---
title: Endpoint y callback para turnero integrado con sistema externo
slug: endpoint-y-callback-para-turnero-integrado-con-sistema-externo
docTags: 
createdAt: 2026-01-09T16:43:50.009Z
---

**Nivel:** Tecnico | **Requiere:** Plan Company o superior, calendario configurado, acceso admin o super

***

## Resumen

Este tutorial te permite conectar el skill de turnero (agendamiento) de AsisteClick con tu propio sistema de gestion de citas. Configuraras dos endpoints:

1. **API de Disponibilidad**: AsisteClick consulta tu sistema para obtener los horarios disponibles
2. **API de Callback**: Tu sistema recibe notificaciones cuando se crea, modifica o cancela una reserva

Con esta integracion, el chatbot actua como interfaz conversacional mientras tu sistema externo mantiene el control total de la agenda.

***

## Antes de Empezar

- [ ] Servidor o servicio que pueda recibir peticiones HTTP POST
- [ ] Endpoint REST que devuelva JSON con horarios disponibles
- [ ] Plan Company o superior en AsisteClick
- [ ] Un calendario creado en AsisteClick (ve a **Configuracion** > **Agendas**)
- [ ] Conocimientos basicos de APIs REST y formato JSON
- [ ] Acceso de administrador o super en AsisteClick

***

## Arquitectura

```text
+-------------------+          +------------------+          +------------------+
|                   |  1. POST |                  |  2. POST |                  |
|    AsisteClick    | -------> |   Tu Endpoint    | -------> |   Tu Sistema     |
|    (Chatbot)      |  slots?  |  Disponibilidad  |  reserva |   de Turnos      |
|                   | <------- |                  | <------- |                  |
+-------------------+  JSON    +------------------+          +------------------+
         |                                                            |
         |  3. POST (callback)                                        |
         | <----------------------------------------------------------|
         |  EVENT.CREATED / EVENT.UPDATED / EVENT.CANCELED            |
         +------------------------------------------------------------+
```

**Flujo completo:**

1. El cliente solicita un turno via chatbot
2. AsisteClick llama a tu **API de Disponibilidad** con los slots nativos
3. Tu sistema responde con los slots filtrados/disponibles
4. El cliente selecciona un horario
5. AsisteClick crea la reserva y llama a tu **API de Callback**
6. Tu sistema procesa la nueva reserva

***

## Configuracion Inicial

### Paso 1: Accede a la configuracion del calendario

1. En el menu lateral, ve a **Configuracion** > **Agendas**
2. Selecciona el calendario que quieres integrar (o crea uno nuevo)
3. Desplazate hasta la seccion de integracion API

***

### Paso 2: Habilita el modo API

Activa la opcion **"Mostrar disponibilidad por API"**.

Esto le indica a AsisteClick que en lugar de usar su motor interno de disponibilidad, debe consultar tu endpoint externo.

***

### Paso 3: Configura el API Endpoint (Disponibilidad)

En el campo **"API Endpoint"**, ingresa la URL de tu servicio que devuelve horarios disponibles:

```text
https://tu-dominio.com/api/turnero/disponibilidad
```

Este endpoint recibira un POST con los slots nativos generados por AsisteClick y debera responder con los slots que estan realmente disponibles en tu sistema.

***

### Paso 4: Configura el Callback API Endpoint (Notificaciones)

En el campo **"Callback API Endpoint"**, ingresa la URL donde AsisteClick enviara las notificaciones de eventos:

```text
https://tu-dominio.com/api/turnero/callback
```

Este endpoint recibira un POST cada vez que se cree, modifique o cancele una reserva.

***

### Paso 5: Guarda la configuracion

Haz clic en **"Guardar"** para aplicar los cambios.

***

## API de Disponibilidad

### Request que recibiras

**Metodo:** `POST`
**Content-Type:** `application/json`
**User-Agent:** `AsisteClick-Booking/2.0`

AsisteClick enviara el siguiente payload a tu endpoint:

