class TextgridFormats:
    LONG_TEXTGRID: Final = "long_textgrid"
    SHORT_TEXTGRID: Final = "short_textgrid"
    JSON: Final = "json"

    validOptions = [LONG_TEXTGRID, SHORT_TEXTGRID, JSON] MIN_INTERVAL_LENGTH: Final = 0.00000001  # Arbitrary threshold class CropCollision:
    STRICT: Final = "strict"
    LAX: Final = "lax"
    TRUNCATED: Final = "truncated"

    validOptions = [STRICT, LAX, TRUNCATED] T = TypeVar("T", bound="TextgridTier")
class TextgridTier(ABC):
    def __init__(
        self,
        name: str,
        entryList: List,
        minT: float,
        maxT: float,
        errorMode: Literal["silence", "warning", "error"] = "warning",
    ):
    def __eq__(self, other):
    def appendTier(self, tier: "TextgridTier") -> "TextgridTier":
    def find(
        self,
        matchLabel: str,
        substrMatchFlag: bool = False,
        usingRE: bool = False,
    ) -> List[int]:
    def new(
        self: T,
        name: Optional[str] = None,
        entryList: Optional[list] = None,
        minTimestamp: Optional[float] = None,
        maxTimestamp: Optional[float] = None,
    ) -> T:
    def sort(self) -> None:
    def union(self, tier: "TextgridTier") -> "TextgridTier":
    def editTimestamps(
        self,
        offset: float,
        reportingMode: Literal["silence", "warning", "error"] = "warning",
    ) -> "TextgridTier":  # pragma: no cover
    def insertEntry(
        self,
        entry,
        collisionMode: Literal["replace", "merge", "error"] = "error",
        collisionReportingMode: Literal["silence", "warning"] = "warning",
    ) -> None:  # pragma: no cover
    def eraseRegion(
        self,
        start: float,
        end: float,
        collisionMode: Literal["truncate", "categorical", "error"] = "error",
        doShrink: bool = True,
    ) -> "TextgridTier":  # pragma: no cover
    def crop(
        self,
        cropStart: float,
        cropEnd: float,
        mode: Literal["strict", "lax", "truncated"],
        rebaseToZero: bool,
    ) -> "TextgridTier":  # pragma: no cover
    def insertSpace(
        self,
        start: float,
        duration: float,
        collisionMode: Literal["stretch", "split", "no_change", "error"],
    ) -> "TextgridTier":  # pragma: no cover
    def deleteEntry(self, entry) -> None:  # pragma: no cover
    def validate(self, reportingMode) -> bool:  # pragma: no cover class PointTier(textgrid_tier.TextgridTier):
    def __init__(
        self,
        name: str,
        entryList: List[constants.Point],
        minT: Optional[float] = None,
        maxT: Optional[float] = None,
    ):
    def crop(
        self,
        cropStart: float,
        cropEnd: float,
        mode: Literal["strict", "lax", "truncated"] = "lax",
        rebaseToZero: bool = True,
    ) -> "PointTier":
    def deleteEntry(self, entry: constants.Point) -> None:
    def editTimestamps(
        self,
        offset: float,
        reportingMode: Literal["silence", "warning", "error"] = "warning",
    ) -> "PointTier":
    def getValuesAtPoints(
        self,
        dataTupleList: List[Tuple[float, ...]],
        fuzzyMatching: bool = False,
    ) -> List[Tuple[Any, ...]]:
    def eraseRegion(
        self,
        start: float,
        end: float,
        collisionMode: Literal["truncate", "categorical", "error"] = "error",
        doShrink: bool = True,
    ) -> "PointTier":
    def insertEntry(
        self,
        entry: constants.Point,
        collisionMode: Literal["replace", "merge", "error"] = "error",
        collisionReportingMode: Literal["silence", "warning"] = "warning",
    ) -> None:
    def insertSpace(
        self,
        start: float,
        duration: float,
        _collisionMode: Literal["stretch", "split", "no_change", "error"] = "error",
    ) -> "PointTier":
    def validate(
        self, reportingMode: Literal["silence", "warning", "error"] = "warning"
    ) -> bool: class IntervalTier(textgrid_tier.TextgridTier):
    def __init__(
        self,
        name: str,
        entryList: List[Interval],
        minT: Optional[float] = None,
        maxT: Optional[float] = None,
    ):
    def crop(
        self,
        cropStart: float,
        cropEnd: float,
        mode: Literal["strict", "lax", "truncated"],
        rebaseToZero: bool,
    ) -> "IntervalTier":
    def deleteEntry(self, entry: Interval) -> None:
    def difference(self, tier: "IntervalTier") -> "IntervalTier":
    def editTimestamps(
        self,
        offset: float,
        reportingMode: Literal["silence", "warning", "error"] = "warning",
    ) -> "IntervalTier":
    def eraseRegion(
        self,
        start: float,
        end: float,
        collisionMode: Literal["truncate", "categorical", "error"] = "error",
        doShrink: bool = True,
    ) -> "IntervalTier":
    def getValuesInIntervals(self, dataTupleList: List) -> List[Tuple[Interval, List]]:
    def getNonEntries(self) -> List[Interval]:
    def insertEntry(
        self,
        entry: Interval,
        collisionMode: Literal["replace", "merge", "error"] = "error",
        collisionReportingMode: Literal["silence", "warning"] = "warning",
    ) -> None:
    def insertSpace(
        self,
        start: float,
        duration: float,
        collisionMode: Literal["stretch", "split", "no_change", "error"],
    ) -> "IntervalTier":
    def intersection(self, tier: "IntervalTier") -> "IntervalTier":
    def morph(
        self,
        targetTier: "IntervalTier",
        filterFunc: Optional[Callable[[str], bool]] = None,
    ) -> "IntervalTier":
    def validate(
        self, reportingMode: Literal["silence", "warning", "error"] = "warning"
    ) -> bool: INTERVAL_TIER: Final = "IntervalTier"
POINT_TIER: Final = "TextTier"
MIN_INTERVAL_LENGTH: Final = 0.00000001  # Arbitrary threshold
    LONG_TEXTGRID: Final = "long_textgrid"
    SHORT_TEXTGRID: Final = "short_textgrid"
    JSON: Final = "json"
    POINT: Final = "PointProcess"
    PITCH: Final = "PitchTier"
    DURATION: Final = "DurationTier"
    STRICT: Final = "strict"
    LAX: Final = "lax"
    TRUNCATED: Final = "truncated"
    SILENCE: Final = "silence"
    WARNING: Final = "warning"
    ERROR: Final = "error"
    REPLACE: Final = "replace"
    MERGE: Final = "merge"
    ERROR: Final = "error"
    STRETCH: Final = "stretch"
    SPLIT: Final = "split"
    NO_CHANGE: Final = "no_change"
    ERROR: Final = "error"
    TRUNCATE: Final = "truncate"
    CATEGORICAL: Final = "categorical"
    ERROR: Final = "error"
    ERROR: Final = "error"
    RENAME: Final = "rename"
class Interval(namedtuple("Interval", ["start", "end", "label"])):
class Point(namedtuple("Point", ["time", "label"])):
class TextgridFormats:
class DataPointTypes:
class CropCollision:
class ErrorReportingMode:
class IntervalCollision:
class WhitespaceCollision:
class EraseCollision:
class DuplicateNames:
    def __eq__(self, other):
    def __ne__(self, other):
    def __eq__(self, other):
    def __ne__(self, other): class PraatioException(Exception):
class SafeZipException(PraatioException):
class FileNotFound(PraatioException):
class ParsingError(PraatioException):
class ArgumentError(PraatioException):
class UnexpectedError(PraatioException):
class WrongOption(PraatioException):
class TextgridException(PraatioException):
class DuplicateTierName(TextgridException):
class OutOfBounds(TextgridException):
class CollisionError(TextgridException):
class TimelessTextgridTierException(TextgridException):
class TextgridStateAutoModified(TextgridException):
class TextgridStateError(TextgridException):
class TierNameExistsError(TextgridException):
class IncompatibleTierError(TextgridException):
class PraatExecutionFailed(PraatioException):
class EndOfAudioData(PraatioException):
class FindZeroCrossingError(PraatioException):
class NormalizationException(PraatioException):
    def __init__(self, fullPath: str):
    def __str__(self):
    def __init__(self, argumentName: str, givenValue: str, availableOptions: List[str]):
    def __str__(self):
    def __str__(self):
    def __init__(self, tier):
    def __str__(self):
    def __init__(self, cmdList: List[str]):
    def __str__(self):
    def __init__(self, startTime: float, endTime: float):
    def __str__(self):
    def __str__(self): def numToStr(inputNum: float) -> str:
def isclose(a: float, b: float, rel_tol: float = 1e-14, abs_tol: float = 0.0) -> bool:
def filterTimeSeriesData(
    filterFunc: Callable[[List[float], int, bool], List[float]],
    featureTimeList: List[list],
    windowSize: int,
    index: int,
    useEdgePadding: bool,
) -> List[list]:
def znormalizeSpeakerData(
    featureTimeList: List[Tuple[float, ...]], index: int, filterZeroValues: bool
) -> List[Tuple[float, ...]]:
def medianFilter(dist: List[float], window: int, useEdgePadding: bool) -> List[float]:
def znormWindowFilter(
    dist: List[float], window: int, useEdgePadding: bool, filterZeroValues: bool
) -> List[float]:
    def znormalizeCenterVal(valList):
def _stepFilter(
    filterFunc, dist: List[float], window: int, useEdgePadding: bool
) -> List[float]:
def znormalizeData(valList: List[float]) -> List[float]:
def rms(intensityValues: List[float]) -> float: def reSearch(pattern, string, flags=None) -> Match[str]:
def _removeBlanks(tier: Dict) -> None:
    def hasContent(entry):
def _removeUltrashortIntervals(
    tier: Dict, minLength: float, minTimestamp: float
) -> None:
def _fillInBlanks(
    tier: Dict,
    blankLabel: str = "",
    minTime: Optional[float] = None,
    maxTime: Optional[float] = None,
) -> None:
def parseTextgridStr(data: str, includeEmptyIntervals: bool = False) -> Dict:
def getTextgridAsStr(
    tg: Dict,
    format: Literal["short_textgrid", "long_textgrid", "json"],
    includeBlankSpaces: bool,
    minTimestamp: Optional[float] = None,
    maxTimestamp: Optional[float] = None,
    minimumIntervalLength: float = MIN_INTERVAL_LENGTH,
) -> str:
def _sortEntries(tg: Dict) -> None:
def _prepTgForSaving(
    tg: Dict,
    includeBlankSpaces: Optional[bool],
    minTimestamp: Optional[float],
    maxTimestamp: Optional[float],
    minimumIntervalLength: float,
) -> Dict:
def _tgToShortTextForm(
    tg: Dict,
) -> str:
def _tgToLongTextForm(tg: Dict) -> str:
def _tgToJson(tgAsDict: Dict) -> str:
def _parseNormalTextgrid(data: str) -> Dict:
def _parseShortTextgrid(data: str) -> Dict:
def _fetchRow(
    dataStr: str, index: int, searchStr: Optional[str] = None
) -> Tuple[str, int]:
def _fetchTextRow(
    dataStr: str, index: int, searchStr: Optional[str] = None
) -> Tuple[str, int]: def reportNoop(_exception: Type[BaseException], _text: str) -> None:
def reportException(exception: Type[BaseException], text: str) -> NoReturn:
def reportWarning(_exception: Type[BaseException], text: str) -> None:
def getErrorReporter(reportingMode: Literal["silence", "warning", "error"]):
def checkIsUndershoot(time: float, referenceTime: float, errorReporter) -> bool:
def checkIsOvershoot(time: float, referenceTime: float, errorReporter) -> bool:
def validateOption(variableName, value, optionClass):
def intervalOverlapCheck(
    interval: Interval,
    cmprInterval: Interval,
    percentThreshold: float = 0,
    timeThreshold: float = 0,
    boundaryInclusive: bool = False,
) -> bool:
def getIntervalsInInterval(
    start: float,
    end: float,
    intervals: List[Interval],
    mode: Literal["strict", "lax", "truncated"],
) -> List[Interval]:
def escapeQuotes(text: str) -> str:
def strToIntOrFloat(inputStr: str) -> float:
def getValueAtTime(
    timestamp: float,
    sortedDataTupleList: List[Tuple[Any, ...]],
    fuzzyMatching: bool = False,
    startI: int = 0,
) -> Tuple[Tuple[Any, ...], int]:
def getValuesInInterval(dataTupleList: List, start: float, end: float) -> List:
def sign(x: float) -> int:
def invertIntervalList(
    inputList: List[Tuple[float, float]], minValue: float = None, maxValue: float = None
) -> List[Tuple[float, float]]:
def makeDir(path: str) -> None:
def findAll(txt: str, subStr: str) -> List[int]:
def runPraatScript(
    praatEXE: str, scriptFN: str, argList: List[Any], cwd: str = None
) -> None:
def safeZip(listOfLists: List[list], enforceLength: bool) -> Iterator[Any]:
def getWavDuration(wavFN: str) -> float:
import io
import copy
from typing import (
    List,
    Optional,
    Dict,
)
from typing_extensions import Literal
from praatio.utilities.constants import (
    TextgridFormats,
    MIN_INTERVAL_LENGTH,
    CropCollision,
)
from praatio.data_classes import textgrid_tier
from praatio.data_classes import point_tier
from praatio.data_classes import interval_tier
from praatio.utilities import constants
from praatio.utilities import errors
from praatio.utilities import my_math
from praatio.utilities import textgrid_io
from praatio.utilities import utils
            raise errors.ArgumentError(
                f"EraseRegion error: start time ({start}) must occur before end time ({end})"
            )

        diff = end - start

        maxTimestamp = self.maxTimestamp
        if doShrink is True:
            maxTimestamp -= diff

        newTG = Textgrid(self.minTimestamp, self.maxTimestamp)
        for name in self.tierNameList:
            tier = self.tierDict[name]
            tier = tier.eraseRegion(
                start, end, constants.EraseCollision.TRUNCATE, doShrink
            )
            newTG.addTier(tier)

        newTG.maxTimestamp = maxTimestamp

        return newTG

    def editTimestamps(
        self,
        offset: float,
        reportingMode: Literal["silence", "warning", "error"] = "warning",
    ) -> "Textgrid":
        """
        Modifies all timestamps by a constant amount

        Args:
            offset (float): the amount to offset in seconds
            reportingMode (str): one of "silence", "warning", or "error". This flag
                determines the behavior if there is a size difference between the
                maxTimestamp in the tier and the current textgrid.

        Returns:
            Textgrid: the modified version of the current textgrid
        """
        utils.validateOption(
            "reportingMode", reportingMode, constants.ErrorReportingMode
        )

        tg = Textgrid(self.minTimestamp, self.maxTimestamp)
        for tierName in self.tierNameList:
            tier = self.tierDict[tierName]
            if len(tier.entryList) > 0:
                tier = tier.editTimestamps(offset, reportingMode)

            tg.addTier(tier, reportingMode=reportingMode)

        return tg

    def insertSpace(
        self,
        start: float,
        duration: float,
        collisionMode: Literal["stretch", "split", "no_change", "error"] = "error",
    ) -> "Textgrid":
        """
        Inserts a blank region into a textgrid

        Every item that occurs after *start* will be pushed back by
        *duration* seconds

        Args:
            start (float):
            duration (float):
            collisionMode (str): Determines behavior in the event that an
                interval stradles the starting point.
                One of ['stretch', 'split', 'no change', None]
                - 'stretch' stretches the interval by /duration/ amount
                - 'split' splits the interval into two--everything to the
                    right of 'start' will be advanced by 'duration' seconds
                - 'no change' leaves the interval as is with no change
                - None or any other value throws an AssertionError

        Returns:
            Textgrid: the modified version of the current textgrid
        """
        utils.validateOption(
            "collisionMode", collisionMode, constants.WhitespaceCollision
        )

        newTG = Textgrid(self.minTimestamp, self.maxTimestamp)
        newTG.minTimestamp = self.minTimestamp
        newTG.maxTimestamp = self.maxTimestamp + duration

        for tierName in self.tierNameList:
            tier = self.tierDict[tierName]
            newTier = tier.insertSpace(start, duration, collisionMode)
            newTG.addTier(newTier)

        return newTG

    def mergeTiers(
        self, tierList: Optional[List[str]] = None, preserveOtherTiers: bool = True
    ) -> "Textgrid":
        """
        Combine tiers

        Args:
            tierList (list): A list of tier names to combine. If none, combine
                all tiers.
            preserveOtherTiers (bool): If false, uncombined tiers are not
                included in the output.

        Returns:
            Textgrid: the modified version of the current textgrid
        """
        if tierList is None:
            tierList = self.tierNameList

        # Determine the tiers to merge
        intervalTierNameList = []
        pointTierNameList = []
        for tierName in tierList:
            tier = self.tierDict[tierName]
            if isinstance(tier, interval_tier.IntervalTier):
                intervalTierNameList.append(tierName)

            elif isinstance(tier, point_tier.PointTier):