<commit_before>#!/usr/bin/env node
'use strict'
const cli = require('cli')
const json = require('jsonfile')
const metalsmith = require('metalsmith')
const filter = require('metalsmith-filter')
const markdown = require('metalsmith-markdown')
// const collections = require('metalsmith-collections')
// const prompt = require('metalsmith-prompt')
const pkg = json.readFileSync(__dirname + '/../package.json', { throws: true }) || {}
const settings = json.readFileSync(__dirname + '/../settings.json', { throws: true }) || {}

const writeJson = (files, metalsmith, done) => {
  var data = {
    app: settings,
    data: []
  }

  data.app.version = pkg.version

  for (var file in files) {
    files[file].contents = files[file].contents.toString()
    //   files[file].section = files[file].section || 'others';
    files[file].id = file.replace(/\.md|\.html/, '').replace(/\//g, '__')
    //   if (files[file].scripts) {
    //     files[file].scripts = files[file].scripts.replace(/\s/g, '').split(',');
    //   }

    //   if (files[file].styles) {
    //     files[file].styles = files[file].styles.replace(/\s/g, '').split(',');
    //   }

    //   data.app.home = options.home.replace('.md', '');

      // Removing unnecessaries properties...
    delete files[file].mode
    delete files[file].stats
    delete files[file].template
    data.data.push(files[file])
  }
  cli.info('Creating data with markdown founded...')

  json.writeFileSync(settings.dist, { data: data }, { spaces: 2 }, (err) => {
    cli.fatal(err)
  })
  cli.ok(`Reactdocs data created on ${settings.dist}`)
  if (cli.options.compile) {
    cli.spinner('Compiling app...', false)
  }
  done()
}

module.exports = ((obj) => {
  const build = () => {
    cli.info(`Reading all markdown files from ${settings.cwd}${settings.src}`)
    metalsmith(settings.cwd)
      .source(settings.src)
      .use(filter(settings.filePattern || '**/*.md'))
      .use(markdown())
      .use(writeJson)
      .build((err, files) => {
        if (err) {
          cli.fatal(err)
        }
      })
  }

  return {
    init: (config) => {
      build(config)
    }
  }
})()
<commit_msg>Update dependencies on script<commit_after>#!/usr/bin/env node
'use strict'
const cli = require('cli')
const json = require('jsonfile')
const metalsmith = require('metalsmith')
const filter = require('metalsmith-filter')
const updated = require('metalsmith-updated')
const excerpt = require('metalsmith-excerpts')
const markdown = require('metalsmith-markdown')
const pkg = json.readFileSync(__dirname + '/../package.json', { throws: true }) || {}
var settings = '/../settings.json'

const writeJson = (files, metalsmith, done) => {
  var data = {
    app: settings,
    data: []
  }

  data.app.version = pkg.version

  for (var file in files) {
    files[file].contents = files[file].contents.toString()
    files[file].id = file.replace(/\.md|\.html/, '').replace(/\//g, '__')
    // Removing unnecessaries properties...
    delete files[file].mode
    delete files[file].stats
    delete files[file].template
    data.data.push(files[file])
  }

  cli.info(`Total files: ${Object.keys(files).length}`)

  json.writeFileSync(settings.dist, data, { spaces: 2 }, (err) => {
    cli.fatal(err)
  })
  cli.info(`Output file created on: ${settings.dist}`)
  cli.ok('Markdown to json process has been finished!')

  done()
}

const build = (settingsFile) => {
  settings = json.readFileSync(__dirname + (settingsFile || settings), { throws: true }) || {}
  cli.info(`Path: ${settings.cwd}${settings.src}`)
  cli.info(`Pattern: ${settings.filePattern}`)

  metalsmith(settings.cwd)
	.source(settings.src)
	.use(filter(settings.filePattern || '**/*.md'))
	.use(markdown())
	.use(excerpt())
	.use(updated())
	.use(writeJson)
	.build((err, files) => {
  	    if (err) {
    		cli.fatal(err)
  		}
	})
}

module.exports = {
  build: build
}
<|endoftext|>


<commit_before>/**
 *@fileoverview Implementation of code generating engine
 *@author Raghav Dua
 */

'use strict';

var Syntax = require ('./syntax');

function getDefaultOptions () {
	return {
		format: {
			indent: {
				style: '\t',
				base: 0
			},
			newline: '\n',
			space: ' ',
			quotes: 'single',
			minify: false
		}
	};
}

function getMinifyOptions () {
	return {
		format: {
			indent: {
				style: '',
				base: 0
			},
			newline: '',
			space: ' ',
			quotes: 'single',
			minify: true
		}
	};
}

function isStrictlyObject (i) {
	return (
		i !== null &&
		typeof i === 'object' &&
		i.constructor !== Array
	);
}

function isASTNode (possibleNode) {
	return (
		isStrictlyObject (possibleNode) &&
		possibleNode.type &&
		typeof possibleNode.type === 'string'
	);
}

function isStatement (node) {
	return CodeGenerator.Statement.hasOwnProperty (node.type);
}

function isExpression (node) {
	return CodeGenerator.Expression.hasOwnProperty (node.type);
}

function mergeObjects (target, source) {
	Object.keys (source).forEach (function (key) {
		target [key] = source [key];
	});

	return target;
}

function repeatString (str, times) {
	return Array (times+1).join (str);
}

function append (mainString, subString) {
	return mainString + subString;
}

function removeAppended (mainString, subString) {
	return mainString.slice (0, -subString.length);
}

function flatten (arrayOrString) {
	if (typeof arrayOrString === 'string') {

		return arrayOrString;

	} else if (typeof arrayOrString === 'object' &&
		arrayOrString.constructor === Array) {

		var result = '';

		for (var i = 0; i < arrayOrString.length; i++) {
			result += flatten (arrayOrString [i]);
		}
		return result;

	}

	throw new Error ('Invalid argument type');
}

function fillGapsDeeply (defaultOpts, opts) {
	var options = {};

	Object.keys (defaultOpts).forEach (function (key) {
 		var defOpt = defaultOpts [key];

 		if (isStrictlyObject (defOpt)) {
 			options [key] = fillGapsDeeply (defOpt, opts [key] || {})
 		} else {
 			options [key] = opts [key] || defOpt;
 		}
 	});

 	return options;
}

var CodeGenerator = function CodeGenerator () {
	if (!(this instanceof CodeGenerator)) {
		return new CodeGenerator ();
	}
}

CodeGenerator.prototype.init = function (config) {
	var format = config.format;

	this._indent = repeatString (format.indent.style, format.indent.base);
	this._indentStyle = format.indent.style;
	this._space = format.space;
	this._lineBreak = format.newline;

	switch (format.quotes) {
		case 'single':
			this._quote = '\'';
			break;
		case 'double':
			this._quote = '\"';
			break;
		default:
			throw new Error ('Invalid value specified for quotes (use \'single\' or \'double\')');
	}

	return this;	//because chainability = SWAG
};

CodeGenerator.prototype.generateStatement = function (node) {
	return this [node.type] (node);
};

CodeGenerator.prototype.generateExpression = function (node) {
	return this [node.type] (node);
};

CodeGenerator.prototype.generate = function (node) {
	if (isStatement (node)) {
		return this.generateStatement (node);
	}
	if (isExpression (node)) {
		return this.generateExpression (node);
	}

	throw new Error ('Unknown node type: ' + node.type);
};

CodeGenerator.Statement = {

	BlockStatement: function (node) {},
	BreakStatement: function (node) {},
	CatchClause: function (node) {},
	ContinueStatement: function (node) {},
	ContractStatement: function (node) {},
	DebuggerStatement: function (node) {},
	DeclarativeExpressionList: function (node) {},
	DoWhileStatement: function (node) {},
	EmptyStatement: function (node) {},
	EnumDeclaration: function (node) {},
	EventDeclaration: function (node) {},
	ExpressionStatement: function (node) {},
	ForInStatement: function (node) {},
	ForStatement: function (node) {},
	FunctionDeclaration: function (node) {},
	FunctionName: function (node) {},
	IfStatement: function (node) {},
	ImportStatement: function (node) {},
	InformalParameter: function (node) {},
	IsStatement: function (node) {},
	LabeledStatement: function (node) {},
	LibraryStatement: function (node) {},
	ModifierDeclaration: function (node) {},
	ModifierName: function (node) {},
	Program: function (node) {},
	ReturnStatement: function (node) {},
	StructDeclaration: function (node) {},
	SwitchCase: function (node) {},
	SwitchStatement: function (node) {},
	Symbol: function (node) {},
	ThrowStatement: function (node) {},
	TryStatement: function (node) {},
	VariableDeclaration: function (node) {},
	VariableDeclarator: function (node) {},
	WhileStatement: function (node) {},
	WithStatement: function (node) {}

};

mergeObjects (CodeGenerator.prototype, CodeGenerator.Statement);

CodeGenerator.Expression = {

	ArrayExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		if (!node.elements.length) {
			return '[]';
		}

		result = ['[', this._lineBreak];
		this._indent = append (this._indent, this._indentStyle);

		node.elements.forEach (function (element) {
			result.push (
				GENERATOR_OBJECT._indent,
				GENERATOR_OBJECT [element.type] (element),
				',',
				GENERATOR_OBJECT._lineBreak
			);
		});

		//remove the last (extra) comma, restore indentation and add whitespace chars & closing bracket
		result [result.length - 2] = GENERATOR_OBJECT._lineBreak;
		this._indent = removeAppended (this._indent, this._indentStyle);
		result [result.length - 1] = GENERATOR_OBJECT._indent;
		result.push (']');

		return result;
	},

	AssignmentExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.left.type] (node.left),
			GENERATOR_OBJECT._space,
			node.operator,
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.right.type] (node.right)
		];

		return result;
	},

	BinaryExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.left.type] (node.left),
			GENERATOR_OBJECT._space,
			node.operator,
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.right.type] (node.right)
		];

		return result;
	},

	CallExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.callee.type] (node.callee),
			GENERATOR_OBJECT._space,
			'('
		];

		if (node.arguments.length) {
			node.arguments.forEach (function (arg) {
				result.push (
					GENERATOR_OBJECT [arg.type] (arg),
					',',
					GENERATOR_OBJECT._space
				);
			});
			result = result.slice (0, -2);	//remove trailing comma & space
		}

		result.push (')');

		return result;
	},

	ConditionalExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.test.type] (node.test),
			GENERATOR_OBJECT._space,
			'?',
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.consequent.type] (node.consequent),
			GENERATOR_OBJECT._space,
			':',
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.alternate.type] (node.alternate)
		];

		return result;
	},

	DeclarativeExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.literal.type] (node.literal),
			GENERATOR_OBJECT._space,
			node.is_constant ? Syntax.constant + GENERATOR_OBJECT._space : '',
			node.is_public ? Syntax.public + GENERATOR_OBJECT._space : '',
			node.is_memory ? Syntax.memory + GENERATOR_OBJECT._space : '',
			node.name
		];

		return result;
	},

	Identifier:function (node) {
		return node.name;
	},

	Literal: function (node) {
		var GENERATOR_OBJECT = this;

		if (node.value === null) {
			return 'null';
		} else if (node.value && node.value.constructor === RegExp) {
			return node.value.toString ();
		}

		switch (typeof node.value) {
			case 'number':
			case 'boolean':
				return node.value.toString ();
			case 'string':
				return GENERATOR_OBJECT._quote +
					node.value +
					GENERATOR_OBJECT._quote;
			default:
				throw new Error ('Invalid Literal');
		}
	},

	MappingExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			Syntax.mapping,
			GENERATOR_OBJECT._space,
			'(',
			GENERATOR_OBJECT [node.from.type] (node.from),
			GENERATOR_OBJECT._space,
			'=>',
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.to.type] (node.to),
			')'
		];

		return result;
	},

	MemberExpression: function (node) {},

	NewExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			Syntax.new,
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.callee.type] (node.callee),
			GENERATOR_OBJECT._space,
			'('
		];

		if (node.arguments.length) {
			node.arguments.forEach (function (arg) {
				result.push (
					GENERATOR_OBJECT [arg.type] (arg),
					',',
					GENERATOR_OBJECT._space
				);
			});
			result = result.slice (0, -2);
		}
		result.push (')');

		return result;
	},

	ObjectExpression: function (node) {},
	SequenceExpression: function (node) {},
	ThisExpression: function (node) {},

	Type: function (node) {
		var GENERATOR_OBJECT = this, result;

		if (isStrictlyObject (node.literal)) {
			return [GENERATOR_OBJECT [node.literal.type] (node.literal)];
		}

		result = [node.literal];

		if (node.array_parts.length) {
			result.push (
				node.array_parts [0] === null ? '[]' : '[' + node.array_parts [0] + ']'
			);
		}

		return result;
	},

	UpdateExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			node.prefix ? node.operator : '',
			GENERATOR_OBJECT [node.argument.type] (node.argument),
			node.prefix ? '' : node.operator
		];

		return result;
	}

};