```json
{
  "calendar_id": 5,
  "timezone": "-3",
  "preferred": "2025-01-15T10:00:00",
  "count": 6,
  "start_date": "2025-01-15",
  "end_date": "2025-01-22",
  "slots": [
    {
      "text": "Miercoles 15 de Enero - 09:00",
      "isoLocal": "2025-01-15T09:00:00",
      "iso": "2025-01-15T12:00:00Z",
      "id": "slot_001"
    },
    {
      "text": "Miercoles 15 de Enero - 10:00",
      "isoLocal": "2025-01-15T10:00:00",
      "iso": "2025-01-15T13:00:00Z",
      "id": "slot_002"
    },
    {
      "text": "Miercoles 15 de Enero - 11:00",
      "isoLocal": "2025-01-15T11:00:00",
      "iso": "2025-01-15T14:00:00Z",
      "id": "slot_003"
    }
  ]
}
```

### Descripcion de campos del request

| Campo         | Tipo        | Descripcion                                                                       |
| ------------- | ----------- | --------------------------------------------------------------------------------- |
| `calendar_id` | number      | ID del calendario en AsisteClick                                                  |
| `timezone`    | string      | Offset de zona horaria del calendario (ej: "-3" para Argentina)                   |
| `preferred`   | string/null | Fecha/hora preferida por el cliente (ISO 8601), si la indico                      |
| `count`       | number      | Cantidad maxima de slots a mostrar al cliente                                     |
| `start_date`  | string      | Fecha de inicio del rango de busqueda (YYYY-MM-DD)                                |
| `end_date`    | string      | Fecha de fin del rango de busqueda (YYYY-MM-DD)                                   |
| `slots`       | array       | Slots nativos pre-generados por AsisteClick segun la configuracion del calendario |

### Descripcion de cada slot

| Campo      | Tipo   | Descripcion                                            |
| ---------- | ------ | ------------------------------------------------------ |
| `text`     | string | Texto legible para mostrar al cliente                  |
| `isoLocal` | string | Fecha/hora en zona horaria local (ISO 8601 sin offset) |
| `iso`      | string | Fecha/hora en UTC (ISO 8601 con Z)                     |
| `id`       | string | Identificador unico del slot                           |

***

### Response que debes devolver

Tu endpoint debe responder con los slots disponibles en tu sistema:

**Status Code:** `200 OK`
**Content-Type:** `application/json`

```json
{
  "slots": [
    {
      "text": "Miercoles 15 de Enero - 10:00",
      "isoLocal": "2025-01-15T10:00:00",
      "iso": "2025-01-15T13:00:00Z",
      "id": "slot_002"
    },
    {
      "text": "Miercoles 15 de Enero - 11:00",
      "isoLocal": "2025-01-15T11:00:00",
      "iso": "2025-01-15T14:00:00Z",
      "id": "slot_003"
    }
  ],
  "showBeforeButton": false,
  "showAfterButton": true
}
```

### Descripcion de campos del response

| Campo              | Tipo    | Requerido | Descripcion                                                    |
| ------------------ | ------- | --------- | -------------------------------------------------------------- |
| `slots`            | array   | Si        | Array de slots disponibles (misma estructura que el request)   |
| `showBeforeButton` | boolean | No        | Si mostrar boton "Anterior" para navegar a fechas previas      |
| `showAfterButton`  | boolean | No        | Si mostrar boton "Siguiente" para navegar a fechas posteriores |

:::BlockQuote
**Importante:** Solo debes devolver los slots que esten realmente disponibles en tu sistema. AsisteClick mostrara exactamente lo que devuelvas.
:::

***

### Logica de filtrado recomendada

Tu endpoint deberia:

1. Recibir los slots pre-generados por AsisteClick
2. Consultar tu base de datos para verificar disponibilidad
3. Filtrar los slots que ya estan ocupados
4. Devolver solo los slots disponibles

```javascript
// Pseudocodigo - Ejemplo en Node.js
app.post('/api/turnero/disponibilidad', async (req, res) => {
  const { calendar_id, slots, start_date, end_date } = req.body;

  // Obtener reservas existentes en tu sistema
  const reservasExistentes = await db.query(`
    SELECT fecha_hora FROM reservas
    WHERE fecha_hora BETWEEN ? AND ?
    AND estado = 'confirmada'
  `, [start_date, end_date]);

  // Convertir a Set para busqueda rapida
  const horariosOcupados = new Set(
    reservasExistentes.map(r => r.fecha_hora.toISOString())
  );

  // Filtrar slots disponibles
  const slotsDisponibles = slots.filter(slot =>
    !horariosOcupados.has(slot.iso)
  );

  res.json({
    slots: slotsDisponibles,
    showBeforeButton: false,
    showAfterButton: slotsDisponibles.length > 0
  });
});
```

