<commit_before>"use strict";

var Key = require('./Key');
var KJUR = require('jsrsasign');
var assert = require('assert');
var PayPro = require('../common/PayPro');
var RootCerts = require('../common/RootCerts');

var asn1 = require('asn1.js');
var rfc3280 = require('asn1.js/rfc/3280');

// Documentation:
// http://kjur.github.io/jsrsasign/api/symbols/KJUR.crypto.Signature.html#.sign
// http://kjur.github.io/jsrsasign/api/symbols/RSAKey.html

PayPro.prototype.x509Sign = function(key, returnTrust) {
  var pki_type = this.get('pki_type');
  var pki_data = this.get('pki_data'); // contains one or more x509 certs
  pki_data = PayPro.X509Certificates.decode(pki_data);
  pki_data = pki_data.certificate;
  var type = pki_type.split('+')[1].toUpperCase();
  var buf = this.serializeForSig();

  var rsa = new KJUR.RSAKey();
  rsa.readPrivateKeyFromPEMString(key.toString());
  key = rsa;

  var jsrsaSig = new KJUR.crypto.Signature({
    alg: type + 'withRSA',
    prov: 'cryptojs/jsrsa'
  });

  jsrsaSig.init(key);

  jsrsaSig.updateHex(buf.toString('hex'));

  var sig = new Buffer(jsrsaSig.sign(), 'hex');

  if (returnTrust) {
    var cert = pki_data[pki_data.length - 1];
    var der = cert.toString('hex');
    var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE');
    var caName = RootCerts.getTrusted(pem);
    var selfSigned = 0;
    if (!caName) {
      selfSigned = pki_data.length > 1
        ? -1
        : 1;
    }
    return {
      selfSigned: selfSigned,
      isChain: pki_data.length > 1,
      signature: sig,
      caTrusted: !!caName,
      caName: caName || null
    };
  }

  return sig;
};

PayPro.prototype.x509Verify = function(returnTrust) {
  var sig = this.get('signature');
  var pki_type = this.get('pki_type');
  var pki_data = this.get('pki_data');
  pki_data = PayPro.X509Certificates.decode(pki_data);
  pki_data = pki_data.certificate;
  var buf = this.serializeForSig();
  var type = pki_type.split('+')[1].toUpperCase();

  var jsrsaSig = new KJUR.crypto.Signature({
    alg: type + 'withRSA',
    prov: 'cryptojs/jsrsa'
  });

  var signedCert = pki_data[0];
  var der = signedCert.toString('hex');
  // var pem = self._DERtoPEM(der, 'CERTIFICATE');
  var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE');
  jsrsaSig.initVerifyByCertificatePEM(pem);
  jsrsaSig.updateHex(buf.toString('hex'));
  var verified = jsrsaSig.verify(sig.toString('hex'));

  var chain = pki_data;

  //
  // Get the CA cert's name
  //
  var issuer = chain[chain.length - 1];
  der = issuer.toString('hex');
  // pem = this._DERtoPEM(der, 'CERTIFICATE');
  pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE');
  var caName = RootCerts.getTrusted(pem);

  if (chain.length === 1 && !caName) {
    if (returnTrust) {
      return {
        selfSigned: 1, // yes
        isChain: false,
        verified: verified,
        caTrusted: false,
        caName: null,
        chainVerified: false
      };
    }
    return verified;
  }

  // If there's no trusted root cert, don't
  // bother validating the cert chain.
  if (!caName) {
    if (returnTrust) {
      return {
        selfSigned: -1, // unknown
        isChain: chain.length > 1,
        verified: verified,
        caTrusted: false,
        caName: null,
        chainVerified: false
      };
    }
    return verified;
  }

  var chainVerified = chain.every(function(cert, i) {
    var der = cert.toString('hex');
    // var pem = self._DERtoPEM(der, 'CERTIFICATE');
    var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE');
    var name = RootCerts.getTrusted(pem);

    var ncert = chain[i + 1];
    // The root cert, check if it's trusted:
    if (!ncert || name) {
      if (!name) {
        return false;
      }
      chain.length = 0;
      return true;
    }
    var nder = ncert.toString('hex');
    // var npem = self._DERtoPEM(nder, 'CERTIFICATE');
    var npem = KJUR.asn1.ASN1Util.getPEMStringFromHex(nder, 'CERTIFICATE');

    //
    // Get Public Key from next certificate (via KJUR because it's a mess):
    //
    var js = new KJUR.crypto.Signature({
      alg: type + 'withRSA',
      prov: 'cryptojs/jsrsa'
    });
    js.initVerifyByCertificatePEM(npem);
    var npubKey = js.pubKey;

    //
    // Get Signature Value from current certificate:
    //
    var data = new Buffer(der, 'hex');
    var c = rfc3280.Certificate.decode(data, 'der');
    var sigAlg = PayPro.getAlgorithm(c.signatureAlgorithm.algorithm, 1);
    var sig = c.signature.data;

    //
    // Check Validity of Certificates
    //
    var validityVerified = PayPro.validateCertTime(c, nc);

    //
    // Check the Issuer matches the Subject of the next certificate:
    //
    var issuerVerified = PayPro.validateCertIssuer(c, nc);

    //
    // Verify current Certificate signature
    //

    var jsrsaSig = new KJUR.crypto.Signature({
      alg: type + 'withRSA',
      prov: 'cryptojs/jsrsa'
    });
    jsrsaSig.initVerifyByPublicKey(npubKey);

    // Get the raw DER TBSCertificate
    // from the DER Certificate:
    var tbs = PayPro.getTBSCertificate(data);

    jsrsaSig.updateHex(tbs.toString('hex'));

    var sigVerified = jsrsaSig.verify(sig.toString('hex'));

    return validityVerified
      && issuerVerified
      && sigVerified;
  });

  if (returnTrust) {
    return {
      selfSigned: 0, // no
      isChain: true,
      verified: verified,
      caTrusted: !!caName,
      caName: caName || null,
      chainVerified: chainVerified
    };
  }

  return verified && chainVerified;
};

module.exports = PayPro;
<commit_msg>paypro: fix uncatchable error in browser paypro.<commit_after>"use strict";

var Key = require('./Key');
var KJUR = require('jsrsasign');
var assert = require('assert');
var PayPro = require('../common/PayPro');
var RootCerts = require('../common/RootCerts');

var asn1 = require('asn1.js');
var rfc3280 = require('asn1.js/rfc/3280');

// Documentation:
// http://kjur.github.io/jsrsasign/api/symbols/KJUR.crypto.Signature.html#.sign
// http://kjur.github.io/jsrsasign/api/symbols/RSAKey.html

PayPro.prototype.x509Sign = function(key, returnTrust) {
  var pki_type = this.get('pki_type');
  var pki_data = this.get('pki_data'); // contains one or more x509 certs
  pki_data = PayPro.X509Certificates.decode(pki_data);
  pki_data = pki_data.certificate;
  var type = pki_type.split('+')[1].toUpperCase();
  var buf = this.serializeForSig();

  var rsa = new KJUR.RSAKey();
  rsa.readPrivateKeyFromPEMString(key.toString());
  key = rsa;

  var jsrsaSig = new KJUR.crypto.Signature({
    alg: type + 'withRSA',
    prov: 'cryptojs/jsrsa'
  });

  jsrsaSig.init(key);

  jsrsaSig.updateHex(buf.toString('hex'));

  var sig = new Buffer(jsrsaSig.sign(), 'hex');

  if (returnTrust) {
    var cert = pki_data[pki_data.length - 1];
    var der = cert.toString('hex');
    var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE');
    var caName = RootCerts.getTrusted(pem);
    var selfSigned = 0;
    if (!caName) {
      selfSigned = pki_data.length > 1
        ? -1
        : 1;
    }
    return {
      selfSigned: selfSigned,
      isChain: pki_data.length > 1,
      signature: sig,
      caTrusted: !!caName,
      caName: caName || null
    };
  }

  return sig;
};

PayPro.prototype.x509Verify = function(returnTrust) {
  var sig = this.get('signature');
  var pki_type = this.get('pki_type');
  var pki_data = this.get('pki_data');
  pki_data = PayPro.X509Certificates.decode(pki_data);
  pki_data = pki_data.certificate;
  var buf = this.serializeForSig();
  var type = pki_type.split('+')[1].toUpperCase();

  var jsrsaSig = new KJUR.crypto.Signature({
    alg: type + 'withRSA',
    prov: 'cryptojs/jsrsa'
  });

  var signedCert = pki_data[0];
  var der = signedCert.toString('hex');
  // var pem = self._DERtoPEM(der, 'CERTIFICATE');
  var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE');
  jsrsaSig.initVerifyByCertificatePEM(pem);
  jsrsaSig.updateHex(buf.toString('hex'));
  var verified = jsrsaSig.verify(sig.toString('hex'));

  var chain = pki_data;

  //
  // Get the CA cert's name
  //
  var issuer = chain[chain.length - 1];
  der = issuer.toString('hex');
  // pem = this._DERtoPEM(der, 'CERTIFICATE');
  pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE');
  var caName = RootCerts.getTrusted(pem);

  if (chain.length === 1 && !caName) {
    if (returnTrust) {
      return {
        selfSigned: 1, // yes
        isChain: false,
        verified: verified,
        caTrusted: false,
        caName: null,
        chainVerified: false
      };
    }
    return verified;
  }

  // If there's no trusted root cert, don't
  // bother validating the cert chain.
  if (!caName) {
    if (returnTrust) {
      return {
        selfSigned: -1, // unknown
        isChain: chain.length > 1,
        verified: verified,
        caTrusted: false,
        caName: null,
        chainVerified: false
      };
    }
    return verified;
  }

  var chainVerified = chain.every(function(cert, i) {
    var der = cert.toString('hex');
    // var pem = self._DERtoPEM(der, 'CERTIFICATE');
    var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(der, 'CERTIFICATE');
    var name = RootCerts.getTrusted(pem);

    var ncert = chain[i + 1];
    // The root cert, check if it's trusted:
    if (!ncert || name) {
      if (!name) {
        return false;
      }
      chain.length = 0;
      return true;
    }
    var nder = ncert.toString('hex');
    // var npem = self._DERtoPEM(nder, 'CERTIFICATE');
    var npem = KJUR.asn1.ASN1Util.getPEMStringFromHex(nder, 'CERTIFICATE');

    //
    // Get Next Certificate:
    //
    var ndata = new Buffer(nder, 'hex');
    var nc = rfc3280.Certificate.decode(ndata, 'der');

    //
    // Get Public Key from next certificate (via KJUR because it's a mess):
    //
    var js = new KJUR.crypto.Signature({
      alg: type + 'withRSA',
      prov: 'cryptojs/jsrsa'
    });
    js.initVerifyByCertificatePEM(npem);
    var npubKey = js.pubKey;

    //
    // Get Signature Value from current certificate:
    //
    var data = new Buffer(der, 'hex');
    var c = rfc3280.Certificate.decode(data, 'der');
    var sigAlg = PayPro.getAlgorithm(c.signatureAlgorithm.algorithm, 1);
    var sig = c.signature.data;

    //
    // Check Validity of Certificates
    //
    var validityVerified = PayPro.validateCertTime(c, nc);

    //
    // Check the Issuer matches the Subject of the next certificate:
    //
    var issuerVerified = PayPro.validateCertIssuer(c, nc);

    //
    // Verify current Certificate signature
    //

    var jsrsaSig = new KJUR.crypto.Signature({
      alg: type + 'withRSA',
      prov: 'cryptojs/jsrsa'
    });
    jsrsaSig.initVerifyByPublicKey(npubKey);

    // Get the raw DER TBSCertificate
    // from the DER Certificate:
    var tbs = PayPro.getTBSCertificate(data);

    jsrsaSig.updateHex(tbs.toString('hex'));

    var sigVerified = jsrsaSig.verify(sig.toString('hex'));

    return validityVerified
      && issuerVerified
      && sigVerified;
  });

  if (returnTrust) {
    return {
      selfSigned: 0, // no
      isChain: true,
      verified: verified,
      caTrusted: !!caName,
      caName: caName || null,
      chainVerified: chainVerified
    };
  }

  return verified && chainVerified;
};

