<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var ConcatSource = require("webpack-core/lib/ConcatSource");
var OriginalSource = require("webpack-core/lib/OriginalSource");
var PrefixSource = require("webpack-core/lib/PrefixSource");
var Template = require("./Template");

function MainTemplate(outputOptions) {
	Template.call(this, outputOptions);
}
module.exports = MainTemplate;

MainTemplate.prototype = Object.create(Template.prototype);
MainTemplate.prototype.requireFn = "require";
MainTemplate.prototype.render = function(hash, chunk, moduleTemplate, dependencyTemplates) {
	var buf = [];
	buf.push(this.asString(this.renderAdditions(hash, chunk, moduleTemplate, dependencyTemplates)));
	buf.push(this.asString(this.renderLocalVars(hash, chunk)));
	buf.push("");
	buf.push("// The require function");
	buf.push("function " + this.requireFn + "(moduleId) {");
	buf.push(this.indent(this.renderRequireContent(hash, chunk)));
	buf.push("}");
	buf.push("");
	buf.push(this.asString(this.renderRequireExtensions(hash, chunk)));
	buf.push(this.asString(this.renderInit(hash, chunk)));
	if(chunk.modules.some(function(m) { return m.id === 0; })) {
		buf.push("");
		buf.push("// Load entry module and return exports");
		buf.push("return " + this.renderRequireFunctionForModule(hash, chunk, "0") + "(0);");
	}
	var source = new ConcatSource();
	source.add("/******/ (function(modules) { // webpackBootstrap\n");
	source.add(new PrefixSource("/******/ \t", new OriginalSource(this.asString(buf), "webpackBootstrap " + hash)));
	source.add("\n/******/ })\n");
	source.add("/************************************************************************/\n");
	source.add("/******/ (");
	source.add(this.renderModules(hash, chunk, moduleTemplate, dependencyTemplates));
	source.add(")");
	chunk.rendered = true;
	return source;
};

MainTemplate.prototype.renderModules = function renderModules(hash, chunk, moduleTemplate, dependencyTemplates) {
	return this.renderChunkModules(chunk, moduleTemplate, dependencyTemplates, "/******/ ");
};

MainTemplate.prototype.indent = function indent(str) {
	if(Array.isArray(str)) {
		return str.map(indent).join("\n");
	} else {
		return "\t" + str.trimRight().replace(/\n/g, "\n\t");
	}
};

MainTemplate.prototype.prefix = function(str, prefix) {
	if(Array.isArray(str)) {
		str = str.join("\n");
	}
	return prefix + str.trim().replace(/\n/g, "\n" + prefix);
};

MainTemplate.prototype.asString = function(str) {
	if(Array.isArray(str)) {
		return str.join("\n");
	}
	return str;
};

MainTemplate.prototype.renderLocalVars = function(hash, chunk) {
	return [
		"// The module cache",
		"var installedModules = {};"
	];
};

MainTemplate.prototype.renderRequireContent = function(hash, chunk) {
	return [
		"// Check if module is in cache",
		"if(installedModules[moduleId])",
		this.indent("return installedModules[moduleId].exports;"),
		"",
		"// Create a new module (and put it into the cache)",
		"var module = installedModules[moduleId] = {",
		this.indent(this.renderModule(hash, chunk, "moduleId")),
		"};",
		"",
		"// Execute the module function",
		"modules[moduleId].call(module.exports, module, module.exports, " + this.renderRequireFunctionForModule(hash, chunk, "moduleId") + ");",
		"",
		"// Flag the module as loaded",
		"module.loaded = true;",
		"",
		"// Return the exports of the module",
		"return module.exports;"
	];
};

MainTemplate.prototype.renderRequireFunctionForModule = function(hash, chunk, varModuleId) {
	return this.requireFn;
};

MainTemplate.prototype.renderModule = function(hash, chunk, varModuleId) {
	return [
		"exports: {},",
		"id: moduleId,",
		"loaded: false"
	];
};

MainTemplate.prototype.renderRequireExtensions = function(hash, chunk) {
	var buf = [];
	if(chunk.chunks.length == 0) {
		buf.push("// The bundle contains no chunks. A empty chunk loading function.");
		buf.push(this.requireFn + ".e = function requireEnsure(_, callback) {");
		buf.push(this.indent([
			"callback.call(null, this);"
		]));
		buf.push("};");
	} else {
		buf.push("// This file contains only the entry chunk.");
		buf.push("// The chunk loading function for additional chunks");
		buf.push(this.requireFn + ".e = function requireEnsure(chunkId, callback) {");
		buf.push(this.indent(this.renderRequireEnsure(hash, chunk)));
		buf.push("};");
	}
	buf.push("");
	buf.push("// expose the modules object (__webpack_modules__)");
	buf.push(this.requireFn + ".modules = modules;");

	buf.push("");
	buf.push("// expose the module cache");
	buf.push(this.requireFn + ".cache = installedModules;");

	var publicPath = this.outputOptions.publicPath || "";
	publicPath = publicPath.replace(Template.REGEXP_HASH, hash);
	buf.push("");
	buf.push("// __webpack_public_path__");
	buf.push(this.requireFn + ".p = " + JSON.stringify(publicPath) + ";");
	return buf;
};

MainTemplate.prototype.renderInit = function(hash, chunk) {
	return [];
};

MainTemplate.prototype.renderAdditions = function(hash, chunk, moduleTemplate, dependencyTemplates) {
	return [];
};

MainTemplate.prototype.renderAddModule = function(hash, chunk, varModuleId, varModule) {
	return ["modules[" + varModuleId + "] = " + varModule + ";"];
};

MainTemplate.prototype.renderCurrentHashCode = function(hash) {
	return JSON.stringify(hash);
};

MainTemplate.prototype.updateHash = function(hash) {
	hash.update("maintemplate");
	hash.update("2");
	hash.update(this.outputOptions.publicPath + "");
};<commit_msg>save 8 chars<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
var ConcatSource = require("webpack-core/lib/ConcatSource");
var OriginalSource = require("webpack-core/lib/OriginalSource");
var PrefixSource = require("webpack-core/lib/PrefixSource");
var Template = require("./Template");

function MainTemplate(outputOptions) {
	Template.call(this, outputOptions);
}
module.exports = MainTemplate;

MainTemplate.prototype = Object.create(Template.prototype);
MainTemplate.prototype.requireFn = "require";
MainTemplate.prototype.render = function(hash, chunk, moduleTemplate, dependencyTemplates) {
	var buf = [];
	buf.push("// shortcut for better minimizing");
	buf.push("var exports = \"exports\";");
	buf.push(this.asString(this.renderAdditions(hash, chunk, moduleTemplate, dependencyTemplates)));
	buf.push(this.asString(this.renderLocalVars(hash, chunk)));
	buf.push("");
	buf.push("// The require function");
	buf.push("function " + this.requireFn + "(moduleId) {");
	buf.push(this.indent(this.renderRequireContent(hash, chunk)));
	buf.push("}");
	buf.push("");
	buf.push(this.asString(this.renderRequireExtensions(hash, chunk)));
	buf.push(this.asString(this.renderInit(hash, chunk)));
	if(chunk.modules.some(function(m) { return m.id === 0; })) {
		buf.push("");
		buf.push("// Load entry module and return exports");
		buf.push("return " + this.renderRequireFunctionForModule(hash, chunk, "0") + "(0);");
	}
	var source = new ConcatSource();
	source.add("/******/ (function(modules) { // webpackBootstrap\n");
	source.add(new PrefixSource("/******/ \t", new OriginalSource(this.asString(buf), "webpackBootstrap " + hash)));
	source.add("\n/******/ })\n");
	source.add("/************************************************************************/\n");
	source.add("/******/ (");
	source.add(this.renderModules(hash, chunk, moduleTemplate, dependencyTemplates));
	source.add(")");
	chunk.rendered = true;
	return source;
};

MainTemplate.prototype.renderModules = function renderModules(hash, chunk, moduleTemplate, dependencyTemplates) {
	return this.renderChunkModules(chunk, moduleTemplate, dependencyTemplates, "/******/ ");
};

MainTemplate.prototype.indent = function indent(str) {
	if(Array.isArray(str)) {
		return str.map(indent).join("\n");
	} else {
		return "\t" + str.trimRight().replace(/\n/g, "\n\t");
	}
};

MainTemplate.prototype.prefix = function(str, prefix) {
	if(Array.isArray(str)) {
		str = str.join("\n");
	}
	return prefix + str.trim().replace(/\n/g, "\n" + prefix);
};

MainTemplate.prototype.asString = function(str) {
	if(Array.isArray(str)) {
		return str.join("\n");
	}
	return str;
};

MainTemplate.prototype.renderLocalVars = function(hash, chunk) {
	return [
		"// The module cache",
		"var installedModules = {};"
	];
};

MainTemplate.prototype.renderRequireContent = function(hash, chunk) {
	return [
		"// Check if module is in cache",
		"if(installedModules[moduleId])",
		this.indent("return installedModules[moduleId][exports];"),
		"",
		"// Create a new module (and put it into the cache)",
		"var module = installedModules[moduleId] = {",
		this.indent(this.renderModule(hash, chunk, "moduleId")),
		"};",
		"",
		"// Execute the module function",
		"modules[moduleId].call(module[exports], module, module[exports], " + this.renderRequireFunctionForModule(hash, chunk, "moduleId") + ");",
		"",
		"// Flag the module as loaded",
		"module.loaded = true;",
		"",
		"// Return the exports of the module",
		"return module[exports];"
	];
};

MainTemplate.prototype.renderRequireFunctionForModule = function(hash, chunk, varModuleId) {
	return this.requireFn;
};

MainTemplate.prototype.renderModule = function(hash, chunk, varModuleId) {
	return [
		"exports: {},",
		"id: moduleId,",
		"loaded: false"
	];
};