***

### Errores y fallback

Si tu endpoint falla o no responde a tiempo, AsisteClick tiene un mecanismo de fallback:

| Situacion             | Comportamiento                          |
| --------------------- | --------------------------------------- |
| Timeout (>5 segundos) | Usa motor nativo de AsisteClick         |
| Status code >= 500    | Reintenta hasta 2 veces, luego fallback |
| Status code 4xx       | Usa motor nativo de AsisteClick         |
| Response invalido     | Usa motor nativo de AsisteClick         |

Esto garantiza que el cliente siempre reciba una respuesta, aunque tu sistema este temporalmente no disponible.

***

## API de Callback (Notificaciones)

### Cuando se envia el callback

AsisteClick enviara un POST a tu callback endpoint cuando ocurra cualquiera de estos eventos:

| Evento           | Descripcion                                        |
| ---------------- | -------------------------------------------------- |
| `EVENT.CREATED`  | Se creo una nueva reserva                          |
| `EVENT.UPDATED`  | Se modifico una reserva existente (reagendamiento) |
| `EVENT.CANCELED` | Se cancelo una reserva                             |

***

### Request que recibiras

**Metodo:** `POST`
**Content-Type:** `application/json`

**Headers adicionales:**

| Header                     | Descripcion                            |
| -------------------------- | -------------------------------------- |
| `AsisteClick-Ticket-Token` | Token unico de verificacion del ticket |
| `AsisteClick-Access-Token` | Token de acceso de la cuenta           |

**Payload completo:**

```json
{
  "event_type": "EVENT.CREATED",
  "ticket_id": "#A1B2C3",
  "key": "d41d8cd98f00b204e9800998ecf8427e",
  "timestamp": "2025-01-15T10:30:00Z",
  "channel": "WHATSAPP",
  "source": "whatsapp_api",
  "source_id": "+5491155551234",
  "status": "OPEN",
  "subject": "Reserva de turno",
  "bot": {
    "id": 123,
    "name": "Bot de Turnos"
  },
  "agent": {
    "id": null,
    "name": null,
    "email": null
  },
  "department": {
    "id": 5,
    "name": "Atencion al Cliente"
  },
  "customer": {
    "fingerprint": "abc123xyz",
    "name": "Juan Perez",
    "email": "juan@ejemplo.com",
    "phone": "+5491155551234",
    "facebook_id": null,
    "sentiment": null,
    "ip": "190.100.50.25",
    "browser_os": "WhatsApp/2.23.5",
    "country_code": "AR",
    "country_name": "Argentina"
  },
  "event": {
    "id": 456,
    "calendar_id": 5,
    "calendar_title": "Turnos Consulta",
    "utc_from": "2025-01-15T13:00:00Z",
    "utc_to": "2025-01-15T13:30:00Z",
    "location": "Consultorio 3, Piso 2",
    "public_key": "XY7K9M2P"
  },
  "messages": [
    {
      "action": "IN",
      "timestamp": "2025-01-15T10:25:00Z",
      "name": "Juan Perez",
      "message": "Hola, quiero sacar un turno",
      "attachments": null
    },
    {
      "action": "OUT",
      "timestamp": "2025-01-15T10:25:05Z",
      "name": "Bot de Turnos",
      "message": "Perfecto! Estos son los horarios disponibles...",
      "attachments": null
    }
  ],
  "tags": ["turno", "consulta_general"],
  "custom_fields": [
    {
      "id": "motivo_consulta",
      "value": "Control anual"
    },
    {
      "id": "obra_social",
      "value": "OSDE"
    }
  ]
}
```

***

### Descripcion de campos principales

| Campo        | Tipo   | Descripcion                                                            |
| ------------ | ------ | ---------------------------------------------------------------------- |
| `event_type` | string | Tipo de evento: `EVENT.CREATED`, `EVENT.UPDATED`, `EVENT.CANCELED`     |
| `ticket_id`  | string | ID del ticket en formato base36 con prefijo #                          |
| `key`        | string | Hash MD5 para verificacion de autenticidad                             |
| `timestamp`  | string | Fecha/hora del ticket (ISO 8601)                                       |
| `channel`    | string | Canal de comunicacion: `WHATSAPP`, `WEB`, `FACEBOOK`, `TELEGRAM`, etc. |

