<commit_before>var gn = {};
gn.refresh_ms = 5000;

function template(row, dss) {
  row.find('.item_name').text(dss.Name);
  row.find('.item_date').text(dss.Create_date);
  row.find('.item_options').text(dss.Params);
  return row;
}

// Update the set of data sources in the table, filter out
// the ones that we already have based on DS name.
gn.updateDs = function() {
  var jqxhr = $.getJSON( "/json/", function() {
    console.log( "success" );
  })
    .done(function() {
      gn.serverActive();
       data = jqxhr.responseJSON;
      $("#dscount").text(data.length);
      $.map(data, function(el) {
        // map all the data onto the HTML table
        // if el.Name already exists, just skip it
        if ($('span').filter(
          function (index) { return $(this).text() == el.Name; }
        ).length == 0)
          {
            var newRow = $('#cart .template').clone().removeClass('template');
            template(newRow, el)
            .prependTo('#cart')
            .fadeIn();
          }
       });
    })
    .fail(function() {
      gn.serverInactive();
      console.log( "ERROR: Could not perform getJSON request. Server down?" );
    })
}

// functions to signal the status of connectivity to backend server
gn.serverActive = function() {
  $("#servercon").addClass('label-success');
  $("#servercon").removeClass('label-danger');
  $("#cart").removeClass('transparent');
}
gn.serverInactive = function() {
  $("#servercon").removeClass('label-success');
  $("#servercon").addClass('label-danger');
  $("#cart").addClass('transparent');
}

// Starting, Stopping and toggling our requests to the
// server.
gn.start = function() {
	if(!gn.timer) {
	gn.timer = setInterval(function() {gn.updateDs();}, gn.refresh_ms);
	$("#hideButton").text('Pauze')
	$("#hideButton").toggleClass('btn-danger');
	$("#hideButton").toggleClass('btn-success');
  }
}
gn.stop = function() {
	clearInterval(gn.timer);
	gn.timer = undefined;
	$("#hideButton").text('Activate')
	$("#hideButton").toggleClass('btn-danger');
	$("#hideButton").toggleClass('btn-success');
}
gn.toggle = function() {
	if (gn.timer === undefined) {
		gn.start();
	} else {
		gn.stop();
	}
}

var init = false;
$(document).ready(function() {
	if (!init){
		init = true;

		$('body').data("gn-last-server-see", new Date().getTime());
		console.log($('body').data("gn-last-server-see"));

		gn.start()
		$("#hideButton").click( function() {
			gn.toggle();
		});
		gn.updateDs()
	}
});
<commit_msg>indenting<commit_after>var gn = {};
gn.refresh_ms = 5000;

function template(row, dss) {
  row.find('.item_name').text(dss.Name);
  row.find('.item_date').text(dss.Create_date);
  row.find('.item_options').text(dss.Params);
  return row;
}

// Update the set of data sources in the table, filter out
// the ones that we already have based on DS name.
gn.updateDs = function() {
  var jqxhr = $.getJSON( "/json/", function() {
    console.log( "success" );
  })
  .done(function() {
    gn.serverActive();
     data = jqxhr.responseJSON;
    $("#dscount").text(data.length);
    $.map(data, function(el) {
      // map all the data onto the HTML table
      // if el.Name already exists, just skip it
      if ($('span').filter(
        function (index) { return $(this).text() == el.Name; }
      ).length == 0)
        {
          var newRow = $('#cart .template').clone().removeClass('template');
          template(newRow, el)
          .prependTo('#cart')
          .fadeIn();
        }
     });
  })
  .fail(function() {
    gn.serverInactive();
    console.log( "ERROR: Could not perform getJSON request. Server down?" );
  })
}

// functions to signal the status of connectivity to backend server
gn.serverActive = function() {
  $("#servercon").addClass('label-success');
  $("#servercon").removeClass('label-danger');
  $("#cart").removeClass('transparent');
}
gn.serverInactive = function() {
  $("#servercon").removeClass('label-success');
  $("#servercon").addClass('label-danger');
  $("#cart").addClass('transparent');
}

// Starting, Stopping and toggling our requests to the
// server.
gn.start = function() {
  if(!gn.timer) {
  gn.timer = setInterval(function() {gn.updateDs();}, gn.refresh_ms);
  $("#hideButton").text('Pauze')
  $("#hideButton").toggleClass('btn-danger');
  $("#hideButton").toggleClass('btn-success');
  }
}
gn.stop = function() {
  clearInterval(gn.timer);
  gn.timer = undefined;
  $("#hideButton").text('Activate')
  $("#hideButton").toggleClass('btn-danger');
  $("#hideButton").toggleClass('btn-success');
}
gn.toggle = function() {
  if (gn.timer === undefined) {
    gn.start();
  } else {
    gn.stop();
  }
}

var init = false;
$(document).ready(function() {
  if (!init){
    init = true;

    gn.start()
    $("#hideButton").click( function() {
      gn.toggle();
    });
    gn.updateDs()
  }
});
<|endoftext|>


