<commit_before>/* jshint node: true */
'use strict';
var MergeTrees = require('broccoli-merge-trees');
var Funnel = require('broccoli-funnel');
var path = require('path');

function distDirFor(packageName) {
  try {
    var resolved = require.resolve(packageName + '/package.json');
    return path.join(path.dirname(resolved), 'dist');
  } catch (e) {
    return null;
  }
}

module.exports = {
  name: 'ember-mobiledoc-editor',

  treeForVendor: function() {
    var files = [];

    files.push(new Funnel(distDirFor('mobiledoc-kit'), {
      files: [
        'css/mobiledoc-kit.css',
        'amd/mobiledoc-kit.js',
        'amd/mobiledoc-kit.map'
      ],
      destDir: 'mobiledoc-kit'
    }));

    var rendererDir = distDirFor('mobiledoc-dom-renderer');
    if (rendererDir) {
      files.push(new Funnel(rendererDir, {
        files: [
          'amd/mobiledoc-dom-renderer.js'
        ],
        destDir: 'mobiledoc-dom-renderer'
      }));
    }

    return new MergeTrees(files);
  },

  included: function(app) {
    app.import('vendor/mobiledoc-kit/css/mobiledoc-kit.css');
    app.import('vendor/mobiledoc-kit/amd/mobiledoc-kit.js');
    var rendererDir = distDirFor('mobiledoc-dom-renderer');
    if (rendererDir) {
      app.import('vendor/mobiledoc-dom-renderer/amd/mobiledoc-dom-renderer.js');
    }
  }
};
<commit_msg>Include mobiledoc-dom-renderer source map<commit_after>/* jshint node: true */
'use strict';
var MergeTrees = require('broccoli-merge-trees');
var Funnel = require('broccoli-funnel');
var path = require('path');

function distDirFor(packageName) {
  try {
    var resolved = require.resolve(packageName + '/package.json');
    return path.join(path.dirname(resolved), 'dist');
  } catch (e) {
    return null;
  }
}

module.exports = {
  name: 'ember-mobiledoc-editor',

  treeForVendor: function() {
    var files = [];

    files.push(new Funnel(distDirFor('mobiledoc-kit'), {
      files: [
        'css/mobiledoc-kit.css',
        'amd/mobiledoc-kit.js',
        'amd/mobiledoc-kit.map'
      ],
      destDir: 'mobiledoc-kit'
    }));

    var rendererDir = distDirFor('mobiledoc-dom-renderer');
    if (rendererDir) {
      files.push(new Funnel(rendererDir, {
        files: [
          'amd/mobiledoc-dom-renderer.js',
          'amd/mobiledoc-dom-renderer.map'
        ],
        destDir: 'mobiledoc-dom-renderer'
      }));
    }

    return new MergeTrees(files);
  },

  included: function(app) {
    app.import('vendor/mobiledoc-kit/css/mobiledoc-kit.css');
    app.import('vendor/mobiledoc-kit/amd/mobiledoc-kit.js');
    var rendererDir = distDirFor('mobiledoc-dom-renderer');
    if (rendererDir) {
      app.import('vendor/mobiledoc-dom-renderer/amd/mobiledoc-dom-renderer.js');
    }
  }
};
<|endoftext|>


<commit_before>'use strict';
const path = require('path');
const electron = require('electron');
const { BrowserWindow } = electron;
const unusedFilename = require('unused-filename');
const request = require("request");

const app = electron.app;
let downloadFolder = app.getPath("downloads");
let lastWindowCreated;

let queue = [];

function _registerListener(win, opts = {}, cb = () => {}) {

    lastWindowCreated = win;
    downloadFolder = opts.downloadFolder || downloadFolder;

    const listener = (e, item, webContents) => {

        let queueItem = _popQueueItem(item.getURL());

        const filePath = unusedFilename.sync(
            path.join(downloadFolder, path.join(queueItem.path, item.getFilename()))
        );

        const totalBytes = item.getTotalBytes();

        item.setSavePath(filePath);

        item.on('updated', () => {
            const progress = item.getReceivedBytes() * 100 / totalBytes;

            if (typeof queueItem.onProgress === 'function') {
                queueItem.onProgress(progress);
            }
        });

        item.on('done', (e, state) => {

            let finishedDownloadCallback = queueItem.callback || function() {};

            if (!win.isDestroyed()) {
                win.setProgressBar(-1);
            }

            if (state === 'interrupted') {
                const message = `The download of ${item.getFilename()} was interrupted`;

                finishedDownloadCallback(new Error(message), item.getURL())

            } else if (state === 'completed') {
                if (process.platform === 'darwin') {
                    app.dock.downloadFinished(filePath);
                }
                // TODO: remove this listener, and/or the listener that attach this listener to newly created windows
                // if (opts.unregisterWhenDone) {
                //     webContents.session.removeListener('will-download', listener);
                // }

                finishedDownloadCallback(null, item.getURL());

            }

        });
    };

    win.webContents.session.on('will-download', listener);
}

var register = (opts = {}) => {

    app.on('browser-window-created', (e, win) => {
        _registerListener(win, opts);
    });
};

var download = (options, callback) => {
    let win = BrowserWindow.getFocusedWindow() || lastWindowCreated;
    options = Object.assign({}, {
        path: ""
    }, options);

    request(options.url).on("response", function(response) {
        response.request.abort();

        queue.push({
            url: response.request.uri.href,
            path: options.path.toString(),
            callback: callback,
            onProgress: options.onProgress
        });

        win.webContents.downloadURL(options.url);
    })

}

var bulkDownload = (options, callback) => {

    options = Object.assign({}, {
        urls: [],
        path: ""
    }, options);

    let urlsCount = options.urls.length;
    let finished = [];
    let errors = [];

    options.urls.forEach((url) => {
        download({
            url,
            path: options.path
        }, function(error, item) {

            if (error) {
                errors.push(item);
            } else {
                finished.push(item);
            }

            let errorsCount = errors.length;
            let finishedCount = finished.length;

            if ((finishedCount + errorsCount) == urlsCount) {
                if (errorsCount > 0) {
                    callback(new Error(errorsCount + " downloads failed"), finished, errors);
                } else {
                    callback(null, finished, []);
                }
            }
        })
    });
}

var _popQueueItem = (url) => {
    let queueItem = queue.find(item => item.url === url);
    queue.splice(queue.indexOf(queueItem), 1);
    return queueItem;
}

module.exports = {
    register,
    download,
    bulkDownload
}
<commit_msg>Added interupted download support<commit_after>'use strict';
const path = require('path');
const electron = require('electron');
const { BrowserWindow } = electron;
const unusedFilename = require('unused-filename');
const request = require("request");

const app = electron.app;
let downloadFolder = app.getPath("downloads");
let lastWindowCreated;

let queue = [];

function _registerListener(win, opts = {}, cb = () => {}) {

    lastWindowCreated = win;
    downloadFolder = opts.downloadFolder || downloadFolder;

    const listener = (e, item, webContents) => {

        let queueItem = _popQueueItem(item.getURL());

        const filePath = unusedFilename.sync(
            path.join(downloadFolder, path.join(queueItem.path, item.getFilename()))
        );

        const totalBytes = item.getTotalBytes();

        item.setSavePath(filePath);

        // Resuming an interupted download
        if (item.getState() === 'interrupted') {
            item.resume();
        }

        item.on('updated', () => {
            const progress = item.getReceivedBytes() * 100 / totalBytes;

            if (typeof queueItem.onProgress === 'function') {
                queueItem.onProgress(progress);
            }
        });

        item.on('done', (e, state) => {

            let finishedDownloadCallback = queueItem.callback || function() {};

            if (!win.isDestroyed()) {
                win.setProgressBar(-1);
            }

            if (state === 'interrupted') {
                const message = `The download of ${item.getFilename()} was interrupted`;

                finishedDownloadCallback(new Error(message), item.getURL())

            } else if (state === 'completed') {
                if (process.platform === 'darwin') {
                    app.dock.downloadFinished(filePath);
                }
                // TODO: remove this listener, and/or the listener that attach this listener to newly created windows
                // if (opts.unregisterWhenDone) {
                //     webContents.session.removeListener('will-download', listener);
                // }

                finishedDownloadCallback(null, item.getURL());

            }

        });
    };

    win.webContents.session.on('will-download', listener);
}

var register = (opts = {}) => {

    app.on('browser-window-created', (e, win) => {
        _registerListener(win, opts);
    });
};

var download = (options, callback) => {
    let win = BrowserWindow.getFocusedWindow() || lastWindowCreated;
    options = Object.assign({}, {
        path: ""
    }, options);

    request(options.url).on("response", function(response) {
        response.request.abort();

        queue.push({
            url: response.request.uri.href,
            path: options.path.toString(),
            callback: callback,
            onProgress: options.onProgress
        });

        const filename = path.basename(response.request.uri.href);

        const filePath = path.join(path.join(downloadFolder, options.path.toString()), filename);

        if (fs.existsSync(filePath)) {
            const stats = fs.statSync(filePath);

            const fileOffset = stats.size;

            const serverFileSize = parseInt(response.headers["content-length"]);

            console.log(filename + ' exists, verifying file size: (' + fileOffset + ' / ' + serverFileSize + " downloaded)");

            // Check if size on disk is lower than server
            if (fileOffset < serverFileSize) {
                console.log('File needs re-downloaded as it was not completed');

                options = {
                    path: filePath,
                    urlChain: [response.request.uri.href],
                    offset: parseInt(fileOffset),
                    length: serverFileSize,
                    lastModified: response.headers["last-modified"]
                };

                win.webContents.session.createInterruptedDownload(options);
            } else {
                console.log(filename + ' verified, no download needed');
            }

        } else {
            console.log(filename + ' does not exist, download it now');
            win.webContents.downloadURL(options.url);
        }
    })

}

var bulkDownload = (options, callback) => {

    options = Object.assign({}, {
        urls: [],
        path: ""
    }, options);

    let urlsCount = options.urls.length;
    let finished = [];
    let errors = [];

    options.urls.forEach((url) => {
        download({
            url,
            path: options.path
        }, function(error, item) {

            if (error) {
                errors.push(item);
            } else {
                finished.push(item);
            }

            let errorsCount = errors.length;
            let finishedCount = finished.length;

            if ((finishedCount + errorsCount) == urlsCount) {
                if (errorsCount > 0) {
                    callback(new Error(errorsCount + " downloads failed"), finished, errors);
                } else {
                    callback(null, finished, []);
                }
            }
        })
    });
}

var _popQueueItem = (url) => {
    let queueItem = queue.find(item => item.url === url);
    queue.splice(queue.indexOf(queueItem), 1);
    return queueItem;
}

module.exports = {
    register,
    download,
    bulkDownload
}<|endoftext|>


<commit_before>'use strict';

var Minimize = require('minimize');
var through = require('through2');
var gutil = require('gulp-util');
var loadash = require('lodash');
var path = require('path');
var fs = require('fs');

// Consts
var PLUGIN_NAME = 'gulp-directive-replace';

