<commit_before>const ansiEscapes = require('ansi-escapes')
const ansiRegex = require('ansi-regex')
const chalk = require('chalk')
const stripAnsi = require('strip-ansi')

const eraseLines = require('../output/erase-lines')

const ESCAPES = {
  LEFT: '\u001B[D',
  RIGHT: '\u001B[C',
  CTRL_C: '\u0003',
  BACKSPACE: '\u0008',
  CTRL_H: '\u007F',
  CARRIAGE: '\r'
}

function formatCC(data) {
  return data.replace(/\s/g, '').replace(/(.{4})/g, '$1 ').trim()
}

module.exports = function(
  {
    label = '',
    initialValue = '',
    // If false, the `- label` will be printed as `✖ label` in red
    // Until the first keypress
    valid = true,
    // Can be:
    // - `false`, which does nothing
    // - `cc`, for credit cards
    // - `date`, for dates in the mm / yyyy format
    mask = false,
    placeholder = '',
    abortSequences = new Set(['\x03']),
    eraseSequences = new Set([ESCAPES.BACKSPACE, ESCAPES.CTRL_H]),
    resolveChars = new Set([ESCAPES.CARRIAGE]),
    stdin = process.stdin,
    stdout = process.stdout,
    // Char to print before resolving/rejecting the promise
    // If `false`, nothing will be printed
    trailing = ansiEscapes.eraseLines(1),
    // Gets called on each keypress;
    // `data` contains the current keypress;
    // `futureValue` contains the current value + the
    // Keypress in the correct place
    validateKeypress = (data, futureValue) => true, // eslint-disable-line no-unused-vars
    // Get's called before the promise is resolved
    // Returning `false` here will prevent the user from submiting the value
    validateValue = data => true, // eslint-disable-line no-unused-vars
    // Receives the value of the input and should return a string
    // Or false if no autocomplion is available
    autoComplete = value => false, // eslint-disable-line no-unused-vars
    // Tab
    // Right arrow
    autoCompleteChars = new Set(['\t', '\x1b[C']),
    // If true, converts everything the user types to to lowercase
    forceLowerCase = false
  } = {}
) {
  return new Promise((resolve, reject) => {
    const isRaw = process.stdin.isRaw

    let value
    let caretOffset = 0
    let regex
    let suggestion = ''

    if (valid) {
      stdout.write(label)
    } else {
      const _label = label.replace('-', '✖')
      stdout.write(chalk.red(_label))
    }
    value = initialValue
    stdout.write(initialValue)

    if (mask) {
      if (!value) {
        value = chalk.gray(placeholder)
        caretOffset = 0 - stripAnsi(value).length
        stdout.write(value)
        stdout.write(ansiEscapes.cursorBackward(Math.abs(caretOffset)))
      }

      regex = placeholder
        .split('')
        .reduce((prev, curr) => {
          if (curr !== ' ' && !prev.includes(curr)) {
            if (curr === '/') {
              prev.push(' / ')
            } else {
              prev.push(curr)
            }
          }
          return prev
        }, [])
        .join('|')
      regex = new RegExp(`(${regex})`, 'g')
    }
    stdin.setRawMode(true)
    stdin.resume()

    function restore() {<commit_msg>Use arrow functions and import comments where possible<commit_after>// Packages
const ansiEscapes = require('ansi-escapes')
const ansiRegex = require('ansi-regex')
const chalk = require('chalk')
const stripAnsi = require('strip-ansi')

// Utilities
const eraseLines = require('../output/erase-lines')

const ESCAPES = {
  LEFT: '\u001B[D',
  RIGHT: '\u001B[C',
  CTRL_C: '\u0003',
  BACKSPACE: '\u0008',
  CTRL_H: '\u007F',
  CARRIAGE: '\r'
}

const formatCC = data => data.replace(/\s/g, '').replace(/(.{4})/g, '$1 ').trim()

module.exports = function(
  {
    label = '',
    initialValue = '',
    // If false, the `- label` will be printed as `✖ label` in red
    // Until the first keypress
    valid = true,
    // Can be:
    // - `false`, which does nothing
    // - `cc`, for credit cards
    // - `date`, for dates in the mm / yyyy format
    mask = false,
    placeholder = '',
    abortSequences = new Set(['\x03']),
    eraseSequences = new Set([ESCAPES.BACKSPACE, ESCAPES.CTRL_H]),
    resolveChars = new Set([ESCAPES.CARRIAGE]),
    stdin = process.stdin,
    stdout = process.stdout,
    // Char to print before resolving/rejecting the promise
    // If `false`, nothing will be printed
    trailing = ansiEscapes.eraseLines(1),
    // Gets called on each keypress;
    // `data` contains the current keypress;
    // `futureValue` contains the current value + the
    // Keypress in the correct place
    validateKeypress = (data, futureValue) => true, // eslint-disable-line no-unused-vars
    // Get's called before the promise is resolved
    // Returning `false` here will prevent the user from submiting the value
    validateValue = data => true, // eslint-disable-line no-unused-vars
    // Receives the value of the input and should return a string
    // Or false if no autocomplion is available
    autoComplete = value => false, // eslint-disable-line no-unused-vars
    // Tab
    // Right arrow
    autoCompleteChars = new Set(['\t', '\x1b[C']),
    // If true, converts everything the user types to to lowercase
    forceLowerCase = false
  } = {}
) {
  return new Promise((resolve, reject) => {
    const isRaw = process.stdin.isRaw

    let value
    let caretOffset = 0
    let regex
    let suggestion = ''

    if (valid) {
      stdout.write(label)
    } else {
      const _label = label.replace('-', '✖')
      stdout.write(chalk.red(_label))
    }

    value = initialValue
    stdout.write(initialValue)

    if (mask) {
      if (!value) {
        value = chalk.gray(placeholder)
        caretOffset = 0 - stripAnsi(value).length
        stdout.write(value)
        stdout.write(ansiEscapes.cursorBackward(Math.abs(caretOffset)))
      }

      regex = placeholder
        .split('')
        .reduce((prev, curr) => {
          if (curr !== ' ' && !prev.includes(curr)) {
            if (curr === '/') {
              prev.push(' / ')
            } else {
              prev.push(curr)
            }
          }
          return prev
        }, [])
        .join('|')
      regex = new RegExp(`(${regex})`, 'g')
    }

    stdin.setRawMode(true)
    stdin.resume()

    function restore() {
{'fraction_non_alphanumeric': 0.14255798969072164, 'fraction_numerical': 0.008054123711340205, 'mean_word_length': 2.3525917926565874, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 14, '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': '886078', 'n_tokens_mistral': 2036, 'n_tokens_neox': 1949, 'n_words': 536}