<commit_before>'use strict'

const path = require('path')
// path.isAbsolute shim for Node.js 0.10 support
const fs = require('graceful-fs')

/**
 * Function that returns two types of paths, one relative to symlink, and one
 * relative to the current working directory. Checks if path is absolute or
 * relative. If the path is relative, this function checks if the path is
 * relative to symlink or relative to current working directory. This is an
 * initiative to find a smarter `srcpath` to supply when building symlinks.
 * This allows you to determine which path to use out of one of three possible
 * types of source paths. The first is an absolute path. This is detected by
 * `path.isAbsolute()`. When an absolute path is provided, it is checked to
 * see if it exists. If it does it's used, if not an error is returned
 * (callback)/ thrown (sync). The other two options for `srcpath` are a
 * relative url. By default Node's `fs.symlink` works by creating a symlink
 * using `dstpath` and expects the `srcpath` to be relative to the newly
 * created symlink. If you provide a `srcpath` that does not exist on the file
 * system it results in a broken symlink. To minimize this, the function
 * checks to see if the 'relative to symlink' source file exists, and if it
 * does it will use it. If it does not, it checks if there's a file that
 * exists that is relative to the current working directory, if does its used.
 * This preserves the expectations of the original fs.symlink spec and adds
 * the ability to pass in `relative to current working direcotry` paths.
 */

function symlinkPaths (srcpath, dstpath, callback) {
  if (path.isAbsolute(srcpath)) {
    return fs.lstat(srcpath, (err, stat) => {
      if (err) {
        err.message = err.message.replace('lstat', 'ensureSymlink')
        return callback(err)
      }
      return callback(null, {
        'toCwd': srcpath,
        'toDst': srcpath
      })
    })
  } else {
    const dstdir = path.dirname(dstpath)
    const relativeToDst = path.join(dstdir, srcpath)
    return fs.exists(relativeToDst, exists => {
      if (exists) {
        return callback(null, {
          'toCwd': relativeToDst,
          'toDst': srcpath
        })
      } else {
        return fs.lstat(srcpath, (err, stat) => {
          if (err) {
            err.message = err.message.replace('lstat', 'ensureSymlink')
            return callback(err)
          }
          return callback(null, {
            'toCwd': srcpath,
            'toDst': path.relative(dstdir, srcpath)
          })
        })
      }
    })
  }
}

function symlinkPathsSync (srcpath, dstpath) {
  let exists
  if (path.isAbsolute(srcpath)) {
    exists = fs.existsSync(srcpath)
    if (!exists) throw new Error('absolute srcpath does not exist')
    return {
      'toCwd': srcpath,
      'toDst': srcpath
    }
  } else {
    const dstdir = path.dirname(dstpath)
    const relativeToDst = path.join(dstdir, srcpath)
    exists = fs.existsSync(relativeToDst)
    if (exists) {
      return {
        'toCwd': relativeToDst,
        'toDst': srcpath
      }
    } else {
      exists = fs.existsSync(srcpath)
      if (!exists) throw new Error('relative srcpath does not exist')
      return {
        'toCwd': srcpath,
        'toDst': path.relative(dstdir, srcpath)
      }
    }
  }
}

module.exports = {
  symlinkPaths,
  symlinkPathsSync
}
<commit_msg>Remove unnecessary comment<commit_after>'use strict'

const path = require('path')
const fs = require('graceful-fs')

/**
 * Function that returns two types of paths, one relative to symlink, and one
 * relative to the current working directory. Checks if path is absolute or
 * relative. If the path is relative, this function checks if the path is
 * relative to symlink or relative to current working directory. This is an
 * initiative to find a smarter `srcpath` to supply when building symlinks.
 * This allows you to determine which path to use out of one of three possible
 * types of source paths. The first is an absolute path. This is detected by
 * `path.isAbsolute()`. When an absolute path is provided, it is checked to
 * see if it exists. If it does it's used, if not an error is returned
 * (callback)/ thrown (sync). The other two options for `srcpath` are a
 * relative url. By default Node's `fs.symlink` works by creating a symlink
 * using `dstpath` and expects the `srcpath` to be relative to the newly
 * created symlink. If you provide a `srcpath` that does not exist on the file
 * system it results in a broken symlink. To minimize this, the function
 * checks to see if the 'relative to symlink' source file exists, and if it
 * does it will use it. If it does not, it checks if there's a file that
 * exists that is relative to the current working directory, if does its used.
 * This preserves the expectations of the original fs.symlink spec and adds
 * the ability to pass in `relative to current working direcotry` paths.
 */

function symlinkPaths (srcpath, dstpath, callback) {
  if (path.isAbsolute(srcpath)) {
    return fs.lstat(srcpath, (err, stat) => {
      if (err) {
        err.message = err.message.replace('lstat', 'ensureSymlink')
        return callback(err)
      }
      return callback(null, {
        'toCwd': srcpath,
        'toDst': srcpath
      })
    })
  } else {
    const dstdir = path.dirname(dstpath)
    const relativeToDst = path.join(dstdir, srcpath)
    return fs.exists(relativeToDst, exists => {
      if (exists) {
        return callback(null, {
          'toCwd': relativeToDst,
          'toDst': srcpath
        })
      } else {
        return fs.lstat(srcpath, (err, stat) => {
          if (err) {
            err.message = err.message.replace('lstat', 'ensureSymlink')
            return callback(err)
          }
          return callback(null, {
            'toCwd': srcpath,
            'toDst': path.relative(dstdir, srcpath)
          })
        })
      }
    })
  }
}

function symlinkPathsSync (srcpath, dstpath) {
  let exists
  if (path.isAbsolute(srcpath)) {
    exists = fs.existsSync(srcpath)
    if (!exists) throw new Error('absolute srcpath does not exist')
    return {
      'toCwd': srcpath,
      'toDst': srcpath
    }
  } else {
    const dstdir = path.dirname(dstpath)
    const relativeToDst = path.join(dstdir, srcpath)
    exists = fs.existsSync(relativeToDst)
    if (exists) {
      return {
        'toCwd': relativeToDst,
        'toDst': srcpath
      }
    } else {
      exists = fs.existsSync(srcpath)
      if (!exists) throw new Error('relative srcpath does not exist')
      return {
        'toCwd': srcpath,
        'toDst': path.relative(dstdir, srcpath)
      }
    }
  }
}

module.exports = {
  symlinkPaths,
  symlinkPathsSync
}
<|endoftext|>


<commit_before>// Load in dependencies
var rocambole = require('rocambole');
var rocamboleToken = require('rocambole-token');

// Handle setting of options
var options;
exports.setOptions = function (_options) {
  options = _options;
};