MainTemplate.prototype.renderRequireExtensions = function(hash, chunk) {
	var buf = [];
	if(chunk.chunks.length == 0) {
		buf.push("// The bundle contains no chunks. A empty chunk loading function.");
		buf.push(this.requireFn + ".e = function requireEnsure(_, callback) {");
		buf.push(this.indent([
			"callback.call(null, this);"
		]));
		buf.push("};");
	} else {
		buf.push("// This file contains only the entry chunk.");
		buf.push("// The chunk loading function for additional chunks");
		buf.push(this.requireFn + ".e = function requireEnsure(chunkId, callback) {");
		buf.push(this.indent(this.renderRequireEnsure(hash, chunk)));
		buf.push("};");
	}
	buf.push("");
	buf.push("// expose the modules object (__webpack_modules__)");
	buf.push(this.requireFn + ".modules = modules;");

	buf.push("");
	buf.push("// expose the module cache");
	buf.push(this.requireFn + ".cache = installedModules;");

	var publicPath = this.outputOptions.publicPath || "";
	publicPath = publicPath.replace(Template.REGEXP_HASH, hash);
	buf.push("");
	buf.push("// __webpack_public_path__");
	buf.push(this.requireFn + ".p = " + JSON.stringify(publicPath) + ";");
	return buf;
};

MainTemplate.prototype.renderInit = function(hash, chunk) {
	return [];
};

MainTemplate.prototype.renderAdditions = function(hash, chunk, moduleTemplate, dependencyTemplates) {
	return [];
};

MainTemplate.prototype.renderAddModule = function(hash, chunk, varModuleId, varModule) {
	return ["modules[" + varModuleId + "] = " + varModule + ";"];
};

MainTemplate.prototype.renderCurrentHashCode = function(hash) {
	return JSON.stringify(hash);
};

MainTemplate.prototype.updateHash = function(hash) {
	hash.update("maintemplate");
	hash.update("2");
	hash.update(this.outputOptions.publicPath + "");
};<|endoftext|>


<commit_before>import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';

class Portal extends React.Component {
  componentDidMount() {
    this.nodeEl = document.createElement('div');
    document.body.appendChild(this.nodeEl);
    this.renderChildren(this.props);
  }

  componentWillUnmount() {
    ReactDOM.unmountComponentAtNode(this.nodeEl);
    document.body.removeChild(this.nodeEl);
  }

  componentWillReceiveProps(nextProps) {
    this.renderChildren(nextProps);
  }

  renderChildren(props) {
    ReactDOM.render(props.children, this.nodeEl);
  }

  render() {
    return null;
  }
}

Portal.propTypes = {
  children: PropTypes.node.isRequired
};

module.exports = Portal;
<commit_msg>Allow passing null to Portal children and render callback<commit_after>import React, {PropTypes} from 'react';
import ReactDOM from 'react-dom';

class Portal extends React.Component {
  componentDidMount() {
    this.nodeEl = document.createElement('div');
    document.body.appendChild(this.nodeEl);
    this.renderChildren(this.props);
  }

  componentWillUnmount() {
    ReactDOM.unmountComponentAtNode(this.nodeEl);
    document.body.removeChild(this.nodeEl);
  }

  componentWillReceiveProps(nextProps) {
    this.renderChildren(nextProps);
  }

  renderChildren(props) {
    let {children} = props;

    if (children == null) {
      children = <div />;
    }

    ReactDOM.render(children, this.nodeEl, this.props.onRender);
  }

  render() {
    return null;
  }
}

Portal.propTypes = {
  children: PropTypes.node,
  onRender: PropTypes.func
};

module.exports = Portal;
<|endoftext|>


<commit_before>var _fs = require('fs');
var _nodeMcuConnector = require('./NodeMcuConnector');
var _serialTerminal = require('./SerialTerminal');
var _path = require('path');
// global default error handler
var errorHandler = function(source, error){
    console.error('[' + source + '] ' + error);
};

// status messages
var statusHandler = function(source, message){
    console.log('[' + source + '] ' + message);
};

// print
var logStatus = function(source, message){
    if (statusHandler){
        statusHandler(source, message);
    }
};
var logError = function(source, error){
    if (errorHandler){
        errorHandler(source, error);
    }
};

// Programmatic Access to the core functions
var Tool = {

    // access the connector directly
    Connector: _nodeMcuConnector,

    // set the error handler
    onError: function(handler){
        errorHandler = handler;
    },

    // set status handler
    onStatus: function(handler){
        statusHandler = handler;
    },

    // show file-system info
    fsinfo: function(port, baud){
        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);

            connector.fsinfo(function(err, meta, files){
                if (err){
                    logError('NodeMCU-Tool', err);
                }else{
                    logStatus('NodeMCU', 'Free Disk Space: ' + meta.remaining + ' KB | Total: ' + meta.total + ' KB | ' + files.length + ' Files');

                    // files found ?
                    if (files.length==0){
                        logStatus('NodeMCU', 'No Files found - have you created the file-system?');
                    }else{
                        logStatus('NodeMCU', 'Files stored into Flash (SPIFFS)');

                        // print fileinfo
                        files.forEach(function(file){
                            logStatus('', '\t  |- ' + file.name + ' (' + file.size + ' Bytes)');
                        });
                    }

                    // finished!
                    connector.disconnect();
                }
            });
        });
    },

    // upload a local file to nodemcu
    upload: function(port, baud, localFile, options, onProgess){
        // local file available ?
        if (!_fs.existsSync(localFile)){
            errorHandler('NodeMCU-Tool', 'Local file not found "' + localFile + '"');
            return;
        }

        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);

            // filename defaults to original filename minus path.
            // this behaviour can be overridden by --keeppath and --remotename options
            var remoteFile = options.remotename ? options.remotename : (options.keeppath ? localFile : _path.basename(localFile));

            // normalize the remote filename (strip relative parts)
            remoteFile = remoteFile.replace(/\.\.\//g, '').replace(/\.\./g, '');

            // display filenames
            logStatus('NodeMCU-Tool', 'Uploading "' + localFile + '" >> "' + remoteFile + '"...');

            // start the file transfer
            connector.upload(localFile, remoteFile, options,

                // onComplete
                function(err){
                    logStatus('NodeMCU-Tool', 'Data Transfer complete!');

                    // compile flag set ?
                    if (options.compile){
                        logStatus('NodeMCU', 'compiling lua file..');

                        connector.compile(remoteFile, function(error){
                            // success ? empty line will return (null)
                            if (error){
                                connector.disconnect();
                                logError('NodeMCU', 'Error: ' + error);
                            }else{
                                logStatus('NodeMCU', 'Success');

                                // drop original lua file
                                connector.removeFile(remoteFile, function(){
                                    connector.disconnect();
                                    logStatus('NodeMCU', 'Original LUA file removed');
                                });
                            }
                        });

                    }else{
                        // finished!
                        connector.disconnect();
                    }
                },
                // on progress handler
                onProgess || function(){}
            );
        });
    },

    // download a remote file from nodemcu
    download: function(port, baud, remoteFile){
        var localFilename = remoteFile;

        // local file with same name already available ?
        if (_fs.existsSync(remoteFile)){
            // change filename
            localFilename += '.' + (new Date().getTime());

            logStatus('NodeMCU-Tool', 'Local file "' + remoteFile + '" already exist - new file renamed to "' + localFilename + '"');
        }

        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);
            logStatus('NodeMCU-Tool', 'Downloading "' + remoteFile + '" ...');

            connector.download(remoteFile,
                // onComplete
                function(err, filedata){
                    if (err){
                        logStatus('NodeMCU-Tool', 'Data Transfer FAILED!');
                    }else{
                        logStatus('NodeMCU-Tool', 'Data Transfer complete!');

                        // store local file
                        _fs.writeFileSync(localFilename, filedata);

                        logStatus('NodeMCU-Tool', 'File "' + localFilename + '" created');
                    }

                    // finished!
                    connector.disconnect();
                }
            );
        });
    },

    // run a file on NodeMCU (.lc or .lua)
    run: function(port, baud, filename){
        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);

            connector.run(filename, function(err, output){
                if (err){
                    logError('NodeMCU', err);
                }else{
                    // show command response
                    logStatus('NodeMCU', 'Running "' + filename + '"');
                    logStatus('', '>----------------------------->');
                    logStatus('', output);
                    logStatus('', '>----------------------------->');
                }

                // finished!
                connector.disconnect();
            });
        });
    },

    // removes a file o nodemcu
    remove: function(port, baud, filename, cb){
        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);

            connector.removeFile(filename, function(err){
                if (err){
                    logError('NodeMCU', err);
                }else{
                    // just show complete message (no feedback from nodemcu)
                    logStatus('NodeMCU', 'File "' + filename + '" removed!');
                }

                // finished!
                connector.disconnect();
            });
        });
    },

    // format the file system
    mkfs: function(port, baud){
        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);
            logStatus('NodeMCU', 'Formatting the file system...this will take around ~30s');

            connector.format(function(err, response){
                if (err){
                    logError('NodeMCU', 'Formatting failed - ' + err);
                }else{
                    // just show complete message
                    logStatus('NodeMCU', 'File System created | ' + response);
                }

                // finished!
                connector.disconnect();
            });
        });

    },

    // serial terminal <> console session
    terminal: function(port, baud){
        // create new connector
        var terminal = new _serialTerminal();

        // handle connection errors
        terminal.onError(errorHandler);

        logStatus('SerialTerminal', 'Starting Terminal Mode - press ctrl+c to exit');

        // start
        terminal.passthrough(port, baud, function(err){
            if (err){
                logError('SerialTerminal', err);
            }else{
                logStatus('SerialTerminal', 'Connection closed');
            }
        });
    }
};

module.exports = Tool;
<commit_msg>added filter to strip local dir reference from remote filename<commit_after>var _fs = require('fs');
var _nodeMcuConnector = require('./NodeMcuConnector');
var _serialTerminal = require('./SerialTerminal');
var _path = require('path');
// global default error handler
var errorHandler = function(source, error){
    console.error('[' + source + '] ' + error);
};

// status messages
var statusHandler = function(source, message){
    console.log('[' + source + '] ' + message);
};

// print
var logStatus = function(source, message){
    if (statusHandler){
        statusHandler(source, message);
    }
};
var logError = function(source, error){
    if (errorHandler){
        errorHandler(source, error);
    }
};

