package com.crm.email.service.impl;

import com.alibaba.fastjson.JSON;
import com.crm.email.dao.mapper.SysEmailRecordMapper;
import com.crm.email.dao.repository.SysEmailConfigRepository;
import com.crm.email.dao.repository.SysEmailRecordRepository;
import com.crm.email.dao.repository.SysEmailTemplateRepository;
import com.crm.email.service.SysConfigService;
import com.crm.email.service.SysEmailRecordService;
import com.crm.email.service.SysEmailUnsubscribeService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.constant.GlobalConfigConstants;
import com.crm.rely.backend.core.constant.MapConstants;
import com.crm.rely.backend.core.constant.RegexpConstants;
import com.crm.rely.backend.core.dto.base.BaseResultDto;
import com.crm.rely.backend.core.dto.base.PageDto;
import com.crm.rely.backend.core.dto.base.ResultWithPagerDto;
import com.crm.rely.backend.core.dto.system.email.record.SysEmailRecordSearchDto;
import com.crm.rely.backend.core.entity.system.email.SupplementSendEmailEntity;
import com.crm.rely.backend.core.entity.system.email.SysEmailEntity;
import com.crm.rely.backend.core.entity.system.email.SysEmailSendEntity;
import com.crm.rely.backend.core.entity.system.email.SysEmailTestSendEntity;
import com.crm.rely.backend.core.entity.system.email.record.SysEmailRecordSearchEntity;
import com.crm.rely.backend.core.exception.ServiceException;
import com.crm.rely.backend.core.pojo.table.SysConfigTable;
import com.crm.rely.backend.core.pojo.table.SysEmailConfigTable;
import com.crm.rely.backend.core.pojo.table.SysEmailRecordTable;
import com.crm.rely.backend.core.pojo.table.SysEmailTemplateTable;
import com.crm.rely.backend.service.MqSendService;
import com.crm.rely.backend.util.FileProcessUtil;
import com.crm.rely.backend.util.TemplateUtil;
import com.crm.rely.backend.util.ValidateUtil;
import com.google.common.base.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.*;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.*;
import java.util.regex.Pattern;

/**
 * @author houn
 */
