<commit_before>/**
 * Copyright 2012 Thanasis Polychronakis. Some Rights Reserved.
 *
 * 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
 *
 * =======================
 *
 * closureBuilder.js Combines and optionally compiles javascript files
 *
 * Call from grunt as:
 */
var gruntConfig = {
  closureDepsWriter: {
     // any name that describes your operation
    targetName: {
      // [Required] To find the depswriter executable we need either the path to
      //    closure library or directly the filepath to the depswriter:
      closureLibraryPath: 'path/to/closure-library', // path to closure library
      depswriter: 'path/to/depswriter.py', // filepath to depswriter

      // [Optional] Set file targets. Can be a string, array or
      //    grunt file syntax (<config:...> or *)
      files: 'path/to/awesome.js',

      // [Optional] If not set, will output to stdout
      output_file: '',

      options: {
        // [Optional] Root directory to scan. Can be string or array
        root: ['source/ss', 'source/closure-library', 'source/showcase'],

        // [Optional] Root with prefix takes a pair of strings separated with a space,
        //    so proper way to use it is to suround with quotes.
        //    can be a string or array
        root_with_prefix: '"source/ss ../../ss"',

        // [Optional] string or array
        path_with_depspath: ''
      }
    }
  }
};

var fs = require('fs');

// path to depswriter from closure lib path
var DEPSWRITER = '/closure/bin/build/depswriter.py';

module.exports = function(grunt) {
  grunt.registerMultiTask('closureDepsWriter', 'Google Closure Library Dependency Calculator script', function() {

    var data = this.data;
    var done = this.async();

    //
    // Validations
    // - Check required parameters
    //
    var params = validate(grunt, data);
    if (false === params) {
      return false;
    }

    //
    // Prepare and compile the command string we will execute
    //
    var command = compileCommand(grunt, params, data);

    if (false === command) {
      return false;
    }

    // execute the task
    grunt.helper('executeCommand', command, done);

  });

};

/**
 * Perform validations for given options
 *
 * @return {boolean|Object} false if error
 */
function validate(grunt, data)
{
  // check for closure lib path
  var lib = data.closureLibraryPath;
  var depswriter;
  if (!lib) {
    // check for direct assignment of depswriter script
    depswriter = data.depswriter;
    if (!depswriter) {
      grunt.log.error('ERROR'.red + ' :: ' + 'closureLibraryPath'.red + ' or ' + 'depswriter'.red + ' properties are required');
      return false;
    }
  } else {
    depswriter = lib + DEPSWRITER;
  }

  depswriter = grunt.file.expandFiles(depswriter).shift();

  // ---
  // check depswriter existence
  // ---
  var fileExists = false;
  try {
      if (fs.lstatSync(depswriter).isFile()) {
        fileExists = true;
      }
  }
  catch (e) {}
  if (!fileExists) {
    grunt.log.error('ERROR'.red + ' :: depswriter file/path not valid: ' + depswriter);
    return false;
  }

  // prep and return params object
  return {
    depswriter: depswriter
  };

}

/**
 * Prepare and compile the depswriter command we will execute
 *
 * @param {grunt} grunt
 * @param {Object} params
 * @param {Object} data
 * @return {string|boolean} boolean false if we failed, command string if all ok
 */
function compileCommand(grunt, params, data)
{
  var cmd = params.depswriter + ' ';

  // ---
  // Check for file targets...
  // ---
  var files = grunt.file.expandFiles(data.files || '');
  for (var i = 0, l = files.length; i < l; i++) {
    cmd += files[i] + ' ';
  }

  // ---
  // loop through any options and add then up...
  // ---
  for(var directive in data.options) {
    cmd += grunt.helper('makeParam', data.options[directive], '--' + directive + '=', true);
  }

  // ---
  // check if output file is defined
  // ---
  if (data.output_file && data.output_file.length) {
    cmd += ' --output_file=' + grunt.file.expandFiles(data.output_file).shift();
  }

  return cmd;
}

<commit_msg>Allow closureDepsWriter to output to non-existent file<commit_after>/**
 * Copyright 2012 Thanasis Polychronakis. Some Rights Reserved.
 *
 * 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
 *
 * =======================
 *
 * closureBuilder.js Combines and optionally compiles javascript files
 *
 * Call from grunt as:
 */
var gruntConfig = {
  closureDepsWriter: {
     // any name that describes your operation
    targetName: {
      // [Required] To find the depswriter executable we need either the path to
      //    closure library or directly the filepath to the depswriter:
      closureLibraryPath: 'path/to/closure-library', // path to closure library
      depswriter: 'path/to/depswriter.py', // filepath to depswriter

      // [Optional] Set file targets. Can be a string, array or
      //    grunt file syntax (<config:...> or *)
      files: 'path/to/awesome.js',

      // [Optional] If not set, will output to stdout
      output_file: '',

      options: {
        // [Optional] Root directory to scan. Can be string or array
        root: ['source/ss', 'source/closure-library', 'source/showcase'],

        // [Optional] Root with prefix takes a pair of strings separated with a space,
        //    so proper way to use it is to suround with quotes.
        //    can be a string or array
        root_with_prefix: '"source/ss ../../ss"',

        // [Optional] string or array
        path_with_depspath: ''
      }
    }
  }
};

var fs = require('fs');

// path to depswriter from closure lib path
var DEPSWRITER = '/closure/bin/build/depswriter.py';

module.exports = function(grunt) {
  grunt.registerMultiTask('closureDepsWriter', 'Google Closure Library Dependency Calculator script', function() {

    var data = this.data;
    var done = this.async();

    //
    // Validations
    // - Check required parameters
    //
    var params = validate(grunt, data);
    if (false === params) {
      return false;
    }

    //
    // Prepare and compile the command string we will execute
    //
    var command = compileCommand(grunt, params, data);

    if (false === command) {
      return false;
    }

    // execute the task
    grunt.helper('executeCommand', command, done);

  });

};

/**
 * Perform validations for given options
 *
 * @return {boolean|Object} false if error
 */
function validate(grunt, data)
{
  // check for closure lib path
  var lib = data.closureLibraryPath;
  var depswriter;
  if (!lib) {
    // check for direct assignment of depswriter script
    depswriter = data.depswriter;
    if (!depswriter) {
      grunt.log.error('ERROR'.red + ' :: ' + 'closureLibraryPath'.red + ' or ' + 'depswriter'.red + ' properties are required');
      return false;
    }
  } else {
    depswriter = lib + DEPSWRITER;
  }

  depswriter = grunt.file.expandFiles(depswriter).shift();

  // ---
  // check depswriter existence
  // ---
  var fileExists = false;
  try {
      if (fs.lstatSync(depswriter).isFile()) {
        fileExists = true;
      }
  }
  catch (e) {}
  if (!fileExists) {
    grunt.log.error('ERROR'.red + ' :: depswriter file/path not valid: ' + depswriter);
    return false;
  }

  // prep and return params object
  return {
    depswriter: depswriter
  };

}

/**
 * Prepare and compile the depswriter command we will execute
 *
 * @param {grunt} grunt
 * @param {Object} params
 * @param {Object} data
 * @return {string|boolean} boolean false if we failed, command string if all ok
 */
function compileCommand(grunt, params, data)
{
  var cmd = params.depswriter + ' ';

  // ---
  // Check for file targets...
  // ---
  var files = grunt.file.expandFiles(data.files || '');
  for (var i = 0, l = files.length; i < l; i++) {
    cmd += files[i] + ' ';
  }

  // ---
  // loop through any options and add then up...
  // ---
  for(var directive in data.options) {
    cmd += grunt.helper('makeParam', data.options[directive], '--' + directive + '=', true);
  }

  // ---
  // check if output file is defined
  // ---
  if (data.output_file && data.output_file.length) {
    grunt.file.write(data.output_file, ''); // Write to the file first in case it doesn't exist
    cmd += ' --output_file=' + grunt.file.expandFiles(data.output_file).shift();
  }

  return cmd;
}

<|endoftext|>


<commit_before>module.exports = function(grunt) {

  /**
   *  Please see the Grunt documentation for more information regarding task
   *  creation: http://gruntjs.com/creating-tasks
   */

  grunt.registerMultiTask("coffee_strip_code", "Strip code matching a specified pattern.", function(target) {

    var options = this.options({
          start_comment_tag: "test-block-start",
          end_comment_tag: "test-block-end"
        })
      , pattern = options.pattern || new RegExp(
          "([\\t ]*\\#\\# ?" + options.start_comment_tag + " ?\\#\\#.*\n)" +
          "[\\s\\S]*?" +
          "(\\#\\# ?" + options.end_comment_tag + " ?\\#\\#.*\n)"
          , "g"
        );

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {
      // Concat specified files.
      f.src.forEach(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return;
        }
        var contents = grunt.file.read(filepath)
          , replacement = contents.replace(pattern, "");
        // if replacement is different than contents, save file and print a success message.
        if (contents !== replacement) {
          if (f.dest) {
            grunt.file.write(f.dest, replacement);
            grunt.log.writeln("Stripped code from " + filepath + " and saved to " + f.dest);
          } else {
            grunt.file.write(filepath, replacement);
            grunt.log.writeln("Stripped code from " + filepath);
          }
        }
      });
    });
  });
};
<commit_msg>improved main regex to be not greedy<commit_after>module.exports = function(grunt) {

  /**
   *  Please see the Grunt documentation for more information regarding task
   *  creation: http://gruntjs.com/creating-tasks
   */

  grunt.registerMultiTask("coffee_strip_code", "Strip code matching a specified pattern.", function(target) {

    var options = this.options({
          start_comment_tag: "test-block-start",
          end_comment_tag: "test-block-end"
        })
      , pattern = options.pattern || new RegExp(
          "([\\t ]*\\#\\# ?" + options.start_comment_tag + " ?\\#\\#.*\n?)" +
          "[\\s\\S]*?" +
          "(\\#\\# ?" + options.end_comment_tag + " ?\\#\\#.*\n)"
          , "g"
        );

    // Iterate over all specified file groups.
    this.files.forEach(function(f) {
      // Concat specified files.
      f.src.forEach(function(filepath) {
        // Warn on and remove invalid source files (if nonull was set).
        if (!grunt.file.exists(filepath)) {
          grunt.log.warn('Source file "' + filepath + '" not found.');
          return;
        }
        var contents = grunt.file.read(filepath)
          , replacement = contents.replace(pattern, "");
        // if replacement is different than contents, save file and print a success message.
        if (contents !== replacement) {
          if (f.dest) {
            grunt.file.write(f.dest, replacement);
            grunt.log.writeln("Stripped code from " + filepath + " and saved to " + f.dest);
          } else {
            grunt.file.write(filepath, replacement);
            grunt.log.writeln("Stripped code from " + filepath);
          }
        }
      });
    });
  });
};
<|endoftext|>


<commit_before>var http     = require('http')
  , xmldoc   = require('xmldoc')
  , path     = require('path')
  , os       = require('os')
  , fs       = require('fs')
  , url      = require('url')
  , unzip    = require('unzip')
  , Progress = require('progress')

