<commit_before>module.exports = newRepo;

// platform options are: db, proto, and trace
function newRepo(conf, platform) {
  var trace = platform.trace;
  var sha1 = platform.sha1;
  var bops = platform.bops;
  var db = conf.db;
  var fs = conf.fs;
  var index = conf.index;
  var proto = conf.proto;

  var encoders = {
    commit: encodeCommit,
    tag: encodeTag,
    tree: encodeTree,
    blob: encodeBlob
  };

  var decoders = {
    commit: decodeCommit,
    tag: decodeTag,
    tree: decodeTree,
    blob: decodeBlob
  };

  var repo = {};

  if (db) {
    // Git Objects
    repo.load = load;       // (hashish) -> object
    repo.save = save;       // (object) -> hash
    repo.loadAs = loadAs;   // (type, hashish) -> value
    repo.saveAs = saveAs;   // (type, value) -> hash
    repo.remove = remove;   // (hashish)

    // Refs
    repo.resolveHashish = resolveHashish; // (hashish) -> hash
    repo.updateHead = updateHead;         // (hash)
    repo.getBranch = getBranch;           // () -> branchName
    repo.setBranch = setBranch;           // (branchName)
    repo.createBranch = createBranch;     // (branchName, hash)
    repo.deleteBranch = deleteBranch;     // (branchName)
    repo.listBranches = listBranches;     // () -> branchNames
    repo.createTag = createTag;           // (tagName, hash)
    repo.deleteTag = deleteTag;           // (tagName)
    repo.listTags = listTags;             // () -> tagNames

    if (fs && index) {
      // TODO: design API for working directories and staging areas.
    }
  }

  // Network Protocols
  if (proto) {
    repo.lsRemote = proto.lsRemote;
    if (db) {
      repo.fetch = fetch;
      repo.push = push;
    }
  }

  return repo;

  function load(hashish, callback) {
    if (!callback) return load.bind(this, hashish);
    return resolveHashish(hashish, function (err, hash) {
      if (err) return callback(err);
      return db.load(hash, function (err, buffer) {
        if (err) return callback(err);
        var checkHash, type, object;
        try {
          var pair = deframe(buffer);
          type = pair[0];
          buffer = pair[1];
          checkHash = sha1(buffer);
          object = {
            type: type,
            body: decoders[type](buffer)
          };
        } catch (err) {
          if (err) return callback(err);
        }
        if (checkHash !== hash) {
          return callback(new Error("Hash checksum failed for " + hash));
        }
        if (trace) trace("load", hash);
        return callback(null, object);
      });
    });
  }

  function save(object, callback) {
    if (!callback) return save.bind(this, object);
    var buffer, hash;
    try {
      buffer = encoders[object.type](object.body);
      hash = sha1(buffer);
      buffer = frame(object.type, buffer);
    }
    catch (err) {
      return callback(err);
    }
    return db.save(hash, buffer, function (err) {
      if (err) return callback(err);
      if (trace) trace("save", hash);
      return callback(null, hash);
    });
  }

  function loadAs(type, hashish, callback) {
    if (!callback) return loadAs.bind(this, type, hashish);
    return load(hashish, function (err, object) {
      if (err) return callback(err);
      if (object.type !== type) {
        return new Error("Expected " + type + ", but found " + object.type);
      }
      return callback(null, object.body);
    });
  }

  function saveAs(type, body, callback) {
    if (!callback) return saveAs.bind(this, type, body);
    return save({ type: type, body: body }, callback);
  }

  function remove(hashish, callback) {
    if (!callback) return remove.bind(this, hashish);
    return resolveHashish(hashish, function (err, hash) {
      if (err) return callback(err);
      return db.remove(hash, function (err) {
        if (err) return callback(err);
        if (trace) trace("remove", hash);
        return callback();
      });
    });
  }

  function resolveHashish(hashish, callback) {
    if (!callback) return resolveHashish.bind(this, hashish);
    hashish = hashish.trim();
    if ((/^[0-9a-f]{40}$/i).test(hashish)) {
      return callback(null, hashish.toLowerCase());
    }
    if (hashish === "HEAD") {
      return getBranch(function (err, ref) {
        if (err) return callback(err);
        return resolveHashish(ref, callback);
      });
    }
    if ((/^refs\//).test(hashish)) {
      return db.read(hashish, checkBranch);
    }
    return checkBranch();
    function checkBranch(err, hash) {
      if (err) return callback(err);
      if (hash) return resolveHashish(hash, callback);
      return db.read("refs/heads/" + hashish, checkTag);
    }
    function checkTag(err, hash) {
      if (err) return callback(err);
      if (hash) return resolveHashish(hash, callback);
      return db.read("refs/tags/" + hashish, final);
    }
    function final(err, hash) {
      if (err) return callback(err);
      if (hash) return resolveHashish(hash, callback);
      return callback(new Error("Cannot find hashish: " + hashish));
    }
  }

  function updateHead(hash, callback) {
    if (!callback) return updateHead.bind(this, hash);
    return getBranch(function (err, ref) {
      if (err) return callback(err);
      return db.write(ref, hash, callback);
    });
  }

  function getBranch(callback) {
    if (!callback) return getBranch.bind(this);
    return db.read("HEAD", function (err, ref) {
      if (err) return callback(err);
      if (!ref) return callback(new Error("Missing HEAD"));
      var match = ref.match(/^ref: *(.*)/);
      if (!match) return callback(new Error("Invalid HEAD"));
      return callback(null, match[1]);
    });
  }

  function setBranch(branchName, callback) {
    if (!callback) return setBranch.bind(this, branchName);
    return db.write("HEAD", "ref: refs/heads/" + branchName + "\n", callback);
  }

  function createBranch(branchName, hash, callback) {
    if (!callback) return createBranch.bind(this, branchName, hash);
    return createThing("refs/heads/", branchName, hash, callback);
  }

  function createTag(tagName, hash, callback) {
    if (!callback) return createTag.bind(this, tagName, hash);
    return createThing("refs/tags/", tagName, hash, callback);
  }

  function createThing(prefix, name, hash, callback) {
    return db.write(prefix + name, hash + "\n", callback);
  }

  function deleteBranch(branchName, callback) {
    if (!callback) return deleteBranch.bind(this, branchName);
    return deleteThing("refs/heads/", branchName, callback);
  }

  function deleteTag(tagName, callback) {
    if (!callback) return deleteTag.bind(this, tagName);
    return deleteThing("refs/tags/", tagName, callback);
  }

  function deleteThing(prefix, name, callback) {
    return db.unlink(prefix + name, callback);
  }

  function listBranches(callback) {
    if (!callback) return listBranches.bind(this);
    return listThings("refs/heads/", callback);
  }

  function listTags(callback) {
    if (!callback) return listTags.bind(this);
    return listThings("refs/tags/", callback);
  }

  function listThings(prefix, callback) {
    var branches = {};
    return loadDir(prefix, function (err) {
      if (err) return callback(err);
      callback(null, branches);
    });

    function loadDir(dir, callback) {
      var list;
      return db.readdir(dir, function (err, names) {
        if (err) return callback(err);
        list = new Array(names.length);
        for (var i = 0, l = names.length; i < l; ++i) {
          list[i] = dir + "/" + names[i];
        }
        return shift();
      });
      function shift(err) {
        if (err) return callback(err);
        var target = list.shift();
        if (!target) return callback();
        return db.read(target, function (err, hash) {
          if (err) return callback(err);
          if (hash) {
            branches[target.substr(11)] = hash.trim();
            return shift();
          }
          return loadDir(target, shift);
        });
      }
    }
  }

  function fetch() {
    throw new Error("TODO: Implement repo.fetch");
  }

  function push() {
    throw new Error("TODO: Implement repo.fetch");
  }

  function deframe(buffer) {
    throw new Error("TODO: Implement frame");
  }

  function frame(type, buffer) {
    throw new Error("TODO: Implement deframe");

  }

  function encodeCommit(commit) {
    throw new Error("TODO: Implement encodeCommit");
  }

  function encodeTag(tag) {
    throw new Error("TODO: Implement encodeTag");
  }

  function encodeTree(tree) {
    throw new Error("TODO: Implement encodeTree");
  }

  function encodeBlob(blob) {
    throw new Error("TODO: Implement encodeBlob");
  }

  function decodeCommit(buffer) {
    throw new Error("TODO: Implement decodeCommit");
  }

  function decodeTag(buffer) {
    throw new Error("TODO: Implement decodeTag");
  }

  function decodeTree(buffer) {
    throw new Error("TODO: Implement decodeTree");
  }

  function decodeBlob(buffer) {
    return buffer;
  }

}

<commit_msg>Implement writable side of git core<commit_after>module.exports = newRepo;

// platform options are: db, proto, and trace
function newRepo(conf, platform) {
  var trace = platform.trace;
  var sha1 = platform.sha1;
  var bops = platform.bops;
  var db = conf.db;
  var fs = conf.fs;
  var index = conf.index;
  var proto = conf.proto;

  var encoders = {
    commit: encodeCommit,
    tag: encodeTag,
    tree: encodeTree,
    blob: encodeBlob
  };

  var decoders = {
    commit: decodeCommit,
    tag: decodeTag,
    tree: decodeTree,
    blob: decodeBlob
  };

  var repo = {};

  if (db) {
    // Git Objects
    repo.load = load;       // (hashish) -> object
    repo.save = save;       // (object) -> hash
    repo.loadAs = loadAs;   // (type, hashish) -> value
    repo.saveAs = saveAs;   // (type, value) -> hash
    repo.remove = remove;   // (hashish)

    // Refs
    repo.resolveHashish = resolveHashish; // (hashish) -> hash
    repo.updateHead = updateHead;         // (hash)
    repo.getBranch = getBranch;           // () -> branchName
    repo.setBranch = setBranch;           // (branchName)
    repo.createBranch = createBranch;     // (branchName, hash)
    repo.deleteBranch = deleteBranch;     // (branchName)
    repo.listBranches = listBranches;     // () -> branchNames
    repo.createTag = createTag;           // (tagName, hash)
    repo.deleteTag = deleteTag;           // (tagName)
    repo.listTags = listTags;             // () -> tagNames

    if (fs && index) {
      // TODO: design API for working directories and staging areas.
    }
  }

  // Network Protocols
  if (proto) {
    repo.lsRemote = proto.lsRemote;
    if (db) {
      repo.fetch = fetch;
      repo.push = push;
    }
  }

  return repo;

  function load(hashish, callback) {
    if (!callback) return load.bind(this, hashish);
    return resolveHashish(hashish, function (err, hash) {
      if (err) return callback(err);
      return db.load(hash, function (err, buffer) {
        if (err) return callback(err);
        var type, object;
        try {
          if (sha1(buffer) !== hash) {
            throw new Error("Hash checksum failed for " + hash);
          };
          var pair = deframe(buffer);
          type = pair[0];
          buffer = pair[1];
          object = {
            type: type,
            body: decoders[type](buffer)
          };
        } catch (err) {
          if (err) return callback(err);
        }
        if (trace) trace("load", hash);
        return callback(null, object);
      });
    });
  }

  function save(object, callback) {
    if (!callback) return save.bind(this, object);
    var buffer, hash;
    try {
      buffer = encoders[object.type](object.body);
      buffer = frame(object.type, buffer);
      hash = sha1(buffer);
    }
    catch (err) {
      return callback(err);
    }
    return db.save(hash, buffer, function (err) {
      if (err) return callback(err);
      if (trace) trace("save", hash);
      return callback(null, hash);
    });
  }

  function loadAs(type, hashish, callback) {
    if (!callback) return loadAs.bind(this, type, hashish);
    return load(hashish, function (err, object) {
      if (err) return callback(err);
      if (object.type !== type) {
        return new Error("Expected " + type + ", but found " + object.type);
      }
      return callback(null, object.body);
    });
  }

  function saveAs(type, body, callback) {
    if (!callback) return saveAs.bind(this, type, body);
    return save({ type: type, body: body }, callback);
  }

  function remove(hashish, callback) {
    if (!callback) return remove.bind(this, hashish);
    return resolveHashish(hashish, function (err, hash) {
      if (err) return callback(err);
      return db.remove(hash, function (err) {
        if (err) return callback(err);
        if (trace) trace("remove", hash);
        return callback();
      });
    });
  }

  function resolveHashish(hashish, callback) {
    if (!callback) return resolveHashish.bind(this, hashish);
    hashish = hashish.trim();
    if ((/^[0-9a-f]{40}$/i).test(hashish)) {
      return callback(null, hashish.toLowerCase());
    }
    if (hashish === "HEAD") {
      return getBranch(function (err, ref) {
        if (err) return callback(err);
        return resolveHashish(ref, callback);
      });
    }
    if ((/^refs\//).test(hashish)) {
      return db.read(hashish, checkBranch);
    }
    return checkBranch();
    function checkBranch(err, hash) {
      if (err) return callback(err);
      if (hash) return resolveHashish(hash, callback);
      return db.read("refs/heads/" + hashish, checkTag);
    }
    function checkTag(err, hash) {
      if (err) return callback(err);
      if (hash) return resolveHashish(hash, callback);
      return db.read("refs/tags/" + hashish, final);
    }
    function final(err, hash) {
      if (err) return callback(err);
      if (hash) return resolveHashish(hash, callback);
      return callback(new Error("Cannot find hashish: " + hashish));
    }
  }

  function updateHead(hash, callback) {
    if (!callback) return updateHead.bind(this, hash);
    return getBranch(function (err, ref) {
      if (err) return callback(err);
      return db.write(ref, hash, callback);
    });
  }

  function getBranch(callback) {
    if (!callback) return getBranch.bind(this);
    return db.read("HEAD", function (err, ref) {
      if (err) return callback(err);
      if (!ref) return callback(new Error("Missing HEAD"));
      var match = ref.match(/^ref: *(.*)/);
      if (!match) return callback(new Error("Invalid HEAD"));
      return callback(null, match[1]);
    });
  }

  function setBranch(branchName, callback) {
    if (!callback) return setBranch.bind(this, branchName);
    return db.write("HEAD", "ref: refs/heads/" + branchName + "\n", callback);
  }

  function createBranch(branchName, hash, callback) {
    if (!callback) return createBranch.bind(this, branchName, hash);
    return createThing("refs/heads/", branchName, hash, callback);
  }

  function createTag(tagName, hash, callback) {
    if (!callback) return createTag.bind(this, tagName, hash);
    return createThing("refs/tags/", tagName, hash, callback);
  }

  function createThing(prefix, name, hash, callback) {
    return db.write(prefix + name, hash + "\n", callback);
  }

  function deleteBranch(branchName, callback) {
    if (!callback) return deleteBranch.bind(this, branchName);
    return deleteThing("refs/heads/", branchName, callback);
  }

  function deleteTag(tagName, callback) {
    if (!callback) return deleteTag.bind(this, tagName);
    return deleteThing("refs/tags/", tagName, callback);
  }

  function deleteThing(prefix, name, callback) {
    return db.unlink(prefix + name, callback);
  }

  function listBranches(callback) {
    if (!callback) return listBranches.bind(this);
    return listThings("refs/heads/", callback);
  }

  function listTags(callback) {
    if (!callback) return listTags.bind(this);
    return listThings("refs/tags/", callback);
  }

  function listThings(prefix, callback) {
    var branches = {};
    return loadDir(prefix, function (err) {
      if (err) return callback(err);
      callback(null, branches);
    });

    function loadDir(dir, callback) {
      var list;
      return db.readdir(dir, function (err, names) {
        if (err) return callback(err);
        list = new Array(names.length);
        for (var i = 0, l = names.length; i < l; ++i) {
          list[i] = dir + "/" + names[i];
        }
        return shift();
      });
      function shift(err) {
        if (err) return callback(err);
        var target = list.shift();
        if (!target) return callback();
        return db.read(target, function (err, hash) {
          if (err) return callback(err);
          if (hash) {
            branches[target.substr(11)] = hash.trim();
            return shift();
          }
          return loadDir(target, shift);
        });
      }
    }
  }

  function fetch() {
    throw new Error("TODO: Implement repo.fetch");
  }

  function push() {
    throw new Error("TODO: Implement repo.fetch");
  }

  function indexOf(buffer, byte, i) {
    i |= 0;
    var length = buffer.length;
    for (;;i++) {
      if (i >= length) return -1;
      if (buffer[i] === byte) return i;
    }
  }

  function parseAscii(buffer, start, end) {
    var val = "";
    while (start < end) {
      val += String.fromCharCode(buffer[start++]);
    }
    return val;
  }

  function parseDec(buffer, start, end) {
    var val = 0;
    while (start < end) {
      val = val * 10 + buffer[start++] - 0x30;
    }
    return val;
  }

  function deframe(buffer) {
    var space = indexOf(buffer, 0x20);
    if (space < 0) throw new Error("Invalid git object buffer");
    var nil = indexOf(buffer, 0x00, space);
    if (nil < 0) throw new Error("Invalid git object buffer");
    var body = bops.subarray(buffer, nil + 1);
    var size = parseDec(buffer, space + 1, nil);
    if (size !== body.length) throw new Error("Invalid body length.");
    return [
      parseAscii(buffer, 0, space),
      body
    ];
  }

  function frame(type, body) {
    return bops.join([
      bops.from(type + " " + body.length + "\0"),
      body
    ]);
  }

  function encodeCommit(commit) {
    var str = "";
    Object.keys(commit).forEach(function (key) {
      if (key === "message") return;
      var value = commit[key];
      if (key === "parents") {
        value.forEach(function (value) {
          str += "parent " + value + "\n";
        });
      }
      else {
        str += key + " " + value + "\n";
      }
    });
    return bops.from(str + "\n" + commit.message);
  }

  function encodeTag(tag) {
    var str = "";
    Object.keys(tag).forEach(function (key) {
      if (key === "message") return;
      var value = tag[key];
      str += key + " " + value + "\n";
    });
    return bops.from(str + "\n" + tag.message);
  }

  function pathCmp(a, b) {
    a += "/"; b += "/";
    return a < b ? -1 : a > b ? 1 : 0;
  }

  function encodeTree(tree) {
    var chunks = [];
    Object.keys(tree).sort(pathCmp).forEach(function (name) {
      var entry = tree[name];
      chunks.push(
        bops.from(entry.mode.toString(8) + " " + name + "\0"),
        bops.from(entry.hash, "hex")
      );
    });
    return bops.join(chunks);
  }

  function encodeBlob(blob) {
    if (bops.is(blob)) return blob;
    return bops.from(blob);
  }

  function decodeCommit(buffer) {
    throw new Error("TODO: Implement decodeCommit");
  }

  function decodeTag(buffer) {
    throw new Error("TODO: Implement decodeTag");
  }

  function decodeTree(buffer) {
    throw new Error("TODO: Implement decodeTree");
  }

  function decodeBlob(buffer) {
    return buffer;
  }

}

<|endoftext|>


<commit_before>/**
 * Spies property usage of a given object.
 *
 * Works in modern browsers only, these that support:
 * - Object.defineProperty
 * - Object.keys
 * - Array.prototype.forEach
 *
 * Be careful with IE8. Even though it supports Object.defineProperty, it's implementation is not valid.
 *
 *
 *
 * # Sample Usage
 *
 *   // Object to be spied:
 *   var user = { name: 'Maciej', surname: 'Smolinski', fullName: 'Maciej Smolinski' };
 *
 *   // Spy it's properties, debug info namespaced with 'user' label:
 *   spyProperties('user', user);
 *
 *   // Access object's properties as usual:
 *   console.log('Full Name is: ' + user.name + ' ' + user.surname);
 *
 *   // Watch debug info in the console:
 *   [Property Usage] user.name
 *   [Property Usage] user.surname
 *
 *
 * @param  {String} debugNamespace  Debugging label (namespace)
 * @param  {Object} objectReference Object which properties you want to spy
 * @return {void}
 */
function spyProperties (debugNamespace, objectReference) {
  // @TODO: Spy unless already spied
  // @TODO: Detect Object.defineProperty, Object.keys and Array.prototype.forEach
  // @TODO: Maybe add an execution time to each debug information so the developer gets an understanding on how long does each part of the code execute

  Object.keys(objectReference).forEach(function (property) {

    var __property = '__' + property;

    try {

      // Store original value as __<propertyName>
      objectReference[__property] = objectReference[property];
      // Reset property to undefined
      objectReference[property]        = undefined;

      // Define spy (will write debug info into console and return original value)
      Object.defineProperty(objectReference, property, {
        get: function () {

          // Write debug info into console
          console.debug('[Property Usage] %debugNamespace.%property'
            .replace('%debugNamespace', debugNamespace)
            .replace('%property', property)
          );

          // Return original value
          return objectReference[__property];

        }
      });

    } catch (error) {
      // The only workaround for Object.defineProperty problems in IE8

      if (objectReference[__property]) {
        // Restore original value
        objectReference[property]        = objectReference[__property];
        // Reset __<property> to undefined
        objectReference[__property] = undefined;
      }

    }
  });

}<commit_msg>+ Inline equal chars<commit_after>/**
 * Spies property usage of a given object.
 *
 * Works in modern browsers only, these that support:
 * - Object.defineProperty
 * - Object.keys
 * - Array.prototype.forEach
 *
 * Be careful with IE8. Even though it supports Object.defineProperty, it's implementation is not valid.
 *
 *
 *
 * # Sample Usage
 *
 *   // Object to be spied:
 *   var user = { name: 'Maciej', surname: 'Smolinski', fullName: 'Maciej Smolinski' };
 *
 *   // Spy it's properties, debug info namespaced with 'user' label:
 *   spyProperties('user', user);
 *
 *   // Access object's properties as usual:
 *   console.log('Full Name is: ' + user.name + ' ' + user.surname);
 *
 *   // Watch debug info in the console:
 *   [Property Usage] user.name
 *   [Property Usage] user.surname
 *
 *
 * @param  {String} debugNamespace  Debugging label (namespace)
 * @param  {Object} objectReference Object which properties you want to spy
 * @return {void}
 */
function spyProperties (debugNamespace, objectReference) {
  // @TODO: Spy unless already spied
  // @TODO: Detect Object.defineProperty, Object.keys and Array.prototype.forEach
  // @TODO: Maybe add an execution time to each debug information so the developer gets an understanding on how long does each part of the code execute

  Object.keys(objectReference).forEach(function (property) {

    var __property = '__' + property;

    try {

      // Store original value as __<propertyName>
      objectReference[__property] = objectReference[property];
      // Reset property to undefined
      objectReference[property]   = undefined;

      // Define spy (will write debug info into console and return original value)
      Object.defineProperty(objectReference, property, {
        get: function () {

          // Write debug info into console
          console.debug('[Property Usage] %debugNamespace.%property'
            .replace('%debugNamespace', debugNamespace)
            .replace('%property', property)
          );

          // Return original value
          return objectReference[__property];

        }
      });

    } catch (error) {
      // The only workaround for Object.defineProperty problems in IE8

      if (objectReference[__property]) {
        // Restore original value
        objectReference[property]   = objectReference[__property];
        // Reset __<property> to undefined
        objectReference[__property] = undefined;
      }

    }
  });

}<|endoftext|>


<commit_before>var app = app || {};

(function() {

	if (location.hash === '#tabletmode') {
		sessionStorage.tabletMode = 'true';
		location.hash = '/';
	}

	// this is the place the user codes
	var myCodeMirror;

	// this is a unique id assigned to the current page
	var pageInstanceUID;

	app.readyToRun = false;

	if (localStorage.uid) {
		app.uid = JSON.parse(localStorage.uid);
	} else {
		app.uid = Date.now().toString(36);
		localStorage.uid = JSON.stringify(app.uid);
	}

	app.initPage = function() {
		// get the hash key
		app.hash = app.getHashKey();

		// create code input area
		app.initCodeMirror();

		// calculate editor layout
		refreshEditorLayout();

		app.diffEngine = window.diffEngine();
		app.diffEncoder = app.diffEngine.getEncoder();
		app.diffDecoder = app.diffEngine.getDecoder();

		// run the code
		app.run();

		// ensure CodeMirror code gets properly rendered
		requestAnimationFrame(function(){
			myCodeMirror.refresh();
		});

		// we're assuming they won't visit the same page twice within one second
		pageInstanceUID = Math.floor(Date.now()/1000);
		app.fb = new Firebase('https://udacity.firebaseio.com/android-layout/users/' + app.uid + '/' + app.hash + '/' + pageInstanceUID);

	};

	app.getHashKey = function() {
		var hash = location.hash;
		if (hash.length > 2 && hash.substr(0,2) === '#/') {
			return hash.slice(2);
		} else {
			return '';
		}
	};

	app.initCodeMirror = function(){
		// clear pre-existing code areas
		$('.input-area').html('');

		myCodeMirror = CodeMirror(document.querySelector('.input-area'), {
			value: app.getCodeForHash(),
			mode: "android-xml",
			lineNumbers: true,
	        lineWrapping: true,
			indentUnit: 4,
			fixedGutter: true,
			viewportMargin: Infinity,
			onChange: function() {
				app.run({ autorun: true });
			}
		});
	};

	app.getCodeForHash = function() {
		// this is for testing code (#/test/...)
		if (app.hash.slice(0,4) === 'test') {
			$.get('tests/android/' + app.hash.slice(12) + '.xml', function(data){
				myCodeMirror.setValue(data);
				myCodeMirror.refresh();
				app.run({
					code: data,
					force: true
				});
			}, 'text');
			$('.test-reference-image').attr('src', 'tests/android/' + app.hash.slice(12) + '.png');
			return '';
		}

		// we have a previously-saved version
		if (localStorage['code-' + app.hash]) {
			return JSON.parse( localStorage['code-' + app.hash] );
		}

		// return the default (if there is one)
		else {
			return app.getCodeForHashDefault();
		}

		return '';
	};

	app.getCodeForHashDefault = function() {
		if (app.androidCodeDefaults) {
			if (app.androidCodeDefaults[ app.hash ]) {
				return app.androidCodeDefaults[ app.hash ];
			} else {
				return app.androidCodeDefaults[ 'default' ];
			}
		}

		return '';
	};

	app.resetCodeToHashDefault = function() {
		myCodeMirror.setValue(app.getCodeForHashDefault());
		myCodeMirror.refresh();
	};

	// this runs after code is successfully evaluated
	function runSuccess(code) {
		if (!localStorage.debug) {
			clearTimeout(app.codeEvaluationTimeout);
		}

		// save current student code
		if (app.hash.slice(0,4) !== 'test') {
			localStorage['code-' + app.hash] = JSON.stringify(code);
		}

		$('html').removeClass('invalid-code evaluating-invalid-code');
		requestAnimationFrame(function(){
			$('html').addClass('valid-code');
		});

		$('.code-saved-msg').removeClass('code-not-saved');

	}

	// this runs if the code is considered invalid or unevaluatable
	function runFail (opt) {
		var code = opt.code;
		clearTimeout(app.codeEvaluationTimeout);
		$('html').removeClass('invalid-code').addClass('evaluating-invalid-code');

		app.codeEvaluationTimeout = setTimeout(function(){
			console.log('TIMEOUT');
	 		$('html').removeClass('evaluating-invalid-code').addClass('invalid-code');
		},2000);

		if (opt.errors) {
			opt.errors.forEach(function(errorID){
				// add any errors to the error stack
				app.errors.push({
					id: errorID
				});
			});
		}

		if (!localStorage.debug) {
			$('.code-saved-msg').addClass('code-not-saved');
		} else {
			console.log('failed, but saving anyway since we\'re in debug mode');
			runSuccess(code);
		}
	}

	function updateState (newState) {
		var state = app.state || {};

		// copy over any new parameters from the previous state
		for(key in newState) {
			state[key] = newState[key];
		}

		var diff = app.diffEncoder.push(state);
		app.state = state;
		// console.log(app.diffDecoder.getState().state);
		// console.log('pushing', diff);
		app.fb.child('diffs').push(diff);
	}

	// this function evaluates code based on the mode the app is in
	app.run = function (opt) {
		opt = opt || {};

		if (!app.readyToRun && !opt.force) return false;

		var codeRaw = opt.code || myCodeMirror.getValue();
		var code;
		var elemToRender;

		updateState({
			code: codeRaw
		});

		// run the code
		var mode = 'android-layout';
		if (mode === 'android-layout') {

			if (app.hash.slice(0,4) === 'test') {
				$('html').addClass('testing-mode');
				if (app.hash === 'test/android' || app.hash === 'test/android/') {
					forwardFillTestingHistory('#/test/android/', app.tests);
				}
			} else {
				$('html').removeClass('testing-mode');
			}

			// pre-processing hook
			code = app.androidLayout.prepareCodeForParsing( codeRaw );

			// catch easy-to-detect errors (like misaligned <>'s, quotes)
			app.androidLayout.xmlSanityCheck( codeRaw );

			// if we don't have code to render, exit early rather than throwing an error
			if (codeRaw === '') {
				return false;
			}

			// parse the XML
			try {
				app.parsedXML = jQuery.parseXML( code );
			} catch (e) {
				app.parsedXML = null;
			}

			if (app.parsedXML !== null) {
				// basic parsing and styling
				elemToRender = app.androidLayout.evaluateXML(app.parsedXML);

				// calculate all the layouts
				console.log('%c-------- layout pass at ' + Math.round(Date.now()/1000) + ' --------', 'color: #666');
				app.androidLayout.evaluateXMLPass2( app.parsedXML );
				if (app.errors().length > 0) {
					runFail({
						code: codeRaw
					});
				} else {
					runSuccess(codeRaw);
				}
			} else {

				runFail({
					code: codeRaw,
					errors: ['parseError']
				});

				$('html').removeClass('valid-code invalid-code')

			}
		}

		if (elemToRender) {
			$('.screen').html('').append(elemToRender);
		}

		renderErrors();

		renderHistoryLinkState();
		refreshEditorLayout();
		console.log('%c-------- end --------', 'color: #666');
	};

	function forwardFillTestingHistory (prefix, urls, startAtBeginning) {

		// add each test to the history
		urls.forEach(function(url){
			history.pushState({}, '', prefix + url);
		});

		// go to the first one
		if (startAtBeginning) {
			history.go((app.tests.length-1) * -1);
		}
	}

	// show the error list in the document
	function renderErrors () {
		var errors = app.errors();
		var errorStrArr = errors.map(function(error){ return error.value; });
		if (errors.length > 0) {
			$('.error-msg').show().html(errorStrArr.join('
'));
			errors.forEach(function(error){
				if (error.line) {
					$('.CodeMirror-lines > div > div:last-child > pre:nth-child('+error.line+')').addClass('highlighted-code');
				}
			});
		} else {
			$('.error-msg').hide();
			$('.highlighted-code').removeClass('highlighted-code');
			console.log('%c No errors!', 'color: #393');
		}
	}

	// undo/redo history state UI
	function renderHistoryLinkState () {
		// console.debug(myCodeMirror.historySize());
		if (myCodeMirror.historySize().undo > 0) {
			$('.btn-undo').attr('disabled', false);
		} else {
			$('.btn-undo').attr('disabled', true);
		}
		if (myCodeMirror.historySize().redo > 0) {
			$('.btn-redo').attr('disabled', false);
		} else {
			$('.btn-redo').attr('disabled', true);
		}
	}

	// recalculate and resize the editor to the proper height
	function refreshEditorLayout () {
		var currentHeight = $('.CodeMirror').height();
		var containerHeight = $('.input-area-wrapper').outerHeight(true);
		var windowHeight = $(window).height();
		var wiggleRoom = 10;

		$('.CodeMirror-scroll').css('height', windowHeight - (containerHeight - currentHeight) - wiggleRoom);
		myCodeMirror.refresh();
	}

	$(window).bind('hashchange', function(e) {
		app.initPage();
	});

	// recalculate editor layout on resize
	$(window).resize(function(){
		refreshEditorLayout();
	});

	// auto-run on code mutation
	$('.code-input-area').on('input', function(){
	  app.run({ autorun: true });
	}, false);

	// manually run on Cmd-Enter / Ctrl-Enter
	$(document).on('keydown', '.code-input-area', function(e) {
	  if (e.keyCode === 13 && (e.metaKey || e.ctrlKey)) {
	    app.run();
	  }
	});

	// manually run when run btn is clicked
	$('.btn-run').on('click', function(){
	  app.run();
	}, false);

	// toggle checkbox states
	$('#toggle-element-outline').change(function(e){
		app.elementOutlinesEnabled = e.target.checked;
		app.run();
	});

	// reset code button
	$('.btn-reset-code').click(function(e) {
		if (!confirm('Press OK to reset your code to the default for this example.\n\nNote: This will overwrite your current code, but pressing Cmd/Ctrl Z will undo this change.')) {
			return false;
		}
		app.resetCodeToHashDefault();
	});

	// undo/redo
	$('.btn-undo').click(function(e) {
		myCodeMirror.undo();
		renderHistoryLinkState();
	});

	$('.btn-redo').click(function(e) {
		myCodeMirror.redo();
		renderHistoryLinkState();
	});

	// hooks for debugging
	if (localStorage.debug) {
		window.myCodeMirror = myCodeMirror;
	}

	// hooks for tablet mode
	if (sessionStorage.tabletMode === 'true') {
		$('#input-topbar').hide().parent().css('padding-top', '12px');
		$('.input-area').css('font-size', '120%');
		$('html').addClass('tablet-mode');
	}

	$('.input-area').mousemove(function(e){ updateMousePosition(e) });

	// report-an-issue modal event listener
	$('#issue-dialog').on('shown.bs.modal', function(e){
		// grab the code from our codeMirror instance
		$('#entry_440939498').val( myCodeMirror.getValue() );

		// grab the user's uid and path
		$('#entry_1934743275').val( JSON.parse(localStorage.uid) + '/' + app.hash + '/' + pageInstanceUID );
	});

  // report-an-issue submittal iframe
	$('#hidden_iframe').on('load', function(e){
		if (submitted) {
			$('#issue-dialog').modal('hide');
			$('#issue-submitted-dialog').modal('show');

			// clear everything
			$('#issue-dialog textarea').val('');
			$('#entry_1934743275').val('');
			$('#issue-dialog [type=radio]').prop('checked', false);

			// grab the user's uid and path
			$('#entry_1934743275').val( JSON.parse(localStorage.uid) + '/' + app.hash + '/' + pageInstanceUID );
			submitted = false;
		}
	});

	var timeOfLastUpdate;
	var updateDebounceThreshold = 200;
	var lastDebouncedState = null;
	var finalStateUpdateTimeout;

	var updateMousePosition = function(e) {
		var mouse = [e.offsetX, e.offsetY];
		var state = lastDebouncedState || {};

		// I'm setting a floor of threshold/4 to give the actual state update
		// a chance to happen. Otherwise, it'd updateDebouncedState exactly on
		// time, not giving normal state updates a chance to happen (and therefore
		// resulting in stale data).
		var timeToUpdateWithFinalState = Math.max(updateDebounceThreshold / 4, updateDebounceThreshold - (Date.now() - timeOfLastUpdate));

		state.mouse = mouse;

		clearTimeout(finalStateUpdateTimeout);

		if (timeOfLastUpdate && (Date.now() - timeOfLastUpdate < updateDebounceThreshold)) {
			lastDebouncedState = state;
			finalStateUpdateTimeout = setTimeout(updateDebouncedState, timeToUpdateWithFinalState);
			return false;
		}

		timeOfLastUpdate = Date.now();
		lastDebouncedState = null;
		updateState(state);
	};

	function updateDebouncedState () {
		timeOfLastUpdate = Date.now();
		updateState(lastDebouncedState);
	}

	app.androidInit();

	app.initPage();

})();

<commit_msg>disable line wrapping<commit_after>var app = app || {};

(function() {

	if (location.hash === '#tabletmode') {
		sessionStorage.tabletMode = 'true';
		location.hash = '/';
	}

	// this is the place the user codes
	var myCodeMirror;

	// this is a unique id assigned to the current page
	var pageInstanceUID;

	app.readyToRun = false;

	if (localStorage.uid) {
		app.uid = JSON.parse(localStorage.uid);
	} else {
		app.uid = Date.now().toString(36);
		localStorage.uid = JSON.stringify(app.uid);
	}

	app.initPage = function() {
		// get the hash key
		app.hash = app.getHashKey();

		// create code input area
		app.initCodeMirror();

		// calculate editor layout
		refreshEditorLayout();

		app.diffEngine = window.diffEngine();
		app.diffEncoder = app.diffEngine.getEncoder();
		app.diffDecoder = app.diffEngine.getDecoder();

		// run the code
		app.run();

		// ensure CodeMirror code gets properly rendered
		requestAnimationFrame(function(){
			myCodeMirror.refresh();
		});

		// we're assuming they won't visit the same page twice within one second
		pageInstanceUID = Math.floor(Date.now()/1000);
		app.fb = new Firebase('https://udacity.firebaseio.com/android-layout/users/' + app.uid + '/' + app.hash + '/' + pageInstanceUID);

	};

	app.getHashKey = function() {
		var hash = location.hash;
		if (hash.length > 2 && hash.substr(0,2) === '#/') {
			return hash.slice(2);
		} else {
			return '';
		}
	};

	app.initCodeMirror = function(){
		// clear pre-existing code areas
		$('.input-area').html('');

		myCodeMirror = CodeMirror(document.querySelector('.input-area'), {
			value: app.getCodeForHash(),
			mode: "android-xml",
			lineNumbers: true,
			indentUnit: 4,
			fixedGutter: true,
			viewportMargin: Infinity,
			onChange: function() {
				app.run({ autorun: true });
			}
		});
	};

	app.getCodeForHash = function() {
		// this is for testing code (#/test/...)
		if (app.hash.slice(0,4) === 'test') {
			$.get('tests/android/' + app.hash.slice(12) + '.xml', function(data){
				myCodeMirror.setValue(data);
				myCodeMirror.refresh();
				app.run({
					code: data,
					force: true
				});
			}, 'text');
			$('.test-reference-image').attr('src', 'tests/android/' + app.hash.slice(12) + '.png');
			return '';
		}

		// we have a previously-saved version
		if (localStorage['code-' + app.hash]) {
			return JSON.parse( localStorage['code-' + app.hash] );
		}

		// return the default (if there is one)
		else {
			return app.getCodeForHashDefault();
		}

		return '';
	};

	app.getCodeForHashDefault = function() {
		if (app.androidCodeDefaults) {
			if (app.androidCodeDefaults[ app.hash ]) {
				return app.androidCodeDefaults[ app.hash ];
			} else {
				return app.androidCodeDefaults[ 'default' ];
			}
		}

		return '';
	};

	app.resetCodeToHashDefault = function() {
		myCodeMirror.setValue(app.getCodeForHashDefault());
		myCodeMirror.refresh();
	};

	// this runs after code is successfully evaluated
	function runSuccess(code) {
		if (!localStorage.debug) {
			clearTimeout(app.codeEvaluationTimeout);
		}

		// save current student code
		if (app.hash.slice(0,4) !== 'test') {
			localStorage['code-' + app.hash] = JSON.stringify(code);
		}

		$('html').removeClass('invalid-code evaluating-invalid-code');
		requestAnimationFrame(function(){
			$('html').addClass('valid-code');
		});

		$('.code-saved-msg').removeClass('code-not-saved');

	}

	// this runs if the code is considered invalid or unevaluatable
	function runFail (opt) {
		var code = opt.code;
		clearTimeout(app.codeEvaluationTimeout);
		$('html').removeClass('invalid-code').addClass('evaluating-invalid-code');

		app.codeEvaluationTimeout = setTimeout(function(){
			console.log('TIMEOUT');
	 		$('html').removeClass('evaluating-invalid-code').addClass('invalid-code');
		},2000);

		if (opt.errors) {
			opt.errors.forEach(function(errorID){
				// add any errors to the error stack
				app.errors.push({
					id: errorID
				});
			});
		}

		if (!localStorage.debug) {
			$('.code-saved-msg').addClass('code-not-saved');
		} else {
			console.log('failed, but saving anyway since we\'re in debug mode');
			runSuccess(code);
		}
	}

	function updateState (newState) {
		var state = app.state || {};

		// copy over any new parameters from the previous state
		for(key in newState) {
			state[key] = newState[key];
		}

		var diff = app.diffEncoder.push(state);
		app.state = state;
		// console.log(app.diffDecoder.getState().state);
		// console.log('pushing', diff);
		app.fb.child('diffs').push(diff);
	}

	// this function evaluates code based on the mode the app is in
	app.run = function (opt) {
		opt = opt || {};

		if (!app.readyToRun && !opt.force) return false;

		var codeRaw = opt.code || myCodeMirror.getValue();
		var code;
		var elemToRender;

		updateState({
			code: codeRaw
		});

		// run the code
		var mode = 'android-layout';
		if (mode === 'android-layout') {

			if (app.hash.slice(0,4) === 'test') {
				$('html').addClass('testing-mode');
				if (app.hash === 'test/android' || app.hash === 'test/android/') {
					forwardFillTestingHistory('#/test/android/', app.tests);
				}
			} else {
				$('html').removeClass('testing-mode');
			}

			// pre-processing hook
			code = app.androidLayout.prepareCodeForParsing( codeRaw );

			// catch easy-to-detect errors (like misaligned <>'s, quotes)
			app.androidLayout.xmlSanityCheck( codeRaw );

			// if we don't have code to render, exit early rather than throwing an error
			if (codeRaw === '') {
				return false;
			}

			// parse the XML
			try {
				app.parsedXML = jQuery.parseXML( code );
			} catch (e) {
				app.parsedXML = null;
			}

			if (app.parsedXML !== null) {
				// basic parsing and styling
				elemToRender = app.androidLayout.evaluateXML(app.parsedXML);

				// calculate all the layouts
				console.log('%c-------- layout pass at ' + Math.round(Date.now()/1000) + ' --------', 'color: #666');
				app.androidLayout.evaluateXMLPass2( app.parsedXML );
				if (app.errors().length > 0) {
					runFail({
						code: codeRaw
					});
				} else {
					runSuccess(codeRaw);
				}
			} else {

				runFail({
					code: codeRaw,
					errors: ['parseError']
				});

				$('html').removeClass('valid-code invalid-code')

			}
		}

		if (elemToRender) {
			$('.screen').html('').append(elemToRender);
		}

		renderErrors();

		renderHistoryLinkState();
		refreshEditorLayout();
		console.log('%c-------- end --------', 'color: #666');
	};

	function forwardFillTestingHistory (prefix, urls, startAtBeginning) {

		// add each test to the history
		urls.forEach(function(url){
			history.pushState({}, '', prefix + url);
		});

		// go to the first one
		if (startAtBeginning) {
			history.go((app.tests.length-1) * -1);
		}
	}

	// show the error list in the document
	function renderErrors () {
		var errors = app.errors();
		var errorStrArr = errors.map(function(error){ return error.value; });
		if (errors.length > 0) {
			$('.error-msg').show().html(errorStrArr.join('
'));
			errors.forEach(function(error){
				if (error.line) {
					$('.CodeMirror-lines > div > div:last-child > pre:nth-child('+error.line+')').addClass('highlighted-code');
				}
			});
		} else {
			$('.error-msg').hide();
			$('.highlighted-code').removeClass('highlighted-code');
			console.log('%c No errors!', 'color: #393');
		}
	}

	// undo/redo history state UI
	function renderHistoryLinkState () {
		// console.debug(myCodeMirror.historySize());
		if (myCodeMirror.historySize().undo > 0) {
			$('.btn-undo').attr('disabled', false);
		} else {
			$('.btn-undo').attr('disabled', true);
		}
		if (myCodeMirror.historySize().redo > 0) {
			$('.btn-redo').attr('disabled', false);
		} else {
			$('.btn-redo').attr('disabled', true);
		}
	}

	// recalculate and resize the editor to the proper height
	function refreshEditorLayout () {
		var currentHeight = $('.CodeMirror').height();
		var containerHeight = $('.input-area-wrapper').outerHeight(true);
		var windowHeight = $(window).height();
		var wiggleRoom = 10;

		$('.CodeMirror-scroll').css('height', windowHeight - (containerHeight - currentHeight) - wiggleRoom);
		myCodeMirror.refresh();
	}

	$(window).bind('hashchange', function(e) {
		app.initPage();
	});

	// recalculate editor layout on resize
	$(window).resize(function(){
		refreshEditorLayout();
	});

	// auto-run on code mutation
	$('.code-input-area').on('input', function(){
	  app.run({ autorun: true });
	}, false);

	// manually run on Cmd-Enter / Ctrl-Enter
	$(document).on('keydown', '.code-input-area', function(e) {
	  if (e.keyCode === 13 && (e.metaKey || e.ctrlKey)) {
	    app.run();
	  }
	});

	// manually run when run btn is clicked
	$('.btn-run').on('click', function(){
	  app.run();
	}, false);

	// toggle checkbox states
	$('#toggle-element-outline').change(function(e){
		app.elementOutlinesEnabled = e.target.checked;
		app.run();
	});

	// reset code button
	$('.btn-reset-code').click(function(e) {
		if (!confirm('Press OK to reset your code to the default for this example.\n\nNote: This will overwrite your current code, but pressing Cmd/Ctrl Z will undo this change.')) {
			return false;
		}
		app.resetCodeToHashDefault();
	});

	// undo/redo
	$('.btn-undo').click(function(e) {
		myCodeMirror.undo();
		renderHistoryLinkState();
	});

	$('.btn-redo').click(function(e) {
		myCodeMirror.redo();
		renderHistoryLinkState();
	});

	// hooks for debugging
	if (localStorage.debug) {
		window.myCodeMirror = myCodeMirror;
	}

	// hooks for tablet mode
	if (sessionStorage.tabletMode === 'true') {
		$('#input-topbar').hide().parent().css('padding-top', '12px');
		$('.input-area').css('font-size', '120%');
		$('html').addClass('tablet-mode');
	}

	$('.input-area').mousemove(function(e){ updateMousePosition(e) });

	// report-an-issue modal event listener
	$('#issue-dialog').on('shown.bs.modal', function(e){
		// grab the code from our codeMirror instance
		$('#entry_440939498').val( myCodeMirror.getValue() );

		// grab the user's uid and path
		$('#entry_1934743275').val( JSON.parse(localStorage.uid) + '/' + app.hash + '/' + pageInstanceUID );
	});

  // report-an-issue submittal iframe
	$('#hidden_iframe').on('load', function(e){
		if (submitted) {
			$('#issue-dialog').modal('hide');
			$('#issue-submitted-dialog').modal('show');

			// clear everything
			$('#issue-dialog textarea').val('');
			$('#entry_1934743275').val('');
			$('#issue-dialog [type=radio]').prop('checked', false);

			// grab the user's uid and path
			$('#entry_1934743275').val( JSON.parse(localStorage.uid) + '/' + app.hash + '/' + pageInstanceUID );
			submitted = false;
		}
	});

	var timeOfLastUpdate;
	var updateDebounceThreshold = 200;
	var lastDebouncedState = null;
	var finalStateUpdateTimeout;

	var updateMousePosition = function(e) {
		var mouse = [e.offsetX, e.offsetY];
		var state = lastDebouncedState || {};

		// I'm setting a floor of threshold/4 to give the actual state update
		// a chance to happen. Otherwise, it'd updateDebouncedState exactly on
		// time, not giving normal state updates a chance to happen (and therefore
		// resulting in stale data).
		var timeToUpdateWithFinalState = Math.max(updateDebounceThreshold / 4, updateDebounceThreshold - (Date.now() - timeOfLastUpdate));

		state.mouse = mouse;

		clearTimeout(finalStateUpdateTimeout);

		if (timeOfLastUpdate && (Date.now() - timeOfLastUpdate < updateDebounceThreshold)) {
			lastDebouncedState = state;
			finalStateUpdateTimeout = setTimeout(updateDebouncedState, timeToUpdateWithFinalState);
			return false;
		}

		timeOfLastUpdate = Date.now();
		lastDebouncedState = null;
		updateState(state);
	};

	function updateDebouncedState () {
		timeOfLastUpdate = Date.now();
		updateState(lastDebouncedState);
	}

	app.androidInit();

	app.initPage();

})();

<|endoftext|>


<commit_before>var app = angular.module('plotText', ['ngAnimate', 'ui.bootstrap']);

app.controller('plotTextController', ['$scope', '$timeout', '$http', function($scope, $timeout, $http){

	//Hide and Display section when JS libs are available or not.
    jQuery("#hideIfNoJS").removeClass("hidden");
    jQuery("#hideIfJS").addClass("hidden");

    //Styling File Input button
    $(":file").filestyle({buttonName: "btn-info"});

    //Alerts
	$scope.alerts = [];

    $scope.dataSet = [{size : 160, text : "Java"},{size : 80, text : "HTML"},{size : 50, text : "CSS"},{size : 90, text : "JavaScript"},{size : 100, text : "C++"},{size : 80, text : ".Net"},{size : 70, text : "C#"},{size : 20, text : "Scala"},{size : 180, text : "Spring"},{size : 50, text : "Clojure"},{size : 160, text : "Python"},{size : 30, text : "Ruby"},{size : 50, text : "Rails"},{size : 160, text : "AngularJs"},{size : 80, text : "EmberJs"},{size : 160, text : "D3.js"},{size : 140, text : "Hibernate"},{size : 120, text : "MongoDb"},{size : 100, text : "MySql"},{size : 170, text : "Node.Js"},{size : 110, text : "Polymer"},{size : 10,text : "AppleScript"},{size : 20,text : "Bash"},{size : 80,text : "CoffeeScript"},{size : 70,text : "Cobra"},{size : 120,text : "Erlang"},{size : 140,text : "ECMAScript"},{size : 100,text : "Fortran"},{size : 120,text : "GoLang"},{size : 160,text : "Groovy"},{size : 60,text : "Haskell"},{size : 30,text : "Jython"},{size : 10,text : "KRYPTON"},{size : 10,text : "LotusScript"},{size : 90,text : "MATLAB"},{size : 100,text : "NoSql"},{size : 110,text : "Pearl"},{size : 20,text : "PowerShell"},{size : 30,text : "SciLab"},{size : 70,text : "VBScript"},{size : 160,text : "Php"},{size : 120,text : "Sql"}, {size : 40, text : "ASP.NET"},{size : 60, text : "ASP.NET MVC"},{size : 20, text : "ASP.NET Razor"},{size : 20, text : "ASP.NET vNext"},{size : 70, text : "COBOL on Wheelchair"},{size : 50, text : "Apache Cocoon"},{size : 20, text : "ColdFusion on Wheels"},{size : 20, text : "ColdSpring Framework"},{size : 20, text : "Cotonti"},{size : 20, text : "Dancer (software)"},{size : 80, text : "Django (web framework)"},{size : 20, text : "Fluid UI"},{size : 20, text : "FuelPHP"},{size : 80, text : "Google Apps Script"},{size : 90, text : "Grails (framework)"},{size : 20, text : "Jamroom"},{size : 100, text : "Java Platform"},{size : 80, text : "JavaServer Faces"},{size : 50, text : "Javeline platform"},{size : 20, text : "JBND"},{size : 70, text : "JBoss Seam"},{size : 20, text : "JHipster"},{size : 90, text : "Joomla"},{size : 70, text : "JQuery Mobile"},{size : 20, text : "Jspx-bay"},{size : 20, text : "JVx (Framework)"},{size : 30, text : "JWt (Java web toolkit)"},{size : 50, text : "Laravel"},{size : 20, text : "Lift (web framework)"},{size : 70, text : "Lithium (PHP framework)"},{size : 100, text : "MEAN"},{size : 20, text : "Moobile.js"},{size : 20, text : "Mozilla Skywriter"},{size : 20, text : "SilverStripe"},{size : 30, text : "Sinatra (software)"},{size : 20, text : "SISCWeb"},{size : 40, text : "SiteMesh"},{size : 20, text : "Slimweb"},{size : 20, text : "Snap (web framework)"},{size : 20, text : "Solution stack"},{size : 60, text : "Spark (software)"},{size : 40, text : "Spring Framework"},{size : 70, text : "Spring Roo"},{size : 20, text : "Stripes (framework)"},{size : 90, text : "Apache Struts"},{size : 100, text : "Apache Struts 2"},{size : 70, text : "Sun Web Developer Pack"},{size : 60, text : "SymbolicWeb"},{size : 90, text : "Vaadin"},{size : 20, text : "Vibe.d"},{size : 70, text : "VRaptor"}];
	drawChart($scope.dataSet);
	function handleFileSelect(evt) {
	    var files = evt.target.files; // FileList object
	    var file = files[0];
		var textType = /text.*/;
		$scope.dataSet = [];

		if (file.type.match(textType)) {
			var reader = new FileReader();

			reader.onload = function(e) {
				var stringToReplace = reader.result;
				var desired = stringToReplace.replace(/[^\w\s]/gi, ' ');
				desired = desired.replace(/(?:\r\n|\r|\n|\t)/g, ' ');
				desired = desired.split(' ');
				desired = desired.filter(function(n){ return n != "" });
				$scope.rawdata = desired;
			}
			reader.readAsText(file);

		} else {
			//alert("file not supported!");
			$('#myModal2').modal('show');
		}
	  }

  	document.getElementById('textFiles').addEventListener('change', handleFileSelect, false);

  	$scope.triggerDrawChart = function () {
  		$('#myModal').modal('show');
  	}

	$scope.drawChart = function() {
		$('#myModal').modal('hide');
		$timeout(function() {
			$scope.dataSet = compressArray($scope.rawdata);
			drawChart($scope.dataSet);
		}, 400);
	};

 	function compressArray(original) {

		var compressed = [];
		// make a copy of the input array
		var copy = original.slice(0);

		// first loop goes over every element
		for (var i = 0; i < original.length; i++) {

			var myCount = 0;
			// loop over every element in the copy and see if it's the same
			for (var w = 0; w < copy.length; w++) {
				if (original[i] == copy[w]) {
					// increase amount of times duplicate is found
					myCount++;
					// sets item to undefined
					delete copy[w];
				}
			}

			if (myCount > 0) {
				var a = new Object();
				a.text= original[i];
				a.size= myCount;
				compressed.push(a);
			}
		}

		return compressed;
	};

  	function drawChart (data) {
  		//console.log(data);
  		jQuery("#chart svg").remove();
		var frequency_list = data;
  	 	var len = frequency_list.length;

  	 	// Define the div for the tooltip
		var div = d3.select("body").append("div")
		    .attr("class", "tooltip")
		    .style("opacity", 0);

		var maxSize = d3.max(data, function(d) { return d.size});

		//Define Size of Text
		var pixScale = d3.scale.linear()
	        .domain([0, maxSize])
	        .range([10, 180]);

	    //console.log(pixScale.domain());

	    var color = d3.scale.category20();
	    	color.domain([100,0]);

	    var width = 960, height = 500;

	    d3.layout.cloud().size([(width-100), (height-100)])
	            .words(frequency_list)
	            .rotate(0)
	            .fontSize(function(d) { return d.size; })
	            .on("end", draw)
	            .start();

	    function draw(words) {
	        var chart = d3.select("#chart").append("svg")
	                .attr("width", width)
	                .attr("height", height)
	                .attr("class", "wordcloud")
	        var g = chart.append("g")
	                // without the transform, words words would get cutoff to the left and top, they would
	                // appear outside of the SVG area
	             //   .call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
	                .attr("transform", "translate(380,250)")
	                .selectAll("text")
	                .data(words)
	                .enter().append("text")
	                .style("font-size", function(d) { return Math.floor(pixScale(d.size)) + "px"; })
	                .style("fill", function(d, i) { return color(i); })
	                .attr("transform", function(d) {
	                    return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
	                })
	                .text(function(d) { return d.text; })
	                .on("mouseover", function(d) {
			            div.transition()
			                .duration(400)
			                .style("opacity", .9);
			            div	.html("" + "Wors : '"+ d.text +"'
Count :  "  + d.size + "")
			                .style("left", (d3.event.pageX) + "px")
			                .style("top", (d3.event.pageY - 28) + "px");
			            })
			        .on("mouseout", function(d) {
			            div.transition()
			                .duration(500)
			                .style("opacity", 0);
			        });

			// function zoom() {
			// 	g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
			// }
	    };
	    $scope.alerts.push({ type: 'success', msg: 'Word Cloud created successfully!'});
	    $timeout(function() {
			$scope.alerts.pop();
		}, 1500);
	};

	//for any other error
	$(window).on("error", function(evt) {

	    console.log("jQuery error event:", evt);
	    var e = evt.originalEvent; // get the javascript event
	    console.log("original event:", e);
	    if (e.message) {
	        //alert("Error:\n\t" + e.message + "\nLine:\n\t" + e.lineno + "\nFile:\n\t" + e.filename);
	        $('#myModal2').modal('show');
	    } else {
	        //alert("Error:\n\t" + e.type + "\nElement:\n\t" + (e.srcElement || e.target));
	        $('#myModal2').modal('show');
	    }
	});

}]);
<commit_msg>Fixed Popup display on every script error<commit_after>var app = angular.module('plotText', ['ngAnimate', 'ui.bootstrap']);

app.controller('plotTextController', ['$scope', '$timeout', '$http', function($scope, $timeout, $http){

	//Hide and Display section when JS libs are available or not.
    jQuery("#hideIfNoJS").removeClass("hidden");
    jQuery("#hideIfJS").addClass("hidden");

    //Styling File Input button
    $(":file").filestyle({buttonName: "btn-info"});

    //Alerts
	$scope.alerts = [];

    $scope.dataSet = [{size : 160, text : "Java"},{size : 80, text : "HTML"},{size : 50, text : "CSS"},{size : 90, text : "JavaScript"},{size : 100, text : "C++"},{size : 80, text : ".Net"},{size : 70, text : "C#"},{size : 20, text : "Scala"},{size : 180, text : "Spring"},{size : 50, text : "Clojure"},{size : 160, text : "Python"},{size : 30, text : "Ruby"},{size : 50, text : "Rails"},{size : 160, text : "AngularJs"},{size : 80, text : "EmberJs"},{size : 160, text : "D3.js"},{size : 140, text : "Hibernate"},{size : 120, text : "MongoDb"},{size : 100, text : "MySql"},{size : 170, text : "Node.Js"},{size : 110, text : "Polymer"},{size : 10,text : "AppleScript"},{size : 20,text : "Bash"},{size : 80,text : "CoffeeScript"},{size : 70,text : "Cobra"},{size : 120,text : "Erlang"},{size : 140,text : "ECMAScript"},{size : 100,text : "Fortran"},{size : 120,text : "GoLang"},{size : 160,text : "Groovy"},{size : 60,text : "Haskell"},{size : 30,text : "Jython"},{size : 10,text : "KRYPTON"},{size : 10,text : "LotusScript"},{size : 90,text : "MATLAB"},{size : 100,text : "NoSql"},{size : 110,text : "Pearl"},{size : 20,text : "PowerShell"},{size : 30,text : "SciLab"},{size : 70,text : "VBScript"},{size : 160,text : "Php"},{size : 120,text : "Sql"}, {size : 40, text : "ASP.NET"},{size : 60, text : "ASP.NET MVC"},{size : 20, text : "ASP.NET Razor"},{size : 20, text : "ASP.NET vNext"},{size : 70, text : "COBOL on Wheelchair"},{size : 50, text : "Apache Cocoon"},{size : 20, text : "ColdFusion on Wheels"},{size : 20, text : "ColdSpring Framework"},{size : 20, text : "Cotonti"},{size : 20, text : "Dancer (software)"},{size : 80, text : "Django (web framework)"},{size : 20, text : "Fluid UI"},{size : 20, text : "FuelPHP"},{size : 80, text : "Google Apps Script"},{size : 90, text : "Grails (framework)"},{size : 20, text : "Jamroom"},{size : 100, text : "Java Platform"},{size : 80, text : "JavaServer Faces"},{size : 50, text : "Javeline platform"},{size : 20, text : "JBND"},{size : 70, text : "JBoss Seam"},{size : 20, text : "JHipster"},{size : 90, text : "Joomla"},{size : 70, text : "JQuery Mobile"},{size : 20, text : "Jspx-bay"},{size : 20, text : "JVx (Framework)"},{size : 30, text : "JWt (Java web toolkit)"},{size : 50, text : "Laravel"},{size : 20, text : "Lift (web framework)"},{size : 70, text : "Lithium (PHP framework)"},{size : 100, text : "MEAN"},{size : 20, text : "Moobile.js"},{size : 20, text : "Mozilla Skywriter"},{size : 20, text : "SilverStripe"},{size : 30, text : "Sinatra (software)"},{size : 20, text : "SISCWeb"},{size : 40, text : "SiteMesh"},{size : 20, text : "Slimweb"},{size : 20, text : "Snap (web framework)"},{size : 20, text : "Solution stack"},{size : 60, text : "Spark (software)"},{size : 40, text : "Spring Framework"},{size : 70, text : "Spring Roo"},{size : 20, text : "Stripes (framework)"},{size : 90, text : "Apache Struts"},{size : 100, text : "Apache Struts 2"},{size : 70, text : "Sun Web Developer Pack"},{size : 60, text : "SymbolicWeb"},{size : 90, text : "Vaadin"},{size : 20, text : "Vibe.d"},{size : 70, text : "VRaptor"}];
	drawChart($scope.dataSet);
	function handleFileSelect(evt) {
	    var files = evt.target.files; // FileList object
	    var file = files[0];
		var textType = /text.*/;
		$scope.dataSet = [];

		if (file.type.match(textType)) {
			var reader = new FileReader();

			reader.onload = function(e) {
				var stringToReplace = reader.result;
				var desired = stringToReplace.replace(/[^\w\s]/gi, ' ');
				desired = desired.replace(/(?:\r\n|\r|\n|\t)/g, ' ');
				desired = desired.split(' ');
				desired = desired.filter(function(n){ return n != "" });
				$scope.rawdata = desired;
			}
			reader.readAsText(file);

		} else {
			//alert("file not supported!");
			$('#myModal2').modal('show');
		}
	  }

  	document.getElementById('textFiles').addEventListener('change', handleFileSelect, false);

  	$scope.triggerDrawChart = function () {
  		$('#myModal').modal('show');
  	}

	$scope.drawChart = function() {
		$('#myModal').modal('hide');
		$timeout(function() {
			$scope.dataSet = compressArray($scope.rawdata);
			drawChart($scope.dataSet);
		}, 400);
	};

 	function compressArray(original) {

		var compressed = [];
		// make a copy of the input array
		var copy = original.slice(0);

		// first loop goes over every element
		for (var i = 0; i < original.length; i++) {

			var myCount = 0;
			// loop over every element in the copy and see if it's the same
			for (var w = 0; w < copy.length; w++) {
				if (original[i] == copy[w]) {
					// increase amount of times duplicate is found
					myCount++;
					// sets item to undefined
					delete copy[w];
				}
			}

			if (myCount > 0) {
				var a = new Object();
				a.text= original[i];
				a.size= myCount;
				compressed.push(a);
			}
		}

		return compressed;
	};

  	function drawChart (data) {
  		//console.log(data);
  		jQuery("#chart svg").remove();
		var frequency_list = data;
  	 	var len = frequency_list.length;

  	 	// Define the div for the tooltip
		var div = d3.select("body").append("div")
		    .attr("class", "tooltip")
		    .style("opacity", 0);

		var maxSize = d3.max(data, function(d) { return d.size});

		//Define Size of Text
		var pixScale = d3.scale.linear()
	        .domain([0, maxSize])
	        .range([10, 180]);

	    //console.log(pixScale.domain());

	    var color = d3.scale.category20();
	    	color.domain([100,0]);

	    var width = 960, height = 500;

	    d3.layout.cloud().size([(width-100), (height-100)])
	            .words(frequency_list)
	            .rotate(0)
	            .fontSize(function(d) { return d.size; })
	            .on("end", draw)
	            .start();

	    function draw(words) {
	        var chart = d3.select("#chart").append("svg")
	                .attr("width", width)
	                .attr("height", height)
	                .attr("class", "wordcloud")
	        var g = chart.append("g")
	                // without the transform, words words would get cutoff to the left and top, they would
	                // appear outside of the SVG area
	             //   .call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
	                .attr("transform", "translate(380,250)")
	                .selectAll("text")
	                .data(words)
	                .enter().append("text")
	                .style("font-size", function(d) { return Math.floor(pixScale(d.size)) + "px"; })
	                .style("fill", function(d, i) { return color(i); })
	                .attr("transform", function(d) {
	                    return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
	                })
	                .text(function(d) { return d.text; })
	                .on("mouseover", function(d) {
			            div.transition()
			                .duration(400)
			                .style("opacity", .9);
			            div	.html("" + "Wors : '"+ d.text +"'
Count :  "  + d.size + "")
			                .style("left", (d3.event.pageX) + "px")
			                .style("top", (d3.event.pageY - 28) + "px");
			            })
			        .on("mouseout", function(d) {
			            div.transition()
			                .duration(500)
			                .style("opacity", 0);
			        });

			// function zoom() {
			// 	g.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
			// }
	    };
	    $scope.alerts.push({ type: 'success', msg: 'Word Cloud created successfully!'});
	    $timeout(function() {
			$scope.alerts.pop();
		}, 1500);
	};

	//for any other error
	$(window).on("error", function(evt) {

	    console.log("jQuery error event:", evt);
	    var e = evt.originalEvent; // get the javascript event
	    console.log("original event:", e);
	    if (e.message) {
	        console.log("Error:\n\t" + e.message + "\nLine:\n\t" + e.lineno + "\nFile:\n\t" + e.filename);
	        //$('#myModal2').modal('show');
	    } else {
	        console.log("Error:\n\t" + e.type + "\nElement:\n\t" + (e.srcElement || e.target));
	        //$('#myModal2').modal('show');
	    }
	});

}]);
<|endoftext|>


<commit_before>var helloWorld = function(name, greeting) {
  return name + ' ' + greeting;
}

console.log(helloWorld('Hello', 'World!'));

const newGreeting1 = (name, greeting) => {
  return name + ' ' + greeting;
}

console.log(newGreeting1('Sup', 'Planet'));

const newGreeting2 = (name, greeting) => name + ' ' + greeting;

console.log(newGreeting2('Yo', 'Earth'));
<commit_msg>Now switching to different part of lesson<commit_after>var helloWorld = function(name, greeting) {
  return name + ' ' + greeting;
}

console.log(helloWorld('Hello', 'World!'));

const newGreeting1 = (name, greeting) => {
  return name + ' ' + greeting;
}

console.log(newGreeting1('Sup', 'Planet'));

const newGreeting2 = (name, greeting) => name + ' ' + greeting;

console.log(newGreeting2('Yo', 'Earth'));

const newGreetingOneParam = greeting => greeting;

console.log(newGreetingOneParam('yello'));

const newGreetingNoParam = () => "This is how I always say Hi";

console.log(newGreetingNoParam());
<|endoftext|>


<commit_before>var enemyDX = 0.3;
var Start = 0;
var Enemy_Pop = 40;

/**
 * Represents an enemy.
 * @constructor
 * @param {int} posX - the X position of the enemy.
 * @param {int} posY - the Y position of the enemy.
 */
var Enemy = function(posX, posY, num) {
    this.x = posX;
    this.y = posY;
    this.dy = 20;
    this.dx = 1;
    this.num = num;
    this.population = 56;
    this.width = 65;
    this.height = 70;
    this.display = true;
    this.sprite = 'images/enemy1.png';
};

/**
 * Update the enemy's position.
 * @param {int} dt - a time delta between ticks.
 */
Enemy.prototype.update = function(dt) {
    this.x += this.dx * dt;

    /**
     * Keep the enemy from going off the edge of the screen.
     * If it does go reach the the edge, reverse direction.
     */
    if ((this.x >= 1200 - 91 || this.x <= 0) && this.display === true) {
        enemyDX = -enemyDX;

        /**
         * We move everyone vertically all at once for
         * simplicity.
         */
        allEnemies.forEach(function(enemy) {
            enemy.y += enemy.dy;
        });
    }

    /**
     * Enemies will come out of alignment due to position
     * not updating at exacty the same time. This will keep
     * them aligned.
     */
    if (this.num > 7) {
        this.x = allEnemies[this.num - 8].x;
    }

    if (this.num % 8 > 0) {
        this.x = allEnemies[this.num - 1].x + 135
    }
};

/** Draw the enemy on the screen */
Enemy.prototype.render = function() {
    if (this.display === true) {
        ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
    }
};

/** Calculates the enemy's movement */
Enemy.prototype.move = function() {
    this.dx = (enemyDX * this.population);

};

/** Add a bullet to the game when an enemy shoots */
Enemy.prototype.shoot = function() {

    /**
     * Balance enemy shooting by having each enemy only have a small
     * chance of firing.
     */
    var rand = Math.floor(Math.random() * 2500 + 1);

    if (rand === this.num && this.display === true) {
        bullets.push(new Bullet(this.x, this.y, "enemy", bullets.length));
    }
};

/** Removes an enemy from the game */
Enemy.prototype.destroy = function() {
    this.display = false;
    hud.score += 100;

    /** Slowly speed up as enemies are defeated */
    enemyDX = enemyDX * 1.07;

    Enemy_Pop -= 1;
}

/**
 * Test to see if the enemy is in contact with any other
 * entity
 *
 * @param {Enemy} enemy - the Enemy object being tested
 * @returns {[int,int]} An array with the first index being the index of
 * the bullet the enemy has collided with and the second index being the
 * current state of the game.
 */
Enemy.prototype.testCollision = function(enemy) {

    var collisionNum = -1
    var state = 0;

    bullets.forEach(function(bullet) {

        if (bullet.type === "player" && enemy.display === true) {

            if (collisionTest(enemy, bullet)) {
                enemy.destroy();
                player.shot = false;
                collisionNum = bullet.num;

            }
        }

        if (enemy.y > (725 - enemy.height) && enemy.display === true) {
            barriers.forEach(function(barrier) {

                if (collisionTest(enemy, barrier) && barrier.display === true) {
                    enemy.destroy();
                    barrier.health -= 1;

                }
            });
        }

    });

    if (collisionTest(enemy, player) && enemy.display === true) {
        enemy.destroy();
        player.lives -= 1;
        hud.lives -= 1;

        if (player.lives > 0) {
            state = 2;
        } else {
            state = 1;
        }
    }

    if ((enemy.y + 70) > 900 && enemy.display === true) {
        player.lives -= 1;
        hud.lives -= 1;
        if (player.lives > 0) {
            state = 2;
        } else {
            state = 1;
        }
    }

    if (Enemy_Pop === 0) {
        state = 3;
    }

    return [collisionNum, state];
}

/**
 * Helper function for finding the vertical placing
 * for enemies.
 */
var calcHeight = function(count) {
    if (count <= 8) {
        return 50;
    } else if (count <= 16) {
        return 70 + 81;
    } else if (count <= 24) {
        return 90 + (2 * 81);
    } else if (count <= 32) {
        return 110 + (3 * 81);
    } else if (count <= 40) {
        return 130 + (4 * 81);
    } else if (count <= 48) {
        return 150 + (5 * 81);
    }
}

/**
 * Represents the player
 * @constructor
 */
var Player = function() {
    this.sprite = 'images/player.png';
    this.x = (500) + (77 / 2);
    this.y = 820;
    this.dx = 0;
    this.dy = 0;
    this.width = 77;
    this.height = 52;
    this.lives = 3;
    this.score = 0;
    this.shot = false;
};

/**
 * Update the player's position.
 * @param {int} dt - a time delta between ticks.
 */
Player.prototype.update = function(dt) {
    this.x += this.dx * dt;
    if (this.x < 20) {
        this.x = 20;
    } else if (this.x > 1060) {
        this.x = 1060;
    }
};

Player.prototype.move = function() {

}

/** Draw the player to the screen. */
Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/**
 * See what button is being pressed and take
 * the appropriate action.
 * @param {[str]} input - array of keys being pressed.
 */
Player.prototype.handleInput = function(input) {

    if (keyboard['\%']) {
        this.dx = -100;
        Start = 1;
    } else if (keyboard["'"]) {
        this.dx = 100;
        Start = 1;
    } else {
        this.dx = 0;
    }

    if (input === 'ctrl') {
        this.shoot();
        Start = 1;
    }

};

/**
 * Add a bullet if the player shoots and stop
 * it from shooting until the bullet is gone.
 */
Player.prototype.shoot = function() {
    if (this.shot === false) {
        bullets.push(new Bullet(this.x + this.width / 2, this.y - this.height + 30, "player", bullets.length));
        this.shot = true;
    }
};

/**
 * Represents a bullet.
 * @constructor
 *
 * @param {int} posX - The X position of the bullet.
 * @param {int} posY - The Y position of the bullet.
 * @param {str} type - Shows whether the bullet is from
 * the player or an enemy.
 * @param {int} num - The index where the bullet is located.
 * Makes it easy to delete it when necessary.
 */
var Bullet = function(posX, posY, type, num) {
    this.x = posX;
    this.y = posY;
    this.dx = 0;
    this.dy = 0;
    this.width = 5;
    this.height = 25;
    this.type = type;
    this.num = num;
    this.sprite = 'images/bullet.png';
};

/**
 * Updates the bullet's position
 *
 * @param {int} dt - a time delta between ticks.
 */
Bullet.prototype.update = function(dt) {
    this.y += this.dy * dt;
};

/** Draws the player to the screen. */
Bullet.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/**
 * Sets the bullets movement rate based on
 * type.
 */
Bullet.prototype.move = function() {
    if (this.type === "player") {
        this.dy = -200;
    } else if (this.type === "enemy") {
        this.dy = 200;
    }
}

/**
 * Tests whether the bullet is in contact with any
 * other entities.
 *
 * @param {[bullet]} bullet - The array of bullets
 * @returns {[int,int]} An array with the first index being the index of
 * the bullet the enemy has collided with and the second index being the
 * current state of the game.
 */
Bullet.prototype.testCollision = function(bullet) {

    var collisionNum = -1;
    var state = 0;

    if (bullet.y > 900 || bullet.y < 0) {
        collisionNum = bullet.num;

        if (bullet.type === "player") {
            player.shot = false;
        }
    }

    if (bullet.type === 'enemy' && bullet.y > 700) {

        if (collisionTest(player, bullet)) {
            player.lives -= 1;
            hud.lives -= 1;
            collisionNum = bullet.num;

            if (player.lives > 0) {
                state = 2;
            } else {
                state = 1;
            }
        }
    }

    if (bullet.y > 650) {

        barriers.forEach(function(barrier) {

            if (collisionTest(bullet, barrier) && barrier.display === true) {
                barrier.health -= 1;
                collisionNum = bullet.num;

                if (bullet.type === "player") {
                    player.shot = false;
                }
            }
        });
    }

    return [collisionNum, state];
}

/**
 * Represents a barrier.
 * @constructor
 *
 * @param {int} posX - The barrier's position on the X axis.
 * @param {int} posY - The barrier's position on the Y axis.
 */
var Barrier = function(posX, posY) {
    this.x = posX
    this.y = posY;
    this.width = 92;
    this.height = 69;
    this.health = 10;
    this.display = true;
    this.sprite = 'images/barrier_full.png';

};

/** Update the barrier's sprite. */
Barrier.prototype.update = function() {
    if (this.health === 0) {
        this.display = false;
    } else if (this.health <= 2) {
        this.sprite = 'images/barrier_most.png';
        this.width = 90;
        this.height = 52;
    } else if (this.health <= 4) {
        this.sprite = 'images/barrier_serious.png';
        this.width = 90;
        this.height = 57;
    } else if (this.health <= 6) {
        this.sprite = 'images/barrier_more.png';
    } else if (this.health <= 8) {
        this.sprite = 'images/barrier_slight.png';
    }
};

/** Draw the barrier to the screen. */
Barrier.prototype.render = function() {
    if (this.display === true) {
        // we take the difference between the current and original dimensions in order
        // to stop them from shifting around
        ctx.drawImage(Resources.get(this.sprite), this.x + (92 - this.width), this.y + (69 - this.height));
    }
};

/**
 * Represents the HUD.
 * @constructor
 *
 * @param {int} score - the score of the player to display.
 * @param {int} lives - the amount of lives the player has
 * to display.
 */
var HUD = function(score, lives) {
    this.score = score;
    this.lives = lives;
};

/** Draw the HUD to the screen */
HUD.prototype.render = function(ctx) {
    ctx.font = "20px Arial";
    ctx.fillStyle = "white";

    var scoreText = "SCORE: " + this.score;
    var livesText = "LIVES: " + this.lives;

    ctx.fillText(scoreText, 10, 30);
    ctx.fillText(livesText, 1100, 30);
};

var allEnemies = [];
var barriers = [];
var bullets = []

var player = new Player();
var hud = new HUD(0, player.lives);

for (var x = 0; x < 41; x++) {
    allEnemies[x] = new Enemy(91 + 135 * (allEnemies.length % 8), calcHeight(x), x);
}
for (var x = 0; x < 3; x++) {
    barriers[x] = new Barrier(230 + (x * 300), 725)
}

// This listens for key presses and sends the keys to your
// Player.handleInput() method. You don't need to modify this.
document.addEventListener('keydown', function(e) {
    var allowedKeys = {
        17: 'ctrl',
        37: 'left',
        39: 'right'

    };

    player.handleInput(allowedKeys[e.keyCode]);
});

/**
 * Properly handles when a key is held down and then released.
 * Credit to: RobKohr
 *
 * @param {Function} onUpdate - An optional parameter. A function
 * that executes when a key is pressed or released.
 * @returns {Object} They keys currently pressed down.
 */
function keyboard_module(onUpdate) {
    var kb = {};
    var unicode_mapping = {};
    document.onkeydown = function(e) {
        var unicode = e.charCode ? e.charCode : e.keyCode
        var key = getKey(unicode);
        kb[key] = true;
        if (onUpdate) {
            onUpdate(kb);
        }
    }

    document.onkeyup = function(e) {
        var unicode = e.charCode ? e.charCode : e.keyCode
        var key = getKey(unicode);
        delete kb[key];
        if (onUpdate) {
            onUpdate(kb);
        }
    }

    function getKey(unicode) {
        if (unicode_mapping[unicode]) {
            var key = unicode_mapping[unicode];
        } else {
            var key = unicode_mapping[unicode] = String.fromCharCode(unicode);
        }
        return key;
    }
    return kb;
}

/**
 * Test if the boundboxes of two entities are intersecting
 *
 * @param {Enemy|Player|Bullet|Barrier} obj1 - The first
 * object being tested.
 * @param {Enemy|Player|Bullet|Barrier} obj2 - The second
 * object being tested.
 * @returns {boolean} Returns whether the two objects are
 * intersecting or not.
 */
function collisionTest(obj1, obj2) {
    if (obj1.x < obj2.x + obj2.width &&
        obj1.x + obj1.width > obj2.x &&
        obj1.y < obj2.y + obj2.height &&
        obj1.height + obj1.y > obj2.y) {

        return true;
    }
}

/**
 * Removes bullets from the bullet array when
 * an in-game event destroys them.
 *
 * @param {[int]} nums - array of indexes of the bullets
 * to delete.
 */
function deleteBullets(nums) {
    nums.forEach(function(num) {
        bullets.splice(num, 1);
    });

    for (var i = 0; i < bullets.length; i++) {
        bullets[i].num = i;
    }
}

var keyboard = keyboard_module();<commit_msg>refactor: create player destroy method<commit_after>var enemyDX = 0.3;
var Start = 0;
var Enemy_Pop = 40;

/**
 * Represents an enemy.
 * @constructor
 * @param {int} posX - the X position of the enemy.
 * @param {int} posY - the Y position of the enemy.
 */
var Enemy = function(posX, posY, num) {
    this.x = posX;
    this.y = posY;
    this.dy = 20;
    this.dx = 1;
    this.num = num;
    this.population = 56;
    this.width = 65;
    this.height = 70;
    this.display = true;
    this.sprite = 'images/enemy1.png';
};

/**
 * Update the enemy's position.
 * @param {int} dt - a time delta between ticks.
 */
Enemy.prototype.update = function(dt) {
    this.x += this.dx * dt;

    /**
     * Keep the enemy from going off the edge of the screen.
     * If it does go reach the the edge, reverse direction.
     */
    if ((this.x >= 1200 - 91 || this.x <= 0) && this.display === true) {
        enemyDX = -enemyDX;

        /**
         * We move everyone vertically all at once for
         * simplicity.
         */
        allEnemies.forEach(function(enemy) {
            enemy.y += enemy.dy;
        });
    }

    /**
     * Enemies will come out of alignment due to position
     * not updating at exacty the same time. This will keep
     * them aligned.
     */
    if (this.num > 7) {
        this.x = allEnemies[this.num - 8].x;
    }

    if (this.num % 8 > 0) {
        this.x = allEnemies[this.num - 1].x + 135
    }
};

/** Draw the enemy on the screen */
Enemy.prototype.render = function() {
    if (this.display === true) {
        ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
    }
};

/** Calculates the enemy's movement */
Enemy.prototype.move = function() {
    this.dx = (enemyDX * this.population);

};

/** Add a bullet to the game when an enemy shoots */
Enemy.prototype.shoot = function() {

    /**
     * Balance enemy shooting by having each enemy only have a small
     * chance of firing.
     */
    var rand = Math.floor(Math.random() * 2500 + 1);

    if (rand === this.num && this.display === true) {
        bullets.push(new Bullet(this.x, this.y, "enemy", bullets.length));
    }
};

/** Removes an enemy from the game */
Enemy.prototype.destroy = function() {
    this.display = false;
    hud.score += 100;

    /** Slowly speed up as enemies are defeated */
    enemyDX = enemyDX * 1.07;

    Enemy_Pop -= 1;
};

/**
 * Test to see if the enemy is in contact with any other
 * entity
 *
 * @param {Enemy} enemy - the Enemy object being tested
 * @returns {[int,int]} An array with the first index being the index of
 * the bullet the enemy has collided with and the second index being the
 * current state of the game.
 */
Enemy.prototype.testCollision = function(enemy) {

    var collisionNum = -1
    var state = 0;

    bullets.forEach(function(bullet) {

        if (bullet.type === "player" && enemy.display === true) {

            if (collisionTest(enemy, bullet)) {
                enemy.destroy();
                player.shot = false;
                collisionNum = bullet.num;

            }
        }

        if (enemy.y > (725 - enemy.height) && enemy.display === true) {
            barriers.forEach(function(barrier) {

                if (collisionTest(enemy, barrier) && barrier.display === true) {
                    enemy.destroy();
                    barrier.damage();
                }
            });
        }

    });

    if (collisionTest(enemy, player) && enemy.display === true) {
        enemy.destroy();
        state = player.destroy();
    }

    if ((enemy.y + 70) > 900 && enemy.display === true) {
        state = player.destroy();
    }

    if (Enemy_Pop === 0) {
        state = 3;
    }

    return [collisionNum, state];
};

/**
 * Helper function for finding the vertical placing
 * for enemies.
 */
var calcHeight = function(count) {
    if (count <= 8) {
        return 50;
    } else if (count <= 16) {
        return 70 + 81;
    } else if (count <= 24) {
        return 90 + (2 * 81);
    } else if (count <= 32) {
        return 110 + (3 * 81);
    } else if (count <= 40) {
        return 130 + (4 * 81);
    } else if (count <= 48) {
        return 150 + (5 * 81);
    }
}

/**
 * Represents the player
 * @constructor
 */
var Player = function() {
    this.sprite = 'images/player.png';
    this.x = (500) + (77 / 2);
    this.y = 820;
    this.dx = 0;
    this.dy = 0;
    this.width = 77;
    this.height = 52;
    this.lives = 3;
    this.score = 0;
    this.shot = false;
};

/**
 * Update the player's position.
 * @param {int} dt - a time delta between ticks.
 */
Player.prototype.update = function(dt) {
    this.x += this.dx * dt;
    if (this.x < 20) {
        this.x = 20;
    } else if (this.x > 1060) {
        this.x = 1060;
    }
};

Player.prototype.move = function() {

};

/** Draw the player to the screen. */
Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/**
 * See what button is being pressed and take
 * the appropriate action.
 * @param {[str]} input - array of keys being pressed.
 */
Player.prototype.handleInput = function(input) {

    if (keyboard['\%']) {
        this.dx = -100;
        Start = 1;
    } else if (keyboard["'"]) {
        this.dx = 100;
        Start = 1;
    } else {
        this.dx = 0;
    }

    if (input === 'ctrl') {
        this.shoot();
        Start = 1;
    }

};

/**
 * Add a bullet if the player shoots and stop
 * it from shooting until the bullet is gone.
 */
Player.prototype.shoot = function() {
    if (this.shot === false) {
        bullets.push(new Bullet(this.x + this.width / 2, this.y - this.height + 30, "player", bullets.length));
        this.shot = true;
    }
};

/* Destroys the player */
Player.prototype.destroy = function() {
    player.lives -= 1;
    hud.lives -= 1;

    /** determine if game over or just normal reset */
    if (player.lives > 0) {
        return 2;
    } else {
        return 1;
    }
};

/**
 * Represents a bullet.
 * @constructor
 *
 * @param {int} posX - The X position of the bullet.
 * @param {int} posY - The Y position of the bullet.
 * @param {str} type - Shows whether the bullet is from
 * the player or an enemy.
 * @param {int} num - The index where the bullet is located.
 * Makes it easy to delete it when necessary.
 */
var Bullet = function(posX, posY, type, num) {
    this.x = posX;
    this.y = posY;
    this.dx = 0;
    this.dy = 0;
    this.width = 5;
    this.height = 25;
    this.type = type;
    this.num = num;
    this.sprite = 'images/bullet.png';
};

/**
 * Updates the bullet's position
 *
 * @param {int} dt - a time delta between ticks.
 */
Bullet.prototype.update = function(dt) {
    this.y += this.dy * dt;
};

/** Draws the player to the screen. */
Bullet.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
};

/**
 * Sets the bullets movement rate based on
 * type.
 */
Bullet.prototype.move = function() {
    if (this.type === "player") {
        this.dy = -200;
    } else if (this.type === "enemy") {
        this.dy = 200;
    }
};

/**
 * Tests whether the bullet is in contact with any
 * other entities.
 *
 * @param {[bullet]} bullet - The array of bullets
 * @returns {[int,int]} An array with the first index being the index of
 * the bullet the enemy has collided with and the second index being the
 * current state of the game.
 */
Bullet.prototype.testCollision = function(bullet) {

    var collisionNum = -1;
    var state = 0;

    if (bullet.y > 900 || bullet.y < 0) {
        collisionNum = bullet.num;

        if (bullet.type === "player") {
            player.shot = false;
        }
    }

    if (bullet.type === 'enemy' && bullet.y > 700) {

        if (collisionTest(player, bullet)) {
            state = player.destroy();
            collisionNum = bullet.num;
        }
    }

    if (bullet.y > 650) {

        barriers.forEach(function(barrier) {

            if (collisionTest(bullet, barrier) && barrier.display === true) {
                barrier.damage();
                collisionNum = bullet.num;

                if (bullet.type === "player") {
                    player.shot = false;
                }
            }
        });
    }

    return [collisionNum, state];
};

/**
 * Represents a barrier.
 * @constructor
 *
 * @param {int} posX - The barrier's position on the X axis.
 * @param {int} posY - The barrier's position on the Y axis.
 */
var Barrier = function(posX, posY) {
    this.x = posX
    this.y = posY;
    this.width = 92;
    this.height = 69;
    this.health = 10;
    this.display = true;
    this.sprite = 'images/barrier_full.png';

};

/** Update the barrier's sprite. */
Barrier.prototype.update = function() {
    if (this.health === 0) {
        this.display = false;
    } else if (this.health <= 2) {
        this.sprite = 'images/barrier_most.png';
        this.width = 90;
        this.height = 52;
    } else if (this.health <= 4) {
        this.sprite = 'images/barrier_serious.png';
        this.width = 90;
        this.height = 57;
    } else if (this.health <= 6) {
        this.sprite = 'images/barrier_more.png';
    } else if (this.health <= 8) {
        this.sprite = 'images/barrier_slight.png';
    }
};

/** Draw the barrier to the screen. */
Barrier.prototype.render = function() {
    if (this.display === true) {
        // we take the difference between the current and original dimensions in order
        // to stop them from shifting around
        ctx.drawImage(Resources.get(this.sprite), this.x + (92 - this.width), this.y + (69 - this.height));
    }
};

/** Damages a barrier */
Barrier.prototype.damage = function() {
    this.health -= 1;
}

/**
 * Represents the HUD.
 * @constructor
 *
 * @param {int} score - the score of the player to display.
 * @param {int} lives - the amount of lives the player has
 * to display.
 */
var HUD = function(score, lives) {
    this.score = score;
    this.lives = lives;
};

/** Draw the HUD to the screen */
HUD.prototype.render = function(ctx) {
    ctx.font = "20px Arial";
    ctx.fillStyle = "white";

    var scoreText = "SCORE: " + this.score;
    var livesText = "LIVES: " + this.lives;

    ctx.fillText(scoreText, 10, 30);
    ctx.fillText(livesText, 1100, 30);
};

var allEnemies = [];
var barriers = [];
var bullets = []

var player = new Player();
var hud = new HUD(0, player.lives);

for (var x = 0; x < 41; x++) {
    allEnemies[x] = new Enemy(91 + 135 * (allEnemies.length % 8), calcHeight(x), x);
}
for (var x = 0; x < 3; x++) {
    barriers[x] = new Barrier(230 + (x * 300), 725)
}

// This listens for key presses and sends the keys to your
// Player.handleInput() method. You don't need to modify this.
document.addEventListener('keydown', function(e) {
    var allowedKeys = {
        17: 'ctrl',
        37: 'left',
        39: 'right'

    };

    player.handleInput(allowedKeys[e.keyCode]);
});

/**
 * Properly handles when a key is held down and then released.
 * Credit to: RobKohr
 *
 * @param {Function} onUpdate - An optional parameter. A function
 * that executes when a key is pressed or released.
 * @returns {Object} They keys currently pressed down.
 */
function keyboard_module(onUpdate) {
    var kb = {};
    var unicode_mapping = {};
    document.onkeydown = function(e) {
        var unicode = e.charCode ? e.charCode : e.keyCode
        var key = getKey(unicode);
        kb[key] = true;
        if (onUpdate) {
            onUpdate(kb);
        }
    }

    document.onkeyup = function(e) {
        var unicode = e.charCode ? e.charCode : e.keyCode
        var key = getKey(unicode);
        delete kb[key];
        if (onUpdate) {
            onUpdate(kb);
        }
    }

    function getKey(unicode) {
        if (unicode_mapping[unicode]) {
            var key = unicode_mapping[unicode];
        } else {
            var key = unicode_mapping[unicode] = String.fromCharCode(unicode);
        }
        return key;
    }
    return kb;
}

/**
 * Test if the boundboxes of two entities are intersecting
 *
 * @param {Enemy|Player|Bullet|Barrier} obj1 - The first
 * object being tested.
 * @param {Enemy|Player|Bullet|Barrier} obj2 - The second
 * object being tested.
 * @returns {boolean} Returns whether the two objects are
 * intersecting or not.
 */
function collisionTest(obj1, obj2) {
    if (obj1.x < obj2.x + obj2.width &&
        obj1.x + obj1.width > obj2.x &&
        obj1.y < obj2.y + obj2.height &&
        obj1.height + obj1.y > obj2.y) {

        return true;
    }
}

/**
 * Removes bullets from the bullet array when
 * an in-game event destroys them.
 *
 * @param {[int]} nums - array of indexes of the bullets
 * to delete.
 */
function deleteBullets(nums) {
    nums.forEach(function(num) {
        bullets.splice(num, 1);
    });

    for (var i = 0; i < bullets.length; i++) {
        bullets[i].num = i;
    }
}

var keyboard = keyboard_module();<|endoftext|>