<commit_before>var Server = require("../../server").Server
  , format = require('util').format;

// The ping strategy uses pings each server and records the
// elapsed time for the server so it can pick a server based on lowest
// return time for the db command {ping:true}
var PingStrategy = exports.PingStrategy = function(replicaset, secondaryAcceptableLatencyMS) {
  this.replicaset = replicaset;
  this.secondaryAcceptableLatencyMS = secondaryAcceptableLatencyMS;
  this.state = 'disconnected';
  this.pingInterval = 5000;
  // Class instance
  this.Db = require("../../../db").Db;
  // Active db connections
  this.dbs = {};
  // Current server index
  this.index = 0;
  // Logger api
  this.Logger = null;
}

// Starts any needed code
PingStrategy.prototype.start = function(callback) {
  // already running?
  if ('connected' == this.state) return;

  this.state = 'connected';

  // Start ping server
  this._pingServer(callback);
}

// Stops and kills any processes running
PingStrategy.prototype.stop = function(callback) {
  // Stop the ping process
  this.state = 'disconnected';

  // Stop all the server instances
  for(var key in this.dbs) {
    this.dbs[key].close();
  }

  // optional callback
  callback && callback(null, null);
}

PingStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) {
  // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS
  // Create a list of candidat servers, containing the primary if available
  var candidateServers = [];
  var self = this;

  // If we have not provided a list of candidate servers use the default setup
  if(!Array.isArray(secondaryCandidates)) {
    candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : [];
    // Add all the secondaries
    var keys = Object.keys(this.replicaset._state.secondaries);
    for(var i = 0; i < keys.length; i++) {
      candidateServers.push(this.replicaset._state.secondaries[keys[i]])
    }
  } else {
    candidateServers = secondaryCandidates;
  }

  // Final list of eligable server
  var finalCandidates = [];

  // If we have tags filter by tags
  if(tags != null && typeof tags == 'object') {
    // If we have an array or single tag selection
    var tagObjects = Array.isArray(tags) ? tags : [tags];
    // Iterate over all tags until we find a candidate server
    for(var _i = 0; _i < tagObjects.length; _i++) {
      // Grab a tag object
      var tagObject = tagObjects[_i];
      // Matching keys
      var matchingKeys = Object.keys(tagObject);
      // Remove any that are not tagged correctly
      for(var i = 0; i < candidateServers.length; i++) {
        var server = candidateServers[i];
        // If we have tags match
        if(server.tags != null) {
          var matching = true;

          // Ensure we have all the values
          for(var j = 0; j < matchingKeys.length; j++) {
            if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
              matching = false;
              break;
            }
          }

          // If we have a match add it to the list of matching servers
          if(matching) {
            finalCandidates.push(server);
          }
        }
      }
    }
  } else {
    // Final array candidates
    var finalCandidates = candidateServers;
  }

  // Filter out any non-connected servers
  finalCandidates = finalCandidates.filter(function(s) {
    return s.isConnected();
  })

  // Sort by ping time
  finalCandidates.sort(function(a, b) {
    return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs'];
  });

  if(0 === finalCandidates.length)
    return new Error("No replica set members available for query");

  // find lowest server with a ping time
  var lowest = finalCandidates.filter(function (server) {
    return undefined != server.runtimeStats.pingMs;
  })[0];

  if(!lowest) {
    lowest = finalCandidates[0];
  }

  // convert to integer
  var lowestPing = lowest.runtimeStats.pingMs | 0;

  // determine acceptable latency
  var acceptable = lowestPing + this.secondaryAcceptableLatencyMS;

  // remove any server responding slower than acceptable
  var len = finalCandidates.length;
  while(len--) {
    if(finalCandidates[len].runtimeStats['pingMs'] > acceptable) {
      finalCandidates.splice(len, 1);
    }
  }

  if(self.logger && self.logger.debug) {
    self.logger.debug("Ping strategy selection order for tags", tags);
    finalCandidates.forEach(function(c) {
      self.logger.debug(format("%s:%s = %s ms", c.host, c.port, c.runtimeStats['pingMs']), null);
    })
  }

  // If no candidates available return an error
  if(finalCandidates.length == 0)
    return new Error("No replica set members available for query");

  // Ensure no we don't overflow
  this.index = this.index % finalCandidates.length
  // Pick a random acceptable server
  var connection = finalCandidates[this.index].checkoutReader();
  // Point to next candidate (round robin style)
  this.index = this.index + 1;

  if(self.logger && self.logger.debug) {
    if(connection)
      self.logger.debug("picked server %s:%s", connection.socketOptions.host, connection.socketOptions.port);
  }

  return connection;
}

PingStrategy.prototype._pingServer = function(callback) {
  var self = this;

  // Ping server function
  var pingFunction = function() {
    // Our state changed to disconnected or destroyed return
    if(self.state == 'disconnected' || self.state == 'destroyed') return;
    // If the replicaset is destroyed return
    if(self.replicaset.isDestroyed() || self.replicaset._serverState == 'disconnected') return

    // Create a list of all servers we can send the ismaster command to
    var allServers = self.replicaset._state.master != null ? [self.replicaset._state.master] : [];

    // Secondary keys
    var keys = Object.keys(self.replicaset._state.secondaries);
    // Add all secondaries
    for(var i = 0; i < keys.length; i++) {
      allServers.push(self.replicaset._state.secondaries[keys[i]]);
    }

    // Number of server entries
    var numberOfEntries = allServers.length;

    // We got keys
    for(var i = 0; i < allServers.length; i++) {

      // We got a server instance
      var server = allServers[i];

      // Create a new server object, avoid using internal connections as they might
      // be in an illegal state
      new function(serverInstance) {
        var _db = self.dbs[serverInstance.host + ":" + serverInstance.port];
        // If we have a db
        if(_db != null) {
          // Startup time of the command
          var startTime = Date.now();

          // Execute ping command in own scope
          var _ping = function(__db, __serverInstance) {
            // Execute ping on this connection
            __db.executeDbCommand({ping:1}, {failFast:true}, function(err) {
              // Emit the ping
              self.replicaset.emit("ping", err, serverInstance);

              if(err) {
                delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                __db.close();
                return done();
              }

              if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
                __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime;
              }

              __db.executeDbCommand({ismaster:1}, {failFast:true}, function(err, result) {
                // Emit the ping
                self.replicaset.emit("ping_ismaster", err, result, serverInstance);

                if(err) {
                  delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                  __db.close();
                  return done();
                }

                // Process the ismaster for the server
                if(result && result.documents && self.replicaset.processIsMaster) {
                  self.replicaset.processIsMaster(__serverInstance, result.documents[0]);
                }

                // Done with the pinging
                done();
              });
            });
          };
          // Ping
          _ping(_db, serverInstance);
        } else {
          var connectTimeoutMS = self.replicaset.options.socketOptions
            ? self.replicaset.options.socketOptions.connectTimeoutMS : 0

          // Create a new master connection
          var _server = new Server(serverInstance.host, serverInstance.port, {
            auto_reconnect: false,
            returnIsMasterResults: true,
            slaveOk: true,
            poolSize: 1,
            socketOptions: { connectTimeoutMS: connectTimeoutMS },
            ssl: self.replicaset.options.ssl,
            sslValidate: self.replicaset.options.sslValidate,
            sslCA: self.replicaset.options.sslCA,
            sslCert: self.replicaset.options.sslCert,
            sslKey: self.replicaset.options.sslKey,
            sslPass: self.replicaset.options.sslPass
          });

          // Create Db instance
          var _db = new self.Db('local', _server, { safe: true });
          _db.on("close", function() {
            delete self.dbs[this.serverConfig.host + ":" + this.serverConfig.port];
          })

          var _ping = function(__db, __serverInstance) {
            if(self.state == 'disconnected') {
              self.stop();
              return;
            }

            __db.open(function(err, db) {
              // Emit ping connect
              self.replicaset.emit("ping_connect", err, __serverInstance);

              if(self.state == 'disconnected' && __db != null) {
                return __db.close();
              }

              if(err) {
                delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                __db.close();
                return done();
              }

              // Save instance
              self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port] = __db;

              // Startup time of the command
              var startTime = Date.now();

              // Execute ping on this connection
              __db.executeDbCommand({ping:1}, {failFast:true}, function(err) {
                self.replicaset.emit("ping", err, __serverInstance);

                if(err) {
                  delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                  __db.close();
                  return done();
                }

                if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
                  __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime;
                }

                __db.executeDbCommand({ismaster:1}, {failFast:true}, function(err, result) {
                  self.replicaset.emit("ping_ismaster", err, result, __serverInstance);

                  if(err) {
                    delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                    __db.close();
                    return done();
                  }

                  // Process the ismaster for the server
                  if(result && result.documents && self.replicaset.processIsMaster) {
                    self.replicaset.processIsMaster(__serverInstance, result.documents[0]);
                  }

                  // Done with the pinging
                  done();
                });
              });
            });
          };

          // Ping the server
          _ping(_db, serverInstance);
        }

        function done() {
          // Adjust the number of checks
          numberOfEntries--;

          // If we are done with all results coming back trigger ping again
          if(0 === numberOfEntries && 'connected' == self.state) {
            setTimeout(pingFunction, self.pingInterval);
          }
        }
      }(server);
    }
  }

  // Start pingFunction
  pingFunction();

  callback && callback(null);
}
<commit_msg>Replica server availability check<commit_after>var Server = require("../../server").Server
  , format = require('util').format;

// The ping strategy uses pings each server and records the
// elapsed time for the server so it can pick a server based on lowest
// return time for the db command {ping:true}
var PingStrategy = exports.PingStrategy = function(replicaset, secondaryAcceptableLatencyMS) {
  this.replicaset = replicaset;
  this.secondaryAcceptableLatencyMS = secondaryAcceptableLatencyMS;
  this.state = 'disconnected';
  // Interval of ping attempts
  this.pingInterval = replicaset.options.socketOptions.pingInterval || 5000;
  // Timeout for ping response, default - no timeout
  this.pingTimeout = replicaset.options.socketOptions.pingTimeout || null;
  // Class instance
  this.Db = require("../../../db").Db;
  // Active db connections
  this.dbs = {};
  // Current server index
  this.index = 0;
  // Logger api
  this.Logger = null;
}

// Starts any needed code
PingStrategy.prototype.start = function(callback) {
  // already running?
  if ('connected' == this.state) return;

  this.state = 'connected';

  // Start ping server
  this._pingServer(callback);
}

