Range Slider如何实现Touch Mobile?

问题描述 投票:0回答:1

[如何在此代码上实现移动触摸以使范围滑块在移动设备上起作用?

[我在互联网上找到了很多教程,但是它们都包含jquery ui,但是我有一个没有ui的范围滑块,而且我不太擅长JS。

$("document").ready(function() {

const rangeSliderAmount   = document.querySelector('.lc-range-slider-amount');
const rangeSliderMonth    = document.querySelector('.lc-range-slider-month');
const rangeValueBarAmount = document.querySelector('#lc-range-value-bar-amount');
const rangeValueBarMonth  = document.querySelector('#lc-range-value-bar-month');
const rangeValueAmount    = document.querySelector('#lc-range-value-amount');
const rangeValueMonth     = document.querySelector('#lc-range-value-month');
const rangeAmount         = document.getElementById("lc-amount");
const rangeMonth          = document.getElementById("lc-month");

let isDown = false;

function dragHandler() {
  isDown = !isDown;
  if (!isDown) {
    rangeValueAmount.style.setProperty('opacity', '1');
    rangeValueMonth.style.setProperty('opacity', '1');
  } else {
    rangeValueAmount.style.setProperty('opacity', '1');
    rangeValueMonth.style.setProperty('opacity', '1');
  }
}

function dragOn(e) {
  if (!isDown) return;
  rangeValueHandler();
}

function rangeValueHandler() {
  amountPercentage            = `${((rangeSliderAmount.value - 500) * 100) / (6000 - 500)}%`;
  monthPercentage             = `${((rangeSliderMonth.value - 6) * 100) / (60 - 6)}%`;
  rangeValueBarAmount.style.setProperty('width', amountPercentage);
  rangeValueBarMonth.style.setProperty('width', monthPercentage);
  rangeValueAmount.innerHTML  = `${rangeSliderAmount.value}`;
  rangeValueMonth.innerHTML   = `${rangeSliderMonth.value}`;
  rangeAmount.innerHTML       = `${rangeSliderAmount.value}`;
  rangeMonth.innerHTML        = `${rangeSliderMonth.value}`;
  vypocetSplatka();
}

rangeValueHandler();
rangeSliderAmount.addEventListener('mousedown', dragHandler);
rangeSliderAmount.addEventListener('mousemove', dragOn);
rangeSliderAmount.addEventListener('mouseup', dragHandler);
rangeSliderAmount.addEventListener('click', rangeValueHandler);

rangeSliderMonth.addEventListener('mousedown', dragHandler);
rangeSliderMonth.addEventListener('mousemove', dragOn);
rangeSliderMonth.addEventListener('mouseup', dragHandler);
rangeSliderMonth.addEventListener('click', rangeValueHandler);


function slideValue(inputElement) {
    var sliderElement = inputElement.closest('.lc-slider').find('.slider');
    var val = parseInt(inputElement.val().replace(' ', '')) || 0;
    var sliderMax = $(sliderElement).slider('option', 'max');
    var sliderMin = $(sliderElement).slider('option', 'min');

    if (val > sliderMax) {
        val = sliderMax;
    }
    if (val < sliderMin) {
        val = sliderMin;
    }
    $(sliderElement).slider('value', val);

    val = formatNumber(val, 0, ',', ' ');
    if (inputElement.val() !== val) {
      inputElement.val(val);
    }
  }

  $('.slider-value .value').change(function(){
    slideValue($(this));
    vypocetSplatka();
  });

  vypocetSplatka();

  $('.insurance-box').on('change', 'input[name=poistenie]', function(){
    vypocetSplatka();
  });

  function formatNumber(number, decimals, dec_point, thousands_sep) {
    var str = number.toFixed(decimals ? decimals : 0).toString().split('.');
    var parts = [];
    for (var i = str[0].length; i > 0; i -= 3) {
      parts.unshift(str[0].substring(Math.max(0, i - 3), i));
    }
    str[0] = parts.join(thousands_sep ? thousands_sep : ',');
    return str.join(dec_point ? dec_point : '.');
  }

  function vypocetSplatka() {
    var mesiace = parseInt($('[data-value="months"]').html());
    var pozicka = parseInt($('[data-value="loan"]').html().replace(' ', ''));
    var poplatok = (pozicka / 100) * 2;
    $('.hascharge').show();
    if(pozicka <= -1){
        poplatok = 0;
        $('.hascharge').hide();
    }
    var benefit = 2;
    var perc, payment_mpr, payment_mpr_full, insurance, payment_month, payment_month_full, suma, suma_full, rateValue, rpmn;
    $('[data-value="charge"]').text(poplatok);
    $('[data-value="months-val"]').text(mesiace);
    $('span[data-value="loan"]').text(price_format(pozicka));
    if (pozicka <= 300) {
      perc = 15.18;
    } else if (pozicka <= 700) {
      perc = 13.9;
    } else if (pozicka <= 1499) {
      perc = 11.4;
    } else {
      perc = 8.9;
    }
    if (pozicka <= 300 && mesiace<=60 && mesiace>=6) {
      perc = 15.18;
    } else if (pozicka <= 679 && mesiace<=60 && mesiace>=6) {
      perc = 13.9;
    } else if (pozicka <= 720 && mesiace<=60 && mesiace>=6) {
      perc = 10.01;
    } else if (pozicka <= 1499 && mesiace<=60 && mesiace>=6) {
      perc = 11.4;
    } else if (mesiace<=60 && mesiace>=6) {
      perc = 8.9;
    }

    var diff = (Math.round((perc - benefit) * 100) / 100).toFixed(2);
    diff = diff.replace('.', ',');
    $('[data-value="interest"]').text(diff);

    var pmt_ir_full = perc / 1200;
    var pmt_ir = (perc - benefit) / 1200;

    //pmt_ir = 13.9 / 1200;
    var pmt_np = mesiace;
    var pmt_pv = -pozicka;

    if (pmt_np > 0 && pmt_pv < 0) {
      payment_mpr = pmt(pmt_ir, pmt_np, pmt_pv);
      payment_mpr_full = pmt(pmt_ir_full, pmt_np, pmt_pv);

      $('.insurance-label').text('');
      // poistenie
      insurance = 0;

      if ($('input[name=poistenie]:checked').val() === '1') {
        insurance += 0.081 * pozicka / 100;
        $('.insurance-label').text('vrátane poistenia');
      }
      if ($('input[name=poistenie]:checked').val() === '2') {
        insurance += 0.148 * pozicka / 100;
        $('.insurance-label').text('vrátane poistenia');
      }
      //payment_mpr += ' €';
      payment_month = rd(payment_mpr + insurance);
      payment_month_full = rd(payment_mpr_full + insurance);
      payment_mpr = rd(payment_mpr);

      suma = payment_month * mesiace + poplatok;
      suma_full = payment_month_full * mesiace + poplatok;

      $('#clientsave').html(price_format(suma_full - suma) + ' &euro;');

    } else {
      payment_mpr = '';
    }
    $('[data-value="fee"]').html(price_format(payment_month));
    $('[data-value="fee-val"]').text(price_format(payment_mpr));

    rateValue = rate(pmt_np, payment_mpr, -pozicka + poplatok);
    rpmn = (Math.pow(rateValue + 1, 12) - 1) * 100;
    $('[data-value="rpmn-val"]').text(price_format(rpmn));
    $('[data-value="sum"]').text(price_format(payment_mpr * mesiace + poplatok));

    $('#vyskaF').val(pozicka);
    $('#splatnostF').val(mesiace);
  if ($('input[name=poistenie]:checked').val() === '0') { $('#poistenieF').val("bez poistenia"); };
  if ($('input[name=poistenie]:checked').val() === '1') { $('#poistenieF').val("základné"); };
  if ($('input[name=poistenie]:checked').val() === '2') { $('#poistenieF').val("rozšírené"); };

  //bez benefitu repre priklad *NEW 16.11:2017 -- START
  var diffWo = (Math.round((perc) * 100) / 100).toFixed(2);
  diffWo = diffWo.replace('.', ',');
  payment_mpr_full = rd(payment_mpr_full);

  var rateValue_full, rpmn_full;
  rateValue_full = rate(pmt_np, payment_mpr_full, -pozicka + poplatok);
  rpmn_full = (Math.pow(rateValue_full + 1, 12) - 1) * 100;

  $('[data-value="interest-wo"]').text(diffWo);
  $('[data-value="fee-val-wo"]').text(price_format(payment_mpr_full));
  $('[data-value="rpmn-val-wo"]').text(price_format(rpmn_full));
  $('[data-value="sum-wo"]').text(price_format(payment_mpr_full * mesiace + poplatok));
  // *NEW 16.11:2017 -- END

  }

  function rd(n) {
    var r = Math.round(n * 100) / 100;
    return r;
  }

  function price_format(number, decimals, decPoint, thousandsSep) {

    decimals = decimals || 2;
    number = parseFloat(number);

    if (!decPoint || !thousandsSep) {
      decPoint = ',';
      thousandsSep = ' ';
    }

    var roundedNumber = Math.round(Math.abs(number) * ('1e' + decimals)) + '';
    var numbersString = decimals ? roundedNumber.slice(0, decimals * -1) : roundedNumber;
    var decimalsString = decimals ? roundedNumber.slice(decimals * -1) : '';
    var formattedNumber = '';

    while (numbersString.length > 3) {
      formattedNumber += thousandsSep + numbersString.slice(-3);
      numbersString = numbersString.slice(0, -3);
    }

    return (number < 0 ? '-' : '') + numbersString + formattedNumber + (decimalsString ? (decPoint + decimalsString) : '');
  }


  //function pmt(ir, np, pv, fv = 0, type = 0) {  //defaul value nie je vsade podporovane!!! RBR
  function pmt(ir, np, pv, fv, type) {

    var fv = (typeof fv !== 'undefined') ?  fv : 0;
    var type = (typeof type !== 'undefined') ?  type : 0;

    /*
     * ir   - interest rate per month
     * np   - number of periods (months)
     * pv   - present value
     * fv   - future value
     * type - when the payments are due:
     *        0: end of the period, e.g. end of month (default)
     *        1: beginning of period
     */

    if (ir === 0) {
      return -(pv + fv) / np;
    }

    var pvif = Math.pow(1 + ir, np);
    var pmt = -ir * pv * (pvif + fv) / (pvif - 1);

    if (type === 1) {
      pmt /= (1 + ir);
    }

    return pmt;
  }

  function rate(paymentsPerYear, paymentAmount, presentValue, futureValue, dueEndOrBeginning, interest) {
    //If interest, futureValue, dueEndorBeginning was not set, set now
    if (interest == null) {
      interest = 0.01;
    }

    if (futureValue == null) {
      futureValue = 0;
    }

    if (dueEndOrBeginning == null) {
      dueEndOrBeginning = 0;

    }

    var FINANCIAL_MAX_ITERATIONS = 128; //Bet accuracy with 128
    var FINANCIAL_PRECISION = 0.0000001; //1.0e-8

    var y, y0, y1, x0, x1 = 0,
      f = 0,
      i = 0;
    var rate = interest;
    if (Math.abs(rate) < FINANCIAL_PRECISION) {
      y = presentValue * (1 + paymentsPerYear * rate) + paymentAmount * (1 + rate * dueEndOrBeginning) * paymentsPerYear + futureValue;
    } else {
      f = Math.exp(paymentsPerYear * Math.log(1 + rate));
      y = presentValue * f + paymentAmount * (1 / rate + dueEndOrBeginning) * (f - 1) + futureValue;
    }
    y0 = presentValue + paymentAmount * paymentsPerYear + futureValue;
    y1 = presentValue * f + paymentAmount * (1 / rate + dueEndOrBeginning) * (f - 1) + futureValue;

    // find root by Newton secant method
    i = x0 = 0.0;
    x1 = rate;
    while ((Math.abs(y0 - y1) > FINANCIAL_PRECISION) &&
      (i < FINANCIAL_MAX_ITERATIONS)) {
      rate = (y1 * x0 - y0 * x1) / (y1 - y0);
      x0 = x1;
      x1 = rate;

      if (Math.abs(rate) < FINANCIAL_PRECISION) {
        y = presentValue * (1 + paymentsPerYear * rate) + paymentAmount * (1 + rate * dueEndOrBeginning) * paymentsPerYear + futureValue;
      } else {
        f = Math.exp(paymentsPerYear * Math.log(1 + rate));
        y = presentValue * f + paymentAmount * (1 / rate + dueEndOrBeginning) * (f - 1) + futureValue;
      }

      y0 = y1;
      y1 = y;
      ++i;
    }
    return rate;
  }

});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  background: #EFEEEE;
}
.lc-container {
  margin-top: 100px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}
.lc-sliders {
  width: 70%;
  padding: 0;
  background-color: #fff;
  border-top: 5px solid #E9EFF4;
  border-bottom: 5px solid #E9EFF4;
  border-left: 5px solid #E9EFF4;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
}
.lc-slider {
  width: 100%;
  margin: 0;
  padding: 10px;
  background: transparent;
}
.lc-slider:first-child {
  border-bottom: 1px solid #E9EFF4;
}
.lc-txtinp {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.lc-amount {
  width: 90px;
  height: 90px;
  position: relative;
  display: block;
  padding-top: 13px;
  line-height: 30px;
  text-align: center;
  font-size: 26px;
  font-weight: bold;
  color: #FC6E50;
  font-style: normal;
  line-height: normal;
  border-radius: 50%;
  box-sizing: border-box;
  border: 5px solid #EFEEEE;
  transform-origin: center center;
  background: #fff;
}
.lc-amount::after {
  display: block;
  content: "EUR";
  font-size: 16px;
  letter-spacing: 0.07em;
  margin-top: -2px;
}
.lc-month {
  width: 90px;
  height: 90px;
  position: relative;
  display: block;
  padding-top: 13px;
  line-height: 30px;
  text-align: center;
  font-size: 26px;
  font-weight: bold;
  color: #FC6E50;
  font-style: normal;
  line-height: normal;
  border-radius: 50%;
  box-sizing: border-box;
  border: 5px solid #EFEEEE;
  transform-origin: center center;
  background: #fff;
}
.lc-month::after {
  display: block;
  content: "Mes.";
  font-size: 16px;
  letter-spacing: 0.07em;
  margin-top: -2px;
}
.lc-ranger {
  width: 100%;
}
.lc-range {
  margin: 20px 0;
  position: relative;
}
.lc-minmax {
  margin-top: 30px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.lc-txtinp span.span,
.lc-minmax span.span {
  font-size: 14px;
  font-weight: 400;
}
.lc-summarize {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 30%;
  height: 421px;
  padding: 0;
  background: #fff;
  border-left: 2px solid #E9EFF4;
  border-top: 5px solid #E9EFF4;
  border-bottom: 5px solid #E9EFF4;
  border-right: 5px solid #E9EFF4;
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
}
.lc-summarize-head {
  padding: 25px 0;
  text-align: center;
}
.lc-summarize-head h2 {
  font-size: 20px;
  background: none;
  color: #4d4d4d;
  margin-bottom: 0;
  background-repeat: no-repeat;
}
.lc-show-payment {
  padding: 5px;
}
.lc-payment-show {
  width: 200px;
  height: 200px;
  position: relative;
  display: block;
  margin: 0 auto;
  padding-top: 60px;
  line-height: 30px;
  text-align: center;
  font-size: 40px;
  font-weight: bold;
  color: #FC6E50;
  font-style: normal;
  line-height: normal;
  border-radius: 50%;
  box-sizing: border-box;
  border: 5px solid #EFEEEE;
  transform-origin: center center;
  background: #fff;
}
.lc-payment-show::after {
  display: block;
  content: "EUR/MES.";
  font-size: 16px;
  letter-spacing: 0.07em;
  margin-top: -2px;
}
.lc-accept-loan {
  padding: 0;
  text-align: center;
  border-top: 2px solid #E9EFF4;
}
a.send-loan-details,
button.send-loan-details {
  text-decoration: none;
  outline: none;
  border: none;
  display: block;
  text-align: center;
  width: 100%;
  padding: 15px 0;
  background: #fff;
  font-size: 20px;
  color: #4d4d4d;
  margin-bottom: 0;
  background-repeat: no-repeat;
  border-bottom-right-radius: 10px;
  cursor: pointer;
}
a.send-loan-details:hover,
a.send-loan-details:focus,
button.send-loan-details:hover,
button.send-loan-details:focus {
  background: #FC6E50;
  color: #fff;
}
.lc-representative-example {
  font-size: 12px;
  width: 100%;
  position: relative;
  margin: 15px 0;
  padding: 5px 0;
  display: block;
}
.lc-representative-example span.spanbold {
  color: #4d4d4d;
  font-weight: bold;
}

.lc-range-slider-container {
  position: relative;
}

input[type=range] {
  -webkit-appearance: none;
  margin: 10px 0;
  width: 100%;
  position: absolute;
  top: 0;
  margin: 0;
}
#lc-range-value-bar-amount {
  width: 100%;
  content: "0";
  background-color: #FC6E50;
  position: absolute;
  z-index: 10000;
  height: 25px;
  top: 0;
  margin: 0;
  border-radius: 5px;
}
#lc-range-value-bar-month {
  width: 100%;
  content: "0";
  background-color: #FC6E50;
  position: absolute;
  z-index: 10000;
  height: 25px;
  top: 0;
  margin: 0;
  border-radius: 5px;
}
/*
#range-value {
  content:"0";
  background: rgba(233, 239, 244, 0.1);;
  position: absolute;
  z-index: 10000;
  height: 25px;
  top: -65px;
  margin: 0;
  border-radius: 5px;
  left: 50%;
  transform0: translateX(-50%);
  font-size: 20px;
  padding: 12px;
  color: #41576B;
  box-shadow: 0 2px 10px 0 rgba(0,0,0,0.08);
  text-align: center;
  opacity: 0;
}*/

input[type=range]:focus {
  outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
  width: 100%;
  height: 25px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  background: #E9EFF4;
  border-radius: 5px;
  border: 0px solid #000101;
}
input[type=range]::-webkit-slider-thumb {
  box-shadow: 0 2px 10px 0 rgba(0,0,0,0.08);
  border: 14px solid #FFF;
  height: 53px;
  width: 53px;
  border-radius: 30px;
  background: #FC6E50;
  cursor: pointer;
  -webkit-appearance: none;
  margin-top: -13.5px;
  position: relative;
  z-index: 1000000000;
}
input[type=range]::-moz-range-track {
  width: 100%;
  height: 12.8px;
  cursor: pointer;
  animate: 0.2s;
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  background: #000;
  border-radius: 25px;
  border: 0px solid #000101;
}
input[type=range]::-moz-range-thumb {
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  border: 0px solid #000000;
  height: 20px;
  width: 39px;
  border-radius: 7px;
  background: #000000;
  cursor: pointer;
}
input[type=range]::-ms-track {
  width: 100%;
  height: 12.8px;
  cursor: pointer;
  animate: 0.2s;
  background: transparent;
  border-color: transparent;
  border-width: 39px 0;
  color: transparent;
}
input[type=range]::-ms-fill-lower {
  background: #000;
  border: 0px solid #000101;
  border-radius: 50px;
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
}
input[type=range]::-ms-fill-upper {
  background: #000;
  border: 0px solid #000101;
  border-radius: 50px;
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
}
input[type=range]::-ms-thumb {
  box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
  border: 0px solid #000000;
  height: 20px;
  width: 39px;
  border-radius: 7px;
  background: #000;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
        <div class="row">
            <div class="col-12">
                <div class="lc-container">
                    <div class="lc-sliders">
                        <div class="lc-slider">
                            <div class="lc-txtinp">
                                <span class="span">Zvoľte si výšku pôžičky</span>
                                <span id="lc-amount" class="lc-amount">2000</span>
                            </div>
                            <div class="lc-range">
                                <div class="lc-range-slider-container slider-value">
                                  <input id="lc-range-amount" type="range" class="slider lc-range-slider-amount" min="500" max="6000" step="100" value="500">
                                  <span id="lc-range-value-bar-amount"></span>
                                  <span id="lc-range-value-amount" data-value="loan" class="value">0</span>
                                </div>
                            </div>
                            <div class="lc-minmax">
                                <span class="span">500€</span>
                                <span class="span">6000€</span>
                            </div>
                        </div>

                        <div class="lc-slider">
                            <div class="lc-txtinp">
                                <span class="span">Zvoľte si dobu splatnosti</span>
                                <span id="lc-month" class="lc-month">6</span>
                            </div>
                            <div class="lc-range">
                                <div class="lc-range-slider-container slider-value">
                                  <input id="lc-range-month" type="range" class="slider lc-range-slider-month" min="6" max="60" step="1" value="6">
                                  <span id="lc-range-value-bar-month"></span>
                                  <span id="lc-range-value-month" data-value="months" class="value ">0</span>
                                </div>
                            </div>
                            <div class="lc-minmax">
                                <span class="span">6 mesiacov</span>
                                <span class="span">60 mesiacov</span>
                            </div>
                        </div>
                    </div>
                    <div class="lc-summarize">
                        <div class="lc-summarize-head">
                            <h2>Vaša mesačná splátka</h2>
                        </div>
                        <div class="lc-show-payment">
                            <span id="lc-payment-show" class="lc-payment-show value payment" data-value="fee">
                                0,00
                            </span>
                        </div>
                        <div class="lc-accept-loan">
                            <button type="submit" class="send-loan-details">
                                Chcem pôžičku
                            </button>
                        </div>
                    </div>
                </div>
                <div class="lc-representative-example">
                    <span class="spanbold">Reprezentatívny príklad:</span> Mesačná anuitná splátka Pôžičky s&nbsp;odmenou vo&nbsp;výške <span data-value="loan">2 000,00</span> € s&nbsp;úrokovou sadzbou
                    <span data-value="interest">13,18</span> % p.a. a&nbsp;splatnosťou <span data-value="months-val">60</span> mesiacov predstavuje
                    <span data-value="fee-val">45,69</span> €. Ročná percentuálna miera nákladov dosahuje
                    <span data-value="rpmn-val">15,03</span> %, počet splátok <span data-value="months-val">60</span>.
                    Výška poplatku za poskytnutie pôžičky je <span class="hascharge">2 % z&nbsp;výšky úveru, v&nbsp;tomto prípade</span> <span data-value="charge">40</span> €.
                    Celková čiastka, ktorú musí klient zaplatiť, predstavuje <span data-value="sum">2 781,40</span> eur. Na schválenie a poskytnutie pôžičky nie je právny nárok. Výška splátky je uvedená bez Poistenia schopnosti splácať úver.
                </div>
            </div>
        </div>
    </div>
javascript jquery
1个回答
0
投票

您需要为touch事件附加处理程序,以使范围滑块在移动设备中工作。如果将以下行添加到代码中,它将开始在移动设备中运行。

  rangeSliderAmount.addEventListener('touchstart', dragHandler);
  rangeSliderAmount.addEventListener('touchmove', dragOn);
  rangeSliderAmount.addEventListener('touchend', dragHandler);
  rangeSliderAmount.addEventListener('touchstart', rangeValueHandler);
  rangeSliderMonth.addEventListener('touchstart', dragHandler);
  rangeSliderMonth.addEventListener('touchmove', dragOn);
  rangeSliderMonth.addEventListener('touchend', dragHandler);
  rangeSliderMonth.addEventListener('touchstart', rangeValueHandler);

请参阅本文档,以了解javascript中的触摸事件:https://developer.mozilla.org/en-US/docs/Web/API/Touch_events

根据您的代码工作的示例:https://plnkr.co/edit/TDLHWvaYFr1V8GQqZ9Zb

© www.soinside.com 2019 - 2024. All rights reserved.