<commit_before>var inherits = require('util').inherits
  , EventEmitter = require('events').EventEmitter
  , Connection = require('./connection')
  , Query = require('./commands').Query
  , Logger = require('./logger')
  , f = require('util').format;

var DISCONNECTED = 'disconnected';
var CONNECTING = 'connecting';
var CONNECTED = 'connected';
var DESTROYED = 'destroyed';

var _id = 0;

/**
 * Creates a new Pool instance
 * @class
 * @param {string} options.host The server host
 * @param {number} options.port The server port
 * @param {number} [options.size=5] Server connection pool size
 * @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
 * @param {number} [options.keepAliveInitialDelay=0] Initial delay before TCP keep alive enabled
 * @param {boolean} [options.noDelay=true] TCP Connection no delay
 * @param {number} [options.connectionTimeout=0] TCP Connection timeout setting
 * @param {number} [options.socketTimeout=0] TCP Socket timeout setting
 * @param {boolean} [options.singleBufferSerializtion=true] Serialize into single buffer, trade of peak memory for serialization speed
 * @param {boolean} [options.ssl=false] Use SSL for connection
 * @param {Buffer} [options.ca] SSL Certificate store binary buffer
 * @param {Buffer} [options.cert] SSL Certificate binary buffer
 * @param {Buffer} [options.key] SSL Key file binary buffer
 * @param {string} [options.passPhrase] SSL Certificate pass phrase
 * @param {boolean} [options.rejectUnauthorized=false] Reject unauthorized server certificates
 * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits
 * @fires Pool#connect
 * @fires Pool#close
 * @fires Pool#error
 * @fires Pool#timeout
 * @fires Pool#parseError
 * @return {Pool} A cursor instance
 */
var Pool = function(options) {
  // Add event listener
  EventEmitter.call(this);
  // Set empty if no options passed
  options = options || {};
  var size = typeof options.size == 'number' ? options.size : 5;
  var logger = options.logger
    ? options.logger.create("Pool") : null;
  var self = this;
  // Message handler
  var messageHandler = options.messageHandler;
  // No bson parser passed in
  if(!options.bson) throw new Error("must pass in valid bson parser");
  // Contains all connections
  var connections = [];
  var closedConnections = [];
  var state = DISCONNECTED;
  // Round robin index
  var index = 0;
  var dead = false;
  // Logger instance
  var logger = Logger('Pool', options);
  // Pool id
  var id = _id++;
  // Grouping tag used for debugging purposes
  var tag = options.tag;

  // //
  // // Handlers
  // var messageHandler = function(response, connection) {
  //   self.emit("message", response, connection)
  // }

  var errorHandler = function(err, connection) {
    if(logger.isDebug()) logger.debug(f('pool [%s] errored out [%s] with connection [%s]', dead, JSON.stringify(err), JSON.stringify(connection)));
    if(!dead) {
      state = DISCONNECTED;
      dead = true;
      self.destroy();
      self.emit('error', err, self);
    }
  }

  var timeoutHandler = function(err, connection) {
    if(logger.isDebug()) logger.debug(f('pool [%s] timedout out [%s] with connection [%s]', dead, JSON.stringify(err), JSON.stringify(connection)));
    if(!dead) {
      state = DISCONNECTED;
      dead = true;
      self.destroy();
      self.emit('timeout', err, self);
    }
  }

  var closeHandler = function(err, connection) {
    if(logger.isDebug()) logger.debug(f('pool [%s] closed [%s] with connection [%s]', dead, JSON.stringify(err), JSON.stringify(connection)));
    if(!dead) {
      state = DISCONNECTED;
      dead = true;
      self.destroy();
      self.emit('close', err, self);
    }
  }

  var parseErrorHandler = function(err, connection) {
    if(logger.isDebug()) logger.debug(f('pool [%s] errored out [%s] with connection [%s]', dead, JSON.stringify(err), JSON.stringify(connection)));
    if(!dead) {
      state = DISCONNECTED;
      dead = true;
      self.destroy();
      self.emit('parseError', err, self);
    }
  }

  var connectHandler = function(connection) {
    connections.push(connection);
    // We have connected to all servers
    if(connections.length == size) {
      state = DISCONNECTED;
      state = CONNECTED;
      // Done connecting
      self.emit("connect", self);
    }
  }

  /**
   * Destroy pool
   * @method
   */
  this.destroy = function() {
    state = DESTROYED;
    // Set dead
    dead = true;
    // Destroy all the connections
    connections.forEach(function(c) {
      // Destroy all event emitters
      ["close", "message", "error", "timeout", "parseError", "connect"].forEach(function(e) {
        c.removeAllListeners(e);
      });

      // Destroy the connection
      c.destroy();
    });
  }

  /**
   * Connect pool
   * @method
   */
  this.connect = function(_options) {
    // Set to connecting
    state = CONNECTING
    // No dead
    dead = false;
    // Connect all sockets
    for(var i = 0; i < size; i++) {
      options.messageHandler = messageHandler;
      var connection = new Connection(options);

      // Add all handlers
      connection.once('close', closeHandler);
      // connection.on('message', messageHandler);
      connection.once('error', errorHandler);
      connection.once('timeout', timeoutHandler);
      connection.once('parseError', parseErrorHandler);
      connection.on('connect', connectHandler);

      // Start connection
      connection.connect(_options);
    }
  }

  /**
   * Get a pool connection (round-robin)
   * @method
   * @return {Connection}
   */
  this.get = function() {
    var connection = connections[index++];
    index = index % connections.length;
    return connection;
  }

  /**
   * Get all pool connections
   * @method
   * @return {array}
   */
  this.getAll = function() {
    return connections.slice(0);
  }

  /**
   * Is the pool connected
   * @method
   * @return {boolean}
   */
  this.isConnected = function() {
    for(var i = 0; i < connections.length; i++) {
      if(!connections[i].isConnected()) return false;
    }

    return state == CONNECTED;
  }

  /**
   * Was the pool destroyed
   * @method
   * @return {boolean}
   */
  this.isDestroyed = function() {
    return state == DESTROYED;
  }
}

inherits(Pool, EventEmitter);

/**
 * A server connect event, used to verify that the connection is up and running
 *
 * @event Pool#connect
 * @type {Pool}
 */

/**
 * The server connection closed, all pool connections closed
 *
 * @event Pool#close
 * @type {Pool}
 */

/**
 * The server connection caused an error, all pool connections closed
 *
 * @event Pool#error
 * @type {Pool}
 */

/**
 * The server connection timed out, all pool connections closed
 *
 * @event Pool#timeout
 * @type {Pool}
 */

/**
 * The driver experienced an invalid message, all pool connections closed
 *
 * @event Pool#parseError
 * @type {Pool}
 */

module.exports = Pool;<commit_msg>refactored pool to use prototype<commit_after>var inherits = require('util').inherits
  , EventEmitter = require('events').EventEmitter
  , Connection = require('./connection')
  , Query = require('./commands').Query
  , Logger = require('./logger')
  , f = require('util').format;

var DISCONNECTED = 'disconnected';
var CONNECTING = 'connecting';
var CONNECTED = 'connected';
var DESTROYED = 'destroyed';

var _id = 0;

/**
 * Creates a new Pool instance
 * @class
 * @param {string} options.host The server host
 * @param {number} options.port The server port
 * @param {number} [options.size=5] Server connection pool size
 * @param {boolean} [options.keepAlive=true] TCP Connection keep alive enabled
 * @param {number} [options.keepAliveInitialDelay=0] Initial delay before TCP keep alive enabled
 * @param {boolean} [options.noDelay=true] TCP Connection no delay
 * @param {number} [options.connectionTimeout=0] TCP Connection timeout setting
 * @param {number} [options.socketTimeout=0] TCP Socket timeout setting
 * @param {boolean} [options.singleBufferSerializtion=true] Serialize into single buffer, trade of peak memory for serialization speed
 * @param {boolean} [options.ssl=false] Use SSL for connection
 * @param {Buffer} [options.ca] SSL Certificate store binary buffer
 * @param {Buffer} [options.cert] SSL Certificate binary buffer
 * @param {Buffer} [options.key] SSL Key file binary buffer
 * @param {string} [options.passPhrase] SSL Certificate pass phrase
 * @param {boolean} [options.rejectUnauthorized=false] Reject unauthorized server certificates
 * @param {boolean} [options.promoteLongs=true] Convert Long values from the db into Numbers if they fit into 53 bits
 * @fires Pool#connect
 * @fires Pool#close
 * @fires Pool#error
 * @fires Pool#timeout
 * @fires Pool#parseError
 * @return {Pool} A cursor instance
 */
var Pool = function(options) {
  var self = this;
  // Add event listener
  EventEmitter.call(this);
  // Set empty if no options passed
  this.options = options || {};
  this.size = typeof options.size == 'number' ? options.size : 5;
  // Message handler
  this.messageHandler = options.messageHandler;
  // No bson parser passed in
  if(!options.bson) throw new Error("must pass in valid bson parser");
  // Contains all connections
  this.connections = [];
  this.state = DISCONNECTED;
  // Round robin index
  this.index = 0;
  this.dead = false;
  // Logger instance
  this.logger = Logger('Pool', options);
  // Pool id
  this.id = _id++;
  // Grouping tag used for debugging purposes
  this.tag = options.tag;
}