### Objeto `event` (datos de la reserva)

| Campo                  | Tipo   | Descripcion                               |
| ---------------------- | ------ | ----------------------------------------- |
| `event.id`             | number | ID unico del evento en AsisteClick        |
| `event.calendar_id`    | number | ID del calendario                         |
| `event.calendar_title` | string | Nombre del calendario                     |
| `event.utc_from`       | string | Inicio de la cita en UTC (ISO 8601)       |
| `event.utc_to`         | string | Fin de la cita en UTC (ISO 8601)          |
| `event.location`       | string | Ubicacion de la cita                      |
| `event.public_key`     | string | Codigo de confirmacion visible al cliente |

### Objeto `customer` (datos del cliente)

| Campo                   | Tipo        | Descripcion                               |
| ----------------------- | ----------- | ----------------------------------------- |
| `customer.name`         | string      | Nombre completo del cliente               |
| `customer.email`        | string/null | Email del cliente                         |
| `customer.phone`        | string      | Telefono del cliente                      |
| `customer.country_code` | string      | Codigo de pais ISO (ej: "AR", "MX", "ES") |

***

### Response esperado

Tu endpoint debe responder con status `200 OK` para indicar que recibio correctamente el callback:

```json
{
  "status": "ok",
  "message": "Reserva procesada correctamente",
  "external_id": "TU-REF-12345"
}
```

El contenido del response es informativo y no afecta el flujo de AsisteClick.

***

### Ejemplo de implementacion del callback

```javascript
// Ejemplo en Node.js con Express
app.post('/api/turnero/callback', async (req, res) => {
  const { event_type, customer, event, custom_fields } = req.body;

  // Verificar token de autenticacion
  const token = req.headers['asisteclick-access-token'];
  if (!verificarToken(token)) {
    return res.status(401).json({ error: 'Token invalido' });
  }

  try {
    switch (event_type) {
      case 'EVENT.CREATED':
        // Crear reserva en tu sistema
        await crearReserva({
          fecha: event.utc_from,
          duracion: calcularMinutos(event.utc_from, event.utc_to),
          cliente: customer.name,
          telefono: customer.phone,
          email: customer.email,
          ubicacion: event.location,
          codigo_asisteclick: event.public_key,
          datos_adicionales: custom_fields
        });
        break;

      case 'EVENT.UPDATED':
        // Actualizar reserva existente
        await actualizarReserva(event.public_key, {
          nuevaFecha: event.utc_from
        });
        break;

      case 'EVENT.CANCELED':
        // Cancelar reserva
        await cancelarReserva(event.public_key);
        break;
    }

    res.json({ status: 'ok' });

  } catch (error) {
    console.error('Error procesando callback:', error);
    res.status(500).json({ error: 'Error interno' });
  }
});
```

***

## Ejemplo Completo: Clinica Medica

### Escenario

Una clinica quiere que su sistema de gestion de pacientes (HIS) sea la fuente de verdad para los turnos, pero usar el chatbot de AsisteClick como interfaz de atencion.

### Implementacion del Endpoint de Disponibilidad

```php
<?php
// disponibilidad.php

header('Content-Type: application/json');

// Recibir datos de AsisteClick
$input = json_decode(file_get_contents('php://input'), true);
$calendar_id = $input['calendar_id'];
$slots = $input['slots'];
$start_date = $input['start_date'];
$end_date = $input['end_date'];

// Mapear calendar_id de AsisteClick a profesional en HIS
$profesionales = [
    5 => 'DR_GARCIA',
    6 => 'DRA_MARTINEZ',
    7 => 'DR_LOPEZ'
];

$profesional_id = $profesionales[$calendar_id] ?? null;

if (!$profesional_id) {
    http_response_code(400);
    echo json_encode(['error' => 'Calendario no mapeado']);
    exit;
}

// Consultar turnos ocupados en el HIS
$conn = new mysqli('localhost', 'user', 'pass', 'his_db');
$stmt = $conn->prepare("
    SELECT fecha_turno
    FROM turnos
    WHERE profesional_id = ?
    AND fecha_turno BETWEEN ? AND ?
    AND estado IN ('confirmado', 'en_espera')
");
$stmt->bind_param("sss", $profesional_id, $start_date, $end_date);
$stmt->execute();
$result = $stmt->get_result();

// Crear set de horarios ocupados
$ocupados = [];
while ($row = $result->fetch_assoc()) {
    $ocupados[] = date('c', strtotime($row['fecha_turno']));
}

// Filtrar slots disponibles
$disponibles = array_filter($slots, function($slot) use ($ocupados) {
    return !in_array($slot['iso'], $ocupados);
});

// Responder
echo json_encode([
    'slots' => array_values($disponibles),
    'showBeforeButton' => false,
    'showAfterButton' => count($disponibles) > 0
]);
```