// Programmatic Access to the core functions
var Tool = {

    // access the connector directly
    Connector: _nodeMcuConnector,

    // set the error handler
    onError: function(handler){
        errorHandler = handler;
    },

    // set status handler
    onStatus: function(handler){
        statusHandler = handler;
    },

    // show file-system info
    fsinfo: function(port, baud){
        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);

            connector.fsinfo(function(err, meta, files){
                if (err){
                    logError('NodeMCU-Tool', err);
                }else{
                    logStatus('NodeMCU', 'Free Disk Space: ' + meta.remaining + ' KB | Total: ' + meta.total + ' KB | ' + files.length + ' Files');

                    // files found ?
                    if (files.length==0){
                        logStatus('NodeMCU', 'No Files found - have you created the file-system?');
                    }else{
                        logStatus('NodeMCU', 'Files stored into Flash (SPIFFS)');

                        // print fileinfo
                        files.forEach(function(file){
                            logStatus('', '\t  |- ' + file.name + ' (' + file.size + ' Bytes)');
                        });
                    }

                    // finished!
                    connector.disconnect();
                }
            });
        });
    },

    // upload a local file to nodemcu
    upload: function(port, baud, localFile, options, onProgess){
        // local file available ?
        if (!_fs.existsSync(localFile)){
            errorHandler('NodeMCU-Tool', 'Local file not found "' + localFile + '"');
            return;
        }

        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);

            // filename defaults to original filename minus path.
            // this behaviour can be overridden by --keeppath and --remotename options
            var remoteFile = options.remotename ? options.remotename : (options.keeppath ? localFile : _path.basename(localFile));

            // normalize the remote filename (strip relative parts)
            remoteFile = remoteFile.replace(/\.\.\//g, '').replace(/\.\./g, '').replace(/^\.\//, '');

            // display filenames
            logStatus('NodeMCU-Tool', 'Uploading "' + localFile + '" >> "' + remoteFile + '"...');

            // start the file transfer
            connector.upload(localFile, remoteFile, options,

                // onComplete
                function(err){
                    logStatus('NodeMCU-Tool', 'Data Transfer complete!');

                    // compile flag set ?
                    if (options.compile){
                        logStatus('NodeMCU', 'compiling lua file..');

                        connector.compile(remoteFile, function(error){
                            // success ? empty line will return (null)
                            if (error){
                                connector.disconnect();
                                logError('NodeMCU', 'Error: ' + error);
                            }else{
                                logStatus('NodeMCU', 'Success');

                                // drop original lua file
                                connector.removeFile(remoteFile, function(){
                                    connector.disconnect();
                                    logStatus('NodeMCU', 'Original LUA file removed');
                                });
                            }
                        });

                    }else{
                        // finished!
                        connector.disconnect();
                    }
                },
                // on progress handler
                onProgess || function(){}
            );
        });
    },

    // download a remote file from nodemcu
    download: function(port, baud, remoteFile){
        var localFilename = remoteFile;

        // local file with same name already available ?
        if (_fs.existsSync(remoteFile)){
            // change filename
            localFilename += '.' + (new Date().getTime());

            logStatus('NodeMCU-Tool', 'Local file "' + remoteFile + '" already exist - new file renamed to "' + localFilename + '"');
        }

        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);
            logStatus('NodeMCU-Tool', 'Downloading "' + remoteFile + '" ...');

            connector.download(remoteFile,
                // onComplete
                function(err, filedata){
                    if (err){
                        logStatus('NodeMCU-Tool', 'Data Transfer FAILED!');
                    }else{
                        logStatus('NodeMCU-Tool', 'Data Transfer complete!');

                        // store local file
                        _fs.writeFileSync(localFilename, filedata);

                        logStatus('NodeMCU-Tool', 'File "' + localFilename + '" created');
                    }

                    // finished!
                    connector.disconnect();
                }
            );
        });
    },

    // run a file on NodeMCU (.lc or .lua)
    run: function(port, baud, filename){
        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);

            connector.run(filename, function(err, output){
                if (err){
                    logError('NodeMCU', err);
                }else{
                    // show command response
                    logStatus('NodeMCU', 'Running "' + filename + '"');
                    logStatus('', '>----------------------------->');
                    logStatus('', output);
                    logStatus('', '>----------------------------->');
                }

                // finished!
                connector.disconnect();
            });
        });
    },

    // removes a file o nodemcu
    remove: function(port, baud, filename, cb){
        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);

            connector.removeFile(filename, function(err){
                if (err){
                    logError('NodeMCU', err);
                }else{
                    // just show complete message (no feedback from nodemcu)
                    logStatus('NodeMCU', 'File "' + filename + '" removed!');
                }

                // finished!
                connector.disconnect();
            });
        });
    },

    // format the file system
    mkfs: function(port, baud){
        // create new connector
        var connector = new _nodeMcuConnector(port, baud);

        // handle connection errors
        connector.onError(errorHandler);

        connector.connect(function(error, response){
            if (error){
                logError('NodeMCU-Tool', 'Unable to establish connection');
                return;
            }

            logStatus('NodeMCU-Tool', 'Connected');
            logStatus('NodeMCU', response);
            logStatus('NodeMCU', 'Formatting the file system...this will take around ~30s');

            connector.format(function(err, response){
                if (err){
                    logError('NodeMCU', 'Formatting failed - ' + err);
                }else{
                    // just show complete message
                    logStatus('NodeMCU', 'File System created | ' + response);
                }

                // finished!
                connector.disconnect();
            });
        });

    },

    // serial terminal <> console session
    terminal: function(port, baud){
        // create new connector
        var terminal = new _serialTerminal();

        // handle connection errors
        terminal.onError(errorHandler);

        logStatus('SerialTerminal', 'Starting Terminal Mode - press ctrl+c to exit');

        // start
        terminal.passthrough(port, baud, function(err){
            if (err){
                logError('SerialTerminal', err);
            }else{
                logStatus('SerialTerminal', 'Connection closed');
            }
        });
    }
};

module.exports = Tool;
<|endoftext|>


<commit_before>/**
 * Class for managing a pool of resources
 *
 * @param {object} options
 * @param {int} options.max
 *   Maximum number of resources to keep
 * @param {int} options.maxUses
 *   Maximum number of times a resource may be used
 * @param {function} options.create
 *   Called to create a new Resource
 * @param {function} options.destroy
 *   Called to destroy an resource, after it is used up
 *   -- @param {Resource}
 * @param {function} options.task
 *   Called to process a task
 *   -- @param {object} task
 *   -- @param {Resouce} resource
 * @param {function} options.complete
 *   Called when Pool runs out of tasks
 */
function ResourcePool (options) {
	this.max = options.max || 1;
	this.maxUses = options.maxUses || 1;
	this.create = options.create || function () {};
	this.destroy = options.destroy || function () {};
	this.task = options.task || function () {};
	this.complete = options.complete || function () {};
	this.active = 0;
	this.resources = new Array(this.max);
	this.resourceActive = new Array(this.max);
	this.resourceUses = new Array(this.max);
	this.tasks = [];
}
ResourcePool.prototype.churn = function () {
	while (this.tasks.length && this.active < this.max) {
		var resource = this.get();
		var task = this.tasks.pop();
		setImmediate(this.task.bind(this, task, resource));
	}
};
/**
 * Apply a new task to the queue
 *
 * @param {object[]} task
 *   Called when a "resource" becomes available to handle the task
 */
ResourcePool.prototype.enqueue = function (tasks) {
	this.tasks.push.apply(this.tasks, tasks);
	this.churn();
};
/**
 * Get a Resource from the pool of resources
 *   Create a new Resource if necessary
 *
 * @return {Resource|null}
 *   returns null if pool is full
 */
ResourcePool.prototype.get = function () {
	for (var i = 0; i < this.max; i++) {
		if (!this.resourceActive[i]) {
			if (!this.resources[i]) {
				this.resources[i] = this.create();
				this.resourceUses[i] = 0;
			}
			this.resourceActive[i] = true;
			this.resourceUses[i]++;
			this.active++;
			return this.resources[i];
		}
	}
	return null;
};
/**
 * Release a Resource back to the pool
 *   If a Resource has been used to the max, it is destroyed
 *
 * @param {Resource} resource
 *   The Resource to release back to the pool
 */
ResourcePool.prototype.release = function (resource) {
	for (var i = 0; i < this.max; i++) {
		if (this.resources[i] === resource) {
			if (this.resourceUses[i] >= this.maxUses) {
				resource.destroy();
				this.resources[i] = null;
				this.resourceUses[i] = 0;
			}
			this.resourceActive[i] = false;
			this.active--;
		}
	}
	if (this.tasks.length) {
		this.churn();
	}
	else if (this.active < 1) {
		this.drain();
		this.complete();
	}
};
/**
 * Destroy all resources
 */
ResourcePool.prototype.drain = function () {
	for (var i = 0; i < this.max; i++) {
		if (this.resources[i]) {
			this.destroy(this.resources[i]);
			this.resourceUses[i] = 0;
			this.resourceActive[i] = false;
		}
	}
	this.active = 0;
};

module.exports = ResourcePool;
<commit_msg>You're a Queue, not a stack<commit_after>/**
 * Class for managing a pool of resources
 *
 * @param {object} options
 * @param {int} options.max
 *   Maximum number of resources to keep
 * @param {int} options.maxUses
 *   Maximum number of times a resource may be used
 * @param {function} options.create
 *   Called to create a new Resource
 * @param {function} options.destroy
 *   Called to destroy an resource, after it is used up
 *   -- @param {Resource}
 * @param {function} options.task
 *   Called to process a task
 *   -- @param {object} task
 *   -- @param {Resouce} resource
 * @param {function} options.complete
 *   Called when Pool runs out of tasks
 */
function ResourcePool (options) {
	this.max = options.max || 1;
	this.maxUses = options.maxUses || 1;
	this.create = options.create || function () {};
	this.destroy = options.destroy || function () {};
	this.task = options.task || function () {};
	this.complete = options.complete || function () {};
	this.active = 0;
	this.resources = new Array(this.max);
	this.resourceActive = new Array(this.max);
	this.resourceUses = new Array(this.max);
	this.tasks = [];
}
ResourcePool.prototype.churn = function () {
	while (this.tasks.length && this.active < this.max) {
		var resource = this.get();
		var task = this.tasks.unshift();
		setImmediate(this.task.bind(this, task, resource));
	}
};
/**
 * Apply a new task to the queue
 *
 * @param {object[]} task
 *   Called when a "resource" becomes available to handle the task
 */
ResourcePool.prototype.enqueue = function (tasks) {
	this.tasks.push.apply(this.tasks, tasks);
	this.churn();
};
/**
 * Get a Resource from the pool of resources
 *   Create a new Resource if necessary
 *
 * @return {Resource|null}
 *   returns null if pool is full
 */