module.exports = function(opts) {
    var defaultOpts = {
        root: '',
        minify: {}
    };

    opts = loadash.merge(defaultOpts, opts || {});

    return through.obj(function(file, enc, cb) {

        if (file.isNull()) {
            cb(null, file);
            return;
        }

        if (file.isStream()) {
            cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported'));
            return;
        }

        try {
            var originalContent = file.contents.toString();
            var templateUrlRegex = /templateUrl\:[^\'\"]*(\'|\")([^\'\"]+)(\'|\")/gm;
            var templateFieldSeparator = ': ';
            var templateUrl = extractTemplateUrl(originalContent, templateUrlRegex, opts);

            if (!templateUrl) {
                templateUrlRegex = /templateUrl\s=\s[^\'\"]*(\'|\")([^\'\"]+)(\'|\")/gm;
                templateFieldSeparator = ' = ';
                templateUrl = extractTemplateUrl(originalContent, templateUrlRegex, opts)
            }

            if (!templateUrl) {
                cb(null, file);
                return;
            }

            var templateContent = getTemplateContent(templateUrl);
            var minimize = new Minimize(opts.minify);

            minimize.parse(templateContent, function(err, minimizedTemplate) {

                if (err) {
                    cb(new gutil.PluginError(PLUGIN_NAME, err, {fileName: file.path}));
                    return;
                }

                var escapedTemplate = escapeString(minimizedTemplate);
                var injectedTemplate = 'template' + templateFieldSeparator + '\'' + escapedTemplate + '\'';
                var replacedContent = originalContent.replace(templateUrlRegex, injectedTemplate);

                file.contents = new Buffer(replacedContent);

                cb(null, file);
                return;
            });

        } catch (err) {
            cb(new gutil.PluginError(PLUGIN_NAME, err, {fileName: file.path}));
            return;
        }
    });
};

//////////////////////////////

function extractTemplateUrl(contents, regex, opts) {
    var match = regex.exec(contents);
    var hasTemplateUrl = match && match[2];

    return hasTemplateUrl ? path.join(opts.root, match[2]) : false;
}

function getTemplateContent(templateUrl) {
    return fs.readFileSync(templateUrl, 'utf8');
}

function escapeString(string) {
    var escapedString = string;
    escapedString = escapedString ? escapedString.replace(/\\/g, '\\\\') : '';
    escapedString = escapedString ? escapedString.replace(/'/g, "\\'") : '';

    return escapedString;
}

<commit_msg>Add support for multiple url-s in directive<commit_after>'use strict';

var minify = require('html-minifier').minify;
var through = require('through2');
var stringEscape = require('js-string-escape');
var gutil = require('gulp-util');
var loadash = require('lodash');
var path = require('path');
var fs = require('fs');
var PluginError = gutil.PluginError;

// Consts
var PLUGIN_NAME = 'gulp-directive-replace';

module.exports = function (opts) {

    var defaultOpts = {
        root: '',
        transform: null
    };

    opts = loadash.merge(defaultOpts, opts || {});

    if (!opts.root) {
        throw new PluginError(PLUGIN_NAME, 'You should specify the templates root path.');
    }

    return through.obj(function (file, encoding, next) {

        if (file.isNull()) {
            return next(null, file);
        }

        if (file.isStream()) {
            return next(new PluginError(PLUGIN_NAME, 'Streaming not supported'));
        }

        var content = proxy(opts.transform || transform, null)(opts.root, String(file.contents));

        file.contents = new Buffer(content);

        return next(null, file);
    });
};

function proxy(fn, context) {
    var args = [].slice.call(arguments, 2);
    return function () {
        return fn.apply(context, args.concat([].slice.call(arguments)));
    }
}

function transform(basePath, template) {

    var templateUrlRegex = /templateUrl\s*([\:\=])[^\'\"]*(\'|\")([^\'\"]+)(\'|\")/gm;

    var matches, templateContent, templateInline, templatePath;
    while ((matches = templateUrlRegex.exec(template)) !== null) {

        templatePath = path.join(basePath, matches[3]);

        if (fileExistsSync(templatePath)) {

            templateContent = extractTemplateUrl(templatePath);

            templateInline = getTemplateInline(matches[1], templateContent, {
                collapseWhitespace: true
            });

            template = replaceTemplateUrl(matches.index, matches[0].length, template, templateInline);
        }
    }
    return template;
}

function fileExistsSync(filePath) {
    try {
        fs.statSync(filePath);
    } catch (err) {
        return err.code != 'ENOENT';
    }
    return true;
}

function extractTemplateUrl(templateUrlPath) {
    return fs.readFileSync(templateUrlPath, 'utf8');
}

function getTemplateInline(sign, content, options) {
    var template = minify(content, options);
    var templateEscaped = stringEscape(template);
    return 'template' + sign + ' \'' + templateEscaped + '\'';
}

function replaceTemplateUrl(index, length, content, templateInline) {
    var templateUrl = content.substr(index, length);
    return content.replace(templateUrl, templateInline);
}
<|endoftext|>


<commit_before>'use strict';

console.log( 7 );

var Gpio = require('chip-gpio').Gpio,
    request = require( 'request' ),
    jsonfile = require( 'jsonfile' ),
    client = null,

    persist = 'persist.json',
    persistedData = jsonfile.readFileSync( persist ),
    brightness = 255;

// Setup th buttons and rotary encoder
var btn = new Gpio(7, 'in', 'both', {
      debounceTimeout: 500
    }),

    a = new Gpio(0, 'in', 'both',{
        debounceTimeout: 200
    }),

    b = new Gpio(1, 'in', 'both',{
      debounceTimeout: 200
    });

var apiBaseUrl,
    // Set default Values
    brightness = 255;

function setState( on, brightness )
{
  console.log( 'setState', {
    on, brightness
  });
  request.put( apiBaseUrl + persistedData.username + '/lights/4/state', {
    json: {
      on: on,
      bri: brightness
    }
  });
}

/*
*  Connect to the Bridge
*/

// Search for the Bridge
request( 'https://www.meethue.com/api/nupnp', function( error, response, body ){
  persistedData.ip = JSON.parse( body )[0].internalipaddress;
  jsonfile.writeFile( persist, persistedData );

  apiBaseUrl = 'http://' + persistedData.ip + '/api/';
  console.log( apiBaseUrl );

  // Do we need to create a user?
  if( typeof persistedData.username == 'undefined' || ! persistedData.username )
  {
    request.post( apiBaseUrl, {
      json: {
        devicetype: 'chip_hue_switch'
      }
    }, function( error, response, body ){
      persistedData.username = body[0].success.username;
      jsonfile.writeFile( persist, persistedData );
    });
  }
});

btn.watch(function (err, value) {
  console.log('press', value);
  console.log( apiBaseUrl + persistedData.username + '/lights' );

  request( apiBaseUrl + persistedData.username + '/lights', function( error, response, body ){
  	body = JSON.parse( body );
  	var newState = ! body[4].state.on;

    setState( newState, brightness );

  });

});

var previousA, previousB;

function setBrightness()
{
	if( brightness >= 255 ) brightness = 255;
	if( brightness <= 1 ) brightness = 1;

	console.info( 'Setting brightness to ' + brightness );

  setState( true, brightness );
}

a.watch(function (err, value) {
	var direction = '';
	var currentA = a.read();
	var currentB = b.read();

	if( previousA != currentA )
	{
		if( currentA != currentB )
		{
			direction = 'forward';
			brightness = brightness + 2.55;
		}
		else
		{
			direction = 'back';
			brightness = brightness - 2.55;
		}
	}

	setBrightness( brightness );
});

b.watch(function (err, value) {
	var direction = '';
	var currentA = a.read();
	var currentB = b.read();

	if( previousB != currentB )
	{
		if( currentA == currentB )
		{
			direction = 'forward';
			brightness = brightness + 2.55;
		}
		else
		{
			direction = 'back';
			brightness = brightness - 2.55;
		}
	}

	setBrightness( brightness );
});

function exit() {
    btn.unexport();
    a.unexport();
    b.unexport();
    process.exit();
}

process.on('SIGINT', exit);
<commit_msg>Change<commit_after>'use strict';

console.log( 7 );

var Gpio = require('chip-gpio').Gpio,
    request = require( 'request' ),
    jsonfile = require( 'jsonfile' ),
    client = null,

    persist = 'persist.json',
    persistedData = jsonfile.readFileSync( persist ),
    brightness = 255;

// Setup th buttons and rotary encoder
var btn = new Gpio(7, 'in', 'both', {
      debounceTimeout: 500
    }),

    a = new Gpio(0, 'in', 'both',{
        debounceTimeout: 200
    }),

    b = new Gpio(1, 'in', 'both',{
      debounceTimeout: 200
    });

var apiBaseUrl,
    // Set default Values
    brightness = 255;

function setState( on, brightness )
{
  console.log( 'setState', {
    on, brightness
  });
  request.put( apiBaseUrl + persistedData.username + '/lights/4/state', {
    json: {
      on: on,
      bri: Math.ceil( brightness )
    }
  });
}

/*
*  Connect to the Bridge
*/

// Search for the Bridge
request( 'https://www.meethue.com/api/nupnp', function( error, response, body ){
  persistedData.ip = JSON.parse( body )[0].internalipaddress;
  jsonfile.writeFile( persist, persistedData );

  apiBaseUrl = 'http://' + persistedData.ip + '/api/';
  console.log( apiBaseUrl );

  // Do we need to create a user?
  if( typeof persistedData.username == 'undefined' || ! persistedData.username )
  {
    request.post( apiBaseUrl, {
      json: {
        devicetype: 'chip_hue_switch'
      }
    }, function( error, response, body ){
      persistedData.username = body[0].success.username;
      jsonfile.writeFile( persist, persistedData );
    });
  }
});

btn.watch(function (err, value) {
  console.log('press', value);
  console.log( apiBaseUrl + persistedData.username + '/lights' );

  request( apiBaseUrl + persistedData.username + '/lights', function( error, response, body ){
  	body = JSON.parse( body );
  	var newState = ! body[4].state.on;

    setState( newState, brightness );

  });

});

var previousA, previousB;

function setBrightness()
{
	if( brightness >= 255 ) brightness = 255;
	if( brightness <= 1 ) brightness = 1;

	console.info( 'Setting brightness to ' + brightness );

  setState( true, brightness );
}

a.watch(function (err, value) {
	var direction = '';
	var currentA = a.read();
	var currentB = b.read();

	if( previousA != currentA )
	{
		if( currentA != currentB )
		{
			direction = 'forward';
			brightness = brightness + 2.55;
		}
		else
		{
			direction = 'back';
			brightness = brightness - 2.55;
		}
	}

	setBrightness( brightness );
});

b.watch(function (err, value) {
	var direction = '';
	var currentA = a.read();
	var currentB = b.read();

	if( previousB != currentB )
	{
		if( currentA == currentB )
		{
			direction = 'forward';
			brightness = brightness + 2.55;
		}
		else
		{
			direction = 'back';
			brightness = brightness - 2.55;
		}
	}

	setBrightness( brightness );
});

function exit() {
    btn.unexport();
    a.unexport();
    b.unexport();
    process.exit();
}

process.on('SIGINT', exit);
<|endoftext|>


<commit_before>'use strict';
require('@doctormckay/stats-reporter').setup(require('./package.json'));

const Crypto = require('crypto');

/**
 * Returns the current local Unix time
 * @param {number} [timeOffset=0] - This many seconds will be added to the returned time
 * @returns {number}
 */
exports.time = function(timeOffset) {
	return Math.floor(Date.now() / 1000) + (timeOffset || 0);
};

/**
 * Generate a Steam-style TOTP authentication code.
 * @param {Buffer|string} secret - Your TOTP shared_secret as a Buffer, hex, or base64
 * @param {number} [timeOffset=0] - If you know how far off your clock is from the Steam servers, put the offset here in seconds
 * @returns {string}
 */
exports.generateAuthCode = exports.getAuthCode = function(secret, timeOffset) {
	if (typeof timeOffset === 'function') {
		exports.getTimeOffset((err, offset, latency) => {
			if (err) {
				timeOffset(err);
				return;
			}

			let code = exports.generateAuthCode(secret, offset);
			timeOffset(null, code, offset, latency);
		});

		return;
	}

	secret = bufferizeSecret(secret);

	let time = exports.time(timeOffset);

	let buffer = Buffer.allocUnsafe(8);
	buffer.writeUInt32BE(0, 0); // This will stop working in 2038!
	buffer.writeUInt32BE(Math.floor(time / 30), 4);

	let hmac = Crypto.createHmac('sha1', secret);
	hmac = hmac.update(buffer).digest();

	let start = hmac[19] & 0x0F;
	hmac = hmac.slice(start, start + 4);

	let fullcode = hmac.readUInt32BE(0) & 0x7FFFFFFF;

	const chars = '23456789BCDFGHJKMNPQRTVWXY';

	let code = '';
	for (let i = 0; i < 5; i++) {
		code += chars.charAt(fullcode % chars.length);
		fullcode /= chars.length;
	}

	return code;
};

/**
 * Generate a base64 confirmation key for use with mobile trade confirmations. The key can only be used once.
 * @param {Buffer|string} identitySecret - The identity_secret that you received when enabling two-factor authentication
 * @param {number} time - The Unix time for which you are generating this secret. Generally should be the current time.
 * @param {string} tag - The tag which identifies what this request (and therefore key) will be for. "conf" to load the confirmations page, "details" to load details about a trade, "allow" to confirm a trade, "cancel" to cancel it.
 * @returns {string}
 */
exports.generateConfirmationKey = exports.getConfirmationKey = function(identitySecret, time, tag) {
	identitySecret = bufferizeSecret(identitySecret);

	let dataLen = 8;

	if (tag) {
		if (tag.length > 32) {
			dataLen += 32;
		} else {
			dataLen += tag.length;
		}
	}

	let buffer = Buffer.allocUnsafe(dataLen);
	buffer.writeUInt32BE(0, 0); // This will stop working in 2038!
	buffer.writeUInt32BE(time, 4);

	if (tag) {
		buffer.write(tag, 8);
	}

	let hmac = Crypto.createHmac('sha1', identitySecret);
	return hmac.update(buffer).digest('base64');
};

exports.getTimeOffset = function(callback) {
	let start = Date.now();
	let req = require('https').request({
		"hostname": "api.steampowered.com",
		"path": "/ITwoFactorService/QueryTime/v1/",
		"method": "POST",
		"headers": {
			"Content-Length": 0
		}
	}, (res) => {
		if (res.statusCode != 200) {
			callback(new Error("HTTP error " + res.statusCode));
			return;
		}

		let response = '';
		res.on('data', (chunk) => {
			response += chunk;
		});

		res.on('end', () => {
			try {
				response = JSON.parse(response).response;
			} catch(e) {
				callback(new Error("Malformed response"));
			}

			if (!response || !response.server_time) {
				callback(new Error("Malformed response"));
			}

			let end = Date.now();
			let offset = response.server_time - exports.time();

			callback(null, offset, end - start);
		});
	});

	req.on('error', callback);

	req.end();
};

/**
 * Get a standardized device ID based on your SteamID.
 * @param {string|object} steamID - Your SteamID, either as a string or as an object which has a toString() method that returns the SteamID
 * @returns {string}
 */
exports.getDeviceID = function(steamID) {
	let salt = process.env.STEAM_TOTP_SALT || '';
	return "android:" + Crypto.createHash('sha1').update(steamID.toString() + salt).digest('hex')
			.replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12}).*$/, '$1-$2-$3-$4-$5');
};

function bufferizeSecret(secret) {
	if (typeof secret === 'string') {
		// Check if it's hex
		if (secret.match(/[0-9a-f]{40}/i)) {
			return Buffer.from(secret, 'hex');
		} else {
			// Looks like it's base64
			return Buffer.from(secret, 'base64');
		}
	}

	return secret;
}
<commit_msg>Removed incorrect comments<commit_after>'use strict';
require('@doctormckay/stats-reporter').setup(require('./package.json'));

const Crypto = require('crypto');

/**
 * Returns the current local Unix time
 * @param {number} [timeOffset=0] - This many seconds will be added to the returned time
 * @returns {number}
 */
exports.time = function(timeOffset) {
	return Math.floor(Date.now() / 1000) + (timeOffset || 0);
};

/**
 * Generate a Steam-style TOTP authentication code.
 * @param {Buffer|string} secret - Your TOTP shared_secret as a Buffer, hex, or base64
 * @param {number} [timeOffset=0] - If you know how far off your clock is from the Steam servers, put the offset here in seconds
 * @returns {string}
 */
exports.generateAuthCode = exports.getAuthCode = function(secret, timeOffset) {
	if (typeof timeOffset === 'function') {
		exports.getTimeOffset((err, offset, latency) => {
			if (err) {
				timeOffset(err);
				return;
			}

			let code = exports.generateAuthCode(secret, offset);
			timeOffset(null, code, offset, latency);
		});

		return;
	}

	secret = bufferizeSecret(secret);

	let time = exports.time(timeOffset);

	let buffer = Buffer.allocUnsafe(8);
	buffer.writeUInt32BE(0, 0);
	buffer.writeUInt32BE(Math.floor(time / 30), 4);

	let hmac = Crypto.createHmac('sha1', secret);
	hmac = hmac.update(buffer).digest();

	let start = hmac[19] & 0x0F;
	hmac = hmac.slice(start, start + 4);

	let fullcode = hmac.readUInt32BE(0) & 0x7FFFFFFF;

	const chars = '23456789BCDFGHJKMNPQRTVWXY';

	let code = '';
	for (let i = 0; i < 5; i++) {
		code += chars.charAt(fullcode % chars.length);
		fullcode /= chars.length;
	}

	return code;
};

/**
 * Generate a base64 confirmation key for use with mobile trade confirmations. The key can only be used once.
 * @param {Buffer|string} identitySecret - The identity_secret that you received when enabling two-factor authentication
 * @param {number} time - The Unix time for which you are generating this secret. Generally should be the current time.
 * @param {string} tag - The tag which identifies what this request (and therefore key) will be for. "conf" to load the confirmations page, "details" to load details about a trade, "allow" to confirm a trade, "cancel" to cancel it.
 * @returns {string}
 */
exports.generateConfirmationKey = exports.getConfirmationKey = function(identitySecret, time, tag) {
	identitySecret = bufferizeSecret(identitySecret);

	let dataLen = 8;

	if (tag) {
		if (tag.length > 32) {
			dataLen += 32;
		} else {
			dataLen += tag.length;
		}
	}

	let buffer = Buffer.allocUnsafe(dataLen);
	buffer.writeUInt32BE(0, 0);
	buffer.writeUInt32BE(time, 4);

	if (tag) {
		buffer.write(tag, 8);
	}

	let hmac = Crypto.createHmac('sha1', identitySecret);
	return hmac.update(buffer).digest('base64');
};

exports.getTimeOffset = function(callback) {
	let start = Date.now();
	let req = require('https').request({
		"hostname": "api.steampowered.com",
		"path": "/ITwoFactorService/QueryTime/v1/",
		"method": "POST",
		"headers": {
			"Content-Length": 0
		}
	}, (res) => {
		if (res.statusCode != 200) {
			callback(new Error("HTTP error " + res.statusCode));
			return;
		}

		let response = '';
		res.on('data', (chunk) => {
			response += chunk;
		});

		res.on('end', () => {
			try {
				response = JSON.parse(response).response;
			} catch(e) {
				callback(new Error("Malformed response"));
			}

			if (!response || !response.server_time) {
				callback(new Error("Malformed response"));
			}

			let end = Date.now();
			let offset = response.server_time - exports.time();

			callback(null, offset, end - start);
		});
	});

	req.on('error', callback);

	req.end();
};

/**
 * Get a standardized device ID based on your SteamID.
 * @param {string|object} steamID - Your SteamID, either as a string or as an object which has a toString() method that returns the SteamID
 * @returns {string}
 */
exports.getDeviceID = function(steamID) {
	let salt = process.env.STEAM_TOTP_SALT || '';
	return "android:" + Crypto.createHash('sha1').update(steamID.toString() + salt).digest('hex')
			.replace(/^([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12}).*$/, '$1-$2-$3-$4-$5');
};

function bufferizeSecret(secret) {
	if (typeof secret === 'string') {
		// Check if it's hex
		if (secret.match(/[0-9a-f]{40}/i)) {
			return Buffer.from(secret, 'hex');
		} else {
			// Looks like it's base64
			return Buffer.from(secret, 'base64');
		}
	}

	return secret;
}
<|endoftext|>


<commit_before>'use strict';

module.exports = generator;

var fs = require('fs');
var fse = require('fs-extra');
var node_path = require('path');
var async = require('async');
var ejs = require('ejs');

// Use '{%' which is more friendly to README.md instead of '<%'
ejs.open = '{%';
ejs.close = '%}';

var clone = require('clone');
var scaffold = require('scaffold-generator');

// @param {Object} options
// - template {string='default'} template name
// - override
function generator(pkg, options, callback) {
  var template = options.template || 'default';
  var license = options.license || 'MIT';

  var cloned_pkg = generator._pkgData(pkg);

  if (!~generator.AVAILABLE_TEMPLATES.indexOf(template)) {
    return callback(new Error('Invalid template'));
  }

  if (!~generator.AVAILABLE_LICENSES.indexOf(license)) {
    return callback(new Error('Invalid license'));
  }

  var s = scaffold({
    data: cloned_pkg,
    override: options.override
  });

  async.parallel([
    // copy template
    function (done) {
      var template_root = node_path.join(__dirname, 'templates', template);
      s.copy(template_root, options.cwd, done);
    },

    // copy licenses
    function (done) {
      var file = node_path.join(__dirname, 'licenses', 'LICENSE-' + license);
      s.copy(file, options.cwd, done);
    },

    // write cortex.json
    function (done) {
      var cortex_json = node_path.join(options.cwd, 'cortex.json');
      var content = JSON.stringify(pkg);
      s.write(cortex_json, content, done);
    }

  ], callback);
};

generator._pkgData = function (pkg) {
  pkg = clone(pkg);

  // `cortex-init-prompts` ensures that `name` is
  // - starts with a letter
  // - only contains letters, numbers, `-` and `.`
  var safe_javascript_name = pkg.name.replace(/[-\.]/g, '_');

  pkg.js_name = safe_javascript_name;

  pkg.main_in_test =
    // Relative to test files, pkg.main is outside the current folder
    node_path.join('..', pkg.main)
    // Removes ending `.js`
    // TODO: related to kaelzhang/node-commonjs-walker#10
    .replace(/\.js$/, '');

  return pkg;
};

generator.AVAILABLE_TEMPLATES = [
  'default'
];

generator.AVAILABLE_LICENSES = [
  'MIT',
  'Apache-2.0',
  'GPL-2.0',
  'MPL-2.0'
];

generator.availableLicenses = function() {
  return [].concat(generator.AVAILABLE_LICENSES);
};

generator.availableTemplates = function () {
  return [].concat(generator.AVAILABLE_TEMPLATES);
};
<commit_msg>json format and package.json<commit_after>'use strict';

module.exports = generator;

var fs = require('fs');
var fse = require('fs-extra');
var node_path = require('path');
var async = require('async');
var ejs = require('ejs');

// Use '{%' which is more friendly to README.md instead of '<%'
ejs.open = '{%';
ejs.close = '%}';

var clone = require('clone');
var scaffold = require('scaffold-generator');

// @param {Object} options
// - template {string='default'} template name
// - override
function generator(pkg, options, callback) {
  var template = options.template || 'default';
  var license = options.license || 'MIT';

  var cloned_pkg = generator._pkgData(pkg);

  if (!~generator.AVAILABLE_TEMPLATES.indexOf(template)) {
    return callback(new Error('Invalid template'));
  }

  if (!~generator.AVAILABLE_LICENSES.indexOf(license)) {
    return callback(new Error('Invalid license'));
  }

  var s = scaffold({
    data: cloned_pkg,
    override: options.override
  });

  async.parallel([
    // copy template
    function (done) {
      var template_root = node_path.join(__dirname, 'templates', template);
      s.copy(template_root, options.cwd, done);
    },

    // copy licenses
    function (done) {
      var file = node_path.join(__dirname, 'licenses', 'LICENSE-' + license);
      s.copy(file, options.cwd, done);
    },

    // write cortex.json
    function (done) {
      var cortex_json = node_path.join(options.cwd, 'cortex.json');
      var content = JSON.stringify(pkg,null,4); //format
      s.write(cortex_json, content, done);
    },

    // write package.json, build will fail if got no package.json
    // for example:
    // http://192.168.214.6/job/beta-quanhua.ma-openapp/2/console
    function (done) {
      var p = clone(pkg);
      delete p.devDependencies;
      var package_json = node_path.join(options.cwd, 'package.json');
      var content = JSON.stringify(p,null,4); //format
      s.write(package_json, content, done);
    }

  ], callback);
};

generator._pkgData = function (pkg) {
  pkg = clone(pkg);

  // `cortex-init-prompts` ensures that `name` is
  // - starts with a letter
  // - only contains letters, numbers, `-` and `.`
  var safe_javascript_name = pkg.name.replace(/[-\.]/g, '_');

  pkg.js_name = safe_javascript_name;

  pkg.main_in_test =
    // Relative to test files, pkg.main is outside the current folder
    node_path.join('..', pkg.main)
    // Removes ending `.js`
    // TODO: related to kaelzhang/node-commonjs-walker#10
    .replace(/\.js$/, '');

  return pkg;
};

generator.AVAILABLE_TEMPLATES = [
  'default'
];

generator.AVAILABLE_LICENSES = [
  'MIT',
  'Apache-2.0',
  'GPL-2.0',
  'MPL-2.0'
];

generator.availableLicenses = function() {
  return [].concat(generator.AVAILABLE_LICENSES);
};

generator.availableTemplates = function () {
  return [].concat(generator.AVAILABLE_TEMPLATES);
};
<|endoftext|>


<commit_before>var http = require('http'),
    httpProxy = require('http-proxy'),
    config = require('uniformer')({
      file: "config.json",
      defaults: {
        host: "arewegood.bengreenier.com",
        port: 8015
      }
    });

//
// Setup our server to proxy standard HTTP requests
//
var proxy = new httpProxy.createProxyServer({
  target: {
    host: config.host
  }
});
var proxyServer = http.createServer(function (req, res) {
  proxy.web(req, res);
});

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
  proxy.ws(req, socket, head);
});