// Stops and kills any processes running
PingStrategy.prototype.stop = function(callback) {
  // Stop the ping process
  this.state = 'disconnected';

  // Stop all the server instances
  for(var key in this.dbs) {
    this.dbs[key].close();
  }

  // optional callback
  callback && callback(null, null);
}

PingStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) {
  // Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS
  // Create a list of candidat servers, containing the primary if available
  var candidateServers = [];
  var self = this;

  // If we have not provided a list of candidate servers use the default setup
  if(!Array.isArray(secondaryCandidates)) {
    candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : [];
    // Add all the secondaries
    var keys = Object.keys(this.replicaset._state.secondaries);
    for(var i = 0; i < keys.length; i++) {
      candidateServers.push(this.replicaset._state.secondaries[keys[i]])
    }
  } else {
    candidateServers = secondaryCandidates;
  }

  // Final list of eligable server
  var finalCandidates = [];

  // If we have tags filter by tags
  if(tags != null && typeof tags == 'object') {
    // If we have an array or single tag selection
    var tagObjects = Array.isArray(tags) ? tags : [tags];
    // Iterate over all tags until we find a candidate server
    for(var _i = 0; _i < tagObjects.length; _i++) {
      // Grab a tag object
      var tagObject = tagObjects[_i];
      // Matching keys
      var matchingKeys = Object.keys(tagObject);
      // Remove any that are not tagged correctly
      for(var i = 0; i < candidateServers.length; i++) {
        var server = candidateServers[i];
        // If we have tags match
        if(server.tags != null) {
          var matching = true;

          // Ensure we have all the values
          for(var j = 0; j < matchingKeys.length; j++) {
            if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
              matching = false;
              break;
            }
          }

          // If we have a match add it to the list of matching servers
          if(matching) {
            finalCandidates.push(server);
          }
        }
      }
    }
  } else {
    // Final array candidates
    var finalCandidates = candidateServers;
  }

  // Filter out any non-connected servers
  finalCandidates = finalCandidates.filter(function(s) {
    return s.isConnected();
  })

  // Sort by ping time
  finalCandidates.sort(function(a, b) {
    return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs'];
  });

  if(0 === finalCandidates.length)
    return new Error("No replica set members available for query");

  // find lowest server with a ping time
  var lowest = finalCandidates.filter(function (server) {
    return undefined != server.runtimeStats.pingMs;
  })[0];

  if(!lowest) {
    lowest = finalCandidates[0];
  }

  // convert to integer
  var lowestPing = lowest.runtimeStats.pingMs | 0;

  // determine acceptable latency
  var acceptable = lowestPing + this.secondaryAcceptableLatencyMS;

  // remove any server responding slower than acceptable
  var len = finalCandidates.length;
  while(len--) {
    if(finalCandidates[len].runtimeStats['pingMs'] > acceptable) {
      finalCandidates.splice(len, 1);
    }
  }

  if(self.logger && self.logger.debug) {
    self.logger.debug("Ping strategy selection order for tags", tags);
    finalCandidates.forEach(function(c) {
      self.logger.debug(format("%s:%s = %s ms", c.host, c.port, c.runtimeStats['pingMs']), null);
    })
  }

  // If no candidates available return an error
  if(finalCandidates.length == 0)
    return new Error("No replica set members available for query");

  // Ensure no we don't overflow
  this.index = this.index % finalCandidates.length
  // Pick a random acceptable server
  var connection = finalCandidates[this.index].checkoutReader();
  // Point to next candidate (round robin style)
  this.index = this.index + 1;

  if(self.logger && self.logger.debug) {
    if(connection)
      self.logger.debug("picked server %s:%s", connection.socketOptions.host, connection.socketOptions.port);
  }

  return connection;
}

PingStrategy.prototype._pingServer = function(callback) {
  var self = this;

  // Ping server function
  var pingFunction = function() {
    // Our state changed to disconnected or destroyed return
    if(self.state == 'disconnected' || self.state == 'destroyed') return;
    // If the replicaset is destroyed return
    if(self.replicaset.isDestroyed() || self.replicaset._serverState == 'disconnected') return

    // Create a list of all servers we can send the ismaster command to
    var allServers = self.replicaset._state.master != null ? [self.replicaset._state.master] : [];

    // Secondary keys
    var keys = Object.keys(self.replicaset._state.secondaries);
    // Add all secondaries
    for(var i = 0; i < keys.length; i++) {
      allServers.push(self.replicaset._state.secondaries[keys[i]]);
    }

    // Number of server entries
    var numberOfEntries = allServers.length;

    // We got keys
    for(var i = 0; i < allServers.length; i++) {

      // We got a server instance
      var server = allServers[i];

      // Create a new server object, avoid using internal connections as they might
      // be in an illegal state
      new function(serverInstance) {
        var _db = self.dbs[serverInstance.host + ":" + serverInstance.port];
        // If we have a db
        if(_db != null) {
          // Startup time of the command
          var startTime = Date.now();

          // Execute ping command in own scope
          var _ping = function(__db, __serverInstance) {

            // Server unavailable. Checks only if pingTimeout defined & greater than 0
            var _failTimer = self.pingTimeout ? setTimeout(function () {
              if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
                __serverInstance.close();
              }
            }, self.pingTimeout) : null;

            // Execute ping on this connection
            __db.executeDbCommand({ping:1}, {failFast:true}, function(err) {

              // Server available
              clearTimeout(_failTimer);

              // Emit the ping
              self.replicaset.emit("ping", err, serverInstance);

              if(err) {
                delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                __db.close();
                return done();
              }

              if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
                __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime;
              }

              __db.executeDbCommand({ismaster:1}, {failFast:true}, function(err, result) {
                // Emit the ping
                self.replicaset.emit("ping_ismaster", err, result, serverInstance);

                if(err) {
                  delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                  __db.close();
                  return done();
                }

                // Process the ismaster for the server
                if(result && result.documents && self.replicaset.processIsMaster) {
                  self.replicaset.processIsMaster(__serverInstance, result.documents[0]);
                }

                // Done with the pinging
                done();
              });
            });
          };
          // Ping
          _ping(_db, serverInstance);
        } else {
          var connectTimeoutMS = self.replicaset.options.socketOptions
            ? self.replicaset.options.socketOptions.connectTimeoutMS : 0

          // Create a new master connection
          var _server = new Server(serverInstance.host, serverInstance.port, {
            auto_reconnect: false,
            returnIsMasterResults: true,
            slaveOk: true,
            poolSize: 1,
            socketOptions: { connectTimeoutMS: connectTimeoutMS },
            ssl: self.replicaset.options.ssl,
            sslValidate: self.replicaset.options.sslValidate,
            sslCA: self.replicaset.options.sslCA,
            sslCert: self.replicaset.options.sslCert,
            sslKey: self.replicaset.options.sslKey,
            sslPass: self.replicaset.options.sslPass
          });

          // Create Db instance
          var _db = new self.Db('local', _server, { safe: true });
          _db.on("close", function() {
            delete self.dbs[this.serverConfig.host + ":" + this.serverConfig.port];
          })

          var _ping = function(__db, __serverInstance) {
            if(self.state == 'disconnected') {
              self.stop();
              return;
            }

            __db.open(function(err, db) {
              // Emit ping connect
              self.replicaset.emit("ping_connect", err, __serverInstance);

              if(self.state == 'disconnected' && __db != null) {
                return __db.close();
              }

              if(err) {
                delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                __db.close();
                return done();
              }

              // Save instance
              self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port] = __db;

              // Startup time of the command
              var startTime = Date.now();

              // Execute ping on this connection
              __db.executeDbCommand({ping:1}, {failFast:true}, function(err) {
                self.replicaset.emit("ping", err, __serverInstance);

                if(err) {
                  delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                  __db.close();
                  return done();
                }

                if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
                  __serverInstance.runtimeStats['pingMs'] = Date.now() - startTime;
                }

                __db.executeDbCommand({ismaster:1}, {failFast:true}, function(err, result) {
                  self.replicaset.emit("ping_ismaster", err, result, __serverInstance);

                  if(err) {
                    delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
                    __db.close();
                    return done();
                  }

                  // Process the ismaster for the server
                  if(result && result.documents && self.replicaset.processIsMaster) {
                    self.replicaset.processIsMaster(__serverInstance, result.documents[0]);
                  }

                  // Done with the pinging
                  done();
                });
              });
            });
          };

          // Ping the server
          _ping(_db, serverInstance);
        }

        function done() {
          // Adjust the number of checks
          numberOfEntries--;

          // If we are done with all results coming back trigger ping again
          if(0 === numberOfEntries && 'connected' == self.state) {
            setTimeout(pingFunction, self.pingInterval);
          }
        }
      }(server);
    }
  }

  // Start pingFunction
  pingFunction();

  callback && callback(null);
}
<|endoftext|>


<commit_before>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace normal
*/
var normal = {};

/**
* @name cdf
* @memberof normal
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/normal/cdf}
*/
setReadOnly( normal, 'cdf', require( '@stdlib/math/base/dist/normal/cdf' ) );

/**
* @name pdf
* @memberof normal
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/normal/pdf}
*/
setReadOnly( normal, 'pdf', require( '@stdlib/math/base/dist/normal/pdf' ) );

/**
* @name quantile
* @memberof normal
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/normal/quantile}
*/
setReadOnly( normal, 'quantile', require( '@stdlib/math/base/dist/normal/quantile' ) );

// EXPORTS //

module.exports = normal;
<commit_msg>Export MGF module to namespace<commit_after>'use strict';

/*
* When adding modules to the namespace, ensure that they are added in alphabetical order according to module name.
*/

// MODULES //

var setReadOnly = require( '@stdlib/utils/define-read-only-property' );

// MAIN //

/**
* Top-level namespace.
*
* @namespace normal
*/
var normal = {};

/**
* @name cdf
* @memberof normal
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/normal/cdf}
*/
setReadOnly( normal, 'cdf', require( '@stdlib/math/base/dist/normal/cdf' ) );

/**
* @name mgf
* @memberof normal
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/normal/mgf}
*/
setReadOnly( normal, 'mgf', require( '@stdlib/math/base/dist/normal/mgf' ) );

/**
* @name pdf
* @memberof normal
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/normal/pdf}
*/
setReadOnly( normal, 'pdf', require( '@stdlib/math/base/dist/normal/pdf' ) );