// Define our transform function
exports._transformNode = function (node) {
  // If the token is not a variable declaration (e.g. `var`, `let`), exit early
  // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
  // interface VariableDeclaration <: Declaration {
  //     type: "VariableDeclaration";
  //     declarations: [ VariableDeclarator ];
  //     kind: "var" | "let" | "const";
  // }
  // interface VariableDeclarator <: Node {
  //   type: "VariableDeclarator";
  //   id: Pattern;
  //   init: Expression | null;
  // }
  if (node.type !== 'VariableDeclaration') {
    return node;
  }

  // If we are inside of a loop, do nothing (e.g. `for`, `while`, `do ... while`)
  // DEV: Technically, a while/dowhile can't have a `var` but this is for good measure
  var parentType = node.parent ? node.parent.type : '';
  if (parentType.match(/WhileStatement|DoWhileStatement|ForStatement|ForInStatement/)) {
    return node;
  }

  // Determine the terminating character
  // Example: `var foo = bar;`
  //   varDeclaration = {type: VariableDeclaration, declarations: [...], kind: 'var'}
  //   declarators[*] = {type: VariableDeclarator, id: {type: Identifier, name: 'foo'}, init: {type: Literal, value: 'bar'}}
  var varDeclaration = node;
  var declarators = varDeclaration.declarations;

  // Find the head and tail of the var declaration for reuse among its declaration clones
  // e.g. `var hello = 'world', goodbye = 'moon';` -> ['var', ' '] = starting tokens; ['hello = world'] = declaration; ...; [';'] = endToken
  var startingTokens = [];
  rocamboleToken.eachInBetween(varDeclaration.startToken, declarators[0].startToken.prev, function saveToken (token) {
    startingTokens.push(token);
  });
  var endingTokens = [];
  rocamboleToken.eachInBetween(declarators[declarators.length - 1].endToken.next, varDeclaration.endToken, function saveToken (token) {
    endingTokens.push(token);
  });

  // Generate a `var` for each of the declarators
  // e.g. `var hello = 'world', goodbye = 'moon';` -> `var hello = 'world'; var goodbye = 'moon';`
  var declarations = [];
  declarators.forEach(function generateDeclaration (declarator, index) {
    // DEV: A brief refresher on nodes and tokens
    //   Nodes are the AST representation of parts of a program (e.g. Identifier, VariableDeclaration)
    //   Tokens are the actual chunks of code these represent (e.g. Keyword, WhiteSpace)
    //   Tokens can be present without there being a node related to them
    //   Nodes have a prev (previous node on the same level), next (next node on the same level),
    //     parent (node containing our node), and sometimes something like a `body` key where they declare child nodes
    //     `body` varies from node type to node type
    //   Tokens don't have levels but are one giant chain
    //   Tokens have next (next token to render), prev (previous token to render),
    //     root (root node of the entire token chain -- i.e. a Program node)
    //   Nodes also have startToken and endToken which are the tokens that a node will start/end on
    //     (e.g. `var` is the start token for a VariableDeclaration)
    //   The only attachment from tokens to nodes is via `range` but this is brittle in rocambole so avoid it

    // Generate a new declaration similar to the original
    // Example: `var hello = 'world', goodbye = 'moon';` should use `var` and have a trailing semicolon `;`
    // https://github.com/millermedeiros/rocambole/blob/a3d0d63d58b769d13bad288aca32c6e2f7766542/rocambole.js#L69-L74
    var declaration = {
      type: varDeclaration.type, // should always be `VariableDeclaration`
      declarations: [declarator],
      kind: varDeclaration.kind, // (e.g. `var`, `let`)
      toString: varDeclaration.toString
      // prev: bound later
      // next: bound later
      // startToken: bound later
      // endToken: bound later
    };

    // Copy the token chains for our varDeclaration onto the current declaration
    // TODO: Abstract me to `cloneTokenChain: tokens, options: {root}`
    var newStartingTokens = [];
    startingTokens.forEach(function copyTokenChain (token, index) {
      // Clone our token
      var newToken = {
        type: token.type, // e.g. Keyword, Whitespace
        value: token.value, // e.g. 'var', ' '
        root: varDeclaration.parent, // e.g. Program node
        next: undefined,
        prev: undefined
      };

      // If this is the first token, save on the declaration itself
      if (index === 0) {
        declaration.startToken = newToken;
      // Otherwise, connect to the previous token
      } else {
        var lastToken = newStartingTokens[index - 1];
        lastToken.next = newToken;
        newToken.prev = lastToken;
      }

      // Save our tokens
      newStartingTokens.push(newToken);
    });
    var newEndingTokens = [];
    endingTokens.forEach(function copyTokenChain (token, index) {
      // Clone our token
      var newToken = {
        type: token.type, // e.g. Keyword, Whitespace
        value: token.value, // e.g. 'var', ' '
        root: varDeclaration.parent, // e.g. Program node
        next: undefined,
        prev: undefined
      };

      // If this is the last token, save on the declaration itself
      if (index === endingTokens.length - 1) {
        declaration.endToken = newToken;
      }

      // If there is a previous token, connect to it
      if (index > 1) {
        var lastToken = newEndingTokens[index - 1];
        lastToken.next = newToken;
        newToken.prev = lastToken;
      }

      // Save our tokens
      newEndingTokens.push(newToken);
    });

    // Attach declarator's starts/ends to our declaration
    //   Handle node
    declarator.parent = declaration;
    //   Handle tokens
    declarator.startToken.prev = newStartingTokens[newStartingTokens.length - 1];
    newStartingTokens[newStartingTokens.length - 1].next = declarator.startToken;
    declarator.endToken.next = newEndingTokens[0];
    newEndingTokens[0].prev = declarator.endToken;

    // If this is the first declaration, replace the previous node/token of the original declaration
    if (index === 0) {
      // Replace nodes
      var varDeclarationPrevNode = varDeclaration.prev;
      if (varDeclarationPrevNode) {
        varDeclarationPrevNode.next = declaration;
        declaration.prev = varDeclarationPrevNode;
      }

      // Replace tokens
      // https://github.com/millermedeiros/rocambole-token/blob/fc03674b38f288dc545db0a5b2bdfd2d96cab170/remove.js#L10-L23
      var varDeclarationPrevToken = varDeclaration.startToken.prev;
      if (varDeclarationPrevToken) {
        varDeclarationPrevToken.next = declaration.startToken;
        declaration.startToken.prev = varDeclarationPrevToken;
      } else if (varDeclaration.startToken.root) {
        var varDeclarationRootNode = varDeclaration.startToken.root;
        varDeclarationRootNode.startToken = declaration.startToken;
      }
    // Otherwise, connect this to the previous declaration
    } else {
      // Attach nodes
      var lastDeclaration = declarations[index - 1];
      lastDeclaration.next = declaration;
      declaration.prev = lastDeclaration;

      // Attach tokens
      // TODO: If there's padding between sections (e.g. new line and indent), then add that here
      lastDeclaration.endToken.next = declaration.startToken;
      declaration.startToken.prev = lastDeclaration.endToken;
    }

    // If this is the last declaration, replace the next node/token of the original declaration
    // DEV: There is no otherwise case as we take care of that when linking to "previous" declarations
    if (index === declarators.length - 1) {
      // Replace nodes
      var varDeclarationNextNode = varDeclaration.next;
      if (varDeclarationNextNode) {
        varDeclarationNextNode.prev = declaration;
        declaration.next = varDeclarationNextNode;
      }

      // Replace tokens
      // https://github.com/millermedeiros/rocambole-token/blob/fc03674b38f288dc545db0a5b2bdfd2d96cab170/remove.js#L10-L23
      var varDeclarationNextToken = varDeclaration.endToken.next;
      if (varDeclarationNextToken) {
        varDeclarationNextToken.prev = declaration.endToken;
        declaration.endToken.next = varDeclarationNextToken;
      } else if (varDeclaration.endToken.root) {
        var varDeclarationRootNode = varDeclaration.endToken.root;
        varDeclarationRootNode.endToken = declaration.endToken;
      }
    }

    // Return the declaration
    declarations.push(declaration);
  });

  // Swap the declarations in the `body` of the parent block statement
  // e.g. `BlockStatement.body = [{orig VariableDeclaration}, some other expressions]`
  //     -> `BlockStatement.body = [{new VariableDeclaration}, {another new VariableDeclaration}, some other expressions]`
  var varDeclarationParentNode = varDeclaration.parent;
  var varDeclarationParentBodyIndex = varDeclarationParentNode.body.indexOf(varDeclaration);
  varDeclarationParentNode.body.splice(varDeclarationParentBodyIndex, 1, declarations);

  console.log('FINAL', node.parent.toString());

  // Return the updated node
  return node;
};

// Export our transformation
// https://github.com/millermedeiros/esformatter/tree/v0.4.3#transformbeforeast
exports.transform = function (ast) {
  rocambole.moonwalk(ast, exports._transformNode);
};
<commit_msg>Fixing up root<commit_after>// Load in dependencies
var rocambole = require('rocambole');
var rocamboleToken = require('rocambole-token');

// Handle setting of options
var options;
exports.setOptions = function (_options) {
  options = _options;
};