proxyServer.listen(config.port, function() {
  console.log("listening on "+config.port);
});<commit_msg>updating configuration defaults to point to azure<commit_after>var http = require('http'),
    httpProxy = require('http-proxy'),
    config = require('uniformer')({
      file: "config.json",
      defaults: {
        host: "arewegood.azurewebsites.net",
        port: 8015
      }
    });

//
// Setup our server to proxy standard HTTP requests
//
var proxy = new httpProxy.createProxyServer({
  target: {
    host: config.host
  }
});
var proxyServer = http.createServer(function (req, res) {
  proxy.web(req, res);
});

//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
  proxy.ws(req, socket, head);
});

proxyServer.listen(config.port, function() {
  console.log("listening on "+config.port);
});<|endoftext|>


<commit_before>#!/usr/bin/env node

var opener = require("opener");
var url = "http://bit.ly/cascadiafest";

console.log("Opening " + url);
opener(url);
<commit_msg>Update url to plain old cascadiajs.com<commit_after>#!/usr/bin/env node

var opener = require("open");
var url = "http://cascadiajs.com/";

console.log("Opening " + url);
opener(url);
<|endoftext|>


<commit_before>'use strict';

module.exports = {
  'app': require.resolve('./generators/app'),
  'boilerplate': require.resolve('./generators/boilerplate'),
  'editorconfig': require.resolve('./generators/editorconfig'),
  'git': require.resolve('./generators/git'),
  'gulp': require.resolve('./generators/gulp'),
  'jscs': require.resolve('./generators/jscs'),
  'jshint': require.resolve('./generators/jshint'),
  'readme': require.resolve('./generators/readme'),
  'travis': require.resolve('./generators/travis')
};
<commit_msg>Remove unneeded quotes<commit_after>'use strict';

