# Path: src/cutadapt/align.py
# START_WITHIN_SEQ1 = 1
# START_WITHIN_SEQ2 = 2
# STOP_WITHIN_SEQ1 = 4
# STOP_WITHIN_SEQ2 = 8
# SEMIGLOBAL = 15
#     REFERENCE_START = 1  # a prefix of the reference may be skipped at no cost
#     QUERY_START = 2  # a prefix of the query may be skipped at no cost
#     REFERENCE_END = 4  # a suffix of the reference may be skipeed at no cost
#     QUERY_STOP = 8  # a suffix of the query may be skipeed at no cost
#     SEMIGLOBAL = 15  # all of the above
# class EndSkip(IntFlag):
# def edit_distance(s: str, t: str) -> int:
# def hamming_sphere(s: str, k: int) -> Iterator[str]:
# def hamming_environment(s: str, k: int) -> Iterator[Tuple[str, int, int]]:
# def naive_edit_environment(s: str, k: int) -> Iterator[str]:
# def edit_environment(s: str, k: int) -> Iterator[Tuple[str, int, int]]:
# def slow_edit_environment(s: str, k: int) -> Iterator[Tuple[str, int, int]]:


import logging
from enum import IntFlag
from collections import defaultdict
from typing import Optional, Tuple, Sequence, Dict, Any, List, Union
from abc import ABC, abstractmethod
from .align import (
    EndSkip,
    Aligner,
    PrefixComparer,
    SuffixComparer,
    edit_environment,
    hamming_environment,
)
        if adapter.read_wildcards:
            raise ValueError("Wildcards in the read not supported")
        if adapter.adapter_wildcards:
            raise ValueError("Wildcards in the adapter not supported")
        k = int(len(adapter) * adapter.max_error_rate)
        if k > 2:
            raise ValueError("Error rate too high")

    @classmethod
    def is_acceptable(cls, adapter):
        """
        Return whether this adapter is acceptable for being used in an index

        Adapters are not acceptable if they allow wildcards, allow too many errors,
        or would lead to a very large index.
        """
        try:
            cls._accept(adapter)
        except ValueError:
            return False
        return True

    def _make_index(self) -> Tuple[List[int], "AdapterIndex"]:
        logger.info("Building index of %s adapters ...", len(self._adapters))
        index: Dict[str, Tuple[SingleAdapter, int, int]] = dict()
        lengths = set()
        has_warned = False
        for adapter in self._adapters:
            sequence = adapter.sequence
            k = int(adapter.max_error_rate * len(sequence))

# Path: src/cutadapt/align.py
# START_WITHIN_SEQ1 = 1
# START_WITHIN_SEQ2 = 2
# STOP_WITHIN_SEQ1 = 4
# STOP_WITHIN_SEQ2 = 8
# SEMIGLOBAL = 15
#     REFERENCE_START = 1  # a prefix of the reference may be skipped at no cost
#     QUERY_START = 2  # a prefix of the query may be skipped at no cost
#     REFERENCE_END = 4  # a suffix of the reference may be skipeed at no cost
#     QUERY_STOP = 8  # a suffix of the query may be skipeed at no cost
#     SEMIGLOBAL = 15  # all of the above
# class EndSkip(IntFlag):
# def edit_distance(s: str, t: str) -> int:
# def hamming_sphere(s: str, k: int) -> Iterator[str]:
# def hamming_environment(s: str, k: int) -> Iterator[Tuple[str, int, int]]:
# def naive_edit_environment(s: str, k: int) -> Iterator[str]:
# def edit_environment(s: str, k: int) -> Iterator[Tuple[str, int, int]]:
# def slow_edit_environment(s: str, k: int) -> Iterator[Tuple[str, int, int]]:


# Path: src/cutadapt/adapters.py
import logging
from enum import IntFlag
from collections import defaultdict
from typing import Optional, Tuple, Sequence, Dict, Any, List, Union
from abc import ABC, abstractmethod
from .align import (
    EndSkip,
    Aligner,
    PrefixComparer,
    SuffixComparer,
    edit_environment,
    hamming_environment,
)

        if adapter.read_wildcards:
            raise ValueError("Wildcards in the read not supported")
        if adapter.adapter_wildcards:
            raise ValueError("Wildcards in the adapter not supported")
        k = int(len(adapter) * adapter.max_error_rate)
        if k > 2:
            raise ValueError("Error rate too high")

    @classmethod
    def is_acceptable(cls, adapter):
        """
        Return whether this adapter is acceptable for being used in an index

        Adapters are not acceptable if they allow wildcards, allow too many errors,
        or would lead to a very large index.
        """
        try:
            cls._accept(adapter)
        except ValueError:
            return False
        return True

    def _make_index(self) -> Tuple[List[int], "AdapterIndex"]:
        logger.info("Building index of %s adapters ...", len(self._adapters))
        index: Dict[str, Tuple[SingleAdapter, int, int]] = dict()
        lengths = set()
        has_warned = False
        for adapter in self._adapters:
            sequence = adapter.sequence
            k = int(adapter.max_error_rate * len(sequence))

            environment = edit_environment if adapter.indels else hamming_environment