module.exports = function(grunt) {
  var URL  = 'http://dl-ssl.google.com/android/repository/repository-8.xml'
    , TEMP = path.join(os.tmpdir(), 'download-adb');

  var LINUX = 'linux'
    , WIN   = 'windows'
    , OSX   = 'macosx'

  var PROGRESS_FMT = '  downloading [:bar] :percent :etas'
    , PROGRESS_OPT = {
      total      : 0,
      complete   : '=',
      incomplete : ' ',
      width      : 20
    }

  var platform = function(platform) {
    if (platform === 'win32')
      return WIN;
    else if (platform === 'darwin')
      return OSX;
    else
      return LINUX;
  }(process.platform);

  function getXml(res) {
    var self = this;
    var body = '';
    res.on('data', function(chunk) {
      body += chunk;
    });
    res.on('end', function() {
      self.binary = extractBinaryInfo(body);
      PROGRESS_OPT.total = parseInt(self.binary.size, 10),
      self.progress = new Progress(PROGRESS_FMT, PROGRESS_OPT);
      self.tempPath = path.join(self.tempDir, self.binary.url);

      if (grunt.file.exists(self.tempPath)) {
        extract.call(self);
      } else {
        var binUrl = url.resolve(self.url, self.binary.url);
        http.get(binUrl, download.bind(self));
      }
    });
    res.on('error', function() {
    });
  }

  function extractBinaryInfo(xml) {
    var doc  = new xmldoc.XmlDocument(xml);
    var node = doc.childNamed('sdk:platform-tool')
                  .childNamed('sdk:archives')
                  .childWithAttribute('os', platform);
    return {
      'checksum' : node.valueWithPath('sdk:checksum'),
      'size'     : node.valueWithPath('sdk:size'),
      'url'      : node.valueWithPath('sdk:url')
    }
  }

  function download(res) {
    var self = this;
    createDir(self.tempDir);
    var outputStream = fs.createWriteStream(self.tempPath);
    res.pipe(outputStream);
    res.on('data', function(chunk) {
      self.progress.tick(chunk.length);
    });
    res.on('end', function() {
      extract.call(self);
    });
    res.on('error', function(e) {
    });
  }

  function extract() {
    var self = this;
    var s = fs.createReadStream(self.tempPath);
    var d = unzip.Extract({ path: self.outputDir });

    s.pipe(d);
    s.on('end', function() {
      self.done();
    });
    s.on('error', function(e) {
    });
  }

  function createDir(path) {
    grunt.file.mkdir(path);
  }

  grunt.registerTask('download-adb', 'Download adb', function() {
    grunt.log.writeln('Download adb');
    var options = this.options({
      url      : URL,
      outputDir: 'bin',
      tempDir  : TEMP,
    });
    options.done = this.async();
    options.outputDir = path.join(process.cwd(), options.outputDir);
    createDir(options.outputDir);

    http.get(options.url, getXml.bind(options));
  });
}
<commit_msg>add execute permission on adb file.<commit_after>var http     = require('http')
  , xmldoc   = require('xmldoc')
  , path     = require('path')
  , os       = require('os')
  , fs       = require('fs')
  , url      = require('url')
  , unzip    = require('unzip')
  , Progress = require('progress')

module.exports = function(grunt) {
  var URL  = 'http://dl-ssl.google.com/android/repository/repository-8.xml'
    , TEMP = path.join(os.tmpdir(), 'download-adb');

  var LINUX = 'linux'
    , WIN   = 'windows'
    , OSX   = 'macosx'

  var PROGRESS_FMT = '  downloading [:bar] :percent :etas'
    , PROGRESS_OPT = {
      total      : 0,
      complete   : '=',
      incomplete : ' ',
      width      : 20
    }

  var platform = function(platform) {
    if (platform === 'win32')
      return WIN;
    else if (platform === 'darwin')
      return OSX;
    else
      return LINUX;
  }(process.platform);

  function getXml(res) {
    var self = this;
    var body = '';
    res.on('data', function(chunk) {
      body += chunk;
    });
    res.on('end', function() {
      self.binary = extractBinaryInfo(body);
      PROGRESS_OPT.total = parseInt(self.binary.size, 10),
      self.progress = new Progress(PROGRESS_FMT, PROGRESS_OPT);
      self.tempPath = path.join(self.tempDir, self.binary.url);

      if (grunt.file.exists(self.tempPath)) {
        extract.call(self);
      } else {
        var binUrl = url.resolve(self.url, self.binary.url);
        http.get(binUrl, download.bind(self));
      }
    });
    res.on('error', function() {
    });
  }

  function extractBinaryInfo(xml) {
    var doc  = new xmldoc.XmlDocument(xml);
    var node = doc.childNamed('sdk:platform-tool')
                  .childNamed('sdk:archives')
                  .childWithAttribute('os', platform);
    return {
      'checksum' : node.valueWithPath('sdk:checksum'),
      'size'     : node.valueWithPath('sdk:size'),
      'url'      : node.valueWithPath('sdk:url')
    }
  }

  function download(res) {
    var self = this;
    createDir(self.tempDir);
    var outputStream = fs.createWriteStream(self.tempPath);
    res.pipe(outputStream);
    res.on('data', function(chunk) {
      self.progress.tick(chunk.length);
    });
    res.on('end', function() {
      extract.call(self);
    });
    res.on('error', function(e) {
    });
  }

  function extract() {
    var self = this;
    var s = fs.createReadStream(self.tempPath);
    var d = unzip.Extract({ path: self.outputDir });

    s.pipe(d);
    s.on('end', function() {
      if (platform != 'win32') {
        var adbPath = grunt.file.expand(path.join(self.outputDir, '**', 'adb'));
        fs.chmodSync(adbPath[0], '755');
      }
      self.done();
    });
    s.on('error', function(e) {
    });
  }

  function createDir(path) {
    grunt.file.mkdir(path);
  }

  grunt.registerTask('download-adb', 'Download adb', function() {
    grunt.log.writeln('Download adb');
    var options = this.options({
      url      : URL,
      outputDir: 'bin',
      tempDir  : TEMP,
    });
    options.done = this.async();
    options.outputDir = path.join(process.cwd(), options.outputDir);
    createDir(options.outputDir);

    http.get(options.url, getXml.bind(options));
  });
}
<|endoftext|>


<commit_before>/**
 * grunt-webfont: fontforge engine
 *
 * @requires fontforge, ttfautohint 1.00+ (optional), eotlitetool.py
 * @author Artem Sapegin (http://sapegin.me)
 */

module.exports = function(o, allDone) {
	'use strict';

	var fs = require('fs');
	var path = require('path');
	var temp = require('temp');
	var async = require('async');
	var glob = require('glob');
	var exec = require('exec');
	var chalk = require('chalk');
	var _ = require('lodash');
	var logger = o.logger || require('winston');
	var wf = require('../util/util');

	// Copy source files to temporary directory
	var tempDir = temp.mkdirSync();
	o.files.forEach(function(file) {
		fs.writeFileSync(path.join(tempDir, o.rename(file)), fs.readFileSync(file));
	});

	// Run Fontforge
	var args = [
		'fontforge',
		'-script',
		path.join(__dirname, 'fontforge/generate.py')
	];

	var proc = exec(args, function(err, out, code) {
		if (err instanceof Error && err.code === 'ENOENT') {
			return error('fontforge not found. Please install fontforge and all other requirements.');
		}
		else if (err) {
			if (err instanceof Error) {
				return error(err.message);
			}

			// Skip some fontforge output such as copyrights. Show warnings only when no font files was created
			// or in verbose mode.
			var success = !!generatedFontFiles();
			var notError = /(Copyright|License |with many parts BSD |Executable based on sources from|Library based on sources from|Based on source from git)/;
			var lines = err.split('\n');

			var warn = [];
			lines.forEach(function(line) {
				if (!line.match(notError) && !success) {
					warn.push(line);
				}
				else {
					logger.verbose(chalk.grey('fontforge: ') + line);
				}
			});

			if (warn.length) {
				return error(warn.join('\n'));
			}
		}

		// Trim fontforge result
		var json = out.replace(/^[^{]+/, '').replace(/[^}]+$/, '');

		// Parse json
		var result;
		try {
			result = JSON.parse(json);
		}
		catch (e) {
			logger.verbose('Webfont did not receive a proper JSON result from Python script: ' + e);
			return error(
				'Something went wrong when running fontforge. Probably one of your SVGs is too complicated for fontforge.\n\n' +
				'1. Try to use “node” engine instead of “fontforge”. (See “engine” option in the Readme.)\n\n' +
				'2. To find “bad” icon try to remove SVGs one by one until error disappears. Then try to simplify this SVG in Sketch, Illustrator, etc.\n\n'
			);
		}

		allDone({
			fontName: path.basename(result.file)
		});
	});

	// Send JSON with params
	if (!proc) return;
	var params = _.extend(o, {
		inputDir: tempDir
	});
	proc.stdin.write(JSON.stringify(params));
	proc.stdin.end();

	function generatedFontFiles() {
		return glob.sync(path.join(o.dest, o.fontBaseName + wf.fontFileMask));
	}

	function error() {
		logger.error.apply(null, arguments);
		allDone(false);
		return false;
	}

};
<commit_msg>Tweak fontforge installation check to prevent “Write EPIPE” error.<commit_after>/**
 * grunt-webfont: fontforge engine
 *
 * @requires fontforge, ttfautohint 1.00+ (optional), eotlitetool.py
 * @author Artem Sapegin (http://sapegin.me)
 */