// Define our transform function
exports._transformNode = function (node) {
  // If the token is not a variable declaration (e.g. `var`, `let`), exit early
  // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
  // interface VariableDeclaration <: Declaration {
  //     type: "VariableDeclaration";
  //     declarations: [ VariableDeclarator ];
  //     kind: "var" | "let" | "const";
  // }
  // interface VariableDeclarator <: Node {
  //   type: "VariableDeclarator";
  //   id: Pattern;
  //   init: Expression | null;
  // }
  if (node.type !== 'VariableDeclaration') {
    return node;
  }

  // If we are inside of a loop, do nothing (e.g. `for`, `while`, `do ... while`)
  // DEV: Technically, a while/dowhile can't have a `var` but this is for good measure
  var parentType = node.parent ? node.parent.type : '';
  if (parentType.match(/WhileStatement|DoWhileStatement|ForStatement|ForInStatement/)) {
    return node;
  }

  // Determine the terminating character
  // Example: `var foo = bar;`
  //   varDeclaration = {type: VariableDeclaration, declarations: [...], kind: 'var'}
  //   declarators[*] = {type: VariableDeclarator, id: {type: Identifier, name: 'foo'}, init: {type: Literal, value: 'bar'}}
  var varDeclaration = node;
  var declarators = varDeclaration.declarations;

  // Find the head and tail of the var declaration for reuse among its declaration clones
  // e.g. `var hello = 'world', goodbye = 'moon';` -> ['var', ' '] = starting tokens; ['hello = world'] = declaration; ...; [';'] = endToken
  var startingTokens = [];
  rocamboleToken.eachInBetween(varDeclaration.startToken, declarators[0].startToken.prev, function saveToken (token) {
    startingTokens.push(token);
  });
  var endingTokens = [];
  rocamboleToken.eachInBetween(declarators[declarators.length - 1].endToken.next, varDeclaration.endToken, function saveToken (token) {
    endingTokens.push(token);
  });

  // Generate a `var` for each of the declarators
  // e.g. `var hello = 'world', goodbye = 'moon';` -> `var hello = 'world'; var goodbye = 'moon';`
  var declarations = [];
  declarators.forEach(function generateDeclaration (declarator, index) {
    // DEV: A brief refresher on nodes and tokens
    //   Nodes are the AST representation of parts of a program (e.g. Identifier, VariableDeclaration)
    //   Tokens are the actual chunks of code these represent (e.g. Keyword, WhiteSpace)
    //   Tokens can be present without there being a node related to them
    //   Nodes have a prev (previous node on the same level), next (next node on the same level),
    //     parent (node containing our node), and sometimes something like a `body` key where they declare child nodes
    //     `body` varies from node type to node type
    //   Tokens don't have levels but are one giant chain
    //   Tokens have next (next token to render), prev (previous token to render),
    //     root (root node of the entire token chain -- i.e. a Program node)
    //   Nodes also have startToken and endToken which are the tokens that a node will start/end on
    //     (e.g. `var` is the start token for a VariableDeclaration)
    //   The only attachment from tokens to nodes is via `range` but this is brittle in rocambole so avoid it

    // Generate a new declaration similar to the original
    // Example: `var hello = 'world', goodbye = 'moon';` should use `var` and have a trailing semicolon `;`
    // https://github.com/millermedeiros/rocambole/blob/a3d0d63d58b769d13bad288aca32c6e2f7766542/rocambole.js#L69-L74
    var declaration = {
      type: varDeclaration.type, // should always be `VariableDeclaration`
      declarations: [declarator],
      kind: varDeclaration.kind, // (e.g. `var`, `let`)
      toString: varDeclaration.toString
      // prev: bound later
      // next: bound later
      // startToken: bound later
      // endToken: bound later
    };

    // Copy the token chains for our varDeclaration onto the current declaration
    // TODO: Abstract me to `cloneTokenChain: tokens, options: {root}`
    var newStartingTokens = [];
    startingTokens.forEach(function copyTokenChain (token, index) {
      // Clone our token
      var newToken = {
        type: token.type, // e.g. Keyword, Whitespace
        value: token.value, // e.g. 'var', ' '
        root: token.root, // e.g. Program node
        next: undefined,
        prev: undefined
      };

      // If this is the first token, save on the declaration itself
      if (index === 0) {
        declaration.startToken = newToken;
      // Otherwise, connect to the previous token
      } else {
        var lastToken = newStartingTokens[index - 1];
        lastToken.next = newToken;
        newToken.prev = lastToken;
      }

      // Save our tokens
      newStartingTokens.push(newToken);
    });
    var newEndingTokens = [];
    endingTokens.forEach(function copyTokenChain (token, index) {
      // Clone our token
      var newToken = {
        type: token.type, // e.g. Keyword, Whitespace
        value: token.value, // e.g. 'var', ' '
        root: token.root, // e.g. Program node
        next: undefined,
        prev: undefined
      };

      // If this is the last token, save on the declaration itself
      if (index === endingTokens.length - 1) {
        declaration.endToken = newToken;
      }

      // If there is a previous token, connect to it
      if (index > 1) {
        var lastToken = newEndingTokens[index - 1];
        lastToken.next = newToken;
        newToken.prev = lastToken;
      }

      // Save our tokens
      newEndingTokens.push(newToken);
    });

    // Attach declarator's starts/ends to our declaration
    //   Handle node
    declarator.parent = declaration;
    //   Handle tokens
    declarator.startToken.prev = newStartingTokens[newStartingTokens.length - 1];
    newStartingTokens[newStartingTokens.length - 1].next = declarator.startToken;
    declarator.endToken.next = newEndingTokens[0];
    newEndingTokens[0].prev = declarator.endToken;

    // If this is the first declaration, replace the previous node/token of the original declaration
    if (index === 0) {
      // Replace nodes
      var varDeclarationPrevNode = varDeclaration.prev;
      if (varDeclarationPrevNode) {
        varDeclarationPrevNode.next = declaration;
        declaration.prev = varDeclarationPrevNode;
      }

      // Replace tokens
      // https://github.com/millermedeiros/rocambole-token/blob/fc03674b38f288dc545db0a5b2bdfd2d96cab170/remove.js#L10-L23
      var varDeclarationPrevToken = varDeclaration.startToken.prev;
      if (varDeclarationPrevToken) {
        varDeclarationPrevToken.next = declaration.startToken;
        declaration.startToken.prev = varDeclarationPrevToken;
      } else if (varDeclaration.startToken.root) {
        var varDeclarationRootNode = varDeclaration.startToken.root;
        varDeclarationRootNode.startToken = declaration.startToken;
      }
    // Otherwise, connect this to the previous declaration
    } else {
      // Attach nodes
      var lastDeclaration = declarations[index - 1];
      lastDeclaration.next = declaration;
      declaration.prev = lastDeclaration;

      // Attach tokens
      // TODO: If there's padding between sections (e.g. new line and indent), then add that here
      lastDeclaration.endToken.next = declaration.startToken;
      declaration.startToken.prev = lastDeclaration.endToken;
    }

    // If this is the last declaration, replace the next node/token of the original declaration
    // DEV: There is no otherwise case as we take care of that when linking to "previous" declarations
    if (index === declarators.length - 1) {
      // Replace nodes
      var varDeclarationNextNode = varDeclaration.next;
      if (varDeclarationNextNode) {
        varDeclarationNextNode.prev = declaration;
        declaration.next = varDeclarationNextNode;
      }

      // Replace tokens
      // https://github.com/millermedeiros/rocambole-token/blob/fc03674b38f288dc545db0a5b2bdfd2d96cab170/remove.js#L10-L23
      var varDeclarationNextToken = varDeclaration.endToken.next;
      if (varDeclarationNextToken) {
        varDeclarationNextToken.prev = declaration.endToken;
        declaration.endToken.next = varDeclarationNextToken;
      } else if (varDeclaration.endToken.root) {
        var varDeclarationRootNode = varDeclaration.endToken.root;
        varDeclarationRootNode.endToken = declaration.endToken;
      }
    }

    // Return the declaration
    declarations.push(declaration);
  });

  // Swap the declarations in the `body` of the parent block statement
  // e.g. `BlockStatement.body = [{orig VariableDeclaration}, some other expressions]`
  //     -> `BlockStatement.body = [{new VariableDeclaration}, {another new VariableDeclaration}, some other expressions]`
  var varDeclarationParentNode = varDeclaration.parent;
  var varDeclarationParentBodyIndex = varDeclarationParentNode.body.indexOf(varDeclaration);
  varDeclarationParentNode.body.splice(varDeclarationParentBodyIndex, 1, declarations);

  console.log('FINAL', node.parent.toString());

  // Return the updated node
  return node;
};

// Export our transformation
// https://github.com/millermedeiros/esformatter/tree/v0.4.3#transformbeforeast
exports.transform = function (ast) {
  rocambole.moonwalk(ast, exports._transformNode);
};
<|endoftext|>


<commit_before>/**
 * An video object return by create('video');
 * Use it to manipulate a video (crop and filters comming in futur)
 * @param {object} videoDescriptor an object return by internal sdk
 */
UT.Video = function(videoDescriptor) {

	/**
	 * The url of the video
	 * @type {String}
	 */
	this.url = "";

	/**
	 * A string containing the type of this media,
	 * Aka "video" here
	 * @type {String}
	 */
	this.type = 'video';

	this.marshall = function(){
		descriptor.url = this.url;
		descriptor._type = 'video';
		return descriptor;
	};

	// Private methods
	// LOOK AWAY!
	// Use to on this interface with Urturn API
	function _buildVideo(videoDescriptor) {
		this.url = videoDescriptor.url;
		descriptor = videoDescriptor;
	}
	var descriptor = {};
	// init !
	_buildVideo.call(this, videoDescriptor);
};<commit_msg>appData for video<commit_after>/**
 * An video object return by create('video');
 * Use it to manipulate a video (crop and filters comming in futur)
 * @param {object} videoDescriptor an object return by internal sdk
 */
UT.Video = function(videoDescriptor) {

	/**
	 * The url of the video
	 * @type {String}
	 */
	this.url = "";

	/**
	 * A string containing the type of this media,
	 * Aka "video" here
	 * @type {String}
	 */
	this.type = 'video';

	this.marshall = function(){
		descriptor.url = this.url;
		descriptor._type = 'video';
		descriptor.appData = this.appData;
		return descriptor;
	};

	// Private methods
	// LOOK AWAY!
	// Use to on this interface with Urturn API
	function _buildVideo(videoDescriptor) {
		this.url = videoDescriptor.url;
		this.appData = videoDescriptor.appData;
		descriptor = videoDescriptor;
	}
	var descriptor = {};
	// init !
	_buildVideo.call(this, videoDescriptor);
};<|endoftext|>


