PageSourceSearch

https://www.northernlogics.com/wp-content/themes/thegem/js/thegem-pagespeed-lazy-items.js

js northernlogics.com collected 2026-10-08 18:42:34 UTC 27,048 bytes, 800 lines download raw bytes

1(function(window, document) {
2    function isMobileDevice() {
3        var a=navigator.userAgent||navigator.vendor||window.opera;
4        return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4));
5    }
6    function excludedDevices() {
7        var a=navigator.userAgent||navigator.vendor||window.opera;
8        return false; // /(iPhone|iPad).*OS 14/i.test(a) || /Version.*14.*Safari/i.test(a);
9    }
10
11    if (!Object.assign) {
12        Object.defineProperty(Object, 'assign', {
13            enumerable: false,
14            configurable: true,
15            writable: true,
16            value: function(target, firstSource) {
17                'use strict';
18                if (target === undefined || target === null) {
19                    throw new TypeError('Cannot convert first argument to object');
20                }
21
22                var to = Object(target);
23                for (var i = 1; i < arguments.length; i++) {
24                    var nextSource = arguments[i];
25                    if (nextSource === undefined || nextSource === null) {
26                        continue;
27                    }
28
29                    var keysArray = Object.keys(Object(nextSource));
30                    for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
31                        var nextKey = keysArray[nextIndex];
32                        var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
33                        if (desc !== undefined && desc.enumerable) {
34                            to[nextKey] = nextSource[nextKey];
35                        }
36                    }
37                }
38                return to;
39            }
40        });
41    }
42
43    if (typeof window.CustomEvent !== "function") {
44        function CustomEvent( event, params ) {
45            params = params || { bubbles: false, cancelable: false, detail: undefined };
46            var evt = document.createEvent( 'CustomEvent' );
47            evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
48            return evt;
49        }
50        CustomEvent.prototype = window.Event.prototype;
51        window.CustomEvent = CustomEvent;
52    }
53
54    function getRootScrollTop() {
55        return window.pageYOffset || document.documentElement.scrollTop;
56    }
57
58    function getNodePosition(node) {
59        try {
60            var position = node.getBoundingClientRect();
61            return {
62                left: position.left,
63                top: position.top + getRootScrollTop(),
64                width: position.width,
65                height: position.height
66            };
67        } catch (err) {
68            return null;
69        }
70    }
71
72    function getAncestorNode(node, className) {
73        while (node !== undefined && node !== null && node.nodeName.toUpperCase() !== 'BODY') {
74            if (node.classList.contains(className)) {
75                return node;
76            }
77            node = node.parentNode;
78        }
79        return null;
80    }
81
82    function addEvent(node, event, callback, useCapture) {
83        if (typeof node.addEventListener == 'function') {
84            node.addEventListener(event, callback, useCapture || false);
85        } else if (typeof node.attachEvent == 'function') {
86            node.attachEvent('on' + event, callback);
87        }
88    }
89
90    function LazyGroup(node, type) {
91        this.node = node;
92        this.type = type || 'default';
93        this.position = null;
94        this.showed = false;
95        this.items = [];
96        this.itemLoaded = 0;
97    }
98
99    LazyGroup.prototype = {
100        getType: function() {
101            return this.type;
102        },
103
104        getItems: function() {
105            return this.items;
106        },
107
108        allItemsLoaded: function() {
109            return this.items.length == this.itemLoaded;
110        },
111
112        updatePosition: function() {
113            this.position = getNodePosition(this.node);
114        },
115
116        getPosition: function() {
117            return this.position;
118        },
119
120        getNode: function() {
121            return this.node;
122        },
123
124        addItem: function(item) {
125            if (this.isShowed()) {
126                this.showItem(item);
127            }
128
129            this.items.push(item);
130        },
131
132        showItem: function(item) {
133            var self = this;
134            item.show(function(event) {
135                self.itemLoaded++;
136                item.loaded(self);
137            });
138        },
139
140        show: function(force) {
141            var self = this;
142
143            if (this.isShowed()) {
144                return;
145            }
146
147            if (force === undefined) {
148                force = false;
149            }
150
151            this.showed = true;
152
153            this.items.forEach(function(item) {
154                if (!item.isShowed()) {
155                    self.showItem(item);
156                }
157            });
158
159            this.dispatchShowedEvent();
160        },
161
162        isShowed: function() {
163            return this.showed;
164        },
165
166        hasItems: function() {
167            return this.items.length > 0;
168        },
169
170        dispatchShowedEvent: function() {
171            this.node.dispatchEvent(new window.CustomEvent('tgpliVisible', {
172                bubbles: true
173            }));
174        }
175    };
176
177    function LazyItem(node, data) {
178        this.node = node;
179        this.data = data || {};
180        this.showed = false;
181        this.initType();
182    }
183
184    LazyItem.prototype = {
185        getNode: function() {
186            return this.node;
187        },
188
189        show: function(loadedCallback) {
190            if (this.isShowed()) {
191                return;
192            }
193
194            loadedCallback = loadedCallback || null;
195
196            this.showed = true;
197
198            switch (this.getType()) {
199                case 'image':
200                    this.showImage(loadedCallback);
201                    break;
202
203                case 'iframe':
204                    this.showIframe(loadedCallback);
205                    break;
206
207                case 'custom':
208                    this.showCustom(loadedCallback);
209                    break;
210
211                default:
212                    this.showDefault(loadedCallback);
213            }
214        },
215
216        showImage: function(loadedCallback) {
217            if (loadedCallback !== undefined && typeof loadedCallback === 'function') {
218                addEvent(this.node, 'load', function(event) { loadedCallback(event); }, true);
219            }
220
221            if (this.data.sources !== undefined && this.data.sources !== null && this.data.sources != '') {
222                this.node.insertAdjacentHTML('beforebegin', this.data.sources);
223            }
224
225            var srcSet = this.node.getAttribute('data-tgpli-srcset');
226            if (srcSet) {
227                this.node.setAttribute('srcset', srcSet);
228            }
229
230            var src = this.node.getAttribute('data-tgpli-src');
231            if (src) {
232                this.node.src = src;
233            }
234
235            this.node.removeAttribute('data-tgpli-image-inited');
236        },
237
238        showDefault: function(loadedCallback) {
239            this.node.classList.remove('tgpli-background-inited');
240        },
241
242        showIframe: function(loadedCallback) {
243            var src = this.node.getAttribute('data-tgpli-src');
244            if (src) {
245                this.node.src = src;
246            }
247
248            this.node.removeAttribute('data-tgpli-iframe-inited');
249        },
250
251        showCustom: function(loadedCallback) {
252            var action = this.node.getAttribute('data-tgpli-action');
253            if (action && window[action] !== undefined && typeof window[action] == 'function') {
254                window[action]();
255            }
256
257            this.node.removeAttribute('data-tgpli-custom-inited');
258        },
259
260        isShowed: function() {
261            return this.showed;
262        },
263
264        initType: function() {
265            if (this.data != undefined && this.data.customItem === true) {
266                this.type = 'custom';
267                return;
268            }
269
270            switch (this.node.nodeName.toUpperCase()) {
271                case 'IMG':
272                    this.type = 'image';
273                    break;
274
275                case 'IFRAME':
276                    this.type = 'iframe';
277                    break;
278
279                default:
280                    this.type = 'default';
281            }
282        },
283
284        getType: function() {
285            return this.type;
286        },
287
288        getGroupNodeInfo: function() {
289            if (this.data != undefined && this.data.customItem === true) {
290                return {
291                    node: this.node,
292                    type: 'custom'
293                };
294            }
295
296            switch (this.getType()) {
297                case 'image':
298                    return this.getImageGroupNode();
299
300                case 'iframe':
301                    return {
302                        node: this.node.parentNode,
303                        type: 'iframe'
304                    };
305
306                default:
307                    return {
308                        node: this.node,
309                        type: 'default'
310                    };
311            }
312        },
313
314        getImageGroupNode: function() {
315            var id = this.node.id;
316
317            if (this.node.parentNode.classList.contains('logo')) {
318                return {
319                    node: this.node.parentNode,
320                    type: 'logo'
321                };
322            }
323
324            if (id && document.querySelector('div.gem-client-item #' + id) !== null) {
325                var ancestorNode = getAncestorNode(this.node, 'gem-clients-type-carousel-grid');
326                if (ancestorNode === null) {
327                    var ancestorNode = getAncestorNode(this.node, 'gem_client_carousel-items');
328                }
329                if (ancestorNode !== null) {
330                    return {
331                        node: ancestorNode,
332                        type: 'gem-clients'
333                    };
334                }
335            }
336
337            if (id && document.querySelector('#colophon .footer-widget-area #' + id) !== null) {
338                var ancestorNode = getAncestorNode(this.node, 'footer-widget-area');
339                if (ancestorNode !== null) {
340                    return {
341                        node: ancestorNode,
342                        type: 'footer-widget-area'
343                    };
344                }
345            }
346
347            if (id && document.querySelector('div.portfolio #' + id) !== null &&
348                !this.node.closest('div.portfolio').classList.contains('disable-isotope')) {
349                var ancestorNode = getAncestorNode(this.node, 'portfolio');
350                if (ancestorNode !== null) {
351                    return {
352                        node: ancestorNode,
353                        type: 'portfolio'
354                    };
355                }
356            }
357
358            if (
359                (this.node.className && this.node.className.indexOf('extended-carousel-grid') != -1) ||
360                (id && document.querySelector('div.extended-carousel-grid #' + id) !== null &&
361                    (this.node.closest('div.extended-carousel-grid').classList.contains('carousel-scroll-init')) )
362            ) {
363                var ancestorNode = getAncestorNode(this.node, 'extended-carousel-grid');
364                if (ancestorNode !== null) {
365                    return {
366                        node: ancestorNode,
367                        type: 'products-carousel'
368                    };
369                }
370            }
371
372            if (
373                (this.node.className && this.node.className.indexOf('gem-blog-slider') != -1) ||
374                (id && document.querySelector('div.gem-blog-slider #' + id) !== null )
375            ) {
376                var ancestorNode = getAncestorNode(this.node, 'gem-blog-slider');
377                if (ancestorNode !== null) {
378                    return {
379                        node: ancestorNode,
380                        type: 'blog-slider'
381                    };
382                }
383            }
384
385            if (
386                (this.node.className && this.node.className.indexOf('gem-news-type-carousel') != -1) ||
387                (id && document.querySelector('div.gem-news-type-carousel #' + id) !== null )
388            ) {
389                var ancestorNode = getAncestorNode(this.node, 'gem-news-type-carousel');
390                if (ancestorNode !== null) {
391                    return {
392                        node: ancestorNode,
393                        type: 'gem-news-carousel'
394                    };
395                }
396            }
397
398            if (id && document.querySelector('div.blog #' + id) !== null) {
399                var ancestorNode = getAncestorNode(this.node, 'blog');
400                if (ancestorNode !== null) {
401                    return {
402                        node: ancestorNode,
403                        type: 'blog'
404                    };
405                }
406            }
407
408            if (id && document.querySelector('div.gem-gallery-grid #' + id) !== null) {
409                var ancestorNode = getAncestorNode(this.node, 'gem-gallery-grid');
410                if (ancestorNode !== null) {
411                    return {
412                        node: ancestorNode,
413                        type: 'gallery-grid'
414                    };
415                }
416            }
417
418            if (id && document.querySelector('div.gem-gallery #' + id) !== null) {
419                var ancestorNode = getAncestorNode(this.node, 'gem-gallery');
420                if (ancestorNode !== null) {
421                    return {
422                        node: ancestorNode,
423                        type: 'gallery'
424                    };
425                }
426            }
427
428            if (id && document.querySelector('div.gem-simple-gallery #' + id) !== null) {
429                var ancestorNode = getAncestorNode(this.node, 'gem-simple-gallery');
430                if (ancestorNode !== null) {
431                    return {
432                        node: ancestorNode,
433                        type: 'simple-gallery'
434                    };
435                }
436            }
437
438            if (id && document.querySelector('div.gem-slideshow #' + id) !== null) {
439                var ancestorNode = getAncestorNode(this.node, 'gem-slideshow');
440                if (ancestorNode !== null) {
441                    return {
442                        node: ancestorNode,
443                        type: 'gem-slideshow'
444                    };
445                }
446            }
447
448            if (id && document.querySelector('div.gem-testimonials #' + id) !== null) {
449                var ancestorNode = getAncestorNode(this.node, 'gem-testimonials');
450                if (ancestorNode !== null) {
451                    return {
452                        node: ancestorNode,
453                        type: 'gem-testimonials'
454                    };
455                }
456            }
457
458            if (id && document.querySelector('div.rev_slider_wrapper #' + id) !== null) {
459                var ancestorNode = getAncestorNode(this.node, 'rev_slider_wrapper');
460                if (ancestorNode !== null) {
461                    return {
462                        node: ancestorNode,
463                        type: 'rev_slider'
464                    };
465                }
466            }
467
468            if (id && document.querySelector('div.wpb_images_carousel #' + id) !== null) {
469                var ancestorNode = getAncestorNode(this.node, 'wpb_images_carousel');
470                if (ancestorNode !== null) {
471                    return {
472                        node: ancestorNode,
473                        type: 'wpb_images_carousel'
474                    };
475                }
476            }
477
478            return {
479                node: this.node.parentNode,
480                type: 'default'
481            };
482        },
483
484        imageShowed: function() {
485            var id = this.node.id;
486
487            if (id && document.querySelector('div.caroufredsel_wrapper #' + id) !== null) {
488                window.dispatchEvent(new window.CustomEvent('resize'));
489            }
490
491            if (window.jQuery !== undefined && window.jQuery !== null &&
492                window.jQuery.waypoints !== undefined && window.jQuery.waypoints !== null &&
493                typeof window.jQuery.waypoints === "function"
494            ) {
495                window.jQuery.waypoints('refresh');
496            }
497        },
498
499        loaded: function(group) {
500            var groupItems = group.getItems();
501
502            if (group.getType() == 'default' && groupItems.length == 1 && groupItems[0].getType() == 'image') {
503                this.imageShowed();
504            }
505
506            if (group.getType() == 'wpb_images_carousel' && group.allItemsLoaded()) {
507                window.dispatchEvent(new window.CustomEvent('resize'));
508            }
509        }
510    };
511
512    function LazyItems(options) {
513        options = options || {};
514
515        this.options = Object.assign({
516            visibilityOffset: 300,
517            desktopEnable: true,
518            mobileEnable: true
519        }, options);
520
521        this.groups = [];
522        this.scrollTop = 0;
523        this.rootHeight = 0;
524        this.checkGroupsProcess = false;
525        this.enabled = false;
526        this.isPageScroller = false;
527        this.isFullpage = false;
528        this.visibilityOffsetFixed = false;
529
530        this.init();
531    }
532
533    LazyItems.prototype = {
534        init: function() {
535            this.checkEnabled();
536            this.updateRootScrollTop();
537            this.updateRootSize();
538            this.initEvents();
539            this.initQueueNodes();
540        },
541
542        checkEnabled: function() {
543            var isMobile = isMobileDevice();
544            this.enabled = !(excludedDevices()) && ((isMobile && this.options.mobileEnable) || (!isMobile && this.options.desktopEnable));
545        },
546
547        isEnabled: function() {
548            return this.enabled;
549        },
550
551        initQueueNodes: function() {
552            if (window.tgpQueue !== undefined) {
553                this.addNodes(window.tgpQueue.flushNodes());
554            }
555        },
556
557        initEvents: function() {
558            var self = this;
559            addEvent(window, 'resize', function() { self.resizeHandle(); }, true);
560            addEvent(document, 'scroll', function() { self.scrollHandle(); }, true);
561            addEvent(document, 'DOMContentLoaded', function() { self.documentReadyHandle(); }, true);
562        },
563
564        resizeHandle: function() {
565            var self = this;
566            setTimeout(function() {
567                self.updateRootScrollTop();
568                self.updateRootSize();
569                self.updateGroupsPositions();
570                self.checkGroups();
571            }, 0);
572        },
573
574        scrollHandle: function() {
575            if (!this.visibilityOffsetFixed) {
576                this.visibilityOffsetFixed = true;
577                this.options.visibilityOffset *= 1.5;
578            }
579            this.updateRootScrollTop();
580            this.updateGroupsPositions();
581            this.checkGroups();
582        },
583
584        documentReadyHandle: function() {
585            this.collectCustomItems();
586            this.detectPageScroller();
587            this.detectFullpage();
588            this.updateRootScrollTop();
589            this.updateRootSize();
590            this.updateGroupsPositions();
591            this.checkGroups();
592        },
593
594        detectPageScroller: function() {
595            var self = this;
596
597            this.isPageScroller = document.body.classList.contains('page-scroller');
598
599            if (this.isPageScroller) {
600                addEvent(document, 'page-scroller-updated', function() {
601                    self.scrollHandle();
602                });
603            }
604        },
605
606        detectFullpage: function() {
607            var self = this;
608
609            this.isFullpage = document.body.classList.contains('thegem-fp');
610
611            if (this.isFullpage) {
612                addEvent(document, 'fullpage-updated', function() {
613                    self.scrollHandle();
614                });
615            }
616        },
617
618        hasGroups: function() {
619            return this.groups.length > 0;
620        },
621
622        checkGroups: function() {
623            var self = this;
624
625            if (this.checkGroupsProcess || !this.hasGroups()) {
626                return;
627            }
628
629            this.checkGroupsProcess = true;
630
631            this.groups.forEach(function(group) {
632                if (group.isShowed() || !group.hasItems()) {
633                    return;
634                }
635
636                if (self.isVisibleGroup(group)) {
637                    self.showGroup(group, false);
638                }
639            });
640
641            this.checkGroupsProcess = false;
642        },
643
644        isVisibleGroup: function(group) {
645            var rootPosition = this.getRootPosition(),
646                groupPosition = group.getPosition();
647
648            if (groupPosition === null) {
649                return true;
650            }
651
652            if (groupPosition.left == 0 && groupPosition.top == 0 && groupPosition.width == 0 && groupPosition.height == 0) {
653                return false;
654            }
655
656            return groupPosition.top - this.options.visibilityOffset <= rootPosition.bottom &&
657                groupPosition.top + groupPosition.height + this.options.visibilityOffset >= rootPosition.top;
658        },
659
660        showGroup: function(group, force) {
661            if (force === undefined) {
662                force = false;
663            }
664            group.show(force);
665        },
666
667        showItem: function(item) {
668            item.show();
669        },
670
671        addItem: function(item) {
672            if (!this.isEnabled() || this.isIgnoreItem(item)) {
673                this.showItem(item);
674                return;
675            }
676
677            this.getItemGroup(item).addItem(item);
678        },
679
680        getItemGroup: function(item) {
681            var groupNodeInfo = item.getGroupNodeInfo(),
682                group = this.findGroup(groupNodeInfo.node);
683
684            if (group === null) {
685                group = new LazyGroup(groupNodeInfo.node, groupNodeInfo.type);
686
687                group.updatePosition();
688
689                if (this.isIgnoreGroup(group) || this.isVisibleGroup(group)) {
690                    this.showGroup(group, true);
691                }
692
693                this.groups.push(group);
694            }
695
696            return group;
697        },
698
699        findGroup: function(node) {
700            for (var i = 0; i < this.groups.length; i++) {
701                if (this.groups[i].getNode() == node) {
702                    return this.groups[i];
703                }
704            }
705            return null;
706        },
707
708        isIgnoreItem: function(item) {
709            return false;
710        },
711
712        isIgnoreGroup: function(group) {
713            if (group.getType() == 'gem-slideshow' || group.getType() == 'rev_slider') {
714                return true;
715            }
716
717            return false;
718        },
719
720        addNodes: function(nodes) {
721            var self = this;
722            nodes.forEach(function(node) {
723                self.addNode(node);
724            });
725        },
726
727        addNode: function(data) {
728            if (data.node === null) {
729                return;
730            }
731
732            this.addItem(new LazyItem(data.node, data.data));
733        },
734
735        collectItems: function() {
736            var self = this;
737
738            document.querySelectorAll('img[data-tgpli-image-inited]').forEach(function(node) {
739                self.addNode(node);
740            });
741
742            document.querySelectorAll('.tgpli-background-inited').forEach(function(node) {
743                self.addNode(node);
744            });
745        },
746
747        collectCustomItems: function() {
748            var self = this;
749
750            document.querySelectorAll('.tgpli-custom-item').forEach(function(node) {
751                self.addNode({
752                    node: node,
753                    data: {
754                        customItem: true
755                    }
756                });
757            });
758        },
759
760        updateGroupsPositions: function() {
761            this.groups.forEach(function(group) {
762                group.updatePosition();
763            });
764        },
765
766        updateRootScrollTop: function() {
767            this.scrollTop = getRootScrollTop();
768        },
769
770        updateRootSize: function() {
771            this.rootHeight = document.documentElement.clientHeight;
772        },
773
774        getRootPosition: function() {
775            return {
776                top: this.scrollTop,
777                bottom: this.scrollTop + this.rootHeight,
778                height: this.rootHeight
779            };
780        },
781
782        checkGroupShowed: function(node, callback) {
783            if (this.isGroupShowed(node)) {
784                return true;
785            } else {
786                addEvent(node, 'tgpliVisible', function() {
787                    callback(node);
788                }, true);
789                return false;
790            }
791        },
792
793        isGroupShowed: function(node) {
794            var group = this.findGroup(node);
795            return group === null || group.isShowed();
796        }
797    };
798
799    window.tgpLazyItems = new LazyItems(window.tgpLazyItemsOptions || {});
800})(window, document);

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.