ResourcePool.prototype.get = function () {
	for (var i = 0; i < this.max; i++) {
		if (!this.resourceActive[i]) {
			if (!this.resources[i]) {
				this.resources[i] = this.create();
				this.resourceUses[i] = 0;
			}
			this.resourceActive[i] = true;
			this.resourceUses[i]++;
			this.active++;
			return this.resources[i];
		}
	}
	return null;
};
/**
 * Release a Resource back to the pool
 *   If a Resource has been used to the max, it is destroyed
 *
 * @param {Resource} resource
 *   The Resource to release back to the pool
 */
ResourcePool.prototype.release = function (resource) {
	for (var i = 0; i < this.max; i++) {
		if (this.resources[i] === resource) {
			if (this.resourceUses[i] >= this.maxUses) {
				resource.destroy();
				this.resources[i] = null;
				this.resourceUses[i] = 0;
			}
			this.resourceActive[i] = false;
			this.active--;
		}
	}
	if (this.tasks.length) {
		this.churn();
	}
	else if (this.active < 1) {
		this.drain();
		this.complete();
	}
};
/**
 * Destroy all resources
 */
ResourcePool.prototype.drain = function () {
	for (var i = 0; i < this.max; i++) {
		if (this.resources[i]) {
			this.destroy(this.resources[i]);
			this.resourceUses[i] = 0;
			this.resourceActive[i] = false;
		}
	}
	this.active = 0;
};

module.exports = ResourcePool;
<|endoftext|>


<commit_before>'use strict';

var fs = require('fs'),
    handlebars = require('handlebars'),
    bower = require('bower'),
    registry = require('./initRegistry');

var getRegistryList = function (request, result) {
    var templateFile = fs.readFileSync('viewRegistryList.hbs', 'utf-8');
    var hbTemplate = handlebars.compile(templateFile);

    var temp = [];
    for (var name in registry.packages) {
        //getDetailedPackageInfo(name);
        temp.push({
            name: name,
            url: registry.packages[name]
        });
    }
    var mustacheData = {
        bowerPackages : temp
    };

    result.send(hbTemplate(mustacheData));
};

var getDetailedPackageInfo = function (request, result) {
    console.log(request.params.name);
    bower.commands.info(request.params.name)
        .on('end', function (packageInfo) {
            console.log('Loaded details for : ' + request.params.name);
            console.log('pkgName: ' + packageInfo.name);
            console.log('versions: ' + packageInfo.versions);
            console.log('latestVersion: ' + packageInfo.versions[0]);
            console.log('dependencies: ' + packageInfo.latest.dependencies);
            console.log('devDependencies: ' + packageInfo.latest.devDependencies);
            result.send(packageInfo);
        });
};

exports.getRegistryList = getRegistryList;
exports.getDetailedPackageInfo = getDetailedPackageInfo;
<commit_msg>Package info now shows the dependencies and devDepencies<commit_after>'use strict';

var fs = require('fs'),
    handlebars = require('handlebars'),
    bower = require('bower'),
    registry = require('./initRegistry');

var getRegistryList = function (request, result) {
    var templateFile = fs.readFileSync('viewRegistryList.hbs', 'utf-8');
    var hbTemplate = handlebars.compile(templateFile);

    var temp = [];
    for (var name in registry.packages) {
        //getDetailedPackageInfo(name);
        temp.push({
            name: name,
            url: registry.packages[name]
        });
    }
    var mustacheData = {
        bowerPackages : temp
    };

    result.send(hbTemplate(mustacheData));
};

var getDetailedPackageInfo = function (request, result) {
    console.log(request.params.name);
    bower.commands.info(request.params.name)
        .on('end', function (packageInfo) {
            console.log('Loaded details for : ' + request.params.name);
            console.log('pkgName: ' + packageInfo.name);
            console.log('versions: ' + packageInfo.versions);
            console.log('latestVersion: ' + packageInfo.versions[0]);

            var flatDependencies = [];
            for (var dep in packageInfo.latest.dependencies) {
                flatDependencies.push(dep);
            }
            packageInfo.latest.dependencies = flatDependencies;
            console.log('dependencies: ' + packageInfo.latest.dependencies);

            var flatDevDependencies = [];
            for (var devDep in packageInfo.latest.devDependencies) {
                flatDevDependencies.push(devDep);
            }
            packageInfo.latest.devDependencies = flatDevDependencies;
            console.log('devDependencies: ' + packageInfo.latest.devDependencies);

            result.send(packageInfo);
        });
};

exports.getRegistryList = getRegistryList;
exports.getDetailedPackageInfo = getDetailedPackageInfo;
<|endoftext|>


<commit_before>'use strict';

const fetch = require('node-fetch');

const WorldstateObject = require('./WorldstateObject.js');

const bountyRewardRegex = /Tier(A|B|C|D|E)Table(A|B|C)Rewards/i;
const ghoulRewardRegex = /GhoulBountyTable(A|B)Rewards/i;

const determineLocation = (i18n) => {
  const last = String(i18n).split('/').slice(-1)[0];
  const bountyMatches = last.match(bountyRewardRegex);

  const isCetus = /eidolonjob/i.test(i18n);
  const isVallis = /venusjob/i.test(i18n);

  const ghoulMatches = last.match(ghoulRewardRegex);
  const tier = bountyMatches && bountyMatches.length
    ? bountyMatches[1]
    : ghoulMatches && ghoulMatches.length && ghoulMatches[1];
  const rotation = bountyMatches && bountyMatches.length ? bountyMatches[2] : '';
  let levelString = '';

  if (bountyMatches && bountyMatches.length) {
    switch (tier) {
      case 'A':
        levelString = '5 - 15';
        break;
      case 'B':
        levelString = '10 - 30';
        break;
      case 'C':
        levelString = '20 - 40';
        break;
      case 'D':
        levelString = '30 - 50';
        break;
      case 'E':
        levelString = '40 - 60';
        break;
      default:
        break;
    }
  } else {
    switch (tier) {
      case 'A':
        levelString = '15 - 25';
        break;
      case 'B':
        levelString = '40 - 50';
        break;
      default:
        break;
    }
  }
  let location;
  if (isCetus) {
    if (ghoulMatches && ghoulMatches.length) {
      location = `Earth/Cetus (Level ${levelString} Ghoul Bounty)`;
    } else {
      location = `Earth/Cetus (Level ${levelString} Bounty)`;
    }
  }
  if (isVallis) {
    location = `Orb Vallis/Venus (Level ${levelString} Bounty)`;
  }

  const locationWRot = rotation.length ? `${location}, Rot ${rotation}` : `${location}, Rot A`;
  return { location, locationWRot };
};

const getCetusBountyRewards = async (i18n) => {
  try {
    const { location, locationWRot } = determineLocation(i18n);
    const url = `https://api.warframestat.us/drops/search/${encodeURIComponent(location)}?grouped_by=location`;

    const reply = await fetch(url).then(res => res.json());
    const pool = reply[0][locationWRot];
    if (!pool) {
      return ['Pattern Mismatch. Results inaccurate.'];
    }
    const results = pool.rewards;
    if (results) {
      return Array.from(new Set(results.map(result => result.item)));
    }
  } catch (e) {
    // eslint-disable-next-line no-console
    console.error(e);
  }

  return [];
};

/**
 * Represents a syndicate daily mission
 * @extends {WorldstateObject}
 */
class SyndicateJob extends WorldstateObject {
  /**
   * @param   {Object}             data            The syndicate mission data
   * @param   {Date}               expiry          The syndicate job expiration
   * @param   {Object}             deps            The dependencies object
   * @param   {Translator}         deps.translator The string translator
   */
  constructor(data, expiry, { translator, timeDate }) {
    super({ _id: { $oid: `${data.jobType.split('/').slice(-1)[0]}${expiry.getTime()}` } }, { timeDate });

    /**
     * Array of strings describing rewards
     * @type {string}
     */
    this.rewardPool = '';
    getCetusBountyRewards(data.rewards)
      .then((rewards) => {
        this.rewardPool = rewards;
      });

    /**
     * The type of job this is
     * @type {String}
     */
    this.type = translator.languageString(data.jobType);

    /**
     * Array of enemy levels
     * @type {Array.<number>}
     */
    this.enemyLevels = [data.minEnemyLevel, data.maxEnemyLevel];

    /**
     * Array of standing gains per stage of job
     * @type {Array.<number>}
     */
    this.standingStages = data.xpAmounts;
  }
}

module.exports = SyndicateJob;
<commit_msg>Syndicate Job Fix<commit_after>'use strict';

const fetch = require('node-fetch');

const WorldstateObject = require('./WorldstateObject.js');

const bountyRewardRegex = /Tier(A|B|C|D|E)Table(A|B|C)Rewards/i;
const ghoulRewardRegex = /GhoulBountyTable(A|B)Rewards/i;

const determineLocation = (i18n) => {
  const last = String(i18n).split('/').slice(-1)[0];
  const bountyMatches = last.match(bountyRewardRegex);

  const isCetus = /eidolonjob/i.test(i18n);
  const isVallis = /venusjob/i.test(i18n);

  const ghoulMatches = last.match(ghoulRewardRegex);
  const tier = bountyMatches && bountyMatches.length
    ? bountyMatches[1]
    : ghoulMatches && ghoulMatches.length && ghoulMatches[1];
  const rotation = bountyMatches && bountyMatches.length ? bountyMatches[2] : '';
  let levelString = '';

  if (bountyMatches && bountyMatches.length) {
    switch (tier) {
      case 'A':
        levelString = '5 - 15';
        break;
      case 'B':
        levelString = '10 - 30';
        break;
      case 'C':
        levelString = '20 - 40';
        break;
      case 'D':
        levelString = '30 - 50';
        break;
      case 'E':
        levelString = '40 - 60';
        break;
      default:
        break;
    }
  } else {
    switch (tier) {
      case 'A':
        levelString = '15 - 25';
        break;
      case 'B':
        levelString = '40 - 50';
        break;
      default:
        break;
    }
  }
  let location;
  let levelClause;
  if (isCetus) {
    location = 'Earth/Cetus ';
    if (ghoulMatches && ghoulMatches.length) {
      levelClause = `(Level ${levelString} Ghoul Bounty)`;
    } else {
      levelClause = `(Level ${levelString} Cetus Bounty)`;
    }
  }
  if (isVallis) {
    location = `Orb Vallis/Venus (Level ${levelString} Solaris Bounty)`;
  }

  const locationWRot = `${location}${levelClause}, Rot ${rotation.length ? rotation : 'A'}`;
  return { location, locationWRot };
};

