PageSourceSearch

https://lambgoat.com/js/main.min.js?v=yir91hKGsY-4IXeEHnkK8oKijghXbcSU5-maOTTubHo

js lambgoat.com collected 2026-10-02 04:47:24 UTC 12,439 bytes, 361 lines download raw bytes

1//window.onscroll = function () { scrollFunction() };
2//function scrollFunction() {
3//    let styleWidth = "200px";
4//    if (document.body.scrollTop > 25 || document.documentElement.scrollTop > 25) {
5//        styleWidth = "135px";
6//    }
7//    document.getElementById("lgLogo").style.width = styleWidth;
8//}
9
10const urlRegex = /(https?:\/\/[-A-Z0-9+&@@#\/%?=~_|!:,.;(]*[-A-Z0-9+&@@#\/%=~_|)])/ig;
11
12function setCookie(name, value, seconds) {
13    var expires = "";
14    if (seconds) {
15        var date = new Date();
16        date.setTime(date.getTime() + (seconds * 1000));
17        expires = "; expires=" + date.toUTCString();
18    }
19    document.cookie = name + "=" + (truncateByBytes(encodeURIComponent(value), 4096) || "") + expires + "; path=/";
20}
21function getCookie(name) {
22    var nameEQ = name + "=";
23    var ca = document.cookie.split(';');
24    for (var i = 0; i < ca.length; i++) {
25        var c = ca[i];
26        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
27        if (c.indexOf(nameEQ) == 0) return decodeURIComponent(c.substring(nameEQ.length, c.length));
28    }
29    return null;
30}
31
32function cacheInServerMemory(name, value, seconds) {
33    $.ajax({
34        type: "POST",
35        url: '/api/cacheinservermemory',
36        data: {
37            "name": name,
38            "value": value,
39            "seconds": seconds
40        }
41    });
42}
43
44function getCacheInServerMemory(name) {
45    return $.ajax({
46        type: "GET",
47        url: '/api/getcacheinservermemory',
48        data: {
49            "name": name
50        }
51    });
52}
53
54function invalidateCacheInServerMemory(name) {
55    $.ajax({
56        type: "POST",
57        url: '/api/invalidatecacheinservermemory',
58        data: {
59            "name": name
60        }
61    });
62}
63
64function byteCount(string) {
65    // UTF8
66    return encodeURI(string).split(/%..|./).length - 1;
67}
68
69function truncateByBytes(string, byteSize) {
70    // UTF8
71    if (byteCount(string) > byteSize) {
72        const charsArray = string.split('');
73        let truncatedStringArray = [];
74        let bytesCounter = 0;
75        for (let i = 0; i < charsArray.length; i++) {
76            bytesCounter += byteCount(charsArray[i]);
77            if (bytesCounter <= byteSize) {
78                truncatedStringArray.push(charsArray[i]);
79            } else {
80                break;
81            }
82        }
83        return truncatedStringArray.join('');
84    }
85    return string;
86}
87
88function linkify(c, l = 50) {
89    return c.replace(urlRegex, function (url) {
90        return '<a href="' + url + '" target="_blank">' + truncateString(url, l) + '</a>';
91    });
92}
93
94function truncateString(str, num) {
95    if (str.length > num)
96        return str.slice(0, num) + "...";
97    else
98        return str;
99}
100
101// Following misc code will execute whenever a form across the entire website is submitted
102$('form').submit(function () {
103
104    // Disable button after form submission to prevent double posting
105    // Button will only disable if _ValidationScriptsPartial.cshtml is not imported or it is imported and the validation succeeds
106    if (typeof validationScriptsPartialImported === 'undefined' || $(this).valid()) {
107        $(this).find("input[type='submit']").prop('disabled', true);
108    }
109});
110
111function stripQueryParameters(url) {
112    return url.split("?")[0]
113}
114
115// Remove empty search query parameter (?q=) from URL if search textbox is empty.
116// Don't worry: this solution makes no extra requests... It simply intercepts the form submission and redirects to the appropriate URL.
117// It also doesn't affect pagination
118$("#searchForm").on("submit", function (e) {
119    e.preventDefault();
120    let queryParam = $("#searchForm input").val();
121    if (queryParam) {
122        window.location.href = stripQueryParameters(window.location.href) + `?q=${queryParam}`;
123    } else {
124        window.location.href = stripQueryParameters(window.location.href);
125    }
126});
127
128function subscribeToEmailingList() {
129    let email = $("#emailSubscriberField").val();
130    if (email) {
131        $.ajax({
132            type: "POST",
133            url: '/api/subscribetoemailinglist',
134            data: {
135                "email": email
136            },
137            success: function (data) {
138                if (data != null) {
139                    if (data.result === "True") {
140                        $("#emailResult").text("Subscribed");
141                        $("#emailResult").css("color", "lawngreen");
142                    }
143                    else if (data.result === "Invalid") {
144                        $("#emailResult").text("Invalid email address");
145                        $("#emailResult").css("color", "orange");
146                    }
147                    else {
148                        $("#emailResult").text("Something broke. Probably not your fault.");
149                        $("#emailResult").css("color", "orange");
150                    }
151                }
152            }
153        });
154    }
155    else {
156        $("#emailResult").text("Please enter email address");
157        $("#emailResult").css("color", "orange");
158    }
159}
160
161$("#submitEmailSubscriber").on("click", function () {
162    subscribeToEmailingList();
163});
164
165$("#emailSubscriberField").keyup(function (e) {
166    // Check if user pressed enter key
167    if (e.keyCode == 13) {
168        subscribeToEmailingList();
169    }
170});
171
172window.onload = function () {
173    let cbs = document.getElementsByClassName('bd-checkbox');
174    for (let i = 0; i < cbs.length; i++) {
175        let cb = cbs[i];
176        let cbInput = cb.querySelector('input');
177        cb.onclick = function () {
178            cbInput.checked = !cbInput.checked;
179            if (cbInput.checked) {
180                cb.querySelector('#selectedText').style.display = 'block';
181                cb.querySelector('#clickToSelectText').style.display = 'none';
182                cb.classList.add('bd-checkbox-checked');
183            } else {
184                cb.querySelector('#selectedText').style.display = 'none';
185                cb.querySelector('#clickToSelectText').style.display = 'block';
186                cb.classList.remove('bd-checkbox-checked');
187            }
188            //console.log(cbInput.checked);
189        }
190    }
191}
192
193document.querySelectorAll('oembed[url]').forEach(element => {
194    let ele = document.createElement('div');
195    ele.className = 'embed-responsive embed-responsive-16by9 mt-0 mb-3';
196    let ifr = document.createElement('iframe');
197    ifr.className = 'embed-responsive-item';
198    
199    let url = element.getAttribute('url');
200    
201    // Fix malformed YouTube URLs with double question marks
202    if (url.includes('youtube.com/watch?v=') && (url.match(/\?/g) || []).length > 1) {
203        // Find the position of the second '?' and replace it with '&'
204        let firstQuestionMark = url.indexOf('?');
205        let secondQuestionMark = url.indexOf('?', firstQuestionMark + 1);
206        if (secondQuestionMark > -1) {
207            url = url.substring(0, secondQuestionMark) + '&' + url.substring(secondQuestionMark + 1);
208        }
209    }
210    
211    // Handle YouTube URLs with timestamp parameters
212    if (url.includes('youtube.com/watch?v=')) {
213        // Extract video ID and parameters
214        let videoIdMatch = url.match(/[?&]v=([^&]+)/);
215        let timeMatch = url.match(/[?&]t=([^&]+)/);
216        
217        if (videoIdMatch) {
218            let videoId = videoIdMatch[1];
219            let embedUrl = 'https://www.youtube.com/embed/' + videoId;
220            
221            // Add timestamp if present
222            if (timeMatch) {
223                let timeValue = timeMatch[1];
224                let seconds = 0;
225                
226                // Parse different time formats
227                if (/^\d+$/.test(timeValue)) {
228                    // Pure number (seconds): t=90
229                    seconds = parseInt(timeValue);
230                } else if (/^\d+s$/.test(timeValue)) {
231                    // Seconds only: t=42s
232                    seconds = parseInt(timeValue.replace('s', ''));
233                } else if (/^(\d+)m(\d+)s$/.test(timeValue)) {
234                    // Minutes and seconds: t=1m30s
235                    let match = timeValue.match(/^(\d+)m(\d+)s$/);
236                    seconds = (parseInt(match[1]) * 60) + parseInt(match[2]);
237                } else if (/^\d+m$/.test(timeValue)) {
238                    // Minutes only: t=2m
239                    seconds = parseInt(timeValue.replace('m', '')) * 60;
240                }
241                
242                if (seconds > 0) {
243                    embedUrl += '?start=' + seconds;
244                }
245            }
246            
247            ifr.src = embedUrl;
248        }
249    } else if (url.includes('youtu.be/')) {
250        // Handle short YouTube URLs
251        let match = url.match(/youtu\.be\/([^?]+)(\?.*)?/);
252        if (match) {
253            let videoId = match[1];
254            let params = match[2] || '';
255            let embedUrl = 'https://www.youtube.com/embed/' + videoId;
256            
257            // Check for time parameter
258            let timeMatch = params.match(/[?&]t=([^&]+)/);
259            if (timeMatch) {
260                let timeValue = timeMatch[1];
261                let seconds = 0;
262                
263                // Parse different time formats (same as above)
264                if (/^\d+$/.test(timeValue)) {
265                    seconds = parseInt(timeValue);
266                } else if (/^\d+s$/.test(timeValue)) {
267                    seconds = parseInt(timeValue.replace('s', ''));
268                } else if (/^(\d+)m(\d+)s$/.test(timeValue)) {
269                    let match = timeValue.match(/^(\d+)m(\d+)s$/);
270                    seconds = (parseInt(match[1]) * 60) + parseInt(match[2]);
271                } else if (/^\d+m$/.test(timeValue)) {
272                    seconds = parseInt(timeValue.replace('m', '')) * 60;
273                }
274                
275                if (seconds > 0) {
276                    embedUrl += '?start=' + seconds;
277                }
278            }
279            
280            ifr.src = embedUrl;
281        }
282    } else {
283        // Fallback for other embed types
284        ifr.src = url;
285    }
286    
287    ifr.setAttribute('allowfullscreen', '');
288    ele.appendChild(ifr);
289    element.parentElement.replaceWith(ele);
290});
291
292const htmlAllowedInEditor = [
293    {
294        name: 'blockquote',
295        classes: ['twitter-tweet', 'instagram-media', 'tiktok-embed', 'reddit-embed-bq'],
296        attributes: true
297    },
298    {
299        name: 'script',
300        attributes: true
301    },
302    {
303        name: 'iframe',
304        attributes: true,
305        styles: true,
306        classes: ['embed-responsive-item']
307    },
308    {
309        name: 'section'
310    },
311    {
312        name: 'div',
313        classes: ['embed-responsive', 'embed-responsive-16by9', 'mt-0', 'mt-1', 'mt-2', 'mt-3', 'mt-4', 'mt-5', 'mb-0', 'mb-1', 'mb-2', 'mb-3', 'mb-4', 'mb-5'],
314        attributes: {
315            style: true
316        }
317    },
318    {
319        name: 'p',
320        attributes: {
321            style: true
322        }
323    }
324];
325
326// Show a preview for Giphy embeds so users can verify the link
327document.addEventListener('DOMContentLoaded', function () {
328    const inputs = document.querySelectorAll("input[name$='.EmbedLink']");
329    inputs.forEach(input => {
330        const preview = document.createElement('div');
331        preview.className = 'mt-2';
332        input.parentNode.insertBefore(preview, input.nextSibling);
333
334        const update = () => {
335            const url = input.value.trim();
336            preview.innerHTML = '';
337            if (!url) {
338                return;
339            }
340
341            const normalized = url.replace(/media[0-9]\.giphy\.com/, 'media.giphy.com');
342            const gifMatch = normalized.match(/giphy\.com\/gifs\/([\w-]+)/i);
343            const mediaMatch = normalized.match(/media\.giphy\.com\/media\/([\w-]+)/i);
344            const id = gifMatch ? gifMatch[1] : (mediaMatch ? mediaMatch[1] : null);
345
346            if (id) {
347                const img = document.createElement('img');
348                img.src = `https://media.giphy.com/media/${id}/giphy.gif`;
349                img.className = 'img-fluid mt-2';
350                img.alt = 'Giphy preview';
351                preview.appendChild(img);
352            } else {
353                preview.innerHTML = '<div class="text-danger">Invalid Giphy URL</div>';
354            }
355        };
356
357        input.addEventListener('input', update);
358        update();
359    });
360});
361$(document).ready(function(){$(".mobile-dropdown-toggle").click(function(o){o.preventDefault(),$(this).next(".mobile-dropdown-menu").toggleClass("show")})});

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.