inherits(Pool, EventEmitter);

var errorHandler = function(self) {
  return function(err, connection) {
    if(self.logger.isDebug()) self.logger.debug(f('pool [%s] errored out [%s] with connection [%s]', this.dead, JSON.stringify(err), JSON.stringify(connection)));
    if(!self.dead) {
      self.state = DISCONNECTED;
      self.dead = true;
      self.destroy();
      self.emit('error', err, self);
    }
  }
}

var timeoutHandler = function(self) {
  return function(err, connection) {
    if(self.logger.isDebug()) self.logger.debug(f('pool [%s] timedout out [%s] with connection [%s]', this.dead, JSON.stringify(err), JSON.stringify(connection)));
    if(!self.dead) {
      self.state = DISCONNECTED;
      self.dead = true;
      self.destroy();
      self.emit('timeout', err, self);
    }
  }
}

var closeHandler = function(self) {
  return function(err, connection) {
    if(self.logger.isDebug()) self.logger.debug(f('pool [%s] closed [%s] with connection [%s]', this.dead, JSON.stringify(err), JSON.stringify(connection)));
    if(!self.dead) {
      self.state = DISCONNECTED;
      self.dead = true;
      self.destroy();
      self.emit('close', err, self);
    }
  }
}

var parseErrorHandler = function(self) {
  return function(err, connection) {
    if(self.logger.isDebug()) self.logger.debug(f('pool [%s] errored out [%s] with connection [%s]', this.dead, JSON.stringify(err), JSON.stringify(connection)));
    if(!self.dead) {
      self.state = DISCONNECTED;
      self.dead = true;
      self.destroy();
      self.emit('parseError', err, self);
    }
  }
}

var connectHandler = function(self) {
  return function(connection) {
    self.connections.push(connection);
    // We have connected to all servers
    if(self.connections.length == self.size) {
      self.state = CONNECTED;
      // Done connecting
      self.emit("connect", self);
    }
  }
}

/**
 * Destroy pool
 * @method
 */
Pool.prototype.destroy = function() {
  this.state = DESTROYED;
  // Set dead
  this.dead = true;
  // Destroy all the connections
  this.connections.forEach(function(c) {
    // Destroy all event emitters
    ["close", "message", "error", "timeout", "parseError", "connect"].forEach(function(e) {
      c.removeAllListeners(e);
    });

    // Destroy the connection
    c.destroy();
  });
}

/**
 * Connect pool
 * @method
 */
Pool.prototype.connect = function(_options) {
  // Set to connecting
  this.state = CONNECTING
  // No dead
  this.dead = false;
  // Connect all sockets
  for(var i = 0; i < this.size; i++) {
    this.options.messageHandler = this.messageHandler;
    var connection = new Connection(this.options);

    // Add all handlers
    connection.once('close', closeHandler(this));
    connection.once('error', errorHandler(this));
    connection.once('timeout', timeoutHandler(this));
    connection.once('parseError', parseErrorHandler(this));
    connection.on('connect', connectHandler(this));

    // Start connection
    connection.connect(_options);
  }
}

/**
 * Get a pool connection (round-robin)
 * @method
 * @return {Connection}
 */
Pool.prototype.get = function() {
  var connection = this.connections[this.index++];
  this.index = this.index % this.connections.length;
  return connection;
}

/**
 * Get all pool connections
 * @method
 * @return {array}
 */
Pool.prototype.getAll = function() {
  return this.connections.slice(0);
}

/**
 * Is the pool connected
 * @method
 * @return {boolean}
 */
Pool.prototype.isConnected = function() {
  for(var i = 0; i < this.connections.length; i++) {
    if(!this.connections[i].isConnected()) return false;
  }

  return this.state == CONNECTED;
}

/**
 * Was the pool destroyed
 * @method
 * @return {boolean}
 */
Pool.prototype.isDestroyed = function() {
  return this.state == DESTROYED;
}

/**
 * A server connect event, used to verify that the connection is up and running
 *
 * @event Pool#connect
 * @type {Pool}
 */

/**
 * The server connection closed, all pool connections closed
 *
 * @event Pool#close
 * @type {Pool}
 */

/**
 * The server connection caused an error, all pool connections closed
 *
 * @event Pool#error
 * @type {Pool}
 */

/**
 * The server connection timed out, all pool connections closed
 *
 * @event Pool#timeout
 * @type {Pool}
 */

/**
 * The driver experienced an invalid message, all pool connections closed
 *
 * @event Pool#parseError
 * @type {Pool}
 */

module.exports = Pool;<|endoftext|>


<commit_before>/*
 * includes
 */
var router = require('./router.js')
    , urlModule = require('url')
    , pathModule = require('path')
    , options = require('../default-config.js')
    , displayRoutes = require('./display-routes.js');
;

/**
 * sends the response to the browser
 * @param data  the data to send to the client, wich can be either a file content or an object with this attribute
 * {
 *   "status": {"success": false/true, code: ...http code...}
 *   "data": ...
 * }
 */
function sendResponse (response, status, data, mime_type, responseFilePath) {
    console.log('sendResponse', status);
    if (status && status.success===false){
        var code;
        if (status.code) code = status.code;
        else code = 500;

        console.error("error code ", code, status);
        response.statusCode = code;
        response.send(status);
    }
    // set mime type
    else{
        if (mime_type){

            // mime type
            response.setHeader('Content-Type', mime_type);
        }
        if (data){
            response.send(data);
        }
        else if (responseFilePath){
            response.sendfile(responseFilePath);
        }
        else{
            response.send(status);
        }
    }
}

/*
 * The middleware
 */
exports.middleware = function(express, app, opt_options) {
    // get options
    var options = opt_options || require('../default-config.js');

    // serve static folders
    var staticFolders  = options.staticFolders;
    for(var folder in staticFolders){
        var name = staticFolders[folder].name;
        var path = staticFolders[folder].path;
        if (name){
            console.log(name, path, '> '+pathModule.resolve(__dirname, path));
            app.use(name, express.static(pathModule.resolve(__dirname, path)));
        }
        else{
            console.log(path, '> '+pathModule.resolve(__dirname, path));
            app.use(express.static(pathModule.resolve(__dirname, path)));
        }
    }
    // app init
    app.configure(function() {

        app.use(options.apiRoot, express.bodyParser());

        // start session
        app.use(options.apiRoot, express.cookieParser());
        app.use(options.apiRoot, express.cookieSession({ secret: 'plum plum plum'}));

        // init unifile
        router.init(app, express, options);
        displayRoutes.init(app, express, options);
    });

  return function(req, res, next) {
    console.log('-------------------------------------');
    var url_parts = urlModule.parse(req.url, true);
    var path = url_parts.path;
    // URL decode path
    path = decodeURIComponent(path.replace(/\+/g, ' '));
    // split to be able to manipulate each folder
    var url_arr = path.split('/');
    // remove the first empty '' from the path (first slash)
    url_arr.shift();
    // remove the 'api' path
    url_arr.shift();
    // remove the api version number
    url_arr.shift();
    console.log('User request:', url_arr);
   // get and remove the service name
    var serviceName = url_arr.shift();
    try{
        if (serviceName){
            var routed = router.route(serviceName, url_arr, req, res, next, sendResponse);
            if (!routed){
                console.error('Unknown service '+serviceName);
                next();
            }
        }
        else{
            // happens all the time when looking for the favicon
            //console.error('Unknown service '+serviceName);
            next();
        }
    }
    catch(e){
        console.error('Error loading service '+serviceName+': '+e);
        next();
    }
  };
}

<commit_msg>manage pathes like "/cloud-explorer/api/v1.0/..."<commit_after>/*
 * includes
 */
var router = require('./router.js')
    , urlModule = require('url')
    , pathModule = require('path')
    , options = require('../default-config.js')
    , displayRoutes = require('./display-routes.js');
;

/**
 * sends the response to the browser
 * @param data  the data to send to the client, wich can be either a file content or an object with this attribute
 * {
 *   "status": {"success": false/true, code: ...http code...}
 *   "data": ...
 * }
 */
function sendResponse (response, status, data, mime_type, responseFilePath) {
    console.log('sendResponse', status);
    if (status && status.success===false){
        var code;
        if (status.code) code = status.code;
        else code = 500;

        console.error("error code ", code, status);
        response.statusCode = code;
        response.send(status);
    }
    // set mime type
    else{
        if (mime_type){

            // mime type
            response.setHeader('Content-Type', mime_type);
        }
        if (data){
            response.send(data);
        }
        else if (responseFilePath){
            response.sendfile(responseFilePath);
        }
        else{
            response.send(status);
        }
    }
}

/*
 * The middleware
 */
