<commit_before>var moment = require('moment');
var dom = require('./dom');

module.exports = render;
module.exports.section = 1;

function splice(str, start, end, replacement) {
  return [str.slice(0, start), replacement, str.slice(end)].join('');
}

function adjustText(tweet) {
  tweet.textAdjustment
  .sort(function(a, b) {
    // sort in reversed order
    return b.indices[0] - a.indices[0];
  })
  .forEach(function(adj) {
    tweet.text = splice(tweet.text, adj.indices[0], adj.indices[1], adj.text);
  });
  delete tweet.textAdjustment;
}

function createTextAdjustment(opt) {
    return {
      indices: opt.indices,
      text: '<a href="' + opt.href + '" target="_blank">' + opt.text + '</a>'
    };
}

function parseHashtags(entities, parsed) {
  if(!entities.hashtags) {
    return;
  }
  entities.hashtags.forEach(function(tag) {
    var ta = createTextAdjustment({
      href: 'https://twitter.com/search/%23' + tag.text,
      text: '#' + tag.text,
      indices: tag.indices
    });
    parsed.textAdjustment.push(ta);
  });
}

function parseUserMentions(entities, parsed) {
  if(!entities.user_mentions) {
    return;
  }
  entities.user_mentions.forEach(function(mention) {
    var ta = createTextAdjustment({
      href: 'https://twitter.com/intent/user?user_id=' + mention.id_str,
      text: '@' + mention.name,
      indices: mention.indices
    });
    parsed.textAdjustment.push(ta);
  });
}

function parseMedia(entities, parsed) {
  if(!entities.media) {
    return;
  }
  entities.media.forEach(function(media) {
    if(!parsed.photo && media.type !== 'photo') {
      return;
    }
    parsed.photo = {
      url: media.expanded_url,
      src: media.media_url_https
    };
    parsed.textAdjustment.push({
      indices: media.indices,
      text: ''
    });
  });
}

function parseUrls(entities, parsed) {
  if(!entities.urls) {
    return;
  }
  entities.urls.forEach(function(url) {
    var ta = createTextAdjustment({
      href: url.expanded_url,
      text: url.display_url,
      indices: url.indices
    });
    parsed.textAdjustment.push(ta);
  });
}

// interesting things about the tweet
// item.created_at
// item.text - tweet text
// item.entities - hashtags, urls, user_mentions, media (type: photo)
function parseTweet(tweet, username) {
  var parsed = {
    href: 'https://twitter.com/' + username + '/status/' + tweet.id_str,
    text: tweet.text,
    date: moment(tweet.created_at).fromNow(),
    textAdjustment: []
  };
  [parseMedia, parseHashtags, parseUserMentions, parseUrls].forEach(function(fn) {
    fn.call(null, tweet.entities, parsed);
  });
  adjustText(parsed);
  return parsed;
}

// .twitter-timeline
//   .follow
//   ul.timeline
//     for tweet in resort.twitter.tweets
//       li.tweet
//         a.date(href="https://twitter.com/#{resort.twitter.user}/status/#{tweet.id_str}")= tweet.created_at
//         .text= tweet.text

function tweet2dom(tweet) {
  var img, content = [
    dom.el('a', tweet.date, { href: tweet.href, class: 'date' }),
    dom.el('div', tweet.text, { class: 'text' })
  ];
  if (tweet.photo) {
    img = dom.el('img', '', { src: tweet.photo.src });
    content.push(dom.el('a', img, { class: 'photo', href: tweet.photo.url,  target: '_blank' }));
  }

  content = content.join('');
  return dom.el('li', content, { class: 'tweet' });
}

function renderTweets(timeline, twitter) {
  timeline.innerHTML = twitter.tweets.map(function(tweet) {
    return parseTweet(tweet, twitter.user);
  })
  .map(tweet2dom)
  .join('');
}
<commit_msg>Open Twitter in a separate tab<commit_after>var moment = require('moment');
var dom = require('./dom');

module.exports = render;
module.exports.section = 1;