/**
* @name quantile
* @memberof normal
* @readonly
* @type {Function}
* @see {@link module:@stdlib/math/base/dist/normal/quantile}
*/
setReadOnly( normal, 'quantile', require( '@stdlib/math/base/dist/normal/quantile' ) );

// EXPORTS //

module.exports = normal;
<|endoftext|>


<commit_before>'use strict';

/*
* The following copyright and license were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/9.3.0/lib/msun/src/k_log.h?view=markup}.
*
* The implementation follows the original, but has been modified for JavaScript.
*/

/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/

// MODULES //

var evalpoly = require( '@stdlib/math/base/tools/evalpoly' ).factory;
var getHighWord = require( '@stdlib/number/float64/base/get-high-word' );

// VARIABLES //

var P = [
	3.999999999940941908e-01,  // 3FD99999 9997FA04
	2.222219843214978396e-01,  // 3FCC71C5 1D8E78AF
	1.531383769920937332e-01  // 3FC39A09 D078C69F
];
var Q = [
	6.666666666666735130e-01, // 3FE55555 55555593
	2.857142874366239149e-01, // 3FD24924 94229359
	1.818357216161805012e-01, // 3FC74664 96CB03DE
	1.479819860511658591e-01 // 3FC2F112 DF3E5244
];

// 0x000fffff = 1048575 => 0 00000000000 11111111111111111111
var HIGH_SIGNIFICAND_MASK = 0x000fffff;

// 1/3
var ONE_THIRD = 0.33333333333333333;

// FUNCTIONS //

// Compile functions to evaluate polynomial functions based on the above coefficients...
var polyvalP = evalpoly( P );
var polyvalQ = evalpoly( Q );

// MAIN //

/**
* Return log(x) - (x-1) for x in ~[sqrt(2)/2, sqrt(2)].
*
* @private
* @param {number} x - input value
* @returns {number} function value
*/
function klog( x ) {
	var hfsq;
	var t1;
	var t2;
	var hx;
	var f;
	var s;
	var z;
	var R;
	var w;
	var i;
	var j;

	hx = getHighWord( x );
	f = x - 1.0;
	if ( ( HIGH_SIGNIFICAND_MASK & (2+hx) ) < 3 ) {
		// Case: -2**-20 <= f < 2**-20
		if ( f === 0.0 ) {
			return 0.0;
		}
		return f * f * ( ( ONE_THIRD*f )- 0.5 );
	}
	s = f / ( 2.0 + f );
	z = s * s;
	hx &= HIGH_SIGNIFICAND_MASK;
	i = hx - 0x6147a;
	w = z * z;
	j = 0x6b851 - hx;
	t1 = w * polyvalP( w );
	t2 = z * polyvalQ( w );
	i |= j;
	R = t2 + t1;
	if ( i > 0 ) {
		hfsq = 0.5 * f * f;
		return ( s * (hfsq+R) ) - hfsq;
	}
	return s * (R-f);
} // end FUNCTION klog()

// EXPORTS //

module.exports = klog;
<commit_msg>Align comments and ensure integer operations<commit_after>'use strict';

/*
* The following copyright and license were part of the original implementation available as part of [FreeBSD]{@link https://svnweb.freebsd.org/base/release/9.3.0/lib/msun/src/k_log.h?view=markup}.
*
* The implementation follows the original, but has been modified for JavaScript.
*/

/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/

// MODULES //

var evalpoly = require( '@stdlib/math/base/tools/evalpoly' ).factory;
var getHighWord = require( '@stdlib/number/float64/base/get-high-word' );

// VARIABLES //

var P = [
	3.999999999940941908e-01, // 3FD99999 9997FA04
	2.222219843214978396e-01, // 3FCC71C5 1D8E78AF
	1.531383769920937332e-01  // 3FC39A09 D078C69F
];
var Q = [
	6.666666666666735130e-01, // 3FE55555 55555593
	2.857142874366239149e-01, // 3FD24924 94229359
	1.818357216161805012e-01, // 3FC74664 96CB03DE
	1.479819860511658591e-01  // 3FC2F112 DF3E5244
];

// 0x000fffff = 1048575 => 0 00000000000 11111111111111111111
var HIGH_SIGNIFICAND_MASK = 0x000fffff|0; // asm type annotation

// 1/3
var ONE_THIRD = 0.33333333333333333;

// FUNCTIONS //

// Compile functions to evaluate polynomial functions based on the above coefficients...
var polyvalP = evalpoly( P );
var polyvalQ = evalpoly( Q );

// MAIN //

/**
* Return `log(x) - (x-1)` for `x` in `~[sqrt(2)/2, sqrt(2)]`.
*
* @private
* @param {number} x - input value
* @returns {number} function value
*/
function klog( x ) {
	var hfsq;
	var t1;
	var t2;
	var hx;
	var f;
	var s;
	var z;
	var R;
	var w;
	var i;
	var j;

	hx = getHighWord( x );
	f = x - 1.0;
	if ( ( HIGH_SIGNIFICAND_MASK & (2+hx) ) < 3 ) {
		// Case: -2**-20 <= f < 2**-20
		if ( f === 0.0 ) {
			return 0.0;
		}
		return f * f * ( ( ONE_THIRD*f )- 0.5 );
	}
	s = f / ( 2.0 + f );
	z = s * s;
	hx &= HIGH_SIGNIFICAND_MASK;
	i = ( hx - 0x6147a )|0; // asm type annotation
	w = z * z;
	j = ( 0x6b851 - hx )|0; // asm type annotation
	t1 = w * polyvalP( w );
	t2 = z * polyvalQ( w );
	i |= j;
	R = t2 + t1;
	if ( i > 0 ) {
		hfsq = 0.5 * f * f;
		return ( s * (hfsq+R) ) - hfsq;
	}
	return s * (R-f);
} // end FUNCTION klog()

// EXPORTS //

module.exports = klog;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import Topic from './Topic'
import { setActiveTopic,
         toggleArgumentsModal,
         toggleMoreModal,
         finishTest } from '../../store/modules/test_state'
import { saveAnswer } from '../../store/modules/results'

class TopicContainer extends React.Component {

    constructor (props, context) {
        super(props)
        this._setAnswer = this._setAnswer.bind(this)
        this._nextTopic = this._nextTopic.bind(this)
    }

    static propTypes = {
        next_topic: PropTypes.object.isRequired,
        setActiveTopic: PropTypes.func.isRequired,
        finishTest: PropTypes.func.isRequired,
        toggleArgumentsModal: PropTypes.func.isRequired,
        toggleMoreModal: PropTypes.func.isRequired,
        saveAnswer: PropTypes.func.isRequired,
        active_topic: PropTypes.object.isRequired,
        topics_amount: PropTypes.number.isRequired,
        params: React.PropTypes.object
    }

    static contextTypes = {
        router: React.PropTypes.object
    }

    componentWillReceiveProps(nextProps) {
        const new_slug = nextProps.params.topicSlug
        if (new_slug !== this.props.params.topicSlug && nextProps.active_topic.slug !== new_slug) {
            this.props.setActiveTopic(new_slug)
        }
    }

    componentWillMount() {
        const topicSlug = this.props.params.topicSlug
        if (Object.keys(this.props.params).length === 0) {
            this.props.setActiveTopic()
        } else {
            if (!this.props.active_topic || this.props.active_topic.slug !== topicSlug) {
                this.props.setActiveTopic(topicSlug)
            }
        }
    }

    _nextTopic () {
        const topicPosition = this.props.next_topic.position
        const topicSlug = this.props.next_topic.slug
        if (topicPosition <= this.props.topics_amount) {
            this.props.setActiveTopic(topicSlug)
            this.context.router.push('/topic/' + topicSlug)
        } else {
            this.props.finishTest()
            this.context.router.push('/results')
        }
    }

    _setAnswer (topic_id, answer) {
        if (topic_id && answer) {
            this.props.saveAnswer(topic_id, answer)
            this._nextTopic()
        } else {
            this._nextTopic()
        }
    }

    render () {
        const done_topics = (this.props.next_topic.position > 2) ? this.props.next_topic.position - 1 : 1
        if (this.props.active_topic) {
            return <Topic saveAnswer={this._setAnswer}
                          nextTopic={this._nextTopic}
                          toggleArguments={this.props.toggleArgumentsModal}
                          toggleDetails={this.props.toggleMoreModal}
                          topic={this.props.active_topic}
                          doneTopics={done_topics}
                          topicsAmount={this.props.topics_amount} />
        } else {
            return
Loading...

        }
    }

}

const mapStateToProps = (state) => ({
    next_topic: state.test_state.next_topic,
    active_topic: state.test_state.active_topic,
    topics_amount: state.test_state.topics.length
})

export default connect((mapStateToProps), {
    setActiveTopic,
    finishTest,
    toggleArgumentsModal,
    toggleMoreModal,
    saveAnswer
})(TopicContainer)<commit_msg>Track click on Details and Arguments buttons<commit_after>import React, { PropTypes } from 'react'
import { connect } from 'react-redux'
import Topic from './Topic'
import { setActiveTopic,
         toggleArgumentsModal,
         toggleMoreModal,
         finishTest } from '../../store/modules/test_state'
import { saveAnswer } from '../../store/modules/results'

class TopicContainer extends React.Component {

    constructor (props, context) {
        super(props)
        this._setAnswer = this._setAnswer.bind(this)
        this._nextTopic = this._nextTopic.bind(this)
        this._toggleDetails = this._toggleDetails.bind(this)
        this._toggleArguments = this._toggleArguments.bind(this)
    }

    static propTypes = {
        next_topic: PropTypes.object.isRequired,
        setActiveTopic: PropTypes.func.isRequired,
        finishTest: PropTypes.func.isRequired,
        toggleArgumentsModal: PropTypes.func.isRequired,
        toggleMoreModal: PropTypes.func.isRequired,
        saveAnswer: PropTypes.func.isRequired,
        active_topic: PropTypes.object.isRequired,
        topics_amount: PropTypes.number.isRequired,
        params: React.PropTypes.object
    }

    static contextTypes = {
        router: React.PropTypes.object
    }

    componentWillReceiveProps(nextProps) {
        const new_slug = nextProps.params.topicSlug
        if (new_slug !== this.props.params.topicSlug && nextProps.active_topic.slug !== new_slug) {
            this.props.setActiveTopic(new_slug)
        }
    }