<commit_before>ig.module('game.entities.zombie')
.requires(
  'impact.impact',
  'impact.entity',
  'game.entities.particle-spawner',
  'game.effects.zombie-giblet',
  'game.effects.blood-giblet',
  'game.entities.dead-zombie'
)
.defines(function() {
  EntityZombie = ig.Entity.extend({
    // don't allow the editor to scale our object
    _wmScalable: false,

    // always draw a box around us
    _wmDrawBox: true,
    _wmBoxColor: 'rgba(255, 170, 66, 0.7)',

    pointValue: 100,

    animSheet: new ig.AnimationSheet( 'media/zombie.png', 32, 32 ),
    zIndex: 9,

    // the size of our collider
    size: { x: 8, y: 32 },

    health: 9,
    maxHealth: 9,

    deathEntity: EntityDeadZombie,

    // the offset of collider
    offset: { x: 12, y: 0 },

    // movement variables
    maxVel: { x: 6, y: 100 },
    friction: { x: 2000, y: 2000 },
    accel: { x: 0, y: 0 },
    gravityFactor: 10,

    speed: 2000,

    // collision settings, collide against player
    type: ig.Entity.TYPE.B,
    checkAgainst: ig.Entity.TYPE.A,
    collides: ig.Entity.COLLIDES.PASSIVE,

    init: function( x, y, settings ) {
      this.parent( x, y, settings );

      // setup animations
      // true means do not repeat
      // idle is a system animation, called by default
      this.addAnim( 'idle', 3, [0], true);
      this.addAnim( 'walk', 0.3, [1,2,3,4,5,6,7,8]);

      this.flip = settings.flip || false;
    },

    kill: function() {
      // when the zombie dies, spawn a bunch of "giblets"
      var pos = {
        x: this.pos.x + this.size.x / 2,
        y: this.pos.y + this.size.y / 2
      };
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectZombieGiblet,
        particles: 5
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectBloodGiblet,
        particles: 3
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectZombieGibletSmall,
        particles: 30
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectBloodGibletSmall,
        particles: 10
      });

      ig.game.spawnEntity( this.deathEntity, this.pos.x, this.pos.y, {
        flip: this.flip
      });

      // increase the players score
      if(this.lastDamageAmount < this.maxHealth) {
        // player shot too far away from the zombie
        // so they won't get as many points
        this.pointValue /= 2;
      }
      ig.game.hud.addPoints(this.pointValue);

      this.parent();
    },

    receiveDamage: function(amt, other) {
      this.parent(amt, other);
      this.lastDamageAmount = amt;

      ig.game.spawnEntity( EntityParticleSpawner, other.pos.x, other.pos.y, {
        Particle: EffectZombieGibletSmall,
        particles: ig._.rndRange(3, 7)
      });
    },

    check: function(other) {
      // when a zombie hits the player
      // the player should take damage
      other.receiveDamage(10, this);
    },

    update: function() {
      if ( this.vel.x != 0 ) {
        this.currentAnim = this.anims.walk;
      }

      this.accel.x = this.speed * (this.flip ? -1 : 1);
      this.currentAnim.flip.x = this.flip;

      this.parent();
    },

    handleMovementTrace: function( res ) {
      this.parent(res);

      // check the collision map, see if we're colliding with
      // a collision tile, if so then we need to turn around
      if( res.collision.x ) {
        this.flip = !this.flip;
      }
    }
  });
});
<commit_msg>rm useless vert friction from zombie<commit_after>ig.module('game.entities.zombie')
.requires(
  'impact.impact',
  'impact.entity',
  'game.entities.particle-spawner',
  'game.effects.zombie-giblet',
  'game.effects.blood-giblet',
  'game.entities.dead-zombie'
)
.defines(function() {
  EntityZombie = ig.Entity.extend({
    // don't allow the editor to scale our object
    _wmScalable: false,

    // always draw a box around us
    _wmDrawBox: true,
    _wmBoxColor: 'rgba(255, 170, 66, 0.7)',

    pointValue: 100,

    animSheet: new ig.AnimationSheet( 'media/zombie.png', 32, 32 ),
    zIndex: 9,

    // the size of our collider
    size: { x: 8, y: 32 },

    health: 9,
    maxHealth: 9,

    deathEntity: EntityDeadZombie,

    // the offset of collider
    offset: { x: 12, y: 0 },

    // movement variables
    maxVel: { x: 6, y: 100 },
    friction: { x: 2000, y: 0 },
    accel: { x: 0, y: 0 },
    gravityFactor: 10,

    speed: 2000,

    // collision settings, collide against player
    type: ig.Entity.TYPE.B,
    checkAgainst: ig.Entity.TYPE.A,
    collides: ig.Entity.COLLIDES.PASSIVE,

    init: function( x, y, settings ) {
      this.parent( x, y, settings );

      // setup animations
      // true means do not repeat
      // idle is a system animation, called by default
      this.addAnim( 'idle', 3, [0], true);
      this.addAnim( 'walk', 0.3, [1,2,3,4,5,6,7,8]);

      this.flip = settings.flip || false;
    },

    kill: function() {
      // when the zombie dies, spawn a bunch of "giblets"
      var pos = {
        x: this.pos.x + this.size.x / 2,
        y: this.pos.y + this.size.y / 2
      };
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectZombieGiblet,
        particles: 5
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectBloodGiblet,
        particles: 3
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectZombieGibletSmall,
        particles: 30
      });
      ig.game.spawnEntity( EntityParticleSpawner, pos.x, pos.y, {
        Particle: EffectBloodGibletSmall,
        particles: 10
      });

      ig.game.spawnEntity( this.deathEntity, this.pos.x, this.pos.y, {
        flip: this.flip
      });

      // increase the players score
      if(this.lastDamageAmount < this.maxHealth) {
        // player shot too far away from the zombie
        // so they won't get as many points
        this.pointValue /= 2;
      }
      ig.game.hud.addPoints(this.pointValue);

      this.parent();
    },

    receiveDamage: function(amt, other) {
      this.parent(amt, other);
      this.lastDamageAmount = amt;

      ig.game.spawnEntity( EntityParticleSpawner, other.pos.x, other.pos.y, {
        Particle: EffectZombieGibletSmall,
        particles: ig._.rndRange(3, 7)
      });
    },

    check: function(other) {
      // when a zombie hits the player
      // the player should take damage
      other.receiveDamage(10, this);
    },

    update: function() {
      if ( this.vel.x != 0 ) {
        this.currentAnim = this.anims.walk;
      }

      this.accel.x = this.speed * (this.flip ? -1 : 1);
      this.currentAnim.flip.x = this.flip;

      this.parent();
    },

    handleMovementTrace: function( res ) {
      this.parent(res);

      // check the collision map, see if we're colliding with
      // a collision tile, if so then we need to turn around
      if( res.collision.x ) {
        this.flip = !this.flip;
      }
    }
  });
});
<|endoftext|>


<commit_before>import _ from 'lodash';
import Scroll from 'react-scroll';

export const handleMessageUtility = (state, message, socket) => {
    const newState = _.cloneDeep(state);

    if (message.type instanceof Error) {
        newState.submitError = message.type.message;
        return newState;
    }

    // no error -> handle message
    newState.submitError = null;

    if (message.type === 'nick') {
        socket.emit('SET_NAME', message.args.join(' '));
    }
    if (message.type === 'oops') {
        const lastMessageId = newState.messageIds[newState.messageIds.length - 1];
        if (lastMessageId) {
            newState.messages.splice(newState.messages.findIndex((message) => message.id === lastMessageId), 1);
            socket.emit('REMOVE_MESSAGE', lastMessageId);
            newState.messageIds.pop();
        }

    }
    else if (message.type === 'countdown') {
        socket.emit('COUNTDOWN', message.args);
    }
    else if (message.type === 'fadelast') {
        // client-side only
        const lastMessageId = newState.messageIds[newState.messageIds.length - 1];

        if (lastMessageId) {
            const lastMessage = newState.messages.findIndex((message) => message.id === lastMessageId);
            lastMessage.css.fontSize = '1.1em';
            // better than css filters for cross-browser support
            lastMessage.css.color = 'hsl(0, 100%, 10%)'; //
        }
    }
    else if (message.type === 'plain' || message.type === 'think') {
        // normal message (eventually with styling)
        let styles = {};
        let content = message.content;

        if (message.type === 'think') {
            styles.color = '#2f4f4f';
            content = message.args.join(' ');
        }

        const id = new Date().getUTCMilliseconds();
        const newMessage = {
            id,
            content,
            author: 'me',
            css: styles,
            sending: true,
        };
        newState.messageIds.push(id);

        newState.messages.push(newMessage);
        newState.lastMessageSent = false;

        // notify WS
        socket.emit('INCOMING_MESSAGE', newMessage);
    }

    Scroll.animateScroll.scrollToBottom();

    return newState;
};
<commit_msg>fadelast command (complete) - session paused<commit_after>import _ from 'lodash';
import Scroll from 'react-scroll';