exports.middleware = function(express, app, opt_options) {
    // get options
    var options = opt_options || require('../default-config.js');

    // serve static folders
    var staticFolders  = options.staticFolders;
    for(var folder in staticFolders){
        var name = staticFolders[folder].name;
        var path = staticFolders[folder].path;
        if (name){
            console.log(name, path, '> '+pathModule.resolve(__dirname, path));
            app.use(name, express.static(pathModule.resolve(__dirname, path)));
        }
        else{
            console.log(path, '> '+pathModule.resolve(__dirname, path));
            app.use(express.static(pathModule.resolve(__dirname, path)));
        }
    }
    // app init
    app.configure(function() {

        app.use(options.apiRoot, express.bodyParser());

        // start session
        app.use(options.apiRoot, express.cookieParser());
        app.use(options.apiRoot, express.cookieSession({ secret: 'plum plum plum'}));

        // init unifile
        router.init(app, express, options);
        displayRoutes.init(app, express, options);
    });

  return function(req, res, next) {
    console.log('-------------------------------------');
    var url_parts = urlModule.parse(req.url, true);
    var path = url_parts.path;
    // URL decode path
    path = decodeURIComponent(path.replace(/\+/g, ' '));
    // remove api root path
    if (path.indexOf(options.apiRoot) > -1) {
        path = path.substr(path.lastIndexOf(options.apiRoot)+options.apiRoot.length);
    }
    // split to be able to manipulate each folder
    var url_arr = path.split('/');
    // remove the first empty '' from the path (first slash)
    url_arr.shift();
    // remove the api version number
    url_arr.shift();
    console.log('User request:', url_arr);
   // get and remove the service name
    var serviceName = url_arr.shift();
    try{
        if (serviceName){
            var routed = router.route(serviceName, url_arr, req, res, next, sendResponse);
            if (!routed){
                console.error('Unknown service '+serviceName);
                next();
            }
        }
        else{
            // happens all the time when looking for the favicon
            //console.error('Unknown service '+serviceName);
            next();
        }
    }
    catch(e){
        console.error('Error loading service '+serviceName+': '+e);
        next();
    }
  };
}

<|endoftext|>


<commit_before>/**
 * Created by Fry on 08.04.2017.
 */
$(document).ready(function(){
    /** debug info **/
   deBugger('File: jgallery-patch.js');

    /** waiting for the DOM **/
    setTimeout(function(){

        function fixZIndex(){
            deBugger('func fixZIndex triggered');
            if ($("span.fa.change-mode").hasClass('fa-compress')) {
                $('#content').css("z-index",2000);
                $('.logout').hide();
                deBugger('fullscreen detected')
            }
            else {
                $('#content').removeAttr("style");
                $('.logout').show();
            }
        }

        $( "span.fa.change-mode" )      //das ist das element mim icon für fullscreen $( ".change-mode" ) müsste sogar reichen
            .on("click", function(){
                deBugger('click on $( "span.fa.change-mode" ) triggered');
                fixZIndex();
            });
        deBugger($( "span.fa.change-mode" ));
        deBugger("jgallery-patch loaded");
    },10);
});<commit_msg>removed some crap^^<commit_after>$(document).ready(function(){
    /** waiting for the DOM **/
    setTimeout(function(){

        function fixZIndex(){
            if ($("span.fa.change-mode").hasClass('fa-compress')) {
                $('#content').css("z-index",2000);
                $('.logout').hide();
            }
            else {
                $('#content').removeAttr("style");
                $('.logout').show();
            }
        }

        $( "span.fa.change-mode" )      //das ist das element mim icon für fullscreen $( ".change-mode" ) müsste sogar reichen
            .on("click", function(){
                fixZIndex();
            });
    },10);
});<|endoftext|>


<commit_before>/** @license MIT License (c) copyright B Cavalier & J Hann */
(function (define) {
define(function (require) {

	var simpleTemplate = require('./simpleTemplate');

	function createAccessors (bindings, options) {
		var getters, setters;

		getters = [];
		setters = [];

		bindings.forEach(function (binding) {
			binding.bind.forEach(function (mapping) {
				var accessor;
				accessor = createAccessor(binding.node, mapping[0], mapping[1]);
				if (accessor[0]) setters.push(accessor[0]);
				if (accessor[1]) getters.push(accessor[1]);
			});

		});

		return {
			push: function (provider) {
				for (var i = 0; i < setters.length; i++) setters[i](provider);
			},
			pull: function (receiver) {
				for (var i = 0; i < getters.length; i++) getters[i](receiver);
			}
		}
	}

	return createAccessors;

	function createAccessor (node, attr, template) {
		var compiled, key, setter, getter;

		compiled = simpleTemplate.compile(template);
		if (compiled.length > 1) {
			setter = createTemplateUpdater(node, attr, compiled);
		}
		else {
			// key is a literal if the {{}} wrapper was omitted
			key = compiled[0].key || compiled[0].literal;
			setter = createSetter(node, attr, key);
			getter = createGetter(node, attr, key);
		}
		return [setter, getter];
	}

	function createTemplateUpdater (node, attr, compiled) {
		var setter = createSetter(node, attr);
		return function (provider) {
			var content = simpleTemplate.exec(compiled, provider);
			setter(function () { return content; });
		};
	}

	function createSetter (node, attr, key) {
		if ('(empty)' == attr) return createEmptySetter(node, key);
		if ('text' == attr) attr = 'data';
		else if ('html' == attr) attr = 'innerHTML';
		return attr in node
			? function (provider) {
				var newVal = provider(key), oldVal = node[attr];
				if (newVal != oldVal) node[attr] = newVal;
			}
			: function (provider) {
				var newVal = provider(key), oldVal = nodegetAttribute(attr);
				if (newVal != oldVal) node.setAttribute(attr, newVal);
			}
	}

	function createGetter (node, attr, key) {
		if ('(empty)' == attr) return createEmptyGetter(node, key);
		if ('text' == attr) attr = 'data';
		else if ('html' == attr) attr = 'innerHTML';
		return attr in node
			? function (receiver) { receiver(key, node[attr]); }
			: function (receiver) { receiver(key, node.getAttribute(attr)); }
	}

	function createEmptySetter (node, key) {
		return function (provider) {
			if (provider(key)) {
				node.setAttribute(key, key);
			}
			else {
				node.removeAttribute(key);
			}
		};
	}

	function createEmptyGetter (node, key) {
		return function (receiver) {
			// Note: there may be IE6-8 issues lurking here:
			receiver(key, node.hasAttribute(key));
		};
	}

});
}(
	typeof define == 'function' && define.amd
		? define
		: function (factory) { module.exports = factory(require); }
));<commit_msg>Don't choke on section bindings<commit_after>/** @license MIT License (c) copyright B Cavalier & J Hann */
(function (define) {
define(function (require) {

	var simpleTemplate = require('./simpleTemplate');

	function createAccessors (bindings, options) {
		var getters, setters;

		getters = [];
		setters = [];

		bindings.forEach(function (binding) {
			if (!binding.bind) return;
			binding.bind.forEach(function (mapping) {
				var accessor;
				accessor = createAccessor(binding.node, mapping[0], mapping[1]);
				if (accessor[0]) setters.push(accessor[0]);
				if (accessor[1]) getters.push(accessor[1]);
			});

		});

		return {
			push: function (provider) {
				for (var i = 0; i < setters.length; i++) setters[i](provider);
			},
			pull: function (receiver) {
				for (var i = 0; i < getters.length; i++) getters[i](receiver);
			}
		}
	}

	return createAccessors;

	function createAccessor (node, attr, template) {
		var compiled, key, setter, getter;

		compiled = simpleTemplate.compile(template);
		if (compiled.length > 1) {
			setter = createTemplateUpdater(node, attr, compiled);
		}
		else {
			// key is a literal if the {{}} wrapper was omitted
			key = compiled[0].key || compiled[0].literal;
			setter = createSetter(node, attr, key);
			getter = createGetter(node, attr, key);
		}
		return [setter, getter];
	}

	function createTemplateUpdater (node, attr, compiled) {
		var setter = createSetter(node, attr);
		return function (provider) {
			var content = simpleTemplate.exec(compiled, provider);
			setter(function () { return content; });
		};
	}

	function createSetter (node, attr, key) {
		if ('(empty)' == attr) return createEmptySetter(node, key);
		if ('text' == attr) attr = 'data';
		else if ('html' == attr) attr = 'innerHTML';
		return attr in node
			? function (provider) {
				var newVal = provider(key), oldVal = node[attr];
				if (newVal != oldVal) node[attr] = newVal;
			}
			: function (provider) {
				var newVal = provider(key), oldVal = nodegetAttribute(attr);
				if (newVal != oldVal) node.setAttribute(attr, newVal);
			}
	}

	function createGetter (node, attr, key) {
		if ('(empty)' == attr) return createEmptyGetter(node, key);
		if ('text' == attr) attr = 'data';
		else if ('html' == attr) attr = 'innerHTML';
		return attr in node
			? function (receiver) { receiver(key, node[attr]); }
			: function (receiver) { receiver(key, node.getAttribute(attr)); }
	}

	function createEmptySetter (node, key) {
		return function (provider) {
			if (provider(key)) {
				node.setAttribute(key, key);
			}
			else {
				node.removeAttribute(key);
			}
		};
	}

	function createEmptyGetter (node, key) {
		return function (receiver) {
			// Note: there may be IE6-8 issues lurking here:
			receiver(key, node.hasAttribute(key));
		};
	}

});
}(
	typeof define == 'function' && define.amd
		? define
		: function (factory) { module.exports = factory(require); }
));<|endoftext|>


