<commit_before>'use strict';

/* eslint-env jasmine */
/* eslint-disable no-inline-comments */

const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');
const os = require('os');

describe('nitro:app', () => {

	jasmine.DEFAULT_TIMEOUT_INTERVAL = 15000;

	describe('when using custom name', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ name: 'my Project' })
				.on('end', done);
		});

		it('package.json contains project name', () => {
			assert.fileContent([
				['package.json', '"name": "my-project",'],
			]);
		});
	});

	describe('when using template engine hbs', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ templateEngine: 'hbs' })
				.on('end', done);
		});

		it('view files have the .hbs file extension', () => {
			assert.file([
				'src/views/index.hbs',
				'src/views/404.hbs',
				'src/views/_partials/head.hbs',
				'src/views/_partials/foot.hbs',
				'project/blueprints/pattern/$pattern$.hbs',
			]);
		});

		it('config contains the correct view file extension', () => {
			assert.fileContent('config/default.js', /viewFileExtension: 'hbs'/);
		});
	});

	describe('when using template engine twig', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ templateEngine: 'twig' })
				.on('end', done);
		});

		it('view files have the .twig file extension', () => {
			assert.file([
				'src/views/index.twig',
				'src/views/404.twig',
				'src/views/_partials/head.twig',
				'src/views/_partials/foot.twig',
				'project/blueprints/pattern/$pattern$.twig',
			]);
		});

		it('config contains the correct view file extension', () => {
			assert.fileContent('config/default.js', /viewFileExtension: 'twig'/);
		});
	});

	describe('when using compiler language typescript', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ compiler: 'ts' })
				.on('end', done);
		});

		it('javascript files have the .ts file extension', () => {
			assert.file([
				'src/proto.ts',
				'src/ui.ts',
				'src/proto/js/prototype.ts',
				'project/blueprints/pattern/js/$pattern$.ts',
			]);
		});

		it('config contains the correct view file extension', () => {
			assert.fileContent('config/default.js', /compiler: 'ts'/);
		});
	});

	describe('when using compiler language javascript', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ compiler: 'js' })
				.on('end', done);
		});

		it('javascript files have the .js file extension', () => {
			assert.file([
				'src/proto.js',
				'src/ui.js',
				'src/proto/js/prototype.js',
				'project/blueprints/pattern/js/$pattern$.js',
			]);
		});

		it('config contains the correct view file extension', () => {
			assert.fileContent('config/default.js', /compiler: 'js'/);
		});
	});

	describe('when including client templates', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ clientTpl: true })
				.on('end', done);
		});

		it('pattern blueprint contains template file', () => {
			assert.file('project/blueprints/pattern/template/$pattern$.hbs');
		});

		it('webpack config enables hbs loader', () => {
			assert.fileContent('config/webpack/options.js', /hbs: true,/);
		});

	});

	describe('when not including client templates', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ clientTpl: false })
				.on('end', done);
		});

		it('pattern blueprint does not contain template file', () => {
			assert.noFile('project/blueprints/pattern/template/$pattern$.hbs');
		});

		it('webpack config disables hbs loader', () => {
			assert.fileContent('config/webpack/options.js', /hbs: false,/);
		});

	});

	describe('when including example files', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ exampleCode: true })
				.on('end', done);
		});

		it('example pattern is present', () => {
			assert.file([
				'src/patterns/molecules/example/readme.md',
				'src/patterns/molecules/example/schema.json',
				'src/patterns/molecules/example/js/example.js',
				'src/patterns/molecules/example/_data/example.json',
			]);
		});

		it('icon pattern is present', () => {
			assert.file([
				'src/patterns/atoms/icon/readme.md',
				'src/patterns/atoms/icon/schema.json',
				'src/patterns/atoms/icon/_data/icon.json',
			]);
		});

		it('more example files are present', () => {
			assert.file([
				'src/patterns/atoms/box/box.hbs',
				'src/patterns/atoms/button/button.hbs',
				'src/patterns/atoms/checkbox/checkbox.hbs',
				'src/shared/base/document/css/document.scss',
				'src/shared/utils/breakpoints/css/breakpoints.scss',
				'src/views/example/patterns.hbs',
			]);
		});

		it('example icons are present', () => {
			assert.file([
				'src/shared/assets/img/icon/favicon.ico',
				'src/shared/assets/img/icon/favicon-16x16.png',
				'src/shared/assets/img/icon/favicon-32x32.png',
				'src/shared/assets/img/icon/apple-touch-icon.png',
			]);
		});

		it('some proto files are present', () => {
			assert.file([
				'src/proto/readme.md',
				'src/proto/css/prototype.scss',
				'src/proto/js/prototype.js',
				'src/proto/utils/develop-helpers/index.js',
				'src/proto/utils/develop-helpers/js/key1Breakpoint.js',
			]);
		});

		it('country project route is present', () => {
			assert.file([
				'project/routes/readme.md',
				'project/routes/countries.js',
				'project/routes/data/countries.json',
				'project/routes/helpers/utils.js',
			]);
		});
	});

	describe('when not including example files', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ exampleCode: false })
				.on('end', done);
		});

		it('example pattern is not present', () => {
			assert.noFile([
				'src/patterns/molecules/example/readme.md',
				'src/patterns/molecules/example/schema.json',
				'src/patterns/molecules/example/js/example.js',
				'src/patterns/molecules/example/_data/example.json',
			]);
		});

		it('icon pattern is not present', () => {
			assert.noFile([
				'src/patterns/atoms/icon/readme.md',
				'src/patterns/atoms/icon/schema.json',
				'src/patterns/atoms/icon/_data/icon.json',
			]);
		});

		it('more example files are not present', () => {
			assert.noFile([
				'src/patterns/atoms/box/box.hbs',
				'src/patterns/atoms/button/button.hbs',
				'src/patterns/atoms/checkbox/checkbox.hbs',
				'src/shared/base/document/css/document.scss',
				'src/shared/utils/breakpoints/css/breakpoints.scss',
				'src/views/example/patterns.hbs',
			]);
		});

		it('example icons are not present', () => {
			assert.noFile([
				'src/shared/assets/img/icon/favicon.ico',
				'src/shared/assets/img/icon/favicon-16x16.png',
				'src/shared/assets/img/icon/favicon-32x32.png',
				'src/shared/assets/img/icon/apple-touch-icon.png',
			]);
		});

		it('some proto files are still present', () => {
			assert.file([
				'src/proto/readme.md',
				'src/proto/css/prototype.scss',
				'src/proto/js/prototype.js',
			]);
		});

		it('some proto files are not present', () => {
			assert.noFile([
				'src/proto/utils/develop-helpers/index.js',
				'src/proto/utils/develop-helpers/js/key1Breakpoint.js',
			]);
		});

		it('country project route is not present', () => {
			assert.noFile([
				'project/routes/countries.js',
				'project/routes/data/countries.json',
				'project/routes/helpers/utils.js',
			]);
		});

		it('but project route readme.md is present', () => {
			assert.file([
				'project/routes/readme.md',
			]);
		});
	});

	describe('when including static exporter', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ exporter: true })
				.on('end', done);
		});

		it('config contains default exporter properties', () => {
			assert.fileContent([
				['config/default.js', /exporter:/],
			]);
		});
	});

	describe('when not including static exporter', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ exporter: false })
				.on('end', done);
		});

		it('config does not contain default exporter properties', () => {
			assert.noFileContent([
				['config/default.js', /exporter:/],
			]);
		});
	});
});
<commit_msg>tests(generator): enhance tests for new typescript option<commit_after>'use strict';

/* eslint-env jasmine */
/* eslint-disable no-inline-comments */

const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');
const os = require('os');

describe('nitro:app', () => {

	jasmine.DEFAULT_TIMEOUT_INTERVAL = 15000;

	describe('when using custom name', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ name: 'my Project' })
				.on('end', done);
		});

		it('package.json contains project name', () => {
			assert.fileContent([
				['package.json', '"name": "my-project",'],
			]);
		});
	});

	describe('when using template engine hbs', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ templateEngine: 'hbs' })
				.on('end', done);
		});

		it('view files have the .hbs file extension', () => {
			assert.file([
				'src/views/index.hbs',
				'src/views/404.hbs',
				'src/views/_partials/head.hbs',
				'src/views/_partials/foot.hbs',
				'project/blueprints/pattern/$pattern$.hbs',
			]);
		});

		it('config contains the correct view file extension', () => {
			assert.fileContent('config/default.js', /viewFileExtension: 'hbs'/);
		});
	});

	describe('when using template engine twig', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ templateEngine: 'twig' })
				.on('end', done);
		});

		it('view files have the .twig file extension', () => {
			assert.file([
				'src/views/index.twig',
				'src/views/404.twig',
				'src/views/_partials/head.twig',
				'src/views/_partials/foot.twig',
				'project/blueprints/pattern/$pattern$.twig',
			]);
		});

		it('config contains the correct view file extension', () => {
			assert.fileContent('config/default.js', /viewFileExtension: 'twig'/);
		});
	});

	describe('when using compiler language typescript', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ compiler: 'ts' })
				.on('end', done);
		});

		it('javascript files have the .ts file extension', () => {
			assert.file([
				'src/proto.ts',
				'src/ui.ts',
				'src/proto/js/prototype.ts',
				'project/blueprints/pattern/js/$pattern$.ts',
				'tsconfig.json',
			]);
			assert.noFile([
				'babel.config.js',
			]);
		});

		it('config contains the correct view file extension', () => {
			assert.fileContent('config/default.js', /compiler: 'ts'/);
		});
	});

	describe('when using compiler language javascript', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ compiler: 'js' })
				.on('end', done);
		});

		it('javascript files have the .js file extension', () => {
			assert.file([
				'src/proto.js',
				'src/ui.js',
				'src/proto/js/prototype.js',
				'project/blueprints/pattern/js/$pattern$.js',
				'babel.config.js',
			]);
			assert.noFile([
				'tsconfig.json',
			]);
		});

		it('config contains the correct view file extension', () => {
			assert.fileContent('config/default.js', /compiler: 'js'/);
		});
	});

	describe('when including client templates', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ clientTpl: true })
				.on('end', done);
		});

		it('pattern blueprint contains template file', () => {
			assert.file('project/blueprints/pattern/template/$pattern$.hbs');
		});

		it('webpack config enables hbs loader', () => {
			assert.fileContent('config/webpack/options.js', /hbs: true,/);
		});

	});

	describe('when not including client templates', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ clientTpl: false })
				.on('end', done);
		});

		it('pattern blueprint does not contain template file', () => {
			assert.noFile('project/blueprints/pattern/template/$pattern$.hbs');
		});

		it('webpack config disables hbs loader', () => {
			assert.fileContent('config/webpack/options.js', /hbs: false,/);
		});

	});

	describe('when including example files', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ exampleCode: true })
				.on('end', done);
		});

		it('example pattern is present', () => {
			assert.file([
				'src/patterns/molecules/example/readme.md',
				'src/patterns/molecules/example/schema.json',
				'src/patterns/molecules/example/js/example.js',
				'src/patterns/molecules/example/_data/example.json',
			]);
		});

		it('icon pattern is present', () => {
			assert.file([
				'src/patterns/atoms/icon/readme.md',
				'src/patterns/atoms/icon/schema.json',
				'src/patterns/atoms/icon/_data/icon.json',
			]);
		});

		it('more example files are present', () => {
			assert.file([
				'src/patterns/atoms/box/box.hbs',
				'src/patterns/atoms/button/button.hbs',
				'src/patterns/atoms/checkbox/checkbox.hbs',
				'src/shared/base/document/css/document.scss',
				'src/shared/utils/breakpoints/css/breakpoints.scss',
				'src/views/example/patterns.hbs',
			]);
		});

		it('example icons are present', () => {
			assert.file([
				'src/shared/assets/img/icon/favicon.ico',
				'src/shared/assets/img/icon/favicon-16x16.png',
				'src/shared/assets/img/icon/favicon-32x32.png',
				'src/shared/assets/img/icon/apple-touch-icon.png',
			]);
		});

		it('some proto files are present', () => {
			assert.file([
				'src/proto/readme.md',
				'src/proto/css/prototype.scss',
				'src/proto/js/prototype.js',
				'src/proto/utils/develop-helpers/index.js',
				'src/proto/utils/develop-helpers/js/key1Breakpoint.js',
			]);
		});

		it('country project route is present', () => {
			assert.file([
				'project/routes/readme.md',
				'project/routes/countries.js',
				'project/routes/data/countries.json',
				'project/routes/helpers/utils.js',
			]);
		});
	});

	describe('when not including example files', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ exampleCode: false })
				.on('end', done);
		});

		it('example pattern is not present', () => {
			assert.noFile([
				'src/patterns/molecules/example/readme.md',
				'src/patterns/molecules/example/schema.json',
				'src/patterns/molecules/example/js/example.js',
				'src/patterns/molecules/example/_data/example.json',
			]);
		});

		it('icon pattern is not present', () => {
			assert.noFile([
				'src/patterns/atoms/icon/readme.md',
				'src/patterns/atoms/icon/schema.json',
				'src/patterns/atoms/icon/_data/icon.json',
			]);
		});

		it('more example files are not present', () => {
			assert.noFile([
				'src/patterns/atoms/box/box.hbs',
				'src/patterns/atoms/button/button.hbs',
				'src/patterns/atoms/checkbox/checkbox.hbs',
				'src/shared/base/document/css/document.scss',
				'src/shared/utils/breakpoints/css/breakpoints.scss',
				'src/views/example/patterns.hbs',
			]);
		});

		it('example icons are not present', () => {
			assert.noFile([
				'src/shared/assets/img/icon/favicon.ico',
				'src/shared/assets/img/icon/favicon-16x16.png',
				'src/shared/assets/img/icon/favicon-32x32.png',
				'src/shared/assets/img/icon/apple-touch-icon.png',
			]);
		});

		it('some proto files are still present', () => {
			assert.file([
				'src/proto/readme.md',
				'src/proto/css/prototype.scss',
				'src/proto/js/prototype.js',
			]);
		});

		it('some proto files are not present', () => {
			assert.noFile([
				'src/proto/utils/develop-helpers/index.js',
				'src/proto/utils/develop-helpers/js/key1Breakpoint.js',
			]);
		});

		it('country project route is not present', () => {
			assert.noFile([
				'project/routes/countries.js',
				'project/routes/data/countries.json',
				'project/routes/helpers/utils.js',
			]);
		});

		it('but project route readme.md is present', () => {
			assert.file([
				'project/routes/readme.md',
			]);
		});
	});

	describe('when including static exporter', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ exporter: true })
				.on('end', done);
		});

		it('config contains default exporter properties', () => {
			assert.fileContent([
				['config/default.js', /exporter:/],
			]);
		});
	});

	describe('when not including static exporter', () => {
		beforeAll((done) => {
			helpers.run(path.join(__dirname, '../../../generators/app'))
				.inDir(path.join(os.tmpdir(), './temp-test'))
				.withOptions({ 'skip-install': true })
				.withPrompts({ exporter: false })
				.on('end', done);
		});

		it('config does not contain default exporter properties', () => {
			assert.noFileContent([
				['config/default.js', /exporter:/],
			]);
		});
	});
});
<|endoftext|>


