<commit_before>var iconv = require('iconv-lite');
var zlib = require('zlib');
var MAX_REQ_SIZE = 128 * 1024;
var MAX_RES_SIZE = 256 * 1024;
var TIMEOUT = 20000;
var CACHE_TIME = 60000;
var CLEAR_INTERVAL = 3000;
var MAX_LENGTH = 512;
var MIN_LENGTH = 412;
var COUNT = 100;
var count = 0;
var ids = [];
var data = {};
var proxy, binded, timeout, interval, util;

function disable() {
	proxy.removeListener('request', handleRequest);
	ids = [];
	data = {};
	interval && clearInterval(interval);
	interval = null;
	binded = false;
}

function enable() {
	!binded && proxy.on('request', handleRequest);
	binded = true;
	clearTimeout(timeout);
	timeout = setTimeout(disable, TIMEOUT);
	if (!interval) {
		interval = setInterval(clearCache, CLEAR_INTERVAL);
	}
}

/**
 * 如果超过最大缓存数，清理如下请求数据：
 * 1. 已经请求结束且结束时间超过10秒
 * 2. 请求#1前面的未结束且未被ui读取过的请求
 */
function clearCache() {
	var len = ids.length;
	if (len <= MAX_LENGTH) {
		return;
	}

	var index = -1; //已经完成，且缓存超过10s的最后一个请求
	var now = Date.now();
	for (var i = len - 1; i >= 0; i--) {
		var curData = data[ids[i]];
		if (curData.endTime && now - curData.endTime > TIMEOUT) {
			index = i;
			break;
		}
	}

	if (index < 0) {
		return;
	}

	var _ids = [];
	var end;
	++index;
	for (var i = 0; i < index; i++) {
		var id = ids[i];
		var curData = data[id];
		if (curData.read && (!curData.endTime || now - curData.endTime < CACHE_TIME)) {
			_ids.push(id);
		} else {
			delete data[id];
			if (--len <= MIN_LENGTH) {
				_ids.push.apply(_ids, ids.slice(i + 1, index));
				break;
			}
		}
	}
	ids = _ids.concat(ids.slice(index));
}

function passThrough(chunk, encoding, callback) {
	callback(null, chunk);
}

function decode(body) {
	if (body) {
		var _body = body + '';
		if (_body.indexOf('�') != -1) {
			_body = iconv.decode(body, 'gbk');
		}
		body = _body;
	}

	return body;
}

function get(options) {
	enable();
	options = options || {};
	var data = {};
	var newIds = options.startTime == -1 ? [] : getIds(options.startTime, options.count);
	var list = getList(newIds).concat(getList(options.ids));
	for (var i = 0, len = list.length; i < len; i++) {
		var item = list[i];
		if (item) {
			data[item.id] = item;
		}
	}

	return {
		ids: options.ids || [],
		newIds: newIds,
		data: data
	};
}

function getIds(startTime, count) {
	var len = ids.length;
	if (!len) {
		return [];
	}

	startTime = (startTime || Date.now() - 6000) + '';
	count = Math.min(count || COUNT, len);
	if (ids[0] > startTime) {

		return ids.slice(0, count);
	}

	if (len === 1 || ids[len - 1] <= startTime) {

		return  [];
	}

	var index = getIndex(startTime, 0, len - 1);
	return ids.slice(index, index + count);
}

function getIndex(startTime, start, end) {
	if (end - start <= 1) {
		return ids[start] > startTime ? start : end;
	}

	var mid = Math.floor((start + end) / 2);
	var id = ids[mid];
	return id == startTime ? mid + 1 : (id < startTime ? getIndex(startTime, mid + 1, end)
			: getIndex(startTime, start, mid));
}

function getList(ids) {
	var result = [];
	for (var i = 0, len = ids && ids.length; i < len; i++) {
		var id = ids[i];
		var curData = data[id];
		if (curData) {
			curData.read = true;
			result[i] = curData;
		}
	}

	return result;
}

function handleRequest(req) {
	var dnsTime = req.dnsTime || 0;
	req.dnsTime = Date.now();
	var startTime = req.dnsTime - dnsTime;
	var id = startTime + '-' + ++count;
	var reqData = {
			method: req.method || 'GET',
			httpVersion: req.httpVersion || '1.1',
            ip: req.ip || '::ffff:127.0.0.1',
            headers: req.headers
		};
	var resData = {
			ip: req.host
	};

	var curData = data[id] = {
			id: id,
			url: req.url,
			startTime: startTime,
			dnsTime: req.dnsTime,
			req: reqData,
			res: resData,
			rules: req.rules
	};

	ids.push(id);
	req.on('response', handleResponse);
	req.on('error', function(err) {
		reqData.body = err && err.stack;
		curData.endTime = reqData.requestTime = Date.now();
		curData.reqError = true;
		req.removeListener('response', handleResponse);
		req._transform = passThrough;
	});

	var reqBody;
	var reqSize = 0;

	if (util.hasRequestBody(req)) {
		reqBody = false;
	}
	req._transform = function(chunk, encoding, callback) {

		if (chunk) {
			if (reqBody || reqBody === false) {
				reqBody = reqBody ? Buffer.concat([reqBody, chunk]) : chunk;
			}
			reqSize += chunk.length;
		}

		if (reqBody && reqBody.length > MAX_REQ_SIZE) {
			reqBody = null;
		}

		if (!chunk) {
			curData.requestTime = Date.now();
			curData.reqEnd = true;
			reqData.size = reqSize;
			reqData.body = decode(reqBody);
		}

		callback(null, chunk);
	};

	function handleResponse(res) {
		curData.responseTime = Date.now();
		resData.headers = res.headers;
		resData.statusCode = res.statusCode;
		resData.ip = res.ip;
		res.on('error', function(err) {
			resData.body = err && err.stack;
			curData.endTime = Date.now();
			curData.resError = true;
			res._transform = passThrough;
		});

		var resBody;
		var resSize = 0;
		var contentType = util.getContentType(res.headers);
		if (contentType && contentType != 'IMG' && util.hasBody(res)) {
			resBody = false;
		}

		res._transform = function(chunk, encoding, callback) {
			if (chunk) {
				if (resBody || resBody === false) {
					resBody = resBody ? Buffer.concat([resBody, chunk]) : chunk;
				}

				resSize += chunk.length;
			}

			if (resBody && resBody.length > MAX_RES_SIZE) {
				resBody = null;
			}

			if (!chunk) {
				curData.endTime = Date.now();
				curData.resEnd = true;
				resData.size = resSize;
				if (resBody) {
					var unzip;
					switch (util.toLowerCase(res.headers['content-encoding'])) {
					    case 'gzip':
					    	unzip = zlib.gunzip.bind(zlib);
					      break;
					    case 'deflate':
					    	unzip = zlib.inflate.bind(zlib);
					      break;
					}

					if (unzip) {
						unzip(resBody, function(err, body) {
							if (err) {
								callback(err, chunk);
								return;
							}
							resData.body = decode(body);
							callback(null, chunk);
						});
						return;
					}
				}
				resData.body = decode(resBody);
			}

			callback(null, chunk);
		};
	}

}

module.exports = function init(_proxy) {
	proxy = _proxy;
	util = proxy.util;
	enable();
	module.exports = get;
};<commit_msg>cache time<commit_after>var iconv = require('iconv-lite');
var zlib = require('zlib');
var MAX_REQ_SIZE = 128 * 1024;
var MAX_RES_SIZE = 256 * 1024;
var TIMEOUT = 20000;
var CACHE_TIME = 6000;
var CLEAR_INTERVAL = 3000;
var MAX_LENGTH = 512;
var MIN_LENGTH = 412;
var COUNT = 100;
var count = 0;
var ids = [];
var data = {};
var proxy, binded, timeout, interval, util;

function disable() {
	proxy.removeListener('request', handleRequest);
	ids = [];
	data = {};
	interval && clearInterval(interval);
	interval = null;
	binded = false;
}

function enable() {
	!binded && proxy.on('request', handleRequest);
	binded = true;
	clearTimeout(timeout);
	timeout = setTimeout(disable, TIMEOUT);
	if (!interval) {
		interval = setInterval(clearCache, CLEAR_INTERVAL);
	}
}

/**
 * 如果超过最大缓存数，清理如下请求数据：
 * 1. 已经请求结束且结束时间超过10秒
 * 2. 请求#1前面的未结束且未被ui读取过的请求
 */
function clearCache() {
	var len = ids.length;
	if (len <= MAX_LENGTH) {
		return;
	}

	var index = -1; //已经完成，且缓存超过10s的最后一个请求
	var now = Date.now();
	for (var i = len - 1; i >= 0; i--) {
		var curData = data[ids[i]];
		if (curData.endTime && now - curData.endTime > TIMEOUT) {
			index = i;
			break;
		}
	}

	if (index < 0) {
		return;
	}

	var _ids = [];
	var end;
	++index;
	for (var i = 0; i < index; i++) {
		var id = ids[i];
		var curData = data[id];
		if (curData.read && (!curData.endTime || now - curData.endTime < CACHE_TIME)) {
			_ids.push(id);
		} else {
			delete data[id];
			if (--len <= MIN_LENGTH) {
				_ids.push.apply(_ids, ids.slice(i + 1, index));
				break;
			}
		}
	}
	ids = _ids.concat(ids.slice(index));
}

function passThrough(chunk, encoding, callback) {
	callback(null, chunk);
}

function decode(body) {
	if (body) {
		var _body = body + '';
		if (_body.indexOf('�') != -1) {
			_body = iconv.decode(body, 'gbk');
		}
		body = _body;
	}

	return body;
}

function get(options) {
	enable();
	options = options || {};
	var data = {};
	var newIds = options.startTime == -1 ? [] : getIds(options.startTime, options.count);
	var list = getList(newIds).concat(getList(options.ids));
	for (var i = 0, len = list.length; i < len; i++) {
		var item = list[i];
		if (item) {
			data[item.id] = item;
		}
	}

	return {
		ids: options.ids || [],
		newIds: newIds,
		data: data
	};
}

function getIds(startTime, count) {
	var len = ids.length;
	if (!len) {
		return [];
	}

	startTime = (startTime || Date.now() - 6000) + '';
	count = Math.min(count || COUNT, len);
	if (ids[0] > startTime) {

		return ids.slice(0, count);
	}

	if (len === 1 || ids[len - 1] <= startTime) {

		return  [];
	}

	var index = getIndex(startTime, 0, len - 1);
	return ids.slice(index, index + count);
}

function getIndex(startTime, start, end) {
	if (end - start <= 1) {
		return ids[start] > startTime ? start : end;
	}

	var mid = Math.floor((start + end) / 2);
	var id = ids[mid];
	return id == startTime ? mid + 1 : (id < startTime ? getIndex(startTime, mid + 1, end)
			: getIndex(startTime, start, mid));
}

function getList(ids) {
	var result = [];
	for (var i = 0, len = ids && ids.length; i < len; i++) {
		var id = ids[i];
		var curData = data[id];
		if (curData) {
			curData.read = true;
			result[i] = curData;
		}
	}

	return result;
}