<commit_before>'use strict';

// Configuring the Articles module
angular.module('articles').run(['Menus',
	function(Menus) {
		// Set top bar menu items
		Menus.addMenuItem('topbar', 'Articles', 'articles', 'dropdown', '/articles(/create)?');
		Menus.addSubMenuItem('topbar', 'articles', 'List Articles', 'articles');
		Menus.addSubMenuItem('topbar', 'articles', 'New Article', 'articles/create');
	}
]);<commit_msg>Hid Articles from the menu (todo: remove articles)<commit_after>'use strict';

// Configuring the Articles module

/* Hide from the menus (TODO: remove Articles completely)
angular.module('articles').run(['Menus',
	function(Menus) {
		// Set top bar menu items
		Menus.addMenuItem('topbar', 'Articles', 'articles', 'dropdown', '/articles(/create)?');
		Menus.addSubMenuItem('topbar', 'articles', 'List Articles', 'articles');
		Menus.addSubMenuItem('topbar', 'articles', 'New Article', 'articles/create');
	}
]);
*/<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import classNames from 'classnames'
import META from '../../utils/Meta'

const MenuItem = ({ __onClick, active, children, className, label, name, onClick, ...rest }) => {
  const handleClick = (e) => {
    if (__onClick) __onClick(name)
    if (onClick) onClick(name)
  }

  const menuLabel = label &&
{label}

  const classes = classNames(
    'sd-menu-item',
    active && 'active',
    className,
    'item',
  )

  return (

      {name}
      {menuLabel}
      {children}

  )
}

MenuItem._meta = {
  library: META.library.semanticUI,
  name: 'MenuItem',
  type: META.type.collection,
  parent: 'Menu',
}

MenuItem.propTypes = {
  __onClick: PropTypes.func,
  active: PropTypes.bool,
  children: PropTypes.node,
  className: PropTypes.string,
  label: PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.string,
  ]),
  name: PropTypes.string,
  onClick: PropTypes.func,
}

export default MenuItem
<commit_msg>refactor(MenuItem): use named function<commit_after>import React, { PropTypes } from 'react'
import classNames from 'classnames'
import META from '../../utils/Meta'

function MenuItem({ __onClick, active, children, className, label, name, onClick, ...rest }) {
  const handleClick = (e) => {
    if (__onClick) __onClick(name)
    if (onClick) onClick(name)
  }

  const menuLabel = label &&
{label}

  const classes = classNames(
    'sd-menu-item',
    active && 'active',
    className,
    'item',
  )

  return (

      {name}
      {menuLabel}
      {children}

  )
}

MenuItem._meta = {
  library: META.library.semanticUI,
  name: 'MenuItem',
  type: META.type.collection,
  parent: 'Menu',
}

MenuItem.propTypes = {
  __onClick: PropTypes.func,
  active: PropTypes.bool,
  children: PropTypes.node,
  className: PropTypes.string,
  label: PropTypes.oneOfType([
    PropTypes.number,
    PropTypes.string,
  ]),
  name: PropTypes.string,
  onClick: PropTypes.func,
}

export default MenuItem
<|endoftext|>


<commit_before>//
// Copyright (c) 2017 DrSmugleaf
//

"use strict"
const _ = require("underscore")
const DB = require("../../../util/db.js")
const winston = require("winston")

module.exports = class Quote {
  constructor(client) {
    this.client = client

    this.db = new DB()

    this.quotes = new Map()
  }

  async init() {
    await this.db.query("CREATE TABLE IF NOT EXISTS quotes (id BIGSERIAL PRIMARY KEY, text TEXT, submitter BIGINT, guild BIGINT)")

    const rows = await this.db.query("SELECT id as realid, text, CAST(submitter as TEXT) as submitter, CAST(guild as TEXT) as guild FROM quotes")
    for(var row of rows) {
      const guild = row.guild
      const quotes = this.quotes.get(guild) || new Array()
      const id = quotes[quotes.length - 1] ? quotes[quotes.length - 1].id + 1 : 1
      row.id = id
      quotes.push(row)
      this.quotes.set(guild, quotes)
    }
  }

  add(data) {
    const that = this
    return new Promise(function(resolve, reject) {
      that.db.query(
        "INSERT INTO quotes (text, submitter, guild) VALUES ($1::text, $2::bigint, $3::bigint) RETURNING id as realid, text, CAST(submitter as TEXT), CAST(guild as TEXT)",
        [data.text, data.submitter, data.guild],
        "one"
      ).then((res) => {
        const quotes = that.quotes.get(res.guild) || new Array()
        const id = quotes[quotes.length - 1] ? quotes[quotes.length - 1].id + 1 : 1
        res.id = id
        quotes.push(res)
        that.quotes.set(res.guild, quotes)
        resolve(id)
      }).catch((e) => {
        winston.error(e)
        reject(e)
      })
    })
  }

  delete(data) {
    var quotes = this.quotes.get(data.guild)
    const quote = quotes.find((quote) => { return quote.id === data.id })

    return new Promise(function(resolve, reject) {
      if(!quote) reject()
      this.db.query("DELETE FROM quotes WHERE id=$1::bigint", [quote.id], "one").then(() => {
        quotes = _.without(quotes, quote)
        this.quotes.set(data.guild, quotes)
        resolve()
      }).catch((e) => {
        winston.error(e)
        reject(e)
      })
    })
  }

  empty(guild) {
    return !this.quotes.has(guild)
  }

  get(data) {
    const quotes = this.quotes.get(data.guild)

    if(data.id) return quotes.find((quote) => { return quote.id === data.id })
    return quotes[Math.floor(Math.random() * quotes.length)]
  }

  has(data) {
    return Boolean(this.quotes.get(data.guild).find((quote) => {
      return quote.id === data.id
    }))
  }
}
<commit_msg>Init now resets the quotes when its executed<commit_after>//
// Copyright (c) 2017 DrSmugleaf
//

"use strict"
const _ = require("underscore")
const DB = require("../../../util/db.js")
const winston = require("winston")

module.exports = class Quote {
  constructor(client) {
    this.client = client

    this.db = new DB()

    this.quotes = new Map()
  }

  async init() {
    this.quotes = new Map()

    await this.db.query("CREATE TABLE IF NOT EXISTS quotes (id BIGSERIAL PRIMARY KEY, text TEXT, submitter BIGINT, guild BIGINT)")

    const rows = await this.db.query("SELECT id as realid, text, CAST(submitter as TEXT) as submitter, CAST(guild as TEXT) as guild FROM quotes")
    for(var row of rows) {
      const guild = row.guild
      const quotes = this.quotes.get(guild) || new Array()
      const id = quotes[quotes.length - 1] ? quotes[quotes.length - 1].id + 1 : 1
      row.id = id
      quotes.push(row)
      this.quotes.set(guild, quotes)
    }
  }

  add(data) {
    const that = this
    return new Promise(function(resolve, reject) {
      that.db.query(
        "INSERT INTO quotes (text, submitter, guild) VALUES ($1::text, $2::bigint, $3::bigint) RETURNING id as realid, text, CAST(submitter as TEXT), CAST(guild as TEXT)",
        [data.text, data.submitter, data.guild],
        "one"
      ).then((res) => {
        const quotes = that.quotes.get(res.guild) || new Array()
        const id = quotes[quotes.length - 1] ? quotes[quotes.length - 1].id + 1 : 1
        res.id = id
        quotes.push(res)
        that.quotes.set(res.guild, quotes)
        resolve(id)
      }).catch((e) => {
        winston.error(e)
        reject(e)
      })
    })
  }

  delete(data) {
    var quotes = this.quotes.get(data.guild)
    const quote = quotes.find((quote) => { return quote.id === data.id })

    return new Promise(function(resolve, reject) {
      if(!quote) reject()
      this.db.query("DELETE FROM quotes WHERE id=$1::bigint", [quote.id], "one").then(() => {
        quotes = _.without(quotes, quote)
        this.quotes.set(data.guild, quotes)
        resolve()
      }).catch((e) => {
        winston.error(e)
        reject(e)
      })
    })
  }

  empty(guild) {
    return !this.quotes.has(guild)
  }

  get(data) {
    const quotes = this.quotes.get(data.guild)

    if(data.id) return quotes.find((quote) => { return quote.id === data.id })
    return quotes[Math.floor(Math.random() * quotes.length)]
  }

  has(data) {
    return Boolean(this.quotes.get(data.guild).find((quote) => {
      return quote.id === data.id
    }))
  }
}
<|endoftext|>


<commit_before>// @flow

import React, { Component } from 'react';