<commit_before>/*
'nefu' MMORPG-style Web UI Library

Copyright (C) 2016 sincfrac

This software is released under the MIT License.
http://opensource.org/licenses/mit-license.php
*/

var nefu = nefu || {};
nefu.effects = nefu.effects || {};

nefu.getCanvasContext2d = function(canvasElement) {
	var ctx = canvasElement.getContext('2d');

	ctx.width = canvasElement.width;
	ctx.height = canvasElement.height;

	ctx.clear = function() {
		ctx.clearRect(0, 0, ctx.width, ctx.height);
	};

	return ctx;
};

nefu.math = (function(){
	return {
		dist2: function(p1, p2) {
			return (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y);
		},
		dist: function(p1, p2) {
			return Math.sqrt(nefu.math.dist2(p1, p2));
		},
		bspline: function(t, x0, x1, x2) {
			return 0.5*(x1+x0) + t*(x1-x0) + 0.5*t*t*(x2-2.0*x1+x0);
		}
	};
})();

nefu.effects.Set = function() {
	this.effects = new Set();
};
nefu.effects.Set.prototype = {
	update: function(dt) {
		var effects = this.effects;
		for(let ef of effects) {
			ef.update(dt);
		}
	},
	draw: function(ctx) {
		var effects = this.effects;
		for(let ef of effects) {
			ef.draw(ctx);
		}
	}
};

nefu.effects.Empty = function() {
};
nefu.effects.Empty.prototype = {
	update: function(dt) { },
	draw: function(ctx) { }
};

nefu.effects.Manager = function(canvasElement) {
	this.effect = new nefu.effects.Empty();
	this._canvas = canvasElement;
	this._ctx = nefu.getCanvasContext2d(canvasElement);
	this._timer = null;
	this._lastUpdate;
	this._maxDt = 0.1;
	this._interval = 10;
};
nefu.effects.Manager.prototype = {
	update: function(dt) {
		return this.effect.update(dt);
	},

	draw: function() {
		this.effect.draw(this._ctx);
	},

	clear: function() {
		this._ctx.clear();
	},

	tick: function() {
		var time = new Date();
		var dt = (time - this._lastUpdate) / 1000;
		dt = Math.min(this._maxDt, dt);

		if (dt == 0) { return; }
		this.effect.update(dt);

		var ctx = this._ctx;
		ctx.clear();
		this.effect.draw(ctx);

		this._lastUpdate = time;
	},

	start: function() {
		if (this._timer) { return; }

		this._lastUpdate = new Date();

		var self = this;
		this._timer = setInterval(function() {
			self.tick();
		},
		this._interval);
	},

	stop: function() {
		if (this._timer) {
			clearInterval(this._timer);
		}
	}
};

nefu.effects.MilkEmitter = function(opt) {
	this.option = $.extend({
		x: 0,
		y: 0,
		ax: 0,
		ay: 300,
		color: 'white',
		drag: 0.01,
		alpha: 1,
		radius: 2,
		minRadius: 1,
		life: 3.000,
		velocity: 600,
		angle: Math.PI*7/4,
		angleA: -Math.PI/8,
		angleD: +Math.PI/16,
		fadeOutDuration: 1.00,
		distSplit: 18,
		dist: 1
	}, opt);

	this._groups = new Set();

	this._isStarted = false;
	this._waitEmit = 0;

};
nefu.effects.MilkEmitter.prototype = {
	update: function(dt) {
		if (!this._isStarted) { return; }

		this._waitEmit -= dt;
		if (this._waitEmit <= 0) {
			this._emit(dt);
		}

		var groups = this._groups,
				opt = this.option;

		var dvx = opt.ax * dt,
				dvy = opt.ay * dt,
				ddt = opt.drag * dt;

		for (let g of groups) {
			var particles = g.particles;

			g.life -= dt;
			if (g.life <= 0) {
				groups.delete(g);
				continue;
			}

			var q = null;
			for (var i=0, len=particles.length; i<len; i++) {
				var p = particles[i];
				var dt_ = dt;

				if (p.wait > 0) {
					p.wait -= dt;

					if (p.wait < 0) {
						dt_ += p.wait;
						p.wait = 0;
					}
					else {
						continue;
					}
				}

				// Update velocity, position
				var v = Math.sqrt(p.vx*p.vx + p.vy*p.vy);
				p.vx += dvx - v*p.vx*ddt;
				p.vy += dvy - v*p.vy*ddt;
				p.x += p.vx * dt_;
				p.y += p.vy * dt_;

				// Update distance
				if (q) {
					var dist = nefu.math.dist(q, p);
					q.dist = dist;
				}
				q = p;
			}
			particles[particles.length-1].dist = 0;

			for (var i=0, len=particles.length; i<len; i++) {
				var p = particles[i];
				var avg = i==0 ? p.dist :
									i==len-1 ? particles[i-1].dist :
									(p.dist + particles[i-1].dist) / 2;

				p.avgDist = avg;
				p.split = p.split || avg >= opt.distSplit;
				p.radius = opt.radius * (1 - Math.min(1, avg / opt.distSplit)) * p.density;

				if (i>0 && i<len-1 && avg >= opt.distSplit) {
					var u = 0.3;
					var x0 = nefu.math.bspline(u, particles[i-1].x, p.x, particles[i+1].x),
							y0 = nefu.math.bspline(u, particles[i-1].y, p.y, particles[i+1].y),
							radius0 = nefu.math.bspline(u, particles[i-1].radius, p.radius, particles[i+1].radius);

					var p0 = {
						x: x0,
						y: y0,
						vx: p.vx,
						vy: p.vy,
						density: p.density/2,
						wait: 0,
						avgDist: particles[i-1].dist
					};

					p0.radius = opt.radius * (1 - Math.min(1, p0.avgDist / opt.distSplit)) * p0.density;

					var arr0 = particles.slice(0, i);
					arr0.push(p0);

					var u = 0.7;
					var x1 = nefu.math.bspline(u, particles[i-1].x, p.x, particles[i+1].x),
							y1 = nefu.math.bspline(u, particles[i-1].y, p.y, particles[i+1].y),
							radius1 = nefu.math.bspline(u, particles[i-1].radius, p.radius, particles[i+1].radius);

					var arr1 = particles.slice(i);
					p.x = x1;
					p.y = y1;
					p.radius = radius1;
					p.density = p.density/2;
					p.avgDist = p.dist;

					p.radius = opt.radius * (1 - Math.min(1, p.avgDist / opt.distSplit)) * p.density;

					g.particles = arr0;
					groups.add({
						particles: arr1,
						life: g.life
					});

					break;
				}
			}
		}
	},

	draw: function(ctx) {
		var groups = this._groups,
				opt = this.option,
				distSplit = opt.distSplit;

		for (let g of groups) {
			var particles = g.particles;
			var galpha = g.life < opt.fadeOutDuration ? g.life / opt.fadeOutDuration : 1;

			for (var i=0, len=particles.length; i<len; i++) {
				var p1 = particles[i];
				if (p1.wait > 0) { break; }

				var p0 = particles[Math.max(0,i-1)];
				var p2 = particles[Math.min(len-1,i+1)];

				var dist = p1.avgDist;
				var alpha = opt.alpha * galpha;

				//if (!p1.split) {
					var du = opt.dist / dist;
					for (var u=0; u<1; u+=du) {
						var x = nefu.math.bspline(u, p0.x, p1.x, p2.x),
								y = nefu.math.bspline(u, p0.y, p1.y, p2.y),
								radius = nefu.math.bspline(u, p0.radius, p1.radius, p2.radius);

						var r = Math.max(0.1, radius);

						ctx.beginPath();
						ctx.fillStyle = opt.color;
						ctx.arc(x, y, r, 0, Math.PI*2, false);
						ctx.globalAlpha = alpha;
						ctx.fill();
					}
				//}
				/*else {
					var k = 0.5 + 0.5*Math.min(1, (dist-distSplit)/5);	// ToDo: parameter

					for (var d=0; d<dist; d+=opt.dist) {
						var u = d / dist;
						var x, y, radius, r;

						if (u < 0.5) {
							var x = nefu.math.bspline(u, p0.x, p1.x, p1.x),
									y = nefu.math.bspline(u, p0.y, p1.y, p1.y),
									radius = nefu.math.bspline(u, p0.radius, p1.radius, p1.radius);

							if (d >= distSplit/2) continue;
							var r = Math.min(1, d / (distSplit/2));
						}
						else {
							var x = nefu.math.bspline(u, p1.x, p1.x, p2.x),
									y = nefu.math.bspline(u, p1.y, p1.y, p2.y),
									radius = nefu.math.bspline(u, p1.radius, p1.radius, p2.radius);

							if (dist-d >= distSplit/2) continue;
							var r = Math.min(1, (dist-d) / (distSplit/2));
						}

						r = Math.max(0.1, Math.max(opt.minRadius*r*k, radius));

						ctx.beginPath();
						ctx.fillStyle = opt.color;
						ctx.arc(x, y, r, 0, Math.PI*2, false);
						ctx.globalAlpha = alpha;
						ctx.fill();
					}
				}*/

				if (opt.debug) {
					ctx.beginPath();
					ctx.fillStyle = 'rgba(255,0,0,0.5)';
					ctx.arc(p1.x, p1.y, 1, 0, Math.PI*2, false);
					ctx.globalAlpha = alpha;
					ctx.fill();

					ctx.beginPath();
					ctx.moveTo(p0.x, p0.y);
					ctx.lineTo(p1.x, p1.y);
					ctx.strokeStyle = 'rgba(255,0,0,0.5)';
					ctx.stroke();
				}
			}
		}
	},

	start: function() {
		this._isStarted = true;
	},

	_emit: function(dt) {
		var opt = this.option;

		/*
			velocity: ADSR
			angle: ADSR
			density: ADSR
			timing: ADSR
		*/

		this._emitOneShot({
			x: opt.x,
			y: opt.y,
			velocity: opt.velocity,
			velocityA: 100,
			velocityD: -200,
			angle: opt.angle,
			angleA: opt.angleA,
			angleD: opt.angleD,
			duration: 0.30,
			durationA: 0.150,
			interval: 0.020,
			intervalDeviation: 0.02
		});

		this._waitEmit = 1.500;
	},

	_calcADSR: function(t, timing, val) {
		if (t < timing.att) {
			return val.bias
							+ val.att * (t/timing.att);
		}
		if (t < timing.dec) {
			return val.bias + val.att
							+ (val.dec-val.att) * (t-timing.att) / (timing.dec-timing.att);
		}
		if (t < timing.sus) {
			return val.bias + val.sus;
		}
		if (t <= timing.rel) {
			return val.bias + val.sus
							+ (val.rel-val.sus) * (t-timing.sus) / (timing.rel-timing.sus);
		}
		return val.bias;
	},

	_emitOneShot: function(conf) {
		var particles = [];
		var opt = this.option;

		var durA = conf.durationA,
				durD = conf.duration - conf.durationA;

		var t = 0;
		while (t < conf.duration) {
			var interval = conf.interval + conf.intervalDeviation * (2*Math.random()-1);

			var angle;
			var velocity;

			if (t < durA) {
				var k = t / durA + Math.random()*0.2;
				angle = conf.angle + conf.angleA * k;
				velocity = conf.velocity + conf.velocityA * k;
			}
			else {
				var k = (t-durA) / durD + Math.random()*0.2;
				angle = conf.angle + conf.angleA + conf.angleD * k;
				velocity = conf.velocity + conf.velocityA + conf.velocityD * k;
			}

			var vx = velocity * Math.cos(angle);
			var vy = velocity * Math.sin(angle);

			particles.push({
				wait: t,
				x: conf.x,
				y: conf.y,
				vx: vx,
				vy: vy,
				density: 1
			});

			t += interval;
		}

		this._groups.add({
			life: opt.life,
			particles: particles
		});
	}
};