    componentWillMount() {
        const topicSlug = this.props.params.topicSlug
        if (Object.keys(this.props.params).length === 0) {
            this.props.setActiveTopic()
        } else {
            if (!this.props.active_topic || this.props.active_topic.slug !== topicSlug) {
                this.props.setActiveTopic(topicSlug)
            }
        }
    }

    _nextTopic () {
        const topicPosition = this.props.next_topic.position
        const topicSlug = this.props.next_topic.slug
        if (topicPosition <= this.props.topics_amount) {
            this.props.setActiveTopic(topicSlug)
            this.context.router.push('/topic/' + topicSlug)
        } else {
            this.props.finishTest()
            this.context.router.push('/results')
        }
    }

    _setAnswer (topic_id, answer) {
        if (topic_id && answer) {
            this.props.saveAnswer(topic_id, answer)
            this._nextTopic()
        } else {
            this._nextTopic()
        }
    }

    _toggleDetails () {
        // Track click in Google Analytics
        window.ga('send', 'event', {
            eventCategory: 'Toggle Details',
            eventAction: 'click',
            eventLabel: this.props.active_topic.slug
        })
        this.props.toggleMoreModal()
    }

    _toggleArguments () {
        // Track click in Google Analytics
        window.ga('send', 'event', {
            eventCategory: 'Toggle Arguments',
            eventAction: 'click',
            eventLabel: this.props.active_topic.slug
        })
        this.props.toggleArgumentsModal()
    }

    render () {
        const done_topics = (this.props.next_topic.position > 2) ? this.props.next_topic.position - 1 : 1
        if (this.props.active_topic) {
            return <Topic saveAnswer={this._setAnswer}
                          nextTopic={this._nextTopic}
                          toggleArguments={this._toggleArguments}
                          toggleDetails={this._toggleDetails}
                          topic={this.props.active_topic}
                          doneTopics={done_topics}
                          topicsAmount={this.props.topics_amount} />
        } else {
            return
Loading...

        }
    }

}

const mapStateToProps = (state) => ({
    next_topic: state.test_state.next_topic,
    active_topic: state.test_state.active_topic,
    topics_amount: state.test_state.topics.length
})

export default connect((mapStateToProps), {
    setActiveTopic,
    finishTest,
    toggleArgumentsModal,
    toggleMoreModal,
    saveAnswer
})(TopicContainer)<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */

// @flow

import { isOriginalId } from "devtools-source-map";
import { PROMISE } from "../utils/middleware/promise";
import { setSymbols } from "../ast";
import {
  getSource,
  getGeneratedSource,
  getSources,
  getTextSearchQuery
} from "../../selectors";
import { setSource } from "../../workers/parser";
import { isThirdParty, isLoading, isLoaded } from "../../utils/source";

import defer from "../../utils/defer";
import type { ThunkArgs } from "../types";
import type { SourceRecord } from "../../reducers/types";
import { searchSource } from "../project-text-search";

const requests = new Map();

async function loadSource(source: SourceRecord, { sourceMaps, client }) {
  const id = source.get("id");
  if (isOriginalId(id)) {
    return await sourceMaps.getOriginalSourceText(source.toJS());
  }

  const response = await client.sourceContents(id);

  return {
    id,
    text: response.source,
    contentType: response.contentType || "text/javascript"
  };
}

/**
  Load the text for all the available sources
 * @memberof actions/sources
 * @static
 */
export function loadAllSources() {
  return async ({ dispatch, getState }: ThunkArgs) => {
    const sources = getSources(getState());
    const query = getTextSearchQuery(getState());
    for (const [, source] of sources) {
      if (isThirdParty(source)) {
        continue;
      }

      await dispatch(loadSourceText(source));
      // If there is a current search query we search
      // each of the source texts as they get loaded
      if (query) {
        await dispatch(searchSource(source.get("id"), query));
      }
    }
  };
}

/**
 * @memberof actions/sources
 * @static
 */
export function loadSourceText(source: SourceRecord) {
  return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
    const deferred = defer();

    // Fetch the source text only once.
    if (isLoaded(source)) {
      return Promise.resolve(source);
    }

    const id = source.get("id");

    if (isLoading(source) || requests.has(id)) {
      return requests.get(id);
    }

    requests.set(id, deferred.promise);
    await dispatch({
      type: "LOAD_SOURCE_TEXT",
      sourceId: id,
      [PROMISE]: loadSource(source, { sourceMaps, client })
    });

    const newSource = getSource(getState(), source.get("id")).toJS();
    if (newSource.isWasm) {
      return;
    }

    if (isOriginalId(newSource.id)) {
      const generatedSource = getGeneratedSource(getState(), source.toJS());
      await dispatch(loadSourceText(generatedSource));
    }

    await setSource(newSource);
    dispatch(setSymbols(id));

    // signal that the action is finished
    deferred.resolve();
    requests.delete(id);
  };
}
<commit_msg>Fixes loadSourceText async loading for wasm. (#5017)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */

// @flow

import { isOriginalId } from "devtools-source-map";
import { PROMISE } from "../utils/middleware/promise";
import { setSymbols } from "../ast";
import {
  getSource,
  getGeneratedSource,
  getSources,
  getTextSearchQuery
} from "../../selectors";
import * as parser from "../../workers/parser";
import { isThirdParty, isLoading, isLoaded } from "../../utils/source";

import defer from "../../utils/defer";
import type { ThunkArgs } from "../types";
import type { SourceRecord } from "../../reducers/types";
import { searchSource } from "../project-text-search";

const requests = new Map();

async function loadSource(source: SourceRecord, { sourceMaps, client }) {
  const id = source.get("id");
  if (isOriginalId(id)) {
    return await sourceMaps.getOriginalSourceText(source.toJS());
  }

  const response = await client.sourceContents(id);

  return {
    id,
    text: response.source,
    contentType: response.contentType || "text/javascript"
  };
}

/**
  Load the text for all the available sources
 * @memberof actions/sources
 * @static
 */
export function loadAllSources() {
  return async ({ dispatch, getState }: ThunkArgs) => {
    const sources = getSources(getState());
    const query = getTextSearchQuery(getState());
    for (const [, source] of sources) {
      if (isThirdParty(source)) {
        continue;
      }

      await dispatch(loadSourceText(source));
      // If there is a current search query we search
      // each of the source texts as they get loaded
      if (query) {
        await dispatch(searchSource(source.get("id"), query));
      }
    }
  };
}

/**
 * @memberof actions/sources
 * @static
 */
export function loadSourceText(source: SourceRecord) {
  return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
    const deferred = defer();

    // Fetch the source text only once.
    if (isLoaded(source)) {
      return Promise.resolve(source);
    }

    const id = source.get("id");

    if (isLoading(source) || requests.has(id)) {
      return requests.get(id);
    }

    requests.set(id, deferred.promise);
    await dispatch({
      type: "LOAD_SOURCE_TEXT",
      sourceId: id,
      [PROMISE]: loadSource(source, { sourceMaps, client })
    });

    const newSource = getSource(getState(), source.get("id")).toJS();

    if (isOriginalId(newSource.id) && !newSource.isWasm) {
      const generatedSource = getGeneratedSource(getState(), source.toJS());
      await dispatch(loadSourceText(generatedSource));
    }

    if (!newSource.isWasm) {
      await parser.setSource(newSource);
      dispatch(setSymbols(id));
    }

    // signal that the action is finished
    deferred.resolve();
    requests.delete(id);
  };
}
<|endoftext|>