mergeObjects (CodeGenerator.prototype, CodeGenerator.Expression);

module.exports = function (node, options) {
	var defaultOptions = options &&
		options.format &&
		options.format.minify ?
		getMinifyOptions () : getDefaultOptions ();
	var sourceCode;

	if (!isASTNode (node)) {
		throw new Error ('Invalid Argument for node');
	}
	if (options && !isStrictlyObject (options)) {
		throw new Error ('Invalid argument for options');
	}

 	//make sure any un-specified options are set to their default values
 	options = fillGapsDeeply (defaultOptions, options || {});
 	sourceCode = new CodeGenerator ()
		.init (options)
		.generate (node);

 	return flatten (sourceCode);
};<commit_msg>ObjectExpression<commit_after>/**
 *@fileoverview Implementation of code generating engine
 *@author Raghav Dua
 */

'use strict';

var Syntax = require ('./syntax');

function getDefaultOptions () {
	return {
		format: {
			indent: {
				style: '\t',
				base: 0
			},
			newline: '\n',
			space: ' ',
			quotes: 'single',
			minify: false
		}
	};
}

function getMinifyOptions () {
	return {
		format: {
			indent: {
				style: '',
				base: 0
			},
			newline: '',
			space: ' ',
			quotes: 'single',
			minify: true
		}
	};
}

function isStrictlyObject (i) {
	return (
		i !== null &&
		typeof i === 'object' &&
		i.constructor !== Array
	);
}

function isASTNode (possibleNode) {
	return (
		isStrictlyObject (possibleNode) &&
		possibleNode.type &&
		typeof possibleNode.type === 'string'
	);
}

function isStatement (node) {
	return CodeGenerator.Statement.hasOwnProperty (node.type);
}

function isExpression (node) {
	return CodeGenerator.Expression.hasOwnProperty (node.type);
}

function mergeObjects (target, source) {
	Object.keys (source).forEach (function (key) {
		target [key] = source [key];
	});

	return target;
}

function repeatString (str, times) {
	return Array (times+1).join (str);
}

function append (mainString, subString) {
	return mainString + subString;
}

function removeAppended (mainString, subString) {
	return mainString.slice (0, -subString.length);
}

function flatten (arrayOrString) {
	if (typeof arrayOrString === 'string') {

		return arrayOrString;

	} else if (typeof arrayOrString === 'object' &&
		arrayOrString.constructor === Array) {

		var result = '';

		for (var i = 0; i < arrayOrString.length; i++) {
			result += flatten (arrayOrString [i]);
		}
		return result;

	}

	throw new Error ('Invalid argument type');
}

function fillGapsDeeply (defaultOpts, opts) {
	var options = {};

	Object.keys (defaultOpts).forEach (function (key) {
 		var defOpt = defaultOpts [key];

 		if (isStrictlyObject (defOpt)) {
 			options [key] = fillGapsDeeply (defOpt, opts [key] || {})
 		} else {
 			options [key] = opts [key] || defOpt;
 		}
 	});

 	return options;
}

var CodeGenerator = function CodeGenerator () {
	if (!(this instanceof CodeGenerator)) {
		return new CodeGenerator ();
	}
}

CodeGenerator.prototype.init = function (config) {
	var format = config.format;

	this._indent = repeatString (format.indent.style, format.indent.base);
	this._indentStyle = format.indent.style;
	this._space = format.space;
	this._lineBreak = format.newline;

	switch (format.quotes) {
		case 'single':
			this._quote = '\'';
			break;
		case 'double':
			this._quote = '\"';
			break;
		default:
			throw new Error ('Invalid value specified for quotes (use \'single\' or \'double\')');
	}

	return this;	//because chainability = SWAG
};

CodeGenerator.prototype.generateStatement = function (node) {
	return this [node.type] (node);
};

CodeGenerator.prototype.generateExpression = function (node) {
	return this [node.type] (node);
};

CodeGenerator.prototype.generate = function (node) {
	if (isStatement (node)) {
		return this.generateStatement (node);
	}
	if (isExpression (node)) {
		return this.generateExpression (node);
	}

	throw new Error ('Unknown node type: ' + node.type);
};

CodeGenerator.Statement = {

	BlockStatement: function (node) {},
	BreakStatement: function (node) {},
	CatchClause: function (node) {},
	ContinueStatement: function (node) {},
	ContractStatement: function (node) {},
	DebuggerStatement: function (node) {},
	DeclarativeExpressionList: function (node) {},
	DoWhileStatement: function (node) {},
	EmptyStatement: function (node) {},
	EnumDeclaration: function (node) {},
	EventDeclaration: function (node) {},
	ExpressionStatement: function (node) {},
	ForInStatement: function (node) {},
	ForStatement: function (node) {},
	FunctionDeclaration: function (node) {},
	FunctionName: function (node) {},
	IfStatement: function (node) {},
	ImportStatement: function (node) {},
	InformalParameter: function (node) {},
	IsStatement: function (node) {},
	LabeledStatement: function (node) {},
	LibraryStatement: function (node) {},
	ModifierDeclaration: function (node) {},
	ModifierName: function (node) {},
	Program: function (node) {},
	ReturnStatement: function (node) {},
	StructDeclaration: function (node) {},
	SwitchCase: function (node) {},
	SwitchStatement: function (node) {},
	Symbol: function (node) {},
	ThrowStatement: function (node) {},
	TryStatement: function (node) {},
	VariableDeclaration: function (node) {},
	VariableDeclarator: function (node) {},
	WhileStatement: function (node) {},
	WithStatement: function (node) {}

};

mergeObjects (CodeGenerator.prototype, CodeGenerator.Statement);

CodeGenerator.Expression = {

	ArrayExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		if (!node.elements.length) {
			return '[]';
		}

		result = ['[', this._lineBreak];
		this._indent = append (this._indent, this._indentStyle);

		node.elements.forEach (function (element) {
			result.push (
				GENERATOR_OBJECT._indent,
				GENERATOR_OBJECT [element.type] (element),
				',',
				GENERATOR_OBJECT._lineBreak
			);
		});

		//remove the last (extra) comma, restore indentation and add whitespace chars & closing bracket
		result [result.length - 2] = GENERATOR_OBJECT._lineBreak;
		this._indent = removeAppended (this._indent, this._indentStyle);
		result [result.length - 1] = GENERATOR_OBJECT._indent;
		result.push (']');

		return result;
	},

	AssignmentExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.left.type] (node.left),
			GENERATOR_OBJECT._space,
			node.operator,
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.right.type] (node.right)
		];

		return result;
	},

	BinaryExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.left.type] (node.left),
			GENERATOR_OBJECT._space,
			node.operator,
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.right.type] (node.right)
		];

		return result;
	},

	CallExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.callee.type] (node.callee),
			GENERATOR_OBJECT._space,
			'('
		];

		if (node.arguments.length) {
			node.arguments.forEach (function (arg) {
				result.push (
					GENERATOR_OBJECT [arg.type] (arg),
					',',
					GENERATOR_OBJECT._space
				);
			});
			result = result.slice (0, -2);	//remove trailing comma & space
		}

		result.push (')');

		return result;
	},

	ConditionalExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.test.type] (node.test),
			GENERATOR_OBJECT._space,
			'?',
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.consequent.type] (node.consequent),
			GENERATOR_OBJECT._space,
			':',
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.alternate.type] (node.alternate)
		];

		return result;
	},

	DeclarativeExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			GENERATOR_OBJECT [node.literal.type] (node.literal),
			GENERATOR_OBJECT._space,
			node.is_constant ? Syntax.constant + GENERATOR_OBJECT._space : '',
			node.is_public ? Syntax.public + GENERATOR_OBJECT._space : '',
			node.is_memory ? Syntax.memory + GENERATOR_OBJECT._space : '',
			node.name
		];

		return result;
	},

	Identifier:function (node) {
		return node.name;
	},

	Literal: function (node) {
		var GENERATOR_OBJECT = this;

		if (node.value === null) {
			return 'null';
		} else if (node.value && node.value.constructor === RegExp) {
			return node.value.toString ();
		}

		switch (typeof node.value) {
			case 'number':
			case 'boolean':
				return node.value.toString ();
			case 'string':
				return GENERATOR_OBJECT._quote +
					node.value +
					GENERATOR_OBJECT._quote;
			default:
				throw new Error ('Invalid Literal');
		}
	},

	MappingExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			Syntax.mapping,
			GENERATOR_OBJECT._space,
			'(',
			GENERATOR_OBJECT [node.from.type] (node.from),
			GENERATOR_OBJECT._space,
			'=>',
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.to.type] (node.to),
			')'
		];

		return result;
	},

	MemberExpression: function (node) {},

	NewExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			Syntax.new,
			GENERATOR_OBJECT._space,
			GENERATOR_OBJECT [node.callee.type] (node.callee),
			GENERATOR_OBJECT._space,
			'('
		];

		if (node.arguments.length) {
			node.arguments.forEach (function (arg) {
				result.push (
					GENERATOR_OBJECT [arg.type] (arg),
					',',
					GENERATOR_OBJECT._space
				);
			});
			result = result.slice (0, -2);
		}
		result.push (')');

		return result;
	},

	ObjectExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		if (!node.properties.length) {
			return '{}';
		}

		this._indent = append (this._indent, this._indentStyle);
		result = [
			'{',
			GENERATOR_OBJECT._lineBreak
		];

		node.properties.forEach (function (property) {
			result.push (
				GENERATOR_OBJECT._indent,
				GENERATOR_OBJECT [property.key.type] (property.key),
				':',
				GENERATOR_OBJECT._space,
				GENERATOR_OBJECT [property.value.type] (property.value),
				',',
				GENERATOR_OBJECT._lineBreak
			);
		});

		result.splice (result.length - 2, 1);	//remove the (unnecessary) comma after last value
		this._indent = removeAppended (this._indent, this._indentStyle);
		result.push (this._indent, '}');

		return result;
	},

	SequenceExpression: function (node) {},
	ThisExpression: function (node) {},

	Type: function (node) {
		var GENERATOR_OBJECT = this, result;

		if (isStrictlyObject (node.literal)) {
			return [GENERATOR_OBJECT [node.literal.type] (node.literal)];
		}

		result = [node.literal];

		if (node.array_parts.length) {
			result.push (
				node.array_parts [0] === null ? '[]' : '[' + node.array_parts [0] + ']'
			);
		}

		return result;
	},

	UpdateExpression: function (node) {
		var GENERATOR_OBJECT = this, result;

		result = [
			node.prefix ? node.operator : '',
			GENERATOR_OBJECT [node.argument.type] (node.argument),
			node.prefix ? '' : node.operator
		];

		return result;
	}

};