function handleRequest(req) {
	var dnsTime = req.dnsTime || 0;
	req.dnsTime = Date.now();
	var startTime = req.dnsTime - dnsTime;
	var id = startTime + '-' + ++count;
	var reqData = {
			method: req.method || 'GET',
			httpVersion: req.httpVersion || '1.1',
            ip: req.ip || '::ffff:127.0.0.1',
            headers: req.headers
		};
	var resData = {
			ip: req.host
	};

	var curData = data[id] = {
			id: id,
			url: req.url,
			startTime: startTime,
			dnsTime: req.dnsTime,
			req: reqData,
			res: resData,
			rules: req.rules
	};

	ids.push(id);
	req.on('response', handleResponse);
	req.on('error', function(err) {
		reqData.body = err && err.stack;
		curData.endTime = reqData.requestTime = Date.now();
		curData.reqError = true;
		req.removeListener('response', handleResponse);
		req._transform = passThrough;
	});

	var reqBody;
	var reqSize = 0;

	if (util.hasRequestBody(req)) {
		reqBody = false;
	}
	req._transform = function(chunk, encoding, callback) {

		if (chunk) {
			if (reqBody || reqBody === false) {
				reqBody = reqBody ? Buffer.concat([reqBody, chunk]) : chunk;
			}
			reqSize += chunk.length;
		}

		if (reqBody && reqBody.length > MAX_REQ_SIZE) {
			reqBody = null;
		}

		if (!chunk) {
			curData.requestTime = Date.now();
			curData.reqEnd = true;
			reqData.size = reqSize;
			reqData.body = decode(reqBody);
		}

		callback(null, chunk);
	};

	function handleResponse(res) {
		curData.responseTime = Date.now();
		resData.headers = res.headers;
		resData.statusCode = res.statusCode;
		resData.ip = res.ip;
		res.on('error', function(err) {
			resData.body = err && err.stack;
			curData.endTime = Date.now();
			curData.resError = true;
			res._transform = passThrough;
		});

		var resBody;
		var resSize = 0;
		var contentType = util.getContentType(res.headers);
		if (contentType && contentType != 'IMG' && util.hasBody(res)) {
			resBody = false;
		}

		res._transform = function(chunk, encoding, callback) {
			if (chunk) {
				if (resBody || resBody === false) {
					resBody = resBody ? Buffer.concat([resBody, chunk]) : chunk;
				}

				resSize += chunk.length;
			}

			if (resBody && resBody.length > MAX_RES_SIZE) {
				resBody = null;
			}

			if (!chunk) {
				curData.endTime = Date.now();
				curData.resEnd = true;
				resData.size = resSize;
				if (resBody) {
					var unzip;
					switch (util.toLowerCase(res.headers['content-encoding'])) {
					    case 'gzip':
					    	unzip = zlib.gunzip.bind(zlib);
					      break;
					    case 'deflate':
					    	unzip = zlib.inflate.bind(zlib);
					      break;
					}

					if (unzip) {
						unzip(resBody, function(err, body) {
							if (err) {
								callback(err, chunk);
								return;
							}
							resData.body = decode(body);
							callback(null, chunk);
						});
						return;
					}
				}
				resData.body = decode(resBody);
			}

			callback(null, chunk);
		};
	}

}

module.exports = function init(_proxy) {
	proxy = _proxy;
	util = proxy.util;
	enable();
	module.exports = get;
};<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       Felipe Alfonso <@bitnenfer>
 * @author       Matthew Groves <@doormat>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Generate shader source to test maximum ifs.
 *
 * @private
 * @ignore
 * @param {number} maxIfs - The number of if statements to generate
 */
function GenerateSrc (maxIfs)
{
    var src = '';

    for (var i = 0; i < maxIfs; ++i)
    {
        if (i > 0)
        {
            src += '\nelse ';
        }

        if (i < maxIfs - 1)
        {
            src += 'if(test == ' + i + '.0){}';
        }
    }

    return src;
}

/**
 * @namespace Phaser.Renderer.WebGL.Utils
 * @since 3.0.0
 */