module.exports = {
  app: require.resolve('./generators/app'),
  boilerplate: require.resolve('./generators/boilerplate'),
  editorconfig: require.resolve('./generators/editorconfig'),
  git: require.resolve('./generators/git'),
  gulp: require.resolve('./generators/gulp'),
  jscs: require.resolve('./generators/jscs'),
  jshint: require.resolve('./generators/jshint'),
  readme: require.resolve('./generators/readme'),
  travis: require.resolve('./generators/travis')
};
<|endoftext|>


<commit_before>'use strict';
var gulp;
var pkg;

var findup = require('findup-sync');
var browserSync = require('browser-sync');
var minimist = require('minimist');
var chalk = require('chalk');
var replace = require('gulp-replace');
var paths = require('./paths');
var build = require('./tasks/build');
var test = require('./tasks/test');
var release = require('./tasks/release');

var knownArgs = {
    string: 'version',
    default: { version: 'patch' }
};
var args = minimist(process.argv.slice(2), knownArgs);

function onError(err) {
    console.log(chalk.colors.red(err));
    process.exit(1);
}

function watch(){
    var htmlPaths = [ paths.demo['root'] + '/**/*.html'];
    var sassPaths = [ paths.source['sass'] + '/**/*', paths.demo['sass'] + '/**/*'];
    var jsPaths =   [ paths.source['js'] + '/**/*',   paths.demo['js'] + '/**/*'];
    gulp.watch(htmlPaths, ['html']);
    gulp.watch(sassPaths, ['sass']);
    gulp.watch(jsPaths,   ['js']);
}

function loadBrowser(baseDir){
    browserSync({
        port: 3456,
        server: {
            baseDir: baseDir
        }
    });
}

function gulpTasks(globalGulp){
    gulp = globalGulp;
    var packageFilePath = findup('package.json');
    pkg = require(packageFilePath);

    /*
     * Building
     */
    gulp.task('build:sass', function() {
        browserSync.notify('Running: Sass compiling');
        return build.css().then(function(){
            browserSync.reload({stream:false});
        });
    });

    gulp.task('build:js', function() {
        browserSync.notify('Running: JS compiling');
        return build.js().then(function(){
            browserSync.reload({stream:false});
        });
    });

    gulp.task('build:html', function() {
        browserSync.notify('Running: HTML compiling');
        return build.html().then(function(){
            browserSync.reload({stream:false});
        });
    });

    gulp.task('build', function() {
        browserSync.notify('Running: Site compiling');
        return build.all().then(function(){
            browserSync.reload({stream:false})
        })
    });

    /*
     * Serving
     */
    gulp.task('serve:quick', function() {
        loadBrowser(paths.site['root']);
        watch();
    });

    gulp.task('serve', ['build', 'serve:quick']);

    /*
     * Testing
     */
    gulp.task('test:tdd', function () {
        return test.tdd().catch(onError);
    });
    gulp.task('test:coverage', function () {
        return test.coverage().catch(onError);
    });
    gulp.task('test', ['build'], function(){
        return test.all().catch(onError);
    });

    /*
     * RELEASING
     */
    gulp.task('release:git', function(){
       return release.git();
    });
    gulp.task('release:aws', function(){
       return release.aws(pkg.version);
    });
    gulp.task('release:gh-page', function(){
       return release.ghPages();
    });
    gulp.task('release', ['build', 'test'], function(){
       return release.component(args.version);
    });

    /*
     * Transfer repo
     */
    gulp.task('transfer:user', function(cb) {
      if (!gulp.env.oldUser || !gulp.env.newUser){
          onError('You must give `old-user` and `new-user` arguments i.e,\n'+
                      '`gulp rename-user --old-user=someone --new-user=someone-else`');
      }
      return gulp.src('./*')
        .pipe(replace(gulp.env.oldUser, gulp.env.newUser))
        .pipe(gulp.dest('./'));
    });

    return {
        paths: paths
    }
}

module.exports = gulpTasks;
<commit_msg>fix watch tasks<commit_after>'use strict';
var gulp;
var pkg;

var findup = require('findup-sync');
var browserSync = require('browser-sync');
var minimist = require('minimist');
var chalk = require('chalk');
var replace = require('gulp-replace');
var paths = require('./paths');
var build = require('./tasks/build');
var test = require('./tasks/test');
var release = require('./tasks/release');

var knownArgs = {
    string: 'version',
    default: { version: 'patch' }
};
var args = minimist(process.argv.slice(2), knownArgs);

function onError(err) {
    console.log(chalk.colors.red(err));
    process.exit(1);
}

function watch(){
    var htmlPaths = [ paths.demo['root'] + '/**/*.html'];
    var sassPaths = [ paths.source['sass'] + '/**/*', paths.demo['sass'] + '/**/*'];
    var jsPaths =   [ paths.source['js'] + '/**/*',   paths.demo['js'] + '/**/*'];
    gulp.watch(htmlPaths, ['build:html']);
    gulp.watch(sassPaths, ['build:sass']);
    gulp.watch(jsPaths,   ['build:js']);
}

function loadBrowser(baseDir){
    browserSync({
        port: 3456,
        server: {
            baseDir: baseDir
        }
    });
}

function gulpTasks(globalGulp){
    gulp = globalGulp;
    var packageFilePath = findup('package.json');
    pkg = require(packageFilePath);

    /*
     * Building
     */
    gulp.task('build:sass', function() {
        browserSync.notify('Running: Sass compiling');
        return build.css().then(browserSync.reload);
    });

    gulp.task('build:js', function() {
        browserSync.notify('Running: JS compiling');
        return build.js().then(browserSync.reload);
    });

    gulp.task('build:html', function() {
        browserSync.notify('Running: HTML compiling');
        return build.html().then(browserSync.reload);
    });

    gulp.task('build', function() {
        browserSync.notify('Running: Site compiling');
        return build.all().then(browserSync.reload)
    });

    /*
     * Serving
     */
    gulp.task('serve:quick', function() {
        loadBrowser(paths.site['root']);
        watch();
    });

    gulp.task('serve', ['build', 'serve:quick']);

    /*
     * Testing
     */
    gulp.task('test:single-run', function () {
        return test.singleRun().catch(onError);
    });
    gulp.task('test:tdd', function () {
        return test.tdd().catch(onError);
    });
    gulp.task('test:coverage', function () {
        return test.coverage().catch(onError);
    });
    gulp.task('test', ['build'], function(){
        return test.all().catch(onError);
    });

    /*
     * RELEASING
     */
    gulp.task('release:git', function(){
       return release.git();
    });
    gulp.task('release:aws', function(){
       return release.aws(pkg.version);
    });
    gulp.task('release:gh-page', function(){
       return release.ghPages();
    });
    gulp.task('release', ['build', 'test'], function(){
       return release.component(args.version);
    });

    /*
     * Transfer repo
     */
    gulp.task('transfer:user', function(cb) {
      if (!gulp.env.oldUser || !gulp.env.newUser){
          onError('You must give `old-user` and `new-user` arguments i.e,\n'+
                      '`gulp rename-user --old-user=someone --new-user=someone-else`');
      }
      return gulp.src('./*')
        .pipe(replace(gulp.env.oldUser, gulp.env.newUser))
        .pipe(gulp.dest('./'));
    });

    return {
        paths: paths
    }
}

module.exports = gulpTasks;
<|endoftext|>


<commit_before>'use strict';

function isObject(x) {
	return (typeof x === 'object' || typeof x === 'function') && x !== null;
}

module.exports.get = function (obj, path) {
	if (!isObject(obj) || typeof path !== 'string') {
		return obj;
	}

	var pathArr = path.split('.');
	pathArr.some(function (path, index) {
		obj = obj[path];

		if (obj === undefined) {
			return true;
		}
	});

	return obj;
};

module.exports.set = function (obj, path, value) {
	if (!isObject(obj) || typeof path !== 'string') {
		return;
	}

	var pathArr = path.split('.');
	pathArr.forEach(function (path, index) {
		if (!isObject(obj[path])) {
			obj[path] = {};
		}

		if (index === pathArr.length - 1) {
			obj[path] = value;
		}

		obj = obj[path];
	});
};
<commit_msg>minor tweaks<commit_after>'use strict';

function isObjOrFn(x) {
	return (typeof x === 'object' || typeof x === 'function') && x !== null;
}

module.exports.get = function (obj, path) {
	if (!isObjOrFn(obj) || typeof path !== 'string') {
		return obj;
	}

	var pathArr = path.split('.');
	pathArr.some(function (path, index) {
		obj = obj[path];

		if (obj === undefined) {
			return true;
		}
	});

	return obj;
};

module.exports.set = function (obj, path, value) {
	if (!isObjOrFn(obj) || typeof path !== 'string') {
		return;
	}

	var pathArr = path.split('.');
	pathArr.forEach(function (path, index) {
		if (!isObjOrFn(obj[path])) {
			obj[path] = {};
		}

		if (index === pathArr.length - 1) {
			obj[path] = value;
		}

		obj = obj[path];
	});
};
<|endoftext|>