mergeObjects (CodeGenerator.prototype, CodeGenerator.Expression);

module.exports = function (node, options) {
	var defaultOptions = options &&
		options.format &&
		options.format.minify ?
		getMinifyOptions () : getDefaultOptions ();
	var sourceCode;

	if (!isASTNode (node)) {
		throw new Error ('Invalid Argument for node');
	}
	if (options && !isStrictlyObject (options)) {
		throw new Error ('Invalid argument for options');
	}

 	//make sure any un-specified options are set to their default values
 	options = fillGapsDeeply (defaultOptions, options || {});
 	sourceCode = new CodeGenerator ()
		.init (options)
		.generate (node);

 	return flatten (sourceCode);
};<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash'),
    Entry = require('./entry.js'),
    getEntries =  Entry.getEntries,
    utils = require('./utils.js');

var specialCategories = ['Methods', 'Properties'];
var reSpecialCategory = RegExp('^(?:' + specialCategories.join('|') + ')$');

/**
 * Escape special Markdown characters in a string.
 *
 * @param {string} str The string to escape.
 * @returns {string} The escaped string.
 */
function escape(str) {
  // replace all code snippets with a token
  var snippets = [];
  str = str.replace(/`.*?`/g, function(match) {
    snippets.push(match);
    return '@@token@@';
  });

  _.forOwn({
    '*': '*',
    '[': '[',
    ']': ']',
  }, function(replacement, char) {
    str = str.replace(RegExp('(\\\\?)\\' + char, 'g'), function(match, backslash) {
      if (backslash) {
        return match;
      }
      return replacement;
    });
  });

  // replace all tokens with code snippets
  str = str.replace(/@@token@@/g, function(match) {
    return snippets.shift();
  });
  return str;
}

/**
 * Make a anchor link
 *
 * @param {string} Value assigned by attr
 * @param {string} Attr name (id, href)
 * @param {string} contents of element, 'toc' is required
 *
 */
function makeHashHTML(attrValue, attr, contents) {
  contents || (contents = '');
  return '' +
    contents +
    '';
}

/**
 * Performs common string formatting operations.
 *
 * @private
 * @param {string} string The string to format.
 * @returns {string} The formatted string.
 */
function format(string) {
  // replace all code snippets with a token
  var snippets = [];
  string = string.replace(/`.*?`/g, function(match) {
    snippets.push(match);
    return '@@token@@';
  });

  string = string
    // italicize parentheses
    .replace(/(^|\s)(\([^)]+\))/g, '$1*$2*')
    // mark numbers as inline code
    .replace(/[\t ](-?\d+(?:.\d+)?)(?!\.[^\n])/g, ' `$1`');

  // replace all tokens with code snippets
  string = string.replace(/@@token@@/g, function(match) {
    return snippets.shift();
  });
  return string.trim();
}

/**
 * Get the seperator (. or .prototype.)
 *
 * @param {Entry} Entry object to get selector for
 *
 */
function getSeparator(entry) {
  return entry.isPlugin() ? '.prototype.' : '.';
}

/**
 * Modify a string by replacing named tokens with matching associated object values.
 *
 * @private
 * @param {string} string The string to modify.
 * @param {Object} object The template object.
 * @returns {string} The modified string.
 */
function interpolate(string, object) {
  return format(
    _.template(string)(object)
  );
}

/**
 * Generates the documentation from JS source.
 *
 * @param {string} The source code to generate the documentation for.
 * @param {object} The options object.
 *
 */
function generateDoc(source, options) {
  var url = options.url,
      entries = getEntries(source),
      api = [],
      byCategories = options.toc == 'categories',
      organizedEntries = {},
      categories,
      members = {},
      indexMarkdown = [],
      tocGroups,
      output = '# '+ options.title + '\n\n';

    // add entries and aliases to the API list
  _.each(entries, function(entry) {
    entry = new Entry(entry, source);
    api.push(entry);

    var aliases = entry.getAliases();
    if (aliases) {
      api.push.apply(api, aliases);
    }
  });

  // build the list of categories for the TOC
  // and generate content for each entry
  _.each(api, function(entry) {
    var name = entry.getName();
    // exit early if entry is private or has no name
    if (entry.isPrivate() || !name) {
      return;
    }
    var members = entry.getMembers();
    members.length || (members = ['']);
    var member = members[0];
    var memberGroup;

    if (
      !member ||
      entry.isCtor() ||
      (entry.getType() == 'Object' &&
        !/[=:]\s*(?:null|undefined)\s*[,;]?$/gi.test(entry.entry))
    ) {
      memberGroup = (member ? member + getSeparator(entry) : '') + name;
    } else if (entry.isStatic()) {
      memberGroup = member;
    } else if (!entry.isCtor()) {
      memberGroup = member + getSeparator(entry).slice(0,-1);
    }
    // add entry to TOC
    var tocGroup;
    if (byCategories) {
      var category = entry.getCategory();
      tocGroup = organizedEntries[category] || (organizedEntries[category] = []);
      tocGroup.push(entry);
    } else {
      // if the name of the entry matches a category, just place it directly in the the category
      tocGroup = member && member + getSeparator(entry) + name;
      if (tocGroup && _.keys(organizedEntries).indexOf(tocGroup) != -1) {
        organizedEntries[tocGroup].push(entry);
      } else {
        tocGroup = organizedEntries[memberGroup] || (organizedEntries[memberGroup] = []);
        tocGroup.push(entry);
      }
    }
    // generate description of entry
    // aliases don't get a description
    if (entry.isAlias()) {
      return;
    }
    var markdown = [];
    // start
    markdown.push('\n');

    // heading
    var theHash = member + entry.getHash();
    entry.theHash = theHash;

    markdown.push(interpolate([
      '### `${member}${separator}${call}`\n',
      '# ',
      '[Ⓢ](${href} "View in source") ',
      '[Ⓣ][1]'
    ].join(''), {
      'call':      entry.getCall(),
      'hash':      theHash,
      'href':      url + '#L' + entry.getLineNumber(),
      'member':    member,
      'separator': getSeparator(entry)
    }));

    markdown.push('');

    // description
    markdown.push(entry.getDesc());
    markdown.push('');

    // function parameters (optional)
    var params = entry.getParams();
    if (params.length) {
      markdown.push('#### Arguments');
      _.each(function(param, index) {
        markdown.push(
          interpolate('${num}. `${name}` (${type}): ${desc}', {
            'desc': escape(param[2]),
            'name': param[1],
            'num':  index + 1,
            'type': escape(param[0])
          })
        );
      });
      markdown.push('');
    }
    // functions returns (optional)
    var returns = entry.getReturns();
    if (returns.length) {
      markdown.push('#### Returns');
      markdown.push(
        interpolate('(${type}): ${desc}', {
          'desc': escape(returns[1]),
          'type': escape(returns[0])
        })
      );
      markdown.push('');
    }
    // function example (optional)
    var example = entry.getExample();
    if (example) {
      markdown.push('#### Example', example);
    }
    // tail
    markdown.push('\n* * *\n');
    markdown.push('\n\n');

    entry.markdown = markdown.join('\n');
  });

  // Table of Contents headers.
  tocGroups = Object.keys(organizedEntries);

  if (byCategories) {
    // Remove special categories.
    var args = [tocGroups];
    args.push.apply(args, specialCategories);
    _.pull.apply(_, args);
    // Sort categories and append special categories.
    tocGroups.sort(utils.compareNatural);
    tocGroups.push.apply(tocGroups, specialCategories);
  } else {
    tocGroups.sort(utils.compareNatural);
  }

  _.each(tocGroups, function(group) {
    //toc category head
    indexMarkdown.push(
      '\n',
      '## ' +
      makeHashHTML(group.toLowerCase(),
        'id'
      ) +
      '`' + group + '`'
    );

    //sort the groups
    organizedEntries[group].sort(function(a, b) {
      var result = utils.compareNatural(
        a.isAlias() ? a.getName() : a.getCall(),
        b.isAlias() ? b.getName() : b.getCall()
      );
      return result;
    });

    // entries for each category
    _.each(organizedEntries[group], function(anIndexEntry) {
      if (anIndexEntry.isAlias()) {
        //alias has a more complex html structure
        indexMarkdown.push(
          '* ' +
          escape(
            anIndexEntry.getMembers(0) +
            getSeparator(anIndexEntry) +
            anIndexEntry.getName()
          ) +
          ' -> ' + anIndexEntry.getOwner().getName() +
          ''
        );
      } else {
        // simple toc entry
        indexMarkdown.push(
          '* ' +
          makeHashHTML(
            '#' + anIndexEntry.theHash,
            'href',
            escape(
              (anIndexEntry.getMembers(0) ? (anIndexEntry.getMembers(0) + getSeparator(anIndexEntry))  : '') +
              anIndexEntry.getName()
            )
          )
        );
      }
    });
  });

  // wrapup toc section
  indexMarkdown.push('\n\n')
  output += indexMarkdown.join('\n');

  _.each(tocGroups, function(group) {
    output += '\n\n';
    if (byCategories && !reSpecialCategory.test(group)) {
      var groupName = '“' + group + '” Methods';
    }
    output += '## `' + (groupName || group) + '` \n';
    _.each(organizedEntries[group], function(entry) {
      if (entry.markdown) {
        output += entry.markdown;
      }
    });
   output += '\n\n\n';
  });

  // back to top
  output += ' [1]: #' + tocGroups[0].toLowerCase() + ' "Jump back to the TOC."\n';

  return output;
}

module.exports = generateDoc;
<commit_msg>Simplify TOC creation<commit_after>'use strict';

var _ = require('lodash'),
    Entry = require('./entry.js'),
    getEntries =  Entry.getEntries,
    utils = require('./utils.js');

var specialCategories = ['Methods', 'Properties'];
var reSpecialCategory = RegExp('^(?:' + specialCategories.join('|') + ')$');

/**
 * Escape special Markdown characters in a string.
 *
 * @param {string} str The string to escape.
 * @returns {string} The escaped string.
 */