<commit_before>/**
*	Copyright 2017 Alan Darmasaputra
*
*	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 Caretaker = (function(){

	var Utils = (function(){

		var getBase64Async = function(file, onSuccess, onError){
			var reader = new FileReader()
   		reader.readAsDataURL(file);
			reader.onload = function(){
				if(onSuccess){
					onSuccess(reader.result)
				}
			}
			reader.onerror = function(error){
				if(onError){
					onError(error)
				}
			}
		}

		return {
			getBase64Async: getBase64Async
		}
	}())

	/**
	* Caretaker top window widget
	*
	*/
	var Widget = (function(){

		// default onclick listener to prevent widget from closing
		var widgetOnClick = function(e){
			console.log(e)
			e.stopPropagation()
		}

		function getInterfaceWidget(){
			const interfaceID = "CaretakerInterfaceWidget"
			var theInterface = document.querySelector('div#'+interfaceID)

			if(!theInterface){
				theInterface = document.createElement('div')
				theInterface.id = interfaceID
				document.body.appendChild(theInterface)

				theInterface.addEventListener('click', function(e){
					if(e.target == theInterface){
						e.stopPropagation();
						e.preventDefault();
						hideInterfaceWidget()
					}
				}, true)

				theInterface.addEventListener('touchend', function(e){
					if(e.target == theInterface){
						e.stopPropagation();
						e.preventDefault();
						hideInterfaceWidget()
					}
				}, true)
			}
			return theInterface
		}

		function removeClassFrom(classAttribute, className){
			classAttribute = classAttribute.trim().split(' ')
			var classIndex = classAttribute.indexOf(className)
			if(classIndex != -1){
				classAttribute.splice(classIndex, 1)
			}
			return classAttribute.join(' ')
		}
		function addClassFrom(classAttribute, className){
			classAttribute = classAttribute.trim().split(' ')
			classAttribute.push(className)
			return classAttribute.join(' ')
		}

		function hideInterfaceWidget(theInterface){
			var theInterface = theInterface || getInterfaceWidget()
			theInterface.className = removeClassFrom(theInterface.className, "active")
			theInterface.innerHTML = ""
			return theInterface
		}

		function callInterfaceWidget(){
			var theInterface = getInterfaceWidget()
			theInterface.className = addClassFrom(theInterface.className, "active")
			return theInterface
		}

		function callDateInputWidget(onChange, value){
			var theInterface = callInterfaceWidget()
			var intermediateChange = function(newValue){
				onChange(newValue)
				hideInterfaceWidget(theInterface)
			}
			ReactDOM.render(React.createElement(CaretakerDateInputWidget, {onChange:intermediateChange, value: value}), theInterface)
		}

		function callTimeInputWidget(onChange, value){
			var theInterface = callInterfaceWidget()
			var intermediateChange = function(newValue){
				onChange(newValue)
				hideInterfaceWidget(theInterface)
			}
			ReactDOM.render(React.createElement(CaretakerTimeInputWidget, {onChange:intermediateChange, value: value}), theInterface)
		}

		return {
			callDateInputWidget,
			callTimeInputWidget
		}
	}())

	/**
	* Special Input & Extensor Support
	*
	*/
	var SpecialInputPrivate = {
		inputMap : {}
	}
	var SpecialInputPublic = {
		isSpecialInput: function(type){
			if(SpecialInputPrivate.inputMap[type]){
				return true
			}else{
				return false
			}
		},
		isCommonInput: function(type){
			return !SpecialInputPublic.isSpecialInput(type)
		},
		getClass: function(type){
			return SpecialInputPrivate.inputMap[type]
		},
		register: function(type,className){
			if(SpecialInputPrivate.inputMap[type]){
				console.warn('SpecialInput '+type+' has been installed and cannot be replaced with '+className)
			}else{
				SpecialInputPrivate.inputMap[type] = className
			}
		}
	}

	class ValueNode{
		static from(object){
			return Object.assign(new this(), object)
		}
		convert(){
			return Object.assign({}, this)
		}
	}
	class ValueArray extends Array{
		convert(){
			return Array.from(this)
		}
	}

	/**
	* SubmissionPreprocessor
	* preprocess valueTree before submission
	*/
	var SubmissionUtility = (function(){
		var utilities = []

		function make(){

		}

		return {}
	}())
	var SubmissionPreprocessor = (function(){
		var preprocessors = []
		var utilities = {}

		function addUtility(name, utility){
			utilities[name] = utility
		}
		function makeUtility(){
			var utilityObject = {}
			for(var i in utilities){
				utilityObject[i] = new utilities[i]()
			}
			return utilityObject;
		}

		function preprocessOne(valueNode, props, utility){
			for(var i in preprocessors){
				valueNode = preprocessors[i](valueNode, props, utility)
			}
			return valueNode
		}
		function preprocessTree(valueNode, props, utility){
			if(valueNode instanceof ValueNode || valueNode instanceof ValueArray){
				valueNode = valueNode.convert()
				for(var i in valueNode){
					valueNode[i] = preprocessTree(valueNode[i], props, utility)
				}
			}
			valueNode = preprocessOne(valueNode, props, utility)
			return valueNode
		}
		function preprocess(valueRoot, props){
			var utility = makeUtility()
			var actionJSON = preprocessTree(valueRoot, props, utility)
			var formData = new FormData()
			var name = props.edit.name || "data"
			formData.append(name, JSON.stringify(actionJSON))
			for(var i in utility){
				var utilityClass = utilities[i]
				var utilityObject = utility[i]

				utilityClass.finalize(formData, utilityObject)
			}
			return formData
		}
		function append(func){
			if(typeof func == "function"){
				preprocessors.push(func)
			}
		}
		function prepend(func){
			if(typeof func == "function"){
				preprocessors.unshift(func)
			}
		}

		return {
			addUtility: addUtility,
			preprocess: preprocess,
			prepend: prepend,
			append: append
		}
	}())

	/**
	* Caretaker UploadedFile and UploadedFileMap
	*
	*/
	var globalInputFile
	class UploadedFile{
		static promptUpload(onChange, props){
			var inputFile = document.createElement('input')
			globalInputFile = inputFile
			var reader = new FileReader()
			var thisClass = this

			//ready the props
			for(var i in props){
				inputFile.setAttribute(i, props[i])
			}

			//ready the render
			inputFile.type = "file"
			inputFile.onchange = function(e){
				var file = inputFile.files[0]
				if(file){
					var uploadedFile = new thisClass(file)
					onChange(uploadedFile)
				}
			}
			inputFile.click()
		}
		constructor(file){
			this.fileData = {
				_is_caretaker_uploaded_file: true,
				name: file.name,
				size: file.size
			}
			this.originalFile = file
		}
		getName(){
			return this.fileData.name
		}
		getSize(){
			return this.fileData.size
		}
		getOriginalFile(){
			return this.originalFile
		}
		getData(){
			return this.fileData.data
		}
		getFileData(){
			return this.fileData
		}
	}
	class UploadedFileCatalog{
		static finalize(formData, uploadedFileCatalog){
			for(var i = 0; i<uploadedFileCatalog.files.length; i++){
				formData.append('files', uploadedFileCatalog.files[i])
			}
		}
		constructor(){
			this.files = []
		}
		register(file){
			var index = this.files.length
			this.files.push(file)
			return index
		}
	}

	SubmissionPreprocessor.addUtility('UploadedFileCatalog',UploadedFileCatalog)
	SubmissionPreprocessor.append(function(valueNode, props, utilities){
		if(valueNode instanceof UploadedFile){
			var fileData =  valueNode.getFileData()
			var index = utilities.UploadedFileCatalog.register(valueNode.getOriginalFile())
			fileData.index = index
			return fileData
		}
		return valueNode
	})

	function makeForm(formCommand, element){
		if(!React || !ReactDOM){
			throw new Error("Caretaker needs React and ReactDOM. If you are using Webpack, please bind React and ReactDOM to window like this \nwindow['React'] = React  \n window['ReactDOM = ReactDOM']")
		}
		if(typeof formCommand != "object"){
			throw new Error("Parameter formCommand must be object")
		}
		//parse
		if(typeof element == "string"){
			element = document.querySelector(element)
		}
		if(!(element instanceof HTMLElement)){
			throw new Error("Parameter element must be object")
		}

		return ReactDOM.render( React.createElement(CaretakerForm, formCommand), element )
	}

	return {
		SpecialInput:SpecialInputPublic,
		SubmissionPreprocessor: SubmissionPreprocessor,
		UploadedFile:UploadedFile,
		ValueArray:ValueArray,
		ValueNode:ValueNode,
		Utils:Utils,
		Widget:Widget,

		makeForm: makeForm
	}
})();
<commit_msg>added StructBank<commit_after>/**
*	Copyright 2017 Alan Darmasaputra
*
*	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 Caretaker = (function(){

	var StructBank = (function(){

		var structMap = {}

		function register(key,data){
			if(structMap[key]){
				console.warn('Key '+key+' has beed reserved')
			}else{
				structMap[key] = data
			}
		}
		function get(key){
			return structMap[key]
		}
		return {register:register, get:get}
	}())

	var Utils = (function(){

		var getBase64Async = function(file, onSuccess, onError){
			var reader = new FileReader()
   		reader.readAsDataURL(file);
			reader.onload = function(){
				if(onSuccess){
					onSuccess(reader.result)
				}
			}
			reader.onerror = function(error){
				if(onError){
					onError(error)
				}
			}
		}

		return {
			getBase64Async: getBase64Async
		}
	}())

	/**
	* Caretaker top window widget
	*
	*/
	var Widget = (function(){

		// default onclick listener to prevent widget from closing
		var widgetOnClick = function(e){
			console.log(e)
			e.stopPropagation()
		}

		function getInterfaceWidget(){
			const interfaceID = "CaretakerInterfaceWidget"
			var theInterface = document.querySelector('div#'+interfaceID)

			if(!theInterface){
				theInterface = document.createElement('div')
				theInterface.id = interfaceID
				document.body.appendChild(theInterface)

				theInterface.addEventListener('click', function(e){
					if(e.target == theInterface){
						e.stopPropagation();
						e.preventDefault();
						hideInterfaceWidget()
					}
				}, true)

				theInterface.addEventListener('touchend', function(e){
					if(e.target == theInterface){
						e.stopPropagation();
						e.preventDefault();
						hideInterfaceWidget()
					}
				}, true)
			}
			return theInterface
		}

		function removeClassFrom(classAttribute, className){
			classAttribute = classAttribute.trim().split(' ')
			var classIndex = classAttribute.indexOf(className)
			if(classIndex != -1){
				classAttribute.splice(classIndex, 1)
			}
			return classAttribute.join(' ')
		}
		function addClassFrom(classAttribute, className){
			classAttribute = classAttribute.trim().split(' ')
			classAttribute.push(className)
			return classAttribute.join(' ')
		}

		function hideInterfaceWidget(theInterface){
			var theInterface = theInterface || getInterfaceWidget()
			theInterface.className = removeClassFrom(theInterface.className, "active")
			theInterface.innerHTML = ""
			return theInterface
		}

		function callInterfaceWidget(){
			var theInterface = getInterfaceWidget()
			theInterface.className = addClassFrom(theInterface.className, "active")
			return theInterface
		}

		function callDateInputWidget(onChange, value){
			var theInterface = callInterfaceWidget()
			var intermediateChange = function(newValue){
				onChange(newValue)
				hideInterfaceWidget(theInterface)
			}
			ReactDOM.render(React.createElement(CaretakerDateInputWidget, {onChange:intermediateChange, value: value}), theInterface)
		}

		function callTimeInputWidget(onChange, value){
			var theInterface = callInterfaceWidget()
			var intermediateChange = function(newValue){
				onChange(newValue)
				hideInterfaceWidget(theInterface)
			}
			ReactDOM.render(React.createElement(CaretakerTimeInputWidget, {onChange:intermediateChange, value: value}), theInterface)
		}

		return {
			callDateInputWidget,
			callTimeInputWidget
		}
	}())

	/**
	* Special Input & Extensor Support
	*
	*/
	var SpecialInputPrivate = {
		inputMap : {}
	}
	var SpecialInputPublic = {
		isSpecialInput: function(type){
			if(SpecialInputPrivate.inputMap[type]){
				return true
			}else{
				return false
			}
		},
		isCommonInput: function(type){
			return !SpecialInputPublic.isSpecialInput(type)
		},
		getClass: function(type){
			return SpecialInputPrivate.inputMap[type]
		},
		register: function(type,className){
			if(SpecialInputPrivate.inputMap[type]){
				console.warn('SpecialInput '+type+' has been installed and cannot be replaced with '+className)
			}else{
				SpecialInputPrivate.inputMap[type] = className
			}
		}
	}

	class ValueNode{
		static from(object){
			return Object.assign(new this(), object)
		}
		convert(){
			return Object.assign({}, this)
		}
	}
	class ValueArray extends Array{
		convert(){
			return Array.from(this)
		}
	}

	/**
	* SubmissionPreprocessor
	* preprocess valueTree before submission
	*/
	var SubmissionUtility = (function(){
		var utilities = []

		function make(){

		}

		return {}
	}())
	var SubmissionPreprocessor = (function(){
		var preprocessors = []
		var utilities = {}

		function addUtility(name, utility){
			utilities[name] = utility
		}
		function makeUtility(){
			var utilityObject = {}
			for(var i in utilities){
				utilityObject[i] = new utilities[i]()
			}
			return utilityObject;
		}

		function preprocessOne(valueNode, props, utility){
			for(var i in preprocessors){
				valueNode = preprocessors[i](valueNode, props, utility)
			}
			return valueNode
		}
		function preprocessTree(valueNode, props, utility){
			if(valueNode instanceof ValueNode || valueNode instanceof ValueArray){
				valueNode = valueNode.convert()
				for(var i in valueNode){
					valueNode[i] = preprocessTree(valueNode[i], props, utility)
				}
			}
			valueNode = preprocessOne(valueNode, props, utility)
			return valueNode
		}
		function preprocess(valueRoot, props){
			var utility = makeUtility()
			var actionJSON = preprocessTree(valueRoot, props, utility)
			var formData = new FormData()
			var name = props.edit.name || "data"
			formData.append(name, JSON.stringify(actionJSON))
			for(var i in utility){
				var utilityClass = utilities[i]
				var utilityObject = utility[i]

				utilityClass.finalize(formData, utilityObject)
			}
			return formData
		}
		function append(func){
			if(typeof func == "function"){
				preprocessors.push(func)
			}
		}
		function prepend(func){
			if(typeof func == "function"){
				preprocessors.unshift(func)
			}
		}

		return {
			addUtility: addUtility,
			preprocess: preprocess,
			prepend: prepend,
			append: append
		}
	}())

	/**
	* Caretaker UploadedFile and UploadedFileMap
	*
	*/
	var globalInputFile
	class UploadedFile{
		static promptUpload(onChange, props){
			var inputFile = document.createElement('input')
			globalInputFile = inputFile
			var reader = new FileReader()
			var thisClass = this

			//ready the props
			for(var i in props){
				inputFile.setAttribute(i, props[i])
			}

			//ready the render
			inputFile.type = "file"
			inputFile.onchange = function(e){
				var file = inputFile.files[0]
				if(file){
					var uploadedFile = new thisClass(file)
					onChange(uploadedFile)
				}
			}
			inputFile.click()
		}
		constructor(file){
			this.fileData = {
				_is_caretaker_uploaded_file: true,
				name: file.name,
				size: file.size
			}
			this.originalFile = file
		}
		getName(){
			return this.fileData.name
		}
		getSize(){
			return this.fileData.size
		}
		getOriginalFile(){
			return this.originalFile
		}
		getData(){
			return this.fileData.data
		}
		getFileData(){
			return this.fileData
		}
	}
	class UploadedFileCatalog{
		static finalize(formData, uploadedFileCatalog){
			for(var i = 0; i<uploadedFileCatalog.files.length; i++){
				formData.append('files', uploadedFileCatalog.files[i])
			}
		}
		constructor(){
			this.files = []
		}
		register(file){
			var index = this.files.length
			this.files.push(file)
			return index
		}
	}

	SubmissionPreprocessor.addUtility('UploadedFileCatalog',UploadedFileCatalog)
	SubmissionPreprocessor.append(function(valueNode, props, utilities){
		if(valueNode instanceof UploadedFile){
			var fileData =  valueNode.getFileData()
			var index = utilities.UploadedFileCatalog.register(valueNode.getOriginalFile())
			fileData.index = index
			return fileData
		}
		return valueNode
	})

	function makeForm(formCommand, element){
		if(!React || !ReactDOM){
			throw new Error("Caretaker needs React and ReactDOM. If you are using Webpack, please bind React and ReactDOM to window like this \nwindow['React'] = React  \n window['ReactDOM = ReactDOM']")
		}
		if(typeof formCommand != "object"){
			throw new Error("Parameter formCommand must be object")
		}
		//parse
		if(typeof element == "string"){
			element = document.querySelector(element)
		}
		if(!(element instanceof HTMLElement)){
			throw new Error("Parameter element must be object")
		}

		return ReactDOM.render( React.createElement(CaretakerForm, formCommand), element )
	}

	return {
		SpecialInput:SpecialInputPublic,
		SubmissionPreprocessor: SubmissionPreprocessor,
		UploadedFile:UploadedFile,
		ValueArray:ValueArray,
		ValueNode:ValueNode,
		Utils:Utils,
		Widget:Widget,
		StructBank:StructBank,
		makeForm: makeForm
	}
})();
<|endoftext|>


<commit_before>/**
 *  This file is subject to the terms and conditions defined in the file
 *  'LICENCE.md', which is part of this source code package.
 *  @author Ralf Mueller
 */

'use strict';

var jasmineNodeLite = require('../lib/index');

function onConsoleReporterDone() {
    console.log('ConsoleReporter done!');
}

