<commit_before>import FontFaceObserver from 'fontfaceobserver';
import { select } from 'd3-selection';
import { csvParseRows } from 'd3-dsv';
import { timeYears, timeMonths, timeDays, timeHours, timeMinutes } from 'd3-time';
import {
  curveLinear,
  curveCardinal,
  curveCatmullRom,
  curveMonotoneX,
  curveNatural,
  curveStepBefore,
  curveStepAfter
} from 'd3-shape';
import Settings from '../config/chart-settings';
import bucket from '../config/env';
import 'core-js/fn/set';
import 'core-js/fn/array/from';

export function debounce(fn, params, timeout, root) {
  let timeoutID = -1;
  return (() => {
    if (timeoutID > -1) { root.clearTimeout(timeoutID); }
    timeoutID = root.setTimeout(() => {
      fn(params);
    }, timeout);
  });
}

export function clearChart(cont) {
  let el = document.querySelector(cont);
  while (el && el.querySelectorAll('svg').length) {
    let svg = el.querySelectorAll('svg');
    svg[svg.length - 1].parentNode.removeChild(svg[svg.length - 1]);
  }
  while (el && el.querySelectorAll('div').length) {
    let div = el.querySelectorAll('div');
    div[div.length - 1].parentNode.removeChild(div[div.length - 1]);
  }
  return cont;
}

export function clearObj(obj) {
  if (obj.chartObj) { obj.chartObj = undefined; }
  return obj;
}

export function clearDrawn(drawn, obj) {
  if (drawn.length) {
    for (let i = drawn.length - 1; i >= 0; i--) {
      if (drawn[i].id === obj.id) {
        drawn.splice(i, 1);
      }
    }
  }
  return drawn;
}

export function getBounding(selector, dimension) {
  return document.querySelector(selector).getBoundingClientRect()[dimension];
}

export class TimeObj {
  constructor() {
    this.second = 1000;
    this.minute = this.second * 60;
    this.hour = this.minute * 60;
    this.day = this.hour * 24;
    this.week = this.day * 7;
    this.month = this.day * 30;
    this.year = this.day * 365;
    this.today = new Date();
  }
}

export function wrapText(text, width) {
  text.each(function() {

    const text = select(this),
      y = text.attr('y'),
      lineHeight = 1.0, // ems
      x = 0,
      dy = parseFloat(text.attr('dy'));

    let words = text.text().split(/\s+/).reverse(),
      line = [],
      lineNumber = 0,
      word,
      tspan = text.text(null).append('tspan')
        .attr('x', x)
        .attr('y', y)
        .attr('dy', `${dy}em`);

    while (word = words.pop()) {
      line.push(word);
      tspan.text(line.join(' '));
      if (tspan.node().getComputedTextLength() > width && line.length > 1) {
        line.pop();
        tspan.text(line.join(' '));
        line = [word];
        tspan = text.append('tspan')
          .attr('x', x)
          .attr('y', y)
          .attr('dy', `${++lineNumber * lineHeight + dy}em`)
          .text(word);
      }
    }
  });
}

