1const menuButton=document.querySelector('.mobile-menu'); 2menuButton.addEventListener('click',()=>{const open=menuButton.getAttribute('aria-expanded')!=='true';menuButton.setAttribute('aria-expanded',String(open));menuButton.textContent=open?'Close â':'Menu +';document.querySelector('.topbar').classList.toggle('menu-open',open);}); 3const MOBILE_PAGE_NAVS={ 4 main:[['#home','Overview'],['#real-jobs','The work'],['#download','Get Nightshift']], 5 howto:[['#how-to-use','Story'],['benchmarks.html#morning','The work'],['#howto-download','Get Nightshift']] 6}; 7function setMobilePageNav(kind){const nav=document.querySelector('.mobile-page-nav');if(!nav||nav.dataset.kind===kind)return;nav.dataset.kind=kind;nav.innerHTML=MOBILE_PAGE_NAVS[kind].map(([href,text],i)=>'<a href="'+href+'" aria-current="'+(i===0)+'">'+text+'</a>').join('');} 8// Each view is its own page: <body data-page> fixes the route; hash changes only move within the page. 9const PAGE=document.body.dataset.page||'nightshift'; 10const PAGE_TOP_HASHES=['#home','#main','#how-to-use','#howto-page','#howto-top','#tour','#optimized-for-local-ai','#local-ai','#localai-page','#free-tools','#free-apps','#engines','#about','#about-page','#benchmarks','#benchmarks-page','#bm-top']; 11function routeMeterless(){ 12 const hash=location.hash; 13 const toolsRoute=PAGE==='tools',enginesRoute=PAGE==='engines',aboutRoute=PAGE==='about',howtoRoute=PAGE==='howto',localaiRoute=PAGE==='localai',benchmarksRoute=PAGE==='benchmarks',modelsRoute=PAGE==='models'; 14 const catalogRoute=toolsRoute||enginesRoute||aboutRoute||howtoRoute||localaiRoute||benchmarksRoute||modelsRoute; 15 document.body.classList.toggle('tools-active',toolsRoute); 16 document.body.classList.toggle('catalog-active',catalogRoute); 17 document.body.classList.toggle('howto-active',howtoRoute); 18 document.body.classList.toggle('field-off',catalogRoute&&!howtoRoute); 19 if(toolsShowcase)toolsShowcase.setActive(toolsRoute); 20 document.querySelector('.skip').href=toolsRoute?'#tools-page':enginesRoute?'#engines-page':aboutRoute?'#about-page':howtoRoute?'#howto-page':localaiRoute?'#localai-page':benchmarksRoute?'#benchmarks-page':modelsRoute?'#models-page':'#main'; 21 for(const [name,active] of [['tools',toolsRoute],['engines',enginesRoute],['models',modelsRoute],['about',aboutRoute],['howto',howtoRoute||localaiRoute],['nightshift',!catalogRoute]])document.querySelector('[data-nav="'+name+'"]').setAttribute('aria-current',active?'page':'false'); 22 setMobilePageNav(howtoRoute?'howto':'main'); 23 menuButton.setAttribute('aria-expanded','false');menuButton.textContent='Menu +';document.querySelector('.topbar').classList.remove('menu-open'); 24 if(typeof setTour==='function')setTour(false); 25 if(typeof measure==='function')measure(); 26 requestAnimationFrame(()=>{ 27 const chapterIndex=chapters.findIndex(chapter=>'#'+chapter.id===hash); 28 if(mobileQuery.matches&&chapterIndex>=0){selectMobileChapter(chapterIndex);document.querySelector('#story').scrollIntoView({behavior:'instant'});} 29 else if(PAGE_TOP_HASHES.includes(hash)){if(PAGE!=='nightshift'||hash!=='#home')window.scrollTo(0,0);} 30 else{const el=document.getElementById(hash.slice(1));if(el){el.scrollIntoView({behavior:'instant'});if(el.id==='tool-search')el.focus({preventScroll:true});}} 31 window.dispatchEvent(new Event('scroll')); 32 if(howtoRoute&&hash==='#tour'){pendingTour=true;history.replaceState(null,'',location.pathname+location.search);} 33 if(pendingTour&&howtoRoute){pendingTour=false;if(typeof measure==='function')measure();startStoryTour();} 34 }); 35} 36window.addEventListener('hashchange',routeMeterless);routeMeterless(); 37// Mode panel demos animate only while on screen. 38(()=>{const io=new IntersectionObserver(entries=>{for(const e of entries)if(e.isIntersecting)e.target.classList.add('is-on');},{threshold:.25});document.querySelectorAll('.modes .mode-panel').forEach(p=>io.observe(p));})();
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.