PageSourceSearch

https://101t.top/js/main.js?v=20260906-ixxx-2&config_v=63eea3607ae43a31

js 101t.top collected 2026-10-09 04:33:54 UTC 11,772 bytes, 342 lines download raw bytes

1function toggleAds() {
2    const remainingAds = document.querySelector('.remaining-ads');
3    const button = document.querySelector('.toggle-button');
4
5    if (remainingAds.classList.contains('adhidden')) {
6        // 显示广告
7        remainingAds.classList.remove('adhidden');
8        remainingAds.style.display = 'flex'; // 强制设置显示样式
9        // 遍历移除子元素 .icon-ad 的 hidden 类
10        const ads = remainingAds.querySelectorAll('.icon-ad');
11        ads.forEach(ad => {
12            ad.classList.remove('adhidden');
13        });
14        button.textContent = '收起';
15    } else {
16        // 隐藏广告
17        remainingAds.classList.add('adhidden');
18        remainingAds.style.display = 'none'; // 强制隐藏样式
19
20        button.textContent = '展开更多';
21    }
22}
23
24
25async function fetchAndRenderSiteData() {
26    try {
27        const response = await fetch(`/site.json?timestamp=${Date.now()}`);
28        if (!response.ok) {
29            throw new Error('Failed to fetch site data');
30        }
31
32        const encrypted = await response.text();
33        const siteData = decodeSiteData(encrypted);
34        window.renderSiteSections(siteData);
35        attachUmamiAdTracking();
36        document.querySelectorAll(".site-link-section").forEach(linkHandleEvent);
37    } catch (error) {
38        console.error('Error fetching or rendering site data:', error);
39    }
40}
41
42document.addEventListener('DOMContentLoaded', function () {
43    if (window.hasExecuted) return;
44    window.hasExecuted = true;
45    fetchAndRenderSiteData();
46    const urlParams = new URLSearchParams(window.location.search);
47    const ref = urlParams.get('ref');
48    if (!ref) return;
49    const today = new Date().toISOString().slice(0, 10);
50    const domain = location.hostname;
51    const cacheKey = `umami_ref_logged_${ref}_${today}_${domain}`;
52    if (localStorage.getItem(cacheKey)) return;
53    const timer = setInterval(() => {
54        if (typeof window.umami === 'object' && typeof umami.track === 'function') {
55            umami.track('ref_visit', {
56                ref,
57                date: today
58            });
59
60            localStorage.setItem(cacheKey, '1');
61            clearInterval(timer);
62        }
63    }, 200);
64});
65
66
67function attachUmamiAdTracking() {
68    // 图标广告点击统计
69    document.querySelectorAll('.ad-link').forEach(link => {
70        link.addEventListener('click', function () {
71            if (typeof umami?.track === 'function') {
72                umami.track('ad_click', {
73                    url: link.href,
74                    title: link.querySelector('img')?.alt || '',
75                    
76                });
77            }
78        });
79    });
80    // 横幅广告点击统计(Banner/Banner2)
81    document.querySelectorAll('.streamer-box a, .streamer-box2 a, .site-banner-link').forEach(link => {
82        link.addEventListener('click', function () {
83            if (typeof umami?.track === 'function') {
84                umami.track('banner_click', {
85                    url: link.href,
86                    title: link.querySelector('img')?.alt || '',
87                    
88                });
89            }
90        });
91    });
92}
93
94function linkHandleEvent(linkContainer) {
95    linkContainer.querySelectorAll('.referrerLink').forEach(link => {
96        link.addEventListener('click', function () {
97            if (typeof umami.track === 'function') {
98                umami.track('outbound_click', {
99                    url: link.href,
100                    title: link.textContent || '',
101                    
102                });
103            }
104
105        });
106    });
107}
108
109class Banner2 {
110    constructor(nodeId, data) {
111        this.nodeId = nodeId;
112        this.node = document.getElementById(nodeId);
113        this.data = data;
114        this.bannerParent = undefined;
115        this.banner = undefined;
116        this.prevBtn = undefined;
117        this.nextBtn = undefined;
118        this.currentIndex = 0; // 当前图片索引
119        this.totalImages = 0;
120        this.autoSwitchInterval = 3000; // 自动切换间隔时间(毫秒)
121        this.autoSwitchTimer = undefined; // 自动切换的定时器
122        this.liWidth = 0;
123    }
124
125    initCSS() {
126        let style = document.createElement('style');
127        style.innerHTML = `
128        .streamer-container2 {
129            width: 100%;
130            overflow-x: auto;
131            padding: 0 5px;
132        }
133        .streamer-box2 {
134            list-style: none;
135            padding: 0;
136            margin: 0;
137        }
138        .streamer-box2 li {
139            width: 100%;
140            max-width: 960px;
141            flex-shrink: 0;
142            margin: 2px auto;
143        }
144        .streamer-box2 li a {
145            display: block;
146        }
147        .streamer-box2 li img {
148            width: 100%;
149            height: auto;
150            max-height: 120px;
151            display: block;
152        }
153        @media screen and (max-width: 640px) {
154            .streamer-box2 li {
155                width: 100%;
156            }
157        }
158    `;
159        document.head.appendChild(style);
160        return this;
161    }
162
163    initDOM() {
164        this.node.innerHTML = '<div class="streamer-container2" id="streamer-container2-' + this.nodeId + '">' +
165            '<ul class="streamer-box2" id="streamer-box2-' + this.nodeId + '">' +
166            '</ul>' +
167            '</div>';
168        return this;
169    }
170
171    initBanner() {
172        for (let i = 0; i < this.totalImages; i++) {
173            const li = document.createElement('li');
174            li.innerHTML = `<a href="${this.data[i].url}" target="_blank" rel="noopener"><img src="${this.data[i].logo}"></a>`;
175            this.banner.appendChild(li);
176        }
177    }
178
179    init() {
180        this.initDOM();
181        this.bannerParent = document.getElementById('streamer-container2-'+this.nodeId);
182        this.banner = document.getElementById('streamer-box2-'+this.nodeId);
183        this.totalImages = this.data.length;
184        this.initBanner();
185    }
186
187    static getRandChar2(length) {
188        const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
189        let result = '';
190        for (let i = 0; i < length; i++) {
191            result += letters.charAt(Math.floor(Math.random() * letters.length));
192        }
193        return result;
194    }
195}
196
197class Banner {
198    constructor(nodeId, data) {
199        this.nodeId = nodeId;
200        this.node = document.getElementById(nodeId);
201        this.data = data;
202        this.bannerParent = undefined;
203        this.banner = undefined;
204        this.prevBtn = undefined;
205        this.nextBtn = undefined;
206        this.currentIndex = 0; // 当前图片索引
207        this.totalImages = 0;
208        this.autoSwitchInterval = 3000; // 自动切换间隔时间(毫秒)
209        this.autoSwitchTimer = undefined; // 自动切换的定时器
210        this.liWidth = 0;
211    }
212
213    init() {
214        //this.initCSS();
215        this.initDOM();
216        this.bannerParent = document.getElementById('streamer-container-'+this.nodeId);
217        this.banner = document.getElementById('streamer-box-'+this.nodeId);
218        this.prevBtn = document.getElementById('prevBtn-'+this.nodeId);
219        this.nextBtn = document.getElementById('nextBtn-'+this.nodeId);
220        this.currentIndex = 0; // 当前图片索引
221        this.totalImages = this.data.length;
222        this.initBanner();
223        this.startAutoSwitch();
224        this.initEvent();
225    }
226
227    initCSS() {
228        let style = document.createElement('style');
229        style.innerHTML = `.streamer-container{position:relative;width:100%;max-width:960px;height:auto;margin:0 auto;overflow:hidden}
230            .streamer-box{display:flex;flex-wrap:nowrap;transition:transform .5s ease-in-out;list-style:none;padding: 0;margin: 0;}
231            .streamer-box li{height:auto;overflow:hidden}
232            .streamer-box li a{display:block;}
233            .streamer-box li img{max-width:100%;border: 0;}
234            .streamer-container .btn{position:absolute;top:50%;transform:translateY(-50%);background-color:rgba(0,0,0,.2);color:rgba(255,255,255,.6);border:none;padding:10px 15px;cursor:pointer;font-size:16px;z-index:2}
235            .streamer-container .btn:hover{background-color:rgba(0,0,0,.7)}
236            .streamer-container .btn.prev{left:10px}
237            .streamer-container .btn.next{right:10px}
238            @media screen and (max-width:640px){
239                .streamer-container .btn{padding:0 3px;background-color:rgba(0,0,0,.2);color:rgba(255,255,255,.6)}
240            }`;
241        document.head.appendChild(style);
242        return this;
243    }
244
245    initDOM() {
246        this.node.innerHTML = '<div class="streamer-container" id="streamer-container-' + this.nodeId + '">' +
247            '<button class="btn prev" id="prevBtn-' + this.nodeId + '">◀</button>' +
248            '<ul class="streamer-box" id="streamer-box-' + this.nodeId + '">' +
249            '</ul>' +
250            '<button class="btn next" id="nextBtn-' + this.nodeId + '">▶</button>' +
251            '</div>';
252        return this;
253    }
254
255    initBanner() {
256        this.liWidth = this.bannerParent.offsetWidth;
257        let ulWidth = this.liWidth * this.totalImages;
258        this.banner.style.width = ulWidth + 'px';
259
260        for (let i = 0; i < this.totalImages; i++) {
261            const li = document.createElement('li');
262            li.style.width = this.liWidth + 'px';
263            li.innerHTML = `<a href="${this.data[i].url}" target="_blank"><img src="${this.data[i].logo}"></a>`;
264            this.banner.appendChild(li);
265        }
266    }
267
268    updateBanner() {
269        const offset = -(this.currentIndex * this.liWidth); // 计算偏移百分比
270        this.banner.style.transform = `translateX(${offset}px)`;
271    }
272
273    startAutoSwitch() {
274        this.autoSwitchTimer = setInterval(() => {
275            this.currentIndex = (this.currentIndex + 1) % this.totalImages;
276            this.updateBanner();
277        }, this.autoSwitchInterval);
278    }
279
280    stopAutoSwitch() {
281        clearInterval(this.autoSwitchTimer);
282    }
283
284    showPrev() {
285        this.currentIndex = (this.currentIndex - 1 + this.totalImages) % this.totalImages;
286        this.stopAutoSwitch()
287        this.updateBanner();
288        this.startAutoSwitch();
289    }
290
291    showNext() {
292        this.currentIndex = (this.currentIndex + 1) % this.totalImages;
293        this.stopAutoSwitch()
294        this.updateBanner();
295        this.startAutoSwitch();
296    }
297
298    resetAutoSwitch() {
299        clearInterval(this.autoSwitchTimer);
300        this.startAutoSwitch();
301    }
302
303    initEvent() {
304        this.prevBtn.addEventListener('click', this.showPrev.bind(this));
305        this.nextBtn.addEventListener('click', this.showNext.bind(this));
306    }
307
308    static getRandChar2(length) {
309        const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
310        let result = '';
311        for (let i = 0; i < length; i++) {
312            result += letters.charAt(Math.floor(Math.random() * letters.length));
313        }
314        return result;
315    }
316}
317function decodeSiteData(data) {
318    if (typeof data !== 'string' || !data.trim()) {
319        console.error('❌ 无效的输入数据');
320        return null;
321    }
322    try {
323        data = data
324            .replace(/\//g, '0')
325            .replace(/@/g, '/')
326            .replace(/\./g, '+')
327            .split('')
328            .reverse()
329            .join('');
330        const mod = data.length % 4;
331        if (mod !== 0) {
332            data = data.padEnd(data.length + (4 - mod), '=');
333        }
334        const binaryStr = atob(data);
335        const bytes = Uint8Array.from(binaryStr, c =>
335 c.charCodeAt(0));
336        const decoded = new TextDecoder('utf-8').decode(bytes);
337        return JSON.parse(decoded);
338    } catch (error) {
339        console.error('❌ site.json 解码失败:', error);
340        return null;
341    }
342}

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.