module.exports = PayPro;
<|endoftext|>


<commit_before>'use babel';
'use strict';

import fs from 'fs';
import path from 'path';
import EventEmitter from 'events';

// Build modes
export const MODE_CONFIG = 0;
export const MODE_PROJECT = 1;

// Games and game indices
export const GAMES = [
	{ title: 'Unknown', slug: 'unknown', flags: '' },
	{ title: 'Skyrim', slug: 'skyrim', flags: 'TESV_Papyrus_Flags.flg' },
	{ title: 'Fallout 4', slug: 'fallout4', flags: 'Institute_Papyrus_Flags.flg' }
];
export const GAME_UNKNOWN = 0;
export const GAME_SKYRIM = 1;
export const GAME_FALLOUT4 = 2;

// The error match string for the compiler output
const ERROR_MATCH = '\n(?<file>[A-Za-z0-9_:\\-\\.\\/ \\\\]+\\.(psc|PSC))\\((?<line>[0-9]+),(?<col>[0-9]+)\\): (?<message>.+)';

export default class PapyrusBuildProvider extends EventEmitter {
	constructor(cwd) {
		super();

		// Add listeners for game compiler settings to notify of validity
		this.disposables = [];
		GAMES.forEach((game, index, array) => {
			if(index === 0) return;
			this.disposables.push(atom.config.onDidChange('build-papyrus.' + game.slug + 'CompilerPath', () => {
				if(this.doesCompilerExist(index) && this.game === index) this.emit('refresh');
			}));
		});
		this.disposables.push(atom.config.onDidChange('build-papyrus.defaultGame', (newValue) => {
			if(this.mode === MODE_PROJECT) this.emit('refresh');
		}));

		// Initialise all the things
		this.cwd = cwd;
		this.mode = MODE_CONFIG;
		this.game = GAME_UNKNOWN;
		this.configFile = null;
		this.projectFile = null;
		this.gameNotifications = [null, null];
		this.fileWatchers = [];
	}

	destructor() {
		this.disposables.forEach((disposable, index, array) => {
			disposable.dispose();
			delete array[index];
		});
		this.closeFileWatchers();
	}

	getNiceName() {
		return 'Papyrus';
	}

	isEligible() {
		this.configFile = null;
		this.projectFile = null;
		this.closeFileWatchers();

		// Search for .papyrus.json and Papyrus project files
		const files = fs.readdirSync(this.cwd);
		for(const fileName of files) {
			const filePath = path.join(this.cwd, fileName);
			if(fs.statSync(filePath).isFile()) {
				if(!this.configFile && path.basename(fileName) === '.papyrus.json') {
					this.configFile = filePath;
					this.fileWatchers.push(fs.watch(this.configFile, () => this.emit('refresh')));
				} else if(!this.projectFile && path.extname(fileName).toLowerCase() === '.ppj') {
					this.projectFile = filePath;
				}
			}
		}

		// Decide what mode we'll use
		this.game = GAME_UNKNOWN;
		if(this.projectFile) {
			this.mode = MODE_PROJECT;
			return true;
		} else if(this.configFile) {
			this.mode = MODE_CONFIG;
			return true;
		}

		return false;
	}

	settings() {
		return new Promise((resolve, reject) => {
			// Parse config file if necessary
			if(this.game === GAME_UNKNOWN) {
				if(this.configFile) {
					this.config = JSON.parse(fs.readFileSync(this.configFile));
					if(this.mode === MODE_CONFIG && !this.config.game && !this.config.compiler) return reject(new Error('Either game or compiler must be specified in .papyrus.json.'));

					// Get the game from the config
					if(this.config.game) {
						this.config.game = this.config.game.toLowerCase();
						this.game = GAMES.findIndex(obj => obj.slug === this.config.game);
						if(this.game === -1) return reject(new Error('Invalid game specified in .papyrus.json.'));
					} else {
						this.game = GAME_UNKNOWN;
					}

					// Get the default game for projects
					if(this.game === GAME_UNKNOWN && this.mode === MODE_PROJECT) {
						if(!this.setGameFromDefault()) return reject(new Error('Invalid default game in build-papyrus settings'));
					}

					// If the game is still unknown, we need a custom compiler path at the very least
					if(this.game === GAME_UNKNOWN) {
						if(!(this.config.compiler && fs.statSync(this.config.compiler).isFile())) return reject(new Error('Invalid compiler path in .papyrus.json.'));
					}
				} else {
					// Get the default game for projects
					if(this.mode === MODE_PROJECT) {
						if(!this.setGameFromDefault()) return reject(new Error('Invalid default game in build-papyrus settings'));
					}
				}
			}

			if(this.game === GAME_UNKNOWN || this.doesCompilerExist()) {
				if(this.mode === MODE_CONFIG) {
					// Validate some stuff
					if(!Array.isArray(this.config.imports)) return reject(new Error('Imports must be specified as an array in .papyrus.json.'));
					if(this.config.output && !fs.statSync(this.config.output).isDirectory()) return reject(new Error('Output must be a valid directory in .papyrus.json.'));
					if(this.game === GAME_UNKNOWN && !this.config.flags) return reject(new Error('Flags must be specified in .papyrus.json.'));

					// Build arguments array
					const args = [
						'{FILE_ACTIVE}',
						'-import=' + this.config.imports.join(';'),
						'-output=' + (this.config.output ? this.config.output : './'),
						'-flags=' + (this.game === GAME_UNKNOWN || this.config.flags ? this.config.flags : GAMES[this.game].flags)
					];
					if(typeof this.config.optimize === 'undefined' || this.config.optimize) args.push('-optimize');
					if(this.config.release) args.push('-release');
					if(this.config.final) args.push('-final');

					// Make build configuration
					return resolve([{
						exec: this.game !== GAME_UNKNOWN ? atom.config.get('build-papyrus.' + GAMES[this.game].slug + 'CompilerPath') : this.config.compiler,
						cwd: this.cwd,
						sh: false,
						args: args,
						errorMatch: ERROR_MATCH
					}]);
				} else if(this.mode === MODE_PROJECT) {
					// Make Papyrus project file build configuration
					return resolve([{
						exec: this.game !== GAME_UNKNOWN ? atom.config.get('build-papyrus.' + GAMES[this.game].slug + 'CompilerPath') : this.config.compiler,
						cwd: this.cwd,
						sh: false,
						args: [ this.projectFile ],
						errorMatch: ERROR_MATCH
					}]);
				}
			}

			return reject(new Error('Invalid ' + GAMES[this.game].title + ' compiler path.'));
		});
	}

	doesCompilerExist(game = -1, showNotification = true) {
		if(game === -1) game = this.game;
		if(game === GAME_UNKNOWN) return false;
		const compiler = atom.config.get('build-papyrus.' + GAMES[game].slug + 'CompilerPath');
		let compilerExists = false;
		try {
			compilerExists = fs.statSync(compiler).isFile();
		} finally {
			if(showNotification) {
				if(!compilerExists) {
					// Path is invalid; show notification
					if(!this.gameNotifications[game]) {
						this.gameNotifications[game] = atom.notifications.addError('The ' + GAMES[game].title + ' compiler path is not a valid file. Make sure it\'s the full path to the executable.', {
							dismissable: true,
							buttons: [{
								text: 'Open settings',
								onDidClick: () => atom.workspace.open('atom://config/packages/build-papyrus')
							}]
						});
						this.gameNotifications[game].onDidDismiss(() => { this.gameNotifications[game] = null; });
					}
				} else {
					// Path is valid; remove the notification
					if(this.gameNotifications[game]) this.gameNotifications[game].dismiss();
				}
			}
			return compilerExists;
		}
	}

	setGameFromDefault() {
		const defaultGame = atom.config.get('build-papyrus.defaultGame');
		this.game = GAMES.findIndex(obj => obj.slug === defaultGame);
		return this.game !== -1;
	}

	closeFileWatchers() {
		this.fileWatchers.forEach((watcher, index, array) => {
			watcher.close();
			delete array[index];
		});
	}
}
<commit_msg>Added an element to notifications initialisation<commit_after>'use babel';
'use strict';

import fs from 'fs';
import path from 'path';
import EventEmitter from 'events';

// Build modes
export const MODE_CONFIG = 0;
export const MODE_PROJECT = 1;

// Games and game indices
export const GAMES = [
	{ title: 'Unknown', slug: 'unknown', flags: '' },
	{ title: 'Skyrim', slug: 'skyrim', flags: 'TESV_Papyrus_Flags.flg' },
	{ title: 'Fallout 4', slug: 'fallout4', flags: 'Institute_Papyrus_Flags.flg' }
];
export const GAME_UNKNOWN = 0;
export const GAME_SKYRIM = 1;
export const GAME_FALLOUT4 = 2;

// The error match string for the compiler output
const ERROR_MATCH = '\n(?<file>[A-Za-z0-9_:\\-\\.\\/ \\\\]+\\.(psc|PSC))\\((?<line>[0-9]+),(?<col>[0-9]+)\\): (?<message>.+)';

export default class PapyrusBuildProvider extends EventEmitter {
	constructor(cwd) {
		super();

		// Add listeners for game compiler settings to notify of validity
		this.disposables = [];
		GAMES.forEach((game, index, array) => {
			if(index === 0) return;
			this.disposables.push(atom.config.onDidChange('build-papyrus.' + game.slug + 'CompilerPath', () => {
				if(this.doesCompilerExist(index) && this.game === index) this.emit('refresh');
			}));
		});
		this.disposables.push(atom.config.onDidChange('build-papyrus.defaultGame', (newValue) => {
			if(this.mode === MODE_PROJECT) this.emit('refresh');
		}));

		// Initialise all the things
		this.cwd = cwd;
		this.mode = MODE_CONFIG;
		this.game = GAME_UNKNOWN;
		this.configFile = null;
		this.projectFile = null;
		this.gameNotifications = [null, null, null];
		this.fileWatchers = [];
	}

	destructor() {
		this.disposables.forEach((disposable, index, array) => {
			disposable.dispose();
			delete array[index];
		});
		this.closeFileWatchers();
	}

	getNiceName() {
		return 'Papyrus';
	}