import { getAvailableDevices } from '../../../base/devices';
import { DialogWithTabs, hideDialog } from '../../../base/dialog';
import { connect } from '../../../base/redux';
import { isCalendarEnabled } from '../../../calendar-sync';
import {
    DeviceSelection,
    getDeviceSelectionDialogProps,
    submitDeviceSelectionTab
} from '../../../device-selection';
import {
    submitModeratorTab,
    submitMoreTab,
    submitProfileTab,
    submitSoundsTab
} from '../../actions';
import { SETTINGS_TABS } from '../../constants';
import {
    getModeratorTabProps,
    getMoreTabProps,
    getProfileTabProps,
    getSoundsTabProps
} from '../../functions';

import CalendarTab from './CalendarTab';
import ModeratorTab from './ModeratorTab';
import MoreTab from './MoreTab';
import ProfileTab from './ProfileTab';
import SoundsTab from './SoundsTab';

declare var interfaceConfig: Object;

/**
 * The type of the React {@code Component} props of
 * {@link ConnectedSettingsDialog}.
 */
type Props = {

    /**
     * Which settings tab should be initially displayed. If not defined then
     * the first tab will be displayed.
     */
    defaultTab: string,

    /**
     * Information about the tabs to be rendered.
     */
    _tabs: Array<Object>,

    /**
     * Invoked to save changed settings.
     */
    dispatch: Function
};

/**
 * A React {@code Component} for displaying a dialog to modify local settings
 * and conference-wide (moderator) settings. This version is connected to
 * redux to get the current settings.
 *
 * @augments Component
 */
class SettingsDialog extends Component<Props> {
    /**
     * Initializes a new {@code ConnectedSettingsDialog} instance.
     *
     * @param {Props} props - The React {@code Component} props to initialize
     * the new {@code ConnectedSettingsDialog} instance with.
     */
    constructor(props: Props) {
        super(props);

        // Bind event handlers so they are only bound once for every instance.
        this._closeDialog = this._closeDialog.bind(this);
    }

    /**
     * Implements React's {@link Component#render()}.
     *
     * @inheritdoc
     * @returns {ReactElement}
     */
    render() {
        const { _tabs, defaultTab, dispatch } = this.props;
        const onSubmit = this._closeDialog;
        const defaultTabIdx
            = _tabs.findIndex(({ name }) => name === defaultTab);
        const tabs = _tabs.map(tab => {
            return {
                ...tab,
                onMount: tab.onMount
                    ? (...args) => dispatch(tab.onMount(...args))
                    : undefined,
                submit: (...args) => tab.submit
                    && dispatch(tab.submit(...args))
            };
        });

        return (
            <DialogWithTabs
                closeDialog = { this._closeDialog }
                cssClassName = 'settings-dialog'
                defaultTab = {
                    defaultTabIdx === -1 ? undefined : defaultTabIdx
                }
                onSubmit = { onSubmit }
                tabs = { tabs }
                titleKey = 'settings.title' />
        );
    }

    _closeDialog: () => void;

    /**
     * Callback invoked to close the dialog without saving changes.
     *
     * @private
     * @returns {void}
     */
    _closeDialog() {
        this.props.dispatch(hideDialog());
    }
}

/**
 * Maps (parts of) the Redux state to the associated props for the
 * {@code ConnectedSettingsDialog} component.
 *
 * @param {Object} state - The Redux state.
 * @private
 * @returns {{
 *     tabs: Array<Object>
 * }}
 */
function _mapStateToProps(state) {
    const configuredTabs = interfaceConfig.SETTINGS_SECTIONS || [];

    // The settings sections to display.
    const showDeviceSettings = configuredTabs.includes('devices');
    const moreTabProps = getMoreTabProps(state);
    const moderatorTabProps = getModeratorTabProps(state);
    const { showModeratorSettings } = moderatorTabProps;
    const { showLanguageSettings, showNotificationsSettings, showPrejoinSettings } = moreTabProps;
    const showMoreTab = showLanguageSettings || showNotificationsSettings || showPrejoinSettings;
    const showProfileSettings
        = configuredTabs.includes('profile') && !state['features/base/config'].disableProfile;
    const showCalendarSettings
        = configuredTabs.includes('calendar') && isCalendarEnabled(state);
    const showSoundsSettings = configuredTabs.includes('sounds');
    const tabs = [];

    if (showDeviceSettings) {
        tabs.push({
            name: SETTINGS_TABS.DEVICES,
            component: DeviceSelection,
            label: 'settings.devices',
            onMount: getAvailableDevices,
            props: getDeviceSelectionDialogProps(state),
            propsUpdateFunction: (tabState, newProps) => {
                // Ensure the device selection tab gets updated when new devices
                // are found by taking the new props and only preserving the
                // current user selected devices. If this were not done, the
                // tab would keep using a copy of the initial props it received,
                // leaving the device list to become stale.

                return {
                    ...newProps,
                    selectedAudioInputId: tabState.selectedAudioInputId,
                    selectedAudioOutputId: tabState.selectedAudioOutputId,
                    selectedVideoInputId: tabState.selectedVideoInputId
                };
            },
            styles: 'settings-pane devices-pane',
            submit: submitDeviceSelectionTab
        });
    }

    if (showProfileSettings) {
        tabs.push({
            name: SETTINGS_TABS.PROFILE,
            component: ProfileTab,
            label: 'profile.title',
            props: getProfileTabProps(state),
            styles: 'settings-pane profile-pane',
            submit: submitProfileTab
        });
    }

    if (showModeratorSettings) {
        tabs.push({
            name: SETTINGS_TABS.MODERATOR,
            component: ModeratorTab,
            label: 'settings.moderator',
            props: moderatorTabProps,
            propsUpdateFunction: (tabState, newProps) => {
                // Updates tab props, keeping users selection

                return {
                    ...newProps,
                    followMeEnabled: tabState.followMeEnabled,
                    startAudioMuted: tabState.startAudioMuted,
                    startVideoMuted: tabState.startVideoMuted,
                    startReactionsMuted: tabState.startReactionsMuted
                };
            },
            styles: 'settings-pane moderator-pane',
            submit: submitModeratorTab
        });
    }

    if (showCalendarSettings) {
        tabs.push({
            name: SETTINGS_TABS.CALENDAR,
            component: CalendarTab,
            label: 'settings.calendar.title',
            styles: 'settings-pane calendar-pane'
        });
    }

    if (showSoundsSettings) {
        tabs.push({
            name: SETTINGS_TABS.SOUNDS,
            component: SoundsTab,
            label: 'settings.sounds',
            props: getSoundsTabProps(state),
            styles: 'settings-pane profile-pane',
            submit: submitSoundsTab
        });
    }

    if (showMoreTab) {
        tabs.push({
            name: SETTINGS_TABS.MORE,
            component: MoreTab,
            label: 'settings.more',
            props: moreTabProps,
            propsUpdateFunction: (tabState, newProps) => {
                // Updates tab props, keeping users selection

                return {
                    ...newProps,
                    currentFramerate: tabState.currentFramerate,
                    currentLanguage: tabState.currentLanguage,
                    hideSelfView: tabState.hideSelfView,
                    showPrejoinPage: tabState.showPrejoinPage,
                    enabledNotifications: tabState.enabledNotifications
                };
            },
            styles: 'settings-pane more-pane',
            submit: submitMoreTab
        });
    }

    return { _tabs: tabs };
}