module.exports = function(o, allDone) {
	'use strict';

	var fs = require('fs');
	var path = require('path');
	var temp = require('temp');
	var async = require('async');
	var glob = require('glob');
	var exec = require('exec');
	var chalk = require('chalk');
	var _ = require('lodash');
	var logger = o.logger || require('winston');
	var wf = require('../util/util');

	// Copy source files to temporary directory
	var tempDir = temp.mkdirSync();
	o.files.forEach(function(file) {
		fs.writeFileSync(path.join(tempDir, o.rename(file)), fs.readFileSync(file));
	});

	// Run Fontforge
	var args = [
		'fontforge',
		'-script',
		path.join(__dirname, 'fontforge/generate.py')
	];

	var proc = exec(args, function(err, out, code) {
		if (err instanceof Error && err.code === 'ENOENT') {
			return fontforgeNotFound();
		}
		else if (err) {
			if (err instanceof Error) {
				return error(err.message);
			}

			// Skip some fontforge output such as copyrights. Show warnings only when no font files was created
			// or in verbose mode.
			var success = !!generatedFontFiles();
			var notError = /(Copyright|License |with many parts BSD |Executable based on sources from|Library based on sources from|Based on source from git)/;
			var lines = err.split('\n');

			var warn = [];
			lines.forEach(function(line) {
				if (!line.match(notError) && !success) {
					warn.push(line);
				}
				else {
					logger.verbose(chalk.grey('fontforge: ') + line);
				}
			});

			if (warn.length) {
				return error(warn.join('\n'));
			}
		}

		// Trim fontforge result
		var json = out.replace(/^[^{]+/, '').replace(/[^}]+$/, '');

		// Parse json
		var result;
		try {
			result = JSON.parse(json);
		}
		catch (e) {
			logger.verbose('Webfont did not receive a proper JSON result from Python script: ' + e);
			return error(
				'Something went wrong when running fontforge. Probably one of your SVGs is too complicated for fontforge.\n\n' +
				'1. Try to use “node” engine instead of “fontforge”. (See “engine” option in the Readme.)\n\n' +
				'2. To find “bad” icon try to remove SVGs one by one until error disappears. Then try to simplify this SVG in Sketch, Illustrator, etc.\n\n'
			);
		}

		allDone({
			fontName: path.basename(result.file)
		});
	});

	// Send JSON with params
	if (!proc) return;
	proc.stdin.on('error', function(err) {
		if (err.code === 'EPIPE') {
			fontforgeNotFound();
		}
	});
	var params = _.extend(o, {
		inputDir: tempDir
	});
	proc.stdin.write(JSON.stringify(params));
	proc.stdin.end();

	function generatedFontFiles() {
		return glob.sync(path.join(o.dest, o.fontBaseName + wf.fontFileMask));
	}

	function error() {
		logger.error.apply(null, arguments);
		allDone(false);
		return false;
	}

	function fontforgeNotFound() {
		error('fontforge not found. Please install fontforge and all other requirements.');
	}

};
<|endoftext|>


<commit_before>/**
 * Upwork auth library for using with public API by OAuth
 *
 * @package     UpworkAPI
 * @since       06/13/2016
 * @copyright   Copyright 2016(c) Upwork.com
 * @author      Maksym Novozhylov <mnovozhilov@upwork.com>
 * @license     Upwork's API Terms of Use {@link https://developers.upwork.com/api-tos.html}
 */

/**
 * @module routes.messages
 */

/**
 * @property entryPoint
 * @type String
 * @default api
 * @static
 * @final
 */
var entryPoint = 'api';

/**
 * Messages
 *
 * @class Messages
 * @constructor
 */
exports.Messages = function(api) {
  this.api = api;
  this.api.epoint = entryPoint;
}

/**
 * Retrive rooms information
 *
 * @method getRooms
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRooms = function(company, callback) {
  debug('running request');
  this.api.client.get('messages/v3/' + company + '/rooms', {}, callback);
}

/**
 * Get a specific room information
 *
 * @method getRoomDetails
 * @param company {String} Company ID
 * @param roomId {String} Room ID
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRoomDetails = function(company, roomId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.get('message/v3/' + company + '/rooms/' + roomId, params, callback);
}

/**
 * Get a specific room by offer ID
 *
 * @method getRoomByOffer
 * @param company {String} Company ID
 * @param offerId {Integer} Offer ID
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRoomByOffer = function(company, offerId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.get('message/v3/' + company + '/rooms/offers/' + offerId, params, callback);
}

/**
 * Get a specific room by application ID
 *
 * @method getRoomByApplication
 * @param company {String} Company ID
 * @param applicationId {Integer} Application ID
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRoomByApplication = function(company, applicationId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.get('message/v3/' + company + '/rooms/applications/' + applicationId, params, callback);
}

/**
 * Get a specific room by contract ID
 *
 * @method getRoomByContract
 * @param company {String} Company ID
 * @param contractId {Integer} Contract ID
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRoomByContract = function(company, contractId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.get('message/v3/' + company + '/rooms/contracts/' + contractId, params, callback);
}

/**
 * Create a new room
 *
 * @method createRoom
 * @param company {String} Company ID
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.createRoom = function(company, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.post('message/v3/' + company + '/rooms', params, callback);
}

/**
 * Send a message to a room
 *
 * @method sendMessageToRoom
 * @param company {String} Company ID
 * @param roomId {String} Room ID
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.sendMessageToRoom = function(company, roomId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.post('message/v3/' + company + '/rooms/' + roomId + '/stories', params, callback);
}

/**
 * Update a room settings
 *
 * @method updateRoomSettings
 * @param company {String} Company ID
 * @param roomId {String} Room ID
 * @param username {String} User ID
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.updateRoomSettings = function(company, roomId, username, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.put('message/v3/' + company + '/rooms/' + roomId + '/users/' + username, params, callback);
}

/**
 * Update the metadata of a room
 *
 * @method updateRoomMetadata
 * @param company {String} Company ID
 * @param roomId {String} Room ID
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.updateRoomMetadata = function(company, roomId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.put('message/v3/' + company + '/rooms/' + roomId, params, callback);
}
<commit_msg>v1.2.0<commit_after>/**
 * Upwork auth library for using with public API by OAuth
 *
 * @package     UpworkAPI
 * @since       06/13/2016
 * @copyright   Copyright 2016(c) Upwork.com
 * @author      Maksym Novozhylov <mnovozhilov@upwork.com>
 * @license     Upwork's API Terms of Use {@link https://developers.upwork.com/api-tos.html}
 */

/**
 * @module routes.messages
 */

/**
 * @property entryPoint
 * @type String
 * @default api
 * @static
 * @final
 */
var entryPoint = 'api';

/**
 * Messages
 *
 * @class Messages
 * @constructor
 */
exports.Messages = function(api) {
  this.api = api;
  this.api.epoint = entryPoint;
}

/**
 * Retrieve rooms information
 *
 * @method getRooms
 * @param company {String} Company ID
 * @param params {Hash} Parameters
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRooms = function(company, params, callback) {
  debug('running request');
  this.api.client.get('messages/v3/' + company + '/rooms', params, callback);
}

/**
 * Get a specific room information
 *
 * @method getRoomDetails
 * @param company {String} Company ID
 * @param roomId {String} Room ID
 * @param params {Hash} Parameters
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRoomDetails = function(company, roomId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.get('message/v3/' + company + '/rooms/' + roomId, params, callback);
}

/**
 * Get a specific room by offer ID
 *
 * @method getRoomByOffer
 * @param company {String} Company ID
 * @param offerId {Integer} Offer ID
 * @param params {Hash} Parameters
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRoomByOffer = function(company, offerId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.get('message/v3/' + company + '/rooms/offers/' + offerId, params, callback);
}

/**
 * Get a specific room by application ID
 *
 * @method getRoomByApplication
 * @param company {String} Company ID
 * @param applicationId {Integer} Application ID
 * @param params {Hash} Parameters
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRoomByApplication = function(company, applicationId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.get('message/v3/' + company + '/rooms/applications/' + applicationId, params, callback);
}

/**
 * Get a specific room by contract ID
 *
 * @method getRoomByContract
 * @param company {String} Company ID
 * @param contractId {Integer} Contract ID
 * @param params {Hash} Parameters
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.getRoomByContract = function(company, contractId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.get('message/v3/' + company + '/rooms/contracts/' + contractId, params, callback);
}

/**
 * Create a new room
 *
 * @method createRoom
 * @param company {String} Company ID
 * @param params {Hash} Parameters
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.createRoom = function(company, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.post('message/v3/' + company + '/rooms', params, callback);
}

/**
 * Send a message to a room
 *
 * @method sendMessageToRoom
 * @param company {String} Company ID
 * @param roomId {String} Room ID
 * @param params {Hash} Parameters
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.sendMessageToRoom = function(company, roomId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.post('message/v3/' + company + '/rooms/' + roomId + '/stories', params, callback);
}

/**
 * Update a room settings
 *
 * @method updateRoomSettings
 * @param company {String} Company ID
 * @param roomId {String} Room ID
 * @param username {String} User ID
 * @param params {Hash} Parameters
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.updateRoomSettings = function(company, roomId, username, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.put('message/v3/' + company + '/rooms/' + roomId + '/users/' + username, params, callback);
}

/**
 * Update the metadata of a room
 *
 * @method updateRoomMetadata
 * @param company {String} Company ID
 * @param roomId {String} Room ID
 * @param params {Hash} Parameters
 * @param callback {String} Callback function
 * @async
 */
exports.Messages.prototype.updateRoomMetadata = function(company, roomId, params, callback) {
  params = params || {};
  debug('running request');
  this.api.client.put('message/v3/' + company + '/rooms/' + roomId, params, callback);
}
<|endoftext|>


<commit_before>
'use strict';

// must have dl, with:
//  dts containing "This Version", "Latest Version", "Previous Version" in that order
//  this version is http://www.w3.org/TR/2013/WD-shortname-2013MMDD/
//  latest version is http://www.w3.org/TR/shortname/
//  h2 date and this version date must match
//  dt for editor or author

exports.name = "headers.dl";