	isEligible() {
		this.configFile = null;
		this.projectFile = null;
		this.closeFileWatchers();

		// Search for .papyrus.json and Papyrus project files
		const files = fs.readdirSync(this.cwd);
		for(const fileName of files) {
			const filePath = path.join(this.cwd, fileName);
			if(fs.statSync(filePath).isFile()) {
				if(!this.configFile && path.basename(fileName) === '.papyrus.json') {
					this.configFile = filePath;
					this.fileWatchers.push(fs.watch(this.configFile, () => this.emit('refresh')));
				} else if(!this.projectFile && path.extname(fileName).toLowerCase() === '.ppj') {
					this.projectFile = filePath;
				}
			}
		}

		// Decide what mode we'll use
		this.game = GAME_UNKNOWN;
		if(this.projectFile) {
			this.mode = MODE_PROJECT;
			return true;
		} else if(this.configFile) {
			this.mode = MODE_CONFIG;
			return true;
		}

		return false;
	}

	settings() {
		return new Promise((resolve, reject) => {
			// Parse config file if necessary
			if(this.game === GAME_UNKNOWN) {
				if(this.configFile) {
					this.config = JSON.parse(fs.readFileSync(this.configFile));
					if(this.mode === MODE_CONFIG && !this.config.game && !this.config.compiler) return reject(new Error('Either game or compiler must be specified in .papyrus.json.'));

					// Get the game from the config
					if(this.config.game) {
						this.config.game = this.config.game.toLowerCase();
						this.game = GAMES.findIndex(obj => obj.slug === this.config.game);
						if(this.game === -1) return reject(new Error('Invalid game specified in .papyrus.json.'));
					} else {
						this.game = GAME_UNKNOWN;
					}

					// Get the default game for projects
					if(this.game === GAME_UNKNOWN && this.mode === MODE_PROJECT) {
						if(!this.setGameFromDefault()) return reject(new Error('Invalid default game in build-papyrus settings'));
					}

					// If the game is still unknown, we need a custom compiler path at the very least
					if(this.game === GAME_UNKNOWN) {
						if(!(this.config.compiler && fs.statSync(this.config.compiler).isFile())) return reject(new Error('Invalid compiler path in .papyrus.json.'));
					}
				} else {
					// Get the default game for projects
					if(this.mode === MODE_PROJECT) {
						if(!this.setGameFromDefault()) return reject(new Error('Invalid default game in build-papyrus settings'));
					}
				}
			}

			if(this.game === GAME_UNKNOWN || this.doesCompilerExist()) {
				if(this.mode === MODE_CONFIG) {
					// Validate some stuff
					if(!Array.isArray(this.config.imports)) return reject(new Error('Imports must be specified as an array in .papyrus.json.'));
					if(this.config.output && !fs.statSync(this.config.output).isDirectory()) return reject(new Error('Output must be a valid directory in .papyrus.json.'));
					if(this.game === GAME_UNKNOWN && !this.config.flags) return reject(new Error('Flags must be specified in .papyrus.json.'));

					// Build arguments array
					const args = [
						'{FILE_ACTIVE}',
						'-import=' + this.config.imports.join(';'),
						'-output=' + (this.config.output ? this.config.output : './'),
						'-flags=' + (this.game === GAME_UNKNOWN || this.config.flags ? this.config.flags : GAMES[this.game].flags)
					];
					if(typeof this.config.optimize === 'undefined' || this.config.optimize) args.push('-optimize');
					if(this.config.release) args.push('-release');
					if(this.config.final) args.push('-final');

					// Make build configuration
					return resolve([{
						exec: this.game !== GAME_UNKNOWN ? atom.config.get('build-papyrus.' + GAMES[this.game].slug + 'CompilerPath') : this.config.compiler,
						cwd: this.cwd,
						sh: false,
						args: args,
						errorMatch: ERROR_MATCH
					}]);
				} else if(this.mode === MODE_PROJECT) {
					// Make Papyrus project file build configuration
					return resolve([{
						exec: this.game !== GAME_UNKNOWN ? atom.config.get('build-papyrus.' + GAMES[this.game].slug + 'CompilerPath') : this.config.compiler,
						cwd: this.cwd,
						sh: false,
						args: [ this.projectFile ],
						errorMatch: ERROR_MATCH
					}]);
				}
			}

			return reject(new Error('Invalid ' + GAMES[this.game].title + ' compiler path.'));
		});
	}

	doesCompilerExist(game = -1, showNotification = true) {
		if(game === -1) game = this.game;
		if(game === GAME_UNKNOWN) return false;
		const compiler = atom.config.get('build-papyrus.' + GAMES[game].slug + 'CompilerPath');
		let compilerExists = false;
		try {
			compilerExists = fs.statSync(compiler).isFile();
		} finally {
			if(showNotification) {
				if(!compilerExists) {
					// Path is invalid; show notification
					if(!this.gameNotifications[game]) {
						this.gameNotifications[game] = atom.notifications.addError('The ' + GAMES[game].title + ' compiler path is not a valid file. Make sure it\'s the full path to the executable.', {
							dismissable: true,
							buttons: [{
								text: 'Open settings',
								onDidClick: () => atom.workspace.open('atom://config/packages/build-papyrus')
							}]
						});
						this.gameNotifications[game].onDidDismiss(() => { this.gameNotifications[game] = null; });
					}
				} else {
					// Path is valid; remove the notification
					if(this.gameNotifications[game]) this.gameNotifications[game].dismiss();
				}
			}
			return compilerExists;
		}
	}

	setGameFromDefault() {
		const defaultGame = atom.config.get('build-papyrus.defaultGame');
		this.game = GAMES.findIndex(obj => obj.slug === defaultGame);
		return this.game !== -1;
	}

	closeFileWatchers() {
		this.fileWatchers.forEach((watcher, index, array) => {
			watcher.close();
			delete array[index];
		});
	}
}
<|endoftext|>


<commit_before>var mkdir = require("mkdirp")
  , fs = require("graceful-fs")
  , log = require("npmlog")
  , chownr = require("chownr")
  , npm = require("../npm.js")
  , inflight = require("inflight")

// to maintain the cache dir's permissions consistently.
var cacheStat = null
module.exports = function getCacheStat (cb) {
  if (cacheStat) return cb(null, cacheStat)

  cb = inflight("getCacheStat", cb)
  if (!cb) return

  fs.stat(npm.cache, function (er, st) {
    if (er) return makeCacheDir(cb)
    if (!st.isDirectory()) {
      log.error("getCacheStat", "invalid cache dir %j", npm.cache)
      return cb(er)
    }
    return cb(null, cacheStat = st)
  })
}

function makeCacheDir (cb) {
  if (!process.getuid) return mkdir(npm.cache, cb)

  var uid = +process.getuid()
    , gid = +process.getgid()

  if (uid === 0) {
    if (process.env.SUDO_UID) uid = +process.env.SUDO_UID
    if (process.env.SUDO_GID) gid = +process.env.SUDO_GID
  }
  if (uid !== 0 || !process.env.HOME) {
    cacheStat = {uid: uid, gid: gid}
    return mkdir(npm.cache, afterMkdir)
  }

  fs.stat(process.env.HOME, function (er, st) {
    if (er) {
      log.error("makeCacheDir", "homeless?")
      return cb(er)
    }
    cacheStat = st
    log.silly("makeCacheDir", "cache dir uid, gid", [st.uid, st.gid])
    return mkdir(npm.cache, afterMkdir)
  })

  function afterMkdir (er, made) {
    if (er || !cacheStat || isNaN(cacheStat.uid) || isNaN(cacheStat.gid)) {
      return cb(er, cacheStat)
    }

    if (!made) return cb(er, cacheStat)

    // ensure that the ownership is correct.
    chownr(made, cacheStat.uid, cacheStat.gid, function (er) {
      return cb(er, cacheStat)
    })
  }
}
<commit_msg>getCacheStat: always return consistent data types to cb<commit_after>var mkdir = require("mkdirp")
  , fs = require("graceful-fs")
  , log = require("npmlog")
  , chownr = require("chownr")
  , npm = require("../npm.js")
  , inflight = require("inflight")

// to maintain the cache dir's permissions consistently.
var cacheStat = null
module.exports = function getCacheStat (cb) {
  if (cacheStat) return cb(null, cacheStat)

  cb = inflight("getCacheStat", cb)
  if (!cb) return

  fs.stat(npm.cache, function (er, st) {
    if (er) return makeCacheDir(cb)
    if (!st.isDirectory()) {
      log.error("getCacheStat", "invalid cache dir %j", npm.cache)
      return cb(er)
    }
    return cb(null, cacheStat = st)
  })
}

function makeCacheDir (cb) {
  if (!process.getuid) return mkdir(npm.cache, function (er) {
    return cb(er, {})
  })

  var uid = +process.getuid()
    , gid = +process.getgid()

  if (uid === 0) {
    if (process.env.SUDO_UID) uid = +process.env.SUDO_UID
    if (process.env.SUDO_GID) gid = +process.env.SUDO_GID
  }
  if (uid !== 0 || !process.env.HOME) {
    cacheStat = {uid: uid, gid: gid}
    return mkdir(npm.cache, afterMkdir)
  }

  fs.stat(process.env.HOME, function (er, st) {
    if (er) {
      log.error("makeCacheDir", "homeless?")
      return cb(er)
    }
    cacheStat = st
    log.silly("makeCacheDir", "cache dir uid, gid", [st.uid, st.gid])
    return mkdir(npm.cache, afterMkdir)
  })

  function afterMkdir (er, made) {
    if (er || !cacheStat || isNaN(cacheStat.uid) || isNaN(cacheStat.gid)) {
      return cb(er, cacheStat)
    }

    if (!made) return cb(er, cacheStat)

    // ensure that the ownership is correct.
    chownr(made, cacheStat.uid, cacheStat.gid, function (er) {
      return cb(er, cacheStat)
    })
  }
}
<|endoftext|>


<commit_before>/* TODO :
    -add client side caching of pokemon they look up in a session so if they re-look them up it doesn't have to make extranious calls to the backend (web-storage)
    store: localstorage.setItem('key', JSON.stringify({name: 'value'}));
    get: JSON.parse(localStorage.getItem('key')).name;
    -set up JSON objects for each pokemon for storage
    {name: 'name', id: '', type: 'type', img: 'url'}

    -add section for what types they are good against

    -suggesting pokemon based on what is typed or some system of "did you mean" if they put in an improper name

    -start turning json call back immediately into local side storable json so the display method can work on both with no mods
        also store before call to display
    {"name": "x", "id":"y", "sprite": "z", "types": ["name": "1","name": "1"]}
*/

var xmlhttp = new XMLHttpRequest();
var baseurl = "http://pokeapi.co/api/v2/pokemon/";
var localStorageBool = false;

function checkStorage(name){
    if (localStorage.name !== null) {
        return localStorage.getItem(name);
    }
}