export default connect(_mapStateToProps)(SettingsDialog);
<commit_msg>fix(settings-dialog) Fix crash (#11191)<commit_after>// @flow

import React, { Component } from 'react';

import { getAvailableDevices } from '../../../base/devices';
import { DialogWithTabs, hideDialog } from '../../../base/dialog';
import { connect } from '../../../base/redux';
import { isCalendarEnabled } from '../../../calendar-sync';
import {
    DeviceSelection,
    getDeviceSelectionDialogProps,
    submitDeviceSelectionTab
} from '../../../device-selection';
import {
    submitModeratorTab,
    submitMoreTab,
    submitProfileTab,
    submitSoundsTab
} from '../../actions';
import { SETTINGS_TABS } from '../../constants';
import {
    getModeratorTabProps,
    getMoreTabProps,
    getProfileTabProps,
    getSoundsTabProps
} from '../../functions';

import CalendarTab from './CalendarTab';
import ModeratorTab from './ModeratorTab';
import MoreTab from './MoreTab';
import ProfileTab from './ProfileTab';
import SoundsTab from './SoundsTab';

declare var interfaceConfig: Object;

/**
 * The type of the React {@code Component} props of
 * {@link ConnectedSettingsDialog}.
 */
type Props = {

    /**
     * Which settings tab should be initially displayed. If not defined then
     * the first tab will be displayed.
     */
    defaultTab: string,

    /**
     * Information about the tabs to be rendered.
     */
    _tabs: Array<Object>,

    /**
     * Invoked to save changed settings.
     */
    dispatch: Function
};

/**
 * A React {@code Component} for displaying a dialog to modify local settings
 * and conference-wide (moderator) settings. This version is connected to
 * redux to get the current settings.
 *
 * @augments Component
 */
class SettingsDialog extends Component<Props> {
    /**
     * Initializes a new {@code ConnectedSettingsDialog} instance.
     *
     * @param {Props} props - The React {@code Component} props to initialize
     * the new {@code ConnectedSettingsDialog} instance with.
     */
    constructor(props: Props) {
        super(props);

        // Bind event handlers so they are only bound once for every instance.
        this._closeDialog = this._closeDialog.bind(this);
    }

    /**
     * Implements React's {@link Component#render()}.
     *
     * @inheritdoc
     * @returns {ReactElement}
     */
    render() {
        const { _tabs, defaultTab, dispatch } = this.props;
        const onSubmit = this._closeDialog;
        const defaultTabIdx
            = _tabs.findIndex(({ name }) => name === defaultTab);
        const tabs = _tabs.map(tab => {
            return {
                ...tab,
                onMount: tab.onMount
                    ? (...args) => dispatch(tab.onMount(...args))
                    : undefined,
                submit: (...args) => tab.submit
                    && dispatch(tab.submit(...args))
            };
        });

        return (
            <DialogWithTabs
                closeDialog = { this._closeDialog }
                cssClassName = 'settings-dialog'
                defaultTab = {
                    defaultTabIdx === -1 ? undefined : defaultTabIdx
                }
                onSubmit = { onSubmit }
                tabs = { tabs }
                titleKey = 'settings.title' />
        );
    }

    _closeDialog: () => void;

    /**
     * Callback invoked to close the dialog without saving changes.
     *
     * @private
     * @returns {void}
     */
    _closeDialog() {
        this.props.dispatch(hideDialog());
    }
}

/**
 * Maps (parts of) the Redux state to the associated props for the
 * {@code ConnectedSettingsDialog} component.
 *
 * @param {Object} state - The Redux state.
 * @private
 * @returns {{
 *     tabs: Array<Object>
 * }}
 */
function _mapStateToProps(state) {
    const configuredTabs = interfaceConfig.SETTINGS_SECTIONS || [];

    // The settings sections to display.
    const showDeviceSettings = configuredTabs.includes('devices');
    const moreTabProps = getMoreTabProps(state);
    const moderatorTabProps = getModeratorTabProps(state);
    const { showModeratorSettings } = moderatorTabProps;
    const { showLanguageSettings, showNotificationsSettings, showPrejoinSettings } = moreTabProps;
    const showMoreTab = showLanguageSettings || showNotificationsSettings || showPrejoinSettings;
    const showProfileSettings
        = configuredTabs.includes('profile') && !state['features/base/config'].disableProfile;
    const showCalendarSettings
        = configuredTabs.includes('calendar') && isCalendarEnabled(state);
    const showSoundsSettings = configuredTabs.includes('sounds');
    const tabs = [];

    if (showDeviceSettings) {
        tabs.push({
            name: SETTINGS_TABS.DEVICES,
            component: DeviceSelection,
            label: 'settings.devices',
            onMount: getAvailableDevices,
            props: getDeviceSelectionDialogProps(state),
            propsUpdateFunction: (tabState, newProps) => {
                // Ensure the device selection tab gets updated when new devices
                // are found by taking the new props and only preserving the
                // current user selected devices. If this were not done, the
                // tab would keep using a copy of the initial props it received,
                // leaving the device list to become stale.

                return {
                    ...newProps,
                    selectedAudioInputId: tabState.selectedAudioInputId,
                    selectedAudioOutputId: tabState.selectedAudioOutputId,
                    selectedVideoInputId: tabState.selectedVideoInputId
                };
            },
            styles: 'settings-pane devices-pane',
            submit: submitDeviceSelectionTab
        });
    }

    if (showProfileSettings) {
        tabs.push({
            name: SETTINGS_TABS.PROFILE,
            component: ProfileTab,
            label: 'profile.title',
            props: getProfileTabProps(state),
            styles: 'settings-pane profile-pane',
            submit: submitProfileTab
        });
    }

    if (showModeratorSettings) {
        tabs.push({
            name: SETTINGS_TABS.MODERATOR,
            component: ModeratorTab,
            label: 'settings.moderator',
            props: moderatorTabProps,
            propsUpdateFunction: (tabState, newProps) => {
                // Updates tab props, keeping users selection

                return {
                    ...newProps,
                    followMeEnabled: tabState?.followMeEnabled,
                    startAudioMuted: tabState?.startAudioMuted,
                    startVideoMuted: tabState?.startVideoMuted,
                    startReactionsMuted: tabState?.startReactionsMuted
                };
            },
            styles: 'settings-pane moderator-pane',
            submit: submitModeratorTab
        });
    }

    if (showCalendarSettings) {
        tabs.push({
            name: SETTINGS_TABS.CALENDAR,
            component: CalendarTab,
            label: 'settings.calendar.title',
            styles: 'settings-pane calendar-pane'
        });
    }

    if (showSoundsSettings) {
        tabs.push({
            name: SETTINGS_TABS.SOUNDS,
            component: SoundsTab,
            label: 'settings.sounds',
            props: getSoundsTabProps(state),
            styles: 'settings-pane profile-pane',
            submit: submitSoundsTab
        });
    }

    if (showMoreTab) {
        tabs.push({
            name: SETTINGS_TABS.MORE,
            component: MoreTab,
            label: 'settings.more',
            props: moreTabProps,
            propsUpdateFunction: (tabState, newProps) => {
                // Updates tab props, keeping users selection

                return {
                    ...newProps,
                    currentFramerate: tabState?.currentFramerate,
                    currentLanguage: tabState?.currentLanguage,
                    hideSelfView: tabState?.hideSelfView,
                    showPrejoinPage: tabState?.showPrejoinPage,
                    enabledNotifications: tabState?.enabledNotifications
                };
            },
            styles: 'settings-pane more-pane',
            submit: submitMoreTab
        });
    }

    return { _tabs: tabs };
}

export default connect(_mapStateToProps)(SettingsDialog);
<|endoftext|>


<commit_before>'use strict';

const merge = require('lodash/merge');
const inRange = require('lodash.inrange');
const ISO6391 = require('iso-639-1');
const defaults = {
    lang: 'en',
    toc: { minLevel: 2, maxLevel: 6 }
};

function defineSettings(options) {
    const settings = merge({}, defaults, options);

    const validMinLevel = inRange(settings.toc.minLevel, defaults.toc.minLevel, defaults.toc.maxLevel + 1);
    const validMaxLevel = inRange(settings.toc.maxLevel, defaults.toc.minLevel, defaults.toc.maxLevel + 1);
    const isValidRange = (validMinLevel && validMaxLevel);

    if (!ISO6391.validate(settings.lang)) {
        throw 'Your language argument is invalid';
    }
    if (settings.toc && !isValidRange) {
        throw `ToC levels must between ${defaults.toc.minLevel} and ${defaults.toc.maxLevel}`;
    }
    return settings;
}

module.exports = defineSettings;
<commit_msg>fix(define-settings): add check for maxlevel > minlevel<commit_after>'use strict';

const merge = require('lodash/merge');
const inRange = require('lodash.inrange');
const ISO6391 = require('iso-639-1');
const defaults = {
    lang: 'en',
    toc: { minLevel: 2, maxLevel: 6 }
};

function defineSettings(options) {
    const settings = merge({}, defaults, options);

    const validMinLevel = inRange(settings.toc.minLevel, defaults.toc.minLevel, defaults.toc.maxLevel + 1);
    const validMaxLevel = (inRange(settings.toc.maxLevel, defaults.toc.minLevel, defaults.toc.maxLevel + 1) && settings.toc.maxLevel >= settings.toc.minLevel);
    const isValidRange = (validMinLevel && validMaxLevel);

    if (!ISO6391.validate(settings.lang)) {
        throw 'Your language argument is invalid';
    }
    if (settings.toc && !isValidRange) {
        throw `ToC levels must between ${defaults.toc.minLevel} and ${defaults.toc.maxLevel}`;
    }
    return settings;
}

module.exports = defineSettings;
<|endoftext|>


<commit_before>'use strict';
import GenBase from '../genBase';
import path from 'path';

export default class Generator extends GenBase {
  constructor(...args) {
    super(...args);
  }

  get prompting() {
    return function () {
      this.askForModuleName();
    };
  }

  get writing() {
    return function () {
      const done = this.async();

      let config;

      this.getConfig().then(requestedConfig => {
        config = requestedConfig;

        config.templateUrl = config.modulePath;

        if (config.structure === 'module-type') {
          config.templateUrl = path.join(config.modulePath, 'directives');
        }
        config.templateUrl = config.templateUrl.replace(/\\/g, '/');

        if (config.directiveTemplateUrl) {
          return this.copyMarkupFile('directive', config);
        }
      }).then(() => {
        return Promise.all([
          this.copySrcFile('directive', config),
          this.copyUnitTest('directive', config)
        ]);
      }).then(() => {
        done();
      });
    };
  }
}
<commit_msg>refactor(directive): use async/await<commit_after>'use strict';
import GenBase from '../genBase';
import path from 'path';

export default class Generator extends GenBase {
  constructor(...args) {
    super(...args);
  }

  get prompting() {
    return function () {
      this.askForModuleName();
    };
  }

  get writing() {
    return async function () {
      const done = this.async();

      let config = await this.getConfig();

      config.templateUrl = config.modulePath;

      if (config.structure === 'module-type') {
        config.templateUrl = path.join(config.modulePath, 'directives');
      }
      config.templateUrl = config.templateUrl.replace(/\\/g, '/');

      if (config.directiveTemplateUrl) {
        await this.copyMarkupFile('directive', config);
      }

      await Promise.all([
        this.copySrcFile('directive', config),
        this.copyUnitTest('directive', config)
      ]);

      done();
    };
  }
}
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';

import colorByCharacter from '~/constants/colorByCharacter';

function WordCard(props) {
  const {word} = props;

  function toggleIsRevealed(word) {
    props.toggleIsRevealed && props.toggleIsRevealed(word);
  }

  return (
    <div
      className={`grid__item col-1-5 mv-`}
    >

 word.isRevealed ? null : toggleIsRevealed(word)}
          className={`bo--1 bor--5 flex flex--jc--c align-items--center height--80 ${word.isRevealed ? 'opacity--4-10' : 'cursor--pointer'} ${colorByCharacter[word.character] ? colorByCharacter[word.character] : 'white'}`}
        >

              {word.text}

  );
}