<commit_before>    // core
var fs = require('fs'),
    path = require('path'),

    // libs
    rimraf = require('rimraf'),
    et = require('elementtree'),

    // parts of this lib
    pluginstall = require('../pluginstall'),
    android = require('../platforms/android'),
    nCallbacks = require('../util/ncallbacks'),

    // setup
    config = {
        platform: 'android',
        projectPath: fs.realpathSync('test/project'),
        pluginPath: fs.realpathSync('test/plugin')
    },
    plugin = pluginstall.parseXml(config),
    assetsDir = path.resolve(config.projectPath, 'assets/www'),
    srcDir = path.resolve(config.projectPath, 'src'),
    jsPath = assetsDir + '/childbrowser.js',
    assetPath = assetsDir + '/childbrowser',
    javaDir  = path.resolve(config.projectPath,
                            'src/com/phonegap/plugins/childBrowser'),
    javaPath = path.resolve(javaDir, 'ChildBrowser.java')

function moveProjFile(origFile, callback) {
    var src = path.resolve(config.projectPath, origFile),
        dest = src.replace('.orig', '')

    fs.createReadStream(src)
        .pipe(fs.createWriteStream(dest))
        .on('close', callback);
}

function clean(callback) {
    var ASYNC_OPS = 5,
        end = nCallbacks(ASYNC_OPS, callback);

    // remove JS (that should be moved)
    fs.stat(jsPath, function (err, stats) {
        if (stats) {
            fs.unlinkSync(jsPath)
        }

        end(null);
    });

    // remove web assets (www/childbrowser)
    rimraf(assetPath, end);

    // remove src code directory
    rimraf(javaDir, end);

    // copy in original plugins.xml
    moveProjFile('res/xml/plugins.orig.xml', end)

    // copy in original AndroidManifest.xml
    moveProjFile('AndroidManifest.orig.xml', end)
}

// global setup/teardown
exports.setUp = clean;
exports.tearDown = clean;

exports['should move the js file'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        test.ok(fs.statSync(jsPath))
        test.done();
    })
}

exports['should move the directory'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        var assets = fs.statSync(assetPath);

        test.ok(assets.isDirectory())
        test.ok(fs.statSync(assetPath + '/image.jpg'))
        test.done();
    })
}

exports['should move the src file'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        test.ok(fs.statSync(javaPath))
        test.done();
    })
}

exports['should add ChildBrowser to plugins.xml'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        var pluginsTxt = fs.readFileSync('test/project/res/xml/plugins.xml', 'utf-8'),
            pluginsDoc = new et.ElementTree(et.XML(pluginsTxt)),
            expected = 'plugin[@name="ChildBrowser"]' +
                        '[@value="com.phonegap.plugins.childBrowser.ChildBrowser"]';

        test.ok(pluginsDoc.find(expected));
        test.done();
    })
}

exports['should add ChildBrowser to AndroidManifest.xml'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        var manifestTxt = fs.readFileSync('test/project/AndroidManifest.xml', 'utf-8'),
            manifestDoc = new et.ElementTree(et.XML(manifestTxt)),
            expected = 'manifest/application/activity[@{http://schemas.android.com/apk/res/android}name=' +
                        '"com.phonegap.plugins.childBrowser.ChildBrowser"]';

        test.ok(manifestDoc.find(expected));
        test.done();
    })
}
<commit_msg>[unit-tests] Fixed ios AndroidManifest test<commit_after>    // core
var fs = require('fs'),
    path = require('path'),

    // libs
    rimraf = require('rimraf'),
    et = require('elementtree'),

    // parts of this lib
    pluginstall = require('../pluginstall'),
    android = require('../platforms/android'),
    nCallbacks = require('../util/ncallbacks'),

    // setup
    config = {
        platform: 'android',
        projectPath: fs.realpathSync('test/project'),
        pluginPath: fs.realpathSync('test/plugin')
    },
    plugin = pluginstall.parseXml(config),
    assetsDir = path.resolve(config.projectPath, 'assets/www'),
    srcDir = path.resolve(config.projectPath, 'src'),
    jsPath = assetsDir + '/childbrowser.js',
    assetPath = assetsDir + '/childbrowser',
    javaDir  = path.resolve(config.projectPath,
                            'src/com/phonegap/plugins/childBrowser'),
    javaPath = path.resolve(javaDir, 'ChildBrowser.java')

function moveProjFile(origFile, callback) {
    var src = path.resolve(config.projectPath, origFile),
        dest = src.replace('.orig', '')

    fs.createReadStream(src)
        .pipe(fs.createWriteStream(dest))
        .on('close', callback);
}

function clean(callback) {
    var ASYNC_OPS = 5,
        end = nCallbacks(ASYNC_OPS, callback);

    // remove JS (that should be moved)
    fs.stat(jsPath, function (err, stats) {
        if (stats) {
            fs.unlinkSync(jsPath)
        }

        end(null);
    });

    // remove web assets (www/childbrowser)
    rimraf(assetPath, end);

    // remove src code directory
    rimraf(javaDir, end);

    // copy in original plugins.xml
    moveProjFile('res/xml/plugins.orig.xml', end)

    // copy in original AndroidManifest.xml
    moveProjFile('AndroidManifest.orig.xml', end)
}

// global setup/teardown
exports.setUp = clean;
exports.tearDown = clean;

exports['should move the js file'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        test.ok(fs.statSync(jsPath))
        test.done();
    })
}

exports['should move the directory'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        var assets = fs.statSync(assetPath);

        test.ok(assets.isDirectory())
        test.ok(fs.statSync(assetPath + '/image.jpg'))
        test.done();
    })
}

exports['should move the src file'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        test.ok(fs.statSync(javaPath))
        test.done();
    })
}

exports['should add ChildBrowser to plugins.xml'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        var pluginsTxt = fs.readFileSync('test/project/res/xml/plugins.xml', 'utf-8'),
            pluginsDoc = new et.ElementTree(et.XML(pluginsTxt)),
            expected = 'plugin[@name="ChildBrowser"]' +
                        '[@value="com.phonegap.plugins.childBrowser.ChildBrowser"]';

        test.ok(pluginsDoc.find(expected));
        test.done();
    })
}

exports['should add ChildBrowser to AndroidManifest.xml'] = function (test) {
    android.installPlugin(config, plugin, function (err) {
        var manifestTxt = fs.readFileSync('test/project/AndroidManifest.xml', 'utf-8'),
            manifestDoc = new et.ElementTree(et.XML(manifestTxt)),
            activities = manifestDoc.findall('application/activity'), i;

        for (i=0; i<activities.length; i++) {
            if ( activities[i].attrib['android:name'] === 'com.phonegap.plugins.childBrowser.ChildBrowser' ) {
                test.ok(true);
            }
        }

        test.done();
    })
}
<|endoftext|>


<commit_before>var featureCollection = require('turf-featurecollection');

/**
 * Takes a FeatureCollection, a property, and a value and
 * returns a FeatureCollection with features matching that
 * property-value pair removed.
 *
 * @module turf/remove
 * @param {FeatureCollection} features
 * @param {string} key the key in a feature's properties property
 * @param {string} value the desired value of that property
 * @return {FeatureCollection} a filtered collection with only features that don't match.
 * @example
 * var trees = turf.featurecollection([
 *  turf.point(1,2, {species: 'oak'}),
 *  turf.point(2,1, {species: 'birch'}),
 *  turf.point(3,1, {species: 'oak'}),
 *  turf.point(2,2, {species: 'redwood'}),
 *  turf.point(2,3, {species: 'maple'}),
 *  turf.point(4,2, {species: 'oak'})
 * ]);
 * //=trees
 * var filtered = turf.remove(trees, 'species', 'oak');
 * //=filtered
*/
module.exports = function(collection, key, val) {
  var newFC = featureCollection([]);
  for(var i = 0; i < collection.features.length; i++) {
    if(collection.features[i].properties[key] != val) {
      newFC.features.push(collection.features[i]);
    }
  }
  return newFC;
}
<commit_msg>Clarify input parameters<commit_after>var featureCollection = require('turf-featurecollection');

/**
 * Takes a FeatureCollection, a property, and a value and
 * returns a FeatureCollection with features matching that
 * property-value pair removed.
 *
 * @module turf/remove
 * @param {FeatureCollection} features a FeatureCollection of any type
 * @param {String} property the property to filter
 * @param {String} value the value to filter
 * @return {FeatureCollection} the resulting FeatureCollection without features that match the property-value pair
 * @example
 * var trees = turf.featurecollection([
 *  turf.point(1,2, {species: 'oak'}),
 *  turf.point(2,1, {species: 'birch'}),
 *  turf.point(3,1, {species: 'oak'}),
 *  turf.point(2,2, {species: 'redwood'}),
 *  turf.point(2,3, {species: 'maple'}),
 *  turf.point(4,2, {species: 'oak'})
 * ]);
 * //=trees
 * var filtered = turf.remove(trees, 'species', 'oak');
 * //=filtered
*/
module.exports = function(collection, key, val) {
  var newFC = featureCollection([]);
  for(var i = 0; i < collection.features.length; i++) {
    if(collection.features[i].properties[key] != val) {
      newFC.features.push(collection.features[i]);
    }
  }
  return newFC;
}
<|endoftext|>


<commit_before>/*
Kinesis Streams to Firehose

Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
var debug = false;

var pjson = require('./package.json');
var region = process.env['AWS_REGION'];

if (!region || region === null || region === "") {
	region = "us-east-1";
	console.log("Warning: Setting default region " + region);
}

if (debug) {
	console.log("AWS Kinesis Stream to Firehose Forwarder v" + pjson.version + " in " + region);
}

var aws = require('aws-sdk');
aws.config.update({
	region : region
});

var firehose = new aws.Firehose({
	apiVersion : '2015-08-04',
	region : region
});
var kinesis = new aws.Kinesis({
	apiVersion : '2013-12-02',
	region : region
});
var async = require('async');

var OK = 'OK';
var ERROR = 'ERROR';
var FORWARD_TO_FIREHOSE_STREAM = "ForwardToFirehoseStream";
var FIREHOSE_MAX_BATCH_COUNT = 500;
// firehose max PutRecordBatch size 4MB
var FIREHOSE_MAX_BATCH_BYTES = 4 * 1024 * 1024;

var deliveryStreamMapping = {};

/**
 * Example transformer that adds a newline to each event
 *
 * Args:
 *
 * data - base64 encoded Buffer containing kinesis data
 *
 * callback(err,data) - callback to be called once transformation is completed.
 * data can be undefined if a filter is implemented
 */
exports.addNewlineTransformer = function(data, callback) {
	// emitting a new buffer as ascii text with newline
	callback(null, new Buffer(data.toString('ascii') + "\n"));
}

/**
 * Example transformer that converts a regular expression to delimited text
 */
exports.regexToDelimiter = function(regex, delimiter, data, callback) {
	var tokens = data.toString('ascii').match(regex);

	if (tokens) {
		callback(null, new Buffer(tokens.slice(1).join(delimiter) + "\n"));
	} else {
		callback("Configured Regular Expression does not match any tokens", null);
	}
}
var transformer = exports.addNewlineTransformer.bind(undefined);
//
// example regex transformer that matches all text after 'my regex' and turns it
// into pipe delimited text
// var transformer = exports.regexToDelimiter.bind(undefined, /(myregex) (.*)/,
// "|");

/**
 * Function which returns the byte length of a string
 */
exports.byteCount = function(s) {
	return encodeURI(s).split(/%..|./).length - 1;
}

/**
 * Convenience function which generates the batch set with low and high offsets
 * for pushing data to Firehose in blocks of FIREHOSE_MAX_BATCH_COUNT and
 * staying within the FIREHOSE_MAX_BATCH_BYTES max payload size. Batch ranges
 * are calculated to be compatible with the array.slice() function which uses a
 * non-inclusive upper bound
 */
exports.getBatchRanges = function(records) {
	var batches = [];
	var currentLowOffset = 0;
	var batchCurrentBytes = 0;
	var batchCurrentCount = 0;
	var recordSize;

	for (var i = 0; i < records.length; i++) {
		// need to calculate the total record size for the call to Firehose on
		// the basis of of non-base64 encoded values
		recordSize = exports.byteCount(records[i].Data.toString('ascii'));

		// batch always has 1 entry, so add it first
		batchCurrentBytes += recordSize;
		batchCurrentCount += 1;

		// generate a new batch marker every 4MB or 500 records, whichever comes
		// first
		if (batchCurrentCount === FIREHOSE_MAX_BATCH_COUNT || batchCurrentBytes + recordSize > FIREHOSE_MAX_BATCH_BYTES || i === records.length - 1) {
			batches.push({
				lowOffset : currentLowOffset,
				// annoying special case handling for record sets of size 1
				highOffset : i + 1,
				sizeBytes : batchCurrentBytes
			});
			// reset accumulators
			currentLowOffset = i + 1;
			batchCurrentBytes = 0;
			batchCurrentCount = 0;
		}
	}

	return batches;
}

