<commit_before>'use strict';
(function(module){
  function Project(project){
    for(var key in project){
      this[key] = project[key];
    }
    this.projectTotal = Project.projectLines(this.code);
  }

  Project.all = [];
  Project.reposArray = [];

  //Method that compiles the project template and returns it.
  Project.prototype.toHtml = function(){
    var $source = $('#project-template').html();
    var template = Handlebars.compile($source);
    return template(this);
  };

  //Method that populates the Project.all property
  Project.loadAll = function(data){
    data.map(function(ele) {
      Project.all.push(new Project(ele));
    });
  };

  //Method that is used to populate the projectTotal property
  Project.projectLines = function(code){
    return code.reduce(function(a, b){
      return a + b;
    });
  };

  //Method that is used to calculate the total lines of code across projects, it is called by the stats template.
  Project.totalLines = function(){
    return Project.all.map(function(project){
      return project.projectTotal;
    }).reduce(function(a, b){
      return a + b;
    }, 0);
  };

  //Method to grab each project's total lines into a format that is usable for a handlebars template
  Project.collateTotals = function(){
    return Project.all.map(function(project){
      return ('<li>' + project.projectName + ': '+ project.projectTotal + ' lines</li>');
    }).reduce(function(a, b){
      return a + b;
    });
  };

  //Method that pulls in the data from the json file in our Project object
  Project.getAll = function(next){
    $.getJSON('/data/projectData.json', function(responseData) {
      Project.loadAll(responseData);
      Project.requestRepos(Project.repoDataMerge);
      // localStorage.projectData = JSON.stringify(responseData);
      localStorage.projectData = JSON.stringify(Project.all);
      next();
    });
  };

  //Method that checks local storage for the data and determines if we use it or parse it from the json file.
  Project.fetchAll = function(next){
    if(localStorage.projectData){
      $.ajax({
        type: 'HEAD',
        url: '/data/projectData.json',
        success: function(data, textStatus, xhr){
          var eTag = xhr.getResponseHeader('ETag');
          if(!localStorage.eTag || eTag !== localStorage.eTag){
            localStorage.etTag = eTag;
            Project.getAll(next);
          }else{
            Project.loadAll(JSON.parse(localStorage.projectData));
            if (next) next();
          }
        }
      });
    }else{
      Project.getAll(next);
    }
  };

  //Method that call upon the github /repos endpoint to get all the repositories sorted by last updated from my github account filtered by non fork repos.
  Project.requestRepos = function(callback){
    $.ajax({
      url: 'https://api.github.com/users/' + gitRepo.gitUser + '/repos' + '?sort=updated',
      type: 'GET',
      headers: {'Authorization': 'token ' + gitRepo.gitToken},
      success: function(data, message, xhr){
        console.log(data);
        Project.reposArray = data.filter(function(repo){
          return repo.fork === false;
        });
        callback();
      }
    });
  };

  //Method to mutate the data in the Project.all property with updated information from the github /repos api
  Project.repoDataMerge = function(){
    Project.reposArray.forEach(function(repo){
      Project.all.forEach(function(project){
        if(repo.name === project.repoName){
          project.lastUpdated = repo.updated_at;
          project.repoUrl = repo.html_url;
        }
      });
    });
  };

  module.Project = Project;
})(window);<commit_msg>Fixing async issue when merging in github data.<commit_after>'use strict';
(function(module){
  function Project(project){
    for(var key in project){
      this[key] = project[key];
    }
    this.projectTotal = Project.projectLines(this.code);
  }

  Project.all = [];
  Project.reposArray = [];

  //Method that compiles the project template and returns it.
  Project.prototype.toHtml = function(){
    var $source = $('#project-template').html();
    var template = Handlebars.compile($source);
    return template(this);
  };

  //Method that populates the Project.all property
  Project.loadAll = function(data){
    Project.all = data.map(function(ele) {
      return new Project(ele);
    });
  };

  //Method that is used to populate the projectTotal property
  Project.projectLines = function(code){
    return code.reduce(function(a, b){
      return a + b;
    });
  };

  //Method that is used to calculate the total lines of code across projects, it is called by the stats template.
  Project.totalLines = function(){
    return Project.all.map(function(project){
      return project.projectTotal;
    }).reduce(function(a, b){
      return a + b;
    }, 0);
  };

  //Method to grab each project's total lines into a format that is usable for a handlebars template
  Project.collateTotals = function(){
    return Project.all.map(function(project){
      return ('<li>' + project.projectName + ': '+ project.projectTotal + ' lines</li>');
    }).reduce(function(a, b){
      return a + b;
    });
  };

  //Method that pulls in the data from the json file in our Project object
  Project.getAll = function(next){
    $.getJSON('/data/projectData.json', function(responseData) {
      Project.loadAll(responseData);
      Project.requestRepos(Project.updateData(next));
    });
  };

  Project.updateData = function(next){
    return function(){
      Project.repoDataMerge();
      localStorage.projectData = JSON.stringify(Project.all);
      next();
    };
  };
  //Method that checks local storage for the data and determines if we use it or parse it from the json file.
  Project.fetchAll = function(next){
    if(localStorage.projectData){
      $.ajax({
        type: 'HEAD',
        url: '/data/projectData.json',
        success: function(data, textStatus, xhr){
          var eTag = xhr.getResponseHeader('ETag');
          if(!localStorage.eTag || eTag !== localStorage.eTag){
            localStorage.etTag = eTag;
            Project.getAll(next);
          }else{
            Project.loadAll(JSON.parse(localStorage.projectData));
            if (next) next();
          }
        }
      });
    }else{
      Project.getAll(next);
    }
  };

  //Method that call upon the github /repos endpoint to get all the repositories sorted by last updated from my github account filtered by non fork repos.
  Project.requestRepos = function(callback){
    $.ajax({
      url: 'https://api.github.com/users/' + gitRepo.gitUser + '/repos' + '?sort=updated',
      type: 'GET',
      headers: {'Authorization': 'token ' + gitRepo.gitToken},
      success: function(data, message, xhr){
        console.log(data);
        Project.reposArray = data.filter(function(repo){
          return repo.fork === false;
        });
        callback();
      }
    });
  };

  //Method to mutate the data in the Project.all property with updated information from the github /repos api
  Project.repoDataMerge = function(){
    Project.reposArray.forEach(function(repo){
      Project.all.forEach(function(project){
        if(repo.name === project.repoName){
          project.lastUpdated = new Date(repo.updated_at);
          project.repoUrl = repo.html_url;
        }
      });
    });
  };

  module.Project = Project;
})(window);
{'fraction_non_alphanumeric': 0.13083479907996212, 'fraction_numerical': 0.00027059937762143147, 'mean_word_length': 2.7714285714285714, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1315820', 'n_tokens_mistral': 2130, 'n_tokens_neox': 2069, 'n_words': 572}