<commit_msg>Add intermolecular power to MilkEmitter<commit_after>/*
'nefu' MMORPG-style Web UI Library

Copyright (C) 2016 sincfrac

This software is released under the MIT License.
http://opensource.org/licenses/mit-license.php
*/

var nefu = nefu || {};
nefu.effects = nefu.effects || {};

nefu.getCanvasContext2d = function(canvasElement) {
	var ctx = canvasElement.getContext('2d');

	ctx.width = canvasElement.width;
	ctx.height = canvasElement.height;

	ctx.clear = function() {
		ctx.clearRect(0, 0, ctx.width, ctx.height);
	};

	return ctx;
};

nefu.math = (function(){
	return {
		dist2: function(p1, p2) {
			return (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y);
		},
		dist: function(p1, p2) {
			return Math.sqrt(nefu.math.dist2(p1, p2));
		},
		bspline: function(t, x0, x1, x2) {
			return 0.5*(x1+x0) + t*(x1-x0) + 0.5*t*t*(x2-2.0*x1+x0);
		}
	};
})();

nefu.effects.Set = function() {
	this.effects = new Set();
};
nefu.effects.Set.prototype = {
	update: function(dt) {
		var effects = this.effects;
		for(let ef of effects) {
			ef.update(dt);
		}
	},
	draw: function(ctx) {
		var effects = this.effects;
		for(let ef of effects) {
			ef.draw(ctx);
		}
	}
};

nefu.effects.Empty = function() {
};
nefu.effects.Empty.prototype = {
	update: function(dt) { },
	draw: function(ctx) { }
};

nefu.effects.Manager = function(canvasElement) {
	this.effect = new nefu.effects.Empty();
	this._canvas = canvasElement;
	this._ctx = nefu.getCanvasContext2d(canvasElement);
	this._timer = null;
	this._lastUpdate;
	this._maxDt = 0.1;
	this._interval = 10;
};
nefu.effects.Manager.prototype = {
	update: function(dt) {
		return this.effect.update(dt);
	},

	draw: function() {
		this.effect.draw(this._ctx);
	},

	clear: function() {
		this._ctx.clear();
	},

	tick: function() {
		var time = new Date();
		var dt = (time - this._lastUpdate) / 1000;
		dt = Math.min(this._maxDt, dt);

		if (dt == 0) { return; }
		this.effect.update(dt);

		var ctx = this._ctx;
		ctx.clear();
		this.effect.draw(ctx);

		this._lastUpdate = time;
	},

	start: function() {
		if (this._timer) { return; }

		this._lastUpdate = new Date();

		var self = this;
		this._timer = setInterval(function() {
			self.tick();
		},
		this._interval);
	},

	stop: function() {
		if (this._timer) {
			clearInterval(this._timer);
		}
	}
};

nefu.effects.MilkEmitter = function(opt) {
	this.option = $.extend({
		x: 0,
		y: 0,
		ax: 0,
		ay: 300,
		color: 'white',
		drag: 0.01,
		alpha: 1,
		radius: 2,
		minRadius: 1,
		life: 3.000,
		velocity: 600,
		angle: Math.PI*7/4,
		angleA: -Math.PI/8,
		angleD: +Math.PI/16,
		fadeOutDuration: 1.00,
		distMax: 18,
		distSplit: 25,
		dist: 1,
		attraction: 150
	}, opt);

	this._groups = new Set();

	this._isStarted = false;
	this._waitEmit = 0;

};
nefu.effects.MilkEmitter.prototype = {
	update: function(dt) {
		if (!this._isStarted) { return; }

		this._waitEmit -= dt;
		if (this._waitEmit <= 0) {
			this._emit(dt);
		}

		var groups = this._groups,
				opt = this.option;

		var dvx = opt.ax * dt,
				dvy = opt.ay * dt,
				ddt = opt.drag * dt;

		for (let g of groups) {
			var particles = g.particles;

			g.life -= dt;
			if (g.life <= 0) {
				groups.delete(g);
				continue;
			}

			for (var i=0, len=particles.length; i<len; i++) {
				var p = particles[i];
				var pn = i<len-1 ? particles[i+1] : null;

				var dt_ = dt;

				if (p.wait > 0) {
					p.wait -= dt;

					if (p.wait < 0) {
						dt_ += p.wait;
						p.wait = 0;
					}
					else {
						continue;
					}
				}

				// Update velocity, position
				var v = Math.sqrt(p.vx*p.vx + p.vy*p.vy);
				p.vx += dvx - v*p.vx*ddt;
				p.vy += dvy - v*p.vy*ddt;
				p.x += p.vx * dt_;
				p.y += p.vy * dt_;

				if (pn) {
					// Update distance
					var dist2 = nefu.math.dist2(p, pn);
					p.dist = Math.sqrt(dist2);

					// Calculate intermolecular force
					if (p.dist > 5) {
						var dx = pn.x - p.x,
								dy = pn.y - p.y;

						// ToDo: 加速度なので速度に加算すべき
						var power = opt.attraction * p.density * pn.density / dist2 * dt_;
						p.x += power * dx;
						p.y += power * dy;
						pn.x -= power * dx;
						pn.y -= power * dy;
					}
				}
				else {
					p.dist = 0;
				}
			}

			for (var i=0, len=particles.length; i<len; i++) {
				var p = particles[i];
				var avg = i==0 ? p.dist :
									i==len-1 ? particles[i-1].dist :
									(p.dist + particles[i-1].dist) / 2;

				p.avgDist = avg;
				p.radius = opt.radius * (1 - Math.min(1, avg / opt.distMax)) * p.density;

				if (i>0 && i<len-1 && avg >= opt.distSplit) {
					var p0 = particles[i-1],
							p2 = particles[i+1];

					var u = 0.4;
					var pp = {};
					pp.x  = nefu.math.bspline(u, p0.x,  p.x,  p2.x);
					pp.y  = nefu.math.bspline(u, p0.y,  p.y,  p2.y),
					pp.vx = nefu.math.bspline(u, p0.vx, p.vx, p2.vx);
					pp.vy = nefu.math.bspline(u, p0.vy, p.vy, p2.vy);

					pp.density = p.density/2;
					pp.wait = 0;
					pp.avgDist = p0.dist;
					pp.radius = opt.radius * (1 - Math.min(1, pp.avgDist / opt.distMax)) * pp.density;

					var arr0 = particles.slice(0, i);
					arr0.push(pp);
					g.particles = arr0;

					var u = 0.6;
					p.x  = nefu.math.bspline(u, p0.x,  p.x,  p2.x);
					p.y  = nefu.math.bspline(u, p0.y,  p.y,  p2.y);
					p.vx = nefu.math.bspline(u, p0.vx, p.vx, p2.vx);
					p.vy = nefu.math.bspline(u, p0.vy, p.vy, p2.vy);

					p.density = p.density/2;
					p.avgDist = p.dist;
					p.radius = opt.radius * (1 - Math.min(1, p.avgDist / opt.distMax)) * p.density;

					var arr1 = particles.slice(i);
					groups.add({
						particles: arr1,
						life: g.life
					});

					break;
				}
			}
		}
	},

	draw: function(ctx) {
		var groups = this._groups,
				opt = this.option,
				distSplit = opt.distSplit;

		for (let g of groups) {
			var particles = g.particles;
			var galpha = g.life < opt.fadeOutDuration ? g.life / opt.fadeOutDuration : 1;

			for (var i=0, len=particles.length; i<len; i++) {
				var p1 = particles[i];
				if (p1.wait > 0) { break; }

				var p0 = particles[Math.max(0,i-1)];
				var p2 = particles[Math.min(len-1,i+1)];

				var alpha = opt.alpha * galpha;

				var du = opt.dist / p1.avgDist;
				for (var u=0; u<1; u+=du) {
					var x = nefu.math.bspline(u, p0.x, p1.x, p2.x),
							y = nefu.math.bspline(u, p0.y, p1.y, p2.y),
							r = nefu.math.bspline(u, p0.radius, p1.radius, p2.radius);

					r = Math.max(0.1, r);

					ctx.beginPath();
					ctx.fillStyle = opt.color;
					ctx.arc(x, y, r, 0, Math.PI*2, false);
					ctx.globalAlpha = alpha;
					ctx.fill();
				}
			}
		}

		//this._drawDebug(ctx);
	},

	_drawDebug: function(ctx) {
		var groups = this._groups;

		ctx.fillStyle = 'red';
		ctx.strokeStyle = 'red';
		ctx.globalAlpha = 0.5;

		for (let g of groups) {
			var particles = g.particles;

			for (var i=0, len=particles.length; i<len-1; i++) {
				var p0 = particles[i];
				var p1 = particles[i+1];

				ctx.beginPath();
				ctx.arc(p1.x, p1.y, 1, 0, Math.PI*2, false);
				ctx.fill();

				ctx.beginPath();
				ctx.moveTo(p0.x, p0.y);
				ctx.lineTo(p1.x, p1.y);
				ctx.stroke();
			}
		}
	},

	start: function() {
		this._isStarted = true;
	},

	_emit: function(dt) {
		var opt = this.option;

		/*
			velocity: ADSR
			angle: ADSR
			density: ADSR
			timing: ADSR
		*/

		this._emitOneShot({
			x: opt.x,
			y: opt.y,
			velocity: opt.velocity,
			velocityA: 300,
			velocityD: -400,
			angle: opt.angle,
			angleA: opt.angleA,
			angleD: opt.angleD,
			duration: 0.30,
			durationA: 0.150,
			interval: 0.020,
			intervalDeviation: 0.02
		});

		this._waitEmit = 1.500;
	},

	_calcADSR: function(t, timing, val) {
		if (t < timing.att) {
			return val.bias
							+ val.att * (t/timing.att);
		}
		if (t < timing.dec) {
			return val.bias + val.att
							+ (val.dec-val.att) * (t-timing.att) / (timing.dec-timing.att);
		}
		if (t < timing.sus) {
			return val.bias + val.sus;
		}
		if (t <= timing.rel) {
			return val.bias + val.sus
							+ (val.rel-val.sus) * (t-timing.sus) / (timing.rel-timing.sus);
		}
		return val.bias;
	},

	_emitOneShot: function(conf) {
		var particles = [];
		var opt = this.option;

		var durA = conf.durationA,
				durD = conf.duration - conf.durationA;

		var t = 0;
		while (t < conf.duration) {
			var interval = conf.interval + conf.intervalDeviation * (2*Math.random()-1);

			var angle;
			var velocity;

			if (t < durA) {
				var k = t / durA + Math.random()*0.2;
				angle = conf.angle + conf.angleA * k;
				velocity = conf.velocity + conf.velocityA * k;
			}
			else {
				var k = (t-durA) / durD + Math.random()*0.2;
				angle = conf.angle + conf.angleA + conf.angleD * k;
				velocity = conf.velocity + conf.velocityA + conf.velocityD * k;
			}

			var vx = velocity * Math.cos(angle);
			var vy = velocity * Math.sin(angle);

			particles.push({
				wait: t,
				x: conf.x,
				y: conf.y,
				vx: vx,
				vy: vy,
				density: 1
			});

			t += interval;
		}

		this._groups.add({
			life: opt.life,
			particles: particles
		});
	}
};