export const handleMessageUtility = (state, message, socket) => {
    const newState = _.cloneDeep(state);

    if (message.type instanceof Error) {
        newState.submitError = message.type.message;
        return newState;
    }

    // no error -> handle message
    newState.submitError = null;

    if (message.type === 'nick') {
        socket.emit('SET_NAME', message.args.join(' '));
    }
    if (message.type === 'oops') {
        const lastMessageId = newState.messageIds[newState.messageIds.length - 1];
        if (lastMessageId) {
            newState.messages.splice(newState.messages.findIndex((message) => message.id === lastMessageId), 1);
            socket.emit('REMOVE_MESSAGE', lastMessageId);
            newState.messageIds.pop();
        }

    }
    else if (message.type === 'countdown') {
        socket.emit('COUNTDOWN', message.args);
    }
    else if (message.type === 'fadelast') {
        // client-side only
        const lastMessageId = newState.messageIds[newState.messageIds.length - 1];

        if (lastMessageId) {
            const lastMessage = newState.messages.find((message) => message.id === lastMessageId);

            if (lastMessage) {
                lastMessage.css.fontSize = '1.1em';
                lastMessage.css.filter = 'brightness(90%)';
            }
        }
    }
    else if (message.type === 'plain' || message.type === 'think') {
        // normal message (eventually with styling)
        let styles = {};
        let content = message.content;

        if (message.type === 'think') {
            styles.color = '#2f4f4f';
            content = message.args.join(' ');
        }

        const id = new Date().getUTCMilliseconds();
        const newMessage = {
            id,
            content,
            author: 'me',
            css: styles,
            sending: true,
        };
        newState.messageIds.push(id);

        newState.messages.push(newMessage);
        newState.lastMessageSent = false;

        // notify WS
        socket.emit('INCOMING_MESSAGE', newMessage);
    }

    Scroll.animateScroll.scrollToBottom();

    return newState;
};
<|endoftext|>


<commit_before>/*
== BSD2 LICENSE ==
Copyright (c) 2014, Tidepool Project

This program is free software; you can redistribute it and/or modify it under
the terms of the associated License, which is identical to the BSD 2-Clause
License as published by the Open Source Initiative at opensource.org.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the License for more details.

You should have received a copy of the License along with this program; if
not, you can obtain one from Tidepool Project at tidepool.org.
== BSD2 LICENSE ==
 */

'use strict';

var mongojs = require('mongojs'),
    groupsCollection,
    dependencyStatus = { running: false, deps: { up: [], down: [] } },
    groupsCollectionName = 'groups',
    log = require('../log.js')('mongoHandler.js')

/*
    Handler CRUD opertaions via Mongo instance
*/
var mongoHandler = function(connectionString) {

    var dbInstance = mongojs(connectionString, [groupsCollectionName]);
    groupsCollection = dbInstance.collection(groupsCollectionName);

    return {
        status : status,
        createGroup : handleCreateGroup,
        findGroupsPatientIn : handleFindGroupsPatientIn,
        findGroupsMemberOf : handleFindGroupsMemberOf,
        findGroupsOwnerOf : handleFindGroupsOwnerOf,
        addUserToGroup : handleAddUserToGroup,
        removeUserFromGroup : handleRemoveUserFromGroup,
        findPatientForGroup : handleFindPatientForGroup
    };
};

/*
    With mongo we change to use the id field
*/
function setGroup(doc){
    var group = {};
    group.id = doc._id;
    group.owners = doc.owners;
    group.members = doc.members;
    group.patient = doc.patient;
    group.name = doc.name;
    return group;
}

function status(callback){
    log.debug('checking status');
    dependencyStatus.running = (dependencyStatus.deps.down.length === 0);
    dependencyStatus.statuscode = dependencyStatus.running ? 200 : 500;
    return callback(null,dependencyStatus)
}

function handleCreateGroup (group,callback) {
    log.debug('Create in mongo group[%j]', group);

    groupsCollection.save(group, function(error, doc) {
        if (error) {
            return callback(error,null);
        } else {
            return callback(null, doc._id);
        }
    });
}

function handleFindGroupsMemberOf(userId,callback) {

    log.debug('Finding groups member of userid[%s]', userId);
    groupsCollection.find({ $or: [
        { owners : userId },
        { members : userId },
        { patient : userId }
    ]},
    function(error,doc){
        if (error) {
            return callback(error,null);
        } else {
            var groups = [];
            doc.forEach(function(item){
                groups.push(setGroup(item));
            });
            return callback(null,groups);
        }
    });
}

function handleFindGroupsOwnerOf(userId,callback) {
    log.debug('Finding groups owned by userid[%s]', userId);
    groupsCollection.find(
        { owners : userId }
    , function(error,doc){
        if (error) {
            return callback(error,null);
        } else {
            var groups = [];
            doc.forEach(function(item){
                groups.push(setGroup(item));
            });
            return callback(null,groups);
        }
    });
}

function handleFindGroupsPatientIn(userId,callback) {
    log.debug('Finding groups patient[%s] is in', userId);
    groupsCollection.find(
        { patient :userId },
        function(error,doc){
            if (error) {
                return callback(error,null);
            }

            var groups = [];
            doc.forEach(function(item){
                groups.push(setGroup(item));
            });
            return callback(null,groups);
        }
    );
}

function handleAddUserToGroup(groupId, userId, callback) {
    log.debug('Adding user[%s] to group[%s]', userId, groupId);

    groupsCollection.findAndModify({
        query: { _id : mongojs.ObjectId(groupId) },
        update: { $push : { members : userId } }, //add the user to the members array
        new : true //we are using new : true to return the updated group
    },
    function(error, doc) {
        if (error) {
            return callback(error,null);
        }

        log.debug('Update [%j] groups by adding user[%s]', doc, userId);
        return callback(null,setGroup(doc));
    });
}

function handleRemoveUserFromGroup(groupId, userId, callback) {
    log.debug('Removing user[%s] from group[%s]', userId, groupId);

    groupsCollection.findAndModify({
        query: { _id : mongojs.ObjectId(groupId) },
        update: { $pull : { members : userId , owners : userId } }, //remove user from these
        new : true //using new : true to return the updated group
    },
    function(error, doc) {
        if (error) {
            return callback(error,null);
        }

        log.debug('Update [%j] groups by removing user[%s]', doc, userId);

        return callback(null,setGroup(doc));
    });
}

function handleFindPatientForGroup(groupId, callback) {
    log.debug('Finding patient for group[%s]', groupId);

    groupsCollection.findOne(
        { _id : mongojs.ObjectId(groupId) },
        function(error, doc) {
            if (error) {
                return callback(error,null);
            }
            return callback(null,doc.patient);
        }
    );
}

module.exports = mongoHandler;
<commit_msg>step three remove from handler<commit_after>/*
== BSD2 LICENSE ==
Copyright (c) 2014, Tidepool Project

This program is free software; you can redistribute it and/or modify it under
the terms of the associated License, which is identical to the BSD 2-Clause
License as published by the Open Source Initiative at opensource.org.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the License for more details.

You should have received a copy of the License along with this program; if
not, you can obtain one from Tidepool Project at tidepool.org.
== BSD2 LICENSE ==
 */

'use strict';

var mongojs = require('mongojs'),
    groupsCollection,
    dependencyStatus = { running: false, deps: { up: [], down: [] } },
    groupsCollectionName = 'groups',
    log = require('../log.js')('mongoHandler.js')

/*
    Handler CRUD opertaions via Mongo instance
*/
var mongoHandler = function(connectionString) {

    var dbInstance = mongojs(connectionString, [groupsCollectionName]);
    groupsCollection = dbInstance.collection(groupsCollectionName);

    return {
        status : status,
        createGroup : handleCreateGroup,
        findGroupsMemberOf : handleFindGroupsMemberOf,
        addUserToGroup : handleAddUserToGroup,
        removeUserFromGroup : handleRemoveUserFromGroup
    };
};

/*
    With mongo we change to use the id field
*/
function setGroup(doc){
    var group = {};
    group.id = doc._id;
    group.members = doc.members;
    return group;
}

function status(callback){
    log.debug('checking status');
    dependencyStatus.running = (dependencyStatus.deps.down.length === 0);
    dependencyStatus.statuscode = dependencyStatus.running ? 200 : 500;
    return callback(null,dependencyStatus)
}

function handleCreateGroup (group,callback) {
    log.debug('Create in mongo group[%j]', group);

    groupsCollection.save(group, function(error, doc) {
        if (error) {
            return callback(error,null);
        } else {
            return callback(null, doc._id);
        }
    });
}

