mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2024-11-25 13:48:42 -05:00
Merge branch 'feat-fst280' of bitbucket.org:k1jt/wsjtx into feat-fst280
This commit is contained in:
commit
c925f6d1cc
@ -59,8 +59,7 @@ program fst240sim
|
|||||||
baud=12000.0/nsps !Keying rate (baud)
|
baud=12000.0/nsps !Keying rate (baud)
|
||||||
nmax=nsec*12000
|
nmax=nsec*12000
|
||||||
nz=nsps*NN
|
nz=nsps*NN
|
||||||
nz2=nsps*NN2
|
txt=nz*dt !Transmission length (s)
|
||||||
txt=nz2*dt !Transmission length (s)
|
|
||||||
tt=nsps*dt !Duration of symbols (s)
|
tt=nsps*dt !Duration of symbols (s)
|
||||||
allocate( c0(0:nmax-1) )
|
allocate( c0(0:nmax-1) )
|
||||||
allocate( c(0:nmax-1) )
|
allocate( c(0:nmax-1) )
|
||||||
|
@ -87,11 +87,5 @@ subroutine gen_fst240wave(itone,nsym,nsps,nwave,fsample,hmod,f0, &
|
|||||||
cwave=cshift(cwave,kshift)
|
cwave=cshift(cwave,kshift)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
! do i=1,nwave
|
|
||||||
! write(71,3071) i,i/48000.0,wave(i)
|
|
||||||
!3071 format(i10,2f15.9)
|
|
||||||
! enddo
|
|
||||||
wave(nsps*nsym:)=0. !Kill a stray spike ??
|
|
||||||
|
|
||||||
return
|
return
|
||||||
end subroutine gen_fst240wave
|
end subroutine gen_fst240wave
|
||||||
|
@ -308,7 +308,6 @@ contains
|
|||||||
call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2)
|
call fst240_downsample(c_bigfft,nfft1,ndown,fc0,sigbw,c2)
|
||||||
|
|
||||||
call timer('sync240 ',0)
|
call timer('sync240 ',0)
|
||||||
|
|
||||||
fc1=0.0
|
fc1=0.0
|
||||||
if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s
|
if(emedelay.lt.0.1) then ! search offsets from 0 s to 2 s
|
||||||
is0=1.5*nspsec
|
is0=1.5*nspsec
|
||||||
@ -393,7 +392,6 @@ contains
|
|||||||
xdt=(isbest-nspsec)/fs2
|
xdt=(isbest-nspsec)/fs2
|
||||||
if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2
|
if(ntrperiod.eq.15) xdt=(isbest-real(nspsec)/2.0)/fs2
|
||||||
call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2)
|
call fst240_downsample(c_bigfft,nfft1,ndown,fc_synced,sigbw,c2)
|
||||||
|
|
||||||
do ijitter=0,jittermax
|
do ijitter=0,jittermax
|
||||||
if(ijitter.eq.0) ioffset=0
|
if(ijitter.eq.0) ioffset=0
|
||||||
if(ijitter.eq.1) ioffset=1
|
if(ijitter.eq.1) ioffset=1
|
||||||
@ -549,6 +547,10 @@ contains
|
|||||||
else
|
else
|
||||||
call get_fst240_tones_from_bits(message74,itone,1)
|
call get_fst240_tones_from_bits(message74,itone,1)
|
||||||
endif
|
endif
|
||||||
|
if(.false.) then
|
||||||
|
call write_ref(itone,iwave,nsps,nmax,ndown,hmod, &
|
||||||
|
isbest,fc_synced)
|
||||||
|
endif
|
||||||
xsig=0
|
xsig=0
|
||||||
do i=1,NN
|
do i=1,NN
|
||||||
xsig=xsig+s4(itone(i),i)**2
|
xsig=xsig+s4(itone(i),i)**2
|
||||||
@ -790,7 +792,6 @@ contains
|
|||||||
iploc=ia+im(1)-1 !Index of CCF peak
|
iploc=ia+im(1)-1 !Index of CCF peak
|
||||||
pval=s2(iploc) !Peak value
|
pval=s2(iploc) !Peak value
|
||||||
if(pval.lt.minsync) exit
|
if(pval.lt.minsync) exit
|
||||||
if(s2(iploc).gt.minsync) then !Is this a possible candidate?
|
|
||||||
do i=-3,+3 !Remove 0.9 of a model CCF at
|
do i=-3,+3 !Remove 0.9 of a model CCF at
|
||||||
k=iploc+2*hmod*i !this frequency from s2()
|
k=iploc+2*hmod*i !this frequency from s2()
|
||||||
if(k.ge.ia .and. k.le.ib) then
|
if(k.ge.ia .and. k.le.ib) then
|
||||||
@ -800,10 +801,26 @@ contains
|
|||||||
ncand=ncand+1
|
ncand=ncand+1
|
||||||
candidates(ncand,1)=df2*iploc !Candidate frequency
|
candidates(ncand,1)=df2*iploc !Candidate frequency
|
||||||
candidates(ncand,2)=pval !Rough estimate of SNR
|
candidates(ncand,2)=pval !Rough estimate of SNR
|
||||||
endif
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
return
|
return
|
||||||
end subroutine get_candidates_fst240
|
end subroutine get_candidates_fst240
|
||||||
|
|
||||||
|
subroutine write_ref(itone,iwave,nsps,nmax,ndown,hmod,i0,fc)
|
||||||
|
complex cwave(nmax)
|
||||||
|
integer itone(160)
|
||||||
|
integer*2 iwave(nmax)
|
||||||
|
integer hmod
|
||||||
|
|
||||||
|
wave=0
|
||||||
|
fsample=12000.0
|
||||||
|
nsym=160
|
||||||
|
call gen_fst240wave(itone,nsym,nsps,nmax,fsample,hmod,fc, &
|
||||||
|
1,cwave,wave)
|
||||||
|
cwave=cshift(cwave,-i0*ndown)
|
||||||
|
do i=1,nmax
|
||||||
|
write(51,*) i,iwave(i),real(cwave(i)),imag(cwave(i))
|
||||||
|
enddo
|
||||||
|
end subroutine write_ref
|
||||||
|
|
||||||
end module fst240_decode
|
end module fst240_decode
|
||||||
|
@ -4218,7 +4218,7 @@ void MainWindow::startTx2()
|
|||||||
if (m_config.TX_messages ()) {
|
if (m_config.TX_messages ()) {
|
||||||
t = " Transmitting " + m_mode + " ----------------------- " +
|
t = " Transmitting " + m_mode + " ----------------------- " +
|
||||||
m_config.bands ()->find (m_freqNominal);
|
m_config.bands ()->find (m_freqNominal);
|
||||||
t=WSPR_hhmm(0) + ' ' + t.rightJustified (66, '-');
|
t=beacon_start_time () + ' ' + t.rightJustified (66, '-');
|
||||||
ui->decodedTextBrowser->appendText(t);
|
ui->decodedTextBrowser->appendText(t);
|
||||||
}
|
}
|
||||||
write_all("Tx",m_currentMessage);
|
write_all("Tx",m_currentMessage);
|
||||||
@ -5824,6 +5824,8 @@ void MainWindow::on_actionFST240_triggered()
|
|||||||
{
|
{
|
||||||
int nsub=m_nSubMode;
|
int nsub=m_nSubMode;
|
||||||
on_actionJT65_triggered();
|
on_actionJT65_triggered();
|
||||||
|
ui->label_6->setText(tr ("Band Activity"));
|
||||||
|
ui->label_7->setText(tr ("Rx Frequency"));
|
||||||
ui->sbSubmode->setMaximum(3);
|
ui->sbSubmode->setMaximum(3);
|
||||||
m_nSubMode=nsub;
|
m_nSubMode=nsub;
|
||||||
ui->sbSubmode->setValue(m_nSubMode);
|
ui->sbSubmode->setValue(m_nSubMode);
|
||||||
@ -5835,11 +5837,8 @@ void MainWindow::on_actionFST240_triggered()
|
|||||||
// 0123456789012345678901234567890123
|
// 0123456789012345678901234567890123
|
||||||
displayWidgets(nWidgets("1111110001001111000100000001000000"));
|
displayWidgets(nWidgets("1111110001001111000100000001000000"));
|
||||||
setup_status_bar (bVHF);
|
setup_status_bar (bVHF);
|
||||||
m_TRperiod = ui->sbTR->value();
|
ui->sbTR->values ({15, 30, 60, 120, 300});
|
||||||
ui->sbTR->setMinimum(15);
|
on_sbTR_valueChanged (ui->sbTR->value());
|
||||||
ui->sbTR->setMaximum(300);
|
|
||||||
m_TRperiod = ui->sbTR->value();
|
|
||||||
on_sbTR_valueChanged(ui->sbTR->value());
|
|
||||||
ui->cbAutoSeq->setChecked(true);
|
ui->cbAutoSeq->setChecked(true);
|
||||||
m_wideGraph->setMode(m_mode);
|
m_wideGraph->setMode(m_mode);
|
||||||
m_wideGraph->setModeTx(m_modeTx);
|
m_wideGraph->setModeTx(m_modeTx);
|
||||||
@ -5862,16 +5861,9 @@ void MainWindow::on_actionFST240W_triggered()
|
|||||||
setup_status_bar (bVHF);
|
setup_status_bar (bVHF);
|
||||||
m_nSubMode=0;
|
m_nSubMode=0;
|
||||||
ui->sbSubmode->setValue(m_nSubMode);
|
ui->sbSubmode->setValue(m_nSubMode);
|
||||||
m_TRperiod = ui->sbTR_FST240W->value ();
|
|
||||||
ui->band_hopping_group_box->setChecked(false);
|
ui->band_hopping_group_box->setChecked(false);
|
||||||
ui->band_hopping_group_box->setVisible(false);
|
ui->band_hopping_group_box->setVisible(false);
|
||||||
int ntr=m_TRperiod;
|
on_sbTR_FST240W_valueChanged (ui->sbTR_FST240W->value ());
|
||||||
ui->sbTR_FST240W->setMinimum(15);
|
|
||||||
ui->sbTR_FST240W->setMaximum(300);
|
|
||||||
ui->sbTR_FST240W->setValue(120); //### Why is all this necessary? ###
|
|
||||||
ui->sbTR_FST240W->setValue(300);
|
|
||||||
ui->sbTR_FST240W->setValue(ntr);
|
|
||||||
m_TRperiod = ui->sbTR_FST240W->value();
|
|
||||||
ui->sbSubmode->setMaximum(3);
|
ui->sbSubmode->setMaximum(3);
|
||||||
m_wideGraph->setMode(m_mode);
|
m_wideGraph->setMode(m_mode);
|
||||||
m_wideGraph->setModeTx(m_modeTx);
|
m_wideGraph->setModeTx(m_modeTx);
|
||||||
@ -6100,19 +6092,23 @@ void MainWindow::on_actionJT9_triggered()
|
|||||||
}
|
}
|
||||||
ui->sbSubmode->setMaximum(7);
|
ui->sbSubmode->setMaximum(7);
|
||||||
if(m_bFast9) {
|
if(m_bFast9) {
|
||||||
m_TRperiod = ui->sbTR->value ();
|
ui->sbTR->values ({5, 10, 15, 30});
|
||||||
|
on_sbTR_valueChanged (ui->sbTR->value());
|
||||||
m_wideGraph->hide();
|
m_wideGraph->hide();
|
||||||
m_fastGraph->showNormal();
|
m_fastGraph->showNormal();
|
||||||
ui->TxFreqSpinBox->setValue(700);
|
ui->TxFreqSpinBox->setValue(700);
|
||||||
ui->RxFreqSpinBox->setValue(700);
|
ui->RxFreqSpinBox->setValue(700);
|
||||||
ui->decodedTextLabel->setText("UTC dB T Freq " + tr ("Message"));
|
ui->decodedTextLabel->setText(" UTC dB T Freq " + tr ("Message"));
|
||||||
ui->decodedTextLabel2->setText("UTC dB T Freq " + tr ("Message"));
|
ui->decodedTextLabel2->setText(" UTC dB T Freq " + tr ("Message"));
|
||||||
} else {
|
} else {
|
||||||
ui->cbAutoSeq->setChecked(false);
|
ui->cbAutoSeq->setChecked(false);
|
||||||
|
if (m_mode != "FST240")
|
||||||
|
{
|
||||||
m_TRperiod=60.0;
|
m_TRperiod=60.0;
|
||||||
ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message"));
|
ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message"));
|
||||||
ui->decodedTextLabel2->setText("UTC dB DT Freq " + tr ("Message"));
|
ui->decodedTextLabel2->setText("UTC dB DT Freq " + tr ("Message"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
|
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
|
||||||
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||||
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||||
@ -6251,7 +6247,8 @@ void MainWindow::on_actionISCAT_triggered()
|
|||||||
m_mode="ISCAT";
|
m_mode="ISCAT";
|
||||||
m_modeTx="ISCAT";
|
m_modeTx="ISCAT";
|
||||||
ui->actionISCAT->setChecked(true);
|
ui->actionISCAT->setChecked(true);
|
||||||
m_TRperiod = ui->sbTR->value ();
|
ui->sbTR->values ({5, 10, 15, 30});
|
||||||
|
on_sbTR_valueChanged (ui->sbTR->value ());
|
||||||
m_modulator->setTRPeriod(m_TRperiod);
|
m_modulator->setTRPeriod(m_TRperiod);
|
||||||
m_detector->setTRPeriod(m_TRperiod);
|
m_detector->setTRPeriod(m_TRperiod);
|
||||||
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
|
m_wideGraph->setPeriod(m_TRperiod,m_nsps);
|
||||||
@ -6318,7 +6315,8 @@ void MainWindow::on_actionMSK144_triggered()
|
|||||||
VHF_features_enabled(true);
|
VHF_features_enabled(true);
|
||||||
m_bFastMode=true;
|
m_bFastMode=true;
|
||||||
m_bFast9=false;
|
m_bFast9=false;
|
||||||
m_TRperiod = ui->sbTR->value ();
|
ui->sbTR->values ({5, 10, 15, 30});
|
||||||
|
on_sbTR_valueChanged (ui->sbTR->value());
|
||||||
m_wideGraph->hide();
|
m_wideGraph->hide();
|
||||||
m_fastGraph->showNormal();
|
m_fastGraph->showNormal();
|
||||||
ui->TxFreqSpinBox->setValue(1500);
|
ui->TxFreqSpinBox->setValue(1500);
|
||||||
@ -6326,8 +6324,8 @@ void MainWindow::on_actionMSK144_triggered()
|
|||||||
ui->RxFreqSpinBox->setMinimum(1400);
|
ui->RxFreqSpinBox->setMinimum(1400);
|
||||||
ui->RxFreqSpinBox->setMaximum(1600);
|
ui->RxFreqSpinBox->setMaximum(1600);
|
||||||
ui->RxFreqSpinBox->setSingleStep(10);
|
ui->RxFreqSpinBox->setSingleStep(10);
|
||||||
ui->decodedTextLabel->setText("UTC dB T Freq " + tr ("Message"));
|
ui->decodedTextLabel->setText(" UTC dB T Freq " + tr ("Message"));
|
||||||
ui->decodedTextLabel2->setText("UTC dB T Freq " + tr ("Message"));
|
ui->decodedTextLabel2->setText(" UTC dB T Freq " + tr ("Message"));
|
||||||
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||||
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||||
m_fastGraph->setTRPeriod(m_TRperiod);
|
m_fastGraph->setTRPeriod(m_TRperiod);
|
||||||
@ -6422,7 +6420,8 @@ void MainWindow::on_actionFreqCal_triggered()
|
|||||||
ui->actionFreqCal->setChecked(true);
|
ui->actionFreqCal->setChecked(true);
|
||||||
switch_mode(Modes::FreqCal);
|
switch_mode(Modes::FreqCal);
|
||||||
m_wideGraph->setMode(m_mode);
|
m_wideGraph->setMode(m_mode);
|
||||||
m_TRperiod = ui->sbTR->value ();
|
ui->sbTR->values ({5, 10, 15, 30});
|
||||||
|
on_sbTR_valueChanged (ui->sbTR->value());
|
||||||
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||||
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe
|
||||||
m_nsps=6912; //For symspec only
|
m_nsps=6912; //For symspec only
|
||||||
@ -6497,8 +6496,8 @@ void MainWindow::WSPR_config(bool b)
|
|||||||
Q_EMIT m_config.transceiver_tx_frequency (0); // turn off split
|
Q_EMIT m_config.transceiver_tx_frequency (0); // turn off split
|
||||||
}
|
}
|
||||||
m_bSimplex = true;
|
m_bSimplex = true;
|
||||||
} else {
|
} else
|
||||||
ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message"));
|
{
|
||||||
m_bSimplex = false;
|
m_bSimplex = false;
|
||||||
}
|
}
|
||||||
enable_DXCC_entity (m_config.DXCC ()); // sets text window proportions and (re)inits the logbook
|
enable_DXCC_entity (m_config.DXCC ()); // sets text window proportions and (re)inits the logbook
|
||||||
@ -7431,6 +7430,25 @@ void MainWindow::on_sbTR_valueChanged(int value)
|
|||||||
// if(!m_bFastMode and n>m_nSubMode) m_MinW=m_nSubMode;
|
// if(!m_bFastMode and n>m_nSubMode) m_MinW=m_nSubMode;
|
||||||
if(m_bFastMode or m_mode=="FreqCal" or m_mode=="FST240" or m_mode=="FST240W") {
|
if(m_bFastMode or m_mode=="FreqCal" or m_mode=="FST240" or m_mode=="FST240W") {
|
||||||
m_TRperiod = value;
|
m_TRperiod = value;
|
||||||
|
if (m_mode == "FST240" || m_mode == "FST240W")
|
||||||
|
{
|
||||||
|
if (m_TRperiod < 60)
|
||||||
|
{
|
||||||
|
ui->decodedTextLabel->setText(" UTC dB DT Freq " + tr ("Message"));
|
||||||
|
if (m_mode != "FST240W")
|
||||||
|
{
|
||||||
|
ui->decodedTextLabel2->setText(" UTC dB DT Freq " + tr ("Message"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->decodedTextLabel->setText("UTC dB DT Freq " + tr ("Message"));
|
||||||
|
if (m_mode != "FST240W")
|
||||||
|
{
|
||||||
|
ui->decodedTextLabel2->setText("UTC dB DT Freq " + tr ("Message"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
m_fastGraph->setTRPeriod (value);
|
m_fastGraph->setTRPeriod (value);
|
||||||
m_modulator->setTRPeriod (value); // TODO - not thread safe
|
m_modulator->setTRPeriod (value); // TODO - not thread safe
|
||||||
m_detector->setTRPeriod (value); // TODO - not thread safe
|
m_detector->setTRPeriod (value); // TODO - not thread safe
|
||||||
@ -7727,7 +7745,7 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout
|
|||||||
if(m_nWSPRdecodes==0 and ui->band_hopping_group_box->isChecked()) {
|
if(m_nWSPRdecodes==0 and ui->band_hopping_group_box->isChecked()) {
|
||||||
t = " " + tr ("Receiving") + " " + m_mode + " ----------------------- " +
|
t = " " + tr ("Receiving") + " " + m_mode + " ----------------------- " +
|
||||||
m_config.bands ()->find (m_dialFreqRxWSPR);
|
m_config.bands ()->find (m_dialFreqRxWSPR);
|
||||||
t=WSPR_hhmm(-60) + ' ' + t.rightJustified (66, '-');
|
t=beacon_start_time (-m_TRperiod / 2) + ' ' + t.rightJustified (66, '-');
|
||||||
ui->decodedTextBrowser->appendText(t);
|
ui->decodedTextBrowser->appendText(t);
|
||||||
}
|
}
|
||||||
killFileTimer.start (45*1000); //Kill in 45s (for slow modes)
|
killFileTimer.start (45*1000); //Kill in 45s (for slow modes)
|
||||||
@ -7814,20 +7832,23 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MainWindow::WSPR_hhmm(int n)
|
QString MainWindow::beacon_start_time (int n)
|
||||||
{
|
{
|
||||||
QDateTime t=QDateTime::currentDateTimeUtc().addSecs(n);
|
auto time = QDateTime::currentDateTimeUtc ().addSecs (n).time ();
|
||||||
int m=t.toString("hhmm").toInt()/2;
|
auto rounded_time = (int ((time.hour () * 10000 + time.minute () * 100 + time.second ()) * 60 / m_TRperiod) * int (m_TRperiod)) / 60;
|
||||||
QString t1;
|
auto result = QString::number (rounded_time).rightJustified (6, QLatin1Char {'0'});
|
||||||
t1 = t1.asprintf("%04d",2*m);
|
if (m_TRperiod < 60)
|
||||||
return t1;
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result.left (4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::WSPR_history(Frequency dialFreq, int ndecodes)
|
void MainWindow::WSPR_history(Frequency dialFreq, int ndecodes)
|
||||||
{
|
{
|
||||||
QDateTime t=QDateTime::currentDateTimeUtc().addSecs(-60);
|
QDateTime t=QDateTime::currentDateTimeUtc().addSecs(-60);
|
||||||
QString t1=t.toString("yyMMdd");
|
QString t1=t.toString("yyMMdd");
|
||||||
QString t2=WSPR_hhmm(-60);
|
QString t2=beacon_start_time (-m_TRperiod / 2);
|
||||||
QString t3;
|
QString t3;
|
||||||
t3 = t3.asprintf("%13.6f",0.000001*dialFreq);
|
t3 = t3.asprintf("%13.6f",0.000001*dialFreq);
|
||||||
if(ndecodes<0) {
|
if(ndecodes<0) {
|
||||||
|
@ -728,7 +728,7 @@ private:
|
|||||||
void freqCalStep();
|
void freqCalStep();
|
||||||
void setRig (Frequency = 0); // zero frequency means no change
|
void setRig (Frequency = 0); // zero frequency means no change
|
||||||
void WSPR_history(Frequency dialFreq, int ndecodes);
|
void WSPR_history(Frequency dialFreq, int ndecodes);
|
||||||
QString WSPR_hhmm(int n);
|
QString beacon_start_time (int n = 0);
|
||||||
QString WSPR_message();
|
QString WSPR_message();
|
||||||
void fast_config(bool b);
|
void fast_config(bool b);
|
||||||
void CQTxFreq();
|
void CQTxFreq();
|
||||||
|
Loading…
Reference in New Issue
Block a user