//main method to search for pokemon
function pokeSearch() {
    //grab the pokemon they search for
    var pokemon = document.getElementById("searchBar").value.lowerString();
    var currentShowing = document.getElementById("pokeName").innerHTML.lowerString();
    //test if they are re-searching for whats already there to prevent another api call
    if (!(pokemon === currentShowing)) {
        document.getElementById("pokeDisplay").style.display = "none";
        document.getElementById("errorState").style.display = "none";
        document.getElementById("loader").style.display = "block";
        if (localStorageBool) {
            var storedPokemon = checkStorage(pokemon);
            if (storedPokemon !== null) {
                pokeDisplay(storedPokemon);
            } else {
                console.log("API Call for " + pokemon);
                //make the full URL based on search
                var url = baseurl.concat(pokemon);
                url = url.concat("/");
                console.log("begin request");
                xmlhttp.open("GET", url, true);
                xmlhttp.onload = function () {
                    if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
                        var json = JSON.parse(xmlhttp.responseText);
                        console.log("end request");
                        //CREATE JSON THEN SEND THAT TO POKEDISPLAY AND STORE IN LOCAL STORAGE
                        var storableJSON;
                        if(json.types.length > 1){
                            storableJSON = {"name": json.name, "id": json.id, "sprite": json.sprites.front_default, "types":[{"name": json.types[0].type.name}, {"name": json.types[1].type.name}]};
                        } else {
                            storableJSON = {"name": json.name, "id": json.id, "sprite": json.sprites.front_default, "types":[{"name": json.types[0].type.name}]};
                        }
                        console.log(JSON.stringify(storableJSON));
                        pokeDisplay(json);
                    } else {
                        document.getElementById("errorMessage").innerHTML = pokemon + " can't be found!";
                        document.getElementById("loader").style.display = "none";
                        document.getElementById("errorState").style.display = "block";
                        console.error(xmlhttp.statusText);
                    }
                };
                xmlhttp.send();
            }
        }

    }
}

//placing the data into the page
function pokeDisplay(json) {
    var name = json.name.capitalizeString();
    var weaknesses = "";

    //var urls = [];
    var formattedTypes = [];
    //place information we already have
    document.getElementById("pokeDisplay").style.display = "block";
    document.getElementById("pokeName").innerHTML = name;
    if(json.id < 10) {
        document.getElementById("pokeID").innerHTML = "#00" + json.id;
    } else if (json.id < 100) {
        document.getElementById("pokeID").innerHTML = "#0" + json.id;
    } else {
        document.getElementById("pokeID").innerHTML = "#" + json.id;
    }

    document.getElementById("pokeImg").src = json.sprites.front_default;
    document.getElementById("type1").style.display = "none";
    document.getElementById("type2").style.display = "none";
    document.getElementById("weaknessesUL").innerHTML = "";
    document.getElementById("pokeDisplay").style.height = "170px";

    showRegion(json.id);

    var types = [];
    //create an array of type names for finding weaknesses and display
    for (i = 0; i < json.types.length; i++) {
        types.push(json.types[i].type.name);
    }
    document.getElementById("weakTitle").style.visibility = "visible";
    localType(types);

    document.getElementById("loader").style.display = "none";

}

//handle all type calculation and display
function localType(pTypes) {
    var allWeaknesses = [];
    var resistances = [];
    var immunities = []
    //loop through the types the pokemon displays
    for (i = 0; i < pTypes.length; i++) {
        var color;
        //use JSON to gather more data on the type
        for (j = 0; j < typeJSON.types.length; j++) {
            var type = typeJSON.types[j];
            if (pTypes[i] === type.name) {
                color = type.color;
                //gather the type weaknesses the pokemon displays
                for (w = 0; w < type.effects.weak_to.length; w++) {
                    allWeaknesses.push(type.effects.weak_to[w]);
                }
                //gather the type resistances the pokemon displays
                for(r = 0; r < type.effects.resistant_to.length; r++){
                    resistances.push(type.effects.resistant_to[r]);
                }
                //gather the type immunities the pokemon displays
                for (im =0; im < type.effects.immune_to.length; im++) {
                    immunities.push(type.effects.immune_to[im]);
                }
            }
        }
        //display the main types on the page
        if(i === 0) {
            var type = document.getElementById("type2");
            type.style.display = "block";
            type.innerHTML = pTypes[i];
            type.style.background = color;
        } else {
            var type = document.getElementById("type1");
            type.style.display = "block";
            type.innerHTML = pTypes[i];
            type.style.background = color;
        }

    }
    displayTypeWeaknesses(allWeaknesses, resistances, immunities);
}

//calculate and display proper type weaknesses
function displayTypeWeaknesses(weaknesses, resistances, immunities) {
    var alreadyDisplayed = [];
    var showing = 0;
    //var pokeWeak = document.getElementById("weaknesses");
    //calculate which weaknesses will be displayed (mostly for 2 typed pokemon)
    for (i = 0; i < weaknesses.length; i++) {
        var found = false;
        //see if the type is overlapped b/w the pokemons types
        for (j = 0; j < alreadyDisplayed.length; j++) {
            if (alreadyDisplayed[j] === weaknesses[i]) {
                found = true;
                break;
            }
        }
        //if there is no overlap check to see if there is a resistance or immunity overlap
        if (!found) {
            var typeInconsistency = false;
            //note that we already checked this one whether we are resistant or not
            alreadyDisplayed.push(weaknesses[i]);
            //loop through resistances and then immunities to filter out wrong weaknesses
            for (k = 0; k < resistances.length; k++) {
                if(weaknesses[i] === resistances[k]) {
                    typeInconsistency = true;
                }
            }
            for (im = 0; im < immunities.length; im++) {
                if(weaknesses[i] === immunities[im]) {
                    typeInconsistency = true;
                }
            }
            if(!typeInconsistency){
                var weaknessLI = document.createElement("li");
                weaknessLI.className = "type";
                weaknessLI.innerHTML = weaknesses[i];
                //weaknessLI.style.background = getTypeColor(weaknesses[i]);
                 for (c = 0; c < typeJSON.types.length; c++) {
                    if (typeJSON.types[c].name === weaknesses[i]) {
                        weaknessLI.style.background = typeJSON.types[c].color;
                    }
                }
                document.getElementById("weaknessesUL").appendChild(weaknessLI);
                showing++;
                if (showing > 6) {
                    document.getElementById("pokeDisplay").style.height = "200px";
                } else if (showing > 3) {
                    document.getElementById("pokeDisplay").style.height = "175px";
                }
            }
        }
    }
}

//display the home region of the pokemon based on id number
function showRegion(id) {
    var regionHolder = document.getElementById("region");
    var regionName = "";
    if (id < 152){
        regionName = regionNames[0];
    } else if (152 <= id && id < 252) {
        regionName = regionNames[1];
    } else if (252 <= id && id < 387) {
        regionName = regionNames[2];
    } else if (387 <= id && id < 494) {
        regionName = regionNames[3];
    } else if (494 <= id && id < 650) {
        regionName = regionNames[4];
    } else {
        regionName = regionNames[5];
    }
    regionHolder.innerHTML = regionName.capitalizeString();
    regionHolder.innerHTML += " REGION";
}

window.onload = function () {
    if (typeof(Storage) !== "undefined") {
        localStorageBool = true;
    }
    document.getElementById("searchButton").addEventListener("click", pokeSearch);
    document.getElementById("searchBar").addEventListener("keyup", function (event) {
        event.preventDefault();
        if (event.keyCode === 13) {
            pokeSearch();
        }
    });
};

//String prototype helper methods for minimizing code
String.prototype.capitalizeFirstLetter = function () {
    return this.charAt(0).toUpperCase() + this.slice(1);
};

String.prototype.lowerFirstLetter = function () {
    return this.charAt(0).toLowerCase() + this.slice(1);
};

String.prototype.capitalizeString = function () {
    var capString = "";
    for (i = 0; i < this.length; i++){
        capString += this.charAt(i).toUpperCase();
    }
    return capString;
};

String.prototype.lowerString = function () {
    var lowString = "";
    for (i = 0; i < this.length; i++) {
        lowString += this.charAt(i).toLowerCase();
    }
    return lowString;
}

//stored data on type and region
var regionNames = ["Kanto", "Johto", "Hoenn", "Sinnoh", "Unova", "Kalos"];
/*
normal: #aaa
    fighting: #C25942
    flying: #B3BAE6
    poison: #A246E8
    ground: #D19F41
    rock: #946715
    bug: #92B368
    ghost: #291B3B
    steel: #DBDBDB
    fire: #F2452E
    water: #6B9DED
    grass: #94DB76
    electric: #E8E83F
    psychic: #E23FE8
    ice: #AAFAF2
    dragon: #032B63
    dark: #1D2024
    fairy: #F7B5EE
*/
var typeJSON = {"types": [{"name": "normal", "color": "#aaa", "effects": {"weak_to": ["fighting"], "resistant_to":[],"immune_to":["ghost"]}},
{"name":"fighting", "color": "#C25942", "effects":{"weak_to":["flying","psychic","fairy"],"resistant_to":["rock","bug","dark"],"immune_to":[]}},
{"name":"flying", "color": "#B3BAE6", "effects":{"weak_to":["rock","electric","ice"],"resistant_to":["fighting","bug","grass"],"immune_to":["ground"]}},
{"name":"poison", "color": "#A246E8", "effects":{"weak_to":["ground","psychic"],"resistant_to":["fighting","poison","bug","grass","fairy"],"immune_to":[]}},
{"name":"ground", "color": "#D19F41", "effects":{"weak_to":["water","grass","ice"],"resistant_to":["poison","rock"],"immune_to":["electric"]}},
{"name":"rock", "color": "#946715", "effects":{"weak_to":["fighting","ground","steel","water","grass"],"resistant_to":["normal","flying","poison","fire"],"immune_to":[]}},
{"name":"bug", "color": "#92B368", "effects":{"weak_to":["flying","rock","fire"],"resistant_to":["fighting","ground","grass"],"immune_to":[]}},
{"name":"ghost", "color": "#291B3B", "effects":{"weak_to":["ghost","dark"],"resistant_to":["poison","bug"],"immune_to":["normal","fighting"]}},
{"name":"steel", "color": "#DBDBDB", "effects":{"weak_to":["fighting","ground","fire"],"resistant_to":["normal","flying","rock","bug","steel","grass","psychic","ice","dragon","fairy"],"immune_to":["poison"]}},
{"name":"fire", "color": "#F2452E", "effects":{"weak_to":["ground","rock","water"],"resistant_to":["bug","steel","fire","grass","ice","fairy"],"immune_to":[]}},
{"name":"water", "color": "#6B9DED", "effects":{"weak_to":["grass","electric"],"resistant_to":["steel","fire","water","ice"],"immune_to":[]}},
{"name":"grass", "color": "#94DB76", "effects":{"weak_to":["flying","poison","bug","fire","ice"],"resistant_to":["ground","water","grass","electric"],"immune_to":[]}},
{"name":"electric", "color": "#E8E83F", "effects":{"weak_to":["ground"],"resistant_to":["flying","steel","electric"],"immune_to":[]}},
{"name":"psychic", "color": "#E23FE8", "effects":{"weak_to":["bug","ghost","dark"],"resistant_to":["fighting","psychic"],"immune_to":[]}},
{"name":"ice", "color": "#AAFAF2", "effects":{"weak_to":["fighting","rock","steel","fire"],"resistant_to":["ice"],"immune_to":[]}},
{"name":"dragon", "color": "#032B63", "effects":{"weak_to":["ice","dragon","fairy"],"resistant_to":["fire","water","grass","electric"],"immune_to":[]}},
{"name":"dark", "color": "#1D2024", "effects":{"weak_to":["fighting","bug","fairy"],"resistant_to":["ghost","dark"],"immune_to":["psychic"]}},
{"name":"fairy", "color": "#F7B5EE", "effects":{"weak_to":["poison","steel"],"resistant_to":["fighting","bug","dark"],"immune_to":["dragon"]}}]};<commit_msg>Fixes #2<commit_after>/* TODO :
    -add client side caching of pokemon they look up in a session so if they re-look them up it doesn't have to make extranious calls to the backend (web-storage)
    store: localstorage.setItem('key', JSON.stringify({name: 'value'}));
    get: JSON.parse(localStorage.getItem('key')).name;
    -set up JSON objects for each pokemon for storage
    {name: 'name', id: '', type: 'type', img: 'url'}

    -add section for what types they are good against

    -suggesting pokemon based on what is typed or some system of "did you mean" if they put in an improper name

    -start turning json call back immediately into local side storable json so the display method can work on both with no mods
        also store before call to display
    {"name": "x", "id":"y", "sprite": "z", "types": ["name": "1","name": "1"]}