function splice(str, start, end, replacement) {
  return [str.slice(0, start), replacement, str.slice(end)].join('');
}

function adjustText(tweet) {
  tweet.textAdjustment
  .sort(function(a, b) {
    // sort in reversed order
    return b.indices[0] - a.indices[0];
  })
  .forEach(function(adj) {
    tweet.text = splice(tweet.text, adj.indices[0], adj.indices[1], adj.text);
  });
  delete tweet.textAdjustment;
}

function createTextAdjustment(opt) {
    return {
      indices: opt.indices,
      text: '<a href="' + opt.href + '" target="_blank">' + opt.text + '</a>'
    };
}

function parseHashtags(entities, parsed) {
  if(!entities.hashtags) {
    return;
  }
  entities.hashtags.forEach(function(tag) {
    var ta = createTextAdjustment({
      href: 'https://twitter.com/search/%23' + tag.text,
      text: '#' + tag.text,
      indices: tag.indices
    });
    parsed.textAdjustment.push(ta);
  });
}

function parseUserMentions(entities, parsed) {
  if(!entities.user_mentions) {
    return;
  }
  entities.user_mentions.forEach(function(mention) {
    var ta = createTextAdjustment({
      href: 'https://twitter.com/intent/user?user_id=' + mention.id_str,
      text: '@' + mention.name,
      indices: mention.indices
    });
    parsed.textAdjustment.push(ta);
  });
}

function parseMedia(entities, parsed) {
  if(!entities.media) {
    return;
  }
  entities.media.forEach(function(media) {
    if(!parsed.photo && media.type !== 'photo') {
      return;
    }
    parsed.photo = {
      url: media.expanded_url,
      src: media.media_url_https
    };
    parsed.textAdjustment.push({
      indices: media.indices,
      text: ''
    });
  });
}

function parseUrls(entities, parsed) {
  if(!entities.urls) {
    return;
  }
  entities.urls.forEach(function(url) {
    var ta = createTextAdjustment({
      href: url.expanded_url,
      text: url.display_url,
      indices: url.indices
    });
    parsed.textAdjustment.push(ta);
  });
}

// interesting things about the tweet
// item.created_at
// item.text - tweet text
// item.entities - hashtags, urls, user_mentions, media (type: photo)
function parseTweet(tweet, username) {
  var parsed = {
    href: 'https://twitter.com/' + username + '/status/' + tweet.id_str,
    text: tweet.text,
    date: moment(tweet.created_at).fromNow(),
    textAdjustment: []
  };
  [parseMedia, parseHashtags, parseUserMentions, parseUrls].forEach(function(fn) {
    fn.call(null, tweet.entities, parsed);
  });
  adjustText(parsed);
  return parsed;
}

// .twitter
//   .follow
//   ul.timeline
//     for tweet in resort.twitter.tweets
//       li.tweet
//         a.date(href="https://twitter.com/#{resort.twitter.user}/status/#{tweet.id_str}")= tweet.created_at
//         .text= tweet.text

function tweet2dom(tweet) {
  var img, content = [
    dom.el('a', tweet.date, { href: tweet.href, class: 'date', target: '_blank' }),
    dom.el('div', tweet.text, { class: 'text' })
  ];
  if (tweet.photo) {
    img = dom.el('img', '', { src: tweet.photo.src });
    content.push(dom.el('a', img, { class: 'photo', href: tweet.photo.url,  target: '_blank' }));
  }

  content = content.join('');
  return dom.el('li', content, { class: 'tweet' });
}

function renderTweets(timeline, twitter) {
  timeline.innerHTML = twitter.tweets.map(function(tweet) {
    return parseTweet(tweet, twitter.user);
  })
  .map(tweet2dom)
  .join('');
}

{'fraction_non_alphanumeric': 0.17076271186440678, 'fraction_numerical': 0.002824858757062147, 'mean_word_length': 3.1775811209439526, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 8, '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': '4910969', 'n_tokens_mistral': 2484, 'n_tokens_neox': 2481, 'n_words': 447}