exports.handler = function(event, context) {
	/** Runtime Functions */
	var finish = function(event, status, message) {
		console.log("Processing Complete");

		// log the event if we've failed
		if (status !== OK) {
			if (message) {
				console.log(message);
			}

			// ensure that Lambda doesn't checkpoint to kinesis on error
			context.done(status, JSON.stringify(message));
		} else {
			context.done(null, message);
		}
	};

	/**
	 * function which handles the output of the defined transformation on each
	 * record.
	 */
	exports.processTransformedRecords = function(transformed, streamName, deliveryStreamName) {
		// get the set of batch offsets based on the transformed record sizes
		var batches = exports.getBatchRanges(transformed);

		if (debug) {
			console.log(JSON.stringify(batches));
		}

		// push to Firehose using PutRecords API at max record count or size.
		// This uses the async reduce method so that records from Kinesis will
		// appear in the Firehose PutRecords request in the same order as they
		// were received by this function
		async.reduce(batches, 0, function(successCount, item, reduceCallback) {
			if (debug) {
				console.log("Forwarding records " + item.lowOffset + ":" + item.highOffset + " - " + item.sizeBytes + " Bytes");
			}

			// grab subset of the records assigned for this batch and push to
			// firehose
			var processRecords = transformed.slice(item.lowOffset, item.highOffset);

			exports.writeToFirehose(processRecords, streamName, deliveryStreamName, function(err) {
				if (err) {
					reduceCallback(err, successCount);
				} else {
					reduceCallback(null, successCount + 1);
				}
			});
		}, function(err, result) {
			if (err) {
				console.log("Forwarding failure after " + result + " successful batches");
				finish(err, ERROR);
			} else {
				console.log("Event forwarding complete. Forwarded " + result + " batches comprising " + event.Records.length + " records to Firehose " + deliveryStreamName);
				finish(null, OK);
			}
		});
	}

	/**
	 * function which forwards a batch of kinesis records to a firehose delivery
	 * stream
	 */
	exports.writeToFirehose = function(firehoseBatch, streamName, deliveryStreamName, callback) {
		// write the batch to firehose with putRecordBatch
		var putRecordBatchParams = {
			DeliveryStreamName : deliveryStreamName,
			Records : firehoseBatch
		};
		firehose.putRecordBatch(putRecordBatchParams, function(err, data) {
			if (err) {
				console.log(JSON.stringify(err));
				callback(err);
			} else {
				if (debug) {
					console.log("Successfully wrote " + firehoseBatch.length + " records to Firehose " + deliveryStreamName);
				}
				callback();
			}
		});
	};
	/**
	 * Function to process a Kinesis Event from AWS Lambda, and generate
	 * requests to forward to Firehose
	 */
	exports.processEvent = function(event, streamName) {
		// look up the delivery stream name of the mapping cache
		var deliveryStreamName = deliveryStreamMapping[streamName];

		if (debug) {
			console.log("Forwarding " + event.Records.length + " Kinesis records to Delivery Stream " + deliveryStreamName);
		}

		// run the user defined transformer for each record to be processed
		async.map(event.Records, function(item, callback) {
			transformer(new Buffer(item.kinesis.data, 'base64'), function(err, transformed) {
				if (err) {
					console.log(JSON.stringify(err));
					callback(err, null);
				} else {
					if (transformed) {
						if (!(transformed instanceof Buffer)) {
							callback("Output of Transformer must be an instance of Buffer", null);
						} else {
							// call the map callback with the transformed Buffer
							// decorated for use as a Firehose batch entry
							callback(null, {
								Data : transformed
							});
						}
					}
				}
			});
		}, function(err, transformed) {
			if (err) {
				finish(err, ERROR)
			} else {
				exports.processTransformedRecords(transformed, streamName, deliveryStreamName);
			}
		});
	};

	/**
	 * Function which resolves the destination delivery stream from the
	 * specified Kinesis Stream Name, using Tags
	 */
	exports.buildDeliveryMap = function(streamName, event, callback) {
		// get the delivery stream name from Kinesis tag
		kinesis.listTagsForStream({
			StreamName : streamName
		}, function(err, data) {
			if (err) {
				finish(event, ERROR, err);
			} else {
				// grab the tag value if it's the foreward_to_firehose name item
				data.Tags.map(function(item) {
					if (item.Key === FORWARD_TO_FIREHOSE_STREAM) {
						deliveryStreamMapping[streamName] = item.Value
					}
				});

				if (!deliveryStreamMapping[streamName]) {
					// fail as the stream isn't tagged for delivery, but since
					// there is an event source configured we think this should
					// have been done and is probably a misconfiguration
					finish(event, ERROR, "Warning: Kinesis Stream " + streamName + " not tagged for Firehose delivery with Tag name " + FORWARD_TO_FIREHOSE_STREAM);
				} else {
					// validate the delivery stream name provided
					var params = {
						DeliveryStreamName : deliveryStreamMapping[streamName]
					};
					firehose.describeDeliveryStream(params, function(err, data) {
						if (err) {
							// do not continue with the cached mapping
							delete deliveryStreamMapping[streamName];

							finish(event, ERROR, "Delivery Stream " + deliveryStreamMapping[streamName] + " does not exist in region " + region);
						} else {
							// call the specified callback - should have already
							// been prepared by the calling function
							callback();
						}
					});
				}
			}
		});
	};
	/** End Runtime Functions */
	if (debug) {
		console.log(JSON.stringify(event));
	}

	// fail the function if the wrong event source type is being sent, or if
	// there is no data, etc
	var noProcessStatus = ERROR;
	var noProcessReason;

	if (!event.Records || event.Records.length === 0) {
		noProcessReason = "Event contains no Data";
		// not fatal - just got an empty event
		noProcessStatus = OK;
	}

	// only configured to support kinesis events. Maybe support SNS in future?
	if (event.Records[0].eventSource !== "aws:kinesis") {
		noProcessReason = "Invalid Event Source " + event.eventSource
	}

	// currently hard coded around the 1.0 kinesis event schema
	if (event.Records[0].kinesis.kinesisSchemaVersion !== "1.0") {
		noProcessReason = "Unsupported Event Schema Version " + event.Records[0].kinesis.kinesisSchemaVersion;
	}

	if (noProcessReason) {
		// terminate if there were any non process reasons
		finish(event, noProcessStatus, noProcessReason);
	} else {
		// parse the stream name out of the event
		var eventSourceARNTokens = event.Records[0].eventSourceARN.split(":");
		var streamName = eventSourceARNTokens[eventSourceARNTokens.length - 1].split("/")[1];

		if (deliveryStreamMapping.length == 0 || !deliveryStreamMapping[streamName]) {
			// no delivery stream cached so far, so add this stream's tag value
			// to the delivery map, and continue with processEvent
			exports.buildDeliveryMap(streamName, event, exports.processEvent.bind(undefined, event, streamName));
		} else {
			// delivery stream is cached
			exports.processEvent(event, streamName);
		}
	}
};<commit_msg>Fixed event source reference<commit_after>/*
Kinesis Streams to Firehose

Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
 */
var debug = false;

var pjson = require('./package.json');
var region = process.env['AWS_REGION'];

if (!region || region === null || region === "") {
	region = "us-east-1";
	console.log("Warning: Setting default region " + region);
}

if (debug) {
	console.log("AWS Kinesis Stream to Firehose Forwarder v" + pjson.version + " in " + region);
}

var aws = require('aws-sdk');
aws.config.update({
	region : region
});

var firehose = new aws.Firehose({
	apiVersion : '2015-08-04',
	region : region
});
var kinesis = new aws.Kinesis({
	apiVersion : '2013-12-02',
	region : region
});
var async = require('async');

var OK = 'OK';
var ERROR = 'ERROR';
var FORWARD_TO_FIREHOSE_STREAM = "ForwardToFirehoseStream";
var FIREHOSE_MAX_BATCH_COUNT = 500;
// firehose max PutRecordBatch size 4MB
var FIREHOSE_MAX_BATCH_BYTES = 4 * 1024 * 1024;

var deliveryStreamMapping = {};

/**
 * Example transformer that adds a newline to each event
 *
 * Args:
 *
 * data - base64 encoded Buffer containing kinesis data
 *
 * callback(err,data) - callback to be called once transformation is completed.
 * data can be undefined if a filter is implemented
 */
exports.addNewlineTransformer = function(data, callback) {
	// emitting a new buffer as ascii text with newline
	callback(null, new Buffer(data.toString('ascii') + "\n"));
}

/**
 * Example transformer that converts a regular expression to delimited text
 */
exports.regexToDelimiter = function(regex, delimiter, data, callback) {
	var tokens = data.toString('ascii').match(regex);

	if (tokens) {
		callback(null, new Buffer(tokens.slice(1).join(delimiter) + "\n"));
	} else {
		callback("Configured Regular Expression does not match any tokens", null);
	}
}
var transformer = exports.addNewlineTransformer.bind(undefined);
//
// example regex transformer that matches all text after 'my regex' and turns it
// into pipe delimited text
// var transformer = exports.regexToDelimiter.bind(undefined, /(myregex) (.*)/,
// "|");

/**
 * Function which returns the byte length of a string
 */
exports.byteCount = function(s) {
	return encodeURI(s).split(/%..|./).length - 1;
}

/**
 * Convenience function which generates the batch set with low and high offsets
 * for pushing data to Firehose in blocks of FIREHOSE_MAX_BATCH_COUNT and
 * staying within the FIREHOSE_MAX_BATCH_BYTES max payload size. Batch ranges
 * are calculated to be compatible with the array.slice() function which uses a
 * non-inclusive upper bound
 */
exports.getBatchRanges = function(records) {
	var batches = [];
	var currentLowOffset = 0;
	var batchCurrentBytes = 0;
	var batchCurrentCount = 0;
	var recordSize;

	for (var i = 0; i < records.length; i++) {
		// need to calculate the total record size for the call to Firehose on
		// the basis of of non-base64 encoded values
		recordSize = exports.byteCount(records[i].Data.toString('ascii'));

		// batch always has 1 entry, so add it first
		batchCurrentBytes += recordSize;
		batchCurrentCount += 1;

		// generate a new batch marker every 4MB or 500 records, whichever comes
		// first
		if (batchCurrentCount === FIREHOSE_MAX_BATCH_COUNT || batchCurrentBytes + recordSize > FIREHOSE_MAX_BATCH_BYTES || i === records.length - 1) {
			batches.push({
				lowOffset : currentLowOffset,
				// annoying special case handling for record sets of size 1
				highOffset : i + 1,
				sizeBytes : batchCurrentBytes
			});
			// reset accumulators
			currentLowOffset = i + 1;
			batchCurrentBytes = 0;
			batchCurrentCount = 0;
		}
	}

	return batches;
}