const getCetusBountyRewards = async (i18n) => {
  try {
    const { location, locationWRot } = determineLocation(i18n);
    const url = `https://api.warframestat.us/drops/search/${encodeURIComponent(location)}?grouped_by=location`;
    const reply = await fetch(url).then(res => res.json());
    const pool = reply[0][locationWRot];
    if (!pool) {
      return ['Pattern Mismatch. Results inaccurate.'];
    }
    const results = pool.rewards;
    if (results) {
      return Array.from(new Set(results.map(result => result.item)));
    }
  } catch (e) {
    // eslint-disable-next-line no-console
    console.error(e);
  }

  return [];
};

/**
 * Represents a syndicate daily mission
 * @extends {WorldstateObject}
 */
class SyndicateJob extends WorldstateObject {
  /**
   * @param   {Object}             data            The syndicate mission data
   * @param   {Date}               expiry          The syndicate job expiration
   * @param   {Object}             deps            The dependencies object
   * @param   {Translator}         deps.translator The string translator
   */
  constructor(data, expiry, { translator, timeDate }) {
    super({ _id: { $oid: `${data.jobType.split('/').slice(-1)[0]}${expiry.getTime()}` } }, { timeDate });

    /**
     * Array of strings describing rewards
     * @type {string}
     */
    this.rewardPool = '';
    getCetusBountyRewards(data.rewards)
      .then((rewards) => {
        this.rewardPool = rewards;
      });

    /**
     * The type of job this is
     * @type {String}
     */
    this.type = translator.languageString(data.jobType);

    /**
     * Array of enemy levels
     * @type {Array.<number>}
     */
    this.enemyLevels = [data.minEnemyLevel, data.maxEnemyLevel];

    /**
     * Array of standing gains per stage of job
     * @type {Array.<number>}
     */
    this.standingStages = data.xpAmounts;
  }
}

module.exports = SyndicateJob;
<|endoftext|>


<commit_before>// tokens.js
// 2009-05-17

// (c) 2006 Douglas Crockford

// Produce an array of simple token objects from a string.
// A simple token object contains these members:
//      type: 'name', 'string', 'number', 'symbol'
//      value: string or number value of the token
//      from: index of first character of the token
//      to: index of the last character + 1

// Comments of the // type are ignored.

// Operators are by default single characters. Multicharacter
// symbols can be made by supplying a string of prefix and
// suffix characters.
// characters. For example,
//      '<>+-&', '=>&:'
// will match any of these:
//      <=  >>  >>>  <>  >=  +: -: &: &&: &&

var fs = require('fs'),
    sys = require('sys'),
	util = require('./util')

exports.tokenize = util.intercept('TokenizeError', doTokenize)

var TokenizeError = function(file, line, column, msg) {
	this.name = 'TokenizeError';
	this.message = ['on line', line + ',', 'column', column, 'of', '"'+file+'":', msg].join(' ')
}
TokenizeError.prototype = Error.prototype

var keywords = ['import', 'let','for','in','if','else','template','handler']
function doTokenize (inputFile) {
    var c;                      // The current character.
    var from;                   // The index of the start of the token.
    var i = 0;                  // The index of the current character.
    var line = 1;               // The line of the current character.
    var lineStart = 0;          // The index at the beginning of the line
    var inputString;            // The string to tokenize
    var length;                 // The length of the input string
    var n;                      // The number value.
    var q;                      // The quote character.
    var str;                    // The string value.
    var prefix = '=<>';
    var suffix = '=';

    var result = [];            // An array to hold the results.

    var halt = function (msg) {
        var col = from - lineStart + 1
        sys.puts(util.grabLine(inputFile, line, col, i - from));
        throw new TokenizeError(inputFile, line, col, msg);
    }

    var make = function (type, value) {

// Make a token object.

        return {
            type: type,
            value: value,
            from: from,
            span: i - from,
            line: line,
            column: from - lineStart + 1,
            file: inputFile
        };
    };

// Allow for keyword lookup with "if (str in keywords) { ... }"

    for (var kWord, keyI=0; kWord = keywords[keyI]; keyI++) {
        keywords[kWord] = true;
    }

// Begin tokenization. If the source string is empty, return nothing.
    inputString = fs.readFileSync(inputFile).toString()
    length = inputString.length
    if (!length) {
        return;
    }

// If prefix and suffix strings are not provided, supply defaults.

    if (typeof prefix !== 'string') {
        prefix = '<>+-&';
    }
    if (typeof suffix !== 'string') {
        suffix = '=>&:';
    }

// Loop through this text, one character at a time.

    c = inputString.charAt(i);
    while (c) {
        from = i;

        if (c == '\n') {

// Keep track of the line number

            line += 1;
            i += 1;
            lineStart = i;
            c = inputString.charAt(i);

// Ignore whitespace.

        } else if (c <= ' ') {
            i += 1;
            c = inputString.charAt(i);

// name.

        } else if (c == '_' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
            str = c;
            i += 1;
            for (;;) {
                c = inputString.charAt(i);
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
                        (c >= '0' && c <= '9') || c === '_') {
                    str += c;
                    i += 1;
                } else {
                    break;
                }
            }
            result.push(make(str in keywords ? 'keyword' : 'name', str));

// number.

// A number cannot start with a decimal point. It must start with a digit,
// possibly '0'.

        } else if (c >= '0' && c <= '9') {
            str = c;
            i += 1;

// Look for more digits.

            for (;;) {
                c = inputString.charAt(i);
                if (c < '0' || c > '9') {
                    break;
                }
                i += 1;
                str += c;
            }

// Look for a decimal fraction part.

            if (c === '.') {
                i += 1;
                str += c;
                for (;;) {
                    c = inputString.charAt(i);
                    if (c < '0' || c > '9') {
                        break;
                    }
                    i += 1;
                    str += c;
                }
            }

// Look for an exponent part.

            if (c === 'e' || c === 'E') {
                i += 1;
                str += c;
                c = inputString.charAt(i);
                if (c === '-' || c === '+') {
                    i += 1;
                    str += c;
                    c = inputString.charAt(i);
                }
                if (c < '0' || c > '9') {
                    halt("Bad exponent");
                }
                do {
                    i += 1;
                    str += c;
                    c = inputString.charAt(i);
                } while (c >= '0' && c <= '9');
            }

// Make sure the next character is not a letter.

            if (c >= 'a' && c <= 'z') {
                str += c;
                i += 1;
                halt("Bad number - should not end in a letter");
            }

// Convert the string value to a number. If it is finite, then it is a good
// token.

            n = +str;
            if (isFinite(n)) {
                result.push(make('number', n));
            } else {
                halt("Bad number");
            }

// string

        } else if (c === '\'' || c === '"') {
            str = '';
            q = c;
            i += 1;
            for (;;) {
                c = inputString.charAt(i);
                if (c < ' ') {
                    halt(c === '\n' || c === '\r' || c === '' ?
                        "Unterminated string." :
                        "Control character in string.", make('', str));
                }

// Look for the closing quote.

                if (c === q) {
                    break;
                }

// Look for escapement.

                if (c === '\\') {
                    i += 1;
                    if (i >= length) {
                        halt("Unterminated string");
                    }
                    c = inputString.charAt(i);
                    switch (c) {
                    case 'b':
                        c = '\b';
                        break;
                    case 'f':
                        c = '\f';
                        break;
                    case 'n':
                        c = '\n';
                        break;
                    case 'r':
                        c = '\r';
                        break;
                    case 't':
                        c = '\t';
                        break;
                    case 'u':
                        if (i >= length) {
                            halt("Unterminated string");
                        }
                        c = parseInt(inputString.substr(i + 1, 4), 16);
                        if (!isFinite(c) || c < 0) {
                            halt("Unterminated string");
                        }
                        c = String.fromCharCode(c);
                        i += 4;
                        break;
                    }
                }
                str += c;
                i += 1;
            }
            i += 1;
            result.push(make('string', str));
            c = inputString.charAt(i);

// comment.

        } else if (c === '/' && inputString.charAt(i + 1) === '/') {
            i += 1;
            for (;;) {
                c = inputString.charAt(i);
                if (c === '\n' || c === '\r' || c === '') {
                    break;
                }
                i += 1;
            }

// combining

        } else if (prefix.indexOf(c) >= 0) {
            str = c;
            i += 1;
            while (i < length) {
                c = inputString.charAt(i);
                if (suffix.indexOf(c) < 0) {
                    break;
                }
                str += c;
                i += 1;
            }
            result.push(make('symbol', str));

// single-character symbol

        } else {
            i += 1;
            result.push(make('symbol', c));
            c = inputString.charAt(i);
        }
    }
    return result;
};
<commit_msg>The tokenizer was returning undefined on an empty input file - return an empty array instead by not returning early<commit_after>// tokens.js
// 2009-05-17

// (c) 2006 Douglas Crockford

// Produce an array of simple token objects from a string.
// A simple token object contains these members:
//      type: 'name', 'string', 'number', 'symbol'
//      value: string or number value of the token
//      from: index of first character of the token
//      to: index of the last character + 1

// Comments of the // type are ignored.

// Operators are by default single characters. Multicharacter
// symbols can be made by supplying a string of prefix and
// suffix characters.
// characters. For example,
//      '<>+-&', '=>&:'
// will match any of these:
//      <=  >>  >>>  <>  >=  +: -: &: &&: &&

var fs = require('fs'),
    sys = require('sys'),
	util = require('./util')

exports.tokenize = util.intercept('TokenizeError', doTokenize)

var TokenizeError = function(file, line, column, msg) {
	this.name = 'TokenizeError';
	this.message = ['on line', line + ',', 'column', column, 'of', '"'+file+'":', msg].join(' ')
}
TokenizeError.prototype = Error.prototype