function handleFindGroupsMemberOf(userId,callback) {

    log.debug('Finding groups member of userid[%s]', userId);
    groupsCollection.find({ $or: [
        { members : userId }
    ]},
    function(error,doc){
        if (error) {
            return callback(error,null);
        } else {
            var groups = [];
            doc.forEach(function(item){
                groups.push(setGroup(item));
            });
            return callback(null,groups);
        }
    });
}

function handleAddUserToGroup(groupId, userId, callback) {
    log.debug('Adding user[%s] to group[%s]', userId, groupId);

    groupsCollection.findAndModify({
        query: { _id : mongojs.ObjectId(groupId) },
        update: { $push : { members : userId } }, //add the user to the members array
        new : true //we are using new : true to return the updated group
    },
    function(error, doc) {
        if (error) {
            return callback(error,null);
        }

        log.debug('Update [%j] groups by adding user[%s]', doc, userId);
        return callback(null,setGroup(doc));
    });
}

function handleRemoveUserFromGroup(groupId, userId, callback) {
    log.debug('Removing user[%s] from group[%s]', userId, groupId);

    groupsCollection.findAndModify({
        query: { _id : mongojs.ObjectId(groupId) },
        update: { $pull : { members : userId } }, //remove user from these
        new : true //using new : true to return the updated group
    },
    function(error, doc) {
        if (error) {
            return callback(error,null);
        }

        log.debug('Update [%j] groups by removing user[%s]', doc, userId);

        return callback(null,setGroup(doc));
    });
}

module.exports = mongoHandler;
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var path = require('path'),
  _ = require('lodash');

/**
 * Adds res.view() method (an enhanced version of res.render) to response object.
 * `res.view()` automatically renders the appropriate view based on the calling middleware's source route
 * Note: the original function is still accessible via res.render()
 *
 * @param {Request}  req
 * @param {Response} res
 * @param {Function} next
 */

module.exports = function _addResViewMethod(req, res, next) {

  var sails = req._sails;

  /**
   * res.view([specifiedPath|locals], [locals])
   *
   * @param {String} specifiedPath
   *				-> path to the view file to load (minus the file extension)
   *					relative to the app's `views` directory
   * @param {Object} locals
   *				-> view locals (data that is accessible in the view template)
   * @param {Function} cb_view(err)
   *				-> called when the view rendering is complete (response is already sent, or in the process)
   *					(probably should be @api private)
   * @api public
   */
  res.view = function(specifiedPath, locals, cb_view) {

    sails.log.verbose('Running res.view(' + (specifiedPath ? specifiedPath : '') + ')...');

    // By default, generate a path to the view using what we know about the controller+action
    var relPathToView;

    // Ensure req.target is an object, then merge it into req.options
    // (this helps ensure backwards compatibility for users who were relying
    //  on `req.target` in previous versions of Sails)
    req.options = _.defaults(req.options, req.target || {});

    // Try to guess the view by looking at the controller/action
    if (!req.options.view) {
      relPathToView = req.options.controller + '/' + req.options.action;
    }
    // Use the new view config
    else relPathToView = req.options.view;

    // Now we have a reasonable guess in `relPathToView`

    // If the path to a view was explicitly specified, use that
    // Serve the view specified
    //
    // If first arg is not an object, treat it like the path
    if (specifiedPath && !_.isObject(specifiedPath)) {
      relPathToView = specifiedPath;
    }
    // If first arg ISSSSS AN object, treat it like locals
    else if (_.isObject(specifiedPath)) {

      // If the "locals" argument is actually the "specifiedPath"
      // give em the old switcheroo
      relPathToView = locals || relPathToView;
      locals = specifiedPath;
    }

    // Ensure specifiedPath is a string (important)
    relPathToView = '' + relPathToView + '';

    // Ensure `locals` is an object
    locals = _.isObject(locals) ? locals : {};

    // Mixin locals from req.options
    if (req.options.locals) {
      locals = _.merge(locals, req.options.locals);
    }

    // Merge with config views locals
    if (sails.config.views.locals) {
      _.merge(locals, sails.config.views.locals, _.defaults);
    }

    // If the path was specified, but invalid
    // else if (specifiedPath) {
    // 	return res.serverError(new Error('Specified path for view (' + specifiedPath + ') is invalid!'));
    // }

    // Trim trailing slash
    if (relPathToView[(relPathToView.length - 1)] === '/') {
      relPathToView = relPathToView.slice(0, -1);
    }

    // if local `layout` is set to true or unspecified
    // fall back to global config
    var layout = locals.layout;
    if (locals.layout === undefined || locals.layout === true) {
      layout = sails.config.views.layout;
    }

    // Disable sails built-in layouts for all view engine's except for ejs
    if (sails.config.views.engine.ext !== 'ejs') {
      layout = false;
    }

    // Allow `res.locals.layout` to override if it was set:
    if (typeof res.locals.layout !== 'undefined') {
      layout = res.locals.layout;
    }

    var pathToViews = sails.config.paths.views;
    var absPathToView = path.join(pathToViews, relPathToView);
    var absPathToLayout;
    var relPathToLayout;

    // Ensure layout is a string by this point
    if (typeof layout !== 'string') {
      layout = false;
    }

    // Set layout file if enabled (using ejs-locals)
    if (layout) {

      // Solve relative path to layout from the view itself
      // (required by ejs-locals module)
      absPathToLayout = path.join(pathToViews, layout);
      relPathToLayout = path.relative(path.dirname(absPathToView), absPathToLayout);

      // If a layout was specified, set view local so it will be used
      res.locals._layoutFile = relPathToLayout;
      sails.log.silly('Using layout at: ', absPathToLayout);
    }

    // Locals passed in to `res.view()` override app and route locals.
    _.each(locals, function(local, key) {
      res.locals[key] = local;
    });

    // Provide access to view metadata in locals
    // (for convenience)
    res.locals.view = res.locals.view || {
      path: relPathToView,
      absPath: absPathToView,
      pathFromViews: relPathToView,
      pathFromApp: path.join(path.relative(sails.config.appPath, sails.config.paths.views), relPathToView),
      ext: sails.config.views.engine.ext
    };

    // In development, provide access to complete path to view via `__dirname` local.
    if (sails.config.environment !== 'production') {
      res.locals.__dirname = res.locals.__dirname ||
        absPathToView + '.' + sails.config.views.engine.ext;
    }

    // Render the view
    if (specifiedPath) {
      sails.log.silly('View override argument passed to res.view(): ', specifiedPath);
    }
    sails.log.silly('Serving view at rel path: ', relPathToView);
    sails.log.silly('View root: ', sails.config.paths.views);
    return res.render(relPathToView, locals, function renderView(err, renderedViewStr) {

      // if a template error occurred, don't rely on any of the Sails request/response methods
      // (since they may not exist yet at this point in the request lifecycle.)
      if (err) {
        sails.log.error('Error rendering view at ::', absPathToView);
        sails.log.error('with layout located at ::', absPathToLayout);
        sails.log.error(err && err.message);
        if (process.env.NODE_ENV === 'development') {
          return res.json(500, err);
        } else return res.send(500);
      }

      if (layout) {
        sails.log.verbose('Using layout: ', absPathToLayout);
      }
      sails.log.verbose('Rendering view ::', relPathToView, '(located @ ' + absPathToView + ')');

      // Backwards compatibility:
      // trigger `res.view` callback if specified
      // (before sending the response)
      if (cb_view) {
        sails.log.warn(
          'Callback function of `res.view([relativePathToView], [options], [cb])`',
          ' will be deprecated in an upcoming release.'
        );
        cb_view(err);
      }

      // Finally, send the view down to the client
      res.send(renderedViewStr);

      // Express version updates should be closely monitored.
      // Express is a "hard" dependency.
      //
      // While unlikely this will change, it's worth noting that this implementation
      // relies on express's private implementation of res.render() here:
      // https://github.com/visionmedia/express/blob/master/lib/response.js#L799
      //
      // To be safe, the version of the Express dependency in package.json will remain locked
      // until it can be verified that each subsequent version is compatible.  Even patch releases!!
    });

  };

  next();
};
<commit_msg>Use `res.serverError` to display view errors, if it exists.<commit_after>/**
 * Module dependencies
 */

var path = require('path'),
  _ = require('lodash');

/**
 * Adds res.view() method (an enhanced version of res.render) to response object.
 * `res.view()` automatically renders the appropriate view based on the calling middleware's source route
 * Note: the original function is still accessible via res.render()
 *
 * @param {Request}  req
 * @param {Response} res
 * @param {Function} next
 */

