<commit_before>/*!
 * GitHub Activity Stream - v0.1.0 - 7/28/2014
 * https://github.com/caseyscarborough/github-activity
 *
 * Copyright (c) 2014 <NAME>
 * MIT License
 * http://opensource.org/licenses/MIT
 */

var GitHubActivity = (function() {
  'use strict';

  var obj = {};

  var methods = {
    renderLink: function(url, title, cssClass) {
      if (!title) { title = url; }
      if (typeof(cssClass) === 'undefined') cssClass = "";
      return Mustache.render('<a class="' + cssClass + '" href="{{url}}" target="_blank">{{{title}}}</a>', { url: url, title: title });
    },
    renderGitHubLink: function(url, title, cssClass) {
      if (!title) { title = url; }
      if (typeof(cssClass) === 'undefined') cssClass = "";
      return methods.renderLink('https://github.com/' + url, title, cssClass);
    },
    getMessageFor: function(data) {
      var p = data.payload;
      data.repoLink = methods.renderGitHubLink(data.repo.name);
      data.userGravatar = Mustache.render('<div class="gha-gravatar-user"><img src="{{url}}" class="gha-gravatar-small"></div>', { url: data.actor.avatar_url });

      // Get the branch name if it exists.
      if (p.ref) {
        if (p.ref.substring(0, 11) === 'refs/heads/') {
          data.branch = p.ref.substring(11);
        } else {
          data.branch = p.ref;
        }
        data.branchLink = methods.renderGitHubLink(data.repo.name + '/tree/' + data.branch, data.branch) + ' at ';
      }

      // Only show the first 6 characters of the SHA of each commit if given.
      if (p.commits) {
        var shaDiff = p.before + '...' + p.head;
        var length = p.commits.length;
        if (length === 2) {
          // If there are 2 commits, show message 'View comparison for these 2 commits >>'
          data.commitsMessage = Mustache.render('<a href="https://github.com/{{repo}}/compare/{{shaDiff}}">View comparison for these 2 commits &raquo;</a>', { repo: data.repo.name, shaDiff: shaDiff });
        } else if (length > 2) {
          // If there are more than two, show message '(numberOfCommits - 2) more commits >>'
          data.commitsMessage = Mustache.render('<a href="https://github.com/{{repo}}/compare/{{shaDiff}}">{{length}} more ' + pluralize('commit', length - 2) + ' &raquo;</a>', { repo: data.repo.name, shaDiff: shaDiff, length: p.size - 2 });
        }

        p.commits.forEach(function(d, i) {
          if (d.message.length > 66) {
            d.message = d.message.substring(0, 66) + '...';
          }
          if (i < 2) {
            d.shaLink = methods.renderGitHubLink(data.repo.name + '/commit/' + d.sha, d.sha.substring(0, 6), 'gha-sha');
            d.committerGravatar = Mustache.render('<img class="gha-gravatar-commit" src="https://gravatar.com/avatar/{{hash}}?s=30&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png" width="16" />', { hash: md5(d.author.email) });
          } else {
            // Delete the rest of the commits after the first 2, and then break out of the each loop.
            p.commits.splice(2, p.size);
            return false;
          }
        });
      }

      // Get the link if this is an IssueEvent.
      if (p.issue) {
        var title = data.repo.name + "#" + p.issue.number;
        data.issueLink = methods.renderLink(p.issue.html_url, title);
        data.issueType = "issue";
        if (p.issue.pull_request) {
          data.issueType = "pull request";
        }
      }

      // Retrieve the pull request link if this is a PullRequestEvent.
      if (p.pull_request) {
        var pr = p.pull_request;
        data.pullRequestLink = methods.renderLink(p.html_url, data.repo.name + "#" + pr.number);
        data.mergeMessage = "";

        // If this was a merge, set the merge message.
        if (p.pull_request.merged) {
          p.action = "merged";
          var message = '{{c}} ' + pluralize('commit', pr.commits) + ' with {{a}} ' + pluralize('addition', pr.additions) + ' and {{d}} ' + pluralize('deletion', pr.deletions);
          data.mergeMessage = Mustache.render('<br><small class="gha-message-merge">' + message + '</small>', { c: pr.commits, a: pr.additions, d: pr.deletions });
        }
      }

      // Get the link if this is a PullRequestReviewCommentEvent
      if (p.comment && p.comment.pull_request_url) {
        var title = data.repo.name + "#" + p.comment.pull_request_url.split('/').pop();
        data.pullRequestLink = methods.renderGitHubLink(p.comment.pull_request_url, title);
      }

      // Get the comment if one exists, and trim it to 150 characters.
      if (p.comment && p.comment.body) {
        data.comment = p.comment.body;
        if (data.comment.length > 150) {
          data.comment = data.comment.substring(0, 150) + '...';
        }
        if (p.comment.html_url && p.comment.commit_id) {
          var title = data.repo.name + '@' + p.comment.commit_id.substring(0, 10);
          data.commentLink = methods.renderLink(p.comment.html_url, title);
        }
      }

      if (data.type === 'ReleaseEvent') {
        data.tagLink = methods.renderLink(p.release.html_url, p.release.tag_name);
        data.zipLink = methods.renderLink(p.release.zipball_url, 'Download Source Code (zip)');
      }

      // Wiki event
      if (data.type === 'GollumEvent') {
        var page = p.pages[0];
        data.actionType = page.action;
        data.message = data.actionType.charAt(0).toUpperCase() + data.actionType.slice(1) + ' ';
        data.message += methods.renderGitHubLink(page.html_url, page.title);
      }

      if (data.type === 'FollowEvent') data.targetLink = methods.renderGitHubLink(p.target.login);
      if (data.type === 'ForkEvent')   data.forkLink   = methods.renderGitHubLink(p.forkee.full_name);
      if (data.type === 'MemberEvent') data.memberLink = methods.renderGitHubLink(p.member.login);

      if (p.gist) {
        data.actionType = p.action === 'fork' ? p.action + 'ed' : p.action + 'd';
        data.gistLink = methods.renderLink(p.gist.html_url, 'gist: ' + p.gist.id);
      }

      var message = Mustache.render(templates[data.type], data);
      var timeString = millisecondsToStr(new Date() - new Date(data.created_at));
      var icon;

      if (data.type == 'CreateEvent' && (['repository', 'branch', 'tag'].indexOf(p.ref_type) >= 0)) {
        // Display separate icons depending on type of create event.
        icon = icons[data.type + '_' + p.ref_type];
      } else {
        icon = icons[data.type]
      }
      var activity = { message: message, icon: icon, timeString: timeString, userLink: methods.renderGitHubLink(data.actor.login) };

      if (singleLineActivities.indexOf(data.type) > -1) {
        return Mustache.render(templates.SingleLineActivity, activity);
      }
      return Mustache.render(templates.Activity, activity);
    },
    getHeaderHTML: function(data) {
      if (data.name) {
        data.userNameLink = methods.renderLink(data.html_url, data.name);
      } else {
        data.withoutName = ' without-name';
      }
      data.userLink = methods.renderLink(data.html_url, data.login);
      data.gravatarLink = methods.renderLink(data.html_url, '<img src="' + data.avatar_url + '">');

      return Mustache.render(templates.UserHeader, data);
    },
    getActivityHTML: function(data, limit) {
      var text = '';
      var dataLength = data.length;
      if (limit && limit > dataLength) {
          limit = dataLength;
      }
      limit = limit ? limit : dataLength;

      if (limit === 0) {
        return Mustache.render(templates.NoActivity, {});
      }
      for (var i = 0; i < limit; i++) {
        text += methods.getMessageFor(data[i]);
      }

      return text;
    },
    getOutputFromRequest: function(url, func) {
      var text, data, request = new XMLHttpRequest();
      request.open('GET', url, false);

      request.onload = function() {
        if (request.status >= 200 && request.status < 400){
          data = JSON.parse(request.responseText);
          text = func(data);
        } else {
          // An error occurred.
          return false;
        }
      };

      request.onerror = function() { console.log('An error occurred connecting to the url.'); };
      request.send();
      return text;
    },
    renderStream: function(output, div) {
      div.innerHTML = Mustache.render(templates.Stream, { text: output, footer: templates.Footer });
      div.style.position = 'relative';
    }
  };

  obj.feed = function(options) {
    if (!options.username || !options.selector) {
      throw "You must specify the username and selector options for the activity stream.";
      return false;
    }

    var selector = options.selector,
        userUrl   = 'https://api.github.com/users/' + options.username,
        eventsUrl = userUrl + '/events',
        output,
        div;

    if (!!options.repository){
      eventsUrl = 'https://api.github.com/repos/' + options.username + '/' + options.repository + '/events';
    }

    if (options.clientId && options.clientSecret) {
      var authString = '?client_id=' + options.clientId + '&client_secret=' + options.clientSecret;
      userUrl   += authString;
      eventsUrl += authString;
    }

    // Allow templates override
    if (typeof options.templates == 'object') {
      for (var template in templates) {
        if (typeof options.templates[template] == 'string') {
          templates[template] = options.templates[template];
        }
      }
    }

    output = methods.getOutputFromRequest(userUrl, methods.getHeaderHTML);<commit_msg>Allow making the events url configurable<commit_after>/*!
 * GitHub Activity Stream - v0.1.0 - 7/28/2014
 * https://github.com/caseyscarborough/github-activity
 *
 * Copyright (c) 2014 <NAME>
 * MIT License
 * http://opensource.org/licenses/MIT
 */

var GitHubActivity = (function() {
  'use strict';

  var obj = {};

  var methods = {
    renderLink: function(url, title, cssClass) {
      if (!title) { title = url; }
      if (typeof(cssClass) === 'undefined') cssClass = "";
      return Mustache.render('<a class="' + cssClass + '" href="{{url}}" target="_blank">{{{title}}}</a>', { url: url, title: title });
    },
    renderGitHubLink: function(url, title, cssClass) {
      if (!title) { title = url; }
      if (typeof(cssClass) === 'undefined') cssClass = "";
      return methods.renderLink('https://github.com/' + url, title, cssClass);
    },
    getMessageFor: function(data) {
      var p = data.payload;
      data.repoLink = methods.renderGitHubLink(data.repo.name);
      data.userGravatar = Mustache.render('<div class="gha-gravatar-user"><img src="{{url}}" class="gha-gravatar-small"></div>', { url: data.actor.avatar_url });

      // Get the branch name if it exists.
      if (p.ref) {
        if (p.ref.substring(0, 11) === 'refs/heads/') {
          data.branch = p.ref.substring(11);
        } else {
          data.branch = p.ref;
        }
        data.branchLink = methods.renderGitHubLink(data.repo.name + '/tree/' + data.branch, data.branch) + ' at ';
      }

      // Only show the first 6 characters of the SHA of each commit if given.
      if (p.commits) {
        var shaDiff = p.before + '...' + p.head;
        var length = p.commits.length;
        if (length === 2) {
          // If there are 2 commits, show message 'View comparison for these 2 commits >>'
          data.commitsMessage = Mustache.render('<a href="https://github.com/{{repo}}/compare/{{shaDiff}}">View comparison for these 2 commits &raquo;</a>', { repo: data.repo.name, shaDiff: shaDiff });
        } else if (length > 2) {
          // If there are more than two, show message '(numberOfCommits - 2) more commits >>'
          data.commitsMessage = Mustache.render('<a href="https://github.com/{{repo}}/compare/{{shaDiff}}">{{length}} more ' + pluralize('commit', length - 2) + ' &raquo;</a>', { repo: data.repo.name, shaDiff: shaDiff, length: p.size - 2 });
        }

        p.commits.forEach(function(d, i) {
          if (d.message.length > 66) {
            d.message = d.message.substring(0, 66) + '...';
          }
          if (i < 2) {
            d.shaLink = methods.renderGitHubLink(data.repo.name + '/commit/' + d.sha, d.sha.substring(0, 6), 'gha-sha');
            d.committerGravatar = Mustache.render('<img class="gha-gravatar-commit" src="https://gravatar.com/avatar/{{hash}}?s=30&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png" width="16" />', { hash: md5(d.author.email) });
          } else {
            // Delete the rest of the commits after the first 2, and then break out of the each loop.
            p.commits.splice(2, p.size);
            return false;
          }
        });
      }

      // Get the link if this is an IssueEvent.
      if (p.issue) {
        var title = data.repo.name + "#" + p.issue.number;
        data.issueLink = methods.renderLink(p.issue.html_url, title);
        data.issueType = "issue";
        if (p.issue.pull_request) {
          data.issueType = "pull request";
        }
      }

      // Retrieve the pull request link if this is a PullRequestEvent.
      if (p.pull_request) {
        var pr = p.pull_request;
        data.pullRequestLink = methods.renderLink(p.html_url, data.repo.name + "#" + pr.number);
        data.mergeMessage = "";

        // If this was a merge, set the merge message.
        if (p.pull_request.merged) {
          p.action = "merged";
          var message = '{{c}} ' + pluralize('commit', pr.commits) + ' with {{a}} ' + pluralize('addition', pr.additions) + ' and {{d}} ' + pluralize('deletion', pr.deletions);
          data.mergeMessage = Mustache.render('<br><small class="gha-message-merge">' + message + '</small>', { c: pr.commits, a: pr.additions, d: pr.deletions });
        }
      }

      // Get the link if this is a PullRequestReviewCommentEvent
      if (p.comment && p.comment.pull_request_url) {
        var title = data.repo.name + "#" + p.comment.pull_request_url.split('/').pop();
        data.pullRequestLink = methods.renderGitHubLink(p.comment.pull_request_url, title);
      }

      // Get the comment if one exists, and trim it to 150 characters.
      if (p.comment && p.comment.body) {
        data.comment = p.comment.body;
        if (data.comment.length > 150) {
          data.comment = data.comment.substring(0, 150) + '...';
        }
        if (p.comment.html_url && p.comment.commit_id) {
          var title = data.repo.name + '@' + p.comment.commit_id.substring(0, 10);
          data.commentLink = methods.renderLink(p.comment.html_url, title);
        }
      }

      if (data.type === 'ReleaseEvent') {
        data.tagLink = methods.renderLink(p.release.html_url, p.release.tag_name);
        data.zipLink = methods.renderLink(p.release.zipball_url, 'Download Source Code (zip)');
      }

      // Wiki event
      if (data.type === 'GollumEvent') {
        var page = p.pages[0];
        data.actionType = page.action;
        data.message = data.actionType.charAt(0).toUpperCase() + data.actionType.slice(1) + ' ';
        data.message += methods.renderGitHubLink(page.html_url, page.title);
      }

      if (data.type === 'FollowEvent') data.targetLink = methods.renderGitHubLink(p.target.login);
      if (data.type === 'ForkEvent')   data.forkLink   = methods.renderGitHubLink(p.forkee.full_name);
      if (data.type === 'MemberEvent') data.memberLink = methods.renderGitHubLink(p.member.login);

      if (p.gist) {
        data.actionType = p.action === 'fork' ? p.action + 'ed' : p.action + 'd';
        data.gistLink = methods.renderLink(p.gist.html_url, 'gist: ' + p.gist.id);
      }

      var message = Mustache.render(templates[data.type], data);
      var timeString = millisecondsToStr(new Date() - new Date(data.created_at));
      var icon;

      if (data.type == 'CreateEvent' && (['repository', 'branch', 'tag'].indexOf(p.ref_type) >= 0)) {
        // Display separate icons depending on type of create event.
        icon = icons[data.type + '_' + p.ref_type];
      } else {
        icon = icons[data.type]
      }
      var activity = { message: message, icon: icon, timeString: timeString, userLink: methods.renderGitHubLink(data.actor.login) };

      if (singleLineActivities.indexOf(data.type) > -1) {
        return Mustache.render(templates.SingleLineActivity, activity);
      }
      return Mustache.render(templates.Activity, activity);
    },
    getHeaderHTML: function(data) {
      if (data.name) {
        data.userNameLink = methods.renderLink(data.html_url, data.name);
      } else {
        data.withoutName = ' without-name';
      }
      data.userLink = methods.renderLink(data.html_url, data.login);
      data.gravatarLink = methods.renderLink(data.html_url, '<img src="' + data.avatar_url + '">');

      return Mustache.render(templates.UserHeader, data);
    },
    getActivityHTML: function(data, limit) {
      var text = '';
      var dataLength = data.length;
      if (limit && limit > dataLength) {
          limit = dataLength;
      }
      limit = limit ? limit : dataLength;

      if (limit === 0) {
        return Mustache.render(templates.NoActivity, {});
      }
      for (var i = 0; i < limit; i++) {
        text += methods.getMessageFor(data[i]);
      }

      return text;
    },
    getOutputFromRequest: function(url, func) {
      var text, data, request = new XMLHttpRequest();
      request.open('GET', url, false);

      request.onload = function() {
        if (request.status >= 200 && request.status < 400){
          data = JSON.parse(request.responseText);
          text = func(data);
        } else {
          // An error occurred.
          return false;
        }
      };

      request.onerror = function() { console.log('An error occurred connecting to the url.'); };
      request.send();
      return text;
    },
    renderStream: function(output, div) {
      div.innerHTML = Mustache.render(templates.Stream, { text: output, footer: templates.Footer });
      div.style.position = 'relative';
    }
  };

  obj.feed = function(options) {
    if (!options.username || !options.selector) {
      throw "You must specify the username and selector options for the activity stream.";
      return false;
    }

    var selector = options.selector,
        userUrl   = 'https://api.github.com/users/' + options.username,
        eventsUrl = userUrl + '/events',
        output,
        div;

    if (!!options.repository){
      eventsUrl = 'https://api.github.com/repos/' + options.username + '/' + options.repository + '/events';
    }

    if (options.clientId && options.clientSecret) {
      var authString = '?client_id=' + options.clientId + '&client_secret=' + options.clientSecret;
      userUrl   += authString;
      eventsUrl += authString;
    }

    if (!!options.eventsUrl){
      eventsUrl = options.eventsUrl;
    }

    // Allow templates override
    if (typeof options.templates == 'object') {
      for (var template in templates) {
        if (typeof options.templates[template] == 'string') {
          templates[template] = options.templates[template];
        }
      }
    }

    output = methods.getOutputFromRequest(userUrl, methods.getHeaderHTML);
{'fraction_non_alphanumeric': 0.15504601466229917, 'fraction_numerical': 0.00811105911714241, 'mean_word_length': 2.4687105500450857, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 55, 'https://': 16, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3357661', 'n_tokens_mistral': 6121, 'n_tokens_neox': 5891, 'n_words': 1312}