exports.check = function (sr, done) {

    // Pseudo-constants:
    var EDITORS_DRAFT = /Latest\ editor's\ draft/i;

    var $dl = sr.$("body div.head dl").first()
    ,   prevRequired = sr.config.previousVersion
    ,   rescinds = sr.config.rescinds
    ,   subType = sr.config.submissionType
    ,   topLevel = "TR"
    ,   dts = {}
    ,   seenEditors = false
    ,   editorIDs = []
    ,   err = function (str, extra) {
            sr.error(exports.name, str, extra);
        }
        // XXX one of the horrible hacks that can be removed when whacko supports .next properly
    ,   getDD = function ($dl, idx) {
            var pastDT = false
            ,   dtIdx = -1
            ,   $dd = null
            ;
            $dl.children().each(function () {
                var $el = sr.$(this);
                if (pastDT && $el.is("dd")) {
                    $dd = $el;
                    return false;
                }
                if (!pastDT && $el.is("dt")) {
                    dtIdx++;
                    if (dtIdx === idx) pastDT = true;
                }
            });
            return $dd;
        }
    ;

    if (subType === "member") topLevel = "Submission";
    else if (subType === "team") topLevel = "TeamSubmission";

    $dl.find("dt").each(function (idx) {
        var $dt = sr.$(this)
        ,   txt = sr.norm($dt.text())
                      .replace(":", "")
                      .toLowerCase()
                      .replace("published ", "")
        ,   $dd = getDD($dl, idx)
        ,   key = null
        ;
        if (!$dd) return err("no-dd", { dt: txt });
        if (/^(editor|author)s?/.test(txt)) seenEditors = true;
        if (txt === "this version") key = "This";
        else if (txt === "latest version") key = "Latest";
        else if (/^previous version(?:s)?$/.test(txt)) key = "Previous";
        else if (/^rescinds this recommendation?$/.test(txt)) key = "Rescinds";
        if (EDITORS_DRAFT.test(txt) && $dd.find('a')) sr.metadata('editorsDraft', $dd.find('a').attr('href'));
        if (key) dts[key] = { pos: idx, el: $dt, dd: $dd };
    });

    if (!dts.This) err("this-version");
    if (!dts.Latest) err("latest-version");
    if (prevRequired && !dts.Previous) err("previous-version");
    if (!prevRequired && dts.Previous) sr.warning(exports.name, "previous-not-needed");
    if (rescinds && !dts.Rescinds) err("rescinds");
    if (!rescinds && dts.Rescinds) sr.warning(exports.name, "rescinds-not-needed");

    if (dts.This && dts.Latest && dts.This.pos > dts.Latest.pos) err("this-latest-order");
    if (dts.Latest && dts.Previous && dts.Latest.pos > dts.Previous.pos) err("latest-previous-order");
    if (dts.Latest && dts.Rescinds && dts.Latest.pos > dts.Rescinds.pos) err("latest-rescinds-order");

    var shortname;
    if (dts.This) {
        var $linkThis = dts.This.dd.find("a").first();
        if (!$linkThis || !$linkThis.length || $linkThis.attr("href") !== $linkThis.text()) err("this-link");

        var vThisRex = "^https?:\\/\\/www\\.w3\\.org\\/" +
                       topLevel +
                       "\\/(\\d{4})\\/" +
                       (sr.config.status || "[A-Z]+") +
                       "-(.+)-(\\d{4})(\\d\\d)(\\d\\d)\\/?$";
        var matches = ($linkThis.attr("href") || "").match(new RegExp(vThisRex))
        ,   docDate = sr.getDocumentDate()
        ;
        if (matches) {
            sr.metadata('thisVersion', matches[0]);
            var year = matches[1] * 1
            ,   year2 = matches[3] * 1
            ,   month = matches[4] * 1
            ,   day = matches[5] * 1
            ;
            shortname = matches[2];
            if (docDate) {
                if (year !== docDate.getFullYear() ||
                    year2 !== docDate.getFullYear() ||
                    month - 1 !== docDate.getMonth() ||
                    day !== docDate.getDate()
                   ) err("this-date");
            }
            else sr.warning(exports.name, "no-date");
        }
        else err("this-syntax");
    }

    if (dts.Latest) {
        var $linkLate = dts.Latest.dd.find("a").first();
        if (!$linkLate || !$linkLate.length || $linkLate.attr("href") !== $linkLate.text()) err("latest-link");

        var lateRex = "^https?:\\/\\/www\\.w3\\.org\\/" + topLevel + "\\/(.+?)\\/?$"
        ,   matches = ($linkLate.attr("href") || "").match(new RegExp(lateRex));
        if (matches) {
            var sn = matches[1];
            sr.metadata('latestVersion', $linkLate.text());
            if (sn !== shortname) err("this-latest-shortname");
        }
        else err("latest-syntax");
    }

    if (dts.Previous) {
        var $linkPrev = dts.Previous.dd.find("a").first();
        if (!$linkPrev || !$linkPrev.length || $linkPrev.attr("href") !== $linkPrev.text()) err("previous-link");

        var prevRex = "^https?:\\/\\/www\\.w3\\.org\\/" + topLevel + "\\/\\d{4}\\/[A-Z]+-(.+)-\\d{8}\\/?$"
        ,   matches = ($linkPrev.attr("href") || "").match(new RegExp(prevRex))
        ;
        if (matches) {
            var sn = matches[1];
            sr.metadata('previousVersion', $linkPrev.text());
            if (sn !== shortname) err("this-previous-shortname");
        }
        else err("previous-syntax");
    }

    if (dts.Rescinds) {
        var $linkResc = dts.Rescinds.dd.find("a").first();
        if (!$linkResc || !$linkResc.length || $linkResc.attr("href") !== $linkResc.text()) err("rescinds-link");

        var matches = ($linkResc.attr("href") || "").match(/^https?:\/\/www\.w3\.org\/TR\/\d{4}\/REC-(.+)-\d{8}\/?$/);
        if (matches) {
            var sn = matches[1];
            if (sn !== shortname) err("this-rescinds-shortname");
        }
        else err("rescinds-syntax");
    }

    if (seenEditors) {
        sr.$('dd[data-editor-id]').each(function() {
            if (/\d+/.test(sr.$(this).attr('data-editor-id'))) {
                editorIDs.push(parseInt(sr.$(this).attr('data-editor-id'), 10));
            }
        });
        sr.metadata('editorIDs', editorIDs);
    }
    if (!seenEditors || editorIDs.length < 1) {
        err("editor");
    }
    done();
};

<commit_msg>https://github.com/w3c/echidna/pull/39#issuecomment-71855010<commit_after>
'use strict';

// must have dl, with:
//  dts containing "This Version", "Latest Version", "Previous Version" in that order
//  this version is http://www.w3.org/TR/2013/WD-shortname-2013MMDD/
//  latest version is http://www.w3.org/TR/shortname/
//  h2 date and this version date must match
//  dt for editor or author

exports.name = "headers.dl";

exports.check = function (sr, done) {

    // Pseudo-constants:
    var EDITORS_DRAFT = /Latest\ editor's\ draft/i;

    var $dl = sr.$("body div.head dl").first()
    ,   prevRequired = sr.config.previousVersion
    ,   rescinds = sr.config.rescinds
    ,   subType = sr.config.submissionType
    ,   topLevel = "TR"
    ,   dts = {}
    ,   seenEditors = false
    ,   editorIDs = []
    ,   err = function (str, extra) {
            sr.error(exports.name, str, extra);
        }
        // XXX one of the horrible hacks that can be removed when whacko supports .next properly
    ,   getDD = function ($dl, idx) {
            var pastDT = false
            ,   dtIdx = -1
            ,   $dd = null
            ;
            $dl.children().each(function () {
                var $el = sr.$(this);
                if (pastDT && $el.is("dd")) {
                    $dd = $el;
                    return false;
                }
                if (!pastDT && $el.is("dt")) {
                    dtIdx++;
                    if (dtIdx === idx) pastDT = true;
                }
            });
            return $dd;
        }
    ;

    if (subType === "member") topLevel = "Submission";
    else if (subType === "team") topLevel = "TeamSubmission";

    $dl.find("dt").each(function (idx) {
        var $dt = sr.$(this)
        ,   txt = sr.norm($dt.text())
                      .replace(":", "")
                      .toLowerCase()
                      .replace("published ", "")
        ,   $dd = getDD($dl, idx)
        ,   key = null
        ;
        if (!$dd) return err("no-dd", { dt: txt });
        if (/^(editor|author)s?/.test(txt)) seenEditors = true;
        if (txt === "this version") key = "This";
        else if (txt === "latest version") key = "Latest";
        else if (/^previous version(?:s)?$/.test(txt)) key = "Previous";
        else if (/^rescinds this recommendation?$/.test(txt)) key = "Rescinds";
        if (EDITORS_DRAFT.test(txt) && $dd.find('a')) sr.metadata('editorsDraft', $dd.find('a').attr('href'));
        if (key) dts[key] = { pos: idx, el: $dt, dd: $dd };
    });

    if (!dts.This) err("this-version");
    if (!dts.Latest) err("latest-version");
    if (prevRequired && !dts.Previous) err("previous-version");
    if (!prevRequired && dts.Previous) sr.warning(exports.name, "previous-not-needed");
    if (rescinds && !dts.Rescinds) err("rescinds");
    if (!rescinds && dts.Rescinds) sr.warning(exports.name, "rescinds-not-needed");

    if (dts.This && dts.Latest && dts.This.pos > dts.Latest.pos) err("this-latest-order");
    if (dts.Latest && dts.Previous && dts.Latest.pos > dts.Previous.pos) err("latest-previous-order");
    if (dts.Latest && dts.Rescinds && dts.Latest.pos > dts.Rescinds.pos) err("latest-rescinds-order");

    var shortname;
    if (dts.This) {
        var $linkThis = dts.This.dd.find("a").first();
        if (!$linkThis || !$linkThis.length || $linkThis.attr("href") !== $linkThis.text()) err("this-link");

        var vThisRex = "^http:\\/\\/www\\.w3\\.org\\/" +
                       topLevel +
                       "\\/(\\d{4})\\/" +
                       (sr.config.status || "[A-Z]+") +
                       "-(.+)-(\\d{4})(\\d\\d)(\\d\\d)\\/?$";
        var matches = ($linkThis.attr("href") || "").match(new RegExp(vThisRex))
        ,   docDate = sr.getDocumentDate()
        ;
        if (matches) {
            sr.metadata('thisVersion', matches[0]);
            var year = matches[1] * 1
            ,   year2 = matches[3] * 1
            ,   month = matches[4] * 1
            ,   day = matches[5] * 1
            ;
            shortname = matches[2];
            if (docDate) {
                if (year !== docDate.getFullYear() ||
                    year2 !== docDate.getFullYear() ||
                    month - 1 !== docDate.getMonth() ||
                    day !== docDate.getDate()
                   ) err("this-date");
            }
            else sr.warning(exports.name, "no-date");
        }
        else err("this-syntax");
    }

    if (dts.Latest) {
        var $linkLate = dts.Latest.dd.find("a").first();
        if (!$linkLate || !$linkLate.length || $linkLate.attr("href") !== $linkLate.text()) err("latest-link");

        var lateRex = "^https?:\\/\\/www\\.w3\\.org\\/" + topLevel + "\\/(.+?)\\/?$"
        ,   matches = ($linkLate.attr("href") || "").match(new RegExp(lateRex));
        if (matches) {
            var sn = matches[1];
            sr.metadata('latestVersion', $linkLate.text());
            if (sn !== shortname) err("this-latest-shortname");
        }
        else err("latest-syntax");
    }

    if (dts.Previous) {
        var $linkPrev = dts.Previous.dd.find("a").first();
        if (!$linkPrev || !$linkPrev.length || $linkPrev.attr("href") !== $linkPrev.text()) err("previous-link");

        var prevRex = "^https?:\\/\\/www\\.w3\\.org\\/" + topLevel + "\\/\\d{4}\\/[A-Z]+-(.+)-\\d{8}\\/?$"
        ,   matches = ($linkPrev.attr("href") || "").match(new RegExp(prevRex))
        ;
        if (matches) {
            var sn = matches[1];
            sr.metadata('previousVersion', $linkPrev.text());
            if (sn !== shortname) err("this-previous-shortname");
        }
        else err("previous-syntax");
    }

    if (dts.Rescinds) {
        var $linkResc = dts.Rescinds.dd.find("a").first();
        if (!$linkResc || !$linkResc.length || $linkResc.attr("href") !== $linkResc.text()) err("rescinds-link");

        var matches = ($linkResc.attr("href") || "").match(/^https?:\/\/www\.w3\.org\/TR\/\d{4}\/REC-(.+)-\d{8}\/?$/);
        if (matches) {
            var sn = matches[1];
            if (sn !== shortname) err("this-rescinds-shortname");
        }
        else err("rescinds-syntax");
    }

    if (seenEditors) {
        sr.$('dd[data-editor-id]').each(function() {
            if (/\d+/.test(sr.$(this).attr('data-editor-id'))) {
                editorIDs.push(parseInt(sr.$(this).attr('data-editor-id'), 10));
            }
        });
        sr.metadata('editorIDs', editorIDs);
    }
    if (!seenEditors || editorIDs.length < 1) {
        err("editor");
    }
    done();
};