### Implementacion del Callback

```php
<?php
// callback.php

header('Content-Type: application/json');

// Verificar token
$token = $_SERVER['HTTP_ASISTECLICK_ACCESS_TOKEN'] ?? '';
if ($token !== 'TU_ACCESS_TOKEN_SECRETO') {
    http_response_code(401);
    echo json_encode(['error' => 'No autorizado']);
    exit;
}

$input = json_decode(file_get_contents('php://input'), true);
$event_type = $input['event_type'];
$customer = $input['customer'];
$event = $input['event'];
$custom_fields = $input['custom_fields'] ?? [];

$conn = new mysqli('localhost', 'user', 'pass', 'his_db');

// Mapear calendario a profesional
$profesionales = [
    5 => 'DR_GARCIA',
    6 => 'DRA_MARTINEZ'
];
$profesional_id = $profesionales[$event['calendar_id']] ?? 'NO_ASIGNADO';

switch ($event_type) {
    case 'EVENT.CREATED':
        // Buscar o crear paciente
        $stmt = $conn->prepare("SELECT paciente_id FROM pacientes WHERE telefono = ?");
        $stmt->bind_param("s", $customer['phone']);
        $stmt->execute();
        $result = $stmt->get_result();

        if ($result->num_rows == 0) {
            // Crear paciente nuevo
            $stmt = $conn->prepare("
                INSERT INTO pacientes (nombre, telefono, email, pais)
                VALUES (?, ?, ?, ?)
            ");
            $stmt->bind_param("ssss",
                $customer['name'],
                $customer['phone'],
                $customer['email'],
                $customer['country_code']
            );
            $stmt->execute();
            $paciente_id = $conn->insert_id;
        } else {
            $paciente_id = $result->fetch_assoc()['paciente_id'];
        }

        // Crear turno
        $stmt = $conn->prepare("
            INSERT INTO turnos
            (paciente_id, profesional_id, fecha_turno, fecha_fin, ubicacion,
             codigo_externo, estado, origen)
            VALUES (?, ?, ?, ?, ?, ?, 'confirmado', 'asisteclick')
        ");
        $stmt->bind_param("isssss",
            $paciente_id,
            $profesional_id,
            $event['utc_from'],
            $event['utc_to'],
            $event['location'],
            $event['public_key']
        );
        $stmt->execute();

        // Guardar campos personalizados
        foreach ($custom_fields as $field) {
            $stmt = $conn->prepare("
                INSERT INTO turno_extras (turno_id, campo, valor)
                VALUES (?, ?, ?)
            ");
            $turno_id = $conn->insert_id;
            $stmt->bind_param("iss", $turno_id, $field['id'], $field['value']);
            $stmt->execute();
        }
        break;

    case 'EVENT.UPDATED':
        $stmt = $conn->prepare("
            UPDATE turnos
            SET fecha_turno = ?, fecha_fin = ?
            WHERE codigo_externo = ?
        ");
        $stmt->bind_param("sss",
            $event['utc_from'],
            $event['utc_to'],
            $event['public_key']
        );
        $stmt->execute();
        break;

    case 'EVENT.CANCELED':
        $stmt = $conn->prepare("
            UPDATE turnos
            SET estado = 'cancelado'
            WHERE codigo_externo = ?
        ");
        $stmt->bind_param("s", $event['public_key']);
        $stmt->execute();
        break;
}

echo json_encode([
    'status' => 'ok',
    'turno_id' => $conn->insert_id ?? null
]);
```

***

## Limites y Consideraciones