function escape(str) {
  // replace all code snippets with a token
  var snippets = [];
  str = str.replace(/`.*?`/g, function(match) {
    snippets.push(match);
    return '@@token@@';
  });

  _.forOwn({
    '*': '*',
    '[': '[',
    ']': ']',
  }, function(replacement, char) {
    str = str.replace(RegExp('(\\\\?)\\' + char, 'g'), function(match, backslash) {
      if (backslash) {
        return match;
      }
      return replacement;
    });
  });

  // replace all tokens with code snippets
  str = str.replace(/@@token@@/g, function(match) {
    return snippets.shift();
  });
  return str;
}

/**
 * Make a anchor link
 *
 * @param {string} Value assigned by attr
 * @param {string} Attr name (id, href)
 * @param {string} contents of element, 'toc' is required
 *
 */
function makeHashHTML(attrValue, attr, contents) {
  contents || (contents = '');
  return '' +
    contents +
    '';
}

/**
 * Performs common string formatting operations.
 *
 * @private
 * @param {string} string The string to format.
 * @returns {string} The formatted string.
 */
function format(string) {
  // replace all code snippets with a token
  var snippets = [];
  string = string.replace(/`.*?`/g, function(match) {
    snippets.push(match);
    return '@@token@@';
  });

  string = string
    // italicize parentheses
    .replace(/(^|\s)(\([^)]+\))/g, '$1*$2*')
    // mark numbers as inline code
    .replace(/[\t ](-?\d+(?:.\d+)?)(?!\.[^\n])/g, ' `$1`');

  // replace all tokens with code snippets
  string = string.replace(/@@token@@/g, function(match) {
    return snippets.shift();
  });
  return string.trim();
}

/**
 * Get the seperator (. or .prototype.)
 *
 * @param {Entry} Entry object to get selector for
 *
 */
function getSeparator(entry) {
  return entry.isPlugin() ? '.prototype.' : '.';
}

/**
 * Modify a string by replacing named tokens with matching associated object values.
 *
 * @private
 * @param {string} string The string to modify.
 * @param {Object} object The template object.
 * @returns {string} The modified string.
 */
function interpolate(string, object) {
  return format(
    _.template(string)(object)
  );
}

/**
 * Generates the documentation from JS source.
 *
 * @param {string} The source code to generate the documentation for.
 * @param {object} The options object.
 *
 */
function generateDoc(source, options) {
  var url = options.url,
      entries = getEntries(source),
      api = [],
      byCategories = options.toc == 'categories',
      organizedEntries = {},
      categories,
      members = {},
      indexMarkdown = [],
      tocGroups,
      output = '# '+ options.title + '\n\n';

    // add entries and aliases to the API list
  _.each(entries, function(entry) {
    entry = new Entry(entry, source);
    api.push(entry);

    var aliases = entry.getAliases();
    if (aliases) {
      api.push.apply(api, aliases);
    }
  });

  // build the list of categories for the TOC
  // and generate content for each entry
  _.each(api, function(entry) {
    var name = entry.getName();
    // exit early if entry is private or has no name
    if (entry.isPrivate() || !name) {
      return;
    }
    var members = entry.getMembers();
    members.length || (members = ['']);
    var member = members[0];
    var memberGroup;

    if (
      !member ||
      entry.isCtor() ||
      (entry.getType() == 'Object' &&
        !/[=:]\s*(?:null|undefined)\s*[,;]?$/gi.test(entry.entry))
    ) {
      memberGroup = (member ? member + getSeparator(entry) : '') + name;
    } else if (entry.isStatic()) {
      memberGroup = member;
    } else if (!entry.isCtor()) {
      memberGroup = member + getSeparator(entry).slice(0,-1);
    }
    // add entry to TOC
    var tocGroup;
    if (byCategories) {
      var category = entry.getCategory();
      tocGroup = organizedEntries[category] || (organizedEntries[category] = []);
      tocGroup.push(entry);
    } else {
      tocGroup = organizedEntries[memberGroup] || (organizedEntries[memberGroup] = []);
      tocGroup.push(entry);
    }
    // generate description of entry
    // aliases don't get a description
    if (entry.isAlias()) {
      return;
    }

    var markdown = [];
    // start
    markdown.push('\n');

    // heading
    var theHash = member + entry.getHash();
    entry.theHash = theHash;

    markdown.push(interpolate([
      '### `${member}${separator}${call}`\n',
      '# ',
      '[Ⓢ](${href} "View in source") ',
      '[Ⓣ][1]'
    ].join(''), {
      'call':      entry.getCall(),
      'hash':      theHash,
      'href':      url + '#L' + entry.getLineNumber(),
      'member':    member,
      'separator': getSeparator(entry)
    }));

    markdown.push('');

    // description
    markdown.push(entry.getDesc());
    markdown.push('');

    // function parameters (optional)
    var params = entry.getParams();
    if (params.length) {
      markdown.push('#### Arguments');
      _.each(function(param, index) {
        markdown.push(
          interpolate('${num}. `${name}` (${type}): ${desc}', {
            'desc': escape(param[2]),
            'name': param[1],
            'num':  index + 1,
            'type': escape(param[0])
          })
        );
      });
      markdown.push('');
    }
    // functions returns (optional)
    var returns = entry.getReturns();
    if (returns.length) {
      markdown.push('#### Returns');
      markdown.push(
        interpolate('(${type}): ${desc}', {
          'desc': escape(returns[1]),
          'type': escape(returns[0])
        })
      );
      markdown.push('');
    }
    // function example (optional)
    var example = entry.getExample();
    if (example) {
      markdown.push('#### Example', example);
    }
    // tail
    markdown.push('\n* * *\n');
    markdown.push('\n\n');

    entry.markdown = markdown.join('\n');
  });

  // Table of Contents headers.
  tocGroups = Object.keys(organizedEntries);

  if (byCategories) {
    // Remove special categories.
    var args = [tocGroups];
    args.push.apply(args, specialCategories);
    _.pull.apply(_, args);
    // Sort categories and append special categories.
    tocGroups.sort(utils.compareNatural);
    tocGroups.push.apply(tocGroups, specialCategories);
  } else {
    tocGroups.sort(utils.compareNatural);
  }

  _.each(tocGroups, function(group) {
    //toc category head
    indexMarkdown.push(
      '\n',
      '## ' +
      makeHashHTML(group.toLowerCase(),
        'id'
      ) +
      '`' + group + '`'
    );

    //sort the groups
    organizedEntries[group].sort(function(a, b) {
      var result = utils.compareNatural(
        a.isAlias() ? a.getName() : a.getCall(),
        b.isAlias() ? b.getName() : b.getCall()
      );
      return result;
    });

    // entries for each category
    _.each(organizedEntries[group], function(anIndexEntry) {
      if (anIndexEntry.isAlias()) {
        //alias has a more complex html structure
        indexMarkdown.push(
          '* ' +
          escape(
            anIndexEntry.getMembers(0) +
            getSeparator(anIndexEntry) +
            anIndexEntry.getName()
          ) +
          ' -> ' + anIndexEntry.getOwner().getName() +
          ''
        );
      } else {
        // simple toc entry
        indexMarkdown.push(
          '* ' +
          makeHashHTML(
            '#' + anIndexEntry.theHash,
            'href',
            escape(
              (anIndexEntry.getMembers(0) ? (anIndexEntry.getMembers(0) + getSeparator(anIndexEntry))  : '') +
              anIndexEntry.getName()
            )
          )
        );
      }
    });
  });

  // wrapup toc section
  indexMarkdown.push('\n\n')
  output += indexMarkdown.join('\n');

  _.each(tocGroups, function(group) {
    output += '\n\n';
    if (byCategories && !reSpecialCategory.test(group)) {
      var groupName = '“' + group + '” Methods';
    }
    output += '## `' + (groupName || group) + '` \n';
    _.each(organizedEntries[group], function(entry) {
      if (entry.markdown) {
        output += entry.markdown;
      }
    });
   output += '\n\n\n';
  });

  // back to top
  output += ' [1]: #' + tocGroups[0].toLowerCase() + ' "Jump back to the TOC."\n';

  return output;
}

module.exports = generateDoc;
<|endoftext|>


<commit_before>'use strict';

var pagination = require('hexo-pagination');
var multilingual = require('hexo-multilingual');
var _ = require('lodash');

module.exports = function(locals) {
  var context = this;
  var config = context.config;
  var result = [];

  function _c(value, lang) {
    return multilingual.util._c(value, lang, config, locals);
  }

  function generate(path, posts, perPage, paginationDir, options) {
    options = options || {};
    options.archive = true;

    result = result.concat(pagination(path, posts, {
      perPage: perPage,
      layout: ['archive', 'index'],
      format: paginationDir + '/%d/',
      data: options
    }));
  }

  _.forEach(config.language, function(lang) {
    if (lang != 'default') {
      var archiveDir = lang + '/' + _c('archive_dir', lang);
      var paginationDir = _c('pagination_dir', lang) || 'page';
      var languagePosts = locals.posts.sort('-date').filter(function(post) {
        return post.lang == lang;
      });
      var perPage = _c('archive_generator.per_page', lang);

      if (!languagePosts.length) return;

      if (archiveDir[archiveDir.length - 1] !== '/') archiveDir += '/';

      generate(archiveDir, languagePosts, perPage, paginationDir, {
        lang: lang
      });

      if (!_c('archive_generator.yearly', lang, config, locals)) return;

      var posts = {};

      // Organize posts by date
      languagePosts.forEach(function(post) {
        var date = post.date;
        var year = date.year();
        var month = date.month() + 1; // month is started from 0

        if (!posts.hasOwnProperty(year)) {
          // 13 arrays. The first array is for posts in this year
          // and the other arrays is for posts in this month
          posts[year] = [
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            []
          ];
        }

        posts[year][0].push(post);
        posts[year][month].push(post);
      });

      var Query = context.model('Post').Query;
      var years = Object.keys(posts);
      var year, data, month, monthData, url;

      // Yearly
      for (var i = 0, len = years.length; i < len; i++) {
        year = +years[i];
        data = posts[year];
        url = archiveDir + year + '/';
        if (!data[0].length) continue;

        generate(url, new Query(data[0]), perPage, paginationDir, {
          lang: lang,
          year: year
        });

        if (!_c('archive_generator.monthly', lang)) continue;

        // Monthly
        for (month = 1; month <= 12; month++) {
          monthData = data[month];
          if (!monthData.length) continue;

          generate(url + (month < 10 ? '0' + month : month) + '/', new Query(monthData), perPage, paginationDir, {
            lang: lang,
            year: year,
            month: month
          });
        }
      }

    }
  });

  return result;
};
<commit_msg>Add simple alternatives<commit_after>'use strict';

var pagination = require('hexo-pagination');
var multilingual = require('hexo-multilingual');
var _ = require('lodash');