<commit_before>/**
Copyright 2016 Autodesk,Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/
import { mount } from 'enzyme';
import * as HIG from 'hig.web';
import React from 'react';

import TextFieldAdapter from './TextFieldAdapter';

describe('<TextFieldAdapter>', () => {
  function createHigTextField(defaults = {}) {
    const higContainer = document.createElement('div');

    const higTextField = new HIG.TextField({ ...defaults });

    higTextField.mount(higContainer);

    return { higTextField, higContainer };
  }

  function createOrionTextField(props) {
    return <TextFieldAdapter {...props} />;
  }

  it('renders a text field', () => {
    const defaults = { name: 'mySpecialField' };

    const { higTextField, higContainer } = createHigTextField(defaults);
    const container = document.createElement('div');
    const wrapper = mount(createOrionTextField(defaults), {
      attachTo: container
    });

    expect(container.firstElementChild.outerHTML).toMatchSnapshot();

    expect(container.firstElementChild.outerHTML).toEqual(
      higContainer.firstElementChild.outerHTML
    );
  });

  it('renders a text field with initial props', () => {
    const defaults = {
      icon: 'assets',
      instructions: "Don't just do something, sit there.",
      label: 'Name of your first pet',
      name: 'mySpecialField',
      placeholder: 'Was it Fluffy?',
      value: 'Rex'
    };

    const { higTextField, higContainer } = createHigTextField(defaults);
    const container = document.createElement('div');
    const wrapper = mount(createOrionTextField(defaults), {
      attachTo: container
    });

    expect(container.firstElementChild.outerHTML).toMatchSnapshot();

    expect(container.firstElementChild.outerHTML).toEqual(
      higContainer.firstElementChild.outerHTML
    );
  });

  it('renders a text field with udpated props', () => {
    const defaults = {
      name: 'mySpecialField'
    };

    const { higTextField, higContainer } = createHigTextField(defaults);
    const orionContainer = document.createElement('div');
    const wrapper = mount(createOrionTextField(defaults), {
      attachTo: orionContainer
    });

    const nextProps = {
      icon: 'assets',
      instructions: "Don't just do something, sit there.",
      label: 'Name of your first pet',
      placeholder: 'Was it Fluffy?',
      required: 'You really must fill this in.',
      value: 'Rex'
    };

    higTextField.setIcon(nextProps.icon);
    higTextField.setInstructions(nextProps.instructions);
    higTextField.setLabel(nextProps.label);
    higTextField.setPlaceholder(nextProps.placeholder);
    higTextField.required(nextProps.required);
    higTextField.setValue(nextProps.value);
    higTextField.onBlur(() => {});
    higTextField.onChange(() => {});
    higTextField.onFocus(() => {});
    higTextField.onInput(() => {});
    wrapper.setProps(nextProps);

    expect(orionContainer.firstElementChild.outerHTML).toMatchSnapshot();

    expect(orionContainer.firstElementChild.outerHTML).toEqual(
      higContainer.firstElementChild.outerHTML
    );
  });
});
<commit_msg>WIP Shore up test coverage<commit_after>/**
Copyright 2016 Autodesk,Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/
import { mount } from 'enzyme';
import * as HIG from 'hig.web';
import React from 'react';

import TextFieldAdapter from './TextFieldAdapter';

describe('<TextFieldAdapter>', () => {
  function createHigTextField(defaults = {}) {
    const higContainer = document.createElement('div');

    const higTextField = new HIG.TextField({ ...defaults });

    higTextField.mount(higContainer);

    return { higTextField, higContainer };
  }

  function createOrionTextField(props) {
    return <TextFieldAdapter {...props} />;
  }

  it('renders a text field', () => {
    const defaults = { name: 'mySpecialField' };

    const { higTextField, higContainer } = createHigTextField(defaults);
    const container = document.createElement('div');
    const wrapper = mount(createOrionTextField(defaults), {
      attachTo: container
    });

    expect(container.firstElementChild.outerHTML).toMatchSnapshot();

    expect(container.firstElementChild.outerHTML).toEqual(
      higContainer.firstElementChild.outerHTML
    );
  });

  it('renders a text field with initial props', () => {
    const defaults = {
      icon: 'assets',
      instructions: "Don't just do something, sit there.",
      label: 'Name of your first pet',
      name: 'mySpecialField',
      placeholder: 'Was it Fluffy?',
      value: 'Rex'
    };

    const { higTextField, higContainer } = createHigTextField(defaults);
    const container = document.createElement('div');
    const wrapper = mount(createOrionTextField(defaults), {
      attachTo: container
    });

    expect(container.firstElementChild.outerHTML).toMatchSnapshot();

    expect(container.firstElementChild.outerHTML).toEqual(
      higContainer.firstElementChild.outerHTML
    );
  });

  it('renders a text field with udpated props', () => {
    const defaults = {
      name: 'mySpecialField'
    };

    const { higTextField, higContainer } = createHigTextField(defaults);
    const orionContainer = document.createElement('div');
    const wrapper = mount(createOrionTextField(defaults), {
      attachTo: orionContainer
    });

    const nextProps = {
      icon: 'assets',
      instructions: "Don't just do something, sit there.",
      label: 'Name of your first pet',
      placeholder: 'Was it Fluffy?',
      required: 'You really must fill this in.',
      value: 'Rex'
    };

    higTextField.setIcon(nextProps.icon);
    higTextField.setInstructions(nextProps.instructions);
    higTextField.setLabel(nextProps.label);
    higTextField.setPlaceholder(nextProps.placeholder);
    higTextField.required(nextProps.required);
    higTextField.setValue(nextProps.value);
    wrapper.setProps(nextProps);

    expect(orionContainer.firstElementChild.outerHTML).toMatchSnapshot();

    expect(orionContainer.firstElementChild.outerHTML).toEqual(
      higContainer.firstElementChild.outerHTML
    );
  });

  it('sets event listeners', () => {
    const defaults = {
      onClick: jest.fn(),
      onBlur: jest.fn(),
      onFocus: jest.fn(),
      onInput: jest.fn()
    };

    const nextProps = {
      onClick: jest.fn(),
      onBlur: jest.fn(),
      onFocus: jest.fn(),
      onInput: jest.fn()
    };

    const container = document.createElement('div');
    const wrapper = mount(createOrionTextField(defaults), {
      attachTo: container
    });
    const instance = wrapper.instance().instance;

    expect(defaults.onClick).toEqual(instance.events['onClick']);
    expect(defaults.onBlur).toEqual(instance.events['onBlur']);
    expect(defaults.onFocus).toEqual(instance.events['onFocus']);
    expect(defaults.onInput).toEqual(instance.events['onInput']);

    wrapper.setProps(nextProps);

    expect(nextProps.onClick).toEqual(instance.events['onClick']);
    expect(nextProps.onBlur).toEqual(instance.events['onBlur']);
    expect(nextProps.onFocus).toEqual(instance.events['onFocus']);
    expect(nextProps.onInput).toEqual(instance.events['onInput']);
  });
});
<|endoftext|>


<commit_before>(function (mw, $, THREE) {
	"use strict";

	mw.PluginManager.add('video360', mw.KBasePlugin.extend({

		defaultConfig: {
			moveMultiplier: 0.3,
			mobileVibrationValue: (mw.isIOS() ? 0.0365 : 1),
			cameraOptions:{
				fov: 75,
				aspect: window.innerWidth / window.innerHeight,
				near: 0.1,
				far: 1000
			}
		},
		manualControl: false,
		longitude: 180,
		latitude: 0,
		savedX: 0,
		savedY: 0,
		savedLongitude: 0,
		savedLatitude: 0,
		enableKeyboardShortcuts: true,
		keyboardShortcutsMap: {
			"left":  "65",  // 'A'
			"up":    "87",  // 'W'
			"right": "68",  // 'D'
			"down":  "83"   // 'S'
		},

		isSafeEnviornment: function () {
			return !( mw.isIE8() || mw.isIE9() || mw.isIE10Comp() || // old IEs
				(mw.isIE11() && (mw.getUserOS() === 'Windows 7' || mw.getUserOS() === 'Windows 8')) || // ie11 on win7/8
				(mw.isIphone() && mw.isIOSBelow10()) || // iPhone and IOS < 10 - doesn't support inline playback
				mw.isIOSBelow9() ); // IOS < 9 doesn't support webgl
		},

		setup: function () {
			this.set360Config();
			this.addBindings();
		},

		set360Config:function(){
			//Get user configuration
			var userCameraOptions = this.getConfig("cameraOptions");
			//Deep extend custom config
			this.cameraOptions = $.extend({}, this.defaultConfig.cameraOptions, userCameraOptions);
		},

		addBindings: function () {
			this.bind("playerReady", function () {
				this.moveMultiplier = this.getConfig("moveMultiplier");
				this.mobileVibrationValue = this.getConfig("mobileVibrationValue");
				this.video = this.getPlayer().getPlayerElement();
				this.video.setAttribute('crossorigin', 'anonymous');
				$(this.video).css('z-index', '-1');
				if (mw.isIE11()) {
					// a workaround for ie11 texture issue
					// see https://github.com/mrdoob/three.js/issues/7560
					this.overrideVideoTextureMethod();
				}
				this.initComponents();
			}.bind(this));

			this.bind("firstPlay", function () {
				this.attachMotionListeners();
				this.getPlayer().layoutBuilder.removePlayerClickBindings();
				this.add360logo();
			}.bind(this));

			this.bind("playing", function () {
				$(this.video).hide();
				this.render();
			}.bind(this));

			this.bind("doStop onChangeMedia", function () {
				cancelAnimationFrame(this.requestId)
			}.bind(this));

			this.bind("updateLayout", function () {
				if(this.renderer){
					this.renderer.setSize(window.innerWidth, window.innerHeight);
				}
			}.bind(this));

			this.bind('addKeyBindCallback', function (e, addKeyCallback) {
				this.addKeyboardShortcuts(addKeyCallback);
			}.bind(this));
		},

		initComponents: function () {
			// setting up the renderer
			this.renderer = new THREE.WebGLRenderer();
			this.renderer.setSize(window.innerWidth, window.innerHeight);

			this.getPlayer().getVideoDisplay().append(this.renderer.domElement);
			// creating a new scene
			this.scene = new THREE.Scene();

			// adding a camera
			this.camera = new THREE.PerspectiveCamera(this.cameraOptions.fov, this.cameraOptions.aspect, this.cameraOptions.near, this.cameraOptions.far);
			this.camera.target = new THREE.Vector3(0, 0, 0);

			// creation of a big sphere geometry
			var sphere = new THREE.SphereGeometry(100, 100, 40);
			sphere.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
			this.texture = new THREE.VideoTexture(this.video);
			this.texture.minFilter = THREE.LinearFilter;
			this.texture.magFilter = THREE.LinearFilter;

			// creation of the sphere material
			var sphereMaterial = new THREE.MeshBasicMaterial();
			sphereMaterial.map = this.texture;

			// geometry + material = mesh (actual object)
			var sphereMesh = new THREE.Mesh(sphere, sphereMaterial);
			this.scene.add(sphereMesh);
		},

		overrideVideoTextureMethod: function () {
			THREE.VideoTexture = function (video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) {
				var scope = this;

				scope.video = video;
				scope.ctx2d = document.createElement('canvas').getContext('2d');
				var canvas = scope.ctx2d.canvas;
				canvas.width = video.width;
				canvas.height = video.height;

				scope.ctx2d.drawImage(scope.video, 0, 0, scope.width, scope.height);
				THREE.Texture.call(scope, scope.ctx2d.canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);

				scope.generateMipmaps = false;

				function update() {
					requestAnimationFrame(update);
					if (video.readyState >= video.HAVE_CURRENT_DATA) {
						scope.ctx2d.drawImage(scope.video, 0, 0, scope.video.width, scope.video.height);
						scope.needsUpdate = true;
					}
				}

				update();
			};

			THREE.VideoTexture.prototype = Object.create(THREE.Texture.prototype);
			THREE.VideoTexture.prototype.constructor = THREE.VideoTexture;
		},

		updateCamera: function () {
			// limiting latitude from -85 to 85 (cannot point to the sky or under your feet)
			this.latitude = Math.max(-85, Math.min(85, this.latitude));

			// moving the camera according to current latitude (vertical movement) and longitude (horizontal movement)
			this.camera.target.x = 500 * Math.sin(THREE.Math.degToRad(90 - this.latitude)) * Math.cos(THREE.Math.degToRad(this.longitude));
			this.camera.target.y = 500 * Math.cos(THREE.Math.degToRad(90 - this.latitude));
			this.camera.target.z = 500 * Math.sin(THREE.Math.degToRad(90 - this.latitude)) * Math.sin(THREE.Math.degToRad(this.longitude));
			this.camera.lookAt(this.camera.target);
		},

		render: function () {
			if (this.texture && this.video.readyState >= this.video.HAVE_CURRENT_DATA) {
				this.texture.needsUpdate = true;
			}
			this.requestId = requestAnimationFrame(this.render.bind(this));

			this.updateCamera();

			// calling again render function
			this.renderer.render(this.scene, this.camera);
		},

		// when the mouse is pressed, we switch to manual control and save current coordinates
		onDocumentMouseDown: function (event) {
			this.manualControl = true;
			this.savedX = event.clientX || event.originalEvent.touches[0].pageX;
			this.savedY = event.clientY || event.originalEvent.touches[0].pageY;
			this.savedLongitude = this.longitude;
			this.savedLatitude = this.latitude;
		},

		// when the mouse moves, if in manual control we adjust coordinates
		onDocumentMouseMove: function (event) {
			if (this.manualControl) {
				if (event.clientX || event.originalEvent.touches) {
					this.longitude = (this.savedX - (event.clientX || event.originalEvent.touches[0].pageX)) * this.moveMultiplier + this.savedLongitude;
				}
				if (event.clientY || event.originalEvent.touches) {
					this.latitude = ((event.clientY || event.originalEvent.touches[0].pageY) - this.savedY) * this.moveMultiplier + this.savedLatitude;
				}
				event.preventDefault();
			}
		},

		// when the mouse is released, we turn manual control off
		onDocumentMouseUp: function (event) {
			this.manualControl = false;
		},

		onMobileOrientation: function (event) {
			if (event.rotationRate) {
				var x = event.rotationRate.alpha;
				var y = event.rotationRate.beta;
				var portrait = $(top).height() > $(top).width();
				var orientation = event.orientation || window.orientation;

				if (portrait) {
					this.longitude = this.longitude - y * this.mobileVibrationValue;
					this.latitude = this.latitude + x * this.mobileVibrationValue;
				} else { // landscape
					var orientationDegree = -90;
					if (typeof orientation != "undefined") {
						orientationDegree = orientation;
					}
					this.longitude = (orientationDegree == -90) ? this.longitude + x * this.mobileVibrationValue : this.longitude - x * this.mobileVibrationValue;
					this.latitude = (orientationDegree == -90) ? this.latitude + y * this.mobileVibrationValue : this.latitude - y * this.mobileVibrationValue;
				}
			}
		},

		attachMotionListeners: function () {
			$(document).on("mousedown touchstart", this.onDocumentMouseDown.bind(this));
			$(document).on("mousemove touchmove", this.onDocumentMouseMove.bind(this));
			$(document).on("mouseup touchend", this.onDocumentMouseUp.bind(this));
			window.addEventListener('devicemotion', this.onMobileOrientation.bind(this));
		},

		addKeyboardShortcuts: function (addKeyCallback) {
			addKeyCallback(this.keyboardShortcutsMap.left, function () {
				this.longitude -= 10 * this.moveMultiplier;
			}.bind(this));
			addKeyCallback(this.keyboardShortcutsMap.up, function () {
				this.latitude += 10 * this.moveMultiplier;
			}.bind(this));
			addKeyCallback(this.keyboardShortcutsMap.right, function () {
				this.longitude += 10 * this.moveMultiplier;
			}.bind(this));
			addKeyCallback(this.keyboardShortcutsMap.down, function () {
				this.latitude -= 10 * this.moveMultiplier;
			}.bind(this));
		},

		add360logo: function () {
			var logo = $('<div />').addClass('logo360 bottomRight');
			this.getPlayer().getVideoHolder().append(logo);
		}
	}));

	// set EmbedPlayer.WebKitPlaysInline true for iPhone inline playback
	var playerConfig = window.kalturaIframePackageData.playerConfig;
	if (playerConfig) {
		if (!playerConfig.vars) {
			playerConfig.vars = {};
		}
		playerConfig.vars["EmbedPlayer.WebKitPlaysInline"] = true;
		mw.setConfig('KalturaSupport.PlayerConfig', playerConfig);
	}

})(window.mw, window.jQuery, window.THREE);<commit_msg>FEC-6353 #comment remove canvas on change media (#3263)<commit_after>(function (mw, $, THREE) {
	"use strict";

	mw.PluginManager.add('video360', mw.KBasePlugin.extend({

		defaultConfig: {
			moveMultiplier: 0.3,
			mobileVibrationValue: (mw.isIOS() ? 0.0365 : 1),
			cameraOptions:{
				fov: 75,
				aspect: window.innerWidth / window.innerHeight,
				near: 0.1,
				far: 1000
			}
		},
		manualControl: false,
		longitude: 180,
		latitude: 0,
		savedX: 0,
		savedY: 0,
		savedLongitude: 0,
		savedLatitude: 0,
		enableKeyboardShortcuts: true,
		keyboardShortcutsMap: {
			"left":  "65",  // 'A'
			"up":    "87",  // 'W'
			"right": "68",  // 'D'
			"down":  "83"   // 'S'
		},

		isSafeEnviornment: function () {
			return !( mw.isIE8() || mw.isIE9() || mw.isIE10Comp() || // old IEs
				(mw.isIE11() && (mw.getUserOS() === 'Windows 7' || mw.getUserOS() === 'Windows 8')) || // ie11 on win7/8
				(mw.isIphone() && mw.isIOSBelow10()) || // iPhone and IOS < 10 - doesn't support inline playback
				mw.isIOSBelow9() ); // IOS < 9 doesn't support webgl
		},

		setup: function () {
			this.set360Config();
			this.addBindings();
		},

		set360Config:function(){
			//Get user configuration
			var userCameraOptions = this.getConfig("cameraOptions");
			//Deep extend custom config
			this.cameraOptions = $.extend({}, this.defaultConfig.cameraOptions, userCameraOptions);
		},

		addBindings: function () {
			this.bind("playerReady", function () {
				this.moveMultiplier = this.getConfig("moveMultiplier");
				this.mobileVibrationValue = this.getConfig("mobileVibrationValue");
				this.video = this.getPlayer().getPlayerElement();
				this.video.setAttribute('crossorigin', 'anonymous');
				$(this.video).css('z-index', '-1');
				if (mw.isIE11()) {
					// a workaround for ie11 texture issue
					// see https://github.com/mrdoob/three.js/issues/7560
					this.overrideVideoTextureMethod();
				}
				this.initComponents();
			}.bind(this));

			this.bind("firstPlay", function () {
				this.attachMotionListeners();
				this.getPlayer().layoutBuilder.removePlayerClickBindings();
				this.add360logo();
			}.bind(this));

			this.bind("playing", function () {
				$(this.video).hide();
				this.render();
			}.bind(this));

			this.bind("doStop", function () {
				cancelAnimationFrame(this.requestId)
			}.bind(this));

			this.bind("onChangeMedia", function () {
				this.clean();
			}.bind(this));

			this.bind("updateLayout", function () {
				if(this.renderer){
					this.renderer.setSize(window.innerWidth, window.innerHeight);
				}
			}.bind(this));

			this.bind('addKeyBindCallback', function (e, addKeyCallback) {
				this.addKeyboardShortcuts(addKeyCallback);
			}.bind(this));
		},

		initComponents: function () {
			// setting up the renderer
			this.renderer = new THREE.WebGLRenderer();
			this.renderer.setSize(window.innerWidth, window.innerHeight);

			this.getPlayer().getVideoDisplay().append(this.renderer.domElement);
			// creating a new scene
			this.scene = new THREE.Scene();

			// adding a camera
			this.camera = new THREE.PerspectiveCamera(this.cameraOptions.fov, this.cameraOptions.aspect, this.cameraOptions.near, this.cameraOptions.far);
			this.camera.target = new THREE.Vector3(0, 0, 0);

			// creation of a big sphere geometry
			var sphere = new THREE.SphereGeometry(100, 100, 40);
			sphere.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
			this.texture = new THREE.VideoTexture(this.video);
			this.texture.minFilter = THREE.LinearFilter;
			this.texture.magFilter = THREE.LinearFilter;

			// creation of the sphere material
			var sphereMaterial = new THREE.MeshBasicMaterial();
			sphereMaterial.map = this.texture;

			// geometry + material = mesh (actual object)
			var sphereMesh = new THREE.Mesh(sphere, sphereMaterial);
			this.scene.add(sphereMesh);
		},

		overrideVideoTextureMethod: function () {
			THREE.VideoTexture = function (video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) {
				var scope = this;

				scope.video = video;
				scope.ctx2d = document.createElement('canvas').getContext('2d');
				var canvas = scope.ctx2d.canvas;
				canvas.width = video.width;
				canvas.height = video.height;

				scope.ctx2d.drawImage(scope.video, 0, 0, scope.width, scope.height);
				THREE.Texture.call(scope, scope.ctx2d.canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);

				scope.generateMipmaps = false;

				function update() {
					requestAnimationFrame(update);
					if (video.readyState >= video.HAVE_CURRENT_DATA) {
						scope.ctx2d.drawImage(scope.video, 0, 0, scope.video.width, scope.video.height);
						scope.needsUpdate = true;
					}
				}

				update();
			};

			THREE.VideoTexture.prototype = Object.create(THREE.Texture.prototype);
			THREE.VideoTexture.prototype.constructor = THREE.VideoTexture;
		},

		updateCamera: function () {
			// limiting latitude from -85 to 85 (cannot point to the sky or under your feet)
			this.latitude = Math.max(-85, Math.min(85, this.latitude));

			// moving the camera according to current latitude (vertical movement) and longitude (horizontal movement)
			this.camera.target.x = 500 * Math.sin(THREE.Math.degToRad(90 - this.latitude)) * Math.cos(THREE.Math.degToRad(this.longitude));
			this.camera.target.y = 500 * Math.cos(THREE.Math.degToRad(90 - this.latitude));
			this.camera.target.z = 500 * Math.sin(THREE.Math.degToRad(90 - this.latitude)) * Math.sin(THREE.Math.degToRad(this.longitude));
			this.camera.lookAt(this.camera.target);
		},

		render: function () {
			if (this.texture && this.video.readyState >= this.video.HAVE_CURRENT_DATA) {
				this.texture.needsUpdate = true;
			}
			this.requestId = requestAnimationFrame(this.render.bind(this));

			this.updateCamera();

			// calling again render function
			this.renderer.render(this.scene, this.camera);
		},

		// when the mouse is pressed, we switch to manual control and save current coordinates
		onDocumentMouseDown: function (event) {
			this.manualControl = true;
			this.savedX = event.clientX || event.originalEvent.touches[0].pageX;
			this.savedY = event.clientY || event.originalEvent.touches[0].pageY;
			this.savedLongitude = this.longitude;
			this.savedLatitude = this.latitude;
		},

		// when the mouse moves, if in manual control we adjust coordinates
		onDocumentMouseMove: function (event) {
			if (this.manualControl) {
				if (event.clientX || event.originalEvent.touches) {
					this.longitude = (this.savedX - (event.clientX || event.originalEvent.touches[0].pageX)) * this.moveMultiplier + this.savedLongitude;
				}
				if (event.clientY || event.originalEvent.touches) {
					this.latitude = ((event.clientY || event.originalEvent.touches[0].pageY) - this.savedY) * this.moveMultiplier + this.savedLatitude;
				}
				event.preventDefault();
			}
		},

		// when the mouse is released, we turn manual control off
		onDocumentMouseUp: function (event) {
			this.manualControl = false;
		},

		onMobileOrientation: function (event) {
			if (event.rotationRate) {
				var x = event.rotationRate.alpha;
				var y = event.rotationRate.beta;
				var portrait = $(top).height() > $(top).width();
				var orientation = event.orientation || window.orientation;

				if (portrait) {
					this.longitude = this.longitude - y * this.mobileVibrationValue;
					this.latitude = this.latitude + x * this.mobileVibrationValue;
				} else { // landscape
					var orientationDegree = -90;
					if (typeof orientation != "undefined") {
						orientationDegree = orientation;
					}
					this.longitude = (orientationDegree == -90) ? this.longitude + x * this.mobileVibrationValue : this.longitude - x * this.mobileVibrationValue;
					this.latitude = (orientationDegree == -90) ? this.latitude + y * this.mobileVibrationValue : this.latitude - y * this.mobileVibrationValue;
				}
			}
		},

		attachMotionListeners: function () {
			$(document).on("mousedown touchstart", this.onDocumentMouseDown.bind(this));
			$(document).on("mousemove touchmove", this.onDocumentMouseMove.bind(this));
			$(document).on("mouseup touchend", this.onDocumentMouseUp.bind(this));
			window.addEventListener('devicemotion', this.onMobileOrientation.bind(this));
		},

		addKeyboardShortcuts: function (addKeyCallback) {
			addKeyCallback(this.keyboardShortcutsMap.left, function () {
				this.longitude -= 10 * this.moveMultiplier;
			}.bind(this));
			addKeyCallback(this.keyboardShortcutsMap.up, function () {
				this.latitude += 10 * this.moveMultiplier;
			}.bind(this));
			addKeyCallback(this.keyboardShortcutsMap.right, function () {
				this.longitude += 10 * this.moveMultiplier;
			}.bind(this));
			addKeyCallback(this.keyboardShortcutsMap.down, function () {
				this.latitude -= 10 * this.moveMultiplier;
			}.bind(this));
		},

		clean: function(){
			cancelAnimationFrame(this.requestId);
			$(this.renderer.domElement).remove();
		},

		add360logo: function () {
			var logo = $('<div />').addClass('logo360 bottomRight');
			this.getPlayer().getVideoHolder().append(logo);
		}
	}));

	// set EmbedPlayer.WebKitPlaysInline true for iPhone inline playback
	var playerConfig = window.kalturaIframePackageData.playerConfig;
	if (playerConfig) {
		if (!playerConfig.vars) {
			playerConfig.vars = {};
		}
		playerConfig.vars["EmbedPlayer.WebKitPlaysInline"] = true;
		mw.setConfig('KalturaSupport.PlayerConfig', playerConfig);
	}

})(window.mw, window.jQuery, window.THREE);<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import Relay from 'react-relay';
import Pusher from 'pusher-js';
import { Link } from 'react-router';
import ProjectRoute from '../../relay/ProjectRoute';
import ProjectHeader from './ProjectHeader';
import MediasAndAnnotations from '../MediasAndAnnotations';
import TeamSidebar from '../TeamSidebar';
import { CreateMedia } from '../media';
import Can from '../Can';
import config from 'config';

class ProjectComponent extends Component {
  redirect() {
    var path = window.location.protocol + '//' +
               Checkdesk.context.team.subdomain + '.' +
               config.selfHost +
               '/project/' +
               Checkdesk.context.project.dbid;
    window.location.href = path;
  }

  setContextProject() {
    Checkdesk.context.project = this.props.project;
    if (!Checkdesk.context.team || Checkdesk.context.team.subdomain != this.props.project.team.subdomain) {
      Checkdesk.context.team = this.props.project.team;
      // this.redirect();
      Checkdesk.history.push('/404');
    }
    this.props.relay.setVariables({ contextId: Checkdesk.context.project.dbid });
  }

  subscribe() {
    if (window.Checkdesk.pusher) {
      const that = this;
      window.Checkdesk.pusher.subscribe(this.props.project.pusher_channel).bind('media_updated', function(data) {
        that.props.relay.forceFetch();
      });
    }
  }

  unsubscribe() {
    if (window.Checkdesk.pusher) {
      window.Checkdesk.pusher.unsubscribe(this.props.project.pusher_channel);
    }
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  componentDidMount() {
    this.setContextProject();
    this.subscribe();
  }

  componentDidUpdate() {
    this.setContextProject();
  }

  render() {
    const project = this.props.project;
    var that = this;

    return (

{/* className={this.sidebarActiveClass('home__sidebar')} */}
          <TeamSidebar />

          <MediasAndAnnotations
            medias={project.medias.edges}
            annotations={project.annotations.edges}
            annotated={project}
            annotatedType="Project"
            types={['comment']} />

          <Can permissions={project.permissions} permission='create Media'>
            <CreateMedia projectComponent={that} />
          </Can>

    );
  }
}

