<commit_before>// @flow
import {escapeRegExp, indexInDirection, posInDirection, type Direction} from '../core/utils.js';
import ChangeDetails from '../core/change-details.js';
import {type TailDetails} from '../core/tail-details.js';

import Masked, {type MaskedOptions, type AppendFlags} from './base.js';


type MaskedNumberOptions = {
  ...MaskedOptions<Number>,
  radix: $PropertyType<MaskedNumber, 'radix'>,
  thousandsSeparator: $PropertyType<MaskedNumber, 'thousandsSeparator'>,
  mapToRadix: $PropertyType<MaskedNumber, 'mapToRadix'>,
  scale: $PropertyType<MaskedNumber, 'scale'>,
  signed: $PropertyType<MaskedNumber, 'signed'>,
  normalizeZeros: $PropertyType<MaskedNumber, 'normalizeZeros'>,
  padFractionalZeros: $PropertyType<MaskedNumber, 'padFractionalZeros'>,
};

/**
  Number mask
  @param {Object} opts
  @param {string} opts.radix - Single char
  @param {string} opts.thousandsSeparator - Single char
  @param {Array<string>} opts.mapToRadix - Array of single chars
  @param {number} opts.min
  @param {number} opts.max
  @param {number} opts.scale - Digits after point
  @param {boolean} opts.signed - Allow negative
  @param {boolean} opts.normalizeZeros - Flag to remove leading and trailing zeros in the end of editing
  @param {boolean} opts.padFractionalZeros - Flag to pad trailing zeros after point in the end of editing
*/
export default
class MaskedNumber extends Masked<Number> {
  static DEFAULTS: $Shape<MaskedNumberOptions>;

  /** Single char */
  radix: string;
  /** Single char */
  thousandsSeparator: string;
  /** Array of single chars */
  mapToRadix: Array<string>;
  /** */
  min: number;
  /** */
  max: number;
  /** Digits after point */
  scale: number;
  /** */
  signed: boolean;
  /** Flag to remove leading and trailing zeros in the end of editing */
  normalizeZeros: boolean;
  /** Flag to pad trailing zeros after point in the end of editing */
  padFractionalZeros: boolean;
  _numberRegExp: RegExp;
  _numberRegExpInput: RegExp;
  _thousandsSeparatorRegExp: RegExp;
  _mapToRadixRegExp: RegExp;
  _separatorsProcessed: boolean;

  constructor (opts: $Shape<MaskedNumberOptions>) {
    super({
      ...MaskedNumber.DEFAULTS,
      ...opts
    });
  }

  /**
    @override
  */
  _update (opts: MaskedNumberOptions) {
    super._update(opts);
    this._updateRegExps();
  }

  /** */
  _updateRegExps () {
    // use different regexp to process user input (more strict, input suffix) and tail shifting
    const start = '^'

    let midInput = '';
    let mid = '';
    if (this.allowNegative) {
      midInput += '([+|\\-]?|([+|\\-]?(0|([1-9]+\\d*))))';
      mid += '[+|\\-]?';
    } else {
      midInput += '(0|([1-9]+\\d*))';
    }
    mid += '\\d*';

    let end = (this.scale ?
      '(' + this.radix + '\\d{0,' + this.scale + '})?' :
      '') + '$';

    this._numberRegExpInput = new RegExp(start + midInput + end);
    this._numberRegExp = new RegExp(start + mid + end);
    this._mapToRadixRegExp = new RegExp('[' +
      this.mapToRadix.map(escapeRegExp).join('') +
    ']', 'g');
    this._thousandsSeparatorRegExp = new RegExp(escapeRegExp(this.thousandsSeparator), 'g');<commit_msg>fix #91 - escape radix char<commit_after>// @flow
import {escapeRegExp, indexInDirection, posInDirection, type Direction} from '../core/utils.js';
import ChangeDetails from '../core/change-details.js';
import {type TailDetails} from '../core/tail-details.js';

import Masked, {type MaskedOptions, type AppendFlags} from './base.js';


type MaskedNumberOptions = {
  ...MaskedOptions<Number>,
  radix: $PropertyType<MaskedNumber, 'radix'>,
  thousandsSeparator: $PropertyType<MaskedNumber, 'thousandsSeparator'>,
  mapToRadix: $PropertyType<MaskedNumber, 'mapToRadix'>,
  scale: $PropertyType<MaskedNumber, 'scale'>,
  signed: $PropertyType<MaskedNumber, 'signed'>,
  normalizeZeros: $PropertyType<MaskedNumber, 'normalizeZeros'>,
  padFractionalZeros: $PropertyType<MaskedNumber, 'padFractionalZeros'>,
};

/**
  Number mask
  @param {Object} opts
  @param {string} opts.radix - Single char
  @param {string} opts.thousandsSeparator - Single char
  @param {Array<string>} opts.mapToRadix - Array of single chars
  @param {number} opts.min
  @param {number} opts.max
  @param {number} opts.scale - Digits after point
  @param {boolean} opts.signed - Allow negative
  @param {boolean} opts.normalizeZeros - Flag to remove leading and trailing zeros in the end of editing
  @param {boolean} opts.padFractionalZeros - Flag to pad trailing zeros after point in the end of editing
*/
export default
class MaskedNumber extends Masked<Number> {
  static DEFAULTS: $Shape<MaskedNumberOptions>;

  /** Single char */
  radix: string;
  /** Single char */
  thousandsSeparator: string;
  /** Array of single chars */
  mapToRadix: Array<string>;
  /** */
  min: number;
  /** */
  max: number;
  /** Digits after point */
  scale: number;
  /** */
  signed: boolean;
  /** Flag to remove leading and trailing zeros in the end of editing */
  normalizeZeros: boolean;
  /** Flag to pad trailing zeros after point in the end of editing */
  padFractionalZeros: boolean;
  _numberRegExp: RegExp;
  _numberRegExpInput: RegExp;
  _thousandsSeparatorRegExp: RegExp;
  _mapToRadixRegExp: RegExp;
  _separatorsProcessed: boolean;

  constructor (opts: $Shape<MaskedNumberOptions>) {
    super({
      ...MaskedNumber.DEFAULTS,
      ...opts
    });
  }

  /**
    @override
  */
  _update (opts: MaskedNumberOptions) {
    super._update(opts);
    this._updateRegExps();
  }

  /** */
  _updateRegExps () {
    // use different regexp to process user input (more strict, input suffix) and tail shifting
    const start = '^'

    let midInput = '';
    let mid = '';
    if (this.allowNegative) {
      midInput += '([+|\\-]?|([+|\\-]?(0|([1-9]+\\d*))))';
      mid += '[+|\\-]?';
    } else {
      midInput += '(0|([1-9]+\\d*))';
    }
    mid += '\\d*';

    let end = (this.scale ?
      '(' + escapeRegExp(this.radix) + '\\d{0,' + this.scale + '})?' :
      '') + '$';

    this._numberRegExpInput = new RegExp(start + midInput + end);
    this._numberRegExp = new RegExp(start + mid + end);
    this._mapToRadixRegExp = new RegExp('[' +
      this.mapToRadix.map(escapeRegExp).join('') +
    ']', 'g');
    this._thousandsSeparatorRegExp = new RegExp(escapeRegExp(this.thousandsSeparator), 'g');
{'fraction_non_alphanumeric': 0.1527777777777778, 'fraction_numerical': 0.0025252525252525255, 'mean_word_length': 3.608727272727273, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, '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': '6701236', 'n_tokens_mistral': 2102, 'n_tokens_neox': 2084, 'n_words': 523}