var options = {
    consoleReporterOptions: {
        stackTrace: false,
        onComplete: onConsoleReporterDone
    },
    jasmineNodeLiteOptions:{
        specs: ['./spec/samplec.spec.js', './spec/samplea.spec.js','./spec/sampleb.spec.js']
    }
};
console.log('Using Jasmine:' + jasmineNodeLite.jasmineVersion);
var reporter = new jasmineNodeLite.ConsoleReporter(options.consoleReporterOptions);
jasmineNodeLite.registerReporter(reporter);

jasmineNodeLite.executeSpecs(options.jasmineNodeLiteOptions);

options.jasmineNodeLiteOptions.specs = ['./spec/literatecoffee.spec.litcoffee'];
jasmineNodeLite.executeSpecs(options.jasmineNodeLiteOptions);<commit_msg>Small test commit (for flow test)<commit_after>/**
 *  This file is subject to the terms and conditions defined in the file
 *  'LICENCE.md', which is part of this source code package.
 *  @author Ralf Mueller
 */

'use strict';

var jasmineNodeLite = require('../lib/index');

function onConsoleReporterDone() {
    console.log('ConsoleReporter done!');
}

var options = {
    consoleReporterOptions: {
        stackTrace: false,
        onComplete: onConsoleReporterDone
    },
    jasmineNodeLiteOptions:{
        specs: ['./spec/samplec.spec.js', './spec/samplea.spec.js', './spec/sampleb.spec.js']
    }
};
console.log('Using Jasmine:' + jasmineNodeLite.jasmineVersion);
var reporter = new jasmineNodeLite.ConsoleReporter(options.consoleReporterOptions);
jasmineNodeLite.registerReporter(reporter);

jasmineNodeLite.executeSpecs(options.jasmineNodeLiteOptions);

options.jasmineNodeLiteOptions.specs = ['./spec/literatecoffee.spec.litcoffee'];
jasmineNodeLite.executeSpecs(options.jasmineNodeLiteOptions);<|endoftext|>


<commit_before>var callbacks = [];

module.exports = function(router) {

  var message_broker = {};

  router.post('/', function(req, res) {
    console.log("YES: " + req.data);
    notify(req.data);
    res.json(["OKAY", 200]);
  });

  message_broker.registerCallback = function(callback) {
    callbacks.push(callback);
  }

  return message_broker;

}

function notify(data) {
  callbacks.forEach(function(element, index, array) {
    element(data);
  });
}
<commit_msg>This should be body not data<commit_after>var callbacks = [];

module.exports = function(router) {

  var message_broker = {};

  router.post('/', function(req, res) {
    console.log("YES: " + req.body);
    notify(req.body);
    res.json(["OKAY", 200]);
  });

  message_broker.registerCallback = function(callback) {
    callbacks.push(callback);
  }

  return message_broker;

}

function notify(data) {
  callbacks.forEach(function(element, index, array) {
    element(data);
  });
}
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Link } from 'react-router';
import _ from 'underscore';

// Constants
import { ADMIN_PREFIX } from '../constants';

// Components
import Splitter from '../components/Splitter';

// Actions
import { fetchCollections } from '../actions/collections';

export class Sidebar extends Component {

  componentDidMount() {
    const { fetchCollections } = this.props;
    fetchCollections();
  }

  renderCollections() {
    const { collections } = this.props;
    if (collections.length) {
      return _.chain(collections)
      .filter(col => col.label != 'posts') // TODO
      .map((col, i) => {
        return (

            <Link activeClassName="active" to={`${ADMIN_PREFIX}/collections/${col.label}`}>
              {col.label}
            </Link>

        );
      }).value();
    }
  }