export function timeDiff(d1, d2, tolerance, data) {

  const diff = d2 - d1,
    time = new TimeObj();

  let ctx;

  // returning the context
  if ((diff / time.year) > tolerance) { ctx = 'years'; }
  else if ((diff / time.month) > tolerance) { ctx = 'months'; }
  else if ((diff / time.week) > tolerance) { ctx = 'weeks'; }
  else if ((diff / time.day) > tolerance) { ctx = 'days'; }
  else if ((diff / time.hour) > tolerance) { ctx = 'hours'; }
  else if ((diff / time.min) > tolerance) { ctx = 'minutes'; }
  else { ctx = 'days'; }
  // if none of these work i feel bad for you son
  // i've got 99 problems but an if/else ain't one

  // data passed in, looking at drawing tips
  if (data && ctx === 'years' || ctx === 'months') {
    const uniqueDayValues = data.uniqueDayValues;
    const uniqueMonthValues = data.uniqueMonthValues;
<commit_msg>just wrapping something in parens for clarity<commit_after>import FontFaceObserver from 'fontfaceobserver';
import { select } from 'd3-selection';
import { csvParseRows } from 'd3-dsv';
import { timeYears, timeMonths, timeDays, timeHours, timeMinutes } from 'd3-time';
import {
  curveLinear,
  curveCardinal,
  curveCatmullRom,
  curveMonotoneX,
  curveNatural,
  curveStepBefore,
  curveStepAfter
} from 'd3-shape';
import Settings from '../config/chart-settings';
import bucket from '../config/env';
import 'core-js/fn/set';
import 'core-js/fn/array/from';

export function debounce(fn, params, timeout, root) {
  let timeoutID = -1;
  return (() => {
    if (timeoutID > -1) { root.clearTimeout(timeoutID); }
    timeoutID = root.setTimeout(() => {
      fn(params);
    }, timeout);
  });
}

export function clearChart(cont) {
  let el = document.querySelector(cont);
  while (el && el.querySelectorAll('svg').length) {
    let svg = el.querySelectorAll('svg');
    svg[svg.length - 1].parentNode.removeChild(svg[svg.length - 1]);
  }
  while (el && el.querySelectorAll('div').length) {
    let div = el.querySelectorAll('div');
    div[div.length - 1].parentNode.removeChild(div[div.length - 1]);
  }
  return cont;
}

export function clearObj(obj) {
  if (obj.chartObj) { obj.chartObj = undefined; }
  return obj;
}

export function clearDrawn(drawn, obj) {
  if (drawn.length) {
    for (let i = drawn.length - 1; i >= 0; i--) {
      if (drawn[i].id === obj.id) {
        drawn.splice(i, 1);
      }
    }
  }
  return drawn;
}

export function getBounding(selector, dimension) {
  return document.querySelector(selector).getBoundingClientRect()[dimension];
}

export class TimeObj {
  constructor() {
    this.second = 1000;
    this.minute = this.second * 60;
    this.hour = this.minute * 60;
    this.day = this.hour * 24;
    this.week = this.day * 7;
    this.month = this.day * 30;
    this.year = this.day * 365;
    this.today = new Date();
  }
}

export function wrapText(text, width) {
  text.each(function() {

    const text = select(this),
      y = text.attr('y'),
      lineHeight = 1.0, // ems
      x = 0,
      dy = parseFloat(text.attr('dy'));

    let words = text.text().split(/\s+/).reverse(),
      line = [],
      lineNumber = 0,
      word,
      tspan = text.text(null).append('tspan')
        .attr('x', x)
        .attr('y', y)
        .attr('dy', `${dy}em`);

    while (word = words.pop()) {
      line.push(word);
      tspan.text(line.join(' '));
      if (tspan.node().getComputedTextLength() > width && line.length > 1) {
        line.pop();
        tspan.text(line.join(' '));
        line = [word];
        tspan = text.append('tspan')
          .attr('x', x)
          .attr('y', y)
          .attr('dy', `${++lineNumber * lineHeight + dy}em`)
          .text(word);
      }
    }
  });
}

export function timeDiff(d1, d2, tolerance, data) {

  const diff = d2 - d1,
    time = new TimeObj();

  let ctx;

  // returning the context
  if ((diff / time.year) > tolerance) { ctx = 'years'; }
  else if ((diff / time.month) > tolerance) { ctx = 'months'; }
  else if ((diff / time.week) > tolerance) { ctx = 'weeks'; }
  else if ((diff / time.day) > tolerance) { ctx = 'days'; }
  else if ((diff / time.hour) > tolerance) { ctx = 'hours'; }
  else if ((diff / time.min) > tolerance) { ctx = 'minutes'; }
  else { ctx = 'days'; }
  // if none of these work i feel bad for you son
  // i've got 99 problems but an if/else ain't one

  // data passed in, looking at drawing tips
  if (data && (ctx === 'years' || ctx === 'months')) {
    const uniqueDayValues = data.uniqueDayValues;
    const uniqueMonthValues = data.uniqueMonthValues;

{'fraction_non_alphanumeric': 0.16816816816816818, 'fraction_numerical': 0.01092001092001092, 'mean_word_length': 2.770972722593927, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 27, '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': '1033340', 'n_tokens_mistral': 2556, 'n_tokens_neox': 2466, 'n_words': 620}