const ProjectContainer = Relay.createContainer(ProjectComponent, {
  initialVariables: {
    contextId: null
  },
  fragments: {
    project: () => Relay.QL`
      fragment on Project {
        id,
        dbid,
        title,
        description,
        pusher_channel,
        permissions,
        team {
          id,
          dbid,
          subdomain,
          projects(first: 10000) {
            edges {
              node {
                id,
                dbid,
                title
              }
            }
          }
        },
        annotations(first: 10000) {
          edges {
            node {
              id,
              content,
              annotation_type,
              created_at,
              annotator {
                name,
                profile_image
              }
            }
          }
        },
        medias(first: 10000) {
          edges {
            node {
              id,
              dbid,
              url,
              published,
              jsondata,
              annotations_count,
              domain,
              last_status(context_id: $contextId),
              permissions,
              verification_statuses
            }
          }
        }
      }
    `
  }
});

class Project extends Component {
  render() {
    var route = new ProjectRoute({ projectId: this.props.params.projectId });
    return (<Relay.RootContainer Component={ProjectContainer} route={route} />);
  }
}

export default Project;
<commit_msg>Move project create media input to top of page<commit_after>import React, { Component, PropTypes } from 'react';
import Relay from 'react-relay';
import Pusher from 'pusher-js';
import { Link } from 'react-router';
import ProjectRoute from '../../relay/ProjectRoute';
import ProjectHeader from './ProjectHeader';
import MediasAndAnnotations from '../MediasAndAnnotations';
import TeamSidebar from '../TeamSidebar';
import { CreateMedia } from '../media';
import Can from '../Can';
import config from 'config';