  render() {
    return (

        <Link className="logo" to={`${ADMIN_PREFIX}/pages`} />

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/pages`}>Pages</Link>

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/collections/posts`}>Posts</Link>

            {this.renderCollections()}

            <Splitter />

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/data`}>Data</Link>

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/static-files`}>Static Files</Link>

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/plugins`}>Plugins</Link>

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/git`}>Git</Link>

            <Splitter />

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/configuration`}>Configuration</Link>

    );
  }
}

Sidebar.propTypes = {
  collections: PropTypes.array.isRequired,
  fetchCollections: PropTypes.func.isRequired
};

function mapStateToProps(state) {
  const { collections } = state;
  return {
    collections: collections.collections
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    fetchCollections
  }, dispatch);
}

export default connect(
  mapStateToProps,
  mapDispatchToProps,
  null,
  {pure:false})(Sidebar); // fix this when react-router 3.0.0
<commit_msg>capitalize Sidebar collection names<commit_after>import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Link } from 'react-router';
import _ from 'underscore';

// Constants
import { ADMIN_PREFIX } from '../constants';

// Components
import Splitter from '../components/Splitter';

// Actions
import { fetchCollections } from '../actions/collections';

import { capitalize } from '../utils/helpers';

export class Sidebar extends Component {

  componentDidMount() {
    const { fetchCollections } = this.props;
    fetchCollections();
  }

  renderCollections() {
    const { collections } = this.props;
    if (collections.length) {
      return _.chain(collections)
      .filter(col => col.label != 'posts') // TODO
      .map((col, i) => {
        return (

            <Link activeClassName="active" to={`${ADMIN_PREFIX}/collections/${col.label}`}>
              {capitalize(col.label)}
            </Link>

        );
      }).value();
    }
  }

  render() {
    return (

        <Link className="logo" to={`${ADMIN_PREFIX}/pages`} />

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/pages`}>Pages</Link>

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/collections/posts`}>Posts</Link>

            {this.renderCollections()}

            <Splitter />

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/data`}>Data</Link>

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/static-files`}>Static Files</Link>

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/plugins`}>Plugins</Link>

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/git`}>Git</Link>

            <Splitter />

              <Link activeClassName="active" to={`${ADMIN_PREFIX}/configuration`}>Configuration</Link>

    );
  }
}

Sidebar.propTypes = {
  collections: PropTypes.array.isRequired,
  fetchCollections: PropTypes.func.isRequired
};

function mapStateToProps(state) {
  const { collections } = state;
  return {
    collections: collections.collections
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({
    fetchCollections
  }, dispatch);
}

export default connect(
  mapStateToProps,
  mapDispatchToProps,
  null,
  {pure:false})(Sidebar); // fix this when react-router 3.0.0
<|endoftext|>


<commit_before>angular.module('materialscommons', []);

var app = angular.module('materialscommons',
    [
        'ngSanitize',
        'ngMessages',
        'ui',
        'ngCookies',
        'ui.router',
        'restangular',
        'jmdobry.angular-cache',
        'textAngular', 'angularGrid',
        'ngDragDrop', 'ngTagsInput',
        'angular.filter', 'ui.calendar',
        '$strap.directives', 'ui.bootstrap', 'toastr',
        "hljs", "RecursionHelper",'googlechart',
        'materialscommons']);

app.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {

    mcglobals = {};
    doConfig();
    $stateProvider
        // Navbar
        .state('home', {
            url: '/home',
            templateUrl: 'application/core/splash.html'
        })
        .state('login', {
            url: '/login',
            templateUrl: 'application/core/login/login.html'
        })
        .state('logout', {
            url: '/logout',
            controller: 'LogoutController'
        })
        .state('reviews', {
            url: '/reviews',
            templateUrl: 'application/core/reviews/reviews.html'
        })
        .state('machines', {
            url: '/machines',
            templateUrl: 'application/core/machines/machines.html'
        })

        /*
         ########################################################################
         ####################### Account ##################################
         ########################################################################
         */
        .state('account', {
            url: '/account',
            templateUrl: 'application/core/account/account.html'
        })
        .state('account.password', {
            url: '/password',
            templateUrl: 'application/core/account/password/password.html'
        })
        .state('account.apikey', {
            url: '/apikey',
            templateUrl: 'application/core/account/apikey/apikey.html'
        })
        .state('account.settings', {
            url: '/settings',
            templateUrl: 'application/core/account/settings/settings.html'
        })
        .state('account.templates', {
            url: '/templates',
            templateUrl: 'application/core/account/templates/templates.html'
        })

        /*
         ########################################################################
         ########################### Projects ###################################
         ########################################################################
         */
        .state('projects', {
            url: '/projects',
            abstract: true,
            template: '

',
            resolve: {
                Projects: "model.projects",
                projects: function (Projects) {
                    return Projects.getList();
                },

                Templates: "model.templates",
                templates: function (Templates) {
                    return Templates.getList();
                }
            }
        })
        .state('projects.create', {
            url: '/create',
            templateUrl: 'application/core/projects/create.html',
            controller: 'CreateProjectController',
            controllerAs: 'project'
        })
        .state('projects.project', {
            url: '/project/:id',
            templateUrl: 'application/core/projects/project/project.html',
            resolve: {
                project: ["$stateParams", "model.projects", "projects", "templates",
                    function ($stateParams, Projects) {
                        // We use templates as a dependency so that they are all loaded
                        // before getting to this step. Otherwise the order of items
                        // being resolved isn't in the order we need them.
                        return Projects.get($stateParams.id);
                    }]
            },
            onEnter: ["pubsub", "project", function (pubsub) {
                pubsub.send("reviews.change");
            }],
            controller: "ProjectController",
            controllerAs: 'project'
        })
        .state('projects.project.home', {
            url: '/home',
            templateUrl: 'application/core/projects/project/home/home.html',
            controller: "projectHome",
            controllerAs: "home"
        })
        .state('projects.project.search', {
            url: '/search/:query',
            templateUrl: 'application/core/projects/project/search.html',
            controller: 'SearchController',
            controllerAs: 'search'
        })
        .state("projects.project.files", {
            url: "/files",
            templateUrl: "application/core/projects/project/files/files.html",
            controller: "FilesController",
            controllerAs: "files"
        })
        .state("projects.project.files.all", {
            url: "/all",
            templateUrl: "application/core/projects/project/files/all.html",
            controller: "FilesAllController",
            controllerAs: 'files'
        })
        .state("projects.project.files.all.edit", {
            url: "/edit/:file_id/:file_type",
            templateUrl: "application/core/projects/project/files/edit.html",
            controller: "FilesEditController",
            controllerAs: 'file'
        })
        .state("projects.project.files.edit", {
            url: "/edit/:file_id/:file_type",
            templateUrl: "application/core/projects/project/files/edit.html",
            controller: "FilesEditController",
            controllerAs: "file"
        })
        .state("projects.project.files.images", {
            url: "/images",
            templateUrl: "application/core/projects/project/files/images.html",
            controller: "FilesImagesController"
        })
        .state("projects.project.files.types", {
            url: "/types",
            templateUrl: "application/core/projects/project/files/types.html",
            controller: "FilesByTypeController"
        })
        .state("projects.project.files.search", {
            url: "/search",
            templateUrl: "application/core/projects/project/files/search.html",
            controller: "FilesSearchController",
            controllerAs: "search"
        })
        .state("projects.project.access", {
            url: "/access",
            templateUrl: "application/core/projects/project/access/access.html",
            controller: "ProjectAccessController",
            controllerAs: 'access'
        })
        .state("projects.project.reviews", {
            url: "/reviews/:category",
            templateUrl: "application/core/projects/project/reviews/reviews.html",
            controller: "projectReviews"
        })
        .state("projects.project.reviews.edit", {
            url: "/edit/:review_id",
            templateUrl: "application/core/projects/project/reviews/edit.html",
            controller: "projectEditReview"
        })
        .state("projects.project.reviews.create", {
            url: "/reviews/create",
            templateUrl: "application/core/projects/project/reviews/create.html",
            controller: "projectCreateReview"
        })
        .state("projects.project.notes", {
            url: "/notes",
            templateUrl: "application/core/projects/project/notes/notes.html",
            controller: "projectNotes",
            controllerAs: 'notes'
        })
        .state("projects.project.sideboard", {
            url: "/sideboard",
            templateUrl: "application/core/projects/project/sideboard/sideboard.html",
            controller: "projectSideboard"
        })
        .state("projects.project.processes", {
            url: "/processes",
            templateUrl: "application/core/projects/project/processes/processes.html",
            controller: "projectProcesses",
            controllerAs: 'processes'
        })
        .state("projects.project.processes.list", {
            url: "/list",
            templateUrl: "application/core/projects/project/processes/list.html",
            controller: "projectListProcess"
        })
        .state("projects.project.processes.create", {
            url: "/create",
            templateUrl: "application/core/projects/project/processes/create.html",
            controller: "projectCreateProcess"
        })
        .state("projects.project.processes.list.edit", {
            url: "/edit/:process_id",
            templateUrl: "application/core/projects/project/processes/edit.html",
            controller: "projectEditProcess"
        })
        .state("projects.project.processes.list.view", {
            url: "/view/:process_id",
            templateUrl: "application/core/projects/project/processes/view.html",
            controller: "projectViewProcess"
        })
        .state("projects.project.samples", {
            url: "/samples",
            templateUrl: "application/core/projects/project/samples/samples.html",
            controller: "SamplesController"
        })
        .state("projects.project.samples.all", {
            url: "/all",
            templateUrl: "application/core/projects/project/samples/all.html",
            controller: "SamplesAllController"
        })
        .state("projects.project.samples.all.edit", {
            url: "/edit/:sample_id",
            templateUrl: "application/core/projects/project/samples/edit.html",
            controller: "SamplesEditController"
        })
        .state("projects.project.samples.edit", {
            url: "/edit/:sample_id",
            templateUrl: "application/core/projects/project/samples/edit.html",
            controller: "SamplesEditController"
        });

    $urlRouterProvider.otherwise('/home');
}]);

app.run(["$rootScope", "User", "Restangular", appRun]);

function appRun($rootScope, User, Restangular) {
    Restangular.setBaseUrl(mcglobals.apihost);

    $rootScope.$on('$stateChangeStart', function () {
        if (User.isAuthenticated()) {
            $rootScope.email_address = User.u();
        }
    });
}
<commit_msg>Remove loading templates (call is unneeded). Add new controller for displaying directories.<commit_after>angular.module('materialscommons', []);

var app = angular.module('materialscommons',
    [
        'ngSanitize',
        'ngMessages',
        'ui',
        'ngCookies',
        'ui.router',
        'restangular',
        'jmdobry.angular-cache',
        'textAngular', 'angularGrid',
        'ngDragDrop', 'ngTagsInput',
        'angular.filter', 'ui.calendar',
        '$strap.directives', 'ui.bootstrap', 'toastr',
        "hljs", "RecursionHelper",'googlechart',
        'materialscommons']);

app.config(["$stateProvider", "$urlRouterProvider", function ($stateProvider, $urlRouterProvider) {

    mcglobals = {};
    doConfig();
    $stateProvider
        // Navbar
        .state('home', {
            url: '/home',
            templateUrl: 'application/core/splash.html'
        })
        .state('login', {
            url: '/login',
            templateUrl: 'application/core/login/login.html'
        })
        .state('logout', {
            url: '/logout',
            controller: 'LogoutController'
        })
        .state('reviews', {
            url: '/reviews',
            templateUrl: 'application/core/reviews/reviews.html'
        })
        .state('machines', {
            url: '/machines',
            templateUrl: 'application/core/machines/machines.html'
        })

        /*
         ########################################################################
         ####################### Account ##################################
         ########################################################################
         */
        .state('account', {
            url: '/account',
            templateUrl: 'application/core/account/account.html'
        })
        .state('account.password', {
            url: '/password',
            templateUrl: 'application/core/account/password/password.html'
        })
        .state('account.apikey', {
            url: '/apikey',
            templateUrl: 'application/core/account/apikey/apikey.html'
        })
        .state('account.settings', {
            url: '/settings',
            templateUrl: 'application/core/account/settings/settings.html'
        })
        .state('account.templates', {
            url: '/templates',
            templateUrl: 'application/core/account/templates/templates.html'
        })

        /*
         ########################################################################
         ########################### Projects ###################################
         ########################################################################
         */
        .state('projects', {
            url: '/projects',
            abstract: true,
            template: '

',
            resolve: {
                Projects: "model.projects",
                projects: function (Projects) {
                    return Projects.getList();
                }
            }
        })
        .state('projects.create', {
            url: '/create',
            templateUrl: 'application/core/projects/create.html',
            controller: 'CreateProjectController',
            controllerAs: 'project'
        })
        .state('projects.project', {
            url: '/project/:id',
            templateUrl: 'application/core/projects/project/project.html',
            resolve: {
                project: ["$stateParams", "model.projects", "projects",
                    function ($stateParams, Projects) {
                        // We use templates as a dependency so that they are all loaded
                        // before getting to this step. Otherwise the order of items
                        // being resolved isn't in the order we need them.
                        return Projects.get($stateParams.id);
                    }]
            },
            onEnter: ["pubsub", "project", function (pubsub) {
                pubsub.send("reviews.change");
            }],
            controller: "ProjectController",
            controllerAs: 'project'
        })
        .state('projects.project.home', {
            url: '/home',
            templateUrl: 'application/core/projects/project/home/home.html',
            controller: "projectHome",
            controllerAs: "home"
        })
        .state('projects.project.search', {
            url: '/search/:query',
            templateUrl: 'application/core/projects/project/search.html',
            controller: 'SearchController',
            controllerAs: 'search'
        })
        .state("projects.project.files", {
            url: "/files",
            templateUrl: "application/core/projects/project/files/files.html",
            controller: "FilesController",
            controllerAs: "files"
        })
        .state("projects.project.files.all", {
            url: "/all",
            templateUrl: "application/core/projects/project/files/all.html",
            controller: "FilesAllController",
            controllerAs: 'files'
        })
        .state("projects.project.files.all.edit", {
            url: "/edit/:file_id",
            templateUrl: "application/core/projects/project/files/edit.html",
            controller: "FilesEditController",
            controllerAs: 'file'
        })
        .state("projects.project.files.all.dir", {
            url: "/dir/:dir_id",
            templateUrl: "application/core/projects/project/files/dir.html",
            controller: "DirController",
            controllerAs: "dir"
        })
        .state("projects.project.files.edit", {
            url: "/edit/:file_id",
            templateUrl: "application/core/projects/project/files/edit.html",
            controller: "FilesEditController",
            controllerAs: "file"
        })
        .state("projects.project.files.images", {
            url: "/images",
            templateUrl: "application/core/projects/project/files/images.html",
            controller: "FilesImagesController"
        })
        .state("projects.project.files.types", {
            url: "/types",
            templateUrl: "application/core/projects/project/files/types.html",
            controller: "FilesByTypeController"
        })
        .state("projects.project.files.search", {
            url: "/search",
            templateUrl: "application/core/projects/project/files/search.html",
            controller: "FilesSearchController",
            controllerAs: "search"
        })
        .state("projects.project.access", {
            url: "/access",
            templateUrl: "application/core/projects/project/access/access.html",
            controller: "ProjectAccessController",
            controllerAs: 'access'
        })
        .state("projects.project.reviews", {
            url: "/reviews/:category",
            templateUrl: "application/core/projects/project/reviews/reviews.html",
            controller: "projectReviews"
        })
        .state("projects.project.reviews.edit", {
            url: "/edit/:review_id",
            templateUrl: "application/core/projects/project/reviews/edit.html",
            controller: "projectEditReview"
        })
        .state("projects.project.reviews.create", {
            url: "/reviews/create",
            templateUrl: "application/core/projects/project/reviews/create.html",
            controller: "projectCreateReview"
        })
        .state("projects.project.notes", {
            url: "/notes",
            templateUrl: "application/core/projects/project/notes/notes.html",
            controller: "projectNotes",
            controllerAs: 'notes'
        })
        .state("projects.project.sideboard", {
            url: "/sideboard",
            templateUrl: "application/core/projects/project/sideboard/sideboard.html",
            controller: "projectSideboard"
        })
        .state("projects.project.processes", {
            url: "/processes",
            templateUrl: "application/core/projects/project/processes/processes.html",
            controller: "projectProcesses",
            controllerAs: 'processes'
        })
        .state("projects.project.processes.list", {
            url: "/list",
            templateUrl: "application/core/projects/project/processes/list.html",
            controller: "projectListProcess"
        })
        .state("projects.project.processes.create", {
            url: "/create",
            templateUrl: "application/core/projects/project/processes/create.html",
            controller: "projectCreateProcess"
        })
        .state("projects.project.processes.list.edit", {
            url: "/edit/:process_id",
            templateUrl: "application/core/projects/project/processes/edit.html",
            controller: "projectEditProcess"
        })
        .state("projects.project.processes.list.view", {
            url: "/view/:process_id",
            templateUrl: "application/core/projects/project/processes/view.html",
            controller: "projectViewProcess"
        })
        .state("projects.project.samples", {
            url: "/samples",
            templateUrl: "application/core/projects/project/samples/samples.html",
            controller: "SamplesController"
        })
        .state("projects.project.samples.all", {
            url: "/all",
            templateUrl: "application/core/projects/project/samples/all.html",
            controller: "SamplesAllController"
        })
        .state("projects.project.samples.all.edit", {
            url: "/edit/:sample_id",
            templateUrl: "application/core/projects/project/samples/edit.html",
            controller: "SamplesEditController"
        })
        .state("projects.project.samples.edit", {
            url: "/edit/:sample_id",
            templateUrl: "application/core/projects/project/samples/edit.html",
            controller: "SamplesEditController"
        });

    $urlRouterProvider.otherwise('/home');
}]);

app.run(["$rootScope", "User", "Restangular", appRun]);

function appRun($rootScope, User, Restangular) {
    Restangular.setBaseUrl(mcglobals.apihost);

    $rootScope.$on('$stateChangeStart', function () {
        if (User.isAuthenticated()) {
            $rootScope.email_address = User.u();
        }
    });
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 SUSE Linux
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE.txt file for details.
 */

(function () {
  'use strict';

  angular.module('janusHangouts')
    .directive('jhVideoChat', jhVideoChatDirective);

  jhVideoChatDirective.$inject = ['$window', 'LogService', 'FeedsService', 'hotkeys', '$timeout'];

  function jhVideoChatDirective($window, LogService, FeedsService, hotkeys, $timeout) {
    return {
      restrict: 'EA',
      templateUrl: 'app/components/videochat/jh-video-chat.html',
      scope: {},
      controllerAs: 'vm',
      bindToController: true,
      link: jhVideoChatLink,
      controller: jhVideoChatCtrl
    };

    function jhVideoChatLink(scope) {
      scope.$on('gridster-resized', function() {
        scope.vm.adjustAllSizes();
      });
      // 'gridster-item-initialized' is not working for us,
      // let's workaround the problem
      $timeout(function() { scope.vm.adjustAllSizes(); }, 600);
    }

    function jhVideoChatCtrl() {
      /* jshint: validthis */
      var vm = this;
      var cols = 16;
      // Window width minus the paddings
      var gridWidth = $(window).width() - 25;
      // Window height minus header and footer (and some safety pixels)
      var gridHeight = $(window).height() - 33 - 20 - 5;
      // Items are square, i.e. width == height
      var itemHeight = gridWidth / cols;
      // How many rows do we have room for?
      var rows = Math.floor(gridHeight / itemHeight);
      if (rows < 6) { rows = 6; }

      // Adjust the layout depending on the vertical space
      var feedsH, chatH, chatR, chatC;
      if (rows < 10) {
        // Not enough space under the speaker (which is always 8x6) for the chat
        feedsH = Math.ceil(rows/2);
        chatH = Math.floor(rows/2);
        chatR = feedsH;
        chatC = 8;
      } else {
        // Chat below the speaker
        feedsH = rows;
        chatH = rows - 6;
        chatR = 6;
        chatC = 0;
      }

      vm.gridsterItems = [
        { size: [8, 6], position: [0, 0], content: "Speaker" },
        { size: [8, feedsH], position: [0, 8], content: "Participants" },
        { size: [8, chatH], position: [chatR, chatC], content: "Chat" }
      ];
      vm.gridsterOpts = {
        columns: cols,
        resizable: {
          stop: function(event, $element) {
            // 'gridster-item-transition-end' is not working for us, so we have
            // to use this callback and wait some extra time for the animations
            // to finish
            $timeout(function() { vm.adjustSize($element); }, 600);
          }
        }
      };

      /* Data */
      vm.highlight = {
        // Feed explicitly selected as highlight by the user (using the UI)
        byUser: null,
        // Feed currently highlighted, either manually (if byUser is set) or
        // automatically (if byUser is null)
        current: null
      };

      /* Functions */
      vm.feeds = feeds;
      vm.highlightedFeed = highlightedFeed;
      vm.mirrored = mirrored;
      vm.toggleHighlightedFeed = toggleHighlightedFeed;
      vm.isHighlighted = isHighlighted;
      vm.isHighlightedByUser = isHighlightedByUser;
      vm.logEntries = logEntries;
      vm.adjustSize = adjustSize;
      vm.adjustAllSizes = adjustAllSizes;
      vm.showHotkeys = showHotkeys;

      function feeds() {
        return FeedsService.allFeeds();
      }

      function highlightedFeed() {
        if (vm.highlight.byUser !== null) {
          vm.highlight.current = vm.highlight.byUser;
        } else {
          vm.highlight.current = FeedsService.speakingFeed() || vm.highlight.current || FeedsService.findMain();
        }
        return vm.highlight.current;
      }

      function mirrored() {
        var f = vm.highlightedFeed();
        if (f) {
          return (f.isPublisher && !f.isLocalScreen);
        } else {
          return false;
        }
      }

      function toggleHighlightedFeed(feed) {
        if (vm.highlight.byUser !== feed) {
          vm.highlight.byUser = feed;
        } else {
          vm.highlight.byUser = null;
        }
      }

      function isHighlighted(f) {
        return f === vm.highlight.current;
      }

      function isHighlightedByUser(f) {
        return f === vm.highlight.byUser;
      }

      function logEntries() {
        return LogService.allEntries();
      }

      function adjustSize($element) {
        var width = $element.innerWidth();
        var height = $element.innerHeight();
        var inner;

        // Is this the video grid item?
        inner = $("#main-video video", $element);
        if (inner.length) {
          inner.css({height: height + "px", width: width + "px"});
        }

        // Is this the chat grid item?
        inner = $("#jh-chat-messages", $element);
        if (inner.length) {
          inner.css({height: height - 40 + "px"});
        }

        // Is this the list of feeds item?
        inner = $("#thumbnails", $element);
        if (inner.length) {
          inner.css({height: height + "px", width: width + "px"});
        }

      }

      function adjustAllSizes() {
        $(".gridster-item").each(function(index, e) {
          vm.adjustSize($(e));
        });
      }

      function showHotkeys() {
        hotkeys.toggleCheatSheet();
      }
    }
  }
})();
<commit_msg>Better control of the highlighted feed<commit_after>/*
 * Copyright (C) 2015 SUSE Linux
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE.txt file for details.
 */

(function () {
  'use strict';

  angular.module('janusHangouts')
    .directive('jhVideoChat', jhVideoChatDirective);

  jhVideoChatDirective.$inject = ['$window', 'LogService', 'FeedsService', 'hotkeys', '$timeout'];

  function jhVideoChatDirective($window, LogService, FeedsService, hotkeys, $timeout) {
    return {
      restrict: 'EA',
      templateUrl: 'app/components/videochat/jh-video-chat.html',
      scope: {},
      controllerAs: 'vm',
      bindToController: true,
      link: jhVideoChatLink,
      controller: jhVideoChatCtrl
    };

    function jhVideoChatLink(scope) {
      scope.$on('gridster-resized', function() {
        scope.vm.adjustAllSizes();
      });
      // 'gridster-item-initialized' is not working for us,
      // let's workaround the problem
      $timeout(function() { scope.vm.adjustAllSizes(); }, 600);
    }

    function jhVideoChatCtrl() {
      /* jshint: validthis */
      var vm = this;
      var cols = 16;
      // Window width minus the paddings
      var gridWidth = $(window).width() - 25;
      // Window height minus header and footer (and some safety pixels)
      var gridHeight = $(window).height() - 33 - 20 - 5;
      // Items are square, i.e. width == height
      var itemHeight = gridWidth / cols;
      // How many rows do we have room for?
      var rows = Math.floor(gridHeight / itemHeight);
      if (rows < 6) { rows = 6; }

      // Adjust the layout depending on the vertical space
      var feedsH, chatH, chatR, chatC;
      if (rows < 10) {
        // Not enough space under the speaker (which is always 8x6) for the chat
        feedsH = Math.ceil(rows/2);
        chatH = Math.floor(rows/2);
        chatR = feedsH;
        chatC = 8;
      } else {
        // Chat below the speaker
        feedsH = rows;
        chatH = rows - 6;
        chatR = 6;
        chatC = 0;
      }

      vm.gridsterItems = [
        { size: [8, 6], position: [0, 0], content: "Speaker" },
        { size: [8, feedsH], position: [0, 8], content: "Participants" },
        { size: [8, chatH], position: [chatR, chatC], content: "Chat" }
      ];
      vm.gridsterOpts = {
        columns: cols,
        resizable: {
          stop: function(event, $element) {
            // 'gridster-item-transition-end' is not working for us, so we have
            // to use this callback and wait some extra time for the animations
            // to finish
            $timeout(function() { vm.adjustSize($element); }, 600);
          }
        }
      };

      /* Data */
      vm.highlight = {
        // Feed explicitly selected as highlight by the user (using the UI)
        byUser: null,
        // Feed currently highlighted, either manually (if byUser is set) or
        // automatically (if byUser is null)
        current: null
      };

      /* Functions */
      vm.feeds = feeds;
      vm.highlightedFeed = highlightedFeed;
      vm.mirrored = mirrored;
      vm.toggleHighlightedFeed = toggleHighlightedFeed;
      vm.isHighlighted = isHighlighted;
      vm.isHighlightedByUser = isHighlightedByUser;
      vm.logEntries = logEntries;
      vm.adjustSize = adjustSize;
      vm.adjustAllSizes = adjustAllSizes;
      vm.showHotkeys = showHotkeys;

      function feeds() {
        return FeedsService.allFeeds();
      }

      function highlightedFeed() {
        if (vm.highlight.byUser !== null) {
          vm.highlight.current = vm.highlight.byUser;
        } else {
          var current = vm.highlight.current;
          // The current one disconnected
          if (current && !current.isConnected()) {
            current = null;
          }
          // If current one is still speaking, there is no need to change
          if (!current || !current.getSpeaking()) {
            vm.highlight.current = FeedsService.speakingFeed() || current || FeedsService.findMain();
          }
        }
        return vm.highlight.current;
      }

      function mirrored() {
        var f = vm.highlightedFeed();
        if (f) {
          return (f.isPublisher && !f.isLocalScreen);
        } else {
          return false;
        }
      }

      function toggleHighlightedFeed(feed) {
        if (vm.highlight.byUser !== feed) {
          vm.highlight.byUser = feed;
        } else {
          vm.highlight.byUser = null;
        }
      }

      function isHighlighted(f) {
        return f === vm.highlight.current;
      }

      function isHighlightedByUser(f) {
        return f === vm.highlight.byUser;
      }

      function logEntries() {
        return LogService.allEntries();
      }

      function adjustSize($element) {
        var width = $element.innerWidth();
        var height = $element.innerHeight();
        var inner;

        // Is this the video grid item?
        inner = $("#main-video video", $element);
        if (inner.length) {
          inner.css({height: height + "px", width: width + "px"});
        }

        // Is this the chat grid item?
        inner = $("#jh-chat-messages", $element);
        if (inner.length) {
          inner.css({height: height - 40 + "px"});
        }

        // Is this the list of feeds item?
        inner = $("#thumbnails", $element);
        if (inner.length) {
          inner.css({height: height + "px", width: width + "px"});
        }

      }

      function adjustAllSizes() {
        $(".gridster-item").each(function(index, e) {
          vm.adjustSize($(e));
        });
      }

      function showHotkeys() {
        hotkeys.toggleCheatSheet();
      }
    }
  }
})();
<|endoftext|>


<commit_before>//
//var hasLibPng

FIRE.savePng = function (canvas, filename, path, pixelBuffer, zip, callback) {
    function getLibpng(callback) {
        if (typeof(libpng) !== 'undefined') {
            callback(libpng);
            return true;
        }
        else if (FIRE.isnode === false && require) {
            require(['libpng'], callback);
            return true;
        }
        return false;
    }

    var usingLibpng = getLibpng(function (libpng) {
        // encode by libpng
        console.time('libpng encode ' + filename);
        var png = libpng.createWriter(canvas.width, canvas.height);
        png.set_filter(libpng.FILTER_NONE);
        png.set_compression_level(3);
        png.write_imageData(pixelBuffer);
        png.write_end();
        console.timeEnd('libpng encode ' + filename);
        //console.log('Bytes: ' + png.data.length);
        if (FIRE.isnode) {
            if (zip) {
                zip.file(filename, png.data);   // TODO: test
            }
            else {
                Fs.writeFileSync(path, new Buffer(png.data));   //, {'encoding': 'base64'}
            }
        }
        else {
            if (zip) {
                zip.file(filename, png.data);
            }
            else {
                var blob = new Blob([new Uint8Array(png.data)], {type: 'image/png'});
                FIRE.downloadBlob(blob, filename);
            }
        }
        if (callback) {
            callback();
        }
    });
    if (usingLibpng === false) {
        var dataUrl, base64;
        if (!canvas) {
            throw 'no png encoder nor canvas';
        }
        // encode by canvas
        if (FIRE.isnode) {
            dataUrl = canvas.toDataURL('image/png');
            base64 = FIRE.imgDataUrlToBase64(dataUrl);
            if (zip) {
                zip.file(filename, base64, { base64: true });
            }
            else {
                Fs.writeFileSync(path, base64, {'encoding': 'base64'});
            }
        }
        else {
            if (zip) {
                dataUrl = canvas.toDataURL('image/png');
                base64 = FIRE.imgDataUrlToBase64(dataUrl);
                zip.file(filename, base64, { base64: true });
            }
            else {
                FIRE.downloadCanvas(canvas, filename);
            }
        }
        if (callback) {
            callback();
        }
    }
};

FIRE.saveText = function (text, filename, path) {
    if (FIRE.isnode) {
        Fs.writeFileSync(path, text, {'encoding': 'ascii'});
    }
    else {
        var blob = new Blob([text], {type: "text/plain;charset=utf-8"});    // not support 'application/json'
        FIRE.downloadBlob(blob, filename);
    }
};
<commit_msg>fix compatibility with node-webkit<commit_after>//
//var hasLibPng

FIRE.savePng = function (canvas, filename, path, pixelBuffer, zip, callback) {
    function getLibpng(callback) {
        if (typeof(libpng) !== 'undefined') {
            callback(libpng);
            return true;
        }
        else if (FIRE.isnode === false && requirejs) {
            requirejs(['libpng'], callback);
            return true;
        }
        return false;
    }

    var usingLibpng = getLibpng(function (libpng) {
        // encode by libpng
        console.time('libpng encode ' + filename);
        var png = libpng.createWriter(canvas.width, canvas.height);
        png.set_filter(libpng.FILTER_NONE);
        png.set_compression_level(3);
        png.write_imageData(pixelBuffer);
        png.write_end();
        console.timeEnd('libpng encode ' + filename);
        //console.log('Bytes: ' + png.data.length);
        if (FIRE.isnode) {
            if (zip) {
                zip.file(filename, png.data);   // TODO: test
            }
            else {
                Fs.writeFileSync(path, new Buffer(png.data));   //, {'encoding': 'base64'}
            }
        }
        else {
            if (zip) {
                zip.file(filename, png.data);
            }
            else {
                var blob = new Blob([new Uint8Array(png.data)], {type: 'image/png'});
                FIRE.downloadBlob(blob, filename);
            }
        }
        if (callback) {
            callback();
        }
    });
    if (usingLibpng === false) {
        var dataUrl, base64;
        if (!canvas) {
            throw 'no png encoder nor canvas';
        }
        // encode by canvas
        if (FIRE.isnode) {
            dataUrl = canvas.toDataURL('image/png');
            base64 = FIRE.imgDataUrlToBase64(dataUrl);
            if (zip) {
                zip.file(filename, base64, { base64: true });
            }
            else {
                Fs.writeFileSync(path, base64, {'encoding': 'base64'});
            }
        }
        else {
            if (zip) {
                dataUrl = canvas.toDataURL('image/png');
                base64 = FIRE.imgDataUrlToBase64(dataUrl);
                zip.file(filename, base64, { base64: true });
            }
            else {
                FIRE.downloadCanvas(canvas, filename);
            }
        }
        if (callback) {
            callback();
        }
    }
};

FIRE.saveText = function (text, filename, path) {
    if (FIRE.isnode) {
        Fs.writeFileSync(path, text, {'encoding': 'ascii'});
    }
    else {
        var blob = new Blob([text], {type: "text/plain;charset=utf-8"});    // not support 'application/json'
        FIRE.downloadBlob(blob, filename);
    }
};
<|endoftext|>


<commit_before>/*
 * Copyright 2019 EPAM Systems
 *
 * 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.
 */

import { PROJECT_MANAGER, OPERATOR, CUSTOMER, MEMBER } from 'common/constants/projectRoles';
import { ALL, OWNER } from 'common/constants/permissions';

export const ACTIONS = {
  EDIT_SETTINGS: 'EDIT_SETTINGS',
  ACTIONS_WITH_MEMBERS: 'ACTIONS_WITH_MEMBERS',
  VIEW_INFO_ABOUT_MEMBERS: 'VIEW_INFO_ABOUT_MEMBERS',
  REPORT_LAUNCH: 'REPORT_LAUNCH',
  VIEW_LAUNCH_IN_DEBUG_MODE: 'VIEW_LAUNCH_IN_DEBUG_MODE',
  MOVE_LAUNCH_TO_DEBUG_DEFAULT: 'MOVE_LAUNCH_TO_DEBUG_DEFAULT',
  ACTIONS_WITH_LAUNCH: 'ACTIONS_WITH_LAUNCH',
  MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT: 'MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT',
  ACTIONS_WITH_ITEM: 'ACTIONS_WITH_ITEM',
  INVESTIGATION_ACTIONS: 'INVESTIGATION_ACTIONS',
  CREATE_SHARE_ITEM: 'CREATE_SHARE_ITEM',
  EDIT_DELETE_SHARED_ITEM: 'EDIT_DELETE_SHARED_ITEM',
  DELETE_SHARED_ITEM: 'DELETE_SHARED_ITEM',
  RERUN_LAUNCHES: 'RERUN_LAUNCHES',
  CHANGE_STATUS: 'CHANGE_STATUS',
};

export const PERMISSIONS_MAP = {
  [PROJECT_MANAGER]: {
    [ACTIONS.EDIT_SETTINGS]: OWNER,
    [ACTIONS.ACTIONS_WITH_MEMBERS]: OWNER,
    [ACTIONS.VIEW_INFO_ABOUT_MEMBERS]: OWNER,
    [ACTIONS.REPORT_LAUNCH]: OWNER,
    [ACTIONS.VIEW_LAUNCH_IN_DEBUG_MODE]: ALL,
    [ACTIONS.MOVE_LAUNCH_TO_DEBUG_DEFAULT]: ALL,
    [ACTIONS.ACTIONS_WITH_LAUNCH]: ALL,
    [ACTIONS.MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT]: ALL,
    [ACTIONS.ACTIONS_WITH_ITEM]: ALL,
    [ACTIONS.INVESTIGATION_ACTIONS]: ALL,
    [ACTIONS.CREATE_SHARE_ITEM]: OWNER,
    [ACTIONS.EDIT_DELETE_SHARED_ITEM]: ALL,
    [ACTIONS.RERUN_LAUNCHES]: ALL,
    [ACTIONS.CHANGE_STATUS]: ALL,
  },
  [MEMBER]: {
    [ACTIONS.VIEW_INFO_ABOUT_MEMBERS]: OWNER,
    [ACTIONS.REPORT_LAUNCH]: OWNER,
    [ACTIONS.VIEW_LAUNCH_IN_DEBUG_MODE]: ALL,
    [ACTIONS.MOVE_LAUNCH_TO_DEBUG_DEFAULT]: OWNER,
    [ACTIONS.ACTIONS_WITH_LAUNCH]: OWNER,
    [ACTIONS.MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT]: ALL,
    [ACTIONS.ACTIONS_WITH_ITEM]: OWNER,
    [ACTIONS.INVESTIGATION_ACTIONS]: ALL,
    [ACTIONS.CREATE_SHARE_ITEM]: OWNER,
    [ACTIONS.EDIT_DELETE_SHARED_ITEM]: OWNER,
    [ACTIONS.RERUN_LAUNCHES]: OWNER,
    [ACTIONS.CHANGE_STATUS]: ALL,
  },
  [OPERATOR]: {
    [ACTIONS.VIEW_INFO_ABOUT_MEMBERS]: OWNER,
    [ACTIONS.VIEW_LAUNCH_IN_DEBUG_MODE]: ALL,
    [ACTIONS.MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT]: ALL,
    [ACTIONS.INVESTIGATION_ACTIONS]: ALL,
    [ACTIONS.CREATE_SHARE_ITEM]: OWNER,
    [ACTIONS.EDIT_DELETE_SHARED_ITEM]: OWNER,
    [ACTIONS.RERUN_LAUNCHES]: OWNER,
    [ACTIONS.CHANGE_STATUS]: ALL,
  },
  [CUSTOMER]: {
    [ACTIONS.REPORT_LAUNCH]: OWNER,
    [ACTIONS.ACTIONS_WITH_LAUNCH]: OWNER,
    [ACTIONS.MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT]: ALL,
    [ACTIONS.ACTIONS_WITH_ITEM]: OWNER,
    [ACTIONS.INVESTIGATION_ACTIONS]: ALL,
    [ACTIONS.CREATE_SHARE_ITEM]: OWNER,
    [ACTIONS.EDIT_DELETE_SHARED_ITEM]: OWNER,
    [ACTIONS.RERUN_LAUNCHES]: OWNER,
    [ACTIONS.CHANGE_STATUS]: ALL,
  },
};
<commit_msg>EPMRPP-43371: Fix operator permissions in permission map<commit_after>/*
 * Copyright 2019 EPAM Systems
 *
 * 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.
 */

import { PROJECT_MANAGER, OPERATOR, CUSTOMER, MEMBER } from 'common/constants/projectRoles';
import { ALL, OWNER } from 'common/constants/permissions';

export const ACTIONS = {
  EDIT_SETTINGS: 'EDIT_SETTINGS',
  ACTIONS_WITH_MEMBERS: 'ACTIONS_WITH_MEMBERS',
  VIEW_INFO_ABOUT_MEMBERS: 'VIEW_INFO_ABOUT_MEMBERS',
  REPORT_LAUNCH: 'REPORT_LAUNCH',
  VIEW_LAUNCH_IN_DEBUG_MODE: 'VIEW_LAUNCH_IN_DEBUG_MODE',
  MOVE_LAUNCH_TO_DEBUG_DEFAULT: 'MOVE_LAUNCH_TO_DEBUG_DEFAULT',
  ACTIONS_WITH_LAUNCH: 'ACTIONS_WITH_LAUNCH',
  MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT: 'MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT',
  ACTIONS_WITH_ITEM: 'ACTIONS_WITH_ITEM',
  INVESTIGATION_ACTIONS: 'INVESTIGATION_ACTIONS',
  CREATE_SHARE_ITEM: 'CREATE_SHARE_ITEM',
  EDIT_DELETE_SHARED_ITEM: 'EDIT_DELETE_SHARED_ITEM',
  DELETE_SHARED_ITEM: 'DELETE_SHARED_ITEM',
  RERUN_LAUNCHES: 'RERUN_LAUNCHES',
  CHANGE_STATUS: 'CHANGE_STATUS',
};

export const PERMISSIONS_MAP = {
  [PROJECT_MANAGER]: {
    [ACTIONS.EDIT_SETTINGS]: OWNER,
    [ACTIONS.ACTIONS_WITH_MEMBERS]: OWNER,
    [ACTIONS.VIEW_INFO_ABOUT_MEMBERS]: OWNER,
    [ACTIONS.REPORT_LAUNCH]: OWNER,
    [ACTIONS.VIEW_LAUNCH_IN_DEBUG_MODE]: ALL,
    [ACTIONS.MOVE_LAUNCH_TO_DEBUG_DEFAULT]: ALL,
    [ACTIONS.ACTIONS_WITH_LAUNCH]: ALL,
    [ACTIONS.MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT]: ALL,
    [ACTIONS.ACTIONS_WITH_ITEM]: ALL,
    [ACTIONS.INVESTIGATION_ACTIONS]: ALL,
    [ACTIONS.CREATE_SHARE_ITEM]: OWNER,
    [ACTIONS.EDIT_DELETE_SHARED_ITEM]: ALL,
    [ACTIONS.RERUN_LAUNCHES]: ALL,
    [ACTIONS.CHANGE_STATUS]: ALL,
  },
  [MEMBER]: {
    [ACTIONS.VIEW_INFO_ABOUT_MEMBERS]: OWNER,
    [ACTIONS.REPORT_LAUNCH]: OWNER,
    [ACTIONS.VIEW_LAUNCH_IN_DEBUG_MODE]: ALL,
    [ACTIONS.MOVE_LAUNCH_TO_DEBUG_DEFAULT]: OWNER,
    [ACTIONS.ACTIONS_WITH_LAUNCH]: OWNER,
    [ACTIONS.MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT]: ALL,
    [ACTIONS.ACTIONS_WITH_ITEM]: OWNER,
    [ACTIONS.INVESTIGATION_ACTIONS]: ALL,
    [ACTIONS.CREATE_SHARE_ITEM]: OWNER,
    [ACTIONS.EDIT_DELETE_SHARED_ITEM]: OWNER,
    [ACTIONS.RERUN_LAUNCHES]: OWNER,
    [ACTIONS.CHANGE_STATUS]: ALL,
  },
  [OPERATOR]: {
    [ACTIONS.VIEW_INFO_ABOUT_MEMBERS]: OWNER,
    [ACTIONS.VIEW_LAUNCH_IN_DEBUG_MODE]: ALL,
    [ACTIONS.MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT]: ALL,
    [ACTIONS.INVESTIGATION_ACTIONS]: ALL,
    [ACTIONS.CREATE_SHARE_ITEM]: OWNER,
    [ACTIONS.EDIT_DELETE_SHARED_ITEM]: OWNER,
    [ACTIONS.CHANGE_STATUS]: ALL,
  },
  [CUSTOMER]: {
    [ACTIONS.REPORT_LAUNCH]: OWNER,
    [ACTIONS.ACTIONS_WITH_LAUNCH]: OWNER,
    [ACTIONS.MANUAL_ANALYSIS_EXPORT_COMPARE_IMPORT]: ALL,
    [ACTIONS.ACTIONS_WITH_ITEM]: OWNER,
    [ACTIONS.INVESTIGATION_ACTIONS]: ALL,
    [ACTIONS.CREATE_SHARE_ITEM]: OWNER,
    [ACTIONS.EDIT_DELETE_SHARED_ITEM]: OWNER,
    [ACTIONS.RERUN_LAUNCHES]: OWNER,
    [ACTIONS.CHANGE_STATUS]: ALL,
  },
};
<|endoftext|>


<commit_before>var gala = (function() {
  var LEFT_BTN = '';
  var RIGHT_BTN = '';
  var FIGURE = '

';
  var CAPTION = '

';

  var addButtons = function($gala, $images) {
    var height = getRenderHeight($images) + 'px';

    moveImages($images, 0); // First transition is ignored w/o this
    $gala.before(LEFT_BTN).prev().css('line-height', height).click(getOnNavLeft($gala, $images));
    $gala.after(RIGHT_BTN).next().css('line-height', height).click(getOnNavRight($gala, $images));

    updateButtonState($gala, 0, $images.length);
  };

  var addCaption = function($gala, $images) {
    $gala.wrap(FIGURE).after(CAPTION);
    updateCaptionText($gala, $images, 0);
  };

  var addKeyboardNav = function($gala, $images) {
    if ($('.gala').length != 1) {
      return; // Keyboard navigation only works if there is only one gala
    }

    $(document).keydown(function(e) {
      switch (e.which) {
        case 37: // left
          (getOnNavLeft($gala, $images))();
          break;
        case 39: // right
          (getOnNavRight($gala, $images))();
          break;
        default:
          return;
      }
      e.preventDefault();
    });
  };

  var create = function(gala) {
    var $gala = $(gala);
    var $images = $gala.children('img');

    $gala.height(getRenderHeight($images)).width(getRenderWidth($images));

    addCaption($gala, $images);
    if ($images.length > 1) {
      addButtons($gala, $images);
      addKeyboardNav($gala, $images);
    }
  };

  var getImageOffset = function($images) {
    return parseInt($images.first().css('left'), 10);
  };

  var getOnNavLeft = function($gala, $images) {
    return function() {
      var width = getRenderWidth($images);
      var offset = getImageOffset($images);
      var totalImages = $images.length;
      if (offset % width != 0 || totalImages <= 1 || offset >= 0) {
        return;
      }
      moveImages($images, offset+width);
      var currentImage = -offset/width-1;
      updateButtonState($gala, currentImage, totalImages);
      updateCaptionText($gala, $images, currentImage);
    };
  };

  var getOnNavRight = function($gala, $images) {
    return function() {
      var width = getRenderWidth($images);
      var offset = getImageOffset($images);
      var totalImages = $images.length;
      if (offset % width != 0 || totalImages <= 1 || offset <= -(width * (totalImages-1))) {
        return;
      }
      moveImages($images, offset-width);
      var currentImage = 1-offset/width;
      updateButtonState($gala, currentImage, totalImages);
      updateCaptionText($gala, $images, currentImage);
    };
  };

  var getRenderHeight = function($images) {
    return $images.first().prop('naturalHeight');
  }

  var getRenderWidth = function($images) {
    return $images.first().prop('naturalWidth');
  }

  var moveImages = function($images, position) {
    $images.css('left', position+'px');
  };

  var updateButtonState = function($gala, currentImage, totalImages) {
    if (currentImage <= 0) {
      $gala.prev().addClass('gala-disabled');
    } else {
      $gala.prev().removeClass('gala-disabled');
    }

    if (currentImage >= totalImages-1) {
      $gala.next().addClass('gala-disabled');
    } else {
      $gala.next().removeClass('gala-disabled');
    }
  };

  var updateCaptionText = function($gala, $images, currentImage) {
    var $caption = $gala.siblings('figcaption');
    $caption.fadeOut(200, function() {
      $caption.text($images[currentImage].getAttribute('alt')).fadeIn(200);
    });
  };

  return {
    initialize: function() {
      $('.gala').each(function(index, gala) {
        create(gala);
      });
    }
  }
})();

$(document).ready(gala.initialize);
<commit_msg>Separate sizing the gala from registering events<commit_after>var gala = (function() {
  var LEFT_BTN = '';
  var RIGHT_BTN = '';
  var FIGURE = '

';
  var CAPTION = '

';

  var addButtons = function($gala, $images) {
    moveImages($images, 0); // First transition is ignored w/o this

    $gala.before(LEFT_BTN).prev().click(getOnNavLeft($gala, $images));
    $gala.after(RIGHT_BTN).next().click(getOnNavRight($gala, $images));

    updateButtonState($gala, 0, $images.length);
  };

  var addCaption = function($gala, $images) {
    $gala.wrap(FIGURE).after(CAPTION);
    updateCaptionText($gala, $images, 0);
  };

  var addKeyboardNav = function($gala, $images) {
    if ($('.gala').length != 1) {
      return; // Keyboard navigation works if there is only one gala
    }

    $(document).keydown(function(e) {
      switch (e.which) {
        case 37: // left
          (getOnNavLeft($gala, $images))();
          break;
        case 39: // right
          (getOnNavRight($gala, $images))();
          break;
        default:
          return;
      }
      e.preventDefault();
    });
  };

  var create = function(gala) {
    var $gala = $(gala);
    var $images = $gala.children('img');

    addCaption($gala, $images);
    if ($images.length > 1) {
      addButtons($gala, $images);
      addKeyboardNav($gala, $images);
    }

    resize($gala, $images);
  };

  var getImageOffset = function($images) {
    return parseInt($images.first().css('left'), 10);
  };

  var getOnNavLeft = function($gala, $images) {
    return function() {
      var width = getRenderWidth($images);
      var offset = getImageOffset($images);
      var totalImages = $images.length;
      if (offset % width != 0 || totalImages <= 1 || offset >= 0) {
        return;
      }
      moveImages($images, offset+width);
      var currentImage = -offset/width-1;
      updateButtonState($gala, currentImage, totalImages);
      updateCaptionText($gala, $images, currentImage);
    };
  };

  var getOnNavRight = function($gala, $images) {
    return function() {
      var width = getRenderWidth($images);
      var offset = getImageOffset($images);
      var totalImages = $images.length;
      if (offset % width != 0 || totalImages <= 1 || offset <= -(width * (totalImages-1))) {
        return;
      }
      moveImages($images, offset-width);
      var currentImage = 1-offset/width;
      updateButtonState($gala, currentImage, totalImages);
      updateCaptionText($gala, $images, currentImage);
    };
  };

  var getRenderHeight = function($images) {
    return $images.first().prop('naturalHeight');
  };

  var getRenderWidth = function($images) {
    return $images.first().prop('naturalWidth');
  };

  var moveImages = function($images, position) {
    $images.css('left', position+'px');
  };

  var resize = function($gala, $images) {
    var height = getRenderHeight($images);
    $gala.height(height).width(getRenderWidth($images));

    $gala.prev().css('line-height', height+'px');
    $gala.next().css('line-height', height+'px');
  };

  var updateButtonState = function($gala, currentImage, totalImages) {
    if (currentImage <= 0) {
      $gala.prev().addClass('gala-disabled');
    } else {
      $gala.prev().removeClass('gala-disabled');
    }

    if (currentImage >= totalImages-1) {
      $gala.next().addClass('gala-disabled');
    } else {
      $gala.next().removeClass('gala-disabled');
    }
  };

  var updateCaptionText = function($gala, $images, currentImage) {
    var $caption = $gala.siblings('figcaption');
    $caption.fadeOut(200, function() {
      $caption.text($images[currentImage].getAttribute('alt')).fadeIn(200);
    });
  };

  return {
    initialize: function() {
      $('.gala').each(function(index, gala) {
        create(gala);
      });
    }
  }
})();

$(document).ready(gala.initialize);
<|endoftext|>


<commit_before>/**
 *  nodeca.loader
 *
 *  This module provides namespace assets loading for nodeca/nlib based
 *  applcations.
 **/

//= depend_on nodeca
//= require minimizer

/*global window, $, _, Modernizr, yepnope, nodeca*/

(function () {
  'use strict';

  // list of already loaded assets
  // TODO: cache loaded assets in the LocalStorage
  var loaded = [];

  // Builds RegExp used to find assets for given namespace
  function build_namespace_regexp(namespace) {
    var locale  = nodeca.runtime.locale,
        theme   = nodeca.runtime.theme,
        parts   = [];

    // common-wide
    parts.push('views/' + locale + '/' + theme + '/layouts.js');
    parts.push('views/' + locale + '/' + theme + '/common.js');
    parts.push('common/i18n/' + locale + '.js');
    parts.push('common/app.(?:js|css)');
    parts.push('app.(?:js|css)');

    // namespace-specific
    parts.push('views/' + locale + '/' + theme + '/' + namespace + '.js');
    parts.push(namespace + '/i18n/' + locale + '.js');
    parts.push(namespace + 'app.(?:js|css)');

    return new RegExp('^(?:' + parts.join('|') + ')$');
  }

  // Returns list of assets that should be loaded by yepnope
  function find_assets(namespace) {
    var assets = [],
        regexp = build_namespace_regexp(namespace);

    _.each(nodeca.config.assets, function (digestPath, logicalPath) {
      if (-1 < loaded.indexOf(digestPath) && regexp.test(logicalPath)) {
        assets.push(nodeca.runtime.ASSETS_BASEURL + digestPath);
      }
    });

    return assets;
  }

  // loader that requries assets for given namespace
  nodeca.load = function load(namespace, callback) {
    var assets = find_assets(namespace);

    // TODO: load assets from localStorage if some were found.
    //       LocalStorage should be something like:
    //       { <logicalPath>: [<digestPath>, <timestamp>, <data>] }

    yepnope({load: assets, complete: function () {
      loaded = loaded.concat(assets);
      callback();
    }});
  };
}());
<commit_msg>Fix requires of nodeca.loader<commit_after>/**
 *  nodeca.loader
 *
 *  This module provides namespace assets loading for nodeca/nlib based
 *  applcations.
 **/

//= depend_on nodeca
//= require modernizr

/*global window, $, _, Modernizr, yepnope, nodeca*/

(function () {
  'use strict';

  // list of already loaded assets
  // TODO: cache loaded assets in the LocalStorage
  var loaded = [];

  // Builds RegExp used to find assets for given namespace
  function build_namespace_regexp(namespace) {
    var locale  = nodeca.runtime.locale,
        theme   = nodeca.runtime.theme,
        parts   = [];

    // common-wide
    parts.push('views/' + locale + '/' + theme + '/layouts.js');
    parts.push('views/' + locale + '/' + theme + '/common.js');
    parts.push('common/i18n/' + locale + '.js');
    parts.push('common/app.(?:js|css)');
    parts.push('app.(?:js|css)');

    // namespace-specific
    parts.push('views/' + locale + '/' + theme + '/' + namespace + '.js');
    parts.push(namespace + '/i18n/' + locale + '.js');
    parts.push(namespace + 'app.(?:js|css)');

    return new RegExp('^(?:' + parts.join('|') + ')$');
  }

  // Returns list of assets that should be loaded by yepnope
  function find_assets(namespace) {
    var assets = [],
        regexp = build_namespace_regexp(namespace);

    _.each(nodeca.config.assets, function (digestPath, logicalPath) {
      if (-1 < loaded.indexOf(digestPath) && regexp.test(logicalPath)) {
        assets.push(nodeca.runtime.ASSETS_BASEURL + digestPath);
      }
    });

    return assets;
  }

  // loader that requries assets for given namespace
  nodeca.load = function load(namespace, callback) {
    var assets = find_assets(namespace);

    // TODO: load assets from localStorage if some were found.
    //       LocalStorage should be something like:
    //       { <logicalPath>: [<digestPath>, <timestamp>, <data>] }

    yepnope({load: assets, complete: function () {
      loaded = loaded.concat(assets);
      callback();
    }});
  };
}());
<|endoftext|>


<commit_before>/**
 * Melodycoder botobe.net
 * 网站上线自动打包部署脚本，包括压缩合并css等等。
 * Version:2.0
 *
 * Copyright (c) 2013 Kai.XU
 * Licensed under the MIT license.
 */

// 包依赖，基础包
var fs = require('fs'), async = require('async'), path = require('path'), util = require('util');

// 进行css和js压缩的包
var uglifyJS = require('uglify-js'), cleanCSS = require('clean-css');

// 对数组的修改
Array.prototype.add = function(element) {
  this.push(element);
  return this;
};

// 检测静态文件的目录结构是否完整，以及生成对应的目录结构
var isFilesReady = true;
var filesPath = ['./public', './public/dist', './public/dist/deploy.log', './public/css', './public/css/ugc', './public/js'];
filesPath.forEach(function(filePath, range) {
  var absolutePath = path.resolve(filePath);

  filesPath[range] = absolutePath;
  if (!fs.existsSync(absolutePath))
    isFilesReady = false;
});

if (!isFilesReady) {
  console.error('文件结构不正确！');
  process.exit();
}

try {
  // 生成对应的目录结构
  var tpVersions = fs.readdirSync(filesPath[1]), versions = [];
  tpVersions.forEach(function(version, range) {
    var versionNumber = parseInt(version.slice(1), 10);
    if (!isNaN(versionNumber)) {
      versions.push(versionNumber);
    }
  });
  var newVersion = Math.max.apply(this, versions) + 1;
  var disPath = filesPath[1] + '/v' + newVersion;
  filesPath.add(disPath).add(disPath + '/css').add(disPath + '/js').add(disPath + '/css/ugc');
  filesPath.forEach(function(filePath) {
    if (!fs.existsSync(filePath))
      fs.mkdirSync(filePath);
  });

  // 合并css文件成home.css，除了ugc目录，单独至于版本文件夹下
  // 获取出所有的css文件
  var cssFolder = filesPath[3];
  var cssFiles = [];
  (function(folder) {
    var contentList = fs.readdirSync(folder);

    var argu = arguments;
    contentList.forEach(function(name) {
      if (name == 'ugc')
        return;

      var oriName = folder + '/' + name;
      if (fs.statSync(oriName).isDirectory()) {
        argu.callee(oriName);
      } else {
        var tpName = oriName.split('.');
        if (tpName[tpName.length - 1] == 'css')
          cssFiles.push(oriName);
      }
    });
  })(cssFolder);

  // 归并css文件
  var executeCSS = function(targetFile, sourceFile) {
    var cssContent = fs.readFileSync(sourceFile);
    cssContent = cleanCSS.process(cssContent.toString(), {
      keepBreaks : true
    });
    fs.appendFileSync(targetFile, cssContent);
  };
  cssFiles.forEach(function(cssFile) {
    executeCSS(filesPath[7] + '/home.css', cssFile);
  });
  fs.readdirSync(filesPath[3] + '/ugc').forEach(function(ugcCssFile) {
    executeCSS(filesPath[9] + '/' + ugcCssFile, filesPath[4] + '/' + ugcCssFile);
  });

  // 处理js文件，这块暂先不处理
  var jsFiles = [], relaJsFiles = [];
  var getJsFiles = function(absoPath, relaPath) {
    var contentList = fs.readdirSync(absoPath);
    contentList.forEach(function(content) {
      var name = absoPath + '/' + content, relaName = relaPath + '/' + content;
      var isDir = fs.statSync(name).isDirectory();
      if (isDir) {
        fs.mkdirSync(disPath + relaName);
        getJsFiles(name, relaName);
      } else {
        if (name.substr(-2) == 'js') {

          // 压缩两份地址，一份是相对的，一份是绝对的
          jsFiles.push(name);
          relaJsFiles.push(relaName);
        }
      }
    });
  };
  getJsFiles(filesPath[5], '/js');

  jsFiles.forEach(function(jsFile, range) {
    var absolutePath = jsFile, relativePath = relaJsFiles[range];

    var content = uglifyJS.minify(absolutePath, {
      mangle : false,
      warnings : true
    });

    // var content = fs.readFileSync(absolutePath);
    fs.writeFileSync(disPath + relativePath, content.code);
  });

  // 修改静态文件的版本号
  var configPath = path.resolve('./config.js');
  var configContent = fs.readFileSync(configPath).toString();
  var versionRegix = /\/v\d{1,}/;
  configContent = configContent.replace(versionRegix, '/v' + newVersion);
  fs.writeFileSync(configPath, configContent);
} catch(e) {
  console.error(e.message);
  process.exit();
}
console.log('部署成功！'); <commit_msg>Beacaus do not use sea.js so, it can mangle variables now.<commit_after>/**
 * Melodycoder botobe.net
 * 网站上线自动打包部署脚本，包括压缩合并css等等。
 * Version:2.0
 *
 * Copyright (c) 2013 Kai.XU
 * Licensed under the MIT license.
 */

// 包依赖，基础包
var fs = require('fs'), async = require('async'), path = require('path'), util = require('util');

// 进行css和js压缩的包
var uglifyJS = require('uglify-js'), cleanCSS = require('clean-css');

// 对数组的修改
Array.prototype.add = function(element) {
  this.push(element);
  return this;
};

// 检测静态文件的目录结构是否完整，以及生成对应的目录结构
var isFilesReady = true;
var filesPath = ['./public', './public/dist', './public/dist/deploy.log', './public/css', './public/css/ugc', './public/js'];
filesPath.forEach(function(filePath, range) {
  var absolutePath = path.resolve(filePath);

  filesPath[range] = absolutePath;
  if (!fs.existsSync(absolutePath))
    isFilesReady = false;
});

if (!isFilesReady) {
  console.error('文件结构不正确！');
  process.exit();
}

try {
  // 生成对应的目录结构
  var tpVersions = fs.readdirSync(filesPath[1]), versions = [];
  tpVersions.forEach(function(version, range) {
    var versionNumber = parseInt(version.slice(1), 10);
    if (!isNaN(versionNumber)) {
      versions.push(versionNumber);
    }
  });
  var newVersion = Math.max.apply(this, versions) + 1;
  var disPath = filesPath[1] + '/v' + newVersion;
  filesPath.add(disPath).add(disPath + '/css').add(disPath + '/js').add(disPath + '/css/ugc');
  filesPath.forEach(function(filePath) {
    if (!fs.existsSync(filePath))
      fs.mkdirSync(filePath);
  });

  // 合并css文件成home.css，除了ugc目录，单独至于版本文件夹下
  // 获取出所有的css文件
  var cssFolder = filesPath[3];
  var cssFiles = [];
  (function(folder) {
    var contentList = fs.readdirSync(folder);

    var argu = arguments;
    contentList.forEach(function(name) {
      if (name == 'ugc')
        return;

      var oriName = folder + '/' + name;
      if (fs.statSync(oriName).isDirectory()) {
        argu.callee(oriName);
      } else {
        var tpName = oriName.split('.');
        if (tpName[tpName.length - 1] == 'css')
          cssFiles.push(oriName);
      }
    });
  })(cssFolder);

  // 归并css文件
  var executeCSS = function(targetFile, sourceFile) {
    var cssContent = fs.readFileSync(sourceFile);
    cssContent = cleanCSS.process(cssContent.toString(), {
      keepBreaks : true
    });
    fs.appendFileSync(targetFile, cssContent);
  };
  cssFiles.forEach(function(cssFile) {
    executeCSS(filesPath[7] + '/home.css', cssFile);
  });
  fs.readdirSync(filesPath[3] + '/ugc').forEach(function(ugcCssFile) {
    executeCSS(filesPath[9] + '/' + ugcCssFile, filesPath[4] + '/' + ugcCssFile);
  });

  // 处理js文件，这块暂先不处理
  var jsFiles = [], relaJsFiles = [];
  var getJsFiles = function(absoPath, relaPath) {
    var contentList = fs.readdirSync(absoPath);
    contentList.forEach(function(content) {
      var name = absoPath + '/' + content, relaName = relaPath + '/' + content;
      var isDir = fs.statSync(name).isDirectory();
      if (isDir) {
        fs.mkdirSync(disPath + relaName);
        getJsFiles(name, relaName);
      } else {
        if (name.substr(-2) == 'js') {

          // 压缩两份地址，一份是相对的，一份是绝对的
          jsFiles.push(name);
          relaJsFiles.push(relaName);
        }
      }
    });
  };
  getJsFiles(filesPath[5], '/js');

  jsFiles.forEach(function(jsFile, range) {
    var absolutePath = jsFile, relativePath = relaJsFiles[range];

    var content = uglifyJS.minify(absolutePath, {
      mangle : true,
      warnings : true
    });

    // var content = fs.readFileSync(absolutePath);
    fs.writeFileSync(disPath + relativePath, content.code);
  });

  // 修改静态文件的版本号
  var configPath = path.resolve('./config.js');
  var configContent = fs.readFileSync(configPath).toString();
  var versionRegix = /\/v\d{1,}/;
  configContent = configContent.replace(versionRegix, '/v' + newVersion);
  fs.writeFileSync(configPath, configContent);
} catch(e) {
  console.error(e.message);
  process.exit();
}
console.log('部署成功！'); <|endoftext|>


<commit_before>// @flow
import * as Constants from '../constants/searchv3'
import {globalColors} from '../styles'

const followingStateToStyle = (followingState: Constants.FollowingState) => {
  return {
    Following: {
      color: globalColors.green2,
    },
    NoState: {
      color: globalColors.black_40,
    },
    NotFollowing: {
      color: globalColors.blue,
    },
    You: {
      fontStyle: 'italic',
      color: globalColors.black,
    },
  }[followingState]
}

export {followingStateToStyle}
<commit_msg>Fix blacks in following style<commit_after>// @flow
import * as Constants from '../constants/searchv3'
import {globalColors} from '../styles'

const followingStateToStyle = (followingState: Constants.FollowingState) => {
  return {
    Following: {
      color: globalColors.green2,
    },
    NoState: {
      color: globalColors.black_75,
    },
    NotFollowing: {
      color: globalColors.blue,
    },
    You: {
      fontStyle: 'italic',
      color: globalColors.black_75,
    },
  }[followingState]
}

export {followingStateToStyle}
<|endoftext|>