1(function () { 2 'use strict'; 3 var container = document.querySelector('#tab-0 > .select-nav'); 4 if (!container || !window.fetch) return; 5 var cards = Array.prototype.filter.call(container.children, function (e) { return e.classList.contains('box'); }); 6 var first = Object.create(null); 7 cards.forEach(function (card) { 8 var id = card.getAttribute('data-artist-id'); 9 if (id && !first[id]) first[id] = card; 10 }); 11 var controller = window.AbortController ? new AbortController() : null; 12 var timer = controller ? setTimeout(function () { controller.abort(); }, 8000) : null; 13 var url = new URL('data/trending.json', document.baseURI); 14 url.searchParams.set('v', String(Math.floor(Date.now() / 1800000))); 15 fetch(url.href, controller ? {signal:controller.signal} : {}) 16 .then(function (r) { if (!r.ok) throw new Error('JSON unavailable'); return r.json(); }) 17 .then(function (data) { 18 var items = data && data.recentArtists; 19 if (!Array.isArray(items) || items.length > 18) return; 20 var seen = Object.create(null); 21 var valid = items.every(function (item) { 22 if (!item || typeof item.artistId !== 'string' || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(item.artistId) 23 || seen[item.artistId] || !first[item.artistId] || !/^\d{4}\.\d{2}\.\d{2}$/.test(item.date) 24 || !/^(new|restock)$/.test(item.type) || item.label !== (item.type === 'new' ? 'æ°ä½å' : 'åå ¥è·')) return false; 25 var d = new Date(item.date.replace(/\./g, '-') + 'T00:00:00Z'); 26 if (!isFinite(d.getTime()) || d.toISOString().slice(0,10).replace(/-/g,'.') !== item.date) return false; 27 seen[item.artistId] = true; 28 return true; 29 }); 30 if (!valid) return; 31 // Validate the entire payload before touching existing cards or labels. 32 var promoted = items.map(function (item) { return first[item.artistId]; }); 33 cards.forEach(function (card) { 34 Array.prototype.forEach.call(card.querySelectorAll('.box_new'), function (badge) { badge.remove(); }); 35 }); 36 items.forEach(function (item, i) { 37 var badge = document.createElement('div'); badge.className = 'box_new'; badge.textContent = item.label; 38 promoted[i].insertBefore(badge, promoted[i].firstChild); 39 }); 40 var fragment = document.createDocumentFragment(); 41 promoted.concat(cards.filter(function (card) { return promoted.indexOf(card) < 0; })).forEach(function (card) { fragment.appendChild(card); }); 42 container.appendChild(fragment); 43 }) 44 .catch(function () { /* Keep the complete fixed HTML on failure. */ }) 45 .then(function () { if (timer) clearTimeout(timer); }); 46}());
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.