PageSourceSearch

https://keras.io/js/index.js

js keras.io collected 2026-09-24 08:23:54 UTC 6,657 bytes, 199 lines download raw bytes

1// Mobile nav controls
2const navButton = document.querySelector('.nav__menu--button');
3const closeButton = document.querySelector('.nav__menu--close');
4const mobileNavMenu = document.querySelector('.k-nav');
5const pageContainer = document.querySelector('.page__container');
6
7navButton.addEventListener('click', () => {
8  mobileNavMenu.style.display = 'block';
9  closeButton.style.display = 'block';
10  navButton.style.display = 'none';
11  pageContainer.style.position = 'fixed';
12});
13
14closeButton.addEventListener('click', () => {
15  mobileNavMenu.style.display = 'none';
16  closeButton.style.display = 'none';
17  navButton.style.display = 'block';
18  pageContainer.style.position = 'static';
19});
20
21// Copy code
22function addCopyButtonsToCodeBlocks() {
23  // Find all code blocks with .codehilite class, excluding those inside .k-default-codeblock
24  const allCodeBlocks = document.querySelectorAll('.codehilite:not(.k-default-codeblock .codehilite)');
25  
26  allCodeBlocks.forEach((block) => {
27    // Skip if button already exists
28    if (block.querySelector('.code__copy--button')) {
29      return;
30    }
31    
32    // Create copy button
33    const button = document.createElement('button');
34    button.className = 'code__copy--button';
35    button.setAttribute('aria-label', 'Copy code to clipboard');
36    
37    // Create icon element
38    const icon = document.createElement('i');
39    icon.className = 'icon--copy';
40    button.appendChild(icon);
41    
42    // Create tooltip
43    const tooltip = document.createElement('div');
44    tooltip.className = 'code__copy--tooltip';
45    tooltip.textContent = 'Copied!';
46    button.appendChild(tooltip);
47    
48    // Add button to container
49    block.insertBefore(button, block.firstChild);
50    
51    // Add click event listener
52    button.addEventListener('click', () => {
53      // Find the code element
54      const codeElement = block.querySelector('pre code') || block.querySelector('code') || block.querySelector('pre');
55      if (!codeElement) return;
56      
57      let text = codeElement.innerText || codeElement.textContent;
58      
59      // Clean the text: remove Python prompts and continuation markers
60      text = cleanCodeText(text);
61      
62      // Copy to clipboard using fallback method for better reliability
63      copyWithFallback(text, button);
64    });
65  });
66}
67
68function cleanCodeText(text) {
69  // Remove Python interactive prompt characters (>>>, ...)
70  // Split by lines, process each line, then rejoin
71  const lines = text.split('\n');
72  const cleanedLines = lines.map(line => {
73    // Remove >>> at the start of line (with optional spaces)
74    line = line.replace(/^\s*>>>\s?/, '');
75    // Remove ... at the start of line (with optional spaces) - continuation prompt
76    line = line.replace(/^\s*\.\.\.\s?/, '');
77    return line;
78  });
79  
80  return cleanedLines.join('\n');
81}
82
83function copyWithFallback(text, button) {
84  const inputElement = document.createElement('textarea');
85  inputElement.value = text;
86  inputElement.setAttribute('readonly', '');
87  inputElement.style.position = 'absolute';
88  inputElement.style.left = '-9999px';
89  document.body.appendChild(inputElement);
90  inputElement.select();
91  
92  try {
93    document.execCommand('copy');
94    showCopyTooltip(button);
95  } catch (err) {
96    console.error('Failed to copy text:', err);
97  }
98  
99  inputElement.remove();
100}
101
102function showCopyTooltip(button) {
103  const tooltip = button.querySelector('.code__copy--tooltip');
104  if (tooltip) {
105    tooltip.style.display = 'block';
106    setTimeout(() => {
107      tooltip.style.display = 'none';
108    }, 2000);
109  }
110}
111
112// Add copy buttons on page load
113document.addEventListener('DOMContentLoaded', addCopyButtonsToCodeBlocks);
114
115// Existing copy buttons (for landing page compatibility)
116const copyButtons = document.querySelectorAll('.code__copy--button');
117copyButtons.forEach((button) => {
118  button.addEventListener('click', () => {
119    const parent = button.parentNode;
120    const text = parent.querySelector('.language-python').innerText;
121    const inputElement = document.createElement('textarea');
122    console.log('text', text);
123    inputElement.value = text;
124    inputElement.setAttribute('class', 'visually-hidden');
125    const body = document.body;
126    body.appendChild(inputElement);
127    inputElement.select();
128    document.execCommand('copy');
129    inputElement.remove();
130
131    button.querySelector('.code__copy--tooltip').style.display = 'block';
132    setTimeout(() => {
133      button.querySelector('.code__copy--tooltip').style.display = 'none';
134    }, 2000);
135  });
136});
137
138// Search controls
139const searchForms = document.querySelectorAll('.nav__search');
140const mobileNavSearchIcon = document.querySelector('.nav__search--mobile');
141const mobileNavSearchForm = document.querySelector('.nav__search-form--mobile');
142const mobileNavControls = document.querySelector('.nav__controls--mobile');
143const desktopSearch = document.querySelector('.nav__menu .nav__search');
144
145mobileNavSearchIcon.addEventListener('click', () => {
146  mobileNavControls.style.display = 'none';
147  mobileNavSearchForm.style.display = 'block';
148});
149
150searchForms.forEach((search) => {
151  search.addEventListener('submit', (event) => {
152    event.preventDefault();
153    const text = search.querySelector('.nav__search--input').value;
154    window.location = `/search.html?query=${text}`;
155  });
156});
157
158pageContainer.addEventListener('click', () => {
159  mobileNavControls.style.display = 'flex';
160  mobileNavSearchForm.style.display = 'none';
161});
162
163mobileNavMenu.addEventListener('click', () => {
164  mobileNavControls.style.display = 'flex';
165  mobileNavSearchForm.style.display = 'none';
166});
167
168if (window.location.pathname.indexOf('search.html') > -1) {
169  desktopSearch.style.display = 'none';
170  mobileNavSearchIcon.style.visibility = 'hidden';
171}
172
173// position:sticky functionality (set margin-top so that the content is correctly centered vertically)
174const exploreModule = document.querySelector('.explore');
175const exploreContent = document.querySelector('.explore__content');
176
177const observer = new IntersectionObserver(
178  (entries) => {
179    entries.forEach((entry) => {
180      if (entry.isIntersecting) {
181        window.addEventListener('resize', verticallyCenterExploreContent);
182        return;
183      }
184
185      window.removeEventListener('resize', verticallyCenterExploreContent);
186    });
187  },
188  { threshold: 0 }
189);
190
191if (exploreModule && window.innerWidth > 1199) {
192  observer.observe(exploreModule);
193  /* let's call it once initially to align it in case a screen never gets resized */
194  verticallyCenterExploreContent();
195}
196
197function verticallyCenterExploreContent() {
198  exploreContent.style.marginTop = `${Math.round(exploreContent.getBoundingClientRect().height / 2)}px`;
199}

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.