<|endoftext|>


<commit_before>function nexusClient(nexusServer, autoConnectOptions) {
  if(!nexusServer) throw new Error('Missing nexusServer address');
  this.nexusServer = nexusServer;
  this._isConnectedToHost = false;

  this._ws = new WebSocket(nexusServer);
  this._ws.onopen = () => {
    if(this._isConnectedToHost) return;
    this.onServerConnect && this.onServerConnect();
    if(autoConnectOptions) {
      this._ws.send(JSON.stringify(Object.assign({
        type: 'CONNECT',
      }, autoConnectOptions)));
    }
  };

  this._ws.onmessage = (event) => {
    //     console.log('Received:', event.data);
    if(this._isConnectedToHost) {
      this.onMessage && this.onMessage(event.data);
    } else {
      const req = JSON.parse(event.data);
      switch(req.type) {
        case 'LIST':
          if(!this._isConnectedToHost) {
            this.onHostList && this.onHostList(req.payload);
          }
          break;
        case 'CONNECTED':
          if(!this._isConnectedToHost) {
            this._isConnectedToHost = true;
            this.onHostConnect && this.onHostConnect(req.payload);
          }
          break;
      }
    }
  };
}

nexusClient.prototype.setDefaultCallbacks = function() {
  /* You can set any of these to null to have no callback */

  this.onHostList = (hosts) => {
    /* example callback */
    console.log("+ Recieved list of hosts:");
    hosts.forEach(h=>{
      console.log('  %d: %s', h.hostID, h.hostName);
    });
  };

  this.onHostConnect = (host) => {
    /* example callback */
    console.log('+ Connected to host:', host);
  };

  this.onMessage = (message) => {
    /* example callback */
    console.log('+ Recieved message:', message);
  };
};

nexusClient.prototype.getHostList = function(callback) {
  if(this._isConnectedToHost) {
    throw new Error('Cannot get host list when connected to a host');
  }

  if(callback) {
    this.onHostList = callback;
  }
  this._ws.send(JSON.stringify({
    type: 'LIST',
  }))
};

nexusClient.prototype.connect = function(connectOptions, callback) {
  if(this._isConnectedToHost) {
    throw new Error('Cannot connect to a host: already connected to one');
  }

  if(callback) {
    this.onHostConnect = callback;
  }

  this._ws.send(JSON.stringify(Object.assign({},{
    type: 'CONNECT',
  }, connectOptions)));
}

nexusClient.prototype.send = function(msg) {
  if(!this._isConnectedToHost) {
    throw new Error('Must be connected to a host before you send anything');
  }
  this._ws.send(msg);
}

nexusClient.prototype.close = function() {
  this._ws.close();
}
<commit_msg>Add onServerConnect and onClose to client callbacks<commit_after>function nexusClient(nexusServer, autoConnectOptions) {
  if(!nexusServer) throw new Error('Missing nexusServer address');
  this.nexusServer = nexusServer;
  this._isConnectedToHost = false;

  this._ws = new WebSocket(nexusServer);
  this._ws.onopen = () => {
    if(this._isConnectedToHost) return;
    this.onServerConnect && this.onServerConnect();
    if(autoConnectOptions) {
      this._ws.send(JSON.stringify(Object.assign({
        type: 'CONNECT',
      }, autoConnectOptions)));
    }
  };

  this._ws.onclose = (...args) => {
    this.onClose && this.onClose(...args);
  }

  this._ws.onmessage = (event) => {
    //     console.log('Received:', event.data);
    if(this._isConnectedToHost) {
      this.onMessage && this.onMessage(event.data);
    } else {
      const req = JSON.parse(event.data);
      switch(req.type) {
        case 'LIST':
          if(!this._isConnectedToHost) {
            this.onHostList && this.onHostList(req.payload);
          }
          break;
        case 'CONNECTED':
          if(!this._isConnectedToHost) {
            this._isConnectedToHost = true;
            this.onHostConnect && this.onHostConnect(req.payload);
          }
          break;
      }
    }
  };
}

nexusClient.prototype.setDefaultCallbacks = function() {
  /* You can set any of these to null to have no callback */

  this.onHostList = (hosts) => {
    /* example callback */
    console.log("+ Recieved list of hosts:");
    hosts.forEach(h=>{
      console.log('  %d: %s', h.hostID, h.hostName);
    });
  };

  this.onServerConnect = () => {
    /* example callback */
    console.log('+ Connected to nexus server.');
  };

  this.onHostConnect = (host) => {
    /* example callback */
    console.log('+ Connected to host:', host);
  };

  this.onMessage = (message) => {
    /* example callback */
    console.log('+ Recieved message:', message);
  };

  this.onClose = (...args) => {
    /* example callback */
    console.log('+ Client closed:', ...args);
  };
};

nexusClient.prototype.getHostList = function(callback) {
  if(this._isConnectedToHost) {
    throw new Error('Cannot get host list when connected to a host');
  }

  if(callback) {
    this.onHostList = callback;
  }
  this._ws.send(JSON.stringify({
    type: 'LIST',
  }))
};

nexusClient.prototype.connect = function(connectOptions, callback) {
  if(this._isConnectedToHost) {
    throw new Error('Cannot connect to a host: already connected to one');
  }

  if(callback) {
    this.onHostConnect = callback;
  }

  this._ws.send(JSON.stringify(Object.assign({},{
    type: 'CONNECT',
  }, connectOptions)));
}

nexusClient.prototype.send = function(msg) {
  if(!this._isConnectedToHost) {
    throw new Error('Must be connected to a host before you send anything');
  }
  this._ws.send(msg);
}

nexusClient.prototype.close = function() {
  this._ws.close();
}
<|endoftext|>


<commit_before>// ==UserScript==
// @name        no feed
// @namespace   mm
// @description takes away the feed
// @include     https://www.facebook.com/
// @version     1
// @grant       none
// ==/UserScript==

document.getElementById("stream_pagelet").lastChild.innerHTML = "Nah"<commit_msg>on hash change<commit_after>// ==UserScript==
// @name        no feed
// @namespace   mm
// @description takes away the feed
// @include     https://www.facebook.com/
// @version     1
// @grant       none
// ==/UserScript==
window.addEventListener('hashchange', function() {
	var stream = document.getElementById("stream_pagelet");
	if(stream) {
		stream.lastChild.innerHTML = "Nah"
	}
});<|endoftext|>


<commit_before>dojo.provide("dijit.Tooltip");

dojo.require("dijit.base.Widget");
dojo.require("dijit.base.TemplatedWidget");
dojo.require("dijit.util.place");
dojo.require("dijit.util.BackgroundIframe");

dojo.declare(
	"dijit._MasterTooltip",
	[dijit.base.Widget, dijit.base.TemplatedWidget],
	{
		// summary
		//		Internal widget that holds the actual tooltip markup,
		//		which occurs once per page.
		//		Called by Tooltip widgets which are just containers to hold
		//		the markup

		// duration: Integer
		//		Milliseconds to fade in/fade out
		duration: 200,

		// opacity: Number
		//		Final opacity tooltips are shown at, after fade in
		opacity: 0.9,

		templatePath: dojo.moduleUrl("dijit", "templates/Tooltip.html"),

		postCreate: function(){
			dojo.body().appendChild(this.domNode);

			this.bgIframe = new dijit.util.BackgroundIframe();
			this.bgIframe.setZIndex(dojo.style(this.domNode, "zIndex")-1);

			this.fadeIn = dojo._fade({node: this.domNode, duration: this.duration, end: this.opacity});
			dojo.connect(this.fadeIn, "onEnd", this, "_onShow");
			this.fadeOut = dojo._fade({node: this.domNode, duration: this.duration, end: 0});
			dojo.connect(this.fadeOut, "onEnd", this, "_onHide");

		},

		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode){
			// summary: display tooltip w/specified contents underneath specified node

			if(this.fadeOut.status() == "playing"){
				// previous tooltip is being hidden; wait until the hide completes then show new one
				this._onDeck=arguments;
				return;
			}
			this.containerNode.innerHTML=innerHTML;
			dijit.util.placeOnScreenAroundElement(this.domNode, aroundNode, [0,0],
				{'BL': 'TL', 'TL': 'BL'});
			dojo.style(this.domNode, "opacity", 0);
			this.fadeIn.play();
			this.isShowingNow = true;
		},

		_onShow: function(){
			this.bgIframe.size(this.domNode);
			this.bgIframe.show();
		},

		hide: function(){
			// summary: hide the tooltip
			if(this._onDeck){
				// this hide request is for a show() that hasn't even started yet;
				// just cancel the pending show()
				this._onDeck=null;
				return;
			}
			this.fadeIn.stop();
			this.isShowingNow = false;
			this.fadeOut.play();
		},

		_onHide: function(){
			this.domNode.style.cssText="";	// to position offscreen again
			this.bgIframe.hide();
			if(this._onDeck){
				// a show request has been queue up; do it now
				this.show.apply(this, this._onDeck);
				this._onDeck=null;
			}
		},

	}
);

