PageSourceSearch

https://www.chiragjpgroup.org/site_libs/quarto-nav/quarto-nav.js

js chiragjpgroup.org collected 2026-10-02 07:18:57 UTC 8,617 bytes, 288 lines download raw bytes

1const headroomChanged = new CustomEvent("quarto-hrChanged", {
2  detail: {},
3  bubbles: true,
4  cancelable: false,
5  composed: false,
6});
7
8window.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});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.