<commit_before>//сделаем превиев картинок что загружаються в новостях

function check_img(value) {
    if ((value.indexOf('.png') + 1) || (value.indexOf('.jpg') + 1) || (value.indexOf('.jpeg') + 1) || (value.indexOf('.bmp') + 1) || (value.indexOf('.gif') + 1)) {
        return true;
    } else {
        return false;
    }
}

function preview_reposition(images) {
    var val='';
    $('li a img',images).each(function(){
        if(val!='') val=val+', ';
        val=val+$(this).attr('src');
    });
    images.next().find('input').val(val);
}

var f=0;
function show_preview(images) {
    //images.parent().parent().find('.preview').remove();
    if(f==0) {
        f=1;
        images.parent().before('

');
    }
    images_array = images.val().split(', ');
    images_array.forEach(function (item, i, arr) {
        if (item.length > 0 && check_img(item)) {
            images.parent().prev().append(
                "
" +
                    "" +
                    "" +
                        "" +
                    "" +
                "
"
            );
        }
    });
}

(function ($) {
    var input = 'input.form-control[type="text"]';
    if ($(input).is(input)) {
        $(input).each(function () {
            var value = $(this).val();
            if (check_img(value)) {
                show_preview($(this));
            }
        });

        $(input).change(function () {
            show_preview($(this));
        });

        $(document).on('click', '.preview .delete', function () {
            var current = $(this).parent().index();
            var images = $(this).parent().parent().parent().find(input);
            var images_val = images.val();
            images_val = images_val.split(',');
            images_val.splice(current, 1);
            images.val(images_val);
            images.parent().parent().find('.preview').html('');
            show_preview(images);
        });

        $('a.preview_fancybox[rel=fancybox]').fancybox({
            'maxWidth': '90%',
            'maxHeight': '90%',
            'playSpeed': 7000,
            'padding': 0,
            'fitToView': false,
            'width': '100%',
            'height': '100%',
            'autoSize': true,
            'closeClick': false,
            'openEffect': 'elastic',
            'closeEffect': 'elastic',
            'prevEffect': 'elastic',
            'nextEffect': 'elastic',
            'closeBtn': false,
            'openOpacity': true,
            'helpers': {
                'title': {'type': 'float'},
                'buttons': {},
                'thumbs': {'width': 100, 'height': 100},
                'overlay': {
                    'css': {
                        'background': 'rgba(0, 0, 0, 0.8)'
                    }
                }
            },
        });
    }

    $(".preview").sortable({
        update: function( event, ui ) {
            preview_reposition($(this));
        }
    });
})(jQuery);
<commit_msg>удаление превьюшки<commit_after>//сделаем превиев картинок что загружаються в новостях

function check_img(value) {
    if ((value.indexOf('.png') + 1) || (value.indexOf('.jpg') + 1) || (value.indexOf('.jpeg') + 1) || (value.indexOf('.bmp') + 1) || (value.indexOf('.gif') + 1)) {
        return true;
    } else {
        return false;
    }
}

function preview_reposition(images) {
    var val='';
    $('li a img',images).each(function(){
        if(val!='') val=val+', ';
        val=val+$(this).attr('src');
    });
    images.next().find('input').val(val);
}

var f=0;
function show_preview(images) {
    //images.parent().parent().find('.preview').remove();
    if(f==0) {
        f=1;
        images.parent().before('

');
    }
    images_array = images.val().split(', ');
    images_array.forEach(function (item, i, arr) {
        if (item.length > 0 && check_img(item)) {
            images.parent().prev().append(
                "
" +
                    "" +
                    "" +
                        "" +
                    "" +
                "
"
            );
        }
    });
}

(function ($) {
    var input = 'input.form-control[type="text"]';
    if ($(input).is(input)) {
        $(input).each(function () {
            var value = $(this).val();
            if (check_img(value)) {
                show_preview($(this));
            }
        });

        $(input).change(function () {
            $(this).parent().parent().find('.preview').html('');
            show_preview($(this));
        });

        $(document).on('click', '.preview .delete', function () {
            var current = $(this).parent().index();
            var images = $(this).parent().parent().parent().find(input);
            var images_val = images.val();
            images_val = images_val.split(',');
            images_val.splice(current, 1);
            images.val(images_val);
            images.parent().parent().find('.preview').html('');
            show_preview(images);
        });

        $('a.preview_fancybox[rel=fancybox]').fancybox({
            'maxWidth': '90%',
            'maxHeight': '90%',
            'playSpeed': 7000,
            'padding': 0,
            'fitToView': false,
            'width': '100%',
            'height': '100%',
            'autoSize': true,
            'closeClick': false,
            'openEffect': 'elastic',
            'closeEffect': 'elastic',
            'prevEffect': 'elastic',
            'nextEffect': 'elastic',
            'closeBtn': false,
            'openOpacity': true,
            'helpers': {
                'title': {'type': 'float'},
                'buttons': {},
                'thumbs': {'width': 100, 'height': 100},
                'overlay': {
                    'css': {
                        'background': 'rgba(0, 0, 0, 0.8)'
                    }
                }
            },
        });
    }

    $(".preview").sortable({
        update: function( event, ui ) {
            preview_reposition($(this));
        }
    });
})(jQuery);
<|endoftext|>


<commit_before>/* Annotorious plugin to use the annotation editor from the
 * ClioPatria image_annotation cpack package as the editor for
 * shapes created in Annotorious.
 *
 * To this, we need to solve three issues:
 *
 * 1. We need to communicate the shape that the user created within
 *    annotorious to all annotation field objects of the cpack.
 *    This is why the plugin has a public member variable 'currentShape'
 *    that the cpack fields can access.
 *
 * 2. The cpack data model assumes multiple annotation can be made on
 *    the same target, while annotorious can have only one.
 *    As a result, we need to collect all tags for the same target and
 *    merge them into a single annotation for annotorious.
 *    This is done in the 'cleantags' array, which is indexed on targetId.
 *
 * 3. While the annotorious editor is open, the user can add and remove
 *    individual tags using the cpack user interface. But we can only
 *    add/rm the final merged tag using the annotorious API when the
 *    editor is closed. As a result, we need to do some bookkeeping
 *    ourselves in the _dirtytag variable, and update annotorious when
 *    the editor is closed by flushing out all changes made to the current
 *    dirty tag.
 *
 * Apart from these issues above, the approach is quite straight forward:
 *
 * 1. We simple move the cpack editor as a plugin field into the annotorious
 *    editor.
 * 2. We hijack the cancel/save buttons of annotorious for our own purposes.
 * 3. We bind handler functions on all relevant events generated by annotorious.
 *
 * @author: Jacco van Ossenbruggen
 *
 * */

annotorious.plugin.DenichePlugin = function(opt_config_options) {
	/** @public **/
	this.currentShape = null; // Should be accessible by cpack objects

	/** @private **/
	this._cleantags = [];	// tags annotorious already knows about
	this._dirtytag = null;	// tag annotorious doesn't know yet
	this._saveButtons = {};	 // we have multiple buttons if we have multiple images per page
	this._cancelButtons = {};
}

annotorious.plugin.DenichePlugin.states = { EMPTY:'empty', SOME:'some' };

annotorious.plugin.DenichePlugin.prototype.onInitAnnotator = function(annotator) {
    // move the cpack editor into the annotorious editor:
    var el =  annotator.element;
    var fieldsId = el.getElementsByTagName('img')[0].getAttribute('fields');
    var fieldsEl = document.getElementById(fieldsId);
    annotator.editor.addField(fieldsEl);

    // get the annotorious save and cancel button so we can manipulate them:
    var oSelf = this;
    YUI().use('node', 'event', function(Y) {
    	var node = Y.one(el);
    	oSelf._saveButtons[fieldsId]   = node.one('.annotorious-editor-button-save').getDOMNode();
    	oSelf._cancelButtons[fieldsId] = node.one('.annotorious-editor-button-cancel').getDOMNode();
    	oSelf._saveButtons[fieldsId].innerHTML = "Done";
    });

    // install all handlers on events created by annotorious:
    this.installHandlers();

    if (this._anno.fields) {
	fields = this._anno.fields[fieldsId];
	for(i in fields) {
	    f = fields[i];
	    if (f.get('lazy')) f.getTags();
	}
    }
}

annotorious.plugin.DenichePlugin.prototype.initPlugin = function(anno) {
	this._anno = anno;	// make sure we know annotorious ...
	this._anno._deniche = this; // and annotorious knows us
}

annotorious.plugin.DenichePlugin.prototype.toggleButtons = function(state, fieldsId) {
	// console.log('annotorious.plugin.DenichePlugin.prototype.toggleButtons');
	// console.log(state);
	// console.log(fieldsId);
	if (!this._cancelButtons[fieldsId]) return;
	if (!state) state = annotorious.plugin.DenichePlugin.states.SOME;
	if (state == annotorious.plugin.DenichePlugin.states.SOME) {
		this._cancelButtons[fieldsId].style.display="none";
		this._saveButtons[fieldsId].style.display="inline-block";
	} else if (state == annotorious.plugin.DenichePlugin.states.EMPTY) {
		this._saveButtons[fieldsId].style.display="none";
		this._cancelButtons[fieldsId].style.display="inline-block";
	}
}

annotorious.plugin.DenichePlugin.prototype.filterTags = function(targetId, fieldsId) {
	var oSelf = this;
	YUI().use('node', 'event', function(Y) {
		var selector = '#'+ fieldsId + ' li.tagitem';
		if (!fieldsId) selector = 'li.tagitem';
		Y.all(selector).each(function(tagNode) {
			if (targetId == tagNode.getAttribute('targetId')) {
				tagNode.show();
			} else {
				tagNode.hide();
			}
		});
	});
}

annotorious.plugin.DenichePlugin.prototype.removeAnnotation = function (label, targetId) {
	var old = this._dirtytag;
	if (!old) old = this._cleantags[targetId];
	if (old) {
		var annotation = JSON.parse(JSON.stringify(old)); // deep copy
		var index = old.compound_text.indexOf(label);
		annotation.compound_text = old.compound_text.splice(index, 1);
		annotation.text = old.compound_text.join(', ');
		this._dirtytag = annotation;
	}

}

annotorious.plugin.DenichePlugin.prototype.addAnnotation = function (annotation, update) {
	var old = this._dirtytag;
	if (!old) old = this._cleantags[annotation.targetId];
	if (old) {
		// extend new annotation by merging in old one
		annotation.compound_text = old.compound_text;
		annotation.compound_text.push(annotation.text);
		annotation.text = annotation.compound_text.join(', ');
	} else {
		annotation.compound_text = [ annotation.text ];
	}

	if (update) {
		this._cleantags[annotation.targetId] = annotation;
		this._anno.addAnnotation(annotation, old);
	} else {
		this._dirtytag = annotation;
	}
	// this.toggleButtons(annotorious.plugin.DenichePlugin.states.SOME, annotation.fieldsId);
}

annotorious.plugin.DenichePlugin.prototype.flushDirtyAnnotation = function(original) {
		var dirty = this._dirtytag;
		this._dirtytag = null;
		if (dirty) {
			if (dirty.text) {
				this._anno.addAnnotation(dirty,original);
				this._cleantags[dirty.targetId] = dirty;
			} else {
				this._anno.removeAnnotation(original);
				this._cleantags[dirty.targetId] = null;
			}
		}
}

annotorious.plugin.DenichePlugin.prototype.installHandlers = function() {
	var oSelf = this;
	this._anno.addHandler('onSelectionCompleted', function(ev) {
		oSelf.currentShape = ev.shape;
		var currentFieldsId = ev.mouseEvent.target.parentNode.getElementsByTagName('img')[0].getAttribute('fields');
		oSelf.toggleButtons(annotorious.plugin.DenichePlugin.states.EMPTY, currentFieldsId);
	});

	this._anno.addHandler('onEditorShown', function(annotation) {
		// console.log('onEditorShown');
		oSelf._dirtytag = null;
		if (annotation && annotation.shapes) {
			oSelf.currentShape = annotation.shapes[0];
			oSelf.toggleButtons(annotorious.plugin.DenichePlugin.states.SOME, annotation.fieldsId);
			oSelf.filterTags(annotation.targetId, annotation.fieldsId); // only show tags for this shape
		} else {
			oSelf.filterTags(null, null);	// hide all tags
		}
	});

	this._anno.addHandler('onAnnotationCreated', function(original) {
		oSelf.flushDirtyAnnotation(original);
	});

	this._anno.addHandler('onAnnotationUpdated', function(original) {
		oSelf.flushDirtyAnnotation(original);
	});
}

anno.addPlugin('DenichePlugin', {});
<commit_msg>toggle Cancel button back to Done after first tags have been added<commit_after>/* Annotorious plugin to use the annotation editor from the
 * ClioPatria image_annotation cpack package as the editor for
 * shapes created in Annotorious.
 *
 * To this, we need to solve three issues:
 *
 * 1. We need to communicate the shape that the user created within
 *    annotorious to all annotation field objects of the cpack.
 *    This is why the plugin has a public member variable 'currentShape'
 *    that the cpack fields can access.
 *
 * 2. The cpack data model assumes multiple annotation can be made on
 *    the same target, while annotorious can have only one.
 *    As a result, we need to collect all tags for the same target and
 *    merge them into a single annotation for annotorious.
 *    This is done in the 'cleantags' array, which is indexed on targetId.
 *
 * 3. While the annotorious editor is open, the user can add and remove
 *    individual tags using the cpack user interface. But we can only
 *    add/rm the final merged tag using the annotorious API when the
 *    editor is closed. As a result, we need to do some bookkeeping
 *    ourselves in the _dirtytag variable, and update annotorious when
 *    the editor is closed by flushing out all changes made to the current
 *    dirty tag.
 *
 * Apart from these issues above, the approach is quite straight forward:
 *
 * 1. We simple move the cpack editor as a plugin field into the annotorious
 *    editor.
 * 2. We hijack the cancel/save buttons of annotorious for our own purposes.
 * 3. We bind handler functions on all relevant events generated by annotorious.
 *
 * @author: Jacco van Ossenbruggen
 *
 * */

annotorious.plugin.DenichePlugin = function(opt_config_options) {
	/** @public **/
	this.currentShape = null; // Should be accessible by cpack objects

	/** @private **/
	this._cleantags = [];	// tags annotorious already knows about
	this._dirtytag = null;	// tag annotorious doesn't know yet
	this._saveButtons = {};	 // we have multiple buttons if we have multiple images per page
	this._cancelButtons = {};
}

annotorious.plugin.DenichePlugin.states = { EMPTY:'empty', SOME:'some' };

annotorious.plugin.DenichePlugin.prototype.onInitAnnotator = function(annotator) {
    // move the cpack editor into the annotorious editor:
    var el =  annotator.element;
    var fieldsId = el.getElementsByTagName('img')[0].getAttribute('fields');
    var fieldsEl = document.getElementById(fieldsId);
    annotator.editor.addField(fieldsEl);

    // get the annotorious save and cancel button so we can manipulate them:
    var oSelf = this;
    YUI().use('node', 'event', function(Y) {
    	var node = Y.one(el);
    	oSelf._saveButtons[fieldsId]   = node.one('.annotorious-editor-button-save').getDOMNode();
    	oSelf._cancelButtons[fieldsId] = node.one('.annotorious-editor-button-cancel').getDOMNode();
    	oSelf._saveButtons[fieldsId].innerHTML = "Done";
    });

    // install all handlers on events created by annotorious:
    this.installHandlers();

    if (this._anno.fields) {
	fields = this._anno.fields[fieldsId];
	for(i in fields) {
	    f = fields[i];
	    if (f.get('lazy')) f.getTags();
	}
    }
}

annotorious.plugin.DenichePlugin.prototype.initPlugin = function(anno) {
	this._anno = anno;	// make sure we know annotorious ...
	this._anno._deniche = this; // and annotorious knows us
}

annotorious.plugin.DenichePlugin.prototype.toggleButtons = function(state, fieldsId) {
	// console.log('annotorious.plugin.DenichePlugin.prototype.toggleButtons');
	// console.log(state);
	// console.log(fieldsId);
	if (!this._cancelButtons[fieldsId]) return;
	if (!state) state = annotorious.plugin.DenichePlugin.states.SOME;
	if (state == annotorious.plugin.DenichePlugin.states.SOME) {
		this._cancelButtons[fieldsId].style.display="none";
		this._saveButtons[fieldsId].style.display="inline-block";
	} else if (state == annotorious.plugin.DenichePlugin.states.EMPTY) {
		this._saveButtons[fieldsId].style.display="none";
		this._cancelButtons[fieldsId].style.display="inline-block";
	}
}

annotorious.plugin.DenichePlugin.prototype.filterTags = function(targetId, fieldsId) {
	var oSelf = this;
	YUI().use('node', 'event', function(Y) {
		var selector = '#'+ fieldsId + ' li.tagitem';
		if (!fieldsId) selector = 'li.tagitem';
		Y.all(selector).each(function(tagNode) {
			if (targetId == tagNode.getAttribute('targetId')) {
				tagNode.show();
			} else {
				tagNode.hide();
				// console.log('Hiding tag ' + targetId + ' <> ' + tagNode.getAttribute('targetId'));
			}
		});
	});
}

annotorious.plugin.DenichePlugin.prototype.removeAnnotation = function (label, targetId) {
	var old = this._dirtytag;
	if (!old) old = this._cleantags[targetId];
	if (old) {
		var annotation = JSON.parse(JSON.stringify(old)); // deep copy
		var index = old.compound_text.indexOf(label);
		annotation.compound_text = old.compound_text.splice(index, 1);
		annotation.text = old.compound_text.join(', ');
		this._dirtytag = annotation;
	}

}

annotorious.plugin.DenichePlugin.prototype.addAnnotation = function (annotation, update) {
	var old = this._dirtytag;
	if (!old) old = this._cleantags[annotation.targetId];
	if (old) {
		// extend new annotation by merging in old one
		annotation.compound_text = old.compound_text;
		annotation.compound_text.push(annotation.text);
		annotation.text = annotation.compound_text.join(', ');
	} else {
		annotation.compound_text = [ annotation.text ];
	}

	if (update) {
		this._cleantags[annotation.targetId] = annotation;
		this._anno.addAnnotation(annotation, old);
	} else {
		this._dirtytag = annotation;
	}
	this.toggleButtons(annotorious.plugin.DenichePlugin.states.SOME, annotation.fieldsId);
}

annotorious.plugin.DenichePlugin.prototype.flushDirtyAnnotation = function(original) {
	var dirty = this._dirtytag;
	this._dirtytag = null;
	if (dirty) {
		if (dirty.text) {
			this._anno.addAnnotation(dirty,original);
			this._cleantags[dirty.targetId] = dirty;
		} else {
			this._anno.removeAnnotation(original);
			this._cleantags[dirty.targetId] = null;
		}
	}
}

annotorious.plugin.DenichePlugin.prototype.installHandlers = function() {
	var oSelf = this;
	this._anno.addHandler('onSelectionCompleted', function(ev) {
		oSelf.currentShape = ev.shape;
		var currentFieldsId = ev.mouseEvent.target.parentNode.getElementsByTagName('img')[0].getAttribute('fields');
		oSelf.toggleButtons(annotorious.plugin.DenichePlugin.states.EMPTY, currentFieldsId);
	});

	this._anno.addHandler('onEditorShown', function(annotation) {
		// console.log('onEditorShown');
		oSelf._dirtytag = null;
		if (annotation && annotation.shapes) {
			oSelf.currentShape = annotation.shapes[0];
			oSelf.toggleButtons(annotorious.plugin.DenichePlugin.states.SOME, annotation.fieldsId);
			oSelf.filterTags(annotation.targetId, annotation.fieldsId); // only show tags for this shape
		} else {
			oSelf.filterTags(null, null);	// hide all tags
		}
	});

	this._anno.addHandler('onAnnotationCreated', function(original) {
		oSelf.flushDirtyAnnotation(original);
	});

	this._anno.addHandler('onAnnotationUpdated', function(original) {
		oSelf.flushDirtyAnnotation(original);
	});
}

anno.addPlugin('DenichePlugin', {});
<|endoftext|>


<commit_before>function info(text) {
	$("#div_info_element").show();
	var info_element = $("#info_element");
	var info_element_text = $("#info_element_text");
	info_element_text.html(text);
	info_element.show();
}

function warn(text) {
	if (text)
	{
		$("#div_warn_element").show();
		var warn_element = $("#warn_element");
		var warn_element_text = $("#warn_element_text");
		warn_element_text.html(text);
		warn_element.show();
	}
	else
	{
		$('#div_warn_element').hide();
		$('#warn_element').hide();
	}
}

// humanFileSize by Mark - http://stackoverflow.com/a/14919494
function humanFileSize(bytes, si) {
	var thresh = si ? 1000 : 1024;
	if(bytes < thresh) return bytes + ' B';
	var units = si ? ['kB','MB','GB','TB','PB','EB','ZB','YB'] : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
	var u = -1;
	do {
		bytes /= thresh;
		++u;
	} while(bytes >= thresh);
	return bytes.toFixed(1)+' '+units[u];
};

// millisecondsToStr by Dan - http://stackoverflow.com/a/8212878
function millisecondsToStr (milliseconds) {
	function numberEnding (number) {
		return (number > 1) ? 's' : '';
	}

	var temp = Math.floor(milliseconds / 1000);

	var days = Math.floor((temp %= 31536000) / 86400);
	if (days) {
		return days + ' day' + numberEnding(days);
	}
	var hours = Math.floor((temp %= 86400) / 3600);
	if (hours) {
		return hours + ' hour' + numberEnding(hours);
	}
	var minutes = Math.floor((temp %= 3600) / 60);
	if (minutes) {
		return minutes + ' minute' + numberEnding(minutes);
	}
	var seconds = temp % 60;
	if (seconds) {
		return seconds + ' second' + numberEnding(seconds);
	}

	return 'now';
}

// modified version for increased accuracy
function millisecondsToAccurateStr (milliseconds) {
	function numberEnding (number) {
		return (number > 1) ? 's' : '';
	}

	var temp = Math.floor(milliseconds / 1000);
	var res = new Array();

	var days = Math.floor((temp %= 31536000) / 86400);
	if (days) {
		res.push(days + ' day' + numberEnding(days));
	}
	var hours = Math.floor((temp %= 86400) / 3600);
	if (hours) {
		res.push(hours + ' hour' + numberEnding(hours));
	}
	var minutes = Math.floor((temp %= 3600) / 60);
	if (minutes) {
		res.push(minutes + ' minute' + numberEnding(minutes));
	}
	var seconds = temp % 60;
	if (seconds) {
		res.push(seconds + ' second' + numberEnding(seconds));
	}

	return res.length > 0 ? res.join(' ') : 'now';
}

// textarea auto height
function textAreaAutoResize (obj) {
  if (obj.scrollHeight > obj.clientHeight) {
    obj.style.height = obj.scrollHeight + "px";
  }
}
<commit_msg>Animate the warning message object.<commit_after>function info(text) {
	$("#div_info_element").show();
	var info_element = $("#info_element");
	var info_element_text = $("#info_element_text");
	info_element_text.html(text);
	info_element.show();
}

function warn(text) {
	if (text)
	{
		$("#div_warn_element").show();
		var warn_element = $("#warn_element");
		var warn_element_text = $("#warn_element_text");
		warn_element_text.html(text);
		warn_element.show();
	}
	else
	{
		$('#div_warn_element').slideUp(1000, "swing");
	}
}

// humanFileSize by Mark - http://stackoverflow.com/a/14919494
function humanFileSize(bytes, si) {
	var thresh = si ? 1000 : 1024;
	if(bytes < thresh) return bytes + ' B';
	var units = si ? ['kB','MB','GB','TB','PB','EB','ZB','YB'] : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'];
	var u = -1;
	do {
		bytes /= thresh;
		++u;
	} while(bytes >= thresh);
	return bytes.toFixed(1)+' '+units[u];
};

// millisecondsToStr by Dan - http://stackoverflow.com/a/8212878
function millisecondsToStr (milliseconds) {
	function numberEnding (number) {
		return (number > 1) ? 's' : '';
	}

	var temp = Math.floor(milliseconds / 1000);

	var days = Math.floor((temp %= 31536000) / 86400);
	if (days) {
		return days + ' day' + numberEnding(days);
	}
	var hours = Math.floor((temp %= 86400) / 3600);
	if (hours) {
		return hours + ' hour' + numberEnding(hours);
	}
	var minutes = Math.floor((temp %= 3600) / 60);
	if (minutes) {
		return minutes + ' minute' + numberEnding(minutes);
	}
	var seconds = temp % 60;
	if (seconds) {
		return seconds + ' second' + numberEnding(seconds);
	}

	return 'now';
}

// modified version for increased accuracy
function millisecondsToAccurateStr (milliseconds) {
	function numberEnding (number) {
		return (number > 1) ? 's' : '';
	}

	var temp = Math.floor(milliseconds / 1000);
	var res = new Array();

	var days = Math.floor((temp %= 31536000) / 86400);
	if (days) {
		res.push(days + ' day' + numberEnding(days));
	}
	var hours = Math.floor((temp %= 86400) / 3600);
	if (hours) {
		res.push(hours + ' hour' + numberEnding(hours));
	}
	var minutes = Math.floor((temp %= 3600) / 60);
	if (minutes) {
		res.push(minutes + ' minute' + numberEnding(minutes));
	}
	var seconds = temp % 60;
	if (seconds) {
		res.push(seconds + ' second' + numberEnding(seconds));
	}

	return res.length > 0 ? res.join(' ') : 'now';
}

// textarea auto height
function textAreaAutoResize (obj) {
  if (obj.scrollHeight > obj.clientHeight) {
    obj.style.height = obj.scrollHeight + "px";
  }
}
<|endoftext|>


<commit_before>var ImageSetModel = require('./model/ImageSetModel');
var jimp = require('jimp');
var fs = require('fs-extra');
var path = require('path');
var config = require('./ConfigurationLoader');
var logger = require('winston');

/**
 * Constructor.
 * **/
var ImageManipulator = function () {};

/* ----- Create Methods ----- */

/**
 * Creates a diff image of the reference and new image and saves it to the, in the config file configured, folder path.
 * Does not update the imageMetaInformationModel information itself.
 *
 * @param imageName The name of the images that should be compared. The image must have the same name in the reference and new folder. The diff image will have the name, too.
 * @param autoCrop Determines if the new/reference images should be autocroped before comparison to yield better results if the sometimes differ in size. Must be a boolean.
 * @param callback The callback function which is called, when the method has finished the comparison. The callback has an imageSet as job.
 * **/
ImageManipulator.prototype.createDiffImage = function (imageName, autoCrop, callback) {

    // Other vars
    var that = this;

    // Assign default value value is falsy
    autoCrop = autoCrop || false;

    // Get images
    var referenceImagePath = config.getReferenceImageFolderPath() + path.sep + imageName;
    var newImagePath = config.getNewImageFolderPath() + path.sep + imageName;
    var diffImagePath = config.getResultImageFolderPath() + path.sep + imageName;
    logger.info('Creating diff image for:', imageName);

    // If one of the images do not exist, then quit
    if(!this.__isImageExisting(referenceImagePath) || !this.__isImageExisting(newImagePath)){
        var errorText = 'Reference or new image does not exist:\n'
            + 'Reference: ' + referenceImagePath
            + "\n"
            +  'New: ' + newImagePath;

        logger.error(errorText);
        throw Error(errorText);
    }

    // Compute differences
    this.loadImage(referenceImagePath, function (err, referenceImage) {
        that.loadImage(newImagePath, function (err, newImage) {

            // If the image size is not identical and autocrop is off
            if((referenceImage.bitmap.height !== newImage.bitmap.height
                || referenceImage.bitmap.width !== newImage.bitmap.width) && !autoCrop){
                var errorText = 'Image dimensions are not equal: '
                    + 'reference: ' + referenceImage.bitmap.height + '/' + referenceImage.bitmap.width
                    + 'reference: ' + referenceImage.bitmap.height + '/' + referenceImage.bitmap.width;
                logger.error(errorText);
                throw Error(errorText);
            }

            // Autocrop if argument is given to normalalize images
            that.__autoCrop(referenceImage, newImage, autoCrop);

            // Create diff, ensure that folder structure exists and write file
            var diff = jimp.diff(referenceImage, newImage);
            fs.ensureDirSync(config.getResultImageFolderPath());
            diff.image.write(diffImagePath, function () {
                // Create data structure for the gathering of imageMetaInformationModel information (distance and difference are between 0 and 0 -> * 100 for percent)
                callback(that.createCompleteImageSet(imageName, referenceImage, newImage, diff.image, diff.percent * 100, jimp.distance(referenceImage, newImage) * 100, ''));
            });
        });
    });
};

/**
 * Deletes images of an image set.
 *
 * @param imageSet The image set from which the images should be deleted.
 * @param callback Called when the complete deletion process is done. Has the updated image imageMetaInformationModel information model object as job.
 * **/
ImageManipulator.prototype.deleteImageSetImages = function (imageSet, callback) {

    // Delete image which are part of the set
    this.__deleteFile(imageSet.getReferenceImage().getPath());
    this.__deleteFile(imageSet.getNewImage().getPath());
    this.__deleteFile(imageSet.getDiffImage().getPath());

    // Call callback when stuff is done
    if(callback){
        callback();
    }
};

/**
 * Loads an image via jimp.
 *
 * @param imagePath The complete path to the image file.
 * @param callback Called when the image was loaded. Returns the image as jimp object and an error object.
 * **/
ImageManipulator.prototype.loadImage = function (imagePath, callback) {
    jimp.read(imagePath, function (err, newImage) {
        callback(err, newImage);
    });
};

/* ----- Creation Helper Methods ----- */

/**
 * Creates an image set for one image only (there exists only a reference or new image).
 *
 * @param imageName The name of the image.
 * @param image The jimp loaded image.
 * @param error The error. E.g. something like: 'There exists no base image for this new image yet'.
 * @param isReferenceImage Determines whether the given information is for a reference or new image. Boolean expected.
 *
 * @return The constructed image set containing the information.
 * **/
ImageManipulator.prototype.createSingleImageSet = function (imageName, image, error, isReferenceImage) {
    var imageSet = new ImageSetModel();

    // Set error values
    imageSet.setError(error);
    imageSet.setDifference(100);
    imageSet.setDistance(100);

    // Edit set dependant of the image type
    if(isReferenceImage) {
        imageSet.getReferenceImage().setHeight(image.bitmap.height);
        imageSet.getReferenceImage().setWidth(image.bitmap.width);
        imageSet.getReferenceImage().setName(imageName);
        imageSet.getReferenceImage().setPath(config.getReferenceImageFolderPath() + path.sep + imageName);
    } else {
        imageSet.getNewImage().setHeight(image.bitmap.height);
        imageSet.getNewImage().setWidth(image.bitmap.width);
        imageSet.getNewImage().setName(imageName);
        imageSet.getNewImage().setPath(config.getNewImageFolderPath() + path.sep + imageName);
    }

    return imageSet;
};

/**
 * Creates an image set containing the reference, new and diff images.
 *
 * @param imageName The name of the image. The name is the same for the reference, new and diff images.
 * @param referenceImage The reference jimp loaded image.
 * @param newImage The new jimp loaded image.
 * @param diffImage The diff jimp loaded image.
 * @param difference The percentual pixel difference between the reference and new image.
 * @param distance The hammond distance between the reference and new image.
 * @param error The error. E.g. something like: 'There exists no base image for this new image yet'.
 *
 * @return The constructed image set containing the information.
 * **/
ImageManipulator.prototype.createCompleteImageSet = function(imageName, referenceImage, newImage, diffImage, difference, distance, error){
    var imageSet = new ImageSetModel();

    imageSet.setDifference(difference);
    imageSet.setDistance(distance);
    imageSet.setError(error);

    imageSet.getReferenceImage().setName(imageName);
    imageSet.getReferenceImage().setHeight(referenceImage.bitmap.height);
    imageSet.getReferenceImage().setWidth(referenceImage.bitmap.width);
    imageSet.getReferenceImage().setPath(config.getReferenceImageFolderPath() + path.sep + imageName);

    imageSet.getNewImage().setName(imageName);
    imageSet.getNewImage().setHeight(referenceImage.bitmap.height);
    imageSet.getNewImage().setWidth(referenceImage.bitmap.width);
    imageSet.getNewImage().setPath(config.getNewImageFolderPath() + path.sep + imageName);

    imageSet.getDiffImage().setName(imageName);
    imageSet.getDiffImage().setHeight(referenceImage.bitmap.height);
    imageSet.getDiffImage().setWidth(referenceImage.bitmap.width);
    imageSet.getDiffImage().setPath(config.getResultImageFolderPath() + path.sep + imageName);

    return imageSet;
};

/* ----- Other helper methods ----- */

/**
 * Autocrops two images.
 *
 * @param image1 The first image to autocrop.
 * @param image2 The second image to autocrop.
 * @param autoCrop Boolean. If true, the images will be autocroped, else not.
 * **/
ImageManipulator.prototype.__autoCrop = function (image1, image2, autoCrop) {
    if(autoCrop){
        image1.autocrop();
        image2.autocrop();
    }
};

/**
 * Checks whether an image exists.
 *
 * @param imagePath The path to the image, which should be checked.
 * @return True if the image does exist, else false.
 * **/
ImageManipulator.prototype.__isImageExisting = function (imagePath) {
    return fs.existsSync(imagePath) && fs.statSync(imagePath).isFile();
};

/**
 * Deletes a file.
 *
 * @param path The file which should be deleted.
 * **/
ImageManipulator.prototype.__deleteFile = function (path) {
    if(this.__isImageExisting(path)){
        fs.unlink(path, function (err) {
            if(err){
                logger.error('Failed to delete file: ' + path, err);
                throw Error('Failed to delete file: ' + path, err);
            }
        });
    }
};

module.exports = ImageManipulator;<commit_msg>Removes a throw exception which didn't make any sense and fixed the output of the image dimensions.<commit_after>var ImageSetModel = require('./model/ImageSetModel');
var jimp = require('jimp');
var fs = require('fs-extra');
var path = require('path');
var config = require('./ConfigurationLoader');
var logger = require('winston');

/**
 * Constructor.
 * **/
var ImageManipulator = function () {};

/* ----- Create Methods ----- */

/**
 * Creates a diff image of the reference and new image and saves it to the, in the config file configured, folder path.
 * Does not update the imageMetaInformationModel information itself.
 *
 * @param imageName The name of the images that should be compared. The image must have the same name in the reference and new folder. The diff image will have the name, too.
 * @param autoCrop Determines if the new/reference images should be autocroped before comparison to yield better results if the sometimes differ in size. Must be a boolean.
 * @param callback The callback function which is called, when the method has finished the comparison. The callback has an imageSet as job.
 * **/
ImageManipulator.prototype.createDiffImage = function (imageName, autoCrop, callback) {

    // Other vars
    var that = this;

    // Assign default value value is falsy
    autoCrop = autoCrop || false;

    // Get images
    var referenceImagePath = config.getReferenceImageFolderPath() + path.sep + imageName;
    var newImagePath = config.getNewImageFolderPath() + path.sep + imageName;
    var diffImagePath = config.getResultImageFolderPath() + path.sep + imageName;
    logger.info('Creating diff image for:', imageName);

    // If one of the images do not exist, then quit
    if(!this.__isImageExisting(referenceImagePath) || !this.__isImageExisting(newImagePath)){
        var errorText = 'Reference or new image does not exist:\n'
            + 'Reference: ' + referenceImagePath
            + "\n"
            +  'New: ' + newImagePath;

        logger.error(errorText);
        throw Error(errorText);
    }

    // Compute differences
    this.loadImage(referenceImagePath, function (err, referenceImage) {
        that.loadImage(newImagePath, function (err, newImage) {

            // If the image size is not identical
            if((referenceImage.bitmap.height !== newImage.bitmap.height
                || referenceImage.bitmap.width !== newImage.bitmap.width) && !autoCrop){
                var errorText = 'Image dimensions are not equal: '
                    + 'new: ' + newImage.bitmap.height + '/' + newImage.bitmap.width
                    + '\nreference: ' + referenceImage.bitmap.height + '/' + referenceImage.bitmap.width;
                logger.error(errorText);
            }

            // Autocrop if argument is given to normalalize images
            that.__autoCrop(referenceImage, newImage, autoCrop);

            // Create diff, ensure that folder structure exists and write file
            var diff = jimp.diff(referenceImage, newImage);
            fs.ensureDirSync(config.getResultImageFolderPath());
            diff.image.write(diffImagePath, function () {
                // Create data structure for the gathering of imageMetaInformationModel information (distance and difference are between 0 and 0 -> * 100 for percent)
                callback(that.createCompleteImageSet(imageName, referenceImage, newImage, diff.image, diff.percent * 100, jimp.distance(referenceImage, newImage) * 100, ''));
            });
        });
    });
};

/**
 * Deletes images of an image set.
 *
 * @param imageSet The image set from which the images should be deleted.
 * @param callback Called when the complete deletion process is done. Has the updated image imageMetaInformationModel information model object as job.
 * **/
ImageManipulator.prototype.deleteImageSetImages = function (imageSet, callback) {

    // Delete image which are part of the set
    this.__deleteFile(imageSet.getReferenceImage().getPath());
    this.__deleteFile(imageSet.getNewImage().getPath());
    this.__deleteFile(imageSet.getDiffImage().getPath());

    // Call callback when stuff is done
    if(callback){
        callback();
    }
};

/**
 * Loads an image via jimp.
 *
 * @param imagePath The complete path to the image file.
 * @param callback Called when the image was loaded. Returns the image as jimp object and an error object.
 * **/
ImageManipulator.prototype.loadImage = function (imagePath, callback) {
    jimp.read(imagePath, function (err, newImage) {
        callback(err, newImage);
    });
};

/* ----- Creation Helper Methods ----- */

/**
 * Creates an image set for one image only (there exists only a reference or new image).
 *
 * @param imageName The name of the image.
 * @param image The jimp loaded image.
 * @param error The error. E.g. something like: 'There exists no base image for this new image yet'.
 * @param isReferenceImage Determines whether the given information is for a reference or new image. Boolean expected.
 *
 * @return The constructed image set containing the information.
 * **/
ImageManipulator.prototype.createSingleImageSet = function (imageName, image, error, isReferenceImage) {
    var imageSet = new ImageSetModel();

    // Set error values
    imageSet.setError(error);
    imageSet.setDifference(100);
    imageSet.setDistance(100);

    // Edit set dependant of the image type
    if(isReferenceImage) {
        imageSet.getReferenceImage().setHeight(image.bitmap.height);
        imageSet.getReferenceImage().setWidth(image.bitmap.width);
        imageSet.getReferenceImage().setName(imageName);
        imageSet.getReferenceImage().setPath(config.getReferenceImageFolderPath() + path.sep + imageName);
    } else {
        imageSet.getNewImage().setHeight(image.bitmap.height);
        imageSet.getNewImage().setWidth(image.bitmap.width);
        imageSet.getNewImage().setName(imageName);
        imageSet.getNewImage().setPath(config.getNewImageFolderPath() + path.sep + imageName);
    }

    return imageSet;
};

/**
 * Creates an image set containing the reference, new and diff images.
 *
 * @param imageName The name of the image. The name is the same for the reference, new and diff images.
 * @param referenceImage The reference jimp loaded image.
 * @param newImage The new jimp loaded image.
 * @param diffImage The diff jimp loaded image.
 * @param difference The percentual pixel difference between the reference and new image.
 * @param distance The hammond distance between the reference and new image.
 * @param error The error. E.g. something like: 'There exists no base image for this new image yet'.
 *
 * @return The constructed image set containing the information.
 * **/
ImageManipulator.prototype.createCompleteImageSet = function(imageName, referenceImage, newImage, diffImage, difference, distance, error){
    var imageSet = new ImageSetModel();

    imageSet.setDifference(difference);
    imageSet.setDistance(distance);
    imageSet.setError(error);

    imageSet.getReferenceImage().setName(imageName);
    imageSet.getReferenceImage().setHeight(referenceImage.bitmap.height);
    imageSet.getReferenceImage().setWidth(referenceImage.bitmap.width);
    imageSet.getReferenceImage().setPath(config.getReferenceImageFolderPath() + path.sep + imageName);

    imageSet.getNewImage().setName(imageName);
    imageSet.getNewImage().setHeight(referenceImage.bitmap.height);
    imageSet.getNewImage().setWidth(referenceImage.bitmap.width);
    imageSet.getNewImage().setPath(config.getNewImageFolderPath() + path.sep + imageName);

    imageSet.getDiffImage().setName(imageName);
    imageSet.getDiffImage().setHeight(referenceImage.bitmap.height);
    imageSet.getDiffImage().setWidth(referenceImage.bitmap.width);
    imageSet.getDiffImage().setPath(config.getResultImageFolderPath() + path.sep + imageName);

    return imageSet;
};

/* ----- Other helper methods ----- */

/**
 * Autocrops two images.
 *
 * @param image1 The first image to autocrop.
 * @param image2 The second image to autocrop.
 * @param autoCrop Boolean. If true, the images will be autocroped, else not.
 * **/
ImageManipulator.prototype.__autoCrop = function (image1, image2, autoCrop) {
    if(autoCrop){
        image1.autocrop();
        image2.autocrop();
    }
};

/**
 * Checks whether an image exists.
 *
 * @param imagePath The path to the image, which should be checked.
 * @return True if the image does exist, else false.
 * **/
ImageManipulator.prototype.__isImageExisting = function (imagePath) {
    return fs.existsSync(imagePath) && fs.statSync(imagePath).isFile();
};

/**
 * Deletes a file.
 *
 * @param path The file which should be deleted.
 * **/
ImageManipulator.prototype.__deleteFile = function (path) {
    if(this.__isImageExisting(path)){
        fs.unlink(path, function (err) {
            if(err){
                logger.error('Failed to delete file: ' + path, err);
                throw Error('Failed to delete file: ' + path, err);
            }
        });
    }
};

module.exports = ImageManipulator;<|endoftext|>


<commit_before>$(document).ready(function() {
    $(".search-box").on("input", function(){
        var val = $(this).val().toLowerCase();

        var notags = [];
        var nomatches = val.match(/notag:\w+/g);
        if (nomatches) {
            $.each(nomatches, function(k, v) {
                notags.push(v.substring(6).toLowerCase());
            });
        }
        val = $.trim(val.replace(/\s*notag:\w+/g, ""));

        var tags = [];

        var show_online = false;
        var show_offline = false;

        var matches = val.match(/tag:\w+/g);
        if (matches) {
            $.each(matches, function(k, v) {
                var tag = v.substring(4).toLowerCase();
                if (tag == "online") {
                    show_online = true;
                }
                else if (tag == "offline") {
                    show_offline = true;
                }
                else {
                    tags.push(tag);
                }
            });
        }
        val = $.trim(val.replace(/\s*tag:\w+/g, ""));

        matches = val.match(/type:\w+/g);
        var types = [];
        if (matches) {
            $.each(matches, function(k, v) {
                types.push(v.substring(5).toLowerCase());
            });
        }
        val = $.trim(val.replace(/\s*type:\w+/g, ""));

        var search_objects = $(this).data("search");
        var search_fields = $(this).data("fields").split(",");
        var sites_shown = 0;
        var sites_total = 0;
        $(search_objects).each(function(k, v) {
            var t = $(this);
            var fields = $.map(search_fields, function(val, i) {
                return t.find(val).text().toLowerCase();
            });
            var show = true;
            var site_tags = null;
            if (tags.length || notags.length) {
                site_tags = [];
                $(this).find(".tag").each(function(k, v) {
                    site_tags.push($(this).text().replace(/\W/g, "").toLowerCase());
                });
            }
            if (tags.length) {
                show = false;
                $.each(tags, function(k, v) {
                    $.each(site_tags, function(k2, v2) {
                        if (v2.indexOf(v) != -1) {
                            show = true;
                            return false;
                        }
                    });
                });
            }
            if (notags.length) {
                $.each(notags, function(k, v) {
                    $.each(site_tags, function(k2, v2) {
                        if (v2.indexOf(v) != -1) {
                            show = false;
                            return false;
                        }
                    });
                });
            }
            var matches = false;
            $.each(fields, function(k, v) {
                if (v.includes(val)) {
                    matches = true;
                    return false;
                }
            });
            if (show_offline) {
                if (!$(this).find(".fa.pull-left span").hasClass("red")) {
                    show = false;
                }
            }
            if (show_online) {
                if (!$(this).find(".fa.pull-left span").hasClass("green")) {
                    show = false;
                }
            }
            if (types.length) {
                var cmpObj = $(this).find(".fa.pull-left");
                var cmp = "other";
                if (cmpObj.hasClass("fa-user")) {
                    cmp = "user";
                }
                else if (cmpObj.hasClass("fa-snowflake-o")) {
                    cmp = "legacy";
                }
                else if (cmpObj.hasClass("fa-globe")) {
                    cmp = "activity";
                }
                if (types.indexOf(cmp) == -1) {
                    show = false;
                }
            }
            if (show && matches) {
                $(this).show();
                sites_shown++;
            }
            else {
                $(this).hide();
            }
            sites_total++;
        });
        if (sites_shown < sites_total) {
            $("#filtered").html("(" + sites_shown + " shown out of " + sites_total + ")");
        }
        else {
            $("#filtered").html("");
        }
    });
});
<commit_msg>match by partial types<commit_after>$(document).ready(function() {
    $(".search-box").on("input", function(){
        var val = $(this).val().toLowerCase();

        var notags = [];
        var nomatches = val.match(/notag:\w+/g);
        if (nomatches) {
            $.each(nomatches, function(k, v) {
                notags.push(v.substring(6).toLowerCase());
            });
        }
        val = $.trim(val.replace(/\s*notag:\w+/g, ""));

        var tags = [];

        var show_online = false;
        var show_offline = false;

        var matches = val.match(/tag:\w+/g);
        if (matches) {
            $.each(matches, function(k, v) {
                var tag = v.substring(4).toLowerCase();
                if (tag == "online") {
                    show_online = true;
                }
                else if (tag == "offline") {
                    show_offline = true;
                }
                else {
                    tags.push(tag);
                }
            });
        }
        val = $.trim(val.replace(/\s*tag:\w+/g, ""));

        matches = val.match(/type:\w+/g);
        var types = [];
        if (matches) {
            $.each(matches, function(k, v) {
                types.push(v.substring(5).toLowerCase());
            });
        }
        val = $.trim(val.replace(/\s*type:\w+/g, ""));

        var search_objects = $(this).data("search");
        var search_fields = $(this).data("fields").split(",");
        var sites_shown = 0;
        var sites_total = 0;
        $(search_objects).each(function(k, v) {
            var t = $(this);
            var fields = $.map(search_fields, function(val, i) {
                return t.find(val).text().toLowerCase();
            });
            var show = true;
            var site_tags = null;
            if (tags.length || notags.length) {
                site_tags = [];
                $(this).find(".tag").each(function(k, v) {
                    site_tags.push($(this).text().replace(/\W/g, "").toLowerCase());
                });
            }
            if (tags.length) {
                show = false;
                $.each(tags, function(k, v) {
                    $.each(site_tags, function(k2, v2) {
                        if (v2.indexOf(v) != -1) {
                            show = true;
                            return false;
                        }
                    });
                });
            }
            if (notags.length) {
                $.each(notags, function(k, v) {
                    $.each(site_tags, function(k2, v2) {
                        if (v2.indexOf(v) != -1) {
                            show = false;
                            return false;
                        }
                    });
                });
            }
            var matches = false;
            $.each(fields, function(k, v) {
                if (v.includes(val)) {
                    matches = true;
                    return false;
                }
            });
            if (show_offline) {
                if (!$(this).find(".fa.pull-left span").hasClass("red")) {
                    show = false;
                }
            }
            if (show_online) {
                if (!$(this).find(".fa.pull-left span").hasClass("green")) {
                    show = false;
                }
            }
            if (types.length) {
                var cmpObj = $(this).find(".fa.pull-left");
                var cmp = "other";
                if (cmpObj.hasClass("fa-user")) {
                    cmp = "user";
                }
                else if (cmpObj.hasClass("fa-snowflake-o")) {
                    cmp = "legacy";
                }
                else if (cmpObj.hasClass("fa-globe")) {
                    cmp = "activity";
                }
                $.each(types, function(k, v) {
                    if (v.includes(cmp)) {
                        matches = true;
                        return false;
                    }
                });
            }
            if (show && matches) {
                $(this).show();
                sites_shown++;
            }
            else {
                $(this).hide();
            }
            sites_total++;
        });
        if (sites_shown < sites_total) {
            $("#filtered").html("(" + sites_shown + " shown out of " + sites_total + ")");
        }
        else {
            $("#filtered").html("");
        }
    });
});
<|endoftext|>


<commit_before>/*
* Copyright (c) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
var serverPath = '//galleryhangout.appspot.com/';

/*
 * ImgUr Image Control Functions
 */
var imgur_getImage = '//api.imgur.com/3/image/';
var imgur_postImage = '//api.imgur.com/3/image';
var imgur_viewImage = '//i.imgur.com/';

/**
 * Retrieve image info based on an id.
 *
 * @param id The id of the image to look up.
 */
function imgur_getImage(id) {
	var url = imgur_getImage + id;
	$.ajax({
		url: url,
		success: imgur_getResponse,
		dataType: "json",
		headers: {"Authorization" : imgur_clientId}
	});
}

/**
 * The callback for the getImage request.
 *
 * This function will also fill in the respective gallery
 * slot if the image exists.
 *
 * @param json JSON returned by the getImage request
 * @returns null
 */
function imgur_getResponse(json) {
	var data = $.parseJson(json);
	if(data['success'] == true) {
		var ext = null;

		if(data['data']['type'] == 'image/jpeg') {
			ext = '.jpg';
		}
		else if(data['data']['type'] == 'image/gif') {
			ext = '.gif';
		}
		else if(data['data']['type'] == 'image/png') {
			ext = '.png';
		}
		else {
			return {'success':false, 'data':'Unknown file type'}
		}

		var url = 'http:' + imgur_viewImage + data['data']['id'] + 'm' + ext;

		var addImage = document.getElementById(data['data']['id']).addImage;
		if(addImage != null) {
			addImage(url, ext);
		}
		else {
			document.getElementById(data['data']['id']).fail();
		}
	}
	else {d
		document.getElementById(data['data']['id']).fail();
	}
}

/* Hangout App Functions */

/**
 * Callback for when App state changes
 */
function updateState(event) {
	if(event.removedKeys.length > 0) {
		for(var k in event.removedKeys) {
			removeImage(k);
		}
	}
	else if(event.addKeys.length > 0) {
		for(var k in event.event.addKeys) {

			/* Make sure image doesn't already exit */
			if(document.getElementById(k) != null) continue;

			var slot = createImageSlot(k);

			/* Set the AddImage call back for after
			 * polling image info.
			 */
			slot.addImage = function(url,ext) {

				// Remove 'Loading' text
				var children = this.childNodes;
				for(var child in children) {
					this.removeChild(child);
				}
				// Remove the addImage function
				this.addImage = null;

				// Create the image and set it up
				var img = document.createElement("IMG");
				img.setAttribute("src", url);
				$(img).data("ext", ext);	// Store the file extension for when clicked
				img.onclick = onGalleryImageClick;
			}

			slot.fail = function() {
				this.style.borderColor = "red";
				$().toastmessage("showErrorToast", "Error fetching image");

				// Remove the node
				var parent = this.parentNode;
				parent.removeChild(this);
			}

			// Place slot in list
			var dropnode = document.getElementById("img-list-dropzone");
			document.getElementById("img-list").insertBefore(slot, dropnode);
		}
	}
}

/**
 * Remove the specified image from the gallery list.
 *
 * @param id An id for a slot to remove.
 */
function removeImage(id) {
	var slot = document.getElementById(id)
	if(slot != null) {
		slot.parentNode.removeChild(slot);
	}
}

function uploadImage(data) {}

//function onDeleteImage(data) {}

/*
 * Show the gallery image on the main pane
 */
function onGalleryImageClick() {
	// Get ID
	var id = this.parentNode.getAttribute("id");
	var ext = $(this).data['ext'];

	// Get mainview and change it
	var img = document.getElementById("img-main-view");
	var url = 'http:' + imgur_viewImage + id + ext;
	img.setAttribute('src', url);
}

function removeImage(key) {
	var node = document.getElementById(key);
	if(node) {
		document.getElementById("img-list").removeChild(node);
	}
}

/*
 * Creates a blank slot in the gallery while the thumb loads
 */
function createImageSlot(key) {

	// Create a holder slot while image loads
	var node = document.createElement("DIV");
	node.style.width = "160px";
	node.style.height = "160px";
	node.style = "5px solid black";
	node.style.textAlign = "center";
	node.setAttribute("id", key);

	// Set filler text to notify user of loading
	txt = Text("Loading...");
	node.appendChild(txt);

	return node;
}

// A function to be run at app initialization time which registers our callbacks
function init() {
  console.log('Init app.');

  // Get End of Image list (ie: Add/Drop Img zone)
  window.imgListDropZone = document.getElementById("img-list-dropzone")

  var apiReady = function(eventObj) {
    if (eventObj.isApiReady) {
      console.log('API is ready');

      gapi.hangout.data.onStateChanged.add(function(eventObj) {
        updateStateUi(eventObj.state);
      });

      updateStateUi(gapi.hangout.data.getState());
      updateParticipantsUi(gapi.hangout.getParticipants());

      gapi.hangout.onApiReady.remove(apiReady);
    }
  };

  // This application is pretty simple, but use this special api ready state
  // event if you would like to any more complex app setup.
  gapi.hangout.onApiReady.add(apiReady);
}

gadgets.util.registerOnLoadHandler(init);
<commit_msg>Add more code for adding/viewing image<commit_after>/*
* Copyright (c) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
var serverPath = '//galleryhangout.appspot.com/';

/*
 * ImgUr Image Control Functions
 */
var imgur_getImage = '//api.imgur.com/3/image/';
var imgur_postImage = '//api.imgur.com/3/image';
var imgur_viewImage = '//i.imgur.com/';

/**
 * Retrieve image info based on an id.
 *
 * @param id The id of the image to look up.
 */
function imgur_getImage(id) {
	var url = imgur_getImage + id;
	$.ajax({
		url: url,
		success: imgur_getResponse,
		dataType: "json",
		headers: {"Authorization" : imgur_clientId}
	});
}

/**
 * The callback for the getImage request.
 *
 * This function will also fill in the respective gallery
 * slot if the image exists.
 *
 * @param json JSON returned by the getImage request
 * @returns null
 */
function imgur_getResponse(json) {
	var data = $.parseJson(json);
	if(data['success'] == true) {
		var ext = null;

		if(data['data']['type'] == 'image/jpeg') {
			ext = '.jpg';
		}
		else if(data['data']['type'] == 'image/gif') {
			ext = '.gif';
		}
		else if(data['data']['type'] == 'image/png') {
			ext = '.png';
		}
		else {
			return {'success':false, 'data':'Unknown file type'}
		}

		var url = 'http:' + imgur_viewImage + data['data']['id'] + 'm' + ext;

		var addImage = document.getElementById(data['data']['id']).addImage;
		if(addImage != null) {
			addImage(url, ext);
		}
		else {
			document.getElementById(data['data']['id']).fail();
		}
	}
	else {d
		document.getElementById(data['data']['id']).fail();
	}
}

/* Hangout App Functions */

/**
 * Callback for when App state changes
 */
function updateState(event) {
	if(event.removedKeys.length > 0) {
		for(var k in event.removedKeys) {
			removeImageFromGalleryList(k);
		}
	}
	else if(event.addKeys.length > 0) {
		for(var k in event.event.addKeys) {
			addImageToGalleryList(k);
		}
	}
	else if(event.addKeys.length == 0 && event.removeKeys.length == 0) {
		/* Refresh List */
		// Add phase
		for(var key in state) {
			var ele = document.getElementById(key);
			if(ele == null) {
				addImageToGalleryList(key);
			}
		}
		// Remove Images not in State
		var node = document.getElementById("img-list").firstChild;
		var end = document.getElementById("img-list-dropzone");
		while(node != end) {
			if(state[node.getAttribute("id")] == null) {
				document.getElementById("img-list").removeChild(node);
			}
			node = node.nextSibling;
		}

	}
}

function addImageToGalleryList(k) {
	/* Make sure image doesn't already exit */
	if(document.getElementById(k) != null) continue;

	var slot = createImageSlot(k);

	/* Set the AddImage call back for after
	 * polling image info.
	 */
	slot.addImage = function(url,ext) {

		// Remove 'Loading' text
		var children = this.childNodes;
		for(var child in children) {
			this.removeChild(child);
		}
		// Remove the addImage function
		this.addImage = null;

		// Create the image and set it up
		var img = document.createElement("IMG");
		img.setAttribute("src", url);
		$(img).data("ext", ext);	// Store the file extension for when clicked
		img.onclick = onGalleryImageClick;
	}

	slot.fail = function() {
		this.style.borderColor = "red";
		$().toastmessage("showErrorToast", "Error fetching image");

		// Remove the node
		var parent = this.parentNode;
		parent.removeChild(this);
	}

	// Place slot in list
	var dropnode = document.getElementById("img-list-dropzone");
	document.getElementById("img-list").insertBefore(slot, dropnode);
}

function uploadImage(data) {

}

//function onDeleteImage(data) {}

/*
 * Show the gallery image on the main pane
 */
function onGalleryImageClick() {
	// Get ID
	var id = this.parentNode.getAttribute("id");
	var ext = $(this).data['ext'];

	// Get mainview and change it
	var img = document.getElementById("img-main-view");
	var url = 'http:' + imgur_viewImage + id + ext;
	img.setAttribute('src', url);
}

/**
 * Remove the specified image from the gallery list.
 *
 * @param key An id for a slot to remove.
 */
function removeImageFromGalleryList(key) {
	var node = document.getElementById(key);
	if(node) {
		document.getElementById("img-list").removeChild(node);
	}
}

/*
 * Creates a blank slot in the gallery while the thumb loads
 */
function createImageSlot(key) {

	// Create a holder slot while image loads
	var node = document.createElement("DIV");
	node.style.width = "160px";
	node.style.height = "160px";
	node.style = "5px solid black";
	node.style.textAlign = "center";
	node.setAttribute("id", key);

	// Set filler text to notify user of loading
	txt = Text("Loading...");
	node.appendChild(txt);

	return node;
}

// A function to be run at app initialization time which registers our callbacks
function init() {
  console.log('Init app.');

  // Get End of Image list (ie: Add/Drop Img zone)
  window.imgListDropZone = document.getElementById("img-list-dropzone")

  var apiReady = function(eventObj) {
    if (eventObj.isApiReady) {
      console.log('API is ready');

      gapi.hangout.data.onStateChanged.add(function(eventObj) {
        updateStateUi(eventObj.state);
      });

      updateStateUi(gapi.hangout.data.getState());
      updateParticipantsUi(gapi.hangout.getParticipants());

      gapi.hangout.onApiReady.remove(apiReady);
    }
  };

  // This application is pretty simple, but use this special api ready state
  // event if you would like to any more complex app setup.
  gapi.hangout.onApiReady.add(apiReady);
}

gadgets.util.registerOnLoadHandler(init);
<|endoftext|>


<commit_before>var INSTALLED={
	"keys":["guyana","greenland","iceland"],
	"guyana":{
		"path":"./static/ggmc/data/guyana/",
		"bbox":[-61.5,1.1,-56.3,8.7],
		"center":[-58.9,4.9],
		"color":"rgba(255,255,0,1)",
		"fill":"rgba(0,100,40,.1)",
		"width":2,
		"polygon_features":[
			{"filename":"pacs.geojson","color":"rgba(0,255,0,1)","fill":'rgba(0,255,0,0.25)','width':1},
			{"filename":"gy_rivers.geojson","color":"rgba(0,0,255,1)","fill":'rgba(0,0,255,1)','width':1},
		],
		"point_features":[
			{"filename":"gy_towns.geojson","color":"rgba(255,0,0,1)","fill":'rgba(255,255,255,1)','width':5,'radius':10},
		],
		"line_features":[
//			{"filename":"test_segment.geojson","color":"rgba(155,255,0,1)",'width':5},
		]
	},
	"iceland":{
		"path":"./static/ggmc/data/iceland/",
		"bbox":[-24.542, 63.39,-13.499,66.536],
		"center":[(-24.542+-13.499)/2.,65.],
		"color":"#ff0",
		"fill":"rgba(0,100,0,0.5)",
		"width":2,
		"polygon_features":[],
		"point_features":[],
		"line_features":[]
	},
	"greenland":{
		"path":"./static/ggmc/data/greenland/",
		"bbox":[-73.054, 59.79,-12.155,83.624],
		"center":[(-73.054-12.155)/2.,76.],
		"color":"#ff0",
		"fill":"rgba(100,100,0,0.5)",
		"width":2,
		"polygon_features":[],
		"point_features":[],
		"line_features":[]
	},
}

<commit_msg>commented the river layer<commit_after>var INSTALLED={
	"keys":["guyana","greenland","iceland"],
	"guyana":{
		"path":"./static/ggmc/data/guyana/",
		"bbox":[-61.5,1.1,-56.3,8.7],
		"center":[-58.9,4.9],
		"color":"rgba(255,255,0,1)",
		"fill":"rgba(0,100,40,.1)",
		"width":2,
		"polygon_features":[
			{"filename":"pacs.geojson","color":"rgba(0,255,0,1)","fill":'rgba(0,255,0,0.25)','width':1},
			//{"filename":"gy_rivers.geojson","color":"rgba(0,0,255,1)","fill":'rgba(0,0,255,1)','width':1},
		],
		"point_features":[
			{"filename":"gy_towns.geojson","color":"rgba(255,0,0,1)","fill":'rgba(255,255,255,1)','width':5,'radius':10},
		],
		"line_features":[
//			{"filename":"test_segment.geojson","color":"rgba(155,255,0,1)",'width':5},
		]
	},
	"iceland":{
		"path":"./static/ggmc/data/iceland/",
		"bbox":[-24.542, 63.39,-13.499,66.536],
		"center":[(-24.542+-13.499)/2.,65.],
		"color":"#ff0",
		"fill":"rgba(0,100,0,0.5)",
		"width":2,
		"polygon_features":[],
		"point_features":[],
		"line_features":[]
	},
	"greenland":{
		"path":"./static/ggmc/data/greenland/",
		"bbox":[-73.054, 59.79,-12.155,83.624],
		"center":[(-73.054-12.155)/2.,76.],
		"color":"#ff0",
		"fill":"rgba(100,100,0,0.5)",
		"width":2,
		"polygon_features":[],
		"point_features":[],
		"line_features":[]
	},
}

<|endoftext|>


<commit_before>var preContestControllers = angular.module('preContestControllers', []);

preContestControllers.controller('MainCtrl', ['$scope', '$http', '$timeout',
    function ($scope, $http, $timeout, $window) {
      function sync () {
        $http.get('api/v1/updates').success(function (data) {
          if ($scope.rawTime < parseInt(data['remaining_time'])) {
            $window.location.reload();
          }
          $scope.rawTime = data['remaining_time'];
          $scope.remainingTime = moment($scope.rawTime);
          $timeout(sync, 5000);
          for (i = 1000; i <= 4000; i += 1000) {
            $timeout(tick, i);
          }
        });
      }

      function tick () {
        $scope.rawTime -= 1;
        if ($scope.rawTime < 0) {
          $window.location.reload();
        } else {
          $scope.remainingTime = moment($scope.rawTime);
        }
      }

      sync();
    }]);

preContestControllers.controller('HomeCtrl', ['$scope', '$http',
    function ($scope, $http) {
    }]);

var contestControllers = angular.module('contestControllers', []);
var probIds = [];

contestControllers.controller('MainCtrl', ['$scope', '$http', '$interval', '$rootScope',
    function ($scope, $http, $interval, $rootScope, $window) {
      $http.get('api/v1/metadata').success(function (data) {
        $scope.probIds = probIds = data['prob_ids'];
        $scope.probContents = data['prob_contents'];
        $scope.remainingPermits = data['remaining_permit_counts'];
        $scope.problemsTimeToSolve = data['problems_time_to_solve'];

        for (var i = 0; i < probIds.length; i++) {
          $scope.problemsTimeToSolve[probIds[i]] = momentMinutes($scope.problemsTimeToSolve[probIds[i]]);
        }
      });

      $rootScope.syncUpdates = function () {
        $http.get('api/v1/updates').success(function (data) {
          if (typeof $rootScope.prevSync !== 'undefined')
            $interval.cancel($rootScope.prevSync);
          $rootScope.rawTime = data['remaining_time'];
          $scope.scoreboard = data['scoreboard'];
          $scope.clarifications = data['clarifications'];
          $rootScope.remainingTime = moment($rootScope.rawTime);
          $rootScope.prevSync = $interval($rootScope.clockTick, 1000, 29);
        });
      }

      $rootScope.clockTick = function () {
        $rootScope.rawTime -= 1;
        if ($rootScope.rawTime >= 0) {
          $rootScope.remainingTime = moment($rootScope.rawTime);
        }
      }

      $rootScope.syncUpdates();
      $interval($rootScope.syncUpdates, 30000);
    }]);

contestControllers.controller('HomeCtrl', ['$scope', '$http',
    function ($scope, $http) {
    }]);

var whitelist = [];
var allClarifications = [];
var radioModel = 'Active';

contestControllers.controller('AdminCtrl', ['$scope', '$rootScope', '$http', '$cookies', '$window', '$modal', '$interval',
    function ($scope, $rootScope, $http, $cookies, $window, $modal, $interval) {
      function sync () {
        $http.get('api/v1/admin/updates').success(function (data) {
          $scope.whitelist = data.whitelist;
          $scope.allClarifications = data.clarifs;
          $scope.boardIsFrozen = data.frozen;
          $scope.radioModel = $scope.boardIsFrozen ? 'Frozen' : 'Active';
        });
      }
      sync();
      $interval(sync, 10000);

      $scope.rejudgeProblem = function(problemId) {
        submit_url = 'api/v1/admin/rejudge';
        submit_data = { '_xsrf': $cookies._xsrf, 'probId': problemId };
        $http({
          method  : 'POST',
          url     : submit_url,
          data    : $.param(submit_data),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function(data) {
          $window.alert("Rejudging problem " + problemId);
        });
      }

      $scope.processAddTimeInput = function(numMin) {
        submit_url = 'api/v1/admin/add_time';
        submit_data = { '_xsrf': $cookies._xsrf, 'numMin': numMin };
        $http({
          method  : 'POST',
          url     : submit_url,
          data    : $.param(submit_data),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function(data) {
          $scope.addTimeTextBox = null;
          $rootScope.syncUpdates();
        });
      }

      $scope.processClarifResponse = function(respNum, clarifNum) {
        submit_url = 'api/v1/admin/clarifications';
        var respString = '';
        if(respNum == 2) {
          $scope.clarifRespModalOpen(respNum, clarifNum)
        }
        else {
          submit_data = { '_xsrf': $cookies._xsrf, 'respNum': respNum, 'clarifNum': clarifNum, 'respString': '' };
          $http({
            method  : 'POST',
            url     : submit_url,
            data    : $.param(submit_data),
            headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
          }).success(function(data) {
            sync();
          });
        }
      }

      $scope.processAddAdminForm = function(newAdmin) {
        if (newAdmin == null)
          return;
        submit_url = 'api/v1/admin/whitelist';
        submit_data = { '_xsrf': $cookies._xsrf, 'newAdmin': newAdmin };
        $http({
          method  : 'POST',
          url     : submit_url,
          data    : $.param(submit_data),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function(data) {
          $scope.addAdminTextBox = null;
          sync();
        });

      }

      $scope.changeState = function(state) {
        submit_url = 'api/v1/admin/frozen';
        submit_data = { '_xsrf': $cookies._xsrf, 'state': state };
        $http({
          method  : 'POST',
          url     : submit_url,
          data    : $.param(submit_data),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function (data) {});
      }

      $scope.clarifRespModalOpen = function(respNum, clarifNum) {
        var modalInstance = $modal.open({
          templateUrl: 'clarifResponse.html',
          controller: 'ClarifRespModalCtrl',
          resolve: {
            respNum: function () {
              return respNum;
            },
            clarifNum: function() {
              return clarifNum;
            }
          }
        });

        modalInstance.result.then(function (response) {
          submit_url = 'api/v1/admin/clarifications'
          response['_xsrf'] = $cookies._xsrf;
              $http({
                method  : 'POST',
                url     : submit_url,
                data    : $.param(response),
                headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
              }).success(function(data) {
                sync();
              });
        }, function () {
        });
      };

      $scope.newClarification = function(index) {
        $scope.newClarifModalOpen($scope.probIds[index])
      }

      $scope.newClarifModalOpen = function(probId) {
        var modalInstance = $modal.open({
          templateUrl: 'newClarification.html',
          controller: 'NewClarifModalCtrl',
          resolve: {
            probId: function () {
              return probId;
            }
          }
        });

        modalInstance.result.then(function (response) {
          submit_url = 'api/v1/admin/clarification'
          response['_xsrf'] = $cookies._xsrf;
              $http({
                method  : 'POST',
                url     : submit_url,
                data    : $.param(response),
                headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
              }).success(function(data) {
                sync();
              });
        }, function () {
        });
      };

      var tabClasses;

      function initTabs() {
        tabClasses = ["","","",""];
      }

      $scope.getTabClass = function (tabNum) {
        return tabClasses[tabNum];
      };

      $scope.getTabPaneClass = function (tabNum) {
        return "tab-pane " + tabClasses[tabNum];
      }

      $scope.setActiveTab = function (tabNum) {
        initTabs();
        tabClasses[tabNum] = "active";
      };

      initTabs();
      $scope.setActiveTab(1);
    }]);

contestControllers.controller('ClarifRespModalCtrl', function ($scope, $modalInstance, respNum, clarifNum) {

  $scope.ok = function () {
    $modalInstance.close({
      'respNum': respNum,
      'clarifNum': clarifNum,
      'response': $scope.response,
    });
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});

contestControllers.controller('NewClarifModalCtrl', function ($scope, $modalInstance, probId) {

  $scope.ok = function () {
    $modalInstance.close({
      'probId': probId,
      'response': $scope.newClarifResp,
    });
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});

contestControllers.controller('ProblemCtrl', ['$scope', '$http', '$rootScope', '$window', '$cookies', '$interval',
    function ($scope, $http, $rootScope, $window, $cookies, $interval) {
      var tabClasses;

      $scope.files = {};
      $scope.files.output = [];
      $scope.files.source = [];
      i = 0;
      for (probId in probIds) {
        $scope.files.output.push("");
        $scope.files.source.push("");
      }
      if (typeof $rootScope.showSubmit == 'undefined') {
        $rootScope.showSubmit = [];
        $rootScope.ttl = [];
        $rootScope.ttlText = [];
        $rootScope.tick = [];
        for (probId in probIds) {
          $rootScope.showSubmit.push(false);
          $rootScope.ttl.push(-1);
          $rootScope.ttlText.push("");
          $rootScope.tick.push(null);
        }
      }

      function initTabs() {
        tabClasses = [];
        $scope.open = [];
        for (probId in probIds) {
          tabClasses.push("");
          $scope.open.push(false);
        }
      }

      $scope.getTabClass = function (tabNum) {
        return tabClasses[tabNum];
      };

      $scope.getTabPaneClass = function (tabNum) {
        return "tab-pane " + tabClasses[tabNum];
      };

      $scope.setActiveTab = function (tabNum) {
        initTabs();
        tabClasses[tabNum] = "active panel-primary";
        $rootScope.activeTab = tabNum;
        $scope.open[tabNum - 1] = true;
      };

      if (typeof $rootScope.activeTab == 'undefined') {
        $scope.setActiveTab(1);
      } else {
        $scope.setActiveTab($rootScope.activeTab);
      }

      $scope.clarif = {}
      $scope.processClarifForm = function (index) {
        submitUrl = 'api/v1/submit/' + probIds[index] + '/clarification';
        submitData = { '_xsrf': $cookies._xsrf, 'content': $scope.clarif[index] };
        $http({
          method  : 'POST',
          url     : submitUrl,
          data    : $.param(submitData),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function (data) {
          if (data) {
            $window.alert("Clarification submitted successfully!");
            $scope.clarifications.push({
              'prob_id': probIds[index],
              'message': $scope.clarif[index],
            });
            $scope.clarif[index] = null;
          }
        });
      };

      function tick (index) {
        $rootScope.ttl[index] -= 1;
        $rootScope.ttlText[index] = momentMinutes($rootScope.ttl[index]);
        if ($rootScope.ttl[index] <= 0) {
          $rootScope.showSubmit[index] = false;
          if ($rootScope.tick[index] != null) {
            $interval.cancel($rootScope.tick[index]);
            $rootScope.tick[index] = null;
          }
        }
      }

      $scope.getPermit = function (index, create) {
        permitUrl = 'api/v1/permits';
        permitData = { '_xsrf': $cookies._xsrf, 'content': probIds[index], 'create': create };
        $http({
          method  : 'POST',
          url     : permitUrl,
          data    : $.param(permitData),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function (data) {
          if (data == null && !create)
            return;
          if ($rootScope.tick[index] != null) {
            $interval.cancel($rootScope.tick[index]);
            $rootScope.tick[index] = null;
          }
          if (data === 'solved') {
            $scope.remainingPermits[probIds[index]] = -1;
            return;
          }
          if (data.is_new)
            $scope.remainingPermits[probIds[index]]--;
          $rootScope.showSubmit[index] = true;
          $rootScope.ttl[index] = data.ttl;
          $rootScope.ttlText[index] = momentMinutes($rootScope.ttl[index]);
          $rootScope.tick[index] = $interval(function () {
            tick(index);
          }, 1000, data.ttl);
        }).error(function (data, status, headers, config) {
          if (create && status == 403) {
            $window.alert("You are out of permits!");
          }
        });
      };

      var i = 0;
      for (probId in probIds) {
        $scope.getPermit(i, false);
        i++;
      }

      $scope.processSubmitForm = function (index) {
        submitUrl = 'api/v1/submit/' + probIds[index] + '/solution';
        submitData = { '_xsrf': $cookies._xsrf,
                       'outputFile': $scope.files.output[index],
                       'sourceFile': $scope.files.source[index], };
        $rootScope.showSubmit[index] = false;
        $rootScope.ttl[index] = 0;
        if ($rootScope.tick[index] != null) {
          $interval.cancel($rootScope.tick[index]);
          $rootScope.tick[index] = null;
        }
        $http({
          method  : 'POST',
          url     : submitUrl,
          data    : $.param(submitData),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function (data) {
          if (data) {
            $window.alert("Solution accepted!");
          } else {
            $window.alert("Solution incorrect!");
          }
        });
      };
    }]);

contestControllers.controller('ScoreboardCtrl', ['$scope', '$http',
    function ($scope, $http) {
    }]);
<commit_msg>fixed not showing solved directly after submitting problem correctly<commit_after>var preContestControllers = angular.module('preContestControllers', []);

preContestControllers.controller('MainCtrl', ['$scope', '$http', '$timeout',
    function ($scope, $http, $timeout, $window) {
      function sync () {
        $http.get('api/v1/updates').success(function (data) {
          if ($scope.rawTime < parseInt(data['remaining_time'])) {
            $window.location.reload();
          }
          $scope.rawTime = data['remaining_time'];
          $scope.remainingTime = moment($scope.rawTime);
          $timeout(sync, 5000);
          for (i = 1000; i <= 4000; i += 1000) {
            $timeout(tick, i);
          }
        });
      }

      function tick () {
        $scope.rawTime -= 1;
        if ($scope.rawTime < 0) {
          $window.location.reload();
        } else {
          $scope.remainingTime = moment($scope.rawTime);
        }
      }

      sync();
    }]);

preContestControllers.controller('HomeCtrl', ['$scope', '$http',
    function ($scope, $http) {
    }]);

var contestControllers = angular.module('contestControllers', []);
var probIds = [];

contestControllers.controller('MainCtrl', ['$scope', '$http', '$interval', '$rootScope',
    function ($scope, $http, $interval, $rootScope, $window) {
      $http.get('api/v1/metadata').success(function (data) {
        $scope.probIds = probIds = data['prob_ids'];
        $scope.probContents = data['prob_contents'];
        $scope.remainingPermits = data['remaining_permit_counts'];
        $scope.problemsTimeToSolve = data['problems_time_to_solve'];

        for (var i = 0; i < probIds.length; i++) {
          $scope.problemsTimeToSolve[probIds[i]] = momentMinutes($scope.problemsTimeToSolve[probIds[i]]);
        }
      });

      $rootScope.syncUpdates = function () {
        $http.get('api/v1/updates').success(function (data) {
          if (typeof $rootScope.prevSync !== 'undefined')
            $interval.cancel($rootScope.prevSync);
          $rootScope.rawTime = data['remaining_time'];
          $scope.scoreboard = data['scoreboard'];
          $scope.clarifications = data['clarifications'];
          $rootScope.remainingTime = moment($rootScope.rawTime);
          $rootScope.prevSync = $interval($rootScope.clockTick, 1000, 29);
        });
      }

      $rootScope.clockTick = function () {
        $rootScope.rawTime -= 1;
        if ($rootScope.rawTime >= 0) {
          $rootScope.remainingTime = moment($rootScope.rawTime);
        }
      }

      $rootScope.syncUpdates();
      $interval($rootScope.syncUpdates, 30000);
    }]);

contestControllers.controller('HomeCtrl', ['$scope', '$http',
    function ($scope, $http) {
    }]);

var whitelist = [];
var allClarifications = [];
var radioModel = 'Active';

contestControllers.controller('AdminCtrl', ['$scope', '$rootScope', '$http', '$cookies', '$window', '$modal', '$interval',
    function ($scope, $rootScope, $http, $cookies, $window, $modal, $interval) {
      function sync () {
        $http.get('api/v1/admin/updates').success(function (data) {
          $scope.whitelist = data.whitelist;
          $scope.allClarifications = data.clarifs;
          $scope.boardIsFrozen = data.frozen;
          $scope.radioModel = $scope.boardIsFrozen ? 'Frozen' : 'Active';
        });
      }
      sync();
      $interval(sync, 10000);

      $scope.rejudgeProblem = function(problemId) {
        submit_url = 'api/v1/admin/rejudge';
        submit_data = { '_xsrf': $cookies._xsrf, 'probId': problemId };
        $http({
          method  : 'POST',
          url     : submit_url,
          data    : $.param(submit_data),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function(data) {
          $window.alert("Rejudging problem " + problemId);
        });
      }

      $scope.processAddTimeInput = function(numMin) {
        submit_url = 'api/v1/admin/add_time';
        submit_data = { '_xsrf': $cookies._xsrf, 'numMin': numMin };
        $http({
          method  : 'POST',
          url     : submit_url,
          data    : $.param(submit_data),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function(data) {
          $scope.addTimeTextBox = null;
          $rootScope.syncUpdates();
        });
      }

      $scope.processClarifResponse = function(respNum, clarifNum) {
        submit_url = 'api/v1/admin/clarifications';
        var respString = '';
        if(respNum == 2) {
          $scope.clarifRespModalOpen(respNum, clarifNum)
        }
        else {
          submit_data = { '_xsrf': $cookies._xsrf, 'respNum': respNum, 'clarifNum': clarifNum, 'respString': '' };
          $http({
            method  : 'POST',
            url     : submit_url,
            data    : $.param(submit_data),
            headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
          }).success(function(data) {
            sync();
          });
        }
      }

      $scope.processAddAdminForm = function(newAdmin) {
        if (newAdmin == null)
          return;
        submit_url = 'api/v1/admin/whitelist';
        submit_data = { '_xsrf': $cookies._xsrf, 'newAdmin': newAdmin };
        $http({
          method  : 'POST',
          url     : submit_url,
          data    : $.param(submit_data),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function(data) {
          $scope.addAdminTextBox = null;
          sync();
        });

      }

      $scope.changeState = function(state) {
        submit_url = 'api/v1/admin/frozen';
        submit_data = { '_xsrf': $cookies._xsrf, 'state': state };
        $http({
          method  : 'POST',
          url     : submit_url,
          data    : $.param(submit_data),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function (data) {});
      }

      $scope.clarifRespModalOpen = function(respNum, clarifNum) {
        var modalInstance = $modal.open({
          templateUrl: 'clarifResponse.html',
          controller: 'ClarifRespModalCtrl',
          resolve: {
            respNum: function () {
              return respNum;
            },
            clarifNum: function() {
              return clarifNum;
            }
          }
        });

        modalInstance.result.then(function (response) {
          submit_url = 'api/v1/admin/clarifications'
          response['_xsrf'] = $cookies._xsrf;
              $http({
                method  : 'POST',
                url     : submit_url,
                data    : $.param(response),
                headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
              }).success(function(data) {
                sync();
              });
        }, function () {
        });
      };

      $scope.newClarification = function(index) {
        $scope.newClarifModalOpen($scope.probIds[index])
      }

      $scope.newClarifModalOpen = function(probId) {
        var modalInstance = $modal.open({
          templateUrl: 'newClarification.html',
          controller: 'NewClarifModalCtrl',
          resolve: {
            probId: function () {
              return probId;
            }
          }
        });

        modalInstance.result.then(function (response) {
          submit_url = 'api/v1/admin/clarification'
          response['_xsrf'] = $cookies._xsrf;
              $http({
                method  : 'POST',
                url     : submit_url,
                data    : $.param(response),
                headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
              }).success(function(data) {
                sync();
              });
        }, function () {
        });
      };

      var tabClasses;

      function initTabs() {
        tabClasses = ["","","",""];
      }

      $scope.getTabClass = function (tabNum) {
        return tabClasses[tabNum];
      };

      $scope.getTabPaneClass = function (tabNum) {
        return "tab-pane " + tabClasses[tabNum];
      }

      $scope.setActiveTab = function (tabNum) {
        initTabs();
        tabClasses[tabNum] = "active";
      };

      initTabs();
      $scope.setActiveTab(1);
    }]);

contestControllers.controller('ClarifRespModalCtrl', function ($scope, $modalInstance, respNum, clarifNum) {

  $scope.ok = function () {
    $modalInstance.close({
      'respNum': respNum,
      'clarifNum': clarifNum,
      'response': $scope.response,
    });
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});

contestControllers.controller('NewClarifModalCtrl', function ($scope, $modalInstance, probId) {

  $scope.ok = function () {
    $modalInstance.close({
      'probId': probId,
      'response': $scope.newClarifResp,
    });
  };

  $scope.cancel = function () {
    $modalInstance.dismiss('cancel');
  };
});

contestControllers.controller('ProblemCtrl', ['$scope', '$http', '$rootScope', '$window', '$cookies', '$interval',
    function ($scope, $http, $rootScope, $window, $cookies, $interval) {
      var tabClasses;

      $scope.files = {};
      $scope.files.output = [];
      $scope.files.source = [];
      i = 0;
      for (probId in probIds) {
        $scope.files.output.push("");
        $scope.files.source.push("");
      }
      if (typeof $rootScope.showSubmit == 'undefined') {
        $rootScope.showSubmit = [];
        $rootScope.ttl = [];
        $rootScope.ttlText = [];
        $rootScope.tick = [];
        for (probId in probIds) {
          $rootScope.showSubmit.push(false);
          $rootScope.ttl.push(-1);
          $rootScope.ttlText.push("");
          $rootScope.tick.push(null);
        }
      }

      function initTabs() {
        tabClasses = [];
        $scope.open = [];
        for (probId in probIds) {
          tabClasses.push("");
          $scope.open.push(false);
        }
      }

      $scope.getTabClass = function (tabNum) {
        return tabClasses[tabNum];
      };

      $scope.getTabPaneClass = function (tabNum) {
        return "tab-pane " + tabClasses[tabNum];
      };

      $scope.setActiveTab = function (tabNum) {
        initTabs();
        tabClasses[tabNum] = "active panel-primary";
        $rootScope.activeTab = tabNum;
        $scope.open[tabNum - 1] = true;
      };

      if (typeof $rootScope.activeTab == 'undefined') {
        $scope.setActiveTab(1);
      } else {
        $scope.setActiveTab($rootScope.activeTab);
      }

      $scope.clarif = {}
      $scope.processClarifForm = function (index) {
        submitUrl = 'api/v1/submit/' + probIds[index] + '/clarification';
        submitData = { '_xsrf': $cookies._xsrf, 'content': $scope.clarif[index] };
        $http({
          method  : 'POST',
          url     : submitUrl,
          data    : $.param(submitData),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function (data) {
          if (data) {
            $window.alert("Clarification submitted successfully!");
            $scope.clarifications.push({
              'prob_id': probIds[index],
              'message': $scope.clarif[index],
            });
            $scope.clarif[index] = null;
          }
        });
      };

      function tick (index) {
        $rootScope.ttl[index] -= 1;
        $rootScope.ttlText[index] = momentMinutes($rootScope.ttl[index]);
        if ($rootScope.ttl[index] <= 0) {
          $rootScope.showSubmit[index] = false;
          if ($rootScope.tick[index] != null) {
            $interval.cancel($rootScope.tick[index]);
            $rootScope.tick[index] = null;
          }
        }
      }

      $scope.getPermit = function (index, create) {
        permitUrl = 'api/v1/permits';
        permitData = { '_xsrf': $cookies._xsrf, 'content': probIds[index], 'create': create };
        $http({
          method  : 'POST',
          url     : permitUrl,
          data    : $.param(permitData),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function (data) {
          if (data == null && !create)
            return;
          if ($rootScope.tick[index] != null) {
            $interval.cancel($rootScope.tick[index]);
            $rootScope.tick[index] = null;
          }
          if (data === 'solved') {
            $scope.remainingPermits[probIds[index]] = -1;
            return;
          }
          if (data.is_new)
            $scope.remainingPermits[probIds[index]]--;
          $rootScope.showSubmit[index] = true;
          $rootScope.ttl[index] = data.ttl;
          $rootScope.ttlText[index] = momentMinutes($rootScope.ttl[index]);
          $rootScope.tick[index] = $interval(function () {
            tick(index);
          }, 1000, data.ttl);
        }).error(function (data, status, headers, config) {
          if (create && status == 403) {
            $window.alert("You are out of permits!");
          }
        });
      };

      var i = 0;
      for (probId in probIds) {
        $scope.getPermit(i, false);
        i++;
      }

      $scope.processSubmitForm = function (index) {
        submitUrl = 'api/v1/submit/' + probIds[index] + '/solution';
        submitData = { '_xsrf': $cookies._xsrf,
                       'outputFile': $scope.files.output[index],
                       'sourceFile': $scope.files.source[index], };
        $rootScope.showSubmit[index] = false;
        $rootScope.ttl[index] = 0;
        if ($rootScope.tick[index] != null) {
          $interval.cancel($rootScope.tick[index]);
          $rootScope.tick[index] = null;
        }
        $http({
          method  : 'POST',
          url     : submitUrl,
          data    : $.param(submitData),
          headers : { 'Content-Type': 'application/x-www-form-urlencoded' },
        }).success(function (data) {
          if (data) {
            $scope.remainingPermits[probIds[index]] = -1;
            $window.alert("Solution accepted!");
          } else {
            $window.alert("Solution incorrect!");
          }
        });
      };
    }]);

contestControllers.controller('ScoreboardCtrl', ['$scope', '$http',
    function ($scope, $http) {
    }]);
<|endoftext|>


<commit_before>$(document).ready(function() {
  var $toggleHandler = $('input[data-toggle]');
  $toggleHandler.on('change', function() {
    var connect = $(this).data('toggle');
    var $target = $('[data-toggle-target]');

    if (connect === 'show') {
      $target.addClass('is-visible');
    } else {
      $target.removeClass('is-visible');
    }
  });
});
<commit_msg>add/remove "required" from field (hiding is not enough)<commit_after>$(document).ready(function() {
  var $toggleHandler = $('input[data-toggle]');
  $toggleHandler.on('change', function() {
    var connect = $(this).data('toggle');
    var $target = $('[data-toggle-target]');

    if (connect === 'show') {
      $target.addClass('is-visible');
      $("#birthdate").prop('required',true);
    } else {
      $target.removeClass('is-visible');
      $("#birthdate").prop('required',false);
    }
  });
});
<|endoftext|>