<commit_before>'use strict';

const groupBy = require('lodash.groupby');
const log = require('intel').getLogger('browsertime');

module.exports = {
  formatMetric(name, metric, multiple, inMs) {
    if (metric === undefined) return null;
    function fmt(value) {
      if (inMs) {
        if (value < 1000) {
          return value + 'ms';
        } else {
          return (value / 1000).toFixed(2).replace(/\.0+$/, '') + 's';
        }
      } else return value;
    }

    let formatted = `${name}: ${fmt(metric.mean)}`;
    if (multiple) {
      formatted += ` (±${fmt(metric.mdev.toFixed(2))})`;
    }
    return formatted;
  },
  logResultLogLine(results) {
    let index = 0;
    for (let result of results) {
      let totalSize = 0;
      let requests = '';
      let firstPaint = '',
        domContent = '',
        pageLoad = '',
        speedIndex = '',
        perceptualSpeedIndex = '',
        contentfulSpeedIndex = '',
        startRender = '',
        visualComplete85 = '',
        backEndTime = '',
        lastVisualChange = '',
        lcp = '',
        fcp = '',
        nRuns = result.browserScripts.length,
        m = nRuns > 1;
      if (results.har && results.har.log.pages[index]) {
        // get the id
        let pageId = results.har.log.pages[index].id;
        let entriesByPage = groupBy(results.har.log.entries, 'pageref');
        requests = entriesByPage[pageId]
          ? entriesByPage[pageId].length + ' requests'
          : '';
        if (entriesByPage[pageId]) {
          for (const request of entriesByPage[pageId]) {
            // transfer size
            totalSize += request.response.bodySize;
          }
        }
        if (totalSize > 1024) {
          totalSize = (totalSize / 1024).toFixed(2) + ' kb';
        } else {
          totalSize = totalSize + ' bytes';
        }
      }

      if (result.statistics.timings && result.statistics.timings.pageTimings) {
        let pt = result.statistics.timings.pageTimings,
          t = result.statistics.timings,
          vm = result.statistics.visualMetrics;

        firstPaint = this.formatMetric('firstPaint', t.firstPaint, m, true);
        if (t.largestContentfulPaint) {
          lcp = this.formatMetric(
            'LCP',
            t.largestContentfulPaint.renderTime,
            m,
            true
          );
        }

        if (
          result.statistics.timings.paintTiming &&
          result.statistics.timings.paintTiming['first-contentful-paint']
        ) {
          fcp = this.formatMetric(
            'FCP',
            result.statistics.timings.paintTiming['first-contentful-paint'],
            m,
            true
          );
        }

        domContent = this.formatMetric(
          'DOMContentLoaded',
          pt.domContentLoadedTime,
          m,
          true
        );
        speedIndex = this.formatMetric(
          'speedIndex',
          vm ? vm.SpeedIndex : vm,
          m
        );
        perceptualSpeedIndex = this.formatMetric(
          'perceptualSpeedIndex',
          vm ? vm.PerceptualSpeedIndex : vm,
          m
        );
        contentfulSpeedIndex = this.formatMetric(
          'contentfulSpeedIndex',
          vm ? vm.ContentfulSpeedIndex : vm,
          m
        );
        startRender = this.formatMetric(
          'firstVisualChange',
          vm ? vm.FirstVisualChange : vm,
          m,
          true
        );
        lastVisualChange = this.formatMetric(
          'lastVisualChange',
          vm ? vm.LastVisualChange : vm,
          m,
          true
        );
        visualComplete85 = this.formatMetric(
          'visualComplete85',
          vm ? vm.VisualComplete85 : vm,
          m,
          true
        );
        pageLoad = this.formatMetric('Load', pt.pageLoadTime, m, true);
        backEndTime = this.formatMetric('backEndTime', pt.backEndTime, m, true);
      }

      let lines = [
          `${requests}`,
          `${totalSize > 0 ? totalSize : ''}`,
          backEndTime,
          firstPaint,
          startRender,
          fcp,
          domContent,
          lcp,
          pageLoad,
          speedIndex,
          perceptualSpeedIndex,
          contentfulSpeedIndex,
          visualComplete85,
          lastVisualChange
        ],
        note = m ? ` (${nRuns} runs)` : '';<commit_msg>Output TBT, CLS and TTFB when availible (#1276)<commit_after>'use strict';

const groupBy = require('lodash.groupby');
const log = require('intel').getLogger('browsertime');

module.exports = {
  formatMetric(name, metric, multiple, inMs) {
    if (metric === undefined) return null;
    function fmt(value) {
      if (inMs) {
        if (value < 1000) {
          return value + 'ms';
        } else {
          return (value / 1000).toFixed(2).replace(/\.0+$/, '') + 's';
        }
      } else return value;
    }

    let formatted = `${name}: ${fmt(metric.mean)}`;
    if (multiple) {
      formatted += ` (±${fmt(metric.mdev.toFixed(2))})`;
    }
    return formatted;
  },
  logResultLogLine(results) {
    let index = 0;
    for (let result of results) {
      let totalSize = 0;
      let requests = '';
      let firstPaint = '',
        domContent = '',
        pageLoad = '',
        speedIndex = '',
        perceptualSpeedIndex = '',
        contentfulSpeedIndex = '',
        startRender = '',
        visualComplete85 = '',
        backEndTime = '',
        lastVisualChange = '',
        lcp = '',
        fcp = '',
        cls = '',
        tbt = '',
        nRuns = result.browserScripts.length,
        m = nRuns > 1;
      if (results.har && results.har.log.pages[index]) {
        // get the id
        let pageId = results.har.log.pages[index].id;
        let entriesByPage = groupBy(results.har.log.entries, 'pageref');
        requests = entriesByPage[pageId]
          ? entriesByPage[pageId].length + ' requests'
          : '';
        if (entriesByPage[pageId]) {
          for (const request of entriesByPage[pageId]) {
            // transfer size
            totalSize += request.response.bodySize;
          }
        }
        if (totalSize > 1024) {
          totalSize = (totalSize / 1024).toFixed(2) + ' kb';
        } else {
          totalSize = totalSize + ' bytes';
        }
      }

      if (result.statistics.timings && result.statistics.timings.pageTimings) {
        let pt = result.statistics.timings.pageTimings,
          t = result.statistics.timings,
          vm = result.statistics.visualMetrics,
          pi = result.statistics.pageinfo,
          cpu = result.statistics.cpu;

        firstPaint = this.formatMetric('firstPaint', t.firstPaint, m, true);
        if (t.largestContentfulPaint) {
          lcp = this.formatMetric(
            'LCP',
            t.largestContentfulPaint.renderTime,
            m,
            true
          );
        }

        if (pi.layoutShift) {
          cls = this.formatMetric('CLS', pi.layoutShift, m, false) + '%';
        }

        if (cpu && cpu.longTasks && cpu.longTasks.totalBlockingTime) {
          tbt = this.formatMetric(
            'TBT',
            cpu.longTasks.totalBlockingTime,
            m,
            true
          );
        }

        if (
          result.statistics.timings.paintTiming &&
          result.statistics.timings.paintTiming['first-contentful-paint']
        ) {
          fcp = this.formatMetric(
            'FCP',
            result.statistics.timings.paintTiming['first-contentful-paint'],
            m,
            true
          );
        }

        domContent = this.formatMetric(
          'DOMContentLoaded',
          pt.domContentLoadedTime,
          m,
          true
        );
        speedIndex = this.formatMetric(
          'speedIndex',
          vm ? vm.SpeedIndex : vm,
          m
        );
        perceptualSpeedIndex = this.formatMetric(
          'perceptualSpeedIndex',
          vm ? vm.PerceptualSpeedIndex : vm,
          m
        );
        contentfulSpeedIndex = this.formatMetric(
          'contentfulSpeedIndex',
          vm ? vm.ContentfulSpeedIndex : vm,
          m
        );
        startRender = this.formatMetric(
          'firstVisualChange',
          vm ? vm.FirstVisualChange : vm,
          m,
          true
        );
        lastVisualChange = this.formatMetric(
          'lastVisualChange',
          vm ? vm.LastVisualChange : vm,
          m,
          true
        );
        visualComplete85 = this.formatMetric(
          'visualComplete85',
          vm ? vm.VisualComplete85 : vm,
          m,
          true
        );
        pageLoad = this.formatMetric('Load', pt.pageLoadTime, m, true);
        backEndTime = this.formatMetric('TTFB', pt.backEndTime, m, true);
      }

      let lines = [
          `${requests}`,
          `${totalSize > 0 ? totalSize : ''}`,
          backEndTime,
          firstPaint,
          startRender,
          fcp,
          domContent,
          lcp,
          cls,
          tbt,
          pageLoad,
          speedIndex,
          perceptualSpeedIndex,
          contentfulSpeedIndex,
          visualComplete85,
          lastVisualChange
        ],
        note = m ? ` (${nRuns} runs)` : '';
{'fraction_non_alphanumeric': 0.12024901703800786, 'fraction_numerical': 0.007863695937090432, 'mean_word_length': 1.596257442585767, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, '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': '766019', 'n_tokens_mistral': 2696, 'n_tokens_neox': 2601, 'n_words': 496}