@Service
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public class SysEmailRecordServiceImpl implements SysEmailRecordService {

    Logger logger = LoggerFactory.getLogger(SysEmailRecordServiceImpl.class);

    @Autowired
    private SysEmailRecordRepository sysEmailRecordRepository;
    @Autowired
    private SysEmailRecordMapper sysEmailRecordMapper;
    @Autowired
    private SysEmailTemplateRepository sysEmailTemplateRepository;

    @Autowired
    private SysEmailConfigRepository sysEmailConfigRepository;

    @Autowired
    private SysConfigService sysConfigService;

    @Autowired
    private SysEmailUnsubscribeService sysEmailUnsubscribeService;

    @Autowired
    private MqSendService mqSendService;

    /**
     * 邮件编码
     */
    private final static String EMAIL_CHARSET = "UTF-8";

    /**
     * 邮件内容编码
     */
    private final static String CONTENT_CHARSET = "text/html;charset=UTF-8";

    /**
     * 创建邮件
     *
     * @param content
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    @JmsListener(destination = Constants.ACTIVEMQ_JMS_URL_EMAIL_MARKETS)
    @Async("taskExecutor")
    public void getActiveMqEmail(String content) throws Exception {

        SysEmailSendEntity sysEmailSendEntity = JSON.parseObject(content, SysEmailSendEntity.class);

        send(sysEmailSendEntity);
    }


    /**
     * 补充发送邮件
     *
     * @param content
     * @throws Exception
     */
    @Transactional(rollbackFor = Exception.class)
    @JmsListener(destination = Constants.ACTIVEMQ_JMS_URL_EMAIL_MARKETS_SUPPLEMENT)
    @Async("taskExecutor")
    public void getActiveMqEmailSupplement(String content) throws Exception {
        SupplementSendEmailEntity supplementSendEmailEntity = JSON.parseObject(content,
                SupplementSendEmailEntity.class);

        send(supplementSendEmailEntity);
    }

    /**
     * 普通邮件发送
     *
     * @param sysEmailSendEntity
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @Async("taskExecutor")
    public BaseResultDto send(SysEmailSendEntity sysEmailSendEntity) throws Exception {

        initEmailEntity(sysEmailSendEntity);

        SysEmailEntity sysEmailEntity = getEmailEntity(sysEmailSendEntity.getEmailConfigId());

        return send(sysEmailSendEntity, sysEmailEntity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResultDto send(SysEmailTestSendEntity entity) throws Exception {
        SysEmailEntity sysEmailEntity = new SysEmailEntity();
        BeanUtils.copyProperties(entity, sysEmailEntity);

        SysEmailSendEntity sysEmailSendEntity = initEmailEntity(entity.getTemplateName());
        sysEmailSendEntity.setUsers(entity.getUsers());

        return send(sysEmailSendEntity, sysEmailEntity);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResultDto send(SupplementSendEmailEntity entity) throws Exception {

        return send(entity.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResultDto send(Long id) throws Exception {
        SysEmailRecordTable sysEmailRecordTable = sysEmailRecordRepository.findFirstById(id);

        //判断发送记录是否存在
        if (sysEmailRecordTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }

        //判断是否状态不为null 且不为成功(1) 且不为退订(2)
        if (sysEmailRecordTable.getStatus() != null && sysEmailRecordTable.getStatus() != 1 && sysEmailRecordTable.getStatus() != 2) {
            SysEmailEntity sysEmailEntity = getEmailEntity(sysEmailRecordTable.getEmailConfigId());
            return send(sysEmailEntity, null, sysEmailRecordTable);
        }

        //判断是否需要回调数据
        if (!Strings.isNullOrEmpty(sysEmailRecordTable.getCallbackMq())) {
            mqSendService.send(sysEmailRecordTable.getCallbackMq(), sysEmailRecordTable);
        }
        return BaseResultDto.success(Constants.MAIL_SUCCESS);
    }

    private BaseResultDto send(SysEmailSendEntity sysEmailSendEntity, SysEmailEntity sysEmailEntity) throws Exception {
        SysEmailRecordTable sysEmailRecordTable = new SysEmailRecordTable();
        BeanUtils.copyProperties(sysEmailSendEntity, sysEmailRecordTable);
        sysEmailRecordTable.setFromAccount(sysEmailEntity.getFromAccount());
        sysEmailRecordTable.setUsers(sysEmailSendEntity.getUsers());
        sysEmailRecordTable.setSendType(sysEmailSendEntity.getEmailSendEnum() != null ?
                sysEmailSendEntity.getEmailSendEnum().getCode() : "");

        return send(sysEmailEntity, sysEmailSendEntity, sysEmailRecordTable);
    }

    private BaseResultDto send(SysEmailEntity sysEmailEntity, SysEmailSendEntity sysEmailSendEntity,
                               SysEmailRecordTable sysEmailRecordTable) throws Exception {

        try {
            Session session = createSession(sysEmailEntity);
            MimeMessage message = new MimeMessage(session);
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            InternetAddress internetAddress = getInternetAddress(sysEmailEntity.getFromAccount(),
                    sysEmailEntity.getFromAccountName());
//            helper.setFrom(new InternetAddress(MimeUtility.encodeText(showName.substring(0, account.indexOf("@")) +
//                    "<邮箱账号>").toString());
            helper.setFrom(internetAddress);
            sysEmailRecordTable.setFromAccountName(internetAddress.getAddress());
            if (sysEmailUnsubscribeService.exist(internetAddress.getAddress(), sysEmailRecordTable.getUsers())) {
                sysEmailRecordTable.setStatus(2);
            } else {
                String content = getUnsubscribeUrlContent(sysEmailRecordTable.getContent(),
                        internetAddress.getAddress(), sysEmailRecordTable.getUsers());
                sysEmailRecordTable.setContent(content);
                if (!ValidateUtil.vStringNull(sysEmailRecordTable.getUsers())) {
                    throw new ServiceException("users 为空");
                } else {
                    String[] arr = sysEmailRecordTable.getUsers().split(",");
                    InternetAddress[] internetAddresses = getInternetAddress(arr);
                    if (arr.length > 1) {
                        //密送
                        helper.setBcc(internetAddresses);
                    } else {
                        //发送
                        helper.setTo(internetAddresses);
                    }

                    //抄送
//                helper.setCc(internetAddresses);

                }
                helper.setSubject(MimeUtility.encodeWord(sysEmailRecordTable.getSubject(), "UTF-8", "Q"));
                helper.setSentDate(sysEmailRecordTable.getSendDate());
                boolean blMimeMultipart = false;
                if (sysEmailSendEntity != null) {
                    //判断是否有附件或者图片
                    blMimeMultipart =
                            (sysEmailSendEntity.getAttachContentsList() != null && sysEmailSendEntity.getAttachContentsList().size() > 0)
                                    || (sysEmailSendEntity.getImageFilesMap() != null && sysEmailSendEntity.getImageFilesMap().size() > 0);
                }
                if (blMimeMultipart) {
                    MimeMultipart mimeMultipart = crateMimeMultipartContent(sysEmailSendEntity);

                    message.setContent(mimeMultipart, "text/html;charset=UTF-8");
                } else {
//                helper.setText(sysEmailRecordTable.getContent());
                    message.setContent(sysEmailRecordTable.getContent(), "text/html;charset=UTF-8");
                }
                Transport transport = session.getTransport();

                transport.connect(sysEmailEntity.getFromAccount(), sysEmailEntity.getPassword());
                message.saveChanges();
                transport.sendMessage(message, message.getAllRecipients());
                sysEmailRecordTable.setStatus(1);
            }
            sysEmailRecordTable.setErrorMsg(null);
            sysEmailRecordTable.setErrorCode(null);
            return BaseResultDto.success(Constants.MAIL_SUCCESS);
        } catch (Exception e) {
            sysEmailRecordTable.setStatus(0);
            sysEmailRecordTable.setErrorMsg(e.getMessage());
            if (sysEmailRecordTable.getErrorNumber() == null) {
                sysEmailRecordTable.setErrorNumber(0);
            }
            sysEmailRecordTable.setErrorNumber(sysEmailRecordTable.getErrorNumber() + 1);

            //打印日志存储
            logger.error("--------------------------------------------");
//            logger.error("邮件发送失败,失败记录数据:" + sysEmailSendEntity);
            logger.error("失败原因:" + e.getMessage());
            logger.error("email exception", e);
            logger.error("--------------------------------------------");
            return BaseResultDto.error(Constants.MAIL_FAILED);
        } finally {
            //todo 添加到数据库
            sysEmailRecordRepository.save(sysEmailRecordTable);
            //如果有需要回调的 回调到对应的队列中
            if (!Strings.isNullOrEmpty(sysEmailRecordTable.getCallbackMq())) {
                mqSendService.send(sysEmailRecordTable.getCallbackMq(), sysEmailRecordTable);
            }

            if (sysEmailRecordTable.getErrorNumber() != null
                    && sysEmailRecordTable.getErrorNumber() < 10
                    && sysEmailRecordTable.getStatus() == 0
                    && !Strings.isNullOrEmpty(sysEmailRecordTable.getUsers())
                    && Pattern.matches(RegexpConstants.REGEXP_EMAIL, sysEmailRecordTable.getUsers())) {
                SupplementSendEmailEntity supplementSendEmailEntity = new SupplementSendEmailEntity();
                supplementSendEmailEntity.setId(sysEmailRecordTable.getId());

                mqSendService.send(Constants.ACTIVEMQ_JMS_URL_EMAIL_MARKETS_SUPPLEMENT, supplementSendEmailEntity);
            }
        }
    }

    @Override
    public ResultWithPagerDto<SysEmailRecordSearchDto> searchList(SysEmailRecordSearchEntity entity) throws Exception {
        Integer count = sysEmailRecordMapper.searchPageCount(entity);
        PageDto pageDto = PageDto.format(entity, count);
        if (count == null || count <= 0) {
            return ResultWithPagerDto.success(pageDto);
        }
        List<SysEmailRecordTable> sysEmailRecordTables = sysEmailRecordMapper.searchPageList(entity);

        if (sysEmailRecordTables == null || sysEmailRecordTables.size() <= 0) {

            throw new ServiceException(Constants.SYSTEM_ERROR);
        }
        List<SysEmailRecordSearchDto> sysEmailRecordSearchDtos = new ArrayList<>(sysEmailRecordTables.size());

        for (SysEmailRecordTable sysEmailRecordTable : sysEmailRecordTables) {
            SysEmailRecordSearchDto sysEmailRecordSearchDto = new SysEmailRecordSearchDto();

            BeanUtils.copyProperties(sysEmailRecordTable, sysEmailRecordSearchDto);

            sysEmailRecordSearchDto.setSubject(transformSubject(sysEmailRecordTable.getSubject()));
            sysEmailRecordSearchDtos.add(sysEmailRecordSearchDto);
        }

        return ResultWithPagerDto.success(pageDto, sysEmailRecordSearchDtos);
    }

    private Session createSession(SysEmailEntity sysEmailEntity) throws ServiceException {
        Properties properties = new Properties();
        if (sysEmailEntity.getSmtpAuth() != null && sysEmailEntity.getSmtpAuth().equals(1)) {
            properties.setProperty("mail.smtp.auth", "true");
        } else {
            properties.setProperty("mail.smtp.auth", "false");
        }
        properties.put("mail.smtp.starttls.enable", "true");
//        properties.setProperty("mail.smtp.socketFactory.fallback", "false");
        properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        properties.setProperty("mail.smtp.socketFactory.port", sysEmailEntity.getTransportProtocol());
        properties.put("mail.smtp.port", sysEmailEntity.getTransportProtocol());
        properties.setProperty("mail.transport.protocol", "smtp");
        properties.setProperty("mail.smtp.timeout", "30000");
        properties.setProperty("mail.smtp.host", sysEmailEntity.getSmtpHost());

        return Session.getInstance(properties);
    }

    private SysEmailEntity getEmailEntity(Long emailConfigId) throws ServiceException {

        SysEmailEntity sysEmailEntity;
        if (emailConfigId != null) {
            SysEmailConfigTable sysEmailConfigTable = sysEmailConfigRepository.getFirstById(emailConfigId);
            if (sysEmailConfigTable != null) {
                sysEmailEntity = new SysEmailEntity();
                BeanUtils.copyProperties(sysEmailConfigTable, sysEmailEntity);
                return sysEmailEntity;
            }
        }

        SysConfigTable sysConfigTable = sysConfigService.getByCode(GlobalConfigConstants.EMAIL_CONFIG_CONFIGURE);

        sysEmailEntity = JSON.parseObject(sysConfigTable.getValue(), SysEmailEntity.class);


        return sysEmailEntity;
    }

    /**
     * @Description: 初始化邮件
     * @Param: [sysEmailSendEntity]
     * @return: void
     * @Author: houn
     * @Date: 2019/3/27
     */
    private SysEmailSendEntity initEmailEntity(String templateName) throws Exception {
        SysEmailSendEntity sysEmailSendEntity = new SysEmailSendEntity();
        sysEmailSendEntity.setTemplateName(templateName);
        initEmailEntity(sysEmailSendEntity);
        return sysEmailSendEntity;
    }

    /**
     * 初始化邮件
     *
     * @param sysEmailSendEntity
     * @throws UnsupportedEncodingException
     */
    private void initEmailEntity(SysEmailSendEntity sysEmailSendEntity) throws Exception {

        setContent(sysEmailSendEntity);

        if (sysEmailSendEntity.getSubject() == null || sysEmailSendEntity.getSubject().trim().length() <= 0) {
//            sysEmailSendEntity.setSubject(sysEmailSendEntity.getContent());
            sysEmailSendEntity.setSubject(sysEmailSendEntity.getContent());
        }
        sysEmailSendEntity.setSubject(sysEmailSendEntity.getSubject());

        if (sysEmailSendEntity.getSendDate() == null) {
            sysEmailSendEntity.setSendDate(new Date());
        }
    }

    /***
     * @Description: 设置邮件内容
     * @Param: [sysEmailSendEntity]
     * @return: void
     * @Author: houn
     * @Date: 2019/3/27
     */
    private void setContent(SysEmailSendEntity sysEmailSendEntity) throws Exception {
        String content = null;
        /**
         * 根据模版名称是否为null或者"" 判断是否是模版发送
         */
        if (!Strings.isNullOrEmpty(sysEmailSendEntity.getTemplateName())) {
            //根据模版名称到数据库中获取模版内容
            SysEmailTemplateTable sysEmailTemplateTable =
                    sysEmailTemplateRepository.getByCode(sysEmailSendEntity.getTemplateName());
            if (sysEmailTemplateTable == null) {

                //在根据模本名称(地址)获取模版内容
                content = FileProcessUtil.getFileContent(sysEmailSendEntity.getTemplateName());

            } else {
                content = sysEmailTemplateTable.getContent();

                sysEmailSendEntity.setSubject(sysEmailTemplateTable.getSubject());
                if (sysEmailTemplateTable.getEmailConfigId() != null) {
                    sysEmailSendEntity.setEmailConfigId(sysEmailTemplateTable.getEmailConfigId());
                }
            }

        }
        if (Strings.isNullOrEmpty(content)) {
            content = sysEmailSendEntity.getContent();
        }


        if (ValidateUtil.vStringNull(content)) {

            content = TemplateUtil.replace(content, sysEmailSendEntity.getMap());
            sysEmailSendEntity.setContent(content);
        }
    }

    /**
     * @Description: 设置称谓
     * @Param: [account]
     * @return: javax.mail.internet.InternetAddress
     * @Author: houn
     * @Date: 2019/3/27
     */
    private InternetAddress getInternetAddress(String account) throws UnsupportedEncodingException {

        return getInternetAddress(account, null);
    }

    /**
     * 设置称谓
     *
     * @param account
     * @param showName
     * @return
     * @throws UnsupportedEncodingException
     */
    private InternetAddress getInternetAddress(String account, String showName) throws UnsupportedEncodingException {

        if (Strings.isNullOrEmpty(showName)) {
            showName = account.substring(0, account.indexOf("@"));
        } else {
            account = showName;
            showName = showName.substring(0, showName.indexOf("@"));
        }
        InternetAddress internetAddress = new InternetAddress(account,
                showName, EMAIL_CHARSET);
        return internetAddress;
    }

    /**
     * 设置称谓
     *
     * @param accounts
     * @return
     * @throws UnsupportedEncodingException
     */
    private InternetAddress[] getInternetAddress(String[] accounts) throws UnsupportedEncodingException {
        int size = accounts.length;
        InternetAddress[] internetAddresses = new InternetAddress[size];
        for (int i = 0; i < size; i++) {
            internetAddresses[i] = getInternetAddress(accounts[i]);
        }
        return internetAddresses;
    }

    /**
     * 设置图片及附件
     *
     * @Description:
     * @Param: [com.crm.rely.backend.entity]
     * @return: javax.mail.internet.MimeMultipart
     * @Author: houn
     * @Date: 2019/4/29
     */
    private MimeMultipart crateMimeMultipartContent(SysEmailSendEntity entity) {
        MimeMultipart mimeMultipart = null;
        try {
            //创建文本“节点”
            MimeBodyPart text = new MimeBodyPart();
            //这里添加图片的方式是将整个图片包含到邮件内容中, 实际上也可以以 http 链接的形式添加网络图片
            text.setContent(entity.getContent(), CONTENT_CHARSET);

            //将 文本 和 图片 “节点”合成一个混合“节点”
            MimeMultipart mm_text_image = new MimeMultipart();
            //放入文本
            mm_text_image.addBodyPart(text);
            //创建并放入图片
            if (entity.getImageFilesMap() != null && entity.getImageFilesMap().size() > 0) {
                Set<String> contentIDs = entity.getImageFilesMap().keySet();
                String[] contentIDsArr = new String[contentIDs.size()];
                contentIDs.toArray(contentIDsArr);
                for (int i = 0; i < contentIDsArr.length; i++) {
                    // 创建图片“节点”
                    MimeBodyPart image = new MimeBodyPart();
                    // 读取本地文件
                    DataHandler imageHander =
                            new DataHandler(new FileDataSource((File) entity.getImageFilesMap().get(contentIDsArr[i])));
                    // 将图片数据添加到“节点”
                    image.setDataHandler(imageHander);
                    // 为“节点”设置一个唯一编号（在文本“节点”将引用该ID）
                    image.setContentID(contentIDsArr[i]);
                    //放入图片(可以放入多张)
                    mm_text_image.addBodyPart(image);
                }
            }
            // 关联关系 setSubType:设置子类型。该方法只能在由客户端创建的新的MimeMultipart对象上调用。这种多部分对象的默认子类型为“mixed”。
            mm_text_image.setSubType("related");

            //将 文本+图片 的混合“节点”封装成一个普通“节点”
            MimeBodyPart text_image = new MimeBodyPart();
            text_image.setContent(mm_text_image);

            //合成一个大的混合“节点”
            mimeMultipart = new MimeMultipart();
            //放入 文本+图片 节点
            mimeMultipart.addBodyPart(text_image);
            //放入附件
            if (entity.getAttachContentsList() != null && entity.getAttachContentsList().size() > 0) {
                for (File file : entity.getAttachContentsList()) {
                    //创建附件“节点”
                    MimeBodyPart attachContent = new MimeBodyPart();
                    // 读取本地文件
                    DataHandler attachContentHander = new DataHandler(new FileDataSource(file));
                    // 将附件数据添加到“节点”
                    attachContent.setDataHandler(attachContentHander);
                    // 设置附件的文件名（需要编码）
                    attachContent.setFileName(MimeUtility.encodeText(attachContentHander.getName()));
                    //放入附件节点（如果有多个附件，可以创建多个多次添加）
                    mimeMultipart.addBodyPart(attachContent);
                }
            }
            //混合关系
            mimeMultipart.setSubType("mixed");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return mimeMultipart;
    }

    private String transformSubject(String subject) throws UnsupportedEncodingException, ParseException {
        if (Strings.isNullOrEmpty(subject)) {
            return "";
        }
        if (!subject.startsWith("=?")) {
            return subject;
        }
        String[] subjects = subject.split(" ");
        StringBuffer stringBufferSubjects = new StringBuffer(subjects.length * 2);
        try {
            for (int i = 0; i < subjects.length; i++) {
                String su = subjects[i];
                if (su.startsWith("=?")) {
                    stringBufferSubjects.append(MimeUtility.decodeWord(su));
                } else {
                    stringBufferSubjects.append(su);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }

        return stringBufferSubjects.toString();
    }

    private String getUnsubscribeUrlContent(String content, String fromAccount, String toAccount) throws Exception {

        if (Strings.isNullOrEmpty(content)) {
            return "";
        }
        if (!content.contains(MapConstants.UNSUBSCRIBE_URL)) {
            return content;
        }

        Map<String, String> map = getUnsubscribeUrlMap(fromAccount, toAccount);
        content = TemplateUtil.replace(content, map);

        return content;
    }

    private Map<String, String> getUnsubscribeUrlMap(String fromAccount, String toAccount) throws Exception {

        Map<String, String> map = new HashMap<>(1);

        String unsubscribeUrl = sysEmailUnsubscribeService.getUnsubscribeUrl(fromAccount, toAccount);
        map.put(MapConstants.UNSUBSCRIBE_URL, unsubscribeUrl);

        return map;
    }

}