module.exports = {

    /**
     * Packs four floats on a range from 0.0 to 1.0 into a single Uint32
     *
     * @function Phaser.Renderer.WebGL.Utils.getTintFromFloats
     * @since 3.0.0
     *
     * @param {number} r - Red component in a range from 0.0 to 1.0
     * @param {number} g - Green component in a range from 0.0 to 1.0
     * @param {number} b - Blue component in a range from 0.0 to 1.0
     * @param {number} a - Alpha component in a range from 0.0 to 1.0
     *
     * @return {number} The packed RGBA values as a Uint32.
     */
    getTintFromFloats: function (r, g, b, a)
    {
        var ur = ((r * 255) | 0) & 0xff;
        var ug = ((g * 255) | 0) & 0xff;
        var ub = ((b * 255) | 0) & 0xff;
        var ua = ((a * 255) | 0) & 0xff;

        return ((ua << 24) | (ur << 16) | (ug << 8) | ub) >>> 0;
    },

    /**
     * Packs a Uint24, representing RGB components, with a Float32, representing
     * the alpha component, with a range between 0.0 and 1.0 and return a Uint32
     *
     * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlpha
     * @since 3.0.0
     *
     * @param {number} rgb - Uint24 representing RGB components
     * @param {number} a - Float32 representing Alpha component
     *
     * @return {number} Packed RGBA as Uint32
     */
    getTintAppendFloatAlpha: function (rgb, a)
    {
        var ua = ((a * 255) | 0) & 0xff;

        return ((ua << 24) | rgb) >>> 0;
    },

    /**
     * Packs a Uint24, representing RGB components, with a Float32, representing
     * the alpha component, with a range between 0.0 and 1.0 and return a
     * swizzled Uint32
     *
     * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlphaAndSwap
     * @since 3.0.0
     *
     * @param {number} rgb - Uint24 representing RGB components
     * @param {number} a - Float32 representing Alpha component
     *
     * @return {number} Packed RGBA as Uint32
     */
    getTintAppendFloatAlphaAndSwap: function (rgb, a)
    {
        var ur = ((rgb >> 16) | 0) & 0xff;
        var ug = ((rgb >> 8) | 0) & 0xff;
        var ub = (rgb | 0) & 0xff;
        var ua = ((a * 255) | 0) & 0xff;

        return ((ua << 24) | (ub << 16) | (ug << 8) | ur) >>> 0;
    },

    /**
     * Unpacks a Uint24 RGB into an array of floats of ranges of 0.0 and 1.0
     *
     * @function Phaser.Renderer.WebGL.Utils.getFloatsFromUintRGB
     * @since 3.0.0
     *
     * @param {number} rgb - RGB packed as a Uint24
     *
     * @return {array} Array of floats representing each component as a float
     */
    getFloatsFromUintRGB: function (rgb)
    {
        var ur = ((rgb >> 16) | 0) & 0xff;
        var ug = ((rgb >> 8) | 0) & 0xff;
        var ub = (rgb | 0) & 0xff;

        return [ ur / 255, ug / 255, ub / 255 ];
    },

    /**
     * Counts how many attributes of 32 bits a vertex has
     *
     * @function Phaser.Renderer.WebGL.Utils.getComponentCount
     * @since 3.0.0
     *
     * @param {array} attributes - Array of attributes
     * @param {WebGLRenderingContext} glContext - WebGLContext used for check types
     *
     * @return {number} Count of 32 bit attributes in vertex
     */
    getComponentCount: function (attributes, glContext)
    {
        var count = 0;

        for (var index = 0; index < attributes.length; ++index)
        {
            var element = attributes[index];

            if (element.type === glContext.FLOAT)
            {
                count += element.size;
            }
            else
            {
                count += 1;
            }
        }

        return count;
    },

    /**
     * Check to see how many texture units the GPU supports, based on the given config value.
     * Then tests this against the maximum number of iterations GLSL can support.
     *
     * @function Phaser.Renderer.WebGL.Utils.checkShaderMax
     * @since 3.50.0
     *
     * @param {WebGLRenderingContext} gl - The WebGLContext used to create the shaders.
     * @param {number} maxTextures - The Game Config maxTextures value.
     *
     * @return {number} The number of texture units that is supported by this browser and GPU.
     */
    checkShaderMax: function (gl, maxTextures)
    {
        if (!maxTextures || maxTextures === -1)
        {
            maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
        }

        var shader = gl.createShader(gl.FRAGMENT_SHADER);

        var fragTemplate = [
            'precision mediump float;',
            'void main(void){',
            'float test = 0.1;',
            '%forloop%',
            'gl_FragColor = vec4(0.0);',
            '}'
        ].join('\n');

        // eslint-disable-next-line no-constant-condition
        while (true)
        {
            var fragmentSrc = fragTemplate.replace(/%forloop%/gi, GenerateSrc(maxTextures));

            gl.shaderSource(shader, fragmentSrc);
            gl.compileShader(shader);

            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
            {
                maxTextures = (maxTextures / 2) | 0;
            }
            else
            {
                // valid!
                break;
            }
        }

        return maxTextures;
    },

    /**
     * Checks the given Fragment Shader Source for `%count%` and `%forloop%` declarations and
     * replaces those with GLSL code for setting `texture = texture2D(uMainSampler[i], outTexCoord)`.
     *
     * @function Phaser.Renderer.WebGL.Utils.parseFragmentShaderMaxTextures
     * @since 3.50.0
     *
     * @param {string} fragmentShaderSource - The Fragment Shader source code to operate on.
     * @param {number} maxTextures - The number of maxTextures value.
     *
     * @return {string} The modified Fragment Shader source.
     */
    parseFragmentShaderMaxTextures: function (fragmentShaderSource, maxTextures)
    {
        var src = '';

        for (var i = 0; i < maxTextures; i++)
        {
            if (i > 0)
            {
                src += '\n\telse ';
            }

            if (i < maxTextures - 1)
            {
                src += 'if (outTexId < ' + i + '.5)';
            }

            src += '\n\t{';
            src += '\n\t\ttexture = texture2D(uMainSampler[' + i + '], outTexCoord);';
            src += '\n\t}';
        }

        fragmentShaderSource = fragmentShaderSource.replace(/%count%/gi, maxTextures.toString());

        return fragmentShaderSource.replace(/%forloop%/gi, src);
    }
};
<commit_msg>The `WebGL.Utils.getComponentCount` function has been removed as this is no longer required internally.<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @author       Felipe Alfonso <@bitnenfer>
 * @author       Matthew Groves <@doormat>
 * @copyright    2020 Photon Storm Ltd.
 * @license      {@link https://opensource.org/licenses/MIT|MIT License}
 */

/**
 * Generate shader source to test maximum ifs.
 *
 * @private
 * @ignore
 * @param {number} maxIfs - The number of if statements to generate
 */
function GenerateSrc (maxIfs)
{
    var src = '';

    for (var i = 0; i < maxIfs; ++i)
    {
        if (i > 0)
        {
            src += '\nelse ';
        }

        if (i < maxIfs - 1)
        {
            src += 'if(test == ' + i + '.0){}';
        }
    }

    return src;
}

/**
 * @namespace Phaser.Renderer.WebGL.Utils
 * @since 3.0.0
 */
module.exports = {

    /**
     * Packs four floats on a range from 0.0 to 1.0 into a single Uint32
     *
     * @function Phaser.Renderer.WebGL.Utils.getTintFromFloats
     * @since 3.0.0
     *
     * @param {number} r - Red component in a range from 0.0 to 1.0
     * @param {number} g - Green component in a range from 0.0 to 1.0
     * @param {number} b - Blue component in a range from 0.0 to 1.0
     * @param {number} a - Alpha component in a range from 0.0 to 1.0
     *
     * @return {number} The packed RGBA values as a Uint32.
     */
    getTintFromFloats: function (r, g, b, a)
    {
        var ur = ((r * 255) | 0) & 0xff;
        var ug = ((g * 255) | 0) & 0xff;
        var ub = ((b * 255) | 0) & 0xff;
        var ua = ((a * 255) | 0) & 0xff;

        return ((ua << 24) | (ur << 16) | (ug << 8) | ub) >>> 0;
    },

    /**
     * Packs a Uint24, representing RGB components, with a Float32, representing
     * the alpha component, with a range between 0.0 and 1.0 and return a Uint32
     *
     * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlpha
     * @since 3.0.0
     *
     * @param {number} rgb - Uint24 representing RGB components
     * @param {number} a - Float32 representing Alpha component
     *
     * @return {number} Packed RGBA as Uint32
     */
    getTintAppendFloatAlpha: function (rgb, a)
    {
        var ua = ((a * 255) | 0) & 0xff;

        return ((ua << 24) | rgb) >>> 0;
    },

    /**
     * Packs a Uint24, representing RGB components, with a Float32, representing
     * the alpha component, with a range between 0.0 and 1.0 and return a
     * swizzled Uint32
     *
     * @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlphaAndSwap
     * @since 3.0.0
     *
     * @param {number} rgb - Uint24 representing RGB components
     * @param {number} a - Float32 representing Alpha component
     *
     * @return {number} Packed RGBA as Uint32
     */
    getTintAppendFloatAlphaAndSwap: function (rgb, a)
    {
        var ur = ((rgb >> 16) | 0) & 0xff;
        var ug = ((rgb >> 8) | 0) & 0xff;
        var ub = (rgb | 0) & 0xff;
        var ua = ((a * 255) | 0) & 0xff;

        return ((ua << 24) | (ub << 16) | (ug << 8) | ur) >>> 0;
    },

    /**
     * Unpacks a Uint24 RGB into an array of floats of ranges of 0.0 and 1.0
     *
     * @function Phaser.Renderer.WebGL.Utils.getFloatsFromUintRGB
     * @since 3.0.0
     *
     * @param {number} rgb - RGB packed as a Uint24
     *
     * @return {array} Array of floats representing each component as a float
     */
    getFloatsFromUintRGB: function (rgb)
    {
        var ur = ((rgb >> 16) | 0) & 0xff;
        var ug = ((rgb >> 8) | 0) & 0xff;
        var ub = (rgb | 0) & 0xff;

        return [ ur / 255, ug / 255, ub / 255 ];
    },

    /**
     * Check to see how many texture units the GPU supports, based on the given config value.
     * Then tests this against the maximum number of iterations GLSL can support.
     *
     * @function Phaser.Renderer.WebGL.Utils.checkShaderMax
     * @since 3.50.0
     *
     * @param {WebGLRenderingContext} gl - The WebGLContext used to create the shaders.
     * @param {number} maxTextures - The Game Config maxTextures value.
     *
     * @return {number} The number of texture units that is supported by this browser and GPU.
     */
    checkShaderMax: function (gl, maxTextures)
    {
        if (!maxTextures || maxTextures === -1)
        {
            maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
        }

        var shader = gl.createShader(gl.FRAGMENT_SHADER);

        var fragTemplate = [
            'precision mediump float;',
            'void main(void){',
            'float test = 0.1;',
            '%forloop%',
            'gl_FragColor = vec4(0.0);',
            '}'
        ].join('\n');

        // eslint-disable-next-line no-constant-condition
        while (true)
        {
            var fragmentSrc = fragTemplate.replace(/%forloop%/gi, GenerateSrc(maxTextures));

            gl.shaderSource(shader, fragmentSrc);
            gl.compileShader(shader);

            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
            {
                maxTextures = (maxTextures / 2) | 0;
            }
            else
            {
                // valid!
                break;
            }
        }

        return maxTextures;
    },

    /**
     * Checks the given Fragment Shader Source for `%count%` and `%forloop%` declarations and
     * replaces those with GLSL code for setting `texture = texture2D(uMainSampler[i], outTexCoord)`.
     *
     * @function Phaser.Renderer.WebGL.Utils.parseFragmentShaderMaxTextures
     * @since 3.50.0
     *
     * @param {string} fragmentShaderSource - The Fragment Shader source code to operate on.
     * @param {number} maxTextures - The number of maxTextures value.
     *
     * @return {string} The modified Fragment Shader source.
     */
    parseFragmentShaderMaxTextures: function (fragmentShaderSource, maxTextures)
    {
        var src = '';

        for (var i = 0; i < maxTextures; i++)
        {
            if (i > 0)
            {
                src += '\n\telse ';
            }

            if (i < maxTextures - 1)
            {
                src += 'if (outTexId < ' + i + '.5)';
            }

            src += '\n\t{';
            src += '\n\t\ttexture = texture2D(uMainSampler[' + i + '], outTexCoord);';
            src += '\n\t}';
        }

        fragmentShaderSource = fragmentShaderSource.replace(/%count%/gi, maxTextures.toString());

        return fragmentShaderSource.replace(/%forloop%/gi, src);
    }
};
<|endoftext|>


<commit_before>import EventEmitter from 'events';
import Synth from './synth';

export default class Track extends EventEmitter {
  constructor(opts) {
    this.id = opts.id || Date.now();
    this.title = opts.title || '';
    this.type = opts.type || 'MIDI';

    this.recordings = opts.recordings || [];
    this.instrument = opts.instrument || new Synth();
    // pass in a gain value on creation, or not
    this.gain = tsw.gain(opts.gain || 1.0);
    this.panner = tsw.panner(opts.panner || 0);
  }

  play(args) {
    var {frequency} = args;
    var node = this.instrument.getNode(frequency);
    tsw.connect(node, this.panner, this.gain, tsw.speakers);
    node.start();

    return {
      stop: function () {
        node.stop();
        // clean up recording and stuff
      }
    };
  }

  record(args) {
    this.recordings.push({
      frequest: args.frequency,
      time: args.time
    });
    return this.play(args);
    // emit something?
  }
}
<commit_msg>minor: remove an unneccessary line break<commit_after>import EventEmitter from 'events';
import Synth from './synth';

export default class Track extends EventEmitter {
  constructor(opts) {
    this.id = opts.id || Date.now();
    this.title = opts.title || '';
    this.type = opts.type || 'MIDI';

    this.recordings = opts.recordings || [];
    this.instrument = opts.instrument || new Synth();
    // pass in a gain value on creation, or not
    this.gain = tsw.gain(opts.gain || 1.0);
    this.panner = tsw.panner(opts.panner || 0);
  }

  play(args) {
    var {frequency} = args;
    var node = this.instrument.getNode(frequency);
    tsw.connect(node, this.panner, this.gain, tsw.speakers);
    node.start();

    return {
      stop: function () {
        node.stop();
        // clean up recording and stuff
      }
    };
  }

  record(args) {
    this.recordings.push({
      frequest: args.frequency,
      time: args.time
    });
    return this.play(args);
    // emit something?
  }
}
<|endoftext|>


<commit_before>module.exports = (app, db, config, addEvent, log) => {
  app.get('/status', (req, res) => {
    const hosts = Object.keys(config);
    res.json(hosts);
  });

  app.get('/status/:host', (req, res) => {
    const host = req.params.host;
    db.all(`SELECT * FROM events WHERE host='${host}'`, (err, events) => {
      if (err) {
        res.status(500).send('Unable to get events');
      } else if (events.length === 0) {
        res.sendStatus(404);
      } else {
        res.status(200).json(events);
      }
    });
  });
};
<commit_msg>Fix config for status route<commit_after>module.exports = (app, db, config, addEvent, log) => {
  app.get('/status', (req, res) => {
    const hosts = Object.keys(config.hosts);
    res.json(hosts);
  });

  app.get('/status/:host', (req, res) => {
    const host = req.params.host;
    db.all(`SELECT * FROM events WHERE host='${host}'`, (err, events) => {
      if (err) {
        res.status(500).send('Unable to get events');
      } else if (events.length === 0) {
        res.sendStatus(404);
      } else {
        res.status(200).json(events);
      }
    });
  });
};
<|endoftext|>


<commit_before>'use strict';

const _ = require('lodash');
const mongoose = require('mongoose');

exports.get = function(req, res, next) {
  let ReplyQueue = req.app.db.models.ReplyQueue;

  ReplyQueue.find({}).populate('asset').exec(function(err, docs) {
    if(!err) {
      res.send(docs);
    } else {
      next(err);
    }
  });
};

exports.getById = function(req, res, next) {
  let id = req.params.id;
  let ReplyQueue = req.app.db.models.ReplyQueue;

  ReplyQueue.findById(id).populate('asset').exec(function(err, doc) {
    if(!err) {
      res.send(doc);
    } else {
      next(err);
    }
  });
};

exports.post = function(req, res, next) {
  let ReplyQueue = req.app.db.models.ReplyQueue;
  let replyQueue = new ReplyQueue(req.body);
  replyQueue.save(function(err) {
    if(!err) {
      res.send({success: true});
    } else {
      next(err);
    }
  });
};

exports.put = function(req, res, next) {
  let id = req.params.id;
  let ReplyQueue = req.app.db.models.ReplyQueue;

  ReplyQueue.findByIdAndUpdate(id, req.body, {new: true}, function(err, user) {
    if (!err) {
      res.send({success: true});
    } else {
      next(err);
    }
  });
};

exports.delete = function(req, res, next) {
  let id = req.params.id;
  let ReplyQueue = req.app.db.models.ReplyQueue;

  ReplyQueue.remove({ _id: id }, function(err) {
    if (!err) {
      res.send({success: true});
    } else {
      next(err);
    }
  });
};

<commit_msg>mod on _id<commit_after>'use strict';

const _ = require('lodash');
const mongoose = require('mongoose');

exports.get = function(req, res, next) {
  let ReplyQueue = req.app.db.models.ReplyQueue;

  ReplyQueue.find({}).populate('asset').exec(function(err, docs) {
    if(!err) {
      res.send(docs);
    } else {
      next(err);
    }
  });
};

exports.getById = function(req, res, next) {
  let id = req.params.id;
  let ReplyQueue = req.app.db.models.ReplyQueue;

  ReplyQueue.findById(id).populate('asset').exec(function(err, doc) {
    if(!err) {
      res.send(doc);
    } else {
      next(err);
    }
  });
};

exports.post = function(req, res, next) {
  let ReplyQueue = req.app.db.models.ReplyQueue;
  let replyQueue = new ReplyQueue(req.body);
  replyQueue.save(function(err) {
    if(!err) {
      res.send({success: true});
    } else {
      next(err);
    }
  });
};

exports.put = function(req, res, next) {
  let id = req.params.id;
  let ReplyQueue = req.app.db.models.ReplyQueue;
  delete req.body._id;
  ReplyQueue.findByIdAndUpdate(id, req.body, {new: true}, function(err, user) {
    if (!err) {
      res.send({success: true});
    } else {
      next(err);
    }
  });
};

exports.delete = function(req, res, next) {
  let id = req.params.id;
  let ReplyQueue = req.app.db.models.ReplyQueue;

  ReplyQueue.remove({ _id: id }, function(err) {
    if (!err) {
      res.send({success: true});
    } else {
      next(err);
    }
  });
};

<|endoftext|>


<commit_before>/*
Copyright 2011 Museum of Moving Image

Licensed under the Educational Community License (ECL), Version 2.0.
ou may not use this file except in compliance with this License.

You may obtain a copy of the ECL 2.0 License at
https://source.collectionspace.org/collection-space/LICENSE.txt
*/

/*global jqUnit, jQuery, cspace, fluid, start, stop, ok, expect*/
"use strict";

cspace.test = cspace.test || {};

var listViewTester = function ($) {

    var container = ".listView-container";

    var bareListViewTest = new jqUnit.TestCase("List View Tests");

    var listViewTest = cspace.tests.testEnvironment({
        testCase: bareListViewTest
    });

    var setupListView = function (callbacks, options) {
        options = fluid.merge(null, options || {}, {
            model: {
                sortable: {},
                columns: [{
                    sortable: true,
                    id: "number",
                    name: "listView-number"
                }, {
                    sortable: false,
                    id: "summary",
                    name: "listView-summary"
                }, {
                    sortable: true,
                    id: "summarylist.updatedAt",
                    name: "listView-updatedAt"
                }],
                pagerModel: {
                    pageCount: 1,
                    pageIndex: 0,
                    pageSize: 5,
                    sortDir: 1,
                    sortKey: "",
                    totalRange: 0
                },
                pageSizeList: ["1", "5", "10", "20", "50"]
            },
            recordType: "person",
            elPath: "results",
            nonSortableColumns: {
                person: ["summary", "random-stuff"]
            }
        });
        options.listeners = options.listeners || {};
        fluid.each(callbacks, function (callback, eventName) {
            options.listeners[eventName] = {
                listener: function (listView) {
                    callback(listView);
                },
                priority: eventName.split(".")[1]
            };
        });
        var listView = cspace.listView(container, options);
        return listView;
    };

    listViewTest.asyncTest("Init and render", function () {
        expect(31);
        setupListView({
            "afterRender.first": function (listView) {
                var headers = listView["**-renderer-headers-0"],
                    row = listView["**-renderer-row-1"],
                    headersList = headers.locate("header"),
                    columnList = row.locate("column"),
                    child,
                    pageSizeList = $("option", listView.locate("pageSize")),
                    nonSortableColumns = fluid.get(listView.options.nonSortableColumns, listView.options.recordType) || [];

                jqUnit.assertEquals("Headers block is rendered", 1, listView.locate("headers").length);
                jqUnit.assertEquals("Headers block has rsf:id", "header:", listView.locate("headers").attr("rsf:id"));
                jqUnit.assertEquals("Row block has rsf:id", "row:", listView.locate("row").attr("rsf:id"));
                jqUnit.assertEquals("Number of headers is correct", 3, headersList.length);

                fluid.each(listView.model.columns, function (column, index) {
                    jqUnit.assertEquals("Sortable class should match the model", column.sortable, headersList.eq(index).hasClass("flc-pager-sort-header"));
                    child = headersList.eq(index).children();
                    jqUnit.assertEquals("Header column has a proper sorting functionality", column.sortable, $.inArray(column["id"], nonSortableColumns) === -1);
                    jqUnit.assertEquals("Sortable header column should be ", column.sortable ? "A" : "SPAN", child[0].tagName);
                    jqUnit.assertEquals("Header column has rsf:id", column.id, child.attr("rsf:id"));
                });

                fluid.each(listView.model.columns, function (column, index) {
                    child = columnList.eq(index);
                    jqUnit.assertEquals("Header column has rsf:id", column.id, child.attr("rsf:id"));
                });

                jqUnit.assertEquals("Message for show should be", listView.options.parentBundle.messageBase["listView-show"], listView.locate("show").text());
                jqUnit.assertEquals("Message for perPage should be", listView.options.parentBundle.messageBase["listView-perPage"], listView.locate("perPage").text());
                jqUnit.assertEquals("Message for next should be", listView.options.parentBundle.messageBase["listView-next"], listView.locate("next").text());
                jqUnit.assertEquals("Message for previous should be", listView.options.parentBundle.messageBase["listView-previous"], listView.locate("previous").text());

                fluid.each(listView.model.pageSizeList, function (pageSize, index) {
                    jqUnit.assertEquals("Page Size list should contain", pageSize, pageSizeList.eq(index).val());
                });
            }, "afterRender.last": function (listView) {
                jqUnit.assertValue("Page should be initialized", listView.pager);
            }, "ready.last": function (listView) {
                jqUnit.assertTrue("List should not be empty", listView.model.list.length > 0);
                jqUnit.assertEquals("Number of rows should be equal to the limit per page", listView.model.pagerModel.pageSize, listView.locate("row").length);
                start();
            }
        }, undefined);
    });
};
$(document).ready(function () {
    listViewTester($);
    }
);<commit_msg>CSPACE-5998: Add test for ListView loading more than once.<commit_after>/*
Copyright 2011 Museum of Moving Image

Licensed under the Educational Community License (ECL), Version 2.0.
ou may not use this file except in compliance with this License.

You may obtain a copy of the ECL 2.0 License at
https://source.collectionspace.org/collection-space/LICENSE.txt
*/

/*global jqUnit, jQuery, cspace, fluid, start, stop, ok, expect*/
"use strict";

cspace.test = cspace.test || {};

var listViewTester = function ($) {

    var container = ".listView-container";

    var bareListViewTest = new jqUnit.TestCase("List View Tests");

    var listViewTest = cspace.tests.testEnvironment({
        testCase: bareListViewTest
    });

    var setupListView = function (callbacks, options) {
        options = fluid.merge(null, options || {}, {
            model: {
                sortable: {},
                columns: [{
                    sortable: true,
                    id: "number",
                    name: "listView-number"
                }, {
                    sortable: false,
                    id: "summary",
                    name: "listView-summary"
                }, {
                    sortable: true,
                    id: "summarylist.updatedAt",
                    name: "listView-updatedAt"
                }],
                pagerModel: {
                    pageCount: 1,
                    pageIndex: 0,
                    pageSize: 5,
                    sortDir: 1,
                    sortKey: "",
                    totalRange: 0
                },
                pageSizeList: ["1", "5", "10", "20", "50"]
            },
            recordType: "person",
            elPath: "results",
            nonSortableColumns: {
                person: ["summary", "random-stuff"]
            }
        });
        options.listeners = options.listeners || {};
        fluid.each(callbacks, function (callback, eventName) {
            options.listeners[eventName] = {
                listener: function (listView) {
                    callback(listView);
                },
                priority: eventName.split(".")[1]
            };
        });
        var listView = cspace.listView(container, options);
        return listView;
    };

    listViewTest.asyncTest("Init and render", function () {
        expect(31);
        setupListView({
            "afterRender.first": function (listView) {
                var headers = listView["**-renderer-headers-0"],
                    row = listView["**-renderer-row-1"],
                    headersList = headers.locate("header"),
                    columnList = row.locate("column"),
                    child,
                    pageSizeList = $("option", listView.locate("pageSize")),
                    nonSortableColumns = fluid.get(listView.options.nonSortableColumns, listView.options.recordType) || [];

                jqUnit.assertEquals("Headers block is rendered", 1, listView.locate("headers").length);
                jqUnit.assertEquals("Headers block has rsf:id", "header:", listView.locate("headers").attr("rsf:id"));
                jqUnit.assertEquals("Row block has rsf:id", "row:", listView.locate("row").attr("rsf:id"));
                jqUnit.assertEquals("Number of headers is correct", 3, headersList.length);

                fluid.each(listView.model.columns, function (column, index) {
                    jqUnit.assertEquals("Sortable class should match the model", column.sortable, headersList.eq(index).hasClass("flc-pager-sort-header"));
                    child = headersList.eq(index).children();
                    jqUnit.assertEquals("Header column has a proper sorting functionality", column.sortable, $.inArray(column["id"], nonSortableColumns) === -1);
                    jqUnit.assertEquals("Sortable header column should be ", column.sortable ? "A" : "SPAN", child[0].tagName);
                    jqUnit.assertEquals("Header column has rsf:id", column.id, child.attr("rsf:id"));
                });

                fluid.each(listView.model.columns, function (column, index) {
                    child = columnList.eq(index);
                    jqUnit.assertEquals("Header column has rsf:id", column.id, child.attr("rsf:id"));
                });

                jqUnit.assertEquals("Message for show should be", listView.options.parentBundle.messageBase["listView-show"], listView.locate("show").text());
                jqUnit.assertEquals("Message for perPage should be", listView.options.parentBundle.messageBase["listView-perPage"], listView.locate("perPage").text());
                jqUnit.assertEquals("Message for next should be", listView.options.parentBundle.messageBase["listView-next"], listView.locate("next").text());
                jqUnit.assertEquals("Message for previous should be", listView.options.parentBundle.messageBase["listView-previous"], listView.locate("previous").text());

                fluid.each(listView.model.pageSizeList, function (pageSize, index) {
                    jqUnit.assertEquals("Page Size list should contain", pageSize, pageSizeList.eq(index).val());
                });
            }, "afterRender.last": function (listView) {
                jqUnit.assertValue("Page should be initialized", listView.pager);
            }, "ready.last": function (listView) {
                jqUnit.assertTrue("List should not be empty", listView.model.list.length > 0);
                jqUnit.assertEquals("Number of rows should be equal to the limit per page", listView.model.pagerModel.pageSize, listView.locate("row").length);
                start();
            }, "afterUpdate.last": function (listView) {
                // CSPACE-5998: Shouldn't get here. If afterUpdate fires, it means the list was loaded more than once.
                jqUnit.assertTrue("The list should only load once", false);
            }
        }, undefined);
    });
};
$(document).ready(function () {
    listViewTester($);
    }
);<|endoftext|>


<commit_before>/*
 * Copyright (c) Maximilian Antoni <max@javascript.studio>
 */
'use strict';

const chalk = require('chalk');
const source_map = require('source-map');

const SPACES = new Array(80).join(' ');

function source(src, loc) {
  const c1 = loc.start.column;
  const c2 = loc.start.line === loc.end.line ? loc.end.column : src.length;
  const pre = src.substring(0, c1);
  const hi = src.substring(c1, c2);
  const post = src.substring(c2);
  return `${pre}${chalk.yellow.underline(hi)}${post}`;
}

function pad_line_number(num) {
  return num < 10 ? `   ${num} ` : (num < 100 ? `  ${num} ` : ` ${num} `);
}

function line_number(pos) {
  return chalk.bgBlack.gray(pad_line_number(pos.line || 0));
}

function section(errs, title, color, source_map_consumer) {
  if (!errs.length) {
    return;
  }
  const heading = `${title}${SPACES.substring(title.length)}`;
  console.log(`\n${chalk[color](chalk.bold.underline(heading))}\n`);

  const errs_by_file = [];
  const errs_index = {};
  for (let i = 0, l = errs.length; i < l; i++) {
    const e = errs[i];
    if (source_map_consumer) {
      const mapped = source_map_consumer.originalPositionFor(e.loc.start);
      e.file = mapped.source || '[unknown]';
    } else {
      e.file = '[stdin]';
    }
    if (errs_index.hasOwnProperty(e.file)) {
      errs_by_file[errs_index[e.file]].errs.push(e);
    } else {
      errs_index[e.file] = errs_by_file.length;
      errs_by_file.push({
        file: e.file,
        errs: [e]
      });
    }
  }
  errs_by_file.forEach(err => {
    console.log(`\n📄  ${err.file}\n\n`);
    err.errs.forEach(err => {
      let pos = err.loc.start;
      if (source_map_consumer) {
        pos = source_map_consumer.originalPositionFor(pos);
      }
      const line = line_number(pos);
      const code = source(err.source, err.loc);
      console.log(chalk[color](`   ${err.name}: ${err.message}`));
      if (code) {
        console.log(`   ${line} ${code}\n`);
      }
      err.occurrences[0].stack.forEach(s => {
        let m = s.match(/:([0-9]+):([0-9]+)$/);
        let line = null;
        let column = null;
        let name = null;
        let file_loc = null;
        if (m) {
          line = m[1];
          column = m[2];
        } else {
          m = s.match(/at ([^ ]+) \(.+:([0-9]+):([0-9]+)\)$/);
          if (!m) {
            console.log(`      ${s}`);
            return;
          }
          name = m[1];
          line = m[2];
          column = m[3];
        }
        if (source_map_consumer) {
          const mapped = source_map_consumer.originalPositionFor({
            line: Number(line),
            column: Number(column)
          });
          if (mapped.source
              && mapped.source.indexOf('node_modules/browser-pack/') === -1) {
            file_loc = `${mapped.source}:${mapped.line}:${column}`;
          }
        } else {
          file_loc = `[stdin]:${line}:${column}`;
        }
        if (file_loc && name) {
          console.log(`      at ${name} (${file_loc})`);
        } else if (file_loc) {
          console.log(`      at ${file_loc}`);
        } else if (name) {
          console.log(`      at ${name}`);
        }
      });
      console.log('');
    });
  });
  console.log('');
}

function stats(report) {
  const nodes = report.evaluated_nodes;
  const percent = Math.round(nodes * 100 / report.total_nodes);
  const seconds = (report.duration / 1000).toFixed(1);
  console.log('');
  console.log(`${chalk.gray('Build Duration:')}  ${seconds}s`);
  if (nodes) {
    console.log(`${chalk.gray('Nodes Analyzed:')}  ${nodes} = ${percent}%`);
  }
  if (report.api_functions) {
    console.log(`${chalk.gray('API Functions:')}   ${report.api_functions}`);
  }
  console.log('');
}

module.exports = function (report, map) {
  stats(report);
  const consumer = map ? new source_map.SourceMapConsumer(map) : null;
  section(report.errors.parser, 'Parser Errors', 'red', consumer);
  section(report.errors.runtime, 'Runtime Errors', 'red', consumer);
  if (report.exceptions) {
    section(report.exceptions.thrown, 'Thrown Exceptions', 'magenta', consumer);
  }
};
<commit_msg>Show source snippet from source map<commit_after>/*
 * Copyright (c) Maximilian Antoni <max@javascript.studio>
 */
'use strict';

const chalk = require('chalk');
const source_map = require('source-map');

const SPACES = new Array(80).join(' ');

function highlight_source(src, loc) {
  const c1 = loc.start.column;
  const c2 = loc.start.line === loc.end.line ? loc.end.column : src.length;
  const pre = src.substring(0, c1);
  const hi = src.substring(c1, c2);
  const post = src.substring(c2);
  return `${pre}${chalk.yellow.underline(hi)}${post}`;
}

function pad_line_number(num) {
  return num < 10 ? `   ${num} ` : (num < 100 ? `  ${num} ` : ` ${num} `);
}

function line_number(pos) {
  return chalk.bgBlack.gray(pad_line_number(pos.line || 0));
}

function section(errs, title, color, source_map_consumer) {
  if (!errs.length) {
    return;
  }
  const heading = `${title}${SPACES.substring(title.length)}`;
  console.log(`\n${chalk[color](chalk.bold.underline(heading))}\n`);

  const errs_by_file = [];
  const errs_index = {};
  for (let i = 0, l = errs.length; i < l; i++) {
    const e = errs[i];
    if (source_map_consumer) {
      const mapped = source_map_consumer.originalPositionFor(e.loc.start);
      e.file = mapped.source || '[unknown]';
    } else {
      e.file = '[stdin]';
    }
    if (errs_index.hasOwnProperty(e.file)) {
      errs_by_file[errs_index[e.file]].errs.push(e);
    } else {
      errs_index[e.file] = errs_by_file.length;
      errs_by_file.push({
        file: e.file,
        errs: [e]
      });
    }
  }
  errs_by_file.forEach(err => {
    console.log(`\n📄  ${err.file}\n\n`);
    err.errs.forEach(err => {
      let source = err.source;
      let loc = err.loc;
      if (source_map_consumer) {
        const start = source_map_consumer.originalPositionFor(loc.start);
        if (start.source) {
          const src = source_map_consumer.sourceContentFor(start.source, true);
          if (src) {
            source = src.split('\n')[start.line - 1];
            const end = source_map_consumer.originalPositionFor(loc.start);
            if (start.column === 0 && end.column === 0) {
              start.column = loc.start.column;
              end.column = loc.end.column;
            }
            loc = { start, end };
          }
        }
      }
      const line = line_number(loc.start);
      const code = highlight_source(source, loc);
      console.log(chalk[color](`   ${err.name}: ${err.message}`));
      if (code) {
        console.log(`   ${line} ${code}\n`);
      }
      err.occurrences[0].stack.forEach(s => {
        let m = s.match(/:([0-9]+):([0-9]+)$/);
        let line = null;
        let column = null;
        let name = null;
        let file_loc = null;
        if (m) {
          line = m[1];
          column = m[2];
        } else {
          m = s.match(/at ([^ ]+) \(.+:([0-9]+):([0-9]+)\)$/);
          if (!m) {
            console.log(`      ${s}`);
            return;
          }
          name = m[1];
          line = m[2];
          column = m[3];
        }
        if (source_map_consumer) {
          const mapped = source_map_consumer.originalPositionFor({
            line: Number(line),
            column: Number(column)
          });
          if (mapped.source
              && mapped.source.indexOf('node_modules/browser-pack/') === -1) {
            file_loc = `${mapped.source}:${mapped.line}:${column}`;
          }
        } else {
          file_loc = `[stdin]:${line}:${column}`;
        }
        if (file_loc && name) {
          console.log(`      at ${name} (${file_loc})`);
        } else if (file_loc) {
          console.log(`      at ${file_loc}`);
        } else if (name) {
          console.log(`      at ${name}`);
        }
      });
      console.log('');
    });
  });
  console.log('');
}

function stats(report) {
  const nodes = report.evaluated_nodes;
  const percent = Math.round(nodes * 100 / report.total_nodes);
  const seconds = (report.duration / 1000).toFixed(1);
  console.log('');
  console.log(`${chalk.gray('Build Duration:')}  ${seconds}s`);
  if (nodes) {
    console.log(`${chalk.gray('Nodes Analyzed:')}  ${nodes} = ${percent}%`);
  }
  if (report.api_functions) {
    console.log(`${chalk.gray('API Functions:')}   ${report.api_functions}`);
  }
  console.log('');
}

module.exports = function (report, map) {
  stats(report);
  const consumer = map ? new source_map.SourceMapConsumer(map) : null;
  section(report.errors.parser, 'Parser Errors', 'red', consumer);
  section(report.errors.runtime, 'Runtime Errors', 'red', consumer);
  if (report.exceptions) {
    section(report.exceptions.thrown, 'Thrown Exceptions', 'magenta', consumer);
  }
};
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var domify = require('domify');
var merge = require('merge-util');

/**
 * Render default modules
 */

var citizen = require('citizen');
var translation = require('t');
var config = require('config');

exports = module.exports = render;
exports.dom = dom;

function render(template, options) {
  var defaults = {
    citizen: citizen,
    t: translation,
    config: config
  };

  return template(merge(defaults,options));
}

function dom(template, options) {
  return domify(render(template, options));
}
<commit_msg>Add support for inheritance locals merge at render<commit_after>/**
 * Module dependencies.
 */

var domify = require('domify');
var merge = require('merge-util');

/**
 * Render default modules
 */

var citizen = require('citizen');
var translation = require('t');
var config = require('config');

exports = module.exports = render;
exports.dom = dom;

function render(template, options) {
  var defaults = {
    citizen: citizen,
    t: translation,
    config: config
  };

  return template(merge(defaults, options, true));
}

function dom(template, options) {
  return domify(render(template, options));
}
<|endoftext|>


<commit_before>cg.Renderer.Grid = (function () {

    /**
     * Create a dynamic background grid.
     * @param paper {Element}
     * @param config {Object}
     * @constructor
     */
    function Grid(paper, config) {
        this._config = config || {
            "pattern-size": 10,
            "step-size": 5,
            "line": {
                "stroke": "rgba(255, 255, 255, 0.05)",
                "stroke-width": 2
            },
            "big-line": {
                "stroke": "rgba(255, 255, 255, 0.2)",
                "stroke-width": 3
            }
        };
        this._paper = paper;
        this._rect = paper.rect(0, 0, "100%", "100%");
        this._cross = this._paper.g();
        this._xLines = [];
        for (var y = 0; y < this._config["step-size"]; ++y) {
            this._xLines.push(this._cross.line(0, 0, 0, 0));
        }
        this._yLines = [];
        for (var x = 0; x < this._config["step-size"]; ++x) {
            this._yLines.push(this._cross.line(0, 0, 0, 0));
        }
    }

    /**
     * Update the grid according the current zoom and pan values.
     * @param zoomTransform {SVGMatrix}
     */
    Grid.prototype.update = function (zoomTransform) {
        var size = zoomTransform.a * this._config["pattern-size"];
        var pan = {x: zoomTransform.e, y: zoomTransform.f};
        var s = this._config["step-size"];
        for (var y = 1; y < s; ++y) {
            this._xLines[y].attr({
                "x1": ~~(pan.x),
                "y1": ~~(pan.y + y * size),
                "x2": ~~(pan.x + size * s),
                "y2": ~~(pan.y + y * size)
            }).attr(this._config["line"]);
        }
        for (var x = 1; x < s; ++x) {
            this._yLines[x].attr({
                "x1": ~~(pan.x + x * size),
                "y1": ~~(pan.y),
                "x2": ~~(pan.x + x * size),
                "y2": ~~(pan.y + size * s)
            }).attr(this._config["line"]);
        }
        this._xLines[0].attr({
            "x1": ~~(pan.x),
            "y1": ~~(pan.y),
            "x2": ~~(pan.x + size * s),
            "y2": ~~(pan.y)
        }).attr(this._config["big-line"]);
        this._yLines[0].attr({
            "x1": ~~(pan.x),
            "y1": ~~(pan.y),
            "x2": ~~(pan.x),
            "y2": ~~(pan.y + size * s)
        }).attr(this._config["big-line"]);
        this._rect.attr({"fill": this._cross.pattern(~~pan.x, ~~pan.y, ~~(size * s), ~~(size * s))});
    };

    /**
     * Round the given value to match grid lines.
     * @param value {Number} the value to round
     * @param bigger {Boolean?} Whether to use the big lines or the small ones.
     */
    Grid.prototype.round = function (value, bigger) {
        var s = bigger ? this._config["pattern-size"] * this._config["step-size"] : this._config["pattern-size"];
        return value % s === 0 ? value : value - value % s + s;
    };

    return Grid;

})();<commit_msg>Fix precision on grid display #18<commit_after>cg.Renderer.Grid = (function () {

    /**
     * Create a dynamic background grid.
     * @param paper {Element}
     * @param config {Object}
     * @constructor
     */
    function Grid(paper, config) {
        this._config = config || {
            "pattern-size": 10,
            "step-size": 5,
            "line": {
                "stroke": "rgba(255, 255, 255, 0.05)",
                "stroke-width": 2
            },
            "big-line": {
                "stroke": "rgba(255, 255, 255, 0.2)",
                "stroke-width": 3
            }
        };
        this._paper = paper;
        this._rect = paper.rect(0, 0, "100%", "100%");
        this._cross = this._paper.g();
        this._xLines = [];
        for (var y = 0; y < this._config["step-size"]; ++y) {
            this._xLines.push(this._cross.line(0, 0, 0, 0));
        }
        this._yLines = [];
        for (var x = 0; x < this._config["step-size"]; ++x) {
            this._yLines.push(this._cross.line(0, 0, 0, 0));
        }
    }

    /**
     * Update the grid according the current zoom and pan values.
     * @param zoomTransform {SVGMatrix}
     */
    Grid.prototype.update = function (zoomTransform) {
        var size = zoomTransform.a * this._config["pattern-size"];
        var pan = {x: zoomTransform.e, y: zoomTransform.f};
        var s = this._config["step-size"];
        var toInt = function (value) {
            return Math.floor(value * 100) / 100;
        };
        for (var y = 1; y < s; ++y) {
            this._xLines[y].attr({
                "x1": toInt(pan.x),
                "y1": toInt(pan.y + y * size),
                "x2": toInt(pan.x + size * s),
                "y2": toInt(pan.y + y * size)
            }).attr(this._config["line"]);
        }
        for (var x = 1; x < s; ++x) {
            this._yLines[x].attr({
                "x1": toInt(pan.x + x * size),
                "y1": toInt(pan.y),
                "x2": toInt(pan.x + x * size),
                "y2": toInt(pan.y + size * s)
            }).attr(this._config["line"]);
        }
        this._xLines[0].attr({
            "x1": toInt(pan.x),
            "y1": toInt(pan.y),
            "x2": toInt(pan.x + size * s),
            "y2": toInt(pan.y)
        }).attr(this._config["big-line"]);
        this._yLines[0].attr({
            "x1": toInt(pan.x),
            "y1": toInt(pan.y),
            "x2": toInt(pan.x),
            "y2": toInt(pan.y + size * s)
        }).attr(this._config["big-line"]);
        var xPattern = toInt(pan.x);
        var yPattern = toInt(pan.y);
        var sizePattern = toInt(size * s);
        this._rect.attr({"fill": this._cross.pattern(xPattern, yPattern, sizePattern, sizePattern)});
    };

    /**
     * Round the given value to match grid lines.
     * @param value {Number} the value to round
     * @param bigger {Boolean?} Whether to use the big lines or the small ones.
     */
    Grid.prototype.round = function (value, bigger) {
        var s = bigger ? this._config["pattern-size"] * this._config["step-size"] : this._config["pattern-size"];
        return value % s === 0 ? value : value - value % s + s;
    };

    return Grid;

})();<|endoftext|>