exports.handler = function(event, context) {
	/** Runtime Functions */
	var finish = function(event, status, message) {
		console.log("Processing Complete");

		// log the event if we've failed
		if (status !== OK) {
			if (message) {
				console.log(message);
			}

			// ensure that Lambda doesn't checkpoint to kinesis on error
			context.done(status, JSON.stringify(message));
		} else {
			context.done(null, message);
		}
	};

	/**
	 * function which handles the output of the defined transformation on each
	 * record.
	 */
	exports.processTransformedRecords = function(transformed, streamName, deliveryStreamName) {
		// get the set of batch offsets based on the transformed record sizes
		var batches = exports.getBatchRanges(transformed);

		if (debug) {
			console.log(JSON.stringify(batches));
		}

		// push to Firehose using PutRecords API at max record count or size.
		// This uses the async reduce method so that records from Kinesis will
		// appear in the Firehose PutRecords request in the same order as they
		// were received by this function
		async.reduce(batches, 0, function(successCount, item, reduceCallback) {
			if (debug) {
				console.log("Forwarding records " + item.lowOffset + ":" + item.highOffset + " - " + item.sizeBytes + " Bytes");
			}

			// grab subset of the records assigned for this batch and push to
			// firehose
			var processRecords = transformed.slice(item.lowOffset, item.highOffset);

			exports.writeToFirehose(processRecords, streamName, deliveryStreamName, function(err) {
				if (err) {
					reduceCallback(err, successCount);
				} else {
					reduceCallback(null, successCount + 1);
				}
			});
		}, function(err, result) {
			if (err) {
				console.log("Forwarding failure after " + result + " successful batches");
				finish(err, ERROR);
			} else {
				console.log("Event forwarding complete. Forwarded " + result + " batches comprising " + event.Records.length + " records to Firehose " + deliveryStreamName);
				finish(null, OK);
			}
		});
	}

	/**
	 * function which forwards a batch of kinesis records to a firehose delivery
	 * stream
	 */
	exports.writeToFirehose = function(firehoseBatch, streamName, deliveryStreamName, callback) {
		// write the batch to firehose with putRecordBatch
		var putRecordBatchParams = {
			DeliveryStreamName : deliveryStreamName,
			Records : firehoseBatch
		};
		firehose.putRecordBatch(putRecordBatchParams, function(err, data) {
			if (err) {
				console.log(JSON.stringify(err));
				callback(err);
			} else {
				if (debug) {
					console.log("Successfully wrote " + firehoseBatch.length + " records to Firehose " + deliveryStreamName);
				}
				callback();
			}
		});
	};
	/**
	 * Function to process a Kinesis Event from AWS Lambda, and generate
	 * requests to forward to Firehose
	 */
	exports.processEvent = function(event, streamName) {
		// look up the delivery stream name of the mapping cache
		var deliveryStreamName = deliveryStreamMapping[streamName];

		if (debug) {
			console.log("Forwarding " + event.Records.length + " Kinesis records to Delivery Stream " + deliveryStreamName);
		}

		// run the user defined transformer for each record to be processed
		async.map(event.Records, function(item, callback) {
			transformer(new Buffer(item.kinesis.data, 'base64'), function(err, transformed) {
				if (err) {
					console.log(JSON.stringify(err));
					callback(err, null);
				} else {
					if (transformed) {
						if (!(transformed instanceof Buffer)) {
							callback("Output of Transformer must be an instance of Buffer", null);
						} else {
							// call the map callback with the transformed Buffer
							// decorated for use as a Firehose batch entry
							callback(null, {
								Data : transformed
							});
						}
					}
				}
			});
		}, function(err, transformed) {
			if (err) {
				finish(err, ERROR)
			} else {
				exports.processTransformedRecords(transformed, streamName, deliveryStreamName);
			}
		});
	};

	/**
	 * Function which resolves the destination delivery stream from the
	 * specified Kinesis Stream Name, using Tags
	 */
	exports.buildDeliveryMap = function(streamName, event, callback) {
		// get the delivery stream name from Kinesis tag
		kinesis.listTagsForStream({
			StreamName : streamName
		}, function(err, data) {
			if (err) {
				finish(event, ERROR, err);
			} else {
				// grab the tag value if it's the foreward_to_firehose name item
				data.Tags.map(function(item) {
					if (item.Key === FORWARD_TO_FIREHOSE_STREAM) {
						deliveryStreamMapping[streamName] = item.Value
					}
				});

				if (!deliveryStreamMapping[streamName]) {
					// fail as the stream isn't tagged for delivery, but since
					// there is an event source configured we think this should
					// have been done and is probably a misconfiguration
					finish(event, ERROR, "Warning: Kinesis Stream " + streamName + " not tagged for Firehose delivery with Tag name " + FORWARD_TO_FIREHOSE_STREAM);
				} else {
					// validate the delivery stream name provided
					var params = {
						DeliveryStreamName : deliveryStreamMapping[streamName]
					};
					firehose.describeDeliveryStream(params, function(err, data) {
						if (err) {
							// do not continue with the cached mapping
							delete deliveryStreamMapping[streamName];

							finish(event, ERROR, "Delivery Stream " + deliveryStreamMapping[streamName] + " does not exist in region " + region);
						} else {
							// call the specified callback - should have already
							// been prepared by the calling function
							callback();
						}
					});
				}
			}
		});
	};
	/** End Runtime Functions */
	if (debug) {
		console.log(JSON.stringify(event));
	}

	// fail the function if the wrong event source type is being sent, or if
	// there is no data, etc
	var noProcessStatus = ERROR;
	var noProcessReason;

	if (!event.Records || event.Records.length === 0) {
		noProcessReason = "Event contains no Data";
		// not fatal - just got an empty event
		noProcessStatus = OK;
	}

	// only configured to support kinesis events. Maybe support SNS in future?
	if (event.Records[0].eventSource !== "aws:kinesis") {
		noProcessReason = "Invalid Event Source " + event.Records[0].eventSource;
	}

	// currently hard coded around the 1.0 kinesis event schema
	if (event.Records[0].kinesis.kinesisSchemaVersion !== "1.0") {
		noProcessReason = "Unsupported Event Schema Version " + event.Records[0].kinesis.kinesisSchemaVersion;
	}

	if (noProcessReason) {
		// terminate if there were any non process reasons
		finish(event, noProcessStatus, noProcessReason);
	} else {
		// parse the stream name out of the event
		var eventSourceARNTokens = event.Records[0].eventSourceARN.split(":");
		var streamName = eventSourceARNTokens[eventSourceARNTokens.length - 1].split("/")[1];

		if (deliveryStreamMapping.length == 0 || !deliveryStreamMapping[streamName]) {
			// no delivery stream cached so far, so add this stream's tag value
			// to the delivery map, and continue with processEvent
			exports.buildDeliveryMap(streamName, event, exports.processEvent.bind(undefined, event, streamName));
		} else {
			// delivery stream is cached
			exports.processEvent(event, streamName);
		}
	}
};<|endoftext|>


<commit_before>(function () {"use strict";})();
/**
 * Created by apizzimenti on 5/19/16.
 */

/**
 * @author Anthony Pizzimenti
 *
 * @desc A set of variables that have to be used in disparate locations.
 *
 * @type {{anchor: number[], mapTileKey: string[], tween: object[], paramNotExist: function}}
 *
 * @property anchor {number[]} Globalized anchor for all sprites.
 * @property mapTileKey {string[]} Will contain keys for tile sprites.
 * @property tween {array} Default tween settings.
 * @property paramNotExist {function} Global testing method for parameters.
 * @property colorTween {function}
 */

var Globals = {
    anchor: [0.5, 0],
    mapTileKey: [],
    tween: [1000, Phaser.Easing.Linear.None, true, 0, 0, false],

    paramNotExist: function (param, type) {
        return (typeof(param) !== type || param == undefined);
    },

    colorTween: function (game, object, start, end, t) {

    var blend = {step: 0},
        tween = game.add.tween(blend).to({step: 100}, time);

    tween.onUpdateCallback(() => {
        object.tint = Phaser.Color.interpolateColor(start, end, blend.step);
    });

    object.tint = start;
    tween.start();
}
};<commit_msg>add colorTween function<commit_after>(function () {"use strict";})();
/**
 * Created by apizzimenti on 5/19/16.
 */

/**
 * @author Anthony Pizzimenti
 *
 * @desc A set of variables that have to be used in disparate locations.
 *
 * @type {{anchor: number[], mapTileKey: string[], tween: object[], paramNotExist: function}}
 *
 * @property anchor {number[]} Globalized anchor for all sprites.
 * @property mapTileKey {string[]} Will contain keys for tile sprites.
 * @property tween {array} Default tween settings.
 * @property paramNotExist {function} Global testing method for parameters.
 * @property colorTween {function}
 */

var Globals = {
    anchor: [0.5, 0],
    mapTileKey: [],
    tween: [1000, Phaser.Easing.Linear.None, true, 0, 0, false],

    paramNotExist: function (param, type) {
        return (typeof(param) !== type || param == undefined);
    },

    colorTween: function (game, object, start, end, t) {

        console.dir(object);

        var blend = {step: 0},
            tween = game.add.tween(blend).to({step: 100}, t);

        tween.onUpdateCallback(() => {
            object.tint = Phaser.Color.interpolateColor(start, end, 100, Math.floor(blend.step), 1);
        });

        object.tint = start;
        tween.start();
    }
};<|endoftext|>


<commit_before>const parseStyle = require('postcss-safe-parser'),
  entities = require('entities');

const property = p => o => o[p];
const isWhitespace = s => /^\s*$/.test(s);

// Rules that are safe to strip from nodes with no child text or only
// whitespace
const contentProps = new Set([
  'color'
  , 'font-family'
  , 'text-align'
  , 'font-weight'
  , 'vertical-align'
  , 'word-wrap'
  , '-webkit-hyphens'
  , '-moz-hyphens'
  , 'hyphens'
]);

const noContentProps = new Set([
  'font-size', 'line-height'
]);

// Rules that are safe to strip from nodes where these rules are
// overriden before they would be applied to any non-whitespace text.
const contentPropsSafe = new Set([
  'color'
  , 'font-family'
  , 'font-weight'
  , 'vertical-align'
  , 'word-wrap'
  , '-webkit-hyphens'
  , '-moz-hyphens'
  , 'hyphens'
]);

// Like contentPropsSafe except will only be removed if never gets
// applied to any text, whitespace or not
const contentPropsNoTextSafe = new Set([
  'text-decoration'
]);

function getText(tree) {
  return (tree.content || []).map(function (child) {
    if (typeof child === 'string') {
      return child;
    } else {
      return getText(child);
    }
  }).join('');
}

function isPropNeverAppliedToText_(targetProp, tree, allowWhitespace) {
  if (typeof tree === 'string') {
    return allowWhitespace ? isWhitespace(tree) : false;
  }

  if (tree.tag === 'img') {
    if (tree.attrs && tree.attrs.style) {
      const styles = parseStyle(tree.attrs.style).nodes;
      if (styles.some(function (s) { return s.prop === targetProp; })) {
        return true;
      }
    }
    return false;
  }

  if (!tree.content) {
    return true;
  }

  if (tree.attrs && tree.attrs.style) {
    const styles = parseStyle(tree.attrs.style).nodes;
    if (styles.some(function (s) { return s.prop === targetProp; })) {
      return true;
    }
  }

  return tree.content.every(function (child) {
    return isPropNeverAppliedToText(targetProp, child);
  });
}

// Same as the _ helper version, except don't check the first level
// for the targetProp style
function isPropNeverAppliedToText(targetProp, tree, allowWhitespace) {
  if (typeof allowWhitespace === 'undefined') {
    allowWhitespace = true;
  }

  if (typeof tree === 'string') {
    return false;
  }
  if (tree.tag === 'img') {
    return false;
  }
  if (!tree.content) {
    return true;
  }

  return tree.content.every(function (child) {
    return isPropNeverAppliedToText_(targetProp, child, allowWhitespace);
  });
}

function postHtmlMinifyInlineCss(tree) {
  tree.match({}, function (node) {
    // Ignore text nodes
    if (!node.tag) {
      return node;
    }

    const text = node.content ? entities.decodeHTML(getText(node)) : '';

    if (isWhitespace(text) && node.attrs && node.attrs.style) {
      if (node.tag.toLowerCase() !== 'img') {
        const styles = parseStyle(node.attrs.style);
        styles.nodes = styles.nodes.filter(function (o) {
          return !contentProps.has(o.prop);
        });
        if (!node.content) {
          styles.nodes = styles.nodes.filter(function (o) {
            return !noContentProps.has(o.prop);
          });
        }
        node.attrs.style = styles.toString();
      }
    }

    if (node.attrs && node.attrs.style) {
      const styles = parseStyle(node.attrs.style),
        props = new Set(styles.nodes.map(property('prop')));

      contentPropsSafe.forEach(function (cp) {
        if (props.has(cp) && isPropNeverAppliedToText(cp, node)) {
          styles.nodes = styles.nodes.filter(function (o) {
            return o.prop !== cp;
          });
        }
      });

      contentPropsNoTextSafe.forEach(function (cp) {
        if (props.has(cp) && isPropNeverAppliedToText(cp, node, false)) {
          styles.nodes = styles.nodes.filter(function (o) {
            return o.prop !== cp;
          });
        }
      });

      node.attrs.style = styles.toString();
    }

    if (node.attrs && node.attrs.style === '') {
      delete node.attrs.style;
    }

    return node;
  });
}