class ProjectComponent extends Component {
  redirect() {
    var path = window.location.protocol + '//' +
               Checkdesk.context.team.subdomain + '.' +
               config.selfHost +
               '/project/' +
               Checkdesk.context.project.dbid;
    window.location.href = path;
  }

  setContextProject() {
    Checkdesk.context.project = this.props.project;
    if (!Checkdesk.context.team || Checkdesk.context.team.subdomain != this.props.project.team.subdomain) {
      Checkdesk.context.team = this.props.project.team;
      // this.redirect();
      Checkdesk.history.push('/404');
    }
    this.props.relay.setVariables({ contextId: Checkdesk.context.project.dbid });
  }

  subscribe() {
    if (window.Checkdesk.pusher) {
      const that = this;
      window.Checkdesk.pusher.subscribe(this.props.project.pusher_channel).bind('media_updated', function(data) {
        that.props.relay.forceFetch();
      });
    }
  }

  unsubscribe() {
    if (window.Checkdesk.pusher) {
      window.Checkdesk.pusher.unsubscribe(this.props.project.pusher_channel);
    }
  }

  componentWillUnmount() {
    this.unsubscribe();
  }

  componentDidMount() {
    this.setContextProject();
    this.subscribe();
  }

  componentDidUpdate() {
    this.setContextProject();
  }

  render() {
    const project = this.props.project;
    var that = this;

    return (

{/* className={this.sidebarActiveClass('home__sidebar')} */}
          <TeamSidebar />

          <Can permissions={project.permissions} permission='create Media'>
            <CreateMedia projectComponent={that} />
          </Can>

          <MediasAndAnnotations
            medias={project.medias.edges}
            annotations={project.annotations.edges}
            annotated={project}
            annotatedType="Project"
            types={['comment']} />

    );
  }
}

const ProjectContainer = Relay.createContainer(ProjectComponent, {
  initialVariables: {
    contextId: null
  },
  fragments: {
    project: () => Relay.QL`
      fragment on Project {
        id,
        dbid,
        title,
        description,
        pusher_channel,
        permissions,
        team {
          id,
          dbid,
          subdomain,
          projects(first: 10000) {
            edges {
              node {
                id,
                dbid,
                title
              }
            }
          }
        },
        annotations(first: 10000) {
          edges {
            node {
              id,
              content,
              annotation_type,
              created_at,
              annotator {
                name,
                profile_image
              }
            }
          }
        },
        medias(first: 10000) {
          edges {
            node {
              id,
              dbid,
              url,
              published,
              jsondata,
              annotations_count,
              domain,
              last_status(context_id: $contextId),
              permissions,
              verification_statuses
            }
          }
        }
      }
    `
  }
});

class Project extends Component {
  render() {
    var route = new ProjectRoute({ projectId: this.props.params.projectId });
    return (<Relay.RootContainer Component={ProjectContainer} route={route} />);
  }
}

export default Project;
<|endoftext|>


<commit_before>// 'use strict';

// angular
//   .module('admin')
//   .directive('a', preventClickDirective)
//   .directive('a', bootstrapCollapseDirective)
//   .directive('a', navigationDirective)
//   .directive('button', layoutToggleDirective)
//   .directive('a', layoutToggleDirective)
//   .directive('button', collapseMenuTogglerDirective)
//   .directive('div', bootstrapCarouselDirective)
//   .directive('toggle', bootstrapTooltipsPopoversDirective)
//   .directive('tab', bootstrapTabsDirective)
//   .directive('button', cardCollapseDirective);

// //Prevent click if href="#"
// function preventClickDirective() {
//   var directive = {
//     restrict: 'E',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {
//     if (attrs.href === '#') {
//       element.on('click', function (event) {
//         event.preventDefault();
//       });
//     }
//   }
// }