module.exports = function _addResViewMethod(req, res, next) {

  var sails = req._sails;

  /**
   * res.view([specifiedPath|locals], [locals])
   *
   * @param {String} specifiedPath
   *				-> path to the view file to load (minus the file extension)
   *					relative to the app's `views` directory
   * @param {Object} locals
   *				-> view locals (data that is accessible in the view template)
   * @param {Function} cb_view(err)
   *				-> called when the view rendering is complete (response is already sent, or in the process)
   *					(probably should be @api private)
   * @api public
   */
  res.view = function(specifiedPath, locals, cb_view) {

    sails.log.verbose('Running res.view(' + (specifiedPath ? specifiedPath : '') + ')...');

    // By default, generate a path to the view using what we know about the controller+action
    var relPathToView;

    // Ensure req.target is an object, then merge it into req.options
    // (this helps ensure backwards compatibility for users who were relying
    //  on `req.target` in previous versions of Sails)
    req.options = _.defaults(req.options, req.target || {});

    // Try to guess the view by looking at the controller/action
    if (!req.options.view) {
      relPathToView = req.options.controller + '/' + req.options.action;
    }
    // Use the new view config
    else relPathToView = req.options.view;

    // Now we have a reasonable guess in `relPathToView`

    // If the path to a view was explicitly specified, use that
    // Serve the view specified
    //
    // If first arg is not an object, treat it like the path
    if (specifiedPath && !_.isObject(specifiedPath)) {
      relPathToView = specifiedPath;
    }
    // If first arg ISSSSS AN object, treat it like locals
    else if (_.isObject(specifiedPath)) {

      // If the "locals" argument is actually the "specifiedPath"
      // give em the old switcheroo
      relPathToView = locals || relPathToView;
      locals = specifiedPath;
    }

    // Ensure specifiedPath is a string (important)
    relPathToView = '' + relPathToView + '';

    // Ensure `locals` is an object
    locals = _.isObject(locals) ? locals : {};

    // Mixin locals from req.options
    if (req.options.locals) {
      locals = _.merge(locals, req.options.locals);
    }

    // Merge with config views locals
    if (sails.config.views.locals) {
      _.merge(locals, sails.config.views.locals, _.defaults);
    }

    // If the path was specified, but invalid
    // else if (specifiedPath) {
    // 	return res.serverError(new Error('Specified path for view (' + specifiedPath + ') is invalid!'));
    // }

    // Trim trailing slash
    if (relPathToView[(relPathToView.length - 1)] === '/') {
      relPathToView = relPathToView.slice(0, -1);
    }

    // if local `layout` is set to true or unspecified
    // fall back to global config
    var layout = locals.layout;
    if (locals.layout === undefined || locals.layout === true) {
      layout = sails.config.views.layout;
    }

    // Disable sails built-in layouts for all view engine's except for ejs
    if (sails.config.views.engine.ext !== 'ejs') {
      layout = false;
    }

    // Allow `res.locals.layout` to override if it was set:
    if (typeof res.locals.layout !== 'undefined') {
      layout = res.locals.layout;
    }

    var pathToViews = sails.config.paths.views;
    var absPathToView = path.join(pathToViews, relPathToView);
    var absPathToLayout;
    var relPathToLayout;

    // Ensure layout is a string by this point
    if (typeof layout !== 'string') {
      layout = false;
    }

    // Set layout file if enabled (using ejs-locals)
    if (layout) {

      // Solve relative path to layout from the view itself
      // (required by ejs-locals module)
      absPathToLayout = path.join(pathToViews, layout);
      relPathToLayout = path.relative(path.dirname(absPathToView), absPathToLayout);

      // If a layout was specified, set view local so it will be used
      res.locals._layoutFile = relPathToLayout;
      sails.log.silly('Using layout at: ', absPathToLayout);
    }

    // Locals passed in to `res.view()` override app and route locals.
    _.each(locals, function(local, key) {
      res.locals[key] = local;
    });

    // Provide access to view metadata in locals
    // (for convenience)
    res.locals.view = res.locals.view || {
      path: relPathToView,
      absPath: absPathToView,
      pathFromViews: relPathToView,
      pathFromApp: path.join(path.relative(sails.config.appPath, sails.config.paths.views), relPathToView),
      ext: sails.config.views.engine.ext
    };

    // In development, provide access to complete path to view via `__dirname` local.
    if (sails.config.environment !== 'production') {
      res.locals.__dirname = res.locals.__dirname ||
        absPathToView + '.' + sails.config.views.engine.ext;
    }

    // Render the view
    if (specifiedPath) {
      sails.log.silly('View override argument passed to res.view(): ', specifiedPath);
    }
    sails.log.silly('Serving view at rel path: ', relPathToView);
    sails.log.silly('View root: ', sails.config.paths.views);
    return res.render(relPathToView, locals, function renderView(err, renderedViewStr) {

      // if a template error occurred, don't rely on any of the Sails request/response methods
      // (since they may not exist yet at this point in the request lifecycle.)
      if (err) {
        sails.log.error('Error rendering view at ::', absPathToView);
        sails.log.error('with layout located at ::', absPathToLayout);
        sails.log.error(err && err.message);
        if (res.serverError) {
          return res.serverError(err.message);
        }
        else if (process.env.NODE_ENV === 'development') {
          return res.json(500, err);
        } else return res.send(500);
      }

      if (layout) {
        sails.log.verbose('Using layout: ', absPathToLayout);
      }
      sails.log.verbose('Rendering view ::', relPathToView, '(located @ ' + absPathToView + ')');

      // Backwards compatibility:
      // trigger `res.view` callback if specified
      // (before sending the response)
      if (cb_view) {
        sails.log.warn(
          'Callback function of `res.view([relativePathToView], [options], [cb])`',
          ' will be deprecated in an upcoming release.'
        );
        cb_view(err);
      }

      // Finally, send the view down to the client
      res.send(renderedViewStr);

      // Express version updates should be closely monitored.
      // Express is a "hard" dependency.
      //
      // While unlikely this will change, it's worth noting that this implementation
      // relies on express's private implementation of res.render() here:
      // https://github.com/visionmedia/express/blob/master/lib/response.js#L799
      //
      // To be safe, the version of the Express dependency in package.json will remain locked
      // until it can be verified that each subsequent version is compatible.  Even patch releases!!
    });

  };

  next();
};
<|endoftext|>


<commit_before>/* Note: Firefox tests work up until version 58. After that, Selenium has a problem:
         POST /session/14641de4c7f12c2f9b2eaf307a0955edf23dc59b/timeouts/async_script did not match a known command
         No combination of browserstack.geckodriver and browserstack.selenium_version that worked was found.
         The solution is to call mochify with `--async-polling false`. */

const travisBuild = process.env.TRAVIS_BUILD_NUMBER
const build = travisBuild ? `travis/${travisBuild.padStart(5, '0')}` : `manual ${new Date().toISOString()}`
console.log(`build: ${build}`)

const capabilitiesBase = {
  project: 'Toryt contracts',
  build: build,
  'browserstack.console': 'verbose',
  'browserstack.user': process.env.BROWSERSTACK_USERNAME,
  'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY
}

const osVersion = {
  'OS X': 'High Sierra',
  Windows: '10'
}

/* We only test the last version of every combination, by not specifying any version.
   By running the tests every week, we stay compatible. */

/* NOTE:
    Safari eats stack traces in Web Driver mode (not when tested manually), and skips stack frames in general.
    Safari on iOS does very weird things with sometimes not setting a prototype property on new (non arrow) functions,
    or setting them 'late'. Some workarounds in tests are provided for this.

    Firefox only works with with `--async-polling false`.
    In general, runs on all browsers are more stable with `--async-polling false` (though a tad slower).

    Edge has trouble with the contract function name (test workaround)
 */

const desktop = [
  { browser: 'Chrome', os: 'OS X' },
  { browser: 'Safari', os: 'OS X' },
  { browser: 'Firefox', os: 'OS X' },
  { browser: 'Chrome', os: 'Windows' },
  { browser: 'Edge', os: 'Windows' },
  { browser: 'Firefox', os: 'Windows' }
].map(d => ({
  name: `${d.browser} - ${d.os}`,
  capabilities: Object.assign(d, capabilitiesBase, {
    os_version: osVersion[d.os]
  })
}))
const mobile = ['Samsung Galaxy S9', 'Samsung Galaxy Note 4', 'iPhone X', 'iPad Pro'].map(m => ({
  name: m,
  capabilities: Object.assign(
    {
      device: m,
      real_mobile: true
    },
    capabilitiesBase
  )
}))

const definitions = desktop.concat(mobile)
console.log(`${definitions.length}:`, definitions.map(d => d.name).join(', '))

module.exports = {
  hostname: 'hub-cloud.browserstack.com',
  port: 80,
  browsers: definitions
}
<commit_msg>test on Mojave<commit_after>/* Note: Firefox tests work up until version 58. After that, Selenium has a problem:
         POST /session/14641de4c7f12c2f9b2eaf307a0955edf23dc59b/timeouts/async_script did not match a known command
         No combination of browserstack.geckodriver and browserstack.selenium_version that worked was found.
         The solution is to call mochify with `--async-polling false`. */