<commit_before>var Utils = require('./utils')

var BLOCK_CHAR = {
  WW: ' ',
  WB: '▄',
  BB: '█',
  BW: '▀'
}

function getBlockChar (top, bottom) {
  if (top && bottom) return BLOCK_CHAR.BB
  if (top && !bottom) return BLOCK_CHAR.BW
  if (!top && bottom) return BLOCK_CHAR.WB
  return BLOCK_CHAR.WW
}

exports.render = function (qrData, options, cb) {
  var size = qrData.modules.size
  var data = qrData.modules.data

  var opts = Utils.getOptions(options)

  var output = ''
  var hMargin = Array(size + (opts.margin * 2) + 1).join(BLOCK_CHAR.WW)
  hMargin = Array((opts.margin / 2) + 1).join(hMargin + '\n')

  var vMargin = Array(opts.margin + 1).join(BLOCK_CHAR.WW)

  output += hMargin
  for (var i = 0; i < size; i += 2) {
    output += vMargin
    for (var j = 0; j < size; j++) {
      var topModule = data[i * size + j]
      var bottomModule = data[(i + 1) * size + j]

      output += getBlockChar(topModule, bottomModule)
    }

    output += vMargin + '\n'
  }

  output += hMargin.slice(0, -1)

  if (typeof cb === 'function') {
    cb(null, output)
  }

  return output
}