module.exports = function(locals) {
  var context = this;
  var config = context.config;
  var result = [];

  function _c(value, lang) {
    return multilingual.util._c(value, lang, config, locals);
  }

  function generate(path, posts, perPage, paginationDir, options) {
    options = options || {};
    options.archive = true;

    result = result.concat(pagination(path, posts, {
      perPage: perPage,
      layout: ['archive', 'index'],
      format: paginationDir + '/%d/',
      data: options
    }));
  }

  function getAlternates() {
    var result = [];
    _.each(config.language, function(lang) {
      if (lang != 'default') {
        var path = lang + '/' + _c('archive_dir', lang);
        result.push({
          title: _c('title', lang, config, locals),
          lang: lang,
          path: path
        });
      }
    });
    return result;
  }

  _.forEach(config.language, function(lang) {
    if (lang != 'default') {
      var archiveDir = lang + '/' + _c('archive_dir', lang);
      var paginationDir = _c('pagination_dir', lang) || 'page';
      var languagePosts = locals.posts.sort('-date').filter(function(post) {
        return post.lang == lang;
      });
      var perPage = _c('archive_generator.per_page', lang);

      if (!languagePosts.length) return;

      if (archiveDir[archiveDir.length - 1] !== '/') archiveDir += '/';

      generate(archiveDir, languagePosts, perPage, paginationDir, {
        lang: lang,
        alternates: getAlternates()
      });

      if (!_c('archive_generator.yearly', lang, config, locals)) return;

      var posts = {};

      // Organize posts by date
      languagePosts.forEach(function(post) {
        var date = post.date;
        var year = date.year();
        var month = date.month() + 1; // month is started from 0

        if (!posts.hasOwnProperty(year)) {
          // 13 arrays. The first array is for posts in this year
          // and the other arrays is for posts in this month
          posts[year] = [
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            [],
            []
          ];
        }

        posts[year][0].push(post);
        posts[year][month].push(post);
      });

      var Query = context.model('Post').Query;
      var years = Object.keys(posts);
      var year, data, month, monthData, url;

      // Yearly
      for (var i = 0, len = years.length; i < len; i++) {
        year = +years[i];
        data = posts[year];
        url = archiveDir + year + '/';
        if (!data[0].length) continue;

        generate(url, new Query(data[0]), perPage, paginationDir, {
          lang: lang,
          year: year,
          alternates: getAlternates()
        });

        if (!_c('archive_generator.monthly', lang)) continue;

        // Monthly
        for (month = 1; month <= 12; month++) {
          monthData = data[month];
          if (!monthData.length) continue;

          generate(url + (month < 10 ? '0' + month : month) + '/', new Query(monthData), perPage, paginationDir, {
            lang: lang,
            year: year,
            month: month,
            alternates: getAlternates()
          });
        }
      }

    }
  });

  return result;
};
<|endoftext|>


<commit_before>var _ = require('underscore'),
    EventEmitter = require('events').EventEmitter;
    fs = require('fs'),
    path = require('path');

var generator = new EventEmitter();

generator.generate = function(options) {

    var overwrite = options.overwrite === true ? true : false,
        sourceDirectory = options.source,
        outputDirectory = options.output,
        template = options.template ?
            options.template : __dirname + "/templates/bdd.tpl";

    if (sourceDirectory.indexOf("/") !== 0) {
        sourceDirectory = process.cwd() + "/" + sourceDirectory;
    }

    if (outputDirectory.indexOf("/") !== 0) {
        outputDirectory = process.cwd() + "/" + outputDirectory;
    }

    if (!outputDirectory.match("/$")) {
        outputDirectory = outputDirectory + "/";
    }

    if (!path.existsSync(sourceDirectory)) {
        console.error("Source directory " + sourceDirectory + " does not exist!");
        console.log("Quitting..");
        return;
    }

    this.overwrite = overwrite;
    this.source = sourceDirectory;
    this.fileList = [];
    this.template = _.template(fs.readFileSync(template, 'ascii'));

    this.compileFileList();

    if (!path.existsSync(outputDirectory)) {
        fs.mkdirSync(outputDirectory);
    }

    var that = this;

    _.each(this.fileList, function(modulePath) {
        var module = require(modulePath);

        var test = {
            path : modulePath.replace(sourceDirectory, outputDirectory),
            name : modulePath,
            methods : []
        };

        for (property in module) {
            if (typeof module[property] === "function") {
                test.methods.push(property);
            }
        };

        that.writeTest(test);

    });

    this.emit('done');

};

generator.writeTest = function(test) {

    var pathParts = test.path.split("/"),
        currentDir = "";
    pathParts.pop();
    _.each(pathParts, function(dir) {
        currentDir = currentDir + dir + "/";
        if (!path.existsSync(currentDir)) {
            console.log("Directory " + currentDir + " does not exist, creating..");
            fs.mkdirSync(currentDir);
        }
    });

    if (path.existsSync(test.path) && !this.overwrite) {
        console.log("Test " + test.path + " already exists, use --overwrite if you know what you are doing..");
    } else {
        console.log("Writing test " + test.path + "...");
        fs.writeFileSync(test.path, this.template(test));

    }

};

generator.compileFileList = function(parent) {

    parent = parent ? parent : this.source;
    if (!parent.match("/$")) {
        parent = parent + "/";
    }
    var that = this;

    var fsObjects = fs.readdirSync(parent);

    _.each(fsObjects, function(fsObject) {
        var path = parent + fsObject,
            stats = fs.lstatSync(path);
        if (stats.isDirectory()) {
            generator.compileFileList(path);
        } else if (stats.isFile()) {
            that.fileList.push(path);
        }
    });

};

module.exports = generator;<commit_msg>Only consider js files..<commit_after>var _ = require('underscore'),
    EventEmitter = require('events').EventEmitter;
    fs = require('fs'),
    path = require('path');

var generator = new EventEmitter();

generator.generate = function(options) {

    var overwrite = options.overwrite === true ? true : false,
        sourceDirectory = options.source,
        outputDirectory = options.output,
        template = options.template ?
            options.template : __dirname + "/templates/bdd.tpl";

    if (sourceDirectory.indexOf("/") !== 0) {
        sourceDirectory = process.cwd() + "/" + sourceDirectory;
    }

    if (outputDirectory.indexOf("/") !== 0) {
        outputDirectory = process.cwd() + "/" + outputDirectory;
    }

    if (!outputDirectory.match("/$")) {
        outputDirectory = outputDirectory + "/";
    }

    if (!path.existsSync(sourceDirectory)) {
        console.error("Source directory " + sourceDirectory + " does not exist!");
        console.log("Quitting..");
        return;
    }

    this.overwrite = overwrite;
    this.source = sourceDirectory;
    this.fileList = [];
    this.template = _.template(fs.readFileSync(template, 'ascii'));

    this.compileFileList();

    if (!path.existsSync(outputDirectory)) {
        fs.mkdirSync(outputDirectory);
    }

    var that = this;

    _.each(this.fileList, function(modulePath) {
        var module = require(modulePath);

        var test = {
            path : modulePath.replace(sourceDirectory, outputDirectory),
            name : modulePath,
            methods : []
        };

        for (property in module) {
            if (typeof module[property] === "function") {
                test.methods.push(property);
            }
        };

        if (test.methods.length === 0) {
            console.log("Skipping this module because it has no exports..");
            return;
        }

        that.writeTest(test);

    });

    this.emit('done');

};

generator.writeTest = function(test) {

    var pathParts = test.path.split("/"),
        currentDir = "";
    pathParts.pop();
    _.each(pathParts, function(dir) {
        currentDir = currentDir + dir + "/";
        if (!path.existsSync(currentDir)) {
            console.log("Directory " + currentDir + " does not exist, creating..");
            fs.mkdirSync(currentDir);
        }
    });

    if (path.existsSync(test.path) && !this.overwrite) {
        console.log("Test " + test.path + " already exists, use --overwrite if you know what you are doing..");
    } else {
        console.log("Writing test " + test.path + "...");
        fs.writeFileSync(test.path, this.template(test));

    }

};

generator.compileFileList = function(parent) {

    parent = parent ? parent : this.source;
    if (!parent.match("/$")) {
        parent = parent + "/";
    }
    var that = this;

    var fsObjects = fs.readdirSync(parent);

    _.each(fsObjects, function(fsObject) {
        var path = parent + fsObject,
            stats = fs.lstatSync(path);
        if (stats.isDirectory()) {
            generator.compileFileList(path);
        } else if (stats.isFile()) {
            //check if extension is js
            var indx = fsObject.lastIndexOf('.'),
            extension = (indx < 0) ? '' : fsObject.substr(indx);
            if (extension === ".js") {
                that.fileList.push(path);
            }
        }
    });

};

module.exports = generator;<|endoftext|>


<commit_before>'use strict';

var nunjucks = require('nunjucks');
var env = new nunjucks.Environment();
var pathFn = require('path');
var fs = require('fs');
var gravatar = require('hexo/lib/plugins/helper/gravatar');

env.addFilter('uriencode', function(str) {
  return encodeURI(str);
});

env.addFilter('noControlChars', function(str) {
  return str.replace(/[\x00-\x1F\x7F]/g, '');
});

var atomTmplSrc = pathFn.join(__dirname, '../atom.xml');
var atomTmpl = nunjucks.compile(fs.readFileSync(atomTmplSrc, 'utf8'), env);
var rss2TmplSrc = pathFn.join(__dirname, '../rss2.xml');
var rss2Tmpl = nunjucks.compile(fs.readFileSync(rss2TmplSrc, 'utf8'), env);

module.exports = function(locals) {
  var config = this.config;
  var feedConfig = config.feed;
  var template = feedConfig.type === 'rss2' ? rss2Tmpl : atomTmpl;

  var posts = locals.posts.sort(feedConfig.order_by);
  posts = posts.filter(function(post) {
    return post.draft !== true;
  });

  if (feedConfig.limit) posts = posts.limit(feedConfig.limit || '-date');

  var url = config.url;
  if (url[url.length - 1] !== '/') url += '/';

  var icon;
  if (config.email) icon = gravatar(config.email);

  var xml = template.render({
    config: config,
    url: url,
    icon: icon,
    posts: posts,
    feed_url: config.root + feedConfig.path
  });

  return {
    path: feedConfig.path,
    data: xml
  };
};
<commit_msg>Update generator.js<commit_after>'use strict';

var nunjucks = require('nunjucks');
var env = new nunjucks.Environment();
var pathFn = require('path');
var fs = require('fs');
var gravatar = require('hexo/lib/plugins/helper/gravatar');

env.addFilter('uriencode', function(str) {
  return encodeURI(str);
});

env.addFilter('noControlChars', function(str) {
  return str.replace(/[\x00-\x1F\x7F]/g, '');
});

var atomTmplSrc = pathFn.join(__dirname, '../atom.xml');
var atomTmpl = nunjucks.compile(fs.readFileSync(atomTmplSrc, 'utf8'), env);
var rss2TmplSrc = pathFn.join(__dirname, '../rss2.xml');
var rss2Tmpl = nunjucks.compile(fs.readFileSync(rss2TmplSrc, 'utf8'), env);

module.exports = function(locals) {
  var config = this.config;
  var feedConfig = config.feed;
  var template = feedConfig.type === 'rss2' ? rss2Tmpl : atomTmpl;

  var posts = locals.posts.sort(feedConfig.order_by || '-date');
  posts = posts.filter(function(post) {
    return post.draft !== true;
  });

  if (feedConfig.limit) posts = posts.limit(feedConfig.limit);

  var url = config.url;
  if (url[url.length - 1] !== '/') url += '/';

  var icon;
  if (config.email) icon = gravatar(config.email);

  var xml = template.render({
    config: config,
    url: url,
    icon: icon,
    posts: posts,
    feed_url: config.root + feedConfig.path
  });

  return {
    path: feedConfig.path,
    data: xml
  };
};
<|endoftext|>