// Make a single tooltip markup on the page that is reused as appropriate
dojo.addOnLoad(function(){
	dijit.MasterTooltip = new dijit._MasterTooltip();
});

dojo.declare(
	"dijit.Tooltip",
	dijit.base.Widget,
	{
		// summary
		//		Pops up a tooltip (a help message) when you hover over a node.

		// caption: String
		//		Text to display in the tooltip.
		//		Can also be specified as innerHTML (when creating the widget from markup).
		caption: "",

		// showDelay: Integer
		//		Number of milliseconds to wait after hovering over/focusing on the object, before
		//		the tooltip is displayed.
		showDelay: 400,

		// connectId: String
		//		Id of domNode to attach the tooltip to.
		//		(When user hovers over specified dom node, the tooltip will appear.)
		connectId: "",

		// A hash to hold connect handles for cleanup
		_connections: [],

		postCreate: function(){
			this._connectNode = dojo.byId(this.connectId);

			dojo.forEach(["onMouseOver", "onHover", "onMouseOut", "onUnHover"], function(event){
				this._connections.event = dojo.connect(this._connectNode, event.toLowerCase(), this, "_"+event);
			}, this);
		},

		//PORT from dojo.dom.isDescendantOf
		_isDescendantOf: function(/*Node*/node, /*Node*/ancestor){
			//	summary
			//	Returns boolean if node is a descendant of ancestor
			// guaranteeDescendant allows us to be a "true" isDescendantOf function

			while(node){
				if(node === ancestor){
					return true; // boolean
				}
				node = node.parentNode;
			}
			return false; // boolean
		},

		_onMouseOver: function(/*Event*/ e){
			if(this._isDescendantOf(e.relatedTarget, this._connectNode)){
				// false event; just moved from target child to target; ignore.
				return;
			}
			this._onHover(e);
		},

		_onMouseOut: function(/*Event*/ e){
			if(this._isDescendantOf(e.relatedTarget, this._connectNode)){
				// false event; just moved from target to target child; ignore.
				return;
			}
			this._onUnHover(e);
		},

		_onHover: function(/*Event*/ e){
			if(this._hover){ return; }
			this._hover=true;

			// If tooltip not showing yet then set a timer to show it shortly
			if(!this.isShowingNow && !this._showTimer){
				this._showTimer = setTimeout(dojo.hitch(this, "open"), this.showDelay);
			}
		},

		_onUnHover: function(/*Event*/ e){
			if(!this._hover){ return; }
			this._hover=false;

			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}else{
				this.close();
			}
		},

		open: function(){
			// summary: display the tooltip; usually not called directly.
			if(this.isShowingNow){ return; }
			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}
			delete this._showTimer;
			dijit.MasterTooltip.show(this.caption || this.domNode.innerHTML, this._connectNode);
			this.isShowingNow = true;
		},

		close: function(){
			// summary: hide the tooltip; usually not called directly.
			if(!this.isShowingNow){ return; }
			dijit.MasterTooltip.hide();
			this.isShowingNow = false;
		},

		uninitialize: function(){
			this.close();
			for(var event in this._connections){
				dojo.disconnect(this._connectNode, event, this._connections.event);
			}
			this._connections = {};
		}
	}
);
<commit_msg>Erase trailing comma; refs #2639.<commit_after>dojo.provide("dijit.Tooltip");

dojo.require("dijit.base.Widget");
dojo.require("dijit.base.TemplatedWidget");
dojo.require("dijit.util.place");
dojo.require("dijit.util.BackgroundIframe");

dojo.declare(
	"dijit._MasterTooltip",
	[dijit.base.Widget, dijit.base.TemplatedWidget],
	{
		// summary
		//		Internal widget that holds the actual tooltip markup,
		//		which occurs once per page.
		//		Called by Tooltip widgets which are just containers to hold
		//		the markup

		// duration: Integer
		//		Milliseconds to fade in/fade out
		duration: 200,

		// opacity: Number
		//		Final opacity tooltips are shown at, after fade in
		opacity: 0.9,

		templatePath: dojo.moduleUrl("dijit", "templates/Tooltip.html"),

		postCreate: function(){
			dojo.body().appendChild(this.domNode);

			this.bgIframe = new dijit.util.BackgroundIframe();
			this.bgIframe.setZIndex(dojo.style(this.domNode, "zIndex")-1);

			this.fadeIn = dojo._fade({node: this.domNode, duration: this.duration, end: this.opacity});
			dojo.connect(this.fadeIn, "onEnd", this, "_onShow");
			this.fadeOut = dojo._fade({node: this.domNode, duration: this.duration, end: 0});
			dojo.connect(this.fadeOut, "onEnd", this, "_onHide");

		},

		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode){
			// summary: display tooltip w/specified contents underneath specified node

			if(this.fadeOut.status() == "playing"){
				// previous tooltip is being hidden; wait until the hide completes then show new one
				this._onDeck=arguments;
				return;
			}
			this.containerNode.innerHTML=innerHTML;
			dijit.util.placeOnScreenAroundElement(this.domNode, aroundNode, [0,0],
				{'BL': 'TL', 'TL': 'BL'});
			dojo.style(this.domNode, "opacity", 0);
			this.fadeIn.play();
			this.isShowingNow = true;
		},

		_onShow: function(){
			this.bgIframe.size(this.domNode);
			this.bgIframe.show();
		},

		hide: function(){
			// summary: hide the tooltip
			if(this._onDeck){
				// this hide request is for a show() that hasn't even started yet;
				// just cancel the pending show()
				this._onDeck=null;
				return;
			}
			this.fadeIn.stop();
			this.isShowingNow = false;
			this.fadeOut.play();
		},

		_onHide: function(){
			this.domNode.style.cssText="";	// to position offscreen again
			this.bgIframe.hide();
			if(this._onDeck){
				// a show request has been queue up; do it now
				this.show.apply(this, this._onDeck);
				this._onDeck=null;
			}
		}

	}
);

// Make a single tooltip markup on the page that is reused as appropriate
dojo.addOnLoad(function(){
	dijit.MasterTooltip = new dijit._MasterTooltip();
});

dojo.declare(
	"dijit.Tooltip",
	dijit.base.Widget,
	{
		// summary
		//		Pops up a tooltip (a help message) when you hover over a node.

		// caption: String
		//		Text to display in the tooltip.
		//		Can also be specified as innerHTML (when creating the widget from markup).
		caption: "",

		// showDelay: Integer
		//		Number of milliseconds to wait after hovering over/focusing on the object, before
		//		the tooltip is displayed.
		showDelay: 400,

		// connectId: String
		//		Id of domNode to attach the tooltip to.
		//		(When user hovers over specified dom node, the tooltip will appear.)
		connectId: "",

		// A hash to hold connect handles for cleanup
		_connections: [],

		postCreate: function(){
			this._connectNode = dojo.byId(this.connectId);

			dojo.forEach(["onMouseOver", "onHover", "onMouseOut", "onUnHover"], function(event){
				this._connections.event = dojo.connect(this._connectNode, event.toLowerCase(), this, "_"+event);
			}, this);
		},

		//PORT from dojo.dom.isDescendantOf
		_isDescendantOf: function(/*Node*/node, /*Node*/ancestor){
			//	summary
			//	Returns boolean if node is a descendant of ancestor
			// guaranteeDescendant allows us to be a "true" isDescendantOf function

			while(node){
				if(node === ancestor){
					return true; // boolean
				}
				node = node.parentNode;
			}
			return false; // boolean
		},

		_onMouseOver: function(/*Event*/ e){
			if(this._isDescendantOf(e.relatedTarget, this._connectNode)){
				// false event; just moved from target child to target; ignore.
				return;
			}
			this._onHover(e);
		},

		_onMouseOut: function(/*Event*/ e){
			if(this._isDescendantOf(e.relatedTarget, this._connectNode)){
				// false event; just moved from target to target child; ignore.
				return;
			}
			this._onUnHover(e);
		},

		_onHover: function(/*Event*/ e){
			if(this._hover){ return; }
			this._hover=true;

			// If tooltip not showing yet then set a timer to show it shortly
			if(!this.isShowingNow && !this._showTimer){
				this._showTimer = setTimeout(dojo.hitch(this, "open"), this.showDelay);
			}
		},

		_onUnHover: function(/*Event*/ e){
			if(!this._hover){ return; }
			this._hover=false;

			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}else{
				this.close();
			}
		},

		open: function(){
			// summary: display the tooltip; usually not called directly.
			if(this.isShowingNow){ return; }
			if(this._showTimer){
				clearTimeout(this._showTimer);
				delete this._showTimer;
			}
			delete this._showTimer;
			dijit.MasterTooltip.show(this.caption || this.domNode.innerHTML, this._connectNode);
			this.isShowingNow = true;
		},

		close: function(){
			// summary: hide the tooltip; usually not called directly.
			if(!this.isShowingNow){ return; }
			dijit.MasterTooltip.hide();
			this.isShowingNow = false;
		},

		uninitialize: function(){
			this.close();
			for(var event in this._connections){
				dojo.disconnect(this._connectNode, event, this._connections.event);
			}
			this._connections = {};
		}
	}
);
<|endoftext|>


<commit_before>/* convenience functions for routing and API functions */
var express = require('express');
var monk = require('monk');

var Item = require('api/models/Item.js');
var Reservation = require('api/models/Reservation.js');

var winston = require('winston');

module.exports = {
    /* Tests for the existence of given keys in req.body.
     * Returns a rejection promise if a key is not found,
     *  otherwise returns a fulfilled promise.
     */
    checkRequestParameters: function (req) {
        var params = Array.prototype.slice.call(arguments, 1);
        for(let param of params) {
            if(!(param in req.body))
                return Promise.reject("Missing parameter: \'"+param+"\'");
        }
        return Promise.resolve();
    },

    /* Catch handler for API handler functions using promises. */
    apiErrorHandler: function (req, res) {
        return (function (req, res, err) {
            if(err instanceof Error) {
                res.status(500);
                res.send(err.stack);
                winston.log('error', "Error on "+req.method+" request to "+req.originalUrl+" from "+req.socket.remoteAddress+":\n"+err.stack);
            } else {
                res.status(400);
                res.send(err.toString());
                winston.log('error', "Error on "+req.method+" request to "+req.originalUrl+" from "+req.socket.remoteAddress+":\n"+err.toString());
            }
        }).bind(this, req, res);
    },

    /* Sends an object as JSON along with a given response code.
     * If the incoming object is an Item or a Reservation,
     * then it will be converted to a summary before being sent. */
    sendJSON: function(r, c) {
        return (function (res, stat, obj) {
            if(obj instanceof Item || obj instanceof Reservation) {
                return obj.summary().then(
                    (summ) => {
                        res.status(stat).json(summ);
                    }
                );
            } else {
                res.status(stat).json(obj);
            }
        }).bind(this, r, c);
    },

    jsonSuccess: function (r) {
        return module.exports.sendJSON(r, 200);
    },

    emptySuccess: function (r) {
        return (function (res) {
            res.status(204).end();
        }).bind(this, r);
    },
}
<commit_msg>Add convenience functions for error and async handling to routing_common.js<commit_after>/* convenience functions for routing and API functions */
var express = require('express');
var monk = require('monk');

var Item = require('api/models/Item.js');
var Reservation = require('api/models/Reservation.js');

var winston = require('winston');

var APIClientError = function(errorCode, message) {
    Error.call(this, message);
    this.resCode = errorCode;
};

APIClientError.prototype = Object.create(Error.prototype);
APIClientError.prototype.constructor = APIClientError;

