/**
 * Función para dar formato numérico.
 * @ Retorna una variable de tipo texto o un arreglo con valores de tipo texto.
 */
export function formatoNumerico(parametroFormatear, cantidadDecimales = 0) {

  const formatear = (valorFormatear) => {

    const numero =
      typeof valorFormatear === 'string'
        ? parseFloat(valorFormatear.replaceAll(',', ''))
        : Number(valorFormatear) ?? 0
    ;

    return numero.toLocaleString('es-419', {
      minimumFractionDigits: cantidadDecimales
    })

  };

  const parametroFormateado =
    Array.isArray(parametroFormatear)
      ? parametroFormatear
          .map(
            (valorFormatear) => formatear(valorFormatear)
          )
      : formatear(parametroFormatear);

  return parametroFormateado;
}

/**
 * Función para verificar si el parámetro enviado es una variable o un arreglo de índice único.
 * @ Retorna una variable de tipo booleano
 */
export function variableArregloIndiceUnico(parametroVerificar) {

  const
    arregloIndiceUnico = (
      Array.isArray(parametroVerificar) &&
      parametroVerificar.length === 1
    ),
    variable = (
      !Array.isArray(parametroVerificar) ||
      typeof parametroVerificar === 'string' ||
      typeof parametroVerificar === 'number'
    );

  return (
    arregloIndiceUnico || variable
  )

}

/**
 * Función para singularizar palabras en español.
 * @ Retorna una variable de tipo texto.
 */
export function singularizarPalabra(palabra) {

  // manejar excepciones
  if (palabra === 'autos') {
    return 'auto';
  }
  if (palabra === 'pies') {
    return 'pie';
  }
  
  // reglas generales
  if (palabra.endsWith('es')) {
    if (palabra.endsWith('ces')) {
      return palabra.slice(0, -3) + 'z';
    }
    if (palabra.endsWith('ses')) {
      return palabra.slice(0, -2);
    }
    if (palabra.endsWith('shes')) {
      return palabra.slice(0, -2);
    }
    if (palabra.endsWith('jes')) {
      return palabra.slice(0, -1);
    }
    if (palabra.endsWith('gues')) {
      return palabra.slice(0, -2);
    }
    if (palabra.endsWith('ques')) {
      return palabra.slice(0, -1);
    }
    if (palabra.endsWith('ues')) {
      return palabra.slice(0, -2) + 'e';
    }
    return palabra.slice(0, -2);
  }
  if (palabra.endsWith('s')) {
    if (palabra.endsWith('rs')) {
      return palabra.slice(0, -1);
    }
    if (palabra.endsWith('ns')) {
      return palabra.slice(0, -1);
    }
    if (palabra.endsWith('ss')) {
      return palabra.slice(0, -1);
    }
    if (palabra.endsWith('us')) {
      return palabra.slice(0, -2) + 'o';
    }
    return palabra.slice(0, -1);
  }
  if (palabra.endsWith('a')) {
    return palabra.slice(0, -1);
  }
  if (palabra.endsWith('z')) {
    return palabra.slice(0, -1);
  }
  if (palabra.endsWith('ión')) {
    return palabra.slice(0, -3);
  }
  if (palabra.endsWith('dad')) {
    return palabra.slice(0, -3);
  }
  if (palabra.endsWith('tud')) {
    return palabra.slice(0, -3);
  }
  if (palabra.endsWith('eza')) {
    return palabra.slice(0, -3);
  }
  if (palabra.endsWith('ie')) {
    return palabra.slice(0, -2) + 'z';
  }
  if (palabra.endsWith('nte')) {
    return palabra.slice(0, -3);
  }

  return palabra;

}

/**
 * Función para pluralizar palabras en español.
 * @ Retorna una variable de tipo texto.
 */