var keywords = ['import', 'let','for','in','if','else','template','handler']
function doTokenize (inputFile) {
    var c;                      // The current character.
    var from;                   // The index of the start of the token.
    var i = 0;                  // The index of the current character.
    var line = 1;               // The line of the current character.
    var lineStart = 0;          // The index at the beginning of the line
    var inputString;            // The string to tokenize
    var length;                 // The length of the input string
    var n;                      // The number value.
    var q;                      // The quote character.
    var str;                    // The string value.
    var prefix = '=<>';
    var suffix = '=';

    var result = [];            // An array to hold the results.

    var halt = function (msg) {
        var col = from - lineStart + 1
        sys.puts(util.grabLine(inputFile, line, col, i - from));
        throw new TokenizeError(inputFile, line, col, msg);
    }

    var make = function (type, value) {

// Make a token object.

        return {
            type: type,
            value: value,
            from: from,
            span: i - from,
            line: line,
            column: from - lineStart + 1,
            file: inputFile
        };
    };

// Allow for keyword lookup with "if (str in keywords) { ... }"

    for (var kWord, keyI=0; kWord = keywords[keyI]; keyI++) {
        keywords[kWord] = true;
    }

// If prefix and suffix strings are not provided, supply defaults.

    if (typeof prefix !== 'string') {
        prefix = '<>+-&';
    }
    if (typeof suffix !== 'string') {
        suffix = '=>&:';
    }

// Loop through the text, one character at a time.

    inputString = fs.readFileSync(inputFile).toString()
    length = inputString.length

    c = inputString.charAt(i);
    while (c) {
        from = i;

        if (c == '\n') {

// Keep track of the line number

            line += 1;
            i += 1;
            lineStart = i;
            c = inputString.charAt(i);

// Ignore whitespace.

        } else if (c <= ' ') {
            i += 1;
            c = inputString.charAt(i);

// name.

        } else if (c == '_' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
            str = c;
            i += 1;
            for (;;) {
                c = inputString.charAt(i);
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
                        (c >= '0' && c <= '9') || c === '_') {
                    str += c;
                    i += 1;
                } else {
                    break;
                }
            }
            result.push(make(str in keywords ? 'keyword' : 'name', str));

// number.

// A number cannot start with a decimal point. It must start with a digit,
// possibly '0'.

        } else if (c >= '0' && c <= '9') {
            str = c;
            i += 1;

// Look for more digits.

            for (;;) {
                c = inputString.charAt(i);
                if (c < '0' || c > '9') {
                    break;
                }
                i += 1;
                str += c;
            }

// Look for a decimal fraction part.

            if (c === '.') {
                i += 1;
                str += c;
                for (;;) {
                    c = inputString.charAt(i);
                    if (c < '0' || c > '9') {
                        break;
                    }
                    i += 1;
                    str += c;
                }
            }

// Look for an exponent part.

            if (c === 'e' || c === 'E') {
                i += 1;
                str += c;
                c = inputString.charAt(i);
                if (c === '-' || c === '+') {
                    i += 1;
                    str += c;
                    c = inputString.charAt(i);
                }
                if (c < '0' || c > '9') {
                    halt("Bad exponent");
                }
                do {
                    i += 1;
                    str += c;
                    c = inputString.charAt(i);
                } while (c >= '0' && c <= '9');
            }

// Make sure the next character is not a letter.

            if (c >= 'a' && c <= 'z') {
                str += c;
                i += 1;
                halt("Bad number - should not end in a letter");
            }

// Convert the string value to a number. If it is finite, then it is a good
// token.

            n = +str;
            if (isFinite(n)) {
                result.push(make('number', n));
            } else {
                halt("Bad number");
            }

// string

        } else if (c === '\'' || c === '"') {
            str = '';
            q = c;
            i += 1;
            for (;;) {
                c = inputString.charAt(i);
                if (c < ' ') {
                    halt(c === '\n' || c === '\r' || c === '' ?
                        "Unterminated string." :
                        "Control character in string.", make('', str));
                }

// Look for the closing quote.

                if (c === q) {
                    break;
                }

// Look for escapement.

                if (c === '\\') {
                    i += 1;
                    if (i >= length) {
                        halt("Unterminated string");
                    }
                    c = inputString.charAt(i);
                    switch (c) {
                    case 'b':
                        c = '\b';
                        break;
                    case 'f':
                        c = '\f';
                        break;
                    case 'n':
                        c = '\n';
                        break;
                    case 'r':
                        c = '\r';
                        break;
                    case 't':
                        c = '\t';
                        break;
                    case 'u':
                        if (i >= length) {
                            halt("Unterminated string");
                        }
                        c = parseInt(inputString.substr(i + 1, 4), 16);
                        if (!isFinite(c) || c < 0) {
                            halt("Unterminated string");
                        }
                        c = String.fromCharCode(c);
                        i += 4;
                        break;
                    }
                }
                str += c;
                i += 1;
            }
            i += 1;
            result.push(make('string', str));
            c = inputString.charAt(i);

// comment.

        } else if (c === '/' && inputString.charAt(i + 1) === '/') {
            i += 1;
            for (;;) {
                c = inputString.charAt(i);
                if (c === '\n' || c === '\r' || c === '') {
                    break;
                }
                i += 1;
            }

// combining

        } else if (prefix.indexOf(c) >= 0) {
            str = c;
            i += 1;
            while (i < length) {
                c = inputString.charAt(i);
                if (suffix.indexOf(c) < 0) {
                    break;
                }
                str += c;
                i += 1;
            }
            result.push(make('symbol', str));

// single-character symbol

        } else {
            i += 1;
            result.push(make('symbol', c));
            c = inputString.charAt(i);
        }
    }
    return result;
};
<|endoftext|>


<commit_before>module.exports = (settings) => `
{
  "name": "${settings.slug}",
  "version": "0.1.0",
  "description": "${settings.title}",
  "private": true,
  "scripts": {
    "start": "func() { fdk url-config && webpack --watch --mode=development --env.fdk_project=\\"\${1:-project}\\"; }; func",
    "build": "func() { fdk url-config && webpack --mode=production --env.fdk_project=\\"\${1:-project}\\"; }; func",
    "dc": "docker-compose",
    "sh": "docker-compose exec -u www-data wp /bin/bash",
    "shroot": "docker-compose exec wp /bin/bash",
    "wp": "docker-compose exec -u www-data -T wp wp",
    "logs": "docker-compose logs -f --tail='46' wp | sed -e \\"s/ WARNING: .* into stderr: \\\\\\"\\\\(NOTICE: PHP message: \\\\)\\\\{0,1\\\\}\\\\(\\\\[[a-zA-Z0-9 :\\\\-]\\\\{1,\\\\}\\\\]\\\\)\\\\{0,1\\\\} \\\\{0,1\\\\}\\\\(.*\\\\)\\\\\\"/ ⚠  $(tput setaf 3)\\\\3$(tput sgr0)/\\"",
    "remove": "docker-compose down --volumes --rmi local"
  },
  "fabrica_dev_kit": {
    "scripts_info": {
      "run": "Run 'gulp'. Default task will watch and process source files.",
      "dc": "Run 'docker-compose', eg. 'fdk dc ps'.",
      "sh": "Start shell on WP container.",
      "shroot": "Start shell as root on WP container.",
      "wp": "Run WP Cli. eg. 'fdk wp option list' or 'fdk wp -- --info'",
      "logs": "Tail WP container logs.",
      "remove": "Stop all project containers, remove their volumes and WP project image."
    }
  },
  "devDependencies": {
    "copy-webpack-plugin": "^5.1.1",
    "del": "^5.1.0",
    "glob": "^7.1.6",
    "js-yaml": "^3.13.1",
    "webpack": "^4.41.5",
    "webpack-cli": "^3.3.10"
  }
}
`;<commit_msg>change default projects/resources file name<commit_after>module.exports = (settings) => `
{
  "name": "${settings.slug}",
  "version": "0.1.0",
  "description": "${settings.title}",
  "private": true,
  "scripts": {
    "start": "func() { fdk url-config && webpack --watch --mode=development --env.fdk_project=\\"\${1:-index}\\"; }; func",
    "build": "func() { fdk url-config && webpack --mode=production --env.fdk_project=\\"\${1:-index}\\"; }; func",
    "dc": "docker-compose",
    "sh": "docker-compose exec -u www-data wp /bin/bash",
    "shroot": "docker-compose exec wp /bin/bash",
    "wp": "docker-compose exec -u www-data -T wp wp",
    "logs": "docker-compose logs -f --tail='46' wp | sed -e \\"s/ WARNING: .* into stderr: \\\\\\"\\\\(NOTICE: PHP message: \\\\)\\\\{0,1\\\\}\\\\(\\\\[[a-zA-Z0-9 :\\\\-]\\\\{1,\\\\}\\\\]\\\\)\\\\{0,1\\\\} \\\\{0,1\\\\}\\\\(.*\\\\)\\\\\\"/ ⚠  $(tput setaf 3)\\\\3$(tput sgr0)/\\"",
    "remove": "docker-compose down --volumes --rmi local"
  },
  "fabrica_dev_kit": {
    "scripts_info": {
      "run": "Run 'gulp'. Default task will watch and process source files.",
      "dc": "Run 'docker-compose', eg. 'fdk dc ps'.",
      "sh": "Start shell on WP container.",
      "shroot": "Start shell as root on WP container.",
      "wp": "Run WP Cli. eg. 'fdk wp option list' or 'fdk wp -- --info'",
      "logs": "Tail WP container logs.",
      "remove": "Stop all project containers, remove their volumes and WP project image."
    }
  },
  "devDependencies": {
    "copy-webpack-plugin": "^5.1.1",
    "del": "^5.1.0",
    "glob": "^7.1.6",
    "js-yaml": "^3.13.1",
    "webpack": "^4.41.5",
    "webpack-cli": "^3.3.10"
  }
}
`;<|endoftext|>


<commit_before>import xmldoc from 'xmldoc';

const instrumentsFromMusicXml = partList => {
  return partList.children.map(part => {
    // TODO handle instruments better, defaulting to acoustic guitar
    return 'acoustic_guitar_steel';
    //return part.childNamed('score-instrument').children[0].val.replace('Steel String Guitar', 'acoustic_guitar_steel');
  });
};

const getTuning = (part, maker) => {
  const staff = part.childNamed('measure').childNamed('attributes').childNamed('staff-details');

  return staff.children.slice(1).map(string => {
    const note = string.children[0].val;
    const octave = parseInt(string.children[1].val);
    return (`${note}${maker === 'TuxGuitar' ? octave - 1 : octave}`).toLowerCase();
  });
};