<|endoftext|>


<commit_before>
// must have dl, with:
//  dts containing "This Version", "Latest Version", "Previous Version" in that order
//  this version is http://www.w3.org/TR/2013/WD-shortname-2013MMDD/
//  latest version is http://www.w3.org/TR/shortname/
//  h2 date and this version date must match
//  dt for editor or author
exports.name = "headers.dl";
exports.check = function (sr, done) {
    var $dl = sr.$("body div.head dl").first()
    ,   prevRequired = sr.config.previousVersion
    ,   rescinds = sr.config.rescinds
    ,   subType = sr.config.submissionType
    ,   topLevel = "TR"
    ,   dts = {}
    ,   seenEditors = false
    ,   err = function (str, extra) {
            sr.error(exports.name, str, extra);
        }
        // XXX one of the horrible hacks that can be removed when whacko supports .next properly
    ,   getDD = function ($dl, idx) {
            var pastDT = false
            ,   dtIdx = -1
            ,   $dd = null
            ;
            $dl.children().each(function () {
                var $el = sr.$(this);
                if (pastDT && $el.is("dd")) {
                    $dd = $el;
                    return false;
                }
                if (!pastDT && $el.is("dt")) {
                    dtIdx++;
                    if (dtIdx === idx) pastDT = true;
                }
            });
            return $dd;
        }
    ;

    if (subType === "member") topLevel = "Submission";
    else if (subType === "team") topLevel = "TeamSubmission";

    $dl.find("dt").each(function (idx) {
        var $dt = sr.$(this)
        ,   txt = sr.norm($dt.text())
                      .replace(":", "")
                      .toLowerCase()
                      .replace("published ", "")
        ,   $dd = getDD($dl, idx)
        ,   key = null
        ;
        if (!$dd) return err("no-dd", { dt: txt });
        if (/^(editor|author)s?/.test(txt)) seenEditors = true;
        if (txt === "this version") key = "This";
        else if (txt === "latest version") key = "Latest";
        else if (/^previous version(?:s)?$/.test(txt)) key = "Previous";
        else if (/^rescinds this recommendation?$/.test(txt)) key = "Rescinds";
        if (key) dts[key] = { pos: idx, el: $dt, dd: $dd };
    });

    if (!dts.This) err("this-version");
    if (!dts.Latest) err("latest-version");
    if (prevRequired && !dts.Previous) err("previous-version");
    if (!prevRequired && dts.Previous) sr.warning(exports.name, "previous-not-needed");
    if (rescinds && !dts.Rescinds) err("rescinds");
    if (!rescinds && dts.Rescinds) sr.warning(exports.name, "rescinds-not-needed");

    if (dts.This && dts.Latest && dts.This.pos > dts.Latest.pos) err("this-latest-order");
    if (dts.Latest && dts.Previous && dts.Latest.pos > dts.Previous.pos) err("latest-previous-order");
    if (dts.Latest && dts.Rescinds && dts.Latest.pos > dts.Rescinds.pos) err("latest-rescinds-order");

    var shortname;
    if (dts.This) {
        var $linkThis = dts.This.dd.find("a").first();
        if (!$linkThis || !$linkThis.length || $linkThis.attr("href") !== $linkThis.text()) err("this-link");

        var vThisRex = "^https?:\\/\\/www\\.w3\\.org\\/" +
                       topLevel +
                       "\\/(\\d{4})\\/" +
                       (sr.config.status || "[A-Z]+") +
                       "-(.+)-(\\d{4})(\\d\\d)(\\d\\d)\\/?$";
        var matches = ($linkThis.attr("href") || "").match(new RegExp(vThisRex))
        ,   docDate = sr.getDocumentDate()
        ;
        if (matches) {
            var year = matches[1] * 1
            ,   year2 = matches[3] * 1
            ,   month = matches[4] * 1
            ,   day = matches[5] * 1
            ;
            shortname = matches[2];
            if (docDate) {
                if (year !== docDate.getFullYear() ||
                    year2 !== docDate.getFullYear() ||
                    month - 1 !== docDate.getMonth() ||
                    day !== docDate.getDate()
                   ) err("this-date");
            }
            else sr.warning(exports.name, "no-date");
        }
        else err("this-syntax");
    }

    if (dts.Latest) {
        var $linkLate = dts.Latest.dd.find("a").first();
        if (!$linkLate || !$linkLate.length || $linkLate.attr("href") !== $linkLate.text()) err("latest-link");

        var lateRex = "^https?:\\/\\/www\\.w3\\.org\\/" + topLevel + "\\/(.+?)\\/?$"
        ,   matches = ($linkLate.attr("href") || "").match(new RegExp(lateRex));
        if (matches) {
            var sn = matches[1];
            if (sn !== shortname) err("this-latest-shortname");
        }
        else err("latest-syntax");
    }

    if (dts.Previous) {
        var $linkPrev = dts.Previous.dd.find("a").first();
        if (!$linkPrev || !$linkPrev.length || $linkPrev.attr("href") !== $linkPrev.text()) err("previous-link");

        var prevRex = "^https?:\\/\\/www\\.w3\\.org\\/" + topLevel + "\\/\\d{4}\\/[A-Z]+-(.+)-\\d{8}\\/?$"
        ,   matches = ($linkPrev.attr("href") || "").match(new RegExp(prevRex))
        ;
        if (matches) {
            var sn = matches[1];
            if (sn !== shortname) err("this-previous-shortname");
        }
        else err("previous-syntax");
    }

    if (dts.Rescinds) {
        var $linkResc = dts.Rescinds.dd.find("a").first();
        if (!$linkResc || !$linkResc.length || $linkResc.attr("href") !== $linkResc.text()) err("rescinds-link");

        var matches = ($linkResc.attr("href") || "").match(/^https?:\/\/www\.w3\.org\/TR\/\d{4}\/REC-(.+)-\d{8}\/?$/);
        if (matches) {
            var sn = matches[1];
            if (sn !== shortname) err("this-rescinds-shortname");
        }
        else err("rescinds-syntax");
    }

    if (!seenEditors) err("editor");
    done();
};
<commit_msg>Extracting latest/this/previous versions [WIP].<commit_after>
// must have dl, with:
//  dts containing "This Version", "Latest Version", "Previous Version" in that order
//  this version is http://www.w3.org/TR/2013/WD-shortname-2013MMDD/
//  latest version is http://www.w3.org/TR/shortname/
//  h2 date and this version date must match
//  dt for editor or author
exports.name = "headers.dl";
exports.check = function (sr, done) {
    var $dl = sr.$("body div.head dl").first()
    ,   prevRequired = sr.config.previousVersion
    ,   rescinds = sr.config.rescinds
    ,   subType = sr.config.submissionType
    ,   topLevel = "TR"
    ,   dts = {}
    ,   seenEditors = false
    ,   err = function (str, extra) {
            sr.error(exports.name, str, extra);
        }
        // XXX one of the horrible hacks that can be removed when whacko supports .next properly
    ,   getDD = function ($dl, idx) {
            var pastDT = false
            ,   dtIdx = -1
            ,   $dd = null
            ;
            $dl.children().each(function () {
                var $el = sr.$(this);
                if (pastDT && $el.is("dd")) {
                    $dd = $el;
                    return false;
                }
                if (!pastDT && $el.is("dt")) {
                    dtIdx++;
                    if (dtIdx === idx) pastDT = true;
                }
            });
            return $dd;
        }
    ;

    if (subType === "member") topLevel = "Submission";
    else if (subType === "team") topLevel = "TeamSubmission";

    $dl.find("dt").each(function (idx) {
        var $dt = sr.$(this)
        ,   txt = sr.norm($dt.text())
                      .replace(":", "")
                      .toLowerCase()
                      .replace("published ", "")
        ,   $dd = getDD($dl, idx)
        ,   key = null
        ;
        if (!$dd) return err("no-dd", { dt: txt });
        if (/^(editor|author)s?/.test(txt)) seenEditors = true;
        if (txt === "this version") key = "This";
        else if (txt === "latest version") key = "Latest";
        else if (/^previous version(?:s)?$/.test(txt)) key = "Previous";
        else if (/^rescinds this recommendation?$/.test(txt)) key = "Rescinds";
        if (key) dts[key] = { pos: idx, el: $dt, dd: $dd };
    });

    if (!dts.This) err("this-version");
    if (!dts.Latest) err("latest-version");
    if (prevRequired && !dts.Previous) err("previous-version");
    if (!prevRequired && dts.Previous) sr.warning(exports.name, "previous-not-needed");
    if (rescinds && !dts.Rescinds) err("rescinds");
    if (!rescinds && dts.Rescinds) sr.warning(exports.name, "rescinds-not-needed");

    if (dts.This && dts.Latest && dts.This.pos > dts.Latest.pos) err("this-latest-order");
    if (dts.Latest && dts.Previous && dts.Latest.pos > dts.Previous.pos) err("latest-previous-order");
    if (dts.Latest && dts.Rescinds && dts.Latest.pos > dts.Rescinds.pos) err("latest-rescinds-order");

    if (dts.This && dts.This.el && dts.This.dd && dts.This.el['0'] && dts.This.dd['0']) {
      sr.data.thisVersion = dts.This.el['0'] + ' ' + dts.This.dd['0'];
    }

    if (dts.Latest && dts.Latest.el && dts.Latest.dd && dts.Latest.el['0'] && dts.Latest.dd['0']) {
      sr.data.latestVersion = dts.Latest.el['0'] + ' ' + dts.Latest.dd['0'];
    }

    if (dts.Previous && dts.Previous.el && dts.Previous.dd && dts.Previous.el['0'] && dts.Previous.dd['0']) {
      sr.data.previousVersion = dts.Previous.el['0'] + ' ' + dts.Previous.dd['0'];
    }

    sr.data.latestVersion = dts.Latest || null;
    sr.data.previousVersion = dts.Previous || null;

    var shortname;
    if (dts.This) {
        var $linkThis = dts.This.dd.find("a").first();
        if (!$linkThis || !$linkThis.length || $linkThis.attr("href") !== $linkThis.text()) err("this-link");

        var vThisRex = "^https?:\\/\\/www\\.w3\\.org\\/" +
                       topLevel +
                       "\\/(\\d{4})\\/" +
                       (sr.config.status || "[A-Z]+") +
                       "-(.+)-(\\d{4})(\\d\\d)(\\d\\d)\\/?$";
        var matches = ($linkThis.attr("href") || "").match(new RegExp(vThisRex))
        ,   docDate = sr.getDocumentDate()
        ;
        if (matches) {
            var year = matches[1] * 1
            ,   year2 = matches[3] * 1
            ,   month = matches[4] * 1
            ,   day = matches[5] * 1
            ;
            shortname = matches[2];
            if (docDate) {
                if (year !== docDate.getFullYear() ||
                    year2 !== docDate.getFullYear() ||
                    month - 1 !== docDate.getMonth() ||
                    day !== docDate.getDate()
                   ) err("this-date");
            }
            else sr.warning(exports.name, "no-date");
        }
        else err("this-syntax");
    }

    if (dts.Latest) {
        var $linkLate = dts.Latest.dd.find("a").first();
        if (!$linkLate || !$linkLate.length || $linkLate.attr("href") !== $linkLate.text()) err("latest-link");

        var lateRex = "^https?:\\/\\/www\\.w3\\.org\\/" + topLevel + "\\/(.+?)\\/?$"
        ,   matches = ($linkLate.attr("href") || "").match(new RegExp(lateRex));
        if (matches) {
            var sn = matches[1];
            if (sn !== shortname) err("this-latest-shortname");
        }
        else err("latest-syntax");
    }

    if (dts.Previous) {
        var $linkPrev = dts.Previous.dd.find("a").first();
        if (!$linkPrev || !$linkPrev.length || $linkPrev.attr("href") !== $linkPrev.text()) err("previous-link");

        var prevRex = "^https?:\\/\\/www\\.w3\\.org\\/" + topLevel + "\\/\\d{4}\\/[A-Z]+-(.+)-\\d{8}\\/?$"
        ,   matches = ($linkPrev.attr("href") || "").match(new RegExp(prevRex))
        ;
        if (matches) {
            var sn = matches[1];
            if (sn !== shortname) err("this-previous-shortname");
        }
        else err("previous-syntax");
    }

    if (dts.Rescinds) {
        var $linkResc = dts.Rescinds.dd.find("a").first();
        if (!$linkResc || !$linkResc.length || $linkResc.attr("href") !== $linkResc.text()) err("rescinds-link");

        var matches = ($linkResc.attr("href") || "").match(/^https?:\/\/www\.w3\.org\/TR\/\d{4}\/REC-(.+)-\d{8}\/?$/);
        if (matches) {
            var sn = matches[1];
            if (sn !== shortname) err("this-rescinds-shortname");
        }
        else err("rescinds-syntax");
    }

    if (!seenEditors) err("editor");
    done();
};
<|endoftext|>