<commit_before>const fetch = require('node-fetch');
const fs = require('fs');
require('chromedriver'); // add chromedriver from this package to the PATH
const chrome = require('selenium-webdriver/chrome');
const webdriver = require('selenium-webdriver');
const moment = require('moment');

const alphavantageKey = fs.readFileSync('alpha_vantage_key.txt', 'utf8').trim();
const alphavantageSleep = 20000;

function sleep(ms) {
  return new Promise(resolve => setTimeout(() => resolve(), ms));
}

function aequitas(rows) {
  if (rows.length === 0) {
    return Promise.resolve([]);
  }
  const baseUri = 'https://www.aequitasneo.com/en/single-security';
  const driver = new webdriver.Builder()
    .forBrowser('chrome')
    .setChromeOptions(new chrome.Options().headless(true))
    .build();

  // There are two prices for the stock, one is LIT and the other is NEO.
  // Not sure what one I want, so using the default shown on the page, LIT.
  // https://aequitasneoexchange.com/en/trading/trading-solutions/lit-book/
  // https://aequitasneoexchange.com/en/trading/trading-solutions/neo-book/
  return rows
    .reduce(async (acc, row, idx) => {
      const accRows = await acc;
      const r = row;
      await driver
        .get(`${baseUri}/${r.symbol}`)
        .then(() => sleep(1000))
        .then(() =>
          driver.executeScript(
            "return document.querySelector('#security-summary-table tr td:nth-child(2)').innerText"
          )
        )
        .then(text => {
          r.price = text.replace(/\$/, '');
        })
        .catch(e => {
          r.err = e.toString().trim();
        })
        .then(() => {
          // don't need to sleep after the last row
          if (idx + 1 < rows.length) {
            return sleep(3000);
          }
          return Promise.resolve();
        });
      accRows.push(r);
      return accRows;
    }, Promise.resolve([]))
    .then(prices => driver.quit().then(() => prices));
}

function alphavantage(rows) {
  if (rows.length === 0) {
    return Promise.resolve([]);
  }

  const baseUri =
    'https://www.alphavantage.co/query?' +
    'function=GLOBAL_QUOTE' +
    `&apikey=${alphavantageKey}` +
    '&symbol=';

  const promises = rows.map(row => {
    let jsonKeys;
    const r = row;
    return fetch(baseUri + row.symbol)
      .then(res => res.json())
      .then(json => {
        jsonKeys = Object.keys(json).join(',');
        const gq = json['Global Quote'];
        if (!gq) {
          r.price = '';
          if (json.Note) {
            r.err = json.Note;
          }
          return;
        }
        if (moment().format('YYYY-MM-DD') === gq['07. latest trading day']) {
          const price = gq['05. price'];
          r.price = price || '';
          return;
        }
        r.err = 'latest trading day is not today';
      })
      .catch(err => {
        r.err = `${err.toString().trim()} - [keys in resp:${jsonKeys}]`;
      })
      .then(() => r);
  });
  return promises.reduce(async (acc, p, idx) => {
    const prices = await acc;
    prices.push(await p);
    // don't need to sleep on the last element
    if (idx + 1 < promises.length) {
      await sleep(alphavantageSleep);
    }
    return prices;
  }, []);
}

module.exports = {
  aequitas,
  alphavantage,
};
<commit_msg>Don't queue all the fetchs and wait for them; run each serially, so as not to hit the free api limit<commit_after>const fetch = require('node-fetch');
const fs = require('fs');
require('chromedriver'); // add chromedriver from this package to the PATH
const chrome = require('selenium-webdriver/chrome');
const webdriver = require('selenium-webdriver');
const moment = require('moment');

const alphavantageKey = fs.readFileSync('alpha_vantage_key.txt', 'utf8').trim();
const alphavantageSleep = 61000 / 5; // free api limit is 5 per minute

function sleep(ms) {
  return new Promise(resolve => setTimeout(() => resolve(), ms));
}

function aequitas(rows) {
  if (rows.length === 0) {
    return Promise.resolve([]);
  }
  const baseUri = 'https://www.aequitasneo.com/en/single-security';
  const driver = new webdriver.Builder()
    .forBrowser('chrome')
    .setChromeOptions(new chrome.Options().headless(true))
    .build();

  // There are two prices for the stock, one is LIT and the other is NEO.
  // Not sure what one I want, so using the default shown on the page, LIT.
  // https://aequitasneoexchange.com/en/trading/trading-solutions/lit-book/
  // https://aequitasneoexchange.com/en/trading/trading-solutions/neo-book/
  return rows
    .reduce(async (acc, row, idx) => {
      const accRows = await acc;
      const r = row;
      await driver
        .get(`${baseUri}/${r.symbol}`)
        .then(() => sleep(1000))
        .then(() =>
          driver.executeScript(
            "return document.querySelector('#security-summary-table tr td:nth-child(2)').innerText"
          )
        )
        .then(text => {
          r.price = text.replace(/\$/, '');
        })
        .catch(e => {
          r.err = e.toString().trim();
        })
        .then(() => {
          // don't need to sleep after the last row
          if (idx + 1 < rows.length) {
            return sleep(3000);
          }
          return Promise.resolve();
        });
      accRows.push(r);
      return accRows;
    }, Promise.resolve([]))
    .then(prices => driver.quit().then(() => prices));
}

function alphavantage(rows) {
  if (rows.length === 0) {
    return Promise.resolve([]);
  }

  return rows.reduce(async (acc, row, idx) => {
    const prices = await acc;
    prices.push(await alphavantageFetch(row));
    // don't need to sleep on the last element
    if (idx + 1 < rows.length) {
      await sleep(alphavantageSleep);
    }
    return prices;
  }, []);
}

async function alphavantageFetch(row) {
  const baseUri =
    'https://www.alphavantage.co/query?' +
    'function=GLOBAL_QUOTE' +
    `&apikey=${alphavantageKey}` +
    '&symbol=';

  let jsonKeys;
  const r = row;
  return fetch(baseUri + row.symbol)
    .then(res => res.json())
    .then(json => {
      jsonKeys = Object.keys(json).join(',');
      const gq = json['Global Quote'];
      if (!gq) {
        r.price = '';
        if (json.Note) {
          r.err = json.Note;
        }
        return;
      }
      if (moment().format('YYYY-MM-DD') === gq['07. latest trading day']) {
        const price = gq['05. price'];
        r.price = price || '';
        return;
      }
      r.err = 'latest trading day is not today';
    })
    .catch(err => {
      r.err = `${err.toString().trim()} - [keys in resp:${jsonKeys}]`;
    })
    .then(() => r);
}

module.exports = {
  aequitas,
  alphavantage,
};
<|endoftext|>


<commit_before>/**
 * This kind provide a widget to tune project properties
 *
 * By default, this widget is tuned for project modification.  In case
 * of project *creation*, the method setupCreate must be called after
 * construction. Since the widget is re-used between call for creation
 * or modification, the methos setupModif must be called also.
 */