*/

var xmlhttp = new XMLHttpRequest();
var baseurl = "http://pokeapi.co/api/v2/pokemon/";
var localStorageBool = false;

function checkStorage(name){
    if (localStorage.name !== null) {
        return localStorage.getItem(name);
    }
}

//main method to search for pokemon
function pokeSearch() {
    //grab the pokemon they search for
    var pokemon = document.getElementById("searchBar").value.lowerString();
    var currentShowing = document.getElementById("pokeName").innerHTML.lowerString();
    //test if they are re-searching for whats already there to prevent another api call
    if (!(pokemon === currentShowing)) {
        document.getElementById("pokeDisplay").style.display = "none";
        document.getElementById("errorState").style.display = "none";
        document.getElementById("loader").style.display = "block";
        if (localStorageBool) {
            var storedPokemon = checkStorage(pokemon);
            if (storedPokemon !== null) {
                console.log("pulling from local storage: " + storedPokemon + " typeof:" + typeof storedPokemon);
                var storedJSON = JSON.parse(storedPokemon);
                console.log("done parsing: " + storedJSON);
                pokeDisplay(storedJSON);
            } else {
                console.log("API Call for " + pokemon);
                //make the full URL based on search
                var url = baseurl.concat(pokemon);
                url = url.concat("/");
                console.log("begin request");
                xmlhttp.open("GET", url, true);
                xmlhttp.onload = function () {
                    if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
                        //console.log(xmlhttp.responseText);
                        var json = JSON.parse(xmlhttp.responseText);
                        console.log(json);
                        console.log("end request");
                        //CREATE JSON THEN SEND THAT TO POKEDISPLAY AND STORE IN LOCAL STORAGE
                        var storableJSON;
                        if(json.types.length > 1){
                            storableJSON = {"name": json.name,"id": json.id, "sprite": json.sprites.front_default,"types": [{"name": json.types[0].type.name},{"name": json.types[1].type.name}]};
                        } else {
                            storableJSON = {"name":json.name,"id":json.id,"sprite":json.sprites.front_default,"types":[{"name":json.types[0].type.name}]};
                        }
                        localStorage.setItem(pokemon, JSON.stringify(storableJSON));
                        pokeDisplay(storableJSON);
                    } else {
                        document.getElementById("errorMessage").innerHTML = pokemon + " can't be found!";
                        document.getElementById("loader").style.display = "none";
                        document.getElementById("errorState").style.display = "block";
                        console.error(xmlhttp.statusText);
                    }
                };
                xmlhttp.send();
            }
        }

    }
}

//placing the data into the page
function pokeDisplay(json) {
    console.log(json.name);
    var name = json.name.capitalizeString();
    var weaknesses = "";

    //var urls = [];
    var formattedTypes = [];
    //place information we already have
    document.getElementById("pokeDisplay").style.display = "block";
    document.getElementById("pokeName").innerHTML = name;
    if(json.id < 10) {
        document.getElementById("pokeID").innerHTML = "#00" + json.id;
    } else if (json.id < 100) {
        document.getElementById("pokeID").innerHTML = "#0" + json.id;
    } else {
        document.getElementById("pokeID").innerHTML = "#" + json.id;
    }

    document.getElementById("pokeImg").src = json.sprite;
    document.getElementById("type1").style.display = "none";
    document.getElementById("type2").style.display = "none";
    document.getElementById("weaknessesUL").innerHTML = "";
    document.getElementById("pokeDisplay").style.height = "170px";

    showRegion(json.id);

    document.getElementById("weakTitle").style.visibility = "visible";
    localType(json.types);

    document.getElementById("loader").style.display = "none";

}

//handle all type calculation and display
function localType(pTypes) {
    var allWeaknesses = [];
    var resistances = [];
    var immunities = []
    //loop through the types the pokemon displays
    for (i = 0; i < pTypes.length; i++) {
        var color;
        //use JSON to gather more data on the type
        for (j = 0; j < typeJSON.types.length; j++) {
            var type = typeJSON.types[j];
            if (pTypes[i].name === type.name) {
                color = type.color;
                //gather the type weaknesses the pokemon displays
                for (w = 0; w < type.effects.weak_to.length; w++) {
                    allWeaknesses.push(type.effects.weak_to[w]);
                }
                //gather the type resistances the pokemon displays
                for(r = 0; r < type.effects.resistant_to.length; r++){
                    resistances.push(type.effects.resistant_to[r]);
                }
                //gather the type immunities the pokemon displays
                for (im =0; im < type.effects.immune_to.length; im++) {
                    immunities.push(type.effects.immune_to[im]);
                }
            }
        }
        //display the main types on the page
        if(i === 0) {
            var type = document.getElementById("type2");
            type.style.display = "block";
            type.innerHTML = pTypes[i].name;
            type.style.background = color;
        } else {
            var type = document.getElementById("type1");
            type.style.display = "block";
            type.innerHTML = pTypes[i].name;
            type.style.background = color;
        }

    }
    displayTypeWeaknesses(allWeaknesses, resistances, immunities);
}

//calculate and display proper type weaknesses
function displayTypeWeaknesses(weaknesses, resistances, immunities) {
    var alreadyDisplayed = [];
    var showing = 0;
    //var pokeWeak = document.getElementById("weaknesses");
    //calculate which weaknesses will be displayed (mostly for 2 typed pokemon)
    for (i = 0; i < weaknesses.length; i++) {
        var found = false;
        //see if the type is overlapped b/w the pokemons types
        for (j = 0; j < alreadyDisplayed.length; j++) {
            if (alreadyDisplayed[j] === weaknesses[i]) {
                found = true;
                break;
            }
        }
        //if there is no overlap check to see if there is a resistance or immunity overlap
        if (!found) {
            var typeInconsistency = false;
            //note that we already checked this one whether we are resistant or not
            alreadyDisplayed.push(weaknesses[i]);
            //loop through resistances and then immunities to filter out wrong weaknesses
            for (k = 0; k < resistances.length; k++) {
                if(weaknesses[i] === resistances[k]) {
                    typeInconsistency = true;
                }
            }
            for (im = 0; im < immunities.length; im++) {
                if(weaknesses[i] === immunities[im]) {
                    typeInconsistency = true;
                }
            }
            if(!typeInconsistency){
                var weaknessLI = document.createElement("li");
                weaknessLI.className = "type";
                weaknessLI.innerHTML = weaknesses[i];
                //weaknessLI.style.background = getTypeColor(weaknesses[i]);
                 for (c = 0; c < typeJSON.types.length; c++) {
                    if (typeJSON.types[c].name === weaknesses[i]) {
                        weaknessLI.style.background = typeJSON.types[c].color;
                    }
                }
                document.getElementById("weaknessesUL").appendChild(weaknessLI);
                showing++;
                if (showing > 6) {
                    document.getElementById("pokeDisplay").style.height = "200px";
                } else if (showing > 3) {
                    document.getElementById("pokeDisplay").style.height = "175px";
                }
            }
        }
    }
}

//display the home region of the pokemon based on id number
function showRegion(id) {
    var regionHolder = document.getElementById("region");
    var regionName = "";
    if (id < 152){
        regionName = regionNames[0];
    } else if (152 <= id && id < 252) {
        regionName = regionNames[1];
    } else if (252 <= id && id < 387) {
        regionName = regionNames[2];
    } else if (387 <= id && id < 494) {
        regionName = regionNames[3];
    } else if (494 <= id && id < 650) {
        regionName = regionNames[4];
    } else {
        regionName = regionNames[5];
    }
    regionHolder.innerHTML = regionName.capitalizeString();
    regionHolder.innerHTML += " REGION";
}

window.onload = function () {
    if (typeof(Storage) !== "undefined") {
        localStorageBool = true;
    }
    document.getElementById("searchButton").addEventListener("click", pokeSearch);
    document.getElementById("searchBar").addEventListener("keyup", function (event) {
        event.preventDefault();
        if (event.keyCode === 13) {
            pokeSearch();
        }
    });
};

//String prototype helper methods for minimizing code
String.prototype.capitalizeFirstLetter = function () {
    return this.charAt(0).toUpperCase() + this.slice(1);
};

String.prototype.lowerFirstLetter = function () {
    return this.charAt(0).toLowerCase() + this.slice(1);
};

String.prototype.capitalizeString = function () {
    var capString = "";
    for (i = 0; i < this.length; i++){
        capString += this.charAt(i).toUpperCase();
    }
    return capString;
};

String.prototype.lowerString = function () {
    var lowString = "";
    for (i = 0; i < this.length; i++) {
        lowString += this.charAt(i).toLowerCase();
    }
    return lowString;
}

