PageSourceSearch

https://www.writersrepublic.com/themes/writers-republic/assets/vendor/lightbox/dist/ekko-lightbox.js

js writersrepublic.com collected 2026-09-24 10:27:43 UTC 25,822 bytes, 694 lines download raw bytes

1/*!
2 * Lightbox for Bootstrap by @ashleydw
3 * https://github.com/ashleydw/lightbox
4 *
5 * License: https://github.com/ashleydw/lightbox/blob/master/LICENSE
6 */
7+function ($) {
8
9'use strict';
10
11var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
12
13function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
14
15var Lightbox = (function ($) {
16
17	var NAME = 'ekkoLightbox';
18	var JQUERY_NO_CONFLICT = $.fn[NAME];
19
20	var Default = {
21		title: '',
22		footer: '',
23		maxWidth: 9999,
24		maxHeight: 9999,
25		showArrows: true, //display the left / right arrows or not
26		wrapping: true, //if true, gallery loops infinitely
27		type: null, //force the lightbox into image / youtube mode. if null, or not image|youtube|vimeo; detect it
28		alwaysShowClose: false, //always show the close button, even if there is no title
29		loadingMessage: '<div class="ekko-lightbox-loader"><div><div></div><div></div></div></div>', // http://tobiasahlin.com/spinkit/
30		leftArrow: '<span>&#10094;</span>',
31		rightArrow: '<span>&#10095;</span>',
32		strings: {
33			close: 'Close',
34			fail: 'Failed to load image:',
35			type: 'Could not detect remote target type. Force the type using data-type'
36		},
37		doc: document, // if in an iframe can specify top.document
38		onShow: function onShow() {},
39		onShown: function onShown() {},
40		onHide: function onHide() {},
41		onHidden: function onHidden() {},
42		onNavigate: function onNavigate() {},
43		onContentLoaded: function onContentLoaded() {}
44	};
45
46	var Lightbox = (function () {
47		_createClass(Lightbox, null, [{
48			key: 'Default',
49
50			/**
51       Class properties:
52   	 _$element: null -> the <a> element currently being displayed
53    _$modal: The bootstrap modal generated
54       _$modalDialog: The .modal-dialog
55       _$modalContent: The .modal-content
56       _$modalBody: The .modal-body
57       _$modalHeader: The .modal-header
58       _$modalFooter: The .modal-footer
59    _$lightboxContainerOne: Container of the first lightbox element
60    _$lightboxContainerTwo: Container of the second lightbox element
61    _$lightboxBody: First element in the container
62    _$modalArrows: The overlayed arrows container
63   	 _$galleryItems: Other <a>'s available for this gallery
64    _galleryName: Name of the current data('gallery') showing
65    _galleryIndex: The current index of the _$galleryItems being shown
66   	 _config: {} the options for the modal
67    _modalId: unique id for the current lightbox
68    _padding / _border: CSS properties for the modal container; these are used to calculate the available space for the content
69   	 */
70
71			get: function get() {
72				return Default;
73			}
74		}]);
75
76		function Lightbox($element, config) {
77			var _this = this;
78
79			_classCallCheck(this, Lightbox);
80
81			this._config = $.extend({}, Default, config);
82			this._$modalArrows = null;
83			this._galleryIndex = 0;
84			this._galleryName = null;
85			this._padding = null;
86			this._border = null;
87			this._titleIsShown = false;
88			this._footerIsShown = false;
89			this._wantedWidth = 0;
90			this._wantedHeight = 0;
91			this._touchstartX = 0;
92			this._touchendX = 0;
93
94			this._modalId = 'ekkoLightbox-' + Math.floor(Math.random() * 1000 + 1);
95			this._$element = $element instanceof jQuery ? $element : $($element);
96
97			this._isBootstrap3 = $.fn.modal.Constructor.VERSION[0] == 3;
98
99			var h4 = '<h4 class="modal-title">' + (this._config.title || "&nbsp;") + '</h4>';
100			var btn = '<button type="button" class="close" data-dismiss="modal" aria-label="' + this._config.strings.close + '"><span aria-hidden="true">&times;</span></button>';
101
102			var header = '<div class="modal-header' + (this._config.title || this._config.alwaysShowClose ? '' : ' hide') + '">' + (this._isBootstrap3 ? btn + h4 : h4 + btn) + '</div>';
103			var footer = '<div class="modal-footer' + (this._config.footer ? '' : ' hide') + '">' + (this._config.footer || "&nbsp;") + '</div>';
104			var body = '<div class="modal-body"><div class="ekko-lightbox-container"><div class="ekko-lightbox-item fade in show"></div><div class="ekko-lightbox-item fade"></div></div></div>';
105			var dialog = '<div class="modal-dialog" role="document"><div class="modal-content">' + header + body + footer + '</div></div>';
106			$(this._config.doc.body).append('<div id="' + this._modalId + '" class="ekko-lightbox modal fade" tabindex="-1" tabindex="-1" role="dialog" aria-hidden="true">' + dialog + '</div>');
107
108			this._$modal = $('#' + this._modalId, this._config.doc);
109			this._$modalDialog = this._$modal.find('.modal-dialog').first();
110			this._$modalContent = this._$modal.find('.modal-content').first();
111			this._$modalBody = this._$modal.find('.modal-body').first();
112			this._$modalHeader = this._$modal.find('.modal-header').first();
113			this._$modalFooter = this._$modal.find('.modal-footer').first();
114
115			this._$lightboxContainer = this._$modalBody.find('.ekko-lightbox-container').first();
116			this._$lightboxBodyOne = this._$lightboxContainer.find('> div:first-child').first();
117			this._$lightboxBodyTwo = this._$lightboxContainer.find('> div:last-child').first();
118
119			this._border = this._calculateBorders();
120			this._padding = this._calculatePadding();
121
122			this._galleryName = this._$element.data('gallery');
123			if (this._galleryName) {
124				this._$galleryItems = $(document.body).find('*[data-gallery="' + this._galleryName + '"]');
125				this._galleryIndex = this._$galleryItems.index(this._$element);
126				$(document).on('keydown.ekkoLightbox', this._navigationalBinder.bind(this));
127
128				// add the directional arrows to the modal
129				if (this._config.showArrows && this._$galleryItems.length > 1) {
130					this._$lightboxContainer.append('<div class="ekko-lightbox-nav-overlay"><a href="#">' + this._config.leftArrow + '</a><a href="#">' + this._config.rightArrow + '</a></div>');
131					this._$modalArrows = this._$lightboxContainer.find('div.ekko-lightbox-nav-overlay').first();
132					this._$lightboxContainer.on('click', 'a:first-child', function (event) {
133						event.preventDefault();
134						return _this.navigateLeft();
135					});
136					this._$lightboxContainer.on('click', 'a:last-child', function (event) {
137						event.preventDefault();
138						return _this.navigateRight();
139					});
140					this.updateNavigation();
141				}
142			}
143
144			this._$modal.on('show.bs.modal', this._config.onShow.bind(this)).on('shown.bs.modal', function () {
145				_this._toggleLoading(true);
146				_this._handle();
147				return _this._config.onShown.call(_this);
148			}).on('hide.bs.modal', this._config.onHide.bind(this)).on('hidden.bs.modal', function () {
149				if (_this._galleryName) {
150					$(document).off('keydown.ekkoLightbox');
151					$(window).off('resize.ekkoLightbox');
152				}
153				_this._$modal.remove();
154				return _this._config.onHidden.call(_this);
155			}).modal(this._config);
156
157			$(window).on('resize.ekkoLightbox', function () {
158				_this._resize(_this._wantedWidth, _this._wantedHeight);
159			});
160			this._$lightboxContainer.on('touchstart', function () {
161				_this._touchstartX = event.changedTouches[0].screenX;
162			}).on('touchend', function () {
163				_this._touchendX = event.changedTouches[0].screenX;
164				_this._swipeGesure();
165			});
166		}
167
168		_createClass(Lightbox, [{
169			key: 'element',
170			value: function element() {
171				return this._$element;
172			}
173		}, {
174			key: 'modal',
175			value: function modal() {
176				return this._$modal;
177			}
178		}, {
179			key: 'navigateTo',
180			value: function navigateTo(index) {
181
182				if (index < 0 || index > this._$galleryItems.length - 1) return this;
183
184				this._galleryIndex = index;
185
186				this.updateNavigation();
187
188				this._$element = $(this._$galleryItems.get(this._galleryIndex));
189				this._handle();
190			}
191		}, {
192			key: 'navigateLeft',
193			value: function navigateLeft() {
194
195				if (!this._$galleryItems) return;
196
197				if (this._$galleryItems.length === 1) return;
198
199				if (this._galleryIndex === 0) {
200					if (this._config.wrapping) this._galleryIndex = this._$galleryItems.length - 1;else return;
201				} else //circular
202					this._galleryIndex--;
203
204				this._config.onNavigate.call(this, 'left', this._galleryIndex);
205				return this.navigateTo(this._galleryIndex);
206			}
207		}, {
208			key: 'navigateRight',
209			value: function navigateRight() {
210
211				if (!this._$galleryItems) return;
212
213				if (this._$galleryItems.length === 1) return;
214
215				if (this._galleryIndex === this._$galleryItems.length - 1) {
216					if (this._config.wrapping) this._galleryIndex = 0;else return;
217				} else //circular
218					this._galleryIndex++;
219
220				this._config.onNavigate.call(this, 'right', this._galleryIndex);
221				return this.navigateTo(this._galleryIndex);
222			}
223		}, {
224			key: 'updateNavigation',
225			value: function updateNavigation() {
226				if (!this._config.wrapping) {
227					var $nav = this._$lightboxContainer.find('div.ekko-lightbox-nav-overlay');
228					if (this._galleryIndex === 0) $nav.find('a:first-child').addClass('disabled');else $nav.find('a:first-child').removeClass('disabled');
229
230					if (this._galleryIndex === this._$galleryItems.length - 1) $nav.find('a:last-child').addClass('disabled');else $nav.find('a:last-child').removeClass('disabled');
231				}
232			}
233		}, {
234			key: 'close',
235			value: function close() {
236				return this._$modal.modal('hide');
237			}
238
239			// helper private methods
240		}, {
241			key: '_navigationalBinder',
242			value: function _navigationalBinder(event) {
243				event = event || window.event;
244				if (event.keyCode === 39) return this.navigateRight();
245				if (event.keyCode === 37) return this.navigateLeft();
246			}
247
248			// type detection private methods
249		}, {
250			key: '_detectRemoteType',
251			value: function _detectRemoteType(src, type) {
252
253				type = type || false;
254
255				if (!type && this._isImage(src)) type = 'image';
256				if (!type && this._getYoutubeId(src)) type = 'youtube';
257				if (!type && this._getVimeoId(src)) type = 'vimeo';
258				if (!type && this._getInstagramId(src)) type = 'instagram';
259				if (type == 'audio' || type == 'video' || !type && this._isMedia(src)) type = 'media';
260				if (!type || ['image', 'youtube', 'vimeo', 'instagram', 'media', 'url'].indexOf(type) < 0) type = 'url';
261
262				return type;
263			}
264		}, {
265			key: '_getRemoteContentType',
266			value: function _getRemoteContentType(src) {
267				var response = $.ajax({
268					type: 'HEAD',
269					url: src,
270					async: false
271				});
272				var contentType = response.getResponseHeader('Content-Type');
273				return contentType;
274			}
275		}, {
276			key: '_isImage',
277			value: function _isImage(string) {
278				return string && string.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
279			}
280		}, {
281			key: '_isMedia',
282			value: function _isMedia(string) {
283				return string && string.match(/(\.(mp3|mp4|ogg|webm|wav)((\?|#).*)?$)/i);
284			}
285		}, {
286			key: '_containerToUse',
287			value: function _containerToUse() {
288				var _this2 = this;
289
290				// if currently showing an image, fade it out and remove
291				var $toUse = this._$lightboxBodyTwo;
292				var $current = this._$lightboxBodyOne;
293
294				if (this._$lightboxBodyTwo.hasClass('in')) {
295					$toUse = this._$lightboxBodyOne;
296					$current = this._$lightboxBodyTwo;
297				}
298
299				$current.removeClass('in show');
300				setTimeout(function () {
301					if (!_this2._$lightboxBodyTwo.hasClass('in')) _this2._$lightboxBodyTwo.empty();
302					if (!_this2._$lightboxBodyOne.hasClass('in')) _this2._$lightboxBodyOne.empty();
303				}, 500);
304
305				$toUse.addClass('in show');
306				return $toUse;
307			}
308		}, {
309			key: '_handle',
310			value: function _handle() {
311
312				var $toUse = this._containerToUse();
313				this._updateTitleAndFooter();
314
315				var currentRemote = this._$element.attr('data-remote') || this._$element.attr('href');
316				var currentType = this._detectRemoteType(currentRemote, this._$element.attr('data-type') || false);
317
318				if (['image', 'youtube', 'vimeo', 'instagram', 'media', 'url'].indexOf(currentType) < 0) return this._error(this._config.strings.type);
319
320				switch (currentType) {
321					case 'image':
322						this._preloadImage(currentRemote, $toUse);
323						this._preloadImageByIndex(this._galleryIndex, 3);
324						break;
325					case 'youtube':
326						this._showYoutubeVideo(currentRemote, $toUse);
327						break;
328					case 'vimeo':
329						this._showVimeoVideo(this._getVimeoId(currentRemote), $toUse);
330						break;
331					case 'instagram':
332						this._showInstagramVideo(this._getInstagramId(currentRemote), $toUse);
333						break;
334					case 'media':
335						this._showHtml5Media(currentRemote, $toUse);
336						break;
337					default:
338						// url
339						this._loadRemoteContent(currentRemote, $toUse);
340						break;
341				}
342
343				return this;
344			}
345		}, {
346			key: '_getYoutubeId',
347			value: function _getYoutubeId(string) {
348				if (!string) return false;
349				var matches = string.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);
350				return matches && matches[2].length === 11 ? matches[2] : false;
351			}
352		}, {
353			key: '_getVimeoId',
354			value: function _getVimeoId(string) {
355				return string && string.indexOf('vimeo') > 0 ? string : false;
356			}
357		}, {
358			key: '_getInstagramId',
359			value: function _getInstagramId(string) {
360				return string && string.indexOf('instagram') > 0 ? string : false;
361			}
362
363			// layout private methods
364		}, {
365			key: '_toggleLoading',
366			value: function _toggleLoading(show) {
367				show = show || false;
368				if (show) {
369					this._$modalDialog.css('display', 'none');
370					this._$modal.removeClass('in show');
371					$('.modal-backdrop').append(this._config.loadingMessage);
372				} else {
373					this._$modalDialog.css('display', 'block');
374					this._$modal.addClass('in show');
375					$('.modal-backdrop').find('.ekko-lightbox-loader').remove();
376				}
377				return this;
378			}
379		}, {
380			key: '_calculateBorders',
381			value: function _calculateBorders() {
382				return {
383					top: this._totalCssByAttribute('border-top-width'),
384					right: this._totalCssByAttribute('border-right-width'),
385					bottom: this._totalCssByAttribute('border-bottom-width'),
386					left: this._totalCssByAttribute('border-left-width')
387				};
388			}
389		}, {
390			key: '_calculatePadding',
391			value: function _calculatePadding() {
392				return {
393					top: this._totalCssByAttribute('padding-top'),
394					right: this._totalCssByAttribute('padding-right'),
395					bottom: this._totalCssByAttribute('padding-bottom'),
396					left: this._totalCssByAttribute('padding-left')
397				};
398			}
399		}, {
400			key: '_totalCssByAttribute',
401			value: function _totalCssByAttribute(attribute) {
402				return parseInt(this._$modalDialog.css(attribute), 10) + parseInt(this._$modalContent.css(attribute), 10) + parseInt(this._$modalBody.css(attribute), 10);
403			}
404		}, {
405			key: '_updateTitleAndFooter',
406			value: function _updateTitleAndFooter() {
407				var title = this._$element.data('title') || "";
408				var caption = this._$element.data('footer') || "";
409
410				this._titleIsShown = false;
411				if (title || this._config.alwaysShowClose) {
412					this._titleIsShown = true;
413					this._$modalHeader.css('display', '').find('.modal-title').html(title || "&nbsp;");
414				} else this._$modalHeader.css('display', 'none');
415
416				this._footerIsShown = false;
417				if (caption) {
418					this._footerIsShown = true;
419					this._$modalFooter.css('display', '').html(caption);
420				} else this._$modalFooter.css('display', 'none');
421
422				return this;
423			}
424		}, {
425			key: '_showYoutubeVideo',
426			value: function _showYoutubeVideo(remote, $containerForElement) {
427				var id = this._getYoutubeId(remote);
428				var query = remote.indexOf('&') > 0 ? remote.substr(remote.indexOf('&')) : '';
429				var width = this._$element.data('width') || 560;
430				var height = this._$element.data('height') || width / (560 / 315);
431				return this._showVideoIframe('//www.youtube.com/embed/' + id + '?badge=0&autoplay=1&html5=1' + query, width, height, $containerForElement);
432			}
433		}, {
434			key: '_showVimeoVideo',
435			value: function _showVimeoVideo(id, $containerForElement) {
436				var width = this._$element.data('width') || 500;
437				var height = this._$element.data('height') || width / (560 / 315);
438				return this._showVideoIframe(id + '?autoplay=1', width, height, $containerForElement);
439			}
440		}, {
441			key: '_showInstagramVideo',
442			value: function _showInstagramVideo(id, $containerForElement) {
443				// instagram load their content into iframe's so this can be put straight into the element
444				var width = this._$element.data('width') || 612;
445				var height = width + 80;
446				id = id.substr(-1) !== '/' ? id + '/' : id; // ensure id has trailing slash
447				$containerForElement.html('<iframe width="' + width + '" height="' + height + '" src="' + id + 'embed/" frameborder="0" allowfullscreen></iframe>');
448				this._resize(width, height);
449				this._config.onContentLoaded.call(this);
450				if (this._$modalArrows) //hide the arrows when showing video
451					this._$modalArrows.css('display', 'none');
452				this._toggleLoading(false);
453				return this;
454			}
455		}, {
456			key: '_showVideoIframe',
457			value: function _showVideoIframe(url, width, height, $containerForElement) {
458				// should be used for videos only. for remote content use loadRemoteContent (data-type=url)
459				height = height || width; // default to square
460				$containerForElement.html('<div class="embed-responsive embed-responsive-16by9"><iframe width="' + width + '" height="' + height + '" src="' + url + '" frameborder="0" allowfullscreen class="embed-responsive-item"></iframe></div>');
461				this._resize(width, height);
462				this._config.onContentLoaded.call(this);
463				if (this._$modalArrows) this._$modalArrows.css('display', 'none'); //hide the arrows when showing video
464				this._toggleLoading(false);
465				return this;
466			}
467		}, {
468			key: '_showHtml5Media',
469			value: function _showHtml5Media(url, $containerForElement) {
470				// should be used for videos only. for remote content use loadRemoteContent (data-type=url)
471				var contentType = this._getRemoteContentType(url);
472				if (!contentType) {
473					return this._error(this._config.strings.type);
474				}
475				var mediaType = '';
476				if (contentType.indexOf('audio') > 0) {
477					mediaType = 'audio';
478				} else {
479					mediaType = 'video';
480				}
481				var width = this._$element.data('width') || 560;
482				var height = this._$element.data('height') || width / (560 / 315);
483				$containerForElement.html('<div class="embed-responsive embed-responsive-16by9"><' + mediaType + ' width="' + width + '" height="' + height + '" preload="auto" autoplay controls class="embed-responsive-item"><source src="' + url + '" type="' + contentType + '">' + this._config.strings.type + '</' + mediaType + '></div>');
484				this._resize(width, height);
485				this._config.onContentLoaded.call(this);
486				if (this._$modalArrows) this._$modalArrows.css('display', 'none'); //hide the arrows when showing video
487				this._toggleLoading(false);
488				return this;
489			}
490		}, {
491			key: '_loadRemoteContent',
492			value: function _loadRemoteContent(url, $containerForElement) {
493				var _this3 = this;
494
495				var width = this._$element.data('width') || 560;
496				var height = this._$element.data('height') || 560;
497
498				var disableExternalCheck = this._$element.data('disableExternalCheck') || false;
499				this._toggleLoading(false);
500
501				// external urls are loading into an iframe
502				// local ajax can be loaded into the container itself
503				if (!disableExternalCheck && !this._isExternal(url)) {
504					$containerForElement.load(url, $.proxy(function () {
505						return _this3._$element.trigger('loaded.bs.modal');l;
506					}));
507				} else {
508					$containerForElement.html('<iframe src="' + url + '" frameborder="0" allowfullscreen></iframe>');
509					this._config.onContentLoaded.call(this);
510				}
511
512				if (this._$modalArrows) //hide the arrows when remote content
513					this._$modalArrows.css('display', 'none');
514
515				this._resize(width, height);
516				return this;
517			}
518		}, {
519			key: '_isExternal',
520			value: function _isExternal(url) {
521				var match = url.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);
522				if (typeof match[1] === "string" && match[1].length > 0 && match[1].toLowerCase() !== location.protocol) return true;
523
524				if (typeof match[2] === "string" && match[2].length > 0 && match[2].replace(new RegExp(':(' + ({
525					"http:": 80,
526					"https:": 443
527				})[location.protocol] + ')?$'), "") !== location.host) return true;
528
529				return false;
530			}
531		}, {
532			key: '_error',
533			value: function _error(message) {
534				console.error(message);
535				this._containerToUse().html(message);
536				this._resize(300, 300);
537				return this;
538			}
539		}, {
540			key: '_preloadImageByIndex',
541			value: function _preloadImageByIndex(startIndex, numberOfTimes) {
542
543				if (!this._$galleryItems) return;
544
545				var next = $(this._$galleryItems.get(startIndex), false);
546				if (typeof next == 'undefined') return;
547
548				var src = next.attr('data-remote') || next.attr('href');
549				if (next.attr('data-type') === 'image' || this._isImage(src)) this._preloadImage(src, false);
550
551				if (numberOfTimes > 0) return this._preloadImageByIndex(startIndex + 1, numberOfTimes - 1);
552			}
553		}, {
554			key: '_preloadImage',
555			value: function _preloadImage(src, $containerForImage) {
556				var _this4 = this;
557
558				$containerForImage = $containerForImage || false;
559
560				var img = new Image();
561				if ($containerForImage) {
562					(function () {
563
564						// if loading takes > 200ms show a loader
565						var loadingTimeout = setTimeout(function () {
566							$containerForImage.append(_this4._config.loadingMessage);
567						}, 200);
568
569						img.onload = function () {
570							if (loadingTimeout) clearTimeout(loadingTimeout);
571							loadingTimeout = null;
572							var image = $('<img />');
573							image.attr('src', img.src);
574							image.addClass('img-fluid');
575
576							// backward compatibility for bootstrap v3
577							image.css('width', '100%');
578
579							$containerForImage.html(image);
580							if (_this4._$modalArrows) _this4._$modalArrows.css('display', ''); // remove display to default to css property
581
582							_this4._resize(img.width, img.height);
583							_this4._toggleLoading(false);
584							return _this4._config.onContentLoaded.call(_this4);
585						};
586						img.onerror = function () {
587							_this4._toggleLoading(false);
588							return _this4._error(_this4._config.strings.fail + ('  ' + src));
589						};
590					})();
591				}
592
593				img.src = src;
594				return img;
595			}
596		}, {
597			key: '_swipeGesure',
598			value: function _swipeGesure() {
599				if (this._touchendX < this._touchstartX) {
600					return this.navigateRight();
601				}
602				if (this._touchendX > this._touchstartX) {
603					return this.navigateLeft();
604				}
605			}
606		}, {
607			key: '_resize',
608			value: function _resize(width, height) {
609
610				height = height || width;
611				this._wantedWidth = width;
612				this._wantedHeight = height;
613
614				var imageAspecRatio = width / height;
615
616				// if width > the available space, scale down the expected width and height
617				var widthBorderAndPadding = this._padding.left + this._padding.right + this._border.left + this._border.right;
618
619				// force 10px margin if window size > 575px
620				var addMargin = this._config.doc.body.clientWidth > 575 ? 20 : 0;
621				var discountMargin = this._config.doc.body.clientWidth > 575 ? 0 : 20;
622
623				var maxWidth = Math.min(width + widthBorderAndPadding, this._config.doc.body.clientWidth - addMargin, this._config.maxWidth);
624
625				if (width + widthBorderAndPadding > maxWidth) {
626					height = (maxWidth - widthBorderAndPadding - discountMargin) / imageAspecRatio;
627					width = maxWidth;
628				} else width = width + widthBorderAndPadding;
629
630				var headerHeight = 0,
631				    footerHeight = 0;
632
633				// as the resize is performed the modal is show, the calculate might fail
634				// if so, default to the default sizes
635				if (this._footerIsShown) footerHeight = this._$modalFooter.outerHeight(true) || 55;
636
637				if (this._titleIsShown) headerHeight = this._$modalHeader.outerHeight(true) || 67;
638
639				var borderPadding = this._padding.top + this._padding.bottom + this._border.bottom + this._border.top;
640
641				//calculated each time as resizing the window can cause them to change due to Bootstraps fluid margins
642				var margins = parseFloat(this._$modalDialog.css('margin-top')) + parseFloat(this._$modalDialog.css('margin-bottom'));
643
644				var maxHeight = Math.min(height, $(window).height() - borderPadding - margins - headerHeight - footerHeight, this._config.maxHeight - borderPadding - headerHeight - footerHeight);
645
646				if (height > maxHeight) {
647					// if height > the available height, scale down the width
648					width = Math.ceil(maxHeight * imageAspecRatio) + widthBorderAndPadding;
649				}
650
651				this._$lightboxContainer.css('height', maxHeight);
652				this._$modalDialog.css('flex', 1).css('maxWidth', width);
653
654				var modal = this._$modal.data('bs.modal');
655				if (modal) {
656					// v4 method is mistakenly protected
657					try {
658						modal._handleUpdate();
659					} catch (Exception) {
660						modal.handleUpdate();
661					}
662				}
663				return this;
664			}
665		}], [{
666			key: '_jQueryInterface',
667			value: function _jQueryInterface(config) {
668				var _this5 = this;
669
670				config = config || {};
671				return this.each(function () {
672					var $this = $(_this5);
673					var _config = $.extend({}, Lightbox.Default, $this.data(), typeof config === 'object' && config);
674
675					new Lightbox(_this5, _config);
676				});
677			}
678		}]);
679
680		return Lightbox;
681	})();
682
683	$.fn[NAME] = Lightbox._jQueryInterface;
684	$.fn[NAME].Constructor = Lightbox;
685	$.fn[NAME].noConflict = function () {
686		$.fn[NAME] = JQUERY_NO_CONFLICT;
687		return Lightbox._jQueryInterface;
688	};
689
690	return Lightbox;
691})(jQuery);
692//# sourceMappingURL=ekko-lightbox.js.map
693
694}(jQuery);

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.