enyo.kind({
	name: "ProjectProperties",
	classes: "enyo-unselectable",
	fit: true,
	events: {
		onModifiedConfig: "",
		onSaveGeneratedXml: "",
		onDone: ""
	},
	createMode: true,

	components: [
		{kind: "onyx.RadioGroup", onActivate: "switchDrawers", name: "thumbnail", components: [
			{content: "Project", serviceId: "project", active: true, attributes: {title: 'project attributes...'}},
			{content: "Preview", serviceId: "preview", attributes: {title: 'project preview parameters...'}}
		]},
		{name: "projectDrawer", kind: "onyx.Drawer", open:true, components: [
			{tag: 'table', components: [
				{tag: "tr" , components: [
					 {tag: "td" , content: "Name: "},
					 {tag: 'td', components:[
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", defaultFocus: true, name: "projectName"}
						  ]}
					 ]},
					 {tag: 'td', content: "Title: "},
					 {tag: "td" , components: [
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", defaultFocus: true, name: "projectTitle"}
						   ]}
					  ]}
				]},
				{tag: "tr" , components: [
					 {tag: "td" , content: "Version: "},
					 {tag: 'td', components:[
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", defaultFocus: true, name: "projectVersion"}
						  ]}
					 ]},
					 {tag: 'td', content: "Id: "},
					 {tag: "td" , components: [
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", defaultFocus: true, name: "projectId",
								attributes: {title: "Application ID in reverse domain-name format: com.example.apps.myapp"}}
						   ]}
					  ]}
				]},
				{tag: "tr" , components: [
					 {tag: "td" , content: "Author name: "},
					 {tag: 'td', attributes: {colspan: 1}, components:[
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", name: "projectAuthor",
								attributes: {title: "Vendor / Committer Name"}
							   }
						   ]}
					 ]},
					 {tag: "td" , content: "Contact: "},
					 {tag: 'td', attributes: {colspan: 2}, components:[
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", name: "projectContact",
								attributes: {title: "mail address or home page of the author"}
							   }
						   ]}
					 ]}
				]},
				{tag: "tr" , name:'directoryEntry', canGenerate:false, components: [
					 {tag: "td", content: "Directory: "},
					 {tag: 'td', attributes: {colspan: 3}, content: "", name: "projectDirectory" }
				]}
			]},
			{kind: "enyo.FittableColumns", name: "servicesList"},
			{kind: "enyo.FittableColumns", components: [
				{kind: "Control", content: "Template:"},
				{kind: "onyx.PickerDecorator", fit: true, components: [
					{name: "templateButton", kind: "onyx.PickerButton", fit: true},
					{kind: "onyx.FlyweightPicker", name: "templatePicker", components: [
						{name: "template"}
					], onSetupItem: "templateSetupItem", onSelect: "templateSelected"}
				]}
			]}
		]},

		{name: "previewDrawer", kind: "onyx.Drawer", open: false, components: [
			{tag: 'table', components: [
				{tag: "tr" , components: [
					{tag: "td" , content: "top application file: "},
					{tag: 'td', attributes: {colspan: 1}, components:[
						{kind: "onyx.InputDecorator", components: [
							{kind: "Input", name: "ppTopFile",
							attributes: {title: 'top file of your application. Typically index.html'}
							}
						]}
					]}
				]}
			]}
		]},

		// FIXME: there should be an HTML/CSS way to avoid using FittableStuff...
		{kind: "FittableRows", style: "margin-top: 10px; width: 100%", fit: true, components: [
			{kind: "onyx.Button", classes: "onyx-negative", content: "Cancel", ontap: "doDone"},
			{name: "ok", kind: "onyx.Button", classes: "onyx-affirmative", content: "OK", ontap: "confirmTap"}
		]},

		{kind: "Ares.ErrorPopup", name: "errorPopup", msg: "unknown error"},
		{kind: "Signals", onServicesChange: "handleServicesChange"}
	],

	debug: false,
	templates: [],
	TEMPLATE_NONE: "NONE",
	selectedTemplate: undefined,

	services: {},

	/**
	 * Receive the {onServicesChange} broadcast notification
	 * @param {Object} inEvent.serviceRegistry
	 */
	handleServicesChange: function(inSender, inEvent) {
		if (this.debug) this.log();
		this.services = this.services || {};
		inEvent.serviceRegistry.forEach(enyo.bind(this, function(inService) {
			var service = {
				id: inService.id,
				name: inService.getName() || inService.getId(),
				kind: inService.getProjectPropertiesKind && inService.getProjectPropertiesKind()
			};
			if (this.debug) this.log("service:", service);
			if (service.kind) {
				this.services[service.id] = service;
			}
		}));
		if (this.debug) this.log("services:", this.services);
		enyo.forEach(enyo.keys(this.services), function(serviceId) {
			var service = this.services[serviceId];
			var drawer = this.$[service.id + 'Drawer'] || this.createComponent({
				name: service.id + 'Drawer',
				kind: "onyx.Drawer",
				open: false
			});
			service.panel = drawer.$[service.id] || drawer.createComponent({
				name: service.id,
				kind: service.kind
			});
			service.tab = this.$.thumbnail[service.id + 'Tab'] || this.$.thumbnail.createComponent({
				name: service.id + 'Tab',
				content: service.name,
				serviceId: service.id,
				showing: false
			});
			this.$.servicesList.createComponent({
				name: service.id + 'Frame'
			});
			if (!service.frame) {
				service.frame = this.$.servicesList.$[service.id + 'Frame'];
				service.frame.createComponent({
					tag: 'span',
					content: service.name
				});
				service.checkBox = service.frame.createComponent({
					kind: 'onyx.Checkbox',
					name: service.id + 'CheckBox',
					onchange: 'toggleService',
					serviceId: service.id
				}, {
					owner: this
				});
			}

			// Take the project configuration into account
			// to show the service or not
			this.showService(serviceId);
		}, this);
	},
	/**
	 * Toggle a service panel
	 */
	toggleService: function(inSender, inEvent) {
		var serviceId = inEvent.originator.serviceId,
		    checked = inEvent.originator.checked;
		this.log("serviceId:", serviceId, 'checked:', checked);
		var service = this.services[serviceId];
		if (service.tab) {
			service.tab.setShowing(checked);
		}
	},
	/**
	 * Tune the widget for project creation
	 */
	setupCreate: function() {
		//this.$.ok.setDisabled(true) ;
		this.$.directoryEntry.show() ;
	},

	/**
	 * Tune the widget for project modification
	 */
	setupModif: function() {
		//this.$.ok.setDisabled(true) ;
		this.$.directoryEntry.hide() ;
	},

	/**
	 * close one drawer and open the other depending on which radio button was tapped
	 */
	switchDrawers: function(inSender, inEvent) {
		if (inEvent.originator.active === true ) {
			enyo.forEach(inEvent.originator.parent.children, function(tab) {
				var activate = (tab.serviceId === inEvent.originator.serviceId);
				this.$[tab.serviceId + 'Drawer'].setOpen(activate);
			}, this);
		}
	},

	/**
	 * pre-fill the widget with configuration data
	 * @param {Object} config is configuration data (typically from project.json)
	 *  can be a json string or an object.
	 */
	preFill: function(inData) {
		this.config = typeof inData === 'object' ? inData : JSON.parse(inData) ;
		var conf = this.config ;
		var confDefault = ProjectConfig.PREFILLED_CONFIG_FOR_UI ;

		 // avoid storing 'undefined' in there
		this.$.projectId.     setValue(conf.id      || '' );
		this.$.projectVersion.setValue(conf.version || '' );
		this.$.projectName.   setValue(conf.name    || '' );
		this.$.projectTitle.  setValue(conf.title   || '' );

		if (! conf.author) { conf.author =  {} ;}
		this.$.projectAuthor. setValue(conf.author.name || '') ;
		this.$.projectContact.setValue(conf.author.href || '') ;

		// Load each builder service configuration into its
		// respective ProjectProperties panel
		enyo.forEach(enyo.keys(this.services), function(serviceId) {
			this.showService(serviceId);
		}, this);

		if (! conf.preview ) {conf.preview = {} ;}
		this.$.ppTopFile.setValue(conf.preview.top_file);

		return this ;
	},

	showService: function(serviceId) {
		var service = this.services[serviceId];
		var config = this.config && this.config.build &&
			    this.config.build[serviceId];
		var enabled = config && config.enabled;
		service.checkBox.setChecked(enabled);
		service.tab.setShowing(enabled);
		if (config) {
			service.panel.setProjectConfig(config);
		}
	},

	confirmTap: function(inSender, inEvent) {
		var tglist, ppConf ;
		// retrieve modified values

		this.config.id       = this.$.projectId     .getValue();
		this.config.version  = this.$.projectVersion.getValue();
		this.config.name     = this.$.projectName   .getValue();
		this.config.title    = this.$.projectTitle  .getValue();

		this.config.author.name = this.$.projectAuthor.getValue();
		this.config.author.href = this.$.projectContact.getValue();

		// Dump each builder service configuration panel into
		// the project configuration.
		enyo.forEach(enyo.keys(this.services), function(serviceId) {
			var service = this.services[serviceId];
			this.config.build[service.id] = service.panel.getProjectConfig();
			this.config.build[service.id].enabled = service.checkBox.checked;
		}, this);

		ppConf = this.config.preview ;
		ppConf.top_file = this.$.ppTopFile.getValue();

		// to be handled by a ProjectWizard
		this.doModifiedConfig({data: this.config, template: this.selectedTemplate}) ;

		this.doDone();

		if (inEvent.callBack) {
			inEvent.callBack() ;
		}

		// handled here (don't bubble)
		return true;
	},
	setTemplateList: function(templates) {
		this.$.templateButton.applyStyle("width", "20em");
		this.templates = [this.TEMPLATE_NONE];
		enyo.forEach(templates, function(item) {
			this.templates.push(item.id);
		}, this);
		this.$.templatePicker.setCount(this.templates.length);
		this.$.templatePicker.setSelected(0);
		this.selectedTemplate = undefined;
	},
	templateSetupItem: function(inSender, inEvent) {
		this.$.template.setContent(this.templates[inEvent.index]);
		return true;
	},
	templateSelected: function(inSender, inEvent) {
		if (inEvent.content === this.TEMPLATE_NONE) {
			this.selectedTemplate = undefined;
		} else {
			this.selectedTemplate = inEvent.content;
		}
	}
});
<commit_msg>ENYO-1783: Do not show template list while modifying properties of an existing project<commit_after>/**
 * This kind provide a widget to tune project properties
 *
 * By default, this widget is tuned for project modification.  In case
 * of project *creation*, the method setupCreate must be called after
 * construction. Since the widget is re-used between call for creation
 * or modification, the methos setupModif must be called also.
 */