exports.renderToFile = function renderToFile (path, qrData, options, cb) {
  if (typeof cb === 'undefined') {
    cb = options
    options = undefined
  }

  var fs = require('fs')
  var utf8 = exports.render(qrData, options)
  fs.writeFile(path, utf8, cb)
}
<commit_msg>feat: inverting colors on utf8 rendered codes<commit_after>var Utils = require('./utils')

var BLOCK_CHAR = {
  WW: ' ',
  WB: '▄',
  BB: '█',
  BW: '▀'
}

var INVERTED_BLOCK_CHAR = {
  BB: ' ',
  BW: '▄',
  WW: '█',
  WB: '▀'
}

function getBlockChar (top, bottom, blocks) {
  if (top && bottom) return blocks.BB
  if (top && !bottom) return blocks.BW
  if (!top && bottom) return blocks.WB
  return blocks.WW
}

exports.render = function (qrData, options, cb) {
  var opts = Utils.getOptions(options)
  var blocks = BLOCK_CHAR
  if (opts.color.dark.hex === '#ffffff' || opts.color.light.hex === '#000000') {
    blocks = INVERTED_BLOCK_CHAR
  }

  var size = qrData.modules.size
  var data = qrData.modules.data

  var output = ''
  var hMargin = Array(size + (opts.margin * 2) + 1).join(blocks.WW)
  hMargin = Array((opts.margin / 2) + 1).join(hMargin + '\n')

  var vMargin = Array(opts.margin + 1).join(blocks.WW)

  output += hMargin
  for (var i = 0; i < size; i += 2) {
    output += vMargin
    for (var j = 0; j < size; j++) {
      var topModule = data[i * size + j]
      var bottomModule = data[(i + 1) * size + j]

      output += getBlockChar(topModule, bottomModule, blocks)
    }

    output += vMargin + '\n'
  }

  output += hMargin.slice(0, -1)

  if (typeof cb === 'function') {
    cb(null, output)
  }

  return output
}