//stored data on type and region
var regionNames = ["Kanto", "Johto", "Hoenn", "Sinnoh", "Unova", "Kalos"];
/*
normal: #aaa
    fighting: #C25942
    flying: #B3BAE6
    poison: #A246E8
    ground: #D19F41
    rock: #946715
    bug: #92B368
    ghost: #291B3B
    steel: #DBDBDB
    fire: #F2452E
    water: #6B9DED
    grass: #94DB76
    electric: #E8E83F
    psychic: #E23FE8
    ice: #AAFAF2
    dragon: #032B63
    dark: #1D2024
    fairy: #F7B5EE
*/
var typeJSON = {"types": [{"name": "normal", "color": "#aaa", "effects": {"weak_to": ["fighting"], "resistant_to":[],"immune_to":["ghost"]}},
{"name":"fighting", "color": "#C25942", "effects":{"weak_to":["flying","psychic","fairy"],"resistant_to":["rock","bug","dark"],"immune_to":[]}},
{"name":"flying", "color": "#B3BAE6", "effects":{"weak_to":["rock","electric","ice"],"resistant_to":["fighting","bug","grass"],"immune_to":["ground"]}},
{"name":"poison", "color": "#A246E8", "effects":{"weak_to":["ground","psychic"],"resistant_to":["fighting","poison","bug","grass","fairy"],"immune_to":[]}},
{"name":"ground", "color": "#D19F41", "effects":{"weak_to":["water","grass","ice"],"resistant_to":["poison","rock"],"immune_to":["electric"]}},
{"name":"rock", "color": "#946715", "effects":{"weak_to":["fighting","ground","steel","water","grass"],"resistant_to":["normal","flying","poison","fire"],"immune_to":[]}},
{"name":"bug", "color": "#92B368", "effects":{"weak_to":["flying","rock","fire"],"resistant_to":["fighting","ground","grass"],"immune_to":[]}},
{"name":"ghost", "color": "#291B3B", "effects":{"weak_to":["ghost","dark"],"resistant_to":["poison","bug"],"immune_to":["normal","fighting"]}},
{"name":"steel", "color": "#DBDBDB", "effects":{"weak_to":["fighting","ground","fire"],"resistant_to":["normal","flying","rock","bug","steel","grass","psychic","ice","dragon","fairy"],"immune_to":["poison"]}},
{"name":"fire", "color": "#F2452E", "effects":{"weak_to":["ground","rock","water"],"resistant_to":["bug","steel","fire","grass","ice","fairy"],"immune_to":[]}},
{"name":"water", "color": "#6B9DED", "effects":{"weak_to":["grass","electric"],"resistant_to":["steel","fire","water","ice"],"immune_to":[]}},
{"name":"grass", "color": "#94DB76", "effects":{"weak_to":["flying","poison","bug","fire","ice"],"resistant_to":["ground","water","grass","electric"],"immune_to":[]}},
{"name":"electric", "color": "#E8E83F", "effects":{"weak_to":["ground"],"resistant_to":["flying","steel","electric"],"immune_to":[]}},
{"name":"psychic", "color": "#E23FE8", "effects":{"weak_to":["bug","ghost","dark"],"resistant_to":["fighting","psychic"],"immune_to":[]}},
{"name":"ice", "color": "#AAFAF2", "effects":{"weak_to":["fighting","rock","steel","fire"],"resistant_to":["ice"],"immune_to":[]}},
{"name":"dragon", "color": "#032B63", "effects":{"weak_to":["ice","dragon","fairy"],"resistant_to":["fire","water","grass","electric"],"immune_to":[]}},
{"name":"dark", "color": "#1D2024", "effects":{"weak_to":["fighting","bug","fairy"],"resistant_to":["ghost","dark"],"immune_to":["psychic"]}},
{"name":"fairy", "color": "#F7B5EE", "effects":{"weak_to":["poison","steel"],"resistant_to":["fighting","bug","dark"],"immune_to":["dragon"]}}]};<|endoftext|>


<commit_before>'use strict';

module.exports = exports = function(number, cellProvider){
  let carrier = cellProvider.toUpperCase();
  if (carrier === 'AT&T' || carrier === 'ATT') return number + '@txt.att.net';
  if (carrier === 'VERIZON') return number + '@vtext.com';
  if (carrier === 'T-MOBILE' || carrier === 'TMOBILE') return number + '@tmomail.net';
  if (carrier === 'T-MOBILE' || carrier === 'TMOBILE') return number + '@tmomail.net';
  if (carrier === 'SPRINT') return number + '@pm.sprint.com';
  if (carrier === 'VIRGIN' || carrier === 'VIRGIN MOBILE') return number + '@vmobl.com';
  if (carrier === 'TRACFONE') return number + '@mmst5.tracfone.com';
  if (carrier === 'METRO PCS' || carrier === 'METROPCS' || carrier === 'METRO') return number + '@mymetropcs.com';
  if (carrier === 'BOOSTMOBILE' || carrier === 'BOOST MOBILE' || carrier === 'BOOST') return number + '@myboostmobile.com';
  if (carrier === 'CRICKET') return number + '@sms.mycricket.com';
  if (carrier === 'NEXTEL') return number + '@messaging.nextel.com';
  if (carrier === 'ALLTEL') return number + '@message.alltel.com';
  if (carrier === 'PTEL') return number + '@ptel.com';
  if (carrier === 'SUNCOM') return number + '@tms.suncom.com';
  if (carrier === 'QWEST') return number + '@qwestmp.com';
  if (carrier === 'US CELLULAR' || carrier === 'USCELLULAR' || carrier === 'U.S. CELLULAR') return number + '@email.uscc.net';
  return console.log('carrier not found');
};
<commit_msg>throwing error to terminate sendgrid if carrier not found<commit_after>'use strict';

module.exports = exports = function(number, cellProvider){
  let carrier = cellProvider.toUpperCase();
  if (carrier === 'AT&T' || carrier === 'ATT') return number + '@txt.att.net';
  if (carrier === 'VERIZON') return number + '@vtext.com';
  if (carrier === 'T-MOBILE' || carrier === 'TMOBILE') return number + '@tmomail.net';
  if (carrier === 'T-MOBILE' || carrier === 'TMOBILE') return number + '@tmomail.net';
  if (carrier === 'SPRINT') return number + '@pm.sprint.com';
  if (carrier === 'VIRGIN' || carrier === 'VIRGIN MOBILE') return number + '@vmobl.com';
  if (carrier === 'TRACFONE') return number + '@mmst5.tracfone.com';
  if (carrier === 'METRO PCS' || carrier === 'METROPCS' || carrier === 'METRO') return number + '@mymetropcs.com';
  if (carrier === 'BOOSTMOBILE' || carrier === 'BOOST MOBILE' || carrier === 'BOOST') return number + '@myboostmobile.com';
  if (carrier === 'CRICKET') return number + '@sms.mycricket.com';
  if (carrier === 'NEXTEL') return number + '@messaging.nextel.com';
  if (carrier === 'ALLTEL') return number + '@message.alltel.com';
  if (carrier === 'PTEL') return number + '@ptel.com';
  if (carrier === 'SUNCOM') return number + '@tms.suncom.com';
  if (carrier === 'QWEST') return number + '@qwestmp.com';
  if (carrier === 'US CELLULAR' || carrier === 'USCELLULAR' || carrier === 'U.S. CELLULAR') return number + '@email.uscc.net';
  throw new Error('Carrier Not Found');
};
<|endoftext|>


<commit_before>var fs = require('fs'),
    get = require('get'),
    url = require('url'),
    sys = require('sys'),
    EventEmitter = require('events').EventEmitter,
    path = require('path'),
    crypto = require('crypto'),
    assert = require('assert'),
    zip = require('zipfile'),
    Step = require('step');

// node compatibility for mkdirs below
var constants = ((!process.EEXIST) >= 1) ?
    require('constants') :
    { EEXIST: process.EEXIST };

function External(env, uri) {
    var local = !(/^https?:\/\//i.test(uri));
    if (local) {
        uri = path.join(env.local_data_dir, uri);
    }

    if (External.instances[uri]) return External.instances[uri];

    this.uri = uri;
    this.env = env;
    this.format = path.extname(uri).toLowerCase();
    this.type = External.findType(this.format);
    this._callbacks = [];
    this.done = false;

    External.mkdirp(this.env.data_dir, 755);

    if (local) {
        this.localFile();
    } else {
        this.downloadFile();
    }

    External.instances[this.uri] = this;
}
sys.inherits(External, EventEmitter);

External.instances = {};

External.prototype.invokeCallbacks = function(err) {
    delete External.instances[this.uri];

    if (err) {
        this.emit('err', err);
    } else {
        this.emit('complete', this);
    }
};

External.prototype.localFile = function() {
    // Only treat files as local that don't have to be processed.
    this.isLocal = !External.processors[this.format];

    this.tempPath = this.uri;
    fs.stat(this.tempPath, this.processFile.bind(this));
};

External.prototype.downloadFile = function() {
    this.tempPath = path.join(
        this.env.data_dir,
        crypto.createHash('md5').update(this.uri).digest('hex') +
            path.extname(this.uri));

    fs.stat(this.path(), function(err, stats) {
        if (err) {
            // This file does not yet exist. Download it!
            (new get(this.uri)).toDisk(
                this.tempPath,
                this.processFile.bind(this));
        } else {
            this.invokeCallbacks(null);
        }
    }.bind(this));
};

External.prototype.processFile = function(err) {
    if (err) {
        this.invokeCallbacks(err);
    } else {
        if (this.isLocal) {
            this.invokeCallbacks(null);
        } else {
            (External.processors[this.format] || External.processors['default'])(
                this.tempPath,
                this.path(),
                function(err) {
                    if (err) {
                        this.invokeCallbacks(err);
                    } else {
                        this.invokeCallbacks(null);
                    }
                }.bind(this)
            );
        }
    }
};

External.prototype.path = function() {
    if (this.isLocal) {
        return this.tempPath;
    } else {
        return path.join(
            this.env.data_dir,
            (External.destinations[this.format] ||
             External.destinations['default'])(this.uri)
        );
    }
};

External.prototype.findDataFile = function(callback) {
    this.type.datafile(this, callback);
};

External.prototype.findOneByExtension = function(ext, callback) {
    var cb = function(err, files) { callback(null, files.pop()); };
    this.findByExtension(ext, cb);
};

// Find a file by extension in `this.path()`.
// Ignores .directories and .files
External.prototype.findByExtension = function(ext, callback) {
    var running = 0;
    var found = [];

    (function find(dir) {
        running++;
        fs.readdir(dir, function(err, files) {
            if (err) {
                running = 0;
                callback(err);
                return;
            }
            files.forEach(function(file) {
                // Ignore dotfiles and dot-directories
                if (file[0] === '.') return;
                running++;
                file = path.join(dir, file);
                fs.stat(file, function(err, stats) {
                    if (err) {
                        running = 0;
                        callback(err);
                        return;
                    }
                    if (stats.isDirectory()) {
                        find(file);
                    } else if (stats.isFile() && path.extname(file) === ext) {
                        found.push(file);
                    }
                    if (running && !--running) callback(null, found);
                });
            });
            if (running && !--running) callback(null, found);
        });
    })(this.path());
};

// https://gist.github.com/707661
External.mkdirp = function mkdirP(p, mode, f) {
    var cb = f || function() {};
    if (p.charAt(0) != '/') {
        cb('Relative path: ' + p);
        return;
    }

    var ps = path.normalize(p).split('/');
    path.exists(p, function(exists) {
        if (exists) cb(null);
        else mkdirP(ps.slice(0, -1).join('/'), mode, function(err) {
            if (err && err.errno != process.EEXIST) cb(err);
            else {
                fs.mkdir(p, mode, cb);
            }
        });
    });
};

External.types = [
    {
        extension: /\.zip/,
        datafile: function(d, c) { d.findOneByExtension('.shp', c); },
        ds_options: {
            type: 'shape'
        }
    },
    {
        extension: /\.shp/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'shape'
        }
    },
    {
        extension: /\.png/,
        datafile: function(d, c) { c(null, d.path()); }
    },
    {
        extension: /\.jpe?g/
    },
    {
        extension: /\.geotiff?|\.tiff?/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'gdal'
        }
    },
    {
        extension: /\.vrt/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'gdal'
        }
    },
    {
        extension: /\.kml/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'ogr',
            layer_by_index: 0
        }
    },
    {
        extension: /\.geojson|\.json/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'ogr',
            layer_by_index: 0
        }
    },
    {
        extension: /\.rss/,
        datafile: function(d, c) { c(d.path()); },
        ds_options: {
            type: 'ogr',
            layer_by_index: 0
        }
    },
    {
        extension: /.*/g,
        datafile: function(d, c) { c(d.path()); }
    }
];