enyo.kind({
	name: "ProjectProperties",
	classes: "enyo-unselectable",
	fit: true,
	events: {
		onModifiedConfig: "",
		onSaveGeneratedXml: "",
		onDone: ""
	},

	components: [
		{kind: "onyx.RadioGroup", onActivate: "switchDrawers", name: "thumbnail", components: [
			{content: "Project", serviceId: "project", active: true, attributes: {title: 'project attributes...'}},
			{content: "Preview", serviceId: "preview", attributes: {title: 'project preview parameters...'}}
		]},
		{name: "projectDrawer", kind: "onyx.Drawer", open:true, components: [
			{tag: 'table', components: [
				{tag: "tr" , components: [
					 {tag: "td" , content: "Name: "},
					 {tag: 'td', components:[
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", defaultFocus: true, name: "projectName"}
						  ]}
					 ]},
					 {tag: 'td', content: "Title: "},
					 {tag: "td" , components: [
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", defaultFocus: true, name: "projectTitle"}
						   ]}
					  ]}
				]},
				{tag: "tr" , components: [
					 {tag: "td" , content: "Version: "},
					 {tag: 'td', components:[
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", defaultFocus: true, name: "projectVersion"}
						  ]}
					 ]},
					 {tag: 'td', content: "Id: "},
					 {tag: "td" , components: [
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", defaultFocus: true, name: "projectId",
								attributes: {title: "Application ID in reverse domain-name format: com.example.apps.myapp"}}
						   ]}
					  ]}
				]},
				{tag: "tr" , components: [
					 {tag: "td" , content: "Author name: "},
					 {tag: 'td', attributes: {colspan: 1}, components:[
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", name: "projectAuthor",
								attributes: {title: "Vendor / Committer Name"}
							   }
						   ]}
					 ]},
					 {tag: "td" , content: "Contact: "},
					 {tag: 'td', attributes: {colspan: 2}, components:[
						  {kind: "onyx.InputDecorator", components: [
							   {kind: "Input", name: "projectContact",
								attributes: {title: "mail address or home page of the author"}
							   }
						   ]}
					 ]}
				]},
				{tag: "tr" , name:'directoryEntry', canGenerate:false, components: [
					 {tag: "td", content: "Directory: "},
					 {tag: 'td', attributes: {colspan: 3}, content: "", name: "projectDirectory" }
				]}
			]},
			{kind: "enyo.FittableColumns", name: "servicesList"},
			{kind: "enyo.FittableColumns", name: "templatesEntry", showing: false, components: [
				{kind: "Control", content: "Template:"},
				{kind: "onyx.PickerDecorator", fit: true, components: [
					{name: "templateButton", kind: "onyx.PickerButton", fit: true},
					{kind: "onyx.FlyweightPicker", name: "templatePicker", components: [
						{name: "template"}
					], onSetupItem: "templateSetupItem", onSelect: "templateSelected"}
				]}
			]}
		]},

		{name: "previewDrawer", kind: "onyx.Drawer", open: false, components: [
			{tag: 'table', components: [
				{tag: "tr" , components: [
					{tag: "td" , content: "top application file: "},
					{tag: 'td', attributes: {colspan: 1}, components:[
						{kind: "onyx.InputDecorator", components: [
							{kind: "Input", name: "ppTopFile",
							attributes: {title: 'top file of your application. Typically index.html'}
							}
						]}
					]}
				]}
			]}
		]},

		// FIXME: there should be an HTML/CSS way to avoid using FittableStuff...
		{kind: "FittableRows", style: "margin-top: 10px; width: 100%", fit: true, components: [
			{kind: "onyx.Button", classes: "onyx-negative", content: "Cancel", ontap: "doDone"},
			{name: "ok", kind: "onyx.Button", classes: "onyx-affirmative", content: "OK", ontap: "confirmTap"}
		]},

		{kind: "Ares.ErrorPopup", name: "errorPopup", msg: "unknown error"},
		{kind: "Signals", onServicesChange: "handleServicesChange"}
	],

	debug: false,
	templates: [],
	TEMPLATE_NONE: "NONE",
	selectedTemplate: undefined,

	services: {},

	/**
	 * Receive the {onServicesChange} broadcast notification
	 * @param {Object} inEvent.serviceRegistry
	 */
	handleServicesChange: function(inSender, inEvent) {
		if (this.debug) this.log();
		this.services = this.services || {};
		inEvent.serviceRegistry.forEach(enyo.bind(this, function(inService) {
			var service = {
				id: inService.id,
				name: inService.getName() || inService.getId(),
				kind: inService.getProjectPropertiesKind && inService.getProjectPropertiesKind()
			};
			if (this.debug) this.log("service:", service);
			if (service.kind) {
				this.services[service.id] = service;
			}
		}));
		if (this.debug) this.log("services:", this.services);
		enyo.forEach(enyo.keys(this.services), function(serviceId) {
			var service = this.services[serviceId];
			var drawer = this.$[service.id + 'Drawer'] || this.createComponent({
				name: service.id + 'Drawer',
				kind: "onyx.Drawer",
				open: false
			});
			service.panel = drawer.$[service.id] || drawer.createComponent({
				name: service.id,
				kind: service.kind
			});
			service.tab = this.$.thumbnail[service.id + 'Tab'] || this.$.thumbnail.createComponent({
				name: service.id + 'Tab',
				content: service.name,
				serviceId: service.id,
				showing: false
			});
			this.$.servicesList.createComponent({
				name: service.id + 'Frame'
			});
			if (!service.frame) {
				service.frame = this.$.servicesList.$[service.id + 'Frame'];
				service.frame.createComponent({
					tag: 'span',
					content: service.name
				});
				service.checkBox = service.frame.createComponent({
					kind: 'onyx.Checkbox',
					name: service.id + 'CheckBox',
					onchange: 'toggleService',
					serviceId: service.id
				}, {
					owner: this
				});
			}

			// Take the project configuration into account
			// to show the service or not
			this.showService(serviceId);
		}, this);
	},
	/**
	 * Toggle a service panel
	 */
	toggleService: function(inSender, inEvent) {
		var serviceId = inEvent.originator.serviceId,
		    checked = inEvent.originator.checked;
		this.log("serviceId:", serviceId, 'checked:', checked);
		var service = this.services[serviceId];
		if (service.tab) {
			service.tab.setShowing(checked);
		}
	},
	/**
	 * Tune the widget for project creation
	 */
	setupCreate: function() {
		//this.$.ok.setDisabled(true) ;
		this.$.directoryEntry.show() ;
		this.$.templatesEntry.show();
	},

	/**
	 * Tune the widget for project modification
	 */
	setupModif: function() {
		//this.$.ok.setDisabled(true) ;
		this.$.directoryEntry.hide() ;
		this.$.templatesEntry.hide();
	},

	/**
	 * close one drawer and open the other depending on which radio button was tapped
	 */
	switchDrawers: function(inSender, inEvent) {
		if (inEvent.originator.active === true ) {
			enyo.forEach(inEvent.originator.parent.children, function(tab) {
				var activate = (tab.serviceId === inEvent.originator.serviceId);
				this.$[tab.serviceId + 'Drawer'].setOpen(activate);
			}, this);
		}
	},

	/**
	 * pre-fill the widget with configuration data
	 * @param {Object} config is configuration data (typically from project.json)
	 *  can be a json string or an object.
	 */
	preFill: function(inData) {
		this.config = typeof inData === 'object' ? inData : JSON.parse(inData) ;
		var conf = this.config ;
		var confDefault = ProjectConfig.PREFILLED_CONFIG_FOR_UI ;

		 // avoid storing 'undefined' in there
		this.$.projectId.     setValue(conf.id      || '' );
		this.$.projectVersion.setValue(conf.version || '' );
		this.$.projectName.   setValue(conf.name    || '' );
		this.$.projectTitle.  setValue(conf.title   || '' );

		if (! conf.author) { conf.author =  {} ;}
		this.$.projectAuthor. setValue(conf.author.name || '') ;
		this.$.projectContact.setValue(conf.author.href || '') ;

		// Load each builder service configuration into its
		// respective ProjectProperties panel
		enyo.forEach(enyo.keys(this.services), function(serviceId) {
			this.showService(serviceId);
		}, this);

		if (! conf.preview ) {conf.preview = {} ;}
		this.$.ppTopFile.setValue(conf.preview.top_file);

		return this ;
	},

	showService: function(serviceId) {
		var service = this.services[serviceId];
		var config = this.config && this.config.build &&
			    this.config.build[serviceId];
		var enabled = config && config.enabled;
		service.checkBox.setChecked(enabled);
		service.tab.setShowing(enabled);
		if (config) {
			service.panel.setProjectConfig(config);
		}
	},

	confirmTap: function(inSender, inEvent) {
		var tglist, ppConf ;
		// retrieve modified values

		this.config.id       = this.$.projectId     .getValue();
		this.config.version  = this.$.projectVersion.getValue();
		this.config.name     = this.$.projectName   .getValue();
		this.config.title    = this.$.projectTitle  .getValue();

		this.config.author.name = this.$.projectAuthor.getValue();
		this.config.author.href = this.$.projectContact.getValue();

		// Dump each builder service configuration panel into
		// the project configuration.
		enyo.forEach(enyo.keys(this.services), function(serviceId) {
			var service = this.services[serviceId];
			this.config.build[service.id] = service.panel.getProjectConfig();
			this.config.build[service.id].enabled = service.checkBox.checked;
		}, this);

		ppConf = this.config.preview ;
		ppConf.top_file = this.$.ppTopFile.getValue();

		// to be handled by a ProjectWizard
		this.doModifiedConfig({data: this.config, template: this.selectedTemplate}) ;

		this.doDone();

		if (inEvent.callBack) {
			inEvent.callBack() ;
		}

		// handled here (don't bubble)
		return true;
	},
	setTemplateList: function(templates) {
		this.$.templateButton.applyStyle("width", "20em");
		this.templates = [this.TEMPLATE_NONE];
		enyo.forEach(templates, function(item) {
			this.templates.push(item.id);
		}, this);
		this.$.templatePicker.setCount(this.templates.length);
		this.$.templatePicker.setSelected(0);
		this.selectedTemplate = undefined;
	},
	templateSetupItem: function(inSender, inEvent) {
		this.$.template.setContent(this.templates[inEvent.index]);
		return true;
	},
	templateSelected: function(inSender, inEvent) {
		if (inEvent.content === this.TEMPLATE_NONE) {
			this.selectedTemplate = undefined;
		} else {
			this.selectedTemplate = inEvent.content;
		}
	}
});
<|endoftext|>


<commit_before>var makeHeaders = require("./make_headers");
var useragent = require("useragent");

module.exports = function(requestOrHeaders) {
	var headers = makeHeaders(requestOrHeaders);
	var uaString = headers["user-agent"] || "";
	var agent = useragent.is(uaString);

	return agent.chrome || agent.safari;
};
<commit_msg>Prevent incremental rendering in MS Edge<commit_after>var makeHeaders = require("./make_headers");
var useragent = require("useragent");

module.exports = function(requestOrHeaders) {
	var headers = makeHeaders(requestOrHeaders);
	var uaString = headers["user-agent"] || "";
	var agent = useragent.lookup(uaString);
	var browser = useragent.is(uaString);

	return agent.family !== "Edge" && (browser.chrome || browser.safari);
};
<|endoftext|>


<commit_before>require('coffee-script/register');

module.exports = require('./src');
<commit_msg>Normalize index-dev.js<commit_after>'use strict';

var path = require('path');

require('coffee-script/register');

module.exports = require(path.join(__dirname, 'src'));
<|endoftext|>


<commit_before>import React from 'react';
import {
  NativeModules,
  requireNativeComponent,
  StyleSheet,
  View,
} from 'react-native';

const { func, number, string, bool } = React.PropTypes;

const SketchManager = NativeModules.RNSketchManager || {};
const BASE_64_CODE = 'data:image/jpg;base64,';

const styles = StyleSheet.create({
  base: {
    flex: 1,
    height: 200,
  },
});

export default class Sketch extends React.Component {

  static propTypes = {
    fillColor: string,
    onReset: func,
    onUpdate: func,
    clearButtonHidden: bool,
    strokeColor: string,
    strokeThickness: number,
    style: View.propTypes.style,
  };

  static defaultProps = {
    fillColor: '#ffffff',
    onReset: () => {},
    onUpdate: () => {},
    clearButtonHidden: false,
    strokeColor: '#000000',
    strokeThickness: 1,
    style: null,
  };

  constructor(props) {
    super(props);
    this.onReset = this.onReset.bind(this);
    this.onUpdate = this.onUpdate.bind(this);
  }

  onReset() {
    this.props.onUpdate(null);
    this.props.onReset();
  }

  onUpdate(e) {
    this.props.onUpdate(`${BASE_64_CODE}${e.nativeEvent.image}`);
  }

  saveImage(image) {
    if (typeof image !== 'string') {
      return Promise.reject('You need to provide a valid base64 encoded image.');
    }

    const src = image.indexOf(BASE_64_CODE) === 0 ? image.replace(BASE_64_CODE, '') : image;
    return SketchManager.saveImage(src);
  }

  clear() {
    return SketchManager.clear();
  }

  score() {
    return Math.random()*1000;
  }

  render() {
    return (
      <RNSketch
        {...this.props}
        onChange={this.onUpdate}
        onReset={this.onReset}
        style={[styles.base, this.props.style]}
      />
    );
  }

}

const RNSketch = requireNativeComponent('RNSketch', Sketch);
<commit_msg>adding points<commit_after>import React from 'react';
import {
  NativeModules,
  requireNativeComponent,
  StyleSheet,
  View,
} from 'react-native';

const { func, number, string, bool } = React.PropTypes;

const SketchManager = NativeModules.RNSketchManager || {};
const BASE_64_CODE = 'data:image/jpg;base64,';

const styles = StyleSheet.create({
  base: {
    flex: 1,
    height: 200,
  },
});

export default class Sketch extends React.Component {

  static propTypes = {
    fillColor: string,
    onReset: func,
    onUpdate: func,
    clearButtonHidden: bool,
    strokeColor: string,
    strokeThickness: number,
    style: View.propTypes.style,
  };

  static defaultProps = {
    fillColor: '#ffffff',
    onReset: () => {},
    onUpdate: () => {},
    clearButtonHidden: false,
    strokeColor: '#000000',
    strokeThickness: 1,
    style: null,
  };

  constructor(props) {
    super(props);
    this.onReset = this.onReset.bind(this);
    this.onUpdate = this.onUpdate.bind(this);
  }

  onReset() {
    this.props.onUpdate(null);
    this.props.onReset();
  }

  onUpdate(e) {
    this.props.onUpdate(`${BASE_64_CODE}${e.nativeEvent.image}`);
  }

  saveImage(image) {
    if (typeof image !== 'string') {
      return Promise.reject('You need to provide a valid base64 encoded image.');
    }

    const src = image.indexOf(BASE_64_CODE) === 0 ? image.replace(BASE_64_CODE, '') : image;
    return SketchManager.saveImage(src);
  }

  clear() {
    return SketchManager.clear();
  }

  get_points() {
    return SketchManager.get_points();
  }

  render() {
    return (
      <RNSketch
        {...this.props}
        onChange={this.onUpdate}
        onReset={this.onReset}
        style={[styles.base, this.props.style]}
      />
    );
  }

}

const RNSketch = requireNativeComponent('RNSketch', Sketch);
<|endoftext|>


<commit_before>'use strict';

import { NativeModules } from 'react-native';

var RNCalendarEvents = NativeModules.RNCalendarEvents;

export default RNCalendarEvents;<commit_msg>better formatting<commit_after>'use strict';

import { NativeModules } from 'react-native';

var RNCalendarEvents = NativeModules.RNCalendarEvents;
export default RNCalendarEvents;<|endoftext|>