<commit_before>'use strict';
var async = require('async');

function saveApplication(args, callback) {
  var seneca = this;
  var ENTITY_NS = 'cd/applications';
  var applications = seneca.make(ENTITY_NS);

  var application = args.application;
  //TODO: Send email to user.

  async.waterfall([
    checkForApplication,
    saveEntity
  ], callback);

  //Make sure this user has not already applied for this event
  function checkForApplication(done) {
    applications.list$({userId:application.user_id, eventId: application.event_id}, function (err, response) {
      if(err) return done(err);
      if(response.length > 0) {
        return done(null, {error: 'User has already applied for this event.'});
      }
      return done(null, {});
    });
  }

  function saveEntity(status, done) {
    if(status.error) return done(status.err);
    if(application.parent_id) delete application.parent_id;
    applications.save$(application, done);
  }
}

module.exports = saveApplication;
<commit_msg>review fixes<commit_after>'use strict';
var async = require('async');

function saveApplication(args, callback) {
  var seneca = this;
  var ENTITY_NS = 'cd/applications';
  var applications = seneca.make(ENTITY_NS);

  var application = args.application;
  //TODO: Send email to user.

  async.waterfall([
    checkForApplication,
    saveEntity
  ], callback);

  //Make sure this user has not already applied for this event
  function checkForApplication(done) {
    applications.list$({userId:application.user_id, eventId: application.event_id}, function (err, response) {
      if(err) return done(err);
      if(response.length > 0) {
        return done(new Error('User has already applied for this event.'));
      }
      return done();
    });
  }

  function saveEntity(done) {
    if(application.parent_id) delete application.parent_id;
    applications.save$(application, done);
  }
}

module.exports = saveApplication;
<|endoftext|>


<commit_before>/**
 * Submit button for teacher feedback, will ask for
 * confirmation from teacher then send data to database.
 * @author: dv13trm, c14gls, group 6
*/

/**
 * Cancel button for popup window, closes popup.
 */
var PopUpCancelButton = React.createClass({
    onclick: function () {
        close();
    },
    render: function () {
        return(
            <button id="cancelButton" onClick={this.onclick}>Cancel</button>
        )
    }

});
/**
 * Confirmation button for popup, will send data to database then close window.
 */
var PopUpConfirmButton = React.createClass({
    onclick: function () {
        sendData();
        close();
        ReactDOM.render(<StudentList/>,document.getElementById('courseContent'));

    },
    render: function () {
        return(
            <button id="confirmationButton" onClick={this.onclick}>Save</button>

        )
    }
});
/**
 * Pass text for popup window, will get status from
 * checkbox then either put PASS or NOT PASSED in text.
 */
var PopUpPassBox = React.createClass({
    render: function () {
        if(document.getElementById('ifStudentPass').checked){
            return(

PASS

            )
        }else{
            return(

NOT PASSED

            )
        }
    }

});
/**
 * Grade for popup window, will get grade teacher selected
 * from previous window and put that into confirmation text.
 */
var PopUpGrade = React.createClass({

    render: function () {
        return(

{document.getElementById('dropDownMenu').value}

        )

    }
});
/**
 * Student name for popup window, will get student
 * selected for grading then put it into confirmation text.
 */
var PopUpStudentName = React.createClass({
    render: function () {

        return(

{this.props.student}

        )

    }
});
/**
 * Render text for popup window, this object do only create text for window.
 */
var PopUpRender = React.createClass({
    render: function () {
        return(

You are about to give

                <PopUpStudentName student={this.props.student}/>
a

                <PopUpPassBox/>
with grade
 <PopUpGrade/>
                <PopUpStudentName student={this.props.student}/>

will be notified

                    <PopUpCancelButton/>
                    <PopUpConfirmButton/>

        )
    }
});
/**
 * Hides popup window.
 */
function close(){
    var popUpElement = document.getElementById('popUpDiv');
    var blanketElement = document.getElementById('blanket');
    blanketElement.style.display='none';
    popUpElement.style.display='none';
}
/**
 * Submits data that will sent later, data in reqBody will be sent.
 */
function submitForm() {
    var reqBody = {};
    reqBody["TeacherComments"] = document.getElementById('teachercomments').value;
    reqBody["DropDown"] = document.getElementById('dropDownMenu').value;
    reqBody["StudentPass"] = document.getElementById('ifStudentPass').checked;
    reqBody["AssignmentID"] = window.assignmentID;
    reqBody["CourseID"] = window.courseID;
    reqBody["TeacherID"] = window.teacherID;

    $.ajax({
        type: "POST",
        contentType: "application/json",
        url: "feedback",
        data: JSON.stringify(reqBody),
        timeout: 100000,
        success: function (response) {
            console.log("SUCCESS: ", response);
            ReactDOM.render(
HEJ
, document.getElementById('courseContent'));
        }, error: function (e) {
            console.log("ERROR: ", e);
        }, done: function (e) {
            console.log("DONE");
        }
    });
}
/**
 * Sending data to database.
 */
function sendData () {
    // answer contains true if Ok is pressed., false if cancel is pressed.
    var passedStatus = 'No pass';
    // alert(document.getElementById('teachercomments').value);
    if (document.getElementById('ifStudentPass').checked) {
        passedStatus = 'Pass';
    } else {
        passedStatus = 'No pass'
    }
    submitForm();

}

/**
 * Creates the submit button used by the GUI.
 * Upon clicking on the button it sends the feedback information to the student.
 */
var SubmitButton = React.createClass({
    /**
     * Used to toggle on divs, make them visable.
     * @param div_id div that will be toggled.
     */
    toggle: function(div_id) {
        var element = document.getElementById(div_id);
        if ( element.style.display == 'none' ) {
            element.style.display = 'block';
        }
        else {
            element.style.display = 'none';
        }
    },
    /**
     * Crates popup on selected div.
     * @param div_id div that will generate popup.
     */
    popUpConfirmation: function (div_id) {
        this.blanket_size(div_id);
        this.window_pos(div_id);
        this.toggle("blanket");
        this.toggle(div_id);
        this.popUpRender();

    },
    /**
     * Rendering popup window in react class.
     */
    popUpRender: function () {
        ReactDOM.render(<PopUpRender student={this.props.student}/>,document.getElementById('popUpDiv'));
    },
    /**
     * Set size for popup blanket.
     * @param popUpDivVar Div that blanket will be generated on.
     */
    blanket_size: function(popUpDivVar) {
        var popUpDiv_height;
        var viewportheight;
        var blanket_height;
        if (typeof window.innerWidth != 'undefined') {
            viewportheight = window.innerHeight;
        } else {
            viewportheight = document.documentElement.clientHeight;
        }
        if ((viewportheight > document.body.parentNode.scrollHeight) &&
            (viewportheight > document.body.parentNode.clientHeight)) {
            blanket_height = viewportheight;
        } else {
            if (document.body.parentNode.clientHeight >
                document.body.parentNode.scrollHeight) {
                blanket_height = document.body.parentNode.clientHeight;
            } else {
                blanket_height = document.body.parentNode.scrollHeight;
            }
        }
        var blanket = document.getElementById('blanket');
        blanket.style.height = blanket_height + 'px';
        var popUpDiv = document.getElementById(popUpDivVar);
        popUpDiv_height=blanket_height/2-200;//200 is half popup's height
        popUpDiv.style.top = popUpDiv_height + 'px';
    },
    /**
     * Calculates window position based on window size.
     * @param popUpDivVar div that will be used for window.
     */
    window_pos: function(popUpDivVar) {
        var viewportwidth;
        var window_width;
        if (typeof window.innerWidth != 'undefined') {
            viewportwidth = window.innerHeight;
        } else {
            viewportwidth = document.documentElement.clientHeight;
        }
        if ((viewportwidth > document.body.parentNode.scrollWidth) &&
            (viewportwidth > document.body.parentNode.clientWidth)) {
            window_width = viewportwidth;
        } else {
            if (document.body.parentNode.clientWidth > document.body.parentNode.scrollWidth) {
                window_width = document.body.parentNode.clientWidth;
            } else {
                window_width = document.body.parentNode.scrollWidth;
            }
        }
        var popUpDiv = document.getElementById(popUpDivVar);
        window_width=window_width/2-200;//200 is half popup's width
        popUpDiv.style.left = window_width + 'px';
    },
    /**
     * onclick function for submit button.
     * Will check if textarea is empty then ask for confirmation
     * from user if they want to leave it empty. If yes popup window will be generated.
     */
    onClick: function() {
        if(document.getElementById('teachercomments').value===''){
            var saftyCheck = confirm("Are you sure you want to leave comment box empty?");
            if(saftyCheck){
                this.popUpConfirmation('popUpDiv');
            }else{
                void(0);
            }
        }else{
            this.popUpConfirmation('popUpDiv');
        }
    },
    /**
     * Render function for submitbutton.
     * @returns {XML} A button.
     */
    render: function () {
        return (
            <button id="submitbutton" onClick={this.onClick}>Submit</button>
        );
    }
});
window.SubmitButton=SubmitButton;<commit_msg>Submitbutton added data push<commit_after>/**
 * Submit button for teacher feedback, will ask for
 * confirmation from teacher then send data to database.
 * @author: dv13trm, c14gls, group 6
*/