exports.renderToFile = function renderToFile (path, qrData, options, cb) {
  if (typeof cb === 'undefined') {
    cb = options
    options = undefined
  }

  var fs = require('fs')
  var utf8 = exports.render(qrData, options)
  fs.writeFile(path, utf8, cb)
}
<|endoftext|>


<commit_before>'use strict';

const dasherize = require('ember-cli-string-utils').dasherize;
const stringUtils = require('ember-cli-string-utils');

module.exports = {
  description: 'Ember CLI blueprint for initializing a new Glimmer application',

  // filesToRemove: [
  //   'app/styles/.gitkeep',
  //   'app/templates/.gitkeep',
  // ],

  locals(options) {
    let name = options.entity.name;
    let component = componentize(name);
    let className = stringUtils.classify(options.entity.name);

    return { name, className, component };
  },

  fileMapTokens(options) {
    return {
      __component__() { return options.locals.component }
    }
  },

  afterInstall(options) {
    if (options.webComponent) {
      return this._installWebComponentSupport(options);
    }
  },

  _installWebComponentSupport(options) {
    let name = options.entity.name;
    let component = componentize(name);

    let addPackagePromise = this.addPackageToProject('@glimmer/web-component');
    let indexTSPromise = this.insertIntoFile(
      'src/index.ts',
      "import initializeCustomElements from '@glimmer/web-component';",
      { after: "import { ComponentManager, setPropertyDidChange } from '@glimmer/component';\n" }
    ).then(() => {
      return this.insertIntoFile(
        'src/index.ts',
        `initializeCustomElements(app, ['${component}']);\n`
      );
    });

    return Promise.all([
      addPackagePromise,
      indexTSPromise
    ]);
  }
};

// Component names must have at least one dash, so we suffix the component name
// with `-app` if it doesn't have one. E.g.: `avatar` -> `avatar-app`
function componentize(name) {
  let dasherized = dasherize(name);
  return hasDash(dasherized) ? dasherized : `${dasherized}-app`;
}

function hasDash(string) {
  return string.indexOf('-') > -1;
}
<commit_msg>Do not include yarn.lock in upgrades<commit_after>'use strict';

const dasherize = require('ember-cli-string-utils').dasherize;
const stringUtils = require('ember-cli-string-utils');

module.exports = {
  description: 'Ember CLI blueprint for initializing a new Glimmer application',

  // filesToRemove: [
  //   'app/styles/.gitkeep',
  //   'app/templates/.gitkeep',
  // ],

  locals(options) {
    let name = options.entity.name;
    let component = componentize(name);
    let className = stringUtils.classify(options.entity.name);

    return { name, className, component };
  },

  fileMapTokens(options) {
    return {
      __component__() { return options.locals.component }
    }
  },

  files() {
    let files = this._super.files.apply(this, arguments);

    if (this.project.pkg.name) {
      files = files.filter((file) => file !== 'yarn.lock');
    }

    return files;
  },

  afterInstall(options) {
    if (options.webComponent) {
      return this._installWebComponentSupport(options);
    }
  },

  _installWebComponentSupport(options) {
    let name = options.entity.name;
    let component = componentize(name);

    let addPackagePromise = this.addPackageToProject('@glimmer/web-component');
    let indexTSPromise = this.insertIntoFile(
      'src/index.ts',
      "import initializeCustomElements from '@glimmer/web-component';",
      { after: "import { ComponentManager, setPropertyDidChange } from '@glimmer/component';\n" }
    ).then(() => {
      return this.insertIntoFile(
        'src/index.ts',
        `initializeCustomElements(app, ['${component}']);\n`
      );
    });

    return Promise.all([
      addPackagePromise,
      indexTSPromise
    ]);
  }
};

// Component names must have at least one dash, so we suffix the component name
// with `-app` if it doesn't have one. E.g.: `avatar` -> `avatar-app`
function componentize(name) {
  let dasherized = dasherize(name);
  return hasDash(dasherized) ? dasherized : `${dasherized}-app`;
}

function hasDash(string) {
  return string.indexOf('-') > -1;
}
<|endoftext|>


<commit_before>import { fileMissing,
         writeFile,
         writeManager,
         writeFileWithDownload   } from '../file-system/file';
import { patchAsset } from '../patch';
import _ from 'lodash';
import Promise from 'promise';

export function getAsset (_owner, _asset, action) {
  return new Promise(function (resolve, reject) {
    _owner.insales.getAsset({
      token: _owner.options.token,
      url: _owner.options.url,
      theme: _owner.options.theme,
      assetId: _asset.id
    }).then(response => {
      var dataReponse = response.data.asset;
      var _contents = dataReponse.content
      var _uri = 'http://' + _owner.options.url + dataReponse.asset_url;
      const _status = fileMissing(_asset.path)

      _status.then(function () {
        action.rewrite = true;
        writeManager(_asset, _uri, dataReponse, action, _owner, resolve(response.data.asset));
      }, function () {
        if (_owner.options.update) {
          action.rewrite = true;
          writeManager(_asset, _uri, dataReponse, action, _owner, resolve(response.data.asset));
        }else{
          if (action.method == 'backup' || _owner.options.startBackup) {
            action.rewrite = false;
            writeManager(_asset, _uri, dataReponse, action, _owner, resolve(response.data.asset));
          }else{
            reject(response.data.asset)
          }
        }
      })
    }).catch(err => {
      console.error('error: ' + _asset.name, err.url);
      reject(err.msg)
    });

  });
}

export function getAssets (_owner, action) {
  return new Promise(function (resolve, reject){
    var _size = _.size(_owner.downloadList);
    var _count = 0;
    recursionDownload(_owner, _count, _size, action).then(function () {
      setTimeout(function () {
        resolve();
      }, 400);
    })
  });
}

function recursionDownload(_owner, count, size, action) {
  return new Promise(function (resolve, reject){
  _recursion(_owner, count, size, action);
  function _recursion(_owner, count, size, action) {
    setTimeout(function () {
      getAsset(_owner, _owner.downloadList[count], action).then(function (_asset) {
        ++count
        if (count === size) {
          resolve()
        }else{
          return _recursion(_owner, count, size, action)
        }
      }, function (_asset) {
        ++count
        if (count === size) {
          resolve()
        }else{
          return _recursion(_owner, count, size, action)
        }
      })
    }, 300)
  }
  });
}
export function upadeteAssets(_owner) {
  return new Promise(function (resolve, reject) {
  if (_owner.state.inProcess) {
    setTimeout(function (_owner) {
      upadeteAssets (_owner);
    }, 300)
  }else{
    _owner.state.inProcess = true;
    _owner.insales.listAsset({
      token: _owner.options.token,
      url: _owner.options.url,
      theme: _owner.options.theme
    }).then(response => {
      var _assets = response.data.assets.asset;
      patchAsset(_owner, _assets).then(function () {
        resolve()
        _owner.state.inProcess = false;
      })
    }).catch(err => {
      console.info(err.msg);
      _owner.state.inProcess = false;
      reject(err.msg);
    });
  }
  });
}

export function uploadAsset (_owner, asset, _path) {

  return new Promise(function (resolve, reject) {
  if (_owner.state.inProcess) {
    setTimeout(function (_owner, asset, _path) {
      uploadAsset (_owner, asset, _path);
    }, 300)
  }else{
      _owner.uploading = true;
      _owner.insales.uploadAsset({
        token: _owner.options.token,
        url: _owner.options.url,
        theme: _owner.options.theme,
        asset
      }).then(output => {
        console.info('Upload ' + asset.type + ': '+ asset.name + ' from ' + _path);
        _owner.state.inProcess = false;
        resolve()
      }).catch(err => {
        console.error(asset.name, err.msg);
        _owner.state.inProcess = false;
        reject()
      });
    }
  });
}

export function removeAsset (_owner, assetId, path, name) {
  return new Promise(function (resolve, reject) {
  if (_owner.state.inProcess) {
    setTimeout(function (_owner, assetId, path, name) {
      removeAsset (_owner, assetId, path, name);
    }, 300)
  }else{
    _owner.insales.removeAsset({
      token: _owner.options.token,
      url: _owner.options.url,
      theme: _owner.options.theme,
      assetId: assetId,
    }).then(output => {
      delete _owner.assets[name];
      console.info('Remove: ' + path);
      resolve()
    }).catch(err => {
      console.error(name, assetId, err.msg);
      reject()
    });
   }
  });
}

export function editAsset (_owner, _asset, assetId, path) {
  return new Promise(function (resolve, reject) {
  if (_owner.state.inProcess) {
    setTimeout(function (_owner, _asset, assetId, path) {
      editAsset (_owner, _asset, assetId, path);
    }, 300)
  }else{
    _owner.insales.editAsset({
      token: _owner.options.token,
      url: _owner.options.url,
      theme: _owner.options.theme,
      assetId: assetId,
      asset: _asset
    }).then(output => {
      console.info('edit: ' + path);
      resolve();
    }).catch(err => {
      console.error(err.msg);
      reject();
    });
  }
  });
}
<commit_msg>Оптимизация обновления данных<commit_after>import { fileMissing,
         writeFile,
         writeManager,
         writeFileWithDownload   } from '../file-system/file';