| Limite                   | Valor      | Nota                                            |
| ------------------------ | ---------- | ----------------------------------------------- |
| Timeout del request      | 5 segundos | Si tu API no responde a tiempo, se usa fallback |
| Reintentos automaticos   | 2          | Solo para errores 5xx                           |
| Tamaño maximo del body   | 1 MB       | Para requests y responses                       |
| Cantidad maxima de slots | Sin limite | Depende de la configuracion del calendario      |

### Consideraciones de seguridad

- **Valida siempre el token** `AsisteClick-Access-Token` en los callbacks
- **Usa HTTPS** para todos los endpoints
- **Implementa rate limiting** para evitar abusos
- **Registra logs** de todas las peticiones para debugging

### Consideraciones de rendimiento

- Tu API de disponibilidad debe responder en menos de 3 segundos idealmente
- Cachea las consultas frecuentes si es posible
- Usa indices en las columnas de fecha en tu base de datos

***

## Troubleshooting

| Sintoma                               | Causa Probable                       | Solucion                                                   |
| ------------------------------------- | ------------------------------------ | ---------------------------------------------------------- |
| No llegan peticiones a mi endpoint    | URL incorrecta o inaccesible         | Verifica que la URL sea publica y accesible desde internet |
| Siempre usa el motor nativo           | Tu endpoint devuelve error o timeout | Revisa logs de tu servidor, optimiza tiempo de respuesta   |
| Los slots no coinciden con mi sistema | Zona horaria incorrecta              | Usa siempre el campo `iso` (UTC) para comparar             |
| Callbacks no llegan                   | Campo api\_callback\_url vacio       | Verifica que guardaste la URL en la configuracion          |
| Error 401 en callbacks                | Token invalido                       | Usa el token correcto de la cuenta                         |
| Duplicados en mi sistema              | No verificas `public_key`            | Usa `public_key` como clave unica para evitar duplicados   |

***

## Validacion y Testing

### Probar el endpoint de disponibilidad

Usa curl o Postman para simular una peticion de AsisteClick:

```bash
curl -X POST https://tu-dominio.com/api/turnero/disponibilidad \
  -H "Content-Type: application/json" \
  -H "User-Agent: AsisteClick-Booking/2.0" \
  -d '{
    "calendar_id": 5,
    "timezone": "-3",
    "preferred": null,
    "count": 6,
    "start_date": "2025-01-15",
    "end_date": "2025-01-22",
    "slots": [
      {
        "text": "Miercoles 15 de Enero - 10:00",
        "isoLocal": "2025-01-15T10:00:00",
        "iso": "2025-01-15T13:00:00Z",
        "id": "slot_001"
      }
    ]
  }'
```

### Probar el callback

```bash
curl -X POST https://tu-dominio.com/api/turnero/callback \
  -H "Content-Type: application/json" \
  -H "AsisteClick-Access-Token: TU_TOKEN" \
  -d '{
    "event_type": "EVENT.CREATED",
    "ticket_id": "#TEST123",
    "customer": {
      "name": "Usuario Prueba",
      "phone": "+5491155550000",
      "email": "test@ejemplo.com"
    },
    "event": {
      "id": 1,
      "calendar_id": 5,
      "utc_from": "2025-01-15T13:00:00Z",
      "utc_to": "2025-01-15T13:30:00Z",
      "location": "Consultorio Test",
      "public_key": "TESTKEY1"
    }
  }'
```

***

## Preguntas Frecuentes

**Puedo usar autenticacion adicional en mis endpoints?**

Si. Puedes agregar headers personalizados en la URL de callback usando el formato:

```text
https://tu-dominio.com/callback::Authorization:Bearer tu-token;X-Custom:valor
```

**Que pasa si mi sistema esta caido?**

AsisteClick tiene fallback automatico al motor nativo para disponibilidad. Para callbacks, los reintentos son limitados, por lo que es importante tener alta disponibilidad en tu endpoint de callback.

**Puedo tener diferentes endpoints para diferentes calendarios?**

Actualmente cada calendario tiene su propia configuracion de API, por lo que puedes apuntar cada uno a un endpoint diferente.

**Como identifico de que calendario viene una reserva en el callback?**

El objeto `event` incluye `calendar_id` y `calendar_title` que te permiten identificar el origen.

**Los callbacks incluyen la conversacion completa?**

Si. El array `messages` contiene toda la conversacion entre el cliente y el bot/agente.