const getBpmForMeasure = (measures, measure, index) => {
  const direction = measure.childNamed('direction');
  if(direction) {
    return parseInt(direction.childNamed('sound').attr.tempo);
  } else {
    return measures[index - 1].bpm ? measures[index - 1].bpm : 120;
  }
};

const getTimeSignatureForMeasure = (measures, measure, index) => {
  const attributes = measure.childNamed('attributes');
  if(attributes) {
    const time = attributes.childNamed('time');
    if(time) {
      const beats = time.childNamed('beats').val;
      const beatType = time.childNamed('beat-type').val;
      return `${beats}/${beatType}`;
    }
  }

  return measures[index - 1].timeSignature ? measures[index - 1].timeSignature : '6/8';
};

const getNotesForMeasure = notes => {
  return notes.reduce((finalNotes, note) => {
    const duration = note.childNamed('type').val.substring(0, 1);
    const dotted = note.childNamed('dot') ? true : false;
    const isChord = note.childNamed('chord') ? true : false;

    const fret = parseInt(note.childNamed('notations').childNamed('technical').childNamed('fret').val);
    const string = 6 - parseInt(note.childNamed('notations').childNamed('technical').childNamed('string').val);

    let frets, strings;
    if(isChord) {
      frets = finalNotes[finalNotes.length - 1].fret.concat(fret);
      strings = finalNotes[finalNotes.length - 1].string.concat(string);

      return finalNotes.slice(0, finalNotes.length - 1).concat({
        duration,
        fret: frets,
        string: strings,
        dotted
      });
    }

    frets = [fret];
    strings = [string];

    return finalNotes.concat({
      duration,
      fret: frets,
      string: strings,
      dotted
    });
  }, []);
};

const measuresFromMusicXml = (measures) => {
  return measures.reduce((finalMeasures, measure, i) => {
    const bpm = getBpmForMeasure(finalMeasures, measure, i);
    const timeSignature = getTimeSignatureForMeasure(finalMeasures, measure, i);
    const notes = getNotesForMeasure(measure.childrenNamed('note'));

   return finalMeasures.concat({
     bpm,
     timeSignature,
     notes
   });
 }, []);
};

export function importMusicXml(xmlString) {
  const xml = new xmldoc.XmlDocument(xmlString);
  const parts = xml.childrenNamed('part');

  const instruments = instrumentsFromMusicXml(xml.childNamed('part-list'));
  const maker = xml.childNamed('identification').childNamed('encoding').childNamed('software').val;

  return parts.reduce((finalParts, part, i) => {
    const instrument = instruments[i];
    const tuning = getTuning(part, maker);
    const measures = measuresFromMusicXml(part.childrenNamed('measure'));

    return finalParts.concat({
      instrument,
      tuning,
      measures
    });
  }, []);
}
<commit_msg>support instruments with different string counts when importing MusicXML<commit_after>import xmldoc from 'xmldoc';

const instrumentsFromMusicXml = partList => {
  return partList.children.map(part => {
    // TODO handle instruments better, defaulting to acoustic guitar
    return 'acoustic_guitar_steel';
    //return part.childNamed('score-instrument').children[0].val.replace('Steel String Guitar', 'acoustic_guitar_steel');
  });
};

const getTuning = (part, maker) => {
  const staff = part.childNamed('measure').childNamed('attributes').childNamed('staff-details');

  return staff.children.slice(1).map(string => {
    const note = string.children[0].val;
    const octave = parseInt(string.children[1].val);
    return (`${note}${maker === 'TuxGuitar' ? octave - 1 : octave}`).toLowerCase();
  });
};

const getBpmForMeasure = (measures, measure, index) => {
  const direction = measure.childNamed('direction');
  if(direction) {
    return parseInt(direction.childNamed('sound').attr.tempo);
  } else {
    return measures[index - 1].bpm ? measures[index - 1].bpm : 120;
  }
};

const getTimeSignatureForMeasure = (measures, measure, index) => {
  const attributes = measure.childNamed('attributes');
  if(attributes) {
    const time = attributes.childNamed('time');
    if(time) {
      const beats = time.childNamed('beats').val;
      const beatType = time.childNamed('beat-type').val;
      return `${beats}/${beatType}`;
    }
  }

  return measures[index - 1].timeSignature ? measures[index - 1].timeSignature : '6/8';
};

const getNotesForMeasure = (notes, stringCount) => {
  return notes.reduce((finalNotes, note) => {
    const duration = note.childNamed('type').val.substring(0, 1);
    const dotted = note.childNamed('dot') ? true : false;
    const isChord = note.childNamed('chord') ? true : false;

    const fret = parseInt(note.childNamed('notations').childNamed('technical').childNamed('fret').val);
    const string = stringCount - parseInt(note.childNamed('notations').childNamed('technical').childNamed('string').val);

    let frets, strings;
    if(isChord) {
      frets = finalNotes[finalNotes.length - 1].fret.concat(fret);
      strings = finalNotes[finalNotes.length - 1].string.concat(string);

      return finalNotes.slice(0, finalNotes.length - 1).concat({
        duration,
        fret: frets,
        string: strings,
        dotted
      });
    }

    frets = [fret];
    strings = [string];

    return finalNotes.concat({
      duration,
      fret: frets,
      string: strings,
      dotted
    });
  }, []);
};

const measuresFromMusicXml = (measures, stringCount) => {
  return measures.reduce((finalMeasures, measure, i) => {
    const bpm = getBpmForMeasure(finalMeasures, measure, i);
    const timeSignature = getTimeSignatureForMeasure(finalMeasures, measure, i);
    const notes = getNotesForMeasure(measure.childrenNamed('note'), stringCount);

   return finalMeasures.concat({
     bpm,
     timeSignature,
     notes
   });
 }, []);
};

export function importMusicXml(xmlString) {
  const xml = new xmldoc.XmlDocument(xmlString);
  const parts = xml.childrenNamed('part');

  const instruments = instrumentsFromMusicXml(xml.childNamed('part-list'));
  const maker = xml.childNamed('identification').childNamed('encoding').childNamed('software').val;

  return parts.reduce((finalParts, part, i) => {
    const instrument = instruments[i];
    const tuning = getTuning(part, maker);
    const measures = measuresFromMusicXml(part.childrenNamed('measure'), tuning.length);

    return finalParts.concat({
      instrument,
      tuning,
      measures
    });
  }, []);
}
<|endoftext|>


<commit_before>import StorageAccess from './StorageAccess';

let DataStorage = {

    MemoryData: null,

    getActivities: () => {
        if (!DataStorage.MemoryData) {
            DataStorage.MemoryData = StorageAccess.loadActivities();
        }

        return DataStorage.MemoryData;
    },

    addActivity: (activity) => {
        let data = DataStorage.getActivities();
        data.push(activity);
        saveActivities();
    },

    saveActivities: () => {
        StorageAccess.saveActivities(DataStorage.getActivities());
    }
};

export default DataStorage;<commit_msg>fix storage<commit_after>import StorageAccess from './StorageAccess';

let DataStorage = {

    MemoryData: null,

    getActivities: () => {
        if (!DataStorage.MemoryData) {
            DataStorage.MemoryData = StorageAccess.loadActivities();
        }

        return DataStorage.MemoryData;
    },

    addActivity: (activity) => {
        let data = DataStorage.getActivities();
        data.push(activity);
        DataStorage.saveActivities();
    },

    saveActivities: () => {
        StorageAccess.saveActivities(DataStorage.getActivities());
    }
};

export default DataStorage;<|endoftext|>


<commit_before>'use strict';

var request = require('request');
var _ = require('lodash');

/**
 * What3Words API wrapper for the API version 2.0.
 *
 * @param options Configuration options
 * @return Instance of {@link Geocoder}
 */
function Geocoder(options) {
    if (!options) {
        options = {};
    }

    if (!options.apiKey) {
        throw new Error('API Key not set');
    }

    this.version = '1.0';
    this.apiKey = options.apiKey;
    this.endpoint = options.endpoint || 'https://api.what3words.com/v2/';
    this.language = options.language || 'en';
    this.userAgent = options.userAgent || 'JS Geo::Geocoder';
}

module.exports = Geocoder;

/**
 * Convert GPS co-ordinates into 3 words.
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * coords: a string containing lat,long
 */