import { patchAsset } from '../patch';
import _ from 'lodash';
import Promise from 'promise';

export function getAsset (_owner, _asset, action) {
  return new Promise(function (resolve, reject) {
    _owner.insales.getAsset({
      token: _owner.options.token,
      url: _owner.options.url,
      theme: _owner.options.theme,
      assetId: _asset.id
    }).then(response => {
      var dataReponse = response.data.asset;
      var _contents = dataReponse.content
      var _uri = 'http://' + _owner.options.url + dataReponse.asset_url;
      const _status = fileMissing(_asset.path)

      _status.then(function () {
        action.rewrite = true;
        writeManager(_asset, _uri, dataReponse, action, _owner, resolve(response.data.asset));
      }, function () {
        if (_owner.options.update) {
          action.rewrite = true;
          writeManager(_asset, _uri, dataReponse, action, _owner, resolve(response.data.asset));
        }else{
          if (action.method == 'backup' || _owner.options.startBackup) {
            action.rewrite = false;
            writeManager(_asset, _uri, dataReponse, action, _owner, resolve(response.data.asset));
          }else{
            reject(response.data.asset)
          }
        }
      })
    }).catch(err => {
      console.error('error: ' + _asset.name, err.url);
      reject(err.msg)
    });

  });
}

export function getAssets (_owner, action) {
  return new Promise(function (resolve, reject){
    var _size = _.size(_owner.downloadList);
    var _count = 0;
    recursionDownload(_owner, _count, _size, action).then(function () {
      setTimeout(function () {
        resolve();
      }, 400);
    })
  });
}

function recursionDownload(_owner, count, size, action) {
  return new Promise(function (resolve, reject){
  _recursion(_owner, count, size, action);
  function _recursion(_owner, count, size, action) {
    setTimeout(function () {
      getAsset(_owner, _owner.downloadList[count], action).then(function (_asset) {
        ++count
        if (count === size) {
          resolve()
        }else{
          return _recursion(_owner, count, size, action)
        }
      }, function (_asset) {
        ++count
        if (count === size) {
          resolve()
        }else{
          return _recursion(_owner, count, size, action)
        }
      })
    }, 300)
  }
  });
}
export function upadeteAssets(_owner) {
  return new Promise(function (resolve, reject) {
  if (_owner.state.inProcess) {
    setTimeout(function (_owner) {
      upadeteAssets (_owner);
    }, 300)
  }else{
    _owner.state.inProcess = true;
    _owner.insales.listAsset({
      token: _owner.options.token,
      url: _owner.options.url,
      theme: _owner.options.theme
    }).then(response => {
      var _assets = response.data.assets.asset;
      patchAsset(_owner, _assets).then(function () {
        _owner.state.inProcess = false;
        resolve()
        return _owner;
      })
    }).catch(err => {
      console.info(err.msg);
      _owner.state.inProcess = false;
      reject(err.msg);
    });
  }
  });
}

export function uploadAsset (_owner, asset, _path) {

  return new Promise(function (resolve, reject) {
  if (_owner.state.inProcess) {
    setTimeout(function (_owner, asset, _path) {
      uploadAsset (_owner, asset, _path);
    }, 300)
  }else{
      _owner.uploading = true;
      _owner.insales.uploadAsset({
        token: _owner.options.token,
        url: _owner.options.url,
        theme: _owner.options.theme,
        asset
      }).then(output => {
        console.info('Upload ' + asset.type + ': '+ asset.name + ' from ' + _path);
        upadeteAssets(_owner).then(function () {
          _owner.state.inProcess = false;
          resolve()
        })
      }).catch(err => {
        console.error(asset.name, err.msg);
        upadeteAssets(_owner).then(function () {
          _owner.state.inProcess = false;
          reject()
        })
      });
    }
  });
}

export function removeAsset (_owner, assetId, path, name) {
  return new Promise(function (resolve, reject) {
  if (_owner.state.inProcess) {
    setTimeout(function (_owner, assetId, path, name) {
      removeAsset (_owner, assetId, path, name);
    }, 300)
  }else{
    _owner.insales.removeAsset({
      token: _owner.options.token,
      url: _owner.options.url,
      theme: _owner.options.theme,
      assetId: assetId,
    }).then(output => {
      delete _owner.assets[name];
      console.info('Remove: ' + path);
      upadeteAssets(_owner).then(function () {
        _owner.state.inProcess = false;
        resolve()
      })
    }).catch(err => {
      console.error(name, assetId, err.msg);
      upadeteAssets(_owner).then(function () {
        _owner.state.inProcess = false;
        reject()
      })
    });
   }
  });
}

export function editAsset (_owner, _asset, assetId, path) {
  return new Promise(function (resolve, reject) {
  if (_owner.state.inProcess) {
    setTimeout(function (_owner, _asset, assetId, path) {
      editAsset (_owner, _asset, assetId, path);
    }, 300)
  }else{
    _owner.insales.editAsset({
      token: _owner.options.token,
      url: _owner.options.url,
      theme: _owner.options.theme,
      assetId: assetId,
      asset: _asset
    }).then(output => {
      console.info('edit: ' + path);
      resolve();
    }).catch(err => {
      console.error(err.msg);
      reject();
    });
  }
  });
}
<|endoftext|>


<commit_before>var Handlebars = require('handlebars');
var haversine = require('haversine');
var select2 = require('select2');

var BikeView = require('./bike_views');
var geocoder = require('./geocoder');

var requestFormTemplate = Handlebars.compile(require('./request-form.html'));

var RequestFormView = module.exports = Backbone.View.extend({

  events: {
    'change .apiParam': 'changeForm',
    'change #mode': 'updateModeControls',
    'click .toggleSettings': 'toggleSettings'
  },

  initialize: function(options) {
    this.options = options || {};
    _.bindAll(this, 'changeForm');

    var view = this;

    this.updatingForm = false;

    this.geocodeItem = Handlebars.compile([
      '{{text}}',
      '{{#if city}}{{city}}, {{state}}{{/if}}'
    ].join('\n'));

    this.selectedGeocodeItem = Handlebars.compile([
      '{{text}}{{#if city}}, {{city}}, {{state}}{{/if}}'
    ].join('\n'));

    this.model.on('change', function(data) {

      if (_.has(data.changed, 'fromPlace') && data.attributes.fromPlace && view.selectFrom) {
        view.updateReverseGeocoder('From', data.attributes.fromPlace, view.selectFrom);
      }

      if (_.has(data.changed, 'toPlace') && data.attributes.toPlace && view.selectTo) {
        view.updateReverseGeocoder('To', data.attributes.toPlace, view.selectTo);
      }

      view.$('#arriveBy').val(data.attributes.arriveBy);
      view.$('#mode').val(data.attributes.mode);
      view.$('#maxWalkDistance').val(data.attributes.maxWalkDistance);
      view.$('#optimize').val(data.attributes.optimize);

      var date = moment(data.attributes.date, 'MM-DD-YYYY').toDate();
      view.datepicker.setDate(date);

      var time = moment(data.attributes.time, 'hh:mm a').toDate();
      view.timepicker.setDate(time);

      view.updateModeControls();
    });
  },

  updateReverseGeocoder: function(field, latlon, select) {
    var view = this;

    if (window.OTP_config.reverseGeocode) {
      geocoder.reverse(latlon, function(err, results) {
        view.updatingForm = true;
        if (err) {
          select.select2('data', []);
        } else {
          select.select2('data', null);
          results.text = field + ' ' + results.address;
          select.select2('data', results);
        }
        view.updatingForm = false;
      });
    } else {

      // this isn't great but appears to be neccesary as selectize triggers a change event even when programatically updated
      view.updatingForm = true;

      var item = {
        text: field + ' marker location',
        id: latlon
      };

      select.select2('data', item);

      view.updatingForm = false;

    }
  },

  render: function() {

    var view = this;

    var html = requestFormTemplate({
      metric: this.options.metric || false
    });

    this.lastResults = [];

    this.$el.html(html);

    this.$('#showSettings').hide();

    view.updatingForm = true;

    this.$('#date').datetimepicker({
      pickTime: false
    });

    this.datepicker = this.$('#date').data('DateTimePicker');
    this.datepicker.setDate(new Date());
    this.$('#date').on('changeDate', this.changeForm);

    this.$('#time').datetimepicker({
      pick12HourFormat: true,
      pickSeconds: false,
      pickDate: false
    });

    this.timepicker = this.$('#time').data('DateTimePicker');
    this.timepicker.setDate(new Date());
    this.$('#time').on('changeDate', this.changeForm);

    this.bikeTriangle = new BikeView({
      model: this.model,
      el: this.$('#bikeTriangle')
    });

    this.selectFrom = this.initializeSelectFor('from');
    this.selectTo = this.initializeSelectFor('to');

    view.updatingForm = false;

    this.changeForm();
    this.updateModeControls();
  },

  changeForm: function(evt) {

    // skip duplicate change events caused by selectize form inputs
    if (this.updatingForm)
      return;

    var maxDistance = $('#mode').val().indexOf('WALK') != -1 ?
      $('#maxWalkDistance').val() : $('#maxBikeDistance').val();

    var data = {
      fromPlace: this.$('#fromPlace').select2('val'),
      toPlace: this.$('#toPlace').select2('val'),
      date: this.$('#date input').val(),
      time: this.$('#time input').val(),
      arriveBy: this.$('#arriveBy').val(),
      maxWalkDistance: maxDistance,
      optimize: this.$('#optimize').val(),
      mode: this.$('#mode').val()
    };

    // skip if either to/from fields are unset
    if (this.$('#fromPlace').select2('val') == 'not found')
      data.fromPlace = false;
    if (this.$('#toPlace').select2('val') == 'not found')
      data.toPlace = false;

    var mode = $('#mode').val();
    if (mode.indexOf('BICYCLE') != -1) {
      data.triangleSafetyFactor = $('#').val();
      data.triangleSlopeFactor = $('#').val();
      data.triangleTimeFactor = $('#').val();
    } else {
      this.model.unset('triangleSafetyFactor', {
        silent: true
      });
      this.model.unset('triangleSlopeFactor', {
        silent: true
      });
      this.model.unset('triangleTimeFactor', {
        silent: true
      });
    }

    this.model.set(data);
  },

  updateModeControls: function() {
    var mode = $('#mode').val();

    if (mode.indexOf('WALK') != -1 && mode.indexOf('TRANSIT') != -1) this.$el
      .find('.maxWalkControl').show();
    else this.$el.find('.maxWalkControl').hide();

    if (mode.indexOf('BICYCLE') != -1 && mode.indexOf('TRANSIT') != -1) this
      .$el.find('.maxBikeControl').show();
    else this.$el.find('.maxBikeControl').hide();

    if (mode.indexOf('TRANSIT') != -1 && mode.indexOf('BICYCLE') == -1)
      this.$el.find('.optimizeControl').show();
    else
      this.$el.find('.optimizeControl').hide();

    if (mode.indexOf('BICYCLE') != -1) this.$el.find('.bikeTriangleControl')
      .show();
    else this.$el.find('.bikeTriangleControl').hide();
  },

  toggleSettings: function() {

    if ($('#hidableSettings').is(':visible')) {
      $('#hidableSettings').slideUp('fast', function() {
        $('#itineraries').height($(window).height() - ($('#request').height() +
          $('#messageWell').height() + 80));
      });
      $('#showSettings').show();
      $('#hideSettings').hide();
    } else {
      $('#hidableSettings').slideDown('fast', function() {
        $('#itineraries').height($(window).height() - ($('#request').height() +
          $('#messageWell').height() + 80));
      });
      $('#showSettings').hide();
      $('#hideSettings').show();
    }

  },

  reverse: function(place, error, success) {

    // esri takes lon/lat
    var parts = place.split(',');
    var lonlat = parts[1] + ',' + parts[0];

    $.ajax({
      url: window.OTP_config.esriApi + 'reverseGeocode?location=' +
        encodeURIComponent(lonlat) + '&f=pjson',
      type: 'GET',
      dataType: 'jsonp',
      error: function() {
        error();
      },
      success: function(res) {

        var data = {
          address: res.address.Address,
          city: res.address.City,
          state: res.address.Region,
          latlon: place
        };

        success(data);
      }
    });
  },

  initializeSelectFor: function(term) {
    var $id = '#' + term + 'Place';
    var placeholder = term === 'from' ? 'Start' : 'End';
    var url = window.OTP_config.esriApi + 'findAddressCandidates';
    var view = this;

    return this.$($id).select2({
      placeholder: placeholder + ' Address',
      minimumInputLength: 4,
      allowClear: true,
      selectOnBlur: true,
      createSearchChoice: function(term) {
        if (view.lastResults.length === 0) {
          var text = term + ' (not found)';
          return {
            id: 'not found',
            text: text
          };
        }
      },
      formatResult: function(object, container) {
        var item = view.geocodeItem(object);
        return item;
      },
      formatSelection: function(object, container) {
        var item = view.selectedGeocodeItem(object);
        return item;
      },
      ajax: {
        url: url,
        dataType: 'json',
        quietMillis: 20,
        data: function(term, page) {
          view.lastResults = [];

          var query = {
            f: 'json',
            distance: 5000, // 5km
            singleLine: term,
            outFields: 'City,Region',
            location: '-73.7562271,42.6525795', // TODO: Should be from config
            maxLocations: 5
          };

          if (view.options.map) {
            var latlng = view.options.map.getCenter();
            query.location = latlng.lng + ',' + latlng.lat;

            var bounds = view.options.map.getBounds();
            var nw = bounds.getNorthWest();
            var se = bounds.getSouthEast();
            query.distance = haversine(nw.lat, nw.lng, se.lat, se.lng) * 1000;
          }

          return query;
        },
        results: function(res, page) {
          var results = [];
          if (res.candidates) {
            for (var i in res.candidates) {
              var candidate = res.candidates[i];
              var location = candidate.location;

              console.log(candidate);

              results.push({
                text: candidate.address.split(',')[0],
                city: candidate.attributes.City,
                state: candidate.attributes.Region,
                id: location.y + ',' + location.x
              });
            }
          }

          view.skipReverseGeocode = true;
          view.lastResults = results;

          if (results.length > 0) {
            view.$($id).select2('data', Object.assign({}, results[0], { text: term + ' ' + results[0].text }));
            view.changeForm();
          }

          return {
            results: results
          };
        }
      }
    });
  }
});
<commit_msg>Use correct event handlers for date/time picker, closes #6<commit_after>var Handlebars = require('handlebars');
var haversine = require('haversine');
var select2 = require('select2');