/**
 * Cancel button for popup window, closes popup.
 */
var PopUpCancelButton = React.createClass({
    onclick: function () {
        close();
    },
    render: function () {
        return(
            <button id="cancelButton" onClick={this.onclick}>Cancel</button>
        )
    }

});
/**
 * Confirmation button for popup, will send data to database then close window.
 */
var PopUpConfirmButton = React.createClass({
    onclick: function () {
        sendData();
        close();
        ReactDOM.render(<StudentList/>,document.getElementById('courseContent'));

    },
    render: function () {
        return(
            <button id="confirmationButton" onClick={this.onclick}>Save</button>

        )
    }
});
/**
 * Pass text for popup window, will get status from
 * checkbox then either put PASS or NOT PASSED in text.
 */
var PopUpPassBox = React.createClass({
    render: function () {
        if(document.getElementById('ifStudentPass').checked){
            return(

PASS

            )
        }else{
            return(

NOT PASSED

            )
        }
    }

});
/**
 * Grade for popup window, will get grade teacher selected
 * from previous window and put that into confirmation text.
 */
var PopUpGrade = React.createClass({

    render: function () {
        return(

{document.getElementById('dropDownMenu').value}

        )

    }
});
/**
 * Student name for popup window, will get student
 * selected for grading then put it into confirmation text.
 */
var PopUpStudentName = React.createClass({
    render: function () {

        return(

{this.props.student}

        )

    }
});
/**
 * Render text for popup window, this object do only create text for window.
 */
var PopUpRender = React.createClass({
    render: function () {
        return(

You are about to give

                <PopUpStudentName student={this.props.student}/>
a

                <PopUpPassBox/>
with grade
 <PopUpGrade/>
                <PopUpStudentName student={this.props.student}/>

will be notified

                    <PopUpCancelButton/>
                    <PopUpConfirmButton/>

        )
    }
});
/**
 * Hides popup window.
 */
function close(){
    var popUpElement = document.getElementById('popUpDiv');
    var blanketElement = document.getElementById('blanket');
    blanketElement.style.display='none';
    popUpElement.style.display='none';
}
/**
 * Submits data that will sent later, data in reqBody will be sent.
 */
function submitForm() {
    var reqBody = {};
    reqBody["TeacherComments"] = document.getElementById('teachercomments').value;
    reqBody["Grade"] = document.getElementById('dropDownMenu').value;
    reqBody["StudentPass"] = document.getElementById('ifStudentPass').checked;
    reqBody["AssignmentID"] = window.assignmentID;
    reqBody["CourseID"] = window.courseID;
    reqBody["TeacherID"] = window.teacherID;
    reqBody["value"] = "set";

    $.ajax({
        type: "POST",
        contentType: "application/json",
        url: "feedback",
        data: JSON.stringify(reqBody),
        timeout: 100000,
        success: function (response) {
            console.log("SUCCESS: ", response);
            ReactDOM.render(
HEJ
, document.getElementById('courseContent'));
        }, error: function (e) {
            console.log("ERROR: ", e);
        }, done: function (e) {
            console.log("DONE");
        }
    });
}
/**
 * Sending data to database.
 */
function sendData () {
    // answer contains true if Ok is pressed., false if cancel is pressed.
    var passedStatus = 'No pass';
    // alert(document.getElementById('teachercomments').value);
    if (document.getElementById('ifStudentPass').checked) {
        passedStatus = 'Pass';
    } else {
        passedStatus = 'No pass'
    }
    submitForm();

}

/**
 * Creates the submit button used by the GUI.
 * Upon clicking on the button it sends the feedback information to the student.
 */
var SubmitButton = React.createClass({
    /**
     * Used to toggle on divs, make them visable.
     * @param div_id div that will be toggled.
     */
    toggle: function(div_id) {
        var element = document.getElementById(div_id);
        if ( element.style.display == 'none' ) {
            element.style.display = 'block';
        }
        else {
            element.style.display = 'none';
        }
    },
    /**
     * Crates popup on selected div.
     * @param div_id div that will generate popup.
     */
    popUpConfirmation: function (div_id) {
        this.blanket_size(div_id);
        this.window_pos(div_id);
        this.toggle("blanket");
        this.toggle(div_id);
        this.popUpRender();

    },
    /**
     * Rendering popup window in react class.
     */
    popUpRender: function () {
        ReactDOM.render(<PopUpRender student={this.props.student}/>,document.getElementById('popUpDiv'));
    },
    /**
     * Set size for popup blanket.
     * @param popUpDivVar Div that blanket will be generated on.
     */
    blanket_size: function(popUpDivVar) {
        var popUpDiv_height;
        var viewportheight;
        var blanket_height;
        if (typeof window.innerWidth != 'undefined') {
            viewportheight = window.innerHeight;
        } else {
            viewportheight = document.documentElement.clientHeight;
        }
        if ((viewportheight > document.body.parentNode.scrollHeight) &&
            (viewportheight > document.body.parentNode.clientHeight)) {
            blanket_height = viewportheight;
        } else {
            if (document.body.parentNode.clientHeight >
                document.body.parentNode.scrollHeight) {
                blanket_height = document.body.parentNode.clientHeight;
            } else {
                blanket_height = document.body.parentNode.scrollHeight;
            }
        }
        var blanket = document.getElementById('blanket');
        blanket.style.height = blanket_height + 'px';
        var popUpDiv = document.getElementById(popUpDivVar);
        popUpDiv_height=blanket_height/2-200;//200 is half popup's height
        popUpDiv.style.top = popUpDiv_height + 'px';
    },
    /**
     * Calculates window position based on window size.
     * @param popUpDivVar div that will be used for window.
     */
    window_pos: function(popUpDivVar) {
        var viewportwidth;
        var window_width;
        if (typeof window.innerWidth != 'undefined') {
            viewportwidth = window.innerHeight;
        } else {
            viewportwidth = document.documentElement.clientHeight;
        }
        if ((viewportwidth > document.body.parentNode.scrollWidth) &&
            (viewportwidth > document.body.parentNode.clientWidth)) {
            window_width = viewportwidth;
        } else {
            if (document.body.parentNode.clientWidth > document.body.parentNode.scrollWidth) {
                window_width = document.body.parentNode.clientWidth;
            } else {
                window_width = document.body.parentNode.scrollWidth;
            }
        }
        var popUpDiv = document.getElementById(popUpDivVar);
        window_width=window_width/2-200;//200 is half popup's width
        popUpDiv.style.left = window_width + 'px';
    },
    /**
     * onclick function for submit button.
     * Will check if textarea is empty then ask for confirmation
     * from user if they want to leave it empty. If yes popup window will be generated.
     */
    onClick: function() {
        if(document.getElementById('teachercomments').value===''){
            var saftyCheck = confirm("Are you sure you want to leave comment box empty?");
            if(saftyCheck){
                this.popUpConfirmation('popUpDiv');
            }else{
                void(0);
            }
        }else{
            this.popUpConfirmation('popUpDiv');
        }
    },
    /**
     * Render function for submitbutton.
     * @returns {XML} A button.
     */
    render: function () {
        return (
            <button id="submitbutton" onClick={this.onClick}>Submit</button>
        );
    }
});
window.SubmitButton=SubmitButton;<|endoftext|>


<commit_before>var hat = require('hat');
var livedb = require('livedb');
var Transform = require('stream').Transform;
var EventEmitter = require('events').EventEmitter;

var UserAgent = function(instance, stream) {
  if (!(this instanceof UserAgent)) return new UserAgent(instance, stream);

  this.instance = instance;
  this.backend = instance.backend;

  this.stream = stream;
  this.sessionId = hat();

  this.connectTime = new Date();
};

module.exports = UserAgent;

/**
 * Helper to run the filters over some data. Returns an error string on error,
 * or nothing on success.  Data is modified.
 *
 * Synchronous.
 */
UserAgent.prototype._runFilters = function(filters, collection, docName, data) {
  try {
    for (var i = 0; i < filters.length; i++) {
      var err = filters[i].call(this, collection, docName, data);
      if (err) return err;
    }
  } catch (e) {
    console.warn('filter threw an exception. Bailing.');
    console.error(e.stack);
    return e.message;
  }
};

UserAgent.prototype.filterDoc = function(collection, docName, data) {
  return this._runFilters(this.instance.docFilters, collection, docName, data);
};
UserAgent.prototype.filterOp = function(collection, docName, data) {
  return this._runFilters(this.instance.opFilters, collection, docName, data);
};

/** Helper to trigger actions */
UserAgent.prototype.trigger = function(action, collection, docName, extraFields, callback) {
  if (typeof extraFields === 'function') {
    callback = extraFields;
    extraFields = {};
  }

  var request = extraFields;
  request.agent = this;
  request.action = action;
  request.collection = collection;
  request.docName = docName;
  request.backend = this.backend;

  this.instance._trigger(request, callback);
};

UserAgent.prototype.fetch = function(collection, docName, callback) {
  var agent = this;

  agent.trigger('fetch', collection, docName, function(err, action) {
    if (err) return callback(err);
    collection = action.collection;
    docName = action.docName;

    agent.backend.fetch(collection, docName, function(err, data) {
      if (err) return callback(err);

      if (data) {
        err = agent.filterDoc(collection, docName, data);
      }
      callback(err, err ? null : data);
    });
  });
};

UserAgent.prototype.getOps = function(collection, docName, start, end, callback) {
  var agent = this;

  agent.trigger('getOps', collection, docName, {start:start, end:end}, function(err, action) {
    if (err) return callback(err);

    agent.backend.getOps(action.collection, action.docName, start, end, function(err, results) {
      if (err) return callback(err);

      if (results) {
        for (var i = 0; i < results.length; i++) {
          err = agent.filterOp(collection, docName, results[i]);

          // If there's an error, throw away all the results and return the error to the client.
          if (err) callback(err);
        }
      }
      callback(null, results);
    });
  });
};

/** Helper function to filter & rewrite wrap a stream of operations */
UserAgent.prototype.wrapOpStream = function(collection, docName, stream) {
  var agent = this;
  var passthrough = new Transform({objectMode:true});

  passthrough._transform = function(data, encoding, callback) {
    var err = agent.filterOp(collection, docName, data);
    if (err) {
      passthrough.push({error:err});
    } else {
      passthrough.push(data);
    }
    callback();
  };

  passthrough.destroy = function() { stream.destroy(); };

  stream.pipe(passthrough);

  return passthrough;
};

