(function (factory){
if(typeof define==='function'&&define.amd){
define(['jquery'], factory);
}else if(typeof module==='object'&&module.exports){
module.exports=function (root, jQuery){
if(jQuery===undefined){
if(typeof window!=='undefined'){
jQuery=require('jquery');
}else{
jQuery=require('jquery')(root);
}}
factory(jQuery);
return jQuery;
};}else{
factory(jQuery);
}}(function ($){
var JustifiedGallery=function ($gallery, settings){
this.settings=settings;
this.checkSettings();
this.imgAnalyzerTimeout=null;
this.entries=null;
this.buildingRow={
entriesBuff: [],
width: 0,
height: 0,
aspectRatio: 0
};
this.lastFetchedEntry=null;
this.lastAnalyzedIndex=-1;
this.yield={
every: 2,
flushed: 0 
};
this.border=settings.border >=0 ? settings.border:settings.margins;
this.maxRowHeight=this.retrieveMaxRowHeight();
this.suffixRanges=this.retrieveSuffixRanges();
this.offY=this.border;
this.rows=0;
this.spinner={
phase: 0,
timeSlot: 150,
$el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'),
intervalId: null
};
this.scrollBarOn=false;
this.checkWidthIntervalId=null;
this.galleryWidth=$gallery.width();
this.$gallery=$gallery;
};
JustifiedGallery.prototype.getSuffix=function (width, height){
var longestSide, i;
longestSide=(width > height) ? width:height;
for (i=0; i < this.suffixRanges.length; i++){
if(longestSide <=this.suffixRanges[i]){
return this.settings.sizeRangeSuffixes[this.suffixRanges[i]];
}}
return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]];
};
JustifiedGallery.prototype.removeSuffix=function (str, suffix){
return str.substring(0, str.length - suffix.length);
};
JustifiedGallery.prototype.endsWith=function (str, suffix){
return str.indexOf(suffix, str.length - suffix.length)!==-1;
};
JustifiedGallery.prototype.getUsedSuffix=function (str){
for (var si in this.settings.sizeRangeSuffixes){
if(this.settings.sizeRangeSuffixes.hasOwnProperty(si)){
if(this.settings.sizeRangeSuffixes[si].length===0) continue;
if(this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si];
}}
return '';
};
JustifiedGallery.prototype.newSrc=function (imageSrc, imgWidth, imgHeight, image){
var newImageSrc;
if(this.settings.thumbnailPath){
newImageSrc=this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image);
}else{
var matchRes=imageSrc.match(this.settings.extension);
var ext=(matchRes!==null) ? matchRes[0]:'';
newImageSrc=imageSrc.replace(this.settings.extension, '');
newImageSrc=this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc));
newImageSrc +=this.getSuffix(imgWidth, imgHeight) + ext;
}
return newImageSrc;
};
JustifiedGallery.prototype.showImg=function ($entry, callback){
if(this.settings.cssAnimation){
$entry.addClass('jg-entry-visible');
if(callback) callback();
}else{
$entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
$entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
}};
JustifiedGallery.prototype.extractImgSrcFromImage=function ($image){
var imageSrc=$image.data('safe-src');
var imageSrcLoc='data-safe-src';
if(typeof imageSrc==='undefined'){
imageSrc=$image.attr('src');
imageSrcLoc='src';
}
$image.data('jg.originalSrc', imageSrc);
$image.data('jg.src', imageSrc);
$image.data('jg.originalSrcLoc', imageSrcLoc);
return imageSrc;
};
JustifiedGallery.prototype.imgFromEntry=function ($entry){
var $img=$entry.find(this.settings.imgSelector);
return $img.length===0 ? null:$img;
};
JustifiedGallery.prototype.captionFromEntry=function ($entry){
var $caption=$entry.find('> .jg-caption');
return $caption.length===0 ? null:$caption;
};
JustifiedGallery.prototype.displayEntry=function ($entry, x, y, imgWidth, imgHeight, rowHeight){
$entry.width(imgWidth);
$entry.height(rowHeight);
$entry.css('top', y);
$entry.css('left', x);
var $image=this.imgFromEntry($entry);
if($image!==null){
$image.css('width', imgWidth);
$image.css('height', imgHeight);
$image.css('margin-left', - imgWidth / 2);
$image.css('margin-top', - imgHeight / 2);
var imageSrc=$image.data('jg.src');
if(imageSrc){
imageSrc=this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]);
$image.one('error', function (){
this.resetImgSrc($image);
});
var loadNewImage=function (){
$image.attr('src', imageSrc);
};
if($entry.data('jg.loaded')==='skipped'&&imageSrc){
this.onImageEvent(imageSrc, (function(){
this.showImg($entry, loadNewImage);
$entry.data('jg.loaded', true);
}).bind(this));
}else{
this.showImg($entry, loadNewImage);
}}
}else{
this.showImg($entry);
}
this.displayEntryCaption($entry);
};
JustifiedGallery.prototype.displayEntryCaption=function ($entry){
var $image=this.imgFromEntry($entry);
if($image!==null&&this.settings.captions){
var $imgCaption=this.captionFromEntry($entry);
if($imgCaption===null){
var caption=$image.attr('alt');
if(!this.isValidCaption(caption)) caption=$entry.attr('title');
if(this.isValidCaption(caption)){
$imgCaption=$('<div class="jg-caption">' + caption + '</div>');
$entry.append($imgCaption);
$entry.data('jg.createdCaption', true);
}}
if($imgCaption!==null){
if(!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity);
this.addCaptionEventsHandlers($entry);
}}else{
this.removeCaptionEventsHandlers($entry);
}};
JustifiedGallery.prototype.isValidCaption=function (caption){
return (typeof caption!=='undefined'&&caption.length > 0);
};
JustifiedGallery.prototype.onEntryMouseEnterForCaption=function (eventObject){
var $caption=this.captionFromEntry($(eventObject.currentTarget));
if(this.settings.cssAnimation){
$caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden');
}else{
$caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
this.settings.captionSettings.visibleOpacity);
}};
JustifiedGallery.prototype.onEntryMouseLeaveForCaption=function (eventObject){
var $caption=this.captionFromEntry($(eventObject.currentTarget));
if(this.settings.cssAnimation){
$caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden');
}else{
$caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
this.settings.captionSettings.nonVisibleOpacity);
}};
JustifiedGallery.prototype.addCaptionEventsHandlers=function ($entry){
var captionMouseEvents=$entry.data('jg.captionMouseEvents');
if(typeof captionMouseEvents==='undefined'){
captionMouseEvents={
mouseenter: this.onEntryMouseEnterForCaption.bind(this),
mouseleave: this.onEntryMouseLeaveForCaption.bind(this)
};
$entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter);
$entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave);
$entry.data('jg.captionMouseEvents', captionMouseEvents);
}};
JustifiedGallery.prototype.removeCaptionEventsHandlers=function ($entry){
var captionMouseEvents=$entry.data('jg.captionMouseEvents');
if(typeof captionMouseEvents!=='undefined'){
$entry.off('mouseenter', undefined, captionMouseEvents.mouseenter);
$entry.off('mouseleave', undefined, captionMouseEvents.mouseleave);
$entry.removeData('jg.captionMouseEvents');
}};
JustifiedGallery.prototype.clearBuildingRow=function (){
this.buildingRow.entriesBuff=[];
this.buildingRow.aspectRatio=0;
this.buildingRow.width=0;
};
JustifiedGallery.prototype.prepareBuildingRow=function (isLastRow, hiddenRow){
var i, $entry, imgAspectRatio, newImgW, newImgH, justify=true;
var minHeight=0;
var availableWidth=this.galleryWidth - 2 * this.border - (
(this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
var rowHeight=availableWidth / this.buildingRow.aspectRatio;
var defaultRowHeight=this.settings.rowHeight;
var justifiable=this.buildingRow.width / availableWidth > this.settings.justifyThreshold;
if(hiddenRow||(isLastRow&&this.settings.lastRow==='hide'&&!justifiable)){
for (i=0; i < this.buildingRow.entriesBuff.length; i++){
$entry=this.buildingRow.entriesBuff[i];
if(this.settings.cssAnimation)
$entry.removeClass('jg-entry-visible');
else {
$entry.stop().fadeTo(0, 0.1);
$entry.find('> img, > a > img').fadeTo(0, 0);
}}
return -1;
}
if(isLastRow&&!justifiable&&this.settings.lastRow!=='justify'&&this.settings.lastRow!=='hide'){
justify=false;
if(this.rows > 0){
defaultRowHeight=(this.offY - this.border - this.settings.margins * this.rows) / this.rows;
justify=defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold;
}}
for (i=0; i < this.buildingRow.entriesBuff.length; i++){
$entry=this.buildingRow.entriesBuff[i];
imgAspectRatio=$entry.data('jg.width') / $entry.data('jg.height');
if(justify){
newImgW=(i===this.buildingRow.entriesBuff.length - 1) ? availableWidth:rowHeight * imgAspectRatio;
newImgH=rowHeight;
}else{
newImgW=defaultRowHeight * imgAspectRatio;
newImgH=defaultRowHeight;
}
availableWidth -=Math.round(newImgW);
$entry.data('jg.jwidth', Math.round(newImgW));
$entry.data('jg.jheight', Math.ceil(newImgH));
if(i===0||minHeight > newImgH) minHeight=newImgH;
}
this.buildingRow.height=minHeight;
return justify;
};
JustifiedGallery.prototype.flushRow=function (isLastRow, hiddenRow){
var settings=this.settings;
var $entry, buildingRowRes, offX=this.border, i;
buildingRowRes=this.prepareBuildingRow(isLastRow, hiddenRow);
if(hiddenRow||(isLastRow&&settings.lastRow==='hide'&&buildingRowRes===-1)){
this.clearBuildingRow();
return;
}
if(this.maxRowHeight){
if(this.maxRowHeight < this.buildingRow.height) this.buildingRow.height=this.maxRowHeight;
}
if(isLastRow&&(settings.lastRow==='center'||settings.lastRow==='right')){
var availableWidth=this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins;
for (i=0; i < this.buildingRow.entriesBuff.length; i++){
$entry=this.buildingRow.entriesBuff[i];
availableWidth -=$entry.data('jg.jwidth');
}
if(settings.lastRow==='center')
offX +=Math.round(availableWidth / 2);
else if(settings.lastRow==='right')
offX +=availableWidth;
}
var lastEntryIdx=this.buildingRow.entriesBuff.length - 1;
for (i=0; i <=lastEntryIdx; i++){
$entry=this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i:i];
this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height);
offX +=$entry.data('jg.jwidth') + settings.margins;
}
this.galleryHeightToSet=this.offY + this.buildingRow.height + this.border;
this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight());
if(!isLastRow||(this.buildingRow.height <=settings.rowHeight&&buildingRowRes)){
this.offY +=this.buildingRow.height + settings.margins;
this.rows +=1;
this.clearBuildingRow();
this.settings.triggerEvent.call(this, 'jg.rowflush');
}};
var galleryPrevStaticHeight=0;
JustifiedGallery.prototype.rememberGalleryHeight=function (){
galleryPrevStaticHeight=this.$gallery.height();
this.$gallery.height(galleryPrevStaticHeight);
};
JustifiedGallery.prototype.setGalleryTempHeight=function (height){
galleryPrevStaticHeight=Math.max(height, galleryPrevStaticHeight);
this.$gallery.height(galleryPrevStaticHeight);
};
JustifiedGallery.prototype.setGalleryFinalHeight=function (height){
galleryPrevStaticHeight=height;
this.$gallery.height(height);
};
JustifiedGallery.prototype.checkWidth=function (){
function proxiedMethod(){
if(!this.$gallery.is(":visible")) return;
var galleryWidth=parseFloat(this.$gallery.width());
if(Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity){
this.galleryWidth=galleryWidth;
this.rewind();
this.rememberGalleryHeight();
this.startImgAnalyzer(true);
}}
this.checkWidthIntervalId=setInterval(proxiedMethod.bind(this), this.settings.refreshTime);
};
JustifiedGallery.prototype.isSpinnerActive=function (){
return this.spinner.intervalId!==null;
};
JustifiedGallery.prototype.getSpinnerHeight=function (){
return this.spinner.$el.innerHeight();
};
JustifiedGallery.prototype.stopLoadingSpinnerAnimation=function (){
clearInterval(this.spinner.intervalId);
this.spinner.intervalId=null;
this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight());
this.spinner.$el.detach();
};
JustifiedGallery.prototype.startLoadingSpinnerAnimation=function (){
var spinnerContext=this.spinner;
var $spinnerPoints=spinnerContext.$el.find('span');
clearInterval(spinnerContext.intervalId);
this.$gallery.append(spinnerContext.$el);
this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight());
spinnerContext.intervalId=setInterval(function (){
if(spinnerContext.phase < $spinnerPoints.length){
$spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1);
}else{
$spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0);
}
spinnerContext.phase=(spinnerContext.phase + 1) % ($spinnerPoints.length * 2);
}, spinnerContext.timeSlot);
};
JustifiedGallery.prototype.rewind=function (){
this.lastFetchedEntry=null;
this.lastAnalyzedIndex=-1;
this.offY=this.border;
this.rows=0;
this.clearBuildingRow();
};
JustifiedGallery.prototype.getSelectorWithoutSpinner=function (){
return this.settings.selector + ', div:not(.jg-spinner)';
};
JustifiedGallery.prototype.getAllEntries=function (){
var selector=this.getSelectorWithoutSpinner();
return this.$gallery.children(selector).toArray();
};
JustifiedGallery.prototype.updateEntries=function (norewind){
var newEntries;
if(norewind&&this.lastFetchedEntry!=null){
var selector=this.getSelectorWithoutSpinner();
newEntries=$(this.lastFetchedEntry).nextAll(selector).toArray();
}else{
this.entries=[];
newEntries=this.getAllEntries();
}
if(newEntries.length > 0){
if(typeof(this.settings.sort)==="function"){
newEntries=this.sortArray(newEntries);
}else if(this.settings.randomize){
newEntries=this.shuffleArray(newEntries);
}
this.lastFetchedEntry=newEntries[newEntries.length - 1];
if(this.settings.filter){
newEntries=this.filterArray(newEntries);
}else{
this.resetFilters(newEntries);
}}
this.entries=this.entries.concat(newEntries);
return true;
};
JustifiedGallery.prototype.insertToGallery=function (entries){
var that=this;
$.each(entries, function (){
$(this).appendTo(that.$gallery);
});
};
JustifiedGallery.prototype.shuffleArray=function (a){
var i, j, temp;
for (i=a.length - 1; i > 0; i--){
j=Math.floor(Math.random() * (i + 1));
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
this.insertToGallery(a);
return a;
};
JustifiedGallery.prototype.sortArray=function (a){
a.sort(this.settings.sort);
this.insertToGallery(a);
return a;
};
JustifiedGallery.prototype.resetFilters=function (a){
for (var i=0; i < a.length; i++) $(a[i]).removeClass('jg-filtered');
};
JustifiedGallery.prototype.filterArray=function (a){
var settings=this.settings;
if(typeof(settings.filter)==='string'){
return a.filter(function (el){
var $el=$(el);
if($el.is(settings.filter)){
$el.removeClass('jg-filtered');
return true;
}else{
$el.addClass('jg-filtered').removeClass('jg-visible');
return false;
}});
}else if(typeof(settings.filter)==="function"){
var filteredArr=a.filter(settings.filter);
for (var i=0; i < a.length; i++){
if(filteredArr.indexOf(a[i])===-1){
$(a[i]).addClass('jg-filtered').removeClass('jg-visible');
}else{
$(a[i]).removeClass('jg-filtered');
}}
return filteredArr;
}};
JustifiedGallery.prototype.resetImgSrc=function ($img){
if($img.data('jg.originalSrcLoc')==='src'){
$img.attr('src', $img.data('jg.originalSrc'));
}else{
$img.attr('src', '');
}};
JustifiedGallery.prototype.destroy=function (){
clearInterval(this.checkWidthIntervalId);
this.stopImgAnalyzerStarter();
function proxiedMethod(_, entry){
var $entry=$(entry);
$entry.css('width', '');
$entry.css('height', '');
$entry.css('top', '');
$entry.css('left', '');
$entry.data('jg.loaded', undefined);
$entry.removeClass('jg-entry jg-filtered jg-entry-visible');
var $img=this.imgFromEntry($entry);
if($img){
$img.css('width', '');
$img.css('height', '');
$img.css('margin-left', '');
$img.css('margin-top', '');
this.resetImgSrc($img);
$img.data('jg.originalSrc', undefined);
$img.data('jg.originalSrcLoc', undefined);
$img.data('jg.src', undefined);
}
this.removeCaptionEventsHandlers($entry);
var $caption=this.captionFromEntry($entry);
if($entry.data('jg.createdCaption')){
$entry.data('jg.createdCaption', undefined);
if($caption!==null) $caption.remove();
}else{
if($caption!==null) $caption.fadeTo(0, 1);
}}
$.each(this.getAllEntries(), proxiedMethod.bind(this));
this.$gallery.css('height', '');
this.$gallery.removeClass('justified-gallery');
this.$gallery.data('jg.controller', undefined);
this.settings.triggerEvent.call(this, 'jg.destroy');
};
JustifiedGallery.prototype.analyzeImages=function (isForResize){
for (var i=this.lastAnalyzedIndex + 1; i < this.entries.length; i++){
var $entry=$(this.entries[i]);
if($entry.data('jg.loaded')===true||$entry.data('jg.loaded')==='skipped'){
var availableWidth=this.galleryWidth - 2 * this.border - (
(this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
var imgAspectRatio=$entry.data('jg.width') / $entry.data('jg.height');
this.buildingRow.entriesBuff.push($entry);
this.buildingRow.aspectRatio +=imgAspectRatio;
this.buildingRow.width +=imgAspectRatio * this.settings.rowHeight;
this.lastAnalyzedIndex=i;
if(availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight){
this.flushRow(false, this.settings.maxRowsCount > 0&&this.rows===this.settings.maxRowsCount);
if(++this.yield.flushed >=this.yield.every){
this.startImgAnalyzer(isForResize);
return;
}}
}else if($entry.data('jg.loaded')!=='error'){
return;
}}
if(this.buildingRow.entriesBuff.length > 0){
this.flushRow(true, this.settings.maxRowsCount > 0&&this.rows===this.settings.maxRowsCount);
}
if(this.isSpinnerActive()){
this.stopLoadingSpinnerAnimation();
}
this.stopImgAnalyzerStarter();
this.setGalleryFinalHeight(this.galleryHeightToSet);
this.settings.triggerEvent.call(this, isForResize ? 'jg.resize':'jg.complete');
};
JustifiedGallery.prototype.stopImgAnalyzerStarter=function (){
this.yield.flushed=0;
if(this.imgAnalyzerTimeout!==null){
clearTimeout(this.imgAnalyzerTimeout);
this.imgAnalyzerTimeout=null;
}};
JustifiedGallery.prototype.startImgAnalyzer=function (isForResize){
var that=this;
this.stopImgAnalyzerStarter();
this.imgAnalyzerTimeout=setTimeout(function (){
that.analyzeImages(isForResize);
}, 0.001);
};
JustifiedGallery.prototype.onImageEvent=function (imageSrc, onLoad, onError){
if(!onLoad&&!onError) return;
var memImage=new Image();
var $memImage=$(memImage);
if(onLoad){
$memImage.one('load', function (){
$memImage.off('load error');
onLoad(memImage);
});
}
if(onError){
$memImage.one('error', function (){
$memImage.off('load error');
onError(memImage);
});
}
memImage.src=imageSrc;
};
JustifiedGallery.prototype.init=function (){
var imagesToLoad=false, skippedImages=false, that=this;
$.each(this.entries, function (index, entry){
var $entry=$(entry);
var $image=that.imgFromEntry($entry);
$entry.addClass('jg-entry');
if($entry.data('jg.loaded')!==true&&$entry.data('jg.loaded')!=='skipped'){
if(that.settings.rel!==null) $entry.attr('rel', that.settings.rel);
if(that.settings.target!==null) $entry.attr('target', that.settings.target);
if($image!==null){
var imageSrc=that.extractImgSrcFromImage($image);
if(that.settings.waitThumbnailsLoad===false||!imageSrc){
var width=parseFloat($image.attr('width'));
var height=parseFloat($image.attr('height'));
if($image.prop('tagName')==='svg'){
width=parseFloat($image[0].getBBox().width);
height=parseFloat($image[0].getBBox().height);
}
if(!isNaN(width)&&!isNaN(height)){
$entry.data('jg.width', width);
$entry.data('jg.height', height);
$entry.data('jg.loaded', 'skipped');
skippedImages=true;
that.startImgAnalyzer(false);
return true;
}}
$entry.data('jg.loaded', false);
imagesToLoad=true;
if(!that.isSpinnerActive()) that.startLoadingSpinnerAnimation();
that.onImageEvent(imageSrc, function (loadImg){
$entry.data('jg.width', loadImg.width);
$entry.data('jg.height', loadImg.height);
$entry.data('jg.loaded', true);
that.startImgAnalyzer(false);
}, function (){
$entry.data('jg.loaded', 'error');
that.startImgAnalyzer(false);
});
}else{
$entry.data('jg.loaded', true);
$entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1);
$entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1);
}}
});
if(!imagesToLoad&&!skippedImages) this.startImgAnalyzer(false);
this.checkWidth();
};
JustifiedGallery.prototype.checkOrConvertNumber=function (settingContainer, settingName){
if(typeof(settingContainer[settingName])==='string'){
settingContainer[settingName]=parseFloat(settingContainer[settingName]);
}
if(typeof(settingContainer[settingName])==='number'){
if(isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName;
}else{
throw settingName + ' must be a number';
}};
JustifiedGallery.prototype.checkSizeRangesSuffixes=function (){
if(typeof(this.settings.sizeRangeSuffixes)!=='object'){
throw 'sizeRangeSuffixes must be defined and must be an object';
}
var suffixRanges=[];
for (var rangeIdx in this.settings.sizeRangeSuffixes){
if(this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx);
}
var newSizeRngSuffixes={ 0: '' };
for (var i=0; i < suffixRanges.length; i++){
if(typeof(suffixRanges[i])==='string'){
try {
var numIdx=parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10);
newSizeRngSuffixes[numIdx]=this.settings.sizeRangeSuffixes[suffixRanges[i]];
} catch (e){
throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')';
}}else{
newSizeRngSuffixes[suffixRanges[i]]=this.settings.sizeRangeSuffixes[suffixRanges[i]];
}}
this.settings.sizeRangeSuffixes=newSizeRngSuffixes;
};
JustifiedGallery.prototype.retrieveMaxRowHeight=function (){
var newMaxRowHeight=null;
var rowHeight=this.settings.rowHeight;
if(typeof(this.settings.maxRowHeight)==='string'){
if(this.settings.maxRowHeight.match(/^[0-9]+%$/)){
newMaxRowHeight=rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100;
}else{
newMaxRowHeight=parseFloat(this.settings.maxRowHeight);
}}else if(typeof(this.settings.maxRowHeight)==='number'){
newMaxRowHeight=this.settings.maxRowHeight;
}else if(this.settings.maxRowHeight===false||this.settings.maxRowHeight==null){
return null;
}else{
throw 'maxRowHeight must be a number or a percentage';
}
if(isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight';
if(newMaxRowHeight < rowHeight) newMaxRowHeight=rowHeight;
return newMaxRowHeight;
};
JustifiedGallery.prototype.checkSettings=function (){
this.checkSizeRangesSuffixes();
this.checkOrConvertNumber(this.settings, 'rowHeight');
this.checkOrConvertNumber(this.settings, 'margins');
this.checkOrConvertNumber(this.settings, 'border');
this.checkOrConvertNumber(this.settings, 'maxRowsCount');
var lastRowModes=[
'justify',
'nojustify',
'left',
'center',
'right',
'hide'
];
if(lastRowModes.indexOf(this.settings.lastRow)===-1){
throw 'lastRow must be one of: ' + lastRowModes.join(', ');
}
this.checkOrConvertNumber(this.settings, 'justifyThreshold');
if(this.settings.justifyThreshold < 0||this.settings.justifyThreshold > 1){
throw 'justifyThreshold must be in the interval [0,1]';
}
if(typeof(this.settings.cssAnimation)!=='boolean'){
throw 'cssAnimation must be a boolean';
}
if(typeof(this.settings.captions)!=='boolean') throw 'captions must be a boolean';
this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration');
this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity');
if(this.settings.captionSettings.visibleOpacity < 0 ||
this.settings.captionSettings.visibleOpacity > 1){
throw 'captionSettings.visibleOpacity must be in the interval [0, 1]';
}
this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity');
if(this.settings.captionSettings.nonVisibleOpacity < 0 ||
this.settings.captionSettings.nonVisibleOpacity > 1){
throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]';
}
this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration');
this.checkOrConvertNumber(this.settings, 'refreshTime');
this.checkOrConvertNumber(this.settings, 'refreshSensitivity');
if(typeof(this.settings.randomize)!=='boolean') throw 'randomize must be a boolean';
if(typeof(this.settings.selector)!=='string') throw 'selector must be a string';
if(this.settings.sort!==false&&typeof(this.settings.sort)!=="function"){
throw 'sort must be false or a comparison function';
}
if(this.settings.filter!==false&&typeof(this.settings.filter)!=="function" &&
typeof(this.settings.filter)!=='string'){
throw 'filter must be false, a string or a filter function';
}};
JustifiedGallery.prototype.retrieveSuffixRanges=function (){
var suffixRanges=[];
for (var rangeIdx in this.settings.sizeRangeSuffixes){
if(this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10));
}
suffixRanges.sort(function (a, b){ return a > b ? 1:a < b ? -1:0; });
return suffixRanges;
};
JustifiedGallery.prototype.updateSettings=function (newSettings){
this.settings=$.extend({}, this.settings, newSettings);
this.checkSettings();
this.border=this.settings.border >=0 ? this.settings.border:this.settings.margins;
this.maxRowHeight=this.retrieveMaxRowHeight();
this.suffixRanges=this.retrieveSuffixRanges();
};
JustifiedGallery.prototype.defaults={
sizeRangeSuffixes: {}, 
thumbnailPath: undefined, 
rowHeight: 120,
maxRowHeight: false,
maxRowsCount: 0,
margins: 1,
border: -1,
lastRow: 'nojustify',
justifyThreshold: 0.90, 
waitThumbnailsLoad: true,
captions: true,
cssAnimation: true,
imagesAnimationDuration: 500,
captionSettings: {
animationDuration: 500,
visibleOpacity: 0.7,
nonVisibleOpacity: 0.0
},
rel: null,
target: null,
extension: /\.[^.\\/]+$/,
refreshTime: 200,
refreshSensitivity: 0,
randomize: false,
rtl: false,
sort: false, 
filter: false, 
selector: 'a',
imgSelector: '> img, > a > img, > svg, > a > svg',
triggerEvent: function (event){
this.$gallery.trigger(event);
}};
$.fn.justifiedGallery=function (arg){
return this.each(function (index, gallery){
var $gallery=$(gallery);
$gallery.addClass('justified-gallery');
var controller=$gallery.data('jg.controller');
if(typeof controller==='undefined'){
if(typeof arg!=='undefined'&&arg!==null&&typeof(arg)!=='object'){
if(arg==='destroy') return;
throw 'The argument must be an object';
}
controller=new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg));
$gallery.data('jg.controller', controller);
}else if(arg==='norewind'){
}else if(arg==='destroy'){
controller.destroy();
return;
}else{
controller.updateSettings(arg);
controller.rewind();
}
if(!controller.updateEntries(arg==='norewind')) return;
controller.init();
});
};}));