External.findType = function(ext) {
    for (var i in External.types) {
        if (ext.match(External.types[i].extension)) {
            return External.types[i];
        }
    }
};

// Destinations are names in the data_dir/cache directory.
External.destinations = {};
External.destinations['default'] = function(uri) {
    return crypto.createHash('md5').update(uri).digest('hex') + path.extname(uri);
};
External.destinations['.zip'] = function(uri) {
    return crypto.createHash('md5').update(uri).digest('hex');
};

External.processors = {};
External.processors['default'] = function(tempPath, destPath, callback) {
    if (tempPath === destPath) {
        callback(null);
    } else {
        fs.rename(tempPath, destPath, callback);
    }
};

External.processors['.zip'] = function(tempPath, destPath, callback) {
    try {
        console.log('unzipping file');
        var zf = new zip.ZipFile(tempPath);
    } catch (err) {
        callback(err);
        return;
    }

    Step(
        function() {
            var group = this.group();
            zf.names.forEach(function(name) {
                var next = group();
                var uncompressed = path.join(destPath, name);
                External.mkdirp(path.dirname(uncompressed), 755, function(err) {
                    if (err && err.errno != constants.EEXIST) {
                        callback("Couldn't create directory " + path.dirname(name));
                    }
                    else {
                        // if just a directory skip ahead
                        if (!path.extname(name) || name[0] === '.') {
                            next();
                        } else {
                            var buffer = zf.readFile(name, function(err, buffer) {
                                fd = fs.open(uncompressed, 'w', 755, function(err, fd) {
                                    sys.debug('saving to: ' + uncompressed);
                                    fs.write(fd, buffer, 0, buffer.length, null,
                                        function(err, written) {
                                            fs.close(fd, function(err) {
                                                next();
                                            });
                                        });
                                  });
                            });
                        }
                    }
                });
            });
        },
        callback
    );
};

module.exports = External;
<commit_msg>Javascript: whoah, what is up with your number system.<commit_after>var fs = require('fs'),
    get = require('get'),
    url = require('url'),
    sys = require('sys'),
    EventEmitter = require('events').EventEmitter,
    path = require('path'),
    crypto = require('crypto'),
    assert = require('assert'),
    zip = require('zipfile'),
    Step = require('step');

// node compatibility for mkdirs below
var constants = ((!process.EEXIST) >= 1) ?
    require('constants') :
    { EEXIST: process.EEXIST };

function External(env, uri) {
    var local = !(/^https?:\/\//i.test(uri));
    if (local) {
        uri = path.join(env.local_data_dir, uri);
    }

    if (External.instances[uri]) return External.instances[uri];

    this.uri = uri;
    this.env = env;
    this.format = path.extname(uri).toLowerCase();
    this.type = External.findType(this.format);
    this._callbacks = [];
    this.done = false;

    External.mkdirp(this.env.data_dir, 0755);

    if (local) {
        this.localFile();
    } else {
        this.downloadFile();
    }

    External.instances[this.uri] = this;
}
sys.inherits(External, EventEmitter);

External.instances = {};

External.prototype.invokeCallbacks = function(err) {
    delete External.instances[this.uri];

    if (err) {
        this.emit('err', err);
    } else {
        this.emit('complete', this);
    }
};

External.prototype.localFile = function() {
    // Only treat files as local that don't have to be processed.
    this.isLocal = !External.processors[this.format];

    this.tempPath = this.uri;
    fs.stat(this.tempPath, this.processFile.bind(this));
};

External.prototype.downloadFile = function() {
    this.tempPath = path.join(
        this.env.data_dir,
        crypto.createHash('md5').update(this.uri).digest('hex') +
            path.extname(this.uri));

    fs.stat(this.path(), function(err, stats) {
        if (err) {
            // This file does not yet exist. Download it!
            (new get(this.uri)).toDisk(
                this.tempPath,
                this.processFile.bind(this));
        } else {
            this.invokeCallbacks(null);
        }
    }.bind(this));
};

External.prototype.processFile = function(err) {
    if (err) {
        this.invokeCallbacks(err);
    } else {
        if (this.isLocal) {
            this.invokeCallbacks(null);
        } else {
            (External.processors[this.format] || External.processors['default'])(
                this.tempPath,
                this.path(),
                function(err) {
                    if (err) {
                        this.invokeCallbacks(err);
                    } else {
                        this.invokeCallbacks(null);
                    }
                }.bind(this)
            );
        }
    }
};

External.prototype.path = function() {
    if (this.isLocal) {
        return this.tempPath;
    } else {
        return path.join(
            this.env.data_dir,
            (External.destinations[this.format] ||
             External.destinations['default'])(this.uri)
        );
    }
};

External.prototype.findDataFile = function(callback) {
    this.type.datafile(this, callback);
};

External.prototype.findOneByExtension = function(ext, callback) {
    var cb = function(err, files) { callback(err, files && files.pop()); };
    this.findByExtension(ext, cb);
};

// Find a file by extension in `this.path()`.
// Ignores .directories and .files
External.prototype.findByExtension = function(ext, callback) {
    var running = 0;
    var found = [];

    (function find(dir) {
        running++;
        fs.readdir(dir, function(err, files) {
            if (err) {
                running = 0;
                callback(err);
                return;
            }
            files.forEach(function(file) {
                // Ignore dotfiles and dot-directories
                if (file[0] === '.') return;
                running++;
                file = path.join(dir, file);
                fs.stat(file, function(err, stats) {
                    if (err) {
                        running = 0;
                        callback(err);
                        return;
                    }
                    if (stats.isDirectory()) {
                        find(file);
                    } else if (stats.isFile() && path.extname(file) === ext) {
                        found.push(file);
                    }
                    if (running && !--running) callback(null, found);
                });
            });
            if (running && !--running) callback(null, found);
        });
    })(this.path());
};

// https://gist.github.com/707661
External.mkdirp = function mkdirP(p, mode, f) {
    var cb = f || function() {};
    if (p.charAt(0) != '/') {
        cb('Relative path: ' + p);
        return;
    }

    var ps = path.normalize(p).split('/');
    path.exists(p, function(exists) {
        if (exists) cb(null);
        else mkdirP(ps.slice(0, -1).join('/'), mode, function(err) {
            if (err && err.errno != process.EEXIST) cb(err);
            else {
                fs.mkdir(p, mode, cb);
            }
        });
    });
};

External.types = [
    {
        extension: /\.zip/,
        datafile: function(d, c) { d.findOneByExtension('.shp', c); },
        ds_options: {
            type: 'shape'
        }
    },
    {
        extension: /\.shp/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'shape'
        }
    },
    {
        extension: /\.png/,
        datafile: function(d, c) { c(null, d.path()); }
    },
    {
        extension: /\.jpe?g/
    },
    {
        extension: /\.geotiff?|\.tiff?/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'gdal'
        }
    },
    {
        extension: /\.vrt/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'gdal'
        }
    },
    {
        extension: /\.kml/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'ogr',
            layer_by_index: 0
        }
    },
    {
        extension: /\.geojson|\.json/,
        datafile: function(d, c) { c(null, d.path()); },
        ds_options: {
            type: 'ogr',
            layer_by_index: 0
        }
    },
    {
        extension: /\.rss/,
        datafile: function(d, c) { c(d.path()); },
        ds_options: {
            type: 'ogr',
            layer_by_index: 0
        }
    },
    {
        extension: /.*/g,
        datafile: function(d, c) { c(d.path()); }
    }
];

External.findType = function(ext) {
    for (var i in External.types) {
        if (ext.match(External.types[i].extension)) {
            return External.types[i];
        }
    }
};

// Destinations are names in the data_dir/cache directory.
External.destinations = {};
External.destinations['default'] = function(uri) {
    return crypto.createHash('md5').update(uri).digest('hex') + path.extname(uri);
};
External.destinations['.zip'] = function(uri) {
    return crypto.createHash('md5').update(uri).digest('hex');
};

External.processors = {};
External.processors['default'] = function(tempPath, destPath, callback) {
    if (tempPath === destPath) {
        callback(null);
    } else {
        fs.rename(tempPath, destPath, callback);
    }
};

External.processors['.zip'] = function(tempPath, destPath, callback) {
    try {
        console.log('unzipping file');
        var zf = new zip.ZipFile(tempPath);
    } catch (err) {
        callback(err);
        return;
    }

    Step(
        function() {
            var group = this.group();
            zf.names.forEach(function(name) {
                var next = group();
                var uncompressed = path.join(destPath, name);
                External.mkdirp(path.dirname(uncompressed), 0755, function(err) {
                    if (err && err.errno != constants.EEXIST) {
                        callback("Couldn't create directory " + path.dirname(name));
                    }
                    else {
                        // if just a directory skip ahead
                        if (!path.extname(name) || name[0] === '.') {
                            next();
                        } else {
                            var buffer = zf.readFile(name, function(err, buffer) {
                                fd = fs.open(uncompressed, 'w', 0755, function(err, fd) {
                                    sys.debug('saving to: ' + uncompressed);
                                    fs.write(fd, buffer, 0, buffer.length, null,
                                        function(err, written) {
                                            fs.close(fd, function(err) {
                                                next();
                                            });
                                        });
                                  });
                            });
                        }
                    }
                });
            });
        },
        callback
    );
};

module.exports = External;
<|endoftext|>


<commit_before>angular.module('app', [
  'ui.router',
  'event'
  ])
  .config(function ($urlRouterProvider, $httpProvider, $stateProvider) {
    $urlRouterProvider.otherwise('/');

    $stateProvider
      .state('event', {
        url: '/',
        templateUrl: "app/event/event.html",
        controller: "eventCtrl"
      });
  });
  // .controller('MainCtrl', function ($scope) {

  // });<commit_msg>[modify] theming for angular material<commit_after>angular.module('app', [
  'ui.router',
  'event',
  'ngMaterial',
  'ngMdIcons'
  ])
  .config(function ($urlRouterProvider, $httpProvider, $stateProvider, $mdThemingProvider) {
    $urlRouterProvider.otherwise('/');

    var customBlueMap =     $mdThemingProvider.extendPalette('light-blue', {
        'contrastDefaultColor': 'light',
        'contrastDarkColors': ['50'],
        '50': 'ffffff'
      });
      $mdThemingProvider.definePalette('customBlue', customBlueMap);
      $mdThemingProvider.theme('default')
        .primaryPalette('customBlue', {
          'default': '500',
          'hue-1': '50'
        })
        .accentPalette('pink');
      $mdThemingProvider.theme('input', 'default')
            .primaryPalette('grey');

    $stateProvider
      .state('event', {
        url: '/',
        templateUrl: "app/event/event.html",
        controller: "eventCtrl"
      });
  });
  // .controller('MainCtrl', function ($scope) {

  // });<|endoftext|>