module.exports = {
    APIClientError: APIClientError,

    asyncMiddleware: function(fn) {
      return function(req, res, next) {
        Promise.resolve(fn(req, res, next))
          .catch(module.exports.apiErrorHandler(req, res));
      };
    },

    /* Tests for the existence of given keys in req.body.
     * Returns a rejection promise if a key is not found,
     *  otherwise returns a fulfilled promise.
     */
    checkRequestParameters: function (req) {
        var params = Array.prototype.slice.call(arguments, 1);
        for(let param of params) {
            if(!(param in req.body))
                return Promise.reject("Missing parameter: \'"+param+"\'");
        }
        return Promise.resolve();
    },

    /* Catch handler for API handler functions using promises. */
    apiErrorHandler: function (req, res) {
        return (function (req, res, err) {
            if(err instanceof module.exports.APIClientError) {
                res.status(err.resCode);
                res.send(err.toString());
                winston.log('error', "Error "+err.resCode.toString()+" on "+req.method+" request to "+req.originalUrl+" from "+req.socket.remoteAddress+":\n"+err.toString());
            } else if(err instanceof Error) {
                res.status(500);
                res.send(err.stack);
                winston.log('error', "Error on "+req.method+" request to "+req.originalUrl+" from "+req.socket.remoteAddress+":\n"+err.stack);
            } else {
                res.status(400);
                res.send(err.toString());
                winston.log('error', "Error on "+req.method+" request to "+req.originalUrl+" from "+req.socket.remoteAddress+":\n"+err.toString());
            }
        }).bind(this, req, res);
    },

    /* Sends an object as JSON along with a given response code.
     * If the incoming object is an Item or a Reservation,
     * then it will be converted to a summary before being sent. */
    sendJSON: function(r, c) {
        return (function (res, stat, obj) {
            if(obj instanceof Item || obj instanceof Reservation) {
                return obj.summary().then(
                    (summ) => {
                        res.status(stat).json(summ);
                    }
                );
            } else {
                res.status(stat).json(obj);
            }
        }).bind(this, r, c);
    },

    jsonSuccess: function (r) {
        return module.exports.sendJSON(r, 200);
    },

    emptySuccess: function (r) {
        return (function (res) {
            res.status(204).end();
        }).bind(this, r);
    },
}
<|endoftext|>


<commit_before>/**
	* Used to generate data overview from sections.
	* This component should be used to display sections in part B.
*/

'use strict';

var normalizeOptions    = require('es5-ext/object/normalize-options')
  , ensureNaturalNumber = require('es5-ext/object/ensure-natural-number-value')

  , max = Math.max
  , renderValue, renderField, renderFields, renderEntity, renderEntities
  , renderSection, renderMainSection, renderSubSection
  , renderMainSections, renderSubSections
  , defaultRenderers = {};

defaultRenderers.renderValue = renderValue = function (data) {
	if (data && data.kind && exports.customRenderers[data.kind]) {
		return exports.customRenderers[data.kind](data, defaultRenderers);
	}
	return data;
};

defaultRenderers.renderField = renderField = function (data) {
	return tr(th(data.label), td(renderValue(data.value)));
};

defaultRenderers.renderFields = renderFields = function (data) {
	return table(tbody(data.map(renderField)));
};

defaultRenderers.renderEntity = renderEntity = function (data, headerRank) {
	return li(ns['h' + headerRank](data.name), renderMainSections(data.sections, headerRank));
};

defaultRenderers.renderEntities = renderEntities = function (data, headerRank) {
	return ul({ class: 'entity-data-section-entities' },
		data, function (entityData) { return renderEntity(entityData, headerRank); });
};

defaultRenderers.renderSection = renderSection = function (data, className, headerRank) {
	if (data.kind && exports.customRenderers[data.kind]) {
		return exports.customRenderers[data.kind](data, className, headerRank, defaultRenderers);
	}
	return section({ class: className },
		data.label && ns['h' + headerRank](data.label),
		data.fields && renderFields(data.fields),
		data.entities && renderEntities(data.entities, max(headerRank + 1, 6)),
		data.sections && renderSubSections(data.sections, max(headerRank + 1, 6)));
};

defaultRenderers.renderMainSection = renderMainSection = function (data, headerRank) {
	return renderSection(data, 'entity-data-section', headerRank);
};

defaultRenderers.renderSubSection = renderSubSection = function (data, headerRank) {
	return renderSection(data, 'entity-data-section-sub', headerRank);
};

defaultRenderers.renderMainSections = renderMainSections = function (data, headerRank) {
	return data.map(function (sectionData) { return renderMainSection(sectionData, headerRank); });
};

defaultRenderers.renderSubSections = renderSubSections = function (data, headerRank) {
	return data.map(function (sectionData) { return renderSubSection(sectionData, headerRank); });
};

module.exports = exports = function (dataForms/*, options*/) {
	var options = normalizeOptions(arguments[1]), headerRank;
	if (options.headerRank != null) headerRank = max(ensureNaturalNumber(options.headerRank), 6);
	if (!headerRank) headerRank = 3;
	return mmap(dataForms._resolved, function (json) {
		return renderMainSections(json, headerRank);
	});
};

exports.customRenderers = {
	fileValue: function (data) {
		return div({ class: 'file-thumb' },
			a({ href: data.url, target: '_blank', class: 'file-thumb-image' },
				img({ src: stUrl(data.thumbUrl) })),
			div({ class: 'file-thumb-actions' },
				span({ class: 'file-thumb-document-size' }, (data.diskSize / 1000000).toFixed(2) + ' Mo'),
				a({ href: data.url, target: '_blank', class: 'file-thumb-action' },
					span({ class: 'fa fa-download' }, "download"))));
	}
};
<commit_msg>Fix signature and headers computation<commit_after>/**
	* Used to generate data overview from sections.
	* This component should be used to display sections in part B.
*/

'use strict';

var normalizeOptions    = require('es5-ext/object/normalize-options')
  , ensureNaturalNumber = require('es5-ext/object/ensure-natural-number-value')

  , min = Math.min
  , renderValue, renderField, renderFields, renderEntity, renderEntities
  , renderSection, renderMainSection, renderSubSection
  , renderMainSections, renderSubSections
  , defaultRenderers = {};

defaultRenderers.renderValue = renderValue = function (data) {
	if (data && data.kind && exports.customRenderers[data.kind]) {
		return exports.customRenderers[data.kind](data, defaultRenderers);
	}
	return data;
};

defaultRenderers.renderField = renderField = function (data) {
	return tr(th(data.label), td(renderValue(data.value)));
};

defaultRenderers.renderFields = renderFields = function (data) {
	return table(tbody(data.map(renderField)));
};

defaultRenderers.renderEntity = renderEntity = function (data, headerRank) {
	return li(ns['h' + headerRank](data.name), renderMainSections(data.sections, headerRank));
};

defaultRenderers.renderEntities = renderEntities = function (data, headerRank) {
	return ul({ class: 'entity-data-section-entities' },
		data, function (entityData) { return renderEntity(entityData, headerRank); });
};

defaultRenderers.renderSection = renderSection = function (data, className, headerRank) {
	if (data.kind && exports.customRenderers[data.kind]) {
		return exports.customRenderers[data.kind](data, className, headerRank, defaultRenderers);
	}
	return section({ class: className },
		data.label && ns['h' + headerRank](data.label),
		data.fields && renderFields(data.fields),
		data.entities && renderEntities(data.entities, min(headerRank + 1, 6)),
		data.sections && renderSubSections(data.sections, min(headerRank + 1, 6)));
};

defaultRenderers.renderMainSection = renderMainSection = function (data, headerRank) {
	return renderSection(data, 'entity-data-section', headerRank);
};

defaultRenderers.renderSubSection = renderSubSection = function (data, headerRank) {
	return renderSection(data, 'entity-data-section-sub', headerRank);
};

defaultRenderers.renderMainSections = renderMainSections = function (data, headerRank) {
	return data.map(function (sectionData) { return renderMainSection(sectionData, headerRank); });
};

defaultRenderers.renderSubSections = renderSubSections = function (data, headerRank) {
	return data.map(function (sectionData) { return renderSubSection(sectionData, headerRank); });
};

module.exports = exports = function (dataSnapshot/*, options*/) {
	var options = normalizeOptions(arguments[1]), headerRank;
	if (options.headerRank != null) headerRank = min(ensureNaturalNumber(options.headerRank), 6);
	if (!headerRank) headerRank = 3;
	return mmap(dataSnapshot._resolved, function (json) {
		return renderMainSections(json, headerRank);
	});
};

exports.customRenderers = {
	fileValue: function (data) {
		return div({ class: 'file-thumb' },
			a({ href: data.url, target: '_blank', class: 'file-thumb-image' },
				img({ src: stUrl(data.thumbUrl) })),
			div({ class: 'file-thumb-actions' },
				span({ class: 'file-thumb-document-size' }, (data.diskSize / 1000000).toFixed(2) + ' Mo'),
				a({ href: data.url, target: '_blank', class: 'file-thumb-action' },
					span({ class: 'fa fa-download' }, "download"))));
	}
};
<|endoftext|>


<commit_before>// LICENSE : MIT
"use strict";
var assert = require("power-assert");
var parse = require("../");
var Syntax = require("./union-syntax");
var inspect = function (obj) {
    return JSON.stringify(obj, null, 4);
};
var traverse = require("traverse");
function findFirstTypedNode(node, type, value) {
    var result = null;
    traverse(node).forEach(function (x) {
        if (this.notLeaf) {
            if (x.type === type) {
                if (value == null) {
                    result = x;
                } else if (x.raw === value) {
                    result = x;
                }
            }
        }
    });
    if (result == null) {
        console.log("Not Found type:" + type);
        console.log(inspect(node));
    }
    return result;
}
/*
    NOTE:
        `line` start with 1
        `column` start with 0

 */
