<commit_before>import btod from "./btod";
import formatDefault from "./formatDefault";
import formatGroup from "./formatGroup";
import formatRounded from "./formatRounded";
import formatRoundedPercentage from "./formatRoundedPercentage";
import formatSystem from "./formatSystem";

// [[fill]align][sign][symbol][0][width][,][.precision][type]
var formatRe = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i;

var formatTypes = {
  "b": function(x) { return x.toString(2); },
  "c": function(x) { return String.fromCharCode(x); },
  "o": function(x) { return x.toString(8); },
  "x": function(x) { return x.toString(16); },
  "X": function(x) { return x.toString(16).toUpperCase(); },
  "g": function(x, p) { return x.toPrecision(p); },
  "e": function(x, p) { return x.toExponential(p); },
  "f": function(x, p) { return x.toFixed(p); },
  "%": function(x, p) { return (x * 100).toFixed(p); },
  "p": formatRoundedPercentage,
  "r": formatRounded,
  "s": formatSystem
};

function identity(x) {
  return x;
}

export default function(locale) {
  var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity,
      currency = locale.currency,
      decimal = locale.decimal;

  return function(specifier) {
    var match = formatRe.exec(specifier),
        fill = match[1] || " ",
        align = match[2] || ">",
        sign = match[3] || "-",
        symbol = match[4] || "",
        zero = match[5],
        width = +match[6],
        comma = match[7],
        precision = match[8],
        type = match[9] || "";

    // The "n" type is an alias for ",g".
    if (type === "n") comma = true, type = "g";

    // If zero fill is specified, padding goes after sign and before digits.
    if (zero || (fill === "0" && align === "=")) zero = fill = "0", align = "=";

    // Clamp the specified precision to the supported range.
    // For significant precision, it must be in [1, 21].
    // For fixed precision, it must be in [0, 20].
    if (precision) {
      precision = +precision.substring(1);
      precision = /[gprs]/.test(type)
          ? Math.max(1, Math.min(21, precision))
          : Math.max(0, Math.min(20, precision));
    }

    // Compute the fixed prefix and suffix.
    var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
        suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : "";

    // Is this an integer type?
    // Can this type generate exponential notation?
    // What format function should we use?
    var integer = /[bcdoxX]/.test(type),
        maybeDecimal = !type || /[defgprs%]/.test(type),
        maybeExponent = !type || /[deg]/.test(type),
        format = formatTypes[type] || formatDefault;

    return function(value) {
      value = +value;

      // Return the empty string for floats formatted as ints.
      if (integer && (value % 1)) return "";

      // Convert negative to positive, and compute the prefix.
      // Note that -0 is not less than 0, but 1 / -0 is!
      var valueSuffix = suffix,
          valuePrefix = (value < 0 || 1 / value < 0 ? (value *= -1, "-")
              : sign === "-" ? ""
              : sign) + prefix;

      // Perform the initial formatting.
      value = format(value, precision);

      // Break the formatted value into the integer “value” part that can be
      // grouped, and fractional or exponential “suffix” part that is not.
      if (maybeDecimal) {
        var i = value.indexOf(".");
        if (i >= 0) {
          valueSuffix = decimal + value.substring(i + 1) + suffix;
          value = value.substring(0, i);
        } else if (maybeExponent) {<commit_msg>Cleaner handling of invalid format types.<commit_after>import btod from "./btod";
import formatDefault from "./formatDefault";
import formatGroup from "./formatGroup";
import formatRounded from "./formatRounded";
import formatRoundedPercentage from "./formatRoundedPercentage";
import formatSystem from "./formatSystem";

// [[fill]align][sign][symbol][0][width][,][.precision][type]
var formatRe = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i;

var formatTypes = {
  "": formatDefault,
  "%": function(x, p) { return (x * 100).toFixed(p); },
  "b": function(x) { return x.toString(2); },
  "c": function(x) { return String.fromCharCode(x); },
  "d": formatDefault,
  "e": function(x, p) { return x.toExponential(p); },
  "f": function(x, p) { return x.toFixed(p); },
  "g": function(x, p) { return x.toPrecision(p); },
  "o": function(x) { return x.toString(8); },
  "p": formatRoundedPercentage,
  "r": formatRounded,
  "s": formatSystem,
  "X": function(x) { return x.toString(16).toUpperCase(); },
  "x": function(x) { return x.toString(16); }
};

function identity(x) {
  return x;
}

export default function(locale) {
  var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity,
      currency = locale.currency,
      decimal = locale.decimal;

  return function(specifier) {
    var match = formatRe.exec(specifier),
        fill = match[1] || " ",
        align = match[2] || ">",
        sign = match[3] || "-",
        symbol = match[4] || "",
        zero = match[5],
        width = +match[6],
        comma = match[7],
        precision = match[8],
        type = match[9];

    // The "n" type is an alias for ",g".
    if (type === "n") comma = true, type = "g";

    // Map invalid types to the default format.
    else if (!(type in formatTypes)) type = "";

    // If zero fill is specified, padding goes after sign and before digits.
    if (zero || (fill === "0" && align === "=")) zero = fill = "0", align = "=";

    // Clamp the specified precision to the supported range.
    // For significant precision, it must be in [1, 21].
    // For fixed precision, it must be in [0, 20].
    if (precision) {
      precision = +precision.substring(1);
      precision = /[gprs]/.test(type)
          ? Math.max(1, Math.min(21, precision))
          : Math.max(0, Math.min(20, precision));
    }

    // Compute the fixed prefix and suffix.
    var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
        suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : "";

    // What format function should we use?
    // Is this an integer type?
    // Can this type generate exponential notation?
    var format = formatTypes[type],
        integer = /[bcdoxX]/.test(type),
        maybeDecimal = !type || /[defgprs%]/.test(type),
        maybeExponent = !type || /[deg]/.test(type);

    return function(value) {
      value = +value;

      // Return the empty string for floats formatted as ints.
      if (integer && (value % 1)) return "";

      // Convert negative to positive, and compute the prefix.
      // Note that -0 is not less than 0, but 1 / -0 is!
      var valueSuffix = suffix,
          valuePrefix = (value < 0 || 1 / value < 0 ? (value *= -1, "-")
              : sign === "-" ? ""
              : sign) + prefix;

      // Perform the initial formatting.
      value = format(value, precision);

      // Break the formatted value into the integer “value” part that can be
      // grouped, and fractional or exponential “suffix” part that is not.
      if (maybeDecimal) {
        var i = value.indexOf(".");
        if (i >= 0) {
          valueSuffix = decimal + value.substring(i + 1) + suffix;
          value = value.substring(0, i);
        } else if (maybeExponent) {
{'fraction_non_alphanumeric': 0.18379733474073096, 'fraction_numerical': 0.013194352816994326, 'mean_word_length': 2.6600676001931434, 'pattern_counts': {'":': 26, '<': 9, '<?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': '7278109', 'n_tokens_mistral': 2472, 'n_tokens_neox': 2384, 'n_words': 696}