<commit_before>var Promise = require('rsvp').Promise;
var asp = require('rsvp').denodeify;
var fs = require('graceful-fs');
var exec = require('child_process').exec;
var semver = require('semver');
var path = require('path');
var rimraf = require('rimraf');
// var P4rc = require('./p4rc.js');

function clone(a) {
  var b = {};
  for (var p in a) {
    if (a[p] instanceof Array)
      b[p] = [].concat(a[p]);
    else if (typeof a[p] == 'object')
      b[p] = clone(a[p]);
    else
      b[p] = a[p];
  }
  return b;
}

/**
* Create a Perforce registry
* @param {object} options Options from jspm (config?). Can contain any other registry-specific config.
* @param {string} options.tmpDir Path to a folder the registry can use to store temporary files. This folder persists and is shared between installs.
* @param {string} options.versionString Represents the minor and major version of the registry package, which is used in the caching hash of packages. This can be altered and written to the instance allowing for custom registry cache invalidation - `this.versionString = options.versionString + '.53'``.
* @param {object} ui      Accessing the ui (console)
*/
var P4Registry = module.exports = function P4Registry(options, ui) {
    this.ui = ui;
    this.registryPath = options.tmpDir;
    this.registryUpdated = false;
    this.repo = options.repo || defaultRepo;

    this.execOptions = {
      cwd: options.tmpDir,
      timeout: options.timeout * 1000,
      killSignal: 'SIGKILL'
    };
};

P4Registry.prototype = {
    // /**
    // * Given a package name, locate it and ensure it exists.
    // * @param  {string} packageName Name of the package
    // * @return {Promise}  Promise { notfound: true } | { redirect: 'new:package' } / undefined
    // */
    // locate: function(packageName) {
    //     // packageName = 'owner/repo'
    //     var root = this.root;
    //
    //     if (repo.split('/').length !== 2) {
    //         throw new Error("Perforce packages must be organized in the form of `owner(team)/repo`.");
    //     }
    //
    //     return new Promise(function(resolve, reject) {
    //         var stat = fs.statSync(root + "/" + packageName);
    //         if (stat.isDirectory()) {
    //             resolve()
    //         }
    //         else {
    //             resolve({ notfound: true});
    //         }
    //     });
    // },
    lookup: function(packageName) {
        var root = this.root;

        if (repo.split('/').length !== 2) {
            throw new Error("Perforce packages must be organized in the form of `owner(team)/repo`.");
        }

        return new Promise(function (resolve, reject) {
            var stat = fs.statSync(root + "/" + packageName);
            if (stat.isDirectory()) {
                resolve()
            }
            else {
                resolve({ notfound: true});
            }
        });
    },
    download: function(packageName, version, hash, meta, dir) {
        return Promise.resolve({ notfound: true});
    },
    parse: function parse(name) {
        var parts = name.split('/');
        if (parts.length !== 2) {
            throw new Error("Perforce packages must be organized in the form of `owner(team)/repo`.");
        }

        return {
            package: parts[0],
            path: parts.splice(1).join('/')
        };
    },
    updateRegistry: function updateRegistry() {
        if (this.updatePromise_)
        return Promise.resolve(this.updatePromise_);

        var ui = this.ui;
        var registryPath = this.registryPath;
        var remoteString = this.repo;
        var execOptions = this.execOptions;
        var self = this;

        return this.updatePromise_ = asp(exec)('git remote show origin -n', execOptions)
        .then(function(output) {
            output = output.toString();

            var curRepoMatch = output.match(/Fetch URL: ([^\n]+)/m);

            if (!curRepoMatch || curRepoMatch[1] != self.repo)
            return self.createRegistry();

            // if the registry does exist, update it
            ui.log('info', 'Updating registry cache...');
            return asp(exec)('git fetch --all && git reset --hard origin/master', execOptions)
            .then(function(stdout, stderr) {
                if (stderr)
                throw stderr;
            })
            .catch(function(err) {
                if (typeof err == 'string') {
                    err = new Error(err);
                    err.hideStack = true;
                }
                err.retriable = true;
                throw err;
            });
        }, function(err) {
            err = err.toString();

            // if the registry does not exist, do a git clone
            if (err.indexOf('Not a git repo') != -1)
            return self.createRegistry();
        })
        .then(function() {
            return asp(fs.readFile)(path.resolve(registryPath, 'registry.json'))
            .then(function(pjson) {
                try {
                    return JSON.parse(pjson);
                }
                catch(e) {
                    return {};
                }
            }, function(err) {
                if (err.code === 'ENOENT')
                return {};
                ui.log('warn', 'Registry file is invalid.');
            });
        })
        .then(function(json) {
            return json;
        });
    }
};