describe("markdown-parser", function () {
    context('Node type is Document', function () {
        it("should has implemented TxtNode", function () {
            var RootDocument = parse("");
            assert.equal(RootDocument.type, Syntax.Document);
            assert.equal(RootDocument.raw, "");
            assert.deepEqual(RootDocument.loc, {
                start: {
                    line: 1,
                    column: 0
                },
                end: {
                    line: 1,
                    column: 0
                }
            });
            assert.deepEqual(RootDocument.range, [0, 0]);
        });
    });
    /*
        Paragraph > Str
     */
    context("Node type is Paragraph", function () {
        var AST, rawValue;
        beforeEach(function () {
            rawValue = "string";
            AST = parse(rawValue);
        });
        context("Paragraph", function () {
            it("should has implemented TxtNode", function () {
                var node = findFirstTypedNode(AST, Syntax.Paragraph, rawValue);
                assert.equal(node.raw, rawValue);
                assert.deepEqual(node.loc, {
                    start: {
                        line: 1,
                        column: 0
                    },
                    end: {
                        line: 1,
                        column: rawValue.length
                    }
                });
                assert.deepEqual(node.range, [0, rawValue.length]);
            });
        });
        context("Text", function () {
            it("should has implemented TxtNode", function () {
                var node = findFirstTypedNode(AST, Syntax.Str, rawValue);
                assert.equal(node.raw, rawValue);
                assert.deepEqual(node.loc, {
                    start: {
                        line: 1,
                        column: 0
                    },
                    end: {
                        line: 1,
                        column: rawValue.length
                    }
                });
                assert.deepEqual(node.range, [0, rawValue.length]);
            });
        });
    });
    /*
        H1  > Str
     */
    context("Node type is Header", function () {
        var AST, rawValue;
        beforeEach(function () {
            rawValue = "string";
            AST = parse("# " + rawValue);
        });
        context("Header", function () {
            it("should has implemented TxtNode", function () {
                var node = findFirstTypedNode(AST, Syntax.Header, rawValue);
                assert.equal(node.raw, rawValue);
                assert.deepEqual(node.loc, {
                    start: {
                        line: 1,
                        column: 0
                    },
                    end: {
                        line: 1,
                        column: rawValue.length
                    }
                });
                assert.deepEqual(node.range, [0, rawValue.length]);
            });
        });
        context("Str", function () {
            it("should has implemented TxtNode", function () {
                var node = findFirstTypedNode(AST, Syntax.Str, rawValue);
                assert.equal(node.raw, rawValue);
                assert.deepEqual(node.loc, {
                    start: {
                        line: 1,
                        column: 0
                    },
                    end: {
                        line: 1,
                        column: rawValue.length
                    }
                });
                assert.deepEqual(node.range, [0, rawValue.length]);
            });
        });
    });
    context("Node type is Link", function () {
        var AST, rawValue, labelText;
        beforeEach(function () {
            labelText = "text";
            rawValue = "[" + labelText + "](http://example.com)";
            AST = parse(rawValue);
        });
        it("should has implemented TxtNode", function () {
            var node = findFirstTypedNode(AST, Syntax.Link);
            assert.deepEqual(node.loc, {
                start: {
                    line: 1,
                    column: 0
                },
                end: {
                    line: 1,
                    column: rawValue.length
                }
            });
            assert.deepEqual(node.range, [0, rawValue.length]);
        });
    });

    context("Node type is List", function () {
        it("should same the bullet_char", function () {
            var node, AST;
            AST = parse("- item");
            node = findFirstTypedNode(AST, Syntax.ListItem);
            assert(/^\-/.test(node.raw));
            AST = parse("* item");
            node = findFirstTypedNode(AST, Syntax.ListItem);
            assert(/^\*/.test(node.raw));
        });

        it("should have marker_offser", function () {
            var node, AST;
            AST = parse("- item\n" +
            "   - item2");
            console.log(inspect(AST));
        });
        it("should has implemented TxtNode", function () {
            var text = "text",
                rawValue = "- " + text,
                AST = parse(rawValue);
            var node = findFirstTypedNode(AST, Syntax.ListItem);
            assert.equal(node.raw, rawValue);
            assert.deepEqual(node.loc, {
                start: {
                    line: 1,
                    column: 0
                },
                end: {
                    line: 1,
                    column: rawValue.length
                }
            });
            assert.deepEqual(node.range, [0, rawValue.length]);
        });
    });
});<commit_msg>test(parser): add test to ListItem<commit_after>// LICENSE : MIT
"use strict";
var assert = require("power-assert");
var parse = require("../");
var Syntax = require("./union-syntax");
var inspect = function (obj) {
    return JSON.stringify(obj, null, 4);
};
var traverse = require("traverse");
function findFirstTypedNode(node, type, value) {
    var result = null;
    traverse(node).forEach(function (x) {
        if (this.notLeaf) {
            if (x.type === type) {
                if (value == null) {
                    result = x;
                } else if (x.raw === value) {
                    result = x;
                }
            }
        }
    });
    if (result == null) {
        console.log("Not Found type:" + type);
        console.log(inspect(node));
    }
    return result;
}
/*
    NOTE:
        `line` start with 1
        `column` start with 0

 */
describe("markdown-parser", function () {
    context('Node type is Document', function () {
        it("should has implemented TxtNode", function () {
            var RootDocument = parse("");
            assert.equal(RootDocument.type, Syntax.Document);
            assert.equal(RootDocument.raw, "");
            assert.deepEqual(RootDocument.loc, {
                start: {
                    line: 1,
                    column: 0
                },
                end: {
                    line: 1,
                    column: 0
                }
            });
            assert.deepEqual(RootDocument.range, [0, 0]);
        });
    });
    /*
        Paragraph > Str
     */
    context("Node type is Paragraph", function () {
        var AST, rawValue;
        beforeEach(function () {
            rawValue = "string";
            AST = parse(rawValue);
        });
        context("Paragraph", function () {
            it("should has implemented TxtNode", function () {
                var node = findFirstTypedNode(AST, Syntax.Paragraph, rawValue);
                assert.equal(node.raw, rawValue);
                assert.deepEqual(node.loc, {
                    start: {
                        line: 1,
                        column: 0
                    },
                    end: {
                        line: 1,
                        column: rawValue.length
                    }
                });
                assert.deepEqual(node.range, [0, rawValue.length]);
            });
        });
        context("Text", function () {
            it("should has implemented TxtNode", function () {
                var node = findFirstTypedNode(AST, Syntax.Str, rawValue);
                assert.equal(node.raw, rawValue);
                assert.deepEqual(node.loc, {
                    start: {
                        line: 1,
                        column: 0
                    },
                    end: {
                        line: 1,
                        column: rawValue.length
                    }
                });
                assert.deepEqual(node.range, [0, rawValue.length]);
            });
        });
    });
    /*
        H1  > Str
     */
    context("Node type is Header", function () {
        var AST, rawValue;
        beforeEach(function () {
            rawValue = "string";
            AST = parse("# " + rawValue);
        });
        context("Header", function () {
            it("should has implemented TxtNode", function () {
                var node = findFirstTypedNode(AST, Syntax.Header, rawValue);
                assert.equal(node.raw, rawValue);
                assert.deepEqual(node.loc, {
                    start: {
                        line: 1,
                        column: 0
                    },
                    end: {
                        line: 1,
                        column: rawValue.length
                    }
                });
                assert.deepEqual(node.range, [0, rawValue.length]);
            });
        });
        context("Str", function () {
            it("should has implemented TxtNode", function () {
                var node = findFirstTypedNode(AST, Syntax.Str, rawValue);
                assert.equal(node.raw, rawValue);
                assert.deepEqual(node.loc, {
                    start: {
                        line: 1,
                        column: 0
                    },
                    end: {
                        line: 1,
                        column: rawValue.length
                    }
                });
                assert.deepEqual(node.range, [0, rawValue.length]);
            });
        });
    });
    context("Node type is Link", function () {
        var AST, rawValue, labelText;
        beforeEach(function () {
            labelText = "text";
            rawValue = "[" + labelText + "](http://example.com)";
            AST = parse(rawValue);
        });
        it("should has implemented TxtNode", function () {
            var node = findFirstTypedNode(AST, Syntax.Link);
            assert.deepEqual(node.loc, {
                start: {
                    line: 1,
                    column: 0
                },
                end: {
                    line: 1,
                    column: rawValue.length
                }
            });
            assert.deepEqual(node.range, [0, rawValue.length]);
        });
    });

    context("Node type is List", function () {
        it("should same the bullet_char", function () {
            var node, AST;
            AST = parse("- item");
            node = findFirstTypedNode(AST, Syntax.ListItem);
            assert(/^\-/.test(node.raw));
            AST = parse("* item");
            node = findFirstTypedNode(AST, Syntax.ListItem);
            assert(/^\*/.test(node.raw));
        });

        it("should have marker_offser of each items", function () {
            var node, AST;
            AST = parse("- item\n" +
            "   - item2");// second line should has offset
            node = findFirstTypedNode(AST, Syntax.ListItem, "   - item2");
            assert(node);
            assert.equal(node.raw, "   - item2");
        });
        it("should has implemented TxtNode", function () {
            var text = "text",
                rawValue = "- " + text,
                AST = parse(rawValue);
            var node = findFirstTypedNode(AST, Syntax.ListItem);
            assert.equal(node.raw, rawValue);
            assert.deepEqual(node.loc, {
                start: {
                    line: 1,
                    column: 0
                },
                end: {
                    line: 1,
                    column: rawValue.length
                }
            });
            assert.deepEqual(node.range, [0, rawValue.length]);
        });
    });
});<|endoftext|>


<commit_before>'use strict';

const Router = require('express').Router;
const jsonParser = require('body-parser').json();
const createError = require('http-errors');
const debug = require('debug')('decor8:post-router');
const fs = require('fs');
const path = require('path');
const del = require('del');
const AWS = require('aws-sdk');
const multer = require('multer');

const Post = require('../model/post.js');
const Category = require('../model/category.js');
const bearerAuth = require('../lib/bearer-auth-middleware.js');

AWS.config.setPromisesDependency(require('bluebird'));

const s3 = new AWS.S3();
const dataDir = `${__dirname}/../data`;
const upload = multer({ dest: dataDir });

const postRouter = module.exports = new Router();

function s3uploadProm(params) {
  debug('s3uploadProm');

  return new Promise((resolve, reject) => {
    s3.upload(params, (err, data) => {
      if (err) return reject(err);
      resolve(data);
    });
  });
}

postRouter.post('/api/category/:categoryID/post', bearerAuth, jsonParser, upload.single('image'), function(req, res, next) {
  debug('post /api/category/:categoryID/post');

  if(!req.body.name || !req.body.desc){
    return next(createError(400, 'missing required values'));
  }
  let ext = path.extname(req.file.originalname);

  let params = {
    ACL: 'public-read',
    Bucket: process.env.AWS_BUCKET,
    Key: `${req.file.filename}${ext}`,
    Body: fs.createReadStream(req.file.path)
  };

  Category.findById(req.params.categoryID)
  .then( () => s3uploadProm(params))
  .then( s3data => {
    del([`${dataDir}/*`]);
    let postData = {
      name: req.body.name,
      desc: req.body.desc,
      price: req.body.price,
      objectKey:s3data.Key,
      imageURI:s3data.Location,
      userID: req.user._id,
      categoryID:req.params.categoryID
    };
    return Category.findByIdAndAddPost(req.params.categoryID, postData);
  })
  .then( post => res.json(post))
  .catch(err => next(err));

});

postRouter.get('/api/post/:id', bearerAuth, function(req, res, next){
  debug('GET: /api/post/:id');

  Post.findById(req.params.id)
  .populate('comments')
  .then( post => {
    if ( post.userID.toString() !== req.user._id.toString()) {
      return next(createError(401, 'invalid user'));
    }
    res.json(post);
  })
  .catch(next);
});

postRouter.get('/api/post', bearerAuth, function(req, res, next){
  debug('Get: /api/post');

  Post.find({})
  .populate('comments')
  .then(posts => res.json(posts))
  .catch(next);
});

postRouter.put('/api/post/:id', bearerAuth, jsonParser, function(req, res, next){
  debug('PUT: /api/post/:id');

  if(!req.body.name) return next(createError(400, 'name required'));
  if(!req.body.desc) return next(createError(400, 'description required'));

  Post.findByIdAndUpdate(req.params.id, req.body, { new: true })
  .then( post => {
    if ( !post){
      return next(createError(404, 'post not found'));
    }
    res.json(post);
  })
  .catch(next);
});

postRouter.delete('/api/category/:categoryID/post/:id', bearerAuth, function(req, res, next){
  debug('DELETE: /api/category/:categoryID/post/:id');

  Category.findByIdAndRemovePost(req.params.categoryID, req.params.id);

  Post.findByIdAndRemove(req.params.id)
  .then(post => {
    if(!post) return next(createError(404, 'post not found'));
    res.sendStatus(204);
  })
  .catch(next);
});
<commit_msg>allowed all users to acces posts<commit_after>'use strict';

const Router = require('express').Router;
const jsonParser = require('body-parser').json();
const createError = require('http-errors');
const debug = require('debug')('decor8:post-router');
const fs = require('fs');
const path = require('path');
const del = require('del');
const AWS = require('aws-sdk');
const multer = require('multer');

const Post = require('../model/post.js');
const Category = require('../model/category.js');
const bearerAuth = require('../lib/bearer-auth-middleware.js');

AWS.config.setPromisesDependency(require('bluebird'));

const s3 = new AWS.S3();
const dataDir = `${__dirname}/../data`;
const upload = multer({ dest: dataDir });

const postRouter = module.exports = new Router();

function s3uploadProm(params) {
  debug('s3uploadProm');

  return new Promise((resolve, reject) => {
    s3.upload(params, (err, data) => {
      if (err) return reject(err);
      resolve(data);
    });
  });
}

