<commit_before>// [VexFlow](http://vexflow.com) - Copyright (c) <NAME> 2010.
//
// ## Description
//
// This file implements an abstract interface for notes and chords that
// are rendered on a stave. Notes have some common properties: All of them
// have a value (e.g., pitch, fret, etc.) and a duration (quarter, half, etc.)
//
// Some notes have stems, heads, dots, etc. Most notational elements that
// surround a note are called *modifiers*, and every note has an associated
// array of them. All notes also have a rendering context and belong to a stave.

import { Vex } from './vex';
import { Flow } from './tables';
import { Tickable } from './tickable';

export class Note extends Tickable {
  static get CATEGORY() { return 'note'; }
  static get STAVEPADDING() { return 12; }

  // Debug helper. Displays various note metrics for the given
  // note.
  static plotMetrics(ctx, note, yPos) {
    const metrics = note.getMetrics();
    const xStart = note.getAbsoluteX() - metrics.modLeftPx - metrics.extraLeftPx;
    const xPre1 = note.getAbsoluteX() - metrics.extraLeftPx;
    const xAbs = note.getAbsoluteX();
    const xPost1 = note.getAbsoluteX() + metrics.noteWidth;
    const xPost2 = note.getAbsoluteX() + metrics.noteWidth + metrics.extraRightPx;
    const xEnd = note.getAbsoluteX()
      + metrics.noteWidth
      + metrics.extraRightPx
      + metrics.modRightPx;
    const xFreedomRight = xEnd + note.getFormatterMetrics().freedom.right;

    const xWidth = xEnd - xStart;
    ctx.save();
    ctx.setFont('Arial', 8, '');
    ctx.fillText(Math.round(xWidth) + 'px', xStart + note.getXShift(), yPos);

    const y = (yPos + 7);
    function stroke(x1, x2, color, yy = y) {
      ctx.beginPath();
      ctx.setStrokeStyle(color);
      ctx.setFillStyle(color);
      ctx.setLineWidth(3);
      ctx.moveTo(x1 + note.getXShift(), yy);
      ctx.lineTo(x2 + note.getXShift(), yy);
      ctx.stroke();
    }

    stroke(xStart, xPre1, 'red');
    stroke(xPre1, xAbs, '#999');
    stroke(xAbs, xPost1, 'green');
    stroke(xPost1, xPost2, '#999');
    stroke(xPost2, xEnd, 'red');
    stroke(xEnd, xFreedomRight, '#DD0');
    stroke(xStart - note.getXShift(), xStart, '#BBB'); // Shift
    Vex.drawDot(ctx, xAbs + note.getXShift(), y, 'blue');

    const formatterMetrics = note.getFormatterMetrics();
    if (formatterMetrics.iterations > 0) {
      const spaceDeviation = formatterMetrics.space.deviation;
      const prefix = spaceDeviation >= 0 ? '+' : '';
      ctx.setFillStyle('red');
      ctx.fillText(prefix + Math.round(spaceDeviation),
        xAbs + note.getXShift(), yPos - 10);
    }
    ctx.restore();
  }

  static parseDuration(durationString) {
    if (typeof (durationString) !== 'string') {
      return null;
    }

    const regexp = /(\d*\/?\d+|[a-z])(d*)([nrhms]|$)/;

    const result = regexp.exec(durationString);
    if (!result) {
      return null;
    }

    const duration = result[1];
    const dots = result[2].length;
    let type = result[3];

    if (type.length === 0) {
      type = 'n';
    }

    return {
      duration,
      dots,
      type,
    };
  }

  static parseNoteStruct(noteStruct) {
    const durationString = noteStruct.duration;
    const customTypes = [];

    // Preserve backwards-compatibility<commit_msg>Formatting fixes.<commit_after>// [VexFlow](http://vexflow.com) - Copyright (c) <NAME> 2010.
//
// ## Description
//
// This file implements an abstract interface for notes and chords that
// are rendered on a stave. Notes have some common properties: All of them
// have a value (e.g., pitch, fret, etc.) and a duration (quarter, half, etc.)
//
// Some notes have stems, heads, dots, etc. Most notational elements that
// surround a note are called *modifiers*, and every note has an associated
// array of them. All notes also have a rendering context and belong to a stave.

import { Vex } from './vex';
import { Flow } from './tables';
import { Tickable } from './tickable';

export class Note extends Tickable {
  static get CATEGORY() { return 'note'; }
  static get STAVEPADDING() { return 12; }

  // Debug helper. Displays various note metrics for the given
  // note.
  static plotMetrics(ctx, note, yPos) {
    const metrics = note.getMetrics();
    const xStart = note.getAbsoluteX() - metrics.modLeftPx - metrics.extraLeftPx;
    const xPre1 = note.getAbsoluteX() - metrics.extraLeftPx;
    const xAbs = note.getAbsoluteX();
    const xPost1 = note.getAbsoluteX() + metrics.noteWidth;
    const xPost2 = note.getAbsoluteX() + metrics.noteWidth + metrics.extraRightPx;
    const xEnd = note.getAbsoluteX()
      + metrics.noteWidth
      + metrics.extraRightPx
      + metrics.modRightPx;
    const xFreedomRight = xEnd + note.getFormatterMetrics().freedom.right;

    const xWidth = xEnd - xStart;
    ctx.save();
    ctx.setFont('Arial', 8, '');
    ctx.fillText(Math.round(xWidth) + 'px', xStart + note.getXShift(), yPos);

    const y = (yPos + 7);
    function stroke(x1, x2, color, yy = y) {
      ctx.beginPath();
      ctx.setStrokeStyle(color);
      ctx.setFillStyle(color);
      ctx.setLineWidth(3);
      ctx.moveTo(x1 + note.getXShift(), yy);
      ctx.lineTo(x2 + note.getXShift(), yy);
      ctx.stroke();
    }

    stroke(xStart, xPre1, 'red');
    stroke(xPre1, xAbs, '#999');
    stroke(xAbs, xPost1, 'green');
    stroke(xPost1, xPost2, '#999');
    stroke(xPost2, xEnd, 'red');
    stroke(xEnd, xFreedomRight, '#DD0');
    stroke(xStart - note.getXShift(), xStart, '#BBB'); // Shift
    Vex.drawDot(ctx, xAbs + note.getXShift(), y, 'blue');

    const formatterMetrics = note.getFormatterMetrics();
    if (formatterMetrics.iterations > 0) {
      const spaceDeviation = formatterMetrics.space.deviation;
      const prefix = spaceDeviation >= 0 ? '+' : '';
      ctx.setFillStyle('red');
      ctx.fillText(prefix + Math.round(spaceDeviation),
        xAbs + note.getXShift(), yPos - 10);
    }
    ctx.restore();
  }

  static parseDuration(durationString) {
    if (typeof (durationString) !== 'string') { return null; }

    const regexp = /(\d*\/?\d+|[a-z])(d*)([nrhms]|$)/;
    const result = regexp.exec(durationString);
    if (!result) { return null; }

    const duration = result[1];
    const dots = result[2].length;
    const type = result[3] || 'n';

    return { duration, dots, type };
  }

  static parseNoteStruct(noteStruct) {
    const durationString = noteStruct.duration;
    const customTypes = [];

    // Preserve backwards-compatibility
{'fraction_non_alphanumeric': 0.14570149714462108, 'fraction_numerical': 0.011267170859700571, 'mean_word_length': 3.0729101194217474, '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': '5642458', 'n_tokens_mistral': 2163, 'n_tokens_neox': 2084, 'n_words': 564}