1(function () { 2 'use strict'; 3 4 var config = window.TimberINInstagramPopup || {}; 5 var endpoint = typeof config.endpoint === 'string' ? config.endpoint : ''; 6 var timeoutMs = Number(config.timeoutMs) || 4500; 7 var hydrated = new WeakSet(); 8 9 function hydrate(root) { 10 if (!endpoint || !root || !root.querySelectorAll) { 11 return; 12 } 13 root.querySelectorAll('.timberin-instagram-popup-feed[data-ti-ig-feed="1"]').forEach(loadFeed); 14 } 15 16 function loadFeed(frame) { 17 if (hydrated.has(frame)) { 18 return; 19 } 20 hydrated.add(frame); 21 22 var controller = typeof AbortController === 'function' ? new AbortController() : null; 23 var timer = window.setTimeout(function () { 24 if (controller) { 25 controller.abort(); 26 } 27 frame.setAttribute('data-refresh', 'timeout'); 28 }, timeoutMs); 29 30 var options = { 31 method: 'GET', 32 credentials: 'same-origin', 33 headers: { Accept: 'application/json' } 34 }; 35 if (controller) { 36 options.signal = controller.signal; 37 } 38 39 window.fetch(endpoint, options) 40 .then(function (response) { 41 if (!response.ok) { 42 throw new Error('feed-http'); 43 } 44 return response.json(); 45 }) 46 .then(function (payload) { 47 if (!payload || Number(payload.itemCount) < 6 || typeof payload.innerHtml !== 'string') { 48 throw new Error('feed-payload'); 49 } 50 var inner = frame.querySelector('.ti-ig-frame-inner'); 51 if (!inner) { 52 throw new Error('feed-target'); 53 } 54 inner.innerHTML = payload.innerHtml; 55 frame.setAttribute('data-state', payload.status === 'stale' ? 'stale' : 'live'); 56 frame.setAttribute('data-updated-at', String(payload.updatedAt || 0)); 57 frame.setAttribute('data-refresh', 'complete'); 58 }) 59 .catch(function () { 60 // The server-rendered grid or polished fallback remains visible. 61 frame.setAttribute('data-refresh', frame.getAttribute('data-refresh') || 'fallback'); 62 }) 63 .finally(function () { 64 window.clearTimeout(timer); 65 }); 66 } 67 68 function start() { 69 hydrate(document); 70 if (typeof MutationObserver === 'function') { 71 var observer = new MutationObserver(function (mutations) { 72 mutations.forEach(function (mutation) { 73 mutation.addedNodes.forEach(function (node) { 74 if (node.nodeType === 1) { 75 if (node.matches && node.matches('.timberin-instagram-popup-feed[data-ti-ig-feed="1"]')) { 76 loadFeed(node); 77 } 78 hydrate(node); 79 } 80 }); 81 }); 82 }); 83 observer.observe(document.documentElement, { childList: true, subtree: true }); 84 } 85 } 86 87 if (document.readyState === 'loading') { 88 document.addEventListener('DOMContentLoaded', start, { once: true }); 89 } else { 90 start(); 91 } 92}()); 93
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.