export function pluralizarPalabra(palabra) {

  // ! Declaración de variables
  let
    palabraPluralizada = null,
    ultimaLetra = null,
    penultimaLetra = null,
    antepenultimaLetra = null,
    trasantepenultimaLetra = null,
    letraAntesY = null,
    letraAntesZ = null;

  // ! Asignando valores
  ultimaLetra = palabra.slice(-1),
  penultimaLetra = palabra.slice(-2),
  antepenultimaLetra = palabra.slice(-3),
  trasantepenultimaLetra = palabra.slice(-4);

  // !
  if (
    ultimaLetra === "a" ||
    ultimaLetra === "e" ||
    ultimaLetra === "i" ||
    ultimaLetra === "o" ||
    ultimaLetra === "u"
  ) {

    // + Asignando valor
    palabraPluralizada = palabra + "s"

  }
  // !
  else if (ultimaLetra === "y") {

    // +
    if (
      penultimaLetra === "ay" ||
      penultimaLetra === "ey" ||
      penultimaLetra === "oy" ||
      penultimaLetra === "uy"
    ) {

      // ? Asignando valor
      palabraPluralizada = palabra + "s"

    }
    // +
    else {

      // ? Asignando valor
      letraAntesY = palabra.slice(0, -1);

      // ? Asignando valor
      palabraPluralizada = letraAntesY + "ies"

    }

  }
  // !
  else if (ultimaLetra === "z") {

    // + Asignando valor
    letraAntesZ = palabra.slice(0, -1);

    // + Asignando valor
    palabraPluralizada = letraAntesZ + "ces"

  }
  // !
  else if (
      ultimaLetra === "n" && (
        antepenultimaLetra === "ión" ||
        trasantepenultimaLetra === "ción"
  )) {

    // + Asignando valor
    palabraPluralizada = palabra

  }
  // !
  else {

    // + Asignando valor
    palabraPluralizada = palabra + "es"

  }

  return palabraPluralizada

}

/**
 * Función para capitalizar solamente la primera letra de palabras en un texto.
 * @ Retorna una variable de tipo texto.
 */
export function capitalizarLetra(texto, delimitador) {

  // Divide la cadena en palabras usando el delimitador especificado o el espacio por defecto
  var palabras = texto.split(delimitador || ' ');
  var resultado = [];

  palabras.forEach(palabra => {

    // Capitaliza la primera letra de cada palabra y convierte el resto de las letras en minúsculas
    resultado.push(palabra.charAt(0).toUpperCase() + palabra.slice(1).toLowerCase())

  });

  // Vuelve a unir las palabras usando el delimitador especificado o el espacio por defecto
  return resultado.join(delimitador || ' '); 

}

/**
 * Función para pluralizar frases en español.
 * @ Retorna una variable de tipo texto.
 */
export function pluralizarFrase(frase, delimitador = '_') {

  // Separar las palabras de la frase en un array
  const palabras = frase.split(delimitador);

  // Pluralizar cada palabra del array utilizando la función pluralizarPalabra
  const palabrasPluralizadas = palabras.map(palabra => pluralizarPalabra(palabra));

  // Unir las palabras del array en una frase nuevamente
  const frasePluralizada = palabrasPluralizadas.join(delimitador);

  return frasePluralizada;

}

/**
 * Función para extraer valores numéricos de un texto.
 * @ Retorna una variable de tipo texto.
 */
export function extraerNumerosTexto(valorExtraer) {

  return valorExtraer.replace(/[^\d.-]/g, "")

}

/**
 * Función para remover los diacríticos de un texto.
 * @ Retorna una variable de tipo texto.
 */
export function removerDiacriticosTexto(texto) {

  return texto.normalize('NFD').replace(/[\u0300-\u036f]/g, "")

}

/**
 * Función para enviar una petición con notificación de validación por defecto.
 * @ Retorna una petición.
 */