module.exports = function (options) {
  // Options not used; but may be later.
  return postHtmlMinifyInlineCss;
};
<commit_msg>Special case to note remove text-decoration from <a><commit_after>const parseStyle = require('postcss-safe-parser'),
  entities = require('entities');

const property = p => o => o[p];
const isWhitespace = s => /^\s*$/.test(s);

// Rules that are safe to strip from nodes with no child text or only
// whitespace
const contentProps = new Set([
  'color'
  , 'font-family'
  , 'text-align'
  , 'font-weight'
  , 'vertical-align'
  , 'word-wrap'
  , '-webkit-hyphens'
  , '-moz-hyphens'
  , 'hyphens'
]);

const noContentProps = new Set([
  'font-size', 'line-height'
]);

// Rules that are safe to strip from nodes where these rules are
// overriden before they would be applied to any non-whitespace text.
const contentPropsSafe = new Set([
  'color'
  , 'font-family'
  , 'font-weight'
  , 'vertical-align'
  , 'word-wrap'
  , '-webkit-hyphens'
  , '-moz-hyphens'
  , 'hyphens'
]);

// Like contentPropsSafe except will only be removed if never gets
// applied to any text, whitespace or not
const contentPropsNoTextSafe = new Set([
  'text-decoration'
]);

function getText(tree) {
  return (tree.content || []).map(function (child) {
    if (typeof child === 'string') {
      return child;
    } else {
      return getText(child);
    }
  }).join('');
}

function isPropNeverAppliedToText_(targetProp, tree, allowWhitespace) {
  if (typeof tree === 'string') {
    return allowWhitespace ? isWhitespace(tree) : false;
  }

  if (tree.tag === 'img') {
    if (tree.attrs && tree.attrs.style) {
      const styles = parseStyle(tree.attrs.style).nodes;
      if (styles.some(function (s) { return s.prop === targetProp; })) {
        return true;
      }
    }
    return false;
  }

  if (!tree.content) {
    return true;
  }

  if (tree.attrs && tree.attrs.style) {
    const styles = parseStyle(tree.attrs.style).nodes;
    if (styles.some(function (s) { return s.prop === targetProp; })) {
      return true;
    }
  }

  return tree.content.every(function (child) {
    return isPropNeverAppliedToText(targetProp, child);
  });
}

// Same as the _ helper version, except don't check the first level
// for the targetProp style
function isPropNeverAppliedToText(targetProp, tree, allowWhitespace) {
  if (typeof allowWhitespace === 'undefined') {
    allowWhitespace = true;
  }

  if (typeof tree === 'string') {
    return false;
  }
  if (tree.tag === 'img') {
    return false;
  }
  if (!tree.content) {
    return true;
  }

  return tree.content.every(function (child) {
    return isPropNeverAppliedToText_(targetProp, child, allowWhitespace);
  });
}

function postHtmlMinifyInlineCss(tree) {
  tree.match({}, function (node) {
    // Ignore text nodes
    if (!node.tag) {
      return node;
    }

    const text = node.content ? entities.decodeHTML(getText(node)) : '';

    if (isWhitespace(text) && node.attrs && node.attrs.style) {
      if (node.tag.toLowerCase() !== 'img') {
        const styles = parseStyle(node.attrs.style);
        styles.nodes = styles.nodes.filter(function (o) {
          return !contentProps.has(o.prop);
        });
        if (!node.content) {
          styles.nodes = styles.nodes.filter(function (o) {
            return !noContentProps.has(o.prop);
          });
        }
        node.attrs.style = styles.toString();
      }
    }

    if (node.attrs && node.attrs.style) {
      const styles = parseStyle(node.attrs.style),
        props = new Set(styles.nodes.map(property('prop')));

      contentPropsSafe.forEach(function (cp) {
        if (props.has(cp) && isPropNeverAppliedToText(cp, node)) {
          styles.nodes = styles.nodes.filter(function (o) {
            return o.prop !== cp;
          });
        }
      });

      contentPropsNoTextSafe.forEach(function (cp) {
        if (node.tag === 'a' && cp === 'text-decoration') {
          return;
        }

        if (props.has(cp) && isPropNeverAppliedToText(cp, node, false)) {
          styles.nodes = styles.nodes.filter(function (o) {
            return o.prop !== cp;
          });
        }
      });

      node.attrs.style = styles.toString();
    }

    if (node.attrs && node.attrs.style === '') {
      delete node.attrs.style;
    }

    return node;
  });
}

module.exports = function (options) {
  // Options not used; but may be later.
  return postHtmlMinifyInlineCss;
};
<|endoftext|>


<commit_before>// Use Hilbert curve point generation to map 2D data to 1D space and vice-versa.
// Will later expand to allow `n` dimensions.

// Accepts the height or width of a square/graph, and the coordinates to
// convert.
function convert2dPointToDistance (height, x, y) { // :: Int -> Int -> Int -> Int
    var xbit, ybit, level, d = 0
    if (height < 2) {
        height = 2
    }

    // For each Hilbert level, we want to add an amount to
    // `d` based on which region we are in
    for (level = height / 2; level > 0; level /= 2) {
        // Determine what region we're in
        xbit = (x & level) > 0
        ybit = (y & level) > 0
        // increase distance based on region
        d += level * level * ((3 * xbit) ^ ybit)
        // rotate so that we'll be in sync with the next
        // region.
        var temp = rotate2d(height, x, y, xbit, ybit)
        x = temp[0]
        y = temp[1]
    }

    return d
}

// height and coordinates.
function convert3dPointToDistance (height, x, y, z) { // :: Int -> Int -> Int -> Int -> Int
    var s = 1, level = 0, max = Math.max.apply(Math, [x, y, z])
    for (;, 2 * s <= max; s *= 2) {
        level = (level + 1) % 3
    }
}

// Accepts height or width of a square/graph and distance
function convertDistanceTo2dPoint (height, distance) { // :: Int -> Int -> [Int, Int]
    distance = Math.floor(distance)
    var xbit, ybit, level
    var x = 0, y = 0
    if (height < 2) {
        height = 2
    }

    for (level = 1; level < height || distance > 0; level *= 2) {
        ybit = 1 & (distance / 2)
        xbit = 1 & (ybit ^ distance)

        var temp = rotate2d(level, x, y, xbit, ybit)
        x = temp[0]
        y = temp[1]
        x += level * xbit
        y += level * ybit
        distance = Math.floor(distance / 4)
    }

    return [x, y]
}

// height/width of a square/graph and distance
function convertDistanceTo3dPoint (height, distance) { // Int -> Int -> [Int, Int, Int]
    distance = Math.floor(distance)
    var xbit, ybit, zbit, level
    var x = 0, y = 0, z = 0
    if (height < 2) {
        height = 2
    }
    var parity = height % 3;

    for (level = 1; level < height || distance > 0; level *=2) {
        xbit = distance & 1;
        ybit = (ditance / 2) & 1;
        zbit = (distance / 4) & 1;

        var temp = rotate3d(level - 1, xbit ^ ybit, ybit ^ zbit, zbit)
        x = temp[0] * level + level - 1
        y = temp[1] * level + level - 1
        z = temp[2] * level + level - 1

        distance = Math.floor(distance / 8)
    }
}

// Rotate the coordinate plane and (x,y)
function rotate2d (n, x, y, xbit, ybit) { // :: Int -> Int -> Int -> Int -> Int -> [Int, Int]
    if (ybit === 0  ) {
        if (xbit === 1) {
            x = n - 1 - x
            y = n - 1 - y
        }

        var temp = x
        x = y
        y = temp
    }

    return [x, y]
}

// Rotate the coordinate plane and (x,y, z)
function rotate3d(level, x, y, z) { // :: Int -> Int -> Int -> Int -> [Int, Int, Int]
    index = 4 * z + 2 * y + x
    if (index == 0) {
        return [z, x, y]
    } else if (index == 1 || index == 3) {
        return [y, z, x]
    } else if (index == 2 || index == 6) {
        return [level - x, level - y, z]
    } else if (index == 5 || index == 7) {
        return [y, level - z, level - x]
    } else {
        return [level - z, x, level - y]
    }
}

exports.p2d = convert2dPointToDistance
exports.d2p = convertDistanceTo2dPoint
<commit_msg>Compiles.<commit_after>// Use Hilbert curve point generation to map 2D data to 1D space and vice-versa.
// Will later expand to allow `n` dimensions.

// Accepts the height or width of a square/graph, and the coordinates to
// convert.
function convert2dPointToDistance (height, x, y) { // :: Int -> Int -> Int -> Int
    var xbit, ybit, level, d = 0
    if (height < 2) {
        height = 2
    }

    // For each Hilbert level, we want to add an amount to
    // `d` based on which region we are in
    for (level = height / 2; level > 0; level /= 2) {
        // Determine what region we're in
        xbit = (x & level) > 0
        ybit = (y & level) > 0
        // increase distance based on region
        d += level * level * ((3 * xbit) ^ ybit)
        // rotate so that we'll be in sync with the next
        // region.
        var temp = rotate2d(height, x, y, xbit, ybit)
        x = temp[0]
        y = temp[1]
    }

    return d
}

// height and coordinates.
function convert3dPointToDistance (height, x, y, z) { // :: Int -> Int -> Int -> Int -> Int
    var s = 1, level = 0, max = Math.max.apply(Math, [x, y, z])
    for (; 2 * s <= max; s *= 2) {
        level = (level + 1) % 3
    }
}

// Accepts height or width of a square/graph and distance
function convertDistanceTo2dPoint (height, distance) { // :: Int -> Int -> [Int, Int]
    distance = Math.floor(distance)
    var xbit, ybit, level
    var x = 0, y = 0
    if (height < 2) {
        height = 2
    }

    for (level = 1; level < height || distance > 0; level *= 2) {
        ybit = 1 & (distance / 2)
        xbit = 1 & (ybit ^ distance)

        var temp = rotate2d(level, x, y, xbit, ybit)
        x = temp[0]
        y = temp[1]
        x += level * xbit
        y += level * ybit
        distance = Math.floor(distance / 4)
    }

    return [x, y]
}

// height/width of a square/graph and distance
function convertDistanceTo3dPoint (height, distance) { // Int -> Int -> [Int, Int, Int]
    distance = Math.floor(distance)
    var xbit, ybit, zbit, level
    var x = 0, y = 0, z = 0
    if (height < 2) {
        height = 2
    }
    var parity = height % 3;

    for (level = 1; level < height || distance > 0; level *=2) {
        xbit = distance & 1;
        ybit = (ditance / 2) & 1;
        zbit = (distance / 4) & 1;

        var temp = rotate3d(level - 1, xbit ^ ybit, ybit ^ zbit, zbit)
        x = temp[0] * level + level - 1
        y = temp[1] * level + level - 1
        z = temp[2] * level + level - 1

        distance = Math.floor(distance / 8)
    }
}

// Rotate the coordinate plane and (x,y)
function rotate2d (n, x, y, xbit, ybit) { // :: Int -> Int -> Int -> Int -> Int -> [Int, Int]
    if (ybit === 0  ) {
        if (xbit === 1) {
            x = n - 1 - x
            y = n - 1 - y
        }

        var temp = x
        x = y
        y = temp
    }

    return [x, y]
}

// Rotate the coordinate plane and (x,y, z)
function rotate3d(level, x, y, z) { // :: Int -> Int -> Int -> Int -> [Int, Int, Int]
    index = 4 * z + 2 * y + x
    if (index == 0) {
        return [z, x, y]
    } else if (index == 1 || index == 3) {
        return [y, z, x]
    } else if (index == 2 || index == 6) {
        return [level - x, level - y, z]
    } else if (index == 5 || index == 7) {
        return [y, level - z, level - x]
    } else {
        return [level - z, x, level - y]
    }
}

exports.p2d = convert2dPointToDistance
exports.d2p = convertDistanceTo2dPoint
<|endoftext|>