const travisBuild = process.env.TRAVIS_BUILD_NUMBER
const build = travisBuild ? `travis/${travisBuild.padStart(5, '0')}` : `manual ${new Date().toISOString()}`
console.log(`build: ${build}`)

const capabilitiesBase = {
  project: 'Toryt contracts',
  build: build,
  'browserstack.console': 'verbose',
  'browserstack.user': process.env.BROWSERSTACK_USERNAME,
  'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY
}

const osVersion = {
  'OS X': 'Mojave',
  Windows: '10'
}

/* We only test the last version of every combination, by not specifying any version.
   By running the tests every week, we stay compatible. */

/* NOTE:
    Safari eats stack traces in Web Driver mode (not when tested manually), and skips stack frames in general.
    Safari on iOS does very weird things with sometimes not setting a prototype property on new (non arrow) functions,
    or setting them 'late'. Some workarounds in tests are provided for this.

    Firefox only works with with `--async-polling false`.
    In general, runs on all browsers are more stable with `--async-polling false` (though a tad slower).

    Edge has trouble with the contract function name (test workaround)
 */

const desktop = [
  { browser: 'Chrome', os: 'OS X' },
  { browser: 'Safari', os: 'OS X' },
  { browser: 'Firefox', os: 'OS X' },
  { browser: 'Chrome', os: 'Windows' },
  { browser: 'Edge', os: 'Windows' },
  { browser: 'Firefox', os: 'Windows' }
].map(d => ({
  name: `${d.browser} - ${d.os}`,
  capabilities: Object.assign(d, capabilitiesBase, {
    os_version: osVersion[d.os]
  })
}))
const mobile = ['Samsung Galaxy S9', 'Samsung Galaxy Note 4', 'iPhone X', 'iPad Pro'].map(m => ({
  name: m,
  capabilities: Object.assign(
    {
      device: m,
      real_mobile: true
    },
    capabilitiesBase
  )
}))

const definitions = desktop.concat(mobile)
console.log(`${definitions.length}:`, definitions.map(d => d.name).join(', '))

module.exports = {
  hostname: 'hub-cloud.browserstack.com',
  port: 80,
  browsers: definitions
}
<|endoftext|>


<commit_before>var angularVersion;
for(var i=0; i<process.argv.length;i++){
  if(process.argv[i].indexOf('--angular-version=') !== -1){
    angularVersion = process.argv[i].replace('--angular-version=','');
  }
}

console.log(module.exports);
var port;
for(var i=0; i<process.argv.length;i++){
  if(process.argv[i].indexOf('--port=') !== -1){
    port = process.argv[i].replace('--port=','');
  }
}

if(!port) {
  throw new Error('Port is not defined');
}

var angularVersions = [
  '1.0.8',
  '1.2.9',
  '1.3.11',
  '1.4.0'
];

var sauceLabsBrowsers = [
  // {name: 'internet explorer', version: 11, platform: 'Windows 8.1'},
  // {name: 'internet explorer', version: 10, platform: 'Windows 8'},
  // {name: 'internet explorer', version: 9, platform: 'Windows 7'},
  // {name: 'internet explorer', version: 8, platform: 'Windows XP'},
  {name: 'chrome'},
  {name: 'firefox'},
  {name: 'opera'},
  {name: 'safari', version: 8, platform: 'OS X 10.10'},
  {name: 'safari', version: 7, platform: 'OS X 10.9'},
  {name: 'safari', version: 6, platform: 'OS X 10.8'},
  {name: 'iphone', version: '8.1', platform: 'OS X 10.10'},
  {name: 'iphone', version: '7.1', platform: 'OS X 10.10'},
  {name: 'iphone', version: '6.1', platform: 'OS X 10.8'},
  {name: 'android', version: '5.0'},
  {name: 'android', version: '4.4'},
  {name: 'android', version: '4.3'},
]

var config = {
  before_tests: './scripts/before_tests',
  on_exit: 'rm -r .tmp/ || echo "tried cleaning up but could not"',
  src_files: [
    'src/*.coffee',
    'tests/*.coffee'
  ],
  launch_in_ci: [],
  launch_in_dev: []
};

if(!angularVersion) {
  config.launchers = {};
  config.serve_files = [];
  angularVersions.forEach(function(version){
    var key = 'Angular ' + version
    config.launchers[key] = {
      command: 'testem ci --port=11'+version.replace(/\./g,'').slice(0,3)+' --file .testem.js -- --angular-version='+version,
      protocol: 'tap'
    }
    config.launch_in_ci.push(key);
  });
} else {
  config.launchers = {};
  sauceLabsBrowsers.forEach(function(browser){
    var key = ['SauceLabs', browser.name, browser.version].join(' ');
    var command = ['saucie', '--port="'+port+'"']
    command.push('--browserNameSL="'+browser.name+'"')
    if(browser.version){
      command.push('--versionSL="'+browser.version+'"')
    }
    if(browser.platform){
      command.push('--platformSL="'+browser.platform+'"')
    }
    config.launchers[key] = {
      command: command.join(' '),
      protocol: 'tap'
    };
    config.launch_in_ci.push(key);
  });
  config.serve_files= [
    'bower_components/angular-'+angularVersion+'/angular.js',
    '.tmp/src/*.js',
    'bower_components/angular-mocks-'+angularVersion+'/angular-mocks.js',
    '.tmp/tests/*.js'
  ]
}

console.log(config);

module.exports = config;
<commit_msg>add timeout of 1 minute<commit_after>var angularVersion;
for(var i=0; i<process.argv.length;i++){
  if(process.argv[i].indexOf('--angular-version=') !== -1){
    angularVersion = process.argv[i].replace('--angular-version=','');
  }
}

console.log(module.exports);
var port;
for(var i=0; i<process.argv.length;i++){
  if(process.argv[i].indexOf('--port=') !== -1){
    port = process.argv[i].replace('--port=','');
  }
}

if(!port) {
  throw new Error('Port is not defined');
}

var angularVersions = [
  '1.0.8',
  '1.2.9',
  '1.3.11',
  '1.4.0'
];

var sauceLabsBrowsers = [
  // {name: 'internet explorer', version: 11, platform: 'Windows 8.1'},
  // {name: 'internet explorer', version: 10, platform: 'Windows 8'},
  // {name: 'internet explorer', version: 9, platform: 'Windows 7'},
  // {name: 'internet explorer', version: 8, platform: 'Windows XP'},
  {name: 'chrome'},
  {name: 'firefox'},
  {name: 'opera'},
  {name: 'safari', version: 8, platform: 'OS X 10.10'},
  {name: 'safari', version: 7, platform: 'OS X 10.9'},
  {name: 'safari', version: 6, platform: 'OS X 10.8'},
  {name: 'iphone', version: '8.1', platform: 'OS X 10.10'},
  {name: 'iphone', version: '7.1', platform: 'OS X 10.10'},
  {name: 'iphone', version: '6.1', platform: 'OS X 10.8'},
  {name: 'android', version: '5.0'},
  {name: 'android', version: '4.4'},
  {name: 'android', version: '4.3'},
]

var config = {
  before_tests: './scripts/before_tests',
  on_exit: 'rm -r .tmp/ || echo "tried cleaning up but could not"',
  src_files: [
    'src/*.coffee',
    'tests/*.coffee'
  ],
  timeout: 60 * 1000,
  launch_in_ci: [],
  launch_in_dev: []
};

if(!angularVersion) {
  config.launchers = {};
  config.serve_files = [];
  angularVersions.forEach(function(version){
    var key = 'Angular ' + version
    config.launchers[key] = {
      command: 'testem ci --port=11'+version.replace(/\./g,'').slice(0,3)+' --file .testem.js -- --angular-version='+version,
      protocol: 'tap'
    }
    config.launch_in_ci.push(key);
  });
} else {
  config.launchers = {};
  sauceLabsBrowsers.forEach(function(browser){
    var key = ['SauceLabs', browser.name, browser.version].join(' ');
    var command = ['saucie', '--port="'+port+'"']
    command.push('--browserNameSL="'+browser.name+'"')
    if(browser.version){
      command.push('--versionSL="'+browser.version+'"')
    }
    if(browser.platform){
      command.push('--platformSL="'+browser.platform+'"')
    }
    config.launchers[key] = {
      command: command.join(' '),
      protocol: 'tap'
    };
    config.launch_in_ci.push(key);
  });
  config.serve_files= [
    'bower_components/angular-'+angularVersion+'/angular.js',
    '.tmp/src/*.js',
    'bower_components/angular-mocks-'+angularVersion+'/angular-mocks.js',
    '.tmp/tests/*.js'
  ]
}

console.log(config);

module.exports = config;
<|endoftext|>