var BikeView = require('./bike_views');
var geocoder = require('./geocoder');

var requestFormTemplate = Handlebars.compile(require('./request-form.html'));

var RequestFormView = module.exports = Backbone.View.extend({

  events: {
    'change .apiParam': 'changeForm',
    'change #mode': 'updateModeControls',
    'click .toggleSettings': 'toggleSettings'
  },

  initialize: function(options) {
    this.options = options || {};
    _.bindAll(this, 'changeForm');

    var view = this;

    this.updatingForm = false;

    this.geocodeItem = Handlebars.compile([
      '{{text}}',
      '{{#if city}}{{city}}, {{state}}{{/if}}'
    ].join('\n'));

    this.selectedGeocodeItem = Handlebars.compile([
      '{{text}}{{#if city}}, {{city}}, {{state}}{{/if}}'
    ].join('\n'));

    this.model.on('change', function(data) {

      if (_.has(data.changed, 'fromPlace') && data.attributes.fromPlace && view.selectFrom) {
        view.updateReverseGeocoder('From', data.attributes.fromPlace, view.selectFrom);
      }

      if (_.has(data.changed, 'toPlace') && data.attributes.toPlace && view.selectTo) {
        view.updateReverseGeocoder('To', data.attributes.toPlace, view.selectTo);
      }

      view.$('#arriveBy').val(data.attributes.arriveBy);
      view.$('#mode').val(data.attributes.mode);
      view.$('#maxWalkDistance').val(data.attributes.maxWalkDistance);
      view.$('#optimize').val(data.attributes.optimize);

      var date = moment(data.attributes.date, 'MM-DD-YYYY').toDate();
      view.datepicker.setDate(date);

      var time = moment(data.attributes.time, 'hh:mm a').toDate();
      view.timepicker.setDate(time);

      view.updateModeControls();
    });
  },

  updateReverseGeocoder: function(field, latlon, select) {
    var view = this;

    if (window.OTP_config.reverseGeocode) {
      geocoder.reverse(latlon, function(err, results) {
        view.updatingForm = true;
        if (err) {
          select.select2('data', []);
        } else {
          select.select2('data', null);
          results.text = field + ' ' + results.address;
          select.select2('data', results);
        }
        view.updatingForm = false;
      });
    } else {

      // this isn't great but appears to be neccesary as selectize triggers a change event even when programatically updated
      view.updatingForm = true;

      var item = {
        text: field + ' marker location',
        id: latlon
      };

      select.select2('data', item);

      view.updatingForm = false;

    }
  },

  render: function() {

    var view = this;

    var html = requestFormTemplate({
      metric: this.options.metric || false
    });

    this.lastResults = [];

    this.$el.html(html);

    this.$('#showSettings').hide();

    view.updatingForm = true;

    this.$('#date').datetimepicker({
      pickTime: false
    });

    this.datepicker = this.$('#date').data('DateTimePicker');
    this.datepicker.setDate(new Date());
    this.$('#date').on('dp.change', function() {
      view.changeForm();
    });

    this.$('#time').datetimepicker({
      pick12HourFormat: true,
      pickSeconds: false,
      pickDate: false
    });

    this.timepicker = this.$('#time').data('DateTimePicker');
    this.timepicker.setDate(new Date());
    this.$('#time').on('dp.change', function() {
      view.changeForm();
    });

    this.bikeTriangle = new BikeView({
      model: this.model,
      el: this.$('#bikeTriangle')
    });

    this.selectFrom = this.initializeSelectFor('from');
    this.selectTo = this.initializeSelectFor('to');

    view.updatingForm = false;

    this.changeForm();
    this.updateModeControls();
  },

  changeForm: function(evt) {

    // skip duplicate change events caused by selectize form inputs
    if (this.updatingForm)
      return;

    var maxDistance = $('#mode').val().indexOf('WALK') != -1 ?
      $('#maxWalkDistance').val() : $('#maxBikeDistance').val();

    var data = {
      fromPlace: this.$('#fromPlace').select2('val'),
      toPlace: this.$('#toPlace').select2('val'),
      date: this.$('#date input').val(),
      time: this.$('#time input').val(),
      arriveBy: this.$('#arriveBy').val(),
      maxWalkDistance: maxDistance,
      optimize: this.$('#optimize').val(),
      mode: this.$('#mode').val()
    };

    // skip if either to/from fields are unset
    if (this.$('#fromPlace').select2('val') == 'not found')
      data.fromPlace = false;
    if (this.$('#toPlace').select2('val') == 'not found')
      data.toPlace = false;

    var mode = $('#mode').val();
    if (mode.indexOf('BICYCLE') != -1) {
      data.triangleSafetyFactor = $('#').val();
      data.triangleSlopeFactor = $('#').val();
      data.triangleTimeFactor = $('#').val();
    } else {
      this.model.unset('triangleSafetyFactor', {
        silent: true
      });
      this.model.unset('triangleSlopeFactor', {
        silent: true
      });
      this.model.unset('triangleTimeFactor', {
        silent: true
      });
    }

    this.model.set(data);
  },

  updateModeControls: function() {
    var mode = $('#mode').val();

    if (mode.indexOf('WALK') != -1 && mode.indexOf('TRANSIT') != -1) this.$el
      .find('.maxWalkControl').show();
    else this.$el.find('.maxWalkControl').hide();

    if (mode.indexOf('BICYCLE') != -1 && mode.indexOf('TRANSIT') != -1) this
      .$el.find('.maxBikeControl').show();
    else this.$el.find('.maxBikeControl').hide();

    if (mode.indexOf('TRANSIT') != -1 && mode.indexOf('BICYCLE') == -1)
      this.$el.find('.optimizeControl').show();
    else
      this.$el.find('.optimizeControl').hide();

    if (mode.indexOf('BICYCLE') != -1) this.$el.find('.bikeTriangleControl')
      .show();
    else this.$el.find('.bikeTriangleControl').hide();
  },

  toggleSettings: function() {

    if ($('#hidableSettings').is(':visible')) {
      $('#hidableSettings').slideUp('fast', function() {
        $('#itineraries').height($(window).height() - ($('#request').height() +
          $('#messageWell').height() + 80));
      });
      $('#showSettings').show();
      $('#hideSettings').hide();
    } else {
      $('#hidableSettings').slideDown('fast', function() {
        $('#itineraries').height($(window).height() - ($('#request').height() +
          $('#messageWell').height() + 80));
      });
      $('#showSettings').hide();
      $('#hideSettings').show();
    }

  },

  reverse: function(place, error, success) {

    // esri takes lon/lat
    var parts = place.split(',');
    var lonlat = parts[1] + ',' + parts[0];

    $.ajax({
      url: window.OTP_config.esriApi + 'reverseGeocode?location=' +
        encodeURIComponent(lonlat) + '&f=pjson',
      type: 'GET',
      dataType: 'jsonp',
      error: function() {
        error();
      },
      success: function(res) {

        var data = {
          address: res.address.Address,
          city: res.address.City,
          state: res.address.Region,
          latlon: place
        };

        success(data);
      }
    });
  },

  initializeSelectFor: function(term) {
    var $id = '#' + term + 'Place';
    var placeholder = term === 'from' ? 'Start' : 'End';
    var url = window.OTP_config.esriApi + 'findAddressCandidates';
    var view = this;

    return this.$($id).select2({
      placeholder: placeholder + ' Address',
      minimumInputLength: 4,
      allowClear: true,
      selectOnBlur: true,
      createSearchChoice: function(term) {
        if (view.lastResults.length === 0) {
          var text = term + ' (not found)';
          return {
            id: 'not found',
            text: text
          };
        }
      },
      formatResult: function(object, container) {
        var item = view.geocodeItem(object);
        return item;
      },
      formatSelection: function(object, container) {
        var item = view.selectedGeocodeItem(object);
        return item;
      },
      ajax: {
        url: url,
        dataType: 'json',
        quietMillis: 20,
        data: function(term, page) {
          view.lastResults = [];

          var query = {
            f: 'json',
            distance: 5000, // 5km
            singleLine: term,
            outFields: 'City,Region',
            location: '-73.7562271,42.6525795', // TODO: Should be from config
            maxLocations: 5
          };

          if (view.options.map) {
            var latlng = view.options.map.getCenter();
            query.location = latlng.lng + ',' + latlng.lat;

            var bounds = view.options.map.getBounds();
            var nw = bounds.getNorthWest();
            var se = bounds.getSouthEast();
            query.distance = haversine(nw.lat, nw.lng, se.lat, se.lng) * 1000;
          }

          return query;
        },
        results: function(res, page) {
          var results = [];
          if (res.candidates) {
            for (var i in res.candidates) {
              var candidate = res.candidates[i];
              var location = candidate.location;

              results.push({
                text: candidate.address.split(',')[0],
                city: candidate.attributes.City,
                state: candidate.attributes.Region,
                id: location.y + ',' + location.x
              });
            }
          }

          view.skipReverseGeocode = true;
          view.lastResults = results;

          if (results.length > 0) {
            view.$($id).select2('data', Object.assign({}, results[0], { text: term + ' ' + results[0].text }));
            view.changeForm();
          }

          return {
            results: results
          };
        }
      }
    });
  }
});
<|endoftext|>