<commit_before>
var EchoPlugin = {
    echo:function(successCallback,errorCallback,strInput) {
        if(!strInput || !strInput.length) {
            errorCallback("Error, something was wrong with the input string. =>" + strInput);
        }
        else {
            successCallback(strInput + "echo");
        }
    }
}<commit_msg>updated common-echoplugin.js to call exec which gets mapped to proxy on windows8<commit_after>
var EchoPlugin = {
    // the echo function calls successCallback with the provided text in strInput
    // if strInput is empty, it will call the errorCallback
    echo:function(successCallback, errorCallback, strInput) {
        cordova.exec(successCallback,errorCallback,"EchoPlugin","echo",[strInput]);
    }
}

module.exports = EchoPlugin;
<|endoftext|>


<commit_before>/*jshint laxcomma:true*/
/*global 'setTimeout':false, 'document':false, 'window':false, 'console':false*/

require.config({
  paths: {
    ace         : '/js/lib/ace'
  , io          : '/socket.io/socket.io'
  , domReady    : '/js/lib/domReady'
  , createEditor: '/js/createEditor'
  }
});

require(['domReady', 'jquery', 'createEditor', 'io'], function(domReady, $, createEditor, io) {
  "use strict";
  domReady(function() {
    var updateCount = 0;

    var update = function(){
      if (--updateCount === 0) {
        document.getElementById('tests').contentDocument.location.reload(true);
      }
    };

    var editors = {};
    editors.p = createEditor('editor-p');
    editors.o = createEditor('editor-o', true);

    // Declare a global to make the player's editor available to the jasmine iframe.
    // TODO: Make this less ugly, maybe by passing this information through sockets.
    // TODO: Make editor naming scheme more consistent across files
    window.xeditor1 = editors.p;

    // Event listeners
    $('#skip-button').click(function(e) {
      e.preventDefault();
      console.log('skip this round button clicked');
    });

    $('#reset-button').click(function(e) {
      e.preventDefault();
      console.log('reset editor area button clicked');
    });

    $('#login-button').click(function(e) {
      e.preventDefault();
      console.log('log in button clicked');
    });

    // Socket connections
    var socket = io.connect();

    socket.on('error', function(e){
      console.error('Unable to create Socket.io connection. Error: ', e);
    });

    socket.on('connect', function(){
      console.info('Socket.io connection established');
    });

    // TODO: security hole: client could broadcast this event to anyone connected
    socket.on('beginGame', function(message){
      setTimeout(function(){
        // TODO: Pass this directly to the testrunner using a socket event
        // TODO: Load specs at this phase rather than on pageload.
        window.xfunction = message;
        editors.p.setValue(message.desc.join('\n') + '\n' + message.boiler.join('\n'));
      }, 2500);
    });

    socket.on('updateEditor', function(message){
      editors.o.setValue(message);
    });

    editors.p.on('change', function(){
      updateCount++;
      socket.emit('editorChange', editors.p.getValue());
      setTimeout(update, 1200);
    });

  });
});
<commit_msg>Added todos for interface buttons<commit_after>/*jshint laxcomma:true*/
/*global 'setTimeout':false, 'document':false, 'window':false, 'console':false*/

require.config({
  paths: {
    ace         : '/js/lib/ace'
  , io          : '/socket.io/socket.io'
  , domReady    : '/js/lib/domReady'
  , createEditor: '/js/createEditor'
  }
});

require(['domReady', 'jquery', 'createEditor', 'io'], function(domReady, $, createEditor, io) {
  "use strict";
  domReady(function() {
    var updateCount = 0;

    var update = function(){
      if (--updateCount === 0) {
        document.getElementById('tests').contentDocument.location.reload(true);
      }
    };

    var editors = {};
    editors.p = createEditor('editor-p');
    editors.o = createEditor('editor-o', true);

    // Declare a global to make the player's editor available to the jasmine iframe.
    // TODO: Make this less ugly, maybe by passing this information through sockets.
    // TODO: Make editor naming scheme more consistent across files
    window.xeditor1 = editors.p;

    // Event listeners
    $('#skip-button').click(function(e) {
      //TODO: Implement this
      e.preventDefault();
      console.log('skip this round button clicked');
    });

    $('#reset-button').click(function(e) {
      //TODO: Implement this
      e.preventDefault();
      console.log('reset editor area button clicked');
    });

    $('#login-button').click(function(e) {
      //TODO: Implement this
      e.preventDefault();
      console.log('log in button clicked');
    });

    // Socket connections
    var socket = io.connect();

    socket.on('error', function(e){
      console.error('Unable to create Socket.io connection. Error: ', e);
    });

    socket.on('connect', function(){
      console.info('Socket.io connection established');
    });

    // TODO: security hole: client could broadcast this event to anyone connected
    socket.on('beginGame', function(message){
      setTimeout(function(){
        // TODO: Pass this directly to the testrunner using a socket event
        // TODO: Load specs at this phase rather than on pageload.
        window.xfunction = message;
        editors.p.setValue(message.desc.join('\n') + '\n' + message.boiler.join('\n'));
      }, 2500);
    });

    socket.on('updateEditor', function(message){
      editors.o.setValue(message);
    });

    editors.p.on('change', function(){
      updateCount++;
      socket.emit('editorChange', editors.p.getValue());
      setTimeout(update, 1200);
    });

  });
});
<|endoftext|>


<commit_before>(function() {

    var searchIco = document.getElementById('search'),
        searchWrap = document.getElementById('search-wrap'),
        keyInput = document.getElementById('key'),
        back = document.getElementById('back'),
        searchPanel = document.getElementById('search-panel'),
        searchResult = document.getElementById('search-result'),
        searchTpl = document.getElementById('search-tpl').innerHTML,
        searchData;

    function loadData(success) {

        if (!searchData) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', '/content.json', true);

            xhr.onload = function() {
                if (this.status >= 200 && this.status < 300) {
                    searchData = JSON.parse(this.response);
                    success(searchData);
                } else {
                    console.error(this.statusText);
                }
            };

            xhr.onerror = function() {
                console.error(this.statusText);
            };

            xhr.send();

        } else {
            success(searchData);
        }
    }

    function tpl(html, data) {
        return html.replace(/\{\w+\}/g, function(str) {
            var prop = str.replace(/\{|\}/g, '');
            return data[prop] || '';
        });
    }

    var docEl = document[navigator.userAgent.indexOf('Firefox') !== -1 ? 'documentElement' : 'body'],
        noop = function() {};

    var Control = {
        show: function() {
            window.innerWidth < 760 ? docEl.classList.add('lock-size') : noop;
            searchPanel.classList.add('in');
        },
        hide: function() {
            window.innerWidth < 760 ? docEl.classList.remove('lock-size') : noop;
            searchPanel.classList.remove('in');
        }
    };

    function render(data) {
        var html = '';
        if (data.length) {

            html = data.map(function(post) {

                return tpl(searchTpl, {
                    title: post.title,
                    path: post.path,
                    date: new Date(post.date).toLocaleDateString(),
                    tags: post.tags.map(function(tag) {
                        return '#' + tag.name + '';
                    }).join('')
                });

            }).join('');

        } else {
            html = '

Results not found!

';
        }

        searchResult.innerHTML = html;
    }

    function matcher(post, regExp) {

        return regExp.test(post.title) || post.tags.some(function(tag) {
            return regExp.test(tag.name);
        }) || regExp.test(post.text);
    }

    function search(e) {
        var key = this.value.trim();
        if (!key) {
            return;
        }

        var regExp = new RegExp(key.replace(/[ ]/g, '|'), 'gmi');

        loadData(function(data) {

            var result = data.filter(function(post) {
                return matcher(post, regExp);
            });

            render(result);
            Control.show();
        });

        e.preventDefault();
    }

    searchIco.addEventListener('click', function() {
        searchWrap.classList.toggle('in');
        keyInput.value = '';
    });

    back.addEventListener('click', function() {
        searchWrap.classList.remove('in');
        Control.hide();
    });

    document.addEventListener('click', function(e) {
        if (e.target.id !== 'key') {
            Control.hide();
        }
    });

    keyInput.addEventListener('input', search);
    keyInput.addEventListener('click', search);

})();
<commit_msg>fixed a search bug<commit_after>(function() {

    var searchIco = document.getElementById('search'),
        searchWrap = document.getElementById('search-wrap'),
        keyInput = document.getElementById('key'),
        back = document.getElementById('back'),
        searchPanel = document.getElementById('search-panel'),
        searchResult = document.getElementById('search-result'),
        searchTpl = document.getElementById('search-tpl').innerHTML,
        searchData;

    function loadData(success) {

        if (!searchData) {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', '/content.json', true);

            xhr.onload = function() {
                if (this.status >= 200 && this.status < 300) {
                    searchData = JSON.parse(this.response);
                    success(searchData);
                } else {
                    console.error(this.statusText);
                }
            };

            xhr.onerror = function() {
                console.error(this.statusText);
            };

            xhr.send();

        } else {
            success(searchData);
        }
    }

    function tpl(html, data) {
        return html.replace(/\{\w+\}/g, function(str) {
            var prop = str.replace(/\{|\}/g, '');
            return data[prop] || '';
        });
    }

    var docEl = document[navigator.userAgent.indexOf('Firefox') !== -1 ? 'documentElement' : 'body'],
        noop = function() {};

    var Control = {
        show: function() {
            window.innerWidth < 760 ? docEl.classList.add('lock-size') : noop;
            searchPanel.classList.add('in');
        },
        hide: function() {
            window.innerWidth < 760 ? docEl.classList.remove('lock-size') : noop;
            searchPanel.classList.remove('in');
        }
    };

    function render(data) {
        var html = '';
        if (data.length) {

            html = data.map(function(post) {

                return tpl(searchTpl, {
                    title: post.title,
                    path: post.path,
                    date: new Date(post.date).toLocaleDateString(),
                    tags: post.tags.map(function(tag) {
                        return '#' + tag.name + '';
                    }).join('')
                });

            }).join('');

        } else {
            html = '

Results not found!

';
        }

        searchResult.innerHTML = html;
    }

    function matcher(post, regExp) {

        regExp.lastIndex = 0;

        return regExp.test(post.title) || post.tags.some(function(tag) {
            return regExp.test(tag.name);
        }) || regExp.test(post.text);
    }

    function search(e) {
        var key = this.value.trim();
        if (!key) {
            return;
        }

        var regExp = new RegExp(key.replace(/[ ]/g, '|'), 'gmi');

        loadData(function(data) {

            var result = data.filter(function(post) {
                return matcher(post, regExp);
            });

            render(result);
            Control.show();
        });

        e.preventDefault();
    }

    searchIco.addEventListener('click', function() {
        searchWrap.classList.toggle('in');
        keyInput.value = '';
    });

    back.addEventListener('click', function() {
        searchWrap.classList.remove('in');
        Control.hide();
    });

    document.addEventListener('click', function(e) {
        if (e.target.id !== 'key') {
            Control.hide();
        }
    });

    keyInput.addEventListener('input', search);
    keyInput.addEventListener('click', search);

})();
<|endoftext|>