diff --git a/.gitattributes b/.gitattributes index 93434826f..b1e1bbf70 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,5 @@ .gitattributes export-ignore /samples export-ignore /lib/fsk4hf export-ignore +/lib/fsk4hf export-ignore +/robots export-ignore diff --git a/Audio/tools/record_time_signal.cpp b/Audio/tools/record_time_signal.cpp new file mode 100644 index 000000000..6a78a0a2c --- /dev/null +++ b/Audio/tools/record_time_signal.cpp @@ -0,0 +1,397 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "revision_utils.hpp" +#include "Audio/BWFFile.hpp" + +namespace +{ + QTextStream qtout {stdout}; +} + +class Record final + : public QObject +{ + Q_OBJECT; + +public: + Record (int start, int duration, QAudioDeviceInfo const& source_device, BWFFile * output, int notify_interval, int buffer_size) + : source_ {source_device, output->format ()} + , notify_interval_ {notify_interval} + , output_ {output} + , duration_ {duration} + { + if (buffer_size) source_.setBufferSize (output_->format ().bytesForFrames (buffer_size)); + if (notify_interval_) + { + source_.setNotifyInterval (notify_interval); + connect (&source_, &QAudioInput::notify, this, &Record::notify); + } + + if (start == -1) + { + start_recording (); + } + else + { + auto now = QDateTime::currentDateTimeUtc (); + auto time = now.time (); + auto then = now; + then.setTime (QTime {time.hour (), time.minute (), start}); + auto delta_ms = (now.msecsTo (then) + (60 * 1000)) % (60 * 1000); + QTimer::singleShot (int (delta_ms), Qt::PreciseTimer, this, &Record::start_recording); + } + } + + Q_SIGNAL void done (); + +private: + Q_SLOT void start_recording () + { + qtout << "started recording at " << QDateTime::currentDateTimeUtc ().toString ("hh:mm:ss.zzz UTC") << endl; + source_.start (output_); + if (!notify_interval_) QTimer::singleShot (duration_ * 1000, Qt::PreciseTimer, this, &Record::stop_recording); + qtout << QString {"buffer size used is: %1"}.arg (source_.bufferSize ()) << endl; + } + + Q_SLOT void notify () + { + auto length = source_.elapsedUSecs (); + qtout << QString {"%1 μs recorded\r"}.arg (length) << flush; + if (length >= duration_ * 1000 * 1000) stop_recording (); + } + + Q_SLOT void stop_recording () + { + auto length = source_.elapsedUSecs (); + source_.stop (); + qtout << QString {"%1 μs recorded "}.arg (length) << '(' << source_.format ().framesForBytes (output_->size ()) << " frames recorded)\n"; + qtout << "stopped recording at " << QDateTime::currentDateTimeUtc ().toString ("hh:mm:ss.zzz UTC") << endl; + Q_EMIT done (); + } + + QAudioInput source_; + int notify_interval_; + BWFFile * output_; + int duration_; +}; + +class Playback final + : public QObject +{ + Q_OBJECT; + +public: + Playback (int start, BWFFile * input, QAudioDeviceInfo const& sink_device, int notify_interval, int buffer_size, QString const& category) + : input_ {input} + , sink_ {sink_device, input->format ()} + , notify_interval_ {notify_interval} + { + if (buffer_size) sink_.setBufferSize (input_->format ().bytesForFrames (buffer_size)); + if (category.size ()) sink_.setCategory (category); + if (notify_interval_) + { + sink_.setNotifyInterval (notify_interval); + connect (&sink_, &QAudioOutput::notify, this, &Playback::notify); + } + connect (&sink_, &QAudioOutput::stateChanged, this, &Playback::sink_state_changed); + if (start == -1) + { + start_playback (); + } + else + { + auto now = QDateTime::currentDateTimeUtc (); + auto time = now.time (); + auto then = now; + then.setTime (QTime {time.hour (), time.minute (), start}); + auto delta_ms = (now.msecsTo (then) + (60 * 1000)) % (60 * 1000); + QTimer::singleShot (int (delta_ms), Qt::PreciseTimer, this, &Playback::start_playback); + } + } + + Q_SIGNAL void done (); + +private: + Q_SLOT void start_playback () + { + qtout << "started playback at " << QDateTime::currentDateTimeUtc ().toString ("hh:mm:ss.zzz UTC") << endl; + sink_.start (input_); + qtout << QString {"buffer size used is: %1 (%2 frames)"}.arg (sink_.bufferSize ()).arg (sink_.format ().framesForBytes (sink_.bufferSize ())) << endl; + } + + Q_SLOT void notify () + { + auto length = sink_.elapsedUSecs (); + qtout << QString {"%1 μs rendered\r"}.arg (length) << flush; + } + + Q_SLOT void sink_state_changed (QAudio::State state) + { + switch (state) + { + case QAudio::ActiveState: + qtout << "\naudio output state changed to active\n"; + break; + case QAudio::SuspendedState: + qtout << "\naudio output state changed to suspended\n"; + break; + case QAudio::StoppedState: + qtout << "\naudio output state changed to stopped\n"; + break; + case QAudio::IdleState: + stop_playback (); + qtout << "\naudio output state changed to idle\n"; + break; +#if QT_VERSION >= QT_VERSION_CHECK (5, 10, 0) + case QAudio::InterruptedState: + qtout << "\naudio output state changed to interrupted\n"; + break; +#endif + } + } + + Q_SLOT void stop_playback () + { + auto length = sink_.elapsedUSecs (); + sink_.stop (); + qtout << QString {"%1 μs rendered "}.arg (length) << '(' << sink_.format ().framesForBytes (input_->size ()) << " frames rendered)\n"; + qtout << "stopped playback at " << QDateTime::currentDateTimeUtc ().toString ("hh:mm:ss.zzz UTC") << endl; + Q_EMIT done (); + } + + BWFFile * input_; + QAudioOutput sink_; + int notify_interval_; +}; + +#include "record_time_signal.moc" + +int main(int argc, char *argv[]) +{ + QCoreApplication app {argc, argv}; + try + { + ::setlocale (LC_NUMERIC, "C"); // ensure number forms are in + // consistent format, do this + // after instantiating + // QApplication so that Qt has + // correct l18n + + // Override programs executable basename as application name. + app.setApplicationName ("WSJT-X Record Time Signal"); + app.setApplicationVersion (version ()); + + QCommandLineParser parser; + parser.setApplicationDescription ( + "\nTool to determine and experiment with QAudioInput latencies\n\n" + "\tUse the -I option to list available recording device numbers\n" + ); + auto help_option = parser.addHelpOption (); + auto version_option = parser.addVersionOption (); + + parser.addOptions ({ + {{"I", "list-audio-inputs"}, + app.translate ("main", "List the available audio input devices")}, + {{"O", "list-audio-outputs"}, + app.translate ("main", "List the available audio output devices")}, + {{"s", "start-time"}, + app.translate ("main", "Record from seconds, default start immediately"), + app.translate ("main", "start-time")}, + {{"d", "duration"}, + app.translate ("main", "Recording seconds"), + app.translate ("main", "duration")}, + {{"o", "output"}, + app.translate ("main", "Save output as "), + app.translate ("main", "output-file")}, + {{"i", "input"}, + app.translate ("main", "Playback "), + app.translate ("main", "input-file")}, + {{"f", "force"}, + app.translate ("main", "Overwrite existing file")}, + {{"r", "sample-rate"}, + app.translate ("main", "Record at , default 48000 Hz"), + app.translate ("main", "sample-rate")}, + {{"c", "num-channels"}, + app.translate ("main", "Record channels, default 2"), + app.translate ("main", "num")}, + {{"R", "recording-device-number"}, + app.translate ("main", "Record from "), + app.translate ("main", "device-number")}, + {{"P", "playback-device-number"}, + app.translate ("main", "Playback to "), + app.translate ("main", "device-number")}, + {{"C", "category"}, + app.translate ("main", "Playback "), + app.translate ("main", "category-name")}, + {{"n", "notify-interval"}, + app.translate ("main", "use notify signals every milliseconds, zero to use a timer"), + app.translate ("main", "interval")}, + {{"b", "buffer-size"}, + app.translate ("main", "audio buffer size "), + app.translate ("main", "frames")}, + }); + parser.process (app); + + auto input_devices = QAudioDeviceInfo::availableDevices (QAudio::AudioInput); + if (parser.isSet ("I")) + { + int n {0}; + for (auto const& device : input_devices) + { + qtout << ++n << " - [" << device.deviceName () << ']' << endl; + } + return 0; + } + + auto output_devices = QAudioDeviceInfo::availableDevices (QAudio::AudioOutput); + if (parser.isSet ("O")) + { + int n {0}; + for (auto const& device : output_devices) + { + qtout << ++n << " - [" << device.deviceName () << ']' << endl; + } + return 0; + } + + bool ok; + int start {-1}; + if (parser.isSet ("s")) + { + start = parser.value ("s").toInt (&ok); + if (!ok) throw std::invalid_argument {"start time not a number"}; + if (0 > start || start > 59) throw std::invalid_argument {"0 > start > 59"}; + } + int sample_rate {48000}; + if (parser.isSet ("r")) + { + sample_rate = parser.value ("r").toInt (&ok); + if (!ok) throw std::invalid_argument {"sample rate not a number"}; + } + int num_channels {2}; + if (parser.isSet ("c")) + { + num_channels = parser.value ("c").toInt (&ok); + if (!ok) throw std::invalid_argument {"channel count not a number"}; + } + int notify_interval {0}; + if (parser.isSet ("n")) + { + notify_interval = parser.value ("n").toInt (&ok); + if (!ok) throw std::invalid_argument {"notify interval not a number"}; + } + int buffer_size {0}; + if (parser.isSet ("b")) + { + buffer_size = parser.value ("b").toInt (&ok); + if (!ok) throw std::invalid_argument {"buffer size not a number"}; + } + int input_device {0}; + if (parser.isSet ("R")) + { + input_device = parser.value ("R").toInt (&ok); + if (!ok || 0 >= input_device || input_device > input_devices.size ()) + { + throw std::invalid_argument {"invalid recording device"}; + } + } + int output_device {0}; + if (parser.isSet ("P")) + { + output_device = parser.value ("P").toInt (&ok); + if (!ok || 0 >= output_device || output_device > output_devices.size ()) + { + throw std::invalid_argument {"invalid playback device"}; + } + } + if (!(parser.isSet ("o") || parser.isSet ("i"))) throw std::invalid_argument {"file required"}; + if (parser.isSet ("o") && parser.isSet ("i")) throw std::invalid_argument {"specify either input or output"}; + + QAudioFormat audio_format; + if (parser.isSet ("o")) // Record + { + int duration = parser.value ("d").toInt (&ok); + if (!ok) throw std::invalid_argument {"duration not a number"}; + + QFileInfo ofi {parser.value ("o")}; + if (!ofi.suffix ().size () && ofi.fileName ()[ofi.fileName ().size () - 1] != QChar {'.'}) + { + ofi.setFile (ofi.filePath () + ".wav"); + } + if (!parser.isSet ("f") && ofi.isFile ()) + { + throw std::invalid_argument {"set the `-force' option to overwrite an existing output file"}; + } + + audio_format.setSampleRate (sample_rate); + audio_format.setChannelCount (num_channels); + audio_format.setSampleSize (16); + audio_format.setSampleType (QAudioFormat::SignedInt); + audio_format.setCodec ("audio/pcm"); + + auto source = input_device ? input_devices[input_device - 1] : QAudioDeviceInfo::defaultInputDevice (); + if (!source.isFormatSupported (audio_format)) + { + qtout << "warning, requested format not supported, using nearest" << endl; + audio_format = source.nearestFormat (audio_format); + } + BWFFile output_file {audio_format, ofi.filePath ()}; + if (!output_file.open (BWFFile::WriteOnly)) throw std::invalid_argument {QString {"cannot open output file \"%1\""}.arg (ofi.filePath ()).toStdString ()}; + + // run the application + Record record {start, duration, source, &output_file, notify_interval, buffer_size}; + QObject::connect (&record, &Record::done, &app, &QCoreApplication::quit); + return app.exec(); + } + else // Playback + { + QFileInfo ifi {parser.value ("i")}; + if (!ifi.isFile () && !ifi.suffix ().size () && ifi.fileName ()[ifi.fileName ().size () - 1] != QChar {'.'}) + { + ifi.setFile (ifi.filePath () + ".wav"); + } + BWFFile input_file {audio_format, ifi.filePath ()}; + if (!input_file.open (BWFFile::ReadOnly)) throw std::invalid_argument {QString {"cannot open input file \"%1\""}.arg (ifi.filePath ()).toStdString ()}; + auto sink = output_device ? output_devices[output_device - 1] : QAudioDeviceInfo::defaultOutputDevice (); + if (!sink.isFormatSupported (input_file.format ())) + { + throw std::invalid_argument {"audio output device does not support input file audio format"}; + } + + // run the application + Playback play {start, &input_file, sink, notify_interval, buffer_size, parser.value ("category")}; + QObject::connect (&play, &Playback::done, &app, &QCoreApplication::quit); + return app.exec(); + } + } + catch (std::exception const& e) + { + std::cerr << "Error: " << e.what () << '\n'; + } + catch (...) + { + std::cerr << "Unexpected fatal error\n"; + throw; // hoping the runtime might tell us more about the exception + } + return -1; +} diff --git a/CMake/Modules/Findhamlib.cmake b/CMake/Modules/Findhamlib.cmake index 98419bda1..234083ae1 100644 --- a/CMake/Modules/Findhamlib.cmake +++ b/CMake/Modules/Findhamlib.cmake @@ -19,9 +19,12 @@ find_path (__hamlib_pc_path NAMES hamlib.pc PATH_SUFFIXES lib/pkgconfig lib64/pkgconfig ) if (__hamlib_pc_path) - set (ENV{PKG_CONFIG_PATH} "${__hamlib_pc_path}" "$ENV{PKG_CONFIG_PATH}") - unset (__hamlib_pc_path CACHE) + set (__pc_path $ENV{PKG_CONFIG_PATH}) + list (APPEND __pc_path "${__hamlib_pc_path}") + set (ENV{PKG_CONFIG_PATH} "${__pc_path}") + unset (__pc_path CACHE) endif () +unset (__hamlib_pc_path CACHE) # Use pkg-config to get hints about paths, libs and, flags unset (__pkg_config_checked_hamlib CACHE) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d39c437d..0c10ff8d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,10 @@ if (POLICY CMP0063) cmake_policy (SET CMP0063 NEW) # honour visibility properties for all library types endif (POLICY CMP0063) +if (POLICY CMP0071) + cmake_policy (SET CMP0071 NEW) # run automoc and autouic on generated sources +endif (POLICY CMP0071) + include (${PROJECT_SOURCE_DIR}/CMake/VersionCompute.cmake) message (STATUS "Building ${CMAKE_PROJECT_NAME}-${wsjtx_VERSION}") @@ -233,6 +237,7 @@ set (wsjt_qt_CXXSRCS models/FrequencyList.cpp models/StationList.cpp widgets/FrequencyLineEdit.cpp + widgets/FrequencyDeltaLineEdit.cpp item_delegates/CandidateKeyFilter.cpp item_delegates/ForeignKeyDelegate.cpp validators/LiveFrequencyValidator.cpp @@ -275,9 +280,12 @@ set (wsjt_qt_CXXSRCS widgets/CabrilloLogWindow.cpp item_delegates/CallsignDelegate.cpp item_delegates/MaidenheadLocatorDelegate.cpp + item_delegates/FrequencyDelegate.cpp + item_delegates/FrequencyDeltaDelegate.cpp models/CabrilloLog.cpp logbook/AD1CCty.cpp logbook/WorkedBefore.cpp + logbook/Multiplier.cpp ) set (wsjt_qtmm_CXXSRCS @@ -383,9 +391,11 @@ set (wsjt_FSRCS lib/astro0.f90 lib/avecho.f90 lib/averms.f90 + lib/ft4/averaged_mf.f90 lib/azdist.f90 lib/badmsg.f90 lib/ft8/baseline.f90 + lib/ft4/ft4_baseline.f90 lib/bpdecode40.f90 lib/bpdecode128_90.f90 lib/ft8/bpdecode174_91.f90 @@ -518,7 +528,6 @@ set (wsjt_FSRCS lib/msk144sim.f90 lib/mskrtd.f90 lib/nuttal_window.f90 - lib/ft4/ft4b.f90 lib/ft4/ft4sim.f90 lib/ft4/ft4sim_mult.f90 lib/ft4/ft4_downsample.f90 @@ -555,6 +564,7 @@ set (wsjt_FSRCS lib/stdmsg.f90 lib/subtract65.f90 lib/ft8/subtractft8.f90 + lib/ft4/subtractft4.f90 lib/sun.f90 lib/symspec.f90 lib/symspec2.f90 @@ -563,7 +573,7 @@ set (wsjt_FSRCS lib/sync64.f90 lib/sync65.f90 lib/ft4/getcandidates4.f90 - lib/ft4/syncft4.f90 + lib/ft4/get_ft4_bitmetrics.f90 lib/ft8/sync8.f90 lib/ft8/sync8d.f90 lib/ft4/sync4d.f90 @@ -846,9 +856,6 @@ if (Boost_NO_SYSTEM_PATHS) set (BOOST_ROOT ${PROJECT_SOURCE_DIR}/boost) endif () find_package (Boost 1.63 REQUIRED) -if (Boost_FOUND) - include_directories (${Boost_INCLUDE_DIRS}) -endif () # # OpenMP @@ -879,10 +886,7 @@ message (STATUS "hamlib_LIBRARY_DIRS: ${hamlib_LIBRARY_DIRS}") # # Widgets finds its own dependencies. -find_package (Qt5Widgets 5 REQUIRED) -find_package (Qt5Multimedia 5 REQUIRED) -find_package (Qt5PrintSupport 5 REQUIRED) -find_package (Qt5Sql 5 REQUIRED) +find_package (Qt5 REQUIRED Widgets Multimedia PrintSupport Sql LinguistTools) if (WIN32) add_definitions (-DQT_NEEDS_QTMAIN) @@ -1088,11 +1092,41 @@ add_custom_target (ctags COMMAND ${CTAGS} -o ${CMAKE_SOURCE_DIR}/tags -R ${sourc add_custom_target (etags COMMAND ${ETAGS} -o ${CMAKE_SOURCE_DIR}/TAGS -R ${sources}) +# Qt i18n +set (LANGUAGES + en_GB + pt_PT + ) +foreach (lang_ ${LANGUAGES}) + file (TO_NATIVE_PATH translations/wsjtx_${lang_}.ts ts_) + list (APPEND TS_FILES ${ts_}) +endforeach () +if (UPDATE_TRANSLATIONS) + message (STATUS "UPDATE_TRANSLATIONS option is set.") + qt5_create_translation ( + QM_FILES ${wsjt_qt_UISRCS} ${wsjtx_UISRCS} ${wsjt_qt_CXXSRCS} ${wsjtx_CXXSRCS} + ${TS_FILES} + ) +else () + qt5_add_translation (QM_FILES ${TS_FILES}) +endif () +add_custom_target (translations DEPENDS ${QM_FILES}) +set_property (DIRECTORY PROPERTY CLEAN_NO_CUSTOM TRUE) +# do this after i18n to stop lupdate walking the boost tree which it +# chokes on +if (Boost_FOUND) + include_directories (${Boost_INCLUDE_DIRS}) +endif () + # embedded resources function (add_resources resources path) foreach (resource_file_ ${ARGN}) get_filename_component (name_ ${resource_file_} NAME) - file (TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${resource_file_} source_) + if (IS_ABSOLUTE "${resource_file_}") + file (TO_NATIVE_PATH ${resource_file_} source_) + else () + file (TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${resource_file_} source_) + endif () file (TO_NATIVE_PATH ${path}/${name_} dest_) set (resources_ "${resources_}\n ${source_}") set (${resources} ${${resources}}${resources_} PARENT_SCOPE) @@ -1101,6 +1135,7 @@ endfunction (add_resources resources path) add_resources (wsjtx_RESOURCES "" ${TOP_LEVEL_RESOURCES}) add_resources (wsjtx_RESOURCES /Palettes ${PALETTE_FILES}) +add_resources (wsjtx_RESOURCES /Translations ${QM_FILES}) configure_file (wsjtx.qrc.in wsjtx.qrc @ONLY) @@ -1121,7 +1156,6 @@ if (WIN32) wrap_ax_server (GENAXSRCS ${AXSERVERSRCS}) endif (WIN32) - # # targets # @@ -1240,6 +1274,9 @@ target_link_libraries (jt49sim wsjt_fort wsjt_cxx) add_executable (allsim lib/allsim.f90 wsjtx.rc) target_link_libraries (allsim wsjt_fort wsjt_cxx) +add_executable (rtty_spec lib/rtty_spec.f90 wsjtx.rc) +target_link_libraries (rtty_spec wsjt_fort wsjt_cxx) + add_executable (jt65code lib/jt65code.f90 wsjtx.rc) target_link_libraries (jt65code wsjt_fort wsjt_cxx) @@ -1282,11 +1319,14 @@ target_link_libraries (msk144sim wsjt_fort wsjt_cxx) add_executable (ft4sim lib/ft4/ft4sim.f90 wsjtx.rc) target_link_libraries (ft4sim wsjt_fort wsjt_cxx) +add_executable (averaged_mf lib/ft4/averaged_mf.f90 wsjtx.rc) +target_link_libraries (averaged_mf wsjt_fort wsjt_cxx) + add_executable (ft4sim_mult lib/ft4/ft4sim_mult.f90 wsjtx.rc) target_link_libraries (ft4sim_mult wsjt_fort wsjt_cxx) -add_executable (ft4d lib/ft4/ft4d.f90 wsjtx.rc) -target_link_libraries (ft4d wsjt_fort wsjt_cxx) +add_executable (record_time_signal Audio/tools/record_time_signal.cpp) +target_link_libraries (record_time_signal wsjt_cxx wsjt_qtmm wsjt_qt) endif(WSJT_BUILD_UTILS) diff --git a/Configuration.cpp b/Configuration.cpp index cce8db23c..ebb6380b3 100644 --- a/Configuration.cpp +++ b/Configuration.cpp @@ -167,8 +167,11 @@ #include "MetaDataRegistry.hpp" #include "SettingsGroup.hpp" #include "widgets/FrequencyLineEdit.hpp" +#include "widgets/FrequencyDeltaLineEdit.hpp" #include "item_delegates/CandidateKeyFilter.hpp" #include "item_delegates/ForeignKeyDelegate.hpp" +#include "item_delegates/FrequencyDelegate.hpp" +#include "item_delegates/FrequencyDeltaDelegate.hpp" #include "TransceiverFactory.hpp" #include "Transceiver.hpp" #include "models/Bands.hpp" @@ -248,6 +251,8 @@ namespace class FrequencyDialog final : public QDialog { + Q_OBJECT + public: using Item = FrequencyList_v2::Item; @@ -294,6 +299,8 @@ private: class StationDialog final : public QDialog { + Q_OBJECT + public: explicit StationDialog (StationList const * stations, Bands * bands, QWidget * parent = nullptr) : QDialog {parent} @@ -564,6 +571,7 @@ private: DecodeHighlightingModel decode_highlighing_model_; DecodeHighlightingModel next_decode_highlighing_model_; bool highlight_by_mode_; + bool include_WAE_entities_; int LotW_days_since_upload_; TransceiverFactory::ParameterPack rig_params_; @@ -609,6 +617,7 @@ private: bool miles_; bool quick_call_; bool disable_TX_on_73_; + bool force_call_1st_; bool alternate_bindings_; int watchdog_; bool TX_messages_; @@ -705,6 +714,7 @@ bool Configuration::clear_DX () const {return m_->clear_DX_;} bool Configuration::miles () const {return m_->miles_;} bool Configuration::quick_call () const {return m_->quick_call_;} bool Configuration::disable_TX_on_73 () const {return m_->disable_TX_on_73_;} +bool Configuration::force_call_1st() const {return m_->force_call_1st_;} bool Configuration::alternate_bindings() const {return m_->alternate_bindings_;} int Configuration::watchdog () const {return m_->watchdog_;} bool Configuration::TX_messages () const {return m_->TX_messages_;} @@ -716,6 +726,7 @@ bool Configuration::x2ToneSpacing() const {return m_->x2ToneSpacing_;} bool Configuration::x4ToneSpacing() const {return m_->x4ToneSpacing_;} bool Configuration::split_mode () const {return m_->split_mode ();} QString Configuration::opCall() const {return m_->opCall_;} +void Configuration::opCall (QString const& call) {m_->opCall_ = call;} QString Configuration::udp_server_name () const {return m_->udp_server_name_;} auto Configuration::udp_server_port () const -> port_type {return m_->udp_server_port_;} bool Configuration::accept_udp_requests () const {return m_->accept_udp_requests_;} @@ -742,6 +753,7 @@ bool Configuration::pwrBandTuneMemory () const {return m_->pwrBandTuneMemory_;} LotWUsers const& Configuration::lotw_users () const {return m_->lotw_users_;} DecodeHighlightingModel const& Configuration::decode_highlighting () const {return m_->decode_highlighing_model_;} bool Configuration::highlight_by_mode () const {return m_->highlight_by_mode_;} +bool Configuration::include_WAE_entities () const {return m_->include_WAE_entities_;} void Configuration::set_calibration (CalibrationParams params) { @@ -947,6 +959,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network , station_insert_action_ {tr ("&Insert ..."), nullptr} , station_dialog_ {new StationDialog {&next_stations_, &bands_, this}} , highlight_by_mode_ {false} + , include_WAE_entities_ {false} , LotW_days_since_upload_ {0} , last_port_type_ {TransceiverFactory::Capabilities::none} , rig_is_dummy_ {false} @@ -1116,9 +1129,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network ui_->frequencies_table_view->setColumnHidden (FrequencyList_v2::frequency_mhz_column, true); // delegates - auto frequencies_item_delegate = new QStyledItemDelegate {this}; - frequencies_item_delegate->setItemEditorFactory (item_editor_factory ()); - ui_->frequencies_table_view->setItemDelegate (frequencies_item_delegate); + ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::frequency_column, new FrequencyDelegate {this}); ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::region_column, new ForeignKeyDelegate {®ions_, 0, this}); ui_->frequencies_table_view->setItemDelegateForColumn (FrequencyList_v2::mode_column, new ForeignKeyDelegate {&modes_, 0, this}); @@ -1157,9 +1168,7 @@ Configuration::impl::impl (Configuration * self, QNetworkAccessManager * network ui_->stations_table_view->sortByColumn (StationList::band_column, Qt::AscendingOrder); // stations delegates - auto stations_item_delegate = new QStyledItemDelegate {this}; - stations_item_delegate->setItemEditorFactory (item_editor_factory ()); - ui_->stations_table_view->setItemDelegate (stations_item_delegate); + ui_->stations_table_view->setItemDelegateForColumn (StationList::offset_column, new FrequencyDeltaDelegate {this}); ui_->stations_table_view->setItemDelegateForColumn (StationList::band_column, new ForeignKeyDelegate {&bands_, &next_stations_, 0, StationList::band_column, this}); // stations actions @@ -1242,6 +1251,7 @@ void Configuration::impl::initialize_models () ui_->miles_check_box->setChecked (miles_); ui_->quick_call_check_box->setChecked (quick_call_); ui_->disable_TX_on_73_check_box->setChecked (disable_TX_on_73_); + ui_->force_call_1st_check_box->setChecked (force_call_1st_); ui_->alternate_bindings_check_box->setChecked (alternate_bindings_); ui_->tx_watchdog_spin_box->setValue (watchdog_); ui_->TX_messages_check_box->setChecked (TX_messages_); @@ -1315,6 +1325,7 @@ void Configuration::impl::initialize_models () next_decode_highlighing_model_.items (decode_highlighing_model_.items ()); ui_->highlight_by_mode_check_box->setChecked (highlight_by_mode_); + ui_->include_WAE_check_box->setChecked (include_WAE_entities_); ui_->LotW_days_since_upload_spin_box->setValue (LotW_days_since_upload_); set_rig_invariants (); @@ -1463,6 +1474,7 @@ void Configuration::impl::read_settings () if (!highlight_items.size ()) highlight_items = DecodeHighlightingModel::default_items (); decode_highlighing_model_.items (highlight_items); highlight_by_mode_ = settings_->value("HighlightByMode", false).toBool (); + include_WAE_entities_ = settings_->value("IncludeWAEEntities", false).toBool (); LotW_days_since_upload_ = settings_->value ("LotWDaysSinceLastUpload", 365).toInt (); lotw_users_.set_age_constraint (LotW_days_since_upload_); @@ -1496,6 +1508,7 @@ void Configuration::impl::read_settings () miles_ = settings_->value ("Miles", false).toBool (); quick_call_ = settings_->value ("QuickCall", false).toBool (); disable_TX_on_73_ = settings_->value ("73TxDisable", false).toBool (); + force_call_1st_ = settings_->value ("ForceCallFirst", false).toBool (); alternate_bindings_ = settings_->value ("AlternateBindings", false).toBool (); watchdog_ = settings_->value ("TxWatchdog", 6).toInt (); TX_messages_ = settings_->value ("Tx2QSO", true).toBool (); @@ -1575,6 +1588,7 @@ void Configuration::impl::write_settings () settings_->setValue ("stations", QVariant::fromValue (stations_.station_list ())); settings_->setValue ("DecodeHighlighting", QVariant::fromValue (decode_highlighing_model_.items ())); settings_->setValue ("HighlightByMode", highlight_by_mode_); + settings_->setValue ("IncludeWAEEntities", include_WAE_entities_); settings_->setValue ("LotWDaysSinceLastUpload", LotW_days_since_upload_); settings_->setValue ("toRTTY", log_as_RTTY_); settings_->setValue ("dBtoComments", report_in_comments_); @@ -1598,6 +1612,7 @@ void Configuration::impl::write_settings () settings_->setValue ("Miles", miles_); settings_->setValue ("QuickCall", quick_call_); settings_->setValue ("73TxDisable", disable_TX_on_73_); + settings_->setValue ("ForceCallFirst", force_call_1st_); settings_->setValue ("AlternateBindings", alternate_bindings_); settings_->setValue ("TxWatchdog", watchdog_); settings_->setValue ("Tx2QSO", TX_messages_); @@ -2042,6 +2057,7 @@ void Configuration::impl::accept () miles_ = ui_->miles_check_box->isChecked (); quick_call_ = ui_->quick_call_check_box->isChecked (); disable_TX_on_73_ = ui_->disable_TX_on_73_check_box->isChecked (); + force_call_1st_ = ui_->force_call_1st_check_box->isChecked (); alternate_bindings_ = ui_->alternate_bindings_check_box->isChecked (); watchdog_ = ui_->tx_watchdog_spin_box->value (); TX_messages_ = ui_->TX_messages_check_box->isChecked (); @@ -2076,7 +2092,12 @@ void Configuration::impl::accept () Q_EMIT self_->udp_server_port_changed (new_port); } - accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked (); + if (ui_->accept_udp_requests_check_box->isChecked () != accept_udp_requests_) + { + accept_udp_requests_ = ui_->accept_udp_requests_check_box->isChecked (); + Q_EMIT self_->accept_udp_requests_changed (accept_udp_requests_); + } + n1mm_server_name_ = ui_->n1mm_server_name_line_edit->text (); n1mm_server_port_ = ui_->n1mm_server_port_spin_box->value (); broadcast_to_n1mm_ = ui_->enable_n1mm_broadcast_check_box->isChecked (); @@ -2109,6 +2130,7 @@ void Configuration::impl::accept () Q_EMIT self_->decode_highlighting_changed (decode_highlighing_model_); } highlight_by_mode_ = ui_->highlight_by_mode_check_box->isChecked (); + include_WAE_entities_ = ui_->include_WAE_check_box->isChecked (); LotW_days_since_upload_ = ui_->LotW_days_since_upload_spin_box->value (); lotw_users_.set_age_constraint (LotW_days_since_upload_); diff --git a/Configuration.hpp b/Configuration.hpp index 991e126fb..dbf232fd5 100644 --- a/Configuration.hpp +++ b/Configuration.hpp @@ -127,6 +127,7 @@ public: bool miles () const; bool quick_call () const; bool disable_TX_on_73 () const; + bool force_call_1st() const; bool alternate_bindings() const; int watchdog () const; bool TX_messages () const; @@ -147,6 +148,7 @@ public: bool EMEonly() const; bool post_decodes () const; QString opCall() const; + void opCall (QString const&); QString udp_server_name () const; port_type udp_server_port () const; QString n1mm_server_name () const; @@ -175,6 +177,7 @@ public: LotWUsers const& lotw_users () const; DecodeHighlightingModel const& decode_highlighting () const; bool highlight_by_mode () const; + bool include_WAE_entities () const; enum class SpecialOperatingActivity {NONE, NA_VHF, EU_VHF, FIELD_DAY, RTTY, FOX, HOUND}; SpecialOperatingActivity special_op_id () const; @@ -268,6 +271,7 @@ public: // Q_SIGNAL void udp_server_changed (QString const& udp_server) const; Q_SIGNAL void udp_server_port_changed (port_type server_port) const; + Q_SIGNAL void accept_udp_requests_changed (bool checked) const; // signal updates to decode highlighting Q_SIGNAL void decode_highlighting_changed (DecodeHighlightingModel const&) const; diff --git a/Configuration.ui b/Configuration.ui index a8f36797c..a9fe51d45 100644 --- a/Configuration.ui +++ b/Configuration.ui @@ -7,7 +7,7 @@ 0 0 546 - 536 + 553 @@ -301,7 +301,14 @@ Behavior - + + + + Decode after EME delay + + + + @@ -347,10 +354,27 @@ - - + + - Decode after EME delay + Enable VHF/UHF/Microwave features + + + + + + + Single decode + + + + + + + <html><head/><body><p>Some rigs are not able to process CAT commands while transmitting. This means that if you are operating in split mode you may have to uncheck this option.</p></body></html> + + + Allow Tx frequency changes while transmitting @@ -367,31 +391,35 @@ - - - - Single decode - - - - - - - Enable VHF/UHF/Microwave features - - - - - + + - <html><head/><body><p>Some rigs are not able to process CAT commands while transmitting. This means that if you are operating in split mode you may have to uncheck this option.</p></body></html> + <html><head/><body><p>Check this if you wish to automatically return to the last monitored frequency when monitor is enabled, leave it unchecked if you wish to have the current rig frequency maintained.</p></body></html> - Allow Tx frequency changes while transmitting + Monitor returns to last used frequency - + + + + Alternate F1-F6 bindings + + + + + + + Turns off automatic transmissions after sending a 73 or any other free +text message. + + + Di&sable Tx after sending 73 + + + + @@ -444,34 +472,6 @@ quiet period when decoding is done. - - - - <html><head/><body><p>Check this if you wish to automatically return to the last monitored frequency when monitor is enabled, leave it unchecked if you wish to have the current rig frequency maintained.</p></body></html> - - - Monitor returns to last used frequency - - - - - - - Alternate F1-F5 bindings - - - - - - - Turns off automatic transmissions after sending a 73 or any other free -text message. - - - Di&sable Tx after sending 73 - - - @@ -482,6 +482,13 @@ text message. + + + + Calling CQ forces Call 1st + + + @@ -1912,7 +1919,7 @@ for assessing propagation and system performance. - N1MM Logger+ Broadcasts + Secondary UDP Server (deprecated) @@ -1928,7 +1935,7 @@ for assessing propagation and system performance. - <html><head/><body><p>N1MM Server name or IP address:</p></body></html> + Server name or IP address: n1mm_server_name_line_edit @@ -1945,7 +1952,7 @@ for assessing propagation and system performance. - <html><head/><body><p>N1MM Server port number:</p></body></html> + Server port number: n1mm_server_port_spin_box @@ -2287,6 +2294,23 @@ Right click for insert and delete options. + + + + + + + + + Include extra WAE entities + + + include_WAE_check_box + + + + + @@ -2299,35 +2323,6 @@ Right click for insert and delete options. Logbook of the World User Validation - - - - Age of last upload less than: - - - LotW_days_since_upload_spin_box - - - - - - - <html><head/><body><p>Adjust this spin box to set the age threshold of LotW user's last upload date that is accepted as a current LotW user.</p></body></html> - - - days - - - 0 - - - 9999 - - - 365 - - - @@ -2362,6 +2357,35 @@ Right click for insert and delete options. + + + + Age of last upload less than: + + + LotW_days_since_upload_spin_box + + + + + + + <html><head/><body><p>Adjust this spin box to set the age threshold of LotW user's last upload date that is accepted as a current LotW user.</p></body></html> + + + days + + + 0 + + + 9999 + + + 365 + + + @@ -2469,7 +2493,7 @@ Right click for insert and delete options. - Special operating activity: Generation of FT8 and MSK144 messages + Special operating activity: Generation of FT4, FT8, and MSK144 messages true @@ -2556,7 +2580,7 @@ Right click for insert and delete options. <html><head/><body><p>ARRL RTTY Roundup and similar contests. Exchange is US state, Canadian province, or &quot;DX&quot;.</p></body></html> - ARRL RTTY Roundup + RTTY Roundup messages special_op_activity_button_group @@ -3079,12 +3103,12 @@ Right click for insert and delete options. - - - - + + + + diff --git a/DXLabSuiteCommanderTransceiver.cpp b/DXLabSuiteCommanderTransceiver.cpp index 4e9270cfe..d745ec17f 100644 --- a/DXLabSuiteCommanderTransceiver.cpp +++ b/DXLabSuiteCommanderTransceiver.cpp @@ -127,7 +127,7 @@ int DXLabSuiteCommanderTransceiver::do_start () throw error {tr ("DX Lab Suite Commander didn't respond correctly reading frequency: ") + reply}; } - poll (); + do_poll (); return resolution; } @@ -247,7 +247,7 @@ void DXLabSuiteCommanderTransceiver::do_mode (MODE m) update_mode (m); } -void DXLabSuiteCommanderTransceiver::poll () +void DXLabSuiteCommanderTransceiver::do_poll () { #if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS bool quiet {false}; diff --git a/DXLabSuiteCommanderTransceiver.hpp b/DXLabSuiteCommanderTransceiver.hpp index b02fbef12..1196678b8 100644 --- a/DXLabSuiteCommanderTransceiver.hpp +++ b/DXLabSuiteCommanderTransceiver.hpp @@ -39,7 +39,7 @@ protected: void do_mode (MODE) override; void do_ptt (bool on) override; - void poll () override; + void do_poll () override; private: MODE get_mode (bool no_debug = false); diff --git a/Darwin/Info.plist.in b/Darwin/Info.plist.in index 830975da5..d2e943fe5 100644 --- a/Darwin/Info.plist.in +++ b/Darwin/Info.plist.in @@ -38,5 +38,7 @@ True NSRequiresAquaSystemAppearance + NSMicrophoneUsageDescription + This app requires microphone access to receive signals. diff --git a/Detector.cpp b/Detector.cpp index 69a10f5e8..05a631b13 100644 --- a/Detector.cpp +++ b/Detector.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "commons.h" #include "moc_Detector.cpp" @@ -10,7 +11,7 @@ extern "C" { void fil4_(qint16*, qint32*, qint16*, qint32*); } -Detector::Detector (unsigned frameRate, unsigned periodLengthInSeconds, +Detector::Detector (unsigned frameRate, double periodLengthInSeconds, unsigned downSampleFactor, QObject * parent) : AudioDevice (parent) , m_frameRate (frameRate) @@ -54,12 +55,14 @@ void Detector::clear () qint64 Detector::writeData (char const * data, qint64 maxSize) { - int ns=secondInPeriod(); - if(ns < m_ns) { // When ns has wrapped around to zero, restart the buffers + static unsigned mstr0=999999; + qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000; + unsigned mstr = ms0 % int(1000.0*m_period); // ms into the nominal Tx start time + if(mstr < mstr0) { //When mstr has wrapped around to 0, restart the buffer dec_data.params.kin = 0; m_bufferPos = 0; } - m_ns=ns; + mstr0=mstr; // no torn frames Q_ASSERT (!(maxSize % static_cast (bytesPerFrame ()))); @@ -72,7 +75,7 @@ qint64 Detector::writeData (char const * data, qint64 maxSize) if (framesAccepted < static_cast (maxSize / bytesPerFrame ())) { qDebug () << "dropped " << maxSize / bytesPerFrame () - framesAccepted << " frames of data on the floor!" - << dec_data.params.kin << ns; + << dec_data.params.kin << mstr; } for (unsigned remaining = framesAccepted; remaining; ) { @@ -120,13 +123,3 @@ qint64 Detector::writeData (char const * data, qint64 maxSize) return maxSize; // we drop any data past the end of the buffer on // the floor until the next period starts } - -unsigned Detector::secondInPeriod () const -{ - // we take the time of the data as the following assuming no latency - // delivering it to us (not true but close enough for us) - qint64 now (QDateTime::currentMSecsSinceEpoch ()); - - unsigned secondInToday ((now % 86400000LL) / 1000); - return secondInToday % m_period; -} diff --git a/Detector.hpp b/Detector.hpp index d5e5b0a38..4d584c130 100644 --- a/Detector.hpp +++ b/Detector.hpp @@ -22,9 +22,10 @@ public: // // the samplesPerFFT argument is the number after down sampling // - Detector (unsigned frameRate, unsigned periodLengthInSeconds, unsigned downSampleFactor = 4u, QObject * parent = 0); + Detector (unsigned frameRate, double periodLengthInSeconds, unsigned downSampleFactor = 4u, + QObject * parent = 0); - void setTRPeriod(unsigned p) {m_period=p;} + void setTRPeriod(double p) {m_period=p;} bool reset () override; Q_SIGNAL void framesWritten (qint64) const; @@ -40,10 +41,9 @@ protected: private: void clear (); // discard buffer contents - unsigned secondInPeriod () const; unsigned m_frameRate; - unsigned m_period; + double m_period; unsigned m_downSampleFactor; qint32 m_samplesPerFFT; // after any down sampling qint32 m_ns; diff --git a/EmulateSplitTransceiver.cpp b/EmulateSplitTransceiver.cpp index 7e84919e2..c42436db0 100644 --- a/EmulateSplitTransceiver.cpp +++ b/EmulateSplitTransceiver.cpp @@ -1,5 +1,7 @@ #include "EmulateSplitTransceiver.hpp" +#include "moc_EmulateSplitTransceiver.cpp" + EmulateSplitTransceiver::EmulateSplitTransceiver (std::unique_ptr wrapped, QObject * parent) : Transceiver {parent} , wrapped_ {std::move (wrapped)} diff --git a/EmulateSplitTransceiver.hpp b/EmulateSplitTransceiver.hpp index 210a37b71..d373c020e 100644 --- a/EmulateSplitTransceiver.hpp +++ b/EmulateSplitTransceiver.hpp @@ -27,6 +27,8 @@ class EmulateSplitTransceiver final : public Transceiver { + Q_OBJECT + public: // takes ownership of wrapped Transceiver explicit EmulateSplitTransceiver (std::unique_ptr wrapped, diff --git a/HRDTransceiver.cpp b/HRDTransceiver.cpp index 3b9f90e23..596f0ba27 100644 --- a/HRDTransceiver.cpp +++ b/HRDTransceiver.cpp @@ -19,6 +19,8 @@ namespace int constexpr yaesu_delay {250}; } +#include "moc_HRDTransceiver.cpp" + void HRDTransceiver::register_transceivers (TransceiverFactory::Transceivers * registry, int id) { (*registry)[HRD_transceiver_name] = TransceiverFactory::Capabilities (id, TransceiverFactory::Capabilities::network, true, true /* maybe */); @@ -885,7 +887,7 @@ bool HRDTransceiver::is_button_checked (int button_index, bool no_debug) return "1" == reply; } -void HRDTransceiver::poll () +void HRDTransceiver::do_poll () { #if WSJT_TRACE_CAT && WSJT_TRACE_CAT_POLLS bool quiet {false}; diff --git a/HRDTransceiver.hpp b/HRDTransceiver.hpp index e17134d53..2f563df6f 100644 --- a/HRDTransceiver.hpp +++ b/HRDTransceiver.hpp @@ -27,6 +27,8 @@ class QByteArray; class HRDTransceiver final : public PollingTransceiver { + Q_OBJECT + public: static void register_transceivers (TransceiverFactory::Transceivers *, int id); @@ -48,7 +50,7 @@ protected: void do_ptt (bool on) override; // Implement the PollingTransceiver interface. - void poll () override; + void do_poll () override; private: QString send_command (QString const&, bool no_debug = false, bool prepend_context = true, bool recurse = false); diff --git a/HamlibTransceiver.cpp b/HamlibTransceiver.cpp index f2e55bb4b..da0623e22 100644 --- a/HamlibTransceiver.cpp +++ b/HamlibTransceiver.cpp @@ -632,7 +632,7 @@ int HamlibTransceiver::do_start () resolution = -1; // best guess } - poll (); + do_poll (); TRACE_CAT ("HamlibTransceiver", "exit" << state () << "reversed =" << reversed_ << "resolution = " << resolution); return resolution; @@ -898,7 +898,7 @@ void HamlibTransceiver::do_mode (MODE mode) update_mode (mode); } -void HamlibTransceiver::poll () +void HamlibTransceiver::do_poll () { #if !WSJT_TRACE_CAT_POLLS #if defined (NDEBUG) diff --git a/HamlibTransceiver.hpp b/HamlibTransceiver.hpp index c8c0f74d7..bcc040d23 100644 --- a/HamlibTransceiver.hpp +++ b/HamlibTransceiver.hpp @@ -21,9 +21,9 @@ extern "C" class HamlibTransceiver final : public PollingTransceiver { - Q_OBJECT; // for translation context + Q_OBJECT // for translation context - public: +public: static void register_transceivers (TransceiverFactory::Transceivers *); static void unregister_transceivers (); @@ -40,7 +40,7 @@ class HamlibTransceiver final void do_mode (MODE) override; void do_ptt (bool) override; - void poll () override; + void do_poll () override; void error_check (int ret_code, QString const& doing) const; void set_conf (char const * item, char const * value); diff --git a/INSTALL b/INSTALL index 4f6e85b78..42169fb38 100644 --- a/INSTALL +++ b/INSTALL @@ -30,13 +30,13 @@ Mac". Qt v5, preferably v5.5 or later is required to build WSJT-X. -Qt v5 multimedia support and serial port is necessary as well as the -core Qt v5 components, normally installing the Qt multimedia -development package and Qt serialport development package are -sufficient to pull in all the required Qt components and dependants as -a single transaction. On some systems the Qt multimedia plugin -component is separate in the distribution repository an it may also -need installing. +Qt v5 multimedia support, serial port, and Linguist is necessary as +well as the core Qt v5 components, normally installing the Qt +multimedia development, Qt serialport development packages, and the Qt +Linguist packages are sufficient to pull in all the required Qt +components and dependants as a single transaction. On some systems +the Qt multimedia plugin component is separate in the distribution +repository an it may also need installing. The single precision FFTW v3 library libfftw3f is required along with the libfftw library development package. Normally installing the @@ -256,47 +256,6 @@ The above commands will build hamlib and install it into ~/hamlib-prefix. If `make install-strip` fails, try `make install`. -Qt --- - -NOTE: As of Qt v5.4 building Qt from source on Mac OS X is no longer -necessary since the Qt team have switched to using the modern libc++ -Standard C++ Library for all distributable run time -components. Instead you may simply download a binary installer for OS -X 64-bit. The binary installer is here: - - http://www.qt.io/download - -The binary Qt distributions prior to Qt v5.4 from -http://www.qt.io/download unfortunately are built to use the libstdc++ -C++ support library, WSJT-X uses a less geriatric C++ dialect which -uses the libc++ C++ support library. This means that you need to -build Qt from sources. This is not difficult but does take some time. - -Download the Qt source tarball from -http://www.qt.io/download-open-source/, the link is about half way -down the page, you want the full sources tar ball shown as a 'tar.gz' -link. - -Unpack the sources and cd into the top level directory then type: - -$ ./configure -prefix ~/local/qt-macx-clang -opensource \ - -confirm-license -platform macx-clang -silent -nomake tests \ - -nomake examples -sdk macosx10.10 -skip qtwebkit \ - -skip qtwebkit-examples -skip qtquick1 -skip qtconnectivity \ - -skip qtlocation -skip qtsensors -skip qtscript \ - -skip qtwebsockets -skip qtwebengine -skip qtwebchannel \ - -skip qtwayland -skip qtquickcontrols -skip qtdeclarative \ - -skip qtxmlpatterns -skip qtenginio -$ make -j4 -$ make install - -If you are building on 10.8 or don't have the 10.10 Mac SDK (Xcode 6) -available, you can substitute '-sdk macosx10.9' above. - -The build above will take a few hours to complete. - - CMake ----- Although CMake is available via MacPorts I prefer to use the binary @@ -328,6 +287,13 @@ $ sudo chgrp wheel /usr/local/bin and then retry the install command. +Qt +-- + +Download the latest on-line installer package from the Qt web site and +isntall the latest Qt stable version development package. + + WSJT-X ------ First fetch the source from the repository: @@ -411,4 +377,4 @@ $ cmake --build . --target install 73 Bill -G4WJS. \ No newline at end of file +G4WJS. diff --git a/MessageClient.cpp b/MessageClient.cpp index 5bf23294b..ddf269564 100644 --- a/MessageClient.cpp +++ b/MessageClient.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ public: impl (QString const& id, QString const& version, QString const& revision, port_type server_port, MessageClient * self) : self_ {self} + , enabled_ {false} , id_ {id} , version_ {version} , revision_ {revision} @@ -79,6 +81,7 @@ public: Q_SLOT void host_info_results (QHostInfo); MessageClient * self_; + bool enabled_; QString id_; QString version_; QString revision_; @@ -160,6 +163,12 @@ void MessageClient::impl::parse_message (QByteArray const& msg) schema_ = in.schema (); } + if (!enabled_) + { + TRACE_UDP ("message processing disabled for id:" << in.id ()); + return; + } + // // message format is described in NetworkMessage.hpp // @@ -200,6 +209,15 @@ void MessageClient::impl::parse_message (QByteArray const& msg) } break; + case NetworkMessage::Close: + TRACE_UDP ("Close"); + if (check_status (in) != Fail) + { + last_message_.clear (); + Q_EMIT self_->close (); + } + break; + case NetworkMessage::Replay: TRACE_UDP ("Replay"); if (check_status (in) != Fail) @@ -261,6 +279,42 @@ void MessageClient::impl::parse_message (QByteArray const& msg) } break; + case NetworkMessage::SwitchConfiguration: + { + QByteArray configuration_name; + in >> configuration_name; + TRACE_UDP ("Switch Configuration name:" << configuration_name); + if (check_status (in) != Fail) + { + Q_EMIT self_->switch_configuration (QString::fromUtf8 (configuration_name)); + } + } + break; + + case NetworkMessage::Configure: + { + QByteArray mode; + quint32 frequency_tolerance; + QByteArray submode; + bool fast_mode {false}; + quint32 tr_period {std::numeric_limits::max ()}; + quint32 rx_df {std::numeric_limits::max ()}; + QByteArray dx_call; + QByteArray dx_grid; + bool generate_messages {false}; + in >> mode >> frequency_tolerance >> submode >> fast_mode >> tr_period >> rx_df + >> dx_call >> dx_grid >> generate_messages; + TRACE_UDP ("Configure mode:" << mode << "frequency tolerance:" << frequency_tolerance << "submode:" << submode << "fast mode:" << fast_mode << "T/R period:" << tr_period << "rx df:" << rx_df << "dx call:" << dx_call << "dx grid:" << dx_grid << "generate messages:" << generate_messages); + if (check_status (in) != Fail) + { + Q_EMIT self_->configure (QString::fromUtf8 (mode), frequency_tolerance + , QString::fromUtf8 (submode), fast_mode, tr_period, rx_df + , QString::fromUtf8 (dx_call), QString::fromUtf8 (dx_grid) + , generate_messages); + } + } + break; + default: // Ignore // @@ -438,13 +492,20 @@ void MessageClient::add_blocked_destination (QHostAddress const& a) } } +void MessageClient::enable (bool flag) +{ + m_->enabled_ = flag; +} + void MessageClient::status_update (Frequency f, QString const& mode, QString const& dx_call , QString const& report, QString const& tx_mode , bool tx_enabled, bool transmitting, bool decoding - , qint32 rx_df, qint32 tx_df, QString const& de_call + , quint32 rx_df, quint32 tx_df, QString const& de_call , QString const& de_grid, QString const& dx_grid , bool watchdog_timeout, QString const& sub_mode - , bool fast_mode, quint8 special_op_mode) + , bool fast_mode, quint8 special_op_mode + , quint32 frequency_tolerance, quint32 tr_period + , QString const& configuration_name) { if (m_->server_port_ && !m_->server_string_.isEmpty ()) { @@ -453,8 +514,8 @@ void MessageClient::status_update (Frequency f, QString const& mode, QString con out << f << mode.toUtf8 () << dx_call.toUtf8 () << report.toUtf8 () << tx_mode.toUtf8 () << tx_enabled << transmitting << decoding << rx_df << tx_df << de_call.toUtf8 () << de_grid.toUtf8 () << dx_grid.toUtf8 () << watchdog_timeout << sub_mode.toUtf8 () - << fast_mode << special_op_mode; - TRACE_UDP ("frequency:" << f << "mode:" << mode << "DX:" << dx_call << "report:" << report << "Tx mode:" << tx_mode << "tx_enabled:" << tx_enabled << "Tx:" << transmitting << "decoding:" << decoding << "Rx df:" << rx_df << "Tx df:" << tx_df << "DE:" << de_call << "DE grid:" << de_grid << "DX grid:" << dx_grid << "w/d t/o:" << watchdog_timeout << "sub_mode:" << sub_mode << "fast mode:" << fast_mode << "spec op mode:" << special_op_mode); + << fast_mode << special_op_mode << frequency_tolerance << tr_period << configuration_name.toUtf8 (); + TRACE_UDP ("frequency:" << f << "mode:" << mode << "DX:" << dx_call << "report:" << report << "Tx mode:" << tx_mode << "tx_enabled:" << tx_enabled << "Tx:" << transmitting << "decoding:" << decoding << "Rx df:" << rx_df << "Tx df:" << tx_df << "DE:" << de_call << "DE grid:" << de_grid << "DX grid:" << dx_grid << "w/d t/o:" << watchdog_timeout << "sub_mode:" << sub_mode << "fast mode:" << fast_mode << "spec op mode:" << special_op_mode << "frequency tolerance:" << frequency_tolerance << "T/R period:" << tr_period << "configuration name:" << configuration_name); m_->send_message (out, message); } } @@ -527,7 +588,7 @@ void MessageClient::logged_ADIF (QByteArray const& ADIF_record) { QByteArray message; NetworkMessage::Builder out {&message, NetworkMessage::LoggedADIF, m_->id_, m_->schema_}; - QByteArray ADIF {"\n3.0.7\nWSJT-X\n\n" + ADIF_record + " "}; + QByteArray ADIF {"\n3.1.0\nWSJT-X\n\n" + ADIF_record + " "}; out << ADIF; TRACE_UDP ("ADIF:" << ADIF); m_->send_message (out, message); diff --git a/MessageClient.hpp b/MessageClient.hpp index ca5f02037..20f39b019 100644 --- a/MessageClient.hpp +++ b/MessageClient.hpp @@ -47,12 +47,16 @@ public: // change the server port messages are sent to Q_SLOT void set_server_port (port_type server_port = 0u); + // enable incoming messages + Q_SLOT void enable (bool); + // outgoing messages Q_SLOT void status_update (Frequency, QString const& mode, QString const& dx_call, QString const& report , QString const& tx_mode, bool tx_enabled, bool transmitting, bool decoding - , qint32 rx_df, qint32 tx_df, QString const& de_call, QString const& de_grid + , quint32 rx_df, quint32 tx_df, QString const& de_call, QString const& de_grid , QString const& dx_grid, bool watchdog_timeout, QString const& sub_mode - , bool fast_mode, quint8 special_op_mode); + , bool fast_mode, quint8 special_op_mode, quint32 frequency_tolerance + , quint32 tr_period, QString const& configuration_name); Q_SLOT void decode (bool is_new, QTime time, qint32 snr, float delta_time, quint32 delta_frequency , QString const& mode, QString const& message, bool low_confidence , bool off_air); @@ -89,6 +93,10 @@ public: Q_SIGNAL void reply (QTime, qint32 snr, float delta_time, quint32 delta_frequency, QString const& mode , QString const& message_text, bool low_confidence, quint8 modifiers); + // this signal is emitted if the server has requested this client to + // close down gracefully + Q_SIGNAL void close (); + // this signal is emitted if the server has requested a replay of // all decodes Q_SIGNAL void replay (); @@ -105,6 +113,16 @@ public: // callsign request for the specified call Q_SIGNAL void highlight_callsign (QString const& callsign, QColor const& bg, QColor const& fg, bool last_only); + // this signal is emitted if the server has requested a + // configuration switch + Q_SIGNAL void switch_configuration (QString const& configuration_name); + + // this signal is emitted if the server has requested a + // configuration change + Q_SIGNAL void configure (QString const& mode, quint32 frequency_tolerance, QString const& submode + , bool fast_mode, quint32 tr_period, quint32 rx_df, QString const& dx_call + , QString const& dx_grid, bool generate_messages); + // this signal is emitted when network errors occur or if a host // lookup fails Q_SIGNAL void error (QString const&) const; diff --git a/MessageServer.cpp b/MessageServer.cpp index dadf3d984..07b2fb429 100644 --- a/MessageServer.cpp +++ b/MessageServer.cpp @@ -1,6 +1,7 @@ #include "MessageServer.hpp" #include +#include #include #include @@ -16,6 +17,11 @@ #include "moc_MessageServer.cpp" +namespace +{ + auto quint32_max = std::numeric_limits::max (); +} + class MessageServer::impl : public QUdpSocket { @@ -238,8 +244,8 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s bool tx_enabled {false}; bool transmitting {false}; bool decoding {false}; - qint32 rx_df {-1}; - qint32 tx_df {-1}; + quint32 rx_df {quint32_max}; + quint32 tx_df {quint32_max}; QByteArray de_call; QByteArray de_grid; QByteArray dx_grid; @@ -247,9 +253,12 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s QByteArray sub_mode; bool fast_mode {false}; quint8 special_op_mode {0}; + quint32 frequency_tolerance {quint32_max}; + quint32 tr_period {quint32_max}; + QByteArray configuration_name; in >> f >> mode >> dx_call >> report >> tx_mode >> tx_enabled >> transmitting >> decoding >> rx_df >> tx_df >> de_call >> de_grid >> dx_grid >> watchdog_timeout >> sub_mode - >> fast_mode >> special_op_mode; + >> fast_mode >> special_op_mode >> frequency_tolerance >> tr_period >> configuration_name; if (check_status (in) != Fail) { Q_EMIT self_->status_update (id, f, QString::fromUtf8 (mode), QString::fromUtf8 (dx_call) @@ -258,7 +267,8 @@ void MessageServer::impl::parse_message (QHostAddress const& sender, port_type s , QString::fromUtf8 (de_call), QString::fromUtf8 (de_grid) , QString::fromUtf8 (dx_grid), watchdog_timeout , QString::fromUtf8 (sub_mode), fast_mode - , special_op_mode); + , special_op_mode, frequency_tolerance, tr_period + , QString::fromUtf8 (configuration_name)); } } break; @@ -493,6 +503,17 @@ void MessageServer::replay (QString const& id) } } +void MessageServer::close (QString const& id) +{ + auto iter = m_->clients_.find (id); + if (iter != std::end (m_->clients_)) + { + QByteArray message; + NetworkMessage::Builder out {&message, NetworkMessage::Close, id, (*iter).negotiated_schema_number_}; + m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_); + } +} + void MessageServer::halt_tx (QString const& id, bool auto_only) { auto iter = m_->clients_.find (id); @@ -541,3 +562,30 @@ void MessageServer::highlight_callsign (QString const& id, QString const& callsi m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_); } } + +void MessageServer::switch_configuration (QString const& id, QString const& configuration_name) +{ + auto iter = m_->clients_.find (id); + if (iter != std::end (m_->clients_)) + { + QByteArray message; + NetworkMessage::Builder out {&message, NetworkMessage::SwitchConfiguration, id, (*iter).negotiated_schema_number_}; + out << configuration_name.toUtf8 (); + m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_); + } +} + +void MessageServer::configure (QString const& id, QString const& mode, quint32 frequency_tolerance + , QString const& submode, bool fast_mode, quint32 tr_period, quint32 rx_df + , QString const& dx_call, QString const& dx_grid, bool generate_messages) +{ + auto iter = m_->clients_.find (id); + if (iter != std::end (m_->clients_)) + { + QByteArray message; + NetworkMessage::Builder out {&message, NetworkMessage::Configure, id, (*iter).negotiated_schema_number_}; + out << mode.toUtf8 () << frequency_tolerance << submode.toUtf8 () << fast_mode << tr_period << rx_df + << dx_call.toUtf8 () << dx_grid.toUtf8 () << generate_messages; + m_->send_message (out, message, iter.value ().sender_address_, (*iter).sender_port_); + } +} diff --git a/MessageServer.hpp b/MessageServer.hpp index 12377bef9..f59c21fe0 100644 --- a/MessageServer.hpp +++ b/MessageServer.hpp @@ -52,6 +52,9 @@ public: Q_SLOT void reply (QString const& id, QTime time, qint32 snr, float delta_time, quint32 delta_frequency , QString const& mode, QString const& message, bool low_confidence, quint8 modifiers); + // ask the client with identification 'id' to close down gracefully + Q_SLOT void close (QString const& id); + // ask the client with identification 'id' to replay all decodes Q_SLOT void replay (QString const& id); @@ -72,15 +75,25 @@ public: , QColor const& bg = QColor {}, QColor const& fg = QColor {} , bool last_only = false); + // ask the client with identification 'id' to switch to + // configuration 'configuration_name' + Q_SLOT void switch_configuration (QString const& id, QString const& configuration_name); + + // ask the client with identification 'id' to change configuration + Q_SLOT void configure (QString const& id, QString const& mode, quint32 frequency_tolerance + , QString const& submode, bool fast_mode, quint32 tr_period, quint32 rx_df + , QString const& dx_call, QString const& dx_grid, bool generate_messages); + // the following signals are emitted when a client broadcasts the // matching message Q_SIGNAL void client_opened (QString const& id, QString const& version, QString const& revision); Q_SIGNAL void status_update (QString const& id, Frequency, QString const& mode, QString const& dx_call , QString const& report, QString const& tx_mode, bool tx_enabled - , bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df + , bool transmitting, bool decoding, quint32 rx_df, quint32 tx_df , QString const& de_call, QString const& de_grid, QString const& dx_grid , bool watchdog_timeout, QString const& sub_mode, bool fast_mode - , quint8 special_op_mode); + , quint8 special_op_mode, quint32 frequency_tolerance, quint32 tr_period + , QString const& configuration_name); Q_SIGNAL void client_closed (QString const& id); Q_SIGNAL void decode (bool is_new, QString const& id, QTime time, qint32 snr, float delta_time , quint32 delta_frequency, QString const& mode, QString const& message diff --git a/MetaDataRegistry.cpp b/MetaDataRegistry.cpp index bf2aab5d4..e66a43008 100644 --- a/MetaDataRegistry.cpp +++ b/MetaDataRegistry.cpp @@ -14,16 +14,35 @@ #include "WFPalette.hpp" #include "models/IARURegions.hpp" #include "models/DecodeHighlightingModel.hpp" -#include "widgets/FrequencyLineEdit.hpp" +#include "widgets/DateTimeEdit.hpp" -QItemEditorFactory * item_editor_factory () +namespace { - static QItemEditorFactory * our_item_editor_factory = new QItemEditorFactory; - return our_item_editor_factory; + class ItemEditorFactory final + : public QItemEditorFactory + { + public: + ItemEditorFactory () + : default_factory_ {QItemEditorFactory::defaultFactory ()} + { + } + + QWidget * createEditor (int user_type, QWidget * parent) const override + { + auto editor = QItemEditorFactory::createEditor (user_type, parent); + return editor ? editor : default_factory_->createEditor (user_type, parent); + } + + private: + QItemEditorFactory const * default_factory_; + }; } void register_types () { + auto item_editor_factory = new ItemEditorFactory; + QItemEditorFactory::setDefaultFactory (item_editor_factory); + // types in Radio.hpp are registered in their own translation unit // as they are needed in the wsjtx_udp shared library too @@ -31,9 +50,7 @@ void register_types () // used as signal/slot connection arguments since the new Qt 5.5 // Q_ENUM macro only seems to register the unqualified name - item_editor_factory ()->registerEditor (qMetaTypeId (), new QStandardItemEditorCreator ()); - //auto frequency_delta_type_id = qRegisterMetaType ("FrequencyDelta"); - item_editor_factory ()->registerEditor (qMetaTypeId (), new QStandardItemEditorCreator ()); + item_editor_factory->registerEditor (qMetaTypeId (), new QStandardItemEditorCreator ()); // Frequency list model qRegisterMetaTypeStreamOperators ("Item_v2"); diff --git a/MetaDataRegistry.hpp b/MetaDataRegistry.hpp index 43000d201..8bf3c80dc 100644 --- a/MetaDataRegistry.hpp +++ b/MetaDataRegistry.hpp @@ -1,9 +1,6 @@ #ifndef META_DATA_REGISTRY_HPP__ #define META_DATA_REGISTRY_HPP__ -class QItemEditorFactory; - -QItemEditorFactory * item_editor_factory (); void register_types (); #endif diff --git a/Modulator.cpp b/Modulator.cpp index 725de9e42..4d0171770 100644 --- a/Modulator.cpp +++ b/Modulator.cpp @@ -25,15 +25,15 @@ double constexpr Modulator::m_twoPi; // unsigned m_nspd=1.2*48000.0/wpm; // m_nspd=3072; //18.75 WPM -Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, +Modulator::Modulator (unsigned frameRate, double periodLengthInSeconds, QObject * parent) : AudioDevice {parent} , m_quickClose {false} , m_phi {0.0} , m_toneSpacing {0.0} , m_fSpread {0.0} - , m_frameRate {frameRate} , m_period {periodLengthInSeconds} + , m_frameRate {frameRate} , m_state {Idle} , m_tuning {false} , m_cwLevel {false} @@ -45,19 +45,15 @@ Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds, void Modulator::start (unsigned symbolsLength, double framesPerSymbol, double frequency, double toneSpacing, SoundOutput * stream, Channel channel, - bool synchronize, bool fastMode, double dBSNR, int TRperiod) + bool synchronize, bool fastMode, double dBSNR, double TRperiod) { Q_ASSERT (stream); // Time according to this computer which becomes our base time qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000; + unsigned mstr = ms0 % int(1000.0*m_period); // ms into the nominal Tx start time -// qDebug() << "ModStart" << symbolsLength << framesPerSymbol -// << frequency << toneSpacing; - - if(m_state != Idle) stop (); - + if(m_state != Idle) stop(); m_quickClose = false; - m_symbolsLength = symbolsLength; m_isym0 = std::numeric_limits::max (); // big number m_frequency0 = 0.; @@ -69,37 +65,33 @@ void Modulator::start (unsigned symbolsLength, double framesPerSymbol, m_toneSpacing = toneSpacing; m_bFastMode=fastMode; m_TRperiod=TRperiod; - unsigned delay_ms = 1920 == m_nsps && 15 == m_period ? 500 : 1000; + unsigned delay_ms=1000; + if(m_nsps==1920) delay_ms=500; //FT8 + if(m_nsps==576) delay_ms=300; //FT4 - // noise generator parameters +// noise generator parameters if (m_addNoise) { m_snr = qPow (10.0, 0.05 * (dBSNR - 6.0)); m_fac = 3000.0; if (m_snr > 1.0) m_fac = 3000.0 / m_snr; } - unsigned mstr = ms0 % (1000 * m_period); // ms in period - - // round up to an exact portion of a second that allows for startup - // delays +// round up to an exact portion of a second that allows for startup delays m_ic = (mstr / delay_ms) * m_frameRate * delay_ms / 1000; if(m_bFastMode) m_ic=0; m_silentFrames = 0; - // calculate number of silent frames to send, so that audio will start at - // the nominal time "delay_ms" into the Tx sequence. +// calculate number of silent frames to send, so that audio will start at +// the nominal time "delay_ms" into the Tx sequence. if (synchronize && !m_tuning && !m_bFastMode) { m_silentFrames = m_ic + m_frameRate / (1000 / delay_ms) - (mstr * (m_frameRate / 1000)); } - if(symbolsLength==105 and framesPerSymbol==512 - and (toneSpacing==12000.0/512.0 or toneSpacing==-2.0)) { -//### FT4 parameters - m_ic=0; - m_silentFrames=0; - } -// qDebug() << "Mod AA" << symbolsLength << framesPerSymbol << toneSpacing; -// qDebug() << "Mod AB" << delay_ms << mstr << m_ic << m_silentFrames; + +// qDebug() << "aa" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.zzz") +// << m_ic << m_silentFrames << m_silentFrames/48000.0 +// << mstr << fmod(double(ms0),1000.0*m_period); + initialize (QIODevice::ReadOnly, channel); Q_EMIT stateChanged ((m_state = (synchronize && m_silentFrames) ? @@ -183,12 +175,12 @@ qint64 Modulator::readData (char * data, qint64 maxSize) if(!m_tuning) isym=m_ic/(4.0*m_nsps); // Actual fsample=48000 bool slowCwId=((isym >= m_symbolsLength) && (icw[0] > 0)) && (!m_bFastMode); - if(m_TRperiod==3) slowCwId=false; + if(m_TRperiod==3.0) slowCwId=false; bool fastCwId=false; static bool bCwId=false; qint64 ms = QDateTime::currentMSecsSinceEpoch(); - float tsec=0.001*(ms % (1000*m_TRperiod)); - if(m_bFastMode and (icw[0]>0) and (tsec>(m_TRperiod-5.0))) fastCwId=true; + float tsec=0.001*(ms % int(1000*m_TRperiod)); + if(m_bFastMode and (icw[0]>0) and (tsec > (m_TRperiod-5.0))) fastCwId=true; if(!m_bFastMode) m_nspd=2560; // 22.5 WPM // qDebug() << "Mod A" << m_ic << isym << tsec; @@ -259,7 +251,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize) i1= m_symbolsLength * 4.0 * m_nsps; } if(m_bFastMode and !m_tuning) { - i1=m_TRperiod*48000 - 24000; + i1=m_TRperiod*48000.0 - 24000.0; i0=i1-816; } @@ -267,7 +259,7 @@ qint64 Modulator::readData (char * data, qint64 maxSize) for (unsigned i = 0; i < numFrames && m_ic <= i1; ++i) { isym=0; - if(!m_tuning and m_TRperiod!=3) isym=m_ic/(4.0*m_nsps); //Actual fsample=48000 + if(!m_tuning and m_TRperiod!=3.0) isym=m_ic/(4.0*m_nsps); //Actual fsample=48000 if(m_bFastMode) isym=isym%m_symbolsLength; if (isym != m_isym0 || m_frequency != m_frequency0) { if(itone[0]>=100) { diff --git a/Modulator.hpp b/Modulator.hpp index e8df7f2dd..3371cbe5e 100644 --- a/Modulator.hpp +++ b/Modulator.hpp @@ -23,7 +23,7 @@ class Modulator public: enum ModulatorState {Synchronizing, Active, Idle}; - Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObject * parent = nullptr); + Modulator (unsigned frameRate, double periodLengthInSeconds, QObject * parent = nullptr); void close () override; @@ -31,14 +31,14 @@ public: double frequency () const {return m_frequency;} bool isActive () const {return m_state != Idle;} void setSpread(double s) {m_fSpread=s;} - void setTRPeriod(unsigned p) {m_period=p;} + void setTRPeriod(double p) {m_period=p;} void set_nsym(int n) {m_symbolsLength=n;} void set_ms0(qint64 ms) {m_ms0=ms;} Q_SLOT void start (unsigned symbolsLength, double framesPerSymbol, double frequency, double toneSpacing, SoundOutput *, Channel = Mono, bool synchronize = true, bool fastMode = false, - double dBSNR = 99., int TRperiod=60); + double dBSNR = 99., double TRperiod=60.0); Q_SLOT void stop (bool quick = false); Q_SLOT void tune (bool newState = true); Q_SLOT void setFrequency (double newFrequency) {m_frequency = newFrequency;} @@ -72,14 +72,14 @@ private: double m_fac; double m_toneSpacing; double m_fSpread; + double m_TRperiod; + double m_period; qint64 m_silentFrames; qint64 m_ms0; - qint32 m_TRperiod; qint16 m_ramp; unsigned m_frameRate; - unsigned m_period; ModulatorState volatile m_state; bool volatile m_tuning; diff --git a/MultiSettings.cpp b/MultiSettings.cpp index f4798bc3f..29c686d3d 100644 --- a/MultiSettings.cpp +++ b/MultiSettings.cpp @@ -65,6 +65,8 @@ namespace class NameDialog final : public QDialog { + Q_OBJECT + public: explicit NameDialog (QString const& current_name, QStringList const& current_names, @@ -112,6 +114,8 @@ namespace class ExistingNameDialog final : public QDialog { + Q_OBJECT + public: explicit ExistingNameDialog (QStringList const& current_names, QWidget * parent = nullptr) : QDialog {parent} @@ -155,13 +159,16 @@ public: bool exit (); QSettings settings_; + QString current_; + + // switch to this configuration + void select_configuration (QString const& target_name); private: using Dictionary = QMap; // create a configuration maintenance sub menu - QMenu * create_sub_menu (QMainWindow * main_window, - QMenu * parent, + QMenu * create_sub_menu (QMenu * parent, QString const& menu_title, QActionGroup * = nullptr); @@ -171,32 +178,32 @@ private: // write the settings values from the dictionary to the current group void load_from (Dictionary const&, bool add_placeholder = true); - // switch to this configuration - void select_configuration (QMainWindow *, QMenu const *); - // clone this configuration - void clone_configuration (QMainWindow * main_window, QMenu *, QMenu const *); + void clone_configuration (QMenu *, QMenu const *); // update this configuration from another - void clone_into_configuration (QMainWindow *, QMenu const *); + void clone_into_configuration (QMenu const *); // reset configuration to default values - void reset_configuration (QMainWindow *, QMenu const *); + void reset_configuration (QMenu const *); // change configuration name - void rename_configuration (QMainWindow *, QMenu *); + void rename_configuration (QMenu *); // remove a configuration - void delete_configuration (QMainWindow *, QMenu *); + void delete_configuration (QMenu *); + + // action to take on restart + enum class RepositionType {unchanged, replace, save_and_replace}; + void restart (RepositionType); MultiSettings const * parent_; // required for emitting signals + QMainWindow * main_window_; bool name_change_emit_pending_; // delayed until menu built QFont original_font_; - QString current_; - // action to take on restart - enum class RepositionType {unchanged, replace, save_and_replace} reposition_type_; + RepositionType reposition_type_; Dictionary new_settings_; bool exit_flag_; // false means loop around with new // configuration @@ -263,6 +270,16 @@ void MultiSettings::create_menu_actions (QMainWindow * main_window, QMenu * menu m_->create_menu_actions (main_window, menu); } +void MultiSettings::select_configuration (QString const& name) +{ + m_->select_configuration (name); +} + +QString MultiSettings::configuration_name () const +{ + return m_->current_; +} + bool MultiSettings::exit () { return m_->exit (); @@ -271,6 +288,7 @@ bool MultiSettings::exit () MultiSettings::impl::impl (MultiSettings const * parent, QString const& config_name) : settings_ {settings_path (), QSettings::IniFormat} , parent_ {parent} + , main_window_ {nullptr} , name_change_emit_pending_ {true} , reposition_type_ {RepositionType::unchanged} , exit_flag_ {true} @@ -407,13 +425,14 @@ bool MultiSettings::impl::reposition () // and, reset void MultiSettings::impl::create_menu_actions (QMainWindow * main_window, QMenu * menu) { + main_window_ = main_window; auto const& current_group = settings_.group (); if (current_group.size ()) settings_.endGroup (); SettingsGroup alternatives {&settings_, multi_settings_root_group}; // get the current configuration name auto const& current_configuration_name = settings_.value (multi_settings_current_name_key, tr (default_string)).toString (); // add the default configuration sub menu - QMenu * default_menu = create_sub_menu (main_window, menu, current_configuration_name, configurations_group_); + QMenu * default_menu = create_sub_menu (menu, current_configuration_name, configurations_group_); // and set as the current configuration default_menu->menuAction ()->setChecked (true); @@ -423,7 +442,7 @@ void MultiSettings::impl::create_menu_actions (QMainWindow * main_window, QMenu // add all the other configurations for (auto const& configuration_name: available_configurations) { - create_sub_menu (main_window, menu, configuration_name, configurations_group_); + create_sub_menu (menu, configuration_name, configurations_group_); } if (current_group.size ()) settings_.beginGroup (current_group); @@ -446,8 +465,7 @@ bool MultiSettings::impl::exit () return reposition (); } -QMenu * MultiSettings::impl::create_sub_menu (QMainWindow * main_window, - QMenu * parent_menu, +QMenu * MultiSettings::impl::create_sub_menu (QMenu * parent_menu, QString const& menu_title, QActionGroup * action_group) { @@ -456,7 +474,7 @@ QMenu * MultiSettings::impl::create_sub_menu (QMainWindow * main_window, sub_menu->menuAction ()->setCheckable (true); // populate sub-menu actions before showing - connect (sub_menu, &QMenu::aboutToShow, [this, main_window, parent_menu, sub_menu] () { + connect (sub_menu, &QMenu::aboutToShow, [this, parent_menu, sub_menu] () { // depopulate before populating and showing because on Mac OS X // there is an issue with depopulating in QMenu::aboutToHide() // with connections being disconnected before they are actioned @@ -470,16 +488,16 @@ QMenu * MultiSettings::impl::create_sub_menu (QMainWindow * main_window, { auto select_action = new QAction {tr ("&Switch To"), this}; sub_menu->addAction (select_action); - connect (select_action, &QAction::triggered, [this, main_window, sub_menu] (bool) { - select_configuration (main_window, sub_menu); + connect (select_action, &QAction::triggered, [this, sub_menu] (bool) { + select_configuration (sub_menu->title ()); }); sub_menu->addSeparator (); } auto clone_action = new QAction {tr ("&Clone"), this}; sub_menu->addAction (clone_action); - connect (clone_action, &QAction::triggered, [this, main_window, parent_menu, sub_menu] (bool) { - clone_configuration (main_window, parent_menu, sub_menu); + connect (clone_action, &QAction::triggered, [this, parent_menu, sub_menu] (bool) { + clone_configuration (parent_menu, sub_menu); }); auto const& current_group = settings_.group (); @@ -489,29 +507,29 @@ QMenu * MultiSettings::impl::create_sub_menu (QMainWindow * main_window, { auto clone_into_action = new QAction {tr ("Clone &Into ..."), this}; sub_menu->addAction (clone_into_action); - connect (clone_into_action, &QAction::triggered, [this, main_window, sub_menu] (bool) { - clone_into_configuration (main_window, sub_menu); + connect (clone_into_action, &QAction::triggered, [this, sub_menu] (bool) { + clone_into_configuration (sub_menu); }); } if (current_group.size ()) settings_.beginGroup (current_group); auto reset_action = new QAction {tr ("R&eset"), this}; sub_menu->addAction (reset_action); - connect (reset_action, &QAction::triggered, [this, main_window, sub_menu] (bool) { - reset_configuration (main_window, sub_menu); + connect (reset_action, &QAction::triggered, [this, sub_menu] (bool) { + reset_configuration (sub_menu); }); auto rename_action = new QAction {tr ("&Rename ..."), this}; sub_menu->addAction (rename_action); - connect (rename_action, &QAction::triggered, [this, main_window, sub_menu] (bool) { - rename_configuration (main_window, sub_menu); + connect (rename_action, &QAction::triggered, [this, sub_menu] (bool) { + rename_configuration (sub_menu); }); if (!is_current) { auto delete_action = new QAction {tr ("&Delete"), this}; sub_menu->addAction (delete_action); - connect (delete_action, &QAction::triggered, [this, main_window, sub_menu] (bool) { - delete_configuration (main_window, sub_menu); + connect (delete_action, &QAction::triggered, [this, sub_menu] (bool) { + delete_configuration (sub_menu); }); } }); @@ -554,11 +572,9 @@ void MultiSettings::impl::load_from (Dictionary const& dictionary, bool add_plac settings_.sync (); } -void MultiSettings::impl::select_configuration (QMainWindow * main_window, QMenu const * menu) +void MultiSettings::impl::select_configuration (QString const& target_name) { - auto const& target_name = menu->title (); - - if (target_name != current_) + if (main_window_ && target_name != current_) { { auto const& current_group = settings_.group (); @@ -573,13 +589,11 @@ void MultiSettings::impl::select_configuration (QMainWindow * main_window, QMenu // and set up the restart current_ = target_name; Q_EMIT parent_->configurationNameChanged (unescape_ampersands (current_)); - reposition_type_ = RepositionType::save_and_replace; - exit_flag_ = false; - main_window->close (); + restart (RepositionType::save_and_replace); } } -void MultiSettings::impl::clone_configuration (QMainWindow * main_window, QMenu * parent_menu, QMenu const * menu) +void MultiSettings::impl::clone_configuration (QMenu * parent_menu, QMenu const * menu) { auto const& current_group = settings_.group (); if (current_group.size ()) settings_.endGroup (); @@ -612,12 +626,15 @@ void MultiSettings::impl::clone_configuration (QMainWindow * main_window, QMenu load_from (source_settings); // insert the new configuration sub menu in the parent menu - create_sub_menu (main_window, parent_menu, new_name, configurations_group_); + create_sub_menu (parent_menu, new_name, configurations_group_); if (current_group.size ()) settings_.beginGroup (current_group); } -void MultiSettings::impl::clone_into_configuration (QMainWindow * main_window, QMenu const * menu) +void MultiSettings::impl::clone_into_configuration (QMenu const * menu) { + Q_ASSERT (main_window_); + if (!main_window_) return; + auto const& current_group = settings_.group (); if (current_group.size ()) settings_.endGroup (); auto const& target_name = menu->title (); @@ -638,15 +655,16 @@ void MultiSettings::impl::clone_into_configuration (QMainWindow * main_window, Q } // pick a source configuration - ExistingNameDialog dialog {sources, main_window}; + ExistingNameDialog dialog {sources, main_window_}; if (sources.size () && (1 == sources.size () || QDialog::Accepted == dialog.exec ())) { QString source_name {1 == sources.size () ? sources.at (0) : dialog.name ()}; - if (MessageBox::Yes == MessageBox::query_message (main_window, - tr ("Clone Into Configuration"), - tr ("Confirm overwrite of all values for configuration \"%1\" with values from \"%2\"?") - .arg (unescape_ampersands (target_name)) - .arg (unescape_ampersands (source_name)))) + if (main_window_ + && MessageBox::Yes == MessageBox::query_message (main_window_, + tr ("Clone Into Configuration"), + tr ("Confirm overwrite of all values for configuration \"%1\" with values from \"%2\"?") + .arg (unescape_ampersands (target_name)) + .arg (unescape_ampersands (source_name)))) { // grab the data to clone from if (source_name == current_group_name) @@ -665,9 +683,7 @@ void MultiSettings::impl::clone_into_configuration (QMainWindow * main_window, Q if (target_name == current_) { // restart with new settings - reposition_type_ = RepositionType::replace; - exit_flag_ = false; - main_window->close (); + restart (RepositionType::replace); } else { @@ -682,14 +698,18 @@ void MultiSettings::impl::clone_into_configuration (QMainWindow * main_window, Q if (current_group.size ()) settings_.beginGroup (current_group); } -void MultiSettings::impl::reset_configuration (QMainWindow * main_window, QMenu const * menu) +void MultiSettings::impl::reset_configuration (QMenu const * menu) { + Q_ASSERT (main_window_); + if (!main_window_) return; + auto const& target_name = menu->title (); - if (MessageBox::Yes != MessageBox::query_message (main_window, - tr ("Reset Configuration"), - tr ("Confirm reset to default values for configuration \"%1\"?") - .arg (unescape_ampersands (target_name)))) + if (!main_window_ + || MessageBox::Yes != MessageBox::query_message (main_window_, + tr ("Reset Configuration"), + tr ("Confirm reset to default values for configuration \"%1\"?") + .arg (unescape_ampersands (target_name)))) { return; } @@ -697,10 +717,8 @@ void MultiSettings::impl::reset_configuration (QMainWindow * main_window, QMenu if (target_name == current_) { // restart with default settings - reposition_type_ = RepositionType::replace; new_settings_.clear (); - exit_flag_ = false; - main_window->close (); + restart (RepositionType::replace); } else { @@ -717,8 +735,11 @@ void MultiSettings::impl::reset_configuration (QMainWindow * main_window, QMenu } } -void MultiSettings::impl::rename_configuration (QMainWindow * main_window, QMenu * menu) +void MultiSettings::impl::rename_configuration (QMenu * menu) { + Q_ASSERT (main_window_); + if (!main_window_) return; + auto const& current_group = settings_.group (); if (current_group.size ()) settings_.endGroup (); auto const& target_name = menu->title (); @@ -729,7 +750,7 @@ void MultiSettings::impl::rename_configuration (QMainWindow * main_window, QMenu invalid_names << settings_.value (multi_settings_current_name_key).toString (); // get the new name - NameDialog dialog {target_name, invalid_names, main_window}; + NameDialog dialog {target_name, invalid_names, main_window_}; if (QDialog::Accepted == dialog.exec ()) { if (target_name == current_) @@ -760,8 +781,9 @@ void MultiSettings::impl::rename_configuration (QMainWindow * main_window, QMenu if (current_group.size ()) settings_.beginGroup (current_group); } -void MultiSettings::impl::delete_configuration (QMainWindow * main_window, QMenu * menu) +void MultiSettings::impl::delete_configuration (QMenu * menu) { + Q_ASSERT (main_window_); auto const& target_name = menu->title (); if (target_name == current_) @@ -770,10 +792,11 @@ void MultiSettings::impl::delete_configuration (QMainWindow * main_window, QMenu } else { - if (MessageBox::Yes != MessageBox::query_message (main_window, - tr ("Delete Configuration"), - tr ("Confirm deletion of configuration \"%1\"?") - .arg (unescape_ampersands (target_name)))) + if (!main_window_ + || MessageBox::Yes != MessageBox::query_message (main_window_, + tr ("Delete Configuration"), + tr ("Confirm deletion of configuration \"%1\"?") + .arg (unescape_ampersands (target_name)))) { return; } @@ -789,3 +812,12 @@ void MultiSettings::impl::delete_configuration (QMainWindow * main_window, QMenu // update the menu menu->deleteLater (); } + +void MultiSettings::impl::restart (RepositionType type) +{ + Q_ASSERT (main_window_); + reposition_type_ = type; + exit_flag_ = false; + main_window_->close (); + main_window_ = nullptr; +} diff --git a/MultiSettings.hpp b/MultiSettings.hpp index 051553b48..5e0c9a679 100644 --- a/MultiSettings.hpp +++ b/MultiSettings.hpp @@ -80,6 +80,10 @@ public: // action is triggered. void create_menu_actions (QMainWindow *, QMenu *); + // switch to this configuration if it exists + Q_SLOT void select_configuration (QString const& name); + QString configuration_name () const; + // Access to the QSettings object instance. QSettings * settings (); diff --git a/NetworkMessage.hpp b/NetworkMessage.hpp index 4783bb369..4628c29b8 100644 --- a/NetworkMessage.hpp +++ b/NetworkMessage.hpp @@ -116,15 +116,18 @@ * Tx Enabled bool * Transmitting bool * Decoding bool - * Rx DF qint32 - * Tx DF qint32 + * Rx DF quint32 + * Tx DF quint32 * DE call utf8 * DE grid utf8 * DX grid utf8 * Tx Watchdog bool * Sub-mode utf8 * Fast mode bool - * Special operation mode quint8 + * Special Operation Mode quint8 + * Frequency Tolerance quint32 + * T/R Period quint32 + * Configuration Name utf8 * * WSJT-X sends this status message when various internal state * changes to allow the server to track the relevant state of each @@ -133,19 +136,22 @@ * * Application start up, * "Enable Tx" button status changes, - * Dial frequency changes, - * Changes to the "DX Call" field, - * Operating mode, sub-mode or fast mode changes, - * Transmit mode changed (in dual JT9+JT65 mode), - * Changes to the "Rpt" spinner, - * After an old decodes replay sequence (see Replay below), - * When switching between Tx and Rx mode, - * At the start and end of decoding, - * When the Rx DF changes, - * When the Tx DF changes, - * When settings are exited, - * When the DX call or grid changes, - * When the Tx watchdog is set or reset. + * dial frequency changes, + * changes to the "DX Call" field, + * operating mode, sub-mode or fast mode changes, + * transmit mode changed (in dual JT9+JT65 mode), + * changes to the "Rpt" spinner, + * after an old decodes replay sequence (see Replay below), + * when switching between Tx and Rx mode, + * at the start and end of decoding, + * when the Rx DF changes, + * when the Tx DF changes, + * when settings are exited, + * when the DX call or grid changes, + * when the Tx watchdog is set or reset, + * when the frequency tolerance is changed, + * when the T/R period is changed, + * when the configuration name changes. * * The Special operation mode is an enumeration that indicates the * setting selected in the WSJT-X "Settings->Advanced->Special @@ -159,6 +165,10 @@ * 5 -> FOX * 6 -> HOUND * + * The Frequency Tolerance and T/R period fields may have a value + * of the maximum quint32 value which implies the field is not + * applicable. + * * * Decode Out 2 quint32 * Id (unique key) utf8 @@ -271,11 +281,12 @@ * button. * * - * Close Out 6 quint32 + * Close Out/In 6 quint32 * Id (unique key) utf8 * - * Close is sent by a client immediately prior to it shutting - * down gracefully. + * Close is sent by a client immediately prior to it shutting + * down gracefully. When sent by a server it requests the target + * client to close down gracefully. * * * Replay In 7 quint32 @@ -414,6 +425,35 @@ * the last instance only instead of all instances of the * specified call be highlighted or have it's highlighting * cleared. + * + * + * SwitchConfiguration In 14 quint32 + * Id (unique key) utf8 + * Configuration Name utf8 + * + * The server may send this message at any time. The message + * specifies the name of the configuration to switch to. The new + * configuration must exist. + * + * + * Configure In 15 quint32 + * Id (unique key) utf8 + * Mode utf8 + * Frequency Tolerance quint32 + * Submode utf8 + * Fast Mode bool + * T/R Period quint32 + * Rx DF quint32 + * DX Call utf8 + * DX Grid utf8 + * Generate Messages bool + * + * The server may send this message at any time. The message + * specifies various configuration options. For utf8 string + * fields an empty value implies no change, for the quint32 Rx DF + * and Frequency Tolerance fields the maximum quint32 value + * implies no change. Invalid or unrecognized values will be + * silently ignored. */ #include @@ -443,6 +483,8 @@ namespace NetworkMessage Location, LoggedADIF, HighlightCallsign, + SwitchConfiguration, + Configure, maximum_message_type_ // ONLY add new message types // immediately before here }; diff --git a/OmniRigTransceiver.cpp b/OmniRigTransceiver.cpp index 09f1e5cfa..de352fb5a 100644 --- a/OmniRigTransceiver.cpp +++ b/OmniRigTransceiver.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "qt_helpers.hpP" @@ -109,6 +110,15 @@ OmniRigTransceiver::OmniRigTransceiver (std::unique_ptr wrapped { } +// returns false on time out +bool OmniRigTransceiver::await_notification_with_timeout (int timeout) +{ + QEventLoop el; + connect (this, &OmniRigTransceiver::notified, &el, [&el] () {el.exit (1);}); + QTimer::singleShot (timeout, Qt::CoarseTimer, &el, [&el] () {el.exit (0);}); + return 1 == el.exec (); // wait for notify or timer +} + int OmniRigTransceiver::do_start () { TRACE_CAT ("OmniRigTransceiver", "starting"); @@ -182,101 +192,109 @@ int OmniRigTransceiver::do_start () .arg (readable_params_, 8, 16, QChar ('0')) .arg (writable_params_, 8, 16, QChar ('0')) .arg (rig_number_).toLocal8Bit ()); - - offline_timer_.reset (new QTimer); - offline_timer_->setSingleShot (true); - offline_timer_->setInterval (5 * 1000); - connect (&*offline_timer_, &QTimer::timeout, this, &OmniRigTransceiver::timeout_check); - - for (unsigned tries {0}; tries < 10; ++tries) + for (int i = 0; i < 5; ++i) { - QThread::msleep (100); // wait until OmniRig polls the rig - auto f = rig_->GetRxFrequency (); - int resolution {0}; - if (f) + if (OmniRig::ST_ONLINE == rig_->Status ()) { - if (OmniRig::PM_UNKNOWN == rig_->Vfo () - && (writable_params_ & (OmniRig::PM_VFOA | OmniRig::PM_VFOB)) - == (OmniRig::PM_VFOA | OmniRig::PM_VFOB)) - { - // start with VFO A (probably MAIN) on rigs that we - // can't query VFO but can set explicitly - rig_->SetVfo (OmniRig::PM_VFOA); - } - if (f % 10) return resolution; // 1Hz resolution - auto test_frequency = f - f % 100 + 55; - if (OmniRig::PM_FREQ & writable_params_) - { - rig_->SetFreq (test_frequency); - } - else if (reversed_ && (OmniRig::PM_FREQB & writable_params_)) - { - rig_->SetFreqB (test_frequency); - } - else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_)) - { - rig_->SetFreqA (test_frequency); - } - else - { - throw_qstring (tr ("OmniRig: don't know how to set rig frequency")); - } - switch (rig_->GetRxFrequency () - test_frequency) - { - case -5: resolution = -1; break; // 10Hz truncated - case 5: resolution = 1; break; // 10Hz rounded - case -15: resolution = -2; break; // 20Hz truncated - case -55: resolution = -2; break; // 100Hz truncated - case 45: resolution = 2; break; // 100Hz rounded - } - if (1 == resolution) // may be 20Hz rounded - { - test_frequency = f - f % 100 + 51; - if (OmniRig::PM_FREQ & writable_params_) - { - rig_->SetFreq (test_frequency); - } - else if (reversed_ && (OmniRig::PM_FREQB & writable_params_)) - { - rig_->SetFreqB (test_frequency); - } - else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_)) - { - rig_->SetFreqA (test_frequency); - } - if (9 == rig_->GetRxFrequency () - test_frequency) - { - resolution = 2; // 20Hz rounded - } - } - if (OmniRig::PM_FREQ & writable_params_) - { - rig_->SetFreq (f); - } - else if (reversed_ && (OmniRig::PM_FREQB & writable_params_)) - { - rig_->SetFreqB (f); - } - else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_)) - { - rig_->SetFreqA (f); - } - update_rx_frequency (f); - return resolution; + break; + } + await_notification_with_timeout (1000); + } + if (OmniRig::ST_ONLINE != rig_->Status ()) + { + throw_qstring ("OmniRig: " + rig_->StatusStr ()); + } + auto f = rig_->GetRxFrequency (); + for (int i = 0; (f == 0) && (i < 5); ++i) + { + await_notification_with_timeout (1000); + f = rig_->GetRxFrequency (); + } + update_rx_frequency (f); + int resolution {0}; + if (OmniRig::PM_UNKNOWN == rig_->Vfo () + && (writable_params_ & (OmniRig::PM_VFOA | OmniRig::PM_VFOB)) + == (OmniRig::PM_VFOA | OmniRig::PM_VFOB)) + { + // start with VFO A (probably MAIN) on rigs that we + // can't query VFO but can set explicitly + rig_->SetVfo (OmniRig::PM_VFOA); + } + f = state ().frequency (); + if (f % 10) return resolution; // 1Hz resolution + auto test_frequency = f - f % 100 + 55; + if (OmniRig::PM_FREQ & writable_params_) + { + rig_->SetFreq (test_frequency); + } + else if (reversed_ && (OmniRig::PM_FREQB & writable_params_)) + { + rig_->SetFreqB (test_frequency); + } + else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_)) + { + rig_->SetFreqA (test_frequency); + } + else + { + throw_qstring (tr ("OmniRig: don't know how to set rig frequency")); + } + if (!await_notification_with_timeout (1000)) + { + TRACE_CAT ("OmniRigTransceiver", "do_start 1: wait timed out"); + throw_qstring (tr ("OmniRig: timeout waiting for update from rig")); + } + switch (rig_->GetRxFrequency () - test_frequency) + { + case -5: resolution = -1; break; // 10Hz truncated + case 5: resolution = 1; break; // 10Hz rounded + case -15: resolution = -2; break; // 20Hz truncated + case -55: resolution = -2; break; // 100Hz truncated + case 45: resolution = 2; break; // 100Hz rounded + } + if (1 == resolution) // may be 20Hz rounded + { + test_frequency = f - f % 100 + 51; + if (OmniRig::PM_FREQ & writable_params_) + { + rig_->SetFreq (test_frequency); + } + else if (reversed_ && (OmniRig::PM_FREQB & writable_params_)) + { + rig_->SetFreqB (test_frequency); + } + else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_)) + { + rig_->SetFreqA (test_frequency); + } + if (!await_notification_with_timeout (2000)) + { + TRACE_CAT ("OmniRigTransceiver", "do_start 2: wait timed out"); + throw_qstring (tr ("OmniRig: timeout waiting for update from rig")); + } + if (9 == rig_->GetRxFrequency () - test_frequency) + { + resolution = 2; // 20Hz rounded } } - throw_qstring (tr ("OmniRig: Initialization timed out")); - return 0; // keep compiler happy + if (OmniRig::PM_FREQ & writable_params_) + { + rig_->SetFreq (f); + } + else if (reversed_ && (OmniRig::PM_FREQB & writable_params_)) + { + rig_->SetFreqB (f); + } + else if (!reversed_ && (OmniRig::PM_FREQA & writable_params_)) + { + rig_->SetFreqA (f); + } + update_rx_frequency (f); + return resolution; } void OmniRigTransceiver::do_stop () { - if (offline_timer_) - { - offline_timer_->stop (); - offline_timer_.reset (); - } - QThread::msleep (200); // leave some time for pending // commands at the server end if (port_) @@ -300,17 +318,6 @@ void OmniRigTransceiver::do_stop () TRACE_CAT ("OmniRigTransceiver", "stopped"); } -void OmniRigTransceiver::do_sync (bool force_signal, bool /*no_poll*/) -{ - // nothing much we can do here, we just have to let OmniRig do its - // stuff and its first poll should send us and update that will - // trigger a update signal from us. Any attempt to query OmniRig - // leads to a whole mess of trouble since its internal state is - // garbage until it has done its first rig poll. - send_update_signal_ = force_signal; - update_complete (); -} - void OmniRigTransceiver::handle_COM_exception (int code, QString source, QString desc, QString help) { TRACE_CAT ("OmniRigTransceiver", QString::number (code) + " at " + source + ": " + desc + " (" + help + ')'); @@ -319,16 +326,20 @@ void OmniRigTransceiver::handle_COM_exception (int code, QString source, QString void OmniRigTransceiver::handle_visible_change () { + if (!omni_rig_ || omni_rig_->isNull ()) return; TRACE_CAT ("OmniRigTransceiver", "visibility change: visibility =" << omni_rig_->DialogVisible ()); } void OmniRigTransceiver::handle_rig_type_change (int rig_number) { + if (!omni_rig_ || omni_rig_->isNull ()) return; + TRACE_CAT ("OmniRigTransceiver", "rig type change: rig =" << rig_number); if (rig_number_ == rig_number) { + if (!rig_ || rig_->isNull ()) return; readable_params_ = rig_->ReadableParams (); writable_params_ = rig_->WriteableParams (); - TRACE_CAT ("OmniRigTransceiver", QString {"OmniRig rig type change to: %1 readable params = 0x%2 writable params = 0x%3 for rig %4"} + TRACE_CAT ("OmniRigTransceiver", QString {"rig type change to: %1 readable params = 0x%2 writable params = 0x%3 for rig %4"} .arg (rig_->RigType ()) .arg (readable_params_, 8, 16, QChar ('0')) .arg (writable_params_, 8, 16, QChar ('0')) @@ -338,48 +349,47 @@ void OmniRigTransceiver::handle_rig_type_change (int rig_number) void OmniRigTransceiver::handle_status_change (int rig_number) { + if (!omni_rig_ || omni_rig_->isNull ()) return; + TRACE_CAT ("OmniRigTransceiver", QString {"status change for rig %1"}.arg (rig_number).toLocal8Bit ()); if (rig_number_ == rig_number) { + if (!rig_ || rig_->isNull ()) return; auto const& status = rig_->StatusStr ().toLocal8Bit (); - TRACE_CAT ("OmniRigTransceiver", QString {"OmniRig status change: new status for rig %1 = "}.arg (rig_number).toLocal8Bit () << status); + TRACE_CAT ("OmniRigTransceiver", "OmniRig status change: new status = " << status); if (OmniRig::ST_ONLINE != rig_->Status ()) { - if (!offline_timer_->isActive ()) - { - offline_timer_->start (); // give OmniRig time to recover - } + offline ("Rig went offline"); } else { - offline_timer_->stop (); - update_rx_frequency (rig_->GetRxFrequency ()); - update_complete (); - TRACE_CAT ("OmniRigTransceiver", "OmniRig frequency:" << state ().frequency ()); + Q_EMIT notified (); } + // else + // { + // update_rx_frequency (rig_->GetRxFrequency ()); + // update_complete (); + // TRACE_CAT ("OmniRigTransceiver", "frequency:" << state ().frequency ()); + // } } } -void OmniRigTransceiver::timeout_check () -{ - offline ("Rig went offline"); -} - void OmniRigTransceiver::handle_params_change (int rig_number, int params) { - if (rig_number_ == rig_number) - { - TRACE_CAT ("OmniRigTransceiver", QString {"OmniRig params change: params = 0x%1 for rig %2"} + if (!omni_rig_ || omni_rig_->isNull ()) return; + TRACE_CAT ("OmniRigTransceiver", QString {"params change: params = 0x%1 for rig %2"} .arg (params, 8, 16, QChar ('0')) .arg (rig_number).toLocal8Bit () << "state before:" << state ()); + if (rig_number_ == rig_number) + { + if (!rig_ || rig_->isNull ()) return; // starting_ = false; TransceiverState old_state {state ()}; auto need_frequency = false; - // state_.online = true; // sometimes we don't get an initial - // // OmniRig::ST_ONLINE status change - // // event + if (params & OmniRig::PM_VFOAA) { + TRACE_CAT ("OmniRigTransceiver", "VFOAA"); update_split (false); reversed_ = false; update_rx_frequency (rig_->FreqA ()); @@ -387,6 +397,7 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params) } if (params & OmniRig::PM_VFOAB) { + TRACE_CAT ("OmniRigTransceiver", "VFOAB"); update_split (true); reversed_ = false; update_rx_frequency (rig_->FreqA ()); @@ -394,6 +405,7 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params) } if (params & OmniRig::PM_VFOBA) { + TRACE_CAT ("OmniRigTransceiver", "VFOBA"); update_split (true); reversed_ = true; update_other_frequency (rig_->FreqA ()); @@ -401,6 +413,7 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params) } if (params & OmniRig::PM_VFOBB) { + TRACE_CAT ("OmniRigTransceiver", "VFOBB"); update_split (false); reversed_ = true; update_other_frequency (rig_->FreqA ()); @@ -408,154 +421,195 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params) } if (params & OmniRig::PM_VFOA) { + TRACE_CAT ("OmniRigTransceiver", "VFOA"); reversed_ = false; need_frequency = true; } if (params & OmniRig::PM_VFOB) { + TRACE_CAT ("OmniRigTransceiver", "VFOB"); reversed_ = true; need_frequency = true; } if (params & OmniRig::PM_FREQ) { + TRACE_CAT ("OmniRigTransceiver", "FREQ"); need_frequency = true; } if (params & OmniRig::PM_FREQA) { + auto f = rig_->FreqA (); + TRACE_CAT ("OmniRigTransceiver", "FREQA = " << f); if (reversed_) { - update_other_frequency (rig_->FreqA ()); + update_other_frequency (f); } else { - update_rx_frequency (rig_->FreqA ()); + update_rx_frequency (f); } } if (params & OmniRig::PM_FREQB) { + auto f = rig_->FreqB (); + TRACE_CAT ("OmniRigTransceiver", "FREQB = " << f); if (reversed_) { - update_rx_frequency (rig_->FreqB ()); + update_rx_frequency (f); } else { - update_other_frequency (rig_->FreqB ()); + update_other_frequency (f); } } if (need_frequency) { if (readable_params_ & OmniRig::PM_FREQA) { - if (reversed_) + auto f = rig_->FreqA (); + if (f) { - update_other_frequency (rig_->FreqA ()); + TRACE_CAT ("OmniRigTransceiver", "FREQA = " << f); + if (reversed_) + { + update_other_frequency (f); + } + else + { + update_rx_frequency (f); + } } - else - { - update_rx_frequency (rig_->FreqA ()); - } - need_frequency = false; } if (readable_params_ & OmniRig::PM_FREQB) { - if (reversed_) + auto f = rig_->FreqB (); + if (f) { - update_rx_frequency (rig_->FreqB ()); + TRACE_CAT ("OmniRigTransceiver", "FREQB = " << f); + if (reversed_) + { + update_rx_frequency (f); + } + else + { + update_other_frequency (f); + } + } + } + if (readable_params_ & OmniRig::PM_FREQ && !state ().ptt ()) + { + auto f = rig_->Freq (); + if (f) + { + TRACE_CAT ("OmniRigTransceiver", "FREQ = " << f); + update_rx_frequency (f); } - else - { - update_other_frequency (rig_->FreqB ()); - } - need_frequency = false; } - } - if (need_frequency && (readable_params_ & OmniRig::PM_FREQ) - && !state ().ptt ()) - { - update_rx_frequency (rig_->Freq ()); } if (params & OmniRig::PM_PITCH) { + TRACE_CAT ("OmniRigTransceiver", "PITCH"); } if (params & OmniRig::PM_RITOFFSET) { + TRACE_CAT ("OmniRigTransceiver", "RITOFFSET"); } if (params & OmniRig::PM_RIT0) { + TRACE_CAT ("OmniRigTransceiver", "RIT0"); } if (params & OmniRig::PM_VFOEQUAL) { auto f = readable_params_ & OmniRig::PM_FREQA ? rig_->FreqA () : rig_->Freq (); + auto m = map_mode (rig_->Mode ()); + TRACE_CAT ("OmniRigTransceiver", QString {"VFOEQUAL f=%1 m=%2"}.arg (f).arg (m)); update_rx_frequency (f); update_other_frequency (f); - update_mode (map_mode (rig_->Mode ())); + update_mode (m); } if (params & OmniRig::PM_VFOSWAP) { - auto temp = state ().tx_frequency (); + TRACE_CAT ("OmniRigTransceiver", "VFOSWAP"); + auto f = state ().tx_frequency (); update_other_frequency (state ().frequency ()); - update_rx_frequency (temp); + update_rx_frequency (f); update_mode (map_mode (rig_->Mode ())); } if (params & OmniRig::PM_SPLITON) { + TRACE_CAT ("OmniRigTransceiver", "SPLITON"); update_split (true); } if (params & OmniRig::PM_SPLITOFF) { + TRACE_CAT ("OmniRigTransceiver", "SPLITOFF"); update_split (false); } if (params & OmniRig::PM_RITON) { + TRACE_CAT ("OmniRigTransceiver", "RITON"); } if (params & OmniRig::PM_RITOFF) { + TRACE_CAT ("OmniRigTransceiver", "RITOFF"); } if (params & OmniRig::PM_XITON) { + TRACE_CAT ("OmniRigTransceiver", "XITON"); } if (params & OmniRig::PM_XITOFF) { + TRACE_CAT ("OmniRigTransceiver", "XITOFF"); } if (params & OmniRig::PM_RX) { + TRACE_CAT ("OmniRigTransceiver", "RX"); update_PTT (false); } if (params & OmniRig::PM_TX) { + TRACE_CAT ("OmniRigTransceiver", "TX"); update_PTT (); } if (params & OmniRig::PM_CW_U) { + TRACE_CAT ("OmniRigTransceiver", "CW-R"); update_mode (CW_R); } if (params & OmniRig::PM_CW_L) { + TRACE_CAT ("OmniRigTransceiver", "CW"); update_mode (CW); } if (params & OmniRig::PM_SSB_U) { + TRACE_CAT ("OmniRigTransceiver", "USB"); update_mode (USB); } if (params & OmniRig::PM_SSB_L) { + TRACE_CAT ("OmniRigTransceiver", "LSB"); update_mode (LSB); } if (params & OmniRig::PM_DIG_U) { + TRACE_CAT ("OmniRigTransceiver", "DATA-U"); update_mode (DIG_U); } if (params & OmniRig::PM_DIG_L) { + TRACE_CAT ("OmniRigTransceiver", "DATA-L"); update_mode (DIG_L); } if (params & OmniRig::PM_AM) { + TRACE_CAT ("OmniRigTransceiver", "AM"); update_mode (AM); } if (params & OmniRig::PM_FM) { + TRACE_CAT ("OmniRigTransceiver", "FM"); update_mode (FM); } @@ -566,6 +620,7 @@ void OmniRigTransceiver::handle_params_change (int rig_number, int params) } TRACE_CAT ("OmniRigTransceiver", "OmniRig params change: state after:" << state ()); } + Q_EMIT notified (); } void OmniRigTransceiver::handle_custom_reply (int rig_number, QVariant const& command, QVariant const& reply) @@ -573,8 +628,10 @@ void OmniRigTransceiver::handle_custom_reply (int rig_number, QVariant const& co (void)command; (void)reply; + if (!omni_rig_ || omni_rig_->isNull ()) return; if (rig_number_ == rig_number) { + if (!rig_ || rig_->isNull ()) return; TRACE_CAT ("OmniRigTransceiver", "custom command" << command.toString ().toLocal8Bit () << "with reply" << reply.toString ().toLocal8Bit () << QString ("for rig %1").arg (rig_number).toLocal8Bit ()); diff --git a/OmniRigTransceiver.hpp b/OmniRigTransceiver.hpp index c63266b69..2ba5fd4d3 100644 --- a/OmniRigTransceiver.hpp +++ b/OmniRigTransceiver.hpp @@ -38,10 +38,11 @@ public: void do_tx_frequency (Frequency, MODE, bool no_ignore) override; void do_mode (MODE) override; void do_ptt (bool on) override; - void do_sync (bool force_signal, bool no_poll) override; private: - Q_SLOT void timeout_check (); + bool await_notification_with_timeout (int timeout); + Q_SIGNAL void notified () const; + // Q_SLOT void timeout_check (); Q_SLOT void handle_COM_exception (int, QString, QString, QString); Q_SLOT void handle_visible_change (); Q_SLOT void handle_rig_type_change (int rig_number); @@ -62,7 +63,7 @@ private: QString rig_type_; int readable_params_; int writable_params_; - QScopedPointer offline_timer_; + // QScopedPointer offline_timer_; bool send_update_signal_; bool reversed_; // some rigs can reverse VFOs }; diff --git a/PollingTransceiver.cpp b/PollingTransceiver.cpp index b2bbab179..ed47144af 100644 --- a/PollingTransceiver.cpp +++ b/PollingTransceiver.cpp @@ -129,52 +129,46 @@ bool PollingTransceiver::do_pre_update () return true; } -void PollingTransceiver::do_sync (bool force_signal, bool no_poll) -{ - if (!no_poll) poll (); // tell sub-classes to update our state - - // Signal new state if it is directly requested or, what we expected - // or, hasn't become what we expected after polls_to_stabilize - // polls. Unsolicited changes will be signalled immediately unless - // they intervene in a expected sequence where they will be delayed. - if (retries_) - { - --retries_; - if (force_signal || state () == next_state_ || !retries_) - { - // our client wants a signal regardless - // or the expected state has arrived - // or there are no more retries - force_signal = true; - } - } - else if (force_signal || state () != last_signalled_state_) - { - // here is the normal passive polling path either our client has - // requested a state update regardless of change or state has - // changed asynchronously - force_signal = true; - } - - if (force_signal) - { - // reset everything, record and signal the current state - retries_ = 0; - next_state_ = state (); - last_signalled_state_ = state (); - update_complete (true); - } -} - void PollingTransceiver::handle_timeout () { QString message; + bool force_signal {false}; // we must catch all exceptions here since we are called by Qt and // inform our parent of the failure via the offline() message try { - do_sync (); + do_poll (); // tell sub-classes to update our state + + // Signal new state if it what we expected or, hasn't become + // what we expected after polls_to_stabilize polls. Unsolicited + // changes will be signalled immediately unless they intervene + // in a expected sequence where they will be delayed. + if (retries_) + { + --retries_; + if (state () == next_state_ || !retries_) + { + // the expected state has arrived or there are no more + // retries + force_signal = true; + } + } + else if (state () != last_signalled_state_) + { + // here is the normal passive polling path where state has + // changed asynchronously + force_signal = true; + } + + if (force_signal) + { + // reset everything, record and signal the current state + retries_ = 0; + next_state_ = state (); + last_signalled_state_ = state (); + update_complete (true); + } } catch (std::exception const& e) { diff --git a/PollingTransceiver.hpp b/PollingTransceiver.hpp index 0945c84ac..a9e639f9d 100644 --- a/PollingTransceiver.hpp +++ b/PollingTransceiver.hpp @@ -39,11 +39,9 @@ protected: QObject * parent); protected: - void do_sync (bool force_signal = false, bool no_poll = false) override final; - // Sub-classes implement this and fetch what they can from the rig // in a non-intrusive manner. - virtual void poll () = 0; + virtual void do_poll () = 0; void do_post_start () override final; void do_post_stop () override final; diff --git a/Radio.cpp b/Radio.cpp index 3940815f4..e5b34c35d 100644 --- a/Radio.cpp +++ b/Radio.cpp @@ -74,14 +74,14 @@ namespace Radio } - QString frequency_MHz_string (Frequency f, QLocale const& locale) + QString frequency_MHz_string (Frequency f, int precision, QLocale const& locale) { - return locale.toString (f / MHz_factor, 'f', frequency_precsion); + return locale.toString (f / MHz_factor, 'f', precision); } - QString frequency_MHz_string (FrequencyDelta d, QLocale const& locale) + QString frequency_MHz_string (FrequencyDelta d, int precision, QLocale const& locale) { - return locale.toString (d / MHz_factor, 'f', frequency_precsion); + return locale.toString (d / MHz_factor, 'f', precision); } QString pretty_frequency_MHz_string (Frequency f, QLocale const& locale) diff --git a/Radio.hpp b/Radio.hpp index 7f8b0a0f4..e63abf4b8 100644 --- a/Radio.hpp +++ b/Radio.hpp @@ -42,8 +42,8 @@ namespace Radio // // Frequency type formatting // - QString UDP_EXPORT frequency_MHz_string (Frequency, QLocale const& = QLocale ()); - QString UDP_EXPORT frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ()); + QString UDP_EXPORT frequency_MHz_string (Frequency, int precision = 6, QLocale const& = QLocale ()); + QString UDP_EXPORT frequency_MHz_string (FrequencyDelta, int precision = 6, QLocale const& = QLocale ()); QString UDP_EXPORT pretty_frequency_MHz_string (Frequency, QLocale const& = QLocale ()); QString UDP_EXPORT pretty_frequency_MHz_string (double, int scale, QLocale const& = QLocale ()); QString UDP_EXPORT pretty_frequency_MHz_string (FrequencyDelta, QLocale const& = QLocale ()); diff --git a/Release_Notes.txt b/Release_Notes.txt index c59ffafca..ed4ab7d92 100644 --- a/Release_Notes.txt +++ b/Release_Notes.txt @@ -12,6 +12,157 @@ Copyright 2001 - 2019 by Joe Taylor, K1JT. + Release: WSJT-X 2.1.0-rc7 + June 3, 2019 + ------------------------- + +This release is a bug fix only release addressing regressions in the +prior RC6 release. There are no functional changes other than an +updated AD1C CTY.DAT database. + + + Release: WSJT-X 2.1.0-rc6 + June 2, 2019 + ------------------------- + +Changes and bug fixes since WSJT-X 2.1.0-rc5: + +IMPORTANT CHANGES TO THE FT4 PROTOCOL *** NOT BACKWARD COMPATIBLE *** + - T/R sequence length increased from 6.0 to 7.5 seconds + - Symbol rate decreased from 23.4375 to 20.8333 baud + - Signal bandwidth decreased from 90 Hz to 80 Hz + +OTHER FT4 IMPROVEMENTS + - Allowable time offsets -1.0 < DT < +1.0 s + - Tx4 message with RRR now allowed, except in contest messages + - Audio frequency is now sent to PSK Reporter + - Add a third decoding pass + - Add ordered statistics decoding + - Improved sensitivity: threshold S/N is now -17.5 dB + - Improved S/N calculation + - In FT4 mode, Shift+F11/F12 moves Tx freq by +/- 100 Hz + +OTHER IMPROVEMENTS + - Improvements to accessibility + - Updates to the User Guide (not yet complete, however) + - New user option: "Calling CQ forces Call 1st" + - N1MM Logger+ now uses the standard WSJT-X UDP messages + - OK/Cancel buttons on Log QSO window maintain fixed positions + - Put EU VHF contest serial numbers into the ADIF SRX and STX fields + - Enhancements to the Omni-Rig CAT interface + - New setting option to include or exclude WAE entities + +BUG FIXES + - Fix generation of Tx5 message when one callsign is nonstandard + - Fix a bug that prevented use on macOS + - Fix a bug that caused mode switch from FT4 to FT8 + - Fix a bug that caused FT4 to do WSPR-style band hopping + - Fix a bug that caused a Fortran bounds error + - Repaired field editing in the Contest Log window + +Release candidate WSJT-X 2.1.0-rc6 will be available for beta-testing +through July 21, 2019. It will be inoperable during the ARRL June VHF +QSO Party (June 8-10) or ARRL Field Day (June 22-23). It will +permanently cease to function after July 21, 2019. If all goes +according to plan, by that time there will be a General +Availability (GA) release of WSJT-X 2.1.0. + + + Release: WSJT-X 2.1.0-rc5 + April 29, 2019 + ------------------------- + +WSJT-X 2.1.0 fifth release candidate is a minor release including the +following. + + - Repairs a defect that stopped messages from UDP servers being accepted. + - Improved message sequencing a QSO end for CQing FT4 stations. + - "Best S+P" action times out after two minutes waiting for a candidate. + - Updated macOS Info.plist to comply with latest mic. privacy controls. + - Multi-pass decoding for FT4 inc. prior decode subtraction. + - Fast/Normal/Deep options for the FT4 decoder. + - Proposed suggested working frequencies for the new FT4 mode. + - Repair a defect in RTTY RU where sequencer fails to advance to Tx3. + - Fix a defect where the contest serial # spin box was incorrectly hidden. + - Fix defects in ALL.TXT formatting for JT65 and JT9. + - Reduce timeout for AP decoding with own call from 10 mins to 5 mins. + + + Release: WSJT-X 2.1.0-rc4 + April 10, 2019 + ------------------------- + +WSJT-X 2.1.0 fourth release candidate is a minor release including the +following. + + - New "Call Best" button for FT4 mode to select the best reply to a + CQ call based on neediness. + - Fixed UTC display on FT4 waterfall. + +This release is made by invitation only to selected testers to trial +the FT4 mode in semi-realistic contest simulations and to elicit +feedback to guide future development. + +*Note* this release is not for general public release and we request + that it is not distributed. + + + Release: WSJT-X 2.1.0-rc3 + April 5, 2019 + ------------------------- + +WSJT-X 2.1.0 third release candidate is an enhancement release to +change the implementation of the new FT4 mode to a synchronous T/R +period of 6 seconds. + +This release is made by invitation only to selected testers to trial +the FT4 mode in semi-realistic contest simulations and to elicit +feedback to guide future development. + +*Note* this release is not for general public release and we request + that it is not distributed. + + + Release: WSJT-X 2.1.0-rc2 + March 29, 2019 + ------------------------- + +WSJT-X 2.1.0 second release candidate is a bug fix release to repair +some usability issues with FT4 contest mode. The following new +features are also included. + + - Better options for QSO flow by clicking Tx# buttons to transmit + - A 64-bit package for Windows 64-bit systems + - Improved FT4 sync detection speed + +This release is made by invitation only to selected testers to trial +the FT4 mode in semi-realistic contest simulations and to elicit +feedback to guide future development. + +*Note* this release is not for general public release and we request +that it is not distributed. + + Release: WSJT-X 2.1.0-rc1 + March 25, 2019 + ------------------------- + +WSJT-X 2.1.0 first release candidate is a preview alpha quality +release containing the following new features. + + - FT4 mode, a new mode targeted at HF digital contesting + - GMSK modulation for FT4 and FT8 + - New waterfall option to select between raw sensitivity or a + filtered signal representation for best visualization of signal + quality + +This release is made by invitation only to selected testers to trial +the FT4 mode in semi-realistic contest simulations and to elicit +feedback to guide future development. + +*Note* this release is not for general public release and we request +that it is not distributed. + + Release: WSJT-X 2.0.1 February 25, 2019 --------------------- diff --git a/TransceiverBase.cpp b/TransceiverBase.cpp index ef77d51e4..f1decb682 100644 --- a/TransceiverBase.cpp +++ b/TransceiverBase.cpp @@ -19,10 +19,10 @@ void TransceiverBase::start (unsigned sequence_number) noexcept QString message; try { + last_sequence_number_ = sequence_number; may_update u {this, true}; shutdown (); startup (); - last_sequence_number_ = sequence_number; } catch (std::exception const& e) { @@ -46,6 +46,7 @@ void TransceiverBase::set (TransceiverState const& s, QString message; try { + last_sequence_number_ = sequence_number; may_update u {this, true}; bool was_online {requested_.online ()}; if (!s.online () && was_online) @@ -115,7 +116,6 @@ void TransceiverBase::set (TransceiverState const& s, // record what actually changed requested_.ptt (actual_.ptt ()); } - last_sequence_number_ = sequence_number; } catch (std::exception const& e) { @@ -133,10 +133,27 @@ void TransceiverBase::set (TransceiverState const& s, void TransceiverBase::startup () { - Q_EMIT resolution (do_start ()); - do_post_start (); - actual_.online (true); - requested_.online (true); + QString message; + try + { + actual_.online (true); + requested_.online (true); + auto res = do_start (); + do_post_start (); + Q_EMIT resolution (res); + } + catch (std::exception const& e) + { + message = e.what (); + } + catch (...) + { + message = unexpected; + } + if (!message.isEmpty ()) + { + offline (message); + } } void TransceiverBase::shutdown () @@ -163,8 +180,8 @@ void TransceiverBase::shutdown () } do_stop (); do_post_stop (); - actual_.online (false); - requested_.online (false); + actual_ = TransceiverState {}; + requested_ = TransceiverState {}; } void TransceiverBase::stop () noexcept @@ -194,8 +211,11 @@ void TransceiverBase::stop () noexcept void TransceiverBase::update_rx_frequency (Frequency rx) { - actual_.frequency (rx); - requested_.frequency (rx); // track rig changes + if (rx) + { + actual_.frequency (rx); + requested_.frequency (rx); // track rig changes + } } void TransceiverBase::update_other_frequency (Frequency tx) diff --git a/TransceiverBase.hpp b/TransceiverBase.hpp index ea981d44b..7d43cc32e 100644 --- a/TransceiverBase.hpp +++ b/TransceiverBase.hpp @@ -112,8 +112,6 @@ protected: virtual void do_ptt (bool = true) = 0; virtual void do_post_ptt (bool = true) {} - virtual void do_sync (bool force_signal = false, bool no_poll = false) = 0; - virtual bool do_pre_update () {return true;} // sub classes report rig state changes with these methods diff --git a/UDPExamples/ClientWidget.cpp b/UDPExamples/ClientWidget.cpp index 1715670bf..ecf0b54fe 100644 --- a/UDPExamples/ClientWidget.cpp +++ b/UDPExamples/ClientWidget.cpp @@ -1,8 +1,11 @@ #include "ClientWidget.hpp" +#include #include #include +#include #include +#include #include "validators/MaidenheadLocatorValidator.hpp" @@ -11,6 +14,9 @@ namespace //QRegExp message_alphabet {"[- A-Za-z0-9+./?]*"}; QRegExp message_alphabet {"[- @A-Za-z0-9+./?#<>]*"}; QRegularExpression cq_re {"(CQ|CQDX|QRZ)[^A-Z0-9/]+"}; + QRegExpValidator message_validator {message_alphabet}; + MaidenheadLocatorValidator locator_validator; + quint32 quint32_max {std::numeric_limits::max ()}; void update_dynamic_property (QWidget * widget, char const * property, QVariant const& value) { @@ -21,9 +27,10 @@ namespace } } -ClientWidget::IdFilterModel::IdFilterModel (QString const& client_id) - : client_id_ {client_id} - , rx_df_ (-1) +ClientWidget::IdFilterModel::IdFilterModel (QString const& client_id, QObject * parent) + : QSortFilterProxyModel {parent} + , client_id_ {client_id} + , rx_df_ (quint32_max) { } @@ -49,7 +56,7 @@ QVariant ClientWidget::IdFilterModel::data (QModelIndex const& proxy_index, int break; case 4: // DF - if (qAbs (QSortFilterProxyModel::data (proxy_index).toInt () - rx_df_) <= 10) + if (qAbs (QSortFilterProxyModel::data (proxy_index).toUInt () - rx_df_) <= 10) { return QColor {255, 200, 200}; } @@ -87,7 +94,7 @@ void ClientWidget::IdFilterModel::de_call (QString const& call) } } -void ClientWidget::IdFilterModel::rx_df (int df) +void ClientWidget::IdFilterModel::rx_df (quint32 df) { if (df != rx_df_) { @@ -119,26 +126,48 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod , QListWidget const * calls_of_interest, QWidget * parent) : QDockWidget {make_title (id, version, revision), parent} , id_ {id} + , done_ {false} , calls_of_interest_ {calls_of_interest} - , decodes_proxy_model_ {id_} + , decodes_proxy_model_ {id} + , beacons_proxy_model_ {id} , erase_action_ {new QAction {tr ("&Erase Band Activity"), this}} , erase_rx_frequency_action_ {new QAction {tr ("Erase &Rx Frequency"), this}} , erase_both_action_ {new QAction {tr ("Erase &Both"), this}} - , decodes_table_view_ {new QTableView} - , beacons_table_view_ {new QTableView} - , message_line_edit_ {new QLineEdit} - , grid_line_edit_ {new QLineEdit} + , decodes_table_view_ {new QTableView {this}} + , beacons_table_view_ {new QTableView {this}} + , message_line_edit_ {new QLineEdit {this}} + , grid_line_edit_ {new QLineEdit {this}} + , generate_messages_push_button_ {new QPushButton {tr ("&Gen Msgs"), this}} + , auto_off_button_ {nullptr} + , halt_tx_button_ {nullptr} + , de_label_ {new QLabel {this}} + , frequency_label_ {new QLabel {this}} + , tx_df_label_ {new QLabel {this}} + , report_label_ {new QLabel {this}} + , configuration_line_edit_ {new QLineEdit {this}} + , mode_line_edit_ {new QLineEdit {this}} + , frequency_tolerance_spin_box_ {new QSpinBox {this}} + , tx_mode_label_ {new QLabel {this}} + , submode_line_edit_ {new QLineEdit {this}} + , fast_mode_check_box_ {new QCheckBox {this}} + , tr_period_spin_box_ {new QSpinBox {this}} + , rx_df_spin_box_ {new QSpinBox {this}} + , dx_call_line_edit_ {new QLineEdit {this}} + , dx_grid_line_edit_ {new QLineEdit {this}} + , decodes_page_ {new QWidget {this}} + , beacons_page_ {new QWidget {this}} + , content_widget_ {new QFrame {this}} + , status_bar_ {new QStatusBar {this}} + , control_button_box_ {new QDialogButtonBox {this}} + , form_layout_ {new QFormLayout} + , horizontal_layout_ {new QHBoxLayout} + , subform1_layout_ {new QFormLayout} + , subform2_layout_ {new QFormLayout} + , subform3_layout_ {new QFormLayout} + , decodes_layout_ {new QVBoxLayout {decodes_page_}} + , beacons_layout_ {new QVBoxLayout {beacons_page_}} + , content_layout_ {new QVBoxLayout {content_widget_}} , decodes_stack_ {new QStackedLayout} - , auto_off_button_ {new QPushButton {tr ("&Auto Off")}} - , halt_tx_button_ {new QPushButton {tr ("&Halt Tx")}} - , de_label_ {new QLabel} - , mode_label_ {new QLabel} - , fast_mode_ {false} - , frequency_label_ {new QLabel} - , dx_label_ {new QLabel} - , rx_df_label_ {new QLabel} - , tx_df_label_ {new QLabel} - , report_label_ {new QLabel} , columns_resized_ {false} { // set up widgets @@ -152,11 +181,33 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod decodes_table_view_->insertAction (nullptr, erase_rx_frequency_action_); decodes_table_view_->insertAction (nullptr, erase_both_action_); - auto form_layout = new QFormLayout; - form_layout->addRow (tr ("Free text:"), message_line_edit_); - form_layout->addRow (tr ("Temporary grid:"), grid_line_edit_); - message_line_edit_->setValidator (new QRegExpValidator {message_alphabet, this}); - grid_line_edit_->setValidator (new MaidenheadLocatorValidator {this}); + message_line_edit_->setValidator (&message_validator); + grid_line_edit_->setValidator (&locator_validator); + dx_grid_line_edit_->setValidator (&locator_validator); + tr_period_spin_box_->setRange (5, 30); + tr_period_spin_box_->setSuffix (" s"); + rx_df_spin_box_->setRange (200, 5000); + frequency_tolerance_spin_box_->setRange (10, 1000); + frequency_tolerance_spin_box_->setPrefix ("\u00b1"); + frequency_tolerance_spin_box_->setSuffix (" Hz"); + + form_layout_->addRow (tr ("Free text:"), message_line_edit_); + form_layout_->addRow (tr ("Temporary grid:"), grid_line_edit_); + form_layout_->addRow (tr ("Configuration name:"), configuration_line_edit_); + form_layout_->addRow (horizontal_layout_); + subform1_layout_->addRow (tr ("Mode:"), mode_line_edit_); + subform2_layout_->addRow (tr ("Submode:"), submode_line_edit_); + subform3_layout_->addRow (tr ("Fast mode:"), fast_mode_check_box_); + subform1_layout_->addRow (tr ("T/R period:"), tr_period_spin_box_); + subform2_layout_->addRow (tr ("Rx DF:"), rx_df_spin_box_); + subform3_layout_->addRow (tr ("Freq. Tol:"), frequency_tolerance_spin_box_); + subform1_layout_->addRow (tr ("DX call:"), dx_call_line_edit_); + subform2_layout_->addRow (tr ("DX grid:"), dx_grid_line_edit_); + subform3_layout_->addRow (generate_messages_push_button_); + horizontal_layout_->addLayout (subform1_layout_); + horizontal_layout_->addLayout (subform2_layout_); + horizontal_layout_->addLayout (subform3_layout_); + connect (message_line_edit_, &QLineEdit::textEdited, [this] (QString const& text) { Q_EMIT do_free_text (id_, text, false); }); @@ -166,66 +217,102 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod connect (grid_line_edit_, &QLineEdit::editingFinished, [this] () { Q_EMIT location (id_, grid_line_edit_->text ()); }); + connect (configuration_line_edit_, &QLineEdit::editingFinished, [this] () { + Q_EMIT switch_configuration (id_, configuration_line_edit_->text ()); + }); + connect (mode_line_edit_, &QLineEdit::editingFinished, [this] () { + QString empty; + Q_EMIT configure (id_, mode_line_edit_->text (), quint32_max, empty, fast_mode () + , quint32_max, quint32_max, empty, empty, false); + }); + connect (frequency_tolerance_spin_box_, static_cast (&QSpinBox::valueChanged), [this] (int i) { + QString empty; + auto f = frequency_tolerance_spin_box_->specialValueText ().size () ? quint32_max : i; + Q_EMIT configure (id_, empty, f, empty, fast_mode () + , quint32_max, quint32_max, empty, empty, false); + }); + connect (submode_line_edit_, &QLineEdit::editingFinished, [this] () { + QString empty; + Q_EMIT configure (id_, empty, quint32_max, submode_line_edit_->text (), fast_mode () + , quint32_max, quint32_max, empty, empty, false); + }); + connect (fast_mode_check_box_, &QCheckBox::stateChanged, [this] (int state) { + QString empty; + Q_EMIT configure (id_, empty, quint32_max, empty, Qt::Checked == state + , quint32_max, quint32_max, empty, empty, false); + }); + connect (tr_period_spin_box_, static_cast (&QSpinBox::valueChanged), [this] (int i) { + QString empty; + Q_EMIT configure (id_, empty, quint32_max, empty, fast_mode () + , i, quint32_max, empty, empty, false); + }); + connect (rx_df_spin_box_, static_cast (&QSpinBox::valueChanged), [this] (int i) { + QString empty; + Q_EMIT configure (id_, empty, quint32_max, empty, fast_mode () + , quint32_max, i, empty, empty, false); + }); + connect (dx_call_line_edit_, &QLineEdit::editingFinished, [this] () { + QString empty; + Q_EMIT configure (id_, empty, quint32_max, empty, fast_mode () + , quint32_max, quint32_max, dx_call_line_edit_->text (), empty, false); + }); + connect (dx_grid_line_edit_, &QLineEdit::editingFinished, [this] () { + QString empty; + Q_EMIT configure (id_, empty, quint32_max, empty, fast_mode () + , quint32_max, quint32_max, empty, dx_grid_line_edit_->text (), false); + }); - auto decodes_page = new QWidget; - auto decodes_layout = new QVBoxLayout {decodes_page}; - decodes_layout->setContentsMargins (QMargins {2, 2, 2, 2}); - decodes_layout->addWidget (decodes_table_view_); - decodes_layout->addLayout (form_layout); + decodes_layout_->setContentsMargins (QMargins {2, 2, 2, 2}); + decodes_layout_->addWidget (decodes_table_view_); + decodes_layout_->addLayout (form_layout_); - auto beacons_proxy_model = new IdFilterModel {id_}; - beacons_proxy_model->setSourceModel (beacons_model); - beacons_table_view_->setModel (beacons_proxy_model); + beacons_proxy_model_.setSourceModel (beacons_model); + beacons_table_view_->setModel (&beacons_proxy_model_); beacons_table_view_->verticalHeader ()->hide (); beacons_table_view_->hideColumn (0); beacons_table_view_->horizontalHeader ()->setStretchLastSection (true); beacons_table_view_->setContextMenuPolicy (Qt::ActionsContextMenu); beacons_table_view_->insertAction (nullptr, erase_action_); - auto beacons_page = new QWidget; - auto beacons_layout = new QVBoxLayout {beacons_page}; - beacons_layout->setContentsMargins (QMargins {2, 2, 2, 2}); - beacons_layout->addWidget (beacons_table_view_); + beacons_layout_->setContentsMargins (QMargins {2, 2, 2, 2}); + beacons_layout_->addWidget (beacons_table_view_); - decodes_stack_->addWidget (decodes_page); - decodes_stack_->addWidget (beacons_page); + decodes_stack_->addWidget (decodes_page_); + decodes_stack_->addWidget (beacons_page_); // stack alternative views - auto content_layout = new QVBoxLayout; - content_layout->setContentsMargins (QMargins {2, 2, 2, 2}); - content_layout->addLayout (decodes_stack_); + content_layout_->setContentsMargins (QMargins {2, 2, 2, 2}); + content_layout_->addLayout (decodes_stack_); // set up controls - auto control_button_box = new QDialogButtonBox; - control_button_box->addButton (auto_off_button_, QDialogButtonBox::ActionRole); - control_button_box->addButton (halt_tx_button_, QDialogButtonBox::ActionRole); + auto_off_button_ = control_button_box_->addButton (tr ("&Auto Off"), QDialogButtonBox::ActionRole); + halt_tx_button_ = control_button_box_->addButton (tr ("&Halt Tx"), QDialogButtonBox::ActionRole); + connect (generate_messages_push_button_, &QAbstractButton::clicked, [this] (bool /*checked*/) { + QString empty; + Q_EMIT configure (id_, empty, quint32_max, empty, fast_mode () + , quint32_max, quint32_max, empty, empty, true); + }); connect (auto_off_button_, &QAbstractButton::clicked, [this] (bool /* checked */) { Q_EMIT do_halt_tx (id_, true); }); connect (halt_tx_button_, &QAbstractButton::clicked, [this] (bool /* checked */) { Q_EMIT do_halt_tx (id_, false); }); - content_layout->addWidget (control_button_box); + content_layout_->addWidget (control_button_box_); // set up status area - auto status_bar = new QStatusBar; - status_bar->addPermanentWidget (de_label_); - status_bar->addPermanentWidget (mode_label_); - status_bar->addPermanentWidget (frequency_label_); - status_bar->addPermanentWidget (dx_label_); - status_bar->addPermanentWidget (rx_df_label_); - status_bar->addPermanentWidget (tx_df_label_); - status_bar->addPermanentWidget (report_label_); - content_layout->addWidget (status_bar); - connect (this, &ClientWidget::topLevelChanged, status_bar, &QStatusBar::setSizeGripEnabled); + status_bar_->addPermanentWidget (de_label_); + status_bar_->addPermanentWidget (tx_mode_label_); + status_bar_->addPermanentWidget (frequency_label_); + status_bar_->addPermanentWidget (tx_df_label_); + status_bar_->addPermanentWidget (report_label_); + content_layout_->addWidget (status_bar_); + connect (this, &ClientWidget::topLevelChanged, status_bar_, &QStatusBar::setSizeGripEnabled); // set up central widget - auto content_widget = new QFrame; - content_widget->setFrameStyle (QFrame::StyledPanel | QFrame::Sunken); - content_widget->setLayout (content_layout); - setWidget (content_widget); + content_widget_->setFrameStyle (QFrame::StyledPanel | QFrame::Sunken); + setWidget (content_widget_); // setMinimumSize (QSize {550, 0}); - setFeatures (DockWidgetMovable | DockWidgetFloatable); setAllowedAreas (Qt::BottomDockWidgetArea); setFloating (true); @@ -252,6 +339,25 @@ ClientWidget::ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemMod } } +void ClientWidget::dispose () +{ + done_ = true; + close (); +} + +void ClientWidget::closeEvent (QCloseEvent *e) +{ + if (!done_) + { + Q_EMIT do_close (id_); + e->ignore (); // defer closure until client actually closes + } + else + { + QDockWidget::closeEvent (e); + } +} + ClientWidget::~ClientWidget () { for (int row = 0; row < calls_of_interest_->count (); ++row) @@ -261,16 +367,45 @@ ClientWidget::~ClientWidget () } } +bool ClientWidget::fast_mode () const +{ + return fast_mode_check_box_->isChecked (); +} + +namespace +{ + void update_line_edit (QLineEdit * le, QString const& value, bool allow_empty = true) + { + le->setEnabled (value.size () || allow_empty); + if (!(le->hasFocus () && le->isModified ())) + { + le->setText (value); + } + } + + void update_spin_box (QSpinBox * sb, int value, QString const& special_value = QString {}) + { + sb->setSpecialValueText (special_value); + bool enable {0 == special_value.size ()}; + sb->setEnabled (enable); + if (!sb->hasFocus () && enable) + { + sb->setValue (value); + } + } +} + void ClientWidget::update_status (QString const& id, Frequency f, QString const& mode, QString const& dx_call , QString const& report, QString const& tx_mode, bool tx_enabled - , bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df + , bool transmitting, bool decoding, quint32 rx_df, quint32 tx_df , QString const& de_call, QString const& de_grid, QString const& dx_grid - , bool watchdog_timeout, QString const& sub_mode, bool fast_mode - , quint8 special_op_mode) + , bool watchdog_timeout, QString const& submode, bool fast_mode + , quint8 special_op_mode, quint32 frequency_tolerance, quint32 tr_period + , QString const& configuration_name) { - if (id == id_) + if (id == id_) { - fast_mode_ = fast_mode; + fast_mode_check_box_->setChecked (fast_mode); decodes_proxy_model_.de_call (de_call); decodes_proxy_model_.rx_df (rx_df); QString special; @@ -288,21 +423,25 @@ void ClientWidget::update_status (QString const& id, Frequency f, QString const& .arg (de_grid.size () ? '(' + de_grid + ')' : QString {}) .arg (special) : QString {}); - mode_label_->setText (QString {"Mode: %1%2%3%4"} - .arg (mode) - .arg (sub_mode) - .arg (fast_mode && !mode.contains (QRegularExpression {R"(ISCAT|MSK144)"}) ? "fast" : "") + update_line_edit (mode_line_edit_, mode); + update_spin_box (frequency_tolerance_spin_box_, frequency_tolerance + , quint32_max == frequency_tolerance ? QString {"n/a"} : QString {}); + update_line_edit (submode_line_edit_, submode, false); + tx_mode_label_->setText (QString {"Tx Mode: %1"} .arg (tx_mode.isEmpty () || tx_mode == mode ? "" : '(' + tx_mode + ')')); frequency_label_->setText ("QRG: " + Radio::pretty_frequency_MHz_string (f)); - dx_label_->setText (dx_call.size () >= 0 ? QString {"DX: %1%2"}.arg (dx_call) - .arg (dx_grid.size () ? '(' + dx_grid + ')' : QString {}) : QString {}); - rx_df_label_->setText (rx_df >= 0 ? QString {"Rx: %1"}.arg (rx_df) : ""); - tx_df_label_->setText (tx_df >= 0 ? QString {"Tx: %1"}.arg (tx_df) : ""); + update_line_edit (dx_call_line_edit_, dx_call); + update_line_edit (dx_grid_line_edit_, dx_grid); + if (rx_df != quint32_max) update_spin_box (rx_df_spin_box_, rx_df); + update_spin_box (tr_period_spin_box_, tr_period + , quint32_max == tr_period ? QString {"n/a"} : QString {}); + tx_df_label_->setText (QString {"Tx: %1"}.arg (tx_df)); report_label_->setText ("SNR: " + report); update_dynamic_property (frequency_label_, "transmitting", transmitting); auto_off_button_->setEnabled (tx_enabled); halt_tx_button_->setEnabled (transmitting); - update_dynamic_property (mode_label_, "decoding", decoding); + update_line_edit (configuration_line_edit_, configuration_name); + update_dynamic_property (mode_line_edit_, "decoding", decoding); update_dynamic_property (tx_df_label_, "watchdog_timeout", watchdog_timeout); } } diff --git a/UDPExamples/ClientWidget.hpp b/UDPExamples/ClientWidget.hpp index 22488531c..983ddd874 100644 --- a/UDPExamples/ClientWidget.hpp +++ b/UDPExamples/ClientWidget.hpp @@ -1,11 +1,11 @@ #ifndef WSJTX_UDP_CLIENT_WIDGET_MODEL_HPP__ #define WSJTX_UDP_CLIENT_WIDGET_MODEL_HPP__ +#include #include #include #include #include -#include #include "MessageServer.hpp" @@ -13,6 +13,20 @@ class QAbstractItemModel; class QModelIndex; class QColor; class QAction; +class QListWidget; +class QFormLayout; +class QVBoxLayout; +class QHBoxLayout; +class QStackedLayout; +class QTableView; +class QLineEdit; +class QAbstractButton; +class QLabel; +class QCheckBox; +class QSpinBox; +class QFrame; +class QStatusBar; +class QDialogButtonBox; using Frequency = MessageServer::Frequency; @@ -25,16 +39,18 @@ public: explicit ClientWidget (QAbstractItemModel * decodes_model, QAbstractItemModel * beacons_model , QString const& id, QString const& version, QString const& revision , QListWidget const * calls_of_interest, QWidget * parent = nullptr); + void dispose (); ~ClientWidget (); - bool fast_mode () const {return fast_mode_;} + bool fast_mode () const; Q_SLOT void update_status (QString const& id, Frequency f, QString const& mode, QString const& dx_call , QString const& report, QString const& tx_mode, bool tx_enabled - , bool transmitting, bool decoding, qint32 rx_df, qint32 tx_df + , bool transmitting, bool decoding, quint32 rx_df, quint32 tx_df , QString const& de_call, QString const& de_grid, QString const& dx_grid , bool watchdog_timeout, QString const& sub_mode, bool fast_mode - , quint8 special_op_mode); + , quint8 special_op_mode, quint32 frequency_tolerance, quint32 tr_period + , QString const& configuration_name); Q_SLOT void decode_added (bool is_new, QString const& client_id, QTime, qint32 snr , float delta_time, quint32 delta_frequency, QString const& mode , QString const& message, bool low_confidence, bool off_air); @@ -45,6 +61,7 @@ public: Q_SLOT void decodes_cleared (QString const& client_id); Q_SIGNAL void do_clear_decodes (QString const& id, quint8 window = 0); + Q_SIGNAL void do_close (QString const& id); Q_SIGNAL void do_reply (QModelIndex const&, quint8 modifier); Q_SIGNAL void do_halt_tx (QString const& id, bool auto_only); Q_SIGNAL void do_free_text (QString const& id, QString const& text, bool); @@ -52,30 +69,39 @@ public: Q_SIGNAL void highlight_callsign (QString const& id, QString const& call , QColor const& bg = QColor {}, QColor const& fg = QColor {} , bool last_only = false); + Q_SIGNAL void switch_configuration (QString const& id, QString const& configuration_name); + Q_SIGNAL void configure (QString const& id, QString const& mode, quint32 frequency_tolerance + , QString const& submode, bool fast_mode, quint32 tr_period, quint32 rx_df + , QString const& dx_call, QString const& dx_grid, bool generate_messages); private: - QString id_; - QListWidget const * calls_of_interest_; class IdFilterModel final : public QSortFilterProxyModel { public: - IdFilterModel (QString const& client_id); + IdFilterModel (QString const& client_id, QObject * = nullptr); void de_call (QString const&); - void rx_df (int); + void rx_df (quint32); QVariant data (QModelIndex const& proxy_index, int role = Qt::DisplayRole) const override; - - protected: + private: bool filterAcceptsRow (int source_row, QModelIndex const& source_parent) const override; - private: QString client_id_; QString call_; QRegularExpression base_call_re_; - int rx_df_; - } decodes_proxy_model_; + quint32 rx_df_; + }; + + void closeEvent (QCloseEvent *) override; + + QString id_; + bool done_; + QListWidget const * calls_of_interest_; + IdFilterModel decodes_proxy_model_; + IdFilterModel beacons_proxy_model_; + QAction * erase_action_; QAction * erase_rx_frequency_action_; QAction * erase_both_action_; @@ -83,17 +109,39 @@ private: QTableView * beacons_table_view_; QLineEdit * message_line_edit_; QLineEdit * grid_line_edit_; - QStackedLayout * decodes_stack_; + QAbstractButton * generate_messages_push_button_; QAbstractButton * auto_off_button_; QAbstractButton * halt_tx_button_; QLabel * de_label_; - QLabel * mode_label_; - bool fast_mode_; QLabel * frequency_label_; - QLabel * dx_label_; - QLabel * rx_df_label_; QLabel * tx_df_label_; QLabel * report_label_; + QLineEdit * configuration_line_edit_; + QLineEdit * mode_line_edit_; + QSpinBox * frequency_tolerance_spin_box_; + QLabel * tx_mode_label_; + QLineEdit * submode_line_edit_; + QCheckBox * fast_mode_check_box_; + QSpinBox * tr_period_spin_box_; + QSpinBox * rx_df_spin_box_; + QLineEdit * dx_call_line_edit_; + QLineEdit * dx_grid_line_edit_; + QWidget * decodes_page_; + QWidget * beacons_page_; + QFrame * content_widget_; + QStatusBar * status_bar_; + QDialogButtonBox * control_button_box_; + + QFormLayout * form_layout_; + QHBoxLayout * horizontal_layout_; + QFormLayout * subform1_layout_; + QFormLayout * subform2_layout_; + QFormLayout * subform3_layout_; + QVBoxLayout * decodes_layout_; + QVBoxLayout * beacons_layout_; + QVBoxLayout * content_layout_; + QStackedLayout * decodes_stack_; + bool columns_resized_; }; diff --git a/UDPExamples/MessageAggregatorMainWindow.cpp b/UDPExamples/MessageAggregatorMainWindow.cpp index e6937e6cb..6245918a9 100644 --- a/UDPExamples/MessageAggregatorMainWindow.cpp +++ b/UDPExamples/MessageAggregatorMainWindow.cpp @@ -250,12 +250,15 @@ void MessageAggregatorMainWindow::add_client (QString const& id, QString const& connect (server_, &MessageServer::WSPR_decode, dock, &ClientWidget::beacon_spot_added); connect (server_, &MessageServer::decodes_cleared, dock, &ClientWidget::decodes_cleared); connect (dock, &ClientWidget::do_clear_decodes, server_, &MessageServer::clear_decodes); + connect (dock, &ClientWidget::do_close, server_, &MessageServer::close); connect (dock, &ClientWidget::do_reply, decodes_model_, &DecodesModel::do_reply); connect (dock, &ClientWidget::do_halt_tx, server_, &MessageServer::halt_tx); connect (dock, &ClientWidget::do_free_text, server_, &MessageServer::free_text); connect (dock, &ClientWidget::location, server_, &MessageServer::location); connect (view_action, &QAction::toggled, dock, &ClientWidget::setVisible); connect (dock, &ClientWidget::highlight_callsign, server_, &MessageServer::highlight_callsign); + connect (dock, &ClientWidget::switch_configuration, server_, &MessageServer::switch_configuration); + connect (dock, &ClientWidget::configure, server_, &MessageServer::configure); dock_widgets_[id] = dock; server_->replay (id); // request decodes and status } @@ -265,7 +268,7 @@ void MessageAggregatorMainWindow::remove_client (QString const& id) auto iter = dock_widgets_.find (id); if (iter != std::end (dock_widgets_)) { - (*iter)->close (); + (*iter)->dispose (); dock_widgets_.erase (iter); } } diff --git a/UDPExamples/UDPDaemon.cpp b/UDPExamples/UDPDaemon.cpp index 0ee202dc7..7caeb3038 100644 --- a/UDPExamples/UDPDaemon.cpp +++ b/UDPExamples/UDPDaemon.cpp @@ -51,7 +51,8 @@ public: , bool /*transmitting*/, bool /*decoding*/, qint32 /*rx_df*/, qint32 /*tx_df*/ , QString const& /*de_call*/, QString const& /*de_grid*/, QString const& /*dx_grid*/ , bool /* watchdog_timeout */, QString const& sub_mode, bool /*fast_mode*/ - , quint8 /*special_op_mode*/) + , quint8 /*special_op_mode*/, quint32 /*frequency_tolerance*/, quint32 /*tr_period*/ + , QString const& /*configuration_name*/) { if (id == id_) { diff --git a/WSPRBandHopping.cpp b/WSPRBandHopping.cpp index fd0167d51..e954d5433 100644 --- a/WSPRBandHopping.cpp +++ b/WSPRBandHopping.cpp @@ -44,6 +44,8 @@ namespace class Dialog : public QDialog { + Q_OBJECT + public: using BandList = QList; @@ -69,6 +71,8 @@ private: static int constexpr band_index_role {Qt::UserRole}; }; +#include "WSPRBandHopping.moc" + Dialog::Dialog (QSettings * settings, Configuration const * configuration, BandList const * WSPR_bands , QBitArray * bands, int * gray_line_duration, QWidget * parent) : QDialog {parent, Qt::Window | Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint} diff --git a/commons.h b/commons.h index 7c202d26e..4083bb22f 100644 --- a/commons.h +++ b/commons.h @@ -8,7 +8,8 @@ #ifdef __cplusplus #include extern "C" { -#else +#endif +#ifndef __cplusplus #include #endif diff --git a/cty.dat b/cty.dat index 1f533072f..b1b8c2789 100644 --- a/cty.dat +++ b/cty.dat @@ -119,11 +119,11 @@ West Malaysia: 28: 54: AS: 3.95: -102.23: -8.0: 9M2: =9W6MAN/2; East Malaysia: 28: 54: OC: 2.68: -113.32: -8.0: 9M6: 9M6,9M8,9W6,9W8,=9M1CSQ,=9M1CSS,=9M2/G3TMA/6,=9M2/PG5M/6,=9M2/R6AF/6,=9M2GCN/6,=9M2MDX/6, - =9M4ARD/6,=9M4CBP,=9M4CCB,=9M4CHQ,=9M4CJN,=9M4CMY,=9M4CPB,=9M4CRB,=9M4CRP,=9M4CSR,=9M4CWS,=9M4GCW, - =9M4JSE,=9M4LHM,=9M4LHS,=9M4LTW,=9M4RSA,=9M4SAB,=9M4SEB,=9M4SHQ,=9M4SJE,=9M4SJO,=9M4SJQ,=9M4SJS, - =9M4SJSA,=9M4SJSB,=9M4SJSD,=9M4SJSL,=9M4SJSP,=9M4SJST,=9M4SJSW,=9M4SJX,=9M4SMO,=9M4SMS,=9M4SMY, - =9M4STA,=9M4SWK,=9M50IARU/6,=9M50IARU/8,=9M50MQ,=9M50MS,=9M51GW,=9M51SB,=9M53QA,=9M57MS,=9M57MW, - =9M58MS,=9M58MW,=9M59MS,=9M59MW,=9M9/7M2VPR,=9M9/CCL,=9W2RCR/6,=9W2VVH/6; + =9M4ARD/6,=9M4CBP,=9M4CCB,=9M4CHQ,=9M4CJN,=9M4CKT,=9M4CMY,=9M4CPB,=9M4CRB,=9M4CRP,=9M4CSR,=9M4CWS, + =9M4GCW,=9M4JSE,=9M4LHM,=9M4LHS,=9M4LTW,=9M4RSA,=9M4SAB,=9M4SEB,=9M4SHQ,=9M4SJE,=9M4SJO,=9M4SJQ, + =9M4SJS,=9M4SJSA,=9M4SJSB,=9M4SJSD,=9M4SJSL,=9M4SJSP,=9M4SJST,=9M4SJSW,=9M4SJX,=9M4SMO,=9M4SMS, + =9M4SMY,=9M4STA,=9M4SWK,=9M50IARU/6,=9M50IARU/8,=9M50MQ,=9M50MS,=9M51GW,=9M51SB,=9M53QA,=9M57MS, + =9M57MW,=9M58MS,=9M58MW,=9M59MS,=9M59MW,=9M9/7M2VPR,=9M9/CCL,=9W2RCR/6,=9W2VVH/6; Nepal: 22: 42: AS: 27.70: -85.33: -5.75: 9N: 9N; Dem. Rep. of the Congo: 36: 52: AF: -3.12: -23.03: -1.0: 9Q: @@ -176,7 +176,7 @@ China: 24: 44: AS: 36.00: -102.00: -8.0: BY: BG,BG0(23)[42],BG9(23)[43],BH,BH0(23)[42],BH9(23)[43],BI,BI0(23)[42],BI9(23)[43],BJ,BJ0(23)[42], BJ9(23)[43],BL,BL0(23)[42],BL9(23)[43],BT,BT0(23)[42],BT9(23)[43],BY,BY0(23)[42],BY9(23)[43],BZ, BZ0(23)[42],BZ9(23)[43],XS,XS0(23)[42],XS9(23)[43],=B90IARU,=BD6KF/0(23)[42],=BD7MQ/9(23), - =BG6IFR/9(23),=BG9XD/4,=BG9XD/5,=BG9XD/7,=VO1AU/BY1RX,=VO1AU/BY1TTY,=W5FKX/BY1RX, + =BG6IFR/9(23),=BG9XD/4,=BG9XD/5,=BG9XD/7,=BH4CXY/9(23),=VO1AU/BY1RX,=VO1AU/BY1TTY,=W5FKX/BY1RX, =BA4DC/0(23)[42],=BD9BI/0(23)[42],=BG8FUL/0(23)[42], =BA4DT/0(23)[42],=BA4RF/0(23)[42],=BA7IO/0(23)[42],=BA7JS/0(23)[42],=BD1PTA/0(23)[42], =BD7IEE/0(23)[42],=BG1KIY/0(23)[42],=BG1LLB/0(23)[42],=BG1PIP/0(23)[42],=BG4WUA/0(23)[42], @@ -567,7 +567,7 @@ Antarctica: 13: 74: SA: -90.00: 0.00: 0.0: CE9: =LU/FT5YJ[73], =OR4TN(38)[67], =CE9/K2ARB(12), - =DH1HB/P(38)[67],=DH5CW(38)[67],=DP0/OJ1ABOA(38)[67],=DP0GVN(38)[67],=DP1POL(38)[67], + =DH1HB/P(38)[67],=DP0/OJ1ABOA(38)[67],=DP0GVN(38)[67],=DP1POL(38)[67], =FT5YJ/P[73], =R1ANR(38)[67],=RI1ANR(38)[67], =OH2FFP/P(38)[67], @@ -588,7 +588,7 @@ Cuba: 08: 11: NA: 21.50: 80.00: 5.0: CM: Morocco: 33: 37: AF: 32.00: 5.00: 0.0: CN: 5C,5D,5E,5F,5G,CN; Bolivia: 10: 12: SA: -17.00: 65.00: 4.0: CP: - CP,=VERSION, + CP, CP2[14], CP3[14], CP4[14], @@ -601,7 +601,7 @@ Portugal: 14: 37: EU: 39.50: 8.00: 0.0: CT: Madeira Islands: 33: 36: AF: 32.75: 16.95: 0.0: CT3: CQ2,CQ3,CQ9,CR3,CR9,CS3,CS9,CT3,CT9,=CT9500AEP/J; Azores: 14: 36: EU: 38.70: 27.23: 1.0: CU: - CQ1,CQ8,CR1,CR2,CR8,CS4,CS8,CT8,CU, + CQ1,CQ8,CR1,CR2,CR8,CS4,CS8,CT8,CU,=CU2JU/ND, =CQ8ARN/LH, =CU5/CU3EJ/LH, =CT8/DK6EA/LH; @@ -654,8 +654,8 @@ Palestine: 20: 39: AS: 31.28: -34.27: -2.0: E4: E4; North Cook Islands: 32: 62: OC: -10.02: 161.08: 10.0: E5/n: =E51LYC,=E51QMA,=E51TUG, - =E51AMF,=E51AUZ,=E51GC,=E51M,=E51MAN,=E51MBX,=E51MKW,=E51MQT,=E51NPQ,=E51PT,=E51QQQ,=E51UFF, - =E51WWB,=ZK1HCC,=ZK1MA,=ZK1NCF,=ZK1NCI,=ZK1TTG, + =E51AMF,=E51M,=E51MAN,=E51MBX,=E51MKW,=E51MQT,=E51PT,=E51QQQ,=E51UFF,=E51WWB,=ZK1HCC,=ZK1MA, + =ZK1NCF,=ZK1NCI,=ZK1TTG, =E50W[63],=E51PDX[63],=E51PEN[63],=E51WL[63],=ZK1/AC4LN/N[63],=ZK1KDN[63],=ZK1NCP[63],=ZK1NDK[63], =ZK1NJC[63],=ZK1QMA[63],=ZK1TUG[63],=ZK1WL[63]; South Cook Islands: 32: 63: OC: -21.90: 157.93: 10.0: E5/s: @@ -676,40 +676,43 @@ Spain: 14: 37: EU: 40.37: 4.88: -1.0: EA: =AO08CIK/H,=AO08CVV/Z,=AO08CXK/H,=AO08CYL/H,=AO08DI/Z,=AO08EIE/Z,=AO08HV/Z,=AO08ICA/Z,=AO08ID/Z, =AO08KJ/Z,=AO08KV/Z,=AO08OK/H,=AO08PB/Z,=AO08RKO/H,=AO08VK/Z,=AO2016DSS/LH,=EA2/ON7RU/LH, =EA2CRX/LH,=EA2EZ/P,=EA2SPS/LH,=EA2URI/O,=EA6SK/2,=EA9CP/2,=EG90IARU/2, - =EA3ESZ/Z,=EA3EVR/R,=EA3HSD/P,=EA3LD/D,=EA3RCV/PAZ,=EA8TL/3,=EA9CI/3,=EA9CP/3,=EG90IARU/3, + =EA3ESZ/Z,=EA3EVR/R,=EA3HSD/P,=EA3LD/D,=EA3RCV/PAZ,=EA6LU/3,=EA8TL/3,=EA9CI/3,=EA9CP/3, + =EG90IARU/3, =EA4AAQ/O,=EA4RCH/CIE,=EA6AFU/4,=EA6RC/4,=EA8BFH/4,=EA8BY/4,=EA9CI/4,=EA9CP/4,=EG8AOP/4, =EG90IARU/4, - =EA5ADM/P,=EA5CC/P,=EA5EQ/N,=EA5EZ/P,=EA5FL/LH,=EA5GVT/AVW,=EA5HCC/P,=EA5IKT/P,=EA5KB/LH,=EA5ND/D, - =EA5RCK/CDI,=EA5RKD/PAZ,=EA5TOM/AVW,=EA5URE/IVA,=EA5URE/P,=EA5URM/C,=EA5URM/F,=EA5URM/G,=EA5URM/H, - =EA5URM/I,=EA5URM/L,=EA5URR/PAZ,=EA5URV/CAC,=EA6AKN/5,=EA8BFH/5,=EA8CWF/5,=EA9BLJ/5,=EA9CI/5, - =EA9CP/5,=EA9PD/5,=ED5MFP/C,=ED5MFP/G,=ED5MFP/H,=ED5MFP/I,=ED5MFP/K,=ED5MFP/Q,=ED5MFP/R,=ED5MFP/S, - =ED5URD/LH,=EG90IARU/5,=EH5FL/LH, + =EA5/ON4LO/LH,=EA5ADM/P,=EA5CC/P,=EA5EQ/N,=EA5EZ/P,=EA5FL/LH,=EA5GVT/AVW,=EA5HCC/P,=EA5IKT/P, + =EA5KB/LH,=EA5ND/D,=EA5RCK/CDI,=EA5RKD/PAZ,=EA5TOM/AVW,=EA5URE/IVA,=EA5URE/P,=EA5URM/C,=EA5URM/F, + =EA5URM/G,=EA5URM/H,=EA5URM/I,=EA5URM/L,=EA5URR/PAZ,=EA5URV/CAC,=EA6AKN/5,=EA8BFH/5,=EA8CWF/5, + =EA9BLJ/5,=EA9CI/5,=EA9CP/5,=EA9PD/5,=ED5MFP/C,=ED5MFP/G,=ED5MFP/H,=ED5MFP/I,=ED5MFP/K,=ED5MFP/Q, + =ED5MFP/R,=ED5MFP/S,=ED5URD/LH,=EG90IARU/5,=EH5FL/LH, =AO7WRD/MA,=EA6SK/7,=EA7CFU/U,=EA7FC/FCJ,=EA7HZ/F,=EA7OBH/LH,=EA7URA/GET,=EA7URA/PAZ,=EA7URA/SG, =EA7URA/YOTA,=EA7URE/PAZ,=EA7URF/PAZ,=EA7URI/MDL,=EA7URJ/CPM,=EA7URL/FSV,=EA7URM/PAZ,=EA7URP/LAI, =EA9CP/7,=EA9FN/7,=EA9HU,=EA9HU/7,=EA9JS/7,=EA9LZ/7,=EA9PD/7,=EA9QD/7,=EA9UL/7,=EA9UV/7,=EB9PH/7, =EC7DZZ/LH,=EG90IARU/7; Balearic Islands: 14: 37: EU: 39.60: -2.95: -1.0: EA6: - AM6,AN6,AO6,EA6,EB6,EC6,ED6,EE6,EF6,EG6,EH6,=EA1QE/6,=EA1YO/6,=EA2EZ/6,=EA2SG/6,=EA2TW/6,=EA3BT/6, - =EA3CBH/6,=EA3ERT/6,=EA3HSD/6,=EA3HUX/6,=EA3HZX/6,=EA3HZX/P,=EA4LO/6,=EA5ADM/6,=EA5BB/6,=EA5BK/6, - =EA5BTL/6,=EA5EOR/6,=EA5ER/6,=EA5EZ/6,=EA5FL/P,=EA5HCC/6,=EA5IIG/6,=EA5IKT/6,=EA5RKB/6, - =EA6/DJ7AO/LH,=EA6/G0SGB/LH,=EA6HP/J,=EA6LU/P,=EA6URI/PAZ,=EA6URL/IF,=EA7DUT/6,=EA9CI/6,=EA9CP/6, - =EB1BRH/6,=EB2GKK/6,=EB3CW/6,=EC5AC/6,=EC5BME/6,=EC5EA/P,=EC5EC/6,=EC6TV/N,=EC7AT/6,=ED4SHF/6, - =ED5ON/6,=EH90IARU/6; + AM6,AN6,AO6,EA6,EB6,EC6,ED6,EE6,EF6,EG6,EH6,=AM70URE/6,=EA1QE/6,=EA1YO/6,=EA2EZ/6,=EA2SG/6, + =EA2TW/6,=EA3BT/6,=EA3CBH/6,=EA3ERT/6,=EA3HSD/6,=EA3HUX/6,=EA3HZX/6,=EA3HZX/P,=EA4LO/6,=EA5ADM/6, + =EA5BB/6,=EA5BK/6,=EA5BTL/6,=EA5EOR/6,=EA5ER/6,=EA5EZ/6,=EA5FL/P,=EA5HCC/6,=EA5IIG/6,=EA5IKT/6, + =EA5RKB/6,=EA6/DJ7AO/LH,=EA6/G0SGB/LH,=EA6HP/J,=EA6LU/P,=EA6URI/PAZ,=EA6URL/IF,=EA7DUT/6,=EA9CI/6, + =EA9CP/6,=EB1BRH/6,=EB2GKK/6,=EB3CW/6,=EC5AC/6,=EC5BME/6,=EC5EA/P,=EC5EC/6,=EC6TV/N,=EC7AT/6, + =ED4SHF/6,=ED5ON/6,=EH90IARU/6; Canary Islands: 33: 36: AF: 28.32: 15.85: 0.0: EA8: - AM8,AN8,AO8,EA8,EB8,EC8,ED8,EE8,EF8,EG8,EH8,=AN400L,=AN400U,=AO150ITU/8,=AO150U,=AO4AAA/8, - =EA1AK/8,=EA1AP/8,=EA1EHW/8,=EA1YO/8,=EA3RKB/8,=EA4BQ/8,=EA4ESI/8,=EA4SV/8,=EA4WT/8,=EA4ZK/8, - =EA5BK/8,=EA5HCC/8,=EA5RKL/8,=EA7JR/8,=EA8/DJ5AA/LH,=EA8AKG/F,=EA8AKG/G,=EA8DO/LP,=EA8EE/L, - =EA8TH/LP,=EA8URE/YOTA,=EA8URL/LH,=EA8URL/P/SBI,=EA9CI/8,=EA9CP/8,=EB2EMH/8,=EC1KR/8,=EC8AFM/LH, - =ED4R/8,=ED5RKL/8,=ED8BTM/C,=ED8BTM/E,=ED8BTM/J,=ED8BTM/L,=ED8BTM/S,=ED8GSA/J,=ED8LIB/C,=ED8LIB/D, - =ED8LIB/E,=ED8LIB/F,=ED8LIB/G,=ED8LIB/H,=ED8LIB/I,=ED8LIB/J,=ED8LIB/K,=ED8LIB/N,=ED8LIB/O, - =ED8LIB/Q,=ED8LPA/L,=ED8MCC/LH,=ED8OTA/D,=ED8OTA/H,=ED8PDC/E,=ED8PDC/K,=ED8PDC/LP,=ED8PDC/O, - =EF8LIB/N,=EG8LIB/C,=EG8LIB/D,=EG8LIB/E,=EG8LIB/F,=EG8LIB/G,=EG8LIB/H,=EG8LIB/I,=EG8LIB/L, - =EG8LIB/M,=EG8LIB/N,=EG8LIB/O,=EG8LIB/P,=EG8LIB/Q,=EG8LP/YL,=EH8FLH/LH,=EH90IARU/8, + AM8,AN8,AO8,EA8,EB8,EC8,ED8,EE8,EF8,EG8,EH8,=AM70URE/8,=AN400L,=AN400U,=AO150ITU/8,=AO150U, + =AO4AAA/8,=EA1AK/8,=EA1AP/8,=EA1EHW/8,=EA1YO/8,=EA3RKB/8,=EA4BQ/8,=EA4ESI/8,=EA4SV/8,=EA4WT/8, + =EA4ZK/8,=EA5BK/8,=EA5HCC/8,=EA5RKL/8,=EA7JR/8,=EA8/DJ5AA/LH,=EA8AKG/F,=EA8AKG/G,=EA8DO/LP, + =EA8EE/L,=EA8TH/LP,=EA8URE/YOTA,=EA8URL/LH,=EA8URL/P/SBI,=EA9CI/8,=EA9CP/8,=EB2EMH/8,=EC1KR/8, + =EC8AFM/LH,=ED4R/8,=ED5RKL/8,=ED8BTM/C,=ED8BTM/E,=ED8BTM/J,=ED8BTM/L,=ED8BTM/S,=ED8GSA/J, + =ED8LIB/C,=ED8LIB/D,=ED8LIB/E,=ED8LIB/F,=ED8LIB/G,=ED8LIB/H,=ED8LIB/I,=ED8LIB/J,=ED8LIB/K, + =ED8LIB/N,=ED8LIB/O,=ED8LIB/Q,=ED8LPA/L,=ED8MCC/LH,=ED8OTA/D,=ED8OTA/H,=ED8PDC/E,=ED8PDC/K, + =ED8PDC/LP,=ED8PDC/O,=EF8LIB/N,=EG8LIB/C,=EG8LIB/D,=EG8LIB/E,=EG8LIB/F,=EG8LIB/G,=EG8LIB/H, + =EG8LIB/I,=EG8LIB/L,=EG8LIB/M,=EG8LIB/N,=EG8LIB/O,=EG8LIB/P,=EG8LIB/Q,=EG8LP/YL,=EH8FLH/LH, + =EH90IARU/8, =EA2TW/8,=EA3FNZ/8,=EA5EZ/8, =AO3MWC/8,=EA2SG/8,=EA4BFH/8,=EA4DE/8,=EA5RKB/8,=EA8BFH/P; Ceuta & Melilla: 33: 37: AF: 35.90: 5.27: -1.0: EA9: - AM9,AN9,AO9,EA9,EB9,EC9,ED9,EE9,EF9,EG9,EH9,=EA4URE/9,=EA7URM/9,=EA9CE/C,=EA9CE/D,=EA9CE/E, - =EA9CE/F,=EA9CE/G,=EA9CE/H,=EA9CE/I,=EA9URC/PAZ,=EC7DZZ/9,=ED3AFR/9,=ED9CE/D,=ED9CE/E,=ED9CE/F, + AM9,AN9,AO9,EA9,EB9,EC9,ED9,EE9,EF9,EG9,EH9,=AM70URE/9,=EA4URE/9,=EA7URM/9,=EA9CE/C,=EA9CE/D, + =EA9CE/E,=EA9CE/F,=EA9CE/G,=EA9CE/H,=EA9CE/I,=EA9URC/PAZ,=EC7DZZ/9,=ED3AFR/9,=ED9CE/D,=ED9CE/E, + =ED9CE/F, =EA3EGB/9,=EA5RKB/9,=EA7UV/P,=EA9CD/M,=EA9CD/P,=EB9PH/P,=EC5ALJ/9, =EA5DCL/9,=EA7JTF/9,=EA9PD/M,=EA9PD/P,=EC7DRS/9; Ireland: 14: 27: EU: 53.13: 8.02: 0.0: EI: @@ -769,7 +772,7 @@ Austral Islands: 32: 63: OC: -23.37: 149.48: 10.0: FO/a: =FO/AC4LN/A,=FO/DF6IC,=FO/DJ4OI,=FO/DL1AWI,=FO/DL1IAN,=FO/DL3APO,=FO/DL3GA,=FO/DL7FT,=FO/DL9AWI, =FO/F6CTL,=FO/F8CFU,=FO/G3BJ,=FO/HG9B,=FO/HG9B/P,=FO/IK2GNW,=FO/JA8BMK,=FO/K7AR,=FO/OH6KN, =FO/ON4AXU/A,=FO/UT6UD,=FO0CLA/A,=FO0ERI,=FO0FLA,=FO0FRY,=FO0HWU,=FO0MOT/P,=FO0SEV,=FO0WEG, - =FO0WII,=FO5FD,=TX0HF,=TX3D,=TX5BTY,=TX5D,=TX5RV,=TX5SPA,=TX5T,=TX5W,=TX5Z,=TX6G; + =FO0WII,=FO5FD,=TX0HF,=TX2A,=TX3D,=TX5BTY,=TX5D,=TX5RV,=TX5SPA,=TX5T,=TX5W,=TX5Z,=TX6G; Clipperton Island: 07: 10: NA: 10.28: 109.22: 8.0: FO/c: =FO0/F8UFT,=FO0AAA,=TX5C,=TX5K,=TX5P; Marquesas Islands: 31: 63: OC: -8.92: 140.07: 9.5: FO/m: @@ -870,25 +873,25 @@ Scotland: 14: 27: EU: 56.82: 4.18: 0.0: GM: =2Q0YCG,=2Q1MIC,=2Q1SJB,=2R0BOO,=2R0BSE,=2R0BXN,=2R0BZB,=2R0DES,=2R0DXR,=2R0FYG,=2R0GLI,=2R0HJS, =2R0IMP,=2R0IOB,=2R0ISM,=2R0JVR,=2R0KAU,=2R0KAU/P,=2R0NCM,=2R0OXX,=2R0YCG,=2R0ZPS,=2R1MIC,=2R1SJB, =2V0GUL,=2V0IVG,=2V0JCH,=2V0KAU,=2V0TAX,=2V1HFE,=2V1MIC,=2V1SJB,=G0FBJ,=GA6NX/LH,=GB0AYR,=GB0BAJ, - =GB0BCG,=GB0BCK,=GB0BD,=GB0BDC,=GB0BL,=GB0BNA,=GB0BNC,=GB0BOL,=GB0BSS,=GB0BWT,=GB0CCF,=GB0CHL, - =GB0CLH,=GB0CML,=GB0CNL,=GB0CWF,=GB0CWS,=GB0DBS,=GB0DHL,=GB0DPK,=GB0EPC,=GB0FFS,=GB0FSG,=GB0GDS, - =GB0GDS/J,=GB0GGR,=GB0GRN,=GB0HHW,=GB0HLD,=GB0JOG,=GB0KEY,=GB0KGS,=GB0KKS,=GB0KLT,=GB0LCS,=GB0LCW, - =GB0LTM,=GB0MLH,=GB0MLM,=GB0MOG,=GB0MOL,=GB0MSL,=GB0MUL,=GB0NGG,=GB0NHL,=GB0NHL/LH,=GB0NRL, - =GB0OYT,=GB0PLS,=GB0POS,=GB0PPE,=GB0PSW,=GB0RGC,=GB0SAA,=GB0SBC,=GB0SCD,=GB0SFM,=GB0SHP,=GB0SI, - =GB0SK,=GB0SKG,=GB0SKY,=GB0SRC,=GB0SSB,=GB0TH,=GB0THL,=GB0TNL,=GB0TTS,=GB0WRH,=GB100MAS,=GB100MUC, - =GB100ZET,=GB10SP,=GB150NRL,=GB18FIFA,=GB19CGM,=GB19CS,=GB1AJ,=GB1ASC,=GB1ASH,=GB1BD,=GB1BOL, - =GB1CFL,=GB1DHL,=GB1FB,=GB1FRS,=GB1FS,=GB1FVS,=GB1FVT,=GB1GEO,=GB1HRS,=GB1KGG,=GB1KLD,=GB1LAY, - =GB1LGG,=GB1LL,=GB1MAY,=GB1NHL,=GB1OL,=GB1OL/LH,=GB1PC,=GB1RB,=GB1RHU,=GB1SLH,=GB1TAY,=GB1WLG, - =GB250RB,=GB2AES,=GB2AGG,=GB2AL,=GB2AST,=GB2ATC,=GB2AYR,=GB2BAJ,=GB2BHM,=GB2BHS,=GB2BMJ,=GB2BOL, - =GB2CAS,=GB2CHC,=GB2CM,=GB2CMA,=GB2CVL,=GB2DAS,=GB2DHS,=GB2DL,=GB2DRC,=GB2DT,=GB2DTM,=GB2ELH, - =GB2ELH/LH,=GB2EPC,=GB2FBM,=GB2FSM,=GB2FSW,=GB2GEO,=GB2GKR,=GB2GNL,=GB2GNL/LH,=GB2GTM,=GB2HLB, - =GB2HMC,=GB2HRH,=GB2IGB,=GB2IGS,=GB2IMG,=GB2IMM,=GB2INV,=GB2IOT,=GB2JCM,=GB2KDR,=GB2KGB,=GB2KW, - =GB2LBN,=GB2LBN/LH,=GB2LCL,=GB2LCP,=GB2LCT,=GB2LDG,=GB2LG,=GB2LGB,=GB2LHI,=GB2LK,=GB2LK/LH, + =GB0BCG,=GB0BCK,=GB0BD,=GB0BDC,=GB0BL,=GB0BNA,=GB0BNC,=GB0BOC,=GB0BOL,=GB0BSS,=GB0BWT,=GB0CCF, + =GB0CHL,=GB0CLH,=GB0CML,=GB0CNL,=GB0CWF,=GB0CWS,=GB0DBS,=GB0DHL,=GB0DPK,=GB0EPC,=GB0FFS,=GB0FSG, + =GB0GDS,=GB0GDS/J,=GB0GGR,=GB0GRN,=GB0HHW,=GB0HLD,=GB0JOG,=GB0KEY,=GB0KGS,=GB0KKS,=GB0KLT,=GB0LCS, + =GB0LCW,=GB0LTM,=GB0MLH,=GB0MLM,=GB0MOG,=GB0MOL,=GB0MSL,=GB0MUL,=GB0NGG,=GB0NHL,=GB0NHL/LH, + =GB0NRL,=GB0OYT,=GB0PLS,=GB0POS,=GB0PPE,=GB0PSW,=GB0RGC,=GB0SAA,=GB0SBC,=GB0SCD,=GB0SFM,=GB0SHP, + =GB0SI,=GB0SK,=GB0SKG,=GB0SKY,=GB0SRC,=GB0SSB,=GB0TH,=GB0THL,=GB0TNL,=GB0TTS,=GB0WRH,=GB100MAS, + =GB100MUC,=GB100ZET,=GB10SP,=GB150NRL,=GB18FIFA,=GB19CGM,=GB19CS,=GB1AJ,=GB1ASC,=GB1ASH,=GB1BD, + =GB1BOL,=GB1CFL,=GB1DHL,=GB1FB,=GB1FRS,=GB1FS,=GB1FVS,=GB1FVT,=GB1GEO,=GB1HRS,=GB1KGG,=GB1KLD, + =GB1LAY,=GB1LGG,=GB1LL,=GB1MAY,=GB1NHL,=GB1OL,=GB1OL/LH,=GB1PC,=GB1RB,=GB1RHU,=GB1SLH,=GB1TAY, + =GB1WLG,=GB250RB,=GB2AES,=GB2AGG,=GB2AL,=GB2AST,=GB2ATC,=GB2AYR,=GB2BAJ,=GB2BHM,=GB2BHS,=GB2BMJ, + =GB2BOL,=GB2CAS,=GB2CHC,=GB2CM,=GB2CMA,=GB2CVL,=GB2DAS,=GB2DHS,=GB2DL,=GB2DRC,=GB2DT,=GB2DTM, + =GB2ELH,=GB2ELH/LH,=GB2EPC,=GB2FBM,=GB2FSM,=GB2FSW,=GB2GEO,=GB2GKR,=GB2GNL,=GB2GNL/LH,=GB2GTM, + =GB2HLB,=GB2HMC,=GB2HRH,=GB2IGB,=GB2IGS,=GB2IMG,=GB2IMM,=GB2INV,=GB2IOT,=GB2JCM,=GB2KDR,=GB2KGB, + =GB2KW,=GB2LBN,=GB2LBN/LH,=GB2LCL,=GB2LCP,=GB2LCT,=GB2LDG,=GB2LG,=GB2LGB,=GB2LHI,=GB2LK,=GB2LK/LH, =GB2LMG,=GB2LP,=GB2LS,=GB2LS/LH,=GB2LSS,=GB2LT,=GB2LT/LH,=GB2LXX,=GB2M,=GB2MAS,=GB2MBB,=GB2MDG, - =GB2MN,=GB2MOF,=GB2MSL,=GB2MUC,=GB2MUL,=GB2NBC,=GB2NEF,=GB2NL,=GB2OL,=GB2OWM,=GB2PBF,=GB2PG, - =GB2QM,=GB2RB,=GB2RDR,=GB2RRL,=GB2RWW,=GB2SAA,=GB2SAM,=GB2SAS,=GB2SB,=GB2SBG,=GB2SHL/LH,=GB2SKG, - =GB2SLH,=GB2SMM,=GB2SOH,=GB2SQN,=GB2SR,=GB2SSB,=GB2SUM,=GB2SWF,=GB2TDS,=GB2THL,=GB2TNL,=GB2VCB, - =GB2VEF,=GB2WBF,=GB2WG,=GB2WLS,=GB2YLS,=GB2ZE,=GB3ANG,=GB3GKR,=GB3GM,=GB3LER,=GB3LER/B,=GB3ORK, + =GB2MN,=GB2MOF,=GB2MSL,=GB2MUC,=GB2MUL,=GB2NBC,=GB2NEF,=GB2NL,=GB2NMM,=GB2OL,=GB2OWM,=GB2PBF, + =GB2PG,=GB2QM,=GB2RB,=GB2RDR,=GB2RRL,=GB2RWW,=GB2SAA,=GB2SAM,=GB2SAS,=GB2SB,=GB2SBG,=GB2SHL/LH, + =GB2SKG,=GB2SLH,=GB2SMM,=GB2SOH,=GB2SQN,=GB2SR,=GB2SSB,=GB2SUM,=GB2SWF,=GB2TDS,=GB2THL,=GB2TNL, + =GB2VCB,=GB2VEF,=GB2WBF,=GB2WG,=GB2WLS,=GB2YLS,=GB2ZE,=GB3ANG,=GB3GKR,=GB3LER,=GB3LER/B,=GB3ORK, =GB3ORK/B,=GB3SWF,=GB3WOI,=GB4AAS,=GB4AST,=GB4BBR,=GB4BG,=GB4CGS,=GB4CMA,=GB4DAS,=GB4DHX,=GB4DTD, =GB4DUK,=GB4EPC,=GB4GD,=GB4GDS,=GB4GS,=GB4IE,=GB4JCM,=GB4JPJ,=GB4JYS,=GB4LER,=GB4MSE,=GB4NFE, =GB4OL,=GB4PAS,=GB4SK,=GB4SKO,=GB4SLH,=GB4SMM,=GB4SRO,=GB4SWF,=GB50FVS,=GB50GDS,=GB50JS,=GB50WAB, @@ -947,64 +950,65 @@ Wales: 14: 27: EU: 52.28: 3.73: 0.0: GW: =2R0BRR,=2R0CDY,=2R0CDZ,=2R0CSS,=2R0CVE,=2R0DRB,=2R0IDT,=2R0OJA,=2R0PHP,=2R0PJP,=2R0REX,=2R0RWF, =2R0TRR,=2R0TYG,=2R0XTP,=2R0YKK,=2R3SFC,=2V0CDY,=2V0CGM,=2V0CLJ,=2V0CVL,=2V0DAA,=2V0DUN,=2V0GME, =2V0GNG,=2V0KED,=2V0WDS,=2V1EPO,=GB0AAW,=GB0AD,=GB0AWE,=GB0AWS,=GB0BHR,=GB0BP,=GB0BRE,=GB0BTB, - =GB0BVL,=GB0BYL,=GB0CCE,=GB0CEW,=GB0CFD,=GB0CGG,=GB0CLC,=GB0CQD,=GB0CSA,=GB0CSR,=GB0CVA,=GB0DFD, - =GB0DMT,=GB0DS,=GB0DVP,=GB0FHD,=GB0FHI,=GB0GDD,=GB0GIW,=GB0GLV,=GB0GMD,=GB0GRM,=GB0HEL,=GB0HGC, - =GB0HLT,=GB0HMM,=GB0HMT,=GB0KF,=GB0L,=GB0LBG,=GB0LM,=GB0LVF,=GB0MFH,=GB0MIW,=GB0ML,=GB0MPA, - =GB0MUU,=GB0MWL,=GB0NAW,=GB0NEW,=GB0NG,=GB0NLC,=GB0PBR,=GB0PEM,=GB0PGG,=GB0PLB,=GB0PLL,=GB0PSG, - =GB0RME,=GB0ROC,=GB0RPO,=GB0RS,=GB0RSC,=GB0RSF,=GB0RWM,=GB0SDD,=GB0SGC,=GB0SH,=GB0SH/LH,=GB0SOA, - =GB0SPE,=GB0SPS,=GB0TD,=GB0TPR,=GB0TS,=GB0TTT,=GB0VCA,=GB0VK,=GB0WHH,=GB0WHR,=GB0WIW,=GB0WUL, - =GB0YG,=GB100AB,=GB100BP,=GB100CSW,=GB100GGC,=GB100GGM,=GB100HD,=GB100LB,=GB100LSG,=GB100MCV, - =GB100TMD,=GB10SOTA,=GB19CGW,=GB19CW,=GB19SG,=GB1AD,=GB1ATC,=GB1BAF,=GB1BGS,=GB1BPL,=GB1BSW, - =GB1BW,=GB1CCC,=GB1CDS,=GB1CPG,=GB1DS,=GB1FHS,=GB1HAS,=GB1HTW,=GB1JC,=GB1LSG,=GB1LW,=GB1OOC, - =GB1PCA,=GB1PCS,=GB1PD,=GB1PGW,=GB1PJ,=GB1PLL,=GB1SEA,=GB1SL,=GB1SPN,=GB1SSL,=GB1TDS,=GB1WAA, - =GB1WIW,=GB1WSM,=GB2000SET,=GB2003SET,=GB200HNT,=GB250TMB,=GB250TT,=GB2ADU,=GB2BEF,=GB2BGG, - =GB2BOM,=GB2BOW,=GB2BPM,=GB2BYF,=GB2CC,=GB2CI,=GB2COB,=GB2CR,=GB2CRS,=GB2DWR,=GB2EI,=GB2FC, - =GB2FLB,=GB2GGM,=GB2GLS,=GB2GOL,=GB2GSG,=GB2GVA,=GB2HDG,=GB2IMD,=GB2LBR,=GB2LM,=GB2LNP,=GB2LSA, - =GB2LSA/LH,=GB2LSH,=GB2MD,=GB2MGY,=GB2MIL,=GB2MMC,=GB2MOP,=GB2NF,=GB2NPH,=GB2NPL,=GB2OOA,=GB2PRC, - =GB2RFS,=GB2RTB,=GB2SAC,=GB2SCD,=GB2SCP,=GB2SFM,=GB2SIP,=GB2SLA,=GB2TD,=GB2TD/LH,=GB2TTA,=GB2VK, - =GB2WAA,=GB2WHO,=GB2WNA,=GB2WSF,=GB2WT,=GB3HLS,=GB3LMW,=GB4ADU,=GB4AFS,=GB4AOS,=GB4BB,=GB4BOJ, - =GB4BPL,=GB4BPL/LH,=GB4BPL/P,=GB4BPR,=GB4BRS/P,=GB4BSG,=GB4CI,=GB4CTC,=GB4EUL,=GB4FAA,=GB4GM, - =GB4GSS,=GB4HFH,=GB4HI,=GB4HLB,=GB4HMD,=GB4HMM,=GB4MBC,=GB4MD,=GB4MDH,=GB4MDI,=GB4MJS,=GB4MPI, - =GB4MUU,=GB4NDG,=GB4NPL,=GB4NTB,=GB4ON,=GB4OST,=GB4PAT,=GB4PCS,=GB4PD,=GB4POW,=GB4RC,=GB4RME, - =GB4RSL,=GB4SDD,=GB4SLC,=GB4SSP,=GB4SUB,=GB4TMS,=GB4UKG,=GB4VJD,=GB4WT,=GB4WWI,=GB4XT,=GB50ABS, - =GB50EVS,=GB50RSC,=GB50SGP,=GB5AC,=GB5FI,=GB5GEO,=GB5IMD,=GB5MD,=GB5ONG,=GB5PSJ,=GB5SIP,=GB5WT, - =GB60DITP,=GB60ER,=GB60PW,=GB60SPS,=GB60VLY,=GB65BTF,=GB6AC,=GB6BLB,=GB6CRI,=GB6GGM,=GB6OQA, - =GB6ORA,=GB6PLB,=GB6RNLI,=GB6SPD,=GB6TS,=GB6TSG,=GB6WT,=GB6WWT,=GB70BTF,=GB750CC,=GB75ATC,=GB75BB, - =GB8CCC,=GB8HI,=GB8MD,=GB8MG,=GB8OAE,=GB8OQE,=GB8RAF,=GB8WOW,=GB8WT,=GB90RSGB/62,=GB90RSGB/72, - =GB9GGM,=GC4BRS/LH,=GG100ACD,=GG100ANG,=GG100CPG,=GG100RGG,=GG100SG,=GO0DIV,=GO0EZQ,=GO0EZY, - =GO0JEQ,=GO0MNP,=GO0MNP/P,=GO0NPL,=GO0PLB,=GO0PNI,=GO0PUP,=GO0VKW,=GO0VML,=GO0VSW,=GO1DPL,=GO1IOT, - =GO1JFV,=GO1MVL,=GO1PKM,=GO3PLB,=GO3UOF,=GO3UOF/M,=GO3XJQ,=GO4BKG,=GO4BLE,=GO4CQZ,=GO4DTQ,=GO4GTI, - =GO4JKR,=GO4JUN,=GO4JUW,=GO4MVA,=GO4NOO,=GO4OKT,=GO4SUE,=GO4SUE/P,=GO4TNZ,=GO4WXM,=GO6IMS,=GO6NKG, - =GO6UKO,=GO7DWR,=GO7SBO,=GO7VJK,=GO7VQD,=GO8BQK,=GO8IQC,=GO8JOY,=GO8OKR,=GQ0ANA,=GQ0DIV,=GQ0JEQ, - =GQ0JRF,=GQ0MNO,=GQ0MNP,=GQ0NPL,=GQ0PUP,=GQ0RYT,=GQ0SLM,=GQ0TQM,=GQ0VKW,=GQ0VML,=GQ0VSW,=GQ0WVL, - =GQ1FKY,=GQ1FOA/P,=GQ1IOT,=GQ1JFV,=GQ1MVL,=GQ1NRS,=GQ1WRV,=GQ1ZKN,=GQ3IRK,=GQ3PLB,=GQ3SB,=GQ3UOF, - =GQ3VEN,=GQ3VKL,=GQ3WSU,=GQ3XJA,=GQ3XJQ,=GQ4BKG,=GQ4BLE,=GQ4CQZ,=GQ4EZW,=GQ4GSH,=GQ4GTI,=GQ4IIL, - =GQ4JKR,=GQ4JUN,=GQ4JUW,=GQ4LZP,=GQ4MVA,=GQ4NOO,=GQ4OKT,=GQ4SUE,=GQ4VNS,=GQ4VZJ,=GQ4WXM,=GQ4WXM/P, - =GQ6IMS,=GQ6ITJ,=GQ6NKG,=GQ6UKO,=GQ7BQK,=GQ7DWR,=GQ7FBV,=GQ7SBO,=GQ7UNJ,=GQ7UNV,=GQ7VJK,=GQ7VQD, - =GQ8BQK,=GQ8IQC,=GQ8JOY,=GQ8OKR,=GR0ANA,=GR0DIV,=GR0DSP,=GR0HUS,=GR0JEQ,=GR0MYY,=GR0NPL,=GR0PSV, - =GR0RYT,=GR0SYN,=GR0TKX,=GR0VKW,=GR0WGK,=GR1FJI,=GR1HNG,=GR1LFX,=GR1LHV,=GR1MCD,=GR1SGG,=GR1WVY, - =GR1YQM,=GR3SB,=GR3SFC,=GR3TKH,=GR3UOF,=GR3XJQ,=GR4BKG,=GR4BLE,=GR4CQZ,=GR4GNY,=GR4GTI,=GR4HZA, - =GR4JUN,=GR4JUW,=GR4OGO,=GR4SUE,=GR4VSS/P,=GR4XXJ,=GR4ZOM,=GR5PH,=GR6NKG,=GR6SIX,=GR6STK,=GR6UKO, - =GR6ZDH,=GR7AAV,=GR7HOC,=GR7NAU,=GR7TKZ,=GR7UNV,=GR7VQD,=GR8BQK,=GR8IQC,=GR8OGI,=GR8TRO,=GV0ANA, - =GV0DCK,=GV0DIV,=GV0EME,=GV0FRE,=GV0MNP,=GV0NPL,=GV1FKY,=GV1IOT,=GV1JFV,=GV1NBW,=GV1YQM,=GV3ATZ, - =GV3TJE/P,=GV3UOF,=GV3WEZ,=GV3XJQ,=GV4BKG,=GV4BRS,=GV4CQZ,=GV4JKR,=GV4JQP,=GV4NQJ,=GV4PUC,=GV6BRC, - =GV6JPC,=GV6NKG,=GV7UNV,=GV7VJK,=GV8IQC,=GW0AWT/2K,=GW0GEI/2K,=GW0GIH/2K,=GW0MNO/2K,=GW0VSW/2K, - =GW3JXN/2K,=GW3KJN/2K,=GW4IIL/2K,=GW4VHP/2K,=M2000Y/97A,=MO0AQZ,=MO0ATI,=MO0COE,=MO0CVT,=MO0EQL, - =MO0EZQ,=MO0GXE,=MO0HCX,=MO0IBZ,=MO0IML,=MO0KLW,=MO0LDJ,=MO0LLK,=MO0LUK,=MO0LZZ,=MO0MAU,=MO0MUM, - =MO0MWZ,=MO0OWW,=MO0SGD,=MO0SGR,=MO0TBB,=MO0TMI,=MO0TTU,=MO0UPH,=MO0VVO,=MO1CFA,=MO1CFN,=MO3DAO, - =MO3DQB,=MO3GKI,=MO3OJA,=MO3PUU,=MO3RNI,=MO3UEZ,=MO3WPH,=MO3YVO,=MO3ZCO,=MO6DVP,=MO6GWK,=MO6GWR, - =MO6GWR/P,=MO6MAU,=MO6PAM,=MO6PLC,=MO6PUT,=MO6SEF,=MO6TBD,=MO6TBP,=MO6WLB,=MQ0AQZ,=MQ0ATI,=MQ0AWW, - =MQ0CDO,=MQ0CNA,=MQ0CVT,=MQ0DHF,=MQ0EQL,=MQ0GXE,=MQ0GYV,=MQ0HCX,=MQ0IBZ,=MQ0IML,=MQ0LDJ,=MQ0LLK, - =MQ0LUK,=MQ0LZZ,=MQ0MAU,=MQ0MUM,=MQ0MWA,=MQ0MWZ,=MQ0OWW,=MQ0PAD,=MQ0RHD,=MQ0SGD,=MQ0SGR,=MQ0TBB, - =MQ0TMI,=MQ0TTU,=MQ0UPH,=MQ0UPH/P,=MQ0VVO,=MQ0XMC/P,=MQ1CFA,=MQ1CFN,=MQ1EYO/P,=MQ1LCR,=MQ3DAO, - =MQ3EPA,=MQ3GKI,=MQ3JAT,=MQ3NDB,=MQ3OJA,=MQ3USK,=MQ3WPH,=MQ3ZCB/P,=MQ5AND,=MQ5EPA,=MQ5VZW,=MQ6DVP, - =MQ6KLL,=MQ6MAU,=MQ6PAM,=MQ6PLC,=MQ6RHD,=MQ6SEF,=MQ6TBD,=MQ6TBP,=MR0AQZ,=MR0BXJ,=MR0CVT,=MR0GUK, - =MR0GXE,=MR0IDX,=MR0JGE,=MR0LAO,=MR0LDJ,=MR0MAU,=MR0RLD,=MR0TTR,=MR0TTU,=MR0YAD,=MR0ZAP,=MR1CFN, - =MR1EAA,=MR1LCR,=MR1MAJ/P,=MR1MDH,=MR3AVB,=MR3AVC,=MR3CBF,=MR3NYR,=MR3OBL,=MR3SET/P,=MR3UFN, - =MR3XZP,=MR3YKL,=MR3YLO,=MR3YVO,=MR3ZCB/P,=MR5HOC,=MR6ADZ,=MR6KDA,=MR6VHF,=MR6YDP,=MV0AEL,=MV0BLM, - =MV0EDX,=MV0GWT,=MV0GXE,=MV0HGY/P,=MV0IML,=MV0LLK,=MV0PJJ,=MV0PJJ/P,=MV0RRD,=MV0SGD,=MV0SGR, - =MV0TBB,=MV0TDQ,=MV0UAA,=MV0USK,=MV0VRQ,=MV0WYN,=MV1CFA,=MV1CFN,=MV1EYP/P,=MV3RNI,=MV6CQN,=MV6GWR, - =MV6GWR/P,=MV6URC,=MV6ZOL,=MW0CND/2K,=MW0DHF/LH,=MW5AAM/2K,=MW5GOL/LH; + =GB0BVL,=GB0BYL,=GB0CAC,=GB0CCE,=GB0CEW,=GB0CFD,=GB0CGG,=GB0CLC,=GB0CQD,=GB0CSA,=GB0CSR,=GB0CVA, + =GB0DFD,=GB0DMT,=GB0DS,=GB0DVP,=GB0FHD,=GB0FHI,=GB0GDD,=GB0GIW,=GB0GLV,=GB0GMD,=GB0GRM,=GB0HEL, + =GB0HGC,=GB0HLT,=GB0HMM,=GB0HMT,=GB0KF,=GB0L,=GB0LBG,=GB0LM,=GB0LVF,=GB0MFH,=GB0MIW,=GB0ML, + =GB0MPA,=GB0MUU,=GB0MWL,=GB0NAW,=GB0NEW,=GB0NG,=GB0NLC,=GB0PBR,=GB0PEM,=GB0PGG,=GB0PLB,=GB0PLL, + =GB0PSG,=GB0RME,=GB0ROC,=GB0RPO,=GB0RS,=GB0RSC,=GB0RSF,=GB0RWM,=GB0SDD,=GB0SGC,=GB0SH,=GB0SH/LH, + =GB0SOA,=GB0SPE,=GB0SPS,=GB0TD,=GB0TPR,=GB0TS,=GB0TTT,=GB0VCA,=GB0VK,=GB0WHH,=GB0WHR,=GB0WIW, + =GB0WUL,=GB0YG,=GB100AB,=GB100BP,=GB100CSW,=GB100GGC,=GB100GGM,=GB100HD,=GB100LB,=GB100LSG, + =GB100MCV,=GB100TMD,=GB10SOTA,=GB19CGW,=GB19CW,=GB19SG,=GB1AD,=GB1ATC,=GB1BAF,=GB1BGS,=GB1BPL, + =GB1BSW,=GB1BW,=GB1CCC,=GB1CDS,=GB1CPG,=GB1DS,=GB1FHS,=GB1HAS,=GB1HTW,=GB1JC,=GB1LSG,=GB1LW, + =GB1OOC,=GB1PCA,=GB1PCS,=GB1PD,=GB1PGW,=GB1PJ,=GB1PLL,=GB1SEA,=GB1SL,=GB1SPN,=GB1SSL,=GB1TDS, + =GB1WAA,=GB1WIW,=GB1WSM,=GB2000SET,=GB2003SET,=GB200HNT,=GB250TMB,=GB250TT,=GB2ADU,=GB2BEF, + =GB2BGG,=GB2BOM,=GB2BOW,=GB2BPM,=GB2BYF,=GB2CC,=GB2CI,=GB2COB,=GB2CR,=GB2CRS,=GB2DWR,=GB2EI, + =GB2FC,=GB2FLB,=GB2GGM,=GB2GLS,=GB2GOL,=GB2GSG,=GB2GVA,=GB2HDG,=GB2IMD,=GB2LBR,=GB2LM,=GB2LNP, + =GB2LSA,=GB2LSA/LH,=GB2LSH,=GB2MD,=GB2MGY,=GB2MIL,=GB2MLM,=GB2MMC,=GB2MOP,=GB2NF,=GB2NPH,=GB2NPL, + =GB2OOA,=GB2ORM,=GB2PRC,=GB2RFS,=GB2RTB,=GB2SAC,=GB2SCD,=GB2SCP,=GB2SFM,=GB2SIP,=GB2SLA,=GB2TD, + =GB2TD/LH,=GB2TTA,=GB2VK,=GB2WAA,=GB2WHO,=GB2WNA,=GB2WSF,=GB2WT,=GB3HLS,=GB3LMW,=GB4ADU,=GB4AFS, + =GB4AOS,=GB4BB,=GB4BOJ,=GB4BPL,=GB4BPL/LH,=GB4BPL/P,=GB4BPR,=GB4BRS/P,=GB4BSG,=GB4CI,=GB4CTC, + =GB4EUL,=GB4FAA,=GB4GM,=GB4GSS,=GB4HFH,=GB4HI,=GB4HLB,=GB4HMD,=GB4HMM,=GB4MBC,=GB4MD,=GB4MDH, + =GB4MDI,=GB4MJS,=GB4MPI,=GB4MUU,=GB4NDG,=GB4NPL,=GB4NTB,=GB4ON,=GB4OST,=GB4PAT,=GB4PCS,=GB4PD, + =GB4POW,=GB4RC,=GB4RME,=GB4RSL,=GB4SDD,=GB4SLC,=GB4SSP,=GB4SUB,=GB4TMS,=GB4UKG,=GB4VJD,=GB4WT, + =GB4WWI,=GB4XT,=GB50ABS,=GB50EVS,=GB50RSC,=GB50SGP,=GB5AC,=GB5FI,=GB5GEO,=GB5IMD,=GB5MD,=GB5ONG, + =GB5PSJ,=GB5SIP,=GB5WT,=GB60DITP,=GB60ER,=GB60PW,=GB60SPS,=GB60VLY,=GB65BTF,=GB6AC,=GB6BLB, + =GB6CRI,=GB6GGM,=GB6OQA,=GB6ORA,=GB6PLB,=GB6RNLI,=GB6SPD,=GB6TS,=GB6TSG,=GB6WT,=GB6WWT,=GB70BTF, + =GB750CC,=GB75ATC,=GB75BB,=GB8CCC,=GB8HI,=GB8MD,=GB8MG,=GB8ND,=GB8OAE,=GB8OQE,=GB8RAF,=GB8WOW, + =GB8WT,=GB90RSGB/62,=GB90RSGB/72,=GB9GGM,=GC4BRS/LH,=GG100ACD,=GG100ANG,=GG100CPG,=GG100RGG, + =GG100SG,=GO0DIV,=GO0EZQ,=GO0EZY,=GO0JEQ,=GO0MNP,=GO0MNP/P,=GO0NPL,=GO0PLB,=GO0PNI,=GO0PUP, + =GO0VKW,=GO0VML,=GO0VSW,=GO1DPL,=GO1IOT,=GO1JFV,=GO1MVL,=GO1PKM,=GO3PLB,=GO3UOF,=GO3UOF/M,=GO3XJQ, + =GO4BKG,=GO4BLE,=GO4CQZ,=GO4DTQ,=GO4GTI,=GO4JKR,=GO4JUN,=GO4JUW,=GO4MVA,=GO4NOO,=GO4OKT,=GO4SUE, + =GO4SUE/P,=GO4TNZ,=GO4WXM,=GO6IMS,=GO6NKG,=GO6UKO,=GO7DWR,=GO7SBO,=GO7VJK,=GO7VQD,=GO8BQK,=GO8IQC, + =GO8JOY,=GO8OKR,=GQ0ANA,=GQ0DIV,=GQ0JEQ,=GQ0JRF,=GQ0MNO,=GQ0MNP,=GQ0NPL,=GQ0PUP,=GQ0RYT,=GQ0SLM, + =GQ0TQM,=GQ0VKW,=GQ0VML,=GQ0VSW,=GQ0WVL,=GQ1FKY,=GQ1FOA/P,=GQ1IOT,=GQ1JFV,=GQ1MVL,=GQ1NRS,=GQ1WRV, + =GQ1ZKN,=GQ3IRK,=GQ3PLB,=GQ3SB,=GQ3UOF,=GQ3VEN,=GQ3VKL,=GQ3WSU,=GQ3XJA,=GQ3XJQ,=GQ4BKG,=GQ4BLE, + =GQ4CQZ,=GQ4EZW,=GQ4GSH,=GQ4GTI,=GQ4IIL,=GQ4JKR,=GQ4JUN,=GQ4JUW,=GQ4LZP,=GQ4MVA,=GQ4NOO,=GQ4OKT, + =GQ4SUE,=GQ4VNS,=GQ4VZJ,=GQ4WXM,=GQ4WXM/P,=GQ6IMS,=GQ6ITJ,=GQ6NKG,=GQ6UKO,=GQ7BQK,=GQ7DWR,=GQ7FBV, + =GQ7SBO,=GQ7UNJ,=GQ7UNV,=GQ7VJK,=GQ7VQD,=GQ8BQK,=GQ8IQC,=GQ8JOY,=GQ8OKR,=GR0ANA,=GR0DIV,=GR0DSP, + =GR0HUS,=GR0JEQ,=GR0MYY,=GR0NPL,=GR0PSV,=GR0RYT,=GR0SYN,=GR0TKX,=GR0VKW,=GR0WGK,=GR1FJI,=GR1HNG, + =GR1LFX,=GR1LHV,=GR1MCD,=GR1SGG,=GR1WVY,=GR1YQM,=GR3SB,=GR3SFC,=GR3TKH,=GR3UOF,=GR3XJQ,=GR4BKG, + =GR4BLE,=GR4CQZ,=GR4GNY,=GR4GTI,=GR4HZA,=GR4JUN,=GR4JUW,=GR4OGO,=GR4SUE,=GR4VSS/P,=GR4XXJ,=GR4ZOM, + =GR5PH,=GR6NKG,=GR6SIX,=GR6STK,=GR6UKO,=GR6ZDH,=GR7AAV,=GR7HOC,=GR7NAU,=GR7TKZ,=GR7UNV,=GR7VQD, + =GR8BQK,=GR8IQC,=GR8OGI,=GR8TRO,=GV0ANA,=GV0DCK,=GV0DIV,=GV0EME,=GV0FRE,=GV0MNP,=GV0NPL,=GV1FKY, + =GV1IOT,=GV1JFV,=GV1NBW,=GV1YQM,=GV3ATZ,=GV3TJE/P,=GV3UOF,=GV3WEZ,=GV3XJQ,=GV4BKG,=GV4BRS,=GV4CQZ, + =GV4JKR,=GV4JQP,=GV4NQJ,=GV4PUC,=GV6BRC,=GV6JPC,=GV6NKG,=GV7UNV,=GV7VJK,=GV8IQC,=GW0AWT/2K, + =GW0GEI/2K,=GW0GIH/2K,=GW0MNO/2K,=GW0VSW/2K,=GW3JXN/2K,=GW3KJN/2K,=GW4IIL/2K,=GW4VHP/2K, + =M2000Y/97A,=MO0AQZ,=MO0ATI,=MO0COE,=MO0CVT,=MO0EQL,=MO0EZQ,=MO0GXE,=MO0HCX,=MO0IBZ,=MO0IML, + =MO0KLW,=MO0LDJ,=MO0LLK,=MO0LUK,=MO0LZZ,=MO0MAU,=MO0MUM,=MO0MWZ,=MO0OWW,=MO0SGD,=MO0SGR,=MO0TBB, + =MO0TMI,=MO0TTU,=MO0UPH,=MO0VVO,=MO1CFA,=MO1CFN,=MO3DAO,=MO3DQB,=MO3GKI,=MO3OJA,=MO3PUU,=MO3RNI, + =MO3UEZ,=MO3WPH,=MO3YVO,=MO3ZCO,=MO6DVP,=MO6GWK,=MO6GWR,=MO6GWR/P,=MO6MAU,=MO6PAM,=MO6PLC,=MO6PUT, + =MO6SEF,=MO6TBD,=MO6TBP,=MO6WLB,=MQ0AQZ,=MQ0ATI,=MQ0AWW,=MQ0CDO,=MQ0CNA,=MQ0CVT,=MQ0DHF,=MQ0EQL, + =MQ0GXE,=MQ0GYV,=MQ0HCX,=MQ0IBZ,=MQ0IML,=MQ0LDJ,=MQ0LLK,=MQ0LUK,=MQ0LZZ,=MQ0MAU,=MQ0MUM,=MQ0MWA, + =MQ0MWZ,=MQ0OWW,=MQ0PAD,=MQ0RHD,=MQ0SGD,=MQ0SGR,=MQ0TBB,=MQ0TMI,=MQ0TTU,=MQ0UPH,=MQ0UPH/P,=MQ0VVO, + =MQ0XMC/P,=MQ1CFA,=MQ1CFN,=MQ1EYO/P,=MQ1LCR,=MQ3DAO,=MQ3EPA,=MQ3GKI,=MQ3JAT,=MQ3NDB,=MQ3OJA, + =MQ3USK,=MQ3WPH,=MQ3ZCB/P,=MQ5AND,=MQ5EPA,=MQ5VZW,=MQ6DVP,=MQ6KLL,=MQ6MAU,=MQ6PAM,=MQ6PLC,=MQ6RHD, + =MQ6SEF,=MQ6TBD,=MQ6TBP,=MR0AQZ,=MR0BXJ,=MR0CVT,=MR0GUK,=MR0GXE,=MR0IDX,=MR0JGE,=MR0LAO,=MR0LDJ, + =MR0MAU,=MR0RLD,=MR0TTR,=MR0TTU,=MR0YAD,=MR0ZAP,=MR1CFN,=MR1EAA,=MR1LCR,=MR1MAJ/P,=MR1MDH,=MR3AVB, + =MR3AVC,=MR3CBF,=MR3NYR,=MR3OBL,=MR3SET/P,=MR3UFN,=MR3XZP,=MR3YKL,=MR3YLO,=MR3YVO,=MR3ZCB/P, + =MR5HOC,=MR6ADZ,=MR6KDA,=MR6VHF,=MR6YDP,=MV0AEL,=MV0BLM,=MV0EDX,=MV0GWT,=MV0GXE,=MV0HGY/P,=MV0IML, + =MV0LLK,=MV0PJJ,=MV0PJJ/P,=MV0RRD,=MV0SGD,=MV0SGR,=MV0TBB,=MV0TDQ,=MV0UAA,=MV0USK,=MV0VRQ,=MV0WYN, + =MV1CFA,=MV1CFN,=MV1EYP/P,=MV3RNI,=MV6CQN,=MV6GWR,=MV6GWR/P,=MV6URC,=MV6ZOL,=MW0CND/2K,=MW0DHF/LH, + =MW5AAM/2K,=MW5GOL/LH; Solomon Islands: 28: 51: OC: -9.00: -160.00: -11.0: H4: H4,=H40/H44RK; Temotu Province: 32: 51: OC: -10.72: -165.80: -11.0: H40: @@ -1073,10 +1077,10 @@ Italy: 15: 28: EU: 42.82: -12.58: -1.0: I: =IQ6PS/LH,=IQ6SB/LGH,=IQ6SB/LGT,=IQ6SB/LH,=IQ6VP/J,=IZ6ASI/LH,=IZ6ASI/N,=IZ6CDI/O,=IZ6RWD/O, =IZ6TGS/LH,=IZ6TGS/N, =4U13FEB,=4U1GSC,=4U20B,=4U24OCT,=4U29MAY,=4U73B,=I7PXV/LH,=I7PXV/P/LH,=I7XUW/MI/224,=II7IAOI/N, - =II7PT/C,=II7PT/D,=II7PT/E,=II7PT/F,=II7PT/G,=II7PT/H,=II7PT/L,=II8ICN/NAVY,=IK7JWX/LH,=IQ7ML/J, - =IQ7ML/LH,=IQ7QK/LH,=IU7SCT/J,=IZ2DPX/7/LH,=IZ7DKA/YL,=IZ7KDX/LH,=IZ7LDC/LH, - =IK2RLS/8/LH,=IK8TEO/N,=IQ8OM/N,=IQ8PC/BWL,=IQ8XS/CEU,=IW8FFG/J,=IZ8AJQ/LGT,=IZ8AJQ/LH, - =IZ8DBJ/LGT,=IZ8DBJ/LH,=IZ8FMU/KR,=IZ8IZK/YL,=IZ8JPV/N,=IZ8QNX/N, + =II7PT/C,=II7PT/D,=II7PT/E,=II7PT/F,=II7PT/G,=II7PT/H,=II7PT/L,=II8ICN/NAVY,=IK7JWX/LH,=IK7SHC/MT, + =IQ7ML/J,=IQ7ML/LH,=IQ7QK/LH,=IU7SCT/J,=IZ2DPX/7/LH,=IZ7DKA/YL,=IZ7KDX/LH,=IZ7LDC/LH, + =IK2RLS/8/LH,=IK8IJN/I/US,=IK8TEO/N,=IQ8OM/N,=IQ8PC/BWL,=IQ8XS/CEU,=IU8CEU/8CZ,=IW8FFG/J, + =IZ8AJQ/LGT,=IZ8AJQ/LH,=IZ8DBJ/LGT,=IZ8DBJ/LH,=IZ8FMU/KR,=IZ8IZK/YL,=IZ8JPV/N,=IZ8QNX/N, =IA5/IW3ILP/L, =IC8/DJ5AA/LH, =IN3IKF/J,=IN3TJK/YL, @@ -1087,9 +1091,9 @@ Sardinia: 15: 28: EU: 40.15: -9.27: -1.0: IS: IM0,IS,IW0U,IW0V,IW0W,IW0X,IW0Y,IW0Z,=II0C,=II0EUDX,=II0FDR,=II0IAML,=II0ICH,=II0IDP,=II0M,=II0P, =II0PAX,=II0RSB,=II0SB,=II0SB/MM,=II0SRT/P,=II3EUDX,=IQ0AG,=IQ0AG/P,=IQ0AH,=IQ0AH/P,=IQ0AI, =IQ0AI/P,=IQ0AK,=IQ0AK/P,=IQ0AL,=IQ0AL/P,=IQ0AM,=IQ0AM/P,=IQ0EH,=IQ0EH/P,=IQ0HO,=IQ0ID,=IQ0ID/P, - =IQ0NU,=IQ0NU/P,=IQ0NV,=IQ0NV/P,=IQ0OG,=IQ0OH,=IQ0QP,=IQ0QP/LH,=IQ0QP/P,=IQ0QP/WW,=IQ0SS,=IQ0SS/P, - =IQ0US,=IQ0UT,=IQ0XP,=IR0EO,=IR0FOC,=IR0IDP,=IR0IDP/1,=IR0IDP/2,=IR0IDP/3,=IR0LVC,=IR0MDC, - =IS0/4Z5KJ/LH,=IS0ICE/N,=IS0IGV/N,=IS0PGF/N,=IS0SDX/N,=IW0HRI,=IY0GA,=IY0NV; + =IQ0NU,=IQ0NU/P,=IQ0NV,=IQ0NV/P,=IQ0OG,=IQ0OH,=IQ0QP,=IQ0QP/LH,=IQ0QP/P,=IQ0SS,=IQ0SS/P,=IQ0US, + =IQ0UT,=IQ0XP,=IR0EO,=IR0FOC,=IR0IDP,=IR0IDP/1,=IR0IDP/2,=IR0IDP/3,=IR0LVC,=IR0MDC,=IS0/4Z5KJ/LH, + =IS0/DL5SE/LH,=IS0ICE/N,=IS0IGV/N,=IS0PGF/N,=IS0SDX/N,=IW0HRI,=IY0GA,=IY0NV; Sicily: 15: 28: EU: 37.50: -14.00: -1.0: *IT9: IB9,ID9,IE9,IF9,II9,IJ9,IO9,IQ9,IR9,IT9,IU9,IW9,IY9,=IQ1QQ/9,=IT9CHU/J,=IT9CKA/CA,=IT9CLY/JZK, =IT9DSA/CA,=IT9DTU/N,=IT9GDS/WLK,=IT9HBS/LH,=IT9JZK/WLK,=IT9KKE/JZK,=IT9MRM/N,=IT9MRZ/LH, @@ -1114,12 +1118,11 @@ Japan: 25: 45: AS: 36.40: -138.38: -9.0: JA: =JD1BHH/6; Minami Torishima: 27: 90: OC: 24.28: -153.97: -10.0: JD/m: =8J1ZIU/JD1,=8N1AQ/JD1,=JA6GXK/JD1,=JD1/8J1ZIU,=JD1/8N1AQ,=JD1/JA6GXK,=JD1/JD1BIC,=JD1/JD1YAB, - =JD1/JE6XPF,=JD1/JF3CTR,=JD1/JF7MTO,=JD1/JF8HIQ,=JD1/JG1RHN,=JD1/JG8NQJ,=JD1/JH1EFP,=JD1/JI2AMA, - =JD1/JK1PCN,=JD1/JR8XXQ,=JD1BCK,=JD1BIC/JD1,=JD1BME,=JD1BMM,=JD1BND,=JD1M/JI2AMA,=JD1YAA, - =JD1YAB/JD1,=JD1YBJ,=JF3CTR/JD1,=JF7MTO/JD1,=JF8HIQ/JD1,=JG1RHN/JD1,=JG8NQJ/JD1,=JH1EFP/JD1, - =JI2AMA/JD1,=JK1PCN/JD1,=JR8XXQ/JD1; + =JD1/JE6XPF,=JD1/JF3CTR,=JD1/JF8HIQ,=JD1/JG1RHN,=JD1/JG8NQJ,=JD1/JH1EFP,=JD1/JI2AMA,=JD1/JK1PCN, + =JD1/JR8XXQ,=JD1BCK,=JD1BIC/JD1,=JD1BME,=JD1BMM,=JD1BND,=JD1M/JI2AMA,=JD1YAA,=JD1YAB/JD1,=JD1YBJ, + =JF3CTR/JD1,=JF8HIQ/JD1,=JG1RHN/JD1,=JG8NQJ/JD1,=JH1EFP/JD1,=JI2AMA/JD1,=JK1PCN/JD1,=JR8XXQ/JD1; Ogasawara: 27: 45: AS: 27.05: -142.20: -9.0: JD/o: - JD1,=8N1OGA; + JD1,=8N1OGA,=JR7ISY/JD1/CM; Mongolia: 23: 32: AS: 46.77: -102.17: -7.0: JT: JT,JU,JV, JT2[33],JU2[33],JV2[33], @@ -1127,7 +1130,7 @@ Mongolia: 23: 32: AS: 46.77: -102.17: -7.0: JT: Svalbard: 40: 18: EU: 78.00: -16.00: -1.0: JW: JW; Bear Island: 40: 18: EU: 74.43: -19.08: -1.0: *JW/b: - =JW0BEA,=JW1I,=JW2US,=JW2VOA,=JW3FL,=JW4GHA,=JW4JSA,=JW4LN,=JW5RIA,=JW7VW,=JW9JKA; + =JW/LB2PG,=JW0BEA,=JW1I,=JW2US,=JW2VOA,=JW3FL,=JW4GHA,=JW4JSA,=JW4LN,=JW5RIA,=JW7VW,=JW9JKA; Jan Mayen: 40: 18: EU: 71.05: 8.28: 1.0: JX: JX; Jordan: 20: 39: AS: 31.18: -36.42: -2.0: JY: @@ -1144,32 +1147,33 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K: WE0(4)[7],WF0(4)[7],WG0(4)[7],WI0(4)[7],WJ0(4)[7],WK0(4)[7],WM0(4)[7],WN0(4)[7],WO0(4)[7], WQ0(4)[7],WR0(4)[7],WS0(4)[7],WT0(4)[7],WU0(4)[7],WV0(4)[7],WW0(4)[7],WX0(4)[7],WY0(4)[7], WZ0(4)[7],=AH2BW(4)[7],=AH2BY(4)[7],=AH6ES/0(4)[7],=AH6FY(4)[7],=AH6MD(4)[7],=AH6N(4)[7], - =AH6N/0(4)[7],=AH6O(4)[7],=AH6OS(4)[7],=AH6RS(4)[7],=AL0G(4)[7],=AL3E(4)[7],=AL6E(4)[7], - =AL7BX(4)[7],=AL7EK(4)[7],=AL7FU(4)[7],=AL7GQ(4)[7],=AL7NY(4)[7],=AL7O/0(4)[7],=AL7OC(4)[7], - =AL7QQ(4)[7],=AL7QQ/P(4)[7],=AL9DB(4)[7],=KH0EX(4)[7],=KH2CZ(4)[7],=KH2JK(4)[7],=KH2OP(4)[7], - =KH2OP/0(4)[7],=KH2SL(4)[7],=KH6DM(4)[7],=KH6GN(4)[7],=KH6HNL(4)[7],=KH6HTV/0(4)[7],=KH6JEM(4)[7], - =KH6JFH(4)[7],=KH6NM(4)[7],=KH6NR(4)[7],=KH6RON(4)[7],=KH6SB(4)[7],=KH6TL(4)[7],=KH6UC(4)[7], - =KH6VHF(4)[7],=KH6VO(4)[7],=KH7AL/M(4)[7],=KH7AL/P(4)[7],=KH7BU(4)[7],=KH7GF(4)[7],=KH7HA(4)[7], - =KH7HY(4)[7],=KH7QI(4)[7],=KH7QJ(4)[7],=KH7QT(4)[7],=KH8CW(4)[7],=KL0DW(4)[7],=KL0EQ(4)[7], - =KL0FOX(4)[7],=KL0GP(4)[7],=KL0GQ(4)[7],=KL0MW(4)[7],=KL0SV(4)[7],=KL0UP(4)[7],=KL0WIZ(4)[7], - =KL1HT(4)[7],=KL1IF(4)[7],=KL1IF/M(4)[7],=KL1J(4)[7],=KL1LD(4)[7],=KL1PV(4)[7],=KL1TU(4)[7], - =KL1V/M(4)[7],=KL1VN(4)[7],=KL2A/0(4)[7],=KL2FU(4)[7],=KL2GR(4)[7],=KL2QO(4)[7],=KL2SX(4)[7], - =KL3LY(4)[7],=KL3MA(4)[7],=KL3MB(4)[7],=KL3MC(4)[7],=KL3QS(4)[7],=KL3SM(4)[7],=KL3VN(4)[7], - =KL4IY(4)[7],=KL4JN(4)[7],=KL7DE(4)[7],=KL7DTJ(4)[7],=KL7ED(4)[7],=KL7EP(4)[7],=KL7EP/0(4)[7], - =KL7GKY/0(4)[7],=KL7GLK(4)[7],=KL7GLK/0(4)[7],=KL7GLK/B(4)[7],=KL7IXI(4)[7],=KL7JGJ(4)[7], - =KL7JIE(4)[7],=KL7JIM(4)[7],=KL7JR/0(4)[7],=KL7MH(4)[7],=KL7MV(4)[7],=KL7NW(4)[7],=KL7PE/M(4)[7], - =KL7QW(4)[7],=KL7QW/0(4)[7],=KL7RH(4)[7],=KL7RZ(4)[7],=KL7SB/0(4)[7],=KL7SFD(4)[7],=KL7UV(4)[7], - =KL7XH(4)[7],=KL7YL(4)[7],=KL7YY/0(4)[7],=KL7ZD(4)[7],=KL7ZT(4)[7],=KP4ATV(4)[7],=KP4MLF(4)[7], - =KP4XZ(4)[7],=NH2LH(4)[7],=NH6CF(4)[7],=NH6WF(4)[7],=NH7CY(4)[7],=NH7FI(4)[7],=NH7XM(4)[7], - =NH7ZH(4)[7],=NL7AS(4)[7],=NL7BU(4)[7],=NL7CQ(4)[7],=NL7CQ/0(4)[7],=NL7FF(4)[7],=NL7FU(4)[7], - =NL7XT(4)[7],=NL7XU(4)[7],=NP4AI(4)[7],=NP4AI/0(4)[7],=VE4AGT/M(4)[7],=VE4XC/M(4)[7],=WH2S(4)[7], - =WH6AKZ(4)[7],=WH6ANH(4)[7],=WH6BLT(4)[7],=WH6BUL(4)[7],=WH6BXD(4)[7],=WH6CTU(4)[7],=WH6CUE(4)[7], - =WH6CYM(4)[7],=WH6CZI(4)[7],=WH6CZU(4)[7],=WH6DCJ(4)[7],=WH6DUV(4)[7],=WH6EAE(4)[7],=WH6ENX(4)[7], - =WH6LR(4)[7],=WH6MS(4)[7],=WH6QS(4)[7],=WH7DA(4)[7],=WH7IR(4)[7],=WH7MZ(4)[7],=WH7PV(4)[7], - =WH9AAH(4)[7],=WL0JF(4)[7],=WL1ON(4)[7],=WL7AEC(4)[7],=WL7AJA(4)[7],=WL7ANY(4)[7],=WL7ATK(4)[7], - =WL7BT(4)[7],=WL7CEG(4)[7],=WL7CLI(4)[7],=WL7CPW(4)[7],=WL7CQF(4)[7],=WL7CRT(4)[7],=WL7CY(4)[7], - =WL7JB(4)[7],=WL7LZ(4)[7],=WL7LZ/M(4)[7],=WL7RV(4)[7],=WL7YM(4)[7],=WP2B/0(4)[7],=WP3QH(4)[7], - =WP3Y(4)[7],=WP4BTQ(4)[7],=WP4GQR(4)[7],=WP4HRK(4)[7],=WP4LC(4)[7],=WP4NPV(4)[7], + =AH6N/0(4)[7],=AH6O(4)[7],=AH6OS(4)[7],=AH6PC(4)[7],=AH6RS(4)[7],=AL0G(4)[7],=AL3E(4)[7], + =AL6E(4)[7],=AL7BX(4)[7],=AL7EK(4)[7],=AL7FU(4)[7],=AL7GQ(4)[7],=AL7NY(4)[7],=AL7O/0(4)[7], + =AL7OC(4)[7],=AL7QQ(4)[7],=AL7QQ/P(4)[7],=AL9DB(4)[7],=KH0EX(4)[7],=KH2CZ(4)[7],=KH2JK(4)[7], + =KH2OP(4)[7],=KH2OP/0(4)[7],=KH2SL(4)[7],=KH6DM(4)[7],=KH6GN(4)[7],=KH6HNL(4)[7],=KH6HTV/0(4)[7], + =KH6JEM(4)[7],=KH6JFH(4)[7],=KH6NM(4)[7],=KH6NR(4)[7],=KH6RON(4)[7],=KH6SB(4)[7],=KH6TL(4)[7], + =KH6UC(4)[7],=KH6VHF(4)[7],=KH6VO(4)[7],=KH7AL/M(4)[7],=KH7AL/P(4)[7],=KH7BU(4)[7],=KH7GF(4)[7], + =KH7HA(4)[7],=KH7HY(4)[7],=KH7QI(4)[7],=KH7QJ(4)[7],=KH7QT(4)[7],=KH8CW(4)[7],=KL0DW(4)[7], + =KL0EQ(4)[7],=KL0FOX(4)[7],=KL0GP(4)[7],=KL0GQ(4)[7],=KL0MW(4)[7],=KL0N(4)[7],=KL0SV(4)[7], + =KL0UP(4)[7],=KL0WIZ(4)[7],=KL1HT(4)[7],=KL1IF(4)[7],=KL1IF/M(4)[7],=KL1J(4)[7],=KL1LD(4)[7], + =KL1PV(4)[7],=KL1TU(4)[7],=KL1V/M(4)[7],=KL1VN(4)[7],=KL2A/0(4)[7],=KL2FU(4)[7],=KL2GR(4)[7], + =KL2QO(4)[7],=KL2SX(4)[7],=KL3LY(4)[7],=KL3MA(4)[7],=KL3MB(4)[7],=KL3MC(4)[7],=KL3QS(4)[7], + =KL3SM(4)[7],=KL3VN(4)[7],=KL4IY(4)[7],=KL4JN(4)[7],=KL7DE(4)[7],=KL7DTJ(4)[7],=KL7ED(4)[7], + =KL7EP(4)[7],=KL7EP/0(4)[7],=KL7GKY/0(4)[7],=KL7GLK(4)[7],=KL7GLK/0(4)[7],=KL7GLK/B(4)[7], + =KL7IXI(4)[7],=KL7JGJ(4)[7],=KL7JIE(4)[7],=KL7JIM(4)[7],=KL7JR/0(4)[7],=KL7MH(4)[7],=KL7MV(4)[7], + =KL7NW(4)[7],=KL7PE/M(4)[7],=KL7QW(4)[7],=KL7QW/0(4)[7],=KL7RH(4)[7],=KL7RZ(4)[7],=KL7SB/0(4)[7], + =KL7SFD(4)[7],=KL7UV(4)[7],=KL7XH(4)[7],=KL7YL(4)[7],=KL7YY/0(4)[7],=KL7ZD(4)[7],=KL7ZT(4)[7], + =KP4ATV(4)[7],=KP4MLF(4)[7],=KP4XZ(4)[7],=NH2LH(4)[7],=NH6CF(4)[7],=NH6WF(4)[7],=NH7CY(4)[7], + =NH7FI(4)[7],=NH7XM(4)[7],=NH7ZH(4)[7],=NL7AS(4)[7],=NL7BU(4)[7],=NL7CQ(4)[7],=NL7CQ/0(4)[7], + =NL7FF(4)[7],=NL7FU(4)[7],=NL7XT(4)[7],=NL7XU(4)[7],=NP4AI(4)[7],=NP4AI/0(4)[7],=VE4AGT/M(4)[7], + =VE4XC/M(4)[7],=WH2S(4)[7],=WH6AKZ(4)[7],=WH6ANH(4)[7],=WH6BLT(4)[7],=WH6BUL(4)[7],=WH6BXD(4)[7], + =WH6CTU(4)[7],=WH6CUE(4)[7],=WH6CYM(4)[7],=WH6CZI(4)[7],=WH6CZU(4)[7],=WH6DCJ(4)[7],=WH6DUV(4)[7], + =WH6EAE(4)[7],=WH6ENX(4)[7],=WH6LR(4)[7],=WH6MS(4)[7],=WH6QS(4)[7],=WH7DA(4)[7],=WH7IR(4)[7], + =WH7MZ(4)[7],=WH7PV(4)[7],=WH9AAH(4)[7],=WL0JF(4)[7],=WL1ON(4)[7],=WL7AEC(4)[7],=WL7AJA(4)[7], + =WL7ANY(4)[7],=WL7ATK(4)[7],=WL7BRV(4)[7],=WL7BT(4)[7],=WL7CEG(4)[7],=WL7CLI(4)[7],=WL7CPW(4)[7], + =WL7CQF(4)[7],=WL7CRT(4)[7],=WL7CY(4)[7],=WL7JB(4)[7],=WL7LZ(4)[7],=WL7LZ/M(4)[7],=WL7RV(4)[7], + =WL7YM(4)[7],=WP2B/0(4)[7],=WP3QH(4)[7],=WP3Y(4)[7],=WP4BTQ(4)[7],=WP4GQR(4)[7],=WP4LC(4)[7], + =WP4NPV(4)[7], =AH2V(5)[8],=AH2W(5)[8],=AH6BV(5)[8],=AL0A(5)[8],=AL1O(5)[8],=AL4V(5)[8],=AL6L(5)[8],=AL6M(5)[8], =AL7EL(5)[8],=AL7LV(5)[8],=AL7QS(5)[8],=AL8E(5)[8],=KH2AB(5)[8],=KH2EH(5)[8],=KH6GR(5)[8], =KH6HZ(5)[8],=KH6IKI(5)[8],=KH6JKQ(5)[8],=KH6JUK(5)[8],=KH6RF(5)[8],=KH6RF/1(5)[8],=KH6RF/M(5)[8], @@ -1178,135 +1182,139 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K: =KL7IXX(5)[8],=KL7JHM(5)[8],=KL7JJN(5)[8],=KL7JR/1(5)[8],=KL7JT(5)[8],=KL7LK(5)[8], =KL7USI/1(5)[8],=KL8DX(5)[8],=KP4ANG(5)[8],=KP4BLS(5)[8],=KP4BPR(5)[8],=KP4DGF(5)[8], =KP4EC/1(5)[8],=KP4G(5)[8],=KP4GVT(5)[8],=KP4MR(5)[8],=KP4NPL(5)[8],=KP4NW(5)[8],=KP4R(5)[8], - =KP4RCD(5)[8],=NH0H(5)[8],=NH6IH(5)[8],=NH6XW(5)[8],=NH6ZB(5)[8],=NL7FJ(5)[8],=NL7MO(5)[8], - =NL7NJ(5)[8],=NL7OI(5)[8],=NL7OT(5)[8],=NL9H(5)[8],=NP2FZ(5)[8],=NP2FZ/1(5)[8],=NP2GG(5)[8], - =NP2PN(5)[8],=NP3IV(5)[8],=NP3LN(5)[8],=NP4AO(5)[8],=NP4AZ(5)[8],=NP4ER(5)[8],=VE1BES/M(5)[8], - =VE3CMB/M(5)[8],=VE4CCN/M(5)[8],=WH0EWX(5)[8],=WH2B(5)[8],=WH6CT(5)[8],=WH6DSN(5)[8],=WH6EI(5)[8], - =WH6FBH(5)[8],=WH6MY(5)[8],=WH6SW(5)[8],=WH6SW/1(5)[8],=WH7TP(5)[8],=WL1B(5)[8],=WL7B(5)[8], - =WL7CC(5)[8],=WL7CUP(5)[8],=WL7CVD(5)[8],=WL7WO(5)[8],=WL7WO/1(5)[8],=WL7Z/1(5)[8],=WP2MG(5)[8], - =WP3NN(5)[8],=WP3QV(5)[8],=WP3QV/1(5)[8],=WP3WV(5)[8],=WP4AKE(5)[8],=WP4AZJ(5)[8],=WP4BC(5)[8], - =WP4BF(5)[8],=WP4CJH(5)[8],=WP4JF(5)[8],=WP4KQ(5)[8],=WP4MKJ(5)[8],=WP4MMV(5)[8],=WP4MOC(5)[8], - =WP4NKW(5)[8],=WP4NUV(5)[8],=WP4NYY(5)[8],=WP4OIG(5)[8],=WP4OJK(5)[8], + =KP4RCD(5)[8],=KP4ZEM(5)[8],=NH0H(5)[8],=NH6IH(5)[8],=NH6XW(5)[8],=NH6ZB(5)[8],=NL7AK(5)[8], + =NL7FJ(5)[8],=NL7MO(5)[8],=NL7NJ(5)[8],=NL7OI(5)[8],=NL7OT(5)[8],=NL9H(5)[8],=NP2FZ(5)[8], + =NP2FZ/1(5)[8],=NP2GG(5)[8],=NP2PN(5)[8],=NP3IV(5)[8],=NP3LN(5)[8],=NP4AO(5)[8],=NP4AZ(5)[8], + =NP4ER(5)[8],=VE1BES/M(5)[8],=VE3CMB/M(5)[8],=VE4CCN/M(5)[8],=WH0EWX(5)[8],=WH2B(5)[8], + =WH6CT(5)[8],=WH6DSN(5)[8],=WH6EI(5)[8],=WH6FBH(5)[8],=WH6MY(5)[8],=WH6SW(5)[8],=WH6SW/1(5)[8], + =WH7TP(5)[8],=WL1B(5)[8],=WL7B(5)[8],=WL7CC(5)[8],=WL7CUP(5)[8],=WL7CVD(5)[8],=WL7WO(5)[8], + =WL7WO/1(5)[8],=WL7Z/1(5)[8],=WP2MG(5)[8],=WP3NN(5)[8],=WP3QV(5)[8],=WP3QV/1(5)[8],=WP3WV(5)[8], + =WP4AKE(5)[8],=WP4AZJ(5)[8],=WP4BC(5)[8],=WP4BF(5)[8],=WP4CJH(5)[8],=WP4JF(5)[8],=WP4KQ(5)[8], + =WP4MKJ(5)[8],=WP4MMV(5)[8],=WP4MOC(5)[8],=WP4NKW(5)[8],=WP4NUV(5)[8],=WP4NYY(5)[8],=WP4OIG(5)[8], + =WP4OJK(5)[8], =AH0BR(5)[8],=AH2AL(5)[8],=AH2O(5)[8],=AH6K(5)[8],=AL0Q(5)[8],=AL0Y(5)[8],=AL2O(5)[8], =AL7RG(5)[8],=KH2CW(5)[8],=KH2P(5)[8],=KH2R(5)[8],=KH4AG(5)[8],=KH6ALN(5)[8],=KH6HO(5)[8], - =KH7GA(5)[8],=KH7JO(5)[8],=KH7JO/2(5)[8],=KH7MX(5)[8],=KH7NE(5)[8],=KH8ZK(5)[8],=KL0WV(5)[8], - =KL1A/2(5)[8],=KL2A/2(5)[8],=KL2NP(5)[8],=KL3ET(5)[8],=KL3ZC(5)[8],=KL4T(5)[8],=KL7DL(5)[8], - =KL7GB(5)[8],=KL7JCQ(5)[8],=KL7NL/2(5)[8],=KL7TJZ(5)[8],=KL7USI/2(5)[8],=KL7WA(5)[8],=KL9ER(5)[8], - =KP2NP(5)[8],=KP3AK(5)[8],=KP3LM(5)[8],=KP3Y(5)[8],=KP4AK(5)[8],=KP4CML(5)[8],=KP4GEG(5)[8], - =KP4HR(5)[8],=KP4I(5)[8],=KP4JDR(5)[8],=KP4JMP(5)[8],=NH2DC(5)[8],=NH7NA(5)[8],=NH7TN(5)[8], - =NL7CC(5)[8],=NP2AQ(5)[8],=NP2GI(5)[8],=NP3D(5)[8],=NP3E(5)[8],=NP3EU(5)[8],=NP3I(5)[8], - =NP3KH(5)[8],=NP3KP(5)[8],=NP4H(5)[8],=NP4IR(5)[8],=NP4IT(5)[8],=NP4JQ(5)[8],=WH0W(5)[8], - =WH2C(5)[8],=WH6DLD(5)[8],=WH6DNT(5)[8],=WH6UO(5)[8],=WL2NAS(5)[8],=WL7OG(5)[8],=WP2AAO(5)[8], - =WP3MD(5)[8],=WP3VU(5)[8],=WP3WZ(5)[8],=WP4AR(5)[8],=WP4BMU(5)[8],=WP4BNI(5)[8],=WP4BZ(5)[8], - =WP4CB(5)[8],=WP4DME(5)[8],=WP4DWH(5)[8],=WP4EHY(5)[8],=WP4EYW(5)[8],=WP4HLY(5)[8],=WP4HXS(5)[8], - =WP4KXX(5)[8],=WP4LYI(5)[8],=WP4MQN(5)[8],=WP4MRB(5)[8],=WP4MUJ(5)[8],=WP4MYM(5)[8],=WP4MZO(5)[8], - =WP4NBS(5)[8],=WP4OCO(5)[8],=WP4OPY(5)[8],=WP4PZB(5)[8],=WP4R(5)[8],=XL3TUV/M(5)[8], - =XM3CMB/M(5)[8], + =KH7GA(5)[8],=KH7JO(5)[8],=KH7JO/2(5)[8],=KH7MX(5)[8],=KH7NE(5)[8],=KH8ZK(5)[8],=KL0TV(5)[8], + =KL0WV(5)[8],=KL1A/2(5)[8],=KL2A/2(5)[8],=KL2NP(5)[8],=KL3ET(5)[8],=KL3ZC(5)[8],=KL4T(5)[8], + =KL7DL(5)[8],=KL7GB(5)[8],=KL7JCQ(5)[8],=KL7NL/2(5)[8],=KL7TJZ(5)[8],=KL7USI/2(5)[8],=KL7WA(5)[8], + =KL9ER(5)[8],=KP2NP(5)[8],=KP3AK(5)[8],=KP3LM(5)[8],=KP3Y(5)[8],=KP4AK(5)[8],=KP4CML(5)[8], + =KP4GEG(5)[8],=KP4HR(5)[8],=KP4I(5)[8],=KP4JDR(5)[8],=KP4JMP(5)[8],=NH2DC(5)[8],=NH7NA(5)[8], + =NH7TN(5)[8],=NL7CC(5)[8],=NP2AQ(5)[8],=NP2GI(5)[8],=NP3D(5)[8],=NP3E(5)[8],=NP3EU(5)[8], + =NP3I(5)[8],=NP3KH(5)[8],=NP3KP(5)[8],=NP4H(5)[8],=NP4IR(5)[8],=NP4IT(5)[8],=NP4JQ(5)[8], + =WH0W(5)[8],=WH2C(5)[8],=WH6DLD(5)[8],=WH6DNT(5)[8],=WH6UO(5)[8],=WL2NAS(5)[8],=WL7OG(5)[8], + =WP2AAO(5)[8],=WP3MD(5)[8],=WP3VU(5)[8],=WP3WZ(5)[8],=WP4AR(5)[8],=WP4BMU(5)[8],=WP4BNI(5)[8], + =WP4BZ(5)[8],=WP4CB(5)[8],=WP4DME(5)[8],=WP4DWH(5)[8],=WP4EHY(5)[8],=WP4EYW(5)[8],=WP4HLY(5)[8], + =WP4HXS(5)[8],=WP4KXX(5)[8],=WP4LYI(5)[8],=WP4MQN(5)[8],=WP4MRB(5)[8],=WP4MUJ(5)[8],=WP4MYM(5)[8], + =WP4MZO(5)[8],=WP4NBS(5)[8],=WP4NZF(5)[8],=WP4OCO(5)[8],=WP4OPY(5)[8],=WP4PZB(5)[8],=WP4R(5)[8], + =XL3TUV/M(5)[8],=XM3CMB/M(5)[8], =4U1WB(5)[8],=AH6AX(5)[8],=AH6FF/3(5)[8],=AH6R(5)[8],=AH6Z(5)[8],=AH7J(5)[8],=AH8P(5)[8], =AL1B(5)[8],=AL1B/M(5)[8],=AL7AB(5)[8],=AL7NN(5)[8],=AL7NN/3(5)[8],=AL7RS(5)[8],=KH2GM(5)[8], =KH2JX(5)[8],=KH2SX(5)[8],=KH6CUJ(5)[8],=KH6ILR/3(5)[8],=KH6JGA(5)[8],=KH6LDO(5)[8],=KH8CN(5)[8], =KL1HA(5)[8],=KL1KM(5)[8],=KL2A(5)[8],=KL2A/3(5)[8],=KL2BV(5)[8],=KL2XF(5)[8],=KL3JC(5)[8], =KL7FD(5)[8],=KL7GLK/3(5)[8],=KL7HR/3(5)[8],=KL7JO(5)[8],=KL7OF/3(5)[8],=KL7OQ(5)[8], - =KL9A/3(5)[8],=KP3M(5)[8],=KP4CAM(5)[8],=KP4FCF(5)[8],=KP4GB/3(5)[8],=KP4IP(5)[8],=KP4JB(5)[8], - =KP4N(5)[8],=KP4N/3(5)[8],=KP4PRI(5)[8],=KP4UV(5)[8],=KP4WR(5)[8],=KP4XO(5)[8],=KP4XX(5)[8], - =KP4YH(5)[8],=NH2CW(5)[8],=NH6BD(5)[8],=NH6BK(5)[8],=NH7C(5)[8],=NH7CC(5)[8],=NH7YK(5)[8], - =NL7CK(5)[8],=NL7PJ(5)[8],=NL7V/3(5)[8],=NL7XM(5)[8],=NL7XM/B(5)[8],=NP2EP(5)[8],=NP2G(5)[8], - =NP2NC(5)[8],=NP3ES(5)[8],=NP3IP(5)[8],=NP3YN(5)[8],=NP4RH(5)[8],=NP4YZ(5)[8],=WH6ADS(5)[8], - =WH6AWO(5)[8],=WH6AZN(5)[8],=WH6CE(5)[8],=WH6CTO(5)[8],=WH6DOA(5)[8],=WH6ECO(5)[8],=WH6EEL(5)[8], - =WH6EEN(5)[8],=WH6EIJ(5)[8],=WH6IO(5)[8],=WH6OB(5)[8],=WH7F(5)[8],=WH7USA(5)[8],=WL7AF(5)[8], - =WL7L(5)[8],=WP2XX(5)[8],=WP3BX(5)[8],=WP3CC(5)[8],=WP3EC(5)[8],=WP3FK(5)[8],=WP4DA(5)[8], - =WP4DCK(5)[8],=WP4EDM(5)[8],=WP4GJL(5)[8],=WP4HSZ(5)[8],=WP4KDN(5)[8],=WP4KKX(5)[8],=WP4LEM(5)[8], - =WP4LNP(5)[8],=WP4MNV(5)[8],=WP4MSX(5)[8],=WP4MYN(5)[8],=WP4OSQ(5)[8],=WP4PPH(5)[8],=WP4PQN(5)[8], - =WP4PUR(5)[8],=WP4PYL(5)[8],=WP4PYM(5)[8],=WP4PYN(5)[8],=WP4PYT(5)[8],=WP4PYU(5)[8],=WP4PYV(5)[8], - =WP4PYZ(5)[8],=WP4PZA(5)[8], + =KL9A/3(5)[8],=KP3M(5)[8],=KP4BEP(5)[8],=KP4CAM(5)[8],=KP4FCF(5)[8],=KP4GB/3(5)[8],=KP4IP(5)[8], + =KP4JB(5)[8],=KP4N(5)[8],=KP4N/3(5)[8],=KP4PRI(5)[8],=KP4UV(5)[8],=KP4WR(5)[8],=KP4XO(5)[8], + =KP4XX(5)[8],=KP4YH(5)[8],=NH2CW(5)[8],=NH2LA(5)[8],=NH6BD(5)[8],=NH6BK(5)[8],=NH7C(5)[8], + =NH7CC(5)[8],=NH7YK(5)[8],=NL7CK(5)[8],=NL7PJ(5)[8],=NL7V/3(5)[8],=NL7XM(5)[8],=NL7XM/B(5)[8], + =NP2EP(5)[8],=NP2G(5)[8],=NP2NC(5)[8],=NP3ES(5)[8],=NP3IP(5)[8],=NP3YN(5)[8],=NP4RH(5)[8], + =NP4YZ(5)[8],=WH6ADS(5)[8],=WH6AWO(5)[8],=WH6AZN(5)[8],=WH6CE(5)[8],=WH6CTO(5)[8],=WH6DOA(5)[8], + =WH6ECO(5)[8],=WH6EEL(5)[8],=WH6EEN(5)[8],=WH6EIJ(5)[8],=WH6IO(5)[8],=WH6OB(5)[8],=WH7F(5)[8], + =WH7USA(5)[8],=WL7AF(5)[8],=WL7L(5)[8],=WP2XX(5)[8],=WP3BX(5)[8],=WP3CC(5)[8],=WP3EC(5)[8], + =WP3FK(5)[8],=WP4DA(5)[8],=WP4DCK(5)[8],=WP4EDM(5)[8],=WP4GJL(5)[8],=WP4HRK(5)[8],=WP4HSZ(5)[8], + =WP4KDN(5)[8],=WP4KKX(5)[8],=WP4LEM(5)[8],=WP4LNP(5)[8],=WP4MNV(5)[8],=WP4MSX(5)[8],=WP4MYN(5)[8], + =WP4OSQ(5)[8],=WP4PPH(5)[8],=WP4PQN(5)[8],=WP4PUR(5)[8],=WP4PYL(5)[8],=WP4PYM(5)[8],=WP4PYN(5)[8], + =WP4PYT(5)[8],=WP4PYU(5)[8],=WP4PYV(5)[8],=WP4PYZ(5)[8],=WP4PZA(5)[8], =AH0BV(5)[8],=AH0BZ(5)[8],=AH0G(5)[8],=AH2AJ(5)[8],=AH2AM(5)[8],=AH2AV/4(5)[8],=AH2DF(5)[8], =AH2EB(5)[8],=AH2X(5)[8],=AH3B(5)[8],=AH6AL(5)[8],=AH6AT(5)[8],=AH6AU(5)[8],=AH6BJ(5)[8], =AH6C(5)[8],=AH6EZ/4(5)[8],=AH6FX(5)[8],=AH6FX/4(5)[8],=AH6IC(5)[8],=AH6IJ(5)[8],=AH6IW(5)[8], =AH6JH(5)[8],=AH6JN/4(5)[8],=AH6JN/M(5)[8],=AH6KS(5)[8],=AH6KT(5)[8],=AH6KT/4(5)[8],=AH6LS(5)[8], - =AH6OB(5)[8],=AH6TI(5)[8],=AH7I/4(5)[8],=AH7MI(5)[8],=AH8B(5)[8],=AH8M(5)[8],=AH8M/M(5)[8], - =AH8T(5)[8],=AL0I(5)[8],=AL1A(5)[8],=AL3G(5)[8],=AL3M(5)[8],=AL4T(5)[8],=AL4T/4(5)[8],=AL4U(5)[8], - =AL4X(5)[8],=AL5A(5)[8],=AL7AL(5)[8],=AL7AM(5)[8],=AL7BA(5)[8],=AL7GF(5)[8],=AL7GK(5)[8], - =AL7HG(5)[8],=AL7HW(5)[8],=AL7HW/4(5)[8],=AL7IS(5)[8],=AL7KT(5)[8],=AL7LH(5)[8],=AL7NL(5)[8], - =AL7NM(5)[8],=AL7NS(5)[8],=AL7NS/140(5)[8],=AL7PL(5)[8],=AL7QI(5)[8],=AL7RE(5)[8],=AL7RL(5)[8], - =G8ERJ(5)[8],=GO4AZM(5)[8],=GQ4AZM(5)[8],=GR4AZM(5)[8],=KH0CW(5)[8],=KH0HR(5)[8],=KH0NI(5)[8], - =KH0ZZ(5)[8],=KH2BX(5)[8],=KH2D(5)[8],=KH2D/4(5)[8],=KH2GUM/P(5)[8],=KH2HB(5)[8],=KH2KD(5)[8], - =KH2N(5)[8],=KH2NC(5)[8],=KH2PM(5)[8],=KH2RL(5)[8],=KH2TI(5)[8],=KH2UV(5)[8],=KH2VM(5)[8], - =KH3AC(5)[8],=KH3AG(5)[8],=KH6AME(5)[8],=KH6CG(5)[8],=KH6CG/4(5)[8],=KH6CT(5)[8],=KH6ED(5)[8], - =KH6HHS(5)[8],=KH6HHS/4(5)[8],=KH6HOW(5)[8],=KH6ILR(5)[8],=KH6ILR/4(5)[8],=KH6ITI(5)[8], - =KH6JAU(5)[8],=KH6JIM(5)[8],=KH6JJD(5)[8],=KH6JUA(5)[8],=KH6M(5)[8],=KH6M/4(5)[8],=KH6M/M(5)[8], - =KH6MT(5)[8],=KH6MT/4(5)[8],=KH6NC(5)[8],=KH6NI(5)[8],=KH6OU(5)[8],=KH6POI(5)[8],=KH6PU(5)[8], - =KH6RP(5)[8],=KH6TY(5)[8],=KH6TY/R(5)[8],=KH6UN(5)[8],=KH6XH(5)[8],=KH7DM(5)[8],=KH7DY(5)[8], - =KH7FC(5)[8],=KH7GZ(5)[8],=KH7HJ/4(5)[8],=KH7OC(5)[8],=KH7OV(5)[8],=KH7WK(5)[8],=KH7XS/4(5)[8], - =KH7XT(5)[8],=KH7ZC(5)[8],=KH8BB(5)[8],=KH8DO(5)[8],=KL0AG(5)[8],=KL0IP(5)[8],=KL0KC(5)[8], - =KL0KE/4(5)[8],=KL0L(5)[8],=KL0MG(5)[8],=KL0MP(5)[8],=KL0S(5)[8],=KL0SS(5)[8],=KL0TY(5)[8], - =KL0VU(5)[8],=KL0WF(5)[8],=KL1KP(5)[8],=KL1NK(5)[8],=KL1NS(5)[8],=KL1OK(5)[8],=KL1PA(5)[8], - =KL1SS(5)[8],=KL2AK(5)[8],=KL2CX(5)[8],=KL2EY(5)[8],=KL2GG(5)[8],=KL2GP(5)[8],=KL2HV(5)[8], - =KL2MQ(5)[8],=KL2UQ(5)[8],=KL2XI(5)[8],=KL3EV(5)[8],=KL3HG(5)[8],=KL3IA(5)[8],=KL3KB(5)[8], - =KL3KG(5)[8],=KL3NR(5)[8],=KL3WM(5)[8],=KL3X(5)[8],=KL3XB(5)[8],=KL4CO(5)[8],=KL4DD(5)[8], - =KL4H(5)[8],=KL4J(5)[8],=KL5X(5)[8],=KL5YJ(5)[8],=KL7A(5)[8],=KL7DA(5)[8],=KL7DA/4(5)[8], - =KL7FO(5)[8],=KL7GLL(5)[8],=KL7H(5)[8],=KL7HIM(5)[8],=KL7HNY(5)[8],=KL7HOT(5)[8],=KL7HQW(5)[8], - =KL7HX(5)[8],=KL7IEK(5)[8],=KL7IKZ(5)[8],=KL7IV(5)[8],=KL7IVY(5)[8],=KL7IWF(5)[8],=KL7JR(5)[8], + =AH6OB(5)[8],=AH6TI(5)[8],=AH7I(5)[8],=AH7I/4(5)[8],=AH7MI(5)[8],=AH8B(5)[8],=AH8M(5)[8], + =AH8M/M(5)[8],=AH8T(5)[8],=AL0I(5)[8],=AL1A(5)[8],=AL3G(5)[8],=AL3M(5)[8],=AL4T(5)[8], + =AL4T/4(5)[8],=AL4U(5)[8],=AL4X(5)[8],=AL5A(5)[8],=AL7AL(5)[8],=AL7AM(5)[8],=AL7BA(5)[8], + =AL7GF(5)[8],=AL7GK(5)[8],=AL7HG(5)[8],=AL7HW(5)[8],=AL7HW/4(5)[8],=AL7IS(5)[8],=AL7KT(5)[8], + =AL7LH(5)[8],=AL7NL(5)[8],=AL7NM(5)[8],=AL7NS(5)[8],=AL7NS/140(5)[8],=AL7PL(5)[8],=AL7QI(5)[8], + =AL7RE(5)[8],=AL7RL(5)[8],=G8ERJ(5)[8],=GO4AZM(5)[8],=GQ4AZM(5)[8],=GR4AZM(5)[8],=KH0CW(5)[8], + =KH0HR(5)[8],=KH0NI(5)[8],=KH0ZZ(5)[8],=KH2BX(5)[8],=KH2D(5)[8],=KH2D/4(5)[8],=KH2GUM/P(5)[8], + =KH2HB(5)[8],=KH2KD(5)[8],=KH2N(5)[8],=KH2NC(5)[8],=KH2PM(5)[8],=KH2RL(5)[8],=KH2TI(5)[8], + =KH2UV(5)[8],=KH2VM(5)[8],=KH3AC(5)[8],=KH3AG(5)[8],=KH6AME(5)[8],=KH6CG(5)[8],=KH6CG/4(5)[8], + =KH6CT(5)[8],=KH6ED(5)[8],=KH6HHS(5)[8],=KH6HHS/4(5)[8],=KH6HOW(5)[8],=KH6ILR(5)[8], + =KH6ILR/4(5)[8],=KH6ITI(5)[8],=KH6JAU(5)[8],=KH6JIM(5)[8],=KH6JJD(5)[8],=KH6JNW(5)[8], + =KH6JUA(5)[8],=KH6KZ(5)[8],=KH6M(5)[8],=KH6M/4(5)[8],=KH6M/M(5)[8],=KH6MT(5)[8],=KH6MT/4(5)[8], + =KH6NC(5)[8],=KH6NI(5)[8],=KH6OU(5)[8],=KH6POI(5)[8],=KH6PU(5)[8],=KH6RP(5)[8],=KH6TY(5)[8], + =KH6TY/R(5)[8],=KH6UN(5)[8],=KH6XH(5)[8],=KH7DM(5)[8],=KH7DY(5)[8],=KH7FC(5)[8],=KH7GZ(5)[8], + =KH7HJ/4(5)[8],=KH7OC(5)[8],=KH7OV(5)[8],=KH7WK(5)[8],=KH7XS/4(5)[8],=KH7XT(5)[8],=KH7ZC(5)[8], + =KH8BB(5)[8],=KH8DO(5)[8],=KL0AG(5)[8],=KL0IP(5)[8],=KL0KC(5)[8],=KL0KE/4(5)[8],=KL0L(5)[8], + =KL0MG(5)[8],=KL0MP(5)[8],=KL0S(5)[8],=KL0SS(5)[8],=KL0TY(5)[8],=KL0VU(5)[8],=KL0WF(5)[8], + =KL1KP(5)[8],=KL1NK(5)[8],=KL1NS(5)[8],=KL1OK(5)[8],=KL1PA(5)[8],=KL1SS(5)[8],=KL2AK(5)[8], + =KL2CX(5)[8],=KL2EY(5)[8],=KL2GG(5)[8],=KL2GP(5)[8],=KL2HV(5)[8],=KL2MQ(5)[8],=KL2NN(5)[8], + =KL2UQ(5)[8],=KL2XI(5)[8],=KL3EV(5)[8],=KL3HG(5)[8],=KL3IA(5)[8],=KL3KB(5)[8],=KL3KG(5)[8], + =KL3NR(5)[8],=KL3WM(5)[8],=KL3X(5)[8],=KL3XB(5)[8],=KL4CO(5)[8],=KL4DD(5)[8],=KL4H(5)[8], + =KL4J(5)[8],=KL5X(5)[8],=KL5YJ(5)[8],=KL7A(5)[8],=KL7DA(5)[8],=KL7DA/4(5)[8],=KL7FO(5)[8], + =KL7GLL(5)[8],=KL7H(5)[8],=KL7HIM(5)[8],=KL7HNY(5)[8],=KL7HOT(5)[8],=KL7HQW(5)[8],=KL7HX(5)[8], + =KL7IEK(5)[8],=KL7IKZ(5)[8],=KL7IV(5)[8],=KL7IVY(5)[8],=KL7IWF(5)[8],=KL7JDS(5)[8],=KL7JR(5)[8], =KL7LS(5)[8],=KL7MJ(5)[8],=KL7NCO(5)[8],=KL7NL(5)[8],=KL7NL/4(5)[8],=KL7NT(5)[8],=KL7P/4(5)[8], =KL7QH(5)[8],=KL7QU(5)[8],=KL7SR(5)[8],=KL7USI/4(5)[8],=KL7XA(5)[8],=KL9A/1(5)[8],=KP2AF(5)[8], =KP2AV(5)[8],=KP2AV/4(5)[8],=KP2CH(5)[8],=KP2CR(5)[8],=KP2L(5)[8],=KP2L/4(5)[8],=KP2N(5)[8], =KP2R(5)[8],=KP2U(5)[8],=KP2US(5)[8],=KP2V(5)[8],=KP3AMG(5)[8],=KP3BL(5)[8],=KP3BP(5)[8], - =KP3J(5)[8],=KP3SK(5)[8],=KP3U(5)[8],=KP4AD(5)[8],=KP4AOD(5)[8],=KP4AOD/4(5)[8],=KP4BEC(5)[8], - =KP4BM(5)[8],=KP4BOB(5)[8],=KP4CBP(5)[8],=KP4CEL(5)[8],=KP4CH(5)[8],=KP4CPP(5)[8],=KP4CSJ(5)[8], - =KP4CSZ(5)[8],=KP4CW(5)[8],=KP4CZ(5)[8],=KP4DAC(5)[8],=KP4DDS(5)[8],=KP4DPQ(5)[8],=KP4DQS(5)[8], - =KP4EIA(5)[8],=KP4EMY(5)[8],=KP4ENK(5)[8],=KP4EOR(5)[8],=KP4EOR/4(5)[8],=KP4ERT(5)[8], - =KP4ESC(5)[8],=KP4FBS(5)[8],=KP4FGI(5)[8],=KP4FIR(5)[8],=KP4FJE(5)[8],=KP4FLP(5)[8],=KP4FOF(5)[8], - =KP4HE(5)[8],=KP4HF(5)[8],=KP4HN(5)[8],=KP4II(5)[8],=KP4IRI(5)[8],=KP4IT(5)[8],=KP4JC(5)[8], - =KP4JCC(5)[8],=KP4JWR(5)[8],=KP4KA(5)[8],=KP4KD(5)[8],=KP4KD/4(5)[8],=KP4KE/4(5)[8],=KP4LEU(5)[8], - =KP4LF(5)[8],=KP4LUV(5)[8],=KP4LX(5)[8],=KP4MA(5)[8],=KP4MPR(5)[8],=KP4MSP(5)[8],=KP4NI(5)[8], - =KP4OO(5)[8],=KP4PC(5)[8],=KP4PF(5)[8],=KP4PMD(5)[8],=KP4Q(5)[8],=KP4QT(5)[8],=KP4QT/4(5)[8], - =KP4REY(5)[8],=KP4RGT(5)[8],=KP4ROP(5)[8],=KP4RRC(5)[8],=KP4RT(5)[8],=KP4RZ(5)[8],=KP4SU(5)[8], - =KP4TL(5)[8],=KP4TR(5)[8],=KP4UFO(5)[8],=KP4USA(5)[8],=KP4WK(5)[8],=KP4WW(5)[8],=KP4WY(5)[8], - =KP4XP(5)[8],=KP4Y(5)[8],=KP4YLV(5)[8],=KP4ZV(5)[8],=KP4ZX(5)[8],=NH2A(5)[8],=NH2BQ(5)[8], - =NH2DB(5)[8],=NH2F(5)[8],=NH6AU(5)[8],=NH6BD/4(5)[8],=NH6E(5)[8],=NH6GE(5)[8],=NH6GR(5)[8], - =NH6HX(5)[8],=NH6HX/4(5)[8],=NH6JX(5)[8],=NH6KI(5)[8],=NH6QR(5)[8],=NH6SR(5)[8],=NH6T(5)[8], - =NH6TL(5)[8],=NH7AA(5)[8],=NH7AQ(5)[8],=NH7AR(5)[8],=NH7FG(5)[8],=NH7OI(5)[8],=NH7T/4(5)[8], - =NH7UN(5)[8],=NH7XN(5)[8],=NL5L(5)[8],=NL7AJ(5)[8],=NL7AU(5)[8],=NL7AU/4(5)[8],=NL7BV(5)[8], - =NL7KX(5)[8],=NL7LO(5)[8],=NL7LR(5)[8],=NL7LY(5)[8],=NL7MD(5)[8],=NL7MR(5)[8],=NL7OB(5)[8], - =NL7OS(5)[8],=NL7P(5)[8],=NL7PV(5)[8],=NL7U(5)[8],=NL7VV(5)[8],=NL7VX(5)[8],=NL7VX/4(5)[8], - =NL7VX/M(5)[8],=NL7YZ(5)[8],=NP2B(5)[8],=NP2B/4(5)[8],=NP2BB(5)[8],=NP2BW(5)[8],=NP2C(5)[8], - =NP2C/4(5)[8],=NP2CB(5)[8],=NP2D(5)[8],=NP2DJ(5)[8],=NP2EI(5)[8],=NP2FT(5)[8],=NP2GN(5)[8], - =NP2GW(5)[8],=NP2HQ(5)[8],=NP2HS(5)[8],=NP2HW(5)[8],=NP2IE(5)[8],=NP2IF(5)[8],=NP2IJ(5)[8], - =NP2IS(5)[8],=NP2IW(5)[8],=NP2IX(5)[8],=NP2JA(5)[8],=NP2JS(5)[8],=NP2LC(5)[8],=NP2MM(5)[8], - =NP2MN(5)[8],=NP2MP(5)[8],=NP2MR(5)[8],=NP2MR/4(5)[8],=NP2O(5)[8],=NP2OL(5)[8],=NP2OO(5)[8], - =NP2OR(5)[8],=NP2PA(5)[8],=NP2R(5)[8],=NP2T(5)[8],=NP2W(5)[8],=NP3AX(5)[8],=NP3BL(5)[8], - =NP3CC(5)[8],=NP3CI(5)[8],=NP3CM(5)[8],=NP3CT(5)[8],=NP3FR(5)[8],=NP3G(5)[8],=NP3HD(5)[8], - =NP3HG(5)[8],=NP3HN(5)[8],=NP3HP(5)[8],=NP3HU(5)[8],=NP3IL(5)[8],=NP3IU(5)[8],=NP3K(5)[8], - =NP3KM(5)[8],=NP3MM(5)[8],=NP3MX(5)[8],=NP3NC(5)[8],=NP3OW(5)[8],=NP3QT(5)[8],=NP3R(5)[8], - =NP3ST(5)[8],=NP3TM(5)[8],=NP3UM(5)[8],=NP3VJ(5)[8],=NP4AS(5)[8],=NP4AV(5)[8],=NP4CC(5)[8], + =KP3J(5)[8],=KP3SK(5)[8],=KP3U(5)[8],=KP4AD(5)[8],=KP4AOD(5)[8],=KP4AOD/4(5)[8],=KP4BBN(5)[8], + =KP4BEC(5)[8],=KP4BM(5)[8],=KP4BOB(5)[8],=KP4CBP(5)[8],=KP4CEL(5)[8],=KP4CH(5)[8],=KP4CPP(5)[8], + =KP4CSJ(5)[8],=KP4CSZ(5)[8],=KP4CW(5)[8],=KP4CZ(5)[8],=KP4DAC(5)[8],=KP4DDS(5)[8],=KP4DPQ(5)[8], + =KP4DQS(5)[8],=KP4EDL(5)[8],=KP4EIA(5)[8],=KP4EMY(5)[8],=KP4ENK(5)[8],=KP4EOR(5)[8], + =KP4EOR/4(5)[8],=KP4ERT(5)[8],=KP4ESC(5)[8],=KP4FBS(5)[8],=KP4FGI(5)[8],=KP4FIR(5)[8], + =KP4FJE(5)[8],=KP4FLP(5)[8],=KP4FOF(5)[8],=KP4HE(5)[8],=KP4HF(5)[8],=KP4HN(5)[8],=KP4II(5)[8], + =KP4IRI(5)[8],=KP4IT(5)[8],=KP4JC(5)[8],=KP4JCC(5)[8],=KP4JOS(5)[8],=KP4JWR(5)[8],=KP4KA(5)[8], + =KP4KD(5)[8],=KP4KD/4(5)[8],=KP4KE/4(5)[8],=KP4LEU(5)[8],=KP4LF(5)[8],=KP4LUV(5)[8],=KP4LX(5)[8], + =KP4MA(5)[8],=KP4MPR(5)[8],=KP4MSP(5)[8],=KP4NI(5)[8],=KP4OO(5)[8],=KP4PC(5)[8],=KP4PF(5)[8], + =KP4PMD(5)[8],=KP4Q(5)[8],=KP4QT(5)[8],=KP4QT/4(5)[8],=KP4REY(5)[8],=KP4RGT(5)[8],=KP4ROP(5)[8], + =KP4RRC(5)[8],=KP4RT(5)[8],=KP4RZ(5)[8],=KP4SU(5)[8],=KP4TL(5)[8],=KP4TR(5)[8],=KP4UFO(5)[8], + =KP4USA(5)[8],=KP4WK(5)[8],=KP4WW(5)[8],=KP4WY(5)[8],=KP4XP(5)[8],=KP4Y(5)[8],=KP4YLV(5)[8], + =KP4ZV(5)[8],=KP4ZX(5)[8],=NH2A(5)[8],=NH2BQ(5)[8],=NH2DB(5)[8],=NH2F(5)[8],=NH6AU(5)[8], + =NH6BD/4(5)[8],=NH6E(5)[8],=NH6GE(5)[8],=NH6GR(5)[8],=NH6HX(5)[8],=NH6HX/4(5)[8],=NH6JX(5)[8], + =NH6KI(5)[8],=NH6QR(5)[8],=NH6SR(5)[8],=NH6T(5)[8],=NH6TL(5)[8],=NH7AA(5)[8],=NH7AQ(5)[8], + =NH7AR(5)[8],=NH7FG(5)[8],=NH7OI(5)[8],=NH7T/4(5)[8],=NH7UN(5)[8],=NH7XN(5)[8],=NL5L(5)[8], + =NL7AJ(5)[8],=NL7AU(5)[8],=NL7AU/4(5)[8],=NL7BV(5)[8],=NL7KL(5)[8],=NL7KX(5)[8],=NL7LO(5)[8], + =NL7LR(5)[8],=NL7LY(5)[8],=NL7MD(5)[8],=NL7MR(5)[8],=NL7OB(5)[8],=NL7OS(5)[8],=NL7P(5)[8], + =NL7PV(5)[8],=NL7U(5)[8],=NL7VV(5)[8],=NL7VX(5)[8],=NL7VX/4(5)[8],=NL7VX/M(5)[8],=NL7YZ(5)[8], + =NP2B(5)[8],=NP2B/4(5)[8],=NP2BB(5)[8],=NP2BW(5)[8],=NP2C(5)[8],=NP2C/4(5)[8],=NP2CB(5)[8], + =NP2D(5)[8],=NP2DJ(5)[8],=NP2EI(5)[8],=NP2FT(5)[8],=NP2GN(5)[8],=NP2GW(5)[8],=NP2HQ(5)[8], + =NP2HS(5)[8],=NP2HW(5)[8],=NP2IE(5)[8],=NP2IF(5)[8],=NP2IJ(5)[8],=NP2IS(5)[8],=NP2IW(5)[8], + =NP2IX(5)[8],=NP2JA(5)[8],=NP2JS(5)[8],=NP2L(5)[8],=NP2LC(5)[8],=NP2MM(5)[8],=NP2MN(5)[8], + =NP2MP(5)[8],=NP2MR(5)[8],=NP2MR/4(5)[8],=NP2O(5)[8],=NP2OL(5)[8],=NP2OO(5)[8],=NP2OR(5)[8], + =NP2PA(5)[8],=NP2R(5)[8],=NP2T(5)[8],=NP2W(5)[8],=NP3AX(5)[8],=NP3BL(5)[8],=NP3CC(5)[8], + =NP3CI(5)[8],=NP3CM(5)[8],=NP3CT(5)[8],=NP3FR(5)[8],=NP3G(5)[8],=NP3HD(5)[8],=NP3HG(5)[8], + =NP3HN(5)[8],=NP3HP(5)[8],=NP3HU(5)[8],=NP3IL(5)[8],=NP3IU(5)[8],=NP3K(5)[8],=NP3KM(5)[8], + =NP3MM(5)[8],=NP3MX(5)[8],=NP3NC(5)[8],=NP3OW(5)[8],=NP3QT(5)[8],=NP3R(5)[8],=NP3ST(5)[8], + =NP3TM(5)[8],=NP3UM(5)[8],=NP3VJ(5)[8],=NP3WX(5)[8],=NP4AS(5)[8],=NP4AV(5)[8],=NP4CC(5)[8], =NP4CK(5)[8],=NP4CV(5)[8],=NP4DM(5)[8],=NP4EM(5)[8],=NP4GH(5)[8],=NP4GW(5)[8],=NP4J(5)[8], =NP4JL(5)[8],=NP4JU(5)[8],=NP4KV(5)[8],=NP4M(5)[8],=NP4ND(5)[8],=NP4PF(5)[8],=NP4RJ(5)[8], =NP4SY(5)[8],=NP4TR(5)[8],=NP4WT(5)[8],=NP4XB(5)[8],=WH2AAT(5)[8],=WH2ABJ(5)[8],=WH2G(5)[8], =WH6A(5)[8],=WH6ACF(5)[8],=WH6AJS(5)[8],=WH6AQ(5)[8],=WH6AVU(5)[8],=WH6AX(5)[8],=WH6BRQ(5)[8], - =WH6CMT(5)[8],=WH6CNC(5)[8],=WH6CTC(5)[8],=WH6CXA(5)[8],=WH6CXT(5)[8],=WH6DBX(5)[8],=WH6DMJ(5)[8], - =WH6DNF(5)[8],=WH6DOL(5)[8],=WH6DUJ(5)[8],=WH6DXT(5)[8],=WH6EFI(5)[8],=WH6EIK(5)[8],=WH6EKW(5)[8], - =WH6ELG(5)[8],=WH6ELM(5)[8],=WH6ETE(5)[8],=WH6ETF(5)[8],=WH6FCP(5)[8],=WH6FGK(5)[8],=WH6HA(5)[8], - =WH6IF(5)[8],=WH6IZ(5)[8],=WH6J(5)[8],=WH6L(5)[8],=WH6LE(5)[8],=WH6LE/4(5)[8],=WH6LE/M(5)[8], - =WH6LE/P(5)[8],=WH6NE(5)[8],=WH6WX(5)[8],=WH6YH(5)[8],=WH6YH/4(5)[8],=WH6YM(5)[8],=WH6ZF(5)[8], - =WH7GD(5)[8],=WH7HX(5)[8],=WH7NI(5)[8],=WH7XK(5)[8],=WH7XU(5)[8],=WH7YL(5)[8],=WH7YV(5)[8], - =WH7ZM(5)[8],=WH9AAF(5)[8],=WL7AUL(5)[8],=WL7AX(5)[8],=WL7BAL(5)[8],=WL7CHA(5)[8],=WL7CIB(5)[8], - =WL7CKJ(5)[8],=WL7COL(5)[8],=WL7CQT(5)[8],=WL7CUY(5)[8],=WL7E/4(5)[8],=WL7GV(5)[8],=WL7SR(5)[8], - =WL7UN(5)[8],=WL7WN(5)[8],=WL7YX(5)[8],=WP2AGD(5)[8],=WP2AGO(5)[8],=WP2AHC(5)[8],=WP2AIG(5)[8], - =WP2BB(5)[8],=WP2C(5)[8],=WP2L(5)[8],=WP2MA(5)[8],=WP2P(5)[8],=WP3AY(5)[8],=WP3BC(5)[8], - =WP3JQ(5)[8],=WP3JU(5)[8],=WP3K(5)[8],=WP3LE(5)[8],=WP3MB(5)[8],=WP3ME(5)[8],=WP3NIS(5)[8], - =WP3O(5)[8],=WP3TQ(5)[8],=WP3ZA(5)[8],=WP3ZP(5)[8],=WP4AIE(5)[8],=WP4AIL(5)[8],=WP4AIZ(5)[8], - =WP4ALH(5)[8],=WP4AQK(5)[8],=WP4B(5)[8],=WP4BFP(5)[8],=WP4BGM(5)[8],=WP4BIN(5)[8],=WP4BJS(5)[8], - =WP4BK(5)[8],=WP4BQV(5)[8],=WP4BXS(5)[8],=WP4CKW(5)[8],=WP4CLS(5)[8],=WP4CMH(5)[8],=WP4DC(5)[8], - =WP4DCB(5)[8],=WP4DFK(5)[8],=WP4DNE(5)[8],=WP4DPX(5)[8],=WP4ENX(5)[8],=WP4EXH(5)[8],=WP4FEI(5)[8], - =WP4FRK(5)[8],=WP4FS(5)[8],=WP4GAK(5)[8],=WP4GFH(5)[8],=WP4GX(5)[8],=WP4GYA(5)[8],=WP4HFZ(5)[8], - =WP4HNN(5)[8],=WP4HOX(5)[8],=WP4IF(5)[8],=WP4IJ(5)[8],=WP4JKO(5)[8],=WP4JQJ(5)[8],=WP4JSR(5)[8], - =WP4JT(5)[8],=WP4KCJ(5)[8],=WP4KDH(5)[8],=WP4KFP(5)[8],=WP4KGI(5)[8],=WP4KI(5)[8],=WP4KJV(5)[8], - =WP4KSK(5)[8],=WP4KTD(5)[8],=WP4LBK(5)[8],=WP4LDG(5)[8],=WP4LDL(5)[8],=WP4LDP(5)[8],=WP4LHA(5)[8], - =WP4MAE(5)[8],=WP4MD(5)[8],=WP4MO(5)[8],=WP4MQF(5)[8],=WP4MWE(5)[8],=WP4MXE(5)[8],=WP4MYG(5)[8], - =WP4MYK(5)[8],=WP4NAI(5)[8],=WP4NAQ(5)[8],=WP4NBF(5)[8],=WP4NBG(5)[8],=WP4NFU(5)[8],=WP4NKU(5)[8], - =WP4NLQ(5)[8],=WP4NQA(5)[8],=WP4NVL(5)[8],=WP4NWW(5)[8],=WP4O/4(5)[8],=WP4O/M(5)[8],=WP4ODR(5)[8], - =WP4OFA(5)[8],=WP4OHJ(5)[8],=WP4OLM(5)[8],=WP4OMG(5)[8],=WP4OMV(5)[8],=WP4ONR(5)[8],=WP4OOI(5)[8], - =WP4OPD(5)[8],=WP4OPF(5)[8],=WP4OPG(5)[8],=WP4OTP(5)[8],=WP4P(5)[8],=WP4PR(5)[8],=WP4PUV(5)[8], - =WP4PWV(5)[8],=WP4PXG(5)[8],=WP4QHU(5)[8],=WP4SW(5)[8],=WP4TD(5)[8],=WP4TX(5)[8],=WP4UM(5)[8], + =WH6CEF(5)[8],=WH6CMT(5)[8],=WH6CNC(5)[8],=WH6CTC(5)[8],=WH6CXA(5)[8],=WH6CXT(5)[8],=WH6DBX(5)[8], + =WH6DMJ(5)[8],=WH6DNF(5)[8],=WH6DOL(5)[8],=WH6DUJ(5)[8],=WH6DXT(5)[8],=WH6EFI(5)[8],=WH6EIK(5)[8], + =WH6EKW(5)[8],=WH6ELG(5)[8],=WH6ELM(5)[8],=WH6ETE(5)[8],=WH6ETF(5)[8],=WH6FCP(5)[8],=WH6FGK(5)[8], + =WH6HA(5)[8],=WH6IF(5)[8],=WH6IZ(5)[8],=WH6J(5)[8],=WH6L(5)[8],=WH6LE(5)[8],=WH6LE/4(5)[8], + =WH6LE/M(5)[8],=WH6LE/P(5)[8],=WH6NE(5)[8],=WH6WX(5)[8],=WH6YH(5)[8],=WH6YH/4(5)[8],=WH6YM(5)[8], + =WH6ZF(5)[8],=WH7GD(5)[8],=WH7HX(5)[8],=WH7NI(5)[8],=WH7XK(5)[8],=WH7XU(5)[8],=WH7YL(5)[8], + =WH7YV(5)[8],=WH7ZM(5)[8],=WH9AAF(5)[8],=WL7AUL(5)[8],=WL7AX(5)[8],=WL7BAL(5)[8],=WL7CHA(5)[8], + =WL7CIB(5)[8],=WL7CKJ(5)[8],=WL7COL(5)[8],=WL7CQT(5)[8],=WL7CUY(5)[8],=WL7E/4(5)[8],=WL7GV(5)[8], + =WL7SR(5)[8],=WL7UN(5)[8],=WL7WN(5)[8],=WL7YX(5)[8],=WP2AGD(5)[8],=WP2AGO(5)[8],=WP2AHC(5)[8], + =WP2AIG(5)[8],=WP2BB(5)[8],=WP2C(5)[8],=WP2L(5)[8],=WP2MA(5)[8],=WP2P(5)[8],=WP3AY(5)[8], + =WP3BC(5)[8],=WP3JE(5)[8],=WP3JQ(5)[8],=WP3JU(5)[8],=WP3K(5)[8],=WP3LE(5)[8],=WP3MB(5)[8], + =WP3ME(5)[8],=WP3NIS(5)[8],=WP3O(5)[8],=WP3TQ(5)[8],=WP3ZA(5)[8],=WP3ZP(5)[8],=WP4AIE(5)[8], + =WP4AIL(5)[8],=WP4AIZ(5)[8],=WP4ALH(5)[8],=WP4AQK(5)[8],=WP4B(5)[8],=WP4BFP(5)[8],=WP4BGM(5)[8], + =WP4BIN(5)[8],=WP4BJS(5)[8],=WP4BK(5)[8],=WP4BOC(5)[8],=WP4BQV(5)[8],=WP4BXS(5)[8],=WP4CKW(5)[8], + =WP4CLS(5)[8],=WP4CMH(5)[8],=WP4DC(5)[8],=WP4DCB(5)[8],=WP4DFK(5)[8],=WP4DNE(5)[8],=WP4DPX(5)[8], + =WP4ENX(5)[8],=WP4EXH(5)[8],=WP4FEI(5)[8],=WP4FRK(5)[8],=WP4FS(5)[8],=WP4GAK(5)[8],=WP4GFH(5)[8], + =WP4GX(5)[8],=WP4GYA(5)[8],=WP4HFZ(5)[8],=WP4HNN(5)[8],=WP4HOX(5)[8],=WP4IF(5)[8],=WP4IJ(5)[8], + =WP4JKO(5)[8],=WP4JQJ(5)[8],=WP4JSR(5)[8],=WP4JT(5)[8],=WP4KCJ(5)[8],=WP4KDH(5)[8],=WP4KFP(5)[8], + =WP4KGI(5)[8],=WP4KI(5)[8],=WP4KJV(5)[8],=WP4KSK(5)[8],=WP4KTD(5)[8],=WP4LBK(5)[8],=WP4LDG(5)[8], + =WP4LDL(5)[8],=WP4LDP(5)[8],=WP4LHA(5)[8],=WP4MAE(5)[8],=WP4MD(5)[8],=WP4MO(5)[8],=WP4MQF(5)[8], + =WP4MWE(5)[8],=WP4MXE(5)[8],=WP4MYG(5)[8],=WP4MYK(5)[8],=WP4NAI(5)[8],=WP4NAQ(5)[8],=WP4NBF(5)[8], + =WP4NBG(5)[8],=WP4NFU(5)[8],=WP4NKU(5)[8],=WP4NLQ(5)[8],=WP4NQA(5)[8],=WP4NVL(5)[8],=WP4NWW(5)[8], + =WP4O/4(5)[8],=WP4O/M(5)[8],=WP4ODR(5)[8],=WP4OFA(5)[8],=WP4OHJ(5)[8],=WP4OLM(5)[8],=WP4OMG(5)[8], + =WP4OMV(5)[8],=WP4ONR(5)[8],=WP4OOI(5)[8],=WP4OPD(5)[8],=WP4OPF(5)[8],=WP4OPG(5)[8],=WP4OTP(5)[8], + =WP4OXA(5)[8],=WP4P(5)[8],=WP4PR(5)[8],=WP4PUV(5)[8],=WP4PWV(5)[8],=WP4PXG(5)[8],=WP4QHU(5)[8], + =WP4SW(5)[8],=WP4TD(5)[8],=WP4TX(5)[8],=WP4UC(5)[8],=WP4UM(5)[8], AA5(4)[7],AB5(4)[7],AC5(4)[7],AD5(4)[7],AE5(4)[7],AF5(4)[7],AG5(4)[7],AI5(4)[7],AJ5(4)[7], AK5(4)[7],K5(4)[7],KA5(4)[7],KB5(4)[7],KC5(4)[7],KD5(4)[7],KE5(4)[7],KF5(4)[7],KG5(4)[7], KI5(4)[7],KJ5(4)[7],KK5(4)[7],KM5(4)[7],KN5(4)[7],KO5(4)[7],KQ5(4)[7],KR5(4)[7],KS5(4)[7], @@ -1316,49 +1324,49 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K: NW5(4)[7],NX5(4)[7],NY5(4)[7],NZ5(4)[7],W5(4)[7],WA5(4)[7],WB5(4)[7],WC5(4)[7],WD5(4)[7], WE5(4)[7],WF5(4)[7],WG5(4)[7],WI5(4)[7],WJ5(4)[7],WK5(4)[7],WM5(4)[7],WN5(4)[7],WO5(4)[7], WQ5(4)[7],WR5(4)[7],WS5(4)[7],WT5(4)[7],WU5(4)[7],WV5(4)[7],WW5(4)[7],WX5(4)[7],WY5(4)[7], - WZ5(4)[7],=AH2AQ(4)[7],=AH2AQ/5(4)[7],=AH2DG(4)[7],=AH2EH(4)[7],=AH2H(4)[7],=AH2T(4)[7], - =AH6AF(4)[7],=AH6DZ(4)[7],=AH6FV(4)[7],=AH6HT(4)[7],=AH6OU(4)[7],=AH6RB(4)[7],=AH6TD(4)[7], - =AH6UD(4)[7],=AH8O(4)[7],=AH9B(4)[7],=AL2K(4)[7],=AL2S(4)[7],=AL4F(4)[7],=AL5J(4)[7],=AL7C(4)[7], - =AL7CJ(4)[7],=AL7CQ(4)[7],=AL7DF(4)[7],=AL7DR(4)[7],=AL7GY(4)[7],=AL7HH(4)[7],=AL7HU(4)[7], - =AL7II/5(4)[7],=AL7IM(4)[7],=AL7J(4)[7],=AL7JP(4)[7],=AL7L/5(4)[7],=AL7PB(4)[7],=AL7RD(4)[7], - =AL7RI(4)[7],=KH0BZ(4)[7],=KH0CE(4)[7],=KH0CU(4)[7],=KH0DW(4)[7],=KH2AI(4)[7],=KH2BH(4)[7], - =KH2DF(4)[7],=KH2DF/5(4)[7],=KH2TB(4)[7],=KH2XD(4)[7],=KH2XO(4)[7],=KH2YO(4)[7],=KH6ABA(4)[7], - =KH6DAN(4)[7],=KH6GGC(4)[7],=KH6HPQ(4)[7],=KH6II(4)[7],=KH6ITY/M(4)[7],=KH6JIQ(4)[7], - =KH6JTM(4)[7],=KH6JVL(4)[7],=KH6KG/5(4)[7],=KH6LX(4)[7],=KH6MB/5(4)[7],=KH6SP/5(4)[7], - =KH6SZ(4)[7],=KH6UW(4)[7],=KH7CF(4)[7],=KH7FB(4)[7],=KH7IC(4)[7],=KH7JE(4)[7],=KH7QL(4)[7], - =KH7QO(4)[7],=KH8CG(4)[7],=KH9AE(4)[7],=KL0EX(4)[7],=KL0HU(4)[7],=KL0PG(4)[7],=KL1DA(4)[7], - =KL1DJ(4)[7],=KL1RX(4)[7],=KL1TS(4)[7],=KL1UR(4)[7],=KL1WG(4)[7],=KL1WO(4)[7],=KL1XK(4)[7], - =KL1Y(4)[7],=KL1ZW(4)[7],=KL2AX(4)[7],=KL2AX/5(4)[7],=KL2CD(4)[7],=KL2HC(4)[7],=KL2HN(4)[7], - =KL2MI(4)[7],=KL2NN(4)[7],=KL2RA(4)[7],=KL2RB(4)[7],=KL2TV(4)[7],=KL2VA(4)[7],=KL3DB(4)[7], - =KL3DP(4)[7],=KL3HK(4)[7],=KL3HZ(4)[7],=KL3JL(4)[7],=KL3KH(4)[7],=KL3KI(4)[7],=KL3TB(4)[7], - =KL4JQ(4)[7],=KL5L(4)[7],=KL5Z(4)[7],=KL7AH(4)[7],=KL7AU(4)[7],=KL7AX(4)[7],=KL7BCD(4)[7], - =KL7BL(4)[7],=KL7BX(4)[7],=KL7BZ/5(4)[7],=KL7BZL(4)[7],=KL7CD(4)[7],=KL7DB(4)[7],=KL7EBE(4)[7], - =KL7EMH(4)[7],=KL7EMH/M(4)[7],=KL7EQQ(4)[7],=KL7F(4)[7],=KL7FB(4)[7],=KL7FHX(4)[7],=KL7FLY(4)[7], - =KL7FQR(4)[7],=KL7GNW(4)[7],=KL7HH(4)[7],=KL7IDM(4)[7],=KL7IK(4)[7],=KL7ITF(4)[7],=KL7IWU(4)[7], - =KL7IZW(4)[7],=KL7JAR(4)[7],=KL7JEX(4)[7],=KL7JIU(4)[7],=KL7JR/5(4)[7],=KL7JW(4)[7],=KL7LJ(4)[7], - =KL7LY(4)[7],=KL7MA(4)[7],=KL7ME(4)[7],=KL7ML(4)[7],=KL7NE(4)[7],=KL7NI(4)[7],=KL7OI(4)[7], - =KL7PZ(4)[7],=KL7QC(4)[7],=KL7SG(4)[7],=KL7TN/5(4)[7],=KL7UHF(4)[7],=KL7USI/5(4)[7],=KL7XP(4)[7], - =KL7XS(4)[7],=KL7YY/5(4)[7],=KP2AZ(4)[7],=KP4CV(4)[7],=KP4DJT(4)[7],=KP4FF(4)[7],=KP4FFW(4)[7], - =KP4GMC(4)[7],=KP4JE(4)[7],=KP4JG(4)[7],=KP4JY(4)[7],=KP4YP(4)[7],=NH0V/5(4)[7],=NH2LA(4)[7], - =NH2LP(4)[7],=NH6AZ(4)[7],=NH6CJ(4)[7],=NH6EF(4)[7],=NH6FA(4)[7],=NH6L(4)[7],=NH6VB(4)[7], - =NH6VJ(4)[7],=NH6WL(4)[7],=NH6WL/5(4)[7],=NH7FO(4)[7],=NH7MV(4)[7],=NH7PZ(4)[7],=NH7RO(4)[7], - =NH7RO/5(4)[7],=NH7TR(4)[7],=NH7VA(4)[7],=NL5J(4)[7],=NL7AX(4)[7],=NL7C(4)[7],=NL7CO(4)[7], - =NL7CO/5(4)[7],=NL7CO/M(4)[7],=NL7DC(4)[7],=NL7HB(4)[7],=NL7IE(4)[7],=NL7JH(4)[7],=NL7JI(4)[7], - =NL7K/5(4)[7],=NL7KB(4)[7],=NL7NP(4)[7],=NL7OM(4)[7],=NL7PD(4)[7],=NL7RQ(4)[7],=NL7RQ/5(4)[7], - =NL7TO(4)[7],=NL7ZL(4)[7],=NP2EE(4)[7],=NP2PR(4)[7],=NP2RA(4)[7],=NP3BA(4)[7],=NP3CV(4)[7], - =NP3NT(4)[7],=NP3PG(4)[7],=NP3RG(4)[7],=NP3SU(4)[7],=NP3TY(4)[7],=NP4EA(4)[7],=NP4NQ(4)[7], - =NP4NQ/5(4)[7],=NP4RW(4)[7],=NP4RZ(4)[7],=WH2ACT(4)[7],=WH2ACT/5(4)[7],=WH6ARN(4)[7], - =WH6BYJ(4)[7],=WH6BYP(4)[7],=WH6CDU(4)[7],=WH6CUL(4)[7],=WH6DZU(4)[7],=WH6ECJ(4)[7],=WH6EMW(4)[7], - =WH6EOF(4)[7],=WH6ERS(4)[7],=WH6EUA(4)[7],=WH6EXQ(4)[7],=WH6FAD(4)[7],=WH6FGM(4)[7], - =WH6FZ/5(4)[7],=WH6L/5(4)[7],=WH6ZR(4)[7],=WH7DC(4)[7],=WH7DW(4)[7],=WH7OK(4)[7],=WH7R(4)[7], - =WH7YQ(4)[7],=WH7YR(4)[7],=WL3WX(4)[7],=WL5H(4)[7],=WL7AIU(4)[7],=WL7AWC(4)[7],=WL7BBV(4)[7], - =WL7BKF(4)[7],=WL7BPY(4)[7],=WL7CA(4)[7],=WL7CJA(4)[7],=WL7CJC(4)[7],=WL7CQE(4)[7],=WL7CTP(4)[7], - =WL7CTQ(4)[7],=WL7D(4)[7],=WL7FT(4)[7],=WL7FT/5(4)[7],=WL7K/5(4)[7],=WL7ME(4)[7],=WL7MQ/5(4)[7], - =WL7OP(4)[7],=WL7OU(4)[7],=WL7SG(4)[7],=WL7W(4)[7],=WL7XI(4)[7],=WL7XR(4)[7],=WP2AHG(4)[7], - =WP2WP(4)[7],=WP3AL(4)[7],=WP4A(4)[7],=WP4ADA(4)[7],=WP4APJ(4)[7],=WP4BAB(4)[7],=WP4BAT(4)[7], - =WP4CJY(4)[7],=WP4EVA(4)[7],=WP4EVL(4)[7],=WP4KSP(4)[7],=WP4KTF(4)[7],=WP4KUW(4)[7],=WP4LKA(4)[7], - =WP4MJP(4)[7],=WP4MWS(4)[7],=WP4MYI(4)[7],=WP4MZR(4)[7],=WP4NAK(4)[7],=WP4NEP(4)[7],=WP4NQL(4)[7], - =WP4OUE(4)[7],=WP4RON(4)[7], + WZ5(4)[7],=AH2AQ(4)[7],=AH2AQ/5(4)[7],=AH2DG(4)[7],=AH2DR(4)[7],=AH2EH(4)[7],=AH2H(4)[7], + =AH2T(4)[7],=AH6AF(4)[7],=AH6DZ(4)[7],=AH6FV(4)[7],=AH6HT(4)[7],=AH6OU(4)[7],=AH6RB(4)[7], + =AH6TD(4)[7],=AH6UD(4)[7],=AH8O(4)[7],=AH9B(4)[7],=AL1F(4)[7],=AL2K(4)[7],=AL2S(4)[7],=AL4F(4)[7], + =AL5J(4)[7],=AL7C(4)[7],=AL7CJ(4)[7],=AL7CQ(4)[7],=AL7DF(4)[7],=AL7DR(4)[7],=AL7GY(4)[7], + =AL7HH(4)[7],=AL7HU(4)[7],=AL7II/5(4)[7],=AL7IM(4)[7],=AL7J(4)[7],=AL7JP(4)[7],=AL7L/5(4)[7], + =AL7PB(4)[7],=AL7RD(4)[7],=AL7RI(4)[7],=AL7V(4)[7],=KH0BZ(4)[7],=KH0CE(4)[7],=KH0CU(4)[7], + =KH0DW(4)[7],=KH2AI(4)[7],=KH2BH(4)[7],=KH2DF(4)[7],=KH2DF/5(4)[7],=KH2TB(4)[7],=KH2XD(4)[7], + =KH2XO(4)[7],=KH2YO(4)[7],=KH6ABA(4)[7],=KH6DAN(4)[7],=KH6GGC(4)[7],=KH6HPQ(4)[7],=KH6II(4)[7], + =KH6ITY/M(4)[7],=KH6JIQ(4)[7],=KH6JTM(4)[7],=KH6JVL(4)[7],=KH6KG/5(4)[7],=KH6LL(4)[7], + =KH6LX(4)[7],=KH6MB/5(4)[7],=KH6SP/5(4)[7],=KH6SZ(4)[7],=KH6UW(4)[7],=KH7CF(4)[7],=KH7FB(4)[7], + =KH7IC(4)[7],=KH7JE(4)[7],=KH7QL(4)[7],=KH7QO(4)[7],=KH8CG(4)[7],=KH9AE(4)[7],=KL0EX(4)[7], + =KL0HU(4)[7],=KL0PG(4)[7],=KL1DA(4)[7],=KL1DJ(4)[7],=KL1RX(4)[7],=KL1TS(4)[7],=KL1UR(4)[7], + =KL1WG(4)[7],=KL1WO(4)[7],=KL1XK(4)[7],=KL1Y(4)[7],=KL1ZW(4)[7],=KL2AX(4)[7],=KL2AX/5(4)[7], + =KL2CD(4)[7],=KL2HC(4)[7],=KL2HN(4)[7],=KL2MI(4)[7],=KL2RA(4)[7],=KL2RB(4)[7],=KL2TV(4)[7], + =KL2VA(4)[7],=KL3DB(4)[7],=KL3DP(4)[7],=KL3HK(4)[7],=KL3HZ(4)[7],=KL3JL(4)[7],=KL3KH(4)[7], + =KL3KI(4)[7],=KL3TB(4)[7],=KL4JQ(4)[7],=KL5L(4)[7],=KL5Z(4)[7],=KL7AH(4)[7],=KL7AU(4)[7], + =KL7AX(4)[7],=KL7BCD(4)[7],=KL7BL(4)[7],=KL7BX(4)[7],=KL7BZ/5(4)[7],=KL7BZL(4)[7],=KL7CD(4)[7], + =KL7DB(4)[7],=KL7EBE(4)[7],=KL7EMH(4)[7],=KL7EMH/M(4)[7],=KL7EQQ(4)[7],=KL7F(4)[7],=KL7FB(4)[7], + =KL7FHX(4)[7],=KL7FLY(4)[7],=KL7FQR(4)[7],=KL7GNW(4)[7],=KL7HH(4)[7],=KL7HJZ(4)[7],=KL7IDM(4)[7], + =KL7IK(4)[7],=KL7ITF(4)[7],=KL7IWU(4)[7],=KL7IZW(4)[7],=KL7JAR(4)[7],=KL7JEX(4)[7],=KL7JIU(4)[7], + =KL7JR/5(4)[7],=KL7JW(4)[7],=KL7LJ(4)[7],=KL7LY(4)[7],=KL7MA(4)[7],=KL7ME(4)[7],=KL7ML(4)[7], + =KL7NE(4)[7],=KL7NI(4)[7],=KL7OI(4)[7],=KL7PZ(4)[7],=KL7QC(4)[7],=KL7SG(4)[7],=KL7TN/5(4)[7], + =KL7UHF(4)[7],=KL7USI/5(4)[7],=KL7XP(4)[7],=KL7XS(4)[7],=KL7YY/5(4)[7],=KP2AZ(4)[7],=KP4CV(4)[7], + =KP4DJT(4)[7],=KP4FF(4)[7],=KP4FFW(4)[7],=KP4GMC(4)[7],=KP4JE(4)[7],=KP4JG(4)[7],=KP4JY(4)[7], + =KP4YP(4)[7],=NH0V/5(4)[7],=NH2LP(4)[7],=NH6AZ(4)[7],=NH6CJ(4)[7],=NH6EF(4)[7],=NH6FA(4)[7], + =NH6L(4)[7],=NH6VB(4)[7],=NH6VJ(4)[7],=NH6WL(4)[7],=NH6WL/5(4)[7],=NH7FO(4)[7],=NH7MV(4)[7], + =NH7PZ(4)[7],=NH7R(4)[7],=NH7RO(4)[7],=NH7RO/5(4)[7],=NH7TR(4)[7],=NH7VA(4)[7],=NL5J(4)[7], + =NL7AX(4)[7],=NL7C(4)[7],=NL7CO(4)[7],=NL7CO/5(4)[7],=NL7CO/M(4)[7],=NL7DC(4)[7],=NL7HB(4)[7], + =NL7IE(4)[7],=NL7JH(4)[7],=NL7JI(4)[7],=NL7K/5(4)[7],=NL7KB(4)[7],=NL7NP(4)[7],=NL7OM(4)[7], + =NL7PD(4)[7],=NL7RQ(4)[7],=NL7RQ/5(4)[7],=NL7SI(4)[7],=NL7TO(4)[7],=NL7ZL(4)[7],=NP2EE(4)[7], + =NP2PR(4)[7],=NP2RA(4)[7],=NP3BA(4)[7],=NP3CV(4)[7],=NP3NT(4)[7],=NP3PG(4)[7],=NP3RG(4)[7], + =NP3SU(4)[7],=NP3TY(4)[7],=NP4EA(4)[7],=NP4NQ(4)[7],=NP4NQ/5(4)[7],=NP4RW(4)[7],=NP4RZ(4)[7], + =WH2ACT(4)[7],=WH2ACT/5(4)[7],=WH6ARN(4)[7],=WH6BYJ(4)[7],=WH6BYP(4)[7],=WH6CDU(4)[7], + =WH6CUL(4)[7],=WH6DZU(4)[7],=WH6ECJ(4)[7],=WH6EMW(4)[7],=WH6EOF(4)[7],=WH6ERS(4)[7],=WH6EUA(4)[7], + =WH6EXQ(4)[7],=WH6FAD(4)[7],=WH6FGM(4)[7],=WH6FZ/5(4)[7],=WH6L/5(4)[7],=WH7DC(4)[7],=WH7DW(4)[7], + =WH7OK(4)[7],=WH7R(4)[7],=WH7YQ(4)[7],=WH7YR(4)[7],=WL3WX(4)[7],=WL5H(4)[7],=WL7AIU(4)[7], + =WL7AWC(4)[7],=WL7BBV(4)[7],=WL7BKF(4)[7],=WL7BPY(4)[7],=WL7CA(4)[7],=WL7CJA(4)[7],=WL7CJC(4)[7], + =WL7CQE(4)[7],=WL7CTP(4)[7],=WL7CTQ(4)[7],=WL7D(4)[7],=WL7FE(4)[7],=WL7FT(4)[7],=WL7FT/5(4)[7], + =WL7K/5(4)[7],=WL7ME(4)[7],=WL7MQ/5(4)[7],=WL7OP(4)[7],=WL7OU(4)[7],=WL7SG(4)[7],=WL7W(4)[7], + =WL7XI(4)[7],=WL7XR(4)[7],=WP2AHG(4)[7],=WP2WP(4)[7],=WP3AL(4)[7],=WP4A(4)[7],=WP4ADA(4)[7], + =WP4APJ(4)[7],=WP4BAB(4)[7],=WP4BAT(4)[7],=WP4CJY(4)[7],=WP4EVA(4)[7],=WP4EVL(4)[7],=WP4KSP(4)[7], + =WP4KTF(4)[7],=WP4KUW(4)[7],=WP4LKA(4)[7],=WP4MJP(4)[7],=WP4MWS(4)[7],=WP4MYI(4)[7],=WP4MZR(4)[7], + =WP4NAK(4)[7],=WP4NEP(4)[7],=WP4NQL(4)[7],=WP4OUE(4)[7],=WP4RON(4)[7], AA6(3)[6],AB6(3)[6],AC6(3)[6],AD6(3)[6],AE6(3)[6],AF6(3)[6],AG6(3)[6],AI6(3)[6],AJ6(3)[6], AK6(3)[6],K6(3)[6],KA6(3)[6],KB6(3)[6],KC6(3)[6],KD6(3)[6],KE6(3)[6],KF6(3)[6],KG6(3)[6], KI6(3)[6],KJ6(3)[6],KK6(3)[6],KM6(3)[6],KN6(3)[6],KO6(3)[6],KQ6(3)[6],KR6(3)[6],KS6(3)[6], @@ -1368,53 +1376,55 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K: NW6(3)[6],NX6(3)[6],NY6(3)[6],NZ6(3)[6],W6(3)[6],WA6(3)[6],WB6(3)[6],WC6(3)[6],WD6(3)[6], WE6(3)[6],WF6(3)[6],WG6(3)[6],WI6(3)[6],WJ6(3)[6],WK6(3)[6],WM6(3)[6],WN6(3)[6],WO6(3)[6], WQ6(3)[6],WR6(3)[6],WS6(3)[6],WT6(3)[6],WU6(3)[6],WV6(3)[6],WW6(3)[6],WX6(3)[6],WY6(3)[6], - WZ6(3)[6],=AH0CS(3)[6],=AH0U(3)[6],=AH0U/6(3)[6],=AH2AP(3)[6],=AH2DY(3)[6],=AH6BS(3)[6], - =AH6CY(3)[6],=AH6CY/P(3)[6],=AH6EI(3)[6],=AH6HE(3)[6],=AH6KG(3)[6],=AH6ML(3)[6],=AH6NL(3)[6], - =AH6NP(3)[6],=AH6PD(3)[6],=AH6RI(3)[6],=AH6S(3)[6],=AH6SU(3)[6],=AH6TX(3)[6],=AH6UN(3)[6], - =AH7A(3)[6],=AH7D(3)[6],=AH7F(3)[6],=AH8C(3)[6],=AL3A(3)[6],=AL5ET(3)[6],=AL6A(3)[6],=AL7DQ(3)[6], - =AL7EM(3)[6],=AL7EP(3)[6],=AL7EW(3)[6],=AL7FN(3)[6],=AL7GS(3)[6],=AL7HO/6(3)[6],=AL7L/6(3)[6], - =AL7PS(3)[6],=KH0BR(3)[6],=KH0BU(3)[6],=KH0CA(3)[6],=KH0CG(3)[6],=KH0DH(3)[6],=KH0DJ(3)[6], - =KH0HQ(3)[6],=KH0JJ(3)[6],=KH0V(3)[6],=KH0XD(3)[6],=KH2BD(3)[6],=KH2BI(3)[6],=KH2BR(3)[6], - =KH2BR/6(3)[6],=KH2C(3)[6],=KH2EE(3)[6],=KH2FI(3)[6],=KH2FI/6(3)[6],=KH2H(3)[6],=KH2IW(3)[6], - =KH2LU(3)[6],=KH2LW(3)[6],=KH2LZ(3)[6],=KH2OJ(3)[6],=KH2QE(3)[6],=KH2QL(3)[6],=KH2QY(3)[6], - =KH2TJ(3)[6],=KH2TJ/6(3)[6],=KH2XW(3)[6],=KH2YJ(3)[6],=KH2Z(3)[6],=KH2ZM(3)[6],=KH4AB(3)[6], - =KH6ARA(3)[6],=KH6AS(3)[6],=KH6BMD(3)[6],=KH6BRY(3)[6],=KH6COL(3)[6],=KH6DDW(3)[6],=KH6DX/M(3)[6], - =KH6DX/M6(3)[6],=KH6DZ(3)[6],=KH6EHF(3)[6],=KH6FH(3)[6],=KH6FL(3)[6],=KH6FOX(3)[6],=KH6FQR(3)[6], - =KH6FQY(3)[6],=KH6GBQ(3)[6],=KH6GC(3)[6],=KH6GJV(3)[6],=KH6GJV/6(3)[6],=KH6GK(3)[6],=KH6GKR(3)[6], - =KH6HJE(3)[6],=KH6HOU(3)[6],=KH6IKH(3)[6],=KH6IKL(3)[6],=KH6IP(3)[6],=KH6IPJ(3)[6],=KH6JCT(3)[6], - =KH6JGD(3)[6],=KH6JJN(3)[6],=KH6JJN/P(3)[6],=KH6JN(3)[6],=KH6JRB(3)[6],=KH6JRC(3)[6],=KH6JS(3)[6], - =KH6JUZ(3)[6],=KH6JVS(3)[6],=KH6JWG(3)[6],=KH6KT(3)[6],=KH6LO(3)[6],=KH6MV(3)[6],=KH6N(3)[6], - =KH6NG(3)[6],=KH6O(3)[6],=KH6PGA/6(3)[6],=KH6PM(3)[6],=KH6PW(3)[6],=KH6SC(3)[6],=KH6TO(3)[6], - =KH6UQ(3)[6],=KH6USA(3)[6],=KH6VC(3)[6],=KH6VC/6(3)[6],=KH6VZ(3)[6],=KH6WL(3)[6],=KH6WZ(3)[6], - =KH7CD/6(3)[6],=KH7CO(3)[6],=KH7CS(3)[6],=KH7EM(3)[6],=KH7I(3)[6],=KH7IZ(3)[6],=KH7JR(3)[6], - =KH7NS(3)[6],=KH7QS(3)[6],=KH7QU(3)[6],=KH7RB(3)[6],=KH7TJ(3)[6],=KH7TJ/6(3)[6],=KH7XX/6(3)[6], + WZ6(3)[6],=AH0C(3)[6],=AH0CS(3)[6],=AH0U(3)[6],=AH0U/6(3)[6],=AH2AP(3)[6],=AH2DY(3)[6], + =AH6BS(3)[6],=AH6CY(3)[6],=AH6CY/P(3)[6],=AH6EI(3)[6],=AH6HE(3)[6],=AH6KG(3)[6],=AH6ML(3)[6], + =AH6NL(3)[6],=AH6NP(3)[6],=AH6PD(3)[6],=AH6RI(3)[6],=AH6S(3)[6],=AH6SU(3)[6],=AH6TX(3)[6], + =AH6UN(3)[6],=AH7A(3)[6],=AH7D(3)[6],=AH7F(3)[6],=AH8C(3)[6],=AL3A(3)[6],=AL5ET(3)[6],=AL6A(3)[6], + =AL7DQ(3)[6],=AL7EM(3)[6],=AL7EP(3)[6],=AL7EW(3)[6],=AL7FN(3)[6],=AL7GS(3)[6],=AL7HO/6(3)[6], + =AL7L/6(3)[6],=AL7PS(3)[6],=AL7QR(3)[6],=KH0BR(3)[6],=KH0BU(3)[6],=KH0CA(3)[6],=KH0CG(3)[6], + =KH0DH(3)[6],=KH0DJ(3)[6],=KH0HQ(3)[6],=KH0JJ(3)[6],=KH0V(3)[6],=KH0XD(3)[6],=KH2BD(3)[6], + =KH2BI(3)[6],=KH2BR(3)[6],=KH2BR/6(3)[6],=KH2C(3)[6],=KH2EE(3)[6],=KH2FI(3)[6],=KH2FI/6(3)[6], + =KH2H(3)[6],=KH2IW(3)[6],=KH2LU(3)[6],=KH2LW(3)[6],=KH2LZ(3)[6],=KH2OJ(3)[6],=KH2QE(3)[6], + =KH2QL(3)[6],=KH2QY(3)[6],=KH2TJ(3)[6],=KH2TJ/6(3)[6],=KH2XW(3)[6],=KH2YJ(3)[6],=KH2Z(3)[6], + =KH2ZM(3)[6],=KH4AB(3)[6],=KH6ARA(3)[6],=KH6AS(3)[6],=KH6BMD(3)[6],=KH6BRY(3)[6],=KH6COL(3)[6], + =KH6DDW(3)[6],=KH6DX/M(3)[6],=KH6DX/M6(3)[6],=KH6DZ(3)[6],=KH6EHF(3)[6],=KH6FH(3)[6],=KH6FL(3)[6], + =KH6FOX(3)[6],=KH6FQR(3)[6],=KH6FQY(3)[6],=KH6GBQ(3)[6],=KH6GC(3)[6],=KH6GJV(3)[6], + =KH6GJV/6(3)[6],=KH6GK(3)[6],=KH6GKR(3)[6],=KH6HJE(3)[6],=KH6HOU(3)[6],=KH6IKH(3)[6], + =KH6IKL(3)[6],=KH6IP(3)[6],=KH6IPJ(3)[6],=KH6JCT(3)[6],=KH6JGD(3)[6],=KH6JJN(3)[6], + =KH6JJN/P(3)[6],=KH6JN(3)[6],=KH6JR(3)[6],=KH6JRB(3)[6],=KH6JRC(3)[6],=KH6JS(3)[6],=KH6JUZ(3)[6], + =KH6JVS(3)[6],=KH6JWG(3)[6],=KH6KT(3)[6],=KH6LO(3)[6],=KH6MV(3)[6],=KH6N(3)[6],=KH6NG(3)[6], + =KH6O(3)[6],=KH6PGA/6(3)[6],=KH6PM(3)[6],=KH6PW(3)[6],=KH6SC(3)[6],=KH6TO(3)[6],=KH6UQ(3)[6], + =KH6USA(3)[6],=KH6VC(3)[6],=KH6VC/6(3)[6],=KH6VZ(3)[6],=KH6WL(3)[6],=KH6WZ(3)[6],=KH7CD/6(3)[6], + =KH7CO(3)[6],=KH7CS(3)[6],=KH7EM(3)[6],=KH7I(3)[6],=KH7IZ(3)[6],=KH7JR(3)[6],=KH7NS(3)[6], + =KH7QS(3)[6],=KH7QU(3)[6],=KH7RB(3)[6],=KH7TJ(3)[6],=KH7TJ/6(3)[6],=KH7TW(3)[6],=KH7XX/6(3)[6], =KH7Y(3)[6],=KH7Y/6(3)[6],=KH8A(3)[6],=KH8AF(3)[6],=KH8FL(3)[6],=KL0AA(3)[6],=KL0AF(3)[6], =KL0AL(3)[6],=KL0HZ(3)[6],=KL0IF(3)[6],=KL1WE/6(3)[6],=KL2CQ(3)[6],=KL3JY/6(3)[6],=KL3YH(3)[6], - =KL4GW(3)[6],=KL4LV(3)[6],=KL4NZ(3)[6],=KL4QW(3)[6],=KL7AK(3)[6],=KL7CE/6(3)[6],=KL7CM(3)[6], - =KL7CN(3)[6],=KL7CW/6(3)[6],=KL7CX(3)[6],=KL7DJ(3)[6],=KL7EAE(3)[6],=KL7EAL(3)[6],=KL7HQR(3)[6], - =KL7HQR/6(3)[6],=KL7HSY(3)[6],=KL7ID(3)[6],=KL7IDY/6(3)[6],=KL7ISN(3)[6],=KL7JBE(3)[6], - =KL7KNP(3)[6],=KL7KX(3)[6],=KL7MF(3)[6],=KL7MF/6(3)[6],=KL7MF/M(3)[6],=KL7OO(3)[6],=KL7RT(3)[6], - =KL7SL(3)[6],=KL7SY(3)[6],=KL7VU(3)[6],=KL7VU/6(3)[6],=KP2BK(3)[6],=KP3BN(3)[6],=KP3YL(3)[6], - =KP4BR(3)[6],=KP4DSO(3)[6],=KP4DX/6(3)[6],=KP4ENM(3)[6],=KP4ERR(3)[6],=KP4FBT(3)[6],=KP4MD(3)[6], - =KP4UB(3)[6],=NH0C(3)[6],=NH0X(3)[6],=NH2AR(3)[6],=NH2BD(3)[6],=NH2BV(3)[6],=NH2CM(3)[6], - =NH2FT(3)[6],=NH2FX(3)[6],=NH2R(3)[6],=NH2S(3)[6],=NH6AC(3)[6],=NH6AE(3)[6],=NH6FV(3)[6], - =NH6FX(3)[6],=NH6NG(3)[6],=NH6RG(3)[6],=NH6WR(3)[6],=NH7AG(3)[6],=NH7EM(3)[6],=NH7FW(3)[6], - =NH7G(3)[6],=NH7IG(3)[6],=NH7IH(3)[6],=NH7PM(3)[6],=NH7QV(3)[6],=NH7RT(3)[6],=NH7ST(3)[6], - =NH7SU(3)[6],=NH7WE(3)[6],=NH7WG(3)[6],=NH7ZE(3)[6],=NL7GE(3)[6],=NL7IB(3)[6],=NL7OP(3)[6], - =NL7RO(3)[6],=NL7YB(3)[6],=NP2KY(3)[6],=NP4AI/6(3)[6],=NP4IW(3)[6],=NP4IW/6(3)[6],=NP4MV(3)[6], - =NP4XE(3)[6],=WH0AAZ(3)[6],=WH0M(3)[6],=WH2ABS(3)[6],=WH2ALN(3)[6],=WH6AAJ(3)[6],=WH6AFM(3)[6], - =WH6ANA(3)[6],=WH6ASW/M(3)[6],=WH6BYT(3)[6],=WH6CIL(3)[6],=WH6CK(3)[6],=WH6CO(3)[6],=WH6CPO(3)[6], - =WH6CPT(3)[6],=WH6CRE(3)[6],=WH6CSG(3)[6],=WH6CUF(3)[6],=WH6CUU(3)[6],=WH6CUX(3)[6],=WH6CVJ(3)[6], - =WH6CWS(3)[6],=WH6CZF(3)[6],=WH6CZH(3)[6],=WH6DHN(3)[6],=WH6DSK(3)[6],=WH6DVM(3)[6],=WH6DVN(3)[6], - =WH6DVX(3)[6],=WH6DYA(3)[6],=WH6DZV(3)[6],=WH6DZY(3)[6],=WH6EAR(3)[6],=WH6EEZ(3)[6],=WH6EHY(3)[6], - =WH6EKB(3)[6],=WH6ENG(3)[6],=WH6EUH(3)[6],=WH6EZW(3)[6],=WH6JO(3)[6],=WH6LZ(3)[6],=WH6OI(3)[6], - =WH6PX(3)[6],=WH6QA(3)[6],=WH6RF(3)[6],=WH6TD(3)[6],=WH6TK(3)[6],=WH6USA(3)[6],=WH6VM(3)[6], - =WH6VN(3)[6],=WH6XI(3)[6],=WH6XX(3)[6],=WH6YJ(3)[6],=WH7DG(3)[6],=WH7DH(3)[6],=WH7HQ(3)[6], - =WH7IN(3)[6],=WH7IV(3)[6],=WH7IZ(3)[6],=WH7LP(3)[6],=WH7OO(3)[6],=WH7PM(3)[6],=WH7QC(3)[6], - =WH7RU(3)[6],=WH7TT(3)[6],=WH7VM(3)[6],=WH7XR(3)[6],=WL3AF(3)[6],=WL3DZ(3)[6],=WL4JC(3)[6], - =WL7ACO(3)[6],=WL7BA(3)[6],=WL7BGF(3)[6],=WL7CPL(3)[6],=WL7CSD(3)[6],=WL7DN/6(3)[6],=WL7EA(3)[6], - =WL7EKK(3)[6],=WL7RA(3)[6],=WL7SE(3)[6],=WL7TG(3)[6],=WL7WL(3)[6],=WL7YQ(3)[6],=WL7YQ/6(3)[6], - =WP2N(3)[6],=WP4CUJ(3)[6],=WP4CW(3)[6],=WP4KSU(3)[6],=WP4MVE(3)[6], + =KL4GW(3)[6],=KL4LV(3)[6],=KL4NZ(3)[6],=KL4QW(3)[6],=KL4UZ(3)[6],=KL7AK(3)[6],=KL7CE/6(3)[6], + =KL7CM(3)[6],=KL7CN(3)[6],=KL7CW/6(3)[6],=KL7CX(3)[6],=KL7DJ(3)[6],=KL7EAE(3)[6],=KL7EAL(3)[6], + =KL7HQR(3)[6],=KL7HQR/6(3)[6],=KL7HSY(3)[6],=KL7ID(3)[6],=KL7IDY/6(3)[6],=KL7ISN(3)[6], + =KL7JBE(3)[6],=KL7KNP(3)[6],=KL7KX(3)[6],=KL7MF(3)[6],=KL7MF/6(3)[6],=KL7MF/M(3)[6],=KL7OO(3)[6], + =KL7RT(3)[6],=KL7SL(3)[6],=KL7SY(3)[6],=KL7VU(3)[6],=KL7VU/6(3)[6],=KP2BK(3)[6],=KP3BN(3)[6], + =KP3YL(3)[6],=KP4BR(3)[6],=KP4DSO(3)[6],=KP4DX/6(3)[6],=KP4ENM(3)[6],=KP4ERR(3)[6],=KP4FBT(3)[6], + =KP4MD(3)[6],=KP4UB(3)[6],=NH0C(3)[6],=NH0X(3)[6],=NH2AR(3)[6],=NH2BD(3)[6],=NH2BV(3)[6], + =NH2CM(3)[6],=NH2FT(3)[6],=NH2FX(3)[6],=NH2R(3)[6],=NH2S(3)[6],=NH6AC(3)[6],=NH6AE(3)[6], + =NH6AF(3)[6],=NH6FV(3)[6],=NH6FX(3)[6],=NH6NG(3)[6],=NH6RG(3)[6],=NH6ST(3)[6],=NH6WR(3)[6], + =NH7AG(3)[6],=NH7EM(3)[6],=NH7FW(3)[6],=NH7G(3)[6],=NH7IG(3)[6],=NH7IH(3)[6],=NH7PM(3)[6], + =NH7QV(3)[6],=NH7RT(3)[6],=NH7ST(3)[6],=NH7SU(3)[6],=NH7WE(3)[6],=NH7WG(3)[6],=NH7ZE(3)[6], + =NL7GE(3)[6],=NL7IB(3)[6],=NL7LC(3)[6],=NL7OP(3)[6],=NL7RO(3)[6],=NL7YB(3)[6],=NP2KY(3)[6], + =NP4AB(3)[6],=NP4AI/6(3)[6],=NP4IW(3)[6],=NP4IW/6(3)[6],=NP4MV(3)[6],=NP4XE(3)[6],=WH0AAZ(3)[6], + =WH0M(3)[6],=WH2ABS(3)[6],=WH2ALN(3)[6],=WH6AAJ(3)[6],=WH6AFM(3)[6],=WH6ANA(3)[6],=WH6ASW/M(3)[6], + =WH6BYT(3)[6],=WH6CIL(3)[6],=WH6CK(3)[6],=WH6CO(3)[6],=WH6CPO(3)[6],=WH6CPT(3)[6],=WH6CRE(3)[6], + =WH6CSG(3)[6],=WH6CUF(3)[6],=WH6CUU(3)[6],=WH6CUX(3)[6],=WH6CVJ(3)[6],=WH6CWS(3)[6],=WH6CZF(3)[6], + =WH6CZH(3)[6],=WH6DHN(3)[6],=WH6DSK(3)[6],=WH6DVM(3)[6],=WH6DVN(3)[6],=WH6DVX(3)[6],=WH6DYA(3)[6], + =WH6DZV(3)[6],=WH6DZY(3)[6],=WH6EAR(3)[6],=WH6EEZ(3)[6],=WH6EHY(3)[6],=WH6EKB(3)[6],=WH6ENG(3)[6], + =WH6EUH(3)[6],=WH6EZW(3)[6],=WH6JO(3)[6],=WH6LZ(3)[6],=WH6MC(3)[6],=WH6OI(3)[6],=WH6PX(3)[6], + =WH6QA(3)[6],=WH6RF(3)[6],=WH6TD(3)[6],=WH6TK(3)[6],=WH6USA(3)[6],=WH6VM(3)[6],=WH6VN(3)[6], + =WH6XI(3)[6],=WH6XX(3)[6],=WH6YJ(3)[6],=WH7DG(3)[6],=WH7DH(3)[6],=WH7HQ(3)[6],=WH7IN(3)[6], + =WH7IV(3)[6],=WH7IZ(3)[6],=WH7LP(3)[6],=WH7OO(3)[6],=WH7PM(3)[6],=WH7QC(3)[6],=WH7RU(3)[6], + =WH7TT(3)[6],=WH7VM(3)[6],=WH7XR(3)[6],=WL3AF(3)[6],=WL3DZ(3)[6],=WL4JC(3)[6],=WL7ACO(3)[6], + =WL7BA(3)[6],=WL7BGF(3)[6],=WL7CPL(3)[6],=WL7CSD(3)[6],=WL7DN/6(3)[6],=WL7EA(3)[6],=WL7EKK(3)[6], + =WL7RA(3)[6],=WL7SE(3)[6],=WL7TG(3)[6],=WL7WL(3)[6],=WL7YQ(3)[6],=WL7YQ/6(3)[6],=WP2N(3)[6], + =WP4CUJ(3)[6],=WP4CW(3)[6],=WP4KSU(3)[6],=WP4MVE(3)[6],=WP4OBB(3)[6], AA7(3)[6],AB7(3)[6],AC7(3)[6],AD7(3)[6],AE7(3)[6],AF7(3)[6],AG7(3)[6],AI7(3)[6],AJ7(3)[6], AK7(3)[6],K7(3)[6],KA7(3)[6],KB7(3)[6],KC7(3)[6],KD7(3)[6],KE7(3)[6],KF7(3)[6],KG7(3)[6], KI7(3)[6],KJ7(3)[6],KK7(3)[6],KM7(3)[6],KN7(3)[6],KO7(3)[6],KQ7(3)[6],KR7(3)[6],KS7(3)[6], @@ -1437,61 +1447,62 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K: =AL7D/7(3)[6],=AL7D/P(3)[6],=AL7D/R(3)[6],=AL7DD(3)[6],=AL7DU(3)[6],=AL7EI(3)[6],=AL7EJ(3)[6], =AL7FA(3)[6],=AL7FB(3)[6],=AL7HS(3)[6],=AL7HY(3)[6],=AL7IG(3)[6],=AL7IT(3)[6],=AL7JF(3)[6], =AL7JJ(3)[6],=AL7JS(3)[6],=AL7JW(3)[6],=AL7JY(3)[6],=AL7KE(3)[6],=AL7KF(3)[6],=AL7KG(3)[6], - =AL7KK(3)[6],=AL7KL(3)[6],=AL7KV(3)[6],=AL7L/7(3)[6],=AL7LL(3)[6],=AL7MH(3)[6],=AL7MQ(3)[6], - =AL7ND(3)[6],=AL7NK(3)[6],=AL7NZ(3)[6],=AL7OK(3)[6],=AL7OW(3)[6],=AL7PR(3)[6],=AL7PV(3)[6], - =AL7QL(3)[6],=AL7R(3)[6],=AL7R/7(3)[6],=AL7RF(3)[6],=AL7RF/7(3)[6],=AL7RM(3)[6],=AL7RR(3)[6], - =AL7W(3)[6],=G4KHG/M(3)[6],=KH0AS(3)[6],=KH0H(3)[6],=KH0K(3)[6],=KH0SH(3)[6],=KH0TL(3)[6], - =KH0X(3)[6],=KH2CH(3)[6],=KH2G(3)[6],=KH2GG(3)[6],=KH2JA(3)[6],=KH2QH(3)[6],=KH2RK(3)[6], - =KH2SK(3)[6],=KH2SR(3)[6],=KH2TJ/7(3)[6],=KH2TJ/P(3)[6],=KH2XP(3)[6],=KH2YL(3)[6],=KH3AD(3)[6], - =KH6AB(3)[6],=KH6AHQ(3)[6],=KH6BXZ(3)[6],=KH6CN(3)[6],=KH6CN/7(3)[6],=KH6COY(3)[6],=KH6CQG(3)[6], - =KH6CQH(3)[6],=KH6CQH/7(3)[6],=KH6DB(3)[6],=KH6DE(3)[6],=KH6DOT(3)[6],=KH6DUT(3)[6],=KH6EE(3)[6], - =KH6EE/7(3)[6],=KH6FKA/7(3)[6],=KH6FU(3)[6],=KH6GB(3)[6],=KH6GDN(3)[6],=KH6HU(3)[6],=KH6HWK(3)[6], - =KH6IA(3)[6],=KH6ICQ(3)[6],=KH6IKC(3)[6],=KH6IMN(3)[6],=KH6IQX(3)[6],=KH6ITY(3)[6],=KH6JFL(3)[6], - =KH6JIM/7(3)[6],=KH6JJS(3)[6],=KH6JPJ(3)[6],=KH6JPO(3)[6],=KH6JRW(3)[6],=KH6JT(3)[6], - =KH6JUQ(3)[6],=KH6KS(3)[6],=KH6KW(3)[6],=KH6LEM(3)[6],=KH6ME(3)[6],=KH6MF(3)[6],=KH6NA(3)[6], - =KH6NO/7(3)[6],=KH6NO/M(3)[6],=KH6NU(3)[6],=KH6OV(3)[6],=KH6PG(3)[6],=KH6PR(3)[6],=KH6QAI(3)[6], - =KH6QAI/7(3)[6],=KH6QAJ(3)[6],=KH6RW(3)[6],=KH6RY(3)[6],=KH6SAT(3)[6],=KH6SS(3)[6],=KH6TG(3)[6], - =KH6TX(3)[6],=KH6VM(3)[6],=KH6VM/7(3)[6],=KH6VT(3)[6],=KH6WX(3)[6],=KH6XG(3)[6],=KH6XS(3)[6], - =KH6XT(3)[6],=KH6YL(3)[6],=KH7AL(3)[6],=KH7AR(3)[6],=KH7AX(3)[6],=KH7CB(3)[6],=KH7CM(3)[6], - =KH7CZ(3)[6],=KH7FJ(3)[6],=KH7FR(3)[6],=KH7HH(3)[6],=KH7HWK(3)[6],=KH7IP(3)[6],=KH7LE(3)[6], - =KH7ME(3)[6],=KH7MR(3)[6],=KH7NP(3)[6],=KH7R(3)[6],=KH7RD(3)[6],=KH7RT(3)[6],=KH7SQ(3)[6], - =KH7SR(3)[6],=KH7WW(3)[6],=KH7WW/7(3)[6],=KH7X/7(3)[6],=KH7YD(3)[6],=KH7YD/7(3)[6],=KH8AB(3)[6], - =KH8AH(3)[6],=KH8AZ(3)[6],=KH8BG(3)[6],=KH8D(3)[6],=KH8E(3)[6],=KH8K(3)[6],=KH9AA(3)[6], - =KL0AI(3)[6],=KL0AN(3)[6],=KL0AP(3)[6],=KL0CA(3)[6],=KL0CM(3)[6],=KL0CW(3)[6],=KL0DF(3)[6], - =KL0DG(3)[6],=KL0DR(3)[6],=KL0DT(3)[6],=KL0IR(3)[6],=KL0IS(3)[6],=KL0IW(3)[6],=KL0IX(3)[6], - =KL0LF(3)[6],=KL0MO(3)[6],=KL0NM(3)[6],=KL0NP(3)[6],=KL0PP(3)[6],=KL0QD(3)[6],=KL0RA(3)[6], - =KL0SZ(3)[6],=KL0TR(3)[6],=KL0TU(3)[6],=KL1AA(3)[6],=KL1AE(3)[6],=KL1DO(3)[6],=KL1DW(3)[6], - =KL1ED(3)[6],=KL1JF(3)[6],=KL1K(3)[6],=KL1LE(3)[6],=KL1LZ(3)[6],=KL1MF(3)[6],=KL1OH(3)[6], - =KL1QL(3)[6],=KL1RH(3)[6],=KL1RV(3)[6],=KL1SF/7(3)[6],=KL1SO(3)[6],=KL1U(3)[6],=KL1UA(3)[6], - =KL1UM(3)[6],=KL1XI(3)[6],=KL1YO(3)[6],=KL1YY/7(3)[6],=KL1ZP(3)[6],=KL1ZR(3)[6],=KL2A/7(3)[6], - =KL2BG(3)[6],=KL2BO(3)[6],=KL2BW(3)[6],=KL2BY(3)[6],=KL2BZ(3)[6],=KL2FD(3)[6],=KL2FL(3)[6], - =KL2JY(3)[6],=KL2K(3)[6],=KL2KY(3)[6],=KL2LA(3)[6],=KL2LN(3)[6],=KL2LT(3)[6],=KL2MP(3)[6], - =KL2NJ(3)[6],=KL2NU(3)[6],=KL2NW(3)[6],=KL2OH(3)[6],=KL2OJ(3)[6],=KL2P(3)[6],=KL2QE(3)[6], - =KL2VK(3)[6],=KL2YH(3)[6],=KL3EZ(3)[6],=KL3FE(3)[6],=KL3IC(3)[6],=KL3IO(3)[6],=KL3IW(3)[6], - =KL3MZ(3)[6],=KL3NE(3)[6],=KL3NO(3)[6],=KL3OQ(3)[6],=KL3PD(3)[6],=KL3TW(3)[6],=KL3TY(3)[6], - =KL3VJ(3)[6],=KL3XS(3)[6],=KL4BS(3)[6],=KL4E(3)[6],=KL4RKH(3)[6],=KL4YFD(3)[6],=KL7AB(3)[6], - =KL7AD(3)[6],=KL7AW(3)[6],=KL7BD(3)[6],=KL7BDC(3)[6],=KL7BH(3)[6],=KL7BR(3)[6],=KL7BS(3)[6], - =KL7BT(3)[6],=KL7BUR(3)[6],=KL7BXP(3)[6],=KL7C(3)[6],=KL7CPO(3)[6],=KL7CT(3)[6],=KL7CY(3)[6], - =KL7DC(3)[6],=KL7DF(3)[6],=KL7DI(3)[6],=KL7DK(3)[6],=KL7DLG(3)[6],=KL7EF(3)[6],=KL7EFL(3)[6], - =KL7EH(3)[6],=KL7EIN(3)[6],=KL7EU(3)[6],=KL7FDQ(3)[6],=KL7FDQ/7(3)[6],=KL7FOZ(3)[6],=KL7FRQ(3)[6], - =KL7FS(3)[6],=KL7GA(3)[6],=KL7GCS(3)[6],=KL7GKY(3)[6],=KL7GRF(3)[6],=KL7GT(3)[6],=KL7HB(3)[6], - =KL7HBV(3)[6],=KL7HFI/7(3)[6],=KL7HFV(3)[6],=KL7HI(3)[6],=KL7HJR(3)[6],=KL7HLF(3)[6],=KL7HM(3)[6], - =KL7HMK(3)[6],=KL7HQL(3)[6],=KL7HSR(3)[6],=KL7IAL(3)[6],=KL7IBT(3)[6],=KL7IDY(3)[6],=KL7IEI(3)[6], - =KL7IFK(3)[6],=KL7IGB(3)[6],=KL7IHK(3)[6],=KL7IIK(3)[6],=KL7IKV(3)[6],=KL7IL(3)[6],=KL7IME(3)[6], - =KL7IPV(3)[6],=KL7ISE(3)[6],=KL7IUX(3)[6],=KL7IWC/7(3)[6],=KL7IZC(3)[6],=KL7IZH(3)[6], - =KL7JBB(3)[6],=KL7JDQ(3)[6],=KL7JES(3)[6],=KL7JIJ(3)[6],=KL7JJE(3)[6],=KL7JKV(3)[6],=KL7KA(3)[6], - =KL7KG/7(3)[6],=KL7LG(3)[6],=KL7LI(3)[6],=KL7LX(3)[6],=KL7LZ(3)[6],=KL7M(3)[6],=KL7MY(3)[6], - =KL7MZ(3)[6],=KL7NA(3)[6],=KL7NP(3)[6],=KL7NP/7(3)[6],=KL7OA(3)[6],=KL7OF(3)[6],=KL7OL(3)[6], - =KL7OR(3)[6],=KL7OR/7(3)[6],=KL7OS(3)[6],=KL7OY(3)[6],=KL7PO(3)[6],=KL7QA(3)[6],=KL7QK(3)[6], - =KL7QK/140(3)[6],=KL7QK/7(3)[6],=KL7QR(3)[6],=KL7QR/7(3)[6],=KL7R(3)[6],=KL7RC(3)[6],=KL7RK(3)[6], - =KL7RM(3)[6],=KL7RS(3)[6],=KL7S(3)[6],=KL7SK(3)[6],=KL7SP(3)[6],=KL7T(3)[6],=KL7TU(3)[6], - =KL7UP(3)[6],=KL7UT(3)[6],=KL7VK(3)[6],=KL7VL(3)[6],=KL7VN(3)[6],=KL7VQ(3)[6],=KL7W(3)[6], - =KL7WM(3)[6],=KL7WN(3)[6],=KL7WP(3)[6],=KL7WP/7(3)[6],=KL7WT(3)[6],=KL7YJ(3)[6],=KL7YQ(3)[6], - =KL7YY/M(3)[6],=KL7ZH(3)[6],=KL7ZW(3)[6],=KL8RV(3)[6],=KL8SU(3)[6],=KL9PC(3)[6],=KP2BX(3)[6], - =KP2CB(3)[6],=KP2CT(3)[6],=KP2X(3)[6],=KP2Y(3)[6],=KP4BBN(3)[6],=KP4EFZ(3)[6],=KP4ND(3)[6], - =KP4UZ(3)[6],=KP4X(3)[6],=NH0F(3)[6],=NH0K(3)[6],=NH2DM(3)[6],=NH2JE(3)[6],=NH2KR(3)[6], - =NH6B(3)[6],=NH6BF(3)[6],=NH6CI(3)[6],=NH6DQ(3)[6],=NH6DX(3)[6],=NH6FF(3)[6],=NH6GZ(3)[6], - =NH6HE(3)[6],=NH6HZ(3)[6],=NH6LM(3)[6],=NH6NS(3)[6],=NH6U(3)[6],=NH6XN(3)[6],=NH6XP(3)[6], + =AL7KK(3)[6],=AL7KL(3)[6],=AL7KV(3)[6],=AL7L/7(3)[6],=AL7LI(3)[6],=AL7LL(3)[6],=AL7MH(3)[6], + =AL7MQ(3)[6],=AL7ND(3)[6],=AL7NK(3)[6],=AL7NZ(3)[6],=AL7OK(3)[6],=AL7OW(3)[6],=AL7PR(3)[6], + =AL7PV(3)[6],=AL7QL(3)[6],=AL7R(3)[6],=AL7R/7(3)[6],=AL7RF(3)[6],=AL7RF/7(3)[6],=AL7RM(3)[6], + =AL7RR(3)[6],=AL7W(3)[6],=G4KHG/M(3)[6],=KH0AS(3)[6],=KH0H(3)[6],=KH0K(3)[6],=KH0SH(3)[6], + =KH0TL(3)[6],=KH0X(3)[6],=KH2CH(3)[6],=KH2G(3)[6],=KH2GG(3)[6],=KH2JA(3)[6],=KH2QH(3)[6], + =KH2RK(3)[6],=KH2SK(3)[6],=KH2SR(3)[6],=KH2TJ/7(3)[6],=KH2TJ/P(3)[6],=KH2XP(3)[6],=KH2YL(3)[6], + =KH3AD(3)[6],=KH6AB(3)[6],=KH6AHQ(3)[6],=KH6BXZ(3)[6],=KH6CN(3)[6],=KH6CN/7(3)[6],=KH6COY(3)[6], + =KH6CQG(3)[6],=KH6CQH(3)[6],=KH6CQH/7(3)[6],=KH6DB(3)[6],=KH6DE(3)[6],=KH6DOT(3)[6],=KH6DUT(3)[6], + =KH6EE(3)[6],=KH6EE/7(3)[6],=KH6FKA/7(3)[6],=KH6FU(3)[6],=KH6GB(3)[6],=KH6GDN(3)[6],=KH6HU(3)[6], + =KH6HWK(3)[6],=KH6IA(3)[6],=KH6ICQ(3)[6],=KH6IKC(3)[6],=KH6IMN(3)[6],=KH6IQX(3)[6],=KH6ITY(3)[6], + =KH6JFL(3)[6],=KH6JIM/7(3)[6],=KH6JJS(3)[6],=KH6JPJ(3)[6],=KH6JPO(3)[6],=KH6JRW(3)[6], + =KH6JT(3)[6],=KH6JUQ(3)[6],=KH6KS(3)[6],=KH6KW(3)[6],=KH6LEM(3)[6],=KH6ME(3)[6],=KH6MF(3)[6], + =KH6NA(3)[6],=KH6NO/7(3)[6],=KH6NO/M(3)[6],=KH6NU(3)[6],=KH6OV(3)[6],=KH6PG(3)[6],=KH6PR(3)[6], + =KH6QAI(3)[6],=KH6QAI/7(3)[6],=KH6QAJ(3)[6],=KH6RW(3)[6],=KH6RY(3)[6],=KH6SAT(3)[6],=KH6SS(3)[6], + =KH6TG(3)[6],=KH6TX(3)[6],=KH6VM(3)[6],=KH6VM/7(3)[6],=KH6VT(3)[6],=KH6WX(3)[6],=KH6XG(3)[6], + =KH6XS(3)[6],=KH6XT(3)[6],=KH6YL(3)[6],=KH7AL(3)[6],=KH7AR(3)[6],=KH7AX(3)[6],=KH7CB(3)[6], + =KH7CM(3)[6],=KH7CZ(3)[6],=KH7FJ(3)[6],=KH7FR(3)[6],=KH7HH(3)[6],=KH7HWK(3)[6],=KH7IP(3)[6], + =KH7LE(3)[6],=KH7ME(3)[6],=KH7MR(3)[6],=KH7NP(3)[6],=KH7R(3)[6],=KH7RD(3)[6],=KH7RT(3)[6], + =KH7SQ(3)[6],=KH7SR(3)[6],=KH7WW(3)[6],=KH7WW/7(3)[6],=KH7X/7(3)[6],=KH7YD(3)[6],=KH7YD/7(3)[6], + =KH8AB(3)[6],=KH8AH(3)[6],=KH8AZ(3)[6],=KH8BG(3)[6],=KH8D(3)[6],=KH8E(3)[6],=KH8K(3)[6], + =KH9AA(3)[6],=KL0AI(3)[6],=KL0AN(3)[6],=KL0AP(3)[6],=KL0CA(3)[6],=KL0CM(3)[6],=KL0CW(3)[6], + =KL0DF(3)[6],=KL0DG(3)[6],=KL0DR(3)[6],=KL0DT(3)[6],=KL0EU(3)[6],=KL0IR(3)[6],=KL0IS(3)[6], + =KL0IW(3)[6],=KL0IX(3)[6],=KL0LF(3)[6],=KL0MO(3)[6],=KL0NM(3)[6],=KL0NP(3)[6],=KL0PP(3)[6], + =KL0QD(3)[6],=KL0RA(3)[6],=KL0SZ(3)[6],=KL0TR(3)[6],=KL0TU(3)[6],=KL1AA(3)[6],=KL1AE(3)[6], + =KL1DO(3)[6],=KL1DW(3)[6],=KL1ED(3)[6],=KL1JF(3)[6],=KL1K(3)[6],=KL1LE(3)[6],=KL1LZ(3)[6], + =KL1MF(3)[6],=KL1OH(3)[6],=KL1QL(3)[6],=KL1RH(3)[6],=KL1RV(3)[6],=KL1SF/7(3)[6],=KL1SO(3)[6], + =KL1U(3)[6],=KL1UA(3)[6],=KL1UM(3)[6],=KL1XI(3)[6],=KL1YO(3)[6],=KL1YY/7(3)[6],=KL1ZN(3)[6], + =KL1ZP(3)[6],=KL1ZR(3)[6],=KL2A/7(3)[6],=KL2BG(3)[6],=KL2BO(3)[6],=KL2BW(3)[6],=KL2BY(3)[6], + =KL2BZ(3)[6],=KL2FD(3)[6],=KL2FL(3)[6],=KL2JY(3)[6],=KL2K(3)[6],=KL2KY(3)[6],=KL2LA(3)[6], + =KL2LN(3)[6],=KL2LT(3)[6],=KL2MA(3)[6],=KL2MP(3)[6],=KL2NJ(3)[6],=KL2NU(3)[6],=KL2NW(3)[6], + =KL2OH(3)[6],=KL2OJ(3)[6],=KL2P(3)[6],=KL2QE(3)[6],=KL2VK(3)[6],=KL2YH(3)[6],=KL3EZ(3)[6], + =KL3FE(3)[6],=KL3IC(3)[6],=KL3IO(3)[6],=KL3IW(3)[6],=KL3MZ(3)[6],=KL3NE(3)[6],=KL3NO(3)[6], + =KL3OQ(3)[6],=KL3PD(3)[6],=KL3TW(3)[6],=KL3TY(3)[6],=KL3VJ(3)[6],=KL3XS(3)[6],=KL4BS(3)[6], + =KL4E(3)[6],=KL4RKH(3)[6],=KL4YFD(3)[6],=KL7AB(3)[6],=KL7AD(3)[6],=KL7AW(3)[6],=KL7BD(3)[6], + =KL7BDC(3)[6],=KL7BH(3)[6],=KL7BR(3)[6],=KL7BS(3)[6],=KL7BT(3)[6],=KL7BUR(3)[6],=KL7BXP(3)[6], + =KL7C(3)[6],=KL7CPO(3)[6],=KL7CT(3)[6],=KL7CY(3)[6],=KL7DC(3)[6],=KL7DF(3)[6],=KL7DI(3)[6], + =KL7DK(3)[6],=KL7DLG(3)[6],=KL7EF(3)[6],=KL7EFL(3)[6],=KL7EH(3)[6],=KL7EIN(3)[6],=KL7EU(3)[6], + =KL7FDQ(3)[6],=KL7FDQ/7(3)[6],=KL7FOZ(3)[6],=KL7FRQ(3)[6],=KL7FS(3)[6],=KL7GA(3)[6],=KL7GCS(3)[6], + =KL7GKY(3)[6],=KL7GRF(3)[6],=KL7GT(3)[6],=KL7HB(3)[6],=KL7HBV(3)[6],=KL7HFI/7(3)[6],=KL7HFV(3)[6], + =KL7HI(3)[6],=KL7HJR(3)[6],=KL7HLF(3)[6],=KL7HM(3)[6],=KL7HMK(3)[6],=KL7HQL(3)[6],=KL7HSR(3)[6], + =KL7IAL(3)[6],=KL7IBT(3)[6],=KL7IDY(3)[6],=KL7IEI(3)[6],=KL7IFK(3)[6],=KL7IGB(3)[6],=KL7IHK(3)[6], + =KL7IIK(3)[6],=KL7IKV(3)[6],=KL7IL(3)[6],=KL7IME(3)[6],=KL7IOW(3)[6],=KL7IPV(3)[6],=KL7ISE(3)[6], + =KL7IUX(3)[6],=KL7IWC/7(3)[6],=KL7IZC(3)[6],=KL7IZH(3)[6],=KL7JBB(3)[6],=KL7JDQ(3)[6], + =KL7JES(3)[6],=KL7JIJ(3)[6],=KL7JJE(3)[6],=KL7JKV(3)[6],=KL7KA(3)[6],=KL7KG/7(3)[6],=KL7LG(3)[6], + =KL7LI(3)[6],=KL7LX(3)[6],=KL7LZ(3)[6],=KL7M(3)[6],=KL7MY(3)[6],=KL7MZ(3)[6],=KL7NA(3)[6], + =KL7NP(3)[6],=KL7NP/7(3)[6],=KL7OA(3)[6],=KL7OF(3)[6],=KL7OL(3)[6],=KL7OR(3)[6],=KL7OR/7(3)[6], + =KL7OS(3)[6],=KL7OY(3)[6],=KL7PO(3)[6],=KL7QA(3)[6],=KL7QK(3)[6],=KL7QK/140(3)[6],=KL7QK/7(3)[6], + =KL7QR(3)[6],=KL7QR/7(3)[6],=KL7R(3)[6],=KL7RC(3)[6],=KL7RK(3)[6],=KL7RM(3)[6],=KL7RS(3)[6], + =KL7S(3)[6],=KL7SK(3)[6],=KL7SP(3)[6],=KL7T(3)[6],=KL7TU(3)[6],=KL7UP(3)[6],=KL7UT(3)[6], + =KL7VK(3)[6],=KL7VL(3)[6],=KL7VN(3)[6],=KL7VQ(3)[6],=KL7W(3)[6],=KL7WC(3)[6],=KL7WM(3)[6], + =KL7WN(3)[6],=KL7WP(3)[6],=KL7WP/7(3)[6],=KL7WT(3)[6],=KL7YJ(3)[6],=KL7YQ(3)[6],=KL7YY/M(3)[6], + =KL7ZH(3)[6],=KL7ZW(3)[6],=KL8RV(3)[6],=KL8SU(3)[6],=KL9PC(3)[6],=KP2BX(3)[6],=KP2CB(3)[6], + =KP2CT(3)[6],=KP2X(3)[6],=KP2Y(3)[6],=KP4EFZ(3)[6],=KP4ND(3)[6],=KP4UZ(3)[6],=KP4X(3)[6], + =NH0F(3)[6],=NH0K(3)[6],=NH0O(3)[6],=NH2DM(3)[6],=NH2JE(3)[6],=NH2KR(3)[6],=NH6B(3)[6], + =NH6BF(3)[6],=NH6CI(3)[6],=NH6DQ(3)[6],=NH6DX(3)[6],=NH6FF(3)[6],=NH6GZ(3)[6],=NH6HE(3)[6], + =NH6HZ(3)[6],=NH6LF(3)[6],=NH6LM(3)[6],=NH6NS(3)[6],=NH6U(3)[6],=NH6XN(3)[6],=NH6XP(3)[6], =NH6Z(3)[6],=NH6ZA(3)[6],=NH6ZE(3)[6],=NH7FZ(3)[6],=NH7L(3)[6],=NH7M(3)[6],=NH7MY(3)[6], =NH7N(3)[6],=NH7ND(3)[6],=NH7NJ/7(3)[6],=NH7OC(3)[6],=NH7PL(3)[6],=NH7RS(3)[6],=NH7S(3)[6], =NH7SH(3)[6],=NH7TG(3)[6],=NH7VZ(3)[6],=NH7W(3)[6],=NH7WT(3)[6],=NH7WU(3)[6],=NH7YE(3)[6], @@ -1509,19 +1520,19 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K: =WH6EEC(3)[6],=WH6EEG(3)[6],=WH6EGM(3)[6],=WH6EHW(3)[6],=WH6EJV(3)[6],=WH6EQB(3)[6],=WH6ESS(3)[6], =WH6ETO(3)[6],=WH6EWE(3)[6],=WH6FCT(3)[6],=WH6FEU(3)[6],=WH6FL(3)[6],=WH6FOJ(3)[6],=WH6OL(3)[6], =WH6OY(3)[6],=WH6QV(3)[6],=WH6SD(3)[6],=WH6SR(3)[6],=WH6TI(3)[6],=WH6U(3)[6],=WH6XV(3)[6], - =WH6YT(3)[6],=WH6ZV(3)[6],=WH7A(3)[6],=WH7CY(3)[6],=WH7DB(3)[6],=WH7DE(3)[6],=WH7G(3)[6], - =WH7GC(3)[6],=WH7GY(3)[6],=WH7HU(3)[6],=WH7LB(3)[6],=WH7NS(3)[6],=WH7P(3)[6],=WH7RG(3)[6], - =WH7TC(3)[6],=WH7UP(3)[6],=WH7WP(3)[6],=WH7WT(3)[6],=WH7XP(3)[6],=WL7AAW(3)[6],=WL7AL(3)[6], - =WL7AP(3)[6],=WL7AUY(3)[6],=WL7AZG(3)[6],=WL7AZL(3)[6],=WL7BCR(3)[6],=WL7BHR(3)[6],=WL7BLM(3)[6], - =WL7BM(3)[6],=WL7BNQ(3)[6],=WL7BON(3)[6],=WL7BOO(3)[6],=WL7BSW(3)[6],=WL7BUI(3)[6],=WL7BVN(3)[6], - =WL7BVS(3)[6],=WL7CAZ(3)[6],=WL7CBF(3)[6],=WL7CES(3)[6],=WL7COQ(3)[6],=WL7CPE(3)[6],=WL7CPI(3)[6], - =WL7CQX(3)[6],=WL7CRJ(3)[6],=WL7CSL(3)[6],=WL7CTB(3)[6],=WL7CTC(3)[6],=WL7CTE(3)[6],=WL7DD(3)[6], - =WL7FA(3)[6],=WL7FU(3)[6],=WL7H(3)[6],=WL7HE(3)[6],=WL7HK(3)[6],=WL7HL(3)[6],=WL7IQ(3)[6], - =WL7IS(3)[6],=WL7JM(3)[6],=WL7K(3)[6],=WL7K/7(3)[6],=WL7K/M(3)[6],=WL7LB(3)[6],=WL7LK(3)[6], - =WL7OA(3)[6],=WL7P(3)[6],=WL7PJ(3)[6],=WL7QC(3)[6],=WL7QX(3)[6],=WL7RV/140(3)[6],=WL7SD(3)[6], - =WL7SO(3)[6],=WL7SV(3)[6],=WL7T(3)[6],=WL7VK(3)[6],=WL7WB(3)[6],=WL7WF(3)[6],=WL7WG(3)[6], - =WL7WU(3)[6],=WL7XE(3)[6],=WL7XJ(3)[6],=WL7XN(3)[6],=WL7XW(3)[6],=WL7Z(3)[6],=WL7ZM(3)[6], - =WP2ADG(3)[6],=WP4BZG(3)[6],=WP4DYP(3)[6],=WP4NBP(3)[6], + =WH6YT(3)[6],=WH6ZR(3)[6],=WH6ZV(3)[6],=WH7A(3)[6],=WH7CY(3)[6],=WH7DB(3)[6],=WH7DE(3)[6], + =WH7G(3)[6],=WH7GC(3)[6],=WH7GY(3)[6],=WH7HU(3)[6],=WH7LB(3)[6],=WH7NS(3)[6],=WH7P(3)[6], + =WH7RG(3)[6],=WH7TC(3)[6],=WH7U(3)[6],=WH7UP(3)[6],=WH7WP(3)[6],=WH7WT(3)[6],=WH7XP(3)[6], + =WL7AAW(3)[6],=WL7AL(3)[6],=WL7AP(3)[6],=WL7AUY(3)[6],=WL7AZG(3)[6],=WL7AZL(3)[6],=WL7BCR(3)[6], + =WL7BHR(3)[6],=WL7BLM(3)[6],=WL7BM(3)[6],=WL7BNQ(3)[6],=WL7BON(3)[6],=WL7BOO(3)[6],=WL7BSW(3)[6], + =WL7BUI(3)[6],=WL7BVN(3)[6],=WL7BVS(3)[6],=WL7CAZ(3)[6],=WL7CBF(3)[6],=WL7CES(3)[6],=WL7COQ(3)[6], + =WL7CPE(3)[6],=WL7CPI(3)[6],=WL7CQX(3)[6],=WL7CRJ(3)[6],=WL7CSL(3)[6],=WL7CTB(3)[6],=WL7CTC(3)[6], + =WL7CTE(3)[6],=WL7DD(3)[6],=WL7FA(3)[6],=WL7FR(3)[6],=WL7FU(3)[6],=WL7H(3)[6],=WL7HE(3)[6], + =WL7HK(3)[6],=WL7HL(3)[6],=WL7IQ(3)[6],=WL7IS(3)[6],=WL7JM(3)[6],=WL7K(3)[6],=WL7K/7(3)[6], + =WL7K/M(3)[6],=WL7LB(3)[6],=WL7LK(3)[6],=WL7OA(3)[6],=WL7P(3)[6],=WL7PJ(3)[6],=WL7QC(3)[6], + =WL7QX(3)[6],=WL7RV/140(3)[6],=WL7SD(3)[6],=WL7SO(3)[6],=WL7SV(3)[6],=WL7T(3)[6],=WL7VK(3)[6], + =WL7WB(3)[6],=WL7WF(3)[6],=WL7WG(3)[6],=WL7WU(3)[6],=WL7XE(3)[6],=WL7XJ(3)[6],=WL7XN(3)[6], + =WL7XW(3)[6],=WL7Z(3)[6],=WL7ZM(3)[6],=WP2ADG(3)[6],=WP4BZG(3)[6],=WP4DYP(3)[6],=WP4NBP(3)[6], AA8(4)[8],AB8(4)[8],AC8(4)[8],AD8(4)[8],AE8(4)[8],AF8(4)[8],AG8(4)[8],AI8(4)[8],AJ8(4)[8], AK8(4)[8],K8(4)[8],KA8(4)[8],KB8(4)[8],KC8(4)[8],KD8(4)[8],KE8(4)[8],KF8(4)[8],KG8(4)[8], KI8(4)[8],KJ8(4)[8],KK8(4)[8],KM8(4)[8],KN8(4)[8],KO8(4)[8],KQ8(4)[8],KR8(4)[8],KS8(4)[8], @@ -1553,17 +1564,17 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K: WQ9(4)[8],WR9(4)[8],WS9(4)[8],WT9(4)[8],WU9(4)[8],WV9(4)[8],WW9(4)[8],WX9(4)[8],WY9(4)[8], WZ9(4)[8],=AH0AJ(4)[8],=AH6DA(4)[8],=AH6EZ/9(4)[8],=AH6OM(4)[8],=AL1CE(4)[8],=AL7AK(4)[8], =AL7AK/9(4)[8],=AL7BT(4)[8],=AL7CV(4)[8],=AL7DS(4)[8],=AL7II/9(4)[8],=AL7OL(4)[8],=AL7PM(4)[8], - =KH0BE(4)[8],=KH6JNY(4)[8],=KH6KI(4)[8],=KH6UX(4)[8],=KH7DR(4)[8],=KH7EI(4)[8],=KL0LB(4)[8], - =KL0NY(4)[8],=KL1NO(4)[8],=KL1QN(4)[8],=KL2A/9(4)[8],=KL2KP(4)[8],=KL2NQ(4)[8],=KL2YD(4)[8], - =KL2ZL(4)[8],=KL4CX(4)[8],=KL7AL(4)[8],=KL7AL/9(4)[8],=KL7BGR(4)[8],=KL7CE(4)[8],=KL7CE/9(4)[8], - =KL7IBV(4)[8],=KL7IPS(4)[8],=KL7IVK(4)[8],=KL7JAB(4)[8],=KL7MU(4)[8],=KL7TD(4)[8],=KP3JOS(4)[8], - =KP3VA/M(4)[8],=KP4CI(4)[8],=KP4GE/9(4)[8],=KP4SL(4)[8],=KP4WG(4)[8],=NH2W(4)[8],=NH2W/9(4)[8], - =NH6R(4)[8],=NH7TK(4)[8],=NL7CM(4)[8],=NL7KD(4)[8],=NL7NK(4)[8],=NL7QC(4)[8],=NL7QC/9(4)[8], - =NL7RC(4)[8],=NL7UH(4)[8],=NL7YI(4)[8],=NP2AV(4)[8],=NP2GM(4)[8],=NP2L/9(4)[8],=NP2MU(4)[8], - =NP3QC(4)[8],=NP4ZI(4)[8],=WH0AI(4)[8],=WH2T(4)[8],=WH6FBA(4)[8],=WH6SB(4)[8],=WL7AHP(4)[8], - =WL7AIT(4)[8],=WL7BEV(4)[8],=WL7CTA(4)[8],=WL7FJ(4)[8],=WL7JAN(4)[8],=WL7NP(4)[8],=WL7UU(4)[8], - =WP2B(4)[8],=WP4JSP(4)[8],=WP4KGF(4)[8],=WP4LKY(4)[8],=WP4LSQ(4)[8],=WP4MQX(4)[8],=WP4MSD(4)[8], - =WP4MTN(4)[8],=WP4MVQ(4)[8],=WP4MYL(4)[8],=WP4OCZ(4)[8], + =KH0BE(4)[8],=KH2RP(4)[8],=KH6JNY(4)[8],=KH6KI(4)[8],=KH6UX(4)[8],=KH7DR(4)[8],=KH7EI(4)[8], + =KL0LB(4)[8],=KL0NY(4)[8],=KL1NO(4)[8],=KL1QN(4)[8],=KL2A/9(4)[8],=KL2KP(4)[8],=KL2NQ(4)[8], + =KL2YD(4)[8],=KL2ZL(4)[8],=KL4CX(4)[8],=KL7AL(4)[8],=KL7AL/9(4)[8],=KL7BGR(4)[8],=KL7CE(4)[8], + =KL7CE/9(4)[8],=KL7IBV(4)[8],=KL7IPS(4)[8],=KL7IVK(4)[8],=KL7JAB(4)[8],=KL7MU(4)[8],=KL7TD(4)[8], + =KP2XX(4)[8],=KP3JOS(4)[8],=KP3VA/M(4)[8],=KP4CI(4)[8],=KP4GE/9(4)[8],=KP4SL(4)[8],=KP4WG(4)[8], + =NH2W(4)[8],=NH2W/9(4)[8],=NH6R(4)[8],=NH7TK(4)[8],=NL7CM(4)[8],=NL7KD(4)[8],=NL7NK(4)[8], + =NL7QC(4)[8],=NL7QC/9(4)[8],=NL7RC(4)[8],=NL7UH(4)[8],=NL7YI(4)[8],=NP2AV(4)[8],=NP2GM(4)[8], + =NP2L/9(4)[8],=NP2MU(4)[8],=NP3QC(4)[8],=NP4ZI(4)[8],=WH0AI(4)[8],=WH2T(4)[8],=WH6ERQ(4)[8], + =WH6FBA(4)[8],=WH6SB(4)[8],=WL7AHP(4)[8],=WL7AIT(4)[8],=WL7BEV(4)[8],=WL7CTA(4)[8],=WL7FJ(4)[8], + =WL7JAN(4)[8],=WL7NP(4)[8],=WL7UU(4)[8],=WP2B(4)[8],=WP4JSP(4)[8],=WP4KGF(4)[8],=WP4LKY(4)[8], + =WP4LSQ(4)[8],=WP4MQX(4)[8],=WP4MSD(4)[8],=WP4MTN(4)[8],=WP4MVQ(4)[8],=WP4MYL(4)[8],=WP4OCZ(4)[8], =AH2BG(4)[8],=AH6ES(4)[8],=AH6FF(4)[8],=AH6HR(4)[8],=AH6HR/4(4)[8],=AH6KB(4)[8],=AL0P(4)[8], =AL2C(4)[8],=AL2F(4)[8],=AL2F/4(4)[8],=AL4B(4)[8],=AL7CX(4)[8],=AL7EU(4)[8],=AL7KN(4)[8], =AL7MR(4)[8],=AL7QO(4)[8],=KH0UN(4)[8],=KH2AR(4)[8],=KH2AR/4(4)[8],=KH2DN(4)[8],=KH4AF(4)[8], @@ -1571,36 +1582,38 @@ United States: 05: 08: NA: 37.53: 91.67: 5.0: K: =KH6SKY/4(4)[8],=KH7JM(4)[8],=KH7UB(4)[8],=KL0AH(4)[8],=KL0BX(4)[8],=KL0CP(4)[8],=KL0ET(4)[8], =KL0ET/M(4)[8],=KL0EY(4)[8],=KL0FF(4)[8],=KL0GI(4)[8],=KL0LN(4)[8],=KL0PM(4)[8],=KL0VH(4)[8], =KL1DN(4)[8],=KL1IG(4)[8],=KL1LV(4)[8],=KL1SE(4)[8],=KL1SE/4(4)[8],=KL1ZA(4)[8],=KL2GB(4)[8], - =KL2HK(4)[8],=KL2LK(4)[8],=KL2LU(4)[8],=KL2MU(4)[8],=KL2UC(4)[8],=KL3PG(4)[8],=KL4KA(4)[8], - =KL7DT/4(4)[8],=KL7FO/P(4)[8],=KL7GN/M(4)[8],=KL7IUQ(4)[8],=KL7JKC(4)[8],=KL7LT(4)[8], - =KL7WW(4)[8],=KL7YN(4)[8],=KL7YT(4)[8],=KL9MEK(4)[8],=KP3RC(4)[8],=KP4TOM(4)[8],=NH2E(4)[8], - =NH6T/4(4)[8],=NH7FK(4)[8],=NH7FL(4)[8],=NH7H(4)[8],=NL7OE(4)[8],=NL7YU(4)[8],=NP3FB(4)[8], - =NP4AC(4)[8],=NP4AC/4(4)[8],=WH6AUL(4)[8],=WH6BPL(4)[8],=WH6BPL/4(4)[8],=WH6DM(4)[8], - =WH6EOG(4)[8],=WH6FEJ(4)[8],=WH6LAK(4)[8],=WL4B(4)[8],=WL7BHI(4)[8],=WL7BHJ(4)[8],=WL7CQH(4)[8], - =WL7CQK(4)[8],=WL7IP(4)[8],=WL7PC(4)[8],=WL7SF(4)[8],=WL7TD(4)[8],=WL7XZ(4)[8],=WP4CNA(4)[8], + =KL2HK(4)[8],=KL2LK(4)[8],=KL2LU(4)[8],=KL2MU(4)[8],=KL2UC(4)[8],=KL3PG(4)[8],=KL3PV(4)[8], + =KL4KA(4)[8],=KL7DT/4(4)[8],=KL7FO/P(4)[8],=KL7GN/M(4)[8],=KL7IUQ(4)[8],=KL7JKC(4)[8], + =KL7LT(4)[8],=KL7WW(4)[8],=KL7YN(4)[8],=KL7YT(4)[8],=KL9MEK(4)[8],=KP3RC(4)[8],=KP4TOM(4)[8], + =NH2E(4)[8],=NH6T/4(4)[8],=NH7FK(4)[8],=NH7FL(4)[8],=NH7H(4)[8],=NL7OE(4)[8],=NL7YU(4)[8], + =NP3FB(4)[8],=NP4AC(4)[8],=NP4AC/4(4)[8],=WH6AUL(4)[8],=WH6BPL(4)[8],=WH6BPL/4(4)[8],=WH6DM(4)[8], + =WH6EOG(4)[8],=WH6EQW(4)[8],=WH6FEJ(4)[8],=WH6LAK(4)[8],=WL4B(4)[8],=WL7BHI(4)[8],=WL7BHJ(4)[8], + =WL7CQH(4)[8],=WL7CQK(4)[8],=WL7IP(4)[8],=WL7PC(4)[8],=WL7SF(4)[8],=WL7TD(4)[8],=WL7XZ(4)[8], + =WP4CNA(4)[8], =AL7AU(4)[7],=AL7NI(4)[7],=AL7RT(4)[7],=AL7RT/7(4)[7],=KH2BR/7(4)[7],=KH6JVF(4)[7],=KH6OZ(4)[7], - =KH7SS(4)[7],=KL0NT(4)[7],=KL0NV(4)[7],=KL0RN(4)[7],=KL1HE(4)[7],=KL1MW(4)[7],=KL1TV(4)[7], - =KL2NZ(4)[7],=KL7AR(4)[7],=KL7HF(4)[7],=KL7JGS(4)[7],=KL7JGS/M(4)[7],=KL7JM(4)[7],=KL7LH(4)[7], - =KL7MVX(4)[7],=KL7YY/7(4)[7],=KL9A(4)[7],=KL9A/7(4)[7],=NH0E(4)[7],=NH6HW(4)[7],=NL7IH(4)[7], - =NL7MW(4)[7],=WH2M(4)[7],=WH6COM(4)[7],=WH6ETU(4)[7],=WH6EVP(4)[7],=WL7A(4)[7],=WL7DP(4)[7], - =WL7HP/7(4)[7],=WL7I(4)[7], + =KH7SS(4)[7],=KL0NT(4)[7],=KL0NV(4)[7],=KL0RN(4)[7],=KL0TF(4)[7],=KL1HE(4)[7],=KL1MW(4)[7], + =KL1TV(4)[7],=KL2NZ(4)[7],=KL4CZ(4)[7],=KL7AR(4)[7],=KL7HF(4)[7],=KL7JGS(4)[7],=KL7JGS/M(4)[7], + =KL7JM(4)[7],=KL7JUL(4)[7],=KL7LH(4)[7],=KL7MVX(4)[7],=KL7YY/7(4)[7],=KL9A(4)[7],=KL9A/7(4)[7], + =NH0E(4)[7],=NH6HW(4)[7],=NL7IH(4)[7],=NL7MW(4)[7],=WH2M(4)[7],=WH6COM(4)[7],=WH6ETU(4)[7], + =WH6EVP(4)[7],=WL7A(4)[7],=WL7DP(4)[7],=WL7HP/7(4)[7],=WL7I(4)[7], =AL7LU(5)[8],=KL7JFR(5)[8],=WL7HC(5)[8],=WP4GR(5)[8]; Guantanamo Bay: 08: 11: NA: 20.00: 75.00: 5.0: KG4: KG4,=KG44WW,=KG4AC,=KG4AS,=KG4AW,=KG4AY,=KG4BP,=KG4DY,=KG4EM,=KG4EU,=KG4HF,=KG4HH,=KG4LA,=KG4LB, =KG4SC,=KG4SS,=KG4WH,=KG4WV,=KG4XP,=KG4ZK,=W1AW/KG4; Mariana Islands: 27: 64: OC: 15.18: -145.72: -10.0: KH0: AH0,KH0,NH0,WH0,=AB2HV,=AB2QH,=AB9HF,=AB9OQ,=AC8CP,=AD5KT,=AD6YP,=AE6OG,=AF4IN,=AF4KH,=AF6EO, - =AH2U,=AJ6K,=AK1JA,=K8KH,=K8RN,=KB5UAB,=KB9LQG,=KC2WIK,=KC5SPG,=KC7SDC,=KC9GQX,=KD7GJX,=KG2QH, - =KG6GQ,=KG6SB,=KG7DCN,=KH0EN/KT,=KH2GV,=KH2O,=KH2VL,=KL7QOL,=KW2X,=N0J,=N3QD,=N6EAX,=N7NVX,=N8CS, - =NA1M,=NH2B,=NH2FG,=NU2A,=W1FPU,=W3FM,=W3NL,=W3STX,=W7KFS,=WA6AC,=WE1J,=WH6ZW,=WO2G; + =AH2U,=AJ6K,=AK1JA,=K0FRI,=K8KH,=K8RN,=KB5UAB,=KB9LQG,=KC2WIK,=KC5SPG,=KC7SDC,=KC9GQX,=KD7GJX, + =KG2QH,=KG6GQ,=KG6SB,=KG7DCN,=KH0EN/KT,=KH2GV,=KH2O,=KH2VL,=KL7QOL,=KW2X,=N0J,=N3QD,=N6EAX,=N7NVX, + =N8CS,=NA1M,=NH2B,=NH2FG,=NO3V,=NU2A,=W1FPU,=W3FM,=W3NL,=W3STX,=W7KFS,=WA6AC,=WE1J,=WH6ZW,=WO2G; Baker & Howland Islands: 31: 61: OC: 0.00: 176.00: 12.0: KH1: AH1,KH1,NH1,WH1; Guam: 27: 64: OC: 13.37: -144.70: -10.0: KH2: - AH2,KH2,NH2,WH2,=AB2AB,=AB8EW,=AC0FG,=AE6QZ,=AH0AX,=AH0F,=AH0FM,=AH0S,=AI6ID,=K1IWD,=K2QGC,=K5GUA, - =K5GUM,=KA0RU,=KA6BEG,=KB7OVT,=KB7PQU,=KC2OOX,=KD7IRV,=KE4YSP,=KE6ATM,=KE7GMC,=KE7IPG,=KF4UFC, - =KF5ULC,=KF7BMU,=KG4BKW,=KG6AGT,=KG6ARL,=KG6DX,=KG6FJG,=KG6JDX,=KG6JKR,=KG6JKT,=KG6TEZ,=KG6TWZ, - =KH0C,=KH0DX,=KH0ES,=KH0TF,=KH0UM,=KH6KK,=KI4KKH,=KI4KKI,=KI7SSW,=KJ6KCJ,=KK6GVF,=KK7AV,=KM4NVB, - =N2MI,=NH0A,=NH0B,=NH7TL,=NH7WC,=NP3EZ,=W5LFA,=W6KV,=W7GVC,=W9MRE,=WA3KNB,=WB7AXZ,=WD6DGS,=WH0AC; + AH2,KH2,NH2,WH2,=AB2AB,=AB8EW,=AC0FG,=AC7WL,=AE6QZ,=AH0AX,=AH0F,=AH0FM,=AH0S,=AI6ID,=AJ6JF,=K1IWD, + =K2QGC,=K5GUA,=K5GUM,=KA0RU,=KA1I,=KA6BEG,=KB5OXR,=KB7OVT,=KB7PQU,=KC2OOX,=KD7IRV,=KE4YSP,=KE6ATM, + =KE7GMC,=KE7IPG,=KF4UFC,=KF5ULC,=KF7BMU,=KG4BKW,=KG6AGT,=KG6ARL,=KG6DX,=KG6FJG,=KG6JDX,=KG6JKR, + =KG6JKT,=KG6TWZ,=KH0C,=KH0DX,=KH0ES,=KH0TF,=KH0UM,=KH6KK,=KI4KKH,=KI4KKI,=KI7SSW,=KJ6KCJ,=KK6GVF, + =KK7AV,=KM4NVB,=N2MI,=NH0A,=NH0B,=NH0Q,=NH7TL,=NH7WC,=NP3EZ,=W5LFA,=W6KV,=W7GVC,=W9MRE,=WA3KNB, + =WB7AXZ,=WD6DGS,=WH0AC; Johnston Island: 31: 61: OC: 16.72: 169.53: 10.0: KH3: AH3,KH3,NH3,WH3,=KJ6BZ; Midway Island: 31: 61: OC: 28.20: 177.37: 11.0: KH4: @@ -1610,44 +1623,45 @@ Palmyra & Jarvis Islands: 31: 61: OC: 5.87: 162.07: 11.0: KH5: Hawaii: 31: 61: OC: 21.12: 157.48: 10.0: KH6: AH6,AH7,KH6,KH7,NH6,NH7,WH6,WH7,=AA7LE,=AA8JA,=AB0JM,=AB3WS,=AB6AP,=AB8VQ,=AC4PJ,=AC4TJ,=AC7LR, =AC7N,=AC9PT,=AE3TT,=AE5AB,=AE5LR,=AG4FH,=AH0A,=AH0AG,=AH2CN,=AJ0M,=AJ8HT,=AK0P,=AK2J,=AL3U, - =AL7RQ,=K0BAD,=K0LAS,=K0LIH,=K0LUC,=K0OUS,=K1ENT,=K1HZM,=K1OWL,=K1RJ,=K1VAN,=K2FFT,=K2GT,=K3NW, - =K3QHP,=K3UNS,=K4EVR,=K4RAC,=K4UAI,=K4UHL,=K4XS,=K4XSS,=K4XV,=K5HQM,=K5ZAI,=K5ZYO,=K6AMA,=K6APP, - =K6ATF,=K6CEE,=K6GJS,=K6GUY,=K6HI,=K6JAE,=K6MIO,=K6NLF,=K6RSB,=K7ASH,=K7FAR,=K7FR,=K7NRJ,=K7QAS, - =K8EUT,=K9AGI,=K9FD,=K9UBS,=KA0FOR,=KA0VHP,=KA1ICJ,=KA1YJ,=KA2IXG,=KA2WXU,=KA3HIZ,=KA3TUA,=KA4INK, - =KA6QOD,=KA7APU,=KA7RKW,=KA8EBL,=KA8KND,=KA9DMP,=KB0DJR,=KB0PXK,=KB0ZKZ,=KB1EUJ,=KB1GC,=KB1PCX, - =KB2MRY,=KB3DMT,=KB3IOC,=KB3OXU,=KB3PJS,=KB3SEV,=KB4NGN,=KB5NNY,=KB5OWT,=KB6CNU,=KB6EGA,=KB6INB, - =KB6PKF,=KB7AKH,=KB7DDX,=KB7EA,=KB7G,=KB7JB,=KB7MEU,=KB7QKJ,=KB7UQH,=KB7UVR,=KB7WDC,=KB7WUP, - =KB8SKX,=KC0WQU,=KC0YIH,=KC0ZER,=KC1DBY,=KC2GSU,=KC2HL,=KC2MIU,=KC2PGW,=KC2SRW,=KC2YL,=KC2ZSG, - =KC2ZSH,=KC2ZSI,=KC3GZT,=KC4HHS,=KC5GAX,=KC6HOX,=KC6QQI,=KC6RYQ,=KC6SHT,=KC6SWR,=KC6YIO,=KC7ASJ, - =KC7AXX,=KC7DUT,=KC7EJC,=KC7HNC,=KC7KAT,=KC7KAW,=KC7KBA,=KC7KHW,=KC7KJT,=KC7LFM,=KC7NZ,=KC7PLG, - =KC7USA,=KC7VHF,=KC7VWU,=KC7YXO,=KC8EFI,=KC8EJ,=KC9AUA,=KC9EQS,=KC9KEX,=KC9NJG,=KC9SBG,=KD0QLQ, - =KD0QLR,=KD0RPD,=KD0WVZ,=KD0ZSP,=KD3FZ,=KD4GW,=KD4ML,=KD4QWO,=KD5ACN,=KD5BSK,=KD5HDA,=KD5HX, - =KD5TBQ,=KD6CVU,=KD6CWF,=KD6EPD,=KD6IPX,=KD6LRA,=KD6VTU,=KD7HTG,=KD7LMP,=KD7SME,=KD7SMV,=KD7TZ, - =KD7UV,=KD7UZG,=KD7WJM,=KD8GVO,=KE0TU,=KE2CX,=KE4DYE,=KE4RNU,=KE4UXQ,=KE4ZXQ,=KE5CGA,=KE5FJM, - =KE5UZN,=KE6AXN,=KE6AXP,=KE6AYZ,=KE6CQE,=KE6EDJ,=KE6EVT,=KE6JXO,=KE6RAW,=KE6TFR,=KE6TIS,=KE6TKQ, - =KE7FJA,=KE7FSK,=KE7HEW,=KE7IZS,=KE7JTX,=KE7KRQ,=KE7LWN,=KE7MW,=KE7PEQ,=KE7PIZ,=KE7QML,=KE7RCT, - =KE7UAJ,=KE7UV,=KE7UW,=KF4DWA,=KF4FQR,=KF4IBW,=KF4JLZ,=KF4OOB,=KF4URD,=KF4VHS,=KF5AHW,=KF5LBQ, - =KF5MXM,=KF5MXP,=KF6BS,=KF6FDG,=KF6IVV,=KF6LWN,=KF6LYU,=KF6MQT,=KF6OSA,=KF6PJ,=KF6PQE,=KF6QZD, - =KF6RLP,=KF6YZR,=KF6ZAL,=KF7GNP,=KF7IJL,=KF7LRS,=KF7OJR,=KF7TUU,=KF7VUK,=KG0XR,=KG4HZF,=KG4SGC, - =KG4SGV,=KG6DV,=KG6EFD,=KG6HRX,=KG6IGY,=KG6JJP,=KG6LFX,=KG6MZJ,=KG6NNF,=KG6NQI,=KG6OOB,=KG6RJI, - =KG6SDD,=KG6TFI,=KG6WZD,=KG7AYU,=KG7CJI,=KG7CVR,=KG7EUP,=KH0AI,=KH0HL,=KH0WJ,=KH2MD,=KH2TD,=KH2TE, - =KH2YI,=KH3AE,=KH3AE/M,=KH3AF,=KH8Z,=KI4CAU,=KI4HCZ,=KI4NOH,=KI4YAF,=KI4YOG,=KI6CRL,=KI6DVJ, - =KI6EFY,=KI6FTE,=KI6HBZ,=KI6JEC,=KI6LPT,=KI6NOC,=KI6QDQ,=KI6QQJ,=KI6SNP,=KI6VYB,=KI6WOJ,=KI6ZRV, - =KI7EZG,=KI7FJW,=KI7FJX,=KI7FUT,=KI7OS,=KI7QZQ,=KJ4BHO,=KJ4EYV,=KJ4KND,=KJ4WOI,=KJ6GYD,=KJ6LAW, - =KJ6LAX,=KJ6LBI,=KJ6NZH,=KJ6QQT,=KJ6RGW,=KJ6SKC,=KJ6TJZ,=KK4EEC,=KK6BRW,=KK6EJ,=KK6GM,=KK6OMX, - =KK6PGA,=KK6QAI,=KK6VJN,=KK6ZQ,=KK6ZZE,=KK7WR,=KL1TP,=KL3FN,=KL7PN,=KL7UB,=KM6BOQ,=KM6IK,=KM6RM, - =KN6BE,=KN6ZU,=KN8AQR,=KO6KW,=KO6QT,=KQ6CD,=KQ6M,=KU4OY,=KW4JC,=KY1I,=N0CAN,=N0DQD,=N0PJV,=N0RMC, - =N0ZSJ,=N1CBF,=N1CFD,=N1CNQ,=N1IDP,=N1SHV,=N1TEE,=N1TLE,=N1VOP,=N1YLH,=N2AL,=N2KJU,=N2KLQ,=N3DJT, - =N3FUR,=N3GWR,=N3HQW,=N3RWD,=N3VDM,=N3ZFY,=N4ERA,=N4ZIW,=N5IWF,=N5JKJ,=N6AI,=N6CGA,=N6DXW,=N6GOZ, - =N6IKX,=N6KB,=N6NCT,=N6PJQ,=N6QBK,=N6ZAB,=N7AMY,=N7BLC,=N7KZB,=N7NYY,=N7ODC,=N7TSV,=N7WBX,=N9CRQ, - =N9GFL,=N9SBL,=NB6R,=NE7SO,=NG1T,=NH2CC,=NH2CD,=NH2CF,=NH2CQ,=NH2CR,=NH2IB,=NH2IF,=NH2II,=NH2IJ, - =NH2IO,=NH2JO,=NH2KF,=NH2KH,=NH2YL,=NH2Z,=NI1J,=NL7UW,=NM2B,=NO0H,=NT0DA,=NT4AA,=NZ2F,=W0UNX, - =W1BMB,=W2UNS,=W3ZRT,=W4YQS,=W5FJG,=W6AUS,=W6CAG,=W6CWJ,=W6KEV,=W6KIT,=W6KPI,=W6MQB,=W6MRJ,=W6NBK, - =W6ROM,=W6SHH,=W6UNX,=W7EHP,=W7NVQ,=W7NX,=W7OO,=W7RCR,=W7UEA,=W8AYD,=W8JAY,=W8WH,=WA0FUR,=WA0NHD, - =WA2AUI,=WA3ZEM,=WA6ECX,=WA6IIQ,=WA6JDA,=WA6JJQ,=WA6QDQ,=WA6UVF,=WA7ESE,=WA7HEO,=WA7TFE,=WA7ZK, - =WA8JQP,=WB0RUA,=WB0TZQ,=WB2AHM,=WB2SQW,=WB4JTT,=WB4MNF,=WB5ZDH,=WB5ZOV,=WB6CVJ,=WB6PIO,=WB6PJT, - =WB6SAA,=WB8NCD,=WB9SMM,=WC6B,=WD0FTF,=WD0LFN,=WD6EZL,=WD6GHJ,=WD8LIB,=WD8OBO,=WH2Y,=WH7K,=WU0H, - =WV0Z,=WV6K,=WX7G; + =AL7RQ,=K0BAD,=K0LAS,=K0LIH,=K0LUC,=K0OUS,=K1ENT,=K1HZM,=K1OSP,=K1OWL,=K1RJ,=K1VAN,=K2FFT,=K2GT, + =K3NW,=K3QHP,=K3UNS,=K4EVR,=K4RAC,=K4UAI,=K4UHL,=K4XS,=K4XSS,=K4XV,=K5HQM,=K5UN,=K5ZAI,=K5ZYO, + =K6AMA,=K6APP,=K6ATF,=K6BU,=K6CEE,=K6GJS,=K6GUY,=K6HI,=K6JAE,=K6MIO,=K6NLF,=K6RSB,=K7ALH,=K7ASH, + =K7FAR,=K7FR,=K7NRJ,=K7QAS,=K8EUT,=K9AGI,=K9FD,=K9UBS,=KA0FOR,=KA0VHP,=KA1ICJ,=KA1YJ,=KA2IXG, + =KA2WXU,=KA3HIZ,=KA3TUA,=KA4INK,=KA6QOD,=KA7APU,=KA7RKW,=KA8EBL,=KA8KND,=KA9DMP,=KB0DJR,=KB0PXK, + =KB0ZKZ,=KB1EUJ,=KB1GC,=KB1PCX,=KB1UHL,=KB2MRY,=KB3DMT,=KB3IOC,=KB3OXU,=KB3PJS,=KB3SEV,=KB4NGN, + =KB5HVJ,=KB5NNY,=KB5OWT,=KB6CNU,=KB6EGA,=KB6INB,=KB6PKF,=KB7AKH,=KB7DDX,=KB7EA,=KB7G,=KB7JB, + =KB7MEU,=KB7QKJ,=KB7UQH,=KB7UVR,=KB7WDC,=KB7WUP,=KB8SKX,=KC0WQU,=KC0YIH,=KC0ZER,=KC1DBY,=KC2GSU, + =KC2HL,=KC2MIU,=KC2PGW,=KC2SRW,=KC2YL,=KC2ZSG,=KC2ZSH,=KC2ZSI,=KC3GZT,=KC4HHS,=KC5GAX,=KC6HOX, + =KC6QQI,=KC6RYQ,=KC6SHT,=KC6SWR,=KC6YIO,=KC7ASJ,=KC7AXX,=KC7DUT,=KC7EJC,=KC7HNC,=KC7KAT,=KC7KAW, + =KC7KBA,=KC7KHW,=KC7KJT,=KC7LFM,=KC7NZ,=KC7PLG,=KC7USA,=KC7VHF,=KC7VWU,=KC7YXO,=KC8EFI,=KC8EJ, + =KC9AUA,=KC9EQS,=KC9KEX,=KC9NJG,=KC9SBG,=KD0QLQ,=KD0QLR,=KD0RPD,=KD0WVZ,=KD0ZSP,=KD3FZ,=KD4GW, + =KD4ML,=KD4QWO,=KD5ACN,=KD5BSK,=KD5HDA,=KD5HX,=KD5TBQ,=KD6CVU,=KD6CWF,=KD6EPD,=KD6IPX,=KD6LRA, + =KD6NVX,=KD6VTU,=KD7GWM,=KD7HTG,=KD7KFT,=KD7LMP,=KD7SME,=KD7SMV,=KD7TZ,=KD7UV,=KD7UZG,=KD7WJM, + =KD8GVO,=KE0TU,=KE2CX,=KE4DYE,=KE4RNU,=KE4UXQ,=KE4ZXQ,=KE5CGA,=KE5FJM,=KE5UZN,=KE6AXN,=KE6AXP, + =KE6AYZ,=KE6CQE,=KE6EDJ,=KE6EVT,=KE6JXO,=KE6RAW,=KE6TFR,=KE6TIS,=KE6TKQ,=KE7FJA,=KE7FSK,=KE7HEW, + =KE7IZS,=KE7JTX,=KE7KRQ,=KE7LWN,=KE7MW,=KE7PEQ,=KE7PIZ,=KE7QML,=KE7RCT,=KE7UAJ,=KE7UV,=KE7UW, + =KF4DWA,=KF4FQR,=KF4IBW,=KF4JLZ,=KF4OOB,=KF4URD,=KF4VHS,=KF5AHW,=KF5LBQ,=KF5MXM,=KF5MXP,=KF6BS, + =KF6FDG,=KF6IVV,=KF6LWN,=KF6LYU,=KF6MQT,=KF6OSA,=KF6PJ,=KF6PQE,=KF6QZD,=KF6RLP,=KF6YZR,=KF6ZAL, + =KF6ZVS,=KF7GNP,=KF7IJL,=KF7LRS,=KF7OJR,=KF7TUU,=KF7VUK,=KG0XR,=KG4HZF,=KG4SGC,=KG4SGV,=KG6DV, + =KG6EFD,=KG6HRX,=KG6IGY,=KG6JJP,=KG6LFX,=KG6MZJ,=KG6NNF,=KG6NQI,=KG6OOB,=KG6RJI,=KG6SDD,=KG6TFI, + =KG6WZD,=KG7AYU,=KG7CJI,=KG7CVR,=KG7EUP,=KH0AI,=KH0HL,=KH0WJ,=KH2MD,=KH2TD,=KH2TE,=KH2YI,=KH3AE, + =KH3AE/M,=KH3AF,=KH8Z,=KI4CAU,=KI4HCZ,=KI4NOH,=KI4YAF,=KI4YOG,=KI6CRL,=KI6DVJ,=KI6EFY,=KI6FTE, + =KI6HBZ,=KI6JEC,=KI6LPT,=KI6NOC,=KI6QDQ,=KI6QQJ,=KI6SNP,=KI6VYB,=KI6WOJ,=KI6ZRV,=KI7EZG,=KI7FJW, + =KI7FJX,=KI7FUT,=KI7OS,=KI7QZQ,=KJ4BHO,=KJ4EYV,=KJ4KND,=KJ4WOI,=KJ6GYD,=KJ6LAW,=KJ6LAX,=KJ6LBI, + =KJ6NZH,=KJ6QQT,=KJ6RGW,=KJ6SKC,=KJ6TJZ,=KK4EEC,=KK6BRW,=KK6EJ,=KK6GM,=KK6OMX,=KK6PGA,=KK6QAI, + =KK6RM,=KK6VJN,=KK6ZQ,=KK6ZZE,=KK7WR,=KL0TK,=KL1TP,=KL3FN,=KL7PN,=KL7UB,=KM6BOQ,=KM6IK,=KM6RM, + =KN6BE,=KN6ZU,=KN8AQR,=KO6KW,=KO6QT,=KQ6CD,=KQ6M,=KU4OY,=KW4JC,=KY1I,=N0CAN,=N0DQD,=N0KXY,=N0PJV, + =N0RMC,=N0ZSJ,=N1CBF,=N1CFD,=N1CNQ,=N1IDP,=N1SHV,=N1TEE,=N1TLE,=N1VOP,=N1YLH,=N2AL,=N2KJU,=N2KLQ, + =N3DJT,=N3FUR,=N3GWR,=N3HQW,=N3RWD,=N3VDM,=N3ZFY,=N4ERA,=N4ZIW,=N5IWF,=N5JKJ,=N6AI,=N6CGA,=N6DXW, + =N6GOZ,=N6IKX,=N6KB,=N6NCT,=N6PJQ,=N6QBK,=N6ZAB,=N7AMY,=N7BLC,=N7KZB,=N7NYY,=N7ODC,=N7TSV,=N7WBX, + =N9CRQ,=N9GFL,=N9SBL,=NB6R,=NE7SO,=NG1T,=NH2CC,=NH2CD,=NH2CF,=NH2CQ,=NH2CR,=NH2IB,=NH2IF,=NH2II, + =NH2IJ,=NH2IO,=NH2JO,=NH2KF,=NH2KH,=NH2YL,=NH2Z,=NI1J,=NL7UW,=NM2B,=NO0H,=NT0DA,=NT4AA,=NZ2F, + =W0UNX,=W1BMB,=W2UNS,=W3ZRT,=W4YQS,=W5FJG,=W6AUS,=W6CAG,=W6CWJ,=W6KEV,=W6KIT,=W6KPI,=W6MQB,=W6MRJ, + =W6NBK,=W6ROM,=W6SHH,=W6UNX,=W7EHP,=W7NVQ,=W7NX,=W7OO,=W7RCR,=W7UEA,=W8AYD,=W8JAY,=W8WH,=WA0FUR, + =WA0NHD,=WA2AUI,=WA3ZEM,=WA6ECX,=WA6IIQ,=WA6JDA,=WA6JJQ,=WA6QDQ,=WA6UVF,=WA7ESE,=WA7HEO,=WA7TFE, + =WA7ZK,=WA8JQP,=WB0RUA,=WB0TZQ,=WB2AHM,=WB2SQW,=WB4JTT,=WB4MNF,=WB5ZDH,=WB5ZOV,=WB6CVJ,=WB6PIO, + =WB6PJT,=WB6SAA,=WB8NCD,=WB9SMM,=WC6B,=WD0FTF,=WD0LFN,=WD6EZL,=WD6GHJ,=WD8LIB,=WD8OBO,=WH2Y,=WH7K, + =WU0H,=WV0Z,=WV6K,=WX7G,=WY6F; Kure Island: 31: 61: OC: 29.00: 178.00: 10.0: KH7K: AH7K,KH7K,NH7K,WH7K; American Samoa: 32: 62: OC: -14.32: 170.78: 11.0: KH8: @@ -1659,72 +1673,72 @@ Wake Island: 31: 65: OC: 19.28: -166.63: -12.0: KH9: Alaska: 01: 01: NA: 61.40: 148.87: 8.0: KL: AL,KL,NL,WL,=AA0NN,=AA8FY,=AB0IC,=AB0WK,=AB5JB,=AB7YB,=AB7YO,=AB8XX,=AB9OM,=AC0CW,=AC9QX,=AD0DK, =AD0FQ,=AD0ZL,=AD3BJ,=AD6GC,=AD7MF,=AD7VV,=AE1DJ,=AE4QH,=AE5CP,=AE5EX,=AE5FN,=AE5IR,=AE7ES,=AE7KS, - =AE7SB,=AF7FV,=AG5LN,=AG5OF,=AH0AH,=AH0H,=AJ4ZI,=K0AZZ,=K0BHC,=K1BZD,=K1MAT,=K2ICW,=K2NPS,=K3JMI, - =K4ETC,=K4HOE,=K4RND,=K4WPK,=K5DOW,=K5HL,=K5RD,=K5RSO,=K5RZW,=K5TDN,=K5UBS,=K6ANE,=K6GKW,=K7EJM, - =K7GRW,=K7LOP,=K7MVX,=K7OCL,=K7RDR,=K7SGA,=K7UNX,=K7ZOA,=K8IEL,=K8OUA,=K9DUG,=K9WUV,=KA0SIM, - =KA0YPV,=KA1NCN,=KA2TJZ,=KA2ZSD,=KA6UGT,=KA7ETQ,=KA7HOX,=KA7JOR,=KA7TMU,=KA7TOM,=KA7UKN,=KA7VCR, - =KA7YEY,=KA9GYQ,=KB0APK,=KB0LOW,=KB0TSU,=KB0UGE,=KB0UVK,=KB1CRT,=KB1FCX,=KB1KLH,=KB1PHP,=KB1QCD, - =KB1QCE,=KB1SYV,=KB1WQL,=KB2JWV,=KB2ZME,=KB3CYB,=KB3JFK,=KB3NCR,=KB4DX,=KB5DNT,=KB5HEV,=KB5UWU, - =KB6DKJ,=KB7AMA,=KB7BNG,=KB7DEL,=KB7FXJ,=KB7IBI,=KB7JA,=KB7LJZ,=KB7LON,=KB7PHT,=KB7QLB,=KB7RXZ, - =KB7SIQ,=KB7UBH,=KB7VFZ,=KB7YEC,=KB7ZVZ,=KB8QKR,=KB8SBG,=KB8TEW,=KB8VYJ,=KB9MWG,=KB9RWE,=KB9RWJ, - =KB9YGR,=KC0ATI,=KC0CWG,=KC0CYR,=KC0EF,=KC0GHH,=KC0NSV,=KC0OKQ,=KC0PSZ,=KC0TK,=KC0TZL,=KC0UYK, - =KC0VDN,=KC0WSG,=KC0YSW,=KC1DL,=KC2BYX,=KC2GVS,=KC2HRV,=KC2KMU,=KC2OJP,=KC2PCV,=KC2PIO,=KC3DBK, - =KC4MXQ,=KC4MXR,=KC5BNN,=KC5CHO,=KC5DJA,=KC5KIG,=KC5LKF,=KC5LKG,=KC5QPJ,=KC5THY,=KC5YIB,=KC5YOX, - =KC5ZAA,=KC6RJW,=KC7BUL,=KC7COW,=KC7ENM,=KC7FWK,=KC7GSO,=KC7HJM,=KC7HPF,=KC7IKE,=KC7IKF,=KC7INC, - =KC7MIJ,=KC7MPY,=KC7MRO,=KC7OQZ,=KC7PLJ,=KC7PLQ,=KC7RCP,=KC7TYT,=KC7UZY,=KC7WOA,=KC7YZR,=KC8BKP, - =KC8GKK,=KC8NMN,=KC8NOY,=KC8WWS,=KC8YIV,=KC9CMY,=KC9HIK,=KC9VLD,=KD0CLU,=KD0CZC,=KD0DHU,=KD0FJG, - =KD0JJB,=KD0NSG,=KD0VAK,=KD0VAL,=KD0VGF,=KD0ZOD,=KD2CTE,=KD2GKT,=KD4EYW,=KD4MEY,=KD4QJL,=KD5DNA, - =KD5DWV,=KD5GAL,=KD5QPD,=KD5RVD,=KD5WCF,=KD5WEV,=KD6DLB,=KD6RVY,=KD6YKS,=KD7APU,=KD7AWK,=KD7BBX, - =KD7BGP,=KD7DIG,=KD7DUQ,=KD7FGL,=KD7FUL,=KD7GFG,=KD7HXF,=KD7KRK,=KD7MGO,=KD7QAR,=KD7SIX,=KD7TWB, - =KD7UAG,=KD7VOI,=KD7VXE,=KD7ZTJ,=KD8BVD,=KD8DDY,=KD8GEL,=KD8GMS,=KD8JOU,=KD8LNA,=KD8WMX,=KD9TK, - =KE0DYM,=KE0KKI,=KE4DGR,=KE4MQD,=KE4YEI,=KE4YLG,=KE5CVD,=KE5CVT,=KE5DQV,=KE5FOC,=KE5GEB,=KE5HHR, - =KE5JHS,=KE5JTB,=KE5NLG,=KE5QDI,=KE5QDJ,=KE5QDK,=KE5VPO,=KE5ZRK,=KE5ZUM,=KE6DLM,=KE6DUJ,=KE6DXH, - =KE6IPM,=KE6SYD,=KE6TCE,=KE6VUB,=KE7DFO,=KE7ELL,=KE7EOP,=KE7EPZ,=KE7FNC,=KE7FXM,=KE7GOE,=KE7HMJ, - =KE7KYU,=KE7TRX,=KE8RO,=KF4JET,=KF4PLR,=KF4TBD,=KF4YFD,=KF5CVM,=KF5FJQ,=KF5HFB,=KF5HJC,=KF5NDT, - =KF5NHR,=KF5YYK,=KF6AWG,=KF6AXS,=KF6BMF,=KF6BOV,=KF6EJR,=KF6GNM,=KF6IAO,=KF6ILC,=KF6IOT,=KF6LGK, - =KF6MFK,=KF6QOJ,=KF6RMG,=KF6RPC,=KF6SHS,=KF6TGR,=KF6UWT,=KF7GKY,=KF7LEX,=KF7LUA,=KF7PCJ,=KF7PFT, - =KF7PSS,=KF7PUQ,=KF7UFY,=KF7VBO,=KF8ZB,=KG2IA,=KG4BBX,=KG4NBL/P,=KG4TJS,=KG4WNZ,=KG5EQN,=KG5GDF, - =KG5GTD,=KG5JQC,=KG5MIB,=KG6DTI,=KG6MBC,=KG6RJE,=KG6TAL,=KG7CUR,=KG7DVI,=KG7GJL,=KG7JVJ,=KG7OQC, - =KG7SEQ,=KG7TGE,=KH0NF,=KH0NG,=KH0RF,=KH2YN,=KH7BW,=KH7DA,=KI4COG,=KI4ERC,=KI4GAG,=KI4GCF,=KI4GDI, - =KI4NGY,=KI4NVI,=KI4SET,=KI4SOM,=KI6BGR,=KI6DES,=KI6HGW,=KI7COR,=KI7PZ,=KI8JT,=KJ4HEW,=KJ4IAQ, - =KJ4PSV,=KJ4WDI,=KJ4WIQ,=KJ4ZWI,=KJ6KRG,=KJ6ZSX,=KJ7IR,=KK4AMV,=KK4CLS,=KK4LRE,=KK4QXE,=KK4RYG, - =KK4WWH,=KK4WWI,=KK6IUY,=KK6PGV,=KK7I,=KK7IV,=KK7STL,=KL7D/M,=KL7NC/IMD,=KM4AGL,=KM4KWS,=KM4KX, - =KM4NIC,=KM4OE,=KM4PJH,=KM4TJI,=KN8IVE,=KR4WV,=KV3X,=KW1W,=KY7J,=KZ6HJC,=N0GDT,=N0GDU,=N0GLI, - =N0HJT,=N0HYI,=N0HZF,=N0JEN,=N0LHN,=N0SN,=N0SUB,=N0WXJ,=N0XKY,=N0XS,=N0ZKV,=N1HUT,=N1KDQ,=N1KTI, - =N1NDA,=N1NJS,=N1QFE,=N1TX,=N2CXH,=N2SHO,=N2TJY,=N2YZW,=N3QEH,=N4AVX,=N4CM,=N4HCJ,=N4HZU,=N4NAV, - =N5CSO,=N5UKX,=N5WPR,=N6BSC,=N6CVV,=N6CZU,=N6JM,=N7BUO,=N7DBN,=N7FCT,=N7HER,=N7HQK,=N7IA,=N7JUX, - =N7MGT,=N7MTG,=N7PHB,=N7QAN,=N7TBU,=N7UTV,=N7UWT,=N7XNM,=N7YKY,=N7YQS,=N7ZYS,=N8DDY,=N8EX,=N8JKB, - =N8KCJ,=N8SUG,=N9AIG,=N9FB,=N9YD,=NA7WM,=NC4OI,=NE7EK,=NH2GZ,=NH7UO,=NJ7H,=NN4NN,=NP4FU,=NW4G, - =NW7F,=W0EZM,=W0FJN,=W0RWS,=W0UZJ,=W1LYD,=W1RSC,=W1ZKA,=W2DLS,=W2KRZ,=W3JPN,=W4AUL,=W4BMR,=W4LS, - =W4RSB,=W5JKT,=W6DDP,=W6GTE,=W6ROW,=W7APM,=W7DDG,=W7EIK,=W7JMR,=W7PWA,=W7RAZ,=W7ROS,=W7WEZ,=W7ZWT, - =W8MDD,=W8PVZ,=W8TCX,=W9ITU,=W9JMC,=WA0JS,=WA1FVJ,=WA2BGL,=WA2BIW,=WA6GFS,=WA7B,=WA7PXH,=WA7USX, - =WA7YXF,=WB0CMZ,=WB1GZL,=WB1ILS,=WB6COP,=WB7TYK,=WB9JZL,=WD6CET,=WH6CYY,=WH6DPL,=WH6DX,=WH7AK, - =WJ8M,=WP4IYI,=WT5T,=WX1NCC; + =AE7SB,=AF7FV,=AG5LN,=AG5OF,=AH0AH,=AH0H,=AJ4ZI,=K0AZZ,=K0BHC,=K1BZD,=K1KAO,=K1MAT,=K2ICW,=K2NPS, + =K3JMI,=K4DRC,=K4ETC,=K4HOE,=K4RND,=K4WPK,=K5DOW,=K5HL,=K5RD,=K5RSO,=K5RZW,=K5TDN,=K6ANE,=K6GKW, + =K7EJM,=K7GRW,=K7LOP,=K7MVX,=K7OCL,=K7RDR,=K7SGA,=K7UNX,=K7ZOA,=K8IEL,=K8OUA,=K9DUG,=K9WUV, + =KA0SIM,=KA0YPV,=KA1NCN,=KA2TJZ,=KA2ZSD,=KA6UGT,=KA7ETQ,=KA7HOX,=KA7JOR,=KA7TMU,=KA7TOM,=KA7UKN, + =KA7VCR,=KA7YEY,=KA9GYQ,=KB0APK,=KB0LOW,=KB0TSU,=KB0UGE,=KB0UVK,=KB1CRT,=KB1FCX,=KB1KLH,=KB1PHP, + =KB1QCD,=KB1QCE,=KB1SYV,=KB1WQL,=KB2JWV,=KB2ZME,=KB3CYB,=KB3JFK,=KB3NCR,=KB3VQE,=KB4DX,=KB5DNT, + =KB5HEV,=KB5UWU,=KB6DKJ,=KB7AMA,=KB7BNG,=KB7DEL,=KB7FXJ,=KB7IBI,=KB7JA,=KB7LJZ,=KB7LON,=KB7PHT, + =KB7QLB,=KB7RXZ,=KB7SIQ,=KB7UBH,=KB7VFZ,=KB7YEC,=KB7ZVZ,=KB8QKR,=KB8SBG,=KB8TEW,=KB8VYJ,=KB9MWG, + =KB9RWE,=KB9RWJ,=KB9YGR,=KC0ATI,=KC0CWG,=KC0CYR,=KC0EF,=KC0GHH,=KC0LLL,=KC0NSV,=KC0OKQ,=KC0PSZ, + =KC0TK,=KC0TZL,=KC0UYK,=KC0VDN,=KC0WSG,=KC0YSW,=KC1DL,=KC2BYX,=KC2GVS,=KC2HRV,=KC2KMU,=KC2OJP, + =KC2PCV,=KC2PIO,=KC3DBK,=KC4MXQ,=KC4MXR,=KC5BNN,=KC5CHO,=KC5DJA,=KC5KIG,=KC5LKF,=KC5LKG,=KC5QPJ, + =KC5THY,=KC5YIB,=KC5YOX,=KC5ZAA,=KC6RJW,=KC7BUL,=KC7COW,=KC7ENM,=KC7FWK,=KC7GSO,=KC7HJM,=KC7HPF, + =KC7IKE,=KC7IKF,=KC7INC,=KC7MIJ,=KC7MPY,=KC7MRO,=KC7OQZ,=KC7PLJ,=KC7PLQ,=KC7RCP,=KC7TYT,=KC7UZY, + =KC7WOA,=KC7YZR,=KC8GKK,=KC8NMN,=KC8NOY,=KC8WWS,=KC8YIV,=KC9CMY,=KC9HIK,=KC9VLD,=KD0CLU,=KD0CZC, + =KD0DHU,=KD0FJG,=KD0JJB,=KD0NSG,=KD0VAK,=KD0VAL,=KD0VGF,=KD0ZOD,=KD2CTE,=KD2GKT,=KD4EYW,=KD4MEY, + =KD4QJL,=KD5DNA,=KD5DWV,=KD5GAL,=KD5QPD,=KD5RVD,=KD5WCF,=KD5WEV,=KD5WYP,=KD6DLB,=KD6RVY,=KD6YKS, + =KD7APU,=KD7AWK,=KD7BBX,=KD7BGP,=KD7DIG,=KD7DUQ,=KD7FGL,=KD7FUL,=KD7GFG,=KD7HXF,=KD7KRK,=KD7MGO, + =KD7QAR,=KD7SIX,=KD7TWB,=KD7UAG,=KD7VOI,=KD7VXE,=KD7ZTJ,=KD8BVD,=KD8DDY,=KD8GEL,=KD8GMS,=KD8JOU, + =KD8LNA,=KD8WMX,=KD9TK,=KE0DYM,=KE0KKI,=KE4DGR,=KE4MQD,=KE4YEI,=KE4YLG,=KE5CVD,=KE5CVT,=KE5DQV, + =KE5FOC,=KE5GEB,=KE5HHR,=KE5JHS,=KE5JTB,=KE5NLG,=KE5QDI,=KE5QDJ,=KE5QDK,=KE5VPO,=KE5ZRK,=KE5ZUM, + =KE6DLM,=KE6DUJ,=KE6DXH,=KE6IPM,=KE6SYD,=KE6TCE,=KE6VUB,=KE7DFO,=KE7ELL,=KE7EOP,=KE7EPZ,=KE7FNC, + =KE7FXM,=KE7GOE,=KE7HMJ,=KE7KYU,=KE7TRX,=KE8RO,=KF4JET,=KF4PLR,=KF4TBD,=KF4YFD,=KF5CVM,=KF5FJQ, + =KF5HFB,=KF5HJC,=KF5NDT,=KF5NHR,=KF5YYK,=KF6AWG,=KF6AXS,=KF6BMF,=KF6BOV,=KF6EJR,=KF6GNM,=KF6IAO, + =KF6ILC,=KF6IOT,=KF6LGK,=KF6MFK,=KF6QOJ,=KF6RMG,=KF6RPC,=KF6SHS,=KF6TGR,=KF6UWT,=KF7CXJ,=KF7GKY, + =KF7LEX,=KF7LUA,=KF7PCJ,=KF7PFT,=KF7PSS,=KF7PUQ,=KF7UFY,=KF7VBO,=KF8ZB,=KG2IA,=KG4BBX,=KG4NBL/P, + =KG4TJS,=KG4WNZ,=KG5EQN,=KG5GDF,=KG5GTD,=KG5JQC,=KG5MIB,=KG5MIO,=KG6DTI,=KG6MBC,=KG6RJE,=KG6TAL, + =KG7CUR,=KG7DVI,=KG7GJL,=KG7JVJ,=KG7OQC,=KG7SEQ,=KG7TGE,=KH0NF,=KH0NG,=KH0RF,=KH2YN,=KH7BW,=KH7DA, + =KI4COG,=KI4ERC,=KI4GAG,=KI4GCF,=KI4GDI,=KI4NGY,=KI4NVI,=KI4SET,=KI4SOM,=KI6BGR,=KI6DES,=KI6HGW, + =KI6YXZ,=KI7COR,=KI7PZ,=KI8JT,=KJ4HEW,=KJ4IAQ,=KJ4PSV,=KJ4WDI,=KJ4WIQ,=KJ4ZWI,=KJ6DCH,=KJ6KRG, + =KJ6ZSX,=KJ7IR,=KK4AMV,=KK4CLS,=KK4LRE,=KK4QXE,=KK4RYG,=KK4WWH,=KK4WWI,=KK6IUY,=KK6PGV,=KK7I, + =KK7IV,=KK7STL,=KL7D/M,=KL7NC/IMD,=KM4AGL,=KM4KWS,=KM4KX,=KM4NIC,=KM4OE,=KM4PJH,=KM4TJI,=KN8IVE, + =KR4WV,=KV3X,=KW1W,=KY7J,=KZ6HJC,=N0GDT,=N0GDU,=N0GLI,=N0HJT,=N0HYI,=N0HZF,=N0JEN,=N0LHN,=N0SN, + =N0SUB,=N0WXJ,=N0XKY,=N0XS,=N0ZKV,=N1HEN,=N1HUT,=N1KDQ,=N1KTI,=N1NDA,=N1NJS,=N1QFE,=N1TX,=N2CXH, + =N2SHO,=N2TJY,=N2YZW,=N3QEH,=N4AVX,=N4CM,=N4HCJ,=N4HZU,=N4NAV,=N5CSO,=N5UKX,=N5WPR,=N6BSC,=N6CVV, + =N6CZU,=N6JM,=N6ZZX,=N7BUO,=N7DBN,=N7FCT,=N7HER,=N7HQK,=N7IA,=N7JUX,=N7MGT,=N7MTG,=N7PHB,=N7QAN, + =N7TBU,=N7UTV,=N7UWT,=N7XNM,=N7YKY,=N7YQS,=N8DDY,=N8EX,=N8JKB,=N8KCJ,=N8SUG,=N9AIG,=N9FB,=N9YD, + =NA7WM,=NC4OI,=NE7EK,=NH2GZ,=NH7UO,=NJ7H,=NM0H,=NN4NN,=NP4FU,=NW4G,=NW7F,=W0EZM,=W0FJN,=W0RWS, + =W0UZJ,=W1LYD,=W1RSC,=W1ZKA,=W2DLS,=W2KRZ,=W3JPN,=W3MKG,=W4AUL,=W4BMR,=W4RSB,=W5JKT,=W6DDP,=W6GTE, + =W6ROW,=W7APM,=W7DDG,=W7EIK,=W7JMR,=W7PWA,=W7RAZ,=W7ROS,=W7WEZ,=W7ZWT,=W8MDD,=W8PVZ,=W8TCX,=W9ITU, + =W9JMC,=WA0JS,=WA1FVJ,=WA2BGL,=WA2BIW,=WA6GFS,=WA7B,=WA7PXH,=WA7USX,=WA7YXF,=WB0CMZ,=WB1GZL, + =WB1ILS,=WB6COP,=WB7TYK,=WB9JZL,=WD6CET,=WH6CYY,=WH6DPL,=WH6DX,=WH7AK,=WJ8M,=WP4IYI,=WT5T,=WX1NCC; Navassa Island: 08: 11: NA: 18.40: 75.00: 5.0: KP1: KP1,NP1,WP1; US Virgin Islands: 08: 11: NA: 17.73: 64.80: 4.0: KP2: KP2,NP2,WP2,=AC7FX,=AJ2O,=K5KFL,=K5TP,=K8RF,=KA7KDU,=KB1MDZ,=KB1ZTY,=KB3ZUD,=KB9ALR,=KC9MCN, - =KD4SGB,=KD5QJN,=KF2HC,=KF4CGR,=KF4MSI,=KG4SZC,=KG5KHO,=KH2XQ,=KH2XR,=KI4FOE,=KI6BLD,=KJ6IR, - =KL7NZ,=KR7O/R,=KV4/W2KW,=KV4AD,=KV4BA,=KV4BT,=KV4BW,=KV4CF,=KV4CQ/P,=KV4DN,=KV4EY,=KV4FZ,=KV4HR, - =KV4IH,=KV4JC,=KV4KW,=N1TKK,=N1VKI,=W0AIH/KV4,=W0YNY,=W2AZK,=W2KW/KV4,=W3K/KD2CLB,=W4LIS,=WA4HLB, - =WB2KQW,=WB4WFU,=WD8AHQ,=WI7C; + =KD4SGB,=KD5QJN,=KF2HC,=KF4CGR,=KF4MSI,=KG4SZC,=KG5KHO,=KG6KVR,=KH2XQ,=KH2XR,=KI4FOE,=KI6BLD, + =KJ6IR,=KL7NZ,=KR7O/R,=KV4/W2KW,=KV4AD,=KV4BA,=KV4BT,=KV4BW,=KV4CF,=KV4CQ/P,=KV4DN,=KV4EY,=KV4FZ, + =KV4HR,=KV4IH,=KV4JC,=KV4KW,=N1TKK,=N1VKI,=W0AIH/KV4,=W0YNY,=W2AZK,=W2KW/KV4,=W3K/KD2CLB,=W4LIS, + =WA4HLB,=WB2KQW,=WB4WFU,=WD8AHQ,=WI7C; Puerto Rico: 08: 11: NA: 18.18: 66.55: 4.0: KP4: - KP3,KP4,NP3,NP4,WP3,WP4,=AA0WX,=AA2ZN,=AB2DR,=AF4OU,=AF5IZ,=AG4CD,=AI4EZ,=K1NDN,=K4C/LH,=K4PFH, - =K5YJR,=K6BOT,=K9JOS,=KA2GNG,=KA2MBR,=KA2YGB,=KA3ZGQ,=KA7URH,=KA9UTY,=KB0AQB,=KB0TEP,=KB1IJU, - =KB1KDP,=KB1RUQ,=KB1TUA,=KB1UEK,=KB1UZV,=KB1ZKF,=KB2ALR,=KB2CIE,=KB2KWB,=KB2MMX,=KB2NMT,=KB2NYN, - =KB2OIF,=KB2OMN,=KB2OPM,=KB2RYP,=KB2TID,=KB2VHY,=KB2WKT,=KB2YKJ,=KB3BPK,=KB3BTN,=KB3LUV,=KB3SBO, - =KB8ZVP,=KB9OWX,=KB9RZD,=KB9YVE,=KB9YVF,=KC1CRV,=KC1CUF,=KC1DRV,=KC1IHB,=KC1IHO,=KC1JLY,=KC2BZZ, - =KC2CJL,=KC2CTM,=KC2EMM,=KC2ERU,=KC2JNE,=KC2LET,=KC2TE,=KC2UXP,=KC2VCR,=KC3GEO,=KC5DKT,=KC8BFN, - =KC8IRI,=KD2KPC,=KD2VQ,=KD4TVS,=KD5DVV,=KD5PKH,=KD9GIZ,=KE0AYJ,=KE0GFK,=KE0SH,=KE1MA,=KE3WW, - =KE4GGD,=KE4GYA,=KE4SKH,=KE4THL,=KE4WUE,=KE5LNG,=KF4KPO,=KF4ZDB,=KF6OGJ,=KG4GYO,=KG4IRC,=KG4IVO, - =KG4VCC,=KG5AFY,=KH2RU,=KH4AA,=KI4LRJ,=KI4WOA,=KI4WOB,=KJ4LOZ,=KJ4UPN,=KJ6OV,=KK4AOZ,=KK4DCX, - =KK4EBE,=KK4PHB,=KM4VDZ,=KM4WGI,=KM4YBN,=KM4YSR,=KM4ZJW,=KM6CTO,=KN4AWH,=KN4GNO,=KN4IBD,=KN4IDV, - =KN4IGP,=KN4ILO,=KN4INP,=KN4JCC,=KN4KPX,=KN4KPY,=KN4MNT,=KN4NLZ,=KN4ODN,=KN4QBT,=KN4QZZ,=KN4REC, - =KN4SKZ,=KP2H,=KP2Z,=KP3CW/SKP,=KP3RE/LGT,=KP3RE/LH,=KP3RE/LT,=KP4ES/L,=KP4ES/LGT,=KP4ES/LH, - =KP4FD/IARU,=KP4FRD/LH,=KP4MD/P,=KP4VP/LH,=N0XAR,=N1CN,=N1HRV,=N1JFL,=N1QVU,=N1SCD,=N1SZM,=N1VCW, - =N1YAY,=N1ZJC,=N2KKN,=N2KUE,=N2PGO,=N3JAM,=N3VIJ,=N3YUB,=N3ZII,=N4CIE,=N4JZD,=N4LER,=N4UK,=N6NVD, - =N6RHF,=NB0G,=NP3M/LH,=NP4VO/LH,=W1AW/PR,=W6WAW,=W9JS,=WA2RVA,=WB2HMY,=WB5YOF,=WB7ADC,=WB7VVV, - =WD4LOL,=WP4L/TP,=WR8Z; + KP3,KP4,NP3,NP4,WP3,WP4,=AA0WX,=AA2ZN,=AB2DR,=AF4OU,=AF5IZ,=AG4CD,=AI4EZ,=K1NDN,=K4C/LH,=K4LCR, + =K4PFH,=K5YJR,=K6BOT,=K9JOS,=KA2GNG,=KA2MBR,=KA2YGB,=KA3ZGQ,=KA7URH,=KA9UTY,=KB0AQB,=KB0TEP, + =KB1IJU,=KB1KDP,=KB1RUQ,=KB1TUA,=KB1UEK,=KB1UZV,=KB1ZKF,=KB2ALR,=KB2CIE,=KB2KWB,=KB2MMX,=KB2NMT, + =KB2NYN,=KB2OIF,=KB2OMN,=KB2OPM,=KB2QQK,=KB2RYP,=KB2TID,=KB2VHY,=KB2WKT,=KB2YKJ,=KB3BPK,=KB3BTN, + =KB3LUV,=KB3SBO,=KB8ZVP,=KB9OWX,=KB9RZD,=KB9YVE,=KB9YVF,=KC1CRV,=KC1CUF,=KC1DRV,=KC1IHB,=KC1IHO, + =KC1JLY,=KC1KZI,=KC2BZZ,=KC2CJL,=KC2CTM,=KC2EMM,=KC2ERU,=KC2JNE,=KC2LET,=KC2TE,=KC2UXP,=KC2VCR, + =KC3GEO,=KC5DKT,=KC8BFN,=KC8IRI,=KD2KPC,=KD2VQ,=KD4TVS,=KD5DVV,=KD5PKH,=KD9GIZ,=KD9MRY,=KE0AYJ, + =KE0GFK,=KE0SH,=KE1MA,=KE3WW,=KE4GGD,=KE4GYA,=KE4SKH,=KE4THL,=KE4WUE,=KE5LNG,=KF4KPO,=KF4ZDB, + =KF6OGJ,=KG4GYO,=KG4IRC,=KG4IVO,=KG4VCC,=KG5AFY,=KH2RU,=KH4AA,=KI4LRJ,=KI4WOA,=KI4WOB,=KJ4KZN, + =KJ4LOZ,=KJ4UPN,=KJ6OV,=KK4AOZ,=KK4DCX,=KK4EBE,=KK4PHB,=KM4VDZ,=KM4WGI,=KM4YBN,=KM4YSR,=KM4ZJW, + =KM6CTO,=KN4AWH,=KN4GNO,=KN4IBD,=KN4IDV,=KN4IGP,=KN4ILO,=KN4INP,=KN4JCC,=KN4KPX,=KN4KPY,=KN4MNT, + =KN4NLZ,=KN4ODN,=KN4QBT,=KN4QZZ,=KN4REC,=KN4SKZ,=KN4TNC,=KN4UAN,=KP2H,=KP2Z,=KP3CW/SKP,=KP3RE/LGT, + =KP3RE/LH,=KP3RE/LT,=KP4ES/L,=KP4ES/LGT,=KP4ES/LH,=KP4FD/IARU,=KP4FRD/LH,=KP4MD/P,=KP4VP/LH, + =N0XAR,=N1CN,=N1HRV,=N1JFL,=N1QVU,=N1SCD,=N1SZM,=N1VCW,=N1YAY,=N1ZJC,=N2KKN,=N2KUE,=N2PGO,=N3JAM, + =N3VIJ,=N3YUB,=N3ZII,=N4CIE,=N4JZD,=N4LER,=N4UK,=N6NVD,=N6RHF,=NB0G,=NP3M/LH,=NP4VO/LH,=W1AW/PR, + =W6WAW,=W9JS,=WA2RVA,=WB2HMY,=WB5YOF,=WB7ADC,=WB7VVV,=WD4LOL,=WP4L/TP,=WR8Z; Desecheo Island: 08: 11: NA: 18.08: 67.88: 4.0: KP5: KP5,NP5,WP5; Norway: 14: 18: EU: 61.00: -9.00: -1.0: LA: @@ -1759,46 +1773,46 @@ Argentina: 13: 14: SA: -34.80: 65.92: 3.0: LU: =LU3DLF/D,=LU3DMZ/D,=LU3DO/D,=LU3DOC/D,=LU3DP/D,=LU3DPH/D,=LU3DQJ/D,=LU3DR/D,=LU3DRP/D,=LU3DRP/E, =LU3DXG/D,=LU3DXI/D,=LU3DY/D,=LU3DYN/D,=LU3DZO/D,=LU3EBS/D,=LU3ED/D,=LU3EDU/D,=LU3EFL/D,=LU3EJ/L, =LU3EJD/D,=LU3ELR/D,=LU3EMB/D,=LU3EOU/D,=LU3EP/D,=LU3ERU/D,=LU3ES/D,=LU3ESY/D,=LU3EZA/D,=LU3FCI/D, - =LU3HKA/D,=LU4AA/D,=LU4AAO/D,=LU4AAO/E,=LU4ACA/D,=LU4AJC/D,=LU4BAN/D,=LU4BR/D,=LU4CMF/D,=LU4DBL/D, - =LU4DBP/D,=LU4DBT/D,=LU4DBV/D,=LU4DCE/D,=LU4DCY/D,=LU4DGC/D,=LU4DHA/D,=LU4DHC/D,=LU4DHE/D, - =LU4DIS/D,=LU4DK/D,=LU4DLJ/D,=LU4DLL/D,=LU4DLN/D,=LU4DMI/D,=LU4DPB/D,=LU4DQ/D,=LU4DRC/D,=LU4DRH/D, - =LU4DRH/E,=LU4DVD/D,=LU4EAE/D,=LU4EET/D,=LU4EGP/D,=LU4EHP/D,=LU4EJ/D,=LU4EL/D,=LU4ELE/D,=LU4EOU/D, - =LU4ERS/D,=LU4ESP/D,=LU4ETD/D,=LU4ETN/D,=LU4EV/D,=LU4HSA/D,=LU4HTD/D,=LU4MA/D,=LU4UWZ/D,=LU4UZW/D, - =LU4VEN/D,=LU4VSD/D,=LU4WAP/D,=LU5AHN/D,=LU5ALS/D,=LU5AM/D,=LU5ANL/D,=LU5AQV/D,=LU5ARS/D, - =LU5ASA/D,=LU5AVD/D,=LU5BDS/D,=LU5BE/D,=LU5BTL/D,=LU5CBA/D,=LU5CRE/D,=LU5DA/D,=LU5DA/E,=LU5DAS/D, - =LU5DCO/D,=LU5DDH/D,=LU5DEM/D,=LU5DF/D,=LU5DFR/D,=LU5DFT/D,=LU5DGG/D,=LU5DGR/D,=LU5DHE/D, - =LU5DIT/D,=LU5DJE/D,=LU5DKE/D,=LU5DLH/D,=LU5DLT/D,=LU5DLZ/D,=LU5DMI/D,=LU5DMP/D,=LU5DMR/D, - =LU5DQ/D,=LU5DRV/D,=LU5DSH/D,=LU5DSM/D,=LU5DT/D,=LU5DTB/D,=LU5DTF/D,=LU5DUC/D,=LU5DVB/D,=LU5DWS/D, - =LU5DYT/D,=LU5EAO/D,=LU5EC/D,=LU5ED/D,=LU5EDS/D,=LU5EFG/D,=LU5EH/D,=LU5EHC/D,=LU5EJL/D,=LU5EM/D, - =LU5EP/D,=LU5EW/D,=LU5FZ/D,=LU5FZ/E,=LU5JAH/D,=LU5JIB/D,=LU5OD/D,=LU5VAS/D,=LU5VAT/D,=LU5XP/D, - =LU6AER/D,=LU6CN/D,=LU6DAX/D,=LU6DBL/D,=LU6DC/D,=LU6DCT/D,=LU6DDC/D,=LU6DG/D,=LU6DIE/D,=LU6DIO/D, - =LU6DKT/D,=LU6DL/D,=LU6DM/D,=LU6DO/D,=LU6DRD/D,=LU6DRD/E,=LU6DRN/D,=LU6DRR/D,=LU6DSA/D,=LU6DTB/D, - =LU6EAG/D,=LU6EC/D,=LU6EDC/D,=LU6EE/D,=LU6EEG/D,=LU6EGO/D,=LU6EI/D,=LU6EJJ/D,=LU6EKL/D,=LU6ELP/D, - =LU6EMM/D,=LU6ENA/D,=LU6EPE/D,=LU6EPR/D,=LU6EPR/E,=LU6EQV/D,=LU6EU/D,=LU6EVD/D,=LU6EWR/D, - =LU6EXD/D,=LU6HBB/D,=LU6JJ/D,=LU6UAL/D,=LU6UO/D,=LU6UVI/D,=LU6XQ/D,=LU7AA/D,=LU7AC/D,=LU7ADC/D, - =LU7ADN/D,=LU7ART/D,=LU7AVW/D,=LU7BSN/D,=LU7BTO/D,=LU7BTO/E,=LU7CAW/D,=LU7CP/D,=LU7DAC/D, - =LU7DAF/D,=LU7DAR/D,=LU7DBA/D,=LU7DBL/D,=LU7DCE/D,=LU7DD/D,=LU7DDC/D,=LU7DDO/D,=LU7DHG/D, - =LU7DJH/D,=LU7DLN/D,=LU7DNM/D,=LU7DOT/D,=LU7DP/D,=LU7DR/D,=LU7DS/D,=LU7DSC/D,=LU7DSS/D,=LU7DSU/D, - =LU7DSY/D,=LU7DTC/D,=LU7DZL/D,=LU7DZL/E,=LU7DZV/D,=LU7ECZ/D,=LU7EGY/D,=LU7EHL/D,=LU7EIA/D, - =LU7EJC/D,=LU7ELY/D,=LU7EMA/D,=LU7EMM/D,=LU7ENP/D,=LU7EO/D,=LU7EON/D,=LU7EPC/D,=LU7ETR/D, - =LU7HBL/D,=LU7HW/D,=LU7HZ/D,=LU7VCH/D,=LU8ABR/D,=LU8ACH/D,=LU8ADX/D,=LU8AE/D,=LU8ARI/D,=LU8ATM/D, - =LU8DAF/D,=LU8DCF/D,=LU8DCH/D,=LU8DCK/D,=LU8DCM/D,=LU8DIP/D,=LU8DIW/D,=LU8DJR/D,=LU8DLD/D, - =LU8DLT/D,=LU8DMD/D,=LU8DQ/D,=LU8DR/D,=LU8DRA/D,=LU8DRH/D,=LU8DRQ/D,=LU8DSJ/D,=LU8DTF/D,=LU8DUJ/D, - =LU8DVQ/D,=LU8DW/D,=LU8DWR/D,=LU8DX/D,=LU8DY/D,=LU8DZE/D,=LU8DZH/D,=LU8EAG/D,=LU8EAJ/D,=LU8EBJ/D, - =LU8EBJ/E,=LU8EBK/D,=LU8EBK/E,=LU8EC/D,=LU8ECF/D,=LU8ECF/E,=LU8EEM/D,=LU8EFF/D,=LU8EGC/D, - =LU8EGS/D,=LU8EHQ/D,=LU8EHQ/E,=LU8EHS/D,=LU8EHV/D,=LU8EKC/D,=LU8EMC/D,=LU8ERH/D,=LU8ETC/D, - =LU8EU/D,=LU8EXJ/D,=LU8EXN/D,=LU8FAU/D,=LU8VCC/D,=LU8VER/D,=LU9ACJ/D,=LU9AEA/D,=LU9AOS/D, - =LU9AUC/D,=LU9BRC/D,=LU9BSA/D,=LU9CGN/D,=LU9CLH/D,=LU9DA/D,=LU9DAA/D,=LU9DAD/D,=LU9DB/D,=LU9DE/D, - =LU9DEQ/D,=LU9DF/D,=LU9DGE/D,=LU9DKO/D,=LU9DMG/D,=LU9DO/D,=LU9DPD/D,=LU9DPI/D,=LU9DPZ/E,=LU9DSD/D, - =LU9DVO/D,=LU9EAG/D,=LU9ECE/D,=LU9EI/D,=LU9EIM/D,=LU9EJM/D,=LU9EJS/E,=LU9EJZ/D,=LU9ENH/D, - =LU9EOE/D,=LU9ERA/D,=LU9ESD/D,=LU9ESD/E,=LU9ESD/LH,=LU9EV/D,=LU9EV/E,=LU9EV/LH,=LU9EY/D,=LU9EYE/D, - =LU9EZX/D,=LU9HDR/D,=LU9HJV/D,=LU9HVR/D,=LU9USD/D,=LU9WM/D,=LV7E/D,=LW1DAL/D,=LW1DDX/D,=LW1DE/D, - =LW1DEN/D,=LW1DEW/D,=LW1DJ/D,=LW1DOG/D,=LW1DQQ/D,=LW1DVB/D,=LW1DXH/D,=LW1DXP/D,=LW1DYN/D, + =LU3HKA/D,=LU4AA/D,=LU4AAO/D,=LU4AAO/E,=LU4ACA/D,=LU4ADE/D,=LU4AJC/D,=LU4BAN/D,=LU4BR/D,=LU4CMF/D, + =LU4DBL/D,=LU4DBP/D,=LU4DBT/D,=LU4DBV/D,=LU4DCE/D,=LU4DCY/D,=LU4DGC/D,=LU4DHA/D,=LU4DHC/D, + =LU4DHE/D,=LU4DIS/D,=LU4DK/D,=LU4DLJ/D,=LU4DLL/D,=LU4DLN/D,=LU4DMI/D,=LU4DPB/D,=LU4DQ/D,=LU4DRC/D, + =LU4DRH/D,=LU4DRH/E,=LU4DVD/D,=LU4EAE/D,=LU4EET/D,=LU4EGP/D,=LU4EHP/D,=LU4EJ/D,=LU4EL/D,=LU4ELE/D, + =LU4EOU/D,=LU4ERS/D,=LU4ESP/D,=LU4ETD/D,=LU4ETN/D,=LU4EV/D,=LU4HSA/D,=LU4HTD/D,=LU4MA/D,=LU4UWZ/D, + =LU4UZW/D,=LU4VEN/D,=LU4VSD/D,=LU4WAP/D,=LU5AHN/D,=LU5ALS/D,=LU5AM/D,=LU5ANL/D,=LU5AQV/D, + =LU5ARS/D,=LU5ASA/D,=LU5AVD/D,=LU5BDS/D,=LU5BE/D,=LU5BTL/D,=LU5CBA/D,=LU5CRE/D,=LU5DA/D,=LU5DA/E, + =LU5DAS/D,=LU5DCO/D,=LU5DDH/D,=LU5DEM/D,=LU5DF/D,=LU5DFR/D,=LU5DFT/D,=LU5DGG/D,=LU5DGR/D, + =LU5DHE/D,=LU5DIT/D,=LU5DJE/D,=LU5DKE/D,=LU5DLH/D,=LU5DLT/D,=LU5DLZ/D,=LU5DMI/D,=LU5DMP/D, + =LU5DMR/D,=LU5DQ/D,=LU5DRV/D,=LU5DSH/D,=LU5DSM/D,=LU5DT/D,=LU5DTB/D,=LU5DTF/D,=LU5DUC/D,=LU5DVB/D, + =LU5DWS/D,=LU5DYT/D,=LU5EAO/D,=LU5EC/D,=LU5ED/D,=LU5EDS/D,=LU5EFG/D,=LU5EH/D,=LU5EHC/D,=LU5EJL/D, + =LU5EM/D,=LU5EP/D,=LU5EW/D,=LU5FZ/D,=LU5FZ/E,=LU5JAH/D,=LU5JIB/D,=LU5OD/D,=LU5VAS/D,=LU5VAT/D, + =LU5XP/D,=LU6AER/D,=LU6CN/D,=LU6DAX/D,=LU6DBL/D,=LU6DC/D,=LU6DCT/D,=LU6DDC/D,=LU6DG/D,=LU6DIE/D, + =LU6DIO/D,=LU6DKT/D,=LU6DL/D,=LU6DM/D,=LU6DO/D,=LU6DRD/D,=LU6DRD/E,=LU6DRN/D,=LU6DRR/D,=LU6DSA/D, + =LU6DTB/D,=LU6EAG/D,=LU6EC/D,=LU6EDC/D,=LU6EE/D,=LU6EEG/D,=LU6EGO/D,=LU6EI/D,=LU6EJJ/D,=LU6EKL/D, + =LU6ELP/D,=LU6EMM/D,=LU6ENA/D,=LU6EPE/D,=LU6EPR/D,=LU6EPR/E,=LU6EQV/D,=LU6EU/D,=LU6EVD/D, + =LU6EWR/D,=LU6EXD/D,=LU6HBB/D,=LU6JJ/D,=LU6UAL/D,=LU6UO/D,=LU6UVI/D,=LU6XQ/D,=LU7AA/D,=LU7AC/D, + =LU7ADC/D,=LU7ADN/D,=LU7ART/D,=LU7AVW/D,=LU7BSN/D,=LU7BTO/D,=LU7BTO/E,=LU7CAW/D,=LU7CP/D, + =LU7DAC/D,=LU7DAF/D,=LU7DAR/D,=LU7DBA/D,=LU7DBL/D,=LU7DCE/D,=LU7DD/D,=LU7DDC/D,=LU7DDO/D, + =LU7DHG/D,=LU7DJH/D,=LU7DLN/D,=LU7DNM/D,=LU7DOT/D,=LU7DP/D,=LU7DR/D,=LU7DS/D,=LU7DSC/D,=LU7DSS/D, + =LU7DSU/D,=LU7DSY/D,=LU7DTC/D,=LU7DZL/D,=LU7DZL/E,=LU7DZV/D,=LU7ECZ/D,=LU7EGY/D,=LU7EHL/D, + =LU7EIA/D,=LU7EJC/D,=LU7ELY/D,=LU7EMA/D,=LU7EMM/D,=LU7ENP/D,=LU7EO/D,=LU7EON/D,=LU7EPC/D, + =LU7ETR/D,=LU7HBL/D,=LU7HW/D,=LU7HZ/D,=LU7VCH/D,=LU8ABR/D,=LU8ACH/D,=LU8ADX/D,=LU8AE/D,=LU8ARI/D, + =LU8ATM/D,=LU8DAF/D,=LU8DCF/D,=LU8DCH/D,=LU8DCK/D,=LU8DCM/D,=LU8DIP/D,=LU8DIW/D,=LU8DJR/D, + =LU8DLD/D,=LU8DLT/D,=LU8DMD/D,=LU8DQ/D,=LU8DR/D,=LU8DRA/D,=LU8DRH/D,=LU8DRQ/D,=LU8DSJ/D,=LU8DTF/D, + =LU8DUJ/D,=LU8DVQ/D,=LU8DW/D,=LU8DWR/D,=LU8DX/D,=LU8DY/D,=LU8DZE/D,=LU8DZH/D,=LU8EAG/D,=LU8EAJ/D, + =LU8EBJ/D,=LU8EBJ/E,=LU8EBK/D,=LU8EBK/E,=LU8EC/D,=LU8ECF/D,=LU8ECF/E,=LU8EEM/D,=LU8EFF/D, + =LU8EGC/D,=LU8EGS/D,=LU8EHQ/D,=LU8EHQ/E,=LU8EHS/D,=LU8EHV/D,=LU8EKC/D,=LU8EMC/D,=LU8ERH/D, + =LU8ETC/D,=LU8EU/D,=LU8EXJ/D,=LU8EXN/D,=LU8FAU/D,=LU8VCC/D,=LU8VER/D,=LU9ACJ/D,=LU9AEA/D, + =LU9AOS/D,=LU9AUC/D,=LU9BRC/D,=LU9BSA/D,=LU9CGN/D,=LU9CLH/D,=LU9DA/D,=LU9DAA/D,=LU9DAD/D,=LU9DB/D, + =LU9DE/D,=LU9DEQ/D,=LU9DF/D,=LU9DGE/D,=LU9DKO/D,=LU9DMG/D,=LU9DO/D,=LU9DPD/D,=LU9DPI/D,=LU9DPZ/E, + =LU9DSD/D,=LU9DVO/D,=LU9EAG/D,=LU9ECE/D,=LU9EI/D,=LU9EIM/D,=LU9EJM/D,=LU9EJS/E,=LU9EJZ/D, + =LU9ENH/D,=LU9EOE/D,=LU9ERA/D,=LU9ESD/D,=LU9ESD/E,=LU9ESD/LH,=LU9EV/D,=LU9EV/E,=LU9EV/LH,=LU9EY/D, + =LU9EYE/D,=LU9EZX/D,=LU9HDR/D,=LU9HJV/D,=LU9HVR/D,=LU9USD/D,=LU9WM/D,=LV7E/D,=LW1DAL/D,=LW1DDX/D, + =LW1DE/D,=LW1DEN/D,=LW1DEW/D,=LW1DJ/D,=LW1DOG/D,=LW1DQQ/D,=LW1DVB/D,=LW1DXH/D,=LW1DXP/D,=LW1DYN/D, =LW1DYP/D,=LW1ECE/D,=LW1ECO/D,=LW1ELI/D,=LW1EQI/D,=LW1EQZ/D,=LW1EVO/D,=LW1EXU/D,=LW2DAW/D, =LW2DET/D,=LW2DJM/D,=LW2DNC/D,=LW2DOD/D,=LW2DOM/D,=LW2DSM/D,=LW2DX/E,=LW2DYA/D,=LW2ECK/D, =LW2ECM/D,=LW2EFS/D,=LW2EHD/D,=LW2ENB/D,=LW2EQS/D,=LW2EUA/D,=LW3DAB/D,=LW3DBM/D,=LW3DC/D, =LW3DED/D,=LW3DER/D,=LW3DFP/D,=LW3DG/D,=LW3DGC/D,=LW3DJC/D,=LW3DKC/D,=LW3DKC/E,=LW3DKO/D, - =LW3DKO/E,=LW3DN/D,=LW3DRW/D,=LW3DSR/D,=LW3DTD/D,=LW3EIH/D,=LW3EMP/D,=LW4DAF/D,=LW4DBE/D, + =LW3DKO/E,=LW3DN/D,=LW3DRW/D,=LW3DSR/D,=LW3DTD/D,=LW3EIH/D,=LW3EK/D,=LW3EMP/D,=LW4DAF/D,=LW4DBE/D, =LW4DBM/D,=LW4DCV/D,=LW4DKI/D,=LW4DOR/D,=LW4DRH/D,=LW4DRH/E,=LW4DRV/D,=LW4DTM/D,=LW4DTR/D, =LW4DWV/D,=LW4DXH/D,=LW4ECV/D,=LW4EIN/D,=LW4EM/D,=LW4EM/E,=LW4EM/LH,=LW4ERO/D,=LW4ESY/D,=LW4ETG/D, =LW4EZT/D,=LW4HCL/D,=LW5DAD/D,=LW5DD/D,=LW5DFR/D,=LW5DHG/D,=LW5DIE/D,=LW5DLY/D,=LW5DNN/D, @@ -1840,8 +1854,8 @@ Argentina: 13: 14: SA: -34.80: 65.92: 3.0: LU: =LU7JMS/J,=LU7JR/J,=LU7JRM/J,=LU8JOP/J,=LU9JLV/J,=LU9JMG/J,=LU9JPR/J,=LU9YB/J,=LW2DRJ/J,=LW3EMP/J, =LU1KWC/K,=LU2KLC/K,=LU4KC/K,=LU5OM/K,=LU6KAQ/K,=LU7KHB/K,=LU7KT/K,=LU8KE/K,=LW1EVO/K,=LW3DFP/K, =LU1AAS/L,=LU1DZ/L,=LU1LAA/L,=LU1LT/L,=LU1LTL/L,=LU2LDB/L,=LU3AYE/L,=LU4AGC/L,=LU4EFC/L,=LU4LAD/L, - =LU4LBU/L,=LU4LMA/L,=LU5FZ/L,=LU5ILA/L,=LU5LAE/L,=LU5LBV/L,=LU6JRA/L,=LU8IEZ/L,=LU8LFV/L,=LU9JX/L, - =LU9LEW/L,=LU9LZY/L,=LU9LZZ/L,=LU9XPA/L,=LW3EMP/L,=LW8DTO/L, + =LU4LBU/L,=LU4LMA/L,=LU5FZ/L,=LU5ILA/L,=LU5LAE/L,=LU5LBV/L,=LU6JRA/L,=LU8IEZ/L,=LU8LFV/L, + =LU9GOY/L,=LU9JX/L,=LU9LEW/L,=LU9LZY/L,=LU9LZZ/L,=LU9XPA/L,=LW3EMP/L,=LW8DTO/L, =LU3PCJ/MA,=LW4DBE/MA, =LU2DSV/N,=LU3AAL/N,=LU5BE/N,=LU5FZ/N,=LU8EFF/N,=LW5DR/N, =LU1HZY/O,=LU1XS/O,=LU2HON/O,=LU3HL/O,=LU4AA/O,=LU5BOJ/O,=LU5OD/O,=LU6FEC/O,=LU6HWT/O,=LU8OAH/O, @@ -2048,7 +2062,7 @@ Denmark: 14: 18: EU: 56.00: -10.00: -1.0: OZ: =OZ2GBW/LH,=OZ2NYB/LGT,=OZ2NYB/LH,=OZ2ZB/LH,=OZ3EDR/LH,=OZ3EVA/LH,=OZ3FYN/LH,=OZ3TL/JOTA, =OZ4EL/LH,=OZ50RN/LH,=OZ5ESB/LH,=OZ7AEI/LH,=OZ7DAL/LH,=OZ7DAL/LS,=OZ7EA/YL,=OZ7HAM/LH,=OZ7LH/LH, =OZ7RJ/LGT,=OZ7RJ/LH,=OZ7SP/JOTA,=OZ7TOM/LH,=OZ8KV/LH,=OZ8SMA/LGT,=OZ8SMA/LH,=OZ9HBO/JOTA, - =OZ9HBO/LH,=OZ9WSR/J; + =OZ9HBO/LH,=OZ9WSR/J,=VERSION; Papua New Guinea: 28: 51: OC: -9.50: -147.12: -10.0: P2: P2; Aruba: 09: 11: SA: 12.53: 69.98: 4.0: P4: @@ -2063,18 +2077,19 @@ Netherlands: 14: 27: EU: 52.28: -5.47: -1.0: PA: =PA3CPI/JOTA,=PA3DEW/J,=PA3EEQ/LH,=PA3EFR/J,=PA3ESO/J,=PA3EWG/J,=PA3FBO/LH,=PA3FYE/J,=PA3GAG/LH, =PA3GQS/J,=PA3GWN/J,=PA3HFJ/J,=PA3WSK/JOTA,=PA40LAB/J,=PA4RVS/MILL,=PA4WK/J,=PA5CA/LH,=PA65DUIN/J, =PA65URK/LH,=PA6ADZ/MILL,=PA6ARC/LH,=PA6FUN/LGT,=PA6FUN/LH,=PA6FUN/LS,=PA6HOOP/MILL,=PA6HYG/J, - =PA6JAM/J,=PA6KMS/MILL,=PA6LH/LH,=PA6LL/LH,=PA6LST/LH,=PA6LST/LS,=PA6MZD/MILL,=PA6RCG/J,=PA6SB/L, - =PA6SB/LH,=PA6SCH/LH,=PA6SHB/J,=PA6SJB/J,=PA6SJS/J,=PA6STAR/MILL,=PA6URK/LH,=PA6VEN/LH,=PA6VLD/LH, - =PA6WAD/LGT,=PA70HYG/JOTA,=PA75SM/J,=PA7AL/LH,=PA7HPH/J,=PA7JWC/J,=PA99HYG/JOTA,=PA9M/LH,=PB6F/LH, - =PB6KW/LH,=PB88XYL/YL,=PB9ZR/J,=PC2D/LH,=PD0ARI/MILL,=PD0FSB/LH,=PD1JL/MILL,=PD1JSH/J,=PD2C/LH, - =PD2GCM/LH,=PD5CW/LH,=PD5MVH/P/LH,=PD7DX/J,=PE18KA/J,=PE1NCS/LGT,=PE1NCS/LH,=PE1NZJ/J,=PE1OPM/LH, - =PE1OXI/J,=PE1RBG/J,=PE1RBR/J,=PE2MC/J,=PE2MGA/J,=PF100ROVER/J,=PF18NAWAKA/J,=PF4R/LH,=PG150N/LH, - =PG6HK/LH,=PG6N/LH,=PH4RTM/MILL,=PH4RTM/WHE,=PH50GFB/J,=PH6BB/J,=PH6WAL/LH,=PH75S/J,=PH9GFB/J, - =PI4ADH/LGT,=PI4ADH/LH,=PI4ADH/LS,=PI4ALK/LH,=PI4AZL/J,=PI4BG/J,=PI4BOZ/LH,=PI4CQ/J,=PI4DHG/DM, - =PI4DHG/MILL,=PI4ET/MILL,=PI4ETL/MILL,=PI4F/LH,=PI4LDN/L,=PI4LDN/LH,=PI4RCK/LGT,=PI4RCK/LH, - =PI4RIS/J,=PI4S/J,=PI4SHV/J,=PI4SRN/LH,=PI4SRN/MILL,=PI4VNW/LGT,=PI4VNW/LH,=PI4VPO/LH,=PI4VPO/LT, - =PI4WAL/LGT,=PI4WAL/LH,=PI4WBR/LH,=PI4WFL/MILL,=PI4YLC/LH,=PI4ZHE/LH,=PI4ZHE/LS,=PI4ZHE/MILL, - =PI4ZVL/FD,=PI4ZVL/LGT,=PI4ZVL/LH,=PI9NHL/LH,=PI9SRS/LH,=PI9TP/J; + =PA6JAM/J,=PA6KMS/MILL,=PA6LH/LH,=PA6LL/LH,=PA6LST/LH,=PA6LST/LS,=PA6MZD/MILL,=PA6OP/MILL, + =PA6RCG/J,=PA6SB/L,=PA6SB/LH,=PA6SCH/LH,=PA6SHB/J,=PA6SJB/J,=PA6SJS/J,=PA6STAR/MILL,=PA6URK/LH, + =PA6VEN/LH,=PA6VLD/LH,=PA6WAD/LGT,=PA70HYG/JOTA,=PA75SM/J,=PA7AL/LH,=PA7HPH/J,=PA7JWC/J, + =PA99HYG/JOTA,=PA9M/LH,=PB6F/LH,=PB6KW/LH,=PB88XYL/YL,=PB9ZR/J,=PC2D/LH,=PD0ARI/MILL,=PD0FSB/LH, + =PD1JL/MILL,=PD1JSH/J,=PD2C/LH,=PD2GCM/LH,=PD5CW/LH,=PD5MVH/P/LH,=PD7DX/J,=PE18KA/J,=PE1NCS/LGT, + =PE1NCS/LH,=PE1NZJ/J,=PE1OPM/LH,=PE1OXI/J,=PE1RBG/J,=PE1RBR/J,=PE2MC/J,=PE2MGA/J,=PF100ROVER/J, + =PF18NAWAKA/J,=PF4R/LH,=PG150N/LH,=PG64HOOP/MIL,=PG6HK/LH,=PG6N/LH,=PH4RTM/MILL,=PH4RTM/WHE, + =PH50GFB/J,=PH6BB/J,=PH6WAL/LH,=PH75S/J,=PH9GFB/J,=PI4ADH/LGT,=PI4ADH/LH,=PI4ADH/LS,=PI4ALK/LH, + =PI4AZL/J,=PI4BG/J,=PI4BOZ/LH,=PI4CQ/J,=PI4DHG/DM,=PI4DHG/MILL,=PI4ET/MILL,=PI4ETL/MILL,=PI4F/LH, + =PI4LDN/L,=PI4LDN/LH,=PI4RCK/LGT,=PI4RCK/LH,=PI4RIS/J,=PI4S/J,=PI4SHV/J,=PI4SRN/LH,=PI4SRN/MILL, + =PI4VNW/LGT,=PI4VNW/LH,=PI4VPO/LH,=PI4VPO/LT,=PI4WAL/LGT,=PI4WAL/LH,=PI4WBR/LH,=PI4WFL/MILL, + =PI4YLC/LH,=PI4ZHE/LH,=PI4ZHE/LS,=PI4ZHE/MILL,=PI4ZVL/FD,=PI4ZVL/LGT,=PI4ZVL/LH,=PI4ZWN/MILL, + =PI9NHL/LH,=PI9SRS/LH,=PI9TP/J; Curacao: 09: 11: SA: 12.17: 69.00: 4.0: PJ2: PJ2; Bonaire: 09: 11: SA: 12.20: 68.25: 4.0: PJ4: @@ -2178,7 +2193,7 @@ Greece: 20: 28: EU: 39.78: -21.78: -2.0: SV: =SV5KJQ/8,=SV8/DJ5AA/LH,=SV8/LY1DF/LGT,=SV9GPM/8,=SW8SW/LH,=SX8DI/LH,=SZ8LES/LH,=SZ8XIO/J, =SZ8XIO/P/JOTA; Mount Athos: 20: 28: EU: 40.00: -24.00: -2.0: SV/a: - =SV2/SV1RP/T,=SV2ASP/A,=SV2RSG/A,=SY2A; + =SV2/SV1RP/T,=SV2ASP,=SV2ASP/A,=SV2ASP/P,=SV2RSG/A,=SY2A; Dodecanese: 20: 28: EU: 36.17: -27.93: -2.0: SV5: J45,SV5,SW5,SX5,SY5,SZ5,=J42004/SP5MXZ,=J45FRE/J,=SV0XAN/5,=SV0XBZ/5,=SV0XCA/5,=SV0XCA/P, =SV1ENJ/5,=SV1GSX/5,=SV5/DJ5AA/LH,=SV5/LY1DF/LGT,=SV5CJQ/LH,=SV9DJO/5,=SV9GPV/5,=SV9JI/5, @@ -2247,35 +2262,34 @@ Benin: 35: 46: AF: 9.87: -2.25: -1.0: TY: Mali: 35: 46: AF: 18.00: 2.58: 0.0: TZ: TZ; European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA: - R,U,=R0CAF/1,=R25EMW(17)[19],=R7AB/M,=R7AB/P,=R80PSP,=R80UPOL,=R8CT/4/P,=R8FF/3/M,=R90DOSAAF, - =R9AV/6,=R9FAZ/6/M,=R9FCH/6,=R9JI/1,=R9KC/6/M,=R9WR/1,=R9XAU/6,=RA0AM/6,=RA0BM/6,=RA0ZZ/3, - =RA2FDX/3,=RA3CQ/9/M(17)[20],=RA80SP,=RA9JR/3,=RA9JX/3,=RA9P/4,=RA9RT/3,=RA9UUY/6,=RA9YA/6, - =RC80SP,=RG0F/5,=RG50P(17),=RG50P/9(17)[30],=RJ80SP,=RK80X(17)[19],=RK8O/4,=RL9AA/6,=RM80SP, - =RM8A/4/M,=RM94AE,=RN9M/4,=RN9OI/3,=RO80RO,=RP61XX(17)[19],=RP62X(17)[19],=RP63X(17)[19], - =RP63XO(17)[19],=RP64X(17)[19],=RP65FPP(17)[30],=RP8X(17)[30],=RQ80SP,=RU0ZW/6,=RU2FB/3, - =RU2FB/3/P,=RU4SS/9(17)[30],=RU4WA/9(17)[30],=RV9LM/3,=RV9XX/3,=RW0IM/1,=RW0QE/6,=RW2F/6,=RW9FF/3, - =RW9W/3,=RW9W/4,=RX2FS/3,=RX9TC/1,=RX9UL/1,=RZ9AWN/6,=UA0AK/3,=UA0FQ/6,=UA0KBG/3,=UA0KBG/6, - =UA0KCX/3/P,=UA0KT/4,=UA0QNE/3,=UA0QNU/3,=UA0QQJ/3,=UA0UV/6,=UA0XAK/3,=UA0XAK/6,=UA0ZL/6, - =UA9CCO/6,=UA9CTT/3,=UA9CTT/6,=UA9FFS/1/MM,=UE23DKA,=UE6MAC/9(17),=UE95AE,=UE95E,=UE95ME,=UE96ME, - =UE99PS, + R,U,=R0CAF/1,=R25EMW(17)[19],=R7AB/M,=R80PSP,=R80UPOL,=R8CT/4/P,=R8FF/3/M,=R90DOSAAF,=R9AV/6, + =R9FAZ/6/M,=R9FCH/6,=R9JI/1,=R9KC/6/M,=R9WR/1,=R9XAU/6,=RA0AM/6,=RA0BM/6,=RA0ZZ/3, + =RA3CQ/9/M(17)[20],=RA80SP,=RA9JR/3,=RA9JX/3,=RA9P/4,=RA9RT/3,=RA9UUY/6,=RA9YA/6,=RC80SP,=RG0F/5, + =RG50P(17),=RG50P/9(17)[30],=RJ80SP,=RK80X(17)[19],=RK8O/4,=RL9AA/6,=RM80SP,=RM8A/4/M,=RM94AE, + =RN9M/4,=RN9OI/3,=RO80RO,=RP61XX(17)[19],=RP62X(17)[19],=RP63X(17)[19],=RP63XO(17)[19], + =RP64X(17)[19],=RP65FPP(17)[30],=RP8X(17)[30],=RQ80SP,=RU0ZW/6,=RU2FB/3,=RU2FB/3/P, + =RU4SS/9(17)[30],=RU4WA/9(17)[30],=RV9LM/3,=RV9XX/3,=RW0IM/1,=RW0QE/6,=RW2F/6,=RW9FF/3,=RW9W/3, + =RW9W/4,=RX2FS/3,=RX9TC/1,=RX9UL/1,=RZ9AWN/6,=UA0AK/3,=UA0FQ/6,=UA0KBG/3,=UA0KBG/6,=UA0KCX/3/P, + =UA0KT/4,=UA0QNE/3,=UA0QNU/3,=UA0QQJ/3,=UA0UV/6,=UA0XAK/3,=UA0XAK/6,=UA0ZL/6,=UA9CCO/6,=UA9CTT/3, + =UA9CTT/6,=UA9FFS/1/MM,=UE23DKA,=UE6MAC/9(17),=UE95AE,=UE95E,=UE95ME,=UE96ME,=UE99PS, =R900BL,=R9J/1,=RA2FN/1,=RA9KU/1,=RA9KU/1/M,=RA9MC/1,=RA9SGI/1,=RK9XWV/1,=RL1O,=RM0L/1,=RM80DZ, - =RN85AM,=RN85KN,=RT9T/1,=RU2FB/1,=RU9YT/1,=RU9YT/1/P,=RV1CC/M,=RW1AI/ANT,=RW8W/1,=RW9QA/1, - =RX3AMI/1/LH,=UA1ADQ/ANT,=UA1BJ/ANT,=UA1JJ/ANT,=UA2FFX/1,=UA9B/1,=UA9KG/1,=UA9KGH/1,=UA9KK/1, - =UA9UDX/1,=UB9YUW/1,=UE21A,=UE21B,=UE21M,=UE22A,=UE25AC,=UE25AQ,=UE2AT/1, - =R0XAC/1,=R900DM,=R90LPU,=R9JNO/1,=RA0FU/1,=RA9FNV/1,=RU9MU/1,=RV0CA/1,=RV2FW/1,=RV9JD/1,=RX9TN/1, - =UA0BDS/1,=UA0SIK/1,=UA1CDA/LH,=UA1CIO/LH,=UA9MQR/1,=UB5O/1, + =RN85AM,=RN85KN,=RT9T/1,=RU2FB/1,=RU9YT/1,=RU9YT/1/P,=RW1AI/ANT,=RW8W/1,=RW9QA/1,=UA1ADQ/ANT, + =UA1BJ/ANT,=UA1JJ/ANT,=UA2FFX/1,=UA9B/1,=UA9KG/1,=UA9KGH/1,=UA9KK/1,=UA9UDX/1,=UB9YUW/1,=UE21A, + =UE21B,=UE21M,=UE22A,=UE25AC,=UE25AQ,=UE2AT/1, + =R0XAC/1,=R8XF/1,=R900DM,=R90LPU,=R9JNO/1,=RA0FU/1,=RA9FNV/1,=RN9N/1,=RU9MU/1,=RV0CA/1,=RV1CC/M, + =RV2FW/1,=RV9JD/1,=RX9TN/1,=UA0BDS/1,=UA0SIK/1,=UA1CDA/LH,=UA1CIO/LH,=UA9MQR/1,=UB5O/1, R1N[19],RA1N[19],RC1N[19],RD1N[19],RE1N[19],RF1N[19],RG1N[19],RJ1N[19],RK1N[19],RL1N[19],RM1N[19], RN1N[19],RO1N[19],RQ1N[19],RT1N[19],RU1N[19],RV1N[19],RW1N[19],RX1N[19],RY1N[19],RZ1N[19],U1N[19], UA1N[19],UB1N[19],UC1N[19],UD1N[19],UE1N[19],UF1N[19],UG1N[19],UH1N[19],UI1N[19],=R01DTV/1[19], =R85KFF[19],=R90K[19],=RN1NA/ANT[19],=RO25KL[19],=RP72PT[19],=RP72RK[19],=RP73PT[19],=RP73RK[19], - =RV1CC/1[19],=RV9JD/1/M[19], + =RP74PT[19],=RP74RK[19],=RV9JD/1/M[19],=RX3AMI/1/LH[19], R1O[19],RA1O[19],RC1O[19],RD1O[19],RE1O[19],RF1O[19],RG1O[19],RJ1O[19],RK1O[19],RL1O[19],RM1O[19], RN1O[19],RO1O[19],RQ1O[19],RT1O[19],RU1O[19],RV1O[19],RW1O[19],RX1O[19],RY1O[19],RZ1O[19],U1O[19], UA1O[19],UB1O[19],UC1O[19],UD1O[19],UE1O[19],UF1O[19],UG1O[19],UH1O[19],UI1O[19],=R0000O[19], =R100K[19],=R20ARRS[19],=R25ILIM[19],=R8FF/1[19],=R9LI/1[19],=R9MCM/1[19],=RA0NN/1[19], =RA9XA/1[19],=RA9XA/1/P[19],=RK0SE/1[19],=RM9X/1[19],=RO80KEDR[19],=RP72A[19],=RP73A[19], - =RP73AU[19],=UA1PAC/ANT[19],=UA9UAX/1[19],=UA9UAX/1/M[19],=UA9XK/1[19],=UA9XMC/1[19], - =UA9XRK/1[19],=UE25IK[19],=UE80AR[19],=UE80AR/M[19],=UE80AR/P[19], + =RP73AU[19],=RP74A[19],=RP74AU[19],=UA1PAC/ANT[19],=UA9UAX/1[19],=UA9UAX/1/M[19],=UA9XK/1[19], + =UA9XMC/1[19],=UA9XRK/1[19],=UE25IK[19],=UE80AR[19],=UE80AR/M[19],=UE80AR/P[19], R1P[20],RA1P[20],RC1P[20],RD1P[20],RE1P[20],RF1P[20],RG1P[20],RJ1P[20],RK1P[20],RL1P[20],RM1P[20], RN1P[20],RO1P[20],RQ1P[20],RT1P[20],RU1P[20],RV1P[20],RW1P[20],RX1P[20],RY1P[20],RZ1P[20],U1P[20], UA1P[20],UB1P[20],UC1P[20],UD1P[20],UE1P[20],UF1P[20],UG1P[20],UH1P[20],UI1P[20],=R8XW/1[20], @@ -2283,16 +2297,16 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA: =RK1PWA/ANT[20],=RL1P[20],=RN2FA/1[20],=UA1PAC/1/ANT[20],=UA9FOJ/1[20],=UA9MRY/1[20], =UA9XRP/1[20], =R9FM/1,=RA0BM/1,=RA0BM/1/P,=RA1QQ/LH,=RU9MX/1,=RW9XC/1,=UA1QV/ANT,=UA9XC/1,=UE80GS, - =R88EPC,=R95NRL,=RA9FBV/1,=RA9SC/1,=RA9XY/1,=RV2FW/1/M,=RZ0IWW/1,=UA9XF/1,=UE9WFF/1, + =R88EPC,=R95NRL,=RA9FBV/1,=RA9SC/1,=RA9XY/1,=RV1CC/1,=RV2FW/1/M,=RZ0IWW/1,=UA9XF/1,=UE9WFF/1, =RA0ZD/1,=RP9X/1,=RP9XWM/1,=UE25WDW,=UE9XBW/1,=UF2F/1/M, R1Z[19],RA1Z[19],RC1Z[19],RD1Z[19],RE1Z[19],RF1Z[19],RG1Z[19],RJ1Z[19],RK1Z[19],RL1Z[19],RM1Z[19], RN1Z[19],RO1Z[19],RQ1Z[19],RT1Z[19],RU1Z[19],RV1Z[19],RW1Z[19],RX1Z[19],RY1Z[19],RZ1Z[19],U1Z[19], UA1Z[19],UB1Z[19],UC1Z[19],UD1Z[19],UE1Z[19],UF1Z[19],UG1Z[19],UH1Z[19],UI1Z[19],=R25RRA[19], =RA9CFH/1[19],=RA9CFH/1/P[19],=RK21Z[19],=RK3DZJ/1/LH[19],=RM9WN/1[19],=RP72MU[19],=RP73MU[19], - =RP73ZP[19],=RU1ZC/ANT[19],=RW1ZQ/LH[19],=RY83HN[19],=UB1ZBD/N[19], - =R01DTV/3,=R85PAR,=R870B,=R870C,=R870K,=R870M,=R870O,=R9FM/3,=RA2AT,=RA9CO/3,=RA9USU/3,=RC85MP, - =RL3AB/FF,=RT2F/3/M,=RT9K/3,=RW0LF/3,=RX9UL/3,=RX9WN/3,=RZ9UA/3,=UA0KCX/3,=UA3AV/ANT,=UA8AA/3, - =UA8AA/5,=UA9KHD/3,=UA9MDU/3,=UA9MRX/3,=UA9QCP/3,=UA9UAX/3,=UE24SU, + =RP73ZP[19],=RP74ZP[19],=RU1ZC/ANT[19],=RW1ZQ/LH[19],=RY83HN[19],=UB1ZBD/N[19], + =R01DTV/3,=R1712M,=R85PAR,=R870B,=R870C,=R870K,=R870M,=R870O,=R9FM/3,=RA2AT,=RA2FDX/3,=RA9CO/3, + =RA9USU/3,=RC85MP,=RL3AB/FF,=RT2F/3/M,=RT9K/3,=RW0LF/3,=RX9UL/3,=RX9WN/3,=RZ9UA/3,=UA0KCX/3, + =UA3AV/ANT,=UA8AA/3,=UA8AA/5,=UA9KHD/3,=UA9MDU/3,=UA9MRX/3,=UA9QCP/3,=UA9UAX/3,=UE24SU, =R85QMR,=R85WDW,=R8B,=R8FF/3,=R90DNF,=R99FSB,=RA0BY/3,=RA80KEDR,=RA9KV/3,=RA9SB/3,=RA9XY/3, =RK3DSW/ANT,=RK3DWA/3/N,=RN9MD/3,=RT80KEDR,=RU0LM/3,=RU2FA/3,=RU3HD/ANT,=RV0AO/3,=RV9LM/3/P, =RW0IM/3,=RW3DU/N,=RW9UEW/3,=RX9SN/3,=RZ9SZ/3,=RZ9W/3,=UA0JAD/3,=UA0KCL/3,=UA0ZAZ/3,=UA9AJ/3/M, @@ -2300,31 +2314,31 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA: =R80ORL,=UA0QGM/3,=UE80O,=UE80OL, =R0CAF/3,=R3GO/FF,=RM0L/3,=RN3GL/FF,=RN3GW/FF,=RT5G/P/FF,=RW0IW/3,=UA3GM/ANT,=UE90FL, =RA9KT/3,=RZ9SZ/3/M,=UA0FHC/3,=UF2F/3/M, - =R0IA/3,=R863LC,=R863LK,=R863LX,=R875R,=R9XZ/3,=RG80KEDR,=RL80KEDR,=RN0CF/3,=RU9QRP/3,=RZ90W/3, - =UA9JFM/3,=UA9XZ/3,=UE80G,=UE80V,=UE80YG, + =R0IA/3,=R17SMW,=R863LC,=R863LK,=R863LX,=R875R,=R9XZ/3,=RG80KEDR,=RL80KEDR,=RN0CF/3,=RU9QRP/3, + =RZ90W/3,=UA9JFM/3,=UA9XZ/3,=UE80G,=UE80V,=UE80YG, =RK3MXT/FF,=RV9AZ/3,=UA0AD/3, =R870T,=RT90PK,=RU0ZW/3,=RW0UM/3,=RW9JV/3, - =RA0CCV/3,=RA0QA/3,=RC9YA/3/P,=RM8X/3,=RV9LC/3,=UA0QJE/3,=UA0QQO/3,=UA9CGL/3,=UA9JLY/3,=UA9XLE/3, - =UB0AJJ/3,=UC0LAF/3,=UE25AFG,=UE25R,=UE27AFG,=UE28AFG,=UE96SN, - =R80RTL,=R90IARU,=R9CZ/3,=RU80TO,=RZ9HK/3/P, + =R17CWB,=RA0CCV/3,=RA0QA/3,=RC9YA/3/P,=RM8X/3,=RV9LC/3,=UA0QJE/3,=UA0QQO/3,=UA9CGL/3,=UA9JLY/3, + =UA9XLE/3,=UB0AJJ/3,=UB5O/M,=UC0LAF/3,=UE25AFG,=UE25R,=UE27AFG,=UE28AFG,=UE96SN, + =R17TCNY,=R80RTL,=R90IARU,=R9CZ/3,=RU80TO,=RZ9HK/3/P, =R920RZ,=R95DOD,=RA0QQ/3,=UA0KBA/3,=UE80S,=UE85NKN,=UE85WDW, =R3TT/FF,=R8FF/M,=R8TA/4/P,=R8TR/3,=R90NOR,=R9KW/3,=R9KW/4,=R9PA/4,=RA9AP/3,=RA9CKQ/4,=RA9KW/3, =RA9KW/3/M,=RA9ST/3/P,=RG9A/3/P,=RM9T/4/P,=RN0CT/4,=RT9S/3,=RT9S/3/P,=RT9S/4,=RU9LA/4,=RV9FQ/3, =RV9FQ/3/M,=RV9WB/4,=RV9WLE/3/P,=RV9WZ/3,=RW9KW/3,=RW9WA/3,=RX9SN/P,=UA0ADX/3,=UA0DM/4,=UA0S/4, =UA0SC/4,=UA9APA/3/P,=UA9CTT/4,=UA9PM/4,=UA9SSR/3,=UE200TARS,=UE25TF,=UE9FDA/3,=UE9FDA/3/M, =UE9WDA/3,=UI8W/3/P, - =R5VAJ/N,=R850G,=R850PN,=RT9T/3,=RU0BW/3,=RU9MU/3,=RV80KEDR,=RX9TL/3, + =R170VN,=R5VAJ/N,=R850G,=R850PN,=RT9T/3,=RU0BW/3,=RU9MU/3,=RV80KEDR,=RX9TL/3, =R110A/P,=R80PVB, =RA9XF/3,=RC80KEDR,=RD0L/3,=RK0BWW/3,=RN80KEDR,=RW9XC/3/M,=RX3XX/N,=UA0KBA/3/P,=UA9SIV/3, =UE0ZOO/3, - =R100WWS,=R85WTA,=R8FF/3/P,=R98KPM,=R99KPM,=RA3YV/ANT,=RK0UT/3,=RW0LX/3,=UA3YH/ANT,=UA9KZ/3, - =UB8JAF/3,=UE91L,=UE95K,=UE95RA, + =R85WTA,=R8FF/3/P,=R98KPM,=R99KPM,=RA3YV/ANT,=RK0UT/3,=RW0LX/3,=UA3YH/ANT,=UA9KZ/3,=UB8JAF/3, + =UE91L,=UE95K,=UE95RA, =R3ZK/FF,=RA3ZZ/ANT,=RA9AK/3,=RA9KD/3,=RU3ZK/FF,=RW0BG/3,=UA0QBC/3, =RA07DR,=RA9ODR/4/M,=RC4AF/FF,=RN4ACA/FF,=RU9CK/6/M,=UA4ASE/FF,=UA4ATL/FF,=UA8WAA/6,=UA9FGR/4, =UE00S,=UE00S/P,=UE09VG,=UE80RWW, - =R4CDX/FF,=R8FF/4,=R8FR/4/M,=RA9KO/4,=RL96WS,=RL97WS,=RU80KEDR,=RU80KEDR/P,=RU9SO/4/M,=RV4CC/FF, - =RV9CX/4/M,=RW0UZ/4,=RW9AW/4/M,=RZ0SB/4,=UA0KAT/4,=UA8WAA/4,=UA9AGR/4/M,=UA9JPX/4,=UA9OC/4, - =UE23DZO,=UE95MS,=UE95WS,=UE98WS,=UE99PW, + =R1747PS,=R4CDX/FF,=R8FF/4,=R8FR/4/M,=RA9KO/4,=RL96WS,=RL97WS,=RU80KEDR,=RU80KEDR/P,=RU9SO/4/M, + =RV4CC/FF,=RV9CX/4/M,=RW0UZ/4,=RW9AW/4/M,=RZ0SB/4,=UA0KAT/4,=UA8WAA/4,=UA9AGR/4/M,=UA9JPX/4, + =UA9OC/4,=UE23DZO,=UE95MS,=UE95WS,=UE98WS,=UE99PW, =R9CMA/4,=R9JBN/4, R4H[30],R4I[30],RA4H[30],RA4I[30],RC4H[30],RC4I[30],RD4H[30],RD4I[30],RE4H[30],RE4I[30],RF4H[30], RF4I[30],RG4H[30],RG4I[30],RJ4H[30],RJ4I[30],RK4H[30],RK4I[30],RL4H[30],RL4I[30],RM4H[30], @@ -2337,11 +2351,12 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA: =R4IT[29],=R9DA/4[30],=RA4HL[29],=RA9FAA/4/M[30],=RA9SC/4[30],=RA9SC/4/P[30],=RC18SA[30], =RC20HZ[30],=RC4HT[29],=RC4I[29],=RC9YA/4/M[30],=RJ4I[29],=RK4HM[29],=RM4I[29],=RN4HFJ[29], =RN4HIF[29],=RN9S/M[30],=RP72AG[30],=RP72I[30],=RP72MF[30],=RP72WO[30],=RP73DD[30],=RP73I[30], - =RP73PM[30],=RT9K/4[30],=RU4HD[29],=RU4HP[29],=RU4I[29],=RU9CK/4/M[30],=RV9JD/4/M[30],=RW4HM[29], - =RW4HTK[29],=RW4HW[29],=RW4HZ[29],=RW9SW/4[30],=RW9TP/4[30],=RW9WJ/4[30],=RW9WJ/4/P[30], - =RW9WJ/P[30],=RZ4HWF/LH[30],=RZ4HZW/FF[30],=RZ9WU/4/M[30],=UA0KAO/4[30],=UA0QJA/4[30],=UA4H[29], - =UA4HBM[29],=UA4HGL[29],=UA4HIP[29],=UA4HIP/M[30],=UA4HRZ[29],=UA4HY[29],=UA9JGX/4[30], - =UA9LAO/4[30],=UA9SQG/4/P[30],=UA9SY/4[30],=UC4I[29],=UI4I[29], + =RP73PM[30],=RP74DD[30],=RP74I[30],=RT9K/4[30],=RU4HD[29],=RU4HP[29],=RU4I[29],=RU9CK/4/M[30], + =RV9JD/4/M[30],=RW4HM[29],=RW4HTK[29],=RW4HW[29],=RW4HZ[29],=RW9SW/4[30],=RW9TP/4[30], + =RW9WJ/4[30],=RW9WJ/4/P[30],=RW9WJ/P[30],=RZ4HWF/LH[30],=RZ4HZW/FF[30],=RZ9WU/4/M[30], + =UA0KAO/4[30],=UA0QJA/4[30],=UA4H[29],=UA4HBM[29],=UA4HGL[29],=UA4HIP[29],=UA4HIP/M[30], + =UA4HRZ[29],=UA4HY[29],=UA9JGX/4[30],=UA9LAO/4[30],=UA9SQG/4/P[30],=UA9SY/4[30],=UC4I[29], + =UI4I[29], =R01DTV/4,=R9XC/4,=RA9XAF/4,=UA4HIP/4,=UA9JFE/4, =R8XF/4,=RA4NCC[30],=RA9FR/4/P,=RA9XSM/4,=RD9CX/4,=RD9CX/4/P,=RU0LM/4,=RW9XC/4/M,=UA4NE/M, =UA4NF[30],=UA4NF/M,=UA9APA/4/P,=UA9FIT/4,=UA9XI/4,=UE9FDA/4,=UE9FDA/4/M,=UE9GDA/4, @@ -2355,7 +2370,8 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA: RN4W[30],RO4W[30],RQ4W[30],RT4W[30],RU4W[30],RV4W[30],RW4W[30],RX4W[30],RY4W[30],RZ4W[30],U4W[30], UA4W[30],UB4W[30],UC4W[30],UD4W[30],UE4W[30],UF4W[30],UG4W[30],UH4W[30],UI4W[30],=R0CM/4[30], =R9GM/4[30],=R9UT/4[30],=RA9FDR/4/P[30],=RA9KV/4/M[30],=RA9WU/4[30],=RA9WU/4/M[30],=RA9WU/4/P[30], - =RP72IZ[30],=RP73IZ[30],=RW9FWB/4[30],=RW9FWR/4[30],=RW9FWR/4/M[30],=RX9FW/4[30],=UA9UAX/4/M[30], + =RP72IZ[30],=RP73IZ[30],=RP74IZ[30],=RW9FWB/4[30],=RW9FWR/4[30],=RW9FWR/4/M[30],=RX9FW/4[30], + =UA9UAX/4/M[30], =RT9T/4,=RV9MD/4,=UA4PCM/M,=UE04YCS,=UE85AGN, =R01DTV,=R01DTV/7,=R0IT/6,=R80TV,=R8XW/6,=R9JO/6,=R9KD/6,=R9OM/6,=R9WGM/6/M,=RA0APW/6,=RA0FW/6, =RA0LIF/6,=RA0LLW/6,=RA0QR/6,=RA9ODR/6,=RA9ODR/6/M,=RA9SAS/6,=RA9UWD/6,=RA9WW/6,=RD9CX/6, @@ -2375,7 +2391,7 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA: =R8FF/6,=R9DA/6,=RU9CK/6/P,=RV9CX/6/P,=UA9CES/6,=UA9FGR/6,=UA9WQK/6, =RU9CK/7/M,=RU9CK/7/P,=RV9CX/7/P,=UA9JFN/6/M, =RT9K/7/P,=RZ7G/6/FF, - =R01DTV/6,=RV9AB/6,=UB5O/M, + =R01DTV/6,=R7AB/P,=RV9AB/6, =R9MJ/6,=R9OM/5/P,=R9XT/6,=RA9KD/6,=RN9N/6,=RT9T/6,=RT9T/6/M,=RU2FB/5,=RU9WW/5/M,=RW9AW/5, =UA0LLM/5,=UA8WAA/5,=UA9CDC/6,=UA9UAX/5,=UE2KR,=UE98PW, =R8AEU/6,=R9MJ/6/M,=RN9N/6/M,=UB8ADI/5,=UB8ADI/6,=UE2SE, @@ -2401,17 +2417,21 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA: =R2014WOG(17)[30],=R20PRM(17)[30],=R2AG/9(17)[30],=R34CZF(17)[30],=R6DAB/9(17)[30], =R8CZ/4(17)[30],=R8CZ/4/M(17)[30],=R8CZ/M(17)[30],=R95FR(17)[30],=R9CZ/4(17)[30], =R9CZ/4/M(17)[30],=R9KC/4/M(17)[30],=R9KC/8/M(17)[30],=RA27FM(17)[30],=RA9XAI/4(17)[30], - =RC20FM(17)[30],=RD4M/9(17)[30],=RG50P/M(17)[30],=RP70PK(17)[30],=RP9FKU(17)[30],=RP9FTK(17)[30], - =RU27FQ(17)[30],=RU27FW(17)[30],=RU4W/9(17)[30],=RV22PM(17)[30],=RX9TX/9(17)[30],=RZ16FM(17)[30], - =RZ9WM/9(17)[30],=UA1ZQO/9(17)[30],=UA4NF/4/M(17)[30],=UA4WA/9(17)[30],=UA9CGL/4/M(17)[30], - =UA9CUA/4/M(17)[30],=UA9UAX/4(17)[30],=UE16SA(17)[30],=UE55PM(17)[30], + =RC20FM(17)[30],=RD4M/9(17)[30],=RG50P/M(17)[30],=RN9N/4(17)[30],=RP70PK(17)[30],=RP9FKU(17)[30], + =RP9FTK(17)[30],=RU27FQ(17)[30],=RU27FW(17)[30],=RU4W/9(17)[30],=RV22PM(17)[30],=RX9TX/9(17)[30], + =RZ16FM(17)[30],=RZ9WM/9(17)[30],=UA1ZQO/9(17)[30],=UA3FQ/4(17)[30],=UA3FQ/4/P(17)[30], + =UA4NF/4/M(17)[30],=UA4WA/9(17)[30],=UA9CGL/4/M(17)[30],=UA9CUA/4/M(17)[30],=UA9UAX/4(17)[30], + =UE16SA(17)[30],=UE55PM(17)[30], =RW3TN/9(17)[30],=UE10SK(17)[30], - R8X(17)[20],R9X(17)[20],RA8X(17)[20],RA9X(17)[20],RC8X(17)[20],RC9X(17)[20],RD8X(17)[20], - RD9X(17)[20],RE8X(17)[20],RE9X(17)[20],RF8X(17)[20],RF9X(17)[20],RG8X(17)[20],RG9X(17)[20], - RI8X(17)[20],RI9X(17)[20],RJ8X(17)[20],RJ9X(17)[20],RK8X(17)[20],RK9X(17)[20],RL8X(17)[20], - RL9X(17)[20],RM8X(17)[20],RM9X(17)[20],RN8X(17)[20],RN9X(17)[20],RO8X(17)[20],RO9X(17)[20], - RQ8X(17)[20],RQ9X(17)[20],RT8X(17)[20],RT9X(17)[20],RU8X(17)[20],RU9X(17)[20],RV8X(17)[20], - RV9X(17)[20],RW8X(17)[20],RW9X(17)[20],RX8X(17)[20],RX9X(17)[20],RY8X(17)[20],RY9X(17)[20], + R1I(17)[20],R8X(17)[20],R9X(17)[20],RA1I(17)[20],RA8X(17)[20],RA9X(17)[20],RC1I(17)[20], + RC8X(17)[20],RC9X(17)[20],RD1I(17)[20],RD8X(17)[20],RD9X(17)[20],RE1I(17)[20],RE8X(17)[20], + RE9X(17)[20],RF1I(17)[20],RF8X(17)[20],RF9X(17)[20],RG1I(17)[20],RG8X(17)[20],RG9X(17)[20], + RI8X(17)[20],RI9X(17)[20],RJ1I(17)[20],RJ8X(17)[20],RJ9X(17)[20],RK1I(17)[20],RK8X(17)[20], + RK9X(17)[20],RL1I(17)[20],RL8X(17)[20],RL9X(17)[20],RM1I(17)[20],RM8X(17)[20],RM9X(17)[20], + RN1I(17)[20],RN8X(17)[20],RN9X(17)[20],RO1I(17)[20],RO8X(17)[20],RO9X(17)[20],RQ1I(17)[20], + RQ8X(17)[20],RQ9X(17)[20],RT1I(17)[20],RT8X(17)[20],RT9X(17)[20],RU1I(17)[20],RU8X(17)[20], + RU9X(17)[20],RV1I(17)[20],RV8X(17)[20],RV9X(17)[20],RW1I(17)[20],RW8X(17)[20],RW9X(17)[20], + RX1I(17)[20],RX8X(17)[20],RX9X(17)[20],RY1I(17)[20],RY8X(17)[20],RY9X(17)[20],RZ1I(17)[20], RZ8X(17)[20],RZ9X(17)[20],U8X(17)[20],U9X(17)[20],UA8X(17)[20],UA9X(17)[20],UB8X(17)[20], UB9X(17)[20],UC8X(17)[20],UC9X(17)[20],UD8X(17)[20],UD9X(17)[20],UE8X(17)[20],UE9X(17)[20], UF8X(17)[20],UF9X(17)[20],UG8X(17)[20],UG9X(17)[20],UH8X(17)[20],UH9X(17)[20],UI8X(17)[20], @@ -2424,11 +2444,10 @@ European Russia: 16: 29: EU: 53.65: -41.37: -4.0: UA: =RA4NH/9(17)[20],=RA4NV/9(17)[20],=RA6ACI/9(17)[20],=RD4CBQ/9(17)[20],=RK1OWZ/9(17)[20], =RK1OWZ/9/M(17)[20],=RK6K/9(17)[20],=RK90DR(17)[20],=RN22OG(17)[20],=RN22OV(17)[20], =RN4ACZ/9(17)[20],=RO25KO(17)[20],=RP67KR(17)[20],=RP68KR(17)[20],=RP70KW(17)[20],=RP71KW(17)[20], - =RP72X(17)[20],=RP73X(17)[20],=RT73LF(17)[20],=RV3UI/9(17)[20],=RW1QN/9(17)[20], + =RP72X(17)[20],=RP73X(17)[20],=RP74X(17)[20],=RT73LF(17)[20],=RV3UI/9(17)[20],=RW1QN/9(17)[20], =RW1QN/9/M(17)[20],=RW1QN/9/P(17)[20],=RW4NJ/9/M(17)[20],=RY110RAEM(17)[20],=UA1OOX/9(17)[20], - =UA1QV/9(17)[20],=UA3FQ/4(17)[20],=UA4WP/9/M(17)[20],=UA6LTO/9(17)[20],=UB1OAD/1/P(17)[20], - =UB1OAD/9/P(17)[20],=UB5O/1/M(17)[20],=UE16ST(17)[20],=UE1RDA/9(17)[20],=UE85DRK(17)[20], - =UE90K(17)[20]; + =UA1QV/9(17)[20],=UA4WP/9/M(17)[20],=UA6LTO/9(17)[20],=UB1OAD/1/P(17)[20],=UB1OAD/9/P(17)[20], + =UB5O/1/M(17)[20],=UE16ST(17)[20],=UE1RDA/9(17)[20],=UE85DRK(17)[20],=UE90K(17)[20]; Kaliningrad: 15: 29: EU: 54.72: -20.52: -3.0: UA2: R2F,R2K,RA2,RC2F,RC2K,RD2F,RD2K,RE2F,RE2K,RF2F,RF2K,RG2F,RG2K,RJ2F,RJ2K,RK2F,RK2K,RL2F,RL2K,RM2F, RM2K,RN2F,RN2K,RO2F,RO2K,RQ2F,RQ2K,RT2F,RT2K,RU2F,RU2K,RV2F,RV2K,RW2F,RW2K,RX2F,RX2K,RY2F,RY2K, @@ -2454,15 +2473,16 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =RA4AAJ/9(18),=RD17CW(19),=RD1AL/0(40)[75],=RD3ARX/0/P(19),=RI18POL(40)[75],=RJ17WG,=RL19WF, =RM17NY,=RM19WF(18),=RN17CW,=RO19WF(19),=RQ17CW(18),=RQ17WG,=RQ4D/9(18),=RU17NY(18),=RV3PZ/9, =RW1AI/0(19),=RW55YG,=RX17WG(19),=RX55YG(18),=RX80SP(18),=RY1AAB/0/M(19),=RY80SP(19),=RZ17NY(19), - =RZ6A/9,=RZ9YI/9,=UA0ZDA/MM(29),=UA3DND/8,=UA3TT/8,=UE18M,=UE18U(18),=UE18Z(19), + =RZ6A/9,=RZ9YI/9,=UA0ZDA/MM(29),=UA3DND/8,=UA3TT/8,=UD6AOP/0(19),=UE18M,=UE18U(18),=UE18Z(19), =R100RG,=R120RG,=R2014Y,=R2015TL,=R20UFO,=R22SKE,=R280A,=R280B,=R3HD/9,=R3RRC/8,=R55TV,=R6RA/9, =R70PW,=R70PW/P,=R9SRR,=RA1AIP/9/P,=RA1AR/9,=RA1QR/9,=RA3WJ/9,=RA3XBN/9,=RA3ZM/8,=RA4FSC/9, =RA4HGN/9,=RA9SC/9,=RA9WJV/8/P,=RC20AB,=RC20AC,=RD3BN/9,=RD4CAQ/9,=RG110RAEM,=RJ17CW,=RK9SZZ/9, =RL5G/8,=RL9AA/P,=RN4WA/9,=RN9O/8,=RP67TG,=RP68MZ,=RP70AZ,=RP70PM,=RP70TG,=RP71AZ,=RP71TG,=RP72AZ, - =RP72MS,=RP72TG,=RP73AZ,=RP73TG,=RP73U,=RQ4D/8,=RT60RT,=RT73AB,=RU22AZ,=RV1AQ/9,=RV1CC/8,=RV1CC/9, - =RV3BA/9,=RV9WB/9/M,=RV9WMZ/9/P,=RV9WMZ/P,=RX3RC/9,=RX9WN/9/M,=RZ0OO/9,=RZ6DR/9/M,=RZ9OO/9/M, - =UA0MF/9,=UA3AKO/8,=UA4RC/9,=UA6A/9,=UA6CW/9,=UA6YGY/8,=UA6YGY/9,=UA8WAA/9,=UA8WAA/9/P,=UA8WAA/M, - =UA9CGL/9/M,=UA9SG/9,=UA9TO/9/M,=UA9WMN/9/P,=UB5O/8,=UE45AWT,=UE70AAA,=UE9WDA/9, + =RP72MS,=RP72TG,=RP73AZ,=RP73TG,=RP73U,=RP74AZ,=RP74TG,=RP74U,=RQ4D/8,=RT60RT,=RT73AB,=RU22AZ, + =RV1AQ/9,=RV1CC/8,=RV1CC/9,=RV3BA/9,=RV9WB/9/M,=RV9WMZ/9/P,=RV9WMZ/P,=RX3RC/9,=RX9WN/9/M,=RZ0OO/9, + =RZ6DR/9/M,=RZ9OO/9/M,=UA0MF/9,=UA3AKO/8,=UA4RC/9,=UA6A/9,=UA6CW/9,=UA6YGY/8,=UA6YGY/9,=UA8WAA/9, + =UA8WAA/9/P,=UA8WAA/M,=UA9CGL/9/M,=UA9SG/9,=UA9TO/9/M,=UA9WMN/9/P,=UB5O/8,=UE45AWT,=UE70AAA, + =UE9WDA/9, =R01DTV/8,=R14CWC/8,=R14CWC/9,=R150DMP,=R155AP,=R15CWC/8,=R15CWC/8/QRP,=R160DMP,=R16SVK,=R170GS/8, =R2015BP,=R2015R,=R2016DR,=R20EKB,=R22SKJ,=R27EKB,=R30ZF,=R35CZF,=R375I,=R44YETI/8,=R4WAB/9/P, =R55EPC,=R55EPC/P,=R6UAE/9,=R70NIK,=R7LZ/8,=R8FF/8,=R9GM/8,=R9GM/8/M,=RA/DL6XK,=RA/US5ETV, @@ -2470,10 +2490,11 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =RD0B/8,=RK9AD/9/M,=RK9DR/N,=RM0B/9,=RM19NY,=RN16CW,=RN3QBG/9,=RP68DT,=RP68RG,=RP68TG,=RP68TK, =RP69GR,=RP70DT,=RP70G,=RP70GB,=RP70GR,=RP70MA,=RP70SA,=RP70UH,=RP71DT,=RP71GA,=RP71GA/M,=RP71GB, =RP71GR,=RP71LT,=RP71MO,=RP71SA,=RP72DT,=RP72FI,=RP72GB,=RP72GR,=RP72IM,=RP72KB,=RP72SA,=RP73DT, - =RP73GB,=RP73GR,=RP73IM,=RP73SA,=RT4C/8,=RT4W/9,=RT73BR,=RT73EB,=RT73FL,=RT73HE,=RT73KB,=RT73SK, - =RU22CR,=RU5D/8,=RU5D/9,=RV6LGY/9,=RV6LGY/9/M,=RV6LGY/9/P,=RV6MD/9,=RW4NX/9,=RW9C[20],=RX0SD/9, - =RX3Q/9,=RX9UL/9,=RY9C/P,=RZ37ZF,=RZ38ZF,=RZ39ZF,=UA0BA/8,=UA3FQ/8,=UA3IHJ/8,=UA4WHX/9,=UA8WAA/8, - =UA9MW/9,=UA9UAX/8,=UA9UAX/8/M,=UE16SR,=UE25F,=UE40CZF,=UE4NFF/9,=UE56S,=UE64RWA,=UE70SL,=UE75DT, + =RP73GB,=RP73GR,=RP73IM,=RP73SA,=RP74DT,=RP74GB,=RP74GR,=RP74IM,=RT4C/8,=RT4W/9,=RT73BR,=RT73EB, + =RT73FL,=RT73HE,=RT73KB,=RT73SK,=RU22CR,=RU5D/8,=RU5D/9,=RV6LGY/9,=RV6LGY/9/M,=RV6LGY/9/P, + =RV6MD/9,=RW4NX/9,=RW9C[20],=RX0SD/9,=RX3Q/9,=RX9UL/9,=RY9C/P,=RZ37ZF,=RZ38ZF,=RZ39ZF,=UA0BA/8, + =UA3FQ/8,=UA3IHJ/8,=UA4WHX/9,=UA8WAA/8,=UA9MW/9,=UA9UAX/8,=UA9UAX/8/M,=UE16SR,=UE25F,=UE40CZF, + =UE4NFF/9,=UE56S,=UE64RWA,=UE70SL,=UE75DT, R8H(18)[31],R8I(18)[31],R9H(18)[31],R9I(18)[31],RA8H(18)[31],RA8I(18)[31],RA9H(18)[31], RA9I(18)[31],RC8H(18)[31],RC8I(18)[31],RC9H(18)[31],RC9I(18)[31],RD8H(18)[31],RD8I(18)[31], RD9H(18)[31],RD9I(18)[31],RE8H(18)[31],RE8I(18)[31],RE9H(18)[31],RE9I(18)[31],RF8H(18)[31], @@ -2497,21 +2518,21 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =RQ9I(18)[31],=RU9AZ/9(18)[31],=RV3LO/9(18)[31],=RZ9HK/FF(18)[31],=RZ9HX/FF(18)[31], =UA9JFN/9/M(18)[31],=UA9MUY/9(18)[31],=UA9OAP/9/P(18)[31],=UA9UAX/9/M(18)[31],=UE14TS(18)[31], =UE9FDA/9(18)[31], - R8J[20],R9J[20],RA8J[20],RA9J[20],RC8J[20],RC9J[20],RD8J[20],RD9J[20],RE8J[20],RE9J[20],RF8J[20], - RF9J[20],RG8J[20],RG9J[20],RJ8J[20],RJ9J[20],RK8J[20],RK9J[20],RL8J[20],RL9J[20],RM8J[20], - RM9J[20],RN8J[20],RN9J[20],RO8J[20],RO9J[20],RQ8J[20],RQ9J[20],RT8J[20],RT9J[20],RU8J[20], - RU9J[20],RV8J[20],RV9J[20],RW8J[20],RW9J[20],RX8J[20],RX9J[20],RY8J[20],RY9J[20],RZ8J[20], - RZ9J[20],U8J[20],U9J[20],UA8J[20],UA9J[20],UB8J[20],UB9J[20],UC8J[20],UC9J[20],UD8J[20],UD9J[20], - UE8J[20],UE9J[20],UF8J[20],UF9J[20],UG8J[20],UG9J[20],UH8J[20],UH9J[20],UI8J[20],UI9J[20], - =R120RJ[20],=R123JDR[20],=R15UGRA[20],=R16UGRA[20],=R18KSA[20],=R25ARCK/8[20],=R2AEA/9[20], - =R4YAC/9[20],=R8JAJ/M[20],=RA/UR8IF[20],=RA/UT2LA[20],=RA1QBH/9[20],=RA3ARS/9[20],=RA3ARS/9/M[20], - =RA3QQI/8[20],=RA4FCJ/9[20],=RA4HRM/9[20],=RA9WN/9[20],=RD4HM/9[20],=RJ9J[20],=RK4PA/9[20], - =RK6ANP/9[20],=RK6YM/8[20],=RK6YM/9[20],=RP67GS[20],=RP68GS[20],=RP68J[20],=RP68LK[20], - =RP69GS[20],=RP69SF[20],=RP70GS[20],=RP70LF[20],=RP70SF[20],=RP70SU[20],=RP70YF[20],=RP71GS[20], - =RP71LF[20],=RP71SF[20],=RP72DS[20],=RP72GS[20],=RP72SF[20],=RP72YF[20],=RP73GS[20],=RP73SF[20], - =RQ0C/8[20],=RU6YD/9[20],=RV6YM/9[20],=RW4HOH/9[20],=RW4LX/9[20],=RW6AHV/9[20],=RW9WX/9[20], - =RX3BP/9[20],=RX3BP/9/MM[20],=RZ5D/8[20],=RZ9WF/8[20],=RZ9WF/9[20],=UA3ZAF/9[20],=UA6WIO/9[20], - =UA9JFN/M[20], + R17[20],R8J[20],R9J[20],RA8J[20],RA9J[20],RC8J[20],RC9J[20],RD8J[20],RD9J[20],RE8J[20],RE9J[20], + RF8J[20],RF9J[20],RG8J[20],RG9J[20],RJ8J[20],RJ9J[20],RK8J[20],RK9J[20],RL8J[20],RL9J[20], + RM8J[20],RM9J[20],RN8J[20],RN9J[20],RO8J[20],RO9J[20],RQ8J[20],RQ9J[20],RT8J[20],RT9J[20], + RU8J[20],RU9J[20],RV8J[20],RV9J[20],RW8J[20],RW9J[20],RX8J[20],RX9J[20],RY8J[20],RY9J[20], + RZ8J[20],RZ9J[20],U8J[20],U9J[20],UA8J[20],UA9J[20],UB8J[20],UB9J[20],UC8J[20],UC9J[20],UD8J[20], + UD9J[20],UE8J[20],UE9J[20],UF8J[20],UF9J[20],UG8J[20],UG9J[20],UH8J[20],UH9J[20],UI8J[20], + UI9J[20],=R11UND[20],=R120RJ[20],=R123JDR[20],=R15UGRA[20],=R16UGRA[20],=R18KSA[20], + =R25ARCK/8[20],=R2AEA/9[20],=R4YAC/9[20],=R8JAJ/M[20],=RA/UR8IF[20],=RA/UT2LA[20],=RA1QBH/9[20], + =RA3ARS/9[20],=RA3ARS/9/M[20],=RA3QQI/8[20],=RA4FCJ/9[20],=RA4HRM/9[20],=RA60PD[20],=RA9WN/9[20], + =RD4HM/9[20],=RJ9J[20],=RK4PA/9[20],=RK6ANP/9[20],=RK6YM/8[20],=RK6YM/9[20],=RP67GS[20], + =RP68GS[20],=RP68J[20],=RP68LK[20],=RP69GS[20],=RP69SF[20],=RP70GS[20],=RP70LF[20],=RP70SF[20], + =RP70SU[20],=RP70YF[20],=RP71GS[20],=RP71LF[20],=RP71SF[20],=RP72DS[20],=RP72GS[20],=RP72SF[20], + =RP72YF[20],=RP73GS[20],=RP73SF[20],=RP74GS[20],=RQ0C/8[20],=RU6YD/9[20],=RV6YM/9[20], + =RW4HOH/9[20],=RW4LX/9[20],=RW6AHV/9[20],=RW9WX/9[20],=RX3BP/9[20],=RX3BP/9/MM[20],=RZ5D/8[20], + =RZ9WF/8[20],=RZ9WF/9[20],=UA3ZAF/9[20],=UA6WIO/9[20],=UA9JFN/M[20], R8K[20],R9K[20],RA8K[20],RA9K[20],RC8K[20],RC9K[20],RD8K[20],RD9K[20],RE8K[20],RE9K[20],RF8K[20], RF9K[20],RG8K[20],RG9K[20],RI9K[20],RJ8K[20],RJ9K[20],RK8K[20],RK9K[20],RL8K[20],RL9K[20], RM8K[20],RM9K[20],RN8K[20],RN9K[20],RO8K[20],RO9K[20],RQ8K[20],RQ9K[20],RT8K[20],RT9K[20], @@ -2527,16 +2548,16 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =UA1FBP/9[20],=UA1PBA/9[20],=UA1PBP/9[20],=UA3DFM/8[20],=UA3DFM/9[20],=UA3MGA/9[20],=UA6BTN/9[20], =UA9SUV/8[20], =R11QRP/8,=R11QRP/8/P,=R120RL,=R18POR,=R2015EP,=R2015LY,=R2015LY/8,=R22BIA,=R30STM,=R430LT, - =R4FAA/8,=R8MC/9,=R8MD/9,=RA/EW8ADX,=RA0UAC/8,=RA0UF/8,=RA3CW/9,=RA9JG/9,=RC1M/8/M,=RN9N/M, - =RO25TN,=RP67JH,=RP67LK,=RP67LL,=RP67TT,=RP68LS,=RP68TT,=RP69CM,=RP69DK,=RP69GP,=RP69LK,=RP69LL, - =RP69LS,=RP69MM,=RP69P,=RP69YN,=RP70GP,=RP70LL,=RP70LM,=RP70P,=RP70TM,=RP71GP,=RP71LL,=RP71P, - =RP72GP,=RP72LL,=RP72P,=RP72PJ,=RP73LL,=RP73P,=RR110RAEM,=RU22LR,=RW0QJ/9,=RX4W/8,=RX6DL/8, + =R4FAA/8,=R8MC/9,=R8MD/9,=RA/EW8ADX,=RA0UAC/8,=RA0UF/8,=RA3CW/9,=RA9JG/9,=RC1M/8/M,=RO25TN, + =RP67JH,=RP67LK,=RP67LL,=RP67TT,=RP68LS,=RP68TT,=RP69CM,=RP69DK,=RP69GP,=RP69LK,=RP69LL,=RP69LS, + =RP69MM,=RP69P,=RP69YN,=RP70GP,=RP70LL,=RP70LM,=RP70P,=RP70TM,=RP71GP,=RP71LL,=RP71P,=RP72GP, + =RP72LL,=RP72P,=RP72PJ,=RP73LL,=RP73P,=RP74LL,=RP74P,=RR110RAEM,=RU22LR,=RW0QJ/9,=RX4W/8,=RX6DL/8, =RX6DL/8/P,=RX6DL/8/P/QRP,=RX6DL/9/P,=RZ9MXM/9/M,=UB5O/8/P,=UE44Y/8,=UE9FDA/9/M,=UE9MDA/9, =R16CAN,=R1716K,=R1716M,=R1716O,=R1716S,=R9MJ/M,=RA22MX,=RA4CQ/9/M,=RA9MR/0,=RA9MX/P,=RC20MX, - =RK6YYA/9,=RN0SZ/9,=RN9N/9,=RP65MOH,=RP67MC,=RP67MD,=RP68MC,=RP68MD,=RP69MC,=RP69MD,=RP70GK, - =RP70MC,=RP70MD,=RP70OB,=RP70OF,=RP70OS,=RP71GK,=RP71MJ,=RP71OB,=RP72GK,=RP72MJ,=RP72OB,=RP72ZW, - =RP73GK,=RP73OB,=RP8M,=RT22MC,=RT22MD,=RV0SR/9,=RW22MW,=RY22MC,=UA1ZGD/9,=UA3AKO/9,=UA9UAX/M, - =UE55OM,=UE70KRM/9,=UE70KRM/9/M,=UE9OFF/9, + =RK6YYA/9,=RN0SZ/9,=RN9N/9,=RN9N/M,=RP65MOH,=RP67MC,=RP67MD,=RP68MC,=RP68MD,=RP69MC,=RP69MD, + =RP70GK,=RP70MC,=RP70MD,=RP70OB,=RP70OF,=RP70OS,=RP71GK,=RP71MJ,=RP71OB,=RP72GK,=RP72MJ,=RP72OB, + =RP72ZW,=RP73GK,=RP73OB,=RP74PO,=RP8M,=RT22MC,=RT22MD,=RV0SR/9,=RW22MW,=RY22MC,=UA1ZGD/9, + =UA3AKO/9,=UA9MA/M,=UE55OM,=UE70KRM/9,=UE70KRM/9/M,=UE9OFF/9, R8O(18)[31],R8P(18)[31],R9O(18)[31],R9P(18)[31],RA8O(18)[31],RA8P(18)[31],RA9O(18)[31], RA9P(18)[31],RC8O(18)[31],RC8P(18)[31],RC9O(18)[31],RC9P(18)[31],RD8O(18)[31],RD8P(18)[31], RD9O(18)[31],RD9P(18)[31],RE8O(18)[31],RE8P(18)[31],RE9O(18)[31],RE9P(18)[31],RF8O(18)[31], @@ -2563,10 +2584,10 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =RA27OM(18)[31],=RA3DH/9(18)[31],=RA3ET/9(18)[31],=RA4FRH/0/P(18)[31],=RA9JJ/9/M(18)[31], =RA9MX/9(18)[31],=RC1M/9(18)[31],=RC1M/9/M(18)[31],=RG9O(18)[31],=RN9N/9/M(18)[31],=RO9O(18)[31], =RP67MP(18)[31],=RP68MP(18)[31],=RP70MP(18)[31],=RP71MP(18)[31],=RP72MP(18)[31],=RP73MP(18)[31], - =RP9OMP(18)[31],=RP9OW(18)[31],=RQ16CW(18)[31],=RR9O(18)[31],=RS9O(18)[31],=RU0ZM/9(18)[31], - =RU27OZ(18)[31],=RU6LA/9(18)[31],=RV0CJ/9(18)[31],=RW1AC/9(18)[31],=RW9MD/9/M(18)[31], - =RZ9MXM/9(18)[31],=UA0KDR/9(18)[31],=UA0ZAY/9(18)[31],=UA6WFO/9(18)[31],=UA9MA/9(18)[31], - =UA9MA/9/M(18)[31],=UA9MRA/9(18)[31],=UE80NSO(18)[31], + =RP74MP(18)[31],=RP9OMP(18)[31],=RP9OW(18)[31],=RQ16CW(18)[31],=RR9O(18)[31],=RS9O(18)[31], + =RU0ZM/9(18)[31],=RU27OZ(18)[31],=RU6LA/9(18)[31],=RV0CJ/9(18)[31],=RW1AC/9(18)[31], + =RW9MD/9/M(18)[31],=RZ9MXM/9(18)[31],=UA0KDR/9(18)[31],=UA0ZAY/9(18)[31],=UA6WFO/9(18)[31], + =UA9MA/9(18)[31],=UA9MA/9/M(18)[31],=UA9MRA/9(18)[31],=UE80NSO(18)[31], =R110RP,=R120RDP,=R120RZ,=R120TM,=R150RP,=R155RP,=R160RP,=R18URU,=RA22QF,=RC20QA,=RC20QC,=RC20QF, =RM20CC,=RM9RZ/A,=RM9RZ/P,=RP65R,=RP67KE,=RP67R,=RP68KE,=RP68R,=RP69KE,=RP69R,=RP70KE,=RP70R, =RP71R,=RP72KE,=RP72R,=RT73CW,=RT73JH,=RV3MN/9,=RW22QA,=RW22QA/8,=RW22QC,=RW22QC/8,=RW4NW/9, @@ -2614,25 +2635,26 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =R22ULM(18)[31],=R400N(18)[31],=R70B(18)[31],=R9/EW1TM(18)[31],=R9UAG/N(18)[31],=RA4CQ/9(18)[31], =RC4W/9(18)[31],=RD0L/9(18)[31],=RK6CG/9(18)[31],=RP65UMF(18)[31],=RP67KM(18)[31],=RP68KM(18)[31], =RP69KM(18)[31],=RP70KM(18)[31],=RP70NM(18)[31],=RP70UK(18)[31],=RP70ZF(18)[31],=RP71KM(18)[31], - =RP72KM(18)[31],=RP72NM(18)[31],=RP73KM(18)[31],=RP73NZ(18)[31],=RP73ZF(18)[31],=RT22UA(18)[31], - =RT77VV(18)[31],=RW4CG/9(18)[31],=RZ5D/9(18)[31],=UA9JFE/9/P(18)[31],=UE3ATV/9(18)[31], - R100W(16),R8W(16),R9W(16),RA8W(16),RA9W(16),RC8W(16),RC9W(16),RD8W(16),RD9W(16),RE8W(16),RE9W(16), - RF8W(16),RF9W(16),RG8W(16),RG9W(16),RJ8W(16),RJ9W(16),RK8W(16),RK9W(16),RL8W(16),RL9W(16), - RM8W(16),RM9W(16),RN8W(16),RN9W(16),RO8W(16),RO9W(16),RQ8W(16),RQ9W(16),RT8W(16),RT9W(16), - RU8W(16),RU9W(16),RV8W(16),RV9W(16),RW8W(16),RW9W(16),RX8W(16),RX9W(16),RY8W(16),RY9W(16), - RZ8W(16),RZ9W(16),U8W(16),U9W(16),UA8W(16),UA9W(16),UB8W(16),UB9W(16),UC8W(16),UC9W(16),UD8W(16), - UD9W(16),UE8W(16),UE9W(16),UF8W(16),UF9W(16),UG8W(16),UG9W(16),UH8W(16),UH9W(16),UI8W(16), - UI9W(16),=R100W(16),=R10RTRS/9(16),=R18KDR/4(16),=R2013CG(16),=R2015AS(16),=R2015DS(16), - =R2015KM(16),=R2017F/P(16),=R20BIS(16),=R20UFA(16),=R25ARCK/4(16),=R25MSB(16),=R25WPW(16), - =R27UFA(16),=R3XX/9(16),=R44WFF(16),=R7378TM(16),=R8JAJ/4(16),=R8JAJ/9(16),=R90WGM(16), - =R90WJV(16),=R90WOB(16),=R90WXK(16),=R9LY/4(16),=RA0R/4(16),=RA1ZPC/9(16),=RA3AUU/9(16), - =RA4POX/9(16),=RA9KDX/8/M(16),=RF9W(16),=RG5A/8(16),=RK3PWJ/9(16),=RK6YYA/9/M(16),=RK9KWI/9(16), - =RK9KWI/9/P(16),=RL3DX/9(16),=RM90WF(16),=RM9RZ/9/P(16),=RN9WWW/9/M(16),=RN9WWW/P(16),=RO17CW(16), - =RP67GI(16),=RP67MG(16),=RP67NG(16),=RP67RK(16),=RP67SW(16),=RP67UF(16),=RP68GM(16),=RP68NK(16), - =RP68UF(16),=RP69GI(16),=RP69PW(16),=RP69UF(16),=RP70GI(16),=RP70GM(16),=RP70LS(16),=RP70NK(16), - =RP70UF(16),=RP70ZO(16),=RP71GI(16),=RP71GM(16),=RP71UF(16),=RP72AR(16),=RP72GI(16),=RP72GM(16), - =RP72UF(16),=RP72WU(16),=RP73AR(16),=RP73GI(16),=RP73UF(16),=RP73WU(16),=RT22WF(16),=RT2F/4(16), - =RT2F/4/M(16),=RT2F/9/M(16),=RT73EA(16),=RT73EL(16),=RT8A/4(16),=RT9W(16),=RT9W/P(16), + =RP72KM(18)[31],=RP72NM(18)[31],=RP73KM(18)[31],=RP73NZ(18)[31],=RP73ZF(18)[31],=RP74KM(18)[31], + =RT22UA(18)[31],=RT77VV(18)[31],=RW4CG/9(18)[31],=RZ5D/9(18)[31],=UA9JFE/9/P(18)[31], + =UA9UAX/M(18)[31],=UE3ATV/9(18)[31], + R8W(16),R9W(16),RA8W(16),RA9W(16),RC8W(16),RC9W(16),RD8W(16),RD9W(16),RE8W(16),RE9W(16),RF8W(16), + RF9W(16),RG8W(16),RG9W(16),RJ8W(16),RJ9W(16),RK8W(16),RK9W(16),RL8W(16),RL9W(16),RM8W(16), + RM9W(16),RN8W(16),RN9W(16),RO8W(16),RO9W(16),RQ8W(16),RQ9W(16),RT8W(16),RT9W(16),RU8W(16), + RU9W(16),RV8W(16),RV9W(16),RW8W(16),RW9W(16),RX8W(16),RX9W(16),RY8W(16),RY9W(16),RZ8W(16), + RZ9W(16),U8W(16),U9W(16),UA8W(16),UA9W(16),UB8W(16),UB9W(16),UC8W(16),UC9W(16),UD8W(16),UD9W(16), + UE8W(16),UE9W(16),UF8W(16),UF9W(16),UG8W(16),UG9W(16),UH8W(16),UH9W(16),UI8W(16),UI9W(16), + =R100W(16),=R10RTRS/9(16),=R18KDR/4(16),=R2013CG(16),=R2015AS(16),=R2015DS(16),=R2015KM(16), + =R2017F/P(16),=R20BIS(16),=R20UFA(16),=R25ARCK/4(16),=R25MSB(16),=R25WPW(16),=R27UFA(16), + =R3XX/9(16),=R44WFF(16),=R7378TM(16),=R8JAJ/4(16),=R8JAJ/9(16),=R90WGM(16),=R90WJV(16), + =R90WOB(16),=R90WXK(16),=R9LY/4(16),=RA0R/4(16),=RA1ZPC/9(16),=RA3AUU/9(16),=RA4POX/9(16), + =RA9KDX/8/M(16),=RF9W(16),=RG5A/8(16),=RK3PWJ/9(16),=RK6YYA/9/M(16),=RK9KWI/9(16),=RK9KWI/9/P(16), + =RL3DX/9(16),=RM90WF(16),=RM9RZ/9/P(16),=RN9WWW/9/M(16),=RN9WWW/P(16),=RO17CW(16),=RP67GI(16), + =RP67MG(16),=RP67NG(16),=RP67RK(16),=RP67SW(16),=RP67UF(16),=RP68GM(16),=RP68NK(16),=RP68UF(16), + =RP69GI(16),=RP69PW(16),=RP69UF(16),=RP70GI(16),=RP70GM(16),=RP70LS(16),=RP70NK(16),=RP70UF(16), + =RP70ZO(16),=RP71GI(16),=RP71GM(16),=RP71UF(16),=RP72AR(16),=RP72GI(16),=RP72GM(16),=RP72UF(16), + =RP72WU(16),=RP73AR(16),=RP73GI(16),=RP73UF(16),=RP73WU(16),=RP74GI(16),=RP74UF(16),=RT22WF(16), + =RT2F/4(16),=RT2F/4/M(16),=RT2F/9/M(16),=RT73EA(16),=RT73EL(16),=RT8A/4(16),=RT9W(16),=RT9W/P(16), =RU110RAEM(16),=RU20WC(16),=RU22WZ(16),=RU27WB(16),=RU27WF(16),=RU27WN(16),=RU27WO(16), =RU3HD/9/P(16),=RU90WZ(16),=RU9KC/4/M(16),=RU9SO/4(16),=RU9SO/4/P(16),=RV22WB(16),=RV2FZ/9(16), =RV90WB(16),=RV9CHB/4(16),=RW3SN/9(16),=RW3XX/9(16),=RW4WA/9/P(16),=RW90WC(16),=RW9FWR/9/M(16), @@ -2653,8 +2675,8 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =RA/IK5MIC/M(18)[31],=RA0CCJ/9(18)[31],=RA50VT(18)[31],=RK1B/9(18)[31],=RP68BP(18)[31], =RP68TZ(18)[31],=RP70AF(18)[31],=RP70BP(18)[31],=RP70GA(18)[31],=RP71BP(18)[31],=RP72BP(18)[31], =RP73BP(18)[31],=RP9Y(18)[31],=RP9YAF(18)[31],=RP9YTZ(18)[31],=RT73GM(18)[31],=RW22WG(18)[31], - =RX6AY/9(18)[31],=UA0LLW/9(18)[31],=UA0ZDY/9(18)[31],=UA9MA/M(18)[31],=UA9UAX/9/P(18)[31], - =UE0ZOO/9(18)[31],=UE44R/9(18)[31],=UE80AL(18)[31], + =RX6AY/9(18)[31],=UA0LLW/9(18)[31],=UA0ZDY/9(18)[31],=UA9UAX/9/P(18)[31],=UE0ZOO/9(18)[31], + =UE44R/9(18)[31],=UE80AL(18)[31], R8Z(18)[31],R9Z(18)[31],RA8Z(18)[31],RA9Z(18)[31],RC8Z(18)[31],RC9Z(18)[31],RD8Z(18)[31], RD9Z(18)[31],RE8Z(18)[31],RE9Z(18)[31],RF8Z(18)[31],RF9Z(18)[31],RG8Z(18)[31],RG9Z(18)[31], RJ8Z(18)[31],RJ9Z(18)[31],RK8Z(18)[31],RK9Z(18)[31],RL8Z(18)[31],RL9Z(18)[31],RM8Z(18)[31], @@ -2686,13 +2708,13 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =RAEM(18)[32],=RD110RAEM(18)[32],=RI0B(18)[32],=RI0BV/0(18)[32],=RK3DZJ/9(18)[32],=RK56GC(18)[32], =RK6BBM/9(18)[32],=RK80KEDR(18)[32],=RL5G/9(18)[32],=RM0A(18)[32],=RM2D/9(18)[32], =RM9RZ/0(18)[32],=RN0A(18)[32],=RN110RAEM(18)[32],=RN110RAEM/P(18)[32],=RP70KV(18)[32], - =RP70RS(18)[32],=RP73KT(18)[32],=RT22SA(18)[32],=RT9K/9(18)[32],=RU19NY(18)[32],=RU3FF/0(18)[32], - =RU4CO/0(18)[32],=RV3DHC/0(18)[32],=RV3DHC/0/P(18)[32],=RV9WP/9(18)[32],=RW3XN/0(18)[32], - =RW3YC/0(18)[32],=RW3YC/9(18)[32],=RY1AAB/9(18)[32],=RY1AAB/9/M(18)[32],=RZ3DSA/0(18)[32], - =RZ3DZS/0(18)[32],=RZ9ON/9(18)[32],=UA0ACG/0(18)[32],=UA0FCB/0(18)[32],=UA0FCB/0/P(18)[32], - =UA0WG/0(18)[32],=UA0WW/0(18)[32],=UA0WW/M(18)[32],=UA0WY/0(18)[32],=UA3ADN/0(18)[32], - =UA4LU/0(18)[32],=UA4PT/0(18)[32],=UA6BTN/0(18)[32],=UA9UAX/9(18)[32],=UA9WDK/0(18)[32], - =UB1AJQ/0(18)[32],=UE1WFF/0(18)[32], + =RP70RS(18)[32],=RP73KT(18)[32],=RP74KT(18)[32],=RT22SA(18)[32],=RT9K/9(18)[32],=RU19NY(18)[32], + =RU3FF/0(18)[32],=RU4CO/0(18)[32],=RV3DHC/0(18)[32],=RV3DHC/0/P(18)[32],=RV9WP/9(18)[32], + =RW3XN/0(18)[32],=RW3YC/0(18)[32],=RW3YC/9(18)[32],=RY1AAB/9(18)[32],=RY1AAB/9/M(18)[32], + =RZ3DSA/0(18)[32],=RZ3DZS/0(18)[32],=RZ9ON/9(18)[32],=UA0ACG/0(18)[32],=UA0FCB/0(18)[32], + =UA0FCB/0/P(18)[32],=UA0WG/0(18)[32],=UA0WW/0(18)[32],=UA0WW/M(18)[32],=UA0WY/0(18)[32], + =UA3ADN/0(18)[32],=UA4LU/0(18)[32],=UA4PT/0(18)[32],=UA6BTN/0(18)[32],=UA9UAX/9(18)[32], + =UA9WDK/0(18)[32],=UB1AJQ/0(18)[32],=UE1WFF/0(18)[32], =R100D(18)[22],=R100DI(18)[22],=R3CA/9(18)[22],=RA3XR/0(18)[22],=RA9LI/0(18)[22],=RI0BDI(18)[22], =RS0B(18)[22],=RS0B/P(18)[22],=RV3EFH/0(18)[22],=RW1AI/9(18)[22],=RW3GW/0(18)[22], =RX6LMQ/0(18)[22],=RZ9DX/0(18)[22],=RZ9DX/0/A(18)[22],=RZ9DX/0/P(18)[22],=RZ9DX/9(18)[22], @@ -2722,11 +2744,12 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: RZ0F(19)[34],U0E(19)[34],U0F(19)[34],UA0E(19)[34],UA0F(19)[34],UB0E(19)[34],UB0F(19)[34], UC0E(19)[34],UC0F(19)[34],UD0E(19)[34],UD0F(19)[34],UE0E(19)[34],UE0F(19)[34],UF0E(19)[34], UF0F(19)[34],UG0E(19)[34],UG0F(19)[34],UH0E(19)[34],UH0F(19)[34],UI0E(19)[34],UI0F(19)[34], - =R10RLHA/0(19)[34],=R7AA/0(19)[34],=R7LP/0(19)[34],=R7MR/0(19)[34],=RA/KE5JA(19)[34], - =RA/OG2K(19)[34],=RA0SS/0(19)[34],=RA1ALA/0(19)[34],=RA4HKM/0(19)[34],=RA4HKM/0/P(19)[34], - =RA6ABC/0(19)[34],=RM0F(19)[34],=RN0F(19)[34],=RN1CR/0(19)[34],=RS0F(19)[34],=RT6A/0(19)[34], - =RV1CC/0(19)[34],=RZ3DW/0(19)[34],=RZ4HD/0(19)[34],=RZ55YG(19)[34],=RZ9ODD/0(19)[34], - =RZ9OWE/0(19)[34],=UA1ANA/0(19)[34],=UA3EDP/0(19)[34],=UB40FSU(19)[34],=UE1AAA/0(19)[34], + =R10RLHA/0(19)[34],=R26RRC(19)[34],=R7AA/0(19)[34],=R7LP/0(19)[34],=R7MR/0(19)[34], + =RA/KE5JA(19)[34],=RA/OG2K(19)[34],=RA0SS/0(19)[34],=RA1ALA/0(19)[34],=RA4HKM/0(19)[34], + =RA4HKM/0/P(19)[34],=RA6ABC/0(19)[34],=RM0F(19)[34],=RN0F(19)[34],=RN1CR/0(19)[34],=RS0F(19)[34], + =RT6A/0(19)[34],=RV1CC/0(19)[34],=RZ3DW/0(19)[34],=RZ4HD/0(19)[34],=RZ55YG(19)[34], + =RZ9ODD/0(19)[34],=RZ9OWE/0(19)[34],=UA1ANA/0(19)[34],=UA3EDP/0(19)[34],=UB40FSU(19)[34], + =UE1AAA/0(19)[34], =RV9WP/0(18)[22],=U0H/UA0AGQ(18)[22], R0I(19)[24],RA0I(19)[24],RC0I(19)[24],RD0I(19)[24],RE0I(19)[24],RF0I(19)[24],RG0I(19)[24], RI0I(19)[24],RJ0I(19)[24],RK0I(19)[24],RL0I(19)[24],RM0I(19)[24],RN0I(19)[24],RO0I(19)[24], @@ -2764,11 +2787,11 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =RN1NS/0(19)[34],=RP0L(19)[34],=RP0LPK(19)[34],=RP60P(19)[34],=RP66V(19)[34],=RP67SD(19)[34], =RP67V(19)[34],=RP68SD(19)[34],=RP68V(19)[34],=RP69SD(19)[34],=RP69V(19)[34],=RP70DG(19)[34], =RP70SD(19)[34],=RP70V(19)[34],=RP71DG(19)[34],=RP71SD(19)[34],=RP71V(19)[34],=RP72DG(19)[34], - =RP72SD(19)[34],=RP72V(19)[34],=RP73DG(19)[34],=RP73SD(19)[34],=RP73V(19)[34],=RU3BY/0(19)[34], - =RU5D/0(19)[34],=RV1AW/0(19)[34],=RV3DSA/0(19)[34],=RW22GO(19)[34],=RW3LG/0(19)[34], - =RX15RX(19)[34],=UA0SDX/0(19)[34],=UA0SIK/0(19)[34],=UA3AHA/0(19)[34],=UA4SBZ/0(19)[34], - =UA6MF/0(19)[34],=UA7R/0(19)[34],=UB0LAP/P(19)[34],=UC0LAF/P(19)[34],=UE1RFF/0(19)[34], - =UE70MA(19)[34],=UE75L(19)[34], + =RP72SD(19)[34],=RP72V(19)[34],=RP73DG(19)[34],=RP73SD(19)[34],=RP73V(19)[34],=RP74DG(19)[34], + =RP74SD(19)[34],=RP74V(19)[34],=RU3BY/0(19)[34],=RU5D/0(19)[34],=RV1AW/0(19)[34], + =RV3DSA/0(19)[34],=RW22GO(19)[34],=RW3LG/0(19)[34],=RX15RX(19)[34],=UA0SDX/0(19)[34], + =UA0SIK/0(19)[34],=UA3AHA/0(19)[34],=UA4SBZ/0(19)[34],=UA6MF/0(19)[34],=UA7R/0(19)[34], + =UB0LAP/P(19)[34],=UC0LAF/P(19)[34],=UE1RFF/0(19)[34],=UE70MA(19)[34],=UE75L(19)[34], R0O(18)[32],RA0O(18)[32],RC0O(18)[32],RD0O(18)[32],RE0O(18)[32],RF0O(18)[32],RG0O(18)[32], RJ0O(18)[32],RK0O(18)[32],RL0O(18)[32],RM0O(18)[32],RN0O(18)[32],RO0O(18)[32],RQ0O(18)[32], RT0O(18)[32],RU0O(18)[32],RV0O(18)[32],RW0O(18)[32],RX0O(18)[32],RY0O(18)[32],RZ0O(18)[32], @@ -2806,7 +2829,7 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =RA0SP/RP(18)[32],=RA0SR/RP(18)[32],=RA110RAEM(18)[32],=RA3TO/0(18)[32],=RA4CSX/0/P(18)[32], =RA9JG/0(18)[32],=RA9JG/0/P(18)[32],=RA9OBG/0(18)[32],=RA9USU/8(18)[32],=RD0L/0(18)[32], =RK17CW(18)[32],=RK9MZZ/0(18)[32],=RN4HIT/0(18)[32],=RP0S(18)[32],=RP0SXR(18)[32],=RP0SZZ(18)[32], - =RP67ST(18)[32],=RP70AB(18)[32],=RP72AB(18)[32],=RP73AB(18)[32],=RQ0C/9(18)[32], + =RP67ST(18)[32],=RP70AB(18)[32],=RP72AB(18)[32],=RP73AB(18)[32],=RP74AB(18)[32],=RQ0C/9(18)[32], =RV3ACA/0/M(18)[32],=RV6AJ/0(18)[32],=RV7AD/0(18)[32],=RV9JD/0(18)[32],=RW4YA/0(18)[32], =RW4YA/9(18)[32],=RX3AT/0(18)[32],=RX3DFH/0(18)[32],=RX9WN/0(18)[32],=RX9WN/0/M(18)[32], =RX9WN/0/P(18)[32],=RZ0SO/P(18)[32],=UA0KBG/0(18)[32],=UA0KBG/9(18)[32],=UA3EDQ/0(18)[32], @@ -2821,15 +2844,15 @@ Asiatic Russia: 17: 30: AS: 55.88: -84.08: -7.0: UA9: =RP0W(18)[31],=RP0W/P(18)[31],=RP0WWS(18)[31],=RP70SL(18)[31],=RP72SL(18)[31],=RV0AE/0/FF(18)[31], =RZ0AM/0(18)[31],=RZ22WW(18)[31],=UA0FCB/P(18)[31],=UA9UAX/0/M(18)[31],=UB5O/9(18)[31], =UE0ARD/0(18)[31],=UE10RFF/9(18)[31],=UE1RFF/0/P(18)[31],=UE9FDA/0(18)[31],=UE9FDA/0/M(18)[31], - =R23RRC(19)[25],=UA6HMC/0(19)[25], + =R205NEW(19)[25],=R23RRC(19)[25],=UA6HMC/0(19)[25], R0Y(23)[32],RA0Y(23)[32],RC0Y(23)[32],RD0Y(23)[32],RE0Y(23)[32],RF0Y(23)[32],RG0Y(23)[32], RJ0Y(23)[32],RK0Y(23)[32],RL0Y(23)[32],RM0Y(23)[32],RN0Y(23)[32],RO0Y(23)[32],RQ0Y(23)[32], RT0Y(23)[32],RU0Y(23)[32],RV0Y(23)[32],RW0Y(23)[32],RX0Y(23)[32],RY0Y(23)[32],RZ0Y(23)[32], U0Y(23)[32],UA0Y(23)[32],UB0Y(23)[32],UC0Y(23)[32],UD0Y(23)[32],UE0Y(23)[32],UF0Y(23)[32], - UG0Y(23)[32],UH0Y(23)[32],UI0Y(23)[32],=R3YAB/9/P(23)[32],=R9OOO/9/M(23)[32],=R9OOO/9/P(23)[32], - =R9OY/9/P(23)[32],=RA0AJ/0/P(23)[32],=RA0WA/0/P(23)[32],=RA9YME/0(23)[32],=RK3BY/0(23)[32], - =RP0Y(23)[32],=RX0AE/0(23)[32],=RX0AT/0/P(23)[32],=UA0ADU/0(23)[32],=UA0WGD/0(23)[32], - =UA9ZZ/0/P(23)[32],=UE0OFF/0(23)[32],=UE44Y/9(23)[32],=UE70Y(23)[32], + UG0Y(23)[32],UH0Y(23)[32],UI0Y(23)[32],=R0WX/P(23)[32],=R3YAB/9/P(23)[32],=R9OOO/9/M(23)[32], + =R9OOO/9/P(23)[32],=R9OY/9/P(23)[32],=RA0AJ/0/P(23)[32],=RA0WA/0/P(23)[32],=RA9YME/0(23)[32], + =RK3BY/0(23)[32],=RP0Y(23)[32],=RX0AE/0(23)[32],=RX0AT/0/P(23)[32],=UA0ADU/0(23)[32], + =UA0WGD/0(23)[32],=UA9ZZ/0/P(23)[32],=UE0OFF/0(23)[32],=UE44Y/9(23)[32],=UE70Y(23)[32], R0X(19)[35],R0Z(19)[35],RA0X(19)[35],RA0Z(19)[35],RC0X(19)[35],RC0Z(19)[35],RD0X(19)[35], RD0Z(19)[35],RE0X(19)[35],RE0Z(19)[35],RF0X(19)[35],RF0Z(19)[35],RG0X(19)[35],RG0Z(19)[35], RI0X(19)[35],RI0Z(19)[35],RJ0X(19)[35],RJ0Z(19)[35],RK0X(19)[35],RK0Z(19)[35],RL0X(19)[35], @@ -2914,12 +2937,12 @@ Marshall Islands: 31: 65: OC: 9.08: -167.33: -12.0: V7: Brunei Darussalam: 28: 54: OC: 4.50: -114.60: -8.0: V8: V8; Canada: 05: 09: NA: 44.35: 78.75: 5.0: VE: - CF,CG,CJ,CK,VA,VB,VC,VE,VG,VX,VY9,XL,XM,=VE2EM/M,=VER20190319, + CF,CG,CJ,CK,VA,VB,VC,VE,VG,VX,VY9,XL,XM,=VE2EM/M,=VER20190523, =CF7AAW/1,=CK7IG/1,=VA3QSL/1,=VA3WR/1,=VE1REC/LH,=VE1REC/M/LH,=VE3RSA/1,=VE7IG/1, CF2[4],CG2[4],CJ2[4],CK2[4],VA2[4],VB2[4],VC2[4],VE2[4],VG2[4],VX2[4],XL2[4],XM2[4],=4Y1CAO[4], - =CY2ZT/2[4],=VA3ELE/2[4],=VA3MPM/2[4],=VA7AQ/P[4],=VE2/G3ZAY/P[4],=VE2/M0BLF/P[4],=VE2FK[9], - =VE2HAY/P[4],=VE2MAM/P[4],=VE2OV/P[4],=VE3AP/2[4],=VE3EXY/2[4],=VE3GF/2[4],=VE3GNO/2[4], - =VE3IAC/2[4],=VE3ZZ/2[4],=VE6TC/2[4],=VE7IG/2[4],=XO0ICE/2[4], + =CY2ZT/2[4],=VA3MPM/2[4],=VA7AQ/P[4],=VE2/G3ZAY/P[4],=VE2/M0BLF/P[4],=VE2FK[9],=VE2HAY/P[4], + =VE2MAM/P[4],=VE2OV/P[4],=VE3AP/2[4],=VE3EXY/2[4],=VE3GF/2[4],=VE3GNO/2[4],=VE3IAC/2[4], + =VE3ZZ/2[4],=VE6TC/2[4],=VE7IG/2[4],=XO0ICE/2[4], CF3(4)[4],CG3(4)[4],CJ3(4)[4],CK3(4)[4],VA3(4)[4],VB3(4)[4],VC3(4)[4],VE3(4)[4],VG3(4)[4], VX3(4)[4],XL3(4)[4],XM3(4)[4],=CF7EWK/3(4)[4],=CI0XN/P(4)[4],=CJ7EWK/3(4)[4],=VA7EWK/3(4)[4], =VE1RM/3(4)[4],=VE2AEJ/3(4)[4],=VE2MAM/3(4)[4],=VE2PK/3(4)[4],=VE2QLF/3(4)[4],=VE2QV/3(4)[4], @@ -2949,17 +2972,17 @@ Canada: 05: 09: NA: 44.35: 78.75: 5.0: VE: =CF2RC(2)[4],=CF2VVV(2)[4],=CJ2BY(2)[4],=CJ2KCE(2)[4],=K3FMQ/VE2(2)[4],=K5YG/VE2(2)[4], =KD3RF/VE2(2)[4],=KD3TB/VE2(2)[4],=N5ZO/VE2(2)[4],=VA1CN/2(2)[4],=VA2BK(2)[4],=VA2BY(2)[4], =VA2KCE(2)[4],=VA2MCJ/VE2(2)[4],=VA2RAG(2)[4],=VA2RC(2)[4],=VA2VFT(2)[4],=VA2VVV(2)[4], - =VA3NA/2(2)[4],=VB2C(2)[4],=VB2R(2)[4],=VB2T(2)[4],=VB2V(2)[4],=VB2W(2)[4],=VC2C(2)[4], - =VC2EME(2)[4],=VC2Q(2)[4],=VC2R(2)[4],=VC2X(2)[4],=VC3W/2(2)[4],=VE2/JA8BMK(2)[4],=VE2/K5YG(2)[4], - =VE2/KD3RF(2)[4],=VE2/KD3RF/M(2)[4],=VE2/N1NK(2)[4],=VE2/UT3UA(2)[4],=VE2/W2NTJ(2)[4], - =VE2/W5GED(2)[4],=VE2A(2)[4],=VE2ACP/P(2)[4],=VE2AE(2)[4],=VE2CSI(2)[4],=VE2CVI(2)[4], - =VE2DXY(2)[4],=VE2EKA(2)[4],=VE2EW(2)[4],=VE2FDJ/2(2)[4],=VE2GHZ/2(2)[4],=VE2HRI(2)[4], - =VE2IDX(2)[4],=VE2III(2)[4],=VE2IM(2)[4],=VE2KK(2)[4],=VE2NN(2)[4],=VE2OTT(2)[4],=VE2PR(2)[4], - =VE2PRG(2)[4],=VE2QIP/2(2)[4],=VE2WDX(2)[4],=VE2XAA/2(2)[4],=VE2XB/2(2)[4],=VE2Z(2)[4], - =VE3AXC/2(2)[4],=VE3CWU/2(2)[4],=VE3EY/2(2)[4],=VE3FDX/2(2)[4],=VE3JM/2(2)[4],=VE3NE/2(2)[4], - =VE3NWA/2(2)[4],=VE3RHJ/2(2)[4],=VE3ZF/2(2)[4],=VE7ACN/VE2(2)[4],=VE7MID/VE2(2)[4],=VE8DX/2(2)[4], - =W0SD/VE2(2)[4],=W2NTJ/VE2(2)[4],=W4TMO/VE2(2)[4],=W5GED/VE2(2)[4],=WB8YTZ/VE2(2)[4], - =XM3NE/2(2)[4], + =VA3ELE/2(2)[4],=VA3NA/2(2)[4],=VA7XW/VE2(2)[4],=VB2C(2)[4],=VB2R(2)[4],=VB2T(2)[4],=VB2V(2)[4], + =VB2W(2)[4],=VC2C(2)[4],=VC2EME(2)[4],=VC2Q(2)[4],=VC2R(2)[4],=VC2X(2)[4],=VC3W/2(2)[4], + =VE2/JA8BMK(2)[4],=VE2/K5YG(2)[4],=VE2/KD3RF(2)[4],=VE2/KD3RF/M(2)[4],=VE2/N1NK(2)[4], + =VE2/UT3UA(2)[4],=VE2/W2NTJ(2)[4],=VE2/W5GED(2)[4],=VE2A(2)[4],=VE2ACP/P(2)[4],=VE2AE(2)[4], + =VE2CSI(2)[4],=VE2CVI(2)[4],=VE2DXY(2)[4],=VE2EKA(2)[4],=VE2EW(2)[4],=VE2FDJ/2(2)[4], + =VE2GHZ/2(2)[4],=VE2HRI(2)[4],=VE2IDX(2)[4],=VE2III(2)[4],=VE2IM(2)[4],=VE2KK(2)[4],=VE2NN(2)[4], + =VE2OTT(2)[4],=VE2PR(2)[4],=VE2PRG(2)[4],=VE2QIP/2(2)[4],=VE2TWO(2)[4],=VE2WDX(2)[4], + =VE2XAA/2(2)[4],=VE2XB/2(2)[4],=VE2Z(2)[4],=VE3AXC/2(2)[4],=VE3CWU/2(2)[4],=VE3EY/2(2)[4], + =VE3FDX/2(2)[4],=VE3JM/2(2)[4],=VE3NE/2(2)[4],=VE3NWA/2(2)[4],=VE3RHJ/2(2)[4],=VE3ZF/2(2)[4], + =VE7ACN/VE2(2)[4],=VE7MID/VE2(2)[4],=VE8DX/2(2)[4],=W0SD/VE2(2)[4],=W2NTJ/VE2(2)[4], + =W4TMO/VE2(2)[4],=W5GED/VE2(2)[4],=WB8YTZ/VE2(2)[4],=XM3NE/2(2)[4], =K8JJ/VY0(4)[4],=K9AJ/VY0(4)[4],=KD6WW/VY0(4)[4],=VY0A(4)[4],=VY0V(4)[4]; Australia: 30: 59: OC: -23.70: -132.33: -10.0: VK: AX,VH,VI,VJ,VK,VL,VM,VN,VZ,=VK9MAV, diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index e81160575..bc333dd8c 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -52,6 +52,7 @@ set (UG_SRCS tutorial-example1.adoc tutorial-example2.adoc tutorial-example3.adoc + tutorial-example4.adoc tutorial-main-window.adoc tutorial-wide-graph-settings.adoc utilities.adoc @@ -77,6 +78,8 @@ set (UG_IMGS images/FreqCal_Graph.png images/FreqCal_Results.png images/freemsg.png + images/ft4_decodes.png + images/ft4_waterfall.png images/ft8_decodes.png images/FT8_waterfall.png images/help-menu.png diff --git a/doc/common/links.adoc b/doc/common/links.adoc index 85fdb1064..58ad60476 100644 --- a/doc/common/links.adoc +++ b/doc/common/links.adoc @@ -92,6 +92,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes. :ubuntu_sdk: https://launchpad.net/~ubuntu-sdk-team/+archive/ppa[Ubuntu SDK Notice] :win_openssl_packages: https://slproweb.com/products/Win32OpenSSL.html[Windows OpenSSL Packages] :win32_openssl: https://slproweb.com/download/Win32OpenSSL_Light-1_0_2r.exe[Win32 OpenSSL Lite Package] +:win64_openssl: https://slproweb.com/download/Win64OpenSSL_Light-1_0_2r.exe[Win64 OpenSSL Lite Package] :writelog: https://writelog.com/[Writelog] :wsjt_yahoo_group: https://groups.yahoo.com/neo/groups/wsjtgroup/info[WSJT Group] :wsjtx: http://physics.princeton.edu/pulsar/K1JT/wsjtx.html[WSJT-X] @@ -115,6 +116,7 @@ d). Edit lines as needed. Keeping them in alphabetic order help see dupes. :QRA64_EME: http://physics.princeton.edu/pulsar/K1JT/QRA64_EME.pdf[QRA64 for microwave EME] :svn: http://subversion.apache.org/packages.html#windows[Subversion] :win32: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-win32.exe[wsjtx-{VERSION}-win32.exe] +:win64: http://physics.princeton.edu/pulsar/K1JT/wsjtx-{VERSION}-win64.exe[wsjtx-{VERSION}-win64.exe] :wsjt-devel: https://lists.sourceforge.net/lists/listinfo/wsjt-devel[here] :wsjt_repo: https://sourceforge.net/p/wsjt/wsjt_orig/ci/master/tree/[WSJT Source Repository] :wspr_code: http://physics.princeton.edu/pulsar/K1JT/WSPRcode.exe[WSPRcode.exe] diff --git a/doc/user_guide/en/images/ft4_decodes.png b/doc/user_guide/en/images/ft4_decodes.png new file mode 100644 index 000000000..05d2083fd Binary files /dev/null and b/doc/user_guide/en/images/ft4_decodes.png differ diff --git a/doc/user_guide/en/images/ft4_waterfall.png b/doc/user_guide/en/images/ft4_waterfall.png new file mode 100644 index 000000000..07ed6398a Binary files /dev/null and b/doc/user_guide/en/images/ft4_waterfall.png differ diff --git a/doc/user_guide/en/install-windows.adoc b/doc/user_guide/en/install-windows.adoc index e3f75858c..786e9a294 100644 --- a/doc/user_guide/en/install-windows.adoc +++ b/doc/user_guide/en/install-windows.adoc @@ -1,11 +1,12 @@ // Status=review -Download and execute the package file {win32}, following these -instructions: +Download and execute the package file {win32} (WinXP, Vista, Win 7, +Win 8, Win10, 32-bit) or {win64} (Vista, Win 7, Win 8, Win10, 64-bit) +following these instructions: * Install _WSJT-X_ into its own directory, for example `C:\WSJTX` or ` C:\WSJT\WSJTX`, rather than the conventional location `C:\Program - Files (x86)\WSJTX`. + Files ...\WSJTX`. * All program files relating to _WSJT-X_ will be stored in the chosen installation directory and its subdirectories. @@ -29,26 +30,31 @@ TIP: Your computer may be configured so that this directory is [[OPENSSL]] -* image:LoTW_TLS_error.png[_WSJT-X_ LoTW download TLS error, role="right"] - From this version onward _WSJT-X_ requires the _OpenSSL_ libraries - to be installed. Suitable libraries may already be installed on your +* image:LoTW_TLS_error.png[_WSJT-X_ LoTW download TLS error, + role="right"] _WSJT-X_ requires the _OpenSSL_ libraries to be + installed. Suitable libraries may already be installed on your system, if they are not you will see this error shortly after startup. To fix this you need to install the _OpenSSL_ libraries. ** You can download a suitable _OpenSSL_ package for from - {win_openssl_packages}, you need the latest *Win32 v1.0.2 Lite* - version (Note it is the Win32 package even if you are using a - 64-bit Windows operating system) which at the time of writing was - {win32_openssl}. + {win_openssl_packages}, you need the latest *Windows v1.0.2 Lite* + version. For the 32-bit _WSJT-X_ build use the Win32 version of the + _OpenSSL_ libraries, for the 64-bit _WSJT-X_ use the Win64 version + of the _OpenSSL_ libraries (Note it is OK to install both versions + on a 64-bit system) which at the time of writing were + {win32_openssl} and {win64_openssl} respectively. ** Install the package and accept the default options, including the - option to copy the _OpenSSL_ DLLs to the Windows system directory - (this is important). + + option to copy the _OpenSSL_ DLLs to the Windows system + directory. There is no obligation to donate to the _OpenSSL_ + project, un-check all the donation options if desired. + NOTE: If you still get the same network error after installing the _OpenSSL_ libraries then you also need to install the {msvcpp_redist} component. From the download page select - `vcredist_x86.exe` and run it to install. + `vcredist_x86.exe` for use with the 32-bit _WSJT-X_ build or + `vcredist_x64.exe` with the 64-bit build, then run it to + install. TIP: If you cannot install the _OpenSSL_ libraries or do not have an Internet connection on the computer used to run diff --git a/doc/user_guide/en/introduction.adoc b/doc/user_guide/en/introduction.adoc index b48738190..f0d8e12e7 100644 --- a/doc/user_guide/en/introduction.adoc +++ b/doc/user_guide/en/introduction.adoc @@ -7,10 +7,10 @@ K1**JT**,`" while the suffix "`-X`" indicates that _WSJT-X_ started as an extended and experimental branch of the program _WSJT_. -_WSJT-X_ Version {VERSION_MAJOR}.{VERSION_MINOR} offers nine different -protocols or modes: *FT8*, *JT4*, *JT9*, *JT65*, *QRA64*, *ISCAT*, -*MSK144*, *WSPR*, and *Echo*. The first five are designed for making -reliable QSOs under extreme weak-signal conditions. They use nearly +_WSJT-X_ Version {VERSION_MAJOR}.{VERSION_MINOR} offers ten different +protocols or modes: *FT4*, *FT8*, *JT4*, *JT9*, *JT65*, *QRA64*, +*ISCAT*, *MSK144*, *WSPR*, and *Echo*. The first six are designed for +making reliable QSOs under weak-signal conditions. They use nearly identical message structure and source encoding. JT65 and QRA64 were designed for EME ("`moonbounce`") on the VHF/UHF bands and have also proven very effective for worldwide QRP communication on the HF bands. @@ -25,12 +25,19 @@ one-minute timed sequences of alternating transmission and reception, so a minimal QSO takes four to six minutes — two or three transmissions by each station, one sending in odd UTC minutes and the other even. FT8 is operationally similar but four times faster -(15-second T/R sequences) and less sensitive by a few dB. On the HF -bands, world-wide QSOs are possible with any of these modes using -power levels of a few watts (or even milliwatts) and compromise -antennas. On VHF bands and higher, QSOs are possible (by EME and -other propagation types) at signal levels 10 to 15 dB below those -required for CW. +(15-second T/R sequences) and less sensitive by a few dB. FT4 is +faster still (7.5 s T/R sequences) and especially well suited for +radio contesting. On the HF bands, world-wide QSOs are possible with +any of these modes using power levels of a few watts (or even +milliwatts) and compromise antennas. On VHF bands and higher, QSOs +are possible (by EME and other propagation types) at signal levels 10 +to 15 dB below those required for CW. + +Note that even though their T/R sequences are short, FT4 and FT8 are +classified as slow modes because their message frames are sent only +once per transmission. All fast modes in _WSJT-X_ send their message +frames repeatedly, as many times as will fit into the Tx sequence +length. *ISCAT*, *MSK144*, and optionally submodes *JT9E-H* are "`fast`" protocols designed to take advantage of brief signal enhancements from @@ -65,10 +72,10 @@ are available for all three platforms. *Version Numbers:* _WSJT-X_ release numbers have major, minor, and patch numbers separated by periods: for example, _WSJT-X_ Version -1.9.0. Temporary "`beta`" release candidates are sometimes made in +2.1.0. Temporary _beta release_ candidates are sometimes made in advance of a new general-availability release, in order to obtain user -feedback. For example, version 1.9.0-rc1, 1.9.0-rc2, etc., would -be beta releases leading up to the final release of v1.9.0. +feedback. For example, version 2.1.0-rc1, 2.1.0-rc2, etc., would +be beta releases leading up to the final release of v2.1.0. Release candidates should be used _only_ during a short testing period. They carry an implied obligation to provide feedback to the program development group. Candidate releases should not be used on diff --git a/doc/user_guide/en/new_features.adoc b/doc/user_guide/en/new_features.adoc index a90b52182..de5c34ff0 100644 --- a/doc/user_guide/en/new_features.adoc +++ b/doc/user_guide/en/new_features.adoc @@ -1,40 +1,11 @@ === New in Version {VERSION} -For quick reference, here's a short list of features and capabilities -added to _WSJT-X_ since Version 1.9.1: - -- New FT8 and MSK144 protocols with 77-bit payloads permit these enhancements: - -* Optimized contest messages for NA VHF, EU VHF, Field Day, RTTY Roundup - -* Full support for "/R" and "/P" calls in relevant contests - -* New logging features for contesting - -* Integration with {n1mm_logger} and {writelog} for contesting - -* Improved support for compound and nonstandard callsigns - -* Nearly equal (or better) sensitivity compared to old protocols - -* Lower false decode rates - -- Improved color highlighting of received messages - -- Improved WSPR sensitivity - -- Expanded and improved UDP messages sent to companion programs - -- Bug fixes and other minor tweaks to user interface - -IMPORTANT: Note that for FT8 and MSK144 there is no backward -compatibility with WSJT-X 1.9.1 and earlier. Everyone using these -modes should upgrade to WSJT-X 2.0 by January 1, 2019. - -IMPORTANT: _WSJT-X_ Version 2.0 drops support for Apple Mac OS X 10.9 -(Mavericks). It is possible to build from source for this operating -system version but the DMG installer package requires 10.10 or later. - +The most important feature added to _WSJT-X_ since Version 2.0.1 is +the new *FT4 protocol*, designed especially for radio contesting. It +has T/R sequence length 7.5 s, bandwidth 80 Hz, and threshold +sensitivity -17.5 dB. Version 2.1.0 also has improvements to FT8 +waveform generation, contest logging, rig control, the user interface, +and accessibility, as well as a number of bug fixes. === Documentation Conventions diff --git a/doc/user_guide/en/protocols.adoc b/doc/user_guide/en/protocols.adoc index f50096097..e0d4145e3 100644 --- a/doc/user_guide/en/protocols.adoc +++ b/doc/user_guide/en/protocols.adoc @@ -12,10 +12,11 @@ Special cases allow other information such as add-on callsign prefixes aim is to compress the most common messages used for minimally valid QSOs into a fixed 72-bit length. -The information payload for FT8 and MSK144 contains 77 bits. The 5 -additional bits are used to flag special message types used for FT8 -DXpedition Mode, contesting, nonstandard callsigns, and a few other -special types. +The information payload for FT4, FT8, and MSK144 contains 77 bits. +The 5 new bits added to the original 72 are used to flag special +message types signifying special message types used for FT8 DXpedition +Mode, contesting, nonstandard callsigns, and a few other +possibilities. A standard amateur callsign consists of a one- or two-character prefix, at least one of which must be a letter, followed by a digit @@ -67,18 +68,29 @@ _WSJT-X_ modes have continuous phase and constant envelope. [[SLOW_MODES]] === Slow Modes +[[FT4PRO]] +==== FT4 + +Forward error correction (FEC) in FT4 uses a low-density parity check +(LDPC) code with 77 information bits, a 14-bit cyclic redundancy check +(CRC), and 83 parity bits making a 174-bit codeword. It is thus +called an LDPC (174,91) code. Synchronization uses four 4×4 Costas +arrays, and ramp-up and ramp-down symbols are inserted at the start +and end of each transmission. Modulation is 4-tone frequency-shift +keying (4-GFSK) with Gaussian smoothing of frequency transitions. The +keying rate is 12000/576 = 20.8333 baud. Each transmitted symbol +conveys two bits, so the total number of channel symbols is 174/2 + 16 ++ 2 = 105. The total bandwidth is 4 × 20.8333 = 83.3 Hz. + [[FT8PRO]] ==== FT8 -Forward error correction (FEC) in FT8 uses a low-density parity check -(LDPC) code with 77 information bits, a 14-bit cyclic redundancy check -(CRC), and 83 parity bits making a 174-bit codeword. It is thus -called an LDPC (174,91) code. Synchronization uses 7×7 Costas arrays -at the beginning, middle, and end of each transmission. Modulation is -8-tone frequency-shift keying (8-FSK) at 12000/1920 = 6.25 baud. Each -transmitted symbol carries three bits, so the total number of channel -symbols is 174/3 + 21 = 79. The total occupied bandwidth is 8 × 6.25 -= 50 Hz. +FT8 uses the same LDPC (174,91) code as FT4. Modulation is 8-tone +frequency-shift keying (8-GFSK) at 12000/1920 = 6.25 baud. +Synchronization uses 7×7 Costas arrays at the beginning, middle, and +end of each transmission. Transmitted symbols carry three bits, so +the total number of channel symbols is 174/3 + 21 = 79. The total +occupied bandwidth is 8 × 6.25 = 50 Hz. [[JT4PRO]] ==== JT4 @@ -227,7 +239,8 @@ which the probability of decoding is 50% or higher. |=============================================================================== |Mode |FEC Type |(n,k) | Q|Modulation type|Keying rate (Baud)|Bandwidth (Hz) |Sync Energy|Tx Duration (s)|S/N Threshold (dB) -|FT8 |LDPC, r=1/2|(174,91)| 8| 8-FSK| 6.25 | 50.0 | 0.27| 12.6 | -21 +|FT4 |LDPC, r=1/2|(174,91)| 4| 4-GFSK| 20.8333 | 83.3 | 0.15| 5.04 | -17.5 +|FT8 |LDPC, r=1/2|(174,91)| 8| 8-GFSK| 6.25 | 50.0 | 0.27| 12.6 | -21 |JT4A |K=32, r=1/2|(206,72)| 2| 4-FSK| 4.375| 17.5 | 0.50| 47.1 | -23 |JT9A |K=32, r=1/2|(206,72)| 8| 9-FSK| 1.736| 15.6 | 0.19| 49.0 | -27 |JT65A |Reed Solomon|(63,12) |64|65-FSK| 2.692| 177.6 | 0.50| 46.8 | -25 @@ -246,6 +259,7 @@ comparable to tone spacing. [width="50%",cols="h,3*^",frame=topbot,options="header"] |===================================== |Mode |Tone Spacing |BW (Hz)|S/N (dB) +|FT4 |20.8333 | 83.3 |-17.5 |FT8 |6.25 | 50.0 |-21 |JT4A |4.375| 17.5 |-23 |JT4B |8.75 | 30.6 |-22 diff --git a/doc/user_guide/en/tutorial-example4.adoc b/doc/user_guide/en/tutorial-example4.adoc new file mode 100644 index 000000000..43be6af1a --- /dev/null +++ b/doc/user_guide/en/tutorial-example4.adoc @@ -0,0 +1,52 @@ +// Status=review +.Main Window: +- Select *FT4* on the *Mode* menu. +- Double-click on *Erase* to clear both text windows. + +.Wide Graph Settings: + +- *Bins/Pixel* = 7, *Start* = 100 Hz, *N Avg* = 1 +- Adjust the width of the Wide Graph window so that the upper +frequency limit is approximately 4000 Hz. + +.Open a Wave File: + +- Select *File | Open* and navigate to ++...\save\samples\FT4\000000_000002.wav+. The waterfall and Band +Activity window should look something like the following screen shots. +This sample file was recorded during a practice contest test session, so +most of the decoded messages use the *RTTY Roundup* message formats. + +[[X15]] +image::ft4_waterfall.png[align="left",alt="Wide Graph Decode FT4"] + +image::ft4_decodes.png[align="left"] + +- Click with the mouse anywhere on the waterfall display. The green Rx +frequency marker will jump to your selected frequency, and the Rx +frequency control on the main window will be updated accordingly. + +- Do the same thing with the *Shift* key held down. Now the red Tx +frequency marker and its associated control on the main window will +follow your frequency selections. + +- Do the same thing with the *Ctrl* key held down. Now the both colored +markers and both spinner controls will follow your selections. + +- Now double-click on any of the the lines of decoded text in the Band +Activity window. Any line will show similar behavior, setting +Rx frequency to that of the selected message and leaving Tx frequency +unchanged. To change both Rx and Tx frequencies, hold *Ctrl* down +when double-clicking. + +TIP: To avoid QRM from competing callers, it is frequently desirable +to answer a CQ on a different frequency from that of the CQing +station. The same is true when you tail-end another QSO. Choose a Tx +frequency that appears to be not in use. You might want to check the +box *Hold Tx Freq*. + +TIP: Keyboard shortcuts *Shift+F11* and *Shift+F12* provide an easy +way to move your FT4 Tx frequency down or up in 90 Hz steps. + +IMPORTANT: When finished with this Tutorial, don't forget to re-enter +your own callsign as *My Call* on the *Settings | General* tab. diff --git a/doc/user_guide/en/wsjtx-main.adoc b/doc/user_guide/en/wsjtx-main.adoc index 6b190e0a2..a3cea81e0 100644 --- a/doc/user_guide/en/wsjtx-main.adoc +++ b/doc/user_guide/en/wsjtx-main.adoc @@ -140,6 +140,10 @@ include::tutorial-example2.adoc[] === FT8 include::tutorial-example3.adoc[] +[[TUT_EX4]] +=== FT4 +include::tutorial-example4.adoc[] + [[MAKE_QSOS]] == Making QSOs include::make-qso.adoc[] diff --git a/item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp b/item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp deleted file mode 100644 index a666ed323..000000000 --- a/item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef DATE_TIME_AS_SECS_SINCE_EPOCH_DELEGATE_HPP_ -#define DATE_TIME_AS_SECS_SINCE_EPOCH_DELEGATE_HPP_ - -#include -#include -#include -#include -#include -#include -#include - -class DateTimeAsSecsSinceEpochDelegate final - : public QStyledItemDelegate -{ -public: - DateTimeAsSecsSinceEpochDelegate (QObject * parent = nullptr) - : QStyledItemDelegate {parent} - { - } - - static QVariant to_secs_since_epoch (QDateTime const& date_time) - { - return date_time.toMSecsSinceEpoch () / 1000ull; - } - - static QDateTime to_date_time (QModelIndex const& index, int role = Qt::DisplayRole) - { - return to_date_time (index.model ()->data (index, role)); - } - - static QDateTime to_date_time (QVariant const& value) - { - return QDateTime::fromMSecsSinceEpoch (value.toULongLong () * 1000ull, Qt::UTC); - } - - QString displayText (QVariant const& value, QLocale const& locale) const override - { - return locale.toString (to_date_time (value), locale.dateFormat (QLocale::ShortFormat) + " hh:mm:ss"); - } - - QWidget * createEditor (QWidget * parent, QStyleOptionViewItem const& /*option*/, QModelIndex const& /*index*/) const override - { - std::unique_ptr editor {new QDateTimeEdit {parent}}; - editor->setDisplayFormat (parent->locale ().dateFormat (QLocale::ShortFormat) + " hh:mm:ss"); - editor->setTimeSpec (Qt::UTC); // needed because it ignores time - // spec of the QDateTime that it is - // set from - return editor.release (); - } - - void setEditorData (QWidget * editor, QModelIndex const& index) const override - { - static_cast (editor)->setDateTime (to_date_time (index, Qt::EditRole)); - } - - void setModelData (QWidget * editor, QAbstractItemModel * model, QModelIndex const& index) const override - { - model->setData (index, to_secs_since_epoch (static_cast (editor)->dateTime ())); - } - - void updateEditorGeometry (QWidget * editor, QStyleOptionViewItem const& option, QModelIndex const& /*index*/) const override - { - editor->setGeometry (option.rect); - } -}; - -#endif diff --git a/item_delegates/FrequencyDelegate.cpp b/item_delegates/FrequencyDelegate.cpp new file mode 100644 index 000000000..b899c0563 --- /dev/null +++ b/item_delegates/FrequencyDelegate.cpp @@ -0,0 +1,27 @@ +#include "FrequencyDelegate.hpp" + +#include "widgets/FrequencyLineEdit.hpp" + +FrequencyDelegate::FrequencyDelegate (QObject * parent) + : QStyledItemDelegate {parent} +{ +} + +QWidget * FrequencyDelegate::createEditor (QWidget * parent, QStyleOptionViewItem const& + , QModelIndex const&) const +{ + auto * editor = new FrequencyLineEdit {parent}; + editor->setFrame (false); + return editor; +} + +void FrequencyDelegate::setEditorData (QWidget * editor, QModelIndex const& index) const +{ + static_cast (editor)->frequency (index.model ()->data (index, Qt::EditRole).value ()); +} + +void FrequencyDelegate::setModelData (QWidget * editor, QAbstractItemModel * model, QModelIndex const& index) const +{ + model->setData (index, static_cast (editor)->frequency (), Qt::EditRole); +} + diff --git a/item_delegates/FrequencyDelegate.hpp b/item_delegates/FrequencyDelegate.hpp new file mode 100644 index 000000000..76fc5545d --- /dev/null +++ b/item_delegates/FrequencyDelegate.hpp @@ -0,0 +1,21 @@ +#ifndef FREQUENCY_DELEGATE_HPP_ +#define FREQUENCY_DELEGATE_HPP_ + +#include + +// +// Class FrequencyDelegate +// +// Item delegate for editing a frequency in Hertz but displayed in MHz +// +class FrequencyDelegate final + : public QStyledItemDelegate +{ +public: + explicit FrequencyDelegate (QObject * parent = nullptr); + QWidget * createEditor (QWidget * parent, QStyleOptionViewItem const&, QModelIndex const&) const override; + void setEditorData (QWidget * editor, QModelIndex const&) const override; + void setModelData (QWidget * editor, QAbstractItemModel *, QModelIndex const&) const override; +}; + +#endif diff --git a/item_delegates/FrequencyDeltaDelegate.cpp b/item_delegates/FrequencyDeltaDelegate.cpp new file mode 100644 index 000000000..40d90dc58 --- /dev/null +++ b/item_delegates/FrequencyDeltaDelegate.cpp @@ -0,0 +1,26 @@ +#include "FrequencyDeltaDelegate.hpp" + +#include "widgets/FrequencyDeltaLineEdit.hpp" + +FrequencyDeltaDelegate::FrequencyDeltaDelegate (QObject * parent) + : QStyledItemDelegate {parent} +{ +} + +QWidget * FrequencyDeltaDelegate::createEditor (QWidget * parent, QStyleOptionViewItem const& + , QModelIndex const&) const +{ + auto * editor = new FrequencyDeltaLineEdit {parent}; + editor->setFrame (false); + return editor; +} + +void FrequencyDeltaDelegate::setEditorData (QWidget * editor, QModelIndex const& index) const +{ + static_cast (editor)->frequency_delta (index.model ()->data (index, Qt::EditRole).value ()); +} + +void FrequencyDeltaDelegate::setModelData (QWidget * editor, QAbstractItemModel * model, QModelIndex const& index) const +{ + model->setData (index, static_cast (editor)->frequency_delta (), Qt::EditRole); +} diff --git a/item_delegates/FrequencyDeltaDelegate.hpp b/item_delegates/FrequencyDeltaDelegate.hpp new file mode 100644 index 000000000..121bc3d94 --- /dev/null +++ b/item_delegates/FrequencyDeltaDelegate.hpp @@ -0,0 +1,21 @@ +#ifndef FREQUENCY_DELTA_DELEGATE_HPP_ +#define FREQUENCY_DELTA_DELEGATE_HPP_ + +#include + +// +// Class FrequencyDeltaDelegate +// +// Item delegate for editing a frequency delta in Hertz but displayed in MHz +// +class FrequencyDeltaDelegate final + : public QStyledItemDelegate +{ +public: + explicit FrequencyDeltaDelegate (QObject * parent = nullptr); + QWidget * createEditor (QWidget * parent, QStyleOptionViewItem const&, QModelIndex const&) const override; + void setEditorData (QWidget * editor, QModelIndex const&) const override; + void setModelData (QWidget * editor, QAbstractItemModel *, QModelIndex const&) const override; +}; + +#endif diff --git a/item_delegates/item_delegates.pri b/item_delegates/item_delegates.pri index 153ad4271..819cb2e0c 100644 --- a/item_delegates/item_delegates.pri +++ b/item_delegates/item_delegates.pri @@ -1,12 +1,13 @@ SOURCES += \ item_delegates/ForeignKeyDelegate.cpp \ - item_delegates/FrequencyItemDelegate.cpp \ + item_delegates/FrequencyDelegate.cpp \ + item_delegates/FrequencyDeltaDelegate.cpp \ item_delegates/CallsignDelegate.cpp \ item_delegates/MaidenheadLocatorItemDelegate.cpp HEADERS += \ item_delegates/ForeignKeyDelegate.hpp \ - item_delegates/FrequencyItemDelegate.hpp \ + item_delegates/FrequencyDelegate.hpp \ + item_delegates/FrequencyDeltaDelegate.hpp \ item_delegates/CallsignDelegate.hpp \ - item_delegates/MaidenheadLocatorDelegate.hpp \ - item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp + item_delegates/MaidenheadLocatorDelegate.hpp diff --git a/lib/77bit/77bit.txt b/lib/77bit/77bit.txt index ef370c111..89b481b6c 100644 --- a/lib/77bit/77bit.txt +++ b/lib/77bit/77bit.txt @@ -22,15 +22,10 @@ i3.n3 Example message Bits Total Purpose 2 PA3XYZ/P GM4ABC/P R JO22 28 1 28 1 1 15 74 EU VHF contest 3 TU; W9XYZ K1ABC R 579 MA 1 28 28 1 3 13 74 ARRL RTTY Roundup 4 PJ4/KA1ABC RR73 12 58 1 2 1 74 Nonstandard calls -5 ... tbd +5 TU; W9XYZ K1ABC R-07 FN 1 28 28 1 7 9 74 WWROF contest ? 6 ... tbd 7 ... tbd ---------------------------------------------------------------------------------- -In case we need them, later: - -5 TU; W9XYZ K1ABC R 579 8 MA 1 28 28 1 3 6 7 74 CQ WW RTTY -6 TU; W9XYZ K1ABC R 579 MA 1 28 28 1 3 13 74 CQ WPX RTTY ----------------------------------------------------------------------------------- NB: three 74-bit message types and two 71-bit message subtypes are still TBD. ---------------------------------------------------------------------------------- diff --git a/lib/77bit/messages.txt b/lib/77bit/messages.txt index 54fd44b05..aa4ab0789 100644 --- a/lib/77bit/messages.txt +++ b/lib/77bit/messages.txt @@ -72,7 +72,18 @@ CQ W9XYZ EN37 W9XYZ R-09 YW18FIFA RRR YW18FIFA 73 -10. Other stuff + +10. WWROF FT8/FT4 contest +----------------------------------------------------------- +CQ TEST K1ABC FN42 + K1ABC W9XYZ -16 EN +W9XYZ K1ABC R-07 FN + K1ABC W9XYZ RR73 + K1ABC G3AAA -11 IO +TU; G3AAA K1ABC R-09 FN + K1ABC G3AAA RR73 + +11. Other stuff ----------------------------------------------------------- TNX BOB 73 GL CQ YW18FIFA diff --git a/lib/77bit/packjt77.f90 b/lib/77bit/packjt77.f90 index 1ee37f5c1..1f9ed9a19 100644 --- a/lib/77bit/packjt77.f90 +++ b/lib/77bit/packjt77.f90 @@ -172,6 +172,10 @@ subroutine pack77(msg0,i3,n3,c77) call pack77_4(nwords,w,i3,n3,c77) if(i3.ge.0) go to 900 +! Check Type 5 (WWROF contest exchange) + call pack77_5(nwords,w,i3,n3,c77) + if(i3.ge.0) go to 900 + ! It defaults to free text 800 i3=0 n3=0 @@ -204,6 +208,7 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) character*6 cexch,grid6 character*4 grid4,cserial character*3 csec(NSEC) + character*2 cfield character*38 c integer hashmy10,hashmy12,hashmy22,hashdx10,hashdx12,hashdx22 logical unpk28_success,unpk77_success @@ -491,8 +496,31 @@ subroutine unpack77(c77,nrx,msg,unpk77_success) else msg='CQ '//trim(call_2) endif + + else if(i3.eq.5) then +! 5 TU; W9XYZ K1ABC R-09 FN 1 28 28 1 7 9 74 WWROF contest + read(c77,1041) itu,n28a,n28b,ir,irpt,nexch,i3 +1041 format(b1,2b28.28,b1,b7.7,b9.9,b3.3) + call unpack28(n28a,call_1,unpk28_success) + if(.not.unpk28_success) unpk77_success=.false. + call unpack28(n28b,call_2,unpk28_success) + if(.not.unpk28_success) unpk77_success=.false. + write(crpt,'(i3.2)') irpt-35 + if(crpt(1:1).eq.' ') crpt(1:1)='+' + n1=nexch/18 + n2=nexch - 18*n1 + cfield(1:1)=char(ichar('A')+n1) + cfield(2:2)=char(ichar('A')+n2) + if(itu.eq.0 .and. ir.eq.0) msg=trim(call_1)//' '//trim(call_2)// & + ' '//crpt//' '//cfield + if(itu.eq.1 .and. ir.eq.0) msg='TU; '//trim(call_1)//' '//trim(call_2)// & + ' '//crpt//' '//cfield + if(itu.eq.0 .and. ir.eq.1) msg=trim(call_1)//' '//trim(call_2)// & + ' R'//crpt//' '//cfield + if(itu.eq.1 .and. ir.eq.1) msg='TU; '//trim(call_1)//' '//trim(call_2)// & + ' R'//crpt//' '//cfield endif - if(msg(1:4).eq.'CQ <') unpk77_success=.false. +! if(msg(1:4).eq.'CQ <') unpk77_success=.false. return end subroutine unpack77 @@ -1040,12 +1068,11 @@ subroutine pack77_3(nwords,w,i3,n3,c77) call chkcall(w(i1+1),bcall_2,ok2) if(.not.ok1 .or. .not.ok2) go to 900 crpt=w(nwords-1)(1:3) + if(index(crpt,'-').ge.1 .or. index(crpt,'+').ge.1) go to 900 if(crpt(1:1).eq.'5' .and. crpt(2:2).ge.'2' .and. crpt(2:2).le.'9' .and. & crpt(3:3).eq.'9') then nserial=0 read(w(nwords),*,err=1) nserial -!1 i3=3 -! n3=0 endif 1 mult=' ' imult=-1 @@ -1150,6 +1177,60 @@ subroutine pack77_4(nwords,w,i3,n3,c77) 900 return end subroutine pack77_4 +subroutine pack77_5(nwords,w,i3,n3,c77) +! Check Type 5 (WWROF contest exchange) + + character*13 w(19) + character*77 c77 + character*6 bcall_1,bcall_2 + character*3 mult + character crpt*4 + character c1*1,c2*2 + logical ok1,ok2 + + if(nwords.eq.4 .or. nwords.eq.5 .or. nwords.eq.6) then + i1=1 + if(trim(w(1)).eq.'TU;') i1=2 + call chkcall(w(i1),bcall_1,ok1) + call chkcall(w(i1+1),bcall_2,ok2) + if(.not.ok1 .or. .not.ok2) go to 900 + crpt=w(nwords-1)(1:4) + if(index(crpt,'-').lt.1 .and. index(crpt,'+').lt.1) go to 900 + + c1=crpt(1:1) + c2=crpt(1:2) + irpt=-1 + if(c1.eq.'+' .or. c1.eq.'-') then + ir=0 + read(w(nwords-1),*,err=900) irpt + irpt=irpt+35 + else if(c2.eq.'R+' .or. c2.eq.'R-') then + ir=1 + read(w(nwords-1)(2:),*) irpt + irpt=irpt+35 + endif + if(irpt.eq.-1 .or. len(trim(w(nwords))).ne.2) go to 900 + c2=w(nwords)(1:2) + n1=ichar(c2(1:1)) - ichar('A') + n2=ichar(c2(2:2)) - ichar('A') + if(n1.lt.0 .or. n1.gt.17) go to 900 + if(n2.lt.0 .or. n2.gt.17) go to 900 + nexch=18*n1 + n2 + i3=5 + n3=0 + itu=0 + if(trim(w(1)).eq.'TU;') itu=1 + call pack28(w(1+itu),n28a) + call pack28(w(2+itu),n28b) +! 5 TU; W9XYZ K1ABC R-09 FN 1 28 28 1 7 9 74 WWROF contest + write(c77,1010) itu,n28a,n28b,ir,irpt,nexch,i3 +1010 format(b1,2b28.28,b1,b7.7,b9.9,b3.3) + + end if + +900 return +end subroutine pack77_5 + subroutine packtext77(c13,c71) character*13 c13,w diff --git a/lib/astrosub.f90 b/lib/astrosub.f90 index 49551ce3e..0670d66dc 100644 --- a/lib/astrosub.f90 +++ b/lib/astrosub.f90 @@ -1,55 +1,97 @@ -subroutine astrosub(nyear,month,nday,uth8,freq8,mygrid,hisgrid, & - AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, & - RAMoon8,DecMoon8,Dgrd8,poloffset8,xnr8,techo8,width1,width2,bTx, & - AzElFileName,jpleph) +module astro_module + use, intrinsic :: iso_c_binding, only : c_int, c_double, c_bool, c_char, c_ptr, c_size_t, c_f_pointer + implicit none - implicit real*8 (a-h,o-z) - character*6 mygrid,hisgrid,c1*1 - character*6 AzElFileName*(*),jpleph*(*) - character*256 jpleph_file_name - logical*1 bTx - common/jplcom/jpleph_file_name + private + public :: astrosub - jpleph_file_name=jpleph +contains - call astro0(nyear,month,nday,uth8,freq8,mygrid,hisgrid, & - AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, & - dbMoon8,RAMoon8,DecMoon8,HA8,Dgrd8,sd8,poloffset8,xnr8,dfdt,dfdt0, & - width1,width2,xlst8,techo8) + subroutine astrosub(nyear,month,nday,uth8,freq8,mygrid_cp,mygrid_len, & + hisgrid_cp,hisgrid_len,AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8, & + ntsky,ndop,ndop00,RAMoon8,DecMoon8,Dgrd8,poloffset8,xnr8,techo8,width1, & + width2,bTx,AzElFileName_cp,AzElFileName_len,jpleph_cp,jpleph_len) & + bind (C, name="astrosub") - if (len_trim(AzElFileName) .eq. 0) go to 999 - imin=60*uth8 - isec=3600*uth8 - ih=uth8 - im=mod(imin,60) - is=mod(isec,60) - open(15,file=AzElFileName,status='unknown',err=900) - c1='R' - nRx=1 - if(bTx) then - c1='T' - nRx=0 - endif - AzAux=0. - ElAux=0. - nfreq=freq8/1000000 - doppler=ndop - doppler00=ndop00 - write(15,1010,err=10) ih,im,is,AzMoon8,ElMoon8, & - ih,im,is,AzSun8,ElSun8, & - ih,im,is,AzAux,ElAux, & - nfreq,doppler,dfdt,doppler00,dfdt0,c1 -! TXFirst,TRPeriod,poloffset,Dgrd,xnr,ave,rms,nRx + integer, parameter :: dp = selected_real_kind(15, 50) + + integer(c_int), intent(in), value :: nyear, month, nday + real(c_double), intent(in), value :: uth8, freq8 + real(c_double), intent(out) :: AzSun8, ElSun8, AzMoon8, ElMoon8, AzMoonB8, & + ElMoonB8, Ramoon8, DecMoon8, Dgrd8, poloffset8, xnr8, techo8, width1, & + width2 + integer(c_int), intent(out) :: ntsky, ndop, ndop00 + logical(c_bool), intent(in), value :: bTx + type(c_ptr), intent(in), value :: mygrid_cp, hisgrid_cp, AzElFileName_cp, jpleph_cp + integer(c_size_t), intent(in), value :: mygrid_len, hisgrid_len, AzElFileName_len, jpleph_len + + character(len=6) :: mygrid, hisgrid + character(kind=c_char, len=:), allocatable :: AzElFileName + character(len=1) :: c1 + integer :: ih, im, imin, is, isec, nfreq, nRx + real(dp) :: AzAux, ElAux, dbMoon8, dfdt, dfdt0, doppler, doppler00, HA8, sd8, xlst8 + character*256 jpleph_file_name + common/jplcom/jpleph_file_name + + block + character(kind=c_char, len=mygrid_len), pointer :: mygrid_fp + character(kind=c_char, len=hisgrid_len), pointer :: hisgrid_fp + character(kind=c_char, len=AzElFileName_len), pointer :: AzElFileName_fp + character(kind=c_char, len=jpleph_len), pointer :: jpleph_fp + call c_f_pointer(cptr=mygrid_cp, fptr=mygrid_fp) + mygrid = mygrid_fp + mygrid_fp => null() + call c_f_pointer(cptr=hisgrid_cp, fptr=hisgrid_fp) + hisgrid = hisgrid_fp + hisgrid_fp => null() + call c_f_pointer(cptr=AzElFileName_cp, fptr=AzElFileName_fp) + AzElFileName = AzElFileName_fp + AzElFileName_fp => null() + call c_f_pointer(cptr=jpleph_cp, fptr=jpleph_fp) + jpleph_file_name = jpleph_fp + jpleph_fp => null() + end block + + call astro0(nyear,month,nday,uth8,freq8,mygrid,hisgrid, & + AzSun8,ElSun8,AzMoon8,ElMoon8,AzMoonB8,ElMoonB8,ntsky,ndop,ndop00, & + dbMoon8,RAMoon8,DecMoon8,HA8,Dgrd8,sd8,poloffset8,xnr8,dfdt,dfdt0, & + width1,width2,xlst8,techo8) + + if (len_trim(AzElFileName) .eq. 0) go to 999 + imin=60*uth8 + isec=3600*uth8 + ih=uth8 + im=mod(imin,60) + is=mod(isec,60) + open(15,file=AzElFileName,status='unknown',err=900) + c1='R' + nRx=1 + if(bTx) then + c1='T' + nRx=0 + endif + AzAux=0. + ElAux=0. + nfreq=freq8/1000000 + doppler=ndop + doppler00=ndop00 + write(15,1010,err=10) ih,im,is,AzMoon8,ElMoon8, & + ih,im,is,AzSun8,ElSun8, & + ih,im,is,AzAux,ElAux, & + nfreq,doppler,dfdt,doppler00,dfdt0,c1 + ! TXFirst,TRPeriod,poloffset,Dgrd,xnr,ave,rms,nRx 1010 format( & - i2.2,':',i2.2,':',i2.2,',',f5.1,',',f5.1,',Moon'/ & - i2.2,':',i2.2,':',i2.2,',',f5.1,',',f5.1,',Sun'/ & - i2.2,':',i2.2,':',i2.2,',',f5.1,',',f5.1,',Source'/ & - i5,',',f8.1,',',f8.2,',',f8.1,',',f8.2,',Doppler, ',a1) -! i1,',',i3,',',f8.1,','f8.1,',',f8.1,',',f12.3,',',f12.3,',',i1,',RPol') -10 close(15) - go to 999 + i2.2,':',i2.2,':',i2.2,',',f5.1,',',f5.1,',Moon'/ & + i2.2,':',i2.2,':',i2.2,',',f5.1,',',f5.1,',Sun'/ & + i2.2,':',i2.2,':',i2.2,',',f5.1,',',f5.1,',Source'/ & + i5,',',f8.1,',',f8.2,',',f8.1,',',f8.2,',Doppler, ',a1) + ! i1,',',i3,',',f8.1,','f8.1,',',f8.1,',',f12.3,',',f12.3,',',i1,',RPol') +10 close(15) + go to 999 900 print*,'Error opening azel.dat' 999 return -end subroutine astrosub + end subroutine astrosub + +end module astro_module diff --git a/lib/azdist.f90 b/lib/azdist.f90 index 2fd26c3d7..41a8fc5bc 100644 --- a/lib/azdist.f90 +++ b/lib/azdist.f90 @@ -1,7 +1,7 @@ -subroutine azdist(grid1,grid2,utch,nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter) +subroutine azdist(MyGrid,HisGrid,utch,nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter) - character*(*) grid1,grid2 - character*6 MyGrid,HisGrid,mygrid0,hisgrid0 + character(len=*) :: MyGrid,HisGrid + character*6 mygrid0,hisgrid0 real*8 utch,utch0 logical HotABetter,IamEast real eltab(22),daztab(22) @@ -12,11 +12,6 @@ subroutine azdist(grid1,grid2,utch,nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter) data mygrid0/" "/,hisgrid0/" "/,utch0/-999.d0/ save - MyGrid=grid1//' ' - HisGrid=grid2//' ' - if(ichar(MyGrid(5:5)).eq.0) MyGrid(5:6)=' ' - if(ichar(HisGrid(5:5)).eq.0) HisGrid(5:6)=' ' - if(MyGrid.eq.HisGrid) then naz=0 nel=0 diff --git a/lib/decoder.f90 b/lib/decoder.f90 index 37ca5b1bd..8abdcb75f 100644 --- a/lib/decoder.f90 +++ b/lib/decoder.f90 @@ -133,8 +133,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample) n30fox(j)=n m=n30max-n if(len(trim(g2fox(j))).eq.4) then - call azdist(mygrid,g2fox(j),0.d0,nAz,nEl,nDmiles,nDkm, & - nHotAz,nHotABetter) + call azdist(mygrid,g2fox(j)//' ',0.d0,nAz,nEl,nDmiles, & + nDkm,nHotAz,nHotABetter) else nDkm=9999 endif @@ -152,8 +152,8 @@ subroutine multimode_decoder(ss,id2,params,nfsample) if(params%nmode.eq.5) then call timer('decft4 ',0) call my_ft4%decode(ft4_decoded,id2,params%nQSOProgress,params%nfqso, & - params%nutc,params%nfa,params%nfb,params%ndepth,ncontest, & - mycall,hiscall) + params%nutc,params%nfa,params%nfb,params%ndepth, & + logical(params%lapcqonly),ncontest,mycall,hiscall) call timer('decft4 ',1) go to 800 endif @@ -517,7 +517,7 @@ contains decoded0=decoded annot=' ' - if(ncontest.eq.0 .and. nap.ne.0) then + if(nap.ne.0) then write(annot,'(a1,i1)') 'a',nap if(qual.lt.0.17) decoded0(37:37)='?' endif @@ -598,15 +598,15 @@ contains decoded0=decoded annot=' ' - if(ncontest.eq.0 .and. nap.ne.0) then + if(nap.ne.0) then write(annot,'(a1,i1)') 'a',nap if(qual.lt.0.17) decoded0(37:37)='?' endif write(*,1001) params%nutc,snr,dt,nint(freq),decoded0,annot -1001 format(i6.6,i4,f5.1,i5,' ~ ',1x,a37,1x,a2) +1001 format(i6.6,i4,f5.1,i5,' + ',1x,a37,1x,a2) write(13,1002) params%nutc,nint(sync),snr,dt,freq,0,decoded0 -1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FT8') +1002 format(i6.6,i4,i5,f6.1,f8.0,i4,3x,a37,' FT4') call flush(6) call flush(13) diff --git a/lib/fast_decode.f90 b/lib/fast_decode.f90 index eebb73108..c3cadb6a7 100644 --- a/lib/fast_decode.f90 +++ b/lib/fast_decode.f90 @@ -1,4 +1,4 @@ -subroutine fast_decode(id2,narg,ntrperiod,line,mycall_12, & +subroutine fast_decode(id2,narg,trperiod,line,mycall_12, & hiscall_12) parameter (NMAX=30*12000) @@ -6,6 +6,7 @@ subroutine fast_decode(id2,narg,ntrperiod,line,mycall_12, & integer*2 id2a(NMAX) integer*2 id2b(NMAX) integer narg(0:14) + double precision trperiod real dat(30*12000) complex cdat(262145),cdat2(262145) real psavg(450) @@ -41,7 +42,7 @@ subroutine fast_decode(id2,narg,ntrperiod,line,mycall_12, & nhashcalls=narg(12) line(1:100)(1:1)=char(0) - if(t0.gt.float(ntrperiod)) go to 900 + if(t0.gt.trperiod) go to 900 if(t0.gt.t1) go to 900 if(nmode.eq.102) then @@ -53,7 +54,7 @@ subroutine fast_decode(id2,narg,ntrperiod,line,mycall_12, & cdat2=cdat ndat=ndat0 call wav11(id2,ndat,dat) - nzz=11025*ntrperiod + nzz=11025*int(trperiod) !beware if fractional T/R period ever used here if(ndat.lt.nzz) dat(ndat+1:nzz)=0.0 ndat=min(ndat,30*11025) call ana932(dat,ndat,cdat,npts) !Make downsampled analytic signal diff --git a/lib/freqcal.f90 b/lib/freqcal.f90 index 540237f6e..80ce90c66 100644 --- a/lib/freqcal.f90 +++ b/lib/freqcal.f90 @@ -41,6 +41,7 @@ subroutine freqcal(id2,k,nkhz,noffset,ntol,line) endif smax=0. s=0. + ipk=-99 do i=ia,ib s(i)=real(cx(i))**2 + aimag(cx(i))**2 if(s(i).gt.smax) then @@ -48,25 +49,32 @@ subroutine freqcal(id2,k,nkhz,noffset,ntol,line) ipk=i endif enddo - - call peakup(s(ipk-1),s(ipk),s(ipk+1),dx) - fpeak=df * (ipk+dx) - ap=(fpeak/fs+1.0/(2.0*NFFT)) - an=(fpeak/fs-1.0/(2.0*NFFT)) - sp=sum(id2((k-NFFT):k-1)*cmplx(cos(xi*ap),-sin(xi*ap))) - sn=sum(id2((k-NFFT):k-1)*cmplx(cos(xi*an),-sin(xi*an))) - fpeak=fpeak+fs*(abs(sp)-abs(sn))/(abs(sp)+abs(sn))/(2*NFFT) - xsum=0. - nsum=0 - do i=ia,ib - if(abs(i-ipk).gt.10) then - xsum=xsum+s(i) - nsum=nsum+1 - endif - enddo - ave=xsum/nsum - snr=db(smax/ave) - pave=db(ave) + 8.0 + + if(ipk.ge.1) then + call peakup(s(ipk-1),s(ipk),s(ipk+1),dx) + fpeak=df * (ipk+dx) + ap=(fpeak/fs+1.0/(2.0*NFFT)) + an=(fpeak/fs-1.0/(2.0*NFFT)) + sp=sum(id2((k-NFFT):k-1)*cmplx(cos(xi*ap),-sin(xi*ap))) + sn=sum(id2((k-NFFT):k-1)*cmplx(cos(xi*an),-sin(xi*an))) + fpeak=fpeak+fs*(abs(sp)-abs(sn))/(abs(sp)+abs(sn))/(2*NFFT) + xsum=0. + nsum=0 + do i=ia,ib + if(abs(i-ipk).gt.10) then + xsum=xsum+s(i) + nsum=nsum+1 + endif + enddo + ave=xsum/nsum + snr=db(smax/ave) + pave=db(ave) + 8.0 + else + snr=-99.9 + pave=-99.9 + fpeak=-99.9 + ferr=-99.9 + endif cflag=' ' if(snr.lt.20.0) cflag='*' n=n+1 @@ -77,7 +85,7 @@ subroutine freqcal(id2,k,nkhz,noffset,ntol,line) ncal=1 ferr=fpeak-noffset write(line,1100) nhr,nmin,nsec,nkhz,ncal,noffset,fpeak,ferr,pave, & - snr,cflag,char(0) + snr,cflag,char(0) 1100 format(i2.2,':',i2.2,':',i2.2,i7,i3,i6,2f10.3,2f7.1,2x,a1,a1) 900 return diff --git a/lib/ft4/averaged_mf.f90 b/lib/ft4/averaged_mf.f90 new file mode 100644 index 000000000..2986572b3 --- /dev/null +++ b/lib/ft4/averaged_mf.f90 @@ -0,0 +1,64 @@ +program averaged_mf + + parameter (nsps=32) + complex cgfsk(3*nsps,64) + complex clin(3*nsps,64) + complex cavg(3*nsps,4) + complex cavl(3*nsps,4) + real pulse(3*nsps) + real dphi(3*nsps) + + do i=1,3*NSPS + t=(i-1.5*nsps)/real(nsps) + pulse(i)=gfsk_pulse(1.0,t) + enddo + + twopi=8.0*atan(1.0) + hmod=1.0 + dphi_peak=twopi*hmod/real(nsps) + + do iwf=1,64 + i0=mod((iwf-1)/16,4) + i1=mod((iwf-1)/4,4) + i2=mod(iwf-1,4) + dphi=0.0 + dphi(1:64)=dphi_peak*pulse(33:96)*i1 + dphi(1:96)=dphi(1:96)+dphi_peak*pulse(1:96)*i0 + dphi(33:96)=dphi(33:96)+dphi_peak*pulse(1:64)*i2 + phi=0.0 + do j=1,96 + cgfsk(j,iwf)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi(j),twopi) + enddo + cgfsk(:,iwf)=cgfsk(:,iwf)*conjg(cgfsk(48,iwf)) + enddo + + do iwf=1,64 + i0=mod((iwf-1)/16,4) + i1=mod((iwf-1)/4,4) + i2=mod(iwf-1,4) + dphi=0.0 + dphi(1:32)=dphi_peak*i1 + dphi(33:64)=dphi_peak*i0 + dphi(65:96)=dphi_peak*i2 + phi=0.0 + do j=1,96 + clin(j,iwf)=cmplx(cos(phi),sin(phi)) + phi=mod(phi+dphi(j),twopi) + enddo + enddo + + + do i=1,4 + ib=(i-1)*16+1 + ie=ib+15 + cavg(:,i)=sum(cgfsk(:,ib:ie),2)/16.0 + cavl(:,i)=sum(clin(:,ib:ie),2)/16.0 + do j=1,96 +write(*,*) j +write(21,*) i,j,real(cavg(j,i)),imag(cavg(j,i)),real(cavl(j,i)),imag(cavl(j,i)) + enddo + enddo + +end program averaged_mf + diff --git a/lib/ft4/ft4_baseline.f90 b/lib/ft4/ft4_baseline.f90 new file mode 100644 index 000000000..85a60d9ec --- /dev/null +++ b/lib/ft4/ft4_baseline.f90 @@ -0,0 +1,49 @@ +subroutine ft4_baseline(s,nfa,nfb,sbase) + +! Fit baseline to spectrum +! Input: s(npts) Linear scale in power +! Output: sbase(npts) Baseline + + include 'ft4_params.f90' + implicit real*8 (a-h,o-z) + real*4 s(NH1) + real*4 sbase(NH1) + real*4 base + real*8 x(1000),y(1000),a(5) + data nseg/10/,npct/10/ + + df=12000.0/NFFT1 !5.21 Hz + ia=max(nint(200.0/df),nfa) + ib=min(NH1,nfb) + do i=ia,ib + s(i)=10.0*log10(s(i)) !Convert to dB scale + enddo + + nterms=5 + nlen=(ib-ia+1)/nseg !Length of test segment + i0=(ib-ia+1)/2 !Midpoint + k=0 + do n=1,nseg !Loop over all segments + ja=ia + (n-1)*nlen + jb=ja+nlen-1 + call pctile(s(ja),nlen,npct,base) !Find lowest npct of points + do i=ja,jb + if(s(i).le.base) then + if (k.lt.1000) k=k+1 !Save all "lower envelope" points + x(k)=i-i0 + y(k)=s(i) + endif + enddo + enddo + kz=k + a=0. + call polyfit(x,y,y,kz,nterms,0,a,chisqr) !Fit a low-order polynomial + do i=ia,ib + t=i-i0 + sbase(i)=a(1)+t*(a(2)+t*(a(3)+t*(a(4)+t*(a(5))))) + 0.65 +! write(51,3051) i*df,s(i),sbase(i) +!3051 format(3f12.3) + sbase(i)=10**(sbase(i)/10.0) + enddo + return +end subroutine ft4_baseline diff --git a/lib/ft4/ft4_downsample.f90 b/lib/ft4/ft4_downsample.f90 index ff0595629..bbe53a2a2 100644 --- a/lib/ft4/ft4_downsample.f90 +++ b/lib/ft4/ft4_downsample.f90 @@ -1,11 +1,8 @@ -subroutine ft4_downsample(iwave,newdata,f0,c) - -! Input: i*2 data in iwave() at sample rate 12000 Hz -! Output: Complex data in c(), sampled at 1200 Hz +subroutine ft4_downsample(dd,newdata,f0,c) include 'ft4_params.f90' - parameter (NFFT2=NMAX/16) - integer*2 iwave(NMAX) + parameter (NFFT2=NMAX/NDOWN) + real dd(NMAX) complex c(0:NMAX/NDOWN-1) complex c1(0:NFFT2-1) complex cx(0:NMAX/2) @@ -33,15 +30,15 @@ subroutine ft4_downsample(iwave,newdata,f0,c) endif if(newdata) then - x=iwave + x=dd call four2a(x,NMAX,1,-1,0) !r2c FFT to freq domain endif i0=nint(f0/df) c1=0. - c1(0)=cx(i0) + if(i0.ge.0 .and. i0.le.NMAX/2) c1(0)=cx(i0) do i=1,NFFT2/2 - if(i0+i.le.NMAX/2) c1(i)=cx(i0+i) - if(i0-i.ge.0) c1(NFFT2-i)=cx(i0-i) + if(i0+i.ge.0 .and. i0+i.le.NMAX/2) c1(i)=cx(i0+i) + if(i0-i.ge.0 .and. i0-i.le.NMAX/2) c1(NFFT2-i)=cx(i0-i) enddo c1=c1*window/NFFT2 call four2a(c1,NFFT2,1,1,1) !c2c FFT back to time domain diff --git a/lib/ft4/ft4_params.f90 b/lib/ft4/ft4_params.f90 index 02d9de655..43abc573a 100644 --- a/lib/ft4/ft4_params.f90 +++ b/lib/ft4/ft4_params.f90 @@ -1,16 +1,16 @@ ! FT4 -! LDPC(174,91) code, four 4x4 Costas arrays for Sync +! LDPC(174,91) code, four 4x4 Costas arrays for sync, ramp-up and ramp-down symbols parameter (KK=91) !Information bits (77 + CRC14) parameter (ND=87) !Data symbols parameter (NS=16) !Sync symbols parameter (NN=NS+ND) !Sync and data symbols (103) parameter (NN2=NS+ND+2) !Total channel symbols (105) -parameter (NSPS=512) !Samples per symbol at 12000 S/s -parameter (NZ=NSPS*NN) !Sync and Data samples (52736) -parameter (NZ2=NSPS*NN2) !Total samples in shaped waveform (53760) -parameter (NMAX=5*12000) !Samples in iwave (60,000) -parameter (NFFT1=2048, NH1=NFFT1/2) !Length of FFTs for symbol spectra +parameter (NSPS=576) !Samples per symbol at 12000 S/s +parameter (NZ=NSPS*NN) !Sync and Data samples (59328) +parameter (NZ2=NSPS*NN2) !Total samples in shaped waveform (60480) +parameter (NMAX=21*3456) !Samples in iwave (72576) +parameter (NFFT1=2304, NH1=NFFT1/2) !Length of FFTs for symbol spectra parameter (NSTEP=NSPS) !Coarse time-sync step size parameter (NHSYM=(NMAX-NFFT1)/NSTEP) !Number of symbol spectra (1/4-sym steps) -parameter (NDOWN=16) !Downsample factor +parameter (NDOWN=18) !Downsample factor diff --git a/lib/ft4/ft4b.f90 b/lib/ft4/ft4b.f90 deleted file mode 100644 index d425277ef..000000000 --- a/lib/ft4/ft4b.f90 +++ /dev/null @@ -1,489 +0,0 @@ -subroutine ft4b(cdatetime0,tbuf,nfa,nfb,nQSOProgress,ncontest,nfqso, & - iwave,ndecodes,mycall,hiscall,cqstr,line,data_dir) - - use packjt77 - include 'ft4_params.f90' - parameter (NSS=NSPS/NDOWN) - - character message*37,msgsent*37,msg0*37 - character c77*77 - character*61 line,linex(100) - character*37 decodes(100) - character*512 data_dir,fname - character*17 cdatetime0 - character*12 mycall,hiscall - character*12 mycall0,hiscall0 - character*6 hhmmss - character*4 cqstr,cqstr0 - - complex cd2(0:NMAX/NDOWN-1) !Complex waveform - complex cb(0:NMAX/NDOWN-1) - complex cd(0:NN*NSS-1) !Complex waveform - complex ctwk(2*NSS),ctwk2(2*NSS,-16:16) - complex csymb(NSS) - complex cs(0:3,NN) - real s4(0:3,NN) - - real bmeta(2*NN),bmetb(2*NN),bmetc(2*NN) - real a(5) - real llr(2*ND),llra(2*ND),llrb(2*ND),llrc(2*ND),llrd(2*ND) - real s2(0:255) - real candidate(3,100) - real savg(NH1),sbase(NH1) - - integer apbits(2*ND) - integer apmy_ru(28),aphis_fd(28) - integer icos4a(0:3),icos4b(0:3),icos4c(0:3),icos4d(0:3) - integer*2 iwave(NMAX) !Raw received data - integer*1 message77(77),rvec(77),apmask(2*ND),cw(2*ND) - integer*1 hbits(2*NN) - integer graymap(0:3) - integer ip(1) - integer nappasses(0:5) ! # of decoding passes for QSO States 0-5 - integer naptypes(0:5,4) ! nQSOProgress, decoding pass - integer mcq(29) - integer mrrr(19),m73(19),mrr73(19) - - logical nohiscall,unpk77_success - logical one(0:255,0:7) ! 256 4-symbol sequences, 8 bits - logical first, dobigfft - - data icos4a/0,1,3,2/ - data icos4b/1,0,2,3/ - data icos4c/2,3,1,0/ - data icos4d/3,2,0,1/ - data graymap/0,1,3,2/ - data msg0/' '/ - data first/.true./ - data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ - data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ - data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/ - data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/ - data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & - 1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1,1,1,0,0,1,0,1, & - 0,1,0,1,0,1,1,0,1,1,1,1,1,0,0,0,1,0,1/ - save fs,dt,tt,txt,twopi,h,one,first,linex,apbits,nappasses,naptypes, & - mycall0,hiscall0,msg0,cqstr0,ctwk2 - - call clockit('ft4_deco',0) - hhmmss=cdatetime0(8:13) - - if(first) then - fs=12000.0/NDOWN !Sample rate after downsampling - dt=1/fs !Sample interval after downsample (s) - tt=NSPS*dt !Duration of "itone" symbols (s) - txt=NZ*dt !Transmission length (s) without ramp up/down - twopi=8.0*atan(1.0) - h=1.0 - one=.false. - do i=0,255 - do j=0,7 - if(iand(i,2**j).ne.0) one(i,j)=.true. - enddo - enddo - - do idf=-16,16 - a=0. - a(1)=real(idf) - ctwk=1. - call clockit('twkfreq1',0) - call twkfreq1(ctwk,2*NSS,fs/2.0,a,ctwk2(:,idf)) - call clockit('twkfreq1',1) - enddo - - mrrr=2*mod(mrrr+rvec(59:77),2)-1 - m73=2*mod(m73+rvec(59:77),2)-1 - mrr73=2*mod(mrr73+rvec(59:77),2)-1 - nappasses(0)=2 - nappasses(1)=2 - nappasses(2)=2 - nappasses(3)=2 - nappasses(4)=2 - nappasses(5)=3 - -! iaptype -!------------------------ -! 1 CQ ??? ??? (29 ap bits) -! 2 MyCall ??? ??? (29 ap bits) -! 3 MyCall DxCall ??? (58 ap bits) -! 4 MyCall DxCall RRR (77 ap bits) -! 5 MyCall DxCall 73 (77 ap bits) -! 6 MyCall DxCall RR73 (77 ap bits) -!******** - naptypes(0,1:4)=(/1,2,0,0/) ! Tx6 selected (CQ) - naptypes(1,1:4)=(/2,3,0,0/) ! Tx1 - naptypes(2,1:4)=(/2,3,0,0/) ! Tx2 - naptypes(3,1:4)=(/3,6,0,0/) ! Tx3 - naptypes(4,1:4)=(/3,6,0,0/) ! Tx4 - naptypes(5,1:4)=(/3,1,2,0/) ! Tx5 - - mycall0='' - hiscall0='' - cqstr0='' - first=.false. - endif - - if(cqstr.ne.cqstr0) then - i0=index(cqstr,' ') - if(i0.le.1) then - message='CQ A1AA AA01' - else - message='CQ '//cqstr(1:i0-1)//' A1AA AA01' - endif - i3=-1 - n3=-1 - call pack77(message,i3,n3,c77) - call unpack77(c77,1,msgsent,unpk77_success) - read(c77,'(29i1)') mcq - mcq=2*mod(mcq+rvec(1:29),2)-1 - cqstr0=cqstr - endif - - l1=index(mycall,char(0)) - if(l1.ne.0) mycall(l1:)=" " - l1=index(hiscall,char(0)) - if(l1.ne.0) hiscall(l1:)=" " - if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then - apbits=0 - apbits(1)=99 - apbits(30)=99 - apmy_ru=0 - aphis_fd=0 - - if(len(trim(mycall)) .lt. 3) go to 10 - - nohiscall=.false. - hiscall0=hiscall - if(len(trim(hiscall0)).lt.3) then - hiscall0=mycall ! use mycall for dummy hiscall - mycall won't be hashed. - nohiscall=.true. - endif - message=trim(mycall)//' '//trim(hiscall0)//' RR73' - i3=-1 - n3=-1 - call pack77(message,i3,n3,c77) - call unpack77(c77,1,msgsent,unpk77_success) - if(i3.ne.1 .or. (message.ne.msgsent) .or. .not.unpk77_success) go to 10 - read(c77,'(77i1)') message77 - apmy_ru=2*mod(message77(1:28)+rvec(2:29),2)-1 - aphis_fd=2*mod(message77(30:57)+rvec(29:56),2)-1 - message77=mod(message77+rvec,2) - call encode174_91(message77,cw) - apbits=2*cw-1 - if(nohiscall) apbits(30)=99 - -10 continue - mycall0=mycall - hiscall0=hiscall - endif - candidate=0.0 - ncand=0 - syncmin=1.2 - maxcand=100 - - fa=nfa - fb=nfb - call clockit('getcand4',0) - call getcandidates4(iwave,fa,fb,syncmin,nfqso,maxcand,savg,candidate, & - ncand,sbase) - call clockit('getcand4',1) - - ndecodes=0 - dobigfft=.true. - do icand=1,ncand - f0=candidate(1,icand) - snr=candidate(3,icand)-1.0 - if( f0.le.10.0 .or. f0.ge.4990.0 ) cycle - call clockit('ft4_down',0) - call ft4_downsample(iwave,dobigfft,f0,cd2) !Downsample from 512 to 32 Sa/Symbol - if(dobigfft) dobigfft=.false. - call clockit('ft4_down',1) - - sum2=sum(cd2*conjg(cd2))/(real(NMAX)/real(NDOWN)) - if(sum2.gt.0.0) cd2=cd2/sqrt(sum2) -! Sample rate is now 12000/16 = 750 samples/second - do isync=1,2 - if(isync.eq.1) then - idfmin=-12 - idfmax=12 - idfstp=3 - ibmin=0 - ibmax=216 !Max DT = 216/750 = 0.288 s - ibstp=4 - else - idfmin=idfbest-4 - idfmax=idfbest+4 - idfstp=1 - ibmin=max(0,ibest-5) - ibmax=min(ibest+5,NMAX/NDOWN-1) - ibstp=1 - endif - ibest=-1 - smax=-99. - idfbest=0 - do idf=idfmin,idfmax,idfstp - - call clockit('sync4d ',0) - do istart=ibmin,ibmax,ibstp - call sync4d(cd2,istart,ctwk2(:,idf),1,sync) !Find sync power - if(sync.gt.smax) then - smax=sync - ibest=istart - idfbest=idf - endif - enddo - call clockit('sync4d ',1) - - enddo - enddo - f0=f0+real(idfbest) - if( f0.le.10.0 .or. f0.ge.4990.0 ) cycle - - call clockit('ft4down ',0) - call ft4_downsample(iwave,dobigfft,f0,cb) !Final downsample with corrected f0 - call clockit('ft4down ',1) - sum2=sum(abs(cb)**2)/(real(NSS)*NN) - if(sum2.gt.0.0) cb=cb/sqrt(sum2) - cd=cb(ibest:ibest+NN*NSS-1) - call clockit('four2a ',0) - do k=1,NN - i1=(k-1)*NSS - csymb=cd(i1:i1+NSS-1) - call four2a(csymb,NSS,1,-1,1) - cs(0:3,k)=csymb(1:4) - s4(0:3,k)=abs(csymb(1:4)) - enddo - call clockit('four2a ',1) - -! Sync quality check - is1=0 - is2=0 - is3=0 - is4=0 - do k=1,4 - ip=maxloc(s4(:,k)) - if(icos4a(k-1).eq.(ip(1)-1)) is1=is1+1 - ip=maxloc(s4(:,k+33)) - if(icos4b(k-1).eq.(ip(1)-1)) is2=is2+1 - ip=maxloc(s4(:,k+66)) - if(icos4c(k-1).eq.(ip(1)-1)) is3=is3+1 - ip=maxloc(s4(:,k+99)) - if(icos4d(k-1).eq.(ip(1)-1)) is4=is4+1 - enddo - nsync=is1+is2+is3+is4 !Number of correct hard sync symbols, 0-16 - if(smax .lt. 0.7 .or. nsync .lt. 8) cycle - - do nseq=1,3 !Try coherent sequences of 1, 2, and 4 symbols - if(nseq.eq.1) nsym=1 - if(nseq.eq.2) nsym=2 - if(nseq.eq.3) nsym=4 - nt=2**(2*nsym) - do ks=1,NN-nsym+1,nsym !87+16=103 symbols. - amax=-1.0 - do i=0,nt-1 - i1=i/64 - i2=iand(i,63)/16 - i3=iand(i,15)/4 - i4=iand(i,3) - if(nsym.eq.1) then - s2(i)=abs(cs(graymap(i4),ks)) - elseif(nsym.eq.2) then - s2(i)=abs(cs(graymap(i3),ks)+cs(graymap(i4),ks+1)) - elseif(nsym.eq.4) then - s2(i)=abs(cs(graymap(i1),ks ) + & - cs(graymap(i2),ks+1) + & - cs(graymap(i3),ks+2) + & - cs(graymap(i4),ks+3) & - ) - else - print*,"Error - nsym must be 1, 2, or 4." - endif - enddo - ipt=1+(ks-1)*2 - if(nsym.eq.1) ibmax=1 - if(nsym.eq.2) ibmax=3 - if(nsym.eq.4) ibmax=7 - do ib=0,ibmax - bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - & - maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib)) - if(ipt+ib.gt.2*NN) cycle - if(nsym.eq.1) then - bmeta(ipt+ib)=bm - elseif(nsym.eq.2) then - bmetb(ipt+ib)=bm - elseif(nsym.eq.4) then - bmetc(ipt+ib)=bm - endif - enddo - enddo - enddo - - bmetb(205:206)=bmeta(205:206) - bmetc(201:204)=bmetb(201:204) - bmetc(205:206)=bmeta(205:206) - - call clockit('normaliz',0) - call normalizebmet(bmeta,2*NN) - call normalizebmet(bmetb,2*NN) - call normalizebmet(bmetc,2*NN) - call clockit('normaliz',1) - - hbits=0 - where(bmeta.ge.0) hbits=1 - ns1=count(hbits( 1: 8).eq.(/0,0,0,1,1,0,1,1/)) - ns2=count(hbits( 67: 74).eq.(/0,1,0,0,1,1,1,0/)) - ns3=count(hbits(133:140).eq.(/1,1,1,0,0,1,0,0/)) - ns4=count(hbits(199:206).eq.(/1,0,1,1,0,0,0,1/)) - nsync_qual=ns1+ns2+ns3+ns4 - if(nsync_qual.lt. 20) cycle - - scalefac=2.83 - llra( 1: 58)=bmeta( 9: 66) - llra( 59:116)=bmeta( 75:132) - llra(117:174)=bmeta(141:198) - llra=scalefac*llra - llrb( 1: 58)=bmetb( 9: 66) - llrb( 59:116)=bmetb( 75:132) - llrb(117:174)=bmetb(141:198) - llrb=scalefac*llrb - llrc( 1: 58)=bmetc( 9: 66) - llrc( 59:116)=bmetc( 75:132) - llrc(117:174)=bmetc(141:198) - llrc=scalefac*llrc - - apmag=maxval(abs(llra))*1.1 - npasses=3+nappasses(nQSOProgress) - if(ncontest.ge.5) npasses=3 ! Don't support Fox and Hound - do ipass=1,npasses - if(ipass.eq.1) llr=llra - if(ipass.eq.2) llr=llrb - if(ipass.eq.3) llr=llrc - if(ipass.le.3) then - apmask=0 - iaptype=0 - endif - - if(ipass .gt. 3) then - llrd=llrc - iaptype=naptypes(nQSOProgress,ipass-3) - -! ncontest=0 : NONE -! 1 : NA_VHF -! 2 : EU_VHF -! 3 : FIELD DAY -! 4 : RTTY -! 5 : FOX -! 6 : HOUND -! -! Conditions that cause us to bail out of AP decoding - napwid=50 - if(ncontest.le.4 .and. iaptype.ge.3 .and. (abs(f0-nfqso).gt.napwid) ) cycle - if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall - if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall - - if(iaptype.eq.1) then ! CQ or CQ TEST or CQ FD or CQ RU or CQ SCC - apmask=0 - apmask(1:29)=1 - llrd(1:29)=apmag*mcq(1:29) - endif - - if(iaptype.eq.2) then ! MyCall,???,??? - apmask=0 - if(ncontest.eq.0.or.ncontest.eq.1) then - apmask(1:29)=1 - llrd(1:29)=apmag*apbits(1:29) - else if(ncontest.eq.2) then - apmask(1:28)=1 - llrd(1:28)=apmag*apbits(1:28) - else if(ncontest.eq.3) then - apmask(1:28)=1 - llrd(1:28)=apmag*apbits(1:28) - else if(ncontest.eq.4) then - apmask(2:29)=1 - llrd(2:29)=apmag*apmy_ru(1:28) - endif - endif - - if(iaptype.eq.3) then ! MyCall,DxCall,??? - apmask=0 - if(ncontest.eq.0.or.ncontest.eq.1.or.ncontest.eq.2) then - apmask(1:58)=1 - llrd(1:58)=apmag*apbits(1:58) - else if(ncontest.eq.3) then ! Field Day - apmask(1:56)=1 - llrd(1:28)=apmag*apbits(1:28) - llrd(29:56)=apmag*aphis_fd(1:28) - else if(ncontest.eq.4) then ! RTTY RU - apmask(2:57)=1 - llrd(2:29)=apmag*apmy_ru(1:28) - llrd(30:57)=apmag*apbits(30:57) - endif - endif - - if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then - apmask=0 - if(ncontest.le.4) then - apmask(1:91)=1 ! mycall, hiscall, RRR|73|RR73 - if(iaptype.eq.6) llrd(1:91)=apmag*apbits(1:91) - endif - endif - - llr=llrd - endif - max_iterations=40 - message77=0 - call clockit('bpdecode',0) - call bpdecode174_91(llr,apmask,max_iterations,message77, & - cw,nharderror,niterations) - call clockit('bpdecode',1) - if(sum(message77).eq.0) cycle - if( nharderror.ge.0 ) then - message77=mod(message77+rvec,2) ! remove rvec scrambling - write(c77,'(77i1)') message77(1:77) - call unpack77(c77,1,message,unpk77_success) - idupe=0 - do i=1,ndecodes - if(decodes(i).eq.message) idupe=1 - enddo - if(ibest.le.10 .and. message.eq.msg0) idupe=1 !Already decoded - if(idupe.eq.1) exit - ndecodes=ndecodes+1 - decodes(ndecodes)=message - if(snr.gt.0.0) then - xsnr=10*log10(snr)-14.0 - else - xsnr=-20.0 - endif - nsnr=nint(max(-20.0,xsnr)) - freq=f0 - tsig=mod(tbuf + ibest/750.0,100.0) - - write(line,1000) hhmmss,nsnr,tsig,nint(freq),message -1000 format(a6,i4,f5.1,i5,' + ',1x,a37) - l1=index(data_dir,char(0))-1 - if(l1.ge.1) data_dir(l1+1:l1+1)="/" - fname=data_dir(1:l1+1)//'all_ft4.txt' - open(24,file=trim(fname),status='unknown',position='append') - write(24,1002) cdatetime0,nsnr,tsig,nint(freq),message, & - nharderror,nsync_qual,ipass,niterations,iaptype,nsync - if(hhmmss.eq.' ') write(*,1002) cdatetime0,nsnr, & - tsig,nint(freq),message,nharderror,nsync_qual,ipass, & - niterations,iaptype -1002 format(a17,i4,f5.1,i5,' Rx ',a37,6i4) - close(24) - linex(ndecodes)=line - if(ibest.ge.ibmax-15) msg0=message !Possible dupe candidate - exit - endif - enddo !Sequence estimation - enddo !Candidate list - call clockit('ft4_deco',1) - call clockit2(data_dir) - call clockit('ft4_deco',101) - return - - entry get_ft4msg(idecode,line) - line=linex(idecode) - return - - end subroutine ft4b diff --git a/lib/ft4/ft4d.f90 b/lib/ft4/ft4d.f90 deleted file mode 100644 index a63e3e0a6..000000000 --- a/lib/ft4/ft4d.f90 +++ /dev/null @@ -1,83 +0,0 @@ -program ft4d - - include 'ft4_params.f90' - character*8 arg - character*17 cdatetime - character*512 data_dir - character*12 mycall - character*12 hiscall - character*80 infile - character*61 line - character*4 cqstr - real*8 fMHz - integer ihdr(11) - integer*2 iwave(240000) !20*12000 - - fs=12000.0/NDOWN !Sample rate - dt=1/fs !Sample interval after downsample (s) - tt=NSPS*dt !Duration of "itone" symbols (s) - baud=1.0/tt !Keying rate for "itone" symbols (baud) - txt=NZ*dt !Transmission length (s) - - nargs=iargc() - if(nargs.lt.1) then - print*,'Usage: ft4d [-a ] [-f fMHz] [-n nQSOProgress] file1 [file2 ...]' - go to 999 - endif - iarg=1 - data_dir="." - call getarg(iarg,arg) - if(arg(1:2).eq.'-a') then - call getarg(iarg+1,data_dir) - iarg=iarg+2 - endif - call getarg(iarg,arg) - if(arg(1:2).eq.'-f') then - call getarg(iarg+1,arg) - read(arg,*) fMHz - iarg=iarg+2 - endif - nQSOProgress=0 - if(arg(1:2).eq.'-n') then - call getarg(iarg+1,arg) - read(arg,*) nQSOProgress - iarg=iarg+2 - endif - nfa=10 - nfb=4990 - ndecodes=0 - nfqso=1500 - mycall="K9AN" - hiscall="K1JT" - ncontest=4 - cqstr="RU " - - do ifile=iarg,nargs - call getarg(ifile,infile) - open(10,file=infile,status='old',access='stream') - read(10) ihdr - npts=min(ihdr(11)/2,180000) - read(10) iwave(1:npts) - close(10) - cdatetime=infile - j2=index(infile,'.wav') - if(j2.ge.14) cdatetime=infile(j2-13:j2)//'000' - istep=3456 - nsteps=(npts-52800)/istep + 1 - do n=1,nsteps - i0=(n-1)*istep + 1 - tbuf=(i0-1)/12000.0 - call ft4b(cdatetime,tbuf,nfa,nfb,nQSOProgress,ncontest, & - nfqso,iwave(i0),ndecodes,mycall,hiscall,cqstr,line,data_dir) - do idecode=1,ndecodes - call get_ft4msg(idecode,line) - write(*,'(a61)') line - enddo - enddo !steps - enddo !files - - call four2a(xx,-1,1,-1,1) !Destroy FFTW plans to free their memory - -999 end program ft4d - - diff --git a/lib/ft4/ft4sim.f90 b/lib/ft4/ft4sim.f90 index 6b5d01599..959cf423c 100644 --- a/lib/ft4/ft4sim.f90 +++ b/lib/ft4/ft4sim.f90 @@ -6,7 +6,7 @@ program ft4sim use packjt77 include 'ft4_params.f90' !Set various constants parameter (NWAVE=NN*NSPS) - parameter (NZZ=18*3456) !62208 + parameter (NZZ=21*3456) !72576 type(hdr) h !Header for .wav file character arg*12,fname*17 character msg37*37,msgsent37*37 @@ -51,19 +51,18 @@ program ft4sim hmod=1.0 !Modulation index (0.5 is MSK, 1.0 is FSK) tt=NSPS*dt !Duration of symbols (s) baud=1.0/tt !Keying rate (baud) - txt=NZ*dt !Transmission length (s) + txt=NZ2*dt !Transmission length (s) bandwidth_ratio=2500.0/(fs/2.0) sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb) if(snrdb.gt.90.0) sig=1.0 - txt=NN*NSPS/12000.0 ! Source-encode, then get itone() i3=-1 n3=-1 call pack77(msg37,i3,n3,c77) read(c77,'(77i1)') msgbits - call genft4(msg37,0,msgsent37,itone) + call genft4(msg37,0,msgsent37,msgbits,itone) write(*,*) write(*,'(a9,a37,3x,a7,i1,a1,i1)') 'Message: ',msgsent37,'i3.n3: ',i3,'.',n3 write(*,1000) f0,xdt,txt,snrdb @@ -111,8 +110,10 @@ program ft4sim c0((NN+1)*NSPS:(NN+2)*NSPS-1)=c0((NN+1)*NSPS:(NN+2)*NSPS-1)*(1.0+cos(twopi*(/(i,i=0,NSPS-1)/)/(2.0*NSPS) ))/2.0 c0((NN+2)*NSPS:)=0. - k=nint((xdt+0.5)/dt) + k=nint((xdt+0.5)/dt)-NSPS c0=cshift(c0,-k) + if(k.gt.0) c0(0:k-1)=0.0 + if(k.lt.0) c0(NZZ+k:NZZ-1)=0.0 do ifile=1,nfiles c=c0 diff --git a/lib/ft4/ft4sim_mult.f90 b/lib/ft4/ft4sim_mult.f90 index 065b2a76b..d93978e5f 100644 --- a/lib/ft4/ft4sim_mult.f90 +++ b/lib/ft4/ft4sim_mult.f90 @@ -6,17 +6,17 @@ program ft4sim_mult use packjt77 include 'ft4_params.f90' !FT4 protocol constants parameter (NWAVE=NN*NSPS) - parameter (NZZ=65760) !Length of .wav file (4.48+1.0)*12000 + parameter (NZZ=72576) !Length of .wav file (21*3456) type(hdr) h !Header for .wav file character arg*12,fname*17,cjunk*4 character msg37*37,msgsent37*37,c77*77 + complex cwave0((NN+2)*NSPS) real wave0((NN+2)*NSPS) real wave(NZZ) real tmp(NZZ) integer itone(NN) + integer*1 msgbits(77) integer*2 iwave(NZZ) !Generated full-length waveform - integer icos4(4) - data icos4/0,1,3,2/ ! Get command-line argument(s) nargs=iargc() @@ -53,17 +53,18 @@ program ft4sim_mult read(10,1003,end=100) cjunk,isnr,xdt0,ifreq,msg37 1003 format(a4,30x,i3,f5.1,i5,1x,a37) if(cjunk.eq.'File') go to 100 - if(isnr.lt.-16) isnr=-16 - f0=ifreq*93.75/50.0 + if(isnr.lt.-17) isnr=-17 + f0=ifreq*960.0/576.0 call random_number(r) xdt=r-0.5 ! Source-encode, then get itone() i3=-1 n3=-1 call pack77(msg37,i3,n3,c77) - call genft4(msg37,0,msgsent37,itone) + call genft4(msg37,0,msgsent37,msgbits,itone) nwave0=(NN+2)*NSPS - call gen_ft4wave(itone,NN,NSPS,12000.0,f0,wave0,nwave0) + icmplx=0 + call gen_ft4wave(itone,NN,NSPS,12000.0,f0,cwave0,wave0,icmplx,nwave0) k0=nint((xdt+0.5)/dt) if(k0.lt.1) k0=1 diff --git a/lib/ft4/gen_ft4wave.f90 b/lib/ft4/gen_ft4wave.f90 index 305310e68..823993612 100644 --- a/lib/ft4/gen_ft4wave.f90 +++ b/lib/ft4/gen_ft4wave.f90 @@ -1,8 +1,9 @@ -subroutine gen_ft4wave(itone,nsym,nsps,fsample,f0,wave,nwave) +subroutine gen_ft4wave(itone,nsym,nsps,fsample,f0,cwave,wave,icmplx,nwave) real wave(nwave) - real pulse(6144) !512*4*3 - real dphi(0:240000-1) + complex cwave(nwave) + real pulse(6912) !576*4*3 + real dphi(0:250000-1) integer itone(nsym) logical first data first/.true./ @@ -12,7 +13,7 @@ subroutine gen_ft4wave(itone,nsym,nsps,fsample,f0,wave,nwave) twopi=8.0*atan(1.0) dt=1.0/fsample hmod=1.0 -! Compute the frequency-smoothing pulse +! Compute the smoothed frequency-deviation pulse do i=1,3*nsps tt=(i-1.5*nsps)/real(nsps) pulse(i)=gfsk_pulse(1.0,tt) @@ -34,19 +35,32 @@ subroutine gen_ft4wave(itone,nsym,nsps,fsample,f0,wave,nwave) phi=0.0 dphi = dphi + twopi*f0*dt !Shift frequency up by f0 wave=0. + if(icmplx.eq.1) cwave=0. k=0 do j=0,nwave-1 k=k+1 - wave(k)=sin(phi) + if(icmplx.eq.0) then + wave(k)=sin(phi) + else + cwave(k)=cmplx(cos(phi),sin(phi)) + endif phi=mod(phi+dphi(j),twopi) enddo ! Compute the ramp-up and ramp-down symbols - wave(1:nsps)=wave(1:nsps) * & - (1.0-cos(twopi*(/(i,i=0,nsps-1)/)/(2.0*nsps)))/2.0 - k1=(nsym+1)*nsps+1 - wave(k1:k1+nsps-1)=wave(k1:k1+nsps-1) * & - (1.0+cos(twopi*(/(i,i=0,nsps-1)/)/(2.0*nsps)))/2.0 + if(icmplx.eq.0) then + wave(1:nsps)=wave(1:nsps) * & + (1.0-cos(twopi*(/(i,i=0,nsps-1)/)/(2.0*nsps)))/2.0 + k1=(nsym+1)*nsps+1 + wave(k1:k1+nsps-1)=wave(k1:k1+nsps-1) * & + (1.0+cos(twopi*(/(i,i=0,nsps-1)/)/(2.0*nsps)))/2.0 + else + cwave(1:nsps)=cwave(1:nsps) * & + (1.0-cos(twopi*(/(i,i=0,nsps-1)/)/(2.0*nsps)))/2.0 + k1=(nsym+1)*nsps+1 + cwave(k1:k1+nsps-1)=cwave(k1:k1+nsps-1) * & + (1.0+cos(twopi*(/(i,i=0,nsps-1)/)/(2.0*nsps)))/2.0 + endif return end subroutine gen_ft4wave diff --git a/lib/ft4/genft4.f90 b/lib/ft4/genft4.f90 index 3c6b8ead1..66e70a612 100644 --- a/lib/ft4/genft4.f90 +++ b/lib/ft4/genft4.f90 @@ -1,4 +1,4 @@ -subroutine genft4(msg0,ichk,msgsent,i4tone) +subroutine genft4(msg0,ichk,msgsent,msgbits,i4tone) ! Encode an FT4 message ! Input: @@ -11,7 +11,7 @@ subroutine genft4(msg0,ichk,msgsent,i4tone) ! s16 + 87symbols + 2 ramp up/down = 105 total channel symbols ! r1 + s4 + d29 + s4 + d29 + s4 + d29 + s4 + r1 -! Message duration: TxT = 105*512/12000 = 4.48 s +! Message duration: TxT = 105*576/12000 = 5.04 s ! use iso_c_binding, only: c_loc,c_size_t @@ -52,8 +52,16 @@ subroutine genft4(msg0,ichk,msgsent,i4tone) call unpack77(c77,0,msgsent,unpk77_success) !Unpack to get msgsent if(ichk.eq.1) go to 999 - read(c77,"(77i1)") msgbits - msgbits=mod(msgbits+rvec,2) + read(c77,'(77i1)',err=1) msgbits + if(unpk77_success) go to 2 +1 msgbits=0 + itone=0 + msgsent='*** bad message *** ' + go to 999 + +entry get_ft4_tones_from_77bits(msgbits,i4tone) + +2 msgbits=mod(msgbits+rvec,2) call encode174_91(msgbits,codeword) ! Grayscale mapping: diff --git a/lib/ft4/get_ft4_bitmetrics.f90 b/lib/ft4/get_ft4_bitmetrics.f90 new file mode 100644 index 000000000..eba86a418 --- /dev/null +++ b/lib/ft4/get_ft4_bitmetrics.f90 @@ -0,0 +1,114 @@ +subroutine get_ft4_bitmetrics(cd,bitmetrics,badsync) + + include 'ft4_params.f90' + parameter (NSS=NSPS/NDOWN,NDMAX=NMAX/NDOWN) + complex cd(0:NN*NSS-1) + complex cs(0:3,NN) + complex csymb(NSS) + integer icos4a(0:3),icos4b(0:3),icos4c(0:3),icos4d(0:3) + integer graymap(0:3) + integer ip(1) + logical one(0:255,0:7) ! 256 4-symbol sequences, 8 bits + logical first + logical badsync + real bitmetrics(2*NN,3) + real s2(0:255) + real s4(0:3,NN) + + data icos4a/0,1,3,2/ + data icos4b/1,0,2,3/ + data icos4c/2,3,1,0/ + data icos4d/3,2,0,1/ + data graymap/0,1,3,2/ + data first/.true./ + save first,one + + if(first) then + one=.false. + do i=0,255 + do j=0,7 + if(iand(i,2**j).ne.0) one(i,j)=.true. + enddo + enddo + first=.false. + endif + + do k=1,NN + i1=(k-1)*NSS + csymb=cd(i1:i1+NSS-1) + call four2a(csymb,NSS,1,-1,1) + cs(0:3,k)=csymb(1:4) + s4(0:3,k)=abs(csymb(1:4)) + enddo + +! Sync quality check + is1=0 + is2=0 + is3=0 + is4=0 + badsync=.false. + do k=1,4 + ip=maxloc(s4(:,k)) + if(icos4a(k-1).eq.(ip(1)-1)) is1=is1+1 + ip=maxloc(s4(:,k+33)) + if(icos4b(k-1).eq.(ip(1)-1)) is2=is2+1 + ip=maxloc(s4(:,k+66)) + if(icos4c(k-1).eq.(ip(1)-1)) is3=is3+1 + ip=maxloc(s4(:,k+99)) + if(icos4d(k-1).eq.(ip(1)-1)) is4=is4+1 + enddo + nsync=is1+is2+is3+is4 !Number of correct hard sync symbols, 0-16 + if(nsync .lt. 8) then + badsync=.true. + return + endif + + do nseq=1,3 !Try coherent sequences of 1, 2, and 4 symbols + if(nseq.eq.1) nsym=1 + if(nseq.eq.2) nsym=2 + if(nseq.eq.3) nsym=4 + nt=2**(2*nsym) + do ks=1,NN-nsym+1,nsym !87+16=103 symbols. + amax=-1.0 + do i=0,nt-1 + i1=i/64 + i2=iand(i,63)/16 + i3=iand(i,15)/4 + i4=iand(i,3) + if(nsym.eq.1) then + s2(i)=abs(cs(graymap(i4),ks)) + elseif(nsym.eq.2) then + s2(i)=abs(cs(graymap(i3),ks)+cs(graymap(i4),ks+1)) + elseif(nsym.eq.4) then + s2(i)=abs(cs(graymap(i1),ks ) + & + cs(graymap(i2),ks+1) + & + cs(graymap(i3),ks+2) + & + cs(graymap(i4),ks+3) & + ) + else + print*,"Error - nsym must be 1, 2, or 4." + endif + enddo + ipt=1+(ks-1)*2 + if(nsym.eq.1) ibmax=1 + if(nsym.eq.2) ibmax=3 + if(nsym.eq.4) ibmax=7 + do ib=0,ibmax + bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - & + maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib)) + if(ipt+ib.gt.2*NN) cycle + bitmetrics(ipt+ib,nseq)=bm + enddo + enddo + enddo + + bitmetrics(205:206,2)=bitmetrics(205:206,1) + bitmetrics(201:204,3)=bitmetrics(201:204,2) + bitmetrics(205:206,3)=bitmetrics(205:206,1) + + call normalizebmet(bitmetrics(:,1),2*NN) + call normalizebmet(bitmetrics(:,2),2*NN) + call normalizebmet(bitmetrics(:,3),2*NN) + return + +end subroutine get_ft4_bitmetrics diff --git a/lib/ft4/getcandidates4.f90 b/lib/ft4/getcandidates4.f90 index bf62abfa7..e9860b7a7 100644 --- a/lib/ft4/getcandidates4.f90 +++ b/lib/ft4/getcandidates4.f90 @@ -1,4 +1,4 @@ -subroutine getcandidates4(id,fa,fb,syncmin,nfqso,maxcand,savg,candidate, & +subroutine getcandidates4(dd,fa,fb,syncmin,nfqso,maxcand,savg,candidate, & ncand,sbase) include 'ft4_params.f90' @@ -8,9 +8,8 @@ subroutine getcandidates4(id,fa,fb,syncmin,nfqso,maxcand,savg,candidate, & real x(NFFT1) real window(NFFT1) complex cx(0:NH1) - real candidate(3,maxcand) - integer*2 id(NMAX) - integer indx(NH1) + real candidate(2,maxcand),candidatet(2,maxcand) + real dd(NMAX) integer ipk(1) equivalence (x,cx) logical first @@ -26,42 +25,35 @@ subroutine getcandidates4(id,fa,fb,syncmin,nfqso,maxcand,savg,candidate, & ! Compute symbol spectra, stepping by NSTEP steps. savg=0. - tstep=NSTEP/12000.0 df=12000.0/NFFT1 fac=1.0/300.0 do j=1,NHSYM ia=(j-1)*NSTEP + 1 ib=ia+NFFT1-1 if(ib.gt.NMAX) exit - x=fac*id(ia:ib)*window + x=fac*dd(ia:ib)*window call four2a(x,NFFT1,1,-1,0) !r2c FFT do i=1,NH1 s(i,j)=real(cx(i))**2 + aimag(cx(i))**2 enddo savg=savg + s(1:NH1,j) !Average spectrum enddo + savg=savg/NHSYM savsm=0. do i=8,NH1-7 savsm(i)=sum(savg(i-7:i+7))/15. enddo - nfa=fa/df - if(nfa.lt.1) nfa=1 - nfb=fb/df - if(nfb.gt.nint(5000.0/df)) nfb=nint(5000.0/df) - n300=300/df - n2500=2500/df -! np=nfb-nfa+1 - np=n2500-n300+1 - indx=0 - call indexx(savsm(n300:n2500),np,indx) - xn=savsm(n300+indx(nint(0.3*np))) - ncand=0 - if(xn.le.1.e-8) return - savsm=savsm/xn -! call ft4_baseline(savg,nfa,nfb,sbase) -! savsm=savsm/sbase - f_offset = -1.5*12000/512 + nfa=fa/df + if(nfa.lt.nint(200.0/df)) nfa=nint(200.0/df) + nfb=fb/df + if(nfb.gt.nint(4910.0/df)) nfb=nint(4910.0/df) + call ft4_baseline(savg,nfa,nfb,sbase) + if(any(sbase(nfa:nfb).le.0)) return + savsm(nfa:nfb)=savsm(nfa:nfb)/sbase(nfa:nfb) + f_offset = -1.5*12000.0/NSPS + ncand=0 + candidatet=0 do i=nfa+1,nfb-1 if(savsm(i).ge.savsm(i-1) .and. savsm(i).ge.savsm(i+1) .and. & savsm(i).ge.syncmin) then @@ -69,18 +61,26 @@ subroutine getcandidates4(id,fa,fb,syncmin,nfqso,maxcand,savg,candidate, & del=0. if(den.ne.0.0) del=0.5*(savsm(i-1)-savsm(i+1))/den fpeak=(i+del)*df+f_offset + if(fpeak.lt.200.0 .or. fpeak.gt.4910.0) cycle speak=savsm(i) - 0.25*(savsm(i-1)-savsm(i+1))*del ncand=ncand+1 - if(ncand.gt.maxcand) then - ncand=maxcand - exit - endif - candidate(1,ncand)=fpeak - candidate(2,ncand)=-99.99 - candidate(3,ncand)=speak + candidatet(1,ncand)=fpeak + candidatet(2,ncand)=speak if(ncand.eq.maxcand) exit endif enddo - + candidate=0 + nq=count(abs(candidatet(1,1:ncand)-nfqso).le.20.0) + n1=1 + n2=nq+1 + do i=1,ncand + if(abs(candidatet(1,i)-nfqso).le.20.0) then + candidate(1:2,n1)=candidatet(1:2,i) + n1=n1+1 + else + candidate(1:2,n2)=candidatet(1:2,i) + n2=n2+1 + endif + enddo return end subroutine getcandidates4 diff --git a/lib/ft4/subtractft4.f90 b/lib/ft4/subtractft4.f90 new file mode 100644 index 000000000..ae104ddb3 --- /dev/null +++ b/lib/ft4/subtractft4.f90 @@ -0,0 +1,66 @@ +subroutine subtractft4(dd,itone,f0,dt) + +! Subtract an ft4 signal +! +! Measured signal : dd(t) = a(t)cos(2*pi*f0*t+theta(t)) +! Reference signal : cref(t) = exp( j*(2*pi*f0*t+phi(t)) ) +! Complex amp : cfilt(t) = LPF[ dd(t)*CONJG(cref(t)) ] +! Subtract : dd(t) = dd(t) - 2*REAL{cref*cfilt} + + use timer_module, only: timer + + parameter (NMAX=21*3456,NSPS=576,NFFT=NMAX,NFILT=1400) + parameter (NFRAME=(103+2)*NSPS) + real*4 dd(NMAX), window(-NFILT/2:NFILT/2), xjunk + complex cref,camp,cfilt,cw + integer itone(103) + logical first + data first/.true./ + common/heap8/cref(NFRAME),camp(NMAX),cfilt(NMAX),cw(NMAX),xjunk(NFRAME) + save first + + nstart=dt*12000+1-NSPS + nsym=103 + fs=12000.0 + icmplx=1 + bt=1.0 + nss=NSPS + call gen_ft4wave(itone,nsym,nss,fs,f0,cref,xjunk,icmplx,NFRAME) + camp=0. + do i=1,nframe + id=nstart-1+i + if(id.ge.1.and.id.le.NMAX) camp(i)=dd(id)*conjg(cref(i)) + enddo + + if(first) then +! Create and normalize the filter + pi=4.0*atan(1.0) + fac=1.0/float(nfft) + sum=0.0 + do j=-NFILT/2,NFILT/2 + window(j)=cos(pi*j/NFILT)**2 + sum=sum+window(j) + enddo + cw=0. + cw(1:NFILT+1)=window/sum + cw=cshift(cw,NFILT/2+1) + call four2a(cw,nfft,1,-1,1) + cw=cw*fac + first=.false. + endif + + cfilt=0.0 + cfilt(1:nframe)=camp(1:nframe) + call four2a(cfilt,nfft,1,-1,1) + cfilt(1:nfft)=cfilt(1:nfft)*cw(1:nfft) + call four2a(cfilt,nfft,1,1,1) + +! Subtract the reconstructed signal + do i=1,nframe + j=nstart+i-1 + if(j.ge.1 .and. j.le.NMAX) dd(j)=dd(j)-2*REAL(cfilt(i)*cref(i)) + enddo + + return +end subroutine subtractft4 + diff --git a/lib/ft4/sync4d.f90 b/lib/ft4/sync4d.f90 index bda7ed4a2..8d78f66aa 100644 --- a/lib/ft4/sync4d.f90 +++ b/lib/ft4/sync4d.f90 @@ -9,7 +9,6 @@ subroutine sync4d(cd0,i0,ctwk,itwk,sync) complex csync2(2*NSS) complex ctwk(2*NSS) complex z1,z2,z3,z4 - complex zz1,zz2,zz3,zz4 logical first integer icos4a(0:3),icos4b(0:3),icos4c(0:3),icos4d(0:3) data icos4a/0,1,3,2/ @@ -19,7 +18,7 @@ subroutine sync4d(cd0,i0,ctwk,itwk,sync) data first/.true./ save first,twopi,csynca,csyncb,csyncc,csyncd,fac - p(z1)=real(z1*fac)**2 + aimag(z1*fac)**2 !Statement function for power + p(z1)=(real(z1*fac)**2 + aimag(z1*fac)**2)**0.5 !Statement function for power if( first ) then twopi=8.0*atan(1.0) @@ -60,7 +59,17 @@ subroutine sync4d(cd0,i0,ctwk,itwk,sync) z4=0. if(itwk.eq.1) csync2=ctwk*csynca !Tweak the frequency - if(i1.ge.0 .and. i1+4*NSS-1.le.NP-1) z1=sum(cd0(i1:i1+4*NSS-1:2)*conjg(csync2)) + z1=0. + if(i1.ge.0 .and. i1+4*NSS-1.le.NP-1) then + z1=sum(cd0(i1:i1+4*NSS-1:2)*conjg(csync2)) + elseif( i1.lt.0 ) then + npts=(i1+4*NSS-1)/2 + if(npts.le.16) then + z1=0. + else + z1=sum(cd0(0:i1+4*NSS-1:2)*conjg(csync2(2*NSS-npts:))) + endif + endif if(itwk.eq.1) csync2=ctwk*csyncb !Tweak the frequency if(i2.ge.0 .and. i2+4*NSS-1.le.NP-1) z2=sum(cd0(i2:i2+4*NSS-1:2)*conjg(csync2)) @@ -69,7 +78,17 @@ subroutine sync4d(cd0,i0,ctwk,itwk,sync) if(i3.ge.0 .and. i3+4*NSS-1.le.NP-1) z3=sum(cd0(i3:i3+4*NSS-1:2)*conjg(csync2)) if(itwk.eq.1) csync2=ctwk*csyncd !Tweak the frequency - if(i4.ge.0 .and. i4+4*NSS-1.le.NP-1) z4=sum(cd0(i4:i4+4*NSS-1:2)*conjg(csync2)) + z4=0. + if(i4.ge.0 .and. i4+4*NSS-1.le.NP-1) then + z4=sum(cd0(i4:i4+4*NSS-1:2)*conjg(csync2)) + elseif( i4+4*NSS-1.gt.NP-1 ) then + npts=(NP-1-i4+1)/2 + if(npts.le.16) then + z4=0. + else + z4=sum(cd0(i4:i4+2*npts-1:2)*conjg(csync2(1:npts))) + endif + endif sync = p(z1) + p(z2) + p(z3) + p(z4) diff --git a/lib/ft4/syncft4.f90 b/lib/ft4/syncft4.f90 deleted file mode 100644 index 4841c560e..000000000 --- a/lib/ft4/syncft4.f90 +++ /dev/null @@ -1,145 +0,0 @@ -subroutine syncft4(iwave,nfa,nfb,syncmin,nfqso,maxcand,s,candidate, & - ncand,sbase) - - include 'ft4_params.f90' -! Search over +/- 2.5s relative to 0.5s TX start time. - parameter (JZ=20) - complex cx(0:NH1) - real s(NH1,NHSYM) - real savg(NH1) - real sbase(NH1) - real x(NFFT1) - real sync2d(NH1,-JZ:JZ) - real red(NH1) - real candidate0(3,maxcand) - real candidate(3,maxcand) - real dd(NMAX) - integer jpeak(NH1) - integer indx(NH1) - integer ii(1) - integer*2 iwave(NMAX) - integer icos4(0:3) - data icos4/0,1,3,2/ !Costas 4x4 tone pattern - equivalence (x,cx) - - dd=iwave/1e3 -! Compute symbol spectra, stepping by NSTEP steps. - savg=0. - tstep=NSTEP/12000.0 - df=12000.0/NFFT1 - fac=1.0/300.0 - do j=1,NHSYM - ia=(j-1)*NSTEP + 1 - ib=ia+NSPS-1 - x(1:NSPS)=fac*dd(ia:ib) - x(NSPS+1:)=0. - call four2a(x,NFFT1,1,-1,0) !r2c FFT - do i=1,NH1 - s(i,j)=real(cx(i))**2 + aimag(cx(i))**2 - enddo - savg=savg + s(1:NH1,j) !Average spectrum - enddo - - call baseline(savg,nfa,nfb,sbase) - - ia=max(1,nint(nfa/df)) - ib=nint(nfb/df) - nssy=NSPS/NSTEP ! # steps per symbol - nfos=NFFT1/NSPS ! # frequency bin oversampling factor - jstrt=0.25/tstep - candidate0=0. - k=0 - - do i=ia,ib - do j=-JZ,+JZ - ta=0. - tb=0. - tc=0. - t0a=0. - t0b=0. - t0c=0. - do n=0,3 - m=j+jstrt+nssy*n - if(m.ge.1.and.m.le.NHSYM) then - ta=ta + s(i+nfos*icos4(n),m) - t0a=t0a + sum(s(i:i+nfos*3:nfos,m)) - endif - tb=tb + s(i+nfos*icos4(n),m+nssy*36) - t0b=t0b + sum(s(i:i+nfos*3:nfos,m+nssy*36)) - if(m+nssy*72.le.NHSYM) then - tc=tc + s(i+nfos*icos4(n),m+nssy*72) - t0c=t0c + sum(s(i:i+nfos*3:nfos,m+nssy*72)) - endif - enddo - t=ta+tb+tc - t0=t0a+t0b+t0c - t0=(t0-t)/3.0 - sync_abc=t/t0 - t=tb+tc - t0=t0b+t0c - t0=(t0-t)/3.0 - sync_bc=t/t0 - sync2d(i,j)=max(sync_abc,sync_bc) - enddo - enddo - - red=0. - do i=ia,ib - ii=maxloc(sync2d(i,-JZ:JZ)) - 1 - JZ - j0=ii(1) - jpeak(i)=j0 - red(i)=sync2d(i,j0) - enddo - iz=ib-ia+1 - call indexx(red(ia:ib),iz,indx) - ibase=indx(nint(0.40*iz)) - 1 + ia - if(ibase.lt.1) ibase=1 - if(ibase.gt.nh1) ibase=nh1 - base=red(ibase) - red=red/base - do i=1,min(maxcand,iz) - n=ia + indx(iz+1-i) - 1 - if(red(n).lt.syncmin.or.isnan(red(n)).or.k.eq.maxcand) exit - k=k+1 -! candidate0(1,k)=n*df+37.5*1.5 - candidate0(1,k)=n*df - candidate0(2,k)=(jpeak(n)-1)*tstep - candidate0(3,k)=red(n) - enddo - ncand=k - -! Put nfqso at top of list, and save only the best of near-dupe freqs. - do i=1,ncand - if(abs(candidate0(1,i)-nfqso).lt.10.0) candidate0(1,i)=-candidate0(1,i) - if(i.ge.2) then - do j=1,i-1 - fdiff=abs(candidate0(1,i))-abs(candidate0(1,j)) - if(abs(fdiff).lt.4.0) then - if(candidate0(3,i).ge.candidate0(3,j)) candidate0(3,j)=0. - if(candidate0(3,i).lt.candidate0(3,j)) candidate0(3,i)=0. - endif - enddo - endif - enddo - - fac=20.0/maxval(s) - s=fac*s - -! Sort by sync -! call indexx(candidate0(3,1:ncand),ncand,indx) -! Sort by frequency - call indexx(candidate0(1,1:ncand),ncand,indx) - k=1 -! do i=ncand,1,-1 - do i=1,ncand - j=indx(i) -! if( candidate0(3,j) .ge. syncmin .and. candidate0(2,j).ge.-1.5 ) then - if( candidate0(3,j) .ge. syncmin ) then - candidate(2:3,k)=candidate0(2:3,j) - candidate(1,k)=abs(candidate0(1,j)) - k=k+1 - endif - enddo - ncand=k-1 - return -end subroutine syncft4 diff --git a/lib/ft4_decode.f90 b/lib/ft4_decode.f90 index 500cdd081..1fd60efa6 100644 --- a/lib/ft4_decode.f90 +++ b/lib/ft4_decode.f90 @@ -1,128 +1,115 @@ module ft4_decode - - type :: ft4_decoder - procedure(ft4_decode_callback), pointer :: callback - contains - procedure :: decode - end type ft4_decoder - abstract interface - subroutine ft4_decode_callback (this,sync,snr,dt,freq,decoded,nap,qual) - import ft4_decoder - implicit none - class(ft4_decoder), intent(inout) :: this - real, intent(in) :: sync - integer, intent(in) :: snr - real, intent(in) :: dt - real, intent(in) :: freq - character(len=37), intent(in) :: decoded - integer, intent(in) :: nap - real, intent(in) :: qual - end subroutine ft4_decode_callback - end interface + type :: ft4_decoder + procedure(ft4_decode_callback), pointer :: callback + contains + procedure :: decode + end type ft4_decoder + + abstract interface + subroutine ft4_decode_callback (this,sync,snr,dt,freq,decoded,nap,qual) + import ft4_decoder + implicit none + class(ft4_decoder), intent(inout) :: this + real, intent(in) :: sync + integer, intent(in) :: snr + real, intent(in) :: dt + real, intent(in) :: freq + character(len=37), intent(in) :: decoded + integer, intent(in) :: nap + real, intent(in) :: qual + end subroutine ft4_decode_callback + end interface contains - subroutine decode(this,callback,iwave,nQSOProgress,nfqso, & - nutc,nfa,nfb,ndepth,ncontest,mycall,hiscall) - use timer_module, only: timer - use packjt77 - include 'ft4/ft4_params.f90' - class(ft4_decoder), intent(inout) :: this - procedure(ft4_decode_callback) :: callback - parameter (NSS=NSPS/NDOWN) - parameter (NZZ=18*3456) - character message*37,msgsent*37,msg0*37 - character c77*77 - character*37 decodes(100) - character*512 data_dir,fname - character*17 cdatetime0 - character*12 mycall,hiscall - character*12 mycall0,hiscall0 - character*6 hhmmss - character*4 cqstr,cqstr0 + subroutine decode(this,callback,iwave,nQSOProgress,nfqso, & + nutc,nfa,nfb,ndepth,lapcqonly,ncontest,mycall,hiscall) + use timer_module, only: timer + use packjt77 + include 'ft4/ft4_params.f90' + class(ft4_decoder), intent(inout) :: this + procedure(ft4_decode_callback) :: callback + parameter (NSS=NSPS/NDOWN,NDMAX=NMAX/NDOWN) + character message*37,msgsent*37 + character c77*77 + character*37 decodes(100) + character*512 data_dir,fname + character*17 cdatetime0 + character*12 mycall,hiscall + character*12 mycall0,hiscall0 + character*6 hhmmss + character*4 cqstr,cqstr0 - complex cd2(0:NZZ/NDOWN-1) !Complex waveform - complex cb(0:NZZ/NDOWN-1+NN*NSS) - complex cd(0:NN*NSS-1) !Complex waveform - complex ctwk(2*NSS),ctwk2(2*NSS,-16:16) - complex csymb(NSS) - complex cs(0:3,NN) - real s4(0:3,NN) + complex cd2(0:NDMAX-1) !Complex waveform + complex cb(0:NDMAX-1) + complex cd(0:NN*NSS-1) !Complex waveform + complex ctwk(2*NSS),ctwk2(2*NSS,-16:16) - real bmeta(2*NN),bmetb(2*NN),bmetc(2*NN) - real a(5) - real llr(2*ND),llra(2*ND),llrb(2*ND),llrc(2*ND),llrd(2*ND) - real s2(0:255) - real candidate(3,100) - real savg(NH1),sbase(NH1) + real a(5) + real bitmetrics(2*NN,3) + real dd(NMAX) + real llr(2*ND),llra(2*ND),llrb(2*ND),llrc(2*ND),llrd(2*ND) + real candidate(2,100) + real savg(NH1),sbase(NH1) - integer apbits(2*ND) - integer apmy_ru(28),aphis_fd(28) - integer icos4a(0:3),icos4b(0:3),icos4c(0:3),icos4d(0:3) - integer*2 iwave(NZZ) !Raw received data - integer*1 message77(77),rvec(77),apmask(2*ND),cw(2*ND) - integer*1 hbits(2*NN) - integer graymap(0:3) - integer ip(1) - integer nappasses(0:5) ! # of decoding passes for QSO States 0-5 - integer naptypes(0:5,4) ! nQSOProgress, decoding pass - integer mcq(29) - integer mrrr(19),m73(19),mrr73(19) + integer apbits(2*ND) + integer apmy_ru(28),aphis_fd(28) + integer*2 iwave(NMAX) !Raw received data + integer*1 message77(77),rvec(77),apmask(2*ND),cw(2*ND) + integer*1 hbits(2*NN) + integer i4tone(103) + integer nappasses(0:5) ! # of decoding passes for QSO States 0-5 + integer naptypes(0:5,4) ! nQSOProgress, decoding pass + integer mcq(29) + integer mrrr(19),m73(19),mrr73(19) - logical nohiscall,unpk77_success - logical one(0:255,0:7) ! 256 4-symbol sequences, 8 bits - logical first, dobigfft + logical nohiscall,unpk77_success + logical first, dobigfft + logical dosubtract,doosd + logical badsync + logical, intent(in) :: lapcqonly - data icos4a/0,1,3,2/ - data icos4b/1,0,2,3/ - data icos4c/2,3,1,0/ - data icos4d/3,2,0,1/ - data graymap/0,1,3,2/ - data msg0/' '/ - data first/.true./ - data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ - data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ - data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/ - data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/ - data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & - 1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1,1,1,0,0,1,0,1, & - 0,1,0,1,0,1,1,0,1,1,1,1,1,0,0,0,1,0,1/ - save fs,dt,tt,txt,twopi,h,one,first,apbits,nappasses,naptypes, & - mycall0,hiscall0,msg0,cqstr0,ctwk2 + data first/.true./ + data mcq/0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0/ + data mrrr/0,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,1/ + data m73/0,1,1,1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1/ + data mrr73/0,1,1,1,1,1,1,0,0,1,1,1,0,1,0,1,0,0,1/ + data rvec/0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,0,1,0,0,0,1,0,0,1,1,0,1,1,0, & + 1,0,0,1,0,1,1,0,0,0,0,1,0,0,0,1,0,1,0,0,1,1,1,1,0,0,1,0,1, & + 0,1,0,1,0,1,1,0,1,1,1,1,1,0,0,0,1,0,1/ + save fs,dt,tt,txt,twopi,h,first,apbits,nappasses,naptypes, & + mycall0,hiscall0,cqstr0,ctwk2 - this%callback => callback - hhmmss=cdatetime0(8:13) - if(first) then - fs=12000.0/NDOWN !Sample rate after downsampling - dt=1/fs !Sample interval after downsample (s) - tt=NSPS*dt !Duration of "itone" symbols (s) - txt=NZ*dt !Transmission length (s) without ramp up/down - twopi=8.0*atan(1.0) - h=1.0 - one=.false. - do i=0,255 - do j=0,7 - if(iand(i,2**j).ne.0) one(i,j)=.true. + this%callback => callback + hhmmss=cdatetime0(8:13) + dxcall13=hiscall + mycall13=mycall + + if(first) then + fs=12000.0/NDOWN !Sample rate after downsampling + dt=1/fs !Sample interval after downsample (s) + tt=NSPS*dt !Duration of "itone" symbols (s) + txt=NZ*dt !Transmission length (s) without ramp up/down + twopi=8.0*atan(1.0) + h=1.0 + + do idf=-16,16 + a=0. + a(1)=real(idf) + ctwk=1. + call twkfreq1(ctwk,2*NSS,fs/2.0,a,ctwk2(:,idf)) enddo - enddo - do idf=-16,16 - a=0. - a(1)=real(idf) - ctwk=1. - call twkfreq1(ctwk,2*NSS,fs/2.0,a,ctwk2(:,idf)) - enddo - - mrrr=2*mod(mrrr+rvec(59:77),2)-1 - m73=2*mod(m73+rvec(59:77),2)-1 - mrr73=2*mod(mrr73+rvec(59:77),2)-1 - nappasses(0)=2 - nappasses(1)=2 - nappasses(2)=2 - nappasses(3)=2 - nappasses(4)=2 - nappasses(5)=3 + mrrr=2*mod(mrrr+rvec(59:77),2)-1 + m73=2*mod(m73+rvec(59:77),2)-1 + mrr73=2*mod(mrr73+rvec(59:77),2)-1 + nappasses(0)=2 + nappasses(1)=2 + nappasses(2)=2 + nappasses(3)=2 + nappasses(4)=2 + nappasses(5)=3 ! iaptype !------------------------ @@ -133,257 +120,230 @@ contains ! 5 MyCall DxCall 73 (77 ap bits) ! 6 MyCall DxCall RR73 (77 ap bits) !******** - naptypes(0,1:4)=(/1,2,0,0/) ! Tx6 selected (CQ) - naptypes(1,1:4)=(/2,3,0,0/) ! Tx1 - naptypes(2,1:4)=(/2,3,0,0/) ! Tx2 - naptypes(3,1:4)=(/3,6,0,0/) ! Tx3 - naptypes(4,1:4)=(/3,6,0,0/) ! Tx4 - naptypes(5,1:4)=(/3,1,2,0/) ! Tx5 + naptypes(0,1:4)=(/1,2,0,0/) ! Tx6 selected (CQ) + naptypes(1,1:4)=(/2,3,0,0/) ! Tx1 + naptypes(2,1:4)=(/2,3,0,0/) ! Tx2 + naptypes(3,1:4)=(/3,6,0,0/) ! Tx3 + naptypes(4,1:4)=(/3,6,0,0/) ! Tx4 + naptypes(5,1:4)=(/3,1,2,0/) ! Tx5 - mycall0='' - hiscall0='' - cqstr0='' - first=.false. - endif - - if(cqstr.ne.cqstr0) then - i0=index(cqstr,' ') - if(i0.le.1) then - message='CQ A1AA AA01' - else - message='CQ '//cqstr(1:i0-1)//' A1AA AA01' + mycall0='' + hiscall0='' + cqstr0='' + first=.false. endif - i3=-1 - n3=-1 - call pack77(message,i3,n3,c77) - call unpack77(c77,1,msgsent,unpk77_success) - read(c77,'(29i1)') mcq - mcq=2*mod(mcq+rvec(1:29),2)-1 - cqstr0=cqstr - endif - l1=index(mycall,char(0)) - if(l1.ne.0) mycall(l1:)=" " - l1=index(hiscall,char(0)) - if(l1.ne.0) hiscall(l1:)=" " - if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then - apbits=0 - apbits(1)=99 - apbits(30)=99 - apmy_ru=0 - aphis_fd=0 - - if(len(trim(mycall)) .lt. 3) go to 10 - - nohiscall=.false. - hiscall0=hiscall - if(len(trim(hiscall0)).lt.3) then - hiscall0=mycall ! use mycall for dummy hiscall - mycall won't be hashed. - nohiscall=.true. - endif - message=trim(mycall)//' '//trim(hiscall0)//' RR73' - i3=-1 - n3=-1 - call pack77(message,i3,n3,c77) - call unpack77(c77,1,msgsent,unpk77_success) - if(i3.ne.1 .or. (message.ne.msgsent) .or. .not.unpk77_success) go to 10 - read(c77,'(77i1)') message77 - apmy_ru=2*mod(message77(1:28)+rvec(2:29),2)-1 - aphis_fd=2*mod(message77(30:57)+rvec(29:56),2)-1 - message77=mod(message77+rvec,2) - call encode174_91(message77,cw) - apbits=2*cw-1 - if(nohiscall) apbits(30)=99 - -10 continue - mycall0=mycall - hiscall0=hiscall - endif - candidate=0.0 - ncand=0 - syncmin=1.2 - maxcand=100 - - fa=nfa - fb=nfb - call timer('getcand4',0) - call getcandidates4(iwave,fa,fb,syncmin,nfqso,maxcand,savg,candidate, & - ncand,sbase) - call timer('getcand4',1) - - ndecodes=0 - dobigfft=.true. - do icand=1,ncand - f0=candidate(1,icand) - snr=candidate(3,icand)-1.0 - call timer('ft4_down',0) - call ft4_downsample(iwave,dobigfft,f0,cd2) !Downsample to 32 Sam/Sym - call timer('ft4_down',1) - if(dobigfft) dobigfft=.false. - sum2=sum(cd2*conjg(cd2))/(real(NZZ)/real(NDOWN)) - if(sum2.gt.0.0) cd2=cd2/sqrt(sum2) -! Sample rate is now 12000/16 = 750 samples/second - do isync=1,2 - if(isync.eq.1) then - idfmin=-12 - idfmax=12 - idfstp=3 - ibmin=0 - ibmax=800 - ibstp=4 + if(cqstr.ne.cqstr0) then + i0=index(cqstr,' ') + if(i0.le.1) then + message='CQ A1AA AA01' else - idfmin=idfbest-4 - idfmax=idfbest+4 - idfstp=1 - ibmin=max(0,ibest-5) - ibmax=min(ibest+5,NZZ/NDOWN-1) - ibstp=1 + message='CQ '//cqstr(1:i0-1)//' A1AA AA01' endif - ibest=-1 - smax=-99. - idfbest=0 - call timer('sync4d ',0) - do idf=idfmin,idfmax,idfstp - do istart=ibmin,ibmax,ibstp - call sync4d(cd2,istart,ctwk2(:,idf),1,sync) !Find sync power - if(sync.gt.smax) then - smax=sync - ibest=istart - idfbest=idf - endif - enddo - enddo - call timer('sync4d ',1) - enddo - f0=f0+real(idfbest) - if( f0.le.10.0 .or. f0.ge.4990.0 ) cycle -! write(*,3002) smax,ibest/750.0,f0 -!3002 format('b',3f8.2) - call timer('ft4down ',0) - call ft4_downsample(iwave,dobigfft,f0,cb) !Final downsample, corrected f0 - call timer('ft4down ',1) - sum2=sum(abs(cb)**2)/(real(NSS)*NN) - if(sum2.gt.0.0) cb=cb/sqrt(sum2) - cd=cb(ibest:ibest+NN*NSS-1) - call timer('four2a ',0) - do k=1,NN - i1=(k-1)*NSS - csymb=cd(i1:i1+NSS-1) - call four2a(csymb,NSS,1,-1,1) - cs(0:3,k)=csymb(1:4) - s4(0:3,k)=abs(csymb(1:4)) - enddo - call timer('four2a ',1) + i3=-1 + n3=-1 + call pack77(message,i3,n3,c77) + call unpack77(c77,1,msgsent,unpk77_success) + read(c77,'(29i1)') mcq + mcq=2*mod(mcq+rvec(1:29),2)-1 + cqstr0=cqstr + endif -! Sync quality check - is1=0 - is2=0 - is3=0 - is4=0 - do k=1,4 - ip=maxloc(s4(:,k)) - if(icos4a(k-1).eq.(ip(1)-1)) is1=is1+1 - ip=maxloc(s4(:,k+33)) - if(icos4b(k-1).eq.(ip(1)-1)) is2=is2+1 - ip=maxloc(s4(:,k+66)) - if(icos4c(k-1).eq.(ip(1)-1)) is3=is3+1 - ip=maxloc(s4(:,k+99)) - if(icos4d(k-1).eq.(ip(1)-1)) is4=is4+1 - enddo - nsync=is1+is2+is3+is4 !Number of correct hard sync symbols, 0-16 - if(smax .lt. 0.7 .or. nsync .lt. 8) cycle + l1=index(mycall,char(0)) + if(l1.ne.0) mycall(l1:)=" " + l1=index(hiscall,char(0)) + if(l1.ne.0) hiscall(l1:)=" " + if(mycall.ne.mycall0 .or. hiscall.ne.hiscall0) then + apbits=0 + apbits(1)=99 + apbits(30)=99 + apmy_ru=0 + aphis_fd=0 - do nseq=1,3 !Try coherent sequences of 1, 2, and 4 symbols - if(nseq.eq.1) nsym=1 - if(nseq.eq.2) nsym=2 - if(nseq.eq.3) nsym=4 - nt=2**(2*nsym) - do ks=1,NN-nsym+1,nsym !87+16=103 symbols. - amax=-1.0 - do i=0,nt-1 - i1=i/64 - i2=iand(i,63)/16 - i3=iand(i,15)/4 - i4=iand(i,3) - if(nsym.eq.1) then - s2(i)=abs(cs(graymap(i4),ks)) - elseif(nsym.eq.2) then - s2(i)=abs(cs(graymap(i3),ks)+cs(graymap(i4),ks+1)) - elseif(nsym.eq.4) then - s2(i)=abs(cs(graymap(i1),ks ) + & - cs(graymap(i2),ks+1) + & - cs(graymap(i3),ks+2) + & - cs(graymap(i4),ks+3) & - ) + if(len(trim(mycall)) .lt. 3) go to 10 + + nohiscall=.false. + hiscall0=hiscall + if(len(trim(hiscall0)).lt.3) then + hiscall0=mycall ! use mycall for dummy hiscall - mycall won't be hashed. + nohiscall=.true. + endif + message=trim(mycall)//' '//trim(hiscall0)//' RR73' + i3=-1 + n3=-1 + call pack77(message,i3,n3,c77) + call unpack77(c77,1,msgsent,unpk77_success) + if(i3.ne.1 .or. (message.ne.msgsent) .or. .not.unpk77_success) go to 10 + read(c77,'(77i1)') message77 + apmy_ru=2*mod(message77(1:28)+rvec(2:29),2)-1 + aphis_fd=2*mod(message77(30:57)+rvec(29:56),2)-1 + message77=mod(message77+rvec,2) + call encode174_91(message77,cw) + apbits=2*cw-1 + if(nohiscall) apbits(30)=99 + +10 continue + mycall0=mycall + hiscall0=hiscall + endif + maxcand=100 + ndecodes=0 + decodes=' ' + fa=nfa + fb=nfb + dd=iwave + +! ndepth=3: 3 passes, bp+osd +! ndepth=2: 3 passes, bp only +! ndepth=1: 1 pass, no subtraction + + max_iterations=40 + syncmin=1.2 + dosubtract=.true. + doosd=.true. + nsp=3 + if(ndepth.eq.2) then + doosd=.false. + endif + if(ndepth.eq.1) then + nsp=1 + dosubtract=.false. + doosd=.false. + endif + + do isp = 1,nsp + if(isp.eq.2) then + if(ndecodes.eq.0) exit + nd1=ndecodes + elseif(isp.eq.3) then + nd2=ndecodes-nd1 + if(nd2.eq.0) exit + endif + + candidate=0.0 + ncand=0 + call timer('getcand4',0) + call getcandidates4(dd,fa,fb,syncmin,nfqso,maxcand,savg,candidate, & + ncand,sbase) + call timer('getcand4',1) + dobigfft=.true. + do icand=1,ncand + f0=candidate(1,icand) + snr=candidate(2,icand)-1.0 + call timer('ft4_down',0) + call ft4_downsample(dd,dobigfft,f0,cd2) !Downsample to 32 Sam/Sym + call timer('ft4_down',1) + if(dobigfft) dobigfft=.false. + sum2=sum(cd2*conjg(cd2))/(real(NMAX)/real(NDOWN)) + if(sum2.gt.0.0) cd2=cd2/sqrt(sum2) +! Sample rate is now 12000/18 = 666.67 samples/second + do iseg=1,3 ! DT search is done over 3 segments + do isync=1,2 + if(isync.eq.1) then + idfmin=-12 + idfmax=12 + idfstp=3 + ibmin=-344 + ibmax=1012 + if(iseg.eq.1) then + ibmin=108 + ibmax=560 + elseif(iseg.eq.2) then + smax1=smax + ibmin=560 + ibmax=1012 + elseif(iseg.eq.3) then + ibmin=-344 + ibmax=108 + endif + ibstp=4 + else + idfmin=idfbest-4 + idfmax=idfbest+4 + idfstp=1 + ibmin=ibest-5 + ibmax=ibest+5 + ibstp=1 + endif + ibest=-1 + idfbest=0 + smax=-99. + call timer('sync4d ',0) + do idf=idfmin,idfmax,idfstp + do istart=ibmin,ibmax,ibstp + call sync4d(cd2,istart,ctwk2(:,idf),1,sync) !Find sync power + if(sync.gt.smax) then + smax=sync + ibest=istart + idfbest=idf + endif + enddo + enddo + call timer('sync4d ',1) + enddo + if(iseg.eq.1) smax1=smax + if(smax.lt.1.2) cycle + if(iseg.gt.1 .and. smax.lt.smax1) cycle + f1=f0+real(idfbest) + if( f1.le.10.0 .or. f1.ge.4990.0 ) cycle + call timer('ft4down ',0) + call ft4_downsample(dd,dobigfft,f1,cb) !Final downsample, corrected f0 + call timer('ft4down ',1) + sum2=sum(abs(cb)**2)/(real(NSS)*NN) + if(sum2.gt.0.0) cb=cb/sqrt(sum2) + cd=0. + if(ibest.ge.0) then + it=min(NDMAX-1,ibest+NN*NSS-1) + np=it-ibest+1 + cd(0:np-1)=cb(ibest:it) else - print*,"Error - nsym must be 1, 2, or 4." + cd(-ibest:ibest+NN*NSS-1)=cb(0:NN*NSS+2*ibest-1) endif - enddo - ipt=1+(ks-1)*2 - if(nsym.eq.1) ibmax=1 - if(nsym.eq.2) ibmax=3 - if(nsym.eq.4) ibmax=7 - do ib=0,ibmax - bm=maxval(s2(0:nt-1),one(0:nt-1,ibmax-ib)) - & - maxval(s2(0:nt-1),.not.one(0:nt-1,ibmax-ib)) - if(ipt+ib.gt.2*NN) cycle - if(nsym.eq.1) then - bmeta(ipt+ib)=bm - elseif(nsym.eq.2) then - bmetb(ipt+ib)=bm - elseif(nsym.eq.4) then - bmetc(ipt+ib)=bm - endif - enddo - enddo - enddo + call timer('bitmet ',0) + call get_ft4_bitmetrics(cd,bitmetrics,badsync) + call timer('bitmet ',1) + if(badsync) cycle + hbits=0 + where(bitmetrics(:,1).ge.0) hbits=1 + ns1=count(hbits( 1: 8).eq.(/0,0,0,1,1,0,1,1/)) + ns2=count(hbits( 67: 74).eq.(/0,1,0,0,1,1,1,0/)) + ns3=count(hbits(133:140).eq.(/1,1,1,0,0,1,0,0/)) + ns4=count(hbits(199:206).eq.(/1,0,1,1,0,0,0,1/)) + nsync_qual=ns1+ns2+ns3+ns4 + if(nsync_qual.lt. 20) cycle - bmetb(205:206)=bmeta(205:206) - bmetc(201:204)=bmetb(201:204) - bmetc(205:206)=bmeta(205:206) + scalefac=2.83 + llra( 1: 58)=bitmetrics( 9: 66, 1) + llra( 59:116)=bitmetrics( 75:132, 1) + llra(117:174)=bitmetrics(141:198, 1) + llra=scalefac*llra + llrb( 1: 58)=bitmetrics( 9: 66, 2) + llrb( 59:116)=bitmetrics( 75:132, 2) + llrb(117:174)=bitmetrics(141:198, 2) + llrb=scalefac*llrb + llrc( 1: 58)=bitmetrics( 9: 66, 3) + llrc( 59:116)=bitmetrics( 75:132, 3) + llrc(117:174)=bitmetrics(141:198, 3) + llrc=scalefac*llrc - call normalizebmet(bmeta,2*NN) - call normalizebmet(bmetb,2*NN) - call normalizebmet(bmetc,2*NN) + apmag=maxval(abs(llra))*1.1 + npasses=3+nappasses(nQSOProgress) + if(lapcqonly) npasses=4 + if(ndepth.eq.1) npasses=3 + if(ncontest.ge.5) npasses=3 ! Don't support Fox and Hound + do ipass=1,npasses + if(ipass.eq.1) llr=llra + if(ipass.eq.2) llr=llrb + if(ipass.eq.3) llr=llrc + if(ipass.le.3) then + apmask=0 + iaptype=0 + endif - hbits=0 - where(bmeta.ge.0) hbits=1 - ns1=count(hbits( 1: 8).eq.(/0,0,0,1,1,0,1,1/)) - ns2=count(hbits( 67: 74).eq.(/0,1,0,0,1,1,1,0/)) - ns3=count(hbits(133:140).eq.(/1,1,1,0,0,1,0,0/)) - ns4=count(hbits(199:206).eq.(/1,0,1,1,0,0,0,1/)) - nsync_qual=ns1+ns2+ns3+ns4 - if(nsync_qual.lt. 20) cycle - - scalefac=2.83 - llra( 1: 58)=bmeta( 9: 66) - llra( 59:116)=bmeta( 75:132) - llra(117:174)=bmeta(141:198) - llra=scalefac*llra - llrb( 1: 58)=bmetb( 9: 66) - llrb( 59:116)=bmetb( 75:132) - llrb(117:174)=bmetb(141:198) - llrb=scalefac*llrb - llrc( 1: 58)=bmetc( 9: 66) - llrc( 59:116)=bmetc( 75:132) - llrc(117:174)=bmetc(141:198) - llrc=scalefac*llrc - - apmag=maxval(abs(llra))*1.1 - npasses=3+nappasses(nQSOProgress) - if(ncontest.ge.5) npasses=3 ! Don't support Fox and Hound - do ipass=1,npasses - if(ipass.eq.1) llr=llra - if(ipass.eq.2) llr=llrb - if(ipass.eq.3) llr=llrc - if(ipass.le.3) then - apmask=0 - iaptype=0 - endif - - if(ipass .gt. 3) then - llrd=llrc - iaptype=naptypes(nQSOProgress,ipass-3) + if(ipass .gt. 3) then + llrd=llra + iaptype=naptypes(nQSOProgress,ipass-3) + if(lapcqonly) iaptype=1 ! ncontest=0 : NONE ! 1 : NA_VHF @@ -394,94 +354,114 @@ contains ! 6 : HOUND ! ! Conditions that cause us to bail out of AP decoding - napwid=50 - if(ncontest.le.4 .and. iaptype.ge.3 .and. (abs(f0-nfqso).gt.napwid) ) cycle - if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall - if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall + napwid=50 + if(ncontest.le.4 .and. iaptype.ge.3 .and. (abs(f1-nfqso).gt.napwid) ) cycle + if(iaptype.ge.2 .and. apbits(1).gt.1) cycle ! No, or nonstandard, mycall + if(iaptype.ge.3 .and. apbits(30).gt.1) cycle ! No, or nonstandard, dxcall - if(iaptype.eq.1) then ! CQ or CQ TEST or CQ FD or CQ RU or CQ SCC - apmask=0 - apmask(1:29)=1 - llrd(1:29)=apmag*mcq(1:29) - endif + if(iaptype.eq.1) then ! CQ or CQ TEST or CQ FD or CQ RU or CQ SCC + apmask=0 + apmask(1:29)=1 + llrd(1:29)=apmag*mcq(1:29) + endif - if(iaptype.eq.2) then ! MyCall,???,??? - apmask=0 - if(ncontest.eq.0.or.ncontest.eq.1) then - apmask(1:29)=1 - llrd(1:29)=apmag*apbits(1:29) - else if(ncontest.eq.2) then - apmask(1:28)=1 - llrd(1:28)=apmag*apbits(1:28) - else if(ncontest.eq.3) then - apmask(1:28)=1 - llrd(1:28)=apmag*apbits(1:28) - else if(ncontest.eq.4) then - apmask(2:29)=1 - llrd(2:29)=apmag*apmy_ru(1:28) - endif - endif + if(iaptype.eq.2) then ! MyCall,???,??? + apmask=0 + if(ncontest.eq.0.or.ncontest.eq.1) then + apmask(1:29)=1 + llrd(1:29)=apmag*apbits(1:29) + else if(ncontest.eq.2) then + apmask(1:28)=1 + llrd(1:28)=apmag*apbits(1:28) + else if(ncontest.eq.3) then + apmask(1:28)=1 + llrd(1:28)=apmag*apbits(1:28) + else if(ncontest.eq.4) then + apmask(2:29)=1 + llrd(2:29)=apmag*apmy_ru(1:28) + endif + endif - if(iaptype.eq.3) then ! MyCall,DxCall,??? - apmask=0 - if(ncontest.eq.0.or.ncontest.eq.1.or.ncontest.eq.2) then - apmask(1:58)=1 - llrd(1:58)=apmag*apbits(1:58) - else if(ncontest.eq.3) then ! Field Day - apmask(1:56)=1 - llrd(1:28)=apmag*apbits(1:28) - llrd(29:56)=apmag*aphis_fd(1:28) - else if(ncontest.eq.4) then ! RTTY RU - apmask(2:57)=1 - llrd(2:29)=apmag*apmy_ru(1:28) - llrd(30:57)=apmag*apbits(30:57) - endif - endif + if(iaptype.eq.3) then ! MyCall,DxCall,??? + apmask=0 + if(ncontest.eq.0.or.ncontest.eq.1.or.ncontest.eq.2) then + apmask(1:58)=1 + llrd(1:58)=apmag*apbits(1:58) + else if(ncontest.eq.3) then ! Field Day + apmask(1:56)=1 + llrd(1:28)=apmag*apbits(1:28) + llrd(29:56)=apmag*aphis_fd(1:28) + else if(ncontest.eq.4) then ! RTTY RU + apmask(2:57)=1 + llrd(2:29)=apmag*apmy_ru(1:28) + llrd(30:57)=apmag*apbits(30:57) + endif + endif - if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then - apmask=0 - if(ncontest.le.4) then - apmask(1:91)=1 ! mycall, hiscall, RRR|73|RR73 - if(iaptype.eq.6) llrd(1:91)=apmag*apbits(1:91) - endif - endif + if(iaptype.eq.4 .or. iaptype.eq.5 .or. iaptype.eq.6) then + apmask=0 + if(ncontest.le.4) then + apmask(1:77)=1 ! mycall, hiscall, RRR|73|RR73 + if(iaptype.eq.6) llrd(1:77)=apmag*apbits(1:77) + endif + endif - llr=llrd - endif - max_iterations=40 - message77=0 - call timer('bpdec174',0) - call bpdecode174_91(llr,apmask,max_iterations,message77, & - cw,nharderror,niterations) - call timer('bpdec174',1) - if(sum(message77).eq.0) cycle - if( nharderror.ge.0 ) then - message77=mod(message77+rvec,2) ! remove rvec scrambling - write(c77,'(77i1)') message77(1:77) - call unpack77(c77,1,message,unpk77_success) - idupe=0 - do i=1,ndecodes - if(decodes(i).eq.message) idupe=1 - enddo - if(ibest.le.10 .and. message.eq.msg0) idupe=1 !Already decoded - if(idupe.eq.1) exit - ndecodes=ndecodes+1 - decodes(ndecodes)=message - if(snr.gt.0.0) then - xsnr=10*log10(snr)-14.0 - else - xsnr=-20.0 - endif - nsnr=nint(max(-20.0,xsnr)) - xdt=ibest/750.0 - 0.5 - call this%callback(sync,nsnr,xdt,f0,message,iaptype,qual) - if(ibest.ge.ibmax-15) msg0=message !Possible dupe candidate - exit - endif - enddo !Sequence estimation - enddo !Candidate list + llr=llrd + endif + message77=0 + dmin=0.0 + call timer('bpdec174',0) + call bpdecode174_91(llr,apmask,max_iterations,message77, & + cw,nharderror,niterations) + call timer('bpdec174',1) - return - end subroutine decode + if(doosd .and. nharderror.lt.0) then + ndeep=3 +! if(abs(nfqso-f1).le.napwid) then +! ndeep=4 +! endif + call timer('osd174_91 ',0) + call osd174_91(llr,apmask,ndeep,message77,cw,nharderror,dmin) + call timer('osd174_91 ',1) + endif + + if(sum(message77).eq.0) cycle + if( nharderror.ge.0 ) then + message77=mod(message77+rvec,2) ! remove rvec scrambling + write(c77,'(77i1)') message77(1:77) + call unpack77(c77,1,message,unpk77_success) + if(unpk77_success.and.dosubtract) then + call get_ft4_tones_from_77bits(message77,i4tone) + dt=real(ibest)/666.67 + call timer('subtract',0) + call subtractft4(dd,i4tone,f1,dt) + call timer('subtract',1) + endif + idupe=0 + do i=1,ndecodes + if(decodes(i).eq.message) idupe=1 + enddo + if(idupe.eq.1) exit + ndecodes=ndecodes+1 + decodes(ndecodes)=message + if(snr.gt.0.0) then + xsnr=10*log10(snr)-14.8 + else + xsnr=-21.0 + endif + nsnr=nint(max(-21.0,xsnr)) + xdt=ibest/666.67 - 0.5 +!write(21,'(i6.6,i5,2x,f4.1,i6,2x,a37,2x,f4.1,3i3,f5.1,i4,i4,i4)') & +! nutc,nsnr,xdt,nint(f1),message,smax,iaptype,ipass,isp,dmin,nsync_qual,nharderror,iseg + call this%callback(smax,nsnr,xdt,f1,message,iaptype,qual) + exit + endif + enddo !Sequence estimation + if(nharderror.ge.0) exit + enddo !3 DT segments + enddo !Candidate list + enddo !Subtraction loop + return + end subroutine decode end module ft4_decode diff --git a/lib/ft8/ft8b.f90 b/lib/ft8/ft8b.f90 index 6fbb03685..0376311f2 100644 --- a/lib/ft8/ft8b.f90 +++ b/lib/ft8/ft8b.f90 @@ -396,7 +396,7 @@ subroutine ft8b(dd0,newdat,nQSOProgress,nfqso,nftx,ndepth,lapon,lapcqonly, & cycle endif nbadcrc=0 ! If we get this far: valid codeword, valid (i3,n3), nonquirky message. - call get_tones_from_77bits(message77,itone) + call get_ft8_tones_from_77bits(message77,itone) if(lsubtract) call subtractft8(dd0,itone,f1,xdt) xsig=0.0 xnoi=0.0 diff --git a/lib/ft8/ft8sim.f90 b/lib/ft8/ft8sim.f90 index bbec600d4..c5dd82bb7 100644 --- a/lib/ft8/ft8sim.f90 +++ b/lib/ft8/ft8sim.f90 @@ -91,7 +91,7 @@ program ft8sim msg0=msg do ifile=1,nfiles k=nint((xdt+0.5)/dt) - ia=k + ia=max(1,k) phi=0.0 c0=0.0 do j=1,NN !Generate complex waveform @@ -105,7 +105,7 @@ program ft8sim if(fspread.ne.0.0 .or. delay.ne.0.0) call watterson(c0,NMAX,NWAVE,fs,delay,fspread) c=sig*c0 - ib=k + ib=min(k,NMAX) wave=real(c) peak=maxval(abs(wave(ia:ib))) nslots=1 diff --git a/lib/ft8/ft8sim_gfsk.f90 b/lib/ft8/ft8sim_gfsk.f90 index aba046cef..4cca67e48 100644 --- a/lib/ft8/ft8sim_gfsk.f90 +++ b/lib/ft8/ft8sim_gfsk.f90 @@ -57,6 +57,7 @@ program ft8sim_gfsk baud=1.0/tt !Keying rate (baud) bw=8*baud !Occupied bandwidth (Hz) txt=NZ*dt !Transmission length (s) + bt=2.0 bandwidth_ratio=2500.0/(fs/2.0) sig=sqrt(2*bandwidth_ratio) * 10.0**(0.05*snrdb) if(snrdb.gt.90.0) sig=1.0 @@ -67,7 +68,7 @@ program ft8sim_gfsk n3=-1 call pack77(msg37,i3,n3,c77) call genft8(msg37,i3,n3,msgsent37,msgbits,itone) - call gen_ft8wave(itone,NN,NSPS,fs,f0,cwave,xjunk,1,NWAVE) !Generate complex cwave + call gen_ft8wave(itone,NN,NSPS,bt,fs,f0,cwave,xjunk,1,NWAVE) !Generate complex cwave write(*,*) write(*,'(a23,a37,3x,a7,i1,a1,i1)') 'New Style FT8 Message: ',msgsent37,'i3.n3: ',i3,'.',n3 diff --git a/lib/ft8/gen_ft8wave.f90 b/lib/ft8/gen_ft8wave.f90 index d4b58a426..10edc994e 100644 --- a/lib/ft8/gen_ft8wave.f90 +++ b/lib/ft8/gen_ft8wave.f90 @@ -1,4 +1,4 @@ -subroutine gen_ft8wave(itone,nsym,nsps,fsample,f0,cwave,wave,icmplx,nwave) +subroutine gen_ft8wave(itone,nsym,nsps,bt,fsample,f0,cwave,wave,icmplx,nwave) ! ! generate ft8 waveform using Gaussian-filtered frequency pulses. ! @@ -9,21 +9,20 @@ subroutine gen_ft8wave(itone,nsym,nsps,fsample,f0,cwave,wave,icmplx,nwave) real pulse(23040) real dphi(0:(nsym+2)*nsps-1) integer itone(nsym) - logical first - data first/.true./ - save pulse,first,twopi,dt,hmod + data ibt0/0/ + save pulse,twopi,dt,hmod,ibt0 - if(first) then + ibt=nint(10*bt) + if(ibt0.ne.ibt) then twopi=8.0*atan(1.0) dt=1.0/fsample hmod=1.0 - bt=2.0 ! Compute the frequency-smoothing pulse do i=1,3*nsps tt=(i-1.5*nsps)/real(nsps) pulse(i)=gfsk_pulse(bt,tt) enddo - first=.false. + ibt0=nint(10*bt) endif ! Compute the smoothed frequency waveform. @@ -43,6 +42,7 @@ subroutine gen_ft8wave(itone,nsym,nsps,fsample,f0,cwave,wave,icmplx,nwave) phi=0.0 dphi = dphi + twopi*f0*dt !Shift frequency up by f0 wave=0. + if (icmplx .ne. 0) cwave=0. ! avoid writing to memory we may not have access to k=0 do j=nsps,nsps+nwave-1 !Don't include dummy symbols k=k+1 diff --git a/lib/ft8/genft8.f90 b/lib/ft8/genft8.f90 index 41ff546c3..a03c3e587 100644 --- a/lib/ft8/genft8.f90 +++ b/lib/ft8/genft8.f90 @@ -25,7 +25,7 @@ subroutine genft8(msg,i3,n3,msgsent,msgbits,itone) msgsent='*** bad message *** ' go to 900 -entry get_tones_from_77bits(msgbits,itone) +entry get_ft8_tones_from_77bits(msgbits,itone) 2 call encode174_91(msgbits,codeword) !Encode the test message diff --git a/lib/ft8/subtractft8.f90 b/lib/ft8/subtractft8.f90 index 1031cf2b7..200139a2b 100644 --- a/lib/ft8/subtractft8.f90 +++ b/lib/ft8/subtractft8.f90 @@ -11,16 +11,22 @@ subroutine subtractft8(dd,itone,f0,dt) parameter (NMAX=15*12000,NFRAME=1920*79) parameter (NFFT=NMAX,NFILT=1400) - real*4 dd(NMAX), window(-NFILT/2:NFILT/2) + real*4 dd(NMAX), window(-NFILT/2:NFILT/2), xjunk complex cref,camp,cfilt,cw integer itone(79) logical first data first/.true./ - common/heap8/cref(NFRAME),camp(NMAX),cfilt(NMAX),cw(NMAX) + common/heap8/cref(NFRAME),camp(NMAX),cfilt(NMAX),cw(NMAX),xjunk(NFRAME) save first nstart=dt*12000+1 - call genft8refsig(itone,cref,f0) +! call genft8refsig(itone,cref,f0) + nsym=79 + nsps=1920 + fs=12000.0 + icmplx=1 + bt=4.0 ! Temporary compromise? + call gen_ft8wave(itone,nsym,nsps,bt,fs,f0,cref,xjunk,icmplx,NFRAME) camp=0. do i=1,nframe id=nstart-1+i diff --git a/lib/ft8/sync8.f90 b/lib/ft8/sync8.f90 index 3924f1bad..219c6ebf1 100644 --- a/lib/ft8/sync8.f90 +++ b/lib/ft8/sync8.f90 @@ -89,7 +89,12 @@ subroutine sync8(dd,nfa,nfb,syncmin,nfqso,maxcand,s,candidate, & enddo iz=ib-ia+1 call indexx(red(ia:ib),iz,indx) - ibase=indx(nint(0.40*iz)) - 1 + ia + npctile=nint(0.40*iz) + if(npctile.lt.1) then ! something is wrong; bail out + ncand=0 + return; + endif + ibase=indx(npctile) - 1 + ia if(ibase.lt.1) ibase=1 if(ibase.gt.nh1) ibase=nh1 base=red(ibase) diff --git a/lib/jt4_decode.f90 b/lib/jt4_decode.f90 index da0fbda68..ff0b33c4d 100644 --- a/lib/jt4_decode.f90 +++ b/lib/jt4_decode.f90 @@ -156,7 +156,7 @@ contains nfreqz=nint(dfx) call timer('sync4 ',1) - nsnr=nint(snrx) + nsnr=-26 if(sync.lt.syncmin) then if (associated (this%decode_callback)) then call this%decode_callback(nsnr,dtxz,nfreqz,.false.,csync, & @@ -166,6 +166,7 @@ contains endif ! We have achieved sync + nsnr=nint(snrsync - 22.9) decoded=blank deepmsg=blank special=' ' diff --git a/lib/jt9.f90 b/lib/jt9.f90 index 7b3b0181e..2e8dbd0f0 100644 --- a/lib/jt9.f90 +++ b/lib/jt9.f90 @@ -22,7 +22,8 @@ program jt9 !### ndepth was defined as 60001. Why??? integer :: arglen,stat,offset,remain,mode=0,flow=200,fsplit=2700, & fhigh=4000,nrxfreq=1500,ntrperiod=1,ndepth=1,nexp_decode=0 - logical :: read_files = .true., tx9 = .false., display_help = .false. + logical :: read_files = .true., tx9 = .false., display_help = .false., & + bLowSidelobes = .false. type (option) :: long_options(26) = [ & option ('help', .false., 'h', 'Display this help message', ''), & option ('shmem',.true.,'s','Use shared memory for sample data','KEY'), & @@ -138,7 +139,7 @@ program jt9 read (optarg(:arglen), *) nexp_decode end select end do - + if (display_help .or. stat .lt. 0 & .or. (.not. read_files .and. remain .gt. 0) & .or. (read_files .and. remain .lt. 1)) then @@ -156,7 +157,7 @@ program jt9 end do go to 999 endif - + iret=fftwf_init_threads() !Initialize FFTW threading ! Default to 1 thread, but use nthreads for the big ones @@ -224,7 +225,7 @@ program jt9 endif shared_data%id2=0 !??? Why is this necessary ??? - + if(mode.eq.5) npts=21*3456 do iblk=1,npts/kstep k=iblk*kstep if(mode.eq.8 .and. k.gt.179712) exit @@ -232,7 +233,7 @@ program jt9 read(unit=wav%lun,end=3) shared_data%id2(k-kstep+1:k) go to 4 3 call timer('read_wav',1) - print*,'EOF on input file ',infile + print*,'EOF on input file ',trim(infile) exit 4 call timer('read_wav',1) nhsym=(k-2048)/kstep @@ -242,7 +243,7 @@ program jt9 ingain=0 call timer('symspec ',0) nminw=1 - call symspec(shared_data,k,ntrperiod,nsps,ingain,nminw,pxdb, & + call symspec(shared_data,k,ntrperiod,nsps,ingain,bLowSidelobes,nminw,pxdb, & s,df3,ihsym,npts8,pxdbmax) call timer('symspec ',1) endif diff --git a/lib/readwav.f90 b/lib/readwav.f90 index ebc30c9a0..253690496 100644 --- a/lib/readwav.f90 +++ b/lib/readwav.f90 @@ -53,7 +53,8 @@ contains type(riff_descriptor) :: desc character(len=4) :: riff_type - open (newunit=this%lun, file=filename, access='stream', form='unformatted', status='old') + this%lun=26 + open (unit=this%lun, file=filename, access='stream',status='old') read (unit=this%lun) desc,riff_type inquire (unit=this%lun, pos=filepos) do @@ -67,5 +68,6 @@ contains end if filepos = filepos + (desc%size + 1) / 2 * 2 ! pad to even alignment end do + return end subroutine read end module readwav diff --git a/lib/rtty_spec.f90 b/lib/rtty_spec.f90 new file mode 100644 index 000000000..2ddc802f1 --- /dev/null +++ b/lib/rtty_spec.f90 @@ -0,0 +1,102 @@ +program rtty_spec + +! Generate simulated data for standard RTTY and WSJT-X modes FT8, FT4 + + use wavhdr + use packjt + parameter (NMAX=15*12000) + type(hdr) h + complex cwave(NMAX) + real wave(NMAX) + real*4 dat(NMAX) !Generated waveform + integer*2 iwave(NMAX) !Generated waveform + integer itone(680) !Channel symbols (values 0-1, 0-3, 0-7) + integer*1 msgbits(77) + character*37 msg37,msgsent37 + character*8 arg + + nargs=iargc() + if(nargs.ne.1) then + print*,'Usage: rtty_spec ' + go to 999 + endif + call getarg(1,arg) + read(arg,*) snrdb !S/N in dB (2500 hz reference BW) + + rmsdb=25. + rms=10.0**(0.05*rmsdb) + sig=10.0**(0.05*snrdb) + npts=NMAX + + do i=1,NMAX !Generate gaussian noise + dat(i)=gran() + enddo + +! Add the RTTY signal + fsample=12000.0 !Sample rate (Hz) + dt=1.0/fsample !Sample interval (s) + twopi=8.0*atan(1.0) + phi=0. + dphi=0. + j0=-1 + do i=6001,NMAX-6000 + j=nint(i*dt/0.022) + if(j.ne.j0) then + f0=1415.0 + call random_number(rr) + if(rr.gt.0.5) f0=1585.0 + dphi=twopi*f0*dt + j0=j + endif + phi=phi+dphi + if(phi.gt.twopi) phi=phi-twopi + dat(i)=dat(i) + sig*sin(phi) + enddo + +! FT8 signal (FSK) + i3=0 + n3=0 + msg37='WB9XYZ KA2ABC FN42' + call genft8(msg37,i3,n3,msgsent37,msgbits,itone) + nsym=79 + nsps=1920 + bt=99.0 + f0=3500.0 + icmplx=0 + nwave=nsym*nsps + call gen_ft8wave(itone,nsym,nsps,bt,fsample,f0,cwave,wave,icmplx,nwave) + dat(6001:6000+nwave)=dat(6001:6000+nwave) + sig*wave(1:nwave) + +! FT8 signal (GFSK) + i3=0 + n3=0 + msg37='WB9XYZ KA2ABC FN42' + call genft8(msg37,i3,n3,msgsent37,msgbits,itone) + nsym=79 + nsps=1920 + bt=2.0 + f0=4000.0 + icmplx=0 + nwave=nsym*nsps + call gen_ft8wave(itone,nsym,nsps,bt,fsample,f0,cwave,wave,icmplx,nwave) + dat(6001:6000+nwave)=dat(6001:6000+nwave) + sig*wave(1:nwave) + +! Add the FT4 signal + ichk=0 + call genft4(msg37,ichk,msgsent37,msgbits,itone) + nsym=103 + nsps=576 + f0=4500.0 + icmplx=0 + nwave=(nsym+2)*nsps + call gen_ft4wave(itone,nsym,nsps,fsample,f0,cwave,wave,icmplx,nwave) + dat(6001:6000+nwave)=dat(6001:6000+nwave) + sig*wave(1:nwave) + + h=default_header(12000,NMAX) + datmax=maxval(abs(dat)) + iwave=nint(32767.0*dat/datmax) + open(10,file='000000_000001.wav',access='stream',status='unknown') + write(10) h,iwave + close(10) + +999 end program rtty_spec diff --git a/logbook/AD1CCty.cpp b/logbook/AD1CCty.cpp index 58ed375f6..23d34fb43 100644 --- a/logbook/AD1CCty.cpp +++ b/logbook/AD1CCty.cpp @@ -16,6 +16,7 @@ #include #include #include +#include "Configuration.hpp" #include "Radio.hpp" #include "pimpl_impl.hpp" @@ -155,14 +156,16 @@ typedef multi_index_container< class AD1CCty::impl final { public: - explicit impl () + using entity_by_id = entities_type::index::type; + + explicit impl (Configuration const * configuration) + : configuration_ {configuration} { } - Record fixup (QString call, prefix const& p) const + entity_by_id::iterator lookup_entity (QString call, prefix const& p) const { call = call.toUpper (); - using entity_by_id = entities_type::index::type; entity_by_id::iterator e; // iterator into entity set // @@ -171,23 +174,26 @@ public: if (call.startsWith ("KG4") && call.size () != 5 && call.size () != 3) { // KG4 2x1 and 2x3 calls that map to Gitmo are mainland US not Gitmo - e = entities_.project (entities_.get ().find ("K")); + return entities_.project (entities_.get ().find ("K")); } else { - e = entities_.get ().find (p.entity_id_); + return entities_.get ().find (p.entity_id_); } - + } + + Record fixup (prefix const& p, entity const& e) const + { Record result; - result.continent = e->continent_; - result.CQ_zone = e->CQ_zone_; - result.ITU_zone = e->ITU_zone_; - result.entity_name = e->name_; - result.WAE_only = e->WAE_only_; - result.latitude = e->lat_; - result.longtitude = e->long_; - result.UTC_offset = e->UTC_offset_; - result.primary_prefix = e->primary_prefix_; + result.continent = e.continent_; + result.CQ_zone = e.CQ_zone_; + result.ITU_zone = e.ITU_zone_; + result.entity_name = e.name_; + result.WAE_only = e.WAE_only_; + result.latitude = e.lat_; + result.longtitude = e.long_; + result.UTC_offset = e.UTC_offset_; + result.primary_prefix = e.primary_prefix_; // check for overrides bool ok1 {true}, ok2 {true}, ok3 {true}, ok4 {true}, ok5 {true}; @@ -220,6 +226,7 @@ public: return false; } + Configuration const * configuration_; QString path_; entities_type entities_; prefixes_type prefixes_; @@ -307,8 +314,13 @@ char const * AD1CCty::continent (Continent c) } } -AD1CCty::AD1CCty () +AD1CCty::AD1CCty (Configuration const * configuration) + : m_ {configuration} { + Q_ASSERT (configuration); + // TODO: G4WJS - consider doing the following asynchronously to + // speed up startup. Not urgent as it takes less than 1s on a Core + // i7 reading BIG CTY.DAT. QDir dataPath {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}; m_->path_ = dataPath.exists (file_name) ? dataPath.absoluteFilePath (file_name) // user override @@ -389,7 +401,7 @@ auto AD1CCty::lookup (QString const& call) const -> Record auto p = m_->prefixes_.find (exact_search); if (p != m_->prefixes_.end () && p->exact_) { - return m_->fixup (call, *p); + return m_->fixup (*p, *m_->lookup_entity (call, *p)); } } while (search_prefix.size ()) @@ -397,9 +409,11 @@ auto AD1CCty::lookup (QString const& call) const -> Record auto p = m_->prefixes_.find (search_prefix); if (p != m_->prefixes_.end ()) { - if (!p->exact_ || call.size () == search_prefix.size ()) + impl::entity_by_id::iterator e = m_->lookup_entity (call, *p); + if ((m_->configuration_->include_WAE_entities () || !e->WAE_only_) + && (!p->exact_ || call.size () == search_prefix.size ())) { - return m_->fixup (call, *p); + return m_->fixup (*p, *e); } } search_prefix = search_prefix.left (search_prefix.size () - 1); diff --git a/logbook/AD1CCty.hpp b/logbook/AD1CCty.hpp index 37cada3e9..4a485afa9 100644 --- a/logbook/AD1CCty.hpp +++ b/logbook/AD1CCty.hpp @@ -1,17 +1,19 @@ #ifndef AD1C_CTY_HPP_ #define AD1C_CTY_HPP_ -#include #include +#include #include "pimpl_h.hpp" +class QString; +class Configuration; + // // AD1CCty - Fast access database of Jim Reisert, AD1C's, cty.dat // entity and entity override information file. // class AD1CCty final : public QObject - , private boost::noncopyable { Q_OBJECT @@ -39,7 +41,7 @@ public: QString primary_prefix; }; - explicit AD1CCty (); + explicit AD1CCty (Configuration const *); ~AD1CCty (); Record lookup (QString const& call) const; diff --git a/logbook/Multiplier.cpp b/logbook/Multiplier.cpp new file mode 100644 index 000000000..6323e4feb --- /dev/null +++ b/logbook/Multiplier.cpp @@ -0,0 +1,44 @@ +#include "Multiplier.hpp" + +#include +#include +#include +#include "models/CabrilloLog.hpp" +#include "pimpl_impl.hpp" + +class Multiplier::impl +{ +public: + impl (AD1CCty const * countries) + : countries_ {countries} + { + } + + AD1CCty const * countries_; + worked_set entities_worked_; + worked_set grids_worked_; +}; + +Multiplier::Multiplier (AD1CCty const * countries) + : m_ {countries} +{ +} + +Multiplier::~Multiplier () +{ +} + +void Multiplier::reload (CabrilloLog const * log) +{ + m_->entities_worked_ = log->unique_DXCC_entities (m_->countries_); +} + +auto Multiplier::entities_worked () const -> worked_set const& +{ + return m_->entities_worked_; +} + +auto Multiplier::grids_worked () const -> worked_set const& +{ + return m_->grids_worked_; +} diff --git a/logbook/Multiplier.hpp b/logbook/Multiplier.hpp new file mode 100644 index 000000000..2271dd775 --- /dev/null +++ b/logbook/Multiplier.hpp @@ -0,0 +1,30 @@ +#ifndef MULTIPLIER_HPP_ +#define MULTIPLIER_HPP_ + +#include +#include +#include "pimpl_h.hpp" + +class QString; +class AD1CCty; +class CabrilloLog; + +class Multiplier final + : private boost::noncopyable +{ +public: + using worked_item = QPair; + using worked_set = QSet; + + explicit Multiplier (AD1CCty const *); + ~Multiplier (); + void reload (CabrilloLog const *); + worked_set const& entities_worked () const; + worked_set const& grids_worked () const; + +private: + class impl; + pimpl m_; +}; + +#endif diff --git a/logbook/WorkedBefore.cpp b/logbook/WorkedBefore.cpp index daaf18fc7..aa65ab651 100644 --- a/logbook/WorkedBefore.cpp +++ b/logbook/WorkedBefore.cpp @@ -18,7 +18,7 @@ #include #include #include - +#include "Configuration.hpp" #include "qt_helpers.hpp" #include "pimpl_impl.hpp" @@ -332,10 +332,15 @@ namespace // will parse a record { auto const& entity = prefixes->lookup (call); + auto mode = extractField (record, "MODE").toUpper (); + if (!mode.size () || "MFSK" == mode) + { + mode = extractField (record, "SUBMODE").toUpper (); + } worked.emplace (call.toUpper () , extractField (record, "GRIDSQUARE").left (4).toUpper () // not interested in 6-digit grids , extractField (record, "BAND").toUpper () - , extractField (record, "MODE").toUpper () + , mode , entity.entity_name , entity.continent , entity.CQ_zone @@ -356,8 +361,9 @@ namespace class WorkedBefore::impl final { public: - impl () + impl (Configuration const * configuration) : path_ {QDir {QStandardPaths::writableLocation (QStandardPaths::DataLocation)}.absoluteFilePath (logFileName)} + , prefixes_ {configuration} { } @@ -374,8 +380,10 @@ public: worked_before_database_type worked_; }; -WorkedBefore::WorkedBefore () +WorkedBefore::WorkedBefore (Configuration const * configuration) + : m_ {configuration} { + Q_ASSERT (configuration); connect (&m_->loader_watcher_, &QFutureWatcher::finished, [this] () { QString error; size_t n {0}; @@ -407,9 +415,9 @@ QString const& WorkedBefore::path () const return m_->path_; } -AD1CCty const& WorkedBefore::countries () const +AD1CCty const * WorkedBefore::countries () const { - return m_->prefixes_; + return &m_->prefixes_; } bool WorkedBefore::add (QString const& call diff --git a/logbook/WorkedBefore.hpp b/logbook/WorkedBefore.hpp index 90a31813a..1aae1aca4 100644 --- a/logbook/WorkedBefore.hpp +++ b/logbook/WorkedBefore.hpp @@ -5,6 +5,7 @@ #include "AD1CCty.hpp" #include "pimpl_h.hpp" +class Configuration; class CountryDat; class QString; class QByteArray; @@ -17,7 +18,7 @@ class WorkedBefore final public: using Continent = AD1CCty::Continent; - explicit WorkedBefore (); + explicit WorkedBefore (Configuration const *); ~WorkedBefore (); Q_SLOT void reload (); @@ -28,7 +29,7 @@ public: , QByteArray const& ADIF_record); QString const& path () const; - AD1CCty const& countries () const; + AD1CCty const * countries () const; bool country_worked (QString const& call, QString const& mode, QString const& band) const; bool grid_worked (QString const& grid, QString const& mode, QString const& band) const; bool call_worked (QString const& call, QString const& mode, QString const& band) const; diff --git a/logbook/logbook.cpp b/logbook/logbook.cpp index b84b65c1a..96a8cb8e3 100644 --- a/logbook/logbook.cpp +++ b/logbook/logbook.cpp @@ -3,15 +3,25 @@ #include #include "Configuration.hpp" #include "AD1CCty.hpp" +#include "Multiplier.hpp" +#include "logbook/AD1CCty.hpp" +#include "models/CabrilloLog.hpp" +#include "models/FoxLog.hpp" #include "moc_logbook.cpp" LogBook::LogBook (Configuration const * configuration) : config_ {configuration} + , worked_before_ {configuration} { + Q_ASSERT (configuration); connect (&worked_before_, &WorkedBefore::finished_loading, this, &LogBook::finished_loading); } +LogBook::~LogBook () +{ +} + void LogBook::match (QString const& call, QString const& mode, QString const& grid, AD1CCty::Record const& looked_up, bool& callB4, @@ -22,7 +32,7 @@ void LogBook::match (QString const& call, QString const& mode, QString const& gr bool& ITUZoneB4, QString const& band) const { - if (call.length() > 0) + if (call.size() > 0) { auto const& mode_to_check = (config_ && !config_->highlight_by_mode ()) ? QString {} : mode; callB4 = worked_before_.call_worked (call, mode_to_check, band); @@ -67,46 +77,121 @@ QByteArray LogBook::QSOToADIF (QString const& hisCall, QString const& hisGrid, Q QString const& xSent, QString const& xRcvd) { QString t; - t = "" + hisCall; - t += " " + hisGrid; - t += " " + mode; - t += " " + rptSent; - t += " " + rptRcvd; + t = "" + hisCall; + t += " " + hisGrid; + if (mode != "FT4") + { + t += " " + mode; + } + else + { + t += " MFSK " + mode; + } + t += " " + rptSent; + t += " " + rptRcvd; t += " " + dateTimeOn.date().toString("yyyyMMdd"); t += " " + dateTimeOn.time().toString("hhmmss"); t += " " + dateTimeOff.date().toString("yyyyMMdd"); t += " " + dateTimeOff.time().toString("hhmmss"); - t += " " + band; - t += " " + strDialFreq; - t += " " + myCall; - t += " " + myGrid; - if(txPower!="") t += " " + txPower; - if(comments!="") t += " " + comments; - if(name!="") t += " " + name; - if(operator_call!="") t+=" " + operator_call; + t += " " + band; + t += " " + strDialFreq; + t += " " + myCall; + t += " " + myGrid; + if(txPower!="") t += " " + txPower; + if(comments!="") t += " " + comments; + if(name!="") t += " " + name; + if(operator_call!="") t+=" " + operator_call; if (xSent.size ()) { auto words = xSent.split (' ', QString::SkipEmptyParts); if (words.size () > 1) { - bool ok; - auto sn = words.back ().toUInt (&ok); - if (ok && sn) + if (words.back ().toUInt ()) { // assume last word is a serial if there are at least // two words and if it is positive numeric - t += " ' + words.back (); + t += " ' + words.back (); + } + else + { + if (words.front ().toUInt () && words.front ().size () > 3) // EU VHF contest mode + { + auto sn_text = words.front ().mid (2); + // assume first word is report+serial if there are + // at least two words and if the first word less the + // first two characters is a positive numeric + t += " ' + sn_text; + } } } } if (xRcvd.size ()) { - QString t1=""; - if(xRcvd.split(" ").size()==2) t1=xRcvd.split(" ").at(1); - if(t1.toInt()>0) { - t += " " + t1; - } else { - t += " " + t1; - } + auto words = xRcvd.split (' ', QString::SkipEmptyParts); + if (words.size () == 2) + { + if (words.at (1).toUInt ()) + { + t += " " + words.at (1); + } + else if (words.at (0).toUInt () && words.at (0).size () > 3) // EU VHF contest exchange + { + // strip report and set SRX to serial + t += " " + words.at (0).mid (2); + } + else + { + if (Configuration::SpecialOperatingActivity::FIELD_DAY == config_->special_op_id ()) + { + // include DX as an ARRL_SECT value even though it is + // not in the ADIF spec ARRL_SECT enumeration, done + // because N1MM does the same + t += " ARRL-FIELD-DAY ' + xRcvd + + " ' + + words.at (0) + " ' + words.at (1); + } + else if (Configuration::SpecialOperatingActivity::RTTY == config_->special_op_id ()) + { + t += " " + words.at (1); + } + } + } } return t.toLatin1(); } + +CabrilloLog * LogBook::contest_log () +{ + // lazy create of Cabrillo log object instance + if (!contest_log_) + { + contest_log_.reset (new CabrilloLog {config_}); + if (!multiplier_) + { + multiplier_.reset (new Multiplier {countries ()}); + } + connect (contest_log_.data (), &CabrilloLog::data_changed, [this] () { + multiplier_->reload (contest_log_.data ()); + }); + } + return contest_log_.data (); +} + +Multiplier const * LogBook::multiplier () const +{ + // lazy create of Multiplier object instance + if (!multiplier_) + { + multiplier_.reset (new Multiplier {countries ()}); + } + return multiplier_.data (); +} + +FoxLog * LogBook::fox_log () +{ + // lazy create of Fox log object instance + if (!fox_log_) + { + fox_log_.reset (new FoxLog {config_}); + } + return fox_log_.data (); +} diff --git a/logbook/logbook.h b/logbook/logbook.h index 1850aa01f..858bb64d8 100644 --- a/logbook/logbook.h +++ b/logbook/logbook.h @@ -8,12 +8,16 @@ #include #include +#include #include "WorkedBefore.hpp" class Configuration; class QByteArray; class QDateTime; +class CabrilloLog; +class Multiplier; +class FoxLog; class LogBook final : public QObject @@ -22,30 +26,38 @@ class LogBook final public: LogBook (Configuration const *); + ~LogBook (); QString const& path () const {return worked_before_.path ();} bool add (QString const& call , QString const& grid , QString const& band , QString const& mode , QByteArray const& ADIF_record); - AD1CCty const& countries () const {return worked_before_.countries ();} + AD1CCty const * countries () const {return worked_before_.countries ();} void rescan (); void match (QString const& call, QString const& mode, QString const& grid, AD1CCty::Record const&, bool& callB4, bool& countryB4, bool &gridB4, bool &continentB4, bool& CQZoneB4, bool& ITUZoneB4, QString const& currentBand = QString {}) const; - static QByteArray QSOToADIF (QString const& hisCall, QString const& hisGrid, QString const& mode, - QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, - QDateTime const& dateTimeOff, QString const& band, QString const& comments, - QString const& name, QString const& strDialFreq, QString const& myCall, - QString const& m_myGrid, QString const& m_txPower, QString const& operator_call, - QString const& xSent, QString const& xRcvd); + QByteArray QSOToADIF (QString const& hisCall, QString const& hisGrid, QString const& mode, + QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, + QDateTime const& dateTimeOff, QString const& band, QString const& comments, + QString const& name, QString const& strDialFreq, QString const& myCall, + QString const& m_myGrid, QString const& m_txPower, QString const& operator_call, + QString const& xSent, QString const& xRcvd); Q_SIGNAL void finished_loading (int worked_before_record_count, QString const& error) const; + CabrilloLog * contest_log (); + Multiplier const * multiplier () const; + FoxLog * fox_log (); + private: Configuration const * config_; WorkedBefore worked_before_; + QScopedPointer contest_log_; + QScopedPointer mutable multiplier_; + QScopedPointer fox_log_; }; #endif diff --git a/logbook/logbook.pri b/logbook/logbook.pri index fcac62524..e67cdebd3 100644 --- a/logbook/logbook.pri +++ b/logbook/logbook.pri @@ -2,10 +2,12 @@ SOURCES += \ logbook/countriesworked.cpp \ logbook/logbook.cpp \ logbook/AD1CCty.cpp \ - logbook/WorkedBefore.cpp + logbook/WorkedBefore.cpp \ + logbook/Multiplier.cpp HEADERS += \ logbook/WorkedBefore.hpp \ logbook/logbook.h \ logbook/countriesworked.h \ - logbook/AD1CCty.hpp + logbook/AD1CCty.hpp \ + logbook/Multiplier.hpp diff --git a/main.cpp b/main.cpp index 1ea0c6a49..fc791adec 100644 --- a/main.cpp +++ b/main.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +107,34 @@ int main(int argc, char *argv[]) ExceptionCatchingApplication a(argc, argv); try { + // + // Enable i18n + // + QTranslator translator_from_resources; + // Default translations for releases use translations stored in + // the resources file system under the Translations + // directory. These are built by the CMake build system from .ts + // files in the translations source directory. New languages are + // added by enabling the UPDATE_TRANSLATIONS CMake option and + // building with the new language added to the LANGUAGES CMake + // list variable. UPDATE_TRANSLATIONS will preserve existing + // translations but should only be set when adding new + // languages. The resulting .ts files should be checked info + // source control for translators to access and update. + translator_from_resources.load (QLocale::system (), "wsjtx", "_", ":/Translations"); + a.installTranslator (&translator_from_resources); + + QTranslator translator_from_files; + // Load any matching translation from the current directory + // using the locale name. This allows translators to easily test + // their translations by releasing (lrelease) a .qm file into + // the current directory with a suitable name + // (e.g. wsjtx_en_GB.qm), then running wsjtx to view the + // results. Either the system locale setting or the environment + // variable LANG can be used to select the target language. + translator_from_files.load (QString {"wsjtx_"} + QLocale::system ().name ()); + a.installTranslator (&translator_from_files); + setlocale (LC_NUMERIC, "C"); // ensure number forms are in // consistent format, do this after // instantiating QApplication so @@ -380,10 +409,12 @@ int main(int argc, char *argv[]) } catch (std::exception const& e) { + MessageBox::critical_message (nullptr, QApplication::translate ("main", "Fatal error"), e.what ()); std::cerr << "Error: " << e.what () << '\n'; } catch (...) { + MessageBox::critical_message (nullptr, QApplication::translate ("main", "Unexpected fatal error")); std::cerr << "Unexpected fatal error\n"; throw; // hoping the runtime might tell us more about the exception } diff --git a/models/Bands.cpp b/models/Bands.cpp index a70358fa3..e24d42965 100644 --- a/models/Bands.cpp +++ b/models/Bands.cpp @@ -55,6 +55,8 @@ namespace } } +#include "moc_Bands.cpp" + Bands::Bands (QObject * parent) : QAbstractTableModel {parent} { diff --git a/models/Bands.hpp b/models/Bands.hpp index ed625f2f1..170d4c756 100644 --- a/models/Bands.hpp +++ b/models/Bands.hpp @@ -29,6 +29,8 @@ class Bands final : public QAbstractTableModel { + Q_OBJECT + public: using Frequency = Radio::Frequency; diff --git a/models/CabrilloLog.cpp b/models/CabrilloLog.cpp index 1fee9b148..dfba3d439 100644 --- a/models/CabrilloLog.cpp +++ b/models/CabrilloLog.cpp @@ -12,6 +12,7 @@ #include #include "Configuration.hpp" #include "Bands.hpp" +#include "logbook/AD1CCty.hpp" #include "qt_db_helpers.hpp" #include "pimpl_impl.hpp" @@ -19,42 +20,109 @@ class CabrilloLog::impl final : public QSqlTableModel { public: - impl (Configuration const *); + impl (CabrilloLog *, Configuration const *); + + int columnCount (QModelIndex const& /*index */) const override + { + return QSqlTableModel::columnCount () + 1; + } + + Qt::ItemFlags flags (QModelIndex const& index) const override + { + auto flags = QSqlTableModel::flags (index); + if (index.isValid () && index.column () == columnCount (index) - 1) + { + flags = Qt::ItemIsEnabled; + } + return flags; + } + + QVariant data (QModelIndex const& model_index, int role) const override + { + QVariant value; + if (model_index.isValid () && model_index.column () == columnCount (model_index) - 1) + { // derive band column + if (Qt::DisplayRole == role) + { + value = configuration_->bands ()->find (QSqlTableModel::data (index (model_index.row (), fieldIndex ("frequency"))).toULongLong ()); + } + } + else + { + value = QSqlTableModel::data (model_index, role); + if (model_index.column () == fieldIndex ("frequency") && Qt::DisplayRole == role) + { + value = Radio::frequency_MHz_string (value.value (), 3); // kHz precision + } + else if (model_index.column () == fieldIndex ("when") + && (Qt::DisplayRole == role || Qt::EditRole == role)) + { // adjust date/time to Qt format + auto t = QDateTime::fromMSecsSinceEpoch (value.toULongLong () * 1000ull, Qt::UTC); + if (Qt::DisplayRole == role) + { + QLocale locale; + return locale.toString (t, locale.dateFormat (QLocale::ShortFormat) + " hh:mm:ss"); + } + value = t; + } + } + return value; + } QString cabrillo_frequency_string (Radio::Frequency frequency) const; + void create_table (); + CabrilloLog * self_; Configuration const * configuration_; QSqlQuery mutable dupe_query_; QSqlQuery mutable export_query_; + bool adding_row_; }; -CabrilloLog::impl::impl (Configuration const * configuration) - : QSqlTableModel {} +CabrilloLog::impl::impl (CabrilloLog * self, Configuration const * configuration) + : self_ {self} , configuration_ {configuration} + , adding_row_ {false} { - if (!database ().tables ().contains ("cabrillo_log")) + if (!database ().tables ().contains ("cabrillo_log_v2")) { - QSqlQuery query; - SQL_error_check (query, static_cast (&QSqlQuery::exec), - "CREATE TABLE cabrillo_log (" - " id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," - " frequency INTEGER NOT NULL," - " \"when\" DATETIME NOT NULL," - " call VARCHAR(20) NOT NULL," - " exchange_sent VARCHAR(32) NOT NULL," - " exchange_rcvd VARCHAR(32) NOT NULL," - " band VARCHAR(6) NOT NULL" - ")"); + create_table (); } + setEditStrategy (QSqlTableModel::OnFieldChange); + setTable ("cabrillo_log_v2"); + setHeaderData (fieldIndex ("frequency"), Qt::Horizontal, tr ("Freq(MHz)")); + setHeaderData (fieldIndex ("mode"), Qt::Horizontal, tr ("Mode")); + setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)")); + setHeaderData (fieldIndex ("call"), Qt::Horizontal, tr ("Call")); + setHeaderData (fieldIndex ("exchange_sent"), Qt::Horizontal, tr ("Sent")); + setHeaderData (fieldIndex ("exchange_rcvd"), Qt::Horizontal, tr ("Rcvd")); + setHeaderData (columnCount (QModelIndex {}) - 1, Qt::Horizontal, tr ("Band")); + + // This descending order by time is important, it makes the view + // place the latest row at the top, without this the model/view + // interactions are both sluggish and unhelpful. + setSort (fieldIndex ("when"), Qt::DescendingOrder); + + connect (this, &CabrilloLog::impl::modelReset, self_, &CabrilloLog::data_changed); + connect (this, &CabrilloLog::impl::dataChanged, [this] (QModelIndex const& tl, QModelIndex const& br) { + if (!adding_row_ && !(tl == br)) // ignore single cell changes + // as a another change for the + // whole row will follow + { + Q_EMIT self_->data_changed (); + } + }); + + SQL_error_check (*this, &QSqlTableModel::select); + SQL_error_check (dupe_query_, &QSqlQuery::prepare, "SELECT " - " COUNT(*) " + " frequency " " FROM " - " cabrillo_log " + " cabrillo_log_v2 " " WHERE " - " call = :call " - " AND band = :band"); + " call = :call "); SQL_error_check (export_query_, &QSqlQuery::prepare, "SELECT " @@ -64,32 +132,31 @@ CabrilloLog::impl::impl (Configuration const * configuration) " , call" " , exchange_rcvd" " FROM " - " cabrillo_log " + " cabrillo_log_v2 " " ORDER BY " " \"when\""); - - setEditStrategy (QSqlTableModel::OnFieldChange); - setTable ("cabrillo_log"); - setHeaderData (fieldIndex ("frequency"), Qt::Horizontal, tr ("Freq(kHz)")); - setHeaderData (fieldIndex ("when"), Qt::Horizontal, tr ("Date & Time(UTC)")); - setHeaderData (fieldIndex ("call"), Qt::Horizontal, tr ("Call")); - setHeaderData (fieldIndex ("exchange_sent"), Qt::Horizontal, tr ("Sent")); - setHeaderData (fieldIndex ("exchange_rcvd"), Qt::Horizontal, tr ("Rcvd")); - setHeaderData (fieldIndex ("band"), Qt::Horizontal, tr ("Band")); +} - // This descending order by time is important, it makes the view - // place the latest row at the top, without this the model/view - // interactions are both sluggish and unhelpful. - setSort (fieldIndex ("when"), Qt::DescendingOrder); - - SQL_error_check (*this, &QSqlTableModel::select); +void CabrilloLog::impl::create_table () +{ + QSqlQuery query; + SQL_error_check (query, static_cast (&QSqlQuery::exec), + "CREATE TABLE cabrillo_log_v2 (" + " id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + " frequency INTEGER NOT NULL," + " mode VARCHAR(6) NOT NULL," + " \"when\" DATETIME NOT NULL," + " call VARCHAR(20) NOT NULL," + " exchange_sent VARCHAR(32) NOT NULL," + " exchange_rcvd VARCHAR(32) NOT NULL" + ")"); } // frequency here is in kHz QString CabrilloLog::impl::cabrillo_frequency_string (Radio::Frequency frequency) const { QString result; - auto band = configuration_->bands ()->find (frequency * 1000ull); + auto band = configuration_->bands ()->find (frequency); if ("1mm" == band) result = "LIGHT"; else if ("2mm" == band) result = "241G"; else if ("2.5mm" == band) result = "134G"; @@ -107,12 +174,15 @@ QString CabrilloLog::impl::cabrillo_frequency_string (Radio::Frequency frequency else if ("2m" == band) result = "144"; else if ("4m" == band) result = "70"; else if ("6m" == band) result = "50"; - else result = QString::number (frequency); + else result = QString::number (frequency / 1000ull); return result; } -CabrilloLog::CabrilloLog (Configuration const * configuration) - : m_ {configuration} +#include "moc_CabrilloLog.cpp" + +CabrilloLog::CabrilloLog (Configuration const * configuration, QObject * parent) + : QObject {parent} + , m_ {this, configuration} { Q_ASSERT (configuration); } @@ -141,11 +211,12 @@ namespace } } -bool CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString const& call +bool CabrilloLog::add_QSO (Frequency frequency, QString const& mode, QDateTime const& when, QString const& call , QString const& exchange_sent, QString const& exchange_received) { auto record = m_->record (); - record.setValue ("frequency", frequency / 1000ull); // kHz + record.setValue ("frequency", frequency); + record.setValue ("mode", mode); if (!when.isNull ()) { record.setValue ("when", when.toMSecsSinceEpoch () / 1000ull); @@ -157,15 +228,16 @@ bool CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString c set_value_maybe_null (record, "call", call); set_value_maybe_null (record, "exchange_sent", exchange_sent); set_value_maybe_null (record, "exchange_rcvd", exchange_received); - set_value_maybe_null (record, "band", m_->configuration_->bands ()->find (frequency)); if (m_->isDirty ()) { m_->revert (); // discard any uncommitted changes } m_->setEditStrategy (QSqlTableModel::OnManualSubmit); ConditionalTransaction transaction {*m_}; + m_->adding_row_ = true; auto ok = m_->insertRecord (-1, record); transaction.submit (); + m_->adding_row_ = false; m_->setEditStrategy (QSqlTableModel::OnFieldChange); return ok; } @@ -173,10 +245,18 @@ bool CabrilloLog::add_QSO (Frequency frequency, QDateTime const& when, QString c bool CabrilloLog::dupe (Frequency frequency, QString const& call) const { m_->dupe_query_.bindValue (":call", call); - m_->dupe_query_.bindValue (":band", m_->configuration_->bands ()->find (frequency)); SQL_error_check (m_->dupe_query_, static_cast (&QSqlQuery::exec)); - m_->dupe_query_.next (); - return m_->dupe_query_.value (0).toInt (); + auto record = m_->dupe_query_.record (); + auto frequency_index = record.indexOf ("frequency"); + while (m_->dupe_query_.next ()) + { + if (m_->configuration_->bands ()->find (m_->dupe_query_.value (frequency_index).toULongLong ()) + == m_->configuration_->bands ()->find (frequency)) + { + return true; + } + } + return false; } void CabrilloLog::reset () @@ -191,6 +271,7 @@ void CabrilloLog::reset () transaction.submit (); m_->select (); // to refresh views m_->setEditStrategy (QSqlTableModel::OnFieldChange); + Q_EMIT data_changed (); } } @@ -199,6 +280,7 @@ void CabrilloLog::export_qsos (QTextStream& stream) const SQL_error_check (m_->export_query_, static_cast (&QSqlQuery::exec)); auto record = m_->export_query_.record (); auto frequency_index = record.indexOf ("frequency"); + // auto mode_index = record.indexOf ("mode"); auto when_index = record.indexOf ("when"); auto call_index = record.indexOf ("call"); auto sent_index = record.indexOf ("exchange_sent"); @@ -215,3 +297,17 @@ void CabrilloLog::export_qsos (QTextStream& stream) const .arg (m_->export_query_.value (rcvd_index).toString (), -13); } } + +auto CabrilloLog::unique_DXCC_entities (AD1CCty const * countries) const -> worked_set +{ + QSqlQuery q {"SELECT DISTINCT BAND, CALL FROM cabrillo_log_v2"}; + auto band_index = q.record ().indexOf ("band"); + auto call_index = q.record ().indexOf ("call"); + worked_set entities; + while (q.next ()) + { + entities << worked_item {q.value (band_index).toString () + , countries->lookup (q.value (call_index).toString ()).primary_prefix}; + } + return entities; +} diff --git a/models/CabrilloLog.hpp b/models/CabrilloLog.hpp index 43b9e8f94..97d8f0d88 100644 --- a/models/CabrilloLog.hpp +++ b/models/CabrilloLog.hpp @@ -1,33 +1,43 @@ #ifndef CABRILLO_LOG_HPP_ #define CABRILLO_LOG_HPP_ -#include +#include +#include +#include +#include #include "Radio.hpp" #include "pimpl_h.hpp" class Configuration; class QDateTime; -class QString; class QSqlTableModel; class QTextStream; +class AD1CCty; class CabrilloLog final - : private boost::noncopyable + : public QObject { + Q_OBJECT + public: using Frequency = Radio::Frequency; + using worked_item = QPair; + using worked_set = QSet; - explicit CabrilloLog (Configuration const *); + explicit CabrilloLog (Configuration const *, QObject * parent = nullptr); ~CabrilloLog (); // returns false if insert fails - bool add_QSO (Frequency, QDateTime const&, QString const& call + bool add_QSO (Frequency, QString const& mode, QDateTime const&, QString const& call , QString const& report_sent, QString const& report_received); bool dupe (Frequency, QString const& call) const; QSqlTableModel * model (); void reset (); void export_qsos (QTextStream&) const; + worked_set unique_DXCC_entities (AD1CCty const *) const; + + Q_SIGNAL void data_changed () const; private: class impl; diff --git a/models/FoxLog.cpp b/models/FoxLog.cpp index 773a5308f..954090bd6 100644 --- a/models/FoxLog.cpp +++ b/models/FoxLog.cpp @@ -18,14 +18,35 @@ class FoxLog::impl final : public QSqlTableModel { + Q_OBJECT + public: impl (Configuration const * configuration); + QVariant data (QModelIndex const& index, int role) const + { + auto value = QSqlTableModel::data (index, role); + if (index.column () == fieldIndex ("when") + && (Qt::DisplayRole == role || Qt::EditRole == role)) + { + auto t = QDateTime::fromMSecsSinceEpoch (value.toULongLong () * 1000ull, Qt::UTC); + if (Qt::DisplayRole == role) + { + QLocale locale; + return locale.toString (t, locale.dateFormat (QLocale::ShortFormat) + " hh:mm:ss"); + } + value = t; + } + return value; + } + Configuration const * configuration_; QSqlQuery mutable dupe_query_; QSqlQuery mutable export_query_; }; +#include "FoxLog.moc" + FoxLog::impl::impl (Configuration const * configuration) : configuration_ {configuration} { diff --git a/models/FrequencyList.cpp b/models/FrequencyList.cpp index d080f76cf..c0170a499 100644 --- a/models/FrequencyList.cpp +++ b/models/FrequencyList.cpp @@ -57,51 +57,206 @@ namespace {1838000, Modes::JT65, IARURegions::ALL}, // squeezed allocations {1839000, Modes::JT9, IARURegions::ALL}, {1840000, Modes::FT8, IARURegions::ALL}, - + + // Band plans (all USB dial unless stated otherwise) + // + // R1: 3570 - 3580 DM NB(<200Hz) + // 3580 - 3600 DM NB(<500Hz) with 3590 - 3600 ACDS + // + // 3577.75 OLIVIA, Contestia, etc. + // 3580 PSK31 + // 3583.25 OLIVIA, Contestia, etc. + // + // R2: 3570 - 3580 DM NB(<200Hz) + // 3580 - 3600 DM NB(<500Hz) with 3590 - 3600 ACDS + // + // 3577.75 OLIVIA, Contestia, etc. + // 3580 PSK31 + // 3583.25 OLIVIA, Contestia, etc. + // 3590 RTTY DX + // 3596 W1AW DM QST + // + // R3: 3535 - 3580 DM NB(<2000Hz) + // + // 3520 - 3575 DM NB(<2000Hz) JA 3535 - 3575 shared with all modes + // + // 3522 OLIVIA, Contestia, etc. + // 3535 JA LSB EMCOMM + // 3580 PSK31 + // 3600 LSB EMCOMM + // {3570000, Modes::JT65, IARURegions::ALL}, // JA compatible {3572000, Modes::JT9, IARURegions::ALL}, - {3573000, Modes::FT8, IARURegions::ALL}, // above as below JT65 - // is out of DM allocation - {3568600, Modes::WSPR, IARURegions::ALL}, // needs guard marker - // and lock out - + {3573000, Modes::FT8, IARURegions::ALL}, // above as below JT65 is out of DM allocation + {3568600, Modes::WSPR, IARURegions::ALL}, // needs guard marker and lock out + {3575000, Modes::FT4, IARURegions::ALL}, // provisional + {3568000, Modes::FT4, IARURegions::R3}, // provisional + + // Band plans (all USB dial unless stated otherwise) + // + // R1: 7040 - 7050 DM NB(<500Hz) with 7047 - 7050 ACDS + // 7050 - 7060 DM WB(<2700Hz) with 7050 - 7053 ACDS + // + // 7040 PSK31 + // 7043.25 OLIVIA, Contestia, etc. (main QRQ) + // 7070 PSK31 + // 7073.25 OLIVIA, Contestia, etc. (main QRQ) + // 7090 LSB QRP CoA + // + // R2: 7040 - 7050 DM NB(<500Hz) with 7047 - 7050 ACDS + // 7050 - 7053 DM WB(<2700Hz) ACDS shared with all modes + // + // 7040 RTTY DX + // 7043.25 OLIVIA, Contestia, etc. (main QRQ) + // 7070 PSK31 (also LSB EMCOMM) + // 7073.25 OLIVIA, Contestia, etc. (main QRQ) + // 7080 - 7125 RTTY/Data + // 7090 LSB QRP CoA + // + // R3: 7030 - 7060 DM NB(<2000Hz) with 7040 - 7060 NB DX all shared with phone + // + // 7030 - 7100 DM WB(<3000Hz) JA 7045 - 7100 shared with all modes + // + // 7026.25 OLIVIA, Contestia, etc. (main QRQ) + // 7035 PSK31 + // 7050 JA LSB EMCOMM + // 7090 LSB QRP CoA + // 7110 LSB EMCOMM + // {7038600, Modes::WSPR, IARURegions::ALL}, {7074000, Modes::FT8, IARURegions::ALL}, {7076000, Modes::JT65, IARURegions::ALL}, - {7078000, Modes::FT4, IARURegions::ALL}, {7078000, Modes::JT9, IARURegions::ALL}, + {7047500, Modes::FT4, IARURegions::ALL}, // provisional - moved + // up 500Hz to clear + // W1AW code practice QRG + // Band plans (all USB dial unless stated otherwise) + // + // R1: 10130 - 10150 DM NB(<500Hz) with 10120 - 10140 shared with phone in southern Africa + // + // 10139.25 OLIVIA, Contestia, etc. + // 10142 PSK31 + // 10142.25 OLIVIA, Contestia, etc. + // 10143.25 OLIVIA, Contestia, etc. (main QRQ) + // + // R2: 10130 - 10140 DM NB(<500Hz) shared with ACDS + // 10140 - 10150 DM WB(<2700Hz) + // + // 10130 - 10140 RTTY + // 10139.25 OLIVIA, Contestia, etc. + // 10140 - 10150 Packet + // 10142 PSK31 + // 10142.25 OLIVIA, Contestia, etc. + // 10143.25 OLIVIA, Contestia, etc. (main QRQ) + // + // R3: 10130 - 10150 DM NB(<2000Hz) + // + // 10139.25 OLIVIA, Contestia, etc. + // 10142 PSK31 + // 10142.25 OLIVIA, Contestia, etc. + // 10143.25 OLIVIA, Contestia, etc. (main QRQ) + // {10136000, Modes::FT8, IARURegions::ALL}, {10138000, Modes::JT65, IARURegions::ALL}, {10138700, Modes::WSPR, IARURegions::ALL}, {10140000, Modes::JT9, IARURegions::ALL}, - + {10140000, Modes::FT4, IARURegions::ALL}, // provisional + + // Band plans (all USB dial unless stated otherwise) + // + // R1: 14070 - 14099 DM NB(<500Hz) with 14089 - 14099 ACDS + // 14101 - 14112 DM NB(<2700Hz) ACDS + // + // 14070 PSK31 + // 14074.4 OLIVIA, Contestia, etc. + // 14075.4 OLIVIA, Contestia, etc. (main QRG) + // 14078.4 OLIVIA, Contestia, etc. + // 14100 NCDXF beacons + // 14105.5 OLIVIA 1000 + // 14106.5 OLIVIA 1000 (main QRG) + // + // R2: 14070 - 14099 DM NB(<500Hz) with 14089 - 14099 ACDS + // 14101 - 14112 DM NB(<2700Hz) ACDS + // + // 14070 - 14095 RTTY + // 14070 PSK31 + // 14074.4 OLIVIA, Contestia, etc. + // 14075.4 OLIVIA, Contestia, etc. (main QRG) + // 14078.4 OLIVIA, Contestia, etc. + // 14095 - 14099.5 Packet + // 14100 NCDXF beacons + // 14100.5 - 14112 Packet + // 14105.5 OLIVIA 1000 + // 14106.5 OLIVIA 1000 (main QRG) + // + // R3: 14070 - 14112 DM NB(<2000Hz) with ±500Hz IBP guard band at 14100 + // + // 14070 PSK31 + // 14074.4 OLIVIA, Contestia, etc. + // 14075.4 OLIVIA, Contestia, etc. (main QRG) + // 14078.4 OLIVIA, Contestia, etc. + // 14100 NCDXF beacons + // 14105.5 OLIVIA 1000 + // 14106.5 OLIVIA 1000 (main QRG) + // {14095600, Modes::WSPR, IARURegions::ALL}, {14074000, Modes::FT8, IARURegions::ALL}, {14076000, Modes::JT65, IARURegions::ALL}, - {14078000, Modes::FT4, IARURegions::ALL}, {14078000, Modes::JT9, IARURegions::ALL}, + {14080000, Modes::FT4, IARURegions::ALL}, // provisional + // Band plans (all USB dial unless stated otherwise) + // + // R1: 18095 - 18109 DM NB(<500Hz) with 18105 - 18109 ACDS + // 18111 - 18120 DM NB(<2700Hz) ACDS + // + // 18100 PSK31 + // 18103.4 OLIVIA, Contestia, etc. (main QRG) + // 18104.4 OLIVIA, Contestia, etc. + // 18110 NCDXF beacons + // + // R2: 18095 - 18109 DM NB(<500Hz) with 18105 - 18109 ACDS + // 18111 - 18120 DM NB(<2700Hz) ACDS + // + // 18100 - 18105 RTTY + // 18100 PSK31 + // 18103.4 OLIVIA, Contestia, etc. (main QRG) + // 18104.4 OLIVIA, Contestia, etc. + // 18105 - 18110 Packet + // 18110 NCDXF beacons + // + // R3: 18095 - 18120 DM NB(<2000Hz) with ±500Hz IBP guard band at 18110 + // + // 18100 PSK31 + // 18103.4 OLIVIA, Contestia, etc. (main QRG) + // 18104.4 OLIVIA, Contestia, etc. + // 18110 NCDXF beacons + // {18100000, Modes::FT8, IARURegions::ALL}, {18102000, Modes::JT65, IARURegions::ALL}, {18104000, Modes::JT9, IARURegions::ALL}, + {18104000, Modes::FT4, IARURegions::ALL}, // provisional {18104600, Modes::WSPR, IARURegions::ALL}, {21074000, Modes::FT8, IARURegions::ALL}, {21076000, Modes::JT65, IARURegions::ALL}, {21078000, Modes::JT9, IARURegions::ALL}, {21094600, Modes::WSPR, IARURegions::ALL}, - + {21140000, Modes::FT4, IARURegions::ALL}, + {24915000, Modes::FT8, IARURegions::ALL}, {24917000, Modes::JT65, IARURegions::ALL}, {24919000, Modes::JT9, IARURegions::ALL}, + {24919000, Modes::FT4, IARURegions::ALL}, // provisional {24924600, Modes::WSPR, IARURegions::ALL}, {28074000, Modes::FT8, IARURegions::ALL}, {28076000, Modes::JT65, IARURegions::ALL}, {28078000, Modes::JT9, IARURegions::ALL}, {28124600, Modes::WSPR, IARURegions::ALL}, - + {28180000, Modes::FT4, IARURegions::ALL}, + {50200000, Modes::Echo, IARURegions::ALL}, {50276000, Modes::JT65, IARURegions::R2}, {50276000, Modes::JT65, IARURegions::R3}, @@ -113,6 +268,7 @@ namespace {50310000, Modes::JT65, IARURegions::ALL}, {50312000, Modes::JT9, IARURegions::ALL}, {50313000, Modes::FT8, IARURegions::ALL}, + {50318000, Modes::FT4, IARURegions::ALL}, // provisional {50323000, Modes::FT8, IARURegions::ALL}, {70100000, Modes::FT8, IARURegions::R1}, @@ -123,6 +279,7 @@ namespace {144120000, Modes::JT65, IARURegions::ALL}, {144120000, Modes::Echo, IARURegions::ALL}, + {144170000, Modes::FT4, IARURegions::ALL}, {144174000, Modes::FT8, IARURegions::ALL}, {144360000, Modes::MSK144, IARURegions::R1}, {144150000, Modes::MSK144, IARURegions::R2}, diff --git a/models/IARURegions.cpp b/models/IARURegions.cpp index 25450ab47..dcdc94d43 100644 --- a/models/IARURegions.cpp +++ b/models/IARURegions.cpp @@ -7,8 +7,6 @@ #include #include -#include "moc_IARURegions.cpp" - namespace { // human readable strings for each Region enumeration value @@ -22,6 +20,8 @@ namespace std::size_t constexpr region_names_size = sizeof (region_names) / sizeof (region_names[0]); } +#include "moc_IARURegions.cpp" + IARURegions::IARURegions (QObject * parent) : QAbstractListModel {parent} { diff --git a/models/IARURegions.hpp b/models/IARURegions.hpp index d849d97b7..498846d34 100644 --- a/models/IARURegions.hpp +++ b/models/IARURegions.hpp @@ -29,6 +29,7 @@ class IARURegions final : public QAbstractListModel { Q_OBJECT + public: // // This enumeration contains the supported regions, to complement diff --git a/models/StationList.cpp b/models/StationList.cpp index eeeb4d607..202cac0e7 100644 --- a/models/StationList.cpp +++ b/models/StationList.cpp @@ -52,6 +52,8 @@ QDataStream& operator >> (QDataStream& is, StationList::Station& station) class StationList::impl final : public QAbstractTableModel { + Q_OBJECT + public: impl (Bands const * bands, Stations stations, QObject * parent) : QAbstractTableModel {parent} @@ -97,6 +99,9 @@ public: Stations stations_; }; +#include "StationList.moc" +#include "moc_StationList.cpp" + StationList::StationList (Bands const * bands, QObject * parent) : StationList {bands, {}, parent} { diff --git a/models/StationList.hpp b/models/StationList.hpp index 25bf428fc..3b0955c18 100644 --- a/models/StationList.hpp +++ b/models/StationList.hpp @@ -40,6 +40,8 @@ class Bands; class StationList final : public QSortFilterProxyModel { + Q_OBJECT + public: using Frequency = Radio::Frequency; using FrequencyDelta = Radio::FrequencyDelta; diff --git a/models/models.pri b/models/models.pri index e0c69e81e..5b3d038bb 100644 --- a/models/models.pri +++ b/models/models.pri @@ -5,7 +5,8 @@ SOURCES += \ models/Modes.cpp \ models/IARURegions.cpp \ models/FoxLog.cpp \ - models/CabrilloLog.cpp + models/CabrilloLog.cpp \ + models/DecodeHighlightingModel.cpp HEADERS += \ models/Bands.hpp \ @@ -15,4 +16,5 @@ HEADERS += \ models/IARURegions.hpp \ models/FoxLog.hpp \ models/CabrilloLog.hpp \ - models/FontOverrideModel.hpp + models/FontOverrideModel.hpp \ + models/DecodeHighlightingModel.hpp diff --git a/qt_db_helpers.hpp b/qt_db_helpers.hpp index 49a082f72..dcf9d0333 100644 --- a/qt_db_helpers.hpp +++ b/qt_db_helpers.hpp @@ -6,6 +6,7 @@ #include #include #include +#include "boost/core/noncopyable.hpp" template void SQL_error_check (T&& object, Func func, Args&&... args) diff --git a/robots/go b/robots/go new file mode 100755 index 000000000..f7bf846fc --- /dev/null +++ b/robots/go @@ -0,0 +1,2 @@ +curl https://pskreporter.info/cgi-bin/robot.pl > robo.dat +robo | sort -nr -k2 -k1 diff --git a/robots/robo.f90 b/robots/robo.f90 new file mode 100644 index 000000000..1f748378c --- /dev/null +++ b/robots/robo.f90 @@ -0,0 +1,48 @@ +program robo + +! Examine spots from PSK Reporter for past week to identify probable robots + +! In a bash shell, from command line: +! $ curl https://pskreporter.info/cgi-bin/robot.pl > robo.dat +! $ robo | sort -nr -k2 + + parameter (NCHARS=20000) + parameter (NMAX=100) + + character*1 c + character*20000 blob + character*12 callsign(0:NMAX) + integer*1 ic1 + + open(10,file='/tmp/robo.dat',status='old',access='stream') + callsign=' ' + + do ichar=1,NCHARS + read(10,end=10) ic1 + ic=ic1 + if(ic.lt.0) ic=ic+256 + c=char(ic) + blob(ichar:ichar)=c + enddo +10 continue + + do icall=1,NMAX + i1=index(blob,'":{"median_minutes":')-1 + do i=i1,i1-10,-1 + if(i1.lt.1) go to 20 + if(blob(i:i).eq.'"') exit + enddo + i0=i+1 + callsign(icall)=blob(i0:i1) + i2=index(blob,',')-1 + read(blob(i1+21:i2),*) median_minutes + i3=index(blob,'median_hours')+14 + i4=index(blob,'}')-1 + read(blob(i3:i4),*) median_hours + write(*,3001) median_minutes,median_hours,trim(callsign(icall)) +3001 format(2i5,2x,a) + blob=blob(i4+3:) + enddo + +20 continue +end program robo diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 6be6a6df2..271d2d3c4 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -1,5 +1,5 @@ set (SAMPLE_FILES - FT4/190106_000112.wav + FT4/000000_000002.wav FT8/181201_180245.wav ISCAT/ISCAT-A/VK7MO_110401_235515.wav ISCAT/ISCAT-B/K0AWU_100714_115000.wav diff --git a/samples/FT4/000000_000002.wav b/samples/FT4/000000_000002.wav new file mode 100644 index 000000000..e5cdc8804 Binary files /dev/null and b/samples/FT4/000000_000002.wav differ diff --git a/samples/FT4/190106_000112.wav b/samples/FT4/190106_000112.wav deleted file mode 100644 index 2c6e0a9d4..000000000 Binary files a/samples/FT4/190106_000112.wav and /dev/null differ diff --git a/shortcuts.txt b/shortcuts.txt index e50278d0f..93c75585b 100644 --- a/shortcuts.txt +++ b/shortcuts.txt @@ -8,19 +8,21 @@ F4 Clear DX Call, DX Grid, Tx messages 1-4 (Alt: transmit Tx4) Alt+F4 Exit program F5 Display special mouse commands (Alt: transmit Tx5) - F6 Open next file in directory + F6 Open next file in directory (Alt: toggle "Call 1st") Shift+F6 Decode all remaining files in directrory F7 Display Message Averaging window F11 Move Rx frequency down 1 Hz Ctrl+F11 Move identical Rx and Tx frequencies down 1 Hz - Shift+F11 Move Tx frequency down 60 Hz + Shift+F11 Move Tx frequency down 60 Hz (FT8) or 90 Hz (FT4) Ctrl+Shift+F11 Move dial frequency down 2000 Hz F12 Move Rx frequency up 1 Hz Ctrl+F12 Move identical Rx and Tx frequencies up 1 Hz - Shift+F12 Move Tx frequency up 60 Hz + Shift+F12 Move Tx frequency up 60 Hz (FT8) or 90 Hz (FT4) Ctrl+Shift+F12 Move dial frequency up 2000 Hz Alt+1-6 Set now transmission to this number on Tab 1 Ctl+1-6 Set next transmission to this number on Tab 1 + Alt+B Toggle "Best S+P" status + Alt+C Toggle "Call 1st" checkbox Alt+D Decode again at QSO frequency Shift+D Full decode (both windows) Ctrl+E Turn on TX even/1st @@ -33,6 +35,7 @@ Alt+M Monitor Alt+N Enable Tx Ctrl+O Open a .wav file + Alt+O Change operator Alt+Q Log QSO Alt+S Stop monitoring Alt+T Tune diff --git a/soundout.cpp b/soundout.cpp index b21675b3a..0264ad91e 100644 --- a/soundout.cpp +++ b/soundout.cpp @@ -9,11 +9,14 @@ #include "moc_soundout.cpp" +/* #if defined (WIN32) # define MS_BUFFERED 1000u #else # define MS_BUFFERED 2000u #endif +*/ +# define MS_BUFFERED 200u bool SoundOutput::audioError () const { diff --git a/translations/wsjtx_en_GB.ts b/translations/wsjtx_en_GB.ts new file mode 100644 index 000000000..2e0570962 --- /dev/null +++ b/translations/wsjtx_en_GB.ts @@ -0,0 +1,6007 @@ + + + + + AbstractLogWindow + + + &Delete ... + + + + + AbstractLogWindow::impl + + + Confirm Delete + + + + + Are you sure you want to delete the %n selected QSO(s) from the log + + + + + + + + Astro + + + + Doppler tracking + + + + + <html><head/><body><p>One station does all Doppler shift correction, their QSO partner receives and transmits on the sked frequency.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p></body></html> + + + + + Full Doppler to DX Grid + + + + + <html><head/><body><p>Transmit takes place on sked frequency and receive frequency is corrected for own echoes. </p><p>This mode can be used for calling CQ, or when using Echo mode.</p></body></html> + + + + + Own Echo + + + + + <html><head/><body><p>Both stations correct for Doppler shift such that they would be heard on the moon at the sked frequency.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p><p>Use this option also for Echo mode.</p></body></html> + + + + + Constant frequency on Moon + + + + + <html><head/><body><p>DX station announces their TX Freq, which is entered as the Sked Freq. Correction applied to RX and TX so you appear on the DX's station's own echo Freq.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p></body></html> + + + + + On DX Echo + + + + + <html><head/><body><p>Tune radio manually and select this mode to put your echo on the same frequency.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p></body></html> + + + + + Call DX + + + + + <html><head/><body><p>No Doppler shift correction is applied. This may be used when the QSO partner does full Doppler correction to your grid square.</p></body></html> + + + + + None + + + + + Sked frequency + + + + + + 0 + + + + + Rx: + + + + + Tx: + + + + + <html><head/><body><p>Press and hold the CTRL key to adjust the sked frequency manually with the rig's VFO dial or enter frequency directly into the band entry field on the main window.</p></body></html> + + + + + Astro Data + + + + + Astronomical Data + + + + + Doppler Tracking Error + + + + + Split operating is required for Doppler tracking + + + + + Go to "Menu->File->Settings->Radio" to enable split operation + + + + + Bands + + + Band name + + + + + Lower frequency limit + + + + + Upper frequency limit + + + + + Band + + + + + Lower Limit + + + + + Upper Limit + + + + + CAboutDlg + + + About WSJT-X + + + + + OK + + + + + CPlotter + + + &Set Rx && Tx Offset + + + + + CabrilloLog + + + Freq(MHz) + + + + + Mode + + + + + Date & Time(UTC) + + + + + Call + + + + + Sent + + + + + Rcvd + + + + + Band + + + + + CabrilloLogWindow + + + Contest Log + + + + + <html><head/><body><p>Right-click here for available actions.</p></body></html> + + + + + Right-click here for available actions. + + + + + CallsignDialog + + + Callsign + + + + + ColorHighlighting + + + + + + + + + + + + + + + + + + K1ABC + + + + + CQ in message + + + + + My Call in message + + + + + Transmitted message + + + + + New DXCC + + + + + New Grid + + + + + New DXCC on Band + + + + + New Call + + + + + New Grid on Band + + + + + New Call on Band + + + + + Uploads to LotW + + + + + New Continent + + + + + New Continent on Band + + + + + New CQ Zone + + + + + New CQ Zone on Band + + + + + New ITU Zone + + + + + New ITU Zone on Band + + + + + Configuration::impl + + + + + &Delete + + + + + + &Insert ... + + + + + Failed to create save directory + + + + + path: "%1% + + + + + Failed to create samples directory + + + + + path: "%1" + + + + + &Load ... + + + + + &Save as ... + + + + + &Merge ... + + + + + &Reset + + + + + Serial Port: + + + + + Serial port used for CAT control + + + + + Network Server: + + + + + Optional hostname and port of network service. +Leave blank for a sensible default on this machine. +Formats: + hostname:port + IPv4-address:port + [IPv6-address]:port + + + + + USB Device: + + + + + Optional device identification. +Leave blank for a sensible default for the rig. +Format: + [VID[:PID[:VENDOR[:PRODUCT]]]] + + + + + Invalid audio input device + + + + + Invalid audio out device + + + + + Invalid PTT method + + + + + Invalid PTT port + + + + + + Invalid Contest Exchange + + + + + You must input a valid ARRL Field Day exchange + + + + + You must input a valid ARRL RTTY Roundup exchange + + + + + Reset Decode Highlighting + + + + + Reset all decode highlighting and priorities to default values + + + + + WSJT-X Decoded Text Font Chooser + + + + + Load Working Frequencies + + + + + + + Frequency files (*.qrg);;All files (*.*) + + + + + Replace Working Frequencies + + + + + Are you sure you want to discard your current working frequencies and replace them with the loaded ones? + + + + + Merge Working Frequencies + + + + + + + Not a valid frequencies file + + + + + Incorrect file magic + + + + + Version is too new + + + + + Contents corrupt + + + + + Save Working Frequencies + + + + + Only Save Selected Working Frequencies + + + + + Are you sure you want to save only the working frequencies that are currently selected? Click No to save all. + + + + + Reset Working Frequencies + + + + + Are you sure you want to discard your current working frequencies and replace them with default ones? + + + + + Save Directory + + + + + AzEl Directory + + + + + Rig control error + + + + + Failed to open connection to rig + + + + + Rig failure + + + + + DXLabSuiteCommanderTransceiver + + + Failed to connect to DX Lab Suite Commander + + + + + + DX Lab Suite Commander didn't respond correctly reading frequency: + + + + + DX Lab Suite Commander sent an unrecognised TX state: + + + + + DX Lab Suite Commander didn't respond correctly polling TX status: + + + + + DX Lab Suite Commander rig did not respond to PTT: + + + + + DX Lab Suite Commander didn't respond correctly polling frequency: + + + + + DX Lab Suite Commander didn't respond correctly polling TX frequency: + + + + + DX Lab Suite Commander sent an unrecognised split state: + + + + + DX Lab Suite Commander didn't respond correctly polling split status: + + + + + DX Lab Suite Commander sent an unrecognised mode: " + + + + + DX Lab Suite Commander didn't respond correctly polling mode: + + + + + DX Lab Suite Commander send command failed + + + + + + DX Lab Suite Commander failed to send command "%1": %2 + + + + + + DX Lab Suite Commander send command "%1" read reply failed: %2 + + + + + + DX Lab Suite Commander retries exhausted sending command "%1" + + + + + DX Lab Suite Commander sent an unrecognized frequency + + + + + DecodeHighlightingListView + + + &Foreground color ... + + + + + Choose %1 Foreground Color + + + + + &Unset foreground color + + + + + &Background color ... + + + + + Choose %1 Background Color + + + + + U&nset background color + + + + + &Reset this item to defaults + + + + + DecodeHighlightingModel + + + Highlight Type + + + + + Designer + + + &Delete + + + + + &Insert ... + + + + + Insert &after ... + + + + + Import Palette + + + + + + Palettes (*.pal) + + + + + Export Palette + + + + + Dialog + + + Gray time: + + + + + Directory + + + + URL Error + + + + + + Invalid URL: +"%1" + + + + + + + + + + + JSON Error + + + + + Contents file syntax error %1 at character offset %2 + + + + + Contents file top level must be a JSON array + + + + + File System Error + + + + + Failed to open "%1" +Error: %2 - %3 + + + + + Contents entries must be a JSON array + + + + + Contents entries must have a valid type + + + + + Contents entries must have a valid name + + + + + Contents entries must be JSON objects + + + + + Contents directories must be relative and within "%1" + + + + + Network Error + + + + + Authentication required + + + + + DisplayText + + + &Erase + + + + + EchoGraph + + + + Echo Graph + + + + + <html><head/><body><p>Compression factor for frequency scale</p></body></html> + + + + + Bins/Pixel + + + + + Gain + + + + + <html><head/><body><p>Echo spectrum gain</p></body></html> + + + + + Zero + + + + + <html><head/><body><p>Echo spectrum zero</p></body></html> + + + + + <html><head/><body><p>Smoothing of echo spectrum</p></body></html> + + + + + Smooth + + + + + <html><head/><body><p>Number of echo transmissions averaged</p></body></html> + + + + + N: 0 + + + + + <html><head/><body><p>Click to cycle through a sequence of colors and line widths.</p></body></html> + + + + + Colors + Colours + + + + EmulateSplitTransceiver + + + Emulated split mode requires rig to be in simplex mode + + + + + EqualizationToolsDialog::impl + + + Phase + + + + + + Freq (Hz) + + + + + Phase (Π) + + + + + Delay (ms) + + + + + Measured + + + + + Proposed + + + + + Current + + + + + Group Delay + + + + + Amplitude + + + + + Relative Power (dB) + + + + + Reference + + + + + Phase ... + + + + + Refresh + + + + + Discard Measured + + + + + ExistingNameDialog + + + Configuration to Clone From + + + + + &Source Configuration Name: + + + + + ExportCabrillo + + + Dialog + + + + + Location: + + + + + SNJ + + + + + Contest: + + + + + ARRL-RTTY + + + + + Callsign: + + + + + Category-Operator: + + + + + SINGLE-OP + + + + + Category-Transmitter: + + + + + ONE + + + + + Category-Power: + + + + + LOW + + + + + Category-Assisted: + + + + + NON-ASSISTED + + + + + Category-Band: + + + + + ALL + + + + + Claimed-Score: + + + + + Operators: + + + + + Club: + + + + + Name: + + + + + + Address: + + + + + Save Log File + + + + + Cabrillo Log (*.cbr) + + + + + Cannot open "%1" for writing: %2 + + + + + Export Cabrillo File Error + + + + + FastGraph + + + + Fast Graph + + + + + Waterfall gain + + + + + Waterfall zero + + + + + Spectrum zero + + + + + <html><head/><body><p>Set reasonable levels for gain and zero sliders.</p></body></html> + + + + + Auto Level + + + + + FoxLog::impl + + + Date & Time(UTC) + + + + + Call + + + + + Grid + + + + + Sent + + + + + Rcvd + + + + + Band + + + + + FoxLogWindow + + + Fox Log + + + + + <html><head/><body><p>Right-click here for available actions.</p></body></html> + + + + + Callers: + + + + + + + N + + + + + In progress: + + + + + Rate: + + + + + &Export ADIF ... + + + + + Export ADIF Log File + + + + + ADIF Log (*.adi) + + + + + Export ADIF File Error + + + + + Cannot open "%1" for writing: %2 + + + + + &Reset ... + + + + + Confirm Reset + + + + + Are you sure you want to erase file FoxQSO.txt and start a new Fox log? + + + + + FrequencyDialog + + + Add Frequency + + + + + IARU &Region: + + + + + &Mode: + + + + + &Frequency (MHz): + + + + + FrequencyList_v2 + + + + IARU Region + + + + + + Mode + + + + + + Frequency + + + + + + Frequency (MHz) + + + + + HRDTransceiver + + + + Failed to connect to Ham Radio Deluxe + + + + + + Failed to open file "%1": %2. + + + + + + Ham Radio Deluxe: no rig found + + + + + Ham Radio Deluxe: rig doesn't support mode + + + + + Ham Radio Deluxe: sent an unrecognised mode + + + + + Ham Radio Deluxe: item not found in %1 dropdown list + + + + + Ham Radio Deluxe: button not available + + + + + Ham Radio Deluxe didn't respond as expected + + + + + Ham Radio Deluxe: rig has disappeared or changed + + + + + Ham Radio Deluxe send command "%1" failed %2 + + + + + + + Ham Radio Deluxe: failed to write command "%1" + + + + + Ham Radio Deluxe sent an invalid reply to our command "%1" + + + + + Ham Radio Deluxe failed to reply to command "%1" %2 + + + + + + Ham Radio Deluxe retries exhausted sending command "%1" + + + + + Ham Radio Deluxe didn't respond to command "%1" as expected + + + + + HamlibTransceiver + + + + Hamlib initialisation error + + + + + Hamlib settings file error: %1 at character offset %2 + + + + + Hamlib settings file error: top level must be a JSON object + + + + + Hamlib settings file error: config must be a JSON object + + + + + Unsupported CAT type + + + + + Hamlib error: %1 while %2 + + + + + opening connection to rig + + + + + getting current frequency + + + + + getting current mode + + + + + + exchanging VFOs + + + + + + getting other VFO frequency + + + + + getting other VFO mode + + + + + setting current VFO + + + + + getting frequency + + + + + getting mode + + + + + + getting current VFO + + + + + + + + getting current VFO frequency + + + + + + + + + + setting frequency + + + + + + + + getting current VFO mode + + + + + + + + + setting current VFO mode + + + + + + setting/unsetting split mode + + + + + + setting split mode + + + + + setting split TX frequency and mode + + + + + setting split TX frequency + + + + + getting split TX VFO mode + + + + + setting split TX VFO mode + + + + + getting PTT state + + + + + setting PTT on + + + + + setting PTT off + + + + + setting a configuration item + + + + + getting a configuration item + + + + + HelpTextWindow + + + Help file error + + + + + Cannot open "%1" for reading + + + + + Error: %1 + + + + + IARURegions + + + + IARU Region + + + + + LogQSO + + + Click OK to confirm the following QSO: + + + + + Call + + + + + Start + + + + + + dd/MM/yyyy HH:mm:ss + + + + + End + + + + + Mode + + + + + Band + + + + + Rpt Sent + + + + + Rpt Rcvd + + + + + Grid + + + + + Name + + + + + Tx power + + + + + + Retain + + + + + Comments + + + + + Operator + + + + + Exch sent + + + + + Rcvd + + + + + + Invalid QSO Data + + + + + Check exchange sent and received + + + + + Check all fields + + + + + Log file error + + + + + Cannot open "%1" for append + + + + + Error: %1 + + + + + LotWUsers::impl + + + Network Error - SSL/TLS support not installed, cannot fetch: +'%1' + + + + + Network Error - Too many redirects: +'%1' + + + + + Network Error: +%1 + + + + + File System Error - Cannot commit changes to: +"%1" + + + + + File System Error - Cannot open file: +"%1" +Error(%2): %3 + + + + + File System Error - Cannot write to file: +"%1" +Error(%2): %3 + + + + + MainWindow + + + WSJT-X by K1JT + + + + + Band Activity + + + + + + UTC dB DT Freq Dr + + + + + Rx Frequency + + + + + CQ only + + + + + Enter this QSO in log + + + + + Log &QSO + + + + + Stop monitoring + + + + + &Stop + + + + + Toggle monitoring On/Off + + + + + &Monitor + + + + + <html><head/><body><p>Erase right window. Double-click to erase both windows.</p></body></html> + + + + + Erase right window. Double-click to erase both windows. + + + + + &Erase + + + + + <html><head/><body><p>Clear the accumulating message average.</p></body></html> + + + + + Clear the accumulating message average. + + + + + Clear Avg + + + + + <html><head/><body><p>Decode most recent Rx period at QSO Frequency</p></body></html> + + + + + Decode most recent Rx period at QSO Frequency + + + + + &Decode + + + + + <html><head/><body><p>Toggle Auto-Tx On/Off</p></body></html> + + + + + Toggle Auto-Tx On/Off + + + + + E&nable Tx + + + + + Stop transmitting immediately + + + + + &Halt Tx + + + + + <html><head/><body><p>Toggle a pure Tx tone On/Off</p></body></html> + + + + + Toggle a pure Tx tone On/Off + + + + + &Tune + + + + + Menus + + + + + USB dial frequency + + + + + 14.078 000 + + + + + <html><head/><body><p>30dB recommended when only noise present<br/>Green when good<br/>Red when clipping may occur<br/>Yellow when too low</p></body></html> + + + + + Rx Signal + + + + + 30dB recommended when only noise present +Green when good +Red when clipping may occur +Yellow when too low + + + + + DX Call + + + + + DX Grid + + + + + Callsign of station to be worked + + + + + Search for callsign in database + + + + + &Lookup + + + + + Locator of station to be worked + + + + + Az: 251 16553 km + + + + + Add callsign and locator to database + + + + + Add + + + + + Pwr + + + + + <html><head/><body><p>If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode.</p></body></html> + + + + + If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode. + + + + + ? + + + + + Adjust Tx audio level + + + + + <html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html> + + + + + Frequncy entry + + + + + Select operating band or enter frequency in MHz or enter kHz increment followed by k. + + + + + <html><head/><body><p align="center"> 2015 Jun 17 </p><p align="center"> 01:23:45 </p></body></html> + + + + + <html><head/><body><p>Check to keep Tx frequency fixed when double-clicking on decoded text.</p></body></html> + + + + + Check to keep Tx frequency fixed when double-clicking on decoded text. + + + + + Hold Tx Freq + + + + + Audio Rx frequency + + + + + + + Hz + + + + + Rx + + + + + Set Tx frequency to Rx Frequency + + + + + â–² + + + + + Frequency tolerance (Hz) + + + + + F Tol + + + + + Set Rx frequency to Tx Frequency + + + + + â–¼ + + + + + <html><head/><body><p>Synchronizing threshold. Lower numbers accept weaker sync signals.</p></body></html> + + + + + Synchronizing threshold. Lower numbers accept weaker sync signals. + + + + + Sync + + + + + <html><head/><body><p>Check to use short-format messages.</p></body></html> + + + + + Check to use short-format messages. + + + + + Sh + + + + + <html><head/><body><p>Check to enable JT9 fast modes</p></body></html> + + + + + Check to enable JT9 fast modes + + + + + + Fast + + + + + <html><head/><body><p>Check to enable automatic sequencing of Tx messages based on received messages.</p></body></html> + + + + + Check to enable automatic sequencing of Tx messages based on received messages. + + + + + Auto Seq + + + + + <html><head/><body><p>Check to call the first decoded responder to my CQ.</p></body></html> + + + + + Check to call the first decoded responder to my CQ. + + + + + Call 1st + + + + + Check to generate "@1250 (SEND MSGS)" in Tx6. + + + + + Tx6 + + + + + <html><head/><body><p>Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences.</p></body></html> + + + + + Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences. + + + + + Tx even/1st + + + + + <html><head/><body><p>Frequency to call CQ on in kHz above the current MHz</p></body></html> + + + + + Frequency to call CQ on in kHz above the current MHz + + + + + Tx CQ + + + + + <html><head/><body><p>Check this to call CQ on the &quot;Tx CQ&quot; frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on.</p><p>Not available to nonstandard callsign holders.</p></body></html> + + + + + Check this to call CQ on the "Tx CQ" frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on. +Not available to nonstandard callsign holders. + + + + + Rx All Freqs + + + + + <html><head/><body><p>Submode determines tone spacing; A is narrowest.</p></body></html> + + + + + Submode determines tone spacing; A is narrowest. + + + + + Submode + + + + + Fox + + + + + <html><head/><body><p>Check to monitor Sh messages.</p></body></html> + + + + + Check to monitor Sh messages. + + + + + SWL + + + + + Best S+P + + + + + <html><head/><body><p>Check this to start recording calibration data.<br/>While measuring calibration correction is disabled.<br/>When not checked you can view the calibration results.</p></body></html> + + + + + Check this to start recording calibration data. +While measuring calibration correction is disabled. +When not checked you can view the calibration results. + + + + + Measure + + + + + <html><head/><body><p>Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB).</p></body></html> + + + + + Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB). + + + + + Report + + + + + <html><head/><body><p>Tx/Rx or Frequency calibration sequence length</p></body></html> + + + + + Tx/Rx or Frequency calibration sequence length + + + + + s + + + + + T/R + + + + + Toggle Tx mode + + + + + Tx JT9 @ + + + + + Audio Tx frequency + + + + + + Tx + + + + + Tx# + + + + + <html><head/><body><p>Double-click on another caller to queue that call for your next QSO.</p></body></html> + + + + + Double-click on another caller to queue that call for your next QSO. + + + + + Next Call + + + + + 1 + + + + + + + Send this message in next Tx interval + + + + + Ctrl+2 + + + + + <html><head/><body><p>Send this message in next Tx interval</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> + + + + + Send this message in next Tx interval +Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) + + + + + Ctrl+1 + + + + + + + + Switch to this Tx message NOW + + + + + Tx &2 + + + + + Alt+2 + + + + + <html><head/><body><p>Switch to this Tx message NOW</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> + + + + + Switch to this Tx message NOW +Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) + + + + + Tx &1 + + + + + Alt+1 + + + + + Ctrl+6 + + + + + <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to reset to the standard 73 message</p></body></html> + + + + + Send this message in next Tx interval +Double-click to reset to the standard 73 message + + + + + Ctrl+5 + + + + + Ctrl+3 + + + + + Tx &3 + + + + + Alt+3 + + + + + <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> + + + + + Send this message in next Tx interval +Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders) +RR73 messages should only be used when you are reasonably confident that no message repetitions will be required + + + + + Ctrl+4 + + + + + <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> + + + + + Switch to this Tx message NOW +Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders) +RR73 messages should only be used when you are reasonably confident that no message repetitions will be required + + + + + Tx &4 + + + + + Alt+4 + + + + + <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to reset to the standard 73 message</p></body></html> + + + + + Switch to this Tx message NOW +Double-click to reset to the standard 73 message + + + + + Tx &5 + + + + + Alt+5 + + + + + Now + + + + + Generate standard messages for minimal QSO + + + + + Generate Std Msgs + + + + + Tx &6 + + + + + Alt+6 + + + + + + Enter a free text message (maximum 13 characters) +or select a predefined macro from the dropdown list. +Press ENTER to add the current text to the predefined +list. The list can be maintained in Settings (F2). + + + + + Queue up the next Tx message + + + + + Next + + + + + 2 + + + + + Calling CQ + + + + + Generate a CQ message + + + + + + + CQ + + + + + Generate message with RRR + + + + + RRR + + + + + Generate message with report + + + + + dB + + + + + Answering CQ + + + + + Generate message for replying to a CQ + + + + + + Grid + + + + + Generate message with R+report + + + + + R+dB + + + + + Generate message with 73 + + + + + 73 + + + + + Send this standard (generated) message + + + + + Gen msg + + + + + Send this free-text message (max 13 characters) + + + + + Free msg + + + + + 3 + + + + + Max dB + + + + + CQ AF + + + + + CQ AN + + + + + CQ AS + + + + + CQ EU + + + + + CQ NA + + + + + CQ OC + + + + + CQ SA + + + + + CQ 0 + + + + + CQ 1 + + + + + CQ 2 + + + + + CQ 3 + + + + + CQ 4 + + + + + CQ 5 + + + + + CQ 6 + + + + + CQ 7 + + + + + CQ 8 + + + + + CQ 9 + + + + + Reset + + + + + N List + + + + + N Slots + + + + + + Random + + + + + Call + + + + + S/N (dB) + + + + + Distance + + + + + More CQs + + + + + Percentage of 2-minute sequences devoted to transmitting. + + + + + % + + + + + Tx Pct + + + + + Band Hopping + + + + + Choose bands and times of day for band-hopping. + + + + + Schedule ... + + + + + Upload decoded messages to WSPRnet.org. + + + + + Upload spots + + + + + <html><head/><body><p>6 digit locators cause 2 different mesages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol.</p></body></html> + + + + + 6 digit locators cause 2 different mesages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol. + + + + + Prefer type 1 messages + + + + + No own call decodes + + + + + Transmit during the next 2-minute sequence. + + + + + Tx Next + + + + + Set Tx power in dBm (dB above 1 mW) as part of your WSPR message. + + + + + File + + + + + View + + + + + Decode + + + + + Save + + + + + Help + + + + + Mode + + + + + Configurations + + + + + Tools + + + + + Exit + + + + + Configuration + + + + + F2 + + + + + About WSJT-X + + + + + Waterfall + + + + + Open + + + + + Ctrl+O + + + + + Open next in directory + + + + + Decode remaining files in directory + + + + + Shift+F6 + + + + + Delete all *.wav && *.c2 files in SaveDir + + + + + None + + + + + Save all + + + + + Online User Guide + + + + + Keyboard shortcuts + + + + + Special mouse commands + + + + + JT9 + + + + + Save decoded + + + + + Normal + + + + + Deep + + + + + Monitor OFF at startup + + + + + Erase ALL.TXT + + + + + Erase wsjtx_log.adi + + + + + Convert mode to RTTY for logging + + + + + Log dB reports to Comments + + + + + Prompt me to log QSO + + + + + Blank line between decoding periods + + + + + Clear DX Call and Grid after logging + + + + + Display distance in miles + + + + + Double-click on call sets Tx Enable + + + + + + F7 + + + + + Tx disabled after sending 73 + + + + + Runaway Tx watchdog + + + + + Allow multiple instances + + + + + Tx freq locked to Rx freq + + + + + JT65 + + + + + JT9+JT65 + + + + + Tx messages to Rx Frequency window + + + + + Gray1 + + + + + Show DXCC entity and worked B4 status + + + + + Astronomical data + + + + + List of Type 1 prefixes and suffixes + + + + + Settings... + + + + + Local User Guide + + + + + Open log directory + + + + + JT4 + + + + + Message averaging + + + + + Enable averaging + + + + + Enable deep search + + + + + WSPR + + + + + Echo Graph + + + + + F8 + + + + + Echo + + + + + EME Echo mode + + + + + ISCAT + + + + + Fast Graph + + + + + F9 + + + + + &Download Samples ... + + + + + <html><head/><body><p>Download sample audio files demonstrating the various modes.</p></body></html> + + + + + MSK144 + + + + + QRA64 + + + + + Release Notes + + + + + Enable AP for DX Call + + + + + FreqCal + + + + + Measure reference spectrum + + + + + Measure phase response + + + + + Erase reference spectrum + + + + + Execute frequency calibration cycle + + + + + Equalization tools ... + + + + + WSPR-LF + + + + + Experimental LF/MF mode + + + + + FT8 + + + + + + Enable AP + + + + + Solve for calibration parameters + + + + + Copyright notice + + + + + Shift+F1 + + + + + Fox log + + + + + FT8 DXpedition Mode User Guide + + + + + Reset Cabrillo log ... + + + + + Color highlighting scheme + + + + + Contest Log + + + + + Export Cabrillo log ... + + + + + Quick-Start Guide to WSJT-X 2.0 + + + + + Contest log + + + + + Erase WSPR hashtable + + + + + FT4 + + + + + Rig Control Error + + + + + Do you want to reconfigure the radio interface? + + + + + Error Scanning ADIF Log + + + + + Scanned ADIF log, %1 worked before records created + + + + + Error Loading LotW Users Data + + + + + Error Writing WAV File + + + + + Configurations... + + + + + Error Killing jt9.exe Process + + + + + KillByName return code: %1 + + + + + Error removing "%1" + + + + + Click OK to retry + + + + + + Improper mode + + + + + + File Open Error + + + + + + + + + Cannot open "%1" for append: %2 + + + + + Error saving c2 file + + + + + Error in Sound Input + + + + + Error in Sound Output + + + + + Change Operator + + + + + New operator: + + + + + Status File Error + + + + + + Cannot open "%1" for writing: %2 + + + + + Subprocess Error + + + + + Subprocess failed with exit code %1 + + + + + + Running: %1 +%2 + + + + + Subprocess error + + + + + Reference spectrum saved + + + + + Invalid data in fmt.all at line %1 + + + + + Good Calibration Solution + + + + + <pre>%1%L2 ±%L3 ppm +%4%L5 ±%L6 Hz + +%7%L8 +%9%L10 Hz</pre> + + + + + Delete Calibration Measurements + + + + + The "fmt.all" file will be renamed as "fmt.bak" + + + + + If you make fair use of any part of WSJT-X under terms of the GNU General Public License, you must display the following copyright notice prominently in your derivative work: + +"The algorithms, source code, look-and-feel of WSJT-X and related programs, and protocol specifications for the modes FSK441, FT8, JT4, JT6M, JT9, JT65, JTMS, QRA64, ISCAT, MSK144 are Copyright (C) 2001-2019 by one or more of the following authors: Joseph Taylor, K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo, IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR; Philip Karn, KA9Q; and other members of the WSJT Development Group." + + + + + No data read from disk. Wrong file format? + + + + + Confirm Delete + + + + + Are you sure you want to delete all *.wav and *.c2 files in "%1"? + + + + + Keyboard Shortcuts + + + + + Special Mouse Commands + + + + + No more files to open. + + + + + Please choose another Tx frequency. WSJT-X will not knowingly transmit another mode in the WSPR sub-band on 30m. + + + + + WSPR Guard Band + + + + + Please choose another dial frequency. WSJT-X will not operate in Fox mode in the standard FT8 sub-bands. + + + + + Fox Mode warning + + + + + Should you switch to ARRL Field Day mode? + + + + + Should you switch to RTTY contest mode? + + + + + + + + Add to CALL3.TXT + + + + + Please enter a valid grid locator + + + + + Cannot open "%1" for read/write: %2 + + + + + %1 +is already in CALL3.TXT, do you wish to replace it? + + + + + Warning: DX Call field is empty. + + + + + Log file error + + + + + Cannot open "%1" + + + + + Error sending log to N1MM + + + + + Write returned "%1" + + + + + + + Confirm Erase + + + + + Are you sure you want to erase file ALL.TXT? + + + + + + Confirm Reset + + + + + Are you sure you want to erase your contest log? + + + + + Doing this will remove all QSO records for the current contest. They will be kept in the ADIF log file but will not be available for export in your Cabrillo log. + + + + + Cabrillo Log saved + + + + + Are you sure you want to erase file wsjtx_log.adi? + + + + + Are you sure you want to erase the WSPR hashtable? + + + + + VHF features warning + + + + + Tune digital gain + + + + + Transmit digital gain + + + + + Prefixes + + + + + Network Error + + + + + Error: %1 +UDP server %2:%3 + + + + + File Error + + + + + Phase Training Disabled + + + + + Phase Training Enabled + + + + + + Log File Error + + + + + Are you sure you want to clear the QSO queues? + + + + + MessageAveraging + + + + Message Averaging + + + + + UTC Sync DT Freq + + + + + Modes + + + + Mode + + + + + MultiSettings + + + Default + + + + + MultiSettings::impl + + + &Switch To + + + + + &Clone + + + + + Clone &Into ... + + + + + R&eset + + + + + &Rename ... + + + + + &Delete + + + + + Clone Into Configuration + + + + + Confirm overwrite of all values for configuration "%1" with values from "%2"? + + + + + Reset Configuration + + + + + Confirm reset to default values for configuration "%1"? + + + + + Delete Configuration + + + + + Confirm deletion of configuration "%1"? + + + + + NameDialog + + + New Configuration Name + + + + + Old name: + + + + + &New name: + + + + + OmniRigTransceiver + + + OmniRig: unrecognized mode + + + + + Failed to start OmniRig COM server + + + + + + OmniRig: don't know how to set rig frequency + + + + + + OmniRig: timeout waiting for update from rig + + + + + OmniRig COM/OLE error: %1 at %2: %3 (%4) + + + + + PollingTransceiver + + + Unexpected rig error + + + + + QObject + + + Invalid rig name - \ & / not allowed + + + + + User Defined + + + + + Failed to open LotW users CSV file: '%1' + + + + + OOB + + + + + Too many colours in palette. + + + + + Error reading waterfall palette file "%1:%2" too many colors. + + + + + Error reading waterfall palette file "%1:%2" invalid triplet. + + + + + Error reading waterfall palette file "%1:%2" invalid color. + + + + + Error opening waterfall palette file "%1": %2. + + + + + Error writing waterfall palette file "%1": %2. + + + + + RemoteFile + + + + + + + + File System Error + + + + + Cannot rename file: +"%1" +to: "%2" +Error(%3): %4 + + + + + Cannot delete file: +"%1" + + + + + + + Network Error + + + + + Too many redirects: %1 + + + + + Redirect not followed: %1 + + + + + Cannot commit changes to: +"%1" + + + + + Cannot open file: +"%1" +Error(%2): %3 + + + + + Cannot make path: +"%1" + + + + + Cannot write to file: +"%1" +Error(%2): %3 + + + + + SampleDownloader::impl + + + Download Samples + + + + + Input Error + + + + + Invalid URL format + + + + + SoundInput + + + An error opening the audio input device has occurred. + + + + + An error occurred during read from the audio input device. + + + + + Audio data not being fed to the audio input device fast enough. + + + + + Non-recoverable error, audio input device not usable at this time. + + + + + Requested input audio format is not valid. + + + + + Requested input audio format is not supported on device. + + + + + Failed to initialize audio sink device + + + + + Idle + + + + + Receiving + + + + + Suspended + + + + + Interrupted + + + + + Error + + + + + Stopped + + + + + SoundOutput + + + An error opening the audio output device has occurred. + + + + + An error occurred during write to the audio output device. + + + + + Audio data not being fed to the audio output device fast enough. + + + + + Non-recoverable error, audio output device not usable at this time. + + + + + Requested output audio format is not valid. + + + + + Requested output audio format is not supported on device. + + + + + Idle + + + + + Sending + + + + + Suspended + + + + + Interrupted + + + + + Error + + + + + Stopped + + + + + StationDialog + + + Add Station + + + + + &Band: + + + + + &Offset (MHz): + + + + + &Antenna: + + + + + StationList::impl + + + Band name + + + + + Frequency offset + + + + + Antenna description + + + + + Band + + + + + Offset + + + + + Antenna Description + + + + + TransceiverBase + + + Unexpected rig error + + + + + WideGraph + + + Dialog + + + + + Controls + + + + + Spectrum gain + + + + + Palette + + + + + <html><head/><body><p>Enter definition for a new color palette.</p></body></html> + + + + + Adjust... + + + + + Waterfall gain + + + + + <html><head/><body><p>Set fractional size of spectrum in this window.</p></body></html> + + + + + % + + + + + Spec + + + + + <html><head/><body><p>Flatten spectral baseline over the full displayed interval.</p></body></html> + + + + + Flatten + + + + + <html><head/><body><p>Compute and save a reference spectrum. (Not yet fully implemented.)</p></body></html> + + + + + Ref Spec + + + + + Smoothing of Linear Average spectrum + + + + + Smooth + + + + + Compression factor for frequency scale + + + + + Bins/Pixel + + + + + Select waterfall palette + + + + + <html><head/><body><p>Select data for spectral display</p></body></html> + + + + + Current + + + + + Cumulative + + + + + Linear Avg + + + + + Reference + + + + + <html><head/><body><p>Frequency at left edge of waterfall</p></body></html> + + + + + Hz + + + + + Start + + + + + <html><head/><body><p>Decode JT9 only above this frequency</p></body></html> + + + + + JT9 + + + + + JT65 + + + + + Number of FFTs averaged (controls waterfall scrolling rate) + + + + + N Avg + + + + + Waterfall zero + + + + + Spectrum zero + + + + + Wide Graph + + + + + + Read Palette + + + + + configuration_dialog + + + Settings + + + + + Genera&l + + + + + General station details and settings. + + + + + Station Details + + + + + My C&all: + + + + + Station callsign. + + + + + M&y Grid: + + + + + <html><head/><body><p>Maidenhead locator, preferably 6 characters.</p></body></html> + + + + + Check to allow grid changes from external programs + + + + + AutoGrid + + + + + IARU Region: + + + + + <html><head/><body><p>Select your IARU region.</p></body></html> + + + + + Message generation for type 2 compound callsign holders: + + + + + <html><head/><body><p>Type 2 compound callsigns are those with prefixes or suffixes not included in the allowed shortlist (See Help-&gt;Add-on prefixes and suffixes).</p><p>This option determines which generated messages should contain your full type 2 compound call sign rather than your base callsign. It only applies if you have a type 2 compound callsign.</p><p>This option controls the way the messages that are used to answer CQ calls are generated. Generated messages 6 (CQ) and 5 (73) will always contain your full callsign. The JT65 and JT9 protocols allow for some standard messages with your full call at the expense of another piece of information such as the DX call or your locator.</p><p>Choosing message 1 omits the DX callsign which may be an issue when replying to CQ calls. Choosing message 3 also omits the DX callsign and many versions of this and other software will not extract the report. Choosing neither means that your full callsign only goes in your message 5 (73) so your QSO partner may log the wrong callsign.</p><p>None of these options are perfect, message 3 is usually best but be aware your QSO partner may not log the report you send them.</p></body></html> + + + + + Full call in Tx1 + + + + + Full call in Tx3 + + + + + Full call in Tx5 only + + + + + Display + + + + + Show outgoing transmitted messages in the Rx frequency window. + + + + + &Tx messages to Rx frequency window + + + + + Show if decoded stations are new DXCC entities or worked before. + + + + + Show &DXCC, grid, and worked-before status + + + + + <html><head/><body><p>Check to have decodes for a new period start at the top of the Band Activity window and not scroll off the top when the window is full.</p><p>This is to aid selecting decodes to double-click while decoding is still in progress. Use the Band Activity vertical scroll bar to reveal decodes past the bottom of the window.</p></body></html> + + + + + Start new period decodes at top + + + + + Show principal prefix instead of country name + + + + + Set the font characteristics for the application. + + + + + Font... + + + + + Set the font characteristics for the Band Activity and Rx Frequency areas. + + + + + Decoded Text Font... + + + + + Include a separator line between periods in the band activity window. + + + + + &Blank line between decoding periods + + + + + Show distance to DX station in miles rather than kilometers. + + + + + Display dista&nce in miles + + + + + Behavior + + + + + Decode after EME delay + + + + + Tx watchdog: + + + + + <html><head/><body><p>Number of minutes before unattended transmissions are aborted</p></body></html> + + + + + Disabled + + + + + minutes + + + + + Enable VHF/UHF/Microwave features + + + + + Single decode + + + + + <html><head/><body><p>Some rigs are not able to process CAT commands while transmitting. This means that if you are operating in split mode you may have to uncheck this option.</p></body></html> + + + + + Allow Tx frequency changes while transmitting + + + + + Don't start decoding until the monitor button is clicked. + + + + + Mon&itor off at startup + + + + + <html><head/><body><p>Check this if you wish to automatically return to the last monitored frequency when monitor is enabled, leave it unchecked if you wish to have the current rig frequency maintained.</p></body></html> + + + + + Monitor returns to last used frequency + + + + + Alternate F1-F6 bindings + + + + + Turns off automatic transmissions after sending a 73 or any other free +text message. + + + + + Di&sable Tx after sending 73 + + + + + Send a CW ID after every 73 or free text message. + + + + + CW ID a&fter 73 + + + + + Periodic CW ID Inter&val: + + + + + Send a CW ID periodically every few minutes. +This might be required under your countries licence regulations. +It will not interfere with other users as it is always sent in the +quiet period when decoding is done. + + + + + Automatic transmission mode. + + + + + Doubl&e-click on call sets Tx enable + + + + + Calling CQ forces Call 1st + + + + + &Radio + + + + + Radio interface configuration settings. + + + + + Settings that control your CAT interface. + + + + + CAT Control + + + + + + Port: + + + + + Serial port used for CAT control. + + + + + Serial Port Parameters + + + + + Baud Rate: + + + + + Serial port data rate which must match the setting of your radio. + + + + + 1200 + + + + + 2400 + + + + + 4800 + + + + + 9600 + + + + + 19200 + + + + + 38400 + + + + + 57600 + + + + + 115200 + + + + + <html><head/><body><p>Number of data bits used to communicate with your radio's CAT interface (usually eight).</p></body></html> + + + + + Data Bits + + + + + D&efault + + + + + Se&ven + + + + + E&ight + + + + + <html><head/><body><p>Number of stop bits used when communicating with your radio's CAT interface</p><p>(consult you radio's manual for details).</p></body></html> + + + + + Stop Bits + + + + + + Default + + + + + On&e + + + + + T&wo + + + + + <html><head/><body><p>Flow control protocol used between this computer and your radio's CAT interface (usually &quot;None&quot; but some require &quot;Hardware&quot;).</p></body></html> + + + + + Handshake + + + + + &None + + + + + Software flow control (very rare on CAT interfaces). + + + + + XON/XOFF + + + + + Flow control using the RTS and CTS RS-232 control lines +not often used but some radios have it as an option and +a few, particularly some Kenwood rigs, require it). + + + + + &Hardware + + + + + Special control of CAT port control lines. + + + + + Force Control Lines + + + + + + High + + + + + + Low + + + + + DTR: + + + + + RTS: + + + + + How this program activates the PTT on your radio + + + + + PTT Method + + + + + <html><head/><body><p>No PTT activation, instead the radio's automatic VOX is used to key the transmitter.</p><p>Use this if you have no radio interface hardware.</p></body></html> + + + + + VO&X + + + + + <html><head/><body><p>Use the RS-232 DTR control line to toggle your radio's PTT, requires hardware to inteface the line.</p><p>Some commercial interface units also use this method.</p><p>The DTR control line of the CAT serial port may be used for this or a DTR control line on a different serial port may be used.</p></body></html> + + + + + &DTR + + + + + Some radios support PTT via CAT commands, +use this option if your radio supports it and you have no +other hardware interface for PTT. + + + + + C&AT + + + + + <html><head/><body><p>Use the RS-232 RTS control line to toggle your radio's PTT, requires hardware to inteface the line.</p><p>Some commercial interface units also use this method.</p><p>The RTS control line of the CAT serial port may be used for this or a RTS control line on a different serial port may be used. Note that this option is not available on the CAT serial port when hardware flow control is used.</p></body></html> + + + + + R&TS + + + + + <html><head/><body><p>Select the RS-232 serial port utilised for PTT control, this option is available when DTR or RTS is selected above as a transmit method.</p><p>This port can be the same one as the one used for CAT control.</p><p>For some interface types the special value CAT may be chosen, this is used for non-serial CAT interfaces that can control serial port control lines remotely (OmniRig for example).</p></body></html> + + + + + Modulation mode selected on radio. + + + + + Mode + + + + + <html><head/><body><p>USB is usually the correct modulation mode,</p><p>unless the radio has a special data or packet mode setting</p><p>for AFSK operation.</p></body></html> + + + + + US&B + + + + + Don't allow the program to set the radio mode +(not recommended but use if the wrong mode +or bandwidth is selected). + + + + + + None + + + + + If this is availabe then it is usually the correct mode for this program. + + + + + Data/P&kt + + + + + Some radios can select the audio input using a CAT command, +this setting allows you to select which audio input will be used +(if it is available then generally the Rear/Data option is best). + + + + + Transmit Audio Source + + + + + Rear&/Data + + + + + &Front/Mic + + + + + Rig: + + + + + Poll Interval: + + + + + <html><head/><body><p>Interval to poll rig for status. Longer intervals will mean that changes to the rig will take longer to be detected.</p></body></html> + + + + + s + + + + + <html><head/><body><p>Attempt to connect to the radio with these settings.</p><p>The button will turn green if the connection is successful or red if there is a problem.</p></body></html> + + + + + Test CAT + + + + + Attempt to activate the transmitter. +Click again to deactivate. Normally no power should be +output since there is no audio being generated at this time. +Check that any Tx indication on your radio and/or your +radio interface behave as expected. + + + + + Test PTT + + + + + Split Operation + + + + + Fake It + + + + + Rig + + + + + A&udio + + + + + Audio interface settings + + + + + Souncard + + + + + Soundcard + + + + + Select the audio CODEC to use for transmitting. +If this is your default device for system sounds then +ensure that all system sounds are disabled otherwise +you will broadcast any systems sounds generated during +transmitting periods. + + + + + Select the audio CODEC to use for receiving. + + + + + &Input: + + + + + Select the channel to use for receiving. + + + + + + Mono + + + + + + Left + + + + + + Right + + + + + + Both + + + + + Select the audio channel used for transmission. +Unless you have multiple radios connected on different +channels; then you will usually want to select mono or +both here. + + + + + Ou&tput: + + + + + + Save Directory + + + + + Loc&ation: + + + + + Path to which .WAV files are saved. + + + + + + TextLabel + + + + + Click to select a different save directory for .WAV files. + + + + + S&elect + + + + + + AzEl Directory + + + + + Location: + + + + + Select + + + + + Power Memory By Band + + + + + Remember power settings by band + + + + + Enable power memory during transmit + + + + + Transmit + + + + + Enable power memory during tuning + + + + + Tune + + + + + Tx &Macros + + + + + Canned free text messages setup + + + + + &Add + + + + + &Delete + + + + + Drag and drop items to rearrange order +Right click for item specific actions +Click, SHIFT+Click and, CRTL+Click to select items + + + + + Reportin&g + + + + + Reporting and logging settings + + + + + Logging + + + + + The program will pop up a partially completed Log QSO dialog when you send a 73 or free text message. + + + + + Promp&t me to log QSO + + + + + Op Call: + + + + + Some logging programs will not accept the type of reports +saved by this program. +Check this option to save the sent and received reports in the +comments field. + + + + + d&B reports to comments + + + + + Check this option to force the clearing of the DX Call +and DX Grid fields when a 73 or free text message is sent. + + + + + Clear &DX call and grid after logging + + + + + <html><head/><body><p>Some logging programs will not accept WSJT-X mode names.</p></body></html> + + + + + Con&vert mode to RTTY + + + + + <html><head/><body><p>The callsign of the operator, if different from the station callsign.</p></body></html> + + + + + <html><head/><body><p>Check to have QSOs logged automatically, when complete.</p></body></html> + + + + + Log automatically (contesting only) + + + + + Network Services + + + + + The program can send your station details and all +decoded signals as spots to the http://pskreporter.info web site. +This is used for reverse beacon analysis which is very useful +for assessing propagation and system performance. + + + + + Enable &PSK Reporter Spotting + + + + + UDP Server + + + + + UDP Server: + + + + + <html><head/><body><p>Optional hostname of network service to receive decodes.</p><p>Formats:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">hostname</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 multicast group address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 multicast group address</li></ul><p>Clearing this field will disable the broadcasting of UDP status updates.</p></body></html> + + + + + UDP Server port number: + + + + + <html><head/><body><p>Enter the service port number of the UDP server that WSJT-X should send updates to. If this is zero no updates will be broadcast.</p></body></html> + + + + + <html><head/><body><p>With this enabled WSJT-X will accept certain requests back from a UDP server that receives decode messages.</p></body></html> + + + + + Accept UDP requests + + + + + <html><head/><body><p>Indicate acceptance of an incoming UDP request. The effect of this option varies depending on the operating system and window manager, its intent is to notify the acceptance of an incoming UDP request even if this application is minimized or hidden.</p></body></html> + + + + + Notify on accepted UDP request + + + + + <html><head/><body><p>Restore the window from minimized if an UDP request is accepted.</p></body></html> + + + + + Accepted UDP request restores window + + + + + Secondary UDP Server (deprecated) + + + + + <html><head/><body><p>When checked, WSJT-X will broadcast a logged contact in ADIF format to the configured hostname and port. </p></body></html> + + + + + Enable logged contact ADIF broadcast + + + + + Server name or IP address: + + + + + <html><head/><body><p>Optional host name of N1MM Logger+ program to receive ADIF UDP broadcasts. This is usually 'localhost' or ip address 127.0.0.1</p><p>Formats:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">hostname</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 multicast group address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 multicast group address</li></ul><p>Clearing this field will disable broadcasting of ADIF information via UDP.</p></body></html> + + + + + Server port number: + + + + + <html><head/><body><p>Enter the port number that WSJT-X should use for UDP broadcasts of ADIF log information. For N1MM Logger+, this value should be 2333. If this is zero, no updates will be broadcast.</p></body></html> + + + + + Frequencies + + + + + Default frequencies and band specific station details setup + + + + + <html><head/><body><p>See &quot;Frequency Calibration&quot; in the WSJT-X User Guide for details of how to determine these parameters for your radio.</p></body></html> + + + + + Frequency Calibration + + + + + Slope: + + + + + ppm + + + + + Intercept: + + + + + Hz + + + + + Working Frequencies + + + + + <html><head/><body><p>Right click to maintain the working frequencies list.</p></body></html> + + + + + Station Information + + + + + Items may be edited. +Right click for insert and delete options. + + + + + Colors + Colours + + + + Decode Highlightling + + + + + <html><head/><body><p>Enable or disable using the check boxes and right-click an item to change or unset the foreground color, background color, or reset the item to default values. Drag and drop the items to change their priority, higher in the list is higher in priority.</p><p>Note that each foreground or background color may be either set or unset, unset means that it is not allocated for that item's type and lower priority items may apply.</p></body></html> + + + + + <html><head/><body><p>Push to reset all highlight items above to default values and priorities.</p></body></html> + + + + + Reset Highlighting + + + + + <html><head/><body><p>Check to indicate new DXCC entities, grid squares, and callsigns per mode.</p></body></html> + + + + + Highlight by Mode + + + + + <html><head/><body><p>Click to scan the wsjtx_log.adi ADIF file again for worked before information</p></body></html> + + + + + Rescan ADIF Log + + + + + Include extra WAE entities + + + + + <html><head/><body><p>Controls for Logbook of the World user lookup.</p></body></html> + + + + + Logbook of the World User Validation + + + + + Users CSV file URL: + + + + + <html><head/><body><p>URL of the ARRL LotW user's last upload dates and times data file which is used to highlight decodes from stations that are known to upload their log file to LotW.</p></body></html> + + + + + https://lotw.arrl.org/lotw-user-activity.csv + + + + + <html><head/><body><p>Push this button to fetch the latest LotW user's upload date and time data file.</p></body></html> + + + + + Fetch Now + + + + + Age of last upload less than: + + + + + <html><head/><body><p>Adjust this spin box to set the age threshold of LotW user's last upload date that is accepted as a current LotW user.</p></body></html> + + + + + days + + + + + Advanced + + + + + <html><head/><body><p>User-selectable parameters for JT65 VHF/UHF/Microwave decoding.</p></body></html> + + + + + JT65 VHF/UHF/Microwave decoding parameters + + + + + Random erasure patterns: + + + + + <html><head/><body><p>Maximum number of erasure patterns for stochastic soft-decision Reed Solomon decoder is 10^(n/2).</p></body></html> + + + + + Aggressive decoding level: + + + + + <html><head/><body><p>Higher levels will increase the probability of decoding, but will also increase probability of a false decode.</p></body></html> + + + + + Two-pass decoding + + + + + Special operating activity: Generation of FT4, FT8, and MSK144 messages + + + + + <html><head/><body><p>FT8 DXpedition mode: Hound operator calling the DX.</p></body></html> + + + + + Hound + + + + + <html><head/><body><p>North American VHF/UHF/Microwave contests and others in which a 4-character grid locator is the required exchange.</p></body></html> + + + + + NA VHF Contest + + + + + <html><head/><body><p>FT8 DXpedition mode: Fox (DXpedition) operator.</p></body></html> + + + + + Fox + + + + + <html><head/><body><p>European VHF+ contests requiring a signal report, serial number, and 6-character locator.</p></body></html> + + + + + EU VHF Contest + + + + + + <html><head/><body><p>ARRL RTTY Roundup and similar contests. Exchange is US state, Canadian province, or &quot;DX&quot;.</p></body></html> + + + + + RTTY Roundup messages + + + + + RTTY RU Exch: + + + + + NJ + + + + + + <html><head/><body><p>ARRL Field Day exchange: number of transmitters, Class, and ARRL/RAC section or &quot;DX&quot;.</p></body></html> + + + + + ARRL Field Day + + + + + FD Exch: + + + + + 6A SNJ + + + + + Miscellaneous + + + + + Degrade S/N of .wav file: + + + + + + For offline sensitivity tests + + + + + dB + + + + + Receiver bandwidth: + + + + + Hz + + + + + Tx delay: + + + + + Minimum delay between assertion of PTT and start of Tx audio. + + + + + s + + + + + Tone spacing + + + + + <html><head/><body><p>Generate Tx audio with twice the normal tone spacing. Intended for special LF/MF transmitters that use a divide-by-2 before generating RF.</p></body></html> + + + + + x 2 + + + + + <html><head/><body><p>Generate Tx audio with four times the normal tone spacing. Intended for special LF/MF transmitters that use a divide-by-4 before generating RF.</p></body></html> + + + + + x 4 + + + + + Waterfall spectra + + + + + Low sidelobes + + + + + Most sensitive + + + + + <html><head/><body><p>Discard (Cancel) or apply (OK) configuration changes including</p><p>resetting the radio interface and applying any soundcard changes</p></body></html> + + + + + main + + + + Fatal error + + + + + + Unexpected fatal error + + + + + Where <rig-name> is for multi-instance support. + + + + + rig-name + + + + + Where <configuration> is an existing one. + + + + + configuration + + + + + Writable files in test location. Use with caution, for testing only. + + + + + Command line error + + + + + Command line help + + + + + Application version + + + + + Another instance may be running + + + + + try to remove stale lock file? + + + + + Failed to create a temporary directory + + + + + + Path: "%1" + + + + + Failed to create a usable temporary directory + + + + + Another application may be locking the directory + + + + + Failed to create data directory + + + + + path: "%1" + + + + + Shared memory error + + + + + Unable to create shared memory segment + + + + + wf_palette_design_dialog + + + Palette Designer + + + + + <html><head/><body><p>Double click a color to edit it.</p><p>Right click to insert or delete colors.</p><p>Colors at the top represent weak signals</p><p>and colors at the bottom represent strong</p><p>signals. You can have up to 256 colors.</p></body></html> + + + + diff --git a/translations/wsjtx_pt_PT.ts b/translations/wsjtx_pt_PT.ts new file mode 100644 index 000000000..6167f5d8d --- /dev/null +++ b/translations/wsjtx_pt_PT.ts @@ -0,0 +1,6007 @@ + + + + + AbstractLogWindow + + + &Delete ... + + + + + AbstractLogWindow::impl + + + Confirm Delete + + + + + Are you sure you want to delete the %n selected QSO(s) from the log + + + + + + + + Astro + + + + Doppler tracking + + + + + <html><head/><body><p>One station does all Doppler shift correction, their QSO partner receives and transmits on the sked frequency.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p></body></html> + + + + + Full Doppler to DX Grid + + + + + <html><head/><body><p>Transmit takes place on sked frequency and receive frequency is corrected for own echoes. </p><p>This mode can be used for calling CQ, or when using Echo mode.</p></body></html> + + + + + Own Echo + + + + + <html><head/><body><p>Both stations correct for Doppler shift such that they would be heard on the moon at the sked frequency.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p><p>Use this option also for Echo mode.</p></body></html> + + + + + Constant frequency on Moon + + + + + <html><head/><body><p>DX station announces their TX Freq, which is entered as the Sked Freq. Correction applied to RX and TX so you appear on the DX's station's own echo Freq.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p></body></html> + + + + + On DX Echo + + + + + <html><head/><body><p>Tune radio manually and select this mode to put your echo on the same frequency.</p><p>If the rig does not accept CAT QSY commands while transmitting a single correction is applied for the whole transmit period.</p></body></html> + + + + + Call DX + + + + + <html><head/><body><p>No Doppler shift correction is applied. This may be used when the QSO partner does full Doppler correction to your grid square.</p></body></html> + + + + + None + + + + + Sked frequency + + + + + + 0 + + + + + Rx: + + + + + Tx: + + + + + <html><head/><body><p>Press and hold the CTRL key to adjust the sked frequency manually with the rig's VFO dial or enter frequency directly into the band entry field on the main window.</p></body></html> + + + + + Astro Data + + + + + Astronomical Data + + + + + Doppler Tracking Error + + + + + Split operating is required for Doppler tracking + + + + + Go to "Menu->File->Settings->Radio" to enable split operation + + + + + Bands + + + Band name + + + + + Lower frequency limit + + + + + Upper frequency limit + + + + + Band + + + + + Lower Limit + + + + + Upper Limit + + + + + CAboutDlg + + + About WSJT-X + + + + + OK + + + + + CPlotter + + + &Set Rx && Tx Offset + + + + + CabrilloLog + + + Freq(MHz) + + + + + Mode + + + + + Date & Time(UTC) + + + + + Call + + + + + Sent + + + + + Rcvd + + + + + Band + + + + + CabrilloLogWindow + + + Contest Log + + + + + <html><head/><body><p>Right-click here for available actions.</p></body></html> + + + + + Right-click here for available actions. + + + + + CallsignDialog + + + Callsign + + + + + ColorHighlighting + + + + + + + + + + + + + + + + + + K1ABC + + + + + CQ in message + + + + + My Call in message + + + + + Transmitted message + + + + + New DXCC + + + + + New Grid + + + + + New DXCC on Band + + + + + New Call + + + + + New Grid on Band + + + + + New Call on Band + + + + + Uploads to LotW + + + + + New Continent + + + + + New Continent on Band + + + + + New CQ Zone + + + + + New CQ Zone on Band + + + + + New ITU Zone + + + + + New ITU Zone on Band + + + + + Configuration::impl + + + + + &Delete + + + + + + &Insert ... + + + + + Failed to create save directory + + + + + path: "%1% + + + + + Failed to create samples directory + + + + + path: "%1" + + + + + &Load ... + + + + + &Save as ... + + + + + &Merge ... + + + + + &Reset + + + + + Serial Port: + + + + + Serial port used for CAT control + + + + + Network Server: + + + + + Optional hostname and port of network service. +Leave blank for a sensible default on this machine. +Formats: + hostname:port + IPv4-address:port + [IPv6-address]:port + + + + + USB Device: + + + + + Optional device identification. +Leave blank for a sensible default for the rig. +Format: + [VID[:PID[:VENDOR[:PRODUCT]]]] + + + + + Invalid audio input device + + + + + Invalid audio out device + + + + + Invalid PTT method + + + + + Invalid PTT port + + + + + + Invalid Contest Exchange + + + + + You must input a valid ARRL Field Day exchange + + + + + You must input a valid ARRL RTTY Roundup exchange + + + + + Reset Decode Highlighting + + + + + Reset all decode highlighting and priorities to default values + + + + + WSJT-X Decoded Text Font Chooser + + + + + Load Working Frequencies + + + + + + + Frequency files (*.qrg);;All files (*.*) + + + + + Replace Working Frequencies + + + + + Are you sure you want to discard your current working frequencies and replace them with the loaded ones? + + + + + Merge Working Frequencies + + + + + + + Not a valid frequencies file + + + + + Incorrect file magic + + + + + Version is too new + + + + + Contents corrupt + + + + + Save Working Frequencies + + + + + Only Save Selected Working Frequencies + + + + + Are you sure you want to save only the working frequencies that are currently selected? Click No to save all. + + + + + Reset Working Frequencies + + + + + Are you sure you want to discard your current working frequencies and replace them with default ones? + + + + + Save Directory + + + + + AzEl Directory + + + + + Rig control error + + + + + Failed to open connection to rig + + + + + Rig failure + + + + + DXLabSuiteCommanderTransceiver + + + Failed to connect to DX Lab Suite Commander + + + + + + DX Lab Suite Commander didn't respond correctly reading frequency: + + + + + DX Lab Suite Commander sent an unrecognised TX state: + + + + + DX Lab Suite Commander didn't respond correctly polling TX status: + + + + + DX Lab Suite Commander rig did not respond to PTT: + + + + + DX Lab Suite Commander didn't respond correctly polling frequency: + + + + + DX Lab Suite Commander didn't respond correctly polling TX frequency: + + + + + DX Lab Suite Commander sent an unrecognised split state: + + + + + DX Lab Suite Commander didn't respond correctly polling split status: + + + + + DX Lab Suite Commander sent an unrecognised mode: " + + + + + DX Lab Suite Commander didn't respond correctly polling mode: + + + + + DX Lab Suite Commander send command failed + + + + + + DX Lab Suite Commander failed to send command "%1": %2 + + + + + + DX Lab Suite Commander send command "%1" read reply failed: %2 + + + + + + DX Lab Suite Commander retries exhausted sending command "%1" + + + + + DX Lab Suite Commander sent an unrecognized frequency + + + + + DecodeHighlightingListView + + + &Foreground color ... + + + + + Choose %1 Foreground Color + + + + + &Unset foreground color + + + + + &Background color ... + + + + + Choose %1 Background Color + + + + + U&nset background color + + + + + &Reset this item to defaults + + + + + DecodeHighlightingModel + + + Highlight Type + + + + + Designer + + + &Delete + + + + + &Insert ... + + + + + Insert &after ... + + + + + Import Palette + + + + + + Palettes (*.pal) + + + + + Export Palette + + + + + Dialog + + + Gray time: + + + + + Directory + + + + URL Error + + + + + + Invalid URL: +"%1" + + + + + + + + + + + JSON Error + + + + + Contents file syntax error %1 at character offset %2 + + + + + Contents file top level must be a JSON array + + + + + File System Error + + + + + Failed to open "%1" +Error: %2 - %3 + + + + + Contents entries must be a JSON array + + + + + Contents entries must have a valid type + + + + + Contents entries must have a valid name + + + + + Contents entries must be JSON objects + + + + + Contents directories must be relative and within "%1" + + + + + Network Error + + + + + Authentication required + + + + + DisplayText + + + &Erase + + + + + EchoGraph + + + + Echo Graph + + + + + <html><head/><body><p>Compression factor for frequency scale</p></body></html> + + + + + Bins/Pixel + + + + + Gain + + + + + <html><head/><body><p>Echo spectrum gain</p></body></html> + + + + + Zero + + + + + <html><head/><body><p>Echo spectrum zero</p></body></html> + + + + + <html><head/><body><p>Smoothing of echo spectrum</p></body></html> + + + + + Smooth + + + + + <html><head/><body><p>Number of echo transmissions averaged</p></body></html> + + + + + N: 0 + + + + + <html><head/><body><p>Click to cycle through a sequence of colors and line widths.</p></body></html> + + + + + Colors + Cores + + + + EmulateSplitTransceiver + + + Emulated split mode requires rig to be in simplex mode + + + + + EqualizationToolsDialog::impl + + + Phase + + + + + + Freq (Hz) + + + + + Phase (Π) + + + + + Delay (ms) + + + + + Measured + + + + + Proposed + + + + + Current + + + + + Group Delay + + + + + Amplitude + + + + + Relative Power (dB) + + + + + Reference + + + + + Phase ... + + + + + Refresh + + + + + Discard Measured + + + + + ExistingNameDialog + + + Configuration to Clone From + + + + + &Source Configuration Name: + + + + + ExportCabrillo + + + Dialog + + + + + Location: + + + + + SNJ + + + + + Contest: + + + + + ARRL-RTTY + + + + + Callsign: + + + + + Category-Operator: + + + + + SINGLE-OP + + + + + Category-Transmitter: + + + + + ONE + + + + + Category-Power: + + + + + LOW + + + + + Category-Assisted: + + + + + NON-ASSISTED + + + + + Category-Band: + + + + + ALL + + + + + Claimed-Score: + + + + + Operators: + + + + + Club: + + + + + Name: + + + + + + Address: + + + + + Save Log File + + + + + Cabrillo Log (*.cbr) + + + + + Cannot open "%1" for writing: %2 + + + + + Export Cabrillo File Error + + + + + FastGraph + + + + Fast Graph + + + + + Waterfall gain + + + + + Waterfall zero + + + + + Spectrum zero + + + + + <html><head/><body><p>Set reasonable levels for gain and zero sliders.</p></body></html> + + + + + Auto Level + + + + + FoxLog::impl + + + Date & Time(UTC) + + + + + Call + + + + + Grid + + + + + Sent + + + + + Rcvd + + + + + Band + + + + + FoxLogWindow + + + Fox Log + + + + + <html><head/><body><p>Right-click here for available actions.</p></body></html> + + + + + Callers: + + + + + + + N + + + + + In progress: + + + + + Rate: + + + + + &Export ADIF ... + + + + + Export ADIF Log File + + + + + ADIF Log (*.adi) + + + + + Export ADIF File Error + + + + + Cannot open "%1" for writing: %2 + + + + + &Reset ... + + + + + Confirm Reset + + + + + Are you sure you want to erase file FoxQSO.txt and start a new Fox log? + + + + + FrequencyDialog + + + Add Frequency + + + + + IARU &Region: + + + + + &Mode: + + + + + &Frequency (MHz): + + + + + FrequencyList_v2 + + + + IARU Region + + + + + + Mode + + + + + + Frequency + + + + + + Frequency (MHz) + + + + + HRDTransceiver + + + + Failed to connect to Ham Radio Deluxe + + + + + + Failed to open file "%1": %2. + + + + + + Ham Radio Deluxe: no rig found + + + + + Ham Radio Deluxe: rig doesn't support mode + + + + + Ham Radio Deluxe: sent an unrecognised mode + + + + + Ham Radio Deluxe: item not found in %1 dropdown list + + + + + Ham Radio Deluxe: button not available + + + + + Ham Radio Deluxe didn't respond as expected + + + + + Ham Radio Deluxe: rig has disappeared or changed + + + + + Ham Radio Deluxe send command "%1" failed %2 + + + + + + + Ham Radio Deluxe: failed to write command "%1" + + + + + Ham Radio Deluxe sent an invalid reply to our command "%1" + + + + + Ham Radio Deluxe failed to reply to command "%1" %2 + + + + + + Ham Radio Deluxe retries exhausted sending command "%1" + + + + + Ham Radio Deluxe didn't respond to command "%1" as expected + + + + + HamlibTransceiver + + + + Hamlib initialisation error + + + + + Hamlib settings file error: %1 at character offset %2 + + + + + Hamlib settings file error: top level must be a JSON object + + + + + Hamlib settings file error: config must be a JSON object + + + + + Unsupported CAT type + + + + + Hamlib error: %1 while %2 + + + + + opening connection to rig + + + + + getting current frequency + + + + + getting current mode + + + + + + exchanging VFOs + + + + + + getting other VFO frequency + + + + + getting other VFO mode + + + + + setting current VFO + + + + + getting frequency + + + + + getting mode + + + + + + getting current VFO + + + + + + + + getting current VFO frequency + + + + + + + + + + setting frequency + + + + + + + + getting current VFO mode + + + + + + + + + setting current VFO mode + + + + + + setting/unsetting split mode + + + + + + setting split mode + + + + + setting split TX frequency and mode + + + + + setting split TX frequency + + + + + getting split TX VFO mode + + + + + setting split TX VFO mode + + + + + getting PTT state + + + + + setting PTT on + + + + + setting PTT off + + + + + setting a configuration item + + + + + getting a configuration item + + + + + HelpTextWindow + + + Help file error + + + + + Cannot open "%1" for reading + + + + + Error: %1 + + + + + IARURegions + + + + IARU Region + + + + + LogQSO + + + Click OK to confirm the following QSO: + + + + + Call + + + + + Start + + + + + + dd/MM/yyyy HH:mm:ss + + + + + End + + + + + Mode + + + + + Band + + + + + Rpt Sent + + + + + Rpt Rcvd + + + + + Grid + + + + + Name + + + + + Tx power + + + + + + Retain + + + + + Comments + + + + + Operator + + + + + Exch sent + + + + + Rcvd + + + + + + Invalid QSO Data + + + + + Check exchange sent and received + + + + + Check all fields + + + + + Log file error + + + + + Cannot open "%1" for append + + + + + Error: %1 + + + + + LotWUsers::impl + + + Network Error - SSL/TLS support not installed, cannot fetch: +'%1' + + + + + Network Error - Too many redirects: +'%1' + + + + + Network Error: +%1 + + + + + File System Error - Cannot commit changes to: +"%1" + + + + + File System Error - Cannot open file: +"%1" +Error(%2): %3 + + + + + File System Error - Cannot write to file: +"%1" +Error(%2): %3 + + + + + MainWindow + + + WSJT-X by K1JT + + + + + Band Activity + + + + + + UTC dB DT Freq Dr + + + + + Rx Frequency + + + + + CQ only + + + + + Enter this QSO in log + + + + + Log &QSO + + + + + Stop monitoring + + + + + &Stop + + + + + Toggle monitoring On/Off + + + + + &Monitor + + + + + <html><head/><body><p>Erase right window. Double-click to erase both windows.</p></body></html> + + + + + Erase right window. Double-click to erase both windows. + + + + + &Erase + + + + + <html><head/><body><p>Clear the accumulating message average.</p></body></html> + + + + + Clear the accumulating message average. + + + + + Clear Avg + + + + + <html><head/><body><p>Decode most recent Rx period at QSO Frequency</p></body></html> + + + + + Decode most recent Rx period at QSO Frequency + + + + + &Decode + + + + + <html><head/><body><p>Toggle Auto-Tx On/Off</p></body></html> + + + + + Toggle Auto-Tx On/Off + + + + + E&nable Tx + + + + + Stop transmitting immediately + + + + + &Halt Tx + + + + + <html><head/><body><p>Toggle a pure Tx tone On/Off</p></body></html> + + + + + Toggle a pure Tx tone On/Off + + + + + &Tune + + + + + Menus + + + + + USB dial frequency + + + + + 14.078 000 + + + + + <html><head/><body><p>30dB recommended when only noise present<br/>Green when good<br/>Red when clipping may occur<br/>Yellow when too low</p></body></html> + + + + + Rx Signal + + + + + 30dB recommended when only noise present +Green when good +Red when clipping may occur +Yellow when too low + + + + + DX Call + + + + + DX Grid + + + + + Callsign of station to be worked + + + + + Search for callsign in database + + + + + &Lookup + + + + + Locator of station to be worked + + + + + Az: 251 16553 km + + + + + Add callsign and locator to database + + + + + Add + + + + + Pwr + + + + + <html><head/><body><p>If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode.</p></body></html> + + + + + If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode. + + + + + ? + + + + + Adjust Tx audio level + + + + + <html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html> + + + + + Frequncy entry + + + + + Select operating band or enter frequency in MHz or enter kHz increment followed by k. + + + + + <html><head/><body><p align="center"> 2015 Jun 17 </p><p align="center"> 01:23:45 </p></body></html> + + + + + <html><head/><body><p>Check to keep Tx frequency fixed when double-clicking on decoded text.</p></body></html> + + + + + Check to keep Tx frequency fixed when double-clicking on decoded text. + + + + + Hold Tx Freq + + + + + Audio Rx frequency + + + + + + + Hz + + + + + Rx + + + + + Set Tx frequency to Rx Frequency + + + + + â–² + + + + + Frequency tolerance (Hz) + + + + + F Tol + + + + + Set Rx frequency to Tx Frequency + + + + + â–¼ + + + + + <html><head/><body><p>Synchronizing threshold. Lower numbers accept weaker sync signals.</p></body></html> + + + + + Synchronizing threshold. Lower numbers accept weaker sync signals. + + + + + Sync + + + + + <html><head/><body><p>Check to use short-format messages.</p></body></html> + + + + + Check to use short-format messages. + + + + + Sh + + + + + <html><head/><body><p>Check to enable JT9 fast modes</p></body></html> + + + + + Check to enable JT9 fast modes + + + + + + Fast + + + + + <html><head/><body><p>Check to enable automatic sequencing of Tx messages based on received messages.</p></body></html> + + + + + Check to enable automatic sequencing of Tx messages based on received messages. + + + + + Auto Seq + + + + + <html><head/><body><p>Check to call the first decoded responder to my CQ.</p></body></html> + + + + + Check to call the first decoded responder to my CQ. + + + + + Call 1st + + + + + Check to generate "@1250 (SEND MSGS)" in Tx6. + + + + + Tx6 + + + + + <html><head/><body><p>Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences.</p></body></html> + + + + + Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences. + + + + + Tx even/1st + + + + + <html><head/><body><p>Frequency to call CQ on in kHz above the current MHz</p></body></html> + + + + + Frequency to call CQ on in kHz above the current MHz + + + + + Tx CQ + + + + + <html><head/><body><p>Check this to call CQ on the &quot;Tx CQ&quot; frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on.</p><p>Not available to nonstandard callsign holders.</p></body></html> + + + + + Check this to call CQ on the "Tx CQ" frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on. +Not available to nonstandard callsign holders. + + + + + Rx All Freqs + + + + + <html><head/><body><p>Submode determines tone spacing; A is narrowest.</p></body></html> + + + + + Submode determines tone spacing; A is narrowest. + + + + + Submode + + + + + Fox + + + + + <html><head/><body><p>Check to monitor Sh messages.</p></body></html> + + + + + Check to monitor Sh messages. + + + + + SWL + + + + + Best S+P + + + + + <html><head/><body><p>Check this to start recording calibration data.<br/>While measuring calibration correction is disabled.<br/>When not checked you can view the calibration results.</p></body></html> + + + + + Check this to start recording calibration data. +While measuring calibration correction is disabled. +When not checked you can view the calibration results. + + + + + Measure + + + + + <html><head/><body><p>Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB).</p></body></html> + + + + + Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB). + + + + + Report + + + + + <html><head/><body><p>Tx/Rx or Frequency calibration sequence length</p></body></html> + + + + + Tx/Rx or Frequency calibration sequence length + + + + + s + + + + + T/R + + + + + Toggle Tx mode + + + + + Tx JT9 @ + + + + + Audio Tx frequency + + + + + + Tx + + + + + Tx# + + + + + <html><head/><body><p>Double-click on another caller to queue that call for your next QSO.</p></body></html> + + + + + Double-click on another caller to queue that call for your next QSO. + + + + + Next Call + + + + + 1 + + + + + + + Send this message in next Tx interval + + + + + Ctrl+2 + + + + + <html><head/><body><p>Send this message in next Tx interval</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> + + + + + Send this message in next Tx interval +Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) + + + + + Ctrl+1 + + + + + + + + Switch to this Tx message NOW + + + + + Tx &2 + + + + + Alt+2 + + + + + <html><head/><body><p>Switch to this Tx message NOW</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> + + + + + Switch to this Tx message NOW +Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) + + + + + Tx &1 + + + + + Alt+1 + + + + + Ctrl+6 + + + + + <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to reset to the standard 73 message</p></body></html> + + + + + Send this message in next Tx interval +Double-click to reset to the standard 73 message + + + + + Ctrl+5 + + + + + Ctrl+3 + + + + + Tx &3 + + + + + Alt+3 + + + + + <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> + + + + + Send this message in next Tx interval +Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders) +RR73 messages should only be used when you are reasonably confident that no message repetitions will be required + + + + + Ctrl+4 + + + + + <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> + + + + + Switch to this Tx message NOW +Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders) +RR73 messages should only be used when you are reasonably confident that no message repetitions will be required + + + + + Tx &4 + + + + + Alt+4 + + + + + <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to reset to the standard 73 message</p></body></html> + + + + + Switch to this Tx message NOW +Double-click to reset to the standard 73 message + + + + + Tx &5 + + + + + Alt+5 + + + + + Now + + + + + Generate standard messages for minimal QSO + + + + + Generate Std Msgs + + + + + Tx &6 + + + + + Alt+6 + + + + + + Enter a free text message (maximum 13 characters) +or select a predefined macro from the dropdown list. +Press ENTER to add the current text to the predefined +list. The list can be maintained in Settings (F2). + + + + + Queue up the next Tx message + + + + + Next + + + + + 2 + + + + + Calling CQ + + + + + Generate a CQ message + + + + + + + CQ + + + + + Generate message with RRR + + + + + RRR + + + + + Generate message with report + + + + + dB + + + + + Answering CQ + + + + + Generate message for replying to a CQ + + + + + + Grid + + + + + Generate message with R+report + + + + + R+dB + + + + + Generate message with 73 + + + + + 73 + + + + + Send this standard (generated) message + + + + + Gen msg + + + + + Send this free-text message (max 13 characters) + + + + + Free msg + + + + + 3 + + + + + Max dB + + + + + CQ AF + + + + + CQ AN + + + + + CQ AS + + + + + CQ EU + + + + + CQ NA + + + + + CQ OC + + + + + CQ SA + + + + + CQ 0 + + + + + CQ 1 + + + + + CQ 2 + + + + + CQ 3 + + + + + CQ 4 + + + + + CQ 5 + + + + + CQ 6 + + + + + CQ 7 + + + + + CQ 8 + + + + + CQ 9 + + + + + Reset + + + + + N List + + + + + N Slots + + + + + + Random + + + + + Call + + + + + S/N (dB) + + + + + Distance + + + + + More CQs + + + + + Percentage of 2-minute sequences devoted to transmitting. + + + + + % + + + + + Tx Pct + + + + + Band Hopping + + + + + Choose bands and times of day for band-hopping. + + + + + Schedule ... + + + + + Upload decoded messages to WSPRnet.org. + + + + + Upload spots + + + + + <html><head/><body><p>6 digit locators cause 2 different mesages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol.</p></body></html> + + + + + 6 digit locators cause 2 different mesages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol. + + + + + Prefer type 1 messages + + + + + No own call decodes + + + + + Transmit during the next 2-minute sequence. + + + + + Tx Next + + + + + Set Tx power in dBm (dB above 1 mW) as part of your WSPR message. + + + + + File + + + + + View + + + + + Decode + + + + + Save + + + + + Help + + + + + Mode + + + + + Configurations + + + + + Tools + + + + + Exit + + + + + Configuration + + + + + F2 + + + + + About WSJT-X + + + + + Waterfall + + + + + Open + + + + + Ctrl+O + + + + + Open next in directory + + + + + Decode remaining files in directory + + + + + Shift+F6 + + + + + Delete all *.wav && *.c2 files in SaveDir + + + + + None + + + + + Save all + + + + + Online User Guide + + + + + Keyboard shortcuts + + + + + Special mouse commands + + + + + JT9 + + + + + Save decoded + + + + + Normal + + + + + Deep + + + + + Monitor OFF at startup + + + + + Erase ALL.TXT + + + + + Erase wsjtx_log.adi + + + + + Convert mode to RTTY for logging + + + + + Log dB reports to Comments + + + + + Prompt me to log QSO + + + + + Blank line between decoding periods + + + + + Clear DX Call and Grid after logging + + + + + Display distance in miles + + + + + Double-click on call sets Tx Enable + + + + + + F7 + + + + + Tx disabled after sending 73 + + + + + Runaway Tx watchdog + + + + + Allow multiple instances + + + + + Tx freq locked to Rx freq + + + + + JT65 + + + + + JT9+JT65 + + + + + Tx messages to Rx Frequency window + + + + + Gray1 + + + + + Show DXCC entity and worked B4 status + + + + + Astronomical data + + + + + List of Type 1 prefixes and suffixes + + + + + Settings... + + + + + Local User Guide + + + + + Open log directory + + + + + JT4 + + + + + Message averaging + + + + + Enable averaging + + + + + Enable deep search + + + + + WSPR + + + + + Echo Graph + + + + + F8 + + + + + Echo + + + + + EME Echo mode + + + + + ISCAT + + + + + Fast Graph + + + + + F9 + + + + + &Download Samples ... + + + + + <html><head/><body><p>Download sample audio files demonstrating the various modes.</p></body></html> + + + + + MSK144 + + + + + QRA64 + + + + + Release Notes + + + + + Enable AP for DX Call + + + + + FreqCal + + + + + Measure reference spectrum + + + + + Measure phase response + + + + + Erase reference spectrum + + + + + Execute frequency calibration cycle + + + + + Equalization tools ... + + + + + WSPR-LF + + + + + Experimental LF/MF mode + + + + + FT8 + + + + + + Enable AP + + + + + Solve for calibration parameters + + + + + Copyright notice + + + + + Shift+F1 + + + + + Fox log + + + + + FT8 DXpedition Mode User Guide + + + + + Reset Cabrillo log ... + + + + + Color highlighting scheme + + + + + Contest Log + + + + + Export Cabrillo log ... + + + + + Quick-Start Guide to WSJT-X 2.0 + + + + + Contest log + + + + + Erase WSPR hashtable + + + + + FT4 + + + + + Rig Control Error + + + + + Do you want to reconfigure the radio interface? + + + + + Error Scanning ADIF Log + + + + + Scanned ADIF log, %1 worked before records created + + + + + Error Loading LotW Users Data + + + + + Error Writing WAV File + + + + + Configurations... + + + + + Error Killing jt9.exe Process + + + + + KillByName return code: %1 + + + + + Error removing "%1" + + + + + Click OK to retry + + + + + + Improper mode + + + + + + File Open Error + + + + + + + + + Cannot open "%1" for append: %2 + + + + + Error saving c2 file + + + + + Error in Sound Input + + + + + Error in Sound Output + + + + + Change Operator + + + + + New operator: + + + + + Status File Error + + + + + + Cannot open "%1" for writing: %2 + + + + + Subprocess Error + + + + + Subprocess failed with exit code %1 + + + + + + Running: %1 +%2 + + + + + Subprocess error + + + + + Reference spectrum saved + + + + + Invalid data in fmt.all at line %1 + + + + + Good Calibration Solution + + + + + <pre>%1%L2 ±%L3 ppm +%4%L5 ±%L6 Hz + +%7%L8 +%9%L10 Hz</pre> + + + + + Delete Calibration Measurements + + + + + The "fmt.all" file will be renamed as "fmt.bak" + + + + + If you make fair use of any part of WSJT-X under terms of the GNU General Public License, you must display the following copyright notice prominently in your derivative work: + +"The algorithms, source code, look-and-feel of WSJT-X and related programs, and protocol specifications for the modes FSK441, FT8, JT4, JT6M, JT9, JT65, JTMS, QRA64, ISCAT, MSK144 are Copyright (C) 2001-2019 by one or more of the following authors: Joseph Taylor, K1JT; Bill Somerville, G4WJS; Steven Franke, K9AN; Nico Palermo, IV3NWV; Greg Beam, KI7MT; Michael Black, W9MDB; Edson Pereira, PY2SDR; Philip Karn, KA9Q; and other members of the WSJT Development Group." + + + + + No data read from disk. Wrong file format? + + + + + Confirm Delete + + + + + Are you sure you want to delete all *.wav and *.c2 files in "%1"? + + + + + Keyboard Shortcuts + + + + + Special Mouse Commands + + + + + No more files to open. + + + + + Please choose another Tx frequency. WSJT-X will not knowingly transmit another mode in the WSPR sub-band on 30m. + + + + + WSPR Guard Band + + + + + Please choose another dial frequency. WSJT-X will not operate in Fox mode in the standard FT8 sub-bands. + + + + + Fox Mode warning + + + + + Should you switch to ARRL Field Day mode? + + + + + Should you switch to RTTY contest mode? + + + + + + + + Add to CALL3.TXT + + + + + Please enter a valid grid locator + + + + + Cannot open "%1" for read/write: %2 + + + + + %1 +is already in CALL3.TXT, do you wish to replace it? + + + + + Warning: DX Call field is empty. + + + + + Log file error + + + + + Cannot open "%1" + + + + + Error sending log to N1MM + + + + + Write returned "%1" + + + + + + + Confirm Erase + + + + + Are you sure you want to erase file ALL.TXT? + + + + + + Confirm Reset + + + + + Are you sure you want to erase your contest log? + + + + + Doing this will remove all QSO records for the current contest. They will be kept in the ADIF log file but will not be available for export in your Cabrillo log. + + + + + Cabrillo Log saved + + + + + Are you sure you want to erase file wsjtx_log.adi? + + + + + Are you sure you want to erase the WSPR hashtable? + + + + + VHF features warning + + + + + Tune digital gain + + + + + Transmit digital gain + + + + + Prefixes + + + + + Network Error + + + + + Error: %1 +UDP server %2:%3 + + + + + File Error + + + + + Phase Training Disabled + + + + + Phase Training Enabled + + + + + + Log File Error + + + + + Are you sure you want to clear the QSO queues? + + + + + MessageAveraging + + + + Message Averaging + + + + + UTC Sync DT Freq + + + + + Modes + + + + Mode + + + + + MultiSettings + + + Default + + + + + MultiSettings::impl + + + &Switch To + + + + + &Clone + + + + + Clone &Into ... + + + + + R&eset + + + + + &Rename ... + + + + + &Delete + + + + + Clone Into Configuration + + + + + Confirm overwrite of all values for configuration "%1" with values from "%2"? + + + + + Reset Configuration + + + + + Confirm reset to default values for configuration "%1"? + + + + + Delete Configuration + + + + + Confirm deletion of configuration "%1"? + + + + + NameDialog + + + New Configuration Name + + + + + Old name: + + + + + &New name: + + + + + OmniRigTransceiver + + + OmniRig: unrecognized mode + + + + + Failed to start OmniRig COM server + + + + + + OmniRig: don't know how to set rig frequency + + + + + + OmniRig: timeout waiting for update from rig + + + + + OmniRig COM/OLE error: %1 at %2: %3 (%4) + + + + + PollingTransceiver + + + Unexpected rig error + + + + + QObject + + + Invalid rig name - \ & / not allowed + + + + + User Defined + + + + + Failed to open LotW users CSV file: '%1' + + + + + OOB + + + + + Too many colours in palette. + + + + + Error reading waterfall palette file "%1:%2" too many colors. + + + + + Error reading waterfall palette file "%1:%2" invalid triplet. + + + + + Error reading waterfall palette file "%1:%2" invalid color. + + + + + Error opening waterfall palette file "%1": %2. + + + + + Error writing waterfall palette file "%1": %2. + + + + + RemoteFile + + + + + + + + File System Error + + + + + Cannot rename file: +"%1" +to: "%2" +Error(%3): %4 + + + + + Cannot delete file: +"%1" + + + + + + + Network Error + + + + + Too many redirects: %1 + + + + + Redirect not followed: %1 + + + + + Cannot commit changes to: +"%1" + + + + + Cannot open file: +"%1" +Error(%2): %3 + + + + + Cannot make path: +"%1" + + + + + Cannot write to file: +"%1" +Error(%2): %3 + + + + + SampleDownloader::impl + + + Download Samples + + + + + Input Error + + + + + Invalid URL format + + + + + SoundInput + + + An error opening the audio input device has occurred. + + + + + An error occurred during read from the audio input device. + + + + + Audio data not being fed to the audio input device fast enough. + + + + + Non-recoverable error, audio input device not usable at this time. + + + + + Requested input audio format is not valid. + + + + + Requested input audio format is not supported on device. + + + + + Failed to initialize audio sink device + + + + + Idle + + + + + Receiving + + + + + Suspended + + + + + Interrupted + + + + + Error + + + + + Stopped + + + + + SoundOutput + + + An error opening the audio output device has occurred. + + + + + An error occurred during write to the audio output device. + + + + + Audio data not being fed to the audio output device fast enough. + + + + + Non-recoverable error, audio output device not usable at this time. + + + + + Requested output audio format is not valid. + + + + + Requested output audio format is not supported on device. + + + + + Idle + + + + + Sending + + + + + Suspended + + + + + Interrupted + + + + + Error + + + + + Stopped + + + + + StationDialog + + + Add Station + + + + + &Band: + + + + + &Offset (MHz): + + + + + &Antenna: + + + + + StationList::impl + + + Band name + + + + + Frequency offset + + + + + Antenna description + + + + + Band + + + + + Offset + + + + + Antenna Description + + + + + TransceiverBase + + + Unexpected rig error + + + + + WideGraph + + + Dialog + + + + + Controls + + + + + Spectrum gain + + + + + Palette + + + + + <html><head/><body><p>Enter definition for a new color palette.</p></body></html> + + + + + Adjust... + + + + + Waterfall gain + + + + + <html><head/><body><p>Set fractional size of spectrum in this window.</p></body></html> + + + + + % + + + + + Spec + + + + + <html><head/><body><p>Flatten spectral baseline over the full displayed interval.</p></body></html> + + + + + Flatten + + + + + <html><head/><body><p>Compute and save a reference spectrum. (Not yet fully implemented.)</p></body></html> + + + + + Ref Spec + + + + + Smoothing of Linear Average spectrum + + + + + Smooth + + + + + Compression factor for frequency scale + + + + + Bins/Pixel + + + + + Select waterfall palette + + + + + <html><head/><body><p>Select data for spectral display</p></body></html> + + + + + Current + + + + + Cumulative + + + + + Linear Avg + + + + + Reference + + + + + <html><head/><body><p>Frequency at left edge of waterfall</p></body></html> + + + + + Hz + + + + + Start + + + + + <html><head/><body><p>Decode JT9 only above this frequency</p></body></html> + + + + + JT9 + + + + + JT65 + + + + + Number of FFTs averaged (controls waterfall scrolling rate) + + + + + N Avg + + + + + Waterfall zero + + + + + Spectrum zero + + + + + Wide Graph + + + + + + Read Palette + + + + + configuration_dialog + + + Settings + + + + + Genera&l + + + + + General station details and settings. + + + + + Station Details + + + + + My C&all: + + + + + Station callsign. + + + + + M&y Grid: + + + + + <html><head/><body><p>Maidenhead locator, preferably 6 characters.</p></body></html> + + + + + Check to allow grid changes from external programs + + + + + AutoGrid + + + + + IARU Region: + + + + + <html><head/><body><p>Select your IARU region.</p></body></html> + + + + + Message generation for type 2 compound callsign holders: + + + + + <html><head/><body><p>Type 2 compound callsigns are those with prefixes or suffixes not included in the allowed shortlist (See Help-&gt;Add-on prefixes and suffixes).</p><p>This option determines which generated messages should contain your full type 2 compound call sign rather than your base callsign. It only applies if you have a type 2 compound callsign.</p><p>This option controls the way the messages that are used to answer CQ calls are generated. Generated messages 6 (CQ) and 5 (73) will always contain your full callsign. The JT65 and JT9 protocols allow for some standard messages with your full call at the expense of another piece of information such as the DX call or your locator.</p><p>Choosing message 1 omits the DX callsign which may be an issue when replying to CQ calls. Choosing message 3 also omits the DX callsign and many versions of this and other software will not extract the report. Choosing neither means that your full callsign only goes in your message 5 (73) so your QSO partner may log the wrong callsign.</p><p>None of these options are perfect, message 3 is usually best but be aware your QSO partner may not log the report you send them.</p></body></html> + + + + + Full call in Tx1 + + + + + Full call in Tx3 + + + + + Full call in Tx5 only + + + + + Display + + + + + Show outgoing transmitted messages in the Rx frequency window. + + + + + &Tx messages to Rx frequency window + + + + + Show if decoded stations are new DXCC entities or worked before. + + + + + Show &DXCC, grid, and worked-before status + + + + + <html><head/><body><p>Check to have decodes for a new period start at the top of the Band Activity window and not scroll off the top when the window is full.</p><p>This is to aid selecting decodes to double-click while decoding is still in progress. Use the Band Activity vertical scroll bar to reveal decodes past the bottom of the window.</p></body></html> + + + + + Start new period decodes at top + + + + + Show principal prefix instead of country name + + + + + Set the font characteristics for the application. + + + + + Font... + + + + + Set the font characteristics for the Band Activity and Rx Frequency areas. + + + + + Decoded Text Font... + + + + + Include a separator line between periods in the band activity window. + + + + + &Blank line between decoding periods + + + + + Show distance to DX station in miles rather than kilometers. + + + + + Display dista&nce in miles + + + + + Behavior + + + + + Decode after EME delay + + + + + Tx watchdog: + + + + + <html><head/><body><p>Number of minutes before unattended transmissions are aborted</p></body></html> + + + + + Disabled + + + + + minutes + + + + + Enable VHF/UHF/Microwave features + + + + + Single decode + + + + + <html><head/><body><p>Some rigs are not able to process CAT commands while transmitting. This means that if you are operating in split mode you may have to uncheck this option.</p></body></html> + + + + + Allow Tx frequency changes while transmitting + + + + + Don't start decoding until the monitor button is clicked. + + + + + Mon&itor off at startup + + + + + <html><head/><body><p>Check this if you wish to automatically return to the last monitored frequency when monitor is enabled, leave it unchecked if you wish to have the current rig frequency maintained.</p></body></html> + + + + + Monitor returns to last used frequency + + + + + Alternate F1-F6 bindings + + + + + Turns off automatic transmissions after sending a 73 or any other free +text message. + + + + + Di&sable Tx after sending 73 + + + + + Send a CW ID after every 73 or free text message. + + + + + CW ID a&fter 73 + + + + + Periodic CW ID Inter&val: + + + + + Send a CW ID periodically every few minutes. +This might be required under your countries licence regulations. +It will not interfere with other users as it is always sent in the +quiet period when decoding is done. + + + + + Automatic transmission mode. + + + + + Doubl&e-click on call sets Tx enable + + + + + Calling CQ forces Call 1st + + + + + &Radio + + + + + Radio interface configuration settings. + + + + + Settings that control your CAT interface. + + + + + CAT Control + + + + + + Port: + + + + + Serial port used for CAT control. + + + + + Serial Port Parameters + + + + + Baud Rate: + + + + + Serial port data rate which must match the setting of your radio. + + + + + 1200 + + + + + 2400 + + + + + 4800 + + + + + 9600 + + + + + 19200 + + + + + 38400 + + + + + 57600 + + + + + 115200 + + + + + <html><head/><body><p>Number of data bits used to communicate with your radio's CAT interface (usually eight).</p></body></html> + + + + + Data Bits + + + + + D&efault + + + + + Se&ven + + + + + E&ight + + + + + <html><head/><body><p>Number of stop bits used when communicating with your radio's CAT interface</p><p>(consult you radio's manual for details).</p></body></html> + + + + + Stop Bits + + + + + + Default + + + + + On&e + + + + + T&wo + + + + + <html><head/><body><p>Flow control protocol used between this computer and your radio's CAT interface (usually &quot;None&quot; but some require &quot;Hardware&quot;).</p></body></html> + + + + + Handshake + + + + + &None + + + + + Software flow control (very rare on CAT interfaces). + + + + + XON/XOFF + + + + + Flow control using the RTS and CTS RS-232 control lines +not often used but some radios have it as an option and +a few, particularly some Kenwood rigs, require it). + + + + + &Hardware + + + + + Special control of CAT port control lines. + + + + + Force Control Lines + + + + + + High + + + + + + Low + + + + + DTR: + + + + + RTS: + + + + + How this program activates the PTT on your radio + + + + + PTT Method + + + + + <html><head/><body><p>No PTT activation, instead the radio's automatic VOX is used to key the transmitter.</p><p>Use this if you have no radio interface hardware.</p></body></html> + + + + + VO&X + + + + + <html><head/><body><p>Use the RS-232 DTR control line to toggle your radio's PTT, requires hardware to inteface the line.</p><p>Some commercial interface units also use this method.</p><p>The DTR control line of the CAT serial port may be used for this or a DTR control line on a different serial port may be used.</p></body></html> + + + + + &DTR + + + + + Some radios support PTT via CAT commands, +use this option if your radio supports it and you have no +other hardware interface for PTT. + + + + + C&AT + + + + + <html><head/><body><p>Use the RS-232 RTS control line to toggle your radio's PTT, requires hardware to inteface the line.</p><p>Some commercial interface units also use this method.</p><p>The RTS control line of the CAT serial port may be used for this or a RTS control line on a different serial port may be used. Note that this option is not available on the CAT serial port when hardware flow control is used.</p></body></html> + + + + + R&TS + + + + + <html><head/><body><p>Select the RS-232 serial port utilised for PTT control, this option is available when DTR or RTS is selected above as a transmit method.</p><p>This port can be the same one as the one used for CAT control.</p><p>For some interface types the special value CAT may be chosen, this is used for non-serial CAT interfaces that can control serial port control lines remotely (OmniRig for example).</p></body></html> + + + + + Modulation mode selected on radio. + + + + + Mode + + + + + <html><head/><body><p>USB is usually the correct modulation mode,</p><p>unless the radio has a special data or packet mode setting</p><p>for AFSK operation.</p></body></html> + + + + + US&B + + + + + Don't allow the program to set the radio mode +(not recommended but use if the wrong mode +or bandwidth is selected). + + + + + + None + + + + + If this is availabe then it is usually the correct mode for this program. + + + + + Data/P&kt + + + + + Some radios can select the audio input using a CAT command, +this setting allows you to select which audio input will be used +(if it is available then generally the Rear/Data option is best). + + + + + Transmit Audio Source + + + + + Rear&/Data + + + + + &Front/Mic + + + + + Rig: + + + + + Poll Interval: + + + + + <html><head/><body><p>Interval to poll rig for status. Longer intervals will mean that changes to the rig will take longer to be detected.</p></body></html> + + + + + s + + + + + <html><head/><body><p>Attempt to connect to the radio with these settings.</p><p>The button will turn green if the connection is successful or red if there is a problem.</p></body></html> + + + + + Test CAT + + + + + Attempt to activate the transmitter. +Click again to deactivate. Normally no power should be +output since there is no audio being generated at this time. +Check that any Tx indication on your radio and/or your +radio interface behave as expected. + + + + + Test PTT + + + + + Split Operation + + + + + Fake It + + + + + Rig + + + + + A&udio + + + + + Audio interface settings + + + + + Souncard + + + + + Soundcard + + + + + Select the audio CODEC to use for transmitting. +If this is your default device for system sounds then +ensure that all system sounds are disabled otherwise +you will broadcast any systems sounds generated during +transmitting periods. + + + + + Select the audio CODEC to use for receiving. + + + + + &Input: + + + + + Select the channel to use for receiving. + + + + + + Mono + + + + + + Left + + + + + + Right + + + + + + Both + + + + + Select the audio channel used for transmission. +Unless you have multiple radios connected on different +channels; then you will usually want to select mono or +both here. + + + + + Ou&tput: + + + + + + Save Directory + + + + + Loc&ation: + + + + + Path to which .WAV files are saved. + + + + + + TextLabel + + + + + Click to select a different save directory for .WAV files. + + + + + S&elect + + + + + + AzEl Directory + + + + + Location: + + + + + Select + + + + + Power Memory By Band + + + + + Remember power settings by band + + + + + Enable power memory during transmit + + + + + Transmit + + + + + Enable power memory during tuning + + + + + Tune + + + + + Tx &Macros + + + + + Canned free text messages setup + + + + + &Add + + + + + &Delete + + + + + Drag and drop items to rearrange order +Right click for item specific actions +Click, SHIFT+Click and, CRTL+Click to select items + + + + + Reportin&g + + + + + Reporting and logging settings + + + + + Logging + + + + + The program will pop up a partially completed Log QSO dialog when you send a 73 or free text message. + + + + + Promp&t me to log QSO + + + + + Op Call: + + + + + Some logging programs will not accept the type of reports +saved by this program. +Check this option to save the sent and received reports in the +comments field. + + + + + d&B reports to comments + + + + + Check this option to force the clearing of the DX Call +and DX Grid fields when a 73 or free text message is sent. + + + + + Clear &DX call and grid after logging + + + + + <html><head/><body><p>Some logging programs will not accept WSJT-X mode names.</p></body></html> + + + + + Con&vert mode to RTTY + + + + + <html><head/><body><p>The callsign of the operator, if different from the station callsign.</p></body></html> + + + + + <html><head/><body><p>Check to have QSOs logged automatically, when complete.</p></body></html> + + + + + Log automatically (contesting only) + + + + + Network Services + + + + + The program can send your station details and all +decoded signals as spots to the http://pskreporter.info web site. +This is used for reverse beacon analysis which is very useful +for assessing propagation and system performance. + + + + + Enable &PSK Reporter Spotting + + + + + UDP Server + + + + + UDP Server: + + + + + <html><head/><body><p>Optional hostname of network service to receive decodes.</p><p>Formats:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">hostname</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 multicast group address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 multicast group address</li></ul><p>Clearing this field will disable the broadcasting of UDP status updates.</p></body></html> + + + + + UDP Server port number: + + + + + <html><head/><body><p>Enter the service port number of the UDP server that WSJT-X should send updates to. If this is zero no updates will be broadcast.</p></body></html> + + + + + <html><head/><body><p>With this enabled WSJT-X will accept certain requests back from a UDP server that receives decode messages.</p></body></html> + + + + + Accept UDP requests + + + + + <html><head/><body><p>Indicate acceptance of an incoming UDP request. The effect of this option varies depending on the operating system and window manager, its intent is to notify the acceptance of an incoming UDP request even if this application is minimized or hidden.</p></body></html> + + + + + Notify on accepted UDP request + + + + + <html><head/><body><p>Restore the window from minimized if an UDP request is accepted.</p></body></html> + + + + + Accepted UDP request restores window + + + + + Secondary UDP Server (deprecated) + + + + + <html><head/><body><p>When checked, WSJT-X will broadcast a logged contact in ADIF format to the configured hostname and port. </p></body></html> + + + + + Enable logged contact ADIF broadcast + + + + + Server name or IP address: + + + + + <html><head/><body><p>Optional host name of N1MM Logger+ program to receive ADIF UDP broadcasts. This is usually 'localhost' or ip address 127.0.0.1</p><p>Formats:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">hostname</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv4 multicast group address</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">IPv6 multicast group address</li></ul><p>Clearing this field will disable broadcasting of ADIF information via UDP.</p></body></html> + + + + + Server port number: + + + + + <html><head/><body><p>Enter the port number that WSJT-X should use for UDP broadcasts of ADIF log information. For N1MM Logger+, this value should be 2333. If this is zero, no updates will be broadcast.</p></body></html> + + + + + Frequencies + + + + + Default frequencies and band specific station details setup + + + + + <html><head/><body><p>See &quot;Frequency Calibration&quot; in the WSJT-X User Guide for details of how to determine these parameters for your radio.</p></body></html> + + + + + Frequency Calibration + + + + + Slope: + + + + + ppm + + + + + Intercept: + + + + + Hz + + + + + Working Frequencies + + + + + <html><head/><body><p>Right click to maintain the working frequencies list.</p></body></html> + + + + + Station Information + + + + + Items may be edited. +Right click for insert and delete options. + + + + + Colors + Cores + + + + Decode Highlightling + + + + + <html><head/><body><p>Enable or disable using the check boxes and right-click an item to change or unset the foreground color, background color, or reset the item to default values. Drag and drop the items to change their priority, higher in the list is higher in priority.</p><p>Note that each foreground or background color may be either set or unset, unset means that it is not allocated for that item's type and lower priority items may apply.</p></body></html> + + + + + <html><head/><body><p>Push to reset all highlight items above to default values and priorities.</p></body></html> + + + + + Reset Highlighting + + + + + <html><head/><body><p>Check to indicate new DXCC entities, grid squares, and callsigns per mode.</p></body></html> + + + + + Highlight by Mode + + + + + <html><head/><body><p>Click to scan the wsjtx_log.adi ADIF file again for worked before information</p></body></html> + + + + + Rescan ADIF Log + + + + + Include extra WAE entities + + + + + <html><head/><body><p>Controls for Logbook of the World user lookup.</p></body></html> + + + + + Logbook of the World User Validation + + + + + Users CSV file URL: + + + + + <html><head/><body><p>URL of the ARRL LotW user's last upload dates and times data file which is used to highlight decodes from stations that are known to upload their log file to LotW.</p></body></html> + + + + + https://lotw.arrl.org/lotw-user-activity.csv + + + + + <html><head/><body><p>Push this button to fetch the latest LotW user's upload date and time data file.</p></body></html> + + + + + Fetch Now + + + + + Age of last upload less than: + + + + + <html><head/><body><p>Adjust this spin box to set the age threshold of LotW user's last upload date that is accepted as a current LotW user.</p></body></html> + + + + + days + + + + + Advanced + + + + + <html><head/><body><p>User-selectable parameters for JT65 VHF/UHF/Microwave decoding.</p></body></html> + + + + + JT65 VHF/UHF/Microwave decoding parameters + + + + + Random erasure patterns: + + + + + <html><head/><body><p>Maximum number of erasure patterns for stochastic soft-decision Reed Solomon decoder is 10^(n/2).</p></body></html> + + + + + Aggressive decoding level: + + + + + <html><head/><body><p>Higher levels will increase the probability of decoding, but will also increase probability of a false decode.</p></body></html> + + + + + Two-pass decoding + + + + + Special operating activity: Generation of FT4, FT8, and MSK144 messages + + + + + <html><head/><body><p>FT8 DXpedition mode: Hound operator calling the DX.</p></body></html> + + + + + Hound + + + + + <html><head/><body><p>North American VHF/UHF/Microwave contests and others in which a 4-character grid locator is the required exchange.</p></body></html> + + + + + NA VHF Contest + + + + + <html><head/><body><p>FT8 DXpedition mode: Fox (DXpedition) operator.</p></body></html> + + + + + Fox + + + + + <html><head/><body><p>European VHF+ contests requiring a signal report, serial number, and 6-character locator.</p></body></html> + + + + + EU VHF Contest + + + + + + <html><head/><body><p>ARRL RTTY Roundup and similar contests. Exchange is US state, Canadian province, or &quot;DX&quot;.</p></body></html> + + + + + RTTY Roundup messages + + + + + RTTY RU Exch: + + + + + NJ + + + + + + <html><head/><body><p>ARRL Field Day exchange: number of transmitters, Class, and ARRL/RAC section or &quot;DX&quot;.</p></body></html> + + + + + ARRL Field Day + + + + + FD Exch: + + + + + 6A SNJ + + + + + Miscellaneous + + + + + Degrade S/N of .wav file: + + + + + + For offline sensitivity tests + + + + + dB + + + + + Receiver bandwidth: + + + + + Hz + + + + + Tx delay: + + + + + Minimum delay between assertion of PTT and start of Tx audio. + + + + + s + + + + + Tone spacing + + + + + <html><head/><body><p>Generate Tx audio with twice the normal tone spacing. Intended for special LF/MF transmitters that use a divide-by-2 before generating RF.</p></body></html> + + + + + x 2 + + + + + <html><head/><body><p>Generate Tx audio with four times the normal tone spacing. Intended for special LF/MF transmitters that use a divide-by-4 before generating RF.</p></body></html> + + + + + x 4 + + + + + Waterfall spectra + + + + + Low sidelobes + + + + + Most sensitive + + + + + <html><head/><body><p>Discard (Cancel) or apply (OK) configuration changes including</p><p>resetting the radio interface and applying any soundcard changes</p></body></html> + + + + + main + + + + Fatal error + + + + + + Unexpected fatal error + + + + + Where <rig-name> is for multi-instance support. + + + + + rig-name + + + + + Where <configuration> is an existing one. + + + + + configuration + + + + + Writable files in test location. Use with caution, for testing only. + + + + + Command line error + + + + + Command line help + + + + + Application version + + + + + Another instance may be running + + + + + try to remove stale lock file? + + + + + Failed to create a temporary directory + + + + + + Path: "%1" + + + + + Failed to create a usable temporary directory + + + + + Another application may be locking the directory + + + + + Failed to create data directory + + + + + path: "%1" + + + + + Shared memory error + + + + + Unable to create shared memory segment + + + + + wf_palette_design_dialog + + + Palette Designer + + + + + <html><head/><body><p>Double click a color to edit it.</p><p>Right click to insert or delete colors.</p><p>Colors at the top represent weak signals</p><p>and colors at the bottom represent strong</p><p>signals. You can have up to 256 colors.</p></body></html> + + + + diff --git a/validators/MaidenheadLocatorValidator.cpp b/validators/MaidenheadLocatorValidator.cpp index 9de41233e..e7e1134c7 100644 --- a/validators/MaidenheadLocatorValidator.cpp +++ b/validators/MaidenheadLocatorValidator.cpp @@ -64,7 +64,7 @@ auto MaidenheadLocatorValidator::validate (QString& input, int& pos) const -> St auto subsquare = match.captured ("subsquare"); if (subsquare.size ()) { - input.replace (match.capturedStart ("subsquare"), match.capturedLength ("subsquare"), subsquare.toLower ()); + input.replace (match.capturedStart ("subsquare"), match.capturedLength ("subsquare"), subsquare.toUpper ()); } if (match.hasMatch ()) return Acceptable; if (!input.size () || match.hasPartialMatch ()) return Intermediate; diff --git a/widgets/AbstractLogWindow.cpp b/widgets/AbstractLogWindow.cpp index efa1e60f1..bbe07a846 100644 --- a/widgets/AbstractLogWindow.cpp +++ b/widgets/AbstractLogWindow.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -16,7 +17,10 @@ #include "pimpl_impl.hpp" class AbstractLogWindow::impl final + : public QObject { + Q_OBJECT + public: impl (AbstractLogWindow * self, QString const& settings_key, QSettings * settings , Configuration const * configuration) @@ -38,6 +42,9 @@ public: FontOverrideModel model_; }; +#include "moc_AbstractLogWindow.cpp" +#include "AbstractLogWindow.moc" + namespace { bool row_is_higher (QModelIndex const& lhs, QModelIndex const& rhs) diff --git a/widgets/AbstractLogWindow.hpp b/widgets/AbstractLogWindow.hpp index 581212d82..476ff62f3 100644 --- a/widgets/AbstractLogWindow.hpp +++ b/widgets/AbstractLogWindow.hpp @@ -19,6 +19,8 @@ class QFont; class AbstractLogWindow : public QWidget { + Q_OBJECT + public: AbstractLogWindow (QString const& settings_key, QSettings * settings , Configuration const * configuration diff --git a/widgets/CabrilloLogWindow.cpp b/widgets/CabrilloLogWindow.cpp index 44a52cc6b..6fd753136 100644 --- a/widgets/CabrilloLogWindow.cpp +++ b/widgets/CabrilloLogWindow.cpp @@ -1,12 +1,13 @@ #include "CabrilloLogWindow.hpp" +#include #include #include #include #include "Configuration.hpp" #include "models/Bands.hpp" +#include "item_delegates/FrequencyDelegate.hpp" #include "item_delegates/ForeignKeyDelegate.hpp" -#include "item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp" #include "item_delegates/CallsignDelegate.hpp" #include "pimpl_impl.hpp" @@ -30,7 +31,7 @@ namespace switch (index.column ()) { case 1: - case 6: + case 7: return Qt::AlignRight + Qt::AlignVCenter; default: break; @@ -64,11 +65,10 @@ CabrilloLogWindow::CabrilloLogWindow (QSettings * settings, Configuration const m_->format_model_.setSourceModel (m_->log_model_); m_->ui_.log_table_view->setModel (&m_->format_model_); set_log_view (m_->ui_.log_table_view); - m_->ui_.log_table_view->setItemDelegateForColumn (2, new DateTimeAsSecsSinceEpochDelegate {this}); - m_->ui_.log_table_view->setItemDelegateForColumn (3, new CallsignDelegate {this}); - m_->ui_.log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration->bands (), 0, this}); + m_->ui_.log_table_view->setItemDelegateForColumn (1, new FrequencyDelegate {this}); + m_->ui_.log_table_view->setItemDelegateForColumn (4, new CallsignDelegate {this}); auto h_header = m_->ui_.log_table_view->horizontalHeader (); - h_header->moveSection (6, 1); // band to first column + h_header->moveSection (7, 1); // band to first column } CabrilloLogWindow::~CabrilloLogWindow () diff --git a/widgets/CabrilloLogWindow.ui b/widgets/CabrilloLogWindow.ui index efefe5d3c..35b4d597d 100644 --- a/widgets/CabrilloLogWindow.ui +++ b/widgets/CabrilloLogWindow.ui @@ -19,6 +19,9 @@ <html><head/><body><p>Right-click here for available actions.</p></body></html> + + Right-click here for available actions. + true diff --git a/widgets/DateTimeEdit.hpp b/widgets/DateTimeEdit.hpp new file mode 100644 index 000000000..ad767a551 --- /dev/null +++ b/widgets/DateTimeEdit.hpp @@ -0,0 +1,23 @@ +#ifndef DATE_TIME_EDIT_HPP_ +#define DATE_TIME_EDIT_HPP_ + +#include + +class QWidget; + +// +// DateTimeEdit - format includes seconds +// +class DateTimeEdit final + : public QDateTimeEdit +{ +public: + explicit DateTimeEdit (QWidget * parent = nullptr) + : QDateTimeEdit {parent} + { + setDisplayFormat (locale ().dateFormat (QLocale::ShortFormat) + " hh:mm:ss"); + setTimeSpec (Qt::UTC); + } +}; + +#endif diff --git a/widgets/DecodeHighlightingListView.cpp b/widgets/DecodeHighlightingListView.cpp index cc5ea5d2e..cfb14fc5d 100644 --- a/widgets/DecodeHighlightingListView.cpp +++ b/widgets/DecodeHighlightingListView.cpp @@ -6,6 +6,8 @@ #include "models/DecodeHighlightingModel.hpp" #include "MessageBox.hpp" +#include "moc_DecodeHighlightingListView.cpp" + DecodeHighlightingListView::DecodeHighlightingListView (QWidget * parent) : QListView {parent} { diff --git a/widgets/DecodeHighlightingListView.hpp b/widgets/DecodeHighlightingListView.hpp index 86aa86f4f..76fd507b7 100644 --- a/widgets/DecodeHighlightingListView.hpp +++ b/widgets/DecodeHighlightingListView.hpp @@ -16,6 +16,8 @@ class QWidget; class DecodeHighlightingListView final : public QListView { + Q_OBJECT + public: explicit DecodeHighlightingListView (QWidget * parent = nullptr); diff --git a/widgets/ExportCabrillo.cpp b/widgets/ExportCabrillo.cpp index 0e61f0f08..5fb54c7dc 100644 --- a/widgets/ExportCabrillo.cpp +++ b/widgets/ExportCabrillo.cpp @@ -11,6 +11,7 @@ #include "models/CabrilloLog.hpp" #include "ui_ExportCabrillo.h" +#include "moc_ExportCabrillo.cpp" ExportCabrillo::ExportCabrillo (QSettings * settings, Configuration const * configuration , CabrilloLog const * log, QWidget * parent) diff --git a/widgets/ExportCabrillo.h b/widgets/ExportCabrillo.h index fbc9294cd..0dfbf6754 100644 --- a/widgets/ExportCabrillo.h +++ b/widgets/ExportCabrillo.h @@ -15,6 +15,8 @@ namespace Ui { class ExportCabrillo final : public QDialog { + Q_OBJECT + public: explicit ExportCabrillo (QSettings *, Configuration const * , CabrilloLog const *, QWidget * parent = nullptr); diff --git a/widgets/FoxLogWindow.cpp b/widgets/FoxLogWindow.cpp index 36f20b85b..9c29a30ad 100644 --- a/widgets/FoxLogWindow.cpp +++ b/widgets/FoxLogWindow.cpp @@ -13,7 +13,6 @@ #include "models/Bands.hpp" #include "models/FoxLog.hpp" #include "item_delegates/ForeignKeyDelegate.hpp" -#include "item_delegates/DateTimeAsSecsSinceEpochDelegate.hpp" #include "item_delegates/CallsignDelegate.hpp" #include "item_delegates/MaidenheadLocatorDelegate.hpp" #include "pimpl_impl.hpp" @@ -42,7 +41,6 @@ FoxLogWindow::FoxLogWindow (QSettings * settings, Configuration const * configur m_->ui_.setupUi (this); m_->ui_.log_table_view->setModel (m_->log_->model ()); set_log_view (m_->ui_.log_table_view); - m_->ui_.log_table_view->setItemDelegateForColumn (1, new DateTimeAsSecsSinceEpochDelegate {this}); m_->ui_.log_table_view->setItemDelegateForColumn (2, new CallsignDelegate {this}); m_->ui_.log_table_view->setItemDelegateForColumn (3, new MaidenheadLocatorDelegate {this}); m_->ui_.log_table_view->setItemDelegateForColumn (6, new ForeignKeyDelegate {configuration->bands (), 0, this}); diff --git a/widgets/FrequencyDeltaLineEdit.cpp b/widgets/FrequencyDeltaLineEdit.cpp new file mode 100644 index 000000000..b7ed144b6 --- /dev/null +++ b/widgets/FrequencyDeltaLineEdit.cpp @@ -0,0 +1,54 @@ +#include "FrequencyDeltaLineEdit.hpp" + +#include + +#include +#include +#include + +#include "moc_FrequencyDeltaLineEdit.cpp" + +namespace +{ + class MHzValidator + : public QDoubleValidator + { + public: + MHzValidator (double bottom, double top, QObject * parent = nullptr) + : QDoubleValidator {bottom, top, 6, parent} + { + } + + State validate (QString& input, int& pos) const override + { + State result = QDoubleValidator::validate (input, pos); + if (Acceptable == result) + { + bool ok; + (void)QLocale {}.toDouble (input, &ok); + if (!ok) + { + result = Intermediate; + } + } + return result; + } + }; +} + +FrequencyDeltaLineEdit::FrequencyDeltaLineEdit (QWidget * parent) + : QLineEdit (parent) +{ + setValidator (new MHzValidator {-std::numeric_limits::max () / 10.e6, + std::numeric_limits::max () / 10.e6, this}); +} + +auto FrequencyDeltaLineEdit::frequency_delta () const -> FrequencyDelta +{ + return Radio::frequency_delta (text (), 6); +} + +void FrequencyDeltaLineEdit::frequency_delta (FrequencyDelta d) +{ + setText (Radio::frequency_MHz_string (d)); +} diff --git a/widgets/FrequencyDeltaLineEdit.hpp b/widgets/FrequencyDeltaLineEdit.hpp new file mode 100644 index 000000000..caa00ecba --- /dev/null +++ b/widgets/FrequencyDeltaLineEdit.hpp @@ -0,0 +1,29 @@ +#ifndef FREQUENCY_DELTA_LINE_EDIT_HPP_ +#define FREQUENCY_DELTA_LINE_EDIT_HPP_ + +#include + +#include "Radio.hpp" + +class QWidget; + +// +// MHz frequency delta line edit with validation +// +class FrequencyDeltaLineEdit final + : public QLineEdit +{ + Q_OBJECT; + Q_PROPERTY (FrequencyDelta frequency_delta READ frequency_delta WRITE frequency_delta USER true); + +public: + using FrequencyDelta = Radio::FrequencyDelta; + + explicit FrequencyDeltaLineEdit (QWidget * parent = nullptr); + + // Property frequency_delta implementation + FrequencyDelta frequency_delta () const; + void frequency_delta (FrequencyDelta); +}; + +#endif diff --git a/widgets/FrequencyLineEdit.cpp b/widgets/FrequencyLineEdit.cpp index 78f8b2e1f..1ca2ba20b 100644 --- a/widgets/FrequencyLineEdit.cpp +++ b/widgets/FrequencyLineEdit.cpp @@ -51,21 +51,3 @@ void FrequencyLineEdit::frequency (Frequency f) { setText (Radio::frequency_MHz_string (f)); } - - -FrequencyDeltaLineEdit::FrequencyDeltaLineEdit (QWidget * parent) - : QLineEdit (parent) -{ - setValidator (new MHzValidator {-std::numeric_limits::max () / 10.e6, - std::numeric_limits::max () / 10.e6, this}); -} - -auto FrequencyDeltaLineEdit::frequency_delta () const -> FrequencyDelta -{ - return Radio::frequency_delta (text (), 6); -} - -void FrequencyDeltaLineEdit::frequency_delta (FrequencyDelta d) -{ - setText (Radio::frequency_MHz_string (d)); -} diff --git a/widgets/FrequencyLineEdit.hpp b/widgets/FrequencyLineEdit.hpp index dec0feb00..7e535f5a9 100644 --- a/widgets/FrequencyLineEdit.hpp +++ b/widgets/FrequencyLineEdit.hpp @@ -8,7 +8,7 @@ class QWidget; // -// MHz frequency line edits with validation +// MHz frequency line edit with validation // class FrequencyLineEdit final : public QLineEdit @@ -26,20 +26,4 @@ public: void frequency (Frequency); }; -class FrequencyDeltaLineEdit final - : public QLineEdit -{ - Q_OBJECT; - Q_PROPERTY (FrequencyDelta frequency_delta READ frequency_delta WRITE frequency_delta USER true); - -public: - using FrequencyDelta = Radio::FrequencyDelta; - - explicit FrequencyDeltaLineEdit (QWidget * parent = nullptr); - - // Property frequency_delta implementation - FrequencyDelta frequency_delta () const; - void frequency_delta (FrequencyDelta); -}; - #endif diff --git a/widgets/HelpTextWindow.cpp b/widgets/HelpTextWindow.cpp index 98c2b38e3..d24a87a51 100644 --- a/widgets/HelpTextWindow.cpp +++ b/widgets/HelpTextWindow.cpp @@ -9,6 +9,8 @@ #include "qt_helpers.hpp" #include "widgets/MessageBox.hpp" +#include "moc_HelpTextWindow.cpp" + HelpTextWindow::HelpTextWindow (QString const& title, QString const& file_name, QFont const& font, QWidget * parent) : QLabel {parent, Qt::WindowCloseButtonHint | Qt::WindowMinimizeButtonHint} { diff --git a/widgets/HelpTextWindow.hpp b/widgets/HelpTextWindow.hpp index c5793ae97..5cc5a6dca 100644 --- a/widgets/HelpTextWindow.hpp +++ b/widgets/HelpTextWindow.hpp @@ -9,6 +9,8 @@ class QString; class HelpTextWindow final : public QLabel { + Q_OBJECT + public: HelpTextWindow (QString const& title, QString const& file_name, QFont const& = QFont {}, QWidget * parent = nullptr); }; diff --git a/widgets/RestrictedSpinBox.cpp b/widgets/RestrictedSpinBox.cpp index d3201b331..3d18ce488 100644 --- a/widgets/RestrictedSpinBox.cpp +++ b/widgets/RestrictedSpinBox.cpp @@ -17,3 +17,17 @@ QValidator::State RestrictedSpinBox::validate (QString& input, int& pos) const } return valid; } + +void RestrictedSpinBox::fixup (QString& input) const +{ + auto iter = std::lower_bound (values ().begin (), values ().end (), valueFromText (input)); + HintedSpinBox::fixup (input); + if (iter != values ().end ()) + { + input = textFromValue (*iter); + } + else + { + input = textFromValue (values ().back ()); + } +} diff --git a/widgets/RestrictedSpinBox.hpp b/widgets/RestrictedSpinBox.hpp index f856e90ce..e984c3770 100644 --- a/widgets/RestrictedSpinBox.hpp +++ b/widgets/RestrictedSpinBox.hpp @@ -20,6 +20,7 @@ public: protected: // override the base class validation QValidator::State validate (QString& input, int& pos) const override; + void fixup (QString& input) const override; }; #endif diff --git a/widgets/astro.cpp b/widgets/astro.cpp index 4ee55da4a..8c083a89a 100644 --- a/widgets/astro.cpp +++ b/widgets/astro.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "commons.h" #include "MessageBox.hpp" @@ -23,14 +24,14 @@ extern "C" { - void astrosub_(int* nyear, int* month, int* nday, double* uth, double* freqMoon, - const char* mygrid, const char* hisgrid, double* azsun, - double* elsun, double* azmoon, double* elmoon, double* azmoondx, - double* elmoondx, int* ntsky, int* ndop, int* ndop00, - double* ramoon, double* decmoon, double* dgrd, double* poloffset, - double* xnr, double* techo, double* width1, double* width2, - bool* bTx, const char* AzElFileName, const char* jpleph, - fortran_charlen_t, fortran_charlen_t, fortran_charlen_t, fortran_charlen_t); + void astrosub(int nyear, int month, int nday, double uth, double freqMoon, + const char * mygrid, size_t mygrid_len, const char * hisgrid, + size_t hisgrid_len, double * azsun, double * elsun, double * azmoon, + double * elmoon, double * azmoondx, double * elmoondx, int * ntsky, + int * ndop, int * ndop00, double * ramoon, double * decmoon, double * dgrd, + double * poloffset, double * xnr, double * techo, double * width1, + double * width2, bool bTx, const char * AzElFileName, size_t AzElFileName_len, + const char * jpleph, size_t jpleph_len); } Astro::Astro(QSettings * settings, Configuration const * configuration, QWidget * parent) @@ -75,8 +76,8 @@ void Astro::read_settings () case 1: ui_->rbFullTrack->setChecked (true); break; case 2: ui_->rbConstFreqOnMoon->setChecked (true); break; case 3: ui_->rbOwnEcho->setChecked (true); break; - case 4: ui_->rbOnDxEcho->setChecked (true); break; - case 5: ui_->rbCallDx->setChecked (true); break; + case 4: ui_->rbOnDxEcho->setChecked (true); break; + case 5: ui_->rbCallDx->setChecked (true); break; } move (settings_->value ("window/pos", pos ()).toPoint ()); } @@ -90,7 +91,7 @@ void Astro::write_settings () } auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const& hisgrid, Frequency freq, - bool dx_is_self, bool bTx, bool no_tx_QSY, int TR_period) -> Correction + bool dx_is_self, bool bTx, bool no_tx_QSY, double TR_period) -> Correction { Frequency freq_moon {freq}; double azsun,elsun,azmoon,elmoon,azmoondx,elmoondx; @@ -106,24 +107,20 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const double sec {t.time().second() + 0.001*t.time().msec()}; double uth {nhr + nmin/60.0 + sec/3600.0}; if(freq_moon < 1) freq_moon = 144000000; - int nfreq {static_cast (freq_moon / 1000000u)}; - double freq8 {static_cast (freq_moon)}; auto const& AzElFileName = QDir::toNativeSeparators (configuration_->azel_directory ().absoluteFilePath ("azel.dat")); auto const& jpleph = configuration_->data_dir ().absoluteFilePath ("JPLEPH"); - - - - QString mygrid_padded {(mygrid + " ").left (6)}; - QString hisgrid_padded {(hisgrid + " ").left (6)}; - astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(), - hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon, - &azmoondx, &elmoondx, &ntsky, &m_dop, &m_dop00, &ramoon, &decmoon, - &dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx, - AzElFileName.toLatin1().constData(), jpleph.toLatin1().constData(), 6, 6, - AzElFileName.length(), jpleph.length()); + astrosub(nyear, month, nday, uth, static_cast (freq_moon), + mygrid.toLatin1 ().constData (), mygrid.size (), + hisgrid.toLatin1().constData(), hisgrid.size (), + &azsun, &elsun, &azmoon, &elmoon, + &azmoondx, &elmoondx, &ntsky, &m_dop, &m_dop00, &ramoon, &decmoon, + &dgrd, &poloffset, &xnr, &techo, &width1, &width2, + bTx, + AzElFileName.toLatin1().constData(), AzElFileName.size (), + jpleph.toLatin1().constData(), jpleph.size ()); - if(hisgrid_padded==" ") { + if(!hisgrid.size ()) { azmoondx=0.0; elmoondx=0.0; m_dop=0; @@ -151,8 +148,8 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const "Dec: " << decmoon << "\n" "SunAz: " << azsun << "\n" "SunEl: " << elsun << "\n" - "Freq: " << nfreq << "\n"; - if(nfreq>=50) { //Suppress data not relevant below VHF + "Freq: " << freq / 1.e6 << "\n"; + if(freq>=5000000ull) { //Suppress data not relevant below VHF out << "Tsky: " << ntsky << "\n" "Dpol: " << poloffset << "\n" "MNR: " << xnr << "\n" @@ -211,11 +208,9 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const // // use a base time of (secs-since-epoch + 2) so as to be sure // we do the next period if we calculate just before it starts - auto sec_since_epoch = t.toMSecsSinceEpoch () / 1000 + 2; - auto target_sec = sec_since_epoch - sec_since_epoch % TR_period + TR_period / 2; + auto sec_since_epoch = t.toMSecsSinceEpoch ()/1000 + 2; + auto target_sec = sec_since_epoch - fmod(double(sec_since_epoch),TR_period) + 0.5*TR_period; auto target_date_time = QDateTime::fromMSecsSinceEpoch (target_sec * 1000, Qt::UTC); - QString date {target_date_time.date().toString("yyyy MMM dd").trimmed ()}; - QString utc {target_date_time.time().toString().trimmed ()}; int nyear {target_date_time.date().year()}; int month {target_date_time.date().month()}; int nday {target_date_time.date().day()}; @@ -223,12 +218,15 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const int nmin {target_date_time.time().minute()}; double sec {target_date_time.time().second() + 0.001*target_date_time.time().msec()}; double uth {nhr + nmin/60.0 + sec/3600.0}; - astrosub_(&nyear, &month, &nday, &uth, &freq8, mygrid_padded.toLatin1().constData(), - hisgrid_padded.toLatin1().constData(), &azsun, &elsun, &azmoon, &elmoon, + astrosub(nyear, month, nday, uth, static_cast (freq_moon), + mygrid.toLatin1 ().constData (), mygrid.size (), + hisgrid.toLatin1().constData(), hisgrid.size (), + &azsun, &elsun, &azmoon, &elmoon, &azmoondx, &elmoondx, &ntsky, &m_dop, &m_dop00, &ramoon, &decmoon, - &dgrd, &poloffset, &xnr, &techo, &width1, &width2, &bTx, - "", jpleph.toLatin1().constData(), 6, 6, - 0, jpleph.length()); + &dgrd, &poloffset, &xnr, &techo, &width1, &width2, + bTx, + AzElFileName.toLatin1().constData(), AzElFileName.size (), + jpleph.toLatin1().constData(), jpleph.size ()); FrequencyDelta offset {0}; switch (m_DopplerMethod) { @@ -254,7 +252,7 @@ auto Astro::astroUpdate(QDateTime const& t, QString const& mygrid, QString const } correction.tx = -offset; - qDebug () << "correction.tx (no tx qsy):" << correction.tx; + qDebug () << "correction.tx (no tx qsy):" << correction.tx; } } return correction; diff --git a/widgets/astro.h b/widgets/astro.h index 03d8c66c6..4f7f71d5b 100644 --- a/widgets/astro.h +++ b/widgets/astro.h @@ -44,7 +44,7 @@ public: bool dx_is_self, bool bTx, bool no_tx_QSY, - int TR_period); + double TR_period); bool doppler_tracking () const; Q_SLOT void nominal_frequency (Frequency rx, Frequency tx); diff --git a/widgets/displaytext.cpp b/widgets/displaytext.cpp index eca4dd4f5..53d7cd5cd 100644 --- a/widgets/displaytext.cpp +++ b/widgets/displaytext.cpp @@ -271,7 +271,7 @@ QString DisplayText::appendWorkedB4 (QString message, QString call, QString cons if(call.length()<3) return message; if(!call.contains(QRegExp("[0-9]|[A-Z]"))) return message; - auto const& looked_up = logBook.countries ().lookup (call); + auto const& looked_up = logBook.countries ()->lookup (call); logBook.match (call, currentMode, grid, looked_up, callB4, countryB4, gridB4, continentB4, CQZoneB4, ITUZoneB4); logBook.match (call, currentMode, grid, looked_up, callB4onBand, countryB4onBand, gridB4onBand, continentB4onBand, CQZoneB4onBand, ITUZoneB4onBand, currentBand); @@ -374,6 +374,7 @@ QString DisplayText::appendWorkedB4 (QString message, QString call, QString cons appendage += countryName; } } + m_CQPriority=DecodeHighlightingModel::highlight_name(top_highlight); // use a nbsp to save the start of appended text so we can find // it again later, align appended data at a fixed column if @@ -423,6 +424,7 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"}; if(!dxGrid.contains(grid_regexp)) dxGrid=""; message = message.left (message.indexOf (QChar::Nbsp)); // strip appended info + m_CQPriority=""; if (CQcall) { if (displayDXCCEntity) @@ -447,6 +449,7 @@ void DisplayText::displayDecodedText(DecodedText const& decodedText, QString con set_colours (m_config, &bg, &fg, types); } } + appendText (message.trimmed (), bg, fg, decodedText.call (), dxCall); } diff --git a/widgets/displaytext.h b/widgets/displaytext.h index cd3426af9..8b580b8a2 100644 --- a/widgets/displaytext.h +++ b/widgets/displaytext.h @@ -35,6 +35,7 @@ public: void displayQSY(QString text); void displayFoxToBeCalled(QString t, QColor bg = QColor {}, QColor fg = QColor {}); void new_period (); + QString CQPriority(){return m_CQPriority;}; Q_SIGNAL void selectCallsign (Qt::KeyboardModifiers); Q_SIGNAL void erased (); @@ -51,6 +52,7 @@ private: Configuration const * m_config; bool m_bPrincipalPrefix; + QString m_CQPriority; QString appendWorkedB4(QString message, QString callsign , QString const& grid, QColor * bg, QColor * fg , LogBook const& logBook, QString const& currentBand @@ -63,6 +65,4 @@ private: int modified_vertical_scrollbar_max_; }; - extern QHash m_LoTW; - #endif // DISPLAYTEXT_H diff --git a/widgets/fastgraph.cpp b/widgets/fastgraph.cpp index e599138f2..9efe5fc63 100644 --- a/widgets/fastgraph.cpp +++ b/widgets/fastgraph.cpp @@ -86,9 +86,9 @@ void FastGraph::on_greenZeroSlider_valueChanged(int value) ui->fastPlot->draw(); } -void FastGraph::setTRPeriod(int n) +void FastGraph::setTRPeriod(double p) { - m_TRperiod=n; + m_TRperiod=p; ui->fastPlot->setTRperiod(m_TRperiod); } diff --git a/widgets/fastgraph.h b/widgets/fastgraph.h index 7ed32671f..b5f7c0b8d 100644 --- a/widgets/fastgraph.h +++ b/widgets/fastgraph.h @@ -22,7 +22,7 @@ public: void plotSpec(bool diskData, int UTCdisk); void saveSettings(); - void setTRPeriod(int n); + void setTRPeriod(double p); void setMode(QString mode); signals: @@ -40,8 +40,8 @@ protected: private: QSettings * m_settings; - float m_ave; - qint32 m_TRperiod; + float m_ave; + double m_TRperiod; QScopedPointer ui; }; diff --git a/widgets/fastplot.cpp b/widgets/fastplot.cpp index 1437834d8..a388f0ac7 100644 --- a/widgets/fastplot.cpp +++ b/widgets/fastplot.cpp @@ -135,11 +135,11 @@ void FPlotter::setGreenZero(int n) m_bPaint2=true; } -void FPlotter::setTRperiod(int n) +void FPlotter::setTRperiod(double p) { - m_TRperiod=n; + m_TRperiod=p; m_pixPerSecond=12000.0/512.0; - if(m_TRperiod<30) m_pixPerSecond=12000.0/256.0; + if(m_TRperiod<30.0) m_pixPerSecond=12000.0/256.0; drawScale(); update(); } diff --git a/widgets/fastplot.h b/widgets/fastplot.h index b13913388..f24fcc24e 100644 --- a/widgets/fastplot.h +++ b/widgets/fastplot.h @@ -37,7 +37,7 @@ public: void setPlotZero(int plotZero); void setPlotGain(int plotGain); void setGreenZero(int n); - void setTRperiod(int n); + void setTRperiod(double p); void drawScale(); void setMode(QString mode); @@ -68,6 +68,7 @@ private: QString m_mode; double m_pixPerSecond; + double m_TRperiod; qint32 m_hdivs; qint32 m_h; @@ -75,7 +76,6 @@ private: qint32 m_h2; QPixmap m_HorizPixmap; qint32 m_jh0; - qint32 m_TRperiod; bool m_bPaint2; }; diff --git a/widgets/logqso.cpp b/widgets/logqso.cpp index eae82aacc..14c92358b 100644 --- a/widgets/logqso.cpp +++ b/widgets/logqso.cpp @@ -1,12 +1,9 @@ #include "logqso.h" -#include -#include #include #include #include #include -#include #include "logbook/logbook.h" #include "MessageBox.hpp" @@ -18,40 +15,18 @@ #include "ui_logqso.h" #include "moc_logqso.cpp" -namespace -{ - using dist_type = std::uniform_int_distribution; - std::random_device rd; - std::mt19937 twister (rd ()); - dist_type int_distribution; -} - LogQSO::LogQSO(QString const& programTitle, QSettings * settings - , Configuration const * config, QWidget *parent) + , Configuration const * config, LogBook * log, QWidget *parent) : QDialog {parent, Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint} , ui(new Ui::LogQSO) - , ok_ {new QPushButton {"OK", this}} - , cancel_ {new QPushButton {"Cancel", this}} , m_settings (settings) , m_config {config} + , m_log {log} { ui->setupUi(this); setWindowTitle(programTitle + " - Log QSO"); - ui->grid->setValidator (new MaidenheadLocatorValidator {this}); - - ok_->setAutoDefault (false); - ok_->setFocusPolicy (Qt::ClickFocus); - cancel_->setAutoDefault (false); - ui->button_layout->addStretch (); - ui->button_layout->addWidget (ok_); - ui->button_layout->addStretch (); - ui->button_layout->addWidget (cancel_); - ui->button_layout->addStretch (); - loadSettings (); - - connect (ok_, &QAbstractButton::clicked, [this] (bool) {accept ();}); - connect (cancel_, &QAbstractButton::clicked, [this] (bool) {reject ();}); + ui->grid->setValidator (new MaidenheadLocatorValidator {this}); } LogQSO::~LogQSO () @@ -83,8 +58,7 @@ void LogQSO::storeSettings () const void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString mode, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff, - Radio::Frequency dialFreq, bool noSuffix, QString xSent, QString xRcvd, - CabrilloLog * cabrillo_log) + Radio::Frequency dialFreq, bool noSuffix, QString xSent, QString xRcvd) { if(!isHidden()) return; ui->call->setText (hisCall); @@ -126,7 +100,6 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString ui->loggedOperator->setText(m_config->opCall()); ui->exchSent->setText (xSent); ui->exchRcvd->setText (xRcvd); - m_cabrilloLog = cabrillo_log; using SpOp = Configuration::SpecialOperatingActivity; auto special_op = m_config->special_op_id (); @@ -139,22 +112,7 @@ void LogQSO::initLogQSO(QString const& hisCall, QString const& hisGrid, QString } else { - // randomize accessible name of buttons - ok_->setAccessibleName (QString::number (int_distribution (twister))); - cancel_->setAccessibleName (QString::number (int_distribution (twister))); - // random sibling order of buttons - if (int_distribution (twister, dist_type::param_type {0, 1})) ok_->stackUnder (cancel_); else cancel_->stackUnder (ok_); - // random shuffle of layout items - for (int item = ui->button_layout->count () - 1; item > 0; --item) - { - auto other_item = int_distribution (twister, dist_type::param_type {0, item}); - if (item != other_item) - { - ui->button_layout->insertItem (other_item, ui->button_layout->takeAt (item)); - ui->button_layout->insertItem (item, ui->button_layout->takeAt (other_item + 1)); - } - } - show (); + show(); } } @@ -199,7 +157,7 @@ void LogQSO::accept() return; // without accepting } - if (!m_cabrilloLog->add_QSO (m_dialFreq, dateTimeOff, hisCall, xsent, xrcvd)) + if (!m_log->contest_log ()->add_QSO (m_dialFreq, mode, dateTimeOff, hisCall, xsent, xrcvd)) { show (); MessageBox::warning_message (this, tr ("Invalid QSO Data"), @@ -244,23 +202,23 @@ void LogQSO::accept() , m_myGrid , xsent , xrcvd - , LogBook::QSOToADIF (hisCall - , hisGrid - , mode - , rptSent - , rptRcvd - , dateTimeOn - , dateTimeOff - , band - , m_comments - , name - , strDialFreq - , m_myCall - , m_myGrid - , m_txPower - , operator_call - , xsent - , xrcvd)); + , m_log->QSOToADIF (hisCall + , hisGrid + , mode + , rptSent + , rptRcvd + , dateTimeOn + , dateTimeOff + , band + , m_comments + , name + , strDialFreq + , m_myCall + , m_myGrid + , m_txPower + , operator_call + , xsent + , xrcvd)); QDialog::accept(); } diff --git a/widgets/logqso.h b/widgets/logqso.h index 5cbb2044d..739a601f7 100644 --- a/widgets/logqso.h +++ b/widgets/logqso.h @@ -17,20 +17,19 @@ namespace Ui { class QSettings; class Configuration; class QByteArray; -class CabrilloLog; -class QPushButton; +class LogBook; class LogQSO : public QDialog { Q_OBJECT public: - explicit LogQSO(QString const& programTitle, QSettings *, Configuration const *, QWidget *parent = 0); + explicit LogQSO(QString const& programTitle, QSettings *, Configuration const *, LogBook *, QWidget *parent = 0); ~LogQSO(); void initLogQSO(QString const& hisCall, QString const& hisGrid, QString mode, QString const& rptSent, QString const& rptRcvd, QDateTime const& dateTimeOn, QDateTime const& dateTimeOff, Radio::Frequency dialFreq, - bool noSuffix, QString xSent, QString xRcvd, CabrilloLog *); + bool noSuffix, QString xSent, QString xRcvd); public slots: void accept(); @@ -53,16 +52,14 @@ private: void storeSettings () const; QScopedPointer ui; - QPushButton * ok_; - QPushButton * cancel_; QSettings * m_settings; Configuration const * m_config; + LogBook * m_log; QString m_txPower; QString m_comments; Radio::Frequency m_dialFreq; QString m_myCall; QString m_myGrid; - CabrilloLog * m_cabrilloLog; }; #endif // LogQSO_H diff --git a/widgets/logqso.ui b/widgets/logqso.ui index 7d249677d..a03a3028a 100644 --- a/widgets/logqso.ui +++ b/widgets/logqso.ui @@ -461,7 +461,14 @@ - + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + @@ -481,5 +488,38 @@ cbComments - + + + buttonBox + accepted() + LogQSO + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + LogQSO + reject() + + + 316 + 260 + + + 286 + 274 + + + + diff --git a/widgets/mainwindow.cpp b/widgets/mainwindow.cpp index 8cc5bc330..e3c4af390 100644 --- a/widgets/mainwindow.cpp +++ b/widgets/mainwindow.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #include "revision_utils.hpp" #include "qt_helpers.hpp" @@ -99,14 +101,14 @@ extern "C" { void genft8_(char* msg, int* i3, int* n3, char* msgsent, char ft8msgbits[], int itone[], fortran_charlen_t, fortran_charlen_t); - void genft4_(char* msg, int* ichk, char* msgsent, int itone[], + void genft4_(char* msg, int* ichk, char* msgsent, char ft4msgbits[], int itone[], fortran_charlen_t, fortran_charlen_t); - void gen_ft8wave_(int itone[], int* nsym, int* nsps, float* fsample, float* f0, + void gen_ft8wave_(int itone[], int* nsym, int* nsps, float* bt, float* fsample, float* f0, float xjunk[], float wave[], int* icmplx, int* nwave); void gen_ft4wave_(int itone[], int* nsym, int* nsps, float* fsample, float* f0, - float wave[], int* nwave); + float xjunk[], float wave[], int* icmplx, int* nwave); void gen4_(char* msg, int* ichk, char* msgsent, int itone[], int* itext, fortran_charlen_t, fortran_charlen_t); @@ -145,7 +147,7 @@ extern "C" { float* level, float* sigdb, float* snr, float* dfreq, float* width); - void fast_decode_(short id2[], int narg[], int* ntrperiod, + void fast_decode_(short id2[], int narg[], double * trperiod, char msg[], char mycall[], char hiscall[], fortran_charlen_t, fortran_charlen_t, fortran_charlen_t); void degrade_snr_(short d2[], int* n, float* db, float* bandwidth); @@ -200,6 +202,7 @@ namespace QRegExp message_alphabet {"[- @A-Za-z0-9+./?#<>;]*"}; // grid exact match excluding RR73 QRegularExpression grid_regexp {"\\A(?![Rr]{2}73)[A-Ra-r]{2}[0-9]{2}([A-Xa-x]{2}){0,1}\\z"}; + auto quint32_max = std::numeric_limits::max (); bool message_is_73 (int type, QStringList const& msg_parts) { @@ -233,8 +236,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, m_configurations_button {0}, m_settings {multi_settings->settings ()}, ui(new Ui::MainWindow), - m_logBook {&m_config}, m_config {&m_network_manager, temp_directory, m_settings, &m_logBook, this}, + m_logBook {&m_config}, m_WSPR_band_hopping {m_settings, &m_config, this}, m_WSPR_tx_next {false}, m_rigErrorMessageBox {MessageBox::Critical, tr ("Rig Control Error") @@ -243,10 +246,10 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, m_echoGraph (new EchoGraph(m_settings)), m_fastGraph (new FastGraph(m_settings)), // no parent so that it has a taskbar icon - m_logDlg (new LogQSO (program_title (), m_settings, &m_config, nullptr)), + m_logDlg (new LogQSO (program_title (), m_settings, &m_config, &m_logBook, nullptr)), m_lastDialFreq {0}, m_dialFreqRxWSPR {0}, - m_detector {new Detector {RX_SAMPLE_RATE, NTMAX, downSampleFactor}}, + m_detector {new Detector {RX_SAMPLE_RATE, double(NTMAX), downSampleFactor}}, m_FFTSize {6192 / 2}, // conservative value to avoid buffer overruns m_soundInput {new SoundInput}, m_modulator {new Modulator {TX_SAMPLE_RATE, NTMAX}}, @@ -257,6 +260,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, m_freqTxNominal {0}, m_s6 {0.}, m_tRemaining {0.}, + m_TRperiod {60.0}, m_DTtol {3.0}, m_waterfallAvg {1}, m_ntx {1}, @@ -268,7 +272,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, m_nutc0 {999999}, m_ntr {0}, m_tx {0}, - m_TRperiod {60}, m_inGain {0}, m_secID {0}, m_idleMinutes {0}, @@ -409,9 +412,11 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, m_config.udp_server_name (), m_config.udp_server_port (), this}}, psk_Reporter {new PSK_Reporter {m_messageClient, this}}, - m_manual {&m_network_manager} + m_manual {&m_network_manager}, + m_block_udp_status_updates {false} { ui->setupUi(this); + setUnifiedTitleAndToolBarOnMac (true); createStatusBar(); add_child_to_event_filter (this); ui->dxGridEntry->setValidator (new MaidenheadLocatorValidator {this}); @@ -499,6 +504,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, }); // Network message handlers + m_messageClient->enable (m_config.accept_udp_requests ()); connect (m_messageClient, &MessageClient::clear_decodes, [this] (quint8 window) { ++window; if (window & 1) @@ -511,52 +517,51 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, } }); connect (m_messageClient, &MessageClient::reply, this, &MainWindow::replyToCQ); + connect (m_messageClient, &MessageClient::close, this, &MainWindow::close); connect (m_messageClient, &MessageClient::replay, this, &MainWindow::replayDecodes); connect (m_messageClient, &MessageClient::location, this, &MainWindow::locationChange); connect (m_messageClient, &MessageClient::halt_tx, [this] (bool auto_only) { - if (m_config.accept_udp_requests ()) { - if (auto_only) { - if (ui->autoButton->isChecked ()) { - ui->autoButton->click(); - } - } else { - ui->stopTxButton->click(); + if (auto_only) { + if (ui->autoButton->isChecked ()) { + ui->autoButton->click(); } + } else { + ui->stopTxButton->click(); } }); connect (m_messageClient, &MessageClient::error, this, &MainWindow::networkError); connect (m_messageClient, &MessageClient::free_text, [this] (QString const& text, bool send) { - if (m_config.accept_udp_requests ()) { - tx_watchdog (false); - // send + non-empty text means set and send the free text - // message, !send + non-empty text means set the current free - // text message, send + empty text means send the current free - // text message without change, !send + empty text means clear - // the current free text message - if (0 == ui->tabWidget->currentIndex ()) { - if (!text.isEmpty ()) { - ui->tx5->setCurrentText (text); - } - if (send) { - ui->txb5->click (); - } else if (text.isEmpty ()) { - ui->tx5->setCurrentText (text); - } - } else if (1 == ui->tabWidget->currentIndex ()) { - if (!text.isEmpty ()) { - ui->freeTextMsg->setCurrentText (text); - } - if (send) { - ui->rbFreeText->click (); - } else if (text.isEmpty ()) { - ui->freeTextMsg->setCurrentText (text); - } + tx_watchdog (false); + // send + non-empty text means set and send the free text + // message, !send + non-empty text means set the current free + // text message, send + empty text means send the current free + // text message without change, !send + empty text means clear + // the current free text message + if (0 == ui->tabWidget->currentIndex ()) { + if (!text.isEmpty ()) { + ui->tx5->setCurrentText (text); + } + if (send) { + ui->txb5->click (); + } else if (text.isEmpty ()) { + ui->tx5->setCurrentText (text); + } + } else if (1 == ui->tabWidget->currentIndex ()) { + if (!text.isEmpty ()) { + ui->freeTextMsg->setCurrentText (text); + } + if (send) { + ui->rbFreeText->click (); + } else if (text.isEmpty ()) { + ui->freeTextMsg->setCurrentText (text); } - QApplication::alert (this); } + QApplication::alert (this); }); connect (m_messageClient, &MessageClient::highlight_callsign, ui->decodedTextBrowser, &DisplayText::highlight_callsign); + connect (m_messageClient, &MessageClient::switch_configuration, m_multi_settings, &MultiSettings::select_configuration); + connect (m_messageClient, &MessageClient::configure, this, &MainWindow::remote_configure); // Hook up WSPR band hopping connect (ui->band_hopping_schedule_push_button, &QPushButton::clicked @@ -707,6 +712,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, connect (&m_config, &Configuration::transceiver_failure, this, &MainWindow::handle_transceiver_failure); connect (&m_config, &Configuration::udp_server_changed, m_messageClient, &MessageClient::set_server); connect (&m_config, &Configuration::udp_server_port_changed, m_messageClient, &MessageClient::set_server_port); + connect (&m_config, &Configuration::accept_udp_requests_changed, m_messageClient, &MessageClient::enable); // set up configurations menu connect (m_multi_settings, &MultiSettings::configurationNameChanged, [this] (QString const& name) { @@ -717,6 +723,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, else { config_label.hide (); } + statusUpdate (); }); m_multi_settings->create_menu_actions (this, ui->menuConfig); m_configurations_button = m_rigErrorMessageBox.addButton (tr ("Configurations...") @@ -877,7 +884,6 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, connect (&m_wav_future_watcher, &QFutureWatcher::finished, this, &MainWindow::diskDat); connect(&watcher3, SIGNAL(finished()),this,SLOT(fast_decode_done())); -// Q_EMIT startAudioInputStream (m_config.audio_input_device (), m_framesAudioInputBuffered, &m_detector, m_downSampleFactor, m_config.audio_input_channel ()); Q_EMIT startAudioInputStream (m_config.audio_input_device (), m_framesAudioInputBuffered, m_detector, m_downSampleFactor, m_config.audio_input_channel ()); Q_EMIT initializeAudioOutputStream (m_config.audio_output_device (), AudioDevice::Mono == m_config.audio_output_channel () ? 1 : 2, m_msAudioOutputBuffered); Q_EMIT transmitFrequency (ui->TxFreqSpinBox->value () - m_XIT); @@ -901,20 +907,8 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, if(m_bFast9) m_bFastMode=true; ui->cbFast9->setChecked(m_bFast9 or m_bFastMode); - if(m_mode=="FT4") on_actionFT4_triggered(); - if(m_mode=="FT8") on_actionFT8_triggered(); - if(m_mode=="JT4") on_actionJT4_triggered(); - if(m_mode=="JT9") on_actionJT9_triggered(); - if(m_mode=="JT65") on_actionJT65_triggered(); - if(m_mode=="JT9+JT65") on_actionJT9_JT65_triggered(); - if(m_mode=="WSPR") on_actionWSPR_triggered(); - if(m_mode=="WSPR-LF") on_actionWSPR_LF_triggered(); - if(m_mode=="ISCAT") on_actionISCAT_triggered(); - if(m_mode=="MSK144") on_actionMSK144_triggered(); - if(m_mode=="QRA64") on_actionQRA64_triggered(); - if(m_mode=="Echo") on_actionEcho_triggered(); + set_mode (m_mode); if(m_mode=="Echo") monitor(false); //Don't auto-start Monitor in Echo mode. - if(m_mode=="FreqCal") on_actionFreqCal_triggered(); ui->sbSubmode->setValue (vhf ? m_nSubMode : 0); if(m_mode=="MSK144") { @@ -979,6 +973,7 @@ MainWindow::MainWindow(QDir const& temp_directory, bool multiple, QTimer::singleShot (0, this, SLOT (not_GA_warning_message ())); } + ui->pbBestSP->setVisible(m_mode=="FT4"); if(!ui->cbMenus->isChecked()) { ui->cbMenus->setChecked(true); ui->cbMenus->setChecked(false); @@ -992,11 +987,17 @@ void MainWindow::not_GA_warning_message () // MessageBox::critical_message (this, // "

" // "This is a pre-release version of WSJT-X 2.1.0 made " - // "available for testing purposes. It will become nonfunctional " - // "after May 1, 2019."); - // QDateTime now=QDateTime::currentDateTime(); - // QDateTime timeout=QDateTime(QDate(2019,5,1)); - // if(now.daysTo(timeout) < 0) Q_EMIT finished(); + // "available for testing purposes. By design it will " + // "be nonfunctional during the 2019 ARRL June VHF contest " + // "(June 8-10) and Field Day (June 22-23) weekends. It " + // "will be permanently nonfunctional after July 21, 2019."); + // auto now = QDateTime::currentDateTimeUtc (); + // if ((QDateTime {{2019, 6, 8}, {18, 0}, Qt::UTC} <= now + // && now < QDateTime {{2019, 6, 10}, {3, 0}, Qt::UTC}) + // || now >= QDateTime {{2019, 7, 21}, {0, 0}, Qt::UTC}) + // { + // Q_EMIT finished (); + // } } void MainWindow::initialize_fonts () @@ -1322,7 +1323,7 @@ void MainWindow::fixStop() } else if (m_mode=="FT8") { m_hsymStop=50; } else if (m_mode=="FT4") { - m_hsymStop=18; + m_hsymStop=21; } } @@ -1354,7 +1355,7 @@ void MainWindow::dataSink(qint64 frames) } // Get power, spectrum, and ihsym - int trmin=m_TRperiod/60; + int trmin=m_TRperiod/60.0; // int k (frames - 1); dec_data.params.nfa=m_wideGraph->nStartFreq(); dec_data.params.nfb=m_wideGraph->Fmax(); @@ -1451,19 +1452,20 @@ void MainWindow::dataSink(qint64 frames) if(!m_mode.startsWith ("WSPR")) decode(); //Start decoder if(!m_diskData) { //Always save; may delete later - if(m_mode=="FT8" or m_mode=="FT4") { - int n=now.time().second() % m_TRperiod; + int n=fmod(double(now.time().second()),m_TRperiod); if(n<(m_TRperiod/2)) n=n+m_TRperiod; auto const& period_start=now.addSecs(-n); m_fnameWE=m_config.save_directory().absoluteFilePath (period_start.toString("yyMMdd_hhmmss")); +// qDebug() << "datasink 2" << QDateTime::currentDateTimeUtc().toString("ss.zzz") +// << n << period_start.toString("ss.zzz"); } else { - auto const& period_start = now.addSecs (-(now.time ().minute () % (m_TRperiod / 60)) * 60); + auto const& period_start = now.addSecs (-(now.time ().minute () % (int(m_TRperiod) / 60)) * 60); m_fnameWE=m_config.save_directory ().absoluteFilePath (period_start.toString ("yyMMdd_hhmm")); } m_fileToSave.clear (); int samples=m_TRperiod*12000; - if(m_mode=="FT4") samples=18*3456; + if(m_mode=="FT4") samples=21*3456; // the following is potential a threading hazard - not a good // idea to pass pointer to be processed in another thread @@ -1588,7 +1590,7 @@ void MainWindow::fastSink(qint64 frames) int ihr=tnow.toString("hh").toInt(); int imin=tnow.toString("mm").toInt(); int isec=tnow.toString("ss").toInt(); - isec=isec - isec%m_TRperiod; + isec=isec - fmod(double(isec),m_TRperiod); int nutc0=10000*ihr + 100*imin + isec; if(m_diskData) nutc0=m_UTCdisk; char line[80]; @@ -1668,7 +1670,7 @@ void MainWindow::fastSink(qint64 frames) if(decodeNow or m_bFastDone) { if(!m_diskData) { QDateTime now {QDateTime::currentDateTimeUtc()}; - int n=now.time().second() % m_TRperiod; + int n=fmod(double(now.time().second()),m_TRperiod); if(n<(m_TRperiod/2)) n=n+m_TRperiod; auto const& period_start = now.addSecs (-n); m_fnameWE = m_config.save_directory ().absoluteFilePath (period_start.toString ("yyMMdd_hhmmss")); @@ -1678,11 +1680,11 @@ void MainWindow::fastSink(qint64 frames) // the following is potential a threading hazard - not a good // idea to pass pointer to be processed in another thread m_saveWAVWatcher.setFuture (QtConcurrent::run (std::bind (&MainWindow::save_wave_file, - this, m_fnameWE, &dec_data.d2[0], m_TRperiod*12000, m_config.my_callsign(), + this, m_fnameWE, &dec_data.d2[0], int(m_TRperiod*12000.0), m_config.my_callsign(), m_config.my_grid(), m_mode, m_nSubMode, m_freqNominal, m_hisCall, m_hisGrid))); } if(m_mode!="MSK144") { - killFileTimer.start (3*1000*m_TRperiod/4); //Kill 3/4 period from now + killFileTimer.start (int(750.0*m_TRperiod)); //Kill 3/4 period from now } } m_bFastDone=false; @@ -1750,18 +1752,7 @@ void MainWindow::on_actionSettings_triggered() //Setup Dialog bool b = vhf && (m_mode=="JT4" or m_mode=="JT65" or m_mode=="ISCAT" or m_mode=="JT9" or m_mode=="MSK144" or m_mode=="QRA64"); if(b) VHF_features_enabled(b); - if(m_mode=="FT8") on_actionFT8_triggered(); - if(m_mode=="JT4") on_actionJT4_triggered(); - if(m_mode=="JT9") on_actionJT9_triggered(); - if(m_mode=="JT9+JT65") on_actionJT9_JT65_triggered(); - if(m_mode=="JT65") on_actionJT65_triggered(); - if(m_mode=="QRA64") on_actionQRA64_triggered(); - if(m_mode=="FreqCal") on_actionFreqCal_triggered(); - if(m_mode=="ISCAT") on_actionISCAT_triggered(); - if(m_mode=="MSK144") on_actionMSK144_triggered(); - if(m_mode=="WSPR") on_actionWSPR_triggered(); - if(m_mode=="WSPR-LF") on_actionWSPR_LF_triggered(); - if(m_mode=="Echo") on_actionEcho_triggered(); + set_mode (m_mode); if(b) VHF_features_enabled(b); m_config.transceiver_online (); @@ -1891,9 +1882,20 @@ void MainWindow::keyPressEvent (QKeyEvent * e) } int n; - bool bAltF1F5=m_config.alternate_bindings(); + bool bAltF1F6=m_config.alternate_bindings(); switch(e->key()) { + case Qt::Key_B: + if(m_mode=="FT4" && e->modifiers() & Qt::AltModifier) { + on_pbBestSP_clicked(); + } + return; + case Qt::Key_C: + if(m_mode=="FT4" && e->modifiers() & Qt::AltModifier) { + bool b=ui->cbFirst->isChecked(); + ui->cbFirst->setChecked(!b); + } + return; case Qt::Key_D: if(m_mode != "WSPR" && e->modifiers() & Qt::ShiftModifier) { if(!m_decoderBusy) { @@ -1905,7 +1907,7 @@ void MainWindow::keyPressEvent (QKeyEvent * e) } break; case Qt::Key_F1: - if(bAltF1F5) { + if(bAltF1F6) { auto_tx_mode(true); on_txb6_clicked(); return; @@ -1914,7 +1916,7 @@ void MainWindow::keyPressEvent (QKeyEvent * e) return; } case Qt::Key_F2: - if(bAltF1F5) { + if(bAltF1F6) { auto_tx_mode(true); on_txb2_clicked(); return; @@ -1923,7 +1925,7 @@ void MainWindow::keyPressEvent (QKeyEvent * e) return; } case Qt::Key_F3: - if(bAltF1F5) { + if(bAltF1F6) { auto_tx_mode(true); on_txb3_clicked(); return; @@ -1932,7 +1934,7 @@ void MainWindow::keyPressEvent (QKeyEvent * e) return; } case Qt::Key_F4: - if(bAltF1F5) { + if(bAltF1F6) { auto_tx_mode(true); on_txb4_clicked(); return; @@ -1942,7 +1944,7 @@ void MainWindow::keyPressEvent (QKeyEvent * e) return; } case Qt::Key_F5: - if(bAltF1F5) { + if(bAltF1F6) { auto_tx_mode(true); on_txb5_clicked(); return; @@ -1951,11 +1953,16 @@ void MainWindow::keyPressEvent (QKeyEvent * e) return; } case Qt::Key_F6: - if(e->modifiers() & Qt::ShiftModifier) { - on_actionDecode_remaining_files_in_directory_triggered(); - return; + if(bAltF1F6) { + bool b=ui->cbFirst->isChecked(); + ui->cbFirst->setChecked(!b); + } else { + if(e->modifiers() & Qt::ShiftModifier) { + on_actionDecode_remaining_files_in_directory_triggered(); + } else { + on_actionOpen_next_in_directory_triggered(); + } } - on_actionOpen_next_in_directory_triggered(); return; case Qt::Key_F11: if((e->modifiers() & Qt::ControlModifier) and (e->modifiers() & Qt::ShiftModifier)) { @@ -1966,7 +1973,7 @@ void MainWindow::keyPressEvent (QKeyEvent * e) if(e->modifiers() & Qt::ControlModifier) n+=100; if(e->modifiers() & Qt::ShiftModifier) { int offset=60; - if(m_mode=="FT4") offset=120; + if(m_mode=="FT4") offset=90; ui->TxFreqSpinBox->setValue(ui->TxFreqSpinBox->value()-offset); } else{ bumpFqso(n); @@ -1982,7 +1989,7 @@ void MainWindow::keyPressEvent (QKeyEvent * e) if(e->modifiers() & Qt::ControlModifier) n+=100; if(e->modifiers() & Qt::ShiftModifier) { int offset=60; - if(m_mode=="FT4") offset=120; + if(m_mode=="FT4") offset=90; ui->TxFreqSpinBox->setValue(ui->TxFreqSpinBox->value()+offset); } else { bumpFqso(n); @@ -1996,11 +2003,6 @@ void MainWindow::keyPressEvent (QKeyEvent * e) on_stopTxButton_clicked(); abortQSO(); return; - case Qt::Key_X: - if(e->modifiers() & Qt::AltModifier) { -// foxTest(); - return; - } case Qt::Key_E: if((e->modifiers() & Qt::ShiftModifier) and SpecOp::FOX > m_config.special_op_id()) { ui->txFirstCheckBox->setChecked(false); @@ -2047,6 +2049,15 @@ void MainWindow::keyPressEvent (QKeyEvent * e) on_actionOpen_triggered(); return; } + else if(e->modifiers() & Qt::AltModifier) { + bool ok; + auto call = QInputDialog::getText (this, tr ("Change Operator"), tr ("New operator:"), + QLineEdit::Normal, m_config.opCall (), &ok); + if (ok) { + m_config.opCall (call); + } + return; + } break; case Qt::Key_V: if(e->modifiers() & Qt::AltModifier) { @@ -2205,7 +2216,6 @@ void MainWindow::createStatusBar() //createStatusBar statusBar()->addPermanentWidget(&progressBar); progressBar.setMinimumSize (QSize {150, 18}); - progressBar.setFormat ("%v/%m"); statusBar ()->addPermanentWidget (&watchdog_label); update_watchdog_label (); @@ -2516,16 +2526,14 @@ void MainWindow::on_actionAstronomical_data_toggled (bool checked) void MainWindow::on_fox_log_action_triggered() { - if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config}); if (!m_foxLogWindow) { - m_foxLogWindow.reset (new FoxLogWindow {m_settings, &m_config, m_foxLog.data ()}); + m_foxLogWindow.reset (new FoxLogWindow {m_settings, &m_config, m_logBook.fox_log ()}); // Connect signals from fox log window connect (this, &MainWindow::finished, m_foxLogWindow.data (), &FoxLogWindow::close); connect (m_foxLogWindow.data (), &FoxLogWindow::reset_log_model, [this] () { - if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config}); - m_foxLog->reset (); + m_logBook.fox_log ()->reset (); }); } m_foxLogWindow->showNormal (); @@ -2535,10 +2543,9 @@ void MainWindow::on_fox_log_action_triggered() void MainWindow::on_contest_log_action_triggered() { - if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config}); if (!m_contestLogWindow) { - m_contestLogWindow.reset (new CabrilloLogWindow {m_settings, &m_config, m_cabrilloLog->model ()}); + m_contestLogWindow.reset (new CabrilloLogWindow {m_settings, &m_config, m_logBook.contest_log ()->model ()}); // Connect signals from contest log window connect (this, &MainWindow::finished, m_contestLogWindow.data (), &CabrilloLogWindow::close); @@ -2618,7 +2625,8 @@ void MainWindow::read_wav_file (QString const& fname) bool ok=file.open (BWFFile::ReadOnly); if(ok) { auto bytes_per_frame = file.format ().bytesPerFrame (); - qint64 max_bytes = std::min (std::size_t (m_TRperiod * RX_SAMPLE_RATE), + int nsamples=m_TRperiod * RX_SAMPLE_RATE; + qint64 max_bytes = std::min (std::size_t (nsamples), sizeof (dec_data.d2) / sizeof (dec_data.d2[0]))* bytes_per_frame; auto n = file.read (reinterpret_cast (dec_data.d2), std::min (max_bytes, file.size ())); @@ -2798,7 +2806,7 @@ void MainWindow::decode() //decode() QDateTime now = QDateTime::currentDateTimeUtc (); if( m_dateTimeLastTX.isValid () ) { qint64 isecs_since_tx = m_dateTimeLastTX.secsTo(now); - dec_data.params.lapcqonly= (isecs_since_tx > 600); + dec_data.params.lapcqonly= (isecs_since_tx > 300); // QTextStream(stdout) << "last tx " << isecs_since_tx << endl; } else { m_dateTimeLastTX = now.addSecs(-900); @@ -2809,7 +2817,7 @@ void MainWindow::decode() //decode() } m_msec0=QDateTime::currentMSecsSinceEpoch(); - if(!m_dataAvailable or m_TRperiod==0) return; + if(!m_dataAvailable or m_TRperiod==0.0) return; ui->DecodeButton->setChecked (true); if(!dec_data.params.nagain && m_diskData && !m_bFastMode && m_mode!="FT8" && m_mode!="FT4") { dec_data.params.nutc=dec_data.params.nutc/100; @@ -2819,14 +2827,16 @@ void MainWindow::decode() //decode() int imin=ms/60000; int ihr=imin/60; imin=imin % 60; - if(m_TRperiod>=60) imin=imin - (imin % (m_TRperiod/60)); + if(m_TRperiod>=60) imin=imin - (imin % (int(m_TRperiod)/60)); dec_data.params.nutc=100*ihr + imin; if(m_mode=="ISCAT" or m_mode=="MSK144" or m_bFast9 or m_mode=="FT8" or m_mode=="FT4") { - QDateTime t=QDateTime::currentDateTimeUtc().addSecs(2-m_TRperiod); + qint64 ms=1000.0*(2.0-m_TRperiod); + if(m_mode=="FT4") ms=1000.0*(2.0-m_TRperiod); + QDateTime t=QDateTime::currentDateTimeUtc().addMSecs(ms); ihr=t.toString("hh").toInt(); imin=t.toString("mm").toInt(); int isec=t.toString("ss").toInt(); - isec=isec - isec%m_TRperiod; + isec=isec - fmod(double(isec),m_TRperiod); dec_data.params.nutc=10000*ihr + 100*imin + isec; } } @@ -2836,7 +2846,7 @@ void MainWindow::decode() //decode() int ihr=t.toString("hh").toInt(); int imin=t.toString("mm").toInt(); int isec=t.toString("ss").toInt(); - isec=isec - isec%m_TRperiod; + isec=isec - fmod(double(isec),m_TRperiod); dec_data.params.nutc=10000*ihr + 100*imin + isec; } if(m_nPick==2) dec_data.params.nutc=m_nutc0; @@ -2884,7 +2894,10 @@ void MainWindow::decode() //decode() if(m_mode=="FT8") dec_data.params.lft8apon = ui->actionEnable_AP_FT8->isVisible () && ui->actionEnable_AP_FT8->isChecked (); if(m_mode=="FT8") dec_data.params.napwid=50; - if(m_mode=="FT4") dec_data.params.nmode=5; + if(m_mode=="FT4") { + dec_data.params.nmode=5; + m_BestCQpriority=""; + } dec_data.params.ntrperiod=m_TRperiod; dec_data.params.nsubmode=m_nSubMode; if(m_mode=="QRA64") dec_data.params.nsubmode=100 + m_nSubMode; @@ -2932,8 +2945,8 @@ void MainWindow::decode() //decode() } static short int d2b[360000]; narg[0]=dec_data.params.nutc; - if(m_kdone>12000*m_TRperiod) { - m_kdone=12000*m_TRperiod; + if(m_kdone>int(12000.0*m_TRperiod)) { + m_kdone=int(12000.0*m_TRperiod); } narg[1]=m_kdone; narg[2]=m_nSubMode; @@ -3039,7 +3052,7 @@ void MainWindow::readFromStdout() //readFromStdout if(line_read.indexOf("") >= 0) { if(m_mode=="QRA64") m_wideGraph->drawRed(0,0); m_bDecoded = line_read.mid(20).trimmed().toInt() > 0; - int mswait=3*1000*m_TRperiod/4; + int mswait=750.0*m_TRperiod; if(!m_diskData) killFileTimer.start(mswait); //Kill in 3/4 period decodeDone (); m_startAnother=m_loopall; @@ -3049,7 +3062,7 @@ void MainWindow::readFromStdout() //readFromStdout } return; } else { - if(m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64" or m_mode=="FT8" or m_mode=="FT4") { + if(m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64") { int n=line_read.indexOf("f"); if(n<0) n=line_read.indexOf("d"); if(n>0) { @@ -3065,7 +3078,7 @@ void MainWindow::readFromStdout() //readFromStdout write_all("Rx",line_read.trimmed()); if (m_config.insert_blank () && m_blankLine && SpecOp::FOX != m_config.special_op_id()) { QString band; - if((QDateTime::currentMSecsSinceEpoch() / 1000 - m_secBandChanged) > 4*m_TRperiod/4) { + if((QDateTime::currentMSecsSinceEpoch() / 1000 - m_secBandChanged) > 4*int(m_TRperiod)/4) { band = ' ' + m_config.bands ()->find (m_freqNominal); } ui->decodedTextBrowser->insertLineSpacer (band.rightJustified (40, '-')); @@ -3103,6 +3116,23 @@ void MainWindow::readFromStdout() //readFromStdout ui->decodedTextBrowser->displayDecodedText(decodedtext0,m_baseCall,m_mode,m_config.DXCC(), m_logBook,m_currentBand,m_config.ppfx(), (ui->cbCQonly->isVisible() and ui->cbCQonly->isChecked())); + if(m_bBestSPArmed and m_mode=="FT4") { + QString messagePriority=ui->decodedTextBrowser->CQPriority(); + if(messagePriority!="") { + if(messagePriority=="New Call on Band" + and m_BestCQpriority!="New Call on Band" + and m_BestCQpriority!="New Multiplier") { + m_BestCQpriority="New Call on Band"; + processMessage(decodedtext0); + } + if(messagePriority=="New DXCC" + and m_BestCQpriority!="New DXCC" + and m_BestCQpriority!="New Multiplier") { + m_BestCQpriority="New DXCC"; + processMessage(decodedtext0); + } + } + } } } @@ -3134,9 +3164,10 @@ void MainWindow::readFromStdout() //readFromStdout if (bDisplayRight) { // This msg is within 10 hertz of our tuned frequency, or a JT4 or JT65 avg, // or contains MyCall - ui->decodedTextBrowser2->displayDecodedText(decodedtext0,m_baseCall,m_mode,m_config.DXCC(), - m_logBook,m_currentBand,m_config.ppfx()); - + if(!m_bBestSPArmed or m_mode!="FT4") { + ui->decodedTextBrowser2->displayDecodedText(decodedtext0,m_baseCall,m_mode,m_config.DXCC(), + m_logBook,m_currentBand,m_config.ppfx()); + } if(m_mode!="JT4") { bool b65=decodedtext.isJT65(); if(b65 and m_modeTx!="JT65") on_pbTxMode_clicked(); @@ -3207,7 +3238,7 @@ void MainWindow::readFromStdout() //readFromStdout } // extract details and send to PSKreporter int nsec=QDateTime::currentMSecsSinceEpoch()/1000-m_secBandChanged; - bool okToPost=(nsec>(4*m_TRperiod)/5); + bool okToPost=(nsec > int(4*m_TRperiod)/5); if (stdMsg && okToPost) pskPost(decodedtext); if((m_mode=="JT4" or m_mode=="JT65" or m_mode=="QRA64") and m_msgAvgWidget!=NULL) { @@ -3307,7 +3338,7 @@ void MainWindow::pskPost (DecodedText const& decodedtext) QString grid; decodedtext.deCallAndGrid(/*out*/deCall,grid); int audioFrequency = decodedtext.frequencyOffset(); - if(m_mode=="FT8" or m_mode=="MSK144") { + if(m_mode=="FT8" or m_mode=="MSK144" or m_mode=="FT4") { audioFrequency=decodedtext.string().mid(16,4).toInt(); } int snr = decodedtext.snr(); @@ -3387,9 +3418,9 @@ void MainWindow::guiUpdate() double txDuration; QString rt; - if(m_TRperiod==0) m_TRperiod=60; + if(m_TRperiod==0) m_TRperiod=60.0; txDuration=0.0; - if(m_modeTx=="FT4") txDuration=0.35 + 105*512/12000.0; // FT4 + if(m_modeTx=="FT4") txDuration=1.0 + 105*576/12000.0; // FT4 if(m_modeTx=="FT8") txDuration=1.0 + 79*1920/12000.0; // FT8 if(m_modeTx=="JT4") txDuration=1.0 + 207.0*2520/11025.0; // JT4 if(m_modeTx=="JT9") txDuration=1.0 + 85.0*m_nsps/12000.0; // JT9 @@ -3417,8 +3448,8 @@ void MainWindow::guiUpdate() double tsec=0.001*ms; double t2p=fmod(tsec,2*m_TRperiod); m_s6=fmod(tsec,6.0); - m_nseq = nsec % m_TRperiod; - m_tRemaining=m_TRperiod - fmod(tsec,double(m_TRperiod)); + m_nseq = fmod(double(nsec),m_TRperiod); + m_tRemaining=m_TRperiod - fmod(tsec,m_TRperiod); if(m_mode=="Echo") { txDuration=2.4; @@ -3459,10 +3490,9 @@ void MainWindow::guiUpdate() if(m_transmitting or m_auto or m_tune) { m_dateTimeLastTX = QDateTime::currentDateTimeUtc (); -// Check for "txboth" (testing purposes only) +// Check for "txboth" (FT4 testing purposes only) QFile f(m_appDir + "/txboth"); - if(f.exists() and - fmod(tsec,m_TRperiod)<(1.0 + 85.0*m_nsps/12000.0)) m_bTxTime=true; + if(f.exists() and fmod(tsec,m_TRperiod) < (0.5 + 105.0*576.0/12000.0)) m_bTxTime=true; // Don't transmit another mode in the 30 m WSPR sub-band Frequency onAirFreq = m_freqNominal + ui->TxFreqSpinBox->value(); @@ -3505,7 +3535,7 @@ void MainWindow::guiUpdate() tx_watchdog (true); // disable transmit } - float fTR=float((ms%(1000*m_TRperiod)))/(1000*m_TRperiod); + float fTR=float((ms%int(1000.0*m_TRperiod)))/int(1000.0*m_TRperiod); QString txMsg; if(m_ntx == 1) txMsg=ui->tx1->text(); @@ -3613,6 +3643,13 @@ void MainWindow::guiUpdate() m_ntx=1; ui->txrb1->setChecked(true); } + + if(m_mode=="FT4" and m_bBestSPArmed) { + m_BestCQpriority=""; + m_bBestSPArmed=false; + ui->pbBestSP->setStyleSheet (""); + } + if(m_ntx == 1) ba=ui->tx1->text().toLocal8Bit(); if(m_ntx == 2) ba=ui->tx2->text().toLocal8Bit(); if(m_ntx == 3) ba=ui->tx3->text().toLocal8Bit(); @@ -3677,10 +3714,11 @@ void MainWindow::guiUpdate() int nsym=79; int nsps=4*1920; float fsample=48000.0; + float bt=2.0; float f0=ui->TxFreqSpinBox->value() - m_XIT; int icmplx=0; int nwave=nsym*nsps; - gen_ft8wave_(const_cast(itone),&nsym,&nsps,&fsample,&f0,foxcom_.wave, + gen_ft8wave_(const_cast(itone),&nsym,&nsps,&bt,&fsample,&f0,foxcom_.wave, foxcom_.wave,&icmplx,&nwave); if(SpecOp::FOX == m_config.special_op_id()) { @@ -3698,13 +3736,17 @@ void MainWindow::guiUpdate() } if(m_modeTx=="FT4") { int ichk=0; - genft4_(message, &ichk, msgsent, const_cast(itone), 37, 37); + char ft4msgbits[77]; + genft4_(message, &ichk, msgsent, const_cast (ft4msgbits), + const_cast(itone), 37, 37); int nsym=103; - int nsps=4*512; + int nsps=4*576; float fsample=48000.0; float f0=ui->TxFreqSpinBox->value() - m_XIT; int nwave=(nsym+2)*nsps; - gen_ft4wave_(const_cast(itone),&nsym,&nsps,&fsample,&f0,foxcom_.wave,&nwave); + int icmplx=0; + gen_ft4wave_(const_cast(itone),&nsym,&nsps,&fsample,&f0,foxcom_.wave, + foxcom_.wave,&icmplx,&nwave); } if(SpecOp::EU_VHF==m_config.special_op_id()) { @@ -3897,7 +3939,7 @@ void MainWindow::guiUpdate() //Once per second: if(nsec != m_sec0) { -// qDebug() << "cc onesec" << (SpecOp::RTTY == m_config.special_op_id()); +// qDebug() << "onesec" << m_config.force_call_1st(); // if((!m_msgAvgWidget or (m_msgAvgWidget and !m_msgAvgWidget->isVisible())) // and (SpecOp::NONE < m_config.special_op_id()) and (SpecOp::HOUND > m_config.special_op_id())) on_actionFox_Log_triggered(); if(m_freqNominal!=0 and m_freqNominal<50000000 and m_config.enable_VHF_features()) { @@ -3913,17 +3955,21 @@ void MainWindow::guiUpdate() if(tHound >= 120 and m_ntx==1) auto_tx_mode(false); } -// progressBar.setVisible(!(m_mode=="FT4")); progressBar.setVisible(true); + progressBar.setFormat ("%v/%m"); if(m_auto and m_mode=="Echo" and m_bEchoTxOK) { - progressBar.setMaximum(6); + progressBar.setMaximum(3); progressBar.setValue(int(m_s6)); } -// if(m_mode!="Echo" and m_mode!="FT4") { if(m_mode!="Echo") { if(m_monitoring or m_transmitting) { progressBar.setMaximum(m_TRperiod); int isec=int(fmod(tsec,m_TRperiod)); + if(m_TRperiod-int(m_TRperiod)>0.0) { + QString progBarLabel; + progBarLabel.sprintf("%d/%3.1f",isec,m_TRperiod); + progressBar.setFormat (progBarLabel); + } progressBar.setValue(isec); } else { progressBar.setValue(0); @@ -3985,9 +4031,8 @@ void MainWindow::guiUpdate() QString utc = t.date().toString("yyyy MMM dd") + "\n " + t.time().toString() + " "; ui->labUTC->setText(utc); - if(!m_monitoring and !m_diskData) { - ui->signal_meter_widget->setValue(0,0); - } + if(m_bBestSPArmed and (m_dateTimeBestSP.secsTo(t) >= 120)) on_pbBestSP_clicked(); //BestSP timeout + if(!m_monitoring and !m_diskData) ui->signal_meter_widget->setValue(0,0); m_sec0=nsec; displayDialFrequency (); } @@ -4023,6 +4068,10 @@ void MainWindow::startTx2() t=ui->tx6->text(); if(t.mid(0,1)=="#") snr=t.mid(1,5).toDouble(); if(snr>0.0 or snr < -50.0) snr=99.0; + if((m_ntx==6 or m_ntx==7) and m_config.force_call_1st()) { + ui->cbAutoSeq->setChecked(true); + ui->cbFirst->setChecked(true); + } transmit (snr); ui->signal_meter_widget->setValue(0,0); if(m_mode=="Echo" and !m_tune) m_bTransmittedEcho=true; @@ -4063,8 +4112,7 @@ void MainWindow::stopTx2() on_stopTxButton_clicked (); m_nTx73 = 0; } - if(((m_mode.startsWith("WSPR") and m_ntr==-1) or m_mode=="FT4") and - !m_tuneup) { + if((m_mode.startsWith("WSPR") and m_ntr==-1) and !m_tuneup) { m_wideGraph->setWSPRtransmitted(); WSPR_scheduling (); m_ntr=0; @@ -4108,7 +4156,8 @@ void MainWindow::set_dateTimeQSO(int m_ntx) } else { // we also take of m_TRperiod/2 to allow for late clicks auto now = QDateTime::currentDateTimeUtc(); - m_dateTimeQSOOn = now.addSecs (-(m_ntx - 2) * m_TRperiod - (now.time ().second () % m_TRperiod)); + m_dateTimeQSOOn = now.addSecs (-(m_ntx - 2) * int(m_TRperiod) - + int(fmod(double(now.time().second()),m_TRperiod))); } } @@ -4174,7 +4223,7 @@ void MainWindow::on_txrb4_doubleClicked () auto const& my_callsign = m_config.my_callsign (); auto is_compound = my_callsign != m_baseCall; m_send_RR73 = !((is_compound && !shortList (my_callsign)) || m_send_RR73); - if(m_mode=="FT4") m_send_RR73=true; + if(m_mode=="FT4" and (m_config.special_op_id()==SpecOp::RTTY)) m_send_RR73=true; genStdMsgs (m_rpt); } @@ -4361,7 +4410,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie } } - int nmod = message.timeInSeconds () % (2*m_TRperiod); + int nmod = fmod(double(message.timeInSeconds()),2.0*m_TRperiod); m_txFirst=(nmod!=0); if( SpecOp::HOUND == m_config.special_op_id() ) m_txFirst=false; //Hound must not transmit first if( SpecOp::FOX == m_config.special_op_id() ) m_txFirst=true; //Fox must always transmit first @@ -4389,7 +4438,6 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie return; } - // only allow automatic mode changes between JT9 and JT65, and when not transmitting if (!m_transmitting and m_mode == "JT9+JT65") { if (message.isJT9()) @@ -4485,11 +4533,11 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie // ### Should be in RTTY contest mode ??? ### MessageBox::information_message (this, tr ("Should you switch to RTTY contest mode?")); } - if(message_words.size () > 3 // enough fields for a normal message && (message_words.at(1).contains(m_baseCall) || "DE" == message_words.at(1)) // && (message_words.at(2).contains(qso_partner_base_call) or bEU_VHF_w2)) { - && (message_words.at(2).contains(qso_partner_base_call) or m_bDoubleClicked or bEU_VHF_w2)) { + && (message_words.at(2).contains(qso_partner_base_call) or m_bDoubleClicked + or bEU_VHF_w2 or (m_QSOProgress==CALLING))) { if(message_words.at(3).contains(grid_regexp) and SpecOp::EU_VHF!=m_config.special_op_id()) { if(SpecOp::NA_VHF==m_config.special_op_id()){ @@ -4551,8 +4599,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie ui->tx3->setText(t); m_bTUmsg=true; } else { -// if(SpecOp::RTTY == m_config.special_op_id()) { - if(false) { + if(SpecOp::RTTY == m_config.special_op_id()) { logQSOTimer.start(0); m_ntx=6; ui->txrb6->setChecked(true); @@ -4616,7 +4663,7 @@ void MainWindow::processMessage (DecodedText const& message, Qt::KeyboardModifie } m_QSOProgress = SIGNOFF; } - else if (!(m_bAutoReply && m_QSOProgress > CALLING)) { + else if (!(m_bAutoReply && (m_QSOProgress > CALLING))) { if ((message_words.size () > 4 && message_words.at (1).contains (m_baseCall) && message_words.at (4) == "OOO")) { // EME short code report or MSK144/FT8 contest mode reply, send back Tx3 @@ -4976,7 +5023,6 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) QDateTime now=QDateTime::currentDateTimeUtc(); int sinceTx3 = m_dateTimeSentTx3.secsTo(now); int sinceRR73 = m_dateTimeRcvdRR73.secsTo(now); -// qDebug() << "aa" << m_bDoubleClicked << sinceTx3 << sinceRR73; if(m_bDoubleClicked and (sinceTx3 < 15) and (sinceRR73 < 3)) { t="TU; " + ui->tx3->text(); ui->tx3->setText(t); @@ -5023,7 +5069,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) msgtype(t, ui->tx4); t=t0 + "73"; - if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8") { + if((m_mode=="MSK144" and !m_bShMsgs) or m_mode=="FT8" or m_mode=="FT4") { if(!bHisCall and bMyCall) t=hisCall + " <" + my_callsign + "> 73"; if(bHisCall and !bMyCall) t="<" + hisCall + "> " + my_callsign + " 73"; } @@ -5039,7 +5085,7 @@ void MainWindow::genStdMsgs(QString rpt, bool unconditional) } } - if(m_mode=="FT8" or m_mode=="MSK144") return; + if(m_mode=="FT8" or m_mode=="FT4" or m_mode=="MSK144") return; if (is_compound) { if (is_type_one) { @@ -5125,10 +5171,9 @@ void MainWindow::TxAgain() void MainWindow::clearDX () { set_dateTimeQSO (-1); - if (m_QSOProgress != CALLING) - { - auto_tx_mode (false); - } + if (m_QSOProgress != CALLING) { + auto_tx_mode (false); + } ui->dxCallEntry->clear (); ui->dxGridEntry->clear (); m_lastCallsign.clear (); @@ -5454,15 +5499,9 @@ void MainWindow::on_logQSOButton_clicked() //Log QSO button default: break; } - auto special_op = m_config.special_op_id (); - if (SpecOp::NONE < special_op && special_op < SpecOp::FOX) - { - if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config}); - } m_logDlg->initLogQSO (m_hisCall, grid, m_modeTx, m_rptSent, m_rptRcvd, m_dateTimeQSOOn, dateTimeQSOOff, m_freqNominal + - ui->TxFreqSpinBox->value(), m_noSuffix, m_xSent, m_xRcvd, - m_cabrilloLog.data ()); + ui->TxFreqSpinBox->value(), m_noSuffix, m_xSent, m_xRcvd); m_inQSOwith=""; } @@ -5500,7 +5539,8 @@ void MainWindow::acceptQSO (QDateTime const& QSO_date_off, QString const& call, } } - if (m_config.clear_DX () and SpecOp::HOUND != m_config.special_op_id()) clearDX (); + if(m_config.clear_DX () and SpecOp::HOUND != m_config.special_op_id()) clearDX (); + auto_tx_mode (false); m_dateTimeQSOOn = QDateTime {}; auto special_op = m_config.special_op_id (); if (SpecOp::NONE < special_op && special_op < SpecOp::FOX && @@ -5574,8 +5614,14 @@ void MainWindow::displayWidgets(qint64 n) if(i==32) ui->cbCQonly->setVisible(b); j=j>>1; } + ui->pbBestSP->setVisible(m_mode=="FT4"); + b=false; + if(m_mode=="FT4" or m_mode=="FT8") { b=SpecOp::EU_VHF==m_config.special_op_id() or (SpecOp::RTTY==m_config.special_op_id() and - (m_config.RTTY_Exchange()=="DX" or m_config.RTTY_Exchange()=="SCC")); + (m_config.RTTY_Exchange()=="DX" or m_config.RTTY_Exchange()=="#" or + m_config.RTTY_Exchange()=="SCC")); + } + if(m_mode=="MSK144") b=SpecOp::EU_VHF==m_config.special_op_id(); ui->sbSerialNumber->setVisible(b); m_lastCallsign.clear (); // ensures Tx5 is updated for new modes genStdMsgs (m_rpt, true); @@ -5585,7 +5631,7 @@ void MainWindow::on_actionFT4_triggered() { m_mode="FT4"; m_modeTx="FT4"; - m_TRperiod=6; + m_TRperiod=7.5; bool bVHF=m_config.enable_VHF_features(); m_bFast9=false; m_bFastMode=false; @@ -5594,9 +5640,9 @@ void MainWindow::on_actionFT4_triggered() m_nsps=6912; m_FFTSize = m_nsps/2; Q_EMIT FFTSize (m_FFTSize); - m_hsymStop=18; + m_hsymStop=21; setup_status_bar (bVHF); - m_toneSpacing=12000.0/512.0; + m_toneSpacing=12000.0/576.0; ui->actionFT4->setChecked(true); m_wideGraph->setMode(m_mode); m_wideGraph->setModeTx(m_modeTx); @@ -5612,7 +5658,7 @@ void MainWindow::on_actionFT4_triggered() ui->label_7->setText("Rx Frequency"); ui->label_6->setText("Band Activity"); ui->decodedTextLabel->setText( " UTC dB DT Freq Message"); - displayWidgets(nWidgets("111010000100111000010000100110001")); + displayWidgets(nWidgets("111010000100111000010000000110001")); ui->txrb2->setEnabled(true); ui->txrb4->setEnabled(true); ui->txrb5->setEnabled(true); @@ -5646,7 +5692,7 @@ void MainWindow::on_actionFT8_triggered() m_wideGraph->setModeTx(m_modeTx); VHF_features_enabled(bVHF); ui->cbAutoSeq->setChecked(true); - m_TRperiod=15; + m_TRperiod=15.0; m_fastGraph->hide(); m_wideGraph->show(); ui->decodedTextLabel2->setText(" UTC dB DT Freq Message"); @@ -5735,7 +5781,7 @@ void MainWindow::on_actionJT4_triggered() WSPR_config(false); switch_mode (Modes::JT4); m_modeTx="JT4"; - m_TRperiod=60; + m_TRperiod=60.0; m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe m_nsps=6912; //For symspec only @@ -5808,7 +5854,7 @@ void MainWindow::on_actionJT9_triggered() ui->decodedTextLabel2->setText("UTC dB T Freq Message"); } else { ui->cbAutoSeq->setChecked(false); - m_TRperiod=60; + m_TRperiod=60.0; ui->decodedTextLabel->setText("UTC dB DT Freq Message"); ui->decodedTextLabel2->setText("UTC dB DT Freq Message"); } @@ -5837,7 +5883,7 @@ void MainWindow::on_actionJT9_JT65_triggered() m_modeTx="JT9"; } m_nSubMode=0; //Dual-mode always means JT9 and JT65A - m_TRperiod=60; + m_TRperiod=60.0; m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe m_nsps=6912; @@ -5879,7 +5925,7 @@ void MainWindow::on_actionJT65_triggered() WSPR_config(false); switch_mode (Modes::JT65); if(m_modeTx!="JT65") on_pbTxMode_clicked(); - m_TRperiod=60; + m_TRperiod=60.0; m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe m_nsps=6912; //For symspec only @@ -6055,7 +6101,7 @@ void MainWindow::on_actionWSPR_triggered() WSPR_config(true); switch_mode (Modes::WSPR); m_modeTx="WSPR"; - m_TRperiod=120; + m_TRperiod=120.0; m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe m_nsps=6912; //For symspec only @@ -6083,7 +6129,7 @@ void MainWindow::on_actionWSPR_LF_triggered() m_mode="WSPR-LF"; switch_mode (Modes::WSPR); m_modeTx="WSPR-LF"; - m_TRperiod=240; + m_TRperiod=240.0; m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe m_hsymStop=813; @@ -6099,7 +6145,7 @@ void MainWindow::on_actionEcho_triggered() on_actionJT4_triggered(); m_mode="Echo"; ui->actionEcho->setChecked(true); - m_TRperiod=3; + m_TRperiod=3.0; m_modulator->setTRPeriod(m_TRperiod); // TODO - not thread safe m_detector->setTRPeriod(m_TRperiod); // TODO - not thread safe m_nsps=6912; //For symspec only @@ -6296,15 +6342,13 @@ void MainWindow::on_reset_cabrillo_log_action_triggered () "for export in your Cabrillo log."))) { if(m_config.RTTY_Exchange()!="SCC") ui->sbSerialNumber->setValue(1); - if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config}); - m_cabrilloLog->reset (); + m_logBook.contest_log ()->reset (); } } void MainWindow::on_actionExport_Cabrillo_log_triggered() { - if (!m_cabrilloLog) m_cabrilloLog.reset (new CabrilloLog {&m_config}); - if (QDialog::Accepted == ExportCabrillo {m_settings, &m_config, m_cabrilloLog.data ()}.exec()) + if (QDialog::Accepted == ExportCabrillo {m_settings, &m_config, m_logBook.contest_log ()}.exec()) { MessageBox::information_message (this, tr ("Cabrillo Log saved")); } @@ -6378,7 +6422,6 @@ void MainWindow::on_bandComboBox_activated (int index) void MainWindow::band_changed (Frequency f) { -// bool monitor_off=!m_monitoring; // Set the attenuation value if options are checked QString curBand = ui->bandComboBox->currentText(); if (m_config.pwrBandTxMemory() && !m_tune) { @@ -6414,7 +6457,6 @@ void MainWindow::band_changed (Frequency f) if(r<0.9 or r>1.1) m_bVHFwarned=false; setRig (f); setXIT (ui->TxFreqSpinBox->value ()); -// if(monitor_off) monitor(false); } } @@ -6895,7 +6937,7 @@ void MainWindow::transmit (double snr) m_dateTimeSentTx3=QDateTime::currentDateTimeUtc(); toneSpacing=-2.0; //Transmit a pre-computed, filtered waveform. Q_EMIT sendMessage (NUM_FT4_SYMBOLS, - 512.0, ui->TxFreqSpinBox->value() - m_XIT, + 576.0, ui->TxFreqSpinBox->value() - m_XIT, toneSpacing, m_soundOutput, m_config.audio_output_channel(), true, false, snr, m_TRperiod); } @@ -7125,6 +7167,7 @@ void MainWindow::transmitDisplay (bool transmitting) void MainWindow::on_sbFtol_valueChanged(int value) { m_wideGraph->setTol (value); + statusUpdate (); } void::MainWindow::VHF_features_enabled(bool b) @@ -7162,6 +7205,7 @@ void MainWindow::on_sbTR_valueChanged(int value) if(m_transmitting) { on_stopTxButton_clicked(); } + statusUpdate (); } QChar MainWindow::current_submode () const @@ -7198,7 +7242,7 @@ void MainWindow::on_sbSubmode_valueChanged(int n) on_cbFast9_clicked(false); ui->cbFast9->setEnabled(false); ui->sbTR->setVisible(false); - m_TRperiod=60; + m_TRperiod=60.0; } else { ui->cbFast9->setEnabled(true); } @@ -7220,9 +7264,9 @@ void MainWindow::on_cbFast9_clicked(bool b) if(b) { m_TRperiod = ui->sbTR->value (); } else { - m_TRperiod=60; + m_TRperiod=60.0; } - progressBar.setMaximum(m_TRperiod); + progressBar.setMaximum(int(m_TRperiod)); m_wideGraph->setPeriod(m_TRperiod,m_nsps); fast_config(b); statusChanged (); @@ -7263,11 +7307,6 @@ void MainWindow::replyToCQ (QTime time, qint32 snr, float delta_time, quint32 de , QString const& mode, QString const& message_text , bool /*low_confidence*/, quint8 modifiers) { - if (!m_config.accept_udp_requests ()) - { - return; - } - QString format_string {"%1 %2 %3 %4 %5 %6"}; auto const& time_string = time.toString ("~" == mode || "&" == mode || "+" == mode ? "hhmmss" : "hhmm"); @@ -7502,8 +7541,8 @@ void MainWindow::p1ReadFromStdout() //p1readFromStdout if(grid!="") { double utch=0.0; int nAz,nEl,nDmiles,nDkm,nHotAz,nHotABetter; - azdist_(const_cast (m_config.my_grid ().toLatin1().constData()), - const_cast (grid.toLatin1().constData()),&utch, + azdist_(const_cast ((m_config.my_grid () + " ").left (6).toLatin1 ().constData ()), + const_cast ((grid + " ").left (6).toLatin1 ().constData ()),&utch, &nAz,&nEl,&nDmiles,&nDkm,&nHotAz,&nHotABetter,6,6); QString t1; if(m_config.miles()) { @@ -7766,7 +7805,7 @@ void MainWindow::setRig (Frequency f) void MainWindow::fastPick(int x0, int x1, int y) { float pixPerSecond=12000.0/512.0; - if(m_TRperiod<30) pixPerSecond=12000.0/256.0; + if(m_TRperiod<30.0) pixPerSecond=12000.0/256.0; if(m_mode!="ISCAT" and m_mode!="MSK144") return; if(!m_decoderBusy) { dec_data.params.newdat=0; @@ -7836,8 +7875,18 @@ void MainWindow::on_cbCQTx_toggled(bool b) void MainWindow::statusUpdate () const { - if (!ui) return; + if (!ui || m_block_udp_status_updates) return; auto submode = current_submode (); + auto ftol = ui->sbFtol->value (); + if (!(ui->sbFtol->isVisible () && ui->sbFtol->isEnabled ())) + { + ftol = quint32_max; + } + auto tr_period = ui->sbTR->value (); + if (!(ui->sbTR->isVisible () && ui->sbTR->isEnabled ())) + { + tr_period = quint32_max; + } m_messageClient->status_update (m_freqNominal, m_mode, m_hisCall, QString::number (ui->rptSpinBox->value ()), m_modeTx, ui->autoButton->isChecked (), @@ -7846,7 +7895,8 @@ void MainWindow::statusUpdate () const m_config.my_callsign (), m_config.my_grid (), m_hisGrid, m_tx_watchdog, submode != QChar::Null ? QString {submode} : QString {}, m_bFastMode, - static_cast (m_config.special_op_id ())); + static_cast (m_config.special_op_id ()), + ftol, tr_period, m_multi_settings->configuration_name ()); } void MainWindow::childEvent (QChildEvent * e) @@ -7967,7 +8017,7 @@ void MainWindow::write_transmit_entry (QString const& file_name) { QTextStream out(&f); auto time = QDateTime::currentDateTimeUtc (); - time = time.addSecs (-(time.time ().second () % m_TRperiod)); + time = time.addSecs (-fmod(double(time.time().second()),m_TRperiod)); out << time.toString("yyMMdd_hhmmss") << " Transmitting " << qSetRealNumberPrecision (12) << (m_freqNominal / 1.e6) << " MHz " << m_modeTx @@ -8207,7 +8257,7 @@ void MainWindow::houndCallers() if(!ui->textBrowser4->toPlainText().contains(paddedHoundCall)) { if(m_loggedByFox[houndCall].contains(m_lastBand)) continue; //already logged on this band if(m_foxQSO.contains(houndCall)) continue; //still in the QSO map - auto const& entity = m_logBook.countries ().lookup (houndCall); + auto const& entity = m_logBook.countries ()->lookup (houndCall); auto const& continent = AD1CCty::continent (entity.continent); //If we are using a directed CQ, ignore Hound calls that do not comply. @@ -8388,9 +8438,8 @@ list2Done: m_hisGrid=m_foxQSO[hc1].grid; m_rptSent=m_foxQSO[hc1].sent; m_rptRcvd=m_foxQSO[hc1].rcvd; - if (!m_foxLog) m_foxLog.reset (new FoxLog {&m_config}); if (!m_foxLogWindow) on_fox_log_action_triggered (); - if (m_foxLog->add_QSO (QSO_time, m_hisCall, m_hisGrid, m_rptSent, m_rptRcvd, m_lastBand)) + if (m_logBook.fox_log ()->add_QSO (QSO_time, m_hisCall, m_hisGrid, m_rptSent, m_rptRcvd, m_lastBand)) { writeFoxQSO (QString {" Log: %1 %2 %3 %4 %5"}.arg (m_hisCall).arg (m_hisGrid) .arg (m_rptSent).arg (m_rptRcvd).arg (m_lastBand)); @@ -8608,24 +8657,44 @@ void MainWindow::write_all(QString txRx, QString message) { QString line; QString t; - QString msg=message.mid(6,-1); + QString msg; + QString mode_string; + + if (message[4]==' ') { + msg=message.mid(4,-1); + } else { + msg=message.mid(6,-1); + } + + if (message[19]=='#') { + mode_string="JT65 "; + } else if (message[19]=='@') { + mode_string="JT9 "; + } else { + mode_string=m_mode.leftJustified(6,' '); + } + msg=msg.mid(0,15) + msg.mid(18,-1); t.sprintf("%5d",ui->TxFreqSpinBox->value()); - if(txRx=="Tx") msg=" 0 0.0" + t + " " + message; + if (txRx=="Tx") msg=" 0 0.0" + t + " " + message; auto time = QDateTime::currentDateTimeUtc (); - time = time.addSecs(-(time.time().second() % m_TRperiod)); + time = time.addSecs(-fmod(double(time.time().second()),m_TRperiod)); t.sprintf("%10.3f ",m_freqNominal/1.e6); - if(m_diskData) { - line=m_fileDateTime + t + txRx + " " + m_mode.leftJustified(6,' ') + msg; + if (m_diskData) { + if (m_fileDateTime.size()==11) { + line=m_fileDateTime + " " + t + txRx + " " + mode_string + msg; + } else { + line=m_fileDateTime + t + txRx + " " + mode_string + msg; + } } else { - line=time.toString("yyMMdd_hhmmss") + t + txRx + " " + m_mode.leftJustified(6,' ') + msg; + line=time.toString("yyMMdd_hhmmss") + t + txRx + " " + mode_string + msg; } QString file_name="ALL.TXT"; - if(m_mode=="WSPR") file_name="ALL_WSPR.TXT"; + if (m_mode=="WSPR") file_name="ALL_WSPR.TXT"; QFile f{m_config.writeable_data_dir().absoluteFilePath(file_name)}; - if(f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { + if (f.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) { QTextStream out(&f); out << line << endl; f.close(); @@ -8640,18 +8709,10 @@ void MainWindow::write_all(QString txRx, QString message) void MainWindow::chkFT4() { if(m_mode!="FT4") return; - if(m_config.special_op_id()==SpecOp::RTTY or m_config.special_op_id()==SpecOp::NA_VHF) { - ui->cbAutoSeq->setEnabled(true); - ui->cbFirst->setEnabled(true); - ui->labDXped->setVisible(true); - } else { - ui->cbAutoSeq->setChecked(false); - ui->cbAutoSeq->setEnabled(false); - ui->cbFirst->setChecked(false); - ui->cbFirst->setEnabled(false); - ui->cbFirst->setVisible(false); - ui->labDXped->setVisible(false); - } + ui->cbAutoSeq->setEnabled(true); + ui->cbFirst->setVisible(true); + ui->cbFirst->setEnabled(true); + ui->labDXped->setVisible(m_config.special_op_id()!=SpecOp::NONE); ui->cbFirst->setVisible(ui->cbAutoSeq->isChecked()); if (SpecOp::NONE < m_config.special_op_id () && SpecOp::FOX > m_config.special_op_id ()) { @@ -8669,3 +8730,87 @@ void MainWindow::chkFT4() on_contest_log_action_triggered(); } } + +void MainWindow::on_pbBestSP_clicked() +{ + m_bBestSPArmed = !m_bBestSPArmed; + if(m_bBestSPArmed and !m_transmitting) ui->pbBestSP->setStyleSheet ("QPushButton{color:red}"); + if(!m_bBestSPArmed) ui->pbBestSP->setStyleSheet (""); + if(m_bBestSPArmed) m_dateTimeBestSP=QDateTime::currentDateTimeUtc(); +} + +void MainWindow::set_mode (QString const& mode) +{ + if ("FT4" == mode) on_actionFT4_triggered (); + else if ("FT8" == mode) on_actionFT8_triggered (); + else if ("JT4" == mode) on_actionJT4_triggered (); + else if ("JT9" == mode) on_actionJT9_triggered (); + else if ("JT9+JT65" == mode) on_actionJT9_JT65_triggered (); + else if ("JT65" == mode) on_actionJT65_triggered (); + else if ("QRA64" == mode) on_actionQRA64_triggered (); + else if ("FreqCal" == mode) on_actionFreqCal_triggered (); + else if ("ISCAT" == mode) on_actionISCAT_triggered (); + else if ("MSK144" == mode) on_actionMSK144_triggered (); + else if ("WSPR" == mode) on_actionWSPR_triggered (); + else if ("WSPR-LF" == mode) on_actionWSPR_LF_triggered (); + else if ("Echo" == mode) on_actionEcho_triggered (); +} + +void MainWindow::remote_configure (QString const& mode, quint32 frequency_tolerance + , QString const& submode, bool fast_mode, quint32 tr_period, quint32 rx_df + , QString const& dx_call, QString const& dx_grid, bool generate_messages) +{ + if (mode.size ()) + { + set_mode (mode); + } + if (frequency_tolerance != quint32_max && ui->sbFtol->isVisible ()) + { + ui->sbFtol->setValue (frequency_tolerance); + } + if (submode.size () && ui->sbSubmode->isVisible ()) + { + ui->sbSubmode->setValue (submode.toUpper ().at (0).toLatin1 () - 'A'); + } + if (ui->cbFast9->isVisible () && ui->cbFast9->isChecked () != fast_mode) + { + ui->cbFast9->click (); + } + if (tr_period != quint32_max && ui->sbTR->isVisible ()) + { + ui->sbTR->setValue (tr_period); + ui->sbTR->interpretText (); + } + if (rx_df != quint32_max && ui->RxFreqSpinBox->isVisible ()) + { + m_block_udp_status_updates = true; + ui->RxFreqSpinBox->setValue (rx_df); + ui->RxFreqSpinBox->interpretText (); + m_block_udp_status_updates = false; + } + if (dx_call.size () && ui->dxCallEntry->isVisible ()) + { + ui->dxCallEntry->setText (dx_call); + } + if (dx_grid.size () && ui->dxGridEntry->isVisible ()) + { + ui->dxGridEntry->setText (dx_grid); + } + if (generate_messages && ui->genStdMsgsPushButton->isVisible ()) + { + ui->genStdMsgsPushButton->click (); + } + if (m_config.udpWindowToFront ()) + { + show (); + raise (); + activateWindow (); + } + if (m_config.udpWindowRestore () && isMinimized ()) + { + showNormal (); + raise (); + } + tx_watchdog (false); + QApplication::alert (this); +} diff --git a/widgets/mainwindow.h b/widgets/mainwindow.h index 6bce17978..514dbb30a 100644 --- a/widgets/mainwindow.h +++ b/widgets/mainwindow.h @@ -72,9 +72,7 @@ class WideGraph; class LogQSO; class Transceiver; class MessageAveraging; -class FoxLog; class FoxLogWindow; -class CabrilloLog; class CabrilloLogWindow; class ColorHighlighting; class MessageClient; @@ -312,8 +310,12 @@ private slots: void on_comboBoxHoundSort_activated (int index); void not_GA_warning_message (); void checkMSK144ContestType(); + void on_pbBestSP_clicked(); int setTxMsg(int n); bool stdCall(QString const& w); + void remote_configure (QString const& mode, quint32 frequency_tolerance, QString const& submode + , bool fast_mode, quint32 tr_period, quint32 rx_df, QString const& dx_call + , QString const& dx_grid, bool generate_messages); private: Q_SIGNAL void initializeAudioOutputStream (QAudioDeviceInfo, @@ -340,6 +342,7 @@ private: Q_SIGNAL void toggleShorthand () const; private: + void set_mode (QString const& mode); void astroUpdate (); void writeAllTxt(QString message); void auto_sequence (DecodedText const& message, unsigned start_tolerance, unsigned stop_tolerance); @@ -358,8 +361,8 @@ private: QSettings * m_settings; QScopedPointer ui; - LogBook m_logBook; // must be before Configuration construction Configuration m_config; + LogBook m_logBook; // must be after Configuration construction WSPRBandHopping m_WSPR_band_hopping; bool m_WSPR_tx_next; MessageBox m_rigErrorMessageBox; @@ -375,9 +378,7 @@ private: QScopedPointer m_prefixes; QScopedPointer m_mouseCmnds; QScopedPointer m_msgAvgWidget; - QScopedPointer m_foxLog; QScopedPointer m_foxLogWindow; - QScopedPointer m_cabrilloLog; QScopedPointer m_contestLogWindow; QScopedPointer m_colorHighlighting; Transceiver::TransceiverState m_rigState; @@ -405,6 +406,7 @@ private: double m_s6; double m_tRemaining; + double m_TRperiod; float m_DTtol; float m_t0; @@ -427,7 +429,6 @@ private: qint32 m_ntr; qint32 m_tx; qint32 m_hsym; - qint32 m_TRperiod; qint32 m_nsps; qint32 m_hsymStop; qint32 m_inGain; @@ -520,6 +521,7 @@ private: bool m_bCheckedContest; bool m_bWarnedSplit=false; bool m_bTUmsg; + bool m_bBestSPArmed=false; enum { @@ -615,6 +617,7 @@ private: QString m_nextGrid; QString m_fileDateTime; QString m_inQSOwith; + QString m_BestCQpriority; QSet m_pfx; QSet m_sfx; @@ -650,6 +653,7 @@ private: QDateTime m_dateTimeLastTX; QDateTime m_dateTimeSentTx3; QDateTime m_dateTimeRcvdRR73; + QDateTime m_dateTimeBestSP; QSharedMemory *mem_jt9; QString m_QSOText; @@ -680,6 +684,7 @@ private: QHash m_pwrBandTuneMemory; // Remembers power level by band for tuning QByteArray m_geometryNoControls; QVector m_phaseEqCoefficients; + bool m_block_udp_status_updates; //---------------------------------------------------- private functions void readSettings(); diff --git a/widgets/mainwindow.ui b/widgets/mainwindow.ui index a779cb413..75be401d0 100644 --- a/widgets/mainwindow.ui +++ b/widgets/mainwindow.ui @@ -340,7 +340,7 @@ - <html><head/><body><p>Enter this QSO in log</p></body></html> + Enter this QSO in log Log &QSO @@ -372,7 +372,7 @@ - <html><head/><body><p>Toggle monitoring On/Off</p></body></html> + Toggle monitoring On/Off QPushButton:checked { @@ -407,6 +407,9 @@ <html><head/><body><p>Erase right window. Double-click to erase both windows.</p></body></html> + + Erase right window. Double-click to erase both windows. + &Erase @@ -420,6 +423,9 @@ <html><head/><body><p>Clear the accumulating message average.</p></body></html> + + Clear the accumulating message average. + Clear Avg @@ -436,6 +442,9 @@ <html><head/><body><p>Decode most recent Rx period at QSO Frequency</p></body></html> + + Decode most recent Rx period at QSO Frequency + QPushButton:checked { background-color: cyan; @@ -466,6 +475,9 @@ <html><head/><body><p>Toggle Auto-Tx On/Off</p></body></html> + + Toggle Auto-Tx On/Off + QPushButton:checked { background-color: red; @@ -506,6 +518,9 @@ <html><head/><body><p>Toggle a pure Tx tone On/Off</p></body></html> + + Toggle a pure Tx tone On/Off + QPushButton:checked { background-color: red; @@ -590,6 +605,15 @@ QLabel[oob="true"] { <html><head/><body><p>30dB recommended when only noise present<br/>Green when good<br/>Red when clipping may occur<br/>Yellow when too low</p></body></html> + + Rx Signal + + + 30dB recommended when only noise present +Green when good +Red when clipping may occur +Yellow when too low + QFrame::Panel @@ -706,6 +730,9 @@ QLabel[oob="true"] { 2 + + dxCallEntry + @@ -795,6 +822,9 @@ QLabel[oob="true"] { 2 + + dxGridEntry + @@ -883,6 +913,9 @@ QLabel[oob="true"] { <html><head/><body><p>If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode.</p></body></html> + + If orange or red there has been a rig control failure, click to reset and read the dial frequency. S implies split mode. + QPushButton { font-family: helvetica; @@ -947,6 +980,12 @@ QPushButton[state="ok"] { <html><head/><body><p>Select operating band or enter frequency in MHz or enter kHz increment followed by k.</p></body></html> + + Frequncy entry + + + Select operating band or enter frequency in MHz or enter kHz increment followed by k. + true @@ -1038,6 +1077,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Check to keep Tx frequency fixed when double-clicking on decoded text.</p></body></html> + + Check to keep Tx frequency fixed when double-clicking on decoded text. + Hold Tx Freq @@ -1155,6 +1197,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Synchronizing threshold. Lower numbers accept weaker sync signals.</p></body></html> + + Synchronizing threshold. Lower numbers accept weaker sync signals. + Qt::AlignCenter @@ -1179,6 +1224,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Check to use short-format messages.</p></body></html> + + Check to use short-format messages. + Sh @@ -1189,6 +1237,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Check to enable JT9 fast modes</p></body></html> + + Check to enable JT9 fast modes + Fast @@ -1199,6 +1250,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Check to enable automatic sequencing of Tx messages based on received messages.</p></body></html> + + Check to enable automatic sequencing of Tx messages based on received messages. + Auto Seq @@ -1209,6 +1263,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Check to call the first decoded responder to my CQ.</p></body></html> + + Check to call the first decoded responder to my CQ. + Call 1st @@ -1234,6 +1291,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences.</p></body></html> + + Check to Tx in even-numbered minutes or sequences, starting at 0; uncheck for odd sequences. + Tx even/1st @@ -1249,6 +1309,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Frequency to call CQ on in kHz above the current MHz</p></body></html> + + Frequency to call CQ on in kHz above the current MHz + Tx CQ @@ -1271,6 +1334,10 @@ QPushButton[state="ok"] { <html><head/><body><p>Check this to call CQ on the &quot;Tx CQ&quot; frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on.</p><p>Not available to nonstandard callsign holders.</p></body></html> + + Check this to call CQ on the "Tx CQ" frequency. Rx will be on the current frequency and the CQ message wiill include the current Rx frequency so callers know which frequency to reply on. +Not available to nonstandard callsign holders. + @@ -1290,6 +1357,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Submode determines tone spacing; A is narrowest.</p></body></html> + + Submode determines tone spacing; A is narrowest. + Qt::AlignCenter @@ -1333,16 +1403,45 @@ QPushButton[state="ok"] { <html><head/><body><p>Check to monitor Sh messages.</p></body></html> + + Check to monitor Sh messages. + SWL + + + + QPushButton:checked { + background-color: red; + border-style: outset; + border-width: 1px; + border-radius: 5px; + border-color: black; + min-width: 5em; + padding: 3px; +} + + + Best S+P + + + true + + + <html><head/><body><p>Check this to start recording calibration data.<br/>While measuring calibration correction is disabled.<br/>When not checked you can view the calibration results.</p></body></html> + + Check this to start recording calibration data. +While measuring calibration correction is disabled. +When not checked you can view the calibration results. + Measure @@ -1355,6 +1454,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB).</p></body></html> + + Signal report: Signal-to-noise ratio in 2500 Hz reference bandwidth (dB). + Qt::AlignCenter @@ -1377,6 +1479,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Tx/Rx or Frequency calibration sequence length</p></body></html> + + Tx/Rx or Frequency calibration sequence length + Qt::AlignCenter @@ -1475,6 +1580,9 @@ QPushButton[state="ok"] { <html><head/><body><p>Double-click on another caller to queue that call for your next QSO.</p></body></html> + + Double-click on another caller to queue that call for your next QSO. + Next Call @@ -1530,6 +1638,10 @@ QPushButton[state="ok"] { <html><head/><body><p>Send this message in next Tx interval</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> + + Send this message in next Tx interval +Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) + margin-left: 10%; margin-right: 0% @@ -1565,6 +1677,10 @@ QPushButton[state="ok"] { <html><head/><body><p>Switch to this Tx message NOW</p><p>Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders)</p></body></html> + + Switch to this Tx message NOW +Double click to toggle the use of the Tx1 message to start a QSO with a station (not allowed for type 1 compound call holders) + Qt::LeftToRight @@ -1606,6 +1722,10 @@ QPushButton[state="ok"] { <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to reset to the standard 73 message</p></body></html> + + Send this message in next Tx interval +Double-click to reset to the standard 73 message + margin-left: 10%; margin-right: 0% @@ -1654,6 +1774,11 @@ QPushButton[state="ok"] { <html><head/><body><p>Send this message in next Tx interval</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> + + Send this message in next Tx interval +Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type 2 compound call holders) +RR73 messages should only be used when you are reasonably confident that no message repetitions will be required + margin-left: 10%; margin-right: 0% @@ -1670,6 +1795,11 @@ QPushButton[state="ok"] { <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders)</p><p>RR73 messages should only be used when you are reasonably confident that no message repetitions will be required</p></body></html> + + Switch to this Tx message NOW +Double-click to toggle between RRR and RR73 messages in Tx4 (not allowed for type2 compound call holders) +RR73 messages should only be used when you are reasonably confident that no message repetitions will be required + padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% @@ -1686,6 +1816,10 @@ QPushButton[state="ok"] { <html><head/><body><p>Switch to this Tx message NOW</p><p>Double-click to reset to the standard 73 message</p></body></html> + + Switch to this Tx message NOW +Double-click to reset to the standard 73 message + padding-left: 15%; padding-right: 15%; padding-top: 3%; padding-bottom: 3% @@ -2503,6 +2637,9 @@ list. The list can be maintained in Settings (F2). <html><head/><body><p>6 digit locators cause 2 different mesages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol.</p></body></html> + + 6 digit locators cause 2 different mesages to be sent, the second contains the full locator but only a hashed callsign, other stations must have decoded the first once before they can decode your call in the second. Check this option to only send 4 digit locators if it will avoid the two message protocol. + Prefer type 1 messages @@ -2792,9 +2929,6 @@ list. The list can be maintained in Settings (F2). Open next in directory - - F6 - @@ -3288,14 +3422,6 @@ list. The list can be maintained in Settings (F2). Fox log - - - Reset Fox log ... - - - <html><head/><body><p>Ths will erase the file FoxQSO.txt and delete the Fox log file which is used for dupe detection.</p></body></html> - - FT8 DXpedition Mode User Guide diff --git a/widgets/messageaveraging.cpp b/widgets/messageaveraging.cpp index fce022842..21f7b07ca 100644 --- a/widgets/messageaveraging.cpp +++ b/widgets/messageaveraging.cpp @@ -8,6 +8,8 @@ #include "qt_helpers.hpp" #include "ui_messageaveraging.h" +#include "moc_messageaveraging.cpp" + MessageAveraging::MessageAveraging(QSettings * settings, QFont const& font, QWidget *parent) : QWidget(parent), settings_ {settings}, diff --git a/widgets/messageaveraging.h b/widgets/messageaveraging.h index 4a8556b24..a5ed7b54d 100644 --- a/widgets/messageaveraging.h +++ b/widgets/messageaveraging.h @@ -14,6 +14,8 @@ namespace Ui { class MessageAveraging : public QWidget { + Q_OBJECT + public: explicit MessageAveraging(QSettings *, QFont const&, QWidget * parent = 0); ~MessageAveraging(); diff --git a/widgets/plotter.cpp b/widgets/plotter.cpp index 60f0892c3..badeff57b 100644 --- a/widgets/plotter.cpp +++ b/widgets/plotter.cpp @@ -123,6 +123,7 @@ void CPlotter::paintEvent(QPaintEvent *) // paint void CPlotter::draw(float swide[], bool bScroll, bool bRed) { + if (!m_TRperiod) return; // not ready to plot yet int j,j0; static int ktop=0; float y,y2,ymin; @@ -240,10 +241,9 @@ void CPlotter::draw(float swide[], bool bScroll, bool bRed) painter1.setPen(Qt::white); QString t; qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000; - int n=(ms/1000) % m_TRperiod; - if(m_mode=="FT4") n=0; + int n = fmod(0.001*ms,m_TRperiod); QDateTime t1=QDateTime::currentDateTimeUtc().addSecs(-n); - if(m_TRperiod < 60 or m_mode=="FT4") { + if(m_TRperiod<60.0) { t=t1.toString("hh:mm:ss") + " " + m_rxBand; } else { t=t1.toString("hh:mm") + " " + m_rxBand; @@ -411,7 +411,7 @@ void CPlotter::DrawOverlay() //DrawOverlay() } float bw=9.0*12000.0/m_nsps; //JT9 - if(m_mode=="FT4") bw=3*12000.0/512.0; //FT4 ### (3x, or 4x???) ### + if(m_mode=="FT4") bw=3*12000.0/576.0; //FT4 ### (3x, or 4x???) ### if(m_mode=="FT8") bw=7*12000.0/1920.0; //FT8 if(m_mode=="JT4") { //JT4 @@ -721,9 +721,9 @@ void CPlotter::mouseDoubleClickEvent (QMouseEvent * event) } } -void CPlotter::setNsps(int ntrperiod, int nsps) //setNsps +void CPlotter::setNsps(double trperiod, int nsps) //setNsps { - m_TRperiod=ntrperiod; + m_TRperiod=trperiod; m_nsps=nsps; m_fftBinWidth=1500.0/2048.0; if(m_nsps==15360) m_fftBinWidth=1500.0/2048.0; diff --git a/widgets/plotter.h b/widgets/plotter.h index e243c1777..2cbfd202b 100644 --- a/widgets/plotter.h +++ b/widgets/plotter.h @@ -56,7 +56,7 @@ public: void DrawOverlay(); int rxFreq(); void setFsample(int n); - void setNsps(int ntrperiod, int nsps); + void setNsps(double trperiod, int nsps); void setTxFreq(int n); void setMode(QString mode); void setSubMode(int n); @@ -145,6 +145,7 @@ private: double m_fftBinWidth; double m_dialFreq; double m_xOffset; + double m_TRperiod; float m_sum[2048]; @@ -161,7 +162,6 @@ private: qint32 m_h; qint32 m_h1; qint32 m_h2; - qint32 m_TRperiod; qint32 m_rxFreq; qint32 m_txFreq; qint32 m_fMin; diff --git a/widgets/widegraph.cpp b/widgets/widegraph.cpp index 1f3110cee..6234f731a 100644 --- a/widgets/widegraph.cpp +++ b/widgets/widegraph.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "ui_widegraph.h" #include "commons.h" #include "Configuration.hpp" @@ -23,7 +24,7 @@ WideGraph::WideGraph(QSettings * settings, QWidget *parent) : ui(new Ui::WideGraph), m_settings (settings), m_palettes_path {":/Palettes"}, - m_ntr0 {0}, + m_tr0 {0.0}, m_n {0}, m_bHaveTransmitted {false} { @@ -186,9 +187,8 @@ void WideGraph::dataSink2(float s[], float df3, int ihsym, int ndiskdata) //dat // Time according to this computer qint64 ms = QDateTime::currentMSecsSinceEpoch() % 86400000; - int ntr = (ms/1000) % m_TRperiod; - if((ndiskdata && ihsym <= m_waterfallAvg) || (!ndiskdata && - (ntrwidePlot->draw(swide,true,false); } } @@ -278,11 +278,11 @@ int WideGraph::fSpan() return ui->widePlot->fSpan (); } -void WideGraph::setPeriod(int ntrperiod, int nsps) //SetPeriod +void WideGraph::setPeriod(double trperiod, int nsps) //SetPeriod { - m_TRperiod=ntrperiod; + m_TRperiod=trperiod; m_nsps=nsps; - ui->widePlot->setNsps(ntrperiod, nsps); + ui->widePlot->setNsps(trperiod, nsps); } void WideGraph::setTxFreq(int n) //setTxFreq diff --git a/widgets/widegraph.h b/widgets/widegraph.h index 2b172ef7d..c87bab050 100644 --- a/widgets/widegraph.h +++ b/widgets/widegraph.h @@ -35,7 +35,7 @@ public: int fSpan(); void saveSettings(); void setFsample(int n); - void setPeriod(int ntrperiod, int nsps); + void setPeriod(double trperiod, int nsps); void setTxFreq(int n); void setMode(QString mode); void setSubMode(int n); @@ -95,10 +95,11 @@ private: WFPalette m_userPalette; QHash m_fMinPerBand; + double m_tr0; + double m_TRperiod; + qint32 m_waterfallAvg; - qint32 m_TRperiod; qint32 m_nsps; - qint32 m_ntr0; qint32 m_fMax; qint32 m_nSubMode; qint32 m_nsmo; diff --git a/widgets/widgets.pri b/widgets/widgets.pri index 24ddd5a3c..3c2cb2444 100644 --- a/widgets/widgets.pri +++ b/widgets/widgets.pri @@ -8,18 +8,20 @@ SOURCES += \ widgets/fastplot.cpp widgets/MessageBox.cpp \ widgets/colorhighlighting.cpp widgets/ExportCabrillo.cpp \ widgets/AbstractLogWindow.cpp \ + widgets/FrequencyLineEdit.cpp widgets/FrequencyDeltaLineEdit.cpp \ widgets/FoxLogWindow.cpp widgets/CabrilloLogWindow.cpp HEADERS += \ widgets/mainwindow.h widgets/plotter.h \ widgets/about.h widgets/widegraph.h \ widgets/displaytext.h widgets/logqso.h widgets/LettersSpinBox.hpp \ - widgets/FrequencyLineEdit.hpp widgets/signalmeter.h \ + widgets/FrequencyLineEdit.hpp widgets/FrequencyDeltaLineEdit.hpp widgets/signalmeter.h \ widgets/meterwidget.h widgets/messageaveraging.h \ widgets/echoplot.h widgets/echograph.h widgets/fastgraph.h \ widgets/fastplot.h widgets/MessageBox.hpp widgets/colorhighlighting.h \ widgets/ExportCabrillo.h widgets/AbstractLogWindow.hpp \ - widgets/FoxLogWindow.hpp widgets/CabrilloLogWindow.hpp + widgets/FoxLogWindow.hpp widgets/CabrilloLogWindow.hpp \ + widgets/DateTimeEdit.hpp FORMS += \ widgets/mainwindow.ui widgets/about.ui \