//* Constants
const default_option = `<option value="" selected disabled>-- ${translateAndReplace('common_actions.select')} --</option>`;

//* Functions
  // Define tax_identifier format
    function defineMoralTaxIdFormat(input_id) {
        const $input = $(`#${input_id}`);
        const country = getCountrySettings();

        // Patrones por país
        const patterns = {
            // México (RFC)
            'MEX': {
                regex: '^([A-ZÑ&]{3,4})(\\d{2})(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])[A-Z0-9]{3}$',
                title: 'RFC válido (3 o 4 letras, fecha AAMMDD, 3 caracteres alfanuméricos finales)',
                max: 13, min: 12
            },
            // Estados Unidos (EIN)
            'USA': {
                regex: '^\\d{2}-\\d{7}$',
                title: 'EIN válido (formato: 12-3456789)',
                max: 10, min: 10
            },
            // Canadá (Business Number / BN)
            'CAN': {
                regex: '^\\d{9}$',
                title: 'Business Number canadiense (9 dígitos)',
                max: 9, min: 9
            },
            // Francia (SIREN/SIRET)
            'FRA': {
                regex: '^(\\d{9}|\\d{14})$',
                title: 'Identifiant SIREN (9 cifras) o SIRET (14 cifras)',
                max: 14, min: 9
            },
            // Italia (Codice Fiscale)
            'ITA': {
                regex: '^[A-Z]{6}[0-9]{2}[A-Z][0-9]{2}[A-Z][0-9]{3}[A-Z]$',
                title: 'Codice Fiscale (16 caracteres alfanuméricos)',
                max: 16, min: 16
            },
            // España (NIF/CIF)
            'ESP': {
                regex: '^[A-Z0-9]{8,9}$',
                title: 'NIF/CIF válido (8-9 caracteres alfanuméricos)',
                max: 9, min: 8
            },

            // América Central y el Caribe — identificador genérico (alfanumérico)
            'GTM': { regex: '^[A-Z0-9]{8,15}$', title: 'NIT válido (8-15 caracteres)', max: 15, min: 8 },
            'BLZ': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico (6-15 caracteres)', max: 15, min: 6 },
            'SLV': { regex: '^\\d{14}$', title: 'NIT salvadoreño (14 dígitos)', max: 14, min: 14 },
            'HND': { regex: '^\\d{14}$', title: 'RTN hondureño (14 dígitos)', max: 14, min: 14 },
            'NIC': { regex: '^\\d{14}$', title: 'RUC nicaragüense (14 dígitos)', max: 14, min: 14 },
            'CRI': { regex: '^\\d{9,12}$', title: 'Cédula jurídica/física costarricense (9-12 dígitos)', max: 12, min: 9 },
            'PAN': { regex: '^[A-Z0-9\\-]{8,20}$', title: 'RUC panameño (alfanumérico con guiones)', max: 20, min: 8 },

            // 🇨🇺 Caribe y otros países con sistemas diversos — formato flexible
            'BHS': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID (6-15 caracteres)', max: 15, min: 6 },
            'CUB': { regex: '^\\d{11}$', title: 'Código tributario cubano (11 dígitos)', max: 11, min: 11 },
            'JAM': { regex: '^\\d{9}$', title: 'TRN jamaiquino (9 dígitos)', max: 9, min: 9 },
            'HTI': { regex: '^\\d{10}$', title: 'NIF haitiano (10 dígitos)', max: 10, min: 10 },
            'DOM': { regex: '^\\d{9}$', title: 'RNC dominicano (9 dígitos)', max: 9, min: 9 },
            'KNA': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico', max: 15, min: 6 },
            'ATG': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico', max: 15, min: 6 },
            'DMA': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico', max: 15, min: 6 },
            'LCA': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico', max: 15, min: 6 },
            'VCT': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico', max: 15, min: 6 },
            'BRB': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico', max: 15, min: 6 },
            'TTO': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico', max: 15, min: 6 },
            'GRD': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico', max: 15, min: 6 },

            // 🇸🇦 Sudamérica
            'COL': { regex: '^\\d{9,10}$', title: 'NIT colombiano (9-10 dígitos)', max: 10, min: 9 },
            'VEN': { regex: '^[V,E,J,G,P]-\\d{8}-\\d$', title: 'RIF venezolano (V/E/J/G/P-XXXXXXXX-X)', max: 12, min: 12 },
            'GUY': { regex: '^[A-Z0-9]{6,15}$', title: 'TIN guyanés (6-15 caracteres)', max: 15, min: 6 },
            'SUR': { regex: '^[A-Z0-9]{6,15}$', title: 'Tax ID genérico', max: 15, min: 6 },
            'BRA': { regex: '^(\\d{11}|\\d{14})$', title: 'CPF (11 dígitos) o CNPJ (14 dígitos)', max: 14, min: 11 },
            'ECU': { regex: '^\\d{13}$', title: 'RUC ecuatoriano (13 dígitos)', max: 13, min: 13 },
            'PER': { regex: '^\\d{11}$', title: 'RUC peruano (11 dígitos)', max: 11, min: 11 },
            'BOL': { regex: '^\\d{7,12}$', title: 'NIT boliviano (7-12 dígitos)', max: 12, min: 7 },
            'CHL': { regex: '^\\d{7,8}-[0-9Kk]$', title: 'RUT chileno (7-8 dígitos + dígito verificador)', max: 10, min: 9 },
            'PRY': { regex: '^\\d{6,8}$', title: 'RUC paraguayo (6-8 dígitos)', max: 8, min: 6 },
            'URY': { regex: '^\\d{12}$', title: 'RUT uruguayo (12 dígitos)', max: 12, min: 12 },
            'ARG': { regex: '^\\d{11}$', title: 'CUIT argentino (11 dígitos)', max: 11, min: 11 },
        };

        // Si el país no está definido, usar un patrón genérico
        const cfg = patterns[country] || {
            regex: '^[A-Z0-9\\-]{6,20}$',
            title: 'Identificador fiscal (6-20 caracteres alfanuméricos)',
            max: 20, min: 6
        };

        // Aplicar restricciones al input dinámicamente
        $input.attr({
            'pattern': cfg.regex,
            'title': cfg.title,
            'maxlength': cfg.max,
            'minlength': cfg.min
        }).trigger('change');
    }

    function definePhysicalTaxIdFormat(input_id) {
        const $input = $(`#${input_id}`);
        const country = getCountrySettings();

        // Patrones por país - Personas Físicas (PF)
        const patterns = {
            // México (RFC PF: 13 caracteres)
            'MEX': {
                regex: '^[A-ZÑ&]{4}(\\d{2})(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])[A-Z0-9]{3}$',
                title: 'RFC persona física (4 letras, fecha AAMMDD, 3 alfanuméricos)',
                max: 13, min: 13
            },

            // Estados Unidos (SSN) - formato clásico; ITIN requiere reglas adicionales
            'USA': {
                regex: '^\\d{3}-\\d{2}-\\d{4}$',
                title: 'SSN (formato: 123-45-6789). Considera validaciones extra para ITIN.',
                max: 11, min: 11
            },

            // Canadá (SIN 9 dígitos) - ideal aplicar verificación Luhn en lógica adicional
            'CAN': {
                regex: '^\\d{9}$',
                title: 'SIN canadiense (9 dígitos; aplica verificación Luhn fuera del patrón)',
                max: 9, min: 9
            },

            // Francia (Numéro fiscal / NIF PF)
            'FRA': {
                regex: '^\\d{13}$',
                title: 'Numéro fiscal (PF) francés (13 dígitos)',
                max: 13, min: 13
            },

            // Italia (Codice Fiscale - PF)
            'ITA': {
                regex: '^[A-Z]{6}[0-9]{2}[A-Z][0-9]{2}[A-Z][0-9]{3}[A-Z]$',
                title: 'Codice Fiscale (PF) - 16 caracteres alfanuméricos',
                max: 16, min: 16
            },

            // España (NIF/NIE PF). Letra final A-HJ-NP-TV-Z; NIE empieza por X/Y/Z.
            'ESP': {
                regex: '^(\\d{8}[A-HJ-NP-TV-Z]|[XYZ]\\d{7}[A-HJ-NP-TV-Z])$',
                title: 'NIF (8 dígitos+letra) o NIE (X|Y|Z + 7 dígitos + letra)',
                max: 10, min: 9
            },

            // América Central y el Caribe — identificador genérico (alfanumérico)
            // Guatemala (NIT PF simplificado; en la práctica incluye DV y puede llevar guion)
            'GTM': {
                regex: '^\\d{7,10}(-\\d)?$',
                title: 'NIT guatemalteco (PF) con DV opcional (formato básico)',
                max: 12, min: 7
            },
            'BLZ': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },
            // El Salvador (NIT 14)
            'SLV': { regex: '^\\d{14}$', title: 'NIT salvadoreño (PF) - 14 dígitos', max: 14, min: 14 },
            // Honduras (RTN 14)
            'HND': { regex: '^\\d{14}$', title: 'RTN hondureño (PF) - 14 dígitos', max: 14, min: 14 },
            // Nicaragua (PF: cédula suele 14 con guiones; se usa simplificado)
            'NIC': {
                regex: '^\\d{14}$',
                title: 'Identidad/RUC (PF) nicaragüense (simplificado - 14 dígitos)',
                max: 14, min: 14
            },
            // Costa Rica (PF suele 9 dígitos)
            'CRI': {
                regex: '^\\d{9}$',
                title: 'Cédula física costarricense (9 dígitos)',
                max: 9, min: 9
            },
            // Panamá (PF muy variable - cédula/RUC con guiones y letras)
            'PAN': {
                regex: '^[A-Z0-9\\-]{8,20}$',
                title: 'Identificador PF panameño (formato flexible con guiones/letras)',
                max: 20, min: 8
            },

            // 🇨🇺 Caribe y otros países con sistemas diversos — formato flexible
            // Caribe (PF genéricos donde aplica)
            'BHS': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal PF (6-15 caracteres)', max: 15, min: 6 },
            'CUB': { regex: '^\\d{11}$', title: 'Carné de identidad cubano (11 dígitos)', max: 11, min: 11 },
            'JAM': { regex: '^\\d{9}$', title: 'TRN jamaiquino (PF) - 9 dígitos', max: 9, min: 9 },
            'HTI': { regex: '^\\d{10}$', title: 'NIF haitiano (PF) - 10 dígitos', max: 10, min: 10 },
            // Rep. Dominicana - PF: cédula 11 dígitos
            'DOM': { regex: '^\\d{11}$', title: 'Cédula dominicana (PF) - 11 dígitos', max: 11, min: 11 },
            'KNA': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },
            'ATG': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },
            'DMA': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },
            'LCA': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },
            'VCT': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },
            'BRB': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },
            'TTO': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },
            'GRD': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },

            // 🇸🇦 Sudamérica
            // Sudamérica
            'COL': {
                regex: '^\\d{9,10}$',
                title: 'NIT colombiano (PF con DV). Considera validar DV fuera del patrón.',
                max: 10, min: 9
            },
            'VEN': {
                regex: '^[VE]-\\d{8}-\\d$',
                title: 'RIF PF venezolano (V|E-XXXXXXXX-DV)',
                max: 12, min: 12
            },
            'GUY': { regex: '^[A-Z0-9]{6,15}$', title: 'TIN (PF) 6-15 caracteres', max: 15, min: 6 },
            'SUR': { regex: '^[A-Z0-9]{6,15}$', title: 'ID fiscal (PF) 6-15 caracteres', max: 15, min: 6 },
            'BRA': { regex: '^\\d{11}$', title: 'CPF brasileño (11 dígitos; valida DV fuera del patrón)', max: 11, min: 11 },
            // Ecuador PF: cédula 10 dígitos (RUC 13 para actividad económica)
            'ECU': { regex: '^\\d{10}$', title: 'Cédula ecuatoriana (PF) - 10 dígitos', max: 10, min: 10 },
            // Perú PF: DNI 8 dígitos (RUC 11 si tiene actividad)
            'PER': { regex: '^\\d{8}$', title: 'DNI peruano (PF) - 8 dígitos', max: 8, min: 8 },
            'BOL': { regex: '^\\d{7,12}$', title: 'NIT/CI boliviano (PF) - 7-12 dígitos (simplificado)', max: 12, min: 7 },
            'CHL': { regex: '^\\d{7,8}-[0-9Kk]$', title: 'RUT chileno (PF) con dígito verificador', max: 10, min: 9 },
            // Paraguay PF: cédula suele 6-8 (sin DV en este patrón simplificado)
            'PRY': { regex: '^\\d{6,8}$', title: 'Cédula paraguaya (PF) - 6-8 dígitos', max: 8, min: 6 },
            // Uruguay PF: cédula 7-8 dígitos (formato simplificado, sin DV)
            'URY': { regex: '^\\d{7,8}$', title: 'Cédula uruguaya (PF) - 7-8 dígitos', max: 8, min: 7 },
            // Argentina PF: CUIL 11 dígitos (formato CUIT/CUIL)
            'ARG': { regex: '^\\d{11}$', title: 'CUIL argentino (PF) - 11 dígitos', max: 11, min: 11 },
        };

        // Si el país no está definido, usar un patrón PF genérico
        const cfg = patterns[country] || {
            regex: '^[A-Z0-9\\-]{6,20}$',
            title: 'Identificador fiscal (PF) - 6-20 alfanuméricos',
            max: 20, min: 6
        };

        // Aplicar restricciones al input dinámicamente
        $input.attr({
            'pattern': cfg.regex,
            'title': cfg.title,
            'maxlength': cfg.max,
            'minlength': cfg.min
        }).trigger('change');
    }

  // Define zip_code format
    function definePostalCodeFormat(input_id, forced_country = null) {
        const $zip = $(`#${input_id}`);
        const country = forced_country || getCountrySettings();

        // Patrones por país (ZIP/Postal Code)
        const zipPatterns = {
            // Norteamérica y Europa
            'MEX': { regex: '^\\d{5}$', title: 'Código Postal de México (5 dígitos)', min: 5, max: 5 },
            'USA': { regex: '^\\d{5}(-\\d{4})?$', title: 'ZIP de EE. UU. (12345 o 12345-6789)', min: 5, max: 10 },
            'CAN': {
            // Letras permitidas: sin D,F,I,O,Q,U
            regex: '^[ABCEGHJ-NPRSTVXY]\\d[ABCEGHJ-NPRSTV-Z][ ]?\\d[ABCEGHJ-NPRSTV-Z]\\d$',
            title: 'Código postal de Canadá (A1A 1A1, espacio opcional)',
            min: 6, max: 7
            },
            'FRA': { regex: '^\\d{5}$', title: 'Code postal de Francia (5 chiffres)', min: 5, max: 5 },
            'ITA': { regex: '^\\d{5}$', title: 'CAP de Italia (5 cifre)', min: 5, max: 5 },
            'ESP': {
            // Provincias 01-52; aceptamos 5 dígitos para simplificar
            regex: '^\\d{5}$',
            title: 'Código postal de España (5 dígitos)',
            min: 5, max: 5
            },

            // Centroamérica
            'GTM': { regex: '^\\d{5}$', title: 'Guatemala (5 dígitos)', min: 5, max: 5 },
            'SLV': { regex: '^\\d{4}$', title: 'El Salvador (4 dígitos)', min: 4, max: 4 },
            'HND': { regex: '^\\d{5}$', title: 'Honduras (5 dígitos)', min: 5, max: 5 },
            'NIC': { regex: '^\\d{5}$', title: 'Nicaragua (5 dígitos)', min: 5, max: 5 },
            'CRI': { regex: '^\\d{5}$', title: 'Costa Rica (5 dígitos)', min: 5, max: 5 },
            'PAN': { regex: '^\\d{4,6}$', title: 'Panamá (4-6 dígitos)', min: 4, max: 6 },
            'BLZ': {
            // Belice no usa códigos postales a nivel nacional
            regex: '^(?:N\\/A|NA|[A-Z0-9\\- ]{3,10})$',
            title: 'Belice: no estándar nacional (usa N/A o un identificador acordado)',
            min: 3, max: 10
            },

            // Caribe
            'CUB': { regex: '^\\d{5}$', title: 'Cuba (5 dígitos)', min: 5, max: 5 },
            'JAM': {
            // Jamaica descontinuó su esquema; se usa formato flexible
            regex: '^(?:N\\/A|NA|[A-Z0-9\\- ]{3,10})$',
            title: 'Jamaica: no estándar nacional (usa N/A o formato acordado)',
            min: 3, max: 10
            },
            'HTI': { regex: '^(?:HT)?\\d{4}$', title: 'Haití (HTdddd o 4 dígitos)', min: 4, max: 6 },
            'DOM': { regex: '^\\d{5}$', title: 'República Dominicana (5 dígitos)', min: 5, max: 5 },

            // Estados del Caribe con sistemas diversos (flexible)
            'BHS': { regex: '^[A-Z0-9\\- ]{3,10}$', title: 'Código postal (formato flexible 3-10)', min: 3, max: 10 },
            'KNA': { regex: '^[A-Z0-9\\- ]{3,10}$', title: 'Código postal (formato flexible 3-10)', min: 3, max: 10 },
            'ATG': { regex: '^[A-Z0-9\\- ]{3,10}$', title: 'Código postal (formato flexible 3-10)', min: 3, max: 10 },
            'DMA': { regex: '^[A-Z0-9\\- ]{3,10}$', title: 'Código postal (formato flexible 3-10)', min: 3, max: 10 },
            'LCA': { regex: '^[A-Z0-9\\- ]{3,10}$', title: 'Código postal (formato flexible 3-10)', min: 3, max: 10 },
            'VCT': { regex: '^[A-Z0-9\\- ]{3,10}$', title: 'Código postal (formato flexible 3-10)', min: 3, max: 10 },
            'BRB': {
            // Barbados: a menudo “BB12345”; aceptamos BB + 5 dígitos o flexible
            regex: '^(?:BB\\d{5}|[A-Z0-9\\- ]{3,10})$',
            title: 'Barbados (BB12345) o flexible 3-10',
            min: 3, max: 7
            },
            'TTO': {
            // Trinidad y Tobago maneja códigos de 6 dígitos (p.ej. 110102)
            regex: '^\\d{6}$',
            title: 'Trinidad y Tobago (6 dígitos)',
            min: 6, max: 6
            },
            'GRD': { regex: '^[A-Z0-9\\- ]{3,10}$', title: 'Código postal (formato flexible 3-10)', min: 3, max: 10 },

            // Sudamérica
            'COL': { regex: '^\\d{6}$', title: 'Colombia (6 dígitos)', min: 6, max: 6 },
            'VEN': { regex: '^\\d{4}$', title: 'Venezuela (4 dígitos)', min: 4, max: 4 },
            'GUY': { regex: '^[A-Z0-9\\- ]{3,10}$', title: 'Guyana (no estándar nacional; 3-10)', min: 3, max: 10 },
            'SUR': { regex: '^[A-Z0-9\\- ]{3,10}$', title: 'Surinam (no estándar nacional; 3-10)', min: 3, max: 10 },
            'BRA': { regex: '^\\d{5}-?\\d{3}$', title: 'Brasil (CEP 12345-678 o 12345678)', min: 8, max: 9 },
            'ECU': { regex: '^\\d{6}$', title: 'Ecuador (6 dígitos)', min: 6, max: 6 },
            'PER': { regex: '^\\d{5}$', title: 'Perú (5 dígitos)', min: 5, max: 5 },
            'BOL': { regex: '^\\d{4}$', title: 'Bolivia (4 dígitos)', min: 4, max: 4 },
            'CHL': {
            // Chile: 7 dígitos o formato 3-4
            regex: '^(?:\\d{7}|\\d{3}-\\d{4})$',
            title: 'Chile (ddddddd o ddd-dddd)',
            min: 7, max: 8
            },
            'PRY': { regex: '^\\d{4}$', title: 'Paraguay (4 dígitos)', min: 4, max: 4 },
            'URY': { regex: '^\\d{5}$', title: 'Uruguay (5 dígitos)', min: 5, max: 5 },
            'ARG': {
            // Argentina: CPA “A1234AAA” o antiguo “1234”
            regex: '^(?:[A-Z]\\d{4}[A-Z]{3}|\\d{4})$',
            title: 'Argentina (CPA A1234AAA o 1234)',
            min: 4, max: 8
            },
        };

        // Si el país no está en la lista, usar un patrón genérico (alfanumérico 3-10)
        const cfg = zipPatterns[country] || {
            regex: '^[A-Z0-9\\- ]{3,10}$',
            title: 'Código postal (3-10 caracteres alfanuméricos)',
            min: 3, max: 10
        };

        // Aplicar restricciones al input
        $zip.attr({
            'pattern': cfg.regex,
            'title': cfg.title,
            'maxlength': cfg.max,
            'minlength': cfg.min,
            // Sugerencias de teclado
            'inputmode': (/^[\^]?\\d/.test(cfg.regex) ? 'numeric' : 'text')
        });

    }

  // Define TaxSystems through TaxPerson type
    function defineMoralTaxSystems(input_id) {
        const $input = $(`#${input_id}`);
        let options = default_option;

        window.moral_tax_systems.forEach(ts => {
            options += `
                <option value="${ts.item_key}">
                    ${ts.item_key} - ${trimText(ts.label, 31)}
                </option>
            `
        });
        $input.html(options);

        return;
    }

    function definePhysicalTaxSystems(input_id) {
        const $input = $(`#${input_id}`);
        let options = default_option;

        window.physical_tax_systems.forEach(ts => {
            options += `
                <option value="${ts.item_key}">
                    ${ts.item_key} - ${trimText(ts.label, 31)}
                </option>
            `
        });
        $input.html(options);

        return;
    }

  // Define CfdiUses through TaxPerson type
    function defineMoralCfdiUses(input_id) {
        const $input = $(`#${input_id}`);
        let options = default_option;

        window.moral_cfdi_uses.forEach(cu => {
            options += `
                <option value="${cu.item_key}">
                    ${cu.item_key} - ${trimText(cu.label, 31)}
                </option>
            `
        });
        $input.html(options);

        return;
    }

    function definePhysicalCfdiUses(input_id) {
        const $input = $(`#${input_id}`);
        let options = default_option;

        window.physical_cfdi_uses.forEach(cu => {
            options += `
                <option value="${cu.item_key}">
                    ${cu.item_key} - ${trimText(cu.label, 31)}
                </option>
            `
        });
        $input.html(options);

        return;
    }

//* Request Functions
  // Dynamic Tax Address
    async function getDynamicTaxAddress(zip_request){
        try{
            const response = await $.ajax({
                url: `/postalia/${zip_request}`,
                method: 'GET',
            });

            return response;
        } catch(error) {
            throw error.responseJSON;
        }
    }

//* Support Functions
  // Text Transform
    function trimText(text = "", limit = 25) {
        const chars = Array.from(text);
        return chars.length > limit ? chars.slice(0, limit).join('') + '…' : text;
    }