P4Location.configure = function(config, ui) {
    config.remote = config.remote || '../';

    // var npmrc = new Npmrc();
    // var npmrcAuth;

    var registry;

    return Promise.resolve()
    .then(function() {
        var customMsg;
        if (config.registry)
        customMsg = 'a custom registry and credentials';
        else if (config.registry)
        customMsg = 'a custom registry';
        else if (config.auth || config.authToken)
        customMsg = 'custom credentials';

        if (customMsg)
        return ui.confirm('Currently using ' + customMsg + '. Would you like to reset to npmrc defaults?', false);
    })
    .then(function(reset) {
        if (reset) {
            delete config.registry;
            delete config.auth;
            delete config.authToken;
        }
        return ui.input('npm registry', config.registry || npmrc.getRegistry() || defaultRegistry);
    })
    .then(function(_registry) {
        registry = _registry;
        if (registry != (npmrc.getRegistry() || defaultRegistry))
        config.registry = registry.replace(/\/$/, '');

        npmrcAuth = npmrc.getAuth(config.registry);

        if (config.auth || config.authToken)
        return ui.confirm('Custom authentication currently configured, reconfigure credentials?', false);
        else if (npmrcAuth)
        return ui.confirm('Currently reading credentials from npmrc, configure custom authentication?', false);
        else
        return ui.confirm('No authentication configured, configure credentials?', false);
    })
    .then(function(doAuth) {
        if (!doAuth)
        return;

        return auth.configureCredentials(registry,
            config.authToken && { token: config.authToken } || config.auth && auth.decodeCredentials(config.auth) || npmrcAuth, ui)
            .then(function(_auth) {
                delete config.auth;
                delete config.authToken;

                if (_auth.token)
                config.authToken = _auth.token;
                else if (_auth.username && _auth.password)
                config.auth = auth.encodeCredentials(_auth);
            });
        })
        .then(function() {
            return config;
        });
    };

    P4Location.packageFormat = /^@[^\/]+\/[^\/]+|^[^@\/][^\/]+/;

    P4Location.prototype = {

        lookup: function(repo) {
            var self = this;

            var newLookup = false;
            var lookupCache;
            var latestKey = 'latest';
            var repoPath = repo[0] == '@' ? '@' + encodeURIComponent(repo.substr(1)) : encodeURIComponent(repo);

            var doAuth = this.alwaysAuth || repo[0] == '@';

            return asp(fs.readFile)(path.resolve(self.tmpDir, repo + '.json'))
            .then(function(lookupJSON) {
                lookupCache = JSON.parse(lookupJSON.toString());
            }).catch(function(e) {
                if (e.code == 'ENOENT' || e instanceof SyntaxError)
                return;
                throw e;
            })
            .then(function() {
                var scope;
                if (repo[0] === '@') {
                    var scopeMatch = repo.match(/^(@.*)\//);
                    if (scopeMatch[1]) {
                        scope = scopeMatch[1];
                    }
                }
                return asp(request)(auth.injectRequestOptions({
                    uri: self.registryURL(scope) + '/' + repoPath,
                    strictSSL: self.strictSSL,
                    headers: lookupCache ? {
                        'if-none-match': lookupCache.eTag
                    } : {}
                }, doAuth && self.auth)).then(function(res) {
                    if (res.statusCode == 304)
                    return { versions: lookupCache.versions,
                        latest: lookupCache.latest };

                        if (res.statusCode == 404)
                        return { notfound: true };

                        if (res.statusCode == 401)
                        throw 'Invalid authentication details. Run %jspm registry config ' + self.name + '% to reconfigure.';

                        if (res.statusCode != 200)
                        throw 'Invalid status code ' + res.statusCode;

                        var versions = {};
                        var latest;
                        var packageData;

                        try {
                            var json = JSON.parse(res.body);
                            var distTags = json['dist-tags'] || {};
                            packageData = json.versions;
                            latest = distTags[latestKey];
                        }
                        catch(e) {
                            throw 'Unable to parse package.json';
                        }

                        for (var v in packageData) {
                            if (packageData[v].dist && packageData[v].dist.shasum)
                            versions[v] = {
                                hash: packageData[v].dist.shasum,
                                meta: packageData[v],
                                stable: !packageData[v].deprecated
                            };
                        }

                        if (res.headers.etag) {
                            newLookup = true;
                            lookupCache = {
                                eTag: res.headers.etag,
                                versions: versions,
                                latest: latest,
                            };
                        }

                        return { versions: versions,
                            latest: latest };
                        });
                    })
                    .then(function(response) {
                        // save lookupCache
                        if (newLookup) {
                            var lookupJSON = JSON.stringify(lookupCache);
                            var outputPath = path.resolve(self.tmpDir, repo + '.json');
                            return asp(mkdirp)(path.dirname(outputPath))
                            .then(function() {
                                return asp(fs.writeFile)(outputPath, lookupJSON);
                            })
                            .then(function() {
                                return response;
                            });
                        }

                        return response;
                    });
                },

                getPackageConfig: function(repo, version, hash, pjson) {
                    if (!pjson)
                    throw 'Package.json meta not provided in endpoint request';

                    if (hash && pjson.dist.shasum != hash)
                    throw 'Package.json lookup hash mismatch';

                    return clone(pjson);
                },

                processPackageConfig: function(pjson, packageName) {
                    if (pjson.jspmNodeConversion === false)
                    return pjson;

                    // peer dependencies are just dependencies in jspm
                    pjson.dependencies = pjson.dependencies || {};
                    if (pjson.peerDependencies) {
                        for (d in pjson.peerDependencies)
                        pjson.dependencies[d] = pjson.peerDependencies[d];
                    }

                    // warn if using jspm-style dependencies at this point
                    for (var d in pjson.dependencies)
                    if (!pjson.dependencies[d].match(/^(https?|git)[:+]/) && pjson.dependencies[d].indexOf(':') > 0)
                    throw 'Package.json dependency %' + d + '% set to `' + pjson.dependencies[d] + '`, which is not a valid dependency format for npm.'
                    + '\nIt\'s advisable to publish jspm-style packages to GitHub or another `registry` so conventions are clear.';
                    + '\nTo skip npm compatibility install with %jspm install ' + packageName + '-o "{jspmNodeConversion: false}"%.'

                    pjson.dependencies = nodeConversion.parseDependencies(pjson.dependencies, this.ui);

                    pjson.format = pjson.format || 'cjs';

                    // json mains become plugins
                    if (pjson.main && typeof pjson.main == 'string' && pjson.main.substr(pjson.main.length - 5, 5) == '.json') {
                        pjson.main += '!systemjs-json';
                        pjson.dependencies['systemjs-json'] = nodeConversion.jsonPlugin;
                    }

                    // ignore directory flattening for NodeJS, as npm doesn't do it
                    // we do allow if there was an override through the jspm property though
                    if (!pjson.jspm || !pjson.jspm.directories)
                    delete pjson.directories;

                    // ignore node_modules by default when processing
                    if (!(pjson.ignore instanceof Array))
                    pjson.ignore = [];
                    pjson.ignore.push('node_modules');

                    if (pjson.files && pjson.files instanceof Array && pjson.files.indexOf('package.json') == -1)
                    pjson.files.push('package.json');

                    // if there is a "browser" object, convert it into map config for browserify support
                    if (typeof pjson.browserify == 'string')
                    pjson.main = pjson.browserify;
                    if (typeof pjson.browser == 'string')
                    pjson.main = pjson.browser;

                    if (typeof pjson.browser == 'object') {
                        pjson.map = pjson.map || {};
                        for (var b in pjson.browser) {
                            var mapping = pjson.browser[b];

                            if (mapping === false) {
                                mapping = '@empty';
                            }
                            else if (typeof mapping == 'string') {
                                if (b.substr(b.length - 3, 3) == '.js')
                                b = b.substr(0, b.length - 3);
                                if (mapping.substr(mapping.length - 3, 3) == '.js')
                                mapping = mapping.substr(0, mapping.length - 3);

                                // we handle relative maps during the build phase
                                if (b.substr(0, 2) == './')
                                continue;
                            }
                            else
                            continue;

                            pjson.map[b] = pjson.map[b] || mapping;
                        }
                    }

                    return pjson;
                },

                download: function(repo, version, hash, versionData, outDir) {
                    var self = this;

                    var doAuth = this.alwaysAuth || repo[0] == '@';

                    // Forcing protocol and port matching for tarballs on the same host as the
                    // registry is taken from npm at
                    // https://github.com/npm/npm/blob/50ce116baac8b6877434ace471104ec8587bab90/lib/cache/add-named.js#L196-L208
                    var tarball = url.parse(versionData.dist.tarball);
                    var registry = url.parse(this.registryURL());

                    if (tarball.hostname === registry.hostname && tarball.protocol !== registry.protocol) {
                        tarball.protocol = registry.protocol;
                        tarball.port = registry.port;
                    }
                    tarball = url.format(tarball);

                    return new Promise(function(resolve, reject) {
                        request(auth.injectRequestOptions({
                            uri: tarball,
                            headers: { 'accept': 'application/octet-stream' },
                            strictSSL: self.strictSSL
                        }, doAuth && self.auth))
                        .on('response', function(npmRes) {

                            if (npmRes.statusCode != 200)
                            return reject('Bad response code ' + npmRes.statusCode);

                            if (npmRes.headers['content-length'] > 50000000)
                            return reject('Response too large.');

                            npmRes.pause();

                            var gzip = zlib.createGunzip();

                            npmRes
                            .pipe(gzip)
                            .pipe(tar.Extract({
                                path: outDir,
                                strip: 1,
                                filter: function() {
                                    return !this.type.match(/^.*Link$/);
                                }
                            }))
                            .on('error', reject)
                            .on('end', resolve);

                            npmRes.resume();
                        })
                        .on('error', function(error) {
                            if (typeof error == 'string') {
                                error = new Error(error);
                                error.hideStack = true;
                            }
                            error.retriable = true;
                            reject(error);
                        });
                    });
                },

                build: function(pjson, dir) {
                    if (pjson.jspmNodeConversion === false)
                    return;

                    // apply static conversions
                    return nodeConversion.convertPackage(pjson, dir);
                }
            };

            module.exports = P4Location;
<commit_msg>Add packageFormat<commit_after>var Promise = require('rsvp').Promise;
var asp = require('rsvp').denodeify;
var fs = require('graceful-fs');
var exec = require('child_process').exec;
var semver = require('semver');
var path = require('path');
var rimraf = require('rimraf');
// var P4rc = require('./p4rc.js');

function clone(a) {
  var b = {};
  for (var p in a) {
    if (a[p] instanceof Array)
      b[p] = [].concat(a[p]);
    else if (typeof a[p] == 'object')
      b[p] = clone(a[p]);
    else
      b[p] = a[p];
  }
  return b;
}

/**
* Create a Perforce registry
* @param {object} options Options from jspm (config?). Can contain any other registry-specific config.
* @param {string} options.tmpDir Path to a folder the registry can use to store temporary files. This folder persists and is shared between installs.
* @param {string} options.versionString Represents the minor and major version of the registry package, which is used in the caching hash of packages. This can be altered and written to the instance allowing for custom registry cache invalidation - `this.versionString = options.versionString + '.53'``.
* @param {object} ui      Accessing the ui (console)
*/
var P4Registry = module.exports = function P4Registry(options, ui) {
    this.ui = ui;
    this.registryPath = options.tmpDir;
    this.registryUpdated = false;
    this.repo = options.repo || defaultRepo;

    this.execOptions = {
      cwd: options.tmpDir,
      timeout: options.timeout * 1000,
      killSignal: 'SIGKILL'
    };
};

P4Registry.packageFormat = /^@[^\/]+\/[^\/]+|^[^@\/][^\/]+/;

P4Registry.prototype = {
    // /**
    // * Given a package name, locate it and ensure it exists.
    // * @param  {string} packageName Name of the package
    // * @return {Promise}  Promise { notfound: true } | { redirect: 'new:package' } / undefined
    // */
    // locate: function(packageName) {
    //     // packageName = 'owner/repo'
    //     var root = this.root;
    //
    //     if (repo.split('/').length !== 2) {
    //         throw new Error("Perforce packages must be organized in the form of `owner(team)/repo`.");
    //     }
    //
    //     return new Promise(function(resolve, reject) {
    //         var stat = fs.statSync(root + "/" + packageName);
    //         if (stat.isDirectory()) {
    //             resolve()
    //         }
    //         else {
    //             resolve({ notfound: true});
    //         }
    //     });
    // },
    lookup: function(packageName) {
        var root = this.root;

        if (repo.split('/').length !== 2) {
            throw new Error("Perforce packages must be organized in the form of `owner(team)/repo`.");
        }

        return new Promise(function (resolve, reject) {
            var stat = fs.statSync(root + "/" + packageName);
            if (stat.isDirectory()) {
                resolve()
            }
            else {
                resolve({ notfound: true});
            }
        });
    },
    download: function(packageName, version, hash, meta, dir) {
        return Promise.resolve({ notfound: true});
    }
    // parse: function parse(name) {
    //     var parts = name.split('/');
    //     if (parts.length !== 2) {
    //         throw new Error("Perforce packages must be organized in the form of `owner(team)/repo`.");
    //     }
    //
    //     return {
    //         package: parts[0],
    //         path: parts.splice(1).join('/')
    //     };
    // },
    // updateRegistry: function updateRegistry() {
    //     if (this.updatePromise_)
    //     return Promise.resolve(this.updatePromise_);
    //
    //     var ui = this.ui;
    //     var registryPath = this.registryPath;
    //     var remoteString = this.repo;
    //     var execOptions = this.execOptions;
    //     var self = this;
    //
    //     return this.updatePromise_ = asp(exec)('git remote show origin -n', execOptions)
    //     .then(function(output) {
    //         output = output.toString();
    //
    //         var curRepoMatch = output.match(/Fetch URL: ([^\n]+)/m);
    //
    //         if (!curRepoMatch || curRepoMatch[1] != self.repo)
    //         return self.createRegistry();
    //
    //         // if the registry does exist, update it
    //         ui.log('info', 'Updating registry cache...');
    //         return asp(exec)('git fetch --all && git reset --hard origin/master', execOptions)
    //         .then(function(stdout, stderr) {
    //             if (stderr)
    //             throw stderr;
    //         })
    //         .catch(function(err) {
    //             if (typeof err == 'string') {
    //                 err = new Error(err);
    //                 err.hideStack = true;
    //             }
    //             err.retriable = true;
    //             throw err;
    //         });
    //     }, function(err) {
    //         err = err.toString();
    //
    //         // if the registry does not exist, do a git clone
    //         if (err.indexOf('Not a git repo') != -1)
    //         return self.createRegistry();
    //     })
    //     .then(function() {
    //         return asp(fs.readFile)(path.resolve(registryPath, 'registry.json'))
    //         .then(function(pjson) {
    //             try {
    //                 return JSON.parse(pjson);
    //             }
    //             catch(e) {
    //                 return {};
    //             }
    //         }, function(err) {
    //             if (err.code === 'ENOENT')
    //             return {};
    //             ui.log('warn', 'Registry file is invalid.');
    //         });
    //     })
    //     .then(function(json) {
    //         return json;
    //     });
    // }
};
<|endoftext|>


<commit_before>/*global module:false*/
module.exports = function(grunt) {
	'use strict';
	grunt.initConfig({
		pkg: '<json:package.json>',
		meta: {
			banner: '// <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
				'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
				'<%= pkg.homepage ? "// " + pkg.homepage + "\n" : "" %>' +
				'// Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
				' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>'
		},
		clean: {
			app: {
				src: ["build", "docs", "app/js", 'test/unit/js']
			}
		},
		docco: {
			app: {
				src: ['**/*.ls', '**/*.js']
			}
		},
		qunit: {
			files: ['test/**/*.html']
		},
		livescript: {
			app: {
				files: {
					'app/scripts/js/app.js': 'app/scripts/ls/app.ls',
					'app/scripts/js/filters.js': 'app/scripts/ls/filters/*ls',
					'app/scripts/js/services.js': 'app/scripts/ls/services/*ls',
					'app/scripts/js/directives.js': 'app/scripts/ls/directives/*ls',
					'app/scripts/js/controllers.js': 'app/scripts/ls/controllers/*ls'
				},
				options: {
					bare: false
				}
			},
			dist: {
				files: {
					'build/modeler.js': 'build/modeler.ls'
				}
			},
			test: {
				files: {
					'test/unit/js/unit.js': 'test/unit/**/*.ls',

					'test/e2e/js/spec.js': 'test/e2e/ls/*.ls'
				},
				options: {
					bare: true
				}
			}
		},
		concat: {
			app: {
				src: [
					'app/scripts/ls/app.ls',
					'app/scripts/ls/**/*ls',
				],
				dest: 'build/modeler.ls'
			},
			unit: {
				src: ['test/unit/js/*'],
				dest: 'test/unit.js'
			},
			e2e: {
				src: ['test/e2e/js/*'],
				dest: 'test/e2e.js'
			}
		},
		min: {
			dist: {
				src: ['<banner:meta.banner>', 'build/modeler.js'],
				dest: 'build/modeler.min.js'
			}
		},
		watch: {
			app: {
				files: ["app/scripts/ls/**", "app/views/**", "app/index.html", "test/**"],
				tasks: ["default"]
			}
		},
		jshint: {
			options: {
				curly: true,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				boss: true,
				eqnull: true
			},
			globals: {
				jQuery:false,
				JEFRi:false,
				UUID: false,
				_:false
			}
		},
		uglify: {}
	});

	grunt.loadNpmTasks('grunt-contrib');
	grunt.loadNpmTasks('grunt-docco');

	grunt.registerTask('app', 'livescript:app concat:app livescript:dist min');
	grunt.registerTask('tests', 'livescript:test concat:unit concat:e2e');
	grunt.registerTask('default', 'clean app tests');
};
<commit_msg>Changed watch list.<commit_after>/*global module:false*/
module.exports = function(grunt) {
	'use strict';
	grunt.initConfig({
		pkg: '<json:package.json>',
		meta: {
			banner: '// <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' +
				'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
				'<%= pkg.homepage ? "// " + pkg.homepage + "\n" : "" %>' +
				'// Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
				' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>'
		},
		clean: {
			app: {
				src: ["build", "docs", "app/js", 'test/unit/js']
			}
		},
		docco: {
			app: {
				src: ['**/*.ls', '**/*.js']
			}
		},
		qunit: {
			files: ['test/**/*.html']
		},
		livescript: {
			app: {
				files: {
					'app/scripts/js/app.js': 'app/scripts/ls/app.ls',
					'app/scripts/js/filters.js': 'app/scripts/ls/filters/*ls',
					'app/scripts/js/services.js': 'app/scripts/ls/services/*ls',
					'app/scripts/js/directives.js': 'app/scripts/ls/directives/*ls',
					'app/scripts/js/controllers.js': 'app/scripts/ls/controllers/*ls'
				},
				options: {
					bare: false
				}
			},
			dist: {
				files: {
					'build/modeler.js': 'build/modeler.ls'
				}
			},
			test: {
				files: {
					'test/unit/js/unit.js': 'test/unit/**/*.ls',

					'test/e2e/js/spec.js': 'test/e2e/ls/*.ls'
				},
				options: {
					bare: true
				}
			}
		},
		concat: {
			app: {
				src: [
					'app/scripts/ls/app.ls',
					'app/scripts/ls/**/*ls',
				],
				dest: 'build/modeler.ls'
			},
			unit: {
				src: ['test/unit/js/*'],
				dest: 'test/unit.js'
			},
			e2e: {
				src: ['test/e2e/js/*'],
				dest: 'test/e2e.js'
			}
		},
		min: {
			dist: {
				src: ['<banner:meta.banner>', 'build/modeler.js'],
				dest: 'build/modeler.min.js'
			}
		},
		watch: {
			app: {
				files: ["app/scripts/ls/**/*ls", "app/views/**", "app/index.html", "test/**/*ls"],
				tasks: ["default"]
			}
		},
		jshint: {
			options: {
				curly: true,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				boss: true,
				eqnull: true
			},
			globals: {
				jQuery:false,
				JEFRi:false,
				UUID: false,
				_:false
			}
		},
		uglify: {}
	});

	grunt.loadNpmTasks('grunt-contrib');
	grunt.loadNpmTasks('grunt-docco');

	grunt.registerTask('app', 'livescript:app concat:app livescript:dist min');
	grunt.registerTask('tests', 'livescript:test concat:unit concat:e2e');
	grunt.registerTask('default', 'clean app tests');
};
<|endoftext|>


<commit_before>function AppDataModel() {
    var self = this;
    // Routes
    self.userInfoUrl = "/api/Me";
    self.siteUrl = "/";

    // Route operations

    // Other private operations

    // Operations

    // Data
    self.returnUrl = self.siteUrl;

    // Data access operations
    self.setAccessToken = function (accessToken) {
        sessionStorage.setItem("accessToken", accessToken);
    };

    self.getAccessToken = function () {
        return sessionStorage.getItem("accessToken");
    };
}
<commit_msg>Delete app.datamodel.js<commit_after><|endoftext|>


<commit_before>import { sort_out_arguments } from './getNumberType'
import isValidNumber from './validate'

/**
 * Checks if a given phone number is valid.
 *
 * If the `number` is a string, it will be parsed to an object,
 * but only if it contains only valid phone number characters.
 * If the `number` is an object, it is used as is.
 *
 * The `country` argument is the country the number must belong to.
 * This is a stricter version of `isValidNumber(number, defaultCountry)`.
 * Though restricting a country might not be a good idea.
 * https://github.com/googlei18n/libphonenumber/blob/master/FAQ.md#when-should-i-use-isvalidnumberforregion
 *
 * Doesn't accept `number` object, only `number` string with a `country` string.
 */
export default function isValidNumberForRegion(number, country, _metadata)
{
	if (typeof number !== 'string')
	{
		throw new TypeError('number must be a string')
	}

	if (typeof country !== 'string')
	{
		throw new TypeError('country must be a string')
	}

	const { input, metadata } = sort_out_arguments(number, country, _metadata)
	const isValid = isValidNumber(input, metadata.metadata)

	return isValid && input.country === country
}<commit_msg>`isValidNumberForRegion` tweak<commit_after>import { sort_out_arguments } from './getNumberType'
import isValidNumber from './validate'

/**
 * Checks if a given phone number is valid.
 *
 * If the `number` is a string, it will be parsed to an object,
 * but only if it contains only valid phone number characters.
 * If the `number` is an object, it is used as is.
 *
 * The `country` argument is the country the number must belong to.
 * This is a stricter version of `isValidNumber(number, defaultCountry)`.
 * Though restricting a country might not be a good idea.
 * https://github.com/googlei18n/libphonenumber/blob/master/FAQ.md#when-should-i-use-isvalidnumberforregion
 *
 * Doesn't accept `number` object, only `number` string with a `country` string.
 */
export default function isValidNumberForRegion(number, country, _metadata)
{
	if (typeof number !== 'string')
	{
		throw new TypeError('number must be a string')
	}

	if (typeof country !== 'string')
	{
		throw new TypeError('country must be a string')
	}

	const { input, metadata } = sort_out_arguments(number, country, _metadata)

	return input.country === country && isValidNumber(input, metadata.metadata)
}<|endoftext|>


<commit_before>'use strict';

var React = require('react');
var merge = require('lodash.merge');
var Router = require('react-router');
var Link = React.createFactory(Router.Link);
var StyleMixin = require('../../lib/StyleMixin');
var css = require('./index.styl');
var Badge = require('../Badge');
var DOM = React.DOM;
var PropTypes = React.PropTypes;

module.exports = React.createClass({
  displayName: 'Navbar',
  mixins: [StyleMixin],
  css: css,

  propTypes: {
    links: PropTypes.arrayOf(PropTypes.object),
    title: PropTypes.string,
    logo: PropTypes.string
  },

  getInitialState: function() {
    return {
      toggleNav: false
    };
  },
  getDefaultProps: function(){
    return {
      links: []
    };
  },
  toggleNav: function() {
    this.setState({toggleNav: !this.state.toggleNav});
  },
  render: function(){
    var props = merge({
      className: 'navbar-component',
      style: this.props.style
    }, this.props);

    var logo = DOM.img({
      className: 'logo',
      src: this.props.logo
    });
    var title = DOM.div({
      className: 'title'
    }, this.props.logo ? logo : this.props.title);

    var button = DOM.div({
      className: 'navbar-button',
      onClick: this.toggleNav
    },
      DOM.div({className: 'bar'}),
      DOM.div({className: 'bar'}),
      DOM.div({className: 'bar'})
    );
    var links = this.props.links.map(function(link) {
      link.key = link.to + '-nav-link';
      link.onClick = this.toggleNav;
      var badge = link.badge != null ? Badge(link.badge) : null;
      return Link(link, link.label, badge);
    }, this);

    var inner = DOM.div({
      className: 'inner',
      style: {
        maxHeight: this.state.toggleNav ? '600' : '0'
      }
    }, links);

    return DOM.nav(props, title, inner, button);
  }
});
<commit_msg>fix bage showing<commit_after>'use strict';

var React = require('react');
var merge = require('lodash.merge');
var Router = require('react-router');
var Link = React.createFactory(Router.Link);
var StyleMixin = require('../../lib/StyleMixin');
var css = require('./index.styl');
var Badge = React.createFactory(require('../Badge'));
var DOM = React.DOM;
var PropTypes = React.PropTypes;

module.exports = React.createClass({
  displayName: 'Navbar',
  mixins: [StyleMixin],
  css: css,

  propTypes: {
    links: PropTypes.arrayOf(PropTypes.object),
    title: PropTypes.string,
    logo: PropTypes.string
  },

  getInitialState: function() {
    return {
      toggleNav: false
    };
  },
  getDefaultProps: function(){
    return {
      links: []
    };
  },
  toggleNav: function() {
    this.setState({toggleNav: !this.state.toggleNav});
  },
  render: function(){
    var props = merge({
      className: 'navbar-component',
      style: this.props.style
    }, this.props);

    var logo = DOM.img({
      className: 'logo',
      src: this.props.logo
    });
    var title = DOM.div({
      className: 'title'
    }, this.props.logo ? logo : this.props.title);

    var button = DOM.div({
      className: 'navbar-button',
      onClick: this.toggleNav
    },
      DOM.div({className: 'bar'}),
      DOM.div({className: 'bar'}),
      DOM.div({className: 'bar'})
    );
    var links = this.props.links.map(function(link) {
      link.key = link.to + '-nav-link';
      link.onClick = this.toggleNav;
      var badge = link.badge != null && link.count != null ? Badge(link.badge) : null;
      return Link(link, link.label, badge);
    }, this);

    var inner = DOM.div({
      className: 'inner',
      style: {
        maxHeight: this.state.toggleNav ? '600' : '0'
      }
    }, links);

    return DOM.nav(props, title, inner, button);
  }
});
<|endoftext|>


<commit_before>exports.BattleAliases = {
	// formes
	"basculinb": "Basculin-Blue",
	"castformh": "Castform-Snowy",
	"castformice": "Castform-Snowy",
	"castformr": "Castform-Rainy",
	"castformwater": "Castform-Rainy",
	"castforms": "Castform-Sunny",
	"castformfire": "Castform-Sunny",
	"cherrims": "Cherrim-Sunshine",
	"cherrimsunny": "Cherrim-Sunshine",
	"darmanitanzenmode": "Darmanitan-Zen",
	"deoxysa": "Deoxys-Attack",
	"deoxysd": "Deoxys-Defense",
	"deoxysdefence": "Deoxys-Defense",
	"deoxyss": "Deoxys-Speed",
	"giratinao": "Giratina-Origin",
	"landorust": "Landorus-Therian",
	"rotomc": "Rotom-Mow",
	"rotomf": "Rotom-Frost",
	"rotomh": "Rotom-Heat",
	"rotoms": "Rotom-Fan",
	"rotomw": "Rotom-Wash",
	"shaymins": "Shaymin-Sky",
	"thundurust": "Thundurus-Therian",
	"tornadust": "Tornadus-Therian",
	"meloettap": "Meloetta-Pirouette",
	"meloettas": "Meloetta-Pirouette",
	"wormadamg": "Wormadam-Sandy",
	"wormadamground": "Wormadam-Sandy",
	"wormadams": "Wormadam-Trash",
	"wormadamsteel": "Wormadam-Trash",

	// base formes
	"nidoranfemale": "Nidoran-F",
	"nidoranmale": "Nidoran-M",
	"giratinaa": "Giratina",
	"giratinaaltered": "Giratina",
	"cherrimo": "Cherrim",
	"cherrimovercast": "Cherrim",
	"meloettaa": "Meloetta",
	"meloettaaria": "Meloetta",
	"basculinr": "Basculin",
	"basculinred": "Basculin",

	// items
	"cb": "Choice Band",
	"band": "Choice Band",
	"lefties": "Leftovers",
	"lo": "Life Orb",

	// pokemon
	"dnite": "Dragonite",
	"ferry": "Ferrothorn",
	"forry": "Forretress",
	"luke":  "Lucario",
	"p2": "Porygon2",
	"pory2": "Porygon2",
	"pz": "Porygon-Z",
	"poryz": "Porygon-Z",
	"rank": "Reuniclus",
	"ttar": "Tyranitar",

	// moves
	"cc": "Close Combat",
	"cm": "Calm Mind",
	"dd": "Dragon Dance",
	"eq": "Earthquake",
	"hjk": "Hi Jump Kick",
	"np": "Nasty Plot",
	"qd": "Quiver Dance",
	"sd": "Swords Dance",
	"se": "Stone Edge",
	"sr": "Stealth Rock",
	"tr": "Trick Room",
	"tbolt": "Thunderbolt",
	"tspikes": "Toxic Spikes",
	"twave": "Thunder Wave",
	"wow": "Will-O-Wisp",

	// Japanese names
	"birijion": "Virizion",
	"terakion": "Terrakion",
	"agirudaa": "Accelgor",
	"randorosu": "Landorus",
	"urugamosu": "Volcarona",
	"erufuun": "Whimsicott",
	"doryuuzu": "Excadrill",
	"burungeru": "Jellicent",
	"nattorei": "Ferrothorn",
	"shandera": "Chandelure",
	"roobushin": "Conkeldurr",
	"ononokusu": "Haxorus",
	"sazandora": "Hydreigon",
	"chirachiino": "Cinccino",
	"kyuremu": "Kyurem",
	"jarooda": "Serperior",
	"zoroaaku": "Zoroark",
	"shinboraa": "Sigilyph",
	"barujiina": "Mandibuzz",
	"rankurusu": "Reuniclus",
	"borutorosu": "Thundurus"
	// there's no need to type out the other Japanese names
	// I'll autogenerate them at some point
};
<commit_msg>Kyurem-B/W aliases<commit_after>exports.BattleAliases = {
	// formes
	"basculinb": "Basculin-Blue",
	"castformh": "Castform-Snowy",
	"castformice": "Castform-Snowy",
	"castformr": "Castform-Rainy",
	"castformwater": "Castform-Rainy",
	"castforms": "Castform-Sunny",
	"castformfire": "Castform-Sunny",
	"cherrims": "Cherrim-Sunshine",
	"cherrimsunny": "Cherrim-Sunshine",
	"darmanitanzenmode": "Darmanitan-Zen",
	"deoxysa": "Deoxys-Attack",
	"deoxysd": "Deoxys-Defense",
	"deoxysdefence": "Deoxys-Defense",
	"deoxyss": "Deoxys-Speed",
	"giratinao": "Giratina-Origin",
	"kyuremb": "Kyurem-Black",
	"kyuremw": "Kyurem-White",
	"landorust": "Landorus-Therian",
	"rotomc": "Rotom-Mow",
	"rotomf": "Rotom-Frost",
	"rotomh": "Rotom-Heat",
	"rotoms": "Rotom-Fan",
	"rotomw": "Rotom-Wash",
	"shaymins": "Shaymin-Sky",
	"thundurust": "Thundurus-Therian",
	"tornadust": "Tornadus-Therian",
	"meloettap": "Meloetta-Pirouette",
	"meloettas": "Meloetta-Pirouette",
	"wormadamg": "Wormadam-Sandy",
	"wormadamground": "Wormadam-Sandy",
	"wormadams": "Wormadam-Trash",
	"wormadamsteel": "Wormadam-Trash",

	// base formes
	"nidoranfemale": "Nidoran-F",
	"nidoranmale": "Nidoran-M",
	"giratinaa": "Giratina",
	"giratinaaltered": "Giratina",
	"cherrimo": "Cherrim",
	"cherrimovercast": "Cherrim",
	"meloettaa": "Meloetta",
	"meloettaaria": "Meloetta",
	"basculinr": "Basculin",
	"basculinred": "Basculin",

	// items
	"cb": "Choice Band",
	"band": "Choice Band",
	"lefties": "Leftovers",
	"lo": "Life Orb",

	// pokemon
	"dnite": "Dragonite",
	"ferry": "Ferrothorn",
	"forry": "Forretress",
	"luke":  "Lucario",
	"p2": "Porygon2",
	"pory2": "Porygon2",
	"pz": "Porygon-Z",
	"poryz": "Porygon-Z",
	"rank": "Reuniclus",
	"ttar": "Tyranitar",

	// moves
	"cc": "Close Combat",
	"cm": "Calm Mind",
	"dd": "Dragon Dance",
	"eq": "Earthquake",
	"hjk": "Hi Jump Kick",
	"np": "Nasty Plot",
	"qd": "Quiver Dance",
	"sd": "Swords Dance",
	"se": "Stone Edge",
	"sr": "Stealth Rock",
	"tr": "Trick Room",
	"tbolt": "Thunderbolt",
	"tspikes": "Toxic Spikes",
	"twave": "Thunder Wave",
	"wow": "Will-O-Wisp",

	// Japanese names
	"birijion": "Virizion",
	"terakion": "Terrakion",
	"agirudaa": "Accelgor",
	"randorosu": "Landorus",
	"urugamosu": "Volcarona",
	"erufuun": "Whimsicott",
	"doryuuzu": "Excadrill",
	"burungeru": "Jellicent",
	"nattorei": "Ferrothorn",
	"shandera": "Chandelure",
	"roobushin": "Conkeldurr",
	"ononokusu": "Haxorus",
	"sazandora": "Hydreigon",
	"chirachiino": "Cinccino",
	"kyuremu": "Kyurem",
	"jarooda": "Serperior",
	"zoroaaku": "Zoroark",
	"shinboraa": "Sigilyph",
	"barujiina": "Mandibuzz",
	"rankurusu": "Reuniclus",
	"borutorosu": "Thundurus"
	// there's no need to type out the other Japanese names
	// I'll autogenerate them at some point
};
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of fiware-iotagent-lib
 *
 * fiware-iotagent-lib is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * fiware-iotagent-lib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with fiware-iotagent-lib.
 * If not, see http://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::daniel.moranjimenez@telefonica.com
 *
 * Modified by: Daniel Calvo - ATOS Research & Innovation
 */

const logger = require('logops');
const dbService = require('../../model/dbConn');
const intoTrans = require('../common/domain').intoTrans;
const fillService = require('./../common/domain').fillService;
const alarmsInt = require('../common/alarmManagement').intercept;
const constants = require('../../constants');
const errors = require('../../errors');
const Group = require('../../model/Group');
const async = require('async');
let context = {
    op: 'IoTAgentNGSI.MongoDBGroupRegister'
};

const attributeList = [
    'url',
    'resource',
    'apikey',
    'type',
    'service',
    'subservice',
    'description',
    'trust',
    'cbHost',
    'timezone',
    'timestamp',
    'commands',
    'lazy',
    'attributes',
    'staticAttributes',
    'internalAttributes',
    'autoprovision',
    'explicitAttrs',
    'expressionLanguage',
    'defaultEntityNameConjunction',
    'ngsiVersion'
];

/**
 * Generates a handler for the save device group operations. The handler will take the customary error and the saved
 * device group as the parameters (and pass the serialized DAO as the callback value).
 *
 * @return {Function}       The generated handler.
 */
function saveGroupHandler(groupDAO, callback) {
    /* eslint-disable-next-line no-unused-vars */
    return function saveHandler(error, result) {
        if (error) {
            logger.debug(fillService(context, groupDAO), 'Error storing device group information: %s', error);

            callback(new errors.InternalDbError(error));
        } else {
            callback(null, groupDAO.toObject());
        }
    };
}

function createGroup(group, callback) {
    /* eslint-disable-next-line  new-cap */
    const groupObj = new Group.model();

    attributeList.forEach((key) => {
        groupObj[key] = group[key];
    });

    logger.debug(
        context,
        'Storing device group with id [%s], type [%s], apikey [%s] and resource [%s]',
        groupObj._id,
        groupObj.type,
        groupObj.apikey,
        groupObj.resource
    );

    groupObj.save(function saveHandler(error, groupDAO) {
        if (error) {
            if (error.code === 11000) {
                logger.debug(
                    context,
                    'Duplicate group entry with resource [%s] and apiKey [%s]',
                    group.resource,
                    group.apikey
                );

                callback(new errors.DuplicateGroup(group.resource, group.apikey));
            } else {
                logger.debug(context, 'Error storing device group information: %s', error);

                callback(new errors.InternalDbError(error));
            }
        } else {
            callback(null, groupDAO.toObject());
        }
    });
}

/**
 * List all the groups created in the IoT Agent.
 *
 * @param {Number} service      Service for wich all the configurations want to be retrieved.
 * @param {Number} limit        Maximum number of entries to return.
 * @param {Number} offset       Number of entries to skip for pagination.
 */
function listGroups(service, limit, offset, callback) {
    const condition = {};

    function toObjectFn(obj) {
        return obj.toObject();
    }

    if (service) {
        condition.service = service;
    }

    const query = Group.model.find(condition).sort();

    if (limit) {
        query.limit(parseInt(limit, 10));
    }

    if (offset) {
        query.skip(parseInt(offset, 10));
    }

    async.series([query.exec.bind(query), Group.model.countDocuments.bind(Group.model, condition)], function (
        error,
        results
    ) {
        callback(error, {
            count: results[1],
            services: results[0].map(toObjectFn)
        });
    });
}

function getById(id, callback) {
    context = fillService(context, { service: 'n/a', subservice: 'n/a' });
    logger.debug(context, 'Looking for device group with id [%s].', id);

    const query = Group.model.findOne({ _id: id });
    query.select({ __v: 0 });

    query.lean().exec(function handleGet(error, data) {
        if (error) {
            logger.debug(context, 'Internal MongoDB Error getting group: %s', error);

            callback(new errors.InternalDbError(error));
        } else if (data) {
            context = fillService(context, data);
            logger.debug(context, 'Device group data found: %j', data);
            callback(null, data);
        } else {
            logger.debug(context, 'Device group [%s] not found.', id);

            callback(new errors.DeviceGroupNotFound(id));
        }
    });
}

/**
 * List all the groups created in the IoT Agent for a service and a subservice.
 *
 * @param  {String} service        Service used to filter the groups.
 * @param  {String} subservice     Subservice used to filter the groups.
 * @param  {Function} callback     The callback function.
 */
function find(service, subservice, callback) {
    const condition = {};

    function toObjectFn(obj) {
        return obj.toObject();
    }

    condition.service = service;
    condition.subservice = subservice;

    const query = Group.model.find(condition).sort();

    async.series([query.exec.bind(query), Group.model.countDocuments.bind(Group.model, condition)], function (
        error,
        results
    ) {
        callback(error, {
            count: results[1],
            services: results[0].map(toObjectFn)
        });
    });
}

function findOneInMongoDB(queryObj, fields, callback) {
    const query = Group.model.findOne(queryObj);
    query.select({ __v: 0 });
    query.lean().exec(function handleGet(error, data) {
        if (error) {
            logger.debug(context, 'Internal MongoDB Error getting group: %s', error);
            callback(new errors.InternalDbError(error));
        } else if (data) {
            context = fillService(context, data);
            logger.debug(context, 'Device group data found: %j', data);
            callback(null, data);
        } else {
            logger.debug(context, 'Device group for fields [%j] not found: [%j]', fields, queryObj);
            callback(new errors.DeviceGroupNotFound(fields, queryObj));
        }
    });
}

function findBy(fields) {
    return function () {
        const queryObj = {};
        let i = 0;

        /* eslint-disable prefer-rest-params */
        while (typeof arguments[i] !== 'function') {
            if (arguments[i]) {
                queryObj[fields[i]] = arguments[i];
            }

            i++;
        }
        const callback = arguments[i];
        /* eslint-enable prefer-rest-params */

        context = fillService(context, { service: 'n/a', subservice: 'n/a' });
        logger.debug(context, 'Looking for group params %j with queryObj %j', fields, queryObj);
        findOneInMongoDB(queryObj, fields, callback);
    };
}

function update(id, body, callback) {
    logger.debug(context, 'Storing updated values for configuration [%s]:\n%s', id, JSON.stringify(body, null, 4));
    getById(id, function (error, group) {
        if (error) {
            callback(error);
        } else {
            attributeList.forEach((key) => {
                if (body[key] !== undefined) {
                    group[key] = body[key];
                }
            });
            /* eslint-disable-next-line  new-cap */
            const groupObj = new Group.model(group);
            groupObj.isNew = false;
            groupObj.save(saveGroupHandler(groupObj, callback));
        }
    });
}

function remove(id, callback) {
    logger.debug(context, 'Removing device group with id [%s]', id);

    getById(id, function (error, deviceGroup) {
        if (error) {
            callback(error);
        } else {
            Group.model.deleteOne({ _id: id }, function (error) {
                if (error) {
                    logger.debug(context, 'Internal MongoDB Error getting device: %s', error);

                    callback(new errors.InternalDbError(error));
                } else {
                    logger.debug(context, 'Device [%s] successfully removed.', id);
                    callback(null, deviceGroup);
                }
            });
        }
    });
}

function init(newConfig, callback) {
    callback(null);
}

function clear(callback) {
    dbService.db.db.dropDatabase(callback);
}

exports.create = alarmsInt(constants.MONGO_ALARM, intoTrans(context, createGroup));
exports.list = alarmsInt(constants.MONGO_ALARM, intoTrans(context, listGroups));
exports.init = alarmsInt(constants.MONGO_ALARM, intoTrans(context, init));
exports.find = alarmsInt(constants.MONGO_ALARM, intoTrans(context, find));
exports.findType = alarmsInt(
    constants.MONGO_ALARM,
    intoTrans(context, findBy(['service', 'subservice', 'type', 'apikey']))
);
exports.findTypeSilently = intoTrans(context, findBy(['service', 'subservice', 'type', 'apikey']));
exports.findBy = alarmsInt(constants.MONGO_ALARM, intoTrans(context, findBy));
exports.get = alarmsInt(constants.MONGO_ALARM, intoTrans(context, findBy(['resource', 'apikey'])));
exports.getSilently = intoTrans(context, findBy(['resource', 'apikey']));
exports.getType = alarmsInt(constants.MONGO_ALARM, intoTrans(context, findBy(['type'])));
exports.update = alarmsInt(constants.MONGO_ALARM, intoTrans(context, update));
exports.remove = alarmsInt(constants.MONGO_ALARM, intoTrans(context, remove));
exports.clear = alarmsInt(constants.MONGO_ALARM, intoTrans(context, clear));
<commit_msg>remove type from findTypeSilently<commit_after>/*
 * Copyright 2015 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of fiware-iotagent-lib
 *
 * fiware-iotagent-lib is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * fiware-iotagent-lib is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with fiware-iotagent-lib.
 * If not, see http://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::daniel.moranjimenez@telefonica.com
 *
 * Modified by: Daniel Calvo - ATOS Research & Innovation
 */

const logger = require('logops');
const dbService = require('../../model/dbConn');
const intoTrans = require('../common/domain').intoTrans;
const fillService = require('./../common/domain').fillService;
const alarmsInt = require('../common/alarmManagement').intercept;
const constants = require('../../constants');
const errors = require('../../errors');
const Group = require('../../model/Group');
const async = require('async');
let context = {
    op: 'IoTAgentNGSI.MongoDBGroupRegister'
};

const attributeList = [
    'url',
    'resource',
    'apikey',
    'type',
    'service',
    'subservice',
    'description',
    'trust',
    'cbHost',
    'timezone',
    'timestamp',
    'commands',
    'lazy',
    'attributes',
    'staticAttributes',
    'internalAttributes',
    'autoprovision',
    'explicitAttrs',
    'expressionLanguage',
    'defaultEntityNameConjunction',
    'ngsiVersion'
];

/**
 * Generates a handler for the save device group operations. The handler will take the customary error and the saved
 * device group as the parameters (and pass the serialized DAO as the callback value).
 *
 * @return {Function}       The generated handler.
 */
function saveGroupHandler(groupDAO, callback) {
    /* eslint-disable-next-line no-unused-vars */
    return function saveHandler(error, result) {
        if (error) {
            logger.debug(fillService(context, groupDAO), 'Error storing device group information: %s', error);

            callback(new errors.InternalDbError(error));
        } else {
            callback(null, groupDAO.toObject());
        }
    };
}

function createGroup(group, callback) {
    /* eslint-disable-next-line  new-cap */
    const groupObj = new Group.model();

    attributeList.forEach((key) => {
        groupObj[key] = group[key];
    });

    logger.debug(
        context,
        'Storing device group with id [%s], type [%s], apikey [%s] and resource [%s]',
        groupObj._id,
        groupObj.type,
        groupObj.apikey,
        groupObj.resource
    );

    groupObj.save(function saveHandler(error, groupDAO) {
        if (error) {
            if (error.code === 11000) {
                logger.debug(
                    context,
                    'Duplicate group entry with resource [%s] and apiKey [%s]',
                    group.resource,
                    group.apikey
                );

                callback(new errors.DuplicateGroup(group.resource, group.apikey));
            } else {
                logger.debug(context, 'Error storing device group information: %s', error);

                callback(new errors.InternalDbError(error));
            }
        } else {
            callback(null, groupDAO.toObject());
        }
    });
}

/**
 * List all the groups created in the IoT Agent.
 *
 * @param {Number} service      Service for wich all the configurations want to be retrieved.
 * @param {Number} limit        Maximum number of entries to return.
 * @param {Number} offset       Number of entries to skip for pagination.
 */
function listGroups(service, limit, offset, callback) {
    const condition = {};

    function toObjectFn(obj) {
        return obj.toObject();
    }

    if (service) {
        condition.service = service;
    }

    const query = Group.model.find(condition).sort();

    if (limit) {
        query.limit(parseInt(limit, 10));
    }

    if (offset) {
        query.skip(parseInt(offset, 10));
    }

    async.series([query.exec.bind(query), Group.model.countDocuments.bind(Group.model, condition)], function (
        error,
        results
    ) {
        callback(error, {
            count: results[1],
            services: results[0].map(toObjectFn)
        });
    });
}

function getById(id, callback) {
    context = fillService(context, { service: 'n/a', subservice: 'n/a' });
    logger.debug(context, 'Looking for device group with id [%s].', id);

    const query = Group.model.findOne({ _id: id });
    query.select({ __v: 0 });

    query.lean().exec(function handleGet(error, data) {
        if (error) {
            logger.debug(context, 'Internal MongoDB Error getting group: %s', error);

            callback(new errors.InternalDbError(error));
        } else if (data) {
            context = fillService(context, data);
            logger.debug(context, 'Device group data found: %j', data);
            callback(null, data);
        } else {
            logger.debug(context, 'Device group [%s] not found.', id);

            callback(new errors.DeviceGroupNotFound(id));
        }
    });
}

/**
 * List all the groups created in the IoT Agent for a service and a subservice.
 *
 * @param  {String} service        Service used to filter the groups.
 * @param  {String} subservice     Subservice used to filter the groups.
 * @param  {Function} callback     The callback function.
 */
function find(service, subservice, callback) {
    const condition = {};

    function toObjectFn(obj) {
        return obj.toObject();
    }

    condition.service = service;
    condition.subservice = subservice;

    const query = Group.model.find(condition).sort();

    async.series([query.exec.bind(query), Group.model.countDocuments.bind(Group.model, condition)], function (
        error,
        results
    ) {
        callback(error, {
            count: results[1],
            services: results[0].map(toObjectFn)
        });
    });
}

function findOneInMongoDB(queryObj, fields, callback) {
    const query = Group.model.findOne(queryObj);
    query.select({ __v: 0 });
    query.lean().exec(function handleGet(error, data) {
        if (error) {
            logger.debug(context, 'Internal MongoDB Error getting group: %s', error);
            callback(new errors.InternalDbError(error));
        } else if (data) {
            context = fillService(context, data);
            logger.debug(context, 'Device group data found: %j', data);
            callback(null, data);
        } else {
            logger.debug(context, 'Device group for fields [%j] not found: [%j]', fields, queryObj);
            callback(new errors.DeviceGroupNotFound(fields, queryObj));
        }
    });
}

function findBy(fields) {
    return function () {
        const queryObj = {};
        let i = 0;

        /* eslint-disable prefer-rest-params */
        while (typeof arguments[i] !== 'function') {
            if (arguments[i]) {
                queryObj[fields[i]] = arguments[i];
            }

            i++;
        }
        const callback = arguments[i];
        /* eslint-enable prefer-rest-params */

        context = fillService(context, { service: 'n/a', subservice: 'n/a' });
        logger.debug(context, 'Looking for group params %j with queryObj %j', fields, queryObj);
        findOneInMongoDB(queryObj, fields, callback);
    };
}

function update(id, body, callback) {
    logger.debug(context, 'Storing updated values for configuration [%s]:\n%s', id, JSON.stringify(body, null, 4));
    getById(id, function (error, group) {
        if (error) {
            callback(error);
        } else {
            attributeList.forEach((key) => {
                if (body[key] !== undefined) {
                    group[key] = body[key];
                }
            });
            /* eslint-disable-next-line  new-cap */
            const groupObj = new Group.model(group);
            groupObj.isNew = false;
            groupObj.save(saveGroupHandler(groupObj, callback));
        }
    });
}

function remove(id, callback) {
    logger.debug(context, 'Removing device group with id [%s]', id);

    getById(id, function (error, deviceGroup) {
        if (error) {
            callback(error);
        } else {
            Group.model.deleteOne({ _id: id }, function (error) {
                if (error) {
                    logger.debug(context, 'Internal MongoDB Error getting device: %s', error);

                    callback(new errors.InternalDbError(error));
                } else {
                    logger.debug(context, 'Device [%s] successfully removed.', id);
                    callback(null, deviceGroup);
                }
            });
        }
    });
}

function init(newConfig, callback) {
    callback(null);
}

function clear(callback) {
    dbService.db.db.dropDatabase(callback);
}

exports.create = alarmsInt(constants.MONGO_ALARM, intoTrans(context, createGroup));
exports.list = alarmsInt(constants.MONGO_ALARM, intoTrans(context, listGroups));
exports.init = alarmsInt(constants.MONGO_ALARM, intoTrans(context, init));
exports.find = alarmsInt(constants.MONGO_ALARM, intoTrans(context, find));
exports.findType = alarmsInt(
    constants.MONGO_ALARM,
    intoTrans(context, findBy(['service', 'subservice', 'type', 'apikey']))
);
exports.findTypeSilently = intoTrans(context, findBy(['service', 'subservice', 'apikey']));
exports.findBy = alarmsInt(constants.MONGO_ALARM, intoTrans(context, findBy));
exports.get = alarmsInt(constants.MONGO_ALARM, intoTrans(context, findBy(['resource', 'apikey'])));
exports.getSilently = intoTrans(context, findBy(['resource', 'apikey']));
exports.getType = alarmsInt(constants.MONGO_ALARM, intoTrans(context, findBy(['type'])));
exports.update = alarmsInt(constants.MONGO_ALARM, intoTrans(context, update));
exports.remove = alarmsInt(constants.MONGO_ALARM, intoTrans(context, remove));
exports.clear = alarmsInt(constants.MONGO_ALARM, intoTrans(context, clear));
<|endoftext|>


<commit_before>// Portfolio Site Show-and-Tell, Lab session

var request = require('request');
var async = require('async');
var calculateScore = require('../calculateScore.js');

module.exports = function(url, cb) {
	if (!url) {
		return cb("URL not found");
	}
	var tests = [{
		description: "submitted URL was accessible from the internet",
		assert: function(url, cb) {
			request(url, function(error, response) {
				if (!error && response.statusCode == 200) {
					this.passed = true;
					cb(null, this);
				} else {
					this.passed = false;
					cb(null, this);
				}
			}.bind(this));
		}
	}];

	async.map(tests, function(test, cb) {
		test.assert(url, cb);
	}, function() {
		for (var test of tests) {
			delete test.assert;
		}
		var scoreObject = {
			score: calculateScore(tests),
			tests: tests,
			url: url
		};
		return cb(null, scoreObject);
	});
};

// var request = require('request');
// var async = require('async');
// var jsdom = require("jsdom");
//
// // - an element with a `background-position`
// // - an element with a `background-size`
// // - an element with a `background-image`
// // - an element with `margin: auto`
// // - an element with `text-align: center`
// // - an element with `display: flex`
//
//
// module.exports = function(url, cb) {
// 	if (!url) {
// 		return cb("URL not found");
// 	}
// 	tests = [{
// 		description: "submitted URL was accessible from the internet",
// 		assert: function(url, cb) {
// 			request(url, function(error, response, body) {
// 				if (!error && response.statusCode == 200) {
// 					this.passed = true;
// 					cb(null, this);
// 				} else {
// 					this.passed = false;
// 					cb(null, this);
// 				}
// 			}.bind(this));
// 		}
// 	}];
//
// 	backgroundStyles = ['background-position', 'background-size', 'background-image'];
//
// 	for (backgroundStyle of backgroundStyles) {
// 		tests.push({
// 			backgroundStyle: backgroundStyle,
// 			description: 'site has an element with a `' + backgroundStyle + '`',
// 			assert: function(url, cb) {
// 				request(url, function(error, response, body) {
// 					if (!error && response.statusCode == 200) {
// 						jsdom.env(body, {
// 							url: url,
// 							features: {
// 								FetchExternalResources: ["link", "css"]
// 							},
// 							done: function(err, window) {
// 								elements = window.document.getElementsByTagName('*');
// 								for (element of elements) {
// 									if (this.backgroundStyle in window.getComputedStyle(element)) {
// 										this.passed = true;
// 										return cb(null, this);
// 									}
// 								}
// 								this.passed = false;
// 								return cb(null, this);
// 							}.bind(this)
// 						});
// 					} else {
// 						this.passed = false;
// 						cb(null, this);
// 					}
// 				}.bind(this));
// 			}
// 		});
// 	}
//
// 	tests.push({
// 		description: 'site has an element with `margin: auto`',
// 		assert: function(url, cb) {
// 			request(url, function(error, response, body) {
// 				if (!error && response.statusCode == 200) {
// 					jsdom.env(body, {
// 						url: url,
// 						features: {
// 							FetchExternalResources: ["link", "css"]
// 						},
// 						done: function(err, window) {
// 							elements = window.document.getElementsByTagName('*');
// 							for (element of elements) {
// 								if (
// 									(window.getComputedStyle(element)["margin-top"] == "auto") &&
// 									(window.getComputedStyle(element)["margin-right"] == "auto") &&
// 									(window.getComputedStyle(element)["margin-bottom"] == "auto") &&
// 									(window.getComputedStyle(element)["margin-left"] == "auto")) {
// 									this.passed = true;
// 									return cb(null, this);
// 								}
// 							}
// 							this.passed = false;
// 							return cb(null, this);
// 						}.bind(this)
// 					});
// 				} else {
// 					this.passed = false;
// 					cb(null, this);
// 				}
// 			}.bind(this));
// 		}
// 	}, {
// 		description: 'site has an element with `text-align: center`',
// 		assert: function(url, cb) {
// 			request(url, function(error, response, body) {
// 				if (!error && response.statusCode == 200) {
// 					jsdom.env(body, {
// 						url: url,
// 						features: {
// 							FetchExternalResources: ["link", "css"]
// 						},
// 						done: function(err, window) {
// 							elements = window.document.getElementsByTagName('*');
// 							for (element of elements) {
// 								if (window.getComputedStyle(element)["text-align"] == "center") {
// 									this.passed = true;
// 									return cb(null, this);
// 								}
// 							}
// 							this.passed = false;
// 							return cb(null, this);
// 						}.bind(this)
// 					});
// 				} else {
// 					this.passed = false;
// 					cb(null, this);
// 				}
// 			}.bind(this));
// 		}
// 	}, {
// 		description: 'site has an element with `display: flex`',
// 		assert: function(url, cb) {
// 			request(url, function(error, response, body) {
// 				if (!error && response.statusCode == 200) {
// 					jsdom.env(body, {
// 						url: url,
// 						features: {
// 							FetchExternalResources: ["link", "css"]
// 						},
// 						done: function(err, window) {
// 							elements = window.document.getElementsByTagName('*');
// 							for (element of elements) {
// 								if (window.getComputedStyle(element)["display"] == "flex") {
// 									this.passed = true;
// 									return cb(null, this);
// 								}
// 							}
// 							this.passed = false;
// 							return cb(null, this);
// 						}.bind(this)
// 					});
// 				} else {
// 					this.passed = false;
// 					cb(null, this);
// 				}
// 			}.bind(this));
// 		}
// 	});
//
// 	async.map(tests, function(test, cb) {
// 		test.assert(url, cb);
// 	}, function(err, results) {
// 		for (test of tests) {
// 			delete test.assert;
// 		}
// 		scoreObject = {
// 			score: calculateScore(tests),
// 			tests: tests
// 		};
// 		return cb(null, scoreObject);
// 	});
// };
<commit_msg>cleaning up whitespace<commit_after>// Portfolio Site Show-and-Tell, Lab session

var request = require('request');
var async = require('async');
var calculateScore = require('../calculateScore.js');

module.exports = function(url, cb) {
	if (!url) {
		return cb("URL not found");
	}
	var tests = [{
		description: "submitted URL was accessible from the internet",
		assert: function(url, cb) {
			request(url, function(error, response) {
				if (!error && response.statusCode == 200) {
					this.passed = true;
					cb(null, this);
				} else {
					this.passed = false;
					cb(null, this);
				}
			}.bind(this));
		}
	}];
	async.map(tests, function(test, cb) {
		test.assert(url, cb);
	}, function() {
		for (var test of tests) {
			delete test.assert;
		}
		var scoreObject = {
			score: calculateScore(tests),
			tests: tests,
			url: url
		};
		return cb(null, scoreObject);
	});
};

// var request = require('request');
// var async = require('async');
// var jsdom = require("jsdom");
//
// // - an element with a `background-position`
// // - an element with a `background-size`
// // - an element with a `background-image`
// // - an element with `margin: auto`
// // - an element with `text-align: center`
// // - an element with `display: flex`
//
//
// module.exports = function(url, cb) {
// 	if (!url) {
// 		return cb("URL not found");
// 	}
// 	tests = [{
// 		description: "submitted URL was accessible from the internet",
// 		assert: function(url, cb) {
// 			request(url, function(error, response, body) {
// 				if (!error && response.statusCode == 200) {
// 					this.passed = true;
// 					cb(null, this);
// 				} else {
// 					this.passed = false;
// 					cb(null, this);
// 				}
// 			}.bind(this));
// 		}
// 	}];
//
// 	backgroundStyles = ['background-position', 'background-size', 'background-image'];
//
// 	for (backgroundStyle of backgroundStyles) {
// 		tests.push({
// 			backgroundStyle: backgroundStyle,
// 			description: 'site has an element with a `' + backgroundStyle + '`',
// 			assert: function(url, cb) {
// 				request(url, function(error, response, body) {
// 					if (!error && response.statusCode == 200) {
// 						jsdom.env(body, {
// 							url: url,
// 							features: {
// 								FetchExternalResources: ["link", "css"]
// 							},
// 							done: function(err, window) {
// 								elements = window.document.getElementsByTagName('*');
// 								for (element of elements) {
// 									if (this.backgroundStyle in window.getComputedStyle(element)) {
// 										this.passed = true;
// 										return cb(null, this);
// 									}
// 								}
// 								this.passed = false;
// 								return cb(null, this);
// 							}.bind(this)
// 						});
// 					} else {
// 						this.passed = false;
// 						cb(null, this);
// 					}
// 				}.bind(this));
// 			}
// 		});
// 	}
//
// 	tests.push({
// 		description: 'site has an element with `margin: auto`',
// 		assert: function(url, cb) {
// 			request(url, function(error, response, body) {
// 				if (!error && response.statusCode == 200) {
// 					jsdom.env(body, {
// 						url: url,
// 						features: {
// 							FetchExternalResources: ["link", "css"]
// 						},
// 						done: function(err, window) {
// 							elements = window.document.getElementsByTagName('*');
// 							for (element of elements) {
// 								if (
// 									(window.getComputedStyle(element)["margin-top"] == "auto") &&
// 									(window.getComputedStyle(element)["margin-right"] == "auto") &&
// 									(window.getComputedStyle(element)["margin-bottom"] == "auto") &&
// 									(window.getComputedStyle(element)["margin-left"] == "auto")) {
// 									this.passed = true;
// 									return cb(null, this);
// 								}
// 							}
// 							this.passed = false;
// 							return cb(null, this);
// 						}.bind(this)
// 					});
// 				} else {
// 					this.passed = false;
// 					cb(null, this);
// 				}
// 			}.bind(this));
// 		}
// 	}, {
// 		description: 'site has an element with `text-align: center`',
// 		assert: function(url, cb) {
// 			request(url, function(error, response, body) {
// 				if (!error && response.statusCode == 200) {
// 					jsdom.env(body, {
// 						url: url,
// 						features: {
// 							FetchExternalResources: ["link", "css"]
// 						},
// 						done: function(err, window) {
// 							elements = window.document.getElementsByTagName('*');
// 							for (element of elements) {
// 								if (window.getComputedStyle(element)["text-align"] == "center") {
// 									this.passed = true;
// 									return cb(null, this);
// 								}
// 							}
// 							this.passed = false;
// 							return cb(null, this);
// 						}.bind(this)
// 					});
// 				} else {
// 					this.passed = false;
// 					cb(null, this);
// 				}
// 			}.bind(this));
// 		}
// 	}, {
// 		description: 'site has an element with `display: flex`',
// 		assert: function(url, cb) {
// 			request(url, function(error, response, body) {
// 				if (!error && response.statusCode == 200) {
// 					jsdom.env(body, {
// 						url: url,
// 						features: {
// 							FetchExternalResources: ["link", "css"]
// 						},
// 						done: function(err, window) {
// 							elements = window.document.getElementsByTagName('*');
// 							for (element of elements) {
// 								if (window.getComputedStyle(element)["display"] == "flex") {
// 									this.passed = true;
// 									return cb(null, this);
// 								}
// 							}
// 							this.passed = false;
// 							return cb(null, this);
// 						}.bind(this)
// 					});
// 				} else {
// 					this.passed = false;
// 					cb(null, this);
// 				}
// 			}.bind(this));
// 		}
// 	});
//
// 	async.map(tests, function(test, cb) {
// 		test.assert(url, cb);
// 	}, function(err, results) {
// 		for (test of tests) {
// 			delete test.assert;
// 		}
// 		scoreObject = {
// 			score: calculateScore(tests),
// 			tests: tests
// 		};
// 		return cb(null, scoreObject);
// 	});
// };
<|endoftext|>


<commit_before>var bcoin = require('../../bcoin');
var constants = require('./constants');
var utils = bcoin.utils;
var assert = utils.assert;

var writeU32 = utils.writeU32;
var writeAscii = utils.writeAscii;

function Framer() {
  if (!(this instanceof Framer))
    return new Framer();
}
module.exports = Framer;

Framer.prototype.header = function header(cmd, payload) {
  assert(cmd.length < 12);
  assert(payload.length <= 0xffffffff);

  var h = new Array(24);

  // Magic value
  writeU32(h, constants.magic, 0);

  // Command
  var len = writeAscii(h, cmd, 4);
  for (var i = 4 + len; i < 4 + 12; i++)
    h[i] = 0;

  // Payload length
  writeU32(h, payload.length, 16);

  // Checksum
  utils.copy(utils.checksum(payload), h, 20);

  return h;
};

Framer.prototype.packet = function packet(cmd, payload) {
  var h = this.header(cmd, payload);
  return h.concat(payload);
};

Framer.prototype._addr = function addr(buf, off) {
  writeU32(buf, 1, off);
  writeU32(buf, 0, off + 4);
  writeU32(buf, 0, off + 8);
  writeU32(buf, 0, off + 12);
  writeU32(buf, 0xffff0000, off + 16);
  writeU32(buf, 0, off + 20);
  buf[off + 24] = 0;
  buf[off + 25] = 0;
};

Framer.prototype.version = function version(packet) {
  var p = new Array(86);

  if (!packet)
    packet = {};

  // Version
  writeU32(p, constants.version, 0);

  // Services
  writeU32(p, constants.services.network, 4);
  writeU32(p, 0, 8);

  // Timestamp
  var ts = ((+new Date()) / 1000) | 0;
  writeU32(p, ts, 12);
  writeU32(p, 0, 16);

  // Remote and local addresses
  this._addr(p, 20);
  this._addr(p, 46);

  // Nonce, very dramatic
  writeU32(p, (Math.random() * 0xffffffff) | 0, 72);
  writeU32(p, (Math.random() * 0xffffffff) | 0, 76);

  // No user-agent
  p[80] = 0;

  // Start height
  writeU32(p, packet.height, 81);

  // Relay
  p[85] = packet.relay ? 1 : 0;

  return this.packet('version', p);
};

Framer.prototype.verack = function verack() {
  return this.packet('verack', []);
};

function varint(arr, value, off) {
  if (!off)
    off = 0;
  if (value < 0xfd) {
    arr[off] = value;
    return 1;
  } else if (value <= 0xffff) {
    arr[off] = 0xfd;
    arr[off + 1] = value & 0xff;
    arr[off + 2] = value >>> 8;
    return 3;
  } else if (value <= 0xffffffff) {
    arr[off] = 0xfd;
    arr[off + 3] = value & 0xff;
    arr[off + 4] = (value >>> 8) & 0xff;
    arr[off + 5] = (value >>> 16) & 0xff;
    arr[off + 6] = value >>> 24;
    return 5;
  } else {
    throw new Error('64bit varint not supported yet');
  }
}

Framer.prototype._inv = function _inv(command, items) {
  var res = [];
  var off = varint(res, items.length, 0);
  assert(items.length <= 50000);

  for (var i = 0; i < items.length; i++) {
    // Type
    off += writeU32(res, constants.inv[items[i].type], off);

    // Hash
    var hash = items[i].hash;
    if (typeof hash === 'string')
      hash = utils.toArray(hash, 'hex');
    assert.equal(hash.length, 32);
    res = res.concat(hash);

    off += hash.length;
  }

  return this.packet(command, res);
};

Framer.prototype.inv = function inv(items) {
  return this._inv('inv', items);
};

Framer.prototype.getData = function getData(items) {
  return this._inv('getdata', items);
};

Framer.prototype.notFound = function notFound(items) {
  return this._inv('notfound', items);
};

Framer.prototype.ping = function ping(nonce) {
  return this.packet('ping', nonce);
};

Framer.prototype.pong = function pong(nonce) {
  return this.packet('pong', nonce.slice(0, 8));
};

Framer.prototype.filterLoad = function filterLoad(bloom, update) {
  var filter = bloom.toArray();
  var before = [];
  varint(before, filter.length, 0);

  var after = new Array(9);

  // Number of hash functions
  writeU32(after, bloom.n, 0);

  // nTweak
  writeU32(after, bloom.tweak, 4);

  // nFlags
  after[8] = constants.filterFlags[update];

  var r = this.packet('filterload', before.concat(filter, after));
  return r;
};

Framer.prototype.filterClear = function filterClear() {
  return this.packet('filterclear', []);
};

Framer.prototype.getBlocks = function getBlocks(hashes, stop) {
  var p = [];
  writeU32(p, constants.version, 0);
  var off = 4 + varint(p, hashes.length, 4);
  p.length = off + 32 * (hashes.length + 1);

  for (var i = 0; i < hashes.length; i++) {
    var hash = hashes[i];
    if (typeof hash === 'string')
      hash = utils.toArray(hash, 'hex');
    var len = utils.copy(hash, p, off);
    for (; len < 32; len++)
      p[off + len] = 0;
    off += len;
  }

  if (stop) {
    stop = utils.toArray(stop, 'hex');
    var len = utils.copy(stop, p, off);
  } else {
    var len = 0;
  }
  for (; len < 32; len++)
    p[off + len] = 0;
  assert.equal(off + len, p.length);

  return this.packet('getblocks', p);
};

Framer.tx = function tx(tx) {
  var p = [];
  var off = writeU32(p, tx.version, 0);
  off += varint(p, tx.inputs.length, off);

  for (var i = 0; i < tx.inputs.length; i++) {
    var input = tx.inputs[i];

    off += utils.copy(utils.toArray(input.out.hash, 'hex'), p, off, true);
    off += writeU32(p, input.out.index, off);

    var s = bcoin.script.encode(input.script);
    off += varint(p, s.length, off);
    off += utils.copy(s, p, off, true);

    off += writeU32(p, input.seq, off);
  }

  off += varint(p, tx.outputs.length, off);
  for (var i = 0; i < tx.outputs.length; i++) {
    var output = tx.outputs[i];

    // Put LE value
    var value = output.value.toArray().slice().reverse();
    assert(value.length <= 8);
    off += utils.copy(value, p, off, true);
    for (var j = value.length; j < 8; j++, off++)
      p[off] = 0;

    var s = bcoin.script.encode(output.script);
    off += varint(p, s.length, off);
    off += utils.copy(s, p, off, true);
  }
  off += writeU32(p, tx.lock, off);

  return p;
};

Framer.prototype.tx = function tx(tx) {
  return this.packet('tx', Framer.tx(tx));
};

Framer.block = function _block(block, type) {
  var p = [];
  var off = 0;

  off += writeU32(p, constants.version, off);

  // prev_block
  util.toArray(block.prevBlock, 'hex').forEach(function(ch) {
    p[off++] = ch;
  });

  // merkle_root
  util.toArray(block.merkleRoot, 'hex').forEach(function(ch) {
    p[off++] = ch;
  });

  // timestamp
  off += writeU32(p, block.ts, off);

  // bits
  off += writeU32(p, block.bits, off);

  // nonce
  off += writeU32(p, block.nonce, off);

  // txn_count
  off += varint(p, block.totalTX, off);

  if (type === 'merkleblock') {
    // hash count
    off += varint(p, block.hashes.length, off);
    // hashes
    block.hashes.forEach(function(hash) {
      utils.toArray(hash, 'hex').forEach(function(ch) {
        p[off++] = ch;
      });
    });
    // flag count
    off += varint(p, block.flags.length, off);
    // flags
    block.flags.forEach(function(flag) {
      p[off++] = flag;
    });
  }

  return p;
};

Framer.prototype.block = function _block(block) {
  return this.packet(Framer.block(block, 'block'));
};

Framer.prototype.merkleBlock = function merkleBlock(block) {
  // XXX Technically we're also supposed to send `tx` packets accompanying the
  // merkleblock here if we have them, as per the offical bitcoin client.
  return this.packet(Framer.block(block, 'merkleblock'));
};
<commit_msg>framer: fix typo.<commit_after>var bcoin = require('../../bcoin');
var constants = require('./constants');
var utils = bcoin.utils;
var assert = utils.assert;

var writeU32 = utils.writeU32;
var writeAscii = utils.writeAscii;

function Framer() {
  if (!(this instanceof Framer))
    return new Framer();
}
module.exports = Framer;

Framer.prototype.header = function header(cmd, payload) {
  assert(cmd.length < 12);
  assert(payload.length <= 0xffffffff);

  var h = new Array(24);

  // Magic value
  writeU32(h, constants.magic, 0);

  // Command
  var len = writeAscii(h, cmd, 4);
  for (var i = 4 + len; i < 4 + 12; i++)
    h[i] = 0;

  // Payload length
  writeU32(h, payload.length, 16);

  // Checksum
  utils.copy(utils.checksum(payload), h, 20);

  return h;
};

Framer.prototype.packet = function packet(cmd, payload) {
  var h = this.header(cmd, payload);
  return h.concat(payload);
};

Framer.prototype._addr = function addr(buf, off) {
  writeU32(buf, 1, off);
  writeU32(buf, 0, off + 4);
  writeU32(buf, 0, off + 8);
  writeU32(buf, 0, off + 12);
  writeU32(buf, 0xffff0000, off + 16);
  writeU32(buf, 0, off + 20);
  buf[off + 24] = 0;
  buf[off + 25] = 0;
};

Framer.prototype.version = function version(packet) {
  var p = new Array(86);

  if (!packet)
    packet = {};

  // Version
  writeU32(p, constants.version, 0);

  // Services
  writeU32(p, constants.services.network, 4);
  writeU32(p, 0, 8);

  // Timestamp
  var ts = ((+new Date()) / 1000) | 0;
  writeU32(p, ts, 12);
  writeU32(p, 0, 16);

  // Remote and local addresses
  this._addr(p, 20);
  this._addr(p, 46);

  // Nonce, very dramatic
  writeU32(p, (Math.random() * 0xffffffff) | 0, 72);
  writeU32(p, (Math.random() * 0xffffffff) | 0, 76);

  // No user-agent
  p[80] = 0;

  // Start height
  writeU32(p, packet.height, 81);

  // Relay
  p[85] = packet.relay ? 1 : 0;

  return this.packet('version', p);
};

Framer.prototype.verack = function verack() {
  return this.packet('verack', []);
};

function varint(arr, value, off) {
  if (!off)
    off = 0;
  if (value < 0xfd) {
    arr[off] = value;
    return 1;
  } else if (value <= 0xffff) {
    arr[off] = 0xfd;
    arr[off + 1] = value & 0xff;
    arr[off + 2] = value >>> 8;
    return 3;
  } else if (value <= 0xffffffff) {
    arr[off] = 0xfd;
    arr[off + 3] = value & 0xff;
    arr[off + 4] = (value >>> 8) & 0xff;
    arr[off + 5] = (value >>> 16) & 0xff;
    arr[off + 6] = value >>> 24;
    return 5;
  } else {
    throw new Error('64bit varint not supported yet');
  }
}

Framer.prototype._inv = function _inv(command, items) {
  var res = [];
  var off = varint(res, items.length, 0);
  assert(items.length <= 50000);

  for (var i = 0; i < items.length; i++) {
    // Type
    off += writeU32(res, constants.inv[items[i].type], off);

    // Hash
    var hash = items[i].hash;
    if (typeof hash === 'string')
      hash = utils.toArray(hash, 'hex');
    assert.equal(hash.length, 32);
    res = res.concat(hash);

    off += hash.length;
  }

  return this.packet(command, res);
};

Framer.prototype.inv = function inv(items) {
  return this._inv('inv', items);
};

Framer.prototype.getData = function getData(items) {
  return this._inv('getdata', items);
};

Framer.prototype.notFound = function notFound(items) {
  return this._inv('notfound', items);
};

Framer.prototype.ping = function ping(nonce) {
  return this.packet('ping', nonce);
};

Framer.prototype.pong = function pong(nonce) {
  return this.packet('pong', nonce.slice(0, 8));
};

Framer.prototype.filterLoad = function filterLoad(bloom, update) {
  var filter = bloom.toArray();
  var before = [];
  varint(before, filter.length, 0);

  var after = new Array(9);

  // Number of hash functions
  writeU32(after, bloom.n, 0);

  // nTweak
  writeU32(after, bloom.tweak, 4);

  // nFlags
  after[8] = constants.filterFlags[update];

  var r = this.packet('filterload', before.concat(filter, after));
  return r;
};

Framer.prototype.filterClear = function filterClear() {
  return this.packet('filterclear', []);
};

Framer.prototype.getBlocks = function getBlocks(hashes, stop) {
  var p = [];
  writeU32(p, constants.version, 0);
  var off = 4 + varint(p, hashes.length, 4);
  p.length = off + 32 * (hashes.length + 1);

  for (var i = 0; i < hashes.length; i++) {
    var hash = hashes[i];
    if (typeof hash === 'string')
      hash = utils.toArray(hash, 'hex');
    var len = utils.copy(hash, p, off);
    for (; len < 32; len++)
      p[off + len] = 0;
    off += len;
  }

  if (stop) {
    stop = utils.toArray(stop, 'hex');
    var len = utils.copy(stop, p, off);
  } else {
    var len = 0;
  }
  for (; len < 32; len++)
    p[off + len] = 0;
  assert.equal(off + len, p.length);

  return this.packet('getblocks', p);
};

Framer.tx = function tx(tx) {
  var p = [];
  var off = writeU32(p, tx.version, 0);
  off += varint(p, tx.inputs.length, off);

  for (var i = 0; i < tx.inputs.length; i++) {
    var input = tx.inputs[i];

    off += utils.copy(utils.toArray(input.out.hash, 'hex'), p, off, true);
    off += writeU32(p, input.out.index, off);

    var s = bcoin.script.encode(input.script);
    off += varint(p, s.length, off);
    off += utils.copy(s, p, off, true);

    off += writeU32(p, input.seq, off);
  }

  off += varint(p, tx.outputs.length, off);
  for (var i = 0; i < tx.outputs.length; i++) {
    var output = tx.outputs[i];

    // Put LE value
    var value = output.value.toArray().slice().reverse();
    assert(value.length <= 8);
    off += utils.copy(value, p, off, true);
    for (var j = value.length; j < 8; j++, off++)
      p[off] = 0;

    var s = bcoin.script.encode(output.script);
    off += varint(p, s.length, off);
    off += utils.copy(s, p, off, true);
  }
  off += writeU32(p, tx.lock, off);

  return p;
};

Framer.prototype.tx = function tx(tx) {
  return this.packet('tx', Framer.tx(tx));
};

Framer.block = function _block(block, type) {
  var p = [];
  var off = 0;

  off += writeU32(p, constants.version, off);

  // prev_block
  utils.toArray(block.prevBlock, 'hex').forEach(function(ch) {
    p[off++] = ch;
  });

  // merkle_root
  utils.toArray(block.merkleRoot, 'hex').forEach(function(ch) {
    p[off++] = ch;
  });

  // timestamp
  off += writeU32(p, block.ts, off);

  // bits
  off += writeU32(p, block.bits, off);

  // nonce
  off += writeU32(p, block.nonce, off);

  // txn_count
  off += varint(p, block.totalTX, off);

  if (type === 'merkleblock') {
    // hash count
    off += varint(p, block.hashes.length, off);
    // hashes
    block.hashes.forEach(function(hash) {
      utils.toArray(hash, 'hex').forEach(function(ch) {
        p[off++] = ch;
      });
    });
    // flag count
    off += varint(p, block.flags.length, off);
    // flags
    block.flags.forEach(function(flag) {
      p[off++] = flag;
    });
  }

  return p;
};

Framer.prototype.block = function _block(block) {
  return this.packet(Framer.block(block, 'block'));
};

Framer.prototype.merkleBlock = function merkleBlock(block) {
  // XXX Technically we're also supposed to send `tx` packets accompanying the
  // merkleblock here if we have them, as per the offical bitcoin client.
  return this.packet(Framer.block(block, 'merkleblock'));
};
<|endoftext|>


<commit_before>var winston = require('winston');
var dbPath = require('../config').DbPath;
// var dbPath =  process.env.MONGOLAB_URI;
var os = require('os');
require('winston-mongodb').MongoDB;
var logger = new (winston.Logger)({
    transports: [
        new (winston.transports.Console)({
            json: true,
            colorize: true,
            level: 'error',
            handleExceptions: true
        }),
        new (winston.transports.MongoDB)({
            db: dbPath,
            level: 'info', //会记录info、warn、error3个级别的日志
            handleExceptions: true
        })
    ],
    exitOnError: false
});

/**
 * 记录错误日志
 * @param req 请求对象
 * @param err 错误对象
 */
exports.errLogger = function (req, err) {
    var obj = {},
        message = err.message;
    obj.process = {
        pid: process.pid,
        uid: process.getuid ? process.getuid() : null,
        gid: process.getgid ? process.getgid() : null,
        cwd: process.cwd(),
        execPath: process.execPath,
        version: process.version,
        argv: process.argv,
        memoryUsage: process.memoryUsage()
    };
    obj.os = {
        hostname: os.hostname(),
        loadavg: os.loadavg(),
        uptime: os.uptime()
    };
    obj.stack = err.stack && err.stack.split('\n');
    obj.code = err.status || 500;
    var query = {};
    for (var q in req.query) {
        query[q] = req.query[q];
    }
    obj.req = {
        baseUrl: req.baseUrl,
        originalUrl: req.originalUrl,
        query: query,
        body: req.body,
        ip: req.ip,
        route: req.route
    };
    if (!message && obj.code === 404) {
        message = 'not fount "' + req.originalUrl + '"';
    }
    logger.error(message, obj);
};
<commit_msg>found写成fount了。<commit_after>var winston = require('winston');
var dbPath = require('../config').DbPath;
// var dbPath =  process.env.MONGOLAB_URI;
var os = require('os');
require('winston-mongodb').MongoDB;
var logger = new (winston.Logger)({
    transports: [
        new (winston.transports.Console)({
            json: true,
            colorize: true,
            level: 'error',
            handleExceptions: true
        }),
        new (winston.transports.MongoDB)({
            db: dbPath,
            level: 'info', //会记录info、warn、error3个级别的日志
            handleExceptions: true
        })
    ],
    exitOnError: false
});

/**
 * 记录错误日志
 * @param req 请求对象
 * @param err 错误对象
 */
exports.errLogger = function (req, err) {
    var obj = {},
        message = err.message;
    obj.process = {
        pid: process.pid,
        uid: process.getuid ? process.getuid() : null,
        gid: process.getgid ? process.getgid() : null,
        cwd: process.cwd(),
        execPath: process.execPath,
        version: process.version,
        argv: process.argv,
        memoryUsage: process.memoryUsage()
    };
    obj.os = {
        hostname: os.hostname(),
        loadavg: os.loadavg(),
        uptime: os.uptime()
    };
    obj.stack = err.stack && err.stack.split('\n');
    obj.code = err.status || 500;
    var query = {};
    for (var q in req.query) {
        query[q] = req.query[q];
    }
    obj.req = {
        baseUrl: req.baseUrl,
        originalUrl: req.originalUrl,
        query: query,
        body: req.body,
        ip: req.ip,
        route: req.route
    };
    if (!message && obj.code === 404) {
        message = 'not found "' + req.originalUrl + '"';
    }
    logger.error(message, obj);
};
<|endoftext|>