<commit_before>const http = require('http'),
			Promise = require('bluebird'),
			url = require('url'),
			baseUrl = 'http://m.mlb.com/lookup/json';

var cornelius = function () {};

cornelius.prototype.findPlayer = function (playerName, pruned) {
	return new Promise(function (resolve, reject) {

		if (!playerName) {
			reject(new Error('No player name provided.'));
		}

		let uri = url.parse(baseUrl + '/named.search_player_all.bam?sport_code=\'mlb\'&name_part=\'' + playerName + '%25\'&active_sw=\'Y\'');

		let options = {
			host: uri.host,
			path: uri.path
		};

		http.get(options, function (res) {
			const statusCode = res.statusCode;
			const contentType = res.headers['content-type'];

			let error;

			if (statusCode !== 200) {
				error = new Error(`${statusCode} - Request failed.`);
			} else if (!/^application\/json/.test(contentType)) {
				error = new Error(`Invalid content type received. Expected JSON, got ${contentType}`);
			}
			if (error) {
				res.resume();
				reject(error);
			}

			res.setEncoding('utf8');
			let rawData = '';
			res.on('data', (chunk) => { rawData += chunk; });
			res.on('end', () => {
				try {
					const parsedData = JSON.parse(rawData);
					let hasPlayerResults = parsedData.search_player_all.queryResults.totalSize > 0;
					if (!hasPlayerResults) {
						reject(new Error(`No player with the name ${playerName} exists.`));
					}
					if (pruned === true) {
						const prunedData = pruneData(parsedData);
						resolve(prunedData);
					}
					resolve(parsedData.search_player_all.queryResults);
				} catch (e) {
					reject(e)
				}
			});
		}).on('error', (e) => {
			reject(e);
		});

	});
};

cornelius.prototype.getPlayer = function (playerName, givenKey) {
		return new Promise(function (resolve, reject) {

			var isFullName = playerName.split(' ').length > 1;
			let error;

			if (!isFullName || !playerName) {
				error = new Error(`Player's full name required for getPlayer.`);
			} else if (!givenKey) {
				error = new Error(`Team code or player ID required for getPlayer.`);
			}

			if (error) {
				reject(error);
			}

			var uri = url.parse(baseUrl + '/named.search_player_all.bam?sport_code=\'mlb\'&name_part=\'' + playerName + '%25\'&active_sw=\'Y\'');

			var options = {
				host: uri.host,
				path: uri.path
			};

			http.get(options, function (res) {
				const statusCode = res.statusCode;
				const contentType = res.headers['content-type'];

				let error;

				if (statusCode !== 200) {
					error = new Error(`${statusCode} - Request failed.`);
				} else if (!/^application\/json/.test(contentType)) {
					error = new Error(`Invalid content type received. Expected JSON, got ${contentType}`);
				}

				if (error) {
					res.resume();
					reject(error);
				}

				res.setEncoding('utf8');
				let rawData = '';
				res.on('data', (chunk) => { rawData += chunk; });
				res.on('end', () => {
					try {
						const parsedData = JSON.parse(rawData);
						const player = findPlayerInResults(parsedData, givenKey);
						resolve(player);
					} catch (e) {
						reject(e)
					}
				});
			}).on('error', (e) => {
				reject(e);
			});

	});
};

module.exports = new cornelius();

function findPlayerInResults(data, key) {
	var resultsCount = data.search_player_all.queryResults.totalSize;
	var requestedPlayer = {};
	var key = key.toUpperCase();

	function hasMatchingKey(player) {
		if (player.team_abbrev === key || player.player_id === key) {
			return true;
		}
		return false;
	}

	var results = data.search_player_all.queryResults.row;

	if (resultsCount > 1) {
		var p = results.findIndex(hasMatchingKey);
		requestedPlayer = results[p];
	} else if (resultsCount == 1) {
		requestedPlayer = results;
	}

	return requestedPlayer

}

function pruneData(data) {
	var prunedData = [];
	var players = data.search_player_all.queryResults.row;

	if (data.search_player_all.queryResults.totalSize > 0) {
		players.forEach(function(player) {
			prunedData.push(player);
		});
	}

	return prunedData;

}
<commit_msg>add quotemarks to no player results error message<commit_after>const http = require('http'),
			Promise = require('bluebird'),
			url = require('url'),
			baseUrl = 'http://m.mlb.com/lookup/json';

var cornelius = function () {};

cornelius.prototype.findPlayer = function (playerName, pruned) {
	return new Promise(function (resolve, reject) {

		if (!playerName) {
			reject(new Error('No player name provided.'));
		}

		let uri = url.parse(baseUrl + '/named.search_player_all.bam?sport_code=\'mlb\'&name_part=\'' + playerName + '%25\'&active_sw=\'Y\'');

		let options = {
			host: uri.host,
			path: uri.path
		};

		http.get(options, function (res) {
			const statusCode = res.statusCode;
			const contentType = res.headers['content-type'];

			let error;

			if (statusCode !== 200) {
				error = new Error(`${statusCode} - Request failed.`);
			} else if (!/^application\/json/.test(contentType)) {
				error = new Error(`Invalid content type received. Expected JSON, got ${contentType}`);
			}
			if (error) {
				res.resume();
				reject(error);
			}

			res.setEncoding('utf8');
			let rawData = '';
			res.on('data', (chunk) => { rawData += chunk; });
			res.on('end', () => {
				try {
					const parsedData = JSON.parse(rawData);
					let hasPlayerResults = parsedData.search_player_all.queryResults.totalSize > 0;
					if (!hasPlayerResults) {
						reject(new Error(`No player with the name '${playerName}' exists.`));
					}
					if (pruned === true) {
						const prunedData = pruneData(parsedData);
						resolve(prunedData);
					}
					resolve(parsedData.search_player_all.queryResults);
				} catch (e) {
					reject(e)
				}
			});
		}).on('error', (e) => {
			reject(e);
		});

	});
};

cornelius.prototype.getPlayer = function (playerName, givenKey) {
		return new Promise(function (resolve, reject) {

			var isFullName = playerName.split(' ').length > 1;
			let error;

			if (!isFullName || !playerName) {
				error = new Error(`Player's full name required for getPlayer.`);
			} else if (!givenKey) {
				error = new Error(`Team code or player ID required for getPlayer.`);
			}

			if (error) {
				reject(error);
			}

			var uri = url.parse(baseUrl + '/named.search_player_all.bam?sport_code=\'mlb\'&name_part=\'' + playerName + '%25\'&active_sw=\'Y\'');

			var options = {
				host: uri.host,
				path: uri.path
			};

			http.get(options, function (res) {
				const statusCode = res.statusCode;
				const contentType = res.headers['content-type'];

				let error;

				if (statusCode !== 200) {
					error = new Error(`${statusCode} - Request failed.`);
				} else if (!/^application\/json/.test(contentType)) {
					error = new Error(`Invalid content type received. Expected JSON, got ${contentType}`);
				}

				if (error) {
					res.resume();
					reject(error);
				}

				res.setEncoding('utf8');
				let rawData = '';
				res.on('data', (chunk) => { rawData += chunk; });
				res.on('end', () => {
					try {
						const parsedData = JSON.parse(rawData);
						const player = findPlayerInResults(parsedData, givenKey);
						resolve(player);
					} catch (e) {
						reject(e)
					}
				});
			}).on('error', (e) => {
				reject(e);
			});

	});
};

module.exports = new cornelius();

function findPlayerInResults(data, key) {
	var resultsCount = data.search_player_all.queryResults.totalSize;
	var requestedPlayer = {};
	var key = key.toUpperCase();

	function hasMatchingKey(player) {
		if (player.team_abbrev === key || player.player_id === key) {
			return true;
		}
		return false;
	}

	var results = data.search_player_all.queryResults.row;

	if (resultsCount > 1) {
		var p = results.findIndex(hasMatchingKey);
		requestedPlayer = results[p];
	} else if (resultsCount == 1) {
		requestedPlayer = results;
	}

	return requestedPlayer

}

function pruneData(data) {
	var prunedData = [];
	var players = data.search_player_all.queryResults.row;

	if (data.search_player_all.queryResults.totalSize > 0) {
		players.forEach(function(player) {
			prunedData.push(player);
		});
	}

	return prunedData;

}
<|endoftext|>


<commit_before>var lineIntersect = require('line-intersect');
var Vec2 = require('vec2');

/**
* Finds where a ray hits a line segment, if at all.
*
* @param {object} rayish
* @param {object} segment
* @return {object} point (x/y) where ray hits segment or null if it doesn't hit
*/
function rayVsLineSegment(rayish, segment) {
  var result = lineIntersect.checkIntersection(
    rayish.start.x, rayish.start.y, rayish.end.x, rayish.end.y,
    segment.start.x, segment.start.y, segment.end.x, segment.end.y
  );

  // definitely no intersection
  if (result.type == 'none' || result.type == 'parallel') return null;

  // single intersection point
  if (result.type == 'intersecting') return result.point;

  // colinear, so now check if ray/segment overlap
  if (segmentContainsPoint(segment, rayish.start)) {
    return rayish.start;
  } else {
    // return segment endpoint that is
    //   - within ray
    //   - closest to ray start
    var rayStart = new Vec2(rayish.start);
    var endpointsInRay = segmentEndpointsInRay(rayish, segment);
    return rayStart.nearest(endpointsInRay);
  }
}

function segmentContainsPoint(segment, point) {
  return lineIntersect.colinearPointWithinSegment(
    point.x, point.y,
    segment.start.x, segment.start.y,
    segment.end.x, segment.end.y
  );
}

function segmentEndpointsInRay(rayish, segment) {
  return [segment.start, segment.end].map(function(p) {
    return new Vec2(p);
  }).filter(function(vec) {
    return segmentContainsPoint(rayish, vec);
  });
}

module.exports = rayVsLineSegment;
<commit_msg>update comment<commit_after>var lineIntersect = require('line-intersect');
var Vec2 = require('vec2');

/**
* Finds where a ray hits a line segment, if at all.
*
* @param {object} ray - Object that looks like
* {
*   start: {x: number, y: number},
*   end: {x: number, y: number}
* }
*
* @param {object} segment - Object that looks like
* {
*   start: {x: number, y: number},
*   end: {x: number, y: number}
* }
*
* @return {object} point (x/y) where ray hits segment or null if it doesn't hit
*/
function rayVsLineSegment(rayish, segment) {
  var result = lineIntersect.checkIntersection(
    rayish.start.x, rayish.start.y, rayish.end.x, rayish.end.y,
    segment.start.x, segment.start.y, segment.end.x, segment.end.y
  );

  // definitely no intersection
  if (result.type == 'none' || result.type == 'parallel') return null;

  // single intersection point
  if (result.type == 'intersecting') return result.point;

  // colinear, so now check if ray/segment overlap
  if (segmentContainsPoint(segment, rayish.start)) {
    return rayish.start;
  } else {
    // return segment endpoint that is
    //   - within ray
    //   - closest to ray start
    var rayStart = new Vec2(rayish.start);
    var endpointsInRay = segmentEndpointsInRay(rayish, segment);
    return rayStart.nearest(endpointsInRay);
  }
}

function segmentContainsPoint(segment, point) {
  return lineIntersect.colinearPointWithinSegment(
    point.x, point.y,
    segment.start.x, segment.start.y,
    segment.end.x, segment.end.y
  );
}

function segmentEndpointsInRay(rayish, segment) {
  return [segment.start, segment.end].map(function(p) {
    return new Vec2(p);
  }).filter(function(vec) {
    return segmentContainsPoint(rayish, vec);
  });
}

module.exports = rayVsLineSegment;
<|endoftext|>


<commit_before>//First we need to require the 'pg' module
var pg = require('pg');
//Next we define a connection string. This string follows a syntax to provide the
//connection protocol, username, password, host, post, and database name. For a
//localhost database it is simple
var connectionString = 'postgres://localhost/booktown';

//Now we access a PostgreSQL client
//There's a way to construct a single client, but I only recommend using the 'pg'
//module's client pooling feature.

//Step 2

