PageSourceSearch

https://conservationbirding.org/wp-content/themes/speakstartertheme/js/baguetteBox.js?ver=20151215

js conservationbirding.org collected 2026-10-03 21:38:41 UTC 27,692 bytes, 789 lines download raw bytes

1/*!
2 * baguetteBox.js
3 * @author  feimosi
4 * @version %%INJECT_VERSION%%
5 * @url https://github.com/feimosi/baguetteBox.js
6 */
7
8/* global define, module */
9
10(function (root, factory) {
11    'use strict';
12    if (typeof define === 'function' && define.amd) {
13        define(factory);
14    } else if (typeof exports === 'object') {
15        module.exports = factory();
16    } else {
17        root.baguetteBox = factory();
18    }
19}(this, function () {
20    'use strict';
21
22    // SVG shapes used on the buttons
23    var leftArrow = '<svg width="44" height="60">' +
24            '<polyline points="30 10 10 30 30 50" stroke="rgba(255,255,255,0.5)" stroke-width="4"' +
25              'stroke-linecap="butt" fill="none" stroke-linejoin="round"/>' +
26            '</svg>',
27        rightArrow = '<svg width="44" height="60">' +
28            '<polyline points="14 10 34 30 14 50" stroke="rgba(255,255,255,0.5)" stroke-width="4"' +
29              'stroke-linecap="butt" fill="none" stroke-linejoin="round"/>' +
30            '</svg>',
31        closeX = '<svg width="30" height="30">' +
32            '<g stroke="rgb(160,160,160)" stroke-width="4">' +
33            '<line x1="5" y1="5" x2="25" y2="25"/>' +
34            '<line x1="5" y1="25" x2="25" y2="5"/>' +
35            '</g></svg>';
36    // Global options and their defaults
37    var options = {},
38        defaults = {
39            captions: true,
40            buttons: 'auto',
41            fullScreen: false,
42            noScrollbars: false,
43            bodyClass: 'baguetteBox-open',
44            titleTag: false,
45            async: false,
46            preload: 2,
47            animation: 'slideIn',
48            afterShow: null,
49            afterHide: null,
50            onChange: null,
51            overlayBackgroundColor: 'rgba(0,0,0,.8)'
52        };
53    // Object containing information about features compatibility
54    var supports = {};
55    // DOM Elements references
56    var overlay, slider, previousButton, nextButton, closeButton;
57    // An array with all images in the current gallery
58    var currentGallery = [];
59    // Current image index inside the slider
60    var currentIndex = 0;
61    // Visibility of the overlay
62    var isOverlayVisible = false;
63    // Touch event start position (for slide gesture)
64    var touch = {};
65    // If set to true ignore touch events because animation was already fired
66    var touchFlag = false;
67    // Regex pattern to match image files
68    var regex = /.+\.(gif|jpe?g|png|webp
vendor: 9,004 bytes, lines 68-320
68)/i;
69    // Object of all used galleries
70    var data = {};
71    // Array containing temporary images DOM elements
72    var imagesElements = [];
73    // The last focused element before opening the overlay
74    var documentLastFocus = null;
75    var overlayClickHandler = function(event) {
76        // Close the overlay when user clicks directly on the background
77        if (event.target.id.indexOf('baguette-img') !== -1) {
78            hideOverlay();
79        }
80    };
81    var previousButtonClickHandler = function(event) {
82        event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // eslint-disable-line no-unused-expressions
83        showPreviousImage();
84    };
85    var nextButtonClickHandler = function(event) {
86        event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // eslint-disable-line no-unused-expressions
87        showNextImage();
88    };
89    var closeButtonClickHandler = function(event) {
90        event.stopPropagation ? event.stopPropagation() : event.cancelBubble = true; // eslint-disable-line no-unused-expressions
91        hideOverlay();
92    };
93    var touchstartHandler = function(event) {
94        touch.count++;
95        if (touch.count > 1) {
96            touch.multitouch = true;
97        }
98        // Save x and y axis position
99        touch.startX = event.changedTouches[0].pageX;
100        touch.startY = event.changedTouches[0].pageY;
101    };
102    var touchmoveHandler = function(event) {
103        // If action was already triggered or multitouch return
104        if (touchFlag || touch.multitouch) {
105            return;
106        }
107        event.preventDefault ? event.preventDefault() : event.returnValue = false; // eslint-disable-line no-unused-expressions
108        var touchEvent = event.touches[0] || event.changedTouches[0];
109        // Move at least 40 pixels to trigger the action
110        if (touchEvent.pageX - touch.startX > 40) {
111            touchFlag = true;
112            showPreviousImage();
113        } else if (touchEvent.pageX - touch.startX < -40) {
114            touchFlag = true;
115            showNextImage();
116        // Move 100 pixels up to close the overlay
117        } else if (touch.startY - touchEvent.pageY > 100) {
118            hideOverlay();
119        }
120    };
121    var touchendHandler = function() {
122        touch.count--;
123        if (touch.count <= 0) {
124            touch.multitouch = false;
125        }
126        touchFlag = false;
127    };
128    var contextmenuHandler = function() {
129        touchendHandler();
130    };
131
132    var trapFocusInsideOverlay = function(event) {
133        if (overlay.style.display === 'block' && (overlay.contains && !overlay.contains(event.target))) {
134            event.stopPropagation();
135            initFocus();
136        }
137    };
138
139    // forEach polyfill for IE8
140    // http://stackoverflow.com/a/14827443/1077846
141    /* eslint-disable */
142    if (![].forEach) {
143        Array.prototype.forEach = function(callback, thisArg) {
144            for (var i = 0; i < this.length; i++) {
145                callback.call(thisArg, this[i], i, this);
146            }
147        };
148    }
149
150    // filter polyfill for IE8
151    // https://gist.github.com/eliperelman/1031656
152    if (![].filter) {
153        Array.prototype.filter = function(a, b, c, d, e) {
154            c = this;
155            d = [];
156            for (e = 0; e < c.length; e++)
157                a.call(b, c[e], e, c) && d.push(c[e]);
158            return d;
159        };
160    }
161    /* eslint-enable */
162
163    // Script entry point
164    function run(selector, userOptions) {
165        // Fill supports object
166        supports.transforms = testTransformsSupport();
167        supports.svg = testSvgSupport();
168        supports.passiveEvents = testPassiveEventsSupport();
169
170        buildOverlay();
171        removeFromCache(selector);
172        return bindImageClickListeners(selector, userOptions);
173    }
174
175    function bindImageClickListeners(selector, userOptions) {
176        // For each gallery bind a click event to every image inside it
177        var galleryNodeList = document.querySelectorAll(selector);
178        var selectorData = {
179            galleries: [],
180            nodeList: galleryNodeList
181        };
182        data[selector] = selectorData;
183
184        [].forEach.call(galleryNodeList, function(galleryElement) {
185            if (userOptions && userOptions.filter) {
186                regex = userOptions.filter;
187            }
188
189            // Get nodes from gallery elements or single-element galleries
190            var tagsNodeList = [];
191            if (galleryElement.tagName === 'A') {
192                tagsNodeList = [galleryElement];
193            } else {
194                tagsNodeList = galleryElement.getElementsByTagName('a');
195            }
196
197            // Filter 'a' elements from those not linking to images
198            tagsNodeList = [].filter.call(tagsNodeList, function(element) {
199                if (element.className.indexOf(userOptions && userOptions.ignoreClass) === -1) {
200                    return regex.test(element.href);
201                }
202            });
203            if (tagsNodeList.length === 0) {
204                return;
205            }
206
207            var gallery = [];
208            [].forEach.call(tagsNodeList, function(imageElement, imageIndex) {
209                var imageElementClickHandler = function(event) {
210                    event.preventDefault ? event.preventDefault() : event.returnValue = false; // eslint-disable-line no-unused-expressions
211                    prepareOverlay(gallery, userOptions);
212                    showOverlay(imageIndex);
213                };
214                var imageItem = {
215                    eventHandler: imageElementClickHandler,
216                    imageElement: imageElement
217                };
218                bind(imageElement, 'click', imageElementClickHandler);
219                gallery.push(imageItem);
220            });
221            selectorData.galleries.push(gallery);
222        });
223
224        return selectorData.galleries;
225    }
226
227    function clearCachedData() {
228        for (var selector in data) {
229            if (data.hasOwnProperty(selector)) {
230                removeFromCache(selector);
231            }
232        }
233    }
234
235    function removeFromCache(selector) {
236        if (!data.hasOwnProperty(selector)) {
237            return;
238        }
239        var galleries = data[selector].galleries;
240        [].forEach.call(galleries, function(gallery) {
241            [].forEach.call(gallery, function(imageItem) {
242                unbind(imageItem.imageElement, 'click', imageItem.eventHandler);
243            });
244
245            if (currentGallery === gallery) {
246                currentGallery = [];
247            }
248        });
249
250        delete data[selector];
251    }
252
253    function buildOverlay() {
254        overlay = getByID('baguetteBox-overlay');
255        // Check if the overlay already exists
256        if (overlay) {
257            slider = getByID('baguetteBox-slider');
258            previousButton = getByID('previous-button');
259            nextButton = getByID('next-button');
260            closeButton = getByID('close-button');
261            return;
262        }
263        // Create overlay element
264        overlay = create('div');
265        overlay.setAttribute('role', 'dialog');
266        overlay.id = 'baguetteBox-overlay';
267        document.getElementsByTagName('body')[0].appendChild(overlay);
268        // Create gallery slider element
269        slider = create('div');
270        slider.id = 'baguetteBox-slider';
271        overlay.appendChild(slider);
272        // Create all necessary buttons
273        previousButton = create('button');
274        previousButton.setAttribute('type', 'button');
275        previousButton.id = 'previous-button';
276        previousButton.setAttribute('aria-label', 'Previous');
277        previousButton.innerHTML = supports.svg ? leftArrow : '&lt;';
278        overlay.appendChild(previousButton);
279
280        nextButton = create('button');
281        nextButton.setAttribute('type', 'button');
282        nextButton.id = 'next-button';
283        nextButton.setAttribute('aria-label', 'Next');
284        nextButton.innerHTML = supports.svg ? rightArrow : '&gt;';
285        overlay.appendChild(nextButton);
286
287        closeButton = create('button');
288        closeButton.setAttribute('type', 'button');
289        closeButton.id = 'close-button';
290        closeButton.setAttribute('aria-label', 'Close');
291        closeButton.innerHTML = supports.svg ? closeX : '&times;';
292        overlay.appendChild(closeButton);
293
294        previousButton.className = nextButton.className = closeButton.className = 'baguetteBox-button';
295
296        bindEvents();
297    }
298
299    function keyDownHandler(event) {
300        switch (event.keyCode) {
301        case 37: // Left arrow
302            showPreviousImage();
303            break;
304        case 39: // Right arrow
305            showNextImage();
306            break;
307        case 27: // Esc
308            hideOverlay();
309            break;
310        case 36: // Home
311            showFirstImage(event);
312            break;
313        case 35: // End
314            showLastImage(event);
315            break;
316        }
317    }
318
319    function bindEvents() {
320        var 
vendor: 16,252 bytes, lines 320-789
320options = supports.passiveEvents ? { passive: true } : null;
321        bind(overlay, 'click', overlayClickHandler);
322        bind(previousButton, 'click', previousButtonClickHandler);
323        bind(nextButton, 'click', nextButtonClickHandler);
324        bind(closeButton, 'click', closeButtonClickHandler);
325        bind(slider, 'contextmenu', contextmenuHandler);
326        bind(overlay, 'touchstart', touchstartHandler, options);
327        bind(overlay, 'touchmove', touchmoveHandler, options);
328        bind(overlay, 'touchend', touchendHandler);
329        bind(document, 'focus', trapFocusInsideOverlay, true);
330    }
331
332    function unbindEvents() {
333        var options = supports.passiveEvents ? { passive: true } : null;
334        unbind(overlay, 'click', overlayClickHandler);
335        unbind(previousButton, 'click', previousButtonClickHandler);
336        unbind(nextButton, 'click', nextButtonClickHandler);
337        unbind(closeButton, 'click', closeButtonClickHandler);
338        unbind(slider, 'contextmenu', contextmenuHandler);
339        unbind(overlay, 'touchstart', touchstartHandler, options);
340        unbind(overlay, 'touchmove', touchmoveHandler, options);
341        unbind(overlay, 'touchend', touchendHandler);
342        unbind(document, 'focus', trapFocusInsideOverlay, true);
343    }
344
345    function prepareOverlay(gallery, userOptions) {
346        // If the same gallery is being opened prevent from loading it once again
347        if (currentGallery === gallery) {
348            return;
349        }
350        currentGallery = gallery;
351        // Update gallery specific options
352        setOptions(userOptions);
353        // Empty slider of previous contents (more effective than .innerHTML = "")
354        while (slider.firstChild) {
355            slider.removeChild(slider.firstChild);
356        }
357        imagesElements.length = 0;
358
359        var imagesFiguresIds = [];
360        var imagesCaptionsIds = [];
361        // Prepare and append images containers and populate figure and captions IDs arrays
362        for (var i = 0, fullImage; i < gallery.length; i++) {
363            fullImage = create('div');
364            fullImage.className = 'full-image';
365            fullImage.id = 'baguette-img-' + i;
366            imagesElements.push(fullImage);
367
368            imagesFiguresIds.push('baguetteBox-figure-' + i);
369            imagesCaptionsIds.push('baguetteBox-figcaption-' + i);
370            slider.appendChild(imagesElements[i]);
371        }
372        overlay.setAttribute('aria-labelledby', imagesFiguresIds.join(' '));
373        overlay.setAttribute('aria-describedby', imagesCaptionsIds.join(' '));
374    }
375
376    function setOptions(newOptions) {
377        if (!newOptions) {
378            newOptions = {};
379        }
380        // Fill options object
381        for (var item in defaults) {
382            options[item] = defaults[item];
383            if (typeof newOptions[item] !== 'undefined') {
384                options[item] = newOptions[item];
385            }
386        }
387        /* Apply new options */
388        // Change transition for proper animation
389        slider.style.transition = slider.style.webkitTransition = (options.animation === 'fadeIn' ? 'opacity .4s ease' :
390            options.animation === 'slideIn' ? '' : 'none');
391        // Hide buttons if necessary
392        if (options.buttons === 'auto' && ('ontouchstart' in window || currentGallery.length === 1)) {
393            options.buttons = false;
394        }
395        // Set buttons style to hide or display them
396        previousButton.style.display = nextButton.style.display = (options.buttons ? '' : 'none');
397        // Set overlay color
398        try {
399            overlay.style.backgroundColor = options.overlayBackgroundColor;
400        } catch (e) {
401            // Silence the error and continue
402        }
403    }
404
405    function showOverlay(chosenImageIndex) {
406        if (options.noScrollbars) {
407            document.documentElement.style.overflowY = 'hidden';
408            document.body.style.overflowY = 'scroll';
409        }
410        if (overlay.style.display === 'block') {
411            return;
412        }
413
414        bind(document, 'keydown', keyDownHandler);
415        currentIndex = chosenImageIndex;
416        touch = {
417            count: 0,
418            startX: null,
419            startY: null
420        };
421        loadImage(currentIndex, function() {
422            preloadNext(currentIndex);
423            preloadPrev(currentIndex);
424        });
425
426        updateOffset();
427        overlay.style.display = 'block';
428        if (options.fullScreen) {
429            enterFullScreen();
430        }
431        // Fade in overlay
432        setTimeout(function() {
433            overlay.className = 'visible';
434            if (options.bodyClass && document.body.classList) {
435                document.body.classList.add(options.bodyClass);
436            }
437            if (options.afterShow) {
438                options.afterShow();
439            }
440        }, 50);
441        if (options.onChange) {
442            options.onChange(currentIndex, imagesElements.length);
443        }
444        documentLastFocus = document.activeElement;
445        initFocus();
446        isOverlayVisible = true;
447    }
448
449    function initFocus() {
450        if (options.buttons) {
451            previousButton.focus();
452        } else {
453            closeButton.focus();
454        }
455    }
456
457    function enterFullScreen() {
458        if (overlay.requestFullscreen) {
459            overlay.requestFullscreen();
460        } else if (overlay.webkitRequestFullscreen) {
461            overlay.webkitRequestFullscreen();
462        } else if (overlay.mozRequestFullScreen) {
463            overlay.mozRequestFullScreen();
464        }
465    }
466
467    function exitFullscreen() {
468        if (document.exitFullscreen) {
469            document.exitFullscreen();
470        } else if (document.mozCancelFullScreen) {
471            document.mozCancelFullScreen();
472        } else if (document.webkitExitFullscreen) {
473            document.webkitExitFullscreen();
474        }
475    }
476
477    function hideOverlay() {
478        if (options.noScrollbars) {
479            document.documentElement.style.overflowY = 'auto';
480            document.body.style.overflowY = 'auto';
481        }
482        if (overlay.style.display === 'none') {
483            return;
484        }
485
486        unbind(document, 'keydown', keyDownHandler);
487        // Fade out and hide the overlay
488        overlay.className = '';
489        setTimeout(function() {
490            overlay.style.display = 'none';
491            if (document.fullscreen) {
492                exitFullscreen();
493            }
494            if (options.bodyClass && document.body.classList) {
495                document.body.classList.remove(options.bodyClass);
496            }
497            if (options.afterHide) {
498                options.afterHide();
499            }
500            documentLastFocus && documentLastFocus.focus();
501            isOverlayVisible = false;
502        }, 500);
503    }
504
505    function loadImage(index, callback) {
506        var imageContainer = imagesElements[index];
507        var galleryItem = currentGallery[index];
508
509        // Return if the index exceeds prepared images in the overlay
510        // or if the current gallery has been changed / closed
511        if (typeof imageContainer === 'undefined' || typeof galleryItem === 'undefined') {
512            return;
513        }
514
515        // If image is already loaded run callback and return
516        if (imageContainer.getElementsByTagName('img')[0]) {
517            if (callback) {
518                callback();
519            }
520            return;
521        }
522
523        // Get element reference, optional caption and source path
524        var imageElement = galleryItem.imageElement;
525        var thumbnailElement = imageElement.getElementsByTagName('img')[0];
526        var imageCaption = typeof options.captions === 'function' ?
527            options.captions.call(currentGallery, imageElement) :
528            imageElement.getAttribute('data-caption') || imageElement.title;
529        var imageSrc = getImageSrc(imageElement);
530
531        // Prepare figure element
532        var figure = create('figure');
533        figure.id = 'baguetteBox-figure-' + index;
534        figure.innerHTML = '<div class="baguetteBox-spinner">' +
535            '<div class="baguetteBox-double-bounce1"></div>' +
536            '<div class="baguetteBox-double-bounce2"></div>' +
537            '</div>';
538        // Insert caption if available
539        if (options.captions && imageCaption) {
540            var figcaption = create('figcaption');
541            figcaption.id = 'baguetteBox-figcaption-' + index;
542            figcaption.innerHTML = imageCaption;
543            figure.appendChild(figcaption);
544        }
545        imageContainer.appendChild(figure);
546
547        // Prepare gallery img element
548        var image = create('img');
549        image.onload = function() {
550            // Remove loader element
551            var spinner = document.querySelector('#baguette-img-' + index + ' .baguetteBox-spinner');
552            figure.removeChild(spinner);
553            if (!options.async && callback) {
554                callback();
555            }
556        };
557        image.setAttribute('src', imageSrc);
558        image.alt = thumbnailElement ? thumbnailElement.alt || '' : '';
559        if (options.titleTag && imageCaption) {
560            image.title = imageCaption;
561        }
562        figure.appendChild(image);
563
564        // Run callback
565        if (options.async && callback) {
566            callback();
567        }
568    }
569
570    // Get image source location, mostly used for responsive images
571    function getImageSrc(image) {
572        // Set default image path from href
573        var result = image.href;
574        // If dataset is supported find the most suitable image
575        if (image.dataset) {
576            var srcs = [];
577            // Get all possible image versions depending on the resolution
578            for (var item in image.dataset) {
579                if (item.substring(0, 3) === 'at-' && !isNaN(item.substring(3))) {
580                    srcs[item.replace('at-', '')] = image.dataset[item];
581                }
582            }
583            // Sort resolutions ascending
584            var keys = Object.keys(srcs).sort(function(a, b) {
585                return parseInt(a, 10) < parseInt(b, 10) ? -1 : 1;
586            });
587            // Get real screen resolution
588            var width = window.innerWidth * window.devicePixelRatio;
589            // Find the first image bigger than or equal to the current width
590            var i = 0;
591            while (i < keys.length - 1 && keys[i] < width) {
592                i++;
593            }
594            result = srcs[keys[i]] || result;
595        }
596        return result;
597    }
598
599    // Return false at the right end of the gallery
600    function showNextImage() {
601        return show(currentIndex + 1);
602    }
603
604    // Return false at the left end of the gallery
605    function showPreviousImage() {
606        return show(currentIndex - 1);
607    }
608
609    // Return false at the left end of the gallery
610    function showFirstImage(event) {
611        if (event) {
612            event.preventDefault();
613        }
614        return show(0);
615    }
616
617    // Return false at the right end of the gallery
618    function showLastImage(event) {
619        if (event) {
620            event.preventDefault();
621        }
622        return show(currentGallery.length - 1);
623    }
624
625    /**
626     * Move the gallery to a specific index
627     * @param `index` {number} - the position of the image
628     * @param `gallery` {array} - gallery which should be opened, if omitted assumes the currently opened one
629     * @return {boolean} - true on success or false if the index is invalid
630     */
631    function show(index, gallery) {
632        if (!isOverlayVisible && index >= 0 && index < gallery.length) {
633            prepareOverlay(gallery, options);
634            showOverlay(index);
635            return true;
636        }
637        if (index < 0) {
638            if (options.animation) {
639                bounceAnimation('left');
640            }
641            return false;
642        }
643        if (index >= imagesElements.length) {
644            if (options.animation) {
645                bounceAnimation('right');
646            }
647            return false;
648        }
649
650        currentIndex = index;
651        loadImage(currentIndex, function() {
652            preloadNext(currentIndex);
653            preloadPrev(currentIndex);
654        });
655        updateOffset();
656
657        if (options.onChange) {
658            options.onChange(currentIndex, imagesElements.length);
659        }
660
661        return true;
662    }
663
664    /**
665     * Triggers the bounce animation
666     * @param {('left'|'right')} direction - Direction of the movement
667     */
668    function bounceAnimation(direction) {
669        slider.className = 'bounce-from-' + direction;
670        setTimeout(function() {
671            slider.className = '';
672        }, 400);
673    }
674
675    function updateOffset() {
676        var offset = -currentIndex * 100 + '%';
677        if (options.animation === 'fadeIn') {
678            slider.style.opacity = 0;
679            setTimeout(function() {
680                supports.transforms ?
681                    slider.style.transform = slider.style.webkitTransform = 'translate3d(' + offset + ',0,0)'
682                    : slider.style.left = offset;
683                slider.style.opacity = 1;
684            }, 400);
685        } else {
686            supports.transforms ?
687                slider.style.transform = slider.style.webkitTransform = 'translate3d(' + offset + ',0,0)'
688                : slider.style.left = offset;
689        }
690    }
691
692    // CSS 3D Transforms test
693    function testTransformsSupport() {
694        var div = create('div');
695        return typeof div.style.perspective !== 'undefined' || typeof div.style.webkitPerspective !== 'undefined';
696    }
697
698    // Inline SVG test
699    function testSvgSupport() {
700        var div = create('div');
701        div.innerHTML = '<svg/>';
702        return (div.firstChild && div.firstChild.namespaceURI) === 'http://www.w3.org/2000/svg';
703    }
704
705    // Borrowed from https://github.com/seiyria/bootstrap-slider/pull/680/files
706    /* eslint-disable getter-return */
707    function testPassiveEventsSupport() {
708        var passiveEvents = false;
709        try {
710            var opts = Object.defineProperty({}, 'passive', {
711                get: function() {
712                    passiveEvents = true;
713                }
714            });
715            window.addEventListener('test', null, opts);
716        } catch (e) { /* Silence the error and continue */ }
717
718        return passiveEvents;
719    }
720    /* eslint-enable getter-return */
721
722    function preloadNext(index) {
723        if (index - currentIndex >= options.preload) {
724            return;
725        }
726        loadImage(index + 1, function() {
727            preloadNext(index + 1);
728        });
729    }
730
731    function preloadPrev(index) {
732        if (currentIndex - index >= options.preload) {
733            return;
734        }
735        loadImage(index - 1, function() {
736            preloadPrev(index - 1);
737        });
738    }
739
740    function bind(element, event, callback, options) {
741        if (element.addEventListener) {
742            element.addEventListener(event, callback, options);
743        } else {
744            // IE8 fallback
745            element.attachEvent('on' + event, function(event) {
746                // `event` and `event.target` are not provided in IE8
747                event = event || window.event;
748                event.target = event.target || event.srcElement;
749                callback(event);
750            });
751        }
752    }
753
754    function unbind(element, event, callback, options) {
755        if (element.removeEventListener) {
756            element.removeEventListener(event, callback, options);
757        } else {
758            // IE8 fallback
759            element.detachEvent('on' + event, callback);
760        }
761    }
762
763    function getByID(id) {
764        return document.getElementById(id);
765    }
766
767    function create(element) {
768        return document.createElement(element);
769    }
770
771    function destroyPlugin() {
772        unbindEvents();
773        clearCachedData();
774        unbind(document, 'keydown', keyDownHandler);
775        document.getElementsByTagName('body')[0].removeChild(document.getElementById('baguetteBox-overlay'));
776        data = {};
777        currentGallery = [];
778        currentIndex = 0;
779    }
780
781    return {
782        run: run,
783        show: show,
784        showNext: showNextImage,
785        showPrevious: showPreviousImage,
786        hide: hideOverlay,
787        destroy: destroyPlugin
788    };
789}));

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.