postRouter.post('/api/category/:categoryID/post', bearerAuth, jsonParser, upload.single('image'), function(req, res, next) {
  debug('post /api/category/:categoryID/post');

  if(!req.body.name || !req.body.desc){
    return next(createError(400, 'missing required values'));
  }
  let ext = path.extname(req.file.originalname);

  let params = {
    ACL: 'public-read',
    Bucket: process.env.AWS_BUCKET,
    Key: `${req.file.filename}${ext}`,
    Body: fs.createReadStream(req.file.path)
  };

  Category.findById(req.params.categoryID)
  .then( () => s3uploadProm(params))
  .then( s3data => {
    del([`${dataDir}/*`]);
    let postData = {
      name: req.body.name,
      desc: req.body.desc,
      price: req.body.price,
      objectKey:s3data.Key,
      imageURI:s3data.Location,
      userID: req.user._id,
      categoryID:req.params.categoryID
    };
    return Category.findByIdAndAddPost(req.params.categoryID, postData);
  })
  .then( post => res.json(post))
  .catch(err => next(err));

});

postRouter.get('/api/post/:id', bearerAuth, function(req, res, next){
  debug('GET: /api/post/:id');

  Post.findById(req.params.id)
  .populate('comments')
  .then( post => {
    res.json(post);
  })
  .catch(next);
});

postRouter.get('/api/post', bearerAuth, function(req, res, next){
  debug('Get: /api/post');

  Post.find({})
  .populate('comments')
  .then(posts => res.json(posts))
  .catch(next);
});

postRouter.put('/api/post/:id', bearerAuth, jsonParser, function(req, res, next){
  debug('PUT: /api/post/:id');

  if(!req.body.name) return next(createError(400, 'name required'));
  if(!req.body.desc) return next(createError(400, 'description required'));

  Post.findByIdAndUpdate(req.params.id, req.body, { new: true })
  .then( post => {
    if ( !post){
      return next(createError(404, 'post not found'));
    }
    res.json(post);
  })
  .catch(next);
});

postRouter.delete('/api/category/:categoryID/post/:id', bearerAuth, function(req, res, next){
  debug('DELETE: /api/category/:categoryID/post/:id');

  Category.findByIdAndRemovePost(req.params.categoryID, req.params.id);

  Post.findByIdAndRemove(req.params.id)
  .then(post => {
    if(!post) return next(createError(404, 'post not found'));
    res.sendStatus(204);
  })
  .catch(next);
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import DayPickerInput from 'react-day-picker/DayPickerInput';
import { provideAxis } from 'react-jsx-highstock';
import 'react-day-picker/lib/style.css';
const ONE_DAY = 86400000;

class DateRangePickers extends Component {

  static propTypes = {
    getHighcharts: PropTypes.func.isRequired,
    axisId: PropTypes.string.isRequired,
    dayFormat: PropTypes.oneOfType([ PropTypes.string, PropTypes.array ]).isRequired,
    locale: PropTypes.oneOfType([ PropTypes.string, PropTypes.array ]).isRequired,
    onChangeFromDate: PropTypes.func.isRequired,
    onChangeToDate: PropTypes.func.isRequired,
    className: PropTypes.string.isRequired,
    fromLabel: PropTypes.string,
    toLabel: PropTypes.string,
    datePickerProps: PropTypes.object
  };

  static defaultProps = {
    dayFormat: 'DD MMM YYYY',
    locale: 'en',
    onChangeFromDate: () => {},
    onChangeToDate: () => {},
    className: 'date-range-pickers',
    datePickerProps: {}
  };

  state = {
    min: null,
    max: null
  };

  constructor (props) {
    super(props);

    const langOpts = props.getHighcharts().getOptions().lang;
    const { months: monthsLong, weekdays, shortWeekdays, rangeSelectorFrom, rangeSelectorTo } = langOpts;

    const {
      locale,
      months = monthsLong,
      weekdaysLong = weekdays,
      weekdaysShort = shortWeekdays,
      fromLabel = rangeSelectorFrom,
      toLabel = rangeSelectorTo,
    } = props;

    this.localisation = {
      locale,
      months,
      weekdaysLong,
      weekdaysShort,
      fromLabel,
      toLabel
    };
    //For input field value
		moment.locale(locale, {
			...langOpts
		});
  }

  componentDidMount () {
    const { getHighcharts, getAxis } = this.props;
    const Highcharts = getHighcharts(); // Get Highcharts injected via withHighcharts
    const axis = getAxis();

    Highcharts.addEvent(axis.object, 'afterSetExtremes', this.handleAfterSetExtremes);

    const { min, max } = axis.getExtremes();
    this.setState({
      min,
      max
    });
  }

  componentWillUnmount () {
    const { getHighcharts, getAxis } = this.props;
    const Highcharts = getHighcharts(); // Get Highcharts injected via withHighcharts
    const axis = getAxis();
    if (axis.object) {
      Highcharts.removeEvent(axis.object, 'afterSetExtremes', this.handleAfterSetExtremes);
    }
  }

  handleFromDateChange = callback => {
    return fromDate => {
      const axis = this.props.getAxis();
      let { max } = axis.getExtremes();
      let selectedTime = fromDate.startOf('day').valueOf();

      let newMax = (selectedTime >= max) ? selectedTime + ONE_DAY : max;
      axis.setExtremes(selectedTime, newMax);

      callback(selectedTime);
    };
  }

  handleToDateChange = callback => {
    return toDate => {
      const axis = this.props.getAxis();
      let { min } = axis.getExtremes();
      let selectedTime = toDate.startOf('day').valueOf();

      let newMin = (selectedTime <= min) ? selectedTime - ONE_DAY : min;
      axis.setExtremes(newMin, selectedTime);

      callback(selectedTime);
    };
  }

  handleAfterSetExtremes = e => {
    const { min, max } = e;
    this.setState({
      min,
      max
    });
  }

  render () {
    const axis = this.props.getAxis();
    if (!axis) return null;

    const { fromLabel, toLabel, ...localisationOpts } = this.localisation;
    const {
      dayFormat,
      onChangeFromDate,
      onChangeToDate,
      className,
      datePickerProps
    } = this.props;
    const { min, max } = this.state;

    const fromDate = moment(min).format(dayFormat);
    const toDate = moment(max).format(dayFormat);

    return (

        <span className={`${className}__label ${className}__from-label`}>{fromLabel}:
        <DayPickerInput
          value={fromDate}
          onDayChange={this.handleFromDateChange(onChangeFromDate)}
          format={dayFormat}
          dayPickerProps={{ ...datePickerProps, ...localisationOpts }}
        />
        <span className={`${className}__label ${className}__to-label`}>{toLabel}:
        <DayPickerInput
          value={toDate}
          onDayChange={this.handleToDateChange(onChangeToDate)}
          format={dayFormat}
          dayPickerProps={{ ...datePickerProps, ...localisationOpts }}
        />

    );
  }
}

export default provideAxis(DateRangePickers);
<commit_msg>Use spaces instead tabs<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import DayPickerInput from 'react-day-picker/DayPickerInput';
import { provideAxis } from 'react-jsx-highstock';
import 'react-day-picker/lib/style.css';
const ONE_DAY = 86400000;

class DateRangePickers extends Component {

  static propTypes = {
    getHighcharts: PropTypes.func.isRequired,
    axisId: PropTypes.string.isRequired,
    dayFormat: PropTypes.oneOfType([ PropTypes.string, PropTypes.array ]).isRequired,
    locale: PropTypes.oneOfType([ PropTypes.string, PropTypes.array ]).isRequired,
    onChangeFromDate: PropTypes.func.isRequired,
    onChangeToDate: PropTypes.func.isRequired,
    className: PropTypes.string.isRequired,
    fromLabel: PropTypes.string,
    toLabel: PropTypes.string,
    datePickerProps: PropTypes.object
  };

  static defaultProps = {
    dayFormat: 'DD MMM YYYY',
    locale: 'en',
    onChangeFromDate: () => {},
    onChangeToDate: () => {},
    className: 'date-range-pickers',
    datePickerProps: {}
  };

  state = {
    min: null,
    max: null
  };

  constructor (props) {
    super(props);

    const langOpts = props.getHighcharts().getOptions().lang;
    const { months: monthsLong, weekdays, shortWeekdays, rangeSelectorFrom, rangeSelectorTo } = langOpts;

    const {
      locale,
      months = monthsLong,
      weekdaysLong = weekdays,
      weekdaysShort = shortWeekdays,
      fromLabel = rangeSelectorFrom,
      toLabel = rangeSelectorTo,
    } = props;

    this.localisation = {
      locale,
      months,
      weekdaysLong,
      weekdaysShort,
      fromLabel,
      toLabel
    };
    //For input field value
    moment.locale(locale, {
      ...langOpts
    });
  }

  componentDidMount () {
    const { getHighcharts, getAxis } = this.props;
    const Highcharts = getHighcharts(); // Get Highcharts injected via withHighcharts
    const axis = getAxis();

    Highcharts.addEvent(axis.object, 'afterSetExtremes', this.handleAfterSetExtremes);

    const { min, max } = axis.getExtremes();
    this.setState({
      min,
      max
    });
  }

  componentWillUnmount () {
    const { getHighcharts, getAxis } = this.props;
    const Highcharts = getHighcharts(); // Get Highcharts injected via withHighcharts
    const axis = getAxis();
    if (axis.object) {
      Highcharts.removeEvent(axis.object, 'afterSetExtremes', this.handleAfterSetExtremes);
    }
  }

  handleFromDateChange = callback => {
    return fromDate => {
      const axis = this.props.getAxis();
      let { max } = axis.getExtremes();
      let selectedTime = fromDate.startOf('day').valueOf();

      let newMax = (selectedTime >= max) ? selectedTime + ONE_DAY : max;
      axis.setExtremes(selectedTime, newMax);

      callback(selectedTime);
    };
  }

  handleToDateChange = callback => {
    return toDate => {
      const axis = this.props.getAxis();
      let { min } = axis.getExtremes();
      let selectedTime = toDate.startOf('day').valueOf();

      let newMin = (selectedTime <= min) ? selectedTime - ONE_DAY : min;
      axis.setExtremes(newMin, selectedTime);

      callback(selectedTime);
    };
  }

  handleAfterSetExtremes = e => {
    const { min, max } = e;
    this.setState({
      min,
      max
    });
  }

  render () {
    const axis = this.props.getAxis();
    if (!axis) return null;

    const { fromLabel, toLabel, ...localisationOpts } = this.localisation;
    const {
      dayFormat,
      onChangeFromDate,
      onChangeToDate,
      className,
      datePickerProps
    } = this.props;
    const { min, max } = this.state;

    const fromDate = moment(min).format(dayFormat);
    const toDate = moment(max).format(dayFormat);

    return (

        <span className={`${className}__label ${className}__from-label`}>{fromLabel}:
        <DayPickerInput
          value={fromDate}
          onDayChange={this.handleFromDateChange(onChangeFromDate)}
          format={dayFormat}
          dayPickerProps={{ ...datePickerProps, ...localisationOpts }}
        />
        <span className={`${className}__label ${className}__to-label`}>{toLabel}:
        <DayPickerInput
          value={toDate}
          onDayChange={this.handleToDateChange(onChangeToDate)}
          format={dayFormat}
          dayPickerProps={{ ...datePickerProps, ...localisationOpts }}
        />

    );
  }
}

export default provideAxis(DateRangePickers);
<|endoftext|>


<commit_before><commit_msg>fixing a synch<commit_after>'use strict';

const {Router} = require('express');
const s3Uplaod = require('../lib/s3-upload-middleware.js');
const bearerAuth = require('../lib/bearer-auth-middleware.js');
const User = require('../model/user.js');

const userRouter = module.expoerts = new Router();
userRouter.post('/api/users', bearerAuth,)

// passwordHash: {type: String, required: true},
// userName: {type: String, required: true, unique: true},
// email: {type: String, required: true, unique: true},
// tokenSeed: {type: String, required: true, unique: true},
// });
<|endoftext|>