<commit_before>import { useDispatch, useSelector } from '../states/store';
import { BoolParam } from './BoolParam';
import { CHANNEL_FX_ROW_MAX } from '../../ChannelWithGUI';
import { InspectorHeader } from './InspectorHeader';
import { InspectorHr } from './InspectorHr';
import { InspectorItem } from './InspectorItem';
import { NumberParam } from './NumberParam';
import React from 'react';

// == component ====================================================================================
export interface InspectorCurveFxProps {
  curve: number;
  fx: string;
}

const InspectorCurveFx = ( props: InspectorCurveFxProps ): JSX.Element => {
  const dispatch = useDispatch();
  const { automaton, curves } = useSelector( ( state ) => ( {
    automaton: state.automaton.instance,
    curves: state.automaton.curves
  } ) );
  const curve = automaton?.getCurve( props.curve ) || null;
  const fx = curves[ props.curve ].fxs[ props.fx ];

  return <>
    { automaton && curve && <>
      <InspectorHeader text={ `Fx: ${ automaton.getFxDefinitionName( fx.def ) }` } />

      <InspectorHr />

      <InspectorItem name="Time">
        <NumberParam
          type="float"
          value={ fx.time }
          onChange={ ( value ) => { curve.moveFx( fx.$id, value ); } }
          onSettle={ ( time, timePrev ) => {
            dispatch( {
              type: 'History/Push',
              description: 'Change Fx Length',
              commands: [
                {
                  type: 'curve/moveFx',
                  curve: props.curve,
                  fx: fx.$id,
                  time,
                  timePrev
                }
              ]
            } );
          } }
        />
      </InspectorItem>
      <InspectorItem name="Length">
        <NumberParam
          type="float"
          value={ fx.length }
          onChange={ ( value ) => { curve.resizeFx( fx.$id, value ); } }
          onSettle={ ( length, lengthPrev ) => {
            dispatch( {
              type: 'History/Push',
              description: 'Change Fx Length',
              commands: [
                {
                  type: 'curve/resizeFx',
                  curve: props.curve,
                  fx: fx.$id,
                  length,
                  lengthPrev
                }
              ]
            } );
          } }
        />
      </InspectorItem>
      <InspectorItem name="Row">
        <NumberParam
          type="int"
          value={ fx.row }
          onChange={ ( value ) => {
            curve.changeFxRow(
              fx.$id,
              Math.min( Math.max( value, 0.0 ), CHANNEL_FX_ROW_MAX - 1 )
            );
          } }
          onSettle={ ( row, rowPrev ) => {
            dispatch( {
              type: 'History/Push',
              description: 'Change Fx Row',
              commands: [
                {
                  type: 'curve/changeFxRow',
                  curve: props.curve,
                  fx: fx.$id,
                  row,
                  rowPrev
                }
              ]
            } );
          } }
        />
      </InspectorItem>
      <InspectorItem name="Bypass">
        <BoolParam
          value={ !!fx.bypass }
          onChange={ ( value ) => {
            curve.bypassFx( fx.$id, value );
          } }
          onSettle={ ( value ) => {
            dispatch( {
              type: 'History/Push',
              description: 'Toggle Fx Bypass',
              commands: [
                {
                  type: 'curve/bypassFx',
                  curve: props.curve,
                  fx: fx.$id,
                  bypass: value<commit_msg>(from automaton-with-gui repo) Inspector: fix undo/redo of fx row<commit_after>import { useDispatch, useSelector } from '../states/store';
import { BoolParam } from './BoolParam';
import { CHANNEL_FX_ROW_MAX } from '../../ChannelWithGUI';
import { InspectorHeader } from './InspectorHeader';
import { InspectorHr } from './InspectorHr';
import { InspectorItem } from './InspectorItem';
import { NumberParam } from './NumberParam';
import React from 'react';
import { clamp } from '../utils/clamp';

// == component ====================================================================================
export interface InspectorCurveFxProps {
  curve: number;
  fx: string;
}

const InspectorCurveFx = ( props: InspectorCurveFxProps ): JSX.Element => {
  const dispatch = useDispatch();
  const { automaton, curves } = useSelector( ( state ) => ( {
    automaton: state.automaton.instance,
    curves: state.automaton.curves
  } ) );
  const curve = automaton?.getCurve( props.curve ) || null;
  const fx = curves[ props.curve ].fxs[ props.fx ];

  return <>
    { automaton && curve && <>
      <InspectorHeader text={ `Fx: ${ automaton.getFxDefinitionName( fx.def ) }` } />

      <InspectorHr />

      <InspectorItem name="Time">
        <NumberParam
          type="float"
          value={ fx.time }
          onChange={ ( value ) => { curve.moveFx( fx.$id, value ); } }
          onSettle={ ( time, timePrev ) => {
            dispatch( {
              type: 'History/Push',
              description: 'Change Fx Length',
              commands: [
                {
                  type: 'curve/moveFx',
                  curve: props.curve,
                  fx: fx.$id,
                  time,
                  timePrev
                }
              ]
            } );
          } }
        />
      </InspectorItem>
      <InspectorItem name="Length">
        <NumberParam
          type="float"
          value={ fx.length }
          onChange={ ( value ) => { curve.resizeFx( fx.$id, value ); } }
          onSettle={ ( length, lengthPrev ) => {
            dispatch( {
              type: 'History/Push',
              description: 'Change Fx Length',
              commands: [
                {
                  type: 'curve/resizeFx',
                  curve: props.curve,
                  fx: fx.$id,
                  length,
                  lengthPrev
                }
              ]
            } );
          } }
        />
      </InspectorItem>
      <InspectorItem name="Row">
        <NumberParam
          type="int"
          value={ fx.row }
          onChange={ ( row ) => {
            curve.changeFxRow(
              fx.$id,
              clamp( row, 0.0, CHANNEL_FX_ROW_MAX - 1 )
            );
          } }
          onSettle={ ( row, rowPrev ) => {
            dispatch( {
              type: 'History/Push',
              description: 'Change Fx Row',
              commands: [
                {
                  type: 'curve/changeFxRow',
                  curve: props.curve,
                  fx: fx.$id,
                  row: clamp( row, 0, CHANNEL_FX_ROW_MAX - 1 ),
                  rowPrev
                }
              ]
            } );
          } }
        />
      </InspectorItem>
      <InspectorItem name="Bypass">
        <BoolParam
          value={ !!fx.bypass }
          onChange={ ( value ) => {
            curve.bypassFx( fx.$id, value );
          } }
          onSettle={ ( value ) => {
            dispatch( {
              type: 'History/Push',
              description: 'Toggle Fx Bypass',
              commands: [
                {
                  type: 'curve/bypassFx',
                  curve: props.curve,
                  fx: fx.$id,
                  bypass: value
{'fraction_non_alphanumeric': 0.14759199134199133, 'fraction_numerical': 0.0010822510822510823, 'mean_word_length': 1.3380771663504112, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 51, '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': '4726833', 'n_tokens_mistral': 2089, 'n_tokens_neox': 1973, 'n_words': 423}