gordon-posit commited on
Commit
05eec1f
1 Parent(s): acedecc

Use HF notebook example

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitignore +4 -0
  2. Dockerfile +20 -0
  3. README.md +1 -2
  4. _quarto.yml +0 -19
  5. _site/about.html +0 -533
  6. _site/index.html +0 -677
  7. _site/listings.json +0 -9
  8. _site/posts/post-with-code/image.jpg +0 -0
  9. _site/posts/post-with-code/index.html +0 -556
  10. _site/posts/welcome/index.html +0 -556
  11. _site/posts/welcome/thumbnail.jpg +0 -0
  12. _site/profile.jpg +0 -0
  13. _site/search.json +0 -30
  14. _site/site_libs/bootstrap/bootstrap-icons.css +0 -0
  15. _site/site_libs/bootstrap/bootstrap-icons.woff +0 -0
  16. _site/site_libs/bootstrap/bootstrap.min.css +0 -0
  17. _site/site_libs/bootstrap/bootstrap.min.js +0 -7
  18. _site/site_libs/clipboard/clipboard.min.js +0 -7
  19. _site/site_libs/quarto-html/anchor.min.js +0 -9
  20. _site/site_libs/quarto-html/popper.min.js +0 -6
  21. _site/site_libs/quarto-html/quarto-syntax-highlighting.css +0 -203
  22. _site/site_libs/quarto-html/quarto.js +0 -899
  23. _site/site_libs/quarto-html/tippy.css +0 -1
  24. _site/site_libs/quarto-html/tippy.umd.min.js +0 -2
  25. _site/site_libs/quarto-listing/list.min.js +0 -2
  26. _site/site_libs/quarto-listing/quarto-listing.js +0 -243
  27. _site/site_libs/quarto-nav/headroom.min.js +0 -7
  28. _site/site_libs/quarto-nav/quarto-nav.js +0 -288
  29. _site/site_libs/quarto-search/autocomplete.umd.js +0 -3
  30. _site/site_libs/quarto-search/fuse.min.js +0 -9
  31. _site/site_libs/quarto-search/quarto-search.js +0 -1247
  32. about.qmd +0 -19
  33. index.qmd +0 -14
  34. posts/_metadata.yml +0 -8
  35. posts/post-with-code/image.jpg +0 -0
  36. posts/post-with-code/index.qmd +0 -9
  37. posts/welcome/index.qmd +0 -12
  38. posts/welcome/thumbnail.jpg +0 -0
  39. profile.jpg +0 -0
  40. requirements.txt +0 -0
  41. src/.gitignore +1 -0
  42. src/_quarto.yml +26 -0
  43. src/about.qmd +5 -0
  44. src/index.qmd +31 -0
  45. src/notebooks/advanced_rag.ipynb +0 -0
  46. src/notebooks/automatic_embedding.ipynb +825 -0
  47. src/notebooks/faiss.ipynb +0 -0
  48. src/notebooks/rag_evaluation.ipynb +1470 -0
  49. src/notebooks/rag_zephyr_langchain.ipynb +527 -0
  50. src/notebooks/single_gpu.ipynb +1129 -0
.gitignore CHANGED
@@ -1 +1,5 @@
1
  /.quarto/
 
 
 
 
 
1
  /.quarto/
2
+
3
+ .DS_Store
4
+ .venv/**
5
+ src/_site/
Dockerfile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ARG QUARTO_VERSION="1.3.340"
2
+
3
+ # Use the Quarto base image
4
+ FROM ghcr.io/quarto-dev/quarto:${QUARTO_VERSION} AS builder
5
+
6
+ COPY src /app
7
+ WORKDIR /app
8
+
9
+ # Install Python requirements
10
+ USER root
11
+ RUN apt-get update && apt-get install -y python3 python3-pip
12
+ COPY requirements.txt /app/
13
+ RUN pip3 install -r requirements.txt
14
+
15
+ # Use Quarto to render your site
16
+ RUN quarto render .
17
+
18
+ # Use httpd:alpine as the final image to serve the site
19
+ FROM httpd:alpine
20
+ COPY --from=builder /app/_site/ /usr/local/apache2/htdocs/
README.md CHANGED
@@ -3,9 +3,8 @@ title: Quarto Template
3
  emoji: 🌖
4
  colorFrom: green
5
  colorTo: pink
6
- sdk: static
7
  pinned: false
8
- app_file: _site/index.html
9
  ---
10
 
11
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
3
  emoji: 🌖
4
  colorFrom: green
5
  colorTo: pink
6
+ sdk: docker
7
  pinned: false
 
8
  ---
9
 
10
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
_quarto.yml DELETED
@@ -1,19 +0,0 @@
1
- project:
2
- type: website
3
-
4
- website:
5
- title: "."
6
- navbar:
7
- right:
8
- - about.qmd
9
- - icon: github
10
- href: https://github.com/
11
- - icon: twitter
12
- href: https://twitter.com
13
- format:
14
- html:
15
- theme: cosmo
16
- css: styles.css
17
-
18
-
19
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/about.html DELETED
@@ -1,533 +0,0 @@
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.4.543">
6
-
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
-
9
-
10
- <title>. - About</title>
11
- <style>
12
- code{white-space: pre-wrap;}
13
- span.smallcaps{font-variant: small-caps;}
14
- div.columns{display: flex; gap: min(4vw, 1.5em);}
15
- div.column{flex: auto; overflow-x: auto;}
16
- div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
17
- ul.task-list{list-style: none;}
18
- ul.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>
27
- <script src="site_libs/quarto-nav/headroom.min.js"></script>
28
- <script src="site_libs/clipboard/clipboard.min.js"></script>
29
- <script src="site_libs/quarto-search/autocomplete.umd.js"></script>
30
- <script src="site_libs/quarto-search/fuse.min.js"></script>
31
- <script src="site_libs/quarto-search/quarto-search.js"></script>
32
- <meta name="quarto:offset" content="./">
33
- <script src="site_libs/quarto-html/quarto.js"></script>
34
- <script src="site_libs/quarto-html/popper.min.js"></script>
35
- <script src="site_libs/quarto-html/tippy.umd.min.js"></script>
36
- <link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
37
- <link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
38
- <script src="site_libs/bootstrap/bootstrap.min.js"></script>
39
- <link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
40
- <link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
41
- <script id="quarto-search-options" type="application/json">{
42
- "location": "navbar",
43
- "copy-button": false,
44
- "collapse-after": 3,
45
- "panel-placement": "end",
46
- "type": "overlay",
47
- "limit": 50,
48
- "keyboard-shortcut": [
49
- "f",
50
- "/",
51
- "s"
52
- ],
53
- "show-item-context": false,
54
- "language": {
55
- "search-no-results-text": "No results",
56
- "search-matching-documents-text": "matching documents",
57
- "search-copy-link-title": "Copy link to search",
58
- "search-hide-matches-text": "Hide additional matches",
59
- "search-more-match-text": "more match in this document",
60
- "search-more-matches-text": "more matches in this document",
61
- "search-clear-button-title": "Clear",
62
- "search-text-placeholder": "",
63
- "search-detached-cancel-button-title": "Cancel",
64
- "search-submit-button-title": "Submit",
65
- "search-label": "Search"
66
- }
67
- }</script>
68
-
69
-
70
- <link rel="stylesheet" href="styles.css">
71
- </head>
72
-
73
- <body class="nav-fixed fullcontent">
74
-
75
- <div id="quarto-search-results"></div>
76
- <header id="quarto-header" class="headroom fixed-top">
77
- <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
78
- <div class="navbar-container container-fluid">
79
- <div class="navbar-brand-container mx-auto">
80
- <a class="navbar-brand" href="./index.html">
81
- <span class="navbar-title">.</span>
82
- </a>
83
- </div>
84
- <div id="quarto-search" class="" title="Search"></div>
85
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
86
- <span class="navbar-toggler-icon"></span>
87
- </button>
88
- <div class="collapse navbar-collapse" id="navbarCollapse">
89
- <ul class="navbar-nav navbar-nav-scroll ms-auto">
90
- <li class="nav-item">
91
- <a class="nav-link active" href="./about.html" aria-current="page">
92
- <span class="menu-text">About</span></a>
93
- </li>
94
- <li class="nav-item compact">
95
- <a class="nav-link" href="https://github.com/"> <i class="bi bi-github" role="img">
96
- </i>
97
- <span class="menu-text"></span></a>
98
- </li>
99
- <li class="nav-item compact">
100
- <a class="nav-link" href="https://twitter.com"> <i class="bi bi-twitter" role="img">
101
- </i>
102
- <span class="menu-text"></span></a>
103
- </li>
104
- </ul>
105
- </div> <!-- /navcollapse -->
106
- <div class="quarto-navbar-tools">
107
- </div>
108
- </div> <!-- /container-fluid -->
109
- </nav>
110
- </header>
111
- <!-- content -->
112
- <div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
113
- <!-- sidebar -->
114
- <!-- margin-sidebar -->
115
-
116
- <!-- main -->
117
- <div class="quarto-about-jolla content">
118
- <img src="profile.jpg" class="about-image
119
- round " style="height: 15em; width: 15em;">
120
- <header id="title-block-header" class="quarto-title-block default">
121
- <div class="quarto-title">
122
- <h1 class="title">About</h1>
123
- </div>
124
- <div class="quarto-title-meta">
125
- </div>
126
- </header><main class="content" id="quarto-document-content">
127
- <p>About this blog</p>
128
-
129
-
130
- </main>
131
- <hr class="about-sep">
132
- <div class="about-links">
133
- <a href="https://twitter.com" class="about-link" rel="" target="">
134
- <i class="bi bi-twitter"></i>
135
- <span class="about-link-text">Twitter</span>
136
- </a>
137
- <a href="https://linkedin.com" class="about-link" rel="" target="">
138
- <i class="bi bi-linkedin"></i>
139
- <span class="about-link-text">LinkedIn</span>
140
- </a>
141
- <a href="https://github.com" class="about-link" rel="" target="">
142
- <i class="bi bi-github"></i>
143
- <span class="about-link-text">Github</span>
144
- </a>
145
- </div>
146
- </div>
147
- <!-- /main -->
148
- <script id="quarto-html-after-body" type="application/javascript">
149
- window.document.addEventListener("DOMContentLoaded", function (event) {
150
- const toggleBodyColorMode = (bsSheetEl) => {
151
- const mode = bsSheetEl.getAttribute("data-mode");
152
- const bodyEl = window.document.querySelector("body");
153
- if (mode === "dark") {
154
- bodyEl.classList.add("quarto-dark");
155
- bodyEl.classList.remove("quarto-light");
156
- } else {
157
- bodyEl.classList.add("quarto-light");
158
- bodyEl.classList.remove("quarto-dark");
159
- }
160
- }
161
- const toggleBodyColorPrimary = () => {
162
- const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
163
- if (bsSheetEl) {
164
- toggleBodyColorMode(bsSheetEl);
165
- }
166
- }
167
- toggleBodyColorPrimary();
168
- const isCodeAnnotation = (el) => {
169
- for (const clz of el.classList) {
170
- if (clz.startsWith('code-annotation-')) {
171
- return true;
172
- }
173
- }
174
- return false;
175
- }
176
- const clipboard = new window.ClipboardJS('.code-copy-button', {
177
- text: function(trigger) {
178
- const codeEl = trigger.previousElementSibling.cloneNode(true);
179
- for (const childEl of codeEl.children) {
180
- if (isCodeAnnotation(childEl)) {
181
- childEl.remove();
182
- }
183
- }
184
- return codeEl.innerText;
185
- }
186
- });
187
- clipboard.on('success', function(e) {
188
- // button target
189
- const button = e.trigger;
190
- // don't keep focus
191
- button.blur();
192
- // flash "checked"
193
- button.classList.add('code-copy-button-checked');
194
- var currentTitle = button.getAttribute("title");
195
- button.setAttribute("title", "Copied!");
196
- let tooltip;
197
- if (window.bootstrap) {
198
- button.setAttribute("data-bs-toggle", "tooltip");
199
- button.setAttribute("data-bs-placement", "left");
200
- button.setAttribute("data-bs-title", "Copied!");
201
- tooltip = new bootstrap.Tooltip(button,
202
- { trigger: "manual",
203
- customClass: "code-copy-button-tooltip",
204
- offset: [0, -8]});
205
- tooltip.show();
206
- }
207
- setTimeout(function() {
208
- if (tooltip) {
209
- tooltip.hide();
210
- button.removeAttribute("data-bs-title");
211
- button.removeAttribute("data-bs-toggle");
212
- button.removeAttribute("data-bs-placement");
213
- }
214
- button.setAttribute("title", currentTitle);
215
- button.classList.remove('code-copy-button-checked');
216
- }, 1000);
217
- // clear code selection
218
- e.clearSelection();
219
- });
220
- function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
221
- const config = {
222
- allowHTML: true,
223
- maxWidth: 500,
224
- delay: 100,
225
- arrow: false,
226
- appendTo: function(el) {
227
- return el.parentElement;
228
- },
229
- interactive: true,
230
- interactiveBorder: 10,
231
- theme: 'quarto',
232
- placement: 'bottom-start',
233
- };
234
- if (contentFn) {
235
- config.content = contentFn;
236
- }
237
- if (onTriggerFn) {
238
- config.onTrigger = onTriggerFn;
239
- }
240
- if (onUntriggerFn) {
241
- config.onUntrigger = onUntriggerFn;
242
- }
243
- window.tippy(el, config);
244
- }
245
- const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
246
- for (var i=0; i<noterefs.length; i++) {
247
- const ref = noterefs[i];
248
- tippyHover(ref, function() {
249
- // use id or data attribute instead here
250
- let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
251
- try { href = new URL(href).hash; } catch {}
252
- const id = href.replace(/^#\/?/, "");
253
- const note = window.document.getElementById(id);
254
- return note.innerHTML;
255
- });
256
- }
257
- const xrefs = window.document.querySelectorAll('a.quarto-xref');
258
- const processXRef = (id, note) => {
259
- // Strip column container classes
260
- const stripColumnClz = (el) => {
261
- el.classList.remove("page-full", "page-columns");
262
- if (el.children) {
263
- for (const child of el.children) {
264
- stripColumnClz(child);
265
- }
266
- }
267
- }
268
- stripColumnClz(note)
269
- if (id === null || id.startsWith('sec-')) {
270
- // Special case sections, only their first couple elements
271
- const container = document.createElement("div");
272
- if (note.children && note.children.length > 2) {
273
- container.appendChild(note.children[0].cloneNode(true));
274
- for (let i = 1; i < note.children.length; i++) {
275
- const child = note.children[i];
276
- if (child.tagName === "P" && child.innerText === "") {
277
- continue;
278
- } else {
279
- container.appendChild(child.cloneNode(true));
280
- break;
281
- }
282
- }
283
- if (window.Quarto?.typesetMath) {
284
- window.Quarto.typesetMath(container);
285
- }
286
- return container.innerHTML
287
- } else {
288
- if (window.Quarto?.typesetMath) {
289
- window.Quarto.typesetMath(note);
290
- }
291
- return note.innerHTML;
292
- }
293
- } else {
294
- // Remove any anchor links if they are present
295
- const anchorLink = note.querySelector('a.anchorjs-link');
296
- if (anchorLink) {
297
- anchorLink.remove();
298
- }
299
- if (window.Quarto?.typesetMath) {
300
- window.Quarto.typesetMath(note);
301
- }
302
- // TODO in 1.5, we should make sure this works without a callout special case
303
- if (note.classList.contains("callout")) {
304
- return note.outerHTML;
305
- } else {
306
- return note.innerHTML;
307
- }
308
- }
309
- }
310
- for (var i=0; i<xrefs.length; i++) {
311
- const xref = xrefs[i];
312
- tippyHover(xref, undefined, function(instance) {
313
- instance.disable();
314
- let url = xref.getAttribute('href');
315
- let hash = undefined;
316
- if (url.startsWith('#')) {
317
- hash = url;
318
- } else {
319
- try { hash = new URL(url).hash; } catch {}
320
- }
321
- if (hash) {
322
- const id = hash.replace(/^#\/?/, "");
323
- const note = window.document.getElementById(id);
324
- if (note !== null) {
325
- try {
326
- const html = processXRef(id, note.cloneNode(true));
327
- instance.setContent(html);
328
- } finally {
329
- instance.enable();
330
- instance.show();
331
- }
332
- } else {
333
- // See if we can fetch this
334
- fetch(url.split('#')[0])
335
- .then(res => res.text())
336
- .then(html => {
337
- const parser = new DOMParser();
338
- const htmlDoc = parser.parseFromString(html, "text/html");
339
- const note = htmlDoc.getElementById(id);
340
- if (note !== null) {
341
- const html = processXRef(id, note);
342
- instance.setContent(html);
343
- }
344
- }).finally(() => {
345
- instance.enable();
346
- instance.show();
347
- });
348
- }
349
- } else {
350
- // See if we can fetch a full url (with no hash to target)
351
- // This is a special case and we should probably do some content thinning / targeting
352
- fetch(url)
353
- .then(res => res.text())
354
- .then(html => {
355
- const parser = new DOMParser();
356
- const htmlDoc = parser.parseFromString(html, "text/html");
357
- const note = htmlDoc.querySelector('main.content');
358
- if (note !== null) {
359
- // This should only happen for chapter cross references
360
- // (since there is no id in the URL)
361
- // remove the first header
362
- if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
363
- note.children[0].remove();
364
- }
365
- const html = processXRef(null, note);
366
- instance.setContent(html);
367
- }
368
- }).finally(() => {
369
- instance.enable();
370
- instance.show();
371
- });
372
- }
373
- }, function(instance) {
374
- });
375
- }
376
- let selectedAnnoteEl;
377
- const selectorForAnnotation = ( cell, annotation) => {
378
- let cellAttr = 'data-code-cell="' + cell + '"';
379
- let lineAttr = 'data-code-annotation="' + annotation + '"';
380
- const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
381
- return selector;
382
- }
383
- const selectCodeLines = (annoteEl) => {
384
- const doc = window.document;
385
- const targetCell = annoteEl.getAttribute("data-target-cell");
386
- const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
387
- const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
388
- const lines = annoteSpan.getAttribute("data-code-lines").split(",");
389
- const lineIds = lines.map((line) => {
390
- return targetCell + "-" + line;
391
- })
392
- let top = null;
393
- let height = null;
394
- let parent = null;
395
- if (lineIds.length > 0) {
396
- //compute the position of the single el (top and bottom and make a div)
397
- const el = window.document.getElementById(lineIds[0]);
398
- top = el.offsetTop;
399
- height = el.offsetHeight;
400
- parent = el.parentElement.parentElement;
401
- if (lineIds.length > 1) {
402
- const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
403
- const bottom = lastEl.offsetTop + lastEl.offsetHeight;
404
- height = bottom - top;
405
- }
406
- if (top !== null && height !== null && parent !== null) {
407
- // cook up a div (if necessary) and position it
408
- let div = window.document.getElementById("code-annotation-line-highlight");
409
- if (div === null) {
410
- div = window.document.createElement("div");
411
- div.setAttribute("id", "code-annotation-line-highlight");
412
- div.style.position = 'absolute';
413
- parent.appendChild(div);
414
- }
415
- div.style.top = top - 2 + "px";
416
- div.style.height = height + 4 + "px";
417
- div.style.left = 0;
418
- let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
419
- if (gutterDiv === null) {
420
- gutterDiv = window.document.createElement("div");
421
- gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
422
- gutterDiv.style.position = 'absolute';
423
- const codeCell = window.document.getElementById(targetCell);
424
- const gutter = codeCell.querySelector('.code-annotation-gutter');
425
- gutter.appendChild(gutterDiv);
426
- }
427
- gutterDiv.style.top = top - 2 + "px";
428
- gutterDiv.style.height = height + 4 + "px";
429
- }
430
- selectedAnnoteEl = annoteEl;
431
- }
432
- };
433
- const unselectCodeLines = () => {
434
- const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
435
- elementsIds.forEach((elId) => {
436
- const div = window.document.getElementById(elId);
437
- if (div) {
438
- div.remove();
439
- }
440
- });
441
- selectedAnnoteEl = undefined;
442
- };
443
- // Handle positioning of the toggle
444
- window.addEventListener(
445
- "resize",
446
- throttle(() => {
447
- elRect = undefined;
448
- if (selectedAnnoteEl) {
449
- selectCodeLines(selectedAnnoteEl);
450
- }
451
- }, 10)
452
- );
453
- function throttle(fn, ms) {
454
- let throttle = false;
455
- let timer;
456
- return (...args) => {
457
- if(!throttle) { // first call gets through
458
- fn.apply(this, args);
459
- throttle = true;
460
- } else { // all the others get throttled
461
- if(timer) clearTimeout(timer); // cancel #2
462
- timer = setTimeout(() => {
463
- fn.apply(this, args);
464
- timer = throttle = false;
465
- }, ms);
466
- }
467
- };
468
- }
469
- // Attach click handler to the DT
470
- const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
471
- for (const annoteDlNode of annoteDls) {
472
- annoteDlNode.addEventListener('click', (event) => {
473
- const clickedEl = event.target;
474
- if (clickedEl !== selectedAnnoteEl) {
475
- unselectCodeLines();
476
- const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
477
- if (activeEl) {
478
- activeEl.classList.remove('code-annotation-active');
479
- }
480
- selectCodeLines(clickedEl);
481
- clickedEl.classList.add('code-annotation-active');
482
- } else {
483
- // Unselect the line
484
- unselectCodeLines();
485
- clickedEl.classList.remove('code-annotation-active');
486
- }
487
- });
488
- }
489
- const findCites = (el) => {
490
- const parentEl = el.parentElement;
491
- if (parentEl) {
492
- const cites = parentEl.dataset.cites;
493
- if (cites) {
494
- return {
495
- el,
496
- cites: cites.split(' ')
497
- };
498
- } else {
499
- return findCites(el.parentElement)
500
- }
501
- } else {
502
- return undefined;
503
- }
504
- };
505
- var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
506
- for (var i=0; i<bibliorefs.length; i++) {
507
- const ref = bibliorefs[i];
508
- const citeInfo = findCites(ref);
509
- if (citeInfo) {
510
- tippyHover(citeInfo.el, function() {
511
- var popup = window.document.createElement('div');
512
- citeInfo.cites.forEach(function(cite) {
513
- var citeDiv = window.document.createElement('div');
514
- citeDiv.classList.add('hanging-indent');
515
- citeDiv.classList.add('csl-entry');
516
- var biblioDiv = window.document.getElementById('ref-' + cite);
517
- if (biblioDiv) {
518
- citeDiv.innerHTML = biblioDiv.innerHTML;
519
- }
520
- popup.appendChild(citeDiv);
521
- });
522
- return popup.innerHTML;
523
- });
524
- }
525
- }
526
- });
527
- </script>
528
- </div> <!-- /content -->
529
-
530
-
531
-
532
-
533
- </body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/index.html DELETED
@@ -1,677 +0,0 @@
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.4.543">
6
-
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
-
9
-
10
- <title>.</title>
11
- <style>
12
- code{white-space: pre-wrap;}
13
- span.smallcaps{font-variant: small-caps;}
14
- div.columns{display: flex; gap: min(4vw, 1.5em);}
15
- div.column{flex: auto; overflow-x: auto;}
16
- div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
17
- ul.task-list{list-style: none;}
18
- ul.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>
27
- <script src="site_libs/quarto-nav/headroom.min.js"></script>
28
- <script src="site_libs/clipboard/clipboard.min.js"></script>
29
- <script src="site_libs/quarto-search/autocomplete.umd.js"></script>
30
- <script src="site_libs/quarto-search/fuse.min.js"></script>
31
- <script src="site_libs/quarto-search/quarto-search.js"></script>
32
- <meta name="quarto:offset" content="./">
33
- <script src="site_libs/quarto-listing/list.min.js"></script>
34
- <script src="site_libs/quarto-listing/quarto-listing.js"></script>
35
- <script src="site_libs/quarto-html/quarto.js"></script>
36
- <script src="site_libs/quarto-html/popper.min.js"></script>
37
- <script src="site_libs/quarto-html/tippy.umd.min.js"></script>
38
- <script src="site_libs/quarto-html/anchor.min.js"></script>
39
- <link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
40
- <link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
41
- <script src="site_libs/bootstrap/bootstrap.min.js"></script>
42
- <link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
43
- <link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
44
- <script id="quarto-search-options" type="application/json">{
45
- "location": "navbar",
46
- "copy-button": false,
47
- "collapse-after": 3,
48
- "panel-placement": "end",
49
- "type": "overlay",
50
- "limit": 50,
51
- "keyboard-shortcut": [
52
- "f",
53
- "/",
54
- "s"
55
- ],
56
- "show-item-context": false,
57
- "language": {
58
- "search-no-results-text": "No results",
59
- "search-matching-documents-text": "matching documents",
60
- "search-copy-link-title": "Copy link to search",
61
- "search-hide-matches-text": "Hide additional matches",
62
- "search-more-match-text": "more match in this document",
63
- "search-more-matches-text": "more matches in this document",
64
- "search-clear-button-title": "Clear",
65
- "search-text-placeholder": "",
66
- "search-detached-cancel-button-title": "Cancel",
67
- "search-submit-button-title": "Submit",
68
- "search-label": "Search"
69
- }
70
- }</script>
71
- <script>
72
-
73
- window.document.addEventListener("DOMContentLoaded", function (_event) {
74
- const listingTargetEl = window.document.querySelector('#listing-listing .list');
75
- if (!listingTargetEl) {
76
- // No listing discovered, do not attach.
77
- return;
78
- }
79
-
80
- const options = {
81
- valueNames: ['listing-date','listing-title','listing-author','listing-image','listing-description','listing-categories',{ data: ['index'] },{ data: ['categories'] },{ data: ['listing-date-sort'] },{ data: ['listing-file-modified-sort'] }],
82
-
83
- searchColumns: ["listing-date","listing-title","listing-author","listing-image","listing-description","listing-categories"],
84
- };
85
-
86
- window['quarto-listings'] = window['quarto-listings'] || {};
87
- window['quarto-listings']['listing-listing'] = new List('listing-listing', options);
88
-
89
- if (window['quarto-listing-loaded']) {
90
- window['quarto-listing-loaded']();
91
- }
92
- });
93
-
94
- window.addEventListener('hashchange',() => {
95
- if (window['quarto-listing-loaded']) {
96
- window['quarto-listing-loaded']();
97
- }
98
- })
99
- </script>
100
-
101
- <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
102
- <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js" type="text/javascript"></script>
103
-
104
- <script type="text/javascript">
105
- const typesetMath = (el) => {
106
- if (window.MathJax) {
107
- // MathJax Typeset
108
- window.MathJax.typeset([el]);
109
- } else if (window.katex) {
110
- // KaTeX Render
111
- var mathElements = el.getElementsByClassName("math");
112
- var macros = [];
113
- for (var i = 0; i < mathElements.length; i++) {
114
- var texText = mathElements[i].firstChild;
115
- if (mathElements[i].tagName == "SPAN") {
116
- window.katex.render(texText.data, mathElements[i], {
117
- displayMode: mathElements[i].classList.contains('display'),
118
- throwOnError: false,
119
- macros: macros,
120
- fleqn: false
121
- });
122
- }
123
- }
124
- }
125
- }
126
- window.Quarto = {
127
- typesetMath
128
- };
129
- </script>
130
-
131
- <link rel="stylesheet" href="styles.css">
132
- </head>
133
-
134
- <body class="nav-fixed">
135
-
136
- <div id="quarto-search-results"></div>
137
- <header id="quarto-header" class="headroom fixed-top quarto-banner">
138
- <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
139
- <div class="navbar-container container-fluid">
140
- <div class="navbar-brand-container mx-auto">
141
- <a class="navbar-brand" href="./index.html">
142
- <span class="navbar-title">.</span>
143
- </a>
144
- </div>
145
- <div id="quarto-search" class="" title="Search"></div>
146
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
147
- <span class="navbar-toggler-icon"></span>
148
- </button>
149
- <div class="collapse navbar-collapse" id="navbarCollapse">
150
- <ul class="navbar-nav navbar-nav-scroll ms-auto">
151
- <li class="nav-item">
152
- <a class="nav-link" href="./about.html">
153
- <span class="menu-text">About</span></a>
154
- </li>
155
- <li class="nav-item compact">
156
- <a class="nav-link" href="https://github.com/"> <i class="bi bi-github" role="img">
157
- </i>
158
- <span class="menu-text"></span></a>
159
- </li>
160
- <li class="nav-item compact">
161
- <a class="nav-link" href="https://twitter.com"> <i class="bi bi-twitter" role="img">
162
- </i>
163
- <span class="menu-text"></span></a>
164
- </li>
165
- </ul>
166
- </div> <!-- /navcollapse -->
167
- <div class="quarto-navbar-tools">
168
- </div>
169
- </div> <!-- /container-fluid -->
170
- </nav>
171
- </header>
172
- <!-- content -->
173
- <header id="title-block-header" class="quarto-title-block default page-columns page-full">
174
- <div class="quarto-title-banner page-columns page-full">
175
- <div class="quarto-title column-page-left">
176
- <h1 class="title">.</h1>
177
- </div>
178
- </div>
179
-
180
-
181
- <div class="quarto-title-meta column-page-left">
182
-
183
-
184
-
185
-
186
- </div>
187
-
188
-
189
- </header><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-full page-navbar">
190
- <!-- sidebar -->
191
- <!-- margin-sidebar -->
192
- <div id="quarto-margin-sidebar" class="sidebar margin-sidebar">
193
-
194
- <h5 class="quarto-listing-category-title">Categories</h5><div class="quarto-listing-category category-default"><div class="category" data-category="">All <span class="quarto-category-count">(2)</span></div><div class="category" data-category="analysis">analysis <span class="quarto-category-count">(1)</span></div><div class="category" data-category="code">code <span class="quarto-category-count">(1)</span></div><div class="category" data-category="news">news <span class="quarto-category-count">(2)</span></div></div></div>
195
- <!-- main -->
196
- <main class="content quarto-banner-title-block column-page-left" id="quarto-document-content">
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
- <div class="quarto-listing quarto-listing-container-default" id="listing-listing">
207
- <div class="list quarto-listing-default">
208
- <div class="quarto-post image-right" data-index="0" data-categories="news,code,analysis" data-listing-date-sort="1707969600000" data-listing-file-modified-sort="1708029149467" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="1" data-listing-word-count-sort="7">
209
- <div class="thumbnail">
210
- <p><a href="./posts/post-with-code/index.html" class="no-external"></a></p><a href="./posts/post-with-code/index.html" class="no-external">
211
- <p><img src="./posts/post-with-code/image.jpg" class="thumbnail-image"></p>
212
- </a><p><a href="./posts/post-with-code/index.html" class="no-external"></a></p>
213
- </div>
214
- <div class="body">
215
- <h3 class="no-anchor listing-title">
216
- <a href="./posts/post-with-code/index.html" class="no-external">Post With Code</a>
217
- </h3>
218
- <div class="listing-subtitle">
219
- <a href="./posts/post-with-code/index.html" class="no-external"></a>
220
- </div>
221
- <div class="listing-categories">
222
- <div class="listing-category" onclick="window.quartoListingCategory('news'); return false;">
223
- news
224
- </div>
225
- <div class="listing-category" onclick="window.quartoListingCategory('code'); return false;">
226
- code
227
- </div>
228
- <div class="listing-category" onclick="window.quartoListingCategory('analysis'); return false;">
229
- analysis
230
- </div>
231
- </div>
232
- <div class="listing-description">
233
- <a href="./posts/post-with-code/index.html" class="no-external">This is a post with executable code.</a>
234
- </div>
235
- </div>
236
- <div class="metadata">
237
- <a href="./posts/post-with-code/index.html" class="no-external">
238
- <div class="listing-date">
239
- Feb 15, 2024
240
- </div>
241
- <div class="listing-author">
242
- Harlow Malloc
243
- </div>
244
- </a>
245
- </div>
246
- </div>
247
- <div class="quarto-post image-right" data-index="1" data-categories="news" data-listing-date-sort="1707710400000" data-listing-file-modified-sort="1708029149467" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="1" data-listing-word-count-sort="32">
248
- <div class="thumbnail">
249
- <p><a href="./posts/welcome/index.html" class="no-external"></a></p><a href="./posts/welcome/index.html" class="no-external">
250
- <p class="card-img-top"><img src="posts/welcome/thumbnail.jpg" class="thumbnail-image card-img"/></p>
251
- </a><p><a href="./posts/welcome/index.html" class="no-external"></a></p>
252
- </div>
253
- <div class="body">
254
- <h3 class="no-anchor listing-title">
255
- <a href="./posts/welcome/index.html" class="no-external">Welcome To My Blog</a>
256
- </h3>
257
- <div class="listing-subtitle">
258
- <a href="./posts/welcome/index.html" class="no-external"></a>
259
- </div>
260
- <div class="listing-categories">
261
- <div class="listing-category" onclick="window.quartoListingCategory('news'); return false;">
262
- news
263
- </div>
264
- </div>
265
- <div class="listing-description">
266
- <a href="./posts/welcome/index.html" class="no-external">This is the first post in a Quarto blog. Welcome!</a>
267
- </div>
268
- </div>
269
- <div class="metadata">
270
- <a href="./posts/welcome/index.html" class="no-external">
271
- <div class="listing-date">
272
- Feb 12, 2024
273
- </div>
274
- <div class="listing-author">
275
- Tristan O’Malley
276
- </div>
277
- </a>
278
- </div>
279
- </div>
280
- </div>
281
- <div class="listing-no-matching d-none">
282
- No matching items
283
- </div>
284
- </div></main> <!-- /main -->
285
- <script id="quarto-html-after-body" type="application/javascript">
286
- window.document.addEventListener("DOMContentLoaded", function (event) {
287
- const toggleBodyColorMode = (bsSheetEl) => {
288
- const mode = bsSheetEl.getAttribute("data-mode");
289
- const bodyEl = window.document.querySelector("body");
290
- if (mode === "dark") {
291
- bodyEl.classList.add("quarto-dark");
292
- bodyEl.classList.remove("quarto-light");
293
- } else {
294
- bodyEl.classList.add("quarto-light");
295
- bodyEl.classList.remove("quarto-dark");
296
- }
297
- }
298
- const toggleBodyColorPrimary = () => {
299
- const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
300
- if (bsSheetEl) {
301
- toggleBodyColorMode(bsSheetEl);
302
- }
303
- }
304
- toggleBodyColorPrimary();
305
- const icon = "";
306
- const anchorJS = new window.AnchorJS();
307
- anchorJS.options = {
308
- placement: 'right',
309
- icon: icon
310
- };
311
- anchorJS.add('.anchored');
312
- const isCodeAnnotation = (el) => {
313
- for (const clz of el.classList) {
314
- if (clz.startsWith('code-annotation-')) {
315
- return true;
316
- }
317
- }
318
- return false;
319
- }
320
- const clipboard = new window.ClipboardJS('.code-copy-button', {
321
- text: function(trigger) {
322
- const codeEl = trigger.previousElementSibling.cloneNode(true);
323
- for (const childEl of codeEl.children) {
324
- if (isCodeAnnotation(childEl)) {
325
- childEl.remove();
326
- }
327
- }
328
- return codeEl.innerText;
329
- }
330
- });
331
- clipboard.on('success', function(e) {
332
- // button target
333
- const button = e.trigger;
334
- // don't keep focus
335
- button.blur();
336
- // flash "checked"
337
- button.classList.add('code-copy-button-checked');
338
- var currentTitle = button.getAttribute("title");
339
- button.setAttribute("title", "Copied!");
340
- let tooltip;
341
- if (window.bootstrap) {
342
- button.setAttribute("data-bs-toggle", "tooltip");
343
- button.setAttribute("data-bs-placement", "left");
344
- button.setAttribute("data-bs-title", "Copied!");
345
- tooltip = new bootstrap.Tooltip(button,
346
- { trigger: "manual",
347
- customClass: "code-copy-button-tooltip",
348
- offset: [0, -8]});
349
- tooltip.show();
350
- }
351
- setTimeout(function() {
352
- if (tooltip) {
353
- tooltip.hide();
354
- button.removeAttribute("data-bs-title");
355
- button.removeAttribute("data-bs-toggle");
356
- button.removeAttribute("data-bs-placement");
357
- }
358
- button.setAttribute("title", currentTitle);
359
- button.classList.remove('code-copy-button-checked');
360
- }, 1000);
361
- // clear code selection
362
- e.clearSelection();
363
- });
364
- function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
365
- const config = {
366
- allowHTML: true,
367
- maxWidth: 500,
368
- delay: 100,
369
- arrow: false,
370
- appendTo: function(el) {
371
- return el.parentElement;
372
- },
373
- interactive: true,
374
- interactiveBorder: 10,
375
- theme: 'quarto',
376
- placement: 'bottom-start',
377
- };
378
- if (contentFn) {
379
- config.content = contentFn;
380
- }
381
- if (onTriggerFn) {
382
- config.onTrigger = onTriggerFn;
383
- }
384
- if (onUntriggerFn) {
385
- config.onUntrigger = onUntriggerFn;
386
- }
387
- window.tippy(el, config);
388
- }
389
- const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
390
- for (var i=0; i<noterefs.length; i++) {
391
- const ref = noterefs[i];
392
- tippyHover(ref, function() {
393
- // use id or data attribute instead here
394
- let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
395
- try { href = new URL(href).hash; } catch {}
396
- const id = href.replace(/^#\/?/, "");
397
- const note = window.document.getElementById(id);
398
- return note.innerHTML;
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
- // TODO in 1.5, we should make sure this works without a callout special case
447
- if (note.classList.contains("callout")) {
448
- return note.outerHTML;
449
- } else {
450
- return note.innerHTML;
451
- }
452
- }
453
- }
454
- for (var i=0; i<xrefs.length; i++) {
455
- const xref = xrefs[i];
456
- tippyHover(xref, undefined, function(instance) {
457
- instance.disable();
458
- let url = xref.getAttribute('href');
459
- let hash = undefined;
460
- if (url.startsWith('#')) {
461
- hash = url;
462
- } else {
463
- try { hash = new URL(url).hash; } catch {}
464
- }
465
- if (hash) {
466
- const id = hash.replace(/^#\/?/, "");
467
- const note = window.document.getElementById(id);
468
- if (note !== null) {
469
- try {
470
- const html = processXRef(id, note.cloneNode(true));
471
- instance.setContent(html);
472
- } finally {
473
- instance.enable();
474
- instance.show();
475
- }
476
- } else {
477
- // See if we can fetch this
478
- fetch(url.split('#')[0])
479
- .then(res => res.text())
480
- .then(html => {
481
- const parser = new DOMParser();
482
- const htmlDoc = parser.parseFromString(html, "text/html");
483
- const note = htmlDoc.getElementById(id);
484
- if (note !== null) {
485
- const html = processXRef(id, note);
486
- instance.setContent(html);
487
- }
488
- }).finally(() => {
489
- instance.enable();
490
- instance.show();
491
- });
492
- }
493
- } else {
494
- // See if we can fetch a full url (with no hash to target)
495
- // This is a special case and we should probably do some content thinning / targeting
496
- fetch(url)
497
- .then(res => res.text())
498
- .then(html => {
499
- const parser = new DOMParser();
500
- const htmlDoc = parser.parseFromString(html, "text/html");
501
- const note = htmlDoc.querySelector('main.content');
502
- if (note !== null) {
503
- // This should only happen for chapter cross references
504
- // (since there is no id in the URL)
505
- // remove the first header
506
- if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
507
- note.children[0].remove();
508
- }
509
- const html = processXRef(null, note);
510
- instance.setContent(html);
511
- }
512
- }).finally(() => {
513
- instance.enable();
514
- instance.show();
515
- });
516
- }
517
- }, function(instance) {
518
- });
519
- }
520
- let selectedAnnoteEl;
521
- const selectorForAnnotation = ( cell, annotation) => {
522
- let cellAttr = 'data-code-cell="' + cell + '"';
523
- let lineAttr = 'data-code-annotation="' + annotation + '"';
524
- const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
525
- return selector;
526
- }
527
- const selectCodeLines = (annoteEl) => {
528
- const doc = window.document;
529
- const targetCell = annoteEl.getAttribute("data-target-cell");
530
- const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
531
- const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
532
- const lines = annoteSpan.getAttribute("data-code-lines").split(",");
533
- const lineIds = lines.map((line) => {
534
- return targetCell + "-" + line;
535
- })
536
- let top = null;
537
- let height = null;
538
- let parent = null;
539
- if (lineIds.length > 0) {
540
- //compute the position of the single el (top and bottom and make a div)
541
- const el = window.document.getElementById(lineIds[0]);
542
- top = el.offsetTop;
543
- height = el.offsetHeight;
544
- parent = el.parentElement.parentElement;
545
- if (lineIds.length > 1) {
546
- const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
547
- const bottom = lastEl.offsetTop + lastEl.offsetHeight;
548
- height = bottom - top;
549
- }
550
- if (top !== null && height !== null && parent !== null) {
551
- // cook up a div (if necessary) and position it
552
- let div = window.document.getElementById("code-annotation-line-highlight");
553
- if (div === null) {
554
- div = window.document.createElement("div");
555
- div.setAttribute("id", "code-annotation-line-highlight");
556
- div.style.position = 'absolute';
557
- parent.appendChild(div);
558
- }
559
- div.style.top = top - 2 + "px";
560
- div.style.height = height + 4 + "px";
561
- div.style.left = 0;
562
- let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
563
- if (gutterDiv === null) {
564
- gutterDiv = window.document.createElement("div");
565
- gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
566
- gutterDiv.style.position = 'absolute';
567
- const codeCell = window.document.getElementById(targetCell);
568
- const gutter = codeCell.querySelector('.code-annotation-gutter');
569
- gutter.appendChild(gutterDiv);
570
- }
571
- gutterDiv.style.top = top - 2 + "px";
572
- gutterDiv.style.height = height + 4 + "px";
573
- }
574
- selectedAnnoteEl = annoteEl;
575
- }
576
- };
577
- const unselectCodeLines = () => {
578
- const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
579
- elementsIds.forEach((elId) => {
580
- const div = window.document.getElementById(elId);
581
- if (div) {
582
- div.remove();
583
- }
584
- });
585
- selectedAnnoteEl = undefined;
586
- };
587
- // Handle positioning of the toggle
588
- window.addEventListener(
589
- "resize",
590
- throttle(() => {
591
- elRect = undefined;
592
- if (selectedAnnoteEl) {
593
- selectCodeLines(selectedAnnoteEl);
594
- }
595
- }, 10)
596
- );
597
- function throttle(fn, ms) {
598
- let throttle = false;
599
- let timer;
600
- return (...args) => {
601
- if(!throttle) { // first call gets through
602
- fn.apply(this, args);
603
- throttle = true;
604
- } else { // all the others get throttled
605
- if(timer) clearTimeout(timer); // cancel #2
606
- timer = setTimeout(() => {
607
- fn.apply(this, args);
608
- timer = throttle = false;
609
- }, ms);
610
- }
611
- };
612
- }
613
- // Attach click handler to the DT
614
- const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
615
- for (const annoteDlNode of annoteDls) {
616
- annoteDlNode.addEventListener('click', (event) => {
617
- const clickedEl = event.target;
618
- if (clickedEl !== selectedAnnoteEl) {
619
- unselectCodeLines();
620
- const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
621
- if (activeEl) {
622
- activeEl.classList.remove('code-annotation-active');
623
- }
624
- selectCodeLines(clickedEl);
625
- clickedEl.classList.add('code-annotation-active');
626
- } else {
627
- // Unselect the line
628
- unselectCodeLines();
629
- clickedEl.classList.remove('code-annotation-active');
630
- }
631
- });
632
- }
633
- const findCites = (el) => {
634
- const parentEl = el.parentElement;
635
- if (parentEl) {
636
- const cites = parentEl.dataset.cites;
637
- if (cites) {
638
- return {
639
- el,
640
- cites: cites.split(' ')
641
- };
642
- } else {
643
- return findCites(el.parentElement)
644
- }
645
- } else {
646
- return undefined;
647
- }
648
- };
649
- var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
650
- for (var i=0; i<bibliorefs.length; i++) {
651
- const ref = bibliorefs[i];
652
- const citeInfo = findCites(ref);
653
- if (citeInfo) {
654
- tippyHover(citeInfo.el, function() {
655
- var popup = window.document.createElement('div');
656
- citeInfo.cites.forEach(function(cite) {
657
- var citeDiv = window.document.createElement('div');
658
- citeDiv.classList.add('hanging-indent');
659
- citeDiv.classList.add('csl-entry');
660
- var biblioDiv = window.document.getElementById('ref-' + cite);
661
- if (biblioDiv) {
662
- citeDiv.innerHTML = biblioDiv.innerHTML;
663
- }
664
- popup.appendChild(citeDiv);
665
- });
666
- return popup.innerHTML;
667
- });
668
- }
669
- }
670
- });
671
- </script>
672
- </div> <!-- /content -->
673
-
674
-
675
-
676
-
677
- </body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/listings.json DELETED
@@ -1,9 +0,0 @@
1
- [
2
- {
3
- "listing": "/index.html",
4
- "items": [
5
- "/posts/post-with-code/index.html",
6
- "/posts/welcome/index.html"
7
- ]
8
- }
9
- ]
 
 
 
 
 
 
 
 
 
 
_site/posts/post-with-code/image.jpg DELETED
Binary file (41.7 kB)
 
_site/posts/post-with-code/index.html DELETED
@@ -1,556 +0,0 @@
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.4.543">
6
-
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
-
9
- <meta name="author" content="Harlow Malloc">
10
- <meta name="dcterms.date" content="2024-02-15">
11
-
12
- <title>. - Post With Code</title>
13
- <style>
14
- code{white-space: pre-wrap;}
15
- span.smallcaps{font-variant: small-caps;}
16
- div.columns{display: flex; gap: min(4vw, 1.5em);}
17
- div.column{flex: auto; overflow-x: auto;}
18
- div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
19
- ul.task-list{list-style: none;}
20
- ul.task-list li input[type="checkbox"] {
21
- width: 0.8em;
22
- margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
23
- vertical-align: middle;
24
- }
25
- </style>
26
-
27
-
28
- <script src="../../site_libs/quarto-nav/quarto-nav.js"></script>
29
- <script src="../../site_libs/quarto-nav/headroom.min.js"></script>
30
- <script src="../../site_libs/clipboard/clipboard.min.js"></script>
31
- <script src="../../site_libs/quarto-search/autocomplete.umd.js"></script>
32
- <script src="../../site_libs/quarto-search/fuse.min.js"></script>
33
- <script src="../../site_libs/quarto-search/quarto-search.js"></script>
34
- <meta name="quarto:offset" content="../../">
35
- <script src="../../site_libs/quarto-html/quarto.js"></script>
36
- <script src="../../site_libs/quarto-html/popper.min.js"></script>
37
- <script src="../../site_libs/quarto-html/tippy.umd.min.js"></script>
38
- <script src="../../site_libs/quarto-html/anchor.min.js"></script>
39
- <link href="../../site_libs/quarto-html/tippy.css" rel="stylesheet">
40
- <link href="../../site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
41
- <script src="../../site_libs/bootstrap/bootstrap.min.js"></script>
42
- <link href="../../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
43
- <link href="../../site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
44
- <script id="quarto-search-options" type="application/json">{
45
- "location": "navbar",
46
- "copy-button": false,
47
- "collapse-after": 3,
48
- "panel-placement": "end",
49
- "type": "overlay",
50
- "limit": 50,
51
- "keyboard-shortcut": [
52
- "f",
53
- "/",
54
- "s"
55
- ],
56
- "show-item-context": false,
57
- "language": {
58
- "search-no-results-text": "No results",
59
- "search-matching-documents-text": "matching documents",
60
- "search-copy-link-title": "Copy link to search",
61
- "search-hide-matches-text": "Hide additional matches",
62
- "search-more-match-text": "more match in this document",
63
- "search-more-matches-text": "more matches in this document",
64
- "search-clear-button-title": "Clear",
65
- "search-text-placeholder": "",
66
- "search-detached-cancel-button-title": "Cancel",
67
- "search-submit-button-title": "Submit",
68
- "search-label": "Search"
69
- }
70
- }</script>
71
-
72
-
73
- <link rel="stylesheet" href="../../styles.css">
74
- </head>
75
-
76
- <body class="nav-fixed fullcontent">
77
-
78
- <div id="quarto-search-results"></div>
79
- <header id="quarto-header" class="headroom fixed-top quarto-banner">
80
- <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
81
- <div class="navbar-container container-fluid">
82
- <div class="navbar-brand-container mx-auto">
83
- <a class="navbar-brand" href="../../index.html">
84
- <span class="navbar-title">.</span>
85
- </a>
86
- </div>
87
- <div id="quarto-search" class="" title="Search"></div>
88
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
89
- <span class="navbar-toggler-icon"></span>
90
- </button>
91
- <div class="collapse navbar-collapse" id="navbarCollapse">
92
- <ul class="navbar-nav navbar-nav-scroll ms-auto">
93
- <li class="nav-item">
94
- <a class="nav-link" href="../../about.html">
95
- <span class="menu-text">About</span></a>
96
- </li>
97
- <li class="nav-item compact">
98
- <a class="nav-link" href="https://github.com/"> <i class="bi bi-github" role="img">
99
- </i>
100
- <span class="menu-text"></span></a>
101
- </li>
102
- <li class="nav-item compact">
103
- <a class="nav-link" href="https://twitter.com"> <i class="bi bi-twitter" role="img">
104
- </i>
105
- <span class="menu-text"></span></a>
106
- </li>
107
- </ul>
108
- </div> <!-- /navcollapse -->
109
- <div class="quarto-navbar-tools">
110
- </div>
111
- </div> <!-- /container-fluid -->
112
- </nav>
113
- </header>
114
- <!-- content -->
115
- <header id="title-block-header" class="quarto-title-block default page-columns page-full">
116
- <div class="quarto-title-banner page-columns page-full">
117
- <div class="quarto-title column-body">
118
- <h1 class="title">Post With Code</h1>
119
- <div class="quarto-categories">
120
- <div class="quarto-category">news</div>
121
- <div class="quarto-category">code</div>
122
- <div class="quarto-category">analysis</div>
123
- </div>
124
- </div>
125
- </div>
126
-
127
-
128
- <div class="quarto-title-meta">
129
-
130
- <div>
131
- <div class="quarto-title-meta-heading">Author</div>
132
- <div class="quarto-title-meta-contents">
133
- <p>Harlow Malloc </p>
134
- </div>
135
- </div>
136
-
137
- <div>
138
- <div class="quarto-title-meta-heading">Published</div>
139
- <div class="quarto-title-meta-contents">
140
- <p class="date">February 15, 2024</p>
141
- </div>
142
- </div>
143
-
144
-
145
- </div>
146
-
147
-
148
- </header><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
149
- <!-- sidebar -->
150
- <!-- margin-sidebar -->
151
-
152
- <!-- main -->
153
- <main class="content quarto-banner-title-block" id="quarto-document-content">
154
-
155
-
156
-
157
-
158
-
159
- <p>This is a post with executable code.</p>
160
-
161
-
162
-
163
- </main> <!-- /main -->
164
- <script id="quarto-html-after-body" type="application/javascript">
165
- window.document.addEventListener("DOMContentLoaded", function (event) {
166
- const toggleBodyColorMode = (bsSheetEl) => {
167
- const mode = bsSheetEl.getAttribute("data-mode");
168
- const bodyEl = window.document.querySelector("body");
169
- if (mode === "dark") {
170
- bodyEl.classList.add("quarto-dark");
171
- bodyEl.classList.remove("quarto-light");
172
- } else {
173
- bodyEl.classList.add("quarto-light");
174
- bodyEl.classList.remove("quarto-dark");
175
- }
176
- }
177
- const toggleBodyColorPrimary = () => {
178
- const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
179
- if (bsSheetEl) {
180
- toggleBodyColorMode(bsSheetEl);
181
- }
182
- }
183
- toggleBodyColorPrimary();
184
- const icon = "";
185
- const anchorJS = new window.AnchorJS();
186
- anchorJS.options = {
187
- placement: 'right',
188
- icon: icon
189
- };
190
- anchorJS.add('.anchored');
191
- const isCodeAnnotation = (el) => {
192
- for (const clz of el.classList) {
193
- if (clz.startsWith('code-annotation-')) {
194
- return true;
195
- }
196
- }
197
- return false;
198
- }
199
- const clipboard = new window.ClipboardJS('.code-copy-button', {
200
- text: function(trigger) {
201
- const codeEl = trigger.previousElementSibling.cloneNode(true);
202
- for (const childEl of codeEl.children) {
203
- if (isCodeAnnotation(childEl)) {
204
- childEl.remove();
205
- }
206
- }
207
- return codeEl.innerText;
208
- }
209
- });
210
- clipboard.on('success', function(e) {
211
- // button target
212
- const button = e.trigger;
213
- // don't keep focus
214
- button.blur();
215
- // flash "checked"
216
- button.classList.add('code-copy-button-checked');
217
- var currentTitle = button.getAttribute("title");
218
- button.setAttribute("title", "Copied!");
219
- let tooltip;
220
- if (window.bootstrap) {
221
- button.setAttribute("data-bs-toggle", "tooltip");
222
- button.setAttribute("data-bs-placement", "left");
223
- button.setAttribute("data-bs-title", "Copied!");
224
- tooltip = new bootstrap.Tooltip(button,
225
- { trigger: "manual",
226
- customClass: "code-copy-button-tooltip",
227
- offset: [0, -8]});
228
- tooltip.show();
229
- }
230
- setTimeout(function() {
231
- if (tooltip) {
232
- tooltip.hide();
233
- button.removeAttribute("data-bs-title");
234
- button.removeAttribute("data-bs-toggle");
235
- button.removeAttribute("data-bs-placement");
236
- }
237
- button.setAttribute("title", currentTitle);
238
- button.classList.remove('code-copy-button-checked');
239
- }, 1000);
240
- // clear code selection
241
- e.clearSelection();
242
- });
243
- function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
244
- const config = {
245
- allowHTML: true,
246
- maxWidth: 500,
247
- delay: 100,
248
- arrow: false,
249
- appendTo: function(el) {
250
- return el.parentElement;
251
- },
252
- interactive: true,
253
- interactiveBorder: 10,
254
- theme: 'quarto',
255
- placement: 'bottom-start',
256
- };
257
- if (contentFn) {
258
- config.content = contentFn;
259
- }
260
- if (onTriggerFn) {
261
- config.onTrigger = onTriggerFn;
262
- }
263
- if (onUntriggerFn) {
264
- config.onUntrigger = onUntriggerFn;
265
- }
266
- window.tippy(el, config);
267
- }
268
- const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
269
- for (var i=0; i<noterefs.length; i++) {
270
- const ref = noterefs[i];
271
- tippyHover(ref, function() {
272
- // use id or data attribute instead here
273
- let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
274
- try { href = new URL(href).hash; } catch {}
275
- const id = href.replace(/^#\/?/, "");
276
- const note = window.document.getElementById(id);
277
- return note.innerHTML;
278
- });
279
- }
280
- const xrefs = window.document.querySelectorAll('a.quarto-xref');
281
- const processXRef = (id, note) => {
282
- // Strip column container classes
283
- const stripColumnClz = (el) => {
284
- el.classList.remove("page-full", "page-columns");
285
- if (el.children) {
286
- for (const child of el.children) {
287
- stripColumnClz(child);
288
- }
289
- }
290
- }
291
- stripColumnClz(note)
292
- if (id === null || id.startsWith('sec-')) {
293
- // Special case sections, only their first couple elements
294
- const container = document.createElement("div");
295
- if (note.children && note.children.length > 2) {
296
- container.appendChild(note.children[0].cloneNode(true));
297
- for (let i = 1; i < note.children.length; i++) {
298
- const child = note.children[i];
299
- if (child.tagName === "P" && child.innerText === "") {
300
- continue;
301
- } else {
302
- container.appendChild(child.cloneNode(true));
303
- break;
304
- }
305
- }
306
- if (window.Quarto?.typesetMath) {
307
- window.Quarto.typesetMath(container);
308
- }
309
- return container.innerHTML
310
- } else {
311
- if (window.Quarto?.typesetMath) {
312
- window.Quarto.typesetMath(note);
313
- }
314
- return note.innerHTML;
315
- }
316
- } else {
317
- // Remove any anchor links if they are present
318
- const anchorLink = note.querySelector('a.anchorjs-link');
319
- if (anchorLink) {
320
- anchorLink.remove();
321
- }
322
- if (window.Quarto?.typesetMath) {
323
- window.Quarto.typesetMath(note);
324
- }
325
- // TODO in 1.5, we should make sure this works without a callout special case
326
- if (note.classList.contains("callout")) {
327
- return note.outerHTML;
328
- } else {
329
- return note.innerHTML;
330
- }
331
- }
332
- }
333
- for (var i=0; i<xrefs.length; i++) {
334
- const xref = xrefs[i];
335
- tippyHover(xref, undefined, function(instance) {
336
- instance.disable();
337
- let url = xref.getAttribute('href');
338
- let hash = undefined;
339
- if (url.startsWith('#')) {
340
- hash = url;
341
- } else {
342
- try { hash = new URL(url).hash; } catch {}
343
- }
344
- if (hash) {
345
- const id = hash.replace(/^#\/?/, "");
346
- const note = window.document.getElementById(id);
347
- if (note !== null) {
348
- try {
349
- const html = processXRef(id, note.cloneNode(true));
350
- instance.setContent(html);
351
- } finally {
352
- instance.enable();
353
- instance.show();
354
- }
355
- } else {
356
- // See if we can fetch this
357
- fetch(url.split('#')[0])
358
- .then(res => res.text())
359
- .then(html => {
360
- const parser = new DOMParser();
361
- const htmlDoc = parser.parseFromString(html, "text/html");
362
- const note = htmlDoc.getElementById(id);
363
- if (note !== null) {
364
- const html = processXRef(id, note);
365
- instance.setContent(html);
366
- }
367
- }).finally(() => {
368
- instance.enable();
369
- instance.show();
370
- });
371
- }
372
- } else {
373
- // See if we can fetch a full url (with no hash to target)
374
- // This is a special case and we should probably do some content thinning / targeting
375
- fetch(url)
376
- .then(res => res.text())
377
- .then(html => {
378
- const parser = new DOMParser();
379
- const htmlDoc = parser.parseFromString(html, "text/html");
380
- const note = htmlDoc.querySelector('main.content');
381
- if (note !== null) {
382
- // This should only happen for chapter cross references
383
- // (since there is no id in the URL)
384
- // remove the first header
385
- if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
386
- note.children[0].remove();
387
- }
388
- const html = processXRef(null, note);
389
- instance.setContent(html);
390
- }
391
- }).finally(() => {
392
- instance.enable();
393
- instance.show();
394
- });
395
- }
396
- }, function(instance) {
397
- });
398
- }
399
- let selectedAnnoteEl;
400
- const selectorForAnnotation = ( cell, annotation) => {
401
- let cellAttr = 'data-code-cell="' + cell + '"';
402
- let lineAttr = 'data-code-annotation="' + annotation + '"';
403
- const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
404
- return selector;
405
- }
406
- const selectCodeLines = (annoteEl) => {
407
- const doc = window.document;
408
- const targetCell = annoteEl.getAttribute("data-target-cell");
409
- const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
410
- const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
411
- const lines = annoteSpan.getAttribute("data-code-lines").split(",");
412
- const lineIds = lines.map((line) => {
413
- return targetCell + "-" + line;
414
- })
415
- let top = null;
416
- let height = null;
417
- let parent = null;
418
- if (lineIds.length > 0) {
419
- //compute the position of the single el (top and bottom and make a div)
420
- const el = window.document.getElementById(lineIds[0]);
421
- top = el.offsetTop;
422
- height = el.offsetHeight;
423
- parent = el.parentElement.parentElement;
424
- if (lineIds.length > 1) {
425
- const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
426
- const bottom = lastEl.offsetTop + lastEl.offsetHeight;
427
- height = bottom - top;
428
- }
429
- if (top !== null && height !== null && parent !== null) {
430
- // cook up a div (if necessary) and position it
431
- let div = window.document.getElementById("code-annotation-line-highlight");
432
- if (div === null) {
433
- div = window.document.createElement("div");
434
- div.setAttribute("id", "code-annotation-line-highlight");
435
- div.style.position = 'absolute';
436
- parent.appendChild(div);
437
- }
438
- div.style.top = top - 2 + "px";
439
- div.style.height = height + 4 + "px";
440
- div.style.left = 0;
441
- let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
442
- if (gutterDiv === null) {
443
- gutterDiv = window.document.createElement("div");
444
- gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
445
- gutterDiv.style.position = 'absolute';
446
- const codeCell = window.document.getElementById(targetCell);
447
- const gutter = codeCell.querySelector('.code-annotation-gutter');
448
- gutter.appendChild(gutterDiv);
449
- }
450
- gutterDiv.style.top = top - 2 + "px";
451
- gutterDiv.style.height = height + 4 + "px";
452
- }
453
- selectedAnnoteEl = annoteEl;
454
- }
455
- };
456
- const unselectCodeLines = () => {
457
- const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
458
- elementsIds.forEach((elId) => {
459
- const div = window.document.getElementById(elId);
460
- if (div) {
461
- div.remove();
462
- }
463
- });
464
- selectedAnnoteEl = undefined;
465
- };
466
- // Handle positioning of the toggle
467
- window.addEventListener(
468
- "resize",
469
- throttle(() => {
470
- elRect = undefined;
471
- if (selectedAnnoteEl) {
472
- selectCodeLines(selectedAnnoteEl);
473
- }
474
- }, 10)
475
- );
476
- function throttle(fn, ms) {
477
- let throttle = false;
478
- let timer;
479
- return (...args) => {
480
- if(!throttle) { // first call gets through
481
- fn.apply(this, args);
482
- throttle = true;
483
- } else { // all the others get throttled
484
- if(timer) clearTimeout(timer); // cancel #2
485
- timer = setTimeout(() => {
486
- fn.apply(this, args);
487
- timer = throttle = false;
488
- }, ms);
489
- }
490
- };
491
- }
492
- // Attach click handler to the DT
493
- const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
494
- for (const annoteDlNode of annoteDls) {
495
- annoteDlNode.addEventListener('click', (event) => {
496
- const clickedEl = event.target;
497
- if (clickedEl !== selectedAnnoteEl) {
498
- unselectCodeLines();
499
- const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
500
- if (activeEl) {
501
- activeEl.classList.remove('code-annotation-active');
502
- }
503
- selectCodeLines(clickedEl);
504
- clickedEl.classList.add('code-annotation-active');
505
- } else {
506
- // Unselect the line
507
- unselectCodeLines();
508
- clickedEl.classList.remove('code-annotation-active');
509
- }
510
- });
511
- }
512
- const findCites = (el) => {
513
- const parentEl = el.parentElement;
514
- if (parentEl) {
515
- const cites = parentEl.dataset.cites;
516
- if (cites) {
517
- return {
518
- el,
519
- cites: cites.split(' ')
520
- };
521
- } else {
522
- return findCites(el.parentElement)
523
- }
524
- } else {
525
- return undefined;
526
- }
527
- };
528
- var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
529
- for (var i=0; i<bibliorefs.length; i++) {
530
- const ref = bibliorefs[i];
531
- const citeInfo = findCites(ref);
532
- if (citeInfo) {
533
- tippyHover(citeInfo.el, function() {
534
- var popup = window.document.createElement('div');
535
- citeInfo.cites.forEach(function(cite) {
536
- var citeDiv = window.document.createElement('div');
537
- citeDiv.classList.add('hanging-indent');
538
- citeDiv.classList.add('csl-entry');
539
- var biblioDiv = window.document.getElementById('ref-' + cite);
540
- if (biblioDiv) {
541
- citeDiv.innerHTML = biblioDiv.innerHTML;
542
- }
543
- popup.appendChild(citeDiv);
544
- });
545
- return popup.innerHTML;
546
- });
547
- }
548
- }
549
- });
550
- </script>
551
- </div> <!-- /content -->
552
-
553
-
554
-
555
-
556
- </body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/posts/welcome/index.html DELETED
@@ -1,556 +0,0 @@
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.4.543">
6
-
7
- <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
-
9
- <meta name="author" content="Tristan O’Malley">
10
- <meta name="dcterms.date" content="2024-02-12">
11
-
12
- <title>. - Welcome To My Blog</title>
13
- <style>
14
- code{white-space: pre-wrap;}
15
- span.smallcaps{font-variant: small-caps;}
16
- div.columns{display: flex; gap: min(4vw, 1.5em);}
17
- div.column{flex: auto; overflow-x: auto;}
18
- div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
19
- ul.task-list{list-style: none;}
20
- ul.task-list li input[type="checkbox"] {
21
- width: 0.8em;
22
- margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
23
- vertical-align: middle;
24
- }
25
- </style>
26
-
27
-
28
- <script src="../../site_libs/quarto-nav/quarto-nav.js"></script>
29
- <script src="../../site_libs/quarto-nav/headroom.min.js"></script>
30
- <script src="../../site_libs/clipboard/clipboard.min.js"></script>
31
- <script src="../../site_libs/quarto-search/autocomplete.umd.js"></script>
32
- <script src="../../site_libs/quarto-search/fuse.min.js"></script>
33
- <script src="../../site_libs/quarto-search/quarto-search.js"></script>
34
- <meta name="quarto:offset" content="../../">
35
- <script src="../../site_libs/quarto-html/quarto.js"></script>
36
- <script src="../../site_libs/quarto-html/popper.min.js"></script>
37
- <script src="../../site_libs/quarto-html/tippy.umd.min.js"></script>
38
- <script src="../../site_libs/quarto-html/anchor.min.js"></script>
39
- <link href="../../site_libs/quarto-html/tippy.css" rel="stylesheet">
40
- <link href="../../site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" id="quarto-text-highlighting-styles">
41
- <script src="../../site_libs/bootstrap/bootstrap.min.js"></script>
42
- <link href="../../site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
43
- <link href="../../site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" id="quarto-bootstrap" data-mode="light">
44
- <script id="quarto-search-options" type="application/json">{
45
- "location": "navbar",
46
- "copy-button": false,
47
- "collapse-after": 3,
48
- "panel-placement": "end",
49
- "type": "overlay",
50
- "limit": 50,
51
- "keyboard-shortcut": [
52
- "f",
53
- "/",
54
- "s"
55
- ],
56
- "show-item-context": false,
57
- "language": {
58
- "search-no-results-text": "No results",
59
- "search-matching-documents-text": "matching documents",
60
- "search-copy-link-title": "Copy link to search",
61
- "search-hide-matches-text": "Hide additional matches",
62
- "search-more-match-text": "more match in this document",
63
- "search-more-matches-text": "more matches in this document",
64
- "search-clear-button-title": "Clear",
65
- "search-text-placeholder": "",
66
- "search-detached-cancel-button-title": "Cancel",
67
- "search-submit-button-title": "Submit",
68
- "search-label": "Search"
69
- }
70
- }</script>
71
-
72
-
73
- <link rel="stylesheet" href="../../styles.css">
74
- </head>
75
-
76
- <body class="nav-fixed fullcontent">
77
-
78
- <div id="quarto-search-results"></div>
79
- <header id="quarto-header" class="headroom fixed-top quarto-banner">
80
- <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
81
- <div class="navbar-container container-fluid">
82
- <div class="navbar-brand-container mx-auto">
83
- <a class="navbar-brand" href="../../index.html">
84
- <span class="navbar-title">.</span>
85
- </a>
86
- </div>
87
- <div id="quarto-search" class="" title="Search"></div>
88
- <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
89
- <span class="navbar-toggler-icon"></span>
90
- </button>
91
- <div class="collapse navbar-collapse" id="navbarCollapse">
92
- <ul class="navbar-nav navbar-nav-scroll ms-auto">
93
- <li class="nav-item">
94
- <a class="nav-link" href="../../about.html">
95
- <span class="menu-text">About</span></a>
96
- </li>
97
- <li class="nav-item compact">
98
- <a class="nav-link" href="https://github.com/"> <i class="bi bi-github" role="img">
99
- </i>
100
- <span class="menu-text"></span></a>
101
- </li>
102
- <li class="nav-item compact">
103
- <a class="nav-link" href="https://twitter.com"> <i class="bi bi-twitter" role="img">
104
- </i>
105
- <span class="menu-text"></span></a>
106
- </li>
107
- </ul>
108
- </div> <!-- /navcollapse -->
109
- <div class="quarto-navbar-tools">
110
- </div>
111
- </div> <!-- /container-fluid -->
112
- </nav>
113
- </header>
114
- <!-- content -->
115
- <header id="title-block-header" class="quarto-title-block default page-columns page-full">
116
- <div class="quarto-title-banner page-columns page-full">
117
- <div class="quarto-title column-body">
118
- <h1 class="title">Welcome To My Blog</h1>
119
- <div class="quarto-categories">
120
- <div class="quarto-category">news</div>
121
- </div>
122
- </div>
123
- </div>
124
-
125
-
126
- <div class="quarto-title-meta">
127
-
128
- <div>
129
- <div class="quarto-title-meta-heading">Author</div>
130
- <div class="quarto-title-meta-contents">
131
- <p>Tristan O’Malley </p>
132
- </div>
133
- </div>
134
-
135
- <div>
136
- <div class="quarto-title-meta-heading">Published</div>
137
- <div class="quarto-title-meta-contents">
138
- <p class="date">February 12, 2024</p>
139
- </div>
140
- </div>
141
-
142
-
143
- </div>
144
-
145
-
146
- </header><div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
147
- <!-- sidebar -->
148
- <!-- margin-sidebar -->
149
-
150
- <!-- main -->
151
- <main class="content quarto-banner-title-block" id="quarto-document-content">
152
-
153
-
154
-
155
-
156
-
157
- <p>This is the first post in a Quarto blog. Welcome!</p>
158
- <p><img src="thumbnail.jpg" class="img-fluid"></p>
159
- <p>Since this post doesn’t specify an explicit <code>image</code>, the first image in the post will be used in the listing page of posts.</p>
160
-
161
-
162
-
163
- </main> <!-- /main -->
164
- <script id="quarto-html-after-body" type="application/javascript">
165
- window.document.addEventListener("DOMContentLoaded", function (event) {
166
- const toggleBodyColorMode = (bsSheetEl) => {
167
- const mode = bsSheetEl.getAttribute("data-mode");
168
- const bodyEl = window.document.querySelector("body");
169
- if (mode === "dark") {
170
- bodyEl.classList.add("quarto-dark");
171
- bodyEl.classList.remove("quarto-light");
172
- } else {
173
- bodyEl.classList.add("quarto-light");
174
- bodyEl.classList.remove("quarto-dark");
175
- }
176
- }
177
- const toggleBodyColorPrimary = () => {
178
- const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
179
- if (bsSheetEl) {
180
- toggleBodyColorMode(bsSheetEl);
181
- }
182
- }
183
- toggleBodyColorPrimary();
184
- const icon = "";
185
- const anchorJS = new window.AnchorJS();
186
- anchorJS.options = {
187
- placement: 'right',
188
- icon: icon
189
- };
190
- anchorJS.add('.anchored');
191
- const isCodeAnnotation = (el) => {
192
- for (const clz of el.classList) {
193
- if (clz.startsWith('code-annotation-')) {
194
- return true;
195
- }
196
- }
197
- return false;
198
- }
199
- const clipboard = new window.ClipboardJS('.code-copy-button', {
200
- text: function(trigger) {
201
- const codeEl = trigger.previousElementSibling.cloneNode(true);
202
- for (const childEl of codeEl.children) {
203
- if (isCodeAnnotation(childEl)) {
204
- childEl.remove();
205
- }
206
- }
207
- return codeEl.innerText;
208
- }
209
- });
210
- clipboard.on('success', function(e) {
211
- // button target
212
- const button = e.trigger;
213
- // don't keep focus
214
- button.blur();
215
- // flash "checked"
216
- button.classList.add('code-copy-button-checked');
217
- var currentTitle = button.getAttribute("title");
218
- button.setAttribute("title", "Copied!");
219
- let tooltip;
220
- if (window.bootstrap) {
221
- button.setAttribute("data-bs-toggle", "tooltip");
222
- button.setAttribute("data-bs-placement", "left");
223
- button.setAttribute("data-bs-title", "Copied!");
224
- tooltip = new bootstrap.Tooltip(button,
225
- { trigger: "manual",
226
- customClass: "code-copy-button-tooltip",
227
- offset: [0, -8]});
228
- tooltip.show();
229
- }
230
- setTimeout(function() {
231
- if (tooltip) {
232
- tooltip.hide();
233
- button.removeAttribute("data-bs-title");
234
- button.removeAttribute("data-bs-toggle");
235
- button.removeAttribute("data-bs-placement");
236
- }
237
- button.setAttribute("title", currentTitle);
238
- button.classList.remove('code-copy-button-checked');
239
- }, 1000);
240
- // clear code selection
241
- e.clearSelection();
242
- });
243
- function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
244
- const config = {
245
- allowHTML: true,
246
- maxWidth: 500,
247
- delay: 100,
248
- arrow: false,
249
- appendTo: function(el) {
250
- return el.parentElement;
251
- },
252
- interactive: true,
253
- interactiveBorder: 10,
254
- theme: 'quarto',
255
- placement: 'bottom-start',
256
- };
257
- if (contentFn) {
258
- config.content = contentFn;
259
- }
260
- if (onTriggerFn) {
261
- config.onTrigger = onTriggerFn;
262
- }
263
- if (onUntriggerFn) {
264
- config.onUntrigger = onUntriggerFn;
265
- }
266
- window.tippy(el, config);
267
- }
268
- const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
269
- for (var i=0; i<noterefs.length; i++) {
270
- const ref = noterefs[i];
271
- tippyHover(ref, function() {
272
- // use id or data attribute instead here
273
- let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
274
- try { href = new URL(href).hash; } catch {}
275
- const id = href.replace(/^#\/?/, "");
276
- const note = window.document.getElementById(id);
277
- return note.innerHTML;
278
- });
279
- }
280
- const xrefs = window.document.querySelectorAll('a.quarto-xref');
281
- const processXRef = (id, note) => {
282
- // Strip column container classes
283
- const stripColumnClz = (el) => {
284
- el.classList.remove("page-full", "page-columns");
285
- if (el.children) {
286
- for (const child of el.children) {
287
- stripColumnClz(child);
288
- }
289
- }
290
- }
291
- stripColumnClz(note)
292
- if (id === null || id.startsWith('sec-')) {
293
- // Special case sections, only their first couple elements
294
- const container = document.createElement("div");
295
- if (note.children && note.children.length > 2) {
296
- container.appendChild(note.children[0].cloneNode(true));
297
- for (let i = 1; i < note.children.length; i++) {
298
- const child = note.children[i];
299
- if (child.tagName === "P" && child.innerText === "") {
300
- continue;
301
- } else {
302
- container.appendChild(child.cloneNode(true));
303
- break;
304
- }
305
- }
306
- if (window.Quarto?.typesetMath) {
307
- window.Quarto.typesetMath(container);
308
- }
309
- return container.innerHTML
310
- } else {
311
- if (window.Quarto?.typesetMath) {
312
- window.Quarto.typesetMath(note);
313
- }
314
- return note.innerHTML;
315
- }
316
- } else {
317
- // Remove any anchor links if they are present
318
- const anchorLink = note.querySelector('a.anchorjs-link');
319
- if (anchorLink) {
320
- anchorLink.remove();
321
- }
322
- if (window.Quarto?.typesetMath) {
323
- window.Quarto.typesetMath(note);
324
- }
325
- // TODO in 1.5, we should make sure this works without a callout special case
326
- if (note.classList.contains("callout")) {
327
- return note.outerHTML;
328
- } else {
329
- return note.innerHTML;
330
- }
331
- }
332
- }
333
- for (var i=0; i<xrefs.length; i++) {
334
- const xref = xrefs[i];
335
- tippyHover(xref, undefined, function(instance) {
336
- instance.disable();
337
- let url = xref.getAttribute('href');
338
- let hash = undefined;
339
- if (url.startsWith('#')) {
340
- hash = url;
341
- } else {
342
- try { hash = new URL(url).hash; } catch {}
343
- }
344
- if (hash) {
345
- const id = hash.replace(/^#\/?/, "");
346
- const note = window.document.getElementById(id);
347
- if (note !== null) {
348
- try {
349
- const html = processXRef(id, note.cloneNode(true));
350
- instance.setContent(html);
351
- } finally {
352
- instance.enable();
353
- instance.show();
354
- }
355
- } else {
356
- // See if we can fetch this
357
- fetch(url.split('#')[0])
358
- .then(res => res.text())
359
- .then(html => {
360
- const parser = new DOMParser();
361
- const htmlDoc = parser.parseFromString(html, "text/html");
362
- const note = htmlDoc.getElementById(id);
363
- if (note !== null) {
364
- const html = processXRef(id, note);
365
- instance.setContent(html);
366
- }
367
- }).finally(() => {
368
- instance.enable();
369
- instance.show();
370
- });
371
- }
372
- } else {
373
- // See if we can fetch a full url (with no hash to target)
374
- // This is a special case and we should probably do some content thinning / targeting
375
- fetch(url)
376
- .then(res => res.text())
377
- .then(html => {
378
- const parser = new DOMParser();
379
- const htmlDoc = parser.parseFromString(html, "text/html");
380
- const note = htmlDoc.querySelector('main.content');
381
- if (note !== null) {
382
- // This should only happen for chapter cross references
383
- // (since there is no id in the URL)
384
- // remove the first header
385
- if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
386
- note.children[0].remove();
387
- }
388
- const html = processXRef(null, note);
389
- instance.setContent(html);
390
- }
391
- }).finally(() => {
392
- instance.enable();
393
- instance.show();
394
- });
395
- }
396
- }, function(instance) {
397
- });
398
- }
399
- let selectedAnnoteEl;
400
- const selectorForAnnotation = ( cell, annotation) => {
401
- let cellAttr = 'data-code-cell="' + cell + '"';
402
- let lineAttr = 'data-code-annotation="' + annotation + '"';
403
- const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
404
- return selector;
405
- }
406
- const selectCodeLines = (annoteEl) => {
407
- const doc = window.document;
408
- const targetCell = annoteEl.getAttribute("data-target-cell");
409
- const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
410
- const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
411
- const lines = annoteSpan.getAttribute("data-code-lines").split(",");
412
- const lineIds = lines.map((line) => {
413
- return targetCell + "-" + line;
414
- })
415
- let top = null;
416
- let height = null;
417
- let parent = null;
418
- if (lineIds.length > 0) {
419
- //compute the position of the single el (top and bottom and make a div)
420
- const el = window.document.getElementById(lineIds[0]);
421
- top = el.offsetTop;
422
- height = el.offsetHeight;
423
- parent = el.parentElement.parentElement;
424
- if (lineIds.length > 1) {
425
- const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
426
- const bottom = lastEl.offsetTop + lastEl.offsetHeight;
427
- height = bottom - top;
428
- }
429
- if (top !== null && height !== null && parent !== null) {
430
- // cook up a div (if necessary) and position it
431
- let div = window.document.getElementById("code-annotation-line-highlight");
432
- if (div === null) {
433
- div = window.document.createElement("div");
434
- div.setAttribute("id", "code-annotation-line-highlight");
435
- div.style.position = 'absolute';
436
- parent.appendChild(div);
437
- }
438
- div.style.top = top - 2 + "px";
439
- div.style.height = height + 4 + "px";
440
- div.style.left = 0;
441
- let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
442
- if (gutterDiv === null) {
443
- gutterDiv = window.document.createElement("div");
444
- gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
445
- gutterDiv.style.position = 'absolute';
446
- const codeCell = window.document.getElementById(targetCell);
447
- const gutter = codeCell.querySelector('.code-annotation-gutter');
448
- gutter.appendChild(gutterDiv);
449
- }
450
- gutterDiv.style.top = top - 2 + "px";
451
- gutterDiv.style.height = height + 4 + "px";
452
- }
453
- selectedAnnoteEl = annoteEl;
454
- }
455
- };
456
- const unselectCodeLines = () => {
457
- const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
458
- elementsIds.forEach((elId) => {
459
- const div = window.document.getElementById(elId);
460
- if (div) {
461
- div.remove();
462
- }
463
- });
464
- selectedAnnoteEl = undefined;
465
- };
466
- // Handle positioning of the toggle
467
- window.addEventListener(
468
- "resize",
469
- throttle(() => {
470
- elRect = undefined;
471
- if (selectedAnnoteEl) {
472
- selectCodeLines(selectedAnnoteEl);
473
- }
474
- }, 10)
475
- );
476
- function throttle(fn, ms) {
477
- let throttle = false;
478
- let timer;
479
- return (...args) => {
480
- if(!throttle) { // first call gets through
481
- fn.apply(this, args);
482
- throttle = true;
483
- } else { // all the others get throttled
484
- if(timer) clearTimeout(timer); // cancel #2
485
- timer = setTimeout(() => {
486
- fn.apply(this, args);
487
- timer = throttle = false;
488
- }, ms);
489
- }
490
- };
491
- }
492
- // Attach click handler to the DT
493
- const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
494
- for (const annoteDlNode of annoteDls) {
495
- annoteDlNode.addEventListener('click', (event) => {
496
- const clickedEl = event.target;
497
- if (clickedEl !== selectedAnnoteEl) {
498
- unselectCodeLines();
499
- const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
500
- if (activeEl) {
501
- activeEl.classList.remove('code-annotation-active');
502
- }
503
- selectCodeLines(clickedEl);
504
- clickedEl.classList.add('code-annotation-active');
505
- } else {
506
- // Unselect the line
507
- unselectCodeLines();
508
- clickedEl.classList.remove('code-annotation-active');
509
- }
510
- });
511
- }
512
- const findCites = (el) => {
513
- const parentEl = el.parentElement;
514
- if (parentEl) {
515
- const cites = parentEl.dataset.cites;
516
- if (cites) {
517
- return {
518
- el,
519
- cites: cites.split(' ')
520
- };
521
- } else {
522
- return findCites(el.parentElement)
523
- }
524
- } else {
525
- return undefined;
526
- }
527
- };
528
- var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
529
- for (var i=0; i<bibliorefs.length; i++) {
530
- const ref = bibliorefs[i];
531
- const citeInfo = findCites(ref);
532
- if (citeInfo) {
533
- tippyHover(citeInfo.el, function() {
534
- var popup = window.document.createElement('div');
535
- citeInfo.cites.forEach(function(cite) {
536
- var citeDiv = window.document.createElement('div');
537
- citeDiv.classList.add('hanging-indent');
538
- citeDiv.classList.add('csl-entry');
539
- var biblioDiv = window.document.getElementById('ref-' + cite);
540
- if (biblioDiv) {
541
- citeDiv.innerHTML = biblioDiv.innerHTML;
542
- }
543
- popup.appendChild(citeDiv);
544
- });
545
- return popup.innerHTML;
546
- });
547
- }
548
- }
549
- });
550
- </script>
551
- </div> <!-- /content -->
552
-
553
-
554
-
555
-
556
- </body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/posts/welcome/thumbnail.jpg DELETED
Binary file (39.9 kB)
 
_site/profile.jpg DELETED
Binary file (60.5 kB)
 
_site/search.json DELETED
@@ -1,30 +0,0 @@
1
- [
2
- {
3
- "objectID": "about.html",
4
- "href": "about.html",
5
- "title": "About",
6
- "section": "",
7
- "text": "About this blog"
8
- },
9
- {
10
- "objectID": "posts/welcome/index.html",
11
- "href": "posts/welcome/index.html",
12
- "title": "Welcome To My Blog",
13
- "section": "",
14
- "text": "This is the first post in a Quarto blog. Welcome!\n\nSince this post doesn’t specify an explicit image, the first image in the post will be used in the listing page of posts."
15
- },
16
- {
17
- "objectID": "posts/post-with-code/index.html",
18
- "href": "posts/post-with-code/index.html",
19
- "title": "Post With Code",
20
- "section": "",
21
- "text": "This is a post with executable code."
22
- },
23
- {
24
- "objectID": "index.html",
25
- "href": "index.html",
26
- "title": ".",
27
- "section": "",
28
- "text": "Post With Code\n\n\n\n\n\n\nnews\n\n\ncode\n\n\nanalysis\n\n\n\n\n\n\n\n\n\nFeb 15, 2024\n\n\nHarlow Malloc\n\n\n\n\n\n\n\n\n\n\n\n\nWelcome To My Blog\n\n\n\n\n\n\nnews\n\n\n\n\n\n\n\n\n\nFeb 12, 2024\n\n\nTristan O’Malley\n\n\n\n\n\n\nNo matching items"
29
- }
30
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/site_libs/bootstrap/bootstrap-icons.css DELETED
The diff for this file is too large to render. See raw diff
 
_site/site_libs/bootstrap/bootstrap-icons.woff DELETED
Binary file (176 kB)
 
_site/site_libs/bootstrap/bootstrap.min.css DELETED
The diff for this file is too large to render. See raw diff
 
_site/site_libs/bootstrap/bootstrap.min.js DELETED
@@ -1,7 +0,0 @@
1
- /*!
2
- * Bootstrap v5.3.1 (https://getbootstrap.com/)
3
- * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
- */
6
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t=new Map,e={set(e,i,n){t.has(e)||t.set(e,new Map);const s=t.get(e);s.has(i)||0===s.size?s.set(i,n):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(e,i)=>t.has(e)&&t.get(e).get(i)||null,remove(e,i){if(!t.has(e))return;const n=t.get(e);n.delete(i),0===n.size&&t.delete(e)}},i="transitionend",n=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),s=t=>{t.dispatchEvent(new Event(i))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(n(t)):null,a=t=>{if(!o(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),i=t.closest("details:not([open])");if(!i)return e;if(i!==t){const e=t.closest("summary");if(e&&e.parentNode!==i)return!1;if(null===e)return!1}return e},l=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),c=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?c(t.parentNode):null},h=()=>{},d=t=>{t.offsetHeight},u=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,f=[],p=()=>"rtl"===document.documentElement.dir,m=t=>{var e;e=()=>{const e=u();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(f.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of f)t()})),f.push(e)):e()},g=(t,e=[],i=t)=>"function"==typeof t?t(...e):i,_=(t,e,n=!0)=>{if(!n)return void g(t);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(e)+5;let r=!1;const a=({target:n})=>{n===e&&(r=!0,e.removeEventListener(i,a),g(t))};e.addEventListener(i,a),setTimeout((()=>{r||s(e)}),o)},b=(t,e,i,n)=>{const s=t.length;let o=t.indexOf(e);return-1===o?!i&&n?t[s-1]:t[0]:(o+=i?1:-1,n&&(o=(o+s)%s),t[Math.max(0,Math.min(o,s-1))])},v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,A={};let E=1;const T={mouseenter:"mouseover",mouseleave:"mouseout"},C=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${E++}`||t.uidEvent||E++}function x(t){const e=O(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function k(t,e,i=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===i))}function L(t,e,i){const n="string"==typeof e,s=n?i:e||i;let o=I(t);return C.has(o)||(o=t),[n,s,o]}function S(t,e,i,n,s){if("string"!=typeof e||!t)return;let[o,r,a]=L(e,i,n);if(e in T){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=x(t),c=l[a]||(l[a]={}),h=k(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=O(r,e.replace(v,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return P(s,{delegateTarget:r}),n.oneOff&&N.off(t,s.type,e,i),i.apply(r,[s])}}(t,i,r):function(t,e){return function i(n){return P(n,{delegateTarget:t}),i.oneOff&&N.off(t,n.type,e),e.apply(t,[n])}}(t,r);u.delegationSelector=o?i:null,u.callable=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function D(t,e,i,n,s){const o=k(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function $(t,e,i,n){const s=e[i]||{};for(const[o,r]of Object.entries(s))o.includes(n)&&D(t,e,i,r.callable,r.delegationSelector)}function I(t){return t=t.replace(y,""),T[t]||t}const N={on(t,e,i,n){S(t,e,i,n,!1)},one(t,e,i,n){S(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=L(e,i,n),a=r!==e,l=x(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const i of Object.keys(l))$(t,l,i,e.slice(1));for(const[i,n]of Object.entries(c)){const s=i.replace(w,"");a&&!e.includes(s)||D(t,l,r,n.callable,n.delegationSelector)}}else{if(!Object.keys(c).length)return;D(t,l,r,o,s?i:null)}},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=u();let s=null,o=!0,r=!0,a=!1;e!==I(e)&&n&&(s=n.Event(e,i),n(t).trigger(s),o=!s.isPropagationStopped(),r=!s.isImmediatePropagationStopped(),a=s.isDefaultPrevented());const l=P(new Event(e,{bubbles:o,cancelable:!0}),i);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&s&&s.preventDefault(),l}};function P(t,e={}){for(const[i,n]of Object.entries(e))try{t[i]=n}catch(e){Object.defineProperty(t,i,{configurable:!0,get:()=>n})}return t}function M(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function j(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const F={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${j(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${j(e)}`)},getDataAttributes(t){if(!t)return{};const e={},i=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const n of i){let i=n.replace(/^bs/,"");i=i.charAt(0).toLowerCase()+i.slice(1,i.length),e[i]=M(t.dataset[n])}return e},getDataAttribute:(t,e)=>M(t.getAttribute(`data-bs-${j(e)}`))};class H{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const i=o(e)?F.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof i?i:{},...o(e)?F.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[n,s]of Object.entries(e)){const e=t[n],r=o(e)?"element":null==(i=e)?`${i}`:Object.prototype.toString.call(i).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(s).test(r))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${n}" provided type "${r}" but expected type "${s}".`)}var i}}class W extends H{constructor(t,i){super(),(t=r(t))&&(this._element=t,this._config=this._getConfig(i),e.set(this._element,this.constructor.DATA_KEY,this))}dispose(){e.remove(this._element,this.constructor.DATA_KEY),N.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,i=!0){_(t,e,i)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return e.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.1"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const B=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return n(e)},z={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode.closest(e);for(;n;)i.push(n),n=n.parentNode.closest(e);return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!l(t)&&a(t)))},getSelectorFromElement(t){const e=B(t);return e&&z.findOne(e)?e:null},getElementFromSelector(t){const e=B(t);return e?z.findOne(e):null},getMultipleElementsFromSelector(t){const e=B(t);return e?z.find(e):[]}},R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,n=t.NAME;N.on(document,i,`[data-bs-dismiss="${n}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),l(this))return;const s=z.getElementFromSelector(this)||this.closest(`.${n}`);t.getOrCreateInstance(s)[e]()}))},q=".bs.alert",V=`close${q}`,K=`closed${q}`;class Q extends W{static get NAME(){return"alert"}close(){if(N.trigger(this._element,V).defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),N.trigger(this._element,K),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(Q,"close"),m(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}N.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),m(Y);const U=".bs.swipe",G=`touchstart${U}`,J=`touchmove${U}`,Z=`touchend${U}`,tt=`pointerdown${U}`,et=`pointerup${U}`,it={endCallback:null,leftCallback:null,rightCallback:null},nt={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class st extends H{constructor(t,e){super(),this._element=t,t&&st.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return it}static get DefaultType(){return nt}static get NAME(){return"swipe"}dispose(){N.off(this._element,U)}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),g(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&g(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(N.on(this._element,tt,(t=>this._start(t))),N.on(this._element,et,(t=>this._end(t))),this._element.classList.add("pointer-event")):(N.on(this._element,G,(t=>this._start(t))),N.on(this._element,J,(t=>this._move(t))),N.on(this._element,Z,(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const ot=".bs.carousel",rt=".data-api",at="next",lt="prev",ct="left",ht="right",dt=`slide${ot}`,ut=`slid${ot}`,ft=`keydown${ot}`,pt=`mouseenter${ot}`,mt=`mouseleave${ot}`,gt=`dragstart${ot}`,_t=`load${ot}${rt}`,bt=`click${ot}${rt}`,vt="carousel",yt="active",wt=".active",At=".carousel-item",Et=wt+At,Tt={ArrowLeft:ht,ArrowRight:ct},Ct={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},Ot={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class xt extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=z.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===vt&&this.cycle()}static get Default(){return Ct}static get DefaultType(){return Ot}static get NAME(){return"carousel"}next(){this._slide(at)}nextWhenVisible(){!document.hidden&&a(this._element)&&this.next()}prev(){this._slide(lt)}pause(){this._isSliding&&s(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?N.one(this._element,ut,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,ut,(()=>this.to(t)));const i=this._getItemIndex(this._getActive());if(i===t)return;const n=t>i?at:lt;this._slide(n,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&N.on(this._element,ft,(t=>this._keydown(t))),"hover"===this._config.pause&&(N.on(this._element,pt,(()=>this.pause())),N.on(this._element,mt,(()=>this._maybeEnableCycle()))),this._config.touch&&st.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of z.find(".carousel-item img",this._element))N.on(t,gt,(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(ct)),rightCallback:()=>this._slide(this._directionToOrder(ht)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new st(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=Tt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=z.findOne(wt,this._indicatorsElement);e.classList.remove(yt),e.removeAttribute("aria-current");const i=z.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);i&&(i.classList.add(yt),i.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const i=this._getActive(),n=t===at,s=e||b(this._getItems(),i,n,this._config.wrap);if(s===i)return;const o=this._getItemIndex(s),r=e=>N.trigger(this._element,e,{relatedTarget:s,direction:this._orderToDirection(t),from:this._getItemIndex(i),to:o});if(r(dt).defaultPrevented)return;if(!i||!s)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=s;const l=n?"carousel-item-start":"carousel-item-end",c=n?"carousel-item-next":"carousel-item-prev";s.classList.add(c),d(s),i.classList.add(l),s.classList.add(l),this._queueCallback((()=>{s.classList.remove(l,c),s.classList.add(yt),i.classList.remove(yt,c,l),this._isSliding=!1,r(ut)}),i,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return z.findOne(Et,this._element)}_getItems(){return z.find(At,this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===ct?lt:at:t===ct?at:lt}_orderToDirection(t){return p()?t===lt?ct:ht:t===lt?ht:ct}static jQueryInterface(t){return this.each((function(){const e=xt.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}N.on(document,bt,"[data-bs-slide], [data-bs-slide-to]",(function(t){const e=z.getElementFromSelector(this);if(!e||!e.classList.contains(vt))return;t.preventDefault();const i=xt.getOrCreateInstance(e),n=this.getAttribute("data-bs-slide-to");return n?(i.to(n),void i._maybeEnableCycle()):"next"===F.getDataAttribute(this,"slide")?(i.next(),void i._maybeEnableCycle()):(i.prev(),void i._maybeEnableCycle())})),N.on(window,_t,(()=>{const t=z.find('[data-bs-ride="carousel"]');for(const e of t)xt.getOrCreateInstance(e)})),m(xt);const kt=".bs.collapse",Lt=`show${kt}`,St=`shown${kt}`,Dt=`hide${kt}`,$t=`hidden${kt}`,It=`click${kt}.data-api`,Nt="show",Pt="collapse",Mt="collapsing",jt=`:scope .${Pt} .${Pt}`,Ft='[data-bs-toggle="collapse"]',Ht={parent:null,toggle:!0},Wt={parent:"(null|element)",toggle:"boolean"};class Bt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const i=z.find(Ft);for(const t of i){const e=z.getSelectorFromElement(t),i=z.find(e).filter((t=>t===this._element));null!==e&&i.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return Ht}static get DefaultType(){return Wt}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>Bt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(N.trigger(this._element,Lt).defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(Pt),this._element.classList.add(Mt),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const i=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt,Nt),this._element.style[e]="",N.trigger(this._element,St)}),this._element,!0),this._element.style[e]=`${this._element[i]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(N.trigger(this._element,Dt).defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,d(this._element),this._element.classList.add(Mt),this._element.classList.remove(Pt,Nt);for(const t of this._triggerArray){const e=z.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(Mt),this._element.classList.add(Pt),N.trigger(this._element,$t)}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(Nt)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=r(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(Ft);for(const e of t){const t=z.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=z.find(jt,this._config.parent);return z.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const i of t)i.classList.toggle("collapsed",!e),i.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const i=Bt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}N.on(document,It,Ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of z.getMultipleElementsFromSelector(this))Bt.getOrCreateInstance(t,{toggle:!1}).toggle()})),m(Bt);var zt="top",Rt="bottom",qt="right",Vt="left",Kt="auto",Qt=[zt,Rt,qt,Vt],Xt="start",Yt="end",Ut="clippingParents",Gt="viewport",Jt="popper",Zt="reference",te=Qt.reduce((function(t,e){return t.concat([e+"-"+Xt,e+"-"+Yt])}),[]),ee=[].concat(Qt,[Kt]).reduce((function(t,e){return t.concat([e,e+"-"+Xt,e+"-"+Yt])}),[]),ie="beforeRead",ne="read",se="afterRead",oe="beforeMain",re="main",ae="afterMain",le="beforeWrite",ce="write",he="afterWrite",de=[ie,ne,se,oe,re,ae,le,ce,he];function ue(t){return t?(t.nodeName||"").toLowerCase():null}function fe(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function pe(t){return t instanceof fe(t).Element||t instanceof Element}function me(t){return t instanceof fe(t).HTMLElement||t instanceof HTMLElement}function ge(t){return"undefined"!=typeof ShadowRoot&&(t instanceof fe(t).ShadowRoot||t instanceof ShadowRoot)}const _e={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];me(s)&&ue(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});me(n)&&ue(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function be(t){return t.split("-")[0]}var ve=Math.max,ye=Math.min,we=Math.round;function Ae(){var t=navigator.userAgentData;return null!=t&&t.brands&&Array.isArray(t.brands)?t.brands.map((function(t){return t.brand+"/"+t.version})).join(" "):navigator.userAgent}function Ee(){return!/^((?!chrome|android).)*safari/i.test(Ae())}function Te(t,e,i){void 0===e&&(e=!1),void 0===i&&(i=!1);var n=t.getBoundingClientRect(),s=1,o=1;e&&me(t)&&(s=t.offsetWidth>0&&we(n.width)/t.offsetWidth||1,o=t.offsetHeight>0&&we(n.height)/t.offsetHeight||1);var r=(pe(t)?fe(t):window).visualViewport,a=!Ee()&&i,l=(n.left+(a&&r?r.offsetLeft:0))/s,c=(n.top+(a&&r?r.offsetTop:0))/o,h=n.width/s,d=n.height/o;return{width:h,height:d,top:c,right:l+h,bottom:c+d,left:l,x:l,y:c}}function Ce(t){var e=Te(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Oe(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&ge(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function xe(t){return fe(t).getComputedStyle(t)}function ke(t){return["table","td","th"].indexOf(ue(t))>=0}function Le(t){return((pe(t)?t.ownerDocument:t.document)||window.document).documentElement}function Se(t){return"html"===ue(t)?t:t.assignedSlot||t.parentNode||(ge(t)?t.host:null)||Le(t)}function De(t){return me(t)&&"fixed"!==xe(t).position?t.offsetParent:null}function $e(t){for(var e=fe(t),i=De(t);i&&ke(i)&&"static"===xe(i).position;)i=De(i);return i&&("html"===ue(i)||"body"===ue(i)&&"static"===xe(i).position)?e:i||function(t){var e=/firefox/i.test(Ae());if(/Trident/i.test(Ae())&&me(t)&&"fixed"===xe(t).position)return null;var i=Se(t);for(ge(i)&&(i=i.host);me(i)&&["html","body"].indexOf(ue(i))<0;){var n=xe(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function Ie(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}function Ne(t,e,i){return ve(t,ye(e,i))}function Pe(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Me(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const je={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=be(i.placement),l=Ie(a),c=[Vt,qt].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return Pe("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Me(t,Qt))}(s.padding,i),d=Ce(o),u="y"===l?zt:Vt,f="y"===l?Rt:qt,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=$e(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,A=Ne(v,w,y),E=l;i.modifiersData[n]=((e={})[E]=A,e.centerOffset=A-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Oe(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function Fe(t){return t.split("-")[1]}var He={top:"auto",right:"auto",bottom:"auto",left:"auto"};function We(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=t.isFixed,u=r.x,f=void 0===u?0:u,p=r.y,m=void 0===p?0:p,g="function"==typeof h?h({x:f,y:m}):{x:f,y:m};f=g.x,m=g.y;var _=r.hasOwnProperty("x"),b=r.hasOwnProperty("y"),v=Vt,y=zt,w=window;if(c){var A=$e(i),E="clientHeight",T="clientWidth";A===fe(i)&&"static"!==xe(A=Le(i)).position&&"absolute"===a&&(E="scrollHeight",T="scrollWidth"),(s===zt||(s===Vt||s===qt)&&o===Yt)&&(y=Rt,m-=(d&&A===w&&w.visualViewport?w.visualViewport.height:A[E])-n.height,m*=l?1:-1),s!==Vt&&(s!==zt&&s!==Rt||o!==Yt)||(v=qt,f-=(d&&A===w&&w.visualViewport?w.visualViewport.width:A[T])-n.width,f*=l?1:-1)}var C,O=Object.assign({position:a},c&&He),x=!0===h?function(t,e){var i=t.x,n=t.y,s=e.devicePixelRatio||1;return{x:we(i*s)/s||0,y:we(n*s)/s||0}}({x:f,y:m},fe(i)):{x:f,y:m};return f=x.x,m=x.y,l?Object.assign({},O,((C={})[y]=b?"0":"",C[v]=_?"0":"",C.transform=(w.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",C)):Object.assign({},O,((e={})[y]=b?m+"px":"",e[v]=_?f+"px":"",e.transform="",e))}const Be={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:be(e.placement),variation:Fe(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s,isFixed:"fixed"===e.options.strategy};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,We(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,We(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var ze={passive:!0};const Re={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=fe(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,ze)})),a&&l.addEventListener("resize",i.update,ze),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,ze)})),a&&l.removeEventListener("resize",i.update,ze)}},data:{}};var qe={left:"right",right:"left",bottom:"top",top:"bottom"};function Ve(t){return t.replace(/left|right|bottom|top/g,(function(t){return qe[t]}))}var Ke={start:"end",end:"start"};function Qe(t){return t.replace(/start|end/g,(function(t){return Ke[t]}))}function Xe(t){var e=fe(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Ye(t){return Te(Le(t)).left+Xe(t).scrollLeft}function Ue(t){var e=xe(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ge(t){return["html","body","#document"].indexOf(ue(t))>=0?t.ownerDocument.body:me(t)&&Ue(t)?t:Ge(Se(t))}function Je(t,e){var i;void 0===e&&(e=[]);var n=Ge(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=fe(n),r=s?[o].concat(o.visualViewport||[],Ue(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Je(Se(r)))}function Ze(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function ti(t,e,i){return e===Gt?Ze(function(t,e){var i=fe(t),n=Le(t),s=i.visualViewport,o=n.clientWidth,r=n.clientHeight,a=0,l=0;if(s){o=s.width,r=s.height;var c=Ee();(c||!c&&"fixed"===e)&&(a=s.offsetLeft,l=s.offsetTop)}return{width:o,height:r,x:a+Ye(t),y:l}}(t,i)):pe(e)?function(t,e){var i=Te(t,!1,"fixed"===e);return i.top=i.top+t.clientTop,i.left=i.left+t.clientLeft,i.bottom=i.top+t.clientHeight,i.right=i.left+t.clientWidth,i.width=t.clientWidth,i.height=t.clientHeight,i.x=i.left,i.y=i.top,i}(e,i):Ze(function(t){var e,i=Le(t),n=Xe(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ve(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ve(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+Ye(t),l=-n.scrollTop;return"rtl"===xe(s||i).direction&&(a+=ve(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Le(t)))}function ei(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?be(s):null,r=s?Fe(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case zt:e={x:a,y:i.y-n.height};break;case Rt:e={x:a,y:i.y+i.height};break;case qt:e={x:i.x+i.width,y:l};break;case Vt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?Ie(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case Xt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Yt:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ii(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.strategy,r=void 0===o?t.strategy:o,a=i.boundary,l=void 0===a?Ut:a,c=i.rootBoundary,h=void 0===c?Gt:c,d=i.elementContext,u=void 0===d?Jt:d,f=i.altBoundary,p=void 0!==f&&f,m=i.padding,g=void 0===m?0:m,_=Pe("number"!=typeof g?g:Me(g,Qt)),b=u===Jt?Zt:Jt,v=t.rects.popper,y=t.elements[p?b:u],w=function(t,e,i,n){var s="clippingParents"===e?function(t){var e=Je(Se(t)),i=["absolute","fixed"].indexOf(xe(t).position)>=0&&me(t)?$e(t):t;return pe(i)?e.filter((function(t){return pe(t)&&Oe(t,i)&&"body"!==ue(t)})):[]}(t):[].concat(e),o=[].concat(s,[i]),r=o[0],a=o.reduce((function(e,i){var s=ti(t,i,n);return e.top=ve(s.top,e.top),e.right=ye(s.right,e.right),e.bottom=ye(s.bottom,e.bottom),e.left=ve(s.left,e.left),e}),ti(t,r,n));return a.width=a.right-a.left,a.height=a.bottom-a.top,a.x=a.left,a.y=a.top,a}(pe(y)?y:y.contextElement||Le(t.elements.popper),l,h,r),A=Te(t.elements.reference),E=ei({reference:A,element:v,strategy:"absolute",placement:s}),T=Ze(Object.assign({},v,E)),C=u===Jt?T:A,O={top:w.top-C.top+_.top,bottom:C.bottom-w.bottom+_.bottom,left:w.left-C.left+_.left,right:C.right-w.right+_.right},x=t.modifiersData.offset;if(u===Jt&&x){var k=x[s];Object.keys(O).forEach((function(t){var e=[qt,Rt].indexOf(t)>=0?1:-1,i=[zt,Rt].indexOf(t)>=0?"y":"x";O[t]+=k[i]*e}))}return O}function ni(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?ee:l,h=Fe(n),d=h?a?te:te.filter((function(t){return Fe(t)===h})):Qt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ii(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[be(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const si={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=be(g),b=l||(_!==g&&p?function(t){if(be(t)===Kt)return[];var e=Ve(t);return[Qe(t),e,Qe(e)]}(g):[Ve(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(be(i)===Kt?ni(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,A=new Map,E=!0,T=v[0],C=0;C<v.length;C++){var O=v[C],x=be(O),k=Fe(O)===Xt,L=[zt,Rt].indexOf(x)>=0,S=L?"width":"height",D=ii(e,{placement:O,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),$=L?k?qt:Vt:k?Rt:zt;y[S]>w[S]&&($=Ve($));var I=Ve($),N=[];if(o&&N.push(D[x]<=0),a&&N.push(D[$]<=0,D[I]<=0),N.every((function(t){return t}))){T=O,E=!1;break}A.set(O,N)}if(E)for(var P=function(t){var e=v.find((function(e){var i=A.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==P(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function oi(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function ri(t){return[zt,qt,Rt,Vt].some((function(e){return t[e]>=0}))}const ai={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ii(e,{elementContext:"reference"}),a=ii(e,{altBoundary:!0}),l=oi(r,n),c=oi(a,s,o),h=ri(l),d=ri(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},li={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=ee.reduce((function(t,i){return t[i]=function(t,e,i){var n=be(t),s=[Vt,zt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[Vt,qt].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},ci={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=ei({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},hi={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ii(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=be(e.placement),b=Fe(e.placement),v=!b,y=Ie(_),w="x"===y?"y":"x",A=e.modifiersData.popperOffsets,E=e.rects.reference,T=e.rects.popper,C="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,O="number"==typeof C?{mainAxis:C,altAxis:C}:Object.assign({mainAxis:0,altAxis:0},C),x=e.modifiersData.offset?e.modifiersData.offset[e.placement]:null,k={x:0,y:0};if(A){if(o){var L,S="y"===y?zt:Vt,D="y"===y?Rt:qt,$="y"===y?"height":"width",I=A[y],N=I+g[S],P=I-g[D],M=f?-T[$]/2:0,j=b===Xt?E[$]:T[$],F=b===Xt?-T[$]:-E[$],H=e.elements.arrow,W=f&&H?Ce(H):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},z=B[S],R=B[D],q=Ne(0,E[$],W[$]),V=v?E[$]/2-M-q-z-O.mainAxis:j-q-z-O.mainAxis,K=v?-E[$]/2+M+q+R+O.mainAxis:F+q+R+O.mainAxis,Q=e.elements.arrow&&$e(e.elements.arrow),X=Q?"y"===y?Q.clientTop||0:Q.clientLeft||0:0,Y=null!=(L=null==x?void 0:x[y])?L:0,U=I+K-Y,G=Ne(f?ye(N,I+V-Y-X):N,I,f?ve(P,U):P);A[y]=G,k[y]=G-I}if(a){var J,Z="x"===y?zt:Vt,tt="x"===y?Rt:qt,et=A[w],it="y"===w?"height":"width",nt=et+g[Z],st=et-g[tt],ot=-1!==[zt,Vt].indexOf(_),rt=null!=(J=null==x?void 0:x[w])?J:0,at=ot?nt:et-E[it]-T[it]-rt+O.altAxis,lt=ot?et+E[it]+T[it]-rt-O.altAxis:st,ct=f&&ot?function(t,e,i){var n=Ne(t,e,i);return n>i?i:n}(at,et,lt):Ne(f?at:nt,et,f?lt:st);A[w]=ct,k[w]=ct-et}e.modifiersData[n]=k}},requiresIfExists:["offset"]};function di(t,e,i){void 0===i&&(i=!1);var n,s,o=me(e),r=me(e)&&function(t){var e=t.getBoundingClientRect(),i=we(e.width)/t.offsetWidth||1,n=we(e.height)/t.offsetHeight||1;return 1!==i||1!==n}(e),a=Le(e),l=Te(t,r,i),c={scrollLeft:0,scrollTop:0},h={x:0,y:0};return(o||!o&&!i)&&(("body"!==ue(e)||Ue(a))&&(c=(n=e)!==fe(n)&&me(n)?{scrollLeft:(s=n).scrollLeft,scrollTop:s.scrollTop}:Xe(n)),me(e)?((h=Te(e,!0)).x+=e.clientLeft,h.y+=e.clientTop):a&&(h.x=Ye(a))),{x:l.left+c.scrollLeft-h.x,y:l.top+c.scrollTop-h.y,width:l.width,height:l.height}}function ui(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var fi={placement:"bottom",modifiers:[],strategy:"absolute"};function pi(){for(var t=arguments.length,e=new Array(t),i=0;i<t;i++)e[i]=arguments[i];return!e.some((function(t){return!(t&&"function"==typeof t.getBoundingClientRect)}))}function mi(t){void 0===t&&(t={});var e=t,i=e.defaultModifiers,n=void 0===i?[]:i,s=e.defaultOptions,o=void 0===s?fi:s;return function(t,e,i){void 0===i&&(i=o);var s,r,a={placement:"bottom",orderedModifiers:[],options:Object.assign({},fi,o),modifiersData:{},elements:{reference:t,popper:e},attributes:{},styles:{}},l=[],c=!1,h={state:a,setOptions:function(i){var s="function"==typeof i?i(a.options):i;d(),a.options=Object.assign({},o,a.options,s),a.scrollParents={reference:pe(t)?Je(t):t.contextElement?Je(t.contextElement):[],popper:Je(e)};var r,c,u=function(t){var e=ui(t);return de.reduce((function(t,i){return t.concat(e.filter((function(t){return t.phase===i})))}),[])}((r=[].concat(n,a.options.modifiers),c=r.reduce((function(t,e){var i=t[e.name];return t[e.name]=i?Object.assign({},i,e,{options:Object.assign({},i.options,e.options),data:Object.assign({},i.data,e.data)}):e,t}),{}),Object.keys(c).map((function(t){return c[t]}))));return a.orderedModifiers=u.filter((function(t){return t.enabled})),a.orderedModifiers.forEach((function(t){var e=t.name,i=t.options,n=void 0===i?{}:i,s=t.effect;if("function"==typeof s){var o=s({state:a,name:e,instance:h,options:n});l.push(o||function(){})}})),h.update()},forceUpdate:function(){if(!c){var t=a.elements,e=t.reference,i=t.popper;if(pi(e,i)){a.rects={reference:di(e,$e(i),"fixed"===a.options.strategy),popper:Ce(i)},a.reset=!1,a.placement=a.options.placement,a.orderedModifiers.forEach((function(t){return a.modifiersData[t.name]=Object.assign({},t.data)}));for(var n=0;n<a.orderedModifiers.length;n++)if(!0!==a.reset){var s=a.orderedModifiers[n],o=s.fn,r=s.options,l=void 0===r?{}:r,d=s.name;"function"==typeof o&&(a=o({state:a,options:l,name:d,instance:h})||a)}else a.reset=!1,n=-1}}},update:(s=function(){return new Promise((function(t){h.forceUpdate(),t(a)}))},function(){return r||(r=new Promise((function(t){Promise.resolve().then((function(){r=void 0,t(s())}))}))),r}),destroy:function(){d(),c=!0}};if(!pi(t,e))return h;function d(){l.forEach((function(t){return t()})),l=[]}return h.setOptions(i).then((function(t){!c&&i.onFirstUpdate&&i.onFirstUpdate(t)})),h}}var gi=mi(),_i=mi({defaultModifiers:[Re,ci,Be,_e]}),bi=mi({defaultModifiers:[Re,ci,Be,_e,li,si,hi,je,ai]});const vi=Object.freeze(Object.defineProperty({__proto__:null,afterMain:ae,afterRead:se,afterWrite:he,applyStyles:_e,arrow:je,auto:Kt,basePlacements:Qt,beforeMain:oe,beforeRead:ie,beforeWrite:le,bottom:Rt,clippingParents:Ut,computeStyles:Be,createPopper:bi,createPopperBase:gi,createPopperLite:_i,detectOverflow:ii,end:Yt,eventListeners:Re,flip:si,hide:ai,left:Vt,main:re,modifierPhases:de,offset:li,placements:ee,popper:Jt,popperGenerator:mi,popperOffsets:ci,preventOverflow:hi,read:ne,reference:Zt,right:qt,start:Xt,top:zt,variationPlacements:te,viewport:Gt,write:ce},Symbol.toStringTag,{value:"Module"})),yi="dropdown",wi=".bs.dropdown",Ai=".data-api",Ei="ArrowUp",Ti="ArrowDown",Ci=`hide${wi}`,Oi=`hidden${wi}`,xi=`show${wi}`,ki=`shown${wi}`,Li=`click${wi}${Ai}`,Si=`keydown${wi}${Ai}`,Di=`keyup${wi}${Ai}`,$i="show",Ii='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Ni=`${Ii}.${$i}`,Pi=".dropdown-menu",Mi=p()?"top-end":"top-start",ji=p()?"top-start":"top-end",Fi=p()?"bottom-end":"bottom-start",Hi=p()?"bottom-start":"bottom-end",Wi=p()?"left-start":"right-start",Bi=p()?"right-start":"left-start",zi={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},Ri={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class qi extends W{constructor(t,e){super(t,e),this._popper=null,this._parent=this._element.parentNode,this._menu=z.next(this._element,Pi)[0]||z.prev(this._element,Pi)[0]||z.findOne(Pi,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return zi}static get DefaultType(){return Ri}static get NAME(){return yi}toggle(){return this._isShown()?this.hide():this.show()}show(){if(l(this._element)||this._isShown())return;const t={relatedTarget:this._element};if(!N.trigger(this._element,xi,t).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add($i),this._element.classList.add($i),N.trigger(this._element,ki,t)}}hide(){if(l(this._element)||!this._isShown())return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){if(!N.trigger(this._element,Ci,t).defaultPrevented){if("ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._popper&&this._popper.destroy(),this._menu.classList.remove($i),this._element.classList.remove($i),this._element.setAttribute("aria-expanded","false"),F.removeDataAttribute(this._menu,"popper"),N.trigger(this._element,Oi,t)}}_getConfig(t){if("object"==typeof(t=super._getConfig(t)).reference&&!o(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${yi.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(){if(void 0===vi)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=this._parent:o(this._config.reference)?t=r(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const e=this._getPopperConfig();this._popper=bi(t,this._menu,e)}_isShown(){return this._menu.classList.contains($i)}_getPlacement(){const t=this._parent;if(t.classList.contains("dropend"))return Wi;if(t.classList.contains("dropstart"))return Bi;if(t.classList.contains("dropup-center"))return"top";if(t.classList.contains("dropdown-center"))return"bottom";const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ji:Mi:e?Hi:Fi}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(F.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...g(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const i=z.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>a(t)));i.length&&b(i,e,t===Ti,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=qi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=z.find(Ni);for(const i of e){const e=qi.getInstance(i);if(!e||!1===e._config.autoClose)continue;const n=t.composedPath(),s=n.includes(e._menu);if(n.includes(e._element)||"inside"===e._config.autoClose&&!s||"outside"===e._config.autoClose&&s)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),i="Escape"===t.key,n=[Ei,Ti].includes(t.key);if(!n&&!i)return;if(e&&!i)return;t.preventDefault();const s=this.matches(Ii)?this:z.prev(this,Ii)[0]||z.next(this,Ii)[0]||z.findOne(Ii,t.delegateTarget.parentNode),o=qi.getOrCreateInstance(s);if(n)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),s.focus())}}N.on(document,Si,Ii,qi.dataApiKeydownHandler),N.on(document,Si,Pi,qi.dataApiKeydownHandler),N.on(document,Li,qi.clearMenus),N.on(document,Di,qi.clearMenus),N.on(document,Li,Ii,(function(t){t.preventDefault(),qi.getOrCreateInstance(this).toggle()})),m(qi);const Vi="backdrop",Ki="show",Qi=`mousedown.bs.${Vi}`,Xi={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},Yi={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class Ui extends H{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Xi}static get DefaultType(){return Yi}static get NAME(){return Vi}show(t){if(!this._config.isVisible)return void g(t);this._append();const e=this._getElement();this._config.isAnimated&&d(e),e.classList.add(Ki),this._emulateAnimation((()=>{g(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Ki),this._emulateAnimation((()=>{this.dispose(),g(t)}))):g(t)}dispose(){this._isAppended&&(N.off(this._element,Qi),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=r(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),N.on(t,Qi,(()=>{g(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){_(t,this._getElement(),this._config.isAnimated)}}const Gi=".bs.focustrap",Ji=`focusin${Gi}`,Zi=`keydown.tab${Gi}`,tn="backward",en={autofocus:!0,trapElement:null},nn={autofocus:"boolean",trapElement:"element"};class sn extends H{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return en}static get DefaultType(){return nn}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),N.off(document,Gi),N.on(document,Ji,(t=>this._handleFocusin(t))),N.on(document,Zi,(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,N.off(document,Gi))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const i=z.focusableChildren(e);0===i.length?e.focus():this._lastTabNavDirection===tn?i[i.length-1].focus():i[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?tn:"forward")}}const on=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",rn=".sticky-top",an="padding-right",ln="margin-right";class cn{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,an,(e=>e+t)),this._setElementAttributes(on,an,(e=>e+t)),this._setElementAttributes(rn,ln,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,an),this._resetElementAttributes(on,an),this._resetElementAttributes(rn,ln)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${i(Number.parseFloat(s))}px`)}))}_saveInitialAttribute(t,e){const i=t.style.getPropertyValue(e);i&&F.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=F.getDataAttribute(t,e);null!==i?(F.removeDataAttribute(t,e),t.style.setProperty(e,i)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(o(t))e(t);else for(const i of z.find(t,this._element))e(i)}}const hn=".bs.modal",dn=`hide${hn}`,un=`hidePrevented${hn}`,fn=`hidden${hn}`,pn=`show${hn}`,mn=`shown${hn}`,gn=`resize${hn}`,_n=`click.dismiss${hn}`,bn=`mousedown.dismiss${hn}`,vn=`keydown.dismiss${hn}`,yn=`click${hn}.data-api`,wn="modal-open",An="show",En="modal-static",Tn={backdrop:!0,focus:!0,keyboard:!0},Cn={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class On extends W{constructor(t,e){super(t,e),this._dialog=z.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new cn,this._addEventListeners()}static get Default(){return Tn}static get DefaultType(){return Cn}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||N.trigger(this._element,pn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(wn),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(N.trigger(this._element,dn).defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(An),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){N.off(window,hn),N.off(this._dialog,hn),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new Ui({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=z.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),d(this._element),this._element.classList.add(An),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,N.trigger(this._element,mn,{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){N.on(this._element,vn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),N.on(window,gn,(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),N.on(this._element,bn,(t=>{N.one(this._element,_n,(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(wn),this._resetAdjustments(),this._scrollBar.reset(),N.trigger(this._element,fn)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,un).defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(En)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(En),this._queueCallback((()=>{this._element.classList.remove(En),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;if(i&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!i&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=On.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,yn,'[data-bs-toggle="modal"]',(function(t){const e=z.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),N.one(e,pn,(t=>{t.defaultPrevented||N.one(e,fn,(()=>{a(this)&&this.focus()}))}));const i=z.findOne(".modal.show");i&&On.getInstance(i).hide(),On.getOrCreateInstance(e).toggle(this)})),R(On),m(On);const xn=".bs.offcanvas",kn=".data-api",Ln=`load${xn}${kn}`,Sn="show",Dn="showing",$n="hiding",In=".offcanvas.show",Nn=`show${xn}`,Pn=`shown${xn}`,Mn=`hide${xn}`,jn=`hidePrevented${xn}`,Fn=`hidden${xn}`,Hn=`resize${xn}`,Wn=`click${xn}${kn}`,Bn=`keydown.dismiss${xn}`,zn={backdrop:!0,keyboard:!0,scroll:!1},Rn={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class qn extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return zn}static get DefaultType(){return Rn}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,Nn,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new cn).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(Dn),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(Sn),this._element.classList.remove(Dn),N.trigger(this._element,Pn,{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(N.trigger(this._element,Mn).defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add($n),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(Sn,$n),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new cn).reset(),N.trigger(this._element,Fn)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new Ui({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():N.trigger(this._element,jn)}:null})}_initializeFocusTrap(){return new sn({trapElement:this._element})}_addEventListeners(){N.on(this._element,Bn,(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():N.trigger(this._element,jn))}))}static jQueryInterface(t){return this.each((function(){const e=qn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,Wn,'[data-bs-toggle="offcanvas"]',(function(t){const e=z.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this))return;N.one(e,Fn,(()=>{a(this)&&this.focus()}));const i=z.findOne(In);i&&i!==e&&qn.getInstance(i).hide(),qn.getOrCreateInstance(e).toggle(this)})),N.on(window,Ln,(()=>{for(const t of z.find(In))qn.getOrCreateInstance(t).show()})),N.on(window,Hn,(()=>{for(const t of z.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&qn.getOrCreateInstance(t).hide()})),R(qn),m(qn);const Vn={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},Kn=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Qn=/^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i,Xn=(t,e)=>{const i=t.nodeName.toLowerCase();return e.includes(i)?!Kn.has(i)||Boolean(Qn.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(i)))},Yn={allowList:Vn,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"<div></div>"},Un={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},Gn={entry:"(string|element|function|null)",selector:"(string|element)"};class Jn extends H{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return Yn}static get DefaultType(){return Un}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,i]of Object.entries(this._config.content))this._setContent(t,i,e);const e=t.children[0],i=this._resolvePossibleFunction(this._config.extraClass);return i&&e.classList.add(...i.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,i]of Object.entries(t))super._typeCheckConfig({selector:e,entry:i},Gn)}_setContent(t,e,i){const n=z.findOne(i,t);n&&((e=this._resolvePossibleFunction(e))?o(e)?this._putElementInTemplate(r(e),n):this._config.html?n.innerHTML=this._maybeSanitize(e):n.textContent=e:n.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,i){if(!t.length)return t;if(i&&"function"==typeof i)return i(t);const n=(new window.DOMParser).parseFromString(t,"text/html"),s=[].concat(...n.body.querySelectorAll("*"));for(const t of s){const i=t.nodeName.toLowerCase();if(!Object.keys(e).includes(i)){t.remove();continue}const n=[].concat(...t.attributes),s=[].concat(e["*"]||[],e[i]||[]);for(const e of n)Xn(e,s)||t.removeAttribute(e.nodeName)}return n.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return g(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Zn=new Set(["sanitize","allowList","sanitizeFn"]),ts="fade",es="show",is=".modal",ns="hide.bs.modal",ss="hover",os="focus",rs={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},as={allowList:Vn,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',title:"",trigger:"hover focus"},ls={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class cs extends W{constructor(t,e){if(void 0===vi)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return as}static get DefaultType(){return ls}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),N.off(this._element.closest(is),ns,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=N.trigger(this._element,this.constructor.eventName("show")),e=(c(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const i=this._getTipElement();this._element.setAttribute("aria-describedby",i.getAttribute("id"));const{container:n}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(n.append(i),N.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(i),i.classList.add(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.on(t,"mouseover",h);this._queueCallback((()=>{N.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!N.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(es),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))N.off(t,"mouseover",h);this._activeTrigger.click=!1,this._activeTrigger[os]=!1,this._activeTrigger[ss]=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(ts,es),e.classList.add(`bs-${this.constructor.NAME}-auto`);const i=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",i),this._isAnimated()&&e.classList.add(ts),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Jn({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(ts)}_isShown(){return this.tip&&this.tip.classList.contains(es)}_createPopper(t){const e=g(this._config.placement,[this,t,this._element]),i=rs[e.toUpperCase()];return bi(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return g(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...g(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)N.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===ss?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),i=e===ss?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");N.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?os:ss]=!0,e._enter()})),N.on(this._element,i,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?os:ss]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(is),ns,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=F.getDataAttributes(this._element);for(const t of Object.keys(e))Zn.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,i]of Object.entries(this._config))this.constructor.Default[e]!==i&&(t[e]=i);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=cs.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(cs);const hs={...cs.Default,content:"",offset:[0,8],placement:"right",template:'<div class="popover" role="tooltip"><div class="popover-arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>',trigger:"click"},ds={...cs.DefaultType,content:"(null|string|element|function)"};class us extends cs{static get Default(){return hs}static get DefaultType(){return ds}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=us.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m(us);const fs=".bs.scrollspy",ps=`activate${fs}`,ms=`click${fs}`,gs=`load${fs}.data-api`,_s="active",bs="[href]",vs=".nav-link",ys=`${vs}, .nav-item > ${vs}, .list-group-item`,ws={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},As={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class Es extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return ws}static get DefaultType(){return As}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=r(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(N.off(this._config.target,ms),N.on(this._config.target,ms,bs,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const i=this._rootElement||window,n=e.offsetTop-this._element.offsetTop;if(i.scrollTo)return void i.scrollTo({top:n,behavior:"smooth"});i.scrollTop=n}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),i=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},n=(this._rootElement||document.documentElement).scrollTop,s=n>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=n;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(s&&t){if(i(o),!n)return}else s||t||i(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=z.find(bs,this._config.target);for(const e of t){if(!e.hash||l(e))continue;const t=z.findOne(decodeURI(e.hash),this._element);a(t)&&(this._targetLinks.set(decodeURI(e.hash),e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add(_s),this._activateParents(t),N.trigger(this._element,ps,{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))z.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add(_s);else for(const e of z.parents(t,".nav, .list-group"))for(const t of z.prev(e,ys))t.classList.add(_s)}_clearActiveClass(t){t.classList.remove(_s);const e=z.find(`${bs}.${_s}`,t);for(const t of e)t.classList.remove(_s)}static jQueryInterface(t){return this.each((function(){const e=Es.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,gs,(()=>{for(const t of z.find('[data-bs-spy="scroll"]'))Es.getOrCreateInstance(t)})),m(Es);const Ts=".bs.tab",Cs=`hide${Ts}`,Os=`hidden${Ts}`,xs=`show${Ts}`,ks=`shown${Ts}`,Ls=`click${Ts}`,Ss=`keydown${Ts}`,Ds=`load${Ts}`,$s="ArrowLeft",Is="ArrowRight",Ns="ArrowUp",Ps="ArrowDown",Ms="Home",js="End",Fs="active",Hs="fade",Ws="show",Bs=":not(.dropdown-toggle)",zs='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Rs=`.nav-link${Bs}, .list-group-item${Bs}, [role="tab"]${Bs}, ${zs}`,qs=`.${Fs}[data-bs-toggle="tab"], .${Fs}[data-bs-toggle="pill"], .${Fs}[data-bs-toggle="list"]`;class Vs extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),N.on(this._element,Ss,(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),i=e?N.trigger(e,Cs,{relatedTarget:t}):null;N.trigger(t,xs,{relatedTarget:e}).defaultPrevented||i&&i.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Fs),this._activate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),N.trigger(t,ks,{relatedTarget:e})):t.classList.add(Ws)}),t,t.classList.contains(Hs)))}_deactivate(t,e){t&&(t.classList.remove(Fs),t.blur(),this._deactivate(z.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),N.trigger(t,Os,{relatedTarget:e})):t.classList.remove(Ws)}),t,t.classList.contains(Hs)))}_keydown(t){if(![$s,Is,Ns,Ps,Ms,js].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=this._getChildren().filter((t=>!l(t)));let i;if([Ms,js].includes(t.key))i=e[t.key===Ms?0:e.length-1];else{const n=[Is,Ps].includes(t.key);i=b(e,t.target,n,!0)}i&&(i.focus({preventScroll:!0}),Vs.getOrCreateInstance(i).show())}_getChildren(){return z.find(Rs,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),i=this._getOuterElement(t);t.setAttribute("aria-selected",e),i!==t&&this._setAttributeIfNotExists(i,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=z.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const i=this._getOuterElement(t);if(!i.classList.contains("dropdown"))return;const n=(t,n)=>{const s=z.findOne(t,i);s&&s.classList.toggle(n,e)};n(".dropdown-toggle",Fs),n(".dropdown-menu",Ws),i.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,i){t.hasAttribute(e)||t.setAttribute(e,i)}_elemIsActive(t){return t.classList.contains(Fs)}_getInnerElement(t){return t.matches(Rs)?t:z.findOne(Rs,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Vs.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,Ls,zs,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),l(this)||Vs.getOrCreateInstance(this).show()})),N.on(window,Ds,(()=>{for(const t of z.find(qs))Vs.getOrCreateInstance(t)})),m(Vs);const Ks=".bs.toast",Qs=`mouseover${Ks}`,Xs=`mouseout${Ks}`,Ys=`focusin${Ks}`,Us=`focusout${Ks}`,Gs=`hide${Ks}`,Js=`hidden${Ks}`,Zs=`show${Ks}`,to=`shown${Ks}`,eo="hide",io="show",no="showing",so={animation:"boolean",autohide:"boolean",delay:"number"},oo={animation:!0,autohide:!0,delay:5e3};class ro extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return oo}static get DefaultType(){return so}static get NAME(){return"toast"}show(){N.trigger(this._element,Zs).defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(eo),d(this._element),this._element.classList.add(io,no),this._queueCallback((()=>{this._element.classList.remove(no),N.trigger(this._element,to),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(N.trigger(this._element,Gs).defaultPrevented||(this._element.classList.add(no),this._queueCallback((()=>{this._element.classList.add(eo),this._element.classList.remove(no,io),N.trigger(this._element,Js)}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(io),super.dispose()}isShown(){return this._element.classList.contains(io)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){N.on(this._element,Qs,(t=>this._onInteraction(t,!0))),N.on(this._element,Xs,(t=>this._onInteraction(t,!1))),N.on(this._element,Ys,(t=>this._onInteraction(t,!0))),N.on(this._element,Us,(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ro.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(ro),m(ro),{Alert:Q,Button:Y,Carousel:xt,Collapse:Bt,Dropdown:qi,Modal:On,Offcanvas:qn,Popover:us,ScrollSpy:Es,Tab:Vs,Toast:ro,Tooltip:cs}}));
7
- //# sourceMappingURL=bootstrap.bundle.min.js.map
 
 
 
 
 
 
 
 
_site/site_libs/clipboard/clipboard.min.js DELETED
@@ -1,7 +0,0 @@
1
- /*!
2
- * clipboard.js v2.0.11
3
- * https://clipboardjs.com/
4
- *
5
- * Licensed MIT © Zeno Rocha
6
- */
7
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{container:document.body},n="";return"string"==typeof t?n=o(t,e):t instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(null==t?void 0:t.type)?n=o(t.value,e):(n=r()(t),c("copy")),n};function l(t){return(l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var s=function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{},e=t.action,n=void 0===e?"copy":e,o=t.container,e=t.target,t=t.text;if("copy"!==n&&"cut"!==n)throw new Error('Invalid "action" value, use either "copy" or "cut"');if(void 0!==e){if(!e||"object"!==l(e)||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===n&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===n&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes')}return t?f(t,{container:o}):e?"cut"===n?a(e):f(e,{container:o}):void 0};function p(t){return(p="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function d(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}function y(t,e){return(y=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function h(n){var o=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],function(){})),!0}catch(t){return!1}}();return function(){var t,e=v(n);return t=o?(t=v(this).constructor,Reflect.construct(e,arguments,t)):e.apply(this,arguments),e=this,!(t=t)||"object"!==p(t)&&"function"!=typeof t?function(t){if(void 0!==t)return t;throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}(e):t}}function v(t){return(v=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function m(t,e){t="data-clipboard-".concat(t);if(e.hasAttribute(t))return e.getAttribute(t)}var b=function(){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&y(t,e)}(r,i());var t,e,n,o=h(r);function r(t,e){var n;return function(t){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")}(this),(n=o.call(this)).resolveOptions(e),n.listenClick(t),n}return t=r,n=[{key:"copy",value:function(t){var e=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{container:document.body};return f(t,e)}},{key:"cut",value:function(t){return a(t)}},{key:"isSupported",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof t?[t]:t,e=!!document.queryCommandSupported;return t.forEach(function(t){e=e&&!!document.queryCommandSupported(t)}),e}}],(e=[{key:"resolveOptions",value:function(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===p(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=u()(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget,n=this.action(e)||"copy",t=s({action:n,container:this.container,target:this.target(e),text:this.text(e)});this.emit(t?"success":"error",{action:n,text:t,trigger:e,clearSelection:function(){e&&e.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(t){return m("action",t)}},{key:"defaultTarget",value:function(t){t=m("target",t);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(t){return m("text",t)}},{key:"destroy",value:function(){this.listener.destroy()}}])&&d(t.prototype,e),n&&d(t,n),r}()},828:function(t){var e;"undefined"==typeof Element||Element.prototype.matches||((e=Element.prototype).matches=e.matchesSelector||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector),t.exports=function(t,e){for(;t&&9!==t.nodeType;){if("function"==typeof t.matches&&t.matches(e))return t;t=t.parentNode}}},438:function(t,e,n){var u=n(828);function i(t,e,n,o,r){var i=function(e,n,t,o){return function(t){t.delegateTarget=u(t.target,n),t.delegateTarget&&o.call(e,t)}}.apply(this,arguments);return t.addEventListener(n,i,r),{destroy:function(){t.removeEventListener(n,i,r)}}}t.exports=function(t,e,n,o,r){return"function"==typeof t.addEventListener?i.apply(null,arguments):"function"==typeof n?i.bind(null,document).apply(null,arguments):("string"==typeof t&&(t=document.querySelectorAll(t)),Array.prototype.map.call(t,function(t){return i(t,e,n,o,r)}))}},879:function(t,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){return"[object Function]"===Object.prototype.toString.call(t)}},370:function(t,e,n){var f=n(879),l=n(438);t.exports=function(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!f.string(e))throw new TypeError("Second argument must be a String");if(!f.fn(n))throw new TypeError("Third argument must be a Function");if(f.node(t))return c=e,a=n,(u=t).addEventListener(c,a),{destroy:function(){u.removeEventListener(c,a)}};if(f.nodeList(t))return o=t,r=e,i=n,Array.prototype.forEach.call(o,function(t){t.addEventListener(r,i)}),{destroy:function(){Array.prototype.forEach.call(o,function(t){t.removeEventListener(r,i)})}};if(f.string(t))return t=t,e=e,n=n,l(document.body,t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList");var o,r,i,u,c,a}},817:function(t){t.exports=function(t){var e,n="SELECT"===t.nodeName?(t.focus(),t.value):"INPUT"===t.nodeName||"TEXTAREA"===t.nodeName?((e=t.hasAttribute("readonly"))||t.setAttribute("readonly",""),t.select(),t.setSelectionRange(0,t.value.length),e||t.removeAttribute("readonly"),t.value):(t.hasAttribute("contenteditable")&&t.focus(),n=window.getSelection(),(e=document.createRange()).selectNodeContents(t),n.removeAllRanges(),n.addRange(e),n.toString());return n}},279:function(t){function e(){}e.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){var o=this;function r(){o.off(t,r),e.apply(n,arguments)}return r._=e,this.on(t,r,n)},emit:function(t){for(var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,r=n.length;o<r;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],r=[];if(o&&e)for(var i=0,u=o.length;i<u;i++)o[i].fn!==e&&o[i].fn._!==e&&r.push(o[i]);return r.length?n[t]=r:delete n[t],this}},t.exports=e,t.exports.TinyEmitter=e}},r={},o.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(e,{a:e}),e},o.d=function(t,e){for(var n in e)o.o(e,n)&&!o.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},o.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},o(686).default;function o(t){if(r[t])return r[t].exports;var e=r[t]={exports:{}};return n[t](e,e.exports,o),e.exports}var n,r});
 
 
 
 
 
 
 
 
_site/site_libs/quarto-html/anchor.min.js DELETED
@@ -1,9 +0,0 @@
1
- // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat
2
- //
3
- // AnchorJS - v5.0.0 - 2023-01-18
4
- // https://www.bryanbraun.com/anchorjs/
5
- // Copyright (c) 2023 Bryan Braun; Licensed MIT
6
- //
7
- // @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt Expat
8
- !function(A,e){"use strict";"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&module.exports?module.exports=e():(A.AnchorJS=e(),A.anchors=new A.AnchorJS)}(globalThis,function(){"use strict";return function(A){function u(A){A.icon=Object.prototype.hasOwnProperty.call(A,"icon")?A.icon:"",A.visible=Object.prototype.hasOwnProperty.call(A,"visible")?A.visible:"hover",A.placement=Object.prototype.hasOwnProperty.call(A,"placement")?A.placement:"right",A.ariaLabel=Object.prototype.hasOwnProperty.call(A,"ariaLabel")?A.ariaLabel:"Anchor",A.class=Object.prototype.hasOwnProperty.call(A,"class")?A.class:"",A.base=Object.prototype.hasOwnProperty.call(A,"base")?A.base:"",A.truncate=Object.prototype.hasOwnProperty.call(A,"truncate")?Math.floor(A.truncate):64,A.titleText=Object.prototype.hasOwnProperty.call(A,"titleText")?A.titleText:""}function d(A){var e;if("string"==typeof A||A instanceof String)e=[].slice.call(document.querySelectorAll(A));else{if(!(Array.isArray(A)||A instanceof NodeList))throw new TypeError("The selector provided to AnchorJS was invalid.");e=[].slice.call(A)}return e}this.options=A||{},this.elements=[],u(this.options),this.add=function(A){var e,t,o,i,n,s,a,r,l,c,h,p=[];if(u(this.options),0!==(e=d(A=A||"h2, h3, h4, h5, h6")).length){for(null===document.head.querySelector("style.anchorjs")&&((A=document.createElement("style")).className="anchorjs",A.appendChild(document.createTextNode("")),void 0===(h=document.head.querySelector('[rel="stylesheet"],style'))?document.head.appendChild(A):document.head.insertBefore(A,h),A.sheet.insertRule(".anchorjs-link{opacity:0;text-decoration:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}",A.sheet.cssRules.length),A.sheet.insertRule(":hover>.anchorjs-link,.anchorjs-link:focus{opacity:1}",A.sheet.cssRules.length),A.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",A.sheet.cssRules.length),A.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',A.sheet.cssRules.length)),h=document.querySelectorAll("[id]"),t=[].map.call(h,function(A){return A.id}),i=0;i<e.length;i++)if(this.hasAnchorJSLink(e[i]))p.push(i);else{if(e[i].hasAttribute("id"))o=e[i].getAttribute("id");else if(e[i].hasAttribute("data-anchor-id"))o=e[i].getAttribute("data-anchor-id");else{for(r=a=this.urlify(e[i].textContent),s=0;n=t.indexOf(r=void 0!==n?a+"-"+s:r),s+=1,-1!==n;);n=void 0,t.push(r),e[i].setAttribute("id",r),o=r}(l=document.createElement("a")).className="anchorjs-link "+this.options.class,l.setAttribute("aria-label",this.options.ariaLabel),l.setAttribute("data-anchorjs-icon",this.options.icon),this.options.titleText&&(l.title=this.options.titleText),c=document.querySelector("base")?window.location.pathname+window.location.search:"",c=this.options.base||c,l.href=c+"#"+o,"always"===this.options.visible&&(l.style.opacity="1"),""===this.options.icon&&(l.style.font="1em/1 anchorjs-icons","left"===this.options.placement)&&(l.style.lineHeight="inherit"),"left"===this.options.placement?(l.style.position="absolute",l.style.marginLeft="-1.25em",l.style.paddingRight=".25em",l.style.paddingLeft=".25em",e[i].insertBefore(l,e[i].firstChild)):(l.style.marginLeft=".1875em",l.style.paddingRight=".1875em",l.style.paddingLeft=".1875em",e[i].appendChild(l))}for(i=0;i<p.length;i++)e.splice(p[i]-i,1);this.elements=this.elements.concat(e)}return this},this.remove=function(A){for(var e,t,o=d(A),i=0;i<o.length;i++)(t=o[i].querySelector(".anchorjs-link"))&&(-1!==(e=this.elements.indexOf(o[i]))&&this.elements.splice(e,1),o[i].removeChild(t));return this},this.removeAll=function(){this.remove(this.elements)},this.urlify=function(A){var e=document.createElement("textarea");return e.innerHTML=A,A=e.value,this.options.truncate||u(this.options),A.trim().replace(/'/gi,"").replace(/[& +$,:;=?@"#{}|^~[`%!'<>\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}});
9
- // @license-end
 
 
 
 
 
 
 
 
 
 
_site/site_libs/quarto-html/popper.min.js DELETED
@@ -1,6 +0,0 @@
1
- /**
2
- * @popperjs/core v2.11.7 - MIT License
3
- */
4
-
5
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){"use strict";function t(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function n(e){return e instanceof t(e).Element||e instanceof Element}function r(e){return e instanceof t(e).HTMLElement||e instanceof HTMLElement}function o(e){return"undefined"!=typeof ShadowRoot&&(e instanceof t(e).ShadowRoot||e instanceof ShadowRoot)}var i=Math.max,a=Math.min,s=Math.round;function f(){var e=navigator.userAgentData;return null!=e&&e.brands&&Array.isArray(e.brands)?e.brands.map((function(e){return e.brand+"/"+e.version})).join(" "):navigator.userAgent}function c(){return!/^((?!chrome|android).)*safari/i.test(f())}function p(e,o,i){void 0===o&&(o=!1),void 0===i&&(i=!1);var a=e.getBoundingClientRect(),f=1,p=1;o&&r(e)&&(f=e.offsetWidth>0&&s(a.width)/e.offsetWidth||1,p=e.offsetHeight>0&&s(a.height)/e.offsetHeight||1);var u=(n(e)?t(e):window).visualViewport,l=!c()&&i,d=(a.left+(l&&u?u.offsetLeft:0))/f,h=(a.top+(l&&u?u.offsetTop:0))/p,m=a.width/f,v=a.height/p;return{width:m,height:v,top:h,right:d+m,bottom:h+v,left:d,x:d,y:h}}function u(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function l(e){return e?(e.nodeName||"").toLowerCase():null}function d(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function h(e){return p(d(e)).left+u(e).scrollLeft}function m(e){return t(e).getComputedStyle(e)}function v(e){var t=m(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function y(e,n,o){void 0===o&&(o=!1);var i,a,f=r(n),c=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),m=d(n),y=p(e,c,o),g={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(f||!f&&!o)&&(("body"!==l(n)||v(m))&&(g=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:u(i)),r(n)?((b=p(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):m&&(b.x=h(m))),{x:y.left+g.scrollLeft-b.x,y:y.top+g.scrollTop-b.y,width:y.width,height:y.height}}function g(e){var t=p(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function b(e){return"html"===l(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||d(e)}function x(e){return["html","body","#document"].indexOf(l(e))>=0?e.ownerDocument.body:r(e)&&v(e)?e:x(b(e))}function w(e,n){var r;void 0===n&&(n=[]);var o=x(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],v(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(w(b(s)))}function O(e){return["table","td","th"].indexOf(l(e))>=0}function j(e){return r(e)&&"fixed"!==m(e).position?e.offsetParent:null}function E(e){for(var n=t(e),i=j(e);i&&O(i)&&"static"===m(i).position;)i=j(i);return i&&("html"===l(i)||"body"===l(i)&&"static"===m(i).position)?n:i||function(e){var t=/firefox/i.test(f());if(/Trident/i.test(f())&&r(e)&&"fixed"===m(e).position)return null;var n=b(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(l(n))<0;){var i=m(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||n}var D="top",A="bottom",L="right",P="left",M="auto",k=[D,A,L,P],W="start",B="end",H="viewport",T="popper",R=k.reduce((function(e,t){return e.concat([t+"-"+W,t+"-"+B])}),[]),S=[].concat(k,[M]).reduce((function(e,t){return e.concat([t,t+"-"+W,t+"-"+B])}),[]),V=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function q(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function N(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function I(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function _(e,r,o){return r===H?I(function(e,n){var r=t(e),o=d(e),i=r.visualViewport,a=o.clientWidth,s=o.clientHeight,f=0,p=0;if(i){a=i.width,s=i.height;var u=c();(u||!u&&"fixed"===n)&&(f=i.offsetLeft,p=i.offsetTop)}return{width:a,height:s,x:f+h(e),y:p}}(e,o)):n(r)?function(e,t){var n=p(e,!1,"fixed"===t);return n.top=n.top+e.clientTop,n.left=n.left+e.clientLeft,n.bottom=n.top+e.clientHeight,n.right=n.left+e.clientWidth,n.width=e.clientWidth,n.height=e.clientHeight,n.x=n.left,n.y=n.top,n}(r,o):I(function(e){var t,n=d(e),r=u(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+h(e),c=-r.scrollTop;return"rtl"===m(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:c}}(d(e)))}function F(e,t,o,s){var f="clippingParents"===t?function(e){var t=w(b(e)),o=["absolute","fixed"].indexOf(m(e).position)>=0&&r(e)?E(e):e;return n(o)?t.filter((function(e){return n(e)&&N(e,o)&&"body"!==l(e)})):[]}(e):[].concat(t),c=[].concat(f,[o]),p=c[0],u=c.reduce((function(t,n){var r=_(e,n,s);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),_(e,p,s));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function U(e){return e.split("-")[1]}function z(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function X(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?U(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case D:t={x:s,y:n.y-r.height};break;case A:t={x:s,y:n.y+n.height};break;case L:t={x:n.x+n.width,y:f};break;case P:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?z(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case W:t[c]=t[c]-(n[p]/2-r[p]/2);break;case B:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function Y(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function G(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function J(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.strategy,s=void 0===a?e.strategy:a,f=r.boundary,c=void 0===f?"clippingParents":f,u=r.rootBoundary,l=void 0===u?H:u,h=r.elementContext,m=void 0===h?T:h,v=r.altBoundary,y=void 0!==v&&v,g=r.padding,b=void 0===g?0:g,x=Y("number"!=typeof b?b:G(b,k)),w=m===T?"reference":T,O=e.rects.popper,j=e.elements[y?w:m],E=F(n(j)?j:j.contextElement||d(e.elements.popper),c,l,s),P=p(e.elements.reference),M=X({reference:P,element:O,strategy:"absolute",placement:i}),W=I(Object.assign({},O,M)),B=m===T?W:P,R={top:E.top-B.top+x.top,bottom:B.bottom-E.bottom+x.bottom,left:E.left-B.left+x.left,right:B.right-E.right+x.right},S=e.modifiersData.offset;if(m===T&&S){var V=S[i];Object.keys(R).forEach((function(e){var t=[L,A].indexOf(e)>=0?1:-1,n=[D,A].indexOf(e)>=0?"y":"x";R[e]+=V[n]*t}))}return R}var K={placement:"bottom",modifiers:[],strategy:"absolute"};function Q(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return!t.some((function(e){return!(e&&"function"==typeof e.getBoundingClientRect)}))}function Z(e){void 0===e&&(e={});var t=e,r=t.defaultModifiers,o=void 0===r?[]:r,i=t.defaultOptions,a=void 0===i?K:i;return function(e,t,r){void 0===r&&(r=a);var i,s,f={placement:"bottom",orderedModifiers:[],options:Object.assign({},K,a),modifiersData:{},elements:{reference:e,popper:t},attributes:{},styles:{}},c=[],p=!1,u={state:f,setOptions:function(r){var i="function"==typeof r?r(f.options):r;l(),f.options=Object.assign({},a,f.options,i),f.scrollParents={reference:n(e)?w(e):e.contextElement?w(e.contextElement):[],popper:w(t)};var s,p,d=function(e){var t=q(e);return V.reduce((function(e,n){return e.concat(t.filter((function(e){return e.phase===n})))}),[])}((s=[].concat(o,f.options.modifiers),p=s.reduce((function(e,t){var n=e[t.name];return e[t.name]=n?Object.assign({},n,t,{options:Object.assign({},n.options,t.options),data:Object.assign({},n.data,t.data)}):t,e}),{}),Object.keys(p).map((function(e){return p[e]}))));return f.orderedModifiers=d.filter((function(e){return e.enabled})),f.orderedModifiers.forEach((function(e){var t=e.name,n=e.options,r=void 0===n?{}:n,o=e.effect;if("function"==typeof o){var i=o({state:f,name:t,instance:u,options:r}),a=function(){};c.push(i||a)}})),u.update()},forceUpdate:function(){if(!p){var e=f.elements,t=e.reference,n=e.popper;if(Q(t,n)){f.rects={reference:y(t,E(n),"fixed"===f.options.strategy),popper:g(n)},f.reset=!1,f.placement=f.options.placement,f.orderedModifiers.forEach((function(e){return f.modifiersData[e.name]=Object.assign({},e.data)}));for(var r=0;r<f.orderedModifiers.length;r++)if(!0!==f.reset){var o=f.orderedModifiers[r],i=o.fn,a=o.options,s=void 0===a?{}:a,c=o.name;"function"==typeof i&&(f=i({state:f,options:s,name:c,instance:u})||f)}else f.reset=!1,r=-1}}},update:(i=function(){return new Promise((function(e){u.forceUpdate(),e(f)}))},function(){return s||(s=new Promise((function(e){Promise.resolve().then((function(){s=void 0,e(i())}))}))),s}),destroy:function(){l(),p=!0}};if(!Q(e,t))return u;function l(){c.forEach((function(e){return e()})),c=[]}return u.setOptions(r).then((function(e){!p&&r.onFirstUpdate&&r.onFirstUpdate(e)})),u}}var $={passive:!0};var ee={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(e){var n=e.state,r=e.instance,o=e.options,i=o.scroll,a=void 0===i||i,s=o.resize,f=void 0===s||s,c=t(n.elements.popper),p=[].concat(n.scrollParents.reference,n.scrollParents.popper);return a&&p.forEach((function(e){e.addEventListener("scroll",r.update,$)})),f&&c.addEventListener("resize",r.update,$),function(){a&&p.forEach((function(e){e.removeEventListener("scroll",r.update,$)})),f&&c.removeEventListener("resize",r.update,$)}},data:{}};var te={name:"popperOffsets",enabled:!0,phase:"read",fn:function(e){var t=e.state,n=e.name;t.modifiersData[n]=X({reference:t.rects.reference,element:t.rects.popper,strategy:"absolute",placement:t.placement})},data:{}},ne={top:"auto",right:"auto",bottom:"auto",left:"auto"};function re(e){var n,r=e.popper,o=e.popperRect,i=e.placement,a=e.variation,f=e.offsets,c=e.position,p=e.gpuAcceleration,u=e.adaptive,l=e.roundOffsets,h=e.isFixed,v=f.x,y=void 0===v?0:v,g=f.y,b=void 0===g?0:g,x="function"==typeof l?l({x:y,y:b}):{x:y,y:b};y=x.x,b=x.y;var w=f.hasOwnProperty("x"),O=f.hasOwnProperty("y"),j=P,M=D,k=window;if(u){var W=E(r),H="clientHeight",T="clientWidth";if(W===t(r)&&"static"!==m(W=d(r)).position&&"absolute"===c&&(H="scrollHeight",T="scrollWidth"),W=W,i===D||(i===P||i===L)&&a===B)M=A,b-=(h&&W===k&&k.visualViewport?k.visualViewport.height:W[H])-o.height,b*=p?1:-1;if(i===P||(i===D||i===A)&&a===B)j=L,y-=(h&&W===k&&k.visualViewport?k.visualViewport.width:W[T])-o.width,y*=p?1:-1}var R,S=Object.assign({position:c},u&&ne),V=!0===l?function(e,t){var n=e.x,r=e.y,o=t.devicePixelRatio||1;return{x:s(n*o)/o||0,y:s(r*o)/o||0}}({x:y,y:b},t(r)):{x:y,y:b};return y=V.x,b=V.y,p?Object.assign({},S,((R={})[M]=O?"0":"",R[j]=w?"0":"",R.transform=(k.devicePixelRatio||1)<=1?"translate("+y+"px, "+b+"px)":"translate3d("+y+"px, "+b+"px, 0)",R)):Object.assign({},S,((n={})[M]=O?b+"px":"",n[j]=w?y+"px":"",n.transform="",n))}var oe={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(e){var t=e.state,n=e.options,r=n.gpuAcceleration,o=void 0===r||r,i=n.adaptive,a=void 0===i||i,s=n.roundOffsets,f=void 0===s||s,c={placement:C(t.placement),variation:U(t.placement),popper:t.elements.popper,popperRect:t.rects.popper,gpuAcceleration:o,isFixed:"fixed"===t.options.strategy};null!=t.modifiersData.popperOffsets&&(t.styles.popper=Object.assign({},t.styles.popper,re(Object.assign({},c,{offsets:t.modifiersData.popperOffsets,position:t.options.strategy,adaptive:a,roundOffsets:f})))),null!=t.modifiersData.arrow&&(t.styles.arrow=Object.assign({},t.styles.arrow,re(Object.assign({},c,{offsets:t.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:f})))),t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-placement":t.placement})},data:{}};var ie={name:"applyStyles",enabled:!0,phase:"write",fn:function(e){var t=e.state;Object.keys(t.elements).forEach((function(e){var n=t.styles[e]||{},o=t.attributes[e]||{},i=t.elements[e];r(i)&&l(i)&&(Object.assign(i.style,n),Object.keys(o).forEach((function(e){var t=o[e];!1===t?i.removeAttribute(e):i.setAttribute(e,!0===t?"":t)})))}))},effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow),function(){Object.keys(t.elements).forEach((function(e){var o=t.elements[e],i=t.attributes[e]||{},a=Object.keys(t.styles.hasOwnProperty(e)?t.styles[e]:n[e]).reduce((function(e,t){return e[t]="",e}),{});r(o)&&l(o)&&(Object.assign(o.style,a),Object.keys(i).forEach((function(e){o.removeAttribute(e)})))}))}},requires:["computeStyles"]};var ae={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.offset,i=void 0===o?[0,0]:o,a=S.reduce((function(e,n){return e[n]=function(e,t,n){var r=C(e),o=[P,D].indexOf(r)>=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[P,L].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},se={left:"right",right:"left",bottom:"top",top:"bottom"};function fe(e){return e.replace(/left|right|bottom|top/g,(function(e){return se[e]}))}var ce={start:"end",end:"start"};function pe(e){return e.replace(/start|end/g,(function(e){return ce[e]}))}function ue(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?S:f,p=U(r),u=p?s?R:R.filter((function(e){return U(e)===p})):k,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=J(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var le={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,y=C(v),g=f||(y===v||!h?[fe(v)]:function(e){if(C(e)===M)return[];var t=fe(e);return[pe(e),t,pe(t)]}(v)),b=[v].concat(g).reduce((function(e,n){return e.concat(C(n)===M?ue(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,j=!0,E=b[0],k=0;k<b.length;k++){var B=b[k],H=C(B),T=U(B)===W,R=[D,A].indexOf(H)>=0,S=R?"width":"height",V=J(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),q=R?T?L:P:T?A:D;x[S]>w[S]&&(q=fe(q));var N=fe(q),I=[];if(i&&I.push(V[H]<=0),s&&I.push(V[q]<=0,V[N]<=0),I.every((function(e){return e}))){E=B,j=!1;break}O.set(B,I)}if(j)for(var _=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return E=t,"break"},F=h?3:1;F>0;F--){if("break"===_(F))break}t.placement!==E&&(t.modifiersData[r]._skip=!0,t.placement=E,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function de(e,t,n){return i(e,a(t,n))}var he={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,v=n.tetherOffset,y=void 0===v?0:v,b=J(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=U(t.placement),O=!w,j=z(x),M="x"===j?"y":"x",k=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,V={x:0,y:0};if(k){if(s){var q,N="y"===j?D:P,I="y"===j?A:L,_="y"===j?"height":"width",F=k[j],X=F+b[N],Y=F-b[I],G=m?-H[_]/2:0,K=w===W?B[_]:H[_],Q=w===W?-H[_]:-B[_],Z=t.elements.arrow,$=m&&Z?g(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=de(0,B[_],$[_]),oe=O?B[_]/2-G-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=O?-B[_]/2+G+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&E(t.elements.arrow),se=ae?"y"===j?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(q=null==S?void 0:S[j])?q:0,ce=F+ie-fe,pe=de(m?a(X,F+oe-fe-se):X,F,m?i(Y,ce):Y);k[j]=pe,V[j]=pe-F}if(c){var ue,le="x"===j?D:P,he="x"===j?A:L,me=k[M],ve="y"===M?"height":"width",ye=me+b[le],ge=me-b[he],be=-1!==[D,P].indexOf(x),xe=null!=(ue=null==S?void 0:S[M])?ue:0,we=be?ye:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ge,je=m&&be?function(e,t,n){var r=de(e,t,n);return r>n?n:r}(we,me,Oe):de(m?we:ye,me,m?Oe:ge);k[M]=je,V[M]=je-me}t.modifiersData[r]=V}},requiresIfExists:["offset"]};var me={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=z(s),c=[P,L].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return Y("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:G(e,k))}(o.padding,n),u=g(i),l="y"===f?D:P,d="y"===f?A:L,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],v=E(i),y=v?"y"===f?v.clientHeight||0:v.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],O=y/2-u[c]/2+b,j=de(x,O,w),M=f;n.modifiersData[r]=((t={})[M]=j,t.centerOffset=j-O,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&N(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ve(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function ye(e){return[D,L,A,P].some((function(t){return e[t]>=0}))}var ge={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=J(t,{elementContext:"reference"}),s=J(t,{altBoundary:!0}),f=ve(a,r),c=ve(s,o,i),p=ye(f),u=ye(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},be=Z({defaultModifiers:[ee,te,oe,ie]}),xe=[ee,te,oe,ie,ae,le,he,me,ge],we=Z({defaultModifiers:xe});e.applyStyles=ie,e.arrow=me,e.computeStyles=oe,e.createPopper=we,e.createPopperLite=be,e.defaultModifiers=xe,e.detectOverflow=J,e.eventListeners=ee,e.flip=le,e.hide=ge,e.offset=ae,e.popperGenerator=Z,e.popperOffsets=te,e.preventOverflow=he,Object.defineProperty(e,"__esModule",{value:!0})}));
6
-
 
 
 
 
 
 
 
_site/site_libs/quarto-html/quarto-syntax-highlighting.css DELETED
@@ -1,203 +0,0 @@
1
- /* quarto syntax highlight colors */
2
- :root {
3
- --quarto-hl-ot-color: #003B4F;
4
- --quarto-hl-at-color: #657422;
5
- --quarto-hl-ss-color: #20794D;
6
- --quarto-hl-an-color: #5E5E5E;
7
- --quarto-hl-fu-color: #4758AB;
8
- --quarto-hl-st-color: #20794D;
9
- --quarto-hl-cf-color: #003B4F;
10
- --quarto-hl-op-color: #5E5E5E;
11
- --quarto-hl-er-color: #AD0000;
12
- --quarto-hl-bn-color: #AD0000;
13
- --quarto-hl-al-color: #AD0000;
14
- --quarto-hl-va-color: #111111;
15
- --quarto-hl-bu-color: inherit;
16
- --quarto-hl-ex-color: inherit;
17
- --quarto-hl-pp-color: #AD0000;
18
- --quarto-hl-in-color: #5E5E5E;
19
- --quarto-hl-vs-color: #20794D;
20
- --quarto-hl-wa-color: #5E5E5E;
21
- --quarto-hl-do-color: #5E5E5E;
22
- --quarto-hl-im-color: #00769E;
23
- --quarto-hl-ch-color: #20794D;
24
- --quarto-hl-dt-color: #AD0000;
25
- --quarto-hl-fl-color: #AD0000;
26
- --quarto-hl-co-color: #5E5E5E;
27
- --quarto-hl-cv-color: #5E5E5E;
28
- --quarto-hl-cn-color: #8f5902;
29
- --quarto-hl-sc-color: #5E5E5E;
30
- --quarto-hl-dv-color: #AD0000;
31
- --quarto-hl-kw-color: #003B4F;
32
- }
33
-
34
- /* other quarto variables */
35
- :root {
36
- --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
37
- }
38
-
39
- pre > code.sourceCode > span {
40
- color: #003B4F;
41
- }
42
-
43
- code span {
44
- color: #003B4F;
45
- }
46
-
47
- code.sourceCode > span {
48
- color: #003B4F;
49
- }
50
-
51
- div.sourceCode,
52
- div.sourceCode pre.sourceCode {
53
- color: #003B4F;
54
- }
55
-
56
- code span.ot {
57
- color: #003B4F;
58
- font-style: inherit;
59
- }
60
-
61
- code span.at {
62
- color: #657422;
63
- font-style: inherit;
64
- }
65
-
66
- code span.ss {
67
- color: #20794D;
68
- font-style: inherit;
69
- }
70
-
71
- code span.an {
72
- color: #5E5E5E;
73
- font-style: inherit;
74
- }
75
-
76
- code span.fu {
77
- color: #4758AB;
78
- font-style: inherit;
79
- }
80
-
81
- code span.st {
82
- color: #20794D;
83
- font-style: inherit;
84
- }
85
-
86
- code span.cf {
87
- color: #003B4F;
88
- font-style: inherit;
89
- }
90
-
91
- code span.op {
92
- color: #5E5E5E;
93
- font-style: inherit;
94
- }
95
-
96
- code span.er {
97
- color: #AD0000;
98
- font-style: inherit;
99
- }
100
-
101
- code span.bn {
102
- color: #AD0000;
103
- font-style: inherit;
104
- }
105
-
106
- code span.al {
107
- color: #AD0000;
108
- font-style: inherit;
109
- }
110
-
111
- code span.va {
112
- color: #111111;
113
- font-style: inherit;
114
- }
115
-
116
- code span.bu {
117
- font-style: inherit;
118
- }
119
-
120
- code span.ex {
121
- font-style: inherit;
122
- }
123
-
124
- code span.pp {
125
- color: #AD0000;
126
- font-style: inherit;
127
- }
128
-
129
- code span.in {
130
- color: #5E5E5E;
131
- font-style: inherit;
132
- }
133
-
134
- code span.vs {
135
- color: #20794D;
136
- font-style: inherit;
137
- }
138
-
139
- code span.wa {
140
- color: #5E5E5E;
141
- font-style: italic;
142
- }
143
-
144
- code span.do {
145
- color: #5E5E5E;
146
- font-style: italic;
147
- }
148
-
149
- code span.im {
150
- color: #00769E;
151
- font-style: inherit;
152
- }
153
-
154
- code span.ch {
155
- color: #20794D;
156
- font-style: inherit;
157
- }
158
-
159
- code span.dt {
160
- color: #AD0000;
161
- font-style: inherit;
162
- }
163
-
164
- code span.fl {
165
- color: #AD0000;
166
- font-style: inherit;
167
- }
168
-
169
- code span.co {
170
- color: #5E5E5E;
171
- font-style: inherit;
172
- }
173
-
174
- code span.cv {
175
- color: #5E5E5E;
176
- font-style: italic;
177
- }
178
-
179
- code span.cn {
180
- color: #8f5902;
181
- font-style: inherit;
182
- }
183
-
184
- code span.sc {
185
- color: #5E5E5E;
186
- font-style: inherit;
187
- }
188
-
189
- code span.dv {
190
- color: #AD0000;
191
- font-style: inherit;
192
- }
193
-
194
- code span.kw {
195
- color: #003B4F;
196
- font-style: inherit;
197
- }
198
-
199
- .prevent-inlining {
200
- content: "</";
201
- }
202
-
203
- /*# sourceMappingURL=debc5d5d77c3f9108843748ff7464032.css.map */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/site_libs/quarto-html/quarto.js DELETED
@@ -1,899 +0,0 @@
1
- const sectionChanged = new CustomEvent("quarto-sectionChanged", {
2
- detail: {},
3
- bubbles: true,
4
- cancelable: false,
5
- composed: false,
6
- });
7
-
8
- const layoutMarginEls = () => {
9
- // Find any conflicting margin elements and add margins to the
10
- // top to prevent overlap
11
- const marginChildren = window.document.querySelectorAll(
12
- ".column-margin.column-container > *, .margin-caption, .aside"
13
- );
14
-
15
- let lastBottom = 0;
16
- for (const marginChild of marginChildren) {
17
- if (marginChild.offsetParent !== null) {
18
- // clear the top margin so we recompute it
19
- marginChild.style.marginTop = null;
20
- const top = marginChild.getBoundingClientRect().top + window.scrollY;
21
- if (top < lastBottom) {
22
- const marginChildStyle = window.getComputedStyle(marginChild);
23
- const marginBottom = parseFloat(marginChildStyle["marginBottom"]);
24
- const margin = lastBottom - top + marginBottom;
25
- marginChild.style.marginTop = `${margin}px`;
26
- }
27
- const styles = window.getComputedStyle(marginChild);
28
- const marginTop = parseFloat(styles["marginTop"]);
29
- lastBottom = top + marginChild.getBoundingClientRect().height + marginTop;
30
- }
31
- }
32
- };
33
-
34
- window.document.addEventListener("DOMContentLoaded", function (_event) {
35
- // Recompute the position of margin elements anytime the body size changes
36
- if (window.ResizeObserver) {
37
- const resizeObserver = new window.ResizeObserver(
38
- throttle(() => {
39
- layoutMarginEls();
40
- if (
41
- window.document.body.getBoundingClientRect().width < 990 &&
42
- isReaderMode()
43
- ) {
44
- quartoToggleReader();
45
- }
46
- }, 50)
47
- );
48
- resizeObserver.observe(window.document.body);
49
- }
50
-
51
- const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]');
52
- const sidebarEl = window.document.getElementById("quarto-sidebar");
53
- const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left");
54
- const marginSidebarEl = window.document.getElementById(
55
- "quarto-margin-sidebar"
56
- );
57
- // function to determine whether the element has a previous sibling that is active
58
- const prevSiblingIsActiveLink = (el) => {
59
- const sibling = el.previousElementSibling;
60
- if (sibling && sibling.tagName === "A") {
61
- return sibling.classList.contains("active");
62
- } else {
63
- return false;
64
- }
65
- };
66
-
67
- // fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior)
68
- function fireSlideEnter(e) {
69
- const event = window.document.createEvent("Event");
70
- event.initEvent("slideenter", true, true);
71
- window.document.dispatchEvent(event);
72
- }
73
- const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
74
- tabs.forEach((tab) => {
75
- tab.addEventListener("shown.bs.tab", fireSlideEnter);
76
- });
77
-
78
- // fire slideEnter for tabby tab activations (for htmlwidget resize behavior)
79
- document.addEventListener("tabby", fireSlideEnter, false);
80
-
81
- // Track scrolling and mark TOC links as active
82
- // get table of contents and sidebar (bail if we don't have at least one)
83
- const tocLinks = tocEl
84
- ? [...tocEl.querySelectorAll("a[data-scroll-target]")]
85
- : [];
86
- const makeActive = (link) => tocLinks[link].classList.add("active");
87
- const removeActive = (link) => tocLinks[link].classList.remove("active");
88
- const removeAllActive = () =>
89
- [...Array(tocLinks.length).keys()].forEach((link) => removeActive(link));
90
-
91
- // activate the anchor for a section associated with this TOC entry
92
- tocLinks.forEach((link) => {
93
- link.addEventListener("click", () => {
94
- if (link.href.indexOf("#") !== -1) {
95
- const anchor = link.href.split("#")[1];
96
- const heading = window.document.querySelector(
97
- `[data-anchor-id=${anchor}]`
98
- );
99
- if (heading) {
100
- // Add the class
101
- heading.classList.add("reveal-anchorjs-link");
102
-
103
- // function to show the anchor
104
- const handleMouseout = () => {
105
- heading.classList.remove("reveal-anchorjs-link");
106
- heading.removeEventListener("mouseout", handleMouseout);
107
- };
108
-
109
- // add a function to clear the anchor when the user mouses out of it
110
- heading.addEventListener("mouseout", handleMouseout);
111
- }
112
- }
113
- });
114
- });
115
-
116
- const sections = tocLinks.map((link) => {
117
- const target = link.getAttribute("data-scroll-target");
118
- if (target.startsWith("#")) {
119
- return window.document.getElementById(decodeURI(`${target.slice(1)}`));
120
- } else {
121
- return window.document.querySelector(decodeURI(`${target}`));
122
- }
123
- });
124
-
125
- const sectionMargin = 200;
126
- let currentActive = 0;
127
- // track whether we've initialized state the first time
128
- let init = false;
129
-
130
- const updateActiveLink = () => {
131
- // The index from bottom to top (e.g. reversed list)
132
- let sectionIndex = -1;
133
- if (
134
- window.innerHeight + window.pageYOffset >=
135
- window.document.body.offsetHeight
136
- ) {
137
- sectionIndex = 0;
138
- } else {
139
- sectionIndex = [...sections].reverse().findIndex((section) => {
140
- if (section) {
141
- return window.pageYOffset >= section.offsetTop - sectionMargin;
142
- } else {
143
- return false;
144
- }
145
- });
146
- }
147
- if (sectionIndex > -1) {
148
- const current = sections.length - sectionIndex - 1;
149
- if (current !== currentActive) {
150
- removeAllActive();
151
- currentActive = current;
152
- makeActive(current);
153
- if (init) {
154
- window.dispatchEvent(sectionChanged);
155
- }
156
- init = true;
157
- }
158
- }
159
- };
160
-
161
- const inHiddenRegion = (top, bottom, hiddenRegions) => {
162
- for (const region of hiddenRegions) {
163
- if (top <= region.bottom && bottom >= region.top) {
164
- return true;
165
- }
166
- }
167
- return false;
168
- };
169
-
170
- const categorySelector = "header.quarto-title-block .quarto-category";
171
- const activateCategories = (href) => {
172
- // Find any categories
173
- // Surround them with a link pointing back to:
174
- // #category=Authoring
175
- try {
176
- const categoryEls = window.document.querySelectorAll(categorySelector);
177
- for (const categoryEl of categoryEls) {
178
- const categoryText = categoryEl.textContent;
179
- if (categoryText) {
180
- const link = `${href}#category=${encodeURIComponent(categoryText)}`;
181
- const linkEl = window.document.createElement("a");
182
- linkEl.setAttribute("href", link);
183
- for (const child of categoryEl.childNodes) {
184
- linkEl.append(child);
185
- }
186
- categoryEl.appendChild(linkEl);
187
- }
188
- }
189
- } catch {
190
- // Ignore errors
191
- }
192
- };
193
- function hasTitleCategories() {
194
- return window.document.querySelector(categorySelector) !== null;
195
- }
196
-
197
- function offsetRelativeUrl(url) {
198
- const offset = getMeta("quarto:offset");
199
- return offset ? offset + url : url;
200
- }
201
-
202
- function offsetAbsoluteUrl(url) {
203
- const offset = getMeta("quarto:offset");
204
- const baseUrl = new URL(offset, window.location);
205
-
206
- const projRelativeUrl = url.replace(baseUrl, "");
207
- if (projRelativeUrl.startsWith("/")) {
208
- return projRelativeUrl;
209
- } else {
210
- return "/" + projRelativeUrl;
211
- }
212
- }
213
-
214
- // read a meta tag value
215
- function getMeta(metaName) {
216
- const metas = window.document.getElementsByTagName("meta");
217
- for (let i = 0; i < metas.length; i++) {
218
- if (metas[i].getAttribute("name") === metaName) {
219
- return metas[i].getAttribute("content");
220
- }
221
- }
222
- return "";
223
- }
224
-
225
- async function findAndActivateCategories() {
226
- const currentPagePath = offsetAbsoluteUrl(window.location.href);
227
- const response = await fetch(offsetRelativeUrl("listings.json"));
228
- if (response.status == 200) {
229
- return response.json().then(function (listingPaths) {
230
- const listingHrefs = [];
231
- for (const listingPath of listingPaths) {
232
- const pathWithoutLeadingSlash = listingPath.listing.substring(1);
233
- for (const item of listingPath.items) {
234
- if (
235
- item === currentPagePath ||
236
- item === currentPagePath + "index.html"
237
- ) {
238
- // Resolve this path against the offset to be sure
239
- // we already are using the correct path to the listing
240
- // (this adjusts the listing urls to be rooted against
241
- // whatever root the page is actually running against)
242
- const relative = offsetRelativeUrl(pathWithoutLeadingSlash);
243
- const baseUrl = window.location;
244
- const resolvedPath = new URL(relative, baseUrl);
245
- listingHrefs.push(resolvedPath.pathname);
246
- break;
247
- }
248
- }
249
- }
250
-
251
- // Look up the tree for a nearby linting and use that if we find one
252
- const nearestListing = findNearestParentListing(
253
- offsetAbsoluteUrl(window.location.pathname),
254
- listingHrefs
255
- );
256
- if (nearestListing) {
257
- activateCategories(nearestListing);
258
- } else {
259
- // See if the referrer is a listing page for this item
260
- const referredRelativePath = offsetAbsoluteUrl(document.referrer);
261
- const referrerListing = listingHrefs.find((listingHref) => {
262
- const isListingReferrer =
263
- listingHref === referredRelativePath ||
264
- listingHref === referredRelativePath + "index.html";
265
- return isListingReferrer;
266
- });
267
-
268
- if (referrerListing) {
269
- // Try to use the referrer if possible
270
- activateCategories(referrerListing);
271
- } else if (listingHrefs.length > 0) {
272
- // Otherwise, just fall back to the first listing
273
- activateCategories(listingHrefs[0]);
274
- }
275
- }
276
- });
277
- }
278
- }
279
- if (hasTitleCategories()) {
280
- findAndActivateCategories();
281
- }
282
-
283
- const findNearestParentListing = (href, listingHrefs) => {
284
- if (!href || !listingHrefs) {
285
- return undefined;
286
- }
287
- // Look up the tree for a nearby linting and use that if we find one
288
- const relativeParts = href.substring(1).split("/");
289
- while (relativeParts.length > 0) {
290
- const path = relativeParts.join("/");
291
- for (const listingHref of listingHrefs) {
292
- if (listingHref.startsWith(path)) {
293
- return listingHref;
294
- }
295
- }
296
- relativeParts.pop();
297
- }
298
-
299
- return undefined;
300
- };
301
-
302
- const manageSidebarVisiblity = (el, placeholderDescriptor) => {
303
- let isVisible = true;
304
- let elRect;
305
-
306
- return (hiddenRegions) => {
307
- if (el === null) {
308
- return;
309
- }
310
-
311
- // Find the last element of the TOC
312
- const lastChildEl = el.lastElementChild;
313
-
314
- if (lastChildEl) {
315
- // Converts the sidebar to a menu
316
- const convertToMenu = () => {
317
- for (const child of el.children) {
318
- child.style.opacity = 0;
319
- child.style.overflow = "hidden";
320
- }
321
-
322
- nexttick(() => {
323
- const toggleContainer = window.document.createElement("div");
324
- toggleContainer.style.width = "100%";
325
- toggleContainer.classList.add("zindex-over-content");
326
- toggleContainer.classList.add("quarto-sidebar-toggle");
327
- toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom
328
- toggleContainer.id = placeholderDescriptor.id;
329
- toggleContainer.style.position = "fixed";
330
-
331
- const toggleIcon = window.document.createElement("i");
332
- toggleIcon.classList.add("quarto-sidebar-toggle-icon");
333
- toggleIcon.classList.add("bi");
334
- toggleIcon.classList.add("bi-caret-down-fill");
335
-
336
- const toggleTitle = window.document.createElement("div");
337
- const titleEl = window.document.body.querySelector(
338
- placeholderDescriptor.titleSelector
339
- );
340
- if (titleEl) {
341
- toggleTitle.append(
342
- titleEl.textContent || titleEl.innerText,
343
- toggleIcon
344
- );
345
- }
346
- toggleTitle.classList.add("zindex-over-content");
347
- toggleTitle.classList.add("quarto-sidebar-toggle-title");
348
- toggleContainer.append(toggleTitle);
349
-
350
- const toggleContents = window.document.createElement("div");
351
- toggleContents.classList = el.classList;
352
- toggleContents.classList.add("zindex-over-content");
353
- toggleContents.classList.add("quarto-sidebar-toggle-contents");
354
- for (const child of el.children) {
355
- if (child.id === "toc-title") {
356
- continue;
357
- }
358
-
359
- const clone = child.cloneNode(true);
360
- clone.style.opacity = 1;
361
- clone.style.display = null;
362
- toggleContents.append(clone);
363
- }
364
- toggleContents.style.height = "0px";
365
- const positionToggle = () => {
366
- // position the element (top left of parent, same width as parent)
367
- if (!elRect) {
368
- elRect = el.getBoundingClientRect();
369
- }
370
- toggleContainer.style.left = `${elRect.left}px`;
371
- toggleContainer.style.top = `${elRect.top}px`;
372
- toggleContainer.style.width = `${elRect.width}px`;
373
- };
374
- positionToggle();
375
-
376
- toggleContainer.append(toggleContents);
377
- el.parentElement.prepend(toggleContainer);
378
-
379
- // Process clicks
380
- let tocShowing = false;
381
- // Allow the caller to control whether this is dismissed
382
- // when it is clicked (e.g. sidebar navigation supports
383
- // opening and closing the nav tree, so don't dismiss on click)
384
- const clickEl = placeholderDescriptor.dismissOnClick
385
- ? toggleContainer
386
- : toggleTitle;
387
-
388
- const closeToggle = () => {
389
- if (tocShowing) {
390
- toggleContainer.classList.remove("expanded");
391
- toggleContents.style.height = "0px";
392
- tocShowing = false;
393
- }
394
- };
395
-
396
- // Get rid of any expanded toggle if the user scrolls
397
- window.document.addEventListener(
398
- "scroll",
399
- throttle(() => {
400
- closeToggle();
401
- }, 50)
402
- );
403
-
404
- // Handle positioning of the toggle
405
- window.addEventListener(
406
- "resize",
407
- throttle(() => {
408
- elRect = undefined;
409
- positionToggle();
410
- }, 50)
411
- );
412
-
413
- window.addEventListener("quarto-hrChanged", () => {
414
- elRect = undefined;
415
- });
416
-
417
- // Process the click
418
- clickEl.onclick = () => {
419
- if (!tocShowing) {
420
- toggleContainer.classList.add("expanded");
421
- toggleContents.style.height = null;
422
- tocShowing = true;
423
- } else {
424
- closeToggle();
425
- }
426
- };
427
- });
428
- };
429
-
430
- // Converts a sidebar from a menu back to a sidebar
431
- const convertToSidebar = () => {
432
- for (const child of el.children) {
433
- child.style.opacity = 1;
434
- child.style.overflow = null;
435
- }
436
-
437
- const placeholderEl = window.document.getElementById(
438
- placeholderDescriptor.id
439
- );
440
- if (placeholderEl) {
441
- placeholderEl.remove();
442
- }
443
-
444
- el.classList.remove("rollup");
445
- };
446
-
447
- if (isReaderMode()) {
448
- convertToMenu();
449
- isVisible = false;
450
- } else {
451
- // Find the top and bottom o the element that is being managed
452
- const elTop = el.offsetTop;
453
- const elBottom =
454
- elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight;
455
-
456
- if (!isVisible) {
457
- // If the element is current not visible reveal if there are
458
- // no conflicts with overlay regions
459
- if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) {
460
- convertToSidebar();
461
- isVisible = true;
462
- }
463
- } else {
464
- // If the element is visible, hide it if it conflicts with overlay regions
465
- // and insert a placeholder toggle (or if we're in reader mode)
466
- if (inHiddenRegion(elTop, elBottom, hiddenRegions)) {
467
- convertToMenu();
468
- isVisible = false;
469
- }
470
- }
471
- }
472
- }
473
- };
474
- };
475
-
476
- const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]');
477
- for (const tabEl of tabEls) {
478
- const id = tabEl.getAttribute("data-bs-target");
479
- if (id) {
480
- const columnEl = document.querySelector(
481
- `${id} .column-margin, .tabset-margin-content`
482
- );
483
- if (columnEl)
484
- tabEl.addEventListener("shown.bs.tab", function (event) {
485
- const el = event.srcElement;
486
- if (el) {
487
- const visibleCls = `${el.id}-margin-content`;
488
- // walk up until we find a parent tabset
489
- let panelTabsetEl = el.parentElement;
490
- while (panelTabsetEl) {
491
- if (panelTabsetEl.classList.contains("panel-tabset")) {
492
- break;
493
- }
494
- panelTabsetEl = panelTabsetEl.parentElement;
495
- }
496
-
497
- if (panelTabsetEl) {
498
- const prevSib = panelTabsetEl.previousElementSibling;
499
- if (
500
- prevSib &&
501
- prevSib.classList.contains("tabset-margin-container")
502
- ) {
503
- const childNodes = prevSib.querySelectorAll(
504
- ".tabset-margin-content"
505
- );
506
- for (const childEl of childNodes) {
507
- if (childEl.classList.contains(visibleCls)) {
508
- childEl.classList.remove("collapse");
509
- } else {
510
- childEl.classList.add("collapse");
511
- }
512
- }
513
- }
514
- }
515
- }
516
-
517
- layoutMarginEls();
518
- });
519
- }
520
- }
521
-
522
- // Manage the visibility of the toc and the sidebar
523
- const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, {
524
- id: "quarto-toc-toggle",
525
- titleSelector: "#toc-title",
526
- dismissOnClick: true,
527
- });
528
- const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, {
529
- id: "quarto-sidebarnav-toggle",
530
- titleSelector: ".title",
531
- dismissOnClick: false,
532
- });
533
- let tocLeftScrollVisibility;
534
- if (leftTocEl) {
535
- tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, {
536
- id: "quarto-lefttoc-toggle",
537
- titleSelector: "#toc-title",
538
- dismissOnClick: true,
539
- });
540
- }
541
-
542
- // Find the first element that uses formatting in special columns
543
- const conflictingEls = window.document.body.querySelectorAll(
544
- '[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]'
545
- );
546
-
547
- // Filter all the possibly conflicting elements into ones
548
- // the do conflict on the left or ride side
549
- const arrConflictingEls = Array.from(conflictingEls);
550
- const leftSideConflictEls = arrConflictingEls.filter((el) => {
551
- if (el.tagName === "ASIDE") {
552
- return false;
553
- }
554
- return Array.from(el.classList).find((className) => {
555
- return (
556
- className !== "column-body" &&
557
- className.startsWith("column-") &&
558
- !className.endsWith("right") &&
559
- !className.endsWith("container") &&
560
- className !== "column-margin"
561
- );
562
- });
563
- });
564
- const rightSideConflictEls = arrConflictingEls.filter((el) => {
565
- if (el.tagName === "ASIDE") {
566
- return true;
567
- }
568
-
569
- const hasMarginCaption = Array.from(el.classList).find((className) => {
570
- return className == "margin-caption";
571
- });
572
- if (hasMarginCaption) {
573
- return true;
574
- }
575
-
576
- return Array.from(el.classList).find((className) => {
577
- return (
578
- className !== "column-body" &&
579
- !className.endsWith("container") &&
580
- className.startsWith("column-") &&
581
- !className.endsWith("left")
582
- );
583
- });
584
- });
585
-
586
- const kOverlapPaddingSize = 10;
587
- function toRegions(els) {
588
- return els.map((el) => {
589
- const boundRect = el.getBoundingClientRect();
590
- const top =
591
- boundRect.top +
592
- document.documentElement.scrollTop -
593
- kOverlapPaddingSize;
594
- return {
595
- top,
596
- bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize,
597
- };
598
- });
599
- }
600
-
601
- let hasObserved = false;
602
- const visibleItemObserver = (els) => {
603
- let visibleElements = [...els];
604
- const intersectionObserver = new IntersectionObserver(
605
- (entries, _observer) => {
606
- entries.forEach((entry) => {
607
- if (entry.isIntersecting) {
608
- if (visibleElements.indexOf(entry.target) === -1) {
609
- visibleElements.push(entry.target);
610
- }
611
- } else {
612
- visibleElements = visibleElements.filter((visibleEntry) => {
613
- return visibleEntry !== entry;
614
- });
615
- }
616
- });
617
-
618
- if (!hasObserved) {
619
- hideOverlappedSidebars();
620
- }
621
- hasObserved = true;
622
- },
623
- {}
624
- );
625
- els.forEach((el) => {
626
- intersectionObserver.observe(el);
627
- });
628
-
629
- return {
630
- getVisibleEntries: () => {
631
- return visibleElements;
632
- },
633
- };
634
- };
635
-
636
- const rightElementObserver = visibleItemObserver(rightSideConflictEls);
637
- const leftElementObserver = visibleItemObserver(leftSideConflictEls);
638
-
639
- const hideOverlappedSidebars = () => {
640
- marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries()));
641
- sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries()));
642
- if (tocLeftScrollVisibility) {
643
- tocLeftScrollVisibility(
644
- toRegions(leftElementObserver.getVisibleEntries())
645
- );
646
- }
647
- };
648
-
649
- window.quartoToggleReader = () => {
650
- // Applies a slow class (or removes it)
651
- // to update the transition speed
652
- const slowTransition = (slow) => {
653
- const manageTransition = (id, slow) => {
654
- const el = document.getElementById(id);
655
- if (el) {
656
- if (slow) {
657
- el.classList.add("slow");
658
- } else {
659
- el.classList.remove("slow");
660
- }
661
- }
662
- };
663
-
664
- manageTransition("TOC", slow);
665
- manageTransition("quarto-sidebar", slow);
666
- };
667
- const readerMode = !isReaderMode();
668
- setReaderModeValue(readerMode);
669
-
670
- // If we're entering reader mode, slow the transition
671
- if (readerMode) {
672
- slowTransition(readerMode);
673
- }
674
- highlightReaderToggle(readerMode);
675
- hideOverlappedSidebars();
676
-
677
- // If we're exiting reader mode, restore the non-slow transition
678
- if (!readerMode) {
679
- slowTransition(!readerMode);
680
- }
681
- };
682
-
683
- const highlightReaderToggle = (readerMode) => {
684
- const els = document.querySelectorAll(".quarto-reader-toggle");
685
- if (els) {
686
- els.forEach((el) => {
687
- if (readerMode) {
688
- el.classList.add("reader");
689
- } else {
690
- el.classList.remove("reader");
691
- }
692
- });
693
- }
694
- };
695
-
696
- const setReaderModeValue = (val) => {
697
- if (window.location.protocol !== "file:") {
698
- window.localStorage.setItem("quarto-reader-mode", val);
699
- } else {
700
- localReaderMode = val;
701
- }
702
- };
703
-
704
- const isReaderMode = () => {
705
- if (window.location.protocol !== "file:") {
706
- return window.localStorage.getItem("quarto-reader-mode") === "true";
707
- } else {
708
- return localReaderMode;
709
- }
710
- };
711
- let localReaderMode = null;
712
-
713
- const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded");
714
- const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1;
715
-
716
- // Walk the TOC and collapse/expand nodes
717
- // Nodes are expanded if:
718
- // - they are top level
719
- // - they have children that are 'active' links
720
- // - they are directly below an link that is 'active'
721
- const walk = (el, depth) => {
722
- // Tick depth when we enter a UL
723
- if (el.tagName === "UL") {
724
- depth = depth + 1;
725
- }
726
-
727
- // It this is active link
728
- let isActiveNode = false;
729
- if (el.tagName === "A" && el.classList.contains("active")) {
730
- isActiveNode = true;
731
- }
732
-
733
- // See if there is an active child to this element
734
- let hasActiveChild = false;
735
- for (child of el.children) {
736
- hasActiveChild = walk(child, depth) || hasActiveChild;
737
- }
738
-
739
- // Process the collapse state if this is an UL
740
- if (el.tagName === "UL") {
741
- if (tocOpenDepth === -1 && depth > 1) {
742
- el.classList.add("collapse");
743
- } else if (
744
- depth <= tocOpenDepth ||
745
- hasActiveChild ||
746
- prevSiblingIsActiveLink(el)
747
- ) {
748
- el.classList.remove("collapse");
749
- } else {
750
- el.classList.add("collapse");
751
- }
752
-
753
- // untick depth when we leave a UL
754
- depth = depth - 1;
755
- }
756
- return hasActiveChild || isActiveNode;
757
- };
758
-
759
- // walk the TOC and expand / collapse any items that should be shown
760
-
761
- if (tocEl) {
762
- walk(tocEl, 0);
763
- updateActiveLink();
764
- }
765
-
766
- // Throttle the scroll event and walk peridiocally
767
- window.document.addEventListener(
768
- "scroll",
769
- throttle(() => {
770
- if (tocEl) {
771
- updateActiveLink();
772
- walk(tocEl, 0);
773
- }
774
- if (!isReaderMode()) {
775
- hideOverlappedSidebars();
776
- }
777
- }, 5)
778
- );
779
- window.addEventListener(
780
- "resize",
781
- throttle(() => {
782
- if (!isReaderMode()) {
783
- hideOverlappedSidebars();
784
- }
785
- }, 10)
786
- );
787
- hideOverlappedSidebars();
788
- highlightReaderToggle(isReaderMode());
789
- });
790
-
791
- // grouped tabsets
792
- window.addEventListener("pageshow", (_event) => {
793
- function getTabSettings() {
794
- const data = localStorage.getItem("quarto-persistent-tabsets-data");
795
- if (!data) {
796
- localStorage.setItem("quarto-persistent-tabsets-data", "{}");
797
- return {};
798
- }
799
- if (data) {
800
- return JSON.parse(data);
801
- }
802
- }
803
-
804
- function setTabSettings(data) {
805
- localStorage.setItem(
806
- "quarto-persistent-tabsets-data",
807
- JSON.stringify(data)
808
- );
809
- }
810
-
811
- function setTabState(groupName, groupValue) {
812
- const data = getTabSettings();
813
- data[groupName] = groupValue;
814
- setTabSettings(data);
815
- }
816
-
817
- function toggleTab(tab, active) {
818
- const tabPanelId = tab.getAttribute("aria-controls");
819
- const tabPanel = document.getElementById(tabPanelId);
820
- if (active) {
821
- tab.classList.add("active");
822
- tabPanel.classList.add("active");
823
- } else {
824
- tab.classList.remove("active");
825
- tabPanel.classList.remove("active");
826
- }
827
- }
828
-
829
- function toggleAll(selectedGroup, selectorsToSync) {
830
- for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) {
831
- const active = selectedGroup === thisGroup;
832
- for (const tab of tabs) {
833
- toggleTab(tab, active);
834
- }
835
- }
836
- }
837
-
838
- function findSelectorsToSyncByLanguage() {
839
- const result = {};
840
- const tabs = Array.from(
841
- document.querySelectorAll(`div[data-group] a[id^='tabset-']`)
842
- );
843
- for (const item of tabs) {
844
- const div = item.parentElement.parentElement.parentElement;
845
- const group = div.getAttribute("data-group");
846
- if (!result[group]) {
847
- result[group] = {};
848
- }
849
- const selectorsToSync = result[group];
850
- const value = item.innerHTML;
851
- if (!selectorsToSync[value]) {
852
- selectorsToSync[value] = [];
853
- }
854
- selectorsToSync[value].push(item);
855
- }
856
- return result;
857
- }
858
-
859
- function setupSelectorSync() {
860
- const selectorsToSync = findSelectorsToSyncByLanguage();
861
- Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => {
862
- Object.entries(tabSetsByValue).forEach(([value, items]) => {
863
- items.forEach((item) => {
864
- item.addEventListener("click", (_event) => {
865
- setTabState(group, value);
866
- toggleAll(value, selectorsToSync[group]);
867
- });
868
- });
869
- });
870
- });
871
- return selectorsToSync;
872
- }
873
-
874
- const selectorsToSync = setupSelectorSync();
875
- for (const [group, selectedName] of Object.entries(getTabSettings())) {
876
- const selectors = selectorsToSync[group];
877
- // it's possible that stale state gives us empty selections, so we explicitly check here.
878
- if (selectors) {
879
- toggleAll(selectedName, selectors);
880
- }
881
- }
882
- });
883
-
884
- function throttle(func, wait) {
885
- let waiting = false;
886
- return function () {
887
- if (!waiting) {
888
- func.apply(this, arguments);
889
- waiting = true;
890
- setTimeout(function () {
891
- waiting = false;
892
- }, wait);
893
- }
894
- };
895
- }
896
-
897
- function nexttick(func) {
898
- return setTimeout(func, 0);
899
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/site_libs/quarto-html/tippy.css DELETED
@@ -1 +0,0 @@
1
- .tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}
 
 
_site/site_libs/quarto-html/tippy.umd.min.js DELETED
@@ -1,2 +0,0 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],t):(e=e||self).tippy=t(e.Popper)}(this,(function(e){"use strict";var t={passive:!0,capture:!0},n=function(){return document.body};function r(e,t,n){if(Array.isArray(e)){var r=e[t];return null==r?Array.isArray(n)?n[t]:n:r}return e}function o(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function i(e,t){return"function"==typeof e?e.apply(void 0,t):e}function a(e,t){return 0===t?e:function(r){clearTimeout(n),n=setTimeout((function(){e(r)}),t)};var n}function s(e,t){var n=Object.assign({},e);return t.forEach((function(e){delete n[e]})),n}function u(e){return[].concat(e)}function c(e,t){-1===e.indexOf(t)&&e.push(t)}function p(e){return e.split("-")[0]}function f(e){return[].slice.call(e)}function l(e){return Object.keys(e).reduce((function(t,n){return void 0!==e[n]&&(t[n]=e[n]),t}),{})}function d(){return document.createElement("div")}function v(e){return["Element","Fragment"].some((function(t){return o(e,t)}))}function m(e){return o(e,"MouseEvent")}function g(e){return!(!e||!e._tippy||e._tippy.reference!==e)}function h(e){return v(e)?[e]:function(e){return o(e,"NodeList")}(e)?f(e):Array.isArray(e)?e:f(document.querySelectorAll(e))}function b(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function y(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function w(e){var t,n=u(e)[0];return null!=n&&null!=(t=n.ownerDocument)&&t.body?n.ownerDocument:document}function E(e,t,n){var r=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[r](t,n)}))}function O(e,t){for(var n=t;n;){var r;if(e.contains(n))return!0;n=null==n.getRootNode||null==(r=n.getRootNode())?void 0:r.host}return!1}var x={isTouch:!1},C=0;function T(){x.isTouch||(x.isTouch=!0,window.performance&&document.addEventListener("mousemove",A))}function A(){var e=performance.now();e-C<20&&(x.isTouch=!1,document.removeEventListener("mousemove",A)),C=e}function L(){var e=document.activeElement;if(g(e)){var t=e._tippy;e.blur&&!t.state.isVisible&&e.blur()}}var D=!!("undefined"!=typeof window&&"undefined"!=typeof document)&&!!window.msCrypto,R=Object.assign({appendTo:n,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),k=Object.keys(R);function P(e){var t=(e.plugins||[]).reduce((function(t,n){var r,o=n.name,i=n.defaultValue;o&&(t[o]=void 0!==e[o]?e[o]:null!=(r=R[o])?r:i);return t}),{});return Object.assign({},e,t)}function j(e,t){var n=Object.assign({},t,{content:i(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(P(Object.assign({},R,{plugins:t}))):k).reduce((function(t,n){var r=(e.getAttribute("data-tippy-"+n)||"").trim();if(!r)return t;if("content"===n)t[n]=r;else try{t[n]=JSON.parse(r)}catch(e){t[n]=r}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},R.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function M(e,t){e.innerHTML=t}function V(e){var t=d();return!0===e?t.className="tippy-arrow":(t.className="tippy-svg-arrow",v(e)?t.appendChild(e):M(t,e)),t}function I(e,t){v(t.content)?(M(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?M(e,t.content):e.textContent=t.content)}function S(e){var t=e.firstElementChild,n=f(t.children);return{box:t,content:n.find((function(e){return e.classList.contains("tippy-content")})),arrow:n.find((function(e){return e.classList.contains("tippy-arrow")||e.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(e){return e.classList.contains("tippy-backdrop")}))}}function N(e){var t=d(),n=d();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=d();function o(n,r){var o=S(t),i=o.box,a=o.content,s=o.arrow;r.theme?i.setAttribute("data-theme",r.theme):i.removeAttribute("data-theme"),"string"==typeof r.animation?i.setAttribute("data-animation",r.animation):i.removeAttribute("data-animation"),r.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?i.setAttribute("role",r.role):i.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||I(a,e.props),r.arrow?s?n.arrow!==r.arrow&&(i.removeChild(s),i.appendChild(V(r.arrow))):i.appendChild(V(r.arrow)):s&&i.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),I(r,e.props),t.appendChild(n),n.appendChild(r),o(e.props,e.props),{popper:t,onUpdate:o}}N.$$tippy=!0;var B=1,H=[],U=[];function _(o,s){var v,g,h,C,T,A,L,k,M=j(o,Object.assign({},R,P(l(s)))),V=!1,I=!1,N=!1,_=!1,F=[],W=a(we,M.interactiveDebounce),X=B++,Y=(k=M.plugins).filter((function(e,t){return k.indexOf(e)===t})),$={id:X,reference:o,popper:d(),popperInstance:null,props:M,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:Y,clearDelayTimeouts:function(){clearTimeout(v),clearTimeout(g),cancelAnimationFrame(h)},setProps:function(e){if($.state.isDestroyed)return;ae("onBeforeUpdate",[$,e]),be();var t=$.props,n=j(o,Object.assign({},t,l(e),{ignoreAttributes:!0}));$.props=n,he(),t.interactiveDebounce!==n.interactiveDebounce&&(ce(),W=a(we,n.interactiveDebounce));t.triggerTarget&&!n.triggerTarget?u(t.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):n.triggerTarget&&o.removeAttribute("aria-expanded");ue(),ie(),J&&J(t,n);$.popperInstance&&(Ce(),Ae().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)})));ae("onAfterUpdate",[$,e])},setContent:function(e){$.setProps({content:e})},show:function(){var e=$.state.isVisible,t=$.state.isDestroyed,o=!$.state.isEnabled,a=x.isTouch&&!$.props.touch,s=r($.props.duration,0,R.duration);if(e||t||o||a)return;if(te().hasAttribute("disabled"))return;if(ae("onShow",[$],!1),!1===$.props.onShow($))return;$.state.isVisible=!0,ee()&&(z.style.visibility="visible");ie(),de(),$.state.isMounted||(z.style.transition="none");if(ee()){var u=re(),p=u.box,f=u.content;b([p,f],0)}A=function(){var e;if($.state.isVisible&&!_){if(_=!0,z.offsetHeight,z.style.transition=$.props.moveTransition,ee()&&$.props.animation){var t=re(),n=t.box,r=t.content;b([n,r],s),y([n,r],"visible")}se(),ue(),c(U,$),null==(e=$.popperInstance)||e.forceUpdate(),ae("onMount",[$]),$.props.animation&&ee()&&function(e,t){me(e,t)}(s,(function(){$.state.isShown=!0,ae("onShown",[$])}))}},function(){var e,t=$.props.appendTo,r=te();e=$.props.interactive&&t===n||"parent"===t?r.parentNode:i(t,[r]);e.contains(z)||e.appendChild(z);$.state.isMounted=!0,Ce()}()},hide:function(){var e=!$.state.isVisible,t=$.state.isDestroyed,n=!$.state.isEnabled,o=r($.props.duration,1,R.duration);if(e||t||n)return;if(ae("onHide",[$],!1),!1===$.props.onHide($))return;$.state.isVisible=!1,$.state.isShown=!1,_=!1,V=!1,ee()&&(z.style.visibility="hidden");if(ce(),ve(),ie(!0),ee()){var i=re(),a=i.box,s=i.content;$.props.animation&&(b([a,s],o),y([a,s],"hidden"))}se(),ue(),$.props.animation?ee()&&function(e,t){me(e,(function(){!$.state.isVisible&&z.parentNode&&z.parentNode.contains(z)&&t()}))}(o,$.unmount):$.unmount()},hideWithInteractivity:function(e){ne().addEventListener("mousemove",W),c(H,W),W(e)},enable:function(){$.state.isEnabled=!0},disable:function(){$.hide(),$.state.isEnabled=!1},unmount:function(){$.state.isVisible&&$.hide();if(!$.state.isMounted)return;Te(),Ae().forEach((function(e){e._tippy.unmount()})),z.parentNode&&z.parentNode.removeChild(z);U=U.filter((function(e){return e!==$})),$.state.isMounted=!1,ae("onHidden",[$])},destroy:function(){if($.state.isDestroyed)return;$.clearDelayTimeouts(),$.unmount(),be(),delete o._tippy,$.state.isDestroyed=!0,ae("onDestroy",[$])}};if(!M.render)return $;var q=M.render($),z=q.popper,J=q.onUpdate;z.setAttribute("data-tippy-root",""),z.id="tippy-"+$.id,$.popper=z,o._tippy=$,z._tippy=$;var G=Y.map((function(e){return e.fn($)})),K=o.hasAttribute("aria-expanded");return he(),ue(),ie(),ae("onCreate",[$]),M.showOnCreate&&Le(),z.addEventListener("mouseenter",(function(){$.props.interactive&&$.state.isVisible&&$.clearDelayTimeouts()})),z.addEventListener("mouseleave",(function(){$.props.interactive&&$.props.trigger.indexOf("mouseenter")>=0&&ne().addEventListener("mousemove",W)})),$;function Q(){var e=$.props.touch;return Array.isArray(e)?e:[e,0]}function Z(){return"hold"===Q()[0]}function ee(){var e;return!(null==(e=$.props.render)||!e.$$tippy)}function te(){return L||o}function ne(){var e=te().parentNode;return e?w(e):document}function re(){return S(z)}function oe(e){return $.state.isMounted&&!$.state.isVisible||x.isTouch||C&&"focus"===C.type?0:r($.props.delay,e?0:1,R.delay)}function ie(e){void 0===e&&(e=!1),z.style.pointerEvents=$.props.interactive&&!e?"":"none",z.style.zIndex=""+$.props.zIndex}function ae(e,t,n){var r;(void 0===n&&(n=!0),G.forEach((function(n){n[e]&&n[e].apply(n,t)})),n)&&(r=$.props)[e].apply(r,t)}function se(){var e=$.props.aria;if(e.content){var t="aria-"+e.content,n=z.id;u($.props.triggerTarget||o).forEach((function(e){var r=e.getAttribute(t);if($.state.isVisible)e.setAttribute(t,r?r+" "+n:n);else{var o=r&&r.replace(n,"").trim();o?e.setAttribute(t,o):e.removeAttribute(t)}}))}}function ue(){!K&&$.props.aria.expanded&&u($.props.triggerTarget||o).forEach((function(e){$.props.interactive?e.setAttribute("aria-expanded",$.state.isVisible&&e===te()?"true":"false"):e.removeAttribute("aria-expanded")}))}function ce(){ne().removeEventListener("mousemove",W),H=H.filter((function(e){return e!==W}))}function pe(e){if(!x.isTouch||!N&&"mousedown"!==e.type){var t=e.composedPath&&e.composedPath()[0]||e.target;if(!$.props.interactive||!O(z,t)){if(u($.props.triggerTarget||o).some((function(e){return O(e,t)}))){if(x.isTouch)return;if($.state.isVisible&&$.props.trigger.indexOf("click")>=0)return}else ae("onClickOutside",[$,e]);!0===$.props.hideOnClick&&($.clearDelayTimeouts(),$.hide(),I=!0,setTimeout((function(){I=!1})),$.state.isMounted||ve())}}}function fe(){N=!0}function le(){N=!1}function de(){var e=ne();e.addEventListener("mousedown",pe,!0),e.addEventListener("touchend",pe,t),e.addEventListener("touchstart",le,t),e.addEventListener("touchmove",fe,t)}function ve(){var e=ne();e.removeEventListener("mousedown",pe,!0),e.removeEventListener("touchend",pe,t),e.removeEventListener("touchstart",le,t),e.removeEventListener("touchmove",fe,t)}function me(e,t){var n=re().box;function r(e){e.target===n&&(E(n,"remove",r),t())}if(0===e)return t();E(n,"remove",T),E(n,"add",r),T=r}function ge(e,t,n){void 0===n&&(n=!1),u($.props.triggerTarget||o).forEach((function(r){r.addEventListener(e,t,n),F.push({node:r,eventType:e,handler:t,options:n})}))}function he(){var e;Z()&&(ge("touchstart",ye,{passive:!0}),ge("touchend",Ee,{passive:!0})),(e=$.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(ge(e,ye),e){case"mouseenter":ge("mouseleave",Ee);break;case"focus":ge(D?"focusout":"blur",Oe);break;case"focusin":ge("focusout",Oe)}}))}function be(){F.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),F=[]}function ye(e){var t,n=!1;if($.state.isEnabled&&!xe(e)&&!I){var r="focus"===(null==(t=C)?void 0:t.type);C=e,L=e.currentTarget,ue(),!$.state.isVisible&&m(e)&&H.forEach((function(t){return t(e)})),"click"===e.type&&($.props.trigger.indexOf("mouseenter")<0||V)&&!1!==$.props.hideOnClick&&$.state.isVisible?n=!0:Le(e),"click"===e.type&&(V=!n),n&&!r&&De(e)}}function we(e){var t=e.target,n=te().contains(t)||z.contains(t);"mousemove"===e.type&&n||function(e,t){var n=t.clientX,r=t.clientY;return e.every((function(e){var t=e.popperRect,o=e.popperState,i=e.props.interactiveBorder,a=p(o.placement),s=o.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,f="right"===a?s.left.x:0,l="left"===a?s.right.x:0,d=t.top-r+u>i,v=r-t.bottom-c>i,m=t.left-n+f>i,g=n-t.right-l>i;return d||v||m||g}))}(Ae().concat(z).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:M}:null})).filter(Boolean),e)&&(ce(),De(e))}function Ee(e){xe(e)||$.props.trigger.indexOf("click")>=0&&V||($.props.interactive?$.hideWithInteractivity(e):De(e))}function Oe(e){$.props.trigger.indexOf("focusin")<0&&e.target!==te()||$.props.interactive&&e.relatedTarget&&z.contains(e.relatedTarget)||De(e)}function xe(e){return!!x.isTouch&&Z()!==e.type.indexOf("touch")>=0}function Ce(){Te();var t=$.props,n=t.popperOptions,r=t.placement,i=t.offset,a=t.getReferenceClientRect,s=t.moveTransition,u=ee()?S(z).arrow:null,c=a?{getBoundingClientRect:a,contextElement:a.contextElement||te()}:o,p=[{name:"offset",options:{offset:i}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(ee()){var n=re().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}}];ee()&&u&&p.push({name:"arrow",options:{element:u,padding:3}}),p.push.apply(p,(null==n?void 0:n.modifiers)||[]),$.popperInstance=e.createPopper(c,z,Object.assign({},n,{placement:r,onFirstUpdate:A,modifiers:p}))}function Te(){$.popperInstance&&($.popperInstance.destroy(),$.popperInstance=null)}function Ae(){return f(z.querySelectorAll("[data-tippy-root]"))}function Le(e){$.clearDelayTimeouts(),e&&ae("onTrigger",[$,e]),de();var t=oe(!0),n=Q(),r=n[0],o=n[1];x.isTouch&&"hold"===r&&o&&(t=o),t?v=setTimeout((function(){$.show()}),t):$.show()}function De(e){if($.clearDelayTimeouts(),ae("onUntrigger",[$,e]),$.state.isVisible){if(!($.props.trigger.indexOf("mouseenter")>=0&&$.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&V)){var t=oe(!1);t?g=setTimeout((function(){$.state.isVisible&&$.hide()}),t):h=requestAnimationFrame((function(){$.hide()}))}}else ve()}}function F(e,n){void 0===n&&(n={});var r=R.plugins.concat(n.plugins||[]);document.addEventListener("touchstart",T,t),window.addEventListener("blur",L);var o=Object.assign({},n,{plugins:r}),i=h(e).reduce((function(e,t){var n=t&&_(t,o);return n&&e.push(n),e}),[]);return v(e)?i[0]:i}F.defaultProps=R,F.setDefaultProps=function(e){Object.keys(e).forEach((function(t){R[t]=e[t]}))},F.currentInput=x;var W=Object.assign({},e.applyStyles,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}}),X={mouseover:"mouseenter",focusin:"focus",click:"click"};var Y={name:"animateFill",defaultValue:!1,fn:function(e){var t;if(null==(t=e.props.render)||!t.$$tippy)return{};var n=S(e.popper),r=n.box,o=n.content,i=e.props.animateFill?function(){var e=d();return e.className="tippy-backdrop",y([e],"hidden"),e}():null;return{onCreate:function(){i&&(r.insertBefore(i,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",e.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(i){var e=r.style.transitionDuration,t=Number(e.replace("ms",""));o.style.transitionDelay=Math.round(t/10)+"ms",i.style.transitionDuration=e,y([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&y([i],"hidden")}}}};var $={clientX:0,clientY:0},q=[];function z(e){var t=e.clientX,n=e.clientY;$={clientX:t,clientY:n}}var J={name:"followCursor",defaultValue:!1,fn:function(e){var t=e.reference,n=w(e.props.triggerTarget||t),r=!1,o=!1,i=!0,a=e.props;function s(){return"initial"===e.props.followCursor&&e.state.isVisible}function u(){n.addEventListener("mousemove",f)}function c(){n.removeEventListener("mousemove",f)}function p(){r=!0,e.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||t.contains(n.target),o=e.props.followCursor,i=n.clientX,a=n.clientY,s=t.getBoundingClientRect(),u=i-s.left,c=a-s.top;!r&&e.props.interactive||e.setProps({getReferenceClientRect:function(){var e=t.getBoundingClientRect(),n=i,r=a;"initial"===o&&(n=e.left+u,r=e.top+c);var s="horizontal"===o?e.top:r,p="vertical"===o?e.right:n,f="horizontal"===o?e.bottom:r,l="vertical"===o?e.left:n;return{width:p-l,height:f-s,top:s,right:p,bottom:f,left:l}}})}function l(){e.props.followCursor&&(q.push({instance:e,doc:n}),function(e){e.addEventListener("mousemove",z)}(n))}function d(){0===(q=q.filter((function(t){return t.instance!==e}))).filter((function(e){return e.doc===n})).length&&function(e){e.removeEventListener("mousemove",z)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=e.props},onAfterUpdate:function(t,n){var i=n.followCursor;r||void 0!==i&&a.followCursor!==i&&(d(),i?(l(),!e.state.isMounted||o||s()||u()):(c(),p()))},onMount:function(){e.props.followCursor&&!o&&(i&&(f($),i=!1),s()||u())},onTrigger:function(e,t){m(t)&&($={clientX:t.clientX,clientY:t.clientY}),o="focus"===t.type},onHidden:function(){e.props.followCursor&&(p(),c(),i=!0)}}}};var G={name:"inlinePositioning",defaultValue:!1,fn:function(e){var t,n=e.reference;var r=-1,o=!1,i=[],a={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(o){var a=o.state;e.props.inlinePositioning&&(-1!==i.indexOf(a.placement)&&(i=[]),t!==a.placement&&-1===i.indexOf(a.placement)&&(i.push(a.placement),e.setProps({getReferenceClientRect:function(){return function(e){return function(e,t,n,r){if(n.length<2||null===e)return t;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||t;switch(e){case"top":case"bottom":var o=n[0],i=n[n.length-1],a="top"===e,s=o.top,u=i.bottom,c=a?o.left:i.left,p=a?o.right:i.right;return{top:s,bottom:u,left:c,right:p,width:p-c,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(e){return e.left}))),l=Math.max.apply(Math,n.map((function(e){return e.right}))),d=n.filter((function(t){return"left"===e?t.left===f:t.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return t}}(p(e),n.getBoundingClientRect(),f(n.getClientRects()),r)}(a.placement)}})),t=a.placement)}};function s(){var t;o||(t=function(e,t){var n;return{popperOptions:Object.assign({},e.popperOptions,{modifiers:[].concat(((null==(n=e.popperOptions)?void 0:n.modifiers)||[]).filter((function(e){return e.name!==t.name})),[t])})}}(e.props,a),o=!0,e.setProps(t),o=!1)}return{onCreate:s,onAfterUpdate:s,onTrigger:function(t,n){if(m(n)){var o=f(e.reference.getClientRects()),i=o.find((function(e){return e.left-2<=n.clientX&&e.right+2>=n.clientX&&e.top-2<=n.clientY&&e.bottom+2>=n.clientY})),a=o.indexOf(i);r=a>-1?a:r}},onHidden:function(){r=-1}}}};var K={name:"sticky",defaultValue:!1,fn:function(e){var t=e.reference,n=e.popper;function r(t){return!0===e.props.sticky||e.props.sticky===t}var o=null,i=null;function a(){var s=r("reference")?(e.popperInstance?e.popperInstance.state.elements.reference:t).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&Q(o,s)||u&&Q(i,u))&&e.popperInstance&&e.popperInstance.update(),o=s,i=u,e.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){e.props.sticky&&a()}}}};function Q(e,t){return!e||!t||(e.top!==t.top||e.right!==t.right||e.bottom!==t.bottom||e.left!==t.left)}return F.setDefaultProps({plugins:[Y,J,G,K],render:N}),F.createSingleton=function(e,t){var n;void 0===t&&(t={});var r,o=e,i=[],a=[],c=t.overrides,p=[],f=!1;function l(){a=o.map((function(e){return u(e.props.triggerTarget||e.reference)})).reduce((function(e,t){return e.concat(t)}),[])}function v(){i=o.map((function(e){return e.reference}))}function m(e){o.forEach((function(t){e?t.enable():t.disable()}))}function g(e){return o.map((function(t){var n=t.setProps;return t.setProps=function(o){n(o),t.reference===r&&e.setProps(o)},function(){t.setProps=n}}))}function h(e,t){var n=a.indexOf(t);if(t!==r){r=t;var s=(c||[]).concat("content").reduce((function(e,t){return e[t]=o[n].props[t],e}),{});e.setProps(Object.assign({},s,{getReferenceClientRect:"function"==typeof s.getReferenceClientRect?s.getReferenceClientRect:function(){var e;return null==(e=i[n])?void 0:e.getBoundingClientRect()}}))}}m(!1),v(),l();var b={fn:function(){return{onDestroy:function(){m(!0)},onHidden:function(){r=null},onClickOutside:function(e){e.props.showOnCreate&&!f&&(f=!0,r=null)},onShow:function(e){e.props.showOnCreate&&!f&&(f=!0,h(e,i[0]))},onTrigger:function(e,t){h(e,t.currentTarget)}}}},y=F(d(),Object.assign({},s(t,["overrides"]),{plugins:[b].concat(t.plugins||[]),triggerTarget:a,popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat((null==(n=t.popperOptions)?void 0:n.modifiers)||[],[W])})})),w=y.show;y.show=function(e){if(w(),!r&&null==e)return h(y,i[0]);if(!r||null!=e){if("number"==typeof e)return i[e]&&h(y,i[e]);if(o.indexOf(e)>=0){var t=e.reference;return h(y,t)}return i.indexOf(e)>=0?h(y,e):void 0}},y.showNext=function(){var e=i[0];if(!r)return y.show(0);var t=i.indexOf(r);y.show(i[t+1]||e)},y.showPrevious=function(){var e=i[i.length-1];if(!r)return y.show(e);var t=i.indexOf(r),n=i[t-1]||e;y.show(n)};var E=y.setProps;return y.setProps=function(e){c=e.overrides||c,E(e)},y.setInstances=function(e){m(!0),p.forEach((function(e){return e()})),o=e,m(!1),v(),l(),p=g(y),y.setProps({triggerTarget:a})},p=g(y),y},F.delegate=function(e,n){var r=[],o=[],i=!1,a=n.target,c=s(n,["target"]),p=Object.assign({},c,{trigger:"manual",touch:!1}),f=Object.assign({touch:R.touch},c,{showOnCreate:!0}),l=F(e,p);function d(e){if(e.target&&!i){var t=e.target.closest(a);if(t){var r=t.getAttribute("data-tippy-trigger")||n.trigger||R.trigger;if(!t._tippy&&!("touchstart"===e.type&&"boolean"==typeof f.touch||"touchstart"!==e.type&&r.indexOf(X[e.type])<0)){var s=F(t,f);s&&(o=o.concat(s))}}}}function v(e,t,n,o){void 0===o&&(o=!1),e.addEventListener(t,n,o),r.push({node:e,eventType:t,handler:n,options:o})}return u(l).forEach((function(e){var n=e.destroy,a=e.enable,s=e.disable;e.destroy=function(e){void 0===e&&(e=!0),e&&o.forEach((function(e){e.destroy()})),o=[],r.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),r=[],n()},e.enable=function(){a(),o.forEach((function(e){return e.enable()})),i=!1},e.disable=function(){s(),o.forEach((function(e){return e.disable()})),i=!0},function(e){var n=e.reference;v(n,"touchstart",d,t),v(n,"mouseover",d),v(n,"focusin",d),v(n,"click",d)}(e)})),l},F.hideAll=function(e){var t=void 0===e?{}:e,n=t.exclude,r=t.duration;U.forEach((function(e){var t=!1;if(n&&(t=g(n)?e.reference===n:e.popper===n.popper),!t){var o=e.props.duration;e.setProps({duration:r}),e.hide(),e.state.isDestroyed||e.setProps({duration:o})}}))},F.roundArrow='<svg width="16" height="6" xmlns="http://www.w3.org/2000/svg"><path d="M0 6s1.796-.013 4.67-3.615C5.851.9 6.93.006 8 0c1.07-.006 2.148.887 3.343 2.385C14.233 6.005 16 6 16 6H0z"></svg>',F}));
2
-
 
 
 
_site/site_libs/quarto-listing/list.min.js DELETED
@@ -1,2 +0,0 @@
1
- var List;List=function(){var t={"./src/add-async.js":function(t){t.exports=function(t){return function e(r,n,s){var i=r.splice(0,50);s=(s=s||[]).concat(t.add(i)),r.length>0?setTimeout((function(){e(r,n,s)}),1):(t.update(),n(s))}}},"./src/filter.js":function(t){t.exports=function(t){return t.handlers.filterStart=t.handlers.filterStart||[],t.handlers.filterComplete=t.handlers.filterComplete||[],function(e){if(t.trigger("filterStart"),t.i=1,t.reset.filter(),void 0===e)t.filtered=!1;else{t.filtered=!0;for(var r=t.items,n=0,s=r.length;n<s;n++){var i=r[n];e(i)?i.filtered=!0:i.filtered=!1}}return t.update(),t.trigger("filterComplete"),t.visibleItems}}},"./src/fuzzy-search.js":function(t,e,r){r("./src/utils/classes.js");var n=r("./src/utils/events.js"),s=r("./src/utils/extend.js"),i=r("./src/utils/to-string.js"),a=r("./src/utils/get-by-class.js"),o=r("./src/utils/fuzzy.js");t.exports=function(t,e){e=s({location:0,distance:100,threshold:.4,multiSearch:!0,searchClass:"fuzzy-search"},e=e||{});var r={search:function(n,s){for(var i=e.multiSearch?n.replace(/ +$/,"").split(/ +/):[n],a=0,o=t.items.length;a<o;a++)r.item(t.items[a],s,i)},item:function(t,e,n){for(var s=!0,i=0;i<n.length;i++){for(var a=!1,o=0,l=e.length;o<l;o++)r.values(t.values(),e[o],n[i])&&(a=!0);a||(s=!1)}t.found=s},values:function(t,r,n){if(t.hasOwnProperty(r)){var s=i(t[r]).toLowerCase();if(o(s,n,e))return!0}return!1}};return n.bind(a(t.listContainer,e.searchClass),"keyup",t.utils.events.debounce((function(e){var n=e.target||e.srcElement;t.search(n.value,r.search)}),t.searchDelay)),function(e,n){t.search(e,n,r.search)}}},"./src/index.js":function(t,e,r){var n=r("./node_modules/string-natural-compare/natural-compare.js"),s=r("./src/utils/get-by-class.js"),i=r("./src/utils/extend.js"),a=r("./src/utils/index-of.js"),o=r("./src/utils/events.js"),l=r("./src/utils/to-string.js"),u=r("./src/utils/classes.js"),c=r("./src/utils/get-attribute.js"),f=r("./src/utils/to-array.js");t.exports=function(t,e,h){var d,v=this,g=r("./src/item.js")(v),m=r("./src/add-async.js")(v),p=r("./src/pagination.js")(v);d={start:function(){v.listClass="list",v.searchClass="search",v.sortClass="sort",v.page=1e4,v.i=1,v.items=[],v.visibleItems=[],v.matchingItems=[],v.searched=!1,v.filtered=!1,v.searchColumns=void 0,v.searchDelay=0,v.handlers={updated:[]},v.valueNames=[],v.utils={getByClass:s,extend:i,indexOf:a,events:o,toString:l,naturalSort:n,classes:u,getAttribute:c,toArray:f},v.utils.extend(v,e),v.listContainer="string"==typeof t?document.getElementById(t):t,v.listContainer&&(v.list=s(v.listContainer,v.listClass,!0),v.parse=r("./src/parse.js")(v),v.templater=r("./src/templater.js")(v),v.search=r("./src/search.js")(v),v.filter=r("./src/filter.js")(v),v.sort=r("./src/sort.js")(v),v.fuzzySearch=r("./src/fuzzy-search.js")(v,e.fuzzySearch),this.handlers(),this.items(),this.pagination(),v.update())},handlers:function(){for(var t in v.handlers)v[t]&&v.handlers.hasOwnProperty(t)&&v.on(t,v[t])},items:function(){v.parse(v.list),void 0!==h&&v.add(h)},pagination:function(){if(void 0!==e.pagination){!0===e.pagination&&(e.pagination=[{}]),void 0===e.pagination[0]&&(e.pagination=[e.pagination]);for(var t=0,r=e.pagination.length;t<r;t++)p(e.pagination[t])}}},this.reIndex=function(){v.items=[],v.visibleItems=[],v.matchingItems=[],v.searched=!1,v.filtered=!1,v.parse(v.list)},this.toJSON=function(){for(var t=[],e=0,r=v.items.length;e<r;e++)t.push(v.items[e].values());return t},this.add=function(t,e){if(0!==t.length){if(!e){var r=[],n=!1;void 0===t[0]&&(t=[t]);for(var s=0,i=t.length;s<i;s++){var a;n=v.items.length>v.page,a=new g(t[s],void 0,n),v.items.push(a),r.push(a)}return v.update(),r}m(t.slice(0),e)}},this.show=function(t,e){return this.i=t,this.page=e,v.update(),v},this.remove=function(t,e,r){for(var n=0,s=0,i=v.items.length;s<i;s++)v.items[s].values()[t]==e&&(v.templater.remove(v.items[s],r),v.items.splice(s,1),i--,s--,n++);return v.update(),n},this.get=function(t,e){for(var r=[],n=0,s=v.items.length;n<s;n++){var i=v.items[n];i.values()[t]==e&&r.push(i)}return r},this.size=function(){return v.items.length},this.clear=function(){return v.templater.clear(),v.items=[],v},this.on=function(t,e){return v.handlers[t].push(e),v},this.off=function(t,e){var r=v.handlers[t],n=a(r,e);return n>-1&&r.splice(n,1),v},this.trigger=function(t){for(var e=v.handlers[t].length;e--;)v.handlers[t][e](v);return v},this.reset={filter:function(){for(var t=v.items,e=t.length;e--;)t[e].filtered=!1;return v},search:function(){for(var t=v.items,e=t.length;e--;)t[e].found=!1;return v}},this.update=function(){var t=v.items,e=t.length;v.visibleItems=[],v.matchingItems=[],v.templater.clear();for(var r=0;r<e;r++)t[r].matching()&&v.matchingItems.length+1>=v.i&&v.visibleItems.length<v.page?(t[r].show(),v.visibleItems.push(t[r]),v.matchingItems.push(t[r])):t[r].matching()?(v.matchingItems.push(t[r]),t[r].hide()):t[r].hide();return v.trigger("updated"),v},d.start()}},"./src/item.js":function(t){t.exports=function(t){return function(e,r,n){var s=this;this._values={},this.found=!1,this.filtered=!1;this.values=function(e,r){if(void 0===e)return s._values;for(var n in e)s._values[n]=e[n];!0!==r&&t.templater.set(s,s.values())},this.show=function(){t.templater.show(s)},this.hide=function(){t.templater.hide(s)},this.matching=function(){return t.filtered&&t.searched&&s.found&&s.filtered||t.filtered&&!t.searched&&s.filtered||!t.filtered&&t.searched&&s.found||!t.filtered&&!t.searched},this.visible=function(){return!(!s.elm||s.elm.parentNode!=t.list)},function(e,r,n){if(void 0===r)n?s.values(e,n):s.values(e);else{s.elm=r;var i=t.templater.get(s,e);s.values(i)}}(e,r,n)}}},"./src/pagination.js":function(t,e,r){var n=r("./src/utils/classes.js"),s=r("./src/utils/events.js"),i=r("./src/index.js");t.exports=function(t){var e=!1,r=function(r,s){if(t.page<1)return t.listContainer.style.display="none",void(e=!0);e&&(t.listContainer.style.display="block");var i,o=t.matchingItems.length,l=t.i,u=t.page,c=Math.ceil(o/u),f=Math.ceil(l/u),h=s.innerWindow||2,d=s.left||s.outerWindow||0,v=s.right||s.outerWindow||0;v=c-v,r.clear();for(var g=1;g<=c;g++){var m=f===g?"active":"";a.number(g,d,v,f,h)?(i=r.add({page:g,dotted:!1})[0],m&&n(i.elm).add(m),i.elm.firstChild.setAttribute("data-i",g),i.elm.firstChild.setAttribute("data-page",u)):a.dotted(r,g,d,v,f,h,r.size())&&(i=r.add({page:"...",dotted:!0})[0],n(i.elm).add("disabled"))}},a={number:function(t,e,r,n,s){return this.left(t,e)||this.right(t,r)||this.innerWindow(t,n,s)},left:function(t,e){return t<=e},right:function(t,e){return t>e},innerWindow:function(t,e,r){return t>=e-r&&t<=e+r},dotted:function(t,e,r,n,s,i,a){return this.dottedLeft(t,e,r,n,s,i)||this.dottedRight(t,e,r,n,s,i,a)},dottedLeft:function(t,e,r,n,s,i){return e==r+1&&!this.innerWindow(e,s,i)&&!this.right(e,n)},dottedRight:function(t,e,r,n,s,i,a){return!t.items[a-1].values().dotted&&(e==n&&!this.innerWindow(e,s,i)&&!this.right(e,n))}};return function(e){var n=new i(t.listContainer.id,{listClass:e.paginationClass||"pagination",item:e.item||"<li><a class='page' href='#'></a></li>",valueNames:["page","dotted"],searchClass:"pagination-search-that-is-not-supposed-to-exist",sortClass:"pagination-sort-that-is-not-supposed-to-exist"});s.bind(n.listContainer,"click",(function(e){var r=e.target||e.srcElement,n=t.utils.getAttribute(r,"data-page"),s=t.utils.getAttribute(r,"data-i");s&&t.show((s-1)*n+1,n)})),t.on("updated",(function(){r(n,e)})),r(n,e)}}},"./src/parse.js":function(t,e,r){t.exports=function(t){var e=r("./src/item.js")(t),n=function(r,n){for(var s=0,i=r.length;s<i;s++)t.items.push(new e(n,r[s]))},s=function e(r,s){var i=r.splice(0,50);n(i,s),r.length>0?setTimeout((function(){e(r,s)}),1):(t.update(),t.trigger("parseComplete"))};return t.handlers.parseComplete=t.handlers.parseComplete||[],function(){var e=function(t){for(var e=t.childNodes,r=[],n=0,s=e.length;n<s;n++)void 0===e[n].data&&r.push(e[n]);return r}(t.list),r=t.valueNames;t.indexAsync?s(e,r):n(e,r)}}},"./src/search.js":function(t){t.exports=function(t){var e,r,n,s={resetList:function(){t.i=1,t.templater.clear(),n=void 0},setOptions:function(t){2==t.length&&t[1]instanceof Array?e=t[1]:2==t.length&&"function"==typeof t[1]?(e=void 0,n=t[1]):3==t.length?(e=t[1],n=t[2]):e=void 0},setColumns:function(){0!==t.items.length&&void 0===e&&(e=void 0===t.searchColumns?s.toArray(t.items[0].values()):t.searchColumns)},setSearchString:function(e){e=(e=t.utils.toString(e).toLowerCase()).replace(/[-[\]{}()*+?.,\\^$|#]/g,"\\$&"),r=e},toArray:function(t){var e=[];for(var r in t)e.push(r);return e}},i=function(){for(var n,s=[],i=r;null!==(n=i.match(/"([^"]+)"/));)s.push(n[1]),i=i.substring(0,n.index)+i.substring(n.index+n[0].length);(i=i.trim()).length&&(s=s.concat(i.split(/\s+/)));for(var a=0,o=t.items.length;a<o;a++){var l=t.items[a];if(l.found=!1,s.length){for(var u=0,c=s.length;u<c;u++){for(var f=!1,h=0,d=e.length;h<d;h++){var v=l.values(),g=e[h];if(v.hasOwnProperty(g)&&void 0!==v[g]&&null!==v[g])if(-1!==("string"!=typeof v[g]?v[g].toString():v[g]).toLowerCase().indexOf(s[u])){f=!0;break}}if(!f)break}l.found=f}}},a=function(){t.reset.search(),t.searched=!1},o=function(o){return t.trigger("searchStart"),s.resetList(),s.setSearchString(o),s.setOptions(arguments),s.setColumns(),""===r?a():(t.searched=!0,n?n(r,e):i()),t.update(),t.trigger("searchComplete"),t.visibleItems};return t.handlers.searchStart=t.handlers.searchStart||[],t.handlers.searchComplete=t.handlers.searchComplete||[],t.utils.events.bind(t.utils.getByClass(t.listContainer,t.searchClass),"keyup",t.utils.events.debounce((function(e){var r=e.target||e.srcElement;""===r.value&&!t.searched||o(r.value)}),t.searchDelay)),t.utils.events.bind(t.utils.getByClass(t.listContainer,t.searchClass),"input",(function(t){""===(t.target||t.srcElement).value&&o("")})),o}},"./src/sort.js":function(t){t.exports=function(t){var e={els:void 0,clear:function(){for(var r=0,n=e.els.length;r<n;r++)t.utils.classes(e.els[r]).remove("asc"),t.utils.classes(e.els[r]).remove("desc")},getOrder:function(e){var r=t.utils.getAttribute(e,"data-order");return"asc"==r||"desc"==r?r:t.utils.classes(e).has("desc")?"asc":t.utils.classes(e).has("asc")?"desc":"asc"},getInSensitive:function(e,r){var n=t.utils.getAttribute(e,"data-insensitive");r.insensitive="false"!==n},setOrder:function(r){for(var n=0,s=e.els.length;n<s;n++){var i=e.els[n];if(t.utils.getAttribute(i,"data-sort")===r.valueName){var a=t.utils.getAttribute(i,"data-order");"asc"==a||"desc"==a?a==r.order&&t.utils.classes(i).add(r.order):t.utils.classes(i).add(r.order)}}}},r=function(){t.trigger("sortStart");var r={},n=arguments[0].currentTarget||arguments[0].srcElement||void 0;n?(r.valueName=t.utils.getAttribute(n,"data-sort"),e.getInSensitive(n,r),r.order=e.getOrder(n)):((r=arguments[1]||r).valueName=arguments[0],r.order=r.order||"asc",r.insensitive=void 0===r.insensitive||r.insensitive),e.clear(),e.setOrder(r);var s,i=r.sortFunction||t.sortFunction||null,a="desc"===r.order?-1:1;s=i?function(t,e){return i(t,e,r)*a}:function(e,n){var s=t.utils.naturalSort;return s.alphabet=t.alphabet||r.alphabet||void 0,!s.alphabet&&r.insensitive&&(s=t.utils.naturalSort.caseInsensitive),s(e.values()[r.valueName],n.values()[r.valueName])*a},t.items.sort(s),t.update(),t.trigger("sortComplete")};return t.handlers.sortStart=t.handlers.sortStart||[],t.handlers.sortComplete=t.handlers.sortComplete||[],e.els=t.utils.getByClass(t.listContainer,t.sortClass),t.utils.events.bind(e.els,"click",r),t.on("searchStart",e.clear),t.on("filterStart",e.clear),r}},"./src/templater.js":function(t){var e=function(t){var e,r=this,n=function(e,r){var n=e.cloneNode(!0);n.removeAttribute("id");for(var s=0,i=r.length;s<i;s++){var a=void 0,o=r[s];if(o.data)for(var l=0,u=o.data.length;l<u;l++)n.setAttribute("data-"+o.data[l],"");else o.attr&&o.name?(a=t.utils.getByClass(n,o.name,!0))&&a.setAttribute(o.attr,""):(a=t.utils.getByClass(n,o,!0))&&(a.innerHTML="")}return n},s=function(){for(var e=t.list.childNodes,r=0,n=e.length;r<n;r++)if(void 0===e[r].data)return e[r].cloneNode(!0)},i=function(t){if("string"==typeof t){if(/<tr[\s>]/g.exec(t)){var e=document.createElement("tbody");return e.innerHTML=t,e.firstElementChild}if(-1!==t.indexOf("<")){var r=document.createElement("div");return r.innerHTML=t,r.firstElementChild}}},a=function(e,r,n){var s=void 0,i=function(e){for(var r=0,n=t.valueNames.length;r<n;r++){var s=t.valueNames[r];if(s.data){for(var i=s.data,a=0,o=i.length;a<o;a++)if(i[a]===e)return{data:e}}else{if(s.attr&&s.name&&s.name==e)return s;if(s===e)return e}}}(r);i&&(i.data?e.elm.setAttribute("data-"+i.data,n):i.attr&&i.name?(s=t.utils.getByClass(e.elm,i.name,!0))&&s.setAttribute(i.attr,n):(s=t.utils.getByClass(e.elm,i,!0))&&(s.innerHTML=n))};this.get=function(e,n){r.create(e);for(var s={},i=0,a=n.length;i<a;i++){var o=void 0,l=n[i];if(l.data)for(var u=0,c=l.data.length;u<c;u++)s[l.data[u]]=t.utils.getAttribute(e.elm,"data-"+l.data[u]);else l.attr&&l.name?(o=t.utils.getByClass(e.elm,l.name,!0),s[l.name]=o?t.utils.getAttribute(o,l.attr):""):(o=t.utils.getByClass(e.elm,l,!0),s[l]=o?o.innerHTML:"")}return s},this.set=function(t,e){if(!r.create(t))for(var n in e)e.hasOwnProperty(n)&&a(t,n,e[n])},this.create=function(t){return void 0===t.elm&&(t.elm=e(t.values()),r.set(t,t.values()),!0)},this.remove=function(e){e.elm.parentNode===t.list&&t.list.removeChild(e.elm)},this.show=function(e){r.create(e),t.list.appendChild(e.elm)},this.hide=function(e){void 0!==e.elm&&e.elm.parentNode===t.list&&t.list.removeChild(e.elm)},this.clear=function(){if(t.list.hasChildNodes())for(;t.list.childNodes.length>=1;)t.list.removeChild(t.list.firstChild)},function(){var r;if("function"!=typeof t.item){if(!(r="string"==typeof t.item?-1===t.item.indexOf("<")?document.getElementById(t.item):i(t.item):s()))throw new Error("The list needs to have at least one item on init otherwise you'll have to add a template.");r=n(r,t.valueNames),e=function(){return r.cloneNode(!0)}}else e=function(e){var r=t.item(e);return i(r)}}()};t.exports=function(t){return new e(t)}},"./src/utils/classes.js":function(t,e,r){var n=r("./src/utils/index-of.js"),s=/\s+/;Object.prototype.toString;function i(t){if(!t||!t.nodeType)throw new Error("A DOM element reference is required");this.el=t,this.list=t.classList}t.exports=function(t){return new i(t)},i.prototype.add=function(t){if(this.list)return this.list.add(t),this;var e=this.array();return~n(e,t)||e.push(t),this.el.className=e.join(" "),this},i.prototype.remove=function(t){if(this.list)return this.list.remove(t),this;var e=this.array(),r=n(e,t);return~r&&e.splice(r,1),this.el.className=e.join(" "),this},i.prototype.toggle=function(t,e){return this.list?(void 0!==e?e!==this.list.toggle(t,e)&&this.list.toggle(t):this.list.toggle(t),this):(void 0!==e?e?this.add(t):this.remove(t):this.has(t)?this.remove(t):this.add(t),this)},i.prototype.array=function(){var t=(this.el.getAttribute("class")||"").replace(/^\s+|\s+$/g,"").split(s);return""===t[0]&&t.shift(),t},i.prototype.has=i.prototype.contains=function(t){return this.list?this.list.contains(t):!!~n(this.array(),t)}},"./src/utils/events.js":function(t,e,r){var n=window.addEventListener?"addEventListener":"attachEvent",s=window.removeEventListener?"removeEventListener":"detachEvent",i="addEventListener"!==n?"on":"",a=r("./src/utils/to-array.js");e.bind=function(t,e,r,s){for(var o=0,l=(t=a(t)).length;o<l;o++)t[o][n](i+e,r,s||!1)},e.unbind=function(t,e,r,n){for(var o=0,l=(t=a(t)).length;o<l;o++)t[o][s](i+e,r,n||!1)},e.debounce=function(t,e,r){var n;return e?function(){var s=this,i=arguments,a=function(){n=null,r||t.apply(s,i)},o=r&&!n;clearTimeout(n),n=setTimeout(a,e),o&&t.apply(s,i)}:t}},"./src/utils/extend.js":function(t){t.exports=function(t){for(var e,r=Array.prototype.slice.call(arguments,1),n=0;e=r[n];n++)if(e)for(var s in e)t[s]=e[s];return t}},"./src/utils/fuzzy.js":function(t){t.exports=function(t,e,r){var n=r.location||0,s=r.distance||100,i=r.threshold||.4;if(e===t)return!0;if(e.length>32)return!1;var a=n,o=function(){var t,r={};for(t=0;t<e.length;t++)r[e.charAt(t)]=0;for(t=0;t<e.length;t++)r[e.charAt(t)]|=1<<e.length-t-1;return r}();function l(t,r){var n=t/e.length,i=Math.abs(a-r);return s?n+i/s:i?1:n}var u=i,c=t.indexOf(e,a);-1!=c&&(u=Math.min(l(0,c),u),-1!=(c=t.lastIndexOf(e,a+e.length))&&(u=Math.min(l(0,c),u)));var f,h,d=1<<e.length-1;c=-1;for(var v,g=e.length+t.length,m=0;m<e.length;m++){for(f=0,h=g;f<h;)l(m,a+h)<=u?f=h:g=h,h=Math.floor((g-f)/2+f);g=h;var p=Math.max(1,a-h+1),y=Math.min(a+h,t.length)+e.length,C=Array(y+2);C[y+1]=(1<<m)-1;for(var b=y;b>=p;b--){var j=o[t.charAt(b-1)];if(C[b]=0===m?(C[b+1]<<1|1)&j:(C[b+1]<<1|1)&j|(v[b+1]|v[b])<<1|1|v[b+1],C[b]&d){var x=l(m,b-1);if(x<=u){if(u=x,!((c=b-1)>a))break;p=Math.max(1,2*a-c)}}}if(l(m+1,a)>u)break;v=C}return!(c<0)}},"./src/utils/get-attribute.js":function(t){t.exports=function(t,e){var r=t.getAttribute&&t.getAttribute(e)||null;if(!r)for(var n=t.attributes,s=n.length,i=0;i<s;i++)void 0!==n[i]&&n[i].nodeName===e&&(r=n[i].nodeValue);return r}},"./src/utils/get-by-class.js":function(t){t.exports=function(t,e,r,n){return(n=n||{}).test&&n.getElementsByClassName||!n.test&&document.getElementsByClassName?function(t,e,r){return r?t.getElementsByClassName(e)[0]:t.getElementsByClassName(e)}(t,e,r):n.test&&n.querySelector||!n.test&&document.querySelector?function(t,e,r){return e="."+e,r?t.querySelector(e):t.querySelectorAll(e)}(t,e,r):function(t,e,r){for(var n=[],s=t.getElementsByTagName("*"),i=s.length,a=new RegExp("(^|\\s)"+e+"(\\s|$)"),o=0,l=0;o<i;o++)if(a.test(s[o].className)){if(r)return s[o];n[l]=s[o],l++}return n}(t,e,r)}},"./src/utils/index-of.js":function(t){var e=[].indexOf;t.exports=function(t,r){if(e)return t.indexOf(r);for(var n=0,s=t.length;n<s;++n)if(t[n]===r)return n;return-1}},"./src/utils/to-array.js":function(t){t.exports=function(t){if(void 0===t)return[];if(null===t)return[null];if(t===window)return[window];if("string"==typeof t)return[t];if(function(t){return"[object Array]"===Object.prototype.toString.call(t)}(t))return t;if("number"!=typeof t.length)return[t];if("function"==typeof t&&t instanceof Function)return[t];for(var e=[],r=0,n=t.length;r<n;r++)(Object.prototype.hasOwnProperty.call(t,r)||r in t)&&e.push(t[r]);return e.length?e:[]}},"./src/utils/to-string.js":function(t){t.exports=function(t){return t=(t=null===(t=void 0===t?"":t)?"":t).toString()}},"./node_modules/string-natural-compare/natural-compare.js":function(t){"use strict";var e,r,n=0;function s(t){return t>=48&&t<=57}function i(t,e){for(var i=(t+="").length,a=(e+="").length,o=0,l=0;o<i&&l<a;){var u=t.charCodeAt(o),c=e.charCodeAt(l);if(s(u)){if(!s(c))return u-c;for(var f=o,h=l;48===u&&++f<i;)u=t.charCodeAt(f);for(;48===c&&++h<a;)c=e.charCodeAt(h);for(var d=f,v=h;d<i&&s(t.charCodeAt(d));)++d;for(;v<a&&s(e.charCodeAt(v));)++v;var g=d-f-v+h;if(g)return g;for(;f<d;)if(g=t.charCodeAt(f++)-e.charCodeAt(h++))return g;o=d,l=v}else{if(u!==c)return u<n&&c<n&&-1!==r[u]&&-1!==r[c]?r[u]-r[c]:u-c;++o,++l}}return o>=i&&l<a&&i>=a?-1:l>=a&&o<i&&a>=i?1:i-a}i.caseInsensitive=i.i=function(t,e){return i((""+t).toLowerCase(),(""+e).toLowerCase())},Object.defineProperties(i,{alphabet:{get:function(){return e},set:function(t){r=[];var s=0;if(e=t)for(;s<e.length;s++)r[e.charCodeAt(s)]=s;for(n=r.length,s=0;s<n;s++)void 0===r[s]&&(r[s]=-1)}}}),t.exports=i}},e={};return function r(n){if(e[n])return e[n].exports;var s=e[n]={exports:{}};return t[n](s,s.exports,r),s.exports}("./src/index.js")}();
2
- //# sourceMappingURL=list.min.js.map
 
 
 
_site/site_libs/quarto-listing/quarto-listing.js DELETED
@@ -1,243 +0,0 @@
1
- const kProgressiveAttr = "data-src";
2
- let categoriesLoaded = false;
3
-
4
- window.quartoListingCategory = (category) => {
5
- if (categoriesLoaded) {
6
- activateCategory(category);
7
- setCategoryHash(category);
8
- }
9
- };
10
-
11
- window["quarto-listing-loaded"] = () => {
12
- // Process any existing hash
13
- const hash = getHash();
14
-
15
- if (hash) {
16
- // If there is a category, switch to that
17
- if (hash.category) {
18
- activateCategory(hash.category);
19
- }
20
- // Paginate a specific listing
21
- const listingIds = Object.keys(window["quarto-listings"]);
22
- for (const listingId of listingIds) {
23
- const page = hash[getListingPageKey(listingId)];
24
- if (page) {
25
- showPage(listingId, page);
26
- }
27
- }
28
- }
29
-
30
- const listingIds = Object.keys(window["quarto-listings"]);
31
- for (const listingId of listingIds) {
32
- // The actual list
33
- const list = window["quarto-listings"][listingId];
34
-
35
- // Update the handlers for pagination events
36
- refreshPaginationHandlers(listingId);
37
-
38
- // Render any visible items that need it
39
- renderVisibleProgressiveImages(list);
40
-
41
- // Whenever the list is updated, we also need to
42
- // attach handlers to the new pagination elements
43
- // and refresh any newly visible items.
44
- list.on("updated", function () {
45
- renderVisibleProgressiveImages(list);
46
- setTimeout(() => refreshPaginationHandlers(listingId));
47
-
48
- // Show or hide the no matching message
49
- toggleNoMatchingMessage(list);
50
- });
51
- }
52
- };
53
-
54
- window.document.addEventListener("DOMContentLoaded", function (_event) {
55
- // Attach click handlers to categories
56
- const categoryEls = window.document.querySelectorAll(
57
- ".quarto-listing-category .category"
58
- );
59
-
60
- for (const categoryEl of categoryEls) {
61
- const category = categoryEl.getAttribute("data-category");
62
- categoryEl.onclick = () => {
63
- activateCategory(category);
64
- setCategoryHash(category);
65
- };
66
- }
67
-
68
- // Attach a click handler to the category title
69
- // (there should be only one, but since it is a class name, handle N)
70
- const categoryTitleEls = window.document.querySelectorAll(
71
- ".quarto-listing-category-title"
72
- );
73
- for (const categoryTitleEl of categoryTitleEls) {
74
- categoryTitleEl.onclick = () => {
75
- activateCategory("");
76
- setCategoryHash("");
77
- };
78
- }
79
-
80
- categoriesLoaded = true;
81
- });
82
-
83
- function toggleNoMatchingMessage(list) {
84
- const selector = `#${list.listContainer.id} .listing-no-matching`;
85
- const noMatchingEl = window.document.querySelector(selector);
86
- if (noMatchingEl) {
87
- if (list.visibleItems.length === 0) {
88
- noMatchingEl.classList.remove("d-none");
89
- } else {
90
- if (!noMatchingEl.classList.contains("d-none")) {
91
- noMatchingEl.classList.add("d-none");
92
- }
93
- }
94
- }
95
- }
96
-
97
- function setCategoryHash(category) {
98
- setHash({ category });
99
- }
100
-
101
- function setPageHash(listingId, page) {
102
- const currentHash = getHash() || {};
103
- currentHash[getListingPageKey(listingId)] = page;
104
- setHash(currentHash);
105
- }
106
-
107
- function getListingPageKey(listingId) {
108
- return `${listingId}-page`;
109
- }
110
-
111
- function refreshPaginationHandlers(listingId) {
112
- const listingEl = window.document.getElementById(listingId);
113
- const paginationEls = listingEl.querySelectorAll(
114
- ".pagination li.page-item:not(.disabled) .page.page-link"
115
- );
116
- for (const paginationEl of paginationEls) {
117
- paginationEl.onclick = (sender) => {
118
- setPageHash(listingId, sender.target.getAttribute("data-i"));
119
- showPage(listingId, sender.target.getAttribute("data-i"));
120
- return false;
121
- };
122
- }
123
- }
124
-
125
- function renderVisibleProgressiveImages(list) {
126
- // Run through the visible items and render any progressive images
127
- for (const item of list.visibleItems) {
128
- const itemEl = item.elm;
129
- if (itemEl) {
130
- const progressiveImgs = itemEl.querySelectorAll(
131
- `img[${kProgressiveAttr}]`
132
- );
133
- for (const progressiveImg of progressiveImgs) {
134
- const srcValue = progressiveImg.getAttribute(kProgressiveAttr);
135
- if (srcValue) {
136
- progressiveImg.setAttribute("src", srcValue);
137
- }
138
- progressiveImg.removeAttribute(kProgressiveAttr);
139
- }
140
- }
141
- }
142
- }
143
-
144
- function getHash() {
145
- // Hashes are of the form
146
- // #name:value|name1:value1|name2:value2
147
- const currentUrl = new URL(window.location);
148
- const hashRaw = currentUrl.hash ? currentUrl.hash.slice(1) : undefined;
149
- return parseHash(hashRaw);
150
- }
151
-
152
- const kAnd = "&";
153
- const kEquals = "=";
154
-
155
- function parseHash(hash) {
156
- if (!hash) {
157
- return undefined;
158
- }
159
- const hasValuesStrs = hash.split(kAnd);
160
- const hashValues = hasValuesStrs
161
- .map((hashValueStr) => {
162
- const vals = hashValueStr.split(kEquals);
163
- if (vals.length === 2) {
164
- return { name: vals[0], value: vals[1] };
165
- } else {
166
- return undefined;
167
- }
168
- })
169
- .filter((value) => {
170
- return value !== undefined;
171
- });
172
-
173
- const hashObj = {};
174
- hashValues.forEach((hashValue) => {
175
- hashObj[hashValue.name] = decodeURIComponent(hashValue.value);
176
- });
177
- return hashObj;
178
- }
179
-
180
- function makeHash(obj) {
181
- return Object.keys(obj)
182
- .map((key) => {
183
- return `${key}${kEquals}${obj[key]}`;
184
- })
185
- .join(kAnd);
186
- }
187
-
188
- function setHash(obj) {
189
- const hash = makeHash(obj);
190
- window.history.pushState(null, null, `#${hash}`);
191
- }
192
-
193
- function showPage(listingId, page) {
194
- const list = window["quarto-listings"][listingId];
195
- if (list) {
196
- list.show((page - 1) * list.page + 1, list.page);
197
- }
198
- }
199
-
200
- function activateCategory(category) {
201
- // Deactivate existing categories
202
- const activeEls = window.document.querySelectorAll(
203
- ".quarto-listing-category .category.active"
204
- );
205
- for (const activeEl of activeEls) {
206
- activeEl.classList.remove("active");
207
- }
208
-
209
- // Activate this category
210
- const categoryEl = window.document.querySelector(
211
- `.quarto-listing-category .category[data-category='${category}'`
212
- );
213
- if (categoryEl) {
214
- categoryEl.classList.add("active");
215
- }
216
-
217
- // Filter the listings to this category
218
- filterListingCategory(category);
219
- }
220
-
221
- function filterListingCategory(category) {
222
- const listingIds = Object.keys(window["quarto-listings"]);
223
- for (const listingId of listingIds) {
224
- const list = window["quarto-listings"][listingId];
225
- if (list) {
226
- if (category === "") {
227
- // resets the filter
228
- list.filter();
229
- } else {
230
- // filter to this category
231
- list.filter(function (item) {
232
- const itemValues = item.values();
233
- if (itemValues.categories !== null) {
234
- const categories = itemValues.categories.split(",");
235
- return categories.includes(category);
236
- } else {
237
- return false;
238
- }
239
- });
240
- }
241
- }
242
- }
243
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/site_libs/quarto-nav/headroom.min.js DELETED
@@ -1,7 +0,0 @@
1
- /*!
2
- * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it
3
- * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js
4
- * License: MIT
5
- */
6
-
7
- !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=l<t?"down":"up",a.distance=Math.abs(t-l),a.isOutOfBounds=t<0||o<t+n,a.top=t<=s.offset[a.direction],a.bottom=o<=t+n,a.toleranceExceeded=a.distance>s.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s});
 
 
 
 
 
 
 
 
_site/site_libs/quarto-nav/quarto-nav.js DELETED
@@ -1,288 +0,0 @@
1
- const headroomChanged = new CustomEvent("quarto-hrChanged", {
2
- detail: {},
3
- bubbles: true,
4
- cancelable: false,
5
- composed: false,
6
- });
7
-
8
- window.document.addEventListener("DOMContentLoaded", function () {
9
- let init = false;
10
-
11
- // Manage the back to top button, if one is present.
12
- let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
13
- const scrollDownBuffer = 5;
14
- const scrollUpBuffer = 35;
15
- const btn = document.getElementById("quarto-back-to-top");
16
- const hideBackToTop = () => {
17
- btn.style.display = "none";
18
- };
19
- const showBackToTop = () => {
20
- btn.style.display = "inline-block";
21
- };
22
- if (btn) {
23
- window.document.addEventListener(
24
- "scroll",
25
- function () {
26
- const currentScrollTop =
27
- window.pageYOffset || document.documentElement.scrollTop;
28
-
29
- // Shows and hides the button 'intelligently' as the user scrolls
30
- if (currentScrollTop - scrollDownBuffer > lastScrollTop) {
31
- hideBackToTop();
32
- lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
33
- } else if (currentScrollTop < lastScrollTop - scrollUpBuffer) {
34
- showBackToTop();
35
- lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop;
36
- }
37
-
38
- // Show the button at the bottom, hides it at the top
39
- if (currentScrollTop <= 0) {
40
- hideBackToTop();
41
- } else if (
42
- window.innerHeight + currentScrollTop >=
43
- document.body.offsetHeight
44
- ) {
45
- showBackToTop();
46
- }
47
- },
48
- false
49
- );
50
- }
51
-
52
- function throttle(func, wait) {
53
- var timeout;
54
- return function () {
55
- const context = this;
56
- const args = arguments;
57
- const later = function () {
58
- clearTimeout(timeout);
59
- timeout = null;
60
- func.apply(context, args);
61
- };
62
-
63
- if (!timeout) {
64
- timeout = setTimeout(later, wait);
65
- }
66
- };
67
- }
68
-
69
- function headerOffset() {
70
- // Set an offset if there is are fixed top navbar
71
- const headerEl = window.document.querySelector("header.fixed-top");
72
- if (headerEl) {
73
- return headerEl.clientHeight;
74
- } else {
75
- return 0;
76
- }
77
- }
78
-
79
- function footerOffset() {
80
- const footerEl = window.document.querySelector("footer.footer");
81
- if (footerEl) {
82
- return footerEl.clientHeight;
83
- } else {
84
- return 0;
85
- }
86
- }
87
-
88
- function dashboardOffset() {
89
- const dashboardNavEl = window.document.getElementById(
90
- "quarto-dashboard-header"
91
- );
92
- if (dashboardNavEl !== null) {
93
- return dashboardNavEl.clientHeight;
94
- } else {
95
- return 0;
96
- }
97
- }
98
-
99
- function updateDocumentOffsetWithoutAnimation() {
100
- updateDocumentOffset(false);
101
- }
102
-
103
- function updateDocumentOffset(animated) {
104
- // set body offset
105
- const topOffset = headerOffset();
106
- const bodyOffset = topOffset + footerOffset() + dashboardOffset();
107
- const bodyEl = window.document.body;
108
- bodyEl.setAttribute("data-bs-offset", topOffset);
109
- bodyEl.style.paddingTop = topOffset + "px";
110
-
111
- // deal with sidebar offsets
112
- const sidebars = window.document.querySelectorAll(
113
- ".sidebar, .headroom-target"
114
- );
115
- sidebars.forEach((sidebar) => {
116
- if (!animated) {
117
- sidebar.classList.add("notransition");
118
- // Remove the no transition class after the animation has time to complete
119
- setTimeout(function () {
120
- sidebar.classList.remove("notransition");
121
- }, 201);
122
- }
123
-
124
- if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) {
125
- sidebar.style.top = "0";
126
- sidebar.style.maxHeight = "100vh";
127
- } else {
128
- sidebar.style.top = topOffset + "px";
129
- sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)";
130
- }
131
- });
132
-
133
- // allow space for footer
134
- const mainContainer = window.document.querySelector(".quarto-container");
135
- if (mainContainer) {
136
- mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)";
137
- }
138
-
139
- // link offset
140
- let linkStyle = window.document.querySelector("#quarto-target-style");
141
- if (!linkStyle) {
142
- linkStyle = window.document.createElement("style");
143
- linkStyle.setAttribute("id", "quarto-target-style");
144
- window.document.head.appendChild(linkStyle);
145
- }
146
- while (linkStyle.firstChild) {
147
- linkStyle.removeChild(linkStyle.firstChild);
148
- }
149
- if (topOffset > 0) {
150
- linkStyle.appendChild(
151
- window.document.createTextNode(`
152
- section:target::before {
153
- content: "";
154
- display: block;
155
- height: ${topOffset}px;
156
- margin: -${topOffset}px 0 0;
157
- }`)
158
- );
159
- }
160
- if (init) {
161
- window.dispatchEvent(headroomChanged);
162
- }
163
- init = true;
164
- }
165
-
166
- // initialize headroom
167
- var header = window.document.querySelector("#quarto-header");
168
- if (header && window.Headroom) {
169
- const headroom = new window.Headroom(header, {
170
- tolerance: 5,
171
- onPin: function () {
172
- const sidebars = window.document.querySelectorAll(
173
- ".sidebar, .headroom-target"
174
- );
175
- sidebars.forEach((sidebar) => {
176
- sidebar.classList.remove("sidebar-unpinned");
177
- });
178
- updateDocumentOffset();
179
- },
180
- onUnpin: function () {
181
- const sidebars = window.document.querySelectorAll(
182
- ".sidebar, .headroom-target"
183
- );
184
- sidebars.forEach((sidebar) => {
185
- sidebar.classList.add("sidebar-unpinned");
186
- });
187
- updateDocumentOffset();
188
- },
189
- });
190
- headroom.init();
191
-
192
- let frozen = false;
193
- window.quartoToggleHeadroom = function () {
194
- if (frozen) {
195
- headroom.unfreeze();
196
- frozen = false;
197
- } else {
198
- headroom.freeze();
199
- frozen = true;
200
- }
201
- };
202
- }
203
-
204
- window.addEventListener(
205
- "hashchange",
206
- function (e) {
207
- if (
208
- getComputedStyle(document.documentElement).scrollBehavior !== "smooth"
209
- ) {
210
- window.scrollTo(0, window.pageYOffset - headerOffset());
211
- }
212
- },
213
- false
214
- );
215
-
216
- // Observe size changed for the header
217
- const headerEl = window.document.querySelector("header.fixed-top");
218
- if (headerEl && window.ResizeObserver) {
219
- const observer = new window.ResizeObserver(() => {
220
- setTimeout(updateDocumentOffsetWithoutAnimation, 0);
221
- });
222
- observer.observe(headerEl, {
223
- attributes: true,
224
- childList: true,
225
- characterData: true,
226
- });
227
- } else {
228
- window.addEventListener(
229
- "resize",
230
- throttle(updateDocumentOffsetWithoutAnimation, 50)
231
- );
232
- }
233
- setTimeout(updateDocumentOffsetWithoutAnimation, 250);
234
-
235
- // fixup index.html links if we aren't on the filesystem
236
- if (window.location.protocol !== "file:") {
237
- const links = window.document.querySelectorAll("a");
238
- for (let i = 0; i < links.length; i++) {
239
- if (links[i].href) {
240
- links[i].href = links[i].href.replace(/\/index\.html/, "/");
241
- }
242
- }
243
-
244
- // Fixup any sharing links that require urls
245
- // Append url to any sharing urls
246
- const sharingLinks = window.document.querySelectorAll(
247
- "a.sidebar-tools-main-item, a.quarto-navigation-tool, a.quarto-navbar-tools, a.quarto-navbar-tools-item"
248
- );
249
- for (let i = 0; i < sharingLinks.length; i++) {
250
- const sharingLink = sharingLinks[i];
251
- const href = sharingLink.getAttribute("href");
252
- if (href) {
253
- sharingLink.setAttribute(
254
- "href",
255
- href.replace("|url|", window.location.href)
256
- );
257
- }
258
- }
259
-
260
- // Scroll the active navigation item into view, if necessary
261
- const navSidebar = window.document.querySelector("nav#quarto-sidebar");
262
- if (navSidebar) {
263
- // Find the active item
264
- const activeItem = navSidebar.querySelector("li.sidebar-item a.active");
265
- if (activeItem) {
266
- // Wait for the scroll height and height to resolve by observing size changes on the
267
- // nav element that is scrollable
268
- const resizeObserver = new ResizeObserver((_entries) => {
269
- // The bottom of the element
270
- const elBottom = activeItem.offsetTop;
271
- const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight;
272
-
273
- // The element height and scroll height are the same, then we are still loading
274
- if (viewBottom !== navSidebar.scrollHeight) {
275
- // Determine if the item isn't visible and scroll to it
276
- if (elBottom >= viewBottom) {
277
- navSidebar.scrollTop = elBottom;
278
- }
279
-
280
- // stop observing now since we've completed the scroll
281
- resizeObserver.unobserve(navSidebar);
282
- }
283
- });
284
- resizeObserver.observe(navSidebar);
285
- }
286
- }
287
- }
288
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
_site/site_libs/quarto-search/autocomplete.umd.js DELETED
@@ -1,3 +0,0 @@
1
- /*! @algolia/autocomplete-js 1.11.1 | MIT License | © Algolia, Inc. and contributors | https://github.com/algolia/autocomplete */
2
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["@algolia/autocomplete-js"]={})}(this,(function(e){"use strict";function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function n(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?t(Object(r),!0).forEach((function(t){o(e,t,r[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):t(Object(r)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))}))}return e}function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}function o(e,t,n){return(t=function(e){var t=function(e,t){if("object"!=typeof e||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!=typeof r)return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}function u(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function a(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,u,a=[],l=!0,c=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=i.call(n)).done)&&(a.push(r.value),a.length!==t);l=!0);}catch(e){c=!0,o=e}finally{try{if(!l&&null!=n.return&&(u=n.return(),Object(u)!==u))return}finally{if(c)throw o}}return a}}(e,t)||c(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(e){return function(e){if(Array.isArray(e))return s(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||c(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function c(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function f(e){return{current:e}}function p(e,t){var n=void 0;return function(){for(var r=arguments.length,o=new Array(r),i=0;i<r;i++)o[i]=arguments[i];n&&clearTimeout(n),n=setTimeout((function(){return e.apply(void 0,o)}),t)}}function m(e){return e.reduce((function(e,t){return e.concat(t)}),[])}var v=0;function d(){return"autocomplete-".concat(v++)}function y(e,t){return t.reduce((function(e,t){return e&&e[t]}),e)}function b(e){return 0===e.collections.length?0:e.collections.reduce((function(e,t){return e+t.items.length}),0)}function g(e){return e!==Object(e)}function h(e,t){if(e===t)return!0;if(g(e)||g(t)||"function"==typeof e||"function"==typeof t)return e===t;if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n=0,r=Object.keys(e);n<r.length;n++){var o=r[n];if(!(o in t))return!1;if(!h(e[o],t[o]))return!1}return!0}var O=function(){};var _="1.11.1",S=[{segment:"autocomplete-core",version:_}];function j(e){var t=e.item,n=e.items,r=void 0===n?[]:n;return{index:t.__autocomplete_indexName,items:[t],positions:[1+r.findIndex((function(e){return e.objectID===t.objectID}))],queryID:t.__autocomplete_queryID,algoliaSource:["autocomplete"]}}function P(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,i,u,a=[],l=!0,c=!1;try{if(i=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;l=!1}else for(;!(l=(r=i.call(n)).done)&&(a.push(r.value),a.length!==t);l=!0);}catch(e){c=!0,o=e}finally{try{if(!l&&null!=n.return&&(u=n.return(),Object(u)!==u))return}finally{if(c)throw o}}return a}}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return w(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return w(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function w(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var I=["items"],A=["items"];function E(e){return E="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},E(e)}function D(e){return function(e){if(Array.isArray(e))return C(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return C(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return C(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function C(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function k(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function x(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function N(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?x(Object(n),!0).forEach((function(t){T(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):x(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function T(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==E(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==E(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===E(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function q(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:20,n=[],r=0;r<e.objectIDs.length;r+=t)n.push(N(N({},e),{},{objectIDs:e.objectIDs.slice(r,r+t)}));return n}function B(e){return e.map((function(e){var t=e.items,n=k(e,I);return N(N({},n),{},{objectIDs:(null==t?void 0:t.map((function(e){return e.objectID})))||n.objectIDs})}))}function R(e){var t,n,r,o=(t=P((e.version||"").split(".").map(Number),2),n=t[0],r=t[1],n>=3||2===n&&r>=4||1===n&&r>=10);function i(t,n,r){if(o&&void 0!==r){var i=r[0].__autocomplete_algoliaCredentials,u={"X-Algolia-Application-Id":i.appId,"X-Algolia-API-Key":i.apiKey};e.apply(void 0,[t].concat(D(n),[{headers:u}]))}else e.apply(void 0,[t].concat(D(n)))}return{init:function(t,n){e("init",{appId:t,apiKey:n})},setUserToken:function(t){e("setUserToken",t)},clickedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];t.length>0&&i("clickedObjectIDsAfterSearch",B(t),t[0].items)},clickedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];t.length>0&&i("clickedObjectIDs",B(t),t[0].items)},clickedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.length>0&&e.apply(void 0,["clickedFilters"].concat(n))},convertedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];t.length>0&&i("convertedObjectIDsAfterSearch",B(t),t[0].items)},convertedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];t.length>0&&i("convertedObjectIDs",B(t),t[0].items)},convertedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.length>0&&e.apply(void 0,["convertedFilters"].concat(n))},viewedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];t.length>0&&t.reduce((function(e,t){var n=t.items,r=k(t,A);return[].concat(D(e),D(q(N(N({},r),{},{objectIDs:(null==n?void 0:n.map((function(e){return e.objectID})))||r.objectIDs})).map((function(e){return{items:n,payload:e}}))))}),[]).forEach((function(e){var t=e.items;return i("viewedObjectIDs",[e.payload],t)}))},viewedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.length>0&&e.apply(void 0,["viewedFilters"].concat(n))}}}function F(e){var t=e.items.reduce((function(e,t){var n;return e[t.__autocomplete_indexName]=(null!==(n=e[t.__autocomplete_indexName])&&void 0!==n?n:[]).concat(t),e}),{});return Object.keys(t).map((function(e){return{index:e,items:t[e],algoliaSource:["autocomplete"]}}))}function L(e){return e.objectID&&e.__autocomplete_indexName&&e.__autocomplete_queryID}function U(e){return U="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},U(e)}function M(e){return function(e){if(Array.isArray(e))return H(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return H(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return H(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function H(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function V(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function W(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?V(Object(n),!0).forEach((function(t){K(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):V(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function K(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==U(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==U(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===U(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Q="2.6.0",$="https://cdn.jsdelivr.net/npm/search-insights@".concat(Q,"/dist/search-insights.min.js"),z=p((function(e){var t=e.onItemsChange,n=e.items,r=e.insights,o=e.state;t({insights:r,insightsEvents:F({items:n}).map((function(e){return W({eventName:"Items Viewed"},e)})),state:o})}),400);function G(e){var t=function(e){return W({onItemsChange:function(e){var t=e.insights,n=e.insightsEvents;t.viewedObjectIDs.apply(t,M(n.map((function(e){return W(W({},e),{},{algoliaSource:[].concat(M(e.algoliaSource||[]),["autocomplete-internal"])})}))))},onSelect:function(e){var t=e.insights,n=e.insightsEvents;t.clickedObjectIDsAfterSearch.apply(t,M(n.map((function(e){return W(W({},e),{},{algoliaSource:[].concat(M(e.algoliaSource||[]),["autocomplete-internal"])})}))))},onActive:O},e)}(e),n=t.insightsClient,r=t.onItemsChange,o=t.onSelect,i=t.onActive,u=n;n||function(e){if("undefined"!=typeof window)e({window:window})}((function(e){var t=e.window,n=t.AlgoliaAnalyticsObject||"aa";"string"==typeof n&&(u=t[n]),u||(t.AlgoliaAnalyticsObject=n,t[n]||(t[n]=function(){t[n].queue||(t[n].queue=[]);for(var e=arguments.length,r=new Array(e),o=0;o<e;o++)r[o]=arguments[o];t[n].queue.push(r)}),t[n].version=Q,u=t[n],function(e){var t="[Autocomplete]: Could not load search-insights.js. Please load it manually following https://alg.li/insights-autocomplete";try{var n=e.document.createElement("script");n.async=!0,n.src=$,n.onerror=function(){console.error(t)},document.body.appendChild(n)}catch(e){console.error(t)}}(t))}));var a=R(u),l=f([]),c=p((function(e){var t=e.state;if(t.isOpen){var n=t.collections.reduce((function(e,t){return[].concat(M(e),M(t.items))}),[]).filter(L);h(l.current.map((function(e){return e.objectID})),n.map((function(e){return e.objectID})))||(l.current=n,n.length>0&&z({onItemsChange:r,items:n,insights:a,state:t}))}}),0);return{name:"aa.algoliaInsightsPlugin",subscribe:function(e){var t=e.setContext,n=e.onSelect,r=e.onActive;function l(e){t({algoliaInsightsPlugin:{__algoliaSearchParameters:W({clickAnalytics:!0},e?{userToken:e}:{}),insights:a}})}u("addAlgoliaAgent","insights-plugin"),l(),u("onUserTokenChange",l),u("getUserToken",null,(function(e,t){l(t)})),n((function(e){var t=e.item,n=e.state,r=e.event,i=e.source;L(t)&&o({state:n,event:r,insights:a,item:t,insightsEvents:[W({eventName:"Item Selected"},j({item:t,items:i.getItems().filter(L)}))]})})),r((function(e){var t=e.item,n=e.source,r=e.state,o=e.event;L(t)&&i({state:r,event:o,insights:a,item:t,insightsEvents:[W({eventName:"Item Active"},j({item:t,items:n.getItems().filter(L)}))]})}))},onStateChange:function(e){var t=e.state;c({state:t})},__autocomplete_pluginOptions:e}}function J(e,t){var n=t;return{then:function(t,r){return J(e.then(Y(t,n,e),Y(r,n,e)),n)},catch:function(t){return J(e.catch(Y(t,n,e)),n)},finally:function(t){return t&&n.onCancelList.push(t),J(e.finally(Y(t&&function(){return n.onCancelList=[],t()},n,e)),n)},cancel:function(){n.isCanceled=!0;var e=n.onCancelList;n.onCancelList=[],e.forEach((function(e){e()}))},isCanceled:function(){return!0===n.isCanceled}}}function X(e){return J(e,{isCanceled:!1,onCancelList:[]})}function Y(e,t,n){return e?function(n){return t.isCanceled?n:e(n)}:n}function Z(e,t,n,r){if(!n)return null;if(e<0&&(null===t||null!==r&&0===t))return n+e;var o=(null===t?-1:t)+e;return o<=-1||o>=n?null===r?null:0:o}function ee(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function te(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ee(Object(n),!0).forEach((function(t){ne(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ee(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function ne(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==re(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==re(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===re(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function re(e){return re="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},re(e)}function oe(e){var t=function(e){var t=e.collections.map((function(e){return e.items.length})).reduce((function(e,t,n){var r=(e[n-1]||0)+t;return e.push(r),e}),[]).reduce((function(t,n){return n<=e.activeItemId?t+1:t}),0);return e.collections[t]}(e);if(!t)return null;var n=t.items[function(e){for(var t=e.state,n=e.collection,r=!1,o=0,i=0;!1===r;){var u=t.collections[o];if(u===n){r=!0;break}i+=u.items.length,o++}return t.activeItemId-i}({state:e,collection:t})],r=t.source;return{item:n,itemInputValue:r.getItemInputValue({item:n,state:e}),itemUrl:r.getItemUrl({item:n,state:e}),source:r}}function ie(e,t,n){return[e,null==n?void 0:n.sourceId,t].filter(Boolean).join("-").replace(/\s/g,"")}var ue=/((gt|sm)-|galaxy nexus)|samsung[- ]|samsungbrowser/i;function ae(e){return ae="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ae(e)}function le(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ce(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==ae(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==ae(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===ae(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function se(e,t,n){var r,o=t.initialState;return{getState:function(){return o},dispatch:function(r,i){var u=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?le(Object(n),!0).forEach((function(t){ce(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):le(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({},o);o=e(o,{type:r,props:t,payload:i}),n({state:o,prevState:u})},pendingRequests:(r=[],{add:function(e){return r.push(e),e.finally((function(){r=r.filter((function(t){return t!==e}))}))},cancelAll:function(){r.forEach((function(e){return e.cancel()}))},isEmpty:function(){return 0===r.length}})}}function fe(e){return fe="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},fe(e)}function pe(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function me(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?pe(Object(n),!0).forEach((function(t){ve(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):pe(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function ve(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==fe(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==fe(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===fe(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function de(e){return de="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},de(e)}function ye(e){return function(e){if(Array.isArray(e))return be(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return be(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return be(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function be(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function ge(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function he(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ge(Object(n),!0).forEach((function(t){Oe(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ge(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Oe(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==de(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==de(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===de(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _e(e,t){var n,r="undefined"!=typeof window?window:{},o=e.plugins||[];return he(he({debug:!1,openOnFocus:!1,enterKeyHint:void 0,placeholder:"",autoFocus:!1,defaultActiveItemId:null,stallThreshold:300,insights:!1,environment:r,shouldPanelOpen:function(e){return b(e.state)>0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:d(),plugins:o,initialState:he({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var n;null===(n=e.onStateChange)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onStateChange)||void 0===n?void 0:n.call(e,t)}))},onSubmit:function(t){var n;null===(n=e.onSubmit)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onSubmit)||void 0===n?void 0:n.call(e,t)}))},onReset:function(t){var n;null===(n=e.onReset)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onReset)||void 0===n?void 0:n.call(e,t)}))},getSources:function(n){return Promise.all([].concat(ye(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return function(e,t){var n=[];return Promise.resolve(e(t)).then((function(e){return Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,n.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));n.push(e.sourceId);var t={getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:O,onResolve:O};Object.keys(t).forEach((function(e){t[e].__default=!0}));var r=te(te({},t),e);return Promise.resolve(r)})))}))}(e,n)}))).then((function(e){return m(e)})).then((function(e){return e.map((function(e){return he(he({},e),{},{onSelect:function(n){e.onSelect(n),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,n)}))},onActive:function(n){e.onActive(n),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,n)}))},onResolve:function(n){e.onResolve(n),t.forEach((function(e){var t;return null===(t=e.onResolve)||void 0===t?void 0:t.call(e,n)}))}})}))}))},navigator:he({navigate:function(e){var t=e.itemUrl;r.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,n=r.open(t,"_blank","noopener");null==n||n.focus()},navigateNewWindow:function(e){var t=e.itemUrl;r.open(t,"_blank","noopener")}},e.navigator)})}function Se(e){return Se="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Se(e)}function je(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Pe(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?je(Object(n),!0).forEach((function(t){we(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):je(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function we(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Se(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Se(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Se(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ie(e){return Ie="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ie(e)}function Ae(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ee(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Ae(Object(n),!0).forEach((function(t){De(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ae(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function De(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Ie(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Ie(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Ie(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ce(e){return function(e){if(Array.isArray(e))return ke(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return ke(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ke(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ke(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function xe(e){return Boolean(e.execute)}function Ne(e,t,n){if(o=e,Boolean(null==o?void 0:o.execute)){var r="algolia"===e.requesterId?Object.assign.apply(Object,[{}].concat(Ce(Object.keys(n.context).map((function(e){var t;return null===(t=n.context[e])||void 0===t?void 0:t.__algoliaSearchParameters}))))):{};return Ee(Ee({},e),{},{requests:e.queries.map((function(n){return{query:"algolia"===e.requesterId?Ee(Ee({},n),{},{params:Ee(Ee({},r),n.params)}):n,sourceId:t,transformResponse:e.transformResponse}}))})}var o;return{items:e,sourceId:t}}function Te(e){var t=e.reduce((function(e,t){if(!xe(t))return e.push(t),e;var n=t.searchClient,r=t.execute,o=t.requesterId,i=t.requests,u=e.find((function(e){return xe(t)&&xe(e)&&e.searchClient===n&&Boolean(o)&&e.requesterId===o}));if(u){var a;(a=u.items).push.apply(a,Ce(i))}else{var l={execute:r,requesterId:o,items:i,searchClient:n};e.push(l)}return e}),[]).map((function(e){if(!xe(e))return Promise.resolve(e);var t=e,n=t.execute,r=t.items;return n({searchClient:t.searchClient,requests:r})}));return Promise.all(t).then((function(e){return m(e)}))}function qe(e,t,n){return t.map((function(t){var r,o=e.filter((function(e){return e.sourceId===t.sourceId})),i=o.map((function(e){return e.items})),u=o[0].transformResponse,a=u?u({results:r=i,hits:r.map((function(e){return e.hits})).filter(Boolean),facetHits:r.map((function(e){var t;return null===(t=e.facetHits)||void 0===t?void 0:t.map((function(e){return{label:e.value,count:e.count,_highlightResult:{label:{value:e.highlighted}}}}))})).filter(Boolean)}):i;return t.onResolve({source:t,results:i,items:a,state:n.getState()}),a.every(Boolean),'The `getItems` function from source "'.concat(t.sourceId,'" must return an array of items but returned ').concat(JSON.stringify(void 0),".\n\nDid you forget to return items?\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems"),{source:t,items:a}}))}function Be(e){return Be="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Be(e)}var Re=["event","nextState","props","query","refresh","store"];function Fe(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Le(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Fe(Object(n),!0).forEach((function(t){Ue(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Fe(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Ue(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Be(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Be(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Be(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Me(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var He,Ve,We,Ke=null,Qe=(He=-1,Ve=-1,We=void 0,function(e){var t=++He;return Promise.resolve(e).then((function(e){return We&&t<Ve?We:(Ve=t,We=e,e)}))});function $e(e){var t=e.event,n=e.nextState,r=void 0===n?{}:n,o=e.props,i=e.query,u=e.refresh,a=e.store,l=Me(e,Re);Ke&&o.environment.clearTimeout(Ke);var c=l.setCollections,s=l.setIsOpen,f=l.setQuery,p=l.setActiveItemId,v=l.setStatus;if(f(i),p(o.defaultActiveItemId),!i&&!1===o.openOnFocus){var d,y=a.getState().collections.map((function(e){return Le(Le({},e),{},{items:[]})}));v("idle"),c(y),s(null!==(d=r.isOpen)&&void 0!==d?d:o.shouldPanelOpen({state:a.getState()}));var b=X(Qe(y).then((function(){return Promise.resolve()})));return a.pendingRequests.add(b)}v("loading"),Ke=o.environment.setTimeout((function(){v("stalled")}),o.stallThreshold);var g=X(Qe(o.getSources(Le({query:i,refresh:u,state:a.getState()},l)).then((function(e){return Promise.all(e.map((function(e){return Promise.resolve(e.getItems(Le({query:i,refresh:u,state:a.getState()},l))).then((function(t){return Ne(t,e.sourceId,a.getState())}))}))).then(Te).then((function(t){return qe(t,e,a)})).then((function(e){return function(e){var t=e.collections,n=e.props,r=e.state,o=t.reduce((function(e,t){return Pe(Pe({},e),{},we({},t.source.sourceId,Pe(Pe({},t.source),{},{getItems:function(){return m(t.items)}})))}),{}),i=n.plugins.reduce((function(e,t){return t.reshape?t.reshape(e):e}),{sourcesBySourceId:o,state:r}).sourcesBySourceId;return m(n.reshape({sourcesBySourceId:i,sources:Object.values(i),state:r})).filter(Boolean).map((function(e){return{source:e,items:e.getItems()}}))}({collections:e,props:o,state:a.getState()})}))})))).then((function(e){var n;v("idle"),c(e);var f=o.shouldPanelOpen({state:a.getState()});s(null!==(n=r.isOpen)&&void 0!==n?n:o.openOnFocus&&!i&&f||f);var p=oe(a.getState());if(null!==a.getState().activeItemId&&p){var m=p.item,d=p.itemInputValue,y=p.itemUrl,b=p.source;b.onActive(Le({event:t,item:m,itemInputValue:d,itemUrl:y,refresh:u,source:b,state:a.getState()},l))}})).finally((function(){v("idle"),Ke&&o.environment.clearTimeout(Ke)}));return a.pendingRequests.add(g)}function ze(e){return ze="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ze(e)}var Ge=["event","props","refresh","store"];function Je(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Xe(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Je(Object(n),!0).forEach((function(t){Ye(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Je(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Ye(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==ze(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==ze(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===ze(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ze(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function et(e){return et="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},et(e)}var tt=["props","refresh","store"],nt=["inputElement","formElement","panelElement"],rt=["inputElement"],ot=["inputElement","maxLength"],it=["source"],ut=["item","source"];function at(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function lt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?at(Object(n),!0).forEach((function(t){ct(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):at(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function ct(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==et(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==et(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===et(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function st(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function ft(e){var t=e.props,n=e.refresh,r=e.store,o=st(e,tt);return{getEnvironmentProps:function(e){var n=e.inputElement,o=e.formElement,i=e.panelElement;function u(e){!r.getState().isOpen&&r.pendingRequests.isEmpty()||e.target===n||!1===[o,i].some((function(t){return n=t,r=e.target,n===r||n.contains(r);var n,r}))&&(r.dispatch("blur",null),t.debug||r.pendingRequests.cancelAll())}return lt({onTouchStart:u,onMouseDown:u,onTouchMove:function(e){!1!==r.getState().isOpen&&n===t.environment.document.activeElement&&e.target!==n&&n.blur()}},st(e,nt))},getRootProps:function(e){return lt({role:"combobox","aria-expanded":r.getState().isOpen,"aria-haspopup":"listbox","aria-owns":r.getState().isOpen?r.getState().collections.map((function(e){var n=e.source;return ie(t.id,"list",n)})).join(" "):void 0,"aria-labelledby":ie(t.id,"label")},e)},getFormProps:function(e){return e.inputElement,lt({action:"",noValidate:!0,role:"search",onSubmit:function(i){var u;i.preventDefault(),t.onSubmit(lt({event:i,refresh:n,state:r.getState()},o)),r.dispatch("submit",null),null===(u=e.inputElement)||void 0===u||u.blur()},onReset:function(i){var u;i.preventDefault(),t.onReset(lt({event:i,refresh:n,state:r.getState()},o)),r.dispatch("reset",null),null===(u=e.inputElement)||void 0===u||u.focus()}},st(e,rt))},getLabelProps:function(e){return lt({htmlFor:ie(t.id,"input"),id:ie(t.id,"label")},e)},getInputProps:function(e){var i;function u(e){(t.openOnFocus||Boolean(r.getState().query))&&$e(lt({event:e,props:t,query:r.getState().completion||r.getState().query,refresh:n,store:r},o)),r.dispatch("focus",null)}var a=e||{};a.inputElement;var l=a.maxLength,c=void 0===l?512:l,s=st(a,ot),f=oe(r.getState()),p=function(e){return Boolean(e&&e.match(ue))}((null===(i=t.environment.navigator)||void 0===i?void 0:i.userAgent)||""),m=t.enterKeyHint||(null!=f&&f.itemUrl&&!p?"go":"search");return lt({"aria-autocomplete":"both","aria-activedescendant":r.getState().isOpen&&null!==r.getState().activeItemId?ie(t.id,"item-".concat(r.getState().activeItemId),null==f?void 0:f.source):void 0,"aria-controls":r.getState().isOpen?r.getState().collections.map((function(e){var n=e.source;return ie(t.id,"list",n)})).join(" "):void 0,"aria-labelledby":ie(t.id,"label"),value:r.getState().completion||r.getState().query,id:ie(t.id,"input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:m,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:c,type:"search",onChange:function(e){$e(lt({event:e,props:t,query:e.currentTarget.value.slice(0,c),refresh:n,store:r},o))},onKeyDown:function(e){!function(e){var t=e.event,n=e.props,r=e.refresh,o=e.store,i=Ze(e,Ge);if("ArrowUp"===t.key||"ArrowDown"===t.key){var u=function(){var e=oe(o.getState()),t=n.environment.document.getElementById(ie(n.id,"item-".concat(o.getState().activeItemId),null==e?void 0:e.source));t&&(t.scrollIntoViewIfNeeded?t.scrollIntoViewIfNeeded(!1):t.scrollIntoView(!1))},a=function(){var e=oe(o.getState());if(null!==o.getState().activeItemId&&e){var n=e.item,u=e.itemInputValue,a=e.itemUrl,l=e.source;l.onActive(Xe({event:t,item:n,itemInputValue:u,itemUrl:a,refresh:r,source:l,state:o.getState()},i))}};t.preventDefault(),!1===o.getState().isOpen&&(n.openOnFocus||Boolean(o.getState().query))?$e(Xe({event:t,props:n,query:o.getState().query,refresh:r,store:o},i)).then((function(){o.dispatch(t.key,{nextActiveItemId:n.defaultActiveItemId}),a(),setTimeout(u,0)})):(o.dispatch(t.key,{}),a(),u())}else if("Escape"===t.key)t.preventDefault(),o.dispatch(t.key,null),o.pendingRequests.cancelAll();else if("Tab"===t.key)o.dispatch("blur",null),o.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===o.getState().activeItemId||o.getState().collections.every((function(e){return 0===e.items.length})))return void(n.debug||o.pendingRequests.cancelAll());t.preventDefault();var l=oe(o.getState()),c=l.item,s=l.itemInputValue,f=l.itemUrl,p=l.source;if(t.metaKey||t.ctrlKey)void 0!==f&&(p.onSelect(Xe({event:t,item:c,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},i)),n.navigator.navigateNewTab({itemUrl:f,item:c,state:o.getState()}));else if(t.shiftKey)void 0!==f&&(p.onSelect(Xe({event:t,item:c,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},i)),n.navigator.navigateNewWindow({itemUrl:f,item:c,state:o.getState()}));else if(t.altKey);else{if(void 0!==f)return p.onSelect(Xe({event:t,item:c,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},i)),void n.navigator.navigate({itemUrl:f,item:c,state:o.getState()});$e(Xe({event:t,nextState:{isOpen:!1},props:n,query:s,refresh:r,store:o},i)).then((function(){p.onSelect(Xe({event:t,item:c,itemInputValue:s,itemUrl:f,refresh:r,source:p,state:o.getState()},i))}))}}}(lt({event:e,props:t,refresh:n,store:r},o))},onFocus:u,onBlur:O,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||u(n)}},s)},getPanelProps:function(e){return lt({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){var n=e||{},r=n.source,o=st(n,it);return lt({role:"listbox","aria-labelledby":ie(t.id,"label"),id:ie(t.id,"list",r)},o)},getItemProps:function(e){var i=e.item,u=e.source,a=st(e,ut);return lt({id:ie(t.id,"item-".concat(i.__autocomplete_id),u),role:"option","aria-selected":r.getState().activeItemId===i.__autocomplete_id,onMouseMove:function(e){if(i.__autocomplete_id!==r.getState().activeItemId){r.dispatch("mousemove",i.__autocomplete_id);var t=oe(r.getState());if(null!==r.getState().activeItemId&&t){var u=t.item,a=t.itemInputValue,l=t.itemUrl,c=t.source;c.onActive(lt({event:e,item:u,itemInputValue:a,itemUrl:l,refresh:n,source:c,state:r.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var a=u.getItemInputValue({item:i,state:r.getState()}),l=u.getItemUrl({item:i,state:r.getState()});(l?Promise.resolve():$e(lt({event:e,nextState:{isOpen:!1},props:t,query:a,refresh:n,store:r},o))).then((function(){u.onSelect(lt({event:e,item:i,itemInputValue:a,itemUrl:l,refresh:n,source:u,state:r.getState()},o))}))}},a)}}}function pt(e){return pt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},pt(e)}function mt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function vt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?mt(Object(n),!0).forEach((function(t){dt(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):mt(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function dt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==pt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==pt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===pt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function yt(e){var t,n,r,o,i=e.plugins,u=e.options,a=null===(t=((null===(n=u.__autocomplete_metadata)||void 0===n?void 0:n.userAgents)||[])[0])||void 0===t?void 0:t.segment,l=a?dt({},a,Object.keys((null===(r=u.__autocomplete_metadata)||void 0===r?void 0:r.options)||{})):{};return{plugins:i.map((function(e){return{name:e.name,options:Object.keys(e.__autocomplete_pluginOptions||[])}})),options:vt({"autocomplete-core":Object.keys(u)},l),ua:S.concat((null===(o=u.__autocomplete_metadata)||void 0===o?void 0:o.userAgents)||[])}}function bt(e){var t,n=e.state;return!1===n.isOpen||null===n.activeItemId?null:(null===(t=oe(n))||void 0===t?void 0:t.itemInputValue)||null}function gt(e){return gt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},gt(e)}function ht(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ot(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ht(Object(n),!0).forEach((function(t){_t(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ht(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function _t(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==gt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==gt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===gt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var St=function(e,t){switch(t.type){case"setActiveItemId":case"mousemove":return Ot(Ot({},e),{},{activeItemId:t.payload});case"setQuery":return Ot(Ot({},e),{},{query:t.payload,completion:null});case"setCollections":return Ot(Ot({},e),{},{collections:t.payload});case"setIsOpen":return Ot(Ot({},e),{},{isOpen:t.payload});case"setStatus":return Ot(Ot({},e),{},{status:t.payload});case"setContext":return Ot(Ot({},e),{},{context:Ot(Ot({},e.context),t.payload)});case"ArrowDown":var n=Ot(Ot({},e),{},{activeItemId:t.payload.hasOwnProperty("nextActiveItemId")?t.payload.nextActiveItemId:Z(1,e.activeItemId,b(e),t.props.defaultActiveItemId)});return Ot(Ot({},n),{},{completion:bt({state:n})});case"ArrowUp":var r=Ot(Ot({},e),{},{activeItemId:Z(-1,e.activeItemId,b(e),t.props.defaultActiveItemId)});return Ot(Ot({},r),{},{completion:bt({state:r})});case"Escape":return e.isOpen?Ot(Ot({},e),{},{activeItemId:null,isOpen:!1,completion:null}):Ot(Ot({},e),{},{activeItemId:null,query:"",status:"idle",collections:[]});case"submit":return Ot(Ot({},e),{},{activeItemId:null,isOpen:!1,status:"idle"});case"reset":return Ot(Ot({},e),{},{activeItemId:!0===t.props.openOnFocus?t.props.defaultActiveItemId:null,status:"idle",query:""});case"focus":return Ot(Ot({},e),{},{activeItemId:t.props.defaultActiveItemId,isOpen:(t.props.openOnFocus||Boolean(e.query))&&t.props.shouldPanelOpen({state:e})});case"blur":return t.props.debug?e:Ot(Ot({},e),{},{isOpen:!1,activeItemId:null});case"mouseleave":return Ot(Ot({},e),{},{activeItemId:t.props.defaultActiveItemId});default:return"The reducer action ".concat(JSON.stringify(t.type)," is not supported."),e}};function jt(e){return jt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},jt(e)}function Pt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function wt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Pt(Object(n),!0).forEach((function(t){It(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Pt(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function It(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==jt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==jt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===jt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function At(e){var t=[],n=_e(e,t),r=se(St,n,(function(e){var t=e.prevState,r=e.state;n.onStateChange(wt({prevState:t,state:r,refresh:u,navigator:n.navigator},o))})),o=function(e){var t=e.store;return{setActiveItemId:function(e){t.dispatch("setActiveItemId",e)},setQuery:function(e){t.dispatch("setQuery",e)},setCollections:function(e){var n=0,r=e.map((function(e){return me(me({},e),{},{items:m(e.items).map((function(e){return me(me({},e),{},{__autocomplete_id:n++})}))})}));t.dispatch("setCollections",r)},setIsOpen:function(e){t.dispatch("setIsOpen",e)},setStatus:function(e){t.dispatch("setStatus",e)},setContext:function(e){t.dispatch("setContext",e)}}}({store:r}),i=ft(wt({props:n,refresh:u,store:r,navigator:n.navigator},o));function u(){return $e(wt({event:new Event("input"),nextState:{isOpen:r.getState().isOpen},props:n,navigator:n.navigator,query:r.getState().query,refresh:u,store:r},o))}if(e.insights&&!n.plugins.some((function(e){return"aa.algoliaInsightsPlugin"===e.name}))){var a="boolean"==typeof e.insights?{}:e.insights;n.plugins.push(G(a))}return n.plugins.forEach((function(e){var r;return null===(r=e.subscribe)||void 0===r?void 0:r.call(e,wt(wt({},o),{},{navigator:n.navigator,refresh:u,onSelect:function(e){t.push({onSelect:e})},onActive:function(e){t.push({onActive:e})},onResolve:function(e){t.push({onResolve:e})}}))})),function(e){var t,n,r=e.metadata,o=e.environment;if(null===(t=o.navigator)||void 0===t||null===(n=t.userAgent)||void 0===n?void 0:n.includes("Algolia Crawler")){var i=o.document.createElement("meta"),u=o.document.querySelector("head");i.name="algolia:metadata",setTimeout((function(){i.content=JSON.stringify(r),u.appendChild(i)}),0)}}({metadata:yt({plugins:n.plugins,options:e}),environment:n.environment}),wt(wt({refresh:u,navigator:n.navigator},i),o)}var Et=function(e,t,n,r){var o;t[0]=0;for(var i=1;i<t.length;i++){var u=t[i++],a=t[i]?(t[0]|=u?1:2,n[t[i++]]):t[++i];3===u?r[0]=a:4===u?r[1]=Object.assign(r[1]||{},a):5===u?(r[1]=r[1]||{})[t[++i]]=a:6===u?r[1][t[++i]]+=a+"":u?(o=e.apply(a,Et(e,a,n,["",null])),r.push(o),a[0]?t[0]|=2:(t[i-2]=0,t[i]=o)):r.push(a)}return r},Dt=new Map;function Ct(e){var t=Dt.get(this);return t||(t=new Map,Dt.set(this,t)),(t=Et(this,t.get(e)||(t.set(e,t=function(e){for(var t,n,r=1,o="",i="",u=[0],a=function(e){1===r&&(e||(o=o.replace(/^\s*\n\s*|\s*\n\s*$/g,"")))?u.push(0,e,o):3===r&&(e||o)?(u.push(3,e,o),r=2):2===r&&"..."===o&&e?u.push(4,e,0):2===r&&o&&!e?u.push(5,0,!0,o):r>=5&&((o||!e&&5===r)&&(u.push(r,0,o,n),r=6),e&&(u.push(r,e,0,n),r=6)),o=""},l=0;l<e.length;l++){l&&(1===r&&a(),a(l));for(var c=0;c<e[l].length;c++)t=e[l][c],1===r?"<"===t?(a(),u=[u],r=3):o+=t:4===r?"--"===o&&">"===t?(r=1,o=""):o=t+o[0]:i?t===i?i="":o+=t:'"'===t||"'"===t?i=t:">"===t?(a(),r=1):r&&("="===t?(r=5,n=o,o=""):"/"===t&&(r<5||">"===e[l][c+1])?(a(),3===r&&(u=u[0]),r=u,(u=u[0]).push(2,0,r),r=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(a(),r=2):o+=t),3===r&&"!--"===o&&(r=4,u=u[0])}return a(),u}(e)),t),arguments,[])).length>1?t:t[0]}var kt=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-ClearIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","18"),n.setAttribute("height","18"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M5.293 6.707l5.293 5.293-5.293 5.293c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0l5.293-5.293 5.293 5.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-5.293-5.293 5.293-5.293c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-5.293 5.293-5.293-5.293c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414z"),n.appendChild(r),n};function xt(e,t){if("string"==typeof t){var n=e.document.querySelector(t);return"The element ".concat(JSON.stringify(t)," is not in the document."),n}return t}function Nt(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.reduce((function(e,t){return Object.keys(t).forEach((function(n){var r=e[n],o=t[n];r!==o&&(e[n]=[r,o].filter(Boolean).join(" "))})),e}),{})}var Tt=function(e){return e&&"object"===r(e)&&"[object Object]"===Object.prototype.toString.call(e)};function qt(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.reduce((function(e,t){return Object.keys(t).forEach((function(n){var r=e[n],o=t[n];Array.isArray(r)&&Array.isArray(o)?e[n]=r.concat.apply(r,l(o)):Tt(r)&&Tt(o)?e[n]=qt(r,o):e[n]=o})),e}),{})}function Bt(e,t){return Object.entries(e).reduce((function(e,r){var i=a(r,2),u=i[0],l=i[1];return t({key:u,value:l})?n(n({},e),{},o({},u,l)):e}),{})}var Rt=["ontouchstart","ontouchend","ontouchmove","ontouchcancel"];function Ft(e,t,n){e[t]=null===n?"":"number"!=typeof n?n:n+"px"}function Lt(e){this._listeners[e.type](e)}function Ut(e,t,n){var r,o,i=e[t];if("style"===t)if("string"==typeof n)e.style=n;else if(null===n)e.style="";else for(t in n)i&&n[t]===i[t]||Ft(e.style,t,n[t]);else"o"===t[0]&&"n"===t[1]?(r=t!==(t=t.replace(/Capture$/,"")),((o=t.toLowerCase())in e||Rt.includes(o))&&(t=o),t=t.slice(2),e._listeners||(e._listeners={}),e._listeners[t]=n,n?i||e.addEventListener(t,Lt,r):e.removeEventListener(t,Lt,r)):"list"!==t&&"tagName"!==t&&"form"!==t&&"type"!==t&&"size"!==t&&"download"!==t&&"href"!==t&&t in e?e[t]=null==n?"":n:"function"!=typeof n&&"dangerouslySetInnerHTML"!==t&&(null==n||!1===n&&!/^ar/.test(t)?e.removeAttribute(t):e.setAttribute(t,n))}function Mt(e){return"onChange"===e?"onInput":e}function Ht(e,t){for(var n in t)Ut(e,Mt(n),t[n])}function Vt(e,t){for(var n in t)"o"===n[0]&&"n"===n[1]||Ut(e,Mt(n),t[n])}var Wt=["children"];function Kt(e){return function(t,n){var r=n.children,o=void 0===r?[]:r,i=u(n,Wt),a=e.document.createElement(t);return Ht(a,i),a.append.apply(a,l(o)),a}}var Qt=["autocompleteScopeApi","environment","classNames","getInputProps","getInputPropsCore","isDetached","state"],$t=function(e){var t=e.environment.document.createElementNS("http://www.w3.org/2000/svg","svg");return t.setAttribute("class","aa-LoadingIcon"),t.setAttribute("viewBox","0 0 100 100"),t.setAttribute("width","20"),t.setAttribute("height","20"),t.innerHTML='<circle\n cx="50"\n cy="50"\n fill="none"\n r="35"\n stroke="currentColor"\n stroke-dasharray="164.93361431346415 56.97787143782138"\n stroke-width="6"\n>\n <animateTransform\n attributeName="transform"\n type="rotate"\n repeatCount="indefinite"\n dur="1s"\n values="0 50 50;90 50 50;180 50 50;360 50 50"\n keyTimes="0;0.40;0.65;1"\n />\n</circle>',t},zt=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-SubmitIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","20"),n.setAttribute("height","20"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M16.041 15.856c-0.034 0.026-0.067 0.055-0.099 0.087s-0.060 0.064-0.087 0.099c-1.258 1.213-2.969 1.958-4.855 1.958-1.933 0-3.682-0.782-4.95-2.050s-2.050-3.017-2.050-4.95 0.782-3.682 2.050-4.95 3.017-2.050 4.95-2.050 3.682 0.782 4.95 2.050 2.050 3.017 2.050 4.95c0 1.886-0.745 3.597-1.959 4.856zM21.707 20.293l-3.675-3.675c1.231-1.54 1.968-3.493 1.968-5.618 0-2.485-1.008-4.736-2.636-6.364s-3.879-2.636-6.364-2.636-4.736 1.008-6.364 2.636-2.636 3.879-2.636 6.364 1.008 4.736 2.636 6.364 3.879 2.636 6.364 2.636c2.125 0 4.078-0.737 5.618-1.968l3.675 3.675c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414z"),n.appendChild(r),n};function Gt(e){var t=e.autocomplete,r=e.autocompleteScopeApi,o=e.classNames,i=e.environment,a=e.isDetached,l=e.placeholder,c=void 0===l?"Search":l,s=e.propGetters,f=e.setIsModalOpen,p=e.state,m=e.translations,v=Kt(i),d=s.getRootProps(n({state:p,props:t.getRootProps({})},r)),y=v("div",n({class:o.root},d)),b=v("div",{class:o.detachedContainer,onMouseDown:function(e){e.stopPropagation()}}),g=v("div",{class:o.detachedOverlay,children:[b],onMouseDown:function(){f(!1),t.setIsOpen(!1)}}),h=s.getLabelProps(n({state:p,props:t.getLabelProps({})},r)),O=v("button",{class:o.submitButton,type:"submit",title:m.submitButtonTitle,children:[zt({environment:i})]}),_=v("label",n({class:o.label,children:[O]},h)),S=v("button",{class:o.clearButton,type:"reset",title:m.clearButtonTitle,children:[kt({environment:i})]}),j=v("div",{class:o.loadingIndicator,children:[$t({environment:i})]}),P=function(e){var t=e.autocompleteScopeApi,r=e.environment;e.classNames;var o=e.getInputProps,i=e.getInputPropsCore,a=e.isDetached,l=e.state,c=u(e,Qt),s=Kt(r)("input",c),f=o(n({state:l,props:i({inputElement:s}),inputElement:s},t));return Ht(s,n(n({},f),{},{onKeyDown:function(e){a&&"Tab"===e.key||f.onKeyDown(e)}})),s}({class:o.input,environment:i,state:p,getInputProps:s.getInputProps,getInputPropsCore:t.getInputProps,autocompleteScopeApi:r,isDetached:a}),w=v("div",{class:o.inputWrapperPrefix,children:[_,j]}),I=v("div",{class:o.inputWrapperSuffix,children:[S]}),A=v("div",{class:o.inputWrapper,children:[P]}),E=s.getFormProps(n({state:p,props:t.getFormProps({inputElement:P})},r)),D=v("form",n({class:o.form,children:[w,A,I]},E)),C=s.getPanelProps(n({state:p,props:t.getPanelProps({})},r)),k=v("div",n({class:o.panel},C)),x=v("div",{class:o.detachedSearchButtonQuery,textContent:p.query}),N=v("div",{class:o.detachedSearchButtonPlaceholder,hidden:Boolean(p.query),textContent:c});if(a){var T=v("div",{class:o.detachedSearchButtonIcon,children:[zt({environment:i})]}),q=v("button",{type:"button",class:o.detachedSearchButton,onClick:function(){f(!0)},children:[T,N,x]}),B=v("button",{type:"button",class:o.detachedCancelButton,textContent:m.detachedCancelButtonText,onTouchStart:function(e){e.stopPropagation()},onClick:function(){t.setIsOpen(!1),f(!1)}}),R=v("div",{class:o.detachedFormContainer,children:[D,B]});b.appendChild(R),y.appendChild(q)}else y.appendChild(D);return{detachedContainer:b,detachedOverlay:g,detachedSearchButtonQuery:x,detachedSearchButtonPlaceholder:N,inputWrapper:A,input:P,root:y,form:D,label:_,submitButton:O,clearButton:S,loadingIndicator:j,panel:k}}var Jt,Xt,Yt,Zt,en,tn,nn,rn={},on=[],un=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function an(e,t){for(var n in t)e[n]=t[n];return e}function ln(e){var t=e.parentNode;t&&t.removeChild(e)}function cn(e,t,n){var r,o,i,u={};for(i in t)"key"==i?r=t[i]:"ref"==i?o=t[i]:u[i]=t[i];if(arguments.length>2&&(u.children=arguments.length>3?Jt.call(arguments,2):n),"function"==typeof e&&null!=e.defaultProps)for(i in e.defaultProps)void 0===u[i]&&(u[i]=e.defaultProps[i]);return sn(e,u,r,o,null)}function sn(e,t,n,r,o){var i={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++Yt:o};return null==o&&null!=Xt.vnode&&Xt.vnode(i),i}function fn(e){return e.children}function pn(e,t){this.props=e,this.context=t}function mn(e,t){if(null==t)return e.__?mn(e.__,e.__.__k.indexOf(e)+1):null;for(var n;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e)return n.__e;return"function"==typeof e.type?mn(e):null}function vn(e){var t,n;if(null!=(e=e.__)&&null!=e.__c){for(e.__e=e.__c.base=null,t=0;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e){e.__e=e.__c.base=n.__e;break}return vn(e)}}function dn(e){(!e.__d&&(e.__d=!0)&&Zt.push(e)&&!yn.__r++||en!==Xt.debounceRendering)&&((en=Xt.debounceRendering)||tn)(yn)}function yn(){var e,t,n,r,o,i,u,a;for(Zt.sort(nn);e=Zt.shift();)e.__d&&(t=Zt.length,r=void 0,o=void 0,u=(i=(n=e).__v).__e,(a=n.__P)&&(r=[],(o=an({},i)).__v=i.__v+1,wn(a,i,o,n.__n,void 0!==a.ownerSVGElement,null!=i.__h?[u]:null,r,null==u?mn(i):u,i.__h),In(r,i),i.__e!=u&&vn(i)),Zt.length>t&&Zt.sort(nn));yn.__r=0}function bn(e,t,n,r,o,i,u,a,l,c){var s,f,p,m,v,d,y,b=r&&r.__k||on,g=b.length;for(n.__k=[],s=0;s<t.length;s++)if(null!=(m=n.__k[s]=null==(m=t[s])||"boolean"==typeof m||"function"==typeof m?null:"string"==typeof m||"number"==typeof m||"bigint"==typeof m?sn(null,m,null,null,m):Array.isArray(m)?sn(fn,{children:m},null,null,null):m.__b>0?sn(m.type,m.props,m.key,m.ref?m.ref:null,m.__v):m)){if(m.__=n,m.__b=n.__b+1,null===(p=b[s])||p&&m.key==p.key&&m.type===p.type)b[s]=void 0;else for(f=0;f<g;f++){if((p=b[f])&&m.key==p.key&&m.type===p.type){b[f]=void 0;break}p=null}wn(e,m,p=p||rn,o,i,u,a,l,c),v=m.__e,(f=m.ref)&&p.ref!=f&&(y||(y=[]),p.ref&&y.push(p.ref,null,m),y.push(f,m.__c||v,m)),null!=v?(null==d&&(d=v),"function"==typeof m.type&&m.__k===p.__k?m.__d=l=gn(m,l,e):l=hn(e,m,p,b,v,l),"function"==typeof n.type&&(n.__d=l)):l&&p.__e==l&&l.parentNode!=e&&(l=mn(p))}for(n.__e=d,s=g;s--;)null!=b[s]&&("function"==typeof n.type&&null!=b[s].__e&&b[s].__e==n.__d&&(n.__d=On(r).nextSibling),Dn(b[s],b[s]));if(y)for(s=0;s<y.length;s++)En(y[s],y[++s],y[++s])}function gn(e,t,n){for(var r,o=e.__k,i=0;o&&i<o.length;i++)(r=o[i])&&(r.__=e,t="function"==typeof r.type?gn(r,t,n):hn(n,r,r,o,r.__e,t));return t}function hn(e,t,n,r,o,i){var u,a,l;if(void 0!==t.__d)u=t.__d,t.__d=void 0;else if(null==n||o!=i||null==o.parentNode)e:if(null==i||i.parentNode!==e)e.appendChild(o),u=null;else{for(a=i,l=0;(a=a.nextSibling)&&l<r.length;l+=1)if(a==o)break e;e.insertBefore(o,i),u=i}return void 0!==u?u:o.nextSibling}function On(e){var t,n,r;if(null==e.type||"string"==typeof e.type)return e.__e;if(e.__k)for(t=e.__k.length-1;t>=0;t--)if((n=e.__k[t])&&(r=On(n)))return r;return null}function _n(e,t,n){"-"===t[0]?e.setProperty(t,null==n?"":n):e[t]=null==n?"":"number"!=typeof n||un.test(t)?n:n+"px"}function Sn(e,t,n,r,o){var i;e:if("style"===t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||_n(e.style,t,"");if(n)for(t in n)r&&n[t]===r[t]||_n(e.style,t,n[t])}else if("o"===t[0]&&"n"===t[1])i=t!==(t=t.replace(/Capture$/,"")),t=t.toLowerCase()in e?t.toLowerCase().slice(2):t.slice(2),e.l||(e.l={}),e.l[t+i]=n,n?r||e.addEventListener(t,i?Pn:jn,i):e.removeEventListener(t,i?Pn:jn,i);else if("dangerouslySetInnerHTML"!==t){if(o)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!==t&&"height"!==t&&"href"!==t&&"list"!==t&&"form"!==t&&"tabIndex"!==t&&"download"!==t&&t in e)try{e[t]=null==n?"":n;break e}catch(e){}"function"==typeof n||(null==n||!1===n&&"-"!==t[4]?e.removeAttribute(t):e.setAttribute(t,n))}}function jn(e){return this.l[e.type+!1](Xt.event?Xt.event(e):e)}function Pn(e){return this.l[e.type+!0](Xt.event?Xt.event(e):e)}function wn(e,t,n,r,o,i,u,a,l){var c,s,f,p,m,v,d,y,b,g,h,O,_,S,j,P=t.type;if(void 0!==t.constructor)return null;null!=n.__h&&(l=n.__h,a=t.__e=n.__e,t.__h=null,i=[a]),(c=Xt.__b)&&c(t);try{e:if("function"==typeof P){if(y=t.props,b=(c=P.contextType)&&r[c.__c],g=c?b?b.props.value:c.__:r,n.__c?d=(s=t.__c=n.__c).__=s.__E:("prototype"in P&&P.prototype.render?t.__c=s=new P(y,g):(t.__c=s=new pn(y,g),s.constructor=P,s.render=Cn),b&&b.sub(s),s.props=y,s.state||(s.state={}),s.context=g,s.__n=r,f=s.__d=!0,s.__h=[],s._sb=[]),null==s.__s&&(s.__s=s.state),null!=P.getDerivedStateFromProps&&(s.__s==s.state&&(s.__s=an({},s.__s)),an(s.__s,P.getDerivedStateFromProps(y,s.__s))),p=s.props,m=s.state,s.__v=t,f)null==P.getDerivedStateFromProps&&null!=s.componentWillMount&&s.componentWillMount(),null!=s.componentDidMount&&s.__h.push(s.componentDidMount);else{if(null==P.getDerivedStateFromProps&&y!==p&&null!=s.componentWillReceiveProps&&s.componentWillReceiveProps(y,g),!s.__e&&null!=s.shouldComponentUpdate&&!1===s.shouldComponentUpdate(y,s.__s,g)||t.__v===n.__v){for(t.__v!==n.__v&&(s.props=y,s.state=s.__s,s.__d=!1),s.__e=!1,t.__e=n.__e,t.__k=n.__k,t.__k.forEach((function(e){e&&(e.__=t)})),h=0;h<s._sb.length;h++)s.__h.push(s._sb[h]);s._sb=[],s.__h.length&&u.push(s);break e}null!=s.componentWillUpdate&&s.componentWillUpdate(y,s.__s,g),null!=s.componentDidUpdate&&s.__h.push((function(){s.componentDidUpdate(p,m,v)}))}if(s.context=g,s.props=y,s.__P=e,O=Xt.__r,_=0,"prototype"in P&&P.prototype.render){for(s.state=s.__s,s.__d=!1,O&&O(t),c=s.render(s.props,s.state,s.context),S=0;S<s._sb.length;S++)s.__h.push(s._sb[S]);s._sb=[]}else do{s.__d=!1,O&&O(t),c=s.render(s.props,s.state,s.context),s.state=s.__s}while(s.__d&&++_<25);s.state=s.__s,null!=s.getChildContext&&(r=an(an({},r),s.getChildContext())),f||null==s.getSnapshotBeforeUpdate||(v=s.getSnapshotBeforeUpdate(p,m)),j=null!=c&&c.type===fn&&null==c.key?c.props.children:c,bn(e,Array.isArray(j)?j:[j],t,n,r,o,i,u,a,l),s.base=t.__e,t.__h=null,s.__h.length&&u.push(s),d&&(s.__E=s.__=null),s.__e=!1}else null==i&&t.__v===n.__v?(t.__k=n.__k,t.__e=n.__e):t.__e=An(n.__e,t,n,r,o,i,u,l);(c=Xt.diffed)&&c(t)}catch(e){t.__v=null,(l||null!=i)&&(t.__e=a,t.__h=!!l,i[i.indexOf(a)]=null),Xt.__e(e,t,n)}}function In(e,t){Xt.__c&&Xt.__c(t,e),e.some((function(t){try{e=t.__h,t.__h=[],e.some((function(e){e.call(t)}))}catch(e){Xt.__e(e,t.__v)}}))}function An(e,t,n,r,o,i,u,a){var l,c,s,f=n.props,p=t.props,m=t.type,v=0;if("svg"===m&&(o=!0),null!=i)for(;v<i.length;v++)if((l=i[v])&&"setAttribute"in l==!!m&&(m?l.localName===m:3===l.nodeType)){e=l,i[v]=null;break}if(null==e){if(null===m)return document.createTextNode(p);e=o?document.createElementNS("http://www.w3.org/2000/svg",m):document.createElement(m,p.is&&p),i=null,a=!1}if(null===m)f===p||a&&e.data===p||(e.data=p);else{if(i=i&&Jt.call(e.childNodes),c=(f=n.props||rn).dangerouslySetInnerHTML,s=p.dangerouslySetInnerHTML,!a){if(null!=i)for(f={},v=0;v<e.attributes.length;v++)f[e.attributes[v].name]=e.attributes[v].value;(s||c)&&(s&&(c&&s.__html==c.__html||s.__html===e.innerHTML)||(e.innerHTML=s&&s.__html||""))}if(function(e,t,n,r,o){var i;for(i in n)"children"===i||"key"===i||i in t||Sn(e,i,null,n[i],r);for(i in t)o&&"function"!=typeof t[i]||"children"===i||"key"===i||"value"===i||"checked"===i||n[i]===t[i]||Sn(e,i,t[i],n[i],r)}(e,p,f,o,a),s)t.__k=[];else if(v=t.props.children,bn(e,Array.isArray(v)?v:[v],t,n,r,o&&"foreignObject"!==m,i,u,i?i[0]:n.__k&&mn(n,0),a),null!=i)for(v=i.length;v--;)null!=i[v]&&ln(i[v]);a||("value"in p&&void 0!==(v=p.value)&&(v!==e.value||"progress"===m&&!v||"option"===m&&v!==f.value)&&Sn(e,"value",v,f.value,!1),"checked"in p&&void 0!==(v=p.checked)&&v!==e.checked&&Sn(e,"checked",v,f.checked,!1))}return e}function En(e,t,n){try{"function"==typeof e?e(t):e.current=t}catch(e){Xt.__e(e,n)}}function Dn(e,t,n){var r,o;if(Xt.unmount&&Xt.unmount(e),(r=e.ref)&&(r.current&&r.current!==e.__e||En(r,null,t)),null!=(r=e.__c)){if(r.componentWillUnmount)try{r.componentWillUnmount()}catch(e){Xt.__e(e,t)}r.base=r.__P=null,e.__c=void 0}if(r=e.__k)for(o=0;o<r.length;o++)r[o]&&Dn(r[o],t,n||"function"!=typeof e.type);n||null==e.__e||ln(e.__e),e.__=e.__e=e.__d=void 0}function Cn(e,t,n){return this.constructor(e,n)}Jt=on.slice,Xt={__e:function(e,t,n,r){for(var o,i,u;t=t.__;)if((o=t.__c)&&!o.__)try{if((i=o.constructor)&&null!=i.getDerivedStateFromError&&(o.setState(i.getDerivedStateFromError(e)),u=o.__d),null!=o.componentDidCatch&&(o.componentDidCatch(e,r||{}),u=o.__d),u)return o.__E=o}catch(t){e=t}throw e}},Yt=0,pn.prototype.setState=function(e,t){var n;n=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=an({},this.state),"function"==typeof e&&(e=e(an({},n),this.props)),e&&an(n,e),null!=e&&this.__v&&(t&&this._sb.push(t),dn(this))},pn.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),dn(this))},pn.prototype.render=fn,Zt=[],tn="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,nn=function(e,t){return e.__v.__b-t.__v.__b},yn.__r=0;var kn="__aa-highlight__",xn="__/aa-highlight__";function Nn(e){var t=e.highlightedValue.split(kn),n=t.shift(),r=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{get:function(){return e},add:function(t){var n=e[e.length-1];(null==n?void 0:n.isHighlighted)===t.isHighlighted?e[e.length-1]={value:n.value+t.value,isHighlighted:n.isHighlighted}:e.push(t)}}}(n?[{value:n,isHighlighted:!1}]:[]);return t.forEach((function(e){var t=e.split(xn);r.add({value:t[0],isHighlighted:!0}),""!==t[1]&&r.add({value:t[1],isHighlighted:!1})})),r.get()}function Tn(e){return function(e){if(Array.isArray(e))return qn(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return qn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return qn(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function qn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Bn(e){var t=e.hit,n=e.attribute,r=Array.isArray(n)?n:[n],o=y(t,["_highlightResult"].concat(Tn(r),["value"]));return"string"!=typeof o&&(o=y(t,r)||""),Nn({highlightedValue:o})}var Rn={"&amp;":"&","&lt;":"<","&gt;":">","&quot;":'"',"&#39;":"'"},Fn=new RegExp(/\w/i),Ln=/&(amp|quot|lt|gt|#39);/g,Un=RegExp(Ln.source);function Mn(e,t){var n,r,o,i=e[t],u=(null===(n=e[t+1])||void 0===n?void 0:n.isHighlighted)||!0,a=(null===(r=e[t-1])||void 0===r?void 0:r.isHighlighted)||!0;return Fn.test((o=i.value)&&Un.test(o)?o.replace(Ln,(function(e){return Rn[e]})):o)||a!==u?i.isHighlighted:a}function Hn(e){return Hn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Hn(e)}function Vn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Wn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Vn(Object(n),!0).forEach((function(t){Kn(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Vn(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Kn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Hn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Hn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Hn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Qn(e){return e.some((function(e){return e.isHighlighted}))?e.map((function(t,n){return Wn(Wn({},t),{},{isHighlighted:!Mn(e,n)})})):e.map((function(e){return Wn(Wn({},e),{},{isHighlighted:!1})}))}function $n(e){return function(e){if(Array.isArray(e))return zn(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return zn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return zn(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function zn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Gn(e){var t=e.hit,n=e.attribute,r=Array.isArray(n)?n:[n],o=y(t,["_snippetResult"].concat($n(r),["value"]));return"string"!=typeof o&&(o=y(t,r)||""),Nn({highlightedValue:o})}function Jn(e){return Jn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Jn(e)}function Xn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Yn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Xn(Object(n),!0).forEach((function(t){Zn(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Xn(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Zn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Jn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Jn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Jn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function er(e){return er="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},er(e)}var tr=["params"];function nr(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function rr(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?nr(Object(n),!0).forEach((function(t){or(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):nr(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function or(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==er(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==er(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===er(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ir(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},i=Object.keys(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)n=i[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function ur(e){return function(e){if(Array.isArray(e))return ar(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return ar(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ar(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ar(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function lr(e){var t=e.createElement,n=e.Fragment;function r(e){var r=e.hit,o=e.attribute,i=e.tagName,u=void 0===i?"mark":i;return t(n,{},Bn({hit:r,attribute:o}).map((function(e,n){return e.isHighlighted?t(u,{key:n},e.value):e.value})))}return r.__autocomplete_componentName="Highlight",r}function cr(e){var t=e.createElement,n=e.Fragment;function r(e){var r,o=e.hit,i=e.attribute,u=e.tagName,a=void 0===u?"mark":u;return t(n,{},(r={hit:o,attribute:i},Qn(Bn(r))).map((function(e,n){return e.isHighlighted?t(a,{key:n},e.value):e.value})))}return r.__autocomplete_componentName="ReverseHighlight",r}function sr(e){var t=e.createElement,n=e.Fragment;function r(e){var r,o=e.hit,i=e.attribute,u=e.tagName,a=void 0===u?"mark":u;return t(n,{},(r={hit:o,attribute:i},Qn(Gn(r))).map((function(e,n){return e.isHighlighted?t(a,{key:n},e.value):e.value})))}return r.__autocomplete_componentName="ReverseSnippet",r}function fr(e){var t=e.createElement,n=e.Fragment;function r(e){var r=e.hit,o=e.attribute,i=e.tagName,u=void 0===i?"mark":i;return t(n,{},Gn({hit:r,attribute:o}).map((function(e,n){return e.isHighlighted?t(u,{key:n},e.value):e.value})))}return r.__autocomplete_componentName="Snippet",r}var pr=["classNames","container","getEnvironmentProps","getFormProps","getInputProps","getItemProps","getLabelProps","getListProps","getPanelProps","getRootProps","panelContainer","panelPlacement","render","renderNoResults","renderer","detachedMediaQuery","components","translations"],mr={clearButton:"aa-ClearButton",detachedCancelButton:"aa-DetachedCancelButton",detachedContainer:"aa-DetachedContainer",detachedFormContainer:"aa-DetachedFormContainer",detachedOverlay:"aa-DetachedOverlay",detachedSearchButton:"aa-DetachedSearchButton",detachedSearchButtonIcon:"aa-DetachedSearchButtonIcon",detachedSearchButtonPlaceholder:"aa-DetachedSearchButtonPlaceholder",detachedSearchButtonQuery:"aa-DetachedSearchButtonQuery",form:"aa-Form",input:"aa-Input",inputWrapper:"aa-InputWrapper",inputWrapperPrefix:"aa-InputWrapperPrefix",inputWrapperSuffix:"aa-InputWrapperSuffix",item:"aa-Item",label:"aa-Label",list:"aa-List",loadingIndicator:"aa-LoadingIndicator",panel:"aa-Panel",panelLayout:"aa-PanelLayout aa-Panel--scrollable",root:"aa-Autocomplete",source:"aa-Source",sourceFooter:"aa-SourceFooter",sourceHeader:"aa-SourceHeader",sourceNoResults:"aa-SourceNoResults",submitButton:"aa-SubmitButton"},vr=function(e,t){var n=e.children;(0,e.render)(n,t)},dr={createElement:cn,Fragment:fn,render:function(e,t,n){var r,o,i;Xt.__&&Xt.__(e,t),o=(r="function"==typeof n)?null:n&&n.__k||t.__k,i=[],wn(t,e=(!r&&n||t).__k=cn(fn,null,[e]),o||rn,rn,void 0!==t.ownerSVGElement,!r&&n?[n]:o?null:t.firstChild?Jt.call(t.childNodes):null,i,!r&&n?n:o?o.__e:t.firstChild,r),In(i,e)}};function yr(e){var t=e.panelPlacement,n=e.container,r=e.form,o=e.environment,i=n.getBoundingClientRect(),u=(o.pageYOffset||o.document.documentElement.scrollTop||o.document.body.scrollTop||0)+i.top+i.height;switch(t){case"start":return{top:u,left:i.left};case"end":return{top:u,right:o.document.documentElement.clientWidth-(i.left+i.width)};case"full-width":return{top:u,left:0,right:0,width:"unset",maxWidth:"unset"};case"input-wrapper-width":var a=r.getBoundingClientRect();return{top:u,left:a.left,right:o.document.documentElement.clientWidth-(a.left+a.width),width:"unset",maxWidth:"unset"};default:throw new Error("[Autocomplete] The `panelPlacement` value ".concat(JSON.stringify(t)," is not valid."))}}var br=[{segment:"autocomplete-js",version:_}],gr=["components"];var hr=function(e,t){function n(t){return e({searchClient:t.searchClient,queries:t.requests.map((function(e){return e.query}))}).then((function(e){return e.map((function(e,n){var r=t.requests[n];return{items:e,sourceId:r.sourceId,transformResponse:r.transformResponse}}))}))}return function(e){return function(r){return Yn(Yn({requesterId:t,execute:n},e),r)}}}((function(e){return function(e){var t=e.searchClient,n=e.queries,r=e.userAgents,o=void 0===r?[]:r;"function"==typeof t.addAlgoliaAgent&&[].concat(ur(S),ur(o)).forEach((function(e){var n=e.segment,r=e.version;t.addAlgoliaAgent(n,r)}));var i=function(e){var t=e.transporter||{},n=t.headers,r=void 0===n?{}:n,o=t.queryParameters,i=void 0===o?{}:o,u="x-algolia-application-id",a="x-algolia-api-key";return{appId:r[u]||i[u],apiKey:r[a]||i[a]}}(t),u=i.appId,a=i.apiKey;return t.search(n.map((function(e){var t=e.params;return rr(rr({},ir(e,tr)),{},{params:rr({hitsPerPage:5,highlightPreTag:kn,highlightPostTag:xn},t)})}))).then((function(e){return e.results.map((function(e,t){var r;return rr(rr({},e),{},{hits:null===(r=e.hits)||void 0===r?void 0:r.map((function(r){return rr(rr({},r),{},{__autocomplete_indexName:e.index||n[t].indexName,__autocomplete_queryID:e.queryID,__autocomplete_algoliaCredentials:{appId:u,apiKey:a}})}))})}))}))}(n(n({},e),{},{userAgents:br}))}),"algolia");var Or=hr({transformResponse:function(e){return e.hits}});e.autocomplete=function(e){var t,r=function(){var e=[],t=[];function n(n){e.push(n);var r=n();t.push(r)}return{runEffect:n,cleanupEffects:function(){var e=t;t=[],e.forEach((function(e){e()}))},runEffects:function(){var t=e;e=[],t.forEach((function(e){n(e)}))}}}(),a=r.runEffect,l=r.cleanupEffects,c=r.runEffects,s=(t=[],{reactive:function(e){var n=e(),r={_fn:e,_ref:{current:n},get value(){return this._ref.current},set value(e){this._ref.current=e}};return t.push(r),r},runReactives:function(){t.forEach((function(e){e._ref.current=e._fn()}))}}),m=s.reactive,v=s.runReactives,y=f(!1),g=f(e),h=f(void 0),O=m((function(){return function(e){var t,r=e.classNames,o=e.container,i=e.getEnvironmentProps,a=e.getFormProps,l=e.getInputProps,c=e.getItemProps,s=e.getLabelProps,f=e.getListProps,p=e.getPanelProps,m=e.getRootProps,v=e.panelContainer,y=e.panelPlacement,b=e.render,g=e.renderNoResults,h=e.renderer,O=e.detachedMediaQuery,_=e.components,S=e.translations,j=u(e,pr),P="undefined"!=typeof window?window:{},w=xt(P,o);w.tagName;var I=n(n({},dr),h),A={Highlight:lr(I),ReverseHighlight:cr(I),ReverseSnippet:sr(I),Snippet:fr(I)};return{renderer:{classNames:Nt(mr,null!=r?r:{}),container:w,getEnvironmentProps:null!=i?i:function(e){return e.props},getFormProps:null!=a?a:function(e){return e.props},getInputProps:null!=l?l:function(e){return e.props},getItemProps:null!=c?c:function(e){return e.props},getLabelProps:null!=s?s:function(e){return e.props},getListProps:null!=f?f:function(e){return e.props},getPanelProps:null!=p?p:function(e){return e.props},getRootProps:null!=m?m:function(e){return e.props},panelContainer:v?xt(P,v):P.document.body,panelPlacement:null!=y?y:"input-wrapper-width",render:null!=b?b:vr,renderNoResults:g,renderer:I,detachedMediaQuery:null!=O?O:getComputedStyle(P.document.documentElement).getPropertyValue("--aa-detached-media-query"),components:n(n({},A),_),translations:n(n({},{clearButtonTitle:"Clear",detachedCancelButtonText:"Cancel",submitButtonTitle:"Submit"}),S)},core:n(n({},j),{},{id:null!==(t=j.id)&&void 0!==t?t:d(),environment:P})}}(g.current)})),_=m((function(){return O.value.core.environment.matchMedia(O.value.renderer.detachedMediaQuery).matches})),S=m((function(){return At(n(n({},O.value.core),{},{onStateChange:function(e){var t,n,r;y.current=e.state.collections.some((function(e){return e.source.templates.noResults})),null===(t=h.current)||void 0===t||t.call(h,e),null===(n=(r=O.value.core).onStateChange)||void 0===n||n.call(r,e)},shouldPanelOpen:g.current.shouldPanelOpen||function(e){var t=e.state;if(_.value)return!0;var n=b(t)>0;if(!O.value.core.openOnFocus&&!t.query)return n;var r=Boolean(y.current||O.value.renderer.renderNoResults);return!n&&r||n},__autocomplete_metadata:{userAgents:br,options:e}}))})),j=f(n({collections:[],completion:null,context:{},isOpen:!1,query:"",activeItemId:null,status:"idle"},O.value.core.initialState)),P={getEnvironmentProps:O.value.renderer.getEnvironmentProps,getFormProps:O.value.renderer.getFormProps,getInputProps:O.value.renderer.getInputProps,getItemProps:O.value.renderer.getItemProps,getLabelProps:O.value.renderer.getLabelProps,getListProps:O.value.renderer.getListProps,getPanelProps:O.value.renderer.getPanelProps,getRootProps:O.value.renderer.getRootProps},w={setActiveItemId:S.value.setActiveItemId,setQuery:S.value.setQuery,setCollections:S.value.setCollections,setIsOpen:S.value.setIsOpen,setStatus:S.value.setStatus,setContext:S.value.setContext,refresh:S.value.refresh,navigator:S.value.navigator},I=m((function(){return Ct.bind(O.value.renderer.renderer.createElement)})),A=m((function(){return Gt({autocomplete:S.value,autocompleteScopeApi:w,classNames:O.value.renderer.classNames,environment:O.value.core.environment,isDetached:_.value,placeholder:O.value.core.placeholder,propGetters:P,setIsModalOpen:k,state:j.current,translations:O.value.renderer.translations})}));function E(){Ht(A.value.panel,{style:_.value?{}:yr({panelPlacement:O.value.renderer.panelPlacement,container:A.value.root,form:A.value.form,environment:O.value.core.environment})})}function D(e){j.current=e;var t={autocomplete:S.value,autocompleteScopeApi:w,classNames:O.value.renderer.classNames,components:O.value.renderer.components,container:O.value.renderer.container,html:I.value,dom:A.value,panelContainer:_.value?A.value.detachedContainer:O.value.renderer.panelContainer,propGetters:P,state:j.current,renderer:O.value.renderer.renderer},r=!b(e)&&!y.current&&O.value.renderer.renderNoResults||O.value.renderer.render;!function(e){var t=e.autocomplete,r=e.autocompleteScopeApi,o=e.dom,i=e.propGetters,u=e.state;Vt(o.root,i.getRootProps(n({state:u,props:t.getRootProps({})},r))),Vt(o.input,i.getInputProps(n({state:u,props:t.getInputProps({inputElement:o.input}),inputElement:o.input},r))),Ht(o.label,{hidden:"stalled"===u.status}),Ht(o.loadingIndicator,{hidden:"stalled"!==u.status}),Ht(o.clearButton,{hidden:!u.query}),Ht(o.detachedSearchButtonQuery,{textContent:u.query}),Ht(o.detachedSearchButtonPlaceholder,{hidden:Boolean(u.query)})}(t),function(e,t){var r=t.autocomplete,o=t.autocompleteScopeApi,u=t.classNames,a=t.html,l=t.dom,c=t.panelContainer,s=t.propGetters,f=t.state,p=t.components,m=t.renderer;if(f.isOpen){c.contains(l.panel)||"loading"===f.status||c.appendChild(l.panel),l.panel.classList.toggle("aa-Panel--stalled","stalled"===f.status);var v=f.collections.filter((function(e){var t=e.source,n=e.items;return t.templates.noResults||n.length>0})).map((function(e,t){var l=e.source,c=e.items;return m.createElement("section",{key:t,className:u.source,"data-autocomplete-source-id":l.sourceId},l.templates.header&&m.createElement("div",{className:u.sourceHeader},l.templates.header({components:p,createElement:m.createElement,Fragment:m.Fragment,items:c,source:l,state:f,html:a})),l.templates.noResults&&0===c.length?m.createElement("div",{className:u.sourceNoResults},l.templates.noResults({components:p,createElement:m.createElement,Fragment:m.Fragment,source:l,state:f,html:a})):m.createElement("ul",i({className:u.list},s.getListProps(n({state:f,props:r.getListProps({source:l})},o))),c.map((function(e){var t=r.getItemProps({item:e,source:l});return m.createElement("li",i({key:t.id,className:u.item},s.getItemProps(n({state:f,props:t},o))),l.templates.item({components:p,createElement:m.createElement,Fragment:m.Fragment,item:e,state:f,html:a}))}))),l.templates.footer&&m.createElement("div",{className:u.sourceFooter},l.templates.footer({components:p,createElement:m.createElement,Fragment:m.Fragment,items:c,source:l,state:f,html:a})))})),d=m.createElement(m.Fragment,null,m.createElement("div",{className:u.panelLayout},v),m.createElement("div",{className:"aa-GradientBottom"})),y=v.reduce((function(e,t){return e[t.props["data-autocomplete-source-id"]]=t,e}),{});e(n(n({children:d,state:f,sections:v,elements:y},m),{},{components:p,html:a},o),l.panel)}else c.contains(l.panel)&&c.removeChild(l.panel)}(r,t)}function C(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};l();var t=O.value.renderer,n=t.components,r=u(t,gr);g.current=qt(r,O.value.core,{components:Bt(n,(function(e){return!e.value.hasOwnProperty("__autocomplete_componentName")})),initialState:j.current},e),v(),c(),S.value.refresh().then((function(){D(j.current)}))}function k(e){requestAnimationFrame((function(){var t=O.value.core.environment.document.body.contains(A.value.detachedOverlay);e!==t&&(e?(O.value.core.environment.document.body.appendChild(A.value.detachedOverlay),O.value.core.environment.document.body.classList.add("aa-Detached"),A.value.input.focus()):(O.value.core.environment.document.body.removeChild(A.value.detachedOverlay),O.value.core.environment.document.body.classList.remove("aa-Detached")))}))}return a((function(){var e=S.value.getEnvironmentProps({formElement:A.value.form,panelElement:A.value.panel,inputElement:A.value.input});return Ht(O.value.core.environment,e),function(){Ht(O.value.core.environment,Object.keys(e).reduce((function(e,t){return n(n({},e),{},o({},t,void 0))}),{}))}})),a((function(){var e=_.value?O.value.core.environment.document.body:O.value.renderer.panelContainer,t=_.value?A.value.detachedOverlay:A.value.panel;return _.value&&j.current.isOpen&&k(!0),D(j.current),function(){e.contains(t)&&e.removeChild(t)}})),a((function(){var e=O.value.renderer.container;return e.appendChild(A.value.root),function(){e.removeChild(A.value.root)}})),a((function(){var e=p((function(e){D(e.state)}),0);return h.current=function(t){var n=t.state,r=t.prevState;(_.value&&r.isOpen!==n.isOpen&&k(n.isOpen),_.value||!n.isOpen||r.isOpen||E(),n.query!==r.query)&&O.value.core.environment.document.querySelectorAll(".aa-Panel--scrollable").forEach((function(e){0!==e.scrollTop&&(e.scrollTop=0)}));e({state:n})},function(){h.current=void 0}})),a((function(){var e=p((function(){var e=_.value;_.value=O.value.core.environment.matchMedia(O.value.renderer.detachedMediaQuery).matches,e!==_.value?C({}):requestAnimationFrame(E)}),20);return O.value.core.environment.addEventListener("resize",e),function(){O.value.core.environment.removeEventListener("resize",e)}})),a((function(){if(!_.value)return function(){};function e(e){A.value.detachedContainer.classList.toggle("aa-DetachedContainer--modal",e)}function t(t){e(t.matches)}var n=O.value.core.environment.matchMedia(getComputedStyle(O.value.core.environment.document.documentElement).getPropertyValue("--aa-detached-modal-media-query"));e(n.matches);var r=Boolean(n.addEventListener);return r?n.addEventListener("change",t):n.addListener(t),function(){r?n.removeEventListener("change",t):n.removeListener(t)}})),a((function(){return requestAnimationFrame(E),function(){}})),n(n({},w),{},{update:C,destroy:function(){l()}})},e.getAlgoliaFacets=function(e){var t=hr({transformResponse:function(e){return e.facetHits}}),r=e.queries.map((function(e){return n(n({},e),{},{type:"facet"})}));return t(n(n({},e),{},{queries:r}))},e.getAlgoliaResults=Or,Object.defineProperty(e,"__esModule",{value:!0})}));
3
-
 
 
 
 
_site/site_libs/quarto-search/fuse.min.js DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * Fuse.js v6.6.2 - Lightweight fuzzy-search (http://fusejs.io)
3
- *
4
- * Copyright (c) 2022 Kiro Risk (http://kiro.me)
5
- * All Rights Reserved. Apache Software License 2.0
6
- *
7
- * http://www.apache.org/licenses/LICENSE-2.0
8
- */
9
- var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?e(Object(r),!0).forEach((function(e){c(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):e(Object(r)).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}function n(e){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n(e)}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function o(e,t,n){return t&&i(e.prototype,t),n&&i(e,n),Object.defineProperty(e,"prototype",{writable:!1}),e}function c(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");Object.defineProperty(e,"prototype",{value:Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),writable:!1}),t&&u(e,t)}function s(e){return s=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},s(e)}function u(e,t){return u=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},u(e,t)}function h(e,t){if(t&&("object"==typeof t||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(e)}function l(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,r=s(e);if(t){var i=s(this).constructor;n=Reflect.construct(r,arguments,i)}else n=r.apply(this,arguments);return h(this,n)}}function f(e){return function(e){if(Array.isArray(e))return d(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(e){if("string"==typeof e)return d(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?d(e,t):void 0}}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function d(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function v(e){return Array.isArray?Array.isArray(e):"[object Array]"===b(e)}function g(e){return"string"==typeof e}function y(e){return"number"==typeof e}function p(e){return!0===e||!1===e||function(e){return m(e)&&null!==e}(e)&&"[object Boolean]"==b(e)}function m(e){return"object"===n(e)}function k(e){return null!=e}function M(e){return!e.trim().length}function b(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":Object.prototype.toString.call(e)}var x=function(e){return"Invalid value for key ".concat(e)},w=function(e){return"Pattern length exceeds max of ".concat(e,".")},L=Object.prototype.hasOwnProperty,S=function(){function e(t){var n=this;r(this,e),this._keys=[],this._keyMap={};var i=0;t.forEach((function(e){var t=_(e);i+=t.weight,n._keys.push(t),n._keyMap[t.id]=t,i+=t.weight})),this._keys.forEach((function(e){e.weight/=i}))}return o(e,[{key:"get",value:function(e){return this._keyMap[e]}},{key:"keys",value:function(){return this._keys}},{key:"toJSON",value:function(){return JSON.stringify(this._keys)}}]),e}();function _(e){var t=null,n=null,r=null,i=1,o=null;if(g(e)||v(e))r=e,t=O(e),n=j(e);else{if(!L.call(e,"name"))throw new Error(function(e){return"Missing ".concat(e," property in key")}("name"));var c=e.name;if(r=c,L.call(e,"weight")&&(i=e.weight)<=0)throw new Error(function(e){return"Property 'weight' in key '".concat(e,"' must be a positive integer")}(c));t=O(c),n=j(c),o=e.getFn}return{path:t,id:n,weight:i,src:r,getFn:o}}function O(e){return v(e)?e:e.split(".")}function j(e){return v(e)?e.join("."):e}var A={useExtendedSearch:!1,getFn:function(e,t){var n=[],r=!1;return function e(t,i,o){if(k(t))if(i[o]){var c=t[i[o]];if(!k(c))return;if(o===i.length-1&&(g(c)||y(c)||p(c)))n.push(function(e){return null==e?"":function(e){if("string"==typeof e)return e;var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}(e)}(c));else if(v(c)){r=!0;for(var a=0,s=c.length;a<s;a+=1)e(c[a],i,o+1)}else i.length&&e(c,i,o+1)}else n.push(t)}(e,g(t)?t.split("."):t,0),r?n:n[0]},ignoreLocation:!1,ignoreFieldNorm:!1,fieldNormWeight:1},I=t(t(t(t({},{isCaseSensitive:!1,includeScore:!1,keys:[],shouldSort:!0,sortFn:function(e,t){return e.score===t.score?e.idx<t.idx?-1:1:e.score<t.score?-1:1}}),{includeMatches:!1,findAllMatches:!1,minMatchCharLength:1}),{location:0,threshold:.6,distance:100}),A),C=/[^ ]+/g;function E(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(C).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}var $=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?I.getFn:n,o=t.fieldNormWeight,c=void 0===o?I.fieldNormWeight:o;r(this,e),this.norm=E(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,g(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();g(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t<n;t+=1)this.records[t].i-=1}},{key:"getValueForItemAtKeyId",value:function(e,t){return e[this._keysMap[t]]}},{key:"size",value:function(){return this.records.length}},{key:"_addString",value:function(e,t){if(k(e)&&!M(e)){var n={v:e,i:t,n:this.norm.get(e)};this.records.push(n)}}},{key:"_addObject",value:function(e,t){var n=this,r={i:t,$:{}};this.keys.forEach((function(t,i){var o=t.getFn?t.getFn(e):n.getFn(e,t.path);if(k(o))if(v(o))!function(){for(var e=[],t=[{nestedArrIndex:-1,value:o}];t.length;){var c=t.pop(),a=c.nestedArrIndex,s=c.value;if(k(s))if(g(s)&&!M(s)){var u={v:s,i:a,n:n.norm.get(s)};e.push(u)}else v(s)&&s.forEach((function(e,n){t.push({nestedArrIndex:n,value:e})}))}r.$[i]=e}();else if(g(o)&&!M(o)){var c={v:o,n:n.norm.get(o)};r.$[i]=c}})),this.records.push(r)}},{key:"toJSON",value:function(){return{keys:this.keys,records:this.records}}}]),e}();function F(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?I.getFn:r,o=n.fieldNormWeight,c=void 0===o?I.fieldNormWeight:o,a=new $({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(_)),a.setSources(t),a.create(),a}function R(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?I.distance:s,h=t.ignoreLocation,l=void 0===h?I.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}function N(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:I.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o<c;o+=1){var a=e[o];a&&-1===r?r=o:a||-1===r||((i=o-1)-r+1>=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}var P=32;function W(e){for(var t={},n=0,r=e.length;n<r;n+=1){var i=e.charAt(n);t[i]=(t[i]||0)|1<<r-n-1}return t}var T=function(){function e(t){var n=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?I.location:o,a=i.threshold,s=void 0===a?I.threshold:a,u=i.distance,h=void 0===u?I.distance:u,l=i.includeMatches,f=void 0===l?I.includeMatches:l,d=i.findAllMatches,v=void 0===d?I.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?I.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?I.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?I.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:W(e),startIndex:t})},x=this.pattern.length;if(x>P){for(var w=0,L=x%P,S=x-L;w<S;)b(this.pattern.substr(w,P),w),w+=P;if(L){var _=x-P;b(this.pattern.substr(_),_)}}else b(this.pattern,0)}}return o(e,[{key:"searchIn",value:function(e){var t=this.options,n=t.isCaseSensitive,r=t.includeMatches;if(n||(e=e.toLowerCase()),this.pattern===e){var i={isMatch:!0,score:0};return r&&(i.indices=[[0,e.length-1]]),i}var o=this.options,c=o.location,a=o.distance,s=o.threshold,u=o.findAllMatches,h=o.minMatchCharLength,l=o.ignoreLocation,d=[],v=0,g=!1;this.chunks.forEach((function(t){var n=t.pattern,i=t.alphabet,o=t.startIndex,y=function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?I.location:i,c=r.distance,a=void 0===c?I.distance:c,s=r.threshold,u=void 0===s?I.threshold:s,h=r.findAllMatches,l=void 0===h?I.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?I.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?I.includeMatches:v,y=r.ignoreLocation,p=void 0===y?I.ignoreLocation:y;if(t.length>P)throw new Error(w(P));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,L=b,S=d>1||g,_=S?Array(M):[];(m=e.indexOf(t,L))>-1;){var O=R(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(O,x),L=m+k,S)for(var j=0;j<k;)_[m+j]=1,j+=1}L=-1;for(var A=[],C=1,E=k+M,$=1<<k-1,F=0;F<k;F+=1){for(var W=0,T=E;W<T;)R(t,{errors:F,currentLocation:b+T,expectedLocation:b,distance:a,ignoreLocation:p})<=x?W=T:E=T,T=Math.floor((E-W)/2+W);E=T;var z=Math.max(1,b-T+1),D=l?M:Math.min(b+T,M)+k,K=Array(D+2);K[D+1]=(1<<F)-1;for(var q=D;q>=z;q-=1){var B=q-1,J=n[e.charAt(B)];if(S&&(_[B]=+!!J),K[q]=(K[q+1]<<1|1)&J,F&&(K[q]|=(A[q+1]|A[q])<<1|1|A[q+1]),K[q]&$&&(C=R(t,{errors:F,currentLocation:B,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=C,(L=B)<=b)break;z=Math.max(1,2*b-L)}}if(R(t,{errors:F+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;A=K}var U={isMatch:L>=0,score:Math.max(.001,C)};if(S){var V=N(_,d);V.length?g&&(U.indices=V):U.isMatch=!1}return U}(e,n,i,{location:c+o,distance:a,threshold:s,findAllMatches:u,minMatchCharLength:h,includeMatches:r,ignoreLocation:l}),p=y.isMatch,m=y.score,k=y.indices;p&&(g=!0),v+=m,p&&k&&(d=[].concat(f(d),f(k)))}));var y={isMatch:g,score:g?v/this.chunks.length:1};return g&&r&&(y.indices=d),y}}]),e}(),z=function(){function e(t){r(this,e),this.pattern=t}return o(e,[{key:"search",value:function(){}}],[{key:"isMultiMatch",value:function(e){return D(e,this.multiRegex)}},{key:"isSingleMatch",value:function(e){return D(e,this.singleRegex)}}]),e}();function D(e,t){var n=e.match(t);return n?n[1]:null}var K=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e===this.pattern;return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"exact"}},{key:"multiRegex",get:function(){return/^="(.*)"$/}},{key:"singleRegex",get:function(){return/^=(.*)$/}}]),n}(z),q=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=-1===e.indexOf(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"$/}},{key:"singleRegex",get:function(){return/^!(.*)$/}}]),n}(z),B=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"prefix-exact"}},{key:"multiRegex",get:function(){return/^\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^\^(.*)$/}}]),n}(z),J=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=!e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-prefix-exact"}},{key:"multiRegex",get:function(){return/^!\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^!\^(.*)$/}}]),n}(z),U=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[e.length-this.pattern.length,e.length-1]}}}],[{key:"type",get:function(){return"suffix-exact"}},{key:"multiRegex",get:function(){return/^"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^(.*)\$$/}}]),n}(z),V=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=!e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-suffix-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^!(.*)\$$/}}]),n}(z),G=function(e){a(n,e);var t=l(n);function n(e){var i,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?I.location:c,s=o.threshold,u=void 0===s?I.threshold:s,h=o.distance,l=void 0===h?I.distance:h,f=o.includeMatches,d=void 0===f?I.includeMatches:f,v=o.findAllMatches,g=void 0===v?I.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?I.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?I.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?I.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new T(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(z),H=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(z),Q=[K,H,B,J,V,U,q,G],X=Q.length,Y=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;function Z(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(Y).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i<o;i+=1){for(var c=n[i],a=!1,s=-1;!a&&++s<X;){var u=Q[s],h=u.isMultiMatch(c);h&&(r.push(new u(h,t)),a=!0)}if(!a)for(s=-1;++s<X;){var l=Q[s],f=l.isSingleMatch(c);if(f){r.push(new l(f,t));break}}}return r}))}var ee=new Set([G.type,H.type]),te=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?I.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?I.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?I.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?I.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?I.findAllMatches:f,v=n.location,g=void 0===v?I.location:v,y=n.threshold,p=void 0===y?I.threshold:y,m=n.distance,k=void 0===m?I.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=Z(this.pattern,this.options)}return o(e,[{key:"searchIn",value:function(e){var t=this.query;if(!t)return{isMatch:!1,score:1};var n=this.options,r=n.includeMatches;e=n.isCaseSensitive?e:e.toLowerCase();for(var i=0,o=[],c=0,a=0,s=t.length;a<s;a+=1){var u=t[a];o.length=0,i=0;for(var h=0,l=u.length;h<l;h+=1){var d=u[h],v=d.search(e),g=v.isMatch,y=v.indices,p=v.score;if(!g){c=0,i=0,o.length=0;break}if(i+=1,c+=p,r){var m=d.constructor.type;ee.has(m)?o=[].concat(f(o),f(y)):o.push(y)}}if(i){var k={isMatch:!0,score:c/i};return r&&(k.indices=o),k}}return{isMatch:!1,score:1}}}],[{key:"condition",value:function(e,t){return t.useExtendedSearch}}]),e}(),ne=[];function re(e,t){for(var n=0,r=ne.length;n<r;n+=1){var i=ne[n];if(i.condition(e,t))return new i(e,t)}return new T(e,t)}var ie="$and",oe="$or",ce="$path",ae="$val",se=function(e){return!(!e[ie]&&!e[oe])},ue=function(e){return!!e[ce]},he=function(e){return!v(e)&&m(e)&&!se(e)},le=function(e){return c({},ie,Object.keys(e).map((function(t){return c({},t,e[t])})))};function fe(e,t){var n=t.ignoreFieldNorm,r=void 0===n?I.ignoreFieldNorm:n;e.forEach((function(e){var t=1;e.matches.forEach((function(e){var n=e.key,i=e.norm,o=e.score,c=n?n.weight:null;t*=Math.pow(0===o&&c?Number.EPSILON:o,(c||1)*(r?1:i))})),e.score=t}))}function de(e,t){var n=e.matches;t.matches=[],k(n)&&n.forEach((function(e){if(k(e.indices)&&e.indices.length){var n={indices:e.indices,value:e.value};e.key&&(n.key=e.key.src),e.idx>-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function ve(e,t){t.score=e.score}function ge(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?I.includeMatches:r,o=n.includeScore,c=void 0===o?I.includeScore:o,a=[];return i&&a.push(de),c&&a.push(ve),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}var ye=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},I),i),this.options.useExtendedSearch,this._keyStore=new S(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof $))throw new Error("Incorrect 'index' type");this._myIndex=t||F(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){k(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n<r;n+=1){var i=this._docs[n];e(i,n)&&(this.removeAt(n),n-=1,r-=1,t.push(i))}return t}},{key:"removeAt",value:function(e){this._docs.splice(e,1),this._myIndex.removeAt(e)}},{key:"getIndex",value:function(){return this._myIndex}},{key:"search",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.limit,r=void 0===n?-1:n,i=this.options,o=i.includeMatches,c=i.includeScore,a=i.shouldSort,s=i.sortFn,u=i.ignoreFieldNorm,h=g(e)?g(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return fe(h,{ignoreFieldNorm:u}),a&&h.sort(s),y(r)&&r>-1&&(h=h.slice(0,r)),ge(h,this._docs,{includeMatches:o,includeScore:c})}},{key:"_searchStringList",value:function(e){var t=re(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(k(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=function(e,t){var n=(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n,i=function e(n){var i=Object.keys(n),o=ue(n);if(!o&&i.length>1&&!se(n))return e(le(n));if(he(n)){var c=o?n[ce]:i[0],a=o?n[ae]:n[c];if(!g(a))throw new Error(x(c));var s={keyId:j(c),pattern:a};return r&&(s.searcher=re(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];v(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u};return se(e)||(e=le(e)),i(e)}(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u<h;u+=1){var l=e(n.children[u],r,i);if(l.length)s.push.apply(s,f(l));else if(n.operator===ie)return[]}return s},i=this._myIndex.records,o={},c=[];return i.forEach((function(e){var t=e.$,i=e.i;if(k(t)){var a=r(n,t,i);a.length&&(o[i]||(o[i]={idx:i,item:t,matches:[]},c.push(o[i])),a.forEach((function(e){var t,n=e.matches;(t=o[i].matches).push.apply(t,f(n))})))}})),c}},{key:"_searchObjectList",value:function(e){var t=this,n=re(e,this.options),r=this._myIndex,i=r.keys,o=r.records,c=[];return o.forEach((function(e){var r=e.$,o=e.i;if(k(r)){var a=[];i.forEach((function(e,i){a.push.apply(a,f(t._findMatches({key:e,value:r[i],searcher:n})))})),a.length&&c.push({idx:o,item:r,matches:a})}})),c}},{key:"_findMatches",value:function(e){var t=e.key,n=e.value,r=e.searcher;if(!k(n))return[];var i=[];if(v(n))n.forEach((function(e){var n=e.v,o=e.i,c=e.n;if(k(n)){var a=r.searchIn(n),s=a.isMatch,u=a.score,h=a.indices;s&&i.push({score:u,key:t,value:n,idx:o,norm:c,indices:h})}}));else{var o=n.v,c=n.n,a=r.searchIn(o),s=a.isMatch,u=a.score,h=a.indices;s&&i.push({score:u,key:t,value:o,norm:c,indices:h})}return i}}]),e}();return ye.version="6.6.2",ye.createIndex=F,ye.parseIndex=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?I.getFn:n,i=t.fieldNormWeight,o=void 0===i?I.fieldNormWeight:i,c=e.keys,a=e.records,s=new $({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ye.config=I,function(){ne.push.apply(ne,arguments)}(te),ye},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t();
 
 
 
 
 
 
 
 
 
 
_site/site_libs/quarto-search/quarto-search.js DELETED
@@ -1,1247 +0,0 @@
1
- const kQueryArg = "q";
2
- const kResultsArg = "show-results";
3
-
4
- // If items don't provide a URL, then both the navigator and the onSelect
5
- // function aren't called (and therefore, the default implementation is used)
6
- //
7
- // We're using this sentinel URL to signal to those handlers that this
8
- // item is a more item (along with the type) and can be handled appropriately
9
- const kItemTypeMoreHref = "0767FDFD-0422-4E5A-BC8A-3BE11E5BBA05";
10
-
11
- window.document.addEventListener("DOMContentLoaded", function (_event) {
12
- // Ensure that search is available on this page. If it isn't,
13
- // should return early and not do anything
14
- var searchEl = window.document.getElementById("quarto-search");
15
- if (!searchEl) return;
16
-
17
- const { autocomplete } = window["@algolia/autocomplete-js"];
18
-
19
- let quartoSearchOptions = {};
20
- let language = {};
21
- const searchOptionEl = window.document.getElementById(
22
- "quarto-search-options"
23
- );
24
- if (searchOptionEl) {
25
- const jsonStr = searchOptionEl.textContent;
26
- quartoSearchOptions = JSON.parse(jsonStr);
27
- language = quartoSearchOptions.language;
28
- }
29
-
30
- // note the search mode
31
- if (quartoSearchOptions.type === "overlay") {
32
- searchEl.classList.add("type-overlay");
33
- } else {
34
- searchEl.classList.add("type-textbox");
35
- }
36
-
37
- // Used to determine highlighting behavior for this page
38
- // A `q` query param is expected when the user follows a search
39
- // to this page
40
- const currentUrl = new URL(window.location);
41
- const query = currentUrl.searchParams.get(kQueryArg);
42
- const showSearchResults = currentUrl.searchParams.get(kResultsArg);
43
- const mainEl = window.document.querySelector("main");
44
-
45
- // highlight matches on the page
46
- if (query && mainEl) {
47
- // perform any highlighting
48
- highlight(escapeRegExp(query), mainEl);
49
-
50
- // fix up the URL to remove the q query param
51
- const replacementUrl = new URL(window.location);
52
- replacementUrl.searchParams.delete(kQueryArg);
53
- window.history.replaceState({}, "", replacementUrl);
54
- }
55
-
56
- // function to clear highlighting on the page when the search query changes
57
- // (e.g. if the user edits the query or clears it)
58
- let highlighting = true;
59
- const resetHighlighting = (searchTerm) => {
60
- if (mainEl && highlighting && query && searchTerm !== query) {
61
- clearHighlight(query, mainEl);
62
- highlighting = false;
63
- }
64
- };
65
-
66
- // Clear search highlighting when the user scrolls sufficiently
67
- const resetFn = () => {
68
- resetHighlighting("");
69
- window.removeEventListener("quarto-hrChanged", resetFn);
70
- window.removeEventListener("quarto-sectionChanged", resetFn);
71
- };
72
-
73
- // Register this event after the initial scrolling and settling of events
74
- // on the page
75
- window.addEventListener("quarto-hrChanged", resetFn);
76
- window.addEventListener("quarto-sectionChanged", resetFn);
77
-
78
- // Responsively switch to overlay mode if the search is present on the navbar
79
- // Note that switching the sidebar to overlay mode requires more coordinate (not just
80
- // the media query since we generate different HTML for sidebar overlays than we do
81
- // for sidebar input UI)
82
- const detachedMediaQuery =
83
- quartoSearchOptions.type === "overlay" ? "all" : "(max-width: 991px)";
84
-
85
- // If configured, include the analytics client to send insights
86
- const plugins = configurePlugins(quartoSearchOptions);
87
-
88
- let lastState = null;
89
- const { setIsOpen, setQuery, setCollections } = autocomplete({
90
- container: searchEl,
91
- detachedMediaQuery: detachedMediaQuery,
92
- defaultActiveItemId: 0,
93
- panelContainer: "#quarto-search-results",
94
- panelPlacement: quartoSearchOptions["panel-placement"],
95
- debug: false,
96
- openOnFocus: true,
97
- plugins,
98
- classNames: {
99
- form: "d-flex",
100
- },
101
- placeholder: language["search-text-placeholder"],
102
- translations: {
103
- clearButtonTitle: language["search-clear-button-title"],
104
- detachedCancelButtonText: language["search-detached-cancel-button-title"],
105
- submitButtonTitle: language["search-submit-button-title"],
106
- },
107
- initialState: {
108
- query,
109
- },
110
- getItemUrl({ item }) {
111
- return item.href;
112
- },
113
- onStateChange({ state }) {
114
- // If this is a file URL, note that
115
-
116
- // Perhaps reset highlighting
117
- resetHighlighting(state.query);
118
-
119
- // If the panel just opened, ensure the panel is positioned properly
120
- if (state.isOpen) {
121
- if (lastState && !lastState.isOpen) {
122
- setTimeout(() => {
123
- positionPanel(quartoSearchOptions["panel-placement"]);
124
- }, 150);
125
- }
126
- }
127
-
128
- // Perhaps show the copy link
129
- showCopyLink(state.query, quartoSearchOptions);
130
-
131
- lastState = state;
132
- },
133
- reshape({ sources, state }) {
134
- return sources.map((source) => {
135
- try {
136
- const items = source.getItems();
137
-
138
- // Validate the items
139
- validateItems(items);
140
-
141
- // group the items by document
142
- const groupedItems = new Map();
143
- items.forEach((item) => {
144
- const hrefParts = item.href.split("#");
145
- const baseHref = hrefParts[0];
146
- const isDocumentItem = hrefParts.length === 1;
147
-
148
- const items = groupedItems.get(baseHref);
149
- if (!items) {
150
- groupedItems.set(baseHref, [item]);
151
- } else {
152
- // If the href for this item matches the document
153
- // exactly, place this item first as it is the item that represents
154
- // the document itself
155
- if (isDocumentItem) {
156
- items.unshift(item);
157
- } else {
158
- items.push(item);
159
- }
160
- groupedItems.set(baseHref, items);
161
- }
162
- });
163
-
164
- const reshapedItems = [];
165
- let count = 1;
166
- for (const [_key, value] of groupedItems) {
167
- const firstItem = value[0];
168
- reshapedItems.push({
169
- ...firstItem,
170
- type: kItemTypeDoc,
171
- });
172
-
173
- const collapseMatches = quartoSearchOptions["collapse-after"];
174
- const collapseCount =
175
- typeof collapseMatches === "number" ? collapseMatches : 1;
176
-
177
- if (value.length > 1) {
178
- const target = `search-more-${count}`;
179
- const isExpanded =
180
- state.context.expanded &&
181
- state.context.expanded.includes(target);
182
-
183
- const remainingCount = value.length - collapseCount;
184
-
185
- for (let i = 1; i < value.length; i++) {
186
- if (collapseMatches && i === collapseCount) {
187
- reshapedItems.push({
188
- target,
189
- title: isExpanded
190
- ? language["search-hide-matches-text"]
191
- : remainingCount === 1
192
- ? `${remainingCount} ${language["search-more-match-text"]}`
193
- : `${remainingCount} ${language["search-more-matches-text"]}`,
194
- type: kItemTypeMore,
195
- href: kItemTypeMoreHref,
196
- });
197
- }
198
-
199
- if (isExpanded || !collapseMatches || i < collapseCount) {
200
- reshapedItems.push({
201
- ...value[i],
202
- type: kItemTypeItem,
203
- target,
204
- });
205
- }
206
- }
207
- }
208
- count += 1;
209
- }
210
-
211
- return {
212
- ...source,
213
- getItems() {
214
- return reshapedItems;
215
- },
216
- };
217
- } catch (error) {
218
- // Some form of error occurred
219
- return {
220
- ...source,
221
- getItems() {
222
- return [
223
- {
224
- title: error.name || "An Error Occurred While Searching",
225
- text:
226
- error.message ||
227
- "An unknown error occurred while attempting to perform the requested search.",
228
- type: kItemTypeError,
229
- },
230
- ];
231
- },
232
- };
233
- }
234
- });
235
- },
236
- navigator: {
237
- navigate({ itemUrl }) {
238
- if (itemUrl !== offsetURL(kItemTypeMoreHref)) {
239
- window.location.assign(itemUrl);
240
- }
241
- },
242
- navigateNewTab({ itemUrl }) {
243
- if (itemUrl !== offsetURL(kItemTypeMoreHref)) {
244
- const windowReference = window.open(itemUrl, "_blank", "noopener");
245
- if (windowReference) {
246
- windowReference.focus();
247
- }
248
- }
249
- },
250
- navigateNewWindow({ itemUrl }) {
251
- if (itemUrl !== offsetURL(kItemTypeMoreHref)) {
252
- window.open(itemUrl, "_blank", "noopener");
253
- }
254
- },
255
- },
256
- getSources({ state, setContext, setActiveItemId, refresh }) {
257
- return [
258
- {
259
- sourceId: "documents",
260
- getItemUrl({ item }) {
261
- if (item.href) {
262
- return offsetURL(item.href);
263
- } else {
264
- return undefined;
265
- }
266
- },
267
- onSelect({
268
- item,
269
- state,
270
- setContext,
271
- setIsOpen,
272
- setActiveItemId,
273
- refresh,
274
- }) {
275
- if (item.type === kItemTypeMore) {
276
- toggleExpanded(item, state, setContext, setActiveItemId, refresh);
277
-
278
- // Toggle more
279
- setIsOpen(true);
280
- }
281
- },
282
- getItems({ query }) {
283
- if (query === null || query === "") {
284
- return [];
285
- }
286
-
287
- const limit = quartoSearchOptions.limit;
288
- if (quartoSearchOptions.algolia) {
289
- return algoliaSearch(query, limit, quartoSearchOptions.algolia);
290
- } else {
291
- // Fuse search options
292
- const fuseSearchOptions = {
293
- isCaseSensitive: false,
294
- shouldSort: true,
295
- minMatchCharLength: 2,
296
- limit: limit,
297
- };
298
-
299
- return readSearchData().then(function (fuse) {
300
- return fuseSearch(query, fuse, fuseSearchOptions);
301
- });
302
- }
303
- },
304
- templates: {
305
- noResults({ createElement }) {
306
- const hasQuery = lastState.query;
307
-
308
- return createElement(
309
- "div",
310
- {
311
- class: `quarto-search-no-results${
312
- hasQuery ? "" : " no-query"
313
- }`,
314
- },
315
- language["search-no-results-text"]
316
- );
317
- },
318
- header({ items, createElement }) {
319
- // count the documents
320
- const count = items.filter((item) => {
321
- return item.type === kItemTypeDoc;
322
- }).length;
323
-
324
- if (count > 0) {
325
- return createElement(
326
- "div",
327
- { class: "search-result-header" },
328
- `${count} ${language["search-matching-documents-text"]}`
329
- );
330
- } else {
331
- return createElement(
332
- "div",
333
- { class: "search-result-header-no-results" },
334
- ``
335
- );
336
- }
337
- },
338
- footer({ _items, createElement }) {
339
- if (
340
- quartoSearchOptions.algolia &&
341
- quartoSearchOptions.algolia["show-logo"]
342
- ) {
343
- const libDir = quartoSearchOptions.algolia["libDir"];
344
- const logo = createElement("img", {
345
- src: offsetURL(
346
- `${libDir}/quarto-search/search-by-algolia.svg`
347
- ),
348
- class: "algolia-search-logo",
349
- });
350
- return createElement(
351
- "a",
352
- { href: "http://www.algolia.com/" },
353
- logo
354
- );
355
- }
356
- },
357
-
358
- item({ item, createElement }) {
359
- return renderItem(
360
- item,
361
- createElement,
362
- state,
363
- setActiveItemId,
364
- setContext,
365
- refresh,
366
- quartoSearchOptions
367
- );
368
- },
369
- },
370
- },
371
- ];
372
- },
373
- });
374
-
375
- window.quartoOpenSearch = () => {
376
- setIsOpen(false);
377
- setIsOpen(true);
378
- focusSearchInput();
379
- };
380
-
381
- document.addEventListener("keyup", (event) => {
382
- const { key } = event;
383
- const kbds = quartoSearchOptions["keyboard-shortcut"];
384
- const focusedEl = document.activeElement;
385
-
386
- const isFormElFocused = [
387
- "input",
388
- "select",
389
- "textarea",
390
- "button",
391
- "option",
392
- ].find((tag) => {
393
- return focusedEl.tagName.toLowerCase() === tag;
394
- });
395
-
396
- if (
397
- kbds &&
398
- kbds.includes(key) &&
399
- !isFormElFocused &&
400
- !document.activeElement.isContentEditable
401
- ) {
402
- event.preventDefault();
403
- window.quartoOpenSearch();
404
- }
405
- });
406
-
407
- // Remove the labeleledby attribute since it is pointing
408
- // to a non-existent label
409
- if (quartoSearchOptions.type === "overlay") {
410
- const inputEl = window.document.querySelector(
411
- "#quarto-search .aa-Autocomplete"
412
- );
413
- if (inputEl) {
414
- inputEl.removeAttribute("aria-labelledby");
415
- }
416
- }
417
-
418
- function throttle(func, wait) {
419
- let waiting = false;
420
- return function () {
421
- if (!waiting) {
422
- func.apply(this, arguments);
423
- waiting = true;
424
- setTimeout(function () {
425
- waiting = false;
426
- }, wait);
427
- }
428
- };
429
- }
430
-
431
- // If the main document scrolls dismiss the search results
432
- // (otherwise, since they're floating in the document they can scroll with the document)
433
- window.document.body.onscroll = throttle(() => {
434
- // Only do this if we're not detached
435
- // Bug #7117
436
- // This will happen when the keyboard is shown on ios (resulting in a scroll)
437
- // which then closed the search UI
438
- if (!window.matchMedia(detachedMediaQuery).matches) {
439
- setIsOpen(false);
440
- }
441
- }, 50);
442
-
443
- if (showSearchResults) {
444
- setIsOpen(true);
445
- focusSearchInput();
446
- }
447
- });
448
-
449
- function configurePlugins(quartoSearchOptions) {
450
- const autocompletePlugins = [];
451
- const algoliaOptions = quartoSearchOptions.algolia;
452
- if (
453
- algoliaOptions &&
454
- algoliaOptions["analytics-events"] &&
455
- algoliaOptions["search-only-api-key"] &&
456
- algoliaOptions["application-id"]
457
- ) {
458
- const apiKey = algoliaOptions["search-only-api-key"];
459
- const appId = algoliaOptions["application-id"];
460
-
461
- // Aloglia insights may not be loaded because they require cookie consent
462
- // Use deferred loading so events will start being recorded when/if consent
463
- // is granted.
464
- const algoliaInsightsDeferredPlugin = deferredLoadPlugin(() => {
465
- if (
466
- window.aa &&
467
- window["@algolia/autocomplete-plugin-algolia-insights"]
468
- ) {
469
- window.aa("init", {
470
- appId,
471
- apiKey,
472
- useCookie: true,
473
- });
474
-
475
- const { createAlgoliaInsightsPlugin } =
476
- window["@algolia/autocomplete-plugin-algolia-insights"];
477
- // Register the insights client
478
- const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({
479
- insightsClient: window.aa,
480
- onItemsChange({ insights, insightsEvents }) {
481
- const events = insightsEvents.flatMap((event) => {
482
- // This API limits the number of items per event to 20
483
- const chunkSize = 20;
484
- const itemChunks = [];
485
- const eventItems = event.items;
486
- for (let i = 0; i < eventItems.length; i += chunkSize) {
487
- itemChunks.push(eventItems.slice(i, i + chunkSize));
488
- }
489
- // Split the items into multiple events that can be sent
490
- const events = itemChunks.map((items) => {
491
- return {
492
- ...event,
493
- items,
494
- };
495
- });
496
- return events;
497
- });
498
-
499
- for (const event of events) {
500
- insights.viewedObjectIDs(event);
501
- }
502
- },
503
- });
504
- return algoliaInsightsPlugin;
505
- }
506
- });
507
-
508
- // Add the plugin
509
- autocompletePlugins.push(algoliaInsightsDeferredPlugin);
510
- return autocompletePlugins;
511
- }
512
- }
513
-
514
- // For plugins that may not load immediately, create a wrapper
515
- // plugin and forward events and plugin data once the plugin
516
- // is initialized. This is useful for cases like cookie consent
517
- // which may prevent the analytics insights event plugin from initializing
518
- // immediately.
519
- function deferredLoadPlugin(createPlugin) {
520
- let plugin = undefined;
521
- let subscribeObj = undefined;
522
- const wrappedPlugin = () => {
523
- if (!plugin && subscribeObj) {
524
- plugin = createPlugin();
525
- if (plugin && plugin.subscribe) {
526
- plugin.subscribe(subscribeObj);
527
- }
528
- }
529
- return plugin;
530
- };
531
-
532
- return {
533
- subscribe: (obj) => {
534
- subscribeObj = obj;
535
- },
536
- onStateChange: (obj) => {
537
- const plugin = wrappedPlugin();
538
- if (plugin && plugin.onStateChange) {
539
- plugin.onStateChange(obj);
540
- }
541
- },
542
- onSubmit: (obj) => {
543
- const plugin = wrappedPlugin();
544
- if (plugin && plugin.onSubmit) {
545
- plugin.onSubmit(obj);
546
- }
547
- },
548
- onReset: (obj) => {
549
- const plugin = wrappedPlugin();
550
- if (plugin && plugin.onReset) {
551
- plugin.onReset(obj);
552
- }
553
- },
554
- getSources: (obj) => {
555
- const plugin = wrappedPlugin();
556
- if (plugin && plugin.getSources) {
557
- return plugin.getSources(obj);
558
- } else {
559
- return Promise.resolve([]);
560
- }
561
- },
562
- data: (obj) => {
563
- const plugin = wrappedPlugin();
564
- if (plugin && plugin.data) {
565
- plugin.data(obj);
566
- }
567
- },
568
- };
569
- }
570
-
571
- function validateItems(items) {
572
- // Validate the first item
573
- if (items.length > 0) {
574
- const item = items[0];
575
- const missingFields = [];
576
- if (item.href == undefined) {
577
- missingFields.push("href");
578
- }
579
- if (!item.title == undefined) {
580
- missingFields.push("title");
581
- }
582
- if (!item.text == undefined) {
583
- missingFields.push("text");
584
- }
585
-
586
- if (missingFields.length === 1) {
587
- throw {
588
- name: `Error: Search index is missing the <code>${missingFields[0]}</code> field.`,
589
- message: `The items being returned for this search do not include all the required fields. Please ensure that your index items include the <code>${missingFields[0]}</code> field or use <code>index-fields</code> in your <code>_quarto.yml</code> file to specify the field names.`,
590
- };
591
- } else if (missingFields.length > 1) {
592
- const missingFieldList = missingFields
593
- .map((field) => {
594
- return `<code>${field}</code>`;
595
- })
596
- .join(", ");
597
-
598
- throw {
599
- name: `Error: Search index is missing the following fields: ${missingFieldList}.`,
600
- message: `The items being returned for this search do not include all the required fields. Please ensure that your index items includes the following fields: ${missingFieldList}, or use <code>index-fields</code> in your <code>_quarto.yml</code> file to specify the field names.`,
601
- };
602
- }
603
- }
604
- }
605
-
606
- let lastQuery = null;
607
- function showCopyLink(query, options) {
608
- const language = options.language;
609
- lastQuery = query;
610
- // Insert share icon
611
- const inputSuffixEl = window.document.body.querySelector(
612
- ".aa-Form .aa-InputWrapperSuffix"
613
- );
614
-
615
- if (inputSuffixEl) {
616
- let copyButtonEl = window.document.body.querySelector(
617
- ".aa-Form .aa-InputWrapperSuffix .aa-CopyButton"
618
- );
619
-
620
- if (copyButtonEl === null) {
621
- copyButtonEl = window.document.createElement("button");
622
- copyButtonEl.setAttribute("class", "aa-CopyButton");
623
- copyButtonEl.setAttribute("type", "button");
624
- copyButtonEl.setAttribute("title", language["search-copy-link-title"]);
625
- copyButtonEl.onmousedown = (e) => {
626
- e.preventDefault();
627
- e.stopPropagation();
628
- };
629
-
630
- const linkIcon = "bi-clipboard";
631
- const checkIcon = "bi-check2";
632
-
633
- const shareIconEl = window.document.createElement("i");
634
- shareIconEl.setAttribute("class", `bi ${linkIcon}`);
635
- copyButtonEl.appendChild(shareIconEl);
636
- inputSuffixEl.prepend(copyButtonEl);
637
-
638
- const clipboard = new window.ClipboardJS(".aa-CopyButton", {
639
- text: function (_trigger) {
640
- const copyUrl = new URL(window.location);
641
- copyUrl.searchParams.set(kQueryArg, lastQuery);
642
- copyUrl.searchParams.set(kResultsArg, "1");
643
- return copyUrl.toString();
644
- },
645
- });
646
- clipboard.on("success", function (e) {
647
- // Focus the input
648
-
649
- // button target
650
- const button = e.trigger;
651
- const icon = button.querySelector("i.bi");
652
-
653
- // flash "checked"
654
- icon.classList.add(checkIcon);
655
- icon.classList.remove(linkIcon);
656
- setTimeout(function () {
657
- icon.classList.remove(checkIcon);
658
- icon.classList.add(linkIcon);
659
- }, 1000);
660
- });
661
- }
662
-
663
- // If there is a query, show the link icon
664
- if (copyButtonEl) {
665
- if (lastQuery && options["copy-button"]) {
666
- copyButtonEl.style.display = "flex";
667
- } else {
668
- copyButtonEl.style.display = "none";
669
- }
670
- }
671
- }
672
- }
673
-
674
- /* Search Index Handling */
675
- // create the index
676
- var fuseIndex = undefined;
677
- var shownWarning = false;
678
- async function readSearchData() {
679
- // Initialize the search index on demand
680
- if (fuseIndex === undefined) {
681
- if (window.location.protocol === "file:" && !shownWarning) {
682
- window.alert(
683
- "Search requires JavaScript features disabled when running in file://... URLs. In order to use search, please run this document in a web server."
684
- );
685
- shownWarning = true;
686
- return;
687
- }
688
- // create fuse index
689
- const options = {
690
- keys: [
691
- { name: "title", weight: 20 },
692
- { name: "section", weight: 20 },
693
- { name: "text", weight: 10 },
694
- ],
695
- ignoreLocation: true,
696
- threshold: 0.1,
697
- };
698
- const fuse = new window.Fuse([], options);
699
-
700
- // fetch the main search.json
701
- const response = await fetch(offsetURL("search.json"));
702
- if (response.status == 200) {
703
- return response.json().then(function (searchDocs) {
704
- searchDocs.forEach(function (searchDoc) {
705
- fuse.add(searchDoc);
706
- });
707
- fuseIndex = fuse;
708
- return fuseIndex;
709
- });
710
- } else {
711
- return Promise.reject(
712
- new Error(
713
- "Unexpected status from search index request: " + response.status
714
- )
715
- );
716
- }
717
- }
718
-
719
- return fuseIndex;
720
- }
721
-
722
- function inputElement() {
723
- return window.document.body.querySelector(".aa-Form .aa-Input");
724
- }
725
-
726
- function focusSearchInput() {
727
- setTimeout(() => {
728
- const inputEl = inputElement();
729
- if (inputEl) {
730
- inputEl.focus();
731
- }
732
- }, 50);
733
- }
734
-
735
- /* Panels */
736
- const kItemTypeDoc = "document";
737
- const kItemTypeMore = "document-more";
738
- const kItemTypeItem = "document-item";
739
- const kItemTypeError = "error";
740
-
741
- function renderItem(
742
- item,
743
- createElement,
744
- state,
745
- setActiveItemId,
746
- setContext,
747
- refresh,
748
- quartoSearchOptions
749
- ) {
750
- switch (item.type) {
751
- case kItemTypeDoc:
752
- return createDocumentCard(
753
- createElement,
754
- "file-richtext",
755
- item.title,
756
- item.section,
757
- item.text,
758
- item.href,
759
- item.crumbs,
760
- quartoSearchOptions
761
- );
762
- case kItemTypeMore:
763
- return createMoreCard(
764
- createElement,
765
- item,
766
- state,
767
- setActiveItemId,
768
- setContext,
769
- refresh
770
- );
771
- case kItemTypeItem:
772
- return createSectionCard(
773
- createElement,
774
- item.section,
775
- item.text,
776
- item.href
777
- );
778
- case kItemTypeError:
779
- return createErrorCard(createElement, item.title, item.text);
780
- default:
781
- return undefined;
782
- }
783
- }
784
-
785
- function createDocumentCard(
786
- createElement,
787
- icon,
788
- title,
789
- section,
790
- text,
791
- href,
792
- crumbs,
793
- quartoSearchOptions
794
- ) {
795
- const iconEl = createElement("i", {
796
- class: `bi bi-${icon} search-result-icon`,
797
- });
798
- const titleEl = createElement("p", { class: "search-result-title" }, title);
799
- const titleContents = [iconEl, titleEl];
800
- const showParent = quartoSearchOptions["show-item-context"];
801
- if (crumbs && showParent) {
802
- let crumbsOut = undefined;
803
- const crumbClz = ["search-result-crumbs"];
804
- if (showParent === "root") {
805
- crumbsOut = crumbs.length > 1 ? crumbs[0] : undefined;
806
- } else if (showParent === "parent") {
807
- crumbsOut = crumbs.length > 1 ? crumbs[crumbs.length - 2] : undefined;
808
- } else {
809
- crumbsOut = crumbs.length > 1 ? crumbs.join(" > ") : undefined;
810
- crumbClz.push("search-result-crumbs-wrap");
811
- }
812
-
813
- const crumbEl = createElement(
814
- "p",
815
- { class: crumbClz.join(" ") },
816
- crumbsOut
817
- );
818
- titleContents.push(crumbEl);
819
- }
820
-
821
- const titleContainerEl = createElement(
822
- "div",
823
- { class: "search-result-title-container" },
824
- titleContents
825
- );
826
-
827
- const textEls = [];
828
- if (section) {
829
- const sectionEl = createElement(
830
- "p",
831
- { class: "search-result-section" },
832
- section
833
- );
834
- textEls.push(sectionEl);
835
- }
836
- const descEl = createElement("p", {
837
- class: "search-result-text",
838
- dangerouslySetInnerHTML: {
839
- __html: text,
840
- },
841
- });
842
- textEls.push(descEl);
843
-
844
- const textContainerEl = createElement(
845
- "div",
846
- { class: "search-result-text-container" },
847
- textEls
848
- );
849
-
850
- const containerEl = createElement(
851
- "div",
852
- {
853
- class: "search-result-container",
854
- },
855
- [titleContainerEl, textContainerEl]
856
- );
857
-
858
- const linkEl = createElement(
859
- "a",
860
- {
861
- href: offsetURL(href),
862
- class: "search-result-link",
863
- },
864
- containerEl
865
- );
866
-
867
- const classes = ["search-result-doc", "search-item"];
868
- if (!section) {
869
- classes.push("document-selectable");
870
- }
871
-
872
- return createElement(
873
- "div",
874
- {
875
- class: classes.join(" "),
876
- },
877
- linkEl
878
- );
879
- }
880
-
881
- function createMoreCard(
882
- createElement,
883
- item,
884
- state,
885
- setActiveItemId,
886
- setContext,
887
- refresh
888
- ) {
889
- const moreCardEl = createElement(
890
- "div",
891
- {
892
- class: "search-result-more search-item",
893
- onClick: (e) => {
894
- // Handle expanding the sections by adding the expanded
895
- // section to the list of expanded sections
896
- toggleExpanded(item, state, setContext, setActiveItemId, refresh);
897
- e.stopPropagation();
898
- },
899
- },
900
- item.title
901
- );
902
-
903
- return moreCardEl;
904
- }
905
-
906
- function toggleExpanded(item, state, setContext, setActiveItemId, refresh) {
907
- const expanded = state.context.expanded || [];
908
- if (expanded.includes(item.target)) {
909
- setContext({
910
- expanded: expanded.filter((target) => target !== item.target),
911
- });
912
- } else {
913
- setContext({ expanded: [...expanded, item.target] });
914
- }
915
-
916
- refresh();
917
- setActiveItemId(item.__autocomplete_id);
918
- }
919
-
920
- function createSectionCard(createElement, section, text, href) {
921
- const sectionEl = createSection(createElement, section, text, href);
922
- return createElement(
923
- "div",
924
- {
925
- class: "search-result-doc-section search-item",
926
- },
927
- sectionEl
928
- );
929
- }
930
-
931
- function createSection(createElement, title, text, href) {
932
- const descEl = createElement("p", {
933
- class: "search-result-text",
934
- dangerouslySetInnerHTML: {
935
- __html: text,
936
- },
937
- });
938
-
939
- const titleEl = createElement("p", { class: "search-result-section" }, title);
940
- const linkEl = createElement(
941
- "a",
942
- {
943
- href: offsetURL(href),
944
- class: "search-result-link",
945
- },
946
- [titleEl, descEl]
947
- );
948
- return linkEl;
949
- }
950
-
951
- function createErrorCard(createElement, title, text) {
952
- const descEl = createElement("p", {
953
- class: "search-error-text",
954
- dangerouslySetInnerHTML: {
955
- __html: text,
956
- },
957
- });
958
-
959
- const titleEl = createElement("p", {
960
- class: "search-error-title",
961
- dangerouslySetInnerHTML: {
962
- __html: `<i class="bi bi-exclamation-circle search-error-icon"></i> ${title}`,
963
- },
964
- });
965
- const errorEl = createElement("div", { class: "search-error" }, [
966
- titleEl,
967
- descEl,
968
- ]);
969
- return errorEl;
970
- }
971
-
972
- function positionPanel(pos) {
973
- const panelEl = window.document.querySelector(
974
- "#quarto-search-results .aa-Panel"
975
- );
976
- const inputEl = window.document.querySelector(
977
- "#quarto-search .aa-Autocomplete"
978
- );
979
-
980
- if (panelEl && inputEl) {
981
- panelEl.style.top = `${Math.round(panelEl.offsetTop)}px`;
982
- if (pos === "start") {
983
- panelEl.style.left = `${Math.round(inputEl.left)}px`;
984
- } else {
985
- panelEl.style.right = `${Math.round(inputEl.offsetRight)}px`;
986
- }
987
- }
988
- }
989
-
990
- /* Highlighting */
991
- // highlighting functions
992
- function highlightMatch(query, text) {
993
- if (text) {
994
- const start = text.toLowerCase().indexOf(query.toLowerCase());
995
- if (start !== -1) {
996
- const startMark = "<mark class='search-match'>";
997
- const endMark = "</mark>";
998
-
999
- const end = start + query.length;
1000
- text =
1001
- text.slice(0, start) +
1002
- startMark +
1003
- text.slice(start, end) +
1004
- endMark +
1005
- text.slice(end);
1006
- const startInfo = clipStart(text, start);
1007
- const endInfo = clipEnd(
1008
- text,
1009
- startInfo.position + startMark.length + endMark.length
1010
- );
1011
- text =
1012
- startInfo.prefix +
1013
- text.slice(startInfo.position, endInfo.position) +
1014
- endInfo.suffix;
1015
-
1016
- return text;
1017
- } else {
1018
- return text;
1019
- }
1020
- } else {
1021
- return text;
1022
- }
1023
- }
1024
-
1025
- function clipStart(text, pos) {
1026
- const clipStart = pos - 50;
1027
- if (clipStart < 0) {
1028
- // This will just return the start of the string
1029
- return {
1030
- position: 0,
1031
- prefix: "",
1032
- };
1033
- } else {
1034
- // We're clipping before the start of the string, walk backwards to the first space.
1035
- const spacePos = findSpace(text, pos, -1);
1036
- return {
1037
- position: spacePos.position,
1038
- prefix: "",
1039
- };
1040
- }
1041
- }
1042
-
1043
- function clipEnd(text, pos) {
1044
- const clipEnd = pos + 200;
1045
- if (clipEnd > text.length) {
1046
- return {
1047
- position: text.length,
1048
- suffix: "",
1049
- };
1050
- } else {
1051
- const spacePos = findSpace(text, clipEnd, 1);
1052
- return {
1053
- position: spacePos.position,
1054
- suffix: spacePos.clipped ? "…" : "",
1055
- };
1056
- }
1057
- }
1058
-
1059
- function findSpace(text, start, step) {
1060
- let stepPos = start;
1061
- while (stepPos > -1 && stepPos < text.length) {
1062
- const char = text[stepPos];
1063
- if (char === " " || char === "," || char === ":") {
1064
- return {
1065
- position: step === 1 ? stepPos : stepPos - step,
1066
- clipped: stepPos > 1 && stepPos < text.length,
1067
- };
1068
- }
1069
- stepPos = stepPos + step;
1070
- }
1071
-
1072
- return {
1073
- position: stepPos - step,
1074
- clipped: false,
1075
- };
1076
- }
1077
-
1078
- // removes highlighting as implemented by the mark tag
1079
- function clearHighlight(searchterm, el) {
1080
- const childNodes = el.childNodes;
1081
- for (let i = childNodes.length - 1; i >= 0; i--) {
1082
- const node = childNodes[i];
1083
- if (node.nodeType === Node.ELEMENT_NODE) {
1084
- if (
1085
- node.tagName === "MARK" &&
1086
- node.innerText.toLowerCase() === searchterm.toLowerCase()
1087
- ) {
1088
- el.replaceChild(document.createTextNode(node.innerText), node);
1089
- } else {
1090
- clearHighlight(searchterm, node);
1091
- }
1092
- }
1093
- }
1094
- }
1095
-
1096
- function escapeRegExp(string) {
1097
- return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
1098
- }
1099
-
1100
- // highlight matches
1101
- function highlight(term, el) {
1102
- const termRegex = new RegExp(term, "ig");
1103
- const childNodes = el.childNodes;
1104
-
1105
- // walk back to front avoid mutating elements in front of us
1106
- for (let i = childNodes.length - 1; i >= 0; i--) {
1107
- const node = childNodes[i];
1108
-
1109
- if (node.nodeType === Node.TEXT_NODE) {
1110
- // Search text nodes for text to highlight
1111
- const text = node.nodeValue;
1112
-
1113
- let startIndex = 0;
1114
- let matchIndex = text.search(termRegex);
1115
- if (matchIndex > -1) {
1116
- const markFragment = document.createDocumentFragment();
1117
- while (matchIndex > -1) {
1118
- const prefix = text.slice(startIndex, matchIndex);
1119
- markFragment.appendChild(document.createTextNode(prefix));
1120
-
1121
- const mark = document.createElement("mark");
1122
- mark.appendChild(
1123
- document.createTextNode(
1124
- text.slice(matchIndex, matchIndex + term.length)
1125
- )
1126
- );
1127
- markFragment.appendChild(mark);
1128
-
1129
- startIndex = matchIndex + term.length;
1130
- matchIndex = text.slice(startIndex).search(new RegExp(term, "ig"));
1131
- if (matchIndex > -1) {
1132
- matchIndex = startIndex + matchIndex;
1133
- }
1134
- }
1135
- if (startIndex < text.length) {
1136
- markFragment.appendChild(
1137
- document.createTextNode(text.slice(startIndex, text.length))
1138
- );
1139
- }
1140
-
1141
- el.replaceChild(markFragment, node);
1142
- }
1143
- } else if (node.nodeType === Node.ELEMENT_NODE) {
1144
- // recurse through elements
1145
- highlight(term, node);
1146
- }
1147
- }
1148
- }
1149
-
1150
- /* Link Handling */
1151
- // get the offset from this page for a given site root relative url
1152
- function offsetURL(url) {
1153
- var offset = getMeta("quarto:offset");
1154
- return offset ? offset + url : url;
1155
- }
1156
-
1157
- // read a meta tag value
1158
- function getMeta(metaName) {
1159
- var metas = window.document.getElementsByTagName("meta");
1160
- for (let i = 0; i < metas.length; i++) {
1161
- if (metas[i].getAttribute("name") === metaName) {
1162
- return metas[i].getAttribute("content");
1163
- }
1164
- }
1165
- return "";
1166
- }
1167
-
1168
- function algoliaSearch(query, limit, algoliaOptions) {
1169
- const { getAlgoliaResults } = window["@algolia/autocomplete-preset-algolia"];
1170
-
1171
- const applicationId = algoliaOptions["application-id"];
1172
- const searchOnlyApiKey = algoliaOptions["search-only-api-key"];
1173
- const indexName = algoliaOptions["index-name"];
1174
- const indexFields = algoliaOptions["index-fields"];
1175
- const searchClient = window.algoliasearch(applicationId, searchOnlyApiKey);
1176
- const searchParams = algoliaOptions["params"];
1177
- const searchAnalytics = !!algoliaOptions["analytics-events"];
1178
-
1179
- return getAlgoliaResults({
1180
- searchClient,
1181
- queries: [
1182
- {
1183
- indexName: indexName,
1184
- query,
1185
- params: {
1186
- hitsPerPage: limit,
1187
- clickAnalytics: searchAnalytics,
1188
- ...searchParams,
1189
- },
1190
- },
1191
- ],
1192
- transformResponse: (response) => {
1193
- if (!indexFields) {
1194
- return response.hits.map((hit) => {
1195
- return hit.map((item) => {
1196
- return {
1197
- ...item,
1198
- text: highlightMatch(query, item.text),
1199
- };
1200
- });
1201
- });
1202
- } else {
1203
- const remappedHits = response.hits.map((hit) => {
1204
- return hit.map((item) => {
1205
- const newItem = { ...item };
1206
- ["href", "section", "title", "text", "crumbs"].forEach(
1207
- (keyName) => {
1208
- const mappedName = indexFields[keyName];
1209
- if (
1210
- mappedName &&
1211
- item[mappedName] !== undefined &&
1212
- mappedName !== keyName
1213
- ) {
1214
- newItem[keyName] = item[mappedName];
1215
- delete newItem[mappedName];
1216
- }
1217
- }
1218
- );
1219
- newItem.text = highlightMatch(query, newItem.text);
1220
- return newItem;
1221
- });
1222
- });
1223
- return remappedHits;
1224
- }
1225
- },
1226
- });
1227
- }
1228
-
1229
- function fuseSearch(query, fuse, fuseOptions) {
1230
- return fuse.search(query, fuseOptions).map((result) => {
1231
- const addParam = (url, name, value) => {
1232
- const anchorParts = url.split("#");
1233
- const baseUrl = anchorParts[0];
1234
- const sep = baseUrl.search("\\?") > 0 ? "&" : "?";
1235
- anchorParts[0] = baseUrl + sep + name + "=" + value;
1236
- return anchorParts.join("#");
1237
- };
1238
-
1239
- return {
1240
- title: result.item.title,
1241
- section: result.item.section,
1242
- href: addParam(result.item.href, kQueryArg, query),
1243
- text: highlightMatch(query, result.item.text),
1244
- crumbs: result.item.crumbs,
1245
- };
1246
- });
1247
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
about.qmd DELETED
@@ -1,19 +0,0 @@
1
- ---
2
- title: "About"
3
- image: profile.jpg
4
- about:
5
- template: jolla
6
- links:
7
- - icon: twitter
8
- text: Twitter
9
- href: https://twitter.com
10
- - icon: linkedin
11
- text: LinkedIn
12
- href: https://linkedin.com
13
- - icon: github
14
- text: Github
15
- href: https://github.com
16
-
17
- ---
18
-
19
- About this blog
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
index.qmd DELETED
@@ -1,14 +0,0 @@
1
- ---
2
- title: "."
3
- listing:
4
- contents: posts
5
- sort: "date desc"
6
- type: default
7
- categories: true
8
- sort-ui: false
9
- filter-ui: false
10
- page-layout: full
11
- title-block-banner: true
12
- ---
13
-
14
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posts/_metadata.yml DELETED
@@ -1,8 +0,0 @@
1
- # options specified here will apply to all posts in this folder
2
-
3
- # freeze computational output
4
- # (see https://quarto.org/docs/projects/code-execution.html#freeze)
5
- freeze: true
6
-
7
- # Enable banner style title blocks
8
- title-block-banner: true
 
 
 
 
 
 
 
 
 
posts/post-with-code/image.jpg DELETED
Binary file (41.7 kB)
 
posts/post-with-code/index.qmd DELETED
@@ -1,9 +0,0 @@
1
- ---
2
- title: "Post With Code"
3
- author: "Harlow Malloc"
4
- date: "2024-02-15"
5
- categories: [news, code, analysis]
6
- image: "image.jpg"
7
- ---
8
-
9
- This is a post with executable code.
 
 
 
 
 
 
 
 
 
 
posts/welcome/index.qmd DELETED
@@ -1,12 +0,0 @@
1
- ---
2
- title: "Welcome To My Blog"
3
- author: "Tristan O'Malley"
4
- date: "2024-02-12"
5
- categories: [news]
6
- ---
7
-
8
- This is the first post in a Quarto blog. Welcome!
9
-
10
- ![](thumbnail.jpg)
11
-
12
- Since this post doesn't specify an explicit `image`, the first image in the post will be used in the listing page of posts.
 
 
 
 
 
 
 
 
 
 
 
 
 
posts/welcome/thumbnail.jpg DELETED
Binary file (39.9 kB)
 
profile.jpg DELETED
Binary file (60.5 kB)
 
requirements.txt ADDED
File without changes
src/.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ /.quarto/
src/_quarto.yml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ project:
2
+ type: website
3
+
4
+ website:
5
+ title: "Open-Source AI Cookbook"
6
+ navbar:
7
+ left:
8
+ - href: index.qmd
9
+ text: Open-Source AI Cookbook
10
+ - notebooks/automatic_embedding.ipynb
11
+ - notebooks/faiss.ipynb
12
+ - notebooks/single_gpu.ipynb
13
+ - text: RAG
14
+ menu:
15
+ - notebooks/rag_zephyr_langchain.ipynb
16
+ - notebooks/advanced_rag.ipynb
17
+ - notebooks/rag_evaluation.ipynb
18
+
19
+ format:
20
+ html:
21
+ theme: cosmo
22
+ css: styles.css
23
+ toc: true
24
+
25
+
26
+
src/about.qmd ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ ---
2
+ title: "About"
3
+ ---
4
+
5
+ About this site
src/index.qmd ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: "Open Source Cookbook"
3
+ ---
4
+
5
+ This is a Quarto implementation of [the Open-Source AI Cookbook](https://github.com/huggingface/cookbook),
6
+ which is a collection of notebooks illustrating practical aspects of building AI
7
+ applications and solving various machine learning tasks using open-source tools and models.
8
+
9
+ ## About Quarto
10
+ [Quarto](https://quarto.org/) is a Markdown-based documentation system which lets you write documents in Markdown or Jupyter Notebooks, and render them to a variety of formats including HTML, PDF, Powerpoint, and more.
11
+ You can also use Quarto to write [books](https://quarto.org/docs/books/), create [dashboards](https://quarto.org/docs/dashboards/), and embed web applications with [Observable](https://quarto.org/docs/interactive/ojs/) and [Shinylive](https://quarto.org/docs/blog/posts/2022-10-25-shinylive-extension/).
12
+
13
+
14
+ ## Latest notebooks
15
+
16
+ Check out the recently added notebooks:
17
+
18
+ - [Automatic Embeddings with TEI through Inference Endpoints](automatic_embedding_tei_inference_endpoints)
19
+ - [Simple RAG for GitHub issues using Hugging Face Zephyr and LangChain](rag_zephyr_langchain)
20
+ - [Embedding multimodal data for similarity search using 🤗 transformers, 🤗 datasets and FAISS](faiss_with_hf_datasets_and_clip)
21
+ - [Fine-tuning a Code LLM on Custom Code on a single GPU](fine_tuning_code_llm_on_single_gpu)
22
+ - [RAG Evaluation Using Synthetic data and LLM-As-A-Judge](rag_evaluation)
23
+ - [Advanced RAG on HuggingFace documentation using LangChain](advanced_rag)
24
+
25
+ You can also check out the notebooks in the cookbook's [GitHub repo](https://github.com/huggingface/cookbook).
26
+
27
+ ## Contributing
28
+
29
+ The Open-Source AI Cookbook is a community effort, and we welcome contributions from everyone!
30
+ Check out the cookbook's [Contribution guide](https://github.com/huggingface/cookbook/blob/main/README.md) to learn
31
+ how you can add your "recipe".
src/notebooks/advanced_rag.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
src/notebooks/automatic_embedding.ipynb ADDED
@@ -0,0 +1,825 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "id": "5d9aca72-957a-4ee2-862f-e011b9cd3a62",
6
+ "metadata": {},
7
+ "source": [
8
+ "---\n",
9
+ "title: \"Inference Endpoints\"\n",
10
+ "---\n",
11
+ "\n",
12
+ "# How to use Inference Endpoints to Embed Documents\n",
13
+ "\n",
14
+ "_Authored by: [Derek Thomas](https://huggingface.co/derek-thomas)_\n",
15
+ "\n",
16
+ "## Goal\n",
17
+ "I have a dataset I want to embed for semantic search (or QA, or RAG), I want the easiest way to do embed this and put it in a new dataset.\n",
18
+ "\n",
19
+ "## Approach\n",
20
+ "I'm using a dataset from my favorite subreddit [r/bestofredditorupdates](https://www.reddit.com/r/bestofredditorupdates/). Because it has long entries, I will use the new [jinaai/jina-embeddings-v2-base-en](https://huggingface.co/jinaai/jina-embeddings-v2-base-en) since it has an 8k context length. I will deploy this using [Inference Endpoint](https://huggingface.co/inference-endpoints) to save time and money. To follow this tutorial, you will need to **have already added a payment method**. If you haven't, you can add one here in [billing](https://huggingface.co/docs/hub/billing#billing). To make it even easier, I'll make this fully API based.\n",
21
+ "\n",
22
+ "To make this MUCH faster I will use the [Text Embeddings Inference](https://github.com/huggingface/text-embeddings-inference) image. This has many benefits like:\n",
23
+ "- No model graph compilation step\n",
24
+ "- Small docker images and fast boot times. Get ready for true serverless!\n",
25
+ "- Token based dynamic batching\n",
26
+ "- Optimized transformers code for inference using Flash Attention, Candle and cuBLASLt\n",
27
+ "- Safetensors weight loading\n",
28
+ "- Production ready (distributed tracing with Open Telemetry, Prometheus metrics)\n",
29
+ "\n",
30
+ "![img](https://media.githubusercontent.com/media/huggingface/text-embeddings-inference/main/assets/bs1-tp.png)"
31
+ ]
32
+ },
33
+ {
34
+ "cell_type": "markdown",
35
+ "id": "3c830114-dd88-45a9-81b9-78b0e3da7384",
36
+ "metadata": {},
37
+ "source": [
38
+ "## Requirements"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": null,
44
+ "id": "35386f72-32cb-49fa-a108-3aa504e20429",
45
+ "metadata": {
46
+ "tags": []
47
+ },
48
+ "outputs": [],
49
+ "source": [
50
+ "!pip install -q aiohttp==3.8.3 datasets==2.14.6 pandas==1.5.3 requests==2.31.0 tqdm==4.66.1 huggingface-hub>=0.20"
51
+ ]
52
+ },
53
+ {
54
+ "cell_type": "markdown",
55
+ "id": "b6f72042-173d-4a72-ade1-9304b43b528d",
56
+ "metadata": {},
57
+ "source": [
58
+ "## Imports"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": 3,
64
+ "id": "e2beecdd-d033-4736-bd45-6754ec53b4ac",
65
+ "metadata": {
66
+ "tags": []
67
+ },
68
+ "outputs": [],
69
+ "source": [
70
+ "import asyncio\n",
71
+ "from getpass import getpass\n",
72
+ "import json\n",
73
+ "from pathlib import Path\n",
74
+ "import time\n",
75
+ "from typing import Optional\n",
76
+ "\n",
77
+ "from aiohttp import ClientSession, ClientTimeout\n",
78
+ "from datasets import load_dataset, Dataset, DatasetDict\n",
79
+ "from huggingface_hub import notebook_login, create_inference_endpoint, list_inference_endpoints, whoami\n",
80
+ "import numpy as np\n",
81
+ "import pandas as pd\n",
82
+ "import requests\n",
83
+ "from tqdm.auto import tqdm"
84
+ ]
85
+ },
86
+ {
87
+ "cell_type": "markdown",
88
+ "id": "5eece903-64ce-435d-a2fd-096c0ff650bf",
89
+ "metadata": {},
90
+ "source": [
91
+ "## Config\n",
92
+ "`DATASET_IN` is where your text data is\n",
93
+ "`DATASET_OUT` is where your embeddings will be stored\n",
94
+ "\n",
95
+ "Note I used 5 for the `MAX_WORKERS` since `jina-embeddings-v2` are quite memory hungry. "
96
+ ]
97
+ },
98
+ {
99
+ "cell_type": "code",
100
+ "execution_count": 4,
101
+ "id": "df2f79f0-9f28-46e6-9fc7-27e9537ff5be",
102
+ "metadata": {
103
+ "tags": []
104
+ },
105
+ "outputs": [],
106
+ "source": [
107
+ "DATASET_IN = 'derek-thomas/dataset-creator-reddit-bestofredditorupdates'\n",
108
+ "DATASET_OUT = \"processed-subset-bestofredditorupdates\"\n",
109
+ "ENDPOINT_NAME = \"boru-jina-embeddings-demo-ie\"\n",
110
+ "\n",
111
+ "MAX_WORKERS = 5 # This is for how many async workers you want. Choose based on the model and hardware \n",
112
+ "ROW_COUNT = 100 # Choose None to use all rows, Im using 100 just for a demo"
113
+ ]
114
+ },
115
+ {
116
+ "cell_type": "markdown",
117
+ "id": "1e680f3d-4900-46cc-8b49-bb6ba3e27e2b",
118
+ "metadata": {},
119
+ "source": [
120
+ "Hugging Face offers a number of GPUs that you can choose from a number of GPUs that you can choose in Inference Endpoints. Here they are in table form:\n",
121
+ "\n",
122
+ "| GPU | instanceType | instanceSize | vRAM |\n",
123
+ "|---------------------|----------------|--------------|-------|\n",
124
+ "| 1x Nvidia Tesla T4 | g4dn.xlarge | small | 16GB |\n",
125
+ "| 4x Nvidia Tesla T4 | g4dn.12xlarge | large | 64GB |\n",
126
+ "| 1x Nvidia A10G | g5.2xlarge | medium | 24GB |\n",
127
+ "| 4x Nvidia A10G | g5.12xlarge | xxlarge | 96GB |\n",
128
+ "| 1x Nvidia A100* | p4de | xlarge | 80GB |\n",
129
+ "| 2x Nvidia A100* | p4de | 2xlarge | 160GB |\n",
130
+ "\n",
131
+ "\\*Note that for A100s you might get a note to email us to get access."
132
+ ]
133
+ },
134
+ {
135
+ "cell_type": "code",
136
+ "execution_count": 4,
137
+ "id": "3c2106c1-2e5a-443a-9ea8-a3cd0e9c5a94",
138
+ "metadata": {
139
+ "tags": []
140
+ },
141
+ "outputs": [],
142
+ "source": [
143
+ "# GPU Choice\n",
144
+ "VENDOR=\"aws\"\n",
145
+ "REGION=\"us-east-1\"\n",
146
+ "INSTANCE_SIZE=\"medium\"\n",
147
+ "INSTANCE_TYPE=\"g5.2xlarge\""
148
+ ]
149
+ },
150
+ {
151
+ "cell_type": "code",
152
+ "execution_count": 5,
153
+ "id": "0ca1140c-3fcc-4b99-9210-6da1505a27b7",
154
+ "metadata": {
155
+ "tags": []
156
+ },
157
+ "outputs": [
158
+ {
159
+ "data": {
160
+ "application/vnd.jupyter.widget-view+json": {
161
+ "model_id": "ee80821056e147fa9cabf30f64dc85a8",
162
+ "version_major": 2,
163
+ "version_minor": 0
164
+ },
165
+ "text/plain": [
166
+ "VBox(children=(HTML(value='<center> <img\\nsrc=https://huggingface.co/front/assets/huggingface_logo-noborder.sv…"
167
+ ]
168
+ },
169
+ "metadata": {},
170
+ "output_type": "display_data"
171
+ }
172
+ ],
173
+ "source": [
174
+ "notebook_login()"
175
+ ]
176
+ },
177
+ {
178
+ "cell_type": "markdown",
179
+ "id": "5f4ba0a8-0a6c-4705-a73b-7be09b889610",
180
+ "metadata": {},
181
+ "source": [
182
+ "Some users might have payment registered in an organization. This allows you to connect to an organization (that you are a member of) with a payment method.\n",
183
+ "\n",
184
+ "Leave it blank is you want to use your username."
185
+ ]
186
+ },
187
+ {
188
+ "cell_type": "code",
189
+ "execution_count": 6,
190
+ "id": "88cdbd73-5923-4ae9-9940-b6be935f70fa",
191
+ "metadata": {
192
+ "tags": []
193
+ },
194
+ "outputs": [
195
+ {
196
+ "name": "stdout",
197
+ "output_type": "stream",
198
+ "text": [
199
+ "What is your Hugging Face 🤗 username or organization? (with an added payment method) ········\n"
200
+ ]
201
+ }
202
+ ],
203
+ "source": [
204
+ "who = whoami()\n",
205
+ "organization = getpass(prompt=\"What is your Hugging Face 🤗 username or organization? (with an added payment method)\")\n",
206
+ "\n",
207
+ "namespace = organization or who['name']"
208
+ ]
209
+ },
210
+ {
211
+ "cell_type": "markdown",
212
+ "id": "b972a719-2aed-4d2e-a24f-fae7776d5fa4",
213
+ "metadata": {},
214
+ "source": [
215
+ "## Get Dataset"
216
+ ]
217
+ },
218
+ {
219
+ "cell_type": "code",
220
+ "execution_count": 7,
221
+ "id": "27835fa4-3a4f-44b1-a02a-5e31584a1bba",
222
+ "metadata": {
223
+ "tags": []
224
+ },
225
+ "outputs": [
226
+ {
227
+ "data": {
228
+ "application/vnd.jupyter.widget-view+json": {
229
+ "model_id": "4041cedd3b3f4f8db3e29ec102f46a3a",
230
+ "version_major": 2,
231
+ "version_minor": 0
232
+ },
233
+ "text/plain": [
234
+ "Downloading readme: 0%| | 0.00/1.73k [00:00<?, ?B/s]"
235
+ ]
236
+ },
237
+ "metadata": {},
238
+ "output_type": "display_data"
239
+ },
240
+ {
241
+ "data": {
242
+ "text/plain": [
243
+ "Dataset({\n",
244
+ " features: ['id', 'content', 'score', 'date_utc', 'title', 'flair', 'poster', 'permalink', 'new', 'updated'],\n",
245
+ " num_rows: 10042\n",
246
+ "})"
247
+ ]
248
+ },
249
+ "execution_count": 7,
250
+ "metadata": {},
251
+ "output_type": "execute_result"
252
+ }
253
+ ],
254
+ "source": [
255
+ "dataset = load_dataset(DATASET_IN)\n",
256
+ "dataset['train']"
257
+ ]
258
+ },
259
+ {
260
+ "cell_type": "code",
261
+ "execution_count": 8,
262
+ "id": "8846087e-4d0d-4c0e-8aeb-ea95d9e97126",
263
+ "metadata": {
264
+ "tags": []
265
+ },
266
+ "outputs": [
267
+ {
268
+ "data": {
269
+ "text/plain": [
270
+ "(100,\n",
271
+ " {'id': '10004zw',\n",
272
+ " 'content': '[removed]',\n",
273
+ " 'score': 1,\n",
274
+ " 'date_utc': Timestamp('2022-12-31 18:16:22'),\n",
275
+ " 'title': 'To All BORU contributors, Thank you :)',\n",
276
+ " 'flair': 'CONCLUDED',\n",
277
+ " 'poster': 'IsItAcOnSeQuEnCe',\n",
278
+ " 'permalink': '/r/BestofRedditorUpdates/comments/10004zw/to_all_boru_contributors_thank_you/',\n",
279
+ " 'new': False,\n",
280
+ " 'updated': False})"
281
+ ]
282
+ },
283
+ "execution_count": 8,
284
+ "metadata": {},
285
+ "output_type": "execute_result"
286
+ }
287
+ ],
288
+ "source": [
289
+ "documents = dataset['train'].to_pandas().to_dict('records')[:ROW_COUNT]\n",
290
+ "len(documents), documents[0]"
291
+ ]
292
+ },
293
+ {
294
+ "cell_type": "markdown",
295
+ "id": "93096cbc-81c6-4137-a283-6afb0f48fbb9",
296
+ "metadata": {},
297
+ "source": [
298
+ "# Inference Endpoints\n",
299
+ "## Create Inference Endpoint\n",
300
+ "We are going to use the [API](https://huggingface.co/docs/inference-endpoints/api_reference) to create an [Inference Endpoint](https://huggingface.co/inference-endpoints). This should provide a few main benefits:\n",
301
+ "- It's convenient (No clicking)\n",
302
+ "- It's repeatable (We have the code to run it easily)\n",
303
+ "- It's cheaper (No time spent waiting for it to load, and automatically shut it down)\n",
304
+ "\n"
305
+ ]
306
+ },
307
+ {
308
+ "cell_type": "code",
309
+ "execution_count": 9,
310
+ "id": "9e59de46-26b7-4bb9-bbad-8bba9931bde7",
311
+ "metadata": {
312
+ "tags": []
313
+ },
314
+ "outputs": [],
315
+ "source": [
316
+ "try:\n",
317
+ " endpoint = create_inference_endpoint(\n",
318
+ " ENDPOINT_NAME,\n",
319
+ " repository=\"jinaai/jina-embeddings-v2-base-en\",\n",
320
+ " revision=\"7302ac470bed880590f9344bfeee32ff8722d0e5\",\n",
321
+ " task=\"sentence-embeddings\",\n",
322
+ " framework=\"pytorch\",\n",
323
+ " accelerator=\"gpu\",\n",
324
+ " instance_size=INSTANCE_SIZE,\n",
325
+ " instance_type=INSTANCE_TYPE,\n",
326
+ " region=REGION,\n",
327
+ " vendor=VENDOR,\n",
328
+ " namespace=namespace,\n",
329
+ " custom_image={\n",
330
+ " \"health_route\": \"/health\",\n",
331
+ " \"env\": {\n",
332
+ " \"MAX_BATCH_TOKENS\": str(MAX_WORKERS * 2048),\n",
333
+ " \"MAX_CONCURRENT_REQUESTS\": \"512\",\n",
334
+ " \"MODEL_ID\": \"/repository\"\n",
335
+ " },\n",
336
+ " \"url\": \"ghcr.io/huggingface/text-embeddings-inference:0.5.0\",\n",
337
+ " },\n",
338
+ " type=\"protected\",\n",
339
+ " )\n",
340
+ "except:\n",
341
+ " endpoint = [ie for ie in list_inference_endpoints(namespace=namespace) if ie.name == ENDPOINT_NAME][0]\n",
342
+ " print('Loaded endpoint')"
343
+ ]
344
+ },
345
+ {
346
+ "cell_type": "markdown",
347
+ "id": "0f2c97dc-34e8-49e9-b60e-f5b7366294c0",
348
+ "metadata": {},
349
+ "source": [
350
+ "There are a few design choices here:\n",
351
+ "- As discussed before we are using `jinaai/jina-embeddings-v2-base-en` as our model. \n",
352
+ " - For reproducibility we are pinning it to a specific revision.\n",
353
+ "- If you are interested in more models, check out the supported list [here](https://huggingface.co/docs/text-embeddings-inference/supported_models). \n",
354
+ " - Note that most embedding models are based on the BERT architecture.\n",
355
+ "- `MAX_BATCH_TOKENS` is chosen based on our number of workers and the context window of our embedding model.\n",
356
+ "- `type=\"protected\"` utilized the security from Inference Endpoints detailed here.\n",
357
+ "- I'm using **1x Nvidia A10** since `jina-embeddings-v2` is memory hungry (remember the 8k context length). \n",
358
+ "- You should consider further tuning `MAX_BATCH_TOKENS` and `MAX_CONCURRENT_REQUESTS` if you have high workloads\n"
359
+ ]
360
+ },
361
+ {
362
+ "cell_type": "markdown",
363
+ "id": "96d173b2-8980-4554-9039-c62843d3fc7d",
364
+ "metadata": {},
365
+ "source": [
366
+ "## Wait until it's running"
367
+ ]
368
+ },
369
+ {
370
+ "cell_type": "code",
371
+ "execution_count": 10,
372
+ "id": "5f3a8bd2-753c-49a8-9452-899578beddc5",
373
+ "metadata": {
374
+ "tags": []
375
+ },
376
+ "outputs": [
377
+ {
378
+ "name": "stdout",
379
+ "output_type": "stream",
380
+ "text": [
381
+ "CPU times: user 48.1 ms, sys: 15.7 ms, total: 63.8 ms\n",
382
+ "Wall time: 52.6 s\n"
383
+ ]
384
+ },
385
+ {
386
+ "data": {
387
+ "text/plain": [
388
+ "InferenceEndpoint(name='boru-jina-embeddings-demo-ie', namespace='HF-test-lab', repository='jinaai/jina-embeddings-v2-base-en', status='running', url='https://k7l1xeok1jwnpbx5.us-east-1.aws.endpoints.huggingface.cloud')"
389
+ ]
390
+ },
391
+ "execution_count": 10,
392
+ "metadata": {},
393
+ "output_type": "execute_result"
394
+ }
395
+ ],
396
+ "source": [
397
+ "%%time\n",
398
+ "endpoint.wait()"
399
+ ]
400
+ },
401
+ {
402
+ "cell_type": "markdown",
403
+ "id": "a906645e-60de-4eb6-b8b6-3ec98a9d9b00",
404
+ "metadata": {},
405
+ "source": [
406
+ "When we use `endpoint.client.post` we get a bytes string back. This is a little tedious because we need to convert this to an `np.array`, but it's just a couple quick lines in python."
407
+ ]
408
+ },
409
+ {
410
+ "cell_type": "code",
411
+ "execution_count": 12,
412
+ "id": "e09253d5-70ff-4d0e-8888-0022ce0adf7b",
413
+ "metadata": {
414
+ "tags": []
415
+ },
416
+ "outputs": [
417
+ {
418
+ "data": {
419
+ "text/plain": [
420
+ "array([-0.05630935, -0.03560849, 0.02789049, 0.02792823, -0.02800371,\n",
421
+ " -0.01530391, -0.01863454, -0.0077982 , 0.05374297, 0.03672185,\n",
422
+ " -0.06114018, -0.06880157, -0.0093503 , -0.03174005, -0.03206085,\n",
423
+ " 0.0610647 , 0.02243694, 0.03217408, 0.04181686, 0.00248854])"
424
+ ]
425
+ },
426
+ "execution_count": 12,
427
+ "metadata": {},
428
+ "output_type": "execute_result"
429
+ }
430
+ ],
431
+ "source": [
432
+ "response = endpoint.client.post(json={\"inputs\": 'This sound track was beautiful! It paints the senery in your mind so well I would recomend it even to people who hate vid. game music!', 'truncate': True}, task=\"feature-extraction\")\n",
433
+ "response = np.array(json.loads(response.decode()))\n",
434
+ "response[0][:20]"
435
+ ]
436
+ },
437
+ {
438
+ "cell_type": "markdown",
439
+ "id": "0d024788-6e6e-4a8d-b192-36ee3dacca13",
440
+ "metadata": {},
441
+ "source": [
442
+ "You may have inputs that exceed the context. In such scenarios, it's up to you to handle them. In my case, I'd like to truncate rather than have an error. Let's test that it works."
443
+ ]
444
+ },
445
+ {
446
+ "cell_type": "code",
447
+ "execution_count": 13,
448
+ "id": "a4a1cd15-dda3-4cfa-8bda-788d8c1b9e32",
449
+ "metadata": {
450
+ "tags": []
451
+ },
452
+ "outputs": [
453
+ {
454
+ "name": "stdout",
455
+ "output_type": "stream",
456
+ "text": [
457
+ "The length of the embedding_input is: 300000\n"
458
+ ]
459
+ },
460
+ {
461
+ "data": {
462
+ "text/plain": [
463
+ "array([-0.03088215, -0.0351537 , 0.05749275, 0.00983467, 0.02108356,\n",
464
+ " 0.04539965, 0.06107162, -0.02536954, 0.03887688, 0.01998681,\n",
465
+ " -0.05391388, 0.01529677, -0.1279156 , 0.01653782, -0.01940958,\n",
466
+ " 0.0367411 , 0.0031748 , 0.04716022, -0.00713609, -0.00155313])"
467
+ ]
468
+ },
469
+ "execution_count": 13,
470
+ "metadata": {},
471
+ "output_type": "execute_result"
472
+ }
473
+ ],
474
+ "source": [
475
+ "embedding_input = 'This input will get multiplied' * 10000\n",
476
+ "print(f'The length of the embedding_input is: {len(embedding_input)}')\n",
477
+ "response = endpoint.client.post(json={\"inputs\": embedding_input, 'truncate': True}, task=\"feature-extraction\")\n",
478
+ "response = np.array(json.loads(response.decode()))\n",
479
+ "response[0][:20]"
480
+ ]
481
+ },
482
+ {
483
+ "cell_type": "markdown",
484
+ "id": "f7186126-ef6a-47d0-b158-112810649cd9",
485
+ "metadata": {},
486
+ "source": [
487
+ "# Get Embeddings"
488
+ ]
489
+ },
490
+ {
491
+ "cell_type": "markdown",
492
+ "id": "1dadfd68-6d46-4ce8-a165-bfeb43b1f114",
493
+ "metadata": {},
494
+ "source": [
495
+ "Here I send a document, update it with the embedding, and return it. This happens in parallel with `MAX_WORKERS`."
496
+ ]
497
+ },
498
+ {
499
+ "cell_type": "code",
500
+ "execution_count": 14,
501
+ "id": "ad3193fb-3def-42a8-968e-c63f2b864ca8",
502
+ "metadata": {
503
+ "tags": []
504
+ },
505
+ "outputs": [],
506
+ "source": [
507
+ "async def request(document, semaphore):\n",
508
+ " # Semaphore guard\n",
509
+ " async with semaphore:\n",
510
+ " result = await endpoint.async_client.post(json={\"inputs\": document['content'], 'truncate': True}, task=\"feature-extraction\")\n",
511
+ " result = np.array(json.loads(result.decode()))\n",
512
+ " document['embedding'] = result[0] # Assuming the API's output can be directly assigned\n",
513
+ " return document\n",
514
+ "\n",
515
+ "async def main(documents):\n",
516
+ " # Semaphore to limit concurrent requests. Adjust the number as needed.\n",
517
+ " semaphore = asyncio.BoundedSemaphore(MAX_WORKERS)\n",
518
+ "\n",
519
+ " # Creating a list of tasks\n",
520
+ " tasks = [request(document, semaphore) for document in documents]\n",
521
+ " \n",
522
+ " # Using tqdm to show progress. It's been integrated into the async loop.\n",
523
+ " for f in tqdm(asyncio.as_completed(tasks), total=len(documents)):\n",
524
+ " await f"
525
+ ]
526
+ },
527
+ {
528
+ "cell_type": "code",
529
+ "execution_count": 15,
530
+ "id": "ec4983af-65eb-4841-808a-3738fb4d682d",
531
+ "metadata": {
532
+ "tags": []
533
+ },
534
+ "outputs": [
535
+ {
536
+ "data": {
537
+ "application/vnd.jupyter.widget-view+json": {
538
+ "model_id": "48a2affdee8d46f3b0c1f691eaac4b89",
539
+ "version_major": 2,
540
+ "version_minor": 0
541
+ },
542
+ "text/plain": [
543
+ " 0%| | 0/100 [00:00<?, ?it/s]"
544
+ ]
545
+ },
546
+ "metadata": {},
547
+ "output_type": "display_data"
548
+ },
549
+ {
550
+ "name": "stdout",
551
+ "output_type": "stream",
552
+ "text": [
553
+ "Embeddings = 100 documents = 100\n",
554
+ "0 min 21.33 sec\n"
555
+ ]
556
+ }
557
+ ],
558
+ "source": [
559
+ "start = time.perf_counter()\n",
560
+ "\n",
561
+ "# Get embeddings\n",
562
+ "await main(documents)\n",
563
+ "\n",
564
+ "# Make sure we got it all\n",
565
+ "count = 0\n",
566
+ "for document in documents:\n",
567
+ " if 'embedding' in document.keys() and len(document['embedding']) == 768:\n",
568
+ " count += 1\n",
569
+ "print(f'Embeddings = {count} documents = {len(documents)}')\n",
570
+ "\n",
571
+ " \n",
572
+ "# Print elapsed time\n",
573
+ "elapsed_time = time.perf_counter() - start\n",
574
+ "minutes, seconds = divmod(elapsed_time, 60)\n",
575
+ "print(f\"{int(minutes)} min {seconds:.2f} sec\")"
576
+ ]
577
+ },
578
+ {
579
+ "cell_type": "markdown",
580
+ "id": "bab97c7b-7bac-4bf5-9752-b528294dadc7",
581
+ "metadata": {},
582
+ "source": [
583
+ "## Pause Inference Endpoint\n",
584
+ "Now that we have finished, let's pause the endpoint so we don't incur any extra charges, this will also allow us to analyze the cost."
585
+ ]
586
+ },
587
+ {
588
+ "cell_type": "code",
589
+ "execution_count": 16,
590
+ "id": "540a0978-7670-4ce3-95c1-3823cc113b85",
591
+ "metadata": {
592
+ "tags": []
593
+ },
594
+ "outputs": [
595
+ {
596
+ "name": "stdout",
597
+ "output_type": "stream",
598
+ "text": [
599
+ "Endpoint Status: paused\n"
600
+ ]
601
+ }
602
+ ],
603
+ "source": [
604
+ "endpoint = endpoint.pause()\n",
605
+ "\n",
606
+ "print(f\"Endpoint Status: {endpoint.status}\")"
607
+ ]
608
+ },
609
+ {
610
+ "cell_type": "markdown",
611
+ "id": "45ad65b7-3da2-4113-9b95-8fb4e21ae793",
612
+ "metadata": {},
613
+ "source": [
614
+ "# Push updated dataset to Hub\n",
615
+ "We now have our documents updated with the embeddings we wanted. First we need to convert it back to a `Dataset` format. I find it easiest to go from list of dicts -> `pd.DataFrame` -> `Dataset`"
616
+ ]
617
+ },
618
+ {
619
+ "cell_type": "code",
620
+ "execution_count": 17,
621
+ "id": "9bb993f8-d624-4192-9626-8e9ed9888a1b",
622
+ "metadata": {
623
+ "tags": []
624
+ },
625
+ "outputs": [],
626
+ "source": [
627
+ "df = pd.DataFrame(documents)\n",
628
+ "dd = DatasetDict({'train': Dataset.from_pandas(df)})"
629
+ ]
630
+ },
631
+ {
632
+ "cell_type": "markdown",
633
+ "id": "129760c8-cae1-4b1e-8216-f5152df8c536",
634
+ "metadata": {},
635
+ "source": [
636
+ "I'm uploading it to the user's account by default (as opposed to uploading to an organization) but feel free to push to wherever you want by setting the user in the `repo_id` or in the config by setting `DATASET_OUT`"
637
+ ]
638
+ },
639
+ {
640
+ "cell_type": "code",
641
+ "execution_count": 18,
642
+ "id": "f48e7c55-d5b7-4ed6-8516-272ae38716b1",
643
+ "metadata": {
644
+ "tags": []
645
+ },
646
+ "outputs": [
647
+ {
648
+ "data": {
649
+ "application/vnd.jupyter.widget-view+json": {
650
+ "model_id": "d3af2e864770481db5adc3968500b5d3",
651
+ "version_major": 2,
652
+ "version_minor": 0
653
+ },
654
+ "text/plain": [
655
+ "Pushing dataset shards to the dataset hub: 0%| | 0/1 [00:00<?, ?it/s]"
656
+ ]
657
+ },
658
+ "metadata": {},
659
+ "output_type": "display_data"
660
+ },
661
+ {
662
+ "data": {
663
+ "application/vnd.jupyter.widget-view+json": {
664
+ "model_id": "4e063c42d8f4490c939bc64e626b507a",
665
+ "version_major": 2,
666
+ "version_minor": 0
667
+ },
668
+ "text/plain": [
669
+ "Downloading metadata: 0%| | 0.00/823 [00:00<?, ?B/s]"
670
+ ]
671
+ },
672
+ "metadata": {},
673
+ "output_type": "display_data"
674
+ }
675
+ ],
676
+ "source": [
677
+ "dd.push_to_hub(repo_id=DATASET_OUT)"
678
+ ]
679
+ },
680
+ {
681
+ "cell_type": "code",
682
+ "execution_count": 19,
683
+ "id": "85ea2244-a4c6-4f04-b187-965a2fc356a8",
684
+ "metadata": {
685
+ "tags": []
686
+ },
687
+ "outputs": [
688
+ {
689
+ "name": "stdout",
690
+ "output_type": "stream",
691
+ "text": [
692
+ "Dataset is at https://huggingface.co/datasets/derek-thomas/processed-subset-bestofredditorupdates\n"
693
+ ]
694
+ }
695
+ ],
696
+ "source": [
697
+ "print(f'Dataset is at https://huggingface.co/datasets/{who[\"name\"]}/{DATASET_OUT}')"
698
+ ]
699
+ },
700
+ {
701
+ "cell_type": "markdown",
702
+ "id": "41abea64-379d-49de-8d9a-355c2f4ce1ac",
703
+ "metadata": {},
704
+ "source": [
705
+ "# Analyze Usage\n",
706
+ "1. Go to your `dashboard_url` printed below\n",
707
+ "1. Click on the Usage & Cost tab\n",
708
+ "1. See how much you have spent"
709
+ ]
710
+ },
711
+ {
712
+ "cell_type": "code",
713
+ "execution_count": 20,
714
+ "id": "16815445-3079-43da-b14e-b54176a07a62",
715
+ "metadata": {},
716
+ "outputs": [
717
+ {
718
+ "name": "stdout",
719
+ "output_type": "stream",
720
+ "text": [
721
+ "https://ui.endpoints.huggingface.co/HF-test-lab/endpoints/boru-jina-embeddings-demo-ie\n"
722
+ ]
723
+ }
724
+ ],
725
+ "source": [
726
+ "dashboard_url = f'https://ui.endpoints.huggingface.co/{namespace}/endpoints/{ENDPOINT_NAME}'\n",
727
+ "print(dashboard_url)"
728
+ ]
729
+ },
730
+ {
731
+ "cell_type": "code",
732
+ "execution_count": 21,
733
+ "id": "81096c6f-d12f-4781-84ec-9066cfa465b3",
734
+ "metadata": {},
735
+ "outputs": [
736
+ {
737
+ "name": "stdout",
738
+ "output_type": "stream",
739
+ "text": [
740
+ "Hit enter to continue with the notebook \n"
741
+ ]
742
+ },
743
+ {
744
+ "data": {
745
+ "text/plain": [
746
+ "''"
747
+ ]
748
+ },
749
+ "execution_count": 21,
750
+ "metadata": {},
751
+ "output_type": "execute_result"
752
+ }
753
+ ],
754
+ "source": [
755
+ "input(\"Hit enter to continue with the notebook\")"
756
+ ]
757
+ },
758
+ {
759
+ "cell_type": "markdown",
760
+ "id": "847d524e-9aa6-4a6f-a275-8a552e289818",
761
+ "metadata": {},
762
+ "source": [
763
+ "We can see that it only took `$0.04` to pay for this!\n"
764
+ ]
765
+ },
766
+ {
767
+ "cell_type": "markdown",
768
+ "id": "b953d5be-2494-4ff8-be42-9daf00c99c41",
769
+ "metadata": {},
770
+ "source": [
771
+ "\n",
772
+ "# Delete Endpoint\n",
773
+ "Now that we are done, we don't need our endpoint anymore. We can delete our endpoint programmatically. \n",
774
+ "\n",
775
+ "![Cost](https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/automatic_embedding_tei_inference_endpoints.png)"
776
+ ]
777
+ },
778
+ {
779
+ "cell_type": "code",
780
+ "execution_count": 22,
781
+ "id": "c310c0f3-6f12-4d5c-838b-3a4c1f2e54ad",
782
+ "metadata": {
783
+ "tags": []
784
+ },
785
+ "outputs": [
786
+ {
787
+ "name": "stdout",
788
+ "output_type": "stream",
789
+ "text": [
790
+ "Endpoint deleted successfully\n"
791
+ ]
792
+ }
793
+ ],
794
+ "source": [
795
+ "endpoint = endpoint.delete()\n",
796
+ "\n",
797
+ "if not endpoint:\n",
798
+ " print('Endpoint deleted successfully')\n",
799
+ "else:\n",
800
+ " print('Delete Endpoint in manually') "
801
+ ]
802
+ }
803
+ ],
804
+ "metadata": {
805
+ "kernelspec": {
806
+ "display_name": "Python 3 (ipykernel)",
807
+ "language": "python",
808
+ "name": "python3"
809
+ },
810
+ "language_info": {
811
+ "codemirror_mode": {
812
+ "name": "ipython",
813
+ "version": 3
814
+ },
815
+ "file_extension": ".py",
816
+ "mimetype": "text/x-python",
817
+ "name": "python",
818
+ "nbconvert_exporter": "python",
819
+ "pygments_lexer": "ipython3",
820
+ "version": "3.10.8"
821
+ }
822
+ },
823
+ "nbformat": 4,
824
+ "nbformat_minor": 5
825
+ }
src/notebooks/faiss.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
src/notebooks/rag_evaluation.ipynb ADDED
@@ -0,0 +1,1470 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {
6
+ "id": "4YErqpfH9jVI"
7
+ },
8
+ "source": [
9
+ "---\n",
10
+ "title: RAG Evaluation\n",
11
+ "---\n",
12
+ "_Authored by: [Aymeric Roucher](https://huggingface.co/m-ric)_\n",
13
+ "\n",
14
+ "This notebook demonstrates how you can evaluate your RAG (Retrieval Augmented Generation), by building a synthetic evaluation dataset and using LLM-as-a-judge to compute the accuracy of your system.\n",
15
+ "\n",
16
+ "For an introduction to RAG, you can check [this other cookbook](rag_zephyr_langchain)!\n",
17
+ "\n",
18
+ "RAG systems are complex: here a RAG diagram, where we noted in blue all possibilities for system enhancement:\n",
19
+ "\n",
20
+ "<img src=\"https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/RAG_workflow.png\" height=\"700\">\n",
21
+ "\n",
22
+ "Implementing any of these improvements can bring a huge performance boost; but changing anything is useless if you cannot monitor the impact of your changes on the system's performance!\n",
23
+ "So let's see how to evaluate our RAG system.\n",
24
+ "\n",
25
+ "### Evaluating RAG performance\n",
26
+ "\n",
27
+ "Since there are so many moving parts to tune with a big impact on performance, benchmarking the RAG system is crucial.\n",
28
+ "\n",
29
+ "For our evaluation pipeline, we will need:\n",
30
+ "1. An evaluation dataset with question - answer couples (QA couples)\n",
31
+ "2. An evaluator to compute the accuracy of our system on the above evaluation dataset.\n",
32
+ "\n",
33
+ "➡️ It turns out, we can use LLMs to help us all along the way!\n",
34
+ "1. The evaluation dataset will be synthetically generated by an LLM 🤖, and questions will be filtered out by other LLMs 🤖\n",
35
+ "2. An [LLM-as-a-judge](https://huggingface.co/papers/2306.05685) agent 🤖 will then perform the evaluation on this synthetic dataset.\n",
36
+ "\n",
37
+ "__Let's dig into it and start building our evaluation pipeline!__ First, we install the required model dependancies."
38
+ ]
39
+ },
40
+ {
41
+ "cell_type": "code",
42
+ "execution_count": null,
43
+ "metadata": {
44
+ "id": "bCKBvOcp9jVK"
45
+ },
46
+ "outputs": [],
47
+ "source": [
48
+ "!pip install -q torch transformers transformers langchain sentence-transformers faiss-gpu openpyxl openai"
49
+ ]
50
+ },
51
+ {
52
+ "cell_type": "code",
53
+ "execution_count": null,
54
+ "metadata": {
55
+ "id": "k_lJFbYm9jVL"
56
+ },
57
+ "outputs": [],
58
+ "source": [
59
+ "%reload_ext autoreload\n",
60
+ "%autoreload 2\n",
61
+ "%reload_ext dotenv\n",
62
+ "%dotenv"
63
+ ]
64
+ },
65
+ {
66
+ "cell_type": "code",
67
+ "execution_count": null,
68
+ "metadata": {
69
+ "id": "oIlNZ1Mn9jVL"
70
+ },
71
+ "outputs": [],
72
+ "source": [
73
+ "from tqdm.notebook import tqdm\n",
74
+ "import pandas as pd\n",
75
+ "from typing import Optional, List, Tuple\n",
76
+ "from langchain_core.language_models import BaseChatModel\n",
77
+ "import json\n",
78
+ "import datasets\n",
79
+ "\n",
80
+ "pd.set_option(\"display.max_colwidth\", None)"
81
+ ]
82
+ },
83
+ {
84
+ "cell_type": "markdown",
85
+ "metadata": {
86
+ "id": "zeW8P62J9jVM"
87
+ },
88
+ "source": [
89
+ "### Load your knowledge base"
90
+ ]
91
+ },
92
+ {
93
+ "cell_type": "code",
94
+ "execution_count": null,
95
+ "metadata": {
96
+ "id": "YRbm5tNF9jVM"
97
+ },
98
+ "outputs": [],
99
+ "source": [
100
+ "ds = datasets.load_dataset(\"m-ric/huggingface_doc\", split=\"train\")"
101
+ ]
102
+ },
103
+ {
104
+ "cell_type": "markdown",
105
+ "metadata": {
106
+ "id": "wy9CKj0M9jVM"
107
+ },
108
+ "source": [
109
+ "# 1. Build a synthetic dataset for evaluation\n",
110
+ "We first build a synthetic dataset of questions and associated contexts. The method is to get elements from our knowledge base, and ask an LLM to generate questions based on these documents.\n",
111
+ "\n",
112
+ "Then we setup other LLM agents to act as quality filters for the generated QA couples: each of them will act as the filter for a specific flaw."
113
+ ]
114
+ },
115
+ {
116
+ "cell_type": "markdown",
117
+ "metadata": {
118
+ "id": "QkoEgiDg9jVM"
119
+ },
120
+ "source": [
121
+ "### 1.1. Prepare source documents"
122
+ ]
123
+ },
124
+ {
125
+ "cell_type": "code",
126
+ "execution_count": null,
127
+ "metadata": {
128
+ "id": "3gTOlRKO9jVM"
129
+ },
130
+ "outputs": [],
131
+ "source": [
132
+ "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
133
+ "from langchain.docstore.document import Document as LangchainDocument\n",
134
+ "\n",
135
+ "langchain_docs = [\n",
136
+ " LangchainDocument(page_content=doc[\"text\"], metadata={\"source\": doc[\"source\"]})\n",
137
+ " for doc in tqdm(ds)\n",
138
+ "]\n",
139
+ "\n",
140
+ "\n",
141
+ "text_splitter = RecursiveCharacterTextSplitter(\n",
142
+ " chunk_size=2000,\n",
143
+ " chunk_overlap=200,\n",
144
+ " add_start_index=True,\n",
145
+ " separators=[\"\\n\\n\", \"\\n\", \".\", \" \", \"\"],\n",
146
+ ")\n",
147
+ "\n",
148
+ "docs_processed = []\n",
149
+ "for doc in langchain_docs:\n",
150
+ " docs_processed += text_splitter.split_documents([doc])"
151
+ ]
152
+ },
153
+ {
154
+ "cell_type": "markdown",
155
+ "metadata": {
156
+ "id": "WjrNhcCh9jVN"
157
+ },
158
+ "source": [
159
+ "### 1.2. Setup agents for question generation\n",
160
+ "\n",
161
+ "We use [Mixtral](https://huggingface.co/mistralai/Mixtral-8x7B-Instruct-v0.1) for QA couple generation because it it has excellent performance in leaderboards such as [Chatbot Arena](https://huggingface.co/spaces/lmsys/chatbot-arena-leaderboard)."
162
+ ]
163
+ },
164
+ {
165
+ "cell_type": "code",
166
+ "execution_count": null,
167
+ "metadata": {
168
+ "id": "GoRySj3Q9jVN"
169
+ },
170
+ "outputs": [],
171
+ "source": [
172
+ "from langchain_community.llms import HuggingFaceHub\n",
173
+ "\n",
174
+ "repo_id = \"mistralai/Mixtral-8x7B-Instruct-v0.1\"\n",
175
+ "\n",
176
+ "llm = HuggingFaceHub(\n",
177
+ " repo_id=repo_id,\n",
178
+ " task=\"text-generation\",\n",
179
+ " model_kwargs={\n",
180
+ " \"max_new_tokens\": 512,\n",
181
+ " \"top_k\": 30,\n",
182
+ " \"temperature\": 0.1,\n",
183
+ " \"repetition_penalty\": 1.03,\n",
184
+ " },\n",
185
+ ")"
186
+ ]
187
+ },
188
+ {
189
+ "cell_type": "code",
190
+ "execution_count": null,
191
+ "metadata": {
192
+ "id": "wubTNTaV9jVN"
193
+ },
194
+ "outputs": [],
195
+ "source": [
196
+ "from langchain_community.chat_models import ChatHuggingFace\n",
197
+ "\n",
198
+ "chat_model = ChatHuggingFace(llm=llm)"
199
+ ]
200
+ },
201
+ {
202
+ "cell_type": "code",
203
+ "execution_count": null,
204
+ "metadata": {
205
+ "id": "hIM_DJRo9jVN"
206
+ },
207
+ "outputs": [],
208
+ "source": [
209
+ "from langchain.prompts import ChatPromptTemplate\n",
210
+ "\n",
211
+ "QA_generation_prompt = \"\"\"\n",
212
+ "Your task is to write a factoid question and an answer given a context.\n",
213
+ "Your factoid question should be answerable with a specific, concise piece of factual information from the context.\n",
214
+ "Your factoid question should be formulated in the same style as questions users could ask in a search engine.\n",
215
+ "This means that your factoid question MUST NOT mention something like \"according to the passage\" or \"context\".\n",
216
+ "\n",
217
+ "Provide your answer as follows:\n",
218
+ "\n",
219
+ "Output:::\n",
220
+ "Factoid question: (your factoid question)\n",
221
+ "Answer: (your answer to the factoid question)\n",
222
+ "\n",
223
+ "Now here is the context.\n",
224
+ "\n",
225
+ "Context: {context}\\n\n",
226
+ "Output:::\"\"\"\n",
227
+ "\n",
228
+ "QA_generation_prompt = ChatPromptTemplate.from_template(QA_generation_prompt)\n",
229
+ "QA_generation_agent = QA_generation_prompt | chat_model"
230
+ ]
231
+ },
232
+ {
233
+ "cell_type": "markdown",
234
+ "metadata": {
235
+ "id": "lVFc-lVy9jVN"
236
+ },
237
+ "source": [
238
+ "Now let's generate our QA couples.\n",
239
+ "For this example, we generate only 10 QA couples and will load the rest from the Hub.\n",
240
+ "\n",
241
+ "But for your specific knowledge base, given that you want to get at least ~100 test samples, and accounting for the fact that we will filter out around half of these with our critique agents later on, you should generate much more, in the >200 samples."
242
+ ]
243
+ },
244
+ {
245
+ "cell_type": "code",
246
+ "execution_count": null,
247
+ "metadata": {
248
+ "id": "8fteqDDD9jVN"
249
+ },
250
+ "outputs": [],
251
+ "source": [
252
+ "import random\n",
253
+ "\n",
254
+ "N_GENERATIONS = (\n",
255
+ " 10 # We intentionally generate only 10 QA couples here for cost and time considerations\n",
256
+ ")\n",
257
+ "\n",
258
+ "print(f\"Generating {N_GENERATIONS} QA couples...\")\n",
259
+ "outputs = []\n",
260
+ "for context in tqdm(random.sample(langchain_docs, N_GENERATIONS)):\n",
261
+ " # Generate QA couple\n",
262
+ " output_QA_couple = QA_generation_agent.invoke({\"context\": context.page_content}).content\n",
263
+ " try:\n",
264
+ " question = output_QA_couple.split(\"Factoid question: \")[1].split(\"Answer: \")[0]\n",
265
+ " answer = output_QA_couple.split(\"Answer: \")[1]\n",
266
+ " outputs.append(\n",
267
+ " {\n",
268
+ " \"context\": context.page_content,\n",
269
+ " \"question\": question,\n",
270
+ " \"answer\": answer,\n",
271
+ " \"source_doc\": context.metadata[\"source\"],\n",
272
+ " }\n",
273
+ " )\n",
274
+ " except:\n",
275
+ " continue"
276
+ ]
277
+ },
278
+ {
279
+ "cell_type": "code",
280
+ "execution_count": null,
281
+ "metadata": {
282
+ "id": "aUlOUDv59jVN",
283
+ "outputId": "c9634fdb-2a7f-43a6-c4eb-e60b166b8238"
284
+ },
285
+ "outputs": [
286
+ {
287
+ "data": {
288
+ "text/html": [
289
+ "<div>\n",
290
+ "<style scoped>\n",
291
+ " .dataframe tbody tr th:only-of-type {\n",
292
+ " vertical-align: middle;\n",
293
+ " }\n",
294
+ "\n",
295
+ " .dataframe tbody tr th {\n",
296
+ " vertical-align: top;\n",
297
+ " }\n",
298
+ "\n",
299
+ " .dataframe thead th {\n",
300
+ " text-align: right;\n",
301
+ " }\n",
302
+ "</style>\n",
303
+ "<table border=\"1\" class=\"dataframe\">\n",
304
+ " <thead>\n",
305
+ " <tr style=\"text-align: right;\">\n",
306
+ " <th></th>\n",
307
+ " <th>context</th>\n",
308
+ " <th>question</th>\n",
309
+ " <th>answer</th>\n",
310
+ " <th>source_doc</th>\n",
311
+ " </tr>\n",
312
+ " </thead>\n",
313
+ " <tbody>\n",
314
+ " <tr>\n",
315
+ " <th>0</th>\n",
316
+ " <td>!--Copyright 2023 The HuggingFace Team. All rights reserved.\\n\\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with\\nthe License. You may obtain a copy of the License at\\n\\nhttp://www.apache.org/licenses/LICENSE-2.0\\n\\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on\\nan \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the\\nspecific language governing permissions and limitations under the License.\\n--&gt;\\n\\n# Schedulers\\n\\n🤗 Diffusers provides many scheduler functions for the diffusion process. A scheduler takes a model's output (the sample which the diffusion process is iterating on) and a timestep to return a denoised sample. The timestep is important because it dictates where in the diffusion process the step is; data is generated by iterating forward *n* timesteps and inference occurs by propagating backward through the timesteps. Based on the timestep, a scheduler may be *discrete* in which case the timestep is an `int` or *continuous* in which case the timestep is a `float`.\\n\\nDepending on the context, a scheduler defines how to iteratively add noise to an image or how to update a sample based on a model's output:\\n\\n- during *training*, a scheduler adds noise (there are different algorithms for how to add noise) to a sample to train a diffusion model\\n- during *inference*, a scheduler defines how to update a sample based on a pretrained model's output\\n\\nMany schedulers are implemented from the [k-diffusion](https://github.com/crowsonkb/k-diffusion) library by [Katherine Crowson](https://github.com/crowsonkb/), and they're also widely used in A1111. To help you map the schedulers from k-diffusion and A1111 to the schedulers in 🤗 Diffusers, take a look at the table below:\\n\\n| A1111/k-diffusion | 🤗 Diffusers | Usage |\\n|---------------------|-------------------------------------|---------------------------------------------------------------------------------------------------------------|\\n| DPM++ 2M | [`DPMSolverMultistepScheduler`] | |\\n| DPM++ 2M Karras | [`DPMSolverMultistepScheduler`] | init with `use_karras_sigmas=True` |\\n| DPM++ 2M SDE | [`DPMSolverMultistepScheduler`] | init with `algorithm_type=\"sde-dpmsolver++\"` |\\n| DPM++ 2M SDE Karras | [`DPMSolverMultistepScheduler`] | init with `use_karras_sigmas=True` and `algorithm_type=\"sde-dpmsolver++\"` |\\n| DPM++ 2S a | N/A | very similar to `DPMSolverSinglestepScheduler` |\\n| DPM++ 2S a Karras | N/A | very similar to `DPMSolverSinglestepScheduler(use_karras_sigmas=True, ...)` |\\n| DPM++ SDE | [`DPMSolverSinglestepScheduler`] | |\\n| DPM++ SDE Karras | [`DPMSolverSinglestepScheduler`] | init with `use_karras_sigmas=True` |\\n| DPM2 | [`KDPM2DiscreteScheduler`] | |\\n| DPM2 Karras | [`KDPM2DiscreteScheduler`] | init with `use_karras_sigmas=True` |\\n| DPM2 a | [`KDPM2AncestralDiscreteScheduler`] | |\\n| DPM2 a Karras | [`KDPM2AncestralDiscreteScheduler`] | init with `use_karras_sigmas=True` |\\n| DPM adaptive | N/A | |\\n| DPM fast | N/A | |\\n| Euler | [`EulerDiscreteScheduler`] | |\\n| Euler a | [`EulerAncestralDiscreteScheduler`] | |\\n| Heun | [`HeunDiscreteScheduler`] | |\\n| LMS | [`LMSDiscreteScheduler`] | |\\n| LMS Karras | [`LMSDiscreteScheduler`] | init with `use_karras_sigmas=True` |\\n| N/A | [`DEISMultistepScheduler`] | |\\n| N/A | [`UniPCMultistepScheduler`] | |\\n\\nAll schedulers are built from the base [`SchedulerMixin`] class which implements low level utilities shared by all schedulers.\\n\\n## SchedulerMixin\\n[[autodoc]] SchedulerMixin\\n\\n## SchedulerOutput\\n[[autodoc]] schedulers.scheduling_utils.SchedulerOutput\\n\\n## KarrasDiffusionSchedulers\\n\\n[`KarrasDiffusionSchedulers`] are a broad generalization of schedulers in 🤗 Diffusers. The schedulers in this class are distinguished at a high level by their noise sampling strategy, the type of network and scaling, the training strategy, and how the loss is weighed.\\n\\nThe different schedulers in this class, depending on the ordinary differential equations (ODE) solver type, fall into the above taxonomy and provide a good abstraction for the design of the main schedulers implemented in 🤗 Diffusers. The schedulers in this class are given [here](https://github.com/huggingface/diffusers/blob/a69754bb879ed55b9b6dc9dd0b3cf4fa4124c765/src/diffusers/schedulers/scheduling_utils.py#L32).\\n\\n## PushToHubMixin\\n\\n[[autodoc]] utils.PushToHubMixin\\n</td>\n",
317
+ " <td>What is the class of schedulers in 🤗 Diffusers that are distinguished by their noise sampling strategy, type of network and scaling, training strategy, and loss weighing?\\n</td>\n",
318
+ " <td>[`KarrasDiffusionSchedulers`]</td>\n",
319
+ " <td>huggingface/diffusers/blob/main/docs/source/en/api/schedulers/overview.md</td>\n",
320
+ " </tr>\n",
321
+ " </tbody>\n",
322
+ "</table>\n",
323
+ "</div>"
324
+ ],
325
+ "text/plain": [
326
+ " context \\\n",
327
+ "0 !--Copyright 2023 The HuggingFace Team. All rights reserved.\\n\\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with\\nthe License. You may obtain a copy of the License at\\n\\nhttp://www.apache.org/licenses/LICENSE-2.0\\n\\nUnless required by applicable law or agreed to in writing, software distributed under the License is distributed on\\nan \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the\\nspecific language governing permissions and limitations under the License.\\n-->\\n\\n# Schedulers\\n\\n🤗 Diffusers provides many scheduler functions for the diffusion process. A scheduler takes a model's output (the sample which the diffusion process is iterating on) and a timestep to return a denoised sample. The timestep is important because it dictates where in the diffusion process the step is; data is generated by iterating forward *n* timesteps and inference occurs by propagating backward through the timesteps. Based on the timestep, a scheduler may be *discrete* in which case the timestep is an `int` or *continuous* in which case the timestep is a `float`.\\n\\nDepending on the context, a scheduler defines how to iteratively add noise to an image or how to update a sample based on a model's output:\\n\\n- during *training*, a scheduler adds noise (there are different algorithms for how to add noise) to a sample to train a diffusion model\\n- during *inference*, a scheduler defines how to update a sample based on a pretrained model's output\\n\\nMany schedulers are implemented from the [k-diffusion](https://github.com/crowsonkb/k-diffusion) library by [Katherine Crowson](https://github.com/crowsonkb/), and they're also widely used in A1111. To help you map the schedulers from k-diffusion and A1111 to the schedulers in 🤗 Diffusers, take a look at the table below:\\n\\n| A1111/k-diffusion | 🤗 Diffusers | Usage |\\n|---------------------|-------------------------------------|---------------------------------------------------------------------------------------------------------------|\\n| DPM++ 2M | [`DPMSolverMultistepScheduler`] | |\\n| DPM++ 2M Karras | [`DPMSolverMultistepScheduler`] | init with `use_karras_sigmas=True` |\\n| DPM++ 2M SDE | [`DPMSolverMultistepScheduler`] | init with `algorithm_type=\"sde-dpmsolver++\"` |\\n| DPM++ 2M SDE Karras | [`DPMSolverMultistepScheduler`] | init with `use_karras_sigmas=True` and `algorithm_type=\"sde-dpmsolver++\"` |\\n| DPM++ 2S a | N/A | very similar to `DPMSolverSinglestepScheduler` |\\n| DPM++ 2S a Karras | N/A | very similar to `DPMSolverSinglestepScheduler(use_karras_sigmas=True, ...)` |\\n| DPM++ SDE | [`DPMSolverSinglestepScheduler`] | |\\n| DPM++ SDE Karras | [`DPMSolverSinglestepScheduler`] | init with `use_karras_sigmas=True` |\\n| DPM2 | [`KDPM2DiscreteScheduler`] | |\\n| DPM2 Karras | [`KDPM2DiscreteScheduler`] | init with `use_karras_sigmas=True` |\\n| DPM2 a | [`KDPM2AncestralDiscreteScheduler`] | |\\n| DPM2 a Karras | [`KDPM2AncestralDiscreteScheduler`] | init with `use_karras_sigmas=True` |\\n| DPM adaptive | N/A | |\\n| DPM fast | N/A | |\\n| Euler | [`EulerDiscreteScheduler`] | |\\n| Euler a | [`EulerAncestralDiscreteScheduler`] | |\\n| Heun | [`HeunDiscreteScheduler`] | |\\n| LMS | [`LMSDiscreteScheduler`] | |\\n| LMS Karras | [`LMSDiscreteScheduler`] | init with `use_karras_sigmas=True` |\\n| N/A | [`DEISMultistepScheduler`] | |\\n| N/A | [`UniPCMultistepScheduler`] | |\\n\\nAll schedulers are built from the base [`SchedulerMixin`] class which implements low level utilities shared by all schedulers.\\n\\n## SchedulerMixin\\n[[autodoc]] SchedulerMixin\\n\\n## SchedulerOutput\\n[[autodoc]] schedulers.scheduling_utils.SchedulerOutput\\n\\n## KarrasDiffusionSchedulers\\n\\n[`KarrasDiffusionSchedulers`] are a broad generalization of schedulers in 🤗 Diffusers. The schedulers in this class are distinguished at a high level by their noise sampling strategy, the type of network and scaling, the training strategy, and how the loss is weighed.\\n\\nThe different schedulers in this class, depending on the ordinary differential equations (ODE) solver type, fall into the above taxonomy and provide a good abstraction for the design of the main schedulers implemented in 🤗 Diffusers. The schedulers in this class are given [here](https://github.com/huggingface/diffusers/blob/a69754bb879ed55b9b6dc9dd0b3cf4fa4124c765/src/diffusers/schedulers/scheduling_utils.py#L32).\\n\\n## PushToHubMixin\\n\\n[[autodoc]] utils.PushToHubMixin\\n \n",
328
+ "\n",
329
+ " question \\\n",
330
+ "0 What is the class of schedulers in 🤗 Diffusers that are distinguished by their noise sampling strategy, type of network and scaling, training strategy, and loss weighing?\\n \n",
331
+ "\n",
332
+ " answer \\\n",
333
+ "0 [`KarrasDiffusionSchedulers`] \n",
334
+ "\n",
335
+ " source_doc \n",
336
+ "0 huggingface/diffusers/blob/main/docs/source/en/api/schedulers/overview.md "
337
+ ]
338
+ },
339
+ "metadata": {},
340
+ "output_type": "display_data"
341
+ }
342
+ ],
343
+ "source": [
344
+ "display(pd.DataFrame(outputs).head(1))"
345
+ ]
346
+ },
347
+ {
348
+ "cell_type": "markdown",
349
+ "metadata": {
350
+ "id": "0KG4dNtg9jVN"
351
+ },
352
+ "source": [
353
+ "### 1.3. Setup critique agents\n",
354
+ "\n",
355
+ "The questions generated by the previous agent can have many flaws: we should do a quality check before validating these questions.\n",
356
+ "\n",
357
+ "We thus build critique agents that will rate each question on several criteria, given in [this paper](https://huggingface.co/papers/2312.10003):\n",
358
+ "- **Groundedness:** can the question be answered from the given context?\n",
359
+ "- **Relevance:** is the question relevant to users? For instance, `\"What is the date when transformers 4.29.1 was released?\"` is not relevant for ML practicioners.\n",
360
+ "\n",
361
+ "One last failure case we've noticed is when a function is tailored for the particular setting where the question was generated, but undecipherable by itself, like `\"What is the name of the function used in this guide?\"`.\n",
362
+ "We also build a critique agent for this criteria:\n",
363
+ "- **Stand-alone**: is the question understandable free of any context, for someone with domain knowledge/Internet access? The opposite of this would be `What is the function used in this article?` for a question generated from a specific blog article.\n",
364
+ "\n",
365
+ "We systematically score functions with all these agents, and whenever the score is too low for any one of the agents, we eliminate the question from our eval dataset.\n",
366
+ "\n",
367
+ "💡 ___When asking the agents to output a score, we first ask them to produce its rationale. This will help us verify scores, but most importantly, asking it to first output rationale gives the model more tokens to think and elaborate an answer before summarizing it into a single score token.___\n",
368
+ "\n",
369
+ "We now build and run these critique agents."
370
+ ]
371
+ },
372
+ {
373
+ "cell_type": "code",
374
+ "execution_count": null,
375
+ "metadata": {
376
+ "id": "05aSgTGs9jVO"
377
+ },
378
+ "outputs": [],
379
+ "source": [
380
+ "question_groundedness_critique_prompt = \"\"\"\n",
381
+ "You will be given a context and a question.\n",
382
+ "Your task is to provide a 'total rating' scoring how well one can answer the given question unambiguously with the given context.\n",
383
+ "Give your answer on a scale of 1 to 5, where 1 means that the question is not answerable at all given the context, and 5 means that the question is clearly and unambiguously answerable with the context.\n",
384
+ "\n",
385
+ "Provide your answer as follows:\n",
386
+ "\n",
387
+ "Answer:::\n",
388
+ "Evaluation: (your rationale for the rating)\n",
389
+ "Total rating: (your rating)\n",
390
+ "\n",
391
+ "Now here are the question and context.\n",
392
+ "\n",
393
+ "Question: {question}\\n\n",
394
+ "Context: {context}\\n\n",
395
+ "Answer::: \"\"\"\n",
396
+ "\n",
397
+ "question_relevance_critique_prompt = \"\"\"\n",
398
+ "You will be given a question.\n",
399
+ "Your task is to provide a 'total rating' representing how useful this question can be to machine learning developers building NLP applications with the Hugging Face ecosystem.\n",
400
+ "Give your answer on a scale of 1 to 5, where 1 means that the question is not useful at all, and 5 means that the question is extremely useful.\n",
401
+ "\n",
402
+ "Provide your answer as follows:\n",
403
+ "\n",
404
+ "Answer:::\n",
405
+ "Evaluation: (your rationale for the rating)\n",
406
+ "Total rating: (your rating)\n",
407
+ "\n",
408
+ "Now here is the question.\n",
409
+ "\n",
410
+ "Question: {question}\\n\n",
411
+ "Answer::: \"\"\"\n",
412
+ "\n",
413
+ "question_standalone_critique_prompt = \"\"\"\n",
414
+ "You will be given a question.\n",
415
+ "Your task is to provide a 'total rating' representing how context-independant this question is.\n",
416
+ "Give your answer on a scale of 1 to 5, where 1 means that the question only makes sense in a specific context, and 5 means that the question makes sense by itself.\n",
417
+ "For instance, if the question refers to a particular setting, like 'in the context' or 'in the document', the rating must be 1.\n",
418
+ "The questions can contain obscure technical nouns or acronyms like Gradio, Hub, Hugging Face or Space and still be a 5: it must simply be clear to an operator with access to documentation what the question is about.\n",
419
+ "\n",
420
+ "Provide your answer as follows:\n",
421
+ "\n",
422
+ "Answer:::\n",
423
+ "Evaluation: (your rationale for the rating)\n",
424
+ "Total rating: (your rating)\n",
425
+ "\n",
426
+ "Now here is the question.\n",
427
+ "\n",
428
+ "Question: {question}\\n\n",
429
+ "Answer::: \"\"\"\n",
430
+ "\n",
431
+ "question_groundedness_critique_prompt = ChatPromptTemplate.from_template(\n",
432
+ " question_groundedness_critique_prompt\n",
433
+ ")\n",
434
+ "question_groundedness_critique_agent = question_groundedness_critique_prompt | chat_model\n",
435
+ "\n",
436
+ "question_relevance_critique_prompt = ChatPromptTemplate.from_template(\n",
437
+ " question_relevance_critique_prompt\n",
438
+ ")\n",
439
+ "question_relevance_critique_agent = question_relevance_critique_prompt | chat_model\n",
440
+ "\n",
441
+ "question_standalone_critique_prompt = ChatPromptTemplate.from_template(\n",
442
+ " question_standalone_critique_prompt\n",
443
+ ")\n",
444
+ "question_standalone_critique_agent = question_standalone_critique_prompt | chat_model"
445
+ ]
446
+ },
447
+ {
448
+ "cell_type": "code",
449
+ "execution_count": null,
450
+ "metadata": {
451
+ "id": "b9tbk7ME9jVO"
452
+ },
453
+ "outputs": [],
454
+ "source": [
455
+ "print(\"Generating critique for each QA couple...\")\n",
456
+ "for output in tqdm(outputs):\n",
457
+ " # Critique the generated QA couple\n",
458
+ " question_groundedness_evaluation = question_groundedness_critique_agent.invoke(\n",
459
+ " {\"context\": output[\"context\"], \"question\": output[\"question\"]}\n",
460
+ " ).content\n",
461
+ " question_relevance_evaluation = question_relevance_critique_agent.invoke(\n",
462
+ " {\"question\": output[\"question\"]}\n",
463
+ " ).content\n",
464
+ " question_standalone_evaluation = question_standalone_critique_agent.invoke(\n",
465
+ " {\"question\": output[\"question\"]}\n",
466
+ " ).content\n",
467
+ "\n",
468
+ " try:\n",
469
+ " groundedness_score = int(question_groundedness_evaluation.split(\"Total rating: \")[1][0])\n",
470
+ " groundedness_eval = question_groundedness_evaluation.split(\"Total rating: \")[0].split(\n",
471
+ " \"Evaluation: \"\n",
472
+ " )[1]\n",
473
+ " relevance_score = int(question_relevance_evaluation.split(\"Total rating: \")[1][0])\n",
474
+ " relevance_eval = question_relevance_evaluation.split(\"Total rating: \")[0].split(\n",
475
+ " \"Evaluation: \"\n",
476
+ " )[1]\n",
477
+ " standalone_score = int(question_standalone_evaluation.split(\"Total rating: \")[1][0])\n",
478
+ " standalone_eval = question_standalone_evaluation.split(\"Total rating: \")[0].split(\n",
479
+ " \"Evaluation: \"\n",
480
+ " )[1]\n",
481
+ " output.update(\n",
482
+ " {\n",
483
+ " \"groundedness_score\": groundedness_score,\n",
484
+ " \"groundedness_eval\": groundedness_eval,\n",
485
+ " \"relevance_score\": relevance_score,\n",
486
+ " \"relevance_eval\": relevance_eval,\n",
487
+ " \"standalone_score\": standalone_score,\n",
488
+ " \"standalone_eval\": standalone_eval,\n",
489
+ " }\n",
490
+ " )\n",
491
+ " except:\n",
492
+ " continue"
493
+ ]
494
+ },
495
+ {
496
+ "cell_type": "markdown",
497
+ "metadata": {
498
+ "id": "IQv36Y_f9jVO"
499
+ },
500
+ "source": [
501
+ "Now let us filter out bad questions based on our critique agent scores:"
502
+ ]
503
+ },
504
+ {
505
+ "cell_type": "code",
506
+ "execution_count": null,
507
+ "metadata": {
508
+ "id": "oBWuOu1b9jVO",
509
+ "outputId": "b32bacea-52f8-486a-96fe-5c188605c5a2"
510
+ },
511
+ "outputs": [
512
+ {
513
+ "name": "stdout",
514
+ "output_type": "stream",
515
+ "text": [
516
+ "Evaluation dataset before filtering:\n"
517
+ ]
518
+ },
519
+ {
520
+ "data": {
521
+ "text/html": [
522
+ "<div>\n",
523
+ "<style scoped>\n",
524
+ " .dataframe tbody tr th:only-of-type {\n",
525
+ " vertical-align: middle;\n",
526
+ " }\n",
527
+ "\n",
528
+ " .dataframe tbody tr th {\n",
529
+ " vertical-align: top;\n",
530
+ " }\n",
531
+ "\n",
532
+ " .dataframe thead th {\n",
533
+ " text-align: right;\n",
534
+ " }\n",
535
+ "</style>\n",
536
+ "<table border=\"1\" class=\"dataframe\">\n",
537
+ " <thead>\n",
538
+ " <tr style=\"text-align: right;\">\n",
539
+ " <th></th>\n",
540
+ " <th>question</th>\n",
541
+ " <th>answer</th>\n",
542
+ " <th>groundedness_score</th>\n",
543
+ " <th>relevance_score</th>\n",
544
+ " <th>standalone_score</th>\n",
545
+ " </tr>\n",
546
+ " </thead>\n",
547
+ " <tbody>\n",
548
+ " <tr>\n",
549
+ " <th>0</th>\n",
550
+ " <td>What is the class of schedulers in 🤗 Diffusers that are distinguished by their noise sampling strategy, type of network and scaling, training strategy, and loss weighing?\\n</td>\n",
551
+ " <td>[`KarrasDiffusionSchedulers`]</td>\n",
552
+ " <td>3.0</td>\n",
553
+ " <td>1.0</td>\n",
554
+ " <td>4.0</td>\n",
555
+ " </tr>\n",
556
+ " <tr>\n",
557
+ " <th>1</th>\n",
558
+ " <td>What are some utility functions provided by the Hugging Face library for pipelines?\\n</td>\n",
559
+ " <td>The Hugging Face library provides several utility functions for pipelines, including `ArgumentHandler`, `ZeroShotClassificationArgumentHandler`, `QuestionAnsweringArgumentHandler` for argument handling, `PipelineDataFormat`, `CsvPipelineDataFormat`, `JsonPipelineDataFormat`, `PipedPipelineDataFormat` for data format, and `PipelineException` for exceptions.</td>\n",
560
+ " <td>5.0</td>\n",
561
+ " <td>4.0</td>\n",
562
+ " <td>5.0</td>\n",
563
+ " </tr>\n",
564
+ " <tr>\n",
565
+ " <th>2</th>\n",
566
+ " <td>What is the default name used in the Gradio demo if no name is provided?\\n</td>\n",
567
+ " <td>User\\n\\nExplanation: The factoid question asks for the default name used in the Gradio demo if no name is provided. The answer to this question can be found in the `argparse.ArgumentParser()` function, where a default value of \"User\" is set for the `--name` argument.</td>\n",
568
+ " <td>5.0</td>\n",
569
+ " <td>3.0</td>\n",
570
+ " <td>5.0</td>\n",
571
+ " </tr>\n",
572
+ " <tr>\n",
573
+ " <th>3</th>\n",
574
+ " <td>What is the function used to load a pre-trained Resnet-18 model in the provided context?\\n</td>\n",
575
+ " <td>The function used to load a pre-trained Resnet-18 model in the provided context is `torch.hub.load('pytorch/vision:v0.6.0', 'resnet18', pretrained=True).eval()`.</td>\n",
576
+ " <td>NaN</td>\n",
577
+ " <td>NaN</td>\n",
578
+ " <td>NaN</td>\n",
579
+ " </tr>\n",
580
+ " <tr>\n",
581
+ " <th>4</th>\n",
582
+ " <td>What is the name of the component used for creating a button in the given code?\\n</td>\n",
583
+ " <td>The name of the component used for creating a button in the given code is `BaseButton`.</td>\n",
584
+ " <td>5.0</td>\n",
585
+ " <td>1.0</td>\n",
586
+ " <td>5.0</td>\n",
587
+ " </tr>\n",
588
+ " <tr>\n",
589
+ " <th>5</th>\n",
590
+ " <td>What is the command to get the example ONNX file for Bart model?\\n</td>\n",
591
+ " <td>The command is `python run_onnx_exporter.py --model_name_or_path facebook/bart-base`.</td>\n",
592
+ " <td>NaN</td>\n",
593
+ " <td>NaN</td>\n",
594
+ " <td>NaN</td>\n",
595
+ " </tr>\n",
596
+ " <tr>\n",
597
+ " <th>6</th>\n",
598
+ " <td>What will be covered in the next unit of the course?\\n</td>\n",
599
+ " <td>The next unit of the course will cover learning more about Unity MLAgents and training agents in Unity environments. It will also prepare students for AI vs AI challenges where they will train their agents to compete against other agents in a snowball fight and a soccer game.</td>\n",
600
+ " <td>5.0</td>\n",
601
+ " <td>1.0</td>\n",
602
+ " <td>5.0</td>\n",
603
+ " </tr>\n",
604
+ " <tr>\n",
605
+ " <th>7</th>\n",
606
+ " <td>What is the purpose of the `negative_original_size`, `negative_crops_coords_top_left`, and `negative_target_size` parameters in SDXL?\\n</td>\n",
607
+ " <td>These parameters allow SDXL to negatively condition the model on image resolution and cropping parameters.</td>\n",
608
+ " <td>2.0</td>\n",
609
+ " <td>4.0</td>\n",
610
+ " <td>2.0</td>\n",
611
+ " </tr>\n",
612
+ " <tr>\n",
613
+ " <th>8</th>\n",
614
+ " <td>How are transformers models tested in the Hugging Face repository?\\n</td>\n",
615
+ " <td>Transformers models are tested in the Hugging Face repository using two test suites: `tests` for the general API and `examples` for various applications that aren't part of the API. These tests are run on CircleCI and GitHub Actions, with different jobs and configurations for each. The tests can be run in various ways, including running all tests, getting the list of all tests, running a specific test module, and running specific tests by name or keyword expression. Additionally, there are options for running tests in parallel, repeating tests, and running tests on a specific GPU or CPU.</td>\n",
616
+ " <td>3.0</td>\n",
617
+ " <td>4.0</td>\n",
618
+ " <td>4.0</td>\n",
619
+ " </tr>\n",
620
+ " <tr>\n",
621
+ " <th>9</th>\n",
622
+ " <td>What command is used to create a virtual environment in the given context?\\n</td>\n",
623
+ " <td>The command used to create a virtual environment in the given context is `python -m venv &lt;env_name&gt;`.</td>\n",
624
+ " <td>NaN</td>\n",
625
+ " <td>NaN</td>\n",
626
+ " <td>NaN</td>\n",
627
+ " </tr>\n",
628
+ " </tbody>\n",
629
+ "</table>\n",
630
+ "</div>"
631
+ ],
632
+ "text/plain": [
633
+ " question \\\n",
634
+ "0 What is the class of schedulers in 🤗 Diffusers that are distinguished by their noise sampling strategy, type of network and scaling, training strategy, and loss weighing?\\n \n",
635
+ "1 What are some utility functions provided by the Hugging Face library for pipelines?\\n \n",
636
+ "2 What is the default name used in the Gradio demo if no name is provided?\\n \n",
637
+ "3 What is the function used to load a pre-trained Resnet-18 model in the provided context?\\n \n",
638
+ "4 What is the name of the component used for creating a button in the given code?\\n \n",
639
+ "5 What is the command to get the example ONNX file for Bart model?\\n \n",
640
+ "6 What will be covered in the next unit of the course?\\n \n",
641
+ "7 What is the purpose of the `negative_original_size`, `negative_crops_coords_top_left`, and `negative_target_size` parameters in SDXL?\\n \n",
642
+ "8 How are transformers models tested in the Hugging Face repository?\\n \n",
643
+ "9 What command is used to create a virtual environment in the given context?\\n \n",
644
+ "\n",
645
+ " answer \\\n",
646
+ "0 [`KarrasDiffusionSchedulers`] \n",
647
+ "1 The Hugging Face library provides several utility functions for pipelines, including `ArgumentHandler`, `ZeroShotClassificationArgumentHandler`, `QuestionAnsweringArgumentHandler` for argument handling, `PipelineDataFormat`, `CsvPipelineDataFormat`, `JsonPipelineDataFormat`, `PipedPipelineDataFormat` for data format, and `PipelineException` for exceptions. \n",
648
+ "2 User\\n\\nExplanation: The factoid question asks for the default name used in the Gradio demo if no name is provided. The answer to this question can be found in the `argparse.ArgumentParser()` function, where a default value of \"User\" is set for the `--name` argument. \n",
649
+ "3 The function used to load a pre-trained Resnet-18 model in the provided context is `torch.hub.load('pytorch/vision:v0.6.0', 'resnet18', pretrained=True).eval()`. \n",
650
+ "4 The name of the component used for creating a button in the given code is `BaseButton`. \n",
651
+ "5 The command is `python run_onnx_exporter.py --model_name_or_path facebook/bart-base`. \n",
652
+ "6 The next unit of the course will cover learning more about Unity MLAgents and training agents in Unity environments. It will also prepare students for AI vs AI challenges where they will train their agents to compete against other agents in a snowball fight and a soccer game. \n",
653
+ "7 These parameters allow SDXL to negatively condition the model on image resolution and cropping parameters. \n",
654
+ "8 Transformers models are tested in the Hugging Face repository using two test suites: `tests` for the general API and `examples` for various applications that aren't part of the API. These tests are run on CircleCI and GitHub Actions, with different jobs and configurations for each. The tests can be run in various ways, including running all tests, getting the list of all tests, running a specific test module, and running specific tests by name or keyword expression. Additionally, there are options for running tests in parallel, repeating tests, and running tests on a specific GPU or CPU. \n",
655
+ "9 The command used to create a virtual environment in the given context is `python -m venv <env_name>`. \n",
656
+ "\n",
657
+ " groundedness_score relevance_score standalone_score \n",
658
+ "0 3.0 1.0 4.0 \n",
659
+ "1 5.0 4.0 5.0 \n",
660
+ "2 5.0 3.0 5.0 \n",
661
+ "3 NaN NaN NaN \n",
662
+ "4 5.0 1.0 5.0 \n",
663
+ "5 NaN NaN NaN \n",
664
+ "6 5.0 1.0 5.0 \n",
665
+ "7 2.0 4.0 2.0 \n",
666
+ "8 3.0 4.0 4.0 \n",
667
+ "9 NaN NaN NaN "
668
+ ]
669
+ },
670
+ "metadata": {},
671
+ "output_type": "display_data"
672
+ },
673
+ {
674
+ "name": "stdout",
675
+ "output_type": "stream",
676
+ "text": [
677
+ "============================================\n",
678
+ "Final evaluation dataset:\n"
679
+ ]
680
+ },
681
+ {
682
+ "data": {
683
+ "text/html": [
684
+ "<div>\n",
685
+ "<style scoped>\n",
686
+ " .dataframe tbody tr th:only-of-type {\n",
687
+ " vertical-align: middle;\n",
688
+ " }\n",
689
+ "\n",
690
+ " .dataframe tbody tr th {\n",
691
+ " vertical-align: top;\n",
692
+ " }\n",
693
+ "\n",
694
+ " .dataframe thead th {\n",
695
+ " text-align: right;\n",
696
+ " }\n",
697
+ "</style>\n",
698
+ "<table border=\"1\" class=\"dataframe\">\n",
699
+ " <thead>\n",
700
+ " <tr style=\"text-align: right;\">\n",
701
+ " <th></th>\n",
702
+ " <th>question</th>\n",
703
+ " <th>answer</th>\n",
704
+ " <th>groundedness_score</th>\n",
705
+ " <th>relevance_score</th>\n",
706
+ " <th>standalone_score</th>\n",
707
+ " </tr>\n",
708
+ " </thead>\n",
709
+ " <tbody>\n",
710
+ " <tr>\n",
711
+ " <th>1</th>\n",
712
+ " <td>What are some utility functions provided by the Hugging Face library for pipelines?\\n</td>\n",
713
+ " <td>The Hugging Face library provides several utility functions for pipelines, including `ArgumentHandler`, `ZeroShotClassificationArgumentHandler`, `QuestionAnsweringArgumentHandler` for argument handling, `PipelineDataFormat`, `CsvPipelineDataFormat`, `JsonPipelineDataFormat`, `PipedPipelineDataFormat` for data format, and `PipelineException` for exceptions.</td>\n",
714
+ " <td>5.0</td>\n",
715
+ " <td>4.0</td>\n",
716
+ " <td>5.0</td>\n",
717
+ " </tr>\n",
718
+ " </tbody>\n",
719
+ "</table>\n",
720
+ "</div>"
721
+ ],
722
+ "text/plain": [
723
+ " question \\\n",
724
+ "1 What are some utility functions provided by the Hugging Face library for pipelines?\\n \n",
725
+ "\n",
726
+ " answer \\\n",
727
+ "1 The Hugging Face library provides several utility functions for pipelines, including `ArgumentHandler`, `ZeroShotClassificationArgumentHandler`, `QuestionAnsweringArgumentHandler` for argument handling, `PipelineDataFormat`, `CsvPipelineDataFormat`, `JsonPipelineDataFormat`, `PipedPipelineDataFormat` for data format, and `PipelineException` for exceptions. \n",
728
+ "\n",
729
+ " groundedness_score relevance_score standalone_score \n",
730
+ "1 5.0 4.0 5.0 "
731
+ ]
732
+ },
733
+ "metadata": {},
734
+ "output_type": "display_data"
735
+ }
736
+ ],
737
+ "source": [
738
+ "import pandas as pd\n",
739
+ "\n",
740
+ "pd.set_option(\"display.max_colwidth\", None)\n",
741
+ "\n",
742
+ "generated_questions = pd.DataFrame.from_dict(outputs)\n",
743
+ "\n",
744
+ "print(\"Evaluation dataset before filtering:\")\n",
745
+ "display(\n",
746
+ " generated_questions[\n",
747
+ " [\"question\", \"answer\", \"groundedness_score\", \"relevance_score\", \"standalone_score\"]\n",
748
+ " ]\n",
749
+ ")\n",
750
+ "generated_questions = generated_questions.loc[\n",
751
+ " (generated_questions[\"groundedness_score\"] >= 4)\n",
752
+ " & (generated_questions[\"relevance_score\"] >= 4)\n",
753
+ " & (generated_questions[\"standalone_score\"] >= 4)\n",
754
+ "]\n",
755
+ "print(\"============================================\")\n",
756
+ "print(\"Final evaluation dataset:\")\n",
757
+ "display(\n",
758
+ " generated_questions[\n",
759
+ " [\"question\", \"answer\", \"groundedness_score\", \"relevance_score\", \"standalone_score\"]\n",
760
+ " ]\n",
761
+ ")\n",
762
+ "\n",
763
+ "eval_dataset = datasets.Dataset.from_pandas(\n",
764
+ " generated_questions, split=\"train\", preserve_index=False\n",
765
+ ")"
766
+ ]
767
+ },
768
+ {
769
+ "cell_type": "markdown",
770
+ "metadata": {
771
+ "id": "HaOMZyu69jVO"
772
+ },
773
+ "source": [
774
+ "Now our synthetic evaluation dataset is complete! We can evaluate different RAG systems on this evaluation dataset.\n",
775
+ "\n",
776
+ "We have generated only a few QA couples here to reduce time and cost. But let's kick start the next part by loading a pre-generated dataset:"
777
+ ]
778
+ },
779
+ {
780
+ "cell_type": "code",
781
+ "execution_count": null,
782
+ "metadata": {
783
+ "id": "Q3RRz4W79jVO"
784
+ },
785
+ "outputs": [],
786
+ "source": [
787
+ "eval_dataset = datasets.load_dataset(\"m-ric/huggingface_doc_qa_eval\", split=\"train\")"
788
+ ]
789
+ },
790
+ {
791
+ "cell_type": "markdown",
792
+ "metadata": {
793
+ "id": "K5s19uTd9jVO"
794
+ },
795
+ "source": [
796
+ "# 2. Build our RAG System"
797
+ ]
798
+ },
799
+ {
800
+ "cell_type": "markdown",
801
+ "metadata": {
802
+ "id": "Z-mET8Dy9jVO"
803
+ },
804
+ "source": [
805
+ "### 2.1. Preprocessing documents to build our vector database\n",
806
+ "\n",
807
+ "- In this part, __we split the documents from our knowledge base into smaller chunks__: these will be the snippets that are picked by the Retriever, to then be ingested by the Reader LLM as supporting elements for its answer.\n",
808
+ "- The goal is to build semantically relevant snippets: not too small to be sufficient for supporting an answer, and not too large too avoid diluting individual ideas.\n",
809
+ "\n",
810
+ "Many options exist for text splitting:\n",
811
+ "- split every `n` words / characters, but this has the risk of cutting in half paragraphs or even sentences\n",
812
+ "- split after `n` words / character, but only on sentence boundaries\n",
813
+ "- **recursive split** tries to preserve even more of the document structure, by processing it tree-like way, splitting first on the largest units (chapters) then recursively splitting on smaller units (paragraphs, sentences).\n",
814
+ "\n",
815
+ "To learn more about chunking, I recommend you read [this great notebook](https://github.com/FullStackRetrieval-com/RetrievalTutorials/blob/main/5_Levels_Of_Text_Splitting.ipynb) by Greg Kamradt.\n",
816
+ "\n",
817
+ "[This space](https://huggingface.co/spaces/m-ric/chunk_visualizer) lets you visualize how different splitting options affect the chunks you get.\n",
818
+ "\n",
819
+ "> In the following, we use Langchain's `RecursiveCharacterTextSplitter`.\n",
820
+ "\n",
821
+ "💡 _To measure chunk length in our Text Splitter, our length function will not be the count of characters, but the count of tokens in the tokenized text: indeed, for subsequent embedder that processes token, measuring length in tokens is more relevant and empirically performs better._"
822
+ ]
823
+ },
824
+ {
825
+ "cell_type": "code",
826
+ "execution_count": null,
827
+ "metadata": {
828
+ "id": "H4fhm55Q9jVO"
829
+ },
830
+ "outputs": [],
831
+ "source": [
832
+ "from langchain.docstore.document import Document as LangchainDocument\n",
833
+ "\n",
834
+ "RAW_KNOWLEDGE_BASE = [\n",
835
+ " LangchainDocument(page_content=doc[\"text\"], metadata={\"source\": doc[\"source\"]})\n",
836
+ " for doc in tqdm(ds)\n",
837
+ "]"
838
+ ]
839
+ },
840
+ {
841
+ "cell_type": "code",
842
+ "execution_count": null,
843
+ "metadata": {
844
+ "id": "sz9Jw2_q9jVO"
845
+ },
846
+ "outputs": [],
847
+ "source": [
848
+ "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
849
+ "from transformers import AutoTokenizer\n",
850
+ "\n",
851
+ "\n",
852
+ "def split_documents(\n",
853
+ " chunk_size: int,\n",
854
+ " knowledge_base: List[LangchainDocument],\n",
855
+ " tokenizer_name: str,\n",
856
+ ") -> List[LangchainDocument]:\n",
857
+ " \"\"\"\n",
858
+ " Split documents into chunks of size `chunk_size` characters and return a list of documents.\n",
859
+ " \"\"\"\n",
860
+ " text_splitter = RecursiveCharacterTextSplitter.from_huggingface_tokenizer(\n",
861
+ " AutoTokenizer.from_pretrained(tokenizer_name),\n",
862
+ " chunk_size=chunk_size,\n",
863
+ " chunk_overlap=int(chunk_size / 10),\n",
864
+ " add_start_index=True,\n",
865
+ " strip_whitespace=True,\n",
866
+ " separators=[\"\\n\\n\", \"\\n\", \".\", \" \", \"\"],\n",
867
+ " )\n",
868
+ "\n",
869
+ " docs_processed = []\n",
870
+ " for doc in knowledge_base:\n",
871
+ " docs_processed += text_splitter.split_documents([doc])\n",
872
+ "\n",
873
+ " # Remove duplicates\n",
874
+ " unique_texts = {}\n",
875
+ " docs_processed_unique = []\n",
876
+ " for doc in docs_processed:\n",
877
+ " if doc.page_content not in unique_texts:\n",
878
+ " unique_texts[doc.page_content] = True\n",
879
+ " docs_processed_unique.append(doc)\n",
880
+ "\n",
881
+ " return docs_processed_unique"
882
+ ]
883
+ },
884
+ {
885
+ "cell_type": "markdown",
886
+ "metadata": {
887
+ "id": "QzBYfNG79jVO"
888
+ },
889
+ "source": [
890
+ "### 2.2. Retriever - embeddings 🗂️\n",
891
+ "The __retriever acts like an internal search engine__: given the user query, it returns the most relevant documents from your knowledge base.\n",
892
+ "\n",
893
+ "> For the knowledge base, we use Langchain vector databases since __it offers a convenient [FAISS](https://github.com/facebookresearch/faiss) index and allows us to keep document metadata throughout the processing__.\n",
894
+ "\n",
895
+ "🛠️ __Options included:__\n",
896
+ "\n",
897
+ "- Tune the chunking method:\n",
898
+ " - Size of the chunks\n",
899
+ " - Method: split on different separators, use [semantic chunking](https://python.langchain.com/docs/modules/data_connection/document_transformers/semantic-chunker)...\n",
900
+ "- Change the embedding model"
901
+ ]
902
+ },
903
+ {
904
+ "cell_type": "code",
905
+ "execution_count": null,
906
+ "metadata": {
907
+ "id": "LqJlIDZR9jVO"
908
+ },
909
+ "outputs": [],
910
+ "source": [
911
+ "from langchain.vectorstores import FAISS\n",
912
+ "from langchain_community.embeddings import HuggingFaceEmbeddings\n",
913
+ "from langchain_community.vectorstores.utils import DistanceStrategy\n",
914
+ "import os\n",
915
+ "\n",
916
+ "\n",
917
+ "def load_embeddings(\n",
918
+ " langchain_docs: List[LangchainDocument],\n",
919
+ " chunk_size: int,\n",
920
+ " embedding_model_name: Optional[str] = \"thenlper/gte-small\",\n",
921
+ ") -> FAISS:\n",
922
+ " \"\"\"\n",
923
+ " Creates a FAISS index from the given embedding model and documents. Loads the index directly if it already exists.\n",
924
+ "\n",
925
+ " Args:\n",
926
+ " langchain_docs: list of documents\n",
927
+ " chunk_size: size of the chunks to split the documents into\n",
928
+ " embedding_model_name: name of the embedding model to use\n",
929
+ "\n",
930
+ " Returns:\n",
931
+ " FAISS index\n",
932
+ " \"\"\"\n",
933
+ " # load embedding_model\n",
934
+ " embedding_model = HuggingFaceEmbeddings(\n",
935
+ " model_name=embedding_model_name,\n",
936
+ " multi_process=True,\n",
937
+ " model_kwargs={\"device\": \"cuda\"},\n",
938
+ " encode_kwargs={\"normalize_embeddings\": True}, # set True to compute cosine similarity\n",
939
+ " )\n",
940
+ "\n",
941
+ " # Check if embeddings already exist on disk\n",
942
+ " index_name = f\"index_chunk:{chunk_size}_embeddings:{embedding_model_name.replace('/', '~')}\"\n",
943
+ " index_folder_path = f\"./data/indexes/{index_name}/\"\n",
944
+ " if os.path.isdir(index_folder_path):\n",
945
+ " return FAISS.load_local(\n",
946
+ " index_folder_path,\n",
947
+ " embedding_model,\n",
948
+ " distance_strategy=DistanceStrategy.COSINE,\n",
949
+ " )\n",
950
+ "\n",
951
+ " else:\n",
952
+ " print(\"Index not found, generating it...\")\n",
953
+ " docs_processed = split_documents(\n",
954
+ " chunk_size,\n",
955
+ " langchain_docs,\n",
956
+ " embedding_model_name,\n",
957
+ " )\n",
958
+ " knowledge_index = FAISS.from_documents(\n",
959
+ " docs_processed, embedding_model, distance_strategy=DistanceStrategy.COSINE\n",
960
+ " )\n",
961
+ " knowledge_index.save_local(index_folder_path)\n",
962
+ " return knowledge_index"
963
+ ]
964
+ },
965
+ {
966
+ "cell_type": "markdown",
967
+ "metadata": {
968
+ "id": "b6y1mQJX9jVO"
969
+ },
970
+ "source": [
971
+ "### 2.3. Reader - LLM 💬\n",
972
+ "\n",
973
+ "In this part, the __LLM Reader reads the retrieved documents to formulate its answer.__\n",
974
+ "\n",
975
+ "🛠️ Here we tried the following options to improve results:\n",
976
+ "- Switch reranking on/off\n",
977
+ "- Change the reader model"
978
+ ]
979
+ },
980
+ {
981
+ "cell_type": "code",
982
+ "execution_count": null,
983
+ "metadata": {
984
+ "id": "9PdpuWyP9jVP"
985
+ },
986
+ "outputs": [],
987
+ "source": [
988
+ "RAG_PROMPT_TEMPLATE = \"\"\"\n",
989
+ "<|system|>\n",
990
+ "Using the information contained in the context,\n",
991
+ "give a comprehensive answer to the question.\n",
992
+ "Respond only to the question asked, response should be concise and relevant to the question.\n",
993
+ "Provide the number of the source document when relevant.\n",
994
+ "If the answer cannot be deduced from the context, do not give an answer.</s>\n",
995
+ "<|user|>\n",
996
+ "Context:\n",
997
+ "{context}\n",
998
+ "---\n",
999
+ "Now here is the question you need to answer.\n",
1000
+ "\n",
1001
+ "Question: {question}\n",
1002
+ "</s>\n",
1003
+ "<|assistant|>\n",
1004
+ "\"\"\""
1005
+ ]
1006
+ },
1007
+ {
1008
+ "cell_type": "code",
1009
+ "execution_count": null,
1010
+ "metadata": {
1011
+ "id": "9SDqenld9jVP"
1012
+ },
1013
+ "outputs": [],
1014
+ "source": [
1015
+ "from langchain_community.llms import HuggingFaceHub\n",
1016
+ "\n",
1017
+ "repo_id = \"HuggingFaceH4/zephyr-7b-beta\"\n",
1018
+ "READER_MODEL_NAME = \"zephyr-7b-beta\"\n",
1019
+ "\n",
1020
+ "READER_LLM = HuggingFaceHub(\n",
1021
+ " repo_id=repo_id,\n",
1022
+ " task=\"text-generation\",\n",
1023
+ " model_kwargs={\n",
1024
+ " \"max_new_tokens\": 512,\n",
1025
+ " \"top_k\": 30,\n",
1026
+ " \"temperature\": 0.1,\n",
1027
+ " \"repetition_penalty\": 1.03,\n",
1028
+ " },\n",
1029
+ ")"
1030
+ ]
1031
+ },
1032
+ {
1033
+ "cell_type": "code",
1034
+ "execution_count": null,
1035
+ "metadata": {
1036
+ "id": "QZ62CbcZ9jVP"
1037
+ },
1038
+ "outputs": [],
1039
+ "source": [
1040
+ "from ragatouille import RAGPretrainedModel\n",
1041
+ "from langchain_core.vectorstores import VectorStore\n",
1042
+ "from langchain_core.language_models.llms import LLM\n",
1043
+ "\n",
1044
+ "\n",
1045
+ "def answer_with_rag(\n",
1046
+ " question: str,\n",
1047
+ " llm: LLM,\n",
1048
+ " knowledge_index: VectorStore,\n",
1049
+ " reranker: Optional[RAGPretrainedModel] = None,\n",
1050
+ " num_retrieved_docs: int = 30,\n",
1051
+ " num_docs_final: int = 7,\n",
1052
+ ") -> Tuple[str, List[LangchainDocument]]:\n",
1053
+ " \"\"\"Answer a question using RAG with the given knowledge index.\"\"\"\n",
1054
+ " # Gather documents with retriever\n",
1055
+ " relevant_docs = knowledge_index.similarity_search(query=question, k=num_retrieved_docs)\n",
1056
+ " relevant_docs = [doc.page_content for doc in relevant_docs] # keep only the text\n",
1057
+ "\n",
1058
+ " # Optionally rerank results\n",
1059
+ " if reranker:\n",
1060
+ " relevant_docs = reranker.rerank(question, relevant_docs, k=num_docs_final)\n",
1061
+ " relevant_docs = [doc[\"content\"] for doc in relevant_docs]\n",
1062
+ "\n",
1063
+ " relevant_docs = relevant_docs[:num_docs_final]\n",
1064
+ "\n",
1065
+ " # Build the final prompt\n",
1066
+ " context = \"\\nExtracted documents:\\n\"\n",
1067
+ " context += \"\".join([f\"Document {str(i)}:::\\n\" + doc for i, doc in enumerate(relevant_docs)])\n",
1068
+ "\n",
1069
+ " final_prompt = RAG_PROMPT_TEMPLATE.format(question=question, context=context)\n",
1070
+ "\n",
1071
+ " # Redact an answer\n",
1072
+ " answer = llm(final_prompt)\n",
1073
+ "\n",
1074
+ " return answer, relevant_docs"
1075
+ ]
1076
+ },
1077
+ {
1078
+ "cell_type": "markdown",
1079
+ "metadata": {
1080
+ "id": "hiygbqfT9jVP"
1081
+ },
1082
+ "source": [
1083
+ "# 3. Benchmarking the RAG system\n",
1084
+ "\n",
1085
+ "The RAG system and the evaluation datasets are now ready. The last step is to judge the RAG system's output on this evlauation dataset.\n",
1086
+ "\n",
1087
+ "To this end, __we setup a judge agent__. ⚖️🤖\n",
1088
+ "\n",
1089
+ "Out of [the different RAG evaluation metrics](https://docs.ragas.io/en/latest/concepts/metrics/index.html), we choose to focus only on faithfulness since it the best end-to-end metric of our system's performance.\n",
1090
+ "\n",
1091
+ "> We use GPT4 as a judge for its empirically good performance, but you could try with other models such as [kaist-ai/prometheus-13b-v1.0](https://huggingface.co/kaist-ai/prometheus-13b-v1.0) or [BAAI/JudgeLM-33B-v1.0](https://huggingface.co/BAAI/JudgeLM-33B-v1.0).\n",
1092
+ "\n",
1093
+ "💡 _In the evaluation prompt, we give a detailed description each metric on the scale 1-5, as is done in [Prometheus's prompt template](https://huggingface.co/kaist-ai/prometheus-13b-v1.0): this helps the model ground its metric precisely. If instead you give the judge LLM a vague scale to work with, the outputs will not be consistent enough between different examples._\n",
1094
+ "\n",
1095
+ "💡 _Again, prompting the LLM to output rationale before giving its final score gives it more tokens to help it formalize and elaborate a judgement._"
1096
+ ]
1097
+ },
1098
+ {
1099
+ "cell_type": "code",
1100
+ "execution_count": null,
1101
+ "metadata": {
1102
+ "id": "VrlMh_ZI9jVP"
1103
+ },
1104
+ "outputs": [],
1105
+ "source": [
1106
+ "def run_rag_tests(\n",
1107
+ " eval_dataset: datasets.Dataset,\n",
1108
+ " llm: BaseChatModel,\n",
1109
+ " knowledge_index: VectorStore,\n",
1110
+ " output_file: str,\n",
1111
+ " reranker: Optional[RAGPretrainedModel] = None,\n",
1112
+ " verbose: Optional[bool] = True,\n",
1113
+ " test_settings: Optional[str] = None, # To document the test settings used\n",
1114
+ "):\n",
1115
+ " \"\"\"Runs RAG tests on the given dataset and saves the results to the given output file.\"\"\"\n",
1116
+ " try: # load previous generations if they exist\n",
1117
+ " with open(output_file, \"r\") as f:\n",
1118
+ " outputs = json.load(f)\n",
1119
+ " except:\n",
1120
+ " outputs = []\n",
1121
+ "\n",
1122
+ " for example in tqdm(eval_dataset):\n",
1123
+ " question = example[\"question\"]\n",
1124
+ " if question in [output[\"question\"] for output in outputs]:\n",
1125
+ " continue\n",
1126
+ "\n",
1127
+ " answer, relevant_docs = answer_with_rag(question, llm, knowledge_index, reranker=reranker)\n",
1128
+ " if verbose:\n",
1129
+ " print(\"=======================================================\")\n",
1130
+ " print(f\"Question: {question}\")\n",
1131
+ " print(f\"Answer: {answer}\")\n",
1132
+ " print(f'True answer: {example[\"answer\"]}')\n",
1133
+ " result = {\n",
1134
+ " \"question\": question,\n",
1135
+ " \"true_answer\": example[\"answer\"],\n",
1136
+ " \"source_doc\": example[\"source_doc\"],\n",
1137
+ " \"generated_answer\": answer,\n",
1138
+ " \"retrieved_docs\": [doc for doc in relevant_docs],\n",
1139
+ " }\n",
1140
+ " if test_settings:\n",
1141
+ " result[\"test_settings\"] = test_settings\n",
1142
+ " outputs.append(result)\n",
1143
+ "\n",
1144
+ " with open(output_file, \"w\") as f:\n",
1145
+ " json.dump(outputs, f)"
1146
+ ]
1147
+ },
1148
+ {
1149
+ "cell_type": "code",
1150
+ "execution_count": null,
1151
+ "metadata": {
1152
+ "id": "Ae-3KWzK9jVP"
1153
+ },
1154
+ "outputs": [],
1155
+ "source": [
1156
+ "EVALUATION_PROMPT = \"\"\"###Task Description:\n",
1157
+ "An instruction (might include an Input inside it), a response to evaluate, a reference answer that gets a score of 5, and a score rubric representing a evaluation criteria are given.\n",
1158
+ "1. Write a detailed feedback that assess the quality of the response strictly based on the given score rubric, not evaluating in general.\n",
1159
+ "2. After writing a feedback, write a score that is an integer between 1 and 5. You should refer to the score rubric.\n",
1160
+ "3. The output format should look as follows: \\\"Feedback: {{write a feedback for criteria}} [RESULT] {{an integer number between 1 and 5}}\\\"\n",
1161
+ "4. Please do not generate any other opening, closing, and explanations. Be sure to include [RESULT] in your output.\n",
1162
+ "\n",
1163
+ "###The instruction to evaluate:\n",
1164
+ "{instruction}\n",
1165
+ "\n",
1166
+ "###Response to evaluate:\n",
1167
+ "{response}\n",
1168
+ "\n",
1169
+ "###Reference Answer (Score 5):\n",
1170
+ "{reference_answer}\n",
1171
+ "\n",
1172
+ "###Score Rubrics:\n",
1173
+ "[Is the response correct, accurate, and factual based on the reference answer?]\n",
1174
+ "Score 1: The response is completely incorrect, inaccurate, and/or not factual.\n",
1175
+ "Score 2: The response is mostly incorrect, inaccurate, and/or not factual.\n",
1176
+ "Score 3: The response is somewhat correct, accurate, and/or factual.\n",
1177
+ "Score 4: The response is mostly correct, accurate, and factual.\n",
1178
+ "Score 5: The response is completely correct, accurate, and factual.\n",
1179
+ "\n",
1180
+ "###Feedback:\"\"\"\n",
1181
+ "\n",
1182
+ "from langchain.prompts.chat import (\n",
1183
+ " ChatPromptTemplate,\n",
1184
+ " HumanMessagePromptTemplate,\n",
1185
+ ")\n",
1186
+ "from langchain.schema import SystemMessage\n",
1187
+ "\n",
1188
+ "\n",
1189
+ "evaluation_prompt_template = ChatPromptTemplate.from_messages(\n",
1190
+ " [\n",
1191
+ " SystemMessage(content=\"You are a fair evaluator language model.\"),\n",
1192
+ " HumanMessagePromptTemplate.from_template(EVALUATION_PROMPT),\n",
1193
+ " ]\n",
1194
+ ")"
1195
+ ]
1196
+ },
1197
+ {
1198
+ "cell_type": "code",
1199
+ "execution_count": null,
1200
+ "metadata": {
1201
+ "id": "ia9Mvn859jVP"
1202
+ },
1203
+ "outputs": [],
1204
+ "source": [
1205
+ "from langchain.chat_models import ChatOpenAI\n",
1206
+ "\n",
1207
+ "eval_chat_model = ChatOpenAI(model=\"gpt-4-1106-preview\", temperature=0)\n",
1208
+ "evaluator_name = \"GPT4\"\n",
1209
+ "\n",
1210
+ "\n",
1211
+ "def evaluate_answers(\n",
1212
+ " answer_path: str,\n",
1213
+ " eval_chat_model: BaseChatModel,\n",
1214
+ " evaluator_name: str,\n",
1215
+ " evaluation_prompt_template: ChatPromptTemplate,\n",
1216
+ ") -> None:\n",
1217
+ " \"\"\"Evaluates generated answers. Modifies the given answer file in place for better checkpointing.\"\"\"\n",
1218
+ " answers = []\n",
1219
+ " if os.path.isfile(answer_path): # load previous generations if they exist\n",
1220
+ " answers = json.load(open(answer_path, \"r\"))\n",
1221
+ "\n",
1222
+ " for experiment in tqdm(answers):\n",
1223
+ " if f\"eval_score_{evaluator_name}\" in experiment:\n",
1224
+ " continue\n",
1225
+ "\n",
1226
+ " eval_prompt = evaluation_prompt_template.format_messages(\n",
1227
+ " instruction=experiment[\"question\"],\n",
1228
+ " response=experiment[\"generated_answer\"],\n",
1229
+ " reference_answer=experiment[\"true_answer\"],\n",
1230
+ " )\n",
1231
+ " eval_result = eval_chat_model.invoke(eval_prompt)\n",
1232
+ " feedback, score = [item.strip() for item in eval_result.content.split(\"[RESULT]\")]\n",
1233
+ " experiment[f\"eval_score_{evaluator_name}\"] = score\n",
1234
+ " experiment[f\"eval_feedback_{evaluator_name}\"] = feedback\n",
1235
+ "\n",
1236
+ " with open(answer_path, \"w\") as f:\n",
1237
+ " json.dump(answers, f)"
1238
+ ]
1239
+ },
1240
+ {
1241
+ "cell_type": "markdown",
1242
+ "metadata": {
1243
+ "id": "EXH-szLe9jVP"
1244
+ },
1245
+ "source": [
1246
+ "🚀 Let's run the tests and evaluate answers!👇"
1247
+ ]
1248
+ },
1249
+ {
1250
+ "cell_type": "code",
1251
+ "execution_count": null,
1252
+ "metadata": {
1253
+ "id": "jW2nnvUT9jVQ"
1254
+ },
1255
+ "outputs": [],
1256
+ "source": [
1257
+ "if not os.path.exists(\"./output\"):\n",
1258
+ " os.mkdir(\"./output\")\n",
1259
+ "\n",
1260
+ "for chunk_size in [200]: # Add other chunk sizes (in tokens) as needed\n",
1261
+ " for embeddings in [\"thenlper/gte-small\"]: # Add other embeddings as needed\n",
1262
+ " for rerank in [True, False]:\n",
1263
+ " settings_name = f\"chunk:{chunk_size}_embeddings:{embeddings.replace('/', '~')}_rerank:{rerank}_reader-model:{READER_MODEL_NAME}\"\n",
1264
+ " output_file_name = f\"./output/rag_{settings_name}.json\"\n",
1265
+ "\n",
1266
+ " print(f\"Running evaluation for {settings_name}:\")\n",
1267
+ "\n",
1268
+ " print(\"Loading knowledge base embeddings...\")\n",
1269
+ " knowledge_index = load_embeddings(\n",
1270
+ " RAW_KNOWLEDGE_BASE,\n",
1271
+ " chunk_size=chunk_size,\n",
1272
+ " embedding_model_name=embeddings,\n",
1273
+ " )\n",
1274
+ "\n",
1275
+ " print(\"Running RAG...\")\n",
1276
+ " reranker = (\n",
1277
+ " RAGPretrainedModel.from_pretrained(\"colbert-ir/colbertv2.0\") if rerank else None\n",
1278
+ " )\n",
1279
+ " run_rag_tests(\n",
1280
+ " eval_dataset=eval_dataset,\n",
1281
+ " llm=READER_LLM,\n",
1282
+ " knowledge_index=knowledge_index,\n",
1283
+ " output_file=output_file_name,\n",
1284
+ " reranker=reranker,\n",
1285
+ " verbose=False,\n",
1286
+ " test_settings=settings_name,\n",
1287
+ " )\n",
1288
+ "\n",
1289
+ " print(\"Running evaluation...\")\n",
1290
+ " evaluate_answers(\n",
1291
+ " output_file_name,\n",
1292
+ " eval_chat_model,\n",
1293
+ " evaluator_name,\n",
1294
+ " evaluation_prompt_template,\n",
1295
+ " )"
1296
+ ]
1297
+ },
1298
+ {
1299
+ "cell_type": "markdown",
1300
+ "metadata": {
1301
+ "id": "tytXV5-h9jVT"
1302
+ },
1303
+ "source": [
1304
+ "### Inspect results"
1305
+ ]
1306
+ },
1307
+ {
1308
+ "cell_type": "code",
1309
+ "execution_count": null,
1310
+ "metadata": {
1311
+ "id": "D4YDSfmr9jVT"
1312
+ },
1313
+ "outputs": [],
1314
+ "source": [
1315
+ "import glob\n",
1316
+ "\n",
1317
+ "outputs = []\n",
1318
+ "for file in glob.glob(\"./output/*.json\"):\n",
1319
+ " output = pd.DataFrame(json.load(open(file, \"r\")))\n",
1320
+ " output[\"settings\"] = file\n",
1321
+ " outputs.append(output)\n",
1322
+ "result = pd.concat(outputs)"
1323
+ ]
1324
+ },
1325
+ {
1326
+ "cell_type": "code",
1327
+ "execution_count": null,
1328
+ "metadata": {
1329
+ "id": "CdkXMNvS9jVT"
1330
+ },
1331
+ "outputs": [],
1332
+ "source": [
1333
+ "result[\"eval_score_GPT4\"] = result[\"eval_score_GPT4\"].apply(\n",
1334
+ " lambda x: int(x) if isinstance(x, str) else 1\n",
1335
+ ")\n",
1336
+ "result[\"eval_score_GPT4\"] = (result[\"eval_score_GPT4\"] - 1) / 4"
1337
+ ]
1338
+ },
1339
+ {
1340
+ "cell_type": "code",
1341
+ "execution_count": null,
1342
+ "metadata": {
1343
+ "id": "lgxBpid29jVT",
1344
+ "outputId": "9a3bcf32-4b0c-4df1-c76c-3ebbca82929d"
1345
+ },
1346
+ "outputs": [
1347
+ {
1348
+ "data": {
1349
+ "text/plain": [
1350
+ "settings\n",
1351
+ "./output/rag_chunk:200_embeddings:thenlper~gte-small_rerank:False_reader-model:zephyr-7b-beta.json 0.884328\n",
1352
+ "./output/rag_chunk:200_embeddings:BAAI~bge-base-en-v1.5_rerank:False_reader-model:zephyr-7b-beta.json 0.906716\n",
1353
+ "./output/rag_chunk:200_embeddings:BAAI~bge-base-en-v1.5_rerank:True_reader-model:zephyr-7b-beta.json 0.906716\n",
1354
+ "./output/rag_chunk:200_embeddings:thenlper~gte-small_rerank:True_reader-model:mixtral.json 0.906716\n",
1355
+ "./output/rag_chunk:200_embeddings:thenlper~gte-small_rerank:True_reader-model:zephyr-7b-beta.json 0.921642\n",
1356
+ "./output/rag_chunk:200_embeddings:thenlper~gte-small_rerank:True_reader-model:mixtral0.json 0.947761\n",
1357
+ "Name: eval_score_GPT4, dtype: float64"
1358
+ ]
1359
+ },
1360
+ "execution_count": 24,
1361
+ "metadata": {},
1362
+ "output_type": "execute_result"
1363
+ }
1364
+ ],
1365
+ "source": [
1366
+ "average_scores = result.groupby(\"settings\")[\"eval_score_GPT4\"].mean()\n",
1367
+ "average_scores.sort_values()"
1368
+ ]
1369
+ },
1370
+ {
1371
+ "cell_type": "markdown",
1372
+ "metadata": {
1373
+ "id": "pSPH9DYI9jVT"
1374
+ },
1375
+ "source": [
1376
+ "## Example results\n",
1377
+ "\n",
1378
+ "Let us load the results that I obtained by tweaking the different options available in this notebook.\n",
1379
+ "For more detail on why these options could work on not, see the notebook on [advanced_RAG](advanced_rag).\n",
1380
+ "\n",
1381
+ "As you can see in the graph below, some tweaks do not bring any improvement, some give huge performance boosts.\n",
1382
+ "\n",
1383
+ "➡️ ___There is no single good recipe: you should try several different directions when tuning your RAG systems.___\n"
1384
+ ]
1385
+ },
1386
+ {
1387
+ "cell_type": "code",
1388
+ "execution_count": null,
1389
+ "metadata": {
1390
+ "id": "RVOxatv99jVT"
1391
+ },
1392
+ "outputs": [],
1393
+ "source": [
1394
+ "import plotly.express as px\n",
1395
+ "\n",
1396
+ "scores = datasets.load_dataset(\"m-ric/rag_scores_cookbook\", split=\"train\")\n",
1397
+ "scores = pd.Series(scores[\"score\"], index=scores[\"settings\"])"
1398
+ ]
1399
+ },
1400
+ {
1401
+ "cell_type": "code",
1402
+ "execution_count": null,
1403
+ "metadata": {
1404
+ "id": "vqK0Dg2Q9jVT"
1405
+ },
1406
+ "outputs": [],
1407
+ "source": [
1408
+ "fig = px.bar(\n",
1409
+ " scores,\n",
1410
+ " color=scores,\n",
1411
+ " labels={\n",
1412
+ " \"value\": \"Accuracy\",\n",
1413
+ " \"settings\": \"Configuration\",\n",
1414
+ " },\n",
1415
+ " color_continuous_scale=\"bluered\",\n",
1416
+ ")\n",
1417
+ "fig.update_layout(w\n",
1418
+ " width=1000,\n",
1419
+ " height=600,\n",
1420
+ " barmode=\"group\",\n",
1421
+ " yaxis_range=[0, 100],\n",
1422
+ " title=\"<b>Accuracy of different RAG configurations</b>\",\n",
1423
+ " xaxis_title=\"RAG settings\",\n",
1424
+ " font=dict(size=15),\n",
1425
+ ")\n",
1426
+ "fig.layout.yaxis.ticksuffix = \"%\"\n",
1427
+ "fig.update_coloraxes(showscale=False)\n",
1428
+ "fig.update_traces(texttemplate=\"%{y:.1f}\", textposition=\"outside\")\n",
1429
+ "fig.show()"
1430
+ ]
1431
+ },
1432
+ {
1433
+ "cell_type": "markdown",
1434
+ "metadata": {
1435
+ "id": "dPUOMWGk9jVT"
1436
+ },
1437
+ "source": [
1438
+ "<img src=\"https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/RAG_settings_accuracy.png\" height=\"500\" width=\"800\">\n",
1439
+ "\n",
1440
+ "As you can see, these had varying impact on performance. In particular, tuning the chunk size is both easy and very impactful.\n",
1441
+ "\n",
1442
+ "But this is our case: your results could be very different: now that you have a robust evaluation pipeline, you can set on to explore other options! 🗺️"
1443
+ ]
1444
+ }
1445
+ ],
1446
+ "metadata": {
1447
+ "colab": {
1448
+ "provenance": []
1449
+ },
1450
+ "kernelspec": {
1451
+ "display_name": "ml2",
1452
+ "language": "python",
1453
+ "name": "python3"
1454
+ },
1455
+ "language_info": {
1456
+ "codemirror_mode": {
1457
+ "name": "ipython",
1458
+ "version": 3
1459
+ },
1460
+ "file_extension": ".py",
1461
+ "mimetype": "text/x-python",
1462
+ "name": "python",
1463
+ "nbconvert_exporter": "python",
1464
+ "pygments_lexer": "ipython3",
1465
+ "version": "3.10.9"
1466
+ }
1467
+ },
1468
+ "nbformat": 4,
1469
+ "nbformat_minor": 0
1470
+ }
src/notebooks/rag_zephyr_langchain.ipynb ADDED
@@ -0,0 +1,527 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {
6
+ "id": "Kih21u1tyr-I"
7
+ },
8
+ "source": [
9
+ "---\n",
10
+ "title: Simple RAG\n",
11
+ "---\n",
12
+ "\n",
13
+ "# Simple RAG for GitHub issues using Hugging Face Zephyr and LangChain\n",
14
+ "\n",
15
+ "_Authored by: [Maria Khalusova](https://github.com/MKhalusova)_\n",
16
+ "\n",
17
+ "This notebook demonstrates how you can quickly build a RAG (Retrieval Augmented Generation) for a project's GitHub issues using [`HuggingFaceH4/zephyr-7b-beta`](https://huggingface.co/HuggingFaceH4/zephyr-7b-beta) model, and LangChain.\n",
18
+ "\n",
19
+ "\n",
20
+ "**What is RAG?**\n",
21
+ "\n",
22
+ "RAG is a popular approach to address the issue of a powerful LLM not being aware of specific content due to said content not being in its training data, or hallucinating even when it has seen it before. Such specific content may be proprietary, sensitive, or, as in this example, recent and updated often.\n",
23
+ "\n",
24
+ "If your data is static and doesn't change regularly, you may consider fine-tuning a large model. In many cases, however, fine-tuning can be costly, and, when done repeatedly (e.g. to address data drift), leads to \"model shift\". This is when the model's behavior changes in ways that are not desirable.\n",
25
+ "\n",
26
+ "**RAG (Retrieval Augmented Generation)** does not require model fine-tuning. Instead, RAG works by providing an LLM with additional context that is retrieved from relevant data so that it can generate a better-informed response.\n",
27
+ "\n",
28
+ "Here's a quick illustration:\n",
29
+ "\n",
30
+ "![RAG diagram](https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/rag-diagram.png)\n",
31
+ "\n",
32
+ "* The external data is converted into embedding vectors with a separate embeddings model, and the vectors are kept in a database. Embeddings models are typically small, so updating the embedding vectors on a regular basis is faster, cheaper, and easier than fine-tuning a model.\n",
33
+ "\n",
34
+ "* At the same time, the fact that fine-tuning is not required gives you the freedom to swap your LLM for a more powerful one when it becomes available, or switch to a smaller distilled version, should you need faster inference.\n",
35
+ "\n",
36
+ "Let's illustrate building a RAG using an open-source LLM, embeddings model, and LangChain.\n",
37
+ "\n",
38
+ "First, install the required dependencies:"
39
+ ]
40
+ },
41
+ {
42
+ "cell_type": "code",
43
+ "execution_count": null,
44
+ "metadata": {
45
+ "id": "lC9frDOlyi38"
46
+ },
47
+ "outputs": [],
48
+ "source": [
49
+ "!pip install -q torch transformers accelerate bitsandbytes transformers sentence-transformers faiss-gpu"
50
+ ]
51
+ },
52
+ {
53
+ "cell_type": "code",
54
+ "execution_count": 2,
55
+ "metadata": {
56
+ "id": "-aYENQwZ-p_c"
57
+ },
58
+ "outputs": [],
59
+ "source": [
60
+ "# If running in Google Colab, you may need to run this cell to make sure you're using UTF-8 locale to install LangChain\n",
61
+ "import locale\n",
62
+ "locale.getpreferredencoding = lambda: \"UTF-8\""
63
+ ]
64
+ },
65
+ {
66
+ "cell_type": "code",
67
+ "execution_count": null,
68
+ "metadata": {
69
+ "id": "W5HhMZ2c-NfU"
70
+ },
71
+ "outputs": [],
72
+ "source": [
73
+ "!pip install -q langchain"
74
+ ]
75
+ },
76
+ {
77
+ "cell_type": "markdown",
78
+ "metadata": {
79
+ "id": "R8po01vMWzXL"
80
+ },
81
+ "source": [
82
+ "## Prepare the data\n"
83
+ ]
84
+ },
85
+ {
86
+ "cell_type": "markdown",
87
+ "metadata": {
88
+ "id": "3cCmQywC04x6"
89
+ },
90
+ "source": [
91
+ "In this example, we'll load all of the issues (both open and closed) from [PEFT library's repo](https://github.com/huggingface/peft).\n",
92
+ "\n",
93
+ "First, you need to acquire a [GitHub personal access token](https://github.com/settings/tokens?type=beta) to access the GitHub API."
94
+ ]
95
+ },
96
+ {
97
+ "cell_type": "code",
98
+ "execution_count": null,
99
+ "metadata": {
100
+ "id": "8MoD7NbsNjlM"
101
+ },
102
+ "outputs": [],
103
+ "source": [
104
+ "from getpass import getpass\n",
105
+ "ACCESS_TOKEN = getpass(\"YOUR_GITHUB_PERSONAL_TOKEN\")"
106
+ ]
107
+ },
108
+ {
109
+ "cell_type": "markdown",
110
+ "metadata": {
111
+ "id": "fccecm3a10N6"
112
+ },
113
+ "source": [
114
+ "Next, we'll load all of the issues in the [huggingface/peft](https://github.com/huggingface/peft) repo:\n",
115
+ "- By default, pull requests are considered issues as well, here we chose to exclude them from data with by setting `include_prs=False`\n",
116
+ "- Setting `state = \"all\"` means we will load both open and closed issues."
117
+ ]
118
+ },
119
+ {
120
+ "cell_type": "code",
121
+ "execution_count": 5,
122
+ "metadata": {
123
+ "id": "8EKMit4WNDY8"
124
+ },
125
+ "outputs": [],
126
+ "source": [
127
+ "from langchain.document_loaders import GitHubIssuesLoader\n",
128
+ "\n",
129
+ "loader = GitHubIssuesLoader(\n",
130
+ " repo=\"huggingface/peft\",\n",
131
+ " access_token=ACCESS_TOKEN,\n",
132
+ " include_prs=False,\n",
133
+ " state=\"all\"\n",
134
+ ")\n",
135
+ "\n",
136
+ "docs = loader.load()"
137
+ ]
138
+ },
139
+ {
140
+ "cell_type": "markdown",
141
+ "metadata": {
142
+ "id": "CChTrY-k2qO5"
143
+ },
144
+ "source": [
145
+ "The content of individual GitHub issues may be longer than what an embedding model can take as input. If we want to embed all of the available content, we need to chunk the documents into appropriately sized pieces.\n",
146
+ "\n",
147
+ "The most common and straightforward approach to chunking is to define a fixed size of chunks and whether there should be any overlap between them. Keeping some overlap between chunks allows us to preserve some semantic context between the chunks.\n",
148
+ "\n",
149
+ "Other approaches are typically more involved and take into account the documents' structure and context. For example, one may want to split a document based on sentences or paragraphs, or create chunks based on the\n",
150
+ "\n",
151
+ "The fixed-size chunking, however, works well for most common cases, so that is what we'll do here."
152
+ ]
153
+ },
154
+ {
155
+ "cell_type": "code",
156
+ "execution_count": null,
157
+ "metadata": {
158
+ "id": "OmsXOf59Pmm-"
159
+ },
160
+ "outputs": [],
161
+ "source": [
162
+ "from langchain.text_splitter import CharacterTextSplitter\n",
163
+ "\n",
164
+ "splitter = CharacterTextSplitter(chunk_size=512, chunk_overlap=30)\n",
165
+ "\n",
166
+ "chunked_docs = splitter.split_documents(docs)"
167
+ ]
168
+ },
169
+ {
170
+ "cell_type": "markdown",
171
+ "metadata": {
172
+ "id": "DAt_zPVlXOn7"
173
+ },
174
+ "source": [
175
+ "## Create the embeddings + retriever"
176
+ ]
177
+ },
178
+ {
179
+ "cell_type": "markdown",
180
+ "metadata": {
181
+ "id": "-mvat6JQl4yp"
182
+ },
183
+ "source": [
184
+ "Now that the docs are all of the appropriate size, we can create a database with their embeddings.\n",
185
+ "\n",
186
+ "To create document chunk embeddings we'll use the `HuggingFaceEmbeddings` and the [`BAAI/bge-base-en-v1.5`](https://huggingface.co/BAAI/bge-base-en-v1.5) embeddings model. There are many other embeddings models available on the Hub, and you can keep an eye on the best performing ones by checking the [Massive Text Embedding Benchmark (MTEB) Leaderboard](https://huggingface.co/spaces/mteb/leaderboard).\n",
187
+ "\n",
188
+ "\n",
189
+ "To create the vector database, we'll use `FAISS`, a library developed by Facebook AI. This library offers efficient similarity search and clustering of dense vectors, which is what we need here. FAISS is currently one of the most used libraries for NN search in massive datasets.\n",
190
+ "\n",
191
+ "We'll access both the embeddings model and FAISS via LangChain API."
192
+ ]
193
+ },
194
+ {
195
+ "cell_type": "code",
196
+ "execution_count": null,
197
+ "metadata": {
198
+ "id": "ixmCdRzBQ5gu"
199
+ },
200
+ "outputs": [],
201
+ "source": [
202
+ "from langchain.vectorstores import FAISS\n",
203
+ "from langchain.embeddings import HuggingFaceEmbeddings\n",
204
+ "\n",
205
+ "db = FAISS.from_documents(chunked_docs,\n",
206
+ " HuggingFaceEmbeddings(model_name='BAAI/bge-base-en-v1.5'))"
207
+ ]
208
+ },
209
+ {
210
+ "cell_type": "markdown",
211
+ "metadata": {
212
+ "id": "2iCgEPi0nnN6"
213
+ },
214
+ "source": [
215
+ "We need a way to return(retrieve) the documents given an unstructured query. For that, we'll use the `as_retriever` method using the `db` as a backbone:\n",
216
+ "- `search_type=\"similarity\"` means we want to perform similarity search between the query and documents\n",
217
+ "- `search_kwargs={'k': 4}` instructs the retriever to return top 4 results.\n"
218
+ ]
219
+ },
220
+ {
221
+ "cell_type": "code",
222
+ "execution_count": 8,
223
+ "metadata": {
224
+ "id": "mBTreCQ9noHK"
225
+ },
226
+ "outputs": [],
227
+ "source": [
228
+ "retriever = db.as_retriever(\n",
229
+ " search_type=\"similarity\",\n",
230
+ " search_kwargs={'k': 4}\n",
231
+ ")"
232
+ ]
233
+ },
234
+ {
235
+ "cell_type": "markdown",
236
+ "metadata": {
237
+ "id": "WgEhlISJpTgj"
238
+ },
239
+ "source": [
240
+ "The vector database and retriever are now set up, next we need to set up the next piece of the chain - the model."
241
+ ]
242
+ },
243
+ {
244
+ "cell_type": "markdown",
245
+ "metadata": {
246
+ "id": "tzQxx0HkXVFU"
247
+ },
248
+ "source": [
249
+ "## Load quantized model"
250
+ ]
251
+ },
252
+ {
253
+ "cell_type": "markdown",
254
+ "metadata": {
255
+ "id": "9jy1cC65p_GD"
256
+ },
257
+ "source": [
258
+ "For this example, we chose [`HuggingFaceH4/zephyr-7b-beta`](https://huggingface.co/HuggingFaceH4/zephyr-7b-beta), a small but powerful model.\n",
259
+ "\n",
260
+ "With many models being released every week, you may want to substitute this model to the latest and greatest. The best way to keep track of open source LLMs is to check the [Open-source LLM leaderboard](https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard).\n",
261
+ "\n",
262
+ "To make inference faster, we will load the quantized version of the model:"
263
+ ]
264
+ },
265
+ {
266
+ "cell_type": "code",
267
+ "execution_count": null,
268
+ "metadata": {
269
+ "id": "L-ggaa763VRo"
270
+ },
271
+ "outputs": [],
272
+ "source": [
273
+ "import torch\n",
274
+ "from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig\n",
275
+ "\n",
276
+ "model_name = 'HuggingFaceH4/zephyr-7b-beta'\n",
277
+ "\n",
278
+ "bnb_config = BitsAndBytesConfig(\n",
279
+ " load_in_4bit=True,\n",
280
+ " bnb_4bit_use_double_quant=True,\n",
281
+ " bnb_4bit_quant_type=\"nf4\",\n",
282
+ " bnb_4bit_compute_dtype=torch.bfloat16\n",
283
+ ")\n",
284
+ "\n",
285
+ "model = AutoModelForCausalLM.from_pretrained(model_name, quantization_config=bnb_config)\n",
286
+ "tokenizer = AutoTokenizer.from_pretrained(model_name)"
287
+ ]
288
+ },
289
+ {
290
+ "cell_type": "markdown",
291
+ "metadata": {
292
+ "id": "hVNRJALyXYHG"
293
+ },
294
+ "source": [
295
+ "## Setup the LLM chain"
296
+ ]
297
+ },
298
+ {
299
+ "cell_type": "markdown",
300
+ "metadata": {
301
+ "id": "RUUNneJ1smhl"
302
+ },
303
+ "source": [
304
+ "Finally, we have all the pieces we need to set up the LLM chain.\n",
305
+ "\n",
306
+ "First, create a text_generation pipeline using the loaded model and its tokenizer.\n",
307
+ "\n",
308
+ "Next, create a prompt template - this should follow the format of the model, so if you substitute the model checkpoint, make sure to use the appropriate formatting."
309
+ ]
310
+ },
311
+ {
312
+ "cell_type": "code",
313
+ "execution_count": 15,
314
+ "metadata": {
315
+ "id": "cR0k1cRWz8Pm"
316
+ },
317
+ "outputs": [],
318
+ "source": [
319
+ "from langchain.llms import HuggingFacePipeline\n",
320
+ "from langchain.prompts import PromptTemplate\n",
321
+ "from transformers import pipeline\n",
322
+ "from langchain_core.output_parsers import StrOutputParser\n",
323
+ "\n",
324
+ "text_generation_pipeline = pipeline(\n",
325
+ " model=model,\n",
326
+ " tokenizer=tokenizer,\n",
327
+ " task=\"text-generation\",\n",
328
+ " temperature=0.2,\n",
329
+ " do_sample=True,\n",
330
+ " repetition_penalty=1.1,\n",
331
+ " return_full_text=True,\n",
332
+ " max_new_tokens=400,\n",
333
+ ")\n",
334
+ "\n",
335
+ "llm = HuggingFacePipeline(pipeline=text_generation_pipeline)\n",
336
+ "\n",
337
+ "prompt_template = \"\"\"\n",
338
+ "<|system|>\n",
339
+ "Answer the question based on your knowledge. Use the following context to help:\n",
340
+ "\n",
341
+ "{context}\n",
342
+ "\n",
343
+ "</s>\n",
344
+ "<|user|>\n",
345
+ "{question}\n",
346
+ "</s>\n",
347
+ "<|assistant|>\n",
348
+ "\n",
349
+ " \"\"\"\n",
350
+ "\n",
351
+ "prompt = PromptTemplate(\n",
352
+ " input_variables=[\"context\", \"question\"],\n",
353
+ " template=prompt_template,\n",
354
+ ")\n",
355
+ "\n",
356
+ "llm_chain = prompt | llm | StrOutputParser()"
357
+ ]
358
+ },
359
+ {
360
+ "cell_type": "markdown",
361
+ "metadata": {
362
+ "id": "l19UKq5HXfSp"
363
+ },
364
+ "source": [
365
+ "Note: _You can also use `tokenizer.apply_chat_template` to convert a list of messages (as dicts: `{'role': 'user', 'content': '(...)'}`) into a string with the appropriate chat format._\n",
366
+ "\n",
367
+ "\n",
368
+ "Finally, we need to combine the `llm_chain` with the retriever to create a RAG chain. We pass the original question through to the final generation step, as well as the retrieved context docs:"
369
+ ]
370
+ },
371
+ {
372
+ "cell_type": "code",
373
+ "execution_count": 17,
374
+ "metadata": {
375
+ "id": "_rI3YNp9Xl4s"
376
+ },
377
+ "outputs": [],
378
+ "source": [
379
+ "from langchain_core.runnables import RunnablePassthrough\n",
380
+ "\n",
381
+ "retriever = db.as_retriever()\n",
382
+ "\n",
383
+ "rag_chain = (\n",
384
+ " {\"context\": retriever, \"question\": RunnablePassthrough()}\n",
385
+ " | llm_chain\n",
386
+ ")\n"
387
+ ]
388
+ },
389
+ {
390
+ "cell_type": "markdown",
391
+ "metadata": {
392
+ "id": "UsCOhfDDXpaS"
393
+ },
394
+ "source": [
395
+ "## Compare the results\n",
396
+ "\n",
397
+ "Let's see the difference RAG makes in generating answers to the library-specific questions."
398
+ ]
399
+ },
400
+ {
401
+ "cell_type": "code",
402
+ "execution_count": 18,
403
+ "metadata": {
404
+ "id": "W7F07fQLXusU"
405
+ },
406
+ "outputs": [],
407
+ "source": [
408
+ "question = \"How do you combine multiple adapters?\""
409
+ ]
410
+ },
411
+ {
412
+ "cell_type": "markdown",
413
+ "metadata": {
414
+ "id": "KC0rJYU1x1ir"
415
+ },
416
+ "source": [
417
+ "First, let's see what kind of answer we can get with just the model itself, no context added:"
418
+ ]
419
+ },
420
+ {
421
+ "cell_type": "code",
422
+ "execution_count": 20,
423
+ "metadata": {
424
+ "colab": {
425
+ "base_uri": "https://localhost:8080/",
426
+ "height": 125
427
+ },
428
+ "id": "GYh-HG1l0De5",
429
+ "outputId": "277d8e89-ce9b-4e04-c11b-639ad2645759"
430
+ },
431
+ "outputs": [
432
+ {
433
+ "data": {
434
+ "application/vnd.google.colaboratory.intrinsic+json": {
435
+ "type": "string"
436
+ },
437
+ "text/plain": [
438
+ "\" To combine multiple adapters, you need to ensure that they are compatible with each other and the devices you want to connect. Here's how you can do it:\\n\\n1. Identify the adapters you need: Determine which adapters you require to connect the devices you want to use together. For example, if you want to connect a USB-C device to an HDMI monitor, you may need a USB-C to HDMI adapter and a USB-C to USB-A adapter (if your computer only has USB-A ports).\\n\\n2. Connect the first adapter: Plug in the first adapter into the device you want to connect. For instance, if you're connecting a USB-C laptop to an HDMI monitor, plug the USB-C to HDMI adapter into the laptop's USB-C port.\\n\\n3. Connect the second adapter: Next, connect the second adapter to the first one. In this case, connect the USB-C to USB-A adapter to the USB-C port of the USB-C to HDMI adapter.\\n\\n4. Connect the final device: Finally, connect the device you want to use to the second adapter. For example, connect the HDMI cable from the monitor to the HDMI port on the USB-C to HDMI adapter.\\n\\n5. Test the connection: Turn on both devices and check whether everything is working correctly. If necessary, adjust the settings on your devices to ensure optimal performance.\\n\\nBy combining multiple adapters, you can connect a variety of devices together, even if they don't have the same type of connector. Just be sure to choose adapters that are compatible with all the devices you want to connect and test the connection thoroughly before relying on it for critical tasks.\""
439
+ ]
440
+ },
441
+ "execution_count": 20,
442
+ "metadata": {},
443
+ "output_type": "execute_result"
444
+ }
445
+ ],
446
+ "source": [
447
+ "llm_chain.invoke({\"context\":\"\", \"question\": question})"
448
+ ]
449
+ },
450
+ {
451
+ "cell_type": "markdown",
452
+ "metadata": {
453
+ "id": "i-TIWr3wx9w8"
454
+ },
455
+ "source": [
456
+ "As you can see, the model interpreted the question as one about physical computer adapters, while in the context of PEFT, \"adapters\" refer to LoRA adapters.\n",
457
+ "Let's see if adding context from GitHub issues helps the model give a more relevant answer:"
458
+ ]
459
+ },
460
+ {
461
+ "cell_type": "code",
462
+ "execution_count": 21,
463
+ "metadata": {
464
+ "colab": {
465
+ "base_uri": "https://localhost:8080/",
466
+ "height": 125
467
+ },
468
+ "id": "FZpNA3o10H10",
469
+ "outputId": "31f9aed3-3dd7-4ff8-d1a8-866794fefe80"
470
+ },
471
+ "outputs": [
472
+ {
473
+ "data": {
474
+ "application/vnd.google.colaboratory.intrinsic+json": {
475
+ "type": "string"
476
+ },
477
+ "text/plain": [
478
+ "\" Based on the provided context, it seems that combining multiple adapters is still an open question in the community. Here are some possibilities:\\n\\n 1. Save the output from the base model and pass it to each adapter separately, as described in the first context snippet. This allows you to run multiple adapters simultaneously and reuse the output from the base model. However, this approach requires loading and running each adapter separately.\\n\\n 2. Export everything into a single PyTorch model, as suggested in the second context snippet. This would involve saving all the adapters and their weights into a single model, potentially making it larger and more complex. The advantage of this approach is that it would allow you to run all the adapters simultaneously without having to load and run them separately.\\n\\n 3. Merge multiple Lora adapters, as mentioned in the third context snippet. This involves adding multiple distinct, independent behaviors to a base model by merging multiple Lora adapters. It's not clear from the context how this would be done, but it suggests that there might be a recommended way of doing it.\\n\\n 4. Combine adapters through a specific architecture, as proposed in the fourth context snippet. This involves merging multiple adapters into a single architecture, potentially creating a more complex model with multiple behaviors. Again, it's not clear from the context how this would be done.\\n\\n Overall, combining multiple adapters is still an active area of research, and there doesn't seem to be a widely accepted solution yet. If you're interested in exploring this further, it might be worth reaching out to the Hugging Face community or checking out their documentation for more information.\""
479
+ ]
480
+ },
481
+ "execution_count": 21,
482
+ "metadata": {},
483
+ "output_type": "execute_result"
484
+ }
485
+ ],
486
+ "source": [
487
+ "rag_chain.invoke(question)"
488
+ ]
489
+ },
490
+ {
491
+ "cell_type": "markdown",
492
+ "metadata": {
493
+ "id": "hZQedZKSyrwO"
494
+ },
495
+ "source": [
496
+ "As we can see, the added context, really helps the exact same model, provide a much more relevant and informed answer to the library-specific question.\n",
497
+ "\n",
498
+ "Notably, combining multiple adapters for inference has been added to the library, and one can find this information in the documentation, so for the next iteration of this RAG it may be worth including documentation embeddings."
499
+ ]
500
+ }
501
+ ],
502
+ "metadata": {
503
+ "accelerator": "GPU",
504
+ "colab": {
505
+ "gpuType": "T4",
506
+ "provenance": []
507
+ },
508
+ "kernelspec": {
509
+ "display_name": "Python 3",
510
+ "name": "python3"
511
+ },
512
+ "language_info": {
513
+ "codemirror_mode": {
514
+ "name": "ipython",
515
+ "version": 3
516
+ },
517
+ "file_extension": ".py",
518
+ "mimetype": "text/x-python",
519
+ "name": "python",
520
+ "nbconvert_exporter": "python",
521
+ "pygments_lexer": "ipython3",
522
+ "version": "3.11.3"
523
+ }
524
+ },
525
+ "nbformat": 4,
526
+ "nbformat_minor": 0
527
+ }
src/notebooks/single_gpu.ipynb ADDED
@@ -0,0 +1,1129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {
6
+ "id": "FNdZ-kD0l78P"
7
+ },
8
+ "source": [
9
+ "---\n",
10
+ "title: Single GPU Fine-tuning\n",
11
+ "---\n",
12
+ "\n",
13
+ "# Fine-tuning a Code LLM on Custom Code on a single GPU\n",
14
+ "\n",
15
+ "_Authored by: [Maria Khalusova](https://github.com/MKhalusova)_\n",
16
+ "\n",
17
+ "Publicly available code LLMs such as Codex, StarCoder, and Code Llama are great at generating code that adheres to general programming principles and syntax, but they may not align with an organization's internal conventions, or be aware of proprietary libraries.\n",
18
+ "\n",
19
+ "In this notebook, we'll see show how you can fine-tune a code LLM on private code bases to enhance its contextual awareness and improve a model's usefulness to your organization's needs. Since the code LLMs are quite large, fine-tuning them in a traditional manner can be resource-draining. Worry not! We will show how you can optimize fine-tuning to fit on a single GPU.\n",
20
+ "\n",
21
+ "\n",
22
+ "## Dataset\n",
23
+ "\n",
24
+ "For this example, we picked the top 10 Hugging Face public repositories on GitHub. We have excluded non-code files from the data, such as images, audio files, presentations, and so on. For Jupyter notebooks, we've kept only cells containing code. The resulting code is stored as a dataset that you can find on the Hugging Face Hub under [`smangrul/hf-stack-v1`](https://huggingface.co/datasets/smangrul/hf-stack-v1). It contains repo id, file path, and file content.\n",
25
+ "\n",
26
+ "\n",
27
+ "## Model\n",
28
+ "\n",
29
+ "We'll finetune [`bigcode/starcoderbase-1b`](https://huggingface.co/bigcode/starcoderbase-1b), which is a 1B parameter model trained on 80+ programming languages. This is a gated model, so if you plan to run this notebook with this exact model, you'll need to gain access to it on the model's page. Log in to your Hugging Face account to do so:"
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "code",
34
+ "execution_count": null,
35
+ "metadata": {
36
+ "id": "bPlCJYDK6vrF"
37
+ },
38
+ "outputs": [],
39
+ "source": [
40
+ "from huggingface_hub import notebook_login\n",
41
+ "\n",
42
+ "notebook_login()"
43
+ ]
44
+ },
45
+ {
46
+ "cell_type": "markdown",
47
+ "metadata": {
48
+ "id": "WMVe_c8q43Qo"
49
+ },
50
+ "source": [
51
+ "To get started, let's install all the necessary libraries. As you can see, in addition to `transformers` and `datasets`, we'll be using `peft`, `bitsandbytes`, and `flash-attn` to optimize the training.\n",
52
+ "\n",
53
+ "By employing parameter-efficient training techniques, we can run this notebook on a single A100 High-RAM GPU."
54
+ ]
55
+ },
56
+ {
57
+ "cell_type": "code",
58
+ "execution_count": null,
59
+ "metadata": {
60
+ "id": "Fp7i8WMCjKJG"
61
+ },
62
+ "outputs": [],
63
+ "source": [
64
+ "!pip install -q transformers datasets peft bitsandbytes flash-attn"
65
+ ]
66
+ },
67
+ {
68
+ "cell_type": "markdown",
69
+ "metadata": {
70
+ "id": "16EdABzt3_Ig"
71
+ },
72
+ "source": [
73
+ "Let's define some variables now. Feel free to play with these."
74
+ ]
75
+ },
76
+ {
77
+ "cell_type": "code",
78
+ "execution_count": null,
79
+ "metadata": {
80
+ "id": "hru3G-CLmqis"
81
+ },
82
+ "outputs": [],
83
+ "source": [
84
+ "MODEL=\"bigcode/starcoderbase-1b\" # Model checkpoint on the Hugging Face Hub\n",
85
+ "DATASET=\"smangrul/hf-stack-v1\" # Dataset on the Hugging Face Hub\n",
86
+ "DATA_COLUMN=\"content\" # Column name containing the code content\n",
87
+ "\n",
88
+ "SEQ_LENGTH=2048 # Sequence length\n",
89
+ "\n",
90
+ "# Training arguments\n",
91
+ "MAX_STEPS=2000 # max_steps\n",
92
+ "BATCH_SIZE=16 # batch_size\n",
93
+ "GR_ACC_STEPS=1 # gradient_accumulation_steps\n",
94
+ "LR=5e-4 # learning_rate\n",
95
+ "LR_SCHEDULER_TYPE=\"cosine\" # lr_scheduler_type\n",
96
+ "WEIGHT_DECAY=0.01 # weight_decay\n",
97
+ "NUM_WARMUP_STEPS=30 # num_warmup_steps\n",
98
+ "EVAL_FREQ=100 # eval_freq\n",
99
+ "SAVE_FREQ=100 # save_freq\n",
100
+ "LOG_FREQ=25 # log_freq\n",
101
+ "OUTPUT_DIR=\"peft-starcoder-lora-a100\" # output_dir\n",
102
+ "BF16=True # bf16\n",
103
+ "FP16=False # no_fp16\n",
104
+ "\n",
105
+ "# FIM trasformations arguments\n",
106
+ "FIM_RATE=0.5 # fim_rate\n",
107
+ "FIM_SPM_RATE=0.5 # fim_spm_rate\n",
108
+ "\n",
109
+ "# LORA\n",
110
+ "LORA_R=8 # lora_r\n",
111
+ "LORA_ALPHA=32 # lora_alpha\n",
112
+ "LORA_DROPOUT=0.0 # lora_dropout\n",
113
+ "LORA_TARGET_MODULES=\"c_proj,c_attn,q_attn,c_fc,c_proj\" # lora_target_modules\n",
114
+ "\n",
115
+ "# bitsandbytes config\n",
116
+ "USE_NESTED_QUANT=True # use_nested_quant\n",
117
+ "BNB_4BIT_COMPUTE_DTYPE=\"bfloat16\"# bnb_4bit_compute_dtype\n",
118
+ "\n",
119
+ "SEED=0"
120
+ ]
121
+ },
122
+ {
123
+ "cell_type": "code",
124
+ "execution_count": null,
125
+ "metadata": {
126
+ "id": "FyZSXTbJrcnC"
127
+ },
128
+ "outputs": [],
129
+ "source": [
130
+ "from transformers import (\n",
131
+ " AutoModelForCausalLM,\n",
132
+ " AutoTokenizer,\n",
133
+ " Trainer,\n",
134
+ " TrainingArguments,\n",
135
+ " logging,\n",
136
+ " set_seed,\n",
137
+ " BitsAndBytesConfig,\n",
138
+ ")\n",
139
+ "\n",
140
+ "set_seed(SEED)"
141
+ ]
142
+ },
143
+ {
144
+ "cell_type": "markdown",
145
+ "metadata": {
146
+ "id": "pO7F5L5AtKo1"
147
+ },
148
+ "source": [
149
+ "## Prepare the data"
150
+ ]
151
+ },
152
+ {
153
+ "cell_type": "markdown",
154
+ "metadata": {
155
+ "id": "1LmrIZqP0oUE"
156
+ },
157
+ "source": [
158
+ "Begin by loading the data. As the dataset is likely to be quite large, make sure to enable the streaming mode. Streaming allows us to load the data progressively as we iterate over the dataset instead of downloading the whole dataset at once.\n",
159
+ "\n",
160
+ "We'll reserve the first 4000 examples as the validation set, and everything else will be the training data."
161
+ ]
162
+ },
163
+ {
164
+ "cell_type": "code",
165
+ "execution_count": null,
166
+ "metadata": {
167
+ "id": "4oJZvZb-1J88"
168
+ },
169
+ "outputs": [],
170
+ "source": [
171
+ "from datasets import load_dataset\n",
172
+ "import torch\n",
173
+ "from tqdm import tqdm\n",
174
+ "\n",
175
+ "\n",
176
+ "dataset = load_dataset(\n",
177
+ " DATASET,\n",
178
+ " data_dir=\"data\",\n",
179
+ " split=\"train\",\n",
180
+ " streaming=True,\n",
181
+ ")\n",
182
+ "\n",
183
+ "valid_data = dataset.take(4000)\n",
184
+ "train_data = dataset.skip(4000)\n",
185
+ "train_data = train_data.shuffle(buffer_size=5000, seed=SEED)"
186
+ ]
187
+ },
188
+ {
189
+ "cell_type": "markdown",
190
+ "metadata": {
191
+ "id": "sLQ8t0LM2GR6"
192
+ },
193
+ "source": [
194
+ "At this step, the dataset still contains raw data with code of arbitraty length. For training, we need inputs of fixed length. Let's create an Iterable dataset that would return constant-length chunks of tokens from a stream of text files.\n",
195
+ "\n",
196
+ "First, let's estimate the average number of characters per token in the dataset, which will help us later estimate the number of tokens in the text buffer later. By default, we'll only take 400 examples (`nb_examples`) from the dataset. Using only a subset of the entire dataset will reduce computational cost while still providing a reasonable estimate of the overall character-to-token ratio."
197
+ ]
198
+ },
199
+ {
200
+ "cell_type": "code",
201
+ "execution_count": null,
202
+ "metadata": {
203
+ "colab": {
204
+ "base_uri": "https://localhost:8080/"
205
+ },
206
+ "id": "KCiAvydztNsu",
207
+ "outputId": "cabf7fd0-a922-4371-cbc6-60ee99ef7469"
208
+ },
209
+ "outputs": [
210
+ {
211
+ "name": "stderr",
212
+ "output_type": "stream",
213
+ "text": [
214
+ "100%|██████████| 400/400 [00:10<00:00, 39.87it/s] "
215
+ ]
216
+ },
217
+ {
218
+ "name": "stdout",
219
+ "output_type": "stream",
220
+ "text": [
221
+ "The character to token ratio of the dataset is: 2.43\n"
222
+ ]
223
+ },
224
+ {
225
+ "name": "stderr",
226
+ "output_type": "stream",
227
+ "text": [
228
+ "\n"
229
+ ]
230
+ }
231
+ ],
232
+ "source": [
233
+ "tokenizer = AutoTokenizer.from_pretrained(MODEL, trust_remote_code=True)\n",
234
+ "\n",
235
+ "def chars_token_ratio(dataset, tokenizer, data_column, nb_examples=400):\n",
236
+ " \"\"\"\n",
237
+ " Estimate the average number of characters per token in the dataset.\n",
238
+ " \"\"\"\n",
239
+ "\n",
240
+ " total_characters, total_tokens = 0, 0\n",
241
+ " for _, example in tqdm(zip(range(nb_examples), iter(dataset)), total=nb_examples):\n",
242
+ " total_characters += len(example[data_column])\n",
243
+ " total_tokens += len(tokenizer(example[data_column]).tokens())\n",
244
+ "\n",
245
+ " return total_characters / total_tokens\n",
246
+ "\n",
247
+ "\n",
248
+ "chars_per_token = chars_token_ratio(train_data, tokenizer, DATA_COLUMN)\n",
249
+ "print(f\"The character to token ratio of the dataset is: {chars_per_token:.2f}\")"
250
+ ]
251
+ },
252
+ {
253
+ "cell_type": "markdown",
254
+ "metadata": {
255
+ "id": "6F13VGobB3Ma"
256
+ },
257
+ "source": [
258
+ "The character-to-token ratio can also be used as an indicator of the quality of text tokenization. For instance, a character-to-token ratio of 1.0 would mean that each character is represented with a token, which is not very meaningful. This would indicate poor tokenization. In standard English text, one token is typically equivalent to approximately four characters, meaning the character-to-token ratio is around 4.0. We can expect a lower ratio in the code dataset, but generally speaking, a number between 2.0 and 3.5 can be considered good enough."
259
+ ]
260
+ },
261
+ {
262
+ "cell_type": "markdown",
263
+ "metadata": {
264
+ "id": "rcwYFRPpwxea"
265
+ },
266
+ "source": [
267
+ "**Optional FIM transformations**\n",
268
+ "\n",
269
+ "\n",
270
+ "Autoregressive language models typically generate sequences from left to right. By applying the FIM transformations, the model can also learn to infill text. Check out [\"Efficient Training of Language Models to Fill in the Middle\" paper](https://arxiv.org/pdf/2207.14255.pdf) to learn more about the technique.\n",
271
+ "We'll define the FIM transformations here and will use them when creating the Iterable Dataset. However, if you want to omit transformations, feel free to set `fim_rate` to 0."
272
+ ]
273
+ },
274
+ {
275
+ "cell_type": "code",
276
+ "execution_count": null,
277
+ "metadata": {
278
+ "id": "zmejYvEKw1E-"
279
+ },
280
+ "outputs": [],
281
+ "source": [
282
+ "import functools\n",
283
+ "import numpy as np\n",
284
+ "\n",
285
+ "\n",
286
+ "# Helper function to get token ids of the special tokens for prefix, suffix and middle for FIM transformations.\n",
287
+ "@functools.lru_cache(maxsize=None)\n",
288
+ "def get_fim_token_ids(tokenizer):\n",
289
+ " try:\n",
290
+ " FIM_PREFIX, FIM_MIDDLE, FIM_SUFFIX, FIM_PAD = tokenizer.special_tokens_map[\"additional_special_tokens\"][1:5]\n",
291
+ " suffix_tok_id, prefix_tok_id, middle_tok_id, pad_tok_id = (\n",
292
+ " tokenizer.vocab[tok] for tok in [FIM_SUFFIX, FIM_PREFIX, FIM_MIDDLE, FIM_PAD]\n",
293
+ " )\n",
294
+ " except KeyError:\n",
295
+ " suffix_tok_id, prefix_tok_id, middle_tok_id, pad_tok_id = None, None, None, None\n",
296
+ " return suffix_tok_id, prefix_tok_id, middle_tok_id, pad_tok_id\n",
297
+ "\n",
298
+ "\n",
299
+ "## Adapted from https://github.com/bigcode-project/Megatron-LM/blob/6c4bf908df8fd86b4977f54bf5b8bd4b521003d1/megatron/data/gpt_dataset.py\n",
300
+ "def permute(\n",
301
+ " sample,\n",
302
+ " np_rng,\n",
303
+ " suffix_tok_id,\n",
304
+ " prefix_tok_id,\n",
305
+ " middle_tok_id,\n",
306
+ " pad_tok_id,\n",
307
+ " fim_rate=0.5,\n",
308
+ " fim_spm_rate=0.5,\n",
309
+ " truncate_or_pad=False,\n",
310
+ "):\n",
311
+ " \"\"\"\n",
312
+ " Take in a sample (list of tokens) and perform a FIM transformation on it with a probability of fim_rate, using two FIM modes:\n",
313
+ " PSM and SPM (with a probability of fim_spm_rate).\n",
314
+ " \"\"\"\n",
315
+ "\n",
316
+ " # The if condition will trigger with the probability of fim_rate\n",
317
+ " # This means FIM transformations will apply to samples with a probability of fim_rate\n",
318
+ " if np_rng.binomial(1, fim_rate):\n",
319
+ "\n",
320
+ " # Split the sample into prefix, middle, and suffix, based on randomly generated indices stored in the boundaries list.\n",
321
+ " boundaries = list(np_rng.randint(low=0, high=len(sample) + 1, size=2))\n",
322
+ " boundaries.sort()\n",
323
+ "\n",
324
+ " prefix = np.array(sample[: boundaries[0]], dtype=np.int64)\n",
325
+ " middle = np.array(sample[boundaries[0] : boundaries[1]], dtype=np.int64)\n",
326
+ " suffix = np.array(sample[boundaries[1] :], dtype=np.int64)\n",
327
+ "\n",
328
+ " if truncate_or_pad:\n",
329
+ " # calculate the new total length of the sample, taking into account tokens indicating prefix, middle, and suffix\n",
330
+ " new_length = suffix.shape[0] + prefix.shape[0] + middle.shape[0] + 3\n",
331
+ " diff = new_length - len(sample)\n",
332
+ "\n",
333
+ " # trancate or pad if there's a difference in length between the new length and the original\n",
334
+ " if diff > 0:\n",
335
+ " if suffix.shape[0] <= diff:\n",
336
+ " return sample, np_rng\n",
337
+ " suffix = suffix[: suffix.shape[0] - diff]\n",
338
+ " elif diff < 0:\n",
339
+ " suffix = np.concatenate([suffix, np.full((-1 * diff), pad_tok_id)])\n",
340
+ "\n",
341
+ " # With the probability of fim_spm_rateapply SPM variant of FIM transformations\n",
342
+ " # SPM: suffix, prefix, middle\n",
343
+ " if np_rng.binomial(1, fim_spm_rate):\n",
344
+ " new_sample = np.concatenate(\n",
345
+ " [\n",
346
+ " [prefix_tok_id, suffix_tok_id],\n",
347
+ " suffix,\n",
348
+ " [middle_tok_id],\n",
349
+ " prefix,\n",
350
+ " middle,\n",
351
+ " ]\n",
352
+ " )\n",
353
+ " # Otherwise, apply the PSM variant of FIM transformations\n",
354
+ " # PSM: prefix, suffix, middle\n",
355
+ " else:\n",
356
+ "\n",
357
+ " new_sample = np.concatenate(\n",
358
+ " [\n",
359
+ " [prefix_tok_id],\n",
360
+ " prefix,\n",
361
+ " [suffix_tok_id],\n",
362
+ " suffix,\n",
363
+ " [middle_tok_id],\n",
364
+ " middle,\n",
365
+ " ]\n",
366
+ " )\n",
367
+ " else:\n",
368
+ " # don't apply FIM transformations\n",
369
+ " new_sample = sample\n",
370
+ "\n",
371
+ " return list(new_sample), np_rng\n"
372
+ ]
373
+ },
374
+ {
375
+ "cell_type": "markdown",
376
+ "metadata": {
377
+ "id": "AwW5FviD9xBH"
378
+ },
379
+ "source": [
380
+ "Let's define the `ConstantLengthDataset`, an Iterable dataset that will return constant-length chunks of tokens. To do so, we'll read a buffer of text from the original dataset until we hit the size limits and then apply tokenizer to convert the raw text into tokenized inputs. Optionally, we'll perform FIM transformations on some sequences (the proportion of sequences affected is controlled by `fim_rate`).\n",
381
+ "\n",
382
+ "Once defined, we can create instances of the `ConstantLengthDataset` from both training and validation data."
383
+ ]
384
+ },
385
+ {
386
+ "cell_type": "code",
387
+ "execution_count": null,
388
+ "metadata": {
389
+ "id": "AgDW-692wzOl"
390
+ },
391
+ "outputs": [],
392
+ "source": [
393
+ "from torch.utils.data import IterableDataset\n",
394
+ "from torch.utils.data.dataloader import DataLoader\n",
395
+ "import random\n",
396
+ "\n",
397
+ "# Create an Iterable dataset that returns constant-length chunks of tokens from a stream of text files.\n",
398
+ "\n",
399
+ "class ConstantLengthDataset(IterableDataset):\n",
400
+ " \"\"\"\n",
401
+ " Iterable dataset that returns constant length chunks of tokens from stream of text files.\n",
402
+ " Args:\n",
403
+ " tokenizer (Tokenizer): The processor used for proccessing the data.\n",
404
+ " dataset (dataset.Dataset): Dataset with text files.\n",
405
+ " infinite (bool): If True the iterator is reset after dataset reaches end else stops.\n",
406
+ " seq_length (int): Length of token sequences to return.\n",
407
+ " num_of_sequences (int): Number of token sequences to keep in buffer.\n",
408
+ " chars_per_token (int): Number of characters per token used to estimate number of tokens in text buffer.\n",
409
+ " fim_rate (float): Rate (0.0 to 1.0) that sample will be permuted with FIM.\n",
410
+ " fim_spm_rate (float): Rate (0.0 to 1.0) of FIM permuations that will use SPM.\n",
411
+ " seed (int): Seed for random number generator.\n",
412
+ " \"\"\"\n",
413
+ "\n",
414
+ " def __init__(\n",
415
+ " self,\n",
416
+ " tokenizer,\n",
417
+ " dataset,\n",
418
+ " infinite=False,\n",
419
+ " seq_length=1024,\n",
420
+ " num_of_sequences=1024,\n",
421
+ " chars_per_token=3.6,\n",
422
+ " content_field=\"content\",\n",
423
+ " fim_rate=0.5,\n",
424
+ " fim_spm_rate=0.5,\n",
425
+ " seed=0,\n",
426
+ " ):\n",
427
+ " self.tokenizer = tokenizer\n",
428
+ " self.concat_token_id = tokenizer.eos_token_id\n",
429
+ " self.dataset = dataset\n",
430
+ " self.seq_length = seq_length\n",
431
+ " self.infinite = infinite\n",
432
+ " self.current_size = 0\n",
433
+ " self.max_buffer_size = seq_length * chars_per_token * num_of_sequences\n",
434
+ " self.content_field = content_field\n",
435
+ " self.fim_rate = fim_rate\n",
436
+ " self.fim_spm_rate = fim_spm_rate\n",
437
+ " self.seed = seed\n",
438
+ "\n",
439
+ " (\n",
440
+ " self.suffix_tok_id,\n",
441
+ " self.prefix_tok_id,\n",
442
+ " self.middle_tok_id,\n",
443
+ " self.pad_tok_id,\n",
444
+ " ) = get_fim_token_ids(self.tokenizer)\n",
445
+ " if not self.suffix_tok_id and self.fim_rate > 0:\n",
446
+ " print(\"FIM is not supported by tokenizer, disabling FIM\")\n",
447
+ " self.fim_rate = 0\n",
448
+ "\n",
449
+ " def __iter__(self):\n",
450
+ " iterator = iter(self.dataset)\n",
451
+ " more_examples = True\n",
452
+ " np_rng = np.random.RandomState(seed=self.seed)\n",
453
+ " while more_examples:\n",
454
+ " buffer, buffer_len = [], 0\n",
455
+ " while True:\n",
456
+ " if buffer_len >= self.max_buffer_size:\n",
457
+ " break\n",
458
+ " try:\n",
459
+ " buffer.append(next(iterator)[self.content_field])\n",
460
+ " buffer_len += len(buffer[-1])\n",
461
+ " except StopIteration:\n",
462
+ " if self.infinite:\n",
463
+ " iterator = iter(self.dataset)\n",
464
+ " else:\n",
465
+ " more_examples = False\n",
466
+ " break\n",
467
+ " tokenized_inputs = self.tokenizer(buffer, truncation=False)[\"input_ids\"]\n",
468
+ " all_token_ids = []\n",
469
+ "\n",
470
+ " for tokenized_input in tokenized_inputs:\n",
471
+ " # optionally do FIM permutations\n",
472
+ " if self.fim_rate > 0:\n",
473
+ " tokenized_input, np_rng = permute(\n",
474
+ " tokenized_input,\n",
475
+ " np_rng,\n",
476
+ " self.suffix_tok_id,\n",
477
+ " self.prefix_tok_id,\n",
478
+ " self.middle_tok_id,\n",
479
+ " self.pad_tok_id,\n",
480
+ " fim_rate=self.fim_rate,\n",
481
+ " fim_spm_rate=self.fim_spm_rate,\n",
482
+ " truncate_or_pad=False,\n",
483
+ " )\n",
484
+ "\n",
485
+ " all_token_ids.extend(tokenized_input + [self.concat_token_id])\n",
486
+ " examples = []\n",
487
+ " for i in range(0, len(all_token_ids), self.seq_length):\n",
488
+ " input_ids = all_token_ids[i : i + self.seq_length]\n",
489
+ " if len(input_ids) == self.seq_length:\n",
490
+ " examples.append(input_ids)\n",
491
+ " random.shuffle(examples)\n",
492
+ " for example in examples:\n",
493
+ " self.current_size += 1\n",
494
+ " yield {\n",
495
+ " \"input_ids\": torch.LongTensor(example),\n",
496
+ " \"labels\": torch.LongTensor(example),\n",
497
+ " }\n",
498
+ "\n",
499
+ "\n",
500
+ "train_dataset = ConstantLengthDataset(\n",
501
+ " tokenizer,\n",
502
+ " train_data,\n",
503
+ " infinite=True,\n",
504
+ " seq_length=SEQ_LENGTH,\n",
505
+ " chars_per_token=chars_per_token,\n",
506
+ " content_field=DATA_COLUMN,\n",
507
+ " fim_rate=FIM_RATE,\n",
508
+ " fim_spm_rate=FIM_SPM_RATE,\n",
509
+ " seed=SEED,\n",
510
+ ")\n",
511
+ "eval_dataset = ConstantLengthDataset(\n",
512
+ " tokenizer,\n",
513
+ " valid_data,\n",
514
+ " infinite=False,\n",
515
+ " seq_length=SEQ_LENGTH,\n",
516
+ " chars_per_token=chars_per_token,\n",
517
+ " content_field=DATA_COLUMN,\n",
518
+ " fim_rate=FIM_RATE,\n",
519
+ " fim_spm_rate=FIM_SPM_RATE,\n",
520
+ " seed=SEED,\n",
521
+ ")"
522
+ ]
523
+ },
524
+ {
525
+ "cell_type": "markdown",
526
+ "metadata": {
527
+ "id": "rxev1sk6tRW9"
528
+ },
529
+ "source": [
530
+ "## Prepare the model"
531
+ ]
532
+ },
533
+ {
534
+ "cell_type": "markdown",
535
+ "metadata": {
536
+ "id": "UCtWV-U42Eq_"
537
+ },
538
+ "source": [
539
+ "Now that the data is prepared, it's time to load the model! We're going to load the quantized version of the model.\n",
540
+ "\n",
541
+ "This will allow us to reduce memory usage, as quantization represents data with fewer bits. We'll use the `bitsandbytes` library to quantize the model, as it has a nice integration with `transformers`. All we need to do is define a `bitsandbytes` config, and then use it when loading the model.\n",
542
+ "\n",
543
+ "There are different variants of 4bit quantization, but generally, we recommend using NF4 quantization for better performance (`bnb_4bit_quant_type=\"nf4\"`).\n",
544
+ "\n",
545
+ "The `bnb_4bit_use_double_quant` option adds a second quantization after the first one to save an additional 0.4 bits per parameter.\n",
546
+ "\n",
547
+ "To learn more about quantization, check out the [\"Making LLMs even more accessible with bitsandbytes, 4-bit quantization and QLoRA\" blog post](https://huggingface.co/blog/4bit-transformers-bitsandbytes).\n",
548
+ "\n",
549
+ "Once defined, pass the config to the `from_pretrained` method to load the quantized version of the model."
550
+ ]
551
+ },
552
+ {
553
+ "cell_type": "code",
554
+ "execution_count": null,
555
+ "metadata": {
556
+ "id": "XuwoX6U2DUvK"
557
+ },
558
+ "outputs": [],
559
+ "source": [
560
+ "from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training\n",
561
+ "from peft.tuners.lora import LoraLayer\n",
562
+ "\n",
563
+ "load_in_8bit = False\n",
564
+ "\n",
565
+ "# 4-bit quantization\n",
566
+ "compute_dtype = getattr(torch, BNB_4BIT_COMPUTE_DTYPE)\n",
567
+ "\n",
568
+ "bnb_config = BitsAndBytesConfig(\n",
569
+ " load_in_4bit=True,\n",
570
+ " bnb_4bit_quant_type=\"nf4\",\n",
571
+ " bnb_4bit_compute_dtype=compute_dtype,\n",
572
+ " bnb_4bit_use_double_quant=USE_NESTED_QUANT,\n",
573
+ ")\n",
574
+ "\n",
575
+ "device_map = {\"\": 0}\n",
576
+ "\n",
577
+ "model = AutoModelForCausalLM.from_pretrained(\n",
578
+ " MODEL,\n",
579
+ " load_in_8bit=load_in_8bit,\n",
580
+ " quantization_config=bnb_config,\n",
581
+ " device_map=device_map,\n",
582
+ " use_cache=False, # We will be using gradient checkpointing\n",
583
+ " trust_remote_code=True,\n",
584
+ " use_flash_attention_2=True,\n",
585
+ ")\n"
586
+ ]
587
+ },
588
+ {
589
+ "cell_type": "markdown",
590
+ "metadata": {
591
+ "id": "bO9e2FV8D8ZF"
592
+ },
593
+ "source": [
594
+ "When using a quantized model for training, you need to call the `prepare_model_for_kbit_training()` function to preprocess the quantized model for training."
595
+ ]
596
+ },
597
+ {
598
+ "cell_type": "code",
599
+ "execution_count": null,
600
+ "metadata": {
601
+ "id": "Qb_eB4xzEDBk"
602
+ },
603
+ "outputs": [],
604
+ "source": [
605
+ "model = prepare_model_for_kbit_training(model)"
606
+ ]
607
+ },
608
+ {
609
+ "cell_type": "markdown",
610
+ "metadata": {
611
+ "id": "lmnLjPZpDVtg"
612
+ },
613
+ "source": [
614
+ "Now that the quantized model is ready, we can set up a LoRA configuration. LoRA makes fine-tuning more efficient by drastically reducing the number of trainable parameters.\n",
615
+ "\n",
616
+ "To train a model using LoRA technique, we need to wrap the base model as a `PeftModel`. This involves definign LoRA configuration with `LoraConfig`, and wrapping the original model with `get_peft_model()` using the `LoraConfig`.\n",
617
+ "\n",
618
+ "To learn more about LoRA and its parameters, refer to [PEFT documentation](https://huggingface.co/docs/peft/conceptual_guides/lora)."
619
+ ]
620
+ },
621
+ {
622
+ "cell_type": "code",
623
+ "execution_count": null,
624
+ "metadata": {
625
+ "colab": {
626
+ "base_uri": "https://localhost:8080/"
627
+ },
628
+ "id": "_pAUU2FR2Gey",
629
+ "outputId": "63328c2b-e693-49b1-ce0a-3ca8722f852a"
630
+ },
631
+ "outputs": [
632
+ {
633
+ "name": "stdout",
634
+ "output_type": "stream",
635
+ "text": [
636
+ "trainable params: 5,554,176 || all params: 1,142,761,472 || trainable%: 0.4860310866343243\n"
637
+ ]
638
+ }
639
+ ],
640
+ "source": [
641
+ "# Set up lora\n",
642
+ "peft_config = LoraConfig(\n",
643
+ " lora_alpha=LORA_ALPHA,\n",
644
+ " lora_dropout=LORA_DROPOUT,\n",
645
+ " r=LORA_R,\n",
646
+ " bias=\"none\",\n",
647
+ " task_type=\"CAUSAL_LM\",\n",
648
+ " target_modules=LORA_TARGET_MODULES.split(\",\"),\n",
649
+ ")\n",
650
+ "\n",
651
+ "model = get_peft_model(model, peft_config)\n",
652
+ "model.print_trainable_parameters()"
653
+ ]
654
+ },
655
+ {
656
+ "cell_type": "markdown",
657
+ "metadata": {
658
+ "id": "tHe7AElXzXVV"
659
+ },
660
+ "source": [
661
+ "As you can see, by applying LoRA technique we will now need to train less than 1% of the parameters."
662
+ ]
663
+ },
664
+ {
665
+ "cell_type": "markdown",
666
+ "metadata": {
667
+ "id": "T_CqVydc40IM"
668
+ },
669
+ "source": [
670
+ "## Train the model"
671
+ ]
672
+ },
673
+ {
674
+ "cell_type": "markdown",
675
+ "metadata": {
676
+ "id": "Q_iN2khjrbD3"
677
+ },
678
+ "source": [
679
+ "Now that we have prepared the data, and optimized the model, we are ready to bring everything together to start the training.\n",
680
+ "\n",
681
+ "To instantiate a `Trainer`, you need to define the training configuration. The most important is the `TrainingArguments`, which is a class that contains all the attributes to configure the training.\n",
682
+ "\n",
683
+ "These are similar to any other kind of model training you may run, so we won't go into detail here."
684
+ ]
685
+ },
686
+ {
687
+ "cell_type": "code",
688
+ "execution_count": null,
689
+ "metadata": {
690
+ "id": "65QHS8l1tKQe"
691
+ },
692
+ "outputs": [],
693
+ "source": [
694
+ "train_data.start_iteration = 0\n",
695
+ "\n",
696
+ "\n",
697
+ "training_args = TrainingArguments(\n",
698
+ " output_dir=f\"Your_HF_username/{OUTPUT_DIR}\",\n",
699
+ " dataloader_drop_last=True,\n",
700
+ " evaluation_strategy=\"steps\",\n",
701
+ " save_strategy=\"steps\",\n",
702
+ " max_steps=MAX_STEPS,\n",
703
+ " eval_steps=EVAL_FREQ,\n",
704
+ " save_steps=SAVE_FREQ,\n",
705
+ " logging_steps=LOG_FREQ,\n",
706
+ " per_device_train_batch_size=BATCH_SIZE,\n",
707
+ " per_device_eval_batch_size=BATCH_SIZE,\n",
708
+ " learning_rate=LR,\n",
709
+ " lr_scheduler_type=LR_SCHEDULER_TYPE,\n",
710
+ " warmup_steps=NUM_WARMUP_STEPS,\n",
711
+ " gradient_accumulation_steps=GR_ACC_STEPS,\n",
712
+ " gradient_checkpointing=True,\n",
713
+ " fp16=FP16,\n",
714
+ " bf16=BF16,\n",
715
+ " weight_decay=WEIGHT_DECAY,\n",
716
+ " push_to_hub=True,\n",
717
+ " include_tokens_per_second=True,\n",
718
+ ")\n"
719
+ ]
720
+ },
721
+ {
722
+ "cell_type": "markdown",
723
+ "metadata": {
724
+ "id": "kB_fLRex09ut"
725
+ },
726
+ "source": [
727
+ "As a final step, instantiate the `Trainer` and call the `train` method. "
728
+ ]
729
+ },
730
+ {
731
+ "cell_type": "code",
732
+ "execution_count": null,
733
+ "metadata": {
734
+ "colab": {
735
+ "base_uri": "https://localhost:8080/",
736
+ "height": 1000
737
+ },
738
+ "id": "rS3nVwhUC69O",
739
+ "outputId": "61a5bdb2-b7d0-4aed-8290-4bf20c2ccd38"
740
+ },
741
+ "outputs": [
742
+ {
743
+ "name": "stdout",
744
+ "output_type": "stream",
745
+ "text": [
746
+ "Training...\n"
747
+ ]
748
+ },
749
+ {
750
+ "data": {
751
+ "text/html": [
752
+ "\n",
753
+ " <div>\n",
754
+ " \n",
755
+ " <progress value='2000' max='2000' style='width:300px; height:20px; vertical-align: middle;'></progress>\n",
756
+ " [2000/2000 4:16:10, Epoch 1/9223372036854775807]\n",
757
+ " </div>\n",
758
+ " <table border=\"1\" class=\"dataframe\">\n",
759
+ " <thead>\n",
760
+ " <tr style=\"text-align: left;\">\n",
761
+ " <th>Step</th>\n",
762
+ " <th>Training Loss</th>\n",
763
+ " <th>Validation Loss</th>\n",
764
+ " </tr>\n",
765
+ " </thead>\n",
766
+ " <tbody>\n",
767
+ " <tr>\n",
768
+ " <td>100</td>\n",
769
+ " <td>5.524600</td>\n",
770
+ " <td>7.456872</td>\n",
771
+ " </tr>\n",
772
+ " <tr>\n",
773
+ " <td>200</td>\n",
774
+ " <td>5.617800</td>\n",
775
+ " <td>7.262190</td>\n",
776
+ " </tr>\n",
777
+ " <tr>\n",
778
+ " <td>300</td>\n",
779
+ " <td>5.129100</td>\n",
780
+ " <td>6.410039</td>\n",
781
+ " </tr>\n",
782
+ " <tr>\n",
783
+ " <td>400</td>\n",
784
+ " <td>5.052200</td>\n",
785
+ " <td>6.306774</td>\n",
786
+ " </tr>\n",
787
+ " <tr>\n",
788
+ " <td>500</td>\n",
789
+ " <td>5.202900</td>\n",
790
+ " <td>6.117062</td>\n",
791
+ " </tr>\n",
792
+ " <tr>\n",
793
+ " <td>600</td>\n",
794
+ " <td>4.654100</td>\n",
795
+ " <td>6.018349</td>\n",
796
+ " </tr>\n",
797
+ " <tr>\n",
798
+ " <td>700</td>\n",
799
+ " <td>5.100200</td>\n",
800
+ " <td>6.000355</td>\n",
801
+ " </tr>\n",
802
+ " <tr>\n",
803
+ " <td>800</td>\n",
804
+ " <td>5.049800</td>\n",
805
+ " <td>5.889457</td>\n",
806
+ " </tr>\n",
807
+ " <tr>\n",
808
+ " <td>900</td>\n",
809
+ " <td>4.541200</td>\n",
810
+ " <td>5.813823</td>\n",
811
+ " </tr>\n",
812
+ " <tr>\n",
813
+ " <td>1000</td>\n",
814
+ " <td>5.000700</td>\n",
815
+ " <td>5.834208</td>\n",
816
+ " </tr>\n",
817
+ " <tr>\n",
818
+ " <td>1100</td>\n",
819
+ " <td>5.026500</td>\n",
820
+ " <td>5.781939</td>\n",
821
+ " </tr>\n",
822
+ " <tr>\n",
823
+ " <td>1200</td>\n",
824
+ " <td>4.411800</td>\n",
825
+ " <td>5.720596</td>\n",
826
+ " </tr>\n",
827
+ " <tr>\n",
828
+ " <td>1300</td>\n",
829
+ " <td>4.782500</td>\n",
830
+ " <td>5.736376</td>\n",
831
+ " </tr>\n",
832
+ " <tr>\n",
833
+ " <td>1400</td>\n",
834
+ " <td>4.980200</td>\n",
835
+ " <td>5.712276</td>\n",
836
+ " </tr>\n",
837
+ " <tr>\n",
838
+ " <td>1500</td>\n",
839
+ " <td>4.368700</td>\n",
840
+ " <td>5.689637</td>\n",
841
+ " </tr>\n",
842
+ " <tr>\n",
843
+ " <td>1600</td>\n",
844
+ " <td>4.884700</td>\n",
845
+ " <td>5.675920</td>\n",
846
+ " </tr>\n",
847
+ " <tr>\n",
848
+ " <td>1700</td>\n",
849
+ " <td>4.914400</td>\n",
850
+ " <td>5.662421</td>\n",
851
+ " </tr>\n",
852
+ " <tr>\n",
853
+ " <td>1800</td>\n",
854
+ " <td>4.248700</td>\n",
855
+ " <td>5.660122</td>\n",
856
+ " </tr>\n",
857
+ " <tr>\n",
858
+ " <td>1900</td>\n",
859
+ " <td>4.798400</td>\n",
860
+ " <td>5.664026</td>\n",
861
+ " </tr>\n",
862
+ " <tr>\n",
863
+ " <td>2000</td>\n",
864
+ " <td>4.704200</td>\n",
865
+ " <td>5.655665</td>\n",
866
+ " </tr>\n",
867
+ " </tbody>\n",
868
+ "</table><p>"
869
+ ],
870
+ "text/plain": [
871
+ "<IPython.core.display.HTML object>"
872
+ ]
873
+ },
874
+ "metadata": {},
875
+ "output_type": "display_data"
876
+ },
877
+ {
878
+ "data": {
879
+ "text/plain": [
880
+ "TrainOutput(global_step=2000, training_loss=4.885598585128784, metrics={'train_runtime': 15380.3075, 'train_samples_per_second': 2.081, 'train_steps_per_second': 0.13, 'train_tokens_per_second': 4261.033, 'total_flos': 4.0317260660736e+17, 'train_loss': 4.885598585128784, 'epoch': 1.0})"
881
+ ]
882
+ },
883
+ "execution_count": 19,
884
+ "metadata": {},
885
+ "output_type": "execute_result"
886
+ }
887
+ ],
888
+ "source": [
889
+ "trainer = Trainer(\n",
890
+ " model=model, args=training_args, train_dataset=train_dataset, eval_dataset=eval_dataset\n",
891
+ ")\n",
892
+ "\n",
893
+ "print(\"Training...\")\n",
894
+ "trainer.train()\n"
895
+ ]
896
+ },
897
+ {
898
+ "cell_type": "markdown",
899
+ "metadata": {
900
+ "id": "aAERlCnt1PEW"
901
+ },
902
+ "source": [
903
+ "Finally, you can push the fine-tuned model to your Hub repository to share with your team."
904
+ ]
905
+ },
906
+ {
907
+ "cell_type": "code",
908
+ "execution_count": null,
909
+ "metadata": {
910
+ "id": "1h7_AUTTDwE1"
911
+ },
912
+ "outputs": [],
913
+ "source": [
914
+ "trainer.push_to_hub()"
915
+ ]
916
+ },
917
+ {
918
+ "cell_type": "markdown",
919
+ "metadata": {
920
+ "id": "KBVH7uFOM_UF"
921
+ },
922
+ "source": [
923
+ "## Inference\n",
924
+ "\n",
925
+ "Once the model is uploaded to Hub, we can use it for inference. To do so we first initialize the original base model and its tokenizer. Next, we need to merge the fine-duned weights with the base model."
926
+ ]
927
+ },
928
+ {
929
+ "cell_type": "code",
930
+ "execution_count": null,
931
+ "metadata": {
932
+ "id": "jtL37piINBFe"
933
+ },
934
+ "outputs": [],
935
+ "source": [
936
+ "from peft import PeftModel\n",
937
+ "import torch\n",
938
+ "\n",
939
+ "# load the original model first\n",
940
+ "tokenizer = AutoTokenizer.from_pretrained(MODEL, trust_remote_code=True)\n",
941
+ "base_model = AutoModelForCausalLM.from_pretrained(\n",
942
+ " MODEL,\n",
943
+ " quantization_config=None,\n",
944
+ " device_map=None,\n",
945
+ " trust_remote_code=True,\n",
946
+ " torch_dtype=torch.bfloat16,\n",
947
+ ").cuda()\n",
948
+ "\n",
949
+ "# merge fine-tuned weights with the base model\n",
950
+ "peft_model_id = f\"Your_HF_username/{OUTPUT_DIR}\"\n",
951
+ "model = PeftModel.from_pretrained(base_model, peft_model_id)\n",
952
+ "model.merge_and_unload()"
953
+ ]
954
+ },
955
+ {
956
+ "cell_type": "markdown",
957
+ "metadata": {
958
+ "id": "3USQ2suvDi9M"
959
+ },
960
+ "source": [
961
+ "Now we can use the merged model for inference. For convenience, we'll define a `get_code_completion` - feel free to experiment with text generation parameters!"
962
+ ]
963
+ },
964
+ {
965
+ "cell_type": "code",
966
+ "execution_count": null,
967
+ "metadata": {
968
+ "id": "RoTGpNbjDeWI"
969
+ },
970
+ "outputs": [],
971
+ "source": [
972
+ "def get_code_completion(prefix, suffix):\n",
973
+ " text = prompt = f\"\"\"<fim_prefix>{prefix}<fim_suffix>{suffix}<fim_middle>\"\"\"\n",
974
+ " model.eval()\n",
975
+ " outputs = model.generate(\n",
976
+ " input_ids=tokenizer(text, return_tensors=\"pt\").input_ids.cuda(),\n",
977
+ " max_new_tokens=128,\n",
978
+ " temperature=0.2,\n",
979
+ " top_k=50,\n",
980
+ " top_p=0.95,\n",
981
+ " do_sample=True,\n",
982
+ " repetition_penalty=1.0,\n",
983
+ " )\n",
984
+ " return tokenizer.batch_decode(outputs, skip_special_tokens=True)[0]"
985
+ ]
986
+ },
987
+ {
988
+ "cell_type": "markdown",
989
+ "metadata": {
990
+ "id": "0kMJiGDfDrBf"
991
+ },
992
+ "source": [
993
+ "Now all we need to do to get code completion is call the `get_code_complete` function and pass the first few lines that we want to be completed as a prefix, and an empty string as a suffix."
994
+ ]
995
+ },
996
+ {
997
+ "cell_type": "code",
998
+ "execution_count": null,
999
+ "metadata": {
1000
+ "colab": {
1001
+ "base_uri": "https://localhost:8080/"
1002
+ },
1003
+ "id": "nXlco2_-YcvM",
1004
+ "outputId": "41c411ad-b7dc-4277-f975-c173888234bb"
1005
+ },
1006
+ "outputs": [
1007
+ {
1008
+ "name": "stdout",
1009
+ "output_type": "stream",
1010
+ "text": [
1011
+ "from peft import LoraConfig, TaskType, get_peft_model\n",
1012
+ "from transformers import AutoModelForCausalLM\n",
1013
+ "peft_config = LoraConfig(\n",
1014
+ " task_type=TaskType.CAUSAL_LM,\n",
1015
+ " r=8,\n",
1016
+ " lora_alpha=32,\n",
1017
+ " target_modules=[\"q_proj\", \"v_proj\"],\n",
1018
+ " lora_dropout=0.1,\n",
1019
+ " bias=\"none\",\n",
1020
+ " modules_to_save=[\"q_proj\", \"v_proj\"],\n",
1021
+ " inference_mode=False,\n",
1022
+ ")\n",
1023
+ "model = AutoModelForCausalLM.from_pretrained(\"gpt2\")\n",
1024
+ "model = get_peft_model(model, peft_config)\n",
1025
+ "model.print_trainable_parameters()\n"
1026
+ ]
1027
+ }
1028
+ ],
1029
+ "source": [
1030
+ "prefix = \"\"\"from peft import LoraConfig, TaskType, get_peft_model\n",
1031
+ "from transformers import AutoModelForCausalLM\n",
1032
+ "peft_config = LoraConfig(\n",
1033
+ "\"\"\"\n",
1034
+ "suffix =\"\"\"\"\"\"\n",
1035
+ "\n",
1036
+ "print(get_code_completion(prefix, suffix))"
1037
+ ]
1038
+ },
1039
+ {
1040
+ "cell_type": "markdown",
1041
+ "metadata": {
1042
+ "id": "Ql2563kGlnmu"
1043
+ },
1044
+ "source": [
1045
+ "As someone who has just used the PEFT library earlier in this notebook, you can see that the generated result for creating a `LoraConfig` is rather good!\n",
1046
+ "\n",
1047
+ "If you go back to the cell where we instantiate the model for inference, and comment out the lines where we merge the fine-tuned weights, you can see what the original model would've generated for the exact same prefix:"
1048
+ ]
1049
+ },
1050
+ {
1051
+ "cell_type": "code",
1052
+ "execution_count": null,
1053
+ "metadata": {
1054
+ "colab": {
1055
+ "base_uri": "https://localhost:8080/"
1056
+ },
1057
+ "id": "29xxp1eHTgJ9",
1058
+ "outputId": "c6d597a2-01da-4d25-a32f-3a551212c5b4"
1059
+ },
1060
+ "outputs": [
1061
+ {
1062
+ "name": "stdout",
1063
+ "output_type": "stream",
1064
+ "text": [
1065
+ "from peft import LoraConfig, TaskType, get_peft_model\n",
1066
+ "from transformers import AutoModelForCausalLM\n",
1067
+ "peft_config = LoraConfig(\n",
1068
+ " model_name_or_path=\"facebook/wav2vec2-base-960h\",\n",
1069
+ " num_labels=1,\n",
1070
+ " num_features=1,\n",
1071
+ " num_hidden_layers=1,\n",
1072
+ " num_attention_heads=1,\n",
1073
+ " num_hidden_layers_per_attention_head=1,\n",
1074
+ " num_attention_heads_per_hidden_layer=1,\n",
1075
+ " hidden_size=1024,\n",
1076
+ " hidden_dropout_prob=0.1,\n",
1077
+ " hidden_act=\"gelu\",\n",
1078
+ " hidden_act_dropout_prob=0.1,\n",
1079
+ " hidden\n"
1080
+ ]
1081
+ }
1082
+ ],
1083
+ "source": [
1084
+ "prefix = \"\"\"from peft import LoraConfig, TaskType, get_peft_model\n",
1085
+ "from transformers import AutoModelForCausalLM\n",
1086
+ "peft_config = LoraConfig(\n",
1087
+ "\"\"\"\n",
1088
+ "suffix =\"\"\"\"\"\"\n",
1089
+ "\n",
1090
+ "print(get_code_completion(prefix, suffix))"
1091
+ ]
1092
+ },
1093
+ {
1094
+ "cell_type": "markdown",
1095
+ "metadata": {
1096
+ "id": "Pwy2ZC7U8Ema"
1097
+ },
1098
+ "source": [
1099
+ "While it is Python syntax, you can see that the original model has no understanding of what a `LoraConfig` should be doing."
1100
+ ]
1101
+ },
1102
+ {
1103
+ "cell_type": "markdown",
1104
+ "metadata": {
1105
+ "id": "CATYE8pp2drQ"
1106
+ },
1107
+ "source": [
1108
+ "To learn how this kind of fine-tuning compares to full fine-tuning, and how to use a model like this as your copilot in VS Code via Inference Endpoints, or locally, check out the [\"Personal Copilot: Train Your Own Coding Assistant\" blog post](https://huggingface.co/blog/personal-copilot). This notebook complements the original blog post.\n"
1109
+ ]
1110
+ }
1111
+ ],
1112
+ "metadata": {
1113
+ "accelerator": "GPU",
1114
+ "colab": {
1115
+ "gpuType": "A100",
1116
+ "machine_shape": "hm",
1117
+ "provenance": []
1118
+ },
1119
+ "kernelspec": {
1120
+ "display_name": "Python 3",
1121
+ "name": "python3"
1122
+ },
1123
+ "language_info": {
1124
+ "name": "python"
1125
+ }
1126
+ },
1127
+ "nbformat": 4,
1128
+ "nbformat_minor": 0
1129
+ }