// //Bootstrap Collapse
// function bootstrapCollapseDirective() {
//   var directive = {
//     restrict: 'E',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {
//     if (attrs.toggle == 'collapse') {
//       element.attr('href', 'javascript;;').attr('data-target', attrs.href.replace('index.html', ''));
//     }
//   }
// }

// /**
// * @desc Genesis main navigation - Siedebar menu
// * @example

// */
// function navigationDirective() {
//   var directive = {
//     restrict: 'E',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {
//     if (element.hasClass('nav-dropdown-toggle') && angular.element('body').width() > 782) {
//       element.on('click', function () {
//         if (!angular.element('body').hasClass('compact-nav')) {
//           element.parent().toggleClass('open').find('.open').removeClass('open');
//         }
//       });
//     } else if (element.hasClass('nav-dropdown-toggle') && angular.element('body').width() < 783) {
//       element.on('click', function () {
//         element.parent().toggleClass('open').find('.open').removeClass('open');
//       });
//     }
//   }
// }

// //Dynamic resize .sidebar-nav
// sidebarNavDynamicResizeDirective.$inject = ['$window', '$timeout'];
// function sidebarNavDynamicResizeDirective($window, $timeout) {
//   var directive = {
//     restrict: 'E',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {

//     if (element.hasClass('sidebar-nav') && angular.element('body').hasClass('fixed-nav')) {
//       var bodyHeight = angular.element(window).height();
//       scope.$watch(function () {
//         var headerHeight = angular.element('header').outerHeight();

//         if (angular.element('body').hasClass('sidebar-off-canvas')) {
//           element.css('height', bodyHeight);
//         } else {
//           element.css('height', bodyHeight - headerHeight);
//         }
//       })

//       angular.element($window).bind('resize', function () {
//         var bodyHeight = angular.element(window).height();
//         var headerHeight = angular.element('header').outerHeight();
//         var sidebarHeaderHeight = angular.element('.sidebar-header').outerHeight();
//         var sidebarFooterHeight = angular.element('.sidebar-footer').outerHeight();

//         if (angular.element('body').hasClass('sidebar-off-canvas')) {
//           element.css('height', bodyHeight - sidebarHeaderHeight - sidebarFooterHeight);
//         } else {
//           element.css('height', bodyHeight - headerHeight - sidebarHeaderHeight - sidebarFooterHeight);
//         }
//       });
//     }
//   }
// }

// //LayoutToggle
// layoutToggleDirective.$inject = ['$interval'];
// function layoutToggleDirective($interval) {
//   var directive = {
//     restrict: 'E',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {
//     element.on('click', function () {

//       if (element.hasClass('sidebar-toggler')) {
//         angular.element('body').toggleClass('sidebar-hidden');
//       }

//       if (element.hasClass('aside-menu-toggler')) {
//         angular.element('body').toggleClass('aside-menu-hidden');
//       }
//     });
//   }
// }

// //Collapse menu toggler
// function collapseMenuTogglerDirective() {
//   var directive = {
//     restrict: 'E',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {
//     element.on('click', function () {
//       if (element.hasClass('navbar-toggler') && !element.hasClass('layout-toggler')) {
//         angular.element('body').toggleClass('sidebar-mobile-show')
//       }
//     })
//   }
// }

// //Bootstrap Carousel
// function bootstrapCarouselDirective() {
//   var directive = {
//     restrict: 'E',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {
//     if (attrs.ride == 'carousel') {
//       element.find('a').each(function () {
//         $(this).attr('data-target', $(this).attr('href').replace('index.html', '')).attr('href', 'javascript;;')
//       });
//     }
//   }
// }

// //Bootstrap Tooltips & Popovers
// function bootstrapTooltipsPopoversDirective() {
//   var directive = {
//     restrict: 'A',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {
//     if (attrs.toggle == 'tooltip') {
//       angular.element(element).tooltip();
//     }
//     if (attrs.toggle == 'popover') {
//       angular.element(element).popover();
//     }
//   }
// }

// //Bootstrap Tabs
// function bootstrapTabsDirective() {
//   var directive = {
//     restrict: 'A',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {
//     element.click(function (e) {
//       e.preventDefault();
//       angular.element(element).tab('show');
//     });
//   }
// }

// //Card Collapse
// function cardCollapseDirective() {
//   var directive = {
//     restrict: 'E',
//     link: link
//   };
//   return directive;

//   function link(scope, element, attrs) {
//     if (attrs.toggle == 'collapse' && element.parent().hasClass('card-actions')) {

//       if (element.parent().parent().parent().find('.card-block').hasClass('in')) {
//         element.find('i').addClass('r180');
//       }

//       var id = 'collapse-' + Math.floor((Math.random() * 1000000000) + 1);
//       element.attr('data-target', '#' + id)
//       element.parent().parent().parent().find('.card-block').attr('id', id);

//       element.on('click', function () {
//         element.find('i').toggleClass('r180');
//       })
//     }
//   }
// }
<commit_msg>Commited from HaNhatLenh at Sat, Jul 22, 2017 12:20:55 PM<commit_after>'use strict';

angular
  .module('admin')
  .directive('a', preventClickDirective)
  .directive('a', bootstrapCollapseDirective)
  .directive('a', navigationDirective)
  .directive('button', layoutToggleDirective)
  .directive('a', layoutToggleDirective)
  .directive('button', collapseMenuTogglerDirective)
  .directive('div', bootstrapCarouselDirective)
  .directive('toggle', bootstrapTooltipsPopoversDirective)
  .directive('tab', bootstrapTabsDirective)
  .directive('button', cardCollapseDirective);

//Prevent click if href="#"
function preventClickDirective() {
  var directive = {
    restrict: 'E',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {
    if (attrs.href === '#') {
      element.on('click', function (event) {
        event.preventDefault();
      });
    }
  }
}

//Bootstrap Collapse
function bootstrapCollapseDirective() {
  var directive = {
    restrict: 'E',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {
    if (attrs.toggle == 'collapse') {
      element.attr('href', 'javascript;;').attr('data-target', attrs.href.replace('index.html', ''));
    }
  }
}

/**
* @desc Genesis main navigation - Siedebar menu
* @example

*/
function navigationDirective() {
  var directive = {
    restrict: 'E',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {
    if (element.hasClass('nav-dropdown-toggle') && angular.element('body').width() > 782) {
      element.on('click', function () {
        if (!angular.element('body').hasClass('compact-nav')) {
          element.parent().toggleClass('open').find('.open').removeClass('open');
        }
      });
    } else if (element.hasClass('nav-dropdown-toggle') && angular.element('body').width() < 783) {
      element.on('click', function () {
        element.parent().toggleClass('open').find('.open').removeClass('open');
      });
    }
  }
}

//Dynamic resize .sidebar-nav
sidebarNavDynamicResizeDirective.$inject = ['$window', '$timeout'];
function sidebarNavDynamicResizeDirective($window, $timeout) {
  var directive = {
    restrict: 'E',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {

    if (element.hasClass('sidebar-nav') && angular.element('body').hasClass('fixed-nav')) {
      var bodyHeight = angular.element(window).height();
      scope.$watch(function () {
        var headerHeight = angular.element('header').outerHeight();

        if (angular.element('body').hasClass('sidebar-off-canvas')) {
          element.css('height', bodyHeight);
        } else {
          element.css('height', bodyHeight - headerHeight);
        }
      })

      angular.element($window).bind('resize', function () {
        var bodyHeight = angular.element(window).height();
        var headerHeight = angular.element('header').outerHeight();
        var sidebarHeaderHeight = angular.element('.sidebar-header').outerHeight();
        var sidebarFooterHeight = angular.element('.sidebar-footer').outerHeight();

        if (angular.element('body').hasClass('sidebar-off-canvas')) {
          element.css('height', bodyHeight - sidebarHeaderHeight - sidebarFooterHeight);
        } else {
          element.css('height', bodyHeight - headerHeight - sidebarHeaderHeight - sidebarFooterHeight);
        }
      });
    }
  }
}

//LayoutToggle
layoutToggleDirective.$inject = ['$interval'];
function layoutToggleDirective($interval) {
  var directive = {
    restrict: 'E',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {
    element.on('click', function () {

      if (element.hasClass('sidebar-toggler')) {
        angular.element('body').toggleClass('sidebar-hidden');
      }

      if (element.hasClass('aside-menu-toggler')) {
        angular.element('body').toggleClass('aside-menu-hidden');
      }
    });
  }
}

//Collapse menu toggler
function collapseMenuTogglerDirective() {
  var directive = {
    restrict: 'E',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {
    element.on('click', function () {
      if (element.hasClass('navbar-toggler') && !element.hasClass('layout-toggler')) {
        angular.element('body').toggleClass('sidebar-mobile-show')
      }
    })
  }
}

//Bootstrap Carousel
function bootstrapCarouselDirective() {
  var directive = {
    restrict: 'E',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {
    if (attrs.ride == 'carousel') {
      element.find('a').each(function () {
        $(this).attr('data-target', $(this).attr('href').replace('index.html', '')).attr('href', 'javascript;;')
      });
    }
  }
}

//Bootstrap Tooltips & Popovers
function bootstrapTooltipsPopoversDirective() {
  var directive = {
    restrict: 'A',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {
    if (attrs.toggle == 'tooltip') {
      angular.element(element).tooltip();
    }
    if (attrs.toggle == 'popover') {
      angular.element(element).popover();
    }
  }
}

//Bootstrap Tabs
function bootstrapTabsDirective() {
  var directive = {
    restrict: 'A',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {
    element.click(function (e) {
      e.preventDefault();
      angular.element(element).tab('show');
    });
  }
}

//Card Collapse
function cardCollapseDirective() {
  var directive = {
    restrict: 'E',
    link: link
  };
  return directive;

  function link(scope, element, attrs) {
    if (attrs.toggle == 'collapse' && element.parent().hasClass('card-actions')) {

      if (element.parent().parent().parent().find('.card-block').hasClass('in')) {
        element.find('i').addClass('r180');
      }

      var id = 'collapse-' + Math.floor((Math.random() * 1000000000) + 1);
      element.attr('data-target', '#' + id)
      element.parent().parent().parent().find('.card-block').attr('id', id);

      element.on('click', function () {
        element.find('i').toggleClass('r180');
      })
    }
  }
}
<|endoftext|>