export function peticion ({
  ruta = '',
  tipo = 'GET',
  asincrona = true,
  parametros = {},
  funcion = {
    antesEnviarPeticion: null,
    peticionExitosa: null,
    peticionNoExitosa: null,
    peticionCompletada: null
  }
}) {

  // !
  funcion.antesEnviarPeticion = (!!funcion.antesEnviarPeticion)
    ? funcion.antesEnviarPeticion
    : function(peticion, configuracion) {}
  ;

  // !
  funcion.peticionExitosa = (!!funcion.peticionExitosa)
    ? funcion.peticionExitosa
    : function(respuesta, estado, peticion) {}
  ;

  // !
  funcion.peticionNoExitosa = (!!funcion.peticionNoExitosa)
    ? funcion.peticionNoExitosa
    : function(peticion, configuracion) {}
  ;

  // !
  funcion.peticionCompletada = (!!funcion.peticionCompletada)
    ? funcion.peticionCompletada
    : function(peticion, estado) {

      // + Declaración de variables
      const formulario = {

          // ? Formulario de la petición
          elemento: $(`form[action="${this.url}"]`),

          // ? Campo deshabilitado del formulario
          // ? Campo invalido del formulario
          // ? Campo invalido de la petición del formulario
          campo: {
            deshabilitar: $(`.campoDeshabilitar`),
            invalido: $(`.is-invalid`),
            elemento: peticion.responseJSON
              ? $(`[name="${peticion.responseJSON[0]?.campo}"]`)
              : null
          }

      };

      // + Deshabilitando los campos que deben estar
      // + deshabilitados por la clase '.campoDeshabilitar'
      $(formulario.campo.deshabilitar)
        .removeClass('campoDeshabilitar')
        .prop('disabled', true)
      ;

      // + Condición cortocircuito para identificar
      // + si en el formulario que envió la petición
      // + contiene campos inválidos y si es así
      // + entonces se restablecerán
      $(formulario.campo.invalido)
        .removeClass('is-invalid')
      ;

      // + Condición cortocircuito para identificar
      // + si la petición retorno en la respuesta
      // + de tipo JSON un campo a validar y si es
      // + así entonces se encofará en ese campo, y
      // + se le añadirá una clase '.is-invalid'
      !!peticion.responseJSON &&
        !!peticion.responseJSON[0]?.campo &&
          $(formulario.campo.elemento)
            .addClass('is-invalid')
            // .focus()
      ;

      // + Método para retornar la notificación
      // + que retorno la petición con respuesta
      // + de tipo JSON
      !!peticion.responseJSON &&
        peticion?.responseJSON[0]?.mensaje &&
        $('.modal-body p', ventanaDialogoAlerta)
          .text(peticion.responseJSON[0].mensaje) &&
        $('.modal-header', ventanaDialogoAlerta)
          .removeClass(
            peticion.status === 200 ? 'bg-danger' : 'bg-success'
          )
          .addClass(
            peticion.status === 200 ? 'bg-success' : 'bg-danger'
          ) &&
        $(ventanaDialogoAlerta).modal('show')
      ;

      // + Condición cortocircuito para identificar si el formulario
      // + de la petición que se encuentra en la ventana del dialogo
      // + no contiene campos inválidos con la clase '.is-invalid' y si
      // + es así, entonces se cierra la ventana del dialogo
      peticion.status === 200 &&
        $('.modal')
          .has(formulario.elemento)
          .modal('hide')
      ;

      // +
      document.cookie.includes('Consulta') &&
      Toastify({

        text: decodeURIComponent(
          document
          .cookie
          .replace(
            /(?:(?:^|.*;\s*)Consulta\s*\=\s*([^;]*).*$)|^.*$/, "$1"
          )
        ).replace(/\s+/g, ' '),
        duration: -1,
        close: true,
        gravity: 'bottom',
        position: 'left',
        style: {

          'max-width': '100%',
          padding: '5px',
          background: 'var(--bs-dark)',
          border: '5px solid var(--bs-danger)'

        },
        onClick: function() {

          $('<textarea>')
            .attr('id', 'consultaSQL')
            .val(this.text)
            .appendTo('body')
          ;

          $('textarea#consultaSQL')[0]
            .select();

          document.execCommand('copy') &&
            Toastify({

              text: '¡Consulta copiada con éxito!',
              duration: 3000,
              close: true,
              position: 'left',
              style: {

                background: 'var(--bs-success)'

              }

            }).showToast()
          ;

          $('textarea#consultaSQL').remove()

        }

      }).showToast();

    }
  ;

  // !
  return $.ajax({

    // + Enlace de la petición
    url: ruta,

    // + Tipo de petición
    type: tipo,

    // +
    async: asincrona,

    // + Parámetros a enviar a la petición
    data: parametros,

    // + Tipo de retorno de datos
    // + de la petición
    dataType: 'JSON',

    // + Función a ejecutar antes
    // + de realizar la petición
    beforeSend: funcion.antesEnviarPeticion,

    // + Función a ejecutar cuando la
    // + petición sea éxitosa
    success: funcion.peticionExitosa,

    // + Función a ejecutar cuando la
    // + petición no sea éxitosa
    error: funcion.peticionNoExitosa,

    // + Función a ejecutar cuando la
    // + petición termine
    complete: funcion.peticionCompletada

  })

}