WordCard.propTypes = {
  word: PropTypes.object.isRequired,
  toggleIsRevealed: PropTypes.func.isRequired,
};

export default WordCard;
<commit_msg>Fix bug with colored tiles always showing for guess board<commit_after>import React, { PropTypes } from 'react';

import colorByCharacter from '~/constants/colorByCharacter';

function WordCard(props) {
  const {word} = props;

  function toggleIsRevealed(word) {
    props.toggleIsRevealed && props.toggleIsRevealed(word);
  }

  return (
    <div
      className={`grid__item col-1-5 mv-`}
    >

 word.isRevealed ? null : toggleIsRevealed(word)}
          className={`bo--1 bor--5 flex flex--jc--c align-items--center height--80 ${word.isRevealed ? 'opacity--4-10' : 'cursor--pointer'} ${word.isRevealed && colorByCharacter[word.character] ? colorByCharacter[word.character] : 'white'}`}
        >

              {word.text}

  );
}

WordCard.propTypes = {
  word: PropTypes.object.isRequired,
  toggleIsRevealed: PropTypes.func.isRequired,
};

export default WordCard;
<|endoftext|>


<commit_before>import React, { Fragment, Component } from 'react'
import { Heading, Text, Link } from '@hackclub/design-system'
import IconButton from 'components/IconButton'
import { Modal, Overlay, CloseButton } from 'components/Modal'

class Help extends Component {
  state = { active: false }

  toggleRules = () => {
    this.setState(state => ({ active: !state.active }))
  }

  // Render a modal for challenge rules on button press
  render() {
    if (this.state.active) {
      return (
        <Fragment>
          <Modal align="left" my={4} p={[3, 4]}>
            <CloseButton onClick={this.toggleRules} />
            <Heading.h2>Challenge Rules</Heading.h2>
            {/*
            <Text
              fontSize={2}
              mt={3}
              color="info"
              py={2}
              px={3}
              bg="blue.0"
              style={{ borderRadius: 4 }}
            >
              For this challenge, your entry must use{' '}
              <Link href="https://p5js.org" target="_blank" bold>
                p5.js
              </Link>{' '}
              in its code.
            </Text>
            */}
            <Text fontSize={2} my={3}>
              Challenge is open to Hack Club members and repl.it users. It
              strictly follows Hack Club’s{' '}
              <Link href="https://conduct.hackclub.com" target="_blank">
                Code of Conduct
              </Link>
              . Anything breaking our Code of Conduct (ex. voter fraud) and
              contestants found cheating can be temporarily or permanently
              banned.
            </Text>
            <Text fontSize={2}>
              If you think anyone has violated our Conduct or cheating policy,
              please reach out to us confidentially at{' '}
              <Link href="mailto:challenge@hackclub.com">
                challenge@hackclub.com
              </Link>
              .
            </Text>
          </Modal>
          <Overlay onClick={this.toggleRules} />
        </Fragment>
      )
    }
    return (
      <IconButton
        glyph="flag-fill"
        bg="info"
        children="Rules"
        inverted
        fontSize={2}
        m={3}
        onClick={this.toggleRules}
        style={{ position: 'absolute', right: 0, top: 0 }}
        {...this.props}
      />
    )
  }
}

export default Help
<commit_msg>Update challenge rules<commit_after>import React, { Fragment, Component } from 'react'
import { Heading, Text, Link } from '@hackclub/design-system'
import IconButton from 'components/IconButton'
import { Modal, Overlay, CloseButton } from 'components/Modal'

class Help extends Component {
  state = { active: false }

  toggleRules = () => {
    this.setState(state => ({ active: !state.active }))
  }

  // Render a modal for challenge rules on button press
  render() {
    if (this.state.active) {
      return (
        <Fragment>
          <Modal align="left" my={4} p={[3, 4]}>
            <CloseButton onClick={this.toggleRules} />
            <Heading.h2>Challenge Rules</Heading.h2>
            {/*
            <Text
              fontSize={2}
              mt={3}
              color="info"
              py={2}
              px={3}
              bg="blue.0"
              style={{ borderRadius: 4 }}
            >
              For this challenge, your entry must use{' '}
              <Link href="https://p5js.org" target="_blank" bold>
                p5.js
              </Link>{' '}
              in its code.
            </Text>
            */}
            <Text fontSize={2} my={3}>
              Challenge is open to Hack Club community members. It
              strictly follows Hack Club’s{' '}
              <Link href="https://conduct.hackclub.com" target="_blank">
                Code of Conduct
              </Link>
              . Anything breaking our Code of Conduct (ex. voter fraud) and
              contestants found cheating can be temporarily or permanently
              banned.
            </Text>
            <Text fontSize={2}>
              If you think anyone has violated our Conduct or cheating policy,
              please reach out to us confidentially at{' '}
              <Link href="mailto:challenge@hackclub.com">
                challenge@hackclub.com
              </Link>
              .
            </Text>
          </Modal>
          <Overlay onClick={this.toggleRules} />
        </Fragment>
      )
    }
    return (
      <IconButton
        glyph="flag-fill"
        bg="info"
        children="Rules"
        inverted
        fontSize={2}
        m={3}
        onClick={this.toggleRules}
        style={{ position: 'absolute', right: 0, top: 0 }}
        {...this.props}
      />
    )
  }
}

export default Help
<|endoftext|>


<commit_before>import { QModal } from '../modal'
import { QInput } from '../input'
import { QBtn } from '../btn'
import { QOptionGroup } from '../option-group'
import clone from '../../utils/clone'
import extend from '../../utils/extend'