UserAgent.prototype.subscribe = function(collection, docName, version, callback) {
  var agent = this;
  agent.trigger('subscribe', collection, docName, {version:version}, function(err, action) {
    if (err) return callback(err);
    collection = action.collection;
    docName = agent.docName;
    agent.backend.subscribe(action.collection, action.docName, action.version, function(err, stream) {
       callback(err, err ? err : agent.wrapOpStream(collection, docName, stream));
    });
  });
};

UserAgent.prototype.fetchAndSubscribe = function(collection, docName, callback) {
  var agent = this;
  agent.trigger('fetch', collection, docName, function(err, action) {
    if (err) return callback(err);
    agent.trigger('subscribe', action.collection, action.docName, function(err, action) {
      if (err) return callback(err);

      collection = action.collection;
      docName = agent.docName;
      agent.backend.fetchAndSubscribe(action.collection, action.docName, function(err, data, stream) {
        if (!err && data) err = agent.filterDoc(collection, docName, data);

        if (err) return callback(err);

        var stream = agent.wrapOpStream(collection, docName, stream);
        callback(null, data, stream);
      });
    });
  });
};

UserAgent.prototype.submit = function(collection, docName, opData, callback) {
  var agent = this;
  agent.trigger('submit', collection, docName, {opData:opData}, function(err, action) {
    if (err) return callback(err);

    collection = action.collection;
    docName = action.docName;
    opData.preValidate = function(opData, oldSnapshot, callback) {
      agent.trigger('pre validate', collection, docName, {opData:opData, oldSnapshot:oldSnapshot}, callback);
    };
    opData.validate = function(opData, snapshot, callback) {
      agent.trigger('validate', collection, docName, {opData:opData, snapshot:snapshot}, callback);
    };

    agent.backend.submit(action.collection, action.docName, action.opData, callback);
  });
};

/** Helper to filter query result sets */
UserAgent.prototype._filterQueryResults = function(results) {
  for(var i = 0; i < results.length; i++) {
    var data = results[i];
    var err = this.filterDoc(data.c, data.docName, data);

    // If there's an error, throw away all the results. You can't have 'em!
    if (err) return err;
  }
};

UserAgent.prototype.queryFetch = function(collection, query, options, callback) {
  var agent = this;
  // Should we emit 'query' or 'query fetch' here?
  agent.trigger('query', collection, null, {query:query, fetch:true, options: options}, function(err, action) {
    if (err) return callback(err);

    collection = action.collection;
    query = action.query;

    agent.backend.queryFetch(collection, query, options, function(err, results, extra) {
      if (err) return callback(err);
      if (results) err = agent._filterQueryResults(results);
      if (err) callback(err);
      else callback(null, results, extra);
    });
  });
};

UserAgent.prototype.query = function(collection, query, options, callback) {
  var agent = this;
  agent.trigger('query', collection, null, {query:query, options:options}, function(err, action) {
    if (err) return callback(err);

    collection = action.collection;
    query = action.query;

    //console.log('query', query, options);
    agent.backend.query(collection, query, options, function(err, emitter) {
      if (!err && emitter) err = agent._filterQueryResults(emitter.data);
      if (err) return callback(err);

      // Wrap the query result event emitter
      var wrapped = new EventEmitter();
      wrapped.data = emitter.data;
      wrapped.extra = emitter.extra; // Can't filter this data. BE CAREFUL!

      wrapped.destroy = function() { emitter.destroy(); };

      emitter.on('diff', function(diff) {
        for (var i = 0; i < diff.length; i++) {
          if (diff[i].type === 'insert') {
            agent._filterQueryResults(diff[i].values);
          }
        }

        wrapped.emit('diff', diff);
      });
      emitter.on('extra', function(extra) {
        wrapped.emit('extra', extra);
      });

      callback(null, wrapped);
    });
  });
};

// 'query',

// filter snapshot
// filter op
// validate new data

<commit_msg>Added after submit hook<commit_after>var hat = require('hat');
var livedb = require('livedb');
var Transform = require('stream').Transform;
var EventEmitter = require('events').EventEmitter;

var UserAgent = function(instance, stream) {
  if (!(this instanceof UserAgent)) return new UserAgent(instance, stream);

  this.instance = instance;
  this.backend = instance.backend;

  this.stream = stream;
  this.sessionId = hat();

  this.connectTime = new Date();
};

module.exports = UserAgent;

/**
 * Helper to run the filters over some data. Returns an error string on error,
 * or nothing on success.  Data is modified.
 *
 * Synchronous.
 */
UserAgent.prototype._runFilters = function(filters, collection, docName, data) {
  try {
    for (var i = 0; i < filters.length; i++) {
      var err = filters[i].call(this, collection, docName, data);
      if (err) return err;
    }
  } catch (e) {
    console.warn('filter threw an exception. Bailing.');
    console.error(e.stack);
    return e.message;
  }
};

UserAgent.prototype.filterDoc = function(collection, docName, data) {
  return this._runFilters(this.instance.docFilters, collection, docName, data);
};
UserAgent.prototype.filterOp = function(collection, docName, data) {
  return this._runFilters(this.instance.opFilters, collection, docName, data);
};

/** Helper to trigger actions */
UserAgent.prototype.trigger = function(action, collection, docName, extraFields, callback) {
  if (typeof extraFields === 'function') {
    callback = extraFields;
    extraFields = {};
  }

  var request = extraFields;
  request.agent = this;
  request.action = action;
  if (collection) request.collection = collection;
  if (docName) request.docName = docName;
  request.backend = this.backend;

  this.instance._trigger(request, callback);
};

UserAgent.prototype.fetch = function(collection, docName, callback) {
  var agent = this;

  agent.trigger('fetch', collection, docName, function(err, action) {
    if (err) return callback(err);
    collection = action.collection;
    docName = action.docName;

    agent.backend.fetch(collection, docName, function(err, data) {
      if (err) return callback(err);

      if (data) {
        err = agent.filterDoc(collection, docName, data);
      }
      callback(err, err ? null : data);
    });
  });
};

UserAgent.prototype.getOps = function(collection, docName, start, end, callback) {
  var agent = this;

  agent.trigger('getOps', collection, docName, {start:start, end:end}, function(err, action) {
    if (err) return callback(err);

    agent.backend.getOps(action.collection, action.docName, start, end, function(err, results) {
      if (err) return callback(err);

      if (results) {
        for (var i = 0; i < results.length; i++) {
          err = agent.filterOp(collection, docName, results[i]);

          // If there's an error, throw away all the results and return the error to the client.
          if (err) callback(err);
        }
      }
      callback(null, results);
    });
  });
};

/** Helper function to filter & rewrite wrap a stream of operations */
UserAgent.prototype.wrapOpStream = function(collection, docName, stream) {
  var agent = this;
  var passthrough = new Transform({objectMode:true});

  passthrough._transform = function(data, encoding, callback) {
    var err = agent.filterOp(collection, docName, data);
    if (err) {
      passthrough.push({error:err});
    } else {
      passthrough.push(data);
    }
    callback();
  };

  passthrough.destroy = function() { stream.destroy(); };

  stream.pipe(passthrough);

  return passthrough;
};

UserAgent.prototype.subscribe = function(collection, docName, version, callback) {
  var agent = this;
  agent.trigger('subscribe', collection, docName, {version:version}, function(err, action) {
    if (err) return callback(err);
    collection = action.collection;
    docName = agent.docName;
    agent.backend.subscribe(action.collection, action.docName, action.version, function(err, stream) {
       callback(err, err ? err : agent.wrapOpStream(collection, docName, stream));
    });
  });
};

UserAgent.prototype.fetchAndSubscribe = function(collection, docName, callback) {
  var agent = this;
  agent.trigger('fetch', collection, docName, function(err, action) {
    if (err) return callback(err);
    agent.trigger('subscribe', action.collection, action.docName, function(err, action) {
      if (err) return callback(err);

      collection = action.collection;
      docName = agent.docName;
      agent.backend.fetchAndSubscribe(action.collection, action.docName, function(err, data, stream) {
        if (!err && data) err = agent.filterDoc(collection, docName, data);

        if (err) return callback(err);

        var stream = agent.wrapOpStream(collection, docName, stream);
        callback(null, data, stream);
      });
    });
  });
};

UserAgent.prototype.submit = function(collection, docName, opData, callback) {
  var agent = this;
  agent.trigger('submit', collection, docName, {opData:opData}, function(err, action) {
    if (err) return callback(err);

    collection = action.collection;
    docName = action.docName;
    opData.preValidate = function(opData, oldSnapshot, callback) {
      agent.trigger('pre validate', collection, docName, {opData:opData, oldSnapshot:oldSnapshot}, callback);
    };
    opData.validate = function(opData, snapshot, callback) {
      agent.trigger('validate', collection, docName, {opData:opData, snapshot:snapshot}, callback);
    };

    agent.backend.submit(action.collection, action.docName, action.opData, function(err, v, ops) {
      if (err) callback(err);

      agent.trigger('after submit', null, null, action, function() {
        callback(err, v, ops);
      }
    });
  });
};

/** Helper to filter query result sets */
UserAgent.prototype._filterQueryResults = function(results) {
  for(var i = 0; i < results.length; i++) {
    var data = results[i];
    var err = this.filterDoc(data.c, data.docName, data);

    // If there's an error, throw away all the results. You can't have 'em!
    if (err) return err;
  }
};

UserAgent.prototype.queryFetch = function(collection, query, options, callback) {
  var agent = this;
  // Should we emit 'query' or 'query fetch' here?
  agent.trigger('query', collection, null, {query:query, fetch:true, options: options}, function(err, action) {
    if (err) return callback(err);

    collection = action.collection;
    query = action.query;

    agent.backend.queryFetch(collection, query, options, function(err, results, extra) {
      if (err) return callback(err);
      if (results) err = agent._filterQueryResults(results);
      if (err) callback(err);
      else callback(null, results, extra);
    });
  });
};

UserAgent.prototype.query = function(collection, query, options, callback) {
  var agent = this;
  agent.trigger('query', collection, null, {query:query, options:options}, function(err, action) {
    if (err) return callback(err);

    collection = action.collection;
    query = action.query;

    //console.log('query', query, options);
    agent.backend.query(collection, query, options, function(err, emitter) {
      if (!err && emitter) err = agent._filterQueryResults(emitter.data);
      if (err) return callback(err);

      // Wrap the query result event emitter
      var wrapped = new EventEmitter();
      wrapped.data = emitter.data;
      wrapped.extra = emitter.extra; // Can't filter this data. BE CAREFUL!

      wrapped.destroy = function() { emitter.destroy(); };

      emitter.on('diff', function(diff) {
        for (var i = 0; i < diff.length; i++) {
          if (diff[i].type === 'insert') {
            agent._filterQueryResults(diff[i].values);
          }
        }

        wrapped.emit('diff', diff);
      });
      emitter.on('extra', function(extra) {
        wrapped.emit('extra', extra);
      });

      callback(null, wrapped);
    });
  });
};

// 'query',

// filter snapshot
// filter op
// validate new data

<|endoftext|>