/**
 * Función inicializar la tabla de registros con la librería 'DataTable'
 * @ Retorna un objeto de 'DataTable'.
 */
export function tablaRegistros({
  tabla = $('#tablaRegistros'),
  columnas = [],
  datos = null,
  configuracion = {},
  peticion = {
    columnas: {
      ruta: null,
      parametros: null
    },
    datos: {
      ruta: null,
      tipo: 'GET',
      parametros: null,
      procesarRespuesta: null,
    }
  }
}) {

  // !
  var
    columna = {
      sumar: {
        indices: [],
        columnas: []
      },
      agrupar: {
        indice: null,
        grupo: null,
        filaPie: $('<tr/>')
      }
    }
  ;

  // !
  !peticion.columnas && (
    peticion.columnas = {
      ruta: null,
      parametros: null
  });

  // !
  !peticion.datos && (
    peticion.datos = {
      ruta: null,
      parametros: null
  });

  // !
  peticion.datos.ruta && (
    configuracion.ajax = {

      url: peticion.datos.ruta,

      type: peticion.datos.tipo,

      data: peticion.datos.parametros,

      dataSrc: peticion.datos.procesarRespuesta ?? '',

      dataType: 'JSON',

      beforeSend: function(peticion, configuracion) {},

      // success: function(respuesta, estado, peticion) {},

      error: function(peticion, configuracion) {},

      complete: function(peticion, estado) {

        // + Método para retornar la notificación
        // + que retorno la petición con respuesta
        // + de tipo JSON
        !!peticion.responseJSON &&
          peticion?.responseJSON[0]?.mensaje &&
          $('.modal-body p', ventanaDialogoAlerta)
            .text(peticion.responseJSON[0].mensaje) &&
          $('.modal-header', ventanaDialogoAlerta)
            .removeClass(
              peticion.status === 200 ? 'bg-danger' : 'bg-success'
            )
            .addClass(
              peticion.status === 200 ? 'bg-success' : 'bg-danger'
            ) &&
          $(ventanaDialogoAlerta).modal('show')
        ;

        // +
        document.cookie.includes('Consulta') &&
          Toastify({

            text: decodeURIComponent(
              document
              .cookie
              .replace(
                /(?:(?:^|.*;\s*)Consulta\s*\=\s*([^;]*).*$)|^.*$/, "$1"
              )
            ).replace(/\s+/g, ' '),
            duration: -1,
            close: true,
            gravity: 'bottom',
            position: 'left',
            style: {

              'max-width': '100%',
              padding: '5px',
              background: 'var(--bs-dark)',
              border: '5px solid var(--bs-danger)'

            },
            onClick: function() {

              $('<textarea>')
                .attr('id', 'consultaSQL')
                .val(this.text)
                .appendTo('body')
              ;

              $('textarea#consultaSQL')[0]
                .select();

              document.execCommand('copy') &&
                Toastify({

                  text: '¡Consulta copiada con éxito!',
                  duration: 3000,
                  close: true,
                  position: 'left',
                  style: {

                    background: 'var(--bs-success)'

                  }

                }).showToast()
              ;

              $('textarea#consultaSQL').remove()

            }

          }).showToast();
      
      }

  });

  // ! Petición
  $.ajax({

    url: peticion.columnas.ruta,

    data: peticion.columnas.parametros,

    dataType: 'JSON',

    beforeSend: function(peticion, configuracion) {},

    success: function(respuesta, estado, peticion) {

      // ?
      respuesta.forEach((registro, iteracion) => {

        switch (registro.tipo) {

          case 'entero': registro.tipo = 'num'; break;

          case 'decimal': registro.tipo = 'num-fmt'; break;

          case 'fecha': registro.tipo = 'date'; break;

          default: registro.tipo = 'string'; break;

        }

        registro.visible = (registro.visible * 1)
          ? ''
          : 'd-none'
        ;

        switch (registro.alineacion) {

          case 'izquierda': registro.alineacion = 'text-start'; break;

          case 'centro': registro.alineacion = 'text-center'; break;

          case 'derecha': registro.alineacion = 'text-end'; break;

          default: registro.alineacion = ''; break;

        }

        registro.negrita = (registro.negrita * 1)
          ? 'fw-bold'
          : 'fw-normal'
        ;

        registro.sumar = (registro.sumar * 1)
          ? 'sumar'
          : ''
        ;

        registro.agrupar = (registro.agrupar * 1)
          ? 'agrupar'
          : ''
        ;

        if (registro.sumar) {

          columna.sumar.indices.push(iteracion);
          columna.sumar.columnas.push(registro.columna)

        }

        if (registro.agrupar) {

          columna.agrupar.indice = iteracion;
          columna.agrupar.grupo = registro.columna

        }

        columna.agrupar.filaPie.append(`
          <td class="${registro.visible} fw-bold text-decoration-underline"></td>
        `);

        columnas.push({

          title: registro.titulo,

          // Funciona para especificar el nombre de
          // la columna, es necesario para las operaciones
          // de ordenamiento y búsqueda.
          name: registro.columna,

          // Funciona para especificar de dónde
          // se tomarán los datos para esa columna
          // ya sea por índice o nombre de la columna
          // que tendrá en los datos
          data: registro.columna,

          className: `${registro.visible} ${registro.alineacion} ${registro.negrita} ${registro.sumar} ${registro.agrupar}`,
          orderable: !!Number(registro.ordenable),

          // Funciona para especificar por cuál columna
          // se ordenara al presionar los ordenes descendentes
          // o ascendentes
          // {} orderData: '',

          // Funciona para especificar el tipo de datos utilizado
          // para la ordenación de una columna, para especificar
          // que tipo de función de ordenación utilizar para ordenar
          // los datos
          // (dom-checkbox, html, currency, date, numeric, percent, string)
          // {} orderDataType: '',

          searchable: !!Number(registro.buscable),

          // Funciona para especificar el tipo de datos que se espera
          // en una columna determinada, para determinar cómo ordenar y
          // buscar en la columna
          // (date, num, num-fmt, html-num, html-num-fmt, html, string)
          // type: registro.tipo,

          // Funciona para especificar el formato con el cuál los datos
          // de tipo fecha serán interpretados (funciona en conjunto de 'type: date')
          // {} dateFormat: 'dd/mm/yyyy'

          // visible: !!Number(registro.visible),
          // {} width: '',

          // Funciona para determinar el tipo de elemento HTML que se va a utilizar
          // para representar la celda en la tabla. Por defecto, se utiliza 'td'
          // {} cellType: '',

          // Funciona para especificar un valor por defecto si la celda viene vacía
          // {} defaultContent: '',

          // Funciona para manipular el valor real de la celda
          // para afectar su comportamiento en la tabla
          render: function(datoCelda, tipoRenderizado, datosFila) {

            if (tipoRenderizado === 'display')
              switch (registro.tipo) {

                case 'num-fmt':
                  datoCelda = formatoNumerico(datoCelda, 2)
                break;

                case 'date':
                  datoCelda.split(' ').length > 1 && (
                    datoCelda =
                      new Date(datoCelda)
                        .toLocaleDateString('uk')
                        .replaceAll('.', '/')
                  )
                break;

                case 'input':
                  datoCelda = `
                    <input
                      class="form-control"
                      value="${datoCelda}"
                    >
                  `
                break;

                case 'checkbox':
                  datoCelda = `
                    <input
                      type="checkbox"
                      class="form-check-input"
                      ${datoCelda * 1 ? 'checked' : ''}
                    >
                  `
                break;

              }
            else
              switch (registro.tipo) {

                case 'string':
                break;

                default:
                  datoCelda *= 1
                break;

              }

            return datoCelda

          },

          // Funciona para crear una celda personalizada
          createdCell: function(celda, valorCelda, datosFila, fila, columna) {

            registro.columna === 'numero_factura' ||
            registro.columna === 'id_suplidor'
              $(celda).addClass(registro.columna)

          },

          // Funciona para especificar cómo los datos de la columna serán tratados
          // para el ordenamiento. Por defecto, se utilizará la propiedad 'type'
          // (string, numeric, num-fmt, html, date, date-dd-mm-yyyy, currency, percent)
          // {} sortDataType: '',

          // Funciona para definir el tipo de datos que se utilizará para realizar la
          // búsqueda en la columna. Por defecto, se utilizará la propiedad 'orderDataType'
          // (numeric, string, date, html) si no se especifica, se utilizará el valor de 'type'
          // {} searchDataType: '',

          // Funciona para indicar si se deben filtrar valores duplicados en la columna.
          // Por defecto 'false'
          // {} unique: false

        });

        $('tfoot tr', tabla).append(`<th>&nbsp;</th>`)

      })

    },

    error: function(peticion, configuracion) {},

    complete: function(peticion, estado) {

      tabla.is('.dataTable') &&
        tabla.DataTable().destroy() &&
        tabla
          .find('thead tr, tbody, tfoot tr')
          .children()
          .remove()
      ;

      $('thead th[columna]', tabla).map(function(indice, elemento) {

        indice === 0 && (
          columnas = []
        );

        columnas.push({
          name: elemento.getAttribute('columna'),
          data: elemento.getAttribute('columna'),
          className: elemento.getAttribute('class'),
          orderable: elemento.getAttribute('ordenable') === '',
          searchable: elemento.getAttribute('buscable') === '',
          render: function(datoCelda, tipoRenderizado, datosFila) {

            if (tipoRenderizado === 'display')
              switch (elemento.getAttribute('tipo')) {

                case 'num-fmt':
                  datoCelda = formatoNumerico(datoCelda, 2)
                break;

                case 'date':
                  datoCelda.split(' ').length > 1 && (
                    datoCelda =
                      new Date(datoCelda)
                        .toLocaleDateString('uk')
                        .replaceAll('.', '/')
                  )
                break;

                case 'input':
                  datoCelda = `
                    <input
                      class="form-control"
                      value="${datoCelda}"
                    >
                  `
                break;

                case 'checkbox':
                  datoCelda = `
                    <input
                      type="checkbox"
                      class="form-check-input"
                      ${datoCelda * 1 ? 'checked' : ''}
                    >
                  `
                break;

              }
            else
              switch (elemento.getAttribute('tipo')) {

                case 'string':
                break;

                default:
                  datoCelda *= 1
                break;

              }

            return datoCelda

          }
        })

      });

      !$('tfoot tr', tabla).children().length &&
      columnas.forEach(function(columna, iteracion) {

        $('tfoot tr', tabla).append('<th>&nbsp;</th>')

      });

      configuracion.modificarRegistro &&
        $('thead tr, tfoot tr', tabla).append(`
            <th></th>
        `) &&
        columnas.push({
          title: 'Acciones',
          className: 'text-center',
          render: function() {

            return `
              <a href="#" class="fw-bold text-success modificarRegistro">
                <i class="fa-solid fa-pen-to-square"></i>
              </a>
            `

          }
        }) &&
        delete configuracion.modificarRegistro
      ;

      configuracion.rowGroup = {
        startRender: function(filas, grupo) {

          if (grupo && grupo !== 'No group')
            return $('<tr/>').append(`

              <td
                colspan="100%"
                style="
                  color: #fff !important;
                  background-color: var(--colorTerciario)
              ">${grupo}</td>

            `);
    
        },
        endRender: function(filas, grupo) {
    
          let subtotal = [];
    
          columna.sumar.columnas.forEach(function(columnaSumar, iteracion) {

            subtotal[columnaSumar] = filas
            .data()
            .map(function(fila, iteracion, filas) {

              return fila[columnaSumar]

            }).sumar()

            columna.agrupar.filaPie
              .children()
              .eq(columna.sumar.indices[iteracion])
              .addClass('text-end')
              .text(formatoNumerico(subtotal[columnaSumar], 2))
            ;

          });

          if (grupo && grupo !== 'No group') {

            columna.agrupar.filaPie
              .children()
              .eq(0)
              .text(filas.count())
            ;

            return columna.agrupar.filaPie.clone()

          }

        }
      }

      configuracion.columns = columnas;
      configuracion.data = datos;

      tabla.DataTable(configuracion)

    }

  })

}

/**
 * Función para actualizar los parámetros de la tabla de registros con la librería 'DataTable'
 * @ Retorna un objeto de 'DataTable'.
 */
export function actualizarParametrosTablaRegistros({
  tabla = `$('#tablaRegistros')`,
  parametros = {}
}) {

  $.each(parametros, function (campo, valor) { 

    eval(`
      $(${tabla})
        .dataTable()
        .fnSettings()
        .ajax
        .data
        .${campo} = '${valor}'
    `)

  })

}