export default {
  name: 'q-dialog',
  props: {
    value: Boolean,
    title: String,
    message: String,
    prompt: Object,
    options: Object,
    ok: {
      type: [String, Object, Boolean],
      default: true
    },
    cancel: [String, Object, Boolean],
    stackButtons: Boolean,
    preventClose: Boolean,
    noBackdropDismiss: Boolean,
    noEscDismiss: Boolean,
    position: String,
    color: {
      type: String,
      default: 'primary'
    }
  },
  render (h) {
    const
      child = [],
      title = this.$slots.title || this.title,
      msg = this.$slots.message || this.message

    if (title) {
      child.push(
        h('div', {
          staticClass: 'modal-header'
        }, [ title ])
      )
    }
    if (msg) {
      child.push(
        h('div', {
          staticClass: 'modal-body modal-message modal-scroll'
        }, [ msg ])
      )
    }

    if (this.hasForm || this.$slots.body) {
      child.push(
        h(
          'div',
          { staticClass: 'modal-body modal-scroll' },
          this.hasForm
            ? (this.prompt ? this.__getPrompt(h) : this.__getOptions(h))
            : [ this.$slots.body ]
        )
      )
    }

    if (this.$scopedSlots.buttons) {
      child.push(
        h('div', {
          staticClass: 'modal-buttons',
          'class': this.buttonClass
        }, [
          this.$scopedSlots.buttons({
            ok: this.__onOk,
            cancel: this.__onCancel
          })
        ])
      )
    }
    else if (this.ok || this.cancel) {
      child.push(this.__getButtons(h))
    }

    return h(QModal, {
      ref: 'modal',
      props: {
        value: this.value,
        minimized: true,
        noBackdropDismiss: this.noBackdropDismiss || this.preventClose,
        noEscDismiss: this.noEscDismiss || this.preventClose,
        position: this.position
      },
      on: {
        input: val => {
          this.$emit('input', val)
        },
        show: () => {
          this.$emit('show')

          if (!this.$q.platform.is.desktop) {
            return
          }

          let node = this.prompt
            ? this.$refs.modal.$el.getElementsByTagName('INPUT')
            : this.$refs.modal.$el.getElementsByClassName('q-option')

          if (node.length) {
            node[0].focus()
            return
          }

          node = this.$refs.modal.$el.getElementsByTagName('BUTTON')
          if (node.length) {
            node[node.length - 1].focus()
          }
        },
        hide: () => {
          this.$emit('hide')
        },
        dismiss: () => {
          this.$emit('cancel')
        },
        'escape-key': () => {
          this.hide().then(() => {
            this.$emit('escape-key')
            this.$emit('cancel')
          })
        }
      }
    }, child)
  },
  computed: {
    hasForm () {
      return this.prompt || this.options
    },
    okLabel () {
      return this.ok === true
        ? this.$q.i18n.label.ok
        : this.ok
    },
    cancelLabel () {
      return this.cancel === true
        ? this.$q.i18n.label.cancel
        : this.cancel
    },
    buttonClass () {
      return this.stackButtons
        ? 'column'
        : 'row'
    },
    okProps () {
      return Object(this.ok) === this.ok
        ? extend({
          color: this.color,
          label: this.$q.i18n.label.ok,
          waitForRipple: true
        }, this.ok)
        : { color: this.color, flat: true, label: this.okLabel, waitForRipple: true }
    },
    cancelProps () {
      return Object(this.cancel) === this.cancel
        ? extend({
          color: this.color,
          label: this.$q.i18n.label.cancel,
          waitForRipple: true
        }, this.cancel)
        : { color: this.color, flat: true, label: this.cancelLabel, waitForRipple: true }
    }
  },
  methods: {
    show () {
      return this.$refs.modal.show()
    },
    hide () {
      let data

      return this.$refs.modal.hide().then(() => {
        if (this.hasForm) {
          data = clone(this.__getData())
        }
        return data
      })
    },
    __getPrompt (h) {
      return [
        h(QInput, {
          style: 'margin-bottom: 10px',
          props: {
            value: this.prompt.model,
            type: this.prompt.type || 'text',
            color: this.color,
            noPassToggle: true
          },
          on: {
            change: v => { this.prompt.model = v }
          }
        })
      ]
    },
    __getOptions (h) {
      return [
        h(QOptionGroup, {
          props: {
            value: this.options.model,
            type: this.options.type,
            color: this.color,
            inline: this.options.inline,
            options: this.options.items
          },
          on: {
            change: v => { this.options.model = v }
          }
        })
      ]
    },
    __getButtons (h) {
      const child = []

      if (this.cancel) {
        child.push(h(QBtn, {
          props: this.cancelProps,
          on: { click: this.__onCancel }
        }))
      }
      if (this.ok) {
        child.push(h(QBtn, {
          props: this.okProps,
          on: { click: this.__onOk }
        }))
      }

      return h('div', {
        staticClass: 'modal-buttons',
        'class': this.buttonClass
      }, child)
    },
    __onOk () {
      return this.hide().then(data => {
        this.$emit('ok', data)
      })
    },
    __onCancel () {
      return this.hide().then(() => {
        this.$emit('cancel')
      })
    },
    __getData () {
      if (this.prompt) {
        return this.prompt.model
      }
      if (this.options) {
        return this.options.model
      }
    }
  }
}
<commit_msg>feat(QDialog): Disable ripple & wait-for-ripple for Buttons (unnecessary)<commit_after>import { QModal } from '../modal'
import { QInput } from '../input'
import { QBtn } from '../btn'
import { QOptionGroup } from '../option-group'
import clone from '../../utils/clone'
import extend from '../../utils/extend'

export default {
  name: 'q-dialog',
  props: {
    value: Boolean,
    title: String,
    message: String,
    prompt: Object,
    options: Object,
    ok: {
      type: [String, Object, Boolean],
      default: true
    },
    cancel: [String, Object, Boolean],
    stackButtons: Boolean,
    preventClose: Boolean,
    noBackdropDismiss: Boolean,
    noEscDismiss: Boolean,
    position: String,
    color: {
      type: String,
      default: 'primary'
    }
  },
  render (h) {
    const
      child = [],
      title = this.$slots.title || this.title,
      msg = this.$slots.message || this.message

    if (title) {
      child.push(
        h('div', {
          staticClass: 'modal-header'
        }, [ title ])
      )
    }
    if (msg) {
      child.push(
        h('div', {
          staticClass: 'modal-body modal-message modal-scroll'
        }, [ msg ])
      )
    }

    if (this.hasForm || this.$slots.body) {
      child.push(
        h(
          'div',
          { staticClass: 'modal-body modal-scroll' },
          this.hasForm
            ? (this.prompt ? this.__getPrompt(h) : this.__getOptions(h))
            : [ this.$slots.body ]
        )
      )
    }

    if (this.$scopedSlots.buttons) {
      child.push(
        h('div', {
          staticClass: 'modal-buttons',
          'class': this.buttonClass
        }, [
          this.$scopedSlots.buttons({
            ok: this.__onOk,
            cancel: this.__onCancel
          })
        ])
      )
    }
    else if (this.ok || this.cancel) {
      child.push(this.__getButtons(h))
    }

    return h(QModal, {
      ref: 'modal',
      props: {
        value: this.value,
        minimized: true,
        noBackdropDismiss: this.noBackdropDismiss || this.preventClose,
        noEscDismiss: this.noEscDismiss || this.preventClose,
        position: this.position
      },
      on: {
        input: val => {
          this.$emit('input', val)
        },
        show: () => {
          this.$emit('show')

          if (!this.$q.platform.is.desktop) {
            return
          }

          let node = this.prompt
            ? this.$refs.modal.$el.getElementsByTagName('INPUT')
            : this.$refs.modal.$el.getElementsByClassName('q-option')

          if (node.length) {
            node[0].focus()
            return
          }

          node = this.$refs.modal.$el.getElementsByTagName('BUTTON')
          if (node.length) {
            node[node.length - 1].focus()
          }
        },
        hide: () => {
          this.$emit('hide')
        },
        dismiss: () => {
          this.$emit('cancel')
        },
        'escape-key': () => {
          this.hide().then(() => {
            this.$emit('escape-key')
            this.$emit('cancel')
          })
        }
      }
    }, child)
  },
  computed: {
    hasForm () {
      return this.prompt || this.options
    },
    okLabel () {
      return this.ok === true
        ? this.$q.i18n.label.ok
        : this.ok
    },
    cancelLabel () {
      return this.cancel === true
        ? this.$q.i18n.label.cancel
        : this.cancel
    },
    buttonClass () {
      return this.stackButtons
        ? 'column'
        : 'row'
    },
    okProps () {
      return Object(this.ok) === this.ok
        ? extend({
          color: this.color,
          label: this.$q.i18n.label.ok,
          noRipple: true
        }, this.ok)
        : { color: this.color, flat: true, label: this.okLabel, noRipple: true }
    },
    cancelProps () {
      return Object(this.cancel) === this.cancel
        ? extend({
          color: this.color,
          label: this.$q.i18n.label.cancel,
          noRipple: true
        }, this.cancel)
        : { color: this.color, flat: true, label: this.cancelLabel, noRipple: true }
    }
  },
  methods: {
    show () {
      return this.$refs.modal.show()
    },
    hide () {
      let data

      return this.$refs.modal.hide().then(() => {
        if (this.hasForm) {
          data = clone(this.__getData())
        }
        return data
      })
    },
    __getPrompt (h) {
      return [
        h(QInput, {
          style: 'margin-bottom: 10px',
          props: {
            value: this.prompt.model,
            type: this.prompt.type || 'text',
            color: this.color,
            noPassToggle: true
          },
          on: {
            change: v => { this.prompt.model = v }
          }
        })
      ]
    },
    __getOptions (h) {
      return [
        h(QOptionGroup, {
          props: {
            value: this.options.model,
            type: this.options.type,
            color: this.color,
            inline: this.options.inline,
            options: this.options.items
          },
          on: {
            change: v => { this.options.model = v }
          }
        })
      ]
    },
    __getButtons (h) {
      const child = []

      if (this.cancel) {
        child.push(h(QBtn, {
          props: this.cancelProps,
          on: { click: this.__onCancel }
        }))
      }
      if (this.ok) {
        child.push(h(QBtn, {
          props: this.okProps,
          on: { click: this.__onOk }
        }))
      }

      return h('div', {
        staticClass: 'modal-buttons',
        'class': this.buttonClass
      }, child)
    },
    __onOk () {
      return this.hide().then(data => {
        this.$emit('ok', data)
      })
    },
    __onCancel () {
      return this.hide().then(() => {
        this.$emit('cancel')
      })
    },
    __getData () {
      if (this.prompt) {
        return this.prompt.model
      }
      if (this.options) {
        return this.options.model
      }
    }
  }
}
<|endoftext|>


<commit_before>const Divider = {
  functional: true,

  render (createElement, { data }) {
    const params = {
      'class': 'divider'
    }

    if (data.attrs) {
      if ('inset' in data.attrs) {
        params.class += ' divider--inset'
      }

      if ('light' in data.attrs) {
        params.class += ' divider--light'
      }
    }

    return createElement('hr', params)
  }
}

export default {
  Divider
}
<commit_msg>cleaned up fn<commit_after>const Divider = {
  functional: true,

  render (h, context) {
    context.data.class = context.data.class || []
    context.data.class.push('divider')

    if (context.data.attrs) {
      'inset' in context.data.attrs && context.data.class.push('divider--inset')
      'light' in context.data.attrs && context.data.class.push('divider--light')
    }

    return h('hr', context.data)
  }
}

export default {
  Divider
}
<|endoftext|>