<commit_before>import React from 'react';

import { Abelito75, emallson, Zerotorescue } from 'CONTRIBUTORS';
import SPELLS from 'common/SPELLS';
import SpellLink from 'common/SpellLink';
import { change, date } from 'common/changelog';

export default [
  change(date(2020, 10, 12), 'Updated checklist to reflect the Shadowlands changes.', emallson),
  change(date(2020, 10, 6), <>Added Fallen Order statistic.</>, Abelito75),
  change(date(2020, 9, 5), <>Updated Brewmaster spells for Shadowlands.</>, emallson),
  change(date(2020, 5, 4), <>Fixed bug in <SpellLink id={SPELLS.CELESTIAL_FORTUNE_HEAL.id} /> handling of absorbs.</>, emallson),
  change(date(2020, 3, 10), <>Updated hit tracking for Ny'alotha and bumped compatability to 8.3.</>, emallson),
  change(date(2019, 12, 22), <>Warning threshold for <SpellLink id={SPELLS.HEAVY_STAGGER_DEBUFF.id} /> / <SpellLink id={SPELLS.PURIFYING_BREW.id} /> is now calculated based on time spent in red stagger.</>, emallson),
  change(date(2019, 10, 28), <>Added support for items in the <SpellLink id={SPELLS.CELESTIAL_FORTUNE_HEAL.id} /> tab.</>, Abelito75),
  change(date(2019, 10, 16), <>Removed <SpellLink id={SPELLS.ARCANE_TORRENT_ENERGY.id} /> from Brewmaster suggestions.</>, emallson),
  change(date(2019, 9, 27), <>Update to date for 8.2.5 </>,Abelito75),
  change(date(2019, 7, 20), 'Updated hit-tracking blacklist and internal constants for Eternal Palace.', emallson),
  change(date(2019, 6, 28), <>Added a <SpellLink id={SPELLS.HOT_TRUB.id} /> damage estimator. Nerf sucks :(</>, [emallson]),
  change(date(2019, 4, 11), <>Fixed a bug in the Mitigation Values tab that caused Mastery's base 8% to be counted towards contribution by Mastery Rating.</>, [emallson]),
  change(date(2019, 3, 10), <>Fixed a bug in the Ironskin Brew normalizer that led to a crash in the new timeline.</>, [Zerotorescue]),
  change(date(2019, 2, 16), <>Removed <SpellLink id={SPELLS.BREATH_OF_FIRE.id} /> from the checklist.</>, [emallson]),
  change(date(2019, 1, 31), <>Added Mitigation Values tab showing estimated stat values for damage mitigation.</>, [emallson]),
  change(date(2018, 12, 30), <>Added <SpellLink id={SPELLS.STRAIGHT_NO_CHASER.id} /> module.</>, [emallson]),
  change(date(2018, 12, 29), <>Added <SpellLink id={SPELLS.GIFT_OF_THE_OX_1.id} /> healing statistic.</>, [emallson]),
  change(date(2018, 10, 26), <>Added <SpellLink id={SPELLS.CELESTIAL_FORTUNE_HEAL.id} /> healing statistic and table.</>, [emallson]),
  change(date(2018, 10, 22), <>The <SpellLink id={SPELLS.MASTERY_ELUSIVE_BRAWLER.id} /> module now loads on-demand, improving load times for lower-end devices.</>, [emallson]),
  change(date(2018, 10, 15), <>Added <SpellLink id={SPELLS.PURIFYING_BREW.id} /> checklist item.</>, [emallson]),
  change(date(2018, 10, 2), <>Re-enabled the <SpellLink id={SPELLS.MASTERY_ELUSIVE_BRAWLER.id} /> module and added additional distribution information to it.</>, [emallson]),
  change(date(2018, 9, 27), 'Updated Stagger plot to show very quick purifies more accurately.', [emallson]),
  change(date(2018, 9, 22), <>Updated Ironskin Brew and <SpellLink id={SPELLS.BREATH_OF_FIRE.id} /> suggestions to use hits mitigated instead of uptime.</>, [emallson]),
  change(date(2018, 9, 22), <>Added support for <SpellLink id={SPELLS.FIT_TO_BURST.id} />.</>, [emallson]),
  change(date(2018, 9, 13), <>Added support for <SpellLink id={SPELLS.ELUSIVE_FOOTWORK.id} />.</>, [emallson]),
  change(date(2018, 8, 11), <>Added support for <SpellLink id={SPELLS.STAGGERING_STRIKES.id} />.</>, [emallson]),
  change(date(2018, 7, 22), <>Updated support for Soul of the Grandmaster legendary and temporarily disabled the <SpellLink id={SPELLS.MASTERY_ELUSIVE_BRAWLER.id} /> module pending new formula coefficients.</>, [emallson]),
  change(date(2018, 7, 18), <>Added support for <SpellLink id={SPELLS.LIGHT_BREWING_TALENT.id} />.</>, [emallson]),
  change(date(2018, 7, 15), <>Added <SpellLink id={SPELLS.TRAINING_OF_NIUZAO.id} /> support.</>, [emallson]),
  change(date(2018, 6, 16), <>Updated Ironskin Brew cooldown and duration and added Guard, along with other changes in beta build 26812.</>, [emallson]),
];
<commit_msg>changelog<commit_after>import React from 'react';

import { Abelito75, emallson, Zerotorescue, Dambroda } from 'CONTRIBUTORS';
import SPELLS from 'common/SPELLS';
import SpellLink from 'common/SpellLink';
import { change, date } from 'common/changelog';

export default [
  change(date(2020, 10, 17), 'Added some missing abilities and updated ability cooldowns.', Dambroda),
  change(date(2020, 10, 12), 'Updated checklist to reflect the Shadowlands changes.', emallson),
  change(date(2020, 10, 6), <>Added Fallen Order statistic.</>, Abelito75),
  change(date(2020, 9, 5), <>Updated Brewmaster spells for Shadowlands.</>, emallson),
  change(date(2020, 5, 4), <>Fixed bug in <SpellLink id={SPELLS.CELESTIAL_FORTUNE_HEAL.id} /> handling of absorbs.</>, emallson),
  change(date(2020, 3, 10), <>Updated hit tracking for Ny'alotha and bumped compatability to 8.3.</>, emallson),
  change(date(2019, 12, 22), <>Warning threshold for <SpellLink id={SPELLS.HEAVY_STAGGER_DEBUFF.id} /> / <SpellLink id={SPELLS.PURIFYING_BREW.id} /> is now calculated based on time spent in red stagger.</>, emallson),
  change(date(2019, 10, 28), <>Added support for items in the <SpellLink id={SPELLS.CELESTIAL_FORTUNE_HEAL.id} /> tab.</>, Abelito75),
  change(date(2019, 10, 16), <>Removed <SpellLink id={SPELLS.ARCANE_TORRENT_ENERGY.id} /> from Brewmaster suggestions.</>, emallson),
  change(date(2019, 9, 27), <>Update to date for 8.2.5 </>,Abelito75),
  change(date(2019, 7, 20), 'Updated hit-tracking blacklist and internal constants for Eternal Palace.', emallson),
  change(date(2019, 6, 28), <>Added a <SpellLink id={SPELLS.HOT_TRUB.id} /> damage estimator. Nerf sucks :(</>, [emallson]),
  change(date(2019, 4, 11), <>Fixed a bug in the Mitigation Values tab that caused Mastery's base 8% to be counted towards contribution by Mastery Rating.</>, [emallson]),
  change(date(2019, 3, 10), <>Fixed a bug in the Ironskin Brew normalizer that led to a crash in the new timeline.</>, [Zerotorescue]),
  change(date(2019, 2, 16), <>Removed <SpellLink id={SPELLS.BREATH_OF_FIRE.id} /> from the checklist.</>, [emallson]),
  change(date(2019, 1, 31), <>Added Mitigation Values tab showing estimated stat values for damage mitigation.</>, [emallson]),
  change(date(2018, 12, 30), <>Added <SpellLink id={SPELLS.STRAIGHT_NO_CHASER.id} /> module.</>, [emallson]),
  change(date(2018, 12, 29), <>Added <SpellLink id={SPELLS.GIFT_OF_THE_OX_1.id} /> healing statistic.</>, [emallson]),
  change(date(2018, 10, 26), <>Added <SpellLink id={SPELLS.CELESTIAL_FORTUNE_HEAL.id} /> healing statistic and table.</>, [emallson]),
  change(date(2018, 10, 22), <>The <SpellLink id={SPELLS.MASTERY_ELUSIVE_BRAWLER.id} /> module now loads on-demand, improving load times for lower-end devices.</>, [emallson]),
  change(date(2018, 10, 15), <>Added <SpellLink id={SPELLS.PURIFYING_BREW.id} /> checklist item.</>, [emallson]),
  change(date(2018, 10, 2), <>Re-enabled the <SpellLink id={SPELLS.MASTERY_ELUSIVE_BRAWLER.id} /> module and added additional distribution information to it.</>, [emallson]),
  change(date(2018, 9, 27), 'Updated Stagger plot to show very quick purifies more accurately.', [emallson]),
  change(date(2018, 9, 22), <>Updated Ironskin Brew and <SpellLink id={SPELLS.BREATH_OF_FIRE.id} /> suggestions to use hits mitigated instead of uptime.</>, [emallson]),
  change(date(2018, 9, 22), <>Added support for <SpellLink id={SPELLS.FIT_TO_BURST.id} />.</>, [emallson]),
  change(date(2018, 9, 13), <>Added support for <SpellLink id={SPELLS.ELUSIVE_FOOTWORK.id} />.</>, [emallson]),
  change(date(2018, 8, 11), <>Added support for <SpellLink id={SPELLS.STAGGERING_STRIKES.id} />.</>, [emallson]),
  change(date(2018, 7, 22), <>Updated support for Soul of the Grandmaster legendary and temporarily disabled the <SpellLink id={SPELLS.MASTERY_ELUSIVE_BRAWLER.id} /> module pending new formula coefficients.</>, [emallson]),
  change(date(2018, 7, 18), <>Added support for <SpellLink id={SPELLS.LIGHT_BREWING_TALENT.id} />.</>, [emallson]),
  change(date(2018, 7, 15), <>Added <SpellLink id={SPELLS.TRAINING_OF_NIUZAO.id} /> support.</>, [emallson]),
  change(date(2018, 6, 16), <>Updated Ironskin Brew cooldown and duration and added Guard, along with other changes in beta build 26812.</>, [emallson]),
];
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * [description]
 *
 * @name Phaser.Physics.Arcade.Components.Bounce
 * @since 3.0.0
 */
var Bounce = {

    /**
     * [description]
     *
     * @method Phaser.Physics.Arcade.Components.Bounce#setBounce
     * @since 3.0.0
     *
     * @param {number} x - [description]
     * @param {number} [y=x] - [description]
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setBounce: function (x, y)
    {
        this.body.bounce.set(x, y);

        return this;
    },

    /**
     * [description]
     *
     * @method Phaser.Physics.Arcade.Components.Bounce#setBounceX
     * @since 3.0.0
     *
     * @param {number} value - [description]
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setBounceX: function (value)
    {
        this.body.bounce.x = value;

        return this;
    },

    /**
     * [description]
     *
     * @method Phaser.Physics.Arcade.Components.Bounce#setBounceY
     * @since 3.0.0
     *
     * @param {number} value - [description]
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setBounceY: function (value)
    {
        this.body.bounce.y = value;

        return this;
    },

    /**
     * [description]
     *
     * @method Phaser.Physics.Arcade.Components.Bounce#setCollideWorldBounds
     * @since 3.0.0
     *
     * @param {number} value - [description]
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setCollideWorldBounds: function (value)
    {
        this.body.collideWorldBounds = value;

        return this;
    }

};

module.exports = Bounce;
<commit_msg>Fix setCollideWorldBounds param type for Arcade<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

/**
 * [description]
 *
 * @name Phaser.Physics.Arcade.Components.Bounce
 * @since 3.0.0
 */
var Bounce = {

    /**
     * [description]
     *
     * @method Phaser.Physics.Arcade.Components.Bounce#setBounce
     * @since 3.0.0
     *
     * @param {number} x - [description]
     * @param {number} [y=x] - [description]
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setBounce: function (x, y)
    {
        this.body.bounce.set(x, y);

        return this;
    },

    /**
     * [description]
     *
     * @method Phaser.Physics.Arcade.Components.Bounce#setBounceX
     * @since 3.0.0
     *
     * @param {number} value - [description]
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setBounceX: function (value)
    {
        this.body.bounce.x = value;

        return this;
    },

    /**
     * [description]
     *
     * @method Phaser.Physics.Arcade.Components.Bounce#setBounceY
     * @since 3.0.0
     *
     * @param {number} value - [description]
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setBounceY: function (value)
    {
        this.body.bounce.y = value;

        return this;
    },

    /**
     * [description]
     *
     * @method Phaser.Physics.Arcade.Components.Bounce#setCollideWorldBounds
     * @since 3.0.0
     *
     * @param {boolean} value - [description]
     *
     * @return {Phaser.GameObjects.GameObject} This Game Object.
     */
    setCollideWorldBounds: function (value)
    {
        this.body.collideWorldBounds = value;

        return this;
    }

};

module.exports = Bounce;
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

(function(Mozilla) {
    'use strict';

    var ua = navigator.userAgent;
    var isLikeFirefox = /Iceweasel|IceCat|SeaMonkey|Camino|like\ Firefox/i.test(ua);
    var isFirefox = /\s(Firefox|FxiOS)/.test(ua) && !isLikeFirefox;

    var isWin10 = (ua.indexOf('Windows NT 10') > -1);

    if (window.site.platform === 'windows' && isWin10 && !isFirefox) {
        var mclane = new Mozilla.TrafficCop({
            id: 'experiment_win10_taskbar_funnelcake',
            variations: {
                'f=138': 9, // control build
                'f=139': 9  // taskbar build
            }
        });

        mclane.init();
    }

})(window.Mozilla);
<commit_msg>[bug 1493595] increase sample rate for win10 taskbar experiment<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

(function(Mozilla) {
    'use strict';

    var ua = navigator.userAgent;
    var isLikeFirefox = /Iceweasel|IceCat|SeaMonkey|Camino|like\ Firefox/i.test(ua);
    var isFirefox = /\s(Firefox|FxiOS)/.test(ua) && !isLikeFirefox;

    var isWin10 = (ua.indexOf('Windows NT 10') > -1);

    if (window.site.platform === 'windows' && isWin10 && !isFirefox) {
        var mclane = new Mozilla.TrafficCop({
            id: 'experiment_win10_taskbar_funnelcake',
            variations: {
                'f=138': 18, // control build
                'f=139': 18  // taskbar build
            }
        });

        mclane.init();
    }

})(window.Mozilla);
<|endoftext|>


<commit_before>var fs = require('fs');
var extend = require('util')._extend;
var util = require('../util');
var url = require('url');
var mime = require('mime');
var rules = require('../rules');
var querystring = require('querystring');
var PassThrough = require('stream').PassThrough;
var protoMgr = require('../rules/protocols');
var CRLF_RE = /\r\n|\r|\n/g;
var RAW_FILE_RE = /rawfile/;
var HEADERS_SEP_RE = /(\r?\n(?:\r\n|\r|\n)|\r\r\n?)/;
var MAX_HEADERS_SIZE = 256 * 1024;
var TPL_RE = /(?:dust|tpl|jsonp):$/;

function isTplProtocol(protocol) {
	return TPL_RE.test(protocol);
}

function isRawFileProtocol(protocol) {
	return RAW_FILE_RE.test(protocol);
}

function readFiles(files, callback) {
	var file = files.shift();
	var execCallback = function(err, stat) {
		 if(!err && stat && stat.isFile()) {
			 callback(null, file);
		 } else if (files.length) {
			 readFiles(files, callback);
		 }  else {
			 callback(err || new Error('Not found file ' + file), file);
		 }
	};

	!file || typeof file != 'string' ? execCallback() : fs.stat(file, execCallback);
}

function parseRes(str) {
	if (!str) {
		return {
			statusCode: 200,
			headers: {}
		};
	}
	var headers = str.split(CRLF_RE);
	var firstLine = headers.shift().trim().split(/\s+/g);
	var _headers = {};
	headers.forEach(function(line) {
		var index = line.indexOf(':');
		var value;
		if (index != -1 && (value = line.substring(index + 1).trim())) {
			var name = line.substring(0, index).trim().toLowerCase();
			var list = _headers[name];
			if (list) {
				if (!Array.isArray(list)) {
					_headers[name] = list = [list];
				}
				list.push(value);
			} else {
				_headers[name] = value;
			}
		}
	});
	return {
		statusCode: firstLine[1] || 200,
		headers: _headers
	};
}

function getRawResByValue(body) {
	var headers;
	if (HEADERS_SEP_RE.test(body)) {
		var crlfStr = RegExp.$1;
		var index = body.indexOf(crlfStr);
		headers = body.substring(0, i);
		body = body.substring(i + crlfStr.length);
	}
	reader = parseRes(headers);
	reader.body = body;
	return reader;
}

function getRawResByPath(protocol, path, callback) {
	var reader = fs.createReadStream(path);
	if (isRawFileProtocol(protocol)) {
		var buffer;
		var response = function(err, crlf) {
			reader.removeAllListeners('data');
			reader.removeAllListeners('error');
			reader.removeAllListeners('end');
			var stream = reader;
			reader = new PassThrough();
			if (err) {
				reader.statusCode = 500;
				reader.headers = {};
				reader.push(err.stack);
				reader.push(null);
			} else if (crlf) {
				crlf = new Buffer(crlf);
				var index = util.indexOfList(buffer, crlf);
				if (index != -1) {
					extend(reader, parseRes(buffer.slice(0, index) + ''));
					buffer = buffer.slice(index + crlf.length);
				}
				reader.push(buffer);
				stream.on('error', function(err) {
					reader.emit('error', err);
				});
				stream.pipe(reader);
			}
			callback(reader);
		}

		reader.on('data', function(data) {
			buffer = buffer ? Buffer.concat([buffer, data]) : data;
			if (HEADERS_SEP_RE.test(buffer + '')) {
				response(null, RegExp.$1);
			} else if (buffer.length > MAX_HEADERS_SIZE) {
				stream.unshift(buffer);
				response();
			}
		});
		reader.on('error', response);
		reader.on('end', response);
	} else {
		reader.statusCode = 200;
		callback(reader);
	}
}

module.exports = function(req, res, next) {
	var options = req.options;
	var config = this.config;
	var protocol = options && options.protocol;
	if (!protoMgr.isFileProxy(protocol)) {
		return next();
	}
	var defaultType = mime.lookup(req.fullUrl.replace(/[?#].*$/, ''), 'text/html');
	var rule = req.rules.rule;
	if (rule.value) {
		var body = util.removeProtocol(rule.value, true);
		var reader = isRawFileProtocol(protocol) ? getRawResByValue(body) : {
				statusCode: 200,
				body: body,
				headers: {
				    	'content-type': (rule.key ? mime.lookup(rule.key, defaultType) : defaultType) + '; charset=utf-8'
				    }
		};

	    if (isTplProtocol(protocol)){
	    	reader.realUrl = rule.matcher;
	    	render(reader);
	    } else {
	    	reader = util.wrapResponse(reader);
	    	reader.realUrl = rule.matcher;
	    	res.response(reader);
	    }
		return;
	}

	readFiles(util.getRuleFiles(rule), function(err, path) {
		if (err) {
	    	if (/^x/.test(protocol)) {
				  extend(options, url.parse(/^xs/.test(protocol) ? req.fullUrl.replace(/^http:/, 'https:') : req.fullUrl));
				  next();
			  } else {
				  var notFound = util.wrapResponse({
						statusCode: 404,
						body: 'Not found file ' + path + '',
						headers: {
						    	'content-type': 'text/html; charset=utf-8'
						    }
				  });
				  notFound.realUrl = path;
				  res.response(notFound);
			  }
	    	return;
	    }

		var headers = {
	    		'server': config.name,
		    	'content-type': mime.lookup(path, defaultType) + '; charset=utf-8'
		    };

	    if (isTplProtocol(protocol)) {
	    	var reader = {
	    			statusCode: 200,
	    			realUrl: path,
	    			headers: headers
	    	};
	    	fs.readFile(path, {encoding: 'utf8'}, function(err, data) {
	    		if (err) {
	    			return util.emitError(req, err);
	    		}
	    		reader.body = data;
	    		render(reader);
	    	});
	    } else {
	    	getRawResByPath(protocol, path, function(reader) {
	    		reader.realUrl = path;
	    		reader.headers = reader.headers || headers;
	    		res.response(reader);
	    	});
	    }
	});

	function render(reader) {
		if (reader.body) {
			var data = querystring.parse(util.getQueryString(req.fullUrl));
			if (!util.isEmptyObject(data)) {
				reader.body = reader.body.replace(/\{([\w\-$]+)\}/g, function(all, matched) {
					return matched in data ? data[matched] : all;
				});
			}
		}
		var realUrl = reader.realUrl;
		reader = util.wrapResponse(reader);
		reader.realUrl = realUrl;
		res.response(reader);
	}
};<commit_msg>feat: Add rawfile<commit_after>var fs = require('fs');
var extend = require('util')._extend;
var util = require('../util');
var url = require('url');
var mime = require('mime');
var rules = require('../rules');
var querystring = require('querystring');
var PassThrough = require('stream').PassThrough;
var protoMgr = require('../rules/protocols');
var CRLF_RE = /\r\n|\r|\n/g;
var RAW_FILE_RE = /rawfile/;
var HEADERS_SEP_RE = /(\r?\n(?:\r\n|\r|\n)|\r\r\n?)/;
var MAX_HEADERS_SIZE = 256 * 1024;
var TPL_RE = /(?:dust|tpl|jsonp):$/;

function isTplProtocol(protocol) {
	return TPL_RE.test(protocol);
}

function isRawFileProtocol(protocol) {
	return RAW_FILE_RE.test(protocol);
}

function readFiles(files, callback) {
	var file = files.shift();
	var execCallback = function(err, stat) {
		 if(!err && stat && stat.isFile()) {
			 callback(null, file);
		 } else if (files.length) {
			 readFiles(files, callback);
		 }  else {
			 callback(err || new Error('Not found file ' + file), file);
		 }
	};

	!file || typeof file != 'string' ? execCallback() : fs.stat(file, execCallback);
}

function parseRes(str) {
	if (!str) {
		return {
			statusCode: 200,
			headers: {}
		};
	}
	var headers = str.split(CRLF_RE);
	var firstLine = headers.shift().trim().split(/\s+/g);
	var _headers = {};
	headers.forEach(function(line) {
		var index = line.indexOf(':');
		var value;
		if (index != -1 && (value = line.substring(index + 1).trim())) {
			var name = line.substring(0, index).trim().toLowerCase();
			var list = _headers[name];
			if (list) {
				if (!Array.isArray(list)) {
					_headers[name] = list = [list];
				}
				list.push(value);
			} else {
				_headers[name] = value;
			}
		}
	});
	return {
		statusCode: firstLine[1] || 200,
		headers: _headers
	};
}

function getRawResByValue(body) {
	var headers;
	if (HEADERS_SEP_RE.test(body)) {
		var crlfStr = RegExp.$1;
		var index = body.indexOf(crlfStr);
		headers = body.substring(0, i);
		body = body.substring(i + crlfStr.length);
	}
	reader = parseRes(headers);
	reader.body = body;
	return reader;
}

function getRawResByPath(protocol, path, callback) {
	var reader = fs.createReadStream(path);
	if (isRawFileProtocol(protocol)) {
		var buffer;
		var response = function(err, crlf) {
			reader.removeAllListeners('data');
			reader.removeAllListeners('error');
			reader.removeAllListeners('end');
			var stream = reader;
			reader = new PassThrough();
			if (err) {
				reader.statusCode = 500;
				reader.headers = {};
				reader.push(err.stack);
				reader.push(null);
			} else {
				if (crlf) {
					crlf = new Buffer(crlf);
					var index = util.indexOfList(buffer, crlf);
					if (index != -1) {
						extend(reader, parseRes(buffer.slice(0, index) + ''));
						buffer = buffer.slice(index + crlf.length);
					}
				}
				buffer && reader.push(buffer);
				stream.on('error', function(err) {
					reader.emit('error', err);
				});
				stream.pipe(reader);
			}
			callback(reader);
		}

		reader.on('data', function(data) {
			buffer = buffer ? Buffer.concat([buffer, data]) : data;
			if (HEADERS_SEP_RE.test(buffer + '')) {
				response(null, RegExp.$1);
			} else if (buffer.length > MAX_HEADERS_SIZE) {
				response();
			}
		});
		reader.on('error', response);
		reader.on('end', response);
	} else {
		reader.statusCode = 200;
		callback(reader);
	}
}

module.exports = function(req, res, next) {
	var options = req.options;
	var config = this.config;
	var protocol = options && options.protocol;
	if (!protoMgr.isFileProxy(protocol)) {
		return next();
	}
	var defaultType = mime.lookup(req.fullUrl.replace(/[?#].*$/, ''), 'text/html');
	var rule = req.rules.rule;
	if (rule.value) {
		var body = util.removeProtocol(rule.value, true);
		var reader = isRawFileProtocol(protocol) ? getRawResByValue(body) : {
				statusCode: 200,
				body: body,
				headers: {
				    	'content-type': (rule.key ? mime.lookup(rule.key, defaultType) : defaultType) + '; charset=utf-8'
				    }
		};

	    if (isTplProtocol(protocol)){
	    	reader.realUrl = rule.matcher;
	    	render(reader);
	    } else {
	    	reader = util.wrapResponse(reader);
	    	reader.realUrl = rule.matcher;
	    	res.response(reader);
	    }
		return;
	}

	readFiles(util.getRuleFiles(rule), function(err, path) {
		if (err) {
	    	if (/^x/.test(protocol)) {
				  extend(options, url.parse(/^xs/.test(protocol) ? req.fullUrl.replace(/^http:/, 'https:') : req.fullUrl));
				  next();
			  } else {
				  var notFound = util.wrapResponse({
						statusCode: 404,
						body: 'Not found file ' + path + '',
						headers: {
						    	'content-type': 'text/html; charset=utf-8'
						    }
				  });
				  notFound.realUrl = path;
				  res.response(notFound);
			  }
	    	return;
	    }

		var headers = {
	    		'server': config.name,
		    	'content-type': mime.lookup(path, defaultType) + '; charset=utf-8'
		    };

	    if (isTplProtocol(protocol)) {
	    	var reader = {
	    			statusCode: 200,
	    			realUrl: path,
	    			headers: headers
	    	};
	    	fs.readFile(path, {encoding: 'utf8'}, function(err, data) {
	    		if (err) {
	    			return util.emitError(req, err);
	    		}
	    		reader.body = data;
	    		render(reader);
	    	});
	    } else {
	    	getRawResByPath(protocol, path, function(reader) {
	    		reader.realUrl = path;
	    		reader.headers = reader.headers || headers;
	    		res.response(reader);
	    	});
	    }
	});

	function render(reader) {
		if (reader.body) {
			var data = querystring.parse(util.getQueryString(req.fullUrl));
			if (!util.isEmptyObject(data)) {
				reader.body = reader.body.replace(/\{([\w\-$]+)\}/g, function(all, matched) {
					return matched in data ? data[matched] : all;
				});
			}
		}
		var realUrl = reader.realUrl;
		reader = util.wrapResponse(reader);
		reader.realUrl = realUrl;
		res.response(reader);
	}
};<|endoftext|>


<commit_before>var _ = require('lodash');
var cheerio = require('cheerio');
var chalk = require('chalk');
var Table = require('cli-table');
var Utility = require('../utility');
var Model = require('../model');

var IgniteModel = function(definition, options) {

  if (!(this instanceof IgniteModel)) return new IgniteModel(definition, options);

  this.options = _.defaults(options || {}, this.options);

  _.extend(this, Model.call(this, definition, options));

};

_.extend(IgniteModel.prototype, Model.prototype);

IgniteModel.prototype.options = {
  table: true,
  table_item_count: 10,
  item_max_length: 50,
  item_format: false
};

IgniteModel.prototype.parse = function(html) {

  var $ = cheerio.load(html);
  var self = this;
  var collection;
  var iteration;

  if (self.type === 'collection') {

    collection = self._parseCollection($);
    iteration = self._parseIteration($);

    // Display parsed models
    if (self.options.table) ((self.options.item_format) ? self._buildCollectionCLiTable(collection) : self._buildIterationCLiTable(iteration));

    // Display summary table
    self._buildSummaryTable(collection.length, (iteration.length - collection.length), iteration.length);

  }

  if (self.type === 'item') {

    if (self.options.item_format) {

      self._buildItemCLiTable(self._applyFilters(self._parseItem($)))

    } else {

      self._buildItemCLiTable(self._parseItem($))

    }

  }

  return Model.prototype.parse.call(this, html);

};

IgniteModel.prototype._buildItemCLiTable = function(item) {

  var table = new Table({
    style: {
      head: [ 'blue' ]
    }
  });
  var row = {};

  _.forOwn(item, function(val, key) {

    row = {};
    row[key] = val;
    table.push(row);

  });

  return console.log(table.toString())

};

IgniteModel.prototype._buildCollectionCLiTable = function(collection) {

  var self = this;
  var table = new Table({
        head: _.keys(self.elements),
        style: {
          head: [ 'blue' ]
        }
      });

  _.chain(collection)
    .first(_.parseInt(self.options.table_item_count))
    .map(function(item) {

      return _.chain(item)
        .values()
        .map(Utility.truncateString(_.parseInt(self.options.item_max_length)))
        .value()

    })
    .map(function(item) {

      table.push(item)

    });

  return console.log(table.toString())

};

IgniteModel.prototype._buildIterationCLiTable = function(iteration) {

  var self = this;
  var item;
  var table = new Table({
      head: _.keys(self.elements),
      style: {
        head: [ 'blue' ]
      }
    });

  _.chain(iteration)
    .first(_.parseInt(self.options.table_item_count))
    .map(function($) {

      item = self._parseItem($);

      return _.chain(item)
        .values()
        .map(Utility.truncateString(_.parseInt(self.options.item_max_length)))
        .map(function(property) {

          return self.validate(item) ? chalk.white(property) : chalk.gray(property)

        })
        .value()

    })
    .map(function(item) {

      table.push(item)

    });

  return console.log(table.toString())

};

IgniteModel.prototype._buildSummaryTable = function(valid, rejected, total) {

  var table = new Table({
    style: {
      head: [ 'white' ]
    }
  });

  table.push(
    { Total: chalk.yellow(total) },
    { '\u2717 Rejected': chalk.red(rejected) },
    { '\u2713 Valid': chalk.green(valid) }
  );

  return console.log(table.toString())

};

module.exports = IgniteModel;
<commit_msg>Added display of model name to ignite-model<commit_after>var _ = require('lodash');
var cheerio = require('cheerio');
var chalk = require('chalk');
var Table = require('cli-table');
var Utility = require('../utility');
var Model = require('../model');

var IgniteModel = function(definition, options) {

  if (!(this instanceof IgniteModel)) return new IgniteModel(definition, options);

  this.options = _.defaults(options || {}, this.options);

  _.extend(this, Model.call(this, definition, options));

};

_.extend(IgniteModel.prototype, Model.prototype);

IgniteModel.prototype.options = {
  table: true,
  table_item_count: 10,
  item_max_length: 50,
  item_format: false
};

IgniteModel.prototype.parse = function(html) {

  var $ = cheerio.load(html);
  var self = this;
  var collection;
  var iteration;

  console.log(chalk.gray('Model: ') + chalk.cyan(self.name));

  if (self.type === 'collection') {

    collection = self._parseCollection($);
    iteration = self._parseIteration($);

    // Display parsed models
    if (self.options.table) ((self.options.item_format) ? self._buildCollectionCLiTable(collection) : self._buildIterationCLiTable(iteration));

    // Display summary table
    self._buildSummaryTable(collection.length, (iteration.length - collection.length), iteration.length);

  }

  if (self.type === 'item') {

    if (self.options.item_format) {

      self._buildItemCLiTable(self._applyFilters(self._parseItem($)))

    } else {

      self._buildItemCLiTable(self._parseItem($))

    }

  }

  return Model.prototype.parse.call(this, html);

};

IgniteModel.prototype._buildItemCLiTable = function(item) {

  var table = new Table({
    style: {
      head: [ 'blue' ]
    }
  });
  var row = {};

  _.forOwn(item, function(val, key) {

    row = {};
    row[key] = val;
    table.push(row);

  });

  return console.log(table.toString())

};

IgniteModel.prototype._buildCollectionCLiTable = function(collection) {

  var self = this;
  var table = new Table({
        head: _.keys(self.elements),
        style: {
          head: [ 'blue' ]
        }
      });

  _.chain(collection)
    .first(_.parseInt(self.options.table_item_count))
    .map(function(item) {

      return _.chain(item)
        .values()
        .map(Utility.truncateString(_.parseInt(self.options.item_max_length)))
        .value()

    })
    .map(function(item) {

      table.push(item)

    });

  return console.log(table.toString())

};

IgniteModel.prototype._buildIterationCLiTable = function(iteration) {

  var self = this;
  var item;
  var table = new Table({
      head: _.keys(self.elements),
      style: {
        head: [ 'blue' ]
      }
    });

  _.chain(iteration)
    .first(_.parseInt(self.options.table_item_count))
    .map(function($) {

      item = self._parseItem($);

      return _.chain(item)
        .values()
        .map(Utility.truncateString(_.parseInt(self.options.item_max_length)))
        .map(function(property) {

          return self.validate(item) ? chalk.white(property) : chalk.gray(property)

        })
        .value()

    })
    .map(function(item) {

      table.push(item)

    });

  return console.log(table.toString())

};

IgniteModel.prototype._buildSummaryTable = function(valid, rejected, total) {

  var table = new Table({
    style: {
      head: [ 'white' ]
    }
  });

  table.push(
    { Total: chalk.yellow(total) },
    { '\u2717 Rejected': chalk.red(rejected) },
    { '\u2713 Valid': chalk.green(valid) }
  );

  return console.log(table.toString())

};

module.exports = IgniteModel;
<|endoftext|>


<commit_before>/*
 * logs.js: Commands related to user resources
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var winston = require('winston'),
    jitsu = require('../../jitsu');

var logs = exports;

logs.usage = [
  'The `jitsu logs` commands allow you to read the logs related to your app.',
  'The default number of lines to show is 10.',
  '',
  'Example usages:',
  'jitsu logs all',
  'jitsu logs all <number of lines to show>',
  'jitsu logs app <app name>',
  'jitsu logs app <app name> <number of lines to show>'
];

//
// ### function all (callback)
// #### @callback {function} Continuation to pass control to when complete.
// Queries the log API and retrieves the logs for all of the user's apps
//
logs.all = function (amount, callback) {
  if (!callback) {
    callback = amount;
    amount = 10;
  }

  jitsu.logs.byUser(jitsu.config.get('username'), amount, function (err, apps) {
    if (err) {
      return callback(err);
    }

    if (apps.length === 0) {
      winston.warn('No logs for ' + jitsu.config.get('username').magenta + ' from timespan');
      return callback();
    }

    function sortLength (lname, rname) {
      var llength = apps[lname].data.length,
          rlength = apps[rname].data.length;

      if (llength === rlength) {
        return 0;
      }

      return llength > rlength ? 1 : -1;
    }

    Object.keys(apps).sort(sortLength).forEach(function (app) {
      putLogs(apps[app], app, amount, true);
    });

    callback();
  });
};

logs.all.usage = [
  'Print the logs from all applications. The default number of',
  'lines to show is 10.',
  'jits logs all <number of lines to show>',
  '',
  'Example usage:',
  'jitsu logs all',
  'jitsu logs all 5'
];

//
// ### function app (appName, callback)
// #### @appName {string} the application to get the logs for
// #### @callback {function} Continuation to pass control to when complete.
// Queries the log API and retrieves the logs for the specified application
//
logs.app = function (appName, amount, callback) {

  // This is defined so that it can get called once all the arguments are
  // sorted out.
  var byApp = function (appName, amount, callback) {

    if(appName.search('/') === -1){
      appName = jitsu.config.get('username') + '/' + appName;
    }

    jitsu.logs.byApp(appName, amount, function (err, results) {
      if (err) {
        return callback(err);
      }
      putLogs(results, appName, amount);
      callback();
    });
  }

  function getAppName(callback) {
    jitsu.package.read(process.cwd(), function (err, pkg) {
      if (!err) {
        return callback(null, pkg.name);
      }
      jitsu.commands.commands.apps.list(function (err) {
        if (err) {
          return callback(err);
        } else {
          winston.error('You need to provide an app name');
          jitsu.prompt.get(["app name"], function (err, result) {
            if (err) {
              // Handle the error
              winston.error('Prompt error:');
              return callback(err);
            } else {
              // Plug in the app name and go
              appName = result["app name"];
              callback(null, appName);
            }
          });
        }
      });
    });
  }

  // Handle missing arguments
  if (typeof appName === 'function') {
    callback = appName;
    getAppName(function (err, name) {
      if (err) {
        return callback(err);
      }
      byApp(name, 100, callback);
    });
  } else if (callback === undefined) {
    callback = amount;
    amount = 100;
    byApp(appName, amount, callback);
  } else {
    byApp(appName, amount, callback);
  }
}

logs.app.usage = [
  'Print the logs from specified application. The default number of',
  'lines to show is 10.',
  'jits logs app <app name> <number of lines to show>',
  '',
  'Example usage:',
  'jitsu logs app test',
  'jitsu logs app test 40'
];

//
// ### function putLogs (results, appName, amount, showApp)
// #### @results {Object} Logs object to output.
// #### @appName {string} App name associated with the log text.
// #### @showApp {boolean} Value indicating if the app name should be output.
// Parses, formats, and outputs the specified `results` to the user.
//
function putLogs (results, appName, amount, showApp) {
  results.data = results.data.filter(function (item) {
    return item.json && item.json.hasOwnProperty('desc');
  });

  if (results.data.length === 0) {
    return winston.warn('No logs for ' + appName.magenta + ' in specified timespan');
  }

  var logged = 0,
      loglength = jitsu.config.get('loglength');

  results.data.reverse().forEach(function (datum) {
    if (datum.json && datum.json.desc != null) {
      datum.json.desc.split('\n').forEach(function (line) {
        var prefix = showApp
          ? datum.timestamp.grey + ' ' + datum.json.app.magenta + ': '
          : datum.timestamp.grey + ': '

        if (line.length > 0 && logged < amount) {
          if (line.length > loglength) {
            line = line.substr(0, loglength - 3) + '...';
          }

          winston.data(prefix + line);
          logged += 1;
        }
      });
    }
  });
}
<commit_msg>[fix] Fix for change in field name in log output from API.<commit_after>/*
 * logs.js: Commands related to user resources
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var winston = require('winston'),
    jitsu = require('../../jitsu');

var logs = exports;

logs.usage = [
  'The `jitsu logs` commands allow you to read the logs related to your app.',
  'The default number of lines to show is 10.',
  '',
  'Example usages:',
  'jitsu logs all',
  'jitsu logs all <number of lines to show>',
  'jitsu logs app <app name>',
  'jitsu logs app <app name> <number of lines to show>'
];

//
// ### function all (callback)
// #### @callback {function} Continuation to pass control to when complete.
// Queries the log API and retrieves the logs for all of the user's apps
//
logs.all = function (amount, callback) {
  if (!callback) {
    callback = amount;
    amount = 10;
  }

  jitsu.logs.byUser(jitsu.config.get('username'), amount, function (err, apps) {
    if (err) {
      return callback(err);
    }

    if (apps.length === 0) {
      winston.warn('No logs for ' + jitsu.config.get('username').magenta + ' from timespan');
      return callback();
    }

    function sortLength (lname, rname) {
      var llength = apps[lname].data.length,
          rlength = apps[rname].data.length;

      if (llength === rlength) {
        return 0;
      }

      return llength > rlength ? 1 : -1;
    }

    Object.keys(apps).sort(sortLength).forEach(function (app) {
      putLogs(apps[app], app, amount, true);
    });

    callback();
  });
};

logs.all.usage = [
  'Print the logs from all applications. The default number of',
  'lines to show is 10.',
  'jits logs all <number of lines to show>',
  '',
  'Example usage:',
  'jitsu logs all',
  'jitsu logs all 5'
];

//
// ### function app (appName, callback)
// #### @appName {string} the application to get the logs for
// #### @callback {function} Continuation to pass control to when complete.
// Queries the log API and retrieves the logs for the specified application
//
logs.app = function (appName, amount, callback) {

  // This is defined so that it can get called once all the arguments are
  // sorted out.
  var byApp = function (appName, amount, callback) {

    if(appName.search('/') === -1){
      appName = jitsu.config.get('username') + '/' + appName;
    }

    jitsu.logs.byApp(appName, amount, function (err, results) {
      if (err) {
        return callback(err);
      }
      putLogs(results, appName, amount);
      callback();
    });
  }

  function getAppName(callback) {
    jitsu.package.read(process.cwd(), function (err, pkg) {
      if (!err) {
        return callback(null, pkg.name);
      }
      jitsu.commands.commands.apps.list(function (err) {
        if (err) {
          return callback(err);
        } else {
          winston.error('You need to provide an app name');
          jitsu.prompt.get(["app name"], function (err, result) {
            if (err) {
              // Handle the error
              winston.error('Prompt error:');
              return callback(err);
            } else {
              // Plug in the app name and go
              appName = result["app name"];
              callback(null, appName);
            }
          });
        }
      });
    });
  }

  // Handle missing arguments
  if (typeof appName === 'function') {
    callback = appName;
    getAppName(function (err, name) {
      if (err) {
        return callback(err);
      }
      byApp(name, 100, callback);
    });
  } else if (callback === undefined) {
    callback = amount;
    amount = 100;
    byApp(appName, amount, callback);
  } else {
    byApp(appName, amount, callback);
  }
}

logs.app.usage = [
  'Print the logs from specified application. The default number of',
  'lines to show is 10.',
  'jits logs app <app name> <number of lines to show>',
  '',
  'Example usage:',
  'jitsu logs app test',
  'jitsu logs app test 40'
];

//
// ### function putLogs (results, appName, amount, showApp)
// #### @results {Object} Logs object to output.
// #### @appName {string} App name associated with the log text.
// #### @showApp {boolean} Value indicating if the app name should be output.
// Parses, formats, and outputs the specified `results` to the user.
//
function putLogs (results, appName, amount, showApp) {
  results.data = results.data.filter(function (item) {
    return item.json && item.json.hasOwnProperty('message');
  });

  if (results.data.length === 0) {
    return winston.warn('No logs for ' + appName.magenta + ' in specified timespan');
  }

  var logged = 0,
      loglength = jitsu.config.get('loglength');

  results.data.reverse().forEach(function (datum) {
    if (datum.json && datum.json.message != null) {
      datum.json.message.split('\n').forEach(function (line) {
        var prefix = showApp
          ? datum.timestamp.grey + ' ' + datum.json.app.magenta + ': '
          : datum.timestamp.grey + ': '

        if (line.length > 0 && logged < amount) {
          if (line.length > loglength) {
            line = line.substr(0, loglength - 3) + '...';
          }

          winston.data(prefix + line);
          logged += 1;
        }
      });
    }
  });
}
<|endoftext|>


<commit_before>import debug from 'debug';
import fs from 'fs';
import sh from 'shelljs';
import { Client } from 'ssh2';

const log = debug('mup:module:default');

sh.config.silent = true;

export function deploy() {
  log('exec => mup deploy');
}

export function init(api) {
  log('exec => mup init');

  const mupJs = api.resolvePath(__dirname, 'template/mup.js.sample');
  const settinsJson = api.resolvePath(__dirname, 'template/settings.json');
  const mupJsDst = api.resolvePath(process.cwd(), 'mup.js');

  const settingsJsonDst = api.resolvePath(process.cwd(), 'settings.json');
  const mupJsExists = fs.existsSync(mupJsDst);
  const settingsJsonExist = fs.existsSync(settingsJsonDst);

  if (!settingsJsonExist) {
    sh.cp(settinsJson, settingsJsonDst);
    console.log('Created settings.json');
  } else {
    console.log('Skipping creation of settings.json.');
    console.log(`settings.json already exist at ${settingsJsonDst}.`);
  }

  if (!mupJsExists) {
    sh.cp(mupJs, mupJsDst);

    console.log('Created mup.js');
    console.log('');
    console.log('Next Steps:');
    console.log('');
    console.log('  Open mup.js and edit the config to meet your needs.');
    console.log('  Required changes have been marked with a TODO comment.');
    console.log('');
    console.log('  Available options can be found in the docs at');
    console.log('    https://github.com/zodern/meteor-up');
    console.log('');
    console.log('  Then, run the command:');
    console.log('    mup setup');
  } else {
    console.log('Skipping creation of mup.js');
    console.log(`mup.js already exists at ${mupJsDst}`);
  }
}

export function logs(api) {
  log('exec => mup logs');
  return api.runCommand('meteor.logs');
}

export function reconfig(api) {
  log('exec => mup reconfig');
  return api.runCommand('meteor.envconfig').then(() => api.runCommand('meteor.start'));
}

export function restart(api) {
  log('exec => mup restart');
  return api.runCommand('meteor.restart');
}

export function setup(api) {
  process.on('exit', function displayNextSteps(code) {
    if (code > 0) {
      return;
    }

    console.log('');
    console.log('Next, you should run:');
    console.log('    mup deploy');
  });

  log('exec => mup setup');
  const config = api.getConfig();
  return api.runCommand('docker.setup')
    .then(() => {
      if (config.proxy) {
        return api.runCommand('proxy.setup');
      }
    });
}

export function start(api) {
  log('exec => mup start');
  return api.runCommand('meteor.start');
}

export function stop(api) {
  log('exec => mup stop');
  return api.runCommand('meteor.stop');
}

export function ssh(api) {
  const servers = api.getConfig().servers;
  const serverOption = api.getArgs()[1];

  if (!(serverOption in servers)) {
    console.log('mup ssh <server>');
    console.log('Available servers are:\n', Object.keys(servers).join('\n'));
    process.exitCode = 1;
    return;
  }

  const server = servers[serverOption];
  const sshOptions = api._createSSHOptions(server);

  var conn = new Client();
  conn.on('ready', function() {
    conn.shell(function(err, stream) {
      if (err) { throw err; }
      stream.on('close', function() {
        conn.end();
        process.exit();
      });

      process.stdin.setRawMode(true);
      process.stdin.pipe(stream);

      stream.pipe(process.stdout);
      stream.stderr.pipe(process.stderr);
      stream.setWindow(process.stdout.rows, process.stdout.columns);

      process.stdout.on('resize', () => {
        stream.setWindow(process.stdout.rows, process.stdout.columns);
      });
    });
  }).connect(sshOptions);
}

export function validate(api) {
  // Shows validation errors
  api.getConfig();

  if (api.getOptions()['show']) {
    console.log(JSON.stringify(api.getConfig(), null, 2));
  }
}
<commit_msg>If there is one server, mup ssh defaults to it<commit_after>import debug from 'debug';
import fs from 'fs';
import sh from 'shelljs';
import { Client } from 'ssh2';

const log = debug('mup:module:default');

sh.config.silent = true;

export function deploy() {
  log('exec => mup deploy');
}

export function init(api) {
  log('exec => mup init');

  const mupJs = api.resolvePath(__dirname, 'template/mup.js.sample');
  const settinsJson = api.resolvePath(__dirname, 'template/settings.json');
  const mupJsDst = api.resolvePath(process.cwd(), 'mup.js');

  const settingsJsonDst = api.resolvePath(process.cwd(), 'settings.json');
  const mupJsExists = fs.existsSync(mupJsDst);
  const settingsJsonExist = fs.existsSync(settingsJsonDst);

  if (!settingsJsonExist) {
    sh.cp(settinsJson, settingsJsonDst);
    console.log('Created settings.json');
  } else {
    console.log('Skipping creation of settings.json.');
    console.log(`settings.json already exist at ${settingsJsonDst}.`);
  }

  if (!mupJsExists) {
    sh.cp(mupJs, mupJsDst);

    console.log('Created mup.js');
    console.log('');
    console.log('Next Steps:');
    console.log('');
    console.log('  Open mup.js and edit the config to meet your needs.');
    console.log('  Required changes have been marked with a TODO comment.');
    console.log('');
    console.log('  Available options can be found in the docs at');
    console.log('    https://github.com/zodern/meteor-up');
    console.log('');
    console.log('  Then, run the command:');
    console.log('    mup setup');
  } else {
    console.log('Skipping creation of mup.js');
    console.log(`mup.js already exists at ${mupJsDst}`);
  }
}

export function logs(api) {
  log('exec => mup logs');
  return api.runCommand('meteor.logs');
}

export function reconfig(api) {
  log('exec => mup reconfig');
  return api.runCommand('meteor.envconfig').then(() => api.runCommand('meteor.start'));
}

export function restart(api) {
  log('exec => mup restart');
  return api.runCommand('meteor.restart');
}

export function setup(api) {
  process.on('exit', function displayNextSteps(code) {
    if (code > 0) {
      return;
    }

    console.log('');
    console.log('Next, you should run:');
    console.log('    mup deploy');
  });

  log('exec => mup setup');
  const config = api.getConfig();
  return api.runCommand('docker.setup')
    .then(() => {
      if (config.proxy) {
        return api.runCommand('proxy.setup');
      }
    });
}

export function start(api) {
  log('exec => mup start');
  return api.runCommand('meteor.start');
}

export function stop(api) {
  log('exec => mup stop');
  return api.runCommand('meteor.stop');
}

export function ssh(api) {
  const servers = api.getConfig().servers;
  let serverOption = api.getArgs()[1];

  if (!(serverOption in servers)) {
    if (Object.keys(servers).length === 1) {
      serverOption = Object.keys(servers)[0];
    } else {
    console.log('mup ssh <server>');
    console.log('Available servers are:\n', Object.keys(servers).join('\n'));
    process.exitCode = 1;
    return;
  }
  }

  const server = servers[serverOption];
  const sshOptions = api._createSSHOptions(server);

  var conn = new Client();
  conn.on('ready', function() {
    conn.shell(function(err, stream) {
      if (err) { throw err; }
      stream.on('close', function() {
        conn.end();
        process.exit();
      });

      process.stdin.setRawMode(true);
      process.stdin.pipe(stream);

      stream.pipe(process.stdout);
      stream.stderr.pipe(process.stderr);
      stream.setWindow(process.stdout.rows, process.stdout.columns);

      process.stdout.on('resize', () => {
        stream.setWindow(process.stdout.rows, process.stdout.columns);
      });
    });
  }).connect(sshOptions);
}

export function validate(api) {
  // Shows validation errors
  api.getConfig();

  if (api.getOptions()['show']) {
    console.log(JSON.stringify(api.getConfig(), null, 2));
  }
}
<|endoftext|>


<commit_before>/* (c) Copyright 2002-2016 by authors of the Tiki Wiki CMS Groupware Project
 *
 * All Rights Reserved. See copyright.txt for details and a complete list of authors.
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
 *
 * $Id$
 *
 * Rewritten for bootstrap tiki 15.x 2015-2016
 * Based on work by Jobi Carter keacarterdev@gmail.com
 */

$.buildAutoToc = function () {
	var $page = $("body"),
		$top = $("#top");

	//if a wiki page, and if there is no toc-off div and not printing
	if ($top.length && !$("#toc-off").length && location.href.indexOf("tiki-print.php") == -1) {

		var $headers = $("h1.pagetitle", "#col1").add($(":header", $top)).not("#toctitle > h3");

		//if there are more than one $headers on the page
		if ($headers.length > 1) {

			var $tocDiv = $("
");

			//create object to store processed IDs.
			var processedId = {};

			//function to process header Id generation. If an ID which has been processed is generated again and passed in again, the id name will be incremented to id_[1*]
			function processId(id) {
				if (id in processedId) {
					//if processed before
					//iterate count for header with this ane
					processedId[id] += 1;
					//set the new id to id plus count for header
					var newId = id + "_" + processedId[id];
				} else {
					//if not processed before
					//add to "dictionary' with count of 0
					processedId[id] = 0;
					//return id passed in
					newId = id;
				}
				return newId;
			}

			// open HTML $list
			var $list = $("
"),
					$currentList = $list,		// pointer to where to add items
					headerLevel,				// how deep we are
					previousHeaderLevel = 0; 	//start from indentation level 0, with header one as base

			//Iterate over the $headers
			$headers.each(function () {

				//get header level for header to see if this header should be processed or not
				var $this = $(this);
				headerLevel = parseInt($this.prop("tagName").substring(1));

				//grab the whole header element to show as the anchor text
				var aText = $.trim($this.text());

				//generate and set id if necessary (if element does not already have an id, create one)
				var id = $this.attr("id");
				if (!id){
					// Set the id to the the inner text of the header, with underscores instead of spaces (" ").
					// processId checks if the ID has been assigned yet, and if so, increments the Id with a number at the end of the id name
					id = processId(aText.replace(/\W/g, "_"));

				} else {
					id = id.replace(":", "\\:").replace(".", "\\.").replace("#", "\\#");
				}
				//set the element's id to the constructed ID
				$this.attr("id", id);
				//construct the anchor URL with chars jquery doesn't like escaped
				var url = "#" + id;

				//create the HTML anchor item with the text from the header and pointing to baseurl#divId
				var $item = $("
" + aText + "
");

				if (previousHeaderLevel && headerLevel > previousHeaderLevel) {	// deeper level

					//open a new sublist for each level of difference
					var $lastItem = $("li:last", $currentList).append($("
"));
					$currentList = $("ul:last", $lastItem);

				} else if (headerLevel < previousHeaderLevel) {					// up some levels

					$currentList = $($currentList.parents("ul")[previousHeaderLevel - headerLevel - 1]);

				}

				$currentList.append($item);

				//set current header level to previous header level for next iteration
				previousHeaderLevel = headerLevel;
			});

			// append the $list
			if (!jqueryTiki.autoToc_inline) {
				$("#page-data").addClass("col-sm-9");
				if (jqueryTiki.autoToc_pos === "left" || jqueryTiki.autoToc_pos === "top") {
					$tocDiv.append($list).css('clear','left').insertBefore('#page-data');
				} else {
					$tocDiv.append($list).css('clear','right').insertAfter('#page-data');
				}

				//Get left offset var for affix (This is needed, specially when there are col-md-pull//push interacting with page-data)
				var leftoffset = $('#autotoc').offset().left;
				$("> .nav", "#autotoc").css('left',leftoffset);
				affix();

				//Fix fixed position and width when resize window
				$(window).resize(function() {
					leftoffset = $('#autotoc').offset().left;
					$("> .nav", "#autotoc").css('left',leftoffset);
					$('#autotoc .nav').width($('#autotoc').width());
					affix();
				});

				// trigger the bootstrap affix and scrollspy
				$page.scrollspy({ target: "#autotoc" , offset: jqueryTiki.autoToc_offset});

				function affix() {
					$("> .nav", "#autotoc").affix({
						offset: {
							top: function () {
								return (this.top = $('#page-data').offset().top - jqueryTiki.autoToc_offset)
							},
							bottom: function () {
								return (this.bottom = $(document).height() - $('#page-data').offset().top - $('#page-data').height() + 10)
							}
						}
					})
					.on('affix.bs.affix', function (e) {
						$(e.target).width($('#autotoc').width());
					});
				}
				//$("> .nav", "#autotoc").affix('checkPosition');//Prevent bottom overlap if page loaded in max-bottom of page (not working)
			} else {
				$tocDiv.prepend($list).prependTo($top);
			}
		}
	}
};

$(document).ready(function () {
	$.buildAutoToc();
});<commit_msg>[FIX] Fix when opening page in the middle of the page, autoToc didn’t have the proper width. Fired a resize event to fix that.<commit_after>/* (c) Copyright 2002-2016 by authors of the Tiki Wiki CMS Groupware Project
 *
 * All Rights Reserved. See copyright.txt for details and a complete list of authors.
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
 *
 * $Id$
 *
 * Rewritten for bootstrap tiki 15.x 2015-2016
 * Based on work by Jobi Carter keacarterdev@gmail.com
 */

$.buildAutoToc = function () {
	var $page = $("body"),
		$top = $("#top");

	//if a wiki page, and if there is no toc-off div and not printing
	if ($top.length && !$("#toc-off").length && location.href.indexOf("tiki-print.php") == -1) {

		var $headers = $("h1.pagetitle", "#col1").add($(":header", $top)).not("#toctitle > h3");

		//if there are more than one $headers on the page
		if ($headers.length > 1) {

			var $tocDiv = $("
");

			//create object to store processed IDs.
			var processedId = {};

			//function to process header Id generation. If an ID which has been processed is generated again and passed in again, the id name will be incremented to id_[1*]
			function processId(id) {
				if (id in processedId) {
					//if processed before
					//iterate count for header with this ane
					processedId[id] += 1;
					//set the new id to id plus count for header
					var newId = id + "_" + processedId[id];
				} else {
					//if not processed before
					//add to "dictionary' with count of 0
					processedId[id] = 0;
					//return id passed in
					newId = id;
				}
				return newId;
			}

			// open HTML $list
			var $list = $("
"),
					$currentList = $list,		// pointer to where to add items
					headerLevel,				// how deep we are
					previousHeaderLevel = 0; 	//start from indentation level 0, with header one as base

			//Iterate over the $headers
			$headers.each(function () {

				//get header level for header to see if this header should be processed or not
				var $this = $(this);
				headerLevel = parseInt($this.prop("tagName").substring(1));

				//grab the whole header element to show as the anchor text
				var aText = $.trim($this.text());

				//generate and set id if necessary (if element does not already have an id, create one)
				var id = $this.attr("id");
				if (!id){
					// Set the id to the the inner text of the header, with underscores instead of spaces (" ").
					// processId checks if the ID has been assigned yet, and if so, increments the Id with a number at the end of the id name
					id = processId(aText.replace(/\W/g, "_"));

				} else {
					id = id.replace(":", "\\:").replace(".", "\\.").replace("#", "\\#");
				}
				//set the element's id to the constructed ID
				$this.attr("id", id);
				//construct the anchor URL with chars jquery doesn't like escaped
				var url = "#" + id;

				//create the HTML anchor item with the text from the header and pointing to baseurl#divId
				var $item = $("
" + aText + "
");

				if (previousHeaderLevel && headerLevel > previousHeaderLevel) {	// deeper level

					//open a new sublist for each level of difference
					var $lastItem = $("li:last", $currentList).append($("
"));
					$currentList = $("ul:last", $lastItem);

				} else if (headerLevel < previousHeaderLevel) {					// up some levels

					$currentList = $($currentList.parents("ul")[previousHeaderLevel - headerLevel - 1]);

				}

				$currentList.append($item);

				//set current header level to previous header level for next iteration
				previousHeaderLevel = headerLevel;
			});

			// append the $list
			if (!jqueryTiki.autoToc_inline) {
				$("#page-data").addClass("col-sm-9");
				if (jqueryTiki.autoToc_pos === "left" || jqueryTiki.autoToc_pos === "top") {
					$tocDiv.append($list).css('clear','left').insertBefore('#page-data');
				} else {
					$tocDiv.append($list).css('clear','right').insertAfter('#page-data');
				}

				//Fix fixed position and width and left offset when resize window
				$(window).resize(function() {
					leftoffset = $('#autotoc').offset().left;
					$("> .nav", "#autotoc").css('left',leftoffset);
					$('#autotoc .nav').width($('#autotoc').width());
					affix();
				}).resize();

				// trigger the bootstrap affix and scrollspy
				$page.scrollspy({ target: "#autotoc" , offset: jqueryTiki.autoToc_offset});

				function affix() {
					$("> .nav", "#autotoc").affix({
						offset: {
							top: function () {
								return (this.top = $('#page-data').offset().top - jqueryTiki.autoToc_offset)
							},
							bottom: function () {
								return (this.bottom = $(document).height() - $('#page-data').offset().top - $('#page-data').height() + 10)
							}
						}
					})
					.on('affix.bs.affix', function (e) {
						$(e.target).width($('#autotoc').width());
					});
				}
				//$("> .nav", "#autotoc").affix('checkPosition');//Prevent bottom overlap if page loaded in max-bottom of page (not working)
			} else {
				$tocDiv.prepend($list).prependTo($top);
			}
		}
	}
};

$(document).ready(function () {
	$.buildAutoToc();
});<|endoftext|>


<commit_before>var Reflux = require('reflux');
var _ = require('underscore');
var Firebase = require('firebase');
var UserActions = require('../actions/UserActions');
var GroupActions = require('../actions/GroupActions');
var GroupStore = require('../stores/GroupStore');

var firebaseRef;

var formatPhoneForFirebase =  function(email){
  var key = email.replace(/\-/, '');
  return key;
};

function setupFirebase() {
  firebaseRef = new Firebase("https://glaring-heat-1654.firebaseio.com/users");
  firebaseRef.on('child_added', snapshot => {
    UserStore.setUsers(snapshot.key(), snapshot.val());
  });

  firebaseRef.on('child_removed', snapshot => {

  });
}

var UserStore = Reflux.createStore({
  _collection: {},
  _currentUser: null,
  listenables: UserActions,
  init() {
    setupFirebase();
  },
  getUser() {
    return this._currentUser;
  },
  updateUser(user) {
    var userRef = this.firebaseRef.child(user.id);
    userRef.update(user);
  },
  setUsers(key, user) {
    this._collection[key] = user;
  },
  setUser(user) {
    this._currentUser = user;
    this.trigger("setUser", {user});
  },
  addUser(user) {
    var key = formatPhoneForFirebase(user.phone);
    firebaseRef.child(key).set(user);
    this.setUser(user);
  },
  login(toLogin) {
    var filtered = _(this._collection).filter(user => {
      return formatPhoneForFirebase(user.phone) === formatPhoneForFirebase(toLogin.phone);
    });
    if (filtered.length === 0) return;
    else this.setUser(filtered[0]);
  },
  logout() {
    this._currentUser = null;
    this.trigger("logout");
  }
});

module.exports = UserStore;
<commit_msg>Added user update<commit_after>var Reflux = require('reflux');
var _ = require('underscore');
var Firebase = require('firebase');
var UserActions = require('../actions/UserActions');
var GroupActions = require('../actions/GroupActions');
var GroupStore = require('../stores/GroupStore');

var firebaseRef;

var formatPhoneForFirebase =  function(email){
  var key = email.replace(/\-/, '');
  return key;
};

function setupFirebase() {
  firebaseRef = new Firebase("https://glaring-heat-1654.firebaseio.com/users");
  firebaseRef.on('child_added', snapshot => {
    UserStore.setUsers(snapshot.key(), snapshot.val());
  });

  firebaseRef.on('child_removed', snapshot => {

  });
}

var UserStore = Reflux.createStore({
  _collection: {},
  _currentUser: null,
  listenables: UserActions,
  init() {
    setupFirebase();
  },
  getUser() {
    return this._currentUser;
  },
  updateUser(hash) {
    var userRef = this.firebaseRef.child(user.id);
    var user = _.extend(this._currentUser, hash);
    userRef.update(user);
  },
  setUsers(key, user) {
    this._collection[key] = user;
  },
  setUser(user) {
    this._currentUser = user;
    this.trigger("setUser", {user});
  },
  addUser(user) {
    var key = formatPhoneForFirebase(user.phone);
    firebaseRef.child(key).set(user);
    this.setUser(user);
  },
  login(toLogin) {
    var filtered = _(this._collection).filter(user => {
      return formatPhoneForFirebase(user.phone) === formatPhoneForFirebase(toLogin.phone);
    });
    if (filtered.length === 0) return;
    else this.setUser(filtered[0]);
  },
  logout() {
    this._currentUser = null;
    this.trigger("logout");
  }
});

module.exports = UserStore;
<|endoftext|>


<commit_before>(function (webgl) {

    /**
     *
     * @param {GLContext} context
     * @param {GLScene} scene
     * @constructor
     */
    var ForwardRenderTree = function (renderInterface, enableSSAO) {
        webgl.BaseRenderTree.call(this, renderInterface);
        var scene = renderInterface.scene;
        scene.addEventListener(webgl.Scene.EVENT_TYPE.LIGHT_STRUCTURE_CHANGED, this.onLightStructureChange.bind(this));
        scene.addEventListener(webgl.Scene.EVENT_TYPE.LIGHT_VALUE_CHANGED, this.onLightValueChange.bind(this));
        scene.addEventListener(webgl.Scene.EVENT_TYPE.SCENE_SHAPE_CHANGED, this.onSceneShapeChange.bind(this));
        scene.addEventListener(webgl.ShaderComposerFactory.EVENT_TYPE.MATERIAL_INITIALIZED, this.onShaderChange.bind(this));
        this._enableSSAO = enableSSAO;
        this.mainPass = null;
        this.createMainPass();
    };

    XML3D.createClass(ForwardRenderTree, webgl.BaseRenderTree);

    XML3D.extend(ForwardRenderTree.prototype, {
        onLightStructureChange: function(evt){
            var light = evt.light;
            if(evt.removed){
                // TODO: Proper clean up ShadowPass
                light.userData = null;
            }
            else{
                if(light.light.type == "spot")
                    light.userData = this.createLightPass(light);
                else if(light.light.type == "directional")
                    light.userData = this.createLightPass(light);
                else if(light.light.type == "point") {
                    light.userData = this.createPointLightPass(light);
                }
            }
            this.reassignLightPasses(evt.target);
        },
        onLightValueChange: function(evt){
            // TODO: Would be great to check of the light position or orientation specifically changed
            // We don't need to invalidate the lightPass otherwise
            if(evt.light.castShadow && evt.light.visible){
                evt.light.userData && evt.light.userData.setProcessed(false);
            }
        },
        onSceneShapeChange: function(evt){
            var scene = evt.target;
            for (var i = 0; i < scene.lights.spot.length; i++) {
                var spotLight = scene.lights.spot[i];
                if(spotLight.castShadow && spotLight.visible)
                    spotLight.userData && spotLight.userData.setProcessed(false);
            }
            for (var i = 0; i < scene.lights.directional.length; i++) {
                var directionalLight = scene.lights.directional[i];
                if(directionalLight.castShadow && directionalLight.visible)
                    directionalLight.userData && directionalLight.userData.setProcessed(false);
            }
            for (var i = 0; i < scene.lights.point.length; i++) {
                var pointLight = scene.lights.point[i];
                if(pointLight.castShadow && pointLight.visible)
                    pointLight.userData && pointLight.userData.setProcessed(false);
            }
        },
        onShaderChange: function(evt) {
            this.reassignLightPasses(evt.target);
        },

        createLightPass: function(light){
            var context = this.renderInterface.context;
            var dimension = Math.max(context.canvasTarget.width, context.canvasTarget.height) * 2;
            var lightFramebuffer  = new webgl.GLRenderTarget(context, {
                width: dimension,
                height: dimension,
                colorFormat: context.gl.RGBA,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });
            var lightPass = new webgl.LightPass(this.renderInterface, lightFramebuffer, light);
            lightPass.init(context);
            return lightPass;
        },

        createPointLightPass: function(light){
            var context = this.renderInterface.context;
            var dimension = Math.max(context.canvasTarget.width, context.canvasTarget.height) * 2;
            var lightFramebuffer  = new webgl.GLCubeMapRenderTarget(context, {
                width: dimension,
                height: dimension,
                colorFormat: context.gl.RGBA,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });
            var lightPass = new webgl.PointLightPass(this.renderInterface, lightFramebuffer, light);
            lightPass.init(context);
            return lightPass;
        },

        reassignLightPasses: function(scene){
            var context = this.renderInterface.context;

            this.mainPass.clearLightPasses();
            for (var i = 0; i < scene.lights.spot.length; i++) {
                var spotLight = scene.lights.spot[i];
                this.mainPass.addLightPass("spotLightShadowMap", spotLight.userData);
                if(!spotLight.castShadow || !spotLight.visible)
                    spotLight.userData.setProcessed(true);
            }
            for (var i = 0; i < scene.lights.directional.length; i++) {
                var directionalLight = scene.lights.directional[i];
                this.mainPass.addLightPass("directionalLightShadowMap", directionalLight.userData);
                if(!directionalLight.castShadow || !directionalLight.visible)
                    directionalLight.userData.setProcessed(true);
            }
            for (var i = 0; i < scene.lights.point.length; i++) {
                var pointLight = scene.lights.point[i];
                this.mainPass.addLightPass("pointLightShadowMap", pointLight.userData);
                if(!pointLight.castShadow || !pointLight.visible)
                    pointLight.userData.setProcessed(true);
            }
        },

        createMainPass: function() {
            var outputTarget = this.renderInterface.context.canvasTarget;
            if (this._enableSSAO) {
                var positionPass = this.createVertexAttributePass("render-position");
                var normalPass = this.createVertexAttributePass("render-normal");
                var ssaoPass = this.createSSAOPass(positionPass.output, normalPass.output);
                ssaoPass.addPrePass(positionPass);
                ssaoPass.addPrePass(normalPass);
                var blurPass = this.createBlurPass(ssaoPass.output);
                blurPass.addPrePass(ssaoPass);
                this._blurPass = blurPass;
                this._ssaoPass = ssaoPass;
                this._positionPass = positionPass;
                this._normalPass = normalPass;
                this.mainPass = new webgl.ForwardRenderPass(this.renderInterface, outputTarget, {
                    inputs: {
                        ssaoMap: blurPass.output
                    }
                });
                this.mainPass.addPrePass(blurPass);
            } else {
                this.mainPass = new webgl.ForwardRenderPass(this.renderInterface, outputTarget);
            }
            this.mainRenderPass = this.mainPass;
        },

        createVertexAttributePass: function (programName) {
            var context = this.renderInterface.context;
            var buffer= new webgl.GLRenderTarget(context, {
                width: context.canvasTarget.width,
                height: context.canvasTarget.height,
                colorFormat: context.gl.RGBA,
                colorType: context.gl.FLOAT,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });
            return new webgl.VertexAttributePass(this.renderInterface, buffer, {
                programName: programName
            });
        },

        createSSAOPass: function (positionBuffer, normalBuffer) {
            var context = this.renderInterface.context;
            var ssaoBuffer = new webgl.GLRenderTarget(context, {
                width: context.canvasTarget.width,
                height: context.canvasTarget.height,
                colorFormat: context.gl.RGBA,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });

            return new webgl.SSAOPass(this.renderInterface, ssaoBuffer, {
                inputs: {
                    positionBuffer: positionBuffer,
                    normalBuffer: normalBuffer
                }
            });
        },

        createBlurPass: function (inputBuffer) {
            var context = this.renderInterface.context;
            var blurBuffer = new webgl.GLRenderTarget(context, {
                width: inputBuffer.width,
                height: inputBuffer.height,
                colorFormat: context.gl.RGBA,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });

            return new webgl.BoxBlurPass(this.renderInterface, blurBuffer, {
                inputs: {
                    buffer: inputBuffer
                }
            });
        },

        render: function(scene){
            if (this._enableSSAO) {
                this._positionPass.setProcessed(false);
                this._normalPass.setProcessed(false);
                this._ssaoPass.setProcessed(false);
                this._blurPass.setProcessed(false);
            }
            this.mainRenderPass.setProcessed(false);
            webgl.BaseRenderTree.prototype.render.call(this, scene);
        },

        getRenderStats: function(){
            return this.mainPass.getRenderStats();
        }
    });

    webgl.ForwardRenderTree = ForwardRenderTree;

})(XML3D.webgl);
<commit_msg>improve light castShadow handling<commit_after>(function (webgl) {

    /**
     *
     * @param {GLContext} context
     * @param {GLScene} scene
     * @constructor
     */
    var ForwardRenderTree = function (renderInterface, enableSSAO) {
        webgl.BaseRenderTree.call(this, renderInterface);
        var scene = renderInterface.scene;
        scene.addEventListener(webgl.Scene.EVENT_TYPE.LIGHT_STRUCTURE_CHANGED, this.onLightStructureChange.bind(this));
        scene.addEventListener(webgl.Scene.EVENT_TYPE.LIGHT_VALUE_CHANGED, this.onLightValueChange.bind(this));
        scene.addEventListener(webgl.Scene.EVENT_TYPE.SCENE_SHAPE_CHANGED, this.onSceneShapeChange.bind(this));
        scene.addEventListener(webgl.ShaderComposerFactory.EVENT_TYPE.MATERIAL_INITIALIZED, this.onShaderChange.bind(this));
        this._enableSSAO = enableSSAO;
        this.mainPass = null;
        this.createMainPass();
    };

    XML3D.createClass(ForwardRenderTree, webgl.BaseRenderTree);

    XML3D.extend(ForwardRenderTree.prototype, {
        onLightStructureChange: function(evt){
            var light = evt.light;
            if(evt.removed){
                // TODO: Proper clean up ShadowPass
                light.userData = null;
            }
            else {
                if(light.light.type == "spot" && light.castShadow && light.visible)
                    light.userData = this.createLightPass(light);
                else if(light.light.type == "directional" && light.castShadow && light.visible)
                    light.userData = this.createLightPass(light);
                else if(light.light.type == "point" && light.castShadow && light.visible) {
                    light.userData = this.createPointLightPass(light);
                }
            }
            this.reassignLightPasses(evt.target);
        },
        onLightValueChange: function(evt){
            var renderLight = evt.light;
            // TODO: Would be great to check of the light position or orientation specifically changed
            // We don't need to invalidate the lightPass otherwise
            if (renderLight.castShadow && renderLight.visible) {
                if (renderLight.userData) {
                    renderLight.userData.setProcessed(false);
                }
                else {
                    if (renderLight.light.type === "spot") {
                        renderLight.userData = this.createLightPass(renderLight);
                        this.mainPass.addLightPass("spotLightShadowMap", renderLight.userData);
                    }
                    else if (renderLight.light.type === "directional") {
                        renderLight.userData = this.createLightPass(renderLight);
                        this.mainPass.addLightPass("directionalLightShadowMap", renderLight.userData);
                    }
                    else if (renderLight.light.type === "point") {
                        renderLight.userData = this.createPointLightPass(renderLight);
                        this.mainPass.addLightPass("pointLightShadowMap", renderLight.userData);
                    }
                }
            }
        },
        onSceneShapeChange: function(evt){
            var scene = evt.target;
            for (var i = 0; i < scene.lights.spot.length; i++) {
                var spotLight = scene.lights.spot[i];
                if(spotLight.castShadow && spotLight.visible)
                    spotLight.userData && spotLight.userData.setProcessed(false);
            }
            for (var i = 0; i < scene.lights.directional.length; i++) {
                var directionalLight = scene.lights.directional[i];
                if(directionalLight.castShadow && directionalLight.visible)
                    directionalLight.userData && directionalLight.userData.setProcessed(false);
            }
            for (var i = 0; i < scene.lights.point.length; i++) {
                var pointLight = scene.lights.point[i];
                if(pointLight.castShadow && pointLight.visible)
                    pointLight.userData && pointLight.userData.setProcessed(false);
            }
        },
        onShaderChange: function(evt) {
            this.reassignLightPasses(evt.target);
        },

        createLightPass: function(light){
            var context = this.renderInterface.context;
            var dimension = Math.max(context.canvasTarget.width, context.canvasTarget.height) * 2;
            var lightFramebuffer  = new webgl.GLRenderTarget(context, {
                width: dimension,
                height: dimension,
                colorFormat: context.gl.RGBA,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });
            var lightPass = new webgl.LightPass(this.renderInterface, lightFramebuffer, light);
            lightPass.init(context);
            return lightPass;
        },

        createPointLightPass: function(light){
            var context = this.renderInterface.context;
            var dimension = Math.max(context.canvasTarget.width, context.canvasTarget.height) * 2;
            var lightFramebuffer  = new webgl.GLCubeMapRenderTarget(context, {
                width: dimension,
                height: dimension,
                colorFormat: context.gl.RGBA,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });
            var lightPass = new webgl.PointLightPass(this.renderInterface, lightFramebuffer, light);
            lightPass.init(context);
            return lightPass;
        },

        reassignLightPasses: function(scene){
            var context = this.renderInterface.context;

            this.mainPass.clearLightPasses();
            for (var i = 0; i < scene.lights.spot.length; i++) {
                var spotLight = scene.lights.spot[i];
                if (spotLight.userData) {
                    this.mainPass.addLightPass("spotLightShadowMap", spotLight.userData);
                    if (!spotLight.castShadow || !spotLight.visible)
                        spotLight.userData.setProcessed(true);
                }
            }
            for (var i = 0; i < scene.lights.directional.length; i++) {
                var directionalLight = scene.lights.directional[i];
                if (directionalLight.userData) {
                    this.mainPass.addLightPass("directionalLightShadowMap", directionalLight.userData);
                    if (!directionalLight.castShadow || !directionalLight.visible)
                        directionalLight.userData.setProcessed(true);
                }
            }
            for (var i = 0; i < scene.lights.point.length; i++) {
                var pointLight = scene.lights.point[i];
                if (pointLight.userData) {
                    this.mainPass.addLightPass("pointLightShadowMap", pointLight.userData);
                    if (!pointLight.castShadow || !pointLight.visible)
                        pointLight.userData.setProcessed(true);
                }
            }
        },

        createMainPass: function() {
            var outputTarget = this.renderInterface.context.canvasTarget;
            if (this._enableSSAO) {
                var positionPass = this.createVertexAttributePass("render-position");
                var normalPass = this.createVertexAttributePass("render-normal");
                var ssaoPass = this.createSSAOPass(positionPass.output, normalPass.output);
                ssaoPass.addPrePass(positionPass);
                ssaoPass.addPrePass(normalPass);
                var blurPass = this.createBlurPass(ssaoPass.output);
                blurPass.addPrePass(ssaoPass);
                this._blurPass = blurPass;
                this._ssaoPass = ssaoPass;
                this._positionPass = positionPass;
                this._normalPass = normalPass;
                this.mainPass = new webgl.ForwardRenderPass(this.renderInterface, outputTarget, {
                    inputs: {
                        ssaoMap: blurPass.output
                    }
                });
                this.mainPass.addPrePass(blurPass);
            } else {
                this.mainPass = new webgl.ForwardRenderPass(this.renderInterface, outputTarget);
            }
            this.mainRenderPass = this.mainPass;
        },

        createVertexAttributePass: function (programName) {
            var context = this.renderInterface.context;
            var buffer= new webgl.GLRenderTarget(context, {
                width: context.canvasTarget.width,
                height: context.canvasTarget.height,
                colorFormat: context.gl.RGBA,
                colorType: context.gl.FLOAT,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });
            return new webgl.VertexAttributePass(this.renderInterface, buffer, {
                programName: programName
            });
        },

        createSSAOPass: function (positionBuffer, normalBuffer) {
            var context = this.renderInterface.context;
            var ssaoBuffer = new webgl.GLRenderTarget(context, {
                width: context.canvasTarget.width,
                height: context.canvasTarget.height,
                colorFormat: context.gl.RGBA,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });

            return new webgl.SSAOPass(this.renderInterface, ssaoBuffer, {
                inputs: {
                    positionBuffer: positionBuffer,
                    normalBuffer: normalBuffer
                }
            });
        },

        createBlurPass: function (inputBuffer) {
            var context = this.renderInterface.context;
            var blurBuffer = new webgl.GLRenderTarget(context, {
                width: inputBuffer.width,
                height: inputBuffer.height,
                colorFormat: context.gl.RGBA,
                depthFormat: context.gl.DEPTH_COMPONENT16,
                stencilFormat: null,
                depthAsRenderbuffer: true
            });

            return new webgl.BoxBlurPass(this.renderInterface, blurBuffer, {
                inputs: {
                    buffer: inputBuffer
                }
            });
        },

        render: function(scene){
            if (this._enableSSAO) {
                this._positionPass.setProcessed(false);
                this._normalPass.setProcessed(false);
                this._ssaoPass.setProcessed(false);
                this._blurPass.setProcessed(false);
            }
            this.mainRenderPass.setProcessed(false);
            webgl.BaseRenderTree.prototype.render.call(this, scene);
        },

        getRenderStats: function(){
            return this.mainPass.getRenderStats();
        }
    });

    webgl.ForwardRenderTree = ForwardRenderTree;

})(XML3D.webgl);
<|endoftext|>


<commit_before>import React from 'react';
import {Dimensions, StyleSheet, Text, View, TouchableHighlight, PanResponder} from 'react-native';

export default class Next extends React.Component {
  constructor(props) {
    super(props);
    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponder: this.handleStartShouldSetPanResponder.bind(this),
      onMoveShouldSetPanResponder: this.handleMoveShouldSetPanResponder.bind(this),
      onPanResponderMove: this.handlePanResponderMove.bind(this),
      onPanResponderRelease: this.handlePanResponderEnd.bind(this),
      onPanResponderTerminate: this.handlePanResponderEnd.bind(this),
    });
  }
  handleStartShouldSetPanResponder(e, gestureState) {
    return true;
  }
  handleMoveShouldSetPanResponder(e, gestureState) {
    return true;
  }
  handlePanResponderMove(e, gestureState) {
    var {moveScene} = this.props;
    var {dx} = gestureState;
    moveScene({translate: Math.max(0, dx) / Dimensions.get('window').width});
  }
  handlePanResponderEnd(e, gestureState) {
    var {moveScene, stateNavigator} = this.props;
    if (gestureState.dx / Dimensions.get('window').width < 0.5)
      moveScene(null);
    else
      stateNavigator.navigateBack(1);
  }
  render() {
    const {stateNavigator} = this.props;
    const {url} = stateNavigator.stateContext;
    return (
      <View
        style={styles.scene}
        {...this.panResponder.panHandlers}
        >
        <TouchableHighlight
          underlayColor="white"
          onPress={() => {
            if (url === stateNavigator.stateContext.url)
              stateNavigator.navigate('next');
        }}>
          <Text>Next</Text>
        </TouchableHighlight>
      </View>
    )
  }
};

const styles = StyleSheet.create({
  scene: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
    borderWidth: 1,
    borderColor: '#000',
  },
});
<commit_msg>Removed start pan because move pan is enough<commit_after>import React from 'react';
import {Dimensions, StyleSheet, Text, View, TouchableHighlight, PanResponder} from 'react-native';

export default class Next extends React.Component {
  constructor(props) {
    super(props);
    this.panResponder = PanResponder.create({
      onMoveShouldSetPanResponder: this.handleMoveShouldSetPanResponder.bind(this),
      onPanResponderMove: this.handlePanResponderMove.bind(this),
      onPanResponderRelease: this.handlePanResponderEnd.bind(this),
      onPanResponderTerminate: this.handlePanResponderEnd.bind(this),
    });
  }
  handleMoveShouldSetPanResponder(e, gestureState) {
    return true;
  }
  handlePanResponderMove(e, gestureState) {
    var {moveScene} = this.props;
    var {dx} = gestureState;
    moveScene({translate: Math.max(0, dx) / Dimensions.get('window').width});
  }
  handlePanResponderEnd(e, gestureState) {
    var {moveScene, stateNavigator} = this.props;
    if (gestureState.dx / Dimensions.get('window').width < 0.5)
      moveScene(null);
    else
      stateNavigator.navigateBack(1);
  }
  render() {
    const {stateNavigator} = this.props;
    const {url} = stateNavigator.stateContext;
    return (
      <View
        style={styles.scene}
        {...this.panResponder.panHandlers}
        >
        <TouchableHighlight
          underlayColor="white"
          onPress={() => {
            if (url === stateNavigator.stateContext.url)
              stateNavigator.navigate('next');
        }}>
          <Text>Next</Text>
        </TouchableHighlight>
      </View>
    )
  }
};

const styles = StyleSheet.create({
  scene: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
    borderWidth: 1,
    borderColor: '#000',
  },
});
<|endoftext|>