Geocoder.prototype.reverse = function(options) {
    options.lang = options.lang || this.language;
    options.coords = options.position ||  options.coords; // backwards compatibility

    return new Promise(_.bind(function(resolve, reject) {
        if (!this.validateLatLng(options.coords)) {
            reject({
                error: 301,
                message: "Invalid or non-existent coordinates."
            });
        }

        this.execute('reverse', options)
            .then(function(res) {
                if (!options.full || options.format.toLowerCase() === 'json') {
                    resolve(res.words);
                } else {
                    resolve(res);
                }
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

// Backwards compatibility
Geocoder.prototype.positionToWords = function(options) {
    return this.reverse(options);
};

/**
 * Convert 3 words or a OneWord into GPS coordinates
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * addr: a string containing 3 dot separated words
 */
Geocoder.prototype.forward = function(options) {
    options.lang = options.lang || this.language;
    options.addr = options.words ||  options.addr; // backwards compatibility

    return new Promise(_.bind(function(resolve, reject) {

        if (!this.validateWord(options.addr)) {
            reject({
                error: 300,
                message: "Invalid or non-existent 3 word address."
            });
        }

        this.execute('forward', options)
            .then(function(res) {
                if (!options.full || options.format.toLowerCase() === 'json') {
                    resolve(res.geometry.lat + ',' + res.geometry.lng);
                } else {
                    resolve(res);
                }
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

// Backwards compatibility
Geocoder.prototype.wordsToPosition = function(options) {
    return this.forward(options);
};

/**
 * Returns a list of 3 word addresses based on user input and other parameters.
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * addr: a string containing 3 dot separated words
 */
Geocoder.prototype.autosuggest = function(options) {
    options.lang = options.lang || this.language;

    return new Promise(_.bind(function(resolve, reject) {
        if (!options.addr) {
            reject({
                code: 400,
                msg: "\/autosuggest: missing required parameter"
            });
        }

        this.execute('autosuggest', options)
            .then(function(res) {
                resolve(res);
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

/**
 * Returns a blend of the three most relevant 3 word address candidates for a given location,
 * based on a full or partial 3 word address.
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * addr: a string containing 3 dot separated words
 */
Geocoder.prototype.standardBlend = function(options) {
    options.lang = options.lang || this.language;

    return new Promise(_.bind(function(resolve, reject) {
        if (!options.addr) {
            reject({
                code: 400,
                msg: "\/autosuggest: missing required parameter"
            });
        }

        this.execute('standardblend', options)
            .then(function(res) {
                resolve(res);
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

/**
 * Returns a section of the 3m x 3m what3words grid for a given area.
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * addr: a string containing 3 dot separated words
 */
Geocoder.prototype.grid = function(options) {
    options.lang = options.lang || this.language;

    return new Promise(_.bind(function(resolve, reject) {
        if (!options.bbox) {
            reject({
                code: 400,
                msg: "\/autosuggest: missing required parameter"
            });
        }

        this.execute('grid', options)
            .then(function(res) {
                resolve(res);
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

/**
 * Returns a list of the W3W available languages
 * @param  {[object]}   options  Can contain the following properties:
 *          * full: Return the full response
 */
Geocoder.prototype.getLanguages = function(options) {
    return new Promise(_.bind(function(resolve, reject) {
        this.execute('languages', options)
            .then(function(res) {
                if (options.full) {
                    resolve(res);
                } else {
                    resolve(_.pluck(res.languages, 'code'));
                }
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

/**
 *  Validations
 */
Geocoder.prototype.validateWord = function(word) {
    return word.match(/^\w+\.\w+\.\w+$/);
};

Geocoder.prototype.validateLatLng = function(latlng) {
    var coordinates = latlng.split(',');
    if (coordinates.length === 2) {
        var lat = Number(coordinates[0]),
            lng = Number(coordinates[1]);
        if ((lng > -180 && lng < 180) && (lat > -90 && lat < 90)) {
            return true;
        }
    }
    return;
};

/**
 * Getters
 */
Geocoder.prototype.getLanguage = function() {
    return this.language;
};

Geocoder.prototype.getUserAgent = function() {
    return this.userAgent;
};

Geocoder.prototype.getEndpoint = function() {
    return this.endpoint;
};

/**
 * Sends a given request as a JSON object to the W3W API and returns
 * a promise which if resolved will contain the resulting JSON object.
 *
 * @param  {[type]}   method   W3W API method to call
 * @param  {[type]}   params   Object containg parameters to call the API with
 * @param  {Function} Promise
 */
Geocoder.prototype.execute = function(method, params) {
    return new Promise(_.bind(function(resolve, reject) {
        var finalParams = _.extend({
            key: this.apiKey
        }, params);

        var options = {
            url: this.endpoint + method,
            qs: finalParams
        };

        request.get(options, function(error, response, body) {
            if (error) {
                reject({
                    code: 404,
                    msg: error
                });
            } else {
                if (response.statusCode !== 200) {
                    reject({
                        code: response.statusCode,
                        msg: 'Unable to connect to the API endpoint ' + options.url
                    });
                } else if (response.body.error) {
                    reject(response.body);
                }
                if (body) {
                    if (params.format && params.format.toLowerCase() !== 'json') {
                        resolve(response.body);
                    } else {
                        resolve(JSON.parse(response.body));
                    }
                }
            }
        });
    }, this));
};
<commit_msg>wrapper version updated to v2<commit_after>'use strict';

var request = require('request');
var _ = require('lodash');

/**
 * What3Words API wrapper for the API version 2.0.
 *
 * @param options Configuration options
 * @return Instance of {@link Geocoder}
 */
function Geocoder(options) {
    if (!options) {
        options = {};
    }

    if (!options.apiKey) {
        throw new Error('API Key not set');
    }

    this.version = '2.0';
    this.apiKey = options.apiKey;
    this.endpoint = options.endpoint || 'https://api.what3words.com/v2/';
    this.language = options.language || 'en';
    this.userAgent = options.userAgent || 'JS Geo::Geocoder';
}

module.exports = Geocoder;

/**
 * Convert GPS co-ordinates into 3 words.
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * coords: a string containing lat,long
 */
Geocoder.prototype.reverse = function(options) {
    options.lang = options.lang || this.language;
    options.coords = options.position ||  options.coords; // backwards compatibility

    return new Promise(_.bind(function(resolve, reject) {
        if (!this.validateLatLng(options.coords)) {
            reject({
                error: 301,
                message: "Invalid or non-existent coordinates."
            });
        }

        this.execute('reverse', options)
            .then(function(res) {
                if (!options.full || options.format.toLowerCase() === 'json') {
                    resolve(res.words);
                } else {
                    resolve(res);
                }
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

// Backwards compatibility
Geocoder.prototype.positionToWords = function(options) {
    return this.reverse(options);
};

/**
 * Convert 3 words or a OneWord into GPS coordinates
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * addr: a string containing 3 dot separated words
 */
Geocoder.prototype.forward = function(options) {
    options.lang = options.lang || this.language;
    options.addr = options.words ||  options.addr; // backwards compatibility

    return new Promise(_.bind(function(resolve, reject) {

        if (!this.validateWord(options.addr)) {
            reject({
                error: 300,
                message: "Invalid or non-existent 3 word address."
            });
        }

        this.execute('forward', options)
            .then(function(res) {
                if (!options.full || options.format.toLowerCase() === 'json') {
                    resolve(res.geometry.lat + ',' + res.geometry.lng);
                } else {
                    resolve(res);
                }
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

// Backwards compatibility
Geocoder.prototype.wordsToPosition = function(options) {
    return this.forward(options);
};

/**
 * Returns a list of 3 word addresses based on user input and other parameters.
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * addr: a string containing 3 dot separated words
 */
Geocoder.prototype.autosuggest = function(options) {
    options.lang = options.lang || this.language;

    return new Promise(_.bind(function(resolve, reject) {
        if (!options.addr) {
            reject({
                code: 400,
                msg: "\/autosuggest: missing required parameter"
            });
        }

        this.execute('autosuggest', options)
            .then(function(res) {
                resolve(res);
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

/**
 * Returns a blend of the three most relevant 3 word address candidates for a given location,
 * based on a full or partial 3 word address.
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * addr: a string containing 3 dot separated words
 */
Geocoder.prototype.standardBlend = function(options) {
    options.lang = options.lang || this.language;

    return new Promise(_.bind(function(resolve, reject) {
        if (!options.addr) {
            reject({
                code: 400,
                msg: "\/autosuggest: missing required parameter"
            });
        }

        this.execute('standardblend', options)
            .then(function(res) {
                resolve(res);
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

/**
 * Returns a section of the 3m x 3m what3words grid for a given area.
 * @param  {[object]}   options  Can contain the following properties:
 *          * lang: alternative language, default will be usef if this is not declared.
 *          * addr: a string containing 3 dot separated words
 */
Geocoder.prototype.grid = function(options) {
    options.lang = options.lang || this.language;

    return new Promise(_.bind(function(resolve, reject) {
        if (!options.bbox) {
            reject({
                code: 400,
                msg: "\/autosuggest: missing required parameter"
            });
        }

        this.execute('grid', options)
            .then(function(res) {
                resolve(res);
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

/**
 * Returns a list of the W3W available languages
 * @param  {[object]}   options  Can contain the following properties:
 *          * full: Return the full response
 */
Geocoder.prototype.getLanguages = function(options) {
    return new Promise(_.bind(function(resolve, reject) {
        this.execute('languages', options)
            .then(function(res) {
                if (options.full) {
                    resolve(res);
                } else {
                    resolve(_.pluck(res.languages, 'code'));
                }
            })
            .catch(function(err) {
                reject(err);
            });
    }, this));
};

/**
 *  Validations
 */
Geocoder.prototype.validateWord = function(word) {
    return word.match(/^\w+\.\w+\.\w+$/);
};

Geocoder.prototype.validateLatLng = function(latlng) {
    var coordinates = latlng.split(',');
    if (coordinates.length === 2) {
        var lat = Number(coordinates[0]),
            lng = Number(coordinates[1]);
        if ((lng > -180 && lng < 180) && (lat > -90 && lat < 90)) {
            return true;
        }
    }
    return;
};

/**
 * Getters
 */
Geocoder.prototype.getLanguage = function() {
    return this.language;
};

Geocoder.prototype.getUserAgent = function() {
    return this.userAgent;
};

Geocoder.prototype.getEndpoint = function() {
    return this.endpoint;
};

/**
 * Sends a given request as a JSON object to the W3W API and returns
 * a promise which if resolved will contain the resulting JSON object.
 *
 * @param  {[type]}   method   W3W API method to call
 * @param  {[type]}   params   Object containg parameters to call the API with
 * @param  {Function} Promise
 */
Geocoder.prototype.execute = function(method, params) {
    return new Promise(_.bind(function(resolve, reject) {
        var finalParams = _.extend({
            key: this.apiKey
        }, params);

        var options = {
            url: this.endpoint + method,
            qs: finalParams
        };

        request.get(options, function(error, response, body) {
            if (error) {
                reject({
                    code: 404,
                    msg: error
                });
            } else {
                if (response.statusCode !== 200) {
                    reject({
                        code: response.statusCode,
                        msg: 'Unable to connect to the API endpoint ' + options.url
                    });
                } else if (response.body.error) {
                    reject(response.body);
                }
                if (body) {
                    if (params.format && params.format.toLowerCase() !== 'json') {
                        resolve(response.body);
                    } else {
                        resolve(JSON.parse(response.body));
                    }
                }
            }
        });
    }, this));
};
<|endoftext|>


<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Jarid Margolin @jaridmargolin
*/
"use strict";

module.exports = class WebpackError extends Error {
	inspect() {
		return this.stack + (this.details ? `\n${this.details}` : "");
	}
};
<commit_msg>Refactor WebpackError to initialize details as undefined<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Jarid Margolin @jaridmargolin
*/
"use strict";

module.exports = class WebpackError extends Error {
	constructor(message) {
		super(message);
		this.name = 'WebpackError';
		this.message = message;
		Error.captureStackTrace(this, this.constructor);

		/** @type {string} */
		this.details = undefined;
	}

	inspect() {
		return this.stack + (this.details ? `\n${this.details}` : "");
	}
};
<|endoftext|>