//We pass the connect function our database connection string, and a callback function
//'onConnect'. We will now define that function.
pg.connect(connectionString, onConnect);

function onConnect(err, client, done) {
  //Err - This means something went wrong connecting to the database. The credentials
  //may be incorrect, the host down, and database doesn't exist.
  //For now, let's console.error this message if it exists and exit the process
  //with a non zero error code.
  if (err) {
    console.error(err);
    process.exit(1);
  }
  //Now we have a 'client' and a 'done' callback.
  //We can use the client to run sql queries for booktown.

  //For now let's end client
  client.end();
}

//Step 3
//We want to build a nice API for creating query code and functions to process
//the data from queries. Let's use a combination of functional programming and
//callbacks to acheive our API.
//For this example let's keep our feature set limited. We will build an api for
//selecting collections with an optional limit
var _ = require('underscore');
//Now we'll use the _.partial function to make a convience function called connectWithConnectionString.
var connectWithConnectionString =  _.bind(_.partial(pg.connect, connectionString), pg);
//connectWithConnectionString is still using pg.connect underneath. It will automatically apply the
//connection string each time we call connectWithConnectionString. So now the API is
//connectWithConnectionString(function(err, client, done) { //your code here })

//OK Cool! So now when we want a PostgreSQL client we only need to worry about the callback
//function. Can we do better? Yes, let's handle the connection 'err' object the same for
//every callback

function buildSelectQuery(tableName) {
  return ['select * from', tableName].join(' ');
}

function buildQueryClient(query) {
  return function(onQueryReturn) {
    connectWithConnectionString(function(err, client, done) {
      console.log(done.toString())
      if (err) {
        return onQueryReturn(new Error(['Database Connection Failed with Error', err.toString()].join(' ')));
      } else {
        client.query(query, function(err, results) {
          done(err);
          onQueryReturn(err, results);
        });
      }
    });
  }
}

function selectAll(tableName) {
  return function(onSelectReturn) {
    var sql = buildSelectQuery(tableName);
    var queryClient = buildQueryClient(sql);
    queryClient(function(err, tableValues) {
      if (err) {
        return onSelectReturn(new Error(['Select all failed on', tableName, 'with error', err.toString()].join(' ')));
      } else {
        return onSelectReturn(null, tableValues);
      }
    });
  }
}

var printRows = function() {
  return function(err, results) {
    if (err) console.error(err)
    else console.log(results.rows);
  }
}

var selectAllShipments = selectAll('shipments');
selectAllShipments(printRows());

//Step 4 - Building on this API
//Now when you want to select all rows from other collections you can build
//a function using selectAll.
var selectAllBooks = selectAll('books')
selectAllBooks(printRows())

//This code will shutdown the 'pg' module's pool so the program exits
setTimeout(pg.end.apply(pg), 5000);
<commit_msg>Example prototype method<commit_after>//First we need to require the 'pg' module
var pg = require('pg');
//Next we define a connection string. This string follows a syntax to provide the
//connection protocol, username, password, host, post, and database name. For a
//localhost database it is simple
var connectionString = 'postgres://localhost/booktown';

//Now we access a PostgreSQL client
//There's a way to construct a single client, but I only recommend using the 'pg'
//module's client pooling feature.

//Step 2

//We pass the connect function our database connection string, and a callback function
//'onConnect'. We will now define that function.
pg.connect(connectionString, onConnect);

function onConnect(err, client, done) {
  //Err - This means something went wrong connecting to the database. The credentials
  //may be incorrect, the host down, and database doesn't exist.
  //For now, let's console.error this message if it exists and exit the process
  //with a non zero error code.
  if (err) {
    console.error(err);
    process.exit(1);
  }
  //Now we have a 'client' and a 'done' callback.
  //We can use the client to run sql queries for booktown.

  //For now let's end client
  client.end();
}

//Step 3
//We want to build a nice API for creating query code and functions to process
//the data from queries. Let's use a combination of functional programming and
//callbacks to acheive our API.
//For this example let's keep our feature set limited. We will build an api for
//selecting collections with an optional limit
var _ = require('underscore');
//Now we'll use the _.partial function to make a convience function called connectWithConnectionString.
var connectWithConnectionString =  _.bind(_.partial(pg.connect, connectionString), pg);
//connectWithConnectionString is still using pg.connect underneath. It will automatically apply the
//connection string each time we call connectWithConnectionString. So now the API is
//connectWithConnectionString(function(err, client, done) { //your code here })

//OK Cool! So now when we want a PostgreSQL client we only need to worry about the callback
//function. Can we do better? Yes, let's handle the connection 'err' object the same for
//every callback

function buildSelectQuery(tableName) {
  return ['select * from', tableName].join(' ');
}

function buildQueryClient(query) {
  return function(onQueryReturn) {
    connectWithConnectionString(function(err, client, done) {
      console.log(done.toString())
      if (err) {
        return onQueryReturn(new Error(['Database Connection Failed with Error', err.toString()].join(' ')));
      } else {
        client.query(query, function(err, results) {
          done(err);
          onQueryReturn(err, results);
        });
      }
    });
  }
}

function selectAll(tableName) {
  return function(onSelectReturn) {
    var sql = buildSelectQuery(tableName);
    var queryClient = buildQueryClient(sql);
    queryClient(function(err, tableValues) {
      if (err) {
        return onSelectReturn(new Error(['Select all failed on', tableName, 'with error', err.toString()].join(' ')));
      } else {
        return onSelectReturn(null, tableValues);
      }
    });
  }
}

var printRows = function(text) {
  return function(err, results) {
    if (err) console.error(err)
    else console.log(results.rows);
    console.log(text);
  }
}

var selectAllShipments = selectAll('shipments');
selectAllShipments(printRows());

//Step 4 - Building on this API
//Now when you want to select all rows from other collections you can build
//a function using selectAll.
var selectAllBooks = selectAll('books')
selectAllBooks(printRows())
var selectAllAuthors = selectAll('authors')
selectAllAuthors(printRows());
//You get the idea. We use the selectAll function generating function to build
//specifically named functions. These functions could be made into methods on
//their appropriate objects.

//Author Function
function AuthorCtrl() {

}
AuthorCtrl.prototype.selectAll = selectAllAuthors;
//Try using the AuthorCtrl.selectAllMethod
var authorCtrl = new AuthorCtrl();
authorCtrl.selectAll(printRows('Im from the Author Controller'));

//This code will shutdown the 'pg' module's pool so the program exits
setTimeout(pg.end.apply(pg), 5000);
<|endoftext|>


<commit_before>/*
* @providesModule react-native-call-detection
*/
import {
  NativeModules,
  NativeEventEmitter,
  Platform,
  PermissionsAndroid
} from 'react-native'
export const permissionDenied = 'PERMISSION DENIED'

const BatchedBridge = require('react-native/Libraries/BatchedBridge/BatchedBridge')

const NativeCallDetector = NativeModules.CallDetectionManager
const NativeCallDetectorAndroid = NativeModules.CallDetectionManagerAndroid

var CallStateUpdateActionModule = require('./CallStateUpdateActionModule')
BatchedBridge.registerCallableModule('CallStateUpdateActionModule', CallStateUpdateActionModule)

const requestPermissionsAndroid = async (permissionMessage) => {
    return await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE)
      .then(async (gotPermission) => gotPermission
          ? true
          : await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE, permissionMessage)
              .then((result) => result === PermissionsAndroid.RESULTS.GRANTED)
        )
}

class CallDetectorManager {

    subscription;
    callback
    constructor(callback, readPhoneNumberAndroid = false, permissionDeniedCallback = ()=>{}, permissionMessage = {
      title: 'Phone State Permission',
      message: 'This app needs access to your phone state in order to react and/or to adapt to incoming calls.'
    }) {
        this.callback = callback
        if (Platform.OS === 'ios') {
            NativeCallDetector && NativeCallDetector.startListener()
            this.subscription = new NativeEventEmitter(NativeCallDetector)
            this.subscription.addListener('PhoneCallStateUpdate', callback);
        }
        else {
            if(NativeCallDetectorAndroid) {
              if(readPhoneNumberAndroid) {
                requestPermissionsAndroid(permissionMessage)
                  .then((permissionGranted) => {
                    if (!permissionGranted) {
                      permissionDeniedCallback(permissionDenied)
                    }
                  })
                  .catch(permissionDeniedCallback)
              }
              NativeCallDetectorAndroid.startListener();
            }
            CallStateUpdateActionModule.callback = callback
        }
    }

    dispose() {
    	NativeCallDetector && NativeCallDetector.stopListener()
    	NativeCallDetectorAndroid && NativeCallDetectorAndroid.stopListener()
        CallStateUpdateActionModule.callback = undefined
      if(this.subscription) {
          this.subscription.removeAllListeners('PhoneCallStateUpdate');
          this.subscription = undefined
      }
    }
}
export default module.exports = CallDetectorManager;
<commit_msg>simplified promise calls in index.js<commit_after>/*
* @providesModule react-native-call-detection
*/
import {
  NativeModules,
  NativeEventEmitter,
  Platform,
  PermissionsAndroid
} from 'react-native'
export const permissionDenied = 'PERMISSION DENIED'

const BatchedBridge = require('react-native/Libraries/BatchedBridge/BatchedBridge')

const NativeCallDetector = NativeModules.CallDetectionManager
const NativeCallDetectorAndroid = NativeModules.CallDetectionManagerAndroid

var CallStateUpdateActionModule = require('./CallStateUpdateActionModule')
BatchedBridge.registerCallableModule('CallStateUpdateActionModule', CallStateUpdateActionModule)

const requestPermissionsAndroid = (permissionMessage) => {
    return PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE)
      .then((gotPermission) => gotPermission
          ? true
          : PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE, permissionMessage)
              .then((result) => result === PermissionsAndroid.RESULTS.GRANTED)
        )
}

class CallDetectorManager {

    subscription;
    callback
    constructor(callback, readPhoneNumberAndroid = false, permissionDeniedCallback = ()=>{}, permissionMessage = {
      title: 'Phone State Permission',
      message: 'This app needs access to your phone state in order to react and/or to adapt to incoming calls.'
    }) {
        this.callback = callback
        if (Platform.OS === 'ios') {
            NativeCallDetector && NativeCallDetector.startListener()
            this.subscription = new NativeEventEmitter(NativeCallDetector)
            this.subscription.addListener('PhoneCallStateUpdate', callback);
        }
        else {
            if(NativeCallDetectorAndroid) {
              if(readPhoneNumberAndroid) {
                requestPermissionsAndroid(permissionMessage)
                  .then((permissionGranted) => {
                    if (!permissionGranted) {
                      permissionDeniedCallback(permissionDenied)
                    }
                  })
                  .catch(permissionDeniedCallback)
              }
              NativeCallDetectorAndroid.startListener();
            }
            CallStateUpdateActionModule.callback = callback
        }
    }

    dispose() {
    	NativeCallDetector && NativeCallDetector.stopListener()
    	NativeCallDetectorAndroid && NativeCallDetectorAndroid.stopListener()
        CallStateUpdateActionModule.callback = undefined
      if(this.subscription) {
          this.subscription.removeAllListeners('PhoneCallStateUpdate');
          this.subscription = undefined
      }
    }
}
export default module.exports = CallDetectorManager;
<|endoftext|>


<commit_before>'use strict';

var del = require('del');
var GlobalsFormatter = require('es6-module-transpiler-globals-formatter');
var gulp = require('gulp');
var gutil = require('gulp-util');
var jspm = require('jspm');
var jspmCore = require('jspm/lib/core');
var karma = require('karma').server;
var merge = require('merge');
var open = require('open');
var path = require('path');
var plugins = require('gulp-load-plugins')();
var renamer = require('gulp-es6-imports-renamer');
var runSequence = require('run-sequence');
var sourcemaps = require('gulp-sourcemaps');
var babel = require('gulp-babel');
var through = require('through2');
var transpile = require('gulp-es6-module-transpiler');
var tunic = require('tunic');

function handleError(error) {
  console.error(error.toString());

  this.emit('end');
}

module.exports = function(options) {
  var bundleFileName = options.bundleFileName;
  var corePathFromSoy = options.corePathFromSoy || 'aui';
  var shouldSkipSoyTemplatesGeneration = options.shouldSkipSoyTemplatesGeneration;

  gulp.task('build', function(done) {
    runSequence('clean', ['soy', 'copy'], ['build:globals', 'build:min'], done);
  });

  gulp.task('build:globals', ['jspm'], function() {
    return gulp.src('src/**/*.js')
      .pipe(sourcemaps.init())
      .pipe(renamer({
        basePath: process.cwd(),
        configPath: path.resolve('config.js')
      })).on('error', handleError)
      .pipe(transpile({
        basePath: process.cwd(),
        bundleFileName: bundleFileName,
        formatter: new GlobalsFormatter({
          globalName: 'aui'
        })
      }))
      .pipe(babel({
        blacklist: 'useStrict',
        compact: false
      })).on('error', handleError)
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('build'));
  });

  gulp.task('build:min', ['build:globals'], function() {
    return gulp.src(path.join('build/', bundleFileName))
      .pipe(plugins.rename(function(path) {
        path.basename += '-min';
      }))
      .pipe(plugins.uglify({
        compress: {
          drop_console: true
        },
        preserveComments: 'some'
      }))
      .pipe(banner(options.pkg))
      .pipe(gulp.dest('build'));
  });

  gulp.task('clean', function(done) {
    del(['build'], done);
  });

  gulp.task('copy', function() {
    return gulp.src('src/**/*.css')
      .pipe(gulp.dest('build'));
  });

  gulp.task('jspm', function(done) {
    jspm.promptDefaults(true);
    jspm.install(true, {
      lock: true
    }).then(function() {
      return jspmCore.checkDlLoader();
    }).then(function() {
      return jspmCore.setMode('local');
    }).then(function() {
      gutil.log(gutil.colors.cyan('Install complete'));
      done();
    }, function(err) {
      gutil.log(gutil.colors.red('err', err.stack || err));
      gutil.log(gutil.colors.red('Installation changes not saved.'));
      done();
    });
  });

  gulp.task('lint', function() {
    return gulp.src(['src/**/*.js', 'test/**/*.js'])
      .pipe(plugins.jshint())
      .pipe(plugins.jshint.reporter(require('jshint-stylish')));
  });

  gulp.task('soy', function() {
    return gulp.src('src/**/*.soy')
      .pipe(plugins.if(!shouldSkipSoyTemplatesGeneration, generateTemplatesAndExtractParams()))
      .pipe(plugins.if(!shouldSkipSoyTemplatesGeneration, gulp.dest('build')))
      .pipe(plugins.soynode({
        loadCompiledTemplates: false,
        shouldDeclareTopLevelNamespaces: false
      }))
      .pipe(plugins.ignore.exclude('*.soy'))
      .pipe(plugins.wrapper({
        header: getHeaderContent(corePathFromSoy),
        footer: getFooterContent
      }))
      .pipe(gulp.dest('src'));
  });

  gulp.task('test', function(done) {
    return runSequence('test:unit', /*'test:complexity', TODO(edu): ES6.*/ done);
  });

  gulp.task('test:complexity', function() {
    return gulp.src(['src/**/*.js', '!src/**/*.soy.js', '!src/promise/Promise.js', 'test/**/*.js'])
      .pipe(babel())
      .pipe(plugins.complexity({
        halstead: [15, 15, 20]
      }));
  });

  gulp.task('test:unit', ['jspm', 'soy'], function(done) {
    runKarma({}, done);
  });

  gulp.task('test:coverage', ['jspm', 'soy'], function(done) {
    runKarma({}, function() {
      open(path.resolve('coverage/lcov/lcov-report/index.html'));
      done();
    });
  });

  gulp.task('test:browsers', ['jspm', 'soy'], function(done) {
    runKarma({
      browsers: ['Chrome', 'Firefox', 'Safari', 'IE9 - Win7', 'IE10 - Win7', 'IE11 - Win7']
    }, done);
  });

  gulp.task('test:saucelabs', ['jspm', 'soy'], function(done) {
    var launchers = {
      sl_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome'
      },
      sl_safari: {
        base: 'SauceLabs',
        browserName: 'safari'
      },
      sl_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox'
      },
      sl_ie_9: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '9'
      },
      sl_ie_10: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '10'
      },
      sl_ie_11: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 8.1',
        version: '11'
      },
      sl_iphone: {
        base: 'SauceLabs',
        browserName: 'iphone',
        platform: 'OS X 10.10',
        version: '7.1'
      },
      sl_android_4: {
        base: 'SauceLabs',
        browserName: 'android',
        platform: 'Linux',
        version: '4.4'
      },
      sl_android_5: {
        base: 'SauceLabs',
        browserName: 'android',
        platform: 'Linux',
        version: '5.0'
      }
    };

    runKarma({
      browsers: Object.keys(launchers),

      browserDisconnectTimeout: 10000,
      browserDisconnectTolerance: 2,
      browserNoActivityTimeout: 240000,

      captureTimeout: 240000,
      customLaunchers: launchers,

      reporters: ['coverage', 'progress', 'saucelabs'],

      sauceLabs: {
        testName: 'AlloyUI tests',
        recordScreenshots: false,
        startConnect: true,
        connectOptions: {
          port: 5757,
          'selenium-version': '2.41.0',
          logfile: 'sauce_connect.log'
        }
      }
    }, done);
  });

  gulp.task('test:watch', ['jspm', 'soy'], function(done) {
    runKarma({
      singleRun: false
    }, done);
  });

  gulp.task('watch', ['build'], function() {
    gulp.watch('src/**/*', ['build']);
  });
};

// Private helpers
// ===============

function addTemplateParam(filePath, namespace, templateName, param) {
  var soyJsPath = filePath + '.js';
  templateName = namespace + '.' + templateName;
  templateParams[soyJsPath] = templateParams[soyJsPath] || {};
  templateParams[soyJsPath][templateName] = templateParams[soyJsPath][templateName] || [];
  templateParams[soyJsPath][templateName].push(param);
}

function banner(pkg) {
  var stamp = [
    '/**',
    ' * <%= pkg.name %> - <%= pkg.description %>',
    ' * @version v<%= pkg.version %>',
    ' * @author <%= pkg.author.name %> <<%= pkg.author.email %>>',
    ' * @link http://liferay.com',
    ' * @license BSD',
    ' */',
    ''
  ].join('\n');

  return plugins.header(stamp, {
    pkg: pkg
  });
}

function createComponentElementSoy(moduleName, hasElementTemplate) {
  if (!hasElementTemplate) {
    return '';
  }
  return '\n/**\n */\n' +
    '{deltemplate ComponentElement variant="\'' + moduleName + '\'"}\n' +
      '{call .contentElement data="all" /}\n' +
    '{/deltemplate}\n';
}

function createComponentSoy(moduleName) {
  return '\n/**\n * @param id\n */\n' +
    '{deltemplate ' + moduleName + '}\n' +
      '{delcall Component data="all"}\n' +
        '{param componentName: \'' + moduleName + '\' /}\n' +
      '{/delcall}\n' +
    '{/deltemplate}\n';
}

function createComponentTemplateSoy(moduleName) {
  return '\n/**\n */\n' +
    '{deltemplate ComponentTemplate variant="\'' + moduleName + '\'"}\n' +
    '{delcall ComponentElement data="all" variant="\'' + moduleName + '\'"}\n' +
      '{param elementContent kind="html"}\n' +
        '{call .content data="all" /}\n' +
      '{/param}\n' +
    '{/delcall}\n' +
  '{/deltemplate}\n';
}

function createSurfaceElementSoy(moduleName, surfaceName, hasElementTemplate) {
  if (!hasElementTemplate) {
    return '\n/**\n * @param? elementContent\n * @param id\n */\n' +
      '{template .' + surfaceName + 'Element}\n' +
        '
\n' +
          '{if $elementContent}\n' +
            '{$elementContent}\n' +
          '{/if}\n' +
        '
\n' +
      '{/template}\n';
  }
}

function createSurfaceSoy(moduleName, surfaceName) {
  return '\n/**\n */\n' +
    '{deltemplate ' + moduleName + '.' + surfaceName + '}\n' +
      '{call .' + surfaceName + 'Element data="all"}\n' +
        '{param elementContent kind="html"}\n' +
          '{if $ij.renderChildComponents}\n' +
              '{call .' + surfaceName + ' data="all" /}\n' +
          '{/if}\n' +
        '{/param}\n' +
      '{/call}\n' +
    '{/deltemplate}\n';
}

var templateParams = {};
function extractTemplateParams(namespace, templateName, templateString, filePath) {
  var paramRegex = /{@param \s*(\S*)\s*:(.*)}/g;
  var currentMatch = paramRegex.exec(templateString);
  while (currentMatch) {
    addTemplateParam(filePath, namespace, templateName, currentMatch[1]);
    currentMatch = paramRegex.exec(templateString);
  }
}

function generateDelTemplate(namespace, templateName, hasElementTemplate) {
  var moduleName = namespace.substr(10);
  if (templateName.substr(templateName.length - 7) === 'Element') {
    return '';
  } else if (templateName === 'content') {
    return createComponentSoy(moduleName) + createComponentTemplateSoy(moduleName) +
      createComponentElementSoy(moduleName, hasElementTemplate);
  } else {
    return createSurfaceElementSoy(moduleName, templateName, hasElementTemplate) +
      createSurfaceSoy(moduleName, templateName);
  }
}

function generateTemplatesAndExtractParams() {
  return through.obj(function(file, encoding, callback) {
    var fileString = file.contents.toString(encoding);
    fileString += '\n// The following templates were generated by alloyui-tasks.\n' +
      '// Please don\'t edit them by hand.\n';

    var namespace = /{namespace (.*)}/.exec(fileString)[1];

    var templateCmds = getAllTemplateCmds(file.contents);
    var hasElementTemplateMap = getHasElementTemplateMap(templateCmds);

    templateCmds.forEach(function(cmd) {
      fileString += generateDelTemplate(namespace, cmd.name, hasElementTemplateMap[cmd.name]);
      extractTemplateParams(namespace, cmd.name, cmd.contents, file.relative);

      cmd.docTags.forEach(function(tag) {
        if (tag.tag === 'param' && tag.name !== '?') {
          addTemplateParam(file.relative, namespace, cmd.name, tag.name);
        }
      });
    })

    file.contents = new Buffer(fileString);
    this.push(file);
    callback();
  });
}

function getAllTemplateCmds(contents) {
  var cmds = [];
  var ast = tunic().parse(contents);
  ast.blocks.forEach(function(block, index) {
    var code = ast.blocks[index + 1];
    if (block.type === 'Comment' && code && code.type === 'Code') {
      var templateName = getTemplateName(code.contents);
      if (templateName) {
        cmds.push({
          contents: code.contents,
          docTags: block.tags,
          name: templateName
        });
      }
    }
  });

  return cmds;
}

function getFooterContent(file) {
  var footer = '';
  var fileParams = templateParams[file.relative];
  for (var templateName in fileParams) {
    footer += '\n' + templateName + '.params = ' + JSON.stringify(fileParams[templateName]) + ';';
  }
  return footer + '\n/* jshint ignore:end */\n';
}

function getHasElementTemplateMap(templateCmds) {
  var hasElementTemplateMap = {};
  templateCmds.forEach(function(cmd) {
    var templateParts = cmd.name.split('Element');
    if (templateParts[1] === '') {
      hasElementTemplateMap[templateParts[0]] = true;
    }
  });
  return hasElementTemplateMap;
}

function getHeaderContent(corePathFromSoy) {
  var registryModulePath = path.join(corePathFromSoy, '/component/ComponentRegistry');
  return '/* jshint ignore:start */\n' +
    'import ComponentRegistry from \'' + registryModulePath + '\';\n' +
    'var Templates = ComponentRegistry.Templates;\n';
}

function getTemplateName(templateString) {
  var regex = /{template (.*)}/;
  var match = regex.exec(templateString);
  return match ? match[1].substr(1) : null;
}

function runKarma(config, done) {
  config = merge({
    configFile: path.resolve('karma.conf.js'),
    singleRun: true
  }, config);
  karma.start(config, done);
}
<commit_msg>Runs soy task when soy file changes during test:watch<commit_after>'use strict';

var del = require('del');
var GlobalsFormatter = require('es6-module-transpiler-globals-formatter');
var gulp = require('gulp');
var gutil = require('gulp-util');
var jspm = require('jspm');
var jspmCore = require('jspm/lib/core');
var karma = require('karma').server;
var merge = require('merge');
var open = require('open');
var path = require('path');
var plugins = require('gulp-load-plugins')();
var renamer = require('gulp-es6-imports-renamer');
var runSequence = require('run-sequence');
var sourcemaps = require('gulp-sourcemaps');
var babel = require('gulp-babel');
var through = require('through2');
var transpile = require('gulp-es6-module-transpiler');
var tunic = require('tunic');

function handleError(error) {
  console.error(error.toString());

  this.emit('end');
}

module.exports = function(options) {
  var bundleFileName = options.bundleFileName;
  var corePathFromSoy = options.corePathFromSoy || 'aui';
  var shouldSkipSoyTemplatesGeneration = options.shouldSkipSoyTemplatesGeneration;

  gulp.task('build', function(done) {
    runSequence('clean', ['soy', 'copy'], ['build:globals', 'build:min'], done);
  });

  gulp.task('build:globals', ['jspm'], function() {
    return gulp.src('src/**/*.js')
      .pipe(sourcemaps.init())
      .pipe(renamer({
        basePath: process.cwd(),
        configPath: path.resolve('config.js')
      })).on('error', handleError)
      .pipe(transpile({
        basePath: process.cwd(),
        bundleFileName: bundleFileName,
        formatter: new GlobalsFormatter({
          globalName: 'aui'
        })
      }))
      .pipe(babel({
        blacklist: 'useStrict',
        compact: false
      })).on('error', handleError)
      .pipe(sourcemaps.write('./'))
      .pipe(gulp.dest('build'));
  });

  gulp.task('build:min', ['build:globals'], function() {
    return gulp.src(path.join('build/', bundleFileName))
      .pipe(plugins.rename(function(path) {
        path.basename += '-min';
      }))
      .pipe(plugins.uglify({
        compress: {
          drop_console: true
        },
        preserveComments: 'some'
      }))
      .pipe(banner(options.pkg))
      .pipe(gulp.dest('build'));
  });

  gulp.task('clean', function(done) {
    del(['build'], done);
  });

  gulp.task('copy', function() {
    return gulp.src('src/**/*.css')
      .pipe(gulp.dest('build'));
  });

  gulp.task('jspm', function(done) {
    jspm.promptDefaults(true);
    jspm.install(true, {
      lock: true
    }).then(function() {
      return jspmCore.checkDlLoader();
    }).then(function() {
      return jspmCore.setMode('local');
    }).then(function() {
      gutil.log(gutil.colors.cyan('Install complete'));
      done();
    }, function(err) {
      gutil.log(gutil.colors.red('err', err.stack || err));
      gutil.log(gutil.colors.red('Installation changes not saved.'));
      done();
    });
  });

  gulp.task('lint', function() {
    return gulp.src(['src/**/*.js', 'test/**/*.js'])
      .pipe(plugins.jshint())
      .pipe(plugins.jshint.reporter(require('jshint-stylish')));
  });

  gulp.task('soy', function() {
    return gulp.src('src/**/*.soy')
      .pipe(plugins.if(!shouldSkipSoyTemplatesGeneration, generateTemplatesAndExtractParams()))
      .pipe(plugins.if(!shouldSkipSoyTemplatesGeneration, gulp.dest('build')))
      .pipe(plugins.soynode({
        loadCompiledTemplates: false,
        shouldDeclareTopLevelNamespaces: false
      }))
      .pipe(plugins.ignore.exclude('*.soy'))
      .pipe(plugins.wrapper({
        header: getHeaderContent(corePathFromSoy),
        footer: getFooterContent
      }))
      .pipe(gulp.dest('src'));
  });

  gulp.task('test', function(done) {
    return runSequence('test:unit', /*'test:complexity', TODO(edu): ES6.*/ done);
  });

  gulp.task('test:complexity', function() {
    return gulp.src(['src/**/*.js', '!src/**/*.soy.js', '!src/promise/Promise.js', 'test/**/*.js'])
      .pipe(babel())
      .pipe(plugins.complexity({
        halstead: [15, 15, 20]
      }));
  });

  gulp.task('test:unit', ['jspm', 'soy'], function(done) {
    runKarma({}, done);
  });

  gulp.task('test:coverage', ['jspm', 'soy'], function(done) {
    runKarma({}, function() {
      open(path.resolve('coverage/lcov/lcov-report/index.html'));
      done();
    });
  });

  gulp.task('test:browsers', ['jspm', 'soy'], function(done) {
    runKarma({
      browsers: ['Chrome', 'Firefox', 'Safari', 'IE9 - Win7', 'IE10 - Win7', 'IE11 - Win7']
    }, done);
  });

  gulp.task('test:saucelabs', ['jspm', 'soy'], function(done) {
    var launchers = {
      sl_chrome: {
        base: 'SauceLabs',
        browserName: 'chrome'
      },
      sl_safari: {
        base: 'SauceLabs',
        browserName: 'safari'
      },
      sl_firefox: {
        base: 'SauceLabs',
        browserName: 'firefox'
      },
      sl_ie_9: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '9'
      },
      sl_ie_10: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 7',
        version: '10'
      },
      sl_ie_11: {
        base: 'SauceLabs',
        browserName: 'internet explorer',
        platform: 'Windows 8.1',
        version: '11'
      },
      sl_iphone: {
        base: 'SauceLabs',
        browserName: 'iphone',
        platform: 'OS X 10.10',
        version: '7.1'
      },
      sl_android_4: {
        base: 'SauceLabs',
        browserName: 'android',
        platform: 'Linux',
        version: '4.4'
      },
      sl_android_5: {
        base: 'SauceLabs',
        browserName: 'android',
        platform: 'Linux',
        version: '5.0'
      }
    };

    runKarma({
      browsers: Object.keys(launchers),

      browserDisconnectTimeout: 10000,
      browserDisconnectTolerance: 2,
      browserNoActivityTimeout: 240000,

      captureTimeout: 240000,
      customLaunchers: launchers,

      reporters: ['coverage', 'progress', 'saucelabs'],

      sauceLabs: {
        testName: 'AlloyUI tests',
        recordScreenshots: false,
        startConnect: true,
        connectOptions: {
          port: 5757,
          'selenium-version': '2.41.0',
          logfile: 'sauce_connect.log'
        }
      }
    }, done);
  });

  gulp.task('test:watch', ['jspm', 'soy'], function(done) {
    gulp.watch('src/**/*.soy', ['soy']);

    runKarma({
      singleRun: false
    }, done);
  });

  gulp.task('watch', ['build'], function() {
    gulp.watch('src/**/*', ['build']);
  });
};

// Private helpers
// ===============

function addTemplateParam(filePath, namespace, templateName, param) {
  var soyJsPath = filePath + '.js';
  templateName = namespace + '.' + templateName;
  templateParams[soyJsPath] = templateParams[soyJsPath] || {};
  templateParams[soyJsPath][templateName] = templateParams[soyJsPath][templateName] || [];
  templateParams[soyJsPath][templateName].push(param);
}

function banner(pkg) {
  var stamp = [
    '/**',
    ' * <%= pkg.name %> - <%= pkg.description %>',
    ' * @version v<%= pkg.version %>',
    ' * @author <%= pkg.author.name %> <<%= pkg.author.email %>>',
    ' * @link http://liferay.com',
    ' * @license BSD',
    ' */',
    ''
  ].join('\n');

  return plugins.header(stamp, {
    pkg: pkg
  });
}

function createComponentElementSoy(moduleName, hasElementTemplate) {
  if (!hasElementTemplate) {
    return '';
  }
  return '\n/**\n */\n' +
    '{deltemplate ComponentElement variant="\'' + moduleName + '\'"}\n' +
      '{call .contentElement data="all" /}\n' +
    '{/deltemplate}\n';
}

function createComponentSoy(moduleName) {
  return '\n/**\n * @param id\n */\n' +
    '{deltemplate ' + moduleName + '}\n' +
      '{delcall Component data="all"}\n' +
        '{param componentName: \'' + moduleName + '\' /}\n' +
      '{/delcall}\n' +
    '{/deltemplate}\n';
}

function createComponentTemplateSoy(moduleName) {
  return '\n/**\n */\n' +
    '{deltemplate ComponentTemplate variant="\'' + moduleName + '\'"}\n' +
    '{delcall ComponentElement data="all" variant="\'' + moduleName + '\'"}\n' +
      '{param elementContent kind="html"}\n' +
        '{call .content data="all" /}\n' +
      '{/param}\n' +
    '{/delcall}\n' +
  '{/deltemplate}\n';
}

function createSurfaceElementSoy(moduleName, surfaceName, hasElementTemplate) {
  if (!hasElementTemplate) {
    return '\n/**\n * @param? elementContent\n * @param id\n */\n' +
      '{template .' + surfaceName + 'Element}\n' +
        '
\n' +
          '{if $elementContent}\n' +
            '{$elementContent}\n' +
          '{/if}\n' +
        '
\n' +
      '{/template}\n';
  }
}

function createSurfaceSoy(moduleName, surfaceName) {
  return '\n/**\n */\n' +
    '{deltemplate ' + moduleName + '.' + surfaceName + '}\n' +
      '{call .' + surfaceName + 'Element data="all"}\n' +
        '{param elementContent kind="html"}\n' +
          '{if $ij.renderChildComponents}\n' +
              '{call .' + surfaceName + ' data="all" /}\n' +
          '{/if}\n' +
        '{/param}\n' +
      '{/call}\n' +
    '{/deltemplate}\n';
}

var templateParams = {};
function extractTemplateParams(namespace, templateName, templateString, filePath) {
  var paramRegex = /{@param \s*(\S*)\s*:(.*)}/g;
  var currentMatch = paramRegex.exec(templateString);
  while (currentMatch) {
    addTemplateParam(filePath, namespace, templateName, currentMatch[1]);
    currentMatch = paramRegex.exec(templateString);
  }
}

function generateDelTemplate(namespace, templateName, hasElementTemplate) {
  var moduleName = namespace.substr(10);
  if (templateName.substr(templateName.length - 7) === 'Element') {
    return '';
  } else if (templateName === 'content') {
    return createComponentSoy(moduleName) + createComponentTemplateSoy(moduleName) +
      createComponentElementSoy(moduleName, hasElementTemplate);
  } else {
    return createSurfaceElementSoy(moduleName, templateName, hasElementTemplate) +
      createSurfaceSoy(moduleName, templateName);
  }
}

function generateTemplatesAndExtractParams() {
  return through.obj(function(file, encoding, callback) {
    var fileString = file.contents.toString(encoding);
    fileString += '\n// The following templates were generated by alloyui-tasks.\n' +
      '// Please don\'t edit them by hand.\n';

    var namespace = /{namespace (.*)}/.exec(fileString)[1];

    var templateCmds = getAllTemplateCmds(file.contents);
    var hasElementTemplateMap = getHasElementTemplateMap(templateCmds);

    templateCmds.forEach(function(cmd) {
      fileString += generateDelTemplate(namespace, cmd.name, hasElementTemplateMap[cmd.name]);
      extractTemplateParams(namespace, cmd.name, cmd.contents, file.relative);

      cmd.docTags.forEach(function(tag) {
        if (tag.tag === 'param' && tag.name !== '?') {
          addTemplateParam(file.relative, namespace, cmd.name, tag.name);
        }
      });
    })

    file.contents = new Buffer(fileString);
    this.push(file);
    callback();
  });
}

function getAllTemplateCmds(contents) {
  var cmds = [];
  var ast = tunic().parse(contents);
  ast.blocks.forEach(function(block, index) {
    var code = ast.blocks[index + 1];
    if (block.type === 'Comment' && code && code.type === 'Code') {
      var templateName = getTemplateName(code.contents);
      if (templateName) {
        cmds.push({
          contents: code.contents,
          docTags: block.tags,
          name: templateName
        });
      }
    }
  });

  return cmds;
}

function getFooterContent(file) {
  var footer = '';
  var fileParams = templateParams[file.relative];
  for (var templateName in fileParams) {
    footer += '\n' + templateName + '.params = ' + JSON.stringify(fileParams[templateName]) + ';';
  }
  return footer + '\n/* jshint ignore:end */\n';
}

function getHasElementTemplateMap(templateCmds) {
  var hasElementTemplateMap = {};
  templateCmds.forEach(function(cmd) {
    var templateParts = cmd.name.split('Element');
    if (templateParts[1] === '') {
      hasElementTemplateMap[templateParts[0]] = true;
    }
  });
  return hasElementTemplateMap;
}

function getHeaderContent(corePathFromSoy) {
  var registryModulePath = path.join(corePathFromSoy, '/component/ComponentRegistry');
  return '/* jshint ignore:start */\n' +
    'import ComponentRegistry from \'' + registryModulePath + '\';\n' +
    'var Templates = ComponentRegistry.Templates;\n';
}

function getTemplateName(templateString) {
  var regex = /{template (.*)}/;
  var match = regex.exec(templateString);
  return match ? match[1].substr(1) : null;
}

function runKarma(config, done) {
  config = merge({
    configFile: path.resolve('karma.conf.js'),
    singleRun: true
  }, config);
  karma.start(config, done);
}
<|endoftext|>


<commit_before>var Verse = {
  render: function (options, root) {
    if (root) {
      // Render as DOM and track events (client side)
      if (options.context) contextualize(options.context, true);
      if (!options.reconcile) root.innerHTML = '';
      this._renderDOM(root,options.template,options.context, options.reconcile, false);
    } else {
      // Render as string (server side)
      if (options.context) contextualize(options.context, false);
      return this._renderString(options.template, options.context);
    }
  },

  _renderString: function (input, context) {
    if (input == null || typeof input == 'undefined') {
      return '';
    } else if (typeof input == 'object') {
      if (isArray(input)) {
        var out = '';
        input.forEach(function (item) {
          out += Verse._renderString(item, context)
        })
        return out;
      } else {
        var tagDefinition = '<'+input.tag;
        var innerHTML = '';
        Object.keys(input).forEach(function(key) {
          var val = input[key];
          if (key == 'tag' || key == 'listen' || key == 'events' || key == 'transition' || val == null || typeof val == 'undefined') {
            // Ignore
          } else if (key == 'render') {
            innerHTML = Verse._renderString(val, context);
          } else {
            if (key == 'className') key = 'class';
            if (typeof val == 'function') {
              var value = val(context) || '';
            } else {
              var value = val;
            }
            if (key == 'style') {
              var styleKeyValuePairs = '';
              Object.keys(value).forEach(function(styleKey) {
                var dashedKey = styleKey.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
                styleKeyValuePairs += dashedKey+':'+value[styleKey]+';';
              });
              value = styleKeyValuePairs;
            }
            tagDefinition += ' '+key+'="'+value+'"';
          }
        });
        tagDefinition += '>';
        return tagDefinition + innerHTML + '</'+input.tag+'>';
      }
    } else if (typeof input == 'function') {
      return Verse._renderString(input(context), context);
    } else {
      return input.toString();
    }
  },

  _renderDOM: function (parent, input, context, reconcile, append) {
    if (input == null || typeof input == 'undefined') {
      // ignore
    } else if (typeof input == 'object') {
      if (isArray(input)) {
        input.forEach(function (item) {
          Verse._renderDOM(parent, item, context, reconcile, true)
        })
      } else {
        if (reconcile) {
          Verse._reconcileElement(parent, input, context);
        } else {
          var el = document.createElement(input.tag);
          Verse._renderElement(el, input, context, true);
          parent.appendChild(el);
        }
      }
    } else if (typeof input == 'function') {
      Verse._renderDOM(parent, input(context), context, reconcile, append);
    } else if (!reconcile) {
      parent.innerHTML = append ? parent.innerHTML + input.toString() : input.toString();
    }
  },

  _renderElement: function (el, input, context, initialize, triggers) {
    Object.keys(input).forEach(function(key) {
      var val = input[key];
      if (val == null || typeof val == 'undefined' || key == 'tag' || key == 'transition') {
        // Ignore
      } else if (key == 'listen' && context) {
        context.__register(input, el);
      } else if (key == 'render') {
        Verse._renderDOM(el, val, context);
      } else if (key == 'events') {
        if (initialize) {
          Object.keys(val).forEach(function(eventType) {
            if (eventType != 'render') {
              el.addEventListener(eventType, val[eventType], false)
            }
          });
        }
      } else {
        if (typeof val == 'function') {
          var value = val(context) || '';
        } else {
          var value = val;
        }
        if (key == 'className') key = 'class';
        if (key == 'style') {
          Object.keys(value).forEach(function(styleKey) {
            el.style[styleKey] = value[styleKey];
          });
        } else if (key == 'class') {
          el.setAttribute(key,el.__transitionClass || value);
          if (input.transition) el.__transitionClass = value;
        } else {
          el.setAttribute(key,value);
        }
      }
    });
    if (input.events && input.events.render) {
      setTimeout(function () {
        input.events.render({
          context: context,
          target: el,
          triggers: triggers || []
        });
      }, 0)
    }

    if (input.transition && el.__transitionClass) {
      if (el.__transitionTimeout) clearTimeout(el.__transitionTimeout)
      el.__transitionTimeout = setTimeout(function () {
        el.className = el.__transitionClass
      }, input.transition)
    }
  },

  _reconcileElement: function(parent, input, context) {
    if (!parent.firstChild) return;
    if (!parent.__cc) parent.__cc = parent.firstChild;
    var el = parent.__cc;
    parent.__cc = el.nextSibling;
    if (el.tagName.toLowerCase() != input.tag.toLowerCase()) {
      console.warn('Warning! Reconcilliation failed at', el, input, el.outerHTML);
      throw new ReconcileError();
    }
    if (input.listen && context) {
      context.__register(input, el);
    }
    if (input.events) {
      Object.keys(input.events).forEach(function(eventType) {
        if (eventType == 'render') {
          setTimeout(function () {
            input.events.render({context: context, target: el, triggers: []});
          }, 0)
        } else {
          el.addEventListener(eventType, input.events[eventType], false)
        }
      });
    }
    if (input.render) {
      Verse._renderDOM(el, input.render, context, true, false);
    }
  },

  _recurseDOM: function (node, triggeredEvents) {
    if (node.__trigger) {
      var l = node.__trigger;
      delete node.__trigger;
      while(node.attributes.length > 0) {
        node.removeAttribute(node.attributes[0].name);
      }
      while (node.firstChild) {
        node.firstChild.__removed = true;
        node.removeChild(node.firstChild);
      }
      Verse._renderElement(node, l.component, l.context, false, triggeredEvents);
    } else {
      node = node.firstChild;
      while(node) {
        Verse._recurseDOM(node, triggeredEvents);
        node = node.nextSibling;
      }
    }
  }
}

function contextualize(ctx, registerEvents) {
  if (!registerEvents) {
    ctx.trigger = ctx.trigger || function () {};
    return;
  }

  if (ctx.__register) return;

  ctx.__listeners = {};
  ctx.__listenersUniqueId = 0;
  ctx.__lastTriggeredEvents = {};

  ctx.__register = function(component, element) {
    if (!component._uid) component._uid = (++ctx.__listenersUniqueId);
    ctx.__listeners[component._uid] = {
      element: element,
      component: component,
      context: ctx
    }
  }

  ctx.trigger = function () {
    Array.prototype.slice.call(arguments).forEach(function (event) {
      ctx.__lastTriggeredEvents[event] = true;
    });

    if (!ctx.__triggerTimeout) {
      ctx.__triggerTimeout = setTimeout(function () {
        var triggeredEvents = Object.keys(ctx.__lastTriggeredEvents);
        ctx.__lastTriggeredEvents = {};
        ctx.__triggerTimeout = null;
        Object.keys(ctx.__listeners).forEach(function (uid) {
          var l = ctx.__listeners[uid];
          if (l.element.__removed) {
            delete ctx.__listeners[uid];
          } else {
            triggeredEvents.forEach(function (event) {
              if (l.component.listen == event ||
                  (l.component.listen.indexOf &&
                    l.component.listen.indexOf(event) >= 0)) {
                l.element.__trigger = l;
              }
            });
          }
        });
        Verse._recurseDOM(document, triggeredEvents);
      }, 0);
    }
  }
}

function ReconcileError() {
  this.name = 'ReconcileError';
  this.stack = (new Error()).stack;
}
ReconcileError.prototype = Object.create(Error.prototype);
ReconcileError.prototype.constructor = ReconcileError;

var isArray = ('isArray' in Array) ? Array.isArray : function (value) {
  return Object.prototype.toString.call(value) === '[object Array]';
}

module.exports = Verse;
<commit_msg>removed semicolons<commit_after>var Verse = {
  render: function (options, root) {
    if (root) {
      // Render as DOM and track events (client side)
      if (options.context) contextualize(options.context, true)
      if (!options.reconcile) root.innerHTML = ''
      this._renderDOM(root,options.template,options.context, options.reconcile, false)
    } else {
      // Render as string (server side)
      if (options.context) contextualize(options.context, false)
      return this._renderString(options.template, options.context)
    }
  },

  _renderString: function (input, context) {
    if (input == null || typeof input == 'undefined') {
      return ''
    } else if (typeof input == 'object') {
      if (isArray(input)) {
        var out = ''
        input.forEach(function (item) {
          out += Verse._renderString(item, context)
        })
        return out
      } else {
        var tagDefinition = '<'+input.tag
        var innerHTML = ''
        Object.keys(input).forEach(function(key) {
          var val = input[key]
          if (key == 'tag' || key == 'listen' || key == 'events' || key == 'transition' || val == null || typeof val == 'undefined') {
            // Ignore
          } else if (key == 'render') {
            innerHTML = Verse._renderString(val, context)
          } else {
            if (key == 'className') key = 'class'
            if (typeof val == 'function') {
              var value = val(context) || ''
            } else {
              var value = val
            }
            if (key == 'style') {
              var styleKeyValuePairs = ''
              Object.keys(value).forEach(function(styleKey) {
                var dashedKey = styleKey.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase()
                styleKeyValuePairs += dashedKey+':'+value[styleKey]+';'
              })
              value = styleKeyValuePairs
            }
            tagDefinition += ' '+key+'="'+value+'"'
          }
        })
        tagDefinition += '>'
        return tagDefinition + innerHTML + '</'+input.tag+'>'
      }
    } else if (typeof input == 'function') {
      return Verse._renderString(input(context), context)
    } else {
      return input.toString()
    }
  },

  _renderDOM: function (parent, input, context, reconcile, append) {
    if (input == null || typeof input == 'undefined') {
      // ignore
    } else if (typeof input == 'object') {
      if (isArray(input)) {
        input.forEach(function (item) {
          Verse._renderDOM(parent, item, context, reconcile, true)
        })
      } else {
        if (reconcile) {
          Verse._reconcileElement(parent, input, context)
        } else {
          var el = document.createElement(input.tag)
          Verse._renderElement(el, input, context, true)
          parent.appendChild(el)
        }
      }
    } else if (typeof input == 'function') {
      Verse._renderDOM(parent, input(context), context, reconcile, append)
    } else if (!reconcile) {
      parent.innerHTML = append ? parent.innerHTML + input.toString() : input.toString()
    }
  },

  _renderElement: function (el, input, context, initialize, triggers) {
    Object.keys(input).forEach(function(key) {
      var val = input[key]
      if (val == null || typeof val == 'undefined' || key == 'tag' || key == 'transition') {
        // Ignore
      } else if (key == 'listen' && context) {
        context.__register(input, el)
      } else if (key == 'render') {
        Verse._renderDOM(el, val, context)
      } else if (key == 'events') {
        if (initialize) {
          Object.keys(val).forEach(function(eventType) {
            if (eventType != 'render') {
              el.addEventListener(eventType, val[eventType], false)
            }
          })
        }
      } else {
        if (typeof val == 'function') {
          var value = val(context) || ''
        } else {
          var value = val
        }
        if (key == 'className') key = 'class'
        if (key == 'style') {
          Object.keys(value).forEach(function(styleKey) {
            el.style[styleKey] = value[styleKey]
          })
        } else if (key == 'class') {
          el.setAttribute(key,el.__transitionClass || value)
          if (input.transition) el.__transitionClass = value
        } else {
          el.setAttribute(key,value)
        }
      }
    })
    if (input.events && input.events.render) {
      setTimeout(function () {
        input.events.render({
          context: context,
          target: el,
          triggers: triggers || []
        })
      }, 0)
    }

    if (input.transition && el.__transitionClass) {
      if (el.__transitionTimeout) clearTimeout(el.__transitionTimeout)
      el.__transitionTimeout = setTimeout(function () {
        el.className = el.__transitionClass
      }, input.transition)
    }
  },

  _reconcileElement: function(parent, input, context) {
    if (!parent.firstChild) return
    if (!parent.__cc) parent.__cc = parent.firstChild
    var el = parent.__cc
    parent.__cc = el.nextSibling
    if (el.tagName.toLowerCase() != input.tag.toLowerCase()) {
      console.warn('Warning! Reconcilliation failed at', el, input, el.outerHTML)
      throw new ReconcileError()
    }
    if (input.listen && context) {
      context.__register(input, el)
    }
    if (input.events) {
      Object.keys(input.events).forEach(function(eventType) {
        if (eventType == 'render') {
          setTimeout(function () {
            input.events.render({context: context, target: el, triggers: []})
          }, 0)
        } else {
          el.addEventListener(eventType, input.events[eventType], false)
        }
      })
    }
    if (input.render) {
      Verse._renderDOM(el, input.render, context, true, false)
    }
  },

  _recurseDOM: function (node, triggeredEvents) {
    if (node.__trigger) {
      var l = node.__trigger
      delete node.__trigger
      while(node.attributes.length > 0) {
        node.removeAttribute(node.attributes[0].name)
      }
      while (node.firstChild) {
        node.firstChild.__removed = true
        node.removeChild(node.firstChild)
      }
      Verse._renderElement(node, l.component, l.context, false, triggeredEvents)
    } else {
      node = node.firstChild
      while(node) {
        Verse._recurseDOM(node, triggeredEvents)
        node = node.nextSibling
      }
    }
  }
}

function contextualize(ctx, registerEvents) {
  if (!registerEvents) {
    ctx.trigger = ctx.trigger || function () {}
    return
  }

  if (ctx.__register) return

  ctx.__listeners = {}
  ctx.__listenersUniqueId = 0
  ctx.__lastTriggeredEvents = {}

  ctx.__register = function(component, element) {
    if (!component._uid) component._uid = (++ctx.__listenersUniqueId)
    ctx.__listeners[component._uid] = {
      element: element,
      component: component,
      context: ctx
    }
  }

  ctx.trigger = function () {
    Array.prototype.slice.call(arguments).forEach(function (event) {
      ctx.__lastTriggeredEvents[event] = true
    })

    if (!ctx.__triggerTimeout) {
      ctx.__triggerTimeout = setTimeout(function () {
        var triggeredEvents = Object.keys(ctx.__lastTriggeredEvents)
        ctx.__lastTriggeredEvents = {}
        ctx.__triggerTimeout = null
        Object.keys(ctx.__listeners).forEach(function (uid) {
          var l = ctx.__listeners[uid]
          if (l.element.__removed) {
            delete ctx.__listeners[uid]
          } else {
            triggeredEvents.forEach(function (event) {
              if (l.component.listen == event ||
                  (l.component.listen.indexOf &&
                    l.component.listen.indexOf(event) >= 0)) {
                l.element.__trigger = l
              }
            })
          }
        })
        Verse._recurseDOM(document, triggeredEvents)
      }, 0)
    }
  }
}

function ReconcileError() {
  this.name = 'ReconcileError'
  this.stack = (new Error()).stack
}
ReconcileError.prototype = Object.create(Error.prototype)
ReconcileError.prototype.constructor = ReconcileError

var isArray = ('isArray' in Array) ? Array.isArray : function (value) {
  return Object.prototype.toString.call(value) === '[object Array]'
}

module.exports = Verse
<|endoftext|>


<commit_before>var exec = require('child_process').exec;
var path = require('path');

const DBUS_COMMAND = "bash "+__dirname+"/dbus.sh ";
const DBUS_DEST_DEFAULT = 'org.mpris.MediaPlayer2.omxplayer';

class OmxInstance {

	constructor(options) {
		this.options = options;

		if (options && options.layer) {
			this.dbusDest = DBUS_DEST_DEFAULT + '_layer' + options.layer;
			this.layer = options.layer;
			console.log('setup for layered mode');
		} else {
			this.dbusDest = DBUS_DEST_DEFAULT;
			this.layer = 1;
			console.log('not layered mode');
		}
		console.log('dbus name will be', this.dbusDest);

		exec('mkfifo omxpipe'+this.layer);

		this.defaults = null;
		this.progressHandler = null;

	}

	getLayer() {
		return this.layer;
	}

	cancelProgressHandlerIfActive() {
		if (this.progressHandler) {
			clearInterval(this.progressHandler);
			console.log('progressHandler cancelled');
		}
	}

	dbusCommand (command)  {
		let merge = "bash " +__dirname+"/dbus.sh " + this.dbusDest + " " + command;
		if (command != 'getplaystatus' && command !='getvolume' && command != 'getposition') { console.log('merge:', merge); }
		return merge;
	}

	resume () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already playing
			if (stdout.indexOf("Paused")>-1) {
				this.togglePlay();
			}
		});
	}

	pause () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already paused
			if (stdout.indexOf("Playing")>-1) {
				this.togglePlay();
			}
		});
	}

	stop () {
		exec(this.dbusCommand('stop'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
		});
	}

	quit () {
		exec(this.dbusCommand('quit'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
	  });
	}

	togglePlay () {
		exec(this.dbusCommand('toggleplay'), (error, stdout, stderr) => {});
	}

	seek (offset) {
		//seek offset in seconds; relative from current position; negative values will cause a jump back;
		exec(this.dbusCommand('seek ' +Math.round(offset*1000000)), (error, stdout, stderr) => {});
	}

	setPosition (position) {
		//position in seconds from start; //positions larger than the duration will stop the player;
		exec(this.dbusCommand('setposition '+Math.round(position*1000000)), (error, stdout, stderr) => {});
	}

	setVolume (volume) {
		// volume range [0.0, 1.0];
		if (volume > 0 && volume < 1.0) {
			exec(this.dbusCommand('setvolume '+volume), (error, stdout, stderr) => {});
		}
	}

	setVisibility (visible) {
		let command = visible ? 'unhidevideo' : 'hidevideo';
		exec(this.dbusCommand(command), (err, stdout, stderr) => {});
	}

	setAlpha (alpha) {
		exec(this.dbusCommand('setalpha ' + alpha), (err, stdout, stderr) => {});
	}

	getCurrentPosition () {
		console.log('getCurrentPosition');
		return new Promise( (resolve, reject) => {
			exec(this.dbusCommand('getposition'), (error, stdout, stderr) => {
				console.log('getposition error, stdout, stderr:', error, stdout, stderr);
				if (error) reject();

				let position = parseInt(stdout);
				console.log('currentPosition:', position, 'or in seconds:', position / 1000);
				resolve(position);
			});
		});
	}

	getIsPlaying () {
		console.log('getIsPlaying');
		return new Promise( (resolve, reject) => {
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				console.log('getplaystatus error, stdout, stderr:', error, stdout, stderr);
				if (error) {
					console.error('error getting play status:', err);
					reject();
				}
				if (stdout === 'Playing') {
					resolve(true);
				} else {
					resolve(false);
				}
			});
		});
	}

	getDuration () {
		return new Promise( (resolve, reject) => {
			exec( this.dbusCommand('getduration'), (error, stdout, stderr) => {
				if (error) reject();

				let duration = parseInt(stdout);
				console.log('getDuration:', duration, 'or in seconds:', duration / 1000);
				resolve(duration);
			});
		});
	}

	getVolume () {
		exec(this.dbusCommand('getvolume'), (error, stdout, stderr) => {
			if (error) return null;
			let volume = parseFloat(stdout);
			console.log('getVolume:', volume);
		});	}

	onProgress (callback) {
		console.log('add new progress handler for layer', this.layer);
		this.progressHandler = setInterval( () => {
			this.getIsPlaying()
				 then( (isPlaying) => {
					 if (isPlaying) {
						 callback({'position': this.getCurrentPosition(), 'duration': this.getDuration()});
					 } else {
						 callback({ 'playing': false });
					 }
				 })
				 .catch( () => {
					 console.error('error getting isPlaying status');
					 callback({ 'status': 'error', 'playing': false });
				 });
		}, 1000);
	}

	onStart (callback) {
		console.log('onStart event');
		if (callback) {
			callback();
		}
	}

	waitTillPlaying (callback) {
		console.log('waitTillPlaying');
		let countAttempts = 0;
		let interval;
		interval = setInterval( () => {
			countAttempts++;
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				if (error) {
					console.log('error on getplaystus:', error);
				} else {
					console.log('getplaystatus result after', countAttempts, ':', stdout);
					clearInterval(interval);
					callback();
				}
			});
		}, 1000);
	}

	open (path, doneCallback, holdMode) {
		console.log('OmxInstance open() for layer #', this.layer, 'holdMode?', holdMode);
		let settings = this.options || {};
		let args = [];
		let command = 'omxplayer';

		args.push('"'+path+'"');

		if (['hdmi','local','both'].indexOf(settings.audioOutput) != -1) {
			args.push('-o');
			args.push(settings.audioOutput);
		}

		if (settings.blackBackground !== false) { // defaults to true
			args.push('-b');
		}

		if (settings.disableKeys === true) { //defaults to  false
			args.push('--no-keys')
		}

		if (settings.disableOnScreenDisplay === true) { //defaults to  false
			args.push('--no-osd')
		}

		if (settings.disableGhostbox === true) { //defaults to  false
			args.push('--no-ghost-box');
		}

		if (settings.loop === true) { // defaults to false
			args.push('--loop');
		}

		if (settings.subtitlePath && settings.subtitlePath != "" ){
			args.push('--subtitles');
			args.push('"'+settings.subtitlePath+'"');
		}

		if (settings.startAt){
			args.push('--pos');
			args.push(''+settings.startAt+'');
		}

		if (settings.layer) {
			args.push('--layer');
			args.push(settings.layer);
		}

		if (holdMode) {
			args.push('--alpha');
			args.push(0);
		}

		args.push('--dbus_name');
		args.push(this.dbusDest);

		let finalOpenCommand = command+' '+args.join(' ')+' < omxpipe'+this.layer;
		console.log('finalOpenCommand:', finalOpenCommand);

	  exec(finalOpenCommand, (error, stdout, stderr) => {
			doneCallback();
			console.log('omxpipe done for layer', this.layer);
  		this.cancelProgressHandlerIfActive();
	  	console.log(stdout);
	  });
	  exec(' . > omxpipe'+this.layer, (error, stdout, stderr) => {
			this.waitTillPlaying( () => {
				console.log('started ok');
				this.onStart();
				if (holdMode) {
					console.log('holdMode ON, so immediately pause and hide');
					this.pause();
					this.setVisibility(false);
				}
			});
		});

	}

}

module.exports = OmxInstance;
<commit_msg>Missing .<commit_after>var exec = require('child_process').exec;
var path = require('path');

const DBUS_COMMAND = "bash "+__dirname+"/dbus.sh ";
const DBUS_DEST_DEFAULT = 'org.mpris.MediaPlayer2.omxplayer';

class OmxInstance {

	constructor(options) {
		this.options = options;

		if (options && options.layer) {
			this.dbusDest = DBUS_DEST_DEFAULT + '_layer' + options.layer;
			this.layer = options.layer;
			console.log('setup for layered mode');
		} else {
			this.dbusDest = DBUS_DEST_DEFAULT;
			this.layer = 1;
			console.log('not layered mode');
		}
		console.log('dbus name will be', this.dbusDest);

		exec('mkfifo omxpipe'+this.layer);

		this.defaults = null;
		this.progressHandler = null;

	}

	getLayer() {
		return this.layer;
	}

	cancelProgressHandlerIfActive() {
		if (this.progressHandler) {
			clearInterval(this.progressHandler);
			console.log('progressHandler cancelled');
		}
	}

	dbusCommand (command)  {
		let merge = "bash " +__dirname+"/dbus.sh " + this.dbusDest + " " + command;
		if (command != 'getplaystatus' && command !='getvolume' && command != 'getposition') { console.log('merge:', merge); }
		return merge;
	}

	resume () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already playing
			if (stdout.indexOf("Paused")>-1) {
				this.togglePlay();
			}
		});
	}

	pause () {
		exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
			// Ignore if already paused
			if (stdout.indexOf("Playing")>-1) {
				this.togglePlay();
			}
		});
	}

	stop () {
		exec(this.dbusCommand('stop'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
		});
	}

	quit () {
		exec(this.dbusCommand('quit'), (error, stdout, stderr) => {
			this.cancelProgressHandlerIfActive();
	  });
	}

	togglePlay () {
		exec(this.dbusCommand('toggleplay'), (error, stdout, stderr) => {});
	}

	seek (offset) {
		//seek offset in seconds; relative from current position; negative values will cause a jump back;
		exec(this.dbusCommand('seek ' +Math.round(offset*1000000)), (error, stdout, stderr) => {});
	}

	setPosition (position) {
		//position in seconds from start; //positions larger than the duration will stop the player;
		exec(this.dbusCommand('setposition '+Math.round(position*1000000)), (error, stdout, stderr) => {});
	}

	setVolume (volume) {
		// volume range [0.0, 1.0];
		if (volume > 0 && volume < 1.0) {
			exec(this.dbusCommand('setvolume '+volume), (error, stdout, stderr) => {});
		}
	}

	setVisibility (visible) {
		let command = visible ? 'unhidevideo' : 'hidevideo';
		exec(this.dbusCommand(command), (err, stdout, stderr) => {});
	}

	setAlpha (alpha) {
		exec(this.dbusCommand('setalpha ' + alpha), (err, stdout, stderr) => {});
	}

	getCurrentPosition () {
		console.log('getCurrentPosition');
		return new Promise( (resolve, reject) => {
			exec(this.dbusCommand('getposition'), (error, stdout, stderr) => {
				console.log('getposition error, stdout, stderr:', error, stdout, stderr);
				if (error) reject();

				let position = parseInt(stdout);
				console.log('currentPosition:', position, 'or in seconds:', position / 1000);
				resolve(position);
			});
		});
	}

	getIsPlaying () {
		console.log('getIsPlaying');
		return new Promise( (resolve, reject) => {
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				console.log('getplaystatus error, stdout, stderr:', error, stdout, stderr);
				if (error) {
					console.error('error getting play status:', err);
					reject();
				}
				if (stdout === 'Playing') {
					resolve(true);
				} else {
					resolve(false);
				}
			});
		});
	}

	getDuration () {
		return new Promise( (resolve, reject) => {
			exec( this.dbusCommand('getduration'), (error, stdout, stderr) => {
				if (error) reject();

				let duration = parseInt(stdout);
				console.log('getDuration:', duration, 'or in seconds:', duration / 1000);
				resolve(duration);
			});
		});
	}

	getVolume () {
		exec(this.dbusCommand('getvolume'), (error, stdout, stderr) => {
			if (error) return null;
			let volume = parseFloat(stdout);
			console.log('getVolume:', volume);
		});	}

	onProgress (callback) {
		console.log('add new progress handler for layer', this.layer);
		this.progressHandler = setInterval( () => {
			this.getIsPlaying()
				 .then( (isPlaying) => {
					 if (isPlaying) {
						 callback({'position': this.getCurrentPosition(), 'duration': this.getDuration()});
					 } else {
						 callback({ 'playing': false });
					 }
				 })
				 .catch( () => {
					 console.error('error getting isPlaying status');
					 callback({ 'status': 'error', 'playing': false });
				 });
		}, 1000);
	}

	onStart (callback) {
		console.log('onStart event');
		if (callback) {
			callback();
		}
	}

	waitTillPlaying (callback) {
		console.log('waitTillPlaying');
		let countAttempts = 0;
		let interval;
		interval = setInterval( () => {
			countAttempts++;
			exec(this.dbusCommand('getplaystatus'), (error, stdout, stderr) => {
				if (error) {
					console.log('error on getplaystus:', error);
				} else {
					console.log('getplaystatus result after', countAttempts, ':', stdout);
					clearInterval(interval);
					callback();
				}
			});
		}, 1000);
	}

	open (path, doneCallback, holdMode) {
		console.log('OmxInstance open() for layer #', this.layer, 'holdMode?', holdMode);
		let settings = this.options || {};
		let args = [];
		let command = 'omxplayer';

		args.push('"'+path+'"');

		if (['hdmi','local','both'].indexOf(settings.audioOutput) != -1) {
			args.push('-o');
			args.push(settings.audioOutput);
		}

		if (settings.blackBackground !== false) { // defaults to true
			args.push('-b');
		}

		if (settings.disableKeys === true) { //defaults to  false
			args.push('--no-keys')
		}

		if (settings.disableOnScreenDisplay === true) { //defaults to  false
			args.push('--no-osd')
		}

		if (settings.disableGhostbox === true) { //defaults to  false
			args.push('--no-ghost-box');
		}

		if (settings.loop === true) { // defaults to false
			args.push('--loop');
		}

		if (settings.subtitlePath && settings.subtitlePath != "" ){
			args.push('--subtitles');
			args.push('"'+settings.subtitlePath+'"');
		}

		if (settings.startAt){
			args.push('--pos');
			args.push(''+settings.startAt+'');
		}

		if (settings.layer) {
			args.push('--layer');
			args.push(settings.layer);
		}

		if (holdMode) {
			args.push('--alpha');
			args.push(0);
		}

		args.push('--dbus_name');
		args.push(this.dbusDest);

		let finalOpenCommand = command+' '+args.join(' ')+' < omxpipe'+this.layer;
		console.log('finalOpenCommand:', finalOpenCommand);

	  exec(finalOpenCommand, (error, stdout, stderr) => {
			doneCallback();
			console.log('omxpipe done for layer', this.layer);
  		this.cancelProgressHandlerIfActive();
	  	console.log(stdout);
	  });
	  exec(' . > omxpipe'+this.layer, (error, stdout, stderr) => {
			this.waitTillPlaying( () => {
				console.log('started ok');
				this.onStart();
				if (holdMode) {
					console.log('holdMode ON, so immediately pause and hide');
					this.pause();
					this.setVisibility(false);
				}
			});
		});

	}

}

module.exports = OmxInstance;
<|endoftext|>


<commit_before>const cssPrefix = require('postcss-prefix')
const nodeResolve = require('resolve')
const mapLimit = require('map-limit')
const postcss = require('postcss')
const assert = require('assert')
const crypto = require('crypto')
const xtend = require('xtend')
const stackTrace = require('stack-trace')
const cssResolve = require('style-resolve').sync
const fs = require('fs')
const path = require('path')

module.exports = sheetify

// transform css
// (str, str, obj?, fn) -> str
function sheetify (src, filename, options, done) {
  // handle tagged template calls directly from Node
  const isTemplate = Array.isArray(src)
  if (isTemplate) src = src.join('')
  assert.equal(typeof src, 'string', 'src must be a string')
  src = src.trim()

  // Ensure prefix is always correct when run from inside node
  let css
  if (!isTemplate && !filename) {
     // module or file name via tagged template call
    const callerDirname = path.dirname(stackTrace.get()[1].getFileName())
    const resolved = cssResolve(src, { basedir: callerDirname })
    css = fs.readFileSync(resolved, 'utf8').trim()
  } else {
    // it better be some css
    css = src
  }

  css = css.trim()
  const prefix = '_' + crypto.createHash('md5')
    .update(css)
    .digest('hex')
    .slice(0, 8)

  // only parse if in a browserify transform
  if (filename) parseCss(src, filename, prefix, options, done)

  return prefix
}

// parse css
// (str, str, str, obj, fn) -> null
function parseCss (src, filename, prefix, options, done) {
  assert.equal(typeof filename, 'string', 'filename must be a string')
  assert.equal(typeof prefix, 'string', 'prefix must be a string')
  assert.equal(typeof options, 'object', 'options must be a object')
  assert.equal(typeof done, 'function', 'done must be a function')

  applyTransforms(filename, String(src), xtend(options), function (err, css) {
    if (err) return done(err)
    var p = postcss()
    if (options.global !== true) p = p.use(cssPrefix('.' + prefix))

    try {
      css = p.process(css).toString()

      return done(null, css, prefix)
    } catch (e) {
      return done(e)
    }
  })

  // apply transforms to a string of css,
  // one at the time
  // (str, str, obj, fn) -> null
  function applyTransforms (filename, src, options, done) {
    options.use = [].concat(options.use || []).concat(options.u || [])
    mapLimit(options.use, 1, iterate, function (err) {
      if (err) return done(err)
      done(null, src)
    })

    // find and apply a transform to a string of css
    // (fn, fn) -> null
    function iterate (plugin, next) {
      if (typeof plugin === 'string') {
        plugin = [ plugin, {} ]
      } else if (!Array.isArray(plugin)) {
        return done(new Error('Plugin must be a string or array'))
      }

      const name = plugin[0]
      const opts = plugin[1] || {}

      const resolveOpts = {
        basedir: opts.basedir || options.basedir || process.cwd()
      }
      nodeResolve(name, resolveOpts, function (err, transformPath) {
        if (err) return done(err)

        const transform = require(transformPath)
        transform(filename, src, opts, function (err, result) {
          if (err) return next(err)
          src = result
          next()
        })
      })
    }
  }
}
<commit_msg>Fix calls with options<commit_after>const cssPrefix = require('postcss-prefix')
const nodeResolve = require('resolve')
const mapLimit = require('map-limit')
const postcss = require('postcss')
const assert = require('assert')
const crypto = require('crypto')
const xtend = require('xtend')
const stackTrace = require('stack-trace')
const cssResolve = require('style-resolve').sync
const fs = require('fs')
const path = require('path')

module.exports = sheetify

// transform css
// (str, str, obj?, fn) -> str
function sheetify (src, filename, options, done) {
  // handle tagged template calls directly from Node
  const isTemplate = Array.isArray(src)
  if (isTemplate) src = src.join('')
  assert.equal(typeof src, 'string', 'src must be a string')
  src = src.trim()

  // Ensure prefix is always correct when run from inside node
  let css
  if (!isTemplate && (!filename || typeof filename === 'object')) {
     // module or file name via tagged template call w or w/out options
    const callerDirname = path.dirname(stackTrace.get()[1].getFileName())
    const resolved = cssResolve(src, { basedir: callerDirname })
    css = fs.readFileSync(resolved, 'utf8').trim()
  } else {
    // it better be some css
    css = src
  }

  css = css.trim()
  const prefix = '_' + crypto.createHash('md5')
    .update(css)
    .digest('hex')
    .slice(0, 8)

  // only parse if in a browserify transform
  if (typeof filename === 'string') parseCss(src, filename, prefix, options, done)

  return prefix
}

// parse css
// (str, str, str, obj, fn) -> null
function parseCss (src, filename, prefix, options, done) {
  assert.equal(typeof filename, 'string', 'filename must be a string')
  assert.equal(typeof prefix, 'string', 'prefix must be a string')
  assert.equal(typeof options, 'object', 'options must be a object')
  assert.equal(typeof done, 'function', 'done must be a function')

  applyTransforms(filename, String(src), xtend(options), function (err, css) {
    if (err) return done(err)
    var p = postcss()
    if (options.global !== true) p = p.use(cssPrefix('.' + prefix))

    try {
      css = p.process(css).toString()

      return done(null, css, prefix)
    } catch (e) {
      return done(e)
    }
  })

  // apply transforms to a string of css,
  // one at the time
  // (str, str, obj, fn) -> null
  function applyTransforms (filename, src, options, done) {
    options.use = [].concat(options.use || []).concat(options.u || [])
    mapLimit(options.use, 1, iterate, function (err) {
      if (err) return done(err)
      done(null, src)
    })

    // find and apply a transform to a string of css
    // (fn, fn) -> null
    function iterate (plugin, next) {
      if (typeof plugin === 'string') {
        plugin = [ plugin, {} ]
      } else if (!Array.isArray(plugin)) {
        return done(new Error('Plugin must be a string or array'))
      }

      const name = plugin[0]
      const opts = plugin[1] || {}

      const resolveOpts = {
        basedir: opts.basedir || options.basedir || process.cwd()
      }
      nodeResolve(name, resolveOpts, function (err, transformPath) {
        if (err) return done(err)

        const transform = require(transformPath)
        transform(filename, src, opts, function (err, result) {
          if (err) return next(err)
          src = result
          next()
        })
      })
    }
  }
}
<|endoftext|>


<commit_before>// dbus.freedesktop.org/doc/dbus-specification.html

var EventEmitter = require('events').EventEmitter;
var net = require('net');
require('abstractsocket')(net);

var binary =    require('binary');
var parser =    require('./lib/parser');
var constants = require('./lib/constants');
var message   = require('./lib/message');

function createStream(opts) {
  if (opts.stream)
      return opts.stream;
  var host = opts.host;
  var port = opts.port;
  var socket = opts.socket;
  var stream;
  if (socket)
    return net.createConnection(socket);
  if (port)
    return net.createConnection(port, host);
  var busAddress = opts.busAddress || process.env.DBUS_SESSION_BUS_ADDRESS;
  if (!busAddress) throw new Error('unknown bus address');
  var familyParams = busAddress.split(':');
  var family = familyParams[0];
  var params = {};
  familyParams[1].split(',').map(function(p) {
    var keyVal = p.split('=');
    params[keyVal[0]] = keyVal[1];
  });
  switch(family.toLowerCase()) {
    case 'tcp':
       host = params.host || 'localhost';
       port = params.port;
       return net.createConnection(port, host);

    case 'unix':
       if (params.socket)
         return net.createConnection(params.socket);
       if (params.abstract) {
         return net.createConnection('\u0000' + params.abstract);
       }
       if (params.path)
    	   return net.createConnection(params.path);

       throw new Error('not enough parameters for \'unix\' connection - you need to specify \'socket\' or \'abstract\' parameter');
    default:
       throw new Error('unknown address type');
  }

}

module.exports = function (opts) {
    var self = new EventEmitter();
    if (!opts) opts = {};
    var stream = self.stream = createStream(opts);
    stream.setNoDelay();

    stream.on('error', function (err) {
        self.emit('error', err);
    });

    stream.on('end', function () {
        self.emit('end');
        self.write = function (buf) {
            console.warn("Didn't write bytes to closed stream");
        };
    });

//    var hexy = require('./lib/hexy');
//    self.stream.on('data', function(data) {
//       console.error(hexy.hexy(data, {prefix: 'from dbus  '}));
//    });

    // start parsing input stream
    parser(self, opts);

    self.write = function (buf) {

        //var hexy = require('./hexy');
        //console.error(hexy.hexy(buf, {prefix: 'from client'}));

        if (Buffer.isBuffer(buf)) {
            stream.write(buf);
        }
        else {
            stream.write(buf, 'binary');
        }
        return self;
    };

    self.end = function () {
        stream.end();
        return self;
    };

    // TODO this is really bad
    // use own internal queue or move to async initialisation
    self.message = function(msg) {
       if (self.state === 'connected')
           message.write.call(self, msg);
       else {
           self.once('connect', function() {
               self.state = 'connected';
               message.write.call(self, msg);
           });
       }
    };
    return self;
};

var bus = require('./lib/bus');
module.exports.createClient = function(params) {
    var conn = module.exports(params);
    return new bus(conn);
};

module.exports.systemBus = function() {
    return module.exports.createClient({socket: '/var/run/dbus/system_bus_socket'});
};

module.exports.sessionBus = function(opts) {
    return module.exports.createClient(opts);
};

module.exports.messageType = constants.messageType;
module.exports.createConnection = module.exports;

var server = require('./lib/server');
module.exports.createServer = server.createServer;
<commit_msg>-- added "path" parameter to error message.<commit_after>// dbus.freedesktop.org/doc/dbus-specification.html

var EventEmitter = require('events').EventEmitter;
var net = require('net');
require('abstractsocket')(net);

var binary =    require('binary');
var parser =    require('./lib/parser');
var constants = require('./lib/constants');
var message   = require('./lib/message');

function createStream(opts) {
  if (opts.stream)
      return opts.stream;
  var host = opts.host;
  var port = opts.port;
  var socket = opts.socket;
  var stream;
  if (socket)
    return net.createConnection(socket);
  if (port)
    return net.createConnection(port, host);
  var busAddress = opts.busAddress || process.env.DBUS_SESSION_BUS_ADDRESS;
  if (!busAddress) throw new Error('unknown bus address');
  var familyParams = busAddress.split(':');
  var family = familyParams[0];
  var params = {};
  familyParams[1].split(',').map(function(p) {
    var keyVal = p.split('=');
    params[keyVal[0]] = keyVal[1];
  });
  switch(family.toLowerCase()) {
    case 'tcp':
       host = params.host || 'localhost';
       port = params.port;
       return net.createConnection(port, host);

    case 'unix':
       if (params.socket)
         return net.createConnection(params.socket);
       if (params.abstract) {
         return net.createConnection('\u0000' + params.abstract);
       }
       if (params.path)
    	   return net.createConnection(params.path);

       throw new Error('not enough parameters for \'unix\' connection - you need to specify \'socket\' or \'abstract\' or \'path\' parameter');
    default:
       throw new Error('unknown address type');
  }

}

module.exports = function (opts) {
    var self = new EventEmitter();
    if (!opts) opts = {};
    var stream = self.stream = createStream(opts);
    stream.setNoDelay();

    stream.on('error', function (err) {
        self.emit('error', err);
    });

    stream.on('end', function () {
        self.emit('end');
        self.write = function (buf) {
            console.warn("Didn't write bytes to closed stream");
        };
    });

//    var hexy = require('./lib/hexy');
//    self.stream.on('data', function(data) {
//       console.error(hexy.hexy(data, {prefix: 'from dbus  '}));
//    });

    // start parsing input stream
    parser(self, opts);

    self.write = function (buf) {

        //var hexy = require('./hexy');
        //console.error(hexy.hexy(buf, {prefix: 'from client'}));

        if (Buffer.isBuffer(buf)) {
            stream.write(buf);
        }
        else {
            stream.write(buf, 'binary');
        }
        return self;
    };

    self.end = function () {
        stream.end();
        return self;
    };

    // TODO this is really bad
    // use own internal queue or move to async initialisation
    self.message = function(msg) {
       if (self.state === 'connected')
           message.write.call(self, msg);
       else {
           self.once('connect', function() {
               self.state = 'connected';
               message.write.call(self, msg);
           });
       }
    };
    return self;
};

var bus = require('./lib/bus');
module.exports.createClient = function(params) {
    var conn = module.exports(params);
    return new bus(conn);
};

module.exports.systemBus = function() {
    return module.exports.createClient({socket: '/var/run/dbus/system_bus_socket'});
};

module.exports.sessionBus = function(opts) {
    return module.exports.createClient(opts);
};

module.exports.messageType = constants.messageType;
module.exports.createConnection = module.exports;

var server = require('./lib/server');
module.exports.createServer = server.createServer;
<|endoftext|>


<commit_before>var {Cc, Ci} = require("chrome");

var gcSvc = Cc["@mozilla.org/grammarcheck;1"].getService(Ci.nsIEditorGrammarCheck);
var xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);

let checkerUrl = "https://languagetool.org:8081/";

function handleText(text) {
	// TODO: add logic to avoid too many API requests (timeout)
	var oReq = xmlhttp;
	oReq.addEventListener("load", function(result) {
		var xml = oReq.responseXML;
		var errors = xml.getElementsByTagName("error");
		var startPositions = [];
		var endPositions = [];
		var replacements = [];
		var messages = [];
		for (var i = 0; i < errors.length; i++) {
			//console.error("Got match: " + errors[i].getAttribute("offset") + ", len: " + errors[i].getAttribute("errorlength"));
			var startPos = parseInt(errors[i].getAttribute("offset"));
			var endPos = startPos + parseInt(errors[i].getAttribute("errorlength"));
			startPositions.push(startPos);
			endPositions.push(endPos);
			replacements.push(errors[i].getAttribute("replacements"));
			messages.push(errors[i].getAttribute("msg"));
		}
		gcSvc.errorsFound(startPositions, endPositions, startPositions.length);
		for (var j = 0; j < errors.length; j++) {
			var suggestions = replacements[j].split("#");
			for (var k = 0; k < suggestions.length; k++) {
				if (suggestions[k] !== "") {
					// TODO: avoid duplications
					gcSvc.addSuggestionForError(j, suggestions[k], messages[j]);
				}
			}
		}
		//gcSvc.addSuggestionForError(0, "suggestion", "message");
	});

	oReq.open("POST", checkerUrl, true);
	oReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	var data = "autodetect=1&text=" + text;
	oReq.send(data);
}

gcSvc.registerAddon(handleText);
<commit_msg>fix event handling<commit_after>var {Cc, Ci} = require("chrome");

var gcSvc = Cc["@mozilla.org/grammarcheck;1"].getService(Ci.nsIEditorGrammarCheck);
var xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
var { setTimeout, clearTimeout } = require("sdk/timers");

xmlhttp.addEventListener("error", function(result) {
	console.error("API request ended in error");
});
xmlhttp.addEventListener("abort", function(result) {
	console.error("API request aborted");
});
xmlhttp.addEventListener("loadend", function(result) {
	handleResponse(result);
});

let checkerUrl = "https://languagetool.org:8081/";

function handleResponse(text) {
	var xml = xmlhttp.responseXML;
	var errors = xml.getElementsByTagName("error");
	var startPositions = [];
	var endPositions = [];
	var replacements = [];
	var messages = [];
	for (var i = 0; i < errors.length; i++) {
		//console.error("Got match: " + errors[i].getAttribute("offset") + ", len: " + errors[i].getAttribute("errorlength"));
		var startPos = parseInt(errors[i].getAttribute("offset"));
		var endPos = startPos + parseInt(errors[i].getAttribute("errorlength"));
		startPositions.push(startPos);
		endPositions.push(endPos);
		replacements.push(errors[i].getAttribute("replacements"));
		messages.push(errors[i].getAttribute("msg"));
	}
	gcSvc.errorsFound(startPositions, endPositions, startPositions.length);
	for (var j = 0; j < errors.length; j++) {
		var suggestions = replacements[j].split("#");
		for (var k = 0; k < suggestions.length; k++) {
			if (suggestions[k] !== "") {
				gcSvc.addSuggestionForError(j, suggestions[k], messages[j]);
			}
		}
	}
}

function sendRequest(text) {
	//console.error("TEXT: " + text);
	// TODO: add logic to avoid too many API requests (timeout)

	/*setTimeout(function() {
		var sp = [0, 15];
		var ep = [5, 17];
		gcSvc.errorsFound(sp, ep, sp.length);
		gcSvc.addSuggestionForError(0, "bsuggestion 1", "message 1");
		gcSvc.addSuggestionForError(1, "bsuggestion 2", "message 2");
		gcSvc.addSuggestionForError(1, "bsuggestion 3", "message 2");
	}, 500);*/

	xmlhttp.open("POST", checkerUrl, true);
	xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	var data = "autodetect=1&text=" + text;
	xmlhttp.send(data);
}

gcSvc.registerAddon(sendRequest);
<|endoftext|>