export function normalizeText(value) {
    return value.trim().replace(/\s+/g, ' ');
}
export function normalizeLabel(value) {
    return normalizeText(value).toLowerCase().replace(/[^a-z0-9._/-]+/g, '-').replace(/^-|-$/g, '');
}
export const TOKEN_CHARS = 4;
export function estimateTokens(value) {
    return Math.max(1, Math.ceil(value.length / TOKEN_CHARS));
}
export function uniqueStrings(values) {
    return [...new Set(values.map((value) => value.trim()).filter(Boolean))];
}
export function clamp(value, min, max) {
    return Math.min(max, Math.max(min, value));
}
export function metadataString(metadata, key) {
    const value = metadata?.[key];
    return typeof value === 'string' ? value : undefined;
}
export function sameSignal(left, right) {
    return normalizeLabel(left) === normalizeLabel(right);
}
export function sameSignals(left, right) {
    return (left ?? []).join('\0') === (right ?? []).join('\0');
}
export function truncate(value, maxChars) {
    if (value.length <= maxChars) {
        return value;
    }
    return `${value.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;
}
export function splitIntoChunks(content, maxTokens = 480) {
    const paragraphs = content.split(/\n{2,}/).map((paragraph) => paragraph.trim()).filter(Boolean);
    const chunks = [];
    let current = '';
    for (const paragraph of paragraphs.length > 0 ? paragraphs : [content]) {
        const next = current ? `${current}\n\n${paragraph}` : paragraph;
        if (estimateTokens(next) <= maxTokens) {
            current = next;
            continue;
        }
        if (current) {
            chunks.push(current);
            current = '';
        }
        if (estimateTokens(paragraph) <= maxTokens) {
            current = paragraph;
            continue;
        }
        const sentences = paragraph.match(/[^.!?]+[.!?]?/g) ?? [paragraph];
        for (const sentence of sentences) {
            const maybe = current ? `${current} ${sentence.trim()}` : sentence.trim();
            if (estimateTokens(maybe) > maxTokens && current) {
                chunks.push(current);
                current = sentence.trim();
            }
            else {
                current = maybe;
            }
        }
    }
    if (current) {
        chunks.push(current);
    }
    return chunks;
}
