From bce56796eb2939324f6aa735ccfa4b1f892fe067 Mon Sep 17 00:00:00 2001 From: SDRSharpR Date: Sat, 24 Mar 2018 23:01:41 -0700 Subject: [PATCH] SDRSharp Build 1632 Full Source (VS2017) --- Build Order.txt | 6 + Core Includes/BandPlan.xml | 95 + Core Includes/FrontEnds.xml | 13 + Core Includes/NDde.dll | Bin 0 -> 110592 bytes Core Includes/Plugins.xml | 22 + Core Includes/PortAudio.dll | Bin 0 -> 81920 bytes Core Includes/SDRSharp.AfedriSDRNet.dll | Bin 0 -> 19456 bytes Core Includes/SDRSharp.FUNcube.dll | Bin 0 -> 79360 bytes Core Includes/SDRSharp.FUNcubeProPlus.dll | Bin 0 -> 31744 bytes Core Includes/SDRSharp.HackRF.dll | Bin 0 -> 22528 bytes Core Includes/SDRSharp.RTLSDR.dll | Bin 0 -> 28672 bytes Core Includes/SDRSharp.RTLTCP.dll | Bin 0 -> 16896 bytes Core Includes/SDRSharp.SDRIP.dll | Bin 0 -> 18944 bytes Core Includes/SDRSharp.SDRIQ.dll | Bin 0 -> 18432 bytes Core Includes/SDRSharp.SoftRock.dll | Bin 0 -> 6144 bytes Core Includes/SRDLL.dll | Bin 0 -> 67584 bytes Core Includes/airspy.dll | Bin 0 -> 91136 bytes Core Includes/airspyhf.dll | Bin 0 -> 103936 bytes Core Includes/digital_frequencies.xml | 2 + Core Includes/frequencies.xml | 57 + Core Includes/hackrf.dll | Bin 0 -> 79360 bytes Core Includes/install-rtlsdr.bat | 17 + Core Includes/inverted_frequencies.xml | 2 + Core Includes/libusb-1.0.dll | Bin 0 -> 97280 bytes Core Includes/modesparser.dll | Bin 0 -> 76800 bytes Core Includes/msvcr100.dll | Bin 0 -> 773968 bytes Core Includes/pthreadVCE2.dll | Bin 0 -> 61952 bytes Core Includes/rtlsdr.dll | Bin 0 -> 44032 bytes Core Includes/sdriq.dll | Bin 0 -> 13824 bytes Core Includes/shark.dll | Bin 0 -> 121856 bytes .../Properties/AssemblyInfo.cs | 15 + .../Resources.cs | 82 + .../Resources.resource | 166 + .../Resources.resx | 166 + .../SDRSharp.CollapsiblePanel.csproj | 65 + .../SDRSharp.CollapsiblePanel.sln | 25 + .../CollapsiblePanel.cs | 271 + .../CollapsiblePanel.resource | 163 + .../CollapsiblePanel.resx | 163 + .../CollapsiblePanelDesigner.cs | 17 + .../SDRSharp.CollapsiblePanel/ContentPanel.cs | 32 + .../ContentPanelDesigner.cs | 16 + .../PanelStateOptions.cs | 8 + SDRSharp.Common/Properties/AssemblyInfo.cs | 17 + SDRSharp.Common/SDRSharp.Common.csproj | 59 + SDRSharp.Common/SDRSharp.Common.sln | 25 + .../SDRSharp.Common/ByteSamplesEventArgs.cs | 19 + .../ComplexSamplesEventArgs.cs | 26 + SDRSharp.Common/SDRSharp.Common/IFFTSource.cs | 36 + .../SDRSharp.Common/ISharpControl.cs | 371 ++ .../SDRSharp.Common/ISharpPlugin.cs | 21 + SDRSharp.Common/SDRSharp.Common/IVFOSource.cs | 27 + .../SDRSharp.Common/PluginPosition.cs | 10 + .../SDRSharp.Common/RealSamplesEventArgs.cs | 25 + .../SamplesAvailableDelegate.cs | 4 + .../refs SDRSharp.PanView and Radio.txt | 0 .../SDRSharp.FrequencyEdit.sln | 22 + .../SDRSharp.FrequencyEdit/EntryMode.cs | 11 + .../FrequencyChangingEventArgs.cs | 15 + .../SDRSharp.FrequencyEdit/FrequencyEdit.cs | 749 +++ .../FrequencyEditDigit.cs | 271 + .../FrequencyEditDigitClickEventArgs.cs | 18 + .../FrequencyEditSeparator.cs | 75 + .../SDRSharp.FrequencyEdit/IRenderable.cs | 9 + .../OnDigitClickDelegate.cs | 6 + .../Properties/AssemblyInfo.cs | 24 + .../Properties/Resources.Designer.cs | 59 + .../Properties/Resources.resx | 177 + .../SDRSharp.FrequencyEdit.csproj | 72 + SDRSharp.PanView/Properties/AssemblyInfo.cs | 15 + SDRSharp.PanView/SDRSharp.PanView.csproj | 73 + SDRSharp.PanView/SDRSharp.PanView.sln | 25 + SDRSharp.PanView/SDRSharp.PanView/BandType.cs | 9 + .../SDRSharp.PanView/BandwidthEventArgs.cs | 38 + .../SDRSharp.PanView/CustomPaintEventArgs.cs | 38 + .../CustomPaintEventHandler.cs | 4 + .../SDRSharp.PanView/FrequencyChangeSource.cs | 9 + .../SDRSharp.PanView/FrequencyEventArgs.cs | 31 + .../SDRSharp.PanView/GradientDialog.cs | 269 + .../SDRSharp.PanView/GradientDialog.resx | 120 + .../SDRSharp.PanView/LineInsertEventArgs.cs | 25 + .../LineInsertEventHandler.cs | 4 + .../ManualBandwidthChangeEventHandler.cs | 4 + .../ManualFrequencyChangeEventHandler.cs | 4 + .../SDRSharp.PanView/PeakDetector.cs | 53 + .../SDRSharp.PanView/SpectrumAnalyzer.cs | 1730 +++++ .../SDRSharp.PanView/SpectrumStyle.cs | 12 + .../SDRSharp.PanView/Waterfall.cs | 1280 ++++ SDRSharp.PanView/refs Radio.txt | 0 .../PortAudioSharp/PaDeviceIndex.cs | 8 + SDRSharp.Radio/PortAudioSharp/PaDeviceInfo.cs | 33 + SDRSharp.Radio/PortAudioSharp/PaError.cs | 36 + .../PortAudioSharp/PaHostApiInfo.cs | 25 + .../PortAudioSharp/PaHostApiTypeId.cs | 20 + .../PortAudioSharp/PaHostErrorInfo.cs | 19 + .../PortAudioSharp/PaSampleFormat.cs | 14 + .../PaStreamCallbackDelegate.cs | 8 + .../PortAudioSharp/PaStreamCallbackFlags.cs | 11 + .../PortAudioSharp/PaStreamCallbackResult.cs | 9 + .../PaStreamCallbackTimeInfo.cs | 16 + .../PaStreamFinishedCallbackDelegate.cs | 8 + .../PortAudioSharp/PaStreamFlags.cs | 12 + SDRSharp.Radio/PortAudioSharp/PaStreamInfo.cs | 18 + .../PortAudioSharp/PaStreamParameters.cs | 22 + SDRSharp.Radio/PortAudioSharp/PortAudioAPI.cs | 202 + SDRSharp.Radio/Properties/AssemblyInfo.cs | 15 + .../AudioBufferAvailableDelegate.cs | 4 + .../AudioBufferNeededDelegate.cs | 4 + .../SDRSharp.Radio.PortAudio/AudioDevice.cs | 68 + .../DeviceDirection.cs | 9 + .../SDRSharp.Radio.PortAudio/Int24.cs | 16 + .../SDRSharp.Radio.PortAudio/WaveDuplex.cs | 83 + .../SDRSharp.Radio.PortAudio/WaveFile.cs | 298 + .../SDRSharp.Radio.PortAudio/WavePlayer.cs | 82 + .../SDRSharp.Radio.PortAudio/WaveRecorder.cs | 82 + SDRSharp.Radio/SDRSharp.Radio.csproj | 149 + SDRSharp.Radio/SDRSharp.Radio.sln | 25 + SDRSharp.Radio/SDRSharp.Radio/AmAntiFading.cs | 29 + SDRSharp.Radio/SDRSharp.Radio/AmDetector.cs | 62 + .../SDRSharp.Radio/AutomaticGainControl.cs | 287 + SDRSharp.Radio/SDRSharp.Radio/BlockMode.cs | 10 + .../SDRSharp.Radio/BufferNeededDelegate.cs | 4 + .../SDRSharp.Radio/CarrierLocker.cs | 120 + .../SDRSharp.Radio/CircularBuffer.cs | 169 + SDRSharp.Radio/SDRSharp.Radio/Complex.cs | 183 + .../SDRSharp.Radio/ComplexCircularBuffer.cs | 30 + .../SDRSharp.Radio/ComplexDecimator.cs | 49 + .../SDRSharp.Radio/ComplexFifoStream.cs | 285 + .../SDRSharp.Radio/ComplexFilter.cs | 67 + SDRSharp.Radio/SDRSharp.Radio/CwDetector.cs | 40 + .../SDRSharp.Radio/DSPThreadPool.cs | 52 + SDRSharp.Radio/SDRSharp.Radio/DcRemover.cs | 56 + SDRSharp.Radio/SDRSharp.Radio/DetectorType.cs | 14 + .../SDRSharp.Radio/DownConverter.cs | 81 + .../SDRSharp.Radio/FilterBuilder.cs | 387 ++ SDRSharp.Radio/SDRSharp.Radio/FirFilter.cs | 68 + .../SDRSharp.Radio/FloatCircularBuffer.cs | 30 + .../SDRSharp.Radio/FloatDecimator.cs | 49 + .../SDRSharp.Radio/FloatFifoStream.cs | 285 + SDRSharp.Radio/SDRSharp.Radio/FmDetector.cs | 157 + SDRSharp.Radio/SDRSharp.Radio/FmMode.cs | 8 + SDRSharp.Radio/SDRSharp.Radio/Fourier.cs | 224 + .../SDRSharp.Radio/FrequencyTranslator.cs | 70 + SDRSharp.Radio/SDRSharp.Radio/HookManager.cs | 221 + .../SDRSharp.Radio/IBaseProcessor.cs | 11 + .../IConfigurationPanelProvider.cs | 12 + .../SDRSharp.Radio/IConnectableSource.cs | 14 + .../SDRSharp.Radio/IControlAwareObject.cs | 7 + .../IFloatingConfigDialogProvider.cs | 11 + .../SDRSharp.Radio/IFrontendController.cs | 9 + .../SDRSharp.Radio/IFrontendOffset.cs | 10 + SDRSharp.Radio/SDRSharp.Radio/IIQProcessor.cs | 7 + .../SDRSharp.Radio/IIQStreamController.cs | 14 + .../SDRSharp.Radio/INonBlockingController.cs | 6 + SDRSharp.Radio/SDRSharp.Radio/IQBalancer.cs | 242 + SDRSharp.Radio/SDRSharp.Radio/IQFirFilter.cs | 68 + .../SDRSharp.Radio/IRdsBitStreamProcessor.cs | 7 + .../SDRSharp.Radio/IRealProcessor.cs | 7 + .../SDRSharp.Radio/ISampleRateChangeSource.cs | 9 + .../SDRSharp.Radio/ISoundcardController.cs | 15 + .../SDRSharp.Radio/ISpectrumProvider.cs | 10 + .../SDRSharp.Radio/IStreamProcessor.cs | 10 + .../SDRSharp.Radio/ITunableSource.cs | 26 + SDRSharp.Radio/SDRSharp.Radio/IirFilter.cs | 105 + .../SDRSharp.Radio/IirFilterType.cs | 10 + SDRSharp.Radio/SDRSharp.Radio/Oscillator.cs | 100 + .../SDRSharp.Radio/OverlapAddProcessor.cs | 121 + .../OverlapCrossfadeProcessor.cs | 130 + .../SDRSharp.Radio/OverlapSaveProcessor.cs | 95 + .../SDRSharp.Radio/OverlapSlideProcessor.cs | 136 + SDRSharp.Radio/SDRSharp.Radio/Pll.cs | 295 + .../SDRSharp.Radio/ProcessorType.cs | 12 + SDRSharp.Radio/SDRSharp.Radio/RdsDecoder.cs | 229 + .../SDRSharp.Radio/RdsDetectorBank.cs | 73 + .../SDRSharp.Radio/RdsDumpGroups.cs | 163 + SDRSharp.Radio/SDRSharp.Radio/RdsFrame.cs | 24 + .../RdsFrameAvailableDelegate.cs | 4 + SDRSharp.Radio/SDRSharp.Radio/Resampler.cs | 168 + .../SamplesAvailableDelegate.cs | 4 + SDRSharp.Radio/SDRSharp.Radio/SharpEvent.cs | 73 + .../SDRSharp.Radio/SharpThreadPool.cs | 117 + .../SDRSharp.Radio/SideBandDetector.cs | 13 + .../SDRSharp.Radio/StereoDecoder.cs | 214 + .../SDRSharp.Radio/StreamControl.cs | 551 ++ .../SDRSharp.Radio/SyndromeDetector.cs | 189 + SDRSharp.Radio/SDRSharp.Radio/Trig.cs | 100 + SDRSharp.Radio/SDRSharp.Radio/TuningStyle.cs | 9 + SDRSharp.Radio/SDRSharp.Radio/UnsafeBuffer.cs | 93 + SDRSharp.Radio/SDRSharp.Radio/Utils.cs | 351 ++ SDRSharp.Radio/SDRSharp.Radio/Vfo.cs | 871 +++ SDRSharp.Radio/SDRSharp.Radio/WindowType.cs | 13 + .../refs to PortAudio.dll & Shark.dll.txt | 0 SDRSharp/Properties/AssemblyInfo.cs | 18 + SDRSharp/Properties/Resources.Designer.cs | 163 + SDRSharp/Properties/Resources.resx | 638 ++ .../SDRSharp.FrontEnds.Airspy/AirspyDevice.cs | 1060 ++++ .../AirspyGainMode.cs | 9 + .../SDRSharp.FrontEnds.Airspy/AirspyIO.cs | 224 + .../ControllerPanel.cs | 1520 +++++ .../ControllerPanel.resx | 120 + .../ConversionFilters.cs | 109 + .../NativeMethods.cs | 135 + .../SDRSharp.FrontEnds.Airspy/airspy_error.cs | 17 + .../airspy_gpio_pin_t.cs | 38 + .../airspy_gpio_port_t.cs | 14 + .../airspy_sample_block_cb_fn.cs | 7 + .../airspy_sample_type.cs | 10 + .../airspy_transfer.cs | 19 + .../AirspyHFDevice.cs | 245 + .../SDRSharp.FrontEnds.AirspyHF/AirspyHFIO.cs | 242 + .../ControllerPanel.cs | 309 + .../ControllerPanel.resx | 120 + .../NativeMethods.cs | 56 + .../airspyhf_error.cs | 8 + .../airspyhf_sample_cb.cs | 7 + .../airspyhf_transfer.cs | 18 + .../ClientHandshake.cs | 9 + .../ClientSync.cs | 23 + .../CommandHeader.cs | 9 + .../CommandType.cs | 10 + .../SDRSharp.FrontEnds.SpyServer/Constants.cs | 42 + .../ControllerPanel.cs | 579 ++ .../ControllerPanel.resx | 120 + .../DeviceInfo.cs | 29 + .../DeviceType.cs | 10 + .../MessageHeader.cs | 15 + .../MessageType.cs | 23 + .../SettingTarget.cs | 9 + .../SettingType.cs | 19 + .../SDRSharp.FrontEnds.SpyServer/SpyClient.cs | 1074 ++++ .../SpyServerIO.cs | 584 ++ .../StreamFormat.cs | 12 + .../StreamType.cs | 10 + .../StreamingMode.cs | 11 + SDRSharp/SDRSharp.csproj | 133 + SDRSharp/SDRSharp.sln | 25 + SDRSharp/SDRSharp/App.config | 213 + SDRSharp/SDRSharp/MainForm.cs | 5611 +++++++++++++++++ SDRSharp/SDRSharp/MainForm.resource | 283 + SDRSharp/SDRSharp/MainForm.resx | 283 + SDRSharp/SDRSharp/Program.cs | 48 + SDRSharp/SDRSharp/SDRSharp.ico | Bin 0 -> 24838 bytes SDRSharp/SDRSharp/SharpControlProxy.cs | 1296 ++++ SDRSharp/SDRSharp/app.manifest | 12 + ...nView Radio & airspy.dll airspyhf.dll .txt | 0 SDRSharp/ver 1.0.0.1632.txt | 0 246 files changed, 31983 insertions(+) create mode 100644 Build Order.txt create mode 100644 Core Includes/BandPlan.xml create mode 100644 Core Includes/FrontEnds.xml create mode 100644 Core Includes/NDde.dll create mode 100644 Core Includes/Plugins.xml create mode 100644 Core Includes/PortAudio.dll create mode 100644 Core Includes/SDRSharp.AfedriSDRNet.dll create mode 100644 Core Includes/SDRSharp.FUNcube.dll create mode 100644 Core Includes/SDRSharp.FUNcubeProPlus.dll create mode 100644 Core Includes/SDRSharp.HackRF.dll create mode 100644 Core Includes/SDRSharp.RTLSDR.dll create mode 100644 Core Includes/SDRSharp.RTLTCP.dll create mode 100644 Core Includes/SDRSharp.SDRIP.dll create mode 100644 Core Includes/SDRSharp.SDRIQ.dll create mode 100644 Core Includes/SDRSharp.SoftRock.dll create mode 100644 Core Includes/SRDLL.dll create mode 100644 Core Includes/airspy.dll create mode 100644 Core Includes/airspyhf.dll create mode 100644 Core Includes/digital_frequencies.xml create mode 100644 Core Includes/frequencies.xml create mode 100644 Core Includes/hackrf.dll create mode 100644 Core Includes/install-rtlsdr.bat create mode 100644 Core Includes/inverted_frequencies.xml create mode 100644 Core Includes/libusb-1.0.dll create mode 100644 Core Includes/modesparser.dll create mode 100644 Core Includes/msvcr100.dll create mode 100644 Core Includes/pthreadVCE2.dll create mode 100644 Core Includes/rtlsdr.dll create mode 100644 Core Includes/sdriq.dll create mode 100644 Core Includes/shark.dll create mode 100644 SDRSharp.CollapsiblePanel/Properties/AssemblyInfo.cs create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.Properties/Resources.cs create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.Properties/Resources.resource create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.Properties/Resources.resx create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.csproj create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.sln create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.cs create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.resource create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.resx create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanelDesigner.cs create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/ContentPanel.cs create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/ContentPanelDesigner.cs create mode 100644 SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/PanelStateOptions.cs create mode 100644 SDRSharp.Common/Properties/AssemblyInfo.cs create mode 100644 SDRSharp.Common/SDRSharp.Common.csproj create mode 100644 SDRSharp.Common/SDRSharp.Common.sln create mode 100644 SDRSharp.Common/SDRSharp.Common/ByteSamplesEventArgs.cs create mode 100644 SDRSharp.Common/SDRSharp.Common/ComplexSamplesEventArgs.cs create mode 100644 SDRSharp.Common/SDRSharp.Common/IFFTSource.cs create mode 100644 SDRSharp.Common/SDRSharp.Common/ISharpControl.cs create mode 100644 SDRSharp.Common/SDRSharp.Common/ISharpPlugin.cs create mode 100644 SDRSharp.Common/SDRSharp.Common/IVFOSource.cs create mode 100644 SDRSharp.Common/SDRSharp.Common/PluginPosition.cs create mode 100644 SDRSharp.Common/SDRSharp.Common/RealSamplesEventArgs.cs create mode 100644 SDRSharp.Common/SDRSharp.Common/SamplesAvailableDelegate.cs create mode 100644 SDRSharp.Common/refs SDRSharp.PanView and Radio.txt create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit.sln create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/EntryMode.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyChangingEventArgs.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEdit.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditDigit.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditDigitClickEventArgs.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditSeparator.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/IRenderable.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/OnDigitClickDelegate.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/AssemblyInfo.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/Resources.Designer.cs create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/Resources.resx create mode 100644 SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit.csproj create mode 100644 SDRSharp.PanView/Properties/AssemblyInfo.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView.csproj create mode 100644 SDRSharp.PanView/SDRSharp.PanView.sln create mode 100644 SDRSharp.PanView/SDRSharp.PanView/BandType.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/BandwidthEventArgs.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/CustomPaintEventArgs.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/CustomPaintEventHandler.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/FrequencyChangeSource.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/FrequencyEventArgs.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/GradientDialog.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/GradientDialog.resx create mode 100644 SDRSharp.PanView/SDRSharp.PanView/LineInsertEventArgs.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/LineInsertEventHandler.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/ManualBandwidthChangeEventHandler.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/ManualFrequencyChangeEventHandler.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/PeakDetector.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/SpectrumAnalyzer.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/SpectrumStyle.cs create mode 100644 SDRSharp.PanView/SDRSharp.PanView/Waterfall.cs create mode 100644 SDRSharp.PanView/refs Radio.txt create mode 100644 SDRSharp.Radio/PortAudioSharp/PaDeviceIndex.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaDeviceInfo.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaError.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaHostApiInfo.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaHostApiTypeId.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaHostErrorInfo.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaSampleFormat.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaStreamCallbackDelegate.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaStreamCallbackFlags.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaStreamCallbackResult.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaStreamCallbackTimeInfo.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaStreamFinishedCallbackDelegate.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaStreamFlags.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaStreamInfo.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PaStreamParameters.cs create mode 100644 SDRSharp.Radio/PortAudioSharp/PortAudioAPI.cs create mode 100644 SDRSharp.Radio/Properties/AssemblyInfo.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioBufferAvailableDelegate.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioBufferNeededDelegate.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioDevice.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.PortAudio/DeviceDirection.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.PortAudio/Int24.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveDuplex.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveFile.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.PortAudio/WavePlayer.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveRecorder.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio.csproj create mode 100644 SDRSharp.Radio/SDRSharp.Radio.sln create mode 100644 SDRSharp.Radio/SDRSharp.Radio/AmAntiFading.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/AmDetector.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/AutomaticGainControl.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/BlockMode.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/BufferNeededDelegate.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/CarrierLocker.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/CircularBuffer.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/Complex.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/ComplexCircularBuffer.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/ComplexDecimator.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/ComplexFifoStream.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/ComplexFilter.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/CwDetector.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/DSPThreadPool.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/DcRemover.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/DetectorType.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/DownConverter.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/FilterBuilder.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/FirFilter.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/FloatCircularBuffer.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/FloatDecimator.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/FloatFifoStream.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/FmDetector.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/FmMode.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/Fourier.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/FrequencyTranslator.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/HookManager.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IBaseProcessor.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IConfigurationPanelProvider.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IConnectableSource.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IControlAwareObject.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IFloatingConfigDialogProvider.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IFrontendController.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IFrontendOffset.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IIQProcessor.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IIQStreamController.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/INonBlockingController.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IQBalancer.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IQFirFilter.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IRdsBitStreamProcessor.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IRealProcessor.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/ISampleRateChangeSource.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/ISoundcardController.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/ISpectrumProvider.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IStreamProcessor.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/ITunableSource.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IirFilter.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/IirFilterType.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/Oscillator.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/OverlapAddProcessor.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/OverlapCrossfadeProcessor.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/OverlapSaveProcessor.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/OverlapSlideProcessor.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/Pll.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/ProcessorType.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/RdsDecoder.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/RdsDetectorBank.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/RdsDumpGroups.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/RdsFrame.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/RdsFrameAvailableDelegate.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/Resampler.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/SamplesAvailableDelegate.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/SharpEvent.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/SharpThreadPool.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/SideBandDetector.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/StereoDecoder.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/StreamControl.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/SyndromeDetector.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/Trig.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/TuningStyle.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/UnsafeBuffer.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/Utils.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/Vfo.cs create mode 100644 SDRSharp.Radio/SDRSharp.Radio/WindowType.cs create mode 100644 SDRSharp.Radio/refs to PortAudio.dll & Shark.dll.txt create mode 100644 SDRSharp/Properties/AssemblyInfo.cs create mode 100644 SDRSharp/Properties/Resources.Designer.cs create mode 100644 SDRSharp/Properties/Resources.resx create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyDevice.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyGainMode.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyIO.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/ControllerPanel.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/ControllerPanel.resx create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/ConversionFilters.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/NativeMethods.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_error.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_gpio_pin_t.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_gpio_port_t.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_sample_block_cb_fn.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_sample_type.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_transfer.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.AirspyHF/AirspyHFDevice.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.AirspyHF/AirspyHFIO.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.AirspyHF/ControllerPanel.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.AirspyHF/ControllerPanel.resx create mode 100644 SDRSharp/SDRSharp.FrontEnds.AirspyHF/NativeMethods.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_error.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_sample_cb.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_transfer.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/ClientHandshake.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/ClientSync.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/CommandHeader.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/CommandType.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/Constants.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/ControllerPanel.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/ControllerPanel.resx create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/DeviceInfo.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/DeviceType.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/MessageHeader.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/MessageType.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/SettingTarget.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/SettingType.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/SpyClient.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/SpyServerIO.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamFormat.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamType.cs create mode 100644 SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamingMode.cs create mode 100644 SDRSharp/SDRSharp.csproj create mode 100644 SDRSharp/SDRSharp.sln create mode 100644 SDRSharp/SDRSharp/App.config create mode 100644 SDRSharp/SDRSharp/MainForm.cs create mode 100644 SDRSharp/SDRSharp/MainForm.resource create mode 100644 SDRSharp/SDRSharp/MainForm.resx create mode 100644 SDRSharp/SDRSharp/Program.cs create mode 100644 SDRSharp/SDRSharp/SDRSharp.ico create mode 100644 SDRSharp/SDRSharp/SharpControlProxy.cs create mode 100644 SDRSharp/SDRSharp/app.manifest create mode 100644 SDRSharp/refs Panel Common FreqEdit PanView Radio & airspy.dll airspyhf.dll .txt create mode 100644 SDRSharp/ver 1.0.0.1632.txt diff --git a/Build Order.txt b/Build Order.txt new file mode 100644 index 0000000..2be7d58 --- /dev/null +++ b/Build Order.txt @@ -0,0 +1,6 @@ +Radio +PanView +Common +CollaspiblePanel +FrequencyEdit +SDRSharp \ No newline at end of file diff --git a/Core Includes/BandPlan.xml b/Core Includes/BandPlan.xml new file mode 100644 index 0000000..eed4739 --- /dev/null +++ b/Core Includes/BandPlan.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Long Wave + Medium Wave + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + Shortwave Broadcast + FM Broadcast + Air Band VOR/ILS + Air Band Voice + 160m Ham Band + 80m Ham Band + 60m Ham Band + 40m Ham Band + + 30m Ham Band + 20m Ham Band + 17m Ham Band + 15m Ham Band + 12m Ham Band + CB + 10m Ham Band + 6m Ham Band + 2m Ham Band + + + + + + Marine + 1.25m Ham Band + Military Air + Mil Sat + 70cm Ham Band + + + + PMR446 + 33cm Ham Band + + + + + 23cm Ham Band + + + 13cm Ham Band + 13cm Ham Band + \ No newline at end of file diff --git a/Core Includes/FrontEnds.xml b/Core Includes/FrontEnds.xml new file mode 100644 index 0000000..388b916 --- /dev/null +++ b/Core Includes/FrontEnds.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/Core Includes/NDde.dll b/Core Includes/NDde.dll new file mode 100644 index 0000000000000000000000000000000000000000..1cd6ddda4573f255ae83cc761eb913f11ccf4101 GIT binary patch literal 110592 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

3}FF{VOd#%|dr5dhz-Og9> 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 CbeJpv literal 0 HcmV?d00001 diff --git a/Core Includes/Plugins.xml b/Core Includes/Plugins.xml new file mode 100644 index 0000000..e5d98b1 --- /dev/null +++ b/Core Includes/Plugins.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core Includes/PortAudio.dll b/Core Includes/PortAudio.dll new file mode 100644 index 0000000000000000000000000000000000000000..4588ded34a848cfddf9fdee922831f23599a373a GIT binary patch literal 81920 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 literal 0 HcmV?d00001 diff --git a/Core Includes/SDRSharp.AfedriSDRNet.dll b/Core Includes/SDRSharp.AfedriSDRNet.dll new file mode 100644 index 0000000000000000000000000000000000000000..ca76364683a7e066562500deac7adf7143c8a7d1 GIT binary patch literal 19456 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⁡q3?0SAa4Pm>kkNV|MElcEqn3=XU^a-2#gv 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 R9dMIEe+}^8F@Ng}{0BnD?dbpj literal 0 HcmV?d00001 diff --git a/Core Includes/SDRSharp.FUNcubeProPlus.dll b/Core Includes/SDRSharp.FUNcubeProPlus.dll new file mode 100644 index 0000000000000000000000000000000000000000..d15394df75e1347a3e0665b9d30fabdbeb8c31b8 GIT binary patch literal 31744 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 literal 0 HcmV?d00001 diff --git a/Core Includes/SDRSharp.HackRF.dll b/Core Includes/SDRSharp.HackRF.dll new file mode 100644 index 0000000000000000000000000000000000000000..5a589e0f58401225d586e186802a49ddebe99453 GIT binary patch literal 22528 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 literal 0 HcmV?d00001 diff --git a/Core Includes/SDRSharp.RTLSDR.dll b/Core Includes/SDRSharp.RTLSDR.dll new file mode 100644 index 0000000000000000000000000000000000000000..fd3007c21c8c06ee5a317c8af7092e9b6532032c GIT binary patch literal 28672 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 literal 0 HcmV?d00001 diff --git a/Core Includes/SDRSharp.SDRIP.dll b/Core Includes/SDRSharp.SDRIP.dll new file mode 100644 index 0000000000000000000000000000000000000000..0c8cedda9dbb3b36b81b06360a800d03d461d3d2 GIT binary patch literal 18944 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 R{Ox-aZo>cn=igrh{x@s0U`YS~ literal 0 HcmV?d00001 diff --git a/Core Includes/SDRSharp.SDRIQ.dll b/Core Includes/SDRSharp.SDRIQ.dll new file mode 100644 index 0000000000000000000000000000000000000000..c19a3685bdcfdba6f572d3d3a66e41aefb6f4e00 GIT binary patch literal 18432 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 literal 0 HcmV?d00001 diff --git a/Core Includes/SDRSharp.SoftRock.dll b/Core Includes/SDRSharp.SoftRock.dll new file mode 100644 index 0000000000000000000000000000000000000000..1d58883c74835dd37f26375120968869581f8c3d GIT binary patch literal 6144 zcmeHLYiu0V6+UxkysK?dZy*& zozE(RFYg?iGd->9IU%LjahT4nD91T#^?PfwCMzmC?Gfk!G`=k=q!^&j4+%S<2 zLhmqldWn9*fmmIpi9Q2bBtx`)HSgnajVQK)9|L}T1)lMZ(?0O8uLS^4+6I4C7L8~+ z<9cohL}^*Sf6nX%Yh)IFxsU)yYB`vgH z!gB4+CZe+muo@r*v!Y*aK@`$6fp}{QDx=~o#>VTM_~vwS(|r00jUISholg&lFYy2= zkV3TMX|{0#=7+MjR2xReFUEIk(-RiW$1hS;+R668&N${*SYE~zG&P0bM=z?oFVadm zmF3oF1#N>23~F0PDVQJK9qnLEOZR5_PM$?HBDc?{ZDB1FZq690(b}sZ}vYGB|ch>=)yNN8o z3)nXuXNj_~YLfc}-!<)7k0l;Pd=8@R7%$LE=<_k@I5wWop?wYb931L6VmU?NT!1RK z-u;8kU=jU8>E?aL`(-1lipq4}dN5ILS8jR1nGTDkEOf}0=^>4E@Hys|`9yzKxX;w} z%0@Lxvl5;sp{}KUm?}y?qQfFef0M9V;r^h6zoPFdQMyLlgi)^(!@KBUBuX@oU| zx}da?7hpeC&j5QQkX%sjR@Tw^0DDmV3a}?7c7OYOuyY+fRUg;>z8C_JcgcQ0LES`} zO1~GRMW~{Z)?CR0xnZVBY_P16F3!umay6i-KQ|z6;bH`cJv|C zKGdVw!S4wL`wwbm_yoIim?HVe}HbFMp$P$dYq`ZPbSia?QJz{iu zsh?!f4-Prynq?fOWBpWcX8cj7bSghg6|dyDmRY0|x^FHR<6eELT=Iq=G)@aT4 z%?iA%RH3eDS}?3Ja6z|f1{G@6s%v=OfNATNc?N_<&o?TWU~Fc>aM=soR8+sP=$PT> zoEk5I;ro)F8!gP~ZZ#9GBo#(;gM*o}Wl>=@uTGV7U}=V{hAmes@5!#`E_X0ZFgJxk z?JIG3mMt`9EF++VvyAFx)1i}w>p(d)47kP}=)qFi%kS;)E08C%EmosK`M7<$AvuuDjCr(x`S$fHYkh8=QZRxA348@)&$*^$?C$i=e#%|Ar0iZ5Aw}6PqDc{LN3Ip^?P{|UM@;}rBoncppP8K4 z((~3sk#T5_@N+uC&*}C%iGLZGRzzAiXaRj4rnKki7+r_kq>pYPjjl$`(_Y*bts}Vh zvT)*Nd?sCuUWDJtOW(^VOZNt6HH^i|)z5^)#*SD%`kh*sXgjswj2+?^D}J3?KUM)- z_>gVXd{?(RwGo_kvvjkuIOd!(>_f%<`}KXLeb;s!=Ah}KwZtceuS%Ha|T4zWOubAaOzigS45pd?Wf zY6{#G#Zi-}iI{@hm&+CW{2LRSZgutQ3CBKqx@5?-IyUDzcX|rsL@2iAy1!BHsPi z!l2}aWftE$mcDob7sWarqb+kZ$VPB$h9&&|W{bCjuHk!E!-v3VAy?S=#BW9(y#2Sm zKYZWPhJH>u#ra8GC5G-9lb5IAYPlHB{J-0l zgKuZ{;4Jqw?p0L1($+s9)$M8o|*C%ZS>8?gTQ*6yQ<3UJJ-5!*l|89&n)kuM0gN`O81~t-ZS3 z7!deXS3gA!i5$B8<)kBT4j_M8NMw2B))}NVF1zGga12}>R1bVkaVEI7p{{)3}}$HVr)P3Rq*4i?qe2$wtD6tMa!9A1I46$_)f{9 z&+;tE_ktyD=Bz&{b%kE!pv}WrwyAoF&Hs+>Eb^4H?AHWzyU^ZiE$n?2cOQE;OLLfkWJE5d zY4`%t=r+jKV5x`EGr-5NSH@x2Ao_b@aTk7E#-zQ&flgjUwl|C=W4t<_%F~|RP{?|s}Uv=fy<^TWy literal 0 HcmV?d00001 diff --git a/Core Includes/SRDLL.dll b/Core Includes/SRDLL.dll new file mode 100644 index 0000000000000000000000000000000000000000..fe5ba82a6cf9ba77ec8e91274d1343cb219460bb GIT binary patch literal 67584 zcmeFaeOy%6wKsl-IRgh7n9+d21Qm5mOie6iGyz8v3=EP)%n)>N5<$}{rPHJ_c#fI| z5PHBeoJ?Y0Z`!8!#@gI#pSJg=w{0{wHH=tZ5}Wwe1S=#YrOC#jhD0xn5jnr_+GhqZ zFYUd*r_bm4=h4rZ{kHbrYp=cb+H0@nGBUA9d9(_~E}TihZ|q-MnZy!nbre7AbITnHwYnS^Yh@^}CJ7LD;ycdeZ~)1A=h# zJS3n@fjX)c-=u$esCtnBCiKsw1XMf?PCxl4{^cR(qUx>HUqlpdDyGJW;6W5e_jcz{CH**(l98Zv-gOo*m)$-=pa_o z8XXdxDh9z+MG?VO4yis9dy$vA}SS9}Ws(PU0VRoa`rq-H@`WlDHEMM(x1uW%r z9%YM=+Hi#GXtO!^PD^!>HpSPE~UfY>oU$e?0w5(qxHm^_7 zWwCipioU|tS<`=idqIjW1Xt)2g`NhpM+^08vO_A8ym33GMA5!Zgf#WKHbzUYM>}n)VDF(BMFA!vkJKufhkm++Gh)x#>;WGQdOKqsWkkz9i)m_icuJ~ zH_u34s|~9Ctqp@q(98)g%tAGF-BQ?`d= ziVChiNRo~HVl+w`)6RJvU{f?PfqtE>8!GMx15v@?%BRpJ+F#1sjM0-`)%d z`?slrV8DXB**#q=Pj`U;uCd3@c)jrVM=&&Q;7Ysx_r)wNjZ2JowQ<4QM zxB)D1`ay^F%zB5ll6U3)!yZJW_^)=JU|)$9TyqUa6u1)(AlesgH0lVww(&@3D_b=Y zjb=ce0AK=t>Xo4A_&EBOSS@v~Xjxn)_=O@*2}h&T4#(>)x6nm{YcbYJ52e}d^e6VXw$Xx4z7@Nywu0>;TXC_(b2~E_@K!p9n$PNNEQhhdy=;x_RTI5D;{*A0R?H&bMbUn?`%M40J?yNEpk|! zPSnQtSgMf4$cPdkp2h`J3QFi%O7)-wNM+Rhoz~vj8!8ZN>+QxgXhiWaZvhJEEpXU_ zsg7PtJ@Va)ZcXJ)AOVuv)5S%|=`IKn5i&!3tHvSH925#E5 z9VA(XB1t?;Og zgwZU~QPOZ&!0bX~@C*0)Z|3Nsb#`hlVlzOL40a#TrPiT>PqgmnQKB7TjtL)%6-q1d z-+nNjIOd)ILcSBkF_C!NcMfZZIaNLdKFfgr@KfO@(=XScUjTr-SW&r)^qZz(PCOCB z6DJdIH?a+IWb+loJ2-`iM{!`H-dTK-0O86GK_Uym8i%xSESP#L)CjMCs-Z%p$0{@_ zYYKyfW1vM%4{EkYYyL#HeMZfBSJoWW-+XPP&H17{6YW3hwVvdsfMf|e4^udLWOC=B zsl-y~B&*-~>HYTO3!MJcZy|TGSQRJ6UB=E=tAE2}(=ZS3OvVHgPWOSnAjoL%fQX)Pox!0d&aMAo2QU(`MF`v#w zCFA@z-N+dp`XBM%ME*OB{6Cw>e+|(ZHBaOGo9Z|tI(m|y!5HeD@u|EF^3eLr*%}ZX zG@pSySmqRgi9BMn)d8=$d5yz_U|jPmM_fx0yaHm(EywHMxg8!+I|hb(>qdwA&g`D# zeW=NNA~X- zmrAI=T~OkjI`gA^wt;@u;74Okf3-FK9tDJ@;7=S>(r)cHq_{T?+ZumN1?#r`yHXM1 z!VF+*YC@E4{}a+^CoW0n zJOEs40AyAzm>L7Hj04ODKn4J+_90Pw%gFyOCnEAIbJ%?V)ouZXO&ehk(jF4fh$c6@ z8!F13t@pPX7Bo`$K$djBsU(m_rkK4y!4E3|HW;E!t+iG*6$Qoeq!Ia{^s&#y0BYXi zrW^p=-*!}=pN_$=&rjvQcK&PSzY_ly`LDo#M~@L?g#TW^uPd31aZ23zwt>5#2x>Z( zuqEo|Q32Kvd(#;u!Pz?S1JqikUJ|R7;A5jr`nIoX#a7r$TI>)nYDjE6A>X^KWK=0` z@mz*~`LdGB%B?M)G5D`rRx+l{Y4Par+n1H-N|Ndx6?1Aws}F~7w>_Vy+n&Eu4;R8W z2H#kCIeeGlyBxk5zESu_!wZbs!nPJWN=aQdRk7!-(A}ds<)hVuu(aIY1zR6Ra^k{J z_`?G?+#=ZbW}-(R&r$+e4&T=~ zNFIFs3n{JuzDM9|EQ!`=P=%|E-QmICE1~)mdW=lhcuyEd1hY?$8Tab1P zy$81wU!>Bu_1Kb1TU~3VZH+}ZK?xrntF)bb`KJO_f6A&{9k!^N+DhB`mve81C2VI> zrR{YnO;~D)ZI!k~`eTlRe+3An4-8FK?UZ^r6&?wn7)W)nKVpPJ*l_R|2IpT!&E1u@ z!y!|yjs;E4oZOo+x_3TDIJ5$}4{hs#+;}yo&!MKnGl!63sqa0=pOR;MO~3ts<+AJ}ra%it3=_wh9JzA_CB)RK$P006H5aCw_wpwgO9kIz>gg&wc|Jy?AwRX?4o zuPTEmqdfg{4GgATfx&!A{#!VtUV#G#k6}?a84Jw~8z{~0H6E7uc|q`@OGpN!pnP@) zJwstO8!6!d_Vgm)l$H)LvbPU>&eq<9sUn-Eifz{uWNiXlgH8&+#_DgRa7`xDZ{VJ* z{Q_Gw-zYvww=6-Pfqft-`zF%ET~6KAp)AhHrTDrAJ(=8`+#yg?v9RA=CkQ#UcI7d) z3Bc^b4E#I+Ou~M$QTy005K%?bg5Shepue;spU*X7YrF;R^y*8i&=30311O70fb{9d zAo#B?^Rjm-0Wjt=+f)n0tQ^yAD*eX2Q^7c^pvn+PjIuO?@!RcUYbQ z;Z3j@?xDoJYY^(N6yX+Bg-BMGCt7M1FxQTBeC>T00ImBFSO5x z@tU>(kyWYaI6cilERstA&~pH@i(sm#Y&|U#X&yZ-15Qj14BEX>$zp{iT2mz3p?D7) zyBQ-nvN>$U{D)u{lA2n5$_G60Z6x~C$POj0uuv-=(gH7n5wygX_?E=xl){#j=J=LS zOG;s5mvX)$yLc3$#~o2OPKcg~D!&gSGR@YKrVKT9$!Xg6cu~_@rY(C}PRMJKP{x0? zNO?%RC7e`$akFf#zvzyoyssTAs?W}nKhmBsFeq(FUpC`@#Z=TXCGU=A$~;VRr{d!n zoIZz2d(z+P8$Pn)YZi=&a;$2jqOPQbCQe;R)fKxuBj}EJ*i5t+(i7q*09G0e6p7)f z=u;2-IVHHQkhB2_k~d0HlAk24Nh1CfJ%;Iu%JynQP$*Nq?Ax~pLY~KK9`UktC!ftK z45l>%?`GoCnBX;{em^-1Q$eY>Ojj~68))6k3j?xq*!8BekUe}W$f6@0NO59B2bdI?q4=C704a zW{3DhGlHw*a?0(pxjo*kt+Wy*J)8={)}A8DE(|%lT<5VYTNt8ZgR4y?9`p=P1o?TAxx?I9!oH8v!Bws{Y!1&3 z&mdlKpDOj}O1jp8(QIcY`R-ymm~}&i^AGp4|Ab*~5_hH>>>cING|r>x<5RsO%3VDj z?m^PloH`^dgowb-!hoAon_6oQ)TU~R)ina9`)COVm>0Jl)7+_QYZCUTbKG{Y+l!QYZn#yem9&I_`vQ8D_EJ+1>M#J8&U@K;#`UtT zX*ViwI%8{UCOPBA;#F6~q}H%mZ5^Wlk{Yat^OTmc4Bn7bu+EJ7S|*?pOk0?1wc>u# zdXdnLT6sE^2rMT`)9w)qN6uV(M*VYN!`p%|v=hDAcD?gN zQb?HtU?gh^4R7nZO(;Z^C9rldoD7G923Q5wUg&V+z={pnrwVn&TA4U+ZA443y;M9p&wZic9jcN20VAza zZOy_aIW+s6ZE@x{(hwgS6`SKV_XXR}J4Nhi7wW~Sl`3Q?`UaKM{(=W;NIzu zRmZo-FDwjCq23>Vx<}ip??#gmPMfeR5%H0HbG6PP6yN!K&4&*6(}E~g4+vCP=P0n39Pp_ zRE&!lL!zf@-P%@By9mL)n$^K*+@vcvvF}4bVSoj)oUI=E$F9dp`xA1#ePA!To~EvC zf2gmu3v#+ku_{-A<6Mv}t>$)f2RflW&m2g^!+dhH{%=dx z>oLntNY)leqL^fz2^|}hfMmTdDp_NqA!(9Sg|sDksug#eU!5dT%^e=*L17buGz|ij z1SyG7?KQR$vn~?Hh3G@DDvkG8*2g9Vh{H0>y=BIva4b40JczzCP(QC+%U;8TY@nXa zzOcYRy<^~eB-D!Su2;6bsku)T1>Aik^p8=m1(#>37fIH2h2s`>2HnRX;!{h?*!TI& zZpi;x;dPWP$K7XpI;2KMYi@G6Q)?G2dqtkolCZL|Rk_%_VT{iZ$NVN_*IuOwqR}{h z63&RF@X4bc>6H2%Y(rw3XT0TGVeg5yoaA?8v%Eo#xaIrQNTq_=Clho-w&-+{$;p;l z-lj$#kY}lp6|w<>swP4G22kNFp7+Xx?O>nq)t{2^RlX%1o2E$a8yN}XXw~=e2_S=O zTV+l?xSxzI`Ymil3W(hy`U3H)zMz`n$P(1CDnT&gP#5%Y=P(vnh8jR>2iKq2_aWfH zTT#_a9Zc`FIz&oaUmG~-y?!1qa+BI}kqxWL)U&-!QzHpFYCW_P67eX-g7QM3C} zvwO7JeYx2^*6h}EEDvIlD5vO4duVZc2D{t7u;sw1DgpeOdhlPtQ35YrLpL6>f|M26piBx-t0+ z10&$y(`?|kJa>#NBGuZDl!j0`)@tfStL+;<1cdGgK9&PpT@=Tk!b5EeKLZbMYatdU|ntRWTPB>7w}!i7Y}4@_vS=@Pu`|hexTK`idx#Ej!=6!u@yDFmRF~xQX~ij8_kp3En5jEUN^q{D z($%S~Wv4NNlg3qd6Ko`P*N`b=9^gwkh(C$lZ)m&WYFG>2gO<(93U4Bi9!nNljulbw zdWVDvl<80MOX1sD0Sd*KBv_0}9}UZbuce@bXL$(`pD#RjxGhupYp**}`tbtnY&owp zgNSp}Pr&r@T$PFP)hbJttwpjKZ9O1@d)p37+C=K+0S0^fJ#{O0C?f6FHy#pR8zA(?;d3&xN9bY zhv;-sOR9vp)yfE$UXT?HgBh0C`7&CYl$HgX7}nDseVeGKWkbNcMEOXQB_4OSHaA+x zkdo)>sJ_tBbPk~HO%##Y*eWjy{^)%~*q-mSJ#Th(ZlAs|l;;V4Cz;aynfJ2U7|lR2 zzr~!7DWw}?YnwILG>R;!&4Zc=5Ic1+on2Z^b6zRp5sPW2Y&^LPnMzsDGAgPd3V>lU z0Z>I}j5yGK4&)%JJ?^GzhC?PfrG8cXOnb}Y7AiJ8bvP6!r%_ZUMWLYP$K#1yVX3{5 zdjx9gp|IDWVn-95r27|O?CiRM`?c>@5@v#&Dd_OUzLJdj@KW~4BOO? zW^6~bDX8Ok{n<=t;pTQhSmAoD`Y_Fow6^lTN0TFLZM(_V_Pq?qzNfG+rbYH}bMVS7 z@=SH-gMxguw!I35H_4yLrrN>rP?i22z-|6ywksE5GQt5Qp!BJ97%_^R;AKlNpZWF>P+(=1#-Wi7pvwUoHHR@UhY)^3Q~FWC-RKk8%8V(-UW)D^ zQ}VR~u-nbtf{8>O8&hU=SjY=fz@Aiug0jm;Wp~tS9A2)DT~?+|1}OkY_>4L>N;c#n zn5-uf!$&A@%YkIIBU_y_MZZLBn8z zI8cwq+8Vz}$YD|0nw2{QZ}oc(I=f7B+7>`I=mXrp34YuD4$QKvIOS}O_aY|fW}Y%* zT+onkB8m^vV199W4|9EyJpzM%4cOG;yxt?@7d zw&x2mSh@yiqMcMs1X>-fHjh}p(v=lZ`hvgQO`W9lhd#KV0->HoEHv*WPL65 zHAs{STr*LcX{9T&?JQ>e!ovF71m!sTO?UUH?UGvCC!&Dr0j&e5b>!1|bb);d204Fx zAm19yw+91_DCfRPZSjiAK-P-9yt|b1+IjW{KnC_>Sk|vH&lK}qp>4w`yG|EuO-n%V zVE(KZ#!ytfB<0s_?#?rNkq)rgbP6){Ais zv8105g4C+#Xb^mJ28MWXpU$4ds!WRnYI_*jF0~C+urD$Nqc`A|T=}A{k+ue^GBN7e zIc(hcv~Db*8?jarUT6kx7!KN{^UtdDU^Pa@1IXy}K|v-ZW0caB9(`NY_z0P*6;|aM zV+4ossk}f%RjHOsqe6dUxNu9Ht?4YX4O?hrnruzI2w-$1K-d_=FJIhSkM?Q#(%wey zTK6`?#W@HtUBpsruhdrM+baWBw~Xk#Fykq?B(rOiTUMoKG&gUFql5t?fdp_ZBvv{} znC9jkW=eZk=OcC;?W_1m9!Ic#*#jEXF7z8ntPNs`;=+^%gl?u^L1D#0$5>UFa~F-7oDT+ zdXb{el)<+2aPGz=$eSu{*K>$NL`6=za-X*AfDyVHp{qP>Um}L&^OTDnB|7@FUBA8p z;2RSFl^j5Sp2}knPsDG6mol~*84FNyp0?`BsJ`e z>;PBDQ?&#%H3=vrc-Sihl(S(Jn|mu^QHVwVnxfSXyIw3Q9bWb<1))eqEodO*QervM z-^=vZwQo>!q5PXY6d>x22MDL}KafexY3q#L_6gc?mJ|JTsM)q{==TQCLro4LU6HIwN8v9xY9Y3SF_85to&!wTeZ-jQH4H+?;IA8kh~}0ap~?2`iS5c<&|dp=E-eRz;}tU0*H2 zzKIc_ALA5W9or+G2`!HHi0OPV=sanEn9+dXj0VG_ml<0`S8Na`dRY=yBtGXbYTAUF zHc;oFVzv_%@p>dbOhKpuW22(YFIA<#3(B9IiaHgEPBKN%4y_QIx-x{}Aq**>R(PWk zdd>(fF+x8!Ld%WNcZ^V;5!z*h3XISWBUEIB{6=VfE_EeU;-d(VYb#NStHgCxkQUdV z3FCUOZcKV*eC&_Yyv*pOWt0*9fX)@Px(AVWUKu+NJ>Tcz16@vS(78~tsyNz(J#!s) zrSU>$A(xk(!ffkfcF=)F0Pns;*oQC>;kUBOS=`UH>0I6=^4(;4Rj&W!7`-aiX`I6$ z88EsluzZ@_l{1NT^kbyr>;Mmp5069~h11h$R2denPY#EtIQb$Z-Yd{xZ7K17l@+vv zgs&3F-TNE{AOaUK5X$z_xJ6))2k4xE{<@k=5Xegv?WN%=PgipZP>_?=TmlkgOg4&R z4@m%C#2y;89Tv(MbPL!mCn%oR5FC4>Biz@&M zIHv5oJj~1ELZ*p_39Y>p$rOY!z4OZ0acr%Dkv3N~tfYa&3w#X#pyu9~ST2f$?zEPdq{+ua|*kT=EI z)m$EFcV84%pd^@Wx1?f|G3Xxkl+cDW%JG{#>|1=REfYOs&vsv+<<=1GwmDnFxO3vh zRu4??7x=-SA=>`JA`G%Mk4E?hFcE-Py8z6_JytmOMerh}S%%z4>22sy}EpqGf{ z(LRoAOu9j{#!f@Opxg?U4NpPNFi`Qed5Nz@?6K-;4}w2{*mQO#orrEoIuFwj3dH*u zUCD}0sAbM!V*DHK09?d}9gpjCEUoD1ZL=|DZb31@U9?%_G9t~i=olj1_hl#&m?QbR z(u+b+cXZ30mxLwQf4{7@kChcIsWzYEL`dD3gT1T&CT5{YrIo!z$U}HhOVCb33ux$| z*am$gRwLUnwB$FT6Y-X?*9tK*K#vSJjgT#vU)UI|@%(ZpCeS0+C}7nB4DOgt0lRWK zf)Exo{!yNVsyY@0rQ$j<$b7th84ySP5}U@m44%)!v=dV?w4rd47LNkrP*=O?Ql#pk zaUz3bz*{!rH!TH+$>a3n9L8Eb7=wW4_EODsasC~XR_nWB8`0fyErhqr10 zf$Sl~0HfSdl~#uE=U3t!ZzfVYM2CX_z6by{_ZY2SeDbwb0yBr;Z*kjyJP4Pzx@=89;)1G^iVtF& z+egdRZpZ%bePN?4G&%uw&!OGa?PMrJ+bLO=kdRLaZR{2-77cy_0kJ70 zu{M;*nTt$#&^v!+gaPDb3N9@{%VTffNps_a#;=w9CEUN9|2ohoUN#+ywwEQqU$x~P zVA_F$2kH^WUSecu7;CEPse2wt#2QnFDiw4;4W?}bOGaDc&+}(ic-eI{Bl=t&wnjQD zx3?7{DzNnD_zgDGG14$LGDSg^^!7ZS6jatyMgX_eg=z^>}!~w@@;rHyyLpU^{N!a$2z3Rm=xunIs&m`ZyPg0Uf^t5_ocrVwKKCL|zv8eCP z4!s+1h7yLNC?lk6i@CW_ta`=V)303E-?tYwf?yLE>^Ne<$ zN?6JZh$p2yNsWxj@%5|4`fzo7q1b?f))xQpI-E>xE28TcYU_WY&uV~)7EyIw&c`6R z9TF~z+mgU-e1fC%j#NrsIFT&+BD~TBR!gH;$+rTd@DzgUhzHN<`RXOJ?eQF@L%Y~8)`}5ca|kng%uZrqFJsRWt7SSdimgPfdeTwlz%!uX@?6=p z(#ww8LD--iZ)%B$N&Ku|Tv^7xip@*RV!lA`DF_ze^NLYIY4{E=`yn!D-TC#m<@)5s zep4yS12kZ9;X_{SE%h)96i%AAT4h^oum38H6zoD`^U{2t?1C@o93yr!VLzXc6V&U4 z4huDaI2Jd%aITxJQ3A7dz27hcX&ot|v5|kfoOR=D0foYppG_Y|poO3Rx+pERx1o z=?NrCVVfwnw#4ghYqO~k6`;DtGxE)Jh(!5m{iRGC3AvQ0{0mAF+waf?63=Lvu`SsW zzdTbGmnSOmh2it7!++)p$ABNH*Fey1AZXW3kZMlsiWjb^ziqvIk+8iETLj8%sz%0E zim5((t|DSSOLn$8&!8D-1ln+XfNnwE$t#are+L@WrF=kbK_AL%IgS!gxO;h`yb@0= z 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 K8u(vb1OE^B0tgBK literal 0 HcmV?d00001 diff --git a/Core Includes/airspy.dll b/Core Includes/airspy.dll new file mode 100644 index 0000000000000000000000000000000000000000..52b38067ae8667812ebb6e3d7161d5977c24f5f9 GIT binary patch literal 91136 zcmeFa4|r6?xj%k3yPGVq;VhCskRU;VQiB#JNwH2eSR`0#E3gRC$A(#X~4S#B}&>EHM#HAVwO#;N6@8_Mf83`3H3!=-<@;`?8GERr;S z`itYG=f=D-W4C4T8#9&$zP&D^ruOb{)!y-)jBnm?*Ijoj8UL~-qgK5u2Rn2DZ^0<_t&|viSVy;KX+V)@FiQ$33vLRb_w^_xrT6W|MoWnRL0-e$mf-$#TL7y zpLx417S}5!%ot~JO49p)JZwUXQ{cMDk4lq|{0Wj|H^ZZ@)P{IsCjMEaTm+C%2kXyJy&Fre3bZ6iM|F+T4WIazAxW#Qsa<`CatG4gP9Pv$3g<)eU-*}c?sAQpOlp`5_$s6$etrF7 z0+6oln%Z@>-$azCE9xvIBCzBO>2j~BU9ojssaC$L+-Y! zD>xRhi+-$PUa+f$Jw-Z@c{^fdmea9G#M<&hLWf0z>RrvdAdAnqh^ zMNnk6u~X|EHfo0Xdn1NXA>d$)Swj+3sGpg**cr|90-UH(W^4D3U~$X=iO4tU+5vX&D;{R~UouY9Cp{x7n-*tlggW^~rqPD1DLS z5`F;Gu%3$0Vb$hti%bd^+N>ReN346ToijVKI$3wtTYAax%H^m?&=IJ~wYd2HYr%4_ zQya3V-{Y468CZgj-d6x=!i`Kb%*P`l(#K1Y*hpOqhPKviMdqvKNK$JiT7?H@QObLg z_)YLc-r`lWDZDX*H(ez>lYGuP=W;+2xZJX{bY9$}_ z8!cxQe3EMCJJA^Yeo!IUrONzi zYb5Q6)M!HqYLzjcpgbGY6FtiVFJt%wE&OL+1)zfUhX&-Pv%u$%Cj2TTL`o$sDEayI zGbv=G)_@IqqPE0lM5g%pJHzM)eI3Z94OwZF@Y^p(I(J(xe;QJMuTv6($Z0`kO289C zbw#^N63C_Qf+Rs_U@JAsJmf%5rqUpBX3r;n$W13HA#r8IqS&>O1a&@3ZnJ=A`xT5V zmmj0cIHY?|V)Qrt25F-(J^@5U!9OL|RJuwjEw2U{Y)G#^354ow43NxH3{nSQ0(fZ| z`F{VoVQd#gv?)mfWb~l3qHwEvm5JmzBpEz5wQVLLQc`27og&ug5%{C6!@43@u;Nq9 zQew=#P<jz_4T_rorXlg(%EW(+o9*Z=X)BAjVkZso7}1 z?LBBy_iMU$7^2E3Q^rt+cfrUC?FkH3LkfpZ!U-;hP~g_d62b%q=k?Grc*3E%z^;c* zz^{jT$sayJ-)+a}`^ZuH?(CuOo`d*SZ`n2^obV~(Jkl+k&_3Zj(I%XKe;Llh4}|*R zFt1Gyad^VyIRj6ZDAIz31Ir!OLnlQdkVAAauL}_2LF!ZR7^w<+92*J?a((>w(e67D zEhkf*%_^UwP7ERHeq$x)@JHn+L`~})bR)qrV?KF})H)zUx3*Rqy(U{PG|L1u%RzUW zkN)xfD4p6UIGNw^42@^S9<*1y@fCm2^2%hJ)aDN+@O3m`_|+f^^IBC@bUVxZoKqXH zB~CUp(0;EvnO9)J)+LRhW?$mWz_i&n6|!caJy%KQIU)`NM~b{(>OMZuZc!%cRkne4 zmr~CP9NK#$dZG?g1rWcVB0}p<&cIaesx?K*NFrY zY<|AY1Mgsg(}66?_n6-Dx#adT{!3&-|6s==h1&iM zlp6_Xm~f|R#)vYBb+NbFhwR#W)7#%mv^qmiVqS^ZUuZ@z9LTd}C@H~&($X@%D_fFg z?gdMH~bs3+1nHavC9IR}uK8f8H(3jXesi%UN-X?5+@=mmDVU3!^@5#a3hML({ zdhAUBM5clWGd`~dL*#fa;tOm5vb>rn6Vyq>)4Up#V~LDq#FRW6#dlU!?zNE+YdqDE z5I@{NWjMSQeYe!FhiH6YI)U_XvHBEUbbNOkJErfU-mQn8q4<9N5gG@2hz1EppZL<4 z(nF7nF9{VrL<5RjNvvPt1dX955oV$Ul5l&*qSNF$bJcJ9c<37HV%^$VLz$wT9Z^!) zA!?fUr?PLE^#|G;*kAI+A*_14lPAuwv9$`=&;;WfKbaN zSP6zmIIwO#EJQ_!2D%>Ffp7D+PsMjPzD>yS3A#EHjL0?l5!x>|zXM?Srrw3+8)W&F zz49v!BxSW;Ig$Ww?IC3HD=&BT0?4{_5oUse?L&|T6s-*<$@gyn79%rMn<=^6ZCaQZ zX@J)kanadXbe1;7B!?FU?ap9nXj?+jcs ze~Yy6Yic^%Lw%%Svt=IoewWskfPCOg-z!MB&>a_lT`c|sV>9aZbBbRrH~kt5fra0e zn;s+gZn^2FjvRf%*q=~a4Xu_Rcmq;Y zZYqI1(1uFo2mXSNpwwwRPjR6q`SEiU70Dsm&Nl4L=o0-BIV5w4Fwuqk52V26vaHI>>huMMb)Y`$%k#nmN*50T0`vAmMqhZj|6yObofDunOptjDA(DPnbYx;n;c#mE=0h9d^7GXQ`TC^a3wXE`{J`k74|{{f&n zq2b)ORKMAA5SAjhc-k>hLbi|)$Y}*=)Aixqm53|jr)EN=3!!Zaa2h#dF-h&AP8b<$ zVxcUi2qv~W^iVS*&2m{G7H?Y+jE+HLC(U9QBF0WC4Wo|`g+&f*gXizV+-$DBus%Mo z?MrX`2-T958QLC7FR5u!MA(1y#HFpMXxKwj%eT~YEcxOR9lSWv4Oh#d*=Q=X1nO51 z9UYSZF{?r?6-8cE10A_aqWo&%aAZ97{fL7AW5KYWux@rP zVrRDvvk`)&dqy^=)!966uDfLLorxoZ@0!G$w4=SZqEQprh&hx)hwrhw58o6?(LNa5 zeWAB`dNw7n9@ajtOHI^w5?x{SG~0WNxq=V1ZBC>(C5MUr`jgvzWhMNU8_?6*=jx9% zA-OIV@9dm*HhWW|HT(=fW`WJ)moOocB0HFvM8jUlfC6(30P0YGV2bk)TX4;~-I~mPn1RNpon{9ugBwK(mGhI-Kfd7fJH6U_U+n%kmqu1xUF*N=|$^$Y<;{GbkvIi6#PB zOdvz%A4O(s`!RhHZIPK@Rv|wpRjbHDi9-7~&P08bFS6z%FcS4)0v8jDIW%gjj}MpKV-|0 zm0_Vy>-8nHVSX6X7bbb_Mnl1DviYOYy@#5HbS{>td(#FAQMyap?2y#4tT+YBeTyZs zM7u&NWtGm*@lCnRo8kivx0cDfu-9G$lz;%M;dN*WuzA;RxJsSqD+}JpuO5vH9p8LF zy8)^m=1tQR#h!;(VH1iLPTZ|vQ`MohImND$lO`2Ap%UG}GtgpC*l(eL;X=^8EUnVmAIF{j4GmW2z05Rt0Bb`2ta&bifa>@H` zc(peTeHulhZ|Tzr>={wy>}f=pl2pdMgwb!LZUn`x1l(R!C+eH*<6ogTpao$2;!)^C z6H0*Xv{~+#+vhG>u1*z!S5{S{giZyyBb;*2rz9(du7huZv?M;g2e-mhNB#gAS96Jz*-K^p=O>EAeWba9U0IDV+C^wRKXW5fMWYmZ2kgU@ZoPzFGm{n=D_{= zl8fg-a(3A=n<+sPC0LIHT225pL^@?^fPCD5=7A79K|lgEHbJ9Z0w4=f`zy)_-D8KJ z5)hwQzn_yh_w%m5(D$n-%g=8X-%G@|h^EYaX;pnsLWw527nFS%0`B8kom!iYbQe z9|pwiuxvgly^Oc9O|Co|I<6?j{I%c<07H7^Nxi;TuRo!EYQxuazP2pJmFy(tV}uKh z>yfZO2Gx^{w=c%3dykFcD?XN8d{VV%dwZ4t(2Gy9cTgY>h1gK!;lOj$bdOWhy@XX$ zMMdCc0_-NhuLU5c(9QtiT0K430YKTSZq`)w6@oVuhyX%$kRaC@_%K(IeG8W=;a_wj0xWe|@ zT7X3RHJ%y$Eya??GCFGb1wpnxJWzH%O; z516M076O4^B;XUw%#@YNF@fa(=7Oq)>*t$*LI8r+z*^)BJG~?>S^L#gz@ee6et!wi z6N7t^5L{h#fzxbh5)_x0rwS4!IGvW1T;8wY`zPWGxY@~U*ff0gqK2bcqurF*QT9y)lEDt-wl4b!s}79&ES_S!sQp= z`yy}O`!e1#TlmSjlFR5dn@LSYmqEwT&N^zZI{k!^xs77CvaT1Y;m}mII0&#>yP*Vq z`K!p58Qx9ta2Jw$5U?Tq(h-<>s3oyEsinZuTxe-2NC4jE!UV0;s&xtM2S>4k*Q04g zDvQ>cpmik>4Zj>swbe|cby|o*ba})!kH!MWFHq(d{F?Bq!%x9)Eq<%sA`{DM(Jp=a)+#$F_aEIXzhi#=QbMd*$htK*|_-v{{#J2$3d^cd5HvqPIb4_?x14;?M zO5a=5R;<}>!#T^xGgkHU zbC?jZA|+cD80hqWMq4mCU*_%)#Qqw4xp)H>m~5Gg89zUbg@bwU@1?24zkeO|;%*B@Q|rvcs#Lv#U<+4hNm!_tA<&J7<9n z3(h(F5WsG^lvS-rV`rm5h1LC~G5ZHF31gd9tIn>1 z)f!-Z_u_`-d?=hybOH*$^3KmU{_sQ)Bi6F#w^A zT-%uaZ!tg%0Wuo1cP2!$khqD+joHr;APL2SEXi2E8e7=I75b*tkuk=1ZB$_=i`88LCT+2WmYYU^THBNf?U%7W zlZTEYv9@WB2+rZ_&EPx{oX5Xq1{aFpLSAkLb44(hFEWGqBACy=ZU&1)u!v_-uyNCh z9<0WwtQC9;L4wKrFIUlO6;>8(NdP@O4b{OW(4xwXXKDMVB$e<_{(z*h1$r4M4m$ZR z$_5zPUt*iqh74t98LuK61y7DRl1*te`srvEsufAa-jq)>Gk_lkzYMwj{6~bB*W(Br z2d!WTsM()|R2}4Z@;$lToj`#8Jj6u2mBBp{29O@9RsPOZLfFIi_ zKfiP#H%l*`n9Y9koJpBEBG>`*+Ld3s` z4DPm$K-GNg!*^pH*h-B-DmLW4lb&O*Xq!k>SN;X8N#V{~!h)j+_SX6az ztX6@(s$;Z?(X{K3Q%e?hOcj0i&PEki2Qu=&#qnsE;5hC9r~(R=%Hd#cFk@vIKRT9* z!qIf`38~akWXeEO!7Lg`_EUC^;6rOYs6zFPCb~4dWpApP0@Ll zb>V=Y4Qd}wZ~rjSI!~Ac=;{fU0Q&~-u@Ht$oeOYfr)15o1{uaSKW)p!J6NyIv-zL%9TMvhngO1vX~`i0#{gM4bh;Mw|rMg9GJ}vEf2tho!as4Xr_2 zN|=06w_J?s7Xd`ffHwz4>f>h_$WFF!4uLT@GLEd)#)yF9?|4xP<*Lbx$fag#B+xJ0 z-u8e%n8<9q^>SBXUk>VlPAF{fV8XQ%BBBG`Gx16qPyVu3s4naVNXF~K_lqttwC-|D zciQG*3CcPn^*L&-@mg1IV>?BM3(t7kYu|$=antWGd0&As-)UVj>3^pjeM$NENpe0We+7fN11eJOho%YbO0FC3&7l?u4 z#3^mDqv3|j)d}u4EHNHzD`4F_E(a_!->`y(c3Lrbd#A!g$j3Kb2QCAHGcLNI z#XGgBO_>7iH{`%?7G@~6g=5sGkUgoh(2ydQCEA)aso@3;+1EirOJX#IwIFg@K%XPR zmN~J$bLd|e{oV;hz9Hf4&AmU8P>|Pf!wTgrk?Dq|7F0|1X_Dd$7g!n=T&~(!e z1*eo7{Coy7HQbO>5iYkVmj^ASdNkZi3`b&NMuXDvP!YopRQ&KB&SnW1(`1#Kc zql?cXk|ga)%m7{Xjp(e@F)DBr(qRatIaft0qCi-ipNyI3tvLp@4y}7nrD$u;z(#b) zRLuFyUS0BG?n|#=xn_8}l;lvSGG?%+^(bb7NHq@DAQif4WO#?%IGyuC`%gBl*OF(S z=?QyJAyFG8D(=TPaTlL*!?dv5^OlVGP-EGUORz}C- z_FhOZx1GpUl1TgBQ`u2z%sPb}*n7}I>*QzxL@PE*V5BZZyikE|=U*1xKN@{1E}Bf= zV+hWSrsy9{ffJCJL9i%ASdts5Cy*4(Gf!^NX}dvdXyBe%+n1tyxCcz)b#)j9?cw6# z5~$gSzNcCWbdeA&9;lLk(MHvUWUNUhQRo9kHh(L9hXPvwDl^_T(F7i%P%ANI6!fS7 z5gSH9&j=7zeH64?fT+5oprZmr^&1796reNlpdkSoiU+yI6A{DlpxFW>p~j=Q77CCp z9<)M$9PuDUfSmE5Edu0<2R$l4DRH3IGz0?A5qz}79+4_NE>)mkfHLAiPMN6Bj0epT zpxN=DTmhOB4_YBWbK^lZ0<<6=)F43f;z3&lXkk3)Q31-02kj7`{CLno0V;|I^$O79 zcu>Cp`Qkw~7uAtEV2nAf?_U4@W1Eu+Df+8Y}NB6JcV40Ij? z(izJ!1VrS~7}Q_p9zcwF&!X{tI%~kv1Z$vK+4dcn>eo-hy$wtVjh!63g$mDn0kqM#ky;%HT_#q}zEBIDvt%shj&pF#X1K0xvG`Lg&? zm43kGg@VzTk9k9aX33?m&2)wF%j!ji#aRu6yZbetzJ?p>5SA;^eUR=Q!X9CDE9L8e zq+hLLO9cL{G#4%NQX|zZ z#aQGHu@3G0h#aay%Qo#-3L`U6d(a?7(zNe8N0hHcF&ubNZ0~Cb&EN5*7^zuVj4#)5 zoQZ*iGtrgeDEqD;a2)$cn}r5qZ?i=X{vnpu2enzLumRq_4^V$F zr3w>bk}#5rBzijQlUQdf#n6)G8Jr!q(kh-7De7fGn_r(#ar}oDMc9LvmREJS55I5> zt*ko}wDyef?Y73V<*Tt{OA_0F2&YXe{{hB8Lk^v~!pezfW6x~NC;a^7{j|IxFSY`^ z36HSkz=m5O^?X))dE>|e;M;I1>&$8=+wC@7B)bDEwZm(i&Gejm)z@6e{auJ?tkZcFYDk@DcR#q#&(A?m zC+TBe{COh(&t!<^r9th7A!29&!dT?%;koeWJ9F{PR$bzPTe1Ue*so6K+m0K?jJbR- zoT#?gZkE;eG41wxaDaI(dd)-MHX9g9S;{uCF%M@V)UskiX2S8F^9|<{VE=dC0vmO& zYp~}@i<&O9jzCSC$|&kzAB4qsGvO7q4dhS2RS}u&Ge~O}0!_jykLcz{KF1=Kv?xBz zWh_KRGf`x;OAO>&Yz=bLb%^Ct$wF;E%Uzq@{3KW!4y7Tr&&(u0*sg~c{(Wv^p2bMb zMHi zAqu(=>)VLSU7-|wsdZ=UA+$gmBFo$sEN9J1G@Kht+d@HTv~p%o*F%&cyUwyeNpH!w z%xm_ZVFJ{=>~Fz@8GzH)CGrgz*!uWZ=rw8Io6kZ-ClfSf?X|+%4HgIY9Y>MDgxkX* zBG|`k&~ec-p%#IvUNDtt&NV_ra^wok4Lb=COP&{({B3X~TE+d*3?(H&yDn-?1O+Y8 zY_OvwCPg*j+KkslKuJ(kfRn6v?AKVLTczv7bSfb6fy$L2e%q}pR`PLFHV@9el5m$TKRTcZZ zY|$^US57YX>7spjALhxpRJRqF6fuF_WWHyaOTPCh42(W6apw^l6a_5_Y#R+l<`hD! zIe+ZDsQl{6PgsC-Qr~2%pHOwPp}w({)f`Xey)71^>;sUn7*8s7471n6z?(V_b>8um zr_!ZwBZh@AM8Zhs-XGp`CW30H{~{mrz35{*|BCOCdMFczX~>Y zCM6f`{8w+sCJ!EfS5NEf z1em>!o*{=m274h><@@RYyD;pvC#Yje;YS32+Jnhid)YPuRe8Lwb?8so=shqEuJ-Jq zKBc-e!Ip$--K}*bpet4D9(>_%JU2q@=r*ezFUhiwVL%DC_+S_FPnZ%NMWVVi7XOM4 zWHKl^CppYD>uQQps@3bG;AmuFWBvAmml~k3TJ|A zxWZ_%^{*!5J*VY+_kpc_8;}HzX;MWCiJc_Qjd|E7#>8RHFtCVT?Kb-8CU6=5%Mr|w zk%cDCe=tMlDq|YHeyO+*pU(e?3|$g-0}}r^yjq4(q}j4QW1XWWQ_r43IZ&Ad(*mn# zP4z1BXnHfEhpN2&h-E}tCRb~8Jz(wZi{p=5sRDQ{5 z!Tbp61v9XKBN{7D#MV~mDiS*q$pX!+@&r?lmGPyQqnr-@n3;jU3D;Z|@(KG;>$h1a z{~Tw7w7@DUiJJ7i0NSuD9Pa(4{=72Qj>EwOR=W}Eeq8-P zAd&sH0U6@LwRLfU-!@+qiAxK$>B}284K;n64sONSg^4Fg+jIt2&TP{#)CDn6r|VYr zFuV6*;IQw&hfXH*u%8oKh^U2Z8M}|p=uw~Q9LINn6$k$t5h~A4QyxhmtFuC!HX>Si8^6{1f03-J~}qKdITRI zzY+=9eRRAgEIP8fd^|;f9s-C$i2@nr=jUHS4@1|xk7}3GO#GOd{SeiX2(_YoV;4p7 z!$??B5lk!(|NK#eb=(c!l-{`6WZ^VMiu)98fuzc?TSQXB%^wvxXfwANJe`EQK}h4I zG)X?LQ6$B6*t9NJ5zwi>_4Dr#G{#wM;mPuXj1o%y7^kp_5zT(fMraBWMZm&Z8W0^9 zzNIcM&>~ngni$P~3!43&ShHt~HYTJ=+C8G#?=hR*1htE1Z=u>Zwny9j+9kA)-wPSy z3^b4o`Q|6!-gZ+)Ck|5NWu~4)mIuZmn#M8ASfC(NJm4Z2JI~MN zdIpu*W%>f%GmKKu{ipi*bCAI>+^>L{!-z0bz)krAh}a6&RV9o$E*zj-68xMOW9?JX zWmm9w#1u#e;wT6OT>UsAlq)oDQ!dqbvNFC%!8;_C9ou)iXe+(_In&u;I?o6PIki)+ za51c^`6S#j&}Q{O2+$@DN+9);E;|LO6eD#mgiBvE2V?!Q@l*!d;lid=jQntjpTmUZ zGuGRT)H$Hnef(9*O;d9}>c%>no9y(2Nv@}>_DoCY6QmA@>Dw71a7JXhysN~5qrOP8 zr)ynur!@wPJJ(-}S5+s8l zz}DO}o>&!0YJOOF@;qmMvYQ>PFO#cL7i&F8 z-Z#k(TuB3#5Yo~7|tpWKo^C9S!Ul#7S~?;1yFpwy#_T}C~o z`Myt&#b19c8Gk+E;OH*e9`Dd^${%2hIAu)#s!QuxuSc`jf{A=f_!RQ2Gyr2IV0lfUv z_Y~-b_KCfPHynyjWa{t}H&yiNxt<#D6uP-KU>sy4!d8hZ} zTzVR<;UO>si((YZx|R7Yd5~aAmb_~M$+*dl=cv)wO>DWp0m&TslcwAx@5-}yde;9L z(yk#}Qr~3WlZCjaM^-L|t#)@QD&AE5A3(~|>a>^OQpLw79(+c8H%ZqrOZIiV} z>o?qZ9mDpNWU(|VoaGH8=XFgdmCUCwF-porI1-*Vh`fQ<#;BC6_KtAg$f)o0QQvUX z$HZ{~UJcoA$xc3s_JcCc?A|Uq-=WK%=**X3v5>>?H==&V=JgZ! zeVy37O{&u8^4FioEKp9j)4{buFaZ2=4`lD4&a3`QHHqGioHrWH-(P`KEstIiUCSt(Rt z#VI9zqXsjs*caoDrQ*WXH1(%uo+oriWV^Xfp;Pmwcyc~~nwH4<_t#Ld%c)|YK^_WQ z6Nmt6-RQ22nz@q}Py15P&VC%arHpG+XM@Qw63=wH4-bCEj=|@E+s`@%R|DS7I?1&j ziWI`X0uZ`}gEWWw4jn)A@u6em_N!+GPqTicNbs!6`B;3^c%FUG=UWMYL}Z>FI4Xxh!}O~%AsFLsYs~g}AyS+#j)Tar&MqMvGrGoV!xINb-W7eMKmO`(>)Nek zIs;?LG@NF_oRCf|u|3NGbND{&zQpz{gx*DJ7#h~t)Y9E@EJ0$62W+YE9t=N@)Ue4u z$yXsYwQ330_~Ke=>{2vtg;H^3QiY4A%scEkCf|E6Ut5``0C~PFNx0;#+5JGM)q7CMtu`m=Z3)?c>@T0BelGlxy3K1YbCPcibIk zkZy*;x7u`TNi>GYK@*yW`7vWeswKU1IC!jLYTMwkB4LuBOAL7y1@JEHLRl`UCngD= z^hEG5WNuu;aW~H34hBA3jaxqECF|L^JQ(fgt#jaqz0~{#aLsGtv6#7lw9cas#kDTP z2SsNFR#DLlP_(w@D6H6eBs$9MCBxWb;yiQQW*=TJ>kKATWVI`oc^6R9#btnl*^fbk-NST`^!;)i02%gWa@o~X<$QZC^y zzZzTiabpLjvgd$Nv@_|2dd%e6X^vECEn!s~G~Ia)3W zmtODROUDMdrYrFlT5%9ZwGoFhRvQ^d4=UR5Kvdx>-FsB~)+&lnZ)An5b#G5s;cC*^ z5aeo>9Du3S~mu9Fb&;H9dYy+zcn8W6lyZa zJ=&fq6LElx=^7RpF1%%Wsk;qt1o4blVyleRkkYJ^Yf zflAYlEXjyT&MtPUS74TMgYwH@V*q+5BM##XE7Zt`<}0RxCJUc2O4FJcO{MIeGFU*J zL!Zz3ll*)lXmf|x3)*JgrhXF1$odS+)XS=MYk0YUCf=r4Z&4#C0xv`W95PlemqXt- zFyw#)4~JmI67*H;OY=s`BR>~Z@TXoDEW6LFR;X>`3>c1YN+yHx$t>ANBVnBBwo-t# z!$d(vp6H49?tcgJZoE8#{MxC^3wtMsqf$1Fx~RVlt9ZQLzWM1{ehwsk|?vObBlLlK_$)K`VB*0>d;4!gBYv>>MgdDFkj~K6$|y@TvF| ztf$a*z6#t~#vyz!4Hus%3DTaWBxvy&%Q#?(175uDI}R)QMi^Ydgk$b@su}QR0v{4g z!#h;C8lf(_yhR{%e4i%h7N z?`o@-SK)UDel=}UX$gBr`#{FFVk7&5_WtJfNRoofhnp?<<+gB{S`mz8uxeVm|-t(G?dYP$u{53EWe zG<3JB=gOCN3?A1yTv3dxU$UD+tKknj?|`6B6pko7}fxkq6|-kYj5H`Gkv8^zs;eS!Djv>7C5^1Oyg(Y zzH7}QtcB*^rL0-2i{#_5qvZ1o*W9I!>mGb3Xt{KM`AB=B!Fgfbuw}hMd$KU!oOjYyjaT0cgcLXe@{B^J{Nebm769q9&mJOj6x^ zylB2Ztez}KSx}Ul2`f&&Ht%N87wE18=R)CUHti5ULvQzDm zL^5kbQIbQsPPi`RD(y{&nS}PdW|Ai}l!@A#877$aye1f0yS6WR@4QSrc8*;Yc2sH0 zZugax1YCEG+BllRWS@@h&uV=ZaFNyHTvqNt>N)NySSrH^3aam=ne()BBZ|%Q*Y($g z=dBN~c-F%oOuDQDp6o50+Ai7A0QI32u{Q5x`X!4gLyXS zjU;+LK*FPYC>l#~cQ>zt5&kk3NHc1jMvcp;!E4?mR`IxsNP{=q^#pN+4T5knGJVDP zZo2W^G~>Iod1^EvuKg{;&Xs+PYZJ%ahhg7s7>C4DNbF;roVMeM>R-UlO~md;ykUHZ zZi=;hP`W*^3v4Oj-Ag5Ub&90z+DymoC5Doj!gr3CgzR;QN2pJUr=n?t{>!H@XuZys z;uLvTKdcX%7SElcPREsvWiI8CcuhymOs^}F!1h7_SaJJT?_^bFyw#CwHlk=e9z*KdbX4i4ellV+Z ze0c=?)2IxC&HGSu=qHoR$e5<#lHVY@YPB_!b zg=1eToLN5MT)i01!w=XS;4rV$stDKCx)Cm3CT?w_uy_%>%ie~8PES>Dr^wbigu3iC z_!7Z53KFqca@!lCK1^?Swn<$LO$d{KFvF(WNndOqLb$ybH~Z+82!#XtFop7i=&C|( z?+P@~Zs01gi8cTy!Jyke1y^R&4+pJPy4vdzwyO1|!T^=oc7Qqgcn?@pV40aT8LND{ z{AR<&Jv?uoQumcuGSjq^^b`VO%-g{)`vvfdke0baDu_IG(SEOsN6;D_uucRC*>omN zD;aa~sN$OIW2jq2FtJN*1{ps4WiRCEzY6r9A%$kWtzkF526 zjt8(KN#f1u1I9{v#<@eQ#%cI?k^&%^c#i{yl)$6J&p%+FB=|X_{sbb8znCn=;;Ygz z%2YXgA2P)_2F6wj#+Lc~ya^{|6|sxXu@oY9t_Iu3OMLuYw4mVqbmDzv3dUI~5+o=% z^6iMmsn#*rAz=r^NlQ}@388c_n5n(7Mv0Zw5o-%@PeKW-OM%Mo1TRB9I?Pq=KL*!K9JvWb$5%v+jxYP7(J@)X z!2*!k@EjihPBi;ZMzix15VWziJ&M6Y53vW)@n}NSj>XyzE{&Q}L#0lg9uE&HX|Scj zo^t|Sgu^3(q)W29_gCvUTribJSZTtzq@PQzXismywwsj5c-R3YVa=N;@4|k^f_vM2 zO#ss!XFz;BpPptTQJ%}{`?bxAWz&_Ol}g<#cN<+U)sH6&@yA=b*}hp)KQ8)p*N$cF6%R5=w`F!*O|~>4{OyiW znI$)U40b_$c|d}Kn>J@(8f z;yZOpkp|6!IGrvcO}{jY585LKb@L`B6yNgyeecMN!E2O-R1SzBmf` zwh1Zn*nLq*nF(3!u`i86yaX||45qwRDp;b&E(~u_?JLX-HjmvI&5&Y393HzX3P~^_ zb3OJ2QAqzof)VpP_JvW%p9m6PjNEh=CT%)A>p&C)IDbjFPX4TLaSva(DZEvag_lGGFBV>ULxSHVymU&*uNU4n^3D<7edL`XyxruT1g{|Z zAcY(v;yLnu{v)FPD0%-XyvNA>s{b7F{#AJAlJ_Iwok!ji!b_Ic z{E+Z2ByXqi=92d%;ms%S4tNF0MHG5WM9@~6|5$i^Jp&hD9*%9 zaOmSmu;P!g*zh!kH!OmCIjlH?-Ya?uFg%^{z_V~+xtZ>d<(!V3$k+E%L}2ZCn^~Vhs?W_~=Z$8C zvcop)y)M*d0p6=&XE2|Ct1B^9oBRh+n|`t_yS*z>)TWb;9tHr&13$|A^k>lov1Dpa zq_!zD=q`7*H$%1ge33*$%>ZRcD60DqP0~Ynryk{2l!}KMV3`(Pa|&BsXrSD0@R4qm zXxev)Q+o$39J(-z8R~2-4G4?C82@K(eEjv#sqbW7Ja3y=%mv9M_^TL=3#bNUjrg~J zgP<4Nvbb)>iqo+J|6=z^FQfjGL5mpl9aQ)4yASO^sqc`9@TOZE&tvZ1ya9ZkI?CtD zcs}~v>yrq{~P2N6+Bj7La_D)QUV5#73`o&y5A(lAlU*IbKNYLRYfxUx&^k*D~ zwBaxWE7uPJ8L+R$T$-TFz(!Zfk8X66u+a@#0(hb)7w0D_5J#v7d^u2B&`GJ_`b!^x zdtsXgrtqx)&`59@j;e=dLY0f97EKn&f`TUAV-Hsu&=+p9c+PL?p$%FRv;A!t38Tsq z^Y7bDqik5yk}6=ME9WE-tQ&)OppT`~`2?LlqTKC1tmUK6226GDFDaoh6wd)5G4JsI zJ(OcuU>j$oy1;CK3nB`;2Q*g|4m|KD-mrhjTORzzH?q#^%UlsFe9+&^)t-*pdUox=(0X?A4wgrCoj=C&+tOX0?;3vyV;aTdO~;23+&TxJa{TJ>8+|kLpS`b1 z*rBu^O&fiy@$cT(6g2$9_cfz943v2azmxc#!0#x22l3m7-^=*nO~#XWlkva#z9tpM z461Ynesl24B}o2-H#Ot^7r)W?-+5p2@eq|O-q&0TFL?H4?`u8@TF@4hc)^EjN&dw5v%YE;8%m+M*JG^YsT+q_@Qn7A9!Dr z3S-7|_`ZzaLHv3N5^J0PeP8qcmG?E{4UEiLco{7}0}Jj)U&QoTuuzgJY3+b@)ECZ6 zu0!jjup+!5#23FR&P!a(H~V(x%e;@oGldG3?{tb;E? z(TqGR;fXv?WJjOCh#vg7+g3BWP9-(oV)O z2S}Xytq%QWn|`NrS&6T_qOxK+PI!!-nEtp7iX$9Pr0~K=Mo-IIeqb2mx+2~I{Dng$ z+s}XBhiiX$mvJ2y@P7UXc!rmx#F`oUr+e(c0PFZo>GUTT)~EBO%~&K=r$hH$?S#M} z1t3hEI4MQndkInE>OBr^$?yS-QfRQ!`0Edk7M_g4Vd+eleL6q@{fQCaiJbEDC9h!N zLJC_vbZ)>)C-kFcQM5{pbOEWj!T)cRl=RJxn^9~KxP;j~mNs;8&c(kW$|F@}-}Cs; zg}GnAja``gA^gz`bG=`@FlV*Vg}K@??t-Dbus4SZd+ffP6}rmVWqb@S$I>FpDYRu| z4Yi8awq(eKg;pAW;%Bfcn9C2tF}0xLa^Gle#u5RYkr|{xR!^4k8HBEbw~i*~A8r9F z@f5+47s02P&JI_W@a_p6@Y_%t)`~t~(2D;7pvw*Ta>%;CftXfO`B4whPQgZ&(>{n# zC%#uY!Z%xTXoJ52b{Krr$hbUm7wbUE_956hJ4(cBZ>w-BB6OTMq;muln!Q8Km1jG> z=jfRX_x|R}p-%5v2|F#0<$jHg-nYY_{h){L0Pyj7XJ{#%j@EZA@Sedj9(1d#YCeY| z8ODa*;hA1%Lp|;};o3|;U7Haj8M^h^)Sf?m!7yH-8$#LQCX#X$t{T1gJ5VD!M}Tf8 z@%s-Db*CoxKl(!-;-DW!THgS~X2!tkk# z7gKsVxblg|H8sPcju~iZLb)*D(2N8%eIPgAqD;b8>T)CvTJX1Trcj;={9TgtGM-HS zXdguTj*azw+I*MsZ&StCTXc?b)=rOnIKy-T(V3rZqdSpKyqyGXUj=QCE)ca<`n&U~L=PV4MwX+GT40^`m z@sAU!W%bc!2&Kh_(-#Lov-_Mk7-OysAgDi8=;h+u(b! z=`J07FKSi}6LG6)VE&%<$Z|xXGjS-G@K;0d*P-nEhtnkK`1_R|yIqAGLt#a*wz$q1U(R-k0%u*JkiAFR}4s<3{3aKg&yikqkDr zct=oQ){AGL8qZnUpk-4oZDL?w|w{miPS<;q5yh zS;J~S>~HjCC!WA%(SyP1_?s(Fgo`Y!{U=XU&3xP1gQr~dW&0Z6n=VNW_t+O{`+M`U z@V8BJ=`GebF+U#Z#p!Y=e_OxY^f;Kvx{mY?_E0!t%U-dqUmbgs=k2<`^@S+Td+;a0 z=@l~%S$p6G;#nrrBCWeOH>(>Z1Md-30~Y+-pknN{LScB!1ACui>_E_1S!?%ryVoV+ z@6_wXM|C8*W#ctC*Sb=qK7j1ujTR4?w6d;RJNo-YN$>d`h-Jk+Y}r1daR##EFBs#2 zrwL#Rdo#T7{;Y0y+v%r8s^09%qlzVur9J}=;SmTsamv$OFUMHOPWSCX$Md`{KQIN0 zi>zfQU>2k=>mgiwpZJOP{&eeJ9PK@!d-uWe^NIM1!bFwI=z{SptM6fN5x;^Ncqg|! zt1D9u z4}XcPZXBNH%@4ycWnaXmuL$>RAKMn)^ARgPn1}WxqRi$zdQo!*ry0M5=Xk8?j>eh}bc{CKkF#EnHC*y@Xs1|R zsR6*&i|UF;m|4e>kHGKB-ofAFl7B_k0d#u;FAepx1H^Q&Yi1WXuP+5Bi%(F8>_vag zMLJJs-S6=%0GQ7@!G2=C`*?-t%{qt4_&BbA+(&9gBeFYqV^$rQ5(@WK%}6M6(2j&i{5cj-%t2Gl5d@n(M_0Q=kN$gx3Qn@qXzF*$vpT>>q7uy98D%E* z;4YJkfE9q1+K3fBxLz<3@40rx@$s!M<0GqYqaJFfro{~%@5@I%96UC)jf~eC#`SOC z4e&U%UmMEB-`2yUtQ+u`Xkgtjl%Xc**VAMcoj%6@Hf}Qe|4ia`gWCUK61NQ$#Uw6K_diGC9tAZdaf!m1#3fjq#3h3Nr$}5u%NHeX z4@msKk+=^(Gb(W#Pc=YX$1QWc*qS%MkXH9Tct;!F%<}=k&@) z^~%Tf%7^vJXR^JSc$u*TTcGG2i3jUwBh}}icLA5V*z0=nj+U_vXYn#%!`U$kd}Hwp z+u3B*dQ;>hye!sS{IoVSPQL&9SgYZ$EN#K+Je>E|LdS;0ptby#$RGa?d+!1tWp(d+ zKa&|?AcHe#(5PvNf)<5nG^l}~CWJ`>B@hTCAVLTvAqgRg$qW}uAUGfy9>&sc+tO~j zOMA2%TiVjr3R)`(P!bdokc}v|#Y@|Xu^N>^pp?Ad|623pCbph^&imQ#d(M95v*x$% z>%Z3eulvpPj$jpA4I52k95Ynq{bsi{yI*Jugh%;?@l^R0>ZRw$a84Js?I-0?&l<#N zb})N$+qUwk*-+g^MCc-HQ~oa7-q%M5qnsV}=STTQ)t^uB-CTb@(f6zR^Xcx##^GoE zdGBgheQQzud7FE~EohYYZzY1Algp!9eW3Ew{b&x-KK{Db%|H|1-0K#J>8zct?=jHQ zq@ca(R@3{m=_ll|Yp&srh}wbmt%<1(?#wn@2I+zg`u_eM<|jd{^-cu$x=G6GQSNm@ z17y3`EkV-iNg4NJAJEf|q|T#nBcI$lP{mRFf&_Bhy&(!0<&M_dF%C_* z6!h-Y`8%L|VC(hhMY8fnveKin@)(-s&Q^KjyLFcO(y`!F|u{N0Saodk{CjSqj*Y@<-dGWp*LlZc8vojLP^YWbiLwFL%ejNX1w>~WX z4w^kV&@srpekqE!EIQktK>XIWVUjgTOAZfmzu^CI;J^|4M{6(TFtfX6u;yFBsC%>R z%8l7SeqlP=ZBDW8j3nPDlO=nzw*-fn+1q5N!fUc2p(A$LwHv+X#`jy*?^0uf_neu% zV_JD^8d2QQW=A1sd7i-HwB%v_L0M^l?>uIq?ETZ3Q#hRy-X%K}vLBbF;Dalp&i&pF zhj_P=&vv^%*7QChvQhpxO{n{;lkscqrJYPUxi{U8{JE3V5P|m=Frl<=FzS_qo=dLc zhWp>6H+Ei(dwshqMWFABF06hq8C0e)7pDJF}m2?^-#?oOPIo4EF}-tar0(JY@R4=E#yoXz3ltoUKWt>ZMS{4V6ox}0HvDf;ZF7L;z zQglA{HNho;lKU{9CKScm@eOH!{m7SR-(aogjaVTwb zuyynJbHWC)oPWhyCgg0!+D@b1W^g-~_XJaa{xPQajo>^bjmP@$pH+0vdqXbH98eOR z_4|xA7w@$Ny}xgBQ0CrXIMOx%$q7lWSvwS4koh&kxXx%^OUYO-4bOf~M{`>Rb#p(X zo;>#+Y8!{&C!+n^@Q6YE$)NW@F#E-lp#N}NJRE?lPdULid?EcH?7%)^#n-R22pMmKyhrDb_c z_~Ikz+*rWvUa2&5t?yEZ<&N_x^8wypdf(jF6pp#66Ke03KmSTzMQ`Lb))saR`|Mm8 zQf}nugyu)(&ImV(OLmbFu+Mp*ztQ?_H0o0l{Eh?t6Ee&?c9%hMLw~sBQpcmwn?mXUf>0td^r|X-l8=MDH?OeIlIt`yV!2gagMf5(NgTX_2 zI)-;~dV6{96rP%s9oL@2O9c`;0u7bil@Yc9cV_hqTdXu;GRBfb*2g2L{F& z?nn0upA^R!&vMlZbA1Aa18gx3_l8o$_oT;!@cKVc!Gy+PU4&rJDYAA z107?RMcMbUrH8cV#xU5-y`zN;V4M5Jrd9{{qfNs*t_R>0@ye(8Tao`6{=UalZb_iS zx$N%p#85`(+>JDtCDIwp@b_zo&1(D5oY$VhB2J7LjP(zw-#4xywr$|0rUowRxs=)o z$sS=Xj&8UcWNO)EKgYa+T=v7hM@jXckAX-l7poikD?-9GvPZGSe1m*?OIT(2$x+!I z*PmSBUgKbc`M?7iwo%m5ZG({{AUXH?RVUA#I?zASyp(csRoZi5QXZQx)?AY_BX@du zA}z2ZF*qwsV!(3e*lT}s)%9!o1{zyR9pmAZ z9In?Hn?Tyy_vM7&rsBaT?k@52{L?3aPz2eMUhP1+M+U*F3hsf)Tps_F+Tf&{$6udtU19| zpPcARfLkZ8?0@bJ$*A(8xhbzQDYf_8=l*6;RtNP|+KoKN*?v!OAk8-47gIkrk);f( z1Y6GZaPgxmklq{mnhR7K%koWr_?;^21){!-KksszP>if@xj5>VH=P=7x}2a$41bT? zG*tD%0%*o+wImzD7nWXq`q=xR@a<^hs_k8Rv?(9?uBMlHI8b+7QdDNQx$*3KNLWV7 zVd*qydeT8{*c36czrxv*@E(?$Sy7>T(T{hVr817g1@|b!7*xCAztW1)9(1)gPyd^4 zZ`4`_1(qWyY&DdsIn}|M!o~1IWVb%js2L?DyrE9$oXZ;IOO>#~x5+@>9^%||^1N8z zb@_|+cR^cv8t42+AtZ!Vy{>;4aZVJyF%2LLhwkUf$C3v#v z{s3JTo8X@w93oW%Qc_^Cz{4w0kGL71@2mQIY%NmP|txeoexoT93 zH>U1pE@2zA(VotojprNEd6)){JR-;S{gjk&Krv)&8y$@~*)I@7&rI zeW~c2>itN$aZE8UmmTQa%T!L#3#e<~IEbK!nj5S-W?YMJzy#6s|8-;31diN}X&X4c z*cUzCEBa9o_)(tu@#Ok(iM|UFSI&)5<7|H0Q{) zs;2I9MGiepmz7CfCHtyR{O0bUW5J&hdYw3@2d7O8W}Go#u;rcjFbk%GJjH z4OeVz;ekCO_{sca@5R2+V`cmG58jOZ!|Aj8(;k*_OxONkVLCcZ*U7?pUU(oA^{F`_ z$9;L6vsx?J=b2x?ab@;}*yWZbn~`)jFMOk7dKcAr6wm$07v5ZMRjF}Qp`N5;yQikY zpj?%4F?dxl*AdKhj-BOlKPpEpm@%5=p?4ExC1=(d7C`BKH*qPG{TKsFiluqjtn09! zjc#X1#DHjT^mz=;!}eqLvoc6(4_?J`yS+2|e6ZHREu3HB0_C9Bld@NqDBsn~TRhjt z4J8M-FreDT;DQ@#Y}%mKfeGhqzrtfWw8yFgtBdj&$SDDm+{d~E3&F}4Sz@pS|Q9fKh3 zcGGlh0)DUudI0B7JA^E+D+`@YCh5Myz?4LGuRlROqSBMI?zv9?ZDy{+j5a?e(cbnj ziitkb^npkEYHxY^wach6np9_p#3@PlTBn)oJh#`Vrvp94OfhR6T!npDQd=i5?(D~+ zkM@&co1J--i`uU5^DyRQJ-R{GoOMTQ3wT)YRb|xkok=LPT@Ft8K8kRw%*a*=)!n zC%!0KhRn5(i{>+~SSc;-sxoM5J%(Pd4MkL_G9YAoQeXv9P59LIrnNs60`b+_-gL2H z-ro;+FR{I8X!ttDL#(&z6PFG1E*|jyUA$tIP;GW9x6h!ty2wL=>drx-J^bgFB?U)N zx`wjh$-R!coq?;OPhIK9;=2DTA<_Mex5IZ+WZzR;ocozs9cZ0zdfOR&q<0kd>fVpk zvys%klGF~R?U9>n?SZCvxdulk_c!3R$Ssgq&kx)yS7zAUkNjQIpw78`Il;J?TaZAw zGv$qs-PNZI_tmGKm0cXeU!k3O_4KIoNyk2MSGl=ayT;;*W-KN{rqe8y=}iC@^b%V=f^+gCd_lM2R^iI z^t%3zs@ax2KrVZ0qrZKTfJioaPg0-en-6nz*nf36hS9CQJ7RV*nR!5+0hWIIGVWUO zFkW4MaJ9qaW*2H8>8}qAzg;W+^|nKFta3y1ZRS2~T(|L>b;meK{KBzJ4qGHX(BMg( zwEp0lRzf>KV{vfBmG$@EwQ6vi{eY2}Ri8Z8ckU98eBR;j*Ezw_c4cmO^bV=qc{(;7 zmZE0o3X{m8>*>>}cGTXN75(MBRlS+xU=xI~_RmspFb32^M?JWro-#kuHOw_@FUfGr z=M1ei*ht%UlbSziyMY|Ava2Lf{s+{QcXII?J+4HOHXU!MaHcQ1M)&55z$CW|*%5adKIZ(jzMXe*c zql8+rd;Ao5zgMqH9Fh^*S32K$;XnM^DwkIa`TGijwXUR>=g$o%{tJ1^{$cBZ zQ&|m=4N>`dvywWK{=zmWZrQ9Gn(39>Va}aA_eS8P!6h&;L6jKAVHlH%S!}mi9A>eR zt2txEgCy%}PEXg>oUx2}39ma0olxThcGQPFc3DVq5!u1FYKJi+1l~}T=YqjC z^gUh>-VM&%H2g%f_lV?&dzasnHoU#rdt6k_-jjz8{q6qXta_$@^W_*){{!h!32hGk z~F|~(qKn?Lwc0SKq=jkXtcgb z|41gZ*KfiF3Gf_HUlNR_&Q00tmmbI!Pob6SA5eORfpJ?VPm$LfzANuVlau{SmL-;6 z6obK7zX|0HrH=bpOHFr_U!4=qXNr|pO*#g@A)o{4_I_={N?qL+?(Vj*Ra;ghr^>>&nNrQEN+M|{WK3u?5>U+)J?b7uPIkK9)oBzH?76G!$_Ik4AYQh~d zE#J@em*?NNb8P}`G)t3oPu^D3@2A~+n$DdJvNqs-Ue-5c9b%>X+{rz%@(}oNK}0)N z#)SUU<}6md8k_2#w+EVM2J0SIYYy+z-R)X)cqN#B<2kW*?b?>5z*jbXoL@)Eo>zIKH&O5_Xh{3w2-GSKz z_N=%l8JoS06&!aU1D%qTy3Otl5wBM^pG>SeuXk% zuRHWKx_2eBuh9Lo4s*gq79&Egb|b3=zaWC9f2XO!mZgcQU1TsV{?&)DY1Xm+*s-=bs!=kCyT2Ms7{{kD z(Z>qK8QxiGVU5CCp*YK~N7LJAZw&g|qnp%pzx_N;n8w7FtWb2Wc}TBNh{nodb6%s_ zeC}k@G3tG`qj`6dh7-)Xb?aue^MJLPeTI2nS*d6|y0meiw-LW(rQ(C5ZP6cfX77|d zV`q`S-Tw*~*UoEPFVxQUxl7CgCDD6X4rqsBwNlZpmW5e&V5Nd%nyggN{OOg7k0UD; zXM^*UR8}f3(DY0FaF(?VS*ggrkQrI2xS&=l&dPyiS*iG#bX7G9D^|7Q^5f{bCkXho z?0E9N4MzvF{{&N)1nb^w<6JPS5l=8X&}#uBEGrD$SQAvdZ`M7|Rw^mLXD^ca*}J*u zY?j<7L(g!JY%ir#Uy{=7e&l;_RvH{Y(URR)Z}1THd01ID%firg&+idF9?piwj^VEa zz3XH~w?k1&Dwm|R=p{DOyN;8WTit;qVO7QFveJz#!soK`CYL|{Lp~p(EH(PCr7)a? zZB$`!F&kp|nOizy_Sa2z$BL%YHs#vB+W=EY{>- zrToc+aW1s2GH0v);wyfa*N_Y&np%0wHhcPFEd z9{r#*d%NWRtakrvEZzfkuMtVBj|IdGp1i zA5h!8HH-v}{)iq@TlA4>IK>0#eG9iVin@sUB}$b39ii0@f;VZCU^Vw+E%-&fZN3<) z+Ybp(%A^ImB-u*Ikh(Ma2n9PdhMm~aAE9BsXz#QiliuqQI5cJ~Vh8y>VV&`FgE zJ#|RoZWd{z=PUE?{lw*2#39(>pXU64#MUTAnn|bR)Ix4}`fNRYL=P#c@obaF*Kc<{ z3C)mXk3p?-w#n&>if%sJx`sI>^H^_Hxgh?GB$kaL~EkDd5=d5s2Cz zFJR+*MgO%2g|^&0c0>GHE_^pn=-5Hx%~UExi;yo!qy*eBRgLRk5;+gZ@iQylyVYxl!Blo%=5q!Pm8Ku!2d z{;Ss>R)k*x5)>pJR>Z%pi1!dhbcp~SsR)2kWCB^ZUZ_XuFsylpO+ktFpNH9*yQ;G;lcf68x=Lrg^izK~yr1z~55wFO;AdH~W z`|3z~OUi1pRhpNl-Xys`cho-L^$Cq@#PXY+;^AUY@Hyl0l%&h$qOwOt<+aO1%sG2RB>`|eBdVKB2etyBlaVw1KS1#PVeDtqiBU!6VSfSo9a0#*?Chu|1z?) zK1Sp+){EhVRQO=`nTKqi=T7tIp17B1#gXV^NS5_OjL#i`j=!$?vM>GKp>zz_4D}7Z z_ak~*{*v80#QN?{@_+BunE9@|_Zor0_r?N#nkr>srur{c|D)wU(AYoFF<|*kY`o0c zZ+LdMkOl;<{@+#qhO!*1{u||ga|#ykLZn5+?GYRf-h!|Q7JAJrrja;KM&E!-O?@Mr zfz_n(fZZ2pWO%W_;5InsBXTw}^&n?K(YUU(k<{S2vCg494wMc1zB?y-hsFlrcWMGgg*Me9pPM z|EfZsD-R}Eghmj0xmQ*F5`-9;4=Ep7o~rK16I#^K1|dbeoX&;cqP=tIt;FFuu6AL? z%{Rg`o+mWQdEKmqsKrT?jPfh3NV(Hrp$0e%xLiMtqJt^F{YFO%fC@Z(&bTPlYh3peqRXGaKS@#47t4 z%2PmIyI8^7NgK9n&D*KcSaKF^cUFtpL_yZ4TDueJzcRk1|C#u1)=`tY#k%90qc!Ee z^nVuLNUlUHPUzx@uH2NX6D9wX4n8MLL5{koyvSvR7GF*OEccQ8{b%mo&v2d?9)c-V z?kDpm4(qCs%!Vmqx->f5yLja~1W&ny&hx zfEr`hHpR{{;pwvBd0A|DlES!f8kiSO;h#y(5zJQ0$ zmyuxSvY7BkS=#?rg>m7xz`XD&{(JgA@CNZ;++4>0Nd4hp?$)DfH8ebA5iiR1s6@KB z#i6*R2aQ;F5DRBeJ$g?&(_QqGOw92tmRqp3x6z-GS+Uw@y|F*!7=fcTIp(?%vdE?A z8PwY$8!lX`CR)3{9xMAct{WjUlPsX$mS;Y#z+p_+O5Y^z2Qhhud&?7TG!zZ2ak@Qwc20gLm*Y|MQ zr!5c{J?#_k{{PsvvQN=&Jl$_lgij(>Ong^WbIm{WLgE`q-&pO7YD3YMiXpaln)OX= zP47Pm{~t7dUG7!>UMBpjKWF%m%1WhbZCRp>w7QOe7;#B#z8>-C#&_jXBHr(x2CSW1 z?k^X9)aMDmtA0N)aYVGyw~?^-CZoF_Ge<6x@zCS3H`usupu3c-{*ie&Kl}+@TS=D4 z&jvBe9A<}ZZPqtFtN7k~UakV@c75m&`_fkN^x7^pxs~DM?B-FHx~bjbn%VcuEIpTa zD`3RH1r{&Qr*0E#1C*uM@bjXfDqJ?5X1IbG9<#r_u{nbtwoExjMf}QuI-EZyw);1o z?iX>rTGV%`F5CV@cYfn1?lqYcyW&7KAR04?%5q0@W~zA6c|v+*1(D8O=~~f}ON>X- zrgk~Bl}q%|#C01qq|w?- zsT15rO}d$%D4QGELo{uS*_m>OZ%``F5;Ea(hOtb0#MT$g4ciF{TA7B4@<-Xv?tV3U zA&=OZA2)r_|5Id3hn8yyA;zUSK%&&Un^2(Y=U#ay5#Z_u-Zx<3;7X$DVjz{3C@d~l zNbloeJy%L?;_}r(e@w_BBS$v<)sA7y-%b)fAS9|)AKxsf^sx<%wXw-OZ&Z`Wewh=2 zw+4(lYQDm%yN&0fLX+Z4+?OPa(oUn5)^4fViTkOP1GPg!MI#K;wZVQc=-QCVJ6)eJ zq0=~b-+WcE&edF}+EZpz*S$vA5dTVe9DHWw0;qG&JgMWa8MBLhUzb+*D`~pbtyLHo zUIONYi}~+v`ST-orbX;zDm!WXhcZWUJIGAfC6qZDSv4{?hM75rwA*&m&16%4*!)Q6EYvWJmC}*aILl19$Q(sm|IojRCxJ%k%Ek~vTn=nC8aumlm;@;qJ8{Gaz1+R~ z`wO)CX7~D^;sl=YMNb^D!o7~+H_dv*h|%l+;(jcIA`dU(6fOR*nD^mnV)^wsv(Oxm zW}xFb|3a=$N~9^BY=mW#6&&irRt~tTw4VGZeV+Mef2arfTNPW}1uiTd3 z`5*AkkGfp99T1oE=E^45p|J#$)cC9_0U9Ip!#gjkfWH zHO}!5FL#WNS8uIe8*SJT@v-myS@M7Gyde$n=VP{SOEy zusQ~r6vAMhYkG5r+@5WOv#9YXEwZ-wh!{P(PW?Bif9dp-rVe72Lm)`$AEKCzBCmA8 zNe<>p+ZM`*N3#gcfZV&~bMBU@rujUxSDN^mvg5)|Y?mD>BmbKbe^)72ED~T{PXbx7 zm+{$oHTqi~SmQMEs4s+K-;F%DyF7W>^>FD39GjU=)3K9K?Y!!hk+M9w<}Y(Y%SZD# z<`hhIi{L|s#)D%0t_A$l30fZ4xjeS>gvds8E|2d#!4^8JO41b+4P19!FGZI6F|Rzz zDpH^;{`&){wq{dCh}?sKO!uf6t=sd>dtHPisqVjlmkzLNS>FJ1fas7d z>}7nt06K z57kQ4@hR|vxK&V01U%#06Ce5@##A0N@nNJTwSTT5-uNX4GPJ`2qb zp^TB8kBU!3Qj!v%+w7egsRSfRijvahKqfV+6)(D?vh4A02YakI{uR|bnd+R~d1MZb z_#&CDPm@OKn>7;I-BizkJrca(zeVxG7XldguOV-_KznGGBEcE4;`?31JLT6ZajSf( zL1u0cw&oS%4MkFqX(g(OsA9D$RU)mdbsm)j+@l&T-q@Npe)o@m^rIggZEbohirc9^ zKKemm&vtz47o>4#r|!38Z>aR+^TM(R#M~fiNvOf*^6^JM5L>Et`KmbLnRxexrEoL1 zo31;>rJmo~EUsJf!q1A^uS$mjy|$)XNB!TIdWm{HJFYL20B!TS)!7pFU6K+K_dVN?u$4r5Ca&<1AzIf`7gBa4 zJ;i37v)lV2-QHcodokW1J`#4ksYVDA3siBs6Hl>YAdfnkdmLuu&_a$RmB)k&e@Q=r z3pZ8$W@ftBUYFQ;1n(4w>zb&WgFC+}?1`zcr{+KR`ukYL(egaSOT9{X!F*W;<(}H$ z>s+__hT&O{IF4wG2&r$Z{`6y#6uHwvX^vStGW_L|rnekT@5S+qU`h1Rl3-ptMrTWut&h#D zGwj(^axN&#I^%vO=WiukTZkK{wtd#j>S$_pDJvaV>Ci4OOw-S6&YwrunD@b%&u5R& zWA#u7a|}KW(@t&rAS$re$uKH|o6;_ZCh^d+lV)WG`(-N|-E-mYIl`3_!Wf@bW_=9a z$DreK21Ft4!sQIkO!fZ@ZDFqY1|vgu)t=`J+5?kA=}~#1<^6dC$<`;D?8y|i;Njf|{hfFKJP9BU#lXg0MacXC0W?;W7u+I_bbgnvX zMpi<26n1Lw>g)ph!&Z+!`eDc+n^bUG81eE^DLmrs(}JgXfYWh*PB`5%l}b)bzX_VF zlgqiE^v`#y{xf$bia{L)NvCGfo0@BON(o3MJ$S_{==e5M4d&=A>;K}LLD2NOac53t ztmX)28zs%&enwQYdRM{-dgFt2o}fRj*&B;@Jnln_za_9Do@-&#Q|2ev{QJBDwR{6a zR&zuqlOpr?b!kObn50};pXwfwp6h;&uO#Q#)yd1o(yeepqZ;o@K)WgNU+Aok51+UL z0yCTt*g0l5uaokGmP0zVMrO+D857T27n@<4^G+V^&DdZnXsp5rCiJdwo( zX?AK+nhj4rhi#fVqLPlWmt>|?2kle`+%M{kG#{Ho4%zo)OptcuQFp%70**&fOnj84 zYR+D*qZDY-^39Qk23g8$tM=1Pmx2>$ycp<+S$?1Unfg_4$!+25OM&UqZiLmb_1m=k zYouJ;jau%fRcgCh%U_pO??GCgAngxc(q`m)RC7f?o<_jM%UY}Nlsn3&#hIEM$Jc_6 zuT7AIN;;Urn-`+}R%quk2>CUrL>G)oTU88jnipuAr2}OtbjoM)+goJBmMIfYybuKx>_Y zzfu^W^;PQ3*4to3v-AAhhUXH(jx{G@FygcFN?v<2n~02aRv!Dnq!XDH!yBnw(VcIu zaFS7;V8w{ou@5pjeoPK#n~v{2z@ipfV5^& zDUza_etHQ#dU6H9Y8M@l!2Z7bBRH*Lrg5fY4*6p~?i)IC3V2?DFKBD`O?W zXGz|uzOHBDt_Pvh^%Q?Icg==EYNgpTcR}+I*DeT`49P(?`v^8B?xJ3sJ#m-hhGa=Z zGe>Dkrld-yXq!`%CfPD4mA{B)meQ0gN|h|qHYX}g$*EMyDXp2RG$q4Q`HN_dSDIwq zoK(p_Z8KSEju1`$BAR2A=19@xFQS>KG)GSr-O*ZiNX%0!6GM*gN-mh6rpzE6(8N^@jv6N!|>S?7oa%9MbhLaDoy^HWBxXhCVw6E+en%O zzD=4;=}r?V({SkPD$h;Mf?By*>7W z9_jH*2=};lOM3iL$W`g_OHyEn>z9xng_zNm9={a6;_iPmC-A2e>6b(rO_#)S0;wXp zLt=J+W-N0pH6wLDDJF5` zq?%vydNVPKd5*s+Laqn;plpgnY_>G~F~1aYRTX5Q)gtkI?w^qS9I=|dg9#3!Z_3(i&VUx>u8J^43^U;oSkLe18N^QYuj$oBD zG+uVWGcEsbVh?60_rMM#gK4bjHNDkudiYV%m&=vWJ=$9CnI5c;4L_tUCm#Kf3Gy82 zky3fHjF9Hiz{CL4nl>Tww|XfvFZ>B>LxKItNe9>eW%V^u_vra0(;k}3NMvJL%FC-h z5f0>ZBh5(HI?nW5d1l;Wz9IcvoF<0+os4Ef>HRZ!Y-h@&KUF$v*?9pO53uW*AJv)7$=>}0ZFHH?-DO>Gc)7dyJD(Cu4>`Pj1to^ zn?3L%FA2uX<~AAC-D#KV^$-MhwDy7%lYYb;_|##Cbo$;v&|S&^F-5W_b9n@ zo!$9kO1)-#O2vryRr{pOauS?FgHRBh!x7CiS4nXC6(pFd+^N<`FA_=`S?)u>ov!rJ zzti`LS$%h2B)z8**D-0Km^8fcq?VYjIVHhCA}6Fd^rV05&Ti7pd+e%X^Mjerg08qq ztr>WKBstQWbddbGK+no!&g1xz1Kt`Fe2`XMW^$&C7%_Iri1F^nekbWZR1PC^BTZ=Z z&JdRpvHC!=Bqnvb_b{qtNrpRC9+S0&z~7wiN7UNVg(&x?Ms(m3k2yn*T*ikcUktgv zozl8|NXVrcM*GX0BMy8=Y`wJhEhfubQpB`p;ESA=j-exVkpTBJ2znVUtr^SbKdPy~*wTImU`s6Iw@7_N_Y1s&5?f zS7FQ1c(=F2U3=0ghL*yi6{}xMIwqtG0V(_HmYXl}48{4VRhg35=A;P>kVLxh42{=S5;~5)l#gyLLj6Gr{eDN1QuMfqnCyJ_-HeI)xsWI-K zxjfP(u%8#^;Z~mxDLqpqTUOq}`|I)$Wo*-*9HZJpj`h-*ib)Q$TGK<0ojKwAzAlAS zW=RvFazs<7n?pO2pC!TMNJf&;DU!LHZlSAD5cKmV1MD}_s=}zhKF>ylKeEEtbECq4 zs1?7y^%o(>g&o7O+Pek|&9;Tcd{<%~9F`Y;=SD0XHp9#vN&Qq66Fw?B9aIxUWMny~ ziC4sie_9;^$h4M3^S{6UQ&S*jn$74x!)A0$w;AsujwALWeu4M_;+u$iL?vP& zA`dYIF%EGvA_n0=yw9t)#}SQ)XAoPmZN?5nBjO0+O+*-R0pXcyGe#iBASNOfAZifx zh;JgcBVIrpN4$$@NA!ozctj%NK13d(6tNny1@Tiv3*v3WMMNw#+>MxzC_y}ocnt9! z#CC*y70@yRk&K8(oaK?;HxP}8A0oCO8W5F;2N2^BqY+<3I1s=8vduVvknacJCd3NF z0>lKwt%&OoPDICK;(|DYcm}Zz(SYdt{W`<&xbh9p&lee0vdz88t>RzuSx= z6}DldSJik|l=*UMsumU3%Dxyr=GBaNyUio+>cN5FNpKLD=&*StqANhwc#I?9m7?Fz z=DAArL78zp0$vNI_P2Rt)qFF^&I<^$dE$U-P_CnV9vmk6PMaqlXaR2k69?KnH-hoe zHqQ#M0bB`g2OkFagBQWmpe(S2!5PNgMk2pEjlsqsBf*F_N{D5ZQE2##GSYi7I@PE} z?n7Qn4pb|h8l|qpO!T#zBGRcy`GoiCv;0r)^51e%jE`0LwwODV#NTSdT!ed}K+-%O zbq%I|@0~_IK=m!e8-i88NCMoXRfWwcncFJ4g{LJqnG5iXI>QcMDXNLRT%g z5URwdc&IK^oY6DxmOpoQ`SbbX?IR4~xkA!19wB*A7>T>(?>$}q`k|rNSV8&~Ly3=n zakW&H6v@NhzDYhUGL~SYm@p&-Y9c=OOxHV%?)X@UY~$v=4)ztrVZ6 zb`bw0ucU5}&_u5gu@D}SI#tZ$jg`0-ZW1%8RV%t&=$yQ*i}$Ux=&q-&G?4Q1kLyug z=7mQkE)ue?VV5e}dh?7GPSQU~FF!F7-?EKdW0ElinY5HrYNZ@Vy|NUUq>@e#sWZjJ zQdI-2#H>igT&R)skh($2%`)Xfw_jo|<@0iU{{KdL#}gaj3Qe`-x0E_*-^!>pi$S5? z;tSygX%Q=wohoA9UFNNrX)dwSDM6)^@Lrk952>q1QWq^kRioOMPuC*d=_wra>6DUs z(}!z6zDT_){G|W8T~5UR3UaHEa4X@}zGbYtJ{5CGfALjPLAY19{XJ_>-Tp0Bz9lFd z5|d^4UxS`i-n(1uiN-WSPa}1wV(-&!k8sgcBlEImGvTjk@LBF`rSae9YkMIREzm9#D{VCU~qd^buV3=_S%05Z3#kZ$V%fr6~=9( ztE{kzf7X``MT?X#(zcaAVZ4!to^XwBHPVey{NkzEddFZ2wiYUSYT!BRV^Oa$I->Xj za#=i*kKGAfa(13JN*~SA?G32F8fbMb<2O%LoPFt_{BkF z!;n6&l#v=zL`q5$y~^%hvteXZ)TUKbR4u}q$TMn+iv=@_eR+iyekISf0M!@*Ay4}ioMH`7x~1#c!IyAq_{?nG$hfclr5|&tXY{~ zT3l%nGo#q&uc^caiJ9)NsUc}19#qv#^)Fqh;)vOls>PC)U1pOiOR8#?7D~cebmy*I zy0EIEY|)gm$|ds-~=1(c-Q2FU?(9>nmP5r3z1rYb9^0 zmR1+m6zBSC$|@J5Cd`Rs7Rg8`TCFWh$XYE~(9?WYZE;N`Ol@^);nHGBze%<5Nm)@Z z%_-^Gh1Ff5^@=}vRJgc!QjyRwvux3l^eTU)@9r_mPDWWpagVr9SeaE=SyZ7}N8G31$8|raoEGS)2T3YIK4p>oLy}Y`**Ld@JkImD9IF2}tD5r)Qwdk_6++)EEZ+KGC0PPz;P*f2EO4M$V)x%oSp% zRwUS~)G|Zt*CtdIsEb0Qd;l}zS4Y)pH(8m zUrS5;?~Bm@Ms;pGuOFv0I9k%oqRTUVaLHEC91TFMy zda8(%R%^O+Us3B=H1^g@BL(EkiC{K(JLy%#|H?@CqLSZeT39icpY%Poj@Z&Rvy3cS z{iUkym!7J8((g$yW0j($z}$KT4q8O4H5NB8g10F;{3A8qN?Sh zo>EvF(aWi-_LKPNN&Pl$VL3Hvj~YnIFJ@M)uRNgXQWbMG3p|Yo72yBnfAQpA@83xJ z&-&L}|MIFVW(xn&Z=Lb!UvK+sjqab#_T{5(I)ef*K!g#bNO` z+&Fy1O*emOiGXxhyTBv{%I4^Cwen7vnEac@|5hU z({iTI$eqc?p4oFA(CPo#=Kr5ae<=j9qii0v?gYyCdn73H0f`{P5hE3p-Sk-?D_=$q zDDwidK^dzr0A;446qGrIYS0C)00)Eh;1ys4$SE9SGbo*qEugGpZ3C|aw}V%KJHZ%m zH#ih*1g{2LK()RFUW@u9DC=9NL0R7lgR;KW4l<`s8%kFV9GD1x0UQs05zGRIfiuB)Z~=G&SOMM$t^kLF>%bA< zX7DC(D|j=w9sCmbG;NZ&jzste^ng>qIB+UB5}XE(0dv4qa0WO9%mZhG`Ct+F0O$jY!FAvg@NuvL zd;(kx?gVXAAkTviQ06LRp}Yn4K=3#?2s{nC!1qC^a5})NK*t^M1Ly&-2IIi%z>(k= zz*KNFI0Z}ri@^K9YA_vK1ug*}2W?bTPk;_^CpZ9n9vld^fP=u}pbI<=UI)Gprhtw+ z@dxyPGOCIP9pGqi0GJF81Sf)nz#Py8J_ue1mVzmu542I?tpgq4W^e$w6&wg|2M2*q zgD$WUybe4BrhxB)HY&z5;6SM$lduoEKo=MbUI&f%eL- z1#AFq@$eNm5PSk01nv}b@Od#G0Ucrvo)mNNT`>pS#eAdz<6sWDz(HUvXd4YZq7NpD zJ~&?V6Dgmf56%>QaDnKLp?r!yxI*;7b)uh4dWjm`D(dm1m#D#~MV(4|i5fg4I1xGp zv!GLO3UmtQP)a{v6B! zw}B6W%$FOb;47dH{131mJO*w8p8~gl&w@{Y`@x;yo8a@Hv;i&PA@Df32Rse7fThqS zZPNRw<>Cp)-S8wh5`Ago;!rOFE8+$H*$OCMl1YOm;{c7R2w zrLCz3H-K5_OP^pBYLZa(1*C7#fcgjEAK?4o%U}n%19aSD^Be>{;Mc)8@HucK_*-xc_%xUbo&cwSN5I+O zm%$>i5v&GZ1xpEUAh-(kQLq909r!r-8n_L75!?a(3fv7gf&0PZ;1Tc%@J;Y1U>N)Z zcn16z&`4$u7I1;T24lg);0W+7FcCZjjt74aW`VDRGrQq>8repx+5 zbfnlk{|1f_0&2i$>rFSsB44frPbL+}jvZLkA(*MqL{HqUp!Sa2S=8+ww!5vU&q zr4OA7CZgU5p2j>GOhsJ}hEb0Nr=VU78mQxd*{J7(MPMc9ME?t5HR=Me1@&FvD%7jM zc+~M=1L}pK2lW@h$5Af;8&Qt|x1s(wa5wlBa5nm10*|0B1K$Lzz%XbBJHWR=Cr{&S z24leQgYn=mz|r83z+^B3oCsEfdgZ`i&Rw|PVE$i9skNSz&TP1p7SXR&D60_i$qoC7-Nm$yXWiS60^LlRYsSwS8Ho zmrqtDg~w- zMM;ES*_$R`X=I(Dkd-+3iX(I_jrdzgO31e);!bwn$S3<^Rh%JwA?uM3D7UgsIgu4f%^xE7A{QP>z~v0&!WRjwTuoB) z8YLHf;g1A#rzp7}c@}FenomSuxKQ^0h5?`Ue)_4ecn)0WX6cK%ii|~=Gvt}u|xSgro3O`A> z;#PP{=$wdL_)6A}bQ($=Cm2$X3V(^8k`Bd+POtJ`_$+}?^UxPw6S>4!_)Yv2I)&#F zurU?6@SV_^ja+z7A47rF42@Vdywf8lpY zx4v-^{#23k30}j)%oS;%s_*l|Nr~6Wsrc+fKNgXY| zPFH?N9Hd?rz7d)<9a8U#&(dbgZZF|8Nk?5~w0&J>w0@;>Yn2&E)0{}2X^L~u>B&R7 z4Cr#(lh4vs9Ch8S^IMk_o!=8wdiBi9p7yQydx?*HI-Xv|3wl38mf}-sYlN?*9OyWw zsj{o%tkYh{IbHE`Z6wtt4n4!u^yxTQVdtn+vcjICa!QAttLV^SPl<#l>8-=iVP{6l zrlgrpV_lz2h|sZ=%MPs)V1+SJ<*5!MTjjhJhOP@F44v;f4B2yP<*BA)p~`Csqi-JR z@N^DX;bkjYbh=GavDNvy*rdDlg`6YV-t-PHakqbZPDSB&F>u9wamYX?|xad5QvS_834qum8o!gchT@p3T z6I4D}X(44r^WS7ezqT_o!gE4Pn#u=lXNoHOR@|jut^LuQtnGYR?Zwe{aw6qb{7I)= zSz)F1$d6fy_q5vyJ?!W7(4QX3OYuk78amuuRikKmRwQ4<&Qxj*i?$p^zvesPRVht6 zp9FP1FT2Mr+6sx2C0|G#Z^?^PPejvMta^=FUPgUp*(q1O8?C=Y^;z@`rlpOKoiFOU-J@bt|X+Ss9^O+74YyE$UG}X&wDvfw|Q_N}n$Q%EV9I z&(XbM-M+{^SkagCT!^a#YW!}u(qEQ+uhM(deW67veI(ojQb*z|edYxImngY}rS}l& zawOsb~Sbl0A()tgpyw`jwIV5&;I#zYbWyiCnFZ+$V z<=ys+dg$vtO4=Wt?pnT>{IuMbsyx&BOX=HK`m%@IlItF{wj-xcy7jxmtyVmt?MMq~ z+41+#m!0aOFKwut1QNOQKg5;QZ<8}dBA0%W9vSKWlO6@=I#`c9v|Q(xC6}_N>OPR>UER0V`?GXk&C-`TT6o&(2kTLk>`F@@r-hev|5ElsTm4!+ zVv?Q93B*U@sQVb2kF{L><)UBV`*Ql>(%%yKVwFC+|F=Z(mF|aWdaVAFR*4(wV=hr~ z*8RjKs=m?vVm%Vm{bfBm(|sn*uezVBM_;;sr+w9}f*u9Q*hu0ab{iDGcA{Yu_Nt~Wk=FTmj~TH)nVx|iXPGGF^cT(w#F->)7>|eGiUNy z{T0pq-D=Ib*7!z`iuL$LkBoI6R)?$mKbrrvT+^xL@-OXy^v(4sT8~j=_rK`tcH0_{ zTWak}n@eA(r@5$mnoG*)(6xO@oo=;^w`3>0m|1)&rzE5gExNt+d)C3)zMLGqoPDj| z+rEsktaK2$6?Ykb$j)^MOZVM%OQXlv7O%*z#csKb2lecN9#84~mU#xzmweS@7M&k@ zJSaOUWsDekaMI}|Nq=w_{fH5``Cr`z^V!=hKG!xF)i08H%BLSQ zJjJ6D6BCi&F+6u_+El?wQ)MhJD05$T44D9zUV=N1`c!%;EFnXRFq8{4MrEe z{^~5Tb$Ok`Fs``bioq_iKG4~}pFLt3C)k&7ko76I*iV}@BR6MGeD2h7Jj=a+`AAo^ z81?TbZ?+i($0s4;ul@$RTtW<`Aw<6#|OhWF*@tlf=_OLGDR@xvpp}k zqG7^#!Pme4m{Pl@yrR?(uZ)%HQKSF%CHD%tzjjoqXV3V-eJJmbV3)pS&vIw^WBF@^ zV})zcVbNvLDRj%d>3`^C?va4Df-*n*_eC!7d@=<^Sw=q>#0WRGXS-wfvAp zHkt5E-C*hTMlS78RB@ZBLQDPJRcyQCv((3Xn9mq$cq$M*&G+{(7yTdJ+S|OZ|6jSA zJN+VVHuRA9wbyn}x4jEJ22PZ z{^*+C=7;*Y|6Z*&moUnZTXgoML(CF=z5VGMkI}*2=6%Dt*vGuD|GC`BAmLcy_l?Kc zO}))~y1!$e;mJmb`<`F$%n2Df8#BDJd)iR9Ioty7PPZ8kPDBU&&HLyVy~w)ALDq_n zfT-(_vOe+(>O+)4#F3X+ClY~v^?uC2RKxUO7-qy9HyAe>!)fbpGHy1$#7_IdvYOiJmA4gD&@EBYf`wIu zHAMwwMFo{|P^+(|9K!3Z$pJARwmAmD3BSs!f}S=O$(cIKdT~unRZTBni@A5hGF@Ek zE2u48T3u0G!wEAwyqcQD)n&cCR2s|W99>Tmo~;R2CK#E@t@I z!!lZZtt~BE0Wp0nYR$e@t2utxBc&venv#NrWrbZCC0aWF3VbW8yE3O+Te7t$MYYA1 zwVVZAcDV>FTil1*vb&P*x?@qV)UJ)_^-k~VvXY9z+R_5JsGIX@d+EZea_q5-7R#_F z<94~|?Yj?NFQ{43<kk~TlCrG72JZ6V%^Jfo zsar2*hRD0smR-UBz60sM{tl!lquQs=BNr6;MLET@sF*X=rL~++E2gEeOjXzxNwhJRzH+5#y1PqHhoJo*)}^a_ zST2X9BX0B3y?3gHCd#0u_17*e;OuqPq5>a>xobHQ%}jnoU$q6g5JAGCnzCxjYe8Y{ zqOvkMj~}tMsG_iJDM?I?T2i=(G`P+(QHjLNj1EOnn`)`V@1o*mWs8a>+ai85lC#Vg zRZyuGlonR_XkD$43M&^CS9B9fTWgu9297a!M6KG38!Z(zwuGVrt0?0j>;%iC2NlYI zQ)CezYKkGCwzy}!N-eWeb*#CdSkB7V7Wg=6UFDbdMOsZ?agkx%YS~mFcO|UxxTRm~ zU%0f)*CQq#%Y^KLhkHb_!7`C59Mh7r#eV8=b+%m7nsCQ$i7G>l{kF`mlj`~iy(0{|EiWQCBmFsFHSRl z`>7B(3eH6ZlWHdxFZ3^7TwIe=Q%sZMGu|`2m5Zv1igPFju!ixXoG$L6cHpM##C!&& z$6r%yxt%QZMGS>9!?@Pg^K!6j#5}vI$X`+1R5OFFZv%iJgu*SWqT?ICjm{qm)EBWKo)nC|dIJ(V6AeeGi^rDhcC zv^uU-x!kS5e3ztokM#XSQcYaWlqUHoDItu~=MDyAk*0vQ&0j5tSo4jmJ{@kFVf?#& zy1%$)We(*{E&!lRs6+UqaZ``ni6kG{vr_r1t`v}40n%y}CCH37#J;z3Sy@e0X=oj3qX-~#Uc)r!-;q(S!_Hh@%~KXccLbJ*8LM{l|{MLWtA!( z#xESX6~&x-Z~Sy@xQ=6HaSfeCYRO0hnaOa>?79P^S>!}Y-+j>{DoE0*1ENw)9^0L+ zI=hMS2k@2 z5L~bBTS%9pP`J3*C>3{U;=?^c)iiIm$ZM2uIl>0UefB9;g_OUAazBN-hhw9Cn%`IL z=Mo9ZoX#|25bK!XtC&@}oMX<$1_`?dH;>TVoUZB3H_8-GsJdNv64wd#Dc!d|pw73c z8#9FduA4Hx8o7l-H1k;jRrhQ}3e1?sHr5CIz6JMKq)sfBKo-zgw2)zvZF}Cu88O_1>+Ibh&TjQo1$OhA@tNEgyyvo zd<2xZ1Q24r4)OoAcQtTX73u!f(AXj+!^H1*6@m(L=6rvjS4G7Zg%p)c16DLjR1!2a zO;l_tDKW8V*Ax|z-B7W}NGVxG!@Y=9sAy=YSd^5Qw2P&A|HBJ@?Rt0j-ur8R_il&Z zpP6^gd_B+1JoB70&&*-dy)aS09+q&-xE?MZ_$H83p8}!zU8RKudSUua_6n6bj zcAw$r>t_!9bR6)$<>jt}^Oo07SI3{Aq+9QEcNc!^1;U@8a{tOAZrMFrCEP8$hx1=q z>;Jv7|9^ChcI`bpqo-o885EA_#d8<`vXw!(pSeBjHoDzKYilntpX<4l7B>&^|G44U z2B-V>U;ST%wNQ4sTHSa4!T5t(<8Md&gX`snGg0tM-j zV~-zmI--s}b&R_%rrW#dlj;+-7qQ0vTw6+aIGcBe01en_+XyrP&A=tVaX0oV0-k_3 z;0ri`AV2|JKqwFnL;#V%L?9Z71>%5sAOT1Ml7aa^Dv$wW0W5wtkOve1ML;P~4pakm zKt0d^Gy`5;+`1yGy)XPuAP^vc0=R$>ARLGW5`YvS6UYOKfO4P;r~&GL2A~PJ1bEzo zG5{Z-7vKj30R|8bOaxf`IJikb3XlQh0EIvqPy^Hf4S>T3^#jx2-O$EgnKeJm6+PSN?lg*m^}GekS7I3M^07wjXzM?>}y% z)!AWX_clLsS-VytPFvXQEWC39ZoC>7Vu8}p4j)Wm&qeHc!UbG`j7ovK2zjt)H1@pZ z1Qr5Uuk7}&tNyYM*ZkjmUiG_HdtLR1@9BKi@7L6&&7bmW*1c_hXYmK!-F}Z<`+L4D zF#o!*%PV^B{$!NP*|_GNga`9B?|tJ*SLLM3{%3l;9M=8p64%qO9$7V{Q-_!C-@3+i zaaVTm*NeI=U$po=*Dm8w?!hY~`X=xG#5HqYZTgof`-ksXnK!6->9nx{>Pvq~sGUE! z`1s2wF23=@+2{W7$dGlP&pBQG?fnB&7u^>e=-urP&0D-r?=Ag4`0S>t3x7F#^5J=_ z4i24C{^5#Fxm&WkpWZO+t|{HTW-oev_MH78BO?dbZCa`7V$oY)j~Th?%p`N~Bz@VM zS0-GUl-sz@SrV}^U5@$a^0Eobs{JRuaPiY8{;;a~Lcp%|Ws{Dl%n058yVsmAwjUi` z>d(wS9S6z}w0^|x2m5LBjw2fq*uQ3bLahE-*h{a?=(6NHd(S69Q@Wpu?DpJy&cl(p^TRXfjKY!Nd&EmoH&K%0zb@&T=_vOnKF{yVyQ~qY1JuvjK zlOsz%$XxaLe*2ZuG5YM_13n-8cB_5ji5;2h(9M0e9n7@-`tLhcyhEok%jVfJV;}wF zbKAzu@3J$>KJv}LmpXp%%F?bs1lxZ0#xK>40bec5d%#|hzpk!0cK)!+<72JK&vq>D zAMwnRD=QY6E56sd&ztN&gqGwRzkJ~%W%2OWiX4}Z=rw7Po;|nKpME~~Hho{}(80HF ze|@(6=|dX-bgz&5f69F`B4dJ@`_05H>0-YUEJt zA!)H+i*m;c9f6qGCvtsQM9Ao&gMx1i8xw)Bkt0S8k8dz^zF&Jr@Pnb7Up z@UaWU{nb0H(I~ea@?+M>%o6+w?AvsoIzIxx+>J7cyp(zeA9 zhUGK+77ojY*{Qp~8NkXN1ph3Q!FEhI@mBKYGs}bUM)g`gg zeD;+Cb}IihDsH5Ml}B25bYuLRIdwgs=79oOhaq=%UM<^k!@iBf+RT0GKeOg`f2D%e zowf5U#AADp+JB^<42P^J4{dOS!o@x1e2(ho{HQS#vomI7EZ!^A5h5NIv za^zZX!nq19Juw1z*;&PGC&9IHS^8gi)UmGWFzn>%@y=HJ7c&6s!U4`HY!w!EFlNBm zh+zYi04Gcga9VZz%o$V6fVoo=18nQAJB*mbM4bE_Ki7#2W+a*cIQLvjoE(SK-xCK+ ze{%AynTa!}CJn$6w-%E){h>KDz=?&&C#S;TVw~Gj%Uv3>aypHqSvYN)EnT(d*6;7+ z#`kMUhm{MAyq<$)rzfT)UcGt!?V-s?%GM%7u`D0&jA#GN zfS5!~WizKunHAui{p6s@?8{PSz|@%d#3=#Jfmib}2Hv_9W8e*SG6r5H4#|yyZG6KI z)&T!5mp9u#hi7@(hZ4G+ZlQZ=6+OY-%lG8{`A7K~d@{e7-@_l}+Y7ygL?KOBFLZ$E z*k*CLbWl1b)k;AMue`17P%4#UN-y<8wL)!De^94sDcUCOJM)x<%$+z72F^G#kt`-@ zWE0s;LbzGN9ATdDoUmAUUU*S>Sx6I$#Y)j3c}kt7-qPbztdt*~?@&4`PG!6jrOZ+m zD2tU>lr_o*Ws6dzR4C_^uuG@M4z z*>o-ah*r}YT1)F_J#CHNy0rCksN@~fM zplO4WI+4NHuUIgpQAO!VvJ!Zx8o2o!gUd&Fa6 zv#3eA(iW*$IxL-*zLhRXo#fu=)1o{?9wm>HC(G02m2xS1@-g{G`9UR7`HhmVoK`L? z{n2N8Xus8}wUg+ZPwSR3-I!yP8;6Xy%=gVov(C)5wpu&U@4)+ToSOrufP7DGqYu)h zw3s?LgL@S8a=gKh=bz?p7bXea#D~Qn#b9ZIv{L#GHR&slki+Hi^5gOxjIHJJYB^Wl zF8@N&m2t{G^|;zqdq7jPL0Y_aLF=VUx}}fMqxE_ED*X-pO}#+hrGKsa8ezs#Bg+Uh zCz?yl3iG&CZz%PV;m4QLY=HWufC?fq5fWd4`ZSN z(%_7GRz0s?RIflP+@;;4b=Q6gnyIF0gS80IJxhBQV`iE5s&-U6uiXJT&trq2NZusd z$h+hNvX_)&R2(BGNj+&K%}~U=XjhB~Cw+hl;8X;SrPJvGx`u9~<@6{$0m*QHyTJX( zIr&6>8-IZBCiE8`7NQ}iR|%_ydf}4b5=V%q#qLrJr0H_$GwHl^o7`0nkX89tkfAf> zMd)uEAwLhx_44ia~>MtjJd|!#z-aD%qH=CQGxVROyfCiC;>M(x0UeIZTe0Ga&B-Wr#9TnW@ZCmMAZvy{na_YQ8#D zkJMxJS$e9Trl;!}dZwPG#~87YElHLylPk4uz9*0ha)`vyc$z?yXfoYQzk$^D;eGjD zEq$}MdfLcme8-bPF#fl-lDmcCxg>5rm&&DcncQkFhs);*TV{cBt_pKN9oN7$ahEs` z-i!A^ehyg6pjd}{?k*ywLYYuw)EN!X1uhvLrkCks_A>p1L+6+RQQY%|f%-EH%r`D)iMlv%zdKFPR>em*r#iviz(dORx+p*b22Gtcg~v z6>lY3^Q}}X-O999TRB#~RcIAkrB=CBWz|@9R)f`KT|)2nvVG9A{p=uHunjxd4z(lf ziFT|VZztLF?NmG6&a_wCInY%K?PAOr<#v@_170@RP4*=wr=0j^FP?inh!^p}X!j#Q zn8gju;-S!6CX!eZPm;)dl1kD^CRt5#pv4rDVp0nERYht@9cgHp(>)-+d}uG~M}r{0 z3`nq0$gqi!V)1CB`82gp3(4Ck zGz$*VQ}h;nMW+}j6396hWL&ryDMpKNVuF|~rif``hL|O0L*5l&l$3~N(15GOTCrYi zgs#AJVQ`krc@#g-GF2q!ca1L7FE^DN>r0A!SL~(2@(JBFt`OQl(T4oxC1n zt66f$p0c;>D?8;tnaGOlg6149M`FCi$q90@oFb=TJDymBjQNz_pHCl~R6VzliMNLyP)GRd{QXO(pEm6zVO0`<8 zRqNG8wOMs&o|?Djt2wnmjX?8oX(3v;7O6#Raaw|wj3P_@*7kd+e=WFQVY3R9mqztod6Y)krRcIt6M;4@Y zH8e;c&X-fr-y)$kWpPE&32QkAWQmK9M&C){kx4YZGu@)=dXQ@9o~cTjnhuIGLDOnb zl>@r+L0KVaD+YC?psyShR)NMEP+12$8$f9jXuSk#JwUG)DE0x(y+E}e=newq1}F~( z?V+GP0`yM=2V%j4cyJ*Je3%bTq=Fae;6^6+u^Jr70Z;P5l|t~P7@R2uZ_2@)D)6TU z9I6A48Z;l>PZ#uHJwi{?Q(9$gJ~X*PJP8!zd8ZUl1Lb<9?l3(e)x06sd?DGKkZpmG cZVIHE3-T=l5-z+&#zjNAfiFK_|7SSxpWEF^@c;k- literal 0 HcmV?d00001 diff --git a/Core Includes/airspyhf.dll b/Core Includes/airspyhf.dll new file mode 100644 index 0000000000000000000000000000000000000000..6c0b89e63d8567b383532c63252f631a9d087f78 GIT binary patch literal 103936 zcmeFae|%KM)jxhW*-aMMa2H50O3)y|rUoi@K}k302D3>-0viLniI8AhNYfQt8tw(G z1QKr+b8}hcc|OvrkG4|uskJ^WeI7xy0=o%jgCGX98VhY>o7#z+Y7|Tsh`FElnY){W z+NZD2U*EsJXzrbR=GU1sXU?2Cb7r>ep4~#SAP8ps>AD~s!khlN`14;s1`s{@x>qL) zFHLxJ)*;ifH)pM^`|hUfjrHIEPW?CU&;Ir|zxTcGOWEIApItA1FZ;XS%Pv|`k$wO7 z*RB6rTH3^%c+tPv6ukQLsef6T_=~xcmVSiqn5$sv$NZhVRKa`Lzj5iOcz^upj-`Wm ze?IlkOaB9J*RIs1L;QXF(hGRUT#NYIwQDhd-~HWh*HPJtmU!HPu*{Sq6h3?NJqcKk zkTh$O$tDOF00|jT-GR5A{!9e0^Kg?7d0>z|bu&+#>B{Zj3XYx~X_?xDo-R z3$4AosBmQ=nrlIP7vfX!-u|U@uCLW^s{b~kI8EpQS_#enEZzDI-$z2CkuZRGYRk?q zrCS2%|Nrm*fdW45qO!v(NDi-KF#qL7b79eZe99Z3H7`E|^N3JX?L&YJIbnJ&t5Z6DhV* zp-mkx;(3(9S_(=MJ#0%n0r8xmbeLDje_iVc)r`k^mDXRLz&S8Td3QGBSrKMQ;htol zhyBthL*>Xj^x#jZmZ&xOESF%r^@Eh01>&ia10k{bIY11!U+}PdRtrLja?GZ*n-$%< z?Ucrw;Lr6jJI`cQi>*L+ljCeam)7|OJ)@KevfQegpWtM9Ty+m4!QI*ss>;W%MmBBL zFj}rHH>(qCBTFnoQe+7yg1RJI{h?j0&x$O`L}H?%W`11Rnk`6E?{NO45uo~~)~*H- zw7*ujuU(BUt2WbmB|mhyEKLSyL|mEAWC(VA=nMAiZwErMnBbCk zYEaMG_8O{WlvzM;r9WFMEK=S5s=G%kELGi1b@yt81zw+aNi7?$6~7nK3g@2}KMWz* z`I%T{2`x9-!|XbMj(;Xr+FtKkVX}WF)`UM3r?>~$zAi!dOuQ#_9$&G~L_0t?pAm#w z(PtSzLdS7!l}(eai6j>SXSOdoFWS=@QR;5-XwjodRHe8Y1yqGmi20Ow)coj`u%c7u zLgyRXPHPRrcWdtkS9sW_>7cILhF)+SN2fpXE07kYF5Hh&@m}AH$NfFK#oXT^kaY@W zuZoGe$MAMvz~g>;tdE@+*L0m1EB`9yz9Hs*1kf8uz4DaVNQu;yonmeWQia9b6NqN` z>k)I?@Ol$}R2<5$I)@aUNc=X?x1p{nD5B8WxvdGo^}SjdkePCSkLK=CON!JLrE7Vg zYwmunjE#q2C{zFR#+3f73a`(fq-U(Lo9rGv<6gW#!(dHLg`TmJ_%m%Co@l*tav`4?U5dQK7kP^<=9mzC-ZI(z`5$0oVjdOF|Qyyh)O(Ku}xi>ldE^3 zSPaaGk)4Dg+AECFM}LHxK1Ls-VPfFi24v5SE{2v>|@!|@=5tPS7NcD_RiAK}l(3_6x% ztIdxPMO9yRJZ5JLeKtQrq&2d*A{>TqffJYtKsV|;sbKWwHlrEQ6rHC7qr_Rnr)QA- zSZ&biBo%;vYip>bTpn1x{-lVTYZ(#uaQ5C*5amk7OEA!_K5em`>M@!x-{2R5?wCiv zMSm|4dO%cSgVY^~D&o21(`&CFGw1#|kxAYi<>{qrZ{*=bN3!0St_Qc|cnxk3mSo2p z2mrN8TUduDO5KvKZ?Ws|QYcH`lBvI|9Lq6^p*BVyPN2dkOk;fU`6kZcfhUk^v@dtz zL-pFqjTR6?u??4WowJ!NtGwe3##TAegYIFVRS8TG!d!!Kim-5Cieh2(`0 z)znqu;bF=&P%{f~4@&j0lyq>_v265fx!;5e1Ou&f10k>ewt-*YH$e=)fCR4pC4q|) zn0S&bBgq5*SjJ2w8Ed*2NW-^w>-cIXk5xDT@i)H0aZ$gcs4J=(7kP-prh9m`-vqAB z1}0jnR(4^id+m(SP}_Z5A^b2oXS=fDJSySAk4E+ z+#;i46G=@m1TZ4fJ(vZu6P&a4FB(7&-C&p#D9Ld=_#afF5;kL!$aY>9gD>F|IdlGj zbBc22ih%&);_OqD^ELSa@!*=A1z?){`GhjcIC8arCLjf#3e=u8${2Ei-wtqAM^R3t z;6Z2^+LetWp?t`XT|^pNvItf5Y`r$ zz>a~%yno{~HR`0Ht3?u15$M^}pH3shtA%}a40ZZV7$Fg=U0`Kc_GvNYm=&YAIUC6! z>kWE}0V_Ur*%n+iti1)QEB#ise3+z}UD;t4_xsVsMI5Y`U?_BLI z4WRk#=jV0ZDBv3HEp{9t+{dE86lupXSxGh*p%UmFEXm>FMub71NXY`KDj1;Q5-C|k zACZy*<5eUGjko)SI#M{m&-l+`$V;M3DWx%5d|uqn^Vf>+x(60h>iVgUP*cOe{vW*Y zoLJ<(pq99zsgV*FWg(5$ge5gZle%cUB7*)0D@7=~5OHw<8*%YoF(k1u-XN2-GAlZp zorGQmb{JJ-jCe#6rtDY$5Npf_P%KF_((LEcPOgDaCwt?IHF3d1mEZ&dD^*{(( zhevc@gpxqCE6xG`ZY8cQHWMfQzsybADPwkG%RU7|Y@W-Oq48c;j3;3a_OEWoBv{?f z+fNgu2r_7;xls94t0Pq1jwU$^bGJ+n_au4rAIzn;4=8*nQY^Z8ls;Zfwvh^_jI7(7 zt@&~tp}-mGDs9Ew;JO^ad9yUp1tH>WtG@sZb-=kLw?1_(O}y3Zbxoj%z6I0Ze6-FW zi5D+3C_+%09D&(s;ym+yFdlW>KTMFoAN5;BA67RzxSmY!r>HkawK*}@axWH2kz&qT zkz&q7kzx-L36bKJ#;ekJtubErzWDlAZjBVLd-LS3+r=rxby$fNZ)I=6Xk(zspGMCm z@RU-JMs*oH63PyNUgXr1oOj)rHk7FKEx8KBvI&++v@_95^9x=Op~IDR@-h`E19Of4G-mRMh* zc?_fAh>PB37j`>OHO$fk%{HX195SosAyU>|X0>R@jF4)DlBs&khbXmkU|X7|=M6lO z*LFJQ?AZQ!@<1UeEg>t)L6OSE9ov4RGz^%;T_vdHND}gBU=O?H88l4mKt5Pu-2JCx zTo_MrGuWyuhY+W_FOa3nFmD-Ftr&ar@R(Jrm#kVbw)!Y_qG8n%eS@0&0&H3XXq~w0 z4OE7z*7pZ(5xnnbjx#W&k^Qz!xwK=)mZ0r(q(FQi$6xo*SW)xKUJ`78Qwh4fuh#6lzXbj7KW@!Cg%QG4BUnJ_;iO}HXsH<=-x!XCL}f} z@q3?F!-|;sn(0mHS?zZ8vgiu^cP5l11TP z+bX7ifcH|e%86AU0xG7z&&e?5TNlKR-oK(T-=YGRW{H*EVn#20Q>jaGj1QFAah6iu z6B9Ge;(ZOJpvv!_i^sRp4d^{qeB5I<>R*x_uRS+jdnO@72)v#^;6v0#1*OMvK-PFQ znFP*4sqy-==^Mx-zH{k&uF~cz6$2MQJ2E6e-W{@LLtSnEG0h2K?K9siq|5~m$Nr@2 z=bsDip|{q__94S7`!SS)0ig#va*DCO0q!1q(B;D01rD{BhVZC7B-+0TiULo&>tq7) zbNKRrlkBC(cq6AEnSps_$RGv82Pae|c+6h;8Z|u~9A@_n;NfE2j%hFL5$&^-utBIP zNEI*RSUm5^_?v1XO4&UZ;+XUsrIq%gpg0EIiQGN$TrB>k8Y_{CFyQr0!B@Pd-guh+ z`1?ZB#r-62c6|aG1%pH|_8684q7PpKe?cI3D7c5HcI0-jqn3oSXW{R=7+~kHRuXex z*Or)-J}^R6bxdiqLRuhre+&;ET93~)Xi8;2{x0M1^X2j@h#Xvthh77~5QYh#!T9`` z1uKjr1arBz%BnU{Q?A8dtr?bW4+8VHL8!zxDDX+c(!MMLWH6Fx{L)YdN9Ts|iGjBU zR$~sr0O4bJ%}E51!R2h*b`%3{;o~Up>oC3B=RJ=QnvHnWIHlIybg7XB;I3}4l-3qz zsW9sgb%%RWle^SaR>+@`a7)?c#*1b#@IDd(5wDfZuxuSx0`z4EDqau<;t-#f-BkWf zUHD#gVe>>W*9b*3D6W&owQaTCxtYj7=JhqjL~F|~R`vGom-A0#aLBdlc!5(@`3zHKiEa z4x>a!P^QCuS_W0Z!R`KI`H={c0LGFNsuYU&>_C|9s=InpAH@?dT<7| zL)tzQ%R`he6Ukqvvs3}6b!FpML zYuRNL_U#79Ul-UN9ERr1p(!l5gtVKG1MLc-o6n0iJ^8Dw;vfj19RygSIc-y;- zwu9lm+;$Ay|L@wp1iKv6bZj#L`CiOXYcQ47Fit zAxN3xLG#3KB*~>vdyBf4C{feq1%qwLG7Fj~&e5?NUObG)miIODL}!wGMv0m?rw8}z zBO@b9n|Y{fcE>Lo@lQI9wesqAntx}6lui@EB&Qm%uRITyA86VO?LUK|IHL~RNLaCE zdfC0SeKr7NI_)p9_4uk%Q;hX?xw3v3R{deG2c#f#-E%xGRw#i%IWylqEKOsx0HW;# zmPv7Cq^WiAPDH)5@=->5wtT4IW)p6&RGv z+No%=<9J~?H^Xe8-L6Nc~$XAT!E%S6)e5btAsjiqErN>Z&AJ}fDxXw~U~v(jwka?&=7 zaye)F)$A2mPvbn>40FCCq{aFsL$ht2f?zeiz`3#D4@}B~lBs2tzWo|9KZ^(3{8kV9 zXb#e?f;Gs7lu^5;>;_51gKvm0n@g1*;(JT$^y26-&7IkJX`XBW_EAgYr93$WU=#*y zpcx0w%Cj0T&6lkHiL2G>^ytm4DFs_4YeA)C_FJR;xOJ`l3GEHl{Z6^ZulseiteZt{1mRZoYpWo~2Gp{1t!29Q5Mc+cxw?mTqpN$x zgJB?ghgJ>Uo+&+M$toT>uJp~1UZc6$95Mk)Qn2u+02W-mC0XgqR>H^0dRE4qW$ByN zC?~9H^#x}`fBoDo7N>ilehwb;6aZwKb5&3MbU@3_Z5FjMyK=&eq@e$e(QAC*`EFf) zhxL9{5R%rR>o(K#x+kXfm3Is!?f@dUFjWN*(G}-V=uY)Yx!RkRX&gm2YnRLVM4U zL&R^3pTW?9ZO2$?gYo3lx=!$SGzrGQ`?xVMo!i)|``$zyerw$`lF81lg2j{e)?+65 zhpZJyV$eaD_7#KbtnUWno9#qIw2%GtRZBfrTd9A(}*XX&wMafgk$_#$i~SF@frgCXc=rJd9+MmBo+$2*OaZ zu*Z}_Cw!0+BBhjx{S-C} zW38%6&yYX{HAPu&)}vQ@*%nxytNPlJONk|u9A*VMNaqN-*u`4}q0PpHLW9kO#ykU> zjCK>F?JEr2Y9#U7>O#~h4Y~@Mk2M1$Ld|Y{CMwZk?0LtS-)l~ z*XNHlA95VcPjA=Ovv@j3h;^VRjCl2fAEI#~xAth!H{Kn<7&hOJVb>%m?GO#Hog`IlkZVK)OF3=kNUR|DM$1OxL?x*9l# zuo~#0aPS;G_jJ?q>38UPpo^Y|$?{&iYfp^7g8lsUbSHlWj`7!XA^!TW*YJAk(ZB#+ zn%k@f7y>~GTtFbgt2AMasJVvKKrc@ObOw;)VQ8OR4{Kl^N8BmSW;q@bSBhyuaZ$<=y~LDsQu!JraO zIzk@$$Bv_R>LdSEY|o1{o+XRlQuXFny?)b?tIR?OJ_T$O4HzyFpgYx2mE2zFWhbZ) zwBG;DvLW*NWeN=E-&;W#@OHc8Xe8uMV- zE;T@ZR6ZC{Q&bdHY*TtZK?Kdh#kODAP=I_R3!u45DBC$8+1LX->~apslYDFgp#V~) zdfC<`2o4q7$ZjkBP{R^wa^4$inJu`4Ch_9TQq1Ck>KjAPW=wT5(+GaS^0ZuKy6l^S@F;s?~HiT~69F(9fggnl`VVqhf_YkO$q1kQ-f#rSH)rWyt) zq0^}b`4A1z08<0|@od@i34b2Kvl%%)28(H&5H5orf#YJ!`v3-)^b}NX5yc~I;*my@ zZc2|BO#-zJQ(@wf*CM$9Y7v!xYn+1N7)BvQE3s7Z;Vmdd&j~zrhd^!&K_a9MT3(WbW>@mG!tJ2x?*4^5|LKJGxmx6%N+l@j5$s@ zVTukkooJ+S!juz9(Z4iax>3GKOI0G~M2}Pb=r8pIPj4RT9^d(W2LQb&nTJ$10e%Vqasn=NEH|~=v&8&rL5zM4bo1Un*$XxM+iHa{*unV36k26ZXE3`8&Ih%xy;gR-xb) zIZHcCJkq$sv;e#xQ9?<`2g>vvLAnCRxcILp;{T%WK-+#o@$1Cq7cc=Ad{=D#8NI(R zHa|&kS#17ydT$k*Tj^aXHa~0R2O~(^6jmtN!AV~HSxaG<%(S5Q+Oi{@FOfqqhKR6RZty3`nv05n!l^O2lf20LLII>H8Ic@|4C)-;uorl#KB~Y4n;WIu4^#e4EVTkAls5Xo~Dk#Wvz`(Jv`#%yo5A@Q@aMNr08=56Zvy{V> zUXU~61wrrc9hbJMs_`&QE#Hx|plXdv)N^H`+vbUZTyzzB0_`h~kB;ep7)_y`@~1|# z6t+oh{u4Ah@N4srsBc-a7`P94{9iGM4k`q)#Rj6yH47R(Z6!B=uaC9>9e$+~Ui6Gb$S|=8;7H!3_HbSs0=g5xC zZD!}GO;d;7pEfe|Cj)r{cl7sebZU||VhrWLnFlP6GfSfB%3p>Kjd7c^YkLwLdcu<; za*BF@@CwT3wYH^(<{Sv^NTE1svBvrJiMu_%a<(5fA|*UueYzRRRjxE^mz0b7+f$N* zF9Kv#*fM#!#zj(ezsBdnpc^uv*w6uh9ojG50o9UFhiSM&oY8?6qQpX!hoCgUp!2-wHMCHVf8|AOvhvvlw+imi-S4eW7Kbs{1StA7mj(&iYsvy^4%8gk9GKu=v!z@S$ zWgAupX(kyOz;NRx6Q6%Rdl@y8MtPV73JRslr3NgWAJ9&f8pIS|hT%EM<4*~~`6x(4 zM)}Y1^54(rxuFiNMU(KuhC=A@h%-xyo@&UxZt9_CITo zmyri1&qIj<$G6T#d!#Ru=5HV*+N1HZG_K5{Q!_m5`lzluLRE%%NJP^N+G_s?Z7+}s zeN_uL9)1e3@ONGfZVx_=FgKIXYKVRHt7rxmL(BuL;)b>v@E#-MaO6#=VE6J3Tl;YaET4$O8Fs-tvBgQ&08mHNv&np7OS2F6IPVmmhKjh zz$aAy490*eX#6tVHSCHN4oZ0I@S=$?ivok&uZ5pdI_c}nX`%WQrY}tL%I&&@*<{Dx z;yOQ;P?<<)*HTn>=3ohGheMxLkSA(o=}`Agrs#6z26)s~+u-2n(%k7D;Bc2uJcu>! zohT9zl&ZU}$|5Y9mD_HVr+Iw-+u6L)xWL&RCzRV@Vu5K;P2p<|)&&n&^l-`{>EBHD zb|qxvXfv{s!?s$kT3I%F42BYh2}MxnV|~J&O61vSh@q$5eoHBu5xz5gb>CCKPY8>-G=nl?RrLwom`Ul8J1;nPgo1L zD|6_J8wbevjG1?azsGT=a%j-$wrvvGCX|=32uI7sUvm?RsThvUFjHrE{nmtioEx4y zArfv>7L(N(^S0M$7nkNVPh$#FH9f5eiqS#dKXP!7A)(?n{9N- zP3ibYIXQjTHDh4`Q%1&aGz`hFs(T6mT^`mm9y1^oUQ~R|PK*&od#VVSu?s0qdVTuB zjcti}Oj|e?<->eFC}pA(r8NB(_VM440SB<;kB!(0FFOm6wlEh-9cR^P*VTp5%aR3O)4zp9X)%SzB{Z@9K>`D|^Nvr#Ie^y-&*(5)n1^vXz zen+u}Z8q~~a0U{akE1OS3mIxbYXQDuKPy03X`pj5PXS^uthSJhP5Qf7CRe|MoexQ0 zxB+wlAf{ILstrAA!#U*>GoH@N_2ePQxhFqW`Uu}8@Lzsc8%RLaRQ=s6OI6+7qve%# z=a==$mV9@Q^eeTjS9>27(($)g^r^ZKb=`jIy5B-;s;a8%B)~BOyubkoLvl6{R~le? z{%XX++lgeWQ5nl~`FGLEG6BP^jIX%ub`DApA{I20o6_2Z(*0ve-i; zlBd@Vqbzna9tOL91)-{{@#1nngaWy$#;&S|?*W&HF98&{0u6)AV^$#I0H2o~!HCsj zRpc7}0OBi9^U^pPVzUSc0QqrL(&DIy&4Z}AX@u|*n+uVs&XWalq+@MSR|#a$V^$O9s~GC09_zX z!RCbq;7tH<3gso_3)EDsT9}XsaUtR}PUAvq z)Gp3`8l|q)inrpcGCxyZsqJi}`Y~hSYnq3tAAsMC?#g=JpMI-7e+K;Bk%>)_qKbSva;3jZ)^t&NBt_q}x6xQ|xe?W2j&?Mu<^4mp!RofodlnJW4GJ?$ z*C;Ganp`U3=v{UD-t3tqS@&icuT0~W&R;-L>9+^VF!8Xxe*zkFo+3q&Iz2WbPmNgU zlWNg3Uc%sy&Q)SxTnXM!;0z@;jLFtLFqQ#+uZ<1Ed?Po;S186N4HS8+*H>pknK=Hw zDHDSIVbEE95U8pT;*h>g{cRRR?JJZb_@M2Vzx?G>Ov zzt9@^7^#CndUgZ|oE^PRJXmhRMnyEu8QGN9VWiH6N89F4um){4HHYLsRG|1^U>LbP zKDoMM>`?D++0T0 zJa3XFH!hoewY{}DZ5U-o?awDk83f5D2uf>do=l{QrnWrA1BK4F>ci10|4)NIBDi*< zGOrDLaVRVKbTUG{2w`_giCw*AA}={um>r#_947eHTP6q1lN(E~&JGs#v?N87TCRbi z4G~6JRP?JfHPkrXT+N=j2Bo9JF#@w`1U{CD?jFQoVYkEBs>R|%aK%O`D}T!d9ADW| z7ax3+;P*s>@8`(T?oVT-u%K0`@-R{$yOZn1(gKW|Oe|_?QlUXZ3_^qEcW05AE7WR9 zoyOB56BaC#@QQKzZ!}KR*h=i_L;thaxd_XTuR>3}rL+GaBO;Wz9#%j)$EG?`htAM= zg$Q&Oo5kijP_Hf<-N*ho9VKYpfwN-sDga+0X{JFH+gPVvKK~rr?0^dvv?|0wUSJ2A z&b9?oiTX%YTBp20t(YQbAl!73H)LWtvr$8kK&`AZu!pxq&!B5#k{I{|6%1NPf|HVeNOzd`;Q*>#yTiJ#h29FW*uKXpcnXT5a?#RYuhoj~vel~QvRwcdMj4N3 zx=7=#A+5FO>dcm=t^dYjK)a?98Ym55v1^HAT6Q-6yUAW0{VOLjj3dC^Do^8Ii;Z5u z`sepVshPBbi6egn>2HQ>A8>x3aBh#z#&)B8ZPR5Va|N49nc40ETH=DV0_2~rMcCsA zlbC})-1xx_(!zs)-2(Snt-A`&J(J;Ag%3C-^!)<(`jGi8Y;%?M=0E;C@DZCC$}Chu z^8s2+W552xrpxRL(hfWD)pWU!hhIfle7W7DXS@h;L2}}GK!R=thq?@sAOv~{ATG#o zFdA2Tgup$tUrWlQdV~mnM}9TiyrQw;W90l;n$=orYCbMqBOW|09<)YNXn@f*5Ss^K z`iJ#S{!_5{npa3WXtY{gcghzb3fT1+V04~vCzYqxSfk1C^KyiO+et9?y@tg3i%CRF zlf3LFNZa>ofM~<{g)5PpO{{&)cAvXU>cv9r|o(ZAK!;2kD@XlM(}P)uvwjoRQ;RT=%B){d0n7|^knqXi!J+u1bSFyl_e zOy-B%R;;D^Vu$;ZP!*l%INnkn>u_HbaNdGpt-8@nb_*CUVmR^xfQNmTE97*<-M+|u z0j@~y0p;F}Utmp{F23v@p6#|ZHb51Di_!qiY}`*0&PMmjkRdO?NW_gcVl#E6vONd( zR(*30%YP3oRkqLNpL5xb#^(b5xq!_uJ`4C~0kavOF8=9aU%bon7V*y__ObC<%0Ell zpXjq``x{lUf#(; zHo&Mmwe1_Azs&YAaS#cei@952dXvue6d3cMD8d8a!ni`NMJ_K}O69T-;LZeRK@bGk z{Ee__r?8Ek>9DsNvG2#n{8V94J|G$*BL6opORT260DG-1lh*FCNUoeV>3B zDl>ea$n!}}iB9mc2Y-i39D}IgHH`kXR2_P}g?juD{78U$q?mVrQfq}`Q=)E9SGRBU z-%(ks?mUDN@uE8lBE@wi=#>9F1XYbB_jid=c@GuWX>XAqHy}&}v2P;-w8y$j zURZu+!VzL0bp{!ArN4L+6gwb}Qfyv=Vr59nht~}97CVn_xsqZK`!(&%%!{vSAMIjv z?e8XGOr&v-wW_{nuIE-BrGM_2OviW)mc2u28~5~ppEV4;5HlJ{L{W6y;))ECQd2&zs~Jv^QY0y0M{`W7Ctsrrp41*%&sk z67j=^q*;)a2a7}Fpf1kiTj8N?pVUcy+VTW^n}61coE){~X&2eVv(|E>Dv2tohc02ahI_RBzI$DA-4j#fGoUQ_}p6)w+ z_Vh=myC)r&FASa62B-}Z=|=GNSF_{e$6H6kf~kC4VjqPQ z!-97AStat)IQaG~8W4~>3~UYa7q&Sp?8!<&IQ!@7_Cp6>5bP1lG3pw|^HklEXgj=DGi_NqW)5`gZ+k&8S$s*g7 zZ$jXNTz!Moo=YY;t7G=>!v`5pwVHd?;(L_`%vM-K0rTg;9giuG;}pz9veFrhrYe({+@i;DBw(K^DsKiN#2vR0`{+~>mm+HgWU2@ zVi#tD3817^5BpvI?6p32dLqd)cwCj8!*0n8{|E_>I`Xz;FL*&#>{@}StD%DJBOf?* z@j9%%E#wK|?A&y7EgkHbs7%n+Dr@66a~fLdH6y^XvXW~S)YEeto0wwH1;d{9U zT}RNp3z}soCX!mE;RsaEo2XyiAyO)HD2Owlz5ME!Zul&@dkz^jZL<)Dy^g_RRqo19 zBODsC{VpGyIv#y7Kt?583WaE-)-J0J@AyYnYwm7sRgd$c7<`?gzfShR)z0&huT{W0 zvix}~RA)US1e}lzaKp!SOuXnx zYB!4R6R;{nlN>tgQ1oOm_%bzVi11v<`$s;f+@?!YvHLSwJW_17H3HebT}aeXY;J;s zgT+5s8J&nj-sIM+gg!@akfoHgSh!_YiMwRO1IpqFM(+3>)QKBn4iJYJ( z@DJ-h(86O$&?0(`ks1lqYxjo2yucLPO{iAdOZpb09biK4(hZN`mtciz2YVicJ){cS z%n@n}w|m|ie3-L9Y}54^w#p7Nt3VYwM!hvziMX1=6df$N;0)J)fDN)YPhw8E0g6S3 zxoPD2UzqIM4jFq%<>d)Ol7;=^@8nnMkXzFs3>$t0uZvq8*k&^cCh5g#ZvI3JZ+8*jT_#!(W8%Ev;*TIc@j0gEowlcB*{T2oq5OIlNkTii4F z5}{!wsEiV9~Qz;^iQzUZVoQMrtBgVg6xzo(%2(MyaTJuS zT#rrx#$zT&3)=x71uwkU&^=gCL!G{g#Nm(7)`G>7sl>~VR25ex4-j&4G+1Ktn>}nB zMga^Si)nim%Azj4VH8mTN=diDj*O*V<86zpf|Vxeda{(=g$!yc*DGD#3J?4AZa$2l zs+Pj}Cz&WLcN%4Q*++2LR^|{&g7OtifDy~qHp5a`g&qEOo$m#+V>}gMK#SriOhJaX z_w+NyZiUjHuB^WR<8aKd8G3z3mw)K`?Ga2nx-%lB1v;b&LtXn8U?zyx!e0bZp_@jA zJLZ7X3GV;lMH{>}zQtb74fWcG90|e3Sw|ZDURB>(}k!~akU^gBEKamRbolwD^?4$+GS=81; zwY5hl#Dk8|>YBCjvADMf63k&Cbfr`%pL$nyd$m5N5;7n z?4L!i9F6WD7flEC5(RihQw)rzz^;Bm0p_*vlYM$dKazrShBpE@HXDcr1|OKScO`hk zF=${8VHvc|y>4utxl8h}sIV*gcEnU@1z}7CuJLSltDHeEPda zF?GWA_}WJl83kE6h{!MsO6MSI`Y0%ygQ&TqpaKq}_Kkv;anObFpnEweHXgKHmE%OdzF_KSF`tZ}L8 zDmf^7JV@f8objN?I4E~K=y?vBJ05h5gXWJ1b#u_7@gT-Q3&w+D98@qKWX+)lxyFMs zIjCqnXaNV6jt7-;(6aHMN)Gaj2W{XWV!#A(_EqAeZX3Z9pt`4csx{+Mt=)GozPJYn zjkJt`#4zAr7x0Bq9!mhpZ-C*0NA@P5UY}!-){6Yx>wlfa!ULD9VLwWqlW*CNd4BUu zFL%po>R`#3I-CnRFd6%JP!HwTjoXbdvLP+B#T4flL1@mysQ#4ijg2u z($MBaDW@RN+Hu(sEq;Jb92tKZO%60I$T#9VvosE&NhmB)%#{eW8wf!&+6{M&qx6VQ z8s`P#9IF2mvLEq}Q#?KXS^T&KZ=L-+5jCk?}!m zaFgA!m?UV#P5bWTY8@NFZuSau@+pUHK3h)<09=#3!e)Hat^$lAgD!Ke7xb6O4N& z+@_Q{oz&EJC!coZr1R~4O<(}tU)+$fEC*L#NIS%XFiME8&S|6zfi|U)LB*$S%dwt+ zAzDr8jLRyvO-7RaPt$J9L$15%%DIcmC3F4FL+>jeBulou(=G7nHYt53c~I*N_gIs| z^s?jihVtj+a9@&?a{ia7ZlaOyBT9#Q*S6znZr^(hsCxbBHJGGRxj!=Q2J2`@)jIZ3 z45?We*q7QzD+^MbZi87opZ)Zu%p_eTt2Pd+P{MRz*LJO&Uwk1R=7X`6AIYi~~K@G*67wY`9{`#ho z$5GyvYqXBMFddT$;WYkEm|mKe+k{4p4=lQH*&c49goH9y?chNrmfkR(CtZ!CV5_R8 zQl6Y#N^RJWjA!671nG_1!u8iJ=9OhO-D}f#z(aYo#_d>?V&!k-bR~o#lzJ-eVtT{0 zc#dEp&@2DviD|zcw=AT>j2(BRJrhCm=^{SOWhgW#5GTUqH1=nhCXM5M(M50p&T;a^ z_oggu?DUsr<_l=?NRid7^gu&l|23M4ZAHo4OkuAZATvcRdXCH!y&$bJGJ*qz%a9oN z13WOAr|%&68i#mWevG$sAuaYrMI&DSWB9T~8&UptUHETUXg*DANYuIrwVLFK+={AX z3sJw9rD8-Gre`D7AQHhuYA9A-R)fMYS-_`kIx~&d%i3V;L;=_)#bMZliEScP9Es)v zU#+3n%f12@g16X@kQP|C<7JSCJ<`Ex$S<)Z<~cNQ4UBV}R|tmsZJcd=uIR7i^NkDX z%51ncUJWe5Hx?dha6SU+0T-V6vYnsdPQ$tv%cASpji_YSeCFeI(V%D78+G-4L@UrP zjJiwllZ@(~T$E6urSIX!f?y85TGvd;Njlqgx$$xmT_UJ%bDAxo0k(`DJ!-XA?{~T7W)ralsy$Y!3F`m>63GvYOa3k>5^v)1c!u(FzeVM(CWQQ^cs3kaAR@&VQXF$4 z@g5X_OTsxB%MB7>8{$H|kK$d*JLTDUr!1rSoAay|B*squ)SyE?XB~0Zoz!WEsiUR4 zi~@r^2Al+B+!s3B7t;Pk@igZvhpAU_Z`%;+(gRdWvBrCs+i}6p#M4Q#LwwolI8*Bk zQm-1_FFw|W-Dh-V%ukIMUp zRbQEEMX`aA#!EMd?_6aUANmCbMxUFg^E3^L;?^W>4-G}l#)Vc((ZmID`4uTjT7+~$ zAN>k|vB!stLncyIV>}s0leGY4AB2R(c#?@R46esnDq7tIU;QB*}KBXG+V!=Q*(xPwSB1DjX(X-RQeaQzXdH!K~ZkukDueBu*6dx)? z8jZKkU@p3Z`ExK7Imy0AtZG?}yQBk;BghKg8WqD|oI?L+_H_WPy#dY;10R9Bkg4L% zZGeppd*wM|OdOvqlh<`#^PsSAcH{hIpJv{lep_s=#WM? z;etBO0(osfSA6JepjO}86blyMLzq~g6+H3f76(dEmc|EG-Wx`nohLRq#g}hIb8)Yv z%A;zX2Y9=u`qS3dk|{FD$iiDbpIVNyx|g1ZV66{327|$;us!AV)~!ktgz{jJs>loT z8z4Pe*yF7u=MzKXjBl$UN~y&HT1=-bUC8Jc^1{JA)Z)A0p-Tlrr{ojM|H@O+wHnWw z9HeZ97%~cThIjlrdQE(2@ig$!;zG|DJI=89=#!{i<5a`_Lk3wtGYIcIFFte(WbNC6 zByz~n zIg?#D!Lze$ULx%8Lf>ILFnn5`#@oraDntd_UeIr#&|-%``;+pQ>%xD5Zk5pJGD)|R zHu~6sI}#cdk{Qv1MVU~l=sFKWukx|)pe$$y*i8L>G=u#d2*h=xIs+H&kA!3OxrA;7 zRuQzfqj|ttt3Id6-9FY?#MP@?ii+);ef62)7x0m}q_Dy7}fW z=pvt0aQurK33ba$uoQTY&_P;w?SF!-(3I6ea)6zn+-b9_Kgf(uLBJd=Ob0kpmM=B&>;-fr4*qOYVPKhz)`ND*;B&D5j>MN$_co!C`i{+0*uAiG`={5a^V!_r zLI)VW7Uu8GPMlE@QT`;Kw}K^sVW3p8=_n~8 z+=wJ>5`xgYO_gosUS9>Ym$LM7FTV_#tkD`y zqDgif;E|s+@;s+nqk9b&BRg#KcyujE^QE{+c<>gx{3 z9&97QYzzC+LE5!9j@GCwUNwaLnM zGxp-?$4e+7zh#(5{}~1flTsM8265| z`B`5O7V;W@Cfm?YBZ|DAL{^8D!`UzU8 zHTjhDV*SJ=N+{R)c0G&}u=V`IfF@oTsq=uCh9z$=&=x%SZHO`RT@2>CQCl7CcxW*t zs>7e1ZNt;BbFBov^9Y7Z6e#9y5EAw-u=Y1JR}OwIY^V!TK2EOj7C&R7l79UPie%Fw z2$2w$YB4WhH5cknpGcbk4p9w<`c7Ms31OMxd#A)eKw1!SV=-?@SlmWwLHX3^6 z5r#>CVDiXAYWV5(vfm>$pGDyD#1FS6j%MO)8dXO-U^wmuyC^QKf9N5~eHl9L3bS(2 zT))}FPLppIF3L7nIR`eC7;X#$o07B+Y#JwbI6LaoaN*=%`lvA&gXzIyoPn&r4Y0T3 zFzM#7p5zH;9U6Di5+mOD3f^T_lgr~VgbupU@CQlk9g}dNTh4~MtN1UwKpn8w?IwaG zgM#dT;AN?~=mgMoPLr-Eu7z`r>o``32Ar(h+bF~(%04@eZ^pTMUpm6r;aZrDw{g)_ zA|?}%eOdINxP3Wzpz55u{Zw@e+NP|32b+#v0$F)_$d93$n|dbg@ZeU)4u4WrURb&w ze^&g})n0l;YxFH^ysR8xoXh5}xtb95V$Now zbc@1Lq}ip?RCWvQ?2KD6Oqf`sFQE)VaxXoi*Wior-b;_D4PS)&UV1pr-T_=aMnhHi zIa--FpGB9W=TdR>&IEG{Mlf9q_ZT_#5=E5}t29v=nMBvAnQ=``$-THZQTfij6d~WP zm8?_UU6GP?)@1e9V8s@R{ZK;S|@O#86>~nET!ESwkd74WVg-PRsZpQ$8E`FHs|S06A*`; z{5E35Q48n3xgcPC3k32U6X&$V&n~R82hPaXI6}CoggqHf%;L2)ad*%Od2IL6e1d!G zlkSx1TE}-U3D#J@S+ zs#4fZqg7r0Z>kD4`LvO|i?~z)MT>CH=0)QNq9AsG;h!keB^ZEF_HjdM)oNC(Zfa5S z=Xq}H=~$^@pIwy>ZO@A=xKC0}%P+IZH$ZD~0P|~Meg(c)Ar9jVPTh)pafIDQ|He7Jp zgP$P9KxWMM0aoGe{``dnC^dfell*wRb?I|RqRc1e=J&=Xlq8=R@MC;q1$ku(+%W`j z-CShDu08Em(`xZ{!0U#6xffA1hDVPyy-7=E zEGS3U5)>F6Wnwc~P;hCV(=r!YpoG(tr9X$9(J-Z1=Eoto7?5=I;gUQU1HNKs+4x&xX8zvFhM%PtZ(|qmCKL`fg4@`K1T~H*pXI?8f_CvB&8h5l9waAU z_9_pOYbg6Q4?a%8XL;}`3O>Pu&rt9Y9(O!7d&gpy2B~NE^-URUV8{@Yg&zOu=V)kWM?XCwPz!|FcIBAP6^B{R)Gd~ZeQ*bR0W>Rn^4`xyDP9Dsr;B7oep1sV$gSiyU<-xfWoXLapDL9n} z7f>*j2g&lyhJQxwFQDM3Jm{j}hdfwB!LtZ*luPOBO&&oz53G#`JrsPI2Uk+?MINlA z;9eeFL%|>M;Jp;o5XALi#`r5QADh(Z>_esxm;20uDM35Mubr~GND07cK-%^#b#??d znzrG`$F#B>cnd-az(j~2#er8sr|Qmeg!0|Fv{8l°-{p`iJ7R490$$UjaK9$cJb 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 + \ No newline at end of file diff --git a/Core Includes/frequencies.xml b/Core Includes/frequencies.xml new file mode 100644 index 0000000..cbdc913 --- /dev/null +++ b/Core Includes/frequencies.xml @@ -0,0 +1,57 @@ + + + + true + Santa Ana + CHP + 39440000 + WFM + 0 + 10 + + + true + NPR Radio + FM Radio + 89300000 + WFM + 0 + 75330 + + + true + KFI AM + Misc + 115840000 + AM + 0 + 11130 + + + true + Air + CHP + 122850000 + AM + 0 + 4240 + + + true + NOAA - Oxnard + Weather + 162550000 + NFM + 0 + 24390 + + + true + Conv. Center Security + Anaheim + 453225000 + NFM + 0 + 5000 + + \ No newline at end of file diff --git a/Core Includes/hackrf.dll b/Core Includes/hackrf.dll new file mode 100644 index 0000000000000000000000000000000000000000..1eafa51e65a203bbc95c662e902444c6dbcb7e48 GIT binary patch literal 79360 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

qsgt%(QYY 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 literal 0 HcmV?d00001 diff --git a/Core Includes/install-rtlsdr.bat b/Core Includes/install-rtlsdr.bat new file mode 100644 index 0000000..039c1e0 --- /dev/null +++ b/Core Includes/install-rtlsdr.bat @@ -0,0 +1,17 @@ +@echo off + +mkdir tmp + +echo Downloading RTLSDR Driver +httpget http://osmocom.org/attachments/download/2242/RelWithDebInfo.zip tmp\RelWithDebInfo.zip + +echo Downloading Zadig +set zadig_exe=zadig.exe +ver | findstr /l "5.1." > NUL +if %errorlevel% equ 0 set zadig_exe=zadig_xp.exe +httpget http://zadig.akeo.ie/downloads/%zadig_exe% %zadig_exe% + +unzip -o tmp\RelWithDebInfo.zip -d tmp +move tmp\rtl-sdr-release\x32\rtlsdr.dll . + +rmdir tmp /S /Q \ No newline at end of file diff --git a/Core Includes/inverted_frequencies.xml b/Core Includes/inverted_frequencies.xml new file mode 100644 index 0000000..71de7e8 --- /dev/null +++ b/Core Includes/inverted_frequencies.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Core Includes/libusb-1.0.dll b/Core Includes/libusb-1.0.dll new file mode 100644 index 0000000000000000000000000000000000000000..2f98c8cd36e626aa5e8ccf0e8aa4e6d7a816f869 GIT binary patch literal 97280 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⩔DpdtvH=ViIhQ6;N7n9uuZGX-{^=jBggqYMG5 zhW2s7)DQ}BH+Hi%thZKZ4$lz=As3RK8ZW%ysK^GfEPeI$p32JljW4{s z!5;f4{w~&tr!iyVolY}9g+TO)P4^116Lu!<_M@vjFy^_S^u8ITonV~9o^zj{# zg;%rsbgjXnHCVL<8^4ky8QeS;Y3QMv1YsZua^a0D_6_aU4DHr*?ba-w7E4I#9dC6N z`v68M$MEjhh(ps3!@2^JkMk{P<*)OLC}2WE1~!uBePLj#x$-YjFE zQ$!aKCEOJM87>}aOQ?Ka`XcaJOkNy&pe0@i!J;_4qjq82L_bQ}az5+Hj=(Zb4ddy8 zC$L*@TVat}!IZEkb7w+?i5(dsJB{Em+t%44so2=NEH!QAA~`(pArk6{@MiOvRnHZJia%5h?+CcYJALDBb8jIHVxH zm(;{~v$?`1?-|BvTKn?cx&8$(Kw528&Vx#gweA3GK}v2|%cyx<^c{$f$qld8{_&o|0ChIeBn9O^h7ZgEX(d~KIg_wB@fsnAGDw+$J z!A_G@GS47|C51a%4sSbw`%}Zz7KhHPdII?DR#Obm$$-Ev(;w48b~5)7oDi$1A)lJp{31i0c7n?%b}H}Ck1 zc(Bmyo6R4Ew`L@f#zca$5EtO`YQ?&o=u5^0IG>>&D{e8=^GdH6q43>=GGga+sOdbF z+p5tI;Wu@lN_}t|`-9YH`P<|g3jo~*00>}9jGATH<7W-?wzX4TI$y(pH zzLk9%kC{h}@L?dxb{{@&(Wk7hwcxjdAf;#T>`nEbdk5^lbARtt6V)s3?>!9fSKQwl z11{(bO1#62PY!;o@QdHM`_lV+l=}bJ{XJ1`ysXJvZh!CoUaaihsNxCy_Td-CuMfX| z{Ep%m#SeY+zv2EKRmL=vg8s%Y1HWASCi~-m?(hBIb$_q2@~q;Jw%qB}fst(sVaCl~ zy#{J_#av8^Rvej->{{;Z2{jm660jeuu)~@gidG1!443vzxL)G2JHiF7EP59OLX%D2 z84j6#M_UjNEGt$CSp-@YWTHo-ZbihlYF)1Rm|i2k&Ui3XV#Y&NSHVI$WOA92Q9O>n zWfmWRff758Q}qjajfW0F&c_yd#*+}IgkAEqUL#2rYB#A-qKWw6L5X9^k6~&8G{^|e zuGc?#aOxiuNaBbKMvoT$5l-I8x-p%ew}2*38g*GE6Z9}StRji(Im~E3CxgCG?z@c*_fAa zqm#lazJ(mt8@geLw%PO~0)L$3cN|%eKs-dYpCr`3`!*ySe-@0Ks1#A+REfyLU&0nw zJz)Q`Bl0PX#40j`RQGuX$*3j{$%LkpxC0IPJcE#AP2BMVkZap@ZD(++bo&-ia^55* z*H5KnA1*HmN*+2($&I~?2{{5guNiC*gEIphInC6Z*lU=-FN#TW(HG^|F$ zJUoDUVgCdJDAI6176tFb)O2{3)NU+H@L!Egbe^UZRI@9yx8cZX+a=Xnvl&++QACZ0 zUxY4$Fz@Wep@`ek9==^x2R_5ImCGz7f&v{JJ=;cce&aM)Cc*NE zV>C|JARA|ou7mnSg(R(@#9=VJG%8;XvPejya~mDezf5; zbS=kUW#VbjW6@@2^$~DH5rLq>!iLnq&(LYwl_<_ z-mELP5NeH-9QvkZ(RaR`zDqLcTa!GQES`<&O>Bjpn%;BSMUh>F2=ylB;!6m_7)iv^yH3S19}aD9 z3QN7Mr3h1h>tQAiJ%Y;<#}JMT;A$dWbD?m3x(Vbtgx-h^L!F)F_79Mm9?4D2AZ;;r zn!orDPzR4xIukQvko$Fr&6#MALGIEa>CVKg7(~$_8P3F<800%TB-5Fg8-sXsh#j_2 zG02rVB;T1>9)slQkV0qT@)+cN9a8K}^u!=$9a8E{Tor?iJT7o9cP6fhK~Ct9<<7)) zF~|{u=z~yiyHdlFoQXn7j%NQ>&tP&U+F}`Y=@7FsF+B#kSBK;}6N_VztvV#nnOGWw z+(eM6)yVBPgU9HU--9TOZC);13ojO~mFElB#&d<6&a=qbNT6CQn7jbW8r4-LE+}}cZ6HW-+~LvBdxiZzbZhbyhpg@`~~4I=X-?f;r}Vz zRs2!muHiow?mGUj!rjR45$+~_mvHO(HsNmO&BATqHw#zcb;7-k*9y0Vd*Koads@M5 zyquu=u|tvYl6st9F1&Y>_v^w-`Y@g$ymW@ZX9_Q!9q=UK73TqGenEvjM9^X3eVDv| z7T(?D{e$rCBkya%`y6=>2yd9YPYdq>^8Tmr_K~*>UV-u<3hfjTbmfqD3hx`_-7dUG z$*TzOaq`|MyaVK|6<*S(@G9ZucgNS-YCP}6U(n}Yj@^@umE-;(55FVy`Bvu1x}JIL*K-?)4wLjRsPpNN0(V(fdteHm zi%MemTViJuo=~aXq~BaYsw_I2pi>D=S&BcUm4l-`C;lKw^TjxoV3yzFeRB&POSJqJ z=Mr=DbBWU5n)x-TnvrJ%Jkh;`cI*mF>|nwX-h|U0{A;`2L^!}e6MvTBdP_m2*`Fwm zD!QvGpKZYO6rBPpX=n)NknaRQqi>WV#x?6(VAM!RN*Qj&emv zwLbxw;OFs`Ul_yp@>Jl^4Iu$2WRS_b95BD6&t4!co;G{8qjk6G^W`^5Gy|Y{!PC<7aT4;@-Th{tNu#az4yK z*xTxR3nK4Lkr$1S7Y#~dHFr|8$$Al~bZK&=)QD>a zRD*<_&VPiF3_~KCj&wZeG0(Ht0wDe2T0nFm5XPxnHD6A}b&KgpPtJe%8*qG|#@~5~ zPV%hv`>3J!B0v`Gkgs68KH;CkFQt0Y`MSw^2KP{V@ki}`MD1NdFC54!qw4+?Ig`jH z)W0l<`~{8u3Ehl`aGXz#^-t&TW8A5kQqq1X8f6N`X_|(csgRA0ZU&2Db>5_Q#Tk;G0J^Vf}0PVy|S%C0l0w?@s zMHil;!JlF|hAMpt*M|axFg7fLzId4%`in$CRKmGf3lPfDuVI7x6anJNpO}*TO;9A( z#DlR6m6g84plCHALl<`zH{0xI%Q+5Q)oS8 zf@fKX7~A-^4+7T zOAAmfZYFwHyz2yZCZ104JLJ7)$B{Z`h>jdck$hh~E!u$pXO_c$FY!jVCDjhp#y|)k?RH5fi2B#CNW?%6C2n<;tLosPhvV z6zP7*Bp; z44v!oa3?ViF>fm6S#J&QB!ZDScnHa0ru6)&C@S8s53p>(gwF1!($48u7k7jfAZ_dE z>3Sw6#-M+O-l(4Bl(Le}os^4+!#i zdUh7L&-fH2FL<85EwlCV+5R|!@|`6}!$j+J=AyrM@;5LPsrDWxR!v;%JR=A0hnFvS zcybaS=tBRe5B31eUIJ&xfe%1l%&GESEr6XJ_Ua?Vm{RB`f<6&n3JxrH5~vmjcunA^ z0&ouw@amk;6HocAs^C5t&N}etFTqN6K_|ZOw|zQ6r^<-V0@?e4u6*Yupw{5)6blv*Lzq~g6Fl+7 z76-~v783(2`z5{2&X=2<^4=@ZT)f#B6j61~r$oEY^QCO4qX$+J^em#~xzzG7TD}_- zYhwg|OD6Q-CwMH?TfZ6-Uu7snRb)qS2z+?V!y+DUJ=wMEGtShu>QgDTSVD_o6c{Q- zMxT@&3GJj7U+)P8s9-#WDi)Tn$^FWz(l2y)b8F`>&$s$A*?jgXeYBCreD(AG4mx zCxf5;FVsVqTg>%GNv3i}H0=d4T`CYJQp!cJftp9B{-o9N)|1&3|L_k8*L0CTF3Y0l zBwmWVWM;Mc0OCn(Aq_+|L?9>>ZM^rPNx9$vM1&c=QP+qY+P4BPe+eVpi2fCQ$c@q0Z zN>d^27O91)cr+^hn)m|8L0k;AmMi9R|Ex;isi?Wq_qV9A(l>&?Btv49N#s>6Nl+_8 zEW> zIGLTVe-w4aY~jhENmyA4(H1XC#>7fv1XP+ddlF|JWX{b$>_IQN@E5aS8GP1iseG~2 zDoJ0auNQVo{ApqvUFlkh=VHVo>FI!hCu^YGp2_$BBu)v|%YGj%#hFK_VhpE8IADMo zc$!s6Lw;GGVm$m-q_2s-j$5>NH4TdV_v0J0)=jyl&u|9BR^yi1*)s=Hyu)fqNypTU z)2^BH!jVm!CE)Kw9IOlCx{axtrcZ|g8d z;0z>dyrgv-45qW#b|rdQJcmQ0JfLw|HRWoEN@S zGPI%G^{l?36gPjWdCNFejTh=X;vqp*Gx(>Cv{IMj27{_4_%lX|OAX3wn0{3vsn3AF zf>KU-YVemaGOBqY`9VCh&bHIz`+hp4tmgNhK`eWXCZ^Mgw9U4JXiDiR#p_YvQ49Wv z_m8Q594q1EC^jF^s1fTzCcb9nd{QNUwi8y7b(T?-=Lo|-4u60R_k}Tk#5)y+&Uo{L z?t2g>u;uc2d`A4QM@x$9pTM8lz@L*sOc(LQR0WHd)L}Ei{wyeqgkgdHr{V!M<4?v9 zv+mJNfcLQ;a*c>E=;bVtCIDB-*LI0`IlWZ8NY)DaRw~oGVJlvRy zKWAy#Vs4b3NZUMZMK&Vlt+Lzj$1?zc&ocUl(WB}gAYHQ8*;`ak?S8BHLq9_~XLtJG z$WX-_VrXO7T5%Z#C-Jz$BWw&qt~W4-s`1ZDSNdqE@*hKgg1>ivAXC2wgTrqgG;4l5 z@Pf!0*pJuLjC33Qsr2U}X5m=cKhtN5T1L7J{?U={1jXnxZfM;)Ag((f7uTID#%Z0U z%dqSfU0%S*Q-`w7;wZ2SRU9P*vCi=S!~zy_9d#VTvwnEkZxS^PDi870%rI^lifu-p zdLRq8F?JI^r|}4idOE=`1E1+oDvaS0FtAzMy7h#>W+0ADw~ozc(4EC5zp3*8{h1Aw z=7B@hk<_&_`bZn-pN6n$^c~Q+YV;kvD}h+*GNbN$$N2hMo%|dIz4%KUFd9tc|1w{a zj=j6Sd*9~ABpg?rzc%jUt-~zEyzfTq(#}dX}u1j-h?UD<;$Nha&KFNxxWtf?LBu*K=*}YTMDz zB}r``Xjc(chgnGiF1WyW5U;=mR}bJBpSDj8kaPTt*-6%2ur4s{pMgK{VQe`y_%y^T zT)o^njH{Qvgtdc@BD^b%(Gl_wl0{ZJ1D zS0DIa?Y#?Jlx6xi{tPoH3O1vXp}9GRrkj#;0_MnY8bt#|0mT#*VGxj0Fr!eA5Lk>O zWv#Wg>uy$7v{`GrR&0@ix`;-Khm6z;&8;yE)CEl|u54J~4!}mhM=_Sp>Xq}F?V*z!2^iy5Zs_lI1biDm) zE15ebx}{Hb*@s6OPL_Vxv7X#4Eze|6SR8m%jAN%QhjS)&dl0H7x3)eo9&frRqBdL|*+WX=&mFFgi_oDxP z(P7z-ryXAO%qZTVpfnEPing;Yl`Y3Br^(X}WQ&pcWzNLkb>Zgk-s2a1liCB3 z`M73q1(s1*ur+*I`kB+Rzb2_0-=0*T&i0zdM`ziOuS}Kt;&IjJnl89^N*qgTx+*V7 zW|w^FjBANNc@j~qI8O{H&g==v)9^@aD_u8h1^-!LK6$gk9Lg7F=Ne~Oi}OJCglG7& zL_t=3$x3ow<&pMTR2g8TKfLqfrg*pG4&@=65&whqWEp3rsfJN_m3ozi~wBWKE) z#nax0*pqeQ`Yz}D#B{JL@BldPNCYS2&X7R1Ltew-&(Ku*k<;D=<~y6{)1P3z`t)MM z;Zh&Qcn_{$=%DYU7)I2ABI!mNF*teZAR+1oR6=KCMI3F5mG=n?;vYaOGVO?K&Xynl zlFEnZMQ(W60FgX}&bYSY?U0TEvSDxeS>!o`TR@rmv^bb3jOuubDCF%bteDjFuET;H zPcV}lhrOAX=)nx-IqCcsMg4K|w0+1HNL@Bzj}*v$kh@hvz=a2d};yvBLJ zgO5jU#z$va14*bi6)k#9Oa1XL=+WKD#5>=v=bB;dYwxP;4z~}-1q8=hd`SeyNV?^A zFGnbj={Vh8$6gxv3MZZZ$6DMrQ2XB&_aC*mC#aaw;u5F++v3{)<6GP_D5w9d7Pl1? z2`w&B_n*_^o(DD5;u3{Ii%WJMEiMuKpVH#;wEVcmZ3l@zr^SuOl)&BMR$MGcbL}zA zwcx$5a$Fp9ShlDeaM3#)PZMmWL8~KW6Yg@iJ5qKzQnoo#wmVX`I#PD%ER(R?Yv0(n zqFA_@riL9pwAYv0^4tS$@s(kY9O6digbx^wD3!B6~d+( z)nVBIC!%1oJ9#{_HMYpdo%~#P;$H}fgEi7BKOr44uZeo-R&Yl8*jE^7ySekoIq2tf z4CC`iae)Msxb#skgvge3%z$%EqCoA8f*~2<+hn>49??h3`_@X=p%WR*HF$6<# zupLFYx#Ji{Y}rFQM6l#DxV2Nv=(Kg0cPPv8X`@H!EJ5cVSRucF>~-$arO0h})SJQ0>+eS-m2sO9UvkF-6z}llIhEbRrR#HH=#0T&`&$sdwQ~X$je7Or;nLmq zS1X%Z#g{5>#N%Ynx)Drnkw)2>&QTlUUfn$()}21&-^b0qZ|6|)#%*zobjEF?GwL5< z->$MdV9nSKma9hZQtulL)t0NyxE=Gd10s;c9i3trXv<_fJkHZjun&)k0NAdkl^0fEiL7b_%q7F$iJ5`-$v=giF2!HEzKgF%8JHY({0&;HcJ57VydicZ z?Qqz4Rkjb6Rvm`*>Sn(>s%2uT-5EMj;YjDDnzFi@xH_0$eDTHJxOb#)mkf6%9ma>~ z_Bv9k*j$;u!?~@Frpke>j+8chXE^0djpR1z+g-e+!@e2U>73+*O7{Q}@Fj zGIdEGRgr0rnK!NVaip|#gpxF0B;x1=`qad!Q?k?dl7y77iDOvcFdvs{^E>Yugcu5_^O)M zy!E~7-gCz7be3&#S~g;fEqoqJ3HDDq?VFuRXDXV!8o=$c6ON>v8MxqKSbwZoMU(4~ z8ZS(6Hj5h?J0|$<6;msMVZQhnzi^5#WcVHxcOeMY2oP%BA^MlayNSD?FG+ExRAIra z4R;pNoQu1zSWbv+q9{yGoO>JFC!ny7=I$J3+3B?GY&<*R=+{Rt_+IOU%qE>dDu~{G zIGbC48VM}1jmkh#_Rh-iJphiL0HvK0tk0f!hs1!cOx{v~^Ufl!qL(Wdad?-(a*_^V zYn+x-juc)ihxbphDv#xnlvA`BKQzOU^y$n_KYVY?VfnOEf;x8!(~-`h(3~W8CGFtF z0)<~V0k8O_G-v26=y>+y_y$)0(KdT?d0Lj<`b^4*TIw zIV1p~eiQ_;Atof@wC|!VXj-ntOj7!G94woh_Ct*>S*Hrme7*17htBVK&2mv^AWzP2 zN;%uBQzkg!5g>TUmcV>`iLAPUUxq{KSmfncJEZTem^S2}`rZ4U=VUve zhP=SZLZP-m-M$_7>!5xORRZ-f)M2O>pxle=1MV!)DmymmuroKF?cP}YE4!_><(1tQ z+kKVY8TPUK{SbU%TUe7nhpoZN{r{H0|O!@?)Gg9IlJ{j#b=i5x@#jtYNiM`$K8{lK-(59JQO7e7grX%h$ zee9-5gzu4|9ttC*4P3PdQScGqiKMl|D)pT7k-a1*R)6jXzv4wd5$^>oYAcR@BVwU9tfkW(ExgXWG5117bSA zcBXV0ESGKm+r z{S6I>6iTt6dI(R5i#~CJ<%v@$r?Vs~fo;>`x^HhQmadavgLqieOwly7(w!rq34-S8 z$D`Y>o^BeVaNaPql}5Zn&*#JEp~BnZ7bMJgMWY9nC>%*HFasiY6&q@8rMIv1uDq6B z=pUb*4lfgL=H(9ZG8~a)4~Lf4rd zxtaU1D}+Mb@g85O7{aWnnd_x1^S6nchFF|Q0nSLja;?G^1Zka9GUVzhDyZ!AC5Gcz zl-m2u)$cjf)#08-F}F~1#d`&A?OP5t^`;kROfk&XbqQaV=&4*Tv>L4I7+MAIM(wlG}uCluZaSkcr1c2nL#6*LUc}&>!^mH<@&6QCL|+g~dKIE`(9j94^70 zLXYc7oQUR6XSfB$-}UN4MCTIhS-$cJMBy0}Aif-fr_i)10k(0786UgB%Ypt72R$zi zjTr|d3I$pfyn-aOsNwj$z&hO9Tj-)!XcnU`&0O5+CGJ8Eo_z~oOI+{L#YmyB6h9I@j|{ZB z#cpa}21dKS#jF&Cb{T!9b6>~HC^mNWgj-6|!c$ z&d_DU%g;EY6^8`u{&<^x9$HHe`V$Z?Mu!kv8}Tr6=`@4Izw9o&Jvw}YI0{b{U#pJ7 zmqj3vt@Hw)9W}*O$qQsaCk7gQ_SA&IX*RZy>E?ux{d$~Gc4wcR;J~N?U9Wpofj0*2 z{ArN(?eK{ zPPtxTyY3F(n}EOZ^jVgB&=8cEo~cvng#6`yR` zay+z;y?rr#WkJNLuPk)k$qPN6gRy(zdoA>HtRek6~hoYUw=eEbA6u@$JHt2os{c zzSrRBJS;vYzCx3vF2`tWwTpXwuQ`e&czpUnJe}vT$P9aFi}F0%-onS$aImlmr)UdA zm|WmVdJ%IdlE4L5Ngl+BP}hQo#E{ow(NNcW<75^KqK^UgYCU@VUB|E5`s@<1{#nBsdIpn7GXtjBw&(zDK=j z+9t+2N)PjE``BTi%q93NUzXvB8s6XV(qw@SGwGhAYS2|#f`du7(qV^e2~Aki_$i2= zvl-JT$0oid@{zvn7g2duc-7rq?;3@c(3DJfYVmMmoX>ONc>N3S^u$!QOK>U(_0GqI zURF5fRe3R>CeB3zAV1eT+mL*U5C0sy;j^L@ICjC4f|lBaL+S~xQ#68s<$k};5zY#t z1Q93W#tBN|j`Fh0oU>vxS-#~LK((cdZwwkcj=_#xVTa7o^Yi;UXhMjWAuEfK)gUY+ z#JL)~Q8qsFrSvI6<;O%IV#S+VKG|N?mY(XAADS#TaH0EFSJ+xCXB~`S$EvDRdYUXh zP*m6@#Fc;oNw#lDc7at?`_XZ|lG;>|Neher|4$0=H`-_Rxdv;>t!jy==?a{S;)4 z+GN~^!klzbrHP)q6iFY(DPXK#_^e%vWc;wUK#AbJ(^KC_3r=&=F{l4Rr#J$Spr1M3 zKJA+N*tgPrDPBcAmLatrg?c|j`q81lW_tkeU|_TKy+-i?teIguzPT5#BzCqYz~SS- zwxeg&4bvI}n`Z~UzeMm9y?6P+eUvP!i4Ko(9-yRbw@TlV;s`)AqOr+mF-v^0NSe17 z@nuN$X|uY*YhtBc(#S^p-w{C_ZL9_!pqE-f59g*Ams@&!kDo*0-GSHb{%+TB8D4!O zJG6`!rS%_)_jbOA%%kf+*!#`vcuD%|$CY1;Hdy?Afa!opJCwec(24PO4-x{~FnXf) zbdmD`dev-pJ-Ity?Y}ioud+57tyhX$K%7Fl^_BwJH8F*J_j~`KAIi=>`UD-!z`}^~D;vAF4AoIlk+!6yJs8 zv7^OToQEn7P{Tyc{-qkpD2KSj<-o}tP=M`=B8hKz23pDf`BUY^0i!DV^r#G*8)wix zW2L~-it!qXd+}mgXvMv#k(C$yYH*aM=fxK@UUc1u9@l9<2xCQjPjfY!+`>0$1MW8;0BXV?dO4fH& zE`W}(;Y3vce^jmwXRZPei9h){+IjS2{;1q(9F@b-I{3m`4O{~Hj>`GFkIKo|QMmvd zkQ>h*mE#Z1#gz>G(P_DPcEK)X*>W7+YAL@KUW82odC?H*YpusG>~ro_A1gmQ;kXN& zP#n;{3BA(@x|rr#iFwsxoHBIXS}0VJ(GO4+=^Td< zDxIz!<_d!!ywm6H3g$fv?_Rij0~*`EhNF#;9?Yvu7@}}%v0mcpd;KuEGw(-jcG>Yk zZFYBc%C#oTb$SR=eXu&EyUB8m!?Q0gzLlmA=FVr|zlBA-%keHr!gxry3@vnD?|~)& z-@mf-1X?ip^yoo^wzuM9HR@LXuwVK%rs@YFqxd4yIt-R}Q)P3cYz#bkz|u+rBz@a1 ziwNvGU^zji1D3Xymha7uq;jlRFQT{UhBQTa1$9dBUye~6mV@njtYNJ`fK+s4KGOBn zZ>bxq?-k=Ybbd9T7T=$u6|fN!d3BVR6EnLgiGu4mg8?0_z^~tk5GXPFia~jX!xx=| zVXvKrOt-uOt8n|!%ofb#J7?j`*X5jTlnItNZ;aJFMdk@|7y<8-VVszG2F98wN%oj{ z*IQTxg#(sa8mrexVh&g~(JsR3=D4iAvN+tGvFxCI1aH5;*IyLlC^`le*h@v9 zeU9HRXqWD3yxQi#W`?DnHe_hyq(pkPZ4YggRDQj}Z5=?9SbMuO3EOlHjb-)X$^(gx zvd#P^$wjmleVZgl9C2IvHc9qlF9&9fWqaeAXp@95SEuCywjHp9j*?bdwofLUXy1;F zEAatG*|xdTx6!8U%rIbO8Vli7STb~^T*kNe9A&$tmB~o#FBBp}7q<;tPSVPmu*oo# zZIV7}WV#)+VdCnrkO_i`9?{}LTelA3?W55iOCcR>v*bcY5P7OB+s4_)%o4Us;H_`F z^mLyZP>FYtg*M(NM_dD@8eis%sb%X2k2>#zOBVUNa-KDosm7* zJ*n~28nAh?&Dn@i@Bxg14@S`5SG6Ou2cks#CQd#)Lef>O4qWb|=;k`&8nC_bCuGoR z-|6JjroEK8ePm!A|MC0b(^-ZM)9#7`UJX=0T@Fh_1{NL+See9@%4K{muo;^w!j{Sv z9Mi<-*~JYGdzWt`zds?qh9FpXMJU=*>0Ng}+fpHm600+%!Fk|noB9|!Dx9CQ>;w-Z zon=*3NnQ9}vNP^77N%)yrQv99!!Sz&;-;;Yua0*5Uh0k8No9tkQ1&kS5qxPcrC~i$ zyTm5Va5iQ5?#2E^7bxbpR=W6oY;2TZYvl`mYX$u^+gka?y|r@1k-}?fYvnq|D%3t) z!Db9?t;AiQ<=$Gk&Tp+;p|`haYvmj8m2Xk7#a2Wizws^Gj)dFkh?eCXB-#=81%x`o zQFfsdPgr65WIL8K2JE=FXiEfF^BuhGJIglX>=#wwD?Q+TTpeCjPokH0&_eE^^RSqO zWEc)eAAS~+6#)rA)uQ8Kr|{k5YY=5Njv#?9tKUO%9EcN`-GN6OmMU6;?&hflmop5_ zY){Z>sls!dTcwq15>;N#X=@%jx17^fA$@@2AIkYi-cy5pEGk1A#D=d7eptTY>{vBz z0?{bj$v`!k+KD&pXnsT$A2Wm;?um8f}g&ZAeVMte6h{C#hJ7vn_Gf-9$J!t z>43YbZ(ci!hHcofyG~+-#+TBtkUUA(zsBp`;w4>A2M|fb+`D%Wu||6-AI~fZ&h^ex zXA*XBA%0@MiabO0!(BUSQEtw%>MNEmY&_0#rd-Cm`tPHDP@U++c4M3G(W77W#??~k zCw19B!hR!Kly0gN(yBO=3Ix!3C_KZr86w?jq8y z;s&i|oW`vCW8YS)SShY~_RpPVIAK%IDjA9ptxxFH&(KMrI55*psdpYa`W0Fm+@os8 z2pB`UPT$sf2#N?m?^%RJr^u?Pow9`5zoX_M36giBPlBjPA8STjXt$k*YRdM5gcoU* z1;;vZ_7iIWy}qre*fknlZ1KGW3+EwxWBwQow_7p#w(Q5K+fR$ijBj+&ddBTIwe5VL zR$AzUH=Pk)e-O_Y#MRkEGo6-Zsvg(jvAak#Q*3W>Hae5)oJSC!Yl0)G!I9Kn<8Q`d zMaP61NeHO+ZFE8`EUrdZ0N9$+iEmcm6iW=~MlMhpebKt0C+-NN79ZIw+qxm57rlis zxYW`)tX!wF`!tCZvkgazzJ-!RWb_WXffc!pcQ==Jh^u47(%lEEmx?em3#S!G{zipv zE26?soi+@-DdZKX7Kp&n4s%%S#h zXmzeM`q;dD4_s-K*t|z@60*P>4kPFrFIO6Ijcx>8RNPHtRr+oOu0DAAHaU;Ji$yjr z@VIS);iPSh;Uk-`;kbSD2yO*tR(>P6Z~y|z=?iwKh|2>HEn8A?4O)>cfJZL`IAk9= zf`*aU0&d14--vKt&);Vxv-42k`?kBmDk6M5kP-gA zeN4q+p72|MND3q#=7~SY6E8y+VT%kPB0d8^FBAfba6M5Eql6O{N;Wzu+h0x)`-r8l zqcOBxRv*M0d&F+`Wf9`|D?ACr^jCNyi0_Ds_>ON*fjT$qovrUu>4V>Qg9tfK_H_~j zp5J5K{3gyavU#3ohfk(bUovf*plvWL&gM>omJM?7^TI)k#p zXXNMQqtW-Uy6F|L-OW6#VPHLlzN95gzc86$RaF#D)l*#AETQ@d^r6}blu_LT%H5R` zTCau9qq|8A+>(FN7KoCdB4QQvBvnvU4XU6JC#s;3F6YsTbF^Y^^MhyjwhzG#Y*g{( z%P3|EZaVP|0M^`mGLz}zqmtIz*-~5S64Zg(aNC?pQ?r6zjE|t}iqhAUd^+#Jjv5wa z_|FpCd@HoLEQO&5J|~JMj=p4DIhhYpY4zDd{@oWBJBL@c@4;#%S-D0ap?xjAlXGxE zuXnNw|54&U@w<4dh?50~I4`Jg@XW=hP=}%Fp>{xRfqDe$&}b2N3hE1}Z=fXpB5oYi zbSNWKEYy8a1yBz|ZGn0nYB$s&sCKB!P%@-<2h`nAdZ-wv6;Opx)lknv)j=JD8Zt)2 z-3b*Al?hbiDu+@*8KGjJ5}~r8)0A!}@I}D_6mWV}ZrMalmHa?Lh5Gya5fY1=6vg%fJa_ z{}CsX1GzR%HW82syc3vwijx%s8-OLicHjfR9$*hJ;56h7C~fe3;cDk{VN0nOdBiNltNRz?rP$UWM}5J#*=i7!fNaj+(OF0yk zMXEdRLcF1U@!COyl`97Stf0h({}d`0e8Y!8L*?wCExOUd<@ z*UjV4MEF#s`Oo6%FCU7Bc$tHca!{3z|M@)CjE7VfMX+J+BuP|8BoVA+Jn2($n!f!1 ze7-J6?2K2$l^Hx=iF0HkiUjIzmR@jQdIjJtm5$skLpGSH{7G&pk5mR(d`kV2(H|o# zKNV`7AYVV9{vyPj&c`js|2&@VEI#cl?g2hGEZzRp1bJ3*{qpkj(<50~`!A+9P<{l? z3g!M|>WQC%ObPTeUa39mVif9UB76#YxLG_mYk$<7vX9>p;3CzMT*w|Pcap@L#YEH+ zO>$01Hy0dXWlt`tpo3(X%AER#;h-%OF;VM4@ljb(+d!$2T`JT{$OyHm73Mgml#ZgkN^#h+>Q5 z61dr1EOgXUQmv(WKW&pA;;{Ghgh>dhKHhW@z7o$BY! zt%A0B(^>0~dHLXCRU62cs1?my0r6ozoz<;4P5OT((MBq~p&nJ?- zEWSLbt)7auC=I4UzJK{~E7H$TlAs@RirP&ZLfa7wwW}mg?0|Td63n? zb*#TVC3oUK#Y$Wt>1BPtXY0xOzg2u}LA(#j$r{982s@#^_xIS*+&rWn0q)L)zaRHK zBt>(%SvPe{gnZ3|oF&}ERmcbBo~X=%gpmyPry%D$js=6f16vp`2R?JCYjK zYeaF=@FzzNADDw!_*%)+QwW(8e%NDaz|I^0qbUa_IQ;Kv4}A^vG!CWTV;=g)J@lJA z^!U6$pMTtT@6-RvL%++b-~LSxJ*Hb6;-Xm@|IRAakwS2UYKj`8%KlL^o`ugTipa^y zPlH#|&n&cB31?Yt3sZCKygotD&(6!TWu@k1Jz$M0gf1;LC&8L#%gWEQ6mwC9)>NC- zvc{TcvlK7Fc$_yUSaVYgGV=?qyd5G+%!GYIWIrGcx8|zmeZ;iBPWLOLNnFcW}Hfv>JYGKKuOlzJ%%mS;;UYG|TU}luPun??qN047Q z*PgqQ&m-Jo^H&is``l*dW#kv;rV?WXx)VxrSLWwrrNw6DtzJYlM_V&e?K!sSoSf*a zLKH%NVV0Gr#gb>wO(-d{S#x9a5vjF^$|gUzAhpn%U@OeZTLm-Hj7DLBjYx%=nP*Cw znW+do-II!}h3+(&*SV>=R^s36BFITr`T)z=sJPUEzSIWfA7zxf$~rrpXh_UTTOE~e z&$ESSct10uyBD=uuutS5s$3FUF$-*2-H1lZ77JUBi^EJ3)JEn*ph0g0WPOcwQC41h z{#r7}rWU#F;`0ma1$-WePxDr0qeMJ%LTSLiAU%8pr~-TeC)o42I23du>e?b}I+vJf z=VlgWaS5q54sPkGXlCHfBm5MR2LAGxjwAntyd}~=INl$^+6#Fd$IVI2<7Qe{a&f7J zTm(KU6^HP1kmekF4i{lx1-=$=^U`eG-263Mv^93HzPfLMhPEJI)2mTarnte zQ-U8C6Qj?~)w3CW0^b@V4BrzX?=TY~i|{`kNFzNva3)&2EMNlUfGRl)M{_pTX0!19 zW)@Eo;$S{leAHg{+p)L{J#2(@giu0yGQMJjn8R@P4qK*@{uQIW^}Q!B(o7{9B3B-4$v>&jd8#k;8!~S zm$=g>6a7s`4@~a#M`KfFL%x{L7%m2*f?R%VKqFcD(YPpxuhF!wh;^1r9RINn7m)hH zE+F;K-9T@k&o{V(29yDDQi}@!Qa>#R(t6QUAdMUpKalq;;oOpd8o+oCs_O(z=ri7zpeFP6BoVCj+@}IoVwRAK(9dHGZMqrshGq3;{4lD*n0Ly_{1Buo+10d@FDvunkD;{S;06jo2pwDH<1<)TT0aE|r4V1$?1UMZy6sQII0HcBUKn%C}bI1cQ9%et_Qs4++ zCh!)Z4JZYc14-aE0!IR=uNnoUzG^g?Veb#z4!o7@fn$L6zyM$~a4hfya2&85csuYS za6GUZ_zR%qJIDi22AlvK50nF^0w)4Bz&nBAz(8Oua1t;XI2o7@ybD+WoB}Kb{t{RX zyc@U~I1RWBI32hH7zEr8oB?bFs(@#J8lVdp47>~s0diL$CqO@-78n530Ve_VKn2hM zGy=nbF+ejg5f~0!0gM3V0Hc7#z-Ztmpar-UI1^Y4oCVwkoDFOM&H=Un?*+C2V}a*^ zbAesJdB7fEJkaMV)?b1Cz=c3La1n4i@IIgsXa&XsR|A&A*z|p`Kpg*t;I0kqgI1bna`~}db8~g|Q0}a6Gz%ZZ| z7zK<5t_CgziqKHy042a;;80){a2RkCa5!))&<|J(90%M5Gyq$GtATAm5gIfXPy)OR z97+w`HN*q-0}clU0R4cIfa8D)paEzEiqPQ20wus?;80*Xa2T)vI2>3C^aEA{#{oA3 z4Zs~h5gNvN;4ok_a5(S;&=1%S90$AzGyo;n;U5j9KX4dO4jc}g4jc#60u8`;phyn6 z0uBS_0EYvM$sJfl?vp?VxdXS6J8%cN1MA3rD(E41;0baEwv+vI&_njXZn6hTzK6X6 z^%FP@I3740IF;-*sGnpH3@3YFEZJ+pFERtu$!r9_$P6qcb2#`#X5ePRXwXR*13C#~ zK__86>M2lCih2qh2W$sYTNuf)HXJ14!#14kejxRk0PZr(ZKUbpWTyarz&C&az-_=u zK+In`1@H*a2>cKj13U&y1ik`X0sIRv2e=O^*aBP)q`r*$xbrZl0jY1NzP<})uz>3UmH~Z!;AC%;J>0#3a+ob-kMI)UbeO5H z(E=X@%3x1pf@qk*LVhejV}p2@p9d}lJ^{=GQr~0){ux*fd=*H24E1drVRi!Lh;Jxx zE6mh~O@-M9SPSzDz+J!(fDOPMz!u;^U>opB;CbLXz%Jllfjz)oK%X0&>?F`1*b0;b z?*&c=HUPE2<3I({8wQMq`6w_R_z7?+@FQR*@DR`jd=pp>Yy@ruo&atEZU=4$z6RV0 z{0vwR{1vbn*bY1aq*L+jz{9|cz_Y+^;Ax-8#0Hn_W8ipT6OaSH0s&KDraoE= zGmSkoFy{aRV5TujILw*kj{FP<#=;y6OosbCgfJHY!{P1=Oow?humJcXuoU<@uo@T# z+zfmRxD8kjY(qRWR@nh_HQB=)3ao>f#tbot*AKWKW*U2}fIE$WT4A;UYvGQjhdTrF zAAv3)jXmOFKLU6e=6S%W2sagoktyb=;1}E{0R3Q21t!CM3orm?R9SuuDFse~`6-|R zI3Jh^e^fz@FfRbcBiUCa;IqIjz*<819|Np~IT^SO z=G%a~U|tMtMtVkI1I+7zEx?z7ZNN3a^T4gZod`D;*ah@z$JOHdi_;J8Yn3n>nZT}o-gLyA-Bk(=ocHm3Edf+p_286pE zcmn3%0Na5nz;fh64ZH~R13(wd;lOT~Hvns4)&hORB3U_bC(JsaKg<=tX2d%lD2I6& za5^v#*b4h!0JShL2W~>RU|=-Nr9c3Gf3J0NG5P!yK2S zp2K{bYN@bx6ovXmwT0}9c%)fB{bB@D-n+i_Q zZ?!ud?S#>f_NnMcXFlk++Up2jM?k;a zKE5#bT(|uycm9aq#IYizM;xKOL&h;C8$l@l2-uT+1aXnrDPb}agw;fn43Z04d%TYi zOKXzRSbb#jL3#`HBqKoxxd3{Siy*8N&F1xmyq@eyK7wEy%j@mX$6$qn$qCt0TC^WW z`b6kSK7z1PME>(Y9qH#mPjV83l^3$7eO98G;wO0tf{y%<%#fbqC%K`t$PdX5<(KF$ z;_in&f{&*N93gwk3&~LsD2UhIG$$O zcNNNohqLb=}V4usEg+M=*Bhwdogr#~z^i$Y0p5|F7NveNTj;t=Qx+H|A{7{{uQl?xB zb&F!5(&ZpwESHfy7fFtZM~v^eJWuEHJfb$5Vx7;&L3yBdndF9OVsucuOEFWQO}noo zXT(QVXPAFhXPA8+A6BR{#M5|pnK6pvVdE)7tPZex>nUeZd>&cb%*vb96IR}lJik24 z($l|?e+%+MKbB7mFAHo>BZik#>T5`@sUEOANAPu*<(cuG;hSfwyb0l950xzhpF!`Iq)6e`Qx@C@NiQvnD z`HAK0zL0ksSF?DSBr`wv^80SgPrSRnQan+pS3+759_5k5%N`3G>ES=#!+yTIEGZt= zYOr(@_!fofW8CFJe&(Xp5NM0%=@<42WB8o0a)KA+o!WUi%_Y#5iaZJWm1yGyeL6o9 zVRTygQ6tl5p*<7)Wb>mNX1|&r!7zOedTPNB+lgWJBol%?o!}Al_j}k=Yb@AP%PQzu zFUR63annqF2WzF$JlZE_!~W;MUFaWa%oha8C{8xcVWVNzztFi9vL}A7M5rLN`2AsN zyiDg%X!OR$LTNmIDBU1%hw@8f<{Dts?3r9r36USh$NWA$oj?-o>HJT>zTbbkhdtX9WbrV*GyN)*rw}%i zFEeJJi?NMhPiMLWJsUwYKXit*-@ZTH0$wJVAL;=GKXwm$Iypx6)Q8f^T+-9{gF*@8 zHahc5dKxFOnGqX5u~`6XgW1f3=~;ORda8R&PyYpd4qw*HJ{Phlj73GErvM~meW2UG7^gU9N z`)rKEX}m@HRXl&#_-{2YS8N={=n=+G%tT>mjJcZ6GaDza=Gz-KE@m?^HeP14Gd5;o z^2)}!Z1%;*cPv)cE3jD*&5bAzRKMAHg=)N@&*jUQjc4hFLRZ2HHBbOxM$!gz&Af4`YYt}wr0vtl;CVKZYk zhGprp@eh+fre}0AJ^iQtfX3!*7R}};bQ+KBS-&mJ#|1MB#oTGEA z?(~~!zC|a~$W4$-I<-h+XtEt>@7V@3|8$c7X8xJ|K>swy68J!RA@4N*pp#^j78|>> zo`%h@1zDj}0{wcL53V;S6d*-mzQab!o_S_A z?7wFo*c@;T_$|!cSh}o#r@BZrQ&`6#Gf7pynZhx@nSA<8Pv=er`y#%sF?$=|jX>L2}8aXZWncw_&>+gR5?6&8ge_{KJFTGs*${$|c@!IQu-1)|z z{=DnWx8AP%%RBGZzqfl&L*w3k`~TW>p!wjT_gg+Ve5Cd0vEwH`Jo!=E$EQx8`Q+2j z+RvW*{QTd(_|nyJq4VP3zxulC(l_5;{_e`v?rYb-@A=_IFDLR6OT32+^%*wY*Kfov zQrXB+qy29kb6ddJakr2E#T^sm6YmV1H2JP6Q-68)wCO?j%upy*YE5uRs8**p7)@d3 z@YI!Q>DG)@nOWJZb8_?Y3+^v0vf0^Y~0*=@$(lXBql9fl)U&p#{Zvo|BvARzbk$}oxPtWe*C%!?Ndf! z^@i4|lCZup3Fh>tvF|=jfv1b{cZ9~{1k1`qfN@q6-#?4QRSbx-%f`6z#Ep!?wP zrpE`m4^IEKUk!Bk4FBZ&IKu)(>3jZORea8Gn4H21DC%sz-KrMmdZ<=988s1S4JKp1 z9h>BvfC`u|!2Sl*$dMv$5>zA<4qRZ2E9N9zZhpG82zN$so8g}H9L%lKi&idY=H;pB zYf|&laMResE{(tKGr%g{nq##M^tB4#=CBpw3Wzm*c^X~(7!aVK@9KW_D58b^-WiRz z4_a~dgr|?$-GTQOaG2z#zyH3;@blhe2<8fG{9UZ&xpteiczG7?cH!jJAX`X*tuViY z(+#q>=jG(5VQL;S$e!8$qR%!BH&>PyWv$9f&Edukv|U-4pPHVAD>OI{HqeD9WonJjtv1|?xk0yKJk0Y&p3hfgQ24m~bbF4~;}X>Ggjgfe(+l}mE{=-ha0@Ie zvczUh%wLq1ZjH)JE#yA%7PN`^eePTXg-)=gvj{ovtT%s;jc!$OY5nPuc`hz@VdG|% zcy>{=b)|jPDr;dp62t{IE*ExvH`Qk1&Y!)|D!7I4oLXRIywdWf1l$(nIA3qv-=h0c zZvKW*dX!RPNr9E~7De-o#h_b-+-^p3YN5?uK-Z}jaVvjJX9ULuN#@(Fg(dOULjK|$ z8Yli*8Mr*0{13c)hvGTO$ID-mqkC=^A2bGJzy!vXO}w@>LYGr@SG@lOeIl z#Na~Vo)^bjQ`Zc>0?KhOi(^rv-S;5*`<{i675;W$6bU+R(sA3V{zOE@bKE18;ygHo~vs(315?z(uM-Bw`71xLsoV?StlO|rn2la#j>SLe8=#j*YO3*q)xii!CoX@bp@ zBL21}m1^HD%`>d#<`w1VSSih~Jj}>AWb{rdE06l|g9K)Z!(C-@F_LR%btWpGk7p6L zj@>tPSE;@3Tc#9f5qGa;!CXtMnl&&t?W_K4`TsTtXp}Mr%FC_jtRd+oPytZhP$Qs* zKn;T$3grhy(c z0srDph=+oU+;IpfL@AgB{3-jNa{oW|FT^9D5dMD>OLIBd&r$zAjk2HovAE?w`TO_N z{tt@br`Hh~kw3i<^dFRo{~M(Iq7Rl)IzAGLs zd3d6`TweN&X`XwLVa2oUJ){eNsGP@I_-}mS)C+Rv{G2Dd`}|YOPRY6Dr?O9}26~36;&|JqxR=N&9}+?` zFLS>LfA@{Cd!nh0Cl$r4x#)J>H-n0Wiib*sN`_hrwE`*=ssO4OstRfo)E21iP_{C7ifXK^nL3YWHICB&g|78Ym-FG*m29BGgi- zbf_FC8&oM&71U;^TBu!6w1TIWSmWgmrR~>3a}~A21%@D*I<@o%^=}{uANz;W zOz!30zZ&aF>m;|mU?icc;3h&c5d-v%Sum~kwZHx@E4(%3hsl2%_t?C#ot5GDKmE~DQMY*4{PK^# z55Kl&TlC*6Mm=8f@L$6B7(aaJNbl?k#e0v3=Qp))>?l7t>z!ZKM%1rgois&PbG4wo zG_wAa$3DIGyYD+6`osLF=e}6;dCNDyoKaPASM*fbZGY%~UH183_g|0heEGz;S3A$n zdElud7Hi9aCvJJ^^=)H6e_`eb>urAaibw2g4#vbKN1lKAS2{y*-JkxR5cl%mQcQnM zF*tw!ho`!~owDco=9Ev$^I{MF_Sf7c=KInOpUtcJb>67T@67v-Pq&UemwemX zM=zOMrGZtmZlAT|uP=XP4u9#bteii3zZd#Qr&(>Pk9^>7A8y`r@=NpHAAUHTS~YTQ z%d6+jGh&yVjoZI_^HX0OG(WjN!C;U6z<>8|{%HPm)jOMYme=lh0Wwtcf+DnFFyRz^KYuoW&Ua8%L|^3 zUi`Lf`sCT?gF-a(5?(*Ndh+9oCEFW5-COp(tLcv4e_4Isq9=@d;w$eAn0v2v=E&FJl{qXao2Dr5QB09rX%_*{xS6ITCC&`ePLUVc zu=bpqlb>fbO)0S!O)-a!7;a20D#A-!IVEyLkXK}yf_LcjMQNFMjjt#uH!H0$zbHS$ z7L=Bst4}S;y=RSbiX1x{SsB>vS?HM>qLRyvwnBRm|D2gSwmbhxZ0bAta0ppsO|#>z zyb`w=Hig#v@raqtnjT-6wFb+itE@$Rj-JkzVg#j?^jPZ}YmPjJ{+p(x7R}CElfT+p zI7M#Hib$iEzD-jyQge!|Q{*%H;xW$n=~Rp}2GC@j(U&;{H_j0F2E)KYytxVEE-Let ziV;e=abaaX_x7oX=&J|up7s+s$v7|6=~oeAfJ>`5Q9{sDxxtF-$R95vZ7|2vUS8 zq7;dW#fl8YYDKBy&x&^yhZP?yK2?0BxUT3`3|IOq?^fQc>{NQGq^jFh(^N`Tq$*Xl z7CC-Y^`z=e)jO&t)%&UoDwTSPI#2zO`aSiB>d(~QtGzTnnlYO38l@&uGgp(OS*ls9 zsnGmUvsW`R*bw}Skd%soSc1LHDX|r*4<7PIngkn5>_! zSLii*t=^~)*GKDP^iS%y=(p;(>9^~L8*Viy450?2A>0scuo@mWG#Z)>ErwR`tj%!7 z&~7+yxW}k5YK=x?xbdLrh$+E*+>E@3(_MbzfmRW&a423-e5Ck9F+@30sZ&~%iOLe? zyGlRR7?oC)pvqB|shq0as^hAURU_5EP^YL%)o-X<)FU;wY3|SzX~*Sha?68$ZDe|?}nNUzpg^z-yd`T~8q-l2a&|BAj|zgOR^ zKca8bf1>|f->L7?U(w&tiw(mJBMoB=;|-GxzckF?ITC4@W0+@1GNc$*8Zr$92D{-w zL#3hG@R;Fg!*31G8D25GZrEk02geQ=j(}gM4Cf4A8ZH{XGh8=tMjzt{<7ngUM!E4W z<2^>TQD=-W&NRjv6OD_F%Z;myIgrH%jO&c+jWxz6ja!V{j4v8rHU8OHXWVUUGQMv- zYW&#vsqwt=qVbaPsND!k)t%}kniZNXja~DA z<|WMz&7U;;G~a2y*Komp!T!PHg6|5R7OV&k4h{=`BKT?4+*84y2fKnV1z!mkhpY(6 z4p|@ac*u>A&`@(|d}vjuGxRygt(SI~R;Im8J3||$jX_y2*XC>YYA7yK>R4T)jX-b>&0p%mgr5*(R-ROzQJzy?PsTMXI+{hgDyyMyV&NFQYz=)lAYPXzDbLnuD6pHD1BD1y2mt2S*3b4_*@d zUhwFU4??)mU7^=QW!l-=SG9lBUefmH0`(^S9Q|T_n%=Ij(mPT2{-A$TzaKffj9jS< z2E%g0M#CoK)5hmf>X(crQv`|sz)#eg2Z8V%mwk9j1luMDP z)ye|ot62G*@__Ph%8SUyWo5UrN6D!qDj(GXe>UtvJMw|yxZxAjiK~X8 z#@kR6B8&+}t8uN-Vf?M}HRB$X+ULgaj6+RhAsLpJnw_UJjqli;1RJ1EDD7=-gE6*#Zs|>39RJp3{Xt~=}_o;uaehwchm1!nw zf;9$BxaOi}Q*dd>!y%7^I76NYc`D?$Amj>B>Oyvh>Jkh>3O1K8=HG+(ApkWoK&1sTvC)NH$#FK zs@@824mKi((YhF2tS(-ch+c82ZiOygm#Moq?D??2g(3V-Iv2um&ni|ZGee3(PKFNA zzNKG;+Hy~r3GKzxVc&*v4Xlrzq02ytR-g>ephZKVR=gtw&?vP^BWhBtG9E4bcI6J` zE@i!Pzp_Pn0=4Kor0+5$PonZu`K!jOCaI>YG%BMiS{18GR8^Zdnm3s@o4Iz(6)}I@ zuHK>ErLI@+M?Y`^?aF!eMMz(dTB7mO_@lp@q?xYKXpEX@O{^vny$+$nh;}1 zbVzJSV#v~v^pKnoTS#e0RmjGW%^_PuwukIMN!Ew#M=72NIfEYfV#wu?o)Af>U#NfR z_|QqA(?d0(#?a`{*wDn#rJ?DeIia@DQnYv*LpO(R#b{;+T8aA5{h=+PCqmDJo)5hk zdO5TwRHF6M`fJB)Cuyf^HCm%KS{tiP)GpPgYjd_joQuHt=jF{9ok*mdhLE~ z3wpyd+VkiSFJnw3(fR58b>lHIny%BJ)<#1j5+M!gx*VNNSE{ShZPabX2w}T!2gV2W zy8XHq-3i?p-Fb|hF6(;GbNZp@9Iu~*F@px4_a&}NB_CWu*I;= zP;1y}s53O6m1xCCqut;#bQ!w&ep6-)KwB}@sKBTr+!$kwHzpfb7&DCpXz9x_e%r+N zmbJ#6=qnqH&8Q`9#&)C2*k$ZCawZ>>%oJdfo2K%8WVk8D6mLp4tuSSp3QWbQ>(!=B zXj!+JYE3&$b*2VWv#Hh8W@5!oy<1;=_`|R-g?o z2rCXN539y_aZA{?u-dSlVRc~*Va;K!VQpdUVXm;Qu|>Uh1I%*sRJ0{pbGSLi z9B)oGuP|qt3(Uo6S*lSFwwSk>Yt1{&b>;?hv$@sWhLNz#+-2@Ib6xJqkHSYGQv@jF z7+os(F;5+ua*!LSrE1@sRUmNcsxMdM2d30P{L?)(1zpXYhKo+n=KoLSDCnfcB+XU1K6|Q@Wu2x#^E!wePaHLmwMA&-~{sX-F`iF*w*}eJ% zdPPKqdIg7iHEz?vYd}~)V8yIi-Mll3uC;pT)DM#K?9Md!n{m5GI_Gom-b)(Tc>V6l zN3AqwcRA<$>fLWU({;PIInznIM>*5Dj5OAnwh!*x&nolfGicjHq@|)u;SIN1Wv)9T z#foN8+(dF_5m}PH^id&2#FObtER%&poYSg^A&QXGnL2acU_HTeb8{C}eA73wwzD>H zrs>I!<|50#6A5@DiSunGg)cgyH|!XPPq6@-aTHe|`Lc*RyigI1(G4LO zfmqDI0<6J4Bty-gMY5wb-a=dS!w^iyVr;-MT!UF4ixfs#)Iv-2!3a#kG%Umh?87PC zhg-ocQVccF61_1DA7LgIU;~cf8l(_$gE!tnL$pL!ypIw12($1bHeeSH;{tBMt#B5} z3vX0KL$pROgyRFmV+l53502pq9wA#1jv1BUi;f7wFigV|Y`{L8!VQ>S#1meqgKh}L zSWLrWY{MBmgd6>0K~zCwbi@0wz8n)0_+C5F?$S0bSGecGAu%(p1u-+X@O}G)9egjH zbK#Kf6ZSB*Ah$KO-&&T}np(^hy|?%zq#W<0NLtjP7e|M&8mSIsx)rt?q##>rp*y_kQDJo~4}>-~Gagt7AMpUS=Zb^c{;@AZH6wYN@w z^q8^H1UIteE!AMFQ-kP@zu<)XMHn!&fIV3&0p}{!bOX} zU-HA!Wj`)ovGS)?tAAdzcHR078xuBdPTaC}+x8thckSM@ci%7j4;=jU&~Jy298EfQ z{KUyqr_Y={cmBe~-!CPnTu!}m_1g6tH*ej(^T*wL_a8j`^U>ocX`-l_ZkR4MSGO$g zS+jX~zL7mg&Rn_kLRj%Swwc1 ze{~P2jCuM`dCjlP9?VL|D$o9@%Ip2h-2PR4`oFjAU)=$$J>}$I<{quNXVaeYnkSr* z?dANhcec-RdCIft^eM#}9Y~9ikihr+L%jM7wFi1d1`do04DB1p0HJYkL||WgSj12- z>zOxjK)8LVG>r=FYYz?!buJ1X5FQdZATZP(7+{SjT8DY@T+~0(%YTr6aEO1O5DIA; z91&lDg>=hRA^r)?C8XjeTGc3wZl37R#Dq}=MR5(@AD=4$B_Vo`5;RG_v$~ZL1 zoOd1@B|jJX_%@kW*ICh-84zr@syW+a9xf4i^;ajyl`fqfQSOdbo{o_=$0o-CZCmXp zgKV|$dyJh$iyQM`G_5Y8V07IZomLJJdyX!hqc3?x|L#%yNiV-BBc)oZ$i3|vd7^S| zN>QWFY0(dC5oK`Mv;X>9NX7eE2C5N2>0kSnzkd&d%Vu_H19a^S~w)0bR4ts zIr-*`02DtEYff~DZK_Ocro=W?DRyErHF}#Cz1>;(o~MP!wUDQIow=0gZEEy()jEWE zPjkhm=ZW5?SO>UWvDQv}x|T97vCl);gDqHx6oeWo2HI2kF{?w@qpv%!!o=rt#y^*j zGvEv}uGuv$`nq*xJ;ruUOG|rh3(EH8fSRK%x}rDwAso>l)&+@mLDIaWc}a7U<|Oqb z^(1vCbtkov+DLU${l#mO9-|qQHy10g!zw%T+BDUOz;oBaInUWXcO5u4@}w_&;o7~_ z>>Q1~-8+m=u(x+~^tSmNkL}^@es8nYLhQL?-J&-uRd(AWqLUSSmGq@im!p&Qi0oY) ze{MQ&(@tB7r*=BEfM0ZiZqJsvg)dt~-Rhob<-O=|^Vz*I?a7l5vP_Wy?k_vVlQMZQkly)F>h?Iw257n z=mcxlBRWNmI^WADp?jh;e=le0@$vs{|FiPdMthV|e-AX63 zECCnrv`_h`{>Lhu`uQ~PtNR}-*WdR)8D+djrjBTd#;Aj;C=YK?Xa5KKA7?butdpLI z$yi{Oomt2Kf9rqTOR|^r{%2i@zwLiKS;e)mGRJ!{-54Rr>@!~3|5&+Sum5qDn_1S= zR{Br4w~C z4KP>-m5FDd%0W_K@lV4{n4 zJ55od?mBjCI%Cr|S&1jfF2(@_*KXckM8R(9`7T@e*nwXn-*u~V;j4>dgtsjsY$n+vMyKbHpmqo0M@0_PXf{qOP-ES>x>6_DA1H^VuA|N&n8-wIw?mJR)Q9 zaTo0Q`6*AD*t3yH8ok@zxS?sOS>uL2NwvideVnSr4SmE;+%xu3DE19&9|!G06Z3E~ z89Tb1YQ!+BJNM;KwDi3>$eOXgvusgy++BOAdz+nm%WkF4-EEJ_lYWvx=@Z+Usp6NI zG2@pwF=K7|+0(yv^wv2XTSj+Z$D!6zqAI#2*h|*(SE5R|U9cD0lTgI z*P=W*3OaSS3sDChX+8;w@dXkNoS_R&ytmovo$YyJRc<5{bBQx!qZ9WwTR)hx&kb_0 z!YY3sOSf6&Z>9Y8(VNuNiJ8Ykf85z8p>4*Oqm#SUzEtwNQl`fu-8=QBBgz)NGmYgG zA8R^SZBsnv=-!dn9GjxIc=cj9^V(n5_0G5y-kF!Xb>`(ZIBdzN8ksfZAFqEEuD^Hs z_0RF_`ZsXas&bnW;~G4%_UD{>{B+8y4%RZ~F*EJnW&BQ$ajV$1RX01QkE}Y_--xwp zJC&?v##rmR!{vp#xczBeY-ZKPq8v-!^kZ>%9!u0O(btvKtc;9OZ47u)8TIJgMswcV z<{Un|I+AEIQ9V+N#pdR&N(HOytdiDUwM<5yi|Ki4ICfhtFo!dvGZVR8tcG}XqDS{$ z>GjW9(>%NP@=J79WviGS>Gj#ntk3Kx7pAx^$9UMu|&X8z&MrGj~J;sk`WooHd(;7Ww^da_g#O%!%&(lBp zymgjOvyr2EbSh_Q9foxb=~u#@JF^gvaZ@Qd%8YQP$0ZGj}=A8ATdZw~5#bTy(pM%a)eG;rdyZa=>a9+A~N$zqI9^(fyvdui| z=fdS2|8%gPypA|}dio?dcAw9FYe|$w(<+zb*zI^2+r<6$LdWLr)-%GZzFx1rI?|jC z)tz`d8|uxtrfKOd)f#`Xdk%YN+N~w*md^dU!d@RUw_T~>V%L2VQdP(HN9jk9K3;Pk z@4d{89z3z*Pos^FZi^ql}-ePPbk1c5?K5xBJe` z?$&FGc%OtItINNV=uCpHrl(h5eQ}@Vw{FbWGPdDBZ9&)5XRPV#&u`qJa~I0zvBx_n zO)+n$_HEm>>vyIi57uebtW*2Ov+2qqK3ihgF5_g$TFKGXM(*-H`5fWy(NCV(Yg0zm z=!Z}2dhJ_-D#leE6xU<9rz1;DbNA@sxDctXlH7(vbgtdW`n0s)xuOK=eQDos!kY_+v`gNb;3gbtPj(XGZEN2y zjV?KP<&*RS*=%!OwP*GB<*Ck%Dp%^-s8S_oJ+V=6r$>&S?o^U{zRr`58XVK)zN3jJ zH7Bmg{g_5M9g*&i;kM`}Y4*->?t`L7e5{MTR_9KR{+?+aKh}HpV(Tmk_R>QtldD7W z$nCs4*`l+ybBE;LoHI5ybLbz(G;(JH8@a6csvoB=cK+&6YC&h1Q*&7*zMs}1c~<&H zJ)Mhta-xolJ)f&ER%MJS8`DjX8D@)#aF6NZ>CnAn8s^EEZ|GI2N~6x(8#>2zuP&{&byc(Mw7YS+Db~A1lr6pd)S@i$ zWJfLRc{+EAvwIhe8&*2{fjP+d*{VplzxC^tc?i*0+)w88PA-&7BsnYVs6B~soKy0S zoFeU~C)M$`3b(fl8dJx6lxjDUN3-0z9gmJGlJqdTt}TYQS{~zXvviGBZ{xCh1*{yB zaw9$0jZsnMze`K=kf;*Tj0GgBaO$4qPOM8UmcIB_`r=fp+Zb(Mdh+P;3T>+|8R87~ z)51T0vGC*~T~z6o5y9xX&6`_CFm9}M@K zKe9qn^3hE=cWP(S!=#-_x1XNp67sCEE<#+^N>&gTF+aG56@SN$5>^zm(Db89@iu~B zojhvSlTuSRCtXY3kgSq3wZMxZeRV9~esLekzjk^S%gj3YeEMI+_se1bd3>9&ZAN^@ zW`8-p69NjXR(LG+F8x_%>kaQ+> zUGi*7f4%r#Cg*c|NsjFJVtoILcm{v|pT{#7+h)YG3P<>2Q$NY?)1}Art&I9=CRGUF z?30q8tDT(=zF8>~FxT!Yoti1O*ad|%vG^3JwaSpSRqw{y#X z9?vMY&4}lxoWYCntjm(ujpvmY;@N{O)^sOE*r`LyC~C+Bm8Cbw<X?s68)QuYR+T%x$ z@r&6YRc?EHz+f}TqjawDx(kPp?!f&ZkI4O1gFHS+2=eG?#5-3!+#lre>#py_#xq>Y zx@iP?#K<6z+q>#kp-zp;66A51C%u!_i`^iPifO~W*IePrE&7UQjP-)~Q1s@UOxU2u zFkH_zh=bkY>CB#a1h;pw=c7R$n>U$t)7W-IiMmzz1^H1+tz+oTG2HU#%E3L|%}HYx z3)$P|LZg{5$yUh9Miz$9&Z3DASCX$A^)pi+inP8m)AYG#-_u;4O+Pm^I&)0RT(Gi+2?9wgQq7Z!0LTi1*chi1$qUKgC-~znn$WFQqfyXE?Z9 z9zC9qcM|U(h_xq2rv!O)c1~C^7w6$VAM?yuS!sF<|5f~NY)sErsZmDEM`xxlUytX@ zwx*w6kGLWKX8rHM2G7_3S-#HeK@D`afit8xXa_eq*~tCX`1UI;qGO4r&TLl8c(|YE zS9hybSnYt;axDEa6;7|WUQ|R^VtA8a-C^4Pw0RsZ>a3l0t#eDS{q{G=pp1EFwXURV zBh;ib#JcnjYCQWn%n{HEo%`KvB#_cxwnS>;{aF*X=*@YpCK!F$X0^hJ5pF_e&*&`$pFYo9kNMW4T4tKrPBPQX>+({XG0UIT zy!5rkv%$h4DeZoyS9MP9;VlKX`1^Fc(`OF5cQWbep3^tfgZK-j%+l1{a);A38!a62 zb;I;DAS2D3|B89b_KeiZ`+WYcJU}{zV;q>B;i?sd~`b`ZX@`zu z+R^Al&$QzI1G`DunZBQ-iy6CT!S~J`U)=wA|JK;8>^Sz!b4RiN!u|_xTmE`1$(x8@ z($14d6O*kUVx-`KRZbY?2}fem z&R1o2&B&bUl9Bt=rdJl~_4=DzhnD{4Wb}Gx%tvLG?Y1+~ZKvI85YPG&n{KmNM0a<3 zzRErA4?g77|Bd@$RJWAat^fJ>w;J0;o-P`#m0+craZ=d#gQkwlHFt6M@%{&I6TJPWiqyLg`Vf$M1|<8-2y@*wcZA!KV%SmU(?erKw z!?~Z#dYOJW%dO25k{%sRS|--eF)GiAtP=_KlTFsrQ%TNc>XS{hwTynvT7KdzJ>Hq5 z8%fEhHYGi#%d=jZjyY%j-DmW!Q9<;`W>Sc^naGv4iQRNYI`M=N-fUs|i^N1nL){ry z>jm5>yLM8wmPB81<7p^u6tD74W*u%Gb9ZFfbT$j~dW^gG@$%l$TimRNC1I`gBX`?# zWhl-Ci5WFfODgZ(jUOoRim@&)NelC$(aWBTlW|VCujZ~K$-xb+y5h`9yW*uQMe5O8 z(o0Rv`PXIky6MO3_q5=$R(VlHGYih^EI9gMA-hX*7H8?nR~tOt$w?!g01!DMMikGU zC^VXRE5fU-FA*LB{p zT3@^}aehrr$Vh$D(;FG4_H3P1zQLbwhE_@6T2xP|)0~S4 z>wYzbG*jmM%l9uUZ)Se$K9*davL>YPW}qSyNjp>XC7n%5j!mhuGu0!#`+dTKoldvu zDS4-Q>a5#UXOGFk1pXzTvNBNjcwu`X0t|mQ9?3yy{q1CF=Um8+- zDJcuhA~mBV>;A#yJ-XqOM^oB5^TzH?mE@filG2@d>x?u1rnlk5^gre5#LIfijpiba z`-n^(&O6Rf-D!SdLuPpyGMV&~1-gv?PM2Z}b?5Y2=2tWCzF3#exci+UYuXv|INT8X zPDO^jWs~|yK~d<@YzwoxO?ogtdaN!pQ4c*}mHlXpF8P@*7^Ta@YBt&XlOjbE6p3N_ z*mzy;<1O-Z#1MRrH8_filsylf$zwyn*)j3w=b(JWj4Bj>W5W1XN&E&Ryx{YWNW%ZQDo4RQGb^%fd3 zt-T>*2O9G0M&+s0NL^}juGTVZdNbvwQLd#mSF2ocMdsF2#ZEssHHdS;4$9xULVxNG z+jb(RQ5f=AWXB^BFVa11Z)bWb+gMJp%}u=9Qjt3eHW@*gIo>v8k-siF`#%3C`&_BZ z7N#GvtQhJ2D1#rt7~)61KO@*D>vxd4ke(pD$+2{0x(`+&hh3L&wq3!xL!?bOZ@mxK zg0egw5et?bV0wR1mNV}|8qKnG(AyX?pP0>{9$4uPBr#ou`WB4stY6u~keWSoDLvni zy9*3?gicnyqkhcqu1jV18`Rd2^1TeX(b6W{Tiaw}Zq=zHWi5x5_JSv6`Xe3-*|sX% zR%&I)wl0RuX=#XSXUb*yIF>igkcIj7w2d7cZ(*+G$2d;>{RSD5n=&mW@eO6_?A!9o zJVWlZu|4JBycY9QtgWjJ8BW@Gogqt^Hc8!>KhE^Zy4+%F*ks)gHYw$6lj>aCoKtO5 z>?f|nU{&&wo?B^1AJTnv(W)d*P-S!lkpoP(FUa{7vPnHJo1AIN-vhI3&wc)6mGy^7_m;KEH>+*Z za+@MK8`BmV+9dU7n}pP}Ngk|&dwrX1Bepduw^dEsQ_)OUW7&*xs=Pg3mFA@R>e%F3 zJNlrGHc2EVzH3cs@z^Gh*l*4`iu77L_Zf1FGzr;R9!$PsrwxhP!vBWBH4NTu zlalCwmXx)pr<=S<+bdXDkz&N`!k0GLHPt3prrV^(G@C5q*m|cLlB<`S=)|Nc^N(iQ zkx(Z1SX%i{z^8B4r!6NCQ-lH)Y+&)T^&ed1H_&IZBz*e5#AQi5m-D z=f5EN9j&q2eL;qn@WXGE#{dkUY=eRoLGi3@cz&pPwktkQd%6iJGU#J8euciRaDErd(s0 zH+|lRZ1d3!Q{G{^N;mpj;(6s$o3xFm4u58oGN0IF+Ewo5*9;kS#gMhX61yU%Y@!{B_)Q@$lj+|`?~!Wk`$}t5X5ACHIK`Au&UrfLTj+gN z&T@TkAV+_jyn!;Pjz!e*9ieV=@fSmi9-z$~G{m2MPNzMUqF-%-8{8WdhU5=O+i^}G z;3JfWjsLgh%{S;Tel(?csv-|on$k6aV<2V`jTMPx{;szoUoNNaA2X#qMxif$!ZiGt zWXhK~dfb#~oM(C$aJ{`~ehY+J^pUkJU%Ho|r)1-K0OBFeR1cqfeT$ zmFeF|KSPyMrX-Vob@VIZvQqnP`#gM}K*;sU%{)lwY8B;beUFWPRF-&hc$A0iJ z>zbhQ1@?KK?O5LiVN4%keGck(A~KnM90=5u0i( z+snElq<2a47FT2q=^1O9GO}=Oe8(|{EvkrX7W$Z!`&9bv&rR9P_4f`|#nV;cw~H0o`5n&<^o73s;@;P6a|v($!o3-3IaDb( zfqOXnv-_&Dw1grvsDs`2+a#{GDwWyy_M$FQ0*5*G#_(;NMO-g(ZJ72ZZ2)gC7ycg( z7s*b(>P+XZWXk0?XeeIr5SGoaqe>^#dSXf=mfa?8hd}mS z5B_P4$(oioM#!7hMNW{`&gLRjm@ehv zBAu9SKGPyD zu{5^}|4)t!|EG-$<0u!2BmMIa+F)K6na{LuKCTzjWAeL57p8wEor(zsU1UG$ubXLa ziQKDKQNI}{#8EH5X8L>~7g>*am_^>-3MewGn8=*0jJ_Cpy(7ArEonId`6kG|R-Vv{2r+qIFZvkffE zXa^5S8`3szcB3wJ=U(A&${Ku&UlG@r`i9xqkJX21OTRK6;a(d=pZf_vWw9M$T#?;X z@^g+5l zUc?kHFZyNt1Y1#Ji0_MYOemVfIH;B?zp+gR_A?MSnaQd4h_>gJu8T85Qr^*i6^&akT2-#_hgLD;Qm~NHR zCO#;LOF3+^khIJ`LppN&p9e7Z4W!>EMxm&Hjm)2e7xiR6l*K&fzzCvmV}H|YP^TGt z9isf^9ADPGrsPLU>Ti#I93Si69;Hg&{f2br{@H~4=jYZvn?7_VeP|TRiZKSye%!{r z%O>w}o)fwESDj>&jSUs?rta3_{{5@My@u;km43Pt{q(OhO_}%|_jAUcQGMud8GGgp zb&<)8J=HNT(wi~l9;R)JTx2lQ?yFqneWvXLP01c%$_moSsLb?I3`9H32%}Dfn{t@+ zXAFoWZkUJ7s8UstB7?c-p(`AAQx@O=PP6_}6!&DNy=d!k`5EsFF(rw5_X}ma3^Jt> z68~T2b`@s>*Thd3P6?qAaBD5v$|G!$mWt zH0}RQu1A^NjIZ*kGU>ccMqjYW+dL<~&p7wSv$1OM_%S{ z(e5|0k1yO*xy%n6j_?elO=28^pK%1rue5=~rrbh;yCPkWP}h1Y;z3#)U(m+ZQrq3Z88 ziR9jT_f4Ly*>1oUMb470VBK}hV0~~lRemP5k7sPnxHq~2_b3#uXi5N9!?!A9!D_T? z(z@R$QmD2fsteE89*nQEQ0@qx(U;Pf5U&Z#=<}G?-!vs_H23(4Od}WDEtti)lk4y$ zZTAO!f@91NA-%>i&Su*JKQd0|r~Nj5!(!)PH~EeJxL*qQ65gH6jWeZ>U6tOvLs`l@ zl%>2wX}ndDM?7yHq7Jm>+Ps-fk;Tc}H@4Ewc)s!Fncz_^>ORJPOdro*5ybK?C7AZ> zK3tVEjIG|JZx5jF4z6sE++R+W)(X#AzO>y2+%LJ0v~0-z1~Uuu9Mag7wz+ubZqB$A zZ!k`~(t`erXA^7R57=)4V~;Frcs^;#esF^Q+`*WQJnu0+zf7#&{)xI*lrbP<(~A2Q zxxAcv+b@b-U%|CeRO!!r<~X$g+gM}OO0=^ZtC_{m}7)F;A z@vYC;f^ysP&TCvJ`tr`{@$6ikzM>1`YSL(oep`_}m#L@AZSv_=#sMpBvV-pbl`4_u!t}r-vy$+t8K@sgj-dCbM{#HkxbRj{9C&`umQ&QyWbgSNw^m!8I!- z@@I2J;-BzCfYKsUxVH(*R#?lJUryfM*BFa)?~^jTpTlBeIrmpZ_LmiD7NE#3>WnY< zw9)Y5nQA}pnLBasY8Ycm8cI_)FLEFCpwAmbzxY)k&l}t;s+6Qo)?%E&@hu*}y8(pt zr|shG9PvOn+b{I1tP2RGza7Z<7c;2ypF}Vn#(C5Kcc3p1;y$~}N0D6gKb7IL z-<0)idpee}kGCS{+!U$opl)#-o}|@S7Rq_PPv3imdKAX8zBd)AP1^~hFS3&k=K61> zT{Y#n^@HpSlbOEh#k0#Hu2B<30$M80KDO@>o~L>#&c3y60mcgC-N&-&^q==>>uqSm z9mkl`n*Qet97LOmBHa;>ZMcR4F+%J_hT{jELGD=EJEE{2szanAdSU{;#{pb}`y?(Q zS|Su5VG)kOjN^a#!vIXd4%|nsk9hZm_85p*{D>pS@-eR$5RPwf6z=>qt`-6@9sBSQ z#XsSgFd4g%hGw6NOu|vOinNX)|? z+(!8?c-4eCI19I_A~oTM(U^)KaSZq1`6c^9DCXic?m(F)k^^4ofiJNe_mF?ONPYCh z2lx`Ju@ArF0X%2Wt}zg?_!i5t4To?OIldC1{}j1UvsT65*wh* zVqA@IOv8FyN49T7-hv&UV>4tn=Z7H7#wnDWL;b;AY=b_RI)$;=h&y=mTao@)fJ-Pi zj~L=(B;p=Q&gVEV8msUK)faGF_z~Ao?mNoCJe)_~gU zfwqb^h$a|}CD?>(D72b-fKC{MC9r-M>kv-h0#!YraTSkXTf;G;2+E;0TH`$o#z&Zqb@&y(<43{V)u1n2l99j&n%CAIQC)|1TL;(HuPxiqUZ33(Ur1{Ddt? zLNe~b*ud}ZAV0iO0oBm}EzuGFh`=~Z!F;U7E}Xy>JVw@y{9GLs;foFkfF0v81@rI| zw&M^^<1+5UHGz1;88vcaqCh8%Ip$eLyBZ3fx z35ds6ScIRj75i}<7jX^up>L+$q6`|L9o|I%24Xm3F$Ih8Bi3LG_TU&U;{iMq8G4`r z+9LpA7>rSf!6*0g0iTFhG>Ou@JBGhF$$kz8s=gN)*uo4a0KU&g4;+# zmTmlZ%P0XK)Il?}haZ9wg)x|fDVT;?Scs)qjcqu9Q@DgHxD9n}kR6|3wKznpYAO>O-VlWM}u?VY>fIT>d3-|+1;JS;x6NOM56;K@w z&2R<2$L}bi?9M)up5VP0oU*l`d->0@}U^Yp(^U3IohBL{1A+R z7>;rH2-EO2zQrPJz)}1Ow|(@f$d3}JfEs9kmgs^$2*+@Ih$;96KVU6(;xI1a1|Gxh z7mgPtQ4PLmg?I5DA~6PWn2z~aiB0$g$B}|RpzY`Spa4q32X)X4ZP6V82*Ys1U<&5o z2du|V9Km_q#1mvaz%il}s-QmJ!Mo^<{uqQYn1rdAi=|kL?f4a^k&1iJ4iZlkKq*v( zFPfq?I-&=9BLMvnhCvvGiTDEZupFE53r^tzuH!zQ!1Y(^1@gcPse4itn)j z2XPkH@epn&h!Luy6?$VRKE_x07E7=eTd)^NID^Z$3;iT*6$MciKB$Kl=nQ{^VmM+k z8MCk$Yp@Bsa1h6F0oQOBX|SE*Tu}&RQ4PLmg>DEyIEEk^4t$PTScIRj5xZ~@CyB3fgj#O7zSf3Vlf%Buox?mfL%C@Q%J@wJb~?Z;)%j2i)v_ychDKV z5QK0H!#Koa8s=dIHewHs;51Tj8)6nA>uncRFh@CiqW4M58xP`lT2uY={ge%@a0eGPV%ApFXqYfIN1v=ne^hO{;F%+W^ zjft3qPcQ}3@D1kSd#u13Y{m}!g2On0v$%xoxCiA5@0gGkIZ*&bQ3e(97JShZtNs;5HsWuF*D;9feT}RZtVYXolA40zU*J98nm7 z(fAPYn1Zh`8w;=utFRGUu?q)~gfqB=Yq*0)(5`bmkP8Ljg%YTM>ZpT;Xo2>47kv!7(5w3c(xYQ5E&k4DHYrJ>ZXEL}D1C z;lO8@fp4)GE3h6ra1f{PJ8s|s^qY(;kPqG{kGD`4P0?!YGM~sEXQXjMjJ;{^*Yg@Z%ccr$(X)zmG2bEKT?w zVm^6}Ppy)yl1)7Lo1r%(yX4?g5^_my$s>6spX8SUQcwy>VJRYBQdElZqdIRXAtm{7 zSZRLrRaVMLd8r^3mL??_8&#fP}H;ire~q`h>Ij?zgwOBd-X?@Bl6EPDqWta??5i(LfkWn&P#>iNSmT@v( zCdh{}QDP)k95PAbB^GQ|YBNS6V1Rl~zh?rH#^7X{WSTIw&2LPD*E` zi_%qjSLvp7S9&OZN^iwq>7(>j0+c`{NO@1`rvxkSEB%!aWq=Z@gel?5KqW$nRP0KW zGDsP$3{i$E!<6C52xX-5fig-Nt&HKbN}`o<%6Mgh@}V+OiBVz|hcZctQ$A8YR^pXU zluwnhmqFh!|l`G0s<(hI`xuM)tZYj5wJIWu*UFDu~UwNQBRQ^;RDUX#W z3P0rLLq}9qQ+3r)P1QxUsjjM3P$b=10QJ+;2-t2R&@s*TjfY7@1o+DvV(wougVzNhw6gVp!d{%VLiKn+#H z)Npm68lgt2b~Q>Jqz+bxs6*9Z>Tq?0I#T^W9i@&|$Eah~Xmy-AUY($Rs7_R4)L7M_ zPEzC4kJOLVc=Z$YQ}r`-vN}cmT>V0ws(z_XQ>Uvl)UVW;>euQl^&54zI!B$Weyh$? z=c^0U@6?6rB6YF)y}CsGL0zgYQ-4&Kt1Hx%>QCw_b+!7lx<*~Au2a{m8`O=6|{=ln_4BUvQ|a& z(W+|Iw70bCS`DqHR!gg`)zRu|^|bn$uhu|os5R0WYfZGKS~IP=)(mHEhw65B_S~sn`)5ZYqP20_cx{6A zp*B&A(PA}+Hc5-qKGHtc;-)g{S7_4 zolO5h z`kQ(sy|P|K_tC5B)%3UY>Us^mrd~_0t=G}(>h<*cy06|qZ>TrY8|zKuvP5dON+n-a+rEchWoSUG%Q{yLvahyWT_ZsrS4Wsa`Vf7nK1?63kI+ZzALyg>(fSyD ztRAh8)5q%*^bhrkdW;^cJM>9>a>hsc$9lZ}iTK3kuo&(*)x=jrqH1^RdTLVc0GSpQyMqW_>T)tBi%>dW;N`bzyLeU-ji z|5;z7uhrM->-7!#Mm<5_q;J*}^)32VeVe{r-=Xi+cj>$JJ^EgKpZ<%!Uq7H9)PL0v z>A&fR^&|RGJxM>NAJ9_Se`XBmT{hoebf1p3q|Kv|cAL~!_G+hkEPz}w{4Z|=E7sF<_8g51w!`;Yg zWHUSrPvZ?EyOG1lY2-3;8+nYpMm{6IQNSo@6fz1MMGP;as8P%)Zg?9djFLtvqqI@R zC~K56${Q7oipHBpC8M%Y#qcqz8r6)qjOs=Wqoz^IsBP3S>KgTo`i8I3z-VYRG8!9A zjHX62qq)(-c-wf#Xlb-ES{rSQwnjUnz0twwXmm0<8(oa9#=Ay0qr1_==xOva{EXg) zztP9&YXlg9Mv(EI(a#7r-Z%OiA;thB)Ce=eje$ml5oy?sC}WT@*cf6AHHI0(jSH65|JBsj@oHl`;1?V z{l)>~pz*75$oS1TY#cF;8cD`6rgYvyfTXEMj_@Ma^Pnansu@ zVU{#YnWfD#W?8eGS>CK*Ry5xW^J>MS=X#*);E34 z24+LEk=fX6Vm39Kna#}>=G*2wW=pe`+1hMlwl&+C?adBmN3&Ij&W+kvu2iXF03RIX z-J)_Ozc!sZw(ZnW>esJS-`lT4cyMSJ|6seXccn_c0fBZt?JUx_QCMi-sE7zYJ8h`1 zZ@UIfeA~X&pljD|zTN)1Q3K!C+p0s~et`i|A%PKX!$N{7_N84k@NLn}S^B@o*TlC$ z!_Ji|`=%etzs%g#S*Bm>u+a8_fqd4Pf2h5o^(k$^q3^XM`TIkE#fEL$wtTH^tdDIA zjOY>(%%^v~<_7=Cp*=mJe{UbJdlnt~@^Nedej!$rUWnhnETBPy&V0CM#uf5=p`543 z{O=Y*CH?2qY|!ZK^eW-k(Lb_(qcA=O(D~VZ|MCiV3?2{|@#CYX_>t#(7Tf`bB1TYkuh;R`?GG^ZJ{l?;>yz-NIkX%UC(2Z(z9fiH*-+rKgoB@Nd>O zPp^QlT>Y$9eZ}hZo$?u(&JSr!?-l+MnWxp@U*vnKuxBCkx7+>u_WSE8|Fz(Mz0Ke5 z#Jb1*yF2;2ZT@yA5rIL0*6lO!-#eLq*eqjL=^y>+XMIAb-`_RlXW@FC+%Fb9fJz!NRpU#gQeU0M(A@56t4hoEjjOt^3GH0Jazkk^5FChwh z-7R0-;j?-e?i|+m^$+~Z(B`=gFE}G!{~u@H0v}a%{D1QxED*S>M#V~%R;<+M&q#a_ z;v*p}1SJp%Nr)KMkYq_hUQPBUp$Y_cS6QyBv_Ea@-_q7!%db>ywXFzNu?e9>d;-2e z9-_7FU4u0WKZqLH|99q`d-rY#uO^@Doipb>XU@!=nR7R1SM3a4d8?XWX}FskE6b}r zkXbAZPO~Xb)%V%8bB4j-KhkQaW%g6`eu|2syE^>W)v`sE(5YUxr$MVfovc5Lva(V7 z|FHFo+^uBwo|<0#Z)8tdOf*$riGRt9C9sr$S?N>)!{WPht|>aSSlaD{-BRJkKa4%i z6wa!&XqZ^3vdP`bR_iI`yC@l*EUk(V*{4;)XIo)l^Z0+h{I8YW_>Z>@g1z1R|7uU3 zv9$f7J)J{cEQwVe1d}E&B*+=;05)@_mD_AHmd}Qgr>N_ux>@JifENZY>`5q_TCBsV zk8q|9c$VeGa%lCBXUs*DXFT4>ZqDg!bG`cvXB*k*;3t+soIFH<*fU2g-hNVu z=A3!+h?Y-h;a)$$3XQgYHv2=gZ{L<@J0^Rb|EQ<4-^5~&L_&9Uy{927%bMeatdi{f z?0M7KTsITBkW|8ePe=AV}!zdsb{<3@YvBf29!U|BAXRr2M&taGwfrJW)<2w)@`PuEbA_^ z@oY9J^jIw(<#!g`lu4e1*g^&5gj89*OsQ`K-^&K9%z-uY z$%93VYn2$J`W$JVto)=yU`h5JRK!((rV>+|DhHejqLOPGd8*DZ z65G6+vc#NG&DB;}uF-KvPJH@+b3sY=bQ&H?&eZA_RyNJ@6je8QwX)j$riOAHDH@t! z$(*5QvxQj&ML1KEqb263P?CLncJU3-%u}p2hG1GcXXx+t=n9)Ia%;Y#i6TB?nQUMd ziWwDz*Yx5WL~&PbWgQ$ycj7=QxSqyh&OZl-sR5fSN;Ip~%!Z1})0VUbbLtf+s48o! ztYAxIwpNKV;-Cg9Z+}`d(a>OA%nL%3BTSMreW%L$dF3!6ya^O$Srxw zO2_i16q9ByOPDjz)htWoIwOVWQ8b9nk2JDC3M#!eCY(`SSM6=iG8-J6O`%byGaXU) zoac5*xs1lney3!gVyE!128xR_P_LxAvX({Apj<#4<<4G+GgOwlz}uvido|h-XA!1A zXn+--JG=Y`T6I%pY#`>WPB^Ejf2Pxk$$`<{t%J>f(zR9jw1J!ftN^5NgAiY zvkb+>bjzW;bFM68%egMGX+gQo>Sx0j(Mna7<%5RRfr2P=Sls zmY6eb-8pmJ+0D(BV9-I!lFFVuC5_J>ZdpDDEuU+hDOz1)p77|MrXzPT1%l0f$ox3P z6fi8Dw}iM_E=t_ zhukrZ3|QwumnvFyW?5aOdtq5~WtQy(lamcv`%v!(W(EGJEaZLqqhp}D9$2Ocn*@wvN?#9kP*{uw0?kK3wh zNvv~_ktbI^3mJKGrE?nTeuD$g zdyKZRI6<717$C*Q2AKOabx*baw#rovT5SdOoxP~6x_$uvoZ^}jB)62h1*ffks_t#| z(eW&b{hsZd&3*^3cd8DfvYuvo7B(pOm~7C~dxgaoD)2Tmo?Xeg)fGzyQ@Sh_S$n%1 z8*AMjt$vXE6j0&WlMCI`3a3xW%5oLoAdL$?AXRy-tKc*nFkQs%3U5PGtU9J0Xi_Pr*eTSvt$blULVmSNa2yuQGpI#@CE}%o z_o2E1Za3k3fw54MotuBtv|Mp3&~0Y3TH(COawnTPV(y$JJ=;_X4gtP`D1^kIBPbBw z9JkwL-fGGBHo^9+UQ|z`pkqq@WcG!}7RhO-YlQEC%D88u1Rquh7HPx<$J4gaxWww# zR`Pl}_zq|bRyVwovb90-#ex5%)=n-t1ySXu25Vp^7noCtn0-U5=u1w$y1u-jzL^{i zd}-5MHuJ^-C;@{I_MEIVEiFx)z}?l&xVj`S6R}0u;Gr_PIA+@{N3s`P^KxAIbEnUm z>CT@uedb)(oC0Yw)|0JiT8nOUQ`Jym=Tf+($nHF)$%(KlFD1K+#WCXtT4mD`cYS56 zyQ-|d0@p@qOz=D8LOn1)MhoB{LJD?dJnV&2R1*!KI$yTV)BE z?L{%FdDBl#pZ~ljxml)zYsH9Si6mOJ7KjDIX_vq}@3q?6aTn)`c3PVUU>Uuz(nIG* zs}tOIoa`dL5b|abD9!PBcR8&2bb1a3pDE8Tzt}0lC z&pH^#HHeP~O!strTaPO@EtQf%&pZRfuMkxrCT%Kfbr0Sb=aR=SYw*}85A)2~gX{p* zBz_X&n%En%pspHI;JqWVc-2pl7h74YuWZA;Bisrwcfh>6tlEQR+N!rUHbGVhA(Njy zZF>IXX>{Umj>Wr+ks%KEF(YLPcp)3kj%|bnwaT9b@5I(PYX%b4VyDhy)#}e~r1rvR zF-$JrGC0xlv-!I3$rqfU71+GyoWVIvXay>O8&^$k^Jd>*{0POIk2n``HLgjEhO5fJ zx~4i2cT)>l`h&CGIn&F^8=Cov8(93re?v5%69|y`cvMjmTt*N6r@wgCHY}nf9@nQ4 z(AdyQ57`(VT&ej7O zZAZmo(1YL#yr(K%R9PNvWD0DNa<4RGM7tJgtofibrf#k<0You72Be@7*-_~NHKU<^ zQB7T=7`{Lu{L~aR<_h2-6?ii~WA$$l3r&+VRfKO&&gO-KJOAVy9+2qUnhcl^cmC%# z6g5<1rNN6+mVh^^%L&VA(zBdZFn7-MnbYRZnlT0VXu>@M$+;+$M=J{0?Wt{cLkqXC z8GVC^fdChniG-;wXZ74j*C^=_X5ngKz*M@+8|_$OYgw4Oh3;|g2X$z6qSY_b%9<*0Z;Yf_G{3B(!YqTg6=*zowBUhT2i0I*+J5eGIP&W4{z=+J zmVHA7u*I+&C*JHP9w_JiODdtPmR7aA2_Y%A{;^YVzR4a0hiy;gX5{3RHO7>(VW~Xd=-?s}HvUCclvj}eM^!g9$V#MRWfkz4 zs9U!X?lI8e44{q@;d`JtMNbKO}7^;8xpsTVn>& z+Gw@LEt%}zXh{dzg_Y3;B}jq;V<7%*s-z36?nTWWyv&GLD^O(AmNhoAM3G5sJyUiH zj3uH(Qp5hPEAv)imlMLY)%wI07qE zXa|DZmTqR%Y-TrjJhXZPOGz{Ye{5|F4^`5h?Dy<@Q&5P*$Ev#V~$3gM*HdHLc z3X3Pv4Uort)>28N@dB90spg4$8}KwS@>y#>&E{$W5N=^*CAQT z;;n3MEo*dZC_)`X5zs@hgrn(ZM0zo%ayg4~ECo`a06Zu#6~shI-2oO8EyvnY8G6tf z5zuNq8BEPxT@(ZBuDm8lB3qa_1IIklSr&Tq1`c&X6c703xUfQoj=0Xvfp!B)(bTHKstL zCMHfc1d7ljs=7fkcSYqwZ4s{cxvLr)7NbOSIcqQR+LBVkXvVj!*!ibaado%S4E3hl*+spDAd>CQKu( zXlRB4V5w#)j|vUL!3P!9;Jj<0c~q9SU>fwvDflDF_^a3O+Bq~$g~{X=NGxs%{>lcZ zS#&}MRVAMvO~)Vlh()9iMBE@43!GVri-FV|J-~PT#7M7OA z7C3MyZV$6BV&h;@th-2JPZ3B{rB9lwr-Hm^czSBJ=Bj9U?5J|wenSTBt@4> zyHLZ-J=L{{UDsnv*kP6`ltonWz)+O?i9kuvSF@ zTlFYuRuiyU3zi02t8EserFjZM2&2K%SY8Xsi4u*~l`woE7zu_Wuu=fz@F6w?jzJLJ z0_}L_Ne_0UBoFOP8{s%9NJN*iSHy08leQ^CfAlajF%w|KmY`wTwk@F|| zloIrjkS$9tdo$w0Ok4rT(m*mP329Q_TUlEhtxqXYSVFceDLUkib}2ohTu^yj9m>i=FdRv3#x`!bB1IvhwlHt0Ez^i2IO+%#B`u>CnNfzO1eT2- z7PUEr-6ozf=vGK2pexF4fW1IPb@O6jTu~`-1@8OeybTdVX`#kVNURvn_P8fi4fz5* z?0YZFE_un7K4n#=+x;9LO*8X&(U4vJ`-r4AEUH+Zu~%8}RZzXhgmxh_FR< zCfk}2^Alr1M_ZP_#;P(2dc8{sg)>SMo0kB^Sxo|>SVi?BICi=6 zqNcLODgnY=s~}rarW#sd>u{O6g;*zaM=hJMEeE|@Io3!}j+>S_wr-HK*xsB-SnVyw zixjdFfl)l~Q8R}VwmiC5VC7N5%A;Ay90D!8y}8)d8f}d+Y}G-;uiB&t!)6Xdghd|# z+j1=WAjd|Za$W^7Gyz+6Y?LdHp_1xE^4bYeT;-xNIa}CKfTKCY8)gMNp9srZ=EP97+(uOaTdl#-T}~T`x@S0=v!rez zsWy?t2`dlpqgrEN*vx5;t~i4h-nM!;$73Z$PCdmQ;B6<9L||--ZX1uS6UY*4_W`yR zwbi!o*xM%BV~`D>>So~|HFeZ$G$CsMjl61^ClfLc#{sT_r^I+0gmgeV0<`c#Ixyap z4xC^<<5plnnmorjn3lu?vf7b*j!RfPM=41PYb?zcbp#|@fO*X(VjaGkgCG-Ig_R^+ z73&*<>Y!7_(=3CpauO&2CeEa1GgH>YHa9Y1;0te*lxeQ0KEFmLy2eyb_&%mWOIwhKt4LN z2ZGHW7&db(A`lnI(##NIQVd#nYp&&hEUZZu8&#sCv(Mg|ylw6T%7HOxwu)n~SZg}; znyXzOC5N3FHe$rk!ep2FD8JO33`2m~mqjug#cTw#)2ne|6XY4lOMt8op(j|5025aU zrv{2ORklcs*-5mIXczV#%qrc{uuRMh1mbfIjhs8P-vhj+P1^Fri&3 z0W}P#3A;zlNQ!wbZLB6=RHJB!trIpOB!p&6h-M>UCTpWSvjR&V6#1}@VL-y)##rgH z1BS*yP8LxbPkV842wU+S^06os%q73NP?1p=x(S(hFj=#AF+AjGzp0K1-c;u$x(YQ; zpG0k;&FPa;&$q9hx22szhBSOkKa{-eUHaxR!v*|6R4AZ&6HOvIY63r2H z*rs3_3G+gdskssdC1Ht33kX$D!qNC4_zDVK6X4gRH=_ljj9&eNqra-GrJABGRLJJx zrX+l<()mHDSdcE^aAc0Mq+f)?IC-JS~48J7d~dHH^3o6C`rRuCkSVp_03HJ9{plDzCR=Eqy%_@#J9zkjE?(g=8)}HhGx1 zw82svMNQSqAe$j3Bulah2Anj(Bt-NUI5AfW-NPu+Hn@l{g^3QFAI*z5p<1uhMUcOz@_YQaSD=)usHd-6$Fi? z-9;+unRx})FCv#b&dgSol#7mtoMh!K14@8 z6iR?rMS###5@4J-I^xR^#o3VnDq)@;wK}}MjWj*Dd_8=kQNJ$kJ_*mR1T3A(XG>4gv^tDa+cXY4b)~@#HK_&OY5~*N(`IOmWU}9n;^PcwdB}M zCB|7X<1llGO;OFvll5#wvNQ#iGbtu|j-``r%4Takb}Jz&nMtOGnP3`PiP(Z-NM%Fn2?x>sWb#u_!R-ebtjr-NRCVRt6HO%7NS?r zTKSd$dgmwc4Fh03379CTd&ZD?CIGVxn`f=&b%0hY_)e@EJ)0 z+?MG?MQbJ~@ZzxDYM!bkz->k37R(J|pRf~~+B6Ah+4$s~XCq$%T*x%@ zC5{gF0whkdEPV+PFG-_cl(UR|pd~EEAr19bvcS_P2)+;|IyDis)d5Rm+=OKPCMh40 zPmsVO(pw3Otkts3T5)P;BTWKa40qqCjJOepCoUn=C$pn<3yv_nNDvsDFLpkx7&dHL zEz3nfRC!4n{t%H^Qm^o_8K2DxUrRQ{xqM<2Wpou6AusVU0U%%Bp?i6NF(iD{DsWM9 zpg=xR4_^J&as{3SETd9hiMSr!Hm5U*1)vmsGYC!4wPgHNDHYW%3O7&pkUcaiaUDqU z(9I=$**CGUxB#Tkb)RznY(#ZRiBI&(H-V6xN?xDyK3}F zjnD%rcF6E2m7_bA=02BCfu;fT0Z%>%%aIbgSIHw}v)nYZ6ceCwVzbCgA4tlBqQWzz z54wzlC&>fxKrH~`L%<0+z})y*OnTFs$6icTX- zge_#q4rviu#P>OKAhDXhsurO^#M(qumI2W?nFF{gPhmKUkTW31(Q0-mB5{;u_9Mg& zVa%RrZz5(1jMbNjwE-o8TH=mcT4u^CLq~bKoN^U;gjLMboCTnf7E`K3A;L=bGEZf|m}_YQ zRLV9X^BAC*0P` zl_#^8=pe~K4=QDCdxB`+6H=1iw5)&;8^x0GYv|`M&wTM@TR3YN{Ks`tQ(o2s| z1^(`#1M!KxA@P5e=_l@T#d+k(w!0@k+17+VKj1{xrXpL3yFgh8T%FAS5#=*en)%;R zzHh7lN5I79KSz<_`@HuW?*cd&?wPr_WABIiu5})LvhCpB#}90|2ZbI#7AV6b zTdOeYMDh81JB?KKW|qLT(xF-FpWI)_KJq`k)e&V!v@n2|xrJ)JZbjFi?xSyTO!$C8)*EFp_h zXZ{hRIx+lHEfe$kyl13DO!$;WXry9%GzfEqiAa1-gNxt$&G1jX@p})2cjsYnQ&Db2 zhc{)yr@lV?PtarUps^2oo({i^%ow_5e9*@4tP0aaxiXm0Y!Wu`rbJDKf%)5B2=x zz@G56sEY>;Zr;El#A&KI(wL?a!^dY(Ei+S0BY_6@w27l70h3JxFPzL|k0P@_+S}?! ziTC#I*z=)<+xy|(UTUI$&)&yBIP?qcTYEe9kDQFg2!{rN^N!pMN-JHP@uBqeZH}kM z=S9B5Ui~OO9S6pY6Q7SCXmJ?Ynqi7>Tgm~C<3N&cn|DE=!#gDWcTA&e4b{hg^p1?o zVn8``yWka(QraWSMYDlY8TOOth%<9JqL5(=w{IgD>bhN2M%H~0r?Wm_Vu6crdrpae3|SWO(7a~SJ@ z&=VgH<|I?n-Y6)1`f$DO^?44xF&S&&o#eZ3+%*wzQl@v@H7(bM zZfMby{~Vk#E;*Q+?7Q#JiHde{RUDCY%AXxrN(s0D^lYMGR|H8UVF^ZqN?qw46*{L^ zEJ>s>Xij~0vOXs{W41#ZBAB*d_6v>W8{2wDNC1r_2k&$Qa}tA#lM83(&nqb{nGcdi zcCsjA%KC22&E43hcL2bNmxw7OUfI4J|M|WBaz)Y9y|;|>=!xSzzC+7BzP{z5 zig6AtJG^vFoU+EOd&{}hRm0y$-M`d+33*m3TqO`WH*1}Qk2diLCcgZ=*iaEIC89ZvUy76*mKaC8 zQGjL*Vmb^)w0pvLt0Ra3YqJhKN)uVl8hChz_gl9_yz_54;k_Mjy82Q_FwlgNhyR4i z9z8&F#iEVXMnkR<;8nZ1fCKqqk`jA=&-Ca*;hWH|=gQvY9teg@J-7BQ_vZAxV8;_G zt!KSxArX}i44Kyt!3h<8U@uAK{ol?-nnY;x4f{t{0q(g*l%~lX7?MArbe1gLlC*#1 zJ%F*p*4ARkIl;9pcpM85N#nF{^@lV^XbUaLx^?aMCdYXlAa3Eh>fmpatn>=_YseHAP{wy*A3Pr?D019c@g zqGSAghW$i85IFqvvkv*p63p}y^LleT&<_IG$ku1*q(;r2pv~H7GJPIWoU1^qX-s7sy^Ey<;_$Q-Qvx^AM>h$MLO11@DEchx@k1O?uV)rhkWb zwm@nG9M zp^dqc9^SX;5vMs;{1Z*LYugsM=VR{r_w`rQXS&6$3P zPaZ`25yF8=l+PLXu&*!G@hx#E-Epr0@(zpqAkiSrNd3GG%x`9#ystK+ErZ&XKh#$r zr#En4lyBzQ`=UC7F4zEMcm!(Oa3oR==j(Tmo7e4n=6fJ-x9eGIzuUE0JYE!!4tj)K z&*-Uo^XQ69wl}=z7ZlYf`BlGAHnbHP8$TPSEST>*p?K3mIb-vU{I7@75#b^|XY8$M z6LN~QWIbmb5a$;}cJ_?abH?Ns8R^F(5s17RMbAkw-bF%xOTQ~o|Di)~f=xH>ZW!{u zor=ED2_rDFFojGr+t>-zNsbojT1w!U_Zr_)hobuLehd`JWjpC(EPbTWM;3kL)5ksZ(HIK0gZ{bN&cJT(HTu?0Bhfn? z8ED;^s~z)wq=L>{)Ax0LLVaF>KJU=_e1{UWJLb<5lPrK<@O^zqec4oB_>q|7JkxJ2Fb0p5Q3;(a!9QJRqM3QqN2Fb)N8j`CavaM=1FQ%BX?$ z1b&&m`?!|u`)XKgsc&nVCwLwNRt}wAGD{sze^2kgL-qX#B|X77UpQXf6z9<|Mlnxt zD3ZSJ_{=YxK1uJOQEp9EcxdPi=00X5Y#SW>BBfovt;Ic0=#iqxjhlIuuW@3Uy@6w@ z|C?{Y+TFgOYgJtK9okpnY^Yn&jLY%Z@ukU<1=2e*T*)nC^gKs&0X@D9#XBquBhGXs zH+_yyI>xG-I>MudV7c%+NvXr{Bn6H(EZ~|o6^i)1Mj5N*$=|VzBg_){t8mVBjK7X? zR5u@3dS=V#6s1xr$6uYY5TE3xShHrP(x4zR5rdnBQeNQAQU%Cw1jb$}ThWw7_=9_o z+qna9EqbOl39d(J(RU+yszx4-u?%pzQU!P_@)shdG0v=4hI&zq7_Xv;F)E4}m!gRA zD2f<^qKLl5vtIT?EoNiXG)vL1*(a5weyE)?j9x>T3P55EQ<18+rRQR_RHE62E5_I> zc!p8zT$HM`mC6JC>TPujkRO|-zG+OwZsQKTh)VUc;qI#ikjKHWHEX6;E^NZrGl?=~^$emP1??+nm)ca& zmV$QhSFhxiEm6=0o=pnsDtEwtT!1@(h%9m&Q=9PZuz==PX-&-%S6o?ve{(4kb2S0w zHPkbr0RPOB%A*YhbrsZ8P+mbf1!WZEV`mo?M=s3Au8rLIEOxNoXZ%+`cJ@xOiGNfN zAr!f=7Wr=4%qVW`K(@$z9k~Jvkq_Ab*|mLYvH~%4p6&>a(z6nSQxj336bDkH6V-xK z9eQppa&oJJGZXbunIjL~v9V1JWc~~dO-;-ka!np3Z+aP`W2)m=R%5)@;md7|N2_r? z&w<4JQ+3yKe=^VKbY>6Mj&p|amwE_?cs{US@9IzgThR4!ez4MrXz;7_cf0x_fFf|R zgj~JiAm63ueVqQf0imLVAA)kp97$(=HE{RyLzN?4#z!bm`s%44K=pMvY)X>F*zC<@ zn0qo@4%Pol41Y73Fr4%~f~301<lCS98A$8-eFOr@pQUkxt#5^?z zNz1QZ1O@Vv13OgzX8=<_N3~JDzU-!9zP`KE`xkv1C3iwfM^XR!3Octl-UID5#FM$x z`-ZydWp&fm)J{_e>#md{EQQqIBSNMIj{^jutF9acAYW?mzDovZa9YmL4S!3+g7|KO zQhRxEyb`%7a^V!PLbL}*L==f!m<7DFB+hbu&a^na(m7J%h8BXEGFy-jsv@w%>#RAH zzI)#B&!HjImFIr~fd`?E4V*h9eF3h7s=_sb3VlIMk9DTArAz9VyXw`956U`N>dksYh){ z!rx4o84X1+Ga43+ciy3W=KE0fj?+6k!!ZM# zt{vggdxxz~S~Ya)wCURMc?;Z9)nY|GdSSA<$>Blk!#$a=c$0k{@jd_cWH`O?=^d8o zmNFbg!ImBBs&?#fQ{#g@jd`#qWx1l_^kZcEeSQq$ps$21n>+pqCWd8$61~2@i1$d( z!RMW{OENoEUv^!*^87vUcXH}gu#@j)vn`yy9q>G*H66z1q~=$k?R`d?>}d9E9KnnA zr8J;GHLMEis`h6%*ux<8rrQWfrXC+`T(_e2R_Dw zHkazZ2PMN5h-Rhl4(ou`O`Settm^+Y&hgZO9~}VzVPKXj)b>J|6YwK8<_l4aj&K`b zkMGN?RlkO8J+Kql#T~=dO*=wU96N)Y4i})17y?K;8za-V&_KXB59J_LlNQ=&Agy=J zVvo0P3#B3@+QINRWRr+kfiVkmMhZtC-*ah4$?=_6xROhH>ZBFx#C|9WHAd8@wUmU< zgF<$<3`qbBr6?`;_?C`Vymu88XTH&zq3_w%<9#yda{4Nrae9}Q5XwO{S4sk0OMS&y z8+1X;>HS_?O2X2V;L>Eh3$$7(5t*`ZB*P}2>YWszWFO(bhW)f*J zr;?DQB*i-uT`t!U`nfSp$p<-<@na|E&l~DcZca-p&c{NI9ZQZz#c@y7J@`?Sw#GL6 zI8Z_vsyG~YIPg2v!6Wn?b_!=Y6mvh0Ia>0usmWQzs{h75Ebi3A6Y8oZ-;Y!DQ6vj+ zC`pRPwsJ2>e|^5OurCskYTMi+mFYga-AqE6v1wWu1u9J9tEg{3N6K35}fJ(R%FtM%nz1Z56 zOSPZi+LVff9|f!j2(~jerNci&7Hyoq>E2>rUzK;Nudfzs+t;cF+{hAR2GNypK9U~a zZME9P2}dLv`!Kk%gPKW4rWmU;e3b={4POda-IV0(yGgs;<69Pgg9g4yl+{5BS^X%C zCSPB=C^JEnSx4lFEQgIHy4cBODpY?r1J$bkB?cN)|3(Hh*j5a*K?X1|Pxb#l0@nQs zO)23Y5Nu?7ovB^k68t$J69Qk;XgkMt2Y!Y!U{)mCVSK8g-Kf#cltnX2_!<;A&XOt(B-7GGD`R`EeqzSLjcvgIRSlQ;aRdoJh)AvR*i<2I#s)XOP5m)@1OvYT?47(S@G_pEz-^Xr*nxx+ zdFCm!7vlWxRIt5?g5c>8iME&LS&Mj zn+OG;E+$62p#Bw9qPcj_e=K!tcYsDnqznHqQ=5`X_~(Fa)6O^kaUphAI6y`ED%A&9 zGO$Q}=trbo`mmnM5G3&R)qAh=^)*2LBR@v!qhm<@8WfWJ17e5gBdJ3}%HbM6$Qi=o zHXoUig5G3AB}g87f=N9N0S1%014IcPbu!4V57mnkecg_5HX76}^7vT3FVafI>QcF$ z*%`dj%aVfpT*18YYve4uS>H%}vSNEF3KkjHz^W+;2DSkO`Z?|N)%Wxa7fn({BD5nI zSc8K4wEke=5dd;oBO8e!)t6Y|MYwsfBKZ+ss1VmG$Tu!MI#kg&_MxzE+n5#qY)7-$ zz=CfzRkl`O%=l!eQc_~g>w>^BTjsAhvpw@#?L0|a%mZN+TH}K7WGqlk+C1>gYe?&? zlYJetk$wZ|;MzU-4DSZP#Q=|WLZYgFoz~xzsBW6p|5*4aWiiRZ--qWJBpIP^Z=aZk z6-P3{oTT&Ki14=BuB3%4kn==-bklTUS!zcO?d#KE<14mbmafb#1jfTeRpszZHC}l+U~)%G(92mJejYm{vUyTYU1Z791*mU0{XtCq3lC2 zIp?VlJn&ss80t&y#;6T#IPRz~`L{aM4Q(|;JNpvv3I<5lW^QdA7a12gdLbsxlbJ16 zDJm+AWl*OjI*WEFh#<4M2dr^{{wTGe3w`)%9u~;mg3EYT)5zkUp$#vxJoilTy(calBK(wo(J{ zp$WiHdurfSzz{pfI>)MkM8qAjf5G^wzv2HPk;kGN;rzhv<)hRG4~}CiaOJyrN;wL_ zuYaZQ(c;s=hcs$M4b5E;C)EiF9KCBqHx5Bynb5|s(M9-e;%9P)&pwuuoK>Xv>O*1s zc!&G$C7-(MQcU0~n2X7Z`tW)*0Bb%tbit0UJ3YRMigzfiw7@>?i&WleyZVF*^KBsx z!hD8O1t!n>EbpbiBfCuv+=}6@k5dCHaoSmrGr|fybv95^w-EcJZegmjtX!XrBVI&( zxPsh08wsy(AwJZZ4?`?FppuC9jGIwJNM}b$i5mEyqqG-^iP7hGXduj-fqm*j7f@;o z$)Ol^XX?4%Afq_{PGbR<5GpPhcn}Df+Ye2EB#vyPY{7tn{|pBXmkC>_P)T6l@~0$| z-#1bW2Dbg{$ntIBJ+JypiRhmZrmsc=EA)Av0Lyrd-jZ4{KY^4Nmn^nEo$(>qE+OFs^l z9y+pteEa_M5cI@Z5Z1FJ69y5}nd7iE^!uCN&dfTZYX{MaHFb$EBq21LOddeEj|6 zdwlOJ`YVWZ?WKMeY{g-T!%&BDB*IBUL{uI?6ppF548X+8RR72T&I(#eD6iMZfbP&; zy&3aT)WEmL(_SP3C#lbk@&p|danKLkib{ynEFglga*VL-3Un+_qK)rO)mbJ!HYdNh zzzAc_eVu8+wZyt0#aF&BGt`Hh#wyCHQ8Rn~8VZnnNZmeF$`;_8Y|1da z4UzA#91L$jGizXAb>MW$Kkx^3K+y2dPi$}qFd1I-^N0M=sUi z4Lh3c0i(!HI6LmBN&y*a;*21MUQ(j>W*%4ldr%v(CGt#1Zp@!aal}OORigr2l0|S% z7a4oFeB{FM$OtC+W+q0Ah3ExqWo*K#cCDfPNA%bupJv+Q{k_oh*s&P%jZe~vpL{6B z_ffK>#EN{8tBaVQohz-xDSdE(KzRBCZ(;Amc)Z@L8EJg*395HRZk%fkSnstWWcOg0 z;lF>3^}JJYDRU6HaVayDbY+6_U&<6fGceMcWaDve1GJrZIcWPkq^jC3+kp9}pgy*L z_td-BkAXt>I6&xW!DT7IWsTeKe;Ji?w%>mzq;O96)T$294dY3rw#X+IX{m}_ScL|p zJKVs<+6X!uP6dKX`ypC_Q){spjwi@54>;0NYutiHOUxQ{PWyeEN#h@5 z%*-d)hc{Bsb~z(?4(%WM18<|i5Nahq@-9bO^#s@|?;zE)b4^lv z`~B@J+TrL(xWE1WmF+1*hQQMi2+&a{Ev-GjeU;)+#$PotzqlQK3^+UT^H-s%vE$oU zwWF2-cSluKmBTT#t+BDSvGF87$6&HM1?<`cURmlSd6fCJkln8X6(hS>fVw2SUqePH z@phKpV_15RhM>xi6gqs+nywTG@2fMr)Cc#Y9LwzAQsZ_Z{(BPve0U=@SB&jGMq;is6MvTpR9G2SU>71J46tg{8r6|FA`&FXAY4 z5=Ei6$7g=t^a;X84k^x;I-{=XrD%gS68WVc2HC*8(zodo5f;_IWi0j*Hm<{1{aq3& zG9Od-=nfw84(+?Gv2o~zUQAns+)$VcADcTq$NlxDu(6c zzYz5UyH)>VaBJ#IS-Ly~kg|qS(|Jw`4*iI7x5AE5{olpSZT<7qFVs!RNl;Q^I^LvN z-h?}~9$1b;(suw&QtI)W%rpqjQGs0h*4!Yw4?Y?1HXk+PEsJ` zN})Rvmgm}qoy}&2$)ey&c53dhIW;rCgj4f9V#SNtsd(<*wsgj zNYgD!KbE1vt$YbM=C~^v=PFov$w*)pkqbYDP=cma{m=XZ#fBv->z0nl@X ze9pm>3BH;1t?zIOg+slw3UEsZT^u&v`4IWqVSOfSH#)m!pRb6pX-%96oL;<)*Ti@n zVBx1k74UfEbYT`puDx|aCU?=K!^m!_=7(zAi^Yrot@x7V+9#qQE9+8m}b1r zZG+k5eI)1k6tJvu7$a##2^h}+UpCnpUV||NCx+L6@$m@K1~HcZ9O?i;wK0G7w{3#!ta|T{X#7&wLL${T=jR+y@M6X3e3O zI-wd2gmsh>2!2!HcC%>v*yurVA(&0w`ZjVqwKKC% zz5kW55Emmr9{AQ163w6>$JHXC*_40Voyo_0pBkq60(DkX~ zX!Pn#bTjoD0-X%rK;U@{-a_E{3}z8{0fSQrOkpsWzzZ3?`&Kf^L>ZV}&mKb8w7B}R zDgo5=u^nNN0985P)*)E;{TFot$3btZV$cPm@h-a9D*s9h!PRQ*P}$rX7Q3v+>K zfAbBmcOyH4F2@4eM<-k5Bp}H>`~(%HVCgX2WsF=%CNCDH4^hH0xDJX9A4XpiE(E+H zV$cl`|2Sai$Q-y7K=_jx;23eL_l^|6P&M$-1rSDCD1M=kYl$3f6vr9hTDtL|6)X~p z`JHOAKEySPgMiuLa{t?aa55IhVhE_Bs_7HJAQ^Bt__mG48m;;(mF+vB`a1w%_sU?> zi~xBOPZ|Y9liFw!A_5e?oSgU!Bbo$Q_-Wg*gyBRahp`7Z{G|hnExh+1V>-g?h0cSA zkRh8oE*!RR5M~`ap29GQL@?>fn97t%m4D5ZDHRF-6!0lxN%tX3#*$`JEGa7*ODaQ_ z^eh7k&%p-_#aivWgo6_81UeIFF-T|lItv~fz5=kiDS@I$mw0^lB8qgrugexi3dd7n z#E&?4g2-LhN8??NA%Bc$o39U%qkRk@(y*HWM2>bafXGn?17Ms@3?Op!2Lhz`7fXZ| z3e<<`-5c*R5k%UKAkuaOk+!RWdtvGOVuMJB(7Tw+8G}f3aZa@bk^X>WG>D`Ip2ixB zmd1vE4cMOdbDY`DyfuJ@TPplhfPsiM!WMt=ts{pWA_e3uBF|bk%B)WELwIZf6bd~H zy!u?nY`g~1huuWs;ZUao^%t0&~A<4?{ z|Dv*Q9VHRO0&F8j7Z<9-IcBz&b$>(h(- z!$Z*^hq0);|1gYIxgUHG!y`Tn#Khvvx;0@qx`zeg~3t-sro6!m)S!}d|jCEVI;xke<90Y+3xCfhVFlW4I zg`M$tpn6Hk$)ScK5*AyS)M{WU&3Wyw(6ApIm=$GUk#DSsu$b{982!dQ?@(z9*3j9r6z zZ6OqbA=-qVOjytxVdm7tFGx6;-Vx+kWN;nz!TXUBnvK}uSMyp&f>+e%+IPYMiMXNu z=r+_|+%Zgj&hP96uEv2^CJ;a*bmmsvTP6PK8>&9=F|EPU(c}&zjYJhp zgkXS&L?&@Ede&bKdr0v;m;tLAUP^3Z} zEe?+@Mp$KcNqPqbRtgbVacAICr2j%U*@G$UYjbuZYC^V%mMpz<`N2X1g@yl3`Z|!y zzNM;^i(okZ0u`X|U?%dEuo44;k>}xbYz8BT05*e>1(=%|jQjw034)Qt6C}B0FtQyC z3<|BprKi&cBdOIS1M{h8do+-2IWro_JCkqg8DH&D(v`N`#>-_iS3A;zU zt80A;J32qRe8ijjm%+TgQ1bbDp^=uO_@3ObfOp26G*m@2V@GA0DS<78>fx zX8_P~C5RVzmIH>LgxU>_xjFL#b>(lV*gSfrwH)n_4+FN6#eUj9r_pC zBMo6625}HQ1oMst^Kehm5p-fg>Py#$k|!WWnE8sjvW!}MLtR zQUqZfcy5Ub`407gc-oWuGUhq7tM&Xu-Lb;e-wV$J!r`BH{@dC4k+btN=ZJSZKXeB3 z6N3&oxAzCz9D1AMc(>9HvnCA}lJwE21ep(yrT!L;F#-xE>=XK=0f{R1xL9 zZ^3Jbn}42Q?r_t^${Wr2<)v6J(T`pO!=34ew(+ykN9zv5;cuGhAGhvZ*J_zl9- z($1b8y}SVr2i~kIrjY4xL+lGGGM2nb4Q9fHJkpdpqp8b-o;3ajEYwf@r7*3ue zlK?1g;IbfS&1#F!N*bYU&Hn}BkX8LY;ljkEO zo8A##en74a+?aSBe5pe}4j0*F@SCT;2Z!S%di|^$kpws_r)&R479L6T=1D0oi>RA+ z;x)aGoFlgG3Ln{U!4A)n4LyGs>x`A-4UCoZCr^f_C}XthPXM6b*bCwCZBMO&|UQ3%%Ka zFBj;d!<3WcI9-0e8aK#15%>w39`-05j>E6wpeL?AQz@N8!}c4ZWI2TY7lp(CAR`h{Sy-23 zIUXaeZ@c>ZB#a5u9L3e=_mG`YINrNBeBB;U;9&R#3|-PU&ry)RyQnx=*bnL9S1EsK za^_cR;JXly8HJEqU%!V7JZ}NowG(KjDQOG{1|OdV72j?oqtp5|<7+gz{u=+<_9f;&h$rr|)$D zbhr3o6hQx_`fsBhL^qz3P*{5pP5CcD1s>o=ln;XS-pqVo_0O+HM|;(k1$br@j=@V6 zU8$YB`Z8Q&)%#IF$)6q3#zwR;2APG}RnSxEyE6*MdB2@{WY>udZM=HFj$%ax5p8@# z8)sZ0bQyKz#Z3?c!HtVP^g=^3wR~`7i64Vya}vjy!#58`#S>v zz7W~Yk?`N()3Y~1)*3f*1u~eI_`Z9R@enL5byMGF(g`J=%s%g^8b`751lr@*G~V|J z&oD`GF5@979Z+E)NlR|U;au4AQTeXtr9cK88p z1Ov2&e9-wV7Fp+R1@ZL|(G!u>z$VO9&Op1ATlaJ8&8q)ivzsOc8q|kJEsdvFjc5#i z#I?Peig^gB1Xd$kUrT+}T#L7TpnEE@pf#xiz6Y?6X^)fcn0D%oC$0uaVE7_!s((Ed zi8SI3LI84YN_lN=ps)qh;4EJRZqKY0V4eW+2E=_NK#YNtIwk@-y((UNp-eSUg?0p8 zBK++t##LxX-L$79$iwUj%1r)7oC0GlnkXr0-@>efC=NE1FEUm2UxxmCTc{hwTV)dI zzu;R$c}YzkjWxY5d3wZd&~-=AOfW&v`vmV0lHknyax3%tsDU&r4#fSHs{cdO#~B^X z$IVy$_1rz}OkB%pLL#=B=VD?s8VhOba^$yfc^N5+3WT-+Ad`wr$n@727~k6-4F?<^ z>#IDZ;QS{}e>nQl`FT&CcpuXLCV(R2eaK0~VGd8nBE?*&`x~<5g*tgmgykTwWJm*! z&iNsilSA6cRe!t{=fahcijeO12qAU)(G;xc)a3O(uVa0d>Nk+&Nupelu^V+t!jEGh zkZAhIXK>AhqOrb1iKShn(MX>B0)jQX1Dc`Kv^JxnkiM9J1>s*o6le`k<{oc3^#*co z!Yq8t=>F+eKy=YT^=|`&_ibU?W+bUA-$5+Pmvn-%^d#?fWJ(40b9^fq_aNeZhd%SY z92cC5Tlz4>0^R=ZYMYzq26x<51x?vDE zGVk}oxy@-`SG-XQ6jp=ptaNzr{T6t2w%7YQzdE};wUf;91(sD#cOU8C!6tbfuVZrf z7nmto^6GO*`Nn1nqp=8m?{2bX$j*GU16IBRL#l}@su>n(OpILknt1Ir@a%h->WESd zSe!d?K;YQ>i(6@>dwrXq0s-RGho{X)k@lC7fWd*4&&A5q(5#W|z<2Y}o{fuyNHM7X z-$6{r5dFFX7#TLc*!N*CxaIg-k`ducX@h);h`NWWI-5Wb$1^H<3{5HbuMKj0(R^m#cHfU_YgH(%XDj&=nE7flfD%I^%l| z$t4-=?iTLdzL-l~7IW{m6R4QGTepHFxVlAn787*0g_+lNDBpPMO=djXwcB;vr0v?R zg|J_{rSI<}HlfJszrlK7UPMy!@B%2mXBwXTH!N&vfA|YL#T59q!>_?RBmqd&EO`pM zh2Mt$1t7w-;)zQcwl8N%#$^cc?IdN$gXv|;E8MEU!7B6Bmgo!DPIYAp3eg*{IKq7n zp7)NR;XRCfUV>L;3H||SftP~uR~&TPs(;3l)|ljb#qV#%6+I=huQ^`tt~qp9>dwsf)Rpd+K>6Zr~y<3q`-f+K=SVY;>?C}q8eKVv(2P%~Uk?<^T7zJTPBc%{<;F#08w>qm_JBDHt5 zV^wle7QQqJmw=9t!~QGCdpe*R-y2`PAF!!w1K zqkXtNiw^N^n9iWq7tVn>FyFm^zL7`>4a^T$6EnYRxf^Q{N*rDQ=>e|p*Wb@P-Z}|f64l^k>dySYI|d$v(fX^YZ>}D_Iwfw^n7CEWteM&u zqD<}?rO&8Kkl+9f>(@R>(iK8zy0pMte_ zp{$Nq#9z@5roNfF2S>>Vhhc`9+r_l~V%pC}r~Q@c+fPO*zLo;hUfSO?izmC{FulUT zS{rT=BJ!g}I7FZfX}p3R(8+kOSoKdQ=tR7_ayNAUO!es_3CFu#N3q>;r0oY4^@zSb zwHpqcBU!#aN9)bF{s|w4zTNm8%G1ts9nB58j;gDEjI{npfL2BK2WVArxX1Tn;KKe_ zJumDs)Tj4g!xozqSauEALGOZd?+X3R)K~8a7WS&ofu@Bc)aRV5QsUI-3P-GR>V>^o z5WXMcOGPB*)Q7i_EGjV5%jUuLqi@eVh`si8>It+l)NEs@Xd`R776wynTPiMC;X3iNofbji`BTmEV03H1RA|I)0sdtbnu-st%WRbSfI zy3p&R){?yGPNLOGHQ=aU(?Rcbgg0fmOc7YCrc(2M<2FHVFzO$w9i zsn&MXB4I*)HL5j9(Jr&;MQ0G!O24TVVbIys;)nRc7y42S@1;=97o(*Mife8v(ff|9 z^Nm&Vjqk!zEpacvl{Ta21%L#6#6YI7ap*0U^ax(MSoXale5oTY!r?nagf^o~df-R0 zWiz+LE7LNUI`8`cH1AW7(8p?G> zu7|Hal4g9m7gq+@sPpf~K6L@-bM+^4`?Npc$4=uOzJ(sp{EDUhuc7(-{>QiUC^qP0 zf5#C_>ot!439CLeU%!>^e5LOzA*b>!)Zo;)1TLn2r&a|Q%ndG>5nPZTT#!rlCULxT z7QUAbKl>lu(3S|8uDKK3hh7MN(zBuMu!Mi|qYZ6`B)t5Q4Q+cQd_M3qa@=#L=eZO- zXBOtU=1k8~)&S0%HPbaWdrk@AbLN)hyXd=%2%a@#M)q8!0B6sbAr{ayv;R7mNWnMp zo&{K>r)3`Ze!Dn0(YOo|=n`;J@FnyyPesjDCvL{%&pJd=R;J{xC z&=9|?FtZk~U)_z3PqmCC0Ki$;O8Q&IYY?SimP5oW`|x!-6wL5mTt&nqlVb$@Yhr~j z#@A_}&EeE0*aX8+Ld$BwArWlf0%I?BE_n3VRD2Q9?Z<}9!}}a@+D(z0tLQ?Wu@7ZR zO889)ebtMo8XP$T_ulkXWVr`Nrr^te^ma1oe?0~ukCOaM<`uqd`c4c-XY=V|;*Xv-CcpGAK35J)a@2pMQle4|950&VK9(ZMZu z0|*B0!KZQEbJ!uPh^)cTTp&U`@X*g_DnsZMl3-{am#)Gm*^PgC56iTLngXA%qXd5? z;NyVWZ_7adAFh%1WpQwKWB{uA)og4?Sg#wYhH(e{g>t_yKm};Hz%&p_=dq9!n9eC4 zsClfc#t3(GarkEgCWx!ya0h=;9Nb7F#FgT}uh2#}e|av3k9YsQgzxf}wNIR( z`WyE_p%xTW`H&T2y^KR*2dIoqj6&I=Wx4p;zRMyvhgd7-8-IVtK**h>8xg*s-6`dN>AX2R3@E*!nlRw_Zuu#If2mCfVMbjnJ zw61;J|Qleml5jD13S$*ESrDpGAm0-&jc}eAmy@cY`G|3V)_PxC$*NxSq)< z{FRoF;2ND#_#4%K>8JRL>iiTq1s?ttB>b(<;MFVj!DRILd^_mq3*QrTJw>sAx#(x< z$m4sS?=8VwORlGo15dw}M8`YVwv583RR8rTqPw2zT>4akuXC>N(9mF>pQ@_BFYZVV zjfvZ=w8I^hk)ZnijIrp2Z{Ti(>zSbI?VxK<(6wLPlrvoKP1oLdKC)a}TDzK7?rxd=QxI3MS~F|SHY+NtXM&2#6qB6q``qUlK*IfezpvNt$LqyB_n!Oz z-?`_WbMCp=P9?=Q@rDu*QPg6ChEu51zlWX>J}_rk!hhN(zBjq`f^X}#%f+|bdGBv1 zIOFgFq`-j(aEh^@z-Anp@8M9z{zlh2ddwEy{v~>6^|5tCfH=5sI}!AX11uhGj$y%` z0cO?R^^SAZg{@NgcdF>%7+ckkHq?f=i2!hmR8-F9{{B)w-L-E(ey#M6F74Z?yAEis z*A{5`yZsd#S;7~SzwUYi(`7q!-%fqjYgmHSE2;;$Rxi+;3$&@+#Cbql8mkq@iwsop z+FoMI+tpyy^Rbj=M_kvJlSa#jo<8AG6zYiu%dVDQ3;z~xDDTb6qu8?i3vN9>P4A~` zf_wCSm&SPibt#*q(L&7E=z{Ybn7ujN9NGuOV-GJO1%kJ*>kFB4sW$I;3_|;j^w5xD!7j^^m^e?$G{1A~@5aD$UyNr1g zeG)#8UY&TvCAe5Lp;&8KJ~;NXlw*f8I30(YUc19@;GB45lEaLeBQX}+oxu!oWH^KA zd^O)2ny*Ro?Fc`LuL@p>Ie6M6ygD2S=L>CdyAQkGiSfo!J;p+>*sssp|JLmX>YGQr z_00gtj(6%m8S$1eVEYWMg7JFC_g0o~lQR%Y1`GW8@5F@L)mFHV{`gPCcea22e{7tr zDJE;yhra%d^M@0|M~Si^;`%V$h9lzoPuSqgTHVF{i&`4)e4w7TPs3C&h`fqh^pO=> z{u|*I6$@UB^MN}5{3cu8ITDTtIR3!heim9{7(AaIW&>jiiNcD&A0T&C*qgEC^3r$(1ed zgG|AlXM#IV6WrF-xbt1Po@BivXHkS*o&3J!7 zw#jM_oQEwfC77`MXW_R*2)@34#YK!9QDGt=!gK;d*D}qo#9(lZPvI!v#bggECc9F- z7cP9b){r?^ml|I2A+?u7j~=fKBX$%h2`^mh%_?uVaeWh;5@(5D>p|gMnmk1Oo&}gr z5lM=!By^^XgZoP*p`geC+@YX|^4yaOL$8ViFZ8@f@Qhk=FlmawR=VMY?!17KL?UD| zoY$*n1!M>3<^XB+N`-22$G~xMZVjoTcVa*)Nb?~|x>wE_070C{Ufsj395Ofa)`L=| z1=`qa|7&GGWu?Nt6Pk1|mF?c!I{9~YQ5Jbi7u|hgExfl{<>;!i(H=_p?}gr>3YAk< zU=5P#6MATX*@zQ+NTk(K(NC&pKB6pZ#tgZE8RY8n_rY&vr=&@d=cNygE7^Cf^q7hW zoJXOS011TvprRp1B#=AvSqUYV z_uUyBLGqZNH%9;7xCem&%Ak>(eao%o;!W%^E(=fS)Xo2tnXyL+b4oPznuAhTc=={o zn>Qn(qu)Avfi?Nq)hb-^=<_zSdC5n7ll9u;I_g_klsqQdm%!EXKf zKX^>xoRUzk#2cPRdJBh+>B6CMB2cyzGv1e7q_howPCsQ6Auts=HyQi+iXLQsvvJN- zly%G*_*6L670p?5QSJy5jB&cs#3kpwC@W<_)*$#O(_(EkgV?UB6B11+55$T$J{L=g zi{8sDZFL5(kYrJ+{FRscc|xaLT6D zYm76fM)-b#3dRyaPuFcA;bG5K87Fu0BQm?Xk($9nWNUQ3kk`LZe~%5b63Q*VNzaSd zxImc)x5ZZVsSsRMEs@JHB-)%cW zO9$`a7Sh|zY*J^%L)7JF*H`opEep1#H)Yg)zrkN|0K`6r93DSNL3&gAKq*i-mRAEr zf%v|eeD#5?0v*=OuQQat1D^V@L%6Hvw@J_I^=9obPTJnbtemrY53&67_w(Ou^Y4!6 zuf6?wqw7E_^Wzt@4jkF1=Qr!iLT&n+BX?{0?-2S8kO9m;0am=D=O1|ci-@b)U(p=L ztXzieVNY!R=dq#u_UqDjXYW~7s9&UcA8hl7?N{F2#)VwZh>~g(IV`b0uix9bE|pa{rDQP07yS`Ub|?g#yX-^f}ZHbC?_6 zI}#Lws3644LFr9r)?tydN#Ajfje*H-TGU^!FL^+>Y4)^+3&iG8(AE+bc2cdxccf$0 z))`lS=B@$tC1D7|NGG&!6#9gerFL&&^mv`v;;hR2-~+a%z~2))jrN~l$5Ee^Z0g;; z?Yw^jNL4Fs&nkuL`r8I3(m0WOicoY^A#$)}B%^{@?Ee(x%i2xjs%g7c0Sdz6Cot!I zUVcrxzDLAl$jW*6Lz6FeOt68_ovUsmQ$xvxc5qzp*Jyj=4Yq?iWQvEfN)MSwJhY1r znG0DYXA~hj-v$cQ$8AK$#Q>@ZN~E@rT>|U z)CV$Q)!9;+KeM~)9bl8`jeS*R8b$l{a!gKBOk1~-=+3hX3$sd7oq<&xYE6|giAKky zMTU%}qo_==A=e5@NN0E@XIFbkX#PPk783>~)7flj)@(7a;EQr;rHqtmtxlf$P=&19CGpj<23(`xWh_X`lSYw%NL@RQWwCw2{fiVVJt{7U+C z`2|%G=J1N8=X4wG8RTM2WL@bej<&uZCe76$`{ig^6dHBgl{``UQC5x&I$6`*gXskk zza~V6>@j<{(2%Xw?9?vJ-FW&>7~U;kTBv}j;gF6!Z>@A}n(Ek;6T9>$)ukytMDo$4 zqZUL~DHcDTWKPKhd*Wi5Qds>!Zx5#m`yFANOS0d_JOeO$uw6Cz7A!`IcG*{jxj%KQ!GFAUvS zeof6Y<%#p2DZg*^Gv)W-zKrkc&@<)vxTpW_+46SWSKRkZdBIK3l$Y>7kN?~FU&_Dm zn;+4;_>PQ{ZMysU@-gHsZux^HW6Q<6VvK%(0BVtAP+0iCe3zK5IW-;o9*EUWY#XP}u}vq}%57l=dV z_?rsQ>qdNG0D64PH{AQ#YZ zVfMk$Tzg~(z5l((>0{SHP{W%7fBy9gx`D zWZD&1)mQN;D9*LgElDagUgqFUOC-q|s*3wn?h>)sO==aH`4*AL_jN`7io0jj1xh$n zeOv}>ufJjsHZ}%B_-gq(Libk!te(4~`nna>r)&AIglYr;QCNMt^Zw~Hq)bwUs%_*A z<2iow@rY+dXq9SJv2o;i$$dYNYJm{pGlAS&M;dA?gz&FaXS~xW;WkZ$=&m~LUf9oc z(hlw39m?^Fb}#!PkS6WkJ<731yLTfFdd-;gFdIxa#jU=N3i^}WXT!h_e|rHmb8`58 z+?rC42!F@{PK+7l^Pp0_L(WNM#5DjsI85OjkEWO@9XH-e?Y>(LC(a%r<|HJWaw$hr=M|V z%CO-hQqMYjWZF6Bo;T_j=ckXp;FlMUx#;4IvE#;Hl9_dBcFu&$F3+8K#iYruDO2;N zU3t~?{25of3$7`gIjgAn+LG&LUtc&&#QQ^b0kLSAxq#0l8yRL?QtJQ7UxCf9xbm}a*x1dii|@4{VJ=pu8&(&18N*$ z<{+gA-bNXc(KBSEPs-CnUG)h~zAr%wUP}bX(qJCn(8Ty()o~}(6Hhj3!UQv=jz;_6 zne0>SmRLp)sX3#Vthy?}U*7>cj8zf$LA2_@-#-R&P@#HA3K4$UBki^`L|x3@D1!K8zey$$*VVV{KKhO0S9Z(3_&G z{OLDK7 zd?3LCdkLOp1`i^5P%pvb&0r_NPANRGN8vVAcu69yM}hHYV}8V}+hCFp?j?A?8O&9S zl2dvKe$fm*mEcpQ@b#yh*zLc^Pr*rqC-sv2*Jkn|1P|#Yc(xfll;EMg1m~E+rxARb z6n;gI!Y?)pPbNIMm*hX0!KV}4+hX|83_gS4GkQtA%?v)1;4`K0_XnTY^4Iax@)W{T zdP!bsCLcyHSFnCIDmR+J!wDYVOR%(*%tsJBLJIfxD107%-F+~-;Goy%-29z$bHTy% z?;fZN4WpNgd}c;rG79$+Tx14+N${7w1YcqXw-DTNl4>NWYP4n-v_`AZ+Dk@X!)&5Y zzapcrdI^5h4E~znuX_pJWCnjj@HZ!^Mu;f7yDht*Em{pu$v+#ETg;5UB_pgN{wz4p z43;7Nu9x6nn8Du@{QXI)5wEIoD7)a0cL~uB(dI+FOJ%QbJe~9tnf&zgAP~Sp^gj!Z6Erls22?8UIcyKFA$#ZM zTx=Xoi=@}XrNf`Gi#`3(`q1Qlk?=C{*M)tm7N2Gpd>ZYHPsy+6g1t&*w(uau^|qcz zo53er&jZci=z8vL!G1YVI^&D%f-j=gkfq(T8as$Zs|~8r+j@S|3_jULLsdsbtDnNcg%=xsd@H-k^Mp2fZmjfk%2-l}ncD7yQb?1FEi)sUs# zvl^StjL;)4=xseeWCovXJ(ruo(e>P0HD;-5e4kzLeY6^~w0le7Nfa;Cta_+4fyNRN^k7O4dQFw!;y-=2R&wBjT%&DDv^tPU>&ES)*=UdI-=z8w0 z9#d33j%61di*|=B?Vi<0H8bj<8nT{y2FIAe(KX#O_!A7DbX(WGRb!iqGL40us}}ZC z_`5IcKd5jS*H3yWzsfA&Q-XV2=r@_cCtK)~%wTJwI|EPkqwKD|J^Tm!CNAr3VIpx9FZ_f2|TPJlQ&a(+sxOF>07S%D$nq?B4d}|1ncX_vM~tFEWEq zws;H8U~BO@1M&E~kN07W#4wXsy$gHWjFVLIf|IS-AI#LO*oD2V*nMU&D|R6}FnoUe z-3!-MxJ>lkcHoCq=)&j@+_T|#o53errs&WdB7C3O;Hy zT(&EV)#?yVZjh@!i{$}adST8-Wa?;_g0M`M26-5HoM?kH91(}3wxuycN2}E=uX|U9?zP=CtKlSCX>|B72aDtZddjA zA-mv*Xm|8RcuzGmitf}st1-$9juPHIgXP63suA6td#lFhYONg2E;t&kMsI|79kIwL zx>5Hm=W#RmWXpb~85~{qy;Wnb8KraS%UdEnmUb*4NbE7hlnWC+_$#okhVrhRR0k4! zduTG`JN&ajDzk}%7RB@u{0*`UC-!m(j_oB_6rl-*u{9%3X!tt(-M9Kp`2Uv*gv=~X zR)IUrU@9;pwq?!#lGnt}yk^9Ng-L1Z@i;eA$$sJ40MY{+$`{|gp?nzMw<|Z4XZyHn zQ@){m0RHLtpYv`gpNIdbe?$2{S8OOBjsJtC8_K`HKLP)fi#L=P;r}=O&C55G56A!J zk`3hz_%Fo&(4r0HdHDZ^e_h3f@c%I< z{K&O`d=vS|RYn8>p496wakKJ8See|+xyTv3232{JmEaZu!a{rYU8p3>dnhLKQU!Hn z--S_?;jK|qt;i^4Fh8Fw?#xb1PTrT-YdoQB0U#=Yr}jBu`c2zVsz)d4H%5BDe8 z1)or?SWZ%$kt)f`{dso5=QI+2ut0rx>h3SI3%=yx+$f|}cYmE-@U=5|E^0a|&Q-em zyX=DR;88~*S-SghHhX{Y$0+1H-Th;B0cMBhw_B-(EYRJ@7i65(DrH8!tA60!xMK0-QmrRrR? z;jw&Gmm8XE*W$eWDl_4O4+Dr%+*=$NrLsUH1av0)5B(~$iLnrG<5Y*8@rew14)qpo zYO*#p#lJ$#JM5P1F+{M_Z&V)n@XW&_+l*}j;=+}(fBp=fs^i8_tkA%pl{>85zr*c( zVJG&+nl15c00?5ZrOA;YbreEve5fSxIdy@4but#u_@rR1Ep~yn(5^15dZ+8-wh;A2 zA)w^Vhrp5FAbQR%EQ^7MA~}hQ#)Y2T&?F?Yu?l9YZJfz##fkowN;Eed##$yg{C;di zDcuM9`iSc5035YBncvO;PBifaq4 zZwX(=D$Kxcd{*gnh+fCRXVCq4`q}b#Ha%PZI`H+lw*e!k&cA9zm1BQrAtZlm!U=Lm zF_LE&wS@`N*C^&9dPzioNhB-p>b!z|hzl+OnKsV*R`P4T)s9Zrq9yQdqWWCFU5$p% z-1k6Y2e=M=ZDX8Lp=xm8xe6U9rU1G)s86xd}}&91AwYxRckFpb#*v%GDdK`Yzr7xlBtO*2fqZw za&1nOn#QStsB<$zleE6lar;D1ig(fp^~4q$W2qC;+P)MWxE5HU#8mMFG6hICwZ!k1 zOTStDl~Cw>;o2+EmOPWZSb7d6#CoAeqx96%Ttj2;}>-J2K!j@RD>)oFG zDD0-LEN^goW<^8S2D++UVWx3GpxiktE9ezpf zb$ha-FuCj@uyVI2CkoqR!Irr_6QVG=*kLyOURkbg&t=h&Kbx`d6{O_$Tpk7M7Pwl0 zbE9Cd1zxSd6QkhLuIy!rx;ndoUNOm-7@S--9@uI~Sj z3S&p1zfAR@(7m#kMAvex+qlC@UZ=q3at2&%fp;jdxuOB*THq!HHWxMEUjVj-M5w^% zx+cVFCD^0D=F$e-{-fETEed>z>KwoyTj2c)Y_4&@uK~8QKcGU=qX{-y37QqyToOP-JdD*^jAjWSm~;7cuVn*y5)AMi*Ed`N-K zwGTLKum(F;M{_ zzqJx1D6okQ057w^i3)5Y1iI05jCuI!Ulh=~>m8EYj-QQ)f!g+v4M4zs|i z3Tz?=V#ixxIekR&1K@9wVUORNMr3T)yEz;i8dt^%950&t!Mo~*zot^j;dSN3@-#KaYZoMt7M zuD~X)0Bp0sa$a+LOk4pt%-KZRI#YpvL08VEFHx@9Lx9yi*QziJTM+cTmF9W{w~z(! zM}SxDya8xY6jPA3%59~}EoXq(WwN$@brHh9Jk?hGaucdg&cLkKxYR$7)I8F8aJB67 zDE&Z-jOH0teW(7W@fw*3Z8H);qk6=V$dI?PMnuK%Oft~6iqFz!t~{E}jTFdcy{%?O zO!c5CLevK?1kmzLlw33KV_+Lo%-ghS6^F8xLkRwQ7u9f6k=as_{g7H8!Q`Y|^jk~s zhSm|?eyFc=0cn{k$x*4f-MHKg?U2yHD%APHlFZN~sFNYQiHF%Xx8da&sketFL7gN; zVK)GywghIiTT#zW1atSGmt)({Cb~7txk<5| z)M}Rdw60nH?<$(Cj)gQzKjyK2|D@qr0s-GS>0g!@G>3UlCI|2_@23)lRiWnnT0mMR z^Zv3z&mc9XO!^h_Og1ym?)EsNuwMa_+30Y45~HwU3kF?mre#DX0kdW(bg`Kn@Mr~A z19hd;X_7-Y8-Y)`?4bs0*+2$rg~J-8PeBJ5uUV2*gukfc;jGlQt;Q!l;iho)UccaHe#d%oY`0p1L2i(i4x3`Om zpFPPs_`kWRcq%zOegg%`MMWu4E-Kmq%0wOmwOi2J`?R16a9 z|G$fh&eeX%@NSnCTcej1rKY`HR=f?cby+cZjU>%~L!Wg>E3tE_z)}}paHpKbjobNH zHZ@)!DmFF36OiDYU}nI%wO@9%HW-;Y3hT%P%_s$ZPefp2=M1C_oQa-z*COC%R z^Uq%mB-|e-b`G?PC$KM%MULB*WT2Zx4wbnxaFjy*?O2A1`9>TU@c7Ty=HBilhn6+| zcGvO&{<<}wzE!^h;)xG8k%X+xe21JQ->ED;xkYj5DhlV;`WJQ<=}lJ zZ28Jxw@0gZ01NN^mcEBIg0gq*FZ|h8s-%ovEyKt@Yw5^e?dp&1^U(CH zJyl1=zRd~@pqedR)VJlpiv@tR{D)hd5}T`rWE2f|u1u1ueSTzrcs`DFS4#LUzMW=E zCV-H-%$AI!8BZ<;Up8kfIfU&J@oKmWfPF$qf&F=En;LyVa0SKoc% zJ$x-=CeNMRn918J)_*l-vWX~-E)hK1!dG(c>uK1eR(6u`6J{*g0m5m-TDoRKdEeh} zD8GsSn;+RwelGt{;eM6>)Bmuc{21T)e6OtDSbiSg=%QFP9(DkCwwWk?^0JV4Ps1mg zD*)47OxwGvr(!}$b7AgewN|l4nLfep$pgyt36@YWeNwATpER;{aK*5&$PbeOZ$X>O`1HY5HW)#c34`tj@D(Cs^uYx`>AG(}cm3X)|4zLzLf;p6ctD%HkYvAnz;+W`Xg+Kf9l$KairvbP)fSR=Gg=iV zW7N}V)z=cI(`eP%L|LGWRy}ueqg9$A{o2!LRRE(^+R|8F6cVdd*t~LDR;x1pHP`6F z1(Z%^cUl+Q9b27}ckgW8ltohy%1lICi|dFm$P zU$c#cw@9U4uB6jjc2vDC?4FiJ3p0%Fs-s+afzS`-zhjgm5fIk=?szdD8ZVDe%p?;b z7=6DCx!$2(2a!M|vB7?ji_P4G%8F(&DDFC--q4i`=5vgrWP-$FXKc$WsxXmZI*b5m zCN99hX_Jl*eRivTyaD|`e9i3T|AcJyDPkIp?dzr=L`Qyxkh0T7f1MBV#v!d4~Pe1 zlJQPr=>(q@|A#6$QsyS{eZY^ZAC)-a{hH|#An(`seyd()$-ys6^nUf;$}g3Vlhd&~ z1q{keQIIre&_`Fu+cm-dKu-2{%^V_04I4>LU-t5L%`{?w3NQ5D&F}Tz#r*PSjk;Fe z`DV>W@@7q{Dh~zcEJ7BSw=x@wV(f<{Q%w-9nw~5*mzCdWOs+1hHR((SCD}G&%DKQReC! z^uAbTxRLjE7k@D7+Dr*UVn_;m*G-a3X&sJy@u@d<-y zf?_!Z&xSc1TJCOiIpP6Ut!S4^c)s6f&Fw%z0Sh-6V~pfGe4iH?K`Bj%i4kh6C#9Ed zKt^O#&_^ZVg}9-aZ{xGTfBZV5JPg+YuC|eFUn(4 z>|ZOdIv8V{PV|{}!;@Z*85MsWqQs}@@J>7EENb=2RCb$l<)KfBecViG z;MRAiH&L#?KC!?kAW_wf1Y0Fn1v|}on>q!}9}_hfYw?(&%zY9wl=EdodG@H067?hg z&qvgM9v?S0D3#~ELsl-=zOv>Zs~t=M3g1o|m5I9lUt}<~u_Vfy>lZvOL+U?H^g#2FPDv3aO$ko_f&}X^1r}l5Iy$cT2IA%)6luFs!+Eey24aF)LasA- z6|N#fDy2H6$hf0NU!+@oae$1J)!>ucfjy`{U0!4?mb^@1eoV}I!_g%JRQ4FxkBTEhGOdYv4lwPq z=ycdbmoOb#R(7qSBxmTrhxE4~(g|b+p;47*qD9tADwsylVCqveZ4SXkAHh8!cp-1H z=+W-8?O$g0#;=KZf?ejG_^p|CsVaySvvJa=#gTE|Yv|y8k#P(8is|YOG%?yRthVwn zYeGMsek?TA?r*m{SALGa(75g%D!U(832d#EzXc}aGC@Wq@~#$-!StfYyK7Zu^7aF= z8DrY@O3D&A{Y`0bf;F_pL8*4Wqd;>QqO4S+w;7r2iQ1Uxl!on{u`ApDFGm6Q*auAX zAH87Fx8Y}YGpP1|B>?L*be6)QQRctr__ffs+N^`@LV>-qGI0|7N>%l>96Qc?_CuUSvZCwseq4ba#y=lUExE}qLZ8+qi)xhI8Y9^0K zi>=$!UhO)LLDxJePG{gRWRS_l=B= zj|@q%6xT{5Nxp&M-0B%PvoY_q$|bPAG5Lo=;Gx5|N{FJffwFcFfq1D*j!Ob77<8QoP(qyfg^*|H`Px>fA=M{=DZMQV?IRrVG+0F)C; z^EK;s1?i)nV`*D__u(mQQ@`}@%x(Fk6CX6uXe!-lpZXxhi(md8gGMl)qZ-KxQ%uzP zwuj~<6q+=Kv6+w+j$hw{Q{evRuW;N=M$3vks_lXl5^8Sj0?7|0#8buTR$X+_? z?=+-=22GO&HDpyB^bXFdXy$Fqvsi57jnN#{Kubwwwa?HixkM6K<3T~t$vgn~V4VmG zZN#NujG0x)3r_<2DwTO#k>Wj-^T#!x{KDaJtP>uTm!*ITm8Kdl?l%xlD64 zN2>@^7gW_Of}-D%%;+ms?d-QVdi2}3?N6KdMyy;px|^gjCJ+^a9@Y}Jv`T-ZGxULD z888hk#LneCmSud{l~`GXDro6}>eA!b?P_$rkwERV(mlMfI7RwU=|onSD${prw^Ndb zzf9wuGNCquF1Rc&h{+FEB1gIO22nk(dx;-b)C0dFt67KW7*Aq}=zafm8q50`9D?8|0%CJAFKHHo-UY?Zd{CmG(V#S zLz83DY8)5mAFup)#TduQVsP%RNvsbi)_vT!@{<+)U#qP6$yV*~^=IhO`OZ}aIS*~2 z+I1tFvYVWN(hbth?OpPJI*Vt4>YUZ~rx+PUnL7RL>xrdm)TR)=I{WBOC}MxkAS%C~ zaElCd%R9%^BLSZ(3Q*@8(sS!JTA zmM$BDIkdyMS*%PRs+pC9HT_{coF-2@1fMt*1LY43$=So$9lVd0R+Wv%uDC?lV-lJe zI+zpZ;cLU9gyXT5$?7D0h)ooQ<@WZ2^=pNk)a&JGJw<(*1PrrnZSu@cDnz`SW}V;_ zBDD*_t=(~A=yQ12Zjql?zRc zJJ?!TwVEPrvbQfDkF_Iz-m%Dn#@vXlzm^w=V}z~$&fK%`WK`!}sE<=8t-9Qh`&iXZ zwFT~5^smC=1zGvrPO$ssM6G`>$7~f*j~64g!8wb0?sSU1O4M`Z5vR~3wRQOGexQnJ z5Po_)0%G{|!JI41|dC>iHO7yY+2D^;>LK z78MnxHx#|qp6f0wDnb`naA!NO1ZB95{j5HvZm`pPj_8N;fH^ANxKQVI26QrJkAFSv87BLA^4L8ghl;qoJ zggVs-DXvIoS!oj>ef;M#nR%_Ke`LrGN?zNha_I8sF)>jXh^~&JGJ^<>eVX`{Ez8W7 zHz39(@}7&-&8@h-ks)42jltWY=uR)sDILmiwPmzv<0J!W*x2U)4zjS}Y>qn1_Tb_^ z0jU5VjDj2c?2kI#^CIIURcLZrLi)Tk#-~^tr5hFlm>%r_p~#S;#5HfN%3oDpujeGt zX!CZ^z5TGXwlmjZE8Xsho`t{FXV@W%gX>=g`?wMm7uo@5M4}kOnSB1b+_kM#qHAdi zW22Opv7Lbko4$Pic{AA4$aMx=CJ2}G5N`u;S_r2>&Z1Xw(~a{|Z@lfcJ8!IzdOTC5qh`;3T<(1Rphb7jm?$g26UA;Pf82zr8x~f@K zttsHLF7`Lpc!LIbt;?FAq9SC1jc*ggRUPOf_%=7YanYfg;MYXm85BUO*j4=C8+A!% zNkS;tA?FjU%aNZ1qgMtxYZad1`(hgqDAg(M3@(l=fiz!?{b>J=$yNl0p({ce{6p*q z5^08tlqQeYuXaf>awZB6r8o{hzB8)Vs3uAUKa5KJy;lnpUOFOGI)aSD-%%;gPsZse zO7e7VgRz#3q?IpjhiELIkHm8uqiOU%rb4Q370)@OT{{Y-$}I_I=-Sa>x5$t&;v9w3 zfQKJ3M$+>nulAA`tsXjnvm^fCJp7S9X`~Ks6wV=Rk8zS0B1o>^WQvZ8_mrFo-k7OH z#!KkRmxR3WF)fD2KDF4`DGAUH)FvcS4zHK>Gt(Bf^x>jR%WQc}Z~_nAkgW2u2_>Ox zW4z~!HOKo%7rmu$kQNl7w0O$>(#^^+SqmV4qdo5XmaP$07vp{u2mI$qwQT>R5)OrIg5*o`{+ARgKE!00Adzi6xU4)98P8xmGNAqVMuuE3Nw$EQl!bE!#TFSSskrSUk^Tn2IFo8e z#z`6aIK?`E0U>d$ibcjr&TGwzVTO=+Yt4$Ox)^KJ6!6Z|CkPXx?9=n)AvM*ecO!e& zK4+Hgb(JN>GDTtxLzsVUNR|$JFM_2c;bsXDqH|d%#RCiL3i#zEC2U*d=$~PS2!~{t zGq=I;4X`s%Er)7rr`)!9%A)!6ZF~#ody8(o&8OT`ySXO{3IT12`TuQW7-oOY4`ZRG zV!R1c{KwOlVGW$SVGSX>;z?m`P&nh4hl_yA@$c*N}*rQQ@KXQZlZU-lHO5%-M;B?Zi3$#e0?wFK(8Le zg!Is=TNL+7<38YAhc-f+o8rGZvGeILNEP^s#{TJYvW+qBq7yCq9xROt05wM zIT3KA|I0quj1?UVva(^{<7R_REGmp%L+r+bIhQPjwNOlnUFY?lbo=#GN*IjaV%QN5 z%u`7H!WWUPxkXcClXs|IU@zi!u6CDQbKCVX`e5xMjmN^b+ijk_EknM0uH1MF$(PL6 zR(5J3`sKYQc`KpOwejY~w`1>jlUDJZRY)ARV za(5{Ipd>c-QzKyn3s+;ecA2)^Zu|oL1E)&`gBNY8Hrt%yo9C2-8237ue!C17i7BhNO%+u;<$S)v-+K?;>V z{g54z`N}Neaqxr0G5V1|rv?Kp$w)(EjL<$Uf;seWE9JTK;Pw3=0FeOgoZ_$ven)Jr znEd+D?Bm`c>dkdC;zS~fE!L@aUEV=vD9p$dix`L;8sjB%$;WtJ+P$+YlD{>z8+pP3 zSQTNM!F<-+!7>#N-W?6Ja`Txg!%f=aD3raRl#YtH4*KiHOlYGSi@vCem=|+*6SFE} zUd-K&+xbExbY}Eo?j|5&OqtU`)Rc0VoRrPx(4-W^{g2N-&fWhj*gv&b?g_;;4M^C zn^RV(Pbg!Dh`f84Hx`}2yU5sjXAuen59i+7+2hUQ^d$S*HL}M|a;$w!eG}F`!B>>u z4*J{sRPgx7^ht>ev;Wm1u$(HOHj{gww1ky8+g#m zlX%_X2D>-T|C-})gG0Xd!wre@jXm6uD&LsH4YA(%Dws&j)E8dY>$eI)JaXqY8%vtk z6mN>PjeHZ9BRyVqRA@_|ip2s^Rk zCqc03FDWVS^x2iZ&z4nioD@ZhS-DM0h|V z+$Is~MdAhJUfMv2EpanSg8bjke>wjF{xko%q5OWnv-u7L|4BUgdyeG4d7gJ)`ETRj zMjU}-)K`%!#_STwdackaLJt0+fpgDZrF5Vr#QN(~{oCzTN2^ggsOYQ64Hm`T7n9LR zDAwhL8B5};{}>hX_f=%(UeL9YOz*-W`PK`dKJ|*KqvfPs#)AoS8_Hh3i^ei#Y}V|T z&Up|ylyJh2>@UeHZ755DW;2`|SLlzO68&vDucYCBIoN9R+j=|OdXl#6Z)4NgDp>bh zwJRhWce=<>s`%MPwwzfB&@P;KwLD(vak!xw3Q%~qbN-=JO)W`UKZ5{i` z{cLRS@*l&0&6a0P{yO*F{qqmO8*H}~vHiizPtd=maiRP}M!A&DE5I}C>ezfpieku0KkW<_;gvb8E}54gw_n2hL=NK+{cWu0l)XLC+?Z-y2~-$vtAo9+niq%T zw0M1zJ!2OY)Mhxe843C%ULTs0m|ef*4E-3FtJ9DBk2)6*(v$jXi4(D!ojoIQ(O3GE zM31v1yM8fG2Hl%vJ{eS%EhL7|=f5X04kH_rk|qdk;S3&nidnWxn~|*Flah5+vbQw* zsJBF)nvh-Zy(Y`CdGFL9{|M!>ANF~ zXtxi!^uJi;a2oLSwuT3DzE5TPtg$gFRKg zj8rFY;b|fr;=gtAGv$96_xH~A6^-w(_!8om8J&zjjsIG9dbuYec?!yqzi7U>xFwy* zV67K+v&G3)G=NMW8P3AuZ8JX4eHmNT%8+;9To`siwzc%aMwsfPa z+r#85^>~9iM|ma&Tqi)C7(Xe!90aN78otlX%@>lHYXVM9YwLD^lqU-2FLfvl975TQ113 zA`vpibzmfNs0-K{`|+B+D{*8ajO5_jxo~z}$8C~1vMtn*Nt!{1kzD9+XYfM2@CKEr zY-Ife>X_>cjJSX|&2Uz745Lg>oFZ|@8+SI#87M&{Q6e@I)zP6MbP8_6S5ppnY%8vB$>H3z70%$F=OeP3l91~R?nS;(WOzIC zJYD56uQShn%0IJ5o|AjzX|Dtuk`pQ@kr{Sp^)jdt9W&lB6SYCAs(+gU!REpWRvmY= z2~-@bz)Ro~u?3@E&RPtZ7OUugAq3rFM|dik`j7s4>1=;}Gn!^Cg=*@Y@RE^w7p7RA z!b|UfD)%{fcJLC}W3ycjr(a;8C*cPqiN@mD;@`OdZJ0#o3l9I$8y7#Oc;v}GSQDZ7 zUGEJ2DO)J%D1wl~E|RW>OPLV)oTS=FGcWm!@s~n!5lI}zwd}huiqE#nr$x%6I7Hd9;uUgv{sJ!5ci4bxpDdh@;^Y7 z^2Kj(XlRcZ%Op>ZmoOnNj^rnJM@c~+BOoe~_by${6J(}219`+>Ao?k&w;u4f_xHUm zw@Tupiwq9RwvzC5(iyTdC~26nl|Ct9)U}Dq_S1vH)SQ;!Xq=cV!ZLlL!+#@sis<=O zR*33eC3S-Rg2g9pYP^^pYpYB>rVG`6D6T;(O+@OFy?=37WfUcE*PP3a$KdzZkgmbFZSSE86La4qkW*CwatsDC+Ig>6Q18 z!iR4ql;n?>nBP~e?+0XOR7p8@q8UqZ>9+86=tpzqs5faqY-{$&GIZzzH_6TP7wi+y zDW(q4=u?2HH`eoz$8KTWss~A#4dD%V;8>o9bZ8;832do^s^jKav|@jZ?QuEaX;aH| zb^7CUPCPl8hNpcZ7;Pq8qLOeW+;vqECGs?0lw~10yXIOAAHd%koM^4s#qfxfRMZky zhhG3d5B@`avRobiI2+N)6gYJ)B`UFK%ok?V6={9-@1SQJ<@jpjIbE3OXk5A+cI{Lm zS6+6uw=U8b6WiC;VC=rZJ;k`4nkqy%?g@Hl7H7f405ZmNnVwF}9Xe+=e9Aa~sx1<;tDz>oI`#@}Rzl04%+80%EGjOuQ=P5t za_oM;sIYoiM-klLAqn)<<04+r#-;L$g7+fo$g3N_(r019q}^Ru7^*mAq$sq|4gv#> zL@r-^4Xh#m(a7Q}_4fKNVncRkcKxEu+{T(L`mwEqhdeK`lE)qAiaHs*4=#~@+>wyC z)~d7 z(Fc3IeRsy%WOyU&HHqQFKSd%l!ma#HnbJ*%E`f@pHkXhUP_4dGC@5oCFI()-x+&|&&cWD8dB&ipJu{Y;pB6HeL>Gd*q z@Ig&X>u71yeLO?!^iLg)He#YmG1%89mrlWOv)GAj*{$j#>#N@Hh=lS+`};+-A!)_T znjxwD>a!fdz0Tkxx3lcd83lmPX!&RZlO;GmSsOS;Ig-{U@zn;7<#%VFOn#BlCUG7b zS`wbfGE)VK*)NWtjqz>oY!Fe}C2ABd^4N-Bw2{I%z>JfV-g0&m?zls!58e zPRza9cSMd+BG?tqrGJ6L*7CKy4S4TI8_Mt6XYIcr8#y`Js}|TJQ2knbCfH_xuw>!I zzbu%+q|0mSt79LR7QqtC{r86Q@S_|-YHM%3!)vQ1&xb$RQ2r8mF1hp8dA65jGlK|O z^+yB(o)|ID2LUY=PN%}MH{U}5m`0pSaq2S?WbVwti7IybM{M=loWz!kIy=GPZ|v*; zqFruiV2mudkGU*TxgkF?JEkNSB0|;E8|5w)_XTDo$_^&B8at)l^2nb4E&VgrgEYvj z%44hydTqEq$e)+M{p!)wUYG}n7dS3>`0v4zyDjLjck;hd$UHxyI4eGA6r(#@9@^U=KU8xGT41EM~n~XNNa%2nXOnClm#1Mq8$$Z6ua>p^|R&? zib7n8ae0%{>%EEmC-CnO<-S(%pqTlQ^GjJCb3tCuO=ht5CS$Fn=cbzrr9d9{YY%TD zvRN8h$$Mq`6?IO(p-7%i&)Aij=sk5}W>Spr$L!aZ^eaHtU|cAu7EbWjL0bo6wOy>a6l|QSts&c$pWmVnEXs<;@2++A1dyDm>)y4Lz zTg zbM^O#J92*QyuXF-6%+M(ZIIk)ZMsJ0%bP}DDLB5y5n!ypBu1_le`!AI&CeZSttg>} zr3>P3?Pe^ZP#-4vt7d?6YrT-6QLroI|aTb!Kqn9HzBI_-V z|A0l>^w%3*&4}`BHG{#Kj!TC+1AnR%B->By3crSp!&o#&+usunI{kIMZFW~YIjncZ zn@7A#bkDql9+%2gX68BrZNNOaW#SLzzhP{W3G0w4j^xLMP%FVUm-VKwt3Rusx1Y>F z<6~G3dj3Iq1`$@E!LmlGp@bTz{!)%&wY9g*zhnNQTW`L=d-uZm7l6mS^KV~x+l}7& z7c9JS(T%sy_s(B*fjLKcXHOp>JyHxIK2}aDTSRXUv^+poQ-gS7LNhOmTvNnS-D$Ha z)|HwoZCIy$ujL!zL$4)T%V%mnA|`?;M_ZP@oYj%B>#Y3tk=u2(hp;z}ue|hfXYj^_ zbmkQ?Ikf)~1n)U%&fp9{Ay=~plR$r@b?7=tFXV7Y*d#IHkX6VR|3CO1=_9+0QjZPX zaEl!8+M&r5{)YG+4be(#>|mF~+_kbl`Rn@nn?>JBuyn~lI#_t^AQ;JeooAeekVT#;B6z1jPpLFgN&Z5Zh{l zcQQ6t%cG76BK!Q3=7$X%b&jq33dRhK-bc~2*_7@ z0{tSP2}4+M7-%{I=voThXi|?bmqIGRTAB8m>OC@-xen)Vy^vZVSF6}COOYum_<_R` zJ1z@KaMd>WRh1PHn{TEegrRE1u%>L+U;RL$CgTvz5uhxU7jZMa!4(6A60zr8 zhV@ynkLNN8{U@U<2-q2%cQea?or{I5>N{6cEm3P?j;0z%_p7N(Hwzsjxydq~jjkRN zd6ON|h)17hubCVp`q=*VDHTNw*#v)k8tl(HnKaH-$C-C!X&*y?4u?2ppH^+z&*F5K zr2v-Ia`vy|<+4Rs9=b5m3q3=H&$*LRSAX{OvLwmi16D>^g1FG~L0wr~yKwpI)~TX? zOHuSh_&PFID;zbAaEc_Cw<%R0nIz9vk(2iGVU{fhd;l#M^clW^Wk$(H2J@iNz$8$+ zkwOwicpv$dwKtpC=qb7w39vJ8JxR-2Eod!C!dD7p^+nGptR+VJ!kIv5vbqCeB;PHq zObBNKe2cp89I~-|ETqsrzG;xEE8bTu_?Vd3*tobp_S)LiC3mvL-3nT&t-blqI~IHS z&YcSdf6>L6I8ArP#WoW*p6}A}V^eJ=Jk!Kw5HOW1peHAZijhO^gn7qj4)`N* zRXQ8~<#wC*Okwa%5liEPg{T*eN{$ARB6~^8XLA}r+AtoSt6l+5I5$^*M7KrKf{lF2 z_R|$DeQqwhaS>O;4jEUHcX%l4!Nhsio>A=*!&?6KeCK^1WiVvzGrSk59qS+C#dnP} z@R)KGW7CagQZ@#Xwq+B2v{W*l>$R2T3gl0 z#HzsX^AwE<2HCei1sKJKE<*)_6>A*1YCS6?JX%J1Jg117iS`Chsx)9OslsBbHfQ28 zN6vNFzoJDs*t*;PRg5hs%Xyzz4Gcezhk;=&CKJ4Ksy!y`G##$>b~aKUs3kf)j<9yRc`L4)9J7|Dg|@4mk={wQeB~ zYc>^clQSsW*jdZ%+VJYq0qg<3S=Pv1+Tgu1C)YbAbC{f#oxv$&ku}^`t*eSwX0ZjK zEkaAS6w$^yOg_7fQ|TMl2(=g{wQzKvj{ee_Dc7`V8>Ch+$X8Ks))s5ZaZfx99bq7> z!;rNNC#$*_%l#EsyC;Uqt47cQw>I4Pjr4(8tl;7)_DdUlmv@%!9ZQ2QSE}x2$B7;k zNH57(+&u5~dCuT_6jxUHnP9GVqm4?5`qo*# zL!7MPyFg;Xn(pABCtN?{fV4qeBJH?SrdmG13I`rigp$zVH{W*S;>D@9vRX22SzlYb z*t^Jgvp3b88$xAq0$KIQm+T9J{Xa&Wfn_*3Gu`hM(DW+1K3K9$WY-`|MRlvAfO}Gr zrVcd5KcokDhC5{VWxlCKXY7I|%f#Hlx9EXqsOv!hL<6_}f$3`GDUgyMS7A-bNu zy;X;6k>957s*4CbH^}1S5 zbPzSK%qrl@RTz8}BfIraxN^prZFrmQS5$K|BFy1SB=l^?BxfRq`sC|&-rqrNSbokY zj@bRi#NXF{Zjak}>W>q-dZ74Zgr74Lz5Jf_GgGSXYxlPY6Ah*v*N~j8(da zW;df>L@}E0kdejQWgidM$nuqG<8PfA9nT_btu&zxFSM5w>JbzIG5ipxRTCf8#ANKH zGuCWB%h%@Ix*xgRmHtoC{o9A8|0iSbSw2IX)vB|NLE>hkAi@Q?JtP%-eSwv73eLhl zkJUB)W4wz}WS5zO9Zqm`9r71ZVmlz`TUWEOcSt>~BuU;o$K)p=!zu1iLbcd=oSFzAU|hbsXPN zmPFQ21fNK3(96vtw;KeH=eG}dT?k7|x`-D-5WV9>wZ@_OOuo<#ciEb-AdZcOjf#TQ zbWyc(?NEFn+R@(fpsItfGJH3cU{6&viiHX|_;pjRR7}g_F0N&$qFsxx2K{1CfVFhB zjQUL%L7mo*fuS;BJI9%7C+u$Dhb*Y{Mt3n=^hZ)Wx{hFTIaB;Nj57uNGqvGe`1^_1 znDf#tlQ0>jNv@e2iv*XPI0?h$kO$7Kx#}dq!O0eW8jWu?Wuga)b2&)RC+suxgtmax z`;Bri)EW-X*}=Cy1B;lvtz6**Z3ML{q9Ei7xJ?z4&9ViU8)g&5bajTBmW4IR=7bii ztk}8rm_IVvdA~yzVBk7_{ommD47E%DH)FU|O?!%rdbToTk)1uzo+78JLgTa-fj1bn z+n@wKKaKH}QfYwF2^*BmbmGRy5WdlSq5W|G+#(LfK4R?t=3Gm8Zp*!#q}#v5o3TreJ3P6s zy%JqXI~vcS&?s^civp47rB0EtnUNu>N@$2Z17hewiQs>7GQT!0C^h!0deg(_52c<8 zlpd5u%$DvI<63LZl)m*Omf5~STK_IRE%H3EpmHlo#DdD||3lch07O-$4S2YZiVhVP z6&Y^WjV=~iB50VRR-zaRvPtSHgk zr$4nr$Xc<0;su)@VFo`Drlhbp^5&QjUbbg(676pO*4-Gc5crX>5?B=b$e~CHjE=Rl zk>oo(dsR}qHrzip42W!eLQ3Ec-}uP%AD7;cub3gk#D}VQ2e*LgY#} zq9^2-KAz~hie0kt*nEE3798Gd;+P{(%Kia#x%eSt%=v6&*>MXmt-b)Zj3<+bs5sNp zxd<}d=*rIE1@QehYps6oSRztdQEH+#8FZnmkQ~h`n;Vzlvzw9gPIDs)Q`=2?y<_Df zE{d>usGSrwBMx_w1iYQvmg1L+m{}Q%sD4mwPW86lnWK$|#INYe#tgPY7>Wjd$MhJK zAd5jsjvS*4{(TWQ^ptMnzMrq?@vi-%f9qKu!OK_vtxU9sq_!DzWWSM>1X3+tolPS7 zeC3~oOoj>t-eA&&l9w#b$#GDLg@Ecw5pR7lpsX_*wATc=VnFUARAFu}z>%`Yv7;ya z{^9OD;i#2#Moe&h6Ur&HB)(6Zqpz!mm!h;wd1V=!@g9!;nn~2wmZ6jkd(Vu}9gRBl`Pxr&X44%*H zso7PqTEyCxUda|!jRs?A9r_08U5?J-WYQ>UNU-cv5S6YdxhcgUAAASI8)sBz`T^Gu zDc)wF37@x#U-zy}{MsDet@N_yZ^hGAn+a(kLXMzDyeTSOig!P5pLeZF5bNrxp%%@t z`g5@9!R->I?OHFtPafje?>)+Ij^BHXmwr8UYx7FZ_JRTqM`6?1wHGf1NEN^s3r=2r zpA+0Jb+f)a$*>j_xOYi5wk5sIOd=g#F_P@wwLwB5G_u(nR|<~Z1Y0WT>$7LSXo!#r zky-=lR;*F^{ag9Yw_WP#+jU%iy_?mq)X=Az?DOi%Z8ljt$mf*`>x(YnCo5k3(ps5Z zrzco^iJrw2Y|6C%o3QE&eA}hozU|UR-}cwluhhBf@o)L{F#Q7b`AFZBHF(ohV#msZ z1o>}o&Y0p@AtgHA*aP0_(BjbT=v^LrD`B;Iq|Ym1qEOm1k5bV+onE{6 zHjq@${KPlUNgk|nX>yL^(LL}M8){Z4h z0UjW?+J&X^06~B&!DUG7qz4uwf^r;HfFO;~W&>Bv?Q}4Tb9^p6hh024+0Ok7sWcFb z7sIW%au;6*vyVHfo|c@mnyV5xw(k|@X*Io+$_md`;$%|E_;1IpG&(NdBA;Se&op`l zG*dF`BwJj%^w-`5foA_8X#>CykK=%Quf0~TJPxlD)T$ENHXT5fl>p7gJc2ES>_cCP z{-quh?&SR}5|qYmV>n+u1UoZ3i4$5_CxU;C?$0jQT5CI_YCnsPh}|xlBwE6?x7tPs zLv3cZToZ!MizRJ*2(VVLjMBJ5$~~~&RyaIYF+Rq5l3eW%k;X9@Fy#(2Wa?BZcLhCb z)OJOM8_GslL!`ONv}GN>T{1aa}ml3XJ2rt>(1RpD45HaYo-RcaqTq zcXdR@Ev|kQ4~GqMCAjOtt#4_T_3ghIl#EoB;$}0&b286^%b53O?sbx47NS1#o(+vu z-t!!uE%J839V_oLu4wWG6Z9x=b89eiaGtXe_n(#;S=$4bfA3^c7}a;lsO36VSJT@f z_cX#8H+HNuna4gB)Y)}sX!@R{2CuA4CYR0JZH!npr*^doi?ImTg0sEVQhYWX{&6ms zXXA_{yy=~;UK?|M11U(I8=CrUP#dBYU_8zi;?`-+DaxQ8%Y>}S1jh{*C9N8Mf(8&o<8 zG(R-!W?V1D#dJ+1^n|2?wn{(X9AuU))5EbF_(@I~XZ*U9J%<$#MUEp;G?sKf#L`~cQhTN?jbDe|Tfq8If5pNz_6=pA( z^`;h_T$gjrv-+C+j5xe*?{Nx`)YMCx-=V)W75$hs+=T96i%{d2bZJk@mrHNeR1TH(g`~{WZ-`?qt7EUg=an;% zaqVLcnQ!}A{4LQw^`VTN-RG?!NE_4P^LlVt$5&7tHXMjSm9@32?2>^5YLHC)>bv|L z{nFksHcg#D?!AeXUsg~rXM%f|)Xe5`So!7a<04{UaH!ZNN8x?03t*!-8@I`fyX|_{ zdDalokTE`0T)rV+m>nS_>GN;KZ)_UFsjpy($cgm|0vcH5{g+B9fCQauGvI}`<~~rC zGup9xOh-$kEP{0gS_WqLv9JGd9115 z`mlkS##IE~ff^krmVU#5^-h|w-r;~DhM>C5XQP7ln6N5Q|mXE;V`j|Ga{0)Q2h^ zmvs^XtFC%WKL1y6yUaiRl?bwaPMmPh$3hNUbP6-tJduT4%WmVz7`e4<49{KdTgvtT zOEK}>fmuuQ-GTXzRcE;Jxb=k&@9Hc8pJZZzAaF&!BB#MGY;@}IlbP!9ZexQM0qyy6 zWl>wHQ9^Bz0VTp(mF6ZvXIT(Aa6*N^2{&^B;N~%5YFo6az6=HC&V2(j)x3CXFGZ3}(f-5}^9~wBW zHw2JEos|1gSdwAIa=#+?nJ~xd>Ef?!!~+Ze6qEwf3*Of*1^yJl0q+!vuIt9_5+@KI z$QXwwW3d7hg{rj7EJW^)bQb1jW z`b7wlWK@W(tg-H0tMi0V7@Ln`VI?l*DPK*+L|26~8@w4PG|w?YOof`7NSO~RUaBn5FNDB8kvut;tQqH9W)YyGuGW~H;p2{PfQ5jwxlsU z2MIGJBA%noN+QC%?@xx+MhE9>)0()mJCWe3%h78j4cp9TN)dPPPHx-RRFb5p5}fI2 z!t#|T!2fr?gkPcc z4C3fk!e{ChEYtQse5|Qjz&k$xc9`wxC>+gzPQ*c#cV+Nty%#t|a+{=b%T&L!)bAjE z>%E2ivhxdKmshFzT4=tenXmiJ*TcNRe7ll)jdr}OBtZ0FKh?8{*)C%*|8cxy)icz} z{bLF8RDTu6985PW$6|-)5_YXlujE~^OO@cgUPRH|xrQW9k zDt4)A_?{HY$Mq@~o9kj)PB*?w;q_jL4`z%6(Tmsd@^JUTB;T$C$s;%y&^R~~I+Ii` z_%LSfq~o{CIQq9sKkK^~0Duu0F@<|!et}Apvdk{lR8E>-I#8I#9h6~J-gT+U+pF?k z2(dU+$U^0q=UBB7hp_z3XBefQgx>b@-@+6`eEti>J*mq55#v^y{w}?i;_y5p4%ON0 zOK;<``pn^VGrQeER{yD`;vmx&9BQJ^zf28>^GK;ZttGR=a`opp?gUU$a|Uz`#kiRg zo*m*)6V2wF5$c>9f?k=zR$rBFx8^jBv)2m}CeXtz4Z1Gs8HwnTtu z;Lh(C1cU5#IVMiQ+Q0-&;LpOyC(AyzWOdlqGTlwv*tEI-SLbxX$(%BDVyElM>Kug< z@+aGDLnpGKdT_W=kdx->aJb)ohttu|4>Ba3$dGgz&*MRg@M{LfIG_t13!L>mhG6eN zAKZ-tOTL6FAw=)(_>I+GW`}H=Ql~sU^(jfS99;^cR|1`|?huw-(uf2I-A))g{U>QK zi!T4c4!OW*FC7|DU%)$}-f(>t44UMI4If30Mjw-BmfWi^f&4#C`A)*F#$cNbxHR2DA-kS&ouObI=Td-5kkhCeF zex4=RpB+0fH$P9f^t5W%k2B$^1`0%dGkrGGne^r!sq>E3@6|{7=ZQCC|E(@FVtn>2%zrp&Lf*trdR9IWCTyku7>A- z+^|zsh!1p=mA;ciW75l8mmE_f(0?XF=(593!PU}FO|X_GroVpI6Lg!9hAMin4u-&k zrIco|;!GO_UsNe!Vu%W+|6Tk(Aq(Cq9}4|3Pan#@tp&R9Y8S-Wb9(hnu^7lO9S3r&HLG+Y2Adx1U{#Ttl<-gODN%Q`7E zehU!cu1P|4xw~z(I1tZ}8IZQv#bzao$ukm{%y-#fCgRTDO%cn`A-19rpKKw_@OXHc znc-MfkdLaZ}f-AOmDr>nm*7W)r^zY zP|a5X{-jmICsHRwBAxO4hC5c?VEU6CtCPhg^yBQ~xz+vh{Y%5TAoOPia{Qfw&|jvi zk+%Z}N~X^dUZGA%<=}*TT2f}k6Iu0Dj&uX7;1lJbgn!{6#`6e?(2EC;jKnmenyMW& zD1Vpy;r4gD{I+99?0D_4`}0WWHI6slhVwi`CWTDyaJ(=%KH@OM z!RpJ$wCt<=ECTR=>w>C5!i3EL%oVubkP#HiT))S&8LKSrX4s(0@Bn=Fkga=#c<3o< z(Gxh^vJyzK7FPud>qNcu33WoDp;in5sD4hZ$>|z{5a93OiyYmh)@A4(RN7Mp%dR)5 zVM1VEeJ$!ELG}Me4J169Q{MJsu*S0*BaJ`%ECpstTaZS#spAHd2DZ%vP=g8uarPhblAbVR(i-# z0Z`95PBnbDLK4N}eG?BC8ka0`iQI^v=IXc63Uq&^f8x3Y(df`J{vDyRjC05uf-vn5 zGLp8V);r`s5W5vS1dqf6-pvmy4bRgT( zWP+Az)q(6((o@MKEkMQ4r8QmG&bZW?+>CKV z-@4R)%*Vm)g3&b5x(vWu=6sTg@F}q-7D1-L67tPAtERsSew$ ztHb>&-|000Y5-N!NcKVj zhLndtM;|7IKQ5tWtNf9-qnBbV`iyRbR&shOo7?H3PDklf0fNA?1y%MzMNq_!@LPvZ zYwxEVzMG8b8p@NE--C*Qq?Anc{m>9ih-;M0ZS{3TeYzS2hx-|6+!yW4Yn58_O9O)@ zCDER%8+>f#xt)||7nx{SHX%Y%+s+LeL0C|cAocoIR%bUxta+5u4N66cOF?P+uZzo-g=bK{8J!>{2Ay{xIbHdgtU-q-M`o?5`b5xLj;e7| zksq-wC(Q$7tV@6gImc|UUP;3!m3H$Y(71)LnIZD@~# zKPcAu5J!UOO-*yfTPK5^jM-83aU23B!%#O6J&dy1^nm?BN5ysYiX0UK$Wk$#b>k!X z`FZgeWlPqttdS{zNXS0bmFCT8ugnY8^_#yH)nOKBh}dGLD3do;=WifN%obR@+5gM5 znW;TvX>FEFWQ!y3K{DVBsanDU4{_wp$Nm3taqbxv%z&gmmL(>Zo((Cr*OL_)gF7CJ|dh4}GA-J2X1rk0;q$~fHebsL4EG{ff# zq)m%-tbC17RBGqxmxYS!5E6O?cPlMFwtbH|UxpyE3khn1U297D0Lx5mdq9RvkTma| zHDiLI4`uQ0X6_^2Nf*l;?qIGBBU#&+SlIq%5QaQ!L{^6)#xs33Ab+Hv0y!qkXksx( zw)B-$Ne=Ie(dezZM?8uVvs+(?0HE|m2OnD#CDi_(&y&|FM6&qZDw!uGhwvJ`VMATq^$(#{<4;hsz1=)nl*t5h~4rR z$wTL>G0en$v}j9NB6=EGssAf(J#px=21*oZ#-*{g@=KM79OJw+G8hNmK1MqjjEiWR z=DRoc9x%U3V6Lt-N?(9-cv&UJ3bHMoRWjuwy8b}|VX1-RrPFzwM9H#h*wveGUnU;_ z2Kt8C5Kcft%CnKYeS_oFuU-Ad@@txD>;iWE*(>$%T|f)GZ>{41&N^;NdX1w~L(6;) z&6Uv`P8nT#pO#pC5E{qV=*p5Rsws@@+iK{yS$n15WSkH+Thm0;;%By%?fv7nvbb5> z$}W3+TiL6>-&STkx~=R@-0nYYD;q#u+lFmrxf{2YP5jNavI3r2Jac#!^N2nQ`a|`z zyf@IG6XYvy>3>M)whsL930uns^33O%!#6qd9eb0cm+_Oo?qeuq10NU%*N`L% zryO~D8TWLBe!4{n{^)knesuQ0UT0mqE0A(V4wF3Hr;#Q{9{_=a(?o5|4pM6e(;F6t zYmH$DIe!2c?_PJBasHvVV0MhjCz&O3I>I)bRtP8)vsAV)S<4V8Lbrs8JxC?0eqbI- zB#u39MNd_VZ0sMEbFiVx0AdFxL_5$9)}6z7B8}&7B~=pEs(EV)iz>U%pC^#Brvb%L z2$A^ysNOk|zCRu%03lWXET$*o3dT~>q4wSD^zrrby$r_no&4nJS77H+TfQIn?h1Yo zA<*Mg&>_ngE`}gquED3bf7vMqpmC#Q(rC1O%kYHh&%P%cm0-VGzLOhcat?l@o@&x5 zyLqK~olGd`khl%`aR*?ax%;6o+iPLWI22xo8^3;r6rSI|M5LaC$TnWL-V5b{{n(C0 z(C1G$09D*ybh?{6+;4~XYJf@6m`l2`z%{)@sN8$&hg_<%PZH&g`k)+WorH7!dB`6}E zXBa3Z<7RM0YQQOuA!WoV%wjt!yVDax#idJe!p<$=_JAboQpAseMY6IczP3A>^(Fxi60bs7aj7{HzulsqM z+agF1NE}LiK=WZHTS0og0P$$NBo3s&d6I!ZDpKeW2ClmyOz?VYGyg4#@d0G7B@%}NL!+^QKUxSgbxxebBys^>D?}RPWbz4iY}7kq=Y@tob;c5v4D? zfmfTXN<2w!7I@V)u0OBGWAtkmy#iXBz3NqkS|IsKXG{GP68|%ma7M7vDl;${*GT025#4LH*YZpu{c~= zFA8jw%+sS1`GrGW5|Q6@^3yI;F=TfQp($eCvEwkT@vX}8BH0Qvi+;D@RCcAx4E(STv*a|4mZ1BuYo5=dj3a;e>?@Hi6WJ?IHczn ze`@u7f<;KuucN`nyJRH_0!{rK6DNXrGbc_!W{L>Y=La|qXN**W2#nT#AZJ5#LI zq~D2?ZJU|nc6_7Q2i!5d{Yw(UOT+W^LqAG~aVeKs6ULCSCSiCx!fhDw$kJg`$OSnB zq)-DRu>%}Ag~;s^$)$5|0#b=0t$q#rk~!41R3c4nsGv4j$XzDa@=AkZZjGz_`+}0i zni{ckOYe(4HXGDsF2ou9fgRQD{5LlXrStUtj4_RX?l9Kp7MY`^rC|Us~ zDle}-(mpIRrHN~unO@~88{J^iqh}XP2x+a_4kawq*EPrK>wW}SeI2qY*NVNp@8H7x z0&To$eJrbTcFU@q-PM|#QtzJh zYX@sjN5KGsrB;y*RQ&XgH^xR*eD)I>bk+S8 zi%!p@I$is26Rjbz3tuyp3d^zlT{(5A+bLw~mOtd_J^xK-$@tFX3e%7kC#;0VDgsT* ztbX?NhOAQrW*Vm z2+_DBCs+2a;CpffYa&$2{aRw{6sAuKilg|OfmyhNRPjPyf*Z(7MQG{W&5wJ0Y?ASk zND{dc^s7`$NcbiRQ@Co0ym>=bK;`k<77*xfa^xAW70bLaUL-(kFpl7pT!5L4dffW! zAn~D&idAvn4E$S_KU4e<;?L6${+SLl4!y}QYwTO29+&DqV@N%pc0yY0-7XHu_K`S@ zr>LkUz%~q6NQrT*4BPX;|245yYT^zox+)pmgR7*E<&zvkG%7-;`Hm#M_*1I)nL9#P;D?g$3JMN zWqMA`PZ~EoV#=8D%0Q~K_;Ys7(P1)r_uwpbD4kZ z!iRICfBovMW#}Ld{$v%_qmV{F%h9uD#K;_|D%>OG>h{PXs1`;IKTs*<&*-OCu(9Q8 zYaU^)?M0N~2K$PkH|D0+YE@Q3)n+FP-xJfJY8}C=G-;X`%kqq8OiCm2N_JkuDvV;6 zvUVg1ch^U&G&kdx?F=z$6^hN!;m$y5R7njV<>|}&NdwiTrso_QZ!g)e!snh1w@G+R zNwW&i>k9Yk02=Q4J{T4QyJGBkRN*RS+Gg4o(nphRlWe1H*W2X&5^~>UyTvxn2FI)l z8*jVAHqti1HcEv6poZC;y@uH`*~h)#>}NG($L*90_7#okjSlZHs1Szj9fJ3Wb_8cH z_vf9y$#KTgN+x)D1(E#^cFnh~N7P(DLR|ZpSX+|Zm7kc&w^{aUxOV>=D7OFPQ^v=< zcgpr)?1i$U)fsgZ!Ygj0Vn_78@eJ69!sEtky!8qoFC%WM%J>xmM9qh>@CsOhl=W2a zD>#kB*&nQ$H55j1Xnp4EpyZ|Nx0dDWb)7#c5J`ZeGbfN{ZSZ;LOVOSa_$t!V(fWX+!8?aQ>AW}Ak4HsN zG`NUi={C%s-J&0tjY0Ml=fy#l%w3OK_x&VWmY}K3THYtw#XqujrYXPc{gEY;vbVsI z@EBmFSYs) zOrE1p%rFnFXxKLij`*v z-JlQ6Mb}KFAvl{HAv^PBTasIn>EDcBR@k#({8?TC@1?oqP-GRh^k=00JKktFg|GyX z=w$ek*)SbD;HtETlShu;$PKPQ_&Omyr`KY|vw(s^uovJ68*H=w{s$~xDRLE^T~H^) zY-J;m)UMKH`}7@mA}yuqA|#v~vI|v&|0AtAG;9*mdMid zeTYo?tgsGrc+XR8=TB9oCyoGKyezD0TguVFASi4r9nR+wJq!b+s16fG5|&p z0+mv`WeZ39BMTyGA~4myAU#K~V8|hJvhCcUOufWDl}8@ruu^i!>KI#~3b-QtH97hN-vUTAM2hKTEvBI5>ovKy2Z3pvwj$dDw!3Zf_~&G&FY6d~l6!w>E^%&IE-OOsL-zi%a1=4@O)EU+>=Sey z)6aa<8H@->kXGKvWx<;#s4s{VH}Qa4^Mq#74i=TI$szkCwLr`A{R!Pa5{iszeOJ*>VOG`cit3g4L~WLj#p z!p36X=uW&+lYxS&?LD5eh$C@3@6?Yr$^}<$kh}5vE)$=$sE4$u`W-5wWgY4gPQUqR z7xT=-iAw(4b1S8rtQXfyJ(R9BI<5n3yPWCz%3MSh1R~o^Yu(wWf~7a)=}$<{sk=rjv9hms=!p!lgt;y<+o7s# z*TYyiN$rV4mf-XZj#<)ki78{+Vk>g{e4^%>>DE5>(o_Ob)yulda{@t^nZ{D1uQ-F=jFTX z6FxigH{QR4Xi*A%UQ!sBQ(!Ij)#=MgVq7NGmBrSbWHR1tQWvJN#Kbh_R~4dW)ZyJb zPMS!;t+KaVEC5tmf{Tr2O1SesrAfa=*N#9ZpXZg1x))uGYgsTNuZH|z$ z&|e3%2iJWrzE&BQz6qRfa?umRAwk!EEuc?%i^>Vh)Q@+`vaoZHK7&geJkCTWxNZ>$ z_gJv6olix{t@1=lK7}X5{az6D4DTVFC+v<@7rPxnBTojX+#c!t)Od-!^w$nCl>d-i zvvkfl&v#4MpA*!<))7&s)a44Q^b?2wAFneNE|XDkto$2puxuYWR@F*+I*8kR&^cA~ zAmp>at9zh}!I|AwYj^d6=jUp8eppb$w06KCtpPTF;Gc*=rgkv-ST>Z7Y8z_elxcAP zXhcBz4xyE@AYT^-*3p3Cfygm1ai#ybWR-EJ6su4!!VaFNKM$zaP3hI3iKf!4EO|ra zxRW<1BV}9za6Gp(9O}qDz3M<7DYaLwtMqqRjTX8?zSegsze0B;2mZ)^GNt{x6$E&vw{JJUYYRT*CpXl*|5^$QQ-YwV_M zQ0_93Yq@p4@LzW*{_BA7U#Hesd#vm*4;f6|!n(BbM9g;7rDVYvp0uct32Ha_Rdm<2 zYVQ-V2$V5CMVTol(_B|CO3PzGV9hL9&oxsRkI2gX#E9l4y1TwT3TlChGhyS|2fe4n z|0_vjG9sT8e;YsM^x)VR3*=Vk+ zxW;PqXb_ILnn&LyM{43?g?_PW?R*`q!N!y=MG%a7t_asG-Cf2c{ zLW=8W)tua#RIq!tlwhywGdi>7>(B%@#Y_6lWuaT*C0F8>`;_~792Pn5RW@X~4xoUF zBgo;sn5c7DWw?Zd4N0-emligqo{K%Q||v=xD8ex%OT} zTd&sIuP^sU-qveRWvy%?K35Y8NCio-y5u4-QgivyvOTFsj7R0`tS0wc!FNAzKjNL_ z1-09|nT~B(S9*ED6^FUF2BI)RZNutim5m5@(J@=fK{UR-`?-Idw^d7vIO8jC*3#0- zn;nn*O6U=jaa@dJtTwq>40RnV6P8);JD&m$W*;-2FQCMe{_>sAJ@;HN`&ED8PGhK4 z!i3qo=?xX)PBw;@Ghinx5I5Un}Qc>Qlw$o!uoF%(M)KT_UwNV`;lgh3%n+orBaWJOk zS}kjXHhGg{$N6$6FM0_y;2tf%!#^lI{rd$I(pwkYrD_0L;jI#kxkci5XU0t8VQEkDy zL=Y(Bq;4xiRZL1&qVX|VrhWtmTyjI!G0L+UA9YaLtjAkz#)J8|1S7bPMPh8hmo}A^ z=$%HwOialx!9=N1D2dA7W6!Uln!&91jH7fX=p}bioQ+L6y>r18?qJx0esX*Am7%M6 z23*RSgNs+nQ;f#fIhNp_@hQVLzP@7Y=3e6-5_Ij`MFA#$E3_XV zqW)PO{Sm;#v_>GuGW;MGTkQ({$iRRF21HTT-ztXMFsr(jl5hMQ0}9yowyPHqg(yn? zdJBp#Yn7TKZ{k)?1b^1voYExGhwPN18})}DV?q)roUxg>jZF|zhKvQ!93Mk-uY3+e zl}XeUeSru<%Nd}|-xzM3SJWC03k{>z@SCr#=Ia=*kPh+r>lAdi83ft@MYQ{xZq$^e z5!p1xY=u=C_5>oB>J_#<=hA;1JJTiwVGg z(hjAK1Sxln$6$sH*>;hwF-DSxb?ABRRVIKehs$0dtr8DvP?~wJVni){Os0|*D3dhv zanc)^JDKN4j2ih?DfVht8j&pNnpNLOn%|Np!c_Ou|24=cX?vNdQ~tphN=YHd>X+L{ zX7FQnTP1WAMwk7+H8iYfsz>)es?_x!o2VUjhyr40DoYu$lo7vyp+%C_D1syiZgbi+ z*W4L%l-UPtWh^K{cm3>{7}c0IZN75>eB;xm70vj~Z1K;WvtZ_oIbtYc+O*;s3!SEC z+B9d$?1drsLg%cmH1lUjuvx~;Sw%DFkk@Z!EG(LJwSlDy6FLDZAQmAbF;a~UR| z9os8i*p?{@{(eKPP8Zr=oAoM2L{@qeT65#tM??w>E4;0;H@HwVctS9XGN0b~BW!x` z!-%^MX^c~@!ReZj}yVoD3fo!TX2iHfI7kG-`zdc55)9$?d|V+9g_;{g##g=*ZZlswO5_h|b?NV;X+QLt+*Q6_E0>OdGfj%d0%Y9)?2ltsoGx$^FYlxVHkrg)nfA&aD0EfS2aiAgMHh8uXp;kkfvx)~w!M&MUj$d>n_UMY0>M!iZV zmE@b<0@ye=dV;APe_U8gt=ZOj8IV|FK>!OOzx05y6kM4VFI^0l>TmsDN-?A zbud@NR06v?{1R4=RizkJCGU1Zgmxi|C!M4}`}!&H{#{?MU9Xl6g*v=Sp{Qv+YipS)U|CqVW;6Tu2A;=ws(6<0%;%ZK zGnHo&&sd%e94gj2*!fmDCi|p{#sud z(!*c3A8FeY=DfB$m>=s<7FkNe zT0WZC(qzsTbUq+w<;*y1*6ne4y&1nN=_59!tALrjHNI$woSluy5ofJT2#?GjWihVV zeWeW(qi0Pzf)zm^HlY8B6Wu4L>QnJd*pV+dqto*THvdC9f4lw1f>Gw2M1iOqI zEQVP8n@OY2F=iw!7b`_4;!tMlyiLH!T!vk`P46i^z$kn6xh}R^6j}<$$j|~M#2`sP z86??PX9g)bDX8GOlJxm`FW&}o38+`P_z0uGC7OXKtjnwzlI*;I80mbqo#>ykg|vKX zCXJ+F1qCffP5Upod9TWOkAa+uv}rJAl!KB96YDr5aM9bV(|9XmBO}x*AJOZ3)8dF= zmY*fA^2^|-lpRPY&wefVbTGJEKo9Tt*qUK}68UW~*sEPM34>hh&FH#M+nv|APjl6n z&)1T0tV(zrUF2?#X4yEr=M$pUv-;~K{%+E_zuaAUpn`#K`N%Rf;(UT}mu-MHvra6# z(5wQb*5mUEzPXZ2)KW0h)zXm-wmB2FmO(4;T|F_f;!LL}zd=F2UFgsWg?1Nby| zV4`F7jT_}~*iC|xqhxC&0is`drE2~pw(`m^mr3&vWEya-v78i6*?3|HlDfG@+4)vW zk*Ph4f&sQfyjG6myA}$LE;e7^_>_z+rW71*34<&Kp>%A#aOq^?XZYtwDn*AfH%f!~ zc@uN>iIRDvdvCI3d@+rLY1rX?WDE|zT=giOUfP^`WJ>#Y(zB1a@%u;EhY2w0SaCh6 z^xNXdV=rCQqrtWx(JFThJK8BICj#lQ4Uk5QP^BY;6p(_0^W$^%_qg^_uuwUAlSEN7 zX~ml`pUG5i6&hw7Sr=&a{vw^(zyeBrM-RL#C@R^4Tb{Od65#(h!O>qtlw6d|>ww-s zUnBONs@VmR(#|(D6{ikr}#X{Ed9kWprGBpIpw~Gma8W2X@^venUY_OLMjB5gdHR zQGR@3##2xrzZ%qeNSTSQwo>xo_&e*G^VUfDpCubW_;v6=l}LD63Tg&3ds8NuvkqaUFI zY||<7#x7SbF5nVlE^h(RB=&I?D@?mjcct5nOYEj$*>Pr)ZMs}S=iYaf+!OERX8_N< z`9%w6IOi=8F$w3@vTypcnsQ2xtEwK-e=But)H~=2@V3k@1*3FufEs)0Q8g7RPprXd zExtI;msix~E4!nA_9>)qG6ircY*l-r`^*T(>OYYhGe-Q15Z}#g*X}bnI#$K35XVi9 z)k6o_Y<$W$LqrdlZ2nNe{fbEo^6XUUy^#GdUj9XC+S+ zPX*6>o^d>*c!uy?%@fOWB9Hud*7G=d#`0XpW9Ka084G4zWt;xMjJY%J!-nRfqM1zBq?z;PKgbV;O2sB10kbj7Efbm9J>5#P zNYEnxXUa8QY5&jsW<5A}#sjP%Y=D=|b|%ddY>ruKF(s?@G(D7N_T1Ud*SZ)`y|~{>4UjOZSW2*De0P z%ru!lvllpB%-UJA7oP2+2WHIwg?ac(l?ct%U#tLoN+|xnRbaXx17|ESyPTfsHaV?% zSyVj3HOKkOJ$^QSHR!+ez1f3jt0(O`XPsILRO;${aDLIeVzb;uG9MVjMZZxaE`ign z(HHlFiCp?41!wIwIr%mQ2!E2bGBSzol@K!EkFR$ij z1WKNp9o{>{e>Xq+AHj1Owfh9RfNP>BR)vfLKry!-ZagIKn(&cI^u>f+O{G0sF6IU< ztc_k^t*7w#!i0TPCHWZ}x~aVIJ>8W7fN$|}WbMWVu{?O8zTiVvrqWAn8WqiGvQ@ASy0)pLB=vztg4^pHp zO>}t6Z=rx~uL)B?Uty^hCOEu<@j;09l?PtSL0h(Q@>(U% zU<7$=cBtw+a5NkGYyP8G-4+V2|=v zV@9qJj^h}Fb(83o&jkUdB+QHt_P|r~;_chZ%ozieBJ-%H%!S??2o~FJAtIm|w>LxL zHg(1Alw@@~C7^ESX8A3R)~7O51$7&*%idl#tVU@kPb;Fs^?NrFZd{LBG3fng92M`N zN}@qu)Jc2{Docnno;Q_){&^9H+_%?TG2Vy&ND^gK#%|2Rt>`{~CstGTnYz<`8inq2 z7ilo4R8`N7%eZbJEr%2PT|6)r?dP>7*EKhL-rPy9qWq#+lS*8p7tGF`;bbb@Ib-hV zqTgiCSTJJ#g6tU&-szfqr)$m#*L}G~^C!%7j-R(^RMAXX*V?FLyEZO4u2&Y$caDsju z`j^Lv|Jxl8}ck)9B5V zzFfv)WJ#|BDeX8b>ai9tMlRm(ChGCF_lPO#ac5_0o3M;JJYPa`laGX|yC6tyM9yP2 z4l}xeXr*+aOTy$l$C1*=}3mr-CC36p%QJ88l zQULoN0z2)`N*H+8OS$4+Btd6MPQkt}vQ3Eq?tv7GIcsow!Une)L-`77Rdcbnt&^kl3aa7 zXUAdeDc{D_*eE5XwzWhF6Z&*07}3y6Mz^#f3YY`x@{j6{OK`Jquo74vEa{&W26pWL zBJzE-^OSjOcTHsaLD%=bAzD457h=H}Q_&l!fcRalKJ}S!C7FB4Ib0>|R0^vRuYCYk z+BdmbraN~sH1#O!bM{Q{KGzTKeIh4;WJ$nR9&bv8t(qf=4rqIRDOsxzTT4YvOu9s7 z=QUfIK_E?TkT;m>D|u^!_ro?SND=n#W2G=`C&D<|R? z267((2p6^jzn?26j2xf2JMsJlPs?|r(8Rce8I>Ar zsWMNn6C7Od2DR!dSWR#XV zh-+^oUx;jZBZG@9qxmW3;K=NGnkfR=`gx~?blfar3wkfy1;V`j^euwQJ(i>Q4Tbns zNE1S_;9yjmhY8V(Zfn5ZJh3kB+RLro+XPN& z<66>6DI>|DL}y_I`(DSCWL|l8GvKNFu(2)qZIrnCYciNr#c7w_KnM%3ZwBxCk7Pvb zF@qn$%Qj5cZ(M^@`VE1UAS`GpQ7Wl?-z2oa+|t|VvEab`k`v_1eBRq){-x_}L~ks6Ur9YH&WNHHpN+0+I8`$3D2IF4HqXy20Ry zq!Gm%Uiv)&lC1QU!1m2+aiQBv;?yy)uJ)H}b0=q(X{K_dbS)5@y%vAnU`T zB+^lJ9f3P-Q?HClGXwks2{2cH(JoWK%p+Yy-#(cFQYq zBA>z40f&FZ9QXv*y|#uq)c&K;bNdsDneFCq?ZqWhv#ePE3R(T@{L_NFRkC2|tZAc5 zV+2W9x2_$&tpLT`lX3_R-u^Mcb?(n2guOEy)5fHDfA*0F_}cFYAFw_cT-W|1tWfvY z#H8$rfWdZh0&MB zU$yQP9W&H+II1u?o5Ot6_nopj^CG%Qw0(P;rIYgGxloKu?<-q|!_$k_rVWcPgU^@mBc%G z58?$fUJ?$GguHK&H`!e$DZGC+vm1yL z?|AgXQ!QGJ`-Ew~SNJmk5KakWHKuf)q~mf+lS^dNz?>Y$TYv$%g^7lxKgx6(8L9P3 zZxB;gYe@o={3C)%b_Ze{{wm`2r-4BgDX%Z}Q47GX_J8Q}uY*`uA#IGJEExS?-&-Na z3DNF~)Y85CmSiupR|YFiMc5XNWZkSwfhFWb&ZTeV!S*A(T(?r35|g?xEh`|J4V&l( zm2C>;(``!lsK--W@A^n%@^q-HHe-lX-dt62iXZ_&Rp6SRZsy7uYVYvZX)k;)recH7 ziBec=inXMmRvjlyHTDM_x%s8Gl8V&N!r(mz-Hh1hXn&4sp6AaVS z+JhVgk5b_j*s%j$>&rhX;@frbzKnQP`w&ZCdK>+c(s1d!rMA~9CQ=STUl4>qeMI2A z$uJb0vdIWkQU_qPM;?@lLKJO8eZJZk{z(8p#Fel%*`UQU|suZBuPu+&?iZ$`M$gaJ;y55zOJP8yP%ZX z$tzbCTbd!M^y^6i4>l)xO29W9eW^+2x{xF87yt6}auG-vl^oxzraXR(HYqu-y{Y{} zcazOWm=7;;iJ`cJvvG;UCG@IsC2;Lbkna(-{Z3st<9NT@G6J{6OiGR?HtulC;SUaf zeYmODN3K)Ew{j^>MA&Rpazgu;5r-G_NhjT6`+}Hs(k==c&tX+R!4=c~A$A8pwB2*> zG;XbV`qEp`prDuWi(PWPbr@IbH(_XUtZw7CWig`LB@eLnA6(Db<+8gwI~|^C;h{oX z&XPkLMaC+CdT}JgsU1WS5_3>JLQZt!sP9<~)<_WgxWy&|nHHxZ;rY4*B1X z+7{vw;Yuw=zU=47wRZ`%gFdMg&bjQ^G^~<&*5J<9Y7r&yN175}r`=y&F6WZ1_N(Z& zQ9~lboG}yi_lM9~2*QUUYa{}neUpLyxM|w;GKuL5=$k~i+!<~oUsLu|KY6=!w5duu zRf>+N9yKr$h(S9q`P-^dLnE~??Skq_Hz)f?4N1N^uHy4$1LFwl*`rF@$fdUc`)*N!4s&8|pzil<)M(I1kD6qK{M`((r$Jx(iHWM7)M|o?@;bBNUs~M7*9yP}bS!;$QrAN)TLYA8$$>~u} zE5vDr3`viwvO<1ihGe8it+YaN%#h6Vs5Mr|a5H37demc9$aQAO*z~BiR>&nPWYM_v z!Ru8>o^F?rv$_n;Q(`9jYH(4c-Xar!kzM~ny<_!{)H_apSH0u)x79mAR|oJd`s>P@ zq`#!z$@*6HzFOa;-q-2t)q9}+n0gP=SE_fS?osa{`V#fd(4D;9dozQJGWFRiXp}xf zy~pYW>OD@MsNOmH9qK(vAEDk;^fdLJs^6sE)AeiAdzRi`y-W0q)q9S9o_f#Md#JZl z4^!_l{q$;S@e=(z-cp5^D`diaA)znJgBDiV zDjyQxKoubiMjxP@P2#*nIgg3cp`6X)j8x9!;yk@dTB?il8|6G9&M%bns5qOHvsIk$ zDCa40?orNwICm&#hd8$?r(i?$jmjA*&Oa!pNQ~+lPE}<=rs(A=LXau?0_BVs=Y7hV zAkL}EnJCVQ%9$k2(aM=D&UEFxTATxw^Ez=3P|ktkyhJ&HjcC7e4iRUha)O(t{esGP zIa8e9DCa0~exaOW#o2^YRe7BF-ck`c;@qvAlf?Owa!wKF^U66@oKGp|ba6h46C4N2 zE^V!BSq|@!8wJI^7?3gevg+sgBw=HEm2kB&P0UB%OO19A6wcVR7-tW6ZDgi9&E{&) z%Pa+#=J>0+@yT^oz`U#tZ1^$YCHtmy=ID1l2k0CPR!@t(70}W3A7OzKjrWMHKTV0x zipD_W?Jdv=YJk>^>3l7i?uf0S!ofS{3BS-XYHwPlcbTqB>N&w5DZyhZboCTU_)@eq zt<1%R3ivocwkn`HO#Ah6td>4Rw3oB03OWI>8V#pb%tggI9B6i4DMnr|bTQxDdenbpWb}o<-W|y!Y^&@%?r43eCFA0mSAJKcL7ERE!(w>sCkAynv zN5t`Uyb7M>uDQVaHJ8Er`S>KBOX zCvnL!W=y_>|}-K$q}elU%yco_@j`{x2&i9#YSr*Jz~ zJ++a@BCaT6&fWXlCpv>IiEh76T+lfF3^+sYWWcNjucWp!SiZ+!$7L-118dP0mzS$! zsYH|k8-w7ug!ySGFB2T*#0CULfl04@vdll*tss;}&MygJ5tRnHpd z74CXSVPQkRS`a<-i^bvLUk+`+Rfns7XtS%A+X!*4(yf>tK-9};;`t_?q7ZxUd4WAhK+Z%g9WE~H`s2pO{MJH zY}fL;X3bd7*0P4M6AfF+jHWRl@wTG(&cv3tW!b~vb!>=EE`!(EyZL(Z(l0Sc&2Gmm*Y>MG5-bAodFGtwSB%x-e&B%MZcd#s(+GfdP{u{P0}v3${AY zcW{XotsMx)`B7M4g`hrLJ8*AsdZdN$XM@pal4+r_m^{_@S~T2vIq1eLGE2eNHy&c` zE7`vmn?82ewc6N>h{npaoGip-F5B6Qek@KKk>ENXs`P`-K8t#!RmwpIlOA+xv!_Z* z9z?OF%0@QFk|}tBq7#%>1!t6CzYoDCzGmdS1zGUX#$HVe>h zQ)IirHp@1LfAowjH-X2WqV8bIL7pd)*Z$Ikl9GqG%m@Skza@I%dg~b^p+~)U(xcFI zCK9EP8*s^`MZGA<6wlwu^4YC8t1jEjui9z7>j?}F7L|Z*e;bKA{l^8f^t;o5pJSZ=!IK}nRmd0mZ3Lm2<6SdP2?`E2vq&pE?(n|C z>`BXNc6eWuX;j$M@^|JU3sK#F8m)K8|00bHVPul1j7VC#QW{iq7!GNtpTkvpMnA+y zDn6`^;6)PL@`HYmcU_6?VfesKNRLf~+*M*1ZzMnZ?Rb&8m-Rq)wr|R}mIYS8yHy2m z7H$a({i(4q2_|;^VJS@bH|6dGjr@MoUzav4dD8Z>rNe{0<;`i3Hca{(B_aSXx|8OK zP`;-PU#MLQpE8SWO2xDj!*nw4Awd7(yC|FS3L!fOa)Q?F93;QOa*>F@psLR~ao=Er~_TD_M#_sDMzf!3vB}HgLDO5t{lXZ}J3P}+X5<(!t30HBXH)F%fOrbLe;Ai--*X=LpBy|a$86+nqBG7EiwzvV7J+O@9i`WUoVXDe0=X39%^3b>$4AY`}+jqe{*~ryXrw~y01?F z28q?*$A&>mNC7F!_Z$KFkI3&A+@QA2@~5fH9f(l;eHu|%_#ipH=n@?&;|M|*IU49* z7jNZbBPH?H0;yDrosxSnFqW35=u<%=9v#9Pke!zM8uOt{={uePH^(^K61+qeP`iKW_-u+_>nDG-5%?Uq*i~aDD-k9IkobOA92^7LODtSCnJ9^QnEqdy6Hbf&72&#CeMYlQX_K>6=U|)h{)TgiYnd`#6^^7F^kEn zr-lGga&?g6up_eVjhB2WU(yF?QzTA4h%ey*B*B=;3oRXH498cms-YT!g;N*1P59e_ zD2d}R3Etblbwbv`!yRSYiiO~<=V&B!b>`=O{`HXPAY_lPL0TeGKYp%@f7*jWuqZ6$ z7%4@ZmSp*kEpPn|_+5XQ@;ChjwU$FNL~kkDruGlIiwx0S-c|lhZ(;dcY`F;CV^xzo ze0Ud7b=s8w{VhWM|MC`LExt)-HQpdh^?OFBWJcw*|EpVuiu9JD+}t5%I%<6_bks-W zsf4#UrX(u*BmV*ICu$o3?Xj#Vd(fMM-|? zBX}OgT3IEy#f->I3Lx=4Me(=Nvs#n<5))drNP?Cmyzoo>Z79(a7b3HyW#qmtWt?r9 ztf*y`<|suQj1h@OHlrdVpWfGff%kPA{7AD@NVAmKX34Y7lBLa}-Ga@M#b(KiZ|?rJ zNx!uR`TdIgj>shJ@`i#&lUhIrsY|AbuPx>$;V z3agR0IMP=fDf*m4!)HYr{_~iii&k+j4E4uok8f7!_s1PWV!RxYU!j0y zJfnz2g)zM*s)0mB242%w-RljLVk(sIHz@k6tayfH`_cEz6W#X`DO>c~cg20GSeu`} z6lNyRi&S(bL9&YB-G8z&`F7?9C--b(};d<;%_dC zE*!QQ;KN0j4jq^IY{h)S&iG=beWZMJA445~d0`+NK_8^3e9|}X;_8P#FZgZyunuxK zbXyykdWWXwqLGYQKJgjKdnd_mVR?T)e_x8H@RWSdFzcf1DSQ??KG#J582v zKtts2o9{Gvz9xozqevXT2VQm@r1#=v@zOhnYK|+GD<1B^n>pCvWl5&}@yE`#GnE&; z=gD?>&y(-??LCd&du4G$d50z88{qklq`&cJvvoX?#$)m$$;Fl*??EaKDH@Vr;d_wCYAFt!^-5Nv;fO{wd@PZ4jT4q2 z+GCArZ=nQMAmrhWUd{F`!Yj77oM~@u{MB0)q-xq*Yw!xKWqw?F;_967An*GegHOo# zTcP{6z2p2O@n#JVft;_;&Vo^fiEInUXGs{RR6#u;vesYSEXi z@01Ad3fqcdJ<-aUQxU0x=GGkaUBg#HcF|`I@pDAo)wtkA#UqUNn{yCdmZ)O-=ToAH zuqr2xctN(L5yFbKy)gc-{;Je4q2H81zeS;9w@Xofak~_YZkHZ-?};LAm+&ECWvp&W zAnST5$a_x^3G?0)h7UH)rzM7m|_!itDd;auJ@& zLZ@fwKogH=qUE|$?kD^aAMBcg&#R;3EERlY-FFTuop=PT$b9|+{_UZ%Kv%c8JeB-tw}<4In7MHQaCqP~L1 z;RrXRBb`K4H9$l)LMct*N$Qdp_QW3LqQk#*LwsO>>6-3|cM0&!i?=@hD706!PPJFG zdV^(rvsbi1YMp`Cx=}R0buL~T^60fqqP^nY7V=mvBos>}v~>1M#|+4h{;_mX;v&4p z!mN=otEzgW^@>(6?G;rs?G-nVG^c6u+sU;pz0SsK=Vl|!kb(&@qvd-{Ofn^SChoQlXR2Nr0rxakAd*beoPW)*xH(qA&qN zIs`3zfxUo|m(s~~)KT(IR<>76NtN_0u0`Q`ek1>#^}N3^+XhuG@x*%@jK@|r&u>Ep z?B{Kr>8gs{NqM#k#|-da}qh zb~x6ljxwOBf3_cA*--25JPZ{xd^i>>b?$*_rTGC7ZbbT`ib4ofD~3p=mA-@_n%7m+ zyOnY2%@$DW?jrM1`U9p-`Y2sQNbFaX8uejHlIY@;cE@}HTxTE3loWP}bUG&d8)tZr zRP?E(YZmg^!DH92UsRNW$EFa4#!ME|cCR68rl~IGiYddiwofwJ4`MoQ{Q0=xW_43B zEtAc-vrWkpmW0_aTC^wyJgTb(E?#s6b`@jA9iK4YUq5qPB)i4$y2Y{eaGelrz%V_8 zYez1~Jj~hVqnZ_E%`hudzpR|wY|BYK>!LR00K+)$@?Lf|_%uh+_nV{DeTK;h8R}&E zbOPs6M%M7E&kXY+Zk6Vy`IkB7OO?|ldPp$4#?%h9ND1S7GQ1ucJV}Ci01NCE&cDvt zIe!l)W-Go)Yhe#K?CZyId9}H6>1F(>ICR{E=Bi-MjYkf{4rJpllXTT=;^sq~oWphp z$9L|;1crxy{&D0KXN;Z8rk!ItG45!(m<8J4-S%Te6mo{dknq(R1}(S&k$# zXpdUj;h`5fFRzaqeQk>*yQr%oG&2%|jduE?&$Ff6sj=C{|qN>yu1DR(9X>MX>ayF8ghkW)MpLn z?x)VoO@+Ay0Rle%`2W#tMPX8#4vsS#$EIQu0komDQ% zFpC^>ZWdRr;n>Z6JF1~XhDl%B@%TdfDUR}+*=KxpWtmSBsVXX3CplHe&CcdJ$TIi7 z)+P*n=+DUy9XzQlLY6UG(O~T@+{GE?s(L1}PL|>5cMgfQz04_1c^x%+v>bE8?wfW7 z|0HML+`~-FhcE zHo6n;N-pZcL@#mPv~S%$PW+D@i#D9^!WbPs4!<<`LOU_*2cVSLx7#7&;T;jB< z&WpJ;qAL?Aee#Y`_lumV%fHueckjx){0EcGrm0Z3;}* z!Ev@y54LfH;8$*B-i;YJL+-fV=3|`PfUrxq!@4oD+BYV~B^}}DEm>L9x3wEn&tHo5hR^YiT$E#7;Vw0VAIzLV_A@{4S*kQy!D;YO=- z()JXssu>sIR?LDmS-0S~4!?O=&l|)W>J^vcE~_jZbBnTS7>*RvzC!jg0Tbc=?p%)- z)-UW8oifcZ>BuOW#2PuUPN3`h;u5^9#JyhE_GgsUGsKdxq$%%PL;?6l^XSTtjtli)nM9zu0@`<=e!wSSnkfPWYW8;6okO4w| zzOX9aNFHTI1&5fvYC65v*Da!yXkPk;q?c&N5zWrJmMCOcGwDz4WUG1%V;ik;2v{{D zHz_p;pxWouglyS7$BPVdfz7e0#qU@Aw&Pbon(|lv4BL=D?-nUVZ*oop`4^&SP1#AI zt41eYiHG^DQD3x>CVh!Ha86jHVMGB&*c2nT`Iz7ZUZa#rYpg$GBoVz0j<4mF zR6tfZ#jHtbC8SHzfAtipfI!*!eTUyH{9?!ct%us$aSG#6d_1Q>PIcjYMsgy~H78oe(X(;QLG?juOaK=D$!`ikQ4%1IajevUJBY}(J;t(!tF`7UU8Ufdeax^-h-RHd7d){ zMst|u<5GRr+=B`IULH|?$>%W6j>lrJ+=DeqtL*k}dCOt)^RLyG-Gi+sZWO%qNaQe6 zuPN#eybnu+!JDLtGdYZ2O`5I!eK5(98oj=R$6@ZLe-6HSABL=p?vPuQ#9^v7TjhMY z4^uA)jAo60&tZ;L8}-n80M-s|DZVOLpNZp!`D-75aQu+-ixN@3BNUa7U3&lp=^=6( z$CPoH$E^c1%O61Hk%pj~-_kft+QLW`{fE#;#X8sY(>4w>jvHa+@DL12H*rmDt2s>6 z7oGFr4UdDe2?SW%!3nD*pm|M(g!$C11V{_x&@IvHx+Q01$^D4>oM@dUh4z5;|hlvd}5N)*BDrN>qV|>+*b}Wt-gNw;74$Kqy7m_ z^A`@|Ieh%>^^YL5bAx&4ltK;@pZ2&r7Up`bv)gHo{eS$zdB!moqS~~zb*-?xm7O)LBVu70w<>nUo)8Wr+%!A7Di*%S zg#=HNi{mga<%cO6K8BSA748@Hk>5osZyh&2hIJNl)o={QSNF$*({4Qm%g=8Izi)lO zVO&Q~H>`OKw|e?pEuDIg!*os<5?~YuR!6i|H*CW6Qvz}uH^o7|#dUrEAt>)>g^QNn zj)NTEzS*5aaK7l3hb0N(V7*H}lbDmpf6ua)hQ?1Ir&oCMB>|4F`KoDWoSuMmY}x+! zLnRz0@_vNOohNXh(}SR01(i7dq_?=%J%JUA!%Kr|UvQXHlQk-aJq5jhPS0AiBsk2B zyZ3FjK81|xNV7DlRXF}mOvt?Z6rNYy%*jl^{&XE2H>2Sx+`V#Qlb#OtSJC6)Nh9K6 z=e0}9ZKHEJ%u@fW6Sl>Jw58$1b=f$+lFItV-HQhq+q-5KcF3Qm!s+o%@vyM_g@Z=E zINmHeFX$M|gF$x|B!4-R#bJgQwd~u#1A_?N54nEW-mUE!-6D9PvT(8rbot0(rk}3~ zsp7#Bx3y{ZWkL>9+u3%gVFJiDw;XI3fc;zOJNnti1bFV+*)u``$JZCH{VO9AU`79; z$-H)~-_dHhgdhQq+z#PNU;l<)5q70t8JY+>;bYY5mp5^kWezoSof5%LJm34Z#t&zj{I<(slPlAV+bnZ)7;(AqRvTJ~I z5-d8J`fY6&Y`=8z_tNMjIP*};^-eVMH`D0&&Bi2{5!!o+yb#+z`0G5^k;zbf;D-@6 z0PFXtnL2%YGR&3BFWcXM^ChOAuja#K_$<9X{=Tq*!?bPJZ*5M7+d(^PdiKZuTvszH ze@qH6zR>T6Pmj9W5=fd|C$e#AC z!y*sI$GL`Kr#a8S@{3%aM{krzO~tOjJ#OH8s z#>w!5jkrE#e0nV*l?vZ-p36P_oWWsu>n{$Pk_z)w+V4dqwBz`b&sw}c6&42>e_S&N z+k51Q%i-s#(0(bfyo*IDhq?ah>~q-{@a}Cw82Gke|K75aoB0Cz$(YX@J+_U*v=5D+ z@Am?l#%okqg<*SUE-ML5djXc?){M)ptH=2H?}Q33L9lpZc!4dhr*`9SE}ZugOe|LS z(z}ZN*~QBBVZcjB_pmOMl)&;-T4wjpd8IG=cjg{Y{qPDtyRP)<6@&8mb~P%jcN+Zo zTGw~(SZwdgBCGLB(;)asfVJMT&m4xEb|N<<4f@za}}N{2EU0ec1RGHXFI!El|aH-4UHv_f3a$`&)WE*@fzpiT16Q+3C>z zmAhrXl+LD%oy3~~N7KQ-R-zAgt(+;NDX+LPBORudDRv6miQ$9Go<;S@0Ettf=SCe+ zFl9F9&Fo>B0W*&@Xy3JyHf8io8V?3#z|i{v+X^ROdt9sgDCcLu%1Ya`ocB0hF0W9# zt&s^@D?iFbu8}ciPR38Qwao1p+LQVQNDRE32`5J`+-PBf=@;+6%zVj&1^0Jq z+!j3IFxnZ1YW1_Aq_EfB?bbLxc?BxM4O!q+WZkXO2;ZN2bw_CT+gacLaoKQ9 z_vq5bv3O&zr2Fmqj%?VlKq+ggKknb@qs)RQzk`$uT?!&rpuRIQ{OFPc?;!P}?*{3? znEue)mJzSsf&btkZtL`M|GG1cKTt6TUOwO2#c>DT_ZwIGe8j>W*x6mO%YpSja6O3W zwDfci+&QD?S(c0AZ+t)LbNM+Spl3MZ5Y=h1mkbrQFC7X9=cub zRW%|C<(~j@ve)0ku8@8kA5X&dnlr)UQT2NW?mAd4XgK!o+ltx)!#}{PIj?tYo~CHZ zSblr!?D_%5%+h@5r-SQ})U^|P;y%FSa!JSV4jkWaA4Ol0$c4J2rwk>-@^QaAdcA6D zF1$E-_-64gTz~mGwF?gCLcyW%L6cq~|3L$!ax-$_d23}tk{a&c0{$xZUU>l8;q7}f zaJ*ePest=xJcv7YZQ%WqZl+9-oZQgMc`()_P=z-I^-WN)7+Zni!LPa=9fajMf^f~y zeE2bGR7k(6$ghjB>wTAeI5_7_<*5Md-X# z1W8k7TK|xpGYUZG=^hK$k+}Y4E6FbnD1c8lJR*D9#dDZLv$R&eFMz%)r*<0s2<2<3 zu-;$uBLrI9RuA5R>%oFgUPWs@!klG>Rq1O`AJ7T!wDi_T81ec1*IUiFo)tgd_oMM6 zgfz}yvbhxHzp3hKDyI;J8FrZ=bSvO6_Q7&b_7#Hkj9U+uT|<6-p3TcoD}?G-d2X5q zvHj5lv~*NIf!`+goxUG%z6B1_4qEmJu6dpL;*f&lJzlSU^wm$WW0?c5kD>(559_s3 zf=|%3aAC%(Zn*y0?djanw+Lj;+}FvwiSgqjGmdkMV4m5LN5=;BHDxaRs5MSuw1ecW=MMAQe;QO7uoy z_Y&~e?DC>^0ggAvrA772Ng4O8af0qsl2Kf}8A$-}xXLw=^L>#SV-8LY0Fs;tezuzBEK zdE-*BmKk4BSBCP}&|Y@Ry%aPLUB15Y2lii|b5Zx+mcogNWn=tyVE-45e&(oM1`B(R zdQ(=ZZpw5uHA>!6219HQzmv*G`G1p5;3buT*Yhmhej}0J*3DrKJ->i^-j0XK<(Pim zt@(-TzQFdB(P!>HLwQMmJ)8aH3#>L4gOF8 z8~4nR$=rqIySJ<{ANduAwC-6lLlMIz^Y5KK@fDhuZ&q719_M2xz3zP*zCst5dqcMt zqdeQ*;?SxDpLH+OKMuq7Px{rCru&sJbpOo<@4IW7GP~lOoqJb-rRBh;UhXLGyaDMO z_Ey2tGqRy_eQ>^>Es<(0t%B{7G!(vHd&gl$2@ejKQw{Yey4Uv0!}X(!rjp9TYS^-( z#kKnY)TbVw&MWR;1DSWuTv||y^U3Q@kBER8*wEYbw$@~Eld5P%d$G_G?0_lSzZn|441#lrn`&r>v0St9} zZ8sBX>Os5j(G>!yc1b$g7peY|EG3whY)gl3W*cExF?vns^%LccML)xo$;aIOi0Tlj-aen?$0G&=>xz+`#e{56stO5am zgwOXw`2uh}XVf<}PXO0Pc^-sWM0} zq?EJ|N*6$uxn$(bw*r_PU$$`F8v(edF0b`@EdbTWle|OI1h8)R8u>@B1hD^Lu;1I4 z0%)$g$CSPhz{!;dHV9J%u&QV2tIkNR%0l|7J{Q24vEGjTo(aHS*&$*`iU6WIs~3+* z7Qmp1o4brl5iqQG z6PAZ<#S0$A!|9PWCed;G(op zt9}ZO$N1;hT_y=&*gejL+6e+Ur~j(WZansHwRe2lXaO8twz<^ML;&5){T=ojqder_ zP0uk9z?pF)y)*_1U`FnV?l!vEzXop_j`b73*QglXcntx}?WPs>xwimxWRo{^s0zSi z^U58{$^say68=KHn*c)YgSBQC0laQ_rqio4&MU~$m+2&cnpd?eYkt%~%h(;!G0inF zR#jo_0znPv9xq>z`lSY@-oE^~PhkzTJ>tHe@va8et7+F+q}4#Qq@*z?sRp!$%dYQu zR09c4*Y}=}s)1exk7oD2Rs-Df6?ZqEtAWuMd;4EJQ3DtBq8~;2*1!qNX)34PYoOeW z@525fD(yq5JfFlgDdXIpG*pzG`dt5O!#K;%ppr-qp|FxfgW`8(7=C1W+Z(4+?X zez7yD%XJHqR04_z#4cs#dx*+_iC7BJ(-aeRKvG%Qu_)@ zs)3sx67QQ+4Hs%=dnvxGh5>bJf;T>?1}(#>?=DAGLxY(`$DPa7@MdxA=hLUEVX(r* zIg5O&A#LXk>94!0L9x^^d(oz9=rZ5XGsw0YCbad=ytAMhEKiypzGzkrn-_;TuN_ql zi|Wc}O6pgG+JyM5ZM~~uc-p=gP*|48(9Upl|x1e&R0R*wy7o`j#PnCTBboD?lbqV9Lns!sR~p% zAvxa5s$lo0Q2vA2m~YgH2am^B!KlG0RmTQb!IRzZMvldO>ZRnBad%{@VEX=9m%cSs zg7av3W#!UJsCzZTur;F+ymWS+yc1su)njdr@Gn=wk(>#;jrLZ8bcx}y8;dI;V7ZO6 zwQ(hkTi|qgv}`48ylA&`;-{}Lt<^-&`Tkd!k+~xx_0U()?R4X#>58u)ke+PwX82b~ zofjVHBK;L|HYUUxy{~|t?Q@mrfS>bxer&fSxgJYlND!8BDywYF0 zm=ATQuRqU-;KTmBJ)<05`JkcEF^`BB=d`;|iXB|Emx z$oLEozF)f8!~HWH{gHL|+ThR7#Uk%{c~%M36*TmV-dO@4w9n`oG=@ZY8rR#&T^cF`tc0l{zbUkxa%U39XdH~L1UZNq9=tM7ZX!a3JU5NjHb^5vY4 zrY|BhWnCgmyvAyX-Be^V#p`msMvLQrWf}d8L6isxlcEt&Un5l1ke`N8Wb!WtQC1dc zEEE|;iHyVsQ6dDi2&=zih5QB!6^d-MMY4GPpA4g{J(QRfMMk+~tOd`KS^lF9)OkJH zKhZ3xKeC9{t%3$aebriet*^__A!gknvU_5bHQITJbpB%ZBvNASp48+?ES*-^ek*d$ z>$h`dhV9g{*-6nG-?{xq=cGJG`=o_w6s_2)5-pY%8YF;KVYPqhATrvBQ5&t0)~TXS zQo^xeO)Qf<45O9Oh76Btq-dSgR~5C)=_9gbL&T1zS*P!WN0NikG6b6OVmV2!phO$3 zZ^#NkS}X))r4U<>);sHFYSYBrL?pzh`V}+gU>I$+)-8A~&5nW`j6>V1Qw5f8T`v+N zo+_|Y@;KWQ^OZdPTCA6C+^U)w_Q-}bLJ#yHx}e9CV=p6vgkHu8kLo{|}9(xprA5sKJSbYkN7=F;NO+{>Cm>xe0oJPY^>M`5Elu`^QAB|S@ssn`3f zl4olXUTl>|nW6>XlFTPe@q5Al+E4$rpZ;qA&{Vf9-)BhjXPx1c#-|VAkwsaTU zJH>WTvAy&EEBmO}yTc#$QI6Pu1Nw5}n}_zJR|ZAz zMbtOLP*p3$oHvnJTN3LfM1vIOL$?an_|?bfH$^@glrR>r@i9#+L*}>ZT3WUUFT!iI zBUE6%kM@es^3kYB9#OQ$XZvi>_LGBb5zh)}vl*&tPHJNxJN$cX>A#iA`|UdFx9iZ~ zt^9=cJy#AkXhw?+)-eNRi4pp6wTsqG~M4F3NNDZ|`6d!=K`hZrYECYMR zR&4Cv5B^eIj5kOL_?f^4pX{^#hzT{uAcjUYv}mbhR`!lz&_;u46Y;BREQ(4eQ5cp= z@et+LNjZoY|8MsMdD@aZ{z@pC&4@KLhqX)6UeU)oU8H|@k`o4U}^jUIx*j|=Lr~Q`;Do` zb!H?&#Bp-|;6?nQ!V%UPQy#(qYwy0#x5UN2-1M-fN$C!p2^!yJ?49U%=IZC6GfHoO z!z>l4Uh0wYPy6_;zNmEt#teJ6NTXMH{H06k)B8<34X^4C4tS$;G5$(Sk@0RNdw4SI z&H~F#`{OGu2m`~fm-wOi?k#P)4f?M}%@wTu#^O<=JRP-~hhTZacH6;T%mkX8i6MAU?7Mgf zN*%sw*Gg#?=MkJ=lamDdH5B~jq_wc+Bolo4u1C+I>n@Y-AGT_;=~D@A{yyLp^cVJ5 zl0Kor;%NkLaasBnj^+=}QAq8?;^_nrZSu>2X)lcv{8s3*cqYM3T4^S~F-}3H7F+X`EJ+EeU z9_*R)piFC}5nE0H!Bg)k6u|1kZ(Gh+iPIMnTxxB^M|kn+knmpLo^1Leg3Es7eu7MU zo2Q|ngITYz~Y|?9^SR67`$!HUTA8@ zH}KL=DZ#CdoGgJu!>SZM%MM`iGJ>nuPWcQWvYrmj&w8`?7lOw?-Dk)wi9S%6*@MN) z2_Aa%bSZ@Q){$#A8O!2$ev4t;n#SNct7EB6#?v`0UP17EzVFIltBMEj!@V&q{*~Zk z>^FV^$-DhG%1-Fd;*|tXzQ&Zp(o^M}Rr~ZFNdU9;~ zddlaqt(71=Ts>yjEOjv??fAxn7RHj+L_q#VvM6 zRDqsN-}>DH#By#V>2*rF;rYfrcUP}JDCVEyX^Zh(=2*Ik<Y5^idP+9S`SA?s7%S+#kQA6aSMS{Jp?YapK)oScszF^ z8TW`jYm#O`dn zJScAUctQi*F>bo))y(qAqj-$gyaqV?-eZQne}pj_ds!pmWK+rRxW>>ju-Als|iPNCRAI zcDvm?hMkXGitl@LqXAaE8en-saS|&ZiW@h?G{ES*aHFr*Y9gFRaq})ELcT44}Z|pkB(DSrmW5zbZ#WMHox_cuqN@mNvpz-M5T?u$ccYg#Yw8_Knax`g7pWBJudAcwo;h zjS!b~T%!<=wPQMT-9~Y#s9lX<^2IM__%t>>kK(iY?r(%7uj}o_yN9y!@5;qohpht| z;nR1XbKTGJL-C>w!Htkxn{+&LrC2@`w^|t12yXf#ew=j?j~|M+DMdEI_Jnx`>+Hn) zi##bm^~%FW=-WPU_Uq%5S@}>rMmeDo&SdOS`}}=2%Rj|=RxcZ2_U20m4?kq}6P^fn z%ff!l?)x_Mj95QWAmxWT7c|1CsWZ&_0*iAgK4xZFBOE?+^XXb=arqQq{iC`Ox~m3- z?oeX&LmtKX{=!C>aADwM(-~l#0m*TUp&TfKE2R8AiyR-b;QhfTGg-vjMagU%XSyrF% zp!k@AB~8#J)$7`po8v`%hEhBtePt8O)esK#S;~%o9>w(|9Gak~uW6Y2MpkY`6gS?y zxe1OH#ME9uJ=(N^eW?zyRMS*xdK%yVA|S>WoN9t>hs%Mw z^6b9Jqqr0|qzN<^+;m&+ZYC+-SM=-hRLnoc zl}sX=AfnWJ+<+r&KXNHPTlQWPY*~9`+(22DPg{ylfAOdZM$XnTde39^D-Vj>xW+d@ z*M3iiNd>a<45c_*Dc4@qKUdn&AFkBVOGnmLD#~9h8fjprq9$c=soEeXyl? z%#^Ywn5Z#k$Lv1rIPsu3&*5tm@FGlx{dg?qpWb{1+^4$9Y#+E9GO_haEo@=NU>0At|!ZMk|`# zXSo!YZITg!^s65)ZA@7?*iyXqmb?(uW!Bpa?5`*)$AjWAR^5g0RQ}trOf&X(St!Lr zn^c9+G+^EU+h^=J^bcHUc;CjKNL^ytR;loUJs|*i1k=TmGHl9*8m}O zTzP+6%0MiCiW`5{6N2xQliJHX+4;z&xWNPiAsnwN+z+bkeq>AW(8I<;czk=^j4g`d z{gmR#Z%l;n#bIT`<6GkSOYu~xu|oLfKQZ9&Yj<C|+u0DulGKSyMY)+t~3#akDuS zh48vnN~1ZbguM^Ylkl%*J4Fa9osP{gj%4)~ZHfo2ogsv%@M+t zdR^7|%H2frv86b7(R?Ay-Z3&Sc(a&)il>fWB!umGYeS8Xvin*n#lw493t|2CLit7F z`NgBSQiY8W(#tbHckE!-+aih^MA-^qqVAj>o_Xq`dYN8?fAx*4g;4vw=F0hYG5-`- z(smHy^K-AYvKra-ic4|h7aN4Ip{ASqu|4d(v!!^5!)76zyB`>1Kbjr49u)Uz-ztQl zvn`$Ww6S<7#TmctLKx!Hq_FOkc>GYD+ij;1D(&hf>6xvHVAJZ>L2%lOG2YP*F#~ag|@NY2htPoylH$A=igY9>1ikrEd7lPna{kl!d z*z{bAhn%=51l_xM1G&2NMWVfm4`sr@ZkIe1Xq+sd-zrw`$uxfPA` zboJVMXPVh^v?;C<^gsy3;}>p^;Vx%xm>pe3u{(0Xj&W&P! z5ArC^8IdQ1(1Y`jKa69?XA#BSQVN7HdUHhC(3`B>7h}oPm~br?G#s8QYwW0lcej+R*CfoQTlgZgz#Ro&~`?!(F80P^=*o4&#u6A zNvpBb>Iz*E9!hcfCzV*vd&mB++Kr-l!J~M%evJ_NM8SLY`hKGHMHH7hS}TO3KI@lv z^kL=0XmGKXF}3x0Kj!WE>8(Cu{wY3tc9Rf-y{_pVaA)^TF2yY_Hw)pSR?^J3L&W+U z#aB0d6T*0PN8yAYY&jkj-#4jE2;s|jZFfJ(>MfxZPd(I*ZCg>XCB45Z#c^W0$55b^k@xWjIlW@w+Cxl8L7 zyKZwS&bcMm43m2JZPIiRj~|L3&h6R^KkjDR?l%}BlA8y`S4(tjhTwZ;U8SF~=|d@= zjqjQUM~OQ*y|uMP>3I|{ovhppd)?Z`44;>q%*uGhmd~Yl=*d3K;8SCAXp}|CMLC4wl_^tQape@sL8`k z3ITQ0&_*67R1Konh8buDLvy0CMidR(5YwV+s3;wp7*$?)CMs=L$0y;Gio8nzBMm(; z(qG!VBEl`9L|PIbf3n6hY?9ETrVt}4<1?1$CX1QzQ8y*xgtG(_@$sQSOsqfBR#Z57 zUaUZb(?{aa9i=`#4MiTnRJKw>uF&(Q4L)sVosEgmAE`A-jK( z`Sj19S{Sx*V=tpe&hZBK2E|?N^$0L+k(%CwI8mNj_`Xg>qVug2@m;U3P=8 z3)>Z5$LDCs={C%!_6_azG7dlEhYQ-y?C^RCuc`lSYR}L%`RK>iUj$aJI)P~;5@2F4 z)eRnT)PA8|oZ|H}{=nfc!O_kUaQR}lLH1{EH2tYPZntW#{rU-h8OF;+l(R;|JMv;&-g#uPs_*o z|1MtoTYk}>M7IF@NyK`bYEs*8V@&PZIyT{NRuEmzMvV z{Qq3PY5BkPAN;ZY)A--|AO6@sX#8*E2maW9X#8*E5B}J{X#8*E7yj7)NIcp9*#4=7 zKlV=&|NH#;bN?mrzt6uv_itMMZ}V5|cZ1;gDT?n-Kb|ap1^R?a;NRf*UXBSp9TP0$ zO`cm``Kb+{bD4lqp zsf`!wjbi%W>yNP{J1S$Su#p!HIlsdfT-x5z1 zSruW1WJb4EhL#hm-9&T67=I(w0v~F(!P8CF=z`vcI1WIU`_||pLmzWlJwt!!ig@y< zLc;Ug56rH3AQGAJtU$j3j3l~i7+i-;2@{IDNG3c|!Whac@vm-1UR|V6E8+)_f9b0- zv{vc}AAP+O9ampf2{BX-F^p;~O>2$Hq5h2k5&!68fpBBhh8(40IxL6g!$W7P#B0JU zs`2S#GgZ;C1ND4B{Cl9!j^CfoM{N_2UtzHdJS-Ny*QcWFQWDT#KI1yw`&-Ah<(}W# zv2Cu7zfziu7*~xFF+v21J`@tuNzO!)a~r;%hmVm-v3wLoPZ z@_zrt+lcC($}o7~i@b{ndsyVgUewIJSpRR%>=ha6@P1pUh|#P5t92OBIWWbaRFR(6 zJUU5CaZZpV?my`m^1h!hV7&JEiNy^@IL<{MQ8~ZuY zt*3f4`Z!@}&>wUX8y3?ldVYvu#59-3`60HY}!IY*_ofx}t zfA}y{hPUc$uPM=xZoV>0a+0YjV=H}lf#3m{tv8-OZZYQPy_~S|WGviH?lgPHstKk{ z(O@ST-KS81zR4z!H#TKFvUi_<&x6t#Zu|P*<6wSU`K&XEkSklTgPDWnd2HV5H!m6P zogFecOo-vo^6gO)&!8;zQ}+7>SikxFo^nyo;d19MSsr%i$CWD;8f^Xoo{gNdbgd?s zGU-Z|zC!eiK13?Ea_ML+FZflne;RDkJkm6&2Kmw6u=Bv+H_%7+fUD<#F{X@h&880z z-@@eY1A4#J!t_zQDx|KYgPHugFM-C$Z_ukqb^8qPTQ4Kes2idmTfukFL78x-?fRab zw|ilE#c?GSnUJXAuPkqj?VtYGQvF&Mc<&3pzd0HGC|iXjc3qhb&tH%Cp0fh$<0_rd z(0B(&LKH5wMvXLOYA+;fq`!l#<*kQra`jA^mf1RLJ~`04&aY+YR((@Owt!LNya(QP zi{^ao5y(#%9IQaU*Y%Uve!GqBHTFG}74!iX57m^h7ovP@CH19d=7QOV!%=bN$iG8; z6d{>9bdh8E1z4NcX=EMB6 z2l6)^LO-#xk8>U#FMveH105IIl`wx&K(|pJAxF{7D&N2a`@2}`M)pVe(WlmM{)gdM zo||3fwnB(o99TW&Q9Hh8!^lxl=@Wct7=6z5jREo>9FiLG2^^nyQ&O1F6Z`AM6))W) zI9wbw*U_NADO13;>9!U9;XxF$tpw#YW@Pz-_#((UkQL&4zqctf+vt3yTrre)oiJ!^ z9{L&1j>#Ias2Gy6qQcdKaJ+cL>fDC;IWIKNyOzL?vm>2HEI|3F@B20=z67csX004^2>tlV&ofyp^BGKP z?JW6c$@o1P?lJo_JTZxAJHgd3Wzxz%a*uz8Xsd@`^G~2WEc$E+{_q(lXojzN{T%y` z+28oKZz=2>-0e}$X7uY`z=Z05J89beuCqJeWmiLFg@_(&gr*}|IS+z(+HMqTq3t*|Bc?gBl>@>cT+~M`iJR|y{J+$EsgvJz|SxJn?x|Y ze35>IREgEc#S~*bFoXL~>UP1rhglX_MJsC!6X1TuerU13{S)IN`iFk}*GLSB^>8u$ zrH_AmbNZQz??|qx=b+VcCuDhx_KjTc@j{oEIr3CNr}b^nd`4~Wg_}LOBk#Bt)bFg1 zmz`)7@3?b`s6BtHhXAEr!X7G#$x=0BSv|_(8p=h`Ha4}fAFlEKimq1iwq+-e=zzf+3PxF01Mju?Imw9Il_@^@nX&>W}k`cbgm z{IGHpN5l#64)ZV)r^Cc_{K* zvD{hu0bJN~alqRo+#f?{`nzs;2s<~0D)S}LZ#=JbZr7X`@R~h0t&G9;aCQ3M8xad5 z7q2yOsw4Z;HH!x)AH(yx+jW+AL%-!k6`cltje}ROjJyVA;Cp349TVd6^9J9llJOtc|}1jpdYG>{7t6*Ny0^Pne$(_UTif z0zFnvFzhS9{hA5rdCC77q@Ov}W)O&e+8KREEA8j-+Jb8ru8sSbxq8RRd(RI363SEuP( zmW8Or_@tH2W$4l9e*?$uZzE%jLM=pXGAQ*JimK`8g#_ zcsZWgz;Zd}+p=7a!C%<#-{h!sn&on|TFi1e^2}H+$NcxqcUzPk15UAAj!T!bT#n5{ zST4u#A4QD5a^z>ST#l50<#KGE#&S7^_aNa323Irto|GIbud!T?Wt&+pN7rdAmt#8E z1;Xt@j;YW-F_&Xp4$I{jyqD#2^jXGoIi@3)%Q01t<#ME?`AqzBEX!uO97m6O&Tkr}}&A^qG83_yEV6GDuv46oBbxpongZ4)VtEcG-=|kET;E2uZ-p>VZ z9u`=;eskc62HBaZJSf?G>tGlMbjy!wh4SQU3*N(^9fCtt ze(-{co&}qR2fXs)f!*Lu74O2#00;@MdK5y!I{0&WtaKy%#~Fa{%zeK>^%;sMFj=pv z*S3b&PkdpA!b&rrabu1G|AQ7KIZ9&oA0)NE5|RQOVZsy=KJ6Ks&kcTzPi-!R zT*xx{Pz(?oxZZ1pocJ*L^Y85S^n9$ieSt*!IAOo5LsR zcr%E35vLLmu9*pCGlYcOf;pNRM-g0u(}isv-)bC+IpCN*1RW@N{KrNKQ`=xhn^9&n z?78TGmLBj5(3%1h_;mjfz7uLAwFNJs(ug75zRJ+_py-lRpbh?f8I_H190QSUogZW!DrydN_7HqhLn+zhY-%%1{8?z)BCJs^A-A&{rp99^Ay; zaI8ju?>nTHZOnnt%()PH@Uju)8oCbFkZ^OtLkm0)g8?EGLi7R9N_*>DeCt8}x4wW2 zDLyiS=^~(}#p$);oaBDUdHF0N&h-Jqb?b-*ER!3J;(2?Ex=@t%V9G zeFPg@-~l$a;IDS~3qr+_hPF`4w;lFs%j&XrnW3wXf>Eyw+V+OM_xKrLkwcN}62CYuI0~{eH z)^Icw9J|+6$d+@rY^L&YA;s`vwE;Y8`Y_E=PbC=;>itnB-nNpuve7Ut3^!@;`S-Gf zx9^y;%=)X8v}2DmB?*nCnF@oNVw=u8+=JF4?HDOYnQJ;ssa*2U%K0x5hIvA@WGg|+ zpaqlbs5*#>?p6TpLpvq~;=`o~ckTUqN~B9ia1weCro8^cZH*GRy-^9k#SFz&2*s7n z6j#kc+`9kLm9fN~@UR=SHa!*G&@y|IWX52RnMT0=y2sX8gs4D!S=W!*=>11urGg*b zOks9*n0!xsLWbb8TD*a|M11V8g&WA#X1q$N438%cG;FVgeCY9`vatE^sLyfKZy3{%dA#aLAGK-wxH5P30k4IEFC{q;E~b{j}&->7{K5E*B>F!O|(E={)ETU zszPX?aMw3rqYW^q@PUzm2YzQ0`Za8Re(igZy@Q7%JgszaF5rDkY!&|APbGhF#V)X; z?vo?0Qmw7OYA@BH+?3Kl6AdSH>VBMgNh8kke;p{!G!UvQt z1~GQT1XK}AJs5}JstM34KK^xA{nr6e^!Fy24B9Bg4>5^)#5Sc>c&u4#{omAN`jPv^ z#A-p*XWVung)Akz?2i5{)*2pOQaAWR79$Ce_hE4mNDj^!z$o80=TBg{Se3Yg{VOcy z?Ih^UB1QJi#UH-1@sNFU@j8}^#}U+Ekw^B;#V5Zo{>7_VQ{-Cy|dPXhhr<2q*jI;>YYh zxcD-Qyg$jl_(tL$K)4Hwd~3qx`{uu@8U1-=-<<@@Gi377Ai zYZ8BC-<(%T_Pyo%<~LZ*Bm3s!IKtNuoJVjHL3;4)Y0PDRxacRbb zJIKd!v6JLBq|bj{6%ryse#h<1&JKn6#ahv&iDJ}6@rLgG@p!+$Zp@C?S!hb=%JYf7 z;GcJSz=pv&=&I@B_G9N^J(dcc;stizgLfP>Kbiyj2P7|Y72iioNBVCrz7HdXfbj1p zRdZ4EMtos8H*x-~w>=U(L-jp13w{im0O9vm zPY^yw4jzG4E!SOuk5n%X&qs>BdTLE|u%4QH&EgrXUwz1Q*6te%XSM1As2 z$e&KQ*5>?I$mF?Z-)y|Uud^yM!1p!!9ra}I-5XGUHaio#SG`8>dd*ciaS`@&bj(ar zmb^jAVUoS>UwcCR$~517d4tYv`#NOBJMdpS;$qF}x2WpR?Um}?VLyd8q3C+kThwaM z-FnV-9^^0di2a5NWU{k7DtHxckBLWCv{#_R%eD-4UIKRKYu9f+iz?B#gz2C3=D~Wq zl}A!2zY@Lb`Ye2G;#erJ=kDFJDpA@@-I|#_pg#ClE!7mNkWZoNwnrzRd?l0L{)xX z(SmoE;+^}H@}z_wM4f&yd+@lsRQ@c<504W1bjajHDi_k{744K&yrBQgOfH({fgrwh zb}7qW&>^2PZN)~T@4|p=?$M@Vdg3Lw!j%o9ApH3L0fJ)McKz@JzK1G>6i;(ohE6d( zNLgaV2{Hu#UET{07tvnIS>wA$Lj1uun+=B)(YCvcD&MWryi3*YRO_2rNDn{dxI*<$ z2gqOQ#rjEw^z^+qf2)TNg7C>Jc;yB3aPetw=|srimFYzzmKD$^W0LG2%;*p4qcQ5g z^69kk>ePh`gCYKxi9U(>^s$QY=|ghIL-@u-Q=@!(+z0)KA^M6if&Ae~2 z*3c2k&ryBzmS?oMP1bPgkCBl7mA~CDJf+o5cHD_s1o82?lKn+_^yr7X-aq}Ja+j){ zW8~NNgdTO%Nh>*K0C2&tRLdvy?PbQ&lsS_j{yVe3PJc`rKUlzDwGZ^=Pk86N=@G5? z)N{$gzEJ+DuId-hKBPTo*DuP9p91=so-}!pOFO2i__PruNxQ=Gw!ksj#o*tMXf%}=Nonky>E4}6e zEDTSA^r-Na_te+X=F+ELnG13G{wP>!FGae1b-21CD=l+ncz=?O$2`s zY$Vt~u%2KY!CHb~pBrn(`$iD#aWni2L9oNk@XrLL1SJGN5&TFH>})gs-xCD;+6;e3 zu!>+ML9nOI$lnrtL+~}hR|H=Y1pC>HfA%{xidRZ_3BeZxiwPF7$OpUGI2<4BWiyyh z5bR|${24*8m(B1zf?zM3;g1PEBKVMCF2M%`!A>^g{~kfGlg;pKf>|t5I&A%mwaGk@ zAdetLP^?Ad1bGB0f?`b~C&(j65fp0>IYAylilDd~krU(*qzH<;5;;L0L5iSQoyZCD z2vP*aYD7+uN01^YRwZ(RJc1NKF`UQ8lpjGJL5iSQg~$o=2vP*a%0y0(N01^YRw8nO zJc1NKu_BQZR>NEP2*yKHzzK&mXSC(=fccaKjHh4|aO!e5R5Iv@ z(0Boi-zb~zkM_HxL24I=eAxiwSxRS-V#F*Yay#oWpaRCvFrb|2?}fe?EZ7%c3*#dy zcwVNHFWOez`n%ED61Z4%w51=4Y^>P&WEy^dD7f;Ox<9J8=)7R~+;PC0Ywk7$puT#y zUj&*>0$$mAbm;;#eRy&Y*8q55gi1Y}^l~9uJbd5n`M+&}*A{P?vKS2)MbnBiVf;z$ zKb9a0MB|$5dMEkAco<&DJ!G>K%@GQQFIzkv_?7nC$CshEeQiThRj|IP+bax~qZs~) zm}e)ffs1eJZC!zc?_2WX=D>KK%3nXDWhLTX?HA!a3hNj5;^6W>P&QX@^_y!j-lK{? zG_MLq8%z{dZq&r-hh7?JwHoQH9P(qUB|DJ4-as*l@vWv6*gxlARKc|Qy5Zyda$HyAi|9(#8 zx=qNYZ}O4;vAFzGZ?CuAj3P|$UH&x#wf{C!9gRIR{EY`RGNLyrl4MxP531zgoaY>wKSkS&W1CU8uGj+lNM> zaO1&i9I|owjxzfrAqr(JF8Y2r5cArInUW~vrn2U3dOYSH*`u7J(IH12gN#p_@yd$Dm_1{T!2L!T6tw8&EtX z7CB@#pYcgG18y%Wj*ms-AHQDyB^%2ZIF)^jMfd72I2#4y@^HHGcKjAJ;Qa9LUd!SA zAWG3dlDY-urF(lG?2X&cKgSDsJ0D+MOS|2EFemjGjGw4OF3)GIr5BqgtZ40n#~YQ~ z3x9;s`Rk7q?`U%cp17nqC5(DwLizAZ@jJ ze-rHAw;(o@)|)aaB2^EEU$pM&z) z``4Lz%p;z7?*y*-@RE2K9zRx^O&AeOPnVs4KFkjD+FtXn{XrWJL0X)3$XL zt!!|7!qxFuKQ&VYr&V-(Sg)@0`eUB&{VaYZ{ia1^ZT%F+!_@vu`wLdkG1G3;)Cc47 zp1Wm0uNCyJpM2fy6d2!A5|R1*<@DL>ai^zU(FHy#{NtG*`q~^VWld`s?^2^?rqwQ^ z*KfPD`CLC-z7MC&AGM60v!ndNhKYDQn7^bqe<{73(@?}4h3muhM1JlPdXt0T<*qLl zz|~{|?IrZeCB?Ru=ka)-+Gy_`NdG>3Ym$CD9?$md@$SfCdQ-;qlbL760UuSA_;C^4 z;O{3)jGhYI{j&YgMRfO^>t}k8#P!8HUmmuQPI;^RbGQ_@hvo+x?=GOLZ+c{V--Yos z6`ir`jFkhnbOWpSb&~;D8K1kET;e)H6-S(%? zuGRX?;ag+5XVb)a^ozzDdlN?E^sjX3S>i|EO;9oLAsJrx2GN-hT}5|I_60qyfGb2SfAA63+S2jr|uCeC1Y@Tig{ksX3!|YC0n!z*Jpr3T;_Co z)QxBMWevDK_<=rUQ|RLx63d(%aQ&ug88uC!gY8W%5?XNk4;WUW??M-i`O!7U8^<5; zP+&WO9+sh^pVS}AdF2+<$I%%Xn0s)To8ky2riuSB>a;S}LAIEM$~tWHo{v8Z()&YW|7}S z_z%JxSmf2SD6S>^JK0ED6S^_9pRNM@+(-R-V*+r@K=PF zv&buBQCvd!3&M+7`R|vdG`VBDI_ForEV7eu8ax;^Qpx2=b2+_f*m@ z3G$AzoPUJK4-+{--XY?Ckhl}%9bh>>g~<04IYHh&BHv5g3G)6V?t54i?c5zC`XrI6{{M4aAm?Iulbh=+JxJA>;`t7hsz5#D4t;%Vh4)81Kf=6#8}usS>;hFhpMjS! zsZwrA?z~A;dgJ*Dbw!za!#(lTYFUgWp8rrwmH1WMB_H1$bsxZl4_2n$b6Z3c>YJZs#9ONGuBJ*gk8e(eX6!A|2tRZ z(86OGQP!9zcHz}=XU4oac5)1!|4`|w;(D(7uWq`cjZ-m)Q_CB*)Evl94Bs7_pet?lD z>hOPYvx5#<3fh_U4D`fp+)8Es)1fEu{1s-*yx&}vfEBw#ZZPGi)?F;)_TTtPZ_Pgw4$nMB3UAweTSHuXrPZ1g0BUv*2n&*m{)3`w))MFno61SvbRjtMAtO$RH=Mq{1*@4 zX`$ye#XVvUGwr8%Af=54xYw#gKK_CAdplUHjRJqzXJ1{&nBuG&srVSQ`e{5Z5I>2L2q|mA9UmZQ9c{XHXVVoQ0^Na%Y(06|o&qu~geeLNd)wENcx=Z8mqv09!_1rvW@eq#rfr$lz&A`#o)yYKZu@8!l$@82|c%sO~6X z|JAzR*O>byc5pySC(@t(*6C?86Mm3Azb9JYzEgQzvjFG! z{)oz+C`#+%;?ps(zYgyIyb4%W} z$20XefaBg9cezDAWztu;b6q51n1UNi0g*>v}Q zsO!4{cOMxs`iIR(?T1eOwzuG2V*0POvnXRU=wjE^>sp!iz1cIs7`d6~SKYYF+CthxOnFe?9e2{c!u@4;{hpkLD&chJA3x>!p0tk!Sj&72C}Ey-^qeoSN)V)*lTy zcdDOoCv$&?jZ!m3SAO%TlKX4-G@ z*kn@_rtrb2dM1`r-5kZHX!y30*XuUn{(wJ$TWg9G^LSRjMl#`}kck;;9B^n~)fpze zM4qb|oD0%>7>JCNW2{>Wwj+Q+WNF?>M!m1q$;`b6@uuKOgx=rny?6 zJ5l=9gI?kOhp*@!Zh-{rMaC2BhhlC$Bh>==jn=p~)^G@LYTwL!3p6}?^z61pO#4yx zpe)g5U$+QjO;zlFji-$z^1gTHuGEUj?-?&2OVltk`%C;JM&EuuaUeGmYpd%s?RTGV zx+PMIS@Ljz9@dZ2pChqEng$cji0)3O(}xdM>04p0Uc93_eZQ~5tdm)Izmv)-_U}#$)w%b2moWY#UJUC_XP(h$ zdA4XOmfM%e4Cy7=SM^JK;q@l!bIEf%j0<1f6+_Y zfF5KTI}B*sdtu$3o)}<0@U_1Iopk3?H{V~)Lf{3jhZ)cfySJYhVmt=R z!{5mC>4Kpz1oN`3F*kbqT%T@;O8tK81zvBWw!OWqPpi`P#fQr#VQyU!sZZa~A2Zi+ zI$n>Vo>ffOr_I*+2bJ$&(qC0+tWT#UZ?PKeY=Y$)Rp0e!>(5@BBm9jpKT}2P(KSX+ zo9_9K!+iX^9eT7||JP>{eHndTzw_6l4YWs;*6F!md1&=8J-TXq>-MeYOnPP2+In(W=fQog@g#gxzP50Sd`3{RbTO`%MB<{zi) z(z^P$yX3^we$4*j&t=L@MGOnr@(A|2W?>|^WIt3z>kTB@x>D{Y?Gwq^|D ze@ii~O+VIB|Eh9&GL|R4@Ykldzn!A_bP`j($t5x^+VL(=VAGvxf61jswdhmkTZXo~ z{KEPsmLV;A(-ym#k9RQZn_J2&H0k~kL+uTow_y38mq#_}%3Cp;qT?8OzgI|;b}k18e%b<#^OS`6H-u60DgSOE$IX>nn!zFKwHRz)UFAjH$XZ+{CrMuBH z0`3)-sWAHAsPOMb8=f{P?lyY@4!^fj)|J*iTRBo;57T}JRncAPJ6kT-pSm&;%e%bu z?@FtA*gZbp=!SXaJDEDYd+N}uCC8ciyj6Wvo#r*)_HTc{)YrE6NS*F(d&qC8=Lei0 zpAQvkbk3*a6~S#x{aAjCRHI{aC#UZVXYyD3(O8WxExhoc_vyYk{#&1*wT4$34O^<= zfcYp%q$)k-aPHc+MI) zwN>zXHudFeq%y7Lw(E^z!2rztz9D5gD*xQZKNm3hSNvX~M5or9J6~MOw4YPoBbDe$ z(siSD&Sd;gtTk4mU7G!at_>N8!@sMg73oWZgT6SuWXeCH&R>!47O-69eH7Ea_3C8` zw8ems(;7~UzNhMsD$wdek3AW^nf!NY@K>O9^&Ye;x-j*+9$zEdMQ=D>6Dof()5nOeG4QH!W&!=Hbq zK4;pec|&BgXiH`M!jc9i{x1#mPtp2{0?lFjnex5RC~Fess)lwe^d@6s?KSUcoTv_=1%rvaeo+eqNXycZa0_&}KzlGxbM2#YsEoOYA%jj46GqOQ+ zYLoT4aw)_4&2+s;W8Kx5tRSZTdbY^wL^Ixp%T)XIz~RrdpgK|0-MB$IUGe?^W#1ZE zD?0ODnxNh~1oPk@k>5p|UyD3_O_=iP*%bLrRGd@rPFIy(Q{AQU{G~oEQQy*6{`lq%;N<=9i-yf=d$+U;1t+J0IH|aND8!^+r znf!|UAj&(s`dogZeFdBB~dRU+poI>5t&!rCiaS z=6A7Gi$nGofc-$VIkN=GtA(+Vt0acwYtgDl>w5J)kt__2H7vT~TZ>eLm}_pLE%P~oh6j(iM{3cC`L;d7U3YS{<6Bnv z+^j`i=f9pj^wfUNPnVFvyYgz$>gn&gzwVdJIbKjS{7W_1P26~YK#wszPM@ORmji#* zqK$W_-TQiQxp2lDy?h1zIyCy=gwZEJ<7tH?|Ad1&o;-6_%UC+539a&Pm4g=xf@ZJ)6%)b4D!) zTeV?SJql6Dy|wvD3J0CKHvQR*dUUd}QRJDmjq@hr-D2nE^{8CROR>8f&52t0qpBjN z9&OS@iDRZ55LUf4{&Dz7J@VAMcv+&ig_B(VGCwlC9-Zhts^oRoal&p&?@z@R)}!Ka zuRL57lQ~|)xMweasYe2{7tY#`S91(++jjlkr2)N`diPQYP`6URSoE_tEdUXSgr=94}WA+LI z%T!igN^C$vMyr(`tmO*JGVBVh8C|Dv;2L+K|_D`@7f*gwe7O$yR2cJaNimC@*lR1 zX#aZu>NmMjLhJbX0cz74(R2QH{oU2Bn4Sb>Y zuDOp-&H%e!AHIG+v@}Wha=^`zE?^hz!fqplA$L+Z?YaAk^^$&|PeupkRQ(yv8R+5q zM)f?%T_&nb8NQcud!p|)%SS)Z@h!`u`nYj8uKh0>{_*Jtn){J&({kz{NB#BMj4G8T zKj zt?IW93fG*SQtTPkgcfmsPPjBGfWw|c-h@0CUDLOJb5KaX>=vdcZbBN}WJ|o_LxjV6 zFXmhW`y=P#IB+cfa$(G#87-S+O{ht0i-k5PP8jO{MG|KG6Qyj3+v2h+N*EfI=6V4A zL}OnpUQvD~S@>v)lUI%ZPgJzh*4x)SS%~JooxY6!6AkIE*fl+HKWD2#%^HJaKhdxh zo9i(^xfu=Gw{pRj zh+RVcXH!z*Et*m3aKmDwDTjp@bIm69c4aQxYfqx@*G0@}MJ`rY6}|v@!8J1Yjz5gYfnV)yw`$6 z^{cN;jELaCoV(XTNefyv}E@#ZH7IduDa&*ev2k!|}=tw*iN zoDB^{^zximl)vKBWBXk@gcpluryP~EqNu#N_D_%P;{@JH8mOxE3z@&?PxuvZ&; z#%mTF81*1jjo4|#|3*9V&hq1r2snZ%xxZ#?_>HQPG#;D2*u{C7eDe6^lfTh! zt3y4^4jmEJE!l4E`usOayr_GlVfP{7fZ6lE^=bW$uG~7gr7`y~XJ6)Whrt#yG=94# zopx+Dhv&R%&RTaF+IFnWx~eFJV<0+ov3;WqsgLNAuXpFLuq^pVRMu%3>bEgVec#gBbNIBXr+4d>2%oEY6 z%B5<{FQ9ePGXFS#O@OxFkCxq~pP}!g+4GAba^_?;K)hc;!zaD)!$%JM2g+EEKUT-T zO2R9NKYY$L{x!?}QUCM#g3NcU|K0w}6>sLtQ1~=f&oG_2{>%PLKEql2FJjgo9HM~j zzfk{a|0NZKNh-n9FaF#9OBowSHN@Y!{TDtP`TsNfFUf2qCU6YJh+w#eFI?f2k^hhF zzf8hk!e&X710CBn!n(sJwkowu(*O8S+^CXOt_;3AhX1}sl7IPo|Uft>4c6 z{;z$Q|FsXp*q8ZV`!N6AzR*AIlOVX0{%)V>f9=Dt_Ms55Z$m@*{N29AKkegS`QPnh z{ImS9{D1Ak{AFL|f9=Ekr+qG_{rsS(Rbagnr=7Pz=XP!SU1hoHwg*9T=3ofhe270qf^#0|W-d zRsjKU0Vl8dzzJbiWpE9-@fijGT}@aYJ^}8);5-^D*I?F#@d7$px$=k?EQKSfeDSak z!u!VIvrYivFf<()P5Z#0R|gJ?!zbk!!bxt}bPQuk1`e(9!w06}v-jYTF1>U%oFN=+ z3e+`N08pjEzM&G{@&2@LU+(!X=dV-^a6&sAJH(StAS%iepakGb&>WS z!whvhFXp*S0dJ~Qr5rXsSX?LJo2SC>YI72Pv)`n|B|zD{k0za_qg%(LI3g71nAF> za1*z$;(QK0*uizf=Db{ZF%}){X7<`AECaMk3+GO+SWcARDv?q?yQTA2t)nD z%y0D@bros!F!lX&S{Sl+ow!vHnT>4bsOavjUW7~*26ELuo&O=Oo@4nSs)N#!XY%U}LqpzYnS2mQ* zvwMNkBwe3HUq6p5Z4K6s%Y1{1tp@wo%}hfpd)ND(H_S(WZpt=|k*1<^4~|x?@Xkl> z1BdL`4=Z#->aU9z?75H9PYQbWy|oANwg^zVRt|c-&~JoVP!V!Wd1f> z>$A`Yi>$rnU*Dm!JBqVc`-zarkda$%tGz^DM@(>YD#}1Rd6V4k>XsvsPvFhm_czhn z_T#&EiHp#l9s^$Lq+COTE0pX+@dd=5+Do*=Ao13)1bnU~{?#If@f!PkHQn#fgLS7U zg%3)3+I1Bj?#_~v6UN?p)4`8kT30okRzM{2{;-whgGj7FRp>01ToIvni#;OejI zg-B(K%l9LTtI!vFwO+S-SE0`qx1PFrZSN@G>K-9i>Rbyu^pNYDKWWI|LvQOl-1iGT zEq%BR9sIcQGTG354e0Jdd+FA%-%zTKmg==14d`TYX`_w?>;r6{mfG8+5f$YHje)^BNPw#o> zpv`+Se}P*}%MYYic6j!cbGp2qR8DBxk5*JI84{WBTc6kJvHiFGns$^lUvr7ZvF<#d z;Ebtyl@#yIgbH*2L%n#E8cZ$T1|GYH{agQI%->*p^qXa%1Rj3vZ|_vU|!seeu9I^UBt%uV%zifM8QsevG%+B(pQBvA=L=o??1?TVda(Jy z3x3IEvuBy?9^9d?am5Y=qmu3&`ikm&mEMn5pjSrNp6s#t6s>K&BwFQ04Y%KdKEviX zA4Q|;^Jesz^+I$Z!=dq;8=t;;d}r=%shE4s=)lfwelXIS6J&SX^_<8@VA*y2Nl*HH zczK2Ktvy_y4Qorg^c)ZAd>$mZ^N61R*=*f1Gv@spMrGOFbrnt@*>k{ge}NsbzRy%; z8R31+I`oZRJtM8MR=Y!A;goLccg}ATJ(##HM%?>2-8y2?)h|U=+~H?>5Bj|N5c-}{ z*xviiBhlr|B(%_OJ^lH?QJWIO8{E~(A4QphU10&DUH`a5JEdFuutC0vk zuREjvO-xt09d|sMz`QTQ=(}viQ{8rjf9t!?&9Jw^a@`JnZPq$j(=G}f`aU!nl~KIt zov7!X6?YQP@1b{1O^QqK%I8LCuL(GKbwASmb@jb_%QaEx(dVX5`!A8NE-|8o5}#w2#;oGD4wHNsc6d1GJF+CwC4&|gW@op| z)5rVq%+Ks^DoG%lmD!8fWm3dq1hyl`#kQp;_-Lh80DmiT9sr zTgx&&UXT2@zNbtt&n+F;h)viqKj$=ImrciicIbN`OE-ku_nwIRV%49G)f?y#t*~!> zl5@B}#ux9@|G5{f=odIrebsJJ)b2mrC8qG5Wbw);urbb+UE3d+du2WvT({hN+w29R z*V5DvhbNiQZ(@{mhxDDpz2#WEG$nlqwBN_84DO}Ui7z%i)pp14f3m+{50A%I`u|&B zxm=DSt)GK;1T}T&D|eS;q~(MX6{~D6YaeuPN4t^B7woLOcWq@7cZs2bFvx5EzvO;@ zt~Z|c(wp1uyZ!EUcL)DVE{})p-~X*IDc=tLIw@Z+DPPn{`Ep75qE5<}OUf5@Qoe|k zZ%2FRtb9rP?Z{^*?Uzg1FY2WIa!LC|owQ#rX}_qG_KQgS?Pw33wO`Udbm-ej|G*{v z1L~xI;FA6Ub<#g@N&kR4=^qg3A3F5ytbZW=Z->5}^uJuv|DsO%UoPo?Q78Q`m-N4= zll~Wx{U#%G9(&rm1hGcFmQ zp-#qUTrxgGos7>A8K2#i_h+4r&&c>!Ece&R_*X6$cQXDJlku;(lku;ZjDN+QjDKl) z`UH9Z;2o6AFT`?(PUaV4GQXfZnO}&>{DSUeejz6F3vnm&3!2O?$b7T&`30H3b>y#; z`5R5ko7%>kl+p zf9NRR&ek8u`c8+woviQBWPOM3WPOJw>pOHO>pL`A-=RBM-=WF+PDlB6w!TBw&pPz& zWc`dL>t}Q)>t{4sKchQYKcmU|8QsbH8BNyDI?A`R^)s?Q*`aSI>ytEDpQJlkpQOq9 zB;CpSBu&;Q=}y)sX|g`qp>JpFlX83Za%B6p@Q(L!;CxfYo;^ho}zJY|Ym z;zY;E_Noq*$Ipy$W(?j-$6U5!D20r;UfIUJE3{( z1MTRSHz~@0UJf~%98OgE+fU$F>v=Pr3bmGRj5LE;pnB~g%I1%9>ns-jtnhgJey!ELgI1{^PUwE<~kKC%yqyjM$ZJWq#i2{<-C=~7OwAC-q$=q!yMZ} zfK#@!K<`LFJ_X(k1cg-15F%yW%UJi9aQp@K@G~3x4offhGw+H2KgzKa^D=JCyBWS! zAtyo8#N%do>?7^ioGx$3h4(OA^mqTY)f0!Ce-nA#wNkE%Wtt zm#yt73saLE^8786o&YCF(|u)17N!GUu=~6VZ8E_<4QU*R9Q&*6?xh{00A3wUnad{Z zO7T(@v}0=EQtARC$y-QC+8eHd6q1}Z+>@p@<~nP5+&&*JnK$9LY-!xX^WjO(jqbV5 zjbC!Xagl*cmPew#uL8%?Gf~IZz@_vi{E;jMh4Lg{FrNw$;8?#vtd+UWUzk|c{)!dc zDsiOl5-o@o^p|;R_y$oyRLwWZc^rY)EO_OsBmrC{zSvU}xY^016!;Z5-f+DcF4K--{4E79(t413N$w@$ruqr4 z1?E3&ros(qCzhJHKsu>Y6{(D7`)hiabjp%vi9gjSAIBnyA1ZWg4cOP+OyEC$@Vv+PO`8k2v1Btw1WJ=KYpU zfvMl zlu7NNNkiMiKS|tZ6=(@EmxM4i>5((-vZV%KR3u125&+i;wZ6Vk>oMLt;TD&TV9Iuc z`!pzFLuH+F;j(<_clrcTUXp9z+1FQQXa%lbfbMluBw_O)x08UhQ_kxZV% zl!Uv)9=l6FTy2NqvSO~^GuM5Y>uTm&hq->oTq`rzRm^qsHXOE+x&FdjS1{L=%r*Ao zEh%QMe=^r)L!dgOCf6W8kVij)T#!j7x+_BE`sW-Q0*asTfSes$1XsB#eCVT(J-8em z&t&&R3{dGaxD%VQJL>B1H;COMJK5-|P*+*;Q`-tYOAT-Rmf?baev!oofU*%iaaD`~ z%>)+slBtUGAdy!^y8~1O1e=@VE*mLnn59VhO0}fFWl1x-29C{MqpE#dJUDA^PDX7P z*ase)r5)W9+7~Mfsm=%l8^DaK;$N;$lP0fa+`d7RB|bCcZZH3GOOv}j_{(jl-0fP2 zn|Abi==L%K;htb(-Tya?F}Z7zn5O+rV)(ZZBmd^!j_svn zxicyE19w3-TxV-Xe*pIk9=zGgNRS;YFZ<)do}(+ z7we>H3O~!Fqd>sV_LhzZe9(oec^RY-)K%)#?YE34U7ib%8|&GD@w$R6MesWk?jiyB zbpm9(MZyJ7%D(_{Ki)3aV<4NNI38SYbhzrXu4l395$p z!1ykbNJi`%ua;0(lgp$Nu@k4GtOzye`c=@PyG|uY(`Rmu$^@v1AT8gq5BrGCvIJta zxjE_f{x`#O(nsOH&{+j3y2r;#z%q=)_9Wb1Wzb!`3e%GqK? zJE>QY$!5uJ;&8Ikgj(r4;DY82+FP6Og}74s4Ny{+B#%T|g#$>at@ysjo@dRPBo@6Hz4SphleDMYRfcKWnf`VnW z)sD3XH_7sj#A?bU^E!e^g!U>_%>%(EH7ZPXmSpo5&_IG1u_?q@b78czns)3u$j2|`elf!V(uD0W82DF4SAbv0$WHLlkvkj$J~*%kZ}+Duau5%xoaoHD(4}Bu(t1eOt}0FmUW+?HC?71PWUGLUrNqu+VNW z>;NH%!lZ$tb+ltla7eKtb8P_EtT5EF^Dv=Z14p|nYR7(*;R563Ncs?@E2NV|ZGm(1`Xe!4X)Xm42qeDvXD zuu&JPA-joDvJmVk`3B(%3sSHX2PrHSs)FV2*gYVFo{5S-d z5|wZ>5iS!R3-0xecQJ|gHjj7d89yDat>UK-kxqa|F^OLZ$ImG8lZlj4hVS0}qwc0d zaHz`Euvvm6tcYw@5N}peEWY$|mkhRr=g&O@JQjHZF0dn(f_KQkjAx z^Z%}W&J1YX`}_U>pFf`ubM{_)?X}lld+oK?ew=;W0T)6)6B?dp%;%5h^R)RCWZ1G^ zHcLo2DVy=?Xh7+dviT)?#^?~)*m!*`q}Ht!SA^7xtLguNtJMEDuJGM5gR6M&^lmAe zpE9}H)WX#O!PUT4ToF<$uF9bm|4vpfBklh|R(Axs8sMEi&}h;?$0Eo-JFtxukrl5E zv*dZlMxa07;m|cw$DADR*tis-pK@E(R|HVNJ3B6^3@CQ|N8!J%u6Y2@^hSEe#_Ag3 z@bxqvo96fP8{lHKE|EWgR5iJ`90_Cf2EwdO3Cs~@eo@}RZVP*H7mQL?98}F~S)WR(RURuyj2s&_!Hp_4KO9c;=J_UVn`7R-gvJurE7G0*ep9D3F< z-x#aa>pZ4b+4V?_4yT_#F@0MB0@tz6UT6-yXvX3Lx2ajR0k*XWJfPSfIo^2Q_%=p{ zVcy)Mv+`2nO7`9F(>-K-_z$j)9gToDp)swQ>loyD*C^9e`KqqiJ zYj_rrDmxC6<@n@`Fy&*lunZs4+yKV(!hKY!>DjDXFq?9Be#siFn`EPZ6=v{c?nf9b3 zzA=OCYO}4-t~dK_ZrkkCFAAedx~Pu8sF7-!-G9pMn8nLLYdZT7#B%&`Q`jJUsZq~8 z!TW%Q(H=BA=!O{k1%}-$X`)e5O@$dBVV3+Ns^T6xg*}emVNS`kF@Q~B`ZG|g#Wr_X zHrx6%5*w&P6*g%B`M&)0!EY91PiJpImqZIGou?prITUsHmfQK|tsyC~Rf*wn&twNy zu-1MLI6SkHcm$Lt)<={RPUU2Za+1CR&D2YZgX&=gFTeuzF+u8*_Bg2nva-!!(LNT7 zAoVO9b=Bi_XMJLoS7|uhaJ{o(PXS!Xz-pVA|eZCUqYT)r$5#mBvT5TBu@rW347m;t~Z5Uc*TT7cz|{ScS_xSp8M%H&!-`yzHiKj`ca0&|WQY|!I9TDEL9wb00n{Hk*>E61 z8uB3aNnfNUca-}`J0e>7d_cO=3!DZ>uwD&JEfo^-IvY}}Bu@&`IL-O8S&v7knMMOZ zniDHx!x777w~VDZ{N8^cWrDq+tsWz7w~qA2_#?AfXG#KdN+)TLvk6Ym{2$i}fg0$VI*y$hh2 znX{2Cz-Iw8%BlSr=>1z#v{1_SS5a5kO{}c|#omH)FBS6vLt}F za8yaph{9=jPb7k`k+UahO~hkHyaoOwuSb||FA6De98rsZ|8n5fFgVW!#Wskl)m9LH zEea~7w8>_lB3q6>T+eWLBWPuInIoI^>kgQUEv2S}^~kW3C-*c&B&;P(G^pi0bXfd+ zM${SwR{z&-hREf?+3d6tZkGGPSbvE~c|&-%FHK9Q#f}=p)w-TJ<#iFZ$eh{!@SU~J zZ3U(2_P%S<)+mu?eT!GcTQHO>9Yvkx7*Ss((yXf2WhbR3Gt|}AY z(T{<1#Cw5B-5I5pCBQu+NG_H{DV+X?FdL15waS8(7K=I|DuImO7xT~(0|mG@!2Tb+ zv+S?N%H8z|4z;e?8$)fI0UWX!9qxsyt$ilg=9K+OB)P+;Oqs-*o9vc8dtt&vN1G40 zzbn?|ru&=@v7nwX*JvPT6L%poSpGDG*%l0WEo>P&S%8ki9v2CMvF}Mx;Ov&xoIQi? zO`NT`2b_&Vj_IPTcflwr1Ip?IprKIySEkTf_arv;3Qm6q34d>Q7_1-V)i3F}jy!K} z6I;|mu2}{_)ml5X<^OCmD z@MgqAxBb!j2=6L~cer;}JQ@lL7}lOv24<(vwbj~QCOEcj8w63s(#^l z(!-Q)TV{(x80;5*V_T*_WYCBIfP3 zb*%sSDrXZKF2HEffUiV(D7&%{Wv@V3>^4y{5-qjnGZ?>*SYEj@WI2xa3AePX;@i*( z)I$OO3Z5?Zgo0+s>xT8mClO~^E$FWUo%EJ^x{8HB{s{uKu3C>LEckp>itD7RKvMC< z+Iu{a9B|2Q$+>VWr)wEs2yh$c3I5-BCLwbj{{bQP1MIyy_&QMvuX!3&E@6rdwVT9- zJS}#L;GldC(n&`yTu5=oNo(IjZ}RU`3(r~Pp1V-h)k#NEzg*TvFTbFi)64yldIbe4 z68HMsLHPo!Q;%V3s3H~X>W?l4eQ0b$HtP)zVFDNTM1eGf%C`xVHwy?>XG7w#>(LJ? zP!QCcrZ5in%0|Hq8zNYy?!_}f9V#Bnzkd-_3ZnwD1avWmt}wA9S}HiNH!9d3^w}>D z2Ww3d8~0a|nEWUe9Hq{WMGIW|OLKrmf@ma}BS9E~WF66O_<1C=Eg>STEhrPEqf+#4d~7m{-p;+ z!bI@?047$Tft4t}A3%0!MNmR)5ar6$0DP|n7*D`MPny}^LjVfg1ucqx#hcCsb&Ntx zZOQg+g27bH2IRbyE_uQc@P93Ww;`w(#_ZMe6Hsti{(nQk_@w=l?j;AiA>9D z54AEa{A-X4nIIYrjofKly@jW|v!nQKN-sRc|Ai;JwS}|CdkSe{?qXJM2=-aBS#=zk ze2)fw_`_Y*hGw~wUafxHQ$JRIDZKpK2wT)3xeNPyfXzeCP6zSURC_o(G_(O!Cgc^VKlP6Ne|Cgr977Vi>sK(Fm)n z>=-&y5lY8=F~WQ%;z?OIf@jK_f+t@mD)79>dW#5O>HsqDQ)S3(CuOrA2|(QT&t@kP zZteOUM4W0MJfEBo$rz)S73b6Ks6Z7oKAXL6WEZ5KZAI$wt4OK;j#S^(a(jK6!yPuG zWZJnB<#+h|{ywlz*#CBiV*#Pw#p0KN4O%{swD+;&g}E0pzyq*Vr^GDnXo%wlB&24< zOB*&K;EnNR2DF-j*g(v<(z~O7*CR^eSNw*2)(kuRGqvul;Zx@6d-+{NG1tMn<7tqZ zE<*8P(wZ!y6~SW(P!@(z8bZv5am=&;_jEV<-_+%3Og{!36F$y_uc0yF(-!#6CVT#tS|)hcfh6$zn3uc z1(0kxt28kA6oR`#$m~rMJ_c)9EV%{#cN3lncu@cUg~__XW+%ZWZw>*%4ZtM;*spS^ z;x2H-1oU@Is=?k8zy0rEY@h%O*_9f&d;r1YLg;Ks zkOp>uH1;DVUrLlhtAh!2Zot1ZC?9&sJ5+MnQG~q7{;7KW^z8g`x8OL(c`V;2 z)u{X8^St9%HKXrI+7}?E7RCmY4(uf}XCL-7<&5`VE0_eD63ZS1sLCRk{Qg=)_g+F) zQ|*ob1a8)1nT+KM%y_7R{|s}92+acB&D5pxV>2+pP>eC%e}D}}y0NFT0VJ?;erX6u zTpP;83Jl8s8~`?1ygW!{ZRK7nvrF2dp%859- zj(hOw$iTXV$UI_@u|XUxq809G$oj*N%=H*%1J(gRYGG~JHxC7Q7;a>Cyo0?{tHu94 zeporBngyOr{S7-zaK&jN@A(G;?1fNftC9KdfR^;|pHAJsEH1IOG%Bpbkv??4?3gHr z2eRUnpHp(<3>qczd=7Bc!nlAUVLs?~mE0W>n8BwB0&HBXa$jVrp<PbV)q(FK($-9s8PMV$(UzzgRxEM) z|3y2vyIWzOVE+tZ#~9chflavI6YgJH;huzuuU``s`uffgI`zimFbil+$#WeH6Pptv z_aP9V0@na4)>r-i(!P>=Ce}(jqQdgL4%&~?YUGHCvh7aAuYDzHCqalhoP!^wP#L^; zB^F0h+%8y|3C%Nj6~M$))1sE@K9w>JMZbq*5$t;ci+YbSivDjvspv4OcNqJqRkjmY z4xlA??TF+V^#;c4F8Ee~lD@Y`j!J2Mpf&J7;bn@lz!oaj-?}{k@6-vhDg&3#+ zCh9K3fQ7vNspoLM3ajC*)IX^eM?(F{KpIsjHYl7q0slN1x82U9uC2bcnssXE{ZKc4fsP5AG zcfW#<^L(g;7^8&c0I-b@h9q&Jqj?gGd0K$qg@B7%fS&|`$vv>=ibbvGpThY+Y>oDU z!+Fd4CJeWr5?>=~t+3cDPO@VY5OM{wY>BYz>d3FIeJDdGZnbTc?TM5qo z>rFHO)=1%|K8JK;Q>QsD9ES?8C1T$0gvMX5f$VJA?sUBnI}fa(hH}A|Q4Xq=wxZ#K z6i1b_n(SUiHaqnYhP(x3u{crUb)G7XNK2F*X@gg`PfJ-Ho#8*5^p&pc<7=v$14YA! zD#^(34rRE%EY0dX1%H9% zc6L{gJ4qV|_a3WkW9=pJx^jx`EXR~_;lMB3y8A1--6+pw~tpvTY?%i$s7pvMJs8cF-seuSU#r_jTcc=zR!r zS^~XZ00ZFy@F4)flTCd(z|^F6ECZsXab)L@fgfo{_*yixD?58~Ht%5oZZQCX<#E~k zZh+jj8SbzgjA!l8%--Av_2T`79o+UA`hLLL0*3LB7D2MX}+w*j2CK-2`~$@2Q7Z|B_m}%8`0lS{DJB zKGp#}v5mFUZ{&h92Kl8PR-%(?Qo}!>Ds3+Jx1$J&MA}rYm*Xl$(t7-{0oS1Fh5=ZF zAZ*I~FVQ_Ox=lOb|7rEF#TNsM(jS-BCL+auik%Fmv0+AzO$VC;E2D}V)2HL)gBtS* z^1m0v@qdH-jfbuqiTszrtpAkmY$&cOO8VBSPCIAOtBb!iER17C_&BwuX`~Vjb<4TX z2n&O)7>BS!8+Qpa1DK>O1$o;g%Il988Te>Gf_WrQDq>iE67I%WV&$eFD{OsxV=M$4 ztV;-50I0v4w4ssIrcu=N(Vs{M?!k|c421Fp!f3LM*E`S9`P(kj>M^AP%-CYtg-}&S zf++L#5cEZa;6BL%v)O#KEbS8Yg3Yu!&zZOz^=duBJI%3CZ_tk?Hg?T*_$57pV$LT0 z_{PMBuE(*WnKorQ%l-~sG(sy|fs-d`YSlh$Dt?OP5Ro<%l|&Xye~xc-TWk&Pv<}CS zr4MDH)$$csIu?0w$|aO3+|1+%W{MY?e*Ts+IgCv4Y86Ao$P^EfwWMs-+L4tvueM`k z?V@MI+sfUM8)sh#SSLhzv*WE3y7AXhRkYKF7x7%_z>#cqBSJv+jd4V7bVnM6 z%e*^&bZ=hpsds<~tY`w71 zxC5()Gf)DmLId8cn}SZ#RD@_kUa|$Pp*C7q^-IZ$U73({Bqi4&J+XH(WHBk*-6pWu z9_V;L5Ck?kRI#Zd%aVlTSys8LUPSqmbFs1b0oL4tg5HWSdpwV7MjKv8r#dxIooJ5t z7bJTJ^AQU|vw+%Ys(QVs`WZrlw>Z~LRX>HQS5Vatb;psVtW(s|Q;@N==U9Fto@!Qn z7=?2XF1j>Wj>6$}vdw%MAw{MY$gycN1eDHm@Hv12gU&_qbGuN$ozE6Ec9Hh%Uv5)* zf?8g~=K@1%lbY2at#u;^`gZcVB+m-OM5=JYYF61@|-n@ga76T#W&zXy1 zZfPjgpE!3iH1`y?qZ`SEkzD?Mw`f$7AKxUxOx;NhWL5@%CM?&V5nvn9vhk$pNZ*nUYhCAm$N&dZjOx|2c07TbN(8r-(Y zlYCiCld=PgaE7FvM~bv#c^J-%@E;LIlY`l{ZGop|#i7Zg z(B#)6#%=h~3mtr4;Bret-wq&qYc4f(+?5S|15yCIqMCbPpIZ;QF_ z9@rIXKQd5n13~>zw3w1heQp1;9(pC63W~stXPokT>V7#IQN@v1dAK3n>x?DiH3c)B zfO3qs&8NT{40IfV4olsAJV>YHV*hHiDC1c2-PV9Sh>u1ot@618t+E-Or6h7iBUdKx z2y78;hRPU+uIRw5b{5f;+*oO?7XgFZ4&t0%fN@(}k<@Fw(`r*cl|1x5tDy8Q0syQd zboFAm^yrHSz~=d)!cwzhrAJ@D(sNP`jyk1&x~g~S_~>)`v|}Yvu|xMuo=1_SXB{1x zj#T0`t9Io{oWV(T#!74GENpV_88S7D`T!{MIfU=5OPLX;^pkePB$er(``hm!?axa+ zxctU+ygwrCz!7(l9tc$bDPLCoB+LnfP{{b1vebUW_5v%rC)g!gmqRA4VLPq)@Ih2u z6~7se)ZgT=k{-;5EV_ly0>tpdzIO;mB?|zxFdkbqB|UIvxDA^JM4X&Hp;y7fae+Y| z4-_0xOCVyGq_s1!=x*Ba9SEYdt$473luu0Zbc6CHK=X8G+%BV*<;#YG6)E-7vUbyP z>LP!&v3>OWoM2Vhj|l395uZb4n4{%XgpspP>ZRq~StW4Xz3D7^Ka@fS{Rz{c``493 zm~3@Mjw%bZ#=@fz3@MB97tr|t9PA_xPOlOi_+Mua2_D2DheMHn9Q)E6!BvOlF!Q3b#z!RzOk;bUcBc%BOavhOO7r?JY@s1b{__KZEio!1O6+OJh7WlBbMB zu{{Houi?~d@~t4`8{G|OPu3UWemXHg-d{7=tJL}4il2fV8Re8eu{6W#DU+|4whx!K zm-(+jhbS#7!Eq+XnAGl|W*wW_u2=MI?f83S^j$@x=DB_&gO<28XR;ANEA{%p zL~K}D6Myk#U|}2xSCM}hPAVJNLaG#`TBC?vXFip%B3iKK0Sj9-i|v!Jx`cm6z7->8 zU~v=~akgj&%~KQT1&7w8FimO)I%-)nzknSpUBYpfR0!op_6}B7agLYHJmB0!F5dHt zHEe($VJo9k8CX5}ZHdw4rAe&zJv({pm@ggiMjpP7Z>OcR{JTRUs>{O0!j^RBin_g5B&PJ(JzYtI&JpIF-D?` zIi}M5P~YZ4at54p7u!n^2;mp60PL8;mnd>ZJ_HbDw~WljGD&<0Wkh zV$Iqkpu#60SUSO4)OefH%a;*WlsrV~643f0Nw4?r&cxHZdpsfb17cBQk|GJLTa-wg zmTWIz^CXW$1Qtl10C+BHTqJqUivSise)|l)i6Pdk!L<(XuMre){VkNAGDlcu5;I z9fW$}$31VhzIh?hzcfhF9>9BPl^Wbm9Hz}f7>7i6Q{o^jGHGauK&55SXnz|6n5c9Q z_~rq4Ma}M41zh)00Rat?36$8|`Lw|Z z;4Ore^cX$Gx0{lE+pvKWV1HjDCUE2=zd%B4E!vMK2N{5scCohDw;+Wo)wL$91nWig zKDurxwUlVNAT?B!Eot8q^a{Q(&m>rD(u+XaVAH5!sUYz`G0TfX%>E8N__ty(BwXqv z*_mR9vi(OfY-pkUUsr2b#iT35U?clNVo-OJfT2LMFbEk9IUmlyXlAFRWdeG&9EJ#( zXnwnG{(t1?a#5(RZLa3%<`73}!yqNmR4BV`(A5;#jvy5!hLb@E>f23Ma;7+Xi5ByB zzM_?CU`>qn`Tr>DzCo5G&tPzLMS(L~6$p)c3fnJ2)Q0ghm=DMuOpCaU+Ly&lB+D0S zj1%ZJW*3#Tmk}|f6VQ@@?DLW4PI3jdkvXWe+bq%^VeB$p>>IHTAIl#?9=uQ-8xRty z(x~f^mr=Bv43K42WTiHnKv(dj|8^Bu1rr2Ufw^)7&glbRHTp0Pb6nLo?!uDf6+)PT z3Yq<$4x8eoADE%J@_03{RKYRoHY+h7ChZv?eIn_Qc3AR!4kUedJa9r1+6|Dpn;3*5|1QiM)eey-kW!*0AR>DI zgWbh&B44Q?ub`SGS}!2^gi&xAwxLRk1!x4M7T7B0V1f=z5P@B+2Gh?xT|}^lk>|C+ zFXjV?6K0b<+u{8p0DotDM5<|227|L^-z?+~abAN?VAy=GMpmBh1mNmM$|xE>OL1gW z3iAR#*ylXq#yW#J{ud3;RifU`&8T$#kih>6ZcCrIi6}jaU`E;?<$li*`M%PaqQ+c# zPR7u~OC2R*DDpc>o}eMA^zcyeTzXxpP@)_5O4~0=+iUeh5Wimaj`hgD%9#xp{+)2d zkG(@-(sq$uFGup*)+65q6Ju{V;_r;vLusu@ddG@{BmXk;VIL+Jo8z!!G;s)^f9PT; zGn&yH+Of-oQ72Kk(HIGoXe^kvsnnK&N2|Zf70PvfJSZIVngi8fyo>^Ey8`2AD~zH` z1+uH?(hT{|DlwW+KTrb&aC}T{jxkG&Xcncp@qIh9U*NE!>6}bq_uomK!992;{}}|X zC@l}AnZ$x@$(__UXjltVchkdK7$jaWn}19CW*cn`=llg+N0K3a%|csyMCb3ILa{6E zsX-M(YV%h_3}c{*o`7+GwMZ9gFURUWG7YrRih-MCqX|=iDdY^q%pu*Zbu8o@Wy+an zfVC^CrlZ!uI`IKWE!s^jf=LI>T1bow)WBkS9@Z0G>`xPA_%GvS z0JsTDucBx#ud`2SO_Es_Vh!(Dj-e*T2V#Q-8Vq^p}MyR zV}GI*)5cK)740S`3HD}d774qhsuzx_hbS3w4L7vXj(rdB00mV zSTnAu-#@{-ehdaG!;q2D5wXUl{fHJ5(jEpoE0{_m;;o&ZCCDsokI67IRZH3n$Ye-} zhYMEF&jUpTR=Au|6tCx(z?3=u@ls%i3>|5z4NCwv3wwJa%^#wW%0F*GziMFmW-Lj) zN{d1X)Sdb3KxNC3wP?5K0tN-SEfJ33q+*pg7Dht3V#4vHpo3Ell4k+Zt{9RZ5ovsq zfRnewT$xaBo&`X%Mpj(XCVvcqSg5)KPu4IYH1o+mkJCBBfru?zYXr|s0osTgB<)rN z^!-~$u=g;K^InKad&(xc*uEsH58n%Dn}`bbW(%b#P@)oMmcTr2OTbUSmrTDR?Au0R zb_8!T(W}iab`c?cTN6wQyopMz!if!z6`)5e(#jdHNaNpwnyw8XI@&oP-(S|&HzvN; zD?of4-j$O)qwy;yS+o=>CRsNNNN|$X9kFJuKWOlH%CKWXm`by(JRBSxqFjr28v|M_ zQoXzF;@3f#KjVclm1bFlbqn4$tF-gu0)`pOVG+PAt6Bsw%lc3RFw0s|iZ$c65Np z!a|WOC2a}b1LKqMgNqO#8f+A99*hL{pc#0jT+)ufW2w}-17hU|$?NgOBMd`3I^Yum zH5y3}V_#smh8o7J5edF)b4ct0mrUgk&jKcBxaZHv^V)NKS{;gon~{zzVx~g{__mz_ zlzjpUVxlj3E}=H2Mi_;;QCJR2!z~d;d3mYT%AiRG@joTaRt3o^?fL7V=T1Z=1+Pky zsUIez&0uLI3KDl5&})32FW`--4ZS7p6oG3f2H&)^ zda=!tHtNM_Y3=Rgn_f(iw3Voe@K5QSg|uU@UY!(x_cQj>A9UXdvb zMpC)fpzkKt!Mqwd`B~_gUZt|dlBX|`B=_)5l$n_+dCt(AcLaD6IfcKd3z6leL`d2Q z;V0jo5-& zAYQfeO22$d0@fSnXQ55JngBu%w}4QURtpp|sCvCXqN{+`<%?w|cP>;TQi*ZhrB;Pi zX0%J-^yLx#iJioS4?#ookVtCxAdYd#3#1*AJ9lPY>X-5?IE9o_yChuN@i8_pe6ipu zFZJ-!8}#zTy~r!=IPTS=0Mz%Jo~2#^!8+mwqhk?VIW6rFxmvrPNKQK9Z!hKw|(idbHItD%|qSu@H!D(C;=&cZ6P@;oa_6I5lU@s#SI z;fzuV-fhCd31#K0i;(kWY8K1nz_xmDgqaRvQ(WvN4278EP;c?8N-?fj`6sI{ zV;U=YCZc~=3ZYo}7l0M*CiY=v`a*`}gcgt!y7WSY(a|rGI+8=$4cj=v?l3^eAsysS z77e!c3jlP@4l26Of!~l%N+7QQ`4<{KDJ2KC5uBB6BA-;CJV9XpxL}bq+Y&|I`J3UN zuDFW2>7TZcXAfS7R~JH>WEeeZM}^7;!$&2&_M(iScECra#*>F!(ca3O*6PUX;g+-( z{uIXOJrX#m-H{i4;7&-dHD@6QwS_U>A2>ldU4*LXqF<7a`cK3}E$9C#YAJb+15*An z^-nmfoBD|w8Te)o;g0}AeVHseJUT&56a^QRBuFl*1?A0*<8VZkb^rva)A?^_cOr+W zj92=KFCjnqikt8>CAp1yI(rr*pv4{mC#%WQhXcZk1%QSxc9Q@U0+6ir06^0If-t#n zUOd?sV?qw%t>BG+`2-SUa66dr4I8r|^$~gn8#SKDo2HgcsS?XJ~!dqRnIWKoJmIfD(79H23`DC`E*md!>GyQQOy+{{Hpd;4E= zv3bK$5;-Bq*3lm0*I%RieT*O*Br=l|?k{HvgnxrL5zc?3R7s?Y9mWUzb{sLmO?Sa< zA7ghU3X>DYMu)1KaWxvYb6F}K_Hrnl*@rEN-GL}bvjuAxu>9@VxDe#3EtxjJ4{q09#&R<28Ny_Re_BEq zw39WC3RQPHu>M3U)K?O}!JccX+AwknPFUQv9A~Z*q#gBmk*HoAycoHp9f5H$0pKzk zGUBlG}Y_+Bk+;u;;M61KayFa_+1?ZI5}gp39#|a5?goS6%!=F|2Qlzc`}?`*E4as~-XFy_AfKs_Q`ia= znuCqBO;|r-il8Vo^HXL=)#+@R8@_{s{T=DpQ3s9O3YOJ^_d4(lrCp3s?*F!V0ytUW z>4l7h;@HZ#(a@}qS`hk#5N@KB*IQEBgi_)t0ELs!ndWN>%@Ye8velwiZFCYK0A!q(xO16XE|sRXacRM^(*E z`S+^YO%(d4s`}Q2t5h`>JD@>TJp~IJQq_ZS@<~-YfZxC}JF_Gs&i{TMBgHbieu&+@ z5OUa#DCsTxa2QxDA}1RszccNrzsM3i-vYZu`DIov|M5YHWrE$CY3K9aLnD_vCQWAd z%nBape;6=~1b@The53a~*ZD{cw@WB^j1Jtn0uRNr>dTO<@g6$Y zk(5-H?2N*>x(av;~e^sTlA_TpKpf%jMF*up1&ZfkFwoWuMJwos& zTf>b^b173kB|ePAfcVZLpMiKyg&r|1YvSlSdGWBxqw!cEUdQ??lKivGJB6P|#JsNf z?+EgG{IFXXX;5A4XssHMYPQVRNeA^nV0rthchUikad^OU5N_)^{ zM@bu!FeFHx-uNX?K*CdP0PYJYt7wJQrC3L{&Tz--c*#RY%~Xb5&x=5Y+$}TH-$`v4 zzY-?}vR1)DOqABs^-*fWB&D;No%aP7#Rn}3R0jlMfe?CufTsf&0+fUk6I=x#GgI!E znW=n@1o&A*3Lx%mrh-y{ zZE^y)Y4FOPX(_9_V)YGIj2(WFq{NmLHwSQ0qt(KrfeU*`xsZPkLSo4 z@-PSw%^_)+ssupSQG9v?*zqp`)(?2P0c)q8{;>EUII#F<0vr;)KZ_EJPp?J>^h9uQs>*jCeKFA0HI8!8A?Y!Uydrtm1VE!&*xL*bw9ki^(aV}H+J^(h!Tv|5< z@=8mVHl*PR+2eYxT4Y3V2BzA8&&8fX9Rq!}*AKl>AfyDANDkOf163$+P(B9SWR=e_ zI0Co8f<*aP0RG4PAvy4PBY#K~Jo0~$AEFuoX8BjEg*YHyUTXxuK}-J1D~!m$1XFXs z)Y}H&LjgeB@#hVIUjXs}c+3F&CIE{8SZx4sK_4ns0KkI)q@^hBP3i8rObwC)plG5e z%6)H%CK?OK{RiJDcpd+K{P%`D)A4^3{wLx8Ui>e`KaQ61>_>3&!!euxD;(xzf?c=H z3e3Tk)qHLQ;?_W{ufUo;eV2tg$tIxisciwTQ%$f`rrX2#qa6Xwa=2~G`zS^++%KU3a!VQQAQ2IlevmDra=Km% zx#o$yM9$lTzZ!|k7cFt5HA`!g9M}d49}KRj(@I(&#QCsmU=;dWD#xPqbN~{|}#-w#F~mJ>~{>{JTsrt z_y8+nIN zUcMjF#_cs}^A|2$uz2Z$rNb?c-FV}TmVvDR0|_8b$&CPV4$5nA)Audl1bMjvznoSLIeTyVy>IiwZr~oE&LG z6>y4nuLRsGZFmn6_dK7|iyQxo*iYy`*mdb(>M(8_f*ObM_s~40PH%~`1l#jbrOwh4 zr?=8sdZXW7>Ga-cmXYno(V96_n$KC{^7+ycWDQU}RPQOHmMcjO9{{oEsqKoA)0NIf zt?~;#d!qoIsD=>61Hq>y3%)NaB;oA*G5>nKz~@^`Bwq%O|LuTq6x>#1`dx*DIwO-B za7vy>$WpIQ1*RIfLt0;s`l*3Qa;h4bjMX=Q-MI9WghD40zCa@gSv}POd|_2U2s?&l@sq%M7Vf=kfQuX znfO!$HulFT{qyIb)3M`WLOS#D$iEwaY@d%fWA{i9gA*m^Q{VJ|;eLb~XRrlrcqwyb zzoJWbtWNN0E}**DSF+GSq@T4y=LQm{gwx0B*$jE$M7hmGIb)*SXQGnr)9AKjSS)l4 zC@s+Tgfg6j;qi(4_gu^uN`EGlzDK0f1w$_OKq!3`r59!ssU04)!Q;@uY<3425*Bm9 zwDIFD>B3dPWI4rwciOWY`L54!hr+kW>A&BV|L&MA1*FAOk=;K7r$o~cGn|{L=n*+N z{tQxh>TLPlJ~w*U%g76r8cdIA^?KGhJ|E{>LTFJy^M65aOk0Wa=THus+mIbZ-Lfk78`{t3T<2nUQ9HO`!F|qZ7n9pxsR0iJ zHK3YpgH8$!sJpe524EEd8n9=Ck>BTh*Cm?Wm-P~>LtCN}_tV4qE^ds~ojZjJ;JX`m zp@A)>0gEnV#k-WarV8DXSnxTw1W9aSn+*~J1c@zPXRYqsYLck+I*+o!f&_vfaa4?q zL1XYN^p(ukF_$|HpBZ6aU>XHxPQqCuAl`joFCvUX_ju8y1IAOAJ#9E%3s0bwcfgB# zIE7xL!PXgzTH+|YRdng(czQXk9@56$?r0erUybC5;YANqZbdezkF;wBbwY%#C9tpHACSjVY_|m(#)GE?n3xt*4z)?B}lP zp*F%{D-xMugNA4gQ??X9^VmX^>fbEw2?6=*|D^rwP@H5jR#f~Hu2(9;di%6Gs!A+> z1-z<_BjgmdF}Vi+^(Ix1&UMWVuLY=8Heye2$KZ=wopar z9TR+n1mtiG=s1kklzf>wd6n8YRod_?0BYkD$@dzS!CjK42#|5OuN))&I7xdAF_YsH zs1^xxJUAA@FSQJ{(hIZHu#7E)Ccy+b zcS5_WU2Ieg6b+iS5lt)7$D8S|BE1A3CpFVo1k(qa=}#fO%*DdY^qgRN6s2G9b8bcY zb8tm&f=h$xV>P=yi1A|+F#4nC6Fa>C<*&j$hgt(WX^H4mIHpc~pCEl^V4l^X_u^$C z`XY?;4El?(CD4UuKnptIpLmtTkAn+*BXrgdyB4kDBm@PenB(mTrJoqfUU|?M0vLP$ zQYbN9>1wpTzk|tY8XEgB~n`#X^Gw+L-v>`QWRvLHXv#n13{kU%T>@V{aL+&VsX z3)Z@F@dDt6<#0c*hSKr`hY znR0u~wflo+{!3rKQNTM==qU=dqd}ft3~gjlg*2-n!ugLOi45b7M6H_bqPMY}P;|V( zevaN={hA8Pau|jozZlreCM4nDmytyEQ69Yi!9~j-Oqf4+snXx_*!%~T2NG!PT{L&$ zJxiBT5a9(6%JY}x-7|N7g5|1ylgxj;zd10;7|$bC2FG)L0#Lm@DPpWX&dxukXhlCu zSL{(^+B7{Mf;tZaZNi3GaLuOVIR(ft%QXmU6A0rd;$l9bS0CmV4&zHm^6l7>r%8o; zqcB39;X#lrcDl%5RI}Hx-U&f$Z6HDH6h`9%G$8ewoi4`L2y6%}6>Dj`#0t?b_n`p` z&q-PsN(2^po(hCbmm=eJ8#0zh{&PQ2}PYKDt z%Dyt1EDsNY6O}}S%~=MTTJpq$04}}f-$N|4v349ILZ~Vvnukeu1l1Cgs%B7)r3Vda zkkuKQ7NAM?vEMNmh}MAt-zNrcXdg`cJJfiD4G{`#(P~u!8^KVk(J)`eG+_I0#6_qR zLcEYzG3`V;_{m>s^3rJNghx;h>I8TZ)E9tyP$QFwVs!puQzvEe!pQvvJ11Ie@k}HH z^90VpmbRxxSwA<}3Y9WiVGUrI0FXSt0uEf1U9`GK3q9|U{66h-xcH(4i&waw7kWrT zaW^t}Is9d;S`pg17Bnnr$zNhlywc1z2iYc~mguW*(G=cUNBRLiPthz*RO~St5Xdxy z#0J+LVw(VFM7I;}Nf~<>Qy6}WC{pQ8x_>X5t1B@>&uSv+K`Kc{jN#yKdoO(1wMP3Gq_dg` zNCQIy=nwltI6Dq0}Me%3Rh5py{iVS*D zq>Qk8L6TC4+%r9S^Ik7eJb0+dngjLN7=;8bT>O;d_G%)8E!1H-9 zq4((C36`01KD?#eq2v=SR_`k?%=(VEzO5&R>!+Z~jtwi85DSv?L*a{=&ucm-M&% zNBp^q9{fWF^5qsTnv3Fs1^kgH;oLLNtt>@Jk60d?vkcF93zjZ!9iCr+7}h!QQwV>s zuz!N3xSv?l{f0V|cvt9AsAC)9=#ZBLms(6W>S+78w~#Kp`Z|ooVrG-$k1$pVijpnz zVgGOBm-fAvjI+Z#*gM0{&mv;1)}1n@7Z$wE?#;#g=jWFB4_J#9?!%;6n3M4ZAjvdZ3 z2+|PV4o_TwiD?kZ;g?Z|cE>4X0ldZYRn4u3TLC4tmb7ar|8cA}5M=%dOY!_V%*RPy z7>)4Bo{GE4!{81K8J-$to3VQQB{sqN&nP3gdkQ=|NqdtfAQ$n2`2*H}X8L@zD#(ud zg>ruN6Dj90tbsaDV9rpI+m06l7h8o*)ScP2@+>+8d{#sp*>V?i(a@(EYlBZIFo66a zWWoI0<<6yIzguhGj7)cRA1!3k(dq5Z_Fufx}?31DT*<#;?E&yE=sevXA36*j+T3l zFY8tI?T@0$>IZPq}ZPk&6Kpgrsp7kwHD{6$c4r{~ke(w9}sV$r5Z!`z4# zZhToK>>A>vnr#-O>PdR%AU!=g9y!#MHgMyJ51Ldbf-Y~1Sj+V80mMSnJ2KgPCLkyP zev~o2!^{KIyJ{BofDqVdB%`#OsI*Y^`E`H>lz5+$*570Cf7Hb?Ny1r2v6PK_Dm-Ip z+G+HoV|)}Ga^dVBW;E9^wuCWMU608fdF@BN(=e4i#`a;jaJOMq5T3fv4zeF0jccqc|wD(ei3Kv{;;n2OX_>2ZZP54cz(9bw5j0CD0?)js$jHJZ27is5ji zv}v!j=hz+UcZurWPKn3$X=iwt@STO#s^v!!!8mKk1k1Y*(!hZ(hEHDM^Iy(mhHW~^ z29i$F8p1i@{WkD^f{GC4QE#DWky}Jw1Zkb2m8q%cCQal8%?ADp3>WT}vEahG?FB+N z#Cy))g9wt!ZeclYp|a{#)coCp^kg7!aj~QD|7jj|j@cL3Eh4eh;we)kB6E&y0K5DK z)W>Kd_#d8bi19wKT~tL$>w=I`7n8F&OJRz@8I~bJoRL(*kWUmjf)GTJf60fD{81P! zQy9r-$@$#EQYdpZ+s8<>EyCcHKo(-77Tv=Bep;Yy4x*t|tBp>C9<&Aq551XG{wRAG zDE#siSo#POZ8>rD91-KS0AjH?0jp!r0FY7`uiTGMfuszV@4Ap-r(=)`?%j$@NtTBi zB@6jBf^{(1=TA#^P|0GhagW_(a@gMP4-Ot% zwrC;Th=o{?F&5MCeHG?n_uplhQJBBygp}%72P(aqJ@W$|wD^CHyD*$Q-xu9OSa7b) zq_bHy6@gm`Mk`fMk{k#Ne!%E#xH33?MDS{&fs>W^;$ytrDW!+pCRq74kY599hjfBs z;jMu+L+rFxOB1+jmXPbs_dp+wwXkpQqp!RRqSsN6fhdFdDv@tGzFnHqQ|=6)*w|=b z$6>^$6WLd&HF4(CFqKVkIcD<(pqsx=n0sIfCM3^av3Nnv+`yheUalfKv_kTH1|!(g zh0=Fj;B>vMBa zLH>A%AfE`7P~|QoF$H(;J_h4xRIVJX^J02`Fu18!3^jrN@QI=Um&)^o4t-ErxDb14 zvt`=0Ha7X1zDK_9XnM1au-Ab7?6G-Z(*kHpc$@~0WbHq?kd}6Q4qtlktrZuWnh8%L zfsUeYz%z)vXyCs=z8eXIJQYtI#Kt{5(^_&pi}0Tou?`88%Y!G2ueDn69ro@At>$;w zM?Z>PN@$fkYF0}47JPtPj-A53uCR*Nd84>rLZ){+!m7P#5$QGoRN;3q3HcEaX)BWCeWVrb}gur&s0Nh=(T%j3fPLOj+FT6Vbo3*xlcA55-hrwr0&F}&2mJjJx&rV3*$Im{YJ3L zN_FDZL;>nhQ-;)&eC+7vz=vb-aS(U9JAoa(9z5aY19_SnF5^DZ1YZfQ$ao`D%a`7) zmW8XCmjdb>o26(@&mwhBk|nPyJz!~z--NbpE7NbX=#pBNZae66T}nN?a6tS`LX>@q7-k9VmJZZV;)7sF z+JPj3b_+q-!|!2p{a>tY2qHcrvl@u><&1yeiI0xr`;)Q!>@LuK1a!Uec+GfjL9DUI^u~8o9j4Rpn$D!7RMPdlar0 z;VuXlXVn92FU~qgN21iMGj`rK1a|Nilvo}OI6L{Ss2)Bnnu=noEb++A1|x`5)xA*8 zd1owq*-hZ8cs>qQ23FHet@S?Vfq=qbPtOFDbFgB8FL)YI^xJUJbwjvr7oUn#PxmZ8 z9pS@ggo+ZHP08a5;6jv`6Hw{`9mmsmYj9b89R=AnIx_1D_F;eKSg!sAH&`;&BlPAL-iBiQ0$SX z79P7+>8w|6oJ=Xo%fjZ;g^ufx6>kYx0NvY7%!cSa-y1=TKZGQFXEe+r_a0_R$D=D^ zb}Wh@M&F$o2_)R?Y30dAAdKIH0PUA70nc#T@jb+~_aTTK-(@%!YhRW~TgKW{fbem{ z<|LX6zKIH8WJw2%KKy}8+}vUO1px7}@9ALb=JmvCY`eYk0bK11Kmq{b!*ayu#UtRe z=D5knB^W`o*m?x1*e6l!a<572dtZ=NkwNRI0qC=rB(Vl$_)g?QA&1^XL$SWFz(Qy7 zc~2fi6@i~~6l|V-|3i!0HWMG>s&e_p3=?0rop?^9;|+Vsb2~`c8dASm{k6J3z~>QL z5qRT7d;v(05}*IUmvnH$vAxKVz@MWsgGv$9F}ICW4E|3)(maHt0v*$?p-VWGAwi>m z`xZxO;f z8%2f9mXdb5y68DB-H#Gy;+MsCU$2Bwg$Ut38l z4Q9JeWP2o(?V(oLkOg~(l;yg%ds%vzMZ%Rq4Gf|HC8kUbWqJ%%84H=f~WPI`kV| zGWF(g^zoH#N;~LM$<&yBqwyJJB^bMIbmB4pH5ZO;bX#HbP?aCNqAJ*2NzAQ3Ocp!} zZ&%g3E&2R17Qe)u)R;#>TD^lE?2|WXkjy$0;E|||i;WMb?nGg`4Xb^~PI7o^oy{Vx&qHq)M?v}k?^59qiY zV?Q53Ef^EV*8`NNTgiIMuGWfEc`S? z#nvH}EQG&pFaw!@LP&+6pM{_->22Xg+->5&FH)%Q<9h*bwxFdM>B7et04n5TWa9}3 z@yO38uN!fb%vOf7v*T|WX6GFw!zVK~nzccMe0Gb$#)KB^Ex_iuEFOamS&M8|frEmu z5Jf_9DsChH~H729WfHNi`{%aXu~KdmK#pTe(ZO1%@Q+zXUpF!Zbr2%5iJ! zPZ$G#k)x7*BM8a!3F7z=E7JANLjduL%t>WlZ6IPPxMg^4AMCJrwRA*FHOhpS4Yd2< z)|9r>xAjFlsfmeN-e6G2$r zO+>8Hx;3B@(1?COQ0L@7rCDWrTA0#H+L45BaWzBI<+#mE70iTrw^9APJ}TKn#03Ea zV|PD^Wdht7LJ>*(p&sQ3qPS>4@F`!9j_dM@bavAf$nOE!;K1MpQ;HN(o}_+*c`%1B z5zu2wI~X`6Q>7t#jCYKb%*&CA_y18M-e4m!7)phk_NBFSa8P}j)X1XmPZSML4V?+V zEL?)UbhNaigYBg4pm#Ghm3pzQa;87M(85q8t34FDW%DjcE9nd9ZN$0b( z^QXb{_WA1Z8p&H@0Vr?7NAXIl$qtfN`+)A1M zOaO9}Z5vfS_2jA;e~mG$7zzPW8_v;+py(KeFbs_sBKZTc3Bi#!N+ zIYp?T632=#B$+N(%&TOZ{i96vj72oZKP1@O$e5+e*BBx$O1@TntxgA7HcXJ{24!OV zUqLZgql496OiAw>advH}6iWJun1MmJhoJ140JZ&JcMq3aANx0Jh zWuFd#*cdANGcn^I;ulrG|ProN0Qoboq5W2)Hj+2ue6J_FT+ItN%=Gzov^ zIT+lpaFaH&zfIXIsPM_JfsNb~eC(TW-;Hm3^S9C9df_qp0`YKw$MOdN5X%ksc0oRz zEU6>E%z>=FsNM7pQm@rqe$d+&@1+HZ)V)hPW0BFKIs%pH;ceA94ht3stxr6}UiOeEEQ{23J^l#mD+$19%?^jlTkK%Hw4muSPGbP-Q*>P6jSzf1)#*`4~$4 zO7gq~SYR7rc(=*;g+tql#BCs<*MkVHG^|I&AC004d;9{OlIarsg_EjEA7H{of5 z2BNM6>We47B1UuV#hb9O7cXh~c)Hl{jl{;?2&=2;;``V;p*Oqn_N%^lA-@R`teBnL zflnr46Q-m1e9xrClD6%?fVJ-q*vZ!sf@gun`;G(1PAg4G_)J#E1CZ|j;qGnVqO8*X z@q1u|QAZgKjasTPsVHBT1PdB15E#Zp90kEw5CsK9AefOc0dYr?+q)^+a%-Qpve$LD z7Th+|-P!`_0WsIidWuq8YOT)fP~mEdNzVU!o%_DwmN56T|IhF9dp6Yb)D;+ zbDeXpbDg(nXh`9$IYmkK0A^Sn`?Zk;Ho+lHHz9z^`sZ+Y ziz)mw6}(RpS}&Bl0chEX2=m>b#+hx~0*qIU_UGte45PoOotmV)AP<4Y5;gaV$V06V^9R#^EwSV8{G z!e_x_BXM3#TyA84xUSD{Y2`PX(Q`GP8A01_z^!n-@geTbps)7AR7aH^FBoE8>9Zh) z&WVHX@f8KN7jhh{>{zHm7zPaA^#}`a&Ug2kDpGNjdsyv-$<9PM+~j7pc6MPA)iLzw z&KQJYKf%%;aOOK?%RR9D$wp75P9}=|3>4KhoeFk9uNnY`j}rPUl#av`YMDkZ; zFg_Q#pf^xF$=^6W z*k;#lIqLWuI*)C`?=qC@?>e~tMRXms@oS&&b9A{66(Kzi^rQ;(m<;5>MrsaZxa(lZ z1M7%2IUt5MeEUAJvtg7O>ciZ?p_GRcpLXUut%T4;=Ss+7e5%(jRe@T{;8fg(9o>v& zrC;No20`b&9&Xlvv9f6VV(FAW?gc7|k}#g;bg zfIct@w=!Pbe4efrs7`vzzX|i~<^XKO&!?JPY-z9fc{)2h1_O*shouH~dK7hTM(oGH zba%@{AWTQ(vsZCn?>%EtjU5;Pl!R|V!rqJUjB{eE;CJ}IBcHyTNX|Nrn*|qpJK-g( zLA@XGXjpPR%%kli`^#q}4J6xhcYxRl$jN<4L>g^A;_oObpmg6Ms8tA9@yVWjI7RgAy86rD@_(N!i3>4hMxiJ)(rtJBM9qJV&gMrxyTMM#_GPMVr^83)6(NG zDsgft4!e<~AwkNwR|&9j;N=|HPJiC7QDbon(Rzk8Ko+ebjp`BB*VOG*3ipu-6D*seMw*d%bbVVe56LhV_H}91)^X7qQ;k@HOf5 zdl%!Jk?WH)abcL>8NrT+aQxmh3Oq%D=Jk=897{NROAf?~0?84U{dj+laCOk5);G`> zyp33M9TB(Cw0>ChSvyhWs-^uKkxr4J`%fsmL z7xp>7V8kuiCUY){PV znCDLFhJ4z*mExP%gdbL@zp) zAb`TQC}CNwbu@3_l#edLhS^$&N1p=jMX?69(s_$>?@c@~Kg&Okaq-(3;+}iP&({8n zN{$weve*+oWDYsT1+&1t4K9p^i;2(Acps%>?P>ZHaWu$}3v!;`jKSM~Pl!7WR*^o- z&*xsO)Q-}ph4hdu(-H6-6@zyYzAP831J3>3lM;ZH?guT{)ihHEkHRNCB`bqR$>3CQ zS0g}L*yl0s6UT`6>8WIHm(hKSPDJip|N99@fmGQ~-H+zc9Pj-Bb{0Fd7&9<-@Sn)d zVjm;_=rR)K_K^=>1V3v{XD{O$g9m$_$HEG(iAUL!g>823!+zh1XY6>fYB0$ZM^Zsd2zgXS3u~(^;I7-Z1jP?zxrQ$1J%L;$p5w7^m)!pS@H$|Z^5psF%e;po5%-qgX?Kg zqt9M|_kGR&N(gj2Fl{GpSW<$XHYAh%^$ggEcIeNB2j3Mqt`jm}N9(*qyRdm4^imK| zjO##g(fERfYjI6R-ABAGy@!jzcY#V3m z#|GifMpts$LZSN(+3r;AL)=af-iDo)I!oBc-HF1hu$S0u!ftNQ7Iwi-w51D=DgL#J zyI2Wd#N8Q!4L0G4flcW}ayvl?<94cGXe%B=km8e5-Jh+sVQaZl?%uaN8!l%p?XJqP8Qq_|@hcLeN=jCq`1q9+t?vh}cuPNJXew9@j*{56HSB~#Kil$4fNtQDl7 zZTjFDGaUw6{k&5rkBl@X(a0DFH`|WEMHvrIKPr!hX+iMUcj*N_dU?;|K7qL9M#oKY z*HItsxQ_Xc%EMqJB6>eZurdtZ2shm%P-nmg#~Q@(Y){Oa7y=`|04AWO=ji+B_=W*0=?!>qoxXcgJTd!lK%++< zXex5~AVaxiBktuL6ZZF{`0lk_&lESUAW>vlWn#EejCPKd>z31Isl$ zJ5(I&pb^DRUv`fXq+#Y_XY+N+sC&U-&&*^us{vW;-APKv<6J=dmT@L8FuA)vEM7a- z?$(aAe)Qz(SUVZdG*I5a4|dJ+`k*p#SJm|h-mh=Ky)W3=5#s5ApYNaZ-0ya!c+bL@PA+*; z>w2Uyp8IuTb(iJ)kY7xg2!Fgz@jb#5yM)Iy=Q^$@#(iUqW?=Cr$%JXJ^&>QcqDp%a;Mz)xBiWVat&!gLJ#- z*xutC=FZ#RgDY9|_ipe?)AO)%GYzjM%JhI3Po_?$2N&@u6cydDc+$b>qj(X_v#hQM z>DFC^9cv)UebE2@=jV>rWz-Q`Dln&kN~^lScS>seHQ*+`7r38t_$B3V!>}~>;Vvs> zF#71E!-S6t@OICP@s^9_ddv3}!R^VNH0c-Pq`95G8*n@B^-39+>!SUZf0Yk&U({6u zLboK|F1>5p@F^V%I^ci5YeJxue1s=Gswi-=2c%3o5Z!$GC23RvGKdXKa{fH?b^Yc2 zf1$XG0-}#C^8V5_z!&ni(ORiRrcc8T{};%Ut}8=f1zxudza-;%E7b;ZAHJZO7O(M+ zBI1ulH^+e!oTI43tIlBRGWMSSJn^;^0Jq$h&dvmAa_11NVw4-!H;CZ-8oNU^?DCb& zF1)o-L!0!j%znf!ae?2Xxk+(x)m`N`#x3mf{S0g}>Br3xyyDjpM;#}Qvf&COT%R}h z_=fkyxyQX5kZ7WJ2Y&z8w@^0k|M3>ujST+pYN3fU2KeHCSqnXb!V0{u3%}Gt|I4B_ zvzzgS7AoQF;9|Wv#=95p*98nZbR@Bwd4sN%kFT)Y?E#n><4};1CbD!W$eW7nYU2i0 z{eVk!ZP3z;RX%3o!;_AAwB>y?tM91`K5Lae5$$>?s<)IO6ba7~7n(%7!J7*wuGAPs zyV}@8Pm;PH*Vt$LLsilI3EMg`J*35OR*GOe6E*_h{4RUPgqgGz0PnlwYL-7DaO6kc z-^1E`kn-YvTK=So)noFffa%U3@F{h&yS||}Fq)zH{CHjOZ$7T>m6rELA3fWua|9Nd zmYi+XI|AJY4QE>oWb4nin#c|~+iE6TceXXa5rkxre8}E+q?U^vuuj8IsN zM+EGZ^^KP4!G*X7Y1wY`XXNWJZ9Y#_Iw=(1JQN;ys08baGIA`KE;LH}z2k`b^MV=v zH^YvHeHE5a>sFKhVZ!EJDt}V8?eZsOJ6Zk&es3l|+52DPMlx&xWv-kcVR1;~@-w)u zF8b(}jt!LQb1g&=&o@4?(~oBzpOhiWJwAyxDu6dBCv}I_LO=<$IwEFr5>Wy~p%L=o zSfvC;C?yau^23Smy1ns^>o$9vp_|4Fw%&MNP9Tw&6CRPzz>xrI9H3*JPzKu!Q;J`wP{HY& z3kqg~7PGJl{(0PQHK%wTk6VD8RNyNYzXY*PSSb_>8{m@%9OVct5!S#}f*6$R^&G(P&m_^klOVjibdSPehISIjZXIm_iKtK~F> zmlKs`A>!nNX0s3}{2ac;z;-KKtAVcsZYm9;iF}9ys62CFeq2%|oJQgtf|7Yf{vCi! z;xx?#1}cfEympC?)cT&*U*9FbK=quDcvMsvLgDX{vY9s!TE^l&xcBr zT5dz-Aa784PZMJM;iD z{D}=kq(?1@+US3h-t_+T%D|Iy-LD6(a^Q5L{EAU(KW;f{TO24cwY*~b@%{Vd zl>^F4z+o<=>p+{O5>j2nqiQV2jsqm`YGa>q566)o&o+L`hJXO9ZH#cIm&qfFaKQLcgcOg z+AHG!Px$51l=66a=PIQj*W>LNtEjYToTAdFUcrI>l={&E_|V9+61h>!R_>XpWYjv6 z@kD9r=ilcC!YcD1@db_7G;+(BRlEc3{NKl$i(IThd8-&J`l(gL!*b>yUQ@dT?1u7{4kgE8jUx^gR41?O!yHVxs@dflkm@s zo|rg=I6{_GQt`DCloRzExQsFb=@OgnXz1iO|~Q;FZZdHkvPo%-`-!acX) ze)nZU1O7MI6EbYX@~hV6P0e@Z3yJgQrrVPf(aSI6F!XDOi~o7+O=8O$x`Gb&bT#bvOkk*Ql(vm3-gilc~mzq+RTb{cP zl$8^mL{I-cQktL@xd7a-uGCp!EX!3k=K1OO%P)5Vq#uTug9BaS2NnQg6{ZAb$YW{JT34EfJJ1H= ztjl*H7Dgw9K9ozIvpkow(2ob{fGJUK8a(;9n=H3@eQsW9c|UCaD(59`R5&Ud*v;kn z@*Qgf>8>gTi%=Fd^sXu`E?u{>kdo<78)aUcuSs`hX>s9tL{aI@Enkyg;*cx6tQ2>& zt#Rg8M-zz>p#5)Oh3??+{-ZWKa)n9`PbedReFD3bo{@pea*>L^G4 zspmpS`Y_H;Pj+eu)k3TvgdQ;WM0rBnw z9qXcUPO5Ote*g6S1rwhAB&5TC&!zzN`)&nJsKqwlhMW@IZkW58j}|$_rE6A#h@1^2 zLe7TUVWNo7T_3l$AP!hMZNoE2*&;=PBW`v!UX?a)csJj@*)I_<%)h zkNcxJ`!}H6xx4z_KbEJK-977bf@eM^sq-SXYi4M`8x|K*LmzrJ& zTh{m^-AZKf9@ncWjjpoGgxe8bh46;Ugx4ax8{xYz6TWNR9#_NcMpq}o-)?&45~I`~ zx2h0t8RGR`2G4=}_PFBHkcYUT^RWZr28736CcFUQN9H!V7F{Mh2H{U2+;y4ozOp^8 z6$pRgGT{dh9*OXMmkDn`cuy+I;WFVX5WWxLy_X4(MR+a3!|ob7|3-w{5FUG(@Z+U> zTqcAsx=i@<2=APO{9h)#0O30k{={X%%?K|*_`b`8pDEenib8njWy1F%y!T$@|1#nA z2yaGsm}Thv+Yw%m@Yu_Qha%jL@I{vi?*{*cA-pVoRY889vzVmA2N8Gu1C6fxVQ$^p z=sF=bUZR(bE#KpEf#=E+OL6zRi?{1ezyv(p=o$_)|CJ`!7}ysdx|H{Cg5NbTTK?|@ zu8euWl~Dj`DGzd`YXkKQkuw@yjkS%g=Xb(}*#ooo$wt?KM;l$IA8&LuJ>BTK@Jl?u zQE@500-Wth4SU%I6b<#jQTZ%rKzvhPqwBiujjq1{#tR((jc@m_8eKOb>@0AnKLff~ zHo6wWMt=6@=Fi1lmDxy3{?M!wv&`50+P_g9X&18D$d`8JQwB1op~ z0xfsGjr|@lZ^N{}C@8tLqhgOM)ZXX{o!RJ$`mWJc_b*T)(Y60VqpJg^F1X3{EKHoC$(0F{F&xI&k~Toj zEL?@Uhs0b_Va?CaTba9Rt)Q?ZMq~szN+He(4GPQI%L_{(S8os$H>Mz~)~0i5prL`L zT*XR2VlMbv3CJMf&M|L&etCs+r9AV(;BU>P%XNw8<`$L!YL&B`WGHYUXuZVU-$dqM z+5>oX*h1m(y4ATW8puxq% z)WS5w2)H;R9;Ozi8Aia7@_3k9m}VFOZw|!6)WS5w(27qj4Bf9)OLuHxNu-vRMX!uBAyQ7H4W{fo3#p7$F2U3>AE5e5316xlR9eyV_NQcD=I6 z*IJm@VW?fjz#rKA|7NTQFQlVyPZ+wtt3&!f)!*$zf7gBW%Pt$>KUpoeTeVF-s<`_T z!^aayZ$<{jJ0|L@vzU+0zfz{-9-$~>?q zL5*WmKmG%oj%@D+O$z|q1?6n>IYD?f&LF&emqA$ann76HGeUR*rV}RW)Cl2mm~sCa zA>_fl3UdY~=``ZN^unZ`86oV1IRj(+4*oC7i!yJd1+B-sc6s89z z{yemXFkLXyzDFFGPMEL@BZOj@FJWT)MhL%xVK6g(7$N)y=3AJeiz9>sFya0Yf&=Dl z7&8V72h6K5dfiAN1Ljqjpn#FWGMJZP`e0@Rjuak*IRq1-ABiz*q;Ldg@-TeEd;oJt z&`6;krVA!2c%)DTa|9;IFj8oM>4J$FjyN#t9}SZR%rQf09@_VN7s)8JCxC`m`osAL zKiTmxv`>J()xS=}O9GtgCR`bCuYfUjyu@))oS|?HhI;d=t^U4!sZyrJ-EVF_O-=31Q^d<4S=;i5Q0M34x|TBVaYy( zcwHJlg6SEAi{cDL`(U_8%w1z(R2pbLI}{wvaa9^9y%lg5Yv5>}JQN(wowaaJ!2P@i zj^^J(!O@&t3wH$W;~F@c*AE3pbA2tG0lI@w7&U*SFBl4rbO>6wc)+A;;7AWK6ddU$ zv~VuCw`kxyWxIA14nw3q2NfDqJ?8{pV7dPK4vI5($Q$)%+TpfhEdCf z^gKhsk?uzew+QY$4IJr@hJquVk`}H3?j0I9(n}2mN4hF4+yS^h(7=(tYbZF%ltaOh?otaE2E9`Rj9MB9^NQ(?7z=OKbs{s{KC2A>K;GWz9U2(%cuL!l?5Z~7xSI0Eii z7zfPDFe;4{m-=Y>)8f>^Q+VDGu%wS0st+d}of!V&xo%yS=vUXQ-%k8njm_Z0<`3PW{6I<%o^AiY`{!Z;v)v}IC2u*x67x-|Gy ze@d$X{zqVTP<*6yQH zPjQCArG+E-Wr&xm!9_63GCn`$!TdvE$1g+UGQz9;5#C}=S}M$7d|DU+ zeGoJ~ufap@=~cMjhUtO{gHDHNr+Abn`qP##!RB2iUwsIZA!I%`0+$x&48W=3TAVSI zrt(MmN+P|ILWk;4_94Kp(8ML$%iyks(egOO8;W)Nuy zAK;A8QEB;&^khT9lJ1Ptp!}2}o&&I|AHk%;{UFRD@<*Le95q~9ep)yxzbzUV(why% zgQQDSagluh@n%5hp!KVT9^y>qrGB=`J+6})SgM0FaO(kUhKYopifE;HL*<)bDXk%C z(xlJxKL{t$MsTDyEkM{7n4K`OpfQ~2ggFT}Pam|Cx|RO4Wkvcs(t)V@7;PBoTqr)J zL9mD5z8wB7$REWW+}`@2J5uY3($M0kdfEp#!aq1H33`r`3QoeSh0D;?0m0_MO?jq# zsxX7`X<-OoAM(6IgNN$vWw_sf>4Z`1jp7YeZv;#HK zgsEwf&Q%T5;v+q*>Q8iLz?}zkNm~HyP;`>cSA`|}ZNz&_<3}*h!@V2kB>AHZDb7&& z(!x>raSaUVWC=h0X=x`tt?VoRE`!cB6uM8aoeVF?G-x3+Ex z#xV#N>4S&L59x>r2Zd1^dKvBmFx0;kqkbD8+%f1%LvWq|L= zO}L2{4RD9U#KJ^iTyW6XfU+iCE|mfOY0HiD!-Pi;xin10O<{yTPr*z0)c8~mRq(He zDI<9cVWbNlsvJl^OmGxN`Fj=aLoiW*BiQ2cFT3n8goE_8lpp%j(n~sG*;oFh{(#!P z>PNVZXw#vjzXTo%SHrY;v@jG-{R8y{YFx@!2HY!P)Nw%VLnw|Gmllr7_(8zzfYFXe zq>mkn&qzm0_~?(q55WBaOxUkvog3+5hbl|b&r1GdfwJ=_oj=pKt<^W~bc27ia}-X?(@U%F=0MSE*saUSUfL?*J*^r8b72iE zi#?fz8=Kt+0O&RgxWGlc22Uim(-NDI<6VU){#>JfI#K4%H3-d}=sa9h6l9A<8MI|nAm>NY7g926-OzH~r%RP` z$^=;BDtb7^pmPLgvcwl~9A1HzlTR?XyK#?C@Z#Bv|3c|5 z_$&}F)j0xo>u?JK9-SS9N3P!aP7uy^UfX=J86o581-q=9F-Yzki6fi1_?*qZ?V`V< zwJ3bwj6hr?aJT>`(hj{yFH}2*c^38gaNZfYmf{VP-5{Oz%+a6w^k-)$p2B9h_c7@`}KhNAwHWT}f3qIg!cG}sATXEe$ zvcc}R>)msaN#D(QcSW-0)pgW_NbvD;TIesx#6NldY}0-+-`!o$%b3WI*YC)g36{s%7!7lpL#j;nHHP zG=Ry)x;&z!B1Wu;t=%+6@L0pdCyU8TzK6Gt-avJX@yyAXFZH%1CJQVJjn0?oap|RZ z*-fcP-#S_5RUEm)$@!j;mSE|xgw&Im!Lxlc03@Ca;C1fiMeYuYWuRKYD+Qi9y2IDb zp2j;z^0$~+)|T8CAXzh{_$U=&VbV z-A>3+f$U@Au(Ti5uy3>n7k_T-N33vkdtx5E1hk3v!~*(aH(^JBvZHYTIfyz?n_ddG;5GqEyxysgZuSM>_TS)k>Y4?2tAZmCy|7K6DMjJp2ZL0m zrwgn`WLsJQHJhM105x13(JGCpJL(J;aha!s);X$h(KuC*#ai%<3Jk))BwB5vHC42(sJAW? ztr?;-i>|Fd7gM>2d9C}I~c5rJQAEq;<9?5EUy9_$qy6Q>Ovu`o8ksjEBy7k8| z%Yjd}_iOTcjeA*_Ww#ay`=ZXh>SDi5#{pqv5+~KI;oFi;(Z}ko@kPNo(H%wlB~tsj z&)b6zt-`LbY@?WM60<|aY_pgh(Qb{@0lAnxSoO`nF?)rWohN1&ocnm>0WrIHzF1QxW;@uojB=1x*78}v{B*l$buoP_9>l}dlFR!f zYk0JO*sH*wf<7@eMM?`7YYdVOom%X5w}Xcq<7#I{!Pb`>v+yhu+YGq?plCNwhoW6?S&jj>*%x(PrD93)c57~;kh@23Fu#Ehk<|DIijvp|HbrBlrweI{w=)8}-`(hIwW__DY7!I5i;ymT9 zaR|7lw~bkc0Ygoa;2iI%Nu{&rHN#jTN`>7COrWMM`Aea;`b)w2O zGjdDTB&1_N!QuW9U$8sB3&V96UWr~%Tm6;bNVU`?Av8sg2aSDtx{t)&z8g;+OF2>Q z)-Z8-C&VB23Gm@HU`xBz1}4JzovIWF62Rkm^6R0%imP|=#!qv7@|PHoa66x$LFyE| zIrvfrC{GHG{dajXli11cF|?&5p#SYc?|K0)s%16?0Q_m@F7HBsQ9&*5Y)?c{BTKE+ zOM!(0Tj9^iAM+!US}9$M{iY0C*5bBWX&LA4qzCx;cc;C_9!w76jr_EK=sv9 zkmW$t7%3C7=fwBWEqF|IMS)J_E$v%ZW>hFidbngvsQ6G+QArH6o1Yv-=F}8W0HTKqC?ON0QMw zfl?|`7HQ+6u$W(&%9)ZzsPs(fW2wTNMK_f^j$rpHGdhM;Db0ql68+ecEcVDuJlVNA zNs!vv@9-&Y3_F|R&^t%q!q1fA1d@Kylh{RMj;*F}KA=iT5ym#_G96nFFZ6((w3w|r zcUxqpr_#kzF=6vf=GR+XmBnr!z&{(G=pB%le|@}^7?z1TV-cwRbaoRs46{wT?^Pzg z+ei&LJ=0TGCIv-zWP#Pkf-9u&-S-I2bqRE7#(}ES(H+vqkQ^3Kx9+?VSGq`dCx~t#{ugI8zeb`}LN05u5HukrFW{D|nCX(mAe`HlokUzzrgp&#_m~GK+MO z;=+5u2g`f$)Zs3W)X@rrl5v}FyQHtjr|)%|f6HVYlL;esmA;R=!8u2v>kQ~R54xsF z^9(G?i+Z{TL%_eJyA!2%EPq#MdxB^)56~v{BFN`-j{QsjT4cj(5+Dp`j%+ z%dw#7ZgA`9B0Q21@j4&hi{kOp9T;#ME-XjgLhfi!iijb#MO#wDDE*te);794RS{tdnk;$m zCOGtRqzpmJba$KGc@cUcUCNHiLJ^M?#AOko?u`b2Rhbls$L`W1Yt~SsLrXKcV+Cgf zH92Wngvk@C!(>CW$4i;Sulb#WOH#;Oru z9&0=?kBP@T==Xs6iD9m;twQqhwZTOf7kkp>;qi|nBuJA;)V)zJILo3t5VT!R8J4uz>fusmjHut{x6Xj9fX-y29#S*P$Si;pBe-OPu8{e=F~lRxaf*{I zE!9)O;gL`b&{RY@)Q6C8g`48_ihLoLI>zU@2KNesAli(IeBQ4`Lmj)B;2brgXVwGtOJTNiM zfNnxGy5lYFRsY1rmy_Cw6+Qabsd1<5y#Q@dpR~~6ejD?dY@?Kh`GjF&yF5u1LpS4s z$P}?g&l-^s-sEIsehD_sS=zzHQ?Tm%EE=Y9ZDXc>>j-JI<-n#fXkrsFc!#5B0wXN( zeF`2n#Y2)vXUQ_T)N^Czg;_4*n-HHQjsrv|y3ZhwO$RB5!m7qfK{~6kf3_A@Zw-}N z*^PuHxo>Gs$Do3%!YxWv82ytVn$}eJ%G?)o9OF3hY7N&G;GgaQE}Cegw4`kPqyrP7 zEj=>ny}(aU8fZ$GCuZu=S#;D~D`kg!W&}*clxD{3((*oW#-p<=?^Ssv+@*#4M3G;j zwYCO&xnWY!t=6!4H2bMGC`C!)91;nas7m6+8QUoT7*!U604msh4X9qL9vzf%c1~c+ zKnY93F{6ua&Rp9(A>_4Ffo%!*I?w$1n(e1Ho%_tA$KCbkoQ7;^zcMVMI_UN?Y2IWh zEAsu`dnYb5T2f|I1y5`Ca@EPa7>xLpxSzagoRs>@bH+Tv}P!Z?QcdL`-` zF;<99qbIxpn4-_3K}S=$;lC5te1+6)g`7}y(cNNLgrG6fbUQ?R-{Bo^$hU)V0Q8uR4jEIS+@R;BN9-lfD%(oS)R&JX;Z|$ z`Q@0;H2o^EK>XrdE9P^*8qG#u0TmVsG33GR~hM?^z-FtK`c-0syT zh&K>dw?dDjbR(B)vPZddaj%&UifxSB0`)8YG9x?q5SmddI|xY#o!%u1lh-csQxqoD z()h$B=Noimws6vKK%&PuZ0KlZ_mXFPxST$b%szV%GDQy?4hb0CeK>o$e?_<|H?a&Q z1@^|T1fipq6xT-}92WGbit8uvFvcNobt+U0G#n|a+t=Z452_zf-2x3}Aw%eHGb@yN z4|MA6%ZGU$jr}T_FgeNPmn3-;CCN5_&2vYhfSD)FO5uZ-Xa=$zvAk8y=c)Ff?)H~l z>;pVRrm9#9Jv98v>jE6ZGdm&ExVs}V>2~ru5FFj{<_>rzNFORgRhWO=BJk656p_b9 zuQhpVkT24m&oF83rlG|*_89_#&el1`Gq;QV`b)oGiR<`61-gwMJngf4=JsG3nz0v@ z#o%qCg8Bn5VLhP7-k#jU$-N72f^d**rTuHH*BZe^a4$;lA%b~h4 zhHP(!4yQfH;G`I#ff(GaVcVei;VPYaYoyeMWgpU>yp8?AgLNd4)u@Y>=nl~URibDM z6>VX-y%0lOd%OwSY(-Ovi9nWg9`h0!f;|vQ)9%Cs9QOOLr91Jm)kWRUrs#oftQ18W60VFhNNtGp4HueaZamqG z=~7n^j?z3s%w%_W&q&u!m~6^~>6E+L;CK8SzXF&c$VQ7$-lKp3SJAu*k1Ffzq9Y=l ztwg5Wc&KX+0wEntCg~uGs?dG6E@aD-@b#oZ@VEgoJai5JM3iuf5=P|@+l&YTJO5AA zKvG0FP=~<|^;ivdfW;z0_{sH+u4%`ZF_z=EqkR!q=(lzH#z;YICNwJ~mJv~6kUKTP z?uSGZ!=yW)+c@SlLj*CC=Kt!VfW@AS2(#Spk;lPO=u511ib}xG`{h6cGotvb}*UtjgM$Q76oWT&-5%j2`!MMTfo_L zBwq;Ai=)Ld47?`+r5E+Dr{Gae@Z@2dLiu&cN(IPTK?sn0^TqaJH>#VB6e=X;1>7S zK+dPTz=Q=xBi0Wwxw118UJ#L%8!eykCt;r_&c2{?ro=4_bp*Mq@t))iNJ$5sw<2}~ zA&dvYNRE)b!4b~TB8>O_fnKk1V@UKa0xpbnpR6Ad7y5uBG~Uu$ewNVQL1-OO7+a?T zX(S;{1=7hJ>7z1In-*y**Pl&mCOA8Ks*u;3@xm9ef0dm*MydG4HzJ-uAxJwSYGFYd z567(IY9X%LSZVN*FhFB$_?w3;z!W*}D! zm`#O;)ICpR&oSU;Sj*v%Ef{z41`$oAvH)OnR>PAH8|En{X`K6GML z)#xkW^|D-=6ABe{W|0|X9GYI>Mc+Q3jf2)_u^o?}LcO&N0~wmnluQs7MYXpKwHL$3 zqFuQ37LE)WgXA$ODPocLaj43aQe}A<)TBhLf;)%NnRBvS8pTQzL}SMdB#WW9vdFKx;`u%dC+$HD z)QH*Pz6eDPjTqOcF~;&30&1+?8cw316daghMBg%2dIx<`kd%e{f%SnY`q|DNjQq)= zXiV{etzt?T6mOd#N9;EV4vg=&Y(f_S(*pA{42|y*@IQd@fX+73In`l`KS`+%BQ41q zYO#j-t)b;#_xD_+`a4xy6G<&7ON1)G5lR|>P_6-(g=>sM>O`W_YC;bLDFieo6k+xG zw`aj5GgpAmd{@iwD>FrZq1I`Oqp!wy@0TvmSed6>WT)HNkQ!+Zk+Uul<7N z1Tv3Hr=W{~f-ulM0iA*;(;Sbe0Z{4S#V_Yb5{QH5ONae-T6F#cS}-O;gq#D7b+vSWP>h2P#j~(iItTCZSU>kN`)7E} zUM)5cHr8NCSK5QUD75fuY!B*DJ1@2H@!WAABB2L}z6mpc93B@E`#@Z-JE4VTKDSbE z-idhaL8iF=?o6)ALD+E{}yEaqXmuYe(1 z8*31Tt9jUwD_}Uao613nH3-B1@UWgMU})0D8ie6d9%i!qG(W7<#u|iSJ`an!0)|Q2 zSc5Qx@G$!oFnF6dKgh8LVfY&lE4V_-`mHt=HgOuUy^n?MynqS%grL>X&OnhUwP7TS zfSD}!<>{I2!Bt4pgYAf&5FsH%2y8zFJ_rMNTaL7;9pbz&abCDM&n($P#hl2s$0m#O zqQtBS$rc&%TIw|rk4!CHhQI^aB2>8T(CaAU$^dE=aiNSDljsy+3KJ{Cv6#(87);|M zq{K)uB~q-6l7$+*m;!XlRx^^Hx{ZAAuyhJD`bZjspapDCHWY(=_EIBCFZm3~{d zHnVQ=Lso|RJ>Hn*FDr}os~f@`LAwH-0aCB!VvZw(REZNXqbQh+IjpZ8@#7X5oL*^> z5z8X4+)W#l`&SN>IY53a%>gt`1G)|>I68w&Hgd`LSs3yC@>a<15&L5Mu#0Esehk8i zQM6bvCyI1?w?oE^OAHU$p8QcgCq`hZwzhe)G}|P_7((_|8B9e+Px47x zbUFGYUjXzwkBH8bc=KvCo*-f6Kp|}ml}@u?{Fdkr_0*WN#OfpdaY;ysrWc@a`p zC|-zvjL-e0lt`BG6xVens)bZ(V2@4)y2?=Y?TZ{OyAHPRM&>3So~KgV&iZyC8*(FJ zPgg=5Rwj?KC-LvV(q z|4GNvpw1Q_AdjUIx3FfLFgdyd;vE0ZQya!zPda)7yhT$a~2pK24;EPt)Yv zKdu1NGI8sJ_{M7_ljP}{rL|_nP1J^=lX^x7H#Rwz)(Qu=}t+rOH1p z68t2l#6oF}ZA=LW#l*EOns4lrMO_rge?udrs_Ngwqp}04dfG9;p6x$PRysHJ`W9k9(|>2PU1PG539qO5H!s06MU^#50UemUe)4 zu19tBI96Q|y`GiI=sjtZ!F)NG^66~O5EXSEP=i!F45nLuj(XaBs>VECjp(5NaUR8k=5M(XJ&mp`Ht|g`nHZIWeE=*;OfDH5RTgsQU|(XU-;Nb|be9{$JQaH8-iczUHej>nwHVNIp!}F)Bjtw< zd`~K(#8j-G`p5CcFd$5DdFErT)c6sl$6pwN(miMKisi;sbm~OeI_exaWuFtv8sZXD zonLtpZOZQbkynXQQ4?A^H+iS<#2E&w*(6-qWNk+O4~U8db&eBWluyqUIK& zrbeaa@23Y*V+A#m73VyRtSyK7D=?ta!%UXfdH$OgDr2%pbYm6W<2*-`)_N^9EVh|erH!&qDo2^;j zhl5ZG#j@au(eYBrlQY%r&j$+qBBvsPvJu~bskmy+z_-ASCY_`WoRbdD!FGo<6Z@7F zN6AK7jmI_}#{`@6dQY}FUV3LM)&)s12`L6lQ-+Qvx_N7$Z#Z`n57BT>GIoo5g-P&k z$0i9*=6t@|PL*hdGPl=&Mu>t$JjoD4=9ipkY+9o zI~hUG>Ue<%0+LN9{MHCm#UUDW4Bn8BLAWeF1jypUkIn=f>!jXFHZ;fBOtG*Xp=I(`9d%M?ldpJDG&sUMblSpYnIfl_rJUOsJJ3~JEL{c!|F zcW12Sg7X$?q8szrhWoG@R!c=Eh>OC{CdylH-K~7bASJtf8s@UH>5X9ucHztnfC36O${kUtQ>CFvAIS^pij zM6kWs)u2c#5WuFNB5CC$`v>`ww1S>S5m?;aru59{W1zHtxt|?JN}3uT>Lkf9cBf2^ zT*0x6HaLuO-A$xYnb%)WMS-ZM9;zg9d5^ff*FQfTRW!+6-J^4iM{#Wi8oWQurqZP8 zFw2FrC;*cKDqthB=F_(&`*jFegpk|ioR_80Sc`oW=-eDPVok_h6RLAAWDWqx+)NoVBa;>I z@y);-9z7pF-8v83j0$$}x`Mn}@$CTu1!L>cugB};fr>WI z(Td4#>Lx6Qo#V4S`{*~G-83eJy_jr52oD`D# z{^jWSmiKw)>BYIdtOr5TUScsiQw%DdF0WUWrd^X)oC9V+?iRJP?P(flu?VUlhhIR|2o!aZz`_>Ead>8lE<;ZCwpOi-8cGXo{MexjDbm(d z-j3b*-8cz%M&M&wH+7a6$#4{r`Wlvln4aoxW_%tsc^k76V0Ji-Q|}f1)HnrrDya|x z&!%&(w-6+s{Iqk~2Km6us20B{daBPhY{8>?3#P#g^@&qCs88l41#L1l87Wi6%i# zj}9}@iLdC6*oP^7XOs*ZYun(sX+C(q7z!D{k0a)}co^r~UPU89FT&b4&;{x_t<#$6 z_yBKu?t20x?6rfS8tx2%&IYUBzELay%kaLDa0Y|S@91<^8{7GvTKK;PPAS-CbBwmx zp#I!s$ns|y7vo4U_B*^k4oS_!<~@USUmkm-5UzJv767p3`p#1C{&xUM%|($W&dYiq z99~YB4+@JZGZY=+JIo9)CFkz99^?g(>=ztMfpI*7YTw#UevVNRS6SioJBYYi+DkD( z?`)!^4Q0sgkg0g@Z-kEH0ftzjq@BG2(Z4&Sj{jA6>A`FV8ohF)01`z;J-g4a$LRntLci0z5ISw6irh-{?C5Bzq5`t|4B1_ytWR zpT?R5Y5JPK`oVul(cR3)J`p4$?8A62%iOY_=zq+lC(eh!olO02P5w zNuyp)BSh{Yqp-s0thbu5X#=O{EBVA-3ln)M6=VW`IS`S^OeqYRR zsA#IjWBzzvtnR_x4m5*F(bGhRYigDOz*Fg9x1qR5zcMM8^eba-P>=IPAFXdV1iD09 zI5zH$J(~dO`wp656?2t@@3z>52FEqr8|P=>%@1F-)e>Lpd_naM^dashmgOf(5+Dfl zz|ksguH_cBB+@O>-6L96K{u&bCT<^MHr)3G9tG#n9Tk8- z)N$D=i~RR;EH%JlOb41|LSwZrl``$nyRcsZ4_N(f#MB%t>iL(SI{ea((t{H2 zdFWB-q{iqRI!0iU55c&-dhgFaMgAVyhd9#am+4m|SzywBOG{;d)Dj4}ww?k5>uV{n zmU@z}6C^u+vLalYZi7;(N)oNscsnCETimgX8ybc*$K=^2Vo ztPiJ;!{S`yF>FC;2!%^*2;;wI{u{x6Bl+)S{u_ngw%Qo{>gqZ+1RWo?2zRibc)~z| zyG{5-MJUURvdZt{EL=?RJ@hld(al~TMo?)hrQ_d9xGkNI+r+Ir#iz-a-3_Ve<8Pun zPMAcS=>%2`_$G7k!e@bie3&S~0V9a=#=yNqP~hW4kmYp6D2vlrfz_)?ZGlH1nQtZf zG5sx1#%`U8cx*wdu#mXsoK8!1TX~K+0+Azd_Xc8E=Y)Avh{lJhh*$+WSuYL<2@>ALnJlF^G>7&bqT|ksKdoe*wCUxfFY#pgui+VtFsfsvIdkO}X}V zQZ2qCeZ-P^{>TsWome!-;Hz8+Rl*)?q22 zkY!>($B?y!dItYqj)La|SXY7e;}28iNPDS#r8a0siK1qePS69ioh>Zw&_%zc%{hMl z{1f33Yyl`h`imE{JK*n|a-!3BEBhMQ&|BZK?P02axwxW_Zs`cwz8^o2wbXO}!2K+g za@8rdDk3o#S8!`uyrK?+thkr6;9;qgg<#C0iBB855ns~doXm%blRPnFP_Y5hr6GR4dUAc@9Bx_Ow?1%=PnQ@+A2>i|X+^|N%O{T2V1fOP7114*1GrkME5L@! z6P)us<$lX)$2ejSN7AKX)6rRd#M+QGD$*LWUnwYd3o>zhROE}e&hxqzVDi6roqaoD zV_=$Zk0)D4d&W9i5d(icZz)2I8EuN>s2)~HJVUuFp^sjyoo>a)iREX|Ay(t-c>bA5 zm|vurPAu;}k=%XU38iT7vE<%Q{y)mz20W_j-1|<*gbXk+qYOG~)Tm<(CiS2}O`M>C zFi8*s2_Xp)A*g86)V49184#0z3#6={<&br-{79YHN97pcOwZH*bzhg5FLa~;3$3h@UE&buKPF4! zCG4egk$(B$ffA3rd^=}2I+&jja?#hW@{HO4A?->j}D; zT8UdPcUjQnrQMGSz8OufvE$3kW7ysEVb*M&MWt=4=04vFxh&l$h_%SU@sflQ5EU2- zFq^p+PS)&A2>B@axgINo?Vp&fpjL>8uZ$rGECNCFRcWPjuosp z-F6<3K%+7j=YS43>M3$U=iqh{Y)%#7^ZV5wpi>&B?r4N>U;Ri=kxxd0qr`p~^0VI_ z3{IwEA4D(RD)z?lsc|CUv`~-H;_E5)O6P45JZp|O?81H~)f}Bj0UBo?q*c^< zjDSH9mNeRl#(_?mfd=sx&$5x9hHC|IJ5y6T!><7!!Z7? zwifB==e~OEbMg|5a3jyvM0a5;)E@t52Ec z7RLSK%|(H9SxwFE4F}rO=OWvU0SILuZ*#K^4r@lbQsT>j>ysC%>z-%S#+us`j>I~W z+*5_Hsm8k)?D@{FqhpSDrG}UBb}+=wLO2)K3_uT zq`h;UG0^3z34MomlY>O0`%s)eZ0B0%o_{=>x_(bMA6&dW|5(2#^dC5T2uL0Zx9HzL z;lkPc==#SP%1ks-2V8~x>hFZa#ty$B!!25!Gug-OPlXOeo7#>^V712XJf%4w&z&pEHYsHX%m{EM{`}K)V2XNY1OSmpPN0%Mn39eQ|p*nsTB*oi_yow97HQde-e@JpWCCk z%(~en(hSb!Y=F~nkDjcqlDbYQF|2>}KvD()DN7RpCK>+t6GSX^^CkqC!&+gi!ymZ9$O(f8O?-v zSOFzOFhPcqMg^ESI0QA7NqCjH8GRf=d0)byt@#- zf_-t7b41rr-B=?7RE4)M}J4JSt^ft65>{+IZoZoH8$@EA+GM4iQ-E;Z)K zR3Z}Gq7v27tI_g7fg(b%+lBT7SBxo*&c%RIL6*~GN!mqi3lDtOmveb$-PDqGQ`Sl{ zOp*_krBoZM^u^sV9AHKOS6t@!<6UW?f1tQqMzBNtBxTGo(LrbH`Hh3b(RYoB9{w~s zI3avKo@yiejE!iHd2&o>96MiS(>>XAHL>e`jgG}8o$ngEjDC%Oa!hzE5On?H08Nd) z>e@JlQur}>*d)=fA*5p`7`?yiskW+dNM@E%?7e6|qj+}s_>w0bA>z)|kJuffny}CX z{dlupI>x&0=j5yP@_=lIV3j(LF$4Xf)`uVJ0#6BD&Mv(vW?7S=*rEc||gdJoVTHr6y9Z$j#@^6WUcR0pm ziaI8heu;Q^^no?)7;2n7Y5#_JNCep^;<3Xf9xGhQbLJ@_O~PrhSVU7WNv&p^Cg`8l zB;augu7JBNls<3K##B}Y!EC2kgMR;Wo{|#!cDPT|))bp}vX3L69x(j5UkHL$V(w>s z5!KsioELaMP{S91oaNXC^?;4vwzCd2A5&6VmqoEx%WD%D$%?K**1(^cmts{X|n zs(vh4wZ1{sXO61+NeY`2M$) zZCafzu>3yiPlw8Y|6t_6rY@U`Zb;=3_w4xod9+7*hk0_S9)RBYa3Et zczV_Ew!-@WdScG-ag7+m1|L_e;B&=O_1$ROP)g`R_T72rL}`_|C$D;_J`a!oDe?ki zqBIi5&-UK^k|%4Q`T=^#g!gV=h3b3D*6CN>8nUxumo|Sl+%)sH+rIf7NqM}v^sBEY zC$rvS)w52X;H9J2$vfDL^g7Wun9S>OgGsIvxu)V7Ni8|deNC-e$MiFZ?)9ScRw4Z> z-MxOJ{JKs58WXx)-Kf8%g)UJG^*7=}(J{V8Aqm*akgg4BhEY|h)96}a=y&r*CatP4 z&nh){y#0aZsICcJEG$rTwId~Rj@g_Ermp+>u^jzj3pHGDFuL6rnB{1WTfw2|tN!>~ ziMrmPE~5V`t=;bD%RiAikC(jtcc~GIHdrvr6aM;!D?(F+D(b4wH&N7BD8x<-f=;I)+QZ~Jy6>pmlyV=OGBi!Fsvuine)c1 zZQqwx`e`MenzoW7?|4tfZq|LQ)NdeZt#tO3x;#820n>Pl6PjY{Kv+}u1F`xBV`ZVS zvdCCD+gMp>(lXoiAAKn0oMg5kD7TKLtGsc=CTNYv=yA)>T40}7~?J({at*r5ahz#)s zjgAJ%qur1~Z)yx}o3y5Ef-KnPU^Ed^1@;A3$#U4({zU@&GGk~6B+?@zk@mqONAHAK zZBM}+QGuD4Qm4`&jy3$3aM~{|GfQzRKlK2-`vHNToL46rNQXY=H*YSvJ>1fe$N^p} zJm;+NZMTu6+!lY#(i;&BYM9!qP5kwzn@wu;Q_+dXohXH||4WKbcGDyj+#eeN@|KV%H!;iaH$?Kn4 zjcx{eJtN0+IAc~Y>>E1Q?1=A9>=}Lhh=2?w{wB)H&P(hH?*}_Cx8zPCuN@> z{`SqcHe(z6m-jTvv3+tJ8N9o11!rpltHoIFU(PRNCD0pk8LWF5tlI#i$Q}2xXtr<= zt@-J5ygARJz@plU?diYaSBhE-j{!r$#R>tzS!7LFYY+2zC}pyY8TwrR@9rdRoef%u zdTu9UK`o8xbva$`^@kYXGTR=(3m0WHH>{l@uS)4jm#0Nz78+|zlMoafW^Fvg2+C+&>|fTvnfV3(K)(_M;CLmpw+)PbY-F`p>wxwJr~Q- zZ2ygROC3dZ|LOOMtK|AdE0Il7(?`nou$$Gtv>D`la%W#NT(d0H#}LyrrC z^0@FP6fAmNpK$ur(u0>yM9b+%sN`P%?Mwvfz`Qrq19PB%;E~GHGA{9Sdj%6m{G~AI|;PWA-@iStDaMlZsw`iTBmi5Il;ObDe z_3jtB1sU;MPkB0xr>!gHarN0O4v@z?`N|f$3?c^3k3fcGi-J$nvG57#7+^Icgp8$g zw3CCohS&w3`WLVKsB?6KH&b2))to5r%Cq#~J|;~tX2_@;Gc;S+6S=g}SC+ST$%&6+ zcQ}g7GoqiQg~wXyQUqI|e3fz>>Sf`-if@{G!wqz%QdP{9gK&maZp@HskIotyqE|%I zQw!^Gt{$kjWuPvWwzp?o)RTyal2N+ulqLhUm>i{drS^Y2N(+vE)hPXlDr&&0TO@$J z;jen-8?L5R_R4=hX?ZxxLF9>#O^ zFn&stSPz~A0cn)>YUWI~?r&ibp>gxR`;Bkja?|a@^l#30Zu@TYw{Hr4^Sj@H2%<0f z_hsx;>oL9WChD2)bK$OqfB-@U$DyC#)*A}+fVelDV5^Q24{y0=$ZGW0RN!%>+E*ZD zm3qH;fEH22C@nIkJtm#!u5Yw_c_DYr1%<}UOtZAmoG3-mvJu`83l0+bFi>G=8{a8X zg_JBGAUOkn%d`kvV>M-}&u@|U7aC3ITnfQE`(i_0FcPoI;)TeV2())N+#Pp8Ot?U# z)TY^&JM=e^aQT7*oG&ob;f^k*Nc_O4Zr`q}@_uWlztZmeI{of1^?f$w=sQO>FI(wF zdR|bZrRP#_^MIyQ7zZ7pkesyNHSKwq{vsR7?7KVuz;I*Y1hb_qG#N*+tMoJ#=nc8j z9lvDs&$CV7wT6I}EKCazs(1g%_JQdR4*K(sM}q@C;g-97fpn?3r78Z4QLh`cUl+N7 zH=Akpn*yV&cE@u^|2*IQ0>QQNo*{E?7LxX$YS6D6M6Bj@G&eOkkk-p9?e{f5W$E>! zvS-Kw*PS!;l_hXF;>_c)4%!m2lnKo{}s%SL~otD^h01D>dR{G&>O@SfjS)!T_ol3u%-_ zGXdWxAy2w=bX0aC96J%5t)|@Z72ZG}c70~ujgJJ386apuXXYP30QzGk>KnE2bif_) z>tGK?;1Ai5Da4ijLgGprkFgr}1C@=dXKbavW_$2syv!7{ePkrwSiAq8R;8Z5iDeM% zgNWh%u2RjYoTh>3T0X;RR;kBA6<$i*EoSf~K4VEHD*Pg!QS9TQQOwS|QGPC#FUDdY z*ezD+;wq#5Ms@Ev_{g?CDxvmMYIRm&2bqJqGrGnpy3a&hbECM0u9=PRQdW3|0o3T1 z8Rm)(S@RWNapx-T)YTcKi|A{rXwee2S}PNiv$pNy6dc!2C)5HVbZ_=HA-$2uY;wkV3{|vJldIUEbT+@Q?U4OX;rOT! z#L^q95MZ3EixSs6C=l{#i~+`rALhFfxw=YYfRUJ=m68o`^-vbpu!m;5DtOr2msR61GA(| zt+)ArS$zcGmPs+kBc?Mp{Xz2#!(&X6DyKgzAOzt)6xHPe1@j$|ZyDuBjBuOySbQ@yTmffm=YJ z>VOG=(VHq=ZrOT@pkgwQ_(W~`pG4ai)8)W^_qs_CX~xywddm_!8k`F@-y41ggInEd z=6=zr+he{20b~@46mA;0DeUi*C|mHFfDJSYA31~z@e4oyoL%TJ>3NysKoJUwq~{WD z7{z#q1(rIS-{z@9>7Li0=2+(0n`3pU_-PQA6L`O6zS#vxHKr_a!v|iu@M@|x-|qVB znBFeaamB&K3Ezvc1O^!Nw#``_c)$5if$|~L^u%D$ZSS<0>pt@=BXgQTSVn)~t>#C7 zH(Ma~o$B5_w(G|ErsKYY6?R>26GVcPIs13Y&HX#Y(d93JJu9c0jt7%PR-eg_{p#Ry z=Xg5G>$-WHGmtdkV{n8iycTCeAF$=FS zuM6b2oZ5x=M!L}dg)R)xg`d}>7u>&-X7ArgGv?@4?B8YgXJ+Vsj$X%8Te@tW(E?xFI6Dsw>vC^&hQRcezFo3 z2fE!I+c*q?fAa<4wA~y3i(g;lj~-e(gzt>ctoGGOEBnov^8nHqyJ2r~4;n_L(9vuMqWmCs{=C~ zBfsA}DYc~TSG|8ZI4A4i?RIPVdZ;d|G(g?WPXI9KMh+5jmubbaz}1wu!Kh|Eh~?N+yQ=_}q}>Np^fy~!aT{r&|b?_ZF0s6LB{_ey=p;-2QsiDv9Y z>>AaKhU5!r#_Q?;(PROdQNZ`N`2OYhGsHgqh@->qc;~_8!;{4PpYqPf6YpHcJ6WMi zJ#whcW9apuUwX=*&vfMIaVIK})7NS4QY*&_;-?JZJ{~S2W+JB>NKFACRF65}caU>y z)Wv!547A9Pye~-uyf%ZTLxYKxwMwtR@Z*eJB?(hp+kkp$Os&D&N1a9OxTB2ub!us# z-PwG2Js^+bp$}jXuUF!JWIMgEos*8Y|EAKEn#Ru;tJl!K|C>tVY~wFgT04CDz`H4II-&HlDNdqXTUqq%$;RBI?qz@~3`GCka zzxW%Q4X%PX(%=B+>YzV>K=r=NE^s-p1l6QU`e-r1CWLI5y}&193p}B|$@FOl)Z~Om z`?4{p19b3~>Xi7g7xYlS1skEZ^1CR|-;xf?5}!bUN96*UvlzE$6ZeQFXD09+k>8D} z1;HaU;Dmau7IoKt7@}Hs{%cN#b)(Q7jPn2?i#KYo5mp5)-pI|u8irvFhsv!5BCi~x<4j~f*CZ2Oqau?YCwW4{#pLz}${fx6k+vu}=P>M{wrRo~f-MdLK%m&$ z{PP+@lW9dIt>HCzP`lS}mE{yXQV={GStiZVZE<(}kjtQO#L95hJSffZi!g|L5H1@P z{^&I*f1<0iQX=PSQ%i0^c&PawdB=q*g(L0E4b1hn)Wy3bTCDt_8d!qBTqf`SSUmtzCNtRkr7=^| z*sH}9Z8l|^(=R8O+q}-0eht5({>xM3&x*^v@L|dftLUq_(Jo)0$RHmR?FBi&-CRI*(5=t_=XLa;#61OZ&l&89dxcmJx}Hy zr~2j**>(MSdu2btj22XRBXfmInp>DwK1kx4N=Jk|JLVmk1>UjYGtFvGU=i5zlX@Iu zc|!`h4rSYwMmv3=Rp04o-k0PeS?RQEo2+Z9bFa^4VhMI{lQ+0K1g*m?E)qf*cA=a| zn_HN})@k#E?kKp!6-hJhaK%bfsiEa2v#QASuKU(re_B;xL9^UzcA2Z4=0aE6CuXH9 zt-_HSioTJ=EmnzZmW;6xMz2V4Hbn&s4HLT3-zZl&LP2=OhX6V?6jLIvKf z?5Uu0dr?CQvBwuOjl}BoiClzcrui4qn_MXY`gevj6Ub}ti>B*YbBr;b--hGaQbs0l zm)E`S?{Y*12gM&3l>P*n)&9MM=CP>td3e0pq4}!8xIapS$+<#--Rpl#qtwqN;_T%u ze9d`T%1C+_^R1j6gny6&Z@oDC;@Ke1-WUiI2n*4>yeyi2cZcEu*`RcYBvHGyAk&{1 zuj`$G>(MTWtrl*JoF^rj?)CBpoE(A!1tln_e#9>c#ymi{W!n5~GnFkIzAk!aR?5nP zwRcWUVN=r3$hGFI%$`)O?wIFu%8k&)@vqs9R{uj_RnDN@zoW&%rVNe=yX>c}a@T@T z#qjFN6%7$0$^&#Let`gd5RKgx2(mtyvZ+B=&S2=mz*~e9yp?k@wMHJ zj#c_J#kuN#6JwkWn4Sn(2Mgx2Krdvhs(OOJxLelLpsF>>`(ld;Djq7B;O_Xp(%15S zLX6ESe_FLfpc>VOjdI}K7!0So<9Qh<&iV2I8OtKi+HG%eh4DG!UT?^~A`iqU?e#SH z(Cjp9&-r7*A)#Cg%!MA(Nag2OWQX$#s(ZtinKgxGTc5e;noJX~wnf)CEiyosiuh*a zq(NE9L*H6#RcXGlUX;@SqmwyK@6L^Q`-bWm><4j?>@B84?FeE|@u< zqV0FF7;KLA2>Zp%tRg>=dLoSnzavH03)AmT&{WbsSCWe(IF6qf4<0hf5GeN%BU z=#1aeFvvKmHFHG^r_I)4fp&A4^H5ENYG;TMfjhaF8*6gLr#9@C@(V`Fi?h;c!{tw( zCreihmhzH2cnMz5s`>-1wINW92DjXm)`>f;H2t_0nWq*}$cj{`dHU}nHCrAczt9)V zuH!>Gz$;3q8|h&~@ONJ-@&Pzd1iyX7oj(dfR2|u5*;L7-U-Q&^<>CcYfsu|rTqGXX zb`mW02Yq9>*RQDBBcq47tBaQ0*Se@Uf8ZssqR2_*_>tp3`q?~iWs74R#NGl(T7NklW!xx)( zcrYQKXRaztV|}+ABx05wwGdUUOMQ)%N7Z?IW!skz*j&S)FEICT^NT`W%OS7*{wPbb z%-ei_VoU4otfTY$)kQ)~mpU7##qKIX0;*%^}=6jm>}Lj}!`3 z+YSH;qyIt;doo}?vW0uGYORvcP5>H|qF>ZXHTm@R7+(Eghz2^OTx1-3Q}_@-MT3L* z3dF~m`i5N4HG!Xw`i{I;mvA@Djk^a5s?kYJHvPB1|F>PIU16|JR)Td>s|58xmjeI>CO zYicXhy?Ude{Rv%etGmqCb9NNW_eU;71k1#c#GLOn-_F?+cr_wI*?76q8y}OipTyes z0|m?cE$49SpZGD@x-yhxq~T;+s_WR4_T;me12Z|E??|>d5xO7=4H!#jEj&+4m|-Hi zWzHfJx6gDO?T|tL0!3qA5N=qk>pGx$E2U}M^J#c-RZKTJew^N*Pv`TKq75Ew#VgEGfTQbimN z9%keTRxOu`_R$Ivrf89Ov(`;#mzcX_i zCzx5e$lMNtV0t}ph-NdNUa7cpkysKOV|X*Fo2G1c$7b1kDJN#Ve@;5ox$+Kpqv*dcC?&j-r$5tj|<%3XmJF(BjYrk6T6VTBB=xI zCvsbuBDfX?^%`;A8i?Kg+QgJgC>is8x&r zc-)`XRG7CH1(YxdcxOZRoY9kM;q-jc42_STbcC;zZ__Ym7#{hSZq4__)2#U}h#Ff2 zWNcEWq}34<(505o6*}Mvjmz6x3eVt+|5Cql*kYP1XG9S)6`E{}E2ug6WrW{JV?X)K z`F=#eK|=1+guk!xnS(iPgE@OdKKq1g)dM*k6E#^msGasOCM3?_VtH-EFGv50>t(HY&~dP_-0+Zu&Ij+#i0 zOwnGyIj1n%N@QW=9NYv^t`3Us0AlV`po3YK`{;km;w>kIC&Sk9EI&k`3VPffKjXXf z(!D{mn<)J&E6@s4D*O;xu`Y{~ZJ>y@1Zc~;5KYx1PTH0} z)G{cyFl`s-T5}x?Z*lHDL3ol;CvcgBGl>dE2BaYDi_9QPw3)e8GT}xpHc9Z39Vp9< zoMVMEV?h#D#)2Lh7xfU^MdB2Zd`kjhU-M3RX?R=Sfr6zjcgNqfg2%^_V~ehe6=QIO z@(c!oz7|Z8i_F)N8I1Bb#Jm@N!<;@==wYG9T;m83eIVL8Bg`^=LzEiTgMn&a^PgyA zVCi9E=y|&OFrq2P!sSLPKaJ^|<)Y(Zq17SmA4`2L>2VXgF(#(5tnXR)-3 zqUDE8?*1qJOXAxioHhgjqup*!3inxvG>f%+7z4+E$@`5kl;%o zq#MC^%vo&9esrbo=$j}D#PA$^Lu6?vUxe&{XknwRmy>+Ae4BfN@Wtl5%N@qj-oSp@ zw!LOKJn=yd>Vtpt`RHS{NpzaXQ>P)~6IFm80kEe!#7sN9ws~p(H}D=VOCOtarseE5Uk&V$0Ee{gX~7*NcPjVhln(@Uh)WZGDNK$9dFTJ? zK6B}7fncV4-M56K;<6GvxVDWv%j;vZ^n<;q=E?^H%E++ZojJWxGN#Fl+~A;-6j-1~G2|pC zYG@vGqX2`z7;}3d=xn)w?=9z}*8=CKe0QL{w}t3%_r@j~8|XS(FKtHH2=?iKh$9w` zPk<1^VgS?m)GZuJktpQb==jAMn46p8Ep9mO zjn_+8nXOs5jIJ5pW}e3olMdWxOtNO>Zl9Hv3h3gjEXeLlD5)f30NPQmEEMj+!)#vn zy5A!Rh^oxJ@n?L~CzsFG1B&7fVXw`TT4gTw*2)H&EE}kV4K&#Vjx@o;qU9AYh`=h= z?QdkfyuT9=++E^@fJk|#GbMaI0aRq15|XA5Ix)Klfkw<(G{%RGeJ^>C%3Xn7jKQw8 zZIf|!36u|nC&$wR<%1CrAt%H2ivkQckf5`aS2h0-mOx+uN(d^56-Lc7DTz@+ax}|g z6iJ5Yd*qviI^Wg_S;j+CX+}w|unPd}UDEUA+`zkm;Z=h|=m&Cb zx|~zy&)JnT&!34wrfeE7&%!VZuqSeqNPfJ<2Lc3tyke}mN#1H=*dje6BZ!e^23NAg zze#$A*UrAMyC;phC%>}99DJF2- z+tq>J;Jc)JvmuhD_%QOiOkR*l_nP0tguB=77n5_4*6E2k<-~%)pS#F#yf{2rW|2Rq zs}z?E@2o(Tv-yvK&)pr5@u)O2(uk*m*X-fbj}qYSW8i23XVkBzvL2XRXoXA_;+{iV zt!II&Jet|!MWI0JwZnshet4$xPb#XYWzivS1t2 z3ye^KSK>a!QSJXGmj%=0*VFU|h^@HjCkz5vd3!~d*{2Ow4>KNlgz5BW>oF}%>k+MH zg(Gr%LaQmxaLAo5W2Of@F0=SX0z=a!ss@#F;GOorR?s!7q8-OXs?N4-A?9?I`3Nl)1lpm(CH%nvdO}%Ra9cw8cE|x|kbrhzebkS*D z7T~DK90kJ8@VJ6tUj$od+*eS3IGn++l^?~^_!EXe9*$&yWm$0@gSK~c_rS&bPa$&5 z5eGu~AYGw{11NAE?sYe_HEn)}j{BoHqUkQ8%+U-r_;s#ruUU9k_HIWLzu&xa6>%$# zE9$L%UmsxWz%ZJ{S+bL~u_`CMC}X1RiF2lpiK#u{$g&3*UZsn-Z%Y8oh2c z^a&LGF8pGo10RW4vafLkRoBOZ);^>>-X}bFPsB509b*)E8;8wjb^)aL?(kDD@f5l< z@Mb<$bMbw0KR+lC+R+bw9PL>l-lR0ec5_U$cS8-YQ9IsDdUPT!>2Ou`6k5tW5Ghjde12&2^%TvO) z5ph>RZ$^eeUoL6%EAJHyDrrl@Iz|u{FGF3-+r-Esv3`xyj8c-{UOuYO7+q-52D^|^ zx&qUR-7hutNBTn4=#~NAK9#q_I)M{OFrD~N4vD+z#i*CfcG3DvI++jL3=80$@AH>M z;V-VM3oP?Czh^}X)$4LEQlz^1Yib2YU7cuf8d6xLWFWAnw9;F%WVty*K>E2gkpTAX zMc!0GU2a>BC2qy=HJ84&f~1~h<_t-5uZBQx_u~vKNKEQXIw?~_ZeLGe*P2P9D=aDt>{tUrM3Ie?55oe^;;NpELAtI! z#MLLZ(xVpP-XS;!Gn*)-@gT>62AT9L?>gGN1=^a3%~vn5Hj>EpFHRC4BRkByF=g99 zaW#Iuo2Iup?N`LWaL7tAiUj?Gl|mXQdEdHH+AS)w`sF>P5|X5^uTqcE4zqN*iGv-p zm%fb~c5t<^pb5fz^&58oq$QQ=Iu9$4d`SgOrvhA$trh%sFM~V`TkV3?Gv}|UQU3+t zqK$!VSlvkId>bv&~s*Rs}+3Cm>qj5el>^Z(}{w6 zC}@^Um-AN6)T?b_J6((m6R|&zv+v=<>J0wQ3T`cE+v>h|B~wAYDeb`a7qmUsKF13E z{v~PF>B(kYu0CY*Q{>DREas2dLKxz-mr{C+LN-yT@o_PZ3k zPl_uDI=ZYzDkqDl4E$MU*>uTSdzvh>iZT{l1_!cFx=~zF66kN;i#?^B*zi9tQ~t?z z3Jr#~KUR`$O*2nc#A;Wm%&FQfELZGH^UI9(d~?l;8i^h0S~F?e?&qEX3E&ceXNkME z9g|;o@=I*x$s;kDjpHPmR^WSFb{;s_=Ho2x$BVuq;-K{b;s#k-6)ZaTX_@TP{%Gfb z1|IDXf34A@e)4tJH2uRJ%5_1Lt0(0r)P@Eb-yoqq$X&Q8ldQv)Vk~nQCC=lec2a{_ zsSPn6t9PlX5n)m1|DFgWkk+$^l5rZBgSyirJR9iN+*WId-{L6Vj(G`u)&(oV=d4{- zl!9hx?OMv9Sd1?vX^;BB?a*>GC@ZWcpPc}WfV=m?*EVLVk8)`#6`YAVLNga0qsa^Q znBGw6_VImKxuPltrFxk6Qbm=nW4TZn!5|vhAmhvhD>QI)wwCXlDNW7ay+vX#`p9!} z@27$>q;V*8KAjF(7-Tp=gknuBGw*wX-{#wIe-e1`Ili@(nD=d!D;>Y!Gq9(1a?T!e z_NJj#lVaDW&cR(VlpaUfyV<;Nieth+dl_5d_P+31V@oU!o7IReOI&3H0jRI39-* zx{OIU%BL9-hbc(9{HMN0L2)0n7ZaO)h1xYqb~fpIKpcDVNqNTz%BwbT2>5ForVoJw zR!bhUtP7SELR^yBL5iR;=eY&MZG^T|)XEoNlYVvAX5kNh>tDJm=olz*$bDm9Bw45kV7cS&~ZZtH4bwAB?{ z$G4DA&=5amPdvTEicDAM$c6euu!5My%5s^kio#X~EuPCZ#yXiF*w=bm&OUSAvqP&~ zv#v)L*VBZYT9j>$E4wJ@TxL4%wom@5T7&QooHIC31)&_6lInpW$M-{4haBpv&G2(XSLR^OU@pZb*XgB8|WdWb(zyb zO965To6abiW|riC(bFMIDw**U#OF(?OW02Hb7$@u41a3O z&y|dq_?w+8vr$_^_~{_1Po?<0RjB?9+4S%W`svYk_9gFNa2qb(HF8mAZW=n!W!deg znHkpfht(6@EQVXiZvCe{EkEW$t%}Jr_O$GlS=k`J>l1mPwSb$2`>})kfXk-U;zB$j zg#bz~K{!_HcTJG(3g&0G--fhCDnP#{nx6s+{A|C=ywQ*ERw`={b4N`PuZaD6-N(y6h9UD`5YibyeL_cVg)FeoJgm?PX z8}-5ccZ6*O*YU;Ur>mNwSCar!yG|M&{HK z&q4j9#G9i^Y~Gw-nV^dTekrX76MF~41rL?Le1uIt8W<(*^X$li?7aO0XdbVScgQSYl`=zT^&qg8lY-zs9ks#lUM_-bHk9O+M z*YxKb`tu$A*~@3oM$rRk!tm%}ef5a`RQj_|fA;IoK|W&}1w6obR34}>9(Cv+f);5! zD#)eQKDy&DuM{c}+gPNp=kiI>Y5K=>T`0D(OfFjcVjJzFe;=oNm5N-%6qLIf9h}YT zn~5J8r2q1$CHyi2v2M<@Mzixsv=}}c(@VLpWxnQt(8G7?q?2Yy2tgK}i^ceI#>} z*l-VoE|pUai|*Rxp-=gvF8%@g^%kdwZI88h)D?v|H>mGQO-b8;zx8(_gWbY4k-?V8 zy*g_p{Lcz{6#WMJ=T~H%a7vP1!?Eok>mMnyPaXUJmL3x(xpmjAp`O&A_Z$NLJYKb zWSN;AWN!5r{qTfkz8Wp;NC^$p8~V16gVn^ttXyH1k!xNuJ3m>4E>3Con zwuvz3nVh3Z45J@EFI##st0&oye&wYfGHf79NjGdENSN)j#T2o2!?`!IQ^OP0)zVS< z-aig!Y68kxo}=3SP!>VD(B=#kxe1{-UA_M!0dM&ysUvM_V*{+JUp_CcmNNyw`r<9H zFOLf$uvhWpxiX9dE_^+SdGbY642SAklU&HN{S2tD<1nNp!M`b8JZH8yqhV)>b}ja9m)|ALHV^~3FLv>I-Q#I1OYYEmjB zk4J3+fTRKli0l=Q%XO&UBSZXcbQ;UNIJl^u3z%M@hbQ!;_|l$PWi;7rMTgKCRSca) z;?!);m9aNMaA2B*r3WT_t# z^T7r9w#21O)ghPe(kUE`t>>jp7AYt@2KZuns>~hM>0rkZ`Fd7(lG$#rDXSp! zfzba}HOK&wQuje2veuL*SmZ{>ZoZR2H!)*h%%Cf0rn`M)#(Wj(w)NoKxYSPxA}|N* z43yv;q0>mmHeK_0sUG3+GHe#F-eLFt@j3L~bj#UZ1&D!Dy?BxKWrSU`qVxRI;J(56 ze>tDMXjRNkBtG*cGqI5tRt6V5p|>ZqBLMEtOUcM(1oKE3LrE1p?3#J{ui zo>_Gj|F-b&FekG7Gp0X-T!JxMRr1&s2RI(Dg0si`uMbs}#0WFpC(>p4QD7}vm_+W8 zT$Y^ZLr(cE@jjA+l_chwauemABb8J5(_aB+B`2(=Fsq-jcjja7us$h$ZfvuhZ02~B zV5i0INHzbgS*W}~SEwp}6l5jINco4erH^v%CXaJ>qu;{spo^jO3X8+?- zv6_TjZcdc18tGF?mVfrCRi|G&a^Nff?}TQ1w_PTXR+Y3=oV8r%%WyiLH*QcWz@NqOBW5VaM8>3?c-fB`2}ysTZf|6@LXTZ0(oguVWTI3|oG7 zplwLp2S`59J}IwLeVMc{;nGrH#Xl<)+W z>2%g6&JW}#G~ZfkEtlM0??0Kyiz0n6?-nM;H01op$R?6iYfe{ma7Bx&5l*}A#Ia~+ zdi>TI!ke^!XwN$a&_5>z;u(8Xx-*NQ@@In15gje#XER2l^c{lbO{b*dm!QE;9ig`o?+u-^>%hi0ThpeqN;f~eJ-g>zbEqo0exgG4UTP; zfzWr%`!xlVygJZf52P3lI|&LM+a%?{6h{Cd#@QL|a#p4b|3)(xLB^7zX6$8Q*lNvQ z&L1x0#RxcO*I&{DT>!CmyQ%=Kkm7L{tcKG}1Ec+Qi|i)$d7;i`N6@7+M74rm4Mj`2 zli9}gp=db~Xy~;sAd-q$jgj%vLU@-$qfn%u#heD6qhglCWAzvaRvohIOKE$)rZ~b(9c}tvX6M7P}beb?C##Lxw$dZ);%6lmyyMs@DG|69Mnz3@4ts#qcCxGYE z5}VP65$Ojbq--2|z@A)5iroKXK2TmR8=?CsdK7E(t&v;56IyU{O80cl2<~d zl7LIBgOTeQJ8ficIKrqWrQs{^61UL{P2TL3HNEN%TsQP`(d~*#yB3X4tdO48&$!o` z5;|i3I&o^sai3@)%WTFpTIy&XU(@JRQI;7^W1GplleBjI7uL})e>039D0^JfTHr8NJPqlgCgjYKw9 zh)CX5wrS4nkdw>aLLO-eUoWZ+=&Nk2RdUS|D_05#mtyrYdr+snU(e%$p8_M6gzx$9 zr$k~+h^00f%_!U+sI9q4rqFyrSV!O|)EM$N5XIz_7=b?{hsHAs${eAwCanqoFaM@N zbv~G4pIw|JlA{G6ENFXDV?W=C*A<{w^PPs{hgOLrcK%I=Yt2E<(RDsO%{ zi@P=I2UMANK!UxH8$2~t73y6d?0UElPMywz@3rZ?QO95v{{a(i17bG7$fuCQyD_Co z2;d{~ARWMe%xSKb-cbiSR8Y@B`5mK?emC0V3l34lV??}he4jjEQ=9rac-8h7x!9EW zE^uAtDpuk%UXW*11cpE$dg6tm=3yUXd9;z?;}$YRlFUvz+L+$XBjl z>KVcxeFQ71LKH_kKYYRtXZ4uzBZh2HVD(vpcekRB3W_@Hzr%OMEd?)|dJ_ zheW(m40`kID+Q_Tv$(B3tE{?hwX)A|AmNIL6_&!ek`+o3Qq4 z_E-E0+SvSZ(smR2HWuIcE8>`tjWet{j`&M@)MQ=@t`vbHe37l3yyK?;bJ$lhq8DpX zV?+)xwW|+ZZ!d^Fs2E3cyd(_~pR~1R7nScoO8c`0)d%1=OuVwQe#wb0PVn_m5xp>JV83kG^65|5LNi#vX8^IlQ^kSaR-#u2c?SX8ZDZsADZYK$W%_g)XGahQ z%KYwoze%?leB87(pE)x(4sL+sp6|&SzkVKNre8^~p?I&Qlpg|FDK)rCQ;J}VYKsRfvR!8v?sA!F4~TX_X1g`Xf~6HvfnLXP;@D?OA3Vl zVIKP}?Ov1EUH!2~rHYF_Vr@`;=O9te+?dmDL zgY}ZBOiGSbh>i~Hg?{Q(<$cgE>jitUY4WZ)1UR&GB}5z|Seh%jG(zXfMmP_JOol0r zv=!bO<&lTYkJ0V^&9?u=5(a^{%^kvl?LTMdMLTe5xWfT^XA8&nv$M@N*-RfK%?7&o zK%%&hBt)^2gztbZ?$M=Hk~9BKk~6>6dSM5Bz)B!OZ(V#5hHP~Qig3gp=(O0VedaW# zacuM((^8=0lL(s=(P)wZ6!~%p_?tYH<%X zXea|AOr&>c4-{P6o>c`8g10Udz-^-S8~TTgNjGD1tTb?K>tC0U6pdV5qMZcWhJ3Og zxV3IdzV4=MjoKwoU?xjwW3g-x+8j`#Wpg0J*J5@{+M4ygFN)5XE`k*B9&;P7MMpbH zRAQ!GcViJ85WMa^LFXoRFpd@Mefm2l1w-XT$IJO=A_KMhvwp^Zlq=+MXN9`wMj`gX zTTa&e^yiPXi7~Vmy(HyChXf^=hiAlmCFeTRFQ!gH7=E?s=AX>jM!7N%~ zkPQxZ4XFwS7QYg+Hp@m{o9-b1-N^I=7Wi8oGmQm)I%7Ig1$@Ynn1`;aFbkZ~dY9knp|c z3u2_x%A;3vHfmGdL-I*LIu5w^yZCCnAfKsYIQLU0<#eT{nH$$KU~u5~{hYrDUgm<^ z-~K$Xveg}1FBcZ9GD|~&WB8IBOZbw^ALUE3)m+dZjwHBDOy5NR7QyP9T{$HrF@?)= z<-lm+ia+0F%=hw6j(-yQo|f|}uPs5s3SX!l>^6meD6jai8ellbMm38)GM_BC9!7S}uu@nQ2{MJObL99=< z&k-*zY;dMQ)h@#~Lwh;)>j^m?x=>rE8n&U})+VYFEGnN|o(4RMgYu|#MEKhDu>4S8 z`x!dbwXf(KA(wtrVkg$TEHA?`P;_RntDctecsyuL*|P2t`&X&hzo@)c{qyhiGU-=! zgdCGmzdxml?dGVJBUjZ{BJsYwl@`>h$isZspfB-j#I>I|p*c?T!A@=xpz(E7Y%8-( zU_(f3bG^$zC5GQkkt24!i*#+c8n}$f2A&9_D+_lfd~wE7ef(V5LVSSP;*5_|wz|C9 z?6R61mPeq>R{zd3OIhWby2}t z=_Yrzq;Y`T=TJd#VCC3&hA>LRqG1NM9(XSSi$3PlcB_=OGw#=X*kUrr?q zyo2aze#~-MsomB%c={TVvq=Alvb|Z#ErYF|6j1hR%^aa7JLT<@8wj4z*(iYK9~F;T`c1K6%}03wwt$fblltbbcs4uh)MtOGpWXbWXS2TI*%iajHu`CAE8Z9! zpn%(twJxtvuYM+zh|BVbf`{3z5&I@um8;ZG^?kr2^?mDdwc#*>kyzOX>F_Co&d5}? zlW`xO=mGUVUc7hh86F^);(*M!dihp-WX9o#INBg%M>7i+nRDfes5K^3k3lAMgT&!W zn)ADw*2DsgLEe9|)35_${lCCVxeHUSC0% z34|VuObDC|Wjt2MGx1$KekMOBgV0Nm#ekYhsES^m@m)3QR=daJ<;I&FMe%3p#bO5^ ztDH()Uz7c?D&hEv(>PPD$AkxxzB!ht2qC|M7?+iz{*Oo~lL$DAeqzBLkxP!h86uiY zijNKKCPMX9W2UpNJ9?+XB1QUc(9O6&p1$bdxJX*#xW%Sp!*m)fS_;eme+n*oW))J| z+`x`_arETL*7WGfjMf>^lkQM{^yINn-rXlt`g!#wlyTmTJ;YiQIiGyS@iXinD?M=! zEW<}}Ct0kWf#KNJn_%3QcCz7KW zg3;3y*{gq=t$5QKn`1Dl6KhmC%D@`cbV##b#8AwW2$hZBV~-tU-c87?cFV&R4aB6< ztcsqDC$7c!q26KCdyIN-A~!eSO@K+)=Nt8_j7NXM1R9TS(VtK1Pkr(}`kem0O@DUk zPhm!kN401Q8Qk>f8~on%=$mpCkB-F{PlYNP8}H?c!r=q+hy2_mKd+IW>GE^4{LGP` z;_|Wa2l5kJvV~QdpAXB=iTo@((JLu$?tVqC$V_kA_(#5k&mhM)x>wZ6zkpeFzuaj* zgU`GOZ$@dWn#l4rb@D262VSeQCs`+snGeZpK@v3X7p8;NILU5_asOI=$4`&VK7-i9 z6FL!=u~Dv>`VKfq+fN(=aFJ{y=Nk7vp>If!?8jrXo$?rw<256%lBbPo;{2IO@(n%n zYTEXxK>plenfu(&RC|n#x)wby#{JT+!0zVpvDvAgQ`7PI#GF?XwH`|gB8|F?jq52R zy~}@8h5)8N-^nOlATAzQ8-OtZ4Qpkq`cbQG_QBEv)w%kIoG6LlV~{479{tB7jEl~N zjB-`2*#e`cvvKx*!Wt^xENe(d)?Q<_yP`b}(d$yemlB@93EV#_;EJo`YSqqC6ca{< zh@c6Z4e5!o&vwXcnGedOidyCJiiMWIZ3SxrrL1cac8 zJuVH}5&a8UcF=bB#?KWq#`)31#O``b(r#`C3pzAbYdY@&Yd(tYE`D|N@Mi>|NXm3^ z90a;SoVTLe1%_d~6b*?cCWGROC~g<>@@{tO)dlU|&}EH!b2qU zK3sdBCM3&TvAckgX&aUHp+@}}*+ctuhR4;YuMzFQ54 z4Qmh|`OxWt7OdGn)xDHn>PQoHAtO+4cJua;@OY9Flk-)g|NC(F9MC#bG{6(gWiGWA z6DlH>3}f`=PFkK4Sz?k5{6N7C&PY)K7!Lt+b$0Z+)bOR|0)N_qOx@?R3F2=a54eQj zundLW7&bJdM}J%r2j-HLG#8kl<{fru1empf4yn8ONj#|F#A;Ly#|nCBhRD)!ELO)B z?pH08SQ6ZLz%|Cp^CQt4lsjt;9ipPW+KrA*%8g27^Z140;^)QjrL(T!5xEJ}1&Rg- z8D2Z&XY(;r*S%@!g#4wh(8NH8Z2Cw#C?lz5=7XAI+^1>9t1F%EXYjKchh%nRxwH9=1L3miF2nco)!uy1bqFkU(%ee-LzwCae4)4pIe=Y@xJUI}mD6 zltH^m?&x2+P9Q@XXleBXWOwpYys30Q-O*?D&pwHkq8!gMEcEy zjhkcW=%IM(+|W)%RnT+B0egV!x&HWAWw zXl~+?n=1uN2O>a^0x@tz&4Qhgzh~@Y{RVsM63h>Z!c7vbc&^C?*)MWHN<)4#>EWDw zAoQrKr>5abh}eiQJq?mkQ11;TD4N0zB|8^4l%ny&6ivaTD)C2AXDuP&cX1Zpf|w!2 zsHinzLU2I4$%a;?3FWPcs>ih+cAaMh~kHz3d4HZP@T z>?)dUlO$WdOIh&rsxkLJy=ol)Dt`qF#oy2GdwSJ;{+{ID#?4Q!x|qLb@eeJRK2$z5 zh6rGi&LvI|JA8I2AP+FexZP=@NhAtqC9$6%e3)x;&3UI~(@ovACy^D2>~b~l1|(0^ zbg6`AchT0Zk%v7!066|8MR`ld`Qi-o+DT#AeIvKU% zXX<@u_KYF{Tf{+9W)~(Nx|k_LKDJ8SNm#oABuQWZOBaB@<|Fjdr3CPXy6Tq|1YOX3 zuB?5V(?nn{8WV|nVw+fxG;@yAx_=A3HTz|?+>uQzUri=Ssx{XGvEQiaM@{C`hlDT~ z%QEwqO~u~vuEzQlK5^5sY?R*i3S^6mYO`DXpYr4Ru%y!iB`%alW%)+A6D>B7XhoUa zKRbVMQFzMsqM}r|FLLS$$Y#IJw2AWCiBIv4;ZSk)6#RvpG}+tK|FV(Z*_d1ziI)O+ zP(6h6B_aMucx5&F9k7>VC8X@wC{|H#pxpg>?fH-X(!j7r)E$QEu&|dC4<6 z>@XbPpJjHzVH}b(K`)|(RiSi-9lWaw?{E`i!8cIBXH==P_cF?A5Jo~8oLI^iNrUUN zPGyF)QHtf83#8NDTmh(AfJGl@n(WxT@lGY6QES_0%4vJQtku!nk~X3G)%SQyVl@i1 zc}9(Fe3qQKGCQroVsQriGlD zq$NTl9_`Lb_~OL)-J|Y9$&ldGYI`zTg~PgZ5B=00meLsgR*Pja^gHnhRnfLpwy=Nv|^z?oI@8|#d z+me~td+oK>UYBP**WaUc(FMXSop0PLN7A@^oA}H4i&?8+a;a<8fXMPv(;KAS+|Sbg z*<;w%{c5r_&D3&_uH_zGi~IDo$l1!46gdL#JH5|WjmKw6Z_;raWh~2$hxD4>owgM) zToAGBM~?!%vVHc^qe<;^O+;=0<~r0eTt4!8SBRzhM!p)DACQj`M$KT&s0>xOf%PR( z{vt1#WXe3IM}ofL2KOU(j7r#ZEFwHZO`g6*Hsn97eVhAn6(@KNu8WXZXw8pNcLt|(i&mdltj%P!D{6vfkD-8b+EB{77trAv}cFx&L>F}P(e&?#8k%`Y3 zv+e3Rd^o_kbFTP2rYjNV@L;c`OV8N{3=0Mf+-d!nV5K1HoDfFrmM&>ljiWvJ5qC~4 z%1-yF#Au5bpYVvZt$Gtq^GNu0aP?L#;Z@~W6+;L?D{=n_EB?`?-ndXZgM1koz6|l% zNUhSG#w@Ia&FcFwKhVwBn(FIqc@c$!WGaqY@(xky+x+C?q;`KVj7ojLL$IZlvj`at|~f zehl|)uzDcV`k0->JEdcL?f=dNIwgG12LZS7YWzSXWVBorKqQSTsmS+N4PH1$8l{^~ zqdp@%SicAP9M{>2F1I?D8NO87aOgISRJx(MmgF5@`>Bp>H%Aw)1(t1CQ{$bui>qn% zqOl|nMHKF&8w82Ft?|Ngv0q(9MY?R7E;~S-qss!dTT(3!M}Ns_o6AET;ji>OHg}8N zHI8h->6V{eUKQxgZ**WHQA-H7)~<@EmNxW3IB;_O;`6T|kJaeqp-H5$e6Y$bazM|i6j^U@^&{4G4hKrWD}0DL7t%o>Ca9+8Hu*WDOFOzon{3W zp;MfeW&A`Jbp9|{TAH&f&{nYtgw+K9Ks>FiqlJe{@_N_q2>q&uDzW>`?92I++6&DV zhv9x<_5b88&9HBCX7JVeNM=Zf)qjrxl<4f?tPbb>2puV=s|FUmF>AwSg!WgvjuD|9 z=C2i@{e}*l|41%GL(fPZ2+*4uon3qkv8h|fW-p1xX3rN^3CKAjvw;skY|QVm;<7!} zCkAGx89Z9tV}@m46n;Hn=HZUwV+r7`o)D8wq5dJ+4abPceuAZVN<=nvT>`RiJ1HQ$ z7S+bdJlAK#I1}Rm*+fhxefG6@?f)9j4v}@lH3SdZg?5{czyF`YvCk54N(3KGjL2S- ze?A9}-UAewT<`Q>p&sqh(i1)%9IgN#S68ZwUWCT! zfV$3XfI>uT+Q7^+%t|yy}Ff0Cf}tzWP4g39%jz zmT#$_@Xsyv8@@oN%fEl;-=qBNxnWCvCGE}lAMP`nRXD7`nZ)RCYp&4W2#7DQtHClX zz2SkKCdv+YJ5}m3*%^eIu!a85fgJJ~G!5kN;7|s#pUL%^uwGA9O0OsQnL+;okVBPJ z^1o?v?Z5w%nOtlCe=P)`{r`o0>ivJEwf{#%_rK*8=F$Y-B>-~%eJe!6@+cWt%5fNjXdvw+=XM;T!Q(xV6r6(5(DDB{M#H|e6G%c47!99y z={fu{E+HmO_r~E}VqXuw5tvLlpPv5aJ*xE}vd1#KB3_NesnhsL>+);;BF` zyC`ds1GqHtN<;G@fooM`-s!z=G&b&%DQi=&XzSX`z^xxL zt^=F-Gz;^j*+_tc4r1ia+$;w3BjQA<0Ym#x%;$BaZ7`?^qxp7iG#_eA5-%Hq$HgPO zqzI0!abB`?)e~CaKtz*plk(`@Mj$}5jTXi2R{lLadMDPbtAut}mBzp{#`2V)lmJ9f z6(T?Hy6o1aSEF!R^8sq+!Dii7;G1c&ubsQV1j`h9I4pFJ&;U&jql+Da*k!r*h;U+% zQ01gP43ljGYEC4u#3f#39i^L6YAsZXGKq%cT7xrEp7xVA;ldfi>Lj#+z3@5YuF<~vw3V#VUA(q8)ufiRS#+rc(v+Ft{ z>(fVn0bU{0f8q<9QWn%wLF%=exS%Qi=aVSFnVpmV%4zbC4-~Bp8B; z81hy-1XJh37tm9eIGS31#%uvT?WpZcg@W3&cO}aWHAkr+#cJ@xB|%S?F)g302c?1n zKh5U?j_Jv3x7K&&1L(Q6K0Jiq$!`6-xOA%(Ss(&k2{?;g?JI(rLOVJ}9>G^g*6>|>*Y8W) zaF-OvWz)?Qf8+_Kh2;k?;fO5Hr*x&dicyiW{+p;R5ocOmQ?^ypkF1*fMbTQ;#cJ8l z19o}9MbqX3F7;OQ0n#jEBc$0``T-Zs?!ODX;W)N)S@aFf5DEHWz2jE%9f_$BS}CpQ zmmFh!NJHmK&)U^3v_nn>_RBhH1wQN(%9_X``bADCEtvjh=`yQyYyZ*-zN`AzE%}tp z(xa`?cg0Hg8#!B_E+)|bCuH9_bqoAj;{I4AnL>01pJpFyqyPgXM8^bVj;)k`Wgkeq zbZ=gR(?1?Cc7)suSp4p%_3k}eb`7}yng+<~HVFVUV+#9*>*%z@+=IYHI?c+k}g5McFJ8!7txULfmGQnTJaaj{#OtpoHgSZov^mg-G+=Z9_9UDzDTo)j#Vb?9<28))+B#8f^$KYX51uM#*T}X&8&LZ2My|jC4(@K>ZGnc~qy{g46C2Lu zug#e5Nc&}5+VgD^H=`P@c5kH;K|n$=Bk`z0ycrR^@JzaW5ct`U{{X~@bTM7|Qg}L< zy7Tc8bf{6hxAgsDE=xO&^sfhuc-|Zm+I(kv4mZeH&+eMubmw{C_;nO!B{bcc1ru-g zrAJmemUI?o5mQQC?{FBh^mU98c`o4?-c+Gh_?4R_W8`67P)v3=yR6h4!e1c>WrH8b zK&9h>za&_gg*z|eppXK|i(yU$W7p7alk|K&Kugn>&`$R69eTTJgLkJ;1a+aN1pXRL zUiw`Z9COMS=xWZO+eV4jV~(QFT)$X%cenZgWX?^Z7?#R5UdOfWBPL!LaemzJTuNW>;YtAzX0Q-s@gO}iR&4>W!L zmCTJ^0!eIW*9ohLg<;JG+UQDV#5h!iAk4g67@rs3qD-BA!aMX>!_L{2w*GQyK$e%C z<;AMB7Ubdhg4AdIi3`#k`V7(il3PlsBfM?YaKhb3kC|&qQV9ea4kt8> zq)dWuxK#sC#a03Bv(n%Se42pI0#oAFQ*!qaJtaTL^Y{8EK(xnGM`8o^{^$z#7s{0r z_rePJ4(73#4l)QVy!7Y$&!ja9?2gNgo~}fhi*MZ|I3nnYm01qvgaIb$zdHLZO4A>~ z*$h~NxWbLa9v5?{sd(YH_3FN5sP9^K{#K(GK%Tlgx%l%bIKv(t!6PgJ&DCUE;q}^8 zKTYlHe{anE_CQ-|;6U$Gn+xXzL0xDEoW$4@_&RHyJ#;PLGRZYZUp+u|jROjdSKsN~ z(6;UapYE zLy9h}{>EFzzzE^lcH>q2riU0)p0i!ErM^nd77(uBgatSOYk#@G_CCqm8u6uvie9w` za;13><|`WAj{SdaCTO`;e1iT*XsevkGOqe7l|tB@yJTa+qrfYu9F;2Ytc(N z6Yve64U}rV<5Y|FXAv}9dyN$Fk0-3FT-o1-$ggq)uU1E%)zbcgV69`W3?;*Y(|CF_ zVdL8p;zj^00K6QUPXxe2J`Gm!Y%b2HwjmaX#@R4!!Ih5ALgxeXw$w*}zilMHheIt& zhr=WOjBxnZ&mwll^W1i-AN0`~ptm_%-$)|r=E{1s z7Y&ZUI^Bj%+9+{|n6D3upm5O|~+QqZ|Iy(SZ+BWs^84_t&-KDLmI9cF_3Y9zR7Vag>H;R}x z(v)d$w;0y2Gwi?;qo&Y$U@38}mFdPnB1uQ!Kln*f;7zCTwMMnNlJL+}obC?v`92oY zck9cuwt}dMbDqDut5){AWc2gd0}Hj3uSO1~^YL==Q8ha{g^t2Qss+ontB1+{m^L;z zps$$5oPFVo8Q--TSbW=kqrslct^)j>NzMUjD#6&qaFOL<#@+Xb2-jVKe9c^-)OuQcr78cAYBh7 zI7;|m?0hoGza;z#S_OPfOT7|aJCwD#{crZ|U*XVJKe|l)?QA+ZI~|f~#?9}chQMn{ z^g*h~3U{AyGw{)IeLvB>?+@e0QKj03p&$c-LsLp?KfddV?nk3^5k%RZvx|g6rSk%f z={Elu+^*rYEA87qvTy&|p7&bg2qWLib`ThGH}A_?h-Y)HICfiFC5)rE-@xnx@NT3` zWzd_}rBtaV<^l45bgvB6xMIf|2k9=9?K0_*7|kq-sU3IRt}5%fN>$2p0fr$FL*`$MqoS1~wE2sQYFOZ?v=DA6IPO-|$`Au0m^2XAzC%3#@=f{p1AqtL8eb=hc!y`eAISRHJf z7i{zf8+~dTK5If6^Cu!pcBlhRqzsC#;dlzJs!)|k@007Z2+i+Re;!Wroko6^kw4`; zfgfMa1EX$@yPTl^Lnyxus=*XZQZ?a3`H~%IB!SZ}+b6H8;62^d;X#3VXjdX&NBPz8 zf`^D)bO`6=7$9%HeqSv>^CpHh;BtFXdB4LqoA0ON6t(0(z-(k3sTKZ(5q4_MhJ8{l?up$Q<_sj_O>bxQh(ZV3$^h>Z^mZs#$h}g6?Xg zu>$(nS#7+>>H~SgHz3>f-6TWP3w@`5a)pfBSj5**b0Da}iC-^`ive;-O0 z^^ax4pqD#j%<@(p*`DanFun@xP7Kw0^@;=*0|(!oPbT^l+~#V;l}a`JKNu#9(nP~f z=ik&9Q4U@NR;w|~271PE^)%ZZ7ib#KTS;D&yu#&vyU`vlGTh5@BI05)xw^vlJvq3# zjzCyD{bTFu)vv_wL)2QBzOdTVC14Bw3C$uSufjdE|m+ilP zrvRFsc*Q4IqU5|Rr>!zn=9CcS#C+|k61pR|j^w`T1z0FP4l_YIm|H(lRu(FCTCi}} z5n)!EtClnGoh*pnK z%@UX`QO_52ro8b62U3S4Ji?=X{}k`bVKt!B_Se61wGEec2!`geyK!4T&{^EAx$H}C zjB(iqaPmB$x$KGPVc6@!Hjvhe+~aMz*M??`!V6!d*BXa}>T`oreoD`-1pxmGuxt{@ zm%V}as8r|BAIvJ@foM0T=c=biVJlp`M}32eLcG<(zUZW$o>HWec%3x5X^k7ABX) zws>{|+d>+DU+07|dV`IQPPg;j`EXCGeUf3d#1}Z8xMGg6dY+(}__N4t@ah}9GUw=E z!tcmuQ0-``79^uKeECb}ab{k}bSw1~lQQ3-Hgi6B)KCAZ<({O-Y@cfNnr=_K)p=6z z4_3jYa*!0gurU0A*a-IJ*0`b;_VV(sa`t6(Aq23XFUodm6qc`E5|YZ9oEcg@(K?Qk z*eC=f^$zg$sGFqnoq4kz{>vc5T(tK;g|Um@A*b+&z;^2tPG}}E8YCb*06fH9I+Stp zx(fd^h(ma|;nv){AFhMtcB^!0RW);s3r1-6giS!AteJ8i383iCc-@yQwK@q-XkEI) zcSybGK!qZBk7sEa-#1jtQQDnlc74`%F5 zbstTHX1=Swyo3evuBMysdeo0E)ecTJ-)f57A-yQ{8q+mTyKXp(6k2HHPhi^!tIVz> z@p8Y5PV=H);!GuaiI?%fSsDz5L6Xe|qEo8u!YMYbbJ=QOWGu`HNXnJ86<7?7gDY?J z0lag!Y|;LWla5ojJSf&OLlwRFEiDhVT6X)$r?d)LZ(aoHk^ko-y|skNmf$don&(Ak z`Ovnm9K!4N1{-k7_0Q7D=Y2`%)!PG0zyzcz$wu$1YT^L&m4Uq3#ylj{Ft|`C__|(< zfUH4365>wv%ki->-P!ePR(;c*FzrK(Koc(o)82KMYoWqEl{gty%%}VStcq#(Ab>VC zd~Wkyh76W0Gbc-u$_Mz*2`p}drPv|s-zZ_|2jKEDvsEQ0!1;g1`j}jN02mNxF6m+B zlg;!%*R#}%RLF6f5x9{tU*obxw-`w#)gKYzG?#td4Z@B4$(*Thq(Es|I?*UyXn4Fy zuWi`1?hIpgg)wac1`b3?$=re?PyRy0`FXLypTmr>B&M_2Z^Q*1#sNM20T$3?CY5DC z9+GeG#?^F##+4gme7rk=OG!wJbcwFydy}xRG@9)HRGJW(Xd#?aRGqwteP zKk6`+6UtMnF1~?E8~SXk@>B_tDq4COVrEJ~`JYhg44)rbjwvCFgz5MY5k;V`0wM<_ zmFL&%=KB)d3*!R1ESF+2IXWWw_7ldlL#_Hs6lzh+r?|XTsds+OyTPxaJ?&5tQ=^6^ zv(F}Zd05VDYO!&wYCMVQ!V+zn(l4Kz?`Ge1oU4pStV>SPZBRr`9FGZu;hH z2ELOmF$i7*WbN=flG01!c9R2vm-dAJORQDHOue5I12*}`&g9wfg+}8<>FH=X<2$!5Nl1rDm*J%TuEWVE zQ=gnXIVZh`O7H&;gLsEJJDI#DZgPZwqyAHNxjvT;TcU+At3vISs@xR~NUj1PkYtq2)4xn-1v+9$uxQf;i0#*&x2Mr( z6hwu(J4|N&CdPIYgN5F=T&wXT3f7d1F9C5=;95JhOVFo)_R~gGK zHK;=$CyDH>x$T^2rQ=D387y6f%muIO2#P)sQ@UgzxL*Pa0#zKMBrD4x=MJn^aAuEk zOlJwO>-1802G)(YHKu9zkTfmkzONYw24Ji~+L((VSfSbJo50Emm26WFu*di|dz*Ti zVtH4i-&-fJkK!uDRQFgyzj}Lt$>oS z{N}r5hF25k3B_~N)Ts5;X6+5`OEL8H9M|%I$Qr=rh4&MR{Pn9QtF9v~Sgiv*>H#XPG4@c!SAkEH27OIX;w}X={ zQIbaQpx2BK%pK?dZ`EBZQdD|tsf_elv~R3V4}8++TN*g-^xXt%H<+V;uQ6Y&QhE6X zLg>S22$y2K*x^zMf7Np3SW0?A#mb|er-*#fTXg_KV*Ma6SgP6Kk|RM%tC9S!QQwyi zyhyLp!lTgXZvQ&7>7xW+%8`8ZZ`mg5U4=1c0_x!r+#dZ_-dnuBPX5OM^(KMe+pL%$ z2sE2qUH&Mes*kgwdUXuq4EqJuvyex_`w!UuN#>x{_TXx}M8)sSjvecS{Ch9>CK5jy zkjOeydh$u7;kMs*=2P`*<<;?gce{Sc$Xn`3&DQGD>nW|i|6sh>qy37poP9QU!e=WG zBbKw9Ro?cfo1v@+I(I2cqf+JnoZJ;DQdi)Kd6cttZd@oI`r9Jwo8>)t$$XhUduxgy z58WU&i>*Wbtu0zJw3{Hl9^bjDXPS_Fr_2k@kRBrC@tGlKe8i$1S)nV<;-tG`=!n_GCotRdJeB_(fz)EC;g zjKA7VTgSFIBhP!eU`DZ+Zli%t3sgE);@{$mr+A-{ebqie){A%BH^*p|cFGOypKiVb zG4r|~X8$(pe*ZAu@40BDGV=86pe5VI$r_a6LGwi#`cCbRSPqc(Y5o~W9 zC9kVrK0SIY%?Q;Yi0C+dG<@Xv?O4$Vy|oWf%?J^cJd>oDU zHlg;2EO$nR%VHJLzMoSfcUHyjgl1)t>Q4vNrAJY^U1|*7?2jd^>F+{@P2I*aiT3jR ze!YA|0fd&5d><%mkv(Kly@Jz+EM1=bV1Y+IOU=)Uh`v<8rHazXG*7Ug0$7s@OrnS= zted<7&&al;d%0a5Dt-9qUfF*bI@%oEYwt{GqYIq{_JjJvk#+5s`mWn9hf*~^%;3d{ zqk5-bCmSA!49JU|E>Z1#p5!k<@#)^<4X6BYMV@l8#(-}PL5Lw=xrN;GW(HLzvJQbycO zL!~>cH_I?a81+*;f{vPHbOt)j>z#fTSnRMZ&>9e(Hbc)(mWerFs_#UlS=HelpAf2r zAJW;VEN9k#rS^75WM-fLO>^Fz!UxB=q?Irb;87K+V=r>bk*21h$2{eF&B)shu?Zi0qwm)!UEEy4Ngg5C{xzfA)x0w z>XO)_cqGqdj3miepwlsZ&6m365V;Oh5gUR@K~ zhg_$sdE~1U4PMYahJ*M_v`q-odn&fnfB*Ka^?&Eze$IONm(KUcm-CNqPWt}V`rj<$ z<@onxzp^{FK3y;WqGhAM<+F@uqw|YtF0|m}xoxRnXi5!)u%wx<_CAVC0d} zhdhL(v6jRrb0A<&b35^_vgchUHDL40y0PHnOUCntX@*WKoilhLgX4+3W$Bqb>3U^E z6^nrG?>`y?-PaHf{c-nm7d=LAZ16R0e5jXS5F2=n*aJ~V=8HLYl2I~Vn4>Sn;`-0A zQ2%GPQM5BjZ|g#HTNmnWt+qi?<=JquhAJl2QNFmalTaiB&;Lw=JQhXSSzYUSUatrI z&~uWT=zgdoJAF=_txV7CjiB{sm=p>)GNM>Y@QC_SFQE>Ay9`%Q_kr>HIuQp%8 z>+F4`np(~EQX`imdl*j|PgiSMXo0oa81nWAj5+~_*`B(@$nYmwzi7=j5CLfRc}8|_ zEM-7ciD~k+;!Go4>9eBESyIiv3W4Ib{0=nz=`1XjU1Z!bMh&7t3wXrVdcR0Xe*`Uv z3WUQo$h?ZQCGKN_MuVU(hXcRlq%bqObvUE3wdHU>vLPLG|mY)hJPbTrAbva zoa0wHM<825M_J@@HqY$KOIV%G0}^2)$%1!S$#cjE-)CnjH#hV>OYyaDv$S2Zj5N4R zrjFA?@!~XNz&+U#qQJ=-9YXDf|Gq$m_;Ia2k#=9KX?Odnv^y=(F{RS-{6C2l>zoz+ zNpWDRkb4=LKb4w8Bfl%5BQN6XVZub9aB`Gab*6OR_8r8oGo_8&3p&aE$$Ya%ksRjA zK%yiAlcJ?^OMTO=TkFSqx7J6NZml20XN-pMedH}$>u=^?1~lkp=#7;9Z~jH;ORTI# zf8@H9B|(EZFM1Z7uuGFmGkjCZ$TATuCE|3wUd`W1WP8-b*x%#KPxG1I0I+V2e!r=f zx$8gGBVtpX9HU-6SWsh=y+bB@&uJzb*- zbU=5_B<*%SOjJv$Ggg54uMFLRrgCzMe|Bzx)0af%gSsqF9PEX`JtQZT9g8|7 zbLv8B4xecf?5Q6^8ht~}+q0$V$e)?lj|4+o`!Y#Tb>L5LW6nU8AA(20 zSuCi>W@xfl?j5s|Z9ROO5I<2-uc#x6Y>z2u5s%Gnv5onC8n&TYTZw#c^1cB5^% z?G{^(?F!qa{9eZYY$Pk6vv}z(D}9SsRIIr1=EWucTNbUXvR!}Mic_viUUOZhSdvBA zHkT~+>7O%hU%GVhiqaczTeNJkl!;z1zU{`FmMxw^YN=(m6R)|K-MDn6>GJo8458$f z=7Rum-2bMQ@>Tu(n!X5n7zu{YnPjnc?}d}<)>T6m;#!C@Ss%)dhl=llQlF!)s=7;L z_rL{G2_I6ets_}yr0V*F*VXMA%bjX64H#3GF(WiH*lZ)>PmjEZDRdp_Q+9%8_n6cY z94?jMP3a$GF5s?*sfX~MKR+TjjB|9M;y$Zpm-_H(-Sr{p*{!ZqX^K>OMcbp2aSFj> zXq0*JS9T=pEL5khEM5KRTPw?Hdn}jAV0Q<`DjQ(FYJx>PUFH~{3@2X{hm)W3JEGQM zH+DGVi1INg`6z(AAk5!Y?BZjvfJ=MSwI~hDtqM-Jhfc)xN0{qHm@o%pf_i7F9*Yaj zf$-*2R`6WC*+1Y*s#p1ONwj&tX5}(QGP?w>`35%*jO&q?trO+>IQ+BdEO4_q7cbEkVaRGx zVTh+q1|OOH%ZjQc1T5&=)e`qY-r^_or)i>=uzS$61Xn>+)b1R#WhrP`LhdmhQ|uC@ z1g{|k85c8sS@<#D{|t~>%n=+CXxkGknG(Jr@OcwKr0Hr>*Kr`F@ga-PYdq1B36-d^ z+cVfhT|eS|u{L1glJIh)gkX5By&EZ>!P_M>Lpsw)>81g)H4+8Ov$gu=b>?;9Q#7njgHXtDI_)ry(L-gWV@4r###&0Htb5f zS5z7tFRS5_MOz}qMKe+W3p0MC;J=qZqc_{Cx70t`NUqeiBBND?3T4bhoYx%a`Blc% zaz-793R(L*+^B-h99>5-ejHdJzVVYpw?-P?oXC6S&Q%ah?Y|2CHW(zxcz(!!!ZeF6 zG%LdtoW4z@?ooLs)b?X)1B9cB|Dv67VxO}l>b%Z%+ruo3bWc^K*Uz|Bskx|YSaImT zboPpvYO4n+#e8wJT5cB$E{TJl*emOsDdern$VnC%wKB3tN7iFJD#Q8lzd3m&s?CQV zlPU9rNNT4h;Vlp-!T#{?Ip4;$`zlI(f@f3}BH<%xdIR+n zQzb+;Q{)Q40Lj7<3d|?&NfWIV+8I1o{hhmc?F$god&DODJU@w8Qy1&YVZ}8@CaP29 zS8nxqoF(__ERNyVtq>nGnj+ntu31c%$mFs=!J;sSB=X%WtXqkF(V|)m$>n0dr5j1- zG8E_yE*YiO-@pt=Sb!i#!3d(2xqxosvf9Z^k>}EC-<6Z>qkUTB03QA@doTR4rC%}j zvV)^!z<)txB~z{w>S+Pb&a1Apl%!2}j<;d#Z6hESR@7z@$k576)Kyh#4=w{*tM3GM zCKfbruCfKhjm36%mKhM9K|qqVgci{?*yb`=WVFQM06XOeP%b|UiYfoLEqFk+;x%Or z5QaY2K-tiW>~MI!-Mb!=qHeiVt8dLf2^59+n}kTnH59b>wP&BWyyL1Myo}%0p3#Ah z36+61p>7gU-%k~)g1o+R>dNCxRll;-314R%S#erLmmjNNrmq!OqZy*0DU4Kj5cr|49--l7N-%d zG7)PG0VwuxNlqkOh_zY*%3$UtDQ^$w#QoTU)ZLldN9Q~og5OgweuV5m$ki@!N=I?g zZM2HbMqPmqzR}PFp??u4965G^xy094<+|o_#`L5A29aSx;5Y>S`foC0?fFsdh*?CL}e#~`%Zcx(PpJ$jiYQ0aj*hX1ZdZti5Fu1LJri3IGSV{)mfHqpG=Yw-^HfR zL}J5}2}BU7nT0ki3dz*(G9q@MgUIa^(on|)Yve-QTkKT~Bx)tYJ%yzAICi>`KiPY! zo$iTpPOHl=Vkq49ngx`@G?6KXW&Z~QOLA?M6n02q`$>fn2sWEL)b!eQmtwIg?v=7o zT6%kvAjNeAb|!j6x#eP&E|hIO-7uX}ukUTa!6ac0w{mMI_>%b*zKo7&O<3+Z&#~ov z__bx_RqKh;%1ey5ql4sEoUm7uzCQadDui4whB~Tb|@Lr%Olv1f02@hO0~> z+3n&Y-GWk7P5B3BVi; zc!_qVzT6B7LWzA39|BB?B}HZ(b~Lowf#X-Y`euS2*_>T~8^U%__Hp@0X%ik~K}B#u zHE=e;1&caM#Hw!71~T)oG$sl6q3vX|mqp&gx%E5Pkb^2Qay+`Z(Z%18OcG%Jljo{= zF3K^quiF{kqwo|4JV*Tp4Ed`rgv2rEv!Z&e=%)vMOuk38AtxBnHm%bmWf`EwRuWk? z&$Oapa*!8voA2p%$cu_Oty=z6ME>0Ac5EX$3O$@t&>n^U2|KLL{un|p*?Juz9Lz+q z+TpHC;P)ALpoeDl;yH4mbtf~>IKxIl2QBP0nE%*OqColQPu@P3!Qoe zlV&Bd4Rnt;QN(tjU(PPCw0?LHqb%)u&XG#~3zDkKVz-dB$Y*wm#U6B=tlZ8}#y8Pn zM|P+`|^FmweD}%o53iT=*F^GF;Nfsm)r3Fi+SC$IMY=@Z*J>}fw zPEu%jZ^%TA7r@F{83x(DUYO@_)j6qjjHDe)e@v$wiL9=m?lB?$EfKF@^*hb-XR&Of z)kn5HOzjjj^<^ARzHFCCy-}^><~NWFEDl-XDDz`_bkyiGva@sEP!l-u%$OjFaWf7z zHQr+Ljl|`6R;g*}!;{rl5F2|OAZDV9l~4mrXT2cHIgLhU@|FaP7$9Y+Y)sjamDL@E zD=iM5=>C`zL9hvBK@sq7<_FGmFJ!ZU3{4)}yklwWdw8MT`QonCSe>@vBYsV;o#!9P zCCTyJ4X45>H(ncy;cvLY*?JyV78U2WKs9K2hJ{^mF23nyZQqxQ7-j5_u%l~v! zqu1s;FXS$b@iDjROG5;EeN~2fLY$%T*ca0an8(wFYzJ=6wUu`kPPEf6wedVo)H{Kp zEwtD00)qlK=i79#%)5#Qg`sA>>Nw?E++NI=L-Cpf&rb#@$*lM;w^ttycHEEzgT5QY zW{p9A&$dL^neG@iV;3soXxy}h>>v^B7-sauq4W7<*peAGe_j6}>rr3ereF@9o_LMFpR;R2n+_I=E%iY6lo;Y*ulQogq73@?f{LfBJUg&>4=?hrnaXmf zasm&h@AwZ*UY(t`exr24-M?|cyG2zjdwP2RJzd-_Te{$vdP}p%i;3GP-tSqWGx~L_ zF+ck{0(|BH^cqX@Ha$zVV4@Z8&)X!nJ>Q_n>hzF*zk1=)h%ROL_bv(QQj`hmGQri^ zoh9&C4ASZ>yi0?Pi)wTJG*?w}+Qnjh_4o_G4v4RuUU+667xSPJ$ik)u7l;OdB@>C~ z(v+FEsvDU0lcMZ17n~vp%q9@JL$wkUiC!(WZs3A1H;4aX6zYMnNS;Bu;F^WOjl$Rw zr|1dYnW4(|qT?V?t}q%Xm$w_zE{vv7bd8)d%!JBx1_5CP*C}gLN*D)z9|p+dY8_Rv z-Xwk@9+w2GhnKuwQ0}bq6PAo#N6_{YXGoQ%#+HYxpQ#Zv7jiHUGvCQoXQnMg!}2PF z6Mor>nlQO4eL|5=BC9U3R(#hwd>7%moZwH9SMZNyBIJ~phz{Ls+6n;Or zI#UK;T`gNVDtzJ47dQ0)p523}QHbR_uRU%3Kd1=eo3{Sf`b$#Udf{-y^Z)ihZ%X4i zsIr7ii~otHe@>kM8<)00q9yB1CN>VLGpt`RK#6gh1&Gj`=1hG{k95f&_e7f`o4h?7|JjPCiBT%JUNp{*CcY;&zhn=md|2phvO>R zqptg$Mh3>at?Tn|lUjt7P>aaVWn}ZB)fcfiO;Kf#Xnh}g48H@HSWp`9 z;nX-XoJo?tJ)Csjd=;9hP)XDw5ondfx5=l^s*Ha|S&rgoLDM=$7p^q-Nw~7VlB80U zBnL%Ff|s1ulSI`VC-E^eA6GjF0kK5G$HTuN9>Zir`i$B|^i-?$ZKBg3WVG|vbuyU~ zSi48|WGA!~gL>~Yj#a9!=t=l25rC`B)zQ?*vT;;0`~WCKnx=|)fb!45g2(wLF>QmK zeqsRDjJ!!LEg}&Ts4cV#o=kJ&>QRs6S48rw@xUr83znA3_+LYa$|KL#YQ_6V>KwS1 zWM=QG^8jVF4zzc>AT8Sd6uvxG5_;NP?@Y#zMM4XBidYWvnr*d8w!V3{jzMunAGjt` z>`1#@cE0yZIzPvw&iiLyBw27kU^<^=-n&qSMSJ3VTIy_gN@NSODqT-t@f(~Ndn9Bg zG;@dg%bzfz9Z_ShfC=wUw6a-l#B|u@C=c(@l9>k0q3v@ZUI#~enx${eC*miY4n~n#g{$&=0Ea*Lbjnb?P{YD$1?CQ~2`KBULxAx+sIIv`{8kZ_8f8|6h9Mw=?W z320!EiA=Tb#sggZPLXQsq39?{3~y?0Y)6Z4ROl6H(DZPM?yL3_@PbBP}#TWwrUa2QQ8)cBve%mpGR3$?fP*Ti*85{TbE zcADO{)i%j$puthGHiE5sfw-NZWCrykaLVV?KS;8_htQP3_DoN(;Q(Io zkun(%Vz~*wJlxdqjm>|?F`V(!YfXLI6JgBufk zNjw1q?c+m5w!}?IK#}vvGV(8g6qev0uLWoVlo^NnDaRlt5E7-+lC*o6w`S3#asZ2rGK{`@xP$2n4*9Tl}YB+B5C97n<^0H(_l6fI5HqImR z=7+IVbP0%~_&FQX)^c}YmQgTXv=aky-hMJM<~bkvoxDrrjx4nlsDv1kcY=QF*URGi ztUK0g8<`s-O;p}L+ktdZKREGN`rQX1@vB1EiKT~=nyzu<4XD~RTf&+Vs z6e!X(^yOk}vHL9b_C$tQ&jvt9#w;0JkBbn^1mB+krkX~A7d_tTCs#8*TFq!vOP<@W znh206W=*(LQqya?rU=eJW@V_gwLK8jRIme*BL(T<^Na$qW~1aetV;1I@;<1QJj6aN z>*1`E<-;wh|M%e*PJB%9?cPK7z&QQ?DXWW2%$yPlxJ$nb38g9fjadbM#FY@<1( zgs$@H;1KUmSOMEV8aSsMTQOlNk8F;0fOn`;JG}INa&0;&-bqx$mi`cyUXa(Z2}-ArVh+c2MG#p_^10>=-6qB zHuQiu#%iw&x^vZGNWNfB)NuY15FwVfOnjqr{p-=lxYX&L+at(9E~_R1RAq#jU{4uo!MthX~8&jnE=Js zMZy_I;j+Ad^ifn4>J7}rtgdr8_MnvNxP%`HZteSKM$J5T_SzRoNV5;~2Ylc$^_~~E z)KXfpl-B0qBPzQz)xi|utj*wEK`HIX+bm=ICq?BUC&?@zCzT3W!qL9hbhP(f z7TVDc&&3~SJxc_iOw_m30rk!4z_3Xc*QOWHX>##+b)Q^sP~L&h*0}dD-7pj3R$>{*vE=3Y*Qa|JEtvXHPV0^ zz_u}_FPLK_+R3IrNQ1Vt4YDxG(TCB;^rf;E%urOLXB>V_`^akAzH-30y-0rI!(#lh zm*RyuiUf|?8^_ey=Y~hCRXhf|-M#WUrW;2aCYk75i%e|jLCI@h`%ZM`HVJl4Idz@B zSL>ItuxjTx$+A2xb^=S(seVQn76QW=#+Bu2 zJ+CXVPL-Lmg7CbModl=#to5va2lP*bo8t*&F2!<{SD3walQ8KEYW=QqRV2>?p7FZ+ zW|63M%m&K687=$^^3W*FjI7+{G=A06}&4MLh_X|Rq89CUEjXWcv|f~I&Tf1B#I zN6r5*b{t}8d+y^t8JcEUo#qIg%omJW7(Ws;cWrEx!X^=BpAYtQ+U6mas3QxcAZtT* zhaPOCUwMr~5IA+2oO(}a`PFdecW#uom;a1hv%Z(44yqgA31+C@N>z2~>V{@Mxi~7Y zkW3o8NEd{klp#Ntc5y4@-kc zdqcy(HqEd+Jkn!37?mk_K=Zq{NndYV7SGtmsu-t-NXO+BJMQ7i`*% zC#5qHRoKwdSC@y(cLEoRPn?=!^E&Xo(r**SBdQ+U~qEG(9y6KJHT-NVqlXbHx zdQ-evtS8gfFMzIC1@4O$5F zurFTVaI}E%rLh_`P>eamPBh{Ybum~3p;&%M6FV!y+eQxYW%`J+{>3ZS#EMM2ZOQE`ZoN@@Ph;h} zZ)V&5@5I_PZx!Btn~!R3@i92*dNKD`&_?;q-o=aj%Wk=C>CD>~5s_k!*__3<-tJp$ zK2lsS?>OzYTYR_Nxa^i6EcUFp{but{fzP+%mYe*(#d=g3hvkbH@6+6;0<(Xoxu>7i zB++8%^+qCF^ByZsz`88Uw+?J|tx3~&)y8=`dqS$lV!bKTvhcyd2%BJWU#cNmXs3F1 z2kQlTJJJb`jnJu1XdcYU4Y49!k5a^Zvbo#oAOgnaMsEEh)=(XdiuTqS{QY6@n$!Ru zGL@G`Ph|LbT7(!6j||@_yvEGF1=@)JLk@^t?Z|#LDDZ8d9l0|oh0o=(a8h75opD8; zliFZy#396EDR}Ws)46rc50BmB&3_WB)P`P)dTscwc+?Yj3X=Bt@CDRS6@A?M z>0(%#mk8RKuD}zS)Ge`B10ROjGrzv;7PLrb^#1Tx-obp6x?c76+kKHYSOJ?i&$V4Z zB-B->{2imOTx^?f%i>!(C9-Vio$$W`+e-eo*tWvv!{y94(Q~RnOL%IU-L}@gv==)(yoD-zqZi;H62HFS7|TPg+epBC}8QbMY#$9Bpc3^A+E`QPvq64)lw&`uRFe^ewC?oQUMh==WbHfUd9#`vLeJc~vt*(wWiW89f={{i(bwifW=s#1fxE>vvya>~Z(V8{% zGUH%zkA#Y-x2rgr;hlZ6CO2mKrkzX>{s%HJ<|*W_1PDO6`qgR_4!waLSsNm202t#n zTIB}sGOp7Tvft@Ze@477S6}*tP=IB?K#mSM3zr1e93SXAt8So%uB~1bu}G&q+s5>l zdrJx8J>eJ9um64dAH0$vC1 zLs)H8E{6|eD<3rgZWZS=LYri`v@=Dc2LW$@`V}%}V2Q^jnZW;2&g-dGvQ(O{5B^@@ z&Sf_L<=X4ZXk4UzSdB`e$y7-!&phHrB{7iI-l0_zLyTb_@*dA|VL+WeBeK#Img0d5 zW-VW-zx{&^ZrTyEf~%Ju*{D;_p=l{u*z|;aKW+h6nL#B8Uzvt`8OwPHGFXRuO@c8L z%Vv7JKA{!@rm-fWUE+=iuSoD;p7Zu5{bfv3J!ytV8KtDDYu?^RwU)C2MyxnQ5%6k& ztm#5IZ=1!m@Xi&`j<-AX4`>mg1e*kskf~-C44a|dA0n$TDn&#-}?ywR+v$ipnBzGwWt$ zHC2>@Zm1#@Szzs)$)!cUo3v%-a>G*ryxsK%P(-Cg3?<(DfmdD9{{pTVbDVjv`L84l zG+$k|k?{+U3wbJxff$+2muZ;>SYlC7QYUX3D0!0y>*X{>qMR@HhB%li=xBl$%0=A3k!; z2wGb^Iu{Mzy?OJ3ri(6HHR6p~KmEFK+b@bHT&77rr(3Kq|3Ashc{kJXe={@Z-+o8v z{)bFEnK^ac7Cy&GnK_|~W}wySGjCqLN$AZfnKwlhfzvc+M`wz7|0@sfvT`W6^WhiV zrL8uAAIIBopAv=iHjVcp_wa{q~K%D6BD6mXw`nP~M6d#T`6l*or+;^df(=#R) zIDBW|SEq))&1r7>gsU*X)uj@xI>;bs=}vNEHn5BC%mCu;*K1`RXxuOYPl^Nqrag(8 zh~P7MwQ54^ff#2IoHYd%Rf-b@JM599oK_!StlUV23Rs{4Nbqr`muknP9reeYT11UF$RYyP1wLoI1^i zw^HR$9R26NbDL9`)FAqIG>nA3Um01RZ!FLC5QDAGdYOK8)Xwi3jax#LI6&WWL#1QN z0v+}0iz0CemBXY8>sfZwnsl3(yYdP$*4jG?(m@(>jQ)aboA@22KP`jpKf@Rb7}bh| zO;_Ufm-pVkFoc9^?M9N3CuZD~*(8^r9V(Gr zc;aNxIU4Lcdoy!5!GQkHbmR^7UkK;_+OLpFYdEpaBC0O0xW}Iync2fpVm%VbZpIck zI|688Z^H{9$!<#0!QC`^C5@_PcnrM=g#gsq)p^29L?&faAVUnd!`QO7MNYNxwa)&S zTsO*+wwS>R4~0jX1^m?T~g;H$(&XW*+OfBGZ$2jr&y2o5%X zsIqunTcdS#CUjqj-^XDGvmhcKECN77TvC7IQj~REbzOhf5&yO_dpIq0M?$}pLj&d1 z^M}Er2RxYh&1s8{XP|pgT(q%*U!KHWjp)QD3Hx}kv-nBJMKt)cMtq`N12MxEKM3&4 zgSr>XclSl=(rZEuPks5T=7y(kUU};Qe_f#AphIU$98e6-nYgbPO)~2`!)X8_#Kxr z__giy+=3VsR?eI%=H2UBz*>Bsu@krN4wqIVn=M7RFRz{&$g&A;PjtOtIVN4CV_bq1 zXB|e18jks0B|<2sk=ZD1!y|M+?5X$nuv3>qsL3_O{;YGUk#%&6iqF(M5p0g^#ZH^| zMM97PdPi-}V1Z<-e)r9>h&n$-Z!fI`A4);>@hg2=m2{50n>Z({O@GpAk_jbS>K8E% zjr>cff2#hH7i3JVx1B|&@RAxtuc9k+e@Xw9NjU+h$7Vz?%?ZGoudZT{10B07CPTY>(Qol%cZm&)eFemky=Rr#=Myj7UN9`9!R0Q!i1!Y$s9~L#2gHx540PU z|Krm~K@yV>hW!X81Pkm6IX0r6vqwcBuFGIA;OcjD@h8FqoZ7`-{XW*ky3E#}N$a-_ z#K~u04!M!K3puRRh#AKslXV1h+WJ4UfK{@-APYQgLx)^AJe~e(?BM3ynX?NIq^+0S zyy~z0F3%~H%VI>St57?ZQog4q=qK?;Ut-=-vXrZB6pn0bp#U>-1&LYo>H?s#1vaEX z1LW2)PjWco$jswN_a3gSZ`Nzxhc@+i@snmTE0Gp(Gf+4`0wdc ziyu_4JhFdg_Q?5y%%P{dhSt?N{hz*$r^U&{MHNhwM@^!?FiFgp)a6k#RwhDrQ~ zGnm?$01ITBjLK~QDFp+?4twzIyuH5UyGFDOD~#Y#)!TIS`TjE`}PGi1_lE&7*m7iHYB8MUa{EtzGy`wO~ zzU{R&T}=?hUV3v^%9JdheaZlTiaY$}tnlCUjX!Wh(-AyO&3+12dJGvw4U!3FOybT2a?pX24*%g+{sb%$oLY@ z{7G5-<;m2hT(BkmiN*(#1s&scgQRkJU7atBrns-BW-85GvvLM@a+1WYECP+k{$k$t z6?p)uvqeoQfZTaz>zU->HQM>!=VO#Xnpf zhkje^$vhmH>PA$$m^$aW0{E<7r#&Wn1deQQHn&x}_c` zU|S2Hq7%>O)5WK{WJ^8XGqx5!iFmW+^QmEa#&4<5;CDTrg0?n>PyBmrt>d=TV4SU-N(*5fk7fpu2MN%T`Kuj^G5pXvCP{b4z4s!A=nS+tsXrl)OarIfku9_3bL z`I5(evrdSHD4Ab6#+Xv`DDOeWwY*YY8hy^^8O5Oo1HTm>v%Br!I>JR(~ z*^9?hpRse?n{`QVedTq~gK_VZuWam%(zLj`{@!cj;w#dv%BpzP{$E9&lUL^2+0o|w zKlHk?5^Uc4=|+|M0>^ZEAFh>nm-4PP3{~A>JSFL|(UbS3&n*dU(ZJv3ENQtr*+E@P zCTEra+&EQS-&d&e&<1J16WSp6JT3E&sjQ`6M{1%MfG5n7x}s*Nfo|dLHV@R+mCc(k z1I_xO5l;fP3_m zspnZ;47jmaMaYyy?=17(Y31#|v~R8djDLDBtC0lksR!6I9<|2WIYQ4i=_~S=nI2=> zWiV|>-=JwmSw#?~VOe$1Qw?HS8IWbl$HG^|G1^xyVJ~>}MIgBb{kKSN*FUsG7;dao zk6e8$;!UT8x&*bnMw9p&M&>%T;#yu{`Las&zFaMK)zl#0R(dlT4`CY{E9&sit2V7S zJ#+%3;eYAqF7F6MO{0=V^V!x zK@o>pM7GliOx^2IGDL3%2Ft^dN2E^fr>)OIh+`culBF_Ox70P5OOXr27$3R7$6q}! zbtK?n)e4 z2anpPT!j?fKCUAl9u=Fe2_zS<%fBPR_v=ws8oFz7s30lfqJ}7YBdI$dFg!}MMs#1TE^Np|f;f5J0KFrX;7pBDDbHjP8sL92LeKVXq!5$!_}Rw@ zXOm>PpiUYc9uxUqK3sIE zmtLwh(39j$Me7_i$5pS-@VH2dk>b7oHA%s7_H?N|@;y?brK*2Y1GsJ()*HA0H<^63 z|E)))M>$8r1B5`v;qi}xljImT`~R4= zVmqO4Uj%cF4z7-%^AOeV@vQvz_XPE8Q+uddW|1Og%6kdeU&%n?3=Ko8^1^AIwl9 zYh(1jVQ!4-*k#!mRtuL%PsT_ydUMnx%Evdyo*(mz&2gJ-j=k3AcmoxFO~{vlC|dt% zGo6X7V{?4T=18nmAEJ1TZjN$uYh+i-7LctmUG~M7A^QS0#%_*_*v9ah?fCCEP~$Wl z#u1r~F)aR`*2d^P&Bkc_NH)fPMxfuu_;sGFJYZ+Pb7Kr-TB=mHkb~IX(A+K>f3J;D zCjKPYa*kB0N0IS$XMF=%JC%qmv}$?n8#B|(jT(}EiB>DG$3H^7%aK(#qBb}|PabkeoYV*yYQa>MccQ)RaIsGU)~7ly(%i^ zi+q%YC5aY@7CtUwiDKlvl7c;n=w*72Qi)=hJ8?MOvbQxkWv_9{W~|Y4dMJp2mMK0` zQd26bO_z$&6qTR%|6Tj+bMAvj+5BfdliahPYp=cb+H0@1_Sy&%8&n;hsMa|5F1?^U zx^#yWZr;3O5(4-p=9ERIUF+PttP$No-Q?U`)T1PIOmUbyy4sYOQIeb@ojM0~!WA$E zU}NcFXJhA_@uVS~D7#`7nN?xlA%&i?9TrBxj|KADva@6^wup>e_c3i36S>LfxG}kH zwQG5XUJZL3j>z5F;S^m)$ZbsiinK{!e0VT=mId&B1*`wk0ogX!f^&O*N-xg|D(_wv z=co)W%L;N-1W%WLY!AHAko7tSZ$Kn5T|G)LHhFziBYB1n9)FrPygKNz38(7FuW9co zEX^}r7KN2;wYx(~wkDQ!p8)FozAR{JdGGR|vhGvM!qdU+e}xiTcMUJLL_wD!BYeUG z;W*Amxx)y5&|$@}l~@57sX!9UXecX(L%&oUl!kmL$|&pxyWg)EGLXpI;CI)(4M01B z2c&H9JiyJq7<)=)tQ1upep&jd!#yic)ghWsCPXFt-;$Nho`JrQOlfuMR>x@?P$dnh zGO?^%y0c<&-GWeT)qAVMP1DQG(AadFUKTMW_1psOsdy2@n&6F%lFcB;Wl>AQ0QSNV z*lPea9-y~qf|I74wd(jpIss143lIt6fijY|#rSavJZXmwS6q9uomc7WAOY$Qtb?tz z4l*r^zJ+crGp@{xYgbqXmc?DzYAQO|y^lo2igS*Z!HX*~ctQkX#HgoGTIxv%sE)YI zwKxa{L-0K)YZN(7M@KBs@fX-`zbzf=?ZG)B+p001sow zxuhL4HR@PAmCzAmpu<7b;iyc^SGu7R2;_54AiK$YACA2UJ3_u{MsB_mflo(GFo@*` zVjEk}hge|w^`VCVVj1O^Ia4Q<)njy0G2tagkP7M8y`%zwytE=y*}?9;URtT}Bb0s| zH4(rCQH*PGut6>yL7*9qAtIPr(CKx6ArJ?U6i724BN;EcajF4OtZ_8KqEXER3{68M z=*GOUTfS<^S9<3wkzjAM({uW1_*3+Q`)r-j&pIvJGwe}_D4a5}8^N-MBXkA;6vwtV z4nu2cpY2{o*m9h`U{No2sW-Pwa?+kuBTli2K<9g8$C;^(%=AFmK&2_W9>S2 zZnf2Hvf<9X44L7%899vb-&L>h;Nq*z6G9{cECbMFtyHc)+5i*5QBJP;3E(KLl)t+ z?MS%Qw)BuLWiJ`cVfFtt9+Gs$r3{))-?P!ipBs*^f#RFrT#DF0Bx zUCs(5LeYSKVODcFxAV_;_-CZcNe8bi_6q-uQJqKl4~xr*%h;YQt{Zh!$J*Gs1+?$R zVP+!Ksz%&WE`JbleF@c}%2(J7u*;y~krCxw3+ zczTe3c7ms}`vsoNrL@0Ocy~K~p0y!OSOHGP% z6DErgeN7ug4JAbNAVgijGL6>Vud_7%!7;OvCE){@dAuFWWP3?yJwQkJc|k&oErz|q zQ$Q`8iWD1O{z8iCqPSd2dK|1wheI@yvh_z0`JSH&x>BYO6{I!X#%9guD1%i9ep`Gf zjo}9B)*bMot_^)Ef#;Hg-Pc(MB&!9Z``U=Xs|8pIEj;8-1 z+kEb0jcta(Q&-)}mmu478R3Vs><(Ci&Nw%qq}Y;r0$ySc{|)2JH=6ThoD(@XY%0$b zjB^}5ewT4>=Ctff^=o;G?{vMO(Yww*<8?B(^%rD5)W+_;$CrcR>a3WeUHkMY>Htj| z2VF73K+;dB;m1KGZ{A+yoi}}tHtPFu(C$bC2aV%-g1)2i@w@cx(pe_oX^2fc#8Z3` zb|+7X>l9(*?=}b;xAO(IUf%1)R;R4=rUV0Dn^6Y?(^+XUa{gOZ8f>%nOJ=4s~@&TgNdeFd^l*VAgwqX>v>lj4r(?qcJCf9#yaPq zm+^6Me>)YGd^u@KMp8-s5vlP`qdBx>NR3vc0@KrYreJ>8;6r16 z)QKTA(g$t%>+m;=mBU2KF};a@KEywP=?eaNH~)k*w38~OV}aLEx>ssE3oAu?Qsbdr zI(9q2j>hv|yx73a8Pp)$7*b=2H}5F&h$1<%ATQdtXBmz%Ed7hxi zKKRfmvJ*Vra@-G3+5FSM(`5eH37+=BP|5M+D>ZKT%!{Pi9h1<7czVG=(>~O}cyv~m zi5wqR#}Pzl5TYiugH4<8?^EOUGv>n{d zQ$Q`8ib!g_ku$vQoQj0hxRX8%sgcu_pVas=8B({!38|5W;v+RaxYLWeHmlE1YD~cx zgzWJgD*5uff!?eo$U1KdJ33Tv+K1?yYQB=&7!Ljri18ppe`&!s3#fMq1N-B)3CwD+%CYUde5JjTd8`bFqc-2FmuJ zk}nsV?ag`*S?5h*aYlU~F813XPGPP1W1M||#>ekc*w`jN>?QC|1AG1Pc|O>C5mr6H zyu6az(rO)RBGTOj?8iz1jb#Et%?!5|W#AD#>y$MH4mKY7OD@N)!LCS4wzsB5$zs*0 zm&1Canrd?)KosQQ@r)P4wn(zlNOKm`4c)DB~&pxZrKpEi$rTk+KO5>*( zR5pnWn|KfA(r1w1a#Gc-0`e(BjCACvEz3Qj_*$Cang{RJY{sBAg{v+3Vdd9wWg>~o z@M4&4L&OQK3cjv|pYvRJdW@9A#-;~JqpF?FXnDN(J%l80CTE5+CxT=HSe~ARrV!rT zGZwwB(?;CI@j4C1%2Mi0`z0Ok)k@O99K=`u`vUPez|Uf4eU>T zTXI-o4E%T5CCGvGQi17KOe6NYNNCQZ*y3&6$=4mtLaC5R3HQ!5tLx|6%91S|wsM8h zik%AStrW%;n3~`uHW|>ML&v$GC1H+p7c7lui6~ZMLM%`d-c!@*jQvoh?Ibr8MzHw+ zCx@KM9Mx(0ihQJSEG$9Rqdag&Jv}&rhzc6E!X3BQncU({+${FpW~!K3=g}|Rk=L+l ztz+Tns0uBQrIyJ>WJLo=2AQVq;xBN?zmL0x{~64De$+-Nh1t-Zh~O86V*$?z0_tSp zT>8_(VLL+?IuR>GgAGm%LGovC<>qSlr+`ndcR1`5Fw$L?&7MHFkHTgT4a>f zmLJ=qs!RKtF6%{cQ}4WUJmc3G1~wxg&xFRsaATt$8!J+FCSg>O0~8w$zk7L zK+p_EqtxP!saDHUT%p3-BCx?RGHYqx5ON&*h?k_@hh6s(RU+qYH?D^9#&J7BG~NYm z6o;xcZi5qChT@vz8^Y?x6tEvbId5WMn6g{(hZBQljD_0-Zd-y&#`xT;)TX(CeTcF& z&Dm6kPxA_WUiSyg^C5JBp0a*IPib0Drvbj`NjD2m>#(btqANy~&{aqMSkZxJ*iPV> zuTHXyg1yyp5}{vYNz!hwO1L;O>_Y;<&pf0J+tX`*2UULkpq(mcxUPfpTicd5zlVFH zP&=0_4H|2wpbxI;!R6gc&dimi%=v^0~cvOeNe z?J%TZs{l7FyxbPu!v1nmkV!DgDFsJ<#-n2FlWv+9my}enpC|lBPZ(UVlP9dv6S@~{ z;|b4+1R0@$($tzt7UHN+j&7k};g0%<=o$oOsJi^t`w$@t{$97-jOb4Id+R+s2G!-a z7u~Meua`I7?RU`RuLdE$GKDVM@G_mqRy~b>;mXvXt$ZJwY8-3nLzK(clWj||sc|R# zu2RoR^#%Rmdt_tZ4HaYQ&32(Ay`7WDa;a)!<7yNo9Lg7zhmXY*d&zmh(ii-S$+*i= z%fW7fgV|KIm7aD`oGa0>i=SEX4zp%PQ=G3M5nHy|xd&J+h@&o*Rg}o?(K~*`#Y<^g z2}HU9<-yx%Il|;3PUbcXT;?CLu>r~O?}G&naWw{FLDGswA4fnF;7W^bOyO-xF`f;) z?eP}SP$7XuS2+qkL|Zi+GP-4w0_Kt)*BIa({qY9NuwGz~c^tJVuh=oBJ{sZ;v97Z{LGo)09}P9VAD&p|Rkha@g#6&(Z!C#1;; zgoN^ZAo&1O-w{qQ{eK20Pp#rO(Pj(;qZ!9-o(-h!U@$boyI=~05N!HWB2_059Gt1A z#HMfxl%gCiTC5&rUMy|5Q$q1y4E~E!`C7_QB9ti>)k$UC!oNC;?RyWzr}e0H2kuJR zByRFL*VEXPmp2u3&M7#LkkA@<#D3HhJYv)b;1R$2^N6ju-9pZJQg8MqN@_eJg{met z)^x}t;x09K#IQ&H5Ra(GH2Cp|sd~rl^N3vZEqH|X>YI)ImSpgWlUVhD`FjolmHr@Wn7(v5&ySD>H^FQxcUKqZ_k)SO)okh=sj2npg%|s?LXHOfNN9 z2K<@5EMpNqbe3@~$`~wT@H;xoNb<4_i(na%%Dmyqyb*51nrokHeACHVt@(3nb$IMfHK01lGb2~_YK|1;}WStFo|SL{Ot69H75iD*zI za;Qf8Ko!7ENG9!woBZ|9ag*bJ7f>ZC_R+p8TxTfpP{M*e=nMsRr;{Oqsi-d6(|Yd0 z#?>(^QDz|Ug_n~k?{>mT)?<$o;yrxj=}S#yZ{rVyWJf%NKJG|343F#37S+O@L>5Hs za0R}w?xBw4!TeeAe(XV{lZ+UnBtp{t?J~Oe981D3!Z3*Q+xf^e+d$ypS3}XN;8zd7 z2Yz+hpI`OpZ}6)#-E@AXP}Ri7T^;hPf?)=~k{|wa{Ob9BqT}}Y)!SIN0sP83(%@I= zfb4hp)$I}I$FE*~J%C>k!IN+^10v3FWyXk(_*HB8pW#=3LwpG#;&jNb;t?~*;8zRQ z>ilYKyZkC%ndi$H0;HTDI^hhv{v2nx?=?TpK&(ji;aBm%ojL^=?C--F0{GPpoj{fR z=b-xHRRL9;V(;IUUjeG&94cSl9>A|Qcfzk;`E&egk`5K|_V)PIe8lqc;aC5k1facd zcfz**FG^!uHrABD7gpGUI}Huiyz=xQq0G9WJUtjcGjYRcsw+LDJaW|Dv7bm+mzLDMh4}M~?kO{yEtqU6O`>hSH~WL3{aO$yq_uQueFwU%lWWk3zq%~fyZJG`Nn}>#;wLZVA zsBITfKkXZEnl#wF1{?$;_Ra2WX~)lZBVh=C%Y)Q7@kW ze$TkOB9#!$b@wOLG0gy(Tk04Jnapt!d2lH^5zi+TQnYuCs@|#*04)Z4mxl{IdL9AEh|cP$QYZTGS?Iu56MllzNn1^Lzt^erb~WKG9aLejwNnL}@YW8>Z)#g!*M#Rg zmImvp@KEzcgz<$g+yPy91VTm!BXA{@;Za-}o{xyKooK@kllezjP?V!q9za*I5MDDpKP4|z`aFw8!DHXNu|h~;LvgR3 zE6GdIxy$)9{^d&YGEAl7T!BxnB;Su=6da*$l~t6;zNK>*;nv~erF13v3GhAADa*t< zG$lFWY&7&Gg5gT?(dZD>?u7D-%y*mo}3y*s5Pu8(ZR+RbkJChgj0OPx}JO!3hH`tswDK} z^b=z`hJ_*ykt(guk9ZMt=~8?^=|x}c&}}4$(NE~fFZ-J=h-rFq?0sA(3?bR8CojVX z^yHN1qZ8Kjw&&{!(lzO6Se6WseB)2M4v61teIP zUhTAigz|hK(e&i)Ln8F#=L^Yie-V&CPrgz>@?txXP@WGYnx4FUNQ9pJd?C3@gG8G# zUp+a|8q3B%K7yF)B#IMy@^$!0dh!zdZBI{5%SqRhQyH&z>#dit7PKDQ>d6nZp3!B6 zsP?w+YLTT1dahkfE^AD(>IR9v)E^nWaXzKFzp%Uuy^M&e0 z9V$&-&Up!-;=H7dx?DgNz*IDKdHYZab@};1wM{=~YU*;LA>)9@`N~;1+xqYo?SQB8 z7S%fX0hGH1!HHPvXopLmW zas^6i45fmqYR35v7|LT8`!bX@cl{xT(nj{UQ}4We*(2;8gP}-}Jqo%T%w!Wf{2kfj z#pd&7CKr|H%%mM9kj6oLWRFzp;JjszTUQwzq(j+b_kBJbV#zy5mu>q_Q+H4~BCl+1b<%w8)*FoNxB3%n62YVZ*R z4o3X%Jhvr_h4#X=|C&&j6dt5TJZh+Ai%hf6Tjid z_y?ZVkMX1y`ZXBpH*0ei4)h3v`RW^_48^rw3VYOBz6(c}>}>Y&3&Fe$TM>K4<0=Zy zQHpC*a+{=X9=VAvL0U))C8^f^s5qlA7~xP%^9aV9kcaS7t|bw8OO(U7dN^W91FT6b z9mM#m_!4E#8hNd#+5aGCO~P2$SA82}&p> zw;?%B8eWbV_$8;uOM`5zxhEFCn%Ur*78JyLa*ak*l7{kbV?ULTAYI9<3#oJ`B+m|# z5=x4K$I8P>ibBRC%w+}QSp8e8T<4k`6sB0~Lc$2RlH~Cc23D6~ZBXU?AuURAg?kX; ziOHR*+)@)o{AEBqM>hcu&Tb$EPwjv9fv*a;NpD|s;VrsVE7m%?&yQj6>G z1cbUfVf#$AE8!tz`%D|_9(l%-P~3ptLr$s1``woz*gXd3xeDC{0kmP>-l}jm0%-Hl z8v;;q*ir_`yHj$v$M7fS{)qx)8ArpfuGAS`dyiA7i`NQI-9` zLcGy<{eAaInli!BRDk#uc!tWZT0sLlid0*Mlm*4o{xjJyZ^#o`IuDed=-ZqiJY+`MFU^ zaE5TeCmWvgcU9oc5%?2XKf%EQZz!?T(2jx?Sa*W>N-Zb@L%nq;-ga^=Netz|&z7bj z44zu+s2@~$CakhPJS6lP>ajd4^yF5H99h;K%qPMfR@T>n3lP?p380-6xn;>GXeK$= zBaJ{?c%*r9VyNR>2$YL(elHA}mwK=`1~no*6X~5NHy#c-L5f4x`UK<%R%cEQB3H zXrdEvOUJKf@-65UL$C8SYpO&KNVA3A$uMUaaThz=joLZx*--Na%i-DVsyCnq7&8rO zj+ER;c>vzgk&oaF1hhcvN&XQ^&E+<^!%-(xj-a#yh%J+Q!~>3V0M{|PvD%;XB?x|q zh?Rm>!`D1%FWyn=#s0+$a7W6n&k8kia(C%_gsn;4D%HbEc;tF|b8sg6EAWdM6#fke zS&n3=)q1hJy-j@bjA)`{tV#L~djJBdA1g^QNrzN~pTS!K@+nUuHFrIm=HHx%ZXNG! zYpKx|>VF4#z=4h-3b%AfgXbsk&zu|`98tgiM}tPM?ySCQA#nEU;LKzj(VBO3T)(zA z^;eAUF>i}aPxH~aL78}nN~*^@EL){RK+}Qi!9*5=4A4rRfC|qO(5;JJY^t}B zziW-`sN&(kzJ=w4Jg+G*I8JGx61J{|6j2Dz=aCK~Fd%M*w4xB6)Vi7ieafv+4kdke z2ESTZ0{-GA3O#F}8EFw96UzEXrMMMA7vtDo>^EY?CTiU_h6C*-*O;VlG=v^e$vfi! zp>+@5GoNc`cb|ce@JNc6a|?cP#xED(Cc?diW9{tuFcOa;yq}cw>@2Sbn*OyL;=QCC5D#OvZrF z)apgpWF46&JaAQJU!K-t2uhcc!%ZuDekZ9>XoDb|kA^Zzf0WL~q+mbMNKrT`X-f=& z7e?UKLN$xf`&1(J7!Qb;H)kH+Ym{37&~-X|W+zTxylN?`=D5a%uoc+Ku;ZKpBMdoS zV{OU6(;pOAGZFqnJ-zjkF*Atc)cUCg90ZJeT0)l>w~RyaB?H}`u?(~WVDU%+c@0Ho zvm@Z}8ob%;wgz-k9GR0++)A9hm1QFVocu(i4ejz^E{%9iT6->r`yGKG7~KIv3xd>e z5kiD423Jo#3!3{J+ku$;q$hC-y9gAXJV^Q;v<)_l0_(j6dQgE-5=bCcN#8>9_=-J) zY=Er9VW=-@(6Z%7b0i0wou7b=h+4|p_-araEj4D|cG!_;)d=(4_ zMZm6tjiL7{tR*gt^@K2HcEWkxqzPoBp9nUkO4MQyzt+vnCQKj*Pmx=(H1r7Q|j$q;JN+FBlh&q-xL)TI1xwU{nuq@G(8G^0EMeU6(ecPpH0V>3<> zHKw+>gW+S*uV5&K!{M{B%u9{k{&`G{jZKIm^hJWlUxi;GEt}|~64f<3N;#E9La6AY z*OKpG!x}lh9o!Gi#ztVZ13|1Cl7Vt5mHO|C*C^0Nv(&9{q>V+3FZoIYY^2#ZgO{DC z3(7`BN%1B3DM>X+JtlGQ0kPT|p8-AD*biTU(2@=V-9&gN*dhAPn}@wZ-zkVo$$gd= zTj=7=vc7!5!CDiCeJK|#3>+&A6z%@OxVVHdBa%IKCPA3|I~Lzq@DaJ5VRV(kC=4bl z_MwZh5ejN`KJK>Hh<$1ZOgMKeidrbHn#W6BG3&Xz#(^LDH+fcUb&* zzi83kZi`QPTWo$z-`Uz}QG=@0Zwuj@AE27PFlFY7HvwW!T1HX z>{_GlA=;*7X|pL2!iqSru;lsdOPJPP>>Y1AX009Cmn=i-QM?1C8(8xze|+l^`8aeZUjfnNa| zlgXp;2W?~eINaEn4x9yV_1T!<+-_`4*I%UXM0{f^H$MG0rdJC(&tU-E31?G-F<&{jkVcw@wy@) zM=5Se-3_GNhaFRmV+Hu5B-^#4S(BZ?yiQmIOPr1z_zg>;N}PKnAu@`kQc`kPT!FrV zs>Rt|nN6D#0qe{xJ04wRpJ`K|HqRllNk4?)&EqouijlW!XLziQ7{^(Uw7_xpoOF*3 z_HONHh&{F^osRHHheL3uQ1!Tbv^s`%UC#kWOE?zMhxN4R=!qV7EgGpYh2y8Yi|0TV zyAIzuj$Jsi$Dj#1d;&9QB@DY6VnbKw;Ye9*R3|aP*n{;0WggGw2g(m0;Y%8?bf+Vpye)kH7ky9!LYo%+wsAT(Z$^9GG5Q=V z$9UU(N^8?SI6tK~KQ?0%KgLg%Ul6+XcXqV=>8LTdX<9QKA1(Lefyp*oI2|n~#(?Db z4qkVV7(xrH#oxdkoC3D;^Bst2vA5gLog5>L6q+jE0a5d74Xuay+46Ia+}$>N;oNMt z0L-y)WHy#X0e<=I;o0mLOuBx!%w|8H()Mr!bMFBiGd&!yi4Wp%nTGX(lZp8ZwL_=L zSSXv>9OE<0g?9^#!{xEk_V(~^$d`lmaB;XKptMb350(U%b+L!EvU0wG^TVaSflue) zg;A{eg-}1!yHNlG2QP}Y&%?N*A^^INkCSUO^$olyRSlg2y;U zU)ovd0d$g!^JT6$UmpKl= zPZ=bAXB;rIy(QkE601-`J7DIg#7XrmNrxDCqIaZEYvE~Ysm#H2wNTIm~Yp3zT{SMM*IO=1Z^$-eEn4MkseGyaIe*_ zct(VnrrC)n-f{A4-iQ9^OVPrwJiTrSZR zXvD2cH2?lmqwpHdq$MPpUvXopBZ)9lUX>Ni<84 z6ClytNl9FynMc($iDoun6%tK?HX0$(NP9qQLZVr*VkG<_vC^~`XXQu)VF3fnVq@PD z=c{Pk1~EzCw6opxB7lw&+DUo9mhL38fM_}|$J_i4H(hhmsc<;NZz(7p5{*DGHHX7v zEc@F*gN|D9#4qj^_Tk;U`S4j!`&GG)7k6dI|5`u#EZWC+{Sa%UXx~uV?ZEQ$(j7$Z z81!soXV!}04qSfjDM+7-doMq?41X6!F8^sY@Z%0&{?jXjCj(+?F_OK9<_vMgXw9y- zW?o)RwY9bu_zqaBjzgihI+yi;g1=(F5NrH&F`)osNQ-gQ8_SqvLX=zREw{(FTs$6| zj44<*3Qo!@ut~4iBHlcPi8IkN75w0r?5+ANs)CI)0%Wkn=N4c#A+DcHk4cm7v$1XT zO}g-Yj+S$Hl&2PU9Cf?nt3j1tg@?p&V~#uQKeg5kMJFc=T_#^bMf+0GSamxrOl0^W zs}Hv`xx+T`f@wobq*%5Ao1hqFPXZyc!IM(lAoul54=svPyP4k$q9^Nd+Bgo^6l~VU z`|xCFrZ?nIU<_4!^4`23CCGOh{1R$1|M$}9`xW4VQ#i~fo@=T7DBgZlZq@bdDQX`< zfUd!zA&YHA8#z_(UkYOjl1BrBQ_%}HZ}luJ!bv+)zmWT<;6c|u?Bsp}{2LHp0pVxJ zcuX%^#F$rAq*h8_63Q*9zYxkRrQKBPkV2$3nxLhSGdhlM;tBr?9MALu`LBn7I9 zn1YrufN(lNs4pJ8&!jJ&vwICdbLfH>77zKD*w~HKtIy(jgueeLi>Js7!U4G2>x<_? zn$m7+w{mM_SrFbO_Jq5mxmIDuMnKZuBKjAQj_HFibNjs|}z>tX!gj2yUt>D1jz13a@KC9@vS zC11M#AgvmuR+E(_KIBhQ9*$r7r>}T z+b{dbr|^$`$(A5?FTF5yc&ig(KZo}KNjHdJ1#1%w?YPk64oWY%I$k=1i>WtDBgQR| z29H||HZ`Nxn3T5{b2fDi#OM!#La?@?@nCn5yUPcp`o+&+JZzs{9&Rs10LMxsxgJ>d zz9|jYv38hCDXbh!I*yiX^W$`ml9oAGyt(uwemYpRbbW?2$-&~J%N#5U4>Yh)vr|Eh z6udR<+=()<+~L#Y_|(!^g}>3q8u8+W>10)!+4(k4Pius@fnv>6tdT4@C#zuQA{`lC zXm)&a&Qag$_%t}W219NvK`MVxTQb^>ci-z^H%K=+SU1UTQ3>ys18G)rcjgnn!?C};XL~)-|R@rMoh=}!ia*=JUhQ|HSjH}c4Bn7Yw|_wi1`c@%N*7W%XR)i&uw*Hc5Rb9YAFt|=MlJ)dI4K#SN~Ds3 z|Mw>~REC8guUFi9>q6748`3XJ#<=P46<1EP;-_iW^r@3(OtzW;d_5r{ayRh_*jJq% zjnnsJ?|%k01b-Q=FMvTv#(X;)SV#}dcV$bM zYqXR6NbGDV<>d%5BV0%r=FJ(QC13qtSw^V7o}&R+QU$978nBA-+}mP=|IVq>*Kb|G z`u!Y$i`7Z$dkm#$9ELI;)#>gTPEp!W`mmpO8i>u5`1+zlFeEw1Kyp`B%d;u+n!CYS zQ52aPMvgcOy0VSljA|}aX+uzBxkzQ+JUKWt$unh0jU3|MH=!hj7IqL8b|e;d?{SOe zM+$@IsHc+lUN|czdH`_*_pRzN_m8mO-%iVv#Y@?=1jakqRZ{m1>0EjE5T) zhbhG|?#tkV(O*5d{2N*g?m_tKhObX)*}J=!9)2K{KkE2R>+(-aFop@`K`{7+xL0Zr zB~>H`fjL6^T}qK5*}Kb#yFzyfLEgeX|CBHjhiZ-A(JH~zDtYwU8A68pPK#R2E(JYk zn^657oVj*1FLz@W_`C?ej{A8ZT-mvM0pD_RtB5fIfL`ndZ|1vNrn?`p;Y|=1a@6fg z_>fPqM=7?@)a?=;B*ICAq~`IM=UJE>dcBdP=Hf_b@FBv{Vj}IGa3x5@gQj zB_sr2OdhEH+{a#9N_$HrDt2W%KGAXE{sbDln$iO&$i_=$6 z77w7bmAUMGzA}dvl%PNDV8!T}AXHMq1(%3m%{w3+n>5rVUjx)#0I1rcE{@fppb!p* zp=GadkdhmtVeE)P>#`3G1}Nfk!hLo&nZEzHoNylJk1<||o|+Gc==_n}AP=##$7+a< z>0x3rV!_d*EC{x(21p4jk>evJ=u=S$tnsP1@OEt~bovdHpGE*hd>&lZSejrl8C^yZ z_t%ei{&`&k@+?`#QTEp>I<9syAkU}TVZSWhQW`@ZZjr3+2O42)E(thT4z+2R({x~p zuY{z-`daA8PS)s@G7G-z;NfY?AQXaE)~DKh;{216YteoqKCUXq>dT}mxi2)>8_{lynHFkRLLY0ug$!CCc$=Y> z(9Y;0G<1@0Vs*ZqbQtTG-ZU?}l}}7Z^HPCf@_Cs_Y>E~MHb&TvX{lr}Vs0dbY>O3c zUSds$PGKmXAWeljLaW7-L~aO8G!ZnzLA5p?e*#DXCk z-zj3B>X>W0F0=w~1{CmV;PIffMZ!1$ifyL>Uf@o@28h+E=`r>-4(S24I2ISzqa2E&8e1nuiHbR;cup45D9X8eBQSK2HIY)c ze?VNL=RwlrAefnOz971=u}5wOVzSs*6N61dwgQVZg=WxYH@0b;P6ptF6toI-(>w`u zbLeAQYsRS<{*OjU)^ryq823c1CG7N32p0^v&jrheXytx+6A=l>7mGtD%P7v}+uJ=h zq94w(?xkwtIMbp2{E2+-`t z{%1YjTM9hVDEMj~fPjBsMUJwH{S2q<^w8oEJU{{;V|ewwG6BPeEw@Gas0o?MGtKxH zZ{S*%;A!iHQ9xjHZR396U9BR?FqBJ%j&BAj&IS}zO_kq-hg6kk3=Q5gj}~k;+FWkb81#h`DqQ>Xm#%^@7Y! zavVt7o064iE+wnRo}ZPE>XDOT3zfU8P6AWqU^b3JbJu(3kMPVN?%6(UzNA0t|CxVzc4>ii8Pm!T1NEat6WcarJvWO zZe5sA9$9j_D{R@ZZWK3VCGF~7INyjhuj3*7cA)9@~2tp-{`Wzyb| z>YfK1$u;m~T4;&XOSMJ1V@k&25nPXxMlvyV&w^(483Ht#BS#*j@{C4=BSO5~qHoyh zN}aA6hXFPy$b!tJ2f!ay8+i*yU-%3))VK{P3DYB~8`rofbLortE(|U-f%Y^U--kmk zFq_I}LLQo`b=P0TGj=h_?ue4)C^=|KT59Ej-#`$icnG^WRJRQ#FV@=8F!>aY?}SMe ze>c%OPi?{5)+U@)TMFyCU8Rn(PE zPICC3w`p7&Hh@PCc25p84q;jp&Y}vsOaSGJDFbZc-$0ZPo9M&tK(^RTKfVKlrx)4W zm(wczc&^|J^sxXIE7I^OvjWtq_3Eq!_6l0%Od*HrfGJ=Oxc)9szj0y;*W;}rP=<3* zz*XsCN80XdAbZzsF~GT!z`^Sm*U=uwWxX2d7*~WQP%qf#Y^*=RdaG~%uuxbLFwT`Y z5J2LBbMQsTX-DE}!EiaG|C&RP>Tm|iTYm$9ZMOwxyQE{m>BfLO?{>qk3CQvl;U)#- z`BWROXOTQL6&O1SEIyx0D@xJV^r(+`1=-sCGg}0yx^Dbu|H1%32@1#EgrQ37X=jXY2cml zZxyldfP5dU74QPzV)iuIDYjt#G~nj|kO8?(J*5=a15bv~*@rFv$UxJv+xTglE;Zu4 zb!$w&ic@vcQTE`^xH$z+@H~u~&JpZRB%Dlx((&Fbb}9#{{{uOyCu1KPfTaU4CAU5$ zx87Vzi-&!WI~AUc(4y|_OZ-x6b=!kGhV4W`7VGgaO)RMlFk!r^#q1;=2Wi@I+9OYP zw1COIg9MZ?m#)DNyiAUe|Ljqt>4yWGzMnU}ak^xwi=Sc8b?_&J73&cl3!3nJge3zm2+!#2CmY%c9Dm?@ z3wam|3{thzF{Dj^nha9MK`BWUxa=X!C%3sD0N)UK3D`fT_obXY%o} z>nMr!hoM6=sYGreh7T6r&2f7@l&lswEWC_n1SMY1DX|<0sWs-(hw+zQx~>i;S~T&d z_K+U~x6VYm_X?W36waF$k=sOnMIk*NOyTe|kTy8U7O~0ztuG=V~R|WpHsgkSemWilkIu2kO>M*qG_4Z1?N zQ=rI#*DxamB{zUdo&@re4#U$ocfXQbmk(Mg%l%r({SccVsdBI&VkCV(o ztdyi35an^B@0rTfPo=}}#=Cn5i$0~kV)TQL%1_lmq$ zk=J;74TX$MS3#G2v|csCNi5qntK#}Bbq}o9n(bOBT0NtqaA!SUNYrTn#&Z?B0!^#d zT4k+j^F z6y8sAl;-(#AUD_q+(+TsZ)z171HCDEgnUow&L-mePs4a{|N3)I-^vF1tZ^3MU#Rp= zt4Ze#4yF#YQ_2}?jo{l4xWZz97%m+@GGQca}fx` z#)jjAE=|)F;$$c~vGqdKq5)iv0iYtBt~Z^ebRq($6@A;tV#a>(CXy>08s^FSyvco$ z%D&t{${gG*hw|(QyYpGHd13M{a#>eoiSYpy+O^CEx--eIWh&MW8|Pw(N^WFf&=zv# zwzC(YON37rG|I2x!qo6=_Q5~N{i=ceoByq2Z{aV%WQEja=5{5r@h(*4&f}N^Xl@b_ zGnJ1679lu~m(u#hgbX31+>6SHFd>?}Ni;c|H)(Odg~hEoOJ}jKwN@1C%Y>yjfMIBP zOYvX;OumOOQ#rVx3L@B6ZW=e&>^z8cav^_pD|wWpShopxaU65k{AQq);yw|6UO;^t z>ar)OAvmCI3)!w>yt@}ppsBDiNvo4hb3xl1+|{2EC|%qxN)c^`?zsY?G|IBKX_OD+ z-<%vmT@ikH+DC5`-|2CNMyElRkV2>`P zx#_|Z31l$RCj7pHdL%*dW*|mw2BCFj7x0?2m$=j6(~4M9ECNYtGBe?i5(ne)qEJp? zKkXr&K#CoB$$#@MAW6n0YBF*_2H%HoC7E=Vh8;>5&y&$BjdwTN!+7;^1)g8>FhJ5M z+Az)v6xB`*oPX1)VF5Z2hrZezK0^0AR)jkmh4FJjsFAiuB9x=SpstqJ7)hS`>r_vj0pqu%!T_iuFV(GHauYN^%+z5==+qh{FJk z^96)lqRer9=@6#xuypnl8EF9-F`y-FrFruyz^lgGE{VZn0uWu z4O8*PA>LNua{te`G{Gl=A3vZ6EXo9?Qmg-Yyl3TD-eE z8>-bQjAG%4O+!62;H51s(as)57dgg~*7d`)-XRi?pToZYN(b**ie%y|hXvC61Yj9* zZhQ`qT}xQ?6Ww9f(?$29e;Fu0VACi+4~9n@J9r(s@Dts+PfU~=UT!Xngg;D-&Ab@_ z9Ii${jGP?uYjS^XW3R&iObj866cr(S`PS=%uZ^dkIRTHR?@pyYxX7;4d!Rho9RmQ- z#NCK-M55kiVq<}1vmRTGSiL9&=4PPv+E3*hl8V!3zq_SVuA`Q1@;WxF> z1m9!<=vT~OrpU@>Tc}lI3Uw~^ zB(Pk?F4h|eVxRNb@0eeOV!#;pCK|T|l>@XKTe0bg5y#KcW-Xa*$2|;O#l3b0LBQ1; zLbt*GNjYuo4?1wa0ew}hoXSANPZf}n71X34)YjE4S%_@YvNWkM)b1J6iVwCU3S~(|lZw=?l#QT1sk@8AmHuTD+{cyi zJgKj6)uk#pb?_{-(PRL#V{l zdETz_jIO$B?Y>IY5k45ZuD(k2S(yizs{s2+jLNH*3)CN81yt}cX+|63rZIAOR$*wC zyGwxyVyM0sBv%r9(kI5z6rXKRI$Rh5OM$BxXNCIXZ^6chov`371BunwYm_D9%u2={ z9Af(N`}UK)WnK|wvfyOsSw`aT_QfGMt&-^#Vk?Y)^;tF6riqvbMP@)6GZzK{-7rER zg31Lr#TG?CnNb$!#x31?s4;$ioTyi=@rL+tS>rGWT}_Am?r|s@yo$7rh7!kCy=e^P z>`aXw9tIrV(e%b>day;_V*63do%@G}GWkyLP%ce9yW~Qj;dIxA6VHc3sv>%TFsy7K z_+lqRdn0gYj@#=^_QD7RYQ{7je`_9e_r2J*e;5NBtPN~O73N*~jzbP~PbGBEV#=&~ znvrJAh>Qb5EI`sMT7nnoF;r&p=lE#KNGoK~*6M@Wa?BG;8QVSigLo%HD|JH$rSzuw z+9gpJQ{Hh?yi^zeQr@0~G?NZ>jo-Ali<>oT4BUj{wI`rk;KmOv%W1#4W>FVxi}G!yDvZs(spz0g0^syMYGJ zbZr@DVy6R>Yrr9i!Em8_WoRpuqd_cGc6UCfYf!V=9I!mI9_7ok+LwlX^w8{^?zA>_ zHq&MfH&OH~a*7apM;xa(pS8WaC)JNL3iQX)$KlAQ#M=QS1QrF6Y>V~f4Q={=Js>*< z%}27G0NU^nC3&6_oBb2@-H3g_N7#sht6qC!LKLkC(39eG-jf=-L@ zWn%R&(lH7A4V#dV5n88dBtY@9IwS$kq{V_@H{oysSTz!Wjs+arW3AVj^tI(g1wPzP zFz-=39a_41dejYn7n~@LelKl)C#G|hrK^rjv z?Q8S=bS=qv2El2G3W&@n(U|-jIPtYJ`BFfJ|Hu~dT%GJOWnk&r&U>8HBie$5u23w% zd8DoM;Z9*86<|);h(s2fm2_C&R@sL*7j!&FZy=gvdvo*{PsbeTQ`9~MS>RYS_f>;} z-oIAcK>tY_D1sl5I8Y_Tfid1N!b!sc*=NshcR0Qh0{aD`J%+-Cf=ukB6Nt9F zWG6P$eUH$PXfthRr+v@Jq@5NP3Q~`Ey4iko!j~EOFIdjFFQqG--hC@z!SW&zofhGo zz2UIlN@09KQ2|8PYk)8)l;tC&n3d~sZJABP$jJS3I7GIB`6z_RuFqosAvqSZX|>dc zB0Wag=zr{R22`KbW+#R1O_5<8qgjCtqMl8DSkq{kofNiLEw2B7BKyERim>u9VJ_MV z)fjZ8xHW)ZYUUBwJtR`)2=#0uRoF88-nWVxDJ~mEk}1R6{U+X)h#uAl-(9nviN(;m1%T?1ehc z`w4+^CJR9wM?AbNU?D5fhA*vVKfZ+2>K=24299ffQKeG96fmCT6S(FK@M-< zaTr3?O!{9VJrJYHco>9LqwSok8#1#s{$V3`y9*2YUd$Kw)n%8UInvqFqV9POU)1npvc@5}Yd4-#F)Zfl#ZpOkUJi)oVVKADY)zqtOpu0PG0Te^u;-)`Pf%UXaKeJwdQWzwHF(S4G zbmK!-oxvL(l37V~BS(Xr;oy>SxuHVMoDYU^Nj<#=s!W7w61auc_?Af1Lz^U4=b$#_~q zCb^g|n!+A1TpZDnHxJnT3b`*+5j=L+1AMJpbr>bhMb_8&3nqdE%tI_+LDc*Ty?JS{Hm~d8F{$CGhq{ZcC#NOaXPgHxW9&L;ir@@b zd;~WXK`;C1ih=u~8fzVKK$iDcVtUMuKj2m3noCT*Ke zEYXMb8S76~5$-60^}sJB&QV;CJFN%=@Dp%{R~k7tyo^{|g$@W?z;a1OgqkknUJ%ip zXrJp}bk*trKrU$ZA@aP0Msx)2!o>s-=^_QyPI(gFzE=u$70_I?$X$%4|^ILhXCZ)H2pqkB7ySj7=KV=_X9^A-3k2+?Q(ERsg|~Y_4OMF z&klmeQc!Xq;K@QgmH-o^Yks^?-IBW&SU=*wVJ{P)*#R2iXq=7B(ZRB@>!9f-t-Ck@ zk{30&E93?nGJO2mbmj7J0unq38`Nk6O7DCJ@|k-9AfIndF@kw57*GRetu)XDL_e|h zcr$N14o9pZ9b~5NM@`L3%Ud&sPJp6Sdb8cPRguRV-PL{`Z}VL}4^uq*exUUKfHsmf z_`RB#)N|yAPz{Ow&F2hsMv})REOpzkMnDa^0~{`g;3CGEB;W=rV*PT+#e^#otpC4X zPLK0KwCHL;M3+P41{oL7?uVioF@*Kwy`9f2-3?iS44;|RSHpCSnUh}_0Uxk`1kzsy zuq5Wyt2@x9b`wXYei$<-izbOr#LABI`DAFWE8hARe#AHCn6_;19t6rUvU%%cJIv;d z_Y27O0Y0`jNU!2q!i~3cpZuw#kpFVW`C(^3oh1SJUg&uBn>)eIdBA<{;1M>8WJhQ7`rWYUj**?We zD)nAZ8|YY=s`0oYp@c?M>Aw7m-7ilWWoC#n*#UZJtP~&t_!DPq!lBHvNT>b*!i8aU zY6~ti^rxe9AljZU;%I|bU2I`!hUij^hS3SjkF0z$H5|$C(t~crS@A#!=F{Mde!4lW zrN-Gs!Btwp z>d9B*sZNyc%R|BTVK<37!2dYra~4r0g1wE^Q9C%5br?+01^7UOOu`E zt6En~`QyHTQ&MjYjLy-^OE%#)WSfa-Ux!0$ape;_(%8vljri{50xlH60Hp0&^iu=o z;9vv7>Oc)RX%SIXTQy(;Pxn;=`YzM!{FZ5MV=BG_wqVZc)_v%|WW}oFjOgirJbhL2 z%*B40K+T`gwgEX}xdHYpmW3mWfrx00DUm`{=S#`5j*7sgH<0J}axA}9#;?VDx0}KF=kL@MQ{el5g z(vJL;Nb}Qh#35B<6POaqm_S09e$)Ie7h#CsG(So#3uly$ZkksBDVh_--OB&Y6R`V-b0wNOVA=*&vNPd%P|sYYvi8ni%0e2ck*a{ zId+1QibA*?yPFrG;6TQOPjNX`yE`KxSZ4}E;^)wUIAJ`BpST?xMxaA>MnI(D0A0Ht z%5TTsK7zh+S?y|NX^gVe_jYVB5CsOHgy?5femgc*+>Rwbaypq8QiFsGV2_VKP%b@+ zk#an=dq4IURMT}6yi`F6aOk@}nRZNo0EkWs)*-hbc{z|bO~ufle#yi$F)>7Dio8vc zw)^w@Uh`pgEkTOz#$19&TG(wcJJ3)78>Ih(B(O+GK0e1bR0-I(jR8#BUj?pVQFQLIlBmR5qM^HY+{ zrH|uBHaoW(K)NPRItQ<^fXJElY*vcl3q+oT{)jO087gEe)|G4<)r8~nN;ocKgxqnt z7Im_;IyS=oR#eJn3Z{%BaeliLUit)haiWTISfFGtr z@mJ@o@gQ9&Lrf2Y_ca6J0DsXW^Ng4o)bRZj`q5=%Bx z7&*9&^lD-<+(tSYzYH5G3_4kCFlUe4MhfM$xikS#azis1A8w%i9Zk~W#sz~ppjSKl zm5c$d$y0P*Fp#3?_T^D@d4)yZ3dBJPhCW;|fyQq1=5<3JTx-#oD>NOC-T_e`meN4~ zi1qRad&YrrB>Pz}kBmo?WW9UD4LB>fWh zOFsQJ_7Y&mWML<|$(0UiIpdrI2Fz{_7%;mO&dteJ@Xl8-w_=7CO77sog(6Aap0I1r zY4u=Xe8QgVv)JRXd}Og}iaBP`SkD5YCTKBV(A(FonZqvew`RurMsKjIUld-R&HB+C z&ku$<^Z0_U>bZookSq5<9A4aqC8IhtFUB?Ycd#+x8hbn$k;hc3~d`>=CTVS0C2aWCP1X2f8UUV=!Nr zx+!xK&uR<<`D5A=QN?S@6sV5aLX!YfW!Y}+yb;AhLcIVCSq?tuUW-B``DR9s0|PiI zxH+?@k2y1ruUg%r`82xb>sGGR$u-cTIkP0dqB##J@LDwA#TRGvI(-J(8Fm7?ZBRS2b%M$<#dyjzddsj%J`iba5%!Ea7Rp~$4A1`aP<9cDh>q+l^No! zj@+cZHpIA&pom+)F7C+|0@Iq2bMHm`lr>1*j+=_+?CDZed9J0b?}X&;^6@!%u_v_5 z;;!W(zO>bsNnW9`NqgB$!PCv+o)yCY{vVYnG7x1^rIeaPS3r!#4ea74wEv#$9UhmMoyg zBE|g|3_?)F)M5Ng_AC|$bfDj27DH1ar7yGX802}35TsD2TK@kGP_g(7jvOe+f8tVr zEXIfVpeGV+YO~Y@SDEu2SDWNhpvHt>%p1GsE3w@WX+9rV{{^(6QO_(W%VH90NmZf5 z1k;fca|cIy4>h(?+-4R`iJx-dCd^M zB(Y$q;l8wDdd`q6`FK?*A2#)h;ORJ_%Z;>bBHht5Bm$CBe#6T7JMp<7_dEJxRV&p! zwtSVq%7+H&H%DV=>YjyhcJszj`D#kOGL}FFLK=e+V&(^0#NL|jsC;!6#?+lEBa*z_ z?9H_SeF@0L+zh2WwNmPNEx{-Q#zX>$`~ZH$E&IJPo*f8cLB{ZI8cf6U_GCd*{XiDx zjkW65%CGq|kkMQBG#-De=Z<_VY9H#b#@eu7OyVrHC;R7vI>x&4Cfy@wKBezrlUmq~ zt)Se&Iq*OE#eFoSB8%HTBH3-v@Z+_Yqs^QNabnBe*t?(?ViO*qEeH#6pkwJc6Skh9 z!VB26724J_4xNXqOUI$0x*IyWJ}d#9i1n*n$k*?3Y>^;egnLFK#~e#zO-sH|ms*^j zqP-4J^s>(oNC(j@s~s(UmQ^B#5`MprM;exGP!Soh=wI~nO+-*~oC#X;3W6&2cb3k9 z8%Td=3I3!WDxRjM$A;aF+b?SE@~@$VD8U0n4}@Lo_@s5B994MR^K(v}1;TscoyX@t zSOG}r)9joDSqhQ4%>0V9V`-oZ{d8a)8PAt4F zxTwFB9ImN{3#EmMN(Rq>IqR}F>H|*O=&UJ6S|I7!;v(vFp5fcqf~SC z1Pf}%^5okb6+K0j?v&YsGV)HHv*)Q>pFeeuDq+m6lm%jYpchOtf-s4EO*$E3ZLt+t;BeP-7v!fYxM!go8XZl;eRm!UF(phXUaXBV zVSl@#NGHA(gZOeyhN%ej@g3;CIEMAmv)v6@ToKWNC&l;)9yes_K#cIKN^LkxQi$NI zdlwsgHK1z>SwE0fAYYK$K=epDQSf8-S6+=e?aEdeMcnmTuMg|J)^Z@C$%DmRt?jHB z$C4gcT%fz?1S@n~F^8=`Qj(7E3x3on78DTWf;4~wBSN;c;}8K7oh4g(C>oo z306zLOsJ47N@nb_dth>9vF$X`G|r1odIXB_nN+d7`so%Noaj7g-42xzG;EG@>E=iO z1>#+Pj>2V_AE&pLT$4bf(dI{{(!?C?J4X+qfdsmL@FSNRz|9|9tdw5jU)%Q#$ zmw|+wfdq(x5agyJio|NdfO4A&DuF;GA!DboRR&1?p)z;Qt ztz4`|6R_bT)c{^lP|#Z4Zda#`*R#kqy3yV;(s(O`Q-Kb+dZt8qZ zq#igKWi8>lJyP}!Zox3axJ6uyg@+eO!@(MtW1~K>gLSaIjc@b3SMV`Nm8PbS7!IM5p>=1cIip*=okllp51v z*zg3#)3d`!3k;$M1R*2crffy$CLg1UD}O<`RSqUIWhLmHTf7SmA5sMH5F+K#Pfp@( z;|@nn(|Nbl{OBRa#y7_-_<9eQO%_k1Y$!Fa@!H5SaQ^b@VoG7GJkZH=(qVt*3A7 znpqZ&Ru2}1Ru<}LAy_wUDtobJ^nGc^5s~TE{WV9w(dpU~&JOyKx2-1cJ*Riqy3vz% z&BmXcNxQZ=g6})&Ic4^wT?U03MK@4Ks5E=ii#3a!j^oi6=VO(I{3CB|tocJv)U_*6 z-R*z@f!D5oBrI(Og~`?F`oY-+BY(W^1Uh|XsMIql`N#Y@f=TKwS`ul?tELAka~-%H z8?SoPi=Ip(>-<^-98I z@-PFRup_X3t^*FW<3u?S91`eUkom*9f9^8LDRxchmqXt0ZpL{THNz>Dd5 z(n{2u`5Hm-t5=A=bRsrUv$;an0Oas(E*3jpHB)Zll$M%5920crS?O>26sJTJ+k(WB6r{(!*i|Dx0|Jv zAo+>z^yku~NB)c-Xe1WendBLO>eP{?;wQ2yb+Dc}si@ohVp37Nk-`a8)Agq1OqN5# zg8RRb>UuLYY|^WkOdaG^Kceq)El8%RJ&B;y$ae>}PsbCN0B+p}?$isRxLXGkUHba5RT;!C zxptB0S?2K`s2<>Y;|e_C9iLF~%TZj?R&)Rr4YevdpoHoCDndf3 zw~4%$X~|&&|N35D5ZZ#UuccUQ*e>5@BC?Cq_gdKZn&iq_VNE1nPzg2zv-HAT?~V;= z)!u@N&h?id987#s9O8}|!=;Yv_3R`pW3!Hd(5lKhzD0HTUaJ~V9@Y+i@kFGC-f2I8 zx&g<@e@Ck=Cb+?+j+e5<*|o-LCFR~>vbeba`3|B?<@#qKw|EL|gEp-O_d5WL?kYrr zq1>~Lqb2g{(4kYXX)0TNt((A{96zaSEjk9ZauZyOt3R(A*z8Zau-Tu4|89r=_NL=q zf1Z-mRF|5xuddXo@1*sHSHFwill2`$p|4G9!ka&}t`rC7nAKe-{&>61N>t&}Z?`DG z448{&tj}$Y5;u;;7EiA+eG^q!V|p`-$8>vaOxICv-!ZjAx&e*AP&)oRrD~wEwW1RP znuY=4zuWO2jO3rU^%@CXZP#}six$NRFFvT}yQ>^2F)m>raS0Gx=nP13|2kzu+KdhR zq2;GzaJcOQ^AFKFDdaR|A?CUfuJ&SL<5ypdCs(t}Q3jg{LODZkL^oJmgmtf;FG|oq zxhXw8gn@Jwi`IL^G&^IH%*exi5`UUa*FK5?-|33ZEDxoDp-4uk<{U8Ft5d4ZUTS30 zosgaq@zbYR?HY5O3$$Jrn<>Z>=nLeK=gH$POT1b|RE~^>MBr9}!a`E9u7MaL{$yv1 zOmxL~n{Un1Gx)wNc_l>0TxYUVeI1fIu9n?aES}_*vJE=JXTsIbgbS0g9AT}mfCR#d z=t1IIt`ukT9Y#HliLs~+_l8y|)n?-FFu-|JuhBO19bw2oR1!1=4r|@#WlBDTMJQfsq&CeS15i8rA(oC0J>ob#rGi@cge0zc5KMT4w&y) zHAvLhMU8`i351zyk|02awO#yr>=QuWctHxstuteY*^jhpimD-BBTK7j8q(@~xYH=# zO~$h&tJtwPozF2a&kyNY026SUm2{sP3Bu(w5%!zfkUoA0eu(Uw)6I;GS{xE z=~-`=EE03g)SQIW3n;Z{q}~aS1!TB7v)%>^;=(Ib@$Fc=S-4=XbskB7 ze7?h>B1;Y)8K~atP=_(Dd?HzE73%DlWNkb30|t1-V)`d0;h>aIDlOc^Qc7AYs4_k5)fhn@g5YGg!o+4854*f=Ssw1!C_be@nFQGVx}UMAl*wK9{AM) z@s%*Jg@WW59(s@jS#QesAid(4;m{wFc>MK$O+2oR6OZYc#bbJacuaLCh{x1`l$sx- zHY$HX1>+^<4Dk$(7Q`gwE$^OMQbxo+lnteV?*UP_e*H|5a-)R_Vg)(CQH1fxO`sEc zVfH4V@b*wqOQ7jFShWHz(Nb93zl|`Tj+Gf3yWB)lz70b#irU<~e^XTki7b0IIT31e zp=U7hsMRo$WCVOIQ6vPGyasHiHG^7FCDlm&6|oxMBotZW(UUimlwDGl3_qbwu+l^Q z7Fx1PTz>duG<`d3khLt3^&6$5mYB%txb_GOvgkGNBBU%U3G8!#2}zfEgK)LNdUwG0 zk~6Sm7c}A23)tSO9OZ#y&Jj%^-!^=_D1{VRC0VeihY*;w1)xV=iS%N$PIkJ4amX&Ta zj;w$IJ7+{Q$j1nj0PG9hpa-Rp`le?c0M$t`QByHipX}0B^X7{cn+b*I%tVJTw=8ugU!z9`WNFz-8?*w?%!sEsEWPbjxtZ zlELgglEIX?lzzBqoQ|D_O3V%SA@m14!$Rh8EcU-Mupk#}5Q0DlZlS=RcIaO4=W__f z_;YL?uCT)2*2#o9A%8ZW+e$DOU0i~@NAR~E)5*o(7DV7fejg2 z4Bt2sNX?E+i|@#du~lxftItSwH5cV#>?*|+NMKi;cD7ia_Eqfa8H`a^!|X)9sI+8W z0@M0@xO!W-&!LnAS_pj{NVK z)>xYs(<)mcrj^>2OzSh^%rBvW>&>)2vCINMJkz=nsfkQ$wOvjeN;wtNdMlW*-b`x` z)nCPyscJph|KJ=-(fhKv45J1m_jdbM^ zSWlrvJXqk*UU#5OS`E)3tKnE_HN>6l!#B{)E5IxSPW5g`XR9GpJl^%g#G`iQJ>Wr6 z`E5kxOEXHyn0S3Z#>AO@jfw8Q#zX~(9y2Dw8h|T)hL90)Lk1fV*P{7UG@olXzd<%{ zfVGk4L^!1@FZ|R)w#3TN8T34yY>Abja`$Z5mIEhT>)?F86dUTytQ?z^`EVDTlxGolCr!$i zP%fF2C*$G&BOHJYI%azAC9w83Ah(rUv|yo=ma9=fekhqhhz|>lXzPWcFcEp6`a{f$Okgv6iSQg}&R;w-C zi4nvhSQg~OMtToWL0wXGxf88nfFxQA;0D%?c3)GTTo40NTf8@S;U zxYyk^^9O7GDTjXGS(9Um4gC@5KV!!82T{T4h8{q^IrR6UPFqi~j6X}%6D+lhT6%&d zR_jtvkkcKnCpeX=F-It<$Wk@ljz&R|Ye5p3+z&vkD(FyK%TVNOVIrfowWj`P5fy368k@Smi19*z1~gg z%S3h7*Nk}1U?i%E;|#|BkIfk*At!+|Fx^5wUSc;q@01N+*H6Q@;rwHaC3y_h#5Mfe zcDvyaauOSE^?-JSi`vA)SK}jJTVUJofR@hn&}`r;RTp*}QpFvH^%LvM7^2tgLN*u~ zIN!}1PuVrF&%)8Os55ZG-CtU(ZpQQTDDX`-xCMRCpRPiH@U6+SxHv(QYFv*AutV(O zI&QNU*@?Y?rnU{S(dmP7vkRVtE(DG`PuBtRXo+rK<_z#OOQl?Q_R8O#O5Us%1lHoF?-Mp2$bD#A8f>WZc)OZWUZvUq;Y)- zyFx$cP1*g{+CO?zacgX+0PWWjdm-^Fm%8vxvkSfPEBACA=ndLjtN8@bZmf3GtkcC_ zmgNt3WF6gLzEJCa+Qp!QaDxynSAnK6H(F&2T>$cjYorFlUDKyPZ1I*A$HSN+ySPQt z%C0C4pU(+Iw;5^>o|s-mUXYH-cv(7jUN9w|OT9XlQ8p}+YR-JmPJ&cO9|e+d$7 zTny(R<4lk$WlJM8Opn6i$RclwKYx_!F2qIh({^Y_?D@FK1s1uB>QmvRKG7cj&taV8;iu2>9$A&; zuer>j4v6~Pe!Q+cfd3Q*lOpgZ;7<%51OPU{I4~CAzKIMr#s4NcWP?Uh;F}YYm?~Z! zpL9zN;6q@&EIw66%bFCQbW57K?uI6$mYJ#11#wN^LaT}@jl`!`u9@8Q#xN?_I*DPXYjVCKU`hs8ZbIHZHqz=Xh;!Z-n}IVA+<{1o2Uqk`Z_BDIQG-rYoxLnHMI8Bp z`P3QV**)G}8l?cOZgT|yqjt3M(S@k8oS$a{yYus4yL zaEm!UF$_WcbS+0OP6odj&X^kPSU)JZfBgXOE7d8_5+%Z6LO9=-lky+oFJ zfXZUZ68n~ezGXw9epFn0C8!mdK5h=IpXVrhu>vbj%PbRXX^DjV^U$gJ`s#V{{bI_o z9uR+)Zu6Zqk9t;6v$F{Fe z&~X2qBf#ab{Y$SNNwDhx?DnF#gx#didCn}@!PPo?3fR3pGYM;iz*APLzYG8wq`bp* zkWD>-mvX&ttxwY53LaXU9?r9WhB#qqH+6Cr}7q8$!j(+lIPOv3M9ZKyn z5M1bZiKIl{$1~Zc;ct;Geqk4Opm1axmD6&7WH?wjKm;fkjxE-VzGPwA?+`RjpP3w< zhb|&&Np#(r;nJvg&xWi?ZMaj-=YdzkW&|I`qA-S3ITl!Hg$Rv_4+w{}E9w<}XYFn^ z2WANUf#<2=A@xJ1;Vjt9dUq`jqt&}-;*Z;ySkrZrmDsMg%&WEzL$kZU3jPz`Wq2vd;HY++t?ZX%q|ikDUqc^n_HN#ET3 zeu#H_mkYG!5Y~o^ga{X+T!lM4$2o(-Ev$jsQ%Jc3g3MAw!=Bt!?S@~2D8?2$o}6fl z#UNN=c}pHr?{ilr)%iN>D!Q6|CmiL*z`Wgca1-)%IcA|IY^Qf;gYBWpxbC_VOAl_NcUJ@Moo1)3tMd@Z1rYs61hQ?mfRq()e#8<7A%|1 z>L|6pMDOV$wukW-XONZJ@8f|1(I#sBlGG|&Qj5j;uv~&mM7PS-tMt0xp;(~Hx&Fd} zqKtLtm6R+>gj*vFr8iq4+{zMu~X$;pNh9xqbys z`r^WBb2>-&8f7*X1o@PEkEmG)6QjX-EHV@GxjKc^CoT|}40zq*{x6Ku6!=>{!Fr*q z&4EWaMk@k7V1lm|A!%x96&0+_)+XsYDdx<50`JO}4CtcMYo<@ZawNaknSmWiaCK4w zd+=f$1sL@i#N5Vs-8aeA?kH_&-D+}I4&699i!Pi=Xz!@2YQpr(Ntt}Ccqsx+)%xlbtWh>+|E~0)9K>X`U1ot(j zmX#%P-f-kSOWa|9RzuG1z`k~i_0F7UCKa_4;>F_oS418FZI@0mCW9S6DWHIieRuE% z0Kw06r^zPlLr`!WUkx9v~j)8jNB-1&wJe6`z3UgJ{8vUmFFFQJ(!&u@2>Q;AW?~ zLYD(Gu9=B!oTK)vhFe@tR2|0+i^WtUa|?eqocx6a9cZ{FplLX=(~)&jY0mfea3|BK zV!K$pDwxnUA#k3MH#b|syRbU*c4IU5erEO*SIpOv2@&f|sim_l`RPjS&5WZgZXB6S zaA*sxMUcJ8*vC_qEiS+dl!*)qJBfm^9IMoN@o0)vkqhx0xZI(xuTQUA=(O}cQ}cGy z?O;t<%t>Vl!Wm-FPsGPm=hJ#on;xQ-ji4Y;AX!YoR7jjd`x3sgs4L)(iXq4)#!SZ| z`76FMNkN1H*ApX${uYZ@V7O%Rc@5RRk!q*2duP_W>HtPGtJKorw4EFTAaXt}b$BI@ z%G*!<-M+ZAxCGt3$Cf1(KEF|OuM=%vgTfKANZV&bP#dojwG zZM_Vf4dq8(BK$@~=qBJDtS-yVEeA<(;U|Pj+eV=Y;9quAyCZN@CqkTdM@vfUeCgP~ zecd4I@U;(Dq=&UmF^ZQ#2AybFb}fIlj*Q}+W}S&1% z79!5BUV|>s76~|zYmtGlZh^Wu>g#k>bkoIaI6ABPjJ>K~CiVU>tYwII zpr*j!34qmantP$#BWWKwD^S!K#YS-mV+iFWWCQ2r!45b=S41c-5mO@Ov%ovL0t&+C z<61n>BFzKlWE45L;#^-jh9;S=Z67hqc_R}9IsvD?A4hsXkcfvW6*9UkQ<@?6N)SU( zjqWfe&P39gxDwIlS(ORv&gx9jc{#IUk1*XpPm)5|qiow@pf%p{pRmD}L-*=mh>tEK z-jE0)n7*;%cc{zU#Rj6c`4s<}ynet!ymgF~7x0#`);U5#?8UlE#g)jSN5+FOJj#|# zo6DIOI7&<1PR-)8ZFq|Pw6 zCdwS0kQr#54lWQOG+q+lo`Gq@$v%WsJA~WM;5&_D3FF0F?ka1BehEja{E8NW^IplS z3xRd%E^MPO&?)tPkU$oHJUQ->NjB~j-n^BaLWTfJCk~W|| z4L31%qCl0W99_`HBYBF7;O^Pbn>vh3>(i#MRR>L9%1LfY8i!+=1x4A~NGhof;{wUk zmueaHh0efEFtJfoh;_SZvEB);p(+|$a!}j>y%&xb>OZ5tAsQUwBjLWW`l6_^r3qb~ zqqhX!PgdQ^3!ep!O)-YE;$JNe&w6zF8OjSyYg_@58@_wDSIb`I1+B*b+}4%^54XbJTm}b~aWbRr_(8bM9e;~D zSJYNh-NI`i{uYkp>COqJkIoE6B}-nKD6;>#nQ#vf0-IL2jtC4wPB2s#RB4zoALosoDBA7(=9yOP@bGeE2+BV zN~}a>YooE~Sps)uL6Lh^E?uVqdqe@tdSFl7qB$w|cSIQk57%c52eI*KkbhYz$bSemU(hFhNJSrV@+y-jNt z!0uS*1c#owlf0S}7;y;6S5v=G8Sn^*?}l(u<-|MjcNaqf1M$Ry?xvek)W3yNjV5s~ z8kAFsBv&9aDsClMnf1!PTU`fJ9Ye90S@2Rs|-L0c%@-re4~)ZX1to>@Z78OBBWjKI+pkN~h% zIIg(@fMj+s+uRHj_yufRrUorLZ#Uwd(luk%d(qJx@h!AqatcS^m24deq+shpMMQys z!7UIrrPh0Kan2PuB@Salk*JyObf{h@6R8YVY$%5|SuP09o%KMZ z1^O*IiNPaG4>=)wysVU11@N>(YiQu&%cEvbs2f!&PzBNezD0bm#=YoR??tRQZ}m}i z7+AlR-!H|dL}Sau(hF(Pdcw(<)~t;>)U%vg8-{Z(g|7cVsl5rXH@;0+5FzP;Xi6^n ziQZ3vsB;)X$5KizI!FR@gpRZ`iL8i}5CrHz9s-R(pk;(N`Olavd?v}lS>o-lS-4d2 z4&zc;-6-NLKJ1V6Ji!#6Sx*J{oK!bTJdE$bca9;cHk+i{bR-6;(zA`<)LoYvm69rP zoUv<`;_#fQ3Xv3b3XQb1j2Ey(guEyraX#+`ysc^AciNmRvAK4xY1mH z=*cPof&hRWM%>yXBIja4IIvllLE$-0yn|O0Nxg?j;~B>cf}ed17@}-VGg2jv5%1KD zFNkhyFv2j$ieR1h?PU`JIMxoF&zO}QPM!nFIFV)TP_GDGX86FedMX3nf1PLbau3f& zNB#w#)q%pjdDah^1X#8=7!M@p*&+tzVd8uq$aHi`4nUIQeM_4l_8{2=$vKAzByr0J zAu#txaBDiW1QzT0Dzl!uOO>s8WyBa2b%*Z-tEgNkzY}Sv?@^$KKX?#u{8p#t+KYX320a-R-SlhO=8T zob4+Y5X0H&^|h^pV}4tKuag+gcFAzIuABmfvqG#s*Je1UVbujbO#;J-7}UgYy7+)1 z7|w1!aSdV(eE@EeJu3F%HbU^5JBZ)x3@z!Fz>HAfi5Kv{UskhQvYMSXtJy7C%}!!9 zTQ2I&YIcIv?2cnKJHcvp6RX(?Rui|{A?_dWCg0*R>A0xPWfCeRAP>NxFX=WA#YKJw z>A4qb#Vp6Cl$gGI04gwp9rp7fWZa^aF zx6NYG#!Db0p6K_W?d;ah8r0~Yh{ME|ijB2cEWeOsTvnQ3b7e}Fp#3x#F)LoEy$mr8 zQlPyl=O%m(y%1l2LYLPcz&;1>STUj{ySIWgU7 z`7=^= z3m6~@42(DW%fJUOB&H|Z;C>=8gEgF7(|7vIKuu~wddyepsY$?FUptn{c^lUzKaS8l z+L)@?w9b&9u{S}E?YLw*7f7EZLSCEbxW!N7F)D7U&!&co+~xwg^Armt@6f51`l?ed z5Q;c0SNmRG?dcu9?qpKFv$YJ%-MD~QZPTF>A)8u@tCAN9&p%jE2HBZ?IiatCsxLWV zJy}AJT=^86*j_6b877-(*sbTq5A46W@?S?_XgRRBl}~;^U%B$BP{PW0^`T=4D?f%0 zKRK82!NLWyrKa3aO|tspH5N$w^DU7e`eP!9XwM@@6@Ox-6eKNN*SHR~c9pKln6V*% zA$@h_zwW>C$TgivSk<634$k_m8?QRT;!%l_rK8X z-zIjO#C*n^i>T`V#e%r@lndgKS_^Mt3nIzxDJ_U$*i-AVy^YJw+dVxOccBp4BU&Z= zm)WwJi1-v1u^+_0dt&?mv{S5Ttml7w%R3yf24Et70hV;GM!R>y`s}rP6A}Ijtf$y0 z{S4)a3IDf-GPw6pF2+zi>IJ7CN=Nc6j|M$I^B_sue()gs;%Mw;iKB=)F@Puh1BPPC zMj5Zrp$=m@q{|E(xgH`Oh~>5Y9e$cHAhY50SL12;?FHp-?ZQNd17>&0qg4F}R(Og1 z>3Xx@yHibvyXk(v_xPH>8}G({L?)0)}SJL+##P^Dr=$ zcMJ0Dc^Ea$o`=ctAZ5kG?j616VE};7v+x?t!mGy7_)lmS_9V_iDS8{T48=CEC&$Jk z|Lv!kg#Tn6XV+NsV6J1D2&be(!+@FCT_hQTp?|uEuVhMqb^>ETzMb*FHgWgkv(bAW z;)S-)BNuJ8uztS#td6E+bx1ERWhQEa#p3~D^h;lmwBq8~%d`|k_EOL5Re1LfN!}AH zsY+V9dq+aam{da>AS3&A31F6j9}Lc{O`d_aAyb*M7=L1Ak@_StE6%AC0ZZdDv0Fps z>LD|?D=?OhK|-kmV+=yD4ikR>Jfz-r&>r?1*@16C0kWY?%0`eX5w;7o;-Iauif(wr z9{tNPmWNYXu?WNZ#+v`zYBo3>+Bp=(^$^s}#8l(LWUApj1QAXE1w2cy0f5L?VJx*X zo=UN^NG;k)EZS^bSg+J&)-QC{EpVddA@I$~ghekk)=I($<^o`RCigU{GVJj7V8^P+ z@V<+2Z$ba%xQC)S_{)%k2wAaH;O<8bNYJed@q8{}OKZX1ZVk8Hco1;^#;+5OvPYTe z7XnKh=_<)D1ZI8xIBX;2Ri5gHM-pO1)7hwTs8h_fTYPL64G=DAbwFs+;YPsQM8nHq z9PEY*`Y1AfK!#Sfz&mbgy9ru%w5YqFx_j08`i@Dy?kAn90=ISji=94-kK+IYp~tOv z)}{Jq!I>1EP$|^B!Obs(kEZ5bpudaj-eENru$sbgV6PuRcA-06S_9{^s4JS{nj-Qy)yepfj_lhCzzEICy7uL$Gm|x zCSney_SofD-N_S_jd21o5d~Tsj*wfTeY91e1O*~Gpun@%CQ^|@ZdeeVwILKUsYFy> z&(jw96H39}seeJ(<1Yl9TvupcAUb(TzM`GKK<|O4CqP8LHNfl5FqugZE%csb5bXqr zQZOuI8Fk?v>H_0z3p`*GP!JwYH-*>tgvj@bX0#163Z@VdY{}04tXAy`6EsUXnx&(3; zE;fSdDDoo8F^~~lmzF}BAC``GtsP*_tV@CSD*!JR;fe1-5X+o@e>qre9e1)gr}4+Y%#IIDEe|OA+;8ostK?rsdtyF@4Bx-{Azl3~?0wgo0E-Ti$FB7$wkjgOn>j-m-ZRwvMvw5~9` zws*5#6p4+j3n1@ymsO@Me?2p9p3(5XL|bwZk*O4pIBlVdcCtozK)UD$zLjkNy^%pt zJo)C5lbGx>G$AK@OA}8vWD7ZqN5#!&&@6sH3fhU7MC_{|A8zs9!^CewW!tLM{v4&r zSAjOxAJQ|7IvR=9(oF~Q#YOoQ9(69=Z%yt##bTf}+$kNtY$q;LE5eP>)G^1tJF+A9 z8x z8TboeUL(USF($L|40j$Scn}ZB#SF`wL?SS<1g?)Et(|tAENtZ1c(Un2>TJ*f+*l39 z$_+DOga$;^i6NVE4@#ZtZ-h9@L;mwCAl~Rk{ z3i!jsEAlMk54L<53M|H~n;0_$$X1A`K85P4hDEMKxdLDJszPSOI=vO{m1F2g5sW;% zZ$J65xuDVkNH&1ER~;c{tP>j&n6YmC3#{0kzIH-7jFqWE)}-Uuf08dFPU9YMaO&;G zr^s-uUQSgrlTmEddp0r8>Qr~sHyM@j=zZ3VY!0s5hqdUonZE(1+yc@Tk!Dczc z*c@xtNT%CosR7M}RI;~qD?z#|ihFZI0nSIHi@y%*wNFj$XP%O|PpgJ2j zCmq4fN!1`gwAB~`a9kk;ub@6}4YiOuA6)=~{etEepSUsKkq7XCAVE07kb+lZA7hme zE!l)stp#h{8etV34=52$h%p1AM2xFado6uvvil41OfV%`@+2?|4ni+adZj+KF8Lxq z=K6M;pPP+OCASSiQ6)@po?Wxvp5=o2%sQps@2q2|L7Hee%c*r~g;dK~R13WIvehii za+;&iWOx#$InA18B68L=cVe0kU_c4%$n5xOCMf_c?tU{giJB5W%|n4a3Cue7BxAY7 zo){lsnl;oer}?$#XqpK?e5%0|Y3?J+0dK7l;wmaB=bDeGc~r`{PaU} z2MLnTm;s4__aW>p-?DOQ=|T$ZEk)>?xwjbK|JOH`XUH%#k0jODhOac1gTP;o|qbKf~7s)u;BL=A%^HkiPwqsi|qKxj?HiUnZ-Sj+|o=qJTbiF`E zQk>nIi3va?vO{oN8zU}6hfTF_cni&JV(YI+aY)L5CmOWC@+5a%+K zEiL|zxo2{rVYspo0iRIlD4|?s`gZv2`r#3)<dnLg<01rYkaz=a%65#O z1R8tdaUkAW#}hq20R>21Y$5CO>4dE9==?IbrkHrqaX!zfA z{t6n;q5K^6sxqLZaZWwXXPoGmdnrxPG#nbLU*w!t483D`ku(2HD0cQ3$D^~LI`y@o_mCRyK&ff&#dTwVfP{0jzWPQ_sK z+cYJ}16l>@$FdIe?CoPj2%*xSYF3`0}d0Cx|e(gN*0T=<&;sy^5CIq zE{zZ)S@xm>QctO}WuUUGqvnTOr6mHGGpt7Vb&=R`C<{mPs@xZjoOj9Zy+uZXS8>2^E+ z!OA45gm#g!=r|T;U_H@EBG&uPr6bCtvBi?1jCa_nSTw1#C_aOG=B)a`poYTKGnsoq zg1rpdmxLYF0@1T+XsMz-Z+}5aj08;nlssUK=|tBdkYNT%oj{Qa)RD|foPoB}XM5jR zHFzdnsGC+e6E7>@#s6d|DiLLG`Lcw*^qDfP*8;Zf1A{s8$6z|T2jv1qN}vSwQ}F>h zDjCi>e`Kcc=g0%NO2md^)LUHhypjdJ*R6f*-Bg^f^*Z#E`WNa71YlUwjy=Y;y}tOY zj_t{60cfzf2oRP4Yq0DV2eFwZvCU*d5DurPmjmc^nf^jLS39ik0%LH;b`K7m)krL_ z#}zI9!kWt++9Nb#2v%{M4s&SYJoH=&YNU=Bi8m^#J8(s_oGIhY#63tP>_LD$hDoO! ziU||U6Ma?`2m4l7pZoa1DulD*LcfwV^e$wY3ISYD40ptX@se&ATla8L3uu|-^8MeF zg*ws(07Gw^K^7TtQ!IOj%x+=$gDGzlY6_6Zw8)G>94GPgM7}|k#;MfOi6e8Qk)P0W zGopahXZjKFqH6(E$Y-F6Mfxj~c3pu0R!_-Omqh-Y3+mH&(so_dF?Zlu&?Bo}KTJro zaR~1!Kpkom@Cg^x`FlvYd|aKvW|-zlJLeUbi50PWa+>{7hcT4RL9gTcea5djWj9N~ zahloq$XM~5QX@mt;*=B`$|x=5g@Wm(1-&`m9z{N1Jz|5nYRpFhzSe1OylS&^Hq2E zp<$Q_4|Dz$QiG0!6H|DmI5*a(ZzEE%viGsScm`bGubdMHNU(&_vpT+%0K#DE3#rN?{h%-U7p+=uok!bjHO%U5-rE~i&eJRs>L@C`e0P7QMqbZ*!;~0#36U7^Wen4SO0rW9SuoEa+ zseci91AoE6Az;w~4F-}<<7$@6Aad=YO1AE<#QkSQot56ZJu5TtI|QdrTz6+17vXu> z%1QXmSu-9fXBwlGtxG!NxKx`}q|bE?ns~^8`ydBGeSp&#Y9VzBO?Deg>!A+!Ogo@{ zZnsS`AqrJ`=W(<1xY>E!>^yFE9ydErHrw5Qv)z?A0z!=Hm`WT68-Vtd;9H$dmD)!M+LGc#et>5-oqnN> zgMKVmyo=9GjF|qbK8p(HLJ@@k3ZMFYfRwL(7gojji2KwPeL7cuRlmm=0j0tP;ld~m z?SQ+3+_DK^{LRqYh5JJEdcfG7Texn@gIPZ+(#Slmb)ze z<5I95w#^2>oeYwr(o?BKw zcma0oT##axE@(#|q`$EMn_&hE8L2a8flqvEdBT=xT?9_u<2~_qMuIp|Ozse3G5W>) z0gk%FaV4}P+X|sL*66;SajennJZ~IHIkFqiCd)ce>_esI$S!=W*T^J&+=SvL3p-By zGFIHtZ*k*x=-PO~o1kTqs;Jcd7#}}uD^Nv&PDxeN@cvX$g`|oaP5cggPY{{mv0fwR z%_xrj=|>}F?G%4Zzy)l+m~Q4QPj+Ft=|T+63h`*^yCM{J%VZ)ah+m(uA(isWM6w|P z^`s3b)x8m|aUj=wVqd)q6Ps~^#p9!2*$5LPzV4C?2&|oL#ib=;8JKSH_WV{Rit&c^ zhUi1ZERy-!N~AvPo{VDg>#K=1$;U~_(PDtzP6CLyXNCvtNdnF-w`0~2)>$BWzc+|D zl$!(-@hAH_yXYAG7utAQg}LHEK+eRSFW`<4PvO9w+$*^g*dsg|u4Za4xW=uGKx5!f zhL5yJwYtROPv%pd`DOJ^MxM@&xmZ1rRtmtO#4{)tf?80?L8u8lO7(EAX?c9xAcv&w z@)L*h8kK#|_)Q;5d&cP~?H}GxWKRfJNT+~6Nq;}i!~v9HjCc_6u*UyrueAdJOj5Qu zF>a|f%BcAUY?`TH=JmE&$Z$0$Oh`NtaEl;17iTQUwxojHJ9si$MIrS9HVjs!#U}8a zHgn07Hf#+8c)M_wo>ouSaA=E#}i#y8tgM^=wOwB zL=?w$%&DgZol3TLV{tsY0X|1^9RCudb83!5>yFpT5u-D+KFe-$VSJNw{(BtGSW?9e zr1?;SWM1m6SR+BtqDO!%=#kXG#WdvBV$1El*erT<+yDG)^k{g8J(C((-}n`98hZ2| zYPaSeU-hL&7Yrbx;xR0G^a`8|WAvyIZ@uXeYw?I44KI$-qi@*l{I}_msSyA{$~%-7 z71P_hq994<&_W+8lI&*1^*>Dnim8n;WkA#LSt_2(v1pM}OX?VlZG4HJGx*4CeG6E@ zJEy&jE8Bm8=38dYjZ)j+`&J)k#h=u`;r|2Wz~s(=(kghS-8Xx%UlBd(rx$^w~w zBN;js3Rb92G5$b*F1D)8<*!KjhHA+yXjhx*M?vjPFr8^&HsR5d8;=NO$vCDK zi`|Pe`pJ=A~v2W22~lsGm_tOCZfesW>#$nu!=|VTp9G0bc-#V~jY2y8mp6 zb4`W^x@oMQ6o_ha4dP{h@iAWEVbGN@jJUx6Hp5N>>EGU2{x0QM%ZxQX*sV$38~ikG zC0S;}h1_?;HXB}yZkn_Az>oWk`+sLPRI!Zy8)n0pCG_cIaYKSxHUoHBD(=mu`3PrB zA%;*=hYF0{9M*F`>NBkW9d)2#{pZwyE+&f2WK2i;<|i1MshrQn$VhXz_yhC)iE^d( zgV@Fa4W};yEcqC*8t^cO`Pzeh*h3t9%E#G@gxwM3diM@fG#eu>iGBaWzTe}vhq7WU zlara~+PkHb4vNq4RPNdV2hMVJ?j!^t?p!mYel)o7S{w%=tW6X;QeS@PR2@MHp(0qPuZ!HWI3Theypa`{g z!2}QSBe&Ru+DJeuwj%5$^!HwX&q2)jYSM&~zG5<t1~uoG9}X{@&N%0yZ;#l zqY-R5C01?)%0(8S6f?|13`0jum#4FdR+ftGcXCfzbC{2Umgew$Jfp_j^h=GKp%v73 z!lXV+IxE2!u=z!zSx{{Z#YroWlM(g9rw!9mrY&%)BMXhx`m|}OYE~iKlroK%3x$eS zrPT^4&~A{k6dWBlT9xnxBWXl>1{psPe!Dadrx>?#<51h7{mbq4{nn>_+t0GvA586M zpnU^zQ@b%7NB(Fn*KXZqRgp?+tD$~sez5WVx>4XHu=n7vfe26V_6kiY&^jqVNK9i2 zsYZ!^higdU7G-g_U+c}?k{C^AmriM$oM+(f6h6%K>jx5TlmFP)zio2%$5?>>mTeN= z1eR@brH@3VQ`jbR|1I0({pd%`Hd#Zx`hRAdBt<$H0U^dmfbbOUkfXrdpzn|e?(4{p zuN6TDSwl@hQ{w$icNlyG9xfG~Y|fS825A+MMOPGy>2ocpHN%$ys%DNd=xUtoU+cIv-RO8=&R29i_do48VLWZ<&wNA_ z#_}5Mbyk)MJATM@5EH>+{lmpa0w*fg_`{3%?`7m7ALv@XCMD1`+HeP&auFb?X?>va z$Uc#>5sP>RDYaL-0*y0?g+zP-=m5u>%-Zf9!VS1ln#4rgX4xy2NMSUQ=Q2Bg{6lnp zN&CicCbR2aKf99I`BL=$1wyH@&1K3Ksijfx>X<_%(xN&#4M$wGJ7)viD;kNH0(#Gx`;kxB$D$sS=nu+y;im%_iHgCTHD-1vv>Up`!u~sb^*{fGPQxOQw_DkoUGzQl*t=a_Gz()`f2_1@ z#*fg?HP_}v^UtF0sf+UVD_ftYj?noiby{BA@n#3+6(UZ1YK@W3KuP1>_|Oric} z)B8#J5A#n__zeY@;&*58eEcp$@leBbN^Ka)zjxyo zXBTqB7vRxM&SBAapl96`jXXDqm;!e=oQy)E=O10s`qbti`CX$Dl|RqNZ*8Mey9Pz| zo)XAG#bW0>G7#P5XqXCxH`A{en(4rC)ozq4hifJHgP+S{N^N%rT*nLqJsz(F|A6QG zLd3ZH2_EtqLqXF0)CDiaZzx#Izw`O`7EZs3e{ba9oB5YK!RvyR{CgLEn}he_*BJ^< z!JoViG(B3`vZGi$2g43AC!_QrRTT|VwYN164A0GJ32{>7Z@}Te$ps4GEtG`hfgd<| zo_crSq+h8e4R+w<6{;t2a=xbaa4T#-1G7`pb%{1AT$ogof3Y?!$}Q`iq0KYVLTK|` z{2F)Ebmf5-Qjw`zvfgQ2SJQQ)T2|9_tGc+R>n^pZrfaP_ucm7$j&%+13DVGvg22gJ z)N=wSZ&wEePOedh^#p0G#@XRQXHEX?>W^g~dV(}+Bcmrw0gsnU+ zuq!tdypAg9yc13yoh#HKfzEr?LFU|_K{K2l4KgD9>^7$(6ePSulVO?Mm%$k*3@~ z5&416o7ejSowurE&?6<7jij0e9=Oh!s{|*Z(#Q#1_!oMRJKjJ&nydtersAw*kWdPz z)$yEnC?K;Sr145>c1)gQ43LSFwBgaP#2+5p_9}a94KxggmKKot$`&57ag&K}oC^HA zzMj+dFfGz3qj+6%dN@dHv{)|S;yESZ2Fea^J|Dm02J{?)0|hev82vZFT4*=Ti|`PP z9KdhwdwP&ouUL3NU+w<8DYZEB*Xd@R!^*Ib-$w@mF=Q z5xp`ycm*C$Idlon`Y=J>9D0W9v_r3q)%+>E;>}*pM=xdnc<4uAYvG{>8j4XfaAiKo zo}93o2(73+pAw`aUaGV(-u)H|6jV^UBlQ6a~AP#vP~&iFn+wto!mmIvgbQ?nC6h|n6K5$2di zV@!btTJkF-&ZrCI>nbfP&^ch;fI#OU<^C_h5C=MQwW%`iUL|NCMS0;7T0D9C^<9DY z(qrD7`9megWuk+YEdvA{U{hfVf+!eUKkq zN^KJg&zlGByOp4v1o0IvH4miQYf^%ZAdx*`+T85{xRIpuz92V+$Z?!O={*lPX1XlA z#;FYquSsfV@(``c#np^e*zE_NM1WL;H@U1r%XqrN-|YJ+H}U`mQ~w}s=#g*Z(La5% zb{q69H`iy@bXBO=`={+&<*wt+%W&5{NSheEOZe}q3H6LD=WT}$9QJViRZN1u^DoZ* z|7a4f@Z6Nc?wrCaHKA!lH_*kthTFMOI7{_KTzJvoj&qhcQjfU*^FPSnX9N7Z;w*D z0ZYinjAOtgxungdgrLMos%cFs#$m!!y-7aYtzKtR$YQYJe++7-= zO>`_@3I749Ix}c`12JgI-9zq!pop#f z_V^kkc|twOO&=zU3n=c6oDZGXo80aKjV+s8ZCNL*36m@$_ds<^48Spb$u`~mb!+UA zY)nr)`4hhaP|Ir?h-q=?4a71lwV%+Cg2Z#`VH%PZcbJnxoW$-evOIzCPc~@Qs+U?I zyuco22u25U0S9IzUo_=K5`l7-xeKcOtedXSu24uUv{+VqhxU|h4qm@Fo!RZ zT|y+hF0G}{pjX~t5Blr92aQt|_Mp|I<40t-{NT8r;LXV1{fVD3F;~l%SSy#ci9~9a zgcCxN2MJOkf3o4JX&}<$P?Hgq9QSx#CYjS7mVOG2`P0X1sgP4NXQ4SgyRHYPbP)8k zF!Tr^70xnU&Vt4>k4j2^hFS1Y6oeB%p?8-CG$*c+&Y!7cBaMjUBY`Ez1Jdx67#+pp zWjvM$8bUd?H{uGN*FvejnOGFDwgppC)8N6gLmj9GGw?ts-F4n==`I5b&!7HgmlgCJ zW`(dXqZlDspXY!$rX0!19@0CD#}m?15q4hl>q=EpF`~g}lf-LKyyAFo8aPY%oa1v` zyGG|29MMbgb@Wm({1YbmhO$VsUkp-2e5(3-C~e;a1Rb;v{~_MIiaVemy~gRFq>^Z= zs9R3(Lnv`Ilfm|_R~c-$Q((un^4Q~Pgxzr%w<+v0XCY;gc#)U5k5EGn{}RkY4cYi* z!S}@Lw&1(8S_;0$Agjg%-xL%e!Izg;h)IT&p=qo5Es9F9x8)T%(TK@U2oPq{EJk5c zi$w~4CC-(@nG1UD$7ErpwhRKXVaPmeLJ)x|CEpJbcrG3go`A_gGmF5G+OFr$lWY-U z@hH?lOI-3qAgsim;1AvPhd<0QHM97Lw>xE`l!uvqqA#Nu+P{bWgx2FAKby8)8}}bkC7C$N zGBKftNC8VhGBLl@Uq^I~5R+x%36Pg{Zb%|VKQi(C5Swcnxbxa9s(fG|x=Kw!3))o4 z5$ZWC%@e1{4?MD&-EsgS-Ui??s(fn^Y6?UlSDz1dPpN$cj5O*~YWHBn4@7TNYM)1n za(_N@1JRq;&kjUMs*Xac9*-om50Zu}!Fx%nz8X?m)s4#oENMfeo&uI$qNX!48P6nA z(^w~yNPQh1ERmWL<3wr(&0RR&Xo9A%NKGH~CsI?o9;T|JL0T~^u@Vi47pW=R6sa?b zA(kTbZ!rRMR@yECJp1;$H)I1&{da`S>>UycHBANd*9lYa& z-N6CqAhy~5hc4k+&-;owbP}mgQ!@feSVR9K=FJ>>S9!wF!?4uw&;v|>fF@F;rcSU( zO%JCPsd<`Nq&`hwz6}$oISpfDeYwN#iz!l@bwQ*~tVkx0yrxMZ-sdMnPxy+Q{nOKZ+lB296 ziiy<47;2(OtxuF9^@pbvshOmaNKL9Sh|~lw*$3QgSd3nj6KP3}hG~Vp}#$0VkPV;Ed&{r zBwOw_kxQ7aCe9769bTrn{c@v^N!U*seI@LlfgLj?Y&y_E681fiu5er2-i`?x@DO6=?TQ1!RrXV~B(l!J|+T>Z}<_RrXVq+U` zC{u9XEQ!c+Q~jEq3xRtf1n#SL@@7EnY9P8+9bqAKrrAcSRGwGeWt7A(1yM)=X?OAj zPQka4R{WT4?1O-BNpD<09o9?Swkln_JVJ2+>s)i>4jlP4q-;O`$`w~Ej*yh-{X(go z0HNDPk8^l+O(*oDZTSqmng~yFHm!OoXFHIgvnrt(ef%6qXv^6IN|v*UJ#>`0(!N-dcH!B=P($krfb??H+l zyc%^$owD+HldI{dE5u15Rx=xwQsQ2ULeb4sRHWpdgzbkOLl082fpef{TMw-Uz`(Yu z@wLjSL*2+y1%O0!Snoy-Prm zaU|Q;G%)+Ej*jn+EqBK{BE`%=lx0<7Pk=)FN2xs@(`L{71&qry^KyCEN{2(|zBxN|9+YM$$DW;9o}Ia94Rc~lmz{(~%(%$@ z`W&32CwN~c$KLb=l};ALIBjKtl~T&}IR3+gCN7kNU5#?%g?xr9Vs)5%M&!!gaNSGd zs0ml4b_YI}{W^Xy@;qK*Qo4(zbeCk8dstL6by~)CEUWt=tNYDGI}#0&tPZu;BPwc< zWXHQh3H}r?V1cOTyK?IoZGI8~UBPJ`vrfqFYvrP?$AKO7n~{^~ri6(&6OYEtrnImg zCv)lQcNZPS|Nc%AG{M?CjCp3^PY}L!Cu>+SqYh(=xC3R()h&yvTtlictQlc~2bUO+ z7K?58s6;%?kzWH1`51sy2@qQ(Zfe8?2UxmwY94VGw>b=zi+k^cV_ko`0!A=XS8$}c zA6-E;H`P~Ha8rEx#@35LfcmvX3sAana3-iaHaPt54ASMM(iYu~r%*#H|9-%~7o!9V z<~N`(rbYV2JEUMf5%HW@FyD)!;`YCFMU}0P%qQU!$j159LPICAD!n_E+V>!u!zN9a z(p`kA*ca_<(J++?Z>C={8Py?*PqE0rLpcuk<03RFo@5qRY8Rpo<3mawUta0mr36PK zq0+lBNvTc46IrM;sMX+M>U(e`KfC#N3V!Q?S^Rq*|6ahqm-FxW{CgpOn}d__3k!7{ zs(67s3%DbrgYRnRGcJ0L@R}vzoa&4Qseap3O-V9%Fqx|FBLuFcGm2!YUd5*BKk}Pt zs$SE>%|#xjf?F3R1z@Yrtqg2PzF0d0x4uQW7l9|TQL7{HL=OEi?g@~!nhH(TQc%da zJ^*X=wEel z3=&Rl;e=vw&0&ePt4yrr8nJh*sD#ar;3wOT@|vj(C6|YTL<_)n&qOBMys2;D%|t82 z{SZ@4$?ymZ=-jh0@jd$uccS)QOsgIw`e53;XHHSJPElS6bDPZoZSWZSnb<2x7)Uc` z`DHl6+T(>r2)(EbUA*+P{X2&Egl7LPNB`oXQWFoAxrZcF?o4c7U1qkUb2lxZWSqXy zZ^Rni!{RanB_qE33>38{&_I+4nD$NVGgUWP6RmoxeAcrPB!ZmSEv5EKN@FCUufA%Q z1Of}1P$-CX=-wiRXVqlzUNi}yquS&}vetg<6hF7>(FRA_unyu-^Zdjfl69Q$(8x9? zFH<%qTRP=5G`#g+oQBUm_NeEevt~zv(2&?zWKKhLGmT$vLE<4=^m1MxV&EA|LQ0egAuY8K_k4) zR#bsjLHag^$9T|?22y6yBJi&J- zZ#u-J)HE=SC8YuFVNe>x#ssCoc6?Tz7cF2iL56sy66WGpYQM$84CCpISCQyM^lF8& zwI%c*RfGM6Q%GxYV!+A)ffIw2`)1*rz=>RKn#_ad;6kJ*Tes`G@}jWu79RLW4-*Fg zd#>_AGH$#N)2^G>6vQcf_!vNmZbSAH=C7&aSPT#2r81O7^86k=vNS)18Y5|*jBF&$ zPp}exWlHlG!{W|pT#%*&{UE75Vd6jRCf)^o)_HFV@lF-_I}_|gs8ub)4v3|frVYeH zGqVY>5YQ-ax_bOAj$CkT>xh>N1v#-1ZcwOaXONgAng_j&3spHv#bbw92~btR6=oJ+ zLsk0Ib0ZH?xd(|giG=Y8bi^V=Cau6bE3qTps%%xNDz2^cz6A=@#5pZ1QCx;!p$4g?Qtyw5mP0{wfEnT7{>|*-G#M%x)R|i);p_x*nmDk^zdW zK^A$0+=aigkBA~jeIy;jLnv+I?0I;J28qa6E3$St=krP-Jp<7Qsb}cHQh|30-kUN0 zHoTb}Y>e$7lRmQ?30%c#C$F?HZt?;R#0vu-;LLzdN?tISix-`tD?7PXT_+#zR#yez zRf1m-ij!~WkpoQKApsyo7P(8CT$PXIu|v6UFB0L^g8u8_9Q@i^2uccZ62c|2-Ji0f zn<-svfX@tkB&o=Qlx+B@$r`K4%t|R4uk2Mb=^#qX@3?Al5rRZ0TMwFeB6oUa>yCh! z0wo01KbY&cFb_%yLJ)O=xvgB_CpaB6vFr=5$8u&%#5~LdL}h|IoB#+7l-l-QW3`nL zv9U(zB(Di$^RwX7^jQL=P1<|6dJzpfXboH2FZaJ0~bmF%#*0TRYO)fYeZ8!&Wh>|~9w#x8vUXc@77g&7~4|M?{k zmYHYr1t5%<^u|Ov@&#bnK(9j64802Z0?qIys1xp@j7PZ->4F}HngJSkhyfAeF~Vb+CZvIe$@+m=XwlRUJX#_31L+>nG4fb%L?JPMv#B2# zPt#}V2Z*$=e&BBq`dK@WWp-WlN_;Z40}Aj9vsWyRVU_9J%W{xYXdFmK@GdH+@hY_; z))B}8lxb=T>R3~-0GfikNmF2ICPED@JTBH0G!PXH@eUB;$!!j%Q&*c==)fOl8cad9 zIXFS)T`K=f#2@GXA@AMeqpGg{;Ry*4ByfTt;FXBrg$RuXl@O{Rgi93&L=z$cS|MUY zMV-;uav3^vG?T+9tg5!+E#oF*y?CPGy%1Ws1@(p$F}Em=p$YV;qox=_q+B! zXU-%6?ejjr-yiSGhn(4G?|t@V?X~w_d#$zCf=&Z|q*bTvYmsXSifQoPt7sn3%wrm` zs!XN<*|DPEPR^eZeMVkKfS*hK_TS2zW*USJo2*Uf31iC)VH%uL6IlVK!JtShmMea-C|(VUsW*%Ye-~9Os+6O+-HvmVrPn zCWA(n0nv>t1JXjmGGK&a83;II>q)@)SOz^J?ZPr(s>?E97#N`>`#hFXvOkRyGFP%c z2084vS+vVCSTSDjYeZg`Wx%iz%>rw|l6n>Hs7+RBzH{BfnCt|fKoi_uNcq_rE#=SX zmqjT*`xBERwMhBTCdYwN{$GH^GNNzs@Ii6HJ;HIAQwmbK8F9wlk0G6Me#q`zIsbi# z(yf4I5!-IwNshzifRFmVa2>cxWjVWiTnFYM*MW20&vlUaOs+%O zMLxhqWTyDJ4*Vj6>%fR|`_q>d+IPuyU=~%kd%z~wf$NN)>%g|f8_80#2g5+3KF?l; zzUqbju?u}I%iub2)#<=>kUGB!*Wq%1sfv4~xDH2YUmfjHDz$~DgzJ!oN|PreLU2q*_B&;~|xj-S;;V6}6rz<6^Lj&c%df(>%j2QxDITZ$8|VL zgKmK>NDYPGrMV8>RfB}fFI^Ltn>rxNn@V_xl9u z3OO@|VaoRZ#bHTaq!k3EcK!7T)!%txl*3Wg=g#v}^AS?=#vx8g*uG!!^1n>i{!{1=( zx61zAuN2o|6uAzf{m&J!O^z9$?a)YBrpa~SE(oqex=-LbT)GdWrB+oSk)+p)&in^U z4mz?-e>#?92F3$R;-jRh^FTwW;}S6A?l7`t?>b9J4~^0{Ac~BL zMfg<>oo(Mwi8&b&2mJG76kfCpiqy#vNt2mECIpuZ#f0dA1WTAvtsq3&F^5`ZUCHv( zA!I`c4U)|LCIj{cE`)jTi3nkh$;ulXE^TQJ#0zyE>L^veRT11i#zReuEbyA~0O`8N zbl@Qy`q^l|6(@o0F&%_mBT>mEis``QR3qcnC-%xYm*J&8XN^gD!UncKl%yB$0hoNhU0(PTL_76!SDoI4R=$q}9k3m2*& z6&8y1NocV^=+?^=gsy1bz;kgarw0FD6T(FIf`EDLaSC&)nbz_aI~92FFG> zybafA$f!5COf80f)M5btf*5H31fPMa zA$y3hI=JE3kNh0t9TANHVRewau9L5Kg>;FNFuPjS!a`5Tsq) z8xXyaUz<};-+;J+)mL}cYPi@RUttZ2oDrZ;h)QeEinC$bp#g3@^X&DfV4W(UHYosby%U&d=RnlQoNUTd+>ccz7c%{lY`I3 zXXUv^p0CK$mgf$6J}u8}c-l8UvOi^id&7RL5Nq%bCz*xzD7jfsdJDm?*#*(s-<{wr6vD4rql(@D=2(cfC%ke3<#u z8#dKN;_MCTT#KJrqw0?8rt07xiDw6$2k;r{iP!~L8=yvce#FiV4xc(TcpPaW^ZQ7S z#F;GVbn1j`6wjWM2kNv#l)L>XnQkv((%iXe+UJ+oM*vDj85YZy3xL>S5p9SW3E zelDd<3tk>RusAp=d|*j%aQMLOhItp_Reu5qIk0IO2$wDi4VdlMPh-tWzNoo9RV^Z} zNc&Rbo=;G>5#5ewqT+_R1)QRkP8EK=5ik z8t8lSa_a)G&2}5Oy*%JNffJVctRR>Nk?*HyGHzJI%eDk#J<@=2-Xwr!nHjIDz(NVN z31Y^+=0KQDy$4OTdRkREk+xh1ZbbtyD0Sf4&{YbZ@E%BBRwAgiq6g&0`0|;D5m~aH z!4)Mqm*aO;EBM?H_+Il%+(?t98mnv*5-?DG6=uX5AHsXGM@&8}-itcd6WXXYX4WHM zO*s@ZS0kWjVoH``Or(@lp|B6i1S}>lUx3=5@pEWQCfJ|I3n#7mJ9-od4pOrsWaxq_ z?C`oQ+)@lDIFYXn^#{(T({`z}(vhKl8uI7~W;feb;hc#hAj=k5&bdpF%Vjq+pod+G7-RP>)jISajG;r z9{N&k6)9Od%%+t+m>e95(>=<(e|C9Al|2^%p-6L4Y(2*gEZKJ>`%6~z$QEeU_nnbU z#LK=cY@Mtd1~`Bpj-0VZ4npv|K%$=3tKpKOU{y+Hs3p(VtfKMBi>B2ezGtMV8+=!M zSt!fT>+Q)iWnD_oQ?)K7drqU9uI}TJ_g^ZnswtA-S^|(ij4`y<6QB0Bj1Qg%dL0pz z=ySA2CQsPglI6Y?CiC{TbPM)VX$5KwksGWk?!ARVy%aWbWEJl3ZOIE2S%=NND@N27 z%(Q1; z;5mC+a)LvWBWjCg*yD~^>Rw-|k;FC>fu0h~!D{op6_;BAY>?XJwLRixU!j)!kXC*P z2y%Px1A5hk)p&`9%jQNVtBlf|8fgx!0}e_4QMWxg0M`{bgu2BOC5xurmX)d*k`p}F zQcJ_hwFNWmWoI1;Dw*wXLa{i9q#7BpbJqgFHb`8xB^z@?cD?M|(1Px7#UDW?OX%2! z9nN!TMi&IAT0Tjc&oBPdT>HicNSd3AHq}M1*;Mxw{*GO^sct_0uEXE&@%IMO#Byf5 zOs*(HzGpuQE(e&On!Jw7m1f4@oe>Y(TGnUC|Cm@3aF5$+ljsg)L*c|4qzH+=8UdF?Z|euyWGrzXqGFAs`Aj^>WO-(V`j#YEg%LH84+g(X zW{Jd?;EA8G`q7P;gSQ4OY**nomME9!Qh9E~vwr zn6Tjsha1u75r|0RQ=wV4$HYy-sJzm?>p|i^E{m_g^;O1&#|#Udq52yL4O~1P6j$7Q z3K#rnSY*>?VKT;~pk%+u2KF^jyj_7MG|yM?C=_hPSt5#`std%GgP2J$#n!QVp);}L z*MACvGF&nYjYWWDWqci09}g&ht_2xaSjMnP{!jY7Qa-UGE#9tv-lGdb0wb6 zKOj=ZIPh#Vjc23tGS5aYBRL}ZbDihCaE|jI2=_{`9A_hft0YSpL*m@;GqAx;EF=b)QVNn7}IA_M+fxiDE(cX?(eZ3`+C!CAFZ>{@5VTGXe7s$jVzKz%1ArI z*oKnU=!?&yFC#29z^h+`+F#1aMVe(YpTFsRcm7GKFl^6V9)^znq%bVP4Gtf~>F_PY zt09%sVJov;h|}R@9f>KdrnB=Hk`$!!ou7N*0_R?YaiyK7!xeHmY{lu2kS7tVzr6{0 zE{6*uWfeI+Vr2na&&wgTZmv1(%MyDY#@@D7Y9`@D}0<-c_;qRmdFKKrF_D zj^YQ0K`3oq2HBEa(I|{Ja@lKWvBwAqI6=X5G5K3>%4!Aj`~r~N4ZFOoeUR083o=^W zT+kCvD_%KActCs{^UH|dFUJHN5NYkk ze@7{5c4Mhvi3hGR?)nu1*47NfHG_z2%OXWv|DX)9b3DmTli=csF?4%+w365R;&D_I zpd*hZD4ISh7Vj--JZI|tq;)*#(JnRch2X2AUKZ$ zG}|r*XlZTn-hErS`WVr>IPMzxFGSdiKaQMMmNhFU(wrNUH>WRJlF_)_S$6-qDE)_8&pwsY5bBv=hZV@DvtsLLNoaKR14*ArJ1LufsR3b!5cn% z2)$yoB69+vg?i7-jWpp5E^UT_PJ9fqByTE_5=dU~ljk2M+~w;PO;#hL+%x}8Kf?M5 z8>ooFL2bQ4+*l*qVeLxZt9DZ?M5kb$TSD8UHy{9qwOQkFA9fr9dfkOdE4)A=&t|8j zHXQs}A}lN5iG%;;;9FQSt$FbO8^!^?vNcqAx|j94!oJf~Cx6xd{*W4{(>_#b>f|rW z8fFqs{)A(NlM7r{P$asxnNtx9JP+v8|9^uE!)5GmM0uY6DQi@@&Ok1OTVaJW*xrC8 zt;pFR#qjiBhvIPhzXLyQ=3+d7Hv#9D$fIDyTUU1_@tWOK(kSR2(xgYpIb7RNTfpgw zk0AeK=W25t>Y4&2QCsi|jgHZqGYfpcU*NEe0x@?2&Sn(h7T8^sy{*-Xo*^In_ZT%ex^6-IA`zOEGbYE~PZrj)>Tb2cGw*Ck=87vr_QlKu?7 ziwl(CB)60;f#i*B(Gp!w=hbqiuMFy@yJdt%dT=nJv^u8&P&LcGwaS~HBLQk>E=4yk zfp>rM!Xwr-)K}N(zPf^Iz0ZqxDjXRf?21?8qN856*8r9tuZEK^u>4eooEVWn@>{VI zy^+V(Dk5zK;v+)-xC|VA<<4f8fkV8DH~t6dRhi`}+0*?z9L_n#!}-b2G!JJEqI^7@ zsd!a99FqkJ8%J6XfWg8uQo;Se6E>Q^Fk+ROi3mUlF zg81k9*7=fi4D)y-wPk^X!9vTL+^%c-G=hZmlJ6ra)XEebUE1ogtfh9@Y1J;6?A3vt z#0+33on0b*z;}wJl>V**ONj}p*J_c?3gK=gdw~VuHI9jp5@0kviWf^ZppD~$=l3lJ zot=F=CPrd~<@Z*i2+z2zOyvIH#r`2K&?_{}t*#E9r-B}@X~&==m9BX;Qaa4vp(ya0 z=HSQWH4#pJUehGJD_&DWy^q(#X!4r)tC>;=*$3d;4IxuLU>IK*blBEuSw#nEjd>-^zg`kvkF35lEPOZEAQ3v7uT^) z745c1@RAj((s(_yq;Ux%mQAtNaqo?ra&Vk_Xj<@;X~7ex1qV+H_MH~&JuPTVn`W3F zAxkVjvNbo^oj*B~BTe}+`LI-qS@B}ZB%&#F>$bdSamuOrFLJupAU1=KW69vob%oH; zyU6Lfap|VIhw!%pe6%aW<7*IGgnhDUT^@5f8>NtG!I|Oxi-Q-2_mlguAKZsEh}Y5&gq&5(2HAAJPd4o= zL8L2{zRC+1IF}(TQt81Wl|D8@D(#$)RB#-ac5X=0JbAQp0@EOgK9;{Y5*@=|NTR#( z7n0}$ASNk^{(`?a7ykplu}0#7Cy8!$CDE@xq*)L{l`vXMn>T^7fF#;wbQ{s3_&OuU zJ;>qQjgpBF|DHTLOnG!OcAT{+lsk^X`2UeSnr2{?aEIK5|6}s#pMxm=I(hUB$Rm6R z8tW2yG|cn6^61q}{I}%M@2_&X1Vhqd*W}mAqfbLcK2-mA<me8B$A()luZp7wk|+>EHev^62*n;G@fTtS|OD|aFJ1S5d-Gx~CwLklh3ZEhq zOmbw3r5~3pM;A-~^_U|;CA0k^g7(DHH-~sskT{5?A3^0x2wl9_C!X%vu+4cEBIy#@ z{CQ>|5r8wpW#33n-THk}??!Y}-OwLws+*0!C-8R=e?20b>Mp_GHAw3yr?xT#&uKaJ ztr_ti^?qfC=v@0L0^|=EELa+9hS{XPsd*seJ(+b73w>H<4Ykq?q4ndiY6}e;J`+vy zY?tSo^88Ak@5}R9dG5l~9`rp>@_)kv=Xkt}%=&G-YD)e*ct{B+o<@pL@=qb)%B&v* zIc{tj2#H+6Ml`H?$#WZ@>psP^ru1ziIuE&OyDiAx2W=R{kr=~|vAT@J{KX&FMA|80 z-r`d)rHHwcYAL>Ct_ue}m{b!H=26A|UomK-$#)?D1l zWLwPljM%weDWKmO=@cLaH@Fd`v~P=6E|sM2%)H?%Bn6!PpcSOx(<2!LGnECugLDlA z=T8V*CR6-H^4)n7N$h<4v|v@FeQ|Jdq#aazq#acJPmrWKB{IZ%yw*e@L>!d8Pe+6C zsm9E?9*GeFK)$oU3l}&Q2!rboX+J+S1h<5{QO&e9M}H1j>CeyRC+)>5kBAa;R&5~s zQY$fhf)-A$W|AA+$;+%LnbV7}*Z(HI%oz;=*Y!Vjzl-Tg1*q47c^ znnWlb=UM@yxwGJL;9h+S%9;#=iTtcYX0j1)M$Y6*Le^6#1*k;VqOnvp{TGN8Lg{D7 zVr+qlTquN3cH7rT*z1MJ+=y`S;(GHH{KidI3tu<EMqMp5^wy2CVRu z;M`$ALmpAdo;A4KjDX4k<9P_j8h7LAoPai1Y=Wv1ywI^qI#;Z~>PhGLP4HMq=hE2W zyhX}=0~;K0UPf3G{mfc!|MABp`kxZwzOxeQFC`vCKMBwdN~m`tO@Si}6Fw*mcr8Rf z$CjcwD4`a6O|~z7K@t5w5TakkUzAXZ%36NLAeB%F4WgsN(b3qbs=$H@)-6AFl~C6p zqm^w{ooDe9Iu@(RwV`ViYO#SetoCkjE2=uj;Q`WlcKc!v_Inc_)6Cstg~#PEee?XxKI zgJIK?qg$z!P+1@cCl=?Hsj2;ySTl(3o)Ri0IBh0#oPoR zvPPO_;e99GV~O|ibV%a6G9p3~4APfLbZlSOl*CE@@rVnW;F32inwliZ1E}vbHH@cuA7U zpPs|XV`kPwpnpnjRSf?Zg_8byyQ(3Q;EVxx~nd}RxKu&F8 zvIhhL18NK0A%tQ#vJzUBY}tkDiJpb)8LP%WFErFT2p!Lp;QvZCotgINy%!8&SBfi)Sj%XU1CVdK24-1RSKdL}hu!MIyZ8^V1*<<|on%`zBPFonVrhRe|ai zBa*)Xrw}ozkm^lxXQ(Rfn~#Whv3#$gXa?axXiA+xAIeH%rZAg zdj{+uUq{kj;vfZh0Z||N6TN45xr{nD_D-xqpqqAM!=wbqJ%@diA3!ZwxcT zmh)qYH3+~LjXbZE=Q4Rd!DnL>&zjPGu;hw$(Ms^EWDiTCYrDv7k^Xx6ea;lhK0Q297!zwW>RH!)7$oSyY0If%L42P|tKF$yDl@-iAP_NicKO<*#+X z5_rRrA>MGp+438$W%?cYh+3uxsIn;|7NGc3nh9#yiv>_lAW5P?0apn~adHvElM+V< zcrz70u#qlL88%Z;&J^@BmmuD`7oTAuI-ZnT^hqhm`r^!=>n!%dInI?{ILj$Vc$MS{ zV{DuWcGE=4Gz`1rCuZohGcW294y z7)#RS!1bz%aPsR1-?70kwi4;;>>t6lGO0Z znen@L#Z2Ux@t}^zq*l}1DMO+{mwczh3l}&e5f($ua%Nm9XT~<1895LEV2%E~2R~6~ z#+BW8W<;J1%#&IPM3$Ar`3v+uF|C57q`}XJYFzM~NP7szsN3s;XMnu`FN+&Es{)nr z#?|<36Fete>?kC;&M!obR4S$#>Ah4VWyf(;ybXkk5&bS_74I2RGg)a+s^elyaA{!+ zj*GB>6z8eE6~{%+FqW;BLe=&0?rb%wHmc{aVLrf@{ZL4%LBMLxz)N!s;@Yw>`C%>O zDH%G4PFeQJROKl$bh9eFAi3BViQ^-Cg5x7cF@1b2-dVDaD~4hAYj8r>@$EP&=4QiGH0&4u{IsQ^zL9Qgy+Qh0g?N2Y_O zdX_)-2VmQ&gJb_TS>|LR=i!m*Di>7m5NYY`}~u$RDno1DiLG_-1{PHd6Huu=_WQ9O@B z$%CD(a1P_pt$;_wZ8PT}7DMK$hK>M9&z0#tB0p6_$@fvY&Ok1;ZiE&3VE+NaJcFFI zawfkDMZs|jp6X2gU4-Db6Hn*IERKutCkSYKzdi%ssTYcg7;vchUQt<_?Z6&p09c7y zg4G%$qc^(c+@CJzv`*!q$pPmN_#EZrC{0jzgp{70s5dK((3S$N5sE95-%-_2Ba|bq zDJ8?z2$c>Lcol0+P`Bi$C@*>%p)!R!mgH)LN=eiORiJ<-XopfnBNQ!KqFdCNkeMlE zP#08#b7Te>lr|{(p9M|r3U78^3g9~P@KJ{ftpGJbRhv84HB{=NE~swr+D@NCBNWZ; zif7_tpkB1sU`g?`K?SdupYEH?qZKXX?#8hP6$!N#gBcN$#O0>&Q+LX{+!Uf(yzv>R zj45&}B?P&jo5J~`xGB*f_Ap-S9fK$zH-+e{xhX72xGB;FKu#@6u}01$Bg$!oWyDnp z{TxUK9aNSkPf-c|Ga?0e4tS0Vcrb#FaC$9I@5TH!cw^~SkH^f2Q`fCwky0mF%nc|} zv6#aM#p9gxip9Kmxu3<%uS(k*3LuO4hLwPp4FxuXk>DFHPpo ztSQM4_Q-B2JrMe;P*TbFVGWw(;z{Wdyka@{BS$K6nY?Ij5W)Ag+#oInM~ZM6Em-+#qgnGwsvie<~t}?ld=ODN?M&rFh0o77WUTne7`fh^ipX4Pw(W zxIwDSolqUkEHfgU0^tU+O^O>tXvNfO9w%mH5Kt~Rs2mC42K`#j$zbJ;#k44(D=%*c{;ou~O9|aFO_(>d<-si`*dQ6K;@nNO6N0cZuCIvn#?4;sz+( zAO`IED$Ilp5?8Hw2{Jp@Mb_S^xSE|Z%qphpB5ZCEqFSWLjR2E73+Z;L&y(qSqnNS;p*hEu^!lV zp(~0XY@y6BCDNK-Dn+l@lro8Hs?Ki9`&hzjfyU^)qA~gq(lS^xmVnCB7@a+je5yAe z*i_f+r<>|Z@pm8oRz3*c6#gz=kGP+8=2NY9RY0{cn(m%?H#(RR@A0YTWkhG%J30qf zr9pzj;8D4K-6!ZsS#CF&JgUYdg3Y78wHMhHh^-c*M{jmEdent<8b*&$v$Y&1n#q%o zttV>|s-E&BFE-ZrraZ}lhGimolI<50A(DN^Tu7&nGVH;X3jE zX!MAFUE%EjnvhZ&nYXdVSLFFDpK-DfYf4`=qSqp4ZMXT^hsm2Fdl7n2cp9t6AR#{M zV~9+IH|5hfwbrpDpSEdjF1S-yKw}fpP%@2HVRA&;dm4AWfpa0)InQkFLSQZZJd(ir zQG94@5q;CCyzx7_aBFZ_VQX-J&_2tM+G`yF=q%^SQ^YPc}`D4r%$bVZMq@&IQ?4gwtuBY+BWjdY+I8 z_Rx}QpM0A5Bnl7|N*K|1K=po|eEM_bQN+XF5%SBY3!&{J7lk{?rxVDj<7IZ(biK=GzzV~8d^7>| zacF~YMu0N=Hw4r>aP)8m)U60-2&j**BfsGH%)$$#9{^p9=!)5LIYUP?IKBfAx{X;@O?_i5QQC(QpP+4OyHlQJb`lRk|cNjCj4C{?vO z99=d&sZ*Ipkxg?*U}y@@jAhn6jc^^tY2?HjSy_)Dn|=dIrLJt6CAp^&>DEzX(*`

rmhzmtCp+er8e;qMvzJ&v@FdZ*vd5I(16)z@Ui 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�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 GT=X9y&Wr8< literal 0 HcmV?d00001 diff --git a/Core Includes/pthreadVCE2.dll b/Core Includes/pthreadVCE2.dll new file mode 100644 index 0000000000000000000000000000000000000000..9d148cc0dae8c9d0f4b4bf73d815d33bd544b2e0 GIT binary patch literal 61952 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 literal 0 HcmV?d00001 diff --git a/Core Includes/rtlsdr.dll b/Core Includes/rtlsdr.dll new file mode 100644 index 0000000000000000000000000000000000000000..40cff2b397f0e1ce3376bb743d84ebb79f4c5a5f GIT binary patch literal 44032 zcmeFa4SZC^)jvMF*(94}!!8&g^14D$lovw+3MSO>vH>c=&D#dV5JIwHvxX#1b|JKY z8<%J{*KKLlR-W35)moqa`fCweK-=nu00Cclu^I$5B5emZ)*uuDME3tZbML++B(%@- z|NlRq|I4#5_s*Sj=FFKhXJ*cvnR}D-z%~}e7}FpG0*vj&oqk#3dgDtsz(dBrHiZ2? z?wwoqs+PWUOM$Jj-dI~#v$n2uow2O6y1K?;Tw^uXIjfD8)y9SQ=Ns46lv}4KCdQ{I zq@Vq|z9Eyhe}ZSZ0qSt{3$pO*7c2Fj10AoC)~1Mis~jF~CX$Cx9UBK>|x7}E}v z-Vd$g*?w)bjj`^2IFXOj9o7a162A3aTnq?QS8DW#pOLZE)9cDh9i@!vMgstvYz%@6 zA>x;XqNmGf?C}@?b|Mh1XAmNOS*Ydoy85~@q=~xv5Fz{>2ob+5qE~0FssZBTRQDqY zg!dvs#4n4n`4Nx*6aBwH0)#pu;TOIg_y>yV@dkaJz`AED0UF1X1_?l#*2mZ7Y=`Wculc z=N6z}>7Q-26nQh>Azkt&y%BY6%D%Z%k-jB*FWpd#SuVoDXUbf-d%keSmbecERu#7u zS@`R7Pyqh|HMrC<+IOj=WHHi%RS|b8FGsg`ZAC@JrFDkZD{5(9D<2=VPb$=!a~t;& z|9Sk9Ag-gV*Vq5M{p(+RcEeo8!tyFUdpFcH@_EsM$Y;q!^0c|UE15Z$k2aA^L|K#t z+6s9K7@LjdEg<+qKOnyWPJ%K zm)|3hf-2D;Zdc{f<2>I=8%cRO{^7p+vJu~EC)Ro)y!uFZfhZ?Q9b zR^CCAp7A@@p~deHVVLx08x0D;u=xaIaX@G>=}Y=FG0NBP&PmemHt7WI+=|vtt$xoT z2+3QRlqVG$a;3$ZybzK7Rg5+HHjXpfdY@tj8^vGB9aI6 zyN?pNiiCY3ktyYYyj&a#*F_Z6dRps#(-`0NQGi8f zKp92)-9G)EuU%JF&gkYGonI>*ZT&*qT&RPf1#9}<$MYcZ=A1-tjxN_MOPcRT>q^~C z7dMWx*k<2=CA$j$;)}R05C}jZ`rU6y2dA`_T7Yr+c%3IW+NYe$B<>6WSz8sDZ(h&43wJ&csk1XhO3|*KA7UjSevw_ZQ+2Gw5Sn-v}NQt&`sK7V7dY9Tmk^Ol;Nf@hOGN#Y)*4 zdzP6$XNQQ!k|uzGQD)mf3>=3{P~RxID83%$plV1|iXxHAwIh^@gmybaY2gaaMHx4y zUb0Gv8TFR1wia}*u7tMpI#s08~^o00kx`jA(1z<^$YLV_~a|cu_G~_t?(-IKp< zicbaG;r=nLpK0BPjo!jDdG?|DJ%@Actl4y?+4NUwfoSblFj)ON9YV?vYi?(*JzkN# z7@P9=I#7|-^+x^NeNE*|UE~fV=^rmZzgk(6?pr10^rpYVe@R^YwYW`8ZF16&lq5U> z@g17;_!cECINFQ(!`-D7{ZCq^DGFBG)N8gGAVwQA%KDL8(QfLEi{ty(qM*5?+|pPY z_Q3RrNEJUW#=#Gv$>z z@W=*Y{4ds^aBjrgZA2|%_!8|!)JDkEL`@mvkNsQJPV|UDx82l39a1v&1P6V$Z-iZi z`P6;LD2o!Km01`7LY)}D?S}Lry$JR0+XHjCzdTsea1RW(0=UTXn0nkjG5SaB=z11D z@v0)h5K)q#!DhTULW0rJ{D~0Vfg~8L8ksb`*NqBAp}Yg~6j2{p6`qLD?Cx%!9Lhdm z(Gi;6o7YzyW_}85E4gP5SoC!|{bWQ->-GF+q3i<|9l?38xo^?Ayfl<|z@j7AmQ{9W zgutO>6GGVsEINYo>jnO|H8-qv1lzK}H4y?w(Z331AF${M&aW5vL!rC_);fZ13?fjo z(g=aCUd^Y5vJY5v1n1Wayc@J`(AE)b%NiaNA#j(AzZ}XwV9^nrUoUWHDDQx^j$m6B z_{$LjA3d7i70Nzf(Gi?qFYqg?Z&>RHwq=1QMhM*P=6?)jAF${M&aW5v!=bzb)f$!? zP37_&t=Mlx>4Bz;p_QwY-O%K7Oq|o8ag4L8EPUie8jBjRP_YD#+L=Y_;Tj~l_a}uW z;lZXaqmiF05rV*yW*|#7xTKNV#li{vU_E-N!(-B&G{J5^mAD-CbF$Qb+#Jb*3H}_z2@u*L% zi^pOU`R6P7mu&LnXg~S-lh%_a6!!0sNcRyDF!b?>bl=AvLW#hyyK79?{+3Kh`BJeV z=z{T>&NN-rZ~ZMXoULi{>9;%|5$}Q zg%^btp%bY^d1n4=LO&To%jfNcmUBs%2QpfIZXS07P1<~>55b=iCT4pwaukB_cdP(r z$*OeUO4+LY6J;cs=ky|#tlE|QB_&N+Z&2OPSz=@_4+M^-c#a|JP~&A{eT#N47MA4y z$xlC7gqnT-S*rYIooxR{8VO`EVyv_60D_&h99I__U^X@vYWeFAB1^>R5|<}@4GN~P z>CJpQkXkeuvrTc1w9q`Sn6hEAVoevvtAOn8Q9H-jqXWa?NHq}O3o<(NkCVAkvJ#d) ztoxOFvCJagLk2wBmsV6w0a4$Q;x>3P4Eg#!#Ys_Zb47jQR*DJ(G=Tp^;TTNtFW@AC zssf$L0J&sqAD0V~jf5)xvk;s*(hcBQj=n&-e>QeaMmvX9{?$dGviB8SEU(YQ^|ha& zex96ekLiLZ=W&l|+uj36O+QR7$#&CD44i>>)9!Mr@LZT|g{H#Ci}b60u&yHj5axj{@67OoQ0ZL`;j=i->ue$Zyo% zWWe=30ZBsauOgO=*fkLwgIF?2x5!G7!diqH zB?NmU#t$(UkbU9El?{t;V}{VpX)rh@l5z3cmx^&=$PZZ;FCxvoKN+J=qUYz-6;{gT z0o~dkr3CuXh$Rog!P5HoZ^G=`h5PU`TjpoRoQ5RFt;EZ8;w8s`375>BtfbsLOW=rX z@Z2O=8YA-&F18Q7nKHd;a~hHz6Nug?T|`e1GbiU-0>@-p?MO!T`qQFXfF2rK8Nae7 z_hnv&_Z^Qh=vw-?-kyZ(O|~d+rfCJPw}mW9_Pc4DO>umU1x@!~@UZ^+tgwoNu>$96 zpV3zE+m9c(g29rq628H(ZcQSjC*A1BZ4pgEPKjj_$ylh&i-b?w;H0{^r-g zCrTig+NuTF8J9NgmQ0!cH#;5{1>O@n6!@QMHyE&y(F2=P*rXcHR#Oc8bmMx(1L;1AHu0YQ zMYXc4^7yamNfrZtn&M=?%4&0#9)oHFeQE5{^pPh-~wBgd7Eg`B}W-HT9?WUVgQ@r^-{Xj)?&D4sB_fTV~$}hX4O5p zD(4WlPwj41Z$0KblkW3JkM_Ac0_X&zNkqF=l?by=DQcR+3HXu@uEOlIl8=h44)xc* z_PG1?nW!Ce-s0Y3WR77)(p<83?W(|sl;FHrV&U3zBt#8V5u1Yi`?(O$GEFYuNRbhF zd$&zzT(zadxaAi#fRL;ve#72zchpPf7`7cbV|!^ZN{Gk zHQAvOUQvgAiHb2F>Ob;)qKt<*NmvEiSuSR!JjtxdwKYOmdHe^UCBOSCJO(XWHF#TrS00Y4a7MyK$pPwRP~Q$xM*q)V*cvo?85TG^{{ zD%ysDk5=LT#zJ0Mfy<36>!aYuahra3VG?W?G4YC~rLAAFz{HjkEx;<5Q5%bCF_b-I zZ#eE4I6tk$kY6l0^Z2dTk)ZnJXuUsthUDC(J=pjpB8T8+m=|1{j&Qs(wXA8uNN_Qw6V($8by8B0aIS1A<-zhG7w@~~485P*}93Z=@Pny+}u z6rIYBa1Noz5AGiV8*sOU-9V=jUC>FWXdkuw3iXc+x=#) z{bsUwyFSH`PkW(C;wU7-UHBIyC-hKSo7p~^5ZjRA-k+J!Ua~S+H>Ewqdcpl3Ef~Hd z8`O69mRgqY7>Z>>zJ*^FQ;b&X@u#{Qw9Jt~-wwtxmTT{MIR$bWQE(AEV zpl|`yXF)*;^c!G7F|fR0g3J*jcgBm(E^1I@ws=G$zuOOk<6DshoL1(3-#>{ z+5bjwDD3eJB`tZB6b`ejg?E5F7GxMv#z~L5kc!DuXSQ&kESQ8IT3C?2$Wv*gc!TrT zb^cyjk~N*wZzZPt_(zgi^0_Y1e_C>tE+I4@)27d|FC1Ov@*JSFt-GxBqe zT?>x!{63!3k0tcDud4Jv-)C2S+kM*L{=$`KkD(gv2GqUZoNs#x+Lh3A{fQTyXI1T4 zavgxTTjtDmjHNPNq-$VJ8(KG33#EdQ>A-5(F&o=yj&!1b5M~UHL%c)GDhw@<85|v~ z0eDOmT%`KP*~}a7LauEh7iy){$spikK*&Xeh;!t+0&5!5ur&|Dy0$&L7U)d+G3Cm$ z@SDG(4BC}Y{YX!nJfO+rS%iO4u8V%_uaTLy2e&>)5%dR#Ht4LQwkyK4I#OCT`RLio z!-Tqbe3L)-(r2w-MElk0$MP(mA5(|mf2Li<9taH#K$Lg88+6PugM^v>iQo!k;-yCk zH_GRalCmdDmIkvlUnj4Fd7{8F$ZD4%@Ya*+nII~V6sorpwUT=U=0MSZrbZg?+I(9U zMp=)kL$(W~4h-vLe|i^OP^`YY7eicRU=|5fJIm*tNP^CLznA(d&FQbdgo9D}=YPpx zhx1Lk$(wU3H?Q4ImLL8z{tKk0U-X#XZ}M&V4xD2F{1pGI>6DbYlU&b5yc}2&#=SV7 zaf9{Rkg$Cp6)>H_T5wLG&M_oA!}r0vqqe zG6|>L;2x7^(cy+7Thex%@A@F}Y?sa*_{Qn9?R~mGK?756a|%tG4tg>%?}wyG?*yu@+{Fn zyGSE~8{Jr3%I7ASQFb=uwJ(^;9D7vQF+YRj9RD;?m)-cS>-K(RV>on}!?vR@OCL%x zP$x5wLy7(v89AT-4joV$0dY>(J2yn?q8kv+foM15JR}p`P_6u4Cjdb5rRSW5qp_pD%)>>0(pH92&6ph-aj?d z;v8$!4MYiddq3ZWFIF`D3v?G48b9MWIO)TXCCZW)5l+POYg<&iWR+)B`a4+u@Hrr$SbOq%ldM{4kxtq$22=iYDLWb6 zbf~m!j8v4AE8TC*%MBcXT(M&|A6r@Nk7kl;;kT-Ip9bSYlp`H0U-e!}^*l;Lq%+2o zZS-WPNJY9l+hiJn!hJ&7j@4mmLT<$$22TqesZI~1pKLc>5QH}Ocs6%=Hg|hA_hwvj z#+R%T-UEycbG8^A$So!SvCk~KYdqP>*cxolHd5PqwxoELjmcBU@&GgDa08orePY?q{Z?AS zN<+M+3)m~%uF%++;J$iM-}DGT{s(}jau(2f87J6~!W`@5rREIspJ6@f&U_6k)z=)O zC5GuX%5jsKe>=!bEb>rUf~Vs_--Xe=xtBRc35SK7U+yL~=`HbCjPU5lG6h3jU`Pu( z{KWNe*_Kf3=>gUYXcKSq$RG9w8ZVEuPQxL`&0u0~=Mx&XK4I>TKPEE$qYoiPvP?Zm zYl^00!R_IJ*99k9JI*Of;Uz|IS|m0RW{f z4Ll|b%-;{gL>yP(MKS~n0B~tn(;j({PpPey8?a4owml2(UZ^76-Qs~w=O=+=9`fb9}C;bBinCIjs$6vB|j#15C{a$$TW36FzfKlZcl zv9$9!(&i@D?orjn&gC2SsMg1o1Z}iA*;5@OJlRuW>;a3cxpvt?g`sFN%*o#5xDVqF zY{9AWng;Fwizj;%&qdwAAYe1RKc>Y=9^3FJ1LVAdP4*+2d(F#^NJ*-Y*$|0Kc$NJay~xB4Myusa>VdFz%V6OP|= z)EP_L`WTa13UTmU+j9Kku?a^eoY3!Hrm?HzkCV5qxiC($7$L*o|3efNaWW=kkLP0a zJ4Yph#n^rvZkDqVhjF1Hus@eihmba%BnF#&4HNXc@5f@eNZsV@nLi8UfP=hS3Nm)oHE+YNRU?4zK{Gy$&Xbs@$etgS$=R&A;Zp zV$eVGJ*c~KLMehb&3`b1?4SRC5Pz8EsB;RPS-SxHp9r-GItVy80?YkT=e`zIr zfSpPR95e;gI6m6Ez|eTv_3U5R`df-@wr2*O*p-I2DC;4oA!Fu&>Op2aVpRf1$%*DKfWyZpi0lNX8*AY)o3V)4`sb@T~vM5rfnL z>b&&}g9U^Hv!iqlnia&>s*o;f9+dD`aOA)$T_dFGOFLw%Mcs^7iHV8{@DB{YZSw~RT^3y7?&AwIql%zl%^&;MOaU?E;GSN1{T!v7ybaycBiqP>Nc=`w%RsoocR<(fd}K^dZ=Cq7_6R z@7Fl0w8UjYcpNcWK%Q~kthQmG_fiu0PV&z*iUuemtDrwLr@QJY2v#ULZ(@mv`e zOoj~bimd$VM=ZYpAKw6wXvRMp7!t#{Z(zuGf6QM51T6DvOv(dL9c$oQ2hKZA!|ek@ z#*gA=K=SRQFnq=QlVa3CdaFZ^nc(<=^dXVns2AhaRM7}p$oLNldcO>fMm*m>Y^Ra0L_zuX zX*;8Mu87qlwn)UjgVp_XlX9)Y&Lzy4cO4c(igK}@&ee#S4Y%+ z5cJGO&%i{9?gd{`@YM3xsd7?iC=wAGkGlH#<1JV%nsHLwvzhayw2xM(JIdkdf^pY) zW%bEf>iWc&SA)+-(oUXz9PBk-nS8(;Rj++HixU0cZM@R4>mf~j{L86$o}YHoZ*RO} zZh0;S7^u_b`TpgNS9V%I)B+q}__0pr%j zD_OTcItmzCO7SP*8sB)O`}@Tc>tkMy0fy#f%_|s9&*^{nHF@0|ud%Blnm)g^9- z&d7PcE=DTsnvV^T!Y+CtKdR-B`Y`>w#|<|m>aE}nSd1y?kEDz`*fcfN4)aPxvsa2d;-|Avnky+4l8H$6) z3SJH0dpu{2;gYpm`nvTqefqK1f5b?wmoC1>vIy#{0FTkp%mtcS`&7z92dAj%hcI?%ifZ$qLW$ z--^{cG)&+886+r~y0RcMY&$)y_8%sV>{c`qHeB}*7vB=be;N3|DD2LY$q5X`9}Hvs zK*k6as9@X^##l!fZ~>fGN;zmcKZK78!*gVK;d!MD{;e=<24F2Y=P^EhcJCY$*Kd6k z8sNH|seg1--*R1_U$UU5#WWY6n#mp#~Uz<>TU`LeSjn_+z~HV=*R>0i@r) zk4m4fl>YTpxpbH)X4?w`o1?Hs!79Dzu#)dn@UI&$@pFe;q$jq9_|8w0Cro{ZlxRTi}C@R(rR^o}J-Hvs=SNjC{0 zm(&zp(E0N^Lr}0?vCXD0xgR@s3YnXM>NTA=?@Z#+a)pSI7$T5!-u2n|voC^=#;dNI zO4B!Bm3%%IcG#(2AqztM81s@q{K^8r6Jfx90K6E4LHB=$Q-2#oAMZMx+X3gPzd>*w8R+K46Vkg=wNcX!>$BrjpB#u(R!=KEgPm zDKfCd&uv;iiEAp!SX^mHf-9l+GlorqY;~@AG&(5x=G>yos z_QxZx7I4@#o4?fm?rQqU4cf+lFl-WBIagrW(2F53Cpc`0y!;|QW-=K!9m2RdBO5o| zQ+Nu-&3iCz+Q_)!WZWDH8#hPDxH%(?n=}7y+>o27QX9s-c zrQ=^u{p||AJfF$)y|OTu2NyBnC-NU)A5ESpqp@q?$15%ov;MBWz-UbU=>hV6(8R8V zR6oDeZ(>iRi9G|^6x%5hj9#F-DIT*ncF>XqWut;cY2ruua0@6#k5n2ojJ=AqujD);4NN1W8^?n$oW{@D022Qq2ZC~S`4 z(A%5TT>K5Mm5UpY&)_rydjb9=c&g;e;(cW@T7Cm9^;%Y^BX}tnY#ueo;nmh-sdu7owpB=V_BaZ zmB+I6YM%p#SD;PY`+X=bp2SD&V`sq-M~9lf&UGAu7ZCT)f_v%FaXJ<6r!1U zjvoYk00?E79tZe~0uH|n#*gi-6VIicgmx9`6$1Di*qz)B6uB?p6#@Tkq<#1zm?(h% zst+uoB}dx$2@jD+74Zm*u{Dn3nN45gAZE+{2}u?vE+M1?VO z>Thqo);95+>uR+AkyQcsjesAlqNs?9e|l8#sI-2G)H?B?ysH>iDd-anbQrZZT3=$| z{wXYl#n{%BKUf#($_(mXaC`vw*fyscThdOVL>zwL>rkRn9P!gD^KT*Out%lK?!T+} zw+BZ_dT`=pe#hYO5t)F;i%Mk;Qp)&aK>7QTLAi+g5b*ZF;R$~M{8xj+b!mV<1~_>% z<;6(z}@>(n|x>=Qo_q{iaL!EtxQtYnGF2$dw6Nr zq+5#7)PD=T<2~OT(gYdD$o~QyLSL#Tru%jX3yS*#;56>YdNuKK|6=ZK=06fBLht%R z)k8p{ZgBYWB*60sev+zVFx#~j{q{C~=T(wp=ESy%p#h!rF-Pa_N@~1JF1z)z)55Rc z>lziqGFtJjQ0FzgK7`Q^`<-vl$cHlvu^H`-Xs>Qb)L}XsaisFt(@2jx?8)iPc(X3r zv-yI5m~`Z!V@osM9DU4vTJ7Ga#-?TZu}e-|aE!h6D8F>xJ9BjFKQ!sb$Vc?MwkY3} zL#>|~$nnzZ*XV!OJ>^|^!!q8g)4(Cp-MG0o>o>Q-J<9?Aq z8C$I1`a?C{ntqHeH%KekQQ)Vsz#l{1;kFGt>)k=sbaJ}fS;h{Ia(fnp`pr9ol1PmM z{A0ie*HrW4KzVI&68UDp|6_1?i5~FphT*c_M0WbpSpL8bSy;nB;_fgBQmse=Wy1j< zIXHZ66yTTM9#jgpXuv-Nd~hjL8i4Zq!AaPM0sdqdPObNl)~=p-Im{||gyH?GP(}T{ z;D#)$YXHiO!AVrps55kMcufJ|=iZ8(>+|ff7IXmqme^&=JR1x3yiOBoh15HxmhVQ^ zK}NHwcgvdi#Na5?{*Kb?2Zswy%m;k%Hdtr`iPXVK2u(E%4i}o*{br~Z*K1;lo*w~x za285Qng4f~ME_NmS|pj}ODC_3T6XY2p`$ zLsIBpg@?4r|0dvrOF<~>uLdWvZU;y_HaNVRhK#j?!)s_NSOhq%(l8f!I1)$7I_{su zo9^rbSl>q|s|DjG)pb%g*9}hkwhgkTo;@_E04C?7^uvS0Z(j}ge*zw6t-lO~GCw*v z38ASKgTsZUW(&BO-Nn@2xLLPtmX@mAXYebzsgB$Qy(PnWl9B_y`Jg>8m$K;HZ(-W$ zpAp0E=k0?^VNDEb*)}+QEy1539Bv~uasxiNl*E|2dT%vQ+gKf| z|CT+?C~lB*ucr7gyPYT%AnxA3cw$d~(UuM8&GEgY_drELgp$RW(^%B3$Bl7K~IY*yV}g(fg1H$P09AH*F&f1<&8ePqZK3Y@iAy^ z9>0p6=RP^YYc+}?KhB4kba?xL+#X3q7#`4TnDp*OSiq_2zNW)lQeGQ}lqp9t-rS;= z-h`I`Z+jbZy#=#1dHm-$iT9}du}Bu@(_^LOI`4gfjC1Rw?(?gqPb5=sl*!OisLMBd z7fm!b7fs-H#)aeJhF9MuE$F$slEeOd z9QAF<(H42LC&GE}&4!B$2Utg#n{hx;EiJR5+AaHpGGH~Pf1LKMBzRM~ez!J1PqNr> zdg#}HOWjbHjPs5h;x*rFu`MM5q~LP>s}{-l*!8dyeBD6aG|Yhigm$XLCuZcN$x0GF z-myS(a(H$x;V1#qYVbL!ZgqUj5PB&iE;uA#)k|0PyEQ|kBkt4smV)73zSEjk zu8A**?wWUhb8f(S8k<+x^Gknc6@L$oAh9bJ7BS=@yN0YWo#>;`-F^btLZ*IV_Oy7$GCl&?$+qJ-4IFLTYkel3eZ zz?o?F9h?Zuj`b(D;Dr=zOLm+;8W$Z}{eC^(iq=T2{;@4bgY3CZC!`&<8wAaVf;1bl zz+WsBaW=}tM{iPmc5P9!Nz0dnFvbA`uU$6aGqd!yUtq)ujN4=k930#By;^3V;6i9Y zXhI0Lj3ZaVQbZ~%&DY@2gSR;KSa42&H;I+H5bQsY50q{u%+rXcoTq~XXtr*%eUyc- z3}fz>F^3Z7Uc^Z*-MJ~_buRlbK~-M=3#v~8PU8_?5ZC{%eXc=0n&C|aqvkGFr&FJF zUCmnm*XH7G|7cuV+FV!F>xZ`F`0@RTBm7!xrg}q9bB^E6{)n|VcBU@i^iPTqDf$1K z=Ylle8vL$S?Tmd{)tuAik7~(*7q-X8H7QZ|w62eBG5N0@@@wm(u9^IZiz7@pXJpvb z$sZThL8IxL{|P-sf5t%$ym_%b7iX4BhJZ4TV4Siuua4#B72yyGZ$V-U4l$!1rc+VA z^kY+i@qV7X5wZ{8)2ajlzRl1j_3U+l-|d$!d(Ajy)|RnvODg6Lv&}K!IDwa{FnTF( zVh&G~d#>Aee!Kg0RMfuK9<_W%<&G27bX_igVxI5w7J&RhrO0g+dRi-l)b8cY&Ma4beS=++ecWM3%mGTVQ%QPo0c5H zz<#EExCQOQM~1;5$OlGsQIISF{vgyx5lIT!QmI!|bb3iB5h}S)We-&@IHW*d_!aS>pHpfov?7(e!l~j* z0?BrwYY(T=DSH^h5FjY$h112WWkc-ac8%wm;ZzS%HVVqO22(dWWqVR^VF;!+l-mAE z$W+`_`Nc8l_fje6Lar$4@1eBWa0gH^e+i}BiYgKFZK0GTq!_^9%b^rC&LAshtkCC_ zuswu7j}ZmsK2hW;=FVgo8lPgz2D3)P-)PqO%6`z)ndM)IVGD=EHY5T5HAW`DeIE(< zL;e(`eFOu>-4pACg>okOq5$0CPr$>I2`ZwJ04l4!-_zjlHoO{(ioR}uX>k6R6~EN) zUXVa)@e!0Xr8_*&=<@k_*vVr5Mc@14Ssw%``;CwJbBc4vRrcO?iarH(s`_U_-=XhUn%=;TnDnjX*XbII{a%a=wD; zXGm+6+u5EVY>Cgsf?ZIhEh%IW&9eh>xn)uwhDVgN;ngtaBLp>|v!(LqMS&1XLoLo| zn$e3^^B;uL9)viece(iHP|CNFG9D=pg;HhQ#TZ*7C%(gV%KdK{Y1XwyGV z`lU03NAPG1KPDFY27+D%HVK5{Um;F{>&b<2M*`{LFNHCW0-EnF(a1*Br$SPqb!qn! zlcR3evwWjS73%W~q+-hjJ1m$WT8i}R0i*b*Vc-R{0!ambQ6QFp_wapTAbm%fBo4B43Rj!Oe;Ee8CIjgks&NGL z@#Zj)z6PL>jVIt;{Gl+=6(*}A;4Ho@2y9r3Ttre&02`kb0xVO=4JAMn9}@!1QaBt* zfD1e-1i%M~1gV<|pyOYBDb%4odo>i7-j0f}PQ`kW=>t9n9(kb)?b*vAZ!8=(;=>7l`WLNQ+!mO02DWx! zQm43{64wrKeP3LUi0j+pdPrRNi>psu|0J$^#r5~%x>H<#Bd*VgD;L+7#PtPn-GOUH zBK;{Sr}})`*(<2#+wQqrcQaVg(}ZE8b)V_McLl!IPt~LxZVSSOy1O(dGEcrj_|hL{fbIU^>U@Qc~e~UU= zHzWgi8?<$?8NgkyT88~|94SGWQov$!K?;H44d8x-)QvA_W+L{y3*vu%6E66YBRX`} zsy6qnjL*hQXIt_Z-f|v^Si2^rQ={`%*91JsQbE31*tXn3Q zKbK5}B+`?#T;sO(;!{egDCdm^6mj+o0MmVEeb7`Gc`AL=D~Od#iIhoNp^;JX*0EWj z)7w*ykz!#ke-j@cnkou>fOkayj!%!^9Y5rH&H=i1^(r)ZoP9i>gk4ns9Gm8c7}a`E zYF~&wW z&Il0&B?g=Z3*Kl645#FPsQTHnDC36gitmUBc5w#8kqBlRh~C+q$QYPK%^=O1jWPot zKmcHKt6Ko5X#yWWAxt_CX7XaK+poze*3~U@XE4Y4!0=7PW|ZSB4)Y-+KFvl6o~S@! zk4!Z1L0}fqAlL^|PS2bigEN}Gc)Q1wWANmFs8;Im|2p8*$zPOOAyW`4A(SKC_dJPa zj;R;#Q7UqQo?y~CyiW(~%r<)mWOD|cS-LEJjThem#LG(QbiBheD;0`>KXj3C&S{t< zw8E+NRVOMc)8^13&lfld4baFD`(052o`oeGG= zr6heDr4b(f9$E_2!B~V>%45q*lR1o(m^nkt4;0!Q$vLKGF{TtM{h1ss{8ZjlRe z$mIihQm}mgXuMe?X{9(%PA5FdAHZ^7v7$|~a<}yiBb|m*A69dK$AKTb_|B)G?6&r3 zsw|QNa{nL=cSiHYfI(SgtCGKsd@G6}IMIdhrwTy(dGqffq{O9k9ln^ZV;9nORu*07 zX5w1$_;8!JB|a!_V`qz7^h|M^lqzo1rsDR@529D&CYjjt1>&xGemU-#OrI~O=cZ10 z-rA#gfK?Sf#`YWmpD(~ud-P&l<220I9=%jRm5(}mnmUl>xfG;%n&|v_VE7p5*z-># z!LH&O)Nh3y1B(%fwzq{Tk%FjuE+H@{+`qh&Bxobrf#H(@GY5uG#qDsLJw7lz8L{VS z7Qo*gwN>HH_YiuUJ;}D3RLcX~xqk;aD?fFO zPA`@X^sR7ej9E1H1wO#H)Q|@|+Hl1NoM!?b2#pUoI}xK!)3=>Z@daR|4JC~c42mWM zHJ%5V$mj7^EXF&20n6UWVElEu6iGc92kZ3`9M29lz5~^+$+%W`u7rkA%idJNqRXII zZ;LYE(cGK!0KS?wN9Di<9*UTk8P(c2oBlYp^Q-h@uVR@F;NoQcll!Fb-x{U)Mb3{t zzBn`LkbciRd@4%6=Q}a!$BMiQwbVUaQGa};2)HI35nCq)Qi77#349QR0BDflzHmyWnQ@iLC+Yw$Xid*Hi36D#(z z=%eY!8s}gb^@*BO7gf+{)z&{lV3LbkebQEOZ5G$ZaTRqEy>*y-E{#RZ87EXL2|$cy z)LluI^pooxm_>}xZ0&*B;YFCz8LoaWs*hR+oNz4nD*Ryh4M_xVfreR=E0Ze^83AV! z<`!AAZCNgen5-pEYaI9fWKu0*`51(p-PRs4808nevFvYIf5bsx{QZe`M`BZ(Bkt0X z=c&K?trl_^28L%*HJ!cbPD~IQs#SMjxK_FA#GUpB0>cf2XS$GX>Q3**cf(>|zaNzS zhNkmQopdm9=px2iI}Hilo>|1#r4Kx_sFYPDD}{Bm4VeRzo)p)`;<{X13&eFPt|Ybp z`Tf6H0;ka3m%oTVtd5X|kc`m#OU618=&#}Y7U4$-TM+CBOA+ouxD{apLN)N|ckBh^ zL--ou3xrd2$9Qo8L5;W$VFbcBgvkh52+I&wA=nWb5FSN%8sWDH^jn6!uOaL}cobna zf)PQB(ESU>-bXlyup8kegzqCb5GoMz5YiBI2w$U)HstC5+uO(t_rngRbaUSQRn{^` zU1fuDp=Czu-FMwJhvjTsR9RMPELfO6BaLvDR#sToS6Vk1ms(~OEVNcR8?0+&qESzB3ES^bdFvM4n*HEkYn^DUUH!VC@rlmH9k-<4J1&x2h6DO zeML2ORprL}il!CLpE)a4mZp-^Tv=9QEU+-Mwe%t5jMTJQcg>l%$b27Lxa7Y3b4cpb zK&3zy^r9t;=FMMGU@|T$m{xdqdMa393u@NYq9H7m<<^>YXa!^8U9(fO2TY$eNO~Hj z&#QOT)vU8RN@c$86b*yAn=2cvRTfebvt`=Cg0%Emg_HA^-OdWEb#*AN%((3S0CEzN512AtOl^yob^kR90K-pfy2w-U8#~JnQ=D z=@I2**OfY}Z8a6vIx0*i6iFk;X|1ZV)>*7|Ri$hDpoGgQT9_9J36(#;PjVPP$68)l zYMftJQ(9hDTJIPzZ>auC-KH7yO3N#2j3!Z~Fs+4Fr=z~iR#jSEUMCR3wFvPMqBXEA zXGF@fzs%-Wl|r&Y=7hJ%T3zX^hh{CRky|u1y-(XfPScI^Z)Z!brRCIjiz=(LMHLGy zMx{H79!MRW`n;pGYFW(&W3IEbJgB(~mP|7l%S!9YfkNe3>nh8Pc?C<;W~ZkW8t*ru zw_Tr3Y4pP()W9i(4-q;L@Ja9h{D|VOb&>Hx1I054SN=IdF%?1Fn7o?`nNRzQ5 z;0u-*(`L<1?Vp}kT2X4PQU>z8*=e&E1~Fv1{o$zvec}DeO%FnYe3`0hsw>Otji#9x zmqWljYrWOsAVHL4?kTfQpFW*fWzPCFC1q8mmFr4qtgWjkEwdUi#MIQuP0Ql%v({CE z-SWE1^{8rPy|J{+f#_5tP-Ie+C`dq3Yc?9|tz|V3Pi1wzqqG{-YATFXm22eopB}%Y z+UT%ZjTM!3=-24nAXHmr#ocIyKB0tijD;BTL46JNtg1@jQI3aXKG2NLDr@}Y^7U&< zhPUf> ztuZ?4N~`N>JcWQ9&iZ>G>8TI}WJR=bhq%h&~duIo&ELDqSrh5aSE$o2Gl%Uxg3Sjl!@ebBY>z$#|}Ob@D_;pAhnSvQ=3% zSt|B@ovJgZleuR7nPt8H9Lp;3Fyj^{47*Zh{M5``6Bmg5^d3;whSAJ*|1d@`EUoU! z7x1k6mNNFOCCrEN2)FZ@d2GiIzQtBQk|D}AI%hN2Kkf?gz}`<~t8?yTzJt?PZPYYo z%$mwvuin8@FWxTrqjI|Wt!&4nTbX&yB*vai5jrZBl9tMXi>O;*CyffbUs3Rs3h&#N$i_^h9>PtMUOF*Wq(Iq#<>wt&v z1IFRyCHD3kH%H;_d#3d^bqt;#e{_)w1iztpR7@OGsnxjY^!PEgMx)VECN_epMyS*y zqSPaz)gxKd$fzhJk}}iDR5D&+vM|jzW=%}4?wdSaO#Zu=JCMZwj=PE?_z~aut1sjh z6?v%0`w-}e08Ls{(q@D>1bWMw=+jOkPU)~i2&e|Tf{Pt>A@Y`?u2rPbD^{2Fv zE@Y%tzb@i;<5{bgL_AZ(zbE4JM7&bOsSUL1As?dhVoh zBaEN9lTy&QS4)>9iy?Pr?f zmHi+@wueh(ySzj;%2{m?DjSXA;xTq9e94Ap1Y~ItV#5--%35MwZ>@IJmynTMl6CO>~Wo&=+ zIw23NE2EXn@M>8WJn>p8CGoNCDl$S+fFrPU+KUCWgUAt z951o51FDkJb@gjYghH?x;AlZ@?eel(M|Ncu(AiZL5rkaVIM=SV)|J?5Y94|o33z2_ z)9Mn(##$?ASJaeLm#(wc%S~Ke3jOwKN}SbXNU)W_hRWAei$W$wm59{CQ6);sE#S7H z%v$RxkwsWHvjj%Px|(YC1=gEX4ReiHU9mUevx|K0QZJ!Zmu#+>8p@D=t(BdPOeIHC zX`M9$WIjy+txjOESj}}cW!Cz7Sb3^NR>uNoT^*V(n0Q=MSS|BYj?CZ=296>W_DfB^ z)iF3YYDxV)@?LnX<1XZjutr!uzIGJc|r}I3*eR#2@EY6u7gZy3Fg1nh*YI~ByXg=`5WsU z)^!EY(|Pr%n3ZCEhU;HGbvlm{bT7$&UW)7p3VUCKS@J8`ng}~m8B3jxXBZW(I}o3O z`F<*%5nqk8)zc6VXSX8_hQ(h!coVB0nq0fvS7PQXEHCve$JCzgsgc;L)ZbPMuNvF2(uCHM_7xn1>qTlJqX7TzC?)mPsYX~q$7MA zVKu@AgvSw{M))z*d!6j%G6LsY7@*$=t??u+X0ekVv?tx`aV$M z6)FjOg(5*zF8VF{5F8xnyAdo@R+n2FO4e*FsfVu(V?zX}rlNwzZFq<<%S8f25paK@ zn?@!JS5nE^(#k#sgj4%)D<{(s6-i={sx`n>*hhF`4pUea9=AT?7b%$4;e8Gg7fF## zB+p4}oE7j^1d*t=rEAMd$e$LOHbCnUs_cflPT&L@MBoG(P^ttNK&q7Nu+}^JGZdC- zB%9&X>uMl_Dl7W54pF~OvKvY(A%sXt$(~C^oYaf{=NFd1&KVds@Xv^lh2TQyrstt} zM(9LHO_T3t#3?7GtyW;Q%6*#xbFIYsL`mC;yHAM+^VNb@H_{Bl6xz5G%#8buV1)Bg zLfYhQ_#1^ECCr}Ofcs4vS4Dxi>uXYRU#@w$R*U;Py8mRIPtyGr_Iq*vJ=-Ske_%Fo z-@_J)`(8Fx++Sr$;_hSJPf)&t?1;D@XTK5m580FA-pOpZ7YsL=&A49}K0`Gd_m#=U z7^AqGW3=M#is}9lWI6hYWE_{i)-7#r-G8pA`3}kGsVEXUEIM{e|NN;{MX{ zOmY9+aih5JJg&k0=CP`w9Y3VIdgu${9yQbZPUfeQ%b0KQvX`A3Zik ze(uoXo`paB;zMvDkX&EF_ql(ggq^tmUI{!m|{74IMC%@7{gm{E(ggAsn2wH?!5Jn>W z0fGDmyAg&X>_tdIcnyJk1AjsohVTXg`34RkP{oKg{iqHqB~YAxR3E~jdeBLXmv4T9 z*bqOkFMh%2|F7Jst|Serw-Kfi`EzFDj+^+&a5`az{y0E7$<8)FdMq-!1O@pLq=U0# zw47%>A!cFutOQpR)`9tK3A>*y!}Ahcvk|A?pEX}y z3$`TjNO8K8UeQm3f5G;ZQyBXI2`bQodBQ4LHCqd6m8=STX-n`_!D@iGOW>r!EKG$t zNcT0k!rp`ys@MYHti$T96!;s#O(~vaTegPPBVNPG1O{W@g(0d6(O(Fxdcde${AF2O zYe0d1Hat0yb`QG~|LU=pt;34DFEx6u1Gjey&Pze(PPPFw9zwVi5C`foP033%>-v;! zLD_YHhRd9Tx~8Lc<+xU$)n~Fs1K#iLT%^Zc?MtvnT@nE{KHBT;ciHTQmw#B zMVvgLIIjV06jRFDwMMZP?DJ} zZ3Y_DR(zAv=quOJ{kr;W3=-^F*^O}Uq8A(?%X?f&)MB)_w1f?o}IZVK3}>wHM78#@6F8e z+3wuzED3ykx;Mo)%IiPO;#)X3XB5QCGR5Z|y#%{m5GBF^8D9=i<$eavc0=mHt$K&J zTvkqYt}iD6qV<2Njdsa_B(RdXz(*H!>T$tkfx8chQlNK}fZBxcF(cjA{qf$sI zkPT;hSOwe94znjX1U?Y1si%~q5hW2f2k?5%dGea>#MBb8gdsAj26YO|_Ur_}&wkn@}~#X0L-a4tD* z4j4v2KJ=$Q3P&E4jM9)7eT%+B)u;}IV}Y093Y<=Nuy}o!Uas%eEA<0*2;6TRqAGu`Jwr_**Q?$!e`Ss~S|ZYE!Web2dA5PLty| zy>h7cX_Sp#N3G}@>WNR{Gx!qTPY#h9GL|OL7w9Vb27Qlip$+UZyUym?8iYwwKU^q~EWU@??C**0_ z%j|6$rZVT73jxPU^P<^o4!82GLd8MK0xYLiTlnQE>D zOao?j@j!L<8T-6_)y`9=RK2>OnpBZf?36fVPPx$gqe5DykK58L#)BpNK0B1tm!b5YV4Ds`B!^}v(4EF{odysb!uS5>O1F4 zi_`Ahb^=zwn%D!BqaYND`lCUB#t1YLj$vrXLh)!4%0hQgAU=qz@o`*-oA6B>PNE1S zg1kiLkpi-jY$H3#Zt^`jMt&k!$nWF^=>si`rg79mXVJxUBi%|rrC-pqw2@w>E%X}g z$p$dQY&Ml`XD3-CpUP+O6rRDo+{c&lm3$3<3v6vOFX3gpoLBNA{5Y@U_53&9%5U=^ z?ICT5=F%S5VzhWIL7S|3wAosgR-nD6y{(mMd$c3kFWMC?N{`Ve>XYR zM2k=k$Sp%F&>FN3ZRpfcj7rdUREBn;angRtIgPjDo4X+SBXq#oTtwKU;T0#s2W`Ad9 z}p;cpj zx^C(__c-r9pMpp4Pdoo@v>&~noj<6Qj`QDFN~hBQ-OB9q!wUVsod1T>Z$E#pQf6rM z=}K7>ZVwU9kFvn$VXQ)z!S22`=1b9>VrfgR&@E)_I`rhIy=k98X$IJowpppCF_yt} zN=K?>y=cOT&)v^h8Y=@5gJ|4LsWn}UO#@ruV62qTKE@tWSy5~DX=UsV$eFS+mOtBj zSuKydWUfH}!evym9V-RCPe9X5Oi4eol_r1AV_~dyWi;3(v_V(6L$Te6a_Jl*RLk&x zrAo#|D2UL(pfg(unDdk|HnK7ri?*Xru@yEebkKF~Q%3xvd{++$bBJFnfOIPa%z4Tf z`|O^IowD>Crt!e#-uuH4l0SlmO0WUC;gIO zH4MBhX2g%kEn^MR2gzeuj3w)@!0S*3*n3+8(BVob{Y_{(;cX>bByUjb%pn`SL8Ws% z`73y5Rz5cZvE^3SAnL(>4EmU%hM}4&HPy-E+2pbLPlL1@`pAktfwBD?uInEW-x}X= zoi14jy||IUB?IQ`Un@0R&B>F{dy8h~Jo#nKuy8JamA*I=^cv&&^o^I$18ejp3l=bz z(qle9;LR}3=&Me~RigR$+Wn+oXs*0$3ILM2$vwIw^YFz&goBi=#L7`&!B9@wkp9`R z!;I6Sq(NFukrAR~B)^10#}b+HO9`(YGwn4byvBq#C*jRYc+Cl~E#d7=c!h+wHQ@~= zyj=-zDB-mxyafsG@(HhnLV3`8-Jo~zpf`WeyC~spPIw#RPZ@^1eVA`6gRaZ3(?P+Zo(wBAWhH^%0cckidM8{jKCT z*CZl&VK|=xcyhd09BFL#uoYwP;#Z&Cx19rB#EJRJ95Wys=d@#Y?SOVpgK1nL@IH z^rAvl3I37BNR82?Vf2i7^mWxWdMhcSgP=4hlMWB*;jRpw(1Zohp=dSZtA)(M640)L zRJ+7k3+FpaQ>!JV)5eTPx8xEx0KJHEk!#Q3G8|oDKSOUt#l+UgO znjx|uvaM?oTNMl{(46RmOygcENj0Id19LLh6{HSCYw9RTxvm^#9}W9AV7-t$%AFJ+wcIOM3i^FWW3E7}P%|$U^EA=(!qBXWo>?8U zQ{g_lRV2{{h#m|q=0>)V1PD?}Wr1ktGa)1SBr+-XqWRO4I)4Hmg+`a-k;lwP5B1Ut z+Qo7D*ze8987LnO81=bM)~WZ0Y}Ya~YB&(loBrY8Bfl8m(~C+-*n|9kn^e`?X{sLg z=IfAM{k;h3Jn)#aPww|Fn&s&G5RL+I6u_}dSPqT_QkBq|29Apqj>6>}11($OlCdQ1 z0H~8+#;{+kAi>-#u!6Q7S4*$33`X^j2)WR)daxy5eh~_G%3#PqAbERnEK0QWO5Tur zOvqFkAyWX88YW2Iu9;z7fvsESuTaHmQ-403 zPpau5u;B?b*ib+>6tps_$|(5_?qlL7A-?lEjrr;{keK>Uf-Xg1>OY3o9g^25UAfoCf)2}e82jT5H+JAu7%La0W4;OjKbpMyK-%QIXYC4rAt&<;_sv*Zbv=<>DjEo+i7^B#UlBQlGorqZW<`U zAwu!3Y2YG`6?2^yKZk<}vV$IA#K}dOIaB|8U_t&P&o@X_!O&q`pr9V*5ye^JqR`%% zlbYlY#-Gw-ejOk`^8m&wsSbx9q}%*zB$_-*G(K#Q10$vZ(vNNysQ34yt{k4CS?b}5 zZXC+#$yn{1b9%zrsF{03lBFsGZal_E=)Q2{v+j4J3t{6EN^4rG(qnGZuWm?xrn)Bi zY23zuOP^Rqvxd6_MCRQ%5r4{<{%bN893PabLfE(|NcQ{l`=2unTm?_TJvfwTVMWIw zvmeI}Y094@Ju5 zS2{WFy^ihoUI$lUVfGDu3seZV9Lb-Dc)S{Mt$2BEND7}z;e~aQH&3cUfbEkeLKF)S zR+B#FORm9*TL#W++qlG=w*mIK-{1WSq`|!E(cc;yYUMhs1)ZF{-+x{IbHeSlGxzB& z0XlNw@*kiRB2^|QLkE;uErv^m)vLdlUN|!5mz>Md6}kslpL}AN_6(Z7*RXDsPXwVK zXc#)`66OdnQZ}&&Jp@!W232UN9}+58K|Kak4N&R@$JGDz8Gc7Jess1aeton2UeNdn z8fxn-ztb8&x(v{$&(83BOXGK!hAEikhwn>@evKL`dzPOWDAJG4`^4`Lm@?H~D=_2< zEvVJpq1x-v_^H<{Q~ytCo>hA*G=6kFB7WbV;n%A1qYDRN25FGWPtf@7RZzmM8n1qh zS4i!?S=H-+#%H(MTdwiAN8{0}cCXNQ9MX97tKC`@*Pb>qFGw;5IAu%4o+UP zFJ!!gd4YO!?=%nPnEW;Ji^}IQsmhnASb&6f5gH`w7UaYy@@8~+7^x*^){d4f*j-iU z$o|k?s3zzB01}&|DSS2%P#ZoBt%e`Mi#~91BV{dP@lUhlQe448rUGV8>QKWGY}sc} zKaY)~i7xe$TrZuguCC=q{0%OTQ7m+2NUNS)i%f{;Pv00 zT`=J>Vk|rO1MuxkYr$b7t8;Pk8r)>hx3|q-l_xy^txNfCFf?#uWrjjeJ5nDS3=W)Jzx7$Q%vCO_4eh>2m$F%2YlfJBbJ3PDqv0u1d3*;qn-SA15l! ziApdvNGH#JPZo`G?)@0rq;gO~LJ1CTWSCsz@>~=RKFu$PlR(RsqsZ=^=1>w*n>-BP z;12u;X{!Oqgy%GOG*Njm;l!N@qA$AN6wNLrDnvt~^7NS>leeaXjQ9s>;>v?Y z&?_u4RhiTyAIGO(h)NgN6Th|UXOZ+Jsvtp?58`Dh`Dd?{Jm(~Xl$EGFh0m17u=h4K zjY)hm&Yxx!(-R&#^T(MwI&(s12U;<(xil0`$ERs-DB1>Tdd>zr4aprej1)=DG5n)WGX=q^ zA8m=ZP7xKoK9XuS z-A^jgq)Nl#%9|PMaOnhmw}r5ErRk&lis_GR;_tcVesTrYQ-^C~p6S4o(vvgaVu+18 z9&x>~H2sL_$Ln%x{iYw^n#nzfUBr-wSh!aDyiwX{biWhLk{S)^FT3B1F8pkKq`-Y5 znnb=t)|__%Q22Fz5VB#8LRmL3bMPSMo%ygY)%qI_nlX`f&ouWmd_EN%CRBn?!l6_P z0nEu8;5KXlh_O1!V^~3bJ{99rFa}^sq%!Mha`A=Z@l!f&Hl)g_U;;-@Og5B~{u@r9 zxa6MO=R%$vQ7osh)X2G!%LmBIo}&3*c8~JDOL>12?>X+CRBe)-B#6$?*cHt~fE!QE zns*WA!75ptmOK|Vc}OWU7LUypttwlsE(2N2LB3RDIP@C47b1rxk3v}dDSSjzyo)P? z;>S2Ytt_zGh9|0iQ}*biSP!y$LdYH%6S6KGAI`zZv%G)EGfhW-m?4Q5IT1;(4s~t{ zpIf!ESt+3%=z>J&d5iN*aZ~OK;)2IFgY#MQz#m1UG@gCc20Hedub4_WNv{hh5>ArR z64-KdY*Jo!0E6XayOsA|<=v0BJDX_5v_FoWq3`3M`wDs$OZJ^Bz>*oZtwY|+UQX}a z0(vj9(%WgF_v(DSJHC>;Q7N)Zm10qzQe@;P#WJ%}tT3Xu>#G@MC?pRXb||HOxESS- z$1q$@?SWGlWqBfFFI3XuTk%0c4m;4A$SA-&OV36oGL|b?Y?!2ZV&Ei(93(>%1Fxcr zPu(zJxDOqjx+MOd%$o42Ah!&iAv3bGoLi1+d^Hg;(Eu8JXJt(x;w|TH1P+d_Kyh?T zUUmmcdD#)=J&89cKYsp-JkX3x5(Vr5d87PTi?|aOVL$?V?sHjWM1bd_<_~5yBne_BJ8hqv(VF3V12fzKd8!m9gl9dA>IMCWsgKXpF{tJc0Uk ziZLpGrJXWV#j9A<6}S3&qV%&BO&8UYO_7csGF0ndALSwX5|pZ|$|Bs$*YHAg*ZLkY zLW3+CU@li|s#fMyDT&`kdi^gS%G$?qexgf6O>KE?-L*HY{>Brz>mUB%)Uwx)w$tYY zw!WmfJ_ctri+DGe^RZimp5Er2J<(ebPL`M;c62mH_?=p| zgASrlpWCn|nGHYRLGDOBB=l$^zfm772Fo>=Sy#wAjt7M2!7N zYL}_%?n$xM9V1)j}CswXXCEzHP^4-OQ7QMemFD zw66;WqkIgB;CIXu!2-UN0W*;lz zovmG4Sk|=8x2|zh8LkpM+8o-A=%99bW=x1i+Piz1Uaj@+VlQR%M#B-IgR#n5|N0uc z&8G5lqzAg&y6`iyKs%C#l+giCFm_E^0C@>NKMV#UB2w$2v_Ke6fkEBuf!TV1XHV+_ zZQZf$0lqJcG-1~T0_%Hw8{2yYZ@3HOtQI}(ScQ>*u&b8`myVu51j#LiD)5mue^03H0h~=X-@fNSWHGBhcQ{-Hn-fPe%p>g8Vjd z`*uDW2=(;bg540aKxX)Q6lv@j{5!XO4s#7HND3eH^tFTQcAlM?+q=G}ySFXM&mh^q zrX%A=clr2eM^Ci7Ez-^_ITE&hgQB1=+Tg48jH7 zyJ&3fu9(1g({8XX2LJI?V<2XxGZpJU*6evJD2)GB(dKJ`Io}1n8&`3r54Y2HIk~B8YpM z!ueg4OEj8x<)EO_2YIZko?RMdJ1+#<;VJ|h7R{|9ZRB%MLFGh&@TC1y9Zw^0XbHrW zBT^I-ItPKR4LJwPt$Q0nNgY6IjuH`$Dr!d$9c9!iX5^#96Dr&h*xnYNOZ=gdi8Oi{ zsn&zc5D{sCe*7pNz&5TtDRcsto>m92(zaNP@7~t6%hK1~6^X50Dn=tEvGx$(-4AWQ=bY z>G-7ZvEV6H@*4IeI$7<&hP0iJ%^>HZJ$)ET8%_nkgYU9*(R=mMw%De~j-Ffi=u(Rq zUe``L-Rh+sZCx>b>6+4;W_ZsZJi~tu#bweUKqpDU^>dZy?0+I$#U;2t?|Q?PUSceXl=PPjm7FP& zOAPLq`!@HN-FLd5ai4Ji*1f2-ptQWSvNTe9U+J$)(^fBD<6g6FP1TyNHTSO3ukBcS z=i2jYnT4@?5rbFRK55Ih-C(=PR%9!;ZGuGsThP{JyUq3m+m~$zZ2xFGX#02DL$=3k z$85i_y<|IWJ7as(CfoFOqy1C%#rDtG9d?&}oqe;t&faYAwD;I|+WYMZ``7IMV!zk^ z1N+1FN9|+wN&B<*m+k*$Pui#K@7iVif=<`UI-Z9|ryP1`zSH3>aaKCJoqL=K=hvJ+agM;d$DGePf93qW)41xIRrXc=s~%YO z&ZHClf}O*{(W(_Yl-VKuG?J)T>s>{ z$Mt~g=dNo@EG0!HH+&6tCG_tZXb>i8Fy_ABsoNbI zMR)hTecyZE_ZIDYZ=E`Is_N9Ks#B*<(=F(yjMkY1 z;Q}B-8g$hHyv_8}5x~s9^@4zu6drjCIRFw9@lP-0AQFiv-N;)DHtyF6hk?5D4V{qA zqxC|!Mv6ig|E1{#>y?7w8mANHT!en(tNUf0kP{C@IjLQ~?ca^QwOf3Me1wpwd{ozH zx$(vSr3u378#k=E+jqAhr2PsYs{6mI@E25!ygg5H`xkBGG9=g$i%d^QW^A6%MAMKCcvgh^>#RW2Ve zHi<&4N^a#$a7kusBGrODfMN`QxXzdCW>e5T`pDZzR`E3 z>Ng|zPR3Vil2#@N_ZpBaa zae^!3@=!@nLMOO_%H~mJHL#T(569QlX+o`*7}?98jc_&3R36PVRyn-2@)i{Oo>_TspgGAu1(D@e<*1AO`YK+1FsHbL{RX^SRlb7A ztD8*fCZnrJIm&9Sgkml(0TTO%izso~9|nIJ&@Qs|(6yJa74ao@wKb9CK*=*@tS__!wxi9m?zRo@(Cp{V?wQMr;>*P8S@ zq-xFQ18-}-R^oiE#MG4pAy8sr>qiMf7$sAdh`~iRbD+v*c7!B(2cnf59ZdRBEq%F- zN+jc}kg9ha@)s#h86lKbj_5WzGv3{=s_Jc_^ZJYs0Ma8}K+nziL+FB@M+6qzEXtvd z-i(l=X`^UA7S8Kh0kOIir!go-Tv4zgS{ePizX~BeVFiz z-6eah?K-plZCB8FZp~hT2iEp0=j{Ule;=B({)F$^x-V(6+yZcSheW#@^GucDy(``ABe_+G&)F!`oSB)$lvJ=EzQw;VB7EmQhK z!)T?Nf^bq)Uy{rVGNp76ez&Jd=|yJA(+NM z9QY+Mqvh~&;(^rCqvCxSeIAP^JQv$cRNrgk>kBYi7?51z&H_A2LmXy8Z#PlvV+CUx z=~bA2p~JQ&l0FFy*6d<5DWUJS=5gf`+K2|eH3sI&=Ey3?F;SE9*eZwgaRrJdh$7up zjvAA%LL)FR<+5}?jDb1bp!gMubD+kQ(Hh7zM}uAz>nQL-pC)?EB~YSS2%!?M;0oj! z+13R_IMseE%WbNegv?EtloatN0kI?cv8Y2_;BcF&K3!D~ZRDczfv=c;mq`T=_-yGk zv?FTE{25nYpa&{*%h!{4k>{UAE>M@jMpk$Ndo5N@=q zQ(u)of{3D*qfc`Yy`ZnUg5#inBHk>2^zV~TS~V}W&5|!@@+m+VsgpKwSwy5JpE(!h zlN3rb*pO+c0&{7pFe{KNI;w0lYOVnbtpJ$qssXIyQ`tROUm`^+@eVD45y9ZLK+&XT zAwE0WrJdVoo|$se4d=cnf%;PZOg3;a3R7`oq1q#r20P-^S&CG339=eh^HyfyrrEg^>T}xcuui`PVd>Z_2-A zKgs_xlK%!x{+l5G6TVgc%~h*I7evVao&PcUk4{hm$^SPds5|_P7rTH&olNTjmrhhj zi(U{nQK73~q5?Q>qCzkEmWc`-=Iawx0S(1SkB)b7qC&@j4Teut=p3c(B;O?Z=pg2A zmHPW&9t9$odQt-$MZ*$WK$=PN0l?yGX8=QuLX#4DDx;}bX%BkTjtllitj(u7wO+t zrOEOBHYuYYS$9MnEj525prJpP5Fs&W)KqF;$2(Oo0c0UV%+52&R4KH)fyIDuJ20$D zGfxi0RF3c#B7$No^i#_D{r5gn3eAexfl#`F$&dz2e9ur?9A8MgYJdzuTw|LNG@ZgX z1=hh#L5q3}qzEPB=Mkm!4k^7ElKcn!4&Zm{thBNnZzv>Yu@y4h1pp235OVXPRtWt{ zppPR(q|`$3D_cbar~*d8aTIKJG}Zi6Mk$SXD%m+u8L9pbsKK{)Gy`Cv+DY}P07UJF zmp1Rn{GEpObC(2jRn$vsNc*u4Y9-!;)Oh2v;bgO=-N?lt$i^CaozgXdkPiMr=1(%S;jr0R^i99?a55o%( zKz~NlKn%Dz;M=P7Uz7#YWrVCv6LFk4Wal1I~e65*!m%Wtna-M zi$1zIkO}zq`+^W_ZK-5{%77;C=aTfHmg5?m4f2Gn(f94gsOMAf!SK`}?UI2KH2n=v z5`}c?rP2BU|7)Ye|E4^oe_bA0AP?r6pHP9285D3Sy#>NyH7LU&wl8 zJEHN4@u`$yi6zy~h1hho&{!hX@BO;CXyZq}+?TF6X@kRrIzx50Km?2mEguk0vp1F~ z^T~RSx?8fqI_a@yjb}a@%*<81Ypt_hGP0fqC>2d;Ue<*1^Bt^2wVuMqPxKTT zOINmCEb@C&`iFpGWF2P$>dH=h@T7m#aNf>AEUIaqei#w}iU@*g7_~*ki8y|=5?*;4 z-+lOf1e5>HP2d42p@?83iaBl_Mn9_1{8fP^V*Iub??3%@eNUo-n$hDxV7u*cgxnPv z{lS4b$`@SHW+=;zCE(Kx_E1Nh#L-q3lz3Kr9ODSoMMxWpyT%6iUHwX~sAPeqbMRZH zwBlI`5aJixO7WbjRjLc{l?YbZR!ZrRNY4>4--S0d>=1q!YD&)&cck>A2p-j@C5$4a zU?s+)l^FXxV4Wu-rN4*Tt|aQ74L5){DADCrTV zUL;ME9!UR*8ppO8saI>|JP87oL>LiOwl#=Y1IRimDP@D-`xlFPA)3RbrH%jz)uQRK zic)HIj#Yz*9|u`_e*n_!siX+6!?%x09+iP_C5>unq=6kHjcO1_QI+)|MI@=T?}OwP zgnf8dfi#Lsb3cqJoG;%|YG8XHTX?oe=^x{T#s~S8oZJ?KKR_1Ukg8fp6>_M;C(Sxq z`O$Gbuzg%6lWxR-J>#C|3AKv+E}D`ugr!8$hys!Hw(YhCPS(=`xR!(G6F_%zD5)-` zLsI%7U?0-j53DKGHi9#07quH*3`Onb;+_dKQhdHb2_BCU9``#=i)}p;*8vKEu*jAZ z?FNgZeFIh|4qwcli|PlY#~#CQkLu6Ea^9B1*Wka4*34&HFQu;|saj)mVUgYqThLkQ z3K)P6|B842@r^JeeId0&A$wP9dG}Y+I9E6D`U&Z*#A8uf4dIB?a)c22v4puK{(UX} zsMK;4@h}ABptd9FLFRzu`J;yOj@0rFa&7||!hvC6dOwXnp7-M8VXgBteIZpfN-d3@ zXkw6fn-Y0GLYhASSxTSDlUP%E{T)uqWIlIOw_ss35A5YSkJ0VYh!`5fpzGnAdSXCNbixvR?UhXV^lMtj2A z-gr#EFuA?y>@fmI7fyGf!3)Vz0n(CZrTLhzRp8X1?IZ)d1bg!k4I^Qg*`mYo`|$un zGRCshqnaowG=}79Lo*EHBOCL*hp@vJrvq!{(fk3TegKqv%msk&{+E+eK-3Sw%nrX3 zpD*_V7|UL`D8bQ8qj_lbl|mHSoNK*g*Z*c^xjC3?9B4}Nry$m2h6?UtZ=6?Em`nIp z|AV4>6Sk`hP3#HS_~ip;f`TGU0rrEiu1t_4>gF*nmWMidl(zbV{)AqW0Xz+HG`H$E zDre*hGq&L^5*nl>QDCnm0M|t^N0=TaN~}A};9vo&8ajIchN0HPo#RM-`dZWu9`(xQ zq8{K;FJ3Nc8INkb7}csH>bLo}l4D(Vfx-l-=YucYd4mT#UD4q%U z8FX3ss3fbyn-cIDzQKO1)!7Hu!i5F<(Sz8wc&DS+(Y9%vceoTA_??>*g7dBl8@$7- z>?eZxx?)$LY={-1cX-e+0cT(Mdt|>^+mAho9N1l3oI`qcGeskA|L9qQ+0(2P_SsJ; zJnKLq+L-(*CdxGy^9E5FAJ!}HBRtx5XAxuAewGiIioH6tAyy&+_K6Y{XI~(ZtQa*G z7=C5dyg{$r(vX_Srh_A7wJT)y6G*~-fds|H?4Q92(%wku<>BGYg;@_;HjY*wG`rd7 zC|5YMw%R24tn#pV(Bd%a!KYJdApvq;x)|rFO{#Iu{$&QQt1okwp(e|0pTEW6|Xsw{r=wd~L zeSl-1YjvKZ9^hj4ejD~Q!WLd3+JsG#?_!Q9Hkt^|K;*=AMtRr_w-$d!B&*uI(V$eD z9cTR$46QDpa;e4-9!j_<2wm145^240zG1(Xk_8kF7$c9y7Xm%B` z*0G!|#4fM|98LsEON%&1ScUGeqO8dzRPLk(nh(8}D$Gk%3|FD0S{A8MvE%7fzbT_r zIRbWP13kQux5g1F(C=XnLV<3K$JUz0#TI^R8I%^7BBD)0O9nT44^^yh1j{{vOkZ+q zjtEaib2tefMtsDY5%J_CVh$9D(bRxA3Ph|^1&7lVH)ilwFDgR86=lT zu)oJ9BgRloERZ@Y*Sz5>62kyKL}eV<)X^g9X#mBTsPX7(ute)9XE2PHz^v;yzo7yp zQCi7!XLAZ?^O86=8-?(E$ot%Qwq#r=4yGC@iEpecC|>C*W~WhW2ro}wV_xy~W};GR zC3q5S=H19?teqqHMGTA0E_O3KG(CKrr;5sJhXkgezj^8#{R#VxXkC=n#r}rrgcujA zbP*xS)h3-^LVRToNkIp2!lOY1jAAdNjW07yrgy=*Z> zXNFfZo)FMNW0ui32CH{@izxWdQbk|~;FXZGUq%{X|BHBj2c}~T?Iip4XPbL(q4{G5 z2JE6%otTDtoScg4Q?9|>WODYA8I8XY;{2UZrUhb9Bm54 z(Wc-CZDSbA>j#z$1vd>T>c2@>yo4@=;^~5v?b!s>?)dmxG@eOUN zt$xNlB(nw6DIV{a5!^iwk4pS@;y0~hM`A^>T|rZspVuk5C7% zM{qfoPHxf5t$HfMKaF7R)^Ow&9hI{!G2+DW~N5GC4ZqRqrP_Qa%DB1|Ni;XbmtFtc*A>UW#BNuhB z3!GkqPtc0B$$70!GN?`Vqb$H6Yk_w2p>+gZvri-shZq{~AY{$`-}B z*jAtE<AI@P{U}OeP)n9rs}-G$xY$6!j|1)KY0uv6}$c-ZcCVITc5Y{Bd@;tku~F7eW~(Rg$K z^bX^962E>V@=$}tpeOTup{bk;t-z_vXA z*tX4pZQHg!_?uef5`2rEclh_hTWG1$5&8@EO??xB{Ok&nBEM}(===6TVKaqZ#cPhu|u# zrAXc}zF`7S5n`9nEbyQ8^j?7Wff)_6873c$3`6SrA$IG?)bEAA5}&rQmLX+=Po-Ee zVk4(M6vX;{qhGa>8{Hr)Ay>oh{^GGonPb@XqruqhW&e!)?~%jNUpW`kGs6qhK& z*vuRJQ2x{qTq+vgF|;{Co5rxufY&OJyL5OAysO~CqO^PJkCA2)9v{rduGHXrh9*PH zwC0Q!r7h!VplE2-igL`GP&l9#v!Bf7`Yo*I{)bq}^`!jylkAPXd6=}=L7Nt4#fS*^ zvZ+8;Q*Z{xymv^iH?yJd3Bul$Js>ler`(#vOw)mRlx5DKlv~o6`$qmT0owC!xPX&N zG+Iq4MVj7j6q>!70emc={cHCSu)eY8k%GPS#g(J%HcZF@9L}6b%O-#}XO~}M)kw#l zMfuok>D(6$jiWLcF@)X*JT$bia(4GIomurIFdtBx!|UOu*|$q}geq=J#Mm%yfhCpah(6&ITBNnC*9HC3*rM$sb$QbHle+Rl_U zoA@DZ?;%7|8HaVg1bJBRpRJ5BLfJxBf!vwNW}tQioIT{mP0PI~jEzH~qTqid)|8ox z375@5F_cK4x(5XP>Gi7LR!qhSmIion34Q$$+U_2nMWZi?gVc6f;L5`W{|y?ESAa6u zIk9mX5%Q(PuuVKxZRhl{*rV1_TEo|3VXf$j)Xa<3#{v!2w=^qjSrpIS$nwwL;^rD4ROlS?XkX~)~>cIS0z(J3v_b^^=ujox< zkKIH7rQfZl7)gHnA-{Y3@F0IiueG$iS-uuLFKwrm)K<%)|}2A#%&(<*?? z2W(yx=DP{!A6&uI{c#mV(X~+U@5F$iC>le>!C*$Vo#=)%%1yN-+2?xtU}ph8xuY4- z{!4!z(MA9N)t^fXzDs|m*vsnA>+-p-R!Q;D+4>ONU4_Ss_#MV?L?`|({h6pkzZ$`f z>SABhpLrR+Rez4sSPD|}@SBC-4E${PrQ&D7&x9XzuKxu6nKDyUs`PsNs_@%QkpJWQ z^SRq8U#>qtk5BOIa{6-wWkFjI@@^v@Gw@r6Urgt{to}^cpcljW4*i+ajl=u5_2($< z7m>w2{PyG5h+i9i?f7-#7sd~5^PiwUQ)Y@P-huYUFBQK`{6^a5zx3z-Bl>gPb`L)f zIvAp*w$HW$e(*ZjFPCTl|K|w+3sG%7`cibStHZ-JhIYAMwKvHj@g+g0tMf4>cL*tO z-rnQ0y#%dC@Lh=)&XVcF??U&6y$44SnuEE+BVS*Qd<{jvG_@Yv8ghk*9TzjSsupaN zshR9Wkh-{Uf$6eUN3n_khh8Prl4}%V=2Og^Ur*1jxR_c?*Zbc9L2hJ62fAa>H;Ksr z)owEi(Bd|W*hYYoErb(sasuArWF)?5E7MBG?gT>2V)kg?r4}>T=yANyHh^ zxJ6gO-h|~Uuu$YmEZNXXTucWI9cpLGLZfaKOu(Xm+Sk^g6v^r)k*%gp9byKtp}ZLz zLeMr6_FGYPu9x+txl6o8&zmy<2v&EWeF3^EY6Ru*%7H|)Z>%E0d{U(7l=W8Cl@_Ru z1pGsYGz}ygeMvCH3pr0=8{i!D&3@J2qx!qm6f=~im_uj$X%I~}DQb4DQHe7G&VQOR z*4Ut7mITrj7CX*@4IR}_`wCDI)seF;R9N>A6>f>qeuUi~R#oWm>Lv@$?vhSvRyUbR z<@uL6#Emp8jF6zHc!*5?1x7oz`^F;)njN-Lxx2zQ4iT+6HY|=vK@YDBd$IH5G^y*Y z{7GKh>Uxbb|K!A78gT&REj9t`AE;w~6Pv8Zs$=9oY>K!lr_rjb7R2QPaNQYF%1p{V zsmc%2)NbU)&m5z8a-Wq~I#|f$wM?*wV9O0S`$0b7JO_uL9BhyMp-?af3M0@qwX;6~ zCkr~6cHRdXG|bdyw(;o3GF0Xm$xL@-B7(`F9^ob8I!8gL%xg@Klv8gQOeoM{1PH|f$;TzPFDP8{_F z?qji%wFRARTFKCQ#96SL*9Xe-IW{^4fLh{7z!|{~5m}S5epnvycr^QYpWvIYMuFN4 zJcCl!7BH*{@K88ei4g`bW85n$0s(BYnB2;Gv@z$Be+aAV`V(91*ant|RsU$V6YE)} zFoN)sAGTPsmKnwBM8`6tu?A}&)t{tP5B(iU^ogyguO%;#NwuB>!j3Jb&7xxv$4~Fj zC?GWi*uZ(qMT?}M5iK<|Qf960NKDOr-;i?8klIb9)wV{8u#zZQqj1p=_#d<+a=4#KXbEU;V~t8GJ2(J{XK4YEb|1!$WP{IJ>(7-esCxm>)imW#{AA*}4s zVIdP#FK2{gm&jwF!=4I;u>_W%D+nh(Dr??f-5{7-6BfOvGvE7T!MryIAFT-mcwRuT zHDNKnmi;|_x$xD6uf5ASN-3T{<7rpo>k5vt8eb3bWNYxX7BI?IO|ha4yt=*HVXt5o zWK4sKh~=W3O&}~iVH41?3pp58E0aZ`ksTxR055Z0pAD0scLE#yC1*;4SMPcE`n{EZ zhJ9ho8hWOzrst%U^qgHv&+KJ*R_siv<*zY5{+i_CuY|??HNAkpW-h|(nOzB6@KT(@ z-gW#f?p=>JHdOakQMmpjhRxQ5{jf9W1f8&lBKP_bYE7ublM39Lu#U&V*pjd%`sEc% zf7mFr)>a{m!A#J?3f~tBEKZ0Z9O@R7F{$k+GQyQEOc(4hW~FFz@s^qiUSTYreH@HZ zQ{YOBg}mSDW>?}kpwh3Vqyge$R)jo(Lv)`sO)6NfCJxcr&B#0x< zKF<+^yGUYAIgMSPojUztcL{EtcqsW)mtEz1GVTfmJ4~;&ywtx9<8Bo?Dt7D#L%bkl z3-x}`^_BsR^_{Wk3bH7lF@aTRDqc~onsOVIxjlqsUtPD>B;8Z6E;Y5xgy*3PJ=yS2|Qxztw zy3dCpwB>L$4a`}^#TWxCJoBAIN_wp^7@+v+60!)L7EhH$Mz>W23WraP^i;GS-|AM* z%AZUgXg2!B4>-*_A371+gVylKpA7cy1}_JiMII$0N@R~}QD64@d6Z7tP9`m+G)mid z~d~-bXp=+YhYc7ErPbH*-OgQ@P>OOUq{K;_dF)CTJUfO<8D`%SamWw217a~tVE5eN;oa^ty+J#vGTu%^i+5`>|rdng{rU5z$|}mzO^%<$-)Z(k-zR2zVlc${LAY=NjZcHbqtYL#)&97Hi`HWt;g6w|<~04Y%Sr zjmf1bT1;$bYhpW96I&C+_Ig4$8p2bkygIpiSZ>n?bm1$a!LLR)hx-X7ZHTC#BoO|z zY`R^_N6Dx1xR1kENAW+E+r;qbXdo=N8F5e%I!K`V%u9J(5e)KF%>d54QWnMno}cb z5MP$689efv!!xfDE}M+PVPL26ByNpFzHM7#~LZ_!1u?eGKA5PamJ- zLq{JU(o*p(bp(UV1mE`xeAg8CMi=&DWc5KdDPr>p2iV`xYSB!| z@rn)`Ksez|sZ$DkNd^9^r;HDeR}!Z+jUk3Y(czz9GPVG~oN`}MSFWpTVmRScuIto9 ztf**^N0qR#;!BYmhwMd0+|;U_0hHvN{`6Y4Ug+Goh{uYK`&5 z9N!&swhQhCf-jf!UFp9sH->M7hnXVO%|VBPA6nfUsJo3mgS`>DQw|x@<>@?yyw>;@ z;YV%N;Zbt;TNp(M#Cot(L`5t*RXud#Bk3(HHZ%>Y=;^NNAq-8(e6V90Zf2TRI8-sZ zO?nN=y{YRyQ#>k0d~`CMZ`6sIb5O(+WyYte&zYb8uv>#*+dU}c1RR1;M@{bf ztc!hc=2Ry_kp8YPMT`^yg^J}9o9%Ib6y|oU*NuZsV7uVYQS@_l{+qG%zjp53I{)=p z|4#}r^W0p$e-eP>=H6}aTVN%So5bxs{$q*?{_uUjiH&lbt{L{RCI}k*>UQAVy$+;4 z)l3kbgH32*!S`H+f(Xjv2*@>29&aO$-^w9E~djdxB zgSka;bW~H)&CvBCm;$c#npR{b>^lSho-uBQy$ilE_fj~C{ftD~%6`IMxFc*u*y3j6 z2!Y9fX?fw4IZG&B2-PH$6heKY$BmF#{LSY|P$i9W3G`;^e zRmyHm)Cs<6*{c)vf-g0DJ-t%0U5N(4Hx@v=k^nRa{&7k+`3cEKbpieXTa5;&K9^KA z+nZ!R81(m)BCkZHMJs-wRHUg5>v6cgIoV5mOdca2)kg_n2WButcM$ptm zP^%3^2}a+|{B8E#ARjSmDAWx!lo!){SIS4yG%!uG8W=v`BQtVcUpnxk))K6$pn9t% zF!o@bvW7OxU%g6ibLfh^^+HvC+h=5TZt)=ATO?q)xvy0o6c84>LsePR^9yxA#M!7Cb|p5c=ng!GQz97 zP>XU^#rwix2*hoOxQt=LO@m$Je__h#Xh4O<7!Z#DwvwXIU}R?2IVjDp;1s#7Vms=wA{ zkw&W2tnr&#^VZ0K^*)M6T^8x3{$#-F5Dfe4vPhNXfb9fWQTptvq87y~>) zfCY6~q#kn&A{oA^F6-}O0JQ=v_e>_%X)p=}Ox*6zP&<9*#(P9yEd<8TBu1Z}{Rxdz%xH_e83kZs2gE3mYE z7^LMI8#gE0*tmY0?-;g{x;UScmsDcVe_-J1mK6tXr=6C zQ;9CCy8?b6A~6J|nL}eNJOqr$Vg~<)c<&)U6dWA!T}N{}`SH8h1}ub>ejekYLAVZK zj|Vp^fj)Y_Tia8Bj|xbc**J{ppzP>Lv`!}$YB<8pe+e%apS9`|6l|}(OdI)1IQKV zD{4NSd#G9OU07NXcyvD~;`JuFQ)^x&F<$?uMBKpll?J8vDvN#h=B0(`5R*0Ic65gThg4D$k$P#WAun6I(?ZRj-~_;aw|@elSQ zMh3PS-$aPrg9OkBE9c%Lm{}v-IQCLwc&If#cE>nY3UgwVV>4qM>jy61NSR39KxcV3 z(7b^(j$yFCz>YB*DU` z(x3#`bM8+%Gh`%l$qN5O9(a?a$R)lZ*@S}oP0_R1O=xH0)1%b(nr8esn&dDo zD&ZeApN4nX3u%tYUJR?G;Jd1l-fYutNPspN#hFVW53^-JyS9zfnJZ0ruy;X-B*4G0 zvT_ro=k1f2o?~*C4I3;QNq|A^6IIv2^uwa1EizU{(=&c z>!6zu$WaL%OKkr+QX0yzWWc!(^kFwU3R-Sf0daS;?bl> z`N(;@H3Tj zsOi$FZQtPixiW_U^9b-u4u}miX(+f{4VT30TN8La5k~FrBHmB~mO}-lc$mzLY!T-e z+X|CIvzoFPt!Y2F_c)kT~p~IUXB8$cQpI?3{XRtEF1FXc+*yu zunsH=`Qf#~lQ>v7(K}50V3l>ltSf%}fNZM>Nf>x z`}fd-inEaxXtedI7{NceQ3Q7lunKf*UTSSs2{>L?*kd2a3;5f!#!wlm)4Vw)?27o} zOZC(b6&_8^@MWO-xOW(~j!tEHx8uANe4C^> z%ex`M^OV+5BtaR3@i_EJqG47&uekrDqNk&GojZhvJkcvuK8FE3mZ!#}@nCcDEz4+?^DyoEQ zajTEZszD0AMpYW5a?XwxQ=YH-uE0P$R(dl}G}WT8y*q)_k|)+-p_1SoC=HJa=5x)-XfY5>r2CCa&H26As0W>$gpmw$8T%E+mu86PeHaZrP&nSCx+wFZA>A7M z5f`?|#;H(y z4ckRUa`ritf?R(886!8gJ}X5?+*^cXKT%TLFzF|=l^=wqJWpxcHx;n(Y}J6=6UbRTe@9|ogL9(vn?@Hq4vP-W zL#DXsydBPo+i?{kmWCJyel;)6C(cXuzl7vTE%~Yt)-93OS_ParkhUK}5q2a-F${U( zvmE*g6>K^7h)}S(T<&3yu&9Fl*aG{(us$!hcK%A=c`BwIc0K=Ox!MZjaWGF;J7=n2 zRQkhX?2Wjb&}l^l0#0j3Z+P_W$X#qnTA7b>9`v8tk%$83W))ifMr1x`Ub1f%a=Sr# z6IIgjDyhCJi7~vsd8&cG!$|-c5K;|!y$?X_G@=5C_Rd5QWd_GV$RJMzXHnv^=8KY2 z2UQA&B638><_a|42{as%r_H=IP7oJ zXt>$rk0IjIsYrr+9ePh|LIlD}g5kkM-Edpx3e@?J2#Y=i6gk`zGbLcFjvq6W`z-R> zbMTpnXqFpy$y-Z4$$8^V%$};F)i7<>2`gRYL@Ja-9p z^HU0t1_ea3-|Avn(3X`>52pVchyzf3(eYzg;BRsH ziYmr?R)fd(1ezFqNuYjZCGPLVJlLBOogW z5gSH8HV&eykAN~ch^jjRTFgOIzY)+%4)Vo=)^pI7cu)feRmFpzS-x3o@xDvhZ+z< zFW(shl8Ro10FT@fgSt!X1BlU%O+An0Jl!B~f&w%>E1?_n{H956_6&yqx)w%u4##W` zG+>=cURZC_pD^Kl38RIQO>y=CWWd^?Uhv_>KMh0DWH&3NDTE`$C=G6kQ8|JEtvR{| zLUE#nS$7K+hNcDo4Ovc;FRnnNzqLTkT7jS$t@&4-`7L^2gZ1Kq%Q3hC7nYLdw2tEG zak==|j#p(r7MD?{M;JuS_#+eMAbuI$s4q9DQVpPc4ZhMO$< zNAA_ul$N5H0}ZWx`>fm*uB64O3d+OA;6}4On}$!gXmTY6S3nQra2*bu9kH7-S#lE? ziF>=3nzZnFm?2;@AIQN;-TI@L+~8+OHhE_sybS{jhwzsaP#VyXw*M8eK`|$ogFU<- z;Vk2i6!;1DW1;!5@;;k3RSBuI-AQ}$j%T0Z(=(7j5qjSgY&z_R(HLw+8)NKMZWnR zTdI@%9!9$Llx`o=vBtlk9ywdSBh52t;lu1nj#mXd7)pA7iySMDZ^c;&?c^9`PWI2V z-+*o@=%QLc-4K;lue`-<@UN-cVo6K*hpT*7;A0AXB;#W$KK!>U1*s7G1xgX^v|LA} zzZ3q$?2+TJB59kz;pz6qIZl)GL?i9yvs+Pu0jM;Rl4Diq9)0`?r6Sd3WRsCQtwHEG zA8u0E)By^K?dS~DS};Ag>L}1#2RLET%{&BP>j8*4kUQUmVim>rW>$6*w;q9S1oz|Z zAuB{1UHOs^Ps~oNanw!LpcA_MYkxp8+?aEmd3%9e+W>CE`x~3^7$j zp`Lsh6N0iF_gtFl9ujMTwk=V5Gv63Cpns87XMW>v z%~XYd8}Yqu{0~DocAY7rDBa2(MnxoZMmRYaDIIs1Hnh0z#9w^ck99A0>&P5c23PW! zk-F6hQyeNb77wMB{R3SHOq@bfI6DLRsMm4!2HMoa3Q%UHuszVg88MfK4r`34o6m>1 z0=Wi4v!JdfCNwoMp{db?<~ju%;MHw{e+p)_NoWMNk4QuAFs0(2pmo?4^>|SG>Yiq= zxId3BP0hM_p}>MSgDk6lLrK`6`e(3Gv=~;uHuV;5ceI542n!>4LF80YZ&v;3{4YJE z!Y`g9K&!wU{bLkBJ}{#kHAuo~gww}x`6(Zd(3{A$g|j7#_a*zc_a&>mB^BQ3>=TS} z@Nx(=aIwIZTT#2J+&7P#Ls1v2{X|3A$%ZnuZkt$(x{|!)ki6tTUNA+eRSAxKu_}T6 zn1tVN)LKTWe;rmeY8|P53~Cc=q4D_O-Fgf@s9Q_*pMhvrd8$f9~PlRBkV>ncX}D(!WUQ8|H0C_z*(GPqz&k7avBEZgL0w*FDb z5=l-%`dIg$DNkxh-#Ydl0!l3fFdMVC5kg0D2Y595M^dLeSPU;xs{67gOOIJlM5Q@U zX2o1p+3+z&ki|xk&3m0L6_V<|M9ncCEX1|pSoJ$5S9SG%%s~he3o%u5IhN{o0jzPW z{=2zFPF`87OwyxYpoBqZCu}zTSoqE0iR}l?XPr~@4t>ABfTZXc{rvS)g7J>4zyr;f#+j|NQE`-bl0lI$*X2)%>hOblo zC!sCDTyNujqpJa8+5}N0oVG9vZ@a zqP99!@Qs2Huz$tHJswYOwJP|xDoN83J2{&qYr_xaZNOQpZccTxzkpl3z1-|e7#7$7 zJ*KRdS~2?+m}D0`U{RJ2ISy^y8pOd6XR0IbT-7~}yvVk4IC|EIa2Zvq zlFniHy;5IsL+6r<4-5W)D~QF4kALXSMde=DY`0> zl8E4di8D1%u(OW<#b z<1)x}5Mzl@3)i#r;l$upli?vFO*x9+;=Z#8*R2)vop#7Vfp2nwe-zEOxR@1)iK%##k!Q^3k&UAwdrg&3QfV5$pk4;)R|@b)`=sqZ zgLKXDz)AcGd?+rsc=%0&C?-kXBLpIKp#I>N1lX?)7x+AH*?w^AQaa3b$DTf@e3+XUY&~>XJ~`9wEcP{_Tq%y02#$Gd`sIW5IHD15|zG)y#|#Mic(T9*|F)c7~087 zUXs_drjaxsqa;LS-w31w5NhiJYxvcHMC^dD$4BB`jbcAC0@(`)4z+2-vElM6$v$0Y zCQ9`*!N65P+AiaRbM)5U3NSRQ-0II_^P@C;_fYl5_Aiq>u?-~YfrQhhU!VyG1e|=JUi9YyfrItF z6Fi@2Hgua{3+}eX%D19~J#`X1jRes6CF=s?m8F$98RtmhzCYvk)P8`WAb-6-iRDay zYL$rMt#Txg;{jN_#HhvRu7`&EbNKM$1TTO}?)n$?{_)%sem(Nhg-0nmB!w?9;zthn zk|pflI5UC2nXwj<8FBjVk|P!Vt2iTZ9||#-wCazzif+N?NaSwcHF6}^r=e(MV_4Nt zd%~HqMu*Lmx*ZSv$vJAi~fKp4*zDBqO?j|t23fP)&kf=I1wy7&R&MhDAksF zb*o&cKf2)>N84r#%OuFuRe?F|wf9xEw}-S)7;*H< zUC_b$l;#k#OsCUE+4S&lg@~(=4?TcaFzm(+Q2@qB85GS6HKklwOO-IP&=IiW@ zqeFqRe*blZoJV)UDGNkp6gs0MjBca5mazN?!{8R715@FomOTAUgmfeiN+<0Fx9H%s zr{G9!Ep<^vz}B`7Bsc*ms+*JLxq|d)6XN8x7U8#8aA15JqLW~1O)*$`r#Q`NnbrYk z*E;MrNrLp&K^DUN<<0a|7(zIzB}cM0=?$bngY-3jEc)O}BV6gL&$T9md-86~2Vp^LhS+25Uk1bET}`fn!G& zipcUO)i%#;hjXy)S7Rp8a=F?4Ffd>aGYrCxMptd>aXU4*{;OFiWULj} zHze|currv9ls4s0Xs6R8D$_bM3L_Icw@BMW_Tc|iD}^WJyVrk3M&tNnQ|ONvePeyqjVT4* zJ<*Y%$CX zZq(rqS*6f*aU>}HaYC6$Hmg)h-el-UA0@MSl7ef;3{F!eqoskH?F{oq#VU7GaEU&v z+Tt^`Bs!JlR%L;yc21^mCZzR_t%-wwqK5LWS>brE%BVEquk;G&tE1wB2Ei>3Bt*`@ zU!&Y-sm;ptOI{2KI!pwXmw6_&)#QdiioM2U&f^mL$L@l)ftxw{W?XcL$J84v?14Gl z!Y?_7>C;_=5v@pFFXA2uD@F-Eyx`#cLr4y@sEC)+6833#jg4aWAdFPu9{Hf^IO7|S zKYV^fu0Bp2&1eIUPk_f6IP8Ah60(UZ`^K@irx(8{&!cf&A&t;w39p7EJoK27D6$gp*cq^K$m3`v2cSq1LLqJC>Hhx ztbg9|D{#tV0ls>lf+%2P6^;vY%B((|4jaN=@RhKwK^*3CaR^nkikX=hRV*Y1+K5UA zwzokShIbk|j|Y7z&x603-H#r82SI-hC=O*nel8AMd}!fEy|-RVc_k{5!4Jd6!A?h{ zO0PuVbFmJo(Er`sLJ4-Ss;!RjMm$H2NE)?Pq3Q9iYWO3{xyP%2g1HTuFAZY>B{X0e>>lEcjv59YPn=fer0sVj5 zpq5KU#=K_|F$ckD=9kk>#M1LZU@tis3u ztKVu2zgp*^0>#E$41LrGdAZ<`gfj@*knFpP%m(aPu#6^4n4_?q8={*H#?g62W`Qj5 z2xCBpsVk21*Q<(ZqK}$b&EHT}a@k6BF?lj_jjRou@}%D&mi4VhYN=n3r||TS;N5t)pKd?j9@-JINq>Z+ zQQc_~f~EY)&?z^Y)oK3;*>oM$^6C0>G2$B zSr!(8XmuSt)!EF*Conv4s`FH5*JsWA#hOq2{`;uSiGQKzK>fXV=0Ka}RZVKv-nx?s zBG}Q~b?|b?$x&pekvx^|gV1G(rv3YqQ_-}W4QhYSdA==1d(^?^QScM)>W(%j_2L8F zw39+t!1VLWU(SV-N5DAYNe-W|$rNILhv5$^pw|QoyIn22L z?lT^YNs6|k*wxrIbn4J_jqGc=RtOqw}d(fYUf45#!2k^4r$i&@=DzZ_HYbxaKG+zqN z!152%ej|vmUd#)3HFHe-O>SIbLFb*Yfz7FgE#HLsvbFNA8X!|@`Xvh zB&Klc?7oYcoJv?sUFaZj3|u^Ya?(76k@jc%X$aofdUDK40K#vbN?7zY#91*!a9G&% zvy)?%5#oQt$qBS8jT!R1zimM;7yMVc*@M8LEexY~9NUc9%A?NWk!s5G*sG<}D*0e&s9fl>K=dtW$JA9P7RC0-Q>{3O&#RV_+lL%;JQ? z_yZ^3L(xYLqhP}jBy!j`6sZ|>aDrF!n5Asr>W4LvS7+(BsZ$xFzQzJejntpKrLTp?U zfM`K_@z>0hQu>pfGwfI4`Xl_Y5uXDz@TZN3eWK%wO*aN-Z3?dZwOJXBOBm#bafQ#} zN*z`p%0eUiVm$u5Bffb+gz+Q1Z_Ta*B8&A2mN3mAD-Pz0FhK~sulelMG3XktHrDukn5i|~hGE$mhF6HebKz(?YTQ}{%SL;DDnQvmWjS6jw>wOb7q+{!b|UF1u?L{x)PV|36iN-A+VW{t(4r=Ul7JM$ zkY3(%KJV{6f1JRcwV!?8Yp=cbZSA!y8Z`u5-uAt3 zuRrBor@!NSZ&OonfCsJTn<6l&4*7A)k2s~K$d4#JPhBQI6#;(@^}f&Bh9ttP&w-1+KpY$!l_ZTA~yldbO!h~p5xY;zLBHY9;XA;=9vEIHqwX^YLNSW zso|~O(2b=<`eQQJXZ2fn_f~dVJzS?1d7bR!c<(~}u^Q9wTE2#67<)P8=zdYc8>b*N znENb|*$MgnsMq%;r}%cSS!eir9XDbn%44cdjh>mLnW8@?hb5CP^OIrZ5I}!S4$xn# z;U|&B-dyFhHS{%2B_{EWTd^`#)*qAF-MvHbF*13p)KUt%-O1$QMe#Ch1YEqhBsx3r zqwRcid>+_1s&&<32otjj$Z#)(0q^zK?5Vu|=ZTDpm{gL7@gw?pe67gz+bQ?m5QDCL~6h%MC%ouJ;*np22BySdr8GblqJtLOfk#f(<5ErvN>cwJ{4uZY|CeVV?1a z+4N$4k7}9A-XSef@+rA=58n$D3r_TPebL`}k2nu!IgjWaFKqQhU?-;k9+|lkR$93h zsbN2Zts`9>tLHl1vN&--!L`Pk;KF+{8@$e6#gVb_M0V z1^qhwUKa76&DLbt)Lid{Fg@0ub*&Xnvg&X3^CDH!K!sfs&bhIXd#h}mCI*s>Yj zvfkeqk_|W42G`s__&Uety0}ZE9dzu7^b8jlr?`+>L)~CORd7JVHf2e5 zy;0c|TwL;Rf$xgD{(5%eK2%+hmgT4g+Zk-WMyIdqy0wE;%7Ij8aH#JUaldZu;DB{- zP1<$NKx%tKWH7SfdR;{|(~_iL?%6lI_q*m8M-QAVJ@8xX3iHM~N1@*rncl8Y7o1n& z8I`=Y)N`%AwkXv3e#Cevo$trQXyz98xlj4#(gGof?oyXlLiMcZDBRYH}s`}}_NI#7;w7(Lexx`VFA*JkKi`DlA@-HGd%Z<@? zV;W3SuPTz=q+`-wVS%n$9A_4Ry&@-#W1MD_bFqGs?bo_Y9A6S{hFFhYQKWzV>2uUM z3F!=*AyX*$1x+$SgflQ0?ba zDkAOme<6eOQNqDEWqpqis`17rQZ|q@!}`qgbXX?T&+HNC6B2u-Rjfx?9s4duRXYmx znfJvO`mO1EaZU{y%BS|C^tbA`%`>lyZ>VjB&EW&?YA;JisfNUE5Q=GdtnIA`$E@HV z6_VM^r0h2DQ1x}U*$NrPqd%9@jFwZ&P~rQb{#I5=l(}9SwmCS?hd9p-wV#`j7Z`4d zY^-6uW2)qU|M9eg@g2}CY|eMq*|&3pT229tJJ<>|Me+w{8UM-$FJpB4gz|D>OMips zlhe;6Z|$Ny_BsQMrTQ8t<8-(5{mKt&KR3RRS?&S8YCrE#_Ls5ScQmW-luV6sjs$v&4A}-Ah-FaUa*3qaV2BJn7+L6No*6lh?Nnn9 zWu~!m;T-C~A^O|2BqPOPB_4zpzhklvO`B#xMOf-E`|icjzQ%Y<6RZ1?>@2d#bX~3- z$Rf~kgtz(zP4_iUa2>BS)RPmENS{B5r{r=`1^wK-`S3Jl)iT%&Ap=EHw{orRHzFu# z-fi%!7egda5yoL`;FoGKiZ5hz>yj^$ay8!`%*&XnD+Or>ly@J_@1Hg=eojMfd5TL7n(_br8ETW6obR&D zGl*)*V>4Dxvt}5^*nZybnGQV7))%WugMvB&{})3i1Dg= zfVu-7qHSjkTB4NNMf$ za?HdHeME*cjH4X;); z!V%OiigYq5JeSGG+^sT;uU!_~y{WsqH^+l#X(=Y&*qwpNUDJA#oM zzKc4>W7B1Njb_O38T7vJi4a0@qzt(~r5KaBIiz%5$PLncXVmMZZXQMbgEHqK(; z!olhY?GSsZhtvv7D8N~S`Eogjsk7qV~m-7P8zH4iEVe=hSWh`WvR0Sdi0_`GR}Hj~sv z)YPOEe24f9E{FZ@cd%3z!OuTOROQP+k<|U`_i2lO)%Cr^eR}87%O#m?LZ3{9&w|En z(#K`P$uo3)RA6a0do3FyT%T`jgDnOJ=+?iUCSZ7_A`QY_3!*(uGf}v8j=Rs0K-EC@ z^!D5(-7<8|;Ay#08M=2oGU?!adGGd0NiOpq@RhE{lae&up%tX4I?(D&%D^tirm?*G z##Aiz;gW|QO1$XLbnvS6Lk~e`_Ci;4Wn3Xo-tw}l)4sb6qHDA7ju7YALYLdImQfh@ zMrH#Kuy4fnQdFU<&4aiP!}Pw~#3pI`K4Y&~K`#i*l?n%wVW@l1b=(qd8^V zpTXk}){s8@nF$kQuUdAgyLrHOL&8M%l3bpIiEAdYORdNL%8yby*{0s`EB2|cHTS7! z{>o;|A!}VMxmbd`rP!e>kfDw0q{e)m^ByLX>#b4-*2VK<^#@~<=i7MWf>BUwUNHaH z6|k{jOvpkavHtsPyrJP=6`MIfBYQCy)7X*jZVOSRyn)7?LNy_rBXpGgBQ_}HBEx!5 z#Kz%r!=c0~SS@3$feiIlG|&2lb->c>yJJ&*?}k_8p|k1mvjM)lM}0y^LG@(1?dk2z z{h@(0UpvqBDo$cNE>sjgNRQ`X2oVzEg$c<%$EKFju0K>QppweHpIlTsRupehMMYgnqDg#VD=Yd+$5}F2fh3ELj(IJAt1Q^EfsqS<3x^IAhQ2CVp2zk$Ns1(uu zqPxp8K2*%$DEo_p;-m zzXQ>K7KL>8+8_Xd3Dczfc-q+`5m zYiEP`SfSl>6!Uta{jEdeTD|eWgX3E5uQXX&kYjfXqhhBo*tP(Vx5u44`fgHVV$-r^zTAV&k}bVH8O@?Cl9gw;{YAU$kbNe}c$~9MM{dB{%l45TF9ffc-I)@& z-`;7T-sJr=3GC?vrQ=#;)0^^Wq4Kgw>Fz%M9+`KI`^-Bm=rk+0?*p_zGc}L ze1*y*DRZ#+{o)YGEquNM!apH@h8G@|MW0&NDBf>BlKoM zT)+9+x?>*XypPR>Z%%%w!I3hj{@|t#a$_Zlu>X*ndvD(m7qlGECa2X*P4-;4jP8_M zy;0rMt-&D+j3xgnvJl)!X|9*$16*01Hc?(gV0+iN5Hw<9=5-BZNJMVcE%z6Vr;p2B zlM_koHu0AweNI?_@na{XaS~BymT2^|C_12@2Vpo3$8+dN=_u!$E#ASRI(n$6^tqA6zf`f)JqE*pO zCY?e}4vKPmiZ+0vsmt4)ESE=cftZIp_D^6vv_r~sk+WLg#YiOWtieG$BD`JfW>K1l zYpTyER?x0k0i|g+OLK~ygYcB6k9du!*aDr3Rmy8Dv5X1!-Rq)%O(WOnT+(_2>Hj~; zWD((0Q)bna>f{+A{bRZBf|9!0%OdCLu?1?iX>j@Rd%8CP#&WM?2uxuxjWRaFIu<4P z>uka7Ky3tpl1?!ovW(R~Zu)3=(|a*7pK!z<^C@br;gS9-t3QVOEjO|CHPmumKUCX- zdc{TZ}?fxQUY`lR#{`Z3fT({4UCE+`iXOiN+3rTOC2N}5K(rwWf*ok z&f>)ZcY6i{>@~c85MZuz>AB|$pEHtg0@2>n{uu}Yx!?0!P<`FbNE2|M$v~Ve%gEx^ zy~*rGNb#F<{Z+9^zg_yU@yMelg2QTK9{mYNRXu-;vNDsplm0A&bWCIQ@Y!xTExvH_ z!aKf`8i&He5SEa`<574Hn~h(5uiq&A;$s@U6Bze+pEzMy(yq=lkkK>R2-l93m;gHRt|O%Zmq4-?jr1( zfe$3&F>+zTC^XjLfNfa%`T-Z-xp30=j;0^dkLzzsR`a}Jx16Q9`yATgnu{q_!)q=& ztD@~cYdij7v%W9sSk1d*jvGwNl8!09A`eo;LOdvUAJ-%-<|pl!Ixl$=prAOJ=NPVA zq`Uc}jeloNW8QY3gblII>zTue^!h;KTEZ|Tjxq+Tz-n=ZD&OzQjJ0`zei{+6Gu&0Q zX6mb~=xDI&XKT+kK+C<|PoKfsuPPQQxA_AbAOt-+&6AksNl5dIPVAjzt6^#=&0JcIKmU-yEqyF z&w|Fwya(WJ{M{^v(yMRzUCu7QyHTR5+emDCOZHG?O@@*ABS|V=S0ySEYM*a>&Q#ZT zj}5Jb!+dvFAa1~ORfs$Mo~n{15*WsKLWt&M1R9qb7dI&a)Zc%Yu`r7UhSC(#sE71= zh{o1KG)(*z(Kr;*wCYPBK~X!5puo|Nqo)+n9E4~-RYWsP5sjmVXktS|V>5|Hk%}T3 z8$=WPC5l-JmC!etamt=9_x6y9=dE1Cnqd>yCp8xO2N*wRVP&@a?b!4KN}k|Cp-7!X zBWgFtdyXh45d^MLiWbs*_JupkC>z%^tMSFC6dOC!Ivd3Xbhr3d{#zZdB=i4 z*GX2<#*Ch<4zXg9dmqh8p@PiY{Z>00ZYt@ylC_a@egNtFBs=%4aliyt=)*wzbvV9LF!GDR4_pd@DX z?+BNP=i?S}mEtotixPit-yKcak^*Z~*~ZWFeiU>je$4FihC;t3@UU`?o+qjxf@FbU zA8pPnXfdyTfSnBsLfH@XPP9X{ONeOz|H z48!*#TfpwK$+v6Fr$bT+qMI(OX!66d6}Mm3rc7hJH<{{meO-&}^(A!3tSdv<>lWZ# zltwf(QHcg7*>S!Xw~X%NMGM9G8Og--6SsWjX6@&;PPy6ox;^9Ii#8ip^ki?^#D69h zcfHy$HJlS*q&a^W!0PcZ*(ZC?dPei&QpYQ>5BWeBuvq}vb}O-PB%o3lEuSb4o0ojI z={bm}tMav5^-Wa6DYv0f` zC-;e-mYR`n0_hQ8G><=vd(Q<#B^5!nUo#_ET~XUY z5q@U6*j!QDLoPosT_(GtT0<^=(`AY)>Tt+qt+@2f#$H#(A+?-rEWxXrm+TfQ7;D_G zpu?D{;4ovFg7L-_fp-{_)Th%JuV8{PT0!Ku6r5uSqf9QBE_BV+y7jhZMZu*r#BI@v?#ojbAF5ZTyFVON<{YxXk#zg89a` z6)Z9~D_Ckgs$hljh=LxYQo(gbiGmx9fcDucUmkFv`Cvyr5% zvU)ZqD66cQjnT>~!Xm~HWtGh*V}P=57waWXQo3J!R;(W@tE_H~50rI}SWhYIUa__* zYol0yqpbVI`m(aNiuD&*Rgn+N*VD@5d9i+1Sx<;nSJsnatx?v~V)ZI(yI4z<^^90^ zmDLdILS=0e>l|f0E7p6IwNtD~%6d+$6O^?}tfQ6nl30f*s~lMw1C&)H(Tq#~5-PHs zN*N#V)%{|uSl?Gx5o$0_D(f(@{#IGz#kx;fM~QW}vO2}OQ&|(l`n0l65bJl9b)r~x zWt}Y68fBd#REvIP7`acvZjc2p|Z{t>l~~K%W3lEQXcYTi7{DOGsHSxSr>}+ zdS%TPt6f=_h}EjB%fxzdi=;Qo?0@s;_l{$-V2kJW|HiQ_CiNq8I0p3CQe@m`NiAFJ zX|4l-iU_XFbn58|D7|FdXMUjbMurtFyzYdg#$@*dnc}ihJPbub0qbwbP|M))_nGj2 z(bU^TBqjwNU&mwPB6BbIV}{|%`z!|osXQFE=3eeN1gvfw5!Gu{Ylj+-b2zV`<~-zv z7RzC1Er@*6vhTsBmHNhkEf(38^)<_5CqY)WU5Fo^@_Zj{1{6anMKJU45$y1GsX}rD zFMDRjFFqtG?s3L*24Ba(qFq4Cj+KQT$`YJ%kzW>xXbJw-uYj`4niY=eB_{DYzK;i& zkmi~7xghnK5s1CltWa{m%BF5_ZC)a2{T!pz%9iMGZN9ygB6N!2&x0+|sx}8~j7sNm zNCh8@vP7GMDr}^gB?H)4S%D?HonC83MljmEKubW;N})7e>RnmJJsoh`1;(8M^p-%u zSy?^G3na#`JUzpl+B#Hc4lA1J58erE3P>t_bR?OXXBdYNC}CB2H4&aZgrujBQoG_; z63D1ULLp8DUZD=sypllVG(o82UqIK!`)WUDJ808dFgdaZlR14cSqt?u+wcRa1Umrc4I815QDF)Z)kg6d_{4S(ZxfmYi5HQ8QrHv4 zWhQCf~bbIQeRN7e&fSEw%mCnKrAh9lf8%y*-hP-_UD9 z=LhBh@8zk5ACuhT;4N9kM6p0wQDhz*bAik0Df9vkN;0WfhA}FEu5ohl;*pKLr-e$A z3PIReu?d!Gk>2S<63*&LUZmfXxRDjm#;+}6Jm&=ol31K!G?50lceOA_pA}ozxZdt- z|H3~jHaNidK&;dEdUvkeU2m4hsr-XQY8nY^4jwu4D;ZX_OU|Pol8sxApwEo0K8@#x zZ;PyVJ*--JeyVUukJ@6Qj)WM=|-9?ph&ZorsJd3yv+Kon+#o@;`!XcFJWZ&lz z-XR&rA80J~Cc_vMcAp7e2T=|uK%@r&$>xxs*D{bZWzLL^STdRwtS5K$VCmj=m1Osn zUE!RX!(uKY2uKckiwCit)5cqfv^1Nss79cTJVoT_q||W@eyWc63=CDU#Im%fdesZU z1*d8=RpB{O9FO>cDz{b2?Ylf|!&k$>%ri;RjU6tY@yTX#RA0V?UDV*m;c~`MPGoED zROPEaLlHWq2_J+1@7uETIu>m+qBKvy>gyhfMF zv2hLcZW)xrTv1HU3ReSOWXI2l%wDFeOE)y#RKlo?r5kD zdr`2%yB4B{8;1;IIf7Y?a&#>RoAo^h2`o{O7ja+Wk-2_5@oF2MTOD13{tImEzA7S@ z$x5`-b2GA=k0J)4gaopRMBLN31Kk0O7e6ERFyf*qu%WSyEaIVij|k2b3WRUViEh-Z zV1PrH7hC%t-=>Y%YS@G9cX8OL)m(+K9W4J$H z*>J8y#wTQnsymS-Dv5l!9Z(*=Kk7u$55U1QFD9;+fx&{j*uc6>W?5ncf1`MuAli-r@ii3P^GsVZ@7cvu|y9{k3jO_8jzwN2~2xju2z5gQx&Q`Ip>5YB2^!514H`0 z#3;d(tF_u5Mxp*`$BQrxjzPY49h@vN^E5BD`7_%jt$ojZ&-dOK%RV^wbAI=Jq&S}I zTT#SKB##yZS@h~Q{SCoai4&cO*@-PB7An6~U--jLwyyUb|1c)AeH@ifZv`tj&S3w+ z_4^Hf(B1nv(rRjtOgdE(nW&O;@8>zL4KX}gFf-7Jf6(e*66o}OXq~hEPkQ>{RN7Mt zWj5!De$81jCOZ*rg>AB2ZUg^jV}AQ;jX6LyW^j#OeOPZP8S_2WmNaDTpUjq==X;}l zwlqiL8$6zK{7)#Fsy=O@N!nd(cejVy@N|_tBxp9^1R8Lx*?^(eYY(?xPoVXu!cBJ~ z+;o(qr{VrJ@ld$o;vBS7xUSLwptWCJQOBq^AO92h&S}5!mY#EZapLQcy*Mwd@6=xx zq=T+;Enwci5KN|@7J_VtUQ-C?Ijyx;AV2BUV%HIL3n;|*!TN_C@{XM= z&Ps{wPsnJjtI|OsNsV+uy{R@`);u*m#6tT0%1WjE>8&Ns3+}lq~6#<#s9IjE<+Igvzb9Ko0CSSw1!kY*LQj+o~w~N`xv* z>YvioZ)YbqgGVVP$b2D$OrhWw6N|Xb0+qhY7AUw{ArUS2Eq(C##?|nsS2qfUMoH7M zi|gKd`~x{6A1}Cz>3n(^&N1FjUssBE5CS#+wO0QC<{e#5Z>0ZD=5^sCq^-q$CU^hO zIBo)^{U46|_c*Roni-BOnED@%>-}%faVOAD|GhZwC`uIOxKg_RJ{)&4r4f!RB@A<1 zaqGizrNIAPIIb$ompSf4iuliP+?(=yIBxCP8rXH8X)em?+%=r2_}yER8hO7rg`<@x zWzy=;*}@aO?f#tS{W;tHInVlYw)t~*Cc6{7*BbZhJ&WmMtaI2>uyJxPsv-~h(|2ti z#0jp)UUPAv2iqVIx}xH|mg&JiZ5}keA^oSmt{D5{-(arRolyVSY0VKxePfz!ZFGqx zdv5S|XqjWfE2LlME@Zb#qOyZ6_E(#HMxr`W9qcnK_WExUohfSYXC;v@$^1UspS~ry zy(BW5QU|FBQ-tj*-8DO|Owr2W>&}{siJruoi<3Mz)m)tHd7%Km{+<{yMJ z2Q~J(*l<1;Wtp*&LwUFTn;$XL4q@l9_ps0H7^vzfX;B1P-2QkZF-oi*x8NO^e%bHd zWw!5tl7Sr~aSJu&jhv1Co? z+2e1uV2kaFpbIfrxbo$aEvrf(yAka?5}!%>O0V8`MCCS#xS&q#hG+V9@VFVLpG=X z^ws$|2Swf4CR+%7pU#!$P2cKAoNv2qYQDwhnXfB;&2^jI7p6sRh`QX^;J%=z@0?c> zpGp;XqNXx^r)-(Z{lR%t$9M;&r2;$`@k0;qd=}d68OEZ~bgT3yMLOW%`p65vw?HB8 zZM3t+;*Hnc&x$S4JIXAm{abTMtM>9PPLkvjynE`mFoff7B*eB_%nCl z+IM#azP%u_qqT5I#?9PYSN0&*msFzbT* zFjTgQ6nGa(RH$F$tKN@TgB(P=k93IU>q5C1G3x?~J3|2nCND-5KlwV(^CeMihGd@1 z^}C<&S8w%KKg%{+cEGzoFl81Sp^yS6)DNZWvy!y$PRH?p?mg6GID)rv zZ|!xxnZfUPAU7g7P8COFU~5Vuk?IY3A;dtC5-Z=wAJ(gDV%%E_{j&$@&4qrue^I1= zZFJ9B_s^G@RcQ!+&J*L_Y;m`Vc$j^+*O5A|v&DTvzFOQT4g>`tpAyZQaaL!;j7S}gaWkxw zwT{yq5l9DBN{E>_$gRDaLVpY!X0Cl+G&6e!i&~u&?|`DI`N(|C=E2Dt%`@a~92>nc z99m2+N)eAZf{*8OY*8AYff?445$Iks4-a6B^{JMI1?C&qjAdL@O+&iKuLBN{U;@%=mW>sr?@jgeoT$|b{ zY$hu9&wI~WxZi>xHd8J5zN5-|(kz?ct&OVfB0~9(q7{sA^Z;{UKb59=1u- zZgoF9Uf@{ovy5w&7Jv2j2kg7q!`W5nf^g|4b*Lis=bYow8-Mllc3(D`y(BRTlhd~| zBH4YjgdMu7x7Z(_X4-ZNKQ%hs^2G>(=&;*RY_j@!?@$;l3PM7>^uvxx63AD*UGt8Z z9p*1y^n%wlu*iz&b1Nb(_C_9f^Y#-Aj2I?YpP4Pip@~ zmp=Ux%ry`@)dg?et~XU$x#k_kev}N24gTquASGd|x{6Os#H4&3k!Era_|v&ivFVpo zQ1|ZARo=pCALuCt-TYf$Cu6;u`BYbJi{iN6PDJMz8sNB%!g0^>PERX5H_UO*vx|$Y zou$$5?Tl$s?8|bIC~W8wOE_-#rmveER~*(C=sAsg%Y~Ck$Kbhaueo>82GjNGy1L9x zo+*@f3Yrz?Z9KZVaiF`Aw1xA2bTkNJ~STCi0*kdo$4;04i zgS~a?Ubb&xcb#gQ3m=8^exNung3Tu9{UpSB&--(fRXFcwFPohAJiJ;sZ~AAmL!9?B z#d*)mS*~#2Prz%4?RHg3%uiyfpCx1V+0M}eplE;k2M~3kzxu-VA?WJ8uL&KGV}rJ9+#7y(ov60$Ql$mUg|1d}%AmXJxE{03?n@FyOQDx{w)VGn*+Hd0WHOc|=%dF3K7 z4XLy({_36f-EfWp_FuH=sSx(Iz%+-e3!46{XR5Hxj}{FzRfy25na6GMwM6=iNTNPK z3Q+SajQ6^G2N!&%r^zty-ho2S?+5{VLj(-X*}o}5Cn(+Z=WIo|d7=>U@h=gv<&>gQ z@EP+lbm>*(%PefGp1BqE?WD8u;X>={9 z*USE-kXUGNhs2t^8&o>8A)L>G8}v*jc->4FRTuf5^p8;Q*g?DL)eYy}oy<#S>pAE2 z1N!Uq59t#@W+NwKjvoD}JAH?=erBilEv6$djxOmG_PTUh1p?F$r4+`rLeib&(=iQ4 zHKPdAwYN(V_$OBq_1<2h_Irh*p-4s4BNb8ay(&?kcgIKQ=}+kHJ?Oti($aIsR@p<} z0~feO28Rd}eaY^c-k~y8ZZI^YS`MUICpRpP>e$H&i6|w*vt3;qIaMGjqv+P_?; zFC;aV*!DB9@n<&rGus2h?u}_9^?>ybN*&XrLl$nM$%qH7IYAVVu*glL+|+{37z1}< zB<{FJI6l>@-nKclo6%z0?Hk;|fi=m=UfY3)$#Yz9RDFuErWSTbUyfjUesgP0hovFS zVt@5u!;%Q@cc=8s-a1*(i=?6`B94-n=P`#Nhkw}e115Jw%F6YW+{9R5ytdv{P0S1_ zsquW1!xOcq21Ikb_?q1Mm4_oDV_MEPSv^s4npGSk#m1C|2Ybcl(6m?OQ1?QUQh^v5 zb3i}(YmEuVxZ|ENt~Wg+TyJ?|T*tjbi#s6z-(1%iWO-Uv!u zYFGP#xZr!iJ6KXfN4iQil9^rO%YuaZeP%vZmQJxcTEuM^-W>Na2QZzkkL`8;PW7^k zd%-B-Q5w?q_UbOG!BnX$>AYEsrK%Q3%vu~VYjGq})#8X*iz8ACE??@0#=Y*j8B|HZ zM*+=(zwRATdqfp{Fp#V$;t^GNrLWTCpo+Ls0TNOb07lXX;nMSI)xtN*p72Yx|1`#8 zv)F$QGjyLzI*81Mp!+A1jKcU&R1pN}KT(Acyn_hA`%fh2FzWTTUrXzQ@0%%vQx*F& zEd?m}9udN~VAd?Q!g)!`cxm;A6PrCFCp9wIdSVlsRbYxARL!7S%x2KI+cmD*cA;%t zQ%sAi$zCT4qdc=x!_&-;Vp9o&AR+ZOORo=QvRo?nrRZ$iB z=jzcEb0q1&Pe6MJd0bKA;+b3&2wxZM>8cSa(mi<|+$#MOXp`OvbV%O>IzycjYh;#w z^i?5_5aqw=8AnS<6PX?KP3fR?4e6kelXOt1OFxRPQ(}2y2~22jbWBT-E}pwoQsyNR zlK~*AGps0n526u!*nCxLeYgVQ>%NTa$17ghjuo+`4pBkN9HHUgfG+jwz1=6Tg22M% z47OeWgYW$@P4D*+W3pI%?Gc{JMTRvFfe_JWLnu?o>HJI!x;!T=GQJQmWYSL{;lhG} zr(vBUyd{db5d4ZaY!rZ-eYf|N1Epm6g(WuzNdXQ7$5LQ404*|x4<@;0Bf2NJ@dO*2 zNJSZAshf!DOqGhhAzRC+#9*jK8^&e!owpMVo!GwxgzEdE)c3r-;a{b`x1WiObl82e zGpPT*>GLT4vhPo0n*Ky(e<<(TBeOMCD(f9&ERy`3TCgO`h@(Z6-}s&lJha zGM17U+i!YTaDFQo9B>~$!KzBuTK z8SWTkBPoxaZ2S}ux>s?lnODb$vP0j-MDepI5oUWg+W*u9Qdpo5drFYw4#XyanwC}W(NbVhH|Z&tDi-5}|zvYnrKjg@`>l1LH%;V0N`glTT zn32%k;tx!_GIsZri00-v$!3iUgfb!rxSn-JT2K^(%t zzt$)Cn_whV#e<;;^XId)QMHx=@q(9`%lz&a1WBRC-Brn@5uYM~5-p(6INwA88`kGS zZ4_!!)hIhdjUpn|x}sSNt{RsnThg-1oL+KQ=Hb?4DNmtZk71L^%IcQ3VGquc&6p?nVL!KiGvEZ(bK@!#M zPq9igRj-%m=aEmPKY4{POsenpzaoSq#5-8x>)PVtUvr{)eB_SHFovo{6Q_WOrFLn<_;n$vU zn@SFeU4eQhVQE`#FN(|GY1yGrpXCJ!p8SgZZWv*vk7z=ufc8gIW!A51XA+le@%|Np z5{dJjLaI>@yFRzqZ^deCDGLuC#(b>)_>KcO>xZBWd;N!?7oKW=Yy)n+-QM?{5T+LR zp~6p7NgR4eo)V{}=;f$_o|0v6swuM2^@`Ax*Wpvt$MwP_Uvng+ROol{i@o-<%Yu$p zv)X+*S>j1LltN1e%5DD+QbN5*Rag3=Jmh8~C^RPgP|#$5;$xN|W;3z4QY4VLkK)=N z{TkTnI4-`Bfa=0R0-K?UFW0y}jkI*tu@VoNb#}d8<+AU-lj^d6;a6UTt`}6jhm^$S z7W$`x3^R(V`DCeiBQ@UvW36mTIv)sZ`-Jypvx+hqALj=Gl0{+@x?PTTW#~;ASw*4_ zE+k}catu{hla)%1HENu6&>u)4Vu{An7f(rzAIu2UOTw0>5JT$6i2E=jZcwVImViVv z*^rr-t7+3Og4c(-mI}kwamA+0zQeTlTi+*hU11Fk)h1d$F%j?j)c)vx(Au$XFEZX-1@{k5Gt&%}{mKzC#WS$xuIs(5Q-h<7 z14L-iMnSU1<5+!8O$5uWi683+dh{MA&LkgG-c=;h7cpUBb9b1rS;ZBZX~Th)DX07V zEJV1IvyA$q^7wC;@mmJ=EaN34r!$QEX*$Mo-inGM1+-Ic@nVm>&^T-C6uql_$oo0DL@K0bV(<8Hp^K1 z0_YGCaMpAnPpNV2nQ1ZI(Sj}EdDgEbs1l$SNoi|h>&QlyDXsec@frejycRV`Z(97M zuKBGA&6CtpObd3Xb?zv+)Sq;0&jTscm3_QR{-OQ_R{sK9awhNC%B>+J8ZvoMll`bJ zJ@Xs_x@>kfsXZDt?YVcWA3=ctJ2joMWdrYwxhPvBM=ZxI=Vfc8(?66eo$Q@lM8g2u zKEHvYW*(fBZ4sCIj46I;VWay7{Q&&8B7(y&w4+6s9#wLhg0%TJYX|VK5IGeE9lfL-IPR?i#a6u4;6g~-#{OM=0~MPH9OB| z0j;vuzR6F$-GL}@~!CxHSTqd*Q20cb)&iUNYx)AK9;1H((%y5h^~;{lM-Da?n%;Fpb+UKmk1@4BoD#fO+4Kdr z3;VPhme5mlmtJMnTl6D>Z4<%7vmA>#8l`p@yNPIq^}OwON#z!xy`j)QV~|?K$uZbr zxrB}u14m4&X#4RF&Crl=v7_Xd{QytncUz@Z;Odh(nA-^0zP1Ol^SGmJ*|d{{Pg&k8>+ zZrlvXs=_$x$7*sE>C#dP^ODSPW2EV0%#m%w| zk+p%xEat|`HO331W3CG!o40~9xquW%@8U|CToEAp88sL6+D!(ZVdN8jaqu`&4>T^f zdp-y+i)->HTfbo6h&O$6mxkCU*SM6*6Y0i~l)*+rfx?`rp{f7;~as8E*kE2xch6{VeGk`V;6x(SiKW-5ao)+V&2zon1y9RD zlVf4*1=34m-!$4k%f=g~bb9z_xLwgs-*uU*`DS5I#*&dyV&Q)gNK7eO#_@dj@J@>P zjF3fh_xNGhyT^~>x6uBZMoZ!N?oEZ0CQmNB`!^2z<99$XpV%F772k|-d}3eRihcMx zWuJ8P6MOa{zDF-p-%Ab^+9wRpFvGoFXdia4cAsO-D2d(fd+%O6C#B#Sh;lp@;b?j< z%CfJ}zL+$YG?Q*zk(tK(gkEPOawC@0c%tfRu~BGWLf{FvJI%x|;eOh5Ure|q@8Cz_ zmb^}!?08CboR7~)^#p-BffBe4gC?!)Nt4Y)oY-%7V3&l5NGYF`zZ;eCsePlBmyc|Mpr{6-swfd=1J!6eaOAc> z-a)HM(#E$V9G}uaBt3e&vQI*h*}{{b+8=8C)SeyJsoa(*NEm8Y^(i>0Iybt|zUZ{s zR5TMw4c|jh9FJp0@4_C4+D_(8?=dGL!pEa24(+!1ZE&)W>Yl_d%{BfcVS$rc65uz6{mUa zKVO2fCnkyGYorg=jA7KazdbFXP#*vCwQu4f+)aV}1e-UrLpH3ogyMT{`#*^r)$vzK zgt{^#BR;LA(g5WXIyIQ{YU1-cimj<3sC;Ai6U45)<#4`}J z1=9c0SlMN!@jmJO?XhyZnfTx29z_1fW92S05yd^WVDHC0=*|7cN>cnk94nco!`c}x zhvp|(e+N>TvNmr@>_x4Nn*<`|IOns1)Fq5>L)kV62kuzIyelwAlQ#QLw^z;1-u7xx z_TKi|uD;Fo+G2*gI=8RDGZ2+RDZkWSJIplxetTt@iT~HyYnhpdYOfUR|G%`?9BH92 z^B*D1zfom9lm-pA6D>G;msz-;kzmi4LUo*EUb`jS|4>Y43rvsI=Nc$Dw%^K5#k0SJ z5iH|^MUU4Ryv|L=%l0e0+y;`O$8RlJDT&3Ls$X>AdX!`CpHv_x5Zt+ue0?)^W1 z|IaY6b8m$9D&_>{4CWjr`jrT62<9ftbj*X8rI-@TI!qnrNz9KidoYJE?U?fz+p7^; zJmx0MJ(vtkA*KfNUCb`bA6nF>e9R-5CotPFyD@EcFGIxP=e!OQ^2_LB-`>aGiG3Vl zUZDJ9Cfunx?!qj>O#OxFcWA2SNX7K^TUk(6P+7b}^OmhDD_>jYEU2t3ucTacp*U@X zUwuWK;_@m_WkKF*f@xv9({$>IeH#_@)Qu8D8*$fou2Y?XK8ua zO0BqTOP`U9h2UR9P#RVI?*vLZ`G^)se9`>V4wN@b&H*dr=Ki2LY}J7;XleKZw0fqM$j0Hy-FfcF9& z*F`vP2TlfF2h0Gvf%(96;5y(e;1j?*f!l#M02_hxfro)pfbGCxz%JlTK z60ihl8x`SL2^pgU5g;_v;*p7P4|&a!fkvtV_F2mcVC&8uALU0qNnO|SB+$Rh<+AT!T!8C1E*r6(;ZtG8^0 zFlUu)mA9gzywW3;APxi9DrerByyDWl<)zY}RL*7P-jzkp)dj053vN9n_LlVob$Tdf z-pagUh_KN&n$=asE@N+GM91S!*cahuzN z+r0dIvaHH2F3a^+QK;}YWy|d;0C|Mn3-eYNm#)th?>@DoT;*kDAe5Tt=9MxC=C79| zD=N!ZO7fb<*qtjyA?KAw2a-r?Q}sB2kxqZdC=UT}Z}LT&8NB8!lUA z!PmVstB{P!FXXNjF)rtN%P7@~q7dqPan`?>(13@b-diD!7NUpTzVr~TT&PScGjN?N zxKR~O{xmV2c!ded85?k&yFT`rW4dkFtdlV+~$5xxG!WzN2|rvmn)J(HlE zed`o%6Z$}vr%&haai?g`@14CAUV4Hv8{SmE^u#X1YiD_7^ir_?M| z@f|fgq_$9((6_TMk%0SRdbp>!u(&{&;Og=1r3EYVN}bEsdkUOYbe00Rg@i53 ztDy81mBo2@z$K}Gr?R|MxQ5ACBur=yT2LTOs})x{^ZGKr5bm5|dJoYq`0q#CJ(Ump z_boO&(xh!?n6{lOii%6~1+^;_7cu#$a6Q6?v+PSMecV;pFiBIDaNh{e$Y};OHe5NT z$hZ;a94ZYp-h_)l*XUPq^Sifig}!^%0rK6KZsof#r&8&g~JN)EmBk zO1llgh)zTQMI~V=2_uCnY%foz9Umk_183Ca}=@hz6VpV zu0pFQU#pdtuM~6ZWI|LGm&tS)UQ?x@C(r!O!$aKj@K6wsFuV;*)z>T4SSZ0HhR)+#&4;Xq}|phBzqL4RjIPwKs2$>sw^lFIJ>};B@`s~1!4P~GS=j*(jO_9QHgCu zUg-jJI^LB0mw8t&P8^x<6viIXP_4+{OEdGz*uMPq;b zj{TtAxR$@pdu>*mO^jxZHI3<^{5C~~!{3vF!z{!s!Q^8qFdHzBVHz-7Fk3O(FxxTDVs>D5Vs>Gk$24O0 zV_GqXF>RO=n3I^(n0Cw=jDb0e>BOAFbYU)Gvi4dw~Vc1$Ct9ix4fbTBEHd`u1IS`Pk(nH`h~CEFOI1<`(8vdBXNJYF!-)Ch3$`_QWa3Th0ar zX?iLl?A%;t40OB|aGP8fXmpm9Wz2EHu2K+ZS%GY|XiQ;B3p@p=p4YT{?qTm}8h2{2 z-;Kjq%)>e1b%+}Fv`K`Ky`RKHO`9|cBX*4J7frh7X6+W>cnryC(}+)S?H=Gn-~=|E zHUgJoWS{0HB5lBOGyaK~NtjzO<1zOTX&MRKgna{MDQ4N4LN#lby`W`lmiMs>BEF(6 zlNm;Np?GV{N`)0MCuJ$S!nqQ@pKrPgV#-#U_BGNjvRd&}dS%lB*JUP}O|;0aa6e!C z^Gz-&lh1H8=L!Y@Z)Jfbx=h+GPiBUo^=k1$>GzEeXJiaa@m;4^i>ElaWHX;~B^8XR?t_*io1WMWZw!;-z>cw=waA92k&Ctv8*Ry2@ zxfl0Lnkr?5>y)~O{TPIqr}ZK0a0tTm5XRrkq9@EhER59gOE~*G>Gtcd9yMhPcU$K| z`n7Xr&!&R(Gv{>ax-&}i*tP5Rak7@5(9bWmvNCTy5kf)JSh(j^t|(gHCz2$GKNA+= zgwA=(OW?FlnO%hXr1;DJam6IY0AL$%AaKIh%zf$_pp43`K-ouk-eT^%*8qo#J5cs( zos-S|@-0BFmul@m*>BId)!e^s1m3`R>}}@0ZU)fFcYKn09#8|6ed3DS8C!rSfwH&R z1(f~pVRtaL0w)8zfm4AGYIkUp`FEQZrwxKzJGDY)fk;!6o6btm7I_#-_{h_itMYiX3EEdFRT1T?0xqXi zl9H2B=TZMszIy8(PUnuEbpH8zd&oo9PkE&0#7JA@h3Xzo_s*Vly_BIqTSuF)Yeq;Z zg_Bx&DUq~c|J0HIsZAV8TU6m<`U@pV8wo|2Ez`Grw`o&)>i^HwQ!i!orf9a`ZS=Y@ef{(0XQzR-m9(AwmZ@?V ztGtV~M^tUhe0y^X)AMawFTMQp`3bG8{ZHoCpMJua4Y&K3OE35g(^R(R@n z!#McIeAMjoLZea_$=T$vt5w3o;@Krxi*lwI$e+3CsB^JV!nKn(rS1L!+BAyCI zTyLeaY1&-&v1b)5*V6MUwbY7A;CgK?dCv8gYN_6p>~~dY^Vl?apnQ!svtWgUXWhJB z;#4XN=@NHE5s>(5L!9_(PmVNHB}m6x#l8b+A#-K!H8th@{0r4mcfO?{i};ldcj43`TQUm_ zvo%6^;XmPcGUqaJZpQEZHq)sh4Ksw9p3EwG-ORKr`?!Sj3C9ZOC%nJcZ7yj_S!a=& z?E6b^l|AQFMTh3Mlxl9MZUSXbC>6L8xPW*Szop8Rwr^0!vrd0V0ACx~cZy5~)d*L#e4=(ZC770l>*XSuain%6c&cC~J^3pq%k!0AqpKz&PMC;9y`8 zP~`h6fU>S!2b6VX4R8ps0VwOrEx=*Gtw52l+71-?s~tdDZ|(wK2iyac^=2bb)|;)s zQNT9fXy8eptUKF*V}J(G3G4)p1$F^t-Kot*t`lGbCIB74@xXYX?Eg7|vY4I#{3>uV zQ1%L^0%ead1t|M~X~0Rq44~{6W&`g4E(6{PECNmiRsfTM>wv<6Yk>Cx8-OXmEx=UZ zR^SZacHm6l4&W@{F5qn79^f2cBXBOT6?h-84Jd7X5;zao4itJYfLXv!ptOA#@FAdf zpDC|r1IlK*0~i4T3^00#m~2^Rw_;yV`T z0mcDqfP;Zg0PVo7Kq0tif!6?qriTE9riTJ|;XVww7dRZ)3LF7E0gMN>1Fr*~1zr#A z0*(Y)?}r|M4&Z3uDBumi3BWPHDL^MM1vnOXKk!CiHgFs;AD95F0FDQ40Nw;_0DcAd zB=D=i?ZBIXJAsM7J-~^;{lH1U)4*GR2JklEIp7qamX2H~Fcx?RFdld(FabCfI2p(t zTWuQfE?^qa1zZTc2e=G)FR&Dt0$c}71=ay)0Ji{V0(Su2z~_OpfQ`V}z{9{fz>~na zz%#)6fSthmftP>}0BsLIN5Emg44@PEAaEiu3pf?H2sjh?5O5)|0GJP41@r(*fpx%I z;1*y63}hS73Kae|0Jwwifxzd1gMf`dPLQ<2Kw&s1fkT03fWv^Dz!AVp!0Umwd9*Xo z37iO=2y_8w0`CE40A~P~09OG$zz7&s9ncEg0vrI`1{?_70UQK;9vBO31YQq340Hj{ z09OG!ff2&cGDrs)3mgE92Mz=#00#jl1Cf*0rU9=9rU6~Rg}?|HUOvzYtN;!GZU7Dh zHUI|!p9IDNw*#*S?gYAk`+*TK#uLDSz;@su;Qwy#P2i%c+xGE6aYsePM5Q9rG=rR# znK|do3@UDghKfr*q@tjp2*~30XyTf=lA>8@;%-H5Dal%sf3yb%0e#>oLx2r{7GOhQ z1h5S-3Mc{-fIh*{D_{fQTwp_BHtT_FSl=G&U_H>udf*|}1It+73F~1!@G|Rx*I6Ed z^$b8c&>z?k7zFgu!ai9JG_o8R&T=E{ljXpnECQ+$5)mjUpK0cq$*dpp<-kDT$H4Z$ zT|g}`7bpRj0eb^a0Hc9tfFpq?fl0vEfKz}j;9TG#U^eg^a1D@Wz&2nha1XE;SOPo> z>2&NJ>N@}q$ooOL|w>qjeRNdRyL^1;9YmZQEF(1LsqmLu;A zj6j}eO%(7sU?-F_CWt{EERksnrKMV{2?g0h^&jLe$ zWk3t?Nnix91Q-Q81?-La8USOE{{WZ(JP*tOehAD09tSQ4?gg#}9sq6vo(Ap&ZUPno z-vk~7ehNGdTmh^ARsb&p-N5U>_kq5Hef&QI`U5`!1_3VsI{`le8iDTs10lzUf#Jx< z1EY{<>=B845>SggW0axDC$Jv-X$Xu%J`$LU`p1dLrvrzgz7cRb@;Sf-z|FuM;C5gx zurDwVm=AOUi-3$77^@sYegVsoHv`L%XUs4Xo9LtX$*L4G#t(Z3mxF_Hr~7v;|bbASVZ z*(lcobCI74?1X#=U>@>gfx*bP2Re}-13Uy=3LJ{^$AD$XPXL|+&H+}U+(txxKCm2l z5qK5(xxg&swLr~KAOE!gKj36wATSfy9ykb?jdeE%YLQ)cA z;7*Ji1{{g}v%p-`2LO|h9}L`vd`sXIgdzYkb~{7|41 z`BuPE=~C&x_I#!wSr1}K11WhrwF|G=89K3Mo@5~2dS0dFIp(5wBr*H zUWwQVuS`!rJ}cmrUcE16z9jjH2JFi7ykU%Iy?j^1E5Y+zAQpG+yy89Un&25X7M$QU z-qVjy!g=vIH7|aCk=J-n`|+Of((#;+SEgrNzC+-}x0by4o{|^eA}Oe>pU((+O{nIJ zQa`~{j!&b?_2f4>mX7(z5xzT6IHu@EDCFN2<II)s43qov z*+m4NQYiYtbPuGdBcbRy0BPz)D4sO+k<)2%n&s4wP?Sc>=}e@1;|YnPCoHEH@_9Vd z(MVH2Lh)pT?US)Ork_HZdJ>AKCoJcC7Ot7&Q(r=nVjJoV(;T0A!@1aoy2Jf){pp&C zNOzUTNe4$*&b?5NLa~D0a+-ak<-XJ>&da{kDXudDY3dc9^(Z{#9=mDiN2y;NlYGE$ zS0LR(9-n#^idhGvoVvy|_e*`_m|Q1yE)*^LAx*vGI{P9`-D7$fenujf;gL0UQI!|< zF%+%2PS%H_HP<#p-j|Y|Cbw78)LXR;b(eA^AE>{SBl$@k=GwTP3G$lz%4_C(7ga9Q zZ_dlTQ^)x%i#kI+XPSCNU1yr(Q{TzAntP%CtFjv8L+Fu@nd!S#Y-f&III_P&fGS6(jeW9L_kBZGG?G>9* z%9G{3s?Ct6Q68BoD~>{mw+<;bpxCXqo^_Y^sQ3~^-ing7WOMx2&f;YpB<>17*)$W!qKutngmhb9Y&n(>+}09=zvM)~D=2ojXeAk~(*! zEGcE~f$}<(xg$OEk>AQ3%G|v?wn?5TJXZWkH_tjI;BQ~67NE`%AWB za1KT8${c(Ltjbhb$0%9WoTH|Ul=&11sPpxe*P`&PkGxxD+$gzR;agu>0t(;$dR$tO zqAlvU(XwonaTT3a#^oC~>b|0bT;rWG;M-r-o2p~+9i1xMCp>BD^I&GJ8Qo*HVO zr#*X7WI|h1`K8RSSgay#wU1(n%9^{$a!`3eTT%4y33>fWn`n>DaV=eCIVf!+W!qQx z&bV3`N6}=Z&6D!;d8JL1$6h&3ci5FWS645243c$E>D$e#eUw*ue~&CVj^Z_xc?ZfK zMM?Me$c1hC!E2~%i;~x`zEkKe?@W;snqcqr^ZYc2y0%#CNllM}k5|)iawMXxGhU7w zm2@Kfnc8NY9Nj48) zN-Q*5<`3r$1$Ve##>}DkIbKe4F6Et{V)x2BFD1>NYV5=}|F_eO@|4&t6#P*lG$pR$ zyJOXMVsWCV=~41J6#Y}8dNs{8DQRVWN;*-VTSNG!rpqBIf|Lyec_V_)x>T>0sqB4%ccO^X*@>KgK$TCyP zCm^;_%lVlOHLXO@N*jKL?RNR?c~fPbP}=YWRNG{FmGhG$Eaw@@Pv$Yr_=COFxQ(Cr zW14Z2a%ZH(Ps&|@;)9ht4<)V0OHI@Elr(>;=_Fa!O8Erno*IiN^C~frqPt3Lt-McF zVl}m#KAJkM#=**66yH#XLekVFCBEcm6V$j?xntrd2|}?S?oo*`6g^hb{K@Zqpx%!| z9L{))>9I0@l=yGFtXE1LrmRPepOhT?Fvc7&?^%fx$IJdkiHnsxF(qDB?#`5$Nzqp& z&Q|0w#Wq?L6lY5wGSz}Q^5i&pMY_-P!LE9bU)Kd$DLUP?V<9q)SPz3a&tWp<@K zxpO|Z4@>5HUp;>xoxwj8i+NVR${;IuFerJ2$W2t;#THQPEKlo`Y&ZWfe z%1NW#U#q&pPZ``!^L|iyx}e-oDe~s$qF7G3D)%gkJe2!Ee)56$IBb)O8P)q8B~td@ zvr?k`^xlJV4>$?@R`1=Ed6n~>wn)oVpW`r3t-76OKc#JgJin6W=g!pfblKLF@(kIJ zEBA%UJpA-R4@4Bo?@&e{ritY6n!d{4LFkr(Uwp*xwROdxh?o>VBrzGk7tVYnesM@C zi%Ln&gkwM%f1ghIaJ$!UyfLOio%&mb@&Nc%N#&Qi<(d9({|MI9{MQMe=TrXGtof^a zZ~VUAzxp><^XGqewx6ZB{m)19_x^d0Fk5r`UoFkw`=|B~{=Y4JdG~*osw#i{rpe#< z_n)8vKC`O-`TWgGl^}7p&+UJ;eE!})wg2DQ;lFNE|6l6AI?vtlZ*JJr%wKb7`@gr_ z+pYXHx6?|>$A@Z=HEZ^qx%1{fx8V7Oixw|gx-9#Ju%a@TLz zxM}m2t=nFE{f)dgx9`}wYxi4w_U0EjU4`zVefx_`4jg>@(BXHE96fgY-O~5oKT-C< z$y2A#oc*x;qmMs1cmBes6`y_n#lRS+ec-4Px;3cq+dW^6*@xbaC7l2cMArln_OPMSPr>a>5vJTrX6 z$h+77bNY;DXZ~03|G#?v|1kf%cIzI|qi3()eV%wSvTwhqqWTXQ7(Hn4kfBcxQ}}=P z`u`UE|BtHQ-M9C*)K8;(cwoP-{WQQn{rJ3}$oFfyhx^OrU6JPd)9!ex#OG&&@Z6<6 z@|s=v{7Ey7zw)b%QncOcZyK?B*`XErjYr;BaI*c?{O0Rp3!dHZe8HND#RV%4|5Pyl z$@`tVhV*dGyqW3DY4@TtAi(LoapSymUa_xhbk_Z@Df6tZfO=26>UN**3UR*R${e-T zC0dGIANTvn^;N;ot|{RS3kQ7Erm*9-kiz+II0`ph7+84Sl33`oeP&_$szrqll)YGZ zVbZ3;y8ql&*!%eY!rZ4y3nPB|sPN^Nzb>?P`nm9$&Bq<%s^^~ZQ)9PS-oo8=Kx=oa zCm(Rz-e~9UJ?s&;uj5ho8pmVq16@Ph=Q@YD#fr}EUcEZG_w{J+zIfmPcj<;!?&r#y zxW^fN-K*2SFP#12$-+H*b`>6YV{u{kcX}2sZS$e4^y&`<+4GNE?cWa*^n3G!as8@< z`hh`W@q^vO9--sJPg*V%4L-SI>hXMWcI^A&f<0e}7kAteJFWARrfq619sJ}GDb!+= z`sa0(#LiDi&u@&8rZ*TTHSIfDdcMnSDR}h)X?yunY15?~Df{i0rOqRArIC9#OJj;( zmx?Ftkouf?OM2o=fi!)hTk_w$Upg@UfOP7>+tP!Z4ohwPk4R^0AC>Aos}R#HV;$SD zE&H%9$KY5TlVfuZ&c!)7H`lidoJ9$7}kSF8~ zc|=~3XXG7uNM4esyP$rZOWkgv~W|SReNLf;*lr3dUSySeeJ#~P( zK%Jm&P)DdM)EVjyb%?q|ouY10$Ea)6IqDvDkh(~nq;672sjJjk>MnJdx=fv>Zd1pp z>(qJbK5c-uK%1a#&_-x0v>DnCZHTsXTJkAq_VAVbV&SoZ8HXkmOzD(c;G1=_px@kj zPW|}DoGDp@oGA~@aZYNv&bjiv{m$>xK6jd$)^RPq(#G}O`+C>mjgc-}zXaFD4`#dc zhUKnN9X7aDPu}g?`u#!IkG)R09@T!~+V`xaII9wyg_ngZ;_r|_PW&n@$J%?F}tLLhCR~M z?0l)oRHxMc8<$l6S)o*CxLYQsS;jiHVO#cLUyi}CI3~yD9Gr`Da&E4HYvG!>Hm;Ft z<(j#6?ty#Zp13#ek$dHyxp(q_ydY1=8}f*}BG1S>@{qhFPsv;In7k&>$$QFxvY<>T z8_I~XqRc2e%8;_8OetH+n6jqKDSPSwb%8oT-Jp(8SEw`89qJHui8@8yqK;A5sB_dk z>L7KII!WE6j#5{tvtur~@;^EA`rdDE?%O-;{!@Er{aCqobCM=M`UAiG*Am<0$7grS zkN?@6|Aezw{*Dbp^IZ+c<+oipBY((}1^LH+T%O;#@vHd@UwSS7(L;OlJIp-YpT8{qa{k66zvZtguTyY5v`N9vbN3ZI_|t<0&-H(_U`dFfz&zMi5PGdw!O*G! z1x-c_FOWjV6(nR%D#**8Rgm}af`WdRmKJRKer3V6$JQ3K+p?)(|IoaGwSD&#?4MFp zF#gh^f{EGh6_{q6Eii2OwBUormkQSI`mwl|!3;oNxtDQBDO zXPpy{eeAq%$pvR-#OF@Sw_iG^&%Wf`Rp*K`WKxy$p%Xtjk2L$m+1Yx-Ij`sM&ZIUP z*Rt6@u1+7-a_xA)*EK(?j;muzU02oQdalRD*LOwsY~WhlprNbZ?uIURcq3Pr-HlwQ z>iW4ZiGHpX{rz12J^Wnb@AGqgcCe9a<`a!v!(VUcTJm`VSLdqwuFzBUTss!jb*=WV z<7$*p+jV}akE_4$E$4G{Za62c{MlJ(t#ZyA_l>h_$BWK@ap#@0^=F;Sr@iky)b$-_ zi`n~}8gY;F`7y6M+xX@>4>ext{B-v7&Krf(oPk2Dv&-b3&aYEDJNLA0?CgH|TtUL6 zH3e;k8VlBb(>}jx%M)QOJ3MQCEAl%43IZQU8`=4lnyk8-}XW_*9m+NOt(a7|xN=-9Qf z;FsD$m|omkDD4s~yj${!a4aoUSkl8NjIfHr?|r)oug&QrwD~wnnBRY>kb7x_kh5W| z;5R)*2%R)pSe-pn*z@HaA*jUyVR6)A;r+GQ!k0I4gq34o5-Pq}E6hpRApEo8R$=a* zH-zOAb_&Bydxi2wg~Hyd{lceTye-uI@~F`4>U+W){-*@g2p>*7FI?ICx$tt`N@4Hl zE5e1+ABC^GUKhq6{9Opz>LaG%TM~o1*Ap)WHWc%I@)M;~O~v$r=3=YdmSWu{fuirT zZN+cX9uQ}ae@J|3Yn2zG)#LnW$#XrW*6=$EDC(h~j zocQ^^1>*G13q@VdBJuo<#p0;pOT{(&mx)PjUl4a>EEjtnUm-RNS}9f~t`ZNt^`bcD z*VW>F;bk#z@+)G~oomF>FV>1B&DV)1rCjl|*!AM6SsTRX*K8Co?b;-sIj~tYm2MHg zE!!%7dSaV+?dWS_VA1R1W3Rm-w$9EIkEXsUwtsTF*y6z*;+)Gn#An{xDK1IhCEg0z zE#`i@TYP5GTjC?yJ!0j1d&Hc$y<+RDd&P0n^TkQO=ZpHu1>y^r3dH%*PO+}jDb^2g ziCGCQaqM1~xc7!jjI|VsW0DKS;x&b0{M&`%pwA1%#lIGc^&7awcl;G%nq{nG8@6R1 z_T?BHi(_(Z&cV4jC+FrGxE8L7YvUTZR<4$P4m>ydjUs zEAouIBM-?-@|3(KkI8HDoV=$DC=1GjvZ0J9E6R+rqYNoa%9OIDj45l%oU*45P#35Z z)D7wgb%i=Z-JuRqm#9L_)UIxFigbeOtKou+P6$EoYo zdFnoGfVM!Jpl#4bXe+cC+74}qwnUqvZOJwUTcgd<_Gp8&McO27lQv3QrOncIX~VQ- z+B9vOHcnfo&C~Yj1LzCr6X+Z0Bj_vWGw3_$L+DHBQ|MdhW9Vz>bLe~MgXoLsljxi1 zqv)&Xv*^3%!|2QC)9BmiV<(bN}m1iu^TAsN)dwB-)EasWavzcc!&uX68JiB>@ z^DO6?&a<6oJkNTb`8@j>127g~Ou*QHF#=-+#te)d7(+0YU`)Z-f-weT4aOXdJs5*9 z7GX@n*n}~P9IGH^VeG;fhOrD|8pbw^aTx0`=3(r^7>KbDV`(=oPVjK^4yF&|?;#(<0k z851%#WQ@pIkuf7B-wy&=xib#2bE|LEsT**?1C*4fZi zdwp|P+udzk{l9AG>TiC`wfj|r>*oN;RcCpG%htHB>&Y2|T$?_8#`STtF|OYqOm@Bd zbEYeJ{tVZ$*x9ZYC+4|M*M8o0@|Q)f=Qb>LHU2HzC0<|dnv|X6DsZiIeUP}yRe#kg z*KETo*H>XHU59g4xP-1RxXjw6uGB#bU86V6bM^4ga=jXu?t1UOIM-#(K-ZiihpSDO z&aU?M=B{?He(&tKY_D^cDarY!;ZVWDN&U=E^&4bazw3Zy&C;gUjf=Zl-@G)*`s4W* zt)2byt(zO1wO;-77i+`P#)4&Sun<4iD71XMkC1tFxDdH7Q+W39e4(hz3ZdNtxq|q@ zn?k?m-9mER<3fD>kAwqDD~02$uM2N4_Z7=qHx?@@T8ck@^?+FGu}Sv*^;JAQ%qO6R3w_up5DOFnx^{N>C#v8sHt z_+jN6qQ-Z(nAgcE1`OIS#y)pQ+`aF(*!EhPxb5)|#bNR1#m=k05d98c5-(r+UVO{< zn%JYoP4Qp@A8D(PuhhM&t~Bp-18KyYe$v}hn@XE4&80so1EeF*w~}tPZX><6I!G$@ zeNdY8%tKP)`iG_6WgVnvFLjjqeEX=>?aX7+#x0@Jj^SOT-8Z#Ttt`EC>uZD5(rA+0 zqr;?$lg!dP<1JEjcdJx<(<-@N6r{QVqBLQmC>_}$N;lqDh-sFwj&0bMeb|>{a4e3= zu{j6l;+&kDYv5YACa#TZUBCp6Z@{T+t zFUeE#mOLh}$#e3aGN3Fd6Uv4%qO2%0%8oLmEGbjUmNKTSDRau6IzU~ZPEa?fBh(e@ z40VS(L|vjzQMagL)HUiHb&onoU8GJ@H>so4Rq8BtmpV*crcP70spHgj>O6IyHb7gT zP0%)IBeWIT3~h%tL|dXw(Y9z~v^ClsZI3ocTcl0WHff`@RoX0Vmo`jWrcKkfY2&nY z+B|KaK7hV}K7qc0K7zi2K7+o4K7_u6K83!8K8C)AK8L=CK8U`EK8e1GK8n7IK8wDK zK8(JMK8?POK90VQK99bSK9IhUK9RnWK9atYK9jzaK9s(cK9#{`rLs zGA|Tny;;XS@%{(g7lSSCjvWTNOUEa>kIkLyp7v9=yZ2|WxDUU)$zA)I*WG8H&U3fi z_nOcUKMkt(^ZAi;mR}8>YY`REuoGr^6O@{PA}bWE9&0Kc5tW8HfV>{7Tq%3wx%S) z=C`_+Eqrlr8JTA}>)DR&*^m7>4#(rT9G~-WKF-Vexel&}>*D&jPOg{h=K8r0?uYy0 z{m;2`a$p`X-d?A0xC-RGYBmc-p@{@cef5~U^n|vq#DF@1fa-n=ECqDNVPVNdj zH|`y?`DME$d*5Emi3Neyh&{>H=1DuOH;!Jl{?z1Q;XwB&VdWb$g-3*q z*lOvV!s0*D3hU-|Ei9c?<@&zQFV4qS&a|d33KYawM+lAIoG1J?W1%3FO%+DHCkppl z-nK5T9qjyJ`;V^Cna>p38sronII^X%<3BbQp8aD%;lVb>!mYmzclp)ZYBjd}hp?<- zv(Pv6xRCbnX(8sF65*9bF9;i|S_q3f?Q@O^d7|*O(R&NOd$+3akJ7qseDAdTgShg- zZ^u1fSdzKG)plvHu}8UL@{)dXd;^Ub6V) zn1{rc^F|6+m(47Er%#ys>i3J?z6;)T4{uZ89{lze_lW`1+;isKC~VQ^ly&)1i%re0C|w!uZ$9)7rJaYmD( zcYitTp7wJKcaz`!#YQm~#69=xq?cEXkYZ0vlv*_yCC%LUxYT|2UNO^eN#Qze!=i12 zXBPeR)sCV)UEeFpezL6S%&Tt|<@8A`O4u6g4t!^zwEyhy(uoiI*&K1pY#nWTY*VhE zv}M-2WGh^JRVJoc#yYlPTlQgJj=`}wCdcL+oQrdEZmxlA;hMNMu90iynz?rFfqUVe zxHs;Rd*zNa(px=x*^?$ZWn3$zK^25p44LYtxO(1vJBv?m(Zus zw}kHfz#98mJ+VdIb>f-}Z;RdhL&S$Z)VY6{`iy(_i)V$t1@pvPhq4MM?Az)NY$RB} zc7lv8d%Jv!_WSGI#?x&j>+mh&k8gz)P3lsw=;GM^Qu3xqsh{uoBI{!-i&}P@ zCG|@`E0ts|DjIgK?Y{9pt&mzJC)*0Uzg)C@#>suI`majI;y2h&*1u*aGS70>vmM*B zANzA0j>mC1KIh?loR{-+9b6CB#r1KWTrbzn^>ZKG5BJ6Wai82T_s#v2599~^?&hYt zg7eq2oLA54T;De=b-i8Qr*PKxw+gLCn!Asb4R=>P@v8f|zNg#;D}0NFR<*+*nznq{nG8@6R1_T?BHi(_(Z&cV4jC+FrGxE8L7YvUTZR<4%lJr*xYyJe>QU_-T40>C(6Fh@X5g%eC*w_wM7h%|(WvTNe4wI9>SEMvXLa z#TaSaqG&0sYMz)owQDAgnMTCX&fPEF2f&2EYdO#XIb&Ku!f3&l2?=ZrC_)4aX%(I;JY{&NO$Nn6L<8fS$&v`f> z=jHrd2iL=OaeZ7T*UNQt{oDul!+mjo+$ZU~>LVS9Pa!RsuKcb(^I;%-uuJ|OXMZI5+1B!D%I{VOBYhf_ z9jE+GHS^m+6=U&P2#gbsbPO;d6M0OYg*?9hL$i7u`s4Ew;rHRY4S*w?Yy2+*%Yrrj zn}8+vFSC(Ud^AE>2k4HrR_E3Xx1zU$J)xqJPH0>j&*~XhZ-Lq<-CtDM$9J&b; zT0QPcFAmxBXwjBdF8+yuiolNcBBf=O-FE?d}-?JlnPXnf{YtJko?qmdzrrzea{HW8!vROvRxQV8 z6;;ahpBvDJV|Gl%tv&#b?{xaSi6iSgN2w;GjMT_4ru>8A1PUnzd1!v`Cel*{$u*Jdp6 z%wNLxURPC(Jbu4l>F>Bp|6{);DUDjXh*}vm1`!DwJ&v6(26?^z!d>8%~ zd*oMq7x@)?w zIqqVA#UA^0+{J#2y@dZ4$*P+D*`D_A(XXnS^Ru4zUtM2g{j8_`SJ&6rzdSzdzq-B# z|5#7^F9PDKs>y%39`;{dUqgO!J?y`_zJ~nedf2~b{)(FVBiFM!eQ|JD6#=)XKZ?7zBy4f~PDhy8o%%WB%6+#mK|U0=g~Sx@`-%wNL1*Hu*`Uv2-Y z|ESr&rvG7mu-E*K8vcv*6<+Ii)bM|Df3N-5^q;Kv=AWa6|CPu0;(ty5EsyUdKSvG! zFV}m?-%;cIkn6ql$5G?_k?Xzm&r#$2lIy+n*HPpAV||5}{yS=%pRD(`pPJ_{>%Hx- z=J_p;?`6M^LGpE&<+v(}o5|NKPx)p?n_M6K?_As}>A-zS2L=}#j||@Y#r;R@O8E^t z{(?=L*ge^{+Zc{`#N|j&t^N4I)}zHaM~_X=j%Xh)53jK(zW|T#UQ+U!EakhEZq4-M zYd}@C-%`&X)z7Ktjp`TG^F{Te>UpC2UG@A>{j_>ssD52NAJlU|MYUXQr}k6FQO8y1 zQRh|Hp{`3^r@C%+AL_om{4;n^%^yvT`s#Du)4%#$^^9K~M|kG1jypW-t3D?^>#sf+ zJ^QOZ2R-|*j+;DusE)Hde5j7gJbb8*<2-z*j{7`(sE!joe5j5qJ^S?Np{fQ|YJIi; zQTMI(SNE-sukKr&U){I5K6T&f`qh1_`&0L=qFS!DQ~RmosN<^hsPn4pP}ildQ(d>Z z4|U%j`Fr+%+Yi^MSL3W|KGqmtjiajNP-A^+oLVi%8v9e@;A%Zk_w8w?#yQn`r0&}@ zj~d5R>!G@D&pOpOrCN{GeXDv7$!Dq3C+;we9qam9pQ#DweU59gQdd>&w^Vc z>#*R?>s~x^FCMuUkKpP=?~DIm$1A;Sh9v)vd|(+qd$(Kp%-?{4 z5d+7?A8fFom#yD&&4^mBWgdM5AKBAH2r)xa(#FT6$EBqw#HOV_o|-u-DRFenfcT{N z*!1|ADVDGpR*Zi%G(ZAHI z93LIjoI}3St3BIr3|`)Ic=uyn0@?*`zdbL<>V&)zq|VJYe>IkOKaRBk?c%(~s*SP? zj#Fbiw&Og!yw~R4mv!6FZcmNz4k3TK#&~S^SL1p2<#d?h$On1KSkHF6 zyw~O3hjo|HF4Aip&K-k%g4bAV^H)6c?#HnLzrgntd5uM$ZA0E!V?4I|t37)6<#-Wj zS6O4c>&VyNdFT4r?ytu4?#uB~(awUtO!MNNdLtj@DPz4{fgj#H^X|iX>b$ppvupwS z=6H?G^=v|ZCrH&jw)rbQdiP`fb@bVGm$j6l?i`47dS7fW*WIOG4nA|Mw&xtFUU`-m zp`R9IM75na4_FuN=@U?+FWa9(znXJQsnIUzBJ>?)H}5is2L4K&n`^v?w*FpaYMtEQ ztDJ2^kmvYn8}GGqPG^m^u-zGafk9pT9k?p|k?`=BaCq;)cS+Uv(L4s~3Hn#p3vD(2 z>KrPn?b(x*iZ!*Xv!XS1Aq#1iWqYj~S@{b0AmJN>#@{=iX#Dd$>dI8)9Q>SjCC27l zA#dI01G4g3SWco%vR}E^I@GeGp0cZY<+Isw7>9jQfr~+8E`2ee+CKb{Uf^l3o&_pD zSSLm*V)?nb8syef!jQDA}jl1qW8EPYxMQsqx201diSM2t=ab@Pv1W< zAnVFKsOC$%Dr;8rr@iXqx@-KO1+m{>)w8^7#GUotM|-7fwmTAkyWLr@^dYbPaJ=5*?woIWjrtA~?yUEo=jv3A|8)?@QP<>MUxK9;CMOp08kz#@`LP+jN;pc1)lcmxZe9^+aas(+^_e%tp9r5zph`l@y`01@@csF&U)|p8*J0~2Z1<` zy1pV0FV%eW*YB(^txTA$b{7Nm&`!4=9ZsqTe@^6n;I(;+|D9Z(v zw8y#831`S7IG@_!)2YqyS!Q6#!%8|B^;(p%yaJR;^0eCt3`afda)DJ^)alR;lm#ls z_&Rfk zt?|{=(bUz{)6~~A&@|LE()ei_Yno`9f*H*;%{47F0h*SY`!vd(MqE;ore{iKT4H=! z&y=*uv1xJ9X|c)aV^Y#4L}q5(t!h9D{>*$z+TE%LCMI`JN!N@{nUI;(D8EGj~|Dq-}EoC(RUVe4Wn8ZH~!=jo4uuSb57dKj+nMt)N z)80)oGLz#qW0F#0Gyc5dn#JlEHOtlUlya}N-Y&SatM@vSN2jRkWKwO&v^p-+@;dj( z@`lK9H9r8^S4X-^nff!Y$VamubQ*LKbQM&0AM_9O2&fxq0BAU99B2w?E+_}I0ptW7 z2UUQsf$Hz~(FB4X0og%OpfR8<&??YQ&~ea3kfzv2^8lzPs2^w)XcA~PC>!)DXd9>q zbQ*LSbRE>B#77eh>I@14bpu6%;y}|ti$S@douGrDlc29a*Fe7H1+Mu%_-2IeDHA5d zCdWl4CdYTx9F|Km)6(LTGollqh;e=55dUdMQ3kdJ}q({V$${ag3J}oLOJ{?1Ad{GvqC~ZnwPw0DQ zTD)3UtCr{c9eSjt!F)6)YW0qfP3@T$kFV2sS59|LN=g~6IVqld$d~`29qda!Fm|;;=}3>BZREeKV6X z61z>!h>uPgk{B1?9giI}&FZMh=#=Vu%@b;G^yF&s9ZM`3m=UK;q0#(A&h|`9ijSU} z8n5{P988MOi0_`3n2|U-HfdlyzTYAxSu- zX(`DQAew<0X^F{W)4`EgAM*UKs!sV1N=}ej7gsHF3`o_`Y$osTTKz?>KFQc|Y!c*D zWA9y);|8YECt@F(-M#~p;^R{_C4b(Hro=ZoK5ar`GMuDmgBs0Y-{_=tMG-Vdn8v0C z$0lXQYmPF9B`LXgn3Gj0@HSr+5n;#QLC>*?8Vl2CthFQKV<**Iutw9N&Jf5ip1jlq z+#XMr6Gm(ZJ;%(6aouS?v18*k3EWZF?ok?znLVEB(U<8od7n`fxyD{QG9?!FI4UhR zZK|xBp|vBs_l-?eM1xTm)_y88BQ-NawyNsVL|MkN_^4xOH^irBQf7Jr*V8R?%$WEz zX!XnTOex9fDM|61InOH(HG}m$M+tgq?pWqIhR6JS;A^njD?9J5j57q^-_kuPCEa6B znq`{q@)^cXLo`qJ7|^drq(T2UkJ112S7kHY^EbzLOM|%C%+>HmpnhM4yLYuNj!2)F zrhI{p%!#U*3PY|lw8r(lCogwpRaO9g3=LMk3pxgf&`C2A$nT<#13m~$0=58V03QNQ z2Q~rD1vUmQ1~vue06Fp+U>)ElAipy@57->I6BrEK17wWv1U3Se09yi&0)v2Mz}CQW zU^8F^Fc4S?ybo9fYz4dyYzNdlq^((rByG zN-cgWCzpbpi}xxd-lG$JL0k*>$Gz7DH2~EEaZmi+aw5x!4MD8qKGiyo%f3YNjpK5G zEaQI3D-z4eZ&XIf&9gi>8_4=OAlA5=iB9Z=|C@LqQ`!37}Na z6i^l@8j(4N&;np7K7M+HE0uP zC#VE;8gvnK9pooqTu=~53mOVa0{Nf4z4m`4^G&C#{h!?IKawY}RDP**uD)=4{GBn7 zZ!DfYkAi$^%&WHl&q4pYUds5vcfI~|=KpUp%H6+rNLk?Bzc}W<$p-#kE#t20!J`(} zUDYF4uKpkY<9~-@_|)>PUsev^hyZNl?5VRK^2lY&r%Gb|W(8-htGLNj__J9uZbSP6 z8$aF{tW^K$=d3@JqHquH{hRH(dfMls{fP}1H?+}wxuJ5yKkh#Mv+Ly^{Sh$s|9JSv z!I}{tkNa5v=k}+{FI4=B?_+vaSy}jxiccl_cspE=_IeM%7{|MbcOBELuNeo`Y;!Mv zj{|?jfndC6^)6T6Q>bM;`yWRp2N(cd{kLeQ=c+{eK(xObaZJV%yNBP7EjZ^M=5Z6| zbMw|M-V^a&A{=xJ_Lv2ng}|TpXS}Bf26=9Hk*aa!)(WpKIa=p-`bPcgbod&->U7lG zO{>%GuQpfHS*upxr>298_Iv(*mv8a0wo8pHUw@_a{k8{B^$QQKdUbE=W82<5yf!hs z?3v#?eA#B{Q?0+96Fza(hby}`sk7wK9j}J}TAUkkWmfZLvu3-(i={JLPTcDA;FN=> z!c*R>4j;M^@$J^rKmGFUXHQI9d7?*r>5&(jY}uaM`iqS{8^^cu%bYbo zbJDTieTR0txOIh9G&y%)8Q6F0m(SP^KO-)Bb@{Mc&upn$A6yc>d9gY6gWneoTU6fR zndg7~WbErJum9Asc*D_W&Sxb@9((1*;DxmYj6BpK6Z_S?SNdM5a{cC*XlwZ4##H{e z?idy)e)`ms7n7UM`PuRIsgU^ApAT(S@WBs`vZfEu?bWtd-r=p^Il{N(CnoKvv(G&L zTZh3`)NR_AXL5?qe(gB;`|t0^&TTfi^o@&-E|LHEtnZ=yIV-<9=2(7cpqLr)UcmmB zcQ`JLEzGg@c=Lf>CvqI^AAaZaqC!y@yJ(stcF@xYp4~NYdUN*($A{l_SyFfZ@_8+P zi*U4eY`$dO-0_>4+d4aDqV#L_YcK$3x?KjyQ}hx`CDp>@67GdtzQ01ndVO(7Yq}FPCopJ{<}We z!>n7L+g~!|Sn#-`>)=tbaU){+Y&$$XBQ8Arj=FgD;rd_HC8dl_96chQkIOx^ zcn;zm*o=fb8+g~JWM+&=88ZU!w8qA(19;cVBaax32d-mN(x$2{?wn&pulVHn zG<6w&ZtOkYh(0NJlNBF3L0QtD8sE`&p#0SOE-mj|Lk1puj!48a)Ec}aU;h>VA|kq@ z$DL#K|oCy-_z3pTd~&7eS-sm@*+LcoLrF<9(5>qwaBS$KZIrox@uj zTgO4sJwq)WgVQtcb|y9{B{|;KacX>eM~A&}Ln$^rJ$}Ndq^ZFeAUWOEF*7Y$NFSXL zKOr_fbVB0jw3PIeF&UwF?JUHmPk4Niu46D>EG3S?OXtDfvtg*dB)dEq-DqW{HoBN=uxCR|aF_)2l1Jt9wjASH32TjGq*r z6r9ALwvMsseUc}ojE_(27@V2dbu{0D+d7VkO-hgN7~G|L9I4CQXOX(xu_mcY_2$rB z>Z0-unLCB}*Ex7|3u=6{jkT?{-LzTS`noLLD&0-p0=;DDW|(3)ZcGRZGPg4iHNS4@ zC_E>e6)J_JHU>lO(XU*4(GX{hHXkrQZJli0VVx?T7yC))?7uot356*kXvb(*XNU_p$(q<`7 z+9~akoKlfgA{~;BO3iJ7wjf)ut-WobZKZ9et-w}fE3qB2eQ9fI?`rRDkF-bGqwPcO zG4_%6IQw?{9=p?CWG}I6!to9P>#x#w(uL~Gy7A!5LS2sTjP6@qfWC`b!#u^j z-h9OTrTMbC%6!#)-F(xmvG`i*TLxH$T4F3CEpe9PmNS+r%P*Fj7LC={+QIsib(VF3 zb+I+unqysUU1QC)ZnA!7y=uK~y=m154W&-f6Vga&lk~97Xq$;0=GjZ__d84ufpUn# zI}pG&txNln?o-_tx=P)5kj8aLxt6}JzLCC}zNNmc{y}{Q{iE2IL2uJX=!fW+=~wDs z(XZEU)xU{-y7dS3$Mj|T5A_%HU+KSt3~L!08T<|R8G;R+4T9kb!!W~WLzZE_VYQ*k zP|MiO*w;A1__N7B?2#}jEF$bh>r7#x@Ul=U*u zOAIRvuNZO-TMXL`Zy8*M1BQ1DrH0dnj|>+KUmGsNK5iIp!Ri|un;Qd-!Nv~8$BYJ} z#b`J7G(KtU56c;Dj58(~CmJUkXBy`k7aErvUo@^YZZ^Jd+-Yzhd5KE;N^$+gKJ^)>`r{S1jwSuUmIoKePr3?Szg(7vYF-TKH0^Bfcv& zpw4CC_aFd|Ld&}9UeZ|&M+|L@ADSMpbg+offEe3bwrjSX4ox;bXNGnYwY>~|4Fh2j zFBvq(ZN?zeC#G{@m&1M!t7C3ye#C4w4~9P&W1enaX5MVxjXG}1r8vhCY=fQ$b7|$C&2e%(IJz<(44GUWuwl_>;o^M_R zZ|ydpFrP7}Tc%p(Sr%HBS#rSBD$CCnqt$Bd2A>@Ts~BZ1wjQ%ygx7jTSS73#3WP(# zDdD{Ez3>OPe4p4}>>}F5-mr#sVxG8H{79@T?Umfp5$O-e@y-~~6y9Jh_SQ(>Q~$W}q%l0KzonUVp}1UpQFM#P#Vg_;qAzSL zSb9VIe}ik$~u4AwFS_LE>3Vk|W_FfBB#F?9_a z6c%b8XdZ6PGM_Rxv*;~W`1uKzG)tBx+xjy6`5tSDRR<{_7f*`QY<~7Y`xcxz~C5N-GL6ijdI-W1uP5q_H-)&X*QSOQq$~D(PkERcV8? zMS5M@F73u?_$++u7TXcqEnAEo<5ehU|7yz#;g%323h+fwi%#)-v4MndjFKKf+l#g< zwnpIg6OO5l*^Y9D{1>&WWVO=l*B;ZJ(^hGB!|NWw$xvjdYiw#X8(%OUHBK>^Ed!wi zuUX10Us-;&w6(UgCR=A)-?5&sHW2~^gK$o0E)EkDMSO1-c3deo0rw9}C#3JBuC@WT zF}5Ude2VQ^+gjUeHka+N?Q>hD?RQ%{`&fIr{R{g84!h$C$8g6O$McSrj#nH99LF3V zVRcs=j6CpJG;A+ayGZ+@cB}R+ZJG8g{Gz{ZkSr4-XO%0oeQ)7MD z{;)$~ABFu9)*UCsadQPu^L7>+&hXKev6f`WcB*9tgDbod%!R+csnzIwb^f{lU7#*V z7px1>X>~@}-eO(0Zj)}CE>E{pw@2sH73oTJhjd4ErMfcRX!0?XgpO@CZXB{CA8Y&X8otFibbhH7qvd7}gjz8S)H!3`K@Rvfn;uxCpO()o|0` zYxFY)7=yr>5Tns386%95#%S<}-a5lL9lm<8F~_*ZxC#DZkFm&j2%3M|c+Pmyc-eRr z9@-E53o^Agg_!U~VWtRp=x9@nDbAE+$}mkg%{47H<-kfdnet3~Ohu+crc%>s(>c>c z(`D0D(@m3am|s{xSWsB|un>513DHDkSaeuSSX@|ASVq|Nu(>$JbHdhyZ3@c^+Y?p< zsg#DD4m%fi5gzwy*v&9sv!6M@9As{94lx_ek~zX0X^w{fjWZ{iA)jC$O#tMh(fVrr zwEo%vZKO6z8?8NxJ(OV=30P$+);R?$&B9t2V71v;?`o_#7i->zRqw>QomhDZ)_xSL zFT?uFv4aZip%S~O!alBJCz>$du=?1IKlT%d9R*`gov{z=Ox(tQS819`!5FvD!_wEaG@%! z2(fUfbXqzmU6d|MSEZYhug%XEfXKMLEd)`cWQ(vx+M*GK#liM8T6{JWJeeX)7qW!8 zLJ_=mDNe+5!bRb-a8f3o}95} z1nvW(aSsq@Pl8XMZl7ykjL371eUm*8cLYUu7Wa5hBhqIEI4I9-x1LpNPF7ak@@w+22Y5B{YH zzNJ+5D;4l5Rq!VoeSN*ZJ`f(I6TFEuj@645d95-xDV)L&>Ad;a6@lHlwqi0q#?nOiaSU~hS|6)$Te&; z>@+wHC5EGhGDEqc0{2W+hUKpy#c(9XEi)b+1*xMLo9BLdX#~@RTS;hs%Y~yNU zF5)Ogfh9O!%5djcVXQ=Kf8D4t)i?Q@0!_iDPKf?2rf^elQ~9V<2b(*YwYYBxH}^J2;eL6fIRSTjQ*h!hFlU=rn{&6ictz!-BVkhpB z5802(mT?(2p>g=jHerM{^mYt|HH>s5IIbOoT*y*DQ zl6`M|ZLn4g{g2T0hWAa-PJ!kxMy#3(z2BzYsXdBl^&Is5y4FuVLqnkHk-8{odXg?x zH$^^0b3G?$nS5gM{?-qg%~NtZv^NhY<7u3T{?JvaT0@g?{!u?S;p9^_^PH@kH$A6b zpnUFGpphBIDbT|`(7|%(oi8*l1iF?Wp9wq%s8^?Dow{kFf2U9H4ew1IqK{T|hi6kI z?m;?1PZDrvxd3``)O;Gc;1BsnLFUe?E5O&=jmKFkA zGs4;=*jog+5DA-$fz8E%AOHF1r4i?1G|s{doO|k-cU7nqtHf;kYIx~f_~~u3Mk-Hl zsFP*z*X8io6|&E+f_8$Z6+ZHPoK_zR@3sIQ?I + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAAA8AAAAMCAYAAAC9QufkAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAN + 1gAADdYBkG95nAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACdSURBVChTlZGx + DcIwEEUtalZIBmEYZiGLULMAtUsGYICQNi0VEpL5D9nWRbYs50tP1t29X9mFELxYxGsH+J7yKGaxJ/gj + ZZjEV/QED9+l8kE8RE/w8HMZTmIVrXDH+3dsGa6iFe7Zt0U4iqeohT337Nti4izewoaZ/cbdDIa7sGEu + vGIRGUT6e17mwisWhov4xLd2b5b5y1t8K/fgfhf9ch0fZsVEAAAAAElFTkSuQmCC + + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD/2wBD + AAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0M + DgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM + DAwMDAwMDAwMDAwMDAz/wAARCAARALkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQF + BgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAk + M2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG + h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx + 8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQA + AQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5 + OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmq + srO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDz + f/hd6/3ovzH+FH/C71/vRfmP8K+Sv+F4v/z0lo/4Xi//AD0lrp9mZ859a/8AC71/vRfmP8KP+F3r/ei/ + Mf4V8lf8Lxf/AJ6S0f8AC8X/AOektHsw5z61/wCF3r/ei/Mf4Uf8LvX+9F+Y/wAK+Sv+F4v/AM9JaP8A + heL/APPSWj2Yc59a/wDC71/vRfmP8KP+F3r/AHovzH+FfJX/AAvF/wDnpLR/wvF/+ektHsw5z61/4Xev + 96L8x/hR/wALvX+9F+Y/wr5K/wCF4v8A89JaP+F4v/z0lo9mHOfWv/C71/vRfmP8KP8Ahd6/3ovzH+Ff + JX/C8X/56S0f8Lxf/npLR7MOc+tf+F3r/ei/Mf4Uf8LvX+9F+Y/wr5K/4Xi//PSWj/heL/8APSWj2Yc5 + 9a/8LvX+9F+Y/wAKP+F3r/ei/Mf4V8lf8Lxf/npLR/wvF/8AnpLR7MOc+tf+F3r/AHovzH+FH/C71/vR + fmP8K+Sv+F4v/wA9JaP+F4v/AM9JaPZhzn1r/wALvX+9F+Y/wo/4Xev96L8x/hXyV/wvF/8AnpLR/wAL + xf8A56S0ezDnPrX/AIXev96L8x/hR/wu9f70X5j/AAr5K/4Xi/8Az0lo/wCF4v8A89JaPZhzn1r/AMLv + X+9F+Y/wo/4Xev8Aei/Mf4V8lf8AC8X/AOektH/C8X/56S0ezDnPJKKKK5jQKKKKACiiigAooooAKKKK + ACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/2Q== + + + + 0 + + + + iVBORw0KGgoAAAANSUhEUgAAAAwAAAAPCAYAAADQ4S5JAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAN + 1gAADdYBkG95nAAAAHRJREFUKFNj+P///z4GBgaZAwcOMBCDQRoeA/F9IG7CpgAdgzSAFIPAbyA+BsSW + 2BTCMLIGGHgNxPOAzuQhVgMMXALiWFI0gMBnIN6GHCiENMAASA04UIjVAAKgQFlFdRtI8gPRoUR0PBAd + 0ySnJRJS6wEGAICmKADl6upOAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.Properties/Resources.resx b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.Properties/Resources.resx new file mode 100644 index 0000000..5c113e8 --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.Properties/Resources.resx @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAAA8AAAAMCAYAAAC9QufkAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAN + 1gAADdYBkG95nAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACdSURBVChTlZGx + DcIwEEUtalZIBmEYZiGLULMAtUsGYICQNi0VEpL5D9nWRbYs50tP1t29X9mFELxYxGsH+J7yKGaxJ/gj + ZZjEV/QED9+l8kE8RE/w8HMZTmIVrXDH+3dsGa6iFe7Zt0U4iqeohT337Nti4izewoaZ/cbdDIa7sGEu + vGIRGUT6e17mwisWhov4xLd2b5b5y1t8K/fgfhf9ch0fZsVEAAAAAElFTkSuQmCC + + + + + /9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD/2wBD + AAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0M + DgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM + DAwMDAwMDAwMDAwMDAz/wAARCAARALkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQF + BgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAk + M2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG + h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx + 8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQA + AQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5 + OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmq + srO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDz + f/hd6/3ovzH+FH/C71/vRfmP8K+Sv+F4v/z0lo/4Xi//AD0lrp9mZ859a/8AC71/vRfmP8KP+F3r/ei/ + Mf4V8lf8Lxf/AJ6S0f8AC8X/AOektHsw5z61/wCF3r/ei/Mf4Uf8LvX+9F+Y/wAK+Sv+F4v/AM9JaP8A + heL/APPSWj2Yc59a/wDC71/vRfmP8KP+F3r/AHovzH+FfJX/AAvF/wDnpLR/wvF/+ektHsw5z61/4Xev + 96L8x/hR/wALvX+9F+Y/wr5K/wCF4v8A89JaP+F4v/z0lo9mHOfWv/C71/vRfmP8KP8Ahd6/3ovzH+Ff + JX/C8X/56S0f8Lxf/npLR7MOc+tf+F3r/ei/Mf4Uf8LvX+9F+Y/wr5K/4Xi//PSWj/heL/8APSWj2Yc5 + 9a/8LvX+9F+Y/wAKP+F3r/ei/Mf4V8lf8Lxf/npLR/wvF/8AnpLR7MOc+tf+F3r/AHovzH+FH/C71/vR + fmP8K+Sv+F4v/wA9JaP+F4v/AM9JaPZhzn1r/wALvX+9F+Y/wo/4Xev96L8x/hXyV/wvF/8AnpLR/wAL + xf8A56S0ezDnPrX/AIXev96L8x/hR/wu9f70X5j/AAr5K/4Xi/8Az0lo/wCF4v8A89JaPZhzn1r/AMLv + X+9F+Y/wo/4Xev8Aei/Mf4V8lf8AC8X/AOektH/C8X/56S0ezDnPJKKKK5jQKKKKACiiigAooooAKKKK + ACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/2Q== + + + + 0 + + + + iVBORw0KGgoAAAANSUhEUgAAAAwAAAAPCAYAAADQ4S5JAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAN + 1gAADdYBkG95nAAAAHRJREFUKFNj+P///z4GBgaZAwcOMBCDQRoeA/F9IG7CpgAdgzSAFIPAbyA+BsSW + 2BTCMLIGGHgNxPOAzuQhVgMMXALiWFI0gMBnIN6GHCiENMAASA04UIjVAAKgQFlFdRtI8gPRoUR0PBAd + 0ySnJRJS6wEGAICmKADl6upOAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.csproj b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.csproj new file mode 100644 index 0000000..b12e1db --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.csproj @@ -0,0 +1,65 @@ + + + + {A5EFB9F9-6F99-4EBD-B5C9-3F68EFEFC823} + Debug + AnyCPU + Library + SDRSharp.CollapsiblePanel + .NETFramework + v4.6 + 4 + True + + + AnyCPU + + + bin\Debug\ + true + full + false + + + bin\Release\ + true + pdbonly + true + + + + C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Design\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Design.dll + + + + + + + UserControl + + + + Component + + + + + + + Resources.cs + + + CollapsiblePanel.cs + + + + \ No newline at end of file diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.sln b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.sln new file mode 100644 index 0000000..ede6d5a --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2015 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDRSharp.CollapsiblePanel", "SDRSharp.CollapsiblePanel.csproj", "{A5EFB9F9-6F99-4EBD-B5C9-3F68EFEFC823}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A5EFB9F9-6F99-4EBD-B5C9-3F68EFEFC823}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A5EFB9F9-6F99-4EBD-B5C9-3F68EFEFC823}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A5EFB9F9-6F99-4EBD-B5C9-3F68EFEFC823}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A5EFB9F9-6F99-4EBD-B5C9-3F68EFEFC823}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {AF25AAAB-B38C-48F7-A7D7-0D815C0D1E47} + EndGlobalSection +EndGlobal diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.cs b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.cs new file mode 100644 index 0000000..45ae156 --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.cs @@ -0,0 +1,271 @@ +using SDRSharp.CollapsiblePanel.Properties; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace SDRSharp.CollapsiblePanel +{ + [DesignTimeVisible(true)] + [Category("Containers")] + [Description("Visual Studio like Collapsible Panel")] + [Designer(typeof(CollapsiblePanelDesigner))] + public class CollapsiblePanel : UserControl + { + private bool _autoHeight; + + private PanelStateOptions _panelState = PanelStateOptions.Expanded; + + private CollapsiblePanel _nextPanel; + + private IContainer components; + + private Panel titlePanel; + + private PictureBox togglingImage; + + private ImageList collapsiblePanelImageList; + + private Label lblPanelTitle; + + private ContentPanel contentPanel; + + private TableLayoutPanel titleTableLayoutPanel; + + [Description("Gets or sets panel title")] + [DisplayName("Panel Title")] + [Category("Collapsible Panel")] + public string PanelTitle + { + get + { + return this.lblPanelTitle.Text; + } + set + { + this.lblPanelTitle.Text = value; + } + } + + [DefaultValue(typeof(PanelStateOptions), "Expanded")] + [Description("Gets or sets current panel state")] + [DisplayName("Panel State")] + [Category("Collapsible Panel")] + public PanelStateOptions PanelState + { + get + { + return this._panelState; + } + set + { + this._panelState = value; + this.UpdateState(); + } + } + + [Category("Collapsible Panel")] + [Description("Gets or sets the panel to be located beneath this panel")] + public CollapsiblePanel NextPanel + { + get + { + return this._nextPanel; + } + set + { + this._nextPanel = value; + this.MoveNextPanel(); + } + } + + [Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public ContentPanel Content + { + get + { + return this.contentPanel; + } + } + + public bool AutoHeight + { + get + { + return this._autoHeight; + } + set + { + if (this._autoHeight != value) + { + this._autoHeight = value; + this.UpdateState(); + } + } + } + + public CollapsiblePanel() + { + this.InitializeComponent(); + base.Load += this.CollapsiblePanel_Load; + base.SizeChanged += this.CollapsiblePanel_SizeChanged; + base.LocationChanged += this.CollapsiblePanel_LocationChanged; + } + + private void CollapsiblePanel_Load(object sender, EventArgs e) + { + if (this._panelState == PanelStateOptions.Collapsed) + { + this.togglingImage.Image = Resources.CollapsedIcon; + } + else + { + this.togglingImage.Image = Resources.ExpandedIcon; + } + } + + private void CollapsiblePanel_SizeChanged(object sender, EventArgs e) + { + this.MoveNextPanel(); + } + + private void CollapsiblePanel_LocationChanged(object sender, EventArgs e) + { + this.MoveNextPanel(); + } + + private void ToggleState(object sender, EventArgs e) + { + this._panelState = ((this._panelState == PanelStateOptions.Collapsed) ? PanelStateOptions.Expanded : PanelStateOptions.Collapsed); + this.UpdateState(); + } + + internal void UpdateState() + { + if (this._panelState == PanelStateOptions.Collapsed) + { + this.contentPanel.Visible = false; + base.Height = this.titlePanel.Height; + this.togglingImage.Image = Resources.CollapsedIcon; + } + else + { + int num = (this.contentPanel.Controls.Count != 1 || !this._autoHeight) ? this.contentPanel.Height : this.contentPanel.Controls[0].Height; + base.Height = this.titlePanel.Height + num; + this.contentPanel.Visible = true; + this.togglingImage.Image = Resources.ExpandedIcon; + Panel panel = base.Parent as Panel; + while (panel != null && panel.AutoSize) + { + panel = (panel.Parent as Panel); + } + if (panel != null) + { + panel.ScrollControlIntoView(this); + } + } + } + + private void MoveNextPanel() + { + if (this._nextPanel != null) + { + CollapsiblePanel nextPanel = this._nextPanel; + Point location = base.Location; + int x = location.X; + location = base.Location; + nextPanel.Location = new Point(x, location.Y + base.Size.Height); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + { + this.components.Dispose(); + } + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = new Container(); + ComponentResourceManager componentResourceManager = new ComponentResourceManager(typeof(CollapsiblePanel)); + this.collapsiblePanelImageList = new ImageList(this.components); + this.titlePanel = new Panel(); + this.titleTableLayoutPanel = new TableLayoutPanel(); + this.togglingImage = new PictureBox(); + this.lblPanelTitle = new Label(); + this.contentPanel = new ContentPanel(); + this.titlePanel.SuspendLayout(); + this.titleTableLayoutPanel.SuspendLayout(); + ((ISupportInitialize)this.togglingImage).BeginInit(); + base.SuspendLayout(); + this.collapsiblePanelImageList.ImageStream = (ImageListStreamer)componentResourceManager.GetObject("collapsiblePanelImageList.ImageStream"); + this.collapsiblePanelImageList.TransparentColor = Color.Transparent; + this.collapsiblePanelImageList.Images.SetKeyName(0, "ExpandIcon.jpg"); + this.titlePanel.BackColor = Color.DarkGray; + this.titlePanel.BackgroundImage = Resources.titleBackground; + this.titlePanel.BackgroundImageLayout = ImageLayout.Stretch; + this.titlePanel.Controls.Add(this.titleTableLayoutPanel); + this.titlePanel.Dock = DockStyle.Top; + this.titlePanel.Location = new Point(0, 0); + this.titlePanel.Name = "titlePanel"; + this.titlePanel.Size = new Size(150, 24); + this.titlePanel.TabIndex = 0; + this.titleTableLayoutPanel.BackColor = Color.Transparent; + this.titleTableLayoutPanel.ColumnCount = 2; + this.titleTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 24f)); + this.titleTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.titleTableLayoutPanel.Controls.Add(this.togglingImage, 0, 0); + this.titleTableLayoutPanel.Controls.Add(this.lblPanelTitle, 1, 0); + this.titleTableLayoutPanel.Dock = DockStyle.Fill; + this.titleTableLayoutPanel.Location = new Point(0, 0); + this.titleTableLayoutPanel.Name = "titleTableLayoutPanel"; + this.titleTableLayoutPanel.RowCount = 1; + this.titleTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.titleTableLayoutPanel.Size = new Size(150, 24); + this.titleTableLayoutPanel.TabIndex = 2; + this.titleTableLayoutPanel.Click += this.ToggleState; + this.togglingImage.Anchor = AnchorStyles.None; + this.togglingImage.BackColor = Color.Transparent; + this.togglingImage.Image = Resources.ExpandedIcon; + this.togglingImage.Location = new Point(7, 7); + this.togglingImage.Name = "togglingImage"; + this.togglingImage.Size = new Size(10, 10); + this.togglingImage.SizeMode = PictureBoxSizeMode.StretchImage; + this.togglingImage.TabIndex = 0; + this.togglingImage.TabStop = false; + this.togglingImage.Click += this.ToggleState; + this.lblPanelTitle.Anchor = AnchorStyles.Left; + this.lblPanelTitle.AutoEllipsis = true; + this.lblPanelTitle.AutoSize = true; + this.lblPanelTitle.BackColor = Color.Transparent; + this.lblPanelTitle.Font = new Font("Segoe UI Semibold", 9f, FontStyle.Regular, GraphicsUnit.Point, 0); + this.lblPanelTitle.ForeColor = Color.WhiteSmoke; + this.lblPanelTitle.Location = new Point(27, 4); + this.lblPanelTitle.Name = "lblPanelTitle"; + this.lblPanelTitle.Size = new Size(59, 15); + this.lblPanelTitle.TabIndex = 1; + this.lblPanelTitle.Text = "Panel title"; + this.lblPanelTitle.Click += this.ToggleState; + this.contentPanel.Location = new Point(0, 24); + this.contentPanel.Margin = new Padding(2); + this.contentPanel.Name = "contentPanel"; + this.contentPanel.Size = new Size(150, 126); + this.contentPanel.TabIndex = 1; + base.AutoScaleDimensions = new SizeF(96f, 96f); + base.AutoScaleMode = AutoScaleMode.Dpi; + base.Controls.Add(this.contentPanel); + base.Controls.Add(this.titlePanel); + base.Name = "CollapsiblePanel"; + this.titlePanel.ResumeLayout(false); + this.titleTableLayoutPanel.ResumeLayout(false); + this.titleTableLayoutPanel.PerformLayout(); + ((ISupportInitialize)this.togglingImage).EndInit(); + base.ResumeLayout(false); + base.PerformLayout(); + } + } +} diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.resource b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.resource new file mode 100644 index 0000000..fed0171 --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.resource @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABe + CAAAAk1TRnQBSQFMAwEBAAHEAQABxAEAARABAAEQAQAE/wEJARAI/wFCAU0BNgEEBgABNgEEAgABKAMA + AUADAAEQAwABAQEAAQgGAAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA + AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA + AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm + AwABmQMAAcwCAAEzAwACMwIAATMBZgIAATMBmQIAATMBzAIAATMB/wIAAWYDAAFmATMCAAJmAgABZgGZ + AgABZgHMAgABZgH/AgABmQMAAZkBMwIAAZkBZgIAApkCAAGZAcwCAAGZAf8CAAHMAwABzAEzAgABzAFm + AgABzAGZAgACzAIAAcwB/wIAAf8BZgIAAf8BmQIAAf8BzAEAATMB/wIAAf8BAAEzAQABMwEAAWYBAAEz + AQABmQEAATMBAAHMAQABMwEAAf8BAAH/ATMCAAMzAQACMwFmAQACMwGZAQACMwHMAQACMwH/AQABMwFm + AgABMwFmATMBAAEzAmYBAAEzAWYBmQEAATMBZgHMAQABMwFmAf8BAAEzAZkCAAEzAZkBMwEAATMBmQFm + AQABMwKZAQABMwGZAcwBAAEzAZkB/wEAATMBzAIAATMBzAEzAQABMwHMAWYBAAEzAcwBmQEAATMCzAEA + ATMBzAH/AQABMwH/ATMBAAEzAf8BZgEAATMB/wGZAQABMwH/AcwBAAEzAv8BAAFmAwABZgEAATMBAAFm + AQABZgEAAWYBAAGZAQABZgEAAcwBAAFmAQAB/wEAAWYBMwIAAWYCMwEAAWYBMwFmAQABZgEzAZkBAAFm + ATMBzAEAAWYBMwH/AQACZgIAAmYBMwEAA2YBAAJmAZkBAAJmAcwBAAFmAZkCAAFmAZkBMwEAAWYBmQFm + AQABZgKZAQABZgGZAcwBAAFmAZkB/wEAAWYBzAIAAWYBzAEzAQABZgHMAZkBAAFmAswBAAFmAcwB/wEA + AWYB/wIAAWYB/wEzAQABZgH/AZkBAAFmAf8BzAEAAcwBAAH/AQAB/wEAAcwBAAKZAgABmQEzAZkBAAGZ + AQABmQEAAZkBAAHMAQABmQMAAZkCMwEAAZkBAAFmAQABmQEzAcwBAAGZAQAB/wEAAZkBZgIAAZkBZgEz + AQABmQEzAWYBAAGZAWYBmQEAAZkBZgHMAQABmQEzAf8BAAKZATMBAAKZAWYBAAOZAQACmQHMAQACmQH/ + AQABmQHMAgABmQHMATMBAAFmAcwBZgEAAZkBzAGZAQABmQLMAQABmQHMAf8BAAGZAf8CAAGZAf8BMwEA + AZkBzAFmAQABmQH/AZkBAAGZAf8BzAEAAZkC/wEAAcwDAAGZAQABMwEAAcwBAAFmAQABzAEAAZkBAAHM + AQABzAEAAZkBMwIAAcwCMwEAAcwBMwFmAQABzAEzAZkBAAHMATMBzAEAAcwBMwH/AQABzAFmAgABzAFm + ATMBAAGZAmYBAAHMAWYBmQEAAcwBZgHMAQABmQFmAf8BAAHMAZkCAAHMAZkBMwEAAcwBmQFmAQABzAKZ + AQABzAGZAcwBAAHMAZkB/wEAAswCAALMATMBAALMAWYBAALMAZkBAAPMAQACzAH/AQABzAH/AgABzAH/ + ATMBAAGZAf8BZgEAAcwB/wGZAQABzAH/AcwBAAHMAv8BAAHMAQABMwEAAf8BAAFmAQAB/wEAAZkBAAHM + ATMCAAH/AjMBAAH/ATMBZgEAAf8BMwGZAQAB/wEzAcwBAAH/ATMB/wEAAf8BZgIAAf8BZgEzAQABzAJm + AQAB/wFmAZkBAAH/AWYBzAEAAcwBZgH/AQAB/wGZAgAB/wGZATMBAAH/AZkBZgEAAf8CmQEAAf8BmQHM + AQAB/wGZAf8BAAH/AcwCAAH/AcwBMwEAAf8BzAFmAQAB/wHMAZkBAAH/AswBAAH/AcwB/wEAAv8BMwEA + AcwB/wFmAQAC/wGZAQAC/wHMAQACZgH/AQABZgH/AWYBAAFmAv8BAAH/AmYBAAH/AWYB/wEAAv8BZgEA + ASEBAAGlAQADXwEAA3cBAAOGAQADlgEAA8sBAAOyAQAD1wEAA90BAAPjAQAD6gEAA/EBAAP4AQAB8AH7 + Af8BAAGkAqABAAOAAwAB/wIAAf8DAAL/AQAB/wMAAf8BAAH/AQAC/wIAA/8BAAHyAfALvAHwAfEB9DAA + AQcBkgvsAe0B7wHxMAAB7QH3B+8B9wPvAfcB7QHwMAAB7AH3BAcB7wGSAe8EBwHvAewBvDAAAewB9wIH + Au8B7AFDAesB7wEHAbwBBwHvAewBvDAAAewB7wHxAvABvAHsAQ4BbQHwAwcB7wHsAbwwAAHsAQcD/wH0 + AZIBDgHsAfQBvAHvAQcB7wHsAbwwAAHsAbwB8wHvAuwBEgEOARQB7AFtAesB9wHvAewBvDAAAewBBwHy + AeoDDgEAAg4BDwEVAe0B7wHsAbwwAAHsAQcB8wEHAvcBbQEOARMB7QH3Ae8B8AEHAewBvDAAAewBBwT/ + AfcBDgHsAfQD/wHwAe0BvDAAAewBvAL/AfQB/wGSAQ4B7AT/AfAB7AG8MAAB7AG8Av8B9AH/AQcB6gHv + BP8B8AHsAbwwAAHsAQcE/wH0AfIB8wH/AfQB8wH/AfEB7QG8MAAB7QHvArwKBwH3AfAwAAEHAZIL7AHt + Ae8B8jAAAUIBTQE+BwABPgMAASgDAAFAAwABEAMAAQEBAAEBBQABgBcAA/+XAAs= + + + \ No newline at end of file diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.resx b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.resx new file mode 100644 index 0000000..fed0171 --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanel.resx @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABe + CAAAAk1TRnQBSQFMAwEBAAHEAQABxAEAARABAAEQAQAE/wEJARAI/wFCAU0BNgEEBgABNgEEAgABKAMA + AUADAAEQAwABAQEAAQgGAAEEGAABgAIAAYADAAKAAQABgAMAAYABAAGAAQACgAIAA8ABAAHAAdwBwAEA + AfABygGmAQABMwUAATMBAAEzAQABMwEAAjMCAAMWAQADHAEAAyIBAAMpAQADVQEAA00BAANCAQADOQEA + AYABfAH/AQACUAH/AQABkwEAAdYBAAH/AewBzAEAAcYB1gHvAQAB1gLnAQABkAGpAa0CAAH/ATMDAAFm + AwABmQMAAcwCAAEzAwACMwIAATMBZgIAATMBmQIAATMBzAIAATMB/wIAAWYDAAFmATMCAAJmAgABZgGZ + AgABZgHMAgABZgH/AgABmQMAAZkBMwIAAZkBZgIAApkCAAGZAcwCAAGZAf8CAAHMAwABzAEzAgABzAFm + AgABzAGZAgACzAIAAcwB/wIAAf8BZgIAAf8BmQIAAf8BzAEAATMB/wIAAf8BAAEzAQABMwEAAWYBAAEz + AQABmQEAATMBAAHMAQABMwEAAf8BAAH/ATMCAAMzAQACMwFmAQACMwGZAQACMwHMAQACMwH/AQABMwFm + AgABMwFmATMBAAEzAmYBAAEzAWYBmQEAATMBZgHMAQABMwFmAf8BAAEzAZkCAAEzAZkBMwEAATMBmQFm + AQABMwKZAQABMwGZAcwBAAEzAZkB/wEAATMBzAIAATMBzAEzAQABMwHMAWYBAAEzAcwBmQEAATMCzAEA + ATMBzAH/AQABMwH/ATMBAAEzAf8BZgEAATMB/wGZAQABMwH/AcwBAAEzAv8BAAFmAwABZgEAATMBAAFm + AQABZgEAAWYBAAGZAQABZgEAAcwBAAFmAQAB/wEAAWYBMwIAAWYCMwEAAWYBMwFmAQABZgEzAZkBAAFm + ATMBzAEAAWYBMwH/AQACZgIAAmYBMwEAA2YBAAJmAZkBAAJmAcwBAAFmAZkCAAFmAZkBMwEAAWYBmQFm + AQABZgKZAQABZgGZAcwBAAFmAZkB/wEAAWYBzAIAAWYBzAEzAQABZgHMAZkBAAFmAswBAAFmAcwB/wEA + AWYB/wIAAWYB/wEzAQABZgH/AZkBAAFmAf8BzAEAAcwBAAH/AQAB/wEAAcwBAAKZAgABmQEzAZkBAAGZ + AQABmQEAAZkBAAHMAQABmQMAAZkCMwEAAZkBAAFmAQABmQEzAcwBAAGZAQAB/wEAAZkBZgIAAZkBZgEz + AQABmQEzAWYBAAGZAWYBmQEAAZkBZgHMAQABmQEzAf8BAAKZATMBAAKZAWYBAAOZAQACmQHMAQACmQH/ + AQABmQHMAgABmQHMATMBAAFmAcwBZgEAAZkBzAGZAQABmQLMAQABmQHMAf8BAAGZAf8CAAGZAf8BMwEA + AZkBzAFmAQABmQH/AZkBAAGZAf8BzAEAAZkC/wEAAcwDAAGZAQABMwEAAcwBAAFmAQABzAEAAZkBAAHM + AQABzAEAAZkBMwIAAcwCMwEAAcwBMwFmAQABzAEzAZkBAAHMATMBzAEAAcwBMwH/AQABzAFmAgABzAFm + ATMBAAGZAmYBAAHMAWYBmQEAAcwBZgHMAQABmQFmAf8BAAHMAZkCAAHMAZkBMwEAAcwBmQFmAQABzAKZ + AQABzAGZAcwBAAHMAZkB/wEAAswCAALMATMBAALMAWYBAALMAZkBAAPMAQACzAH/AQABzAH/AgABzAH/ + ATMBAAGZAf8BZgEAAcwB/wGZAQABzAH/AcwBAAHMAv8BAAHMAQABMwEAAf8BAAFmAQAB/wEAAZkBAAHM + ATMCAAH/AjMBAAH/ATMBZgEAAf8BMwGZAQAB/wEzAcwBAAH/ATMB/wEAAf8BZgIAAf8BZgEzAQABzAJm + AQAB/wFmAZkBAAH/AWYBzAEAAcwBZgH/AQAB/wGZAgAB/wGZATMBAAH/AZkBZgEAAf8CmQEAAf8BmQHM + AQAB/wGZAf8BAAH/AcwCAAH/AcwBMwEAAf8BzAFmAQAB/wHMAZkBAAH/AswBAAH/AcwB/wEAAv8BMwEA + AcwB/wFmAQAC/wGZAQAC/wHMAQACZgH/AQABZgH/AWYBAAFmAv8BAAH/AmYBAAH/AWYB/wEAAv8BZgEA + ASEBAAGlAQADXwEAA3cBAAOGAQADlgEAA8sBAAOyAQAD1wEAA90BAAPjAQAD6gEAA/EBAAP4AQAB8AH7 + Af8BAAGkAqABAAOAAwAB/wIAAf8DAAL/AQAB/wMAAf8BAAH/AQAC/wIAA/8BAAHyAfALvAHwAfEB9DAA + AQcBkgvsAe0B7wHxMAAB7QH3B+8B9wPvAfcB7QHwMAAB7AH3BAcB7wGSAe8EBwHvAewBvDAAAewB9wIH + Au8B7AFDAesB7wEHAbwBBwHvAewBvDAAAewB7wHxAvABvAHsAQ4BbQHwAwcB7wHsAbwwAAHsAQcD/wH0 + AZIBDgHsAfQBvAHvAQcB7wHsAbwwAAHsAbwB8wHvAuwBEgEOARQB7AFtAesB9wHvAewBvDAAAewBBwHy + AeoDDgEAAg4BDwEVAe0B7wHsAbwwAAHsAQcB8wEHAvcBbQEOARMB7QH3Ae8B8AEHAewBvDAAAewBBwT/ + AfcBDgHsAfQD/wHwAe0BvDAAAewBvAL/AfQB/wGSAQ4B7AT/AfAB7AG8MAAB7AG8Av8B9AH/AQcB6gHv + BP8B8AHsAbwwAAHsAQcE/wH0AfIB8wH/AfQB8wH/AfEB7QG8MAAB7QHvArwKBwH3AfAwAAEHAZIL7AHt + Ae8B8jAAAUIBTQE+BwABPgMAASgDAAFAAwABEAMAAQEBAAEBBQABgBcAA/+XAAs= + + + \ No newline at end of file diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanelDesigner.cs b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanelDesigner.cs new file mode 100644 index 0000000..33b6dd6 --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/CollapsiblePanelDesigner.cs @@ -0,0 +1,17 @@ +using System.ComponentModel; +using System.Windows.Forms.Design; + +namespace SDRSharp.CollapsiblePanel +{ + public class CollapsiblePanelDesigner : ParentControlDesigner + { + public override void Initialize(IComponent component) + { + base.Initialize(component); + if (this.Control is CollapsiblePanel) + { + base.EnableDesignMode(((CollapsiblePanel)this.Control).Content, "Content"); + } + } + } +} diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/ContentPanel.cs b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/ContentPanel.cs new file mode 100644 index 0000000..18894e2 --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/ContentPanel.cs @@ -0,0 +1,32 @@ +using System; +using System.ComponentModel; +using System.Windows.Forms; + +namespace SDRSharp.CollapsiblePanel +{ + [Designer(typeof(ContentPanelDesigner))] + public class ContentPanel : Panel + { + public ContentPanel() + { + base.Dock = DockStyle.Fill; + } + + protected override void OnControlAdded(ControlEventArgs e) + { + e.Control.Resize += this.sourceControlPanel_Resize; + base.OnControlAdded(e); + } + + protected override void OnControlRemoved(ControlEventArgs e) + { + e.Control.Resize -= this.sourceControlPanel_Resize; + base.OnControlRemoved(e); + } + + private void sourceControlPanel_Resize(object sender, EventArgs e) + { + ((CollapsiblePanel)base.Parent).UpdateState(); + } + } +} diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/ContentPanelDesigner.cs b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/ContentPanelDesigner.cs new file mode 100644 index 0000000..f5e2f35 --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/ContentPanelDesigner.cs @@ -0,0 +1,16 @@ +using System.Collections; +using System.Windows.Forms.Design; + +namespace SDRSharp.CollapsiblePanel +{ + public class ContentPanelDesigner : ScrollableControlDesigner + { + protected override void PreFilterProperties(IDictionary properties) + { + properties.Remove("Dock"); + properties.Remove("AutoSize"); + properties.Remove("AutoSizeMode"); + base.PreFilterProperties(properties); + } + } +} diff --git a/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/PanelStateOptions.cs b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/PanelStateOptions.cs new file mode 100644 index 0000000..a1444dd --- /dev/null +++ b/SDRSharp.CollapsiblePanel/SDRSharp.CollapsiblePanel/PanelStateOptions.cs @@ -0,0 +1,8 @@ +namespace SDRSharp.CollapsiblePanel +{ + public enum PanelStateOptions + { + Collapsed, + Expanded + } +} diff --git a/SDRSharp.Common/Properties/AssemblyInfo.cs b/SDRSharp.Common/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3d0289c --- /dev/null +++ b/SDRSharp.Common/Properties/AssemblyInfo.cs @@ -0,0 +1,17 @@ +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Security; +using System.Security.Permissions; + +[assembly: CompilationRelaxations(8)] +[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] +[assembly: SecurityRules(SecurityRuleSet.Level1)] +[assembly: AssemblyTitle("SDR Sharp")] +[assembly: AssemblyDescription("Software Defined Radio")] +[assembly: AssemblyProduct("SDR#")] +[assembly: AssemblyCopyright("Copyright © Youssef TOUIL 2012")] +[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] +[assembly: AssemblyVersion("0.0.0.0")] diff --git a/SDRSharp.Common/SDRSharp.Common.csproj b/SDRSharp.Common/SDRSharp.Common.csproj new file mode 100644 index 0000000..9f0919c --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common.csproj @@ -0,0 +1,59 @@ + + + + {E8BB1EAC-ED6B-4D5E-AA88-6A6CD961F37E} + Debug + AnyCPU + Library + SDRSharp.Common + .NETFramework + v4.6 + 4 + True + + + AnyCPU + + + bin\Debug\ + true + full + false + + + bin\Release\ + true + pdbonly + true + + + + ..\SDRSharp.PanView\bin\Debug\SDRSharp.PanView.dll + + + ..\SDRSharp.Radio\bin\Debug\SDRSharp.Radio.dll + + + C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SDRSharp.Common/SDRSharp.Common.sln b/SDRSharp.Common/SDRSharp.Common.sln new file mode 100644 index 0000000..404925d --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2015 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDRSharp.Common", "SDRSharp.Common.csproj", "{E8BB1EAC-ED6B-4D5E-AA88-6A6CD961F37E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E8BB1EAC-ED6B-4D5E-AA88-6A6CD961F37E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E8BB1EAC-ED6B-4D5E-AA88-6A6CD961F37E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E8BB1EAC-ED6B-4D5E-AA88-6A6CD961F37E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E8BB1EAC-ED6B-4D5E-AA88-6A6CD961F37E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0AE04AD9-F937-4F9E-9BEC-85735408578C} + EndGlobalSection +EndGlobal diff --git a/SDRSharp.Common/SDRSharp.Common/ByteSamplesEventArgs.cs b/SDRSharp.Common/SDRSharp.Common/ByteSamplesEventArgs.cs new file mode 100644 index 0000000..167bff0 --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common/ByteSamplesEventArgs.cs @@ -0,0 +1,19 @@ +using System; + +namespace SDRSharp.Common +{ + public sealed class ByteSamplesEventArgs : EventArgs + { + public int Length + { + get; + set; + } + + public unsafe byte* Buffer + { + get; + set; + } + } +} diff --git a/SDRSharp.Common/SDRSharp.Common/ComplexSamplesEventArgs.cs b/SDRSharp.Common/SDRSharp.Common/ComplexSamplesEventArgs.cs new file mode 100644 index 0000000..f37f10f --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common/ComplexSamplesEventArgs.cs @@ -0,0 +1,26 @@ +using SDRSharp.Radio; +using System; + +namespace SDRSharp.Common +{ + public sealed class ComplexSamplesEventArgs : EventArgs + { + public int Length + { + get; + set; + } + + public ulong DroppedSamples + { + get; + set; + } + + public unsafe Complex* Buffer + { + get; + set; + } + } +} diff --git a/SDRSharp.Common/SDRSharp.Common/IFFTSource.cs b/SDRSharp.Common/SDRSharp.Common/IFFTSource.cs new file mode 100644 index 0000000..76da60d --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common/IFFTSource.cs @@ -0,0 +1,36 @@ +namespace SDRSharp.Common +{ + public interface IFFTSource + { + bool FFTEnabled + { + get; + set; + } + + int FFTRange + { + get; + set; + } + + int FFTOffset + { + get; + set; + } + + int DisplayBandwidth + { + get; + } + + int DisplayPixels + { + get; + set; + } + + event SamplesAvailableDelegate FFTAvailable; + } +} diff --git a/SDRSharp.Common/SDRSharp.Common/ISharpControl.cs b/SDRSharp.Common/SDRSharp.Common/ISharpControl.cs new file mode 100644 index 0000000..0017a54 --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common/ISharpControl.cs @@ -0,0 +1,371 @@ +using SDRSharp.PanView; +using SDRSharp.Radio; +using System; +using System.ComponentModel; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace SDRSharp.Common +{ + public interface ISharpControl + { + DetectorType DetectorType + { + get; + set; + } + + WindowType FilterType + { + get; + set; + } + + int AudioGain + { + get; + set; + } + + long CenterFrequency + { + get; + set; + } + + int CWShift + { + get; + set; + } + + bool FilterAudio + { + get; + set; + } + + bool UnityGain + { + get; + set; + } + + int FilterBandwidth + { + get; + set; + } + + int FilterOrder + { + get; + set; + } + + bool FmStereo + { + get; + set; + } + + long Frequency + { + get; + set; + } + + long FrequencyShift + { + get; + set; + } + + bool FrequencyShiftEnabled + { + get; + set; + } + + bool MarkPeaks + { + get; + set; + } + + bool SnapToGrid + { + get; + set; + } + + bool SquelchEnabled + { + get; + set; + } + + int SquelchThreshold + { + get; + set; + } + + bool IsSquelchOpen + { + get; + } + + bool SwapIq + { + get; + set; + } + + bool UseAgc + { + get; + set; + } + + bool AgcHang + { + get; + set; + } + + int AgcThreshold + { + get; + set; + } + + int AgcDecay + { + get; + set; + } + + int AgcSlope + { + get; + set; + } + + int FFTResolution + { + get; + } + + float FFTRange + { + get; + } + + float FFTOffset + { + get; + } + + int FFTContrast + { + get; + } + + float VisualSNR + { + get; + } + + int IFOffset + { + get; + } + + ColorBlend Gradient + { + get; + } + + SpectrumStyle FFTSpectrumStyle + { + get; + } + + int StepSize + { + get; + set; + } + + int Zoom + { + get; + set; + } + + bool IsPlaying + { + get; + } + + float SAttack + { + get; + set; + } + + float SDecay + { + get; + set; + } + + float WAttack + { + get; + set; + } + + float WDecay + { + get; + set; + } + + bool UseTimeMarkers + { + get; + set; + } + + string RdsProgramService + { + get; + } + + string RdsRadioText + { + get; + } + + bool RdsUseFEC + { + get; + set; + } + + int RFBandwidth + { + get; + } + + int RFDisplayBandwidth + { + get; + } + + int TunableBandwidth + { + get; + } + + float TuningLimit + { + get; + set; + } + + TuningStyle TuningStyle + { + get; + set; + } + + bool TuningStyleFreezed + { + get; + set; + } + + bool SourceIsSoundCard + { + get; + } + + bool SourceIsWaveFile + { + get; + } + + bool SourceIsTunable + { + get; + } + + object Source + { + get; + } + + bool AudioIsMuted + { + get; + set; + } + + bool BypassDemodulation + { + get; + set; + } + + Type SourceType + { + get; + } + + string SourceName + { + get; + } + + double AudioSampleRate + { + get; + } + + event PropertyChangedEventHandler PropertyChanged; + + event CustomPaintEventHandler WaterfallCustomPaint; + + event CustomPaintEventHandler SpectrumAnalyzerCustomPaint; + + event CustomPaintEventHandler SpectrumAnalyzerBackgroundCustomPaint; + + void SetFrequency(long frequency, bool onlyMoveCenterFrequency); + + void ResetFrequency(long frequency); + + void ResetFrequency(long frequency, long centerFrequency); + + [Obsolete("Use GetSpectrumSnapshot(float[], float, float) instead")] + void GetSpectrumSnapshot(byte[] destArray); + + void GetSpectrumSnapshot(float[] destArray, float scale = 1f, float offset = 0f); + + void StartRadio(); + + void StopRadio(); + + void RegisterStreamHook(object streamHook, ProcessorType processorType); + + void UnregisterStreamHook(object streamHook); + + void RegisterFrontControl(UserControl control, PluginPosition preferredPosition); + + void Perform(); + + void RefreshSource(bool reload); + } +} diff --git a/SDRSharp.Common/SDRSharp.Common/ISharpPlugin.cs b/SDRSharp.Common/SDRSharp.Common/ISharpPlugin.cs new file mode 100644 index 0000000..0c66174 --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common/ISharpPlugin.cs @@ -0,0 +1,21 @@ +using System.Windows.Forms; + +namespace SDRSharp.Common +{ + public interface ISharpPlugin + { + UserControl Gui + { + get; + } + + string DisplayName + { + get; + } + + void Initialize(ISharpControl control); + + void Close(); + } +} diff --git a/SDRSharp.Common/SDRSharp.Common/IVFOSource.cs b/SDRSharp.Common/SDRSharp.Common/IVFOSource.cs new file mode 100644 index 0000000..4670454 --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common/IVFOSource.cs @@ -0,0 +1,27 @@ +namespace SDRSharp.Common +{ + public interface IVFOSource + { + long VFOFrequency + { + get; + set; + } + + int VFODecimation + { + get; + set; + } + + int VFOMinIQDecimation + { + get; + } + + double VFOMaxSampleRate + { + get; + } + } +} diff --git a/SDRSharp.Common/SDRSharp.Common/PluginPosition.cs b/SDRSharp.Common/SDRSharp.Common/PluginPosition.cs new file mode 100644 index 0000000..26f1718 --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common/PluginPosition.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.Common +{ + public enum PluginPosition + { + Top, + Bottom, + Left, + Right + } +} diff --git a/SDRSharp.Common/SDRSharp.Common/RealSamplesEventArgs.cs b/SDRSharp.Common/SDRSharp.Common/RealSamplesEventArgs.cs new file mode 100644 index 0000000..9567ba9 --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common/RealSamplesEventArgs.cs @@ -0,0 +1,25 @@ +using System; + +namespace SDRSharp.Common +{ + public sealed class RealSamplesEventArgs : EventArgs + { + public int Length + { + get; + set; + } + + public ulong DroppedSamples + { + get; + set; + } + + public unsafe float* Buffer + { + get; + set; + } + } +} diff --git a/SDRSharp.Common/SDRSharp.Common/SamplesAvailableDelegate.cs b/SDRSharp.Common/SDRSharp.Common/SamplesAvailableDelegate.cs new file mode 100644 index 0000000..b6b1d17 --- /dev/null +++ b/SDRSharp.Common/SDRSharp.Common/SamplesAvailableDelegate.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.Common +{ + public delegate void SamplesAvailableDelegate(object sender, ArgsType e); +} diff --git a/SDRSharp.Common/refs SDRSharp.PanView and Radio.txt b/SDRSharp.Common/refs SDRSharp.PanView and Radio.txt new file mode 100644 index 0000000..e69de29 diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit.sln b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit.sln new file mode 100644 index 0000000..2e2a264 --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.4 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDRSharp.FrequencyEdit", "SDRSharp.FrequencyEdit\SDRSharp.FrequencyEdit.csproj", "{A50690CF-7A7A-4B31-9A03-B3A2AF0AF0E0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A50690CF-7A7A-4B31-9A03-B3A2AF0AF0E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A50690CF-7A7A-4B31-9A03-B3A2AF0AF0E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A50690CF-7A7A-4B31-9A03-B3A2AF0AF0E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A50690CF-7A7A-4B31-9A03-B3A2AF0AF0E0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/EntryMode.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/EntryMode.cs new file mode 100644 index 0000000..352df41 --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/EntryMode.cs @@ -0,0 +1,11 @@ +using System; + +namespace SDRSharp.FrequencyEdit +{ + public enum EntryMode + { + None, + Direct, + Arrow + } +} diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyChangingEventArgs.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyChangingEventArgs.cs new file mode 100644 index 0000000..6dbb358 --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyChangingEventArgs.cs @@ -0,0 +1,15 @@ +using System; + +namespace SDRSharp.FrequencyEdit +{ + public class FrequencyChangingEventArgs : EventArgs + { + public long Frequency { get; set; } + + public bool Accept { get; set; } + + public FrequencyChangingEventArgs() + { + } + } +} diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEdit.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEdit.cs new file mode 100644 index 0000000..9a9b227 --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEdit.cs @@ -0,0 +1,749 @@ +using System; +using System.Drawing; +using System.Windows.Forms; +using SDRSharp.FrequencyEdit.Properties; + +namespace SDRSharp.FrequencyEdit +{ + public sealed class FrequencyEdit : UserControl + { + public event EventHandler FrequencyChanged; + + public event EventHandler FrequencyChanging; + + public int StepSize + { + get + { + return this._stepSize; + } + set + { + this._stepSize = value; + } + } + + public bool DisableFrequencyEvents + { + get + { + return this._disableFrequencyEvents; + } + set + { + this._disableFrequencyEvents = value; + } + } + + public bool EntryModeActive + { + get + { + return this._currentEntryMode > EntryMode.None; + } + } + + public long Frequency + { + get + { + return this._frequency; + } + set + { + this._frequencyChangingEventArgs.Accept = true; + this._frequencyChangingEventArgs.Frequency = value; + if (!this._disableFrequencyEvents && this.FrequencyChanging != null) + { + this.FrequencyChanging(this, this._frequencyChangingEventArgs); + } + if (this._frequencyChangingEventArgs.Accept) + { + this._frequency = this._frequencyChangingEventArgs.Frequency; + this.UpdateDigitsValues(); + if (!this._disableFrequencyEvents && this.FrequencyChanged != null) + { + this.FrequencyChanged(this, EventArgs.Empty); + } + } + } + } + + public FrequencyEdit() + { + this.DoubleBuffered = true; + this.AutoSize = true; + base.AutoSizeMode = AutoSizeMode.GrowAndShrink; + this._digitImages = Resources.Numbers; + this._renderTimer.Interval = 30; + this._renderTimer.Tick += this.renderTimer_Tick; + this._renderTimer.Enabled = true; + this.ConfigureComponent(); + } + + private void renderTimer_Tick(object sender, EventArgs e) + { + for (int i = 0; i < base.Controls.Count; i++) + { + if (base.Controls[i] is IRenderable) + { + ((IRenderable)base.Controls[i]).Render(); + } + } + } + + private void ConfigureComponent() + { + this.BackColor = Color.Transparent; + if (this._digitImages != null) + { + for (int i = 0; i < 12; i++) + { + if (this._digitControls[i] != null && base.Controls.Contains(this._digitControls[i])) + { + base.Controls.Remove(this._digitControls[i]); + this._digitControls[i] = null; + } + } + for (int j = 0; j < 12; j++) + { + if (this._separatorControls[j] != null && base.Controls.Contains(this._separatorControls[j])) + { + base.Controls.Remove(this._separatorControls[j]); + this._separatorControls[j] = null; + } + } + this.SplitDigitImages(); + } + if (this._imageList.Images.Count == 0) + { + return; + } + int num = 0; + int y = 0; + int width = this._imageList.ImageSize.Width; + int height = this._imageList.ImageSize.Height; + for (int k = 11; k >= 0; k--) + { + if ((k + 1) % 3 == 0 && k != 11) + { + FrequencyEditSeparator frequencyEditSeparator = new FrequencyEditSeparator(); + int num2 = width / 2; + int num3 = k / 3; + frequencyEditSeparator.Image = this._imageList.Images[11]; + frequencyEditSeparator.Width = num2; + frequencyEditSeparator.Height = height; + frequencyEditSeparator.Location = new Point(num, y); + base.Controls.Add(frequencyEditSeparator); + this._separatorControls[num3] = frequencyEditSeparator; + num += num2 + 2; + } + FrequencyEditDigit frequencyEditDigit = new FrequencyEditDigit(k); + frequencyEditDigit.Location = new Point(num, y); + frequencyEditDigit.OnDigitClick += this.DigitClickHandler; + frequencyEditDigit.MouseLeave += this.DigitMouseLeave; + frequencyEditDigit.Width = width; + frequencyEditDigit.Height = height; + frequencyEditDigit.ImageList = this._imageList; + base.Controls.Add(frequencyEditDigit); + this._digitControls[k] = frequencyEditDigit; + num += width + 2; + } + long num4 = 1L; + for (int l = 0; l < 12; l++) + { + this._digitControls[l].Weight = num4; + num4 *= 10L; + } + base.Height = height; + this.UpdateDigitMask(); + } + + private void SplitDigitImages() + { + int height = this._digitImages.Height; + int num = (int)Math.Round((double)((float)this._digitImages.Width / 11.5f)); + this._imageList.Images.Clear(); + this._imageList.ImageSize = new Size(num, height); + int num2 = 0; + Bitmap bitmap; + for (int i = 0; i < 11; i++) + { + bitmap = new Bitmap(num, height); + using (Graphics graphics = Graphics.FromImage(bitmap)) + { + graphics.DrawImage(this._digitImages, new Rectangle(0, 0, num, height), new Rectangle(num2, 0, num, height), GraphicsUnit.Pixel); + } + num2 += num; + this._imageList.Images.Add(bitmap); + } + bitmap = new Bitmap(num, height); + using (Graphics graphics2 = Graphics.FromImage(bitmap)) + { + graphics2.DrawImage(this._digitImages, new Rectangle(0, 0, num, height), new Rectangle(num2, 0, num / 2, height), GraphicsUnit.Pixel); + } + this._imageList.Images.Add(bitmap); + } + + private void DigitClickHandler(object sender, FrequencyEditDigitClickEventArgs args) + { + if (this._currentEntryMode != EntryMode.None) + { + this.LeaveEntryMode(); + return; + } + FrequencyEditDigit frequencyEditDigit = (FrequencyEditDigit)sender; + if (frequencyEditDigit != null) + { + this._newFrequency = this._frequency; + if (args.Button == MouseButtons.Right) + { + this.ZeroDigits(frequencyEditDigit.DigitIndex); + } + else if (args.IsUpperHalf && this._frequency >= 0L) + { + this.IncrementDigit(frequencyEditDigit.DigitIndex, true); + } + else + { + this.DecrementDigit(frequencyEditDigit.DigitIndex, true); + } + if (this._newFrequency != this._frequency) + { + this._frequencyChangingEventArgs.Accept = true; + this._frequencyChangingEventArgs.Frequency = this._newFrequency; + if (!this._disableFrequencyEvents && this.FrequencyChanging != null) + { + this.FrequencyChanging(this, this._frequencyChangingEventArgs); + } + if (this._frequencyChangingEventArgs.Accept) + { + this._frequency = this._frequencyChangingEventArgs.Frequency; + this.UpdateDigitsValues(); + if (!this._disableFrequencyEvents && this.FrequencyChanged != null) + { + this.FrequencyChanged(this, EventArgs.Empty); + return; + } + } + else + { + this.UpdateDigitsValues(); + } + } + } + } + + private void IncrementDigit(int index, bool updateDigit) + { + FrequencyEditDigit frequencyEditDigit = this._digitControls[index]; + if (frequencyEditDigit != null) + { + int displayedDigit = frequencyEditDigit.DisplayedDigit; + int num = (frequencyEditDigit.DisplayedDigit == 9) ? 0 : (frequencyEditDigit.DisplayedDigit + 1); + long newFrequency = this._newFrequency - (long)displayedDigit * frequencyEditDigit.Weight + (long)num * frequencyEditDigit.Weight; + if (updateDigit) + { + frequencyEditDigit.DisplayedDigit = num; + } + this._newFrequency = newFrequency; + if (displayedDigit == 9 && index < 11) + { + this.IncrementDigit(index + 1, updateDigit); + } + } + } + + private void DecrementDigit(int index, bool updateDigit) + { + FrequencyEditDigit frequencyEditDigit = this._digitControls[index]; + if (frequencyEditDigit != null) + { + int displayedDigit = frequencyEditDigit.DisplayedDigit; + int num = (frequencyEditDigit.DisplayedDigit == 0) ? 9 : (frequencyEditDigit.DisplayedDigit - 1); + long newFrequency = this._newFrequency - (long)displayedDigit * frequencyEditDigit.Weight + (long)num * frequencyEditDigit.Weight; + if (updateDigit) + { + frequencyEditDigit.DisplayedDigit = num; + } + this._newFrequency = newFrequency; + if (displayedDigit == 0 && index < 11 && (double)this._newFrequency > Math.Pow(10.0, (double)(index + 1))) + { + this.DecrementDigit(index + 1, updateDigit); + } + } + } + + private void ZeroDigits(int index) + { + for (int i = 0; i <= index; i++) + { + this._digitControls[i].DisplayedDigit = 0; + } + long num = (long)Math.Pow(10.0, (double)(index + 1)); + this._newFrequency = this._newFrequency / num * num; + } + + private void UpdateDigitsValues() + { + if (this._digitControls[0] == null) + { + return; + } + long num = this._frequency; + for (int i = 11; i >= 0; i--) + { + long num2 = num / this._digitControls[i].Weight; + this._digitControls[i].DisplayedDigit = (int)num2; + num -= (long)this._digitControls[i].DisplayedDigit * this._digitControls[i].Weight; + } + this.UpdateDigitMask(); + } + + private void UpdateDigitMask() + { + long frequency = this._frequency; + if (frequency >= 0L) + { + for (int i = 1; i < 12; i++) + { + if ((i + 1) % 3 == 0 && i != 11) + { + int num = i / 3; + if (this._separatorControls[num] != null) + { + this._separatorControls[num].Masked = (this._digitControls[i + 1].Weight > frequency); + } + } + if (this._digitControls[i] != null) + { + this._digitControls[i].Masked = (this._digitControls[i].Weight > frequency); + } + } + } + } + + private void DigitMouseLeave(object sender, EventArgs e) + { + if (!base.ClientRectangle.Contains(base.PointToClient(Control.MousePosition)) && this._currentEntryMode != EntryMode.None) + { + this.AbortEntryMode(); + } + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + if (!base.ClientRectangle.Contains(base.PointToClient(Control.MousePosition)) && this._currentEntryMode != EntryMode.None) + { + this.AbortEntryMode(); + } + } + + private long GetFrequencyValue() + { + long num = 0L; + for (int i = 0; i < this._digitControls.Length; i++) + { + num += this._digitControls[i].Weight * (long)this._digitControls[i].DisplayedDigit; + } + return num; + } + + private void SetFrequencyValue(long newFrequency) + { + if (newFrequency != this._frequency) + { + this._frequencyChangingEventArgs.Accept = true; + this._frequencyChangingEventArgs.Frequency = newFrequency; + if (!this._disableFrequencyEvents && this.FrequencyChanging != null) + { + this.FrequencyChanging(this, this._frequencyChangingEventArgs); + } + if (this._frequencyChangingEventArgs.Accept) + { + this._frequency = this._frequencyChangingEventArgs.Frequency; + this.UpdateDigitsValues(); + if (!this._disableFrequencyEvents && this.FrequencyChanged != null) + { + this.FrequencyChanged(this, EventArgs.Empty); + } + } + } + } + + private void EnterDirectMode() + { + if (this._changingEntryMode) + { + return; + } + this._changingEntryMode = true; + for (int i = 0; i < this._digitControls.Length; i++) + { + if (this._digitControls[i] != null) + { + this._digitControls[i].Masked = false; + if (this._digitControls[i].CursorInside) + { + this._editModePosition = i; + this._digitControls[i].Highlight = true; + } + } + } + this.ZeroDigits(this._digitControls.Length - 1); + this._currentEntryMode = EntryMode.Direct; + this._changingEntryMode = false; + } + + private void DirectModeHandler(KeyEventArgs args) + { + Keys keyCode = args.KeyCode; + if (keyCode <= Keys.Return) + { + if (keyCode != Keys.Back) + { + if (keyCode != Keys.Tab) + { + if (keyCode != Keys.Return) + { + return; + } + this.LeaveEntryMode(); + return; + } + } + else + { + this._digitControls[this._editModePosition].DisplayedDigit = 0; + if (this._editModePosition < this._digitControls.Length - 1) + { + this._digitControls[this._editModePosition].Highlight = false; + this._editModePosition++; + this._digitControls[this._editModePosition].Highlight = true; + return; + } + return; + } + } + else + { + if (keyCode <= Keys.D9) + { + if (keyCode == Keys.Escape) + { + this.AbortEntryMode(); + return; + } + switch (keyCode) + { + case Keys.Left: + if (this._editModePosition < this._digitControls.Length - 1) + { + this._digitControls[this._editModePosition].Highlight = false; + this._editModePosition++; + this._digitControls[this._editModePosition].Highlight = true; + return; + } + return; + case Keys.Up: + case Keys.Down: + case Keys.Select: + case Keys.Print: + case Keys.Execute: + case Keys.Snapshot: + case Keys.Insert: + case Keys.Delete: + case Keys.Help: + return; + case Keys.Right: + if (this._editModePosition > 0) + { + this._digitControls[this._editModePosition].Highlight = false; + this._editModePosition--; + this._digitControls[this._editModePosition].Highlight = true; + return; + } + return; + case Keys.D0: + case Keys.D1: + case Keys.D2: + case Keys.D3: + case Keys.D4: + case Keys.D5: + case Keys.D6: + case Keys.D7: + case Keys.D8: + case Keys.D9: + break; + default: + return; + } + } + else + { + switch (keyCode) + { + case Keys.NumPad0: + case Keys.NumPad1: + case Keys.NumPad2: + case Keys.NumPad3: + case Keys.NumPad4: + case Keys.NumPad5: + case Keys.NumPad6: + case Keys.NumPad7: + case Keys.NumPad8: + case Keys.NumPad9: + break; + case Keys.Multiply: + case Keys.Add: + case Keys.Separator: + case Keys.Subtract: + return; + case Keys.Decimal: + goto IL_249; + default: + if (keyCode != Keys.OemPeriod) + { + return; + } + goto IL_249; + } + } + int displayedDigit = (args.KeyCode >= Keys.D0 && args.KeyCode <= Keys.D9) ? (args.KeyCode - Keys.D0) : (args.KeyCode - Keys.NumPad0); + this._digitControls[this._editModePosition].DisplayedDigit = displayedDigit; + if (this._editModePosition > 0) + { + this._digitControls[this._editModePosition].Highlight = false; + this._editModePosition--; + this._digitControls[this._editModePosition].Highlight = true; + return; + } + this.LeaveEntryMode(); + return; + } + IL_249: + this._digitControls[this._editModePosition].Highlight = false; + this._editModePosition -= this._editModePosition % 3 + 1; + if (this._editModePosition < 2) + { + if (args.KeyCode != Keys.Tab) + { + this._editModePosition = 0; + this.LeaveEntryMode(); + return; + } + this._editModePosition = this._digitControls.Length - 1; + } + this._digitControls[this._editModePosition].Highlight = true; + } + + private void EnterArrowMode() + { + if (this._changingEntryMode) + { + return; + } + this._changingEntryMode = true; + for (int i = 0; i < this._digitControls.Length; i++) + { + if (this._digitControls[i] != null) + { + this._digitControls[i].Masked = false; + if (this._digitControls[i].CursorInside) + { + this._editModePosition = i; + this._digitControls[i].Highlight = true; + } + } + } + this._currentEntryMode = EntryMode.Arrow; + this._changingEntryMode = false; + } + + private void ArrowModeHandler(KeyEventArgs args) + { + Keys keyCode = args.KeyCode; + if (keyCode <= Keys.Return) + { + if (keyCode == Keys.Tab) + { + this._digitControls[this._editModePosition].Highlight = false; + this._editModePosition -= this._editModePosition % 3 + 1; + if (this._editModePosition < 2) + { + this._editModePosition = this._digitControls.Length - 1; + } + this._digitControls[this._editModePosition].Highlight = true; + return; + } + if (keyCode != Keys.Return) + { + return; + } + } + else if (keyCode != Keys.Escape) + { + switch (keyCode) + { + case Keys.Left: + if (this._editModePosition < this._digitControls.Length - 1) + { + this._digitControls[this._editModePosition].Highlight = false; + this._editModePosition++; + this._digitControls[this._editModePosition].Highlight = true; + return; + } + return; + case Keys.Up: + this._newFrequency = this._frequency; + this.IncrementDigit(this._editModePosition, false); + this.SetFrequencyValue(this._newFrequency); + return; + case Keys.Right: + if (this._editModePosition > 0) + { + this._digitControls[this._editModePosition].Highlight = false; + this._editModePosition--; + this._digitControls[this._editModePosition].Highlight = true; + return; + } + return; + case Keys.Down: + this._newFrequency = this._frequency; + this.DecrementDigit(this._editModePosition, false); + this.SetFrequencyValue(this._newFrequency); + return; + default: + return; + } + } + this.AbortEntryMode(); + } + + private void AbortEntryMode() + { + if (this._changingEntryMode) + { + return; + } + this._changingEntryMode = true; + this._digitControls[this._editModePosition].Highlight = false; + this.UpdateDigitsValues(); + this._currentEntryMode = EntryMode.None; + this._changingEntryMode = false; + } + + private void LeaveEntryMode() + { + if (this._changingEntryMode) + { + return; + } + this._changingEntryMode = true; + this._digitControls[this._editModePosition].Highlight = false; + if (this._currentEntryMode == EntryMode.Direct) + { + long frequencyValue = this.GetFrequencyValue(); + this.SetFrequencyValue(frequencyValue); + } + this._currentEntryMode = EntryMode.None; + this._changingEntryMode = false; + } + + private bool DigitKeyHandler(KeyEventArgs args) + { + if (!base.ClientRectangle.Contains(base.PointToClient(Control.MousePosition)) || this._changingEntryMode) + { + return false; + } + if (this._currentEntryMode != EntryMode.None) + { + EntryMode currentEntryMode = this._currentEntryMode; + if (currentEntryMode != EntryMode.Direct) + { + if (currentEntryMode == EntryMode.Arrow) + { + this.ArrowModeHandler(args); + } + } + else + { + this.DirectModeHandler(args); + } + return true; + } + if ((args.KeyCode >= Keys.D0 && args.KeyCode <= Keys.D9) || (args.KeyCode >= Keys.NumPad0 && args.KeyCode <= Keys.NumPad9)) + { + this.EnterDirectMode(); + this.DirectModeHandler(args); + return true; + } + if (args.KeyCode == Keys.Up || args.KeyCode == Keys.Down || args.KeyCode == Keys.Left || args.KeyCode == Keys.Right) + { + this.EnterArrowMode(); + this.ArrowModeHandler(args); + return true; + } + if (args.Modifiers == Keys.Control) + { + if (args.KeyCode == Keys.C) + { + Clipboard.SetText(string.Format("{0}", this.GetFrequencyValue()), TextDataFormat.Text); + return true; + } + if (args.KeyCode == Keys.V) + { + long frequencyValue = 0L; + if (long.TryParse(Clipboard.GetText(), out frequencyValue)) + { + this.SetFrequencyValue(frequencyValue); + } + return true; + } + } + return false; + } + + protected override bool ProcessCmdKey(ref Message msg, Keys keyData) + { + if (msg.Msg == 256 || msg.Msg == 260) + { + return this.DigitKeyHandler(new KeyEventArgs(keyData)); + } + return base.ProcessCmdKey(ref msg, keyData); + } + + private const int DigitCount = 12; + + private const int DigitImageSplitCount = 12; + + private const int DigitSeperatorCount = 12; + + private readonly FrequencyEditDigit[] _digitControls = new FrequencyEditDigit[12]; + + private readonly FrequencyEditSeparator[] _separatorControls = new FrequencyEditSeparator[12]; + + private readonly ImageList _imageList = new ImageList(); + + private readonly Image _digitImages; + + private readonly Timer _renderTimer = new Timer(); + + private readonly FrequencyChangingEventArgs _frequencyChangingEventArgs = new FrequencyChangingEventArgs(); + + private long _frequency; + + private long _newFrequency; + + private int _stepSize; + + private int _editModePosition; + + private bool _changingEntryMode; + + private bool _disableFrequencyEvents; + + private EntryMode _currentEntryMode; + } +} diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditDigit.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditDigit.cs new file mode 100644 index 0000000..0d1298a --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditDigit.cs @@ -0,0 +1,271 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Windows.Forms; + +namespace SDRSharp.FrequencyEdit +{ + internal sealed class FrequencyEditDigit : UserControl, IRenderable + { + public event OnDigitClickDelegate OnDigitClick; + + public ImageList ImageList + { + get + { + return this._imageList; + } + set + { + this._imageList = value; + } + } + + public bool Highlight + { + get + { + return this._highlight; + } + set + { + this._highlight = value; + this._renderNeeded = true; + } + } + + public bool CursorInside + { + get + { + return this._cursorInside; + } + } + + public int DisplayedDigit + { + get + { + return this._displayedDigit; + } + set + { + if (value >= 0 && value <= 9 && this._displayedDigit != value) + { + this._displayedDigit = value; + this._renderNeeded = true; + } + } + } + + public int DigitIndex + { + get + { + return this._digitIndex; + } + } + + public bool Masked + { + get + { + return this._masked; + } + set + { + if (this._masked != value) + { + this._masked = value; + this._renderNeeded = true; + } + } + } + + public long Weight + { + get + { + return this._weight; + } + set + { + this._weight = value; + } + } + + public FrequencyEditDigit(int digitIndex) + { + this.DoubleBuffered = true; + this.BackColor = Color.Transparent; + this._tickTimer.Tick += this.timer_Tick; + base.UpdateStyles(); + this._digitIndex = digitIndex; + ColorMatrix colorMatrix = new ColorMatrix(); + colorMatrix.Matrix33 = 0.3f; + this._maskedAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); + } + + protected override void OnPaint(PaintEventArgs e) + { + if (this._imageList != null && this._displayedDigit < this._imageList.Images.Count) + { + Image image = this._imageList.Images[this._displayedDigit]; + ImageAttributes imageAttrs = ((this._masked && !this._cursorInside) || !base.Parent.Enabled) ? this._maskedAttributes : null; + e.Graphics.DrawImage(image, new Rectangle(0, 0, base.Width, base.Height), 0f, 0f, (float)image.Width, (float)image.Height, GraphicsUnit.Pixel, imageAttrs); + } + if (this._cursorInside && !((FrequencyEdit)base.Parent).EntryModeActive) + { + bool flag = this._lastMouseY <= base.ClientRectangle.Height / 2; + using (SolidBrush solidBrush = new SolidBrush(Color.FromArgb(100, flag ? Color.Red : Color.Blue))) + { + if (flag) + { + e.Graphics.FillRectangle(solidBrush, new Rectangle(0, 0, base.ClientRectangle.Width, base.ClientRectangle.Height / 2)); + } + else + { + e.Graphics.FillRectangle(solidBrush, new Rectangle(0, base.ClientRectangle.Height / 2, base.ClientRectangle.Width, base.ClientRectangle.Height)); + } + } + } + if (this._highlight) + { + SolidBrush brush = new SolidBrush(Color.FromArgb(25, Color.Red)); + e.Graphics.FillRectangle(brush, new Rectangle(0, 0, base.ClientRectangle.Width, base.ClientRectangle.Height)); + } + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + this._isUpperHalf = (e.Y <= base.ClientRectangle.Height / 2); + this._lastMouseY = e.Y; + if (this._isUpperHalf != this._lastIsUpperHalf) + { + this._renderNeeded = true; + this._tickCount = 0; + } + this._lastIsUpperHalf = this._isUpperHalf; + } + + protected override void OnMouseEnter(EventArgs e) + { + base.OnMouseEnter(e); + this._cursorInside = true; + this._renderNeeded = true; + base.Focus(); + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + this._cursorInside = false; + this._renderNeeded = true; + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + this._isUpperHalf = (e.Y <= base.ClientRectangle.Height / 2); + if (this.OnDigitClick != null) + { + this.OnDigitClick(this, new FrequencyEditDigitClickEventArgs(this._isUpperHalf, e.Button)); + } + this._tickCount = 1; + this._tickTimer.Interval = 300; + this._tickTimer.Enabled = true; + } + + protected override void OnMouseUp(MouseEventArgs e) + { + this._tickTimer.Enabled = false; + } + + protected override void OnMouseWheel(MouseEventArgs e) + { + base.OnMouseWheel(e); + if (this.OnDigitClick != null) + { + this.OnDigitClick(this, new FrequencyEditDigitClickEventArgs(e.Delta > 0, e.Button)); + } + } + + public void Render() + { + if (this._renderNeeded) + { + base.Invalidate(); + this._renderNeeded = false; + } + } + + private void timer_Tick(object sender, EventArgs e) + { + if (this.OnDigitClick != null) + { + this.OnDigitClick(this, new FrequencyEditDigitClickEventArgs(this._isUpperHalf, MouseButtons.Left)); + } + this._tickCount++; + int tickCount = this._tickCount; + if (tickCount <= 20) + { + if (tickCount == 10) + { + this._tickTimer.Interval = 200; + return; + } + if (tickCount != 20) + { + return; + } + this._tickTimer.Interval = 100; + return; + } + else + { + if (tickCount == 50) + { + this._tickTimer.Interval = 50; + return; + } + if (tickCount != 100) + { + return; + } + this._tickTimer.Interval = 20; + return; + } + } + + private const float MaskedDigitTransparency = 0.3f; + + private bool _masked; + + private int _displayedDigit; + + private long _weight; + + private bool _renderNeeded; + + private bool _cursorInside; + + private bool _highlight; + + private int _lastMouseY; + + private bool _lastIsUpperHalf; + + private bool _isUpperHalf; + + private int _tickCount; + + private ImageList _imageList; + + private readonly int _digitIndex; + + private readonly Timer _tickTimer = new Timer(); + + private readonly ImageAttributes _maskedAttributes = new ImageAttributes(); + } +} diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditDigitClickEventArgs.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditDigitClickEventArgs.cs new file mode 100644 index 0000000..f6cc3c9 --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditDigitClickEventArgs.cs @@ -0,0 +1,18 @@ +using System; +using System.Windows.Forms; + +namespace SDRSharp.FrequencyEdit +{ + public class FrequencyEditDigitClickEventArgs + { + public FrequencyEditDigitClickEventArgs(bool isUpperHalf, MouseButtons button) + { + this.IsUpperHalf = isUpperHalf; + this.Button = button; + } + + public bool IsUpperHalf; + + public MouseButtons Button; + } +} diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditSeparator.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditSeparator.cs new file mode 100644 index 0000000..2b7cc74 --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/FrequencyEditSeparator.cs @@ -0,0 +1,75 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Windows.Forms; + +namespace SDRSharp.FrequencyEdit +{ + internal sealed class FrequencyEditSeparator : UserControl, IRenderable + { + public Image Image + { + get + { + return this._image; + } + set + { + this._image = value; + } + } + + public bool Masked + { + get + { + return this._masked; + } + set + { + if (this._masked != value) + { + this._masked = value; + this._renderNeeded = true; + } + } + } + + public FrequencyEditSeparator() + { + this.DoubleBuffered = true; + base.UpdateStyles(); + ColorMatrix colorMatrix = new ColorMatrix(); + colorMatrix.Matrix33 = 0.3f; + this._maskedAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); + } + + public void Render() + { + if (this._renderNeeded) + { + base.Invalidate(); + this._renderNeeded = false; + } + } + + protected override void OnPaint(PaintEventArgs e) + { + if (this._image != null) + { + ImageAttributes imageAttrs = (this._masked || !base.Parent.Enabled) ? this._maskedAttributes : null; + e.Graphics.DrawImage(this._image, new Rectangle(0, 0, base.Width, base.Height), 0f, 0f, (float)this._image.Width, (float)this._image.Height, GraphicsUnit.Pixel, imageAttrs); + } + } + + private const float MaskedDigitTransparency = 0.3f; + + private Image _image; + + private bool _masked; + + private bool _renderNeeded; + + private readonly ImageAttributes _maskedAttributes = new ImageAttributes(); + } +} diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/IRenderable.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/IRenderable.cs new file mode 100644 index 0000000..8e7fa9c --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/IRenderable.cs @@ -0,0 +1,9 @@ +using System; + +namespace SDRSharp.FrequencyEdit +{ + internal interface IRenderable + { + void Render(); + } +} diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/OnDigitClickDelegate.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/OnDigitClickDelegate.cs new file mode 100644 index 0000000..9fd38d5 --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/OnDigitClickDelegate.cs @@ -0,0 +1,6 @@ +using System; + +namespace SDRSharp.FrequencyEdit +{ + public delegate void OnDigitClickDelegate(object sender, FrequencyEditDigitClickEventArgs args); +} diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/AssemblyInfo.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cbf8a45 --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/AssemblyInfo.cs @@ -0,0 +1,24 @@ +using System; +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; +using System.Security; +using System.Security.Permissions; + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: CompilationRelaxations(8)] +[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] +[assembly: AssemblyTitle("Frequency Edit Control")] +[assembly: AssemblyDescription("Frequency Edit Control")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SDR#")] +[assembly: AssemblyCopyright("Copyright © 2012 Youssef Touil, Ian Gilmour")] +[assembly: AssemblyTrademark("")] +[assembly: ComVisible(false)] +[assembly: Guid("300880ef-fb6f-41ec-b607-d468751fe0ad")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/Resources.Designer.cs b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/Resources.Designer.cs new file mode 100644 index 0000000..9812f8e --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/Resources.Designer.cs @@ -0,0 +1,59 @@ +using System; +using System.CodeDom.Compiler; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Globalization; +using System.Resources; +using System.Runtime.CompilerServices; + +namespace SDRSharp.FrequencyEdit.Properties +{ + [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [DebuggerNonUserCode] + [CompilerGenerated] + internal class Resources + { + internal Resources() + { + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + internal static ResourceManager ResourceManager + { + get + { + if (Resources.resourceMan == null) + { + Resources.resourceMan = new ResourceManager("SDRSharp.FrequencyEdit.Properties.Resources", typeof(Resources).Assembly); + } + return Resources.resourceMan; + } + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + internal static CultureInfo Culture + { + get + { + return Resources.resourceCulture; + } + set + { + Resources.resourceCulture = value; + } + } + + internal static Bitmap Numbers + { + get + { + return (Bitmap)Resources.ResourceManager.GetObject("Numbers", Resources.resourceCulture); + } + } + + private static ResourceManager resourceMan; + + private static CultureInfo resourceCulture; + } +} diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/Resources.resx b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/Resources.resx new file mode 100644 index 0000000..a3fd2aa --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/Properties/Resources.resx @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAAM8AAAAWCAYAAABnsMi4AAAABGdBTUEAALGPC/xhBQAAABp0RVh0U29m + dHdhcmUAUGFpbnQuTkVUIHYzLjUuMTAw9HKhAAALqklEQVR4XtXcBawluRGF4QkzMzMzKszMzMykMEeh + DSqkMDMzMyjMzMzMzDA532pKcloN7vvenVWO9Gtn+7rdbttll8vut2dExwnXD08O7w179/GF8Oxwy3DK + cPDQq8OEk4Q7hEeG04Qeue884d7Bsz8Wqjz+7drdw+nDVHkOFy4V7hm80xvDH0Ll877wtOC9ThTW6B5B + Hj8Op3ahQ8cO9exenhF6dKrwqfD9cEUXFnSk8KYw9swlLhnGVP1HnarbSv+b8OLw4HDBcOgwp6OGq4dH + hdeGX4XK5/lBnzhDWNMPt6ZDhWuHj4a/hHrpIX8Lnw8MQcdc0sXDu8LXgvt/GM4clnSsoNJ0zHr2H8PP + ws/DP/ddw3fCAWGsPAxdhVda5Xe/fPCPUNc/E24UehqEEXw6uPepYakzlHRw9/wr6BBVjjkeHZZ0/PDu + IO/fh2uGJTEeHXrsmWOof/njEmGo84UPhLn+g5+Gx4Sp/nOm8M5Qz2vrqtoLXw63DfruQaZDhNuEKhRe + Hx4Y7rIPI7fRpE3zoHD4MCf5viF8JLin13hOG6T/bXhuuF+4SjhHOHdQaRqgNS4zwSFDK/l4pjyMejcO + 7pcPbh3MSJUHLhqWdPNQneR0LnSq3utH4cqhyjGHWXtOOs8zgwFA3jcIw3oYkzS8gLFnjvHyIH+dWAdv + ZTAxiPkd+s/9Q/UfbfPE0LbXvcKw48uHl1NpDKDuvVBQBu1lMGnzuVU4yGag8wajgYJ8NVw1GEkPFlqp + bB2vDMHorxPNyT3yulxwT6/x6DA3CUZUeQzLQozezGK0kzd3xVTeinEfLchjqoLlww35SZCPmfLoYUre + 58NB2teFsbJNSSdw39fDCVzYoXS+Owaj85/DfcM2OtJJgzIr+9MDl7rkeZ7rNwZskBrrP+r5bOGzQdpv + BTNx6bDhhcFvZp07hbl8PhGk5dXoB/tdCvzmUC9u1Fqq/PMHRuCeTwZ+7pJ0Tul7jUdn79XVgs4j/xu6 + sIG88yOCPDTcWcKULhCk4x7xy0s6sk6FKYOqeuByzBlor7jFvwzytAY8QtiG7hz+HjzHANrKMw0ifvtm + OHGYE6OQFq37d/LwjeA6T2FpWXCNUGXatN13pHOFmnVMtUcMS9JJHhLcY7S7TljSWuNZIwv9LwX5cxU2 + lUW2PKC8YzKTcSWk+WKwbiB1wpV8QbDIPUYYU3UcrklPXc/pKOE9QX48ht6gxVrpxIzdc6zzhmoDD2YV + s8Wcqi+gXZu119tBaUrHDBWUeI0L+1v3Cf8OCtAToSmJcNWLPsmFBW3TeMx8Ah3yf7ULG+pKod5pbEFM + FsW1tuB/l3SYlwTXuTfczTGJnEmjE65x98ZkzVCBk8uGneY3JnlWvfw13CwM1c48nwu8mTkpq7RoB6nr + hrpuUF+SAetFQXpBrG3NupMqHxPHdaFT3KqKfDCIJW3TeKxzKpRpcbqJdBIDiTwsiM8YhpLGrCINP5ub + UeoxHq7hc4I0Hw98dx3AvcXc2qyVDqou5WWNZnZo8/Jv+e/UoMxubw2eY3Yfc9GVt4JJggbtOmYo5dFG + 0lqjtsEWIW7XITjQoxqMlM3adr/qK8HDf3Hg/63Tq0K97JK2aTzCy1UOgYlNxFi+G+Qx5b7qFJXmoUHn + LOmwS8bTpvlQeHzg5olGFs8KDPRaQeRpSq2LKaxr9n9eqHz8W/4iURb7bVnXqNoNd3VhQicLbXmm1nNm + MVsF0ilzG3jgqlUe1tU9KuPhttre2K+qwqrwtfLydf+StmU8Kqw2T0XApmZPIzEDEVlsuUzgiiiXoIP1 + n1FvbMQWmq+olg7Zqsd4dJSXhaqzOTyDC2QdJe9W1l0vDWP3DeFi6ljWgmvXWGZBRigfgYC5NZXZ5wGh + wvfSGwRuug8urg3qXwd1aK02rCMGUy7x7VxYkPLZMJV+N9aQq+XBMIus1eNC3b+kbRmP/Se+uLyFtqdc + nnZdNIUGndrj4U/XPob9jqF6jEfj6kD8dHsV1iy3D8L90MHsnJcfXzhF0RqQaFYFSH4XlMeelyCO+hA2 + fmyoYELxsLAUwWplsPlBcC+jb2eJMfndXk77zDHkKdQ81PFChZ8NhHMzLx05VKTYBvems+vGqhf6fzMe + RmI/qp4vAjYnbgQ35i2BD++/sGfVHv24WzBLtTIL6dzSONojND5Uj/Eoc28I/qyh9q+UzyxZukhwHTZa + 5ySsXPlgTVDIyYm6b24dQwYX67maebhm7wgCOK8I6rpOZEAdCQq0g51/q/9K46iRNlaXInoGH56Gslwv + 8JYqrY3U/a56uGjJWj0h1P1L2k3j0ZlFverIj/DocHN0KA2jASyAW7h53DSBE3sGFXpvG1VI9P3Bsyz0 + GSIDa9F5yiWzV3HCsFOJ+P0pyNNMUq6k9ZBrAjbndGFB3KHvBfc4iTDmkg5lpq5jTQabuVHdjFOBFG4X + V+rswfk0M53fzRLqhHfQhr2duGhVLmnt39hLk97MIj33zOaqdvJ7PfNiYUza0Uytf4xhtttYFTDQqdeq + 9d+XtJvGo7PXKPbt0I7Km0pDW+jK094Bgyk5yFjvyVAt6ocYdTWqNFwp+zlLR5eW1O6fCMWWy1VRKR2p + 5zBrG0ruCenqcFxK6W0YCyHPiXtXpzMMQkvvfeEgoin9w10YiKF5vraVZgxn8mpz+INhKljQ1uEYvYdu + R9WGqteE+oxEtQboMbzdMB7PNBqb8v8TjKZG1Z6RtEe3CMpoQes0d6nKvgazggW/0W1Tta6gQa46SBmP + +m/D5VNq8xE8WFpLOBrFyKQXFTRDz4kbKy2u4MKC2g6tjsYW+gyYkTNM9e80weWDgVM9+He527YYpvrA + Vo2n3SR17qpXok1VADH+Je3UeKwVnPquEYsBOZqym6rzd1DekjCsmWQOvjof3b3C/iJPrrt3U3F3Kqom + QGB2pHYzt2czsTUepyKWjMF6ovJ3bm5J7f5MO+hMaa0xD8VNtoZyv0Fl7n30Gy7kpSew2b+x2uM5Gmop + okJmgDoIyPdU2UvaifEok47IHZIHH7in06xVO4K2xtOjnoDBWjGWtwd5tsde6mwdeo6xGNntXQ3zGZOR + 2qartGa2nm+v2nrrOZHO/XxlkH5tiFnfE8Z2L5dSGPwgkxd5W1AYx+R7Xt4izwjmnm0dDC2dIjwlCEdD + 5MZp5N1y1UpGqPo0wWcQwyP3S9qG8XBNat/D5yElbktF0ISplwY8YWFtK/3S2T9uVwUKBCnmDK1ktqlv + bxwgbYMtY2rdQi7VmrYUaazwubD/0vpt62IwNfsI3fIzxyrAS+oUFSLs+SShtNZ4PF+YtfYqGI59jCWX + YyiL16VPEvzGZWsPyBqB16jXeLgoGtwzpzqN0dUAZb0hP65qG1Xzu91+vwmd2x+aai+GVsEC78eFmZL0 + lda6bxgJm5LoYwVbrGG071RdG6ztW9UzuOK9EjWrqOdO15Oz2rt374HsEzdREAPq/n+kIWsqhA+NHM/n + HhglRHSMXkYVha50PR/DldYYj8Kajus5sDZrP2KbYvhhmg7gmWMfw/mvTcr2Iz/rlbkONqVe47FAFejw + TLOAIIVoYZXHiQL7UUsfjTFuLk+l0V6CJ9oK6lhebXtpY209JXVXaUVS18jso+7cq+zquu0/9mZsAfAc + ai9Im/QOUu0m96Zt1K2B8SyeudM4w8+whQI1NIxadRDUmqP3M+zSGuMZi5C0n07PYWOu1dxn2P5bp5K9 + s3fnKk2NmnPqNR6zZ7tHoU51hmF5lJNrM1fPXEvrk7H2EjqWB6xzzE5DA2zF9fORm3zUl5PPa6TOfOlr + H2ysPFytuu5dhfZ7v2cyW9dnICJsQuebtFG31hpPiYVLPPUHQJyInfuDG1PaqfH0IuLVSsfr+QMgDpfu + 5MvOXuPhRvmGRTROZx2Wp/6wSe8fWvHdkPbyDu0fSGn/sMnwHN6YuOo127WRvbVSh+rSs+f+AEhPYKrE + eGo96m9VzA0Cu6Jl49mz578LaXeu1eI/rQAAAABJRU5ErkJggg== + + + \ No newline at end of file diff --git a/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit.csproj b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit.csproj new file mode 100644 index 0000000..5c7ad5a --- /dev/null +++ b/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit/SDRSharp.FrequencyEdit.csproj @@ -0,0 +1,72 @@ + + + + + Debug + AnyCPU + {A50690CF-7A7A-4B31-9A03-B3A2AF0AF0E0} + Library + SDRSharp.FrequencyEdit + SDRSharp.FrequencyEdit + v4.6 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + + + + + + + + + + + + + + UserControl + + + UserControl + + + + UserControl + + + + + + Resources.resx + True + True + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + \ No newline at end of file diff --git a/SDRSharp.PanView/Properties/AssemblyInfo.cs b/SDRSharp.PanView/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..acedc97 --- /dev/null +++ b/SDRSharp.PanView/Properties/AssemblyInfo.cs @@ -0,0 +1,15 @@ +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Security.Permissions; + +[assembly: CompilationRelaxations(8)] +[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] +[assembly: AssemblyTitle("Panoramic Spectrum Viewer")] +[assembly: AssemblyDescription("Panoramic Spectrum Viewer")] +[assembly: AssemblyProduct("SDR#")] +[assembly: AssemblyCopyright("Copyright © Youssef TOUIL 2012")] +[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] +[assembly: AssemblyVersion("0.0.0.0")] diff --git a/SDRSharp.PanView/SDRSharp.PanView.csproj b/SDRSharp.PanView/SDRSharp.PanView.csproj new file mode 100644 index 0000000..21a325f --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView.csproj @@ -0,0 +1,73 @@ + + + + {040E3622-194B-4FA6-9CBB-1A22BD52A13D} + Debug + AnyCPU + Library + SDRSharp.PanView + .NETFramework + v4.6 + 4 + True + + + AnyCPU + + + bin\Debug\ + true + full + false + + + bin\Release\ + true + pdbonly + true + + + + ..\SDRSharp.Radio\bin\Debug\SDRSharp.Radio.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll + + + C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll + + + + + + + + + + + + Form + + + + + + + + UserControl + + + + UserControl + + + + + GradientDialog.cs + + + + \ No newline at end of file diff --git a/SDRSharp.PanView/SDRSharp.PanView.sln b/SDRSharp.PanView/SDRSharp.PanView.sln new file mode 100644 index 0000000..1e62575 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2015 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDRSharp.PanView", "SDRSharp.PanView.csproj", "{040E3622-194B-4FA6-9CBB-1A22BD52A13D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {040E3622-194B-4FA6-9CBB-1A22BD52A13D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {040E3622-194B-4FA6-9CBB-1A22BD52A13D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {040E3622-194B-4FA6-9CBB-1A22BD52A13D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {040E3622-194B-4FA6-9CBB-1A22BD52A13D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A133AD22-210D-4E51-898D-75EF97AE9732} + EndGlobalSection +EndGlobal diff --git a/SDRSharp.PanView/SDRSharp.PanView/BandType.cs b/SDRSharp.PanView/SDRSharp.PanView/BandType.cs new file mode 100644 index 0000000..66cc6bd --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/BandType.cs @@ -0,0 +1,9 @@ +namespace SDRSharp.PanView +{ + public enum BandType + { + Lower, + Upper, + Center + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/BandwidthEventArgs.cs b/SDRSharp.PanView/SDRSharp.PanView/BandwidthEventArgs.cs new file mode 100644 index 0000000..23adebd --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/BandwidthEventArgs.cs @@ -0,0 +1,38 @@ +using System; + +namespace SDRSharp.PanView +{ + public class BandwidthEventArgs : EventArgs + { + public int Bandwidth + { + get; + set; + } + + public int Offset + { + get; + set; + } + + public bool Cancel + { + get; + set; + } + + public BandType Side + { + get; + private set; + } + + public BandwidthEventArgs(int bandwidth, int offset, BandType side) + { + this.Bandwidth = bandwidth; + this.Offset = offset; + this.Side = side; + } + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/CustomPaintEventArgs.cs b/SDRSharp.PanView/SDRSharp.PanView/CustomPaintEventArgs.cs new file mode 100644 index 0000000..bdd84f9 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/CustomPaintEventArgs.cs @@ -0,0 +1,38 @@ +using System; +using System.Drawing; + +namespace SDRSharp.PanView +{ + public class CustomPaintEventArgs : EventArgs + { + public Graphics Graphics + { + get; + private set; + } + + public Point CursorPosition + { + get; + private set; + } + + public string CustomTitle + { + get; + set; + } + + public bool Cancel + { + get; + set; + } + + public CustomPaintEventArgs(Graphics graphics, Point cursorPosition) + { + this.Graphics = graphics; + this.CursorPosition = cursorPosition; + } + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/CustomPaintEventHandler.cs b/SDRSharp.PanView/SDRSharp.PanView/CustomPaintEventHandler.cs new file mode 100644 index 0000000..1bfb161 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/CustomPaintEventHandler.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.PanView +{ + public delegate void CustomPaintEventHandler(object sender, CustomPaintEventArgs e); +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/FrequencyChangeSource.cs b/SDRSharp.PanView/SDRSharp.PanView/FrequencyChangeSource.cs new file mode 100644 index 0000000..c3d4662 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/FrequencyChangeSource.cs @@ -0,0 +1,9 @@ +namespace SDRSharp.PanView +{ + public enum FrequencyChangeSource + { + Scroll, + Drag, + Click + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/FrequencyEventArgs.cs b/SDRSharp.PanView/SDRSharp.PanView/FrequencyEventArgs.cs new file mode 100644 index 0000000..10560ef --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/FrequencyEventArgs.cs @@ -0,0 +1,31 @@ +using System; + +namespace SDRSharp.PanView +{ + public class FrequencyEventArgs : EventArgs + { + public long Frequency + { + get; + set; + } + + public FrequencyChangeSource Source + { + get; + set; + } + + public bool Cancel + { + get; + set; + } + + public FrequencyEventArgs(long frequency, FrequencyChangeSource source) + { + this.Frequency = frequency; + this.Source = source; + } + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/GradientDialog.cs b/SDRSharp.PanView/SDRSharp.PanView/GradientDialog.cs new file mode 100644 index 0000000..41d3a98 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/GradientDialog.cs @@ -0,0 +1,269 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace SDRSharp.PanView +{ + public class GradientDialog : Form + { + private IContainer components; + + private ListBox colorListBox; + + private Button upButton; + + private Button downButton; + + private PictureBox gradientPictureBox; + + private Button addButton; + + private Button deleteButton; + + private Button cancelButton; + + private Button okButton; + + private ColorDialog colorDialog; + + private GradientDialog() + { + this.InitializeComponent(); + } + + public static ColorBlend GetGradient(ColorBlend originalBlend) + { + using (GradientDialog gradientDialog = new GradientDialog()) + { + gradientDialog.SetColorBlend(originalBlend); + if (gradientDialog.ShowDialog() == DialogResult.OK) + { + return gradientDialog.GetColorBlend(); + } + } + return null; + } + + private ColorBlend GetColorBlend() + { + ColorBlend colorBlend = new ColorBlend(this.colorListBox.Items.Count); + float num = 1f / (float)(colorBlend.Positions.Length - 1); + for (int i = 0; i < colorBlend.Positions.Length; i++) + { + colorBlend.Positions[i] = (float)i * num; + colorBlend.Colors[i] = (Color)this.colorListBox.Items[i]; + } + return colorBlend; + } + + private void SetColorBlend(ColorBlend colorBlend) + { + for (int i = 0; i < colorBlend.Positions.Length; i++) + { + this.colorListBox.Items.Add(colorBlend.Colors[i]); + } + } + + private void colorListBox_DrawItem(object sender, DrawItemEventArgs e) + { + if (e.Index >= 0) + { + Color color = (Color)this.colorListBox.Items[e.Index]; + Rectangle bounds; + if ((e.State & DrawItemState.Selected) == DrawItemState.None) + { + using (SolidBrush solidBrush = new SolidBrush(color)) + { + Graphics graphics = e.Graphics; + SolidBrush brush = solidBrush; + bounds = e.Bounds; + int x = bounds.Left + 1; + bounds = e.Bounds; + int y = bounds.Top + 1; + bounds = e.Bounds; + int width = bounds.Width - 2; + bounds = e.Bounds; + graphics.FillRectangle(brush, x, y, width, bounds.Height - 1); + } + } + else + { + using (HatchBrush hatchBrush = new HatchBrush(HatchStyle.Percent70, color, Color.Gray)) + { + Graphics graphics2 = e.Graphics; + HatchBrush brush2 = hatchBrush; + bounds = e.Bounds; + int x2 = bounds.Left + 1; + bounds = e.Bounds; + int y2 = bounds.Top + 1; + bounds = e.Bounds; + int width2 = bounds.Width - 2; + bounds = e.Bounds; + graphics2.FillRectangle(brush2, x2, y2, width2, bounds.Height - 1); + } + } + } + } + + private void upButton_Click(object sender, EventArgs e) + { + int selectedIndex = this.colorListBox.SelectedIndex; + if (selectedIndex > 0) + { + object item = this.colorListBox.Items[selectedIndex]; + this.colorListBox.Items.RemoveAt(selectedIndex); + this.colorListBox.Items.Insert(selectedIndex - 1, item); + this.colorListBox.SelectedIndex = selectedIndex - 1; + this.gradientPictureBox.Invalidate(); + } + } + + private void downButton_Click(object sender, EventArgs e) + { + int selectedIndex = this.colorListBox.SelectedIndex; + if (selectedIndex >= 0 && selectedIndex < this.colorListBox.Items.Count - 1) + { + object item = this.colorListBox.Items[selectedIndex]; + this.colorListBox.Items.RemoveAt(selectedIndex); + this.colorListBox.Items.Insert(selectedIndex + 1, item); + this.colorListBox.SelectedIndex = selectedIndex + 1; + this.gradientPictureBox.Invalidate(); + } + } + + private void addButton_Click(object sender, EventArgs e) + { + if (this.colorDialog.ShowDialog(this) == DialogResult.OK) + { + this.colorListBox.Items.Add(this.colorDialog.Color); + this.gradientPictureBox.Invalidate(); + } + } + + private void deleteButton_Click(object sender, EventArgs e) + { + int selectedIndex = this.colorListBox.SelectedIndex; + if (selectedIndex >= 0 && this.colorListBox.Items.Count > 2) + { + this.colorListBox.Items.RemoveAt(selectedIndex); + this.gradientPictureBox.Invalidate(); + } + } + + private void gradientPictureBox_Paint(object sender, PaintEventArgs e) + { + ColorBlend colorBlend = this.GetColorBlend(); + using (LinearGradientBrush linearGradientBrush = new LinearGradientBrush(this.gradientPictureBox.ClientRectangle, Color.White, Color.Black, LinearGradientMode.Vertical)) + { + linearGradientBrush.InterpolationColors = colorBlend; + e.Graphics.FillRectangle(linearGradientBrush, e.ClipRectangle); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + { + this.components.Dispose(); + } + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.colorListBox = new ListBox(); + this.upButton = new Button(); + this.downButton = new Button(); + this.gradientPictureBox = new PictureBox(); + this.addButton = new Button(); + this.deleteButton = new Button(); + this.cancelButton = new Button(); + this.okButton = new Button(); + this.colorDialog = new ColorDialog(); + ((ISupportInitialize)this.gradientPictureBox).BeginInit(); + base.SuspendLayout(); + this.colorListBox.DrawMode = DrawMode.OwnerDrawVariable; + this.colorListBox.FormattingEnabled = true; + this.colorListBox.Location = new Point(12, 12); + this.colorListBox.Name = "colorListBox"; + this.colorListBox.Size = new Size(107, 238); + this.colorListBox.TabIndex = 0; + this.colorListBox.DrawItem += this.colorListBox_DrawItem; + this.upButton.Location = new Point(164, 12); + this.upButton.Name = "upButton"; + this.upButton.Size = new Size(75, 23); + this.upButton.TabIndex = 1; + this.upButton.Text = "Up"; + this.upButton.UseVisualStyleBackColor = true; + this.upButton.Click += this.upButton_Click; + this.downButton.Location = new Point(164, 41); + this.downButton.Name = "downButton"; + this.downButton.Size = new Size(75, 23); + this.downButton.TabIndex = 2; + this.downButton.Text = "Down"; + this.downButton.UseVisualStyleBackColor = true; + this.downButton.Click += this.downButton_Click; + this.gradientPictureBox.BorderStyle = BorderStyle.FixedSingle; + this.gradientPictureBox.Location = new Point(125, 12); + this.gradientPictureBox.Name = "gradientPictureBox"; + this.gradientPictureBox.Size = new Size(33, 238); + this.gradientPictureBox.TabIndex = 3; + this.gradientPictureBox.TabStop = false; + this.gradientPictureBox.Paint += this.gradientPictureBox_Paint; + this.addButton.Location = new Point(164, 70); + this.addButton.Name = "addButton"; + this.addButton.Size = new Size(75, 23); + this.addButton.TabIndex = 3; + this.addButton.Text = "Add"; + this.addButton.UseVisualStyleBackColor = true; + this.addButton.Click += this.addButton_Click; + this.deleteButton.Location = new Point(164, 99); + this.deleteButton.Name = "deleteButton"; + this.deleteButton.Size = new Size(75, 23); + this.deleteButton.TabIndex = 4; + this.deleteButton.Text = "Delete"; + this.deleteButton.UseVisualStyleBackColor = true; + this.deleteButton.Click += this.deleteButton_Click; + this.cancelButton.DialogResult = DialogResult.Cancel; + this.cancelButton.Location = new Point(164, 227); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new Size(75, 23); + this.cancelButton.TabIndex = 6; + this.cancelButton.Text = "Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + this.okButton.DialogResult = DialogResult.OK; + this.okButton.Location = new Point(164, 198); + this.okButton.Name = "okButton"; + this.okButton.Size = new Size(75, 23); + this.okButton.TabIndex = 5; + this.okButton.Text = "OK"; + this.okButton.UseVisualStyleBackColor = true; + this.colorDialog.AnyColor = true; + this.colorDialog.FullOpen = true; + base.AcceptButton = this.okButton; + base.AutoScaleDimensions = new SizeF(6f, 13f); + base.AutoScaleMode = AutoScaleMode.Font; + base.CancelButton = this.cancelButton; + base.ClientSize = new Size(251, 262); + base.Controls.Add(this.okButton); + base.Controls.Add(this.cancelButton); + base.Controls.Add(this.deleteButton); + base.Controls.Add(this.addButton); + base.Controls.Add(this.gradientPictureBox); + base.Controls.Add(this.downButton); + base.Controls.Add(this.upButton); + base.Controls.Add(this.colorListBox); + base.FormBorderStyle = FormBorderStyle.FixedDialog; + base.MaximizeBox = false; + base.MinimizeBox = false; + base.Name = "GradientDialog"; + base.ShowInTaskbar = false; + base.StartPosition = FormStartPosition.CenterParent; + this.Text = "Gradient Editor"; + ((ISupportInitialize)this.gradientPictureBox).EndInit(); + base.ResumeLayout(false); + } + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/GradientDialog.resx b/SDRSharp.PanView/SDRSharp.PanView/GradientDialog.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/GradientDialog.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SDRSharp.PanView/SDRSharp.PanView/LineInsertEventArgs.cs b/SDRSharp.PanView/SDRSharp.PanView/LineInsertEventArgs.cs new file mode 100644 index 0000000..5194747 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/LineInsertEventArgs.cs @@ -0,0 +1,25 @@ +using System; + +namespace SDRSharp.PanView +{ + public class LineInsertEventArgs : EventArgs + { + public unsafe int* RgbBuffer + { + get; + private set; + } + + public int Length + { + get; + private set; + } + + public unsafe LineInsertEventArgs(int* rgbBuffer, int length) + { + rgbBuffer = this.RgbBuffer; + this.Length = length; + } + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/LineInsertEventHandler.cs b/SDRSharp.PanView/SDRSharp.PanView/LineInsertEventHandler.cs new file mode 100644 index 0000000..9dff765 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/LineInsertEventHandler.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.PanView +{ + public delegate void LineInsertEventHandler(object sender, LineInsertEventArgs e); +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/ManualBandwidthChangeEventHandler.cs b/SDRSharp.PanView/SDRSharp.PanView/ManualBandwidthChangeEventHandler.cs new file mode 100644 index 0000000..e178224 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/ManualBandwidthChangeEventHandler.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.PanView +{ + public delegate void ManualBandwidthChangeEventHandler(object sender, BandwidthEventArgs e); +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/ManualFrequencyChangeEventHandler.cs b/SDRSharp.PanView/SDRSharp.PanView/ManualFrequencyChangeEventHandler.cs new file mode 100644 index 0000000..30ac633 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/ManualFrequencyChangeEventHandler.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.PanView +{ + public delegate void ManualFrequencyChangeEventHandler(object sender, FrequencyEventArgs e); +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/PeakDetector.cs b/SDRSharp.PanView/SDRSharp.PanView/PeakDetector.cs new file mode 100644 index 0000000..5040db0 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/PeakDetector.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; + +namespace SDRSharp.PanView +{ + public sealed class PeakDetector + { + private const byte Threshold = 20; + + public static void GetPeaks(byte[] buffer, List peaks, int windowSize) + { + windowSize |= 1; + int halfSize = windowSize / 2; + float num = 1f / (float)windowSize; + peaks.Clear(); + for (int i = 0; i < buffer.Length; i++) + { + int num2 = 0; + int max_index = i; + for (int j = 0; j < windowSize; j++) + { + int num3 = i + j - halfSize; + if (num3 < 0) + { + num3 = 0; + } + if (num3 >= buffer.Length) + { + num3 = buffer.Length - 1; + } + if (buffer[num3] >= buffer[max_index]) + { + max_index = num3; + } + num2 += buffer[num3]; + } + float num4 = (float)num2 * num; + if ((float)(int)buffer[max_index] - num4 > 20f && !peaks.Exists(delegate(int x) + { + if (Math.Abs(max_index - x) <= halfSize) + { + return buffer[x] > buffer[max_index]; + } + return false; + })) + { + peaks.RemoveAll((int x) => Math.Abs(max_index - x) <= halfSize); + peaks.Add(max_index); + } + } + } + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/SpectrumAnalyzer.cs b/SDRSharp.PanView/SDRSharp.PanView/SpectrumAnalyzer.cs new file mode 100644 index 0000000..91579f6 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/SpectrumAnalyzer.cs @@ -0,0 +1,1730 @@ +using SDRSharp.Radio; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Windows.Forms; + +namespace SDRSharp.PanView +{ + public class SpectrumAnalyzer : UserControl + { + private const int RefreshInterval = 20; + + private const int GradientAlpha = 180; + + private const int SnrMeterWidth = 10; + + private static readonly Color _spectrumEnvelopeColor = Utils.GetColorSetting("spectrumAnalyzer.envelopeColor", Color.DarkGray); + + private static readonly Color _spectrumFillColor = Utils.GetColorSetting("spectrumAnalyzer.fillColor", Color.DodgerBlue, 100); + + private static readonly bool _useAntiAliasedDisplay = Utils.GetBooleanSetting("useAntiAliasedDisplay", false); + + private float _attack; + + private float _decay; + + private bool _performNeeded; + + private byte[] _scaledSpectrumEnvelope; + + private byte[] _scaledSpectrumMinimum; + + private float[] _smoothedSpectrumEnvelope; + + private float[] _smoothedSpectrumMinimum; + + private float[] _temp; + + private float _peak; + + private float _floor; + + private float _snr; + + private List _peaks = new List(); + + private Bitmap _buffer; + + private Graphics _graphics; + + private long _spectrumWidth; + + private long _centerFrequency; + + private long _displayCenterFrequency; + + private Point[] _envelopePoints; + + private Point[] _minMaxPoints; + + private BandType _bandType; + + private BandType _side; + + private bool _useStepSizeForDisplay; + + private int _filterBandwidth; + + private int _filterOffset; + + private int _stepSize = 1000; + + private float _xIncrement; + + private long _frequency; + + private float _lower; + + private float _upper; + + private int _zoom; + + private float _scale = 1f; + + private int _oldX; + + private float _snappedX; + + private long _trackingFrequency; + + private int _oldFilterBandwidth; + + private int _displayedBandwidth; + + private long _oldFrequency; + + private long _oldCenterFrequency; + + private bool _changingBandwidth; + + private bool _changingFrequency; + + private bool _changingCenterFrequency; + + private bool _useSmoothing; + + private bool _enableFilter = true; + + private bool _enableHotTracking = true; + + private bool _enableFrequencyMarker = true; + + private bool _enableSideFilterResize; + + private bool _enableFilterMove = true; + + private bool _enableSnrBar; + + private bool _hotTrackNeeded; + + private bool _useSnap; + + private bool _markPeaks; + + private float _trackingPower; + + private string _statusText; + + private int _displayRange = 130; + + private int _displayOffset; + + private int _contrast; + + private Point _cursorPosition; + + private string _customTitle; + + private SpectrumStyle _spectrumStyle = SpectrumStyle.StaticGradient; + + private Pen[] _gradientPens = new Pen[256]; + + private Pen[] _snrGradientPens = new Pen[100]; + + private Timer _performTimer; + + private LinearGradientBrush _gradientBrush; + + private ColorBlend _staticGradient = Utils.GetGradientBlend(180, "spectrumAnalyzer.gradient"); + + private ColorBlend _verticalLinesGradient = Utils.GetGradientBlend(255, "waterfall.gradient"); + + private ColorBlend _snrGradient = Utils.GetGradientBlend(255, "spectrumAnalyzer.snrGradient"); + + public int SpectrumWidth + { + get + { + return (int)this._spectrumWidth; + } + set + { + if (this._spectrumWidth != value) + { + this._spectrumWidth = value; + this.ApplyZoom(); + } + } + } + + public int FilterBandwidth + { + get + { + return this._filterBandwidth; + } + set + { + if (this._filterBandwidth != value) + { + this._filterBandwidth = value; + this._performNeeded = true; + } + } + } + + public int FilterOffset + { + get + { + return this._filterOffset; + } + set + { + if (this._filterOffset != value) + { + this._filterOffset = value; + this._performNeeded = true; + } + } + } + + public BandType BandType + { + get + { + return this._bandType; + } + set + { + if (this._bandType != value) + { + this._bandType = value; + this._performNeeded = true; + } + } + } + + public bool UseStepSizeForDisplay + { + get + { + return this._useStepSizeForDisplay; + } + set + { + if (this._useStepSizeForDisplay != value) + { + this._useStepSizeForDisplay = value; + this._performNeeded = true; + } + } + } + + public long Frequency + { + get + { + return this._frequency; + } + set + { + if (this._frequency != value) + { + this._frequency = value; + this._performNeeded = true; + } + } + } + + public long CenterFrequency + { + get + { + return this._centerFrequency; + } + set + { + if (this._centerFrequency != value) + { + this._displayCenterFrequency += value - this._centerFrequency; + this._centerFrequency = value; + this._performNeeded = true; + } + } + } + + public int DisplayedBandwidth + { + get + { + return this._displayedBandwidth; + } + } + + public long DisplayCenterFrequency + { + get + { + return this._displayCenterFrequency; + } + } + + public int DisplayRange + { + get + { + return this._displayRange; + } + set + { + if (this._displayRange != value) + { + this._displayRange = value; + this._performNeeded = true; + } + } + } + + public int DisplayOffset + { + get + { + return this._displayOffset; + } + set + { + if (this._displayOffset != value) + { + this._displayOffset = value; + this._performNeeded = true; + } + } + } + + public int Zoom + { + get + { + return this._zoom; + } + set + { + if (this._zoom != value) + { + this._zoom = value; + this.ApplyZoom(); + } + } + } + + public bool UseSmoothing + { + get + { + return this._useSmoothing; + } + set + { + this._useSmoothing = value; + } + } + + public bool EnableFilter + { + get + { + return this._enableFilter; + } + set + { + this._enableFilter = value; + this._performNeeded = true; + } + } + + public bool EnableSNR + { + get + { + return this._enableSnrBar; + } + set + { + this._enableSnrBar = value; + this._performNeeded = true; + } + } + + public float VisualSNR + { + get + { + return this._snr; + } + } + + public bool EnableHotTracking + { + get + { + return this._enableHotTracking; + } + set + { + this._enableHotTracking = value; + this._performNeeded = true; + } + } + + public bool EnableFrequencyMarker + { + get + { + return this._enableFrequencyMarker; + } + set + { + this._enableFrequencyMarker = value; + this._performNeeded = true; + } + } + + public bool EnableSideFilterResize + { + get + { + return this._enableSideFilterResize; + } + set + { + this._enableSideFilterResize = value; + this._performNeeded = true; + } + } + + public bool EnableFilterMove + { + get + { + return this._enableFilterMove; + } + set + { + this._enableFilterMove = value; + this._performNeeded = true; + } + } + + public string StatusText + { + get + { + return this._statusText; + } + set + { + if (this._statusText != value) + { + this._statusText = value; + this._performNeeded = true; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ColorBlend GradientColorBlend + { + get + { + return this._staticGradient; + } + set + { + this._staticGradient = new ColorBlend(value.Colors.Length); + for (int i = 0; i < value.Colors.Length; i++) + { + this._staticGradient.Colors[i] = Color.FromArgb(180, value.Colors[i]); + this._staticGradient.Positions[i] = value.Positions[i]; + } + this._gradientBrush.Dispose(); + this._gradientBrush = new LinearGradientBrush(new Rectangle(30, 30, this._buffer.Width - 30, this._buffer.Height - 30), Color.White, Color.Black, LinearGradientMode.Vertical); + this._gradientBrush.InterpolationColors = this._staticGradient; + this._performNeeded = true; + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ColorBlend SNRGradient + { + get + { + return this._snrGradient; + } + set + { + if (this._snrGradient != value) + { + this._snrGradient = value; + this.BuildSNRGradientVector(); + this._performNeeded = true; + } + } + } + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ColorBlend VerticalLinesGradient + { + get + { + return this._verticalLinesGradient; + } + set + { + if (this._verticalLinesGradient != value) + { + this._verticalLinesGradient = value; + this.BuildDynamicGradientVector(); + this._performNeeded = true; + } + } + } + + public SpectrumStyle SpectrumStyle + { + get + { + return this._spectrumStyle; + } + set + { + if (this._spectrumStyle != value) + { + this._spectrumStyle = value; + this._performNeeded = true; + } + } + } + + public int Contrast + { + get + { + return this._contrast; + } + set + { + this._contrast = value; + } + } + + public float Attack + { + get + { + return this._attack; + } + set + { + this._attack = value; + } + } + + public float Decay + { + get + { + return this._decay; + } + set + { + this._decay = value; + } + } + + public int StepSize + { + get + { + return this._stepSize; + } + set + { + if (this._stepSize != value) + { + this._stepSize = value; + this._performNeeded = true; + } + } + } + + public bool UseSnap + { + get + { + return this._useSnap; + } + set + { + this._useSnap = value; + } + } + + public bool MarkPeaks + { + get + { + return this._markPeaks; + } + set + { + this._markPeaks = value; + } + } + + public event ManualFrequencyChangeEventHandler FrequencyChanged; + + public event ManualFrequencyChangeEventHandler CenterFrequencyChanged; + + public event ManualBandwidthChangeEventHandler BandwidthChanged; + + public event CustomPaintEventHandler CustomPaint; + + public event CustomPaintEventHandler BackgroundCustomPaint; + + public SpectrumAnalyzer() + { + this._performTimer = new Timer(); + this._performTimer.Enabled = true; + this._performTimer.Interval = 20; + this._performTimer.Tick += this.performTimer_Tick; + Rectangle clientRectangle = base.ClientRectangle; + int width = clientRectangle.Width; + clientRectangle = base.ClientRectangle; + this._buffer = new Bitmap(width, clientRectangle.Height, PixelFormat.Format32bppPArgb); + this._graphics = Graphics.FromImage(this._buffer); + this._gradientBrush = new LinearGradientBrush(new Rectangle(30, 30, this._buffer.Width - 30, this._buffer.Height - 30), Color.White, Color.Black, LinearGradientMode.Vertical); + this._gradientBrush.InterpolationColors = this._staticGradient; + int num = this._buffer.Width - 60; + this._smoothedSpectrumEnvelope = new float[num]; + this._smoothedSpectrumMinimum = new float[num]; + this._scaledSpectrumEnvelope = new byte[num]; + this._scaledSpectrumMinimum = new byte[num]; + this._envelopePoints = new Point[num + 2]; + this._minMaxPoints = new Point[num * 2 + 2]; + this._temp = new float[num]; + for (int i = 0; i < this._smoothedSpectrumEnvelope.Length; i++) + { + this._smoothedSpectrumEnvelope[i] = -250f; + this._smoothedSpectrumMinimum[i] = -250f; + } + base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + base.SetStyle(ControlStyles.DoubleBuffer, true); + base.SetStyle(ControlStyles.UserPaint, true); + base.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + base.UpdateStyles(); + this.BuildDynamicGradientVector(); + this.BuildSNRGradientVector(); + } + + ~SpectrumAnalyzer() + { + this._buffer.Dispose(); + this._graphics.Dispose(); + this._gradientBrush.Dispose(); + } + + private void BuildDynamicGradientVector() + { + using (Bitmap bitmap = new Bitmap(1, this._gradientPens.Length)) + { + using (Graphics graphics = Graphics.FromImage(bitmap)) + { + using (LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new Rectangle(0, 0, 1, this._gradientPens.Length), Color.White, Color.Black, LinearGradientMode.Vertical)) + { + linearGradientBrush.InterpolationColors = this._verticalLinesGradient; + Pen pen = new Pen(linearGradientBrush); + graphics.DrawLine(pen, 0, 0, 0, this._gradientPens.Length - 1); + for (int i = 0; i < this._gradientPens.Length; i++) + { + this._gradientPens[this._gradientPens.Length - 1 - i] = new Pen(Color.FromArgb(bitmap.GetPixel(0, i).ToArgb())); + } + } + } + } + } + + private void BuildSNRGradientVector() + { + using (Bitmap bitmap = new Bitmap(1, this._snrGradientPens.Length)) + { + using (Graphics graphics = Graphics.FromImage(bitmap)) + { + using (LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new Rectangle(0, 0, 1, this._snrGradientPens.Length), Color.Black, Color.White, LinearGradientMode.Vertical)) + { + linearGradientBrush.InterpolationColors = this._snrGradient; + Pen pen = new Pen(linearGradientBrush); + graphics.DrawLine(pen, 0, 0, 0, this._snrGradientPens.Length - 1); + for (int i = 0; i < this._snrGradientPens.Length; i++) + { + this._snrGradientPens[this._snrGradientPens.Length - 1 - i] = new Pen(Color.FromArgb(bitmap.GetPixel(0, i).ToArgb()), 10f); + } + } + } + } + } + + private void ApplyZoom() + { + this._scale = (float)Math.Pow(10.0, (double)((float)this._zoom * 4f / 100f)); + if (this._spectrumWidth > 0) + { + this._displayCenterFrequency = this.GetDisplayCenterFrequency(); + this._xIncrement = this._scale * (float)(this._buffer.Width - 60) / (float)this._spectrumWidth; + this._displayedBandwidth = (int)((float)this._spectrumWidth / this._scale); + this._performNeeded = true; + } + } + + public void CenterZoom() + { + this._displayCenterFrequency = this.GetDisplayCenterFrequency(); + this._performNeeded = true; + } + + private long GetDisplayCenterFrequency() + { + long num = this._frequency + this._filterOffset; + switch (this._bandType) + { + case BandType.Lower: + num = (long)((float)num - (float)this._filterBandwidth * 0.5f); + break; + case BandType.Upper: + num = (long)((float)num + (float)this._filterBandwidth * 0.5f); + break; + } + long num2 = (long)((double)((float)this._centerFrequency - (float)this._spectrumWidth * 0.5f) - ((double)num - (double)this._spectrumWidth * 0.5 / (double)this._scale)); + if (num2 > 0) + { + num += num2; + } + long num3 = (long)((double)((float)num + (float)this._spectrumWidth * 0.5f / this._scale) - ((double)this._centerFrequency + (double)this._spectrumWidth * 0.5)); + if (num3 > 0) + { + num -= num3; + } + return num; + } + + private void performTimer_Tick(object sender, EventArgs e) + { + this.Perform(false); + } + + private void Perform(bool force) + { + if (this._performNeeded | force) + { + this.DrawLayers(); + base.Invalidate(); + this._performNeeded = false; + } + } + + public void Perform() + { + this._performNeeded = true; + } + + private void DrawCursor(bool drawFilter = true, bool drawFrequencyMarker = true, bool drawPeaks = true, bool drawHotTrackingLine = true, bool drawHotTrackingText = true) + { + this._lower = 0f; + int num = (int)Math.Max((float)this._filterBandwidth * this._xIncrement, 2f) | 1; + float num2 = (float)this._buffer.Width * 0.5f + (float)(this._frequency - this._displayCenterFrequency) * this._xIncrement; + switch (this._bandType) + { + case BandType.Upper: + this._lower = num2; + break; + case BandType.Lower: + this._lower = num2 - (float)num; + break; + case BandType.Center: + this._lower = num2 - (float)num * 0.5f; + break; + } + this._lower += (float)this._filterOffset * this._xIncrement; + this._upper = this._lower + (float)num; + using (SolidBrush brush = new SolidBrush(Color.FromArgb(80, Color.DarkGray))) + { + using (SolidBrush brush2 = new SolidBrush(Color.FromArgb(200, 50, 50, 50))) + { + using (Pen pen5 = new Pen(Color.FromArgb(200, Color.Gray))) + { + using (Pen pen3 = new Pen(Color.DodgerBlue)) + { + using (Pen pen2 = new Pen(Color.LimeGreen)) + { + using (Pen pen = new Pen(Color.Red)) + { + using (FontFamily family = new FontFamily("Verdana")) + { + using (GraphicsPath graphicsPath = new GraphicsPath()) + { + using (Pen pen4 = new Pen(Color.Black)) + { + if (drawFilter && this._enableFilter && num < this._buffer.Width - 60) + { + float num3 = this._lower; + float num4 = (float)num; + if (this._lower < 30f) + { + num3 = 31f; + num4 -= num3 - this._lower; + } + if (this._upper > (float)(this._buffer.Width - 30)) + { + num4 -= this._upper - (float)(this._buffer.Width - 30); + } + this._graphics.FillRectangle(brush, num3, 30f, num4, (float)(this._buffer.Height - 60)); + } + if (drawFrequencyMarker && this._enableFrequencyMarker && num2 > 30f && num2 < (float)(this._buffer.Width - 30)) + { + pen.Width = 1f; + this._graphics.DrawLine(pen, num2, 30f, num2, (float)(this._buffer.Height - 30)); + } + if (drawPeaks && this._markPeaks && this._spectrumWidth > 0) + { + int val = num; + val = Math.Max(val, 10); + val = Math.Min(val, this._scaledSpectrumEnvelope.Length); + PeakDetector.GetPeaks(this._scaledSpectrumEnvelope, this._peaks, val); + float num5 = (float)(this._buffer.Height - 60) / 255f; + foreach (int peak in this._peaks) + { + int num6 = (int)((float)(this._buffer.Height - 30) - (float)(int)this._scaledSpectrumEnvelope[peak] * num5); + int num7 = peak + 30; + this._graphics.DrawEllipse(Pens.Yellow, num7 - 5, num6 - 5, 10, 10); + } + } + if (this._enableHotTracking && this._hotTrackNeeded && this._cursorPosition.X >= 30 && this._cursorPosition.X <= this._buffer.Width - 30 && this._cursorPosition.Y >= 30 && this._cursorPosition.Y <= this._buffer.Height - 30) + { + if (drawHotTrackingLine && this.Cursor != Cursors.SizeWE && (this._snappedX < this._lower || this._snappedX > this._upper) && this._scaledSpectrumEnvelope != null && !this._changingFrequency && !this._changingCenterFrequency && !this._changingBandwidth) + { + pen2.DashStyle = DashStyle.Dash; + this._graphics.DrawLine(pen3, this._snappedX, 30f, this._snappedX, (float)(this._buffer.Height - 30)); + int num8 = num / 2; + switch (this._bandType) + { + case BandType.Center: + this._graphics.DrawLine(pen2, this._snappedX - (float)num8, 30f, this._snappedX - (float)num8, (float)(this._buffer.Height - 30)); + this._graphics.DrawLine(pen2, this._snappedX + (float)num8, 30f, this._snappedX + (float)num8, (float)(this._buffer.Height - 30)); + break; + case BandType.Lower: + this._graphics.DrawLine(pen2, this._snappedX - (float)num, 30f, this._snappedX - (float)num, (float)(this._buffer.Height - 30)); + break; + case BandType.Upper: + this._graphics.DrawLine(pen2, this._snappedX + (float)num, 30f, this._snappedX + (float)num, (float)(this._buffer.Height - 30)); + break; + } + } + if (drawHotTrackingText) + { + string text = string.Empty; + if (this._changingBandwidth || this.Cursor == Cursors.SizeWE) + { + text = "Bandwidth: " + SpectrumAnalyzer.GetFrequencyDisplay(this._filterBandwidth); + } + else if (!this._changingCenterFrequency) + { + if (!string.IsNullOrEmpty(this._customTitle)) + { + text = this._customTitle; + } + if (this._changingFrequency || ((float)this._cursorPosition.X >= this._lower && (float)this._cursorPosition.X <= this._upper)) + { + if (!string.IsNullOrEmpty(text)) + { + text = text + Environment.NewLine + Environment.NewLine; + } + text += string.Format("VFO:\t{0}{1}Peak:\t{2:0.0}dBFS{3}Floor:\t{4:0.0}dBFS{5}SNR:\t{6:0.0}dB", SpectrumAnalyzer.GetFrequencyDisplay(this._frequency), Environment.NewLine, this._peak, Environment.NewLine, this._floor, Environment.NewLine, this._snr); + } + if (string.IsNullOrEmpty(text)) + { + text = string.Format("{0}\r\n{1:0.##}dBFS", SpectrumAnalyzer.GetFrequencyDisplay(this._trackingFrequency), this._trackingPower); + } + } + graphicsPath.AddString(text, family, 0, 16f, Point.Empty, StringFormat.GenericTypographic); + RectangleF bounds = graphicsPath.GetBounds(); + Cursor current2 = Cursor.Current; + float val2 = (float)this._cursorPosition.X + 30f; + float val3 = (float)this._cursorPosition.Y + ((current2 == (Cursor)null) ? 32f : ((float)current2.Size.Height)) - 8f; + val2 = Math.Min(val2, (float)this._buffer.Width - bounds.Width - 30f - 20f); + val3 = Math.Min(val3, (float)this._buffer.Height - bounds.Height - 30f - 20f); + graphicsPath.Reset(); + graphicsPath.AddString(text, family, 0, 16f, new Point((int)val2, (int)val3), StringFormat.GenericTypographic); + SmoothingMode smoothingMode = this._graphics.SmoothingMode; + InterpolationMode interpolationMode = this._graphics.InterpolationMode; + this._graphics.SmoothingMode = SmoothingMode.AntiAlias; + this._graphics.InterpolationMode = InterpolationMode.HighQualityBilinear; + pen4.Width = 2f; + RectangleF bounds2 = graphicsPath.GetBounds(); + bounds2.X -= 10f; + bounds2.Y -= 10f; + bounds2.Width += 20f; + bounds2.Height += 20f; + this._graphics.FillRoundedRectangle(brush2, bounds2, 6); + this._graphics.DrawRoundedRectangle(pen5, bounds2, 6); + this._graphics.DrawPath(pen4, graphicsPath); + this._graphics.FillPath(Brushes.White, graphicsPath); + this._graphics.SmoothingMode = smoothingMode; + this._graphics.InterpolationMode = interpolationMode; + } + } + } + } + } + } + } + } + } + } + } + } + + private void ProcessVfo() + { + int num = Math.Max((int)this._lower - 30, 0); + int num2 = Math.Min((int)this._upper - 30, this._smoothedSpectrumEnvelope.Length - 1); + float num3 = -600f; + for (int i = num; i <= num2; i++) + { + if (this._smoothedSpectrumEnvelope[i] > num3) + { + num3 = this._smoothedSpectrumEnvelope[i]; + } + } + float num4 = (num3 > this._peak) ? 0.3f : 0.01f; + this._peak += num4 * (num3 - this._peak); + float val = (this._upper - this._lower) * 0.25f; + val = Math.Min(5f, val); + float num5 = 0f; + float val2 = 0f; + float val3 = 0f; + num = Math.Max((int)(this._lower - val) - 30, 0); + num2 = Math.Min((int)this._lower - 30, this._smoothedSpectrumEnvelope.Length - 1); + if (num2 > num) + { + for (int j = num; j <= num2; j++) + { + num5 += this._smoothedSpectrumEnvelope[j]; + } + val2 = num5 / (float)(num2 - num + 1); + } + num = Math.Max((int)this._upper - 30, 0); + num2 = Math.Min((int)(this._upper + val) - 30, this._smoothedSpectrumEnvelope.Length - 1); + if (num2 > num) + { + num5 = 0f; + for (int k = num; k <= num2; k++) + { + num5 += this._smoothedSpectrumEnvelope[k]; + } + val3 = num5 / (float)(num2 - num + 1); + } + float num6 = Math.Min(val2, val3); + if (num6 == 0f) + { + num = Math.Max((int)this._lower - 30, 0); + num2 = Math.Min((int)this._upper - 30, this._smoothedSpectrumEnvelope.Length - 1); + float num7 = 600f; + for (int l = num; l <= num2; l++) + { + if (this._smoothedSpectrumEnvelope[l] < num7) + { + num7 = this._smoothedSpectrumEnvelope[l]; + } + } + num6 = num7; + } + this._floor += 0.03f * (num6 - this._floor); + this._snr = this._peak - this._floor; + } + + public unsafe void Render(float* powerSpectrum, int length) + { + float offset = (float)(this._displayCenterFrequency - this._centerFrequency) / (float)this._spectrumWidth; + this.ExtractSpectrum(powerSpectrum, length, offset, this._scale, this._useSmoothing); + this._performNeeded = true; + } + + private unsafe void ExtractSpectrum(float* powerSpectrum, int length, float offset, float scale, bool useSmoothing) + { + int num = this._displayOffset / 10 * 10; + int num2 = this._displayRange / 10 * 10; + float[] temp = this._temp; + fixed (float* ptr = temp) + { + float[] smoothedSpectrumEnvelope = this._smoothedSpectrumEnvelope; + fixed (float* ptr2 = smoothedSpectrumEnvelope) + { + byte[] scaledSpectrumEnvelope = this._scaledSpectrumEnvelope; + fixed (byte* dest = scaledSpectrumEnvelope) + { + byte[] scaledSpectrumMinimum = this._scaledSpectrumMinimum; + fixed (byte* ptr3 = scaledSpectrumMinimum) + { + Fourier.SmoothMaxCopy(powerSpectrum, ptr, length, this._smoothedSpectrumEnvelope.Length, scale, offset); + if (useSmoothing) + { + for (int i = 0; i < this._temp.Length; i++) + { + float num3 = (ptr2[i] < ptr[i]) ? this.Attack : this.Decay; + ptr2[i] = ptr2[i] * (1f - num3) + ptr[i] * num3; + } + } + else + { + Utils.Memcpy(ptr2, ptr, this._smoothedSpectrumEnvelope.Length * 4); + } + Fourier.ScaleFFT(ptr2, dest, this._smoothedSpectrumEnvelope.Length, (float)(num - num2), (float)num); + } + } + } + } + this.ProcessVfo(); + if (this._spectrumStyle == SpectrumStyle.MinMax) + { + temp = this._temp; + fixed (float* ptr4 = temp) + { + float[] smoothedSpectrumEnvelope = this._smoothedSpectrumMinimum; + fixed (float* ptr5 = smoothedSpectrumEnvelope) + { + byte[] scaledSpectrumEnvelope = this._scaledSpectrumMinimum; + fixed (byte* dest2 = scaledSpectrumEnvelope) + { + Fourier.SmoothMinCopy(powerSpectrum, ptr4, length, this._smoothedSpectrumMinimum.Length, scale, offset); + if (useSmoothing) + { + for (int j = 0; j < this._temp.Length; j++) + { + float num4 = (ptr5[j] < ptr4[j]) ? this.Attack : this.Decay; + ptr5[j] = ptr5[j] * (1f - num4) + ptr4[j] * num4; + } + } + else + { + Utils.Memcpy(ptr5, ptr4, this._smoothedSpectrumMinimum.Length * 4); + } + Fourier.ScaleFFT(ptr5, dest2, this._smoothedSpectrumMinimum.Length, (float)(num - num2), (float)num); + } + } + } + } + } + + private void DrawStatusText() + { + using (Font font = new Font("Lucida Console", 9f)) + { + if (!string.IsNullOrEmpty(this._statusText)) + { + this._graphics.DrawString(this._statusText, font, Brushes.White, 30f, 10f); + } + } + } + + private void DrawGrid() + { + if (this._displayRange > 0) + { + using (SolidBrush brush = new SolidBrush(Color.Silver)) + { + using (Pen pen = new Pen(Color.FromArgb(80, 80, 80))) + { + using (Font font = new Font("Arial", 8f)) + { + using (new Pen(Color.DarkGray)) + { + int num = (int)this._graphics.MeasureString("100", font).Height; + int num2 = this._buffer.Height - 60; + int num3 = 1; + int num4 = this._displayRange / num3; + if (num2 < num * num4) + { + num3 = 5; + num4 = this._displayRange / num3; + } + if (num2 < num * num4) + { + num3 = 10; + num4 = this._displayRange / num3; + } + float num5 = (float)(this._buffer.Height - 60) / (float)num4; + for (int i = 1; i <= num4; i++) + { + this._graphics.DrawLine(pen, 30, (int)((float)(this._buffer.Height - 30) - (float)i * num5), this._buffer.Width - 30, (int)((float)(this._buffer.Height - 30) - (float)i * num5)); + } + int num6 = this._displayOffset / 10 * 10; + for (int j = 0; j <= num4; j++) + { + string text = (num6 - (num4 - j) * num3).ToString(); + SizeF sizeF = this._graphics.MeasureString(text, font); + float width = sizeF.Width; + float height = sizeF.Height; + this._graphics.DrawString(text, font, brush, 30f - width, (float)(this._buffer.Height - 30) - (float)j * num5 - height * 0.5f); + } + } + } + } + } + } + } + + private void DrawFrequencyMarkers() + { + if (this._spectrumWidth > 0) + { + using (SolidBrush brush = new SolidBrush(Color.Silver)) + { + using (Pen pen = new Pen(Color.FromArgb(80, 80, 80))) + { + using (Font font = new Font("Arial", 8f)) + { + using (Pen pen2 = new Pen(Color.DarkGray)) + { + string frequencyDisplay = Utils.GetFrequencyDisplay((long)((float)this._centerFrequency + (float)this._spectrumWidth * 0.5f), false); + float num = this._graphics.MeasureString(frequencyDisplay, font).Width + 30f; + long num2 = (long)((float)(this._buffer.Width - 60) / num); + long num3; + long num4; + if (this._useStepSizeForDisplay) + { + num3 = 0L; + do + { + num3 += this._stepSize; + num4 = (int)((float)this._spectrumWidth / this._scale) / num3; + } + while (num4 > num2); + } + else + { + int num5 = 2; + num3 = 10L; + do + { + num5 = ((num5 == 2) ? 5 : 2); + num3 *= num5; + num4 = (int)((float)this._spectrumWidth / this._scale) / num3; + } + while (num4 > num2); + if (num4 > 0) + { + if (num4 * 5 < num2) + { + num4 *= 5; + num3 /= 5; + } + if (num4 * 2 < num2) + { + num3 /= 2; + } + } + } + num4 = num2 * 2; + long num6 = this._displayCenterFrequency / num3 * num3; + for (long num7 = -num4 / 2; num7 < num4 / 2; num7++) + { + long frequency = num6 + num3 * num7; + float num8 = this.FrequencyToPoint(frequency); + if (num8 >= 29f && num8 <= (float)(this._buffer.Width - 30 + 1)) + { + this._graphics.DrawLine(pen, num8, 30f, num8, (float)(this._buffer.Height - 30)); + this._graphics.DrawLine(pen2, num8, (float)(this._buffer.Height - 30), num8, (float)(this._buffer.Height - 30 + 5)); + string frequencyDisplay2 = Utils.GetFrequencyDisplay(frequency, false); + float width = this._graphics.MeasureString(frequencyDisplay2, font).Width; + num8 -= width * 0.5f; + this._graphics.DrawString(frequencyDisplay2, font, brush, num8, (float)(this._buffer.Height - 30) + 8f); + } + } + } + } + } + } + } + } + + private void DrawAxis() + { + using (Pen pen = new Pen(Color.DarkGray)) + { + this._graphics.DrawLine(pen, 30, 30, 30, this._buffer.Height - 30); + this._graphics.DrawLine(pen, 30, this._buffer.Height - 30, this._buffer.Width - 30, this._buffer.Height - 30); + } + } + + public static string GetFrequencyDisplay(long frequency) + { + return Utils.GetFrequencyDisplay(frequency, true); + } + + public static void ConfigureGraphics(Graphics graphics, bool useAntiAliasedDisplay) + { + if (useAntiAliasedDisplay) + { + graphics.CompositingMode = CompositingMode.SourceOver; + graphics.CompositingQuality = CompositingQuality.AssumeLinear; + graphics.SmoothingMode = SmoothingMode.AntiAlias; + graphics.PixelOffsetMode = PixelOffsetMode.Default; + graphics.InterpolationMode = InterpolationMode.HighQualityBilinear; + } + else + { + graphics.CompositingMode = CompositingMode.SourceOver; + graphics.CompositingQuality = CompositingQuality.HighSpeed; + graphics.SmoothingMode = SmoothingMode.None; + graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed; + graphics.InterpolationMode = InterpolationMode.Low; + } + } + + public void ResetSpectrum() + { + for (int i = 0; i < this._scaledSpectrumEnvelope.Length; i++) + { + this._scaledSpectrumEnvelope[i] = 0; + this._scaledSpectrumMinimum[i] = 0; + } + this._peak = 0f; + this._floor = 0f; + this._snr = 0f; + this._performNeeded = true; + } + + private void DrawLayers() + { + if (this._buffer.Width > 30 && this._buffer.Height > 30) + { + this._graphics.Clear(Color.Black); + this.DrawStatusText(); + this.DrawSNR(); + this.OnBackgroundCustomPaint(new CustomPaintEventArgs(this._graphics, this._cursorPosition)); + this.DrawGrid(); + this.DrawFrequencyMarkers(); + this.DrawSpectrum(); + this.DrawAxis(); + } + } + + private void DrawSpectrum() + { + if (this._scaledSpectrumEnvelope != null && this._scaledSpectrumEnvelope.Length != 0) + { + float num = (float)(this._buffer.Width - 60) / (float)this._scaledSpectrumEnvelope.Length; + float num2 = (float)(this._buffer.Height - 60) / 255f; + if (this._spectrumStyle == SpectrumStyle.Dots) + { + this.DrawCursor(true, true, true, false, false); + for (int i = 0; i < this._scaledSpectrumEnvelope.Length; i++) + { + Math.Min(Math.Max(0, this._scaledSpectrumEnvelope[i] + this._contrast * 2), 255); + int x = (int)(30f + (float)i * num); + int y = (int)((float)(this._buffer.Height - 30) - (float)(int)this._scaledSpectrumEnvelope[i] * num2); + this._buffer.SetPixel(x, y, SpectrumAnalyzer._spectrumEnvelopeColor); + } + this.OnCustomPaint(new CustomPaintEventArgs(this._graphics, this._cursorPosition)); + this.DrawCursor(false, false, false, true, true); + } + else if (this._spectrumStyle == SpectrumStyle.DynamicGradient) + { + for (int j = 0; j < this._scaledSpectrumEnvelope.Length; j++) + { + int num3 = Math.Min(Math.Max(0, this._scaledSpectrumEnvelope[j] + this._contrast * 2), 255); + int num4 = (int)(30f + (float)j * num); + int num5 = (int)((float)(this._buffer.Height - 30) - (float)(int)this._scaledSpectrumEnvelope[j] * num2); + this._envelopePoints[j + 1].X = num4; + this._envelopePoints[j + 1].Y = num5; + this._graphics.DrawLine(this._gradientPens[num3], num4, num5, num4, this._buffer.Height - 30); + } + this.DrawCursor(true, true, true, false, false); + this._envelopePoints[0] = this._envelopePoints[1]; + this._envelopePoints[this._envelopePoints.Length - 1] = this._envelopePoints[this._envelopePoints.Length - 2]; + SpectrumAnalyzer.ConfigureGraphics(this._graphics, SpectrumAnalyzer._useAntiAliasedDisplay); + this._graphics.DrawLines(Pens.Gray, this._envelopePoints); + SpectrumAnalyzer.ConfigureGraphics(this._graphics, false); + this.OnCustomPaint(new CustomPaintEventArgs(this._graphics, this._cursorPosition)); + this.DrawCursor(false, false, false, true, true); + } + else if (this._spectrumStyle == SpectrumStyle.MinMax) + { + for (int k = 0; k < this._scaledSpectrumEnvelope.Length; k++) + { + byte b = this._scaledSpectrumMinimum[k]; + byte b2 = this._scaledSpectrumEnvelope[k]; + int x2 = (int)(30f + (float)k * num); + int y2 = (int)((float)(this._buffer.Height - 30) - (float)(int)b * num2); + int y3 = (int)((float)(this._buffer.Height - 30) - (float)(int)b2 * num2); + this._minMaxPoints[k * 2 + 1].X = x2; + this._minMaxPoints[k * 2 + 1].Y = y2; + this._minMaxPoints[k * 2 + 2].X = x2; + this._minMaxPoints[k * 2 + 2].Y = y3; + } + this.DrawCursor(true, true, true, false, false); + this._minMaxPoints[0] = this._minMaxPoints[1]; + this._minMaxPoints[this._minMaxPoints.Length - 1] = this._minMaxPoints[this._minMaxPoints.Length - 2]; + SpectrumAnalyzer.ConfigureGraphics(this._graphics, SpectrumAnalyzer._useAntiAliasedDisplay); + this._graphics.DrawLines(new Pen(SpectrumAnalyzer._spectrumEnvelopeColor), this._minMaxPoints); + SpectrumAnalyzer.ConfigureGraphics(this._graphics, false); + this.OnCustomPaint(new CustomPaintEventArgs(this._graphics, this._cursorPosition)); + this.DrawCursor(false, false, false, true, true); + } + else + { + for (int l = 0; l < this._scaledSpectrumEnvelope.Length; l++) + { + byte b3 = this._scaledSpectrumEnvelope[l]; + int x3 = (int)(30f + (float)l * num); + int y4 = (int)((float)(this._buffer.Height - 30) - (float)(int)b3 * num2); + this._envelopePoints[l + 1].X = x3; + this._envelopePoints[l + 1].Y = y4; + } + if (this._spectrumStyle == SpectrumStyle.StaticGradient) + { + this._envelopePoints[0].X = 30; + this._envelopePoints[0].Y = this._buffer.Height - 30 + 1; + this._envelopePoints[this._envelopePoints.Length - 1].X = this._buffer.Width - 30; + this._envelopePoints[this._envelopePoints.Length - 1].Y = this._buffer.Height - 30 + 1; + this._graphics.FillPolygon(this._gradientBrush, this._envelopePoints); + } + else if (this._spectrumStyle == SpectrumStyle.SolidFill) + { + this._envelopePoints[0].X = 30; + this._envelopePoints[0].Y = this._buffer.Height - 30 + 1; + this._envelopePoints[this._envelopePoints.Length - 1].X = this._buffer.Width - 30; + this._envelopePoints[this._envelopePoints.Length - 1].Y = this._buffer.Height - 30 + 1; + this._graphics.FillPolygon(new SolidBrush(SpectrumAnalyzer._spectrumFillColor), this._envelopePoints); + } + this.DrawCursor(true, true, true, false, false); + this._envelopePoints[0] = this._envelopePoints[1]; + this._envelopePoints[this._envelopePoints.Length - 1] = this._envelopePoints[this._envelopePoints.Length - 2]; + SpectrumAnalyzer.ConfigureGraphics(this._graphics, SpectrumAnalyzer._useAntiAliasedDisplay); + this._graphics.DrawLines(new Pen(SpectrumAnalyzer._spectrumEnvelopeColor), this._envelopePoints); + SpectrumAnalyzer.ConfigureGraphics(this._graphics, false); + this.OnCustomPaint(new CustomPaintEventArgs(this._graphics, this._cursorPosition)); + this.DrawCursor(false, false, false, true, true); + } + } + } + + private void DrawSNR() + { + if (this._enableSnrBar) + { + int val = (int)(this._snr / 100f * (float)this._snrGradientPens.Length); + val = Math.Max(0, val); + val = Math.Min(this._snrGradientPens.Length - 1, val); + float val2 = (float)(this._buffer.Height - 60) * this._snr / 100f; + val2 = Math.Max(0f, val2); + val2 = Math.Min((float)(this._buffer.Height - 30), val2); + this._graphics.DrawLine(new Pen(Color.FromArgb(50, 50, 50), 14f), (float)this._buffer.Width - 15f, 30f, (float)this._buffer.Width - 15f, (float)(this._buffer.Height - 30 + 1)); + this._graphics.DrawLine(this._snrGradientPens[val], (float)this._buffer.Width - 15f, (float)(this._buffer.Height - 30) - val2, (float)this._buffer.Width - 15f, (float)(this._buffer.Height - 30 + 1)); + string text = this._snr.ToString("##"); + SizeF sizeF = this._graphics.MeasureString(text, this.Font); + this._graphics.DrawString(text, this.Font, new SolidBrush(Color.White), (float)this._buffer.Width - (30f + sizeF.Width) * 0.5f, (float)(this._buffer.Height - 30) - val2 - sizeF.Height); + } + } + + protected override void OnPaint(PaintEventArgs e) + { + Rectangle clientRectangle = base.ClientRectangle; + if (clientRectangle.Width > 60) + { + clientRectangle = base.ClientRectangle; + if (clientRectangle.Height <= 60) + { + goto IL_0024; + } + SpectrumAnalyzer.ConfigureGraphics(e.Graphics, false); + e.Graphics.DrawImageUnscaled(this._buffer, 0, 0); + return; + } + goto IL_0024; + IL_0024: + e.Graphics.Clear(Color.Black); + } + + protected override void OnPaintBackground(PaintEventArgs e) + { + } + + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + Rectangle clientRectangle = base.ClientRectangle; + if (clientRectangle.Width > 60) + { + clientRectangle = base.ClientRectangle; + if (clientRectangle.Height > 60) + { + this._buffer.Dispose(); + this._graphics.Dispose(); + clientRectangle = base.ClientRectangle; + int width = clientRectangle.Width; + clientRectangle = base.ClientRectangle; + this._buffer = new Bitmap(width, clientRectangle.Height, PixelFormat.Format32bppPArgb); + this._graphics = Graphics.FromImage(this._buffer); + SpectrumAnalyzer.ConfigureGraphics(this._graphics, false); + int num = this._buffer.Width - 60; + this._scaledSpectrumEnvelope = new byte[num]; + this._scaledSpectrumMinimum = new byte[num]; + this._smoothedSpectrumEnvelope = new float[num]; + this._smoothedSpectrumMinimum = new float[num]; + this._temp = new float[num]; + this._envelopePoints = new Point[num + 2]; + this._minMaxPoints = new Point[num * 2 + 2]; + if (this._spectrumWidth > 0) + { + this._xIncrement = this._scale * (float)num / (float)this._spectrumWidth; + } + this._gradientBrush.Dispose(); + this._gradientBrush = new LinearGradientBrush(new Rectangle(30, 30, this._buffer.Width - 30, this._buffer.Height - 30), Color.White, Color.Black, LinearGradientMode.Vertical); + this._gradientBrush.InterpolationColors = this._staticGradient; + this.Perform(true); + } + } + } + + public float FrequencyToPoint(long frequency) + { + return (float)this._buffer.Width * 0.5f + (float)(frequency - this._displayCenterFrequency) * this._xIncrement; + } + + public long PointToFrequency(float point) + { + return (long)((point - (float)this._buffer.Width * 0.5f) / this._xIncrement) + this._displayCenterFrequency; + } + + protected virtual void OnFrequencyChanged(FrequencyEventArgs e) + { + ManualFrequencyChangeEventHandler frequencyChanged = this.FrequencyChanged; + if (frequencyChanged != null) + { + frequencyChanged(this, e); + } + } + + protected virtual void OnCenterFrequencyChanged(FrequencyEventArgs e) + { + ManualFrequencyChangeEventHandler centerFrequencyChanged = this.CenterFrequencyChanged; + if (centerFrequencyChanged != null) + { + centerFrequencyChanged(this, e); + } + } + + protected virtual void OnBandwidthChanged(BandwidthEventArgs e) + { + ManualBandwidthChangeEventHandler bandwidthChanged = this.BandwidthChanged; + if (bandwidthChanged != null) + { + bandwidthChanged(this, e); + } + } + + private bool UpdateFrequency(long f, FrequencyChangeSource source) + { + if (this._useSnap) + { + f = (long)((float)f + (float)(Math.Sign(f) * this._stepSize) * 0.5f) / this._stepSize * this._stepSize; + } + long num = (long)((float)this._displayCenterFrequency - (float)this._spectrumWidth * 0.5f / this._scale); + long num2 = (long)((float)this._displayCenterFrequency + (float)this._spectrumWidth * 0.5f / this._scale); + if (source == FrequencyChangeSource.Scroll) + { + if (f < num || f > num2) + { + long num3 = f - this._frequency; + if (num3 != 0L && !this.UpdateCenterFrequency(this._centerFrequency + num3, source)) + { + return false; + } + } + } + else if (f < num) + { + f = num; + } + else if (f > num2) + { + f = num2; + } + if (f != this._frequency) + { + FrequencyEventArgs frequencyEventArgs = new FrequencyEventArgs(f, source); + this.OnFrequencyChanged(frequencyEventArgs); + if (!frequencyEventArgs.Cancel) + { + this._frequency = frequencyEventArgs.Frequency; + this._performNeeded = true; + } + return true; + } + return false; + } + + private bool UpdateCenterFrequency(long f, FrequencyChangeSource source) + { + if (this._useSnap) + { + f = (long)((float)f + (float)(Math.Sign(f) * this._stepSize) * 0.5f) / this._stepSize * this._stepSize; + } + if (f < 0) + { + f = 0L; + } + if (f != this._centerFrequency) + { + FrequencyEventArgs frequencyEventArgs = new FrequencyEventArgs(f, source); + this.OnCenterFrequencyChanged(frequencyEventArgs); + if (!frequencyEventArgs.Cancel) + { + long num = frequencyEventArgs.Frequency - this._centerFrequency; + this._displayCenterFrequency += num; + this._centerFrequency = frequencyEventArgs.Frequency; + this._performNeeded = true; + } + return true; + } + return false; + } + + private void UpdateBandwidth(int bw) + { + bw = 10 * (bw / 10); + if (bw < 10) + { + bw = 10; + } + int num = (int)((float)(18 * this._spectrumWidth) / this._scale / (float)(this._buffer.Width - 60)); + if (bw < num) + { + bw = num; + } + if (bw != this._filterBandwidth) + { + int num2 = this._enableSideFilterResize ? ((int)((float)(bw - this._filterBandwidth) * 0.5f)) : 0; + int offset = this._filterOffset + ((this._side == BandType.Upper) ? num2 : (-num2)); + BandwidthEventArgs bandwidthEventArgs = new BandwidthEventArgs(bw, offset, this._side); + this.OnBandwidthChanged(bandwidthEventArgs); + if (!bandwidthEventArgs.Cancel) + { + this._filterOffset = bandwidthEventArgs.Offset; + this._filterBandwidth = bandwidthEventArgs.Bandwidth; + this._performNeeded = true; + } + } + } + + protected virtual void OnCustomPaint(CustomPaintEventArgs e) + { + CustomPaintEventHandler customPaint = this.CustomPaint; + if (customPaint != null) + { + customPaint(this, e); + this._customTitle = e.CustomTitle; + } + } + + protected virtual void OnBackgroundCustomPaint(CustomPaintEventArgs e) + { + CustomPaintEventHandler backgroundCustomPaint = this.BackgroundCustomPaint; + if (backgroundCustomPaint != null) + { + backgroundCustomPaint(this, e); + this._customTitle = e.CustomTitle; + } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + if (e.X >= 30 && e.X <= this._buffer.Width - 30 && e.Y >= 30) + { + if (e.Button == MouseButtons.Left) + { + float num = Math.Max((float)this._filterBandwidth * this._xIncrement, 2f); + if (this._enableFilter && e.Y <= this._buffer.Height - 30) + { + if (this._enableFilterMove && (float)e.X > this._lower && (float)e.X < this._upper && num < (float)this._buffer.Width) + { + this._oldX = e.X; + this._oldFrequency = this._frequency; + this._changingFrequency = true; + } + else if (this._upper - this._lower > 12f) + { + if (Math.Abs((float)e.X - this._upper - 6f) <= 6f && (this._bandType == BandType.Center || this._bandType == BandType.Upper)) + { + this._side = BandType.Upper; + this._oldX = e.X; + this._oldFilterBandwidth = this._filterBandwidth; + this._changingBandwidth = true; + } + else if (Math.Abs((float)e.X - this._lower + 6f) <= 6f && (this._bandType == BandType.Center || this._bandType == BandType.Lower)) + { + this._side = BandType.Lower; + this._oldX = e.X; + this._oldFilterBandwidth = this._filterBandwidth; + this._changingBandwidth = true; + } + } + } + if (!this._changingBandwidth && !this._changingFrequency) + { + this._oldX = e.X; + this._oldCenterFrequency = this._centerFrequency; + this._changingCenterFrequency = true; + } + } + else if (e.Button == MouseButtons.Right) + { + this.UpdateFrequency(this._frequency / 500 * 500, FrequencyChangeSource.Click); + } + } + } + + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + if (this._enableFilterMove && this._changingCenterFrequency && e.X == this._oldX) + { + long f = (long)(((float)this._oldX - (float)this._buffer.Width * 0.5f) * (float)this._spectrumWidth / this._scale / (float)(this._buffer.Width - 60) + (float)this._displayCenterFrequency); + this.UpdateFrequency(f, FrequencyChangeSource.Click); + } + this._changingCenterFrequency = false; + this._changingBandwidth = false; + this._changingFrequency = false; + this._performNeeded = true; + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + this._cursorPosition.X = e.X; + this._cursorPosition.Y = e.Y; + if (this._enableHotTracking) + { + this._snappedX = (float)e.X; + this._trackingFrequency = (long)(((float)e.X - (float)this._buffer.Width * 0.5f) * (float)this._spectrumWidth / this._scale / (float)(this._buffer.Width - 60) + (float)this._displayCenterFrequency); + if (this._useSnap) + { + this._trackingFrequency = (long)((float)this._trackingFrequency + (float)(Math.Sign(this._trackingFrequency) * this._stepSize) * 0.5f) / this._stepSize * this._stepSize; + this._snappedX = this.FrequencyToPoint(this._trackingFrequency); + } + int num = this._displayRange / 10 * 10; + int num2 = this._displayOffset / 10 * 10; + float num3 = (float)(this._buffer.Height - 60) / (float)num; + this._trackingPower = (float)(num2 - num) - (float)(e.Y + 30 - this._buffer.Height) / num3; + } + if (this._changingFrequency) + { + long f = (long)((float)((e.X - this._oldX) * this._spectrumWidth) / this._scale / (float)(this._buffer.Width - 60) + (float)this._oldFrequency); + this.UpdateFrequency(f, FrequencyChangeSource.Drag); + } + else if (this._changingCenterFrequency) + { + long f2 = (long)((float)((this._oldX - e.X) * this._spectrumWidth) / this._scale / (float)(this._buffer.Width - 60) + (float)this._oldCenterFrequency); + this.UpdateCenterFrequency(f2, FrequencyChangeSource.Drag); + } + else if (this._changingBandwidth) + { + int num4 = 0; + switch (this._side) + { + case BandType.Upper: + num4 = e.X - this._oldX; + break; + case BandType.Lower: + num4 = this._oldX - e.X; + break; + } + if (this._bandType == BandType.Center && !this._enableSideFilterResize) + { + num4 *= 2; + } + num4 = (int)((float)(num4 * this._spectrumWidth) / this._scale / (float)(this._buffer.Width - 60) + (float)this._oldFilterBandwidth); + this.UpdateBandwidth(num4); + } + else if (this._enableFilter) + { + if (e.Y >= 30 && e.Y <= this._buffer.Height - 30 && e.X >= 30 && e.X <= this._buffer.Width - 30 && this._upper - this._lower > 12f) + { + if (Math.Abs((float)e.X - this._lower + 6f) <= 6f && (this._bandType == BandType.Center || this._bandType == BandType.Lower)) + { + goto IL_0325; + } + if (Math.Abs((float)e.X - this._upper - 6f) <= 6f && (this._bandType == BandType.Center || this._bandType == BandType.Upper)) + { + goto IL_0325; + } + this.Cursor = Cursors.Default; + } + else + { + this.Cursor = Cursors.Default; + } + } + goto IL_034a; + IL_034a: + this._performNeeded = true; + return; + IL_0325: + this.Cursor = Cursors.SizeWE; + goto IL_034a; + } + + protected override void OnMouseWheel(MouseEventArgs e) + { + base.OnMouseWheel(e); + if (this._enableFilter) + { + this.UpdateFrequency(this._frequency + this._stepSize * Math.Sign(e.Delta), FrequencyChangeSource.Scroll); + } + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + this._hotTrackNeeded = false; + this._performNeeded = true; + this._cursorPosition = Point.Empty; + } + + protected override void OnMouseEnter(EventArgs e) + { + base.Focus(); + base.OnMouseEnter(e); + this._hotTrackNeeded = true; + } + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/SpectrumStyle.cs b/SDRSharp.PanView/SDRSharp.PanView/SpectrumStyle.cs new file mode 100644 index 0000000..e5c6f41 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/SpectrumStyle.cs @@ -0,0 +1,12 @@ +namespace SDRSharp.PanView +{ + public enum SpectrumStyle + { + Dots, + SimpleCurve, + SolidFill, + StaticGradient, + DynamicGradient, + MinMax + } +} diff --git a/SDRSharp.PanView/SDRSharp.PanView/Waterfall.cs b/SDRSharp.PanView/SDRSharp.PanView/Waterfall.cs new file mode 100644 index 0000000..491ecc5 --- /dev/null +++ b/SDRSharp.PanView/SDRSharp.PanView/Waterfall.cs @@ -0,0 +1,1280 @@ +using SDRSharp.Radio; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Windows.Forms; + +namespace SDRSharp.PanView +{ + public class Waterfall : UserControl + { + private const int RefreshInterval = 20; + + public const float TrackingFontSize = 16f; + + public const float TimestampFontSize = 14f; + + public const int CarrierPenWidth = 1; + + public const int AxisMargin = 30; + + public const int CursorSnapDistance = 6; + + public const float MaxZoom = 4f; + + public const int RightClickSnapDistance = 500; + + public const float DefaultCursorHeight = 32f; + + private static readonly bool _useUtcTimeStamp = Utils.GetBooleanSetting("waterfall.useUtcTimeStamp"); + + private float _attack; + + private float _decay; + + private bool _performNeeded; + + private Bitmap _buffer; + + private Bitmap _buffer2; + + private Graphics _graphics; + + private Graphics _graphics2; + + private BandType _bandType; + + private BandType _side; + + private int _filterBandwidth; + + private int _filterOffset; + + private float _xIncrement; + + private float[] _temp; + + private float[] _smoothedSpectrum; + + private byte[] _scaledSpectrum; + + private long _centerFrequency; + + private long _spectrumWidth; + + private int _stepSize; + + private long _frequency; + + private float _lower; + + private float _upper; + + private float _scale = 1f; + + private long _displayCenterFrequency; + + private bool _changingBandwidth; + + private bool _changingFrequency; + + private bool _changingCenterFrequency; + + private bool _mouseIn; + + private int _oldX; + + private int _displayedBandwidth; + + private long _oldFrequency; + + private long _oldCenterFrequency; + + private int _oldFilterBandwidth; + + private int[] _gradientPixels; + + private int _contrast; + + private int _zoom; + + private bool _useSmoothing; + + private bool _enableFilter = true; + + private bool _enableHotTracking = true; + + private bool _enableFrequencyMarker = true; + + private bool _enableSideFilterResize; + + private bool _enableFilterMove = true; + + private bool _useSnap; + + private float _snappedX; + + private long _trackingFrequency; + + private bool _useTimestamps; + + private int _scanlines; + + private int _timestampInterval; + + private int _displayRange = 130; + + private int _displayOffset; + + private Point _cursorPosition; + + private string _customTitle; + + private Timer _performTimer; + + private LinearGradientBrush _gradientBrush; + + private ColorBlend _gradientColorBlend = Utils.GetGradientBlend(255, "waterfall.gradient"); + + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] + public ColorBlend GradientColorBlend + { + get + { + return this._gradientColorBlend; + } + set + { + if (this._gradientColorBlend != value) + { + this._gradientColorBlend = value; + this._gradientBrush.Dispose(); + this._gradientBrush = new LinearGradientBrush(new RectangleF(15f, 15f, (float)this._buffer.Width - 15f, (float)this._buffer.Height - 15f), Color.White, Color.Black, LinearGradientMode.Vertical); + this._gradientBrush.InterpolationColors = this._gradientColorBlend; + this.DrawGradient(); + this.BuildGradientVector(); + this._performNeeded = true; + } + } + } + + public long CenterFrequency + { + get + { + return this._centerFrequency; + } + set + { + if (this._centerFrequency != value) + { + this._displayCenterFrequency += value - this._centerFrequency; + this._centerFrequency = value; + this._performNeeded = true; + } + } + } + + public int DisplayedBandwidth + { + get + { + return this._displayedBandwidth; + } + } + + public long DisplayCenterFrequency + { + get + { + return this._displayCenterFrequency; + } + } + + public int SpectrumWidth + { + get + { + return (int)this._spectrumWidth; + } + set + { + if (this._spectrumWidth != value) + { + this._spectrumWidth = value; + this.ApplyZoom(); + } + } + } + + public long Frequency + { + get + { + return this._frequency; + } + set + { + if (this._frequency != value) + { + this._frequency = value; + this._performNeeded = true; + } + } + } + + public int FilterBandwidth + { + get + { + return this._filterBandwidth; + } + set + { + if (this._filterBandwidth != value) + { + this._filterBandwidth = value; + this._performNeeded = true; + } + } + } + + public int DisplayRange + { + get + { + return this._displayRange; + } + set + { + this._displayRange = value; + } + } + + public int DisplayOffset + { + get + { + return this._displayOffset; + } + set + { + this._displayOffset = value; + } + } + + public int FilterOffset + { + get + { + return this._filterOffset; + } + set + { + if (this._filterOffset != value) + { + this._filterOffset = value; + this._performNeeded = true; + } + } + } + + public BandType BandType + { + get + { + return this._bandType; + } + set + { + if (this._bandType != value) + { + this._bandType = value; + this._performNeeded = true; + } + } + } + + public int Contrast + { + get + { + return this._contrast; + } + set + { + this._contrast = value; + } + } + + public int Zoom + { + get + { + return this._zoom; + } + set + { + if (this._zoom != value) + { + this._zoom = value; + this.ApplyZoom(); + } + } + } + + public bool UseSmoothing + { + get + { + return this._useSmoothing; + } + set + { + this._useSmoothing = value; + } + } + + public bool EnableFilter + { + get + { + return this._enableFilter; + } + set + { + this._enableFilter = value; + this._performNeeded = true; + } + } + + public bool EnableHotTracking + { + get + { + return this._enableHotTracking; + } + set + { + this._enableHotTracking = value; + this._performNeeded = true; + } + } + + public bool EnableFrequencyMarker + { + get + { + return this._enableFrequencyMarker; + } + set + { + this._enableFrequencyMarker = value; + this._performNeeded = true; + } + } + + public bool EnableSideFilterResize + { + get + { + return this._enableSideFilterResize; + } + set + { + this._enableSideFilterResize = value; + this._performNeeded = true; + } + } + + public bool EnableFilterMove + { + get + { + return this._enableFilterMove; + } + set + { + this._enableFilterMove = value; + this._performNeeded = true; + } + } + + public float Decay + { + get + { + return this._decay; + } + set + { + this._decay = value; + } + } + + public float Attack + { + get + { + return this._attack; + } + set + { + this._attack = value; + } + } + + public int StepSize + { + get + { + return this._stepSize; + } + set + { + this._performNeeded = true; + this._stepSize = value; + } + } + + public bool UseSnap + { + get + { + return this._useSnap; + } + set + { + this._useSnap = value; + } + } + + public bool UseTimestamps + { + get + { + return this._useTimestamps; + } + set + { + this._useTimestamps = value; + this._scanlines = 0; + } + } + + public int TimestampInterval + { + get + { + return this._timestampInterval; + } + set + { + this._timestampInterval = value; + } + } + + public event ManualFrequencyChangeEventHandler FrequencyChanged; + + public event ManualFrequencyChangeEventHandler CenterFrequencyChanged; + + public event ManualBandwidthChangeEventHandler BandwidthChanged; + + public event CustomPaintEventHandler CustomPaint; + + public event LineInsertEventHandler LineInserted; + + public Waterfall() + { + this._performTimer = new Timer(); + this._performTimer.Enabled = true; + this._performTimer.Interval = 20; + this._performTimer.Tick += this.performTimer_Tick; + Rectangle clientRectangle = base.ClientRectangle; + int width = clientRectangle.Width; + clientRectangle = base.ClientRectangle; + this._buffer = new Bitmap(width, clientRectangle.Height, PixelFormat.Format32bppPArgb); + clientRectangle = base.ClientRectangle; + int width2 = clientRectangle.Width; + clientRectangle = base.ClientRectangle; + this._buffer2 = new Bitmap(width2, clientRectangle.Height, PixelFormat.Format32bppPArgb); + this._graphics = Graphics.FromImage(this._buffer); + this._graphics2 = Graphics.FromImage(this._buffer2); + this._gradientBrush = new LinearGradientBrush(new RectangleF(15f, 15f, (float)this._buffer.Width - 15f, (float)this._buffer.Height - 15f), Color.White, Color.Black, LinearGradientMode.Vertical); + this._gradientBrush.InterpolationColors = this._gradientColorBlend; + this._smoothedSpectrum = new float[this._buffer.Width - 60]; + this._scaledSpectrum = new byte[this._smoothedSpectrum.Length]; + this._temp = new float[this._smoothedSpectrum.Length]; + this._gradientPixels = new int[256]; + for (int i = 0; i < this._smoothedSpectrum.Length; i++) + { + this._smoothedSpectrum[i] = -250f; + } + base.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); + base.SetStyle(ControlStyles.DoubleBuffer, true); + base.SetStyle(ControlStyles.UserPaint, true); + base.SetStyle(ControlStyles.AllPaintingInWmPaint, true); + base.UpdateStyles(); + this.BuildGradientVector(); + } + + ~Waterfall() + { + this._buffer.Dispose(); + this._buffer2.Dispose(); + this._graphics.Dispose(); + this._graphics2.Dispose(); + this._gradientBrush.Dispose(); + } + + private void performTimer_Tick(object sender, EventArgs e) + { + this.Perform(false); + } + + private void Perform(bool force) + { + if (this._performNeeded | force) + { + this.DrawGradient(); + this.CopyMainBuffer(); + this.OnCustomPaint(new CustomPaintEventArgs(this._graphics2, this._cursorPosition)); + if (this._mouseIn) + { + this.DrawCursor(); + } + base.Invalidate(); + this._performNeeded = false; + } + } + + public void Perform() + { + this._performNeeded = true; + } + + private void ApplyZoom() + { + this._scale = (float)Math.Pow(10.0, (double)((float)this._zoom * 4f / 100f)); + this._displayCenterFrequency = this.GetDisplayCenterFrequency(); + if (this._spectrumWidth > 0) + { + this._xIncrement = this._scale * (float)(this._buffer.Width - 60) / (float)this._spectrumWidth; + this._displayedBandwidth = (int)((float)this._spectrumWidth / this._scale); + this._performNeeded = true; + } + } + + public void CenterZoom() + { + this._displayCenterFrequency = this.GetDisplayCenterFrequency(); + this._performNeeded = true; + } + + private long GetDisplayCenterFrequency() + { + long num = this._frequency + this._filterOffset; + switch (this._bandType) + { + case BandType.Lower: + num = (long)((float)num - (float)this._filterBandwidth * 0.5f); + break; + case BandType.Upper: + num = (long)((float)num + (float)this._filterBandwidth * 0.5f); + break; + } + long num2 = (long)((double)this._centerFrequency - (double)this._spectrumWidth * 0.5 - ((double)num - (double)this._spectrumWidth * 0.5 / (double)this._scale)); + if (num2 > 0) + { + num += num2; + } + long num3 = (long)((double)num + (double)this._spectrumWidth * 0.5 / (double)this._scale - ((double)this._centerFrequency + (double)this._spectrumWidth * 0.5)); + if (num3 > 0) + { + num -= num3; + } + return num; + } + + public unsafe void Render(float* powerSpectrum, int length) + { + float offset = (float)(this._displayCenterFrequency - this._centerFrequency) / (float)this._spectrumWidth; + this.ExtractSpectrum(powerSpectrum, length, offset, this._scale, this._useSmoothing); + this.Draw(); + } + + private unsafe void ExtractSpectrum(float* powerSpectrum, int length, float offset, float scale, bool useSmoothing) + { + int num = this._displayOffset / 10 * 10; + int num2 = this._displayRange / 10 * 10; + float[] temp = this._temp; + fixed (float* ptr = temp) + { + float[] smoothedSpectrum = this._smoothedSpectrum; + fixed (float* ptr2 = smoothedSpectrum) + { + byte[] scaledSpectrum = this._scaledSpectrum; + fixed (byte* dest = scaledSpectrum) + { + Fourier.SmoothMaxCopy(powerSpectrum, ptr, length, this._smoothedSpectrum.Length, scale, offset); + if (useSmoothing) + { + for (int i = 0; i < this._temp.Length; i++) + { + float num3 = (ptr2[i] < ptr[i]) ? this.Attack : this.Decay; + ptr2[i] = ptr2[i] * (1f - num3) + ptr[i] * num3; + } + } + else + { + Utils.Memcpy(ptr2, ptr, this._smoothedSpectrum.Length * 4); + } + Fourier.ScaleFFT(ptr2, dest, this._smoothedSpectrum.Length, (float)(num - num2), (float)num); + } + } + } + } + + private void Draw() + { + if (this._buffer.Width > 30 && this._buffer.Height > 30) + { + this.InsertNewLine(); + if (this._useTimestamps && this._scanlines == 0) + { + this.DrawTimestamp(); + } + this._performNeeded = true; + } + } + + private unsafe void InsertNewLine() + { + if (this._buffer.Width > 0 && this._buffer.Height > 0) + { + Rectangle rect = new Rectangle(0, 0, this._buffer.Width, this._buffer.Height); + BitmapData bitmapData = this._buffer.LockBits(rect, ImageLockMode.ReadWrite, this._buffer.PixelFormat); + void* ptr; + void* dest; + if (bitmapData.Stride > 0) + { + ptr = (void*)bitmapData.Scan0; + dest = (void*)((long)bitmapData.Scan0 + bitmapData.Stride); + } + else + { + dest = (void*)bitmapData.Scan0; + ptr = (void*)((long)bitmapData.Scan0 - bitmapData.Stride); + } + Utils.Memmove(dest, ptr, (bitmapData.Height - 1) * Math.Abs(bitmapData.Stride)); + if (this._scaledSpectrum != null && this._scaledSpectrum.Length != 0) + { + int* ptr2 = (int*)((byte*)ptr + 30L * 4L); + int* ptr3 = ptr2; + for (int i = 0; i < this._scaledSpectrum.Length; i++) + { + int val = (this._scaledSpectrum[i] + this._contrast * 2) * this._gradientPixels.Length / 255; + val = Math.Max(val, 0); + val = Math.Min(val, this._gradientPixels.Length - 1); + int* intPtr = ptr3; + ptr3 = intPtr + 1; + *intPtr = this._gradientPixels[val]; + } + this.OnLineInserted(new LineInsertEventArgs(ptr2, this._scaledSpectrum.Length)); + } + this._buffer.UnlockBits(bitmapData); + this._scanlines++; + if (this._scanlines >= this.TimestampInterval) + { + this._scanlines = 0; + } + } + } + + private void DrawTimestamp() + { + using (FontFamily family = new FontFamily("Verdana")) + { + using (GraphicsPath graphicsPath = new GraphicsPath()) + { + using (Pen pen = new Pen(Color.Black)) + { + DateTime dateTime; + string s; + if (Waterfall._useUtcTimeStamp) + { + dateTime = DateTime.UtcNow; + s = dateTime.ToString("u"); + } + else + { + dateTime = DateTime.Now; + s = dateTime.ToString(); + } + graphicsPath.AddString(s, family, 0, 14f, new Point(30, 0), StringFormat.GenericTypographic); + SmoothingMode smoothingMode = this._graphics.SmoothingMode; + InterpolationMode interpolationMode = this._graphics.InterpolationMode; + this._graphics.SmoothingMode = SmoothingMode.AntiAlias; + this._graphics.InterpolationMode = InterpolationMode.HighQualityBilinear; + pen.Width = 2f; + this._graphics.DrawPath(pen, graphicsPath); + this._graphics.FillPath(Brushes.White, graphicsPath); + this._graphics.SmoothingMode = smoothingMode; + this._graphics.InterpolationMode = interpolationMode; + } + } + } + } + + private void DrawCursor() + { + this._lower = 0f; + float num = (float)((int)Math.Max((float)this._filterBandwidth * this._xIncrement, 2f) | 1); + float num2 = (float)this._buffer.Width * 0.5f + (float)(this._frequency - this._displayCenterFrequency) * this._xIncrement; + switch (this._bandType) + { + case BandType.Upper: + this._lower = num2; + break; + case BandType.Lower: + this._lower = num2 - num; + break; + case BandType.Center: + this._lower = num2 - num * 0.5f; + break; + } + this._lower += (float)this._filterOffset * this._xIncrement; + this._upper = this._lower + num; + using (SolidBrush brush = new SolidBrush(Color.FromArgb(80, Color.DarkGray))) + { + using (SolidBrush brush2 = new SolidBrush(Color.FromArgb(200, 50, 50, 50))) + { + using (Pen pen5 = new Pen(Color.FromArgb(200, Color.Gray))) + { + using (Pen pen3 = new Pen(Color.DodgerBlue)) + { + using (Pen pen2 = new Pen(Color.LimeGreen)) + { + using (Pen pen = new Pen(Color.Red)) + { + using (FontFamily family = new FontFamily("Verdana")) + { + using (GraphicsPath graphicsPath = new GraphicsPath()) + { + using (Pen pen4 = new Pen(Color.Black)) + { + if (this._enableFilter && num < (float)this._buffer.Width) + { + float num3 = this._lower; + float num4 = num; + if (this._lower < 30f) + { + num3 = 31f; + num4 -= num3 - this._lower; + } + if (this._upper > (float)(this._buffer.Width - 30)) + { + num4 -= this._upper - (float)(this._buffer.Width - 30); + } + this._graphics2.FillRectangle(brush, num3, 0f, num4, (float)this._buffer.Height); + } + if (this._enableFrequencyMarker && num2 > 30f && num2 < (float)(this._buffer.Width - 30)) + { + pen.Width = 1f; + this._graphics2.DrawLine(pen, num2, 0f, num2, (float)this._buffer.Height); + } + if (this._enableHotTracking && this._cursorPosition.X >= 30 && this._cursorPosition.X <= this._buffer.Width - 30) + { + if (this.Cursor != Cursors.SizeWE && ((float)this._cursorPosition.X < this._lower || (float)this._cursorPosition.X > this._upper) && !this._changingFrequency && !this._changingCenterFrequency && !this._changingBandwidth) + { + pen2.DashStyle = DashStyle.Dash; + this._graphics2.DrawLine(pen3, this._snappedX, 0f, this._snappedX, (float)this._buffer.Height); + float num5 = num / 2f; + switch (this._bandType) + { + case BandType.Center: + this._graphics2.DrawLine(pen2, this._snappedX - num5, 0f, this._snappedX - num5, (float)this._buffer.Height); + this._graphics2.DrawLine(pen2, this._snappedX + num5, 0f, this._snappedX + num5, (float)this._buffer.Height); + break; + case BandType.Lower: + this._graphics2.DrawLine(pen2, this._snappedX - num, 0f, this._snappedX - num, (float)this._buffer.Height); + break; + case BandType.Upper: + this._graphics2.DrawLine(pen2, this._snappedX + num, 0f, this._snappedX + num, (float)this._buffer.Height); + break; + } + } + string s = (this._changingBandwidth || this.Cursor == Cursors.SizeWE) ? ("Bandwidth: " + SpectrumAnalyzer.GetFrequencyDisplay(this._filterBandwidth)) : (string.IsNullOrEmpty(this._customTitle) ? ((this._changingFrequency || ((float)this._cursorPosition.X >= this._lower && (float)this._cursorPosition.X <= this._upper)) ? ("VFO: " + SpectrumAnalyzer.GetFrequencyDisplay(this._frequency)) : ((!this._changingCenterFrequency) ? SpectrumAnalyzer.GetFrequencyDisplay(this._trackingFrequency) : ("Center Frequency: " + SpectrumAnalyzer.GetFrequencyDisplay(this._centerFrequency)))) : this._customTitle); + graphicsPath.AddString(s, family, 0, 16f, Point.Empty, StringFormat.GenericTypographic); + RectangleF bounds = graphicsPath.GetBounds(); + Cursor current = Cursor.Current; + float val = (float)this._cursorPosition.X + 30f; + float val2 = (float)this._cursorPosition.Y + ((current == (Cursor)null) ? 32f : ((float)current.Size.Height)) - 8f; + val = Math.Min(val, (float)this._buffer.Width - bounds.Width - 30f - 20f); + val2 = Math.Min(val2, (float)this._buffer.Height - bounds.Height - 20f); + graphicsPath.Reset(); + graphicsPath.AddString(s, family, 0, 16f, new Point((int)val, (int)val2), StringFormat.GenericTypographic); + SmoothingMode smoothingMode = this._graphics2.SmoothingMode; + InterpolationMode interpolationMode = this._graphics2.InterpolationMode; + this._graphics2.SmoothingMode = SmoothingMode.AntiAlias; + this._graphics2.InterpolationMode = InterpolationMode.HighQualityBilinear; + pen4.Width = 2f; + RectangleF bounds2 = graphicsPath.GetBounds(); + bounds2.X -= 10f; + bounds2.Y -= 10f; + bounds2.Width += 20f; + bounds2.Height += 20f; + this._graphics2.FillRoundedRectangle(brush2, bounds2, 6); + this._graphics2.DrawRoundedRectangle(pen5, bounds2, 6); + this._graphics2.DrawPath(pen4, graphicsPath); + this._graphics2.FillPath(Brushes.White, graphicsPath); + this._graphics2.SmoothingMode = smoothingMode; + this._graphics2.InterpolationMode = interpolationMode; + } + } + } + } + } + } + } + } + } + } + } + + private unsafe void CopyMainBuffer() + { + if (this._buffer.Width > 0 && this._buffer.Height > 0) + { + Rectangle rect = new Rectangle(0, 0, this._buffer.Width, this._buffer.Height); + BitmapData bitmapData = this._buffer.LockBits(rect, ImageLockMode.ReadOnly, this._buffer.PixelFormat); + BitmapData bitmapData2 = this._buffer2.LockBits(rect, ImageLockMode.WriteOnly, this._buffer2.PixelFormat); + Utils.Memcpy((void*)bitmapData2.Scan0, (void*)bitmapData.Scan0, Math.Abs(bitmapData.Stride) * bitmapData.Height); + this._buffer.UnlockBits(bitmapData); + this._buffer2.UnlockBits(bitmapData2); + } + } + + protected override void OnPaint(PaintEventArgs e) + { + Rectangle clientRectangle = base.ClientRectangle; + if (clientRectangle.Width > 60) + { + clientRectangle = base.ClientRectangle; + if (clientRectangle.Height <= 60) + { + goto IL_0024; + } + SpectrumAnalyzer.ConfigureGraphics(e.Graphics, false); + e.Graphics.DrawImageUnscaled(this._buffer2, 0, 0); + return; + } + goto IL_0024; + IL_0024: + e.Graphics.Clear(Color.Black); + } + + protected override void OnPaintBackground(PaintEventArgs e) + { + } + + protected unsafe override void OnResize(EventArgs e) + { + base.OnResize(e); + this._performNeeded = true; + Rectangle clientRectangle = base.ClientRectangle; + if (clientRectangle.Width > 60) + { + clientRectangle = base.ClientRectangle; + if (clientRectangle.Height > 60) + { + Bitmap buffer = this._buffer; + clientRectangle = base.ClientRectangle; + int width = clientRectangle.Width; + clientRectangle = base.ClientRectangle; + this._buffer = new Bitmap(width, clientRectangle.Height, PixelFormat.Format32bppPArgb); + Bitmap buffer2 = this._buffer2; + clientRectangle = base.ClientRectangle; + int width2 = clientRectangle.Width; + clientRectangle = base.ClientRectangle; + this._buffer2 = new Bitmap(width2, clientRectangle.Height, PixelFormat.Format32bppPArgb); + int num = this._buffer.Width - 60; + float[] smoothedSpectrum = this._smoothedSpectrum; + this._scaledSpectrum = new byte[num]; + this._smoothedSpectrum = new float[num]; + this._temp = new float[num]; + float[] array = smoothedSpectrum; + fixed (float* powerSpectrum = array) + { + this.ExtractSpectrum(powerSpectrum, smoothedSpectrum.Length, 0f, 1f, false); + } + this._graphics.Dispose(); + this._graphics = Graphics.FromImage(this._buffer); + SpectrumAnalyzer.ConfigureGraphics(this._graphics, false); + this._graphics2.Dispose(); + this._graphics2 = Graphics.FromImage(this._buffer2); + SpectrumAnalyzer.ConfigureGraphics(this._graphics2, false); + this._graphics.Clear(Color.Black); + Rectangle destRect = new Rectangle(30, 0, this._buffer.Width - 60, buffer.Height); + this._graphics.DrawImage(buffer, destRect, 30, 0, buffer.Width - 60, buffer.Height, GraphicsUnit.Pixel); + buffer.Dispose(); + buffer2.Dispose(); + if (this._spectrumWidth > 0) + { + this._xIncrement = this._scale * (float)(this._buffer.Width - 60) / (float)this._spectrumWidth; + } + this._gradientBrush.Dispose(); + this._gradientBrush = new LinearGradientBrush(new RectangleF(15f, 15f, (float)base.Width - 15f, (float)this._buffer.Height - 15f), Color.White, Color.Black, LinearGradientMode.Vertical); + this._gradientBrush.InterpolationColors = this._gradientColorBlend; + this.Perform(true); + } + } + } + + private void DrawGradient() + { + using (Pen pen = new Pen(this._gradientBrush, 10f)) + { + this._graphics.FillRectangle(Brushes.Black, this._buffer.Width - 30, 0, 30, this._buffer.Height); + this._graphics.DrawLine(pen, (float)this._buffer.Width - 15f, (float)this._buffer.Height - 15f, (float)this._buffer.Width - 15f, 15f); + } + } + + private void BuildGradientVector() + { + using (Bitmap bitmap = new Bitmap(1, this._gradientPixels.Length)) + { + using (Graphics graphics = Graphics.FromImage(bitmap)) + { + using (LinearGradientBrush linearGradientBrush = new LinearGradientBrush(new Rectangle(0, 0, 1, this._gradientPixels.Length - 1), Color.White, Color.Black, LinearGradientMode.Vertical)) + { + linearGradientBrush.InterpolationColors = this._gradientColorBlend; + Pen pen = new Pen(linearGradientBrush); + graphics.DrawLine(pen, 0, 0, 0, this._gradientPixels.Length - 1); + for (int i = 0; i < this._gradientPixels.Length; i++) + { + this._gradientPixels[this._gradientPixels.Length - 1 - i] = bitmap.GetPixel(0, i).ToArgb(); + } + } + } + } + } + + public float FrequencyToPoint(long frequency) + { + return (float)this._buffer.Width * 0.5f + (float)(frequency - this._displayCenterFrequency) * this._xIncrement; + } + + public long PointToFrequency(float point) + { + return (long)((point - (float)this._buffer.Width * 0.5f) / this._xIncrement) + this._displayCenterFrequency; + } + + protected virtual void OnFrequencyChanged(FrequencyEventArgs e) + { + ManualFrequencyChangeEventHandler frequencyChanged = this.FrequencyChanged; + if (frequencyChanged != null) + { + frequencyChanged(this, e); + } + } + + protected virtual void OnCenterFrequencyChanged(FrequencyEventArgs e) + { + ManualFrequencyChangeEventHandler centerFrequencyChanged = this.CenterFrequencyChanged; + if (centerFrequencyChanged != null) + { + centerFrequencyChanged(this, e); + } + } + + protected virtual void OnBandwidthChanged(BandwidthEventArgs e) + { + ManualBandwidthChangeEventHandler bandwidthChanged = this.BandwidthChanged; + if (bandwidthChanged != null) + { + bandwidthChanged(this, e); + } + } + + private bool UpdateFrequency(long f, FrequencyChangeSource source) + { + if (this._useSnap) + { + f = (long)((float)f + (float)(Math.Sign(f) * this._stepSize) * 0.5f) / this._stepSize * this._stepSize; + } + long num = (long)((float)this._displayCenterFrequency - (float)this._spectrumWidth / this._scale * 0.5f); + long num2 = (long)((float)this._displayCenterFrequency + (float)this._spectrumWidth / this._scale * 0.5f); + if (source == FrequencyChangeSource.Scroll) + { + long num3 = 0L; + if (f < num) + { + num3 = f - num; + } + else if (f > num2) + { + num3 = f - num2; + } + if (num3 != 0L && !this.UpdateCenterFrequency(this._centerFrequency + num3, source)) + { + return false; + } + } + else if (f < num) + { + f = num; + } + else if (f > num2) + { + f = num2; + } + if (f != this._frequency) + { + FrequencyEventArgs frequencyEventArgs = new FrequencyEventArgs(f, source); + this.OnFrequencyChanged(frequencyEventArgs); + if (!frequencyEventArgs.Cancel) + { + this._frequency = frequencyEventArgs.Frequency; + this._performNeeded = true; + } + return true; + } + return false; + } + + private bool UpdateCenterFrequency(long f, FrequencyChangeSource source) + { + if (f < 0) + { + f = 0L; + } + if (this._useSnap) + { + f = (long)((float)f + (float)(Math.Sign(f) * this._stepSize) * 0.5f) / this._stepSize * this._stepSize; + } + if (f != this._centerFrequency) + { + FrequencyEventArgs frequencyEventArgs = new FrequencyEventArgs(f, source); + this.OnCenterFrequencyChanged(frequencyEventArgs); + if (!frequencyEventArgs.Cancel) + { + long num = frequencyEventArgs.Frequency - this._centerFrequency; + this._displayCenterFrequency += num; + this._centerFrequency = frequencyEventArgs.Frequency; + this._performNeeded = true; + } + return true; + } + return false; + } + + private void UpdateBandwidth(int bw) + { + bw = 10 * (bw / 10); + if (bw < 10) + { + bw = 10; + } + int num = (int)((float)(18 * this._spectrumWidth) / this._scale / (float)(this._buffer.Width - 60)); + if (bw < num) + { + bw = num; + } + if (bw != this._filterBandwidth) + { + int num2 = this._enableSideFilterResize ? ((int)((float)(bw - this._filterBandwidth) * 0.5f)) : 0; + int offset = this._filterOffset + ((this._side == BandType.Upper) ? num2 : (-num2)); + BandwidthEventArgs bandwidthEventArgs = new BandwidthEventArgs(bw, offset, this._side); + this.OnBandwidthChanged(bandwidthEventArgs); + if (!bandwidthEventArgs.Cancel) + { + this._filterOffset = bandwidthEventArgs.Offset; + this._filterBandwidth = bandwidthEventArgs.Bandwidth; + this._performNeeded = true; + } + } + } + + protected virtual void OnCustomPaint(CustomPaintEventArgs e) + { + CustomPaintEventHandler customPaint = this.CustomPaint; + if (customPaint != null) + { + customPaint(this, e); + this._customTitle = e.CustomTitle; + } + } + + protected virtual void OnLineInserted(LineInsertEventArgs e) + { + LineInsertEventHandler lineInserted = this.LineInserted; + if (lineInserted != null) + { + lineInserted(this, e); + } + } + + protected override void OnMouseDown(MouseEventArgs e) + { + base.OnMouseDown(e); + if (e.X >= 30 && e.X <= this._buffer.Width - 30) + { + if (e.Button == MouseButtons.Left) + { + float num = Math.Max((float)this._filterBandwidth * this._xIncrement, 2f); + if (this._enableFilter) + { + if (this._enableFilterMove && (float)e.X > this._lower && (float)e.X < this._upper && num < (float)this._buffer.Width) + { + this._oldX = e.X; + this._oldFrequency = this._frequency; + this._changingFrequency = true; + } + else if (this._upper - this._lower > 12f) + { + if (Math.Abs((float)e.X - this._upper - 6f) <= 6f && (this._bandType == BandType.Center || this._bandType == BandType.Upper)) + { + this._side = BandType.Upper; + this._oldX = e.X; + this._oldFilterBandwidth = this._filterBandwidth; + this._changingBandwidth = true; + } + else if (Math.Abs((float)e.X - this._lower + 6f) <= 6f && (this._bandType == BandType.Center || this._bandType == BandType.Lower)) + { + this._side = BandType.Lower; + this._oldX = e.X; + this._oldFilterBandwidth = this._filterBandwidth; + this._changingBandwidth = true; + } + } + } + if (!this._changingBandwidth && !this._changingFrequency) + { + this._oldX = e.X; + this._oldCenterFrequency = this._centerFrequency; + this._changingCenterFrequency = true; + } + } + else if (e.Button == MouseButtons.Right) + { + this.UpdateFrequency(this._frequency / 500 * 500, FrequencyChangeSource.Click); + } + } + } + + protected override void OnMouseUp(MouseEventArgs e) + { + base.OnMouseUp(e); + if (this._enableFilterMove && this._changingCenterFrequency && e.X == this._oldX) + { + long f = (long)(((float)this._oldX - (float)this._buffer.Width * 0.5f) * (float)this._spectrumWidth / this._scale / (float)(this._buffer.Width - 60) + (float)this._displayCenterFrequency); + this.UpdateFrequency(f, FrequencyChangeSource.Click); + } + this._changingCenterFrequency = false; + this._changingBandwidth = false; + this._changingFrequency = false; + this._performNeeded = true; + } + + protected override void OnMouseMove(MouseEventArgs e) + { + base.OnMouseMove(e); + this._cursorPosition.X = e.X; + this._cursorPosition.Y = e.Y; + if (this._enableHotTracking) + { + this._snappedX = (float)e.X; + this._trackingFrequency = this.PointToFrequency((float)e.X); + if (this._useSnap) + { + this._trackingFrequency = (long)((float)this._trackingFrequency + (float)(Math.Sign(this._trackingFrequency) * this._stepSize) * 0.5f) / this._stepSize * this._stepSize; + this._snappedX = this.FrequencyToPoint(this._trackingFrequency); + } + } + if (this._changingFrequency) + { + long f = (long)((float)((e.X - this._oldX) * this._spectrumWidth) / this._scale / (float)(this._buffer.Width - 60) + (float)this._oldFrequency); + this.UpdateFrequency(f, FrequencyChangeSource.Drag); + } + else if (this._changingCenterFrequency) + { + long f2 = (long)((float)((this._oldX - e.X) * this._spectrumWidth) / this._scale / (float)(this._buffer.Width - 60) + (float)this._oldCenterFrequency); + this.UpdateCenterFrequency(f2, FrequencyChangeSource.Drag); + } + else if (this._changingBandwidth) + { + int num = 0; + switch (this._side) + { + case BandType.Upper: + num = e.X - this._oldX; + break; + case BandType.Lower: + num = this._oldX - e.X; + break; + } + if (this._bandType == BandType.Center && !this._enableSideFilterResize) + { + num *= 2; + } + num = (int)((float)(num * this._spectrumWidth) / this._scale / (float)(this._buffer.Width - 60) + (float)this._oldFilterBandwidth); + this.UpdateBandwidth(num); + } + else if (this._enableFilter) + { + if (e.X >= 30 && e.X <= this._buffer.Width - 30 && this._upper - this._lower > 12f) + { + if (Math.Abs((float)e.X - this._lower + 6f) <= 6f && (this._bandType == BandType.Center || this._bandType == BandType.Lower)) + { + goto IL_0267; + } + if (Math.Abs((float)e.X - this._upper - 6f) <= 6f && (this._bandType == BandType.Center || this._bandType == BandType.Upper)) + { + goto IL_0267; + } + this.Cursor = Cursors.Default; + } + else + { + this.Cursor = Cursors.Default; + } + } + goto IL_028c; + IL_028c: + this._performNeeded = this._enableHotTracking; + return; + IL_0267: + this.Cursor = Cursors.SizeWE; + goto IL_028c; + } + + protected override void OnMouseEnter(EventArgs e) + { + base.Focus(); + base.OnMouseEnter(e); + this._mouseIn = true; + this._performNeeded = true; + } + + protected override void OnMouseLeave(EventArgs e) + { + base.OnMouseLeave(e); + this._mouseIn = false; + this._performNeeded = true; + this._cursorPosition = Point.Empty; + } + + protected override void OnMouseWheel(MouseEventArgs e) + { + base.OnMouseWheel(e); + if (this._enableFilter) + { + this.UpdateFrequency(this._frequency + this._stepSize * Math.Sign(e.Delta), FrequencyChangeSource.Scroll); + } + } + } +} diff --git a/SDRSharp.PanView/refs Radio.txt b/SDRSharp.PanView/refs Radio.txt new file mode 100644 index 0000000..e69de29 diff --git a/SDRSharp.Radio/PortAudioSharp/PaDeviceIndex.cs b/SDRSharp.Radio/PortAudioSharp/PaDeviceIndex.cs new file mode 100644 index 0000000..4e9c484 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaDeviceIndex.cs @@ -0,0 +1,8 @@ +namespace PortAudioSharp +{ + internal enum PaDeviceIndex + { + PaNoDevice = -1, + PaUseHostApiSpecificDeviceSpecification = -2 + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaDeviceInfo.cs b/SDRSharp.Radio/PortAudioSharp/PaDeviceInfo.cs new file mode 100644 index 0000000..ec36b61 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaDeviceInfo.cs @@ -0,0 +1,33 @@ +using System.Runtime.InteropServices; + +namespace PortAudioSharp +{ + internal struct PaDeviceInfo + { + public int structVersion; + + [MarshalAs(UnmanagedType.LPStr)] + public string name; + + public int hostApi; + + public int maxInputChannels; + + public int maxOutputChannels; + + public double defaultLowInputLatency; + + public double defaultLowOutputLatency; + + public double defaultHighInputLatency; + + public double defaultHighOutputLatency; + + public double defaultSampleRate; + + public override string ToString() + { + return "[" + ((object)this).GetType().Name + "]\nname: " + this.name + "\nhostApi: " + this.hostApi + "\nmaxInputChannels: " + this.maxInputChannels + "\nmaxOutputChannels: " + this.maxOutputChannels + "\ndefaultLowInputLatency: " + this.defaultLowInputLatency + "\ndefaultLowOutputLatency: " + this.defaultLowOutputLatency + "\ndefaultHighInputLatency: " + this.defaultHighInputLatency + "\ndefaultHighOutputLatency: " + this.defaultHighOutputLatency + "\ndefaultSampleRate: " + this.defaultSampleRate; + } + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaError.cs b/SDRSharp.Radio/PortAudioSharp/PaError.cs new file mode 100644 index 0000000..7d59089 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaError.cs @@ -0,0 +1,36 @@ +namespace PortAudioSharp +{ + internal enum PaError + { + paNoError, + paNotInitialized = -10000, + paUnanticipatedHostError, + paInvalidChannelCount, + paInvalidSampleRate, + paInvalidDevice, + paInvalidFlag, + paSampleFormatNotSupported, + paBadIODeviceCombination, + paInsufficientMemory, + paBufferTooBig, + paBufferTooSmall, + paNullCallback, + paBadStreamPtr, + paTimedOut, + paInternalError, + paDeviceUnavailable, + paIncompatibleHostApiSpecificStreamInfo, + paStreamIsStopped, + paStreamIsNotStopped, + paInputOverflowed, + paOutputUnderflowed, + paHostApiNotFound, + paInvalidHostApi, + paCanNotReadFromACallbackStream, + paCanNotWriteToACallbackStream, + paCanNotReadFromAnOutputOnlyStream, + paCanNotWriteToAnInputOnlyStream, + paIncompatibleStreamHostApi, + paBadBufferPtr + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaHostApiInfo.cs b/SDRSharp.Radio/PortAudioSharp/PaHostApiInfo.cs new file mode 100644 index 0000000..458532b --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaHostApiInfo.cs @@ -0,0 +1,25 @@ +using System.Runtime.InteropServices; + +namespace PortAudioSharp +{ + internal struct PaHostApiInfo + { + public int structVersion; + + public PaHostApiTypeId type; + + [MarshalAs(UnmanagedType.LPStr)] + public string name; + + public int deviceCount; + + public int defaultInputDevice; + + public int defaultOutputDevice; + + public override string ToString() + { + return "[" + ((object)this).GetType().Name + "]\nstructVersion: " + this.structVersion + "\ntype: " + this.type + "\nname: " + this.name + "\ndeviceCount: " + this.deviceCount + "\ndefaultInputDevice: " + this.defaultInputDevice + "\ndefaultOutputDevice: " + this.defaultOutputDevice; + } + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaHostApiTypeId.cs b/SDRSharp.Radio/PortAudioSharp/PaHostApiTypeId.cs new file mode 100644 index 0000000..bad7979 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaHostApiTypeId.cs @@ -0,0 +1,20 @@ +namespace PortAudioSharp +{ + internal enum PaHostApiTypeId : uint + { + paInDevelopment, + paDirectSound, + paMME, + paASIO, + paSoundManager, + paCoreAudio, + paOSS = 7u, + paALSA, + paAL, + paBeOS, + paWDMKS, + paJACK, + paWASAPI, + paAudioScienceHPI + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaHostErrorInfo.cs b/SDRSharp.Radio/PortAudioSharp/PaHostErrorInfo.cs new file mode 100644 index 0000000..6b06da1 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaHostErrorInfo.cs @@ -0,0 +1,19 @@ +using System.Runtime.InteropServices; + +namespace PortAudioSharp +{ + internal struct PaHostErrorInfo + { + public PaHostApiTypeId hostApiType; + + public int errorCode; + + [MarshalAs(UnmanagedType.LPStr)] + public string errorText; + + public override string ToString() + { + return "[" + ((object)this).GetType().Name + "]\nhostApiType: " + this.hostApiType + "\nerrorCode: " + this.errorCode + "\nerrorText: " + this.errorText; + } + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaSampleFormat.cs b/SDRSharp.Radio/PortAudioSharp/PaSampleFormat.cs new file mode 100644 index 0000000..f4200c8 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaSampleFormat.cs @@ -0,0 +1,14 @@ +namespace PortAudioSharp +{ + internal enum PaSampleFormat : uint + { + PaFloat32 = 1u, + PaInt32, + PaInt24 = 4u, + PaInt16 = 8u, + PaInt8 = 0x10, + PaUInt8 = 0x20, + PaCustomFormat = 0x10000, + PaNonInterleaved = 0x80000000 + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackDelegate.cs b/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackDelegate.cs new file mode 100644 index 0000000..4ec6754 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackDelegate.cs @@ -0,0 +1,8 @@ +using System; +using System.Runtime.InteropServices; + +namespace PortAudioSharp +{ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal unsafe delegate PaStreamCallbackResult PaStreamCallbackDelegate(float* input, float* output, uint frameCount, ref PaStreamCallbackTimeInfo timeInfo, PaStreamCallbackFlags statusFlags, IntPtr userData); +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackFlags.cs b/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackFlags.cs new file mode 100644 index 0000000..3537556 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackFlags.cs @@ -0,0 +1,11 @@ +namespace PortAudioSharp +{ + internal enum PaStreamCallbackFlags : uint + { + PaInputUnderflow = 1u, + PaInputOverflow, + PaOutputUnderflow = 4u, + PaOutputOverflow = 8u, + PaPrimingOutput = 0x10 + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackResult.cs b/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackResult.cs new file mode 100644 index 0000000..363c251 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackResult.cs @@ -0,0 +1,9 @@ +namespace PortAudioSharp +{ + internal enum PaStreamCallbackResult : uint + { + PaContinue, + PaComplete, + PaAbort + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackTimeInfo.cs b/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackTimeInfo.cs new file mode 100644 index 0000000..463f160 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaStreamCallbackTimeInfo.cs @@ -0,0 +1,16 @@ +namespace PortAudioSharp +{ + internal struct PaStreamCallbackTimeInfo + { + public double inputBufferAdcTime; + + public double currentTime; + + public double outputBufferDacTime; + + public override string ToString() + { + return "[" + ((object)this).GetType().Name + "]\ncurrentTime: " + this.currentTime + "\ninputBufferAdcTime: " + this.inputBufferAdcTime + "\noutputBufferDacTime: " + this.outputBufferDacTime; + } + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaStreamFinishedCallbackDelegate.cs b/SDRSharp.Radio/PortAudioSharp/PaStreamFinishedCallbackDelegate.cs new file mode 100644 index 0000000..82da18c --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaStreamFinishedCallbackDelegate.cs @@ -0,0 +1,8 @@ +using System; +using System.Runtime.InteropServices; + +namespace PortAudioSharp +{ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void PaStreamFinishedCallbackDelegate(IntPtr userData); +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaStreamFlags.cs b/SDRSharp.Radio/PortAudioSharp/PaStreamFlags.cs new file mode 100644 index 0000000..11b9627 --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaStreamFlags.cs @@ -0,0 +1,12 @@ +namespace PortAudioSharp +{ + internal enum PaStreamFlags : uint + { + PaNoFlag, + PaClipOff, + PaDitherOff, + PaNeverDropInput = 4u, + PaPrimeOutputBuffersUsingStreamCallback = 8u, + PaPlatformSpecificFlags = 4294901760u + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaStreamInfo.cs b/SDRSharp.Radio/PortAudioSharp/PaStreamInfo.cs new file mode 100644 index 0000000..64aa21f --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaStreamInfo.cs @@ -0,0 +1,18 @@ +namespace PortAudioSharp +{ + internal struct PaStreamInfo + { + public int structVersion; + + public double inputLatency; + + public double outputLatency; + + public double sampleRate; + + public override string ToString() + { + return "[" + ((object)this).GetType().Name + "]\nstructVersion: " + this.structVersion + "\ninputLatency: " + this.inputLatency + "\noutputLatency: " + this.outputLatency + "\nsampleRate: " + this.sampleRate; + } + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PaStreamParameters.cs b/SDRSharp.Radio/PortAudioSharp/PaStreamParameters.cs new file mode 100644 index 0000000..8a9ca6d --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PaStreamParameters.cs @@ -0,0 +1,22 @@ +using System; + +namespace PortAudioSharp +{ + internal struct PaStreamParameters + { + public int device; + + public int channelCount; + + public PaSampleFormat sampleFormat; + + public double suggestedLatency; + + public IntPtr hostApiSpecificStreamInfo; + + public override string ToString() + { + return "[" + ((object)this).GetType().Name + "]\ndevice: " + this.device + "\nchannelCount: " + this.channelCount + "\nsampleFormat: " + this.sampleFormat + "\nsuggestedLatency: " + this.suggestedLatency; + } + } +} diff --git a/SDRSharp.Radio/PortAudioSharp/PortAudioAPI.cs b/SDRSharp.Radio/PortAudioSharp/PortAudioAPI.cs new file mode 100644 index 0000000..4dba8fc --- /dev/null +++ b/SDRSharp.Radio/PortAudioSharp/PortAudioAPI.cs @@ -0,0 +1,202 @@ +using System; +using System.Runtime.InteropServices; + +namespace PortAudioSharp +{ + internal static class PortAudioAPI + { + public const int PaFormatIsSupported = 0; + + public const int PaFramesPerBufferUnspecified = 0; + + private const string PortAudioLibrary = "portaudio"; + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_GetVersion(); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Pa_GetVersionText")] + private static extern IntPtr IntPtr_Pa_GetVersionText(); + + public static string Pa_GetVersionText() + { + return Marshal.PtrToStringAnsi(PortAudioAPI.IntPtr_Pa_GetVersionText()); + } + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Pa_GetErrorText")] + public static extern IntPtr IntPtr_Pa_GetErrorText(PaError errorCode); + + public static string Pa_GetErrorText(PaError errorCode) + { + return Marshal.PtrToStringAnsi(PortAudioAPI.IntPtr_Pa_GetErrorText(errorCode)); + } + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_Initialize(); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_Terminate(); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_GetHostApiCount(); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_GetDefaultHostApi(); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Pa_GetHostApiInfo")] + public static extern IntPtr IntPtr_Pa_GetHostApiInfo(int hostApi); + + public static PaHostApiInfo Pa_GetHostApiInfo(int hostApi) + { + return (PaHostApiInfo)Marshal.PtrToStructure(PortAudioAPI.IntPtr_Pa_GetHostApiInfo(hostApi), typeof(PaHostApiInfo)); + } + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_HostApiTypeIdToHostApiIndex(PaHostApiTypeId type); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_HostApiDeviceIndexToDeviceIndex(int hostApi, int hostApiDeviceIndex); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Pa_GetLastHostErrorInfo")] + public static extern IntPtr IntPtr_Pa_GetLastHostErrorInfo(); + + public static PaHostErrorInfo Pa_GetLastHostErrorInfo() + { + return (PaHostErrorInfo)Marshal.PtrToStructure(PortAudioAPI.IntPtr_Pa_GetLastHostErrorInfo(), typeof(PaHostErrorInfo)); + } + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_GetDeviceCount(); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_GetDefaultInputDevice(); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_GetDefaultOutputDevice(); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Pa_GetDeviceInfo")] + public static extern IntPtr IntPtr_Pa_GetDeviceInfo(int device); + + public static PaDeviceInfo Pa_GetDeviceInfo(int device) + { + return (PaDeviceInfo)Marshal.PtrToStructure(PortAudioAPI.IntPtr_Pa_GetDeviceInfo(device), typeof(PaDeviceInfo)); + } + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_IsFormatSupported(ref PaStreamParameters inputParameters, ref PaStreamParameters outputParameters, double sampleRate); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_IsFormatSupported(IntPtr inputParameters, ref PaStreamParameters outputParameters, double sampleRate); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_IsFormatSupported(ref PaStreamParameters inputParameters, IntPtr outputParameters, double sampleRate); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_OpenStream(out IntPtr stream, ref PaStreamParameters inputParameters, ref PaStreamParameters outputParameters, double sampleRate, uint framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallbackDelegate streamCallback, IntPtr userData); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_OpenStream(out IntPtr stream, IntPtr inputParameters, ref PaStreamParameters outputParameters, double sampleRate, uint framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallbackDelegate streamCallback, IntPtr userData); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_OpenStream(out IntPtr stream, ref PaStreamParameters inputParameters, IntPtr outputParameters, double sampleRate, uint framesPerBuffer, PaStreamFlags streamFlags, PaStreamCallbackDelegate streamCallback, IntPtr userData); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_OpenDefaultStream(out IntPtr stream, int numInputChannels, int numOutputChannels, uint sampleFormat, double sampleRate, uint framesPerBuffer, PaStreamCallbackDelegate streamCallback, IntPtr userData); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_CloseStream(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_SetStreamFinishedCallback(ref IntPtr stream, [MarshalAs(UnmanagedType.FunctionPtr)] PaStreamFinishedCallbackDelegate streamFinishedCallback); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_StartStream(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_StopStream(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_AbortStream(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_IsStreamStopped(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_IsStreamActive(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Pa_GetStreamInfo")] + public static extern IntPtr IntPtr_Pa_GetStreamInfo(IntPtr stream); + + public static PaStreamInfo Pa_GetStreamInfo(IntPtr stream) + { + return (PaStreamInfo)Marshal.PtrToStructure(PortAudioAPI.IntPtr_Pa_GetStreamInfo(stream), typeof(PaStreamInfo)); + } + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern double Pa_GetStreamTime(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern double Pa_GetStreamCpuLoad(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_ReadStream(IntPtr stream, [Out] float[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_ReadStream(IntPtr stream, [Out] byte[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_ReadStream(IntPtr stream, [Out] sbyte[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_ReadStream(IntPtr stream, [Out] ushort[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_ReadStream(IntPtr stream, [Out] short[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_ReadStream(IntPtr stream, [Out] uint[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_ReadStream(IntPtr stream, [Out] int[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_ReadStream(IntPtr stream, IntPtr buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_WriteStream(IntPtr stream, [In] float[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_WriteStream(IntPtr stream, [In] byte[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_WriteStream(IntPtr stream, [In] sbyte[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_WriteStream(IntPtr stream, [In] ushort[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_WriteStream(IntPtr stream, [In] short[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_WriteStream(IntPtr stream, [In] uint[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_WriteStream(IntPtr stream, [In] int[] buffer, uint frames); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_GetStreamReadAvailable(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern int Pa_GetStreamWriteAvailable(IntPtr stream); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern PaError Pa_GetSampleSize(PaSampleFormat format); + + [DllImport("portaudio", CallingConvention = CallingConvention.Cdecl)] + public static extern void Pa_Sleep(int msec); + + static PortAudioAPI() + { + PortAudioAPI.Pa_Initialize(); + } + } +} diff --git a/SDRSharp.Radio/Properties/AssemblyInfo.cs b/SDRSharp.Radio/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2454348 --- /dev/null +++ b/SDRSharp.Radio/Properties/AssemblyInfo.cs @@ -0,0 +1,15 @@ +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Security.Permissions; + +[assembly: CompilationRelaxations(8)] +[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] +[assembly: AssemblyTitle("Radio DSP")] +[assembly: AssemblyDescription("Radio DSP")] +[assembly: AssemblyProduct("SDR#")] +[assembly: AssemblyCopyright("Copyright © Youssef TOUIL 2012")] +[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] +[assembly: AssemblyVersion("0.0.0.0")] diff --git a/SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioBufferAvailableDelegate.cs b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioBufferAvailableDelegate.cs new file mode 100644 index 0000000..01c1618 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioBufferAvailableDelegate.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.Radio.PortAudio +{ + public unsafe delegate void AudioBufferAvailableDelegate(float* buffer, int length); +} diff --git a/SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioBufferNeededDelegate.cs b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioBufferNeededDelegate.cs new file mode 100644 index 0000000..eda7799 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioBufferNeededDelegate.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.Radio.PortAudio +{ + public unsafe delegate void AudioBufferNeededDelegate(float* buffer, int length); +} diff --git a/SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioDevice.cs b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioDevice.cs new file mode 100644 index 0000000..6a112a8 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/AudioDevice.cs @@ -0,0 +1,68 @@ +using PortAudioSharp; +using System.Collections.Generic; + +namespace SDRSharp.Radio.PortAudio +{ + public class AudioDevice + { + public int Index + { + get; + set; + } + + public string Name + { + get; + set; + } + + public string Host + { + get; + set; + } + + public DeviceDirection Direction + { + get; + set; + } + + public bool IsDefault + { + get; + set; + } + + public static List GetDevices(DeviceDirection direction) + { + List list = new List(); + int num = PortAudioAPI.Pa_GetDefaultInputDevice(); + int num2 = PortAudioAPI.Pa_GetDefaultOutputDevice(); + int num3 = PortAudioAPI.Pa_GetDeviceCount(); + for (int i = 0; i < num3; i++) + { + PaDeviceInfo paDeviceInfo = PortAudioAPI.Pa_GetDeviceInfo(i); + DeviceDirection deviceDirection = (paDeviceInfo.maxInputChannels <= 0) ? DeviceDirection.Output : ((paDeviceInfo.maxOutputChannels > 0) ? DeviceDirection.InputOutput : DeviceDirection.Input); + if (deviceDirection == direction || deviceDirection == DeviceDirection.InputOutput) + { + PaHostApiInfo paHostApiInfo = PortAudioAPI.Pa_GetHostApiInfo(paDeviceInfo.hostApi); + AudioDevice audioDevice = new AudioDevice(); + audioDevice.Name = paDeviceInfo.name; + audioDevice.Host = paHostApiInfo.name; + audioDevice.Index = i; + audioDevice.Direction = deviceDirection; + audioDevice.IsDefault = (i == num || i == num2); + list.Add(audioDevice); + } + } + return list; + } + + public override string ToString() + { + return "[" + this.Host + "] " + this.Name; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio.PortAudio/DeviceDirection.cs b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/DeviceDirection.cs new file mode 100644 index 0000000..04575fa --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/DeviceDirection.cs @@ -0,0 +1,9 @@ +namespace SDRSharp.Radio.PortAudio +{ + public enum DeviceDirection + { + Input, + Output, + InputOutput + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio.PortAudio/Int24.cs b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/Int24.cs new file mode 100644 index 0000000..7ce3951 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/Int24.cs @@ -0,0 +1,16 @@ +namespace SDRSharp.Radio.PortAudio +{ + public struct Int24 + { + public byte C; + + public byte B; + + public sbyte A; + + public static implicit operator float(Int24 i) + { + return (float)((i.C << 8 | i.B << 16 | i.A << 24) >> 8); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveDuplex.cs b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveDuplex.cs new file mode 100644 index 0000000..227cfd6 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveDuplex.cs @@ -0,0 +1,83 @@ +using PortAudioSharp; +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio.PortAudio +{ + public class WaveDuplex : IDisposable + { + private IntPtr _streamHandle; + + private GCHandle _gcHandle; + + private readonly AudioBufferAvailableDelegate _bufferAvailable; + + private unsafe readonly PaStreamCallbackDelegate _paCallback = WaveDuplex.PaStreamCallback; + + public unsafe WaveDuplex(int deviceIndex, double sampleRate, int framesPerBuffer, AudioBufferAvailableDelegate bufferNeededDelegate) + { + this._bufferAvailable = bufferNeededDelegate; + PaStreamParameters paStreamParameters = new PaStreamParameters + { + device = deviceIndex, + channelCount = 2, + suggestedLatency = 0.0, + sampleFormat = PaSampleFormat.PaFloat32 + }; + PaError paError = PortAudioAPI.Pa_IsFormatSupported(ref paStreamParameters, ref paStreamParameters, sampleRate); + if (paError != 0) + { + throw new ApplicationException(paError.ToString()); + } + this._gcHandle = GCHandle.Alloc(this); + paError = PortAudioAPI.Pa_OpenStream(out this._streamHandle, ref paStreamParameters, ref paStreamParameters, sampleRate, (uint)framesPerBuffer, PaStreamFlags.PaNoFlag, this._paCallback, (IntPtr)this._gcHandle); + if (paError != 0) + { + this._gcHandle.Free(); + throw new ApplicationException(paError.ToString()); + } + paError = PortAudioAPI.Pa_StartStream(this._streamHandle); + if (paError == PaError.paNoError) + { + return; + } + PortAudioAPI.Pa_CloseStream(this._streamHandle); + this._gcHandle.Free(); + throw new ApplicationException(paError.ToString()); + } + + private unsafe static PaStreamCallbackResult PaStreamCallback(float* input, float* output, uint frameCount, ref PaStreamCallbackTimeInfo timeInfo, PaStreamCallbackFlags statusFlags, IntPtr userData) + { + GCHandle gCHandle = GCHandle.FromIntPtr(userData); + if (!gCHandle.IsAllocated) + { + return PaStreamCallbackResult.PaAbort; + } + WaveDuplex waveDuplex = (WaveDuplex)gCHandle.Target; + try + { + Utils.Memcpy(output, input, (int)(frameCount * 2 * 4)); + if (waveDuplex._bufferAvailable != null) + { + waveDuplex._bufferAvailable(output, (int)frameCount); + } + } + catch + { + return PaStreamCallbackResult.PaAbort; + } + return PaStreamCallbackResult.PaContinue; + } + + public void Dispose() + { + if (this._streamHandle != IntPtr.Zero) + { + PortAudioAPI.Pa_StopStream(this._streamHandle); + PortAudioAPI.Pa_CloseStream(this._streamHandle); + this._streamHandle = IntPtr.Zero; + } + this._gcHandle.Free(); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveFile.cs b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveFile.cs new file mode 100644 index 0000000..acb668d --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveFile.cs @@ -0,0 +1,298 @@ +using System; +using System.IO; +using System.Text; + +namespace SDRSharp.Radio.PortAudio +{ + public sealed class WaveFile : IDisposable + { + private unsafe static readonly float* _lutu8; + + private static readonly UnsafeBuffer _lutu8Buffer; + + private unsafe static readonly float* _lut16; + + private static readonly UnsafeBuffer _lut16Buffer; + + private readonly Stream _stream; + + private bool _isPCM; + + private long _dataPos; + + private short _formatTag; + + private int _sampleRate; + + private int _avgBytesPerSec; + + private int _length; + + private short _blockAlign; + + private short _bitsPerSample; + + private UnsafeBuffer _tempBuffer; + + private byte[] _temp; + + private unsafe byte* _tempPtr; + + public long Position + { + get + { + return this._stream.Position - this._dataPos; + } + set + { + this._stream.Seek(value + this._dataPos, SeekOrigin.Begin); + } + } + + public short FormatTag + { + get + { + return this._formatTag; + } + } + + public int SampleRate + { + get + { + return this._sampleRate; + } + } + + public int AvgBytesPerSec + { + get + { + return this._avgBytesPerSec; + } + } + + public short BlockAlign + { + get + { + return this._blockAlign; + } + } + + public short BitsPerSample + { + get + { + return this._bitsPerSample; + } + } + + public int Length + { + get + { + return this._length; + } + } + + unsafe static WaveFile() + { + WaveFile._lutu8Buffer = UnsafeBuffer.Create(256, 4); + WaveFile._lut16Buffer = UnsafeBuffer.Create(65536, 4); + WaveFile._lutu8 = (float*)(void*)WaveFile._lutu8Buffer; + for (int i = 0; i < 256; i++) + { + WaveFile._lutu8[i] = (float)(i - 128) * 0.007874016f; + } + WaveFile._lut16 = (float*)(void*)WaveFile._lut16Buffer; + for (int j = 0; j < 65536; j++) + { + WaveFile._lut16[j] = (float)(j - 32768) * 3.051851E-05f; + } + } + + ~WaveFile() + { + this.Dispose(); + } + + public WaveFile(string fileName) + { + this._stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); + this.ReadHeader(); + } + + public void Dispose() + { + this.Close(); + GC.SuppressFinalize(this); + } + + public void Close() + { + if (this._stream != null) + { + this._stream.Close(); + } + } + + private static string ReadChunk(BinaryReader reader) + { + byte[] array = new byte[4]; + reader.Read(array, 0, array.Length); + return Encoding.ASCII.GetString(array); + } + + private void ReadHeader() + { + BinaryReader binaryReader = new BinaryReader(this._stream); + if (WaveFile.ReadChunk(binaryReader) != "RIFF") + { + throw new Exception("Invalid file format"); + } + binaryReader.ReadInt32(); + if (WaveFile.ReadChunk(binaryReader) != "WAVE") + { + throw new Exception("Invalid file format"); + } + if (WaveFile.ReadChunk(binaryReader) != "fmt ") + { + throw new Exception("Invalid file format"); + } + int num = binaryReader.ReadInt32(); + if (num < 16) + { + throw new Exception("Invalid file format"); + } + this._formatTag = binaryReader.ReadInt16(); + this._isPCM = (this._formatTag == 1); + if (binaryReader.ReadInt16() != 2) + { + throw new Exception("Invalid file format"); + } + this._sampleRate = binaryReader.ReadInt32(); + this._avgBytesPerSec = binaryReader.ReadInt32(); + this._blockAlign = binaryReader.ReadInt16(); + this._bitsPerSample = binaryReader.ReadInt16(); + for (num -= 16; num > 0; num--) + { + binaryReader.ReadByte(); + } + while (this._stream.Position < this._stream.Length && WaveFile.ReadChunk(binaryReader) != "data") + { + num = binaryReader.ReadInt32(); + while (this._stream.Position < this._stream.Length && num > 0) + { + binaryReader.ReadByte(); + num--; + } + } + if (this._stream.Position >= this._stream.Length) + { + throw new Exception("Invalid file format"); + } + this._length = binaryReader.ReadInt32(); + this._dataPos = this._stream.Position; + } + + public unsafe void Read(Complex* iqBuffer, int length) + { + if (this._temp == null || this._temp.Length != this._blockAlign * length) + { + this._temp = new byte[this._blockAlign * length]; + this._tempBuffer = UnsafeBuffer.Create(this._temp); + this._tempPtr = (byte*)(void*)this._tempBuffer; + } + int i = 0; + int num2; + for (int length2 = this._tempBuffer.Length; i < length2; i += num2) + { + int num = length2 - i; + num2 = this._stream.Read(this._temp, i, num); + if (num2 < num) + { + this._stream.Position = this._dataPos; + } + } + this.FillIQ(iqBuffer, length); + } + + private unsafe void FillIQ(Complex* iqPtr, int length) + { + if (this._isPCM) + { + if (this._blockAlign == 6) + { + Int24* ptr = (Int24*)this._tempPtr; + for (int i = 0; i < length; i++) + { + Complex* intPtr = iqPtr; + Int24* intPtr2 = ptr; + ptr = intPtr2 + 1; + intPtr->Real = (float)(*intPtr2) * 1.192093E-07f; + Complex* intPtr3 = iqPtr; + Int24* intPtr4 = ptr; + ptr = intPtr4 + 1; + intPtr3->Imag = (float)(*intPtr4) * 1.192093E-07f; + iqPtr++; + } + } + else if (this._blockAlign == 4) + { + short* ptr2 = (short*)this._tempPtr; + for (int j = 0; j < length; j++) + { + Complex* intPtr5 = iqPtr; + float* lut = WaveFile._lut16; + short* intPtr6 = ptr2; + ptr2 = intPtr6 + 1; + intPtr5->Real = lut[*intPtr6 + 32768]; + Complex* intPtr7 = iqPtr; + float* lut2 = WaveFile._lut16; + short* intPtr8 = ptr2; + ptr2 = intPtr8 + 1; + intPtr7->Imag = lut2[*intPtr8 + 32768]; + iqPtr++; + } + } + else if (this._blockAlign == 2) + { + byte* ptr3 = this._tempPtr; + for (int k = 0; k < length; k++) + { + Complex* intPtr9 = iqPtr; + float* lutu = WaveFile._lutu8; + byte* intPtr10 = ptr3; + ptr3 = intPtr10 + 1; + intPtr9->Real = lutu[(int)(*intPtr10)]; + Complex* intPtr11 = iqPtr; + float* lutu2 = WaveFile._lutu8; + byte* intPtr12 = ptr3; + ptr3 = intPtr12 + 1; + intPtr11->Imag = lutu2[(int)(*intPtr12)]; + iqPtr++; + } + } + } + else + { + float* ptr4 = (float*)this._tempPtr; + for (int l = 0; l < length; l++) + { + Complex* intPtr13 = iqPtr; + float* intPtr14 = ptr4; + ptr4 = intPtr14 + 1; + intPtr13->Real = *intPtr14; + Complex* intPtr15 = iqPtr; + float* intPtr16 = ptr4; + ptr4 = intPtr16 + 1; + intPtr15->Imag = *intPtr16; + iqPtr++; + } + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WavePlayer.cs b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WavePlayer.cs new file mode 100644 index 0000000..8336e74 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WavePlayer.cs @@ -0,0 +1,82 @@ +using PortAudioSharp; +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio.PortAudio +{ + public class WavePlayer : IDisposable + { + private IntPtr _streamHandle; + + private GCHandle _gcHandle; + + private readonly AudioBufferNeededDelegate _bufferNeeded; + + private unsafe readonly PaStreamCallbackDelegate _paCallback = WavePlayer.PaStreamCallback; + + public unsafe WavePlayer(int deviceIndex, double sampleRate, int framesPerBuffer, AudioBufferNeededDelegate bufferNeededDelegate) + { + this._bufferNeeded = bufferNeededDelegate; + PaStreamParameters paStreamParameters = new PaStreamParameters + { + device = deviceIndex, + channelCount = 2, + suggestedLatency = 0.0, + sampleFormat = PaSampleFormat.PaFloat32 + }; + PaError paError = PortAudioAPI.Pa_IsFormatSupported(IntPtr.Zero, ref paStreamParameters, sampleRate); + if (paError != 0) + { + throw new ApplicationException(paError.ToString()); + } + this._gcHandle = GCHandle.Alloc(this); + paError = PortAudioAPI.Pa_OpenStream(out this._streamHandle, IntPtr.Zero, ref paStreamParameters, sampleRate, (uint)framesPerBuffer, PaStreamFlags.PaNoFlag, this._paCallback, (IntPtr)this._gcHandle); + if (paError != 0) + { + this._gcHandle.Free(); + throw new ApplicationException(paError.ToString()); + } + paError = PortAudioAPI.Pa_StartStream(this._streamHandle); + if (paError == PaError.paNoError) + { + return; + } + PortAudioAPI.Pa_CloseStream(this._streamHandle); + this._gcHandle.Free(); + throw new ApplicationException(paError.ToString()); + } + + private unsafe static PaStreamCallbackResult PaStreamCallback(float* input, float* output, uint frameCount, ref PaStreamCallbackTimeInfo timeInfo, PaStreamCallbackFlags statusFlags, IntPtr userData) + { + GCHandle gCHandle = GCHandle.FromIntPtr(userData); + if (!gCHandle.IsAllocated) + { + return PaStreamCallbackResult.PaAbort; + } + WavePlayer wavePlayer = (WavePlayer)gCHandle.Target; + try + { + if (wavePlayer._bufferNeeded != null) + { + wavePlayer._bufferNeeded(output, (int)frameCount); + } + } + catch + { + return PaStreamCallbackResult.PaAbort; + } + return PaStreamCallbackResult.PaContinue; + } + + public void Dispose() + { + if (this._streamHandle != IntPtr.Zero) + { + PortAudioAPI.Pa_StopStream(this._streamHandle); + PortAudioAPI.Pa_CloseStream(this._streamHandle); + this._streamHandle = IntPtr.Zero; + } + this._gcHandle.Free(); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveRecorder.cs b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveRecorder.cs new file mode 100644 index 0000000..86de588 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.PortAudio/WaveRecorder.cs @@ -0,0 +1,82 @@ +using PortAudioSharp; +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio.PortAudio +{ + public class WaveRecorder : IDisposable + { + private IntPtr _streamHandle; + + private GCHandle _gcHandle; + + private readonly AudioBufferAvailableDelegate _bufferAvailable; + + private unsafe readonly PaStreamCallbackDelegate _paCallback = WaveRecorder.PaStreamCallback; + + public unsafe WaveRecorder(int deviceIndex, double sampleRate, int framesPerBuffer, AudioBufferAvailableDelegate bufferAvailable) + { + this._bufferAvailable = bufferAvailable; + PaStreamParameters paStreamParameters = new PaStreamParameters + { + device = deviceIndex, + channelCount = 2, + suggestedLatency = 0.0, + sampleFormat = PaSampleFormat.PaFloat32 + }; + PaError paError = PortAudioAPI.Pa_IsFormatSupported(ref paStreamParameters, IntPtr.Zero, sampleRate); + if (paError != 0) + { + throw new ApplicationException(paError.ToString()); + } + this._gcHandle = GCHandle.Alloc(this); + paError = PortAudioAPI.Pa_OpenStream(out this._streamHandle, ref paStreamParameters, IntPtr.Zero, sampleRate, (uint)framesPerBuffer, PaStreamFlags.PaNoFlag, this._paCallback, (IntPtr)this._gcHandle); + if (paError != 0) + { + this._gcHandle.Free(); + throw new ApplicationException(paError.ToString()); + } + paError = PortAudioAPI.Pa_StartStream(this._streamHandle); + if (paError == PaError.paNoError) + { + return; + } + PortAudioAPI.Pa_CloseStream(this._streamHandle); + this._gcHandle.Free(); + throw new ApplicationException(paError.ToString()); + } + + private unsafe static PaStreamCallbackResult PaStreamCallback(float* input, float* output, uint frameCount, ref PaStreamCallbackTimeInfo timeInfo, PaStreamCallbackFlags statusFlags, IntPtr userData) + { + GCHandle gCHandle = GCHandle.FromIntPtr(userData); + if (!gCHandle.IsAllocated) + { + return PaStreamCallbackResult.PaAbort; + } + WaveRecorder waveRecorder = (WaveRecorder)gCHandle.Target; + try + { + if (waveRecorder._bufferAvailable != null) + { + waveRecorder._bufferAvailable(input, (int)frameCount); + } + } + catch + { + return PaStreamCallbackResult.PaAbort; + } + return PaStreamCallbackResult.PaContinue; + } + + public void Dispose() + { + if (this._streamHandle != IntPtr.Zero) + { + PortAudioAPI.Pa_StopStream(this._streamHandle); + PortAudioAPI.Pa_CloseStream(this._streamHandle); + this._streamHandle = IntPtr.Zero; + } + this._gcHandle.Free(); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio.csproj b/SDRSharp.Radio/SDRSharp.Radio.csproj new file mode 100644 index 0000000..c5038c9 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.csproj @@ -0,0 +1,149 @@ + + + + {A24DD927-34EF-4301-BDF3-42C872BC944E} + Debug + AnyCPU + Library + SDRSharp.Radio + .NETFramework + v4.6 + 4 + True + + + AnyCPU + + + bin\Debug\ + true + full + false + + + bin\Release\ + true + pdbonly + true + + + + C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll + + + C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SDRSharp.Radio/SDRSharp.Radio.sln b/SDRSharp.Radio/SDRSharp.Radio.sln new file mode 100644 index 0000000..1d9e5df --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2015 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDRSharp.Radio", "SDRSharp.Radio.csproj", "{A24DD927-34EF-4301-BDF3-42C872BC944E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A24DD927-34EF-4301-BDF3-42C872BC944E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A24DD927-34EF-4301-BDF3-42C872BC944E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A24DD927-34EF-4301-BDF3-42C872BC944E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A24DD927-34EF-4301-BDF3-42C872BC944E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6BA50BE1-BD57-44A9-8AD3-3F881F01F86F} + EndGlobalSection +EndGlobal diff --git a/SDRSharp.Radio/SDRSharp.Radio/AmAntiFading.cs b/SDRSharp.Radio/SDRSharp.Radio/AmAntiFading.cs new file mode 100644 index 0000000..a6332af --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/AmAntiFading.cs @@ -0,0 +1,29 @@ +namespace SDRSharp.Radio +{ + public class AmAntiFading : OverlapAddProcessor + { + public AmAntiFading() + : base(4096) + { + } + + protected unsafe override void ProcessFft(Complex* buffer, int length) + { + for (int i = 1; i < length / 2 - 1; i++) + { + int num = i; + int num2 = length - i; + float num3 = buffer[num].ModulusSquared(); + float num4 = buffer[num2].ModulusSquared(); + if (num3 > num4) + { + buffer[num2] = buffer[num].Conjugate(); + } + else + { + buffer[num] = buffer[num2].Conjugate(); + } + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/AmDetector.cs b/SDRSharp.Radio/SDRSharp.Radio/AmDetector.cs new file mode 100644 index 0000000..e9a5bc0 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/AmDetector.cs @@ -0,0 +1,62 @@ +using System; + +namespace SDRSharp.Radio +{ + public sealed class AmDetector + { + private float _avg; + + private float _powerThreshold; + + private int _squelchThreshold; + + private bool _isSquelchOpen; + + public int SquelchThreshold + { + get + { + return this._squelchThreshold; + } + set + { + if (this._squelchThreshold != value) + { + this._squelchThreshold = value; + this._powerThreshold = ((float)this._squelchThreshold / 100f - 1f) * 100f - 50f; + } + } + } + + public bool IsSquelchOpen + { + get + { + return this._isSquelchOpen; + } + } + + public unsafe void Demodulate(Complex* iq, float* audio, int length) + { + for (int i = 0; i < length; i++) + { + float num = iq[i].Modulus(); + if (this._squelchThreshold == 0) + { + audio[i] = num; + } + else + { + float num2 = (float)(20.0 * Math.Log10(1E-60 + (double)num)); + this._avg = 0.99f * this._avg + 0.01f * num2; + this._isSquelchOpen = (this._avg > this._powerThreshold); + audio[i] = num; + if (!this._isSquelchOpen) + { + audio[i] *= 1E-15f; + } + } + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/AutomaticGainControl.cs b/SDRSharp.Radio/SDRSharp.Radio/AutomaticGainControl.cs new file mode 100644 index 0000000..c1bac24 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/AutomaticGainControl.cs @@ -0,0 +1,287 @@ +using System; + +namespace SDRSharp.Radio +{ + public sealed class AutomaticGainControl + { + private const float DelayTimeconst = 0.015f; + + private const float WindowTimeconst = 0.018f; + + private const float AttackRiseTimeconst = 0.002f; + + private const float AttackFallTimeconst = 0.005f; + + private const float DecayRisefallRatio = 0.3f; + + private const float ReleaseTimeconst = 0.05f; + + private const float AGCOutscale = 0.7f; + + private UnsafeBuffer _sigDelayBuf; + + private unsafe float* _sigDelayBufPtr; + + private UnsafeBuffer _magBuf; + + private unsafe float* _magBufPtr; + + private float _decayAve; + + private float _attackAve; + + private float _attackRiseAlpha; + + private float _attackFallAlpha; + + private float _decayRiseAlpha; + + private float _decayFallAlpha; + + private float _fixedGain; + + private float _knee; + + private float _gainSlope; + + private float _peak; + + private int _sigDelayPtr; + + private int _magBufPos; + + private int _delaySamples; + + private int _windowSamples; + + private int _hangTime; + + private int _hangTimer; + + private float _threshold; + + private float _slopeFactor; + + private float _decay; + + private double _sampleRate; + + private bool _useHang; + + public double SampleRate + { + get + { + return this._sampleRate; + } + set + { + if (this._sampleRate != value) + { + this._sampleRate = value; + this.Configure(true); + } + } + } + + public bool UseHang + { + get + { + return this._useHang; + } + set + { + if (this._useHang != value) + { + this._useHang = value; + this.Configure(false); + } + } + } + + public float Threshold + { + get + { + return this._threshold; + } + set + { + if (this._threshold != value) + { + this._threshold = value; + this.Configure(false); + } + } + } + + public float Slope + { + get + { + return this._slopeFactor; + } + set + { + if (this._slopeFactor != value) + { + this._slopeFactor = value; + this.Configure(false); + } + } + } + + public float Decay + { + get + { + return this._decay; + } + set + { + if (this._decay != value) + { + this._decay = value; + this.Configure(false); + } + } + } + + private unsafe void Configure(bool resetBuffers) + { + if (resetBuffers) + { + this._sigDelayPtr = 0; + this._hangTimer = 0; + this._peak = -16f; + this._decayAve = -5f; + this._attackAve = -5f; + this._magBufPos = 0; + if (this._sampleRate > 0.0) + { + this._delaySamples = (int)(this._sampleRate * 0.014999999664723873); + this._windowSamples = (int)(this._sampleRate * 0.017999999225139618); + this._sigDelayBuf = UnsafeBuffer.Create(this._delaySamples, 4); + this._sigDelayBufPtr = (float*)(void*)this._sigDelayBuf; + this._magBuf = UnsafeBuffer.Create(this._windowSamples, 4); + this._magBufPtr = (float*)(void*)this._magBuf; + for (int i = 0; i < this._windowSamples; i++) + { + this._magBufPtr[i] = -16f; + } + if (this._delaySamples >= this._sigDelayBuf.Length - 1) + { + this._delaySamples = this._sigDelayBuf.Length - 1; + } + } + } + this._knee = this._threshold / 20f; + this._gainSlope = this._slopeFactor / 100f; + this._fixedGain = 0.7f * (float)Math.Pow(10.0, (double)this._knee * ((double)this._gainSlope - 1.0)); + this._attackRiseAlpha = 1f - (float)Math.Exp(-1.0 / (this._sampleRate * 0.0020000000949949026)); + this._attackFallAlpha = 1f - (float)Math.Exp(-1.0 / (this._sampleRate * 0.004999999888241291)); + this._decayRiseAlpha = 1f - (float)Math.Exp(-1.0 / (this._sampleRate * (double)this.Decay * 0.001 * 0.30000001192092896)); + this._hangTime = (int)(this._sampleRate * (double)this.Decay * 0.001); + if (this._useHang) + { + this._decayFallAlpha = 1f - (float)Math.Exp(-1.0 / (this._sampleRate * 0.05000000074505806)); + } + else + { + this._decayFallAlpha = 1f - (float)Math.Exp(-1.0 / (this._sampleRate * (double)this.Decay * 0.001)); + } + } + + public unsafe void Process(float* buffer, int length) + { + for (int i = 0; i < length; i++) + { + float num = buffer[i]; + if ((double)num != 0.0) + { + num *= 1000f; + float num2 = this._sigDelayBufPtr[this._sigDelayPtr]; + this._sigDelayBufPtr[this._sigDelayPtr++] = num; + if (this._sigDelayPtr >= this._delaySamples) + { + this._sigDelayPtr = 0; + } + float num3 = (float)Math.Log10((double)Math.Abs(num)); + if (float.IsNaN(num3) || float.IsInfinity(num3)) + { + num3 = -8f; + } + float num4 = this._magBufPtr[this._magBufPos]; + this._magBufPtr[this._magBufPos++] = num3; + if (this._magBufPos >= this._windowSamples) + { + this._magBufPos = 0; + } + if (num3 > this._peak) + { + this._peak = num3; + } + else if (num4 == this._peak) + { + this._peak = -8f; + for (int j = 0; j < this._windowSamples; j++) + { + num4 = this._magBufPtr[j]; + if (num4 > this._peak) + { + this._peak = num4; + } + } + } + if (this.UseHang) + { + if (this._peak > this._attackAve) + { + this._attackAve = (1f - this._attackRiseAlpha) * this._attackAve + this._attackRiseAlpha * this._peak; + } + else + { + this._attackAve = (1f - this._attackFallAlpha) * this._attackAve + this._attackFallAlpha * this._peak; + } + if (this._peak > this._decayAve) + { + this._decayAve = (1f - this._decayRiseAlpha) * this._decayAve + this._decayRiseAlpha * this._peak; + this._hangTimer = 0; + } + else if (this._hangTimer < this._hangTime) + { + this._hangTimer++; + } + else + { + this._decayAve = (1f - this._decayFallAlpha) * this._decayAve + this._decayFallAlpha * this._peak; + } + } + else + { + if (this._peak > this._attackAve) + { + this._attackAve = (1f - this._attackRiseAlpha) * this._attackAve + this._attackRiseAlpha * this._peak; + } + else + { + this._attackAve = (1f - this._attackFallAlpha) * this._attackAve + this._attackFallAlpha * this._peak; + } + if (this._peak > this._decayAve) + { + this._decayAve = (1f - this._decayRiseAlpha) * this._decayAve + this._decayRiseAlpha * this._peak; + } + else + { + this._decayAve = (1f - this._decayFallAlpha) * this._decayAve + this._decayFallAlpha * this._peak; + } + } + num3 = ((this._attackAve > this._decayAve) ? this._attackAve : this._decayAve); + float num5 = (!(num3 <= this._knee)) ? (0.7f * (float)Math.Pow(10.0, (double)num3 * ((double)this._gainSlope - 1.0))) : this._fixedGain; + buffer[i] = num2 * num5 * 1E-05f; + } + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/BlockMode.cs b/SDRSharp.Radio/SDRSharp.Radio/BlockMode.cs new file mode 100644 index 0000000..5442bce --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/BlockMode.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.Radio +{ + public enum BlockMode + { + None, + BlockingRead, + BlockingWrite, + BlockingReadWrite + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/BufferNeededDelegate.cs b/SDRSharp.Radio/SDRSharp.Radio/BufferNeededDelegate.cs new file mode 100644 index 0000000..636fa33 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/BufferNeededDelegate.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.Radio +{ + public unsafe delegate void BufferNeededDelegate(Complex* iqBuffer, float* audioBuffer, int length); +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/CarrierLocker.cs b/SDRSharp.Radio/SDRSharp.Radio/CarrierLocker.cs new file mode 100644 index 0000000..012931e --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/CarrierLocker.cs @@ -0,0 +1,120 @@ +using System; + +namespace SDRSharp.Radio +{ + public class CarrierLocker + { + private const int PllRange = 2000; + + private const int PllBandwith = 10; + + private const float PllThreshold = 2f; + + private const float PllLockTime = 0.5f; + + private const float PllResumeDelay = 0.5f; + + private const float PllZeta = 1.5f; + + private const float PllPhaseAdjM = 0f; + + private const float PllPhaseAdjB = 0f; + + private const float TimeConst = 0.003f; + + private Pll _pll; + + private float _iavg; + + private float _qavg; + + private float _alpha; + + private int _unlockedCount; + + private int _maxUnlockedTicks; + + private bool _resetNeeded; + + private double _sampleRate; + + public double SampleRate + { + get + { + return this._sampleRate; + } + set + { + if (value != this._sampleRate) + { + this._sampleRate = value; + this.Configure(); + } + } + } + + public bool IsLocked + { + get + { + return this._pll.IsLocked; + } + } + + private void Configure() + { + this._pll.SampleRate = (float)this._sampleRate; + this._pll.DefaultFrequency = 0f; + this._pll.Range = 2000f; + this._pll.Bandwidth = 10f; + this._pll.Zeta = 1.5f; + this._pll.PhaseAdjM = 0f; + this._pll.PhaseAdjB = 0f; + this._pll.LockTime = 0.5f; + this._pll.LockThreshold = 2f; + this._alpha = (float)(1.0 - Math.Exp(-1.0 / (this._sampleRate * 0.0030000000260770321))); + this._maxUnlockedTicks = (int)(this._sampleRate * 0.5); + } + + public void Reset() + { + this._resetNeeded = true; + } + + public unsafe void Process(Complex* buffer, int length) + { + if (this._resetNeeded) + { + this._pll.Reset(); + this._resetNeeded = false; + } + for (int i = 0; i < length; i++) + { + Complex b = Complex.FromAngleFast(this._pll.Phase); + Complex* intPtr = buffer + i; + *intPtr *= b; + Complex complex = buffer[i]; + if (this._pll.StickOnFrequencyIfNotLocked || this._pll.IsLocked) + { + this._iavg += this._alpha * (complex.Real - this._iavg); + this._qavg += this._alpha * (complex.Imag - this._qavg); + complex.Real = this._iavg; + complex.Imag = this._qavg; + this._pll.StickOnFrequencyIfNotLocked = true; + if (this._pll.IsLocked) + { + this._unlockedCount = 0; + } + else if (++this._unlockedCount > this._maxUnlockedTicks) + { + this._pll.StickOnFrequencyIfNotLocked = false; + this._unlockedCount = 0; + } + } + complex *= b.Conjugate(); + this._pll.Process(complex); + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/CircularBuffer.cs b/SDRSharp.Radio/SDRSharp.Radio/CircularBuffer.cs new file mode 100644 index 0000000..adb7fde --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/CircularBuffer.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; + +namespace SDRSharp.Radio +{ + public class CircularBuffer : IDisposable + { + private readonly int _bufferSize; + + private readonly int _elementSize; + + private readonly int _maxBufferCount; + + private readonly SharpEvent _readEvent = new SharpEvent(false); + + private readonly SharpEvent _writeEvent = new SharpEvent(false); + + private int _count; + + private int _len; + + private int _head; + + private int _tail; + + private bool _closed; + + private List _buffers = new List(); + + public int BufferSize + { + get + { + return this._bufferSize; + } + } + + public int BufferCount + { + get + { + return this._maxBufferCount; + } + } + + public int AvailableCount + { + get + { + return this._count; + } + } + + protected CircularBuffer(int bufferSize, int elementSize, int maxBufferCount) + { + this._bufferSize = bufferSize; + this._elementSize = elementSize; + this._maxBufferCount = maxBufferCount; + for (int i = 0; i < this._maxBufferCount; i++) + { + this._buffers.Add(UnsafeBuffer.Create(this._bufferSize, this._elementSize)); + } + } + + ~CircularBuffer() + { + this.Dispose(); + } + + public void Dispose() + { + this.Close(); + GC.SuppressFinalize(this); + } + + protected unsafe bool Write(byte* buffer, int len, bool block) + { + int num = len; + while (num > 0 && !this._closed) + { + if (block) + { + while (this._count >= this._maxBufferCount && !this._closed) + { + this._writeEvent.WaitOne(); + } + } + else if (this._count >= this._maxBufferCount) + { + return false; + } + if (this._closed) + { + return false; + } + byte* ptr = (byte*)(void*)this._buffers[this._head]; + int num2 = Math.Min(this._bufferSize - this._len, num); + int num3 = num2 * this._elementSize; + Utils.Memcpy(ptr + this._len * this._elementSize, buffer, num3); + buffer += num3; + this._len += num2; + num -= num2; + if (this._len == this._bufferSize) + { + this._len = 0; + this._head = (this._head + 1) % this._maxBufferCount; + lock (this) + { + this._count++; + this._readEvent.Set(); + } + } + } + return true; + } + + protected unsafe void* AcquireRawBuffer(bool block) + { + if (this._closed) + { + return null; + } + if (block) + { + while (this._count == 0 && !this._closed) + { + this._readEvent.WaitOne(); + } + } + if (!this._closed && this._count != 0) + { + return this._buffers[this._tail]; + } + return null; + } + + public void Release() + { + if (!this._closed && this._count != 0) + { + this._tail = (this._tail + 1) % this._maxBufferCount; + lock (this) + { + this._count--; + this._writeEvent.Set(); + } + } + } + + public void Close() + { + this._closed = true; + this._readEvent.Set(); + this._writeEvent.Set(); + this._head = 0; + this._tail = 0; + this._count = 0; + this._len = 0; + lock (this) + { + foreach (UnsafeBuffer buffer in this._buffers) + { + buffer.Dispose(); + } + this._buffers.Clear(); + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/Complex.cs b/SDRSharp.Radio/SDRSharp.Radio/Complex.cs new file mode 100644 index 0000000..5b44fe1 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/Complex.cs @@ -0,0 +1,183 @@ +using System; + +namespace SDRSharp.Radio +{ + public struct Complex + { + public float Real; + + public float Imag; + + public Complex(float real, float imaginary) + { + this.Real = real; + this.Imag = imaginary; + } + + public Complex(Complex c) + { + this.Real = c.Real; + this.Imag = c.Imag; + } + + public float Modulus() + { + return (float)Math.Sqrt((double)this.ModulusSquared()); + } + + public float ModulusSquared() + { + return this.Real * this.Real + this.Imag * this.Imag; + } + + public float Argument() + { + return (float)Math.Atan2((double)this.Imag, (double)this.Real); + } + + public float ArgumentFast() + { + return Trig.Atan2(this.Imag, this.Real); + } + + public Complex Conjugate() + { + Complex result = default(Complex); + result.Real = this.Real; + result.Imag = 0f - this.Imag; + return result; + } + + public Complex Normalize() + { + float b = 1f / this.Modulus(); + return this * b; + } + + public Complex NormalizeFast() + { + float b = 1.95f - this.ModulusSquared(); + return this * b; + } + + public override string ToString() + { + return string.Format("real {0}, imag {1}", this.Real, this.Imag); + } + + public static Complex FromAngle(double angle) + { + Complex result = default(Complex); + result.Real = (float)Math.Cos(angle); + result.Imag = (float)Math.Sin(angle); + return result; + } + + public static Complex FromAngleFast(float angle) + { + return Trig.SinCos(angle); + } + + public static bool operator ==(Complex leftHandSide, Complex rightHandSide) + { + if (leftHandSide.Real != rightHandSide.Real) + { + return false; + } + return leftHandSide.Imag == rightHandSide.Imag; + } + + public static bool operator !=(Complex leftHandSide, Complex rightHandSide) + { + if (leftHandSide.Real != rightHandSide.Real) + { + return true; + } + return leftHandSide.Imag != rightHandSide.Imag; + } + + public static Complex operator +(Complex a, Complex b) + { + Complex result = default(Complex); + result.Real = a.Real + b.Real; + result.Imag = a.Imag + b.Imag; + return result; + } + + public static Complex operator -(Complex a, Complex b) + { + Complex result = default(Complex); + result.Real = a.Real - b.Real; + result.Imag = a.Imag - b.Imag; + return result; + } + + public static Complex operator *(Complex a, Complex b) + { + Complex result = default(Complex); + result.Real = a.Real * b.Real - a.Imag * b.Imag; + result.Imag = a.Imag * b.Real + a.Real * b.Imag; + return result; + } + + public static Complex operator *(Complex a, float b) + { + Complex result = default(Complex); + result.Real = a.Real * b; + result.Imag = a.Imag * b; + return result; + } + + public static Complex operator /(Complex a, Complex b) + { + float num = b.Real * b.Real + b.Imag * b.Imag; + num = 1f / num; + Complex result = default(Complex); + result.Real = (a.Real * b.Real + a.Imag * b.Imag) * num; + result.Imag = (a.Imag * b.Real - a.Real * b.Imag) * num; + return result; + } + + public static Complex operator /(Complex a, float b) + { + b = 1f / b; + Complex result = default(Complex); + result.Real = a.Real * b; + result.Imag = a.Imag * b; + return result; + } + + public static Complex operator ~(Complex a) + { + return a.Conjugate(); + } + + public static implicit operator Complex(float d) + { + return new Complex(d, 0f); + } + + public override int GetHashCode() + { + return this.Real.GetHashCode() * 397 ^ this.Imag.GetHashCode(); + } + + public bool Equals(Complex obj) + { + if (obj.Real == this.Real) + { + return obj.Imag == this.Imag; + } + return false; + } + + public override bool Equals(object obj) + { + if (obj.GetType() != typeof(Complex)) + { + return false; + } + return this.Equals((Complex)obj); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/ComplexCircularBuffer.cs b/SDRSharp.Radio/SDRSharp.Radio/ComplexCircularBuffer.cs new file mode 100644 index 0000000..3eb41e5 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/ComplexCircularBuffer.cs @@ -0,0 +1,30 @@ +namespace SDRSharp.Radio +{ + public class ComplexCircularBuffer : CircularBuffer + { + public unsafe ComplexCircularBuffer(int bufferSize, int maxBufferCount) + : base(bufferSize, sizeof(Complex), maxBufferCount) + { + } + + public unsafe bool Write(Complex* buffer, int len, bool block) + { + return base.Write((byte*)buffer, len, block); + } + + public unsafe bool Write(Complex* buffer, int len) + { + return base.Write((byte*)buffer, len, true); + } + + public unsafe Complex* Acquire() + { + return this.Acquire(true); + } + + public unsafe Complex* Acquire(bool block) + { + return (Complex*)base.AcquireRawBuffer(block); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/ComplexDecimator.cs b/SDRSharp.Radio/SDRSharp.Radio/ComplexDecimator.cs new file mode 100644 index 0000000..f9ab3b1 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/ComplexDecimator.cs @@ -0,0 +1,49 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + public sealed class ComplexDecimator : IDisposable + { + private IntPtr _dec; + + private int _decimationRatio; + + public int DecimationRatio + { + get + { + return this._decimationRatio; + } + } + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr complex_decimator_create(int decimation); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern void complex_decimator_destroy(IntPtr instance); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern int complex_decimator_process(IntPtr instance, Complex* buffer, int length); + + public ComplexDecimator(int decimationRatio) + { + this._decimationRatio = decimationRatio; + this._dec = ComplexDecimator.complex_decimator_create(decimationRatio); + } + + public void Dispose() + { + if (this._dec != IntPtr.Zero) + { + ComplexDecimator.complex_decimator_destroy(this._dec); + this._dec = IntPtr.Zero; + } + } + + public unsafe int Process(Complex* buffer, int length) + { + return ComplexDecimator.complex_decimator_process(this._dec, buffer, length); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/ComplexFifoStream.cs b/SDRSharp.Radio/SDRSharp.Radio/ComplexFifoStream.cs new file mode 100644 index 0000000..ce8c640 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/ComplexFifoStream.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections.Generic; + +namespace SDRSharp.Radio +{ + public sealed class ComplexFifoStream : IDisposable + { + private const int BlockSize = 8192; + + private const int MaxBlocksInCache = 512; + + private int _size; + + private int _readPos; + + private int _writePos; + + private bool _terminated; + + private readonly int _maxSize; + + private readonly SharpEvent _writeEvent; + + private readonly SharpEvent _readEvent; + + private readonly Stack _usedBlocks = new Stack(); + + private readonly List _blocks = new List(); + + public int Length + { + get + { + return this._size; + } + } + + public ComplexFifoStream() + : this(BlockMode.None) + { + } + + public ComplexFifoStream(BlockMode blockMode) + : this(blockMode, 0) + { + } + + public ComplexFifoStream(BlockMode blockMode, int maxSize) + { + if (blockMode == BlockMode.BlockingRead || blockMode == BlockMode.BlockingReadWrite) + { + this._readEvent = new SharpEvent(false); + } + if (blockMode == BlockMode.BlockingWrite || blockMode == BlockMode.BlockingReadWrite) + { + if (maxSize <= 0) + { + throw new ArgumentException("MaxSize should be greater than zero when in blocking write mode", "maxSize"); + } + this._writeEvent = new SharpEvent(false); + } + this._maxSize = maxSize; + } + + ~ComplexFifoStream() + { + this.Dispose(); + } + + public void Dispose() + { + this.Close(); + GC.SuppressFinalize(this); + } + + private unsafe UnsafeBuffer AllocBlock() + { + if (this._usedBlocks.Count <= 0) + { + return UnsafeBuffer.Create(8192, sizeof(Complex)); + } + return this._usedBlocks.Pop(); + } + + private void FreeBlock(UnsafeBuffer block) + { + if (this._usedBlocks.Count < 512) + { + this._usedBlocks.Push(block); + } + } + + private UnsafeBuffer GetWBlock() + { + UnsafeBuffer unsafeBuffer; + if (this._writePos < 8192 && this._blocks.Count > 0) + { + unsafeBuffer = this._blocks[this._blocks.Count - 1]; + } + else + { + unsafeBuffer = this.AllocBlock(); + this._blocks.Add(unsafeBuffer); + this._writePos = 0; + } + return unsafeBuffer; + } + + public void Open() + { + this._terminated = false; + } + + public void Close() + { + this._terminated = true; + this.Flush(); + } + + public void Flush() + { + lock (this) + { + foreach (UnsafeBuffer block in this._blocks) + { + this.FreeBlock(block); + } + this._blocks.Clear(); + this._readPos = 0; + this._writePos = 0; + this._size = 0; + } + if (this._writeEvent != null) + { + this._writeEvent.Set(); + } + if (this._readEvent != null) + { + this._readEvent.Set(); + } + } + + public unsafe int Read(Complex* buf, int ofs, int count) + { + if (this._readEvent != null) + { + while (this._size == 0 && !this._terminated) + { + this._readEvent.WaitOne(); + } + if (this._terminated) + { + return 0; + } + } + int num = default(int); + lock (this) + { + num = this.DoPeek(buf, ofs, count); + this.DoAdvance(num); + } + if (this._writeEvent != null) + { + this._writeEvent.Set(); + } + return num; + } + + public unsafe void Write(Complex* buf, int ofs, int count) + { + if (this._writeEvent != null) + { + while (this._size >= this._maxSize && !this._terminated) + { + this._writeEvent.WaitOne(); + } + if (this._terminated) + { + return; + } + } + lock (this) + { + int num2; + for (int num = count; num > 0; num -= num2) + { + num2 = Math.Min(8192 - this._writePos, num); + Complex* ptr = (Complex*)(void*)this.GetWBlock(); + Utils.Memcpy(ptr + this._writePos, buf + ofs + count - num, num2 * sizeof(Complex)); + this._writePos += num2; + } + this._size += count; + } + if (this._readEvent != null) + { + this._readEvent.Set(); + } + } + + public unsafe int Read(Complex* buf, int count) + { + return this.Read(buf, 0, count); + } + + public unsafe void Write(Complex* buf, int count) + { + this.Write(buf, 0, count); + } + + private int DoAdvance(int count) + { + int num = count; + while (num > 0 && this._size > 0) + { + if (this._readPos == 8192) + { + this._readPos = 0; + this.FreeBlock(this._blocks[0]); + this._blocks.RemoveAt(0); + } + int num2 = (this._blocks.Count == 1) ? Math.Min(this._writePos - this._readPos, num) : Math.Min(8192 - this._readPos, num); + this._readPos += num2; + num -= num2; + this._size -= num2; + } + return count - num; + } + + public int Advance(int count) + { + if (this._readEvent != null) + { + while (this._size == 0 && !this._terminated) + { + this._readEvent.WaitOne(); + } + if (this._terminated) + { + return 0; + } + } + int result = default(int); + lock (this) + { + result = this.DoAdvance(count); + } + if (this._writeEvent != null) + { + this._writeEvent.Set(); + } + return result; + } + + private unsafe int DoPeek(Complex* buf, int ofs, int count) + { + int num = count; + int num2 = this._readPos; + int num3 = this._size; + int num4 = 0; + while (num > 0 && num3 > 0) + { + if (num2 == 8192) + { + num2 = 0; + num4++; + } + int num5 = Math.Min(((num4 < this._blocks.Count - 1) ? 8192 : this._writePos) - num2, num); + Complex* ptr = (Complex*)(void*)this._blocks[num4]; + Utils.Memcpy(buf + ofs + count - num, ptr + num2, num5 * sizeof(Complex)); + num -= num5; + num2 += num5; + num3 -= num5; + } + return count - num; + } + + public unsafe int Peek(Complex* buf, int ofs, int count) + { + lock (this) + { + return this.DoPeek(buf, ofs, count); + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/ComplexFilter.cs b/SDRSharp.Radio/SDRSharp.Radio/ComplexFilter.cs new file mode 100644 index 0000000..2dd6fb4 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/ComplexFilter.cs @@ -0,0 +1,67 @@ +namespace SDRSharp.Radio +{ + public class ComplexFilter : OverlapSaveProcessor + { + private UnsafeBuffer _kernelBuffer; + + private unsafe Complex* _kernelPtr; + + private int _actualKernelLength; + + public int KernelSize + { + get + { + return this._actualKernelLength; + } + } + + public unsafe ComplexFilter(Complex[] kernel) + : base(ComplexFilter.GetFFTSize(kernel.Length)) + { + this._actualKernelLength = kernel.Length; + this._kernelBuffer = UnsafeBuffer.Create(base.FFTSize, sizeof(Complex)); + this._kernelPtr = (Complex*)(void*)this._kernelBuffer; + this.SetKernel(kernel); + } + + private static int GetFFTSize(int length) + { + int num; + for (num = 1; num < length; num <<= 1) + { + } + return num << 1; + } + + public bool IsKernelLengthSupported(int length) + { + return length < base.FFTSize / 2; + } + + public unsafe void SetKernel(Complex[] kernel) + { + if (this.IsKernelLengthSupported(kernel.Length)) + { + fixed (Complex* src = kernel) + { + Utils.Memcpy(this._kernelPtr, src, kernel.Length * sizeof(Complex)); + } + for (int i = kernel.Length; i < base.FFTSize; i++) + { + this._kernelPtr[i] = 0f; + } + Fourier.ForwardTransform(this._kernelPtr, base.FFTSize, false); + } + } + + protected unsafe override void ProcessFft(Complex* buffer, int length) + { + for (int i = 0; i < length; i++) + { + Complex* intPtr = buffer + i; + *intPtr *= this._kernelPtr[i]; + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/CwDetector.cs b/SDRSharp.Radio/SDRSharp.Radio/CwDetector.cs new file mode 100644 index 0000000..8ba914c --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/CwDetector.cs @@ -0,0 +1,40 @@ +namespace SDRSharp.Radio +{ + public sealed class CwDetector + { + private Oscillator _bfo = new Oscillator(); + + public double SampleRate + { + get + { + return this._bfo.SampleRate; + } + set + { + this._bfo.SampleRate = value; + } + } + + public int BfoFrequency + { + get + { + return (int)this._bfo.Frequency; + } + set + { + this._bfo.Frequency = (double)value; + } + } + + public unsafe void Demodulate(Complex* iq, float* audio, int length) + { + for (int i = 0; i < length; i++) + { + this._bfo.Tick(); + audio[i] = (iq[i] * this._bfo.Phase).Real; + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/DSPThreadPool.cs b/SDRSharp.Radio/SDRSharp.Radio/DSPThreadPool.cs new file mode 100644 index 0000000..dcc0f19 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/DSPThreadPool.cs @@ -0,0 +1,52 @@ +using System.Threading; + +namespace SDRSharp.Radio +{ + public static class DSPThreadPool + { + private static SharpThreadPool _threadPool; + + public static void Initialize() + { + if (DSPThreadPool._threadPool == null) + { + DSPThreadPool._threadPool = new SharpThreadPool(); + } + } + + public static void Initialize(int threadCount) + { + if (DSPThreadPool._threadPool == null) + { + DSPThreadPool._threadPool = new SharpThreadPool(threadCount); + } + } + + public static void QueueUserWorkItem(WaitCallback callback) + { + if (DSPThreadPool._threadPool == null) + { + DSPThreadPool._threadPool = new SharpThreadPool(); + } + DSPThreadPool._threadPool.QueueUserWorkItem(callback); + } + + public static void QueueUserWorkItem(WaitCallback callback, object parameter) + { + if (DSPThreadPool._threadPool == null) + { + DSPThreadPool._threadPool = new SharpThreadPool(); + } + DSPThreadPool._threadPool.QueueUserWorkItem(callback, parameter); + } + + public static void Terminate() + { + if (DSPThreadPool._threadPool != null) + { + DSPThreadPool._threadPool.Dispose(); + DSPThreadPool._threadPool = null; + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/DcRemover.cs b/SDRSharp.Radio/SDRSharp.Radio/DcRemover.cs new file mode 100644 index 0000000..f87034d --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/DcRemover.cs @@ -0,0 +1,56 @@ +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + [StructLayout(LayoutKind.Sequential, Pack = 16)] + public struct DcRemover + { + private float _average; + + private float _ratio; + + public float Offset + { + get + { + return this._average; + } + } + + public DcRemover(float ratio) + { + this._ratio = ratio; + this._average = 0f; + } + + public void Init(float ratio) + { + this._ratio = ratio; + this._average = 0f; + } + + public unsafe void Process(float* buffer, int length) + { + for (int i = 0; i < length; i++) + { + this._average += this._ratio * (buffer[i] - this._average); + buffer[i] -= this._average; + } + } + + public unsafe void ProcessInterleaved(float* buffer, int length) + { + length *= 2; + for (int i = 0; i < length; i += 2) + { + this._average += this._ratio * (buffer[i] - this._average); + buffer[i] -= this._average; + } + } + + public void Reset() + { + this._average = 0f; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/DetectorType.cs b/SDRSharp.Radio/SDRSharp.Radio/DetectorType.cs new file mode 100644 index 0000000..4d8b70c --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/DetectorType.cs @@ -0,0 +1,14 @@ +namespace SDRSharp.Radio +{ + public enum DetectorType + { + NFM, + WFM, + AM, + DSB, + LSB, + USB, + CW, + RAW + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/DownConverter.cs b/SDRSharp.Radio/SDRSharp.Radio/DownConverter.cs new file mode 100644 index 0000000..e13e7b8 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/DownConverter.cs @@ -0,0 +1,81 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + public sealed class DownConverter : IDisposable + { + private IntPtr _dec; + + private int _decimationRatio; + + private double _sampleRate; + + private double _frequency; + + public double Frequency + { + get + { + return this._frequency; + } + set + { + if (this._frequency != value) + { + this._frequency = value; + DownConverter.ddc_tune(this._dec, this._frequency); + } + } + } + + public int DecimationRatio + { + get + { + return this._decimationRatio; + } + } + + public double SampleRate + { + get + { + return this._sampleRate; + } + } + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr ddc_create(double sample_rate, int decimation); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern void ddc_destroy(IntPtr instance); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern void ddc_tune(IntPtr instance, double frequency); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern int ddc_process(IntPtr instance, Complex* buffer, int length); + + public DownConverter(double sampleRate, int decimationRatio) + { + this._sampleRate = sampleRate; + this._decimationRatio = decimationRatio; + this._dec = DownConverter.ddc_create(this._sampleRate, this._decimationRatio); + } + + public void Dispose() + { + if (this._dec != IntPtr.Zero) + { + DownConverter.ddc_destroy(this._dec); + this._dec = IntPtr.Zero; + } + } + + public unsafe int Process(Complex* buffer, int length) + { + return DownConverter.ddc_process(this._dec, buffer, length); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/FilterBuilder.cs b/SDRSharp.Radio/SDRSharp.Radio/FilterBuilder.cs new file mode 100644 index 0000000..e5985d0 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/FilterBuilder.cs @@ -0,0 +1,387 @@ +using System; + +namespace SDRSharp.Radio +{ + public static class FilterBuilder + { + public const int DefaultFilterOrder = 500; + + public static float[] MakeWindow(WindowType windowType, int length) + { + float[] array = new float[length]; + length--; + for (int i = 0; i <= length; i++) + { + array[i] = 1f; + switch (windowType) + { + case WindowType.Hamming: + { + float num = 0.54f; + float num2 = 0.46f; + float num3 = 0f; + float num4 = 0f; + array[i] *= num - num2 * (float)Math.Cos(6.2831853071795862 * (double)i / (double)length) + num3 * (float)Math.Cos(12.566370614359172 * (double)i / (double)length) - num4 * (float)Math.Cos(18.849555921538759 * (double)i / (double)length); + break; + } + case WindowType.Blackman: + { + float num = 0.42f; + float num2 = 0.5f; + float num3 = 0.08f; + float num4 = 0f; + array[i] *= num - num2 * (float)Math.Cos(6.2831853071795862 * (double)i / (double)length) + num3 * (float)Math.Cos(12.566370614359172 * (double)i / (double)length) - num4 * (float)Math.Cos(18.849555921538759 * (double)i / (double)length); + break; + } + case WindowType.BlackmanHarris4: + { + float num = 0.35875f; + float num2 = 0.48829f; + float num3 = 0.14128f; + float num4 = 0.01168f; + array[i] *= num - num2 * (float)Math.Cos(6.2831853071795862 * (double)i / (double)length) + num3 * (float)Math.Cos(12.566370614359172 * (double)i / (double)length) - num4 * (float)Math.Cos(18.849555921538759 * (double)i / (double)length); + break; + } + case WindowType.BlackmanHarris7: + { + float num = 0.2710514f; + float num2 = 0.433297932f; + float num3 = 0.218123f; + float num4 = 0.06592545f; + float num6 = 0.0108117424f; + float num7 = 0.000776584842f; + float num8 = 1.38872174E-05f; + array[i] *= num - num2 * (float)Math.Cos(6.2831853071795862 * (double)i / (double)length) + num3 * (float)Math.Cos(12.566370614359172 * (double)i / (double)length) - num4 * (float)Math.Cos(18.849555921538759 * (double)i / (double)length) + num6 * (float)Math.Cos(25.132741228718345 * (double)i / (double)length) - num7 * (float)Math.Cos(31.415926535897931 * (double)i / (double)length) + num8 * (float)Math.Cos(37.699111843077517 * (double)i / (double)length); + break; + } + case WindowType.HannPoisson: + { + float value = (float)i - (float)length / 2f; + float num5 = 0.005f; + array[i] *= 0.5f * (float)((1.0 + Math.Cos(6.2831853071795862 * (double)value / (double)length)) * Math.Exp(-2.0 * (double)num5 * (double)Math.Abs(value) / (double)length)); + break; + } + case WindowType.Youssef: + { + float num = 0.35875f; + float num2 = 0.48829f; + float num3 = 0.14128f; + float num4 = 0.01168f; + float value = (float)i - (float)length / 2f; + float num5 = 0.005f; + array[i] *= num - num2 * (float)Math.Cos(6.2831853071795862 * (double)i / (double)length) + num3 * (float)Math.Cos(12.566370614359172 * (double)i / (double)length) - num4 * (float)Math.Cos(18.849555921538759 * (double)i / (double)length); + array[i] *= (float)Math.Exp(-2.0 * (double)num5 * (double)Math.Abs(value) / (double)length); + break; + } + } + } + return array; + } + + public static float[] MakeSinc(double sampleRate, double frequency, int length) + { + if (length % 2 == 0) + { + throw new ArgumentException("Length should be odd", "length"); + } + double num = 6.2831853071795862 * frequency / sampleRate; + float[] array = new float[length]; + for (int i = 0; i < length; i++) + { + int num2 = i - length / 2; + if (num2 == 0) + { + array[i] = (float)num; + } + else + { + array[i] = (float)(Math.Sin(num * (double)num2) / (double)num2); + } + } + return array; + } + + public static float[] MakeSin(double sampleRate, double frequency, int length) + { + if (length % 2 == 0) + { + throw new ArgumentException("Length should be odd", "length"); + } + double num = 6.2831853071795862 * frequency / sampleRate; + float[] array = new float[length]; + int num2 = length / 2; + for (int i = 0; i <= num2; i++) + { + array[num2 - i] = 0f - (array[num2 + i] = (float)Math.Sin(num * (double)i)); + } + return array; + } + + public static float[] MakeLowPassKernel(double sampleRate, int filterOrder, double cutoffFrequency, WindowType windowType) + { + filterOrder |= 1; + float[] array = FilterBuilder.MakeSinc(sampleRate, cutoffFrequency, filterOrder); + float[] window = FilterBuilder.MakeWindow(windowType, filterOrder); + FilterBuilder.ApplyWindow(array, window); + FilterBuilder.Normalize(array); + return array; + } + + public static float[] MakeHighPassKernel(double sampleRate, int filterOrder, double cutoffFrequency, WindowType windowType) + { + return FilterBuilder.InvertSpectrum(FilterBuilder.MakeLowPassKernel(sampleRate, filterOrder, cutoffFrequency, windowType)); + } + + public static float[] MakeBandPassKernel(double sampleRate, int filterOrder, double cutoff1, double cutoff2, WindowType windowType) + { + double num = (cutoff2 - cutoff1) / 2.0; + double num2 = cutoff2 - num; + double num3 = 6.2831853071795862 * num2 / sampleRate; + float[] array = FilterBuilder.MakeLowPassKernel(sampleRate, filterOrder, num, windowType); + for (int i = 0; i < array.Length; i++) + { + int num4 = i - array.Length / 2; + array[i] *= (float)(2.0 * Math.Cos(num3 * (double)num4)); + } + return array; + } + + public static Complex[] MakeComplexKernel(double sampleRate, int filterOrder, double bandwidth, double offset, WindowType windowType) + { + double num = -6.2831853071795862 * offset / sampleRate; + float[] array = FilterBuilder.MakeLowPassKernel(sampleRate, filterOrder, bandwidth * 0.5, windowType); + Complex[] array2 = new Complex[array.Length]; + for (int i = 0; i < array2.Length; i++) + { + int num2 = i - array2.Length / 2; + double num3 = num * (double)num2; + array2[i].Real = (float)((double)array[i] * Math.Cos(num3)); + array2[i].Imag = (float)((double)(0f - array[i]) * Math.Sin(num3)); + } + return array2; + } + + public static Complex[] MakeComplexKernel(double sampleRate, double passband, double transition, double ripple, double attenuation, double offset) + { + double num = -6.2831853071795862 * offset / sampleRate; + passband *= 0.5; + float[] array = FilterBuilder.MakeLowPassKernel(sampleRate, passband, passband + transition, ripple, attenuation); + if (array == null) + { + return null; + } + Complex[] array2 = new Complex[array.Length]; + for (int i = 0; i < array2.Length; i++) + { + int num2 = i - array2.Length / 2; + double num3 = num * (double)num2; + array2[i].Real = (float)((double)array[i] * Math.Cos(num3)); + array2[i].Imag = (float)((double)(0f - array[i]) * Math.Sin(num3)); + } + return array2; + } + + private static double ACosh(double x) + { + return Math.Log(x + Math.Sqrt(x * x - 1.0)); + } + + private static double ChebychevPoly(int n, double x) + { + if (Math.Abs(x) <= 1.0) + { + return Math.Cos((double)n * Math.Acos(x)); + } + return Math.Cosh((double)n * FilterBuilder.ACosh(x)); + } + + private static float[] MakeChebychevWindow(int length, double attenuation) + { + double num = Math.Pow(10.0, attenuation / 20.0); + float[] array = new float[length]; + float num2 = 0f; + double num3 = Math.Cosh(FilterBuilder.ACosh(num) / (double)(length - 1)); + double num4 = (double)((length - 1) / 2); + if (length % 2 == 0) + { + num4 += 0.5; + } + for (int i = 0; i < length / 2 + 1; i++) + { + double num5 = (double)i - num4; + double num6 = 0.0; + for (int j = 1; (double)j <= num4; j++) + { + num6 += FilterBuilder.ChebychevPoly(length - 1, num3 * Math.Cos(3.1415926535897931 * (double)j / (double)length)) * Math.Cos(2.0 * num5 * 3.1415926535897931 * (double)j / (double)length); + } + array[i] = (float)(num + 2.0 * num6); + array[length - i - 1] = array[i]; + if (array[i] > num2) + { + num2 = array[i]; + } + } + float num7 = 1f / num2; + for (int k = 0; k < length; k++) + { + array[k] *= num7; + } + return array; + } + + private static float[] MakeChebychevLowPass(int filterOrder, double normalizedCutoff, double attenuation) + { + float[] array = FilterBuilder.MakeChebychevWindow(filterOrder, attenuation); + float[] array2 = FilterBuilder.MakeSinc(2.0, normalizedCutoff, array.Length); + FilterBuilder.ApplyWindow(array2, array); + FilterBuilder.Normalize(array2); + return array2; + } + + public static float[] MakeLowPassKernel(double sampleRate, double passband, double stopband, double ripple, double attenuation) + { + double num = 2.0 * passband / sampleRate; + double num2 = 2.0 * stopband / sampleRate; + int num3 = (int)((double)FilterBuilder.EstimateOrder(num, num2, ripple, attenuation) * 1.4) | 1; + int num4 = Math.Max(1, num3 - 20); + int num5 = num4 + 40; + for (int i = num4; i < num5; i += 2) + { + int num6 = 50; + double num7 = 0.0; + for (int j = 0; j < 100; j++) + { + double normalizedCutoff = (num * (double)num6 + num2 * (double)(100 - num6)) / 100.0; + float[] array = FilterBuilder.MakeChebychevLowPass(i, normalizedCutoff, attenuation + num7); + double num8; + double num9; + FilterBuilder.GetFilterSpecs(array, num, num2, out num8, out num9); + if (num8 <= ripple && num9 >= attenuation) + { + return array; + } + num6 += Math.Sign(ripple - num8); + num7 += (double)Math.Sign(attenuation - num9) * 0.15 - (double)Math.Sign(ripple - num8) * 2.5; + if (num7 < -20.0) + { + num7 = -20.0; + } + if (num7 > 20.0) + { + num7 = 20.0; + } + if (num6 < 0) + { + num6 = 0; + } + if (num6 > 100) + { + num6 = 100; + } + } + } + return null; + } + + public static int EstimateOrder(double passband, double stopband, double ripple, double attenuation) + { + return (int)Math.Round(0.0010765282977552 * (52.0490855934073 * attenuation + 194.466145732802 / Math.Log10(1.0 + ripple)) / (stopband - passband) + 1.74881176954081); + } + + public static double GetFilterError(float[] kernel, double passband, double stopband, double ripple, double attenuation) + { + double num; + double num2; + FilterBuilder.GetFilterSpecs(kernel, passband, stopband, out num, out num2); + return ((num2 >= attenuation) ? 0.0 : (attenuation - num2)) + 100.0 * ((num <= ripple) ? 0.0 : (num - ripple)); + } + + public unsafe static void GetFilterSpecs(float[] kernel, double passband, double stopband, out double ripple, out double attenuation) + { + int num = 0; + int num2 = 0; + int num3 = 2; + while (true) + { + if (num3 >= kernel.Length * 2 && num >= 4) + { + break; + } + num = (int)Math.Round((double)num3 * passband); + num2 = (int)Math.Ceiling((double)num3 * stopband); + num3 *= 2; + } + Complex[] obj = new Complex[num3]; + float[] array = new float[num3 / 2]; + Complex[] array2 = obj; + fixed (Complex* ptr = array2) + { + float[] array3 = array; + fixed (float* ptr2 = array3) + { + for (int i = 0; i < kernel.Length; i++) + { + ptr[i] = kernel[i]; + } + Fourier.ForwardTransform(ptr, num3, false); + Fourier.SpectrumPower(ptr, ptr2, array.Length, 0f); + float num4 = float.PositiveInfinity; + float num5 = float.NegativeInfinity; + for (int j = 0; j <= num; j++) + { + if (num4 > ptr2[j]) + { + num4 = ptr2[j]; + } + if (num5 < ptr2[j]) + { + num5 = ptr2[j]; + } + } + ripple = (double)(num5 - num4); + float num6 = float.NegativeInfinity; + for (int k = num2; k < array.Length; k++) + { + if (num6 < ptr2[k]) + { + num6 = ptr2[k]; + } + } + attenuation = Math.Max(0.0, (double)(num4 + num5) * 0.5 - (double)num6); + } + } + } + + public static void Normalize(float[] h) + { + double num = 0.0; + for (int i = 0; i < h.Length; i++) + { + num += (double)h[i]; + } + double num2 = 1.0 / num; + for (int j = 0; j < h.Length; j++) + { + h[j] = (float)((double)h[j] * num2); + } + } + + public static void ApplyWindow(float[] coefficients, float[] window) + { + for (int i = 0; i < coefficients.Length; i++) + { + coefficients[i] *= window[i]; + } + } + + private static float[] InvertSpectrum(float[] h) + { + for (int i = 0; i < h.Length; i++) + { + h[i] = 0f - h[i]; + } + h[(h.Length - 1) / 2] += 1f; + return h; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/FirFilter.cs b/SDRSharp.Radio/SDRSharp.Radio/FirFilter.cs new file mode 100644 index 0000000..cb9733a --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/FirFilter.cs @@ -0,0 +1,68 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + public sealed class FirFilter : IDisposable + { + private int _decimationRatio; + + private int _length; + + private IntPtr _fir; + + public int Length + { + get + { + return this._length; + } + } + + public int DecimationRatio + { + get + { + return this._decimationRatio; + } + } + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern IntPtr float_fir_create(float* kernel, int length, int decimation); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern void float_fir_destroy(IntPtr instance); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern int float_fir_process(IntPtr instance, float* buffer, int length); + + public unsafe FirFilter(float[] coefficients, int decimationRatio = 1) + { + if (decimationRatio <= 0) + { + throw new ArgumentException("The decimation factor must be greater than zero", "decimationRatio"); + } + this._decimationRatio = decimationRatio; + this._length = coefficients.Length; + fixed (float* kernel = coefficients) + { + this._fir = FirFilter.float_fir_create(kernel, this._length, decimationRatio); + } + } + + public void Dispose() + { + if (this._fir != IntPtr.Zero) + { + FirFilter.float_fir_destroy(this._fir); + this._fir = IntPtr.Zero; + } + GC.SuppressFinalize(this); + } + + public unsafe int Process(float* buffer, int length) + { + return FirFilter.float_fir_process(this._fir, buffer, length); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/FloatCircularBuffer.cs b/SDRSharp.Radio/SDRSharp.Radio/FloatCircularBuffer.cs new file mode 100644 index 0000000..f19489b --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/FloatCircularBuffer.cs @@ -0,0 +1,30 @@ +namespace SDRSharp.Radio +{ + public class FloatCircularBuffer : CircularBuffer + { + public FloatCircularBuffer(int bufferSize, int maxBufferCount) + : base(bufferSize, 4, maxBufferCount) + { + } + + public unsafe bool Write(float* buffer, int len, bool block) + { + return base.Write((byte*)buffer, len, block); + } + + public unsafe bool Write(float* buffer, int len) + { + return base.Write((byte*)buffer, len, true); + } + + public unsafe float* Acquire() + { + return (float*)base.AcquireRawBuffer(true); + } + + public unsafe float* Acquire(bool block) + { + return (float*)base.AcquireRawBuffer(block); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/FloatDecimator.cs b/SDRSharp.Radio/SDRSharp.Radio/FloatDecimator.cs new file mode 100644 index 0000000..dc3e708 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/FloatDecimator.cs @@ -0,0 +1,49 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + public sealed class FloatDecimator : IDisposable + { + private IntPtr _dec; + + private int _decimationRatio; + + public int DecimationRatio + { + get + { + return this._decimationRatio; + } + } + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr float_decimator_create(int decimation); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern void float_decimator_destroy(IntPtr instance); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern int float_decimator_process(IntPtr instance, float* buffer, int length); + + public FloatDecimator(int decimationRatio) + { + this._decimationRatio = decimationRatio; + this._dec = FloatDecimator.float_decimator_create(decimationRatio); + } + + public void Dispose() + { + if (this._dec != IntPtr.Zero) + { + FloatDecimator.float_decimator_destroy(this._dec); + this._dec = IntPtr.Zero; + } + } + + public unsafe int Process(float* buffer, int length) + { + return FloatDecimator.float_decimator_process(this._dec, buffer, length); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/FloatFifoStream.cs b/SDRSharp.Radio/SDRSharp.Radio/FloatFifoStream.cs new file mode 100644 index 0000000..ba1b4ab --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/FloatFifoStream.cs @@ -0,0 +1,285 @@ +using System; +using System.Collections.Generic; + +namespace SDRSharp.Radio +{ + public sealed class FloatFifoStream : IDisposable + { + private const int BlockSize = 16384; + + private const int MaxBlocksInCache = 128; + + private int _size; + + private int _readPos; + + private int _writePos; + + private bool _terminated; + + private readonly int _maxSize; + + private readonly SharpEvent _writeEvent; + + private readonly SharpEvent _readEvent; + + private readonly Stack _usedBlocks = new Stack(); + + private readonly List _blocks = new List(); + + public int Length + { + get + { + return this._size; + } + } + + public FloatFifoStream() + : this(BlockMode.None) + { + } + + public FloatFifoStream(BlockMode blockMode) + : this(blockMode, 0) + { + } + + public FloatFifoStream(BlockMode blockMode, int maxSize) + { + if (blockMode == BlockMode.BlockingRead || blockMode == BlockMode.BlockingReadWrite) + { + this._readEvent = new SharpEvent(false); + } + if (blockMode == BlockMode.BlockingWrite || blockMode == BlockMode.BlockingReadWrite) + { + if (maxSize <= 0) + { + throw new ArgumentException("MaxSize should be greater than zero when in blocking write mode", "maxSize"); + } + this._writeEvent = new SharpEvent(false); + } + this._maxSize = maxSize; + } + + ~FloatFifoStream() + { + this.Dispose(); + } + + public void Dispose() + { + this.Close(); + GC.SuppressFinalize(this); + } + + private UnsafeBuffer AllocBlock() + { + if (this._usedBlocks.Count <= 0) + { + return UnsafeBuffer.Create(16384, 4); + } + return this._usedBlocks.Pop(); + } + + private void FreeBlock(UnsafeBuffer block) + { + if (this._usedBlocks.Count < 128) + { + this._usedBlocks.Push(block); + } + } + + private UnsafeBuffer GetWBlock() + { + UnsafeBuffer unsafeBuffer; + if (this._writePos < 16384 && this._blocks.Count > 0) + { + unsafeBuffer = this._blocks[this._blocks.Count - 1]; + } + else + { + unsafeBuffer = this.AllocBlock(); + this._blocks.Add(unsafeBuffer); + this._writePos = 0; + } + return unsafeBuffer; + } + + public void Open() + { + this._terminated = false; + } + + public void Close() + { + this._terminated = true; + this.Flush(); + } + + public void Flush() + { + lock (this) + { + foreach (UnsafeBuffer block in this._blocks) + { + this.FreeBlock(block); + } + this._blocks.Clear(); + this._readPos = 0; + this._writePos = 0; + this._size = 0; + } + if (this._writeEvent != null) + { + this._writeEvent.Set(); + } + if (this._readEvent != null) + { + this._readEvent.Set(); + } + } + + public unsafe int Read(float* buf, int ofs, int count) + { + if (this._readEvent != null) + { + while (this._size == 0 && !this._terminated) + { + this._readEvent.WaitOne(); + } + if (this._terminated) + { + return 0; + } + } + int num = default(int); + lock (this) + { + num = this.DoPeek(buf, ofs, count); + this.DoAdvance(num); + } + if (this._writeEvent != null) + { + this._writeEvent.Set(); + } + return num; + } + + public unsafe int Read(float* buf, int count) + { + return this.Read(buf, 0, count); + } + + public unsafe void Write(float* buf, int ofs, int count) + { + if (this._writeEvent != null) + { + while (this._size >= this._maxSize && !this._terminated) + { + this._writeEvent.WaitOne(); + } + if (this._terminated) + { + return; + } + } + lock (this) + { + int num2; + for (int num = count; num > 0; num -= num2) + { + num2 = Math.Min(16384 - this._writePos, num); + float* ptr = (float*)(void*)this.GetWBlock(); + Utils.Memcpy(ptr + this._writePos, buf + ofs + count - num, num2 * 4); + this._writePos += num2; + } + this._size += count; + } + if (this._readEvent != null) + { + this._readEvent.Set(); + } + } + + public unsafe void Write(float* buf, int count) + { + this.Write(buf, 0, count); + } + + private int DoAdvance(int count) + { + int num = count; + while (num > 0 && this._size > 0) + { + if (this._readPos == 16384) + { + this._readPos = 0; + this.FreeBlock(this._blocks[0]); + this._blocks.RemoveAt(0); + } + int num2 = (this._blocks.Count == 1) ? Math.Min(this._writePos - this._readPos, num) : Math.Min(16384 - this._readPos, num); + this._readPos += num2; + num -= num2; + this._size -= num2; + } + return count - num; + } + + public int Advance(int count) + { + if (this._readEvent != null) + { + while (this._size == 0 && !this._terminated) + { + this._readEvent.WaitOne(); + } + if (this._terminated) + { + return 0; + } + } + int result = default(int); + lock (this) + { + result = this.DoAdvance(count); + } + if (this._writeEvent != null) + { + this._writeEvent.Set(); + } + return result; + } + + private unsafe int DoPeek(float* buf, int ofs, int count) + { + int num = count; + int num2 = this._readPos; + int num3 = this._size; + int num4 = 0; + while (num > 0 && num3 > 0) + { + if (num2 == 16384) + { + num2 = 0; + num4++; + } + int num5 = Math.Min(((num4 < this._blocks.Count - 1) ? 16384 : this._writePos) - num2, num); + float* ptr = (float*)(void*)this._blocks[num4]; + Utils.Memcpy(buf + ofs + count - num, ptr + num2, num5 * 4); + num -= num5; + num2 += num5; + num3 -= num5; + } + return count - num; + } + + public unsafe int Peek(float* buf, int ofs, int count) + { + lock (this) + { + return this.DoPeek(buf, ofs, count); + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/FmDetector.cs b/SDRSharp.Radio/SDRSharp.Radio/FmDetector.cs new file mode 100644 index 0000000..8076b27 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/FmDetector.cs @@ -0,0 +1,157 @@ +using System; + +namespace SDRSharp.Radio +{ + public sealed class FmDetector + { + private const float NarrowAFGain = 0.5f; + + private const float FMGain = 1E-05f; + + private const int MinHissFrequency = 4000; + + private const int MaxHissFrequency = 6000; + + private const int HissFilterOrder = 20; + + private const float HissFactor = 2E-05f; + + private unsafe float* _hissPtr; + + private UnsafeBuffer _hissBuffer; + + private FirFilter _hissFilter; + + private Complex _iqState; + + private float _noiseLevel; + + private double _sampleRate; + + private float _noiseAveragingRatio; + + private int _squelchThreshold; + + private bool _isSquelchOpen; + + private float _noiseThreshold; + + private FmMode _mode; + + public double SampleRate + { + get + { + return this._sampleRate; + } + set + { + if (value != this._sampleRate) + { + this._sampleRate = value; + this._noiseAveragingRatio = (float)(30.0 / this._sampleRate); + float[] coefficients = FilterBuilder.MakeBandPassKernel(this._sampleRate, 20, 4000.0, 6000.0, WindowType.BlackmanHarris4); + if (this._hissFilter != null) + { + this._hissFilter.Dispose(); + } + this._hissFilter = new FirFilter(coefficients, 1); + } + } + } + + public int SquelchThreshold + { + get + { + return this._squelchThreshold; + } + set + { + if (this._squelchThreshold != value) + { + this._squelchThreshold = value; + this._noiseThreshold = (float)Math.Log10(2.0 - (double)this._squelchThreshold / 100.0) * 2E-05f; + } + } + } + + public bool IsSquelchOpen + { + get + { + return this._isSquelchOpen; + } + } + + public FmMode Mode + { + get + { + return this._mode; + } + set + { + this._mode = value; + } + } + + public unsafe void Demodulate(Complex* iq, float* audio, int length) + { + for (int i = 0; i < length; i++) + { + Complex a = iq[i] * this._iqState.Conjugate(); + float num = a.Modulus(); + if (num > 0f) + { + a /= num; + } + float num2 = a.Argument(); + if (!float.IsNaN(num2)) + { + audio[i] = num2 * 1E-05f; + } + else + { + audio[i] = 0f; + } + this._iqState = iq[i]; + } + if (this._mode == FmMode.Narrow) + { + this.ProcessSquelch(audio, length); + for (int j = 0; j < length; j++) + { + audio[j] *= 0.5f; + } + } + } + + private unsafe void ProcessSquelch(float* audio, int length) + { + if (this._squelchThreshold > 0) + { + if (this._hissBuffer == null || this._hissBuffer.Length != length) + { + this._hissBuffer = UnsafeBuffer.Create(length, 4); + this._hissPtr = (float*)(void*)this._hissBuffer; + } + Utils.Memcpy(this._hissPtr, audio, length * 4); + this._hissFilter.Process(this._hissPtr, length); + for (int i = 0; i < this._hissBuffer.Length; i++) + { + this._noiseLevel = (1f - this._noiseAveragingRatio) * this._noiseLevel + this._noiseAveragingRatio * Math.Abs(this._hissPtr[i]); + if (this._noiseLevel > this._noiseThreshold) + { + audio[i] *= 1E-15f; + } + } + this._isSquelchOpen = (this._noiseLevel < this._noiseThreshold); + } + else + { + this._isSquelchOpen = true; + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/FmMode.cs b/SDRSharp.Radio/SDRSharp.Radio/FmMode.cs new file mode 100644 index 0000000..115b00a --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/FmMode.cs @@ -0,0 +1,8 @@ +namespace SDRSharp.Radio +{ + public enum FmMode + { + Narrow, + Wide + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/Fourier.cs b/SDRSharp.Radio/SDRSharp.Radio/Fourier.cs new file mode 100644 index 0000000..686a2b1 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/Fourier.cs @@ -0,0 +1,224 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + public static class Fourier + { + private const int MaxLutBits = 16; + + private const int MaxLutBins = 65536; + + private const int LutSize = 32768; + + private const double TwoPi = 6.2831853071795862; + + private static UnsafeBuffer _lutBuffer; + + private unsafe static Complex* _lut; + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern void FourierForwardTransformLut(Complex* buffer, int length, Complex* lut, int lutbits); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern void FourierForwardTransformSinCos(Complex* buffer, int length); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern void FourierForwardTransformRotator(Complex* buffer, int length); + + unsafe static Fourier() + { + Fourier._lutBuffer = UnsafeBuffer.Create(32768, sizeof(Complex)); + Fourier._lut = (Complex*)(void*)Fourier._lutBuffer; + for (int i = 0; i < 32768; i++) + { + Fourier._lut[i] = Complex.FromAngle(9.5873799242852573E-05 * (double)i).Conjugate(); + } + } + + public static float DecibelToRatio(float db) + { + return (float)Math.Pow(10.0, (double)db * 0.1); + } + + public unsafe static void SpectrumPower(Complex* buffer, float* power, int length, float offset = 0f) + { + for (int i = 0; i < length; i++) + { + float num = buffer[i].ModulusSquared(); + float num2 = power[i] = (float)(10.0 * Math.Log10(1E-60 + (double)num)) + offset; + } + } + + public unsafe static void ScaleFFT(float* src, byte* dest, int length, float minPower, float maxPower) + { + float num = 255f / (maxPower - minPower); + for (int i = 0; i < length; i++) + { + float num2 = src[i]; + if (num2 < minPower) + { + num2 = minPower; + } + else if (num2 > maxPower) + { + num2 = maxPower; + } + dest[i] = (byte)((num2 - minPower) * num); + } + } + + public unsafe static void SmoothMaxCopy(float* srcPtr, float* dstPtr, int sourceLength, int destinationLength, float zoom = 1f, float offset = 0f) + { + if (zoom < 1f) + { + zoom = 1f; + } + float num = (float)sourceLength / (zoom * (float)destinationLength); + float num2 = (float)sourceLength * (offset + 0.5f * (1f - 1f / zoom)); + if (num > 1f) + { + int num3 = (int)Math.Ceiling((double)num * 0.5); + int num4 = -1; + for (int i = 0; i < destinationLength; i++) + { + float num5 = -600f; + for (int j = -num3; j <= num3; j++) + { + int num6 = (int)Math.Round((double)(num2 + num * (float)i + (float)j)); + if (num6 > num4 && num6 >= 0 && num6 < sourceLength && num5 < srcPtr[num6]) + { + num5 = srcPtr[num6]; + } + num4 = num6; + } + dstPtr[i] = num5; + } + } + else + { + int num7 = (int)Math.Ceiling((double)(1f / num)); + float num8 = 1f / (float)num7; + int num9 = 0; + int num10 = (int)num2; + int num11 = num10 + 1; + int num12 = sourceLength - 1; + for (int k = 0; k < destinationLength; k++) + { + int num13 = (int)(num2 + (float)k * num); + if (num13 > num10) + { + num9 = 0; + if (num13 >= num12) + { + num10 = num12; + num11 = num12; + } + else + { + num10 = num13; + num11 = num13 + 1; + } + } + dstPtr[k] = (srcPtr[num10] * (float)(num7 - num9) + srcPtr[num11] * (float)num9) * num8; + num9++; + } + } + } + + public unsafe static void SmoothMinCopy(float* srcPtr, float* dstPtr, int sourceLength, int destinationLength, float zoom = 1f, float offset = 0f) + { + if (zoom < 1f) + { + zoom = 1f; + } + float num = (float)sourceLength / (zoom * (float)destinationLength); + float num2 = (float)sourceLength * (offset + 0.5f * (1f - 1f / zoom)); + if (num > 1f) + { + int num3 = (int)Math.Ceiling((double)num * 0.5); + int num4 = -1; + for (int i = 0; i < destinationLength; i++) + { + float num5 = 600f; + for (int j = -num3; j <= num3; j++) + { + int num6 = (int)Math.Round((double)(num2 + num * (float)i + (float)j)); + if (num6 > num4 && num6 >= 0 && num6 < sourceLength && num5 > srcPtr[num6]) + { + num5 = srcPtr[num6]; + } + num4 = num6; + } + dstPtr[i] = num5; + } + } + else + { + for (int k = 0; k < destinationLength; k++) + { + int num7 = (int)(num * (float)k + num2); + if (num7 >= 0 && num7 < sourceLength) + { + dstPtr[k] = srcPtr[num7]; + } + } + } + } + + public unsafe static void ApplyFFTWindow(Complex* buffer, float* window, int length) + { + for (int i = 0; i < length; i++) + { + buffer[i].Real *= window[i]; + buffer[i].Imag *= window[i]; + } + } + + public unsafe static void ForwardTransform(Complex* buffer, int length, bool rearrange = true) + { + if (length <= 128) + { + Fourier.FourierForwardTransformRotator(buffer, length); + } + else if (length <= 65536) + { + Fourier.FourierForwardTransformLut(buffer, length, Fourier._lut, 16); + } + else if (rearrange) + { + Fourier.FourierForwardTransformRotator(buffer, length); + } + else + { + Fourier.FourierForwardTransformSinCos(buffer, length); + } + if (rearrange) + { + int num = length / 2; + for (int i = 0; i < num; i++) + { + int num2 = num + i; + Complex complex = buffer[i]; + buffer[i] = buffer[num2]; + buffer[num2] = complex; + } + } + } + + public unsafe static void InverseTransform(Complex* samples, int length) + { + for (int i = 0; i < length; i++) + { + samples[i].Imag = 0f - samples[i].Imag; + } + Fourier.ForwardTransform(samples, length, false); + float num = 1f / (float)length; + for (int j = 0; j < length; j++) + { + samples[j].Real *= num; + samples[j].Imag = (0f - samples[j].Imag) * num; + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/FrequencyTranslator.cs b/SDRSharp.Radio/SDRSharp.Radio/FrequencyTranslator.cs new file mode 100644 index 0000000..aa9e05b --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/FrequencyTranslator.cs @@ -0,0 +1,70 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + public class FrequencyTranslator : IDisposable + { + private IntPtr _nco; + + private double _sampleRate; + + private double _frequency; + + public double SampleRate + { + get + { + return this._sampleRate; + } + } + + public double Frequency + { + get + { + return this._frequency; + } + set + { + if (this._frequency != value) + { + this._frequency = value; + FrequencyTranslator.nco_tune(this._nco, this._frequency); + } + } + } + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr nco_create(double sample_rate); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern void nco_destroy(IntPtr instance); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern void nco_tune(IntPtr instance, double frequency); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern void nco_process(IntPtr instance, Complex* buffer, int length); + + public FrequencyTranslator(double sampleRate) + { + this._sampleRate = sampleRate; + this._nco = FrequencyTranslator.nco_create(sampleRate); + } + + public void Dispose() + { + if (this._nco != IntPtr.Zero) + { + FrequencyTranslator.nco_destroy(this._nco); + this._nco = IntPtr.Zero; + } + } + + public unsafe void Process(Complex* buffer, int length) + { + FrequencyTranslator.nco_process(this._nco, buffer, length); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/HookManager.cs b/SDRSharp.Radio/SDRSharp.Radio/HookManager.cs new file mode 100644 index 0000000..957623c --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/HookManager.cs @@ -0,0 +1,221 @@ +using System.Collections.Generic; + +namespace SDRSharp.Radio +{ + public class HookManager + { + private readonly List _filteredAudioProcessors = new List(); + + private readonly List _demodulatorOutputProcessors = new List(); + + private readonly List _rawIQProcessors = new List(); + + private readonly List _decimatedAndFilteredIQProcessors = new List(); + + private readonly List _fmMPXProcessors = new List(); + + private readonly List _rdsBitStreamProcessors = new List(); + + public void RegisterStreamHook(object hook, ProcessorType processorType) + { + switch (processorType) + { + case ProcessorType.RawIQ: + lock (this._rawIQProcessors) + { + this._rawIQProcessors.Add((IIQProcessor)hook); + } + break; + case ProcessorType.DecimatedAndFilteredIQ: + lock (this._decimatedAndFilteredIQProcessors) + { + this._decimatedAndFilteredIQProcessors.Add((IIQProcessor)hook); + } + break; + case ProcessorType.DemodulatorOutput: + lock (this._demodulatorOutputProcessors) + { + this._demodulatorOutputProcessors.Add((IRealProcessor)hook); + } + break; + case ProcessorType.FilteredAudioOutput: + lock (this._filteredAudioProcessors) + { + this._filteredAudioProcessors.Add((IRealProcessor)hook); + } + break; + case ProcessorType.FMMPX: + lock (this._fmMPXProcessors) + { + this._fmMPXProcessors.Add((IRealProcessor)hook); + } + break; + case ProcessorType.RDSBitStream: + lock (this._rdsBitStreamProcessors) + { + this._rdsBitStreamProcessors.Add((IRdsBitStreamProcessor)hook); + } + break; + } + } + + public void UnregisterStreamHook(object hook) + { + if (hook != null) + { + if (hook is IIQProcessor) + { + IIQProcessor item = (IIQProcessor)hook; + lock (this._rawIQProcessors) + { + this._rawIQProcessors.Remove(item); + } + lock (this._decimatedAndFilteredIQProcessors) + { + this._decimatedAndFilteredIQProcessors.Remove(item); + } + } + if (hook is IRealProcessor) + { + IRealProcessor item2 = (IRealProcessor)hook; + lock (this._demodulatorOutputProcessors) + { + this._demodulatorOutputProcessors.Remove(item2); + } + lock (this._filteredAudioProcessors) + { + this._filteredAudioProcessors.Remove(item2); + } + lock (this._fmMPXProcessors) + { + this._fmMPXProcessors.Remove(item2); + } + } + if (hook is IRdsBitStreamProcessor) + { + IRdsBitStreamProcessor item3 = (IRdsBitStreamProcessor)hook; + lock (this._rdsBitStreamProcessors) + { + this._rdsBitStreamProcessors.Remove(item3); + } + } + } + } + + public void SetProcessorSampleRate(ProcessorType processorType, double sampleRate) + { + switch (processorType) + { + case ProcessorType.RawIQ: + this.SetSampleRate(this._rawIQProcessors, sampleRate); + break; + case ProcessorType.DecimatedAndFilteredIQ: + this.SetSampleRate(this._decimatedAndFilteredIQProcessors, sampleRate); + break; + case ProcessorType.DemodulatorOutput: + this.SetSampleRate(this._demodulatorOutputProcessors, sampleRate); + break; + case ProcessorType.FilteredAudioOutput: + this.SetSampleRate(this._filteredAudioProcessors, sampleRate); + break; + case ProcessorType.FMMPX: + this.SetSampleRate(this._fmMPXProcessors, sampleRate); + break; + } + } + + public unsafe void ProcessRawIQ(Complex* buffer, int length) + { + this.ProcessHooks(this._rawIQProcessors, buffer, length); + } + + public unsafe void ProcessDecimatedAndFilteredIQ(Complex* buffer, int length) + { + this.ProcessHooks(this._decimatedAndFilteredIQProcessors, buffer, length); + } + + public unsafe void ProcessDemodulatorOutput(float* buffer, int length) + { + this.ProcessHooks(this._demodulatorOutputProcessors, buffer, length); + } + + public unsafe void ProcessFilteredAudioOutput(float* buffer, int length) + { + this.ProcessHooks(this._filteredAudioProcessors, buffer, length); + } + + public unsafe void ProcessFMMPX(float* buffer, int length) + { + this.ProcessHooks(this._fmMPXProcessors, buffer, length); + } + + public void ProcessRdsBitStream(ref RdsFrame frame) + { + this.ProcessHooks(this._rdsBitStreamProcessors, ref frame); + } + + private void SetSampleRate(List processors, double sampleRate) + { + lock (processors) + { + for (int i = 0; i < processors.Count; i++) + { + processors[i].SampleRate = sampleRate; + } + } + } + + private void SetSampleRate(List processors, double sampleRate) + { + lock (processors) + { + for (int i = 0; i < processors.Count; i++) + { + processors[i].SampleRate = sampleRate; + } + } + } + + private unsafe void ProcessHooks(List processors, Complex* buffer, int length) + { + lock (processors) + { + for (int i = 0; i < processors.Count; i++) + { + if (processors[i].Enabled) + { + processors[i].Process(buffer, length); + } + } + } + } + + private unsafe void ProcessHooks(List processors, float* buffer, int length) + { + lock (processors) + { + for (int i = 0; i < processors.Count; i++) + { + if (processors[i].Enabled) + { + processors[i].Process(buffer, length); + } + } + } + } + + private void ProcessHooks(List processors, ref RdsFrame frame) + { + lock (processors) + { + for (int i = 0; i < processors.Count; i++) + { + if (processors[i].Enabled) + { + processors[i].Process(ref frame); + } + } + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IBaseProcessor.cs b/SDRSharp.Radio/SDRSharp.Radio/IBaseProcessor.cs new file mode 100644 index 0000000..169183a --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IBaseProcessor.cs @@ -0,0 +1,11 @@ +namespace SDRSharp.Radio +{ + public interface IBaseProcessor + { + bool Enabled + { + get; + set; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IConfigurationPanelProvider.cs b/SDRSharp.Radio/SDRSharp.Radio/IConfigurationPanelProvider.cs new file mode 100644 index 0000000..37999c2 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IConfigurationPanelProvider.cs @@ -0,0 +1,12 @@ +using System.Windows.Forms; + +namespace SDRSharp.Radio +{ + public interface IConfigurationPanelProvider + { + UserControl Gui + { + get; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IConnectableSource.cs b/SDRSharp.Radio/SDRSharp.Radio/IConnectableSource.cs new file mode 100644 index 0000000..6f08e55 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IConnectableSource.cs @@ -0,0 +1,14 @@ +namespace SDRSharp.Radio +{ + public interface IConnectableSource + { + bool Connected + { + get; + } + + void Connect(); + + void Disconnect(); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IControlAwareObject.cs b/SDRSharp.Radio/SDRSharp.Radio/IControlAwareObject.cs new file mode 100644 index 0000000..d6bcd3d --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IControlAwareObject.cs @@ -0,0 +1,7 @@ +namespace SDRSharp.Radio +{ + public interface IControlAwareObject + { + void SetControl(object control); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IFloatingConfigDialogProvider.cs b/SDRSharp.Radio/SDRSharp.Radio/IFloatingConfigDialogProvider.cs new file mode 100644 index 0000000..f55414a --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IFloatingConfigDialogProvider.cs @@ -0,0 +1,11 @@ +using System.Windows.Forms; + +namespace SDRSharp.Radio +{ + public interface IFloatingConfigDialogProvider + { + void ShowSettingGUI(IWin32Window parent); + + void HideSettingGUI(); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IFrontendController.cs b/SDRSharp.Radio/SDRSharp.Radio/IFrontendController.cs new file mode 100644 index 0000000..230a738 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IFrontendController.cs @@ -0,0 +1,9 @@ +namespace SDRSharp.Radio +{ + public interface IFrontendController + { + void Open(); + + void Close(); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IFrontendOffset.cs b/SDRSharp.Radio/SDRSharp.Radio/IFrontendOffset.cs new file mode 100644 index 0000000..8683d7f --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IFrontendOffset.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.Radio +{ + public interface IFrontendOffset + { + int Offset + { + get; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IIQProcessor.cs b/SDRSharp.Radio/SDRSharp.Radio/IIQProcessor.cs new file mode 100644 index 0000000..68efc90 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IIQProcessor.cs @@ -0,0 +1,7 @@ +namespace SDRSharp.Radio +{ + public interface IIQProcessor : IStreamProcessor, IBaseProcessor + { + unsafe void Process(Complex* buffer, int length); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IIQStreamController.cs b/SDRSharp.Radio/SDRSharp.Radio/IIQStreamController.cs new file mode 100644 index 0000000..2be8804 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IIQStreamController.cs @@ -0,0 +1,14 @@ +namespace SDRSharp.Radio +{ + public interface IIQStreamController + { + double Samplerate + { + get; + } + + void Start(SamplesAvailableDelegate callback); + + void Stop(); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/INonBlockingController.cs b/SDRSharp.Radio/SDRSharp.Radio/INonBlockingController.cs new file mode 100644 index 0000000..aab0f53 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/INonBlockingController.cs @@ -0,0 +1,6 @@ +namespace SDRSharp.Radio +{ + public interface INonBlockingController + { + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IQBalancer.cs b/SDRSharp.Radio/SDRSharp.Radio/IQBalancer.cs new file mode 100644 index 0000000..16c78ce --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IQBalancer.cs @@ -0,0 +1,242 @@ +using System; + +namespace SDRSharp.Radio +{ + public class IQBalancer + { + private const int FFTBins = 128; + + private const int SkippedBuffers = 5; + + private const float DcTimeConst = 1E-05f; + + private const float MaximumStep = 0.01f; + + private const float MinimumStep = 1E-05f; + + private const float StepIncrement = 1.1f; + + private const float StepDecrement = 0.9090909f; + + private const float MaxPhaseCorrection = 0.2f; + + private const float PhaseAlpha = 0.01f; + + private const float GainAlpha = 0.01f; + + private bool _enabled; + + private float _phase; + + private float _lastPhase; + + private float _step = 1E-05f; + + private float _stepFactor = 0.9090909f; + + private double _gain; + + private double _iampavg; + + private double _qampavg; + + private unsafe readonly DcRemover* _dcRemoverI; + + private readonly UnsafeBuffer _dcRemoverIBuffer; + + private unsafe readonly DcRemover* _dcRemoverQ; + + private readonly UnsafeBuffer _dcRemoverQBuffer; + + private readonly bool _isMultithreaded; + + private readonly SharpEvent _event = new SharpEvent(false); + + private unsafe static readonly float* _windowPtr; + + private static readonly UnsafeBuffer _windowBuffer; + + public float Phase + { + get + { + return (float)Math.Asin((double)this._phase); + } + } + + public float Gain + { + get + { + return (float)this._gain; + } + } + + public bool Enabled + { + get + { + return this._enabled; + } + set + { + this._enabled = value; + } + } + + public unsafe IQBalancer() + { + this._dcRemoverIBuffer = UnsafeBuffer.Create(sizeof(DcRemover)); + this._dcRemoverI = (DcRemover*)(void*)this._dcRemoverIBuffer; + this._dcRemoverI->Init(1E-05f); + this._dcRemoverQBuffer = UnsafeBuffer.Create(sizeof(DcRemover)); + this._dcRemoverQ = (DcRemover*)(void*)this._dcRemoverQBuffer; + this._dcRemoverQ->Init(1E-05f); + this._isMultithreaded = (Environment.ProcessorCount > 1); + } + + unsafe static IQBalancer() + { + IQBalancer._windowBuffer = UnsafeBuffer.Create(FilterBuilder.MakeWindow(WindowType.BlackmanHarris7, 128)); + IQBalancer._windowPtr = (float*)(void*)IQBalancer._windowBuffer; + } + + public unsafe void Reset() + { + this._phase = 0f; + this._lastPhase = 0f; + this._gain = 1.0; + this._step = 1E-05f; + this._stepFactor = 1.1f; + this._iampavg = 1.0; + this._qampavg = 1.0; + this._dcRemoverI->Reset(); + this._dcRemoverQ->Reset(); + } + + public unsafe void Process(Complex* iq, int length) + { + if (this._enabled) + { + this.RemoveDC(iq, length); + int num = 0; + while (length >= 128) + { + if (num % 5 == 0) + { + this.EstimatePhaseImbalance(iq); + } + this.Adjust(iq, 128); + iq += 128; + length -= 128; + num++; + } + this.Adjust(iq, length); + } + } + + private unsafe void RemoveDC(Complex* iq, int length) + { + float* buffer = (float*)((byte*)iq + 4); + if (this._isMultithreaded) + { + DSPThreadPool.QueueUserWorkItem(delegate + { + this._dcRemoverI->ProcessInterleaved((float*)iq, length); + this._event.Set(); + }); + } + else + { + this._dcRemoverI->ProcessInterleaved((float*)iq, length); + } + this._dcRemoverQ->ProcessInterleaved(buffer, length); + if (this._isMultithreaded) + { + this._event.WaitOne(); + } + } + + private unsafe void EstimatePhaseImbalance(Complex* iq) + { + float num = this.Utility(iq, this._phase); + float num2 = this._phase + this._step; + if (num2 > 0.2f) + { + num2 = 0.2f; + } + if (num2 < -0.2f) + { + num2 = -0.2f; + } + if (this.Utility(iq, num2) > num) + { + this._phase += 0.01f * (num2 - this._phase); + } + else + { + if (Math.Abs(this._step) < 1E-05f) + { + this._stepFactor = -1.1f; + } + else if (Math.Abs(this._step) > 0.01f) + { + this._stepFactor = -0.9090909f; + } + this._step *= this._stepFactor; + } + } + + private unsafe float Utility(Complex* iq, float phase) + { + Complex* ptr = stackalloc Complex[128 * sizeof(Complex)]; + Utils.Memcpy(ptr, iq, 128 * sizeof(Complex)); + this.AdjustPhase(ptr, phase); + Fourier.ApplyFFTWindow(ptr, IQBalancer._windowPtr, 128); + Fourier.ForwardTransform(ptr, 128, false); + float num = 0f; + int num2 = 1; + int num3 = 127; + while (num2 < 64) + { + float num4 = Math.Abs(ptr[num2].Real) + Math.Abs(ptr[num2].Imag); + float num5 = Math.Abs(ptr[num3].Real) + Math.Abs(ptr[num3].Imag); + num += Math.Abs(num4 - num5); + num2++; + num3--; + } + return num; + } + + private unsafe void AdjustPhase(Complex* iq, float phase) + { + float num = (float)this._gain; + for (int i = 0; i < 128; i++) + { + iq[i].Real += phase * iq[i].Imag; + iq[i].Imag *= num; + } + } + + private unsafe void Adjust(Complex* iq, int length) + { + float num = 1f / (float)(length - 1); + for (int i = 0; i < length; i++) + { + float num2 = ((float)i * this._lastPhase + (float)(length - 1 - i) * this._phase) * num; + iq[i].Real += num2 * iq[i].Imag; + float num3 = iq[i].Real * iq[i].Real; + float num4 = iq[i].Imag * iq[i].Imag; + this._iampavg += 9.9999997473787516E-06 * ((double)num3 - this._iampavg); + this._qampavg += 9.9999997473787516E-06 * ((double)num4 - this._qampavg); + if (this._qampavg != 0.0) + { + double num5 = Math.Sqrt(this._iampavg / this._qampavg); + this._gain += 0.0099999997764825821 * (num5 - this._gain); + } + iq[i].Imag *= (float)this._gain; + } + this._lastPhase = this._phase; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IQFirFilter.cs b/SDRSharp.Radio/SDRSharp.Radio/IQFirFilter.cs new file mode 100644 index 0000000..e1e1239 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IQFirFilter.cs @@ -0,0 +1,68 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + public sealed class IQFirFilter : IDisposable + { + private int _decimationRatio; + + private int _length; + + private IntPtr _fir; + + public int Length + { + get + { + return this._length; + } + } + + public int DecimationRatio + { + get + { + return this._decimationRatio; + } + } + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern IntPtr complex_fir_create(float* kernel, int length, int decimation); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private static extern void complex_fir_destroy(IntPtr instance); + + [DllImport("shark", CallingConvention = CallingConvention.Cdecl)] + private unsafe static extern int complex_fir_process(IntPtr instance, Complex* buffer, int length); + + public unsafe IQFirFilter(float[] coefficients, int decimationRatio = 1) + { + if (decimationRatio <= 0) + { + throw new ArgumentException("The decimation factor must be greater than zero", "decimationRatio"); + } + this._decimationRatio = decimationRatio; + this._length = coefficients.Length; + fixed (float* kernel = coefficients) + { + this._fir = IQFirFilter.complex_fir_create(kernel, this._length, decimationRatio); + } + } + + public void Dispose() + { + if (this._fir != IntPtr.Zero) + { + IQFirFilter.complex_fir_destroy(this._fir); + this._fir = IntPtr.Zero; + } + GC.SuppressFinalize(this); + } + + public unsafe int Process(Complex* buffer, int length) + { + return IQFirFilter.complex_fir_process(this._fir, buffer, length); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IRdsBitStreamProcessor.cs b/SDRSharp.Radio/SDRSharp.Radio/IRdsBitStreamProcessor.cs new file mode 100644 index 0000000..36d5f43 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IRdsBitStreamProcessor.cs @@ -0,0 +1,7 @@ +namespace SDRSharp.Radio +{ + public interface IRdsBitStreamProcessor : IBaseProcessor + { + void Process(ref RdsFrame frame); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IRealProcessor.cs b/SDRSharp.Radio/SDRSharp.Radio/IRealProcessor.cs new file mode 100644 index 0000000..202b29c --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IRealProcessor.cs @@ -0,0 +1,7 @@ +namespace SDRSharp.Radio +{ + public interface IRealProcessor : IStreamProcessor, IBaseProcessor + { + unsafe void Process(float* buffer, int length); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/ISampleRateChangeSource.cs b/SDRSharp.Radio/SDRSharp.Radio/ISampleRateChangeSource.cs new file mode 100644 index 0000000..3392071 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/ISampleRateChangeSource.cs @@ -0,0 +1,9 @@ +using System; + +namespace SDRSharp.Radio +{ + public interface ISampleRateChangeSource + { + event EventHandler SampleRateChanged; + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/ISoundcardController.cs b/SDRSharp.Radio/SDRSharp.Radio/ISoundcardController.cs new file mode 100644 index 0000000..1f07a2b --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/ISoundcardController.cs @@ -0,0 +1,15 @@ +namespace SDRSharp.Radio +{ + public interface ISoundcardController + { + string SoundCardHint + { + get; + } + + double SampleRateHint + { + get; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/ISpectrumProvider.cs b/SDRSharp.Radio/SDRSharp.Radio/ISpectrumProvider.cs new file mode 100644 index 0000000..dc1ed0f --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/ISpectrumProvider.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.Radio +{ + public interface ISpectrumProvider + { + float UsableSpectrumRatio + { + get; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IStreamProcessor.cs b/SDRSharp.Radio/SDRSharp.Radio/IStreamProcessor.cs new file mode 100644 index 0000000..8d89cd1 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IStreamProcessor.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.Radio +{ + public interface IStreamProcessor : IBaseProcessor + { + double SampleRate + { + set; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/ITunableSource.cs b/SDRSharp.Radio/SDRSharp.Radio/ITunableSource.cs new file mode 100644 index 0000000..bada880 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/ITunableSource.cs @@ -0,0 +1,26 @@ +namespace SDRSharp.Radio +{ + public interface ITunableSource + { + bool CanTune + { + get; + } + + long Frequency + { + get; + set; + } + + long MinimumTunableFrequency + { + get; + } + + long MaximumTunableFrequency + { + get; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IirFilter.cs b/SDRSharp.Radio/SDRSharp.Radio/IirFilter.cs new file mode 100644 index 0000000..cd2977a --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IirFilter.cs @@ -0,0 +1,105 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + [StructLayout(LayoutKind.Sequential, Pack = 16)] + public struct IirFilter + { + private float _a0; + + private float _a1; + + private float _a2; + + private float _b0; + + private float _b1; + + private float _b2; + + private float _x1; + + private float _x2; + + private float _y1; + + private float _y2; + + public void Init(IirFilterType filterType, double frequency, double sampleRate, double qualityFactor) + { + double num = 6.2831853071795862 * frequency / sampleRate; + double num2 = Math.Sin(num) / (2.0 * qualityFactor); + switch (filterType) + { + case IirFilterType.LowPass: + this._b0 = (float)((1.0 - Math.Cos(num)) / 2.0); + this._b1 = (float)(1.0 - Math.Cos(num)); + this._b2 = (float)((1.0 - Math.Cos(num)) / 2.0); + this._a0 = (float)(1.0 + num2); + this._a1 = (float)(-2.0 * Math.Cos(num)); + this._a2 = (float)(1.0 - num2); + break; + case IirFilterType.HighPass: + this._b0 = (float)((1.0 + Math.Cos(num)) / 2.0); + this._b1 = (float)(0.0 - (1.0 + Math.Cos(num))); + this._b2 = (float)((1.0 + Math.Cos(num)) / 2.0); + this._a0 = (float)(1.0 + num2); + this._a1 = (float)(-2.0 * Math.Cos(num)); + this._a2 = (float)(1.0 - num2); + break; + default: + this._b0 = (float)num2; + this._b1 = 0f; + this._b2 = (float)(0.0 - num2); + this._a0 = (float)(1.0 + num2); + this._a1 = (float)(-2.0 * Math.Cos(num)); + this._a2 = (float)(1.0 - num2); + break; + case IirFilterType.Notch: + this._b0 = 1f; + this._b1 = (float)(-2.0 * Math.Cos(num)); + this._b2 = 1f; + this._a0 = (float)(1.0 + num2); + this._a1 = (float)(-2.0 * Math.Cos(num)); + this._a2 = (float)(1.0 - num2); + break; + } + this._b0 /= this._a0; + this._b1 /= this._a0; + this._b2 /= this._a0; + this._a1 /= this._a0; + this._a2 /= this._a0; + this._x1 = 0f; + this._x2 = 0f; + this._y1 = 0f; + this._y2 = 0f; + } + + public void Reset() + { + this._x1 = 0f; + this._x2 = 0f; + this._y1 = 0f; + this._y2 = 0f; + } + + public float Process(float sample) + { + float num = this._b0 * sample + this._b1 * this._x1 + this._b2 * this._x2 - this._a1 * this._y1 - this._a2 * this._y2; + this._x2 = this._x1; + this._x1 = sample; + this._y2 = this._y1; + this._y1 = num; + return num; + } + + public unsafe void Process(float* buffer, int length) + { + for (int i = 0; i < length; i++) + { + buffer[i] = this.Process(buffer[i]); + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/IirFilterType.cs b/SDRSharp.Radio/SDRSharp.Radio/IirFilterType.cs new file mode 100644 index 0000000..de3860b --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/IirFilterType.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.Radio +{ + public enum IirFilterType + { + LowPass, + HighPass, + BandPass, + Notch + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/Oscillator.cs b/SDRSharp.Radio/SDRSharp.Radio/Oscillator.cs new file mode 100644 index 0000000..a4100b5 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/Oscillator.cs @@ -0,0 +1,100 @@ +namespace SDRSharp.Radio +{ + public class Oscillator + { + private Complex _vector; + + private Complex _rotation; + + private double _sampleRate; + + private double _frequency; + + public double SampleRate + { + get + { + return this._sampleRate; + } + set + { + if (this._sampleRate != value) + { + this._sampleRate = value; + this.Configure(); + } + } + } + + public double Frequency + { + get + { + return this._frequency; + } + set + { + if (this._frequency != value) + { + this._frequency = value; + this.Configure(); + } + } + } + + public Complex Phase + { + get + { + return this._vector; + } + set + { + this._vector = value; + } + } + + public float Real + { + get + { + return this._vector.Real; + } + set + { + this._vector.Real = value; + } + } + + public float Imag + { + get + { + return this._vector.Imag; + } + set + { + this._vector.Imag = value; + } + } + + private void Configure() + { + if (this._vector.Real == 0f && this._vector.Imag == 0f) + { + this._vector.Real = 1f; + } + if (this._sampleRate != 0.0) + { + double angle = 6.2831853071795862 * this._frequency / this._sampleRate; + this._rotation = Complex.FromAngle(angle); + } + } + + public void Tick() + { + this._vector *= this._rotation; + this._vector = this._vector.NormalizeFast(); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/OverlapAddProcessor.cs b/SDRSharp.Radio/SDRSharp.Radio/OverlapAddProcessor.cs new file mode 100644 index 0000000..739d0c6 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/OverlapAddProcessor.cs @@ -0,0 +1,121 @@ +using System; + +namespace SDRSharp.Radio +{ + public abstract class OverlapAddProcessor + { + private readonly int _fftSize; + + private readonly int _halfSize; + + private int _inputPos; + + private int _outputPos; + + private UnsafeBuffer _fftBuffer; + + private unsafe Complex* _fftPtr; + + private UnsafeBuffer _queuepBuffer; + + private unsafe Complex* _queuePtr; + + private UnsafeBuffer _outputBuffer; + + private unsafe Complex* _outputPtr; + + private UnsafeBuffer _overlapBuffer; + + private unsafe Complex* _overlapPtr; + + private UnsafeBuffer _windowBuffer; + + private unsafe float* _windowPtr; + + public int FFTSize + { + get + { + return this._fftSize; + } + } + + public unsafe OverlapAddProcessor(int fftSize) + { + this._fftSize = fftSize; + this._halfSize = this._fftSize / 2; + this._inputPos = this._halfSize; + this._queuepBuffer = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); + this._queuePtr = (Complex*)(void*)this._queuepBuffer; + this._windowBuffer = UnsafeBuffer.Create(this._fftSize, 4); + this._windowPtr = (float*)(void*)this._windowBuffer; + this._fftBuffer = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); + this._fftPtr = (Complex*)(void*)this._fftBuffer; + this._outputBuffer = UnsafeBuffer.Create(this._halfSize, sizeof(Complex)); + this._outputPtr = (Complex*)(void*)this._outputBuffer; + this._overlapBuffer = UnsafeBuffer.Create(this._halfSize, sizeof(Complex)); + this._overlapPtr = (Complex*)(void*)this._overlapBuffer; + double num = 1.5707963267948966 / (double)(this._halfSize - 1); + for (int i = 0; i < this._halfSize; i++) + { + double a = (double)i * num; + this._windowPtr[i] = (float)Math.Sin(a); + this._windowPtr[this._fftSize - 1 - i] = this._windowPtr[i]; + } + } + + public unsafe virtual void Process(Complex* buffer, int length) + { + while (length > 0) + { + int num = Math.Min(this._fftSize - this._inputPos, length); + Utils.Memcpy(this._queuePtr + this._inputPos, buffer, num * sizeof(Complex)); + Utils.Memcpy(buffer, this._outputPtr + this._outputPos, num * sizeof(Complex)); + buffer += num; + this._inputPos += num; + this._outputPos += num; + length -= num; + if (this._inputPos == this._fftSize) + { + this.OverlapAdd(); + this._inputPos = this._halfSize; + this._outputPos = 0; + } + } + } + + public unsafe virtual void Process(float* buffer, int length, int step = 1) + { + for (int i = 0; i < length; i += step) + { + this._queuePtr[this._inputPos++] = buffer[i]; + buffer[i] = this._outputPtr[this._outputPos++].Real; + if (this._inputPos == this._fftSize) + { + this.OverlapAdd(); + this._inputPos = this._halfSize; + this._outputPos = 0; + } + } + } + + private unsafe void OverlapAdd() + { + for (int i = 0; i < this._fftSize; i++) + { + this._fftPtr[i] = this._queuePtr[i] * this._windowPtr[i]; + } + Fourier.ForwardTransform(this._fftPtr, this._fftSize, false); + this.ProcessFft(this._fftPtr, this._fftSize); + Fourier.InverseTransform(this._fftPtr, this._fftSize); + for (int j = 0; j < this._halfSize; j++) + { + this._outputPtr[j] = this._overlapPtr[j] * this._windowPtr[this._halfSize + j] + this._fftPtr[j] * this._windowPtr[j]; + } + Utils.Memcpy(this._overlapPtr, this._fftPtr + this._halfSize, this._halfSize * sizeof(Complex)); + Utils.Memcpy(this._queuePtr, this._queuePtr + this._halfSize, this._halfSize * sizeof(Complex)); + } + + protected unsafe abstract void ProcessFft(Complex* buffer, int length); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/OverlapCrossfadeProcessor.cs b/SDRSharp.Radio/SDRSharp.Radio/OverlapCrossfadeProcessor.cs new file mode 100644 index 0000000..dfa5a2a --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/OverlapCrossfadeProcessor.cs @@ -0,0 +1,130 @@ +using System; + +namespace SDRSharp.Radio +{ + public abstract class OverlapCrossfadeProcessor + { + private readonly int _fftSize; + + private readonly int _halfSize; + + private readonly int _outputSize; + + private readonly int _crossFadingSize; + + private int _inputPos; + + private int _outputPos; + + private UnsafeBuffer _fftBuffer; + + private unsafe Complex* _fftPtr; + + private UnsafeBuffer _queuepBuffer; + + private unsafe Complex* _queuePtr; + + private UnsafeBuffer _outputBuffer; + + private unsafe Complex* _outputPtr; + + private UnsafeBuffer _crossFadingBuffer; + + private unsafe Complex* _crossFadingPtr; + + private UnsafeBuffer _windowBuffer; + + private unsafe float* _windowPtr; + + public int FFTSize + { + get + { + return this._fftSize; + } + } + + public unsafe OverlapCrossfadeProcessor(int fftSize, float crossFadingRatio = 0f) + { + this._fftSize = fftSize; + this._halfSize = this._fftSize / 2; + this._crossFadingSize = (int)((float)this._halfSize * crossFadingRatio); + this._outputSize = this._halfSize - this._crossFadingSize; + this._inputPos = this._halfSize + this._crossFadingSize; + this._queuepBuffer = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); + this._queuePtr = (Complex*)(void*)this._queuepBuffer; + this._windowBuffer = UnsafeBuffer.Create(this._crossFadingSize, 4); + this._windowPtr = (float*)(void*)this._windowBuffer; + this._fftBuffer = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); + this._fftPtr = (Complex*)(void*)this._fftBuffer; + this._outputBuffer = UnsafeBuffer.Create(this._outputSize, sizeof(Complex)); + this._outputPtr = (Complex*)(void*)this._outputBuffer; + this._crossFadingBuffer = UnsafeBuffer.Create(this._crossFadingSize, sizeof(Complex)); + this._crossFadingPtr = (Complex*)(void*)this._crossFadingBuffer; + double num = 1.5707963267948966 / (double)(this._crossFadingSize - 1); + for (int i = 0; i < this._crossFadingSize; i++) + { + double a = (double)i * num; + this._windowPtr[i] = (float)Math.Pow(Math.Sin(a), 2.0); + } + } + + public unsafe virtual void Process(Complex* buffer, int length) + { + while (length > 0) + { + int num = Math.Min(this._fftSize - this._inputPos, length); + Utils.Memcpy(this._queuePtr + this._inputPos, buffer, num * sizeof(Complex)); + Utils.Memcpy(buffer, this._outputPtr + this._outputPos, num * sizeof(Complex)); + buffer += num; + this._inputPos += num; + this._outputPos += num; + length -= num; + if (this._inputPos == this._fftSize) + { + this.OverlapCrossfade(); + this._inputPos = this._halfSize + this._crossFadingSize; + this._outputPos = 0; + } + } + } + + public unsafe virtual void Process(float* buffer, int length, int step = 1) + { + for (int i = 0; i < length; i += step) + { + this._queuePtr[this._inputPos++] = buffer[i]; + buffer[i] = this._outputPtr[this._outputPos++].Real; + if (this._inputPos == this._fftSize) + { + this.OverlapCrossfade(); + this._inputPos = this._halfSize + this._crossFadingSize; + this._outputPos = 0; + } + } + } + + private unsafe void OverlapCrossfade() + { + Utils.Memcpy(this._fftPtr, this._queuePtr, this._fftSize * sizeof(Complex)); + Fourier.ForwardTransform(this._fftPtr, this._fftSize, false); + this.ProcessFft(this._fftPtr, this._fftSize); + Fourier.InverseTransform(this._fftPtr, this._fftSize); + int num = 0; + int num2 = this._crossFadingSize - 1; + int num3 = this._halfSize; + while (num < this._crossFadingSize) + { + this._outputPtr[num] = this._fftPtr[num3] * this._windowPtr[num] + this._crossFadingPtr[num] * this._windowPtr[num2]; + num++; + num2--; + num3++; + } + Utils.Memcpy(this._outputPtr + this._crossFadingSize, this._fftPtr + this._halfSize + this._crossFadingSize, (this._outputSize - this._crossFadingSize) * sizeof(Complex)); + Utils.Memcpy(this._crossFadingPtr, this._fftPtr + this._halfSize + this._outputSize, this._crossFadingSize * sizeof(Complex)); + Utils.Memcpy(this._queuePtr, this._queuePtr + this._outputSize, (this._fftSize - this._outputSize) * sizeof(Complex)); + } + + protected unsafe abstract void ProcessFft(Complex* buffer, int length); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/OverlapSaveProcessor.cs b/SDRSharp.Radio/SDRSharp.Radio/OverlapSaveProcessor.cs new file mode 100644 index 0000000..0eba2d2 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/OverlapSaveProcessor.cs @@ -0,0 +1,95 @@ +using System; + +namespace SDRSharp.Radio +{ + public abstract class OverlapSaveProcessor + { + private readonly int _fftSize; + + private readonly int _halfSize; + + private int _inputPos; + + private int _outputPos; + + private UnsafeBuffer _fftBuffer; + + private unsafe Complex* _fftPtr; + + private UnsafeBuffer _queuepBuffer; + + private unsafe Complex* _queuePtr; + + private UnsafeBuffer _outputBuffer; + + private unsafe Complex* _outputPtr; + + public int FFTSize + { + get + { + return this._fftSize; + } + } + + public unsafe OverlapSaveProcessor(int fftSize) + { + this._fftSize = fftSize; + this._halfSize = this._fftSize / 2; + this._inputPos = this._halfSize; + this._queuepBuffer = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); + this._queuePtr = (Complex*)(void*)this._queuepBuffer; + this._fftBuffer = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); + this._fftPtr = (Complex*)(void*)this._fftBuffer; + this._outputBuffer = UnsafeBuffer.Create(this._halfSize, sizeof(Complex)); + this._outputPtr = (Complex*)(void*)this._outputBuffer; + } + + public unsafe virtual void Process(Complex* buffer, int length) + { + while (length > 0) + { + int num = Math.Min(this._fftSize - this._inputPos, length); + Utils.Memcpy(this._queuePtr + this._inputPos, buffer, num * sizeof(Complex)); + Utils.Memcpy(buffer, this._outputPtr + this._outputPos, num * sizeof(Complex)); + buffer += num; + this._inputPos += num; + this._outputPos += num; + length -= num; + if (this._inputPos == this._fftSize) + { + this.OverlapSave(); + this._inputPos = this._halfSize; + this._outputPos = 0; + } + } + } + + public unsafe virtual void Process(float* buffer, int length, int step = 1) + { + for (int i = 0; i < length; i += step) + { + this._queuePtr[this._inputPos++] = buffer[i]; + buffer[i] = this._outputPtr[this._outputPos++].Real; + if (this._inputPos == this._fftSize) + { + this.OverlapSave(); + this._inputPos = this._halfSize; + this._outputPos = 0; + } + } + } + + private unsafe void OverlapSave() + { + Utils.Memcpy(this._fftPtr, this._queuePtr, this._fftSize * sizeof(Complex)); + Fourier.ForwardTransform(this._fftPtr, this._fftSize, false); + this.ProcessFft(this._fftPtr, this._fftSize); + Fourier.InverseTransform(this._fftPtr, this._fftSize); + Utils.Memcpy(this._outputPtr, this._fftPtr + this._halfSize, this._halfSize * sizeof(Complex)); + Utils.Memcpy(this._queuePtr, this._queuePtr + this._halfSize, this._halfSize * sizeof(Complex)); + } + + protected unsafe abstract void ProcessFft(Complex* buffer, int length); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/OverlapSlideProcessor.cs b/SDRSharp.Radio/SDRSharp.Radio/OverlapSlideProcessor.cs new file mode 100644 index 0000000..4bf35e8 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/OverlapSlideProcessor.cs @@ -0,0 +1,136 @@ +using System; + +namespace SDRSharp.Radio +{ + public abstract class OverlapSlideProcessor + { + private readonly int _fftSize; + + private readonly int _outputSize; + + private readonly float _overlapRatio; + + private int _inputPos; + + private int _outputPos; + + private UnsafeBuffer _fftBuffer; + + private unsafe Complex* _fftPtr; + + private UnsafeBuffer _queuepBuffer; + + private unsafe Complex* _queuePtr; + + private UnsafeBuffer _outputBuffer; + + private unsafe Complex* _outputPtr; + + private UnsafeBuffer _overlapBuffer; + + private unsafe Complex* _overlapPtr; + + public int FFTSize + { + get + { + return this._fftSize; + } + } + + public float OverlapRatio + { + get + { + return this._overlapRatio; + } + } + + public OverlapSlideProcessor(int fftSize) + : this(fftSize, 0.75f) + { + } + + public unsafe OverlapSlideProcessor(int fftSize, float overlapRatio) + { + if (overlapRatio < 0.75f) + { + throw new ArgumentException("Overlap ratio must be greater than or equal to 0.75", "overlapRatio"); + } + if (overlapRatio > 1f) + { + throw new ArgumentException("Overlap ratio must be less than 1.0", "overlapRatio"); + } + this._fftSize = fftSize; + this._outputSize = (int)Math.Round((double)((float)this._fftSize * (1f - overlapRatio))); + if (this._outputSize < 3) + { + this._outputSize = 3; + } + this._overlapRatio = 1f - (float)this._outputSize / (float)this._fftSize; + this._inputPos = this._fftSize - this._outputSize; + this._queuepBuffer = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); + this._queuePtr = (Complex*)(void*)this._queuepBuffer; + this._fftBuffer = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); + this._fftPtr = (Complex*)(void*)this._fftBuffer; + this._outputBuffer = UnsafeBuffer.Create(this._outputSize, sizeof(Complex)); + this._outputPtr = (Complex*)(void*)this._outputBuffer; + this._overlapBuffer = UnsafeBuffer.Create(this._outputSize, sizeof(Complex)); + this._overlapPtr = (Complex*)(void*)this._overlapBuffer; + } + + public unsafe virtual void Process(Complex* buffer, int length) + { + while (length > 0) + { + int num = Math.Min(this._fftSize - this._inputPos, length); + Utils.Memcpy(this._queuePtr + this._inputPos, buffer, num * sizeof(Complex)); + Utils.Memcpy(buffer, this._outputPtr + this._outputPos, num * sizeof(Complex)); + buffer += num; + this._inputPos += num; + this._outputPos += num; + length -= num; + if (this._inputPos == this._fftSize) + { + this.OverlapAdd(); + this._inputPos = this._fftSize - this._outputSize; + this._outputPos = 0; + } + } + } + + public unsafe virtual void Process(float* buffer, int length, int step = 1) + { + for (int i = 0; i < length; i += step) + { + this._queuePtr[this._inputPos++] = buffer[i]; + buffer[i] = this._outputPtr[this._outputPos++].Real; + if (this._inputPos == this._fftSize) + { + this.OverlapAdd(); + this._inputPos = this._fftSize - this._outputSize; + this._outputPos = 0; + } + } + } + + private unsafe void OverlapAdd() + { + Utils.Memcpy(this._fftPtr, this._queuePtr, this._fftSize * sizeof(Complex)); + Fourier.ForwardTransform(this._fftPtr, this._fftSize, false); + this.ProcessFft(this._fftPtr, this._fftSize); + Fourier.InverseTransform(this._fftPtr, this._fftSize); + Complex* ptr = this._fftPtr + this._fftSize / 2; + float num = 1f / (float)(this._outputSize - 1); + for (int i = 0; i < this._outputSize; i++) + { + float num2 = num * (float)i; + this._outputPtr[i] = this._overlapPtr[i] * (1f - num2) + ptr[i] * num2; + } + Utils.Memmove(this._overlapPtr, ptr + this._outputSize, this._outputSize * sizeof(Complex)); + Utils.Memmove(this._queuePtr, this._queuePtr + this._outputSize, (this._fftSize - this._outputSize) * sizeof(Complex)); + } + + protected unsafe abstract void ProcessFft(Complex* buffer, int length); + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/Pll.cs b/SDRSharp.Radio/SDRSharp.Radio/Pll.cs new file mode 100644 index 0000000..b0eb75c --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/Pll.cs @@ -0,0 +1,295 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + [StructLayout(LayoutKind.Sequential, Pack = 16)] + public struct Pll + { + private float _sampleRate; + + private float _phase; + + private float _frequencyRadian; + + private float _minFrequencyRadian; + + private float _maxFrequencyRadian; + + private float _defaultFrequency; + + private float _range; + + private float _bandwidth; + + private float _alpha; + + private float _beta; + + private float _zeta; + + private float _phaseAdj; + + private float _phaseAdjM; + + private float _phaseAdjB; + + private float _lockAlpha; + + private float _lockOneMinusAlpha; + + private float _lockTime; + + private float _phaseErrorAvg; + + private float _adjustedPhase; + + private float _lockThreshold; + + private bool _stickOnFrequencyIfNotLocked; + + public float AdjustedPhase + { + get + { + return this._adjustedPhase; + } + } + + public float Phase + { + get + { + return this._phase; + } + } + + public float SampleRate + { + get + { + return this._sampleRate; + } + set + { + if (this._sampleRate != value) + { + this._sampleRate = value; + this.Configure(); + } + } + } + + public float DefaultFrequency + { + get + { + return this._defaultFrequency; + } + set + { + if (this._defaultFrequency != value) + { + this._defaultFrequency = value; + this.Configure(); + } + } + } + + public float Range + { + get + { + return this._range; + } + set + { + if (this._range != value) + { + this._range = value; + this.Configure(); + } + } + } + + public float Bandwidth + { + get + { + return this._bandwidth; + } + set + { + if (this._bandwidth != value) + { + this._bandwidth = value; + this.Configure(); + } + } + } + + public float LockTime + { + get + { + return this._lockTime; + } + set + { + if (this._lockTime != value) + { + this._lockTime = value; + this.Configure(); + } + } + } + + public float LockThreshold + { + get + { + return this._lockThreshold; + } + set + { + if (this._lockThreshold != value) + { + this._lockThreshold = value; + this.Configure(); + } + } + } + + public float Zeta + { + get + { + return this._zeta; + } + set + { + if (this._zeta != value) + { + this._zeta = value; + this.Configure(); + } + } + } + + public float PhaseAdjM + { + get + { + return this._phaseAdjM; + } + set + { + if (this._phaseAdjM != value) + { + this._phaseAdjM = value; + this.Configure(); + } + } + } + + public float PhaseAdjB + { + get + { + return this._phaseAdjB; + } + set + { + if (this._phaseAdjB != value) + { + this._phaseAdjB = value; + this.Configure(); + } + } + } + + public bool StickOnFrequencyIfNotLocked + { + get + { + return this._stickOnFrequencyIfNotLocked; + } + set + { + this._stickOnFrequencyIfNotLocked = value; + } + } + + public bool IsLocked + { + get + { + return this._phaseErrorAvg < this._lockThreshold; + } + } + + private void Configure() + { + this._phase = 0f; + float num = (float)(6.2831853071795862 / (double)this._sampleRate); + this._frequencyRadian = this._defaultFrequency * num; + this._minFrequencyRadian = (this._defaultFrequency - this._range) * num; + this._maxFrequencyRadian = (this._defaultFrequency + this._range) * num; + this._alpha = 2f * this._zeta * this._bandwidth * num; + this._beta = this._alpha * this._alpha / (4f * this._zeta * this._zeta); + this._phaseAdj = this._phaseAdjM * this._sampleRate + this._phaseAdjB; + this._lockAlpha = (float)(1.0 - Math.Exp(-1.0 / (double)(this._sampleRate * this._lockTime))); + this._lockOneMinusAlpha = 1f - this._lockAlpha; + } + + public Complex Process(float sample) + { + Complex complex = Trig.SinCos(this._phase); + complex *= sample; + float phaseError = 0f - complex.ArgumentFast(); + this.ProcessPhaseError(phaseError); + return complex; + } + + public Complex Process(Complex sample) + { + Complex complex = Trig.SinCos(this._phase); + complex *= sample; + float phaseError = 0f - complex.ArgumentFast(); + this.ProcessPhaseError(phaseError); + return complex; + } + + private void ProcessPhaseError(float phaseError) + { + this._phaseErrorAvg = this._lockOneMinusAlpha * this._phaseErrorAvg + this._lockAlpha * phaseError * phaseError; + if (this._stickOnFrequencyIfNotLocked && !this.IsLocked) + { + this._phase += this._frequencyRadian; + } + else + { + this._frequencyRadian += this._beta * phaseError; + if (this._frequencyRadian > this._maxFrequencyRadian) + { + this._frequencyRadian = this._maxFrequencyRadian; + } + else if (this._frequencyRadian < this._minFrequencyRadian) + { + this._frequencyRadian = this._minFrequencyRadian; + } + this._phase += this._frequencyRadian + this._alpha * phaseError; + } + this._phase %= 6.28318548f; + this._adjustedPhase = this._phase + this._phaseAdj; + } + + public void Reset() + { + this._phase = 0f; + this._frequencyRadian = 0f; + this._phaseErrorAvg = 10f; + this._stickOnFrequencyIfNotLocked = false; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/ProcessorType.cs b/SDRSharp.Radio/SDRSharp.Radio/ProcessorType.cs new file mode 100644 index 0000000..005ff1c --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/ProcessorType.cs @@ -0,0 +1,12 @@ +namespace SDRSharp.Radio +{ + public enum ProcessorType + { + RawIQ, + DecimatedAndFilteredIQ, + DemodulatorOutput, + FilteredAudioOutput, + FMMPX, + RDSBitStream + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/RdsDecoder.cs b/SDRSharp.Radio/SDRSharp.Radio/RdsDecoder.cs new file mode 100644 index 0000000..255d547 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/RdsDecoder.cs @@ -0,0 +1,229 @@ +using System; + +namespace SDRSharp.Radio +{ + public class RdsDecoder + { + private const int PllDefaultFrequency = 57000; + + private const int PllRange = 12; + + private const int PllBandwith = 1; + + private const float PllZeta = 0.707f; + + private const float PllLockTime = 0.5f; + + private const float PllLockThreshold = 3.2f; + + private const float RdsBitRate = 1187.5f; + + private readonly RdsDetectorBank _bitDecoder; + + private unsafe readonly Pll* _pll; + + private readonly UnsafeBuffer _pllBuffer; + + private readonly Oscillator _osc = new Oscillator(); + + private unsafe readonly IirFilter* _syncFilter; + + private readonly UnsafeBuffer _syncFilterBuffer; + + private UnsafeBuffer _rawBuffer; + + private unsafe Complex* _rawPtr; + + private UnsafeBuffer _magBuffer; + + private unsafe float* _magPtr; + + private UnsafeBuffer _dataBuffer; + + private unsafe float* _dataPtr; + + private DownConverter _decimator; + + private FirFilter _matchedFilter; + + private IQFirFilter _baseBandFilter; + + private double _sampleRate; + + private double _demodulationSampleRate; + + private int _decimationFactor; + + private bool _configureNeeded; + + private float _lastSync; + + private float _lastData; + + private float _lastSyncSlope; + + private bool _lastBit; + + public double SampleRate + { + get + { + return this._sampleRate; + } + set + { + if (value != this._sampleRate) + { + this._sampleRate = value; + this._configureNeeded = true; + } + } + } + + public string RadioText + { + get + { + return this._bitDecoder.RadioText; + } + } + + public string ProgramService + { + get + { + return this._bitDecoder.ProgramService; + } + } + + public ushort PICode + { + get + { + return this._bitDecoder.PICode; + } + } + + public bool UseFEC + { + get + { + return this._bitDecoder.UseFEC; + } + set + { + this._bitDecoder.UseFEC = value; + } + } + + public event RdsFrameAvailableDelegate RdsFrameAvailable; + + public unsafe RdsDecoder() + { + this._pllBuffer = UnsafeBuffer.Create(sizeof(Pll)); + this._pll = (Pll*)(void*)this._pllBuffer; + this._syncFilterBuffer = UnsafeBuffer.Create(sizeof(IirFilter)); + this._syncFilter = (IirFilter*)(void*)this._syncFilterBuffer; + this._bitDecoder = new RdsDetectorBank(); + this._bitDecoder.FrameAvailable += this.FrameAvailableHandler; + } + + private unsafe void Configure() + { + this._osc.SampleRate = this._sampleRate; + this._osc.Frequency = 57000.0; + int i; + for (i = 0; this._sampleRate >= (double)(20000 << i); i++) + { + } + this._decimationFactor = 1 << i; + this._demodulationSampleRate = this._sampleRate / (double)this._decimationFactor; + this._decimator = new DownConverter(this._demodulationSampleRate, this._decimationFactor); + float[] coefficients = FilterBuilder.MakeLowPassKernel(this._demodulationSampleRate, 200, 2500.0, WindowType.BlackmanHarris4); + this._baseBandFilter = new IQFirFilter(coefficients, 1); + this._pll->SampleRate = (float)this._demodulationSampleRate; + this._pll->DefaultFrequency = 0f; + this._pll->Range = 12f; + this._pll->Bandwidth = 1f; + this._pll->Zeta = 0.707f; + this._pll->LockTime = 0.5f; + this._pll->LockThreshold = 3.2f; + int length = (int)(this._demodulationSampleRate / 1187.5) | 1; + coefficients = FilterBuilder.MakeSin(this._demodulationSampleRate, 1187.5, length); + this._matchedFilter = new FirFilter(coefficients, 1); + this._syncFilter->Init(IirFilterType.BandPass, 1187.5, this._demodulationSampleRate, 500.0); + } + + public unsafe void Reset() + { + this._bitDecoder.Reset(); + this._syncFilter->Reset(); + } + + public unsafe void Process(float* baseBand, int length) + { + if (this._configureNeeded) + { + this.Configure(); + this._configureNeeded = false; + } + if (this._rawBuffer == null || this._rawBuffer.Length != length) + { + this._rawBuffer = UnsafeBuffer.Create(length, sizeof(Complex)); + this._rawPtr = (Complex*)(void*)this._rawBuffer; + } + if (this._magBuffer == null || this._magBuffer.Length != length) + { + this._magBuffer = UnsafeBuffer.Create(length, 4); + this._magPtr = (float*)(void*)this._magBuffer; + } + if (this._dataBuffer == null || this._dataBuffer.Length != length) + { + this._dataBuffer = UnsafeBuffer.Create(length, 4); + this._dataPtr = (float*)(void*)this._dataBuffer; + } + for (int i = 0; i < length; i++) + { + this._osc.Tick(); + this._rawPtr[i] = this._osc.Phase * baseBand[i]; + } + this._decimator.Process(this._rawPtr, length); + length /= this._decimationFactor; + this._baseBandFilter.Process(this._rawPtr, length); + for (int j = 0; j < length; j++) + { + this._dataPtr[j] = this._pll->Process(this._rawPtr[j]).Imag; + } + this._matchedFilter.Process(this._dataPtr, length); + for (int k = 0; k < length; k++) + { + this._magPtr[k] = Math.Abs(this._dataPtr[k]); + } + this._syncFilter->Process(this._magPtr, length); + for (int l = 0; l < length; l++) + { + float lastData = this._dataPtr[l]; + float num = this._magPtr[l]; + float num2 = num - this._lastSync; + this._lastSync = num; + if (num2 < 0f && this._lastSyncSlope * num2 < 0f) + { + bool flag = this._lastData > 0f; + this._bitDecoder.Process(flag ^ this._lastBit); + this._lastBit = flag; + } + this._lastData = lastData; + this._lastSyncSlope = num2; + } + } + + private void FrameAvailableHandler(ref RdsFrame frame) + { + RdsFrameAvailableDelegate rdsFrameAvailable = this.RdsFrameAvailable; + if (rdsFrameAvailable != null) + { + rdsFrameAvailable(ref frame); + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/RdsDetectorBank.cs b/SDRSharp.Radio/SDRSharp.Radio/RdsDetectorBank.cs new file mode 100644 index 0000000..f5c38d5 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/RdsDetectorBank.cs @@ -0,0 +1,73 @@ +namespace SDRSharp.Radio +{ + public class RdsDetectorBank + { + private readonly RdsDumpGroups _dumpGroups; + + private readonly SyndromeDetector _detector; + + public string RadioText + { + get + { + return this._dumpGroups.RadioText; + } + } + + public string ProgramService + { + get + { + return this._dumpGroups.ProgramService; + } + } + + public ushort PICode + { + get + { + return this._dumpGroups.PICode; + } + } + + public bool UseFEC + { + get + { + return this._detector.UseFEC; + } + set + { + this._detector.UseFEC = value; + } + } + + public event RdsFrameAvailableDelegate FrameAvailable; + + public RdsDetectorBank() + { + this._dumpGroups = new RdsDumpGroups(); + this._detector = new SyndromeDetector(this._dumpGroups); + this._detector.FrameAvailable += this.FrameAvailableHandler; + } + + public void Process(bool b) + { + this._detector.Clock(b); + } + + public void Reset() + { + this._dumpGroups.Reset(); + } + + private void FrameAvailableHandler(ref RdsFrame frame) + { + RdsFrameAvailableDelegate frameAvailable = this.FrameAvailable; + if (frameAvailable != null) + { + frameAvailable(ref frame); + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/RdsDumpGroups.cs b/SDRSharp.Radio/SDRSharp.Radio/RdsDumpGroups.cs new file mode 100644 index 0000000..7d630cb --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/RdsDumpGroups.cs @@ -0,0 +1,163 @@ +using System; +using System.Linq; +using System.Text; + +namespace SDRSharp.Radio +{ + public class RdsDumpGroups + { + private StringBuilder _radioTextSB = new StringBuilder(" "); + + private StringBuilder _programServiceSB = new StringBuilder(" "); + + private string _radioText = string.Empty; + + private string _programService = " "; + + private ushort _piCode; + + private bool _radioTextABFlag; + + public string RadioText + { + get + { + return this._radioText; + } + } + + public string ProgramService + { + get + { + return this._programService; + } + } + + public ushort PICode + { + get + { + return this._piCode; + } + } + + public void Reset() + { + lock (this) + { + this._radioTextSB = new StringBuilder(" "); + this._programServiceSB = new StringBuilder(" "); + this._radioText = string.Empty; + this._programService = " "; + this._piCode = 0; + this._radioTextABFlag = false; + } + } + + public bool AnalyseFrames(ref RdsFrame frame) + { + bool result = false; + if ((frame.GroupB & 0xF800) == 8192) + { + int num = (frame.GroupB & 0xF) * 4; + bool flag = (frame.GroupB >> 4 & 1) == 1; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append((char)(frame.GroupC >> 8)); + stringBuilder.Append((char)(frame.GroupC & 0xFF)); + stringBuilder.Append((char)(frame.GroupD >> 8)); + stringBuilder.Append((char)(frame.GroupD & 0xFF)); + if (stringBuilder.ToString().Any(delegate(char ch) + { + if (ch >= ' ') + { + return ch > '\u007f'; + } + return true; + })) + { + return false; + } + lock (this) + { + if (flag != this._radioTextABFlag) + { + for (int i = 0; i < this._radioTextSB.Length; i++) + { + this._radioTextSB[i] = ' '; + } + this._radioTextABFlag = flag; + } + else + { + this._radioTextSB.Remove(num, 4); + } + this._radioTextSB.Insert(num, stringBuilder.ToString()); + this._radioText = this._radioTextSB.ToString().Trim(); + this._piCode = frame.GroupA; + } + result = true; + } + if ((frame.GroupB & 0xF800) == 0) + { + int num2 = (frame.GroupB & 3) * 2; + StringBuilder stringBuilder2 = new StringBuilder(); + stringBuilder2.Append((char)(frame.GroupD >> 8)); + stringBuilder2.Append((char)(frame.GroupD & 0xFF)); + if (stringBuilder2.ToString().Any(delegate(char ch) + { + if (ch >= ' ') + { + return ch > '\u007f'; + } + return true; + })) + { + return false; + } + lock (this) + { + this._programServiceSB.Remove(num2, 2); + this._programServiceSB.Insert(num2, stringBuilder2.ToString()); + this._programService = this._programServiceSB.ToString().Substring(0, 8); + this._piCode = frame.GroupA; + } + result = true; + } + return result; + } + + private static string Dump4A(ushort blockB, ushort block3, ushort block4) + { + int num = block4 & 0x1F; + if ((block4 & 0x20) != 0) + { + num *= -1; + } + int minute = block4 >> 6 & 0x3F; + int hour = (block4 >> 12 & 0xF) | (block3 << 4 & 0x10); + int num2 = block3 >> 1 | (blockB << 15 & 0x18000); + int num3 = (int)(((double)num2 - 15078.2) / 365.25); + int num4 = (int)(((double)num2 - 14956.1 - (double)(int)((double)num3 * 365.25)) / 30.6001); + int day = num2 - 14956 - (int)((double)num3 * 365.25) - (int)((double)num4 * 30.6001); + int num5 = 0; + if (num4 == 14 || num4 == 15) + { + num5 = 1; + } + num3 = num3 + num5 + 1900; + num4 = num4 - 1 - num5 * 12; + try + { + DateTime d = new DateTime(num3, num4, day, hour, minute, 0); + TimeSpan t = new TimeSpan(num / 2, num * 30 % 60, 0); + d += t; + return "4A " + d.ToLongDateString() + " " + d.ToLongTimeString(); + } + catch (Exception ex) + { + return ex.Message; + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/RdsFrame.cs b/SDRSharp.Radio/SDRSharp.Radio/RdsFrame.cs new file mode 100644 index 0000000..96d973b --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/RdsFrame.cs @@ -0,0 +1,24 @@ +namespace SDRSharp.Radio +{ + public struct RdsFrame + { + public ushort GroupA; + + public ushort GroupB; + + public ushort GroupC; + + public ushort GroupD; + + public bool Filter; + + public RdsFrame(ushort groupA, ushort groupB, ushort groupC, ushort groupD) + { + this.GroupA = groupA; + this.GroupB = groupB; + this.GroupC = groupC; + this.GroupD = groupD; + this.Filter = false; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/RdsFrameAvailableDelegate.cs b/SDRSharp.Radio/SDRSharp.Radio/RdsFrameAvailableDelegate.cs new file mode 100644 index 0000000..c8a6a8c --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/RdsFrameAvailableDelegate.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.Radio +{ + public delegate void RdsFrameAvailableDelegate(ref RdsFrame frame); +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/Resampler.cs b/SDRSharp.Radio/SDRSharp.Radio/Resampler.cs new file mode 100644 index 0000000..ea3a814 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/Resampler.cs @@ -0,0 +1,168 @@ +using System; + +namespace SDRSharp.Radio +{ + public class Resampler + { + public const double DefaultProtectedPassband = 0.45; + + public const int DefaultTapsPerPhase = 160; + + private int _phase; + + private readonly int _interpolationFactor; + + private readonly int _decimationFactor; + + private readonly int _tapsPerPhase; + + private readonly UnsafeBuffer _firKernelBuffer; + + private unsafe readonly float* _firKernel; + + private readonly UnsafeBuffer _firQueueBuffer; + + private unsafe readonly float* _firQueue; + + public unsafe Resampler(double inputSampleRate, double outputSampleRate, int tapsPerPhase = 160, double protectedPassband = 0.45) + { + Resampler.DoubleToFraction(outputSampleRate / inputSampleRate, out this._interpolationFactor, out this._decimationFactor); + this._tapsPerPhase = tapsPerPhase; + int num = tapsPerPhase * this._interpolationFactor; + this._firKernelBuffer = UnsafeBuffer.Create(num, 4); + this._firKernel = (float*)(void*)this._firKernelBuffer; + double cutoffFrequency = Math.Min(inputSampleRate, outputSampleRate) * protectedPassband; + float[] array = FilterBuilder.MakeLowPassKernel(inputSampleRate * (double)this._interpolationFactor, num - 1, cutoffFrequency, WindowType.BlackmanHarris4); + float[] array2 = array; + fixed (float* ptr = array2) + { + for (int i = 0; i < array.Length; i++) + { + ptr[i] *= (float)this._interpolationFactor; + } + Utils.Memcpy(this._firKernel, ptr, (num - 1) * 4); + this._firKernel[num - 1] = 0f; + } + this._firQueueBuffer = UnsafeBuffer.Create(num, 4); + this._firQueue = (float*)(void*)this._firQueueBuffer; + } + + private static void DoubleToFraction(double value, out int num, out int den) + { + int num2 = 1; + int num3 = 1; + double num4 = 1.0; + while (Math.Abs(num4 - value) > 1E-15) + { + if (num4 > value) + { + num3++; + } + else + { + num2++; + } + num4 = (double)num2 / (double)num3; + } + num = num2; + den = num3; + } + + public unsafe int Process(float* input, float* output, int inputLength) + { + int num = 0; + while (inputLength > 0) + { + int num2 = 0; + while (this._phase >= this._interpolationFactor) + { + this._phase -= this._interpolationFactor; + num2++; + if (--inputLength == 0) + { + break; + } + } + if (num2 >= this._tapsPerPhase) + { + input += num2 - this._tapsPerPhase; + num2 = this._tapsPerPhase; + } + for (int num3 = this._tapsPerPhase - 1; num3 >= num2; num3--) + { + this._firQueue[num3] = this._firQueue[num3 - num2]; + } + for (int num4 = num2 - 1; num4 >= 0; num4--) + { + float* intPtr = this._firQueue + num4; + float* intPtr2 = input; + input = intPtr2 + 1; + *intPtr = *intPtr2; + } + while (this._phase < this._interpolationFactor) + { + float* ptr = this._firKernel + this._phase; + float num5 = 0f; + for (int i = 0; i < this._tapsPerPhase; i++) + { + num5 += *ptr * this._firQueue[i]; + ptr += this._interpolationFactor; + } + float* intPtr3 = output; + output = intPtr3 + 1; + *intPtr3 = num5; + num++; + this._phase += this._decimationFactor; + } + } + return num; + } + + public unsafe int ProcessInterleaved(float* input, float* output, int inputLength) + { + int num = 0; + while (inputLength > 0) + { + int num2 = 0; + while (this._phase >= this._interpolationFactor) + { + this._phase -= this._interpolationFactor; + num2++; + if (--inputLength == 0) + { + break; + } + } + if (num2 >= this._tapsPerPhase) + { + input += (num2 - this._tapsPerPhase) * 2; + num2 = this._tapsPerPhase; + } + for (int num3 = this._tapsPerPhase - 1; num3 >= num2; num3--) + { + this._firQueue[num3] = this._firQueue[num3 - num2]; + } + for (int num4 = num2 - 1; num4 >= 0; num4--) + { + this._firQueue[num4] = *input; + input += 2; + } + while (this._phase < this._interpolationFactor) + { + float* ptr = this._firKernel + this._phase; + float num5 = 0f; + for (int i = 0; i < this._tapsPerPhase; i++) + { + num5 += *ptr * this._firQueue[i]; + ptr += this._interpolationFactor; + } + *output = num5; + output += 2; + num++; + this._phase += this._decimationFactor; + } + } + return num; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/SamplesAvailableDelegate.cs b/SDRSharp.Radio/SDRSharp.Radio/SamplesAvailableDelegate.cs new file mode 100644 index 0000000..fbf9964 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/SamplesAvailableDelegate.cs @@ -0,0 +1,4 @@ +namespace SDRSharp.Radio +{ + public unsafe delegate void SamplesAvailableDelegate(IFrontendController sender, Complex* data, int len); +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/SharpEvent.cs b/SDRSharp.Radio/SDRSharp.Radio/SharpEvent.cs new file mode 100644 index 0000000..a6a7a27 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/SharpEvent.cs @@ -0,0 +1,73 @@ +using System; +using System.Threading; + +namespace SDRSharp.Radio +{ + public sealed class SharpEvent + { + private bool _state; + + private bool _waiting; + + public SharpEvent(bool initialState) + { + this._state = initialState; + } + + public SharpEvent() + : this(false) + { + } + + ~SharpEvent() + { + this.Dispose(); + } + + public void Dispose() + { + this.Set(); + GC.SuppressFinalize(this); + } + + public void Set() + { + lock (this) + { + this._state = true; + if (this._waiting) + { + Monitor.Pulse(this); + } + } + } + + public void WaitOne() + { + lock (this) + { + if (!this._state) + { + this._waiting = true; + try + { + Monitor.Wait(this); + } + finally + { + this._waiting = false; + } + } + this._state = false; + } + } + + public void Reset() + { + lock (this) + { + this._state = false; + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/SharpThreadPool.cs b/SDRSharp.Radio/SDRSharp.Radio/SharpThreadPool.cs new file mode 100644 index 0000000..5c1bee9 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/SharpThreadPool.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Threading; + +namespace SDRSharp.Radio +{ + public class SharpThreadPool + { + private struct WorkItem + { + private readonly WaitCallback _callback; + + private readonly object _parameter; + + public WorkItem(WaitCallback callback, object parameter) + { + this._callback = callback; + this._parameter = parameter; + } + + public void Invoke() + { + this._callback(this._parameter); + } + } + + private readonly Queue _jobQueue = new Queue(); + + private readonly Thread[] _workerThreads; + + private int _threadsWaiting; + + private bool _terminated; + + public SharpThreadPool() + : this(Environment.ProcessorCount) + { + } + + public SharpThreadPool(int threadCount) + { + this._workerThreads = new Thread[threadCount]; + for (int i = 0; i < this._workerThreads.Length; i++) + { + this._workerThreads[i] = new Thread(this.DispatchLoop); + this._workerThreads[i].Priority = ThreadPriority.Highest; + this._workerThreads[i].Start(); + } + } + + public void QueueUserWorkItem(WaitCallback callback) + { + this.QueueUserWorkItem(callback, null); + } + + public void QueueUserWorkItem(WaitCallback callback, object parameter) + { + WorkItem item = new WorkItem(callback, parameter); + lock (this._jobQueue) + { + this._jobQueue.Enqueue(item); + if (this._threadsWaiting > 0) + { + Monitor.Pulse(this._jobQueue); + } + } + } + + private void DispatchLoop() + { + while (true) + { + WorkItem workItem; + lock (this._jobQueue) + { + if (!this._terminated) + { + while (this._jobQueue.Count == 0) + { + this._threadsWaiting++; + try + { + Monitor.Wait(this._jobQueue); + } + finally + { + this._threadsWaiting--; + } + if (this._terminated) + { + return; + } + } + workItem = this._jobQueue.Dequeue(); + goto end_IL_0009; + } + return; + end_IL_0009:; + } + workItem.Invoke(); + } + } + + public void Dispose() + { + this._terminated = true; + lock (this._jobQueue) + { + Monitor.PulseAll(this._jobQueue); + } + for (int i = 0; i < this._workerThreads.Length; i++) + { + this._workerThreads[i].Join(); + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/SideBandDetector.cs b/SDRSharp.Radio/SDRSharp.Radio/SideBandDetector.cs new file mode 100644 index 0000000..de071c8 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/SideBandDetector.cs @@ -0,0 +1,13 @@ +namespace SDRSharp.Radio +{ + public sealed class SideBandDetector + { + public unsafe void Demodulate(Complex* iq, float* audio, int length) + { + for (int i = 0; i < length; i++) + { + audio[i] = iq[i].Real; + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/StereoDecoder.cs b/SDRSharp.Radio/SDRSharp.Radio/StereoDecoder.cs new file mode 100644 index 0000000..9809a56 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/StereoDecoder.cs @@ -0,0 +1,214 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + [StructLayout(LayoutKind.Sequential, Pack = 16)] + public sealed class StereoDecoder + { + private const int DefaultPilotFrequency = 19000; + + private const int PllRange = 20; + + private const int PllBandwith = 10; + + private const float PllThreshold = 1f; + + private const float PllLockTime = 0.5f; + + private const float PllZeta = 0.707f; + + private const float AudioGain = 0.2f; + + private static readonly float _deemphasisTime = (float)Utils.GetDoubleSetting("deemphasisTime", 50.0) * 1E-06f; + + private static readonly float _pllPhaseAdjM = (float)Utils.GetDoubleSetting("pllPhaseAdjM", 0.0); + + private static readonly float _pllPhaseAdjB = (float)Utils.GetDoubleSetting("pllPhaseAdjB", -1.75); + + private unsafe readonly Pll* _pll; + + private readonly UnsafeBuffer _pllBuffer; + + private unsafe IirFilter* _pilotFilter; + + private UnsafeBuffer _pilotFilterBuffer; + + private UnsafeBuffer _channelABuffer; + + private UnsafeBuffer _channelBBuffer; + + private unsafe float* _channelAPtr; + + private unsafe float* _channelBPtr; + + private ComplexFilter _channelAFilter; + + private ComplexFilter _channelBFilter; + + private FloatDecimator _channelADecimator; + + private FloatDecimator _channelBDecimator; + + private double _sampleRate; + + private int _audioDecimationRatio; + + private float _deemphasisAlpha; + + private float _deemphasisAvgL; + + private float _deemphasisAvgR; + + private bool _forceMono; + + public bool ForceMono + { + get + { + return this._forceMono; + } + set + { + this._forceMono = value; + } + } + + public unsafe bool IsPllLocked + { + get + { + return this._pll->IsLocked; + } + } + + public unsafe StereoDecoder() + { + this._pllBuffer = UnsafeBuffer.Create(sizeof(Pll)); + this._pll = (Pll*)(void*)this._pllBuffer; + } + + public unsafe void Process(float* baseBand, float* interleavedStereo, int length) + { + if (this._forceMono) + { + this.ProcessMono(baseBand, interleavedStereo, length); + } + else + { + this.ProcessStereo(baseBand, interleavedStereo, length); + } + } + + private unsafe void ProcessMono(float* baseBand, float* interleavedStereo, int length) + { + if (this._channelABuffer == null || this._channelABuffer.Length != length) + { + this._channelABuffer = UnsafeBuffer.Create(length, 4); + this._channelAPtr = (float*)(void*)this._channelABuffer; + } + Utils.Memcpy(this._channelAPtr, baseBand, length * 4); + this._channelADecimator.Process(this._channelAPtr, length); + length /= this._audioDecimationRatio; + this._channelAFilter.Process(this._channelAPtr, length, 1); + for (int i = 0; i < length; i++) + { + this._deemphasisAvgL += this._deemphasisAlpha * (this._channelAPtr[i] - this._deemphasisAvgL); + this._channelAPtr[i] = this._deemphasisAvgL; + } + for (int j = 0; j < length; j++) + { + interleavedStereo[j * 2 + 1] = (interleavedStereo[j * 2] = this._channelAPtr[j] * 0.2f); + } + } + + private unsafe void ProcessStereo(float* baseBand, float* interleavedStereo, int length) + { + if (this._channelABuffer == null || this._channelABuffer.Length != length) + { + this._channelABuffer = UnsafeBuffer.Create(length, 4); + this._channelAPtr = (float*)(void*)this._channelABuffer; + } + if (this._channelBBuffer == null || this._channelBBuffer.Length != length) + { + this._channelBBuffer = UnsafeBuffer.Create(length, 4); + this._channelBPtr = (float*)(void*)this._channelBBuffer; + } + int num = length / this._audioDecimationRatio; + Utils.Memcpy(this._channelAPtr, baseBand, length * 4); + this._channelADecimator.Process(this._channelAPtr, length); + this._channelAFilter.Process(this._channelAPtr, num, 1); + for (int i = 0; i < length; i++) + { + float sample = this._pilotFilter->Process(baseBand[i]); + this._pll->Process(sample); + this._channelBPtr[i] = baseBand[i] * Trig.Sin((float)((double)this._pll->AdjustedPhase * 2.0)); + } + if (!this._pll->IsLocked) + { + for (int j = 0; j < num; j++) + { + this._deemphasisAvgL += this._deemphasisAlpha * (this._channelAPtr[j] - this._deemphasisAvgL); + this._channelAPtr[j] = this._deemphasisAvgL; + } + for (int k = 0; k < num; k++) + { + interleavedStereo[k * 2 + 1] = (interleavedStereo[k * 2] = this._channelAPtr[k] * 0.2f); + } + } + else + { + this._channelBDecimator.Process(this._channelBPtr, length); + this._channelBFilter.Process(this._channelBPtr, num, 1); + for (int l = 0; l < num; l++) + { + float num2 = this._channelAPtr[l]; + float num3 = 2f * this._channelBPtr[l]; + interleavedStereo[l * 2] = (num2 + num3) * 0.2f; + interleavedStereo[l * 2 + 1] = (num2 - num3) * 0.2f; + } + for (int m = 0; m < num; m++) + { + this._deemphasisAvgL += this._deemphasisAlpha * (interleavedStereo[m * 2] - this._deemphasisAvgL); + interleavedStereo[m * 2] = this._deemphasisAvgL; + this._deemphasisAvgR += this._deemphasisAlpha * (interleavedStereo[m * 2 + 1] - this._deemphasisAvgR); + interleavedStereo[m * 2 + 1] = this._deemphasisAvgR; + } + } + } + + public unsafe void Configure(double sampleRate, int decimationStageCount) + { + this._audioDecimationRatio = 1 << decimationStageCount; + if (this._sampleRate != sampleRate) + { + this._sampleRate = sampleRate; + this._pilotFilterBuffer = UnsafeBuffer.Create(sizeof(IirFilter)); + this._pilotFilter = (IirFilter*)(void*)this._pilotFilterBuffer; + this._pilotFilter->Init(IirFilterType.BandPass, 19000.0, this._sampleRate, 500.0); + this._pll->SampleRate = (float)this._sampleRate; + this._pll->DefaultFrequency = 19000f; + this._pll->Range = 20f; + this._pll->Bandwidth = 10f; + this._pll->Zeta = 0.707f; + this._pll->PhaseAdjM = StereoDecoder._pllPhaseAdjM; + this._pll->PhaseAdjB = StereoDecoder._pllPhaseAdjB; + this._pll->LockTime = 0.5f; + this._pll->LockThreshold = 1f; + double num = sampleRate / (double)this._audioDecimationRatio; + Complex[] kernel = FilterBuilder.MakeComplexKernel(num, 250, Math.Min(0.9 * num, 30000.0), 0.0, WindowType.BlackmanHarris4); + this._channelAFilter = new ComplexFilter(kernel); + this._channelBFilter = new ComplexFilter(kernel); + this._deemphasisAlpha = (float)(1.0 - Math.Exp(-1.0 / (num * (double)StereoDecoder._deemphasisTime))); + this._deemphasisAvgL = 0f; + this._deemphasisAvgR = 0f; + } + if (this._channelADecimator != null && this._channelBDecimator != null && this._audioDecimationRatio == this._channelADecimator.DecimationRatio) + { + return; + } + this._channelADecimator = new FloatDecimator(this._audioDecimationRatio); + this._channelBDecimator = new FloatDecimator(this._audioDecimationRatio); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/StreamControl.cs b/SDRSharp.Radio/SDRSharp.Radio/StreamControl.cs new file mode 100644 index 0000000..7a0d8e7 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/StreamControl.cs @@ -0,0 +1,551 @@ +using SDRSharp.Radio.PortAudio; +using System; +using System.Threading; + +namespace SDRSharp.Radio +{ + public sealed class StreamControl : IDisposable + { + private enum InputType + { + SoundCard, + Plugin, + WaveFile + } + + private const int IQBufferingFactor = 6; + + private const int AudioBufferingFactor = 2; + + private const int WaveBufferSize = 65536; + + private const int MaxDecimationStageCount = 20; + + private static readonly int _bufferAlignment = 8 * Environment.ProcessorCount; + + private static readonly int _minOutputSampleRate = Utils.GetIntSetting("minOutputSampleRate", 24000); + + private static readonly int _minReducedNarrowBandwidth = Utils.GetIntSetting("minReducedNarrowBandwidth", 8000); + + private static readonly int _minReducedWideBandwidth = Utils.GetIntSetting("minReducedWideBandwidth", 120000); + + private unsafe float* _dspOutPtr; + + private UnsafeBuffer _dspOutBuffer; + + private unsafe Complex* _dspInPtr; + + private WavePlayer _wavePlayer; + + private WaveRecorder _waveRecorder; + + private WaveDuplex _waveDuplex; + + private WaveFile _waveFile; + + private ComplexCircularBuffer _iqCircularBuffer; + + private FloatCircularBuffer _audioCircularBuffer; + + private Thread _waveReadThread; + + private Thread _dspThread; + + private float _audioGain; + + private float _outputGain; + + private int _inputDevice; + + private double _inputSampleRate; + + private int _inputBufferSize; + + private double _bufferSizeInMs; + + private int _outputDevice; + + private double _outputSampleRate; + + private int _outputBufferSize; + + private int _decimationStageCount; + + private bool _swapIQ; + + private bool _isPlaying; + + private InputType _inputType; + + private IFrontendController _frontend; + + private HookManager _hookManager; + + public static bool ReducedBandwidth + { + get; + set; + } + + public float AudioGain + { + get + { + return this._audioGain; + } + set + { + this._audioGain = value; + this._outputGain = (float)Math.Pow(10.0, (double)value / 10.0); + } + } + + public bool ScaleOutput + { + get; + set; + } + + public bool SwapIQ + { + get + { + return this._swapIQ; + } + set + { + this._swapIQ = value; + } + } + + public double SampleRate + { + get + { + return this._inputSampleRate; + } + } + + public bool IsPlaying + { + get + { + return this._isPlaying; + } + } + + public int BufferSize + { + get + { + return this._inputBufferSize; + } + } + + public double BufferSizeInMs + { + get + { + return this._bufferSizeInMs; + } + } + + public int DecimationStageCount + { + get + { + return this._decimationStageCount; + } + } + + public double AudioSampleRate + { + get + { + return this._outputSampleRate; + } + } + + public event BufferNeededDelegate BufferNeeded; + + public StreamControl(HookManager hookManager = null) + { + this._hookManager = hookManager; + this.AudioGain = 10f; + this.ScaleOutput = true; + } + + ~StreamControl() + { + this.Dispose(); + } + + public void Dispose() + { + this.Stop(); + GC.SuppressFinalize(this); + } + + private unsafe void DuplexFiller(float* buffer, int frameCount) + { + if (!this._isPlaying) + { + Utils.Memset(buffer, 0, this._outputBufferSize * 4); + } + else + { + this._dspInPtr = (Complex*)buffer; + if (this._dspOutBuffer == null || this._dspOutBuffer.Length != frameCount * 2) + { + this._dspOutBuffer = UnsafeBuffer.Create(frameCount * 2, 4); + this._dspOutPtr = (float*)(void*)this._dspOutBuffer; + } + if (this._hookManager != null) + { + this._hookManager.ProcessRawIQ(this._dspInPtr, frameCount); + } + this.ProcessIQ(); + this.ScaleBuffer(this._dspOutPtr, this._dspOutBuffer.Length); + Utils.Memcpy(buffer, this._dspOutPtr, this._dspOutBuffer.Length * 4); + } + } + + private unsafe void PlayerFiller(float* buffer, int frameCount) + { + if (!this._isPlaying) + { + Utils.Memset(buffer, 0, this._outputBufferSize * 4); + } + else + { + float* ptr = this._audioCircularBuffer.Acquire(); + if (ptr != null) + { + Utils.Memcpy(buffer, ptr, this._outputBufferSize * 4); + this._audioCircularBuffer.Release(); + this.ScaleBuffer(buffer, this._outputBufferSize); + } + } + } + + private unsafe void RecorderFiller(float* buffer, int frameCount) + { + if (this._isPlaying) + { + Utils.Memcpy(buffer, buffer, frameCount * sizeof(Complex)); + if (this._hookManager != null) + { + this._hookManager.ProcessRawIQ((Complex*)buffer, frameCount); + } + this._iqCircularBuffer.Write((Complex*)buffer, frameCount); + } + } + + private unsafe void FrontendFiller(IFrontendController sender, Complex* samples, int len) + { + if (this._isPlaying) + { + if (this._hookManager != null) + { + this._hookManager.ProcessRawIQ(samples, len); + } + this._iqCircularBuffer.Write(samples, len, !(sender is INonBlockingController)); + } + } + + private unsafe void WaveFileFiller() + { + Complex[] array = new Complex[65536]; + Complex[] array2 = array; + fixed (Complex* ptr = array2) + { + while (this.IsPlaying) + { + this._waveFile.Read(ptr, array.Length); + if (this._hookManager != null) + { + this._hookManager.ProcessRawIQ(ptr, array.Length); + } + this._iqCircularBuffer.Write(ptr, array.Length); + } + } + } + + private unsafe void ScaleBuffer(float* buffer, int length) + { + if (this.ScaleOutput) + { + for (int i = 0; i < length; i++) + { + buffer[i] *= this._outputGain; + } + } + } + + private unsafe void DSPProc() + { + if (this._dspOutBuffer == null || this._dspOutBuffer.Length != this._outputBufferSize) + { + this._dspOutBuffer = UnsafeBuffer.Create(this._outputBufferSize, 4); + this._dspOutPtr = (float*)(void*)this._dspOutBuffer; + } + while (this._isPlaying) + { + this._dspInPtr = this._iqCircularBuffer.Acquire(); + if (this._dspInPtr == null) + { + break; + } + this.ProcessIQ(); + this._iqCircularBuffer.Release(); + this._audioCircularBuffer.Write(this._dspOutPtr, this._outputBufferSize); + } + } + + private unsafe void ProcessIQ() + { + BufferNeededDelegate bufferNeeded = this.BufferNeeded; + if (bufferNeeded != null) + { + if (this._swapIQ) + { + this.SwapIQBuffer(); + } + bufferNeeded(this._dspInPtr, this._dspOutPtr, this._inputBufferSize); + } + } + + private unsafe void SwapIQBuffer() + { + for (int i = 0; i < this._inputBufferSize; i++) + { + float real = this._dspInPtr[i].Real; + this._dspInPtr[i].Real = this._dspInPtr[i].Imag; + this._dspInPtr[i].Imag = real; + } + } + + public void Stop() + { + this._isPlaying = false; + if (this._inputType == InputType.Plugin && this._frontend is IIQStreamController) + { + ((IIQStreamController)this._frontend).Stop(); + this._frontend = null; + } + if (this._iqCircularBuffer != null) + { + this._iqCircularBuffer.Close(); + } + if (this._audioCircularBuffer != null) + { + this._audioCircularBuffer.Close(); + } + if (this._wavePlayer != null) + { + this._wavePlayer.Dispose(); + this._wavePlayer = null; + } + if (this._waveRecorder != null) + { + this._waveRecorder.Dispose(); + this._waveRecorder = null; + } + if (this._waveDuplex != null) + { + this._waveDuplex.Dispose(); + this._waveDuplex = null; + } + this._inputSampleRate = 0.0; + if (this._waveReadThread != null) + { + this._waveReadThread.Join(); + this._waveReadThread = null; + } + if (this._dspThread != null) + { + this._dspThread.Join(); + this._dspThread = null; + } + if (this._waveFile != null) + { + this._waveFile.Dispose(); + this._waveFile = null; + } + this._iqCircularBuffer = null; + this._audioCircularBuffer = null; + this._dspOutBuffer = null; + } + + public unsafe void Play() + { + if (this._wavePlayer == null && this._waveDuplex == null) + { + this._isPlaying = true; + try + { + switch (this._inputType) + { + case InputType.SoundCard: + if (this._inputDevice == this._outputDevice) + { + this._waveDuplex = new WaveDuplex(this._inputDevice, this._inputSampleRate, this._inputBufferSize, this.DuplexFiller); + } + else + { + this._iqCircularBuffer = new ComplexCircularBuffer(this._inputBufferSize, 6); + this._audioCircularBuffer = new FloatCircularBuffer(this._outputBufferSize, 2); + this._waveRecorder = new WaveRecorder(this._inputDevice, this._inputSampleRate, this._inputBufferSize, this.RecorderFiller); + this._wavePlayer = new WavePlayer(this._outputDevice, this._outputSampleRate, this._outputBufferSize / 2, this.PlayerFiller); + this._dspThread = new Thread(this.DSPProc); + this._dspThread.Start(); + } + break; + case InputType.WaveFile: + this._iqCircularBuffer = new ComplexCircularBuffer(this._inputBufferSize, 6); + this._audioCircularBuffer = new FloatCircularBuffer(this._outputBufferSize, 2); + this._wavePlayer = new WavePlayer(this._outputDevice, this._outputSampleRate, this._outputBufferSize / 2, this.PlayerFiller); + this._waveReadThread = new Thread(this.WaveFileFiller); + this._waveReadThread.Start(); + this._dspThread = new Thread(this.DSPProc); + this._dspThread.Start(); + break; + case InputType.Plugin: + this._iqCircularBuffer = new ComplexCircularBuffer(this._inputBufferSize, 6); + this._audioCircularBuffer = new FloatCircularBuffer(this._outputBufferSize, 2); + this._wavePlayer = new WavePlayer(this._outputDevice, this._outputSampleRate, this._outputBufferSize / 2, this.PlayerFiller); + if (this._frontend is IIQStreamController) + { + ((IIQStreamController)this._frontend).Start(this.FrontendFiller); + } + this._dspThread = new Thread(this.DSPProc); + this._dspThread.Start(); + break; + } + if (this._dspThread != null) + { + this._dspThread.Name = "DSP Thread"; + } + } + catch + { + this._isPlaying = false; + throw; + } + } + } + + public void OpenSoundDevice(int inputDevice, int outputDevice, double inputSampleRate, int bufferSizeInMs) + { + this.Stop(); + this._inputType = InputType.SoundCard; + this._inputDevice = inputDevice; + this._outputDevice = outputDevice; + this._inputSampleRate = inputSampleRate; + this._inputBufferSize = (int)((double)bufferSizeInMs * this._inputSampleRate / 1000.0); + if (this._inputDevice == this._outputDevice) + { + this._decimationStageCount = 0; + this._outputSampleRate = this._inputSampleRate; + this._outputBufferSize = this._inputBufferSize * 2; + } + else + { + this._decimationStageCount = StreamControl.GetDecimationStageCount(this._inputSampleRate, DetectorType.AM); + int num = 1 << this._decimationStageCount; + int num2 = num * StreamControl._bufferAlignment; + this._inputBufferSize = this._inputBufferSize / num2 * num2; + this._outputSampleRate = this._inputSampleRate / (double)num; + this._outputBufferSize = this._inputBufferSize / num * 2; + } + this._bufferSizeInMs = (double)this._inputBufferSize / this._inputSampleRate * 1000.0; + } + + public void OpenFile(string filename, int outputDevice, int bufferSizeInMs) + { + this.Stop(); + try + { + this._inputType = InputType.WaveFile; + this._waveFile = new WaveFile(filename); + this._outputDevice = outputDevice; + this._inputSampleRate = (double)this._waveFile.SampleRate; + this._inputBufferSize = (int)((double)bufferSizeInMs * this._inputSampleRate / 1000.0); + this._decimationStageCount = StreamControl.GetDecimationStageCount(this._inputSampleRate, DetectorType.AM); + int num = 1 << this._decimationStageCount; + int num2 = num * StreamControl._bufferAlignment; + this._inputBufferSize = this._inputBufferSize / num2 * num2; + this._outputSampleRate = this._inputSampleRate / (double)num; + this._outputBufferSize = this._inputBufferSize / num * 2; + this._bufferSizeInMs = (double)this._inputBufferSize / this._inputSampleRate * 1000.0; + } + catch + { + this.Stop(); + throw; + } + } + + public void OpenPlugin(IFrontendController frontend, int outputDevice, int bufferSizeInMs) + { + this.Stop(); + try + { + this._inputType = InputType.Plugin; + this._frontend = frontend; + if (frontend is IIQStreamController) + { + this._inputSampleRate = ((IIQStreamController)this._frontend).Samplerate; + this._outputDevice = outputDevice; + this._inputBufferSize = (int)((double)bufferSizeInMs * this._inputSampleRate / 1000.0); + if (this._inputBufferSize == 0) + { + throw new ArgumentException("The source '" + this._frontend + "' is not ready"); + } + this._decimationStageCount = StreamControl.GetDecimationStageCount(this._inputSampleRate, DetectorType.AM); + int num = 1 << this._decimationStageCount; + int num2 = num * StreamControl._bufferAlignment; + this._inputBufferSize = this._inputBufferSize / num2 * num2; + this._outputSampleRate = this._inputSampleRate / (double)num; + this._outputBufferSize = this._inputBufferSize / num * 2; + this._bufferSizeInMs = (double)this._inputBufferSize / this._inputSampleRate * 1000.0; + goto end_IL_0006; + } + throw new ArgumentException("The source '" + this._frontend + "' is not ready"); + end_IL_0006:; + } + catch + { + this.Stop(); + throw; + } + } + + public static int GetDecimationStageCount(double inputSampleRate, DetectorType detector = DetectorType.AM) + { + int num = 20; + int num2; + if (StreamControl.ReducedBandwidth) + { + if (inputSampleRate <= (double)StreamControl._minReducedNarrowBandwidth) + { + return 0; + } + num2 = ((detector == DetectorType.WFM) ? StreamControl._minReducedWideBandwidth : StreamControl._minReducedNarrowBandwidth); + } + else + { + if (inputSampleRate <= (double)StreamControl._minOutputSampleRate) + { + return 0; + } + num2 = ((detector == DetectorType.WFM) ? 250000 : StreamControl._minOutputSampleRate); + } + while (inputSampleRate / (double)(1 << num) < (double)num2 && num > 0) + { + num--; + } + return num; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/SyndromeDetector.cs b/SDRSharp.Radio/SDRSharp.Radio/SyndromeDetector.cs new file mode 100644 index 0000000..4d15c82 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/SyndromeDetector.cs @@ -0,0 +1,189 @@ +namespace SDRSharp.Radio +{ + public class SyndromeDetector + { + protected enum BlockSequence + { + GotA, + GotB, + GotC, + GotD, + WaitBitSync, + GotBitSync + } + + private const int MaxCorrectableBits = 5; + + private const int CheckwordBitsCount = 10; + + private readonly RdsDumpGroups _dumpGroups; + + private readonly ushort[] _blocks = new ushort[4]; + + private bool _useFec = Utils.GetBooleanSetting("RdsUseFec"); + + private BlockSequence _sequence = BlockSequence.WaitBitSync; + + private ushort _syndrome; + + private uint _raw; + + private RdsFrame _frame; + + private int _count; + + public bool UseFEC + { + get + { + return this._useFec; + } + set + { + this._useFec = value; + } + } + + public event RdsFrameAvailableDelegate FrameAvailable; + + public SyndromeDetector(RdsDumpGroups dumpGroups) + { + this._dumpGroups = dumpGroups; + } + + public void Clock(bool b) + { + this._raw <<= 1; + this._raw |= (uint)(b ? 1 : 0); + this._count++; + if (this._sequence == BlockSequence.WaitBitSync) + { + this._syndrome = SyndromeDetector.BuildSyndrome(this._raw); + this._syndrome ^= 984; + this._sequence = ((this._syndrome != 0) ? BlockSequence.WaitBitSync : BlockSequence.GotA); + this._blocks[0] = (ushort)(this._raw >> 10 & 0xFFFF); + this._count = 0; + } + if (this._count == 26) + { + this.ProcessSyndrome(); + if (this._sequence == BlockSequence.GotD) + { + this._frame.GroupA = this._blocks[0]; + this._frame.GroupB = this._blocks[1]; + this._frame.GroupC = this._blocks[2]; + this._frame.GroupD = this._blocks[3]; + this._frame.Filter = false; + RdsFrameAvailableDelegate frameAvailable = this.FrameAvailable; + if (frameAvailable != null) + { + frameAvailable(ref this._frame); + } + if (!this._frame.Filter) + { + this._dumpGroups.AnalyseFrames(ref this._frame); + } + this._sequence = BlockSequence.GotBitSync; + } + this._count = 0; + } + } + + private void ProcessSyndrome() + { + this._syndrome = SyndromeDetector.BuildSyndrome(this._raw); + switch (this._sequence) + { + case BlockSequence.GotBitSync: + this._syndrome ^= 984; + this._sequence = BlockSequence.GotA; + break; + case BlockSequence.GotA: + this._syndrome ^= 980; + this._sequence = BlockSequence.GotB; + break; + case BlockSequence.GotB: + this._syndrome ^= (ushort)(((this._blocks[1] & 0x800) == 0) ? 604 : 972); + this._sequence = BlockSequence.GotC; + break; + case BlockSequence.GotC: + this._syndrome ^= 600; + this._sequence = BlockSequence.GotD; + break; + } + int sequence = (int)this._sequence; + if (this._syndrome != 0) + { + if (this._useFec) + { + int num = this.ApplyFEC(); + if (this._syndrome != 0 || num > 5) + { + this._sequence = BlockSequence.WaitBitSync; + } + else + { + this._blocks[sequence] = (ushort)(this._raw & 0xFFFF); + } + } + else + { + this._sequence = BlockSequence.WaitBitSync; + } + } + else + { + this._blocks[sequence] = (ushort)(this._raw >> 10 & 0xFFFF); + } + } + + private int ApplyFEC() + { + uint num = 33554432u; + int num2 = 0; + for (int i = 0; i < 16; i++) + { + bool flag = (this._syndrome & 0x200) == 512; + bool flag2 = (this._syndrome & 0x20) == 0; + this._raw ^= ((flag & flag2) ? num : 0); + this._syndrome <<= 1; + this._syndrome ^= (ushort)((flag && !flag2) ? 1465 : 0); + num2 += ((flag & flag2) ? 1 : 0); + num >>= 1; + } + this._syndrome &= 1023; + return num2; + } + + private static ushort BuildSyndrome(uint raw) + { + ushort[] array = new ushort[16] + { + 732, + 366, + 183, + 647, + 927, + 787, + 853, + 886, + 443, + 513, + 988, + 494, + 247, + 679, + 911, + 795 + }; + uint num = raw & 0x3FFFFFF; + ushort num2 = (ushort)(num >> 16); + for (int i = 0; i < 16; i++) + { + num2 = (ushort)(num2 ^ (((num & 0x8000) == 32768) ? array[i] : 0)); + num <<= 1; + } + return num2; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/Trig.cs b/SDRSharp.Radio/SDRSharp.Radio/Trig.cs new file mode 100644 index 0000000..f33ece4 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/Trig.cs @@ -0,0 +1,100 @@ +using System; + +namespace SDRSharp.Radio +{ + public static class Trig + { + private const int ResolutionInBits = 16; + + private static readonly int _mask; + + private static readonly float _indexScale; + + private static readonly UnsafeBuffer _sinBuffer; + + private static readonly UnsafeBuffer _cosBuffer; + + private unsafe static readonly float* _sinPtr; + + private unsafe static readonly float* _cosPtr; + + unsafe static Trig() + { + Trig._mask = 65535; + int num = Trig._mask + 1; + Trig._sinBuffer = UnsafeBuffer.Create(num, 4); + Trig._cosBuffer = UnsafeBuffer.Create(num, 4); + Trig._sinPtr = (float*)(void*)Trig._sinBuffer; + Trig._cosPtr = (float*)(void*)Trig._cosBuffer; + Trig._indexScale = (float)num / 6.28318548f; + for (int i = 0; i < num; i++) + { + Trig._sinPtr[i] = (float)Math.Sin((double)(((float)i + 0.5f) / (float)num * 6.28318548f)); + Trig._cosPtr[i] = (float)Math.Cos((double)(((float)i + 0.5f) / (float)num * 6.28318548f)); + } + for (float num2 = 0f; num2 < 6.28318548f; num2 += 1.57079637f) + { + Trig._sinPtr[(int)(num2 * Trig._indexScale) & Trig._mask] = (float)Math.Sin((double)num2); + Trig._cosPtr[(int)(num2 * Trig._indexScale) & Trig._mask] = (float)Math.Cos((double)num2); + } + } + + public unsafe static float Sin(float angle) + { + return Trig._sinPtr[(int)(angle * Trig._indexScale) & Trig._mask]; + } + + public unsafe static float Cos(float angle) + { + return Trig._cosPtr[(int)(angle * Trig._indexScale) & Trig._mask]; + } + + public unsafe static Complex SinCos(float rad) + { + int num = (int)(rad * Trig._indexScale) & Trig._mask; + Complex result = default(Complex); + result.Real = Trig._cosPtr[num]; + result.Imag = Trig._sinPtr[num]; + return result; + } + + public static float Atan2(float y, float x) + { + if ((double)x == 0.0) + { + if ((double)y > 0.0) + { + return 1.57079637f; + } + if ((double)y == 0.0) + { + return 0f; + } + return -1.57079637f; + } + float num = y / x; + float num2; + if ((double)Math.Abs(num) < 1.0) + { + num2 = num / (1f + 0.2854f * num * num); + if ((double)x < 0.0) + { + if ((double)y < 0.0) + { + return num2 - 3.14159274f; + } + return num2 + 3.14159274f; + } + } + else + { + num2 = 1.57079637f - num / (num * num + 0.2854f); + if ((double)y < 0.0) + { + return num2 - 3.14159274f; + } + } + return num2; + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/TuningStyle.cs b/SDRSharp.Radio/SDRSharp.Radio/TuningStyle.cs new file mode 100644 index 0000000..baa41e2 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/TuningStyle.cs @@ -0,0 +1,9 @@ +namespace SDRSharp.Radio +{ + public enum TuningStyle + { + Free, + Sticky, + Center + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/UnsafeBuffer.cs b/SDRSharp.Radio/SDRSharp.Radio/UnsafeBuffer.cs new file mode 100644 index 0000000..6636977 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/UnsafeBuffer.cs @@ -0,0 +1,93 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.Radio +{ + public sealed class UnsafeBuffer : IDisposable + { + private readonly GCHandle _handle; + + private unsafe void* _ptr; + + private int _length; + + private Array _buffer; + + public unsafe void* Address + { + get + { + return this._ptr; + } + } + + public int Length + { + get + { + return this._length; + } + } + + private unsafe UnsafeBuffer(Array buffer, int realLength, bool aligned) + { + this._buffer = buffer; + this._handle = GCHandle.Alloc(this._buffer, GCHandleType.Pinned); + this._ptr = (void*)this._handle.AddrOfPinnedObject(); + if (aligned) + { + this._ptr = (void*)((long)this._ptr + 15 & -16); + } + this._length = realLength; + } + + ~UnsafeBuffer() + { + this.Dispose(); + } + + public unsafe void Dispose() + { + GCHandle handle = this._handle; + if (handle.IsAllocated) + { + handle = this._handle; + handle.Free(); + } + this._buffer = null; + this._ptr = null; + this._length = 0; + GC.SuppressFinalize(this); + } + + public void Clear() + { + Array.Clear(this._buffer, 0, this._buffer.Length); + } + + public unsafe static implicit operator void*(UnsafeBuffer unsafeBuffer) + { + return unsafeBuffer.Address; + } + + public static UnsafeBuffer Create(int size) + { + return UnsafeBuffer.Create(size, 1, true); + } + + public static UnsafeBuffer Create(int length, int sizeOfElement) + { + return UnsafeBuffer.Create(length, sizeOfElement, true); + } + + public static UnsafeBuffer Create(int length, int sizeOfElement, bool aligned) + { + return new UnsafeBuffer(new byte[length * sizeOfElement + (aligned ? 16 : 0)], length, aligned); + } + + public static UnsafeBuffer Create(Array buffer) + { + return new UnsafeBuffer(buffer, buffer.Length, false); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/Utils.cs b/SDRSharp.Radio/SDRSharp.Radio/Utils.cs new file mode 100644 index 0000000..ae57eb1 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/Utils.cs @@ -0,0 +1,351 @@ +using System; +using System.Configuration; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Text; + +namespace SDRSharp.Radio +{ + public static class Utils + { + private const string Libc = "msvcrt.dll"; + + public unsafe static void ManagedMemcpy(void* dest, void* src, int len) + { + byte* ptr = (byte*)dest; + byte* ptr2 = (byte*)src; + if (len >= 16) + { + do + { + *(int*)ptr = *(int*)ptr2; + *(int*)(ptr + 4) = *(int*)(ptr2 + 4); + *(int*)(ptr + 2L * 4L) = *(int*)(ptr2 + 2L * 4L); + *(int*)(ptr + 3L * 4L) = *(int*)(ptr2 + 3L * 4L); + ptr += 16; + ptr2 += 16; + } + while ((len -= 16) >= 16); + } + if (len > 0) + { + if ((len & 8) != 0) + { + *(int*)ptr = *(int*)ptr2; + *(int*)(ptr + 4) = *(int*)(ptr2 + 4); + ptr += 8; + ptr2 += 8; + } + if ((len & 4) != 0) + { + *(int*)ptr = *(int*)ptr2; + ptr += 4; + ptr2 += 4; + } + if ((len & 2) != 0) + { + *(short*)ptr = *(short*)ptr2; + ptr += 2; + ptr2 += 2; + } + if ((len & 1) != 0) + { + *ptr = *ptr2; + } + } + } + + [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "memmove")] + public unsafe static extern void* Memmove(void* dest, void* src, int len); + + [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "memcpy")] + public unsafe static extern void* Memcpy(void* dest, void* src, int len); + + [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "memset")] + public unsafe static extern void* Memset(void* dest, int value, int len); + + [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod", SetLastError = true)] + public static extern uint TimeBeginPeriod(uint uMilliseconds); + + [DllImport("winmm.dll", EntryPoint = "timeEndPeriod", SetLastError = true)] + public static extern uint TimeEndPeriod(uint uMilliseconds); + + public static double GetDoubleSetting(string name, double defaultValue) + { + double result; + if (double.TryParse(ConfigurationManager.AppSettings[name], NumberStyles.Number, (IFormatProvider)CultureInfo.InvariantCulture, out result)) + { + return result; + } + return defaultValue; + } + + public static bool GetBooleanSetting(string name) + { + return Utils.GetBooleanSetting(name, false); + } + + public static bool GetBooleanSetting(string name, bool defaultValue) + { + string text; + try + { + text = (ConfigurationManager.AppSettings[name] ?? string.Empty); + } + catch + { + return defaultValue; + } + if (string.IsNullOrEmpty(text)) + { + return defaultValue; + } + return "YyTt".IndexOf(text[0]) >= 0; + } + + public static Color GetColorSetting(string name, Color defaultColor) + { + return Utils.GetColorSetting(name, defaultColor, byte.MaxValue); + } + + public static Color GetColorSetting(string name, Color defaultColor, byte alpha) + { + try + { + string text = ConfigurationManager.AppSettings[name]; + int red = int.Parse(text.Substring(0, 2), NumberStyles.HexNumber); + int green = int.Parse(text.Substring(2, 2), NumberStyles.HexNumber); + int blue = int.Parse(text.Substring(4, 2), NumberStyles.HexNumber); + return Color.FromArgb(alpha, red, green, blue); + } + catch + { + return defaultColor; + } + } + + public static ColorBlend GetGradientBlend(int alpha, string settingName) + { + ColorBlend colorBlend = new ColorBlend(); + string text; + try + { + text = (ConfigurationManager.AppSettings[settingName] ?? string.Empty); + } + catch + { + text = string.Empty; + } + string[] array = text.Split(','); + if (array.Length < 2) + { + colorBlend.Colors = new Color[6] + { + Color.White, + Color.LightBlue, + Color.DodgerBlue, + Color.FromArgb(0, 0, 80), + Color.Black, + Color.Black + }; + for (int i = 0; i < colorBlend.Colors.Length; i++) + { + colorBlend.Colors[i] = Color.FromArgb(alpha, colorBlend.Colors[i]); + } + } + else + { + colorBlend.Colors = new Color[array.Length]; + for (int j = 0; j < array.Length; j++) + { + string obj2 = array[j]; + int red = int.Parse(obj2.Substring(0, 2), NumberStyles.HexNumber); + int green = int.Parse(obj2.Substring(2, 2), NumberStyles.HexNumber); + int blue = int.Parse(obj2.Substring(4, 2), NumberStyles.HexNumber); + colorBlend.Colors[j] = Color.FromArgb(red, green, blue); + } + } + float[] array2 = new float[colorBlend.Colors.Length]; + float num = 1f / (float)(array2.Length - 1); + for (int k = 0; k < array2.Length; k++) + { + byte r = colorBlend.Colors[k].R; + byte g = colorBlend.Colors[k].G; + byte b = colorBlend.Colors[k].B; + colorBlend.Colors[k] = Color.FromArgb(alpha, r, g, b); + array2[k] = (float)k * num; + } + colorBlend.Positions = array2; + return colorBlend; + } + + public static GraphicsPath RoundedRect(RectangleF bounds, int radius) + { + int num = radius * 2; + SizeF size = new SizeF((float)num, (float)num); + RectangleF rect = new RectangleF(bounds.Location, size); + GraphicsPath graphicsPath = new GraphicsPath(); + if (radius == 0) + { + graphicsPath.AddRectangle(bounds); + return graphicsPath; + } + graphicsPath.AddArc(rect, 180f, 90f); + rect.X = bounds.Right - (float)num; + graphicsPath.AddArc(rect, 270f, 90f); + rect.Y = bounds.Bottom - (float)num; + graphicsPath.AddArc(rect, 0f, 90f); + rect.X = bounds.Left; + graphicsPath.AddArc(rect, 90f, 90f); + graphicsPath.CloseFigure(); + return graphicsPath; + } + + public static void DrawRoundedRectangle(this Graphics graphics, Pen pen, RectangleF bounds, int cornerRadius) + { + if (graphics == null) + { + throw new ArgumentNullException("graphics"); + } + if (pen == null) + { + throw new ArgumentNullException("pen"); + } + using (GraphicsPath path = Utils.RoundedRect(bounds, cornerRadius)) + { + graphics.DrawPath(pen, path); + } + } + + public static void FillRoundedRectangle(this Graphics graphics, Brush brush, RectangleF bounds, int cornerRadius) + { + if (graphics == null) + { + throw new ArgumentNullException("graphics"); + } + if (brush == null) + { + throw new ArgumentNullException("brush"); + } + using (GraphicsPath path = Utils.RoundedRect(bounds, cornerRadius)) + { + graphics.FillPath(brush, path); + } + } + + public static string GetFrequencyDisplay(long frequency, bool appendHz) + { + string str = (frequency != 0L) ? ((Math.Abs(frequency) < 1000000000) ? ((Math.Abs(frequency) < 1000000) ? ((Math.Abs(frequency) < 1000) ? string.Format("{0} ", frequency) : string.Format("{0:#,#.###} k", (double)frequency / 1000.0)) : string.Format("{0:#,0.000#} M", (double)frequency / 1000000.0)) : string.Format("{0:#,0.000 000} G", (double)frequency / 1000000000.0)) : "0"; + return str + ((frequency == 0L || !appendHz) ? string.Empty : "Hz"); + } + + public static int GetIntSetting(string name, int defaultValue) + { + int result; + if (int.TryParse(ConfigurationManager.AppSettings[name], out result)) + { + return result; + } + return defaultValue; + } + + public static long GetLongSetting(string name, long defaultValue) + { + long result; + if (long.TryParse(ConfigurationManager.AppSettings[name], out result)) + { + return result; + } + return defaultValue; + } + + public static string IntArrayToString(params int[] values) + { + StringBuilder stringBuilder = new StringBuilder(); + foreach (int value in values) + { + stringBuilder.Append(value); + stringBuilder.Append(','); + } + return stringBuilder.ToString().TrimEnd(','); + } + + public static string ColorToString(Color color) + { + return string.Format("{0:X2}{1:X2}{2:X2}{3:X2}", color.A, color.R, color.G, color.B); + } + + public static Color StringToColor(string code, byte defaultTransparency = byte.MaxValue) + { + if (string.IsNullOrEmpty(code)) + { + return Color.Empty; + } + int argb; + if (int.TryParse(code, NumberStyles.HexNumber, (IFormatProvider)null, out argb)) + { + return Color.FromArgb(argb); + } + Color baseColor = Color.FromName(code); + if (!baseColor.IsKnownColor) + { + return Color.Empty; + } + return Color.FromArgb(defaultTransparency, baseColor); + } + + public static int[] GetIntArraySetting(string name, int[] defaultValue) + { + try + { + string text = ConfigurationManager.AppSettings[name]; + if (string.IsNullOrEmpty(text)) + { + return defaultValue; + } + string[] array = text.Split(','); + if (defaultValue != null && defaultValue.Length != array.Length) + { + return defaultValue; + } + int[] array2 = new int[array.Length]; + for (int i = 0; i < array2.Length; i++) + { + array2[i] = int.Parse(array[i]); + } + return array2; + } + catch + { + return defaultValue; + } + } + + public static string GetStringSetting(string name, string defaultValue) + { + string text = ConfigurationManager.AppSettings[name]; + if (string.IsNullOrEmpty(text)) + { + return defaultValue; + } + return text; + } + + public static void SaveSetting(string key, object value) + { + string value2 = Convert.ToString(value, CultureInfo.InvariantCulture); + Utils.SaveSetting(key, value2); + } + + public static void SaveSetting(string key, string value) + { + Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); + configuration.AppSettings.Settings.Remove(key); + configuration.AppSettings.Settings.Add(key, value); + configuration.Save(ConfigurationSaveMode.Full); + ConfigurationManager.RefreshSection("appSettings"); + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/Vfo.cs b/SDRSharp.Radio/SDRSharp.Radio/Vfo.cs new file mode 100644 index 0000000..af3ea38 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/Vfo.cs @@ -0,0 +1,871 @@ +using System; + +namespace SDRSharp.Radio +{ + public sealed class Vfo + { + private const float NFMDeemphasisTime = 0.000149999993f; + + public const int DefaultCwSideTone = 600; + + public const int DefaultSSBBandwidth = 2400; + + public const int DefaultWFMBandwidth = 250000; + + public const int MinSSBAudioFrequency = 100; + + public const int MinBCAudioFrequency = 20; + + public const int MaxBCAudioFrequency = 15000; + + public const int MaxNFMBandwidth = 15000; + + public const int MinNFMAudioFrequency = 300; + + public const int MaxNFMAudioFrequency = 3800; + + private readonly double _minThreadedSampleRate = Utils.GetDoubleSetting("minThreadedSampleRate", 1000000.0); + + private readonly AutomaticGainControl _agc = new AutomaticGainControl(); + + private readonly AmDetector _amDetector = new AmDetector(); + + private readonly FmDetector _fmDetector = new FmDetector(); + + private readonly SideBandDetector _sideBandDetector = new SideBandDetector(); + + private readonly CwDetector _cwDetector = new CwDetector(); + + private readonly StereoDecoder _stereoDecoder = new StereoDecoder(); + + private readonly RdsDecoder _rdsDecoder = new RdsDecoder(); + + private readonly CarrierLocker _carrierLocker = new CarrierLocker(); + + private readonly AmAntiFading _amAntiFading = new AmAntiFading(); + + private readonly HookManager _hookManager; + + private DownConverter _mainDownConverter; + + private FrequencyTranslator _ifOffsetTranslator; + + private ComplexFilter _iqFilter; + + private ComplexFilter _audioFIR; + + private IirFilter _audioIIR; + + private DetectorType _detectorType; + + private DetectorType _actualDetectorType; + + private WindowType _windowType; + + private double _sampleRate; + + private int _bandwidth; + + private int _frequency; + + private int _ifOffset; + + private int _filterOrder; + + private int _decimationStageCount; + + private int _baseBandDecimationStageCount; + + private int _audioDecimationStageCount; + + private int _cwToneShift; + + private bool _needConfigure; + + private bool _lockCarrier; + + private bool _useAgc; + + private float _agcThreshold; + + private float _agcDecay; + + private float _agcSlope; + + private bool _agcUseHang; + + private bool _useAntiFading; + + private float _deemphasisAlpha; + + private float _deemphasisState; + + private int _squelchThreshold; + + private bool _fmStereo; + + private bool _filterAudio; + + private bool _bypassDemodulation; + + private bool _muted; + + private bool _hooksEnabled; + + private UnsafeBuffer _rawAudioBuffer; + + private unsafe float* _rawAudioPtr; + + public DetectorType DetectorType + { + get + { + return this._detectorType; + } + set + { + if (value != this._detectorType) + { + this._detectorType = value; + this._needConfigure = true; + } + } + } + + public int Frequency + { + get + { + return this._frequency; + } + set + { + if (this._frequency != value) + { + this._frequency = value; + this._needConfigure = true; + this._carrierLocker.Reset(); + } + } + } + + public int IFOffset + { + get + { + return this._ifOffset; + } + set + { + if (this._ifOffset != value) + { + this._ifOffset = value; + this._needConfigure = true; + this._carrierLocker.Reset(); + } + } + } + + public int FilterOrder + { + get + { + return this._filterOrder; + } + set + { + if (this._filterOrder != value) + { + this._filterOrder = value; + this._needConfigure = true; + } + } + } + + public double SampleRate + { + get + { + return this._sampleRate; + } + set + { + if (this._sampleRate != value) + { + this._sampleRate = value; + this._needConfigure = true; + } + } + } + + public WindowType WindowType + { + get + { + return this._windowType; + } + set + { + if (this._windowType != value) + { + this._windowType = value; + this._needConfigure = true; + } + } + } + + public int Bandwidth + { + get + { + return this._bandwidth; + } + set + { + if (this._bandwidth != value) + { + this._bandwidth = value; + this._needConfigure = true; + } + } + } + + public bool UseAGC + { + get + { + return this._useAgc; + } + set + { + this._useAgc = value; + } + } + + public float AgcThreshold + { + get + { + return this._agcThreshold; + } + set + { + if (this._agcThreshold != value) + { + this._agcThreshold = value; + this._needConfigure = true; + } + } + } + + public float AgcDecay + { + get + { + return this._agcDecay; + } + set + { + if (this._agcDecay != value) + { + this._agcDecay = value; + this._needConfigure = true; + } + } + } + + public float AgcSlope + { + get + { + return this._agcSlope; + } + set + { + if (this._agcSlope != value) + { + this._agcSlope = value; + this._needConfigure = true; + } + } + } + + public bool AgcHang + { + get + { + return this._agcUseHang; + } + set + { + if (this._agcUseHang != value) + { + this._agcUseHang = value; + this._needConfigure = true; + } + } + } + + public bool UseAntiFading + { + get + { + return this._useAntiFading; + } + set + { + this._useAntiFading = value; + } + } + + public int SquelchThreshold + { + get + { + return this._squelchThreshold; + } + set + { + if (this._squelchThreshold != value) + { + this._squelchThreshold = value; + this._needConfigure = true; + } + } + } + + public bool IsSquelchOpen + { + get + { + if (this._actualDetectorType == DetectorType.NFM && this._fmDetector.IsSquelchOpen) + { + return true; + } + if (this._actualDetectorType == DetectorType.AM) + { + return this._amDetector.IsSquelchOpen; + } + return false; + } + } + + public int DecimationStageCount + { + get + { + return this._decimationStageCount; + } + set + { + if (this._decimationStageCount != value) + { + this._decimationStageCount = value; + this._needConfigure = true; + } + } + } + + public int CWToneShift + { + get + { + return this._cwToneShift; + } + set + { + if (this._cwToneShift != value) + { + this._cwToneShift = value; + this._needConfigure = true; + } + } + } + + public bool LockCarrier + { + get + { + return this._lockCarrier; + } + set + { + if (this._lockCarrier != value) + { + this._lockCarrier = value; + this._needConfigure = true; + } + } + } + + public bool FmStereo + { + get + { + return this._fmStereo; + } + set + { + if (this._fmStereo != value) + { + this._fmStereo = value; + this._needConfigure = true; + } + } + } + + public bool Muted + { + get + { + return this._muted; + } + set + { + this._muted = value; + } + } + + public bool HookdEnabled + { + get + { + return this._hooksEnabled; + } + set + { + this._hooksEnabled = value; + } + } + + public bool SignalIsStereo + { + get + { + if (this._actualDetectorType == DetectorType.WFM && this._fmStereo) + { + return this._stereoDecoder.IsPllLocked; + } + return false; + } + } + + public string RdsStationName + { + get + { + return this._rdsDecoder.ProgramService; + } + } + + public string RdsStationText + { + get + { + return this._rdsDecoder.RadioText; + } + } + + public ushort RdsPICode + { + get + { + return this._rdsDecoder.PICode; + } + } + + public bool RdsUseFEC + { + get + { + return this._rdsDecoder.UseFEC; + } + set + { + this._rdsDecoder.UseFEC = value; + } + } + + public bool FilterAudio + { + get + { + return this._filterAudio; + } + set + { + this._filterAudio = value; + } + } + + public bool BypassDemodulation + { + get + { + return this._bypassDemodulation; + } + set + { + this._bypassDemodulation = value; + } + } + + public double BasebandSampleRate + { + get + { + return this._sampleRate / (double)(1 << this._baseBandDecimationStageCount); + } + } + + public Vfo(HookManager hookManager = null) + { + this._hookManager = hookManager; + this._bandwidth = 2400; + this._filterOrder = 500; + this._rdsDecoder.RdsFrameAvailable += this.RdsFrameAvailableHandler; + this._needConfigure = true; + } + + public void RdsReset() + { + this._rdsDecoder.Reset(); + } + + public void CarrierLockerReset() + { + this._carrierLocker.Reset(); + } + + private void ConfigureHookSampleRates() + { + if (this._hookManager != null) + { + this._hookManager.SetProcessorSampleRate(ProcessorType.RawIQ, this._sampleRate); + this._hookManager.SetProcessorSampleRate(ProcessorType.DecimatedAndFilteredIQ, this._sampleRate / (double)(1 << this._baseBandDecimationStageCount)); + this._hookManager.SetProcessorSampleRate(ProcessorType.DemodulatorOutput, this._sampleRate / (double)(1 << this._baseBandDecimationStageCount)); + this._hookManager.SetProcessorSampleRate(ProcessorType.FMMPX, this._sampleRate / (double)(1 << this._baseBandDecimationStageCount)); + this._hookManager.SetProcessorSampleRate(ProcessorType.FilteredAudioOutput, this._sampleRate / (double)(1 << this._decimationStageCount)); + } + } + + public void Init() + { + this.Configure(false); + } + + private void Configure(bool refreshOnly = true) + { + if (this._sampleRate != 0.0) + { + this._actualDetectorType = this._detectorType; + bool refresh = false; + this._baseBandDecimationStageCount = StreamControl.GetDecimationStageCount(this._sampleRate, this._actualDetectorType); + this._audioDecimationStageCount = this._decimationStageCount - this._baseBandDecimationStageCount; + int num = 1 << this._baseBandDecimationStageCount; + double num2 = this._sampleRate / (double)num; + if (!refreshOnly || this._mainDownConverter == null || this._mainDownConverter.SampleRate != this._sampleRate || this._mainDownConverter.DecimationRatio != num) + { + this._mainDownConverter = new DownConverter(this._sampleRate, num); + refresh = true; + this.ConfigureHookSampleRates(); + } + this._mainDownConverter.Frequency = (double)this._frequency; + if (!refreshOnly || this._ifOffsetTranslator == null || this._ifOffsetTranslator.SampleRate != num2) + { + this._ifOffsetTranslator = new FrequencyTranslator(num2); + } + this._ifOffsetTranslator.Frequency = (double)(-this._ifOffset); + this.UpdateFilters(refresh); + this._carrierLocker.SampleRate = num2; + this._cwDetector.SampleRate = num2; + this._fmDetector.SampleRate = num2; + this._fmDetector.SquelchThreshold = this._squelchThreshold; + this._amDetector.SquelchThreshold = this._squelchThreshold; + this._stereoDecoder.Configure(this._fmDetector.SampleRate, this._audioDecimationStageCount); + this._rdsDecoder.SampleRate = this._fmDetector.SampleRate; + this._stereoDecoder.ForceMono = !this._fmStereo; + switch (this._actualDetectorType) + { + case DetectorType.CW: + this._cwDetector.BfoFrequency = this._cwToneShift; + break; + case DetectorType.NFM: + this._fmDetector.Mode = FmMode.Narrow; + break; + case DetectorType.WFM: + this._fmDetector.Mode = FmMode.Wide; + break; + } + this._agc.SampleRate = this._sampleRate / (double)(1 << this._decimationStageCount); + this._agc.Decay = this._agcDecay; + this._agc.Slope = this._agcSlope; + this._agc.Threshold = this._agcThreshold; + this._agc.UseHang = this._agcUseHang; + this._needConfigure = false; + } + } + + private void UpdateFilters(bool refresh) + { + int num = 0; + int num2 = 15000; + int num3 = 0; + switch (this._actualDetectorType) + { + case DetectorType.WFM: + case DetectorType.AM: + num = 20; + num2 = Math.Min(this._bandwidth / 2, 15000); + break; + case DetectorType.CW: + num = Math.Abs(this._cwToneShift) - this._bandwidth / 2; + num2 = Math.Abs(this._cwToneShift) + this._bandwidth / 2; + break; + case DetectorType.USB: + num = (this._lockCarrier ? 20 : 100); + num2 = this._bandwidth; + num3 = this._bandwidth / 2; + break; + case DetectorType.LSB: + num = (this._lockCarrier ? 20 : 100); + num2 = this._bandwidth; + num3 = -this._bandwidth / 2; + break; + case DetectorType.DSB: + num = 20; + num2 = this._bandwidth / 2; + break; + case DetectorType.NFM: + num = 300; + num2 = Math.Min(this._bandwidth / 2, 3800); + break; + } + Complex[] array = FilterBuilder.MakeComplexKernel(this._sampleRate / (double)(1 << this._baseBandDecimationStageCount), this._filterOrder, (double)this._bandwidth, (double)num3, this._windowType); + if ((this._iqFilter == null | refresh) || this._iqFilter.KernelSize != array.Length) + { + this._iqFilter = new ComplexFilter(array); + } + else + { + this._iqFilter.SetKernel(array); + } + double num4 = this._sampleRate / (double)(1 << this._decimationStageCount); + if (refresh) + { + if (this._actualDetectorType == DetectorType.CW) + { + this._audioIIR.Init(IirFilterType.BandPass, (double)Math.Abs(this._cwToneShift), num4, 3.0); + } + else if (this._actualDetectorType == DetectorType.WFM) + { + double sampleRate = this._sampleRate / (double)(1 << this._baseBandDecimationStageCount); + this._audioIIR.Init(IirFilterType.HighPass, (double)num, sampleRate, 1.0); + } + else + { + this._audioIIR.Init(IirFilterType.HighPass, (double)num, num4, 1.0); + } + } + Complex[] array2 = FilterBuilder.MakeComplexKernel(num4, this._filterOrder, (double)(num2 - num), (double)(num2 + num) * 0.5, this._windowType); + if ((this._audioFIR == null | refresh) || this._audioFIR.KernelSize != array2.Length) + { + this._audioFIR = new ComplexFilter(array2); + } + else + { + this._audioFIR.SetKernel(array2); + } + this._deemphasisAlpha = (float)(1.0 - Math.Exp(-1.0 / (num4 * 0.00014999999257270247))); + this._deemphasisState = 0f; + } + + public unsafe void ProcessBuffer(Complex* iqBuffer, float* audioBuffer, int length) + { + if (this._needConfigure) + { + this.Configure(true); + } + length = this._mainDownConverter.Process(iqBuffer, length); + this._ifOffsetTranslator.Process(iqBuffer, length); + if (this._lockCarrier && (this._actualDetectorType == DetectorType.LSB || this._actualDetectorType == DetectorType.USB)) + { + this._carrierLocker.Process(iqBuffer, length); + } + this._iqFilter.Process(iqBuffer, length); + if (this._hookManager != null && this._hooksEnabled) + { + this._hookManager.ProcessDecimatedAndFilteredIQ(iqBuffer, length); + } + if (this._lockCarrier && (this._actualDetectorType == DetectorType.DSB || this._actualDetectorType == DetectorType.AM)) + { + this._carrierLocker.Process(iqBuffer, length); + } + if (this._lockCarrier && this._useAntiFading && this._carrierLocker.IsLocked && (this._actualDetectorType == DetectorType.DSB || this._actualDetectorType == DetectorType.AM)) + { + this._amAntiFading.Process(iqBuffer, length); + } + if (this._actualDetectorType == DetectorType.RAW) + { + Utils.Memcpy(audioBuffer, iqBuffer, length * sizeof(Complex)); + if (this._hookManager != null && this._hooksEnabled) + { + this._hookManager.ProcessFilteredAudioOutput(audioBuffer, length * 2); + } + if (this._muted) + { + Vfo.MuteAudio(audioBuffer, length * 2); + } + } + else + { + if (this._rawAudioBuffer == null || this._rawAudioBuffer.Length != length) + { + this._rawAudioBuffer = UnsafeBuffer.Create(length, 4); + this._rawAudioPtr = (float*)(void*)this._rawAudioBuffer; + } + if (this._actualDetectorType != DetectorType.WFM) + { + Vfo.ScaleIQ(iqBuffer, length); + } + if (this._bypassDemodulation) + { + if (this._actualDetectorType == DetectorType.WFM) + { + length >>= this._audioDecimationStageCount; + } + length <<= 1; + Vfo.MuteAudio(audioBuffer, length); + } + else + { + this.Demodulate(iqBuffer, this._rawAudioPtr, length); + if (this._hookManager != null && this._hooksEnabled) + { + this._hookManager.ProcessDemodulatorOutput(this._rawAudioPtr, length); + } + switch (this._actualDetectorType) + { + case DetectorType.WFM: + if (this._filterAudio) + { + this._audioIIR.Process(this._rawAudioPtr, length); + } + if (this._hookManager != null && this._hooksEnabled) + { + this._hookManager.ProcessFMMPX(this._rawAudioPtr, length); + } + this._rdsDecoder.Process(this._rawAudioPtr, length); + this._stereoDecoder.Process(this._rawAudioPtr, audioBuffer, length); + length >>= this._audioDecimationStageCount; + break; + case DetectorType.NFM: + if (this._filterAudio) + { + this._audioIIR.Process(this._rawAudioPtr, length); + this._audioFIR.Process(this._rawAudioPtr, length, 1); + this.Deemphasis(this._rawAudioPtr, length); + } + if (this._useAgc) + { + this._agc.Process(this._rawAudioPtr, length); + } + Vfo.MonoToStereo(this._rawAudioPtr, audioBuffer, length); + break; + default: + if (this._useAgc) + { + this._agc.Process(this._rawAudioPtr, length); + } + if (this._filterAudio) + { + this._audioIIR.Process(this._rawAudioPtr, length); + this._audioFIR.Process(this._rawAudioPtr, length, 1); + } + Vfo.MonoToStereo(this._rawAudioPtr, audioBuffer, length); + break; + } + length <<= 1; + if (this._hookManager != null && this._hooksEnabled) + { + this._hookManager.ProcessFilteredAudioOutput(audioBuffer, length); + } + if (this._muted) + { + Vfo.MuteAudio(audioBuffer, length); + } + } + } + } + + private unsafe static void MuteAudio(float* buffer, int length) + { + for (int i = 0; i < length; i++) + { + buffer[i] = 0f; + } + } + + private unsafe static void ScaleIQ(Complex* buffer, int length) + { + for (int i = 0; i < length; i++) + { + buffer[i].Real *= 0.01f; + buffer[i].Imag *= 0.01f; + } + } + + private unsafe static void MonoToStereo(float* input, float* output, int inputLength) + { + for (int i = 0; i < inputLength; i++) + { + float* intPtr = output; + output = intPtr + 1; + *intPtr = *input; + float* intPtr2 = output; + output = intPtr2 + 1; + *intPtr2 = *input; + input++; + } + } + + private unsafe void Deemphasis(float* buffer, int length) + { + for (int i = 0; i < length; i++) + { + this._deemphasisState += this._deemphasisAlpha * (buffer[i] - this._deemphasisState); + buffer[i] = this._deemphasisState; + } + } + + private unsafe void Demodulate(Complex* iq, float* audio, int length) + { + switch (this._actualDetectorType) + { + case DetectorType.NFM: + case DetectorType.WFM: + this._fmDetector.Demodulate(iq, audio, length); + break; + case DetectorType.AM: + this._amDetector.Demodulate(iq, audio, length); + break; + case DetectorType.DSB: + case DetectorType.LSB: + case DetectorType.USB: + this._sideBandDetector.Demodulate(iq, audio, length); + break; + case DetectorType.CW: + this._cwDetector.Demodulate(iq, audio, length); + break; + } + } + + private void RdsFrameAvailableHandler(ref RdsFrame frame) + { + if (this._hookManager != null) + { + this._hookManager.ProcessRdsBitStream(ref frame); + } + } + } +} diff --git a/SDRSharp.Radio/SDRSharp.Radio/WindowType.cs b/SDRSharp.Radio/SDRSharp.Radio/WindowType.cs new file mode 100644 index 0000000..27663f3 --- /dev/null +++ b/SDRSharp.Radio/SDRSharp.Radio/WindowType.cs @@ -0,0 +1,13 @@ +namespace SDRSharp.Radio +{ + public enum WindowType + { + None, + Hamming, + Blackman, + BlackmanHarris4, + BlackmanHarris7, + HannPoisson, + Youssef + } +} diff --git a/SDRSharp.Radio/refs to PortAudio.dll & Shark.dll.txt b/SDRSharp.Radio/refs to PortAudio.dll & Shark.dll.txt new file mode 100644 index 0000000..e69de29 diff --git a/SDRSharp/Properties/AssemblyInfo.cs b/SDRSharp/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..5210412 --- /dev/null +++ b/SDRSharp/Properties/AssemblyInfo.cs @@ -0,0 +1,18 @@ +using System.Diagnostics; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Security; +using System.Security.Permissions; + +[assembly: CompilationRelaxations(8)] +[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] +[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] +[assembly: SecurityRules(SecurityRuleSet.Level1)] +[assembly: AssemblyTitle("SDR Sharp")] +[assembly: AssemblyDescription("Software Defined Radio")] +[assembly: AssemblyProduct("SDR#")] +[assembly: AssemblyCopyright("Copyright © Youssef TOUIL 2012")] +[assembly: AssemblyFileVersion("1.0.0.1632")] +[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] +[assembly: AssemblyVersion("1.0.0.1632")] diff --git a/SDRSharp/Properties/Resources.Designer.cs b/SDRSharp/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e65dda0 --- /dev/null +++ b/SDRSharp/Properties/Resources.Designer.cs @@ -0,0 +1,163 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Properties { + using System; + + + ///

+ /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap audio_muted { + get { + object obj = ResourceManager.GetObject("audio_muted", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap audio_unmuted { + get { + object obj = ResourceManager.GetObject("audio_unmuted", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap center_24 { + get { + object obj = ResourceManager.GetObject("center_24", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap config_gear { + get { + object obj = ResourceManager.GetObject("config_gear", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap free_tuning { + get { + object obj = ResourceManager.GetObject("free_tuning", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + public static System.Drawing.Icon mainicon { + get { + object obj = ResourceManager.GetObject("mainicon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap sdr_start { + get { + object obj = ResourceManager.GetObject("sdr_start", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap sdr_stop { + get { + object obj = ResourceManager.GetObject("sdr_stop", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap sticky { + get { + object obj = ResourceManager.GetObject("sticky", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + public static System.Drawing.Bitmap toggle_menu { + get { + object obj = ResourceManager.GetObject("toggle_menu", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/SDRSharp/Properties/Resources.resx b/SDRSharp/Properties/Resources.resx new file mode 100644 index 0000000..66466c6 --- /dev/null +++ b/SDRSharp/Properties/Resources.resx @@ -0,0 +1,638 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAABE + IAAARCABv5pDRgAAAbdJREFUSEu1lbFKA0EURddkJRGxEoOtWIig/oGgYmMhRFArCxv9ApEg+AWiFkFb + EdHWQlSMzeajUoUQzw07Mu68rImYgUPy3rt7387s7kyUJMlANJvNMUZs1fIwk1k6nc5UFEWXcGvV8zCT + Pq1WaxzjC/gUloaZlYVVCxI+lUqliOmZM+/XgHEDz7CtpfxR84MsjGP4Nhd9dHvwpjozqfnPKhA7GDvQ + 0EU+llYUi8V56nfS0ODE5QNhLxlFqxCYC6fRUhDvw6LLxXE8TXwvHU02e178qaqjg+IpvEhk4cy63e4M + sW5CS7Pl8oVCYYH4A57wK/PbC0wzC2ckGBugm3mHZZfHuEYsveqhSR5+g9RsjbxmUndvELNbSfXnEJrk + kW2QPos6NPSglWu32xPEmtkD2Eb9yDYQzOIwra8rTps+wiuEJnlkzcVIG/hLBHPK/esSDfKQR/uaEvzp + Q0M7S/z7h+YKPoxftwoujuEAllzO3CpcMQuCKsKgiaUVQ212DsaRLvCxdBjuUhtuuxZDHDh6TYc/cETm + yGxYGu64XCqVJq1akLBID/1ruLLqeZhJC03dX9vBSKIvPrZM3Y89BAAAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + wwAADsMBx2+oZAAAAWFJREFUSEu1kjFOw1AMQBMBGysR3IARJBZ2BmZOADtHYOEE3dlg5BTpCgMCiRWY + y4ZUgTo0PH99R07q3yQoWHpqYjt++U6zsiz/FTc5Jm4yRZ7np3Dp1VLUFzy4DyfT6TS3DRbq51mWTbya + Qs8RPcd6XxeIJ1jScJWSdAmIM/iBL3q3Q84U36GCING8ZZ2A0OEyY1FV1U7ImwYVBLyTpASEDF/Ic5Fu + AaysyxMQ9s2VXgKhsa62gPCGC70FAT2JFRDttViGCSCchN8LmEDqzZXBAmEJd3AP3zGX4k+CGVzDDTzH + XIrBAhl+qN+Ah/f4fYk1j0GCTwYfSI/9yFzvcv1q+iy9BTMdHoc2/qZR4p2klyCsRetCWyAk1tUpqNdi + 8QQx316XK3iLxcZaLClBrNl1uYJb+IDGWizrBEJc1wM80rspubpYFMXGfD7f0nuPLoEgg+2clYaxcZNj + 4ibHo8x+AU63uPHXUkSFAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAA3 + XAAAN1wBy8ekuQAAALZJREFUSEvFlcENwjAQBM8PSkGiOGrgDxRBK3ZR/hL2JPYTLSS27pSV5jNRvLHj + OFZrTUXKSKSMRErSez+Z2bm1VtT1PUhJkBt4g/tsiZQEeYHly2OmREqyKnCeoyVSEmRd4AzNREqCqIKh + EikJ8qvA2bVcUhLkX4GzORMpCbJVsJRSrupeIiVBDi9IXaLUl5y6TVM/tNSjYujJiZQE8ePaB885rv2H + g31+mR3ckTISKSORMo5qH5MYfWaww5UBAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + wwAADsMBx2+oZAAAAIxJREFUSEvt1UEKAjEMBdAURip4//vkFE4Zi5cYuxP1ZyOz+DCbn1mIgbdpoIWk + TW2Mcaq1XjLE3oaY4ZHkCvZO9AKaUDnmgDs8k3Rz91R0UYkuKkV0YA1SuAFNqPzIO1iAzRGFOX+asqul + ZKWUiZ2uEHujTNY2NVP7/we7vu9gTdIsOg3nJBO9uzpuH18Eg6dHrMZ7AAAAAElFTkSuQmCC + + + + + AAABAAQAEBAAAAEAIABoBAAARgAAABgYAAABACAAiAkAAK4EAAAgIAAAAQAgAKgQAAA2DgAAQEAAAAEA + IAAoQgAA3h4AACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAABRAwDYVAMA7FED + AOdUAwDsUQMA7VMDAOhRAwDnUQMA51EDAOdRAwDnUQMA51EDAOdRAwDnUQMA51QDAOxRAwDYWwcA6l8K + AP9jDAD/XggA6V0KAOBiDAD/XgsA/1oKAPpdCgD7XQoA+10KAPtdCgD7XQoA+10KAPteCgD/WwcA6mYQ + AOVpFAD/Yw4AeWMSAClpEgApYgwAU2cTAPBmEwD5ZhAA8mMQAPNjEADzYxAA82MQAPNjEADzZRIA+WYT + AONsHQD2bR0Ae3QhAC5sGgDdbB0A63MfAEluHQA8bR0A+24cAPNuGwDxbhsA8W4bAPFuGwDxbhsA8W4a + APdrHADheCMAtHskACN2JQDoeCUA/HglAPh4JQD8fyUAIngkAJR6JgD/diUA8XglAPZ5JQDwdyUA73cl + AO92JQD1eSMA34IuADGBLgCUiDAA/4IsAOuALgDsgC4A/oEuAKuCKwApgS8A/oIuAO1/LQDKgC4A8oAv + APSALgDsgi4A838rAN6NOAASizQAWIk4ANmMOQD1izYA6ow4AOyMNQD3jDkAOoo3AIaLNwBYkjwAXIo3 + AFOMNwDhijYA84k4APGKOADdlUIAipdCALiUQQA+lEAA7ZRAAO2TQADpk0AA/JZDAJy2bQAHl0IAwJhE + AP+XQwCUlUAAS5ZAAPSWQADxk0AA3Z1KANGmTgD/o04Acp5KAGeiTQD/oEwA56JNAP+fSgB+fz8ACJ1M + AOShTADtoEwA/6FMAGifSwCDqlEA/6FMAKSqUwDZqVMA7qZWAO2oVgA+qFMAma5YAP+nVAGjqFYAR6dT + AFKrVQBxp1YA/KpTAOioVQDmrFYARKlVAMWsVgBNtF8A1LNfAOm0XwDstGAA1LZgAEq0XgJcuWADQrJd + ANK0XgDQtFUAGLVgANa0XwDssVwA7bRfANO2YgBGqlUABrxqANO+aQDovmoA4bxnAOq+aQDkv2sAub9n + AOC8aQDrvmoA9b9qAGW6aAA4wGsA871rAPq/ZwDsumMAKb5rAHfKdADQyXIA5cpzAN/KcwDfx3IA4cZx + AOfHdADiyXMA38lyAOPJdADoznkAP8JvADfGcACDwnIAJsp2AGHHdADi1H8A0NR/AOTUfwDe1H8A3tR/ + AN7UfwDe1H8A3tR/AN7UgADd038A5NJ8AOXYgQB+2YQAUdWBAI7TfgDw03wA09+IANPghwDn4IoA4eCK + AOHgigDh4IoA4eCKAOHgigDh4IoA4eCKAOHfigDj34gA8d+JAPPghwDv4IoA6N+IANPplQC/65YA0euW + AMzrlgDM65YAzOuWAMzrlgDM65YAzOuWAMzrlgDM65YAzOuWAMzrlgDM65YAzOuWANHplQC/AAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgA + AAAYAAAAMAAAAAEAIAAAAAAAYAkAAAAAAAAAAAAAAAAAAAAAAABPAQDXUgEA61IBAOZSAQDmUgEA5lIB + AOZSAQDmUgEA5lIBAOZSAQDmUgEA5lIBAOZSAQDmUgEA5lIBAOZSAQDmUgEA5lIBAOZSAQDmUgEA5lIB + AOZSAQDmUgEA61EBANZXBgDsWggA/1kIAPxZCAD8VggA/VoIAP9bCAD/WQgA/1kIAPxZCAD8WQgA/FkI + APxZCAD8WQgA/FkIAPxZCAD8WQgA/FkIAPxZCAD8WQgA/FkIAPxZCAD8WggA/1YGAOtfCwDkXAsA+l8K + APNdDAD9YQwA/18MAONfCgDbXQwA+GIMAP9fCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8L + APRfCwD0XwsA9F8LAPRfCwD0XAsA+l8LAONhDQDjYg8A+WURAP9iEADcYg0ATgAAAAAAAAAAZA0AJmQQ + AKpnEQD/Yw0A9GENAPNhDQDzYQ0A82ENAPNhDQDzYQ0A82ENAPNhDQDzYQ0A82ENAPNhDQDzYxAA+WMN + AOJqGgDhbhsA/2sZANNpDwARaxoAE2wZAIttGgCcbh4AMwAAAABsGQCLbhsA/2sZAPJrGQDyaxkA8msZ + APJrGQDyaxkA8msZAPJrGQDyaxkA8msZAPJrGQDyaRcA+GoaAOFsGgDmbh0A9HIjAB1zHgAqcBwA6nMd + AP9yHQD/bx0A/nAeAFsAAAAAbhwAsnAdAP9uGgDwbhoA8G4aAPBuGgDwbhoA8G4aAPBuGgDwbhoA8G4a + APBuGgDwbR0A9nAbAN90JAD1dyQAbwAAAAB3IQDcdiQA/nQlAO52JQDvdCUA93YlAPh4IQAmeyMAHXUi + APN3IgDydiUA73YlAO92JQDvdiUA73YlAO92JQDvdiUA73YlAO92JQDvdCUA9XYiAN5+KQDEAAAAAH0q + AIqAKgD/eyYA7X0mAO59JgDueyYA7X4pAP59KgC7AAAAAH0pAJt/KgD/fSYA7nspAPF+KQD2eyYA830m + AO59JgDufSYA7n0mAO59JgDufSYA9HwpAN2ELwBLiTEAGoQwAP+DMADzgS4A7IMvAO2DLwDtgy8A7YMw + AO2EMAD/gzAAOoMzACOBLQD2hS4A+4EtAPCCMADPgDAA5IQwAP2EMADtgS4A7IMvAO2DLwDtgy8A84Qv + ANwAAAAAeC0AEYk0AnqLNwD5iDYA74g3AOuINwDriDcA64g3AOuLNAD7izcAsAAAAACLNwDCizcAwoUz + ACiQOwAeiC0AHIo2AIyLNwD9iDQA7Yg3AOuINwDriDcA8Yo1ANuTQwATkz0Au5E/AByPPQJgkD0A/pI6 + AOuSPQDqkToA65E6AOuPPADsjzoA85I/BiiOPQAykTwAFZM/AIWUPgHhkj8ArqJFAAuQPAJ6kj4A/5I9 + AOqSPQDqkDsA8JI9ANyVQgBjn0gA/5VCANd/fwAClkMAkJdCAP2VRQDol0IA6ZdCAOmVRQDol0IA/ZhE + AJUAAAAAlkQAjZtGAP+WRADvl0QA/5hCAMQAAAAAmEUAsJVCAPmVRQDol0UA75ZFANmeRwDBn0gA8pxH + APyfSgCeAAAAAJ9LANKfSADynEcA55xLAOecRwDnnUsA/p9KAHsAAAAAnUoAnZ9KAPqcRwDnnEcA559K + AP+gSwCElkUAFp5KAO2cSQDsnEgA+Z5JAJyjUQDcplIA7KRPAOejUQD7qFIARKVQADOmTwD6pE8A6qNR + AOWkUgD4plEBwKJFAAujVQAno04AKqNPAPClTgDpplIA5qNRAOijTwD2o1EAMqZQAF+nUgD/plEA9KVQ + ADyrWADWq1UA66pVAOWrVwDtqFYA3bBiAA2qVwBmq1gA/KxZAP+rWAHZr08PEKpWAGqpVQDFAAAAAKtX + AKSrWAD2q1gA5KpVAOWoVwDvqlcA06JcAAuqVwGmrFcA0v9/AAKyWwDUsl0A6bFdAOOyXADisVoA8rJc + AMS2YQAVrVgDQq9aAnaqVQ4StF8AS7JaAO+xXQD2sF0ANK5eACOyWwDvsV0A5rFdAOOyXADir10A9LJe + ALC1XQAmsF4APgAAAAC6ZQDUumIA6bplAOO6ZQDjumQA4rdiAPC3ZQDWvmcAZ79qAEi8ZAGRumIA7rdk + AOi4ZQDvumMAtgAAAAC6ZACCuWIA+rplAOK6ZQDjt2IA4bxmAP+5ZQCXAAAAALllA0nBbQDSwGwA579q + AOG/agDhv2oA4cBsAODAbADnvGsA87xrAPO/awDwwGkA479qAOG/agDhwGkA9MBsAF4AAAAAwGwBs75t + APrAagDowWoA9L9sAN27aQAiv2gALL1pAN7IcQDRxnMA5shwAODIcADgyHAA4MhwAODIcADgyHAA4Mhw + AODIcADgyHAA4MhwAODJcgDfyHAA5chwAOXKcwA1AAAAAMRyAI/IcwDSx3EAr8FsACG/fwAIx3EAyshw + ANzPegDQz3oA5cx6AN/MegDfzHoA38x6AN/MegDfzHoA38x6AN/MegDfzHoA38x6AN/MegDfzHcA3s16 + AOjOegDd0HoATQAAAAAAAAAAAAAAANR/ACTPeQC7y3kA9M16AM7VfwDQ1H8A5NR/AN7UfwDe1H8A3tR/ + AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tWBAN3UfwDk1H8A6td/ALTXggCN1oAAo9OA + AN/UfwDq1oEA49Z/AM7dhADO3ocA4t6GANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6G + ANzehgDc3oYA3N6GANzdhgDc3YgA3duHAObdhwDs3oUA6duIAN/eiADb3ocA4t2HAM3lkADS5I8A5+OP + AODjjwDg448A4OOPAODjjwDg448A4OOPAODjjwDg448A4OOPAODjjwDg448A4OOPAODjjwDg448A4OOP + AODjjwDg448A4OOPAODjjwDg5I8A5+WNANHslQC/65cA0eyXAMzslwDM7JcAzOyXAMzslwDM7JcAzOyX + AMzslwDM7JcAzOyXAMzslwDM7JcAzOyXAMzslwDM7JcAzOyXAMzslwDM7JcAzOyXAMzslwDM65cA0eyX + AL4AAAAAAAAAAAAAAAAGAAAAAIAAAABAAAAgAAAAQCAAAAAAAACAEAAAAAAAAAAIIAAICAAAAAAAAAAE + AAAAAAEAAAICAAABAAAAAIAAAABwAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAIAQ + AAAAAAAAAAAAAAAAAAAAAAAAUQEA2E4BAO1PAQDnTwEA508BAOdPAQDnTwEA508BAOdPAQDnTwEA508B + AOdPAQDnTwEA508BAOdPAQDnTwEA508BAOdPAQDnTwEA508BAOdPAQDnTwEA508BAOdPAQDnTwEA508B + AOdPAQDnTwEA508BAOdPAQDnTgEA7VEBANhWBQDsVwUA/1MFAP1TBQD9UwUA/VMFAP1TBQD9UwUA/VMF + AP1TBQD9UwUA/VMFAP1TBQD9UwUA/VMFAP1TBQD9UwUA/VMFAP1TBQD9UwUA/VMFAP1TBQD9UwUA/VMF + AP1TBQD9UwUA/VMFAP1TBQD9UwUA/VMFAP1XBQD/VgUA7FsKAOVbCgD7WQoA9VkKAPVZCgD1WQoA9VkK + APdZCgD9XAoA/1kKAPpZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkK + APVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VsKAPtbCgDlYAsA5F0LAPpgCwD0XwoA810L + APVjDAD/YQwA/F4LAN1gDQDUYAoA7GMMAP9fCwD7XwoA82ALAPRgCwD0YAsA9GALAPRgCwD0YAsA9GAL + APRgCwD0YAsA9GALAPRgCwD0YAsA9GALAPRgCwD0YAsA9GALAPRgCwD0XQsA+mALAORfDQDjYQ4A+V8M + APNiDgD3ZRAA/2MQAK5jEQA7AAAAAQAAAABmFAAZYw8AcWMPAOdkDwD/XwwA8l8MAPNfDADzXwwA818M + APNfDADzXwwA818MAPNfDADzXwwA818MAPNfDADzXwwA818MAPNfDADzXwwA818MAPNhDgD5Xw0A42YV + AOJnFQD4ZhQA9moXAP9oEwBzAAAAAAAAAABtGAAqaRoAOn8AAAIAAAAAbRUAI2kVAM5rGAD/ZhcA8WkX + APJpFwDyaRcA8mkXAPJpFwDyaRcA8mkXAPJpFwDyaRcA8mkXAPJpFwDyaRcA8mkXAPJpFwDyaRcA8mcV + APhmFQDiahsA4WoZAPlvHAD/bBwAdQAAAABsFwAhbhoAt2oYAPlsGwD+ahgA2m0ZAE8AAAAAah8AGG0c + ANlqGwD9ahsA8WobAPFqGwDxahsA8WobAPFqGwDxahsA8WobAPFqGwDxahsA8WobAPFqGwDxahsA8Wob + APFqGwDxbRkA92obAOFwGwDfdB4A/3AeAKoAAAAAdB0AI28cAOByHQD/bRwA8m8bAPFwHAD8cB0A/nAg + AFYAAAAAbxsAN28aAPdvHQDzbhoA8G4aAPBuGgDwbhoA8G4aAPBuGgDwbhoA8G4aAPBuGgDwbhoA8G4a + APBuGgDwbhoA8G4aAPBtHQD2bxwA4HUjAOZ3IwDtdCoAGD8AAAR0IgDHdyUA/3MlAO52JQDvdiUA73Ul + AO92JQD4diEA8XIfACgAAAAAdSQAlHglAP91JQDvdiUA73YlAO92JQDvdiUA73YlAO92JQDvdiUA73Yl + AO92JQDvdiUA73YlAO92JQDvdiUA73QlAPV0IwDfeSQA83onAHsAAAAAfCUAeX4oAP97JQDueyUA7nsl + AO57JQDueyUA7nslAO58JwD/eycAtgAAAAB7KQAfeScA73gkAPN7JQDueyUA7nslAO57JQDueyUA7nsl + AO57JQDueyUA7nslAO57JQDueyUA7nslAO57JQDueyQA9HwnAN5/KwDOfyoADHovABt8LADrfykA9H8p + AO5/KQDufykA7n8pAO5/KQDufykA7n8pAO6ALQD/fy0ATgAAAACALACbgSwA/4AsAO1/KQDufyoA8H8q + APaAKQD1gCkA738pAO5/KQDufykA7n8pAO5/KQDufykA7n8pAO5/KQD0fyoA3oMyAGUAAAAAhjAAlIwz + AP+ELQDrgi4A7IIuAOyCLgDsgi4A7IIuAOyCLgDsgi4A7IItAPqFMAC/AAAAAIIwAC+FLgD1hDAA74Iu + APyCLgDwhDAA0oIvANeCMQD4gi4A9oQuAOuCLgDsgi4A7IIuAOyCLgDsgi4A7IIwAPKDMADdAAAAAAAA + AACHMAAviDYBu4g3AP6HNwDrhzcA64g3AOuINwDriDcA64g3AOuINwDrijcA7Ic3APqLNQA+AAAAAIo2 + ALiROQD/ijYApIYxByQAAAAAAAAAAIYzAEaHNADRiDQA/Io2AOqINwDriDcA64g3AOuINwDriDcA8Ys2 + ANwAAAAAjDoAV408AEgAAAAAjjoBp407AP6MNwDqjzkA6485AOuPOQDrjzkA6485AOuNNwDqjDcA/I06 + AKYAAAAAkDsAY445AJMAAAAAkTwEP5A8AaGPPAGQjD8AFH8zGQqNOgHBjzgA+4w3AOqPOQDrjzkA6485 + AOuMOQDxjjcA3H8/AASTPgDQl0IA/5ZCAEkAAAAAkj8AwZJAAPqSPwDplEAA6pRAAOqUQADqlEAA6pRA + AOqUPwDtlD0B7JE6ByOqVQADAAAAAJI/AHGUQAD/lD8A/ZVBAP+UPwDlk0QALYk6AA2UQADalD4A9JRA + AOqUQADqlEAA6pI+APCSPwDdlkQAR5dCAPiXQwDxl0UA7JZDACKcRAAal0UA5ZVFAPCVRQDolUUA6JVF + AOiVRQDolUUA6JVFAOiXQwD9l0UAhQAAAACbRgNFlEIA/JVCAO2VRQDolUUA6JdFAPaVRADcnDoADZZC + AD2WRQD3l0MA6pVFAOiVRQDolEUA8JVDANeeSQCrm0kA955KAOabSQD3nkcAwQAAAACdSgBWnkoA+55I + AOieSADonkgA6J5IAOieSADom0cA555HAP2dSABwAAAAAJ9IA0ObRwD2nkgA6J5IAOieSADom0cA555J + APudSQCnAAAAAJ1JAJKbRwD8m0cA55xHAOeeSQD6nUkAkqNMANyiTQDto04A56RMAOajTAD9pE0CcwAA + AACjTwCqoUwA+aRMAOajTgDno04A56RMAOahTAD2oU0AvwAAAAD/AP8BAAAAAKNOALqkTwD0o04A56NO + AOejTgDnpE8A56FOAPuhTQNSmWYABaFOANqkTwDxoU8A6KFMAPCjTAUyplEA2KdUAOyoVADmp1QA5qhS + AOuoUgDrqlUAJKVMABSoUwDfplQA8qhTAOWoUwDlp1QA76hSAeunUAYmplgAF6ZTAZMAAAAAp1MDUqVR + APmnVADmqFQA5qhUAOanVADmp1IA7qRTAOKqVQASp1MAQKZUAPimVQD1p1MBuAAAAACrWADWq1UA66tV + AOWrVQDlrFgA5KtYAPOsWADCAAAAAa5VADasWADnrFgA+alYAPiqVwHvqlgDSwAAAACsVwCqqVcA+6pV + ACR/fwACrFcAxqxYAPCrVQDlq1UA5atVAOWsWADkqVgA9axYALMAAAAArFgCdrdeAP+tWQJhAAAAAK1c + ANWwWwDqrlkA5K5ZAOSxXADjsFwA47BcAPaxXACoAAAAAK9XByCvXAGgsVsDp61cBS8AAAAAsF0AiLBc + APawXAD2sV0AkAAAAACyXANQsV0A9q5aAOSxXADjrlkA5LFcAOOwXADjrVsA+LBcAI8AAAAAsFwCcape + ABsAAAAAuGEA1LRhAOm3XwDjt18A47dfAOO3XwDjt18A47dfAPW5YQC6uWQFMAAAAAAAAAAAuWQHIbhj + AKK3XwD1t2IA5LhgAOa3YQDnuGMAJAAAAAC4YgCwtWIA9LViAOK3XwDjt18A47dfAOO3YgDkt18A9bhj + AJ8AAAAAAAAAAKJcAAu8ZQDTvWcA6L1lAOK9ZQDivWUA4r1lAOK9ZQDivGUA4rlnAO+8ZADpu2gAwbtm + AL26ZwHjumcA8r1lAOK9ZQDivGUA4rplAPO7ZgCiAAAAALpnACW6ZwDjumgA67xlAOK9ZQDivWUA4r1o + AOG6ZQD2u2cAubZtAAfBaQgdvGgBv8FtANLAbADnv2oA4b9qAOG/agDhv2oA4b9qAOG/agDhv2oA4cBq + AOO+agDqwGwA68BsAOS/agDhv2oA4b9qAOG/agDhvm0A4r5rAPLBawBTAAAAAMBtA02+bQDuwW0A7L9q + AOG+bQDiwWsA9MBtANDBcAAZAAAAAMFsAKLAagDoyHEA0cZyAObIbwDgyG8A4MhvAODIbwDgyG8A4Mhv + AODIbwDgyG8A4MhvAODIbwDgyG8A4MhvAODIbwDgyG8A4MhvAODIcgDfxW8A58VwAN7FcwAsAAAAAMZx + AEjHbwDOx3MA78VyAOzHcQCyx28AIAAAAADFcgBix28A98huANLLdADQyXcA5ct0AN/LdADfy3QA38t0 + AN/LdADfy3QA38t0AN/LdADfy3QA38t0AN/LdADfy3QA38t0AN/LdADfy3QA38t0AN/MdwDeyHcA68l0 + ANLNeQAuAAAAAL9/AATJdwA+yncAMQAAAAAAAAAAzHcAWsp3AOnKdwDpy3QA0NB9ANDSfQDk0n0A3tJ9 + AN7SfQDe0n0A3tJ9AN7SfQDe0n0A3tJ9AN7SfQDe0n0A3tJ9AN7SfQDe0n0A3tJ9AN7SfQDe0n0A3tJ9 + AN7PewDd0noA6c99ANzQfQBu0H8AFgAAAAAAAAAAzXwAKdJ8AI/RegDr0noA49F9AOTQfQDQ1n8A0NaC + AOPVggDd1YIA3dWCAN3VggDd1YIA3dWCAN3VggDd1YIA3dWCAN3VggDd1YIA3dWCAN3VggDd1YIA3dWC + AN3VggDd1YIA3dWCAN3VgQDd1oEA49Z/AO7WfwDW14EAu9eCAMDUgQDf1n8A7tSCAN/VggDd1oIA49Z/ + ANDdhADO3YcA4t2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2G + ANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3NuHAODbhgDm3IQA5duEAN/dhgDc3YYA3N2G + ANzdhwDi3YQAzuKMAM3hjADh44oA2+OKANvjigDb44oA2+OKANvjigDb44oA2+OKANvjigDb44oA2+OK + ANvjigDb44oA2+OKANvjigDb44oA2+OKANvjigDb44oA2+OKANvjigDb44oA2+OKANvjigDb44oA2+OK + ANvjigDb44oA2+GMAOHijADN5ZAA0uWSAObokADg6JAA4OiQAODokADg6JAA4OiQAODokADg6JAA4OiQ + AODokADg6JAA4OiQAODokADg6JAA4OiQAODokADg6JAA4OiQAODokADg6JAA4OiQAODokADg6JAA4OiQ + AODokADg6JAA4OiQAODokADg5ZIA5uWQANLtlwC+65cA0e2YAMztmADM7ZgAzO2YAMztmADM7ZgAzO2Y + AMztmADM7ZgAzO2YAMztmADM7ZgAzO2YAMztmADM7ZgAzO2YAMztmADM7ZgAzO2YAMztmADM7ZgAzO2Y + AMztmADM7ZgAzO2YAMztmADM7ZgAzO2YAMzrlwDR7ZcAvgAAAAAAAAAAAAAAAAAAAAAAgAAABiAAAAgQ + AAAQCAAAAAQAACAEAAAAAgAAQAIAAMABDACQASAACABAAAAAgAAEAIBAAgFAAAAAQAEAAgARAIQgCQAw + EAYAABAAAAAIBAAABAgAAAIwAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAEAAAACAAAAAAQAgAAAA + AAAAQgAAAAAAAAAAAAAAAAAAAAAAAFEAAdlPAAHtUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEA + AehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEA + AehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEA + AehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoUQAB6FEA + AehRAAHoUQAB6FEAAehRAAHoUQAB6FEAAehRAAHoTwAB7VEAAdlOAgDtUgIA/04CAP1OAgD9TgIA/U4C + AP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4C + AP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4C + AP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4C + AP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/U4CAP1OAgD9TgIA/VICAP9OAgDtUgQA51IE + AP1SBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IE + APdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IE + APdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IE + APdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IEAPdSBAD3UgQA91IE + APdSBAD9UgQA51YFAOZYBgD8WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgG + APZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgG + APZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgG + APZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgGAPZYBgD2WAYA9lgG + APZYBgD2WAYA9lgGAPZYBgD2WAYA/FYFAOZYBwDmWwoA/FsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsK + APZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsK + APZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsK + APZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsK + APZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPZbCgD2WwoA9lsKAPxYBwDmWwoA5VsKAPtZCgD1WQoA9VkK + APVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkK + APVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkK + APVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkK + APVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVZCgD1WQoA9VkKAPVbCgD7WwoA5V8L + AORcCwD6XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD2XwsA+18M + AP9hDAD/YAwA/18LAPtfCwD2XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8L + APRfCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8L + APRfCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8LAPRfCwD0XwsA9F8L + APRfCwD0XAsA+l8LAORiCwDkXwsA+mILAPRiCwD0YgsA9GILAPRiCwD0YgsA9GILAPRiCwD0XwoA82IM + APllDQD/Xg0A/WINAOJhDADMYg0Au2EOAMdiDQDiYg0A/2UNAP9iCwD5XwoA82ILAPRiCwD0YgsA9GIL + APRiCwD0YgsA9GILAPRiCwD0YgsA9GILAPRiCwD0YgsA9GILAPRiCwD0YgsA9GILAPRiCwD0YgsA9GIL + APRiCwD0YgsA9GILAPRiCwD0YgsA9GILAPRiCwD0YgsA9GILAPRiCwD0YgsA9GILAPRiCwD0YgsA9GIL + APRiCwD0YgsA9GILAPRiCwD0YgsA9F8LAPpiCwDkXw0A42ANAPlfCwDzXwsA818LAPNfCwDzXwsA818L + APNfCwDzYQsA9GQOAP9iDADvYg4Am2QRAEdrGgATfyoABgAAAABVAAADaAsAFmERAEliDgCeYA0A8GQO + AP9gCwD0XwsA818LAPNfCwDzXwsA818LAPNfCwDzXwsA818LAPNfCwDzXwsA818LAPNfCwDzXwsA818L + APNfCwDzXwsA818LAPNfCwDzXwsA818LAPNfCwDzXwsA818LAPNfCwDzXwsA818LAPNfCwDzXwsA818L + APNfCwDzXwsA818LAPNfCwDzXwsA818LAPNfCwDzXwsA818LAPNgDQD5Xw0A42ANAONiDwD5YA0A82AN + APNgDQDzYA0A82ANAPNjDQDyYRAA+GUSAP9jEQCxZA8AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAGQVADBjEQCxZxIA/2MPAPdjDQDyYA0A82ANAPNgDQDzYA0A82ANAPNgDQDzYA0A82AN + APNgDQDzYA0A82ANAPNgDQDzYA0A82ANAPNgDQDzYA0A82ANAPNgDQDzYA0A82ANAPNgDQDzYA0A82AN + APNgDQDzYA0A82ANAPNgDQDzYA0A82ANAPNgDQDzYA0A82ANAPNgDQDzYA0A82ANAPNgDQDzYg8A+WAN + AONnFQDjZxUA+WQSAPNkEgDzZBIA82QSAPNnFQDyZxQA+mYUAP1mFQB3AAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGgUAHxlFAD9ZxUA+WcVAPJkEgDzZBIA82QS + APNkEgDzZBIA82QSAPNkEgDzZBIA82QSAPNkEgDzZBIA82QSAPNkEgDzZBIA82QSAPNkEgDzZBIA82QS + APNkEgDzZBIA82QSAPNkEgDzZBIA82QSAPNkEgDzZBIA82QSAPNkEgDzZBIA82QSAPNkEgDzZBIA82QS + APNkEgDzZBIA82cVAPlnFQDjaxYA4mkWAPhrGADyaxgA8msYAPJpGADxaRYA+GgVAPZqFQBdAAAAAAAA + AAAAAAAAAAAAAAAAAABmFgA5aRgAamgYAHxpFwBhbxoAJwAAAAAAAAAAAAAAAAAAAAAAAAAAbBUAYGoV + APlpFgD4aRgA8WsYAPJrGADyaxgA8msYAPJrGADyaxgA8msYAPJrGADyaxgA8msYAPJrGADyaxgA8msY + APJrGADyaxgA8msYAPJrGADyaxgA8msYAPJrGADyaxgA8msYAPJrGADyaxgA8msYAPJrGADyaxgA8msY + APJrGADyaxgA8msYAPJrGADyaxgA8msYAPJpFgD4axYA4mscAOJpGgD4axwA8mscAPJrHADyaRkA9mwb + AP9qGgBiAAAAAAAAAAAAAAAAAAAAAG4aAENsGQC/ahgA+WwbAP9tHAD/bBsA/2gaAPFqGwCcaRoAHQAA + AAAAAAAAAAAAAAAAAABqGgBibBsA/mkZAPZrHADyaxwA8mscAPJrHADyaxwA8mscAPJrHADyaxwA8msc + APJrHADyaxwA8mscAPJrHADyaxwA8mscAPJrHADyaxwA8mscAPJrHADyaxwA8mscAPJrHADyaxwA8msc + APJrHADyaxwA8mscAPJrHADyaxwA8mscAPJrHADyaxwA8mscAPJrHADyaRoA+GscAOJqGwDhbRkA92ob + APFqGwDxaxsA8m8cAP9sGQCBAAAAAAAAAAAAAAAAAAAAAG0bAIJsGgD7bhsA/2sbAPRqGwDxahsA8Wob + APFqGAD2cRwA/24aAN5tGwBBAAAAAAAAAAAAAAAAAAAAAG0cAH5wHAD/axsA8mobAPFqGwDxahsA8Wob + APFqGwDxahsA8WobAPFqGwDxahsA8WobAPFqGwDxahsA8WobAPFqGwDxahsA8WobAPFqGwDxahsA8Wob + APFqGwDxahsA8WobAPFqGwDxahsA8WobAPFqGwDxahsA8WobAPFqGwDxahsA8WobAPFqGwDxahsA8W0Z + APdqGwDhbhoA4GwYAPZuGQDwbBgA73AbAP9uHgCyAAAAAAAAAAAAAAAAfwAAAm8cAJlxHAD/bhsA9WwY + AO9uGQDwbhkA8G4ZAPBuGQDwbhkA8GwYAO9uGgD+bhkA8G4dAEUAAAAAAAAAAAAAAAAAAAAAcBsAsXAb + AP9sGADvbhkA8G4ZAPBuGQDwbhkA8G4ZAPBuGQDwbhkA8G4ZAPBuGQDwbhkA8G4ZAPBuGQDwbhkA8G4Z + APBuGQDwbhkA8G4ZAPBuGQDwbhkA8G4ZAPBuGQDwbhkA8G4ZAPBuGQDwbhkA8G4ZAPBuGQDwbhkA8G4Z + APBuGQDwbhkA8G4ZAPBsGAD2bhoA4G8cAOBuHwD2bhwA8HEcAPhyHQDocSMAJAAAAAAAAAAAAAAAAHIg + AIZ0IQD/bh0A8m4cAPBuHADwbhwA8G4cAPBuHADwbhwA8G4cAPBuHADwcBwA73AeAPxzHwDrdB8AMAAA + AAAAAAAAAAAAAHcfACBvIADnbxwA924cAPBuHADwbhwA8G4cAPBuHADwbhwA8G4cAPBuHADwbhwA8G4c + APBuHADwbhwA8G4cAPBuHADwbhwA8G4cAPBuHADwbhwA8G4cAPBuHADwbhwA8G4cAPBuHADwbhwA8G4c + APBuHADwbhwA8G4cAPBuHADwbhwA8G4cAPBuHADwbh8A9m8cAOBzIwDfcyQA9XMkAPB2IwD/cyQAYwAA + AAAAAAAAAAAAAHUgAF13IwD/dCEA83UkAO91JADvdSQA73UkAO91JADvdSQA73UkAO91JADvdSQA73Uk + AO91JADvdiMA/3YhAM1tEgAOAAAAAAAAAAAAAAAAdCIAdnYkAP91JADvdSQA73UkAO91JADvdSQA73Uk + AO91JADvdSQA73UkAO91JADvdSQA73UkAO91JADvdSQA73UkAO91JADvdSQA73UkAO91JADvdSQA73Uk + AO91JADvdSQA73UkAO91JADvdSQA73UkAO91JADvdSQA73UkAO91JADvdSQA73MkAPVzIwDfeCQA33gj + APR4JgD+dyQAvP8AAAEAAAAAAAAAAHMeACF2JADndyUA+HUlAO53JgDvdyYA73cmAO93JgDvdyYA73cm + AO93JgDvdyYA73cmAO93JgDvdyYA73clAO94JgD/diUAkAAAAAAAAAAAAAAAAHciAA94IwDYdSMA+Xcl + AO93JgDvdyYA73cmAO93JgDvdyYA73cmAO93JgDvdyYA73cmAO93JgDvdyYA73cmAO93JgDvdyYA73cm + AO93JgDvdyYA73cmAO93JgDvdyYA73cmAO93JgDvdyYA73cmAO93JgDvdyYA73cmAO93JgDvdyYA73cm + AO91JgD1eCQA33koAN94JwD4dyQA+X0nAEEAAAAAAAAAAAAAAAB5JwCqeScA/3UlAO53JwDvdycA73cn + AO93JwDvdycA73cnAO93JwDvdycA73cnAO93JwDvdycA73cnAO93JwDveCQA8nYkAPl5JAA/AAAAAAAA + AAAAAAAAeiYAcHooAP93JwDvdycA73cnAO93JwDvdycA73cnAO93JwDvdycA73cnAO93JwDvdycA73cn + AO93JwDvdycA73cnAO93JwDvdycA73cnAO93JwDvdycA73cnAO93JwDvdycA73cnAO93JwDvdycA73cn + AO93JwDvdycA73cnAO93JwDvdiYA9XkoAN9+JwDegSgA/3wmAKYAAAAAAAAAAAAAAAB9KQBPeicA/X4m + APB+JQDufiUA7n4lAO5+JQDufiUA7n4lAO5+JQDufiUA7n4lAO5+JQDufiUA7n4lAO5+JQDufiUA7nwk + AO19JgD8fCcAw5EkAAcAAAAAAAAAAH8qABJ7JgDbfiYA9n4lAO5+JQDufiUA7n4lAO5+JQDufiUA7n4l + AO5+JQDufiUA7n4lAO5+JQDufiUA7n4lAO5+JQDufiUA7n4lAO5+JQDufiUA7n4lAO5+JQDufiUA7n4l + AO5+JQDufiUA7n4lAO5+JQDufiUA7n4lAO5+JQDufiUA7n4kAPR+JwDefycA4n8qAPiCKQAxAAAAAAAA + AAB/MwAKfywAynwoAPt/JwDufycA7n8nAO5/JwDufycA7n8nAO5/JwDufycA7n8nAO5/JwDufycA7n8n + AO5/JwDufycA7n8nAO5/JwDufycA7oAqAP9+KwBjAAAAAAAAAAAAAAAAgCwAfYErAP9/JwDufycA7n8n + AO5/JwDufycA7n8nAO5/JwDufycA7n8nAO5/JwDufycA7n8nAO5/JwDufycA7n8nAO5/JwDufycA7n8n + AO5/JwDufycA7n8nAO5/JwDufycA7n8nAO5/JwDufycA7n8nAO5/JwDufycA7n8nAO5/JwD0fykA3oAs + AO+BLgCxAAAAAAAAAAAAAAAAgC8AZ4EvAP9/LwDufy8A7n8vAO5/LwDufy8A7n8vAO5/LwDufy8A7n8v + AO5/LwDufy8A7n8vAO5/LwDufy8A7n8vAO5/LwDufy8A7n8vAO6ALwD5fy4A0H8qAAwAAAAAAAAAAIMr + AB1/LQDmfy8A9H8vAO5/LwDufy8A7n8vAO5/LwDufy8A7n8vAO5/LwDufy8A7n8vAO5/LwDufy8A7n8v + AO5/LwDufy8A7n8vAO5/LwDufy8A7n8vAO5/LwDufy8A7n8vAO5/LwDufy8A7n8vAO5/LwDufy8A7n8v + AO5/LwDufy8A9H8vAN6ALQDqgzEASAAAAAAAAAAAiy4AC4IvAM1/LwD4gC4A7IAuAOyALgDsgC4A7IAu + AOyALgDsgC4A7IAuAOyALgDsgC4A7IAuAOyALgDsgC4A7IAuAOyALgDsgC4A7IAuAOyALgDsgC4A7IEv + AP6ELwBgAAAAAAAAAAAAAAAAgy4Ak4MwAP9/LgDsgC4A7IAuAOyALgDsgC4A7IAuAOyCLADvgC0A9oAv + APiCLwD3gC8A8oIvAO2ALgDsgC4A7IAuAOyALgDsgC4A7IAuAOyALgDsgC4A7IAuAOyALgDsgC4A7IAu + AOyALgDsgC4A7IAuAOyALgDsgC4A7IAvAPKCLwDdhjMAn38/AAQAAAAAAAAAAIc0AGuONQD/hzAA74Ut + AOuHLgDshy4A7IcuAOyHLgDshy4A7IcuAOyHLgDshy4A7IcuAOyHLgDshy4A7IcuAOyHLgDshy4A7Icu + AOyHLgDshy4A7IcuAOyFMAD4hjIAxX8qAAYAAAAAAAAAAIcyADOGLwDxhzAA74cuAOyHLgDshS0A64Uw + APKHMQD9hjEA7YQxAM6GMQC+hTIAxYYxAN6GLgD7hDAA+IcuAOyHLgDshy4A7IcuAOyHLgDshy4A7Icu + AOyHLgDshy4A7IcuAOyHLgDshy4A7IcuAOyHLgDshy4A7IcuAOyELwDyhC8A3ZE2AA4AAAAAAAAAAAAA + AACINAA6hzIAooYyAPKKMwD3hzYA64k2AOyJNgDsiTYA7Ik2AOyJNgDsiTYA7Ik2AOyJNgDsiTYA7Ik2 + AOyJNgDsiTYA7Ik2AOyJNgDsiTYA7Ik2AOyJNgDshzMA7YgzAPuHNgBPAAAAAAAAAAAAAAAAhzYAs4c2 + APqHNgDriTYA7IczAPyKNQDhiDYBg4k1CTSZMwAKAAAAAKpVAAOEOAAbijYAXog1AMSJNQD9ijYA8Ic2 + AOuJNgDsiTYA7Ik2AOyJNgDsiTYA7Ik2AOyJNgDsiTYA7Ik2AOyJNgDsiTYA7Ik2AOyJNgDshjMA8ok2 + AN0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACKOABEiTYD14o1APuKNgDqhzgA64c4AOuHOADrhzgA64c4 + AOuHOADrhzgA64c4AOuHOADrhzgA64c4AOuHOADrhzgA64c4AOuHOADrhzgA64c4AOuIOAD6jDYAsgAA + AAAAAAAAAAAAAIs3AFiINwD6hzkA7Yc4AP6KNwCqijoAIwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAB/PwAIijcAe4c3APSKNgDzijYA6oc4AOuHOADrhzgA64c4AOuHOADrhzgA64c4AOuHOADrhzgA64c4 + AOuHOADrhzgA64g4APGHNgDcAAAAAAAAAAAAAAAAjjgARIUwABUAAAAAAAAAAI48HiKNOQDMjzcA+4w3 + AOqOOQDrjjkA6445AOuOOQDrjjkA6445AOuOOQDrjjkA6445AOuOOQDrjjkA6445AOuOOQDrjjkA6445 + AOuOOQDrjjYA7os4APGJNQA0AAAAAAAAAACIMwAPizkA1pI7AP+NOACQf38AAgAAAAAAAAAAfzMzCow7 + C0WPOgBpkDoCXIs5IB8AAAAAAAAAAAAAAACLNw9SjDkB7I45APSMNwDqjjkA6445AOuOOQDrjjkA6445 + AOuOOQDrjjkA6445AOuOOQDrjjkA6445AOuLOQDxjjcA3AAAAAAAAAAAkD4AJY88APKOOQDVjz4AOQAA + AAAAAAAAizkIH487AtKPOgD5jjcA6pA5AOuQOQDrkDkA65A5AOuQOQDrkDkA65A5AOuQOQDrkDkA65A5 + AOuQOQDrkDkA65A5AOuQOQDrkDkA6444AOqQOgD9jzsAkgAAAAAAAAAAAAAAAJE6AJWQPACqAAAAAAAA + AAAAAAAAjzsAUo48AsyQOwH2jTsA/o45APyQOwLkjzwAfpkzAAUAAAAAAAAAAJE8B0iQOwLwjToA8Y44 + AOqQOQDrkDkA65A5AOuQOQDrkDkA65A5AOuQOQDrkDkA65A5AOuQOQDrjToA8Y43ANwAAAAAAAAAAJI+ + AH+SPwD9kj8A+ZA8AOePPQA+AAAAAAAAAACWPwssjz8A5ZBAAPOQPwDpkz8A6pM/AOqTPwDqkz8A6pM/ + AOqTPwDqkz8A6pM/AOqTPwDqkz8A6pM/AOqTPwDqkz8A6pM/AOqTPwDqkj8A8ZM+At6UPx8YAAAAAAAA + AACRPxIckUgADgAAAAAAAAAAkj4AepI+APmQPAD3kkAA65M/AOqTPwDqkz8A8ZM/AP+RPwCxk0MAEwAA + AAAAAAAAkj8CYJE+APmSPwDtkz8A6pM/AOqTPwDqkz8A6pM/AOqTPwDqkz8A6pM/AOqTPwDqkz8A6pA9 + APCRPADbAAAAAJlEAA+WPgDUlkIA85dAAOmUQgD3lD8A4ZRBACsAAAAAAAAAAJNBAE6UQAD1k0IA7pZC + AOqWQgDqlkIA6pZCAOqWQgDqlkIA6pZCAOqWQgDqlkIA6pZCAOqWQgDqlkIA6pZCAOqWQgDqlkIA6pZC + AOqUPwH8l0AEagAAAAAAAAAAAAAAAAAAAAAAAAAAlUIAb5NBAP6WQgDvlkIA6pZCAOqWQgDqlkIA6pZC + AOqUQgDrlkIA/5ZBALeZTAAKAAAAAAAAAACUQQCQlkAA/ZZCAOqWQgDqlkIA6pZCAOqWQgDqlkIA6pZC + AOqWQgDqlkIA6pZCAOqUQADwlUIA3AAAAACWQQBdlEEA+ZNBAOmTQQDplUQA6JRBAPmVQwDImUQADwAA + AAAAAAAAl0MAgJRBAPyTQQDpk0EA6ZNBAOmTQQDpk0EA6ZNBAOmTQQDpk0EA6ZNBAOmTQQDpk0EA6ZNB + AOmTQQDpk0EA6ZNBAOmTQQDpk0EA9ZVEAL+ZZgAFAAAAAAAAAAAAAAAAmkEDQpZBAPGVQwDvlUQA6JNB + AOmTQQDpk0EA6ZNBAOmTQQDpk0EA6ZNBAOmURAD+lEIAmQAAAAAAAAAAiToADZZDAMiWQwD2lUQA6JNB + AOmTQQDpk0EA6ZNBAOmTQQDpk0EA6ZNBAOmTQQDplUMA75RDAN9/AAACl0YAuZZHAPSVRwDolUcA6JVH + AOiYRQDnlkQA/JlEAJkAAAAAAAAAAJlmAAWXRQC0mEMA+JhFAOeVRwDolUcA6JVHAOiVRwDolUcA6JVH + AOiVRwDolUcA6JVHAOiVRwDolUcA6JVHAOiVRwDolUcA6JhHAOmXRgD0m0MHSAAAAAAAAAAAnz8ACJlG + BcSWRwD3mEUA55VHAOiVRwDolUcA6JVHAOiVRwDolUcA6JVHAOiVRwDol0QA6plGAPuYRABoAAAAAAAA + AACcRQg+mUYB8JVGAOuVRgDolUcA6JVHAOiVRwDolUcA6JVHAOiVRwDolUYA6JZHAPSXRgDAnEoAPp1F + APKeRQDqnUgA6J1IAOidSADonUgA6J5JAOqaRQD5m0YAWgAAAAAAAAAAm0oAKZ1HAOWbRwDvnUgA6J1I + AOidSADonUgA6J1IAOidSADonUgA6J1IAOidSADonUgA6J1IAOidSADonUgA6J1IAOiaSADsnEUA7ptF + ADsAAAAAAAAAAKpVAAObRwGhnUUA+J1IAOidSADonUgA6J1IAOidSADonUgA6J1IAOidSADonUgA6J1I + AOiaRwDvnUcA6JxFACwAAAAAAAAAAJpIAIyaRQD8m0YA551IAOidSADonUgA6J1IAOidSADonUgA6J5I + AOidSAD6nEgAap5LAJ+fSgD4oEsA56BLAOegSwDnoEsA56BLAOecSwDnn0sA8J5JAN6fTwAgAAAAAAAA + AACeSgBqn0oA+p9IAOigSwDnoEsA56BLAOegSwDnoEsA56BLAOegSwDnoEsA56BLAOegSwDnoEsA56BL + AOecSwDnn0oA+59KAJAAAAAAAAAAAAAAAAAAAAAAoEoAQZ5JAPOdSgDpoEsA56BLAOegSwDnoEsA56BL + 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 + AOSuWQDkrlkA5K5ZAOSuWQDkrlkA5K5ZAOSuWQDkr1gA46xZAPWwWwC2qlUADAAAAAC2bW0HsFsAorBa + AP2vYAA9AAAAAAAAAAD/fwACsl8A1LFfAOmxXwDjsV8A47FfAOOxXwDjsV8A47FfAOOxXwDjsV8A47Ff + AOOxXwDjsV8A47FeAOOxXADys14Aza9gAC0AAAAAAAAAAAAAAAC1XwA7sl4KfLNeBYGzYBFK////AQAA + AAAAAAAAtkgAB7NfAJivXAD1r18A5LFfAOOxXwDjsV8A47JfAPa0XgB0AAAAAAAAAAAAAAAAtF4AZ7Je + APaxXwDjsV8A47FfAOOxXwDjsV8A47FfAOOxXwDjsV8A47FfAOOxXwDjsV8A47FfAOOxXwDjsV8A9rNe + AKW2bQAHAAAAAL9/AASxXQZSuVwACwAAAAAAAAAAf38AArRfANSzXwDpsl8A47JfAOOyXwDjsl8A47Jf + AOOyXwDjsl8A47JfAOOyXwDjsl8A47JfAOOyXwDjtF0A4rNdAPC2XQDatmEAUQAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAtV0AJrZhAK+1XQD1tV8A5LJfAOOyXwDjsl8A47JfAOO1XwDrtGAA1LFj + ABcAAAAAAAAAALZtAAe2YAC+s10A8LRdAOKyXwDjsl8A47JfAOOyXwDjsl8A47JfAOOyXwDjsl8A47Jf + AOOyXwDjsl8A47JfAOO2XQD1tF8Aq7xeABsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC5YQDUumIA6bph + AOO6YQDjumEA47phAOO6YQDjumEA47phAOO6YQDjumEA47phAOO6YQDjumEA47phAOO6ZADit2QA7Ldk + AO+4ZQOcuWYNN8xmAAUAAAAAAAAAAAAAAAC6ZxslumQEerdjANq2YgDzuWEA47lhAOO6YQDjumEA47ph + AOO6YQDjuWEA47hjAPa5YwCAAAAAAAAAAAAAAAAAuWQAQrdkAO+5ZADnuWEA47phAOO6YQDjumEA47ph + AOO6YQDjumEA47phAOO6YQDjumEA47phAOO5YQDjumEA47dhAPO5YgDXtmIAMQAAAAAAAAAAAAAAAH9/ + AAK5ZAAhumYA1LtjAOm6ZgDjumYA47pmAOO6ZgDjumYA47pmAOO6ZgDjumYA47pmAOO6ZgDjumYA47pm + AOO6ZgDjumYA47tlAOK7ZgDlumYA8rtjAea7ZgC9u2cAnrtkAJu8ZgCzvGUB3bliAPO8YwDpu2UA4rpm + AOO6ZgDjumYA47pmAOO6ZgDjumYA47xlAOK4ZgDot2IA4b1iACcAAAAAAAAAAAAAAAC5ZwCHuGcA97tl + AOK6ZgDjumYA47pmAOO6ZgDjumYA47pmAOO6ZgDjumYA47pmAOO6ZgDjumYA47tlAOK8ZwDwuWcAxsJh + ABUAAAAAAAAAAJlmZgW6ZwOoumUA1LxpANO9aADovWYA4r1mAOK9ZgDivWYA4r1mAOK9ZgDivWYA4r1m + AOK9ZgDivWYA4r1mAOK9ZgDivWYA4r1mAOK9ZgDivWYA4r1mAOK9ZgDlvWYA7LxmAPG8ZwDxu2YA7rxp + AOa9ZgDivWYA4r1mAOK9ZgDivWYA4r1mAOK9ZgDivWYA4r1mAOK9ZgDivmkA4btoAPK7aQCiAAAAAAAA + AAAAAAAAzGYACr1nALu7aADyvWkA4b1mAOK9ZgDivWYA4r1mAOK9ZgDivWYA4r1mAOK9ZgDivWYA4r1m + AOK9aADoumYA58FsADYAAAAAAAAAAAAAAAC9agdiumkB/r1oANm8awDTvmkA6L1sAOK9bADivWwA4r1s + AOK9bADivWwA4r1sAOK9bADivWwA4r1sAOK9bADivWwA4r1sAOK9bADivWwA4r1sAOK9bADivWwA4r1s + AOK9bADivWwA4r1sAOK9bADivWwA4r1sAOK9bADivWwA4r1sAOK9bADivWwA4r1sAOK9bADivWwA4r1s + AOK8agDjv2kA8b9sAFkAAAAAAAAAAAAAAADEaA0nv2wD2b1sAO6/agDhvWwA4r1sAOK9bADivWwA4r1s + AOK9bADivWwA4r1sAOK+bADlv2kA9L5sAGcAAAAAAAAAAAAAAAC8ZwAbvWsA1sBqAO+8awDTv28A0b5r + AObBbgDgwW4A4MFuAODBbgDgwW4A4MFuAODBbgDgwW4A4MFuAODBbgDgwW4A4MFuAODBbgDgwW4A4MFu + AODBbgDgwW4A4MFuAODBbgDgwW4A4MFuAODBbgDgwW4A4MFuAODBbgDgwW4A4MFuAODBbgDgwW4A4MFu + AODBbgDgwW4A4MFuAODBbgDgwW4A4MJrAOi/bQHZw2kHIgAAAAAAAAAAAAAAAMJsBDvAbADdwGsA7cJr + AN/BbgDgwW4A4MFuAODBbgDgwW4A4MFuAODBbADkv20A9cFtA4UAAAAAAAAAAAAAAAAAAAAAw24An8Bv + APG/bgDlv28A0chwANHGcQDmx28A4MdvAODHbwDgx28A4MdvAODHbwDgx28A4MdvAODHbwDgx28A4Mdv + AODHbwDgx28A4MdvAODHbwDgx28A4MdvAODHbwDgx28A4MdvAODHbwDgx28A4MdvAODHbwDgx28A4Mdv + AODHbwDgx28A4MdvAODHbwDgx28A4MdvAODHbwDgx28A4MdvAODEcADfxnAA78ZwALO/fwAIAAAAAAAA + AAAAAAAAx28AN8ZvAM7HcADzx20A5MdvAODHbwDgx28A4MdwAOHFcADsxXAA7sRxAH7/AP8BAAAAAAAA + AAAAAAAAxnAAZMNuAPDHcADhxm0A5shwANHJcQDRx3QA5sl0AODJdADgyXQA4Ml0AODJdADgyXQA4Ml0 + AODJdADgyXQA4Ml0AODJdADgyXQA4Ml0AODJdADgyXQA4Ml0AODJdADgyXQA4Ml0AODJdADgyXQA4Ml0 + AODJdADgyXQA4Ml0AODJdADgyXQA4Ml0AODJdADgyXQA4Ml0AODJdADgyXQA4Ml0AODJdADgyXQA4Ml0 + AODIdADzx3QBl/8AAAEAAAAAAAAAAAAAAADNdQAayHMAlsVxAOPIcgDyyXMA8clyAPLIcgDuyHMBwMZz + AE0AAAAAAAAAAAAAAAAAAAAAynQARMZzAObJcgDlyXQA4Md0AObJcQDRy3QA0MlyAOXLcwDfy3MA38tz + AN/LcwDfy3MA38tzAN/LcwDfy3MA38tzAN/LcwDfy3MA38tzAN/LcwDfy3MA38tzAN/LcwDfy3MA38tz + AN/LcwDfy3MA38tzAN/LcwDfy3MA38tzAN/LcwDfy3MA38tzAN/LcwDfy3MA38tzAN/LcwDfy3MA38tz + AN/LcwDfy3MA38tzAN/LcwDfyXQA4Mt1APHKdgCMAAAAAAAAAAAAAAAAAAAAAAAAAADKeQAsyXcAacp1 + AILKdwB1xnQDSNptJAcAAAAAAAAAAAAAAAAAAAAAx3IAPMpyANrLdADoy3UA3stzAN/JcgDly3QA0Mt5 + ANDJeQDly3kA38t5AN/LeQDfy3kA38t5AN/LeQDfy3kA38t5AN/LeQDfy3kA38t5AN/LeQDfy3kA38t5 + AN/LeQDfy3kA38t5AN/LeQDfy3kA38t5AN/LeQDfy3kA38t5AN/LeQDfy3kA38t5AN/LeQDfy3kA38t5 + AN/LeQDfy3kA38t5AN/LeQDfy3kA38t5AN/LeQDfy3kA38t5AN/JeQDhzHkA8Mp6AZbEdQANAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzXcATct3AN7KeQDpzHcA3st5 + AN/LeQDfyXkA5ct5ANDQegDQ0HoA5dB7AN/QewDf0HsA39B7AN/QewDf0HsA39B7AN/QewDf0HsA39B7 + AN/QewDf0HsA39B7AN/QewDf0HsA39B7AN/QewDf0HsA39B7AN/QewDf0HsA39B7AN/QewDf0HsA39B7 + AN/QewDf0HsA39B7AN/QewDf0HsA39B7AN/QewDf0HsA39B7AN/QewDf0HsA39B7AN/QewDf0XwA3tB4 + AODQewDw0HsAutB7ADwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADJeAATz3sAgs17 + AOjPegDn0XwA3tB7AN/QewDf0HsA39B6AOXQegDQ1H4A0NR+AOTUfgDe1H4A3tR+AN7UfgDe1H4A3tR+ + AN7UfgDe1H4A3tR+AN7UfgDe1H4A3tR+AN7UfgDe1H4A3tR+AN7UfgDe1H4A3tR+AN7UfgDe1H4A3tR+ + AN7UfgDe1H4A3tR+AN7UfgDe1H4A3tR+AN7UfgDe1H4A3tR+AN7UfgDe1H4A3tR+AN7UfgDe1H4A3tR+ + AN7UfgDe1H4A3tR+AN7UfgDe034A3tJ8AOvTfADj038AmNJ9AEXUfwASAAAAAAAAAAAAAAAAzGYABdeC + ACfSfQBu0n0AydN7AO/RfADh1HwA3dR+AN7UfgDe1H4A3tR+AN7UfgDk1H4A0NR/ANDUfwDk1H8A3tR/ + AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/ + AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/ + AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UgADd1YAA4dN/AO7UfwDo0n8AyNaA + AKnVgACf1IAAp9R/ALrUgADd1H8A7tF8AOfUfwDe1H8A3tR/AN7UfwDe1H8A3tR/AN7UfwDe1H8A5NR/ + ANDXggDP1oMA49aDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daD + AN3WgwDd1oMA3daDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daD + AN3WgwDd1oMA3daDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daD + AN3WgwDd2IMA39mDAOXWgQDq2YAA7NmDAOvYgQDo2IMA4daDAN3WgwDd1oMA3daDAN3WgwDd1oMA3daD + AN3WgwDd1oMA3daDAOPXggDP3IQAzt2GAOLdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2G + ANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2G + ANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDc3YYA3N2G + ANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzchgDc3IYA3NyGANzchgDc3IYA3N2GANzdhgDc3YYA3N2G + ANzdhgDc3YYA3N2GANzdhgDc3YYA3N2GANzdhgDi3IQAzt2EAM7ehwDi3oYA3N6GANzehgDc3oYA3N6G + ANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6G + ANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6G + ANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6G + ANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3oYA3N6GANzehgDc3ocA4t2EAM7diQDO34gA4t6L + ANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6L + ANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6L + ANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6L + ANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N6LANzeiwDc3osA3N+I + AOLdiQDO4owAzeGMAOHkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SO + ANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SO + ANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SO + ANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SOANvkjgDb5I4A2+SO + ANvkjgDb5I4A2+SOANvhjADh4owAzeaRAM3mkQDh5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aR + ANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aR + ANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aR + ANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA2+aR + ANvmkQDb5pEA2+aRANvmkQDb5pEA2+aRANvmkQDb5pEA4eaRAM3okwDM6JAA4OaTANrmkwDa5pMA2uaT + ANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaT + ANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaT + ANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaT + ANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uaTANrmkwDa5pMA2uiQAODokwDM65cA0eyT + AObqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqW + AODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqW + AODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqW + AODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqWAODqlgDg6pYA4OqW + AODskwDm65cA0fCaAL7rmADR7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2a + AMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2a + AMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2a + AMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2aAMvtmgDL7ZoAy+2a + AMvtmgDL7ZoAy+2aAMvtmgDL65gA0fCaAL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAD/gAAAAAAAA//gAAAAAAAHwfAAAA + AAAA8AeAAAAAAAHgA8AAAAAAA4AB4AAAAAADgADgAAAAAAcAAHAAAAAABgAAcAAAAAAOAAA4AAAAABwA + ABgAAAAAGAAAHAAAAAA4AAAMAAAAADAAAA4AAAAAMAAABgAAAABwAAAHAEAAAPwAAAcD+AAA5gAAAwYO + AADDAAADnAMAAMGAAAGYAYAAgMAAAfAAwACAYAAA4ADAAABgAADAAGAAADAAAMAAMAAAGAAB4AAQAAAY + AAHgABgBAAwAAzAADAEABgAHMAAEAQAGAAY4AAYDAAMADBgAAwMAAYAYHAABhwAAwDAMAACGAABwYA4A + AEYAAD/ABgAAPwAABwAHAAAcAAAAAAOAABgAAAAAA4AAOAAAAAABwABwAAAAAADgAPAAAAAAAHAA4AAA + AAAAOAPAAAAAAAA+B4AAAAAAAA//AAAAAAAAB/wAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + wwAADsMBx2+oZAAAAPhJREFUSEu1kNERwjAMQzMOn+0OjNVlmIgNgG/YgdQyMcSJyjUh5O7dNbIqtQ4x + xr9CxZFQcSRUHAkVDTlH4cBmADN42MygIpCzCE/hzOYAs+RZ2Bxw8ROOy5V5AGbJs1lSC69wPBh7Coyq + xF/8lxstBdWf5GYWDloKgCsxY7mWnNYCQ0twtr7c6C3QPxG+hoPeAoDscM8Exi8FyA5zemAG0FuAzNmM + k/AQShPoKUDWpJ7MjBL2J60FyNBw9RQvsHW1FOhanCe/qFCva2/Bey3OUwoq+nVdmAdgljxuLc7DRCAH + 67oJJzYHmCWPW0sOFUdCxZFQcRwxrOuq/3kR1YvqAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAA3 + XAAAN1wBy8ekuQAAAcBJREFUSEu1lr9KA0EQxjdHIoiIiI2VjYVY2IlIGrEQEcR3EJsUwc4TCQELS0FE + RNJIChGOICKCiC8gwQe6Luc3cfacndtc/pwu/Mjt3Ow3t5PZuTNhGA4ljuMpY8wxOGVqsAU+X43XqMFY + A1+SUqm06PPVZAxJksxDYFPaMA6ssGBD+iDgVqVSmZY2wpmweMQCTVqAVJRxfcY2ST9N+J0Dl2xrBUEw + IzW1+CM7WjrgVdkkT0Dfb8mdpAGwxX3lWIQ0fWmA/sSYG+E0KeeOppz0er0FOLyrBePQGfgfEFzvRQJE + +nyQaBn5X6Yyg8OJWiDpgjZ44GufD1EDVbDEVZYravkE1fSpfs5FXhDLITBNYRjErdw2B7HnJY86+P8A + 1Lx8NyWUot/aNmYXjJKiI1s5q2AH+FqChYLcgXuQJ05PvQ1WqICcbdMRx40PdpyETqZM5YT70ZtaNA6R + 7qhOAIwr4TwpDUdTiO8Jp6KsZwKod4HlGeS1jhegU9qW/SgNQHCzs0EuyJGrrME2SZ2qhB/smm3USmal + phOAoAXUl6QNY+grE4PK3BHv27XBB8bfvfR98PmgpkipIig9I3y2hOYbflY6gOGbmaUAAAAASUVORK5C + YII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAABE + IAAARCABv5pDRgAAAY9JREFUSEu1lj9KxFAQh19gRQgKXsJO7QQVLBQRERHWI1hYiScQ0Uqw8CA2oqCi + NsmhUob4TXiJ85JJ3OyuAx+Z92fmtzObl8QlSfKv1E6aplGe58t6sY84jhclxlrT1E4URQfOuXcY6w0W + 2CY8wbm1rvl1nFuFF/iCM71Jg23DG3zDnbVHEw6cW4dKpFUJtgNSpSQfLlBOdIhgu6CTTycg8H+sEVy3 + C/bgA3Ty6QUETFfyCc3kwwX45UsEXcEF/oiriLyClVwYLLBVBePfZlm2gN8nMkwAk1tQJ7gRkaIoNvCl + XXpNmFmgrETa5UWalcwuIPS0az4CHqtd9zreIhz0C1jtMk+8JhgQvCJJCHrwPPokgUijXeVh1Hk05qQG + G/skuppmuzoraU1YYKc+SVCJtAtfn/j2A7I50QV2DMEjA4FLWeMaPLuCOD34CxIdkUCL1LcpZlYSJJgE + 7BAqkeAcYLUIP+aknNMbJgXbB3mrtV6Zvl3PXK/Lvc0Nk0ICuaVH1pp8PMhHgfitxfmSuB+m6Lf0bhB1 + xAAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAA3 + XAAAN1wBy8ekuQAAAGhJREFUSEvtlbEKwDAIRM89X5ipn+qftQYyKBUsrdLFwEM89C5TAmYuxRUzccVM + TENEA8CUerxh7w7taQLWgHB+ZBpP3exbeEuPWR7aswNudEBIB4R0QMi/AXLKn+vaD6cCV8zEFfNgXD54 + TuKdeifcAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAA + TgAAAE4Bsc0fMwAAAXxJREFUSEullEFKw0AUhichImStSG8gCCIewIV4gd7BhV30EopLPYAbF9IzdBsE + u+lK11IPoGA3AXET/xfexJfJm8mkffCVmTfz/3+YSWqKotiIPM93jTHzqqqOtXWL2owhSZJLBFTgMxSi + NmNAzTggGNJpxOIEeENakyGgboW5N6QligU1Br9sGgzpiPtAhcwtTYhq4gMVY26pQ1QjDdQQc8u8ZYLE + EZrXYAFWYAnuwAT0mdM6XTy9XTP6TuqP0ZqjcYGFNdDEfZD5WD6spRng6fex6U2IYvGaE63JBiFBc6LT + GBDSa06oTdzHHsSvwkxjomld1CZBBsJM417TuehNY87ADxv5WGpal04Dx3MI8Reb0DlPgXZcK1er0Zrw + Bb+zwTc4pz7fiXvxC6n10QzKstyB6JnFH2maHsmNytt1I9d9/A+MeWDhS5ZlB3KTRYSsMR5pe1zqHxzB + FZs/0v+Hu0nCIfXRxUDmJxDQeU+1DdtC9YSnOtUWt6cwf9hd9nVpKvmOAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyDevice.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyDevice.cs new file mode 100644 index 0000000..a7fd471 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyDevice.cs @@ -0,0 +1,1060 @@ +using SDRSharp.Common; +using SDRSharp.Radio; +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; + +namespace SDRSharp.FrontEnds.Airspy +{ + public class AirspyDevice : IDisposable + { + private enum CalibrationState + { + UnCalibrated, + PrologSent, + EpilogueSent + } + + private class AnalogFilterConfig + { + public byte LPF + { + get; + set; + } + + public byte HPF + { + get; + set; + } + + public int Shift + { + get; + set; + } + } + + private class AnalogFilterSet + { + public uint SampleRate + { + get; + set; + } + + public AnalogFilterConfig[] Filters + { + get; + set; + } + } + + public const float TimeConst = 0.05f; + + public const uint DefaultFrequency = 103000000u; + + public const uint DefaultSpyVerterLO = 120000000u; + + public const uint DefaultSpyVerterThreshold = 35000000u; + + public const uint CalibrationDelay = 500u; + + public const uint CalibrationDuration = 100u; + + public const string DeviceName = "AIRSPY"; + + private static readonly AnalogFilterSet[] _analogDecimationFilters = new AnalogFilterSet[4] + { + new AnalogFilterSet + { + SampleRate = 10000000u, + Filters = new AnalogFilterConfig[6] + { + new AnalogFilterConfig + { + LPF = 60, + HPF = 2, + Shift = 0 + }, + new AnalogFilterConfig + { + LPF = 38, + HPF = 7, + Shift = 1250000 + }, + new AnalogFilterConfig + { + LPF = 28, + HPF = 4, + Shift = 2750000 + }, + new AnalogFilterConfig + { + LPF = 15, + HPF = 5, + Shift = 3080000 + }, + new AnalogFilterConfig + { + LPF = 6, + HPF = 5, + Shift = 3200000 + }, + new AnalogFilterConfig + { + LPF = 2, + HPF = 6, + Shift = 3250000 + } + } + }, + new AnalogFilterSet + { + SampleRate = 2500000u, + Filters = new AnalogFilterConfig[4] + { + new AnalogFilterConfig + { + LPF = 4, + HPF = 0, + Shift = 0 + }, + new AnalogFilterConfig + { + LPF = 8, + HPF = 3, + Shift = -280000 + }, + new AnalogFilterConfig + { + LPF = 5, + HPF = 5, + Shift = -500000 + }, + new AnalogFilterConfig + { + LPF = 3, + HPF = 6, + Shift = -550000 + } + } + }, + new AnalogFilterSet + { + SampleRate = 6000000u, + Filters = new AnalogFilterConfig[5] + { + new AnalogFilterConfig + { + LPF = 33, + HPF = 2, + Shift = 0 + }, + new AnalogFilterConfig + { + LPF = 26, + HPF = 2, + Shift = 1000000 + }, + new AnalogFilterConfig + { + LPF = 17, + HPF = 4, + Shift = 1100000 + }, + new AnalogFilterConfig + { + LPF = 7, + HPF = 5, + Shift = 1200000 + }, + new AnalogFilterConfig + { + LPF = 2, + HPF = 6, + Shift = 1250000 + } + } + }, + new AnalogFilterSet + { + SampleRate = 3000000u, + Filters = new AnalogFilterConfig[3] + { + new AnalogFilterConfig + { + LPF = 8, + HPF = 0, + Shift = 0 + }, + new AnalogFilterConfig + { + LPF = 7, + HPF = 4, + Shift = -250000 + }, + new AnalogFilterConfig + { + LPF = 2, + HPF = 4, + Shift = -300000 + } + } + } + }; + + private IntPtr _dev; + + private uint _sampleRate; + + private uint _centerFrequency; + + private uint _frequencySet; + + private int _decimationStages; + + private byte _vgaGain; + + private byte _mixerGain; + + private byte _lnaGain; + + private byte _linearityGain; + + private byte _sensitivityGain; + + private bool _isStreaming; + + private bool _lnaGainAuto; + + private bool _mixerGainAuto; + + private bool _biasTeeEnabled; + + private bool _biasTeeState; + + private bool _spyVerterEnabled; + + private bool _usePacking; + + private bool _bypassTrackingFilter; + + private bool _bypassTrackingFilterState; + + private uint[] _supportedSampleRates; + + private float _spyVerterPPM; + + private float _iavg; + + private float _qavg; + + private float _alpha; + + private byte _old_0x0f_value; + + private byte _old_0x0b_value; + + private CalibrationState _calibrationState; + + private Timer _calibrationTimer; + + private AnalogFilterConfig _analogFilterConfig; + + private DownConverter _ddc; + + private AirspyGainMode _gainMode; + + private GCHandle _gcHandle; + + private bool _useDynamicRangeEnhancements = Utils.GetBooleanSetting("airspy.useDynamicRangeEnhancements", true); + + private unsafe static readonly airspy_sample_block_cb_fn _airspyCallback = AirspyDevice.AirSpySamplesAvailable; + + public uint[] SupportedSampleRates + { + get + { + return this._supportedSampleRates; + } + } + + public uint SampleRate + { + get + { + return this._sampleRate; + } + set + { + if (value != this._sampleRate) + { + if (NativeMethods.airspy_set_samplerate(this._dev, value) != 0) + { + throw new ApplicationException("Sample rate is not supported"); + } + this._sampleRate = value; + this.OnSampleRateChanged(); + } + } + } + + public bool UseDynamicRangeEnhancements + { + get + { + return this._useDynamicRangeEnhancements; + } + set + { + this._useDynamicRangeEnhancements = value; + } + } + + public uint DecimatedSampleRate + { + get + { + return this._sampleRate >> this._decimationStages; + } + } + + public bool UsePacking + { + get + { + return this._usePacking; + } + set + { + this._usePacking = value; + NativeMethods.airspy_set_packing(this._dev, this._usePacking); + } + } + + public uint Frequency + { + get + { + return this._centerFrequency; + } + set + { + this._centerFrequency = value; + this.UpdateFrequency(); + } + } + + public byte VgaGain + { + get + { + return this._vgaGain; + } + set + { + this._vgaGain = value; + this.UpdateGains(); + } + } + + public byte MixerGain + { + get + { + return this._mixerGain; + } + set + { + this._mixerGain = value; + this.UpdateGains(); + } + } + + public byte LnaGain + { + get + { + return this._lnaGain; + } + set + { + this._lnaGain = value; + this.UpdateGains(); + } + } + + public bool MixerGainAuto + { + get + { + return this._mixerGainAuto; + } + set + { + this._mixerGainAuto = value; + NativeMethods.airspy_set_mixer_agc(this._dev, value); + } + } + + public bool LnaGainAuto + { + get + { + return this._lnaGainAuto; + } + set + { + this._lnaGainAuto = value; + NativeMethods.airspy_set_lna_agc(this._dev, value); + } + } + + public byte LinearityGain + { + get + { + return this._linearityGain; + } + set + { + this._linearityGain = value; + this.UpdateGains(); + } + } + + public byte SensitivityGain + { + get + { + return this._sensitivityGain; + } + set + { + this._sensitivityGain = value; + this.UpdateGains(); + } + } + + public AirspyGainMode GainMode + { + get + { + return this._gainMode; + } + set + { + this._gainMode = value; + this.UpdateGains(); + } + } + + public int DecimationStages + { + get + { + return this._decimationStages; + } + set + { + if (this._decimationStages != value) + { + this._decimationStages = value; + this._alpha = (float)(1.0 - Math.Exp(-1.0 / (double)((float)(double)this.DecimatedSampleRate * 0.05f))); + this.OnSampleRateChanged(); + } + } + } + + public bool BiasTeeEnabled + { + get + { + return this._biasTeeEnabled; + } + set + { + this._biasTeeEnabled = value; + this.UpdateFrequency(); + } + } + + public bool BypassTrackingFilter + { + get + { + return this._bypassTrackingFilter; + } + set + { + this._bypassTrackingFilter = value; + this.UpdateTrackingFilter(); + } + } + + public bool SpyVerterEnabled + { + get + { + return this._spyVerterEnabled; + } + set + { + this._spyVerterEnabled = value; + this.UpdateFrequency(); + } + } + + public float SpyVerterPPM + { + get + { + return this._spyVerterPPM; + } + set + { + this._spyVerterPPM = value; + this.UpdateFrequency(); + } + } + + public bool IsStreaming + { + get + { + return this._isStreaming; + } + } + + public bool IsHung + { + get + { + if (this._isStreaming) + { + return NativeMethods.airspy_is_streaming(this._dev) != airspy_error.AIRSPY_TRUE; + } + return false; + } + } + + public event SamplesAvailableDelegate ComplexSamplesAvailable; + + public event SamplesAvailableDelegate RealSamplesAvailable; + + public event EventHandler SampleRateChanged; + + public unsafe AirspyDevice(bool useRealSamples = false) + { + if (NativeMethods.airspy_open(out this._dev) != 0) + { + throw new ApplicationException("Cannot open AirSpy device"); + } + if (useRealSamples) + { + NativeMethods.airspy_set_sample_type(this._dev, airspy_sample_type.AIRSPY_SAMPLE_FLOAT32_REAL); + } + else + { + NativeMethods.airspy_set_sample_type(this._dev, airspy_sample_type.AIRSPY_SAMPLE_FLOAT32_IQ); + } + uint num = default(uint); + NativeMethods.airspy_get_samplerates(this._dev, &num, 0u); + this._supportedSampleRates = new uint[num]; + uint[] supportedSampleRates = this._supportedSampleRates; + fixed (uint* buffer = supportedSampleRates) + { + NativeMethods.airspy_get_samplerates(this._dev, buffer, num); + } + this._sampleRate = this._supportedSampleRates[0]; + this._alpha = (float)(1.0 - Math.Exp(-1.0 / (double)((float)(double)this.DecimatedSampleRate * 0.05f))); + NativeMethods.airspy_set_samplerate(this._dev, this._sampleRate); + NativeMethods.airspy_set_rf_bias(this._dev, false); + NativeMethods.airspy_set_packing(this._dev, false); + this.UpdateGains(); + this._calibrationTimer = new Timer(this.CalibrationHandler, null, 500L, -1L); + this._gcHandle = GCHandle.Alloc(this); + } + + ~AirspyDevice() + { + this.Dispose(); + } + + public void Dispose() + { + if (this._dev != IntPtr.Zero) + { + try + { + this.Stop(); + NativeMethods.airspy_close(this._dev); + } + catch (AccessViolationException) + { + } + if (this._gcHandle.IsAllocated) + { + this._gcHandle.Free(); + } + this._dev = IntPtr.Zero; + GC.SuppressFinalize(this); + } + } + + private void SendCalibrationProlog() + { + if (this._calibrationState == CalibrationState.UnCalibrated) + { + airspy_error airspy_error = NativeMethods.airspy_r820t_read(this._dev, (byte)15, out this._old_0x0f_value); + if (airspy_error >= airspy_error.AIRSPY_SUCCESS) + { + airspy_error = NativeMethods.airspy_r820t_read(this._dev, (byte)11, out this._old_0x0b_value); + if (airspy_error >= airspy_error.AIRSPY_SUCCESS) + { + NativeMethods.airspy_r820t_write(this._dev, 15, (byte)((this._old_0x0f_value & -5) | 4)); + NativeMethods.airspy_r820t_write(this._dev, 11, (byte)((this._old_0x0b_value & -17) | 0x10)); + this._calibrationState = CalibrationState.PrologSent; + } + } + } + } + + private void SendCalibrationEpilogue() + { + if (this._calibrationState == CalibrationState.PrologSent) + { + NativeMethods.airspy_r820t_write(this._dev, 11, this._old_0x0b_value); + NativeMethods.airspy_r820t_write(this._dev, 15, this._old_0x0f_value); + this._old_0x0b_value = 0; + this._old_0x0f_value = 0; + this._calibrationState = CalibrationState.EpilogueSent; + } + } + + private void AbortCalibration() + { + if (this._calibrationState == CalibrationState.PrologSent) + { + this.SendCalibrationEpilogue(); + } + this._calibrationState = CalibrationState.UnCalibrated; + } + + public void CalibrateIF() + { + lock (this) + { + this.AbortCalibration(); + this._calibrationTimer.Change(500L, -1L); + } + } + + private void CalibrationHandler(object state) + { + if (this._isStreaming) + { + lock (this) + { + switch (this._calibrationState) + { + case CalibrationState.UnCalibrated: + this.SendCalibrationProlog(); + this._calibrationTimer.Change(100L, -1L); + break; + case CalibrationState.PrologSent: + this.SendCalibrationEpilogue(); + break; + } + } + } + } + + public unsafe void Start() + { + if (!this._isStreaming) + { + this._iavg = 0f; + this._qavg = 0f; + int num = (!this._useDynamicRangeEnhancements) ? Math.Min(this._decimationStages, ConversionFilters.FirKernels100dB.Length - 1) : 0; + float[] array = ConversionFilters.FirKernels100dB[num]; + float[] array2 = array; + fixed (float* kernel = array2) + { + NativeMethods.airspy_set_conversion_filter_float32(this._dev, kernel, array.Length); + } + if (NativeMethods.airspy_start_rx(this._dev, AirspyDevice._airspyCallback, (IntPtr)this._gcHandle) != 0) + { + throw new ApplicationException("airspy_start_rx() error"); + } + this.UpdateTrackingFilter(); + this.UpdateAnalogIFFilters(); + this._isStreaming = true; + } + } + + public void Stop() + { + if (this._isStreaming) + { + NativeMethods.airspy_stop_rx(this._dev); + this._isStreaming = false; + } + } + + private void UpdateGains() + { + switch (this._gainMode) + { + case AirspyGainMode.Custom: + NativeMethods.airspy_set_lna_gain(this._dev, this._lnaGain); + NativeMethods.airspy_set_mixer_gain(this._dev, this._mixerGain); + NativeMethods.airspy_set_vga_gain(this._dev, this._vgaGain); + NativeMethods.airspy_set_lna_agc(this._dev, this._lnaGainAuto); + NativeMethods.airspy_set_mixer_agc(this._dev, this._mixerGainAuto); + break; + case AirspyGainMode.Linearity: + NativeMethods.airspy_set_linearity_gain(this._dev, this._linearityGain); + break; + case AirspyGainMode.Sensitivity: + NativeMethods.airspy_set_sensitivity_gain(this._dev, this._sensitivityGain); + break; + } + } + + private void UpdateFrequency() + { + uint num = this._centerFrequency; + if (this._spyVerterEnabled && num < 35000000) + { + num += (uint)(120000000.0 * (1.0 + (double)this._spyVerterPPM * 1E-06)); + if (!this._biasTeeState) + { + NativeMethods.airspy_set_rf_bias(this._dev, true); + this._biasTeeState = true; + } + } + else if (this._biasTeeState != this._biasTeeEnabled) + { + NativeMethods.airspy_set_rf_bias(this._dev, this._biasTeeEnabled); + this._biasTeeState = this._biasTeeEnabled; + } + if (this._analogFilterConfig != null) + { + num = (uint)((int)num - this._analogFilterConfig.Shift); + } + if (this._frequencySet != num) + { + this._frequencySet = num; + this.SetDeviceCenterFrequency(); + this._bypassTrackingFilterState = false; + this.UpdateTrackingFilter(); + } + } + + private void UpdateTrackingFilter() + { + if (this._bypassTrackingFilter) + { + if (!this._bypassTrackingFilterState) + { + byte b; + NativeMethods.airspy_r820t_read(this._dev, (byte)26, out b); + b = (byte)((b & 0x3F) | 0x40); + NativeMethods.airspy_r820t_write(this._dev, 26, b); + this._bypassTrackingFilterState = true; + } + } + else if (this._bypassTrackingFilterState) + { + this.SetDeviceCenterFrequency(); + this._bypassTrackingFilterState = false; + } + } + + private void SetDeviceCenterFrequency() + { + lock (this) + { + this.AbortCalibration(); + NativeMethods.airspy_set_freq(this._dev, this._frequencySet); + this.CalibrateIF(); + } + } + + private void UpdateAnalogIFFilters() + { + this._analogFilterConfig = null; + if (this._useDynamicRangeEnhancements) + { + AnalogFilterSet analogFilterSet = Array.Find(AirspyDevice._analogDecimationFilters, (AnalogFilterSet item) => item.SampleRate == this._sampleRate); + if (analogFilterSet != null) + { + int num = Math.Min(this._decimationStages, analogFilterSet.Filters.Length - 1); + this._analogFilterConfig = analogFilterSet.Filters[num]; + this.SetAnalogIFFilters(this._analogFilterConfig.LPF, this._analogFilterConfig.HPF); + } + } + } + + private void UpdateDDC() + { + int num = 1 << this._decimationStages; + if (this._ddc != null && this._ddc.DecimationRatio == num && this._ddc.SampleRate == (double)this._sampleRate) + { + return; + } + this._ddc = new DownConverter((double)this._sampleRate, num); + AnalogFilterConfig analogFilterConfig = this._analogFilterConfig; + if (analogFilterConfig != null) + { + this._ddc.Frequency = (double)analogFilterConfig.Shift; + } + } + + public virtual void OnSampleRateChanged() + { + this._alpha = (float)(1.0 - Math.Exp(-1.0 / (double)((float)(double)this.DecimatedSampleRate * 0.05f))); + this.UpdateAnalogIFFilters(); + EventHandler sampleRateChanged = this.SampleRateChanged; + if (sampleRateChanged != null) + { + sampleRateChanged(this, EventArgs.Empty); + } + } + + protected unsafe virtual void OnComplexSamplesAvailable(Complex* buffer, int length, ulong droppedSamples) + { + SamplesAvailableDelegate complexSamplesAvailable = this.ComplexSamplesAvailable; + if (complexSamplesAvailable != null) + { + ComplexSamplesEventArgs complexSamplesEventArgs = new ComplexSamplesEventArgs(); + complexSamplesEventArgs.Buffer = buffer; + complexSamplesEventArgs.Length = length; + complexSamplesEventArgs.DroppedSamples = droppedSamples; + complexSamplesAvailable(this, complexSamplesEventArgs); + } + } + + protected unsafe virtual void OnRealSamplesAvailable(float* buffer, int length, ulong droppedSamples) + { + SamplesAvailableDelegate realSamplesAvailable = this.RealSamplesAvailable; + if (realSamplesAvailable != null) + { + RealSamplesEventArgs realSamplesEventArgs = new RealSamplesEventArgs(); + realSamplesEventArgs.Buffer = buffer; + realSamplesEventArgs.Length = length; + realSamplesEventArgs.DroppedSamples = droppedSamples; + realSamplesAvailable(this, realSamplesEventArgs); + } + } + + private unsafe static int AirSpySamplesAvailable(airspy_transfer* data) + { + int num = data->sample_count; + ulong dropped_samples = data->dropped_samples; + IntPtr ctx = data->ctx; + GCHandle gCHandle = GCHandle.FromIntPtr(ctx); + if (!gCHandle.IsAllocated) + { + return -1; + } + AirspyDevice airspyDevice = (AirspyDevice)gCHandle.Target; + if (data->sample_type == airspy_sample_type.AIRSPY_SAMPLE_FLOAT32_REAL) + { + float* samples = (float*)data->samples; + airspyDevice.OnRealSamplesAvailable(samples, num, dropped_samples); + } + else + { + Complex* samples2 = (Complex*)data->samples; + bool flag = airspyDevice._analogFilterConfig != null && airspyDevice._analogFilterConfig.Shift != 0; + if (airspyDevice._decimationStages > 0) + { + airspyDevice.UpdateDDC(); + num = airspyDevice._ddc.Process(samples2, num); + } + if (!flag) + { + float num2 = airspyDevice._iavg; + float num3 = airspyDevice._qavg; + float alpha = airspyDevice._alpha; + for (int i = 0; i < num; i++) + { + num2 += alpha * (samples2[i].Real - num2); + num3 += alpha * (samples2[i].Imag - num3); + samples2[i].Real -= num2; + samples2[i].Imag -= num3; + } + airspyDevice._iavg = num2; + airspyDevice._qavg = num3; + } + airspyDevice.OnComplexSamplesAvailable(samples2, num, dropped_samples); + } + return 0; + } + + public void Dump(string baseFileName = "") + { + string str = "airspy_dump_" + DateTime.Now.ToString("yyyy_MM_dd__hh_mm_ss__"); + this.DumpFile(268435456, 131072, Path.Combine(baseFileName, str + "local_sram0_128K.bin")); + this.DumpFile(268959744, 73728, Path.Combine(baseFileName, str + "local_sram1_72K.bin")); + this.DumpFile(402653184, 18432, Path.Combine(baseFileName, str + "m0sub_sram_18K.bin")); + this.DumpFile(536870912, 32768, Path.Combine(baseFileName, str + "ahb1_sram_32K.bin")); + this.DumpFile(671088640, 32768, Path.Combine(baseFileName, str + "ahb2_sram_32K.bin")); + this.DumpFile(1074724884, 812, Path.Combine(baseFileName, str + "periph_adchs.bin")); + this.DumpFile(1074728716, 4, Path.Combine(baseFileName, str + "periph_adchs_status0.bin")); + this.DumpFile(1074728748, 4, Path.Combine(baseFileName, str + "periph_adchs_status1.bin")); + this.DumpFile(1074069524, 184, Path.Combine(baseFileName, str + "periph_cgu.bin")); + this.DumpTunerRegs(Path.Combine(baseFileName, str + "r820t.txt")); + } + + private void DumpTunerRegs(string filename) + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.AppendLine("Address\tValue"); + for (int i = 0; i < 32; i++) + { + byte b; + NativeMethods.airspy_r820t_read(this._dev, (byte)i, out b); + stringBuilder.AppendLine("0x" + i.ToString("x2") + "\t0x" + b.ToString("x2")); + } + File.WriteAllText(filename, stringBuilder.ToString()); + } + + private unsafe void DumpFile(int address, int length, string fileName) + { + FileStream fileStream = new FileStream(fileName, FileMode.CreateNew); + try + { + byte[] array = new byte[256]; + try + { + byte[] array2 = array; + fixed (byte* data = array2) + { + while (length > 0) + { + ushort num = (ushort)Math.Min(array.Length, length); + if (NativeMethods.airspy_spiflash_read(this._dev, (uint)address, num, data) != 0) + { + break; + } + fileStream.Write(array, 0, num); + length -= num; + address += num; + } + } + } + finally + { + } + } + finally + { + fileStream.Close(); + } + } + + public byte GetR820TRegister(byte reg) + { + byte result; + NativeMethods.airspy_r820t_read(this._dev, reg, out result); + return result; + } + + public void SetR820TRegister(byte reg, byte value) + { + NativeMethods.airspy_r820t_write(this._dev, reg, value); + } + + public byte GetSi5351CRegister(byte reg) + { + byte result; + NativeMethods.airspy_si5351c_read(this._dev, reg, out result); + return result; + } + + public void SetSi5351CRegister(byte reg, byte value) + { + NativeMethods.airspy_si5351c_write(this._dev, reg, value); + } + + public void SetGPIO(airspy_gpio_port_t port, airspy_gpio_pin_t pin, bool value) + { + NativeMethods.airspy_gpio_write(this._dev, port, pin, value); + } + + public bool GetGPIO(airspy_gpio_port_t port, airspy_gpio_pin_t pin) + { + bool result; + NativeMethods.airspy_gpio_read(this._dev, port, pin, out result); + return result; + } + + public unsafe uint GetMemory(uint address) + { + uint result = 0u; + NativeMethods.airspy_spiflash_read(this._dev, address, 4, (byte*)(&result)); + return result; + } + + public void SetIFBandwidth(byte bw) + { + this.SetAnalogIFFilters(bw, 0); + } + + public void SetAnalogIFFilters(byte lpf, byte hpf) + { + byte[] array = new byte[4] + { + 224, + 128, + 96, + 0 + }; + byte[] array2 = new byte[16] + { + 15, + 14, + 13, + 12, + 11, + 10, + 9, + 8, + 7, + 6, + 5, + 4, + 3, + 2, + 1, + 0 + }; + int num = 0xF0 | array2[lpf & 0xF]; + int num2 = array[lpf >> 4] | array2[hpf & 0xF]; + NativeMethods.airspy_r820t_write(this._dev, 10, (byte)num); + NativeMethods.airspy_r820t_write(this._dev, 11, (byte)num2); + } + + public unsafe void WriteFlash(uint address, ushort length, byte* data) + { + NativeMethods.airspy_spiflash_write(this._dev, address, length, data); + } + + public unsafe void ReadFlash(uint address, ushort length, byte* data) + { + NativeMethods.airspy_spiflash_read(this._dev, address, length, data); + } + + public void EraseFlashSector(ushort sector_num) + { + NativeMethods.airspy_spiflash_erase_sector(this._dev, sector_num); + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyGainMode.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyGainMode.cs new file mode 100644 index 0000000..afbbc75 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyGainMode.cs @@ -0,0 +1,9 @@ +namespace SDRSharp.FrontEnds.Airspy +{ + public enum AirspyGainMode + { + Linearity, + Sensitivity, + Custom + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyIO.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyIO.cs new file mode 100644 index 0000000..1526512 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/AirspyIO.cs @@ -0,0 +1,224 @@ +using SDRSharp.Common; +using SDRSharp.Radio; +using System; +using System.Windows.Forms; + +namespace SDRSharp.FrontEnds.Airspy +{ + public class AirspyIO : IFrontendController, IIQStreamController, ITunableSource, ISampleRateChangeSource, IControlAwareObject, ISpectrumProvider, IConfigurationPanelProvider, IFrontendOffset, IDisposable + { + private const int DefaultIFOffset = -1582; + + private const double DefaultSampleRate = 10000000.0; + + private bool _disposed; + + private ControllerPanel _gui; + + private AirspyDevice _airspyDevice; + + private ISharpControl _control; + + private long _frequency = 102998418L; + + private SamplesAvailableDelegate _callback; + + private static float _aliasFreeRatio = (float)Math.Min(Math.Max(Utils.GetDoubleSetting("airspy.aliasFreeRatio", 0.8), 0.1), 1.0); + + public bool CanTune + { + get + { + return true; + } + } + + public long MinimumTunableFrequency + { + get + { + return 0L; + } + } + + public long MaximumTunableFrequency + { + get + { + return 2000000000L; + } + } + + public ISharpControl SharpControl + { + get + { + return this._control; + } + } + + public double Samplerate + { + get + { + if (this._airspyDevice != null) + { + return (double)this._airspyDevice.DecimatedSampleRate; + } + return 10000000.0; + } + } + + public long Frequency + { + get + { + return this._frequency; + } + set + { + this._frequency = value; + this.SetDeviceFrequency(); + } + } + + public float UsableSpectrumRatio + { + get + { + return AirspyIO._aliasFreeRatio; + } + } + + public UserControl Gui + { + get + { + return this._gui; + } + } + + public bool IsDeviceHung + { + get + { + if (this._airspyDevice != null && this._airspyDevice.IsHung) + { + return true; + } + return false; + } + } + + public int Offset + { + get + { + return -1582; + } + } + + public event EventHandler SampleRateChanged; + + public AirspyIO() + { + this._gui = new ControllerPanel(this); + } + + ~AirspyIO() + { + this.Dispose(); + } + + public void Dispose() + { + if (!this._disposed) + { + this._disposed = true; + this.Close(); + GC.SuppressFinalize(this); + } + } + + public void Open() + { + this._airspyDevice = new AirspyDevice(false); + this._airspyDevice.Frequency = (uint)this._frequency; + this._gui.Device = this._airspyDevice; + this._airspyDevice.ComplexSamplesAvailable += this.AirSpyDevice_SamplesAvailable; + this._airspyDevice.SampleRateChanged += this.AirSpyDevice_SampleRateChanged; + this._gui.RefreshTimerEnabled = true; + } + + public void Close() + { + if (this._airspyDevice != null) + { + this._gui.RefreshTimerEnabled = false; + this._gui.SaveSettings(); + this._gui.Device = null; + this._airspyDevice.ComplexSamplesAvailable -= this.AirSpyDevice_SamplesAvailable; + this._airspyDevice.SampleRateChanged -= this.AirSpyDevice_SampleRateChanged; + this._airspyDevice.Dispose(); + this._airspyDevice = null; + } + } + + public unsafe void Start(SamplesAvailableDelegate callback) + { + this._callback = callback; + try + { + if (this._airspyDevice == null) + { + this.Open(); + } + this._airspyDevice.Start(); + this.SetDeviceFrequency(); + } + catch + { + this.Close(); + throw; + } + } + + public void Stop() + { + if (this._airspyDevice != null) + { + this._airspyDevice.Stop(); + } + } + + public void SetControl(object control) + { + this._control = (ISharpControl)control; + } + + private void SetDeviceFrequency() + { + if (this._airspyDevice != null) + { + this._airspyDevice.Frequency = (uint)this._frequency; + } + } + + private unsafe void AirSpyDevice_SamplesAvailable(object sender, ComplexSamplesEventArgs e) + { + this._callback(this, e.Buffer, e.Length); + } + + private void AirSpyDevice_SampleRateChanged(object sender, EventArgs e) + { + EventHandler evt = this.SampleRateChanged; + this._gui.BeginInvoke((Action)delegate + { + if (evt != null) + { + evt(this, EventArgs.Empty); + } + }); + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/ControllerPanel.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/ControllerPanel.cs new file mode 100644 index 0000000..411a734 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/ControllerPanel.cs @@ -0,0 +1,1520 @@ +using SDRSharp.Common; +using SDRSharp.Radio; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.Threading; +using System.Windows.Forms; + +namespace SDRSharp.FrontEnds.Airspy +{ + public class ControllerPanel : UserControl + { + private AirspyDevice _device; + + private AirspyGainMode _gainMode; + + private AirspyIO _owner; + + private uint _sampleRate; + + private int _baseHeight; + + private bool _debug; + + private IContainer components; + + private TrackBar lnaTrackBar; + + private Label label2; + + private CheckBox lnaAgcCheckBox; + + private Label lnaGainLabel; + + private Label vgaGainLabel; + + private Label label3; + + private TrackBar vgaTrackBar; + + private Label mixerGainLabel; + + private CheckBox mixerAgcCheckBox; + + private Label label6; + + private TrackBar mixerTrackBar; + + private Label label8; + + private ComboBox decimationComboBox; + + private ComboBox sampleRateComboBox; + + private Label label9; + + private Label label10; + + private Label displayBandwidthRateLabel; + + private TableLayoutPanel mainTableLayoutPanel; + + private Panel debugPanel; + + private Label label4; + + private Button writeClockButton; + + private Label label1; + + private Button readClockButton; + + private TextBox tunerRegTextBox; + + private TextBox clockValTextBox; + + private Label label5; + + private TextBox clockRegTextBox; + + private TextBox tunerValTextBox; + + private Label label7; + + private Button readTunerButton; + + private Button writeTunerButton; + + private Label label11; + + private NumericUpDown lpfNumericUpDown; + + private Button writeGPIOButton; + + private Button readGPIOButton; + + private TextBox gpioValueTextBox; + + private TextBox gpioAddressTextBox; + + private Label label12; + + private Button dumpButton; + + private Button readMemoryButton; + + private TextBox memoryValueTextBox; + + private TextBox memoryAddressTextBox; + + private Label label13; + + private Label label14; + + private CheckBox biasTeeCheckBox; + + private CheckBox usePackingCheckBox; + + private CheckBox spyVerterCheckBox; + + private Label label15; + + private Label label16; + + private NumericUpDown spyverterPPMnumericUpDown; + + private System.Windows.Forms.Timer refreshTimer; + + private TableLayoutPanel advancedTableLayoutPanel; + + private RadioButton freeRadioButton; + + private RadioButton linearityRadioButton; + + private RadioButton sensitivityRadioButton; + + private TableLayoutPanel simplifiedTableLayoutPanel; + + private TrackBar simplifiedTrackBar; + + private Label simplifiedGainLabel; + + private Label label18; + + private TableLayoutPanel tableLayoutPanel2; + + private CheckBox trackingFilterCheckBox; + + private Button calibrateButton; + + private NumericUpDown hpfNumericUpDown; + + private CheckBox dynamicRangeCheckBox; + + public AirspyDevice Device + { + get + { + return this._device; + } + set + { + this._device = value; + if (this._device != null) + { + this.InitDevice(); + } + else + { + this.sampleRateComboBox.Items.Clear(); + this.UpdateActualSampleRate(); + } + } + } + + public bool RefreshTimerEnabled + { + get + { + return this.refreshTimer.Enabled; + } + set + { + this.refreshTimer.Enabled = value; + } + } + + public ControllerPanel(AirspyIO owner) + { + this._owner = owner; + this.InitializeComponent(); + this.vgaTrackBar.Value = Utils.GetIntSetting("airspy.vga", 2); + this.mixerAgcCheckBox.Checked = Utils.GetBooleanSetting("airspy.mixerAgc"); + this.mixerTrackBar.Value = Utils.GetIntSetting("airspy.mixer", 0); + this.lnaAgcCheckBox.Checked = Utils.GetBooleanSetting("airspy.lnaAgc"); + this.lnaTrackBar.Value = Utils.GetIntSetting("airspy.lna", 0); + this.simplifiedTrackBar.Value = Utils.GetIntSetting("airspy.simplifiedGain", 0); + this.decimationComboBox.SelectedIndex = Utils.GetIntSetting("airspy.decimation", 0); + this.trackingFilterCheckBox.Checked = Utils.GetBooleanSetting("airspy.trackingFilterEnabled"); + this.biasTeeCheckBox.Checked = Utils.GetBooleanSetting("airspy.biasTeeEnabled"); + this.spyVerterCheckBox.Checked = Utils.GetBooleanSetting("airspy.spyVerterEnabled"); + this.spyverterPPMnumericUpDown.Value = (decimal)Utils.GetDoubleSetting("airspy.spyVerterPPM", 0.0); + this._sampleRate = (uint)Utils.GetIntSetting("airspy.sampleRate", 0); + this.usePackingCheckBox.Checked = Utils.GetBooleanSetting("airspy.usePacking"); + this.dynamicRangeCheckBox.Checked = Utils.GetBooleanSetting("airspy.useDynamicRangeEnhancements", true); + this._debug = (Utils.GetIntSetting("airspy.debug", 0) != 0); + base.Height -= this.simplifiedTableLayoutPanel.Height; + base.Height -= this.advancedTableLayoutPanel.Height; + if (this._debug) + { + this.sampleRateComboBox.DropDownStyle = ComboBoxStyle.DropDown; + this.sampleRateComboBox.SelectedValueChanged += this.SampleRate_Changed; + this.sampleRateComboBox.KeyDown += this.SampleRateComboBox_KeyDown; + } + else + { + this.debugPanel.Visible = false; + base.Height -= this.debugPanel.Height; + this.sampleRateComboBox.SelectedIndexChanged += this.SampleRate_Changed; + } + this._baseHeight = base.Height; + this._gainMode = (AirspyGainMode)Utils.GetIntSetting("airspy.gainMode", 0); + switch (this._gainMode) + { + case AirspyGainMode.Custom: + this.freeRadioButton.Checked = true; + break; + case AirspyGainMode.Linearity: + this.linearityRadioButton.Checked = true; + break; + case AirspyGainMode.Sensitivity: + this.sensitivityRadioButton.Checked = true; + break; + } + this.gainModeRadioButton_CheckedChanged(null, null); + } + + private void InitDevice() + { + this.sampleRateComboBox.Items.Clear(); + uint[] supportedSampleRates = this._device.SupportedSampleRates; + foreach (uint sampleRate in supportedSampleRates) + { + this.sampleRateComboBox.Items.Add(ControllerPanel.SampleRateToString(sampleRate) + "SPS"); + } + if (this._sampleRate == 0) + { + this._sampleRate = this._device.SupportedSampleRates[0]; + } + string text = ControllerPanel.SampleRateToString(this._sampleRate) + "SPS"; + if (this._debug) + { + this.sampleRateComboBox.Text = text; + } + else + { + int num = this.sampleRateComboBox.Items.IndexOf(text); + if (num < 0) + { + num = 0; + } + this.sampleRateComboBox.SelectedIndex = num; + } + this.SampleRate_Changed(null, null); + this.trackingFilterCheckBox_CheckedChanged(null, null); + this.biasTeeCheckBox_CheckedChanged(null, null); + this.spyVerterCheckBox_CheckedChanged(null, null); + this.spyverterPPMnumericUpDown_ValueChanged(null, null); + this.usePackingCheckBox_CheckedChanged(null, null); + this.dynamicRangeCheckBox_CheckedChanged(null, null); + this.InitGains(); + } + + private void InitGains() + { + if (this._device != null) + { + this._device.GainMode = this._gainMode; + } + switch (this._gainMode) + { + case AirspyGainMode.Custom: + this.vgaTrackBar_Scroll(null, null); + this.mixerAgcCheckBox_CheckedChanged(null, null); + this.mixerTrackBar_Scroll(null, null); + this.lnaAgcCheckBox_CheckedChanged(null, null); + this.lnaTrackBar_Scroll(null, null); + break; + case AirspyGainMode.Linearity: + case AirspyGainMode.Sensitivity: + this.simplifiedTrackBar_Scroll(null, null); + break; + } + } + + public void SaveSettings() + { + Utils.SaveSetting("airspy.vga", this.vgaTrackBar.Value); + Utils.SaveSetting("airspy.mixerAgc", this.mixerAgcCheckBox.Checked); + Utils.SaveSetting("airspy.mixer", this.mixerTrackBar.Value); + Utils.SaveSetting("airspy.lnaAgc", this.lnaAgcCheckBox.Checked); + Utils.SaveSetting("airspy.lna", this.lnaTrackBar.Value); + Utils.SaveSetting("airspy.simplifiedGain", this.simplifiedTrackBar.Value); + Utils.SaveSetting("airspy.sampleRate", this._sampleRate); + Utils.SaveSetting("airspy.decimation", this.decimationComboBox.SelectedIndex); + Utils.SaveSetting("airspy.trackingFilterEnabled", this.trackingFilterCheckBox.Checked); + Utils.SaveSetting("airspy.biasTeeEnabled", this.biasTeeCheckBox.Checked); + Utils.SaveSetting("airspy.spyVerterEnabled", this.spyVerterCheckBox.Checked); + Utils.SaveSetting("airspy.spyVerterPPM", this.spyverterPPMnumericUpDown.Value); + Utils.SaveSetting("airspy.usePacking", this.usePackingCheckBox.Checked); + Utils.SaveSetting("airspy.gainMode", (int)this._gainMode); + Utils.SaveSetting("airspy.useDynamicRangeEnhancements", this.dynamicRangeCheckBox.Checked); + } + + private void vgaTrackBar_Scroll(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.VgaGain = (byte)this.vgaTrackBar.Value; + this.vgaGainLabel.Text = this.vgaTrackBar.Value.ToString(); + } + } + + private void mixerAgcCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.MixerGainAuto = this.mixerAgcCheckBox.Checked; + this.mixerTrackBar.Enabled = !this.mixerAgcCheckBox.Checked; + this.mixerGainLabel.Visible = !this.mixerAgcCheckBox.Checked; + } + } + + private void mixerTrackBar_Scroll(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.MixerGain = (byte)this.mixerTrackBar.Value; + this.mixerGainLabel.Text = this.mixerTrackBar.Value.ToString(); + } + } + + private void lnaAgcCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.LnaGainAuto = this.lnaAgcCheckBox.Checked; + this.lnaTrackBar.Enabled = !this.lnaAgcCheckBox.Checked; + this.lnaGainLabel.Visible = !this.lnaAgcCheckBox.Checked; + } + } + + private void lnaTrackBar_Scroll(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.LnaGain = (byte)this.lnaTrackBar.Value; + this.lnaGainLabel.Text = this.lnaTrackBar.Value.ToString(); + } + } + + private void SampleRate_Changed(object sender, EventArgs e) + { + try + { + this.UpdateActualSampleRate(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + + private void SampleRateComboBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + this.SampleRate_Changed(sender, e); + } + } + + private void UpdateActualSampleRate() + { + if (this._device != null) + { + string[] array = this.sampleRateComboBox.Text.Split(' '); + this._sampleRate = (uint)(float.Parse((array == null || array.Length == 0) ? this.sampleRateComboBox.Text : array[0], CultureInfo.InvariantCulture) * 1000000f); + this._device.SampleRate = this._sampleRate; + this._device.DecimationStages = this.decimationComboBox.SelectedIndex; + this.displayBandwidthRateLabel.Text = ControllerPanel.SampleRateToString((uint)((float)(double)this._device.DecimatedSampleRate * this._owner.UsableSpectrumRatio)) + "Hz"; + } + else + { + this.displayBandwidthRateLabel.Text = "Unknown"; + } + } + + private static string SampleRateToString(uint sampleRate) + { + double num; + if ((double)sampleRate >= 1000000.0) + { + num = (double)sampleRate * 1E-06; + return num.ToString(CultureInfo.InvariantCulture) + " M"; + } + if ((double)sampleRate >= 1000.0) + { + num = (double)sampleRate * 0.001; + return num.ToString(CultureInfo.InvariantCulture) + " k"; + } + return sampleRate.ToString(CultureInfo.InvariantCulture) + " "; + } + + private void biasTeeCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.BiasTeeEnabled = this.biasTeeCheckBox.Checked; + } + } + + private void spyVerterCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.SpyVerterEnabled = this.spyVerterCheckBox.Checked; + } + this.spyverterPPMnumericUpDown.Enabled = this.spyVerterCheckBox.Checked; + } + + private void spyverterPPMnumericUpDown_ValueChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.SpyVerterPPM = (float)this.spyverterPPMnumericUpDown.Value; + } + } + + private void usePackingCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (this._device != null) + { + ISharpControl sharpControl = this._owner.SharpControl; + if (sharpControl != null && sharpControl.IsPlaying && e != null) + { + sharpControl.StopRadio(); + this._device.UsePacking = this.usePackingCheckBox.Checked; + sharpControl.StartRadio(); + } + else + { + this._device.UsePacking = this.usePackingCheckBox.Checked; + } + } + } + + private void refreshTimer_Tick(object sender, EventArgs e) + { + if (this._owner.IsDeviceHung) + { + this._owner.SharpControl.StopRadio(); + } + AirspyDevice device = this._device; + if (device != null) + { + this.dynamicRangeCheckBox.Enabled = !device.IsStreaming; + } + else + { + this.dynamicRangeCheckBox.Enabled = true; + } + } + + private void gainModeRadioButton_CheckedChanged(object sender, EventArgs e) + { + if (this.sensitivityRadioButton.Checked) + { + this.advancedTableLayoutPanel.Visible = false; + this.simplifiedTableLayoutPanel.Visible = true; + base.Height = this._baseHeight + this.simplifiedTableLayoutPanel.Height; + this._gainMode = AirspyGainMode.Sensitivity; + this.InitGains(); + } + else if (this.linearityRadioButton.Checked) + { + this.advancedTableLayoutPanel.Visible = false; + this.simplifiedTableLayoutPanel.Visible = true; + base.Height = this._baseHeight + this.simplifiedTableLayoutPanel.Height; + this._gainMode = AirspyGainMode.Linearity; + this.InitGains(); + } + else if (this.freeRadioButton.Checked) + { + this.simplifiedTableLayoutPanel.Visible = false; + this.advancedTableLayoutPanel.Visible = true; + base.Height = this._baseHeight + this.advancedTableLayoutPanel.Height; + this._gainMode = AirspyGainMode.Custom; + this.InitGains(); + } + } + + private void simplifiedTrackBar_Scroll(object sender, EventArgs e) + { + if (this._device != null) + { + switch (this._gainMode) + { + case AirspyGainMode.Sensitivity: + this._device.SensitivityGain = (byte)this.simplifiedTrackBar.Value; + break; + case AirspyGainMode.Linearity: + this._device.LinearityGain = (byte)this.simplifiedTrackBar.Value; + break; + } + } + this.simplifiedGainLabel.Text = this.simplifiedTrackBar.Value.ToString(); + } + + private void trackingFilterCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.BypassTrackingFilter = !this.trackingFilterCheckBox.Checked; + } + } + + private void dynamicRangeCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.UseDynamicRangeEnhancements = this.dynamicRangeCheckBox.Checked; + } + } + + private void readTunerButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + try + { + byte reg = this.ParseHex(this.tunerRegTextBox.Text); + byte r820TRegister = this._device.GetR820TRegister(reg); + string text = Convert.ToString(r820TRegister, 2); + text = text.PadLeft(8, '0'); + this.tunerValTextBox.Text = text.Insert(4, " "); + } + catch (FormatException) + { + MessageBox.Show(this, "The register address is not a valid hex number", "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + } + } + } + + private void readClockButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + try + { + byte reg = this.ParseHex(this.clockRegTextBox.Text); + byte si5351CRegister = this._device.GetSi5351CRegister(reg); + string text = Convert.ToString(si5351CRegister, 2); + text = text.PadLeft(8, '0'); + this.clockValTextBox.Text = text.Insert(4, " "); + } + catch (FormatException) + { + MessageBox.Show(this, "The register address is not a valid hex number", "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + } + } + } + + private void writeTunerButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + try + { + byte reg = this.ParseHex(this.tunerRegTextBox.Text); + byte value = this.ParseBin(this.tunerValTextBox.Text); + this._device.SetR820TRegister(reg, value); + } + catch (FormatException) + { + MessageBox.Show(this, "The register address is not a valid hex number", "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + } + } + } + + private void writeClockButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + try + { + byte reg = this.ParseHex(this.clockRegTextBox.Text); + byte value = this.ParseBin(this.clockValTextBox.Text); + this._device.SetSi5351CRegister(reg, value); + } + catch (FormatException) + { + MessageBox.Show(this, "The register address is not a valid hex number", "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + } + } + } + + private byte ParseHex(string s) + { + s = s.Replace("0X", string.Empty).Replace("0x", string.Empty); + return byte.Parse(s, NumberStyles.HexNumber); + } + + private byte ParseBin(string s) + { + s = s.Replace(" ", string.Empty); + return Convert.ToByte(s, 2); + } + + private void tunerRegTextBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + this.readTunerButton_Click(sender, e); + } + } + + private void clockRegTextBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + this.readClockButton_Click(sender, e); + } + } + + private void tunerValTextBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + this.writeTunerButton_Click(sender, e); + } + } + + private void clockValTextBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + this.writeClockButton_Click(sender, e); + } + } + + private void gpioAddressTextBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + this.readGPIOButton_Click(sender, e); + } + } + + private void gpioValueTextBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + this.writeGPIOButton_Click(sender, e); + } + } + + private void readGPIOButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + try + { + string[] array = this.gpioAddressTextBox.Text.Split(':'); + int port = int.Parse(array[0]); + int pin = int.Parse(array[1]); + bool gPIO = this._device.GetGPIO((airspy_gpio_port_t)port, (airspy_gpio_pin_t)pin); + this.gpioValueTextBox.Text = (gPIO ? "1" : "0"); + } + catch (FormatException) + { + MessageBox.Show(this, "The register address is not in the \"port:pin\" format", "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + } + } + } + + private void writeGPIOButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + try + { + string[] array = this.gpioAddressTextBox.Text.Split(':'); + int port = int.Parse(array[0]); + int pin = int.Parse(array[1]); + int num = int.Parse(this.gpioValueTextBox.Text); + this._device.SetGPIO((airspy_gpio_port_t)port, (airspy_gpio_pin_t)pin, num != 0); + } + catch (FormatException) + { + MessageBox.Show(this, "The register address is not in the \"port:pin\" format", "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + } + } + } + + private void dumpButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + this.dumpButton.Enabled = false; + WaitCallback callBack = delegate + { + this._device.Dump(""); + base.BeginInvoke((Action)delegate + { + this.dumpButton.Enabled = true; + }); + }; + ThreadPool.QueueUserWorkItem(callBack); + } + } + + private void readMemoryButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + try + { + uint address = uint.Parse(this.memoryAddressTextBox.Text.Remove(0, 2), NumberStyles.HexNumber); + uint memory = this._device.GetMemory(address); + this.memoryValueTextBox.Text = "0x" + memory.ToString("X").PadLeft(8, '0'); + } + catch (FormatException) + { + MessageBox.Show(this, "The memory address is not in the hex format", "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); + } + } + } + + private void memoryAddressTextBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + this.readMemoryButton_Click(sender, e); + } + } + + private void calibrateButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.CalibrateIF(); + } + } + + private void hpfNumericUpDown_ValueChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.SetAnalogIFFilters((byte)this.lpfNumericUpDown.Value, (byte)this.hpfNumericUpDown.Value); + } + } + + private void lpfNumericUpDown_ValueChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.SetAnalogIFFilters((byte)this.lpfNumericUpDown.Value, (byte)this.hpfNumericUpDown.Value); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + { + this.components.Dispose(); + } + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = new Container(); + this.lnaTrackBar = new TrackBar(); + this.label2 = new Label(); + this.lnaAgcCheckBox = new CheckBox(); + this.lnaGainLabel = new Label(); + this.vgaGainLabel = new Label(); + this.label3 = new Label(); + this.vgaTrackBar = new TrackBar(); + this.mixerGainLabel = new Label(); + this.mixerAgcCheckBox = new CheckBox(); + this.label6 = new Label(); + this.mixerTrackBar = new TrackBar(); + this.label8 = new Label(); + this.decimationComboBox = new ComboBox(); + this.sampleRateComboBox = new ComboBox(); + this.label9 = new Label(); + this.label10 = new Label(); + this.displayBandwidthRateLabel = new Label(); + this.mainTableLayoutPanel = new TableLayoutPanel(); + this.debugPanel = new Panel(); + this.hpfNumericUpDown = new NumericUpDown(); + this.calibrateButton = new Button(); + this.usePackingCheckBox = new CheckBox(); + this.readMemoryButton = new Button(); + this.memoryValueTextBox = new TextBox(); + this.memoryAddressTextBox = new TextBox(); + this.label13 = new Label(); + this.dumpButton = new Button(); + this.writeGPIOButton = new Button(); + this.readGPIOButton = new Button(); + this.gpioValueTextBox = new TextBox(); + this.gpioAddressTextBox = new TextBox(); + this.label12 = new Label(); + this.label11 = new Label(); + this.lpfNumericUpDown = new NumericUpDown(); + this.label4 = new Label(); + this.writeClockButton = new Button(); + this.label1 = new Label(); + this.readClockButton = new Button(); + this.tunerRegTextBox = new TextBox(); + this.clockValTextBox = new TextBox(); + this.label5 = new Label(); + this.clockRegTextBox = new TextBox(); + this.tunerValTextBox = new TextBox(); + this.label7 = new Label(); + this.readTunerButton = new Button(); + this.writeTunerButton = new Button(); + this.biasTeeCheckBox = new CheckBox(); + this.label14 = new Label(); + this.advancedTableLayoutPanel = new TableLayoutPanel(); + this.simplifiedTableLayoutPanel = new TableLayoutPanel(); + this.simplifiedTrackBar = new TrackBar(); + this.simplifiedGainLabel = new Label(); + this.label18 = new Label(); + this.spyverterPPMnumericUpDown = new NumericUpDown(); + this.label16 = new Label(); + this.tableLayoutPanel2 = new TableLayoutPanel(); + this.freeRadioButton = new RadioButton(); + this.sensitivityRadioButton = new RadioButton(); + this.linearityRadioButton = new RadioButton(); + this.trackingFilterCheckBox = new CheckBox(); + this.dynamicRangeCheckBox = new CheckBox(); + this.label15 = new Label(); + this.spyVerterCheckBox = new CheckBox(); + this.refreshTimer = new System.Windows.Forms.Timer(this.components); + ((ISupportInitialize)this.lnaTrackBar).BeginInit(); + ((ISupportInitialize)this.vgaTrackBar).BeginInit(); + ((ISupportInitialize)this.mixerTrackBar).BeginInit(); + this.mainTableLayoutPanel.SuspendLayout(); + this.debugPanel.SuspendLayout(); + ((ISupportInitialize)this.hpfNumericUpDown).BeginInit(); + ((ISupportInitialize)this.lpfNumericUpDown).BeginInit(); + this.advancedTableLayoutPanel.SuspendLayout(); + this.simplifiedTableLayoutPanel.SuspendLayout(); + ((ISupportInitialize)this.simplifiedTrackBar).BeginInit(); + ((ISupportInitialize)this.spyverterPPMnumericUpDown).BeginInit(); + this.tableLayoutPanel2.SuspendLayout(); + base.SuspendLayout(); + this.lnaTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.advancedTableLayoutPanel.SetColumnSpan(this.lnaTrackBar, 3); + this.lnaTrackBar.Location = new Point(0, 170); + this.lnaTrackBar.Margin = new Padding(0); + this.lnaTrackBar.Maximum = 15; + this.lnaTrackBar.Name = "lnaTrackBar"; + this.lnaTrackBar.Size = new Size(202, 45); + this.lnaTrackBar.TabIndex = 4; + this.lnaTrackBar.Scroll += this.lnaTrackBar_Scroll; + this.label2.Anchor = AnchorStyles.Left; + this.label2.AutoSize = true; + this.label2.Location = new Point(0, 147); + this.label2.Margin = new Padding(0); + this.label2.Name = "label2"; + this.label2.Size = new Size(53, 13); + this.label2.TabIndex = 22; + this.label2.Text = "LNA Gain"; + this.lnaAgcCheckBox.Anchor = AnchorStyles.Left; + this.lnaAgcCheckBox.AutoSize = true; + this.lnaAgcCheckBox.Location = new Point(60, 145); + this.lnaAgcCheckBox.Name = "lnaAgcCheckBox"; + this.lnaAgcCheckBox.Size = new Size(48, 17); + this.lnaAgcCheckBox.TabIndex = 3; + this.lnaAgcCheckBox.Text = "Auto"; + this.lnaAgcCheckBox.UseVisualStyleBackColor = true; + this.lnaAgcCheckBox.CheckedChanged += this.lnaAgcCheckBox_CheckedChanged; + this.lnaGainLabel.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.lnaGainLabel.Location = new Point(111, 147); + this.lnaGainLabel.Margin = new Padding(0); + this.lnaGainLabel.Name = "lnaGainLabel"; + this.lnaGainLabel.Size = new Size(91, 13); + this.lnaGainLabel.TabIndex = 26; + this.lnaGainLabel.Text = "0"; + this.lnaGainLabel.TextAlign = ContentAlignment.MiddleRight; + this.vgaGainLabel.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.vgaGainLabel.Location = new Point(111, 0); + this.vgaGainLabel.Margin = new Padding(0); + this.vgaGainLabel.Name = "vgaGainLabel"; + this.vgaGainLabel.Size = new Size(91, 13); + this.vgaGainLabel.TabIndex = 32; + this.vgaGainLabel.Text = "0"; + this.vgaGainLabel.TextAlign = ContentAlignment.MiddleRight; + this.label3.Anchor = AnchorStyles.Left; + this.label3.AutoSize = true; + this.label3.Location = new Point(0, 0); + this.label3.Margin = new Padding(0); + this.label3.Name = "label3"; + this.label3.Size = new Size(41, 13); + this.label3.TabIndex = 31; + this.label3.Text = "IF Gain"; + this.vgaTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.advancedTableLayoutPanel.SetColumnSpan(this.vgaTrackBar, 3); + this.vgaTrackBar.Location = new Point(0, 17); + this.vgaTrackBar.Margin = new Padding(0); + this.vgaTrackBar.Maximum = 15; + this.vgaTrackBar.Name = "vgaTrackBar"; + this.vgaTrackBar.Size = new Size(202, 45); + this.vgaTrackBar.TabIndex = 0; + this.vgaTrackBar.Scroll += this.vgaTrackBar_Scroll; + this.mixerGainLabel.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.mixerGainLabel.Location = new Point(111, 71); + this.mixerGainLabel.Margin = new Padding(0); + this.mixerGainLabel.Name = "mixerGainLabel"; + this.mixerGainLabel.Size = new Size(91, 13); + this.mixerGainLabel.TabIndex = 36; + this.mixerGainLabel.Text = "0"; + this.mixerGainLabel.TextAlign = ContentAlignment.MiddleRight; + this.mixerAgcCheckBox.Anchor = AnchorStyles.Left; + this.mixerAgcCheckBox.AutoSize = true; + this.mixerAgcCheckBox.Location = new Point(60, 69); + this.mixerAgcCheckBox.Name = "mixerAgcCheckBox"; + this.mixerAgcCheckBox.Size = new Size(48, 17); + this.mixerAgcCheckBox.TabIndex = 1; + this.mixerAgcCheckBox.Text = "Auto"; + this.mixerAgcCheckBox.UseVisualStyleBackColor = true; + this.mixerAgcCheckBox.CheckedChanged += this.mixerAgcCheckBox_CheckedChanged; + this.label6.Anchor = AnchorStyles.Left; + this.label6.AutoSize = true; + this.label6.Location = new Point(0, 71); + this.label6.Margin = new Padding(0); + this.label6.Name = "label6"; + this.label6.Size = new Size(57, 13); + this.label6.TabIndex = 35; + this.label6.Text = "Mixer Gain"; + this.mixerTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.advancedTableLayoutPanel.SetColumnSpan(this.mixerTrackBar, 3); + this.mixerTrackBar.Location = new Point(0, 93); + this.mixerTrackBar.Margin = new Padding(0); + this.mixerTrackBar.Maximum = 15; + this.mixerTrackBar.Name = "mixerTrackBar"; + this.mixerTrackBar.Size = new Size(202, 45); + this.mixerTrackBar.TabIndex = 2; + this.mixerTrackBar.Scroll += this.mixerTrackBar_Scroll; + this.label8.Anchor = AnchorStyles.Left; + this.label8.AutoSize = true; + this.label8.Location = new Point(0, 352); + this.label8.Margin = new Padding(0); + this.label8.Name = "label8"; + this.label8.Size = new Size(60, 13); + this.label8.TabIndex = 46; + this.label8.Text = "Decimation"; + this.decimationComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.mainTableLayoutPanel.SetColumnSpan(this.decimationComboBox, 3); + this.decimationComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.decimationComboBox.FormattingEnabled = true; + this.decimationComboBox.Items.AddRange(new object[7] + { + "None", + "2", + "4", + "8", + "16", + "32", + "64" + }); + this.decimationComboBox.Location = new Point(63, 348); + this.decimationComboBox.Margin = new Padding(0, 3, 0, 3); + this.decimationComboBox.Name = "decimationComboBox"; + this.decimationComboBox.Size = new Size(139, 21); + this.decimationComboBox.TabIndex = 6; + this.decimationComboBox.SelectedIndexChanged += this.SampleRate_Changed; + this.sampleRateComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.mainTableLayoutPanel.SetColumnSpan(this.sampleRateComboBox, 3); + this.sampleRateComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.sampleRateComboBox.FormattingEnabled = true; + this.sampleRateComboBox.Location = new Point(63, 321); + this.sampleRateComboBox.Margin = new Padding(0, 3, 0, 3); + this.sampleRateComboBox.Name = "sampleRateComboBox"; + this.sampleRateComboBox.Size = new Size(139, 21); + this.sampleRateComboBox.TabIndex = 5; + this.label9.Anchor = AnchorStyles.Left; + this.label9.AutoSize = true; + this.label9.Location = new Point(0, 325); + this.label9.Margin = new Padding(0); + this.label9.Name = "label9"; + this.label9.Size = new Size(63, 13); + this.label9.TabIndex = 48; + this.label9.Text = "Sample rate"; + this.label10.Anchor = AnchorStyles.Left; + this.label10.AutoSize = true; + this.label10.Location = new Point(0, 377); + this.label10.Margin = new Padding(0); + this.label10.Name = "label10"; + this.label10.Size = new Size(41, 13); + this.label10.TabIndex = 49; + this.label10.Text = "Display"; + this.displayBandwidthRateLabel.Anchor = AnchorStyles.Left; + this.displayBandwidthRateLabel.AutoSize = true; + this.mainTableLayoutPanel.SetColumnSpan(this.displayBandwidthRateLabel, 3); + this.displayBandwidthRateLabel.Font = new Font("Microsoft Sans Serif", 14f, FontStyle.Bold, GraphicsUnit.Point, 0); + this.displayBandwidthRateLabel.Location = new Point(66, 372); + this.displayBandwidthRateLabel.Name = "displayBandwidthRateLabel"; + this.displayBandwidthRateLabel.Size = new Size(80, 24); + this.displayBandwidthRateLabel.TabIndex = 50; + this.displayBandwidthRateLabel.Text = "10 MHz"; + this.mainTableLayoutPanel.ColumnCount = 4; + this.mainTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.mainTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.mainTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.mainTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.mainTableLayoutPanel.Controls.Add(this.label10, 0, 5); + this.mainTableLayoutPanel.Controls.Add(this.displayBandwidthRateLabel, 1, 5); + this.mainTableLayoutPanel.Controls.Add(this.label8, 0, 4); + this.mainTableLayoutPanel.Controls.Add(this.label9, 0, 3); + this.mainTableLayoutPanel.Controls.Add(this.sampleRateComboBox, 1, 3); + this.mainTableLayoutPanel.Controls.Add(this.decimationComboBox, 1, 4); + this.mainTableLayoutPanel.Controls.Add(this.debugPanel, 0, 10); + this.mainTableLayoutPanel.Controls.Add(this.biasTeeCheckBox, 1, 6); + this.mainTableLayoutPanel.Controls.Add(this.label14, 0, 6); + this.mainTableLayoutPanel.Controls.Add(this.advancedTableLayoutPanel, 0, 2); + this.mainTableLayoutPanel.Controls.Add(this.simplifiedTableLayoutPanel, 0, 1); + this.mainTableLayoutPanel.Controls.Add(this.spyverterPPMnumericUpDown, 3, 9); + this.mainTableLayoutPanel.Controls.Add(this.label16, 2, 9); + this.mainTableLayoutPanel.Controls.Add(this.tableLayoutPanel2, 0, 0); + this.mainTableLayoutPanel.Controls.Add(this.trackingFilterCheckBox, 2, 6); + this.mainTableLayoutPanel.Controls.Add(this.dynamicRangeCheckBox, 2, 7); + this.mainTableLayoutPanel.Controls.Add(this.label15, 0, 7); + this.mainTableLayoutPanel.Controls.Add(this.spyVerterCheckBox, 1, 7); + this.mainTableLayoutPanel.Dock = DockStyle.Fill; + this.mainTableLayoutPanel.Location = new Point(0, 0); + this.mainTableLayoutPanel.Margin = new Padding(0); + this.mainTableLayoutPanel.Name = "mainTableLayoutPanel"; + this.mainTableLayoutPanel.RowCount = 11; + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.mainTableLayoutPanel.Size = new Size(202, 648); + this.mainTableLayoutPanel.TabIndex = 51; + this.debugPanel.Anchor = AnchorStyles.None; + this.mainTableLayoutPanel.SetColumnSpan(this.debugPanel, 4); + this.debugPanel.Controls.Add(this.hpfNumericUpDown); + this.debugPanel.Controls.Add(this.calibrateButton); + this.debugPanel.Controls.Add(this.usePackingCheckBox); + this.debugPanel.Controls.Add(this.readMemoryButton); + this.debugPanel.Controls.Add(this.memoryValueTextBox); + this.debugPanel.Controls.Add(this.memoryAddressTextBox); + this.debugPanel.Controls.Add(this.label13); + this.debugPanel.Controls.Add(this.dumpButton); + this.debugPanel.Controls.Add(this.writeGPIOButton); + this.debugPanel.Controls.Add(this.readGPIOButton); + this.debugPanel.Controls.Add(this.gpioValueTextBox); + this.debugPanel.Controls.Add(this.gpioAddressTextBox); + this.debugPanel.Controls.Add(this.label12); + this.debugPanel.Controls.Add(this.label11); + this.debugPanel.Controls.Add(this.lpfNumericUpDown); + this.debugPanel.Controls.Add(this.label4); + this.debugPanel.Controls.Add(this.writeClockButton); + this.debugPanel.Controls.Add(this.label1); + this.debugPanel.Controls.Add(this.readClockButton); + this.debugPanel.Controls.Add(this.tunerRegTextBox); + this.debugPanel.Controls.Add(this.clockValTextBox); + this.debugPanel.Controls.Add(this.label5); + this.debugPanel.Controls.Add(this.clockRegTextBox); + this.debugPanel.Controls.Add(this.tunerValTextBox); + this.debugPanel.Controls.Add(this.label7); + this.debugPanel.Controls.Add(this.readTunerButton); + this.debugPanel.Controls.Add(this.writeTunerButton); + this.debugPanel.Location = new Point(0, 474); + this.debugPanel.Margin = new Padding(0); + this.debugPanel.Name = "debugPanel"; + this.debugPanel.Size = new Size(202, 167); + this.debugPanel.TabIndex = 7; + this.hpfNumericUpDown.Location = new Point(105, 119); + this.hpfNumericUpDown.Maximum = new decimal(new int[4] + { + 15, + 0, + 0, + 0 + }); + this.hpfNumericUpDown.Name = "hpfNumericUpDown"; + this.hpfNumericUpDown.Size = new Size(38, 20); + this.hpfNumericUpDown.TabIndex = 60; + this.hpfNumericUpDown.ValueChanged += this.hpfNumericUpDown_ValueChanged; + this.calibrateButton.Location = new Point(147, 142); + this.calibrateButton.Name = "calibrateButton"; + this.calibrateButton.Size = new Size(47, 22); + this.calibrateButton.TabIndex = 59; + this.calibrateButton.Text = "Cal"; + this.calibrateButton.UseVisualStyleBackColor = true; + this.calibrateButton.Click += this.calibrateButton_Click; + this.usePackingCheckBox.AutoSize = true; + this.usePackingCheckBox.Location = new Point(58, 146); + this.usePackingCheckBox.Name = "usePackingCheckBox"; + this.usePackingCheckBox.Size = new Size(87, 17); + this.usePackingCheckBox.TabIndex = 58; + this.usePackingCheckBox.Text = "Use Packing"; + this.usePackingCheckBox.TextAlign = ContentAlignment.MiddleRight; + this.usePackingCheckBox.UseVisualStyleBackColor = true; + this.usePackingCheckBox.CheckedChanged += this.usePackingCheckBox_CheckedChanged; + this.readMemoryButton.Location = new Point(147, 94); + this.readMemoryButton.Margin = new Padding(2); + this.readMemoryButton.Name = "readMemoryButton"; + this.readMemoryButton.Size = new Size(21, 21); + this.readMemoryButton.TabIndex = 56; + this.readMemoryButton.Text = "R"; + this.readMemoryButton.UseVisualStyleBackColor = true; + this.readMemoryButton.Click += this.readMemoryButton_Click; + this.memoryValueTextBox.Location = new Point(105, 95); + this.memoryValueTextBox.Margin = new Padding(2); + this.memoryValueTextBox.Name = "memoryValueTextBox"; + this.memoryValueTextBox.Size = new Size(38, 20); + this.memoryValueTextBox.TabIndex = 55; + this.memoryAddressTextBox.Location = new Point(58, 95); + this.memoryAddressTextBox.Margin = new Padding(2); + this.memoryAddressTextBox.Name = "memoryAddressTextBox"; + this.memoryAddressTextBox.Size = new Size(43, 20); + this.memoryAddressTextBox.TabIndex = 54; + this.memoryAddressTextBox.Text = "0x100800c0"; + this.memoryAddressTextBox.KeyDown += this.memoryAddressTextBox_KeyDown; + this.label13.AutoSize = true; + this.label13.Location = new Point(9, 98); + this.label13.Name = "label13"; + this.label13.Size = new Size(44, 13); + this.label13.TabIndex = 57; + this.label13.Text = "Memory"; + this.dumpButton.Location = new Point(147, 119); + this.dumpButton.Name = "dumpButton"; + this.dumpButton.Size = new Size(47, 22); + this.dumpButton.TabIndex = 53; + this.dumpButton.Text = "Dump"; + this.dumpButton.UseVisualStyleBackColor = true; + this.dumpButton.Click += this.dumpButton_Click; + this.writeGPIOButton.Location = new Point(173, 70); + this.writeGPIOButton.Margin = new Padding(2); + this.writeGPIOButton.Name = "writeGPIOButton"; + this.writeGPIOButton.Size = new Size(21, 21); + this.writeGPIOButton.TabIndex = 51; + this.writeGPIOButton.Text = "W"; + this.writeGPIOButton.UseVisualStyleBackColor = true; + this.writeGPIOButton.Click += this.writeGPIOButton_Click; + this.readGPIOButton.Location = new Point(147, 70); + this.readGPIOButton.Margin = new Padding(2); + this.readGPIOButton.Name = "readGPIOButton"; + this.readGPIOButton.Size = new Size(21, 21); + this.readGPIOButton.TabIndex = 50; + this.readGPIOButton.Text = "R"; + this.readGPIOButton.UseVisualStyleBackColor = true; + this.readGPIOButton.Click += this.readGPIOButton_Click; + this.gpioValueTextBox.Location = new Point(105, 71); + this.gpioValueTextBox.Margin = new Padding(2); + this.gpioValueTextBox.Name = "gpioValueTextBox"; + this.gpioValueTextBox.Size = new Size(38, 20); + this.gpioValueTextBox.TabIndex = 49; + this.gpioValueTextBox.KeyDown += this.gpioValueTextBox_KeyDown; + this.gpioAddressTextBox.Location = new Point(58, 71); + this.gpioAddressTextBox.Margin = new Padding(2); + this.gpioAddressTextBox.Name = "gpioAddressTextBox"; + this.gpioAddressTextBox.Size = new Size(43, 20); + this.gpioAddressTextBox.TabIndex = 48; + this.gpioAddressTextBox.Text = "0:12"; + this.gpioAddressTextBox.KeyDown += this.gpioAddressTextBox_KeyDown; + this.label12.AutoSize = true; + this.label12.Location = new Point(20, 74); + this.label12.Name = "label12"; + this.label12.Size = new Size(33, 13); + this.label12.TabIndex = 52; + this.label12.Text = "GPIO"; + this.label11.AutoSize = true; + this.label11.Location = new Point(11, 121); + this.label11.Name = "label11"; + this.label11.Size = new Size(41, 13); + this.label11.TabIndex = 47; + this.label11.Text = "IF Filter"; + this.lpfNumericUpDown.Location = new Point(58, 119); + this.lpfNumericUpDown.Maximum = new decimal(new int[4] + { + 63, + 0, + 0, + 0 + }); + this.lpfNumericUpDown.Name = "lpfNumericUpDown"; + this.lpfNumericUpDown.Size = new Size(43, 20); + this.lpfNumericUpDown.TabIndex = 46; + this.lpfNumericUpDown.Value = new decimal(new int[4] + { + 55, + 0, + 0, + 0 + }); + this.lpfNumericUpDown.ValueChanged += this.lpfNumericUpDown_ValueChanged; + this.label4.AutoSize = true; + this.label4.Location = new Point(56, 6); + this.label4.Name = "label4"; + this.label4.Size = new Size(45, 13); + this.label4.TabIndex = 40; + this.label4.Text = "Address"; + this.writeClockButton.Location = new Point(173, 46); + this.writeClockButton.Margin = new Padding(2); + this.writeClockButton.Name = "writeClockButton"; + this.writeClockButton.Size = new Size(21, 21); + this.writeClockButton.TabIndex = 14; + this.writeClockButton.Text = "W"; + this.writeClockButton.UseVisualStyleBackColor = true; + this.writeClockButton.Click += this.writeClockButton_Click; + this.label1.AutoSize = true; + this.label1.Location = new Point(7, 26); + this.label1.Name = "label1"; + this.label1.Size = new Size(46, 13); + this.label1.TabIndex = 38; + this.label1.Text = "R820T2"; + this.readClockButton.Location = new Point(147, 46); + this.readClockButton.Margin = new Padding(2); + this.readClockButton.Name = "readClockButton"; + this.readClockButton.Size = new Size(21, 21); + this.readClockButton.TabIndex = 13; + this.readClockButton.Text = "R"; + this.readClockButton.UseVisualStyleBackColor = true; + this.readClockButton.Click += this.readClockButton_Click; + this.tunerRegTextBox.Location = new Point(58, 23); + this.tunerRegTextBox.Margin = new Padding(2); + this.tunerRegTextBox.Name = "tunerRegTextBox"; + this.tunerRegTextBox.Size = new Size(43, 20); + this.tunerRegTextBox.TabIndex = 7; + this.tunerRegTextBox.Text = "0x0A"; + this.tunerRegTextBox.KeyDown += this.tunerRegTextBox_KeyDown; + this.clockValTextBox.Location = new Point(105, 47); + this.clockValTextBox.Margin = new Padding(2); + this.clockValTextBox.Name = "clockValTextBox"; + this.clockValTextBox.Size = new Size(38, 20); + this.clockValTextBox.TabIndex = 12; + this.clockValTextBox.KeyDown += this.clockValTextBox_KeyDown; + this.label5.AutoSize = true; + this.label5.Location = new Point(102, 6); + this.label5.Name = "label5"; + this.label5.Size = new Size(34, 13); + this.label5.TabIndex = 41; + this.label5.Text = "Value"; + this.clockRegTextBox.Location = new Point(58, 47); + this.clockRegTextBox.Margin = new Padding(2); + this.clockRegTextBox.Name = "clockRegTextBox"; + this.clockRegTextBox.Size = new Size(43, 20); + this.clockRegTextBox.TabIndex = 11; + this.clockRegTextBox.Text = "0x00"; + this.clockRegTextBox.KeyDown += this.clockRegTextBox_KeyDown; + this.tunerValTextBox.Location = new Point(105, 23); + this.tunerValTextBox.Margin = new Padding(2); + this.tunerValTextBox.Name = "tunerValTextBox"; + this.tunerValTextBox.Size = new Size(38, 20); + this.tunerValTextBox.TabIndex = 8; + this.tunerValTextBox.KeyDown += this.tunerValTextBox_KeyDown; + this.label7.AutoSize = true; + this.label7.Location = new Point(6, 49); + this.label7.Name = "label7"; + this.label7.Size = new Size(47, 13); + this.label7.TabIndex = 45; + this.label7.Text = "Si5351C"; + this.readTunerButton.Location = new Point(147, 22); + this.readTunerButton.Margin = new Padding(2); + this.readTunerButton.Name = "readTunerButton"; + this.readTunerButton.Size = new Size(21, 21); + this.readTunerButton.TabIndex = 9; + this.readTunerButton.Text = "R"; + this.readTunerButton.UseVisualStyleBackColor = true; + this.readTunerButton.Click += this.readTunerButton_Click; + this.writeTunerButton.Location = new Point(173, 22); + this.writeTunerButton.Margin = new Padding(2); + this.writeTunerButton.Name = "writeTunerButton"; + this.writeTunerButton.Size = new Size(21, 21); + this.writeTunerButton.TabIndex = 10; + this.writeTunerButton.Text = "W"; + this.writeTunerButton.UseVisualStyleBackColor = true; + this.writeTunerButton.Click += this.writeTunerButton_Click; + this.biasTeeCheckBox.Anchor = AnchorStyles.Left; + this.biasTeeCheckBox.AutoSize = true; + this.biasTeeCheckBox.Location = new Point(66, 400); + this.biasTeeCheckBox.Name = "biasTeeCheckBox"; + this.biasTeeCheckBox.Size = new Size(15, 14); + this.biasTeeCheckBox.TabIndex = 52; + this.biasTeeCheckBox.UseVisualStyleBackColor = true; + this.biasTeeCheckBox.CheckedChanged += this.biasTeeCheckBox_CheckedChanged; + this.label14.Anchor = AnchorStyles.Left; + this.label14.AutoSize = true; + this.label14.Location = new Point(0, 401); + this.label14.Margin = new Padding(0); + this.label14.Name = "label14"; + this.label14.Size = new Size(49, 13); + this.label14.TabIndex = 51; + this.label14.Text = "Bias-Tee"; + this.advancedTableLayoutPanel.ColumnCount = 3; + this.mainTableLayoutPanel.SetColumnSpan(this.advancedTableLayoutPanel, 4); + this.advancedTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.advancedTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.advancedTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.advancedTableLayoutPanel.Controls.Add(this.vgaTrackBar, 0, 1); + this.advancedTableLayoutPanel.Controls.Add(this.label3, 0, 0); + this.advancedTableLayoutPanel.Controls.Add(this.vgaGainLabel, 2, 0); + this.advancedTableLayoutPanel.Controls.Add(this.label6, 0, 2); + this.advancedTableLayoutPanel.Controls.Add(this.mixerAgcCheckBox, 1, 2); + this.advancedTableLayoutPanel.Controls.Add(this.mixerGainLabel, 2, 2); + this.advancedTableLayoutPanel.Controls.Add(this.lnaTrackBar, 0, 5); + this.advancedTableLayoutPanel.Controls.Add(this.lnaAgcCheckBox, 1, 4); + this.advancedTableLayoutPanel.Controls.Add(this.lnaGainLabel, 2, 4); + this.advancedTableLayoutPanel.Controls.Add(this.label2, 0, 4); + this.advancedTableLayoutPanel.Controls.Add(this.mixerTrackBar, 0, 3); + this.advancedTableLayoutPanel.Dock = DockStyle.Fill; + this.advancedTableLayoutPanel.Location = new Point(0, 98); + this.advancedTableLayoutPanel.Margin = new Padding(0); + this.advancedTableLayoutPanel.Name = "advancedTableLayoutPanel"; + this.advancedTableLayoutPanel.RowCount = 6; + this.advancedTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.advancedTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33333f)); + this.advancedTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.advancedTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33333f)); + this.advancedTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.advancedTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33333f)); + this.advancedTableLayoutPanel.Size = new Size(202, 220); + this.advancedTableLayoutPanel.TabIndex = 58; + this.advancedTableLayoutPanel.Visible = false; + this.simplifiedTableLayoutPanel.ColumnCount = 2; + this.mainTableLayoutPanel.SetColumnSpan(this.simplifiedTableLayoutPanel, 4); + this.simplifiedTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.simplifiedTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.simplifiedTableLayoutPanel.Controls.Add(this.simplifiedTrackBar, 0, 1); + this.simplifiedTableLayoutPanel.Controls.Add(this.simplifiedGainLabel, 1, 0); + this.simplifiedTableLayoutPanel.Controls.Add(this.label18, 0, 0); + this.simplifiedTableLayoutPanel.Dock = DockStyle.Fill; + this.simplifiedTableLayoutPanel.Location = new Point(0, 30); + this.simplifiedTableLayoutPanel.Margin = new Padding(0); + this.simplifiedTableLayoutPanel.Name = "simplifiedTableLayoutPanel"; + this.simplifiedTableLayoutPanel.RowCount = 2; + this.simplifiedTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.simplifiedTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.simplifiedTableLayoutPanel.Size = new Size(202, 68); + this.simplifiedTableLayoutPanel.TabIndex = 62; + this.simplifiedTableLayoutPanel.Visible = false; + this.simplifiedTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.simplifiedTableLayoutPanel.SetColumnSpan(this.simplifiedTrackBar, 3); + this.simplifiedTrackBar.Location = new Point(0, 18); + this.simplifiedTrackBar.Margin = new Padding(0); + this.simplifiedTrackBar.Maximum = 21; + this.simplifiedTrackBar.Name = "simplifiedTrackBar"; + this.simplifiedTrackBar.Size = new Size(202, 45); + this.simplifiedTrackBar.TabIndex = 35; + this.simplifiedTrackBar.Scroll += this.simplifiedTrackBar_Scroll; + this.simplifiedGainLabel.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.simplifiedGainLabel.Location = new Point(29, 1); + this.simplifiedGainLabel.Margin = new Padding(0); + this.simplifiedGainLabel.Name = "simplifiedGainLabel"; + this.simplifiedGainLabel.Size = new Size(173, 10); + this.simplifiedGainLabel.TabIndex = 33; + this.simplifiedGainLabel.Text = "0"; + this.simplifiedGainLabel.TextAlign = ContentAlignment.MiddleRight; + this.label18.Anchor = AnchorStyles.Left; + this.label18.AutoSize = true; + this.label18.Location = new Point(0, 0); + this.label18.Margin = new Padding(0); + this.label18.Name = "label18"; + this.label18.Size = new Size(29, 13); + this.label18.TabIndex = 34; + this.label18.Text = "Gain"; + this.spyverterPPMnumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.spyverterPPMnumericUpDown.DecimalPlaces = 2; + this.spyverterPPMnumericUpDown.Increment = new decimal(new int[4] + { + 5, + 0, + 0, + 131072 + }); + this.spyverterPPMnumericUpDown.Location = new Point(117, 445); + this.spyverterPPMnumericUpDown.Minimum = new decimal(new int[4] + { + 100, + 0, + 0, + -2147483648 + }); + this.spyverterPPMnumericUpDown.Name = "spyverterPPMnumericUpDown"; + this.spyverterPPMnumericUpDown.Size = new Size(82, 20); + this.spyverterPPMnumericUpDown.TabIndex = 57; + this.spyverterPPMnumericUpDown.TextAlign = HorizontalAlignment.Right; + this.spyverterPPMnumericUpDown.ValueChanged += this.spyverterPPMnumericUpDown_ValueChanged; + this.label16.Anchor = AnchorStyles.Right; + this.label16.AutoSize = true; + this.label16.Location = new Point(84, 448); + this.label16.Margin = new Padding(0); + this.label16.Name = "label16"; + this.label16.Size = new Size(30, 13); + this.label16.TabIndex = 56; + this.label16.Text = "PPM"; + this.tableLayoutPanel2.ColumnCount = 3; + this.mainTableLayoutPanel.SetColumnSpan(this.tableLayoutPanel2, 4); + this.tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel2.Controls.Add(this.freeRadioButton, 2, 0); + this.tableLayoutPanel2.Controls.Add(this.sensitivityRadioButton, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.linearityRadioButton, 1, 0); + this.tableLayoutPanel2.Dock = DockStyle.Fill; + this.tableLayoutPanel2.Location = new Point(3, 3); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 1; + this.tableLayoutPanel2.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel2.Size = new Size(196, 24); + this.tableLayoutPanel2.TabIndex = 63; + this.freeRadioButton.AutoSize = true; + this.freeRadioButton.Location = new Point(151, 3); + this.freeRadioButton.Name = "freeRadioButton"; + this.freeRadioButton.Size = new Size(46, 17); + this.freeRadioButton.TabIndex = 61; + this.freeRadioButton.TabStop = true; + this.freeRadioButton.Text = "Free"; + this.freeRadioButton.UseVisualStyleBackColor = true; + this.freeRadioButton.CheckedChanged += this.gainModeRadioButton_CheckedChanged; + this.sensitivityRadioButton.AutoSize = true; + this.sensitivityRadioButton.Location = new Point(3, 3); + this.sensitivityRadioButton.Name = "sensitivityRadioButton"; + this.sensitivityRadioButton.Size = new Size(72, 17); + this.sensitivityRadioButton.TabIndex = 59; + this.sensitivityRadioButton.TabStop = true; + this.sensitivityRadioButton.Text = "Sensitivity"; + this.sensitivityRadioButton.UseVisualStyleBackColor = true; + this.sensitivityRadioButton.CheckedChanged += this.gainModeRadioButton_CheckedChanged; + this.linearityRadioButton.AutoSize = true; + this.linearityRadioButton.Location = new Point(81, 3); + this.linearityRadioButton.Name = "linearityRadioButton"; + this.linearityRadioButton.Size = new Size(64, 17); + this.linearityRadioButton.TabIndex = 60; + this.linearityRadioButton.TabStop = true; + this.linearityRadioButton.Text = "Linearity"; + this.linearityRadioButton.UseVisualStyleBackColor = true; + this.linearityRadioButton.CheckedChanged += this.gainModeRadioButton_CheckedChanged; + this.trackingFilterCheckBox.Anchor = AnchorStyles.Right; + this.trackingFilterCheckBox.AutoSize = true; + this.trackingFilterCheckBox.CheckAlign = ContentAlignment.MiddleRight; + this.trackingFilterCheckBox.Checked = true; + this.trackingFilterCheckBox.CheckState = CheckState.Checked; + this.mainTableLayoutPanel.SetColumnSpan(this.trackingFilterCheckBox, 2); + this.trackingFilterCheckBox.Location = new Point(106, 399); + this.trackingFilterCheckBox.Name = "trackingFilterCheckBox"; + this.trackingFilterCheckBox.Size = new Size(93, 17); + this.trackingFilterCheckBox.TabIndex = 65; + this.trackingFilterCheckBox.Text = "Tracking Filter"; + this.trackingFilterCheckBox.UseVisualStyleBackColor = true; + this.trackingFilterCheckBox.CheckedChanged += this.trackingFilterCheckBox_CheckedChanged; + this.dynamicRangeCheckBox.Anchor = AnchorStyles.Right; + this.dynamicRangeCheckBox.AutoSize = true; + this.dynamicRangeCheckBox.CheckAlign = ContentAlignment.MiddleRight; + this.mainTableLayoutPanel.SetColumnSpan(this.dynamicRangeCheckBox, 2); + this.dynamicRangeCheckBox.Location = new Point(113, 422); + this.dynamicRangeCheckBox.Name = "dynamicRangeCheckBox"; + this.dynamicRangeCheckBox.Size = new Size(86, 17); + this.dynamicRangeCheckBox.TabIndex = 66; + this.dynamicRangeCheckBox.Text = "Enable HDR"; + this.dynamicRangeCheckBox.UseVisualStyleBackColor = true; + this.dynamicRangeCheckBox.CheckedChanged += this.dynamicRangeCheckBox_CheckedChanged; + this.label15.Anchor = AnchorStyles.Left; + this.label15.AutoSize = true; + this.label15.Location = new Point(0, 424); + this.label15.Margin = new Padding(0); + this.label15.Name = "label15"; + this.label15.Size = new Size(53, 13); + this.label15.TabIndex = 54; + this.label15.Text = "SpyVerter"; + this.spyVerterCheckBox.Anchor = AnchorStyles.Left; + this.spyVerterCheckBox.AutoSize = true; + this.spyVerterCheckBox.Location = new Point(66, 423); + this.spyVerterCheckBox.Name = "spyVerterCheckBox"; + this.spyVerterCheckBox.Size = new Size(15, 14); + this.spyVerterCheckBox.TabIndex = 53; + this.spyVerterCheckBox.UseVisualStyleBackColor = true; + this.spyVerterCheckBox.CheckedChanged += this.spyVerterCheckBox_CheckedChanged; + this.refreshTimer.Tick += this.refreshTimer_Tick; + base.AutoScaleDimensions = new SizeF(6f, 13f); + base.AutoScaleMode = AutoScaleMode.Font; + base.Controls.Add(this.mainTableLayoutPanel); + base.Name = "ControllerPanel"; + base.Size = new Size(202, 648); + ((ISupportInitialize)this.lnaTrackBar).EndInit(); + ((ISupportInitialize)this.vgaTrackBar).EndInit(); + ((ISupportInitialize)this.mixerTrackBar).EndInit(); + this.mainTableLayoutPanel.ResumeLayout(false); + this.mainTableLayoutPanel.PerformLayout(); + this.debugPanel.ResumeLayout(false); + this.debugPanel.PerformLayout(); + ((ISupportInitialize)this.hpfNumericUpDown).EndInit(); + ((ISupportInitialize)this.lpfNumericUpDown).EndInit(); + this.advancedTableLayoutPanel.ResumeLayout(false); + this.advancedTableLayoutPanel.PerformLayout(); + this.simplifiedTableLayoutPanel.ResumeLayout(false); + this.simplifiedTableLayoutPanel.PerformLayout(); + ((ISupportInitialize)this.simplifiedTrackBar).EndInit(); + ((ISupportInitialize)this.spyverterPPMnumericUpDown).EndInit(); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); + base.ResumeLayout(false); + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/ControllerPanel.resx b/SDRSharp/SDRSharp.FrontEnds.Airspy/ControllerPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/ControllerPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/ConversionFilters.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/ConversionFilters.cs new file mode 100644 index 0000000..ca4b668 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/ConversionFilters.cs @@ -0,0 +1,109 @@ +namespace SDRSharp.FrontEnds.Airspy +{ + public static class ConversionFilters + { + private static readonly float[] Kernel_Dec16_110dB = new float[7] + { + -0.03183508f, + 0f, + 0.2818315f, + 0.5000073f, + 0.2818315f, + 0f, + -0.03183508f + }; + + private static readonly float[] Kernel_Dec8_100dB = new float[11] + { + 0.006633401f, + 0f, + -0.0510355234f, + 0f, + 0.2944033f, + 0.4999975f, + 0.2944033f, + 0f, + -0.0510355234f, + 0f, + 0.006633401f + }; + + private static readonly float[] Kernel_Dec4_90dB = new float[15] + { + -0.0024741888f, + 0f, + 0.0169657469f, + 0f, + -0.0676806f, + 0f, + 0.303180575f, + 0.500017047f, + 0.303180575f, + 0f, + -0.0676806f, + 0f, + 0.0169657469f, + 0f, + -0.0024741888f + }; + + private static readonly float[] Kernel_Dec2_80dB = new float[47] + { + -0.00019800663f, + 0f, + 0.000576853752f, + 0f, + -0.001352191f, + 0f, + 0.00272917747f, + 0f, + -0.00498819351f, + 0f, + 0.008499503f, + 0f, + -0.0137885809f, + 0f, + 0.0217131376f, + 0f, + -0.0339800119f, + 0f, + 0.0549448729f, + 0f, + -0.100657463f, + 0f, + 0.3164574f, + 0.5f, + 0.3164574f, + 0f, + -0.100657463f, + 0f, + 0.0549448729f, + 0f, + -0.0339800119f, + 0f, + 0.0217131376f, + 0f, + -0.0137885809f, + 0f, + 0.008499503f, + 0f, + -0.00498819351f, + 0f, + 0.00272917747f, + 0f, + -0.001352191f, + 0f, + 0.000576853752f, + 0f, + -0.00019800663f + }; + + public static readonly float[][] FirKernels100dB = new float[4][] + { + ConversionFilters.Kernel_Dec2_80dB, + ConversionFilters.Kernel_Dec4_90dB, + ConversionFilters.Kernel_Dec8_100dB, + ConversionFilters.Kernel_Dec16_110dB + }; + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/NativeMethods.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/NativeMethods.cs new file mode 100644 index 0000000..62342e1 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/NativeMethods.cs @@ -0,0 +1,135 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.FrontEnds.Airspy +{ + public static class NativeMethods + { + private const string LibAirSpy = "airspy"; + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_init(); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_exit(); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_open(out IntPtr dev); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_close(IntPtr dev); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_samplerate(IntPtr dev, uint samplerate); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public unsafe static extern airspy_error airspy_set_conversion_filter_float32(IntPtr dev, float* kernel, int len); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public unsafe static extern airspy_error airspy_set_conversion_filter_int16(IntPtr dev, short* kernel, int len); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public unsafe static extern airspy_error airspy_get_samplerates(IntPtr dev, uint* buffer, uint len); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_start_rx(IntPtr dev, airspy_sample_block_cb_fn cb, IntPtr rx_ctx); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_stop_rx(IntPtr dev); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_is_streaming(IntPtr dev); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl, EntryPoint = "airspy_board_id_name")] + private static extern IntPtr airspy_board_id_name_native(uint index); + + public static string airspy_board_id_name(uint index) + { + try + { + IntPtr ptr = NativeMethods.airspy_board_id_name_native(index); + return Marshal.PtrToStringAnsi(ptr); + } + catch (EntryPointNotFoundException ex) + { + Console.WriteLine("{0}:\n {1}", ex.GetType().Name, ex.Message); + return "AirSpy"; + } + } + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_sample_type(IntPtr dev, airspy_sample_type sample_type); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_freq(IntPtr dev, uint freq_hz); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_packing(IntPtr dev, [MarshalAs(UnmanagedType.U1)] bool value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_lna_gain(IntPtr dev, byte value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_mixer_gain(IntPtr dev, byte value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_vga_gain(IntPtr dev, byte value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_lna_agc(IntPtr dev, [MarshalAs(UnmanagedType.U1)] bool value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_mixer_agc(IntPtr dev, [MarshalAs(UnmanagedType.U1)] bool value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_linearity_gain(IntPtr dev, byte value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_sensitivity_gain(IntPtr dev, byte value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_r820t_write(IntPtr device, byte register_number, byte value); + + public static airspy_error airspy_r820t_write_mask(IntPtr device, byte reg, byte value, byte mask) + { + byte b; + airspy_error airspy_error = NativeMethods.airspy_r820t_read(device, reg, out b); + if (airspy_error < airspy_error.AIRSPY_SUCCESS) + { + return airspy_error; + } + value = (byte)((b & ~mask) | (value & mask)); + return NativeMethods.airspy_r820t_write(device, reg, value); + } + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_r820t_read(IntPtr device, byte register_number, out byte value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_si5351c_write(IntPtr device, byte register_number, byte value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_si5351c_read(IntPtr device, byte register_number, out byte value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_set_rf_bias(IntPtr dev, [In] [MarshalAs(UnmanagedType.U1)] bool value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_gpio_read(IntPtr device, airspy_gpio_port_t port, airspy_gpio_pin_t pin, [MarshalAs(UnmanagedType.U1)] out bool value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_gpio_write(IntPtr device, airspy_gpio_port_t port, airspy_gpio_pin_t pin, [MarshalAs(UnmanagedType.U1)] bool value); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_spiflash_erase(IntPtr device); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public unsafe static extern airspy_error airspy_spiflash_write(IntPtr device, uint address, ushort length, byte* data); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public unsafe static extern airspy_error airspy_spiflash_read(IntPtr device, uint address, ushort length, byte* data); + + [DllImport("airspy", CallingConvention = CallingConvention.Cdecl)] + public static extern airspy_error airspy_spiflash_erase_sector(IntPtr device, ushort sector_num); + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_error.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_error.cs new file mode 100644 index 0000000..c9648a9 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_error.cs @@ -0,0 +1,17 @@ +namespace SDRSharp.FrontEnds.Airspy +{ + public enum airspy_error + { + AIRSPY_SUCCESS, + AIRSPY_TRUE, + AIRSPY_ERROR_INVALID_PARAM = -2, + AIRSPY_ERROR_NOT_FOUND = -5, + AIRSPY_ERROR_BUSY = -6, + AIRSPY_ERROR_NO_MEM = -11, + AIRSPY_ERROR_LIBUSB = -1000, + AIRSPY_ERROR_THREAD = -1001, + AIRSPY_ERROR_STREAMING_THREAD_ERR = -1002, + AIRSPY_ERROR_STREAMING_STOPPED = -1003, + AIRSPY_ERROR_OTHER = -9999 + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_gpio_pin_t.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_gpio_pin_t.cs new file mode 100644 index 0000000..d4d27f1 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_gpio_pin_t.cs @@ -0,0 +1,38 @@ +namespace SDRSharp.FrontEnds.Airspy +{ + public enum airspy_gpio_pin_t + { + GPIO_PIN0, + GPIO_PIN1, + GPIO_PIN2, + GPIO_PIN3, + GPIO_PIN4, + GPIO_PIN5, + GPIO_PIN6, + GPIO_PIN7, + GPIO_PIN8, + GPIO_PIN9, + GPIO_PIN10, + GPIO_PIN11, + GPIO_PIN12, + GPIO_PIN13, + GPIO_PIN14, + GPIO_PIN15, + GPIO_PIN16, + GPIO_PIN17, + GPIO_PIN18, + GPIO_PIN19, + GPIO_PIN20, + GPIO_PIN21, + GPIO_PIN22, + GPIO_PIN23, + GPIO_PIN24, + GPIO_PIN25, + GPIO_PIN26, + GPIO_PIN27, + GPIO_PIN28, + GPIO_PIN29, + GPIO_PIN30, + GPIO_PIN31 + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_gpio_port_t.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_gpio_port_t.cs new file mode 100644 index 0000000..185b3db --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_gpio_port_t.cs @@ -0,0 +1,14 @@ +namespace SDRSharp.FrontEnds.Airspy +{ + public enum airspy_gpio_port_t + { + GPIO_PORT0, + GPIO_PORT1, + GPIO_PORT2, + GPIO_PORT3, + GPIO_PORT4, + GPIO_PORT5, + GPIO_PORT6, + GPIO_PORT7 + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_sample_block_cb_fn.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_sample_block_cb_fn.cs new file mode 100644 index 0000000..a71e29e --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_sample_block_cb_fn.cs @@ -0,0 +1,7 @@ +using System.Runtime.InteropServices; + +namespace SDRSharp.FrontEnds.Airspy +{ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public unsafe delegate int airspy_sample_block_cb_fn(airspy_transfer* ptr); +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_sample_type.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_sample_type.cs new file mode 100644 index 0000000..e5f5ac3 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_sample_type.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.FrontEnds.Airspy +{ + public enum airspy_sample_type + { + AIRSPY_SAMPLE_FLOAT32_IQ, + AIRSPY_SAMPLE_FLOAT32_REAL, + AIRSPY_SAMPLE_INT16_IQ, + AIRSPY_SAMPLE_INT16_REAL + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_transfer.cs b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_transfer.cs new file mode 100644 index 0000000..368cc27 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.Airspy/airspy_transfer.cs @@ -0,0 +1,19 @@ +using System; + +namespace SDRSharp.FrontEnds.Airspy +{ + public struct airspy_transfer + { + public IntPtr device; + + public IntPtr ctx; + + public unsafe void* samples; + + public int sample_count; + + public ulong dropped_samples; + + public airspy_sample_type sample_type; + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.AirspyHF/AirspyHFDevice.cs b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/AirspyHFDevice.cs new file mode 100644 index 0000000..9f43040 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/AirspyHFDevice.cs @@ -0,0 +1,245 @@ +using SDRSharp.Common; +using SDRSharp.Radio; +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.FrontEnds.AirspyHF +{ + public class AirspyHFDevice : IDisposable + { + public const string DeviceName = "AIRSPY HF+"; + + public const uint DefaultFrequency = 7200000u; + + public const uint DefaultSampleRate = 768000u; + + public const uint DefaultIFShift = 192000u; + + private uint _deviceSampleRate = 768000u; + + private int _decimationStages; + + private IntPtr _dev; + + private uint _centerFrequency; + + private bool _isStreaming; + + private double _ifShift; + + private GCHandle _gcHandle; + + private DownConverter _ddc; + + private unsafe static readonly airspyhf_sample_cb _airspyhfCallback = AirspyHFDevice.AirSpyHFSamplesAvailable; + + public int DecimationStages + { + get + { + return this._decimationStages; + } + set + { + this._decimationStages = value; + this.SetDeviceFrequency(); + } + } + + public int CalibrationPPB + { + get + { + int result; + NativeMethods.airspyhf_get_calibration(this._dev, out result); + return result; + } + set + { + NativeMethods.airspyhf_set_calibration(this._dev, value); + } + } + + public double SampleRate + { + get + { + return (double)this._deviceSampleRate / (double)(1 << this._decimationStages); + } + } + + public uint Frequency + { + get + { + return this._centerFrequency; + } + set + { + this._centerFrequency = value; + this.SetDeviceFrequency(); + } + } + + public bool IsStreaming + { + get + { + return this._isStreaming; + } + } + + public bool IsHung + { + get + { + if (this._isStreaming) + { + return !NativeMethods.airspyhf_is_streaming(this._dev); + } + return false; + } + } + + public event SamplesAvailableDelegate SamplesAvailable; + + public unsafe AirspyHFDevice() + { + if (NativeMethods.airspyhf_open(out this._dev) != 0) + { + throw new ApplicationException("Cannot open AIRSPY HF+ device"); + } + uint num = default(uint); + if (NativeMethods.airspyhf_get_samplerates(this._dev, &num, 0u) == airspyhf_error.SUCCESS && num != 0) + { + uint[] array = new uint[num]; + uint[] array2 = array; + airspyhf_error airspyhf_error; + fixed (uint* buffer = array2) + { + airspyhf_error = NativeMethods.airspyhf_get_samplerates(this._dev, buffer, num); + } + if (airspyhf_error == airspyhf_error.SUCCESS) + { + this._deviceSampleRate = array[0]; + NativeMethods.airspyhf_set_samplerate(this._dev, this._deviceSampleRate); + } + } + this._gcHandle = GCHandle.Alloc(this); + } + + ~AirspyHFDevice() + { + this.Dispose(); + } + + public void Dispose() + { + if (this._dev != IntPtr.Zero) + { + this.Stop(); + NativeMethods.airspyhf_close(this._dev); + if (this._gcHandle.IsAllocated) + { + this._gcHandle.Free(); + } + this._dev = IntPtr.Zero; + GC.SuppressFinalize(this); + } + } + + internal void FlashCalibration() + { + NativeMethods.airspyhf_flash_calibration(this._dev); + } + + public unsafe void Start() + { + if (!this._isStreaming) + { + if (NativeMethods.airspyhf_start(this._dev, AirspyHFDevice._airspyhfCallback, (IntPtr)this._gcHandle) != 0) + { + throw new ApplicationException("airspy_start_rx() error"); + } + this._isStreaming = true; + } + } + + public void Stop() + { + if (this._isStreaming) + { + NativeMethods.airspyhf_stop(this._dev); + this._isStreaming = false; + } + } + + private void SetDeviceFrequency() + { + if (!(this._dev == IntPtr.Zero)) + { + uint num = this._centerFrequency; + if (this._decimationStages > 1) + { + this._ifShift = -192000.0; + num += 192000; + } + else + { + this._ifShift = 0.0; + } + NativeMethods.airspyhf_set_freq(this._dev, num); + } + } + + protected unsafe virtual void OnComplexSamplesAvailable(Complex* buffer, int length, ulong droppedSamples) + { + SamplesAvailableDelegate samplesAvailable = this.SamplesAvailable; + if (samplesAvailable != null) + { + ComplexSamplesEventArgs complexSamplesEventArgs = new ComplexSamplesEventArgs(); + complexSamplesEventArgs.Buffer = buffer; + complexSamplesEventArgs.Length = length; + complexSamplesEventArgs.DroppedSamples = droppedSamples; + samplesAvailable(this, complexSamplesEventArgs); + } + } + + private unsafe static int AirSpyHFSamplesAvailable(airspyhf_transfer* data) + { + int length = data->sample_count; + Complex* samples = data->samples; + ulong num = data->dropped_samples; + IntPtr ctx = data->ctx; + GCHandle gCHandle = GCHandle.FromIntPtr(ctx); + if (!gCHandle.IsAllocated) + { + return -1; + } + AirspyHFDevice airspyHFDevice = (AirspyHFDevice)gCHandle.Target; + if (airspyHFDevice._decimationStages > 0) + { + int num2 = 1 << airspyHFDevice._decimationStages; + if (airspyHFDevice._ddc == null || airspyHFDevice._ddc.DecimationRatio != num2) + { + airspyHFDevice._ddc = new DownConverter((double)airspyHFDevice._deviceSampleRate, num2); + } + airspyHFDevice._ddc.Frequency = airspyHFDevice._ifShift; + length = airspyHFDevice._ddc.Process(samples, length); + num >>= airspyHFDevice._decimationStages; + } + airspyHFDevice.OnComplexSamplesAvailable(samples, length, num); + return 0; + } + + public unsafe airspyhf_error TunerRead(uint address, byte* data) + { + return NativeMethods.airspyhf_tuner_read(this._dev, address, data); + } + + public airspyhf_error TunerWrite(uint address, uint value) + { + return NativeMethods.airspyhf_tuner_write(this._dev, address, value); + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.AirspyHF/AirspyHFIO.cs b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/AirspyHFIO.cs new file mode 100644 index 0000000..41fd134 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/AirspyHFIO.cs @@ -0,0 +1,242 @@ +using SDRSharp.Common; +using SDRSharp.Radio; +using System; +using System.Windows.Forms; + +namespace SDRSharp.FrontEnds.AirspyHF +{ + public class AirspyHFIO : IFrontendController, IIQStreamController, ITunableSource, IFrontendOffset, IControlAwareObject, ISpectrumProvider, IConfigurationPanelProvider, ISampleRateChangeSource, IDisposable + { + private const float AliasFreeRatio = 1f; + + private bool _disposed; + + private ControllerPanel _gui; + + private AirspyHFDevice _device; + + private ISharpControl _control; + + private long _frequency = 7200000L; + + private int _decimationStages; + + private SamplesAvailableDelegate _callback; + + public bool CanTune + { + get + { + return true; + } + } + + public long MinimumTunableFrequency + { + get + { + return 0L; + } + } + + public long MaximumTunableFrequency + { + get + { + return 1700000000L; + } + } + + public ISharpControl SharpControl + { + get + { + return this._control; + } + } + + public double Samplerate + { + get + { + return 768000.0 / Math.Pow(2.0, (double)this._decimationStages); + } + } + + public long Frequency + { + get + { + return this._frequency; + } + set + { + this._frequency = value; + this.SetDeviceFrequency(); + } + } + + public float UsableSpectrumRatio + { + get + { + return 1f; + } + } + + public UserControl Gui + { + get + { + return this._gui; + } + } + + public bool IsDeviceHung + { + get + { + if (this._device != null) + { + return this._device.IsHung; + } + return false; + } + } + + public int Offset + { + get + { + return 0; + } + } + + public int DecimationStages + { + get + { + return this._decimationStages; + } + set + { + this._decimationStages = value; + if (this._device != null) + { + this._device.DecimationStages = value; + } + if (this._gui != null) + { + this.NotifySampleRateChanged(); + } + } + } + + public event EventHandler SampleRateChanged; + + public AirspyHFIO() + { + this._gui = new ControllerPanel(this); + } + + ~AirspyHFIO() + { + this.Dispose(); + } + + public void Dispose() + { + if (!this._disposed) + { + this._disposed = true; + this.Close(); + GC.SuppressFinalize(this); + } + } + + public void Open() + { + this._device = new AirspyHFDevice(); + this._device.DecimationStages = this._decimationStages; + this._device.Frequency = (uint)this._frequency; + this._gui.Device = this._device; + this._device.SamplesAvailable += this.Device_SamplesAvailable; + } + + public void Close() + { + if (this._device != null) + { + this._gui.Device = null; + this._device.SamplesAvailable -= this.Device_SamplesAvailable; + this._device.Dispose(); + this._device = null; + } + } + + public unsafe void Start(SamplesAvailableDelegate callback) + { + this._callback = callback; + try + { + if (this._device == null) + { + this.Open(); + } + this._device.Start(); + this.SetDeviceFrequency(); + } + catch + { + this.Close(); + throw; + } + } + + public void Stop() + { + if (this._device != null) + { + this._device.Stop(); + } + } + + public void ShowSettingGUI(IWin32Window parent) + { + } + + public void HideSettingGUI() + { + } + + public void SetControl(object control) + { + this._control = (ISharpControl)control; + } + + private void SetDeviceFrequency() + { + if (this._device != null) + { + this._device.Frequency = (uint)this._frequency; + } + } + + private unsafe void Device_SamplesAvailable(object sender, ComplexSamplesEventArgs e) + { + this._callback(this, e.Buffer, e.Length); + } + + public void NotifySampleRateChanged() + { + this._gui.BeginInvoke((Action)delegate + { + EventHandler sampleRateChanged = this.SampleRateChanged; + if (sampleRateChanged != null) + { + sampleRateChanged(this, EventArgs.Empty); + } + }); + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.AirspyHF/ControllerPanel.cs b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/ControllerPanel.cs new file mode 100644 index 0000000..1fef24d --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/ControllerPanel.cs @@ -0,0 +1,309 @@ +using SDRSharp.Radio; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.Windows.Forms; + +namespace SDRSharp.FrontEnds.AirspyHF +{ + public class ControllerPanel : UserControl + { + private AirspyHFIO _owner; + + private AirspyHFDevice _device; + + private IContainer components; + + private Label label18; + + private TableLayoutPanel tableLayoutPanel; + + private Label label1; + + private TextBox valueTextBox; + + private TextBox addressTextBox; + + private Button readButton; + + private Button writeButton; + + private Label label2; + + private ComboBox spanComboBox; + + private TableLayoutPanel tableLayoutPanel1; + + private Label label3; + + private NumericUpDown calibrationNumericUpDown; + + private Button flashButton; + + public AirspyHFDevice Device + { + get + { + return this._device; + } + set + { + this._device = value; + if (this._device != null) + { + this.calibrationNumericUpDown.Value = this._device.CalibrationPPB; + } + else + { + this.calibrationNumericUpDown.Value = decimal.Zero; + } + } + } + + public ControllerPanel(AirspyHFIO owner) + { + this._owner = owner; + this.InitializeComponent(); + for (int i = 0; i < 5; i++) + { + double num = (double)((float)(double)(768000u >> i) * this._owner.UsableSpectrumRatio) * 0.001; + this.spanComboBox.Items.Add(num + " kHz"); + } + this.spanComboBox.SelectedIndex = Utils.GetIntSetting("airspyhf.decimation", 0); + if (Utils.GetIntSetting("airspyhf.debug", 0) == 0) + { + this.tableLayoutPanel.Visible = false; + base.Height -= this.tableLayoutPanel.Height; + } + } + + private void spanComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + this._owner.DecimationStages = this.spanComboBox.SelectedIndex; + Utils.SaveSetting("airspyhf.decimation", this.spanComboBox.SelectedIndex); + } + + private void calibrationNumericUpDown_ValueChanged(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.CalibrationPPB = (int)this.calibrationNumericUpDown.Value; + } + } + + private void flashButton_Click(object sender, EventArgs e) + { + if (this._device != null) + { + this._device.FlashCalibration(); + } + } + + private unsafe void readButton_Click(object sender, EventArgs e) + { + if (this._device != null && this.addressTextBox.Text.Length > 0) + { + uint address = this.ParseHex(this.addressTextBox.Text); + byte[] array = new byte[6]; + byte[] array2 = array; + fixed (byte* data = array2) + { + this._device.TunerRead(address, data); + } + uint num = (uint)(array[0] << 16 | array[1] << 8 | array[2]); + this.valueTextBox.Text = "0x" + string.Format("{0:x6}", num); + } + } + + private void writeButton_Click(object sender, EventArgs e) + { + if (this._device != null && this.addressTextBox.Text.Length > 0 && this.valueTextBox.Text.Length > 0) + { + uint address = this.ParseHex(this.addressTextBox.Text); + uint value = this.ParseHex(this.valueTextBox.Text); + this._device.TunerWrite(address, value); + } + } + + private uint ParseHex(string s) + { + s = s.Replace("0X", string.Empty).Replace("0x", string.Empty); + return uint.Parse(s, NumberStyles.HexNumber); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + { + this.components.Dispose(); + } + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.tableLayoutPanel = new TableLayoutPanel(); + this.valueTextBox = new TextBox(); + this.label18 = new Label(); + this.label1 = new Label(); + this.addressTextBox = new TextBox(); + this.readButton = new Button(); + this.writeButton = new Button(); + this.label2 = new Label(); + this.spanComboBox = new ComboBox(); + this.tableLayoutPanel1 = new TableLayoutPanel(); + this.label3 = new Label(); + this.calibrationNumericUpDown = new NumericUpDown(); + this.flashButton = new Button(); + this.tableLayoutPanel.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); + ((ISupportInitialize)this.calibrationNumericUpDown).BeginInit(); + base.SuspendLayout(); + this.tableLayoutPanel.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right); + this.tableLayoutPanel.ColumnCount = 4; + this.tableLayoutPanel1.SetColumnSpan(this.tableLayoutPanel, 2); + this.tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f)); + this.tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f)); + this.tableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel.Controls.Add(this.valueTextBox, 1, 2); + this.tableLayoutPanel.Controls.Add(this.label18, 0, 1); + this.tableLayoutPanel.Controls.Add(this.label1, 1, 1); + this.tableLayoutPanel.Controls.Add(this.addressTextBox, 0, 2); + this.tableLayoutPanel.Controls.Add(this.readButton, 2, 2); + this.tableLayoutPanel.Controls.Add(this.writeButton, 3, 2); + this.tableLayoutPanel.Controls.Add(this.label3, 0, 0); + this.tableLayoutPanel.Controls.Add(this.calibrationNumericUpDown, 1, 0); + this.tableLayoutPanel.Controls.Add(this.flashButton, 2, 0); + this.tableLayoutPanel.Location = new Point(0, 27); + this.tableLayoutPanel.Margin = new Padding(0); + this.tableLayoutPanel.Name = "tableLayoutPanel"; + this.tableLayoutPanel.RowCount = 3; + this.tableLayoutPanel.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.tableLayoutPanel.Size = new Size(202, 73); + this.tableLayoutPanel.TabIndex = 63; + this.valueTextBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.valueTextBox.Location = new Point(78, 47); + this.valueTextBox.Name = "valueTextBox"; + this.valueTextBox.Size = new Size(69, 20); + this.valueTextBox.TabIndex = 37; + this.label18.Anchor = AnchorStyles.Left; + this.label18.AutoSize = true; + this.label18.Location = new Point(0, 29); + this.label18.Margin = new Padding(0); + this.label18.Name = "label18"; + this.label18.Size = new Size(45, 13); + this.label18.TabIndex = 34; + this.label18.Text = "Address"; + this.label1.Anchor = AnchorStyles.Left; + this.label1.AutoSize = true; + this.label1.Location = new Point(75, 29); + this.label1.Margin = new Padding(0); + this.label1.Name = "label1"; + this.label1.Size = new Size(34, 13); + this.label1.TabIndex = 35; + this.label1.Text = "Value"; + this.addressTextBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.addressTextBox.Location = new Point(3, 47); + this.addressTextBox.Name = "addressTextBox"; + this.addressTextBox.Size = new Size(69, 20); + this.addressTextBox.TabIndex = 36; + this.readButton.Anchor = AnchorStyles.None; + this.readButton.Location = new Point(153, 47); + this.readButton.Name = "readButton"; + this.readButton.Size = new Size(20, 20); + this.readButton.TabIndex = 38; + this.readButton.Text = "R"; + this.readButton.UseVisualStyleBackColor = true; + this.readButton.Click += this.readButton_Click; + this.writeButton.Anchor = AnchorStyles.None; + this.writeButton.Location = new Point(179, 47); + this.writeButton.Name = "writeButton"; + this.writeButton.Size = new Size(20, 20); + this.writeButton.TabIndex = 39; + this.writeButton.Text = "W"; + this.writeButton.UseVisualStyleBackColor = true; + this.writeButton.Click += this.writeButton_Click; + this.label2.Anchor = AnchorStyles.Left; + this.label2.AutoSize = true; + this.label2.Location = new Point(3, 7); + this.label2.Name = "label2"; + this.label2.Size = new Size(57, 13); + this.label2.TabIndex = 40; + this.label2.Text = "Bandwidth"; + this.spanComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.spanComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.spanComboBox.FormattingEnabled = true; + this.spanComboBox.Location = new Point(79, 3); + this.spanComboBox.Name = "spanComboBox"; + this.spanComboBox.Size = new Size(120, 21); + this.spanComboBox.TabIndex = 41; + this.spanComboBox.SelectedIndexChanged += this.spanComboBox_SelectedIndexChanged; + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 37.62376f)); + this.tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 62.37624f)); + this.tableLayoutPanel1.Controls.Add(this.label2, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.spanComboBox, 1, 0); + this.tableLayoutPanel1.Dock = DockStyle.Fill; + this.tableLayoutPanel1.Location = new Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.tableLayoutPanel1.Size = new Size(202, 100); + this.tableLayoutPanel1.TabIndex = 64; + this.label3.Anchor = AnchorStyles.Left; + this.label3.AutoSize = true; + this.label3.Location = new Point(3, 8); + this.label3.Name = "label3"; + this.label3.Size = new Size(57, 13); + this.label3.TabIndex = 40; + this.label3.Text = "CLK (PPB)"; + this.calibrationNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.calibrationNumericUpDown.Location = new Point(78, 4); + this.calibrationNumericUpDown.Maximum = new decimal(new int[4] + { + 10000, + 0, + 0, + 0 + }); + this.calibrationNumericUpDown.Minimum = new decimal(new int[4] + { + 10000, + 0, + 0, + -2147483648 + }); + this.calibrationNumericUpDown.Name = "calibrationNumericUpDown"; + this.calibrationNumericUpDown.Size = new Size(69, 20); + this.calibrationNumericUpDown.TabIndex = 41; + this.calibrationNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.calibrationNumericUpDown.ValueChanged += this.calibrationNumericUpDown_ValueChanged; + this.flashButton.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.tableLayoutPanel.SetColumnSpan(this.flashButton, 2); + this.flashButton.Location = new Point(153, 3); + this.flashButton.Name = "flashButton"; + this.flashButton.Size = new Size(46, 23); + this.flashButton.TabIndex = 42; + this.flashButton.Text = "Flash"; + this.flashButton.UseVisualStyleBackColor = true; + this.flashButton.Click += this.flashButton_Click; + base.AutoScaleDimensions = new SizeF(6f, 13f); + base.AutoScaleMode = AutoScaleMode.Font; + base.Controls.Add(this.tableLayoutPanel1); + base.Name = "ControllerPanel"; + base.Size = new Size(202, 100); + this.tableLayoutPanel.ResumeLayout(false); + this.tableLayoutPanel.PerformLayout(); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + ((ISupportInitialize)this.calibrationNumericUpDown).EndInit(); + base.ResumeLayout(false); + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.AirspyHF/ControllerPanel.resx b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/ControllerPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/ControllerPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SDRSharp/SDRSharp.FrontEnds.AirspyHF/NativeMethods.cs b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/NativeMethods.cs new file mode 100644 index 0000000..79f0946 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/NativeMethods.cs @@ -0,0 +1,56 @@ +using System; +using System.Runtime.InteropServices; + +namespace SDRSharp.FrontEnds.AirspyHF +{ + public static class NativeMethods + { + private const string LibAirspyHF = "airspyhf"; + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_open(out IntPtr dev); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_close(IntPtr dev); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_start(IntPtr dev, airspyhf_sample_cb cb, IntPtr ctx); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_stop(IntPtr dev); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool airspyhf_is_streaming(IntPtr dev); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_set_freq(IntPtr dev, uint freq_hz); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_i2c_write(IntPtr device, byte register_number, byte value); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_i2c_read(IntPtr device, byte register_number, out byte value); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_tuner_write(IntPtr device, uint address, uint value); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public unsafe static extern airspyhf_error airspyhf_tuner_read(IntPtr device, uint address, byte* data); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public unsafe static extern airspyhf_error airspyhf_get_samplerates(IntPtr device, uint* buffer, uint len); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_set_samplerate(IntPtr device, uint samplerate); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_get_calibration(IntPtr device, out int ppb); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_set_calibration(IntPtr device, int ppb); + + [DllImport("airspyhf", CallingConvention = CallingConvention.Cdecl)] + public static extern airspyhf_error airspyhf_flash_calibration(IntPtr dev); + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_error.cs b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_error.cs new file mode 100644 index 0000000..633b8f5 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_error.cs @@ -0,0 +1,8 @@ +namespace SDRSharp.FrontEnds.AirspyHF +{ + public enum airspyhf_error + { + SUCCESS, + ERROR = -1 + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_sample_cb.cs b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_sample_cb.cs new file mode 100644 index 0000000..a080688 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_sample_cb.cs @@ -0,0 +1,7 @@ +using System.Runtime.InteropServices; + +namespace SDRSharp.FrontEnds.AirspyHF +{ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public unsafe delegate int airspyhf_sample_cb(airspyhf_transfer* ptr); +} diff --git a/SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_transfer.cs b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_transfer.cs new file mode 100644 index 0000000..7bfb3b0 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.AirspyHF/airspyhf_transfer.cs @@ -0,0 +1,18 @@ +using SDRSharp.Radio; +using System; + +namespace SDRSharp.FrontEnds.AirspyHF +{ + public struct airspyhf_transfer + { + public IntPtr device; + + public IntPtr ctx; + + public unsafe Complex* samples; + + public int sample_count; + + public ulong dropped_samples; + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/ClientHandshake.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/ClientHandshake.cs new file mode 100644 index 0000000..020acd0 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/ClientHandshake.cs @@ -0,0 +1,9 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public struct ClientHandshake + { + public uint ProtocolVersion; + + public uint ClientNameLength; + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/ClientSync.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/ClientSync.cs new file mode 100644 index 0000000..6a96d1c --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/ClientSync.cs @@ -0,0 +1,23 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public struct ClientSync + { + public uint CanControl; + + public uint Gain; + + public uint DeviceCenterFrequency; + + public uint IQCenterFrequency; + + public uint FFTCenterFrequency; + + public uint MinimumIQCenterFrequency; + + public uint MaximumIQCenterFrequency; + + public uint MinimumFFTCenterFrequency; + + public uint MaximumFFTCenterFrequency; + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/CommandHeader.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/CommandHeader.cs new file mode 100644 index 0000000..00f5966 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/CommandHeader.cs @@ -0,0 +1,9 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public struct CommandHeader + { + public CommandType CommandType; + + public uint BodySize; + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/CommandType.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/CommandType.cs new file mode 100644 index 0000000..4f9ca83 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/CommandType.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public enum CommandType : uint + { + CMD_HELLO, + CMD_GET_SETTING, + CMD_SET_SETTING, + CMD_PING + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/Constants.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/Constants.cs new file mode 100644 index 0000000..3e0f73c --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/Constants.cs @@ -0,0 +1,42 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public static class Constants + { + public const uint SPYSERVER_PROTOCOL_VERSION = 33556024u; + + public const uint SPYSERVER_MAX_COMMAND_BODY_SIZE = 256u; + + public const uint SPYSERVER_MAX_MESSAGE_BODY_SIZE = 1048576u; + + public const uint SPYSERVER_MAX_DISPLAY_PIXELS = 32768u; + + public const uint SPYSERVER_MIN_DISPLAY_PIXELS = 100u; + + public const uint SPYSERVER_MAX_FFT_DB_RANGE = 150u; + + public const uint SPYSERVER_MIN_FFT_DB_RANGE = 10u; + + public const uint SPYSERVER_MAX_FFT_DB_OFFSET = 100u; + + public const uint SPYSERVER_DIGITAL_GAIN_AUTO = uint.MaxValue; + + public const int SPYSERVER_MESSAGE_TYPE_BITS = 16; + + public const uint SPYSERVER_MESSAGE_TYPE_MASK = 65535u; + + public static string GetDeviceName(DeviceType deviceID) + { + switch (deviceID) + { + case DeviceType.DEVICE_AIRSPY_ONE: + return "Airspy One"; + case DeviceType.DEVICE_AIRSPY_HF: + return "Airspy HF+"; + case DeviceType.DEVICE_RTLSDR: + return "RTL-SDR"; + default: + return "Unknown"; + } + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/ControllerPanel.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/ControllerPanel.cs new file mode 100644 index 0000000..2a7d523 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/ControllerPanel.cs @@ -0,0 +1,579 @@ +using SDRSharp.Radio; +using System; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Text; +using System.Windows.Forms; + +namespace SDRSharp.FrontEnds.SpyServer +{ + public class ControllerPanel : UserControl + { + private const int DefaultPort = 5555; + + private readonly string _historyFileName = ".\\spybrowser.history"; + + private SpyServerIO _owner; + + private float _rate; + + private int _minDecimation; + + private IContainer components; + + private TableLayoutPanel hostTableLayoutPanel; + + private Button connectButton; + + private TableLayoutPanel deviceInfoTableLayoutPanel; + + private TableLayoutPanel bandwidthTableLayoutPanel; + + private TableLayoutPanel iqFormatTableLayoutPanel; + + private TableLayoutPanel gainTableLayoutPanel; + + private Label label1; + + private ComboBox bandwidthComboBox; + + private Label gainLabel; + + private Label label2; + + private TrackBar gainTrackBar; + + private Label deviceSerialLabel; + + private Label deviceNameLabel; + + private CheckBox useFullIQCheckBox; + + private Label bitrateLabel; + + private Timer downStreamTimer; + + private Label label3; + + private ComboBox streamFormatComboBox; + + private ComboBox uriComboBox; + + private Label serverVersionLabel; + + public string Host + { + get + { + Uri uri = new Uri(this.uriComboBox.Text); + return uri.Host; + } + } + + public int Port + { + get + { + Uri uri = new Uri(this.uriComboBox.Text); + if (uri.Port > 0) + { + return uri.Port; + } + return 5555; + } + } + + public bool UseFullIQ + { + get + { + return this.useFullIQCheckBox.Checked; + } + set + { + this.useFullIQCheckBox.Checked = value; + } + } + + public int Decimation + { + get + { + return Math.Max(0, this.bandwidthComboBox.SelectedIndex); + } + } + + public ControllerPanel(SpyServerIO owner) + { + this._owner = owner; + this.InitializeComponent(); + try + { + this.uriComboBox.Items.AddRange(File.ReadAllLines(this._historyFileName)); + } + catch + { + } + this.uriComboBox.Text = Utils.GetStringSetting("spyserver.uri", "sdr://127.0.0.1:5555"); + this.streamFormatComboBox.SelectedIndex = Utils.GetIntSetting("spyserver.streamFormat", 3); + this.useFullIQCheckBox.Checked = Utils.GetBooleanSetting("spyserver.fullIQ", false); + this.useFullIQCheckBox_CheckStateChanged(null, null); + this.streamFormatComboBox_SelectedIndexChanged(null, null); + this.useFullIQCheckBox_CheckStateChanged(null, null); + this.uriComboBox.SelectedValueChanged += this.connectButton_Click; + } + + public void SaveSettings() + { + Utils.SaveSetting("spyserver.uri", this.uriComboBox.Text); + Utils.SaveSetting("spyserver.streamFormat", this.streamFormatComboBox.SelectedIndex); + Utils.SaveSetting("spyserver.fullIQ", this.useFullIQCheckBox.Checked); + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < this.uriComboBox.Items.Count; i++) + { + stringBuilder.AppendLine(this.uriComboBox.Items[i].ToString()); + } + File.WriteAllText(this._historyFileName, stringBuilder.ToString()); + } + + public void Force8bit() + { + this.streamFormatComboBox.SelectedIndex = 3; + } + + public void EnableURI(bool enable) + { + this.uriComboBox.Enabled = enable; + } + + public void EnableFullIQ(bool enable) + { + if (base.InvokeRequired) + { + this.useFullIQCheckBox.Enabled = enable; + } + else if (base.IsHandleCreated) + { + base.BeginInvoke((Action)delegate + { + this.useFullIQCheckBox.Enabled = enable; + }); + } + } + + public void UpdateDisplaySections(bool connected, bool bandwidth, bool format, bool gain) + { + int num = this.hostTableLayoutPanel.Height; + this.deviceInfoTableLayoutPanel.Visible = connected; + this.bandwidthTableLayoutPanel.Visible = bandwidth; + this.iqFormatTableLayoutPanel.Visible = format; + this.gainTableLayoutPanel.Visible = gain; + if (connected) + { + num += this.deviceInfoTableLayoutPanel.Height; + } + if (bandwidth) + { + num += this.bandwidthTableLayoutPanel.Height; + } + if (format) + { + num += this.iqFormatTableLayoutPanel.Height; + } + if (gain) + { + num += this.gainTableLayoutPanel.Height; + } + base.Height = num; + } + + public void UpdateGain(int value, bool canControl) + { + if (value >= this.gainTrackBar.Minimum && value <= this.gainTrackBar.Maximum) + { + this.gainTrackBar.Value = value; + } + this.gainTrackBar.Enabled = canControl; + } + + internal void UpdateGain(object gain, bool canControl) + { + throw new NotImplementedException(); + } + + private void connectButton_Click(object sender, EventArgs e) + { + try + { + if (this._owner.Connected) + { + this._owner.Disconnect(); + } + else + { + this._owner.Connect(); + this.UpdateHistory(); + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + + private void UpdateBandwidthOptions(int[] bandwidthOptions) + { + this.bandwidthComboBox.Items.Clear(); + for (int i = 0; i < bandwidthOptions.Length; i++) + { + string frequencyDisplay = Utils.GetFrequencyDisplay(bandwidthOptions[i], true); + this.bandwidthComboBox.Items.Add(frequencyDisplay); + } + if (bandwidthOptions.Length != 0) + { + this.bandwidthComboBox.SelectedIndex = 0; + } + } + + public void UpdateControlOptions(string deviceName, string deviceSerial, string serverVersion, int[] bandwidthOptions, int minDecimation, int maxGain) + { + this.deviceNameLabel.Text = "Device: " + deviceName; + this.deviceSerialLabel.Text = "SN: " + deviceSerial; + this.serverVersionLabel.Text = "Server: " + serverVersion; + this._minDecimation = minDecimation; + this.UpdateBandwidthOptions(bandwidthOptions); + this._owner.SetDecimation(this.bandwidthComboBox.SelectedIndex); + this._owner.SetFormat((StreamFormat)(4 - this.streamFormatComboBox.SelectedIndex)); + this.gainTrackBar.ValueChanged -= this.gainTrackBar_ValueChanged; + this.gainTrackBar.Maximum = maxGain; + this.gainTrackBar.Value = 0; + this.gainTrackBar.ValueChanged += this.gainTrackBar_ValueChanged; + this.gainLabel.Text = "0"; + } + + private void bandwidthComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (this.bandwidthComboBox.SelectedIndex < this._minDecimation) + { + this.UseFullIQ = false; + this.EnableFullIQ(false); + } + else + { + this.EnableFullIQ(!this._owner.Control.IsPlaying); + } + this._owner.SetDecimation(this.bandwidthComboBox.SelectedIndex); + } + + private void streamFormatComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (this._owner != null) + { + this._owner.SetFormat((StreamFormat)(4 - this.streamFormatComboBox.SelectedIndex)); + } + } + + private void gainTrackBar_ValueChanged(object sender, EventArgs e) + { + this.gainLabel.Text = this.gainTrackBar.Value.ToString(); + this._owner.SetGain(this.gainTrackBar.Value); + } + + private void useFullIQCheckBox_CheckStateChanged(object sender, EventArgs e) + { + this._owner.FFTEnabled = !this.useFullIQCheckBox.Checked; + } + + private void downStreamTimer_Tick(object sender, EventArgs e) + { + long downstreamBytes = this._owner.GetDownstreamBytes(); + if (downstreamBytes == 0L) + { + this.bitrateLabel.Text = "0 kB/s"; + this._rate = 0f; + } + else + { + float num = (float)downstreamBytes / (0.001f * (float)this.downStreamTimer.Interval); + float num2 = num - this._rate; + float num3 = (num2 > 0f) ? 0.8f : 0.2f; + this._rate += num3 * num2; + if (this._rate < 1000000f) + { + this.bitrateLabel.Text = Math.Round((double)(this._rate * 0.001f)) + " kB/s"; + } + else + { + this.bitrateLabel.Text = Math.Round((double)(this._rate * 1E-06f), 1) + " MB/s"; + } + } + } + + private void uriComboBox_KeyDown(object sender, KeyEventArgs e) + { + if (e.KeyCode == Keys.Return) + { + this.connectButton_Click(sender, e); + } + } + + private void UpdateHistory() + { + string text = this.uriComboBox.Text; + Uri uri = new Uri(text); + if (uri.IsWellFormedOriginalString()) + { + for (int i = 0; i < this.uriComboBox.Items.Count; i++) + { + Uri uri2 = new Uri(this.uriComboBox.Items[i].ToString()); + if (string.Compare(uri2.AbsoluteUri, uri.AbsoluteUri) == 0) + { + return; + } + } + this.uriComboBox.Items.Add(uri.AbsoluteUri); + } + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + { + this.components.Dispose(); + } + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = new Container(); + this.hostTableLayoutPanel = new TableLayoutPanel(); + this.connectButton = new Button(); + this.uriComboBox = new ComboBox(); + this.bandwidthTableLayoutPanel = new TableLayoutPanel(); + this.label1 = new Label(); + this.bandwidthComboBox = new ComboBox(); + this.label3 = new Label(); + this.streamFormatComboBox = new ComboBox(); + this.gainTableLayoutPanel = new TableLayoutPanel(); + this.gainLabel = new Label(); + this.label2 = new Label(); + this.gainTrackBar = new TrackBar(); + this.deviceInfoTableLayoutPanel = new TableLayoutPanel(); + this.bitrateLabel = new Label(); + this.deviceSerialLabel = new Label(); + this.deviceNameLabel = new Label(); + this.useFullIQCheckBox = new CheckBox(); + this.downStreamTimer = new Timer(this.components); + this.iqFormatTableLayoutPanel = new TableLayoutPanel(); + this.serverVersionLabel = new Label(); + this.hostTableLayoutPanel.SuspendLayout(); + this.bandwidthTableLayoutPanel.SuspendLayout(); + this.gainTableLayoutPanel.SuspendLayout(); + ((ISupportInitialize)this.gainTrackBar).BeginInit(); + this.deviceInfoTableLayoutPanel.SuspendLayout(); + this.iqFormatTableLayoutPanel.SuspendLayout(); + base.SuspendLayout(); + this.hostTableLayoutPanel.ColumnCount = 2; + this.hostTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.hostTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 32f)); + this.hostTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20f)); + this.hostTableLayoutPanel.Controls.Add(this.connectButton, 1, 0); + this.hostTableLayoutPanel.Controls.Add(this.uriComboBox, 0, 0); + this.hostTableLayoutPanel.Dock = DockStyle.Top; + this.hostTableLayoutPanel.Location = new Point(0, 0); + this.hostTableLayoutPanel.Name = "hostTableLayoutPanel"; + this.hostTableLayoutPanel.RowCount = 1; + this.hostTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.hostTableLayoutPanel.Size = new Size(202, 30); + this.hostTableLayoutPanel.TabIndex = 64; + this.connectButton.Location = new Point(173, 3); + this.connectButton.Name = "connectButton"; + this.connectButton.Size = new Size(25, 23); + this.connectButton.TabIndex = 2; + this.connectButton.Text = "C"; + this.connectButton.UseVisualStyleBackColor = true; + this.connectButton.Click += this.connectButton_Click; + this.uriComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.uriComboBox.FormattingEnabled = true; + this.uriComboBox.Location = new Point(3, 4); + this.uriComboBox.Name = "uriComboBox"; + this.uriComboBox.Size = new Size(164, 21); + this.uriComboBox.TabIndex = 3; + this.uriComboBox.KeyDown += this.uriComboBox_KeyDown; + this.bandwidthTableLayoutPanel.ColumnCount = 2; + this.bandwidthTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 40f)); + this.bandwidthTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 60f)); + this.bandwidthTableLayoutPanel.Controls.Add(this.label1, 0, 0); + this.bandwidthTableLayoutPanel.Controls.Add(this.bandwidthComboBox, 1, 0); + this.bandwidthTableLayoutPanel.Dock = DockStyle.Top; + this.bandwidthTableLayoutPanel.Location = new Point(0, 106); + this.bandwidthTableLayoutPanel.Name = "bandwidthTableLayoutPanel"; + this.bandwidthTableLayoutPanel.RowCount = 1; + this.bandwidthTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.bandwidthTableLayoutPanel.Size = new Size(202, 31); + this.bandwidthTableLayoutPanel.TabIndex = 65; + this.label1.Anchor = AnchorStyles.Left; + this.label1.AutoSize = true; + this.label1.Location = new Point(3, 9); + this.label1.Name = "label1"; + this.label1.Size = new Size(57, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Bandwidth"; + this.bandwidthComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.bandwidthComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.bandwidthComboBox.FormattingEnabled = true; + this.bandwidthComboBox.Location = new Point(83, 5); + this.bandwidthComboBox.Name = "bandwidthComboBox"; + this.bandwidthComboBox.Size = new Size(116, 21); + this.bandwidthComboBox.TabIndex = 1; + this.bandwidthComboBox.SelectedIndexChanged += this.bandwidthComboBox_SelectedIndexChanged; + this.label3.Anchor = AnchorStyles.Left; + this.label3.AutoSize = true; + this.label3.Location = new Point(3, 9); + this.label3.Name = "label3"; + this.label3.Size = new Size(53, 13); + this.label3.TabIndex = 2; + this.label3.Text = "IQ Format"; + this.streamFormatComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.streamFormatComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.streamFormatComboBox.FormattingEnabled = true; + this.streamFormatComboBox.Items.AddRange(new object[4] + { + "Float 32bit", + "PCM 24bit", + "PCM 16bit", + "PCM 8bit" + }); + this.streamFormatComboBox.Location = new Point(83, 5); + this.streamFormatComboBox.Name = "streamFormatComboBox"; + this.streamFormatComboBox.Size = new Size(116, 21); + this.streamFormatComboBox.TabIndex = 1; + this.streamFormatComboBox.SelectedIndexChanged += this.streamFormatComboBox_SelectedIndexChanged; + this.gainTableLayoutPanel.ColumnCount = 2; + this.gainTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f)); + this.gainTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f)); + this.gainTableLayoutPanel.Controls.Add(this.gainLabel, 1, 0); + this.gainTableLayoutPanel.Controls.Add(this.label2, 0, 0); + this.gainTableLayoutPanel.Controls.Add(this.gainTrackBar, 0, 1); + this.gainTableLayoutPanel.Dock = DockStyle.Top; + this.gainTableLayoutPanel.Location = new Point(0, 169); + this.gainTableLayoutPanel.Name = "gainTableLayoutPanel"; + this.gainTableLayoutPanel.RowCount = 2; + this.gainTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.gainTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.gainTableLayoutPanel.Size = new Size(202, 57); + this.gainTableLayoutPanel.TabIndex = 66; + this.gainLabel.Anchor = AnchorStyles.Right; + this.gainLabel.AutoSize = true; + this.gainLabel.Location = new Point(180, 0); + this.gainLabel.Name = "gainLabel"; + this.gainLabel.Size = new Size(19, 13); + this.gainLabel.TabIndex = 1; + this.gainLabel.Text = "10"; + this.label2.Anchor = AnchorStyles.Left; + this.label2.AutoSize = true; + this.label2.Location = new Point(3, 0); + this.label2.Name = "label2"; + this.label2.Size = new Size(29, 13); + this.label2.TabIndex = 0; + this.label2.Text = "Gain"; + this.gainTrackBar.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right); + this.gainTableLayoutPanel.SetColumnSpan(this.gainTrackBar, 2); + this.gainTrackBar.Location = new Point(3, 16); + this.gainTrackBar.Name = "gainTrackBar"; + this.gainTrackBar.Size = new Size(196, 38); + this.gainTrackBar.TabIndex = 2; + this.gainTrackBar.ValueChanged += this.gainTrackBar_ValueChanged; + this.deviceInfoTableLayoutPanel.ColumnCount = 2; + this.deviceInfoTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f)); + this.deviceInfoTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f)); + this.deviceInfoTableLayoutPanel.Controls.Add(this.deviceSerialLabel, 0, 0); + this.deviceInfoTableLayoutPanel.Controls.Add(this.deviceNameLabel, 0, 0); + this.deviceInfoTableLayoutPanel.Controls.Add(this.useFullIQCheckBox, 0, 2); + this.deviceInfoTableLayoutPanel.Controls.Add(this.bitrateLabel, 1, 1); + this.deviceInfoTableLayoutPanel.Controls.Add(this.serverVersionLabel, 0, 1); + this.deviceInfoTableLayoutPanel.Dock = DockStyle.Top; + this.deviceInfoTableLayoutPanel.Location = new Point(0, 30); + this.deviceInfoTableLayoutPanel.Name = "deviceInfoTableLayoutPanel"; + this.deviceInfoTableLayoutPanel.RowCount = 3; + this.deviceInfoTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33333f)); + this.deviceInfoTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33333f)); + this.deviceInfoTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 33.33333f)); + this.deviceInfoTableLayoutPanel.Size = new Size(202, 76); + this.deviceInfoTableLayoutPanel.TabIndex = 67; + this.bitrateLabel.Anchor = AnchorStyles.Right; + this.bitrateLabel.AutoSize = true; + this.bitrateLabel.Location = new Point(160, 31); + this.bitrateLabel.Name = "bitrateLabel"; + this.bitrateLabel.Size = new Size(39, 13); + this.bitrateLabel.TabIndex = 4; + this.bitrateLabel.Text = "0 kbps"; + this.deviceSerialLabel.Anchor = AnchorStyles.Right; + this.deviceSerialLabel.AutoSize = true; + this.deviceSerialLabel.Location = new Point(165, 6); + this.deviceSerialLabel.Name = "deviceSerialLabel"; + this.deviceSerialLabel.Size = new Size(34, 13); + this.deviceSerialLabel.TabIndex = 2; + this.deviceSerialLabel.Text = "SN: 0"; + this.deviceNameLabel.Anchor = AnchorStyles.Left; + this.deviceNameLabel.AutoSize = true; + this.deviceNameLabel.Location = new Point(3, 6); + this.deviceNameLabel.Name = "deviceNameLabel"; + this.deviceNameLabel.Size = new Size(58, 13); + this.deviceNameLabel.TabIndex = 1; + this.deviceNameLabel.Text = "Airspy One"; + this.useFullIQCheckBox.AutoSize = true; + this.useFullIQCheckBox.Location = new Point(3, 53); + this.useFullIQCheckBox.Name = "useFullIQCheckBox"; + this.useFullIQCheckBox.Size = new Size(75, 17); + this.useFullIQCheckBox.TabIndex = 3; + this.useFullIQCheckBox.Text = "Use full IQ"; + this.useFullIQCheckBox.UseVisualStyleBackColor = true; + this.useFullIQCheckBox.CheckStateChanged += this.useFullIQCheckBox_CheckStateChanged; + this.downStreamTimer.Enabled = true; + this.downStreamTimer.Interval = 500; + this.downStreamTimer.Tick += this.downStreamTimer_Tick; + this.iqFormatTableLayoutPanel.ColumnCount = 2; + this.iqFormatTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 40f)); + this.iqFormatTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 60f)); + this.iqFormatTableLayoutPanel.Controls.Add(this.label3, 0, 0); + this.iqFormatTableLayoutPanel.Controls.Add(this.streamFormatComboBox, 1, 0); + this.iqFormatTableLayoutPanel.Dock = DockStyle.Top; + this.iqFormatTableLayoutPanel.Location = new Point(0, 137); + this.iqFormatTableLayoutPanel.Name = "iqFormatTableLayoutPanel"; + this.iqFormatTableLayoutPanel.RowCount = 1; + this.iqFormatTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.iqFormatTableLayoutPanel.Size = new Size(202, 32); + this.iqFormatTableLayoutPanel.TabIndex = 68; + this.serverVersionLabel.Anchor = AnchorStyles.Left; + this.serverVersionLabel.AutoSize = true; + this.serverVersionLabel.Location = new Point(3, 31); + this.serverVersionLabel.Name = "serverVersionLabel"; + this.serverVersionLabel.Size = new Size(86, 13); + this.serverVersionLabel.TabIndex = 5; + this.serverVersionLabel.Text = "Server: 2.0.1606"; + base.AutoScaleDimensions = new SizeF(6f, 13f); + base.AutoScaleMode = AutoScaleMode.Font; + base.Controls.Add(this.gainTableLayoutPanel); + base.Controls.Add(this.iqFormatTableLayoutPanel); + base.Controls.Add(this.bandwidthTableLayoutPanel); + base.Controls.Add(this.deviceInfoTableLayoutPanel); + base.Controls.Add(this.hostTableLayoutPanel); + base.Name = "ControllerPanel"; + base.Size = new Size(202, 30); + this.hostTableLayoutPanel.ResumeLayout(false); + this.bandwidthTableLayoutPanel.ResumeLayout(false); + this.bandwidthTableLayoutPanel.PerformLayout(); + this.gainTableLayoutPanel.ResumeLayout(false); + this.gainTableLayoutPanel.PerformLayout(); + ((ISupportInitialize)this.gainTrackBar).EndInit(); + this.deviceInfoTableLayoutPanel.ResumeLayout(false); + this.deviceInfoTableLayoutPanel.PerformLayout(); + this.iqFormatTableLayoutPanel.ResumeLayout(false); + this.iqFormatTableLayoutPanel.PerformLayout(); + base.ResumeLayout(false); + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/ControllerPanel.resx b/SDRSharp/SDRSharp.FrontEnds.SpyServer/ControllerPanel.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/ControllerPanel.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/DeviceInfo.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/DeviceInfo.cs new file mode 100644 index 0000000..6da5c8e --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/DeviceInfo.cs @@ -0,0 +1,29 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public struct DeviceInfo + { + public DeviceType DeviceType; + + public uint DeviceSerial; + + public uint MaximumSampleRate; + + public uint MaximumBandwidth; + + public uint DecimationStageCount; + + public uint GainStageCount; + + public uint MaximumGainIndex; + + public uint MinimumFrequency; + + public uint MaximumFrequency; + + public uint Resolution; + + public uint MinimumIQDecimation; + + public uint ForcedIQFormat; + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/DeviceType.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/DeviceType.cs new file mode 100644 index 0000000..ce5c546 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/DeviceType.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public enum DeviceType : uint + { + DEVICE_INVALID, + DEVICE_AIRSPY_ONE, + DEVICE_AIRSPY_HF, + DEVICE_RTLSDR + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/MessageHeader.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/MessageHeader.cs new file mode 100644 index 0000000..a56565c --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/MessageHeader.cs @@ -0,0 +1,15 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public struct MessageHeader + { + public uint ProtocolID; + + public MessageType MessageType; + + public StreamType StreamType; + + public uint SequenceNumber; + + public uint BodySize; + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/MessageType.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/MessageType.cs new file mode 100644 index 0000000..c59b41d --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/MessageType.cs @@ -0,0 +1,23 @@ +using System; + +namespace SDRSharp.FrontEnds.SpyServer +{ + [Flags] + public enum MessageType : uint + { + MSG_TYPE_DEVICE_INFO = 0u, + MSG_TYPE_CLIENT_SYNC = 1u, + MSG_TYPE_PONG = 2u, + MSG_TYPE_READ_SETTING = 3u, + MSG_TYPE_UINT8_IQ = 0x64, + MSG_TYPE_INT16_IQ = 0x65, + MSG_TYPE_INT24_IQ = 0x66, + MSG_TYPE_FLOAT_IQ = 0x67, + MSG_TYPE_UINT8_AF = 0xC8, + MSG_TYPE_INT16_AF = 0xC9, + MSG_TYPE_INT24_AF = 0xCA, + MSG_TYPE_FLOAT_AF = 0xCB, + MSG_TYPE_DINT4_FFT = 0x12C, + MSG_TYPE_UINT8_FFT = 0x12D + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/SettingTarget.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/SettingTarget.cs new file mode 100644 index 0000000..87e6728 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/SettingTarget.cs @@ -0,0 +1,9 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public struct SettingTarget + { + public StreamType StreamType; + + public SettingType SettingType; + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/SettingType.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/SettingType.cs new file mode 100644 index 0000000..f14d85a --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/SettingType.cs @@ -0,0 +1,19 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public enum SettingType : uint + { + SETTING_STREAMING_MODE, + SETTING_STREAMING_ENABLED, + SETTING_GAIN, + SETTING_IQ_FORMAT = 100u, + SETTING_IQ_FREQUENCY, + SETTING_IQ_DECIMATION, + SETTING_IQ_DIGITAL_GAIN, + SETTING_FFT_FORMAT = 200u, + SETTING_FFT_FREQUENCY, + SETTING_FFT_DECIMATION, + SETTING_FFT_DB_OFFSET, + SETTING_FFT_DB_RANGE, + SETTING_FFT_DISPLAY_PIXELS + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/SpyClient.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/SpyClient.cs new file mode 100644 index 0000000..9ecc87b --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/SpyClient.cs @@ -0,0 +1,1074 @@ +using SDRSharp.Common; +using SDRSharp.Radio; +using SDRSharp.Radio.PortAudio; +using System; +using System.Net.Sockets; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +namespace SDRSharp.FrontEnds.SpyServer +{ + public class SpyClient : IDisposable + { + private enum ParserPhase + { + AcquiringHeader, + ReadingData + } + + private const float TimeConst = 0.05f; + + private const int BufferSize = 65536; + + private const int DefaultDisplayPixels = 1000; + + private const int DefaultFFTRange = 127; + + private Socket _s; + + private Thread _receiveThread; + + private bool _terminated; + + private bool _streaming; + + private StreamingMode _streamingMode = StreamingMode.STREAM_MODE_FFT_IQ; + + private StreamFormat _streamFormat = StreamFormat.STREAM_FORMAT_UINT8; + + private bool _optimizePropertyChanges = true; + + private uint _channelCenterFrequency; + + private uint _displayCenterFrequency; + + private uint _deviceCenterFrequency; + + private int _displayDecimationStageCount; + + private int _channelDecimationStageCount; + + private uint _minimumTunableFrequency; + + private uint _maximumTunableFrequency; + + private uint _autoGainDecibels; + + private int _gain; + + private int _fftOffset; + + private int _fftRange = 127; + + private int _displayPixels = 1000; + + private int _messageSize; + + private uint _lastSequenceNumber = uint.MaxValue; + + private uint _droppedBuffers; + + private long _down_stream_bytes; + + private bool _gotDeviceInfo; + + private bool _gotSyncInfo; + + private bool _canControl; + + private Exception _error; + + private DeviceInfo _deviceInfo; + + private ParserPhase _parserPhase; + + private int _parserPosition; + + private unsafe byte[] _headerData = new byte[sizeof(MessageHeader)]; + + private MessageHeader _header; + + private UnsafeBuffer _bodyBuffer; + + private UnsafeBuffer _uncompressedBuffer; + + private UnsafeBuffer _messageBuffer; + + private UnsafeBuffer _iqBuffer; + + private string _serverVersion; + + public string ServerVersion + { + get + { + return this._serverVersion; + } + } + + public bool OptimizePropertyChanges + { + get + { + return this._optimizePropertyChanges; + } + set + { + this._optimizePropertyChanges = value; + } + } + + public bool IsConnected + { + get + { + if (!this._terminated && this._s != null) + { + return this._s.Connected; + } + return false; + } + } + + public bool IsSynchronized + { + get + { + if (this._gotDeviceInfo) + { + return this._gotSyncInfo; + } + return false; + } + } + + public string DeviceName + { + get + { + return Constants.GetDeviceName(this._deviceInfo.DeviceType); + } + } + + public uint DeviceSerial + { + get + { + return this._deviceInfo.DeviceSerial; + } + } + + public uint MaximumDecimationStageCount + { + get + { + return this._deviceInfo.DecimationStageCount; + } + } + + public uint MaximumBandwidth + { + get + { + return this._deviceInfo.MaximumBandwidth; + } + } + + public uint MaximumSampleRate + { + get + { + return this._deviceInfo.MaximumSampleRate; + } + } + + public uint MaximumGainIndex + { + get + { + return this._deviceInfo.MaximumGainIndex; + } + } + + public double ChannelSamplerate + { + get + { + return (double)this._deviceInfo.MaximumSampleRate / (double)(1 << this._channelDecimationStageCount); + } + } + + public int DisplayBandwidth + { + get + { + return (int)((double)this._deviceInfo.MaximumBandwidth / (double)(1 << this._displayDecimationStageCount)); + } + } + + public int ChannelBandwidth + { + get + { + return (int)((double)this._deviceInfo.MaximumBandwidth / (double)(1 << this._channelDecimationStageCount)); + } + } + + public bool Is8bitForced + { + get + { + return this._deviceInfo.ForcedIQFormat == 1; + } + } + + public int MinimumIQDecimation + { + get + { + return (int)this._deviceInfo.MinimumIQDecimation; + } + } + + public bool CanControl + { + get + { + return this._canControl; + } + } + + public uint MaximumTunableFrequency + { + get + { + return this._maximumTunableFrequency; + } + } + + public uint MinimumTunableFrequency + { + get + { + return this._minimumTunableFrequency; + } + } + + public uint DeviceCenterFrequency + { + get + { + return this._deviceCenterFrequency; + } + } + + public StreamingMode StreamingMode + { + get + { + return this._streamingMode; + } + set + { + if (this._streamingMode == value && this._optimizePropertyChanges) + { + return; + } + this._streamingMode = value; + this.SetSetting(SettingType.SETTING_STREAMING_MODE, (uint)this._streamingMode); + } + } + + public StreamFormat StreamFormat + { + get + { + return this._streamFormat; + } + set + { + if (this._streamFormat == value && this._optimizePropertyChanges) + { + return; + } + this._streamFormat = value; + this.UpdateIQFormat(); + } + } + + public uint DisplayCenterFrequency + { + get + { + return this._displayCenterFrequency; + } + set + { + if (this._canControl) + { + this._deviceCenterFrequency = value; + } + if (this._displayCenterFrequency == value && this._optimizePropertyChanges) + { + return; + } + this._displayCenterFrequency = value; + this.SetSetting(SettingType.SETTING_FFT_FREQUENCY, this._displayCenterFrequency); + } + } + + public uint ChannelCenterFrequency + { + get + { + return this._channelCenterFrequency; + } + set + { + if (this._channelCenterFrequency == value && this._optimizePropertyChanges) + { + return; + } + this._channelCenterFrequency = value; + this.SetSetting(SettingType.SETTING_IQ_FREQUENCY, this._channelCenterFrequency); + } + } + + public int Gain + { + get + { + return this._gain; + } + set + { + if (this._gain == value && this._optimizePropertyChanges) + { + return; + } + this._gain = value; + this.SetSetting(SettingType.SETTING_GAIN, (uint)this._gain); + } + } + + public int DisplayDecimationStageCount + { + get + { + return this._displayDecimationStageCount; + } + set + { + if (this._displayDecimationStageCount == value && this._optimizePropertyChanges) + { + return; + } + this._displayDecimationStageCount = value; + this.SetSetting(SettingType.SETTING_FFT_DECIMATION, (uint)this._displayDecimationStageCount); + } + } + + public int ChannelDecimationStageCount + { + get + { + return this._channelDecimationStageCount; + } + set + { + if (this._channelDecimationStageCount == value && this._optimizePropertyChanges) + { + return; + } + this._channelDecimationStageCount = value; + this.SetSetting(SettingType.SETTING_IQ_DECIMATION, (uint)this._channelDecimationStageCount); + this.UpdateIQFormat(); + } + } + + public int FFTRange + { + get + { + return this._fftRange; + } + set + { + if (this._fftRange == value && this._optimizePropertyChanges) + { + return; + } + this._fftRange = value; + this.SetSetting(SettingType.SETTING_FFT_DB_RANGE, (uint)this._fftRange); + } + } + + public int FFTOffset + { + get + { + return this._fftOffset; + } + set + { + if (this._fftOffset == value && this._optimizePropertyChanges) + { + return; + } + this._fftOffset = value; + this.SetSetting(SettingType.SETTING_FFT_DB_OFFSET, (uint)this._fftOffset); + } + } + + public int DisplayPixels + { + get + { + return this._displayPixels; + } + set + { + if (this._displayPixels == value && this._optimizePropertyChanges) + { + return; + } + this._displayPixels = value; + this.SetSetting(SettingType.SETTING_FFT_DISPLAY_PIXELS, (uint)this._displayPixels); + } + } + + public event EventHandler Connected; + + public event EventHandler Disconnected; + + public event EventHandler Synchronized; + + public event SamplesAvailableDelegate SamplesAvailable; + + public event SamplesAvailableDelegate FFTAvailable; + + public void Dispose() + { + this.Disconnect(); + } + + public void Connect(string host, int port) + { + if (this._receiveThread == null) + { + this._s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) + { + NoDelay = true + }; + this._s.Connect(host, port); + this._s.Blocking = false; + this.SayHello(); + this.Cleanup(); + this._error = null; + this._terminated = false; + this._receiveThread = new Thread(this.ThreadProc) + { + Name = "Spy Server Receive Thread" + }; + this._receiveThread.Start(); + for (int i = 0; i < 2000; i++) + { + if (this._error != null) + { + break; + } + if (this._gotDeviceInfo) + { + if (this._deviceInfo.DeviceType == DeviceType.DEVICE_INVALID) + { + this._error = new ApplicationException("Server is up but no device is available."); + break; + } + if (this._gotSyncInfo) + { + this.OnConnect(); + return; + } + } + Thread.Sleep(1); + Application.DoEvents(); + } + this.Disconnect(); + if (this._error != null) + { + Exception error = this._error; + this._error = null; + throw error; + } + throw new ApplicationException("Server didn't send the device capability and synchronization info."); + } + } + + public void Disconnect() + { + this._terminated = true; + if (this._s != null) + { + this._s.Close(); + this._s = null; + } + Thread receiveThread = this._receiveThread; + if (receiveThread != null) + { + receiveThread.Join(); + this._receiveThread = null; + } + this.Cleanup(); + } + + private void OnConnect() + { + this.SetSetting(SettingType.SETTING_STREAMING_MODE, (uint)this._streamingMode); + this.SetSetting(SettingType.SETTING_FFT_DISPLAY_PIXELS, (uint)this._displayPixels); + this.SetSetting(SettingType.SETTING_FFT_DB_OFFSET, (uint)this._fftOffset); + this.SetSetting(SettingType.SETTING_FFT_DB_RANGE, (uint)this._fftRange); + if (!Utils.GetBooleanSetting("spyserver.disableAutoScaling")) + { + this.SetSetting(SettingType.SETTING_IQ_DIGITAL_GAIN, uint.MaxValue); + } + this.UpdateFFTFormat(); + this.UpdateIQFormat(); + } + + public void StartStreaming() + { + if (!this._streaming) + { + this._streaming = true; + this._down_stream_bytes = 0L; + this.SetStreamState(); + } + } + + public void StopStreaming() + { + if (this._streaming) + { + this._streaming = false; + this._down_stream_bytes = 0L; + this.SetStreamState(); + } + } + + private void Cleanup() + { + this._deviceInfo.DeviceType = DeviceType.DEVICE_INVALID; + this._deviceInfo.DeviceSerial = 0u; + this._deviceInfo.DecimationStageCount = 0u; + this._deviceInfo.GainStageCount = 0u; + this._deviceInfo.MaximumSampleRate = 0u; + this._deviceInfo.MaximumBandwidth = 0u; + this._deviceInfo.MaximumGainIndex = 0u; + this._deviceInfo.MinimumFrequency = 0u; + this._deviceInfo.MaximumFrequency = 0u; + this._deviceInfo.Resolution = 0u; + this._deviceInfo.MinimumIQDecimation = 0u; + this._deviceInfo.ForcedIQFormat = 0u; + this._gain = 0; + this._displayCenterFrequency = 0u; + this._deviceCenterFrequency = 0u; + this._displayDecimationStageCount = 0; + this._channelDecimationStageCount = 0; + this._minimumTunableFrequency = 0u; + this._maximumTunableFrequency = 0u; + this._canControl = false; + this._gotDeviceInfo = false; + this._gotSyncInfo = false; + this._lastSequenceNumber = uint.MaxValue; + this._droppedBuffers = 0u; + this._down_stream_bytes = 0L; + this._parserPhase = ParserPhase.AcquiringHeader; + this._parserPosition = 0; + this._streaming = false; + this._terminated = true; + } + + private void UpdateFFTFormat() + { + this.SetSetting(SettingType.SETTING_FFT_FORMAT, 1u); + } + + private void UpdateIQFormat() + { + this.SetSetting(SettingType.SETTING_IQ_FORMAT, (uint)this._streamFormat); + } + + private bool SetStreamState() + { + return this.SetSetting(SettingType.SETTING_STREAMING_ENABLED, (uint)(this._streaming ? 1 : 0)); + } + + private unsafe bool SetSetting(SettingType setting, params uint[] args) + { + byte[] array; + if (args != null && args.Length != 0) + { + array = new byte[4 + args.Length * 4]; + byte* ptr = (byte*)(&setting); + for (int i = 0; i < 4; i++) + { + array[i] = ptr[i]; + } + Buffer.BlockCopy(args, 0, array, 4, args.Length * 4); + } + else + { + array = null; + } + return this.SendCommand(CommandType.CMD_SET_SETTING, array); + } + + private bool SayHello() + { + byte[] bytes = BitConverter.GetBytes(33556024u); + string s = string.Format("SDR# v{0} on {1}", Assembly.GetEntryAssembly().GetName().Version, Environment.OSVersion); + byte[] bytes2 = Encoding.ASCII.GetBytes(s); + byte[] array = new byte[bytes.Length + bytes2.Length]; + Buffer.BlockCopy(bytes, 0, array, 0, bytes.Length); + Buffer.BlockCopy(bytes2, 0, array, bytes.Length, bytes2.Length); + return this.SendCommand(CommandType.CMD_HELLO, array); + } + + private unsafe bool SendCommand(CommandType cmd, byte[] args) + { + if (this._s == null) + { + return false; + } + int num = sizeof(CommandHeader); + int num2 = (args != null) ? args.Length : 0; + byte[] array = new byte[num + num2]; + CommandHeader commandHeader = default(CommandHeader); + commandHeader.CommandType = cmd; + commandHeader.BodySize = (ushort)num2; + byte* ptr = (byte*)(&commandHeader); + for (int i = 0; i < sizeof(CommandHeader); i++) + { + array[i] = ptr[i]; + } + if (args != null) + { + byte[] array2 = array; + fixed (byte* ptr2 = array2) + { + byte* ptr3 = ptr2 + num; + for (int j = 0; j < args.Length; j++) + { + ptr3[j] = args[j]; + } + } + } + try + { + this._s.Send(array); + } + catch + { + return false; + } + return true; + } + + private unsafe void ThreadProc() + { + EventHandler connected = this.Connected; + if (connected != null) + { + connected(this, EventArgs.Empty); + } + this._parserPhase = ParserPhase.AcquiringHeader; + this._parserPosition = 0; + byte[] array = new byte[65536]; + byte[] array2 = array; + fixed (byte* buffer = array2) + { + try + { + while (!this._terminated) + { + Socket s = this._s; + if (s != null && s.Poll(1000000, SelectMode.SelectRead)) + { + if (this._terminated) + { + break; + } + int num = s.Receive(array, 0, array.Length, SocketFlags.None); + if (num > 0) + { + this.ParseMessage(buffer, num); + continue; + } + throw new ApplicationException("Device got disconnected"); + } + } + } + catch (Exception error) + { + Exception ex = this._error = error; + } + } + if (this._bodyBuffer != null) + { + this._bodyBuffer.Dispose(); + this._bodyBuffer = null; + } + if (this._uncompressedBuffer != null) + { + this._uncompressedBuffer.Dispose(); + this._uncompressedBuffer = null; + } + this._messageBuffer = null; + this.Cleanup(); + this._receiveThread = null; + EventHandler disconnected = this.Disconnected; + if (disconnected != null) + { + disconnected(this, EventArgs.Empty); + } + } + + private unsafe int ParseHeader(byte* buffer, int length) + { + int num = 0; + byte[] headerData = this._headerData; + fixed (byte* ptr = headerData) + { + while (length > 0) + { + int num2 = Math.Min(sizeof(MessageHeader) - this._parserPosition, length); + Utils.Memcpy(ptr + this._parserPosition, buffer, num2); + length -= num2; + buffer += num2; + this._parserPosition += num2; + num += num2; + if (this._parserPosition == sizeof(MessageHeader)) + { + this._parserPosition = 0; + MessageHeader messageHeader = default(MessageHeader); + Utils.Memcpy(&messageHeader, ptr, sizeof(MessageHeader)); + this._header = messageHeader; + if (messageHeader.BodySize != 0) + { + this._parserPhase = ParserPhase.ReadingData; + } + return num; + } + } + } + return num; + } + + private unsafe int ParseBody(byte* buffer, int length) + { + int num = 0; + byte* ptr = (byte*)(void*)this._bodyBuffer; + while (length > 0) + { + int num2 = Math.Min((int)this._header.BodySize - this._parserPosition, length); + Utils.Memcpy(ptr + this._parserPosition, buffer, num2); + length -= num2; + buffer += num2; + this._parserPosition += num2; + num += num2; + if (this._parserPosition == this._header.BodySize) + { + this._parserPosition = 0; + this._parserPhase = ParserPhase.AcquiringHeader; + return num; + } + } + return num; + } + + public long GetDownstreamBytes() + { + return Interlocked.Exchange(ref this._down_stream_bytes, 0L); + } + + private unsafe void ParseMessage(byte* buffer, int len) + { + Interlocked.Add(ref this._down_stream_bytes, len); + while (true) + { + if (len > 0 && !this._terminated) + { + if (this._parserPhase == ParserPhase.AcquiringHeader) + { + while (this._parserPhase == ParserPhase.AcquiringHeader && len > 0) + { + int num = this.ParseHeader(buffer, len); + buffer += num; + len -= num; + } + if (this._parserPhase == ParserPhase.ReadingData) + { + byte b = 2; + byte b2 = 0; + ushort num2 = 1592; + byte b3 = (byte)(this._header.ProtocolID >> 24); + byte b4 = (byte)(this._header.ProtocolID >> 16 & 0xFF); + ushort num3 = (ushort)(this._header.ProtocolID & 0xFFFF); + this._serverVersion = string.Format("{0}.{1}.{2}", b3, b4, num3); + if (b == b3 && b2 == b4) + { + if (this._header.BodySize <= 1048576) + { + if (this._bodyBuffer == null || this._bodyBuffer.Length < this._header.BodySize) + { + if (this._bodyBuffer != null) + { + this._bodyBuffer.Dispose(); + } + this._bodyBuffer = UnsafeBuffer.Create((int)this._header.BodySize); + } + goto IL_017b; + } + break; + } + string message = string.Format("Server is running an unsupported protocol version.\r\nExpected {0}.{1}.* but got {3}.{4}.{5}.", b, b2, num2, b3, b4, num3); + throw new ApplicationException(message); + } + } + goto IL_017b; + } + return; + IL_017b: + if (this._parserPhase == ParserPhase.ReadingData) + { + int num = this.ParseBody(buffer, len); + buffer += num; + len -= num; + if (this._parserPhase == ParserPhase.AcquiringHeader) + { + if (this._header.StreamType == StreamType.STREAM_TYPE_IQ) + { + uint num4 = this._header.SequenceNumber - this._lastSequenceNumber - 1; + this._lastSequenceNumber = this._header.SequenceNumber; + this._droppedBuffers += num4; + } + this.HandleNewMessage(); + } + } + } + throw new ApplicationException("The server is probably buggy"); + } + + private void HandleNewMessage() + { + if (!this._terminated) + { + this._messageBuffer = this._bodyBuffer; + this._messageSize = (int)this._header.BodySize; + switch (this._header.MessageType & (MessageType)65535u) + { + case MessageType.MSG_TYPE_DEVICE_INFO: + this.ProcessDeviceInfo(); + break; + case MessageType.MSG_TYPE_CLIENT_SYNC: + this.ProcessClientSync(); + break; + case MessageType.MSG_TYPE_UINT8_IQ: + this._autoGainDecibels = (uint)this._header.MessageType >> 16; + this.ProcessUInt8Samples(); + break; + case MessageType.MSG_TYPE_INT16_IQ: + this._autoGainDecibels = (uint)this._header.MessageType >> 16; + this.ProcessInt16Samples(); + break; + case MessageType.MSG_TYPE_INT24_IQ: + this._autoGainDecibels = (uint)this._header.MessageType >> 16; + this.ProcessInt24Samples(); + break; + case MessageType.MSG_TYPE_FLOAT_IQ: + this._autoGainDecibels = (uint)this._header.MessageType >> 16; + this.ProcessFloatSamples(); + break; + case MessageType.MSG_TYPE_UINT8_FFT: + this.ProcessUInt8FFT(); + break; + } + } + } + + private unsafe void ProcessDeviceInfo() + { + DeviceInfo deviceInfo = default(DeviceInfo); + Utils.Memcpy(&deviceInfo, this._messageBuffer, Math.Min(this._messageSize, sizeof(DeviceInfo))); + this._deviceInfo = deviceInfo; + if (this._deviceInfo.Resolution == 0) + { + switch (this._deviceInfo.DeviceType) + { + case DeviceType.DEVICE_AIRSPY_HF: + this._deviceInfo.Resolution = 16u; + break; + case DeviceType.DEVICE_AIRSPY_ONE: + this._deviceInfo.Resolution = 12u; + break; + case DeviceType.DEVICE_RTLSDR: + this._deviceInfo.Resolution = 8u; + break; + } + } + this._minimumTunableFrequency = this._deviceInfo.MinimumFrequency; + this._maximumTunableFrequency = this._deviceInfo.MaximumFrequency; + this._gotDeviceInfo = true; + } + + private unsafe void ProcessClientSync() + { + ClientSync clientSync = default(ClientSync); + Utils.Memcpy(&clientSync, this._messageBuffer, Math.Min(this._messageSize, sizeof(ClientSync))); + this._canControl = (clientSync.CanControl != 0); + this._gain = (int)clientSync.Gain; + this._deviceCenterFrequency = clientSync.DeviceCenterFrequency; + this._channelCenterFrequency = clientSync.IQCenterFrequency; + this._displayCenterFrequency = clientSync.FFTCenterFrequency; + switch (this._streamingMode) + { + case StreamingMode.STREAM_MODE_FFT_ONLY: + case StreamingMode.STREAM_MODE_FFT_IQ: + this._minimumTunableFrequency = clientSync.MinimumFFTCenterFrequency; + this._maximumTunableFrequency = clientSync.MaximumFFTCenterFrequency; + break; + case StreamingMode.STREAM_MODE_IQ_ONLY: + this._minimumTunableFrequency = clientSync.MinimumIQCenterFrequency; + this._maximumTunableFrequency = clientSync.MaximumIQCenterFrequency; + break; + } + this._gotSyncInfo = true; + EventHandler synchronized = this.Synchronized; + if (synchronized != null) + { + synchronized(this, EventArgs.Empty); + } + } + + private unsafe void ProcessUInt8Samples() + { + int num = this._messageSize / 2; + if (this._iqBuffer == null || this._iqBuffer.Length != num) + { + this._iqBuffer = UnsafeBuffer.Create(num, sizeof(Complex)); + } + byte* ptr = (byte*)(void*)this._messageBuffer; + Complex* ptr2 = (Complex*)(void*)this._iqBuffer; + for (int i = 0; i < num; i++) + { + Complex* intPtr = ptr2 + i; + byte* intPtr2 = ptr; + ptr = intPtr2 + 1; + intPtr->Real = ((float)(int)(*intPtr2) - 128f) * 0.0078125f; + Complex* intPtr3 = ptr2 + i; + byte* intPtr4 = ptr; + ptr = intPtr4 + 1; + intPtr3->Imag = ((float)(int)(*intPtr4) - 128f) * 0.0078125f; + } + this.PushIQData(ptr2, num); + } + + private unsafe void ProcessInt16Samples() + { + int num = this._messageSize / 4; + if (this._iqBuffer == null || this._iqBuffer.Length != num) + { + this._iqBuffer = UnsafeBuffer.Create(num, sizeof(Complex)); + } + short* ptr = (short*)(void*)this._messageBuffer; + Complex* ptr2 = (Complex*)(void*)this._iqBuffer; + for (int i = 0; i < num; i++) + { + Complex* intPtr = ptr2 + i; + short* intPtr2 = ptr; + ptr = intPtr2 + 1; + intPtr->Real = (float)(*intPtr2) * 3.05175781E-05f; + Complex* intPtr3 = ptr2 + i; + short* intPtr4 = ptr; + ptr = intPtr4 + 1; + intPtr3->Imag = (float)(*intPtr4) * 3.05175781E-05f; + } + this.PushIQData(ptr2, num); + } + + private unsafe void ProcessInt24Samples() + { + int num = this._messageSize / 6; + if (this._iqBuffer == null || this._iqBuffer.Length != num) + { + this._iqBuffer = UnsafeBuffer.Create(num, sizeof(Complex)); + } + Int24* ptr = (Int24*)(void*)this._messageBuffer; + Complex* ptr2 = (Complex*)(void*)this._iqBuffer; + for (int i = 0; i < num; i++) + { + Complex* intPtr = ptr2 + i; + Int24* ptr3 = ptr; + ptr = ptr3 + 1; + intPtr->Real = (float)(*ptr3) * 1.1920929E-07f; + Complex* intPtr2 = ptr2 + i; + ptr3 = ptr; + ptr = ptr3 + 1; + intPtr2->Imag = (float)(*ptr3) * 1.1920929E-07f; + } + this.PushIQData(ptr2, num); + } + + private unsafe void ProcessFloatSamples() + { + int count = this._messageSize / 8; + Complex* samples = (Complex*)(void*)this._messageBuffer; + this.PushIQData(samples, count); + } + + private unsafe void PushIQData(Complex* samples, int count) + { + ComplexSamplesEventArgs e = new ComplexSamplesEventArgs + { + Buffer = samples, + Length = count, + DroppedSamples = (uint)((int)this._droppedBuffers * count) + }; + this._droppedBuffers = 0u; + if (this._autoGainDecibels != 0) + { + float b = (float)Math.Pow(10.0, (double)((float)(double)this._autoGainDecibels * -0.05f)); + for (int i = 0; i < count; i++) + { + Complex* intPtr = samples + i; + *intPtr *= b; + } + } + SamplesAvailableDelegate samplesAvailable = this.SamplesAvailable; + if (samplesAvailable != null) + { + samplesAvailable(this, e); + } + } + + private unsafe void ProcessUInt8FFT() + { + ByteSamplesEventArgs e = new ByteSamplesEventArgs + { + Buffer = (byte*)(void*)this._messageBuffer, + Length = this._messageSize + }; + SamplesAvailableDelegate fFTAvailable = this.FFTAvailable; + if (fFTAvailable != null) + { + fFTAvailable(this, e); + } + } + + public unsafe SpyClient() + { + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/SpyServerIO.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/SpyServerIO.cs new file mode 100644 index 0000000..8bc32f8 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/SpyServerIO.cs @@ -0,0 +1,584 @@ +using SDRSharp.Common; +using SDRSharp.Radio; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Windows.Forms; + +namespace SDRSharp.FrontEnds.SpyServer +{ + public class SpyServerIO : IFrontendController, IIQStreamController, INonBlockingController, ITunableSource, ISampleRateChangeSource, IConnectableSource, IFrontendOffset, IControlAwareObject, ISpectrumProvider, IConfigurationPanelProvider, IFFTSource, IVFOSource, IDisposable + { + private bool _disposed; + + private ControllerPanel _gui; + + private ISharpControl _control; + + private SpyClient _client; + + private SamplesAvailableDelegate _callback; + + public ISharpControl Control + { + get + { + return this._control; + } + } + + public bool Connected + { + get + { + if (this._client != null) + { + return this._client.IsConnected; + } + return false; + } + } + + public float UsableSpectrumRatio + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return (float)(double)this._client.MaximumBandwidth / (float)(double)this._client.MaximumSampleRate; + } + return 1f; + } + } + + public UserControl Gui + { + get + { + return this._gui; + } + } + + public int Offset + { + get + { + return 0; + } + } + + public long Frequency + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return (this._client.StreamingMode == StreamingMode.STREAM_MODE_FFT_IQ) ? this._client.DisplayCenterFrequency : this._client.ChannelCenterFrequency; + } + return 0L; + } + set + { + if (this._client != null && this._client.IsSynchronized) + { + if (this._client.StreamingMode == StreamingMode.STREAM_MODE_FFT_IQ) + { + if (this.CanTune) + { + this._client.DisplayCenterFrequency = (uint)value; + } + } + else + { + this._client.ChannelCenterFrequency = (uint)value; + } + } + } + } + + public bool CanTune + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + if (!this._client.CanControl) + { + return this._client.MaximumTunableFrequency > this._client.MinimumTunableFrequency; + } + return true; + } + return false; + } + } + + public long MinimumTunableFrequency + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return this._client.MinimumTunableFrequency; + } + return 0L; + } + } + + public long MaximumTunableFrequency + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return this._client.MaximumTunableFrequency; + } + return 9223372036854775807L; + } + } + + public double Samplerate + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return this._client.ChannelSamplerate; + } + return 0.0; + } + } + + public int FFTRange + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return this._client.FFTRange; + } + return 0; + } + set + { + if (this._client != null && this._client.IsSynchronized) + { + this._client.FFTRange = value; + } + } + } + + public int FFTOffset + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return this._client.FFTOffset; + } + return 0; + } + set + { + if (this._client != null && this._client.IsSynchronized) + { + this._client.FFTOffset = value; + } + } + } + + public int DisplayPixels + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return this._client.DisplayPixels; + } + return 0; + } + set + { + if (this._client != null && this._client.IsSynchronized) + { + this._client.DisplayPixels = value; + } + } + } + + public int DisplayBandwidth + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return this._client.DisplayBandwidth; + } + return 0; + } + } + + public long VFOFrequency + { + get + { + return (this._client != null) ? this._client.ChannelCenterFrequency : 0; + } + set + { + if (this._client == null && this._client.IsSynchronized) + { + return; + } + this._client.ChannelCenterFrequency = (uint)value; + } + } + + public int VFODecimation + { + get + { + if (this._client != null) + { + return this._client.ChannelDecimationStageCount; + } + return 0; + } + set + { + if (this._client != null && this._client.IsSynchronized && this._client.ChannelDecimationStageCount != value) + { + this._client.ChannelDecimationStageCount = value; + } + } + } + + public double VFOMaxSampleRate + { + get + { + if (this._client == null) + { + return 0.0; + } + return (double)this._client.MaximumSampleRate; + } + } + + public int VFOMinIQDecimation + { + get + { + if (this._client == null) + { + return 0; + } + return this._client.MinimumIQDecimation; + } + } + + public bool FFTEnabled + { + get + { + if (this._client != null && this._client.IsSynchronized) + { + return this._client.StreamingMode == StreamingMode.STREAM_MODE_FFT_IQ; + } + return false; + } + set + { + if (this._client != null && this._client.IsSynchronized) + { + this._client.StreamingMode = ((!value) ? StreamingMode.STREAM_MODE_IQ_ONLY : StreamingMode.STREAM_MODE_FFT_IQ); + this._client.OptimizePropertyChanges = false; + long num = this._control.FrequencyShiftEnabled ? this._control.FrequencyShift : 0; + switch (this._client.StreamingMode) + { + case StreamingMode.STREAM_MODE_FFT_IQ: + this._client.DisplayCenterFrequency = (uint)(this._control.CenterFrequency - num); + this._client.ChannelCenterFrequency = (uint)(this._control.Frequency - num); + this._client.DisplayDecimationStageCount = this._gui.Decimation; + this._client.ChannelDecimationStageCount = StreamControl.GetDecimationStageCount((double)this._client.MaximumSampleRate, this._control.DetectorType); + break; + case StreamingMode.STREAM_MODE_IQ_ONLY: + this._client.ChannelCenterFrequency = (uint)(this._control.CenterFrequency - num); + this._client.ChannelDecimationStageCount = this._gui.Decimation; + break; + default: + throw new ApplicationException("Streaming Mode is not supported: " + value.ToString()); + } + this._client.OptimizePropertyChanges = true; + } + } + } + + public event EventHandler SampleRateChanged; + + public event SamplesAvailableDelegate FFTAvailable; + + public SpyServerIO() + { + this._gui = new ControllerPanel(this); + } + + ~SpyServerIO() + { + this.Dispose(); + } + + public void Dispose() + { + if (!this._disposed) + { + this._disposed = true; + this.DestroyClient(); + GC.SuppressFinalize(this); + } + } + + private void DestroyClient() + { + if (this._client != null) + { + this._client.Synchronized -= this.Client_Synchronized; + this._client.Disconnected -= this.Client_Disconnected; + this._client.SamplesAvailable -= this.Client_SamplesAvailable; + this._client.FFTAvailable -= this.Client_FFTAvailable; + this._client.Dispose(); + this._client = null; + } + } + + public void Connect() + { + if (this._client == null) + { + this._client = new SpyClient(); + this._client.Synchronized += this.Client_Synchronized; + this._client.Disconnected += this.Client_Disconnected; + this._client.SamplesAvailable += this.Client_SamplesAvailable; + this._client.FFTAvailable += this.Client_FFTAvailable; + } + this._client.Connect(this._gui.Host, this._gui.Port); + this._control.FrequencyShiftEnabled = false; + this._control.ResetFrequency(this._client.ChannelCenterFrequency); + this.UpdateTuningBoundaries(); + bool bandwidth = this._client.MaximumDecimationStageCount != 0; + List list = new List(); + for (int i = 0; i <= this._client.MaximumDecimationStageCount; i++) + { + list.Add((int)this._client.MaximumBandwidth >> i); + } + string deviceName = this._client.DeviceName; + string deviceSerial = this._client.DeviceSerial.ToString("X8"); + int maximumGainIndex = (int)this._client.MaximumGainIndex; + bool flag = maximumGainIndex > 0; + if (this._client.Is8bitForced) + { + this._gui.Force8bit(); + } + this._gui.EnableURI(false); + this._gui.UpdateControlOptions(deviceName, deviceSerial, this._client.ServerVersion, list.ToArray(), this._client.MinimumIQDecimation, maximumGainIndex); + this._gui.UpdateDisplaySections(true, bandwidth, !this._client.Is8bitForced, flag); + this.FFTEnabled = !this._gui.UseFullIQ; + if (flag) + { + this._gui.UpdateGain(this._client.Gain, this._client.CanControl); + } + } + + private void Client_Disconnected(object sender, EventArgs e) + { + if (this._control.IsPlaying) + { + this._control.StopRadio(); + } + if (this._gui.IsHandleCreated) + { + this._gui.BeginInvoke((Action)delegate + { + this._gui.EnableURI(true); + this._gui.UpdateDisplaySections(false, false, false, false); + this._gui.EnableFullIQ(true); + }); + } + } + + private void Client_Synchronized(object sender, EventArgs e) + { + if (this._client.IsConnected) + { + this.UpdateTuningStyle(); + this.UpdateTuningBoundaries(); + if (this._gui.IsHandleCreated) + { + this._gui.BeginInvoke((Action)delegate + { + this._gui.UpdateGain(this._client.Gain, this._client.CanControl); + }); + } + } + } + + private unsafe void Client_SamplesAvailable(object sender, ComplexSamplesEventArgs e) + { + this._callback(this, e.Buffer, e.Length); + } + + private void Client_FFTAvailable(object sender, ByteSamplesEventArgs e) + { + SamplesAvailableDelegate fFTAvailable = this.FFTAvailable; + if (fFTAvailable != null) + { + fFTAvailable(sender, e); + } + } + + public void Disconnect() + { + this._client.Disconnect(); + } + + public void SetFormat(StreamFormat format) + { + if (this._client != null) + { + this._client.StreamFormat = format; + } + } + + public long GetDownstreamBytes() + { + if (this._client == null) + { + return 0L; + } + return this._client.GetDownstreamBytes(); + } + + public void SetControl(object control) + { + this._control = (ISharpControl)control; + if (this._control != null) + { + this._control.PropertyChanged += this.Control_PropertyChanged; + } + } + + private void Control_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (this._client != null) + { + string propertyName = e.PropertyName; + if (!(propertyName == "StartRadio")) + { + if (propertyName == "StopRadio") + { + this._gui.EnableFullIQ(this._gui.Decimation >= this._client.MinimumIQDecimation); + } + } + else + { + this._gui.EnableFullIQ(false); + } + } + } + + public void Open() + { + this._gui.EnableURI(true); + this._control.TuningStyle = TuningStyle.Free; + this._control.TuningStyleFreezed = true; + } + + public void Close() + { + if (this._client != null) + { + this._client.Dispose(); + this._client = null; + } + this._control.TuningStyleFreezed = false; + this._gui.SaveSettings(); + } + + public unsafe void Start(SamplesAvailableDelegate callback) + { + if (this._client != null && this._client.IsSynchronized) + { + this._callback = callback; + this._client.StartStreaming(); + return; + } + throw new ApplicationException("Not connected to a server"); + } + + public void Stop() + { + if (this._client != null) + { + this._client.StopStreaming(); + } + } + + public void SetGain(int value) + { + this._client.Gain = value; + } + + public void SetDecimation(int value) + { + switch (this._client.StreamingMode) + { + case StreamingMode.STREAM_MODE_IQ_ONLY: + this._client.ChannelDecimationStageCount = value; + break; + case StreamingMode.STREAM_MODE_FFT_IQ: + this._client.DisplayDecimationStageCount = value; + break; + } + EventHandler sampleRateChanged = this.SampleRateChanged; + if (sampleRateChanged != null) + { + sampleRateChanged(this, EventArgs.Empty); + } + if (this._client.StreamingMode == StreamingMode.STREAM_MODE_IQ_ONLY) + { + this._control.ResetFrequency(this._client.DeviceCenterFrequency); + } + } + + private void UpdateTuningStyle() + { + if (!this.CanTune) + { + this._control.TuningStyle = TuningStyle.Free; + this._control.TuningStyleFreezed = true; + } + else + { + this._control.TuningStyleFreezed = false; + } + } + + private void UpdateTuningBoundaries() + { + if (this._client != null) + { + switch (this._client.StreamingMode) + { + case StreamingMode.STREAM_MODE_IQ_ONLY: + if (!this._client.IsSynchronized) + { + this._control.ResetFrequency(this._client.ChannelCenterFrequency); + } + break; + case StreamingMode.STREAM_MODE_FFT_IQ: + this._control.ResetFrequency(this._client.ChannelCenterFrequency, this._client.DisplayCenterFrequency); + break; + } + } + } + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamFormat.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamFormat.cs new file mode 100644 index 0000000..b5882dd --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamFormat.cs @@ -0,0 +1,12 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public enum StreamFormat : uint + { + STREAM_FORMAT_INVALID, + STREAM_FORMAT_UINT8, + STREAM_FORMAT_INT16, + STREAM_FORMAT_INT24, + STREAM_FORMAT_FLOAT, + STREAM_FORMAT_DINT4 + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamType.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamType.cs new file mode 100644 index 0000000..99ff647 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamType.cs @@ -0,0 +1,10 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public enum StreamType : uint + { + STREAM_TYPE_STATUS, + STREAM_TYPE_IQ, + STREAM_TYPE_AF, + STREAM_TYPE_FFT = 4u + } +} diff --git a/SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamingMode.cs b/SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamingMode.cs new file mode 100644 index 0000000..80ba480 --- /dev/null +++ b/SDRSharp/SDRSharp.FrontEnds.SpyServer/StreamingMode.cs @@ -0,0 +1,11 @@ +namespace SDRSharp.FrontEnds.SpyServer +{ + public enum StreamingMode : uint + { + STREAM_MODE_IQ_ONLY = 1u, + STREAM_MODE_AF_ONLY, + STREAM_MODE_FFT_ONLY = 4u, + STREAM_MODE_FFT_IQ, + STREAM_MODE_FFT_AF + } +} diff --git a/SDRSharp/SDRSharp.csproj b/SDRSharp/SDRSharp.csproj new file mode 100644 index 0000000..db71f12 --- /dev/null +++ b/SDRSharp/SDRSharp.csproj @@ -0,0 +1,133 @@ + + + + {4331A8D2-EF97-40C6-AE40-F1D8066B466C} + Debug + x86 + WinExe + SDRSharp + .NETFramework + v4.6 + 4 + True + + + x86 + + + bin\Debug\ + true + full + false + + + bin\Release\ + true + pdbonly + true + + + + ..\SDRSharp.CollapsiblePanel\bin\Debug\SDRSharp.CollapsiblePanel.dll + + + ..\SDRSharp.Common\bin\Debug\SDRSharp.Common.dll + + + False + ..\SDRSharp.FrequencyEdit\SDRSharp.FrequencyEdit\bin\Debug\SDRSharp.FrequencyEdit.dll + + + ..\SDRSharp.PanView\bin\Debug\SDRSharp.PanView.dll + + + ..\SDRSharp.Radio\bin\Debug\SDRSharp.Radio.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll + + + C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll + + + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll + + + + + + True + True + Resources.resx + + + + + + + + UserControl + + + + + + + + + + + + + UserControl + + + + + + + + + + UserControl + + + + + + + + + + + + + + Form + + + + + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + + ControllerPanel.cs + + + ControllerPanel.cs + + + ControllerPanel.cs + + + MainForm.cs + + + + \ No newline at end of file diff --git a/SDRSharp/SDRSharp.sln b/SDRSharp/SDRSharp.sln new file mode 100644 index 0000000..67291b7 --- /dev/null +++ b/SDRSharp/SDRSharp.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27428.2015 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDRSharp", "SDRSharp.csproj", "{4331A8D2-EF97-40C6-AE40-F1D8066B466C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4331A8D2-EF97-40C6-AE40-F1D8066B466C}.Debug|x86.ActiveCfg = Debug|x86 + {4331A8D2-EF97-40C6-AE40-F1D8066B466C}.Debug|x86.Build.0 = Debug|x86 + {4331A8D2-EF97-40C6-AE40-F1D8066B466C}.Release|x86.ActiveCfg = Release|x86 + {4331A8D2-EF97-40C6-AE40-F1D8066B466C}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {379FF569-D44F-4EE1-9196-41EA04C154C2} + EndGlobalSection +EndGlobal diff --git a/SDRSharp/SDRSharp/App.config b/SDRSharp/SDRSharp/App.config new file mode 100644 index 0000000..f16e512 --- /dev/null +++ b/SDRSharp/SDRSharp/App.config @@ -0,0 +1,213 @@ + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SDRSharp/SDRSharp/MainForm.cs b/SDRSharp/SDRSharp/MainForm.cs new file mode 100644 index 0000000..c3b3355 --- /dev/null +++ b/SDRSharp/SDRSharp/MainForm.cs @@ -0,0 +1,5611 @@ +using Properties; +using SDRSharp.CollapsiblePanel; +using SDRSharp.Common; +using SDRSharp.FrequencyEdit; +using SDRSharp.FrontEnds.Airspy; +using SDRSharp.FrontEnds.AirspyHF; +using SDRSharp.FrontEnds.SpyServer; +using SDRSharp.PanView; +//using SDRSharp.Properties; +using SDRSharp.Radio; +using SDRSharp.Radio.PortAudio; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Configuration; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.IO; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Windows.Forms; + +namespace SDRSharp +{ + public class MainForm : Form, ISharpControl, INotifyPropertyChanged + { + private class IQCorrectionProcessor : IIQProcessor, IStreamProcessor, IBaseProcessor + { + private readonly IQBalancer _iqBalancer = new IQBalancer(); + + public double SampleRate + { + set + { + } + } + + public bool Enabled + { + get + { + return true; + } + set + { + } + } + + public IQBalancer Engine + { + get + { + return this._iqBalancer; + } + } + + public unsafe void Process(Complex* buffer, int length) + { + this._iqBalancer.Process(buffer, length); + } + } + + private enum FrequencyInitType + { + None, + Vfo, + Device + } + + private IContainer components; + + private Button playStopButton; + + private OpenFileDialog openDlg; + + private CheckBox agcCheckBox; + + private Label label4; + + private NumericUpDown agcThresholdNumericUpDown; + + private SpectrumAnalyzer spectrumAnalyzer; + + private Waterfall waterfall; + + private Label label10; + + private NumericUpDown agcDecayNumericUpDown; + + private Label label12; + + private ComboBox outputDeviceComboBox; + + private Label label11; + + private ComboBox inputDeviceComboBox; + + private Label label13; + + private ComboBox sampleRateComboBox; + + private Label label7; + + private ComboBox viewComboBox; + + private Label label8; + + private ComboBox fftWindowComboBox; + + private System.Windows.Forms.Timer iqTimer; + + private Button gradientButton; + + private Label label14; + + private TrackBar fftContrastTrackBar; + + private TrackBar fftZoomTrackBar; + + private Label label19; + + private Label label20; + + private Label label21; + + private ComboBox fftResolutionComboBox; + + private NumericUpDown agcSlopeNumericUpDown; + + private Label label22; + + private RadioButton nfmRadioButton; + + private RadioButton rawRadioButton; + + private RadioButton cwRadioButton; + + private RadioButton amRadioButton; + + private RadioButton dsbRadioButton; + + private RadioButton wfmRadioButton; + + private Button configureSourceButton; + + private RadioButton lsbRadioButton; + + private Label label18; + + private RadioButton usbRadioButton; + + private ComboBox stepSizeComboBox; + + private NumericUpDown filterBandwidthNumericUpDown; + + private Label label1; + + private NumericUpDown squelchNumericUpDown; + + private NumericUpDown filterOrderNumericUpDown; + + private Label label16; + + private Label label5; + + private ComboBox iqSourceComboBox; + + private ComboBox filterTypeComboBox; + + private CheckBox swapIQCheckBox; + + private CheckBox correctIQCheckBox; + + private SDRSharp.CollapsiblePanel.CollapsiblePanel radioCollapsiblePanel; + + private SDRSharp.CollapsiblePanel.CollapsiblePanel audioCollapsiblePanel; + + private SDRSharp.CollapsiblePanel.CollapsiblePanel agcCollapsiblePanel; + + private CheckBox agcUseHangCheckBox; + + private SDRSharp.CollapsiblePanel.CollapsiblePanel fftCollapsiblePanel; + + private NumericUpDown latencyNumericUpDown; + + private Label label6; + + private Label label15; + + private NumericUpDown cwShiftNumericUpDown; + + private Panel controlPanel; + + private Label label25; + + private Label label26; + + private Label label24; + + private Label label23; + + private TrackBar wDecayTrackBar; + + private TrackBar wAttackTrackBar; + + private TrackBar sDecayTrackBar; + + private TrackBar sAttackTrackBar; + + private CheckBox snapFrequencyCheckBox; + + private TrackBar audioGainTrackBar; + + private CheckBox fmStereoCheckBox; + + private CheckBox filterAudioCheckBox; + + private CheckBox useSquelchCheckBox; + + private CheckBox frequencyShiftCheckBox; + + private NumericUpDown frequencyShiftNumericUpDown; + + private CheckBox markPeaksCheckBox; + + private CheckBox useTimestampsCheckBox; + + private Label label17; + + private TrackBar fftSpeedTrackBar; + + private GroupBox groupBox1; + + private TrackBar fftOffsetTrackBar; + + private TrackBar fftRangeTrackBar; + + private Label label28; + + private GroupBox smoothingGroupBox; + + private Panel scrollPanel; + + private SDRSharp.FrequencyEdit.FrequencyEdit vfoFrequencyEdit; + + private CheckBox unityGainCheckBox; + + private TableLayoutPanel rightTableLayoutPanel; + + private TableLayoutPanel settingsTableLayoutPanel; + + private Panel centerPanel; + + private TableLayoutPanel leftPluginPanel; + + private TableLayoutPanel rightPluginPanel; + + private Splitter rightSplitter; + + private Splitter leftSplitter; + + private Panel spectrumPanel; + + private Splitter spectrumSplitter; + + private TableLayoutPanel radioTableLayoutPanel; + + private TableLayoutPanel tableLayoutPanel1; + + private TableLayoutPanel tableLayoutPanel2; + + private TableLayoutPanel tableLayoutPanel3; + + private TableLayoutPanel tableLayoutPanel5; + + private TableLayoutPanel tableLayoutPanel4; + + private Button muteButton; + + private Splitter bottomSplitter; + + private TableLayoutPanel bottomPluginPanel; + + private Splitter topSplitter; + + private TableLayoutPanel topPluginPanel; + + private SDRSharp.CollapsiblePanel.CollapsiblePanel sourceCollapsiblePanel; + + private TableLayoutPanel sourceTableLayoutPanel; + + private TableLayoutPanel tableLayoutPanel7; + + private Button toggleMenuButton; + + private Panel menuSpacerPanel; + + private Label label2; + + private CheckBox lockCarrierCheckBox; + + private CheckBox useAntiFadingCheckBox; + + private Button tuningStyleButton; + + private Label label3; + + private ComboBox spectrumStyleComboBox; + + private PictureBox logoPictureBox; + + private static readonly string _baseTitle = "SDR# v" + Assembly.GetExecutingAssembly().GetName().Version; + + private static readonly int[] _defaultNFMState = new int[12] + { + 8000, + 1000, + 3, + 50, + 1, + 1000, + 1, + 12, + 0, + 0, + 0, + 0 + }; + + private static readonly int[] _defaultWFMState = new int[12] + { + 200000, + 250, + 3, + 50, + 0, + 1000, + 1, + 17, + 0, + 0, + 0, + 0 + }; + + private static readonly int[] _defaultAMState = new int[12] + { + 10000, + 1000, + 3, + 50, + 0, + 1000, + 1, + 4, + 0, + 1, + 0, + 0 + }; + + private static readonly int[] _defaultSSBState = new int[12] + { + 2400, + 1000, + 3, + 50, + 0, + 1000, + 1, + 1, + 0, + 1, + 0, + 0 + }; + + private static readonly int[] _defaultDSBState = new int[12] + { + 6000, + 1000, + 3, + 50, + 0, + 1000, + 1, + 1, + 0, + 1, + 0, + 0 + }; + + private static readonly int[] _defaultCWState = new int[12] + { + 300, + 1000, + 3, + 50, + 0, + 1000, + 1, + 1, + 0, + 1, + 0, + 0 + }; + + private static readonly int[] _defaultRAWState = new int[12] + { + 10000, + 1000, + 3, + 50, + 0, + 1000, + 1, + 4, + 1, + 0, + 0, + 0 + }; + + private const long DefaultFrontEndFrequency = 103000000L; + + private const int DefaultFrontEndSpectrumWidth = 250000; + + private const float DefaultUsableSpectrumRatio = 0.9f; + + private const double DefaultSoundCardSampleRate = 48000.0; + + private const int FFTFrameQueueLength = 3; + + private const int SpectrumAnalyzerInterval = 20; + + private const int MaxLockTime = 300000; + + private WindowType _fftWindowType; + + private IFrontendController _frontendController; + + private readonly Dictionary _frontendControllers = new Dictionary(); + + private readonly List _builtinControllers = new List(); + + private readonly IQCorrectionProcessor _iqBalancerProcessor = new IQCorrectionProcessor(); + + private readonly Vfo _vfo; + + private readonly HookManager _hookManager; + + private readonly StreamControl _streamControl; + + private readonly ComplexFifoStream _fftStream = new ComplexFifoStream(BlockMode.BlockingRead); + + private readonly SharpEvent _fftEvent = new SharpEvent(false); + + private readonly ReaderWriterLock _fftResolutionLock = new ReaderWriterLock(); + + private FloatCircularBuffer _fftFrames; + + private UnsafeBuffer _iqBuffer; + + private unsafe Complex* _iqPtr; + + private UnsafeBuffer _fftBuffer; + + private unsafe Complex* _fftPtr; + + private UnsafeBuffer _fftWindow; + + private unsafe float* _fftWindowPtr; + + private UnsafeBuffer _fftSpectrum; + + private unsafe float* _fftSpectrumPtr; + + private unsafe float* _fftDisplayPtr; + + private int _fftDisplaySize; + + private UnsafeBuffer _scaledFFTSpectrum; + + private unsafe byte* _scaledFFTSpectrumPtr; + + private System.Windows.Forms.Timer _waterfallTimer; + + private System.Windows.Forms.Timer _spectrumAnalyzerTimer; + + private long _centerFrequency; + + private long _frequencySet; + + private long _frequencyShift; + + private int _fftFramesCount; + + private int _fftcorrectionFPS; + + private float _fftAverageFPS; + + private DateTime _lastFFTTick; + + private int _inputBufferLength; + + private int _fftBins; + + private int _stepSize; + + private int _usableSpectrumWidth; + + private volatile bool _fftIsRunning; + + private bool _changingStickySpot; + + private bool _changingCenterSpot; + + private bool _changingSampleRate; + + private bool _configuringSnap; + + private bool _configuringSquelch; + + private bool _terminated; + + private string _waveFile; + + private Point _lastLocation; + + private Size _lastSize; + + private string _lastSourceName; + + private bool _initializing; + + private int _oldTopSplitterPosition = 200; + + private int _oldBottomSplitterPosition = 200; + + private int _oldLeftSplitterPosition = 200; + + private int _oldRightSplitterPosition = 200; + + private int _sourcePanelHeight; + + private int _ifOffset; + + private float _usableSpectrumRatio = 0.9f; + + private TuningStyle _tuningStyle; + + private bool _tuningStyleFreezed; + + private float _tuningLimit = (float)Math.Min(0.5, Utils.GetDoubleSetting("tuningLimit", 0.4)); + + private readonly ToolTip _tooltip = new ToolTip(); + + private readonly float _fftOffset = (float)Utils.GetDoubleSetting("fftOffset", -40.0); + + private readonly int _minOutputSampleRate = Utils.GetIntSetting("minOutputSampleRate", 24000); + + private readonly Dictionary _sharpPlugins = new Dictionary(); + + private readonly Dictionary _modeStates = new Dictionary(); + + private SharpControlProxy _sharpControlProxy; + + public DetectorType DetectorType + { + get + { + return this._vfo.DetectorType; + } + set + { + switch (value) + { + case DetectorType.AM: + this.amRadioButton.Checked = true; + break; + case DetectorType.CW: + this.cwRadioButton.Checked = true; + break; + case DetectorType.DSB: + this.dsbRadioButton.Checked = true; + break; + case DetectorType.LSB: + this.lsbRadioButton.Checked = true; + break; + case DetectorType.USB: + this.usbRadioButton.Checked = true; + break; + case DetectorType.NFM: + this.nfmRadioButton.Checked = true; + break; + case DetectorType.WFM: + this.wfmRadioButton.Checked = true; + break; + case DetectorType.RAW: + this.rawRadioButton.Checked = true; + break; + } + } + } + + public WindowType FilterType + { + get + { + return (WindowType)(this.filterTypeComboBox.SelectedIndex + 1); + } + set + { + this.filterTypeComboBox.SelectedIndex = (int)(value - 1); + } + } + + public bool IsPlaying + { + get + { + return this._streamControl.IsPlaying; + } + } + + public long Frequency + { + get + { + return this.vfoFrequencyEdit.Frequency; + } + set + { + this.SetFrequency(value, false); + } + } + + public long CenterFrequency + { + get + { + return this._centerFrequency; + } + set + { + if (this._frontendController == null) + { + throw new ApplicationException("Cannot set the center frequency when no front end is connected"); + } + this.SetCenterFrequency(value); + } + } + + public long FrequencyShift + { + get + { + return (long)this.frequencyShiftNumericUpDown.Value; + } + set + { + this.frequencyShiftNumericUpDown.Value = value; + } + } + + public bool FrequencyShiftEnabled + { + get + { + return this.frequencyShiftCheckBox.Checked; + } + set + { + this.frequencyShiftCheckBox.Checked = value; + } + } + + public int FilterBandwidth + { + get + { + return (int)this.filterBandwidthNumericUpDown.Value; + } + set + { + if ((decimal)value <= this.filterBandwidthNumericUpDown.Maximum) + { + this.filterBandwidthNumericUpDown.Value = value; + } + else + { + this.filterBandwidthNumericUpDown.Value = this.filterBandwidthNumericUpDown.Maximum; + } + } + } + + public int FilterOrder + { + get + { + return (int)this.filterOrderNumericUpDown.Value; + } + set + { + this.filterOrderNumericUpDown.Value = value; + } + } + + public bool SquelchEnabled + { + get + { + return this.useSquelchCheckBox.Checked; + } + set + { + this.useSquelchCheckBox.Checked = value; + } + } + + public int SquelchThreshold + { + get + { + return (int)this.squelchNumericUpDown.Value; + } + set + { + this.squelchNumericUpDown.Value = value; + } + } + + public int CWShift + { + get + { + return (int)this.cwShiftNumericUpDown.Value; + } + set + { + this.cwShiftNumericUpDown.Value = value; + } + } + + public bool SnapToGrid + { + get + { + return this.snapFrequencyCheckBox.Checked; + } + set + { + this.snapFrequencyCheckBox.Checked = value; + } + } + + public bool SwapIq + { + get + { + return this.swapIQCheckBox.Checked; + } + set + { + this.swapIQCheckBox.Checked = value; + } + } + + public bool FmStereo + { + get + { + return this.fmStereoCheckBox.Checked; + } + set + { + this.fmStereoCheckBox.Checked = value; + } + } + + public bool MarkPeaks + { + get + { + return this.markPeaksCheckBox.Checked; + } + set + { + this.markPeaksCheckBox.Checked = value; + } + } + + public int AudioGain + { + get + { + return this.audioGainTrackBar.Value; + } + set + { + this.audioGainTrackBar.Value = value; + } + } + + public bool AudioIsMuted + { + get + { + return this._vfo.Muted; + } + set + { + this._vfo.Muted = value; + this.UpdateMuteButton(); + } + } + + public string SourceName + { + get + { + if (this.SourceIsWaveFile) + { + if (File.Exists(this._waveFile)) + { + Uri uri = new Uri(this._waveFile); + return uri.AbsolutePath; + } + } + else + { + if (this.SourceIsSoundCard) + { + return "Sound Card"; + } + if (this.SourceIsFrontEnd) + { + if (this._frontendController == null) + { + return string.Empty; + } + return this._frontendController.GetType().AssemblyQualifiedName; + } + } + return string.Empty; + } + } + + public Type SourceType + { + get + { + if (this.SourceIsFrontEnd) + { + if (this._frontendController == null) + { + return null; + } + return this._frontendController.GetType(); + } + return null; + } + } + + public object Source + { + get + { + if (this.SourceIsFrontEnd) + { + if (this._frontendController == null) + { + return null; + } + return this._frontendController; + } + return null; + } + } + + public bool FilterAudio + { + get + { + return this.filterAudioCheckBox.Checked; + } + set + { + this.filterAudioCheckBox.Checked = value; + } + } + + public bool UnityGain + { + get + { + return this.unityGainCheckBox.Checked; + } + set + { + this.unityGainCheckBox.Checked = value; + } + } + + public bool UseAgc + { + get + { + return this.agcCheckBox.Checked; + } + set + { + this.agcCheckBox.Checked = value; + } + } + + public bool AgcHang + { + get + { + return this.agcUseHangCheckBox.Checked; + } + set + { + this.agcUseHangCheckBox.Checked = value; + } + } + + public int AgcThreshold + { + get + { + return (int)this.agcThresholdNumericUpDown.Value; + } + set + { + this.agcThresholdNumericUpDown.Value = value; + } + } + + public int AgcDecay + { + get + { + return (int)this.agcDecayNumericUpDown.Value; + } + set + { + this.agcDecayNumericUpDown.Value = value; + } + } + + public int AgcSlope + { + get + { + return (int)this.agcSlopeNumericUpDown.Value; + } + set + { + this.agcSlopeNumericUpDown.Value = value; + } + } + + public float SAttack + { + get + { + return (float)this.sAttackTrackBar.Value / (float)this.sAttackTrackBar.Maximum; + } + set + { + this.sAttackTrackBar.Value = (int)(value * (float)this.sAttackTrackBar.Maximum); + } + } + + public float SDecay + { + get + { + return (float)this.sDecayTrackBar.Value / (float)this.sDecayTrackBar.Maximum; + } + set + { + this.sDecayTrackBar.Value = (int)(value * (float)this.sDecayTrackBar.Maximum); + } + } + + public float WAttack + { + get + { + return (float)this.wAttackTrackBar.Value / (float)this.wAttackTrackBar.Maximum; + } + set + { + this.wAttackTrackBar.Value = (int)(value * (float)this.wAttackTrackBar.Maximum); + } + } + + public float WDecay + { + get + { + return (float)this.wDecayTrackBar.Value / (float)this.wDecayTrackBar.Maximum; + } + set + { + this.wDecayTrackBar.Value = (int)(value * (float)this.wDecayTrackBar.Maximum); + } + } + + public int Zoom + { + get + { + return this.fftZoomTrackBar.Value; + } + set + { + this.fftZoomTrackBar.Value = value; + } + } + + public bool UseTimeMarkers + { + get + { + return this.useTimestampsCheckBox.Checked; + } + set + { + this.useTimestampsCheckBox.Checked = value; + } + } + + public string RdsProgramService + { + get + { + return this._vfo.RdsStationName; + } + } + + public string RdsRadioText + { + get + { + return this._vfo.RdsStationText; + } + } + + public ushort RdsPICode + { + get + { + return this._vfo.RdsPICode; + } + } + + public bool RdsUseFEC + { + get + { + return this._vfo.RdsUseFEC; + } + set + { + this._vfo.RdsUseFEC = value; + } + } + + public int RFBandwidth + { + get + { + return (int)this._vfo.SampleRate; + } + } + + public int RFDisplayBandwidth + { + get + { + return this._usableSpectrumWidth; + } + } + + public bool SourceIsWaveFile + { + get + { + return this.iqSourceComboBox.SelectedIndex == this.iqSourceComboBox.Items.Count - 2; + } + } + + public bool SourceIsSoundCard + { + get + { + return this.iqSourceComboBox.SelectedIndex == this.iqSourceComboBox.Items.Count - 1; + } + } + + public bool SourceIsFrontEnd + { + get + { + if (!this.SourceIsSoundCard) + { + return !this.SourceIsWaveFile; + } + return false; + } + } + + public bool SourceIsTunable + { + get + { + if (!this.SourceIsSoundCard && !this.SourceIsWaveFile) + { + if (this._frontendController == null) + { + return false; + } + if (this._frontendController is ITunableSource) + { + return ((ITunableSource)this._frontendController).CanTune; + } + return false; + } + return false; + } + } + + public bool IsSquelchOpen + { + get + { + return this._vfo.IsSquelchOpen; + } + } + + public int FFTResolution + { + get + { + return this._fftBins; + } + } + + public float FFTRange + { + get + { + return (float)this.spectrumAnalyzer.DisplayRange; + } + } + + public float FFTOffset + { + get + { + return (float)this.spectrumAnalyzer.DisplayOffset; + } + } + + public int FFTContrast + { + get + { + return this.spectrumAnalyzer.Contrast; + } + } + + public ColorBlend Gradient + { + get + { + return this.spectrumAnalyzer.VerticalLinesGradient; + } + } + + public SpectrumStyle FFTSpectrumStyle + { + get + { + return this.spectrumAnalyzer.SpectrumStyle; + } + } + + public int StepSize + { + get + { + return this._stepSize; + } + set + { + if (this.SetStepSize(value)) + { + this._stepSize = value; + } + } + } + + public bool BypassDemodulation + { + get + { + return this._vfo.BypassDemodulation; + } + set + { + this._vfo.BypassDemodulation = value; + } + } + + public int TunableBandwidth + { + get + { + return (int)Math.Ceiling((double)((float)this._usableSpectrumWidth * this._tuningLimit * 2f)); + } + } + + public TuningStyle TuningStyle + { + get + { + return this._tuningStyle; + } + set + { + if (!this._tuningStyleFreezed) + { + this._tuningStyle = value; + } + this.UpdateTuningStyle(); + } + } + + public int IFOffset + { + get + { + return this._ifOffset; + } + } + + public float TuningLimit + { + get + { + return this._tuningLimit; + } + set + { + if (value != this._tuningLimit) + { + this._tuningLimit = value; + this._tuningLimit = Math.Min(0.5f, this._tuningLimit); + this._tuningLimit = Math.Max(0.1f, this._tuningLimit); + this.UpdateTunableBandwidth(); + } + } + } + + public float VisualSNR + { + get + { + return this.spectrumAnalyzer.VisualSNR; + } + } + + public bool TuningStyleFreezed + { + get + { + return this._tuningStyleFreezed; + } + set + { + this._tuningStyleFreezed = value; + this.tuningStyleButton.Enabled = !this._tuningStyleFreezed; + } + } + + public bool UseFFTSource + { + get + { + if (this._frontendController is IFFTSource) + { + return (this._frontendController as IFFTSource).FFTEnabled; + } + return false; + } + } + + public double AudioSampleRate + { + get + { + return this._streamControl.AudioSampleRate; + } + } + + public event PropertyChangedEventHandler PropertyChanged; + + public event CustomPaintEventHandler WaterfallCustomPaint; + + public event CustomPaintEventHandler SpectrumAnalyzerCustomPaint; + + public event CustomPaintEventHandler SpectrumAnalyzerBackgroundCustomPaint; + + private void InitializeComponent() + { + this.components = new Container(); + ComponentResourceManager componentResourceManager = new ComponentResourceManager(typeof(MainForm)); + this.openDlg = new OpenFileDialog(); + this.iqTimer = new System.Windows.Forms.Timer(this.components); + this.fftContrastTrackBar = new TrackBar(); + this.fftZoomTrackBar = new TrackBar(); + this.label19 = new Label(); + this.label20 = new Label(); + this.controlPanel = new Panel(); + this.sourceCollapsiblePanel = new SDRSharp.CollapsiblePanel.CollapsiblePanel(); + this.sourceTableLayoutPanel = new TableLayoutPanel(); + this.iqSourceComboBox = new ComboBox(); + this.radioCollapsiblePanel = new SDRSharp.CollapsiblePanel.CollapsiblePanel(); + this.radioTableLayoutPanel = new TableLayoutPanel(); + this.swapIQCheckBox = new CheckBox(); + this.frequencyShiftCheckBox = new CheckBox(); + this.tableLayoutPanel7 = new TableLayoutPanel(); + this.amRadioButton = new RadioButton(); + this.nfmRadioButton = new RadioButton(); + this.lsbRadioButton = new RadioButton(); + this.usbRadioButton = new RadioButton(); + this.wfmRadioButton = new RadioButton(); + this.dsbRadioButton = new RadioButton(); + this.cwRadioButton = new RadioButton(); + this.rawRadioButton = new RadioButton(); + this.useSquelchCheckBox = new CheckBox(); + this.stepSizeComboBox = new ComboBox(); + this.cwShiftNumericUpDown = new NumericUpDown(); + this.label18 = new Label(); + this.label15 = new Label(); + this.squelchNumericUpDown = new NumericUpDown(); + this.filterBandwidthNumericUpDown = new NumericUpDown(); + this.label1 = new Label(); + this.label5 = new Label(); + this.filterOrderNumericUpDown = new NumericUpDown(); + this.frequencyShiftNumericUpDown = new NumericUpDown(); + this.filterTypeComboBox = new ComboBox(); + this.label16 = new Label(); + this.correctIQCheckBox = new CheckBox(); + this.snapFrequencyCheckBox = new CheckBox(); + this.lockCarrierCheckBox = new CheckBox(); + this.fmStereoCheckBox = new CheckBox(); + this.useAntiFadingCheckBox = new CheckBox(); + this.audioCollapsiblePanel = new SDRSharp.CollapsiblePanel.CollapsiblePanel(); + this.tableLayoutPanel1 = new TableLayoutPanel(); + this.label13 = new Label(); + this.sampleRateComboBox = new ComboBox(); + this.label11 = new Label(); + this.inputDeviceComboBox = new ComboBox(); + this.label12 = new Label(); + this.outputDeviceComboBox = new ComboBox(); + this.latencyNumericUpDown = new NumericUpDown(); + this.label6 = new Label(); + this.unityGainCheckBox = new CheckBox(); + this.filterAudioCheckBox = new CheckBox(); + this.agcCollapsiblePanel = new SDRSharp.CollapsiblePanel.CollapsiblePanel(); + this.tableLayoutPanel2 = new TableLayoutPanel(); + this.agcCheckBox = new CheckBox(); + this.agcSlopeNumericUpDown = new NumericUpDown(); + this.agcUseHangCheckBox = new CheckBox(); + this.label22 = new Label(); + this.label4 = new Label(); + this.agcDecayNumericUpDown = new NumericUpDown(); + this.label10 = new Label(); + this.agcThresholdNumericUpDown = new NumericUpDown(); + this.fftCollapsiblePanel = new SDRSharp.CollapsiblePanel.CollapsiblePanel(); + this.tableLayoutPanel3 = new TableLayoutPanel(); + this.label7 = new Label(); + this.viewComboBox = new ComboBox(); + this.label8 = new Label(); + this.fftWindowComboBox = new ComboBox(); + this.label21 = new Label(); + this.fftResolutionComboBox = new ComboBox(); + this.groupBox1 = new GroupBox(); + this.tableLayoutPanel5 = new TableLayoutPanel(); + this.label28 = new Label(); + this.fftSpeedTrackBar = new TrackBar(); + this.smoothingGroupBox = new GroupBox(); + this.tableLayoutPanel4 = new TableLayoutPanel(); + this.label23 = new Label(); + this.wDecayTrackBar = new TrackBar(); + this.wAttackTrackBar = new TrackBar(); + this.label25 = new Label(); + this.sDecayTrackBar = new TrackBar(); + this.sAttackTrackBar = new TrackBar(); + this.label24 = new Label(); + this.label26 = new Label(); + this.markPeaksCheckBox = new CheckBox(); + this.useTimestampsCheckBox = new CheckBox(); + this.label14 = new Label(); + this.gradientButton = new Button(); + this.label3 = new Label(); + this.spectrumStyleComboBox = new ComboBox(); + this.fftOffsetTrackBar = new TrackBar(); + this.fftRangeTrackBar = new TrackBar(); + this.audioGainTrackBar = new TrackBar(); + this.label17 = new Label(); + this.scrollPanel = new Panel(); + this.rightTableLayoutPanel = new TableLayoutPanel(); + this.label2 = new Label(); + this.centerPanel = new Panel(); + this.spectrumPanel = new Panel(); + this.spectrumSplitter = new Splitter(); + this.waterfall = new Waterfall(); + this.spectrumAnalyzer = new SpectrumAnalyzer(); + this.bottomSplitter = new Splitter(); + this.bottomPluginPanel = new TableLayoutPanel(); + this.topSplitter = new Splitter(); + this.topPluginPanel = new TableLayoutPanel(); + this.rightSplitter = new Splitter(); + this.leftSplitter = new Splitter(); + this.leftPluginPanel = new TableLayoutPanel(); + this.rightPluginPanel = new TableLayoutPanel(); + this.settingsTableLayoutPanel = new TableLayoutPanel(); + this.playStopButton = new Button(); + this.configureSourceButton = new Button(); + this.toggleMenuButton = new Button(); + this.muteButton = new Button(); + this.vfoFrequencyEdit = new SDRSharp.FrequencyEdit.FrequencyEdit(); + this.tuningStyleButton = new Button(); + this.logoPictureBox = new PictureBox(); + this.menuSpacerPanel = new Panel(); + ((ISupportInitialize)this.fftContrastTrackBar).BeginInit(); + ((ISupportInitialize)this.fftZoomTrackBar).BeginInit(); + this.controlPanel.SuspendLayout(); + this.sourceCollapsiblePanel.Content.SuspendLayout(); + this.sourceCollapsiblePanel.SuspendLayout(); + this.sourceTableLayoutPanel.SuspendLayout(); + this.radioCollapsiblePanel.Content.SuspendLayout(); + this.radioCollapsiblePanel.SuspendLayout(); + this.radioTableLayoutPanel.SuspendLayout(); + this.tableLayoutPanel7.SuspendLayout(); + ((ISupportInitialize)this.cwShiftNumericUpDown).BeginInit(); + ((ISupportInitialize)this.squelchNumericUpDown).BeginInit(); + ((ISupportInitialize)this.filterBandwidthNumericUpDown).BeginInit(); + ((ISupportInitialize)this.filterOrderNumericUpDown).BeginInit(); + ((ISupportInitialize)this.frequencyShiftNumericUpDown).BeginInit(); + this.audioCollapsiblePanel.Content.SuspendLayout(); + this.audioCollapsiblePanel.SuspendLayout(); + this.tableLayoutPanel1.SuspendLayout(); + ((ISupportInitialize)this.latencyNumericUpDown).BeginInit(); + this.agcCollapsiblePanel.Content.SuspendLayout(); + this.agcCollapsiblePanel.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); + ((ISupportInitialize)this.agcSlopeNumericUpDown).BeginInit(); + ((ISupportInitialize)this.agcDecayNumericUpDown).BeginInit(); + ((ISupportInitialize)this.agcThresholdNumericUpDown).BeginInit(); + this.fftCollapsiblePanel.Content.SuspendLayout(); + this.fftCollapsiblePanel.SuspendLayout(); + this.tableLayoutPanel3.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.tableLayoutPanel5.SuspendLayout(); + ((ISupportInitialize)this.fftSpeedTrackBar).BeginInit(); + this.smoothingGroupBox.SuspendLayout(); + this.tableLayoutPanel4.SuspendLayout(); + ((ISupportInitialize)this.wDecayTrackBar).BeginInit(); + ((ISupportInitialize)this.wAttackTrackBar).BeginInit(); + ((ISupportInitialize)this.sDecayTrackBar).BeginInit(); + ((ISupportInitialize)this.sAttackTrackBar).BeginInit(); + ((ISupportInitialize)this.fftOffsetTrackBar).BeginInit(); + ((ISupportInitialize)this.fftRangeTrackBar).BeginInit(); + ((ISupportInitialize)this.audioGainTrackBar).BeginInit(); + this.scrollPanel.SuspendLayout(); + this.rightTableLayoutPanel.SuspendLayout(); + this.centerPanel.SuspendLayout(); + this.spectrumPanel.SuspendLayout(); + this.settingsTableLayoutPanel.SuspendLayout(); + ((ISupportInitialize)this.logoPictureBox).BeginInit(); + base.SuspendLayout(); + this.openDlg.DefaultExt = "wav"; + this.openDlg.Filter = "WAV files|*.wav"; + this.iqTimer.Enabled = true; + this.iqTimer.Tick += this.iqTimer_Tick; + this.fftContrastTrackBar.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom); + this.fftContrastTrackBar.Location = new Point(3, 186); + this.fftContrastTrackBar.Maximum = 24; + this.fftContrastTrackBar.Minimum = -24; + this.fftContrastTrackBar.Name = "fftContrastTrackBar"; + this.fftContrastTrackBar.Orientation = Orientation.Vertical; + this.fftContrastTrackBar.RightToLeftLayout = true; + this.fftContrastTrackBar.Size = new Size(45, 151); + this.fftContrastTrackBar.TabIndex = 1; + this.fftContrastTrackBar.TickFrequency = 6; + this.fftContrastTrackBar.TickStyle = TickStyle.Both; + this.fftContrastTrackBar.ValueChanged += this.fftContrastTrackBar_Changed; + this.fftZoomTrackBar.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom); + this.fftZoomTrackBar.Location = new Point(3, 16); + this.fftZoomTrackBar.Maximum = 50; + this.fftZoomTrackBar.Name = "fftZoomTrackBar"; + this.fftZoomTrackBar.Orientation = Orientation.Vertical; + this.fftZoomTrackBar.RightToLeftLayout = true; + this.fftZoomTrackBar.Size = new Size(45, 151); + this.fftZoomTrackBar.TabIndex = 0; + this.fftZoomTrackBar.TickFrequency = 5; + this.fftZoomTrackBar.TickStyle = TickStyle.Both; + this.fftZoomTrackBar.ValueChanged += this.fftZoomTrackBar_ValueChanged; + this.label19.Anchor = AnchorStyles.None; + this.label19.AutoSize = true; + this.label19.Location = new Point(9, 0); + this.label19.Name = "label19"; + this.label19.Size = new Size(34, 13); + this.label19.TabIndex = 19; + this.label19.Text = "Zoom"; + this.label19.TextAlign = ContentAlignment.MiddleCenter; + this.label20.Anchor = AnchorStyles.None; + this.label20.AutoSize = true; + this.label20.Location = new Point(3, 170); + this.label20.Name = "label20"; + this.label20.Size = new Size(46, 13); + this.label20.TabIndex = 20; + this.label20.Text = "Contrast"; + this.label20.TextAlign = ContentAlignment.MiddleCenter; + this.controlPanel.AutoSize = true; + this.controlPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink; + this.controlPanel.Controls.Add(this.sourceCollapsiblePanel); + this.controlPanel.Controls.Add(this.radioCollapsiblePanel); + this.controlPanel.Controls.Add(this.audioCollapsiblePanel); + this.controlPanel.Controls.Add(this.fftCollapsiblePanel); + this.controlPanel.Controls.Add(this.agcCollapsiblePanel); + this.controlPanel.Location = new Point(0, 0); + this.controlPanel.Margin = new Padding(0); + this.controlPanel.Name = "controlPanel"; + this.controlPanel.Size = new Size(227, 1218); + this.controlPanel.TabIndex = 25; + this.sourceCollapsiblePanel.AutoHeight = true; + this.sourceCollapsiblePanel.Content.Controls.Add(this.sourceTableLayoutPanel); + this.sourceCollapsiblePanel.Content.Location = new Point(0, 24); + this.sourceCollapsiblePanel.Content.Margin = new Padding(2); + this.sourceCollapsiblePanel.Content.Name = "Content"; + this.sourceCollapsiblePanel.Content.Size = new Size(224, 28); + this.sourceCollapsiblePanel.Content.TabIndex = 1; + this.sourceCollapsiblePanel.Location = new Point(0, 0); + this.sourceCollapsiblePanel.Margin = new Padding(0); + this.sourceCollapsiblePanel.Name = "sourceCollapsiblePanel"; + this.sourceCollapsiblePanel.NextPanel = this.radioCollapsiblePanel; + this.sourceCollapsiblePanel.PanelTitle = "Source"; + this.sourceCollapsiblePanel.Size = new Size(224, 52); + this.sourceCollapsiblePanel.TabIndex = 4; + this.sourceTableLayoutPanel.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right); + this.sourceTableLayoutPanel.AutoSize = true; + this.sourceTableLayoutPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink; + this.sourceTableLayoutPanel.ColumnCount = 1; + this.sourceTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.sourceTableLayoutPanel.Controls.Add(this.iqSourceComboBox, 0, 0); + this.sourceTableLayoutPanel.Location = new Point(0, 0); + this.sourceTableLayoutPanel.Margin = new Padding(0); + this.sourceTableLayoutPanel.Name = "sourceTableLayoutPanel"; + this.sourceTableLayoutPanel.RowCount = 2; + this.sourceTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.sourceTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.sourceTableLayoutPanel.Size = new Size(224, 27); + this.sourceTableLayoutPanel.TabIndex = 0; + this.iqSourceComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.iqSourceComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.iqSourceComboBox.DropDownWidth = 250; + this.iqSourceComboBox.FormattingEnabled = true; + this.iqSourceComboBox.Location = new Point(3, 3); + this.iqSourceComboBox.Name = "iqSourceComboBox"; + this.iqSourceComboBox.Size = new Size(218, 21); + this.iqSourceComboBox.TabIndex = 1; + this.iqSourceComboBox.SelectedIndexChanged += this.iqSourceComboBox_SelectedIndexChanged; + this.radioCollapsiblePanel.AutoHeight = false; + this.radioCollapsiblePanel.Content.Controls.Add(this.radioTableLayoutPanel); + this.radioCollapsiblePanel.Content.Location = new Point(0, 24); + this.radioCollapsiblePanel.Content.Name = "Content"; + this.radioCollapsiblePanel.Content.Size = new Size(224, 341); + this.radioCollapsiblePanel.Content.TabIndex = 1; + this.radioCollapsiblePanel.Location = new Point(0, 52); + this.radioCollapsiblePanel.Margin = new Padding(0); + this.radioCollapsiblePanel.Name = "radioCollapsiblePanel"; + this.radioCollapsiblePanel.NextPanel = this.audioCollapsiblePanel; + this.radioCollapsiblePanel.PanelTitle = "Radio"; + this.radioCollapsiblePanel.Size = new Size(224, 365); + this.radioCollapsiblePanel.TabIndex = 0; + this.radioTableLayoutPanel.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right); + this.radioTableLayoutPanel.ColumnCount = 4; + this.radioTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.radioTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.radioTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.radioTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.radioTableLayoutPanel.Controls.Add(this.swapIQCheckBox, 2, 10); + this.radioTableLayoutPanel.Controls.Add(this.frequencyShiftCheckBox, 0, 1); + this.radioTableLayoutPanel.Controls.Add(this.tableLayoutPanel7, 0, 0); + this.radioTableLayoutPanel.Controls.Add(this.useSquelchCheckBox, 0, 5); + this.radioTableLayoutPanel.Controls.Add(this.stepSizeComboBox, 2, 8); + this.radioTableLayoutPanel.Controls.Add(this.cwShiftNumericUpDown, 2, 6); + this.radioTableLayoutPanel.Controls.Add(this.label18, 2, 7); + this.radioTableLayoutPanel.Controls.Add(this.label15, 2, 5); + this.radioTableLayoutPanel.Controls.Add(this.squelchNumericUpDown, 0, 6); + this.radioTableLayoutPanel.Controls.Add(this.filterBandwidthNumericUpDown, 0, 4); + this.radioTableLayoutPanel.Controls.Add(this.label1, 0, 3); + this.radioTableLayoutPanel.Controls.Add(this.label5, 2, 3); + this.radioTableLayoutPanel.Controls.Add(this.filterOrderNumericUpDown, 2, 4); + this.radioTableLayoutPanel.Controls.Add(this.frequencyShiftNumericUpDown, 1, 1); + this.radioTableLayoutPanel.Controls.Add(this.filterTypeComboBox, 1, 2); + this.radioTableLayoutPanel.Controls.Add(this.label16, 0, 2); + this.radioTableLayoutPanel.Controls.Add(this.correctIQCheckBox, 2, 9); + this.radioTableLayoutPanel.Controls.Add(this.snapFrequencyCheckBox, 0, 8); + this.radioTableLayoutPanel.Controls.Add(this.lockCarrierCheckBox, 0, 9); + this.radioTableLayoutPanel.Controls.Add(this.fmStereoCheckBox, 0, 7); + this.radioTableLayoutPanel.Controls.Add(this.useAntiFadingCheckBox, 0, 10); + this.radioTableLayoutPanel.Location = new Point(0, 0); + this.radioTableLayoutPanel.Name = "radioTableLayoutPanel"; + this.radioTableLayoutPanel.RowCount = 11; + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.radioTableLayoutPanel.Size = new Size(224, 341); + this.radioTableLayoutPanel.TabIndex = 34; + this.swapIQCheckBox.Anchor = AnchorStyles.Right; + this.swapIQCheckBox.AutoSize = true; + this.radioTableLayoutPanel.SetColumnSpan(this.swapIQCheckBox, 2); + this.swapIQCheckBox.Location = new Point(143, 321); + this.swapIQCheckBox.Name = "swapIQCheckBox"; + this.swapIQCheckBox.RightToLeft = RightToLeft.Yes; + this.swapIQCheckBox.Size = new Size(79, 17); + this.swapIQCheckBox.TabIndex = 25; + this.swapIQCheckBox.Text = "Swap I && Q"; + this.swapIQCheckBox.UseVisualStyleBackColor = true; + this.swapIQCheckBox.CheckedChanged += this.swapIQCheckBox_CheckedChanged; + this.frequencyShiftCheckBox.Anchor = AnchorStyles.Left; + this.frequencyShiftCheckBox.AutoSize = true; + this.frequencyShiftCheckBox.Location = new Point(3, 106); + this.frequencyShiftCheckBox.Name = "frequencyShiftCheckBox"; + this.frequencyShiftCheckBox.Size = new Size(47, 17); + this.frequencyShiftCheckBox.TabIndex = 7; + this.frequencyShiftCheckBox.Text = "Shift"; + this.frequencyShiftCheckBox.UseVisualStyleBackColor = true; + this.frequencyShiftCheckBox.CheckedChanged += this.frequencyShiftCheckBox_CheckStateChanged; + this.tableLayoutPanel7.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right); + this.tableLayoutPanel7.ColumnCount = 4; + this.radioTableLayoutPanel.SetColumnSpan(this.tableLayoutPanel7, 4); + this.tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel7.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel7.Controls.Add(this.amRadioButton, 1, 0); + this.tableLayoutPanel7.Controls.Add(this.nfmRadioButton, 0, 0); + this.tableLayoutPanel7.Controls.Add(this.lsbRadioButton, 2, 0); + this.tableLayoutPanel7.Controls.Add(this.usbRadioButton, 3, 0); + this.tableLayoutPanel7.Controls.Add(this.wfmRadioButton, 0, 1); + this.tableLayoutPanel7.Controls.Add(this.dsbRadioButton, 1, 1); + this.tableLayoutPanel7.Controls.Add(this.cwRadioButton, 2, 1); + this.tableLayoutPanel7.Controls.Add(this.rawRadioButton, 3, 1); + this.tableLayoutPanel7.Location = new Point(3, 3); + this.tableLayoutPanel7.Name = "tableLayoutPanel7"; + this.tableLayoutPanel7.RowCount = 2; + this.tableLayoutPanel7.RowStyles.Add(new RowStyle(SizeType.Percent, 50f)); + this.tableLayoutPanel7.RowStyles.Add(new RowStyle(SizeType.Percent, 50f)); + this.tableLayoutPanel7.Size = new Size(219, 94); + this.tableLayoutPanel7.TabIndex = 32; + this.amRadioButton.Anchor = AnchorStyles.Left; + this.amRadioButton.AutoSize = true; + this.amRadioButton.Location = new Point(60, 15); + this.amRadioButton.Name = "amRadioButton"; + this.amRadioButton.Size = new Size(41, 17); + this.amRadioButton.TabIndex = 1; + this.amRadioButton.Text = "AM"; + this.amRadioButton.UseVisualStyleBackColor = true; + this.amRadioButton.CheckedChanged += this.modeRadioButton_CheckStateChanged; + this.nfmRadioButton.Anchor = AnchorStyles.Left; + this.nfmRadioButton.AutoSize = true; + this.nfmRadioButton.Location = new Point(3, 15); + this.nfmRadioButton.Name = "nfmRadioButton"; + this.nfmRadioButton.Size = new Size(48, 17); + this.nfmRadioButton.TabIndex = 0; + this.nfmRadioButton.Text = "NFM"; + this.nfmRadioButton.UseVisualStyleBackColor = true; + this.nfmRadioButton.CheckedChanged += this.modeRadioButton_CheckStateChanged; + this.lsbRadioButton.Anchor = AnchorStyles.Left; + this.lsbRadioButton.AutoSize = true; + this.lsbRadioButton.Location = new Point(113, 15); + this.lsbRadioButton.Name = "lsbRadioButton"; + this.lsbRadioButton.Size = new Size(45, 17); + this.lsbRadioButton.TabIndex = 2; + this.lsbRadioButton.Text = "LSB"; + this.lsbRadioButton.UseVisualStyleBackColor = true; + this.lsbRadioButton.CheckedChanged += this.modeRadioButton_CheckStateChanged; + this.usbRadioButton.Anchor = AnchorStyles.Left; + this.usbRadioButton.AutoSize = true; + this.usbRadioButton.Location = new Point(164, 15); + this.usbRadioButton.Name = "usbRadioButton"; + this.usbRadioButton.Size = new Size(47, 17); + this.usbRadioButton.TabIndex = 3; + this.usbRadioButton.Text = "USB"; + this.usbRadioButton.UseVisualStyleBackColor = true; + this.usbRadioButton.CheckedChanged += this.modeRadioButton_CheckStateChanged; + this.wfmRadioButton.Anchor = AnchorStyles.Left; + this.wfmRadioButton.AutoSize = true; + this.wfmRadioButton.Location = new Point(3, 62); + this.wfmRadioButton.Name = "wfmRadioButton"; + this.wfmRadioButton.Size = new Size(51, 17); + this.wfmRadioButton.TabIndex = 4; + this.wfmRadioButton.Text = "WFM"; + this.wfmRadioButton.UseVisualStyleBackColor = true; + this.wfmRadioButton.CheckedChanged += this.modeRadioButton_CheckStateChanged; + this.dsbRadioButton.Anchor = AnchorStyles.Left; + this.dsbRadioButton.AutoSize = true; + this.dsbRadioButton.Location = new Point(60, 62); + this.dsbRadioButton.Name = "dsbRadioButton"; + this.dsbRadioButton.Size = new Size(47, 17); + this.dsbRadioButton.TabIndex = 5; + this.dsbRadioButton.Text = "DSB"; + this.dsbRadioButton.UseVisualStyleBackColor = true; + this.dsbRadioButton.CheckedChanged += this.modeRadioButton_CheckStateChanged; + this.cwRadioButton.Anchor = AnchorStyles.Left; + this.cwRadioButton.AutoSize = true; + this.cwRadioButton.Location = new Point(113, 62); + this.cwRadioButton.Name = "cwRadioButton"; + this.cwRadioButton.Size = new Size(43, 17); + this.cwRadioButton.TabIndex = 6; + this.cwRadioButton.Text = "CW"; + this.cwRadioButton.UseVisualStyleBackColor = true; + this.cwRadioButton.CheckedChanged += this.modeRadioButton_CheckStateChanged; + this.rawRadioButton.Anchor = AnchorStyles.Left; + this.rawRadioButton.AutoSize = true; + this.rawRadioButton.Location = new Point(164, 62); + this.rawRadioButton.Name = "rawRadioButton"; + this.rawRadioButton.Size = new Size(51, 17); + this.rawRadioButton.TabIndex = 6; + this.rawRadioButton.Text = "RAW"; + this.rawRadioButton.UseVisualStyleBackColor = true; + this.rawRadioButton.CheckedChanged += this.modeRadioButton_CheckStateChanged; + this.useSquelchCheckBox.Anchor = AnchorStyles.Left; + this.useSquelchCheckBox.AutoSize = true; + this.radioTableLayoutPanel.SetColumnSpan(this.useSquelchCheckBox, 2); + this.useSquelchCheckBox.Location = new Point(3, 199); + this.useSquelchCheckBox.Name = "useSquelchCheckBox"; + this.useSquelchCheckBox.Size = new Size(65, 17); + this.useSquelchCheckBox.TabIndex = 15; + this.useSquelchCheckBox.Text = "Squelch"; + this.useSquelchCheckBox.UseVisualStyleBackColor = true; + this.useSquelchCheckBox.CheckedChanged += this.useSquelchCheckBox_CheckedChanged; + this.stepSizeComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.radioTableLayoutPanel.SetColumnSpan(this.stepSizeComboBox, 2); + this.stepSizeComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.stepSizeComboBox.FormattingEnabled = true; + this.stepSizeComboBox.Location = new Point(114, 271); + this.stepSizeComboBox.Name = "stepSizeComboBox"; + this.stepSizeComboBox.Size = new Size(108, 21); + this.stepSizeComboBox.TabIndex = 21; + this.stepSizeComboBox.SelectedIndexChanged += this.stepSizeComboBox_SelectedIndexChanged; + this.cwShiftNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.radioTableLayoutPanel.SetColumnSpan(this.cwShiftNumericUpDown, 2); + this.cwShiftNumericUpDown.Enabled = false; + this.cwShiftNumericUpDown.Location = new Point(114, 222); + this.cwShiftNumericUpDown.Maximum = new decimal(new int[4] + { + 2000, + 0, + 0, + 0 + }); + this.cwShiftNumericUpDown.Minimum = new decimal(new int[4] + { + 2000, + 0, + 0, + -2147483648 + }); + this.cwShiftNumericUpDown.Name = "cwShiftNumericUpDown"; + this.cwShiftNumericUpDown.Size = new Size(108, 20); + this.cwShiftNumericUpDown.TabIndex = 18; + this.cwShiftNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.cwShiftNumericUpDown.ThousandsSeparator = true; + this.cwShiftNumericUpDown.Value = new decimal(new int[4] + { + 1000, + 0, + 0, + 0 + }); + this.cwShiftNumericUpDown.ValueChanged += this.cwShiftNumericUpDown_ValueChanged; + this.label18.Anchor = AnchorStyles.Left; + this.label18.AutoSize = true; + this.radioTableLayoutPanel.SetColumnSpan(this.label18, 2); + this.label18.Location = new Point(114, 250); + this.label18.Name = "label18"; + this.label18.Size = new Size(52, 13); + this.label18.TabIndex = 19; + this.label18.Text = "Step Size"; + this.label18.TextAlign = ContentAlignment.MiddleLeft; + this.label15.Anchor = AnchorStyles.Left; + this.label15.AutoSize = true; + this.radioTableLayoutPanel.SetColumnSpan(this.label15, 2); + this.label15.Location = new Point(114, 201); + this.label15.Name = "label15"; + this.label15.Size = new Size(49, 13); + this.label15.TabIndex = 16; + this.label15.Text = "CW Shift"; + this.label15.TextAlign = ContentAlignment.MiddleLeft; + this.squelchNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.radioTableLayoutPanel.SetColumnSpan(this.squelchNumericUpDown, 2); + this.squelchNumericUpDown.Enabled = false; + this.squelchNumericUpDown.Location = new Point(3, 222); + this.squelchNumericUpDown.Name = "squelchNumericUpDown"; + this.squelchNumericUpDown.Size = new Size(105, 20); + this.squelchNumericUpDown.TabIndex = 17; + this.squelchNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.squelchNumericUpDown.ValueChanged += this.squelchNumericUpDown_ValueChanged; + this.filterBandwidthNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.radioTableLayoutPanel.SetColumnSpan(this.filterBandwidthNumericUpDown, 2); + this.filterBandwidthNumericUpDown.Increment = new decimal(new int[4] + { + 10, + 0, + 0, + 0 + }); + this.filterBandwidthNumericUpDown.Location = new Point(3, 173); + this.filterBandwidthNumericUpDown.Maximum = new decimal(new int[4] + { + 250000, + 0, + 0, + 0 + }); + this.filterBandwidthNumericUpDown.Minimum = new decimal(new int[4] + { + 10, + 0, + 0, + 0 + }); + this.filterBandwidthNumericUpDown.Name = "filterBandwidthNumericUpDown"; + this.filterBandwidthNumericUpDown.Size = new Size(105, 20); + this.filterBandwidthNumericUpDown.TabIndex = 13; + this.filterBandwidthNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.filterBandwidthNumericUpDown.ThousandsSeparator = true; + this.filterBandwidthNumericUpDown.Value = new decimal(new int[4] + { + 10000, + 0, + 0, + 0 + }); + this.filterBandwidthNumericUpDown.ValueChanged += this.filterBandwidthNumericUpDown_ValueChanged; + this.label1.Anchor = AnchorStyles.Left; + this.label1.AutoSize = true; + this.radioTableLayoutPanel.SetColumnSpan(this.label1, 2); + this.label1.Location = new Point(3, 157); + this.label1.Name = "label1"; + this.label1.Size = new Size(57, 13); + this.label1.TabIndex = 11; + this.label1.Text = "Bandwidth"; + this.label1.TextAlign = ContentAlignment.MiddleLeft; + this.label5.Anchor = AnchorStyles.Left; + this.label5.AutoSize = true; + this.radioTableLayoutPanel.SetColumnSpan(this.label5, 2); + this.label5.Location = new Point(114, 157); + this.label5.Name = "label5"; + this.label5.Size = new Size(33, 13); + this.label5.TabIndex = 12; + this.label5.Text = "Order"; + this.label5.TextAlign = ContentAlignment.MiddleLeft; + this.filterOrderNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.radioTableLayoutPanel.SetColumnSpan(this.filterOrderNumericUpDown, 2); + this.filterOrderNumericUpDown.Increment = new decimal(new int[4] + { + 10, + 0, + 0, + 0 + }); + this.filterOrderNumericUpDown.Location = new Point(114, 173); + this.filterOrderNumericUpDown.Maximum = new decimal(new int[4] + { + 9999, + 0, + 0, + 0 + }); + this.filterOrderNumericUpDown.Minimum = new decimal(new int[4] + { + 10, + 0, + 0, + 0 + }); + this.filterOrderNumericUpDown.Name = "filterOrderNumericUpDown"; + this.filterOrderNumericUpDown.Size = new Size(108, 20); + this.filterOrderNumericUpDown.TabIndex = 14; + this.filterOrderNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.filterOrderNumericUpDown.ThousandsSeparator = true; + this.filterOrderNumericUpDown.Value = new decimal(new int[4] + { + 400, + 0, + 0, + 0 + }); + this.filterOrderNumericUpDown.ValueChanged += this.filterOrderNumericUpDown_ValueChanged; + this.frequencyShiftNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.radioTableLayoutPanel.SetColumnSpan(this.frequencyShiftNumericUpDown, 3); + this.frequencyShiftNumericUpDown.Enabled = false; + this.frequencyShiftNumericUpDown.Font = new Font("Microsoft Sans Serif", 11.25f, FontStyle.Bold, GraphicsUnit.Point, 0); + this.frequencyShiftNumericUpDown.Increment = new decimal(new int[4] + { + 10, + 0, + 0, + 0 + }); + this.frequencyShiftNumericUpDown.Location = new Point(56, 103); + this.frequencyShiftNumericUpDown.Maximum = new decimal(new int[4] + { + 276447232, + 23283, + 0, + 0 + }); + this.frequencyShiftNumericUpDown.Minimum = new decimal(new int[4] + { + 276447232, + 23283, + 0, + -2147483648 + }); + this.frequencyShiftNumericUpDown.Name = "frequencyShiftNumericUpDown"; + this.frequencyShiftNumericUpDown.Size = new Size(166, 24); + this.frequencyShiftNumericUpDown.TabIndex = 8; + this.frequencyShiftNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.frequencyShiftNumericUpDown.ThousandsSeparator = true; + this.frequencyShiftNumericUpDown.ValueChanged += this.frequencyShiftNumericUpDown_ValueChanged; + this.filterTypeComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.radioTableLayoutPanel.SetColumnSpan(this.filterTypeComboBox, 3); + this.filterTypeComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.filterTypeComboBox.FormattingEnabled = true; + this.filterTypeComboBox.Items.AddRange(new object[6] + { + "Hamming", + "Blackman", + "Blackman-Harris 4", + "Blackman-Harris 7", + "Hann-Poisson", + "Youssef" + }); + this.filterTypeComboBox.Location = new Point(56, 133); + this.filterTypeComboBox.Name = "filterTypeComboBox"; + this.filterTypeComboBox.Size = new Size(166, 21); + this.filterTypeComboBox.TabIndex = 10; + this.filterTypeComboBox.SelectedIndexChanged += this.filterTypeComboBox_SelectedIndexChanged; + this.label16.Anchor = AnchorStyles.Left; + this.label16.AutoSize = true; + this.label16.Location = new Point(3, 137); + this.label16.Name = "label16"; + this.label16.Size = new Size(29, 13); + this.label16.TabIndex = 9; + this.label16.Text = "Filter"; + this.label16.TextAlign = ContentAlignment.MiddleLeft; + this.correctIQCheckBox.Anchor = AnchorStyles.Right; + this.correctIQCheckBox.AutoSize = true; + this.radioTableLayoutPanel.SetColumnSpan(this.correctIQCheckBox, 2); + this.correctIQCheckBox.Location = new Point(148, 298); + this.correctIQCheckBox.Name = "correctIQCheckBox"; + this.correctIQCheckBox.RightToLeft = RightToLeft.Yes; + this.correctIQCheckBox.Size = new Size(74, 17); + this.correctIQCheckBox.TabIndex = 22; + this.correctIQCheckBox.Text = "Correct IQ"; + this.correctIQCheckBox.UseVisualStyleBackColor = true; + this.correctIQCheckBox.CheckedChanged += this.autoCorrectIQCheckBox_CheckStateChanged; + this.snapFrequencyCheckBox.Anchor = AnchorStyles.Right; + this.snapFrequencyCheckBox.AutoSize = true; + this.radioTableLayoutPanel.SetColumnSpan(this.snapFrequencyCheckBox, 2); + this.snapFrequencyCheckBox.Location = new Point(23, 273); + this.snapFrequencyCheckBox.Name = "snapFrequencyCheckBox"; + this.snapFrequencyCheckBox.RightToLeft = RightToLeft.Yes; + this.snapFrequencyCheckBox.Size = new Size(85, 17); + this.snapFrequencyCheckBox.TabIndex = 20; + this.snapFrequencyCheckBox.Text = "Snap to Grid"; + this.snapFrequencyCheckBox.UseVisualStyleBackColor = true; + this.snapFrequencyCheckBox.CheckedChanged += this.stepSizeComboBox_SelectedIndexChanged; + this.lockCarrierCheckBox.Anchor = AnchorStyles.Right; + this.lockCarrierCheckBox.AutoSize = true; + this.lockCarrierCheckBox.CheckAlign = ContentAlignment.MiddleRight; + this.radioTableLayoutPanel.SetColumnSpan(this.lockCarrierCheckBox, 2); + this.lockCarrierCheckBox.Location = new Point(25, 298); + this.lockCarrierCheckBox.Name = "lockCarrierCheckBox"; + this.lockCarrierCheckBox.Size = new Size(83, 17); + this.lockCarrierCheckBox.TabIndex = 33; + this.lockCarrierCheckBox.Text = "Lock Carrier"; + this.lockCarrierCheckBox.UseVisualStyleBackColor = true; + this.lockCarrierCheckBox.CheckedChanged += this.lockCarrierCheckBox_CheckedChanged; + this.fmStereoCheckBox.Anchor = AnchorStyles.Right; + this.fmStereoCheckBox.AutoSize = true; + this.radioTableLayoutPanel.SetColumnSpan(this.fmStereoCheckBox, 2); + this.fmStereoCheckBox.Enabled = false; + this.fmStereoCheckBox.Location = new Point(33, 248); + this.fmStereoCheckBox.Name = "fmStereoCheckBox"; + this.fmStereoCheckBox.RightToLeft = RightToLeft.Yes; + this.fmStereoCheckBox.Size = new Size(75, 17); + this.fmStereoCheckBox.TabIndex = 24; + this.fmStereoCheckBox.Text = "FM Stereo"; + this.fmStereoCheckBox.UseVisualStyleBackColor = true; + this.fmStereoCheckBox.CheckedChanged += this.fmStereoCheckBox_CheckedChanged; + this.useAntiFadingCheckBox.Anchor = AnchorStyles.Right; + this.useAntiFadingCheckBox.AutoSize = true; + this.useAntiFadingCheckBox.CheckAlign = ContentAlignment.MiddleRight; + this.radioTableLayoutPanel.SetColumnSpan(this.useAntiFadingCheckBox, 2); + this.useAntiFadingCheckBox.Location = new Point(29, 321); + this.useAntiFadingCheckBox.Name = "useAntiFadingCheckBox"; + this.useAntiFadingCheckBox.Size = new Size(79, 17); + this.useAntiFadingCheckBox.TabIndex = 34; + this.useAntiFadingCheckBox.Text = "Anti-Fading"; + this.useAntiFadingCheckBox.UseVisualStyleBackColor = true; + this.useAntiFadingCheckBox.CheckedChanged += this.useAntiFadingCheckBox_CheckedChanged; + this.audioCollapsiblePanel.AutoHeight = false; + this.audioCollapsiblePanel.Content.Controls.Add(this.tableLayoutPanel1); + this.audioCollapsiblePanel.Content.Location = new Point(0, 24); + this.audioCollapsiblePanel.Content.Name = "Content"; + this.audioCollapsiblePanel.Content.Size = new Size(224, 136); + this.audioCollapsiblePanel.Content.TabIndex = 1; + this.audioCollapsiblePanel.Location = new Point(0, 417); + this.audioCollapsiblePanel.Name = "audioCollapsiblePanel"; + this.audioCollapsiblePanel.NextPanel = this.agcCollapsiblePanel; + this.audioCollapsiblePanel.PanelTitle = "Audio"; + this.audioCollapsiblePanel.Size = new Size(224, 160); + this.audioCollapsiblePanel.TabIndex = 1; + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 40f)); + this.tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 60f)); + this.tableLayoutPanel1.Controls.Add(this.label13, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.sampleRateComboBox, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.label11, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.inputDeviceComboBox, 1, 1); + this.tableLayoutPanel1.Controls.Add(this.label12, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.outputDeviceComboBox, 1, 2); + this.tableLayoutPanel1.Controls.Add(this.latencyNumericUpDown, 1, 3); + this.tableLayoutPanel1.Controls.Add(this.label6, 0, 3); + this.tableLayoutPanel1.Controls.Add(this.unityGainCheckBox, 0, 4); + this.tableLayoutPanel1.Controls.Add(this.filterAudioCheckBox, 1, 4); + this.tableLayoutPanel1.Dock = DockStyle.Fill; + this.tableLayoutPanel1.Location = new Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 5; + this.tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.tableLayoutPanel1.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel1.Size = new Size(224, 136); + this.tableLayoutPanel1.TabIndex = 31; + this.label13.Anchor = AnchorStyles.Left; + this.label13.AutoSize = true; + this.label13.Location = new Point(3, 10); + this.label13.Name = "label13"; + this.label13.Size = new Size(60, 13); + this.label13.TabIndex = 28; + this.label13.Text = "Samplerate"; + this.sampleRateComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.sampleRateComboBox.FormattingEnabled = true; + this.sampleRateComboBox.Items.AddRange(new object[14] + { + "8000 sample/sec", + "11025 sample/sec", + "16000 sample/sec", + "22050 sample/sec", + "24000 sample/sec", + "32000 sample/sec", + "44100 sample/sec", + "48000 sample/sec", + "80000 sample/sec", + "96000 sample/sec", + "120000 sample/sec", + "125000 sample/sec", + "150000 sample/sec", + "192000 sample/sec" + }); + this.sampleRateComboBox.Location = new Point(92, 6); + this.sampleRateComboBox.Name = "sampleRateComboBox"; + this.sampleRateComboBox.Size = new Size(129, 21); + this.sampleRateComboBox.TabIndex = 1; + this.label11.Anchor = AnchorStyles.Left; + this.label11.AutoSize = true; + this.label11.Location = new Point(3, 40); + this.label11.Name = "label11"; + this.label11.Size = new Size(31, 13); + this.label11.TabIndex = 24; + this.label11.Text = "Input"; + this.inputDeviceComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.inputDeviceComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.inputDeviceComboBox.DropDownWidth = 300; + this.inputDeviceComboBox.FormattingEnabled = true; + this.inputDeviceComboBox.Location = new Point(92, 36); + this.inputDeviceComboBox.Name = "inputDeviceComboBox"; + this.inputDeviceComboBox.Size = new Size(129, 21); + this.inputDeviceComboBox.TabIndex = 2; + this.label12.Anchor = AnchorStyles.Left; + this.label12.AutoSize = true; + this.label12.Location = new Point(3, 67); + this.label12.Name = "label12"; + this.label12.Size = new Size(39, 13); + this.label12.TabIndex = 26; + this.label12.Text = "Output"; + this.outputDeviceComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.outputDeviceComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.outputDeviceComboBox.DropDownWidth = 300; + this.outputDeviceComboBox.FormattingEnabled = true; + this.outputDeviceComboBox.Location = new Point(92, 63); + this.outputDeviceComboBox.Name = "outputDeviceComboBox"; + this.outputDeviceComboBox.Size = new Size(129, 21); + this.outputDeviceComboBox.TabIndex = 3; + this.latencyNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.latencyNumericUpDown.Location = new Point(92, 90); + this.latencyNumericUpDown.Maximum = new decimal(new int[4] + { + 2000, + 0, + 0, + 0 + }); + this.latencyNumericUpDown.Minimum = new decimal(new int[4] + { + 1, + 0, + 0, + 0 + }); + this.latencyNumericUpDown.Name = "latencyNumericUpDown"; + this.latencyNumericUpDown.Size = new Size(129, 20); + this.latencyNumericUpDown.TabIndex = 4; + this.latencyNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.latencyNumericUpDown.Value = new decimal(new int[4] + { + 1, + 0, + 0, + 0 + }); + this.label6.Anchor = AnchorStyles.Left; + this.label6.AutoSize = true; + this.label6.Location = new Point(3, 93); + this.label6.Name = "label6"; + this.label6.Size = new Size(67, 13); + this.label6.TabIndex = 30; + this.label6.Text = "Latency (ms)"; + this.unityGainCheckBox.Anchor = AnchorStyles.Left; + this.unityGainCheckBox.AutoSize = true; + this.unityGainCheckBox.Location = new Point(3, 116); + this.unityGainCheckBox.Name = "unityGainCheckBox"; + this.unityGainCheckBox.Size = new Size(75, 17); + this.unityGainCheckBox.TabIndex = 5; + this.unityGainCheckBox.Text = "Unity Gain"; + this.unityGainCheckBox.UseVisualStyleBackColor = true; + this.unityGainCheckBox.CheckStateChanged += this.unityGainCheckBox_CheckStateChanged; + this.filterAudioCheckBox.Anchor = AnchorStyles.Left; + this.filterAudioCheckBox.AutoSize = true; + this.filterAudioCheckBox.Location = new Point(92, 116); + this.filterAudioCheckBox.Name = "filterAudioCheckBox"; + this.filterAudioCheckBox.Size = new Size(78, 17); + this.filterAudioCheckBox.TabIndex = 6; + this.filterAudioCheckBox.Text = "Filter Audio"; + this.filterAudioCheckBox.UseVisualStyleBackColor = true; + this.filterAudioCheckBox.CheckedChanged += this.filterAudioCheckBox_CheckStateChanged; + this.agcCollapsiblePanel.AutoHeight = false; + this.agcCollapsiblePanel.Content.Controls.Add(this.tableLayoutPanel2); + this.agcCollapsiblePanel.Content.Location = new Point(0, 24); + this.agcCollapsiblePanel.Content.Name = "Content"; + this.agcCollapsiblePanel.Content.Size = new Size(224, 106); + this.agcCollapsiblePanel.Content.TabIndex = 1; + this.agcCollapsiblePanel.Location = new Point(0, 577); + this.agcCollapsiblePanel.Name = "agcCollapsiblePanel"; + this.agcCollapsiblePanel.NextPanel = this.fftCollapsiblePanel; + this.agcCollapsiblePanel.PanelTitle = "AGC"; + this.agcCollapsiblePanel.Size = new Size(224, 130); + this.agcCollapsiblePanel.TabIndex = 2; + this.tableLayoutPanel2.ColumnCount = 2; + this.tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 40f)); + this.tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 60f)); + this.tableLayoutPanel2.Controls.Add(this.agcCheckBox, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.agcSlopeNumericUpDown, 1, 3); + this.tableLayoutPanel2.Controls.Add(this.agcUseHangCheckBox, 1, 0); + this.tableLayoutPanel2.Controls.Add(this.label22, 0, 3); + this.tableLayoutPanel2.Controls.Add(this.label4, 0, 1); + this.tableLayoutPanel2.Controls.Add(this.agcDecayNumericUpDown, 1, 2); + this.tableLayoutPanel2.Controls.Add(this.label10, 0, 2); + this.tableLayoutPanel2.Controls.Add(this.agcThresholdNumericUpDown, 1, 1); + this.tableLayoutPanel2.Dock = DockStyle.Fill; + this.tableLayoutPanel2.Location = new Point(0, 0); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 4; + this.tableLayoutPanel2.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.tableLayoutPanel2.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel2.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 20f)); + this.tableLayoutPanel2.Size = new Size(224, 106); + this.tableLayoutPanel2.TabIndex = 14; + this.agcCheckBox.Anchor = AnchorStyles.Left; + this.agcCheckBox.AutoSize = true; + this.agcCheckBox.Location = new Point(3, 3); + this.agcCheckBox.Name = "agcCheckBox"; + this.agcCheckBox.Size = new Size(70, 17); + this.agcCheckBox.TabIndex = 0; + this.agcCheckBox.Text = "Use AGC"; + this.agcCheckBox.UseVisualStyleBackColor = true; + this.agcCheckBox.CheckedChanged += this.agcCheckBox_CheckedChanged; + this.agcSlopeNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.agcSlopeNumericUpDown.Location = new Point(92, 83); + this.agcSlopeNumericUpDown.Maximum = new decimal(new int[4] + { + 10, + 0, + 0, + 0 + }); + this.agcSlopeNumericUpDown.Name = "agcSlopeNumericUpDown"; + this.agcSlopeNumericUpDown.Size = new Size(129, 20); + this.agcSlopeNumericUpDown.TabIndex = 4; + this.agcSlopeNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.agcSlopeNumericUpDown.Value = new decimal(new int[4] + { + 10, + 0, + 0, + 0 + }); + this.agcSlopeNumericUpDown.ValueChanged += this.agcSlopeNumericUpDown_ValueChanged; + this.agcUseHangCheckBox.Anchor = AnchorStyles.Left; + this.agcUseHangCheckBox.AutoSize = true; + this.agcUseHangCheckBox.Location = new Point(92, 3); + this.agcUseHangCheckBox.Name = "agcUseHangCheckBox"; + this.agcUseHangCheckBox.Size = new Size(74, 17); + this.agcUseHangCheckBox.TabIndex = 1; + this.agcUseHangCheckBox.Text = "Use Hang"; + this.agcUseHangCheckBox.UseVisualStyleBackColor = true; + this.agcUseHangCheckBox.CheckedChanged += this.agcUseHangCheckBox_CheckedChanged; + this.label22.Anchor = AnchorStyles.Left; + this.label22.AutoSize = true; + this.label22.Location = new Point(3, 86); + this.label22.Name = "label22"; + this.label22.Size = new Size(56, 13); + this.label22.TabIndex = 13; + this.label22.Text = "Slope (dB)"; + this.label4.Anchor = AnchorStyles.Left; + this.label4.AutoSize = true; + this.label4.Location = new Point(3, 32); + this.label4.Name = "label4"; + this.label4.Size = new Size(76, 13); + this.label4.TabIndex = 7; + this.label4.Text = "Threshold (dB)"; + this.agcDecayNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.agcDecayNumericUpDown.Location = new Point(92, 57); + this.agcDecayNumericUpDown.Maximum = new decimal(new int[4] + { + 2000, + 0, + 0, + 0 + }); + this.agcDecayNumericUpDown.Minimum = new decimal(new int[4] + { + 10, + 0, + 0, + 0 + }); + this.agcDecayNumericUpDown.Name = "agcDecayNumericUpDown"; + this.agcDecayNumericUpDown.Size = new Size(129, 20); + this.agcDecayNumericUpDown.TabIndex = 3; + this.agcDecayNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.agcDecayNumericUpDown.Value = new decimal(new int[4] + { + 2000, + 0, + 0, + 0 + }); + this.agcDecayNumericUpDown.ValueChanged += this.agcDecayNumericUpDown_ValueChanged; + this.label10.Anchor = AnchorStyles.Left; + this.label10.AutoSize = true; + this.label10.Location = new Point(3, 60); + this.label10.Name = "label10"; + this.label10.Size = new Size(60, 13); + this.label10.TabIndex = 11; + this.label10.Text = "Decay (ms)"; + this.agcThresholdNumericUpDown.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.agcThresholdNumericUpDown.Font = new Font("Microsoft Sans Serif", 10f, FontStyle.Bold, GraphicsUnit.Point, 0); + this.agcThresholdNumericUpDown.Location = new Point(92, 27); + this.agcThresholdNumericUpDown.Maximum = new decimal(new int[4]); + this.agcThresholdNumericUpDown.Minimum = new decimal(new int[4] + { + 160, + 0, + 0, + -2147483648 + }); + this.agcThresholdNumericUpDown.Name = "agcThresholdNumericUpDown"; + this.agcThresholdNumericUpDown.Size = new Size(129, 23); + this.agcThresholdNumericUpDown.TabIndex = 2; + this.agcThresholdNumericUpDown.TextAlign = HorizontalAlignment.Right; + this.agcThresholdNumericUpDown.ValueChanged += this.agcThresholdNumericUpDown_ValueChanged; + this.fftCollapsiblePanel.AutoHeight = false; + this.fftCollapsiblePanel.Content.Controls.Add(this.tableLayoutPanel3); + this.fftCollapsiblePanel.Content.Location = new Point(0, 24); + this.fftCollapsiblePanel.Content.Name = "Content"; + this.fftCollapsiblePanel.Content.Size = new Size(224, 484); + this.fftCollapsiblePanel.Content.TabIndex = 1; + this.fftCollapsiblePanel.Location = new Point(0, 707); + this.fftCollapsiblePanel.Name = "fftCollapsiblePanel"; + this.fftCollapsiblePanel.NextPanel = null; + this.fftCollapsiblePanel.PanelTitle = "FFT Display"; + this.fftCollapsiblePanel.Size = new Size(224, 508); + this.fftCollapsiblePanel.TabIndex = 3; + this.tableLayoutPanel3.ColumnCount = 4; + this.tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 40f)); + this.tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 10f)); + this.tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 35f)); + this.tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 15f)); + this.tableLayoutPanel3.Controls.Add(this.label7, 0, 0); + this.tableLayoutPanel3.Controls.Add(this.viewComboBox, 1, 0); + this.tableLayoutPanel3.Controls.Add(this.label8, 0, 1); + this.tableLayoutPanel3.Controls.Add(this.fftWindowComboBox, 1, 1); + this.tableLayoutPanel3.Controls.Add(this.label21, 0, 2); + this.tableLayoutPanel3.Controls.Add(this.fftResolutionComboBox, 1, 2); + this.tableLayoutPanel3.Controls.Add(this.groupBox1, 0, 7); + this.tableLayoutPanel3.Controls.Add(this.smoothingGroupBox, 0, 6); + this.tableLayoutPanel3.Controls.Add(this.markPeaksCheckBox, 0, 5); + this.tableLayoutPanel3.Controls.Add(this.useTimestampsCheckBox, 0, 4); + this.tableLayoutPanel3.Controls.Add(this.label14, 2, 4); + this.tableLayoutPanel3.Controls.Add(this.gradientButton, 3, 4); + this.tableLayoutPanel3.Controls.Add(this.label3, 0, 3); + this.tableLayoutPanel3.Controls.Add(this.spectrumStyleComboBox, 1, 3); + this.tableLayoutPanel3.Dock = DockStyle.Fill; + this.tableLayoutPanel3.Location = new Point(0, 0); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + this.tableLayoutPanel3.RowCount = 8; + this.tableLayoutPanel3.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel3.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel3.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel3.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel3.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel3.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 75f)); + this.tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.tableLayoutPanel3.Size = new Size(224, 484); + this.tableLayoutPanel3.TabIndex = 33; + this.label7.Anchor = AnchorStyles.Left; + this.label7.AutoSize = true; + this.label7.Location = new Point(3, 7); + this.label7.Name = "label7"; + this.label7.Size = new Size(30, 13); + this.label7.TabIndex = 12; + this.label7.Text = "View"; + this.viewComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.tableLayoutPanel3.SetColumnSpan(this.viewComboBox, 3); + this.viewComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.viewComboBox.FormattingEnabled = true; + this.viewComboBox.Items.AddRange(new object[4] + { + "Spectrum Analyzer", + "Waterfall", + "Both", + "None" + }); + this.viewComboBox.Location = new Point(92, 3); + this.viewComboBox.Name = "viewComboBox"; + this.viewComboBox.Size = new Size(129, 21); + this.viewComboBox.TabIndex = 0; + this.viewComboBox.SelectedIndexChanged += this.viewComboBox_SelectedIndexChanged; + this.label8.Anchor = AnchorStyles.Left; + this.label8.AutoSize = true; + this.label8.Location = new Point(3, 34); + this.label8.Name = "label8"; + this.label8.Size = new Size(46, 13); + this.label8.TabIndex = 14; + this.label8.Text = "Window"; + this.fftWindowComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.tableLayoutPanel3.SetColumnSpan(this.fftWindowComboBox, 3); + this.fftWindowComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.fftWindowComboBox.FormattingEnabled = true; + this.fftWindowComboBox.Items.AddRange(new object[7] + { + "None", + "Hamming", + "Blackman", + "Blackman-Harris 4", + "Blackman-Harris 7", + "Hann-Poisson", + "Youssef" + }); + this.fftWindowComboBox.Location = new Point(92, 30); + this.fftWindowComboBox.Name = "fftWindowComboBox"; + this.fftWindowComboBox.Size = new Size(129, 21); + this.fftWindowComboBox.TabIndex = 1; + this.fftWindowComboBox.SelectedIndexChanged += this.fftWindowComboBox_SelectedIndexChanged; + this.label21.Anchor = AnchorStyles.Left; + this.label21.AutoSize = true; + this.label21.Location = new Point(3, 61); + this.label21.Name = "label21"; + this.label21.Size = new Size(57, 13); + this.label21.TabIndex = 18; + this.label21.Text = "Resolution"; + this.fftResolutionComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.tableLayoutPanel3.SetColumnSpan(this.fftResolutionComboBox, 3); + this.fftResolutionComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.fftResolutionComboBox.FormattingEnabled = true; + this.fftResolutionComboBox.Items.AddRange(new object[14] + { + "512", + "1024", + "2048", + "4096", + "8192", + "16384", + "32768", + "65536", + "131072", + "262144", + "524288", + "1048576", + "2097152", + "4194304" + }); + this.fftResolutionComboBox.Location = new Point(92, 57); + this.fftResolutionComboBox.Name = "fftResolutionComboBox"; + this.fftResolutionComboBox.Size = new Size(129, 21); + this.fftResolutionComboBox.TabIndex = 2; + this.fftResolutionComboBox.SelectedIndexChanged += this.fftResolutionComboBox_SelectedIndexChanged; + this.tableLayoutPanel3.SetColumnSpan(this.groupBox1, 4); + this.groupBox1.Controls.Add(this.tableLayoutPanel5); + this.groupBox1.Dock = DockStyle.Fill; + this.groupBox1.Location = new Point(3, 406); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new Size(218, 75); + this.groupBox1.TabIndex = 32; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Spectrum"; + this.tableLayoutPanel5.ColumnCount = 2; + this.tableLayoutPanel5.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 40f)); + this.tableLayoutPanel5.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 60f)); + this.tableLayoutPanel5.Controls.Add(this.label28, 0, 0); + this.tableLayoutPanel5.Controls.Add(this.fftSpeedTrackBar, 1, 0); + this.tableLayoutPanel5.Dock = DockStyle.Fill; + this.tableLayoutPanel5.Location = new Point(3, 16); + this.tableLayoutPanel5.Name = "tableLayoutPanel5"; + this.tableLayoutPanel5.RowCount = 1; + this.tableLayoutPanel5.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.tableLayoutPanel5.RowStyles.Add(new RowStyle(SizeType.Absolute, 56f)); + this.tableLayoutPanel5.Size = new Size(212, 56); + this.tableLayoutPanel5.TabIndex = 31; + this.label28.Anchor = AnchorStyles.Left; + this.label28.AutoSize = true; + this.label28.Location = new Point(3, 21); + this.label28.Name = "label28"; + this.label28.Size = new Size(38, 13); + this.label28.TabIndex = 29; + this.label28.Text = "Speed"; + this.fftSpeedTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.fftSpeedTrackBar.Location = new Point(87, 5); + this.fftSpeedTrackBar.Maximum = 100; + this.fftSpeedTrackBar.Minimum = 1; + this.fftSpeedTrackBar.Name = "fftSpeedTrackBar"; + this.fftSpeedTrackBar.RightToLeftLayout = true; + this.fftSpeedTrackBar.Size = new Size(122, 45); + this.fftSpeedTrackBar.TabIndex = 2; + this.fftSpeedTrackBar.TickFrequency = 10; + this.fftSpeedTrackBar.TickStyle = TickStyle.Both; + this.fftSpeedTrackBar.Value = 50; + this.fftSpeedTrackBar.ValueChanged += this.fftSpeedTrackBar_ValueChanged; + this.tableLayoutPanel3.SetColumnSpan(this.smoothingGroupBox, 4); + this.smoothingGroupBox.Controls.Add(this.tableLayoutPanel4); + this.smoothingGroupBox.Dock = DockStyle.Fill; + this.smoothingGroupBox.Location = new Point(3, 163); + this.smoothingGroupBox.Name = "smoothingGroupBox"; + this.smoothingGroupBox.Size = new Size(218, 237); + this.smoothingGroupBox.TabIndex = 31; + this.smoothingGroupBox.TabStop = false; + this.smoothingGroupBox.Text = "Smoothing"; + this.tableLayoutPanel4.ColumnCount = 2; + this.tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 40f)); + this.tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 60f)); + this.tableLayoutPanel4.Controls.Add(this.label23, 0, 0); + this.tableLayoutPanel4.Controls.Add(this.wDecayTrackBar, 1, 3); + this.tableLayoutPanel4.Controls.Add(this.wAttackTrackBar, 1, 2); + this.tableLayoutPanel4.Controls.Add(this.label25, 0, 3); + this.tableLayoutPanel4.Controls.Add(this.sDecayTrackBar, 1, 1); + this.tableLayoutPanel4.Controls.Add(this.sAttackTrackBar, 1, 0); + this.tableLayoutPanel4.Controls.Add(this.label24, 0, 1); + this.tableLayoutPanel4.Controls.Add(this.label26, 0, 2); + this.tableLayoutPanel4.Dock = DockStyle.Fill; + this.tableLayoutPanel4.Location = new Point(3, 16); + this.tableLayoutPanel4.Name = "tableLayoutPanel4"; + this.tableLayoutPanel4.RowCount = 4; + this.tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.tableLayoutPanel4.Size = new Size(212, 218); + this.tableLayoutPanel4.TabIndex = 27; + this.label23.Anchor = AnchorStyles.Left; + this.label23.AutoSize = true; + this.label23.Location = new Point(3, 20); + this.label23.Name = "label23"; + this.label23.Size = new Size(48, 13); + this.label23.TabIndex = 23; + this.label23.Text = "S-Attack"; + this.wDecayTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.wDecayTrackBar.Location = new Point(87, 167); + this.wDecayTrackBar.Maximum = 50; + this.wDecayTrackBar.Name = "wDecayTrackBar"; + this.wDecayTrackBar.Size = new Size(122, 45); + this.wDecayTrackBar.TabIndex = 8; + this.wDecayTrackBar.TickFrequency = 5; + this.wDecayTrackBar.TickStyle = TickStyle.Both; + this.wDecayTrackBar.ValueChanged += this.wDecayTrackBar_ValueChanged; + this.wAttackTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.wAttackTrackBar.Location = new Point(87, 112); + this.wAttackTrackBar.Maximum = 50; + this.wAttackTrackBar.Name = "wAttackTrackBar"; + this.wAttackTrackBar.Size = new Size(122, 45); + this.wAttackTrackBar.TabIndex = 7; + this.wAttackTrackBar.TickFrequency = 5; + this.wAttackTrackBar.TickStyle = TickStyle.Both; + this.wAttackTrackBar.ValueChanged += this.wAttackTrackBar_ValueChanged; + this.label25.Anchor = AnchorStyles.Left; + this.label25.AutoSize = true; + this.label25.Location = new Point(3, 183); + this.label25.Name = "label25"; + this.label25.Size = new Size(52, 13); + this.label25.TabIndex = 26; + this.label25.Text = "W-Decay"; + this.sDecayTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.sDecayTrackBar.Location = new Point(87, 58); + this.sDecayTrackBar.Maximum = 50; + this.sDecayTrackBar.Name = "sDecayTrackBar"; + this.sDecayTrackBar.Size = new Size(122, 45); + this.sDecayTrackBar.TabIndex = 6; + this.sDecayTrackBar.TickFrequency = 5; + this.sDecayTrackBar.TickStyle = TickStyle.Both; + this.sDecayTrackBar.ValueChanged += this.sDecayTrackBar_ValueChanged; + this.sAttackTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.sAttackTrackBar.Location = new Point(87, 4); + this.sAttackTrackBar.Maximum = 50; + this.sAttackTrackBar.Name = "sAttackTrackBar"; + this.sAttackTrackBar.Size = new Size(122, 45); + this.sAttackTrackBar.TabIndex = 5; + this.sAttackTrackBar.TickFrequency = 5; + this.sAttackTrackBar.TickStyle = TickStyle.Both; + this.sAttackTrackBar.ValueChanged += this.sAttackTrackBar_ValueChanged; + this.label24.Anchor = AnchorStyles.Left; + this.label24.AutoSize = true; + this.label24.Location = new Point(3, 74); + this.label24.Name = "label24"; + this.label24.Size = new Size(48, 13); + this.label24.TabIndex = 24; + this.label24.Text = "S-Decay"; + this.label26.Anchor = AnchorStyles.Left; + this.label26.AutoSize = true; + this.label26.Location = new Point(3, 128); + this.label26.Name = "label26"; + this.label26.Size = new Size(52, 13); + this.label26.TabIndex = 25; + this.label26.Text = "W-Attack"; + this.markPeaksCheckBox.Anchor = AnchorStyles.Right; + this.markPeaksCheckBox.AutoSize = true; + this.markPeaksCheckBox.Location = new Point(3, 140); + this.markPeaksCheckBox.Name = "markPeaksCheckBox"; + this.markPeaksCheckBox.Size = new Size(83, 17); + this.markPeaksCheckBox.TabIndex = 23; + this.markPeaksCheckBox.Text = "Mark Peaks"; + this.markPeaksCheckBox.UseVisualStyleBackColor = true; + this.markPeaksCheckBox.CheckedChanged += this.markPeaksCheckBox_CheckedChanged; + this.useTimestampsCheckBox.Anchor = AnchorStyles.Left; + this.useTimestampsCheckBox.AutoSize = true; + this.tableLayoutPanel3.SetColumnSpan(this.useTimestampsCheckBox, 2); + this.useTimestampsCheckBox.Location = new Point(3, 114); + this.useTimestampsCheckBox.Name = "useTimestampsCheckBox"; + this.useTimestampsCheckBox.Size = new Size(90, 17); + this.useTimestampsCheckBox.TabIndex = 3; + this.useTimestampsCheckBox.Text = "Time Markers"; + this.useTimestampsCheckBox.UseVisualStyleBackColor = true; + this.useTimestampsCheckBox.CheckedChanged += this.useTimestampCheckBox_CheckedChanged; + this.label14.Anchor = AnchorStyles.Right; + this.label14.AutoSize = true; + this.label14.Location = new Point(139, 116); + this.label14.Name = "label14"; + this.label14.Size = new Size(47, 13); + this.label14.TabIndex = 16; + this.label14.Text = "Gradient"; + this.gradientButton.Anchor = AnchorStyles.Right; + this.gradientButton.Location = new Point(197, 111); + this.gradientButton.Name = "gradientButton"; + this.gradientButton.Size = new Size(24, 23); + this.gradientButton.TabIndex = 4; + this.gradientButton.Text = "..."; + this.gradientButton.UseVisualStyleBackColor = true; + this.gradientButton.Click += this.gradientButton_Click; + this.label3.Anchor = AnchorStyles.Left; + this.label3.AutoSize = true; + this.label3.Location = new Point(3, 88); + this.label3.Name = "label3"; + this.label3.Size = new Size(78, 13); + this.label3.TabIndex = 33; + this.label3.Text = "Spectrum Style"; + this.spectrumStyleComboBox.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.tableLayoutPanel3.SetColumnSpan(this.spectrumStyleComboBox, 3); + this.spectrumStyleComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + this.spectrumStyleComboBox.FormattingEnabled = true; + this.spectrumStyleComboBox.Items.AddRange(new object[6] + { + "Dots", + "Simple Curve", + "Solid Fill", + "Static Gradient", + "Dynamic Gradient", + "Min Max" + }); + this.spectrumStyleComboBox.Location = new Point(92, 84); + this.spectrumStyleComboBox.Name = "spectrumStyleComboBox"; + this.spectrumStyleComboBox.Size = new Size(129, 21); + this.spectrumStyleComboBox.TabIndex = 34; + this.spectrumStyleComboBox.SelectedIndexChanged += this.spectrumStyleComboBox_SelectedIndexChanged; + this.fftOffsetTrackBar.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom); + this.fftOffsetTrackBar.Location = new Point(3, 533); + this.fftOffsetTrackBar.Maximum = 15; + this.fftOffsetTrackBar.Name = "fftOffsetTrackBar"; + this.fftOffsetTrackBar.Orientation = Orientation.Vertical; + this.fftOffsetTrackBar.Size = new Size(45, 154); + this.fftOffsetTrackBar.TabIndex = 27; + this.fftOffsetTrackBar.TickStyle = TickStyle.Both; + this.fftOffsetTrackBar.Scroll += this.fftOffsetTrackBar_Scroll; + this.fftRangeTrackBar.Anchor = (AnchorStyles.Top | AnchorStyles.Bottom); + this.fftRangeTrackBar.LargeChange = 10; + this.fftRangeTrackBar.Location = new Point(3, 356); + this.fftRangeTrackBar.Maximum = 15; + this.fftRangeTrackBar.Minimum = 1; + this.fftRangeTrackBar.Name = "fftRangeTrackBar"; + this.fftRangeTrackBar.Orientation = Orientation.Vertical; + this.fftRangeTrackBar.Size = new Size(45, 151); + this.fftRangeTrackBar.TabIndex = 28; + this.fftRangeTrackBar.TickStyle = TickStyle.Both; + this.fftRangeTrackBar.Value = 13; + this.fftRangeTrackBar.Scroll += this.fftRangeTrackBar_Scroll; + this.audioGainTrackBar.Anchor = (AnchorStyles.Left | AnchorStyles.Right); + this.audioGainTrackBar.Location = new Point(147, 3); + this.audioGainTrackBar.Maximum = 60; + this.audioGainTrackBar.Minimum = 25; + this.audioGainTrackBar.Name = "audioGainTrackBar"; + this.audioGainTrackBar.Size = new Size(143, 45); + this.audioGainTrackBar.TabIndex = 0; + this.audioGainTrackBar.TickFrequency = 5; + this.audioGainTrackBar.TickStyle = TickStyle.Both; + this.audioGainTrackBar.Value = 40; + this.audioGainTrackBar.ValueChanged += this.audioGainTrackBar_ValueChanged; + this.label17.Anchor = AnchorStyles.None; + this.label17.AutoSize = true; + this.label17.Location = new Point(6, 340); + this.label17.Name = "label17"; + this.label17.Size = new Size(39, 13); + this.label17.TabIndex = 27; + this.label17.Text = "Range"; + this.label17.TextAlign = ContentAlignment.MiddleCenter; + this.scrollPanel.AutoScroll = true; + this.scrollPanel.Controls.Add(this.controlPanel); + this.scrollPanel.Dock = DockStyle.Left; + this.scrollPanel.Location = new Point(10, 61); + this.scrollPanel.Margin = new Padding(3, 0, 3, 0); + this.scrollPanel.Name = "scrollPanel"; + this.scrollPanel.Size = new Size(246, 690); + this.scrollPanel.TabIndex = 28; + this.rightTableLayoutPanel.AutoSize = true; + this.rightTableLayoutPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink; + this.rightTableLayoutPanel.ColumnCount = 1; + this.rightTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.rightTableLayoutPanel.Controls.Add(this.label2, 0, 6); + this.rightTableLayoutPanel.Controls.Add(this.label19, 0, 0); + this.rightTableLayoutPanel.Controls.Add(this.label20, 0, 2); + this.rightTableLayoutPanel.Controls.Add(this.label17, 0, 4); + this.rightTableLayoutPanel.Controls.Add(this.fftZoomTrackBar, 0, 1); + this.rightTableLayoutPanel.Controls.Add(this.fftContrastTrackBar, 0, 3); + this.rightTableLayoutPanel.Controls.Add(this.fftOffsetTrackBar, 0, 7); + this.rightTableLayoutPanel.Controls.Add(this.fftRangeTrackBar, 0, 5); + this.rightTableLayoutPanel.Dock = DockStyle.Right; + this.rightTableLayoutPanel.Location = new Point(922, 61); + this.rightTableLayoutPanel.Margin = new Padding(0); + this.rightTableLayoutPanel.Name = "rightTableLayoutPanel"; + this.rightTableLayoutPanel.RowCount = 8; + this.rightTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.rightTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.rightTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.rightTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.rightTableLayoutPanel.RowStyles.Add(new RowStyle()); + this.rightTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.rightTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 20f)); + this.rightTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.rightTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 20f)); + this.rightTableLayoutPanel.Size = new Size(52, 690); + this.rightTableLayoutPanel.TabIndex = 33; + this.label2.Anchor = AnchorStyles.None; + this.label2.AutoSize = true; + this.label2.Location = new Point(8, 513); + this.label2.Name = "label2"; + this.label2.Size = new Size(35, 13); + this.label2.TabIndex = 28; + this.label2.Text = "Offset"; + this.label2.TextAlign = ContentAlignment.MiddleCenter; + this.centerPanel.BackColor = Color.Black; + this.centerPanel.Controls.Add(this.spectrumPanel); + this.centerPanel.Controls.Add(this.bottomSplitter); + this.centerPanel.Controls.Add(this.bottomPluginPanel); + this.centerPanel.Controls.Add(this.topSplitter); + this.centerPanel.Controls.Add(this.topPluginPanel); + this.centerPanel.Controls.Add(this.rightSplitter); + this.centerPanel.Controls.Add(this.leftSplitter); + this.centerPanel.Controls.Add(this.leftPluginPanel); + this.centerPanel.Controls.Add(this.rightPluginPanel); + this.centerPanel.Dock = DockStyle.Fill; + this.centerPanel.Location = new Point(256, 61); + this.centerPanel.Margin = new Padding(0); + this.centerPanel.Name = "centerPanel"; + this.centerPanel.Size = new Size(666, 690); + this.centerPanel.TabIndex = 4; + this.spectrumPanel.Controls.Add(this.spectrumSplitter); + this.spectrumPanel.Controls.Add(this.waterfall); + this.spectrumPanel.Controls.Add(this.spectrumAnalyzer); + this.spectrumPanel.Dock = DockStyle.Fill; + this.spectrumPanel.Location = new Point(4, 4); + this.spectrumPanel.Name = "spectrumPanel"; + this.spectrumPanel.Size = new Size(658, 682); + this.spectrumPanel.TabIndex = 38; + this.spectrumSplitter.BackColor = SystemColors.Control; + this.spectrumSplitter.Dock = DockStyle.Top; + this.spectrumSplitter.Location = new Point(0, 324); + this.spectrumSplitter.MinExtra = 0; + this.spectrumSplitter.MinSize = 0; + this.spectrumSplitter.Name = "spectrumSplitter"; + this.spectrumSplitter.Size = new Size(658, 4); + this.spectrumSplitter.TabIndex = 1; + this.spectrumSplitter.TabStop = false; + this.waterfall.Attack = 0.9f; + this.waterfall.BandType = BandType.Center; + this.waterfall.CenterFrequency = 0L; + this.waterfall.Contrast = 0; + this.waterfall.Decay = 0.5f; + this.waterfall.DisplayOffset = 0; + this.waterfall.DisplayRange = 130; + this.waterfall.Dock = DockStyle.Fill; + this.waterfall.EnableFilter = true; + this.waterfall.EnableFilterMove = true; + this.waterfall.EnableFrequencyMarker = true; + this.waterfall.EnableHotTracking = true; + this.waterfall.EnableSideFilterResize = false; + this.waterfall.FilterBandwidth = 10000; + this.waterfall.FilterOffset = 0; + this.waterfall.Frequency = 0L; + this.waterfall.Location = new Point(0, 324); + this.waterfall.Name = "waterfall"; + this.waterfall.Size = new Size(658, 358); + this.waterfall.SpectrumWidth = 48000; + this.waterfall.StepSize = 0; + this.waterfall.TabIndex = 0; + this.waterfall.TimestampInterval = 100; + this.waterfall.UseSmoothing = true; + this.waterfall.UseSnap = false; + this.waterfall.UseTimestamps = false; + this.waterfall.Zoom = 0; + this.waterfall.FrequencyChanged += this.panview_FrequencyChanged; + this.waterfall.CenterFrequencyChanged += this.panview_CenterFrequencyChanged; + this.waterfall.BandwidthChanged += this.panview_BandwidthChanged; + this.waterfall.CustomPaint += this.waterfall_CustomPaint; + this.spectrumAnalyzer.Attack = 0.9f; + this.spectrumAnalyzer.BandType = BandType.Center; + this.spectrumAnalyzer.CenterFrequency = 0L; + this.spectrumAnalyzer.Contrast = 0; + this.spectrumAnalyzer.Decay = 0.3f; + this.spectrumAnalyzer.DisplayOffset = 0; + this.spectrumAnalyzer.DisplayRange = 130; + this.spectrumAnalyzer.Dock = DockStyle.Top; + this.spectrumAnalyzer.EnableFilter = true; + this.spectrumAnalyzer.EnableFilterMove = true; + this.spectrumAnalyzer.EnableFrequencyMarker = true; + this.spectrumAnalyzer.EnableHotTracking = true; + this.spectrumAnalyzer.EnableSideFilterResize = false; + this.spectrumAnalyzer.EnableSNR = true; + this.spectrumAnalyzer.FilterBandwidth = 10000; + this.spectrumAnalyzer.FilterOffset = 100; + this.spectrumAnalyzer.Frequency = 0L; + this.spectrumAnalyzer.Location = new Point(0, 0); + this.spectrumAnalyzer.MarkPeaks = false; + this.spectrumAnalyzer.Name = "spectrumAnalyzer"; + this.spectrumAnalyzer.Size = new Size(658, 324); + this.spectrumAnalyzer.SpectrumStyle = SpectrumStyle.StaticGradient; + this.spectrumAnalyzer.SpectrumWidth = 48000; + this.spectrumAnalyzer.StatusText = null; + this.spectrumAnalyzer.StepSize = 1000; + this.spectrumAnalyzer.TabIndex = 0; + this.spectrumAnalyzer.UseSmoothing = true; + this.spectrumAnalyzer.UseSnap = false; + this.spectrumAnalyzer.UseStepSizeForDisplay = false; + this.spectrumAnalyzer.Zoom = 0; + this.spectrumAnalyzer.FrequencyChanged += this.panview_FrequencyChanged; + this.spectrumAnalyzer.CenterFrequencyChanged += this.panview_CenterFrequencyChanged; + this.spectrumAnalyzer.BandwidthChanged += this.panview_BandwidthChanged; + this.spectrumAnalyzer.CustomPaint += this.spectrumAnalyzer_CustomPaint; + this.spectrumAnalyzer.BackgroundCustomPaint += this.spectrumAnalyzer_BackgroundCustomPaint; + this.bottomSplitter.BackColor = SystemColors.Control; + this.bottomSplitter.Dock = DockStyle.Bottom; + this.bottomSplitter.Location = new Point(4, 686); + this.bottomSplitter.MinSize = 0; + this.bottomSplitter.Name = "bottomSplitter"; + this.bottomSplitter.Size = new Size(658, 4); + this.bottomSplitter.TabIndex = 42; + this.bottomSplitter.TabStop = false; + this.bottomSplitter.SplitterMoved += this.pluginSplitter_SplitterMoved; + this.bottomPluginPanel.BackColor = SystemColors.Control; + this.bottomPluginPanel.ColumnCount = 1; + this.bottomPluginPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.bottomPluginPanel.Dock = DockStyle.Bottom; + this.bottomPluginPanel.Location = new Point(4, 690); + this.bottomPluginPanel.Margin = new Padding(0); + this.bottomPluginPanel.Name = "bottomPluginPanel"; + this.bottomPluginPanel.RowCount = 1; + this.bottomPluginPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.bottomPluginPanel.Size = new Size(658, 0); + this.bottomPluginPanel.TabIndex = 41; + this.topSplitter.BackColor = SystemColors.Control; + this.topSplitter.Dock = DockStyle.Top; + this.topSplitter.Location = new Point(4, 0); + this.topSplitter.MinSize = 0; + this.topSplitter.Name = "topSplitter"; + this.topSplitter.Size = new Size(658, 4); + this.topSplitter.TabIndex = 40; + this.topSplitter.TabStop = false; + this.topSplitter.SplitterMoved += this.pluginSplitter_SplitterMoved; + this.topPluginPanel.BackColor = SystemColors.Control; + this.topPluginPanel.ColumnCount = 1; + this.topPluginPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.topPluginPanel.Dock = DockStyle.Top; + this.topPluginPanel.Location = new Point(4, 0); + this.topPluginPanel.Margin = new Padding(0); + this.topPluginPanel.Name = "topPluginPanel"; + this.topPluginPanel.RowCount = 1; + this.topPluginPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.topPluginPanel.Size = new Size(658, 0); + this.topPluginPanel.TabIndex = 39; + this.rightSplitter.BackColor = SystemColors.Control; + this.rightSplitter.Dock = DockStyle.Right; + this.rightSplitter.Location = new Point(662, 0); + this.rightSplitter.MinSize = 0; + this.rightSplitter.Name = "rightSplitter"; + this.rightSplitter.Size = new Size(4, 690); + this.rightSplitter.TabIndex = 37; + this.rightSplitter.TabStop = false; + this.rightSplitter.SplitterMoved += this.pluginSplitter_SplitterMoved; + this.leftSplitter.BackColor = SystemColors.Control; + this.leftSplitter.Location = new Point(0, 0); + this.leftSplitter.MinSize = 0; + this.leftSplitter.Name = "leftSplitter"; + this.leftSplitter.Size = new Size(4, 690); + this.leftSplitter.TabIndex = 36; + this.leftSplitter.TabStop = false; + this.leftSplitter.SplitterMoved += this.pluginSplitter_SplitterMoved; + this.leftPluginPanel.BackColor = SystemColors.Control; + this.leftPluginPanel.ColumnCount = 1; + this.leftPluginPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.leftPluginPanel.Dock = DockStyle.Left; + this.leftPluginPanel.Location = new Point(0, 0); + this.leftPluginPanel.Margin = new Padding(0); + this.leftPluginPanel.Name = "leftPluginPanel"; + this.leftPluginPanel.RowCount = 1; + this.leftPluginPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.leftPluginPanel.Size = new Size(0, 690); + this.leftPluginPanel.TabIndex = 1; + this.rightPluginPanel.BackColor = SystemColors.Control; + this.rightPluginPanel.ColumnCount = 1; + this.rightPluginPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.rightPluginPanel.Dock = DockStyle.Right; + this.rightPluginPanel.Location = new Point(666, 0); + this.rightPluginPanel.Margin = new Padding(0); + this.rightPluginPanel.Name = "rightPluginPanel"; + this.rightPluginPanel.RowCount = 1; + this.rightPluginPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.rightPluginPanel.Size = new Size(0, 690); + this.rightPluginPanel.TabIndex = 3; + this.settingsTableLayoutPanel.ColumnCount = 8; + this.settingsTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.settingsTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.settingsTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.settingsTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.settingsTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.settingsTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.settingsTableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.settingsTableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.settingsTableLayoutPanel.Controls.Add(this.playStopButton, 1, 0); + this.settingsTableLayoutPanel.Controls.Add(this.configureSourceButton, 2, 0); + this.settingsTableLayoutPanel.Controls.Add(this.toggleMenuButton, 0, 0); + this.settingsTableLayoutPanel.Controls.Add(this.muteButton, 3, 0); + this.settingsTableLayoutPanel.Controls.Add(this.audioGainTrackBar, 4, 0); + this.settingsTableLayoutPanel.Controls.Add(this.vfoFrequencyEdit, 5, 0); + this.settingsTableLayoutPanel.Controls.Add(this.tuningStyleButton, 6, 0); + this.settingsTableLayoutPanel.Controls.Add(this.logoPictureBox, 7, 0); + this.settingsTableLayoutPanel.Dock = DockStyle.Top; + this.settingsTableLayoutPanel.Location = new Point(10, 10); + this.settingsTableLayoutPanel.Margin = new Padding(0); + this.settingsTableLayoutPanel.Name = "settingsTableLayoutPanel"; + this.settingsTableLayoutPanel.RowCount = 1; + this.settingsTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.settingsTableLayoutPanel.Size = new Size(964, 51); + this.settingsTableLayoutPanel.TabIndex = 33; + this.playStopButton.Anchor = AnchorStyles.None; + this.playStopButton.FlatAppearance.BorderSize = 0; + this.playStopButton.FlatStyle = FlatStyle.Flat; + this.playStopButton.Image = Resources.sdr_start; + this.playStopButton.Location = new Point(39, 10); + this.playStopButton.Name = "playStopButton"; + this.playStopButton.Size = new Size(30, 30); + this.playStopButton.TabIndex = 0; + this.playStopButton.Click += this.playStopButton_Click; + this.configureSourceButton.Anchor = AnchorStyles.None; + this.configureSourceButton.FlatAppearance.BorderSize = 0; + this.configureSourceButton.FlatStyle = FlatStyle.Flat; + this.configureSourceButton.Image = Resources.config_gear; + this.configureSourceButton.Location = new Point(75, 12); + this.configureSourceButton.Name = "configureSourceButton"; + this.configureSourceButton.Size = new Size(30, 26); + this.configureSourceButton.TabIndex = 0; + this.configureSourceButton.UseVisualStyleBackColor = true; + this.configureSourceButton.Click += this.frontendGuiButton_Click; + this.toggleMenuButton.Anchor = AnchorStyles.None; + this.toggleMenuButton.FlatAppearance.BorderSize = 0; + this.toggleMenuButton.FlatStyle = FlatStyle.Flat; + this.toggleMenuButton.Image = Resources.toggle_menu; + this.toggleMenuButton.Location = new Point(3, 10); + this.toggleMenuButton.Name = "toggleMenuButton"; + this.toggleMenuButton.Size = new Size(30, 30); + this.toggleMenuButton.TabIndex = 0; + this.toggleMenuButton.Click += this.toggleMenuButton_Click; + this.muteButton.Anchor = AnchorStyles.None; + this.muteButton.FlatAppearance.BorderSize = 0; + this.muteButton.FlatStyle = FlatStyle.Flat; + this.muteButton.Image = Resources.audio_unmuted; + this.muteButton.Location = new Point(111, 10); + this.muteButton.Name = "muteButton"; + this.muteButton.Size = new Size(30, 30); + this.muteButton.TabIndex = 1; + this.muteButton.UseVisualStyleBackColor = true; + this.muteButton.Click += this.muteButton_Click; + this.vfoFrequencyEdit.Anchor = AnchorStyles.Left; + this.vfoFrequencyEdit.AutoSize = true; + this.vfoFrequencyEdit.AutoSizeMode = AutoSizeMode.GrowAndShrink; + this.vfoFrequencyEdit.BackColor = Color.Transparent; + this.vfoFrequencyEdit.DisableFrequencyEvents = false; + this.vfoFrequencyEdit.Frequency = 0L; + this.vfoFrequencyEdit.Location = new Point(296, 13); + this.vfoFrequencyEdit.Name = "vfoFrequencyEdit"; + this.vfoFrequencyEdit.Size = new Size(274, 25); + this.vfoFrequencyEdit.StepSize = 0; + this.vfoFrequencyEdit.TabIndex = 1; + this.vfoFrequencyEdit.FrequencyChanged += this.vfoFrequencyEdit_FrequencyChanged; + this.vfoFrequencyEdit.FrequencyChanging += this.vfoFrequencyEdit_FrequencyChanging; + this.tuningStyleButton.Anchor = AnchorStyles.Left; + this.tuningStyleButton.FlatAppearance.BorderSize = 0; + this.tuningStyleButton.FlatStyle = FlatStyle.Flat; + this.tuningStyleButton.Image = Resources.free_tuning; + this.tuningStyleButton.Location = new Point(576, 10); + this.tuningStyleButton.Name = "tuningStyleButton"; + this.tuningStyleButton.Size = new Size(30, 30); + this.tuningStyleButton.TabIndex = 2; + this.tuningStyleButton.Click += this.centerButton_Click; + this.logoPictureBox.Anchor = AnchorStyles.Right; + this.logoPictureBox.Cursor = Cursors.Hand; + //this.logoPictureBox.Image = (Image)componentResourceManager.GetObject("logoPictureBox.Image"); + this.logoPictureBox.Location = new Point(842, 3); + this.logoPictureBox.Name = "logoPictureBox"; + this.logoPictureBox.Size = new Size(119, 45); + this.logoPictureBox.SizeMode = PictureBoxSizeMode.Zoom; + this.logoPictureBox.TabIndex = 3; + this.logoPictureBox.TabStop = false; + this.logoPictureBox.Click += this.logoPictureBox_Click; + this.menuSpacerPanel.Dock = DockStyle.Left; + this.menuSpacerPanel.Location = new Point(256, 61); + this.menuSpacerPanel.Name = "menuSpacerPanel"; + this.menuSpacerPanel.Size = new Size(3, 690); + this.menuSpacerPanel.TabIndex = 34; + base.AutoScaleDimensions = new SizeF(96f, 96f); + base.AutoScaleMode = AutoScaleMode.Dpi; + base.ClientSize = new Size(984, 761); + base.Controls.Add(this.menuSpacerPanel); + base.Controls.Add(this.centerPanel); + base.Controls.Add(this.rightTableLayoutPanel); + base.Controls.Add(this.scrollPanel); + base.Controls.Add(this.settingsTableLayoutPanel); + base.KeyPreview = true; + base.Name = "MainForm"; + base.Padding = new Padding(10); + base.SizeGripStyle = SizeGripStyle.Show; + base.StartPosition = FormStartPosition.Manual; + this.Text = "SDR#"; + base.Closing += this.MainForm_Closing; + base.Load += this.MainForm_Load; + base.Move += this.MainForm_Move; + base.Resize += this.MainForm_Resize; + ((ISupportInitialize)this.fftContrastTrackBar).EndInit(); + ((ISupportInitialize)this.fftZoomTrackBar).EndInit(); + this.controlPanel.ResumeLayout(false); + this.sourceCollapsiblePanel.Content.ResumeLayout(false); + this.sourceCollapsiblePanel.Content.PerformLayout(); + this.sourceCollapsiblePanel.ResumeLayout(false); + this.sourceTableLayoutPanel.ResumeLayout(false); + this.radioCollapsiblePanel.Content.ResumeLayout(false); + this.radioCollapsiblePanel.ResumeLayout(false); + this.radioTableLayoutPanel.ResumeLayout(false); + this.radioTableLayoutPanel.PerformLayout(); + this.tableLayoutPanel7.ResumeLayout(false); + this.tableLayoutPanel7.PerformLayout(); + ((ISupportInitialize)this.cwShiftNumericUpDown).EndInit(); + ((ISupportInitialize)this.squelchNumericUpDown).EndInit(); + ((ISupportInitialize)this.filterBandwidthNumericUpDown).EndInit(); + ((ISupportInitialize)this.filterOrderNumericUpDown).EndInit(); + ((ISupportInitialize)this.frequencyShiftNumericUpDown).EndInit(); + this.audioCollapsiblePanel.Content.ResumeLayout(false); + this.audioCollapsiblePanel.ResumeLayout(false); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + ((ISupportInitialize)this.latencyNumericUpDown).EndInit(); + this.agcCollapsiblePanel.Content.ResumeLayout(false); + this.agcCollapsiblePanel.ResumeLayout(false); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); + ((ISupportInitialize)this.agcSlopeNumericUpDown).EndInit(); + ((ISupportInitialize)this.agcDecayNumericUpDown).EndInit(); + ((ISupportInitialize)this.agcThresholdNumericUpDown).EndInit(); + this.fftCollapsiblePanel.Content.ResumeLayout(false); + this.fftCollapsiblePanel.ResumeLayout(false); + this.tableLayoutPanel3.ResumeLayout(false); + this.tableLayoutPanel3.PerformLayout(); + this.groupBox1.ResumeLayout(false); + this.tableLayoutPanel5.ResumeLayout(false); + this.tableLayoutPanel5.PerformLayout(); + ((ISupportInitialize)this.fftSpeedTrackBar).EndInit(); + this.smoothingGroupBox.ResumeLayout(false); + this.tableLayoutPanel4.ResumeLayout(false); + this.tableLayoutPanel4.PerformLayout(); + ((ISupportInitialize)this.wDecayTrackBar).EndInit(); + ((ISupportInitialize)this.wAttackTrackBar).EndInit(); + ((ISupportInitialize)this.sDecayTrackBar).EndInit(); + ((ISupportInitialize)this.sAttackTrackBar).EndInit(); + ((ISupportInitialize)this.fftOffsetTrackBar).EndInit(); + ((ISupportInitialize)this.fftRangeTrackBar).EndInit(); + ((ISupportInitialize)this.audioGainTrackBar).EndInit(); + this.scrollPanel.ResumeLayout(false); + this.scrollPanel.PerformLayout(); + this.rightTableLayoutPanel.ResumeLayout(false); + this.rightTableLayoutPanel.PerformLayout(); + this.centerPanel.ResumeLayout(false); + this.spectrumPanel.ResumeLayout(false); + this.settingsTableLayoutPanel.ResumeLayout(false); + this.settingsTableLayoutPanel.PerformLayout(); + ((ISupportInitialize)this.logoPictureBox).EndInit(); + base.ResumeLayout(false); + base.PerformLayout(); + } + + public MainForm() + { + this._hookManager = new HookManager(); + this._hookManager.RegisterStreamHook(this._iqBalancerProcessor, ProcessorType.RawIQ); + this._streamControl = new StreamControl(this._hookManager); + this._vfo = new Vfo(this._hookManager); + this._sharpControlProxy = new SharpControlProxy(this); + this.InitializeComponent(); + this.InitializeGUI(); + } + + private unsafe void InitializeGUI() + { + this._initializing = true; + base.Icon = Resources.mainicon; + this._sourcePanelHeight = this.sourceCollapsiblePanel.Height; + this._modeStates[DetectorType.WFM] = Utils.GetIntArraySetting("wfmState", MainForm._defaultWFMState); + this._modeStates[DetectorType.NFM] = Utils.GetIntArraySetting("nfmState", MainForm._defaultNFMState); + this._modeStates[DetectorType.AM] = Utils.GetIntArraySetting("amState", MainForm._defaultAMState); + this._modeStates[DetectorType.LSB] = Utils.GetIntArraySetting("lsbState", MainForm._defaultSSBState); + this._modeStates[DetectorType.USB] = Utils.GetIntArraySetting("usbState", MainForm._defaultSSBState); + this._modeStates[DetectorType.DSB] = Utils.GetIntArraySetting("dsbState", MainForm._defaultDSBState); + this._modeStates[DetectorType.CW] = Utils.GetIntArraySetting("cwState", MainForm._defaultCWState); + this._modeStates[DetectorType.RAW] = Utils.GetIntArraySetting("rawState", MainForm._defaultRAWState); + ThreadPool.QueueUserWorkItem(this.TuneThreadProc); + string stringSetting = Utils.GetStringSetting("stepSizes", "1 Hz,10 Hz,100 Hz,500 Hz,1 kHz,2.5 kHz,5 kHz,6.25 kHz,7.5 kHz,8.33 kHz,9 kHz,10 kHz,12.5 kHz,15 kHz,20 kHz,25 kHz,30 kHz,50 kHz,100 kHz,150 kHz,200 kHz,250 kHz,300 kHz,350 kHz,400 kHz,450 kHz,500 kHz"); + this.stepSizeComboBox.Items.AddRange(stringSetting.Split(',')); + this._tuningStyle = (TuningStyle)Utils.GetIntSetting("tuningStyle", 0); + int num = 0; + int num2 = -1; + List devices = AudioDevice.GetDevices(DeviceDirection.Input); + string stringSetting2 = Utils.GetStringSetting("inputDevice", string.Empty); + for (int i = 0; i < devices.Count; i++) + { + this.inputDeviceComboBox.Items.Add(devices[i]); + if (devices[i].IsDefault) + { + num = i; + } + if (devices[i].ToString() == stringSetting2) + { + num2 = i; + } + } + if (this.inputDeviceComboBox.Items.Count > 0) + { + this.inputDeviceComboBox.SelectedIndex = ((num2 >= 0) ? num2 : num); + } + num = 0; + devices = AudioDevice.GetDevices(DeviceDirection.Output); + stringSetting2 = Utils.GetStringSetting("outputDevice", string.Empty); + for (int j = 0; j < devices.Count; j++) + { + this.outputDeviceComboBox.Items.Add(devices[j]); + if (devices[j].IsDefault) + { + num = j; + } + if (devices[j].ToString() == stringSetting2) + { + num2 = j; + } + } + if (this.outputDeviceComboBox.Items.Count > 0) + { + this.outputDeviceComboBox.SelectedIndex = ((num2 >= 0) ? num2 : num); + } + this._streamControl.BufferNeeded += this.ProcessBuffer; + this.DetectorType = (DetectorType)Utils.GetIntSetting("detectorType", 2); + this.modeRadioButton_CheckStateChanged(null, null); + this.filterBandwidthNumericUpDown_ValueChanged(null, null); + this.filterOrderNumericUpDown_ValueChanged(null, null); + this.filterTypeComboBox_SelectedIndexChanged(null, null); + this.cwShiftNumericUpDown_ValueChanged(null, null); + this.agcCheckBox.Checked = Utils.GetBooleanSetting("useAGC"); + this.agcCheckBox_CheckedChanged(null, null); + this.agcThresholdNumericUpDown.Value = Utils.GetIntSetting("agcThreshold", -100); + this.agcThresholdNumericUpDown_ValueChanged(null, null); + this.agcDecayNumericUpDown.Value = Utils.GetIntSetting("agcDecay", 100); + this.agcDecayNumericUpDown_ValueChanged(null, null); + this.agcSlopeNumericUpDown.Value = Utils.GetIntSetting("agcSlope", 0); + this.agcSlopeNumericUpDown_ValueChanged(null, null); + this.agcUseHangCheckBox.Checked = Utils.GetBooleanSetting("agcHang"); + this.agcUseHangCheckBox_CheckedChanged(null, null); + this.ResetFrequency(0L); + this.frequencyShiftNumericUpDown.Value = Utils.GetLongSetting("frequencyShift", 0L); + this.frequencyShiftNumericUpDown_ValueChanged(null, null); + this.frequencyShiftCheckBox.Checked = Utils.GetBooleanSetting("frequencyShiftEnabled"); + this.frequencyShiftCheckBox_CheckStateChanged(null, null); + this.swapIQCheckBox.Checked = Utils.GetBooleanSetting("swapIQ"); + this.swapIQCheckBox_CheckedChanged(null, null); + this.correctIQCheckBox.Checked = Utils.GetBooleanSetting("correctIQ"); + this.autoCorrectIQCheckBox_CheckStateChanged(null, null); + this.markPeaksCheckBox.Checked = Utils.GetBooleanSetting("markPeaks"); + this.markPeaksCheckBox_CheckedChanged(null, null); + this.fmStereoCheckBox.Checked = Utils.GetBooleanSetting("fmStereo"); + this.fmStereoCheckBox_CheckedChanged(null, null); + this.filterAudioCheckBox.Checked = Utils.GetBooleanSetting("filterAudio"); + this.filterAudioCheckBox_CheckStateChanged(null, null); + this.unityGainCheckBox.Checked = Utils.GetBooleanSetting("unityGain"); + this.unityGainCheckBox_CheckStateChanged(null, null); + this.audioGainTrackBar.Value = Utils.GetIntSetting("audioGain", 50); + this.audioGainTrackBar_ValueChanged(null, null); + this._vfo.Muted = Utils.GetBooleanSetting("AudioIsMuted"); + this.UpdateMuteButton(); + this.latencyNumericUpDown.Value = Utils.GetIntSetting("latency", 100); + this.sampleRateComboBox.Text = Utils.GetStringSetting("sampleRate", "48000 sample/sec"); + base.WindowState = (FormWindowState)Utils.GetIntSetting("windowState", 0); + this._usableSpectrumWidth = Utils.GetIntSetting("spectrumWidth", 48000); + this.spectrumAnalyzer.SpectrumWidth = this._usableSpectrumWidth; + this.waterfall.SpectrumWidth = this._usableSpectrumWidth; + this.lockCarrierCheckBox.Checked = Utils.GetBooleanSetting("lockCarrier"); + this.lockCarrierCheckBox_CheckedChanged(null, null); + this.useAntiFadingCheckBox.Checked = Utils.GetBooleanSetting("useAntiFading"); + this.useAntiFadingCheckBox_CheckedChanged(null, null); + int[] intArraySetting = Utils.GetIntArraySetting("windowPosition", null); + if (intArraySetting != null) + { + this._lastLocation.X = intArraySetting[0]; + this._lastLocation.Y = intArraySetting[1]; + base.Location = this._lastLocation; + } + else + { + this._lastLocation = base.Location; + } + int[] intArraySetting2 = Utils.GetIntArraySetting("windowSize", null); + if (intArraySetting2 != null) + { + this._lastSize.Width = intArraySetting2[0]; + this._lastSize.Height = intArraySetting2[1]; + base.Size = this._lastSize; + } + else + { + this._lastSize = base.Size; + } + this.spectrumSplitter.SplitPosition = Utils.GetIntSetting("splitterPosition", this.spectrumSplitter.SplitPosition); + this._waterfallTimer = new System.Windows.Forms.Timer(this.components); + this._waterfallTimer.Tick += this.waterfallTimer_Tick; + this._waterfallTimer.Enabled = true; + this._spectrumAnalyzerTimer = new System.Windows.Forms.Timer(this.components); + this._spectrumAnalyzerTimer.Tick += this.spectrumAnalyzerTimer_Tick; + this._spectrumAnalyzerTimer.Interval = 20; + this._spectrumAnalyzerTimer.Enabled = true; + this.viewComboBox.SelectedIndex = Utils.GetIntSetting("fftView", 2); + this.fftResolutionComboBox.SelectedIndex = Utils.GetIntSetting("fftResolution", 6); + this.fftWindowComboBox.SelectedIndex = Utils.GetIntSetting("fftWindowType", 3); + this.spectrumStyleComboBox.SelectedIndex = Utils.GetIntSetting("spectrumStyle", 3); + this.spectrumStyleComboBox_SelectedIndexChanged(null, null); + this.fftSpeedTrackBar.Value = Utils.GetIntSetting("fftSpeed", 40); + this.fftSpeedTrackBar_ValueChanged(null, null); + this.fftContrastTrackBar.Value = Utils.GetIntSetting("fftContrast", 0); + this.fftContrastTrackBar_Changed(null, null); + this.spectrumAnalyzer.Attack = (float)Utils.GetDoubleSetting("spectrumAnalyzer.attack", 0.5); + this.sAttackTrackBar.Value = (int)(this.spectrumAnalyzer.Attack * (float)this.sAttackTrackBar.Maximum); + this.spectrumAnalyzer.Decay = (float)Utils.GetDoubleSetting("spectrumAnalyzer.decay", 0.45); + this.sDecayTrackBar.Value = (int)(this.spectrumAnalyzer.Decay * (float)this.sDecayTrackBar.Maximum); + this.waterfall.Attack = (float)Utils.GetDoubleSetting("waterfall.attack", 0.9); + this.wAttackTrackBar.Value = (int)(this.waterfall.Attack * (float)this.wAttackTrackBar.Maximum); + this.waterfall.Decay = (float)Utils.GetDoubleSetting("waterfall.decay", 0.5); + this.wDecayTrackBar.Value = (int)(this.waterfall.Decay * (float)this.wDecayTrackBar.Maximum); + this.useTimestampsCheckBox.Checked = Utils.GetBooleanSetting("useTimeMarkers"); + this.useTimestampCheckBox_CheckedChanged(null, null); + this.fftOffsetTrackBar.Value = Utils.GetIntSetting("fftDisplayOffset", 0); + this.fftOffsetTrackBar_Scroll(null, null); + this.fftRangeTrackBar.Value = Utils.GetIntSetting("fftDisplayRange", 13); + this.fftRangeTrackBar_Scroll(null, null); + this.LoadSource("AIRSPY", new AirspyIO(), 2147483647); + this.LoadSource("AIRSPY HF+", new AirspyHFIO(), 2147483647); + this.LoadSource("Spy Server", new SpyServerIO(), 2147483647); + this.LoadSource("UHD / USRP", "SDRSharp.USRP.UsrpIO,SDRSharp.USRP", 10); + this.LoadSource("HackRF", "SDRSharp.HackRF.HackRFIO,SDRSharp.HackRF", 10); + this.LoadSource("RTL-SDR (R820T)", "SDRSharp.R820T.RtlSdrIO,SDRSharp.R820T", 10); + this.LoadSource("RTL-SDR (USB)", "SDRSharp.RTLSDR.RtlSdrIO,SDRSharp.RTLSDR", 10); + this.LoadSource("RTL-SDR (TCP)", "SDRSharp.RTLTCP.RtlTcpIO,SDRSharp.RTLTCP", 10); + this.LoadSource("FUNcube Dongle Pro", "SDRSharp.FUNcube.FunCubeIO,SDRSharp.FUNcube", 10); + this.LoadSource("FUNcube Dongle Pro+", "SDRSharp.FUNcubeProPlus.FunCubeProPlusIO,SDRSharp.FUNcubeProPlus", 10); + this.LoadSource("SoftRock (Si570)", "SDRSharp.SoftRock.SoftRockIO,SDRSharp.SoftRock", 10); + this.LoadSource("RFSPACE SDR-IQ (USB)", "SDRSharp.SDRIQ.SdrIqIO,SDRSharp.SDRIQ", 10); + this.LoadSource("RFSPACE Networked Radios", "SDRSharp.SDRIP.SdrIpIO,SDRSharp.SDRIP", 10); + this.LoadSource("AFEDRI Networked Radios", "SDRSharp.AfedriSDRNet.AfedriSdrNetIO,SDRSharp.AfedriSDRNet", 10); + this.LoadSource("File Player", "SDRSharp.WAVPlayer.WAVFileIO,SDRSharp.WAVPlayer", 10); + NameValueCollection nameValueCollection = (NameValueCollection)ConfigurationManager.GetSection("frontendPlugins"); + foreach (string key in nameValueCollection.Keys) + { + string text = nameValueCollection[key]; + if (!this.IsFrontEndTypeLoaded(text)) + { + this.LoadSource(key, text, 0); + } + } + this.iqSourceComboBox.Items.Add("IQ File (*.wav)"); + this.iqSourceComboBox.Items.Add("IQ from Sound Card"); + this._waveFile = Utils.GetStringSetting("waveFile", string.Empty); + int intSetting = Utils.GetIntSetting("iqSource", this.iqSourceComboBox.Items.Count - 1); + this.iqSourceComboBox.SelectedIndex = ((intSetting < this.iqSourceComboBox.Items.Count) ? intSetting : (this.iqSourceComboBox.Items.Count - 1)); + this.ResetFrequency(Utils.GetLongSetting("centerFrequency", this._centerFrequency)); + long longSetting = Utils.GetLongSetting("vfo", this._centerFrequency); + this.vfoFrequencyEdit.Frequency = longSetting; + this._tooltip.SetToolTip(this.playStopButton, "Start"); + this._tooltip.SetToolTip(this.logoPictureBox, "Visit our website and check our high performance radios!"); + this.UpdateTuningStyle(); + bool visible = !Utils.GetBooleanSetting("menuIsHidden"); + this.scrollPanel.Visible = visible; + this.menuSpacerPanel.Visible = visible; + this.rightTableLayoutPanel.Visible = visible; + this._tooltip.SetToolTip(this.toggleMenuButton, "Menu"); + this._initializing = false; + } + + private void LoadSource(string name, string fqdn, int access) + { + try + { + IFrontendController controller = (IFrontendController)this.LoadExtension(fqdn); + this.LoadSource(name, controller, access); + } + catch (Exception) + { + } + } + + private void LoadSource(string name, IFrontendController controller, int access) + { + if (access > 0) + { + ISampleRateChangeSource sampleRateChangeSource = controller as ISampleRateChangeSource; + if (sampleRateChangeSource != null) + { + sampleRateChangeSource.SampleRateChanged += this.frontendController_SampleRateChanged; + } + IFFTSource iFFTSource = controller as IFFTSource; + if (iFFTSource != null) + { + iFFTSource.FFTAvailable += this.frontendController_FFTAvailable; + } + IControlAwareObject controlAwareObject = controller as IControlAwareObject; + if (controlAwareObject != null) + { + controlAwareObject.SetControl(this._sharpControlProxy); + } + this._builtinControllers.Add(controller); + } + this._frontendControllers.Add(name, controller); + this.iqSourceComboBox.Items.Add(name); + } + + private void MainForm_Load(object sender, EventArgs e) + { + this.InitialiseSharpPlugins(); + this.scrollPanel.VerticalScroll.Value = Utils.GetIntSetting("menuPosition", 0); + } + + private bool IsFrontEndTypeLoaded(string fqtn) + { + fqtn = fqtn.Replace(" ", string.Empty); + foreach (IFrontendController value in this._frontendControllers.Values) + { + if (value.GetType().AssemblyQualifiedName.Replace(" ", string.Empty).StartsWith(fqtn)) + { + return true; + } + } + return false; + } + + private object LoadExtension(string fqtn) + { + string[] array = fqtn.Split(','); + string typeName = array[0].Trim(); + string assemblyString = array[1].Trim(); + Assembly assembly = Assembly.Load(assemblyString); + return assembly.CreateInstance(typeName); + } + + private void frontendController_SampleRateChanged(object sender, EventArgs e) + { + if (base.InvokeRequired) + { + base.BeginInvoke((Action)delegate + { + this.frontendController_SampleRateChanged(sender, e); + }); + } + else + { + if (this._streamControl.IsPlaying) + { + this._changingSampleRate = true; + try + { + this.StopRadio(); + this.StartRadio(); + } + catch (ApplicationException ex) + { + this.StopRadio(); + MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + finally + { + this._changingSampleRate = false; + } + } + this.ResetFrequency(this._centerFrequency); + this.fftZoomTrackBar.Value = 0; + } + } + + private void MainForm_Closing(object sender, CancelEventArgs e) + { + this._terminated = true; + this._streamControl.Stop(); + this._fftEvent.Set(); + if (this._frontendController != null) + { + this._frontendController.Close(); + } + foreach (ISharpPlugin value in this._sharpPlugins.Values) + { + value.Close(); + } + this._modeStates[this._vfo.DetectorType] = this.GetModeState(); + Utils.SaveSetting("spectrumAnalyzer.attack", (float)this.sAttackTrackBar.Value / (float)this.sAttackTrackBar.Maximum); + Utils.SaveSetting("spectrumAnalyzer.decay", (float)this.sDecayTrackBar.Value / (float)this.sDecayTrackBar.Maximum); + Utils.SaveSetting("waterfall.Attack", (float)this.wAttackTrackBar.Value / (float)this.wAttackTrackBar.Maximum); + Utils.SaveSetting("waterfall.decay", (float)this.wDecayTrackBar.Value / (float)this.wDecayTrackBar.Maximum); + Utils.SaveSetting("useTimeMarkers", this.useTimestampsCheckBox.Checked); + Utils.SaveSetting("fftSpeed", this.fftSpeedTrackBar.Value); + Utils.SaveSetting("fftContrast", this.fftContrastTrackBar.Value); + Utils.SaveSetting("fftWindowType", this.fftWindowComboBox.SelectedIndex); + Utils.SaveSetting("spectrumStyle", this.spectrumStyleComboBox.SelectedIndex); + Utils.SaveSetting("fftView", this.viewComboBox.SelectedIndex); + Utils.SaveSetting("fftResolution", this.fftResolutionComboBox.SelectedIndex); + Utils.SaveSetting("detectorType", (int)this.DetectorType); + Utils.SaveSetting("useAGC", this.agcCheckBox.Checked); + Utils.SaveSetting("agcThreshold", (int)this.agcThresholdNumericUpDown.Value); + Utils.SaveSetting("agcDecay", (int)this.agcDecayNumericUpDown.Value); + Utils.SaveSetting("agcSlope", (int)this.agcSlopeNumericUpDown.Value); + Utils.SaveSetting("agcHang", this.agcUseHangCheckBox.Checked); + Utils.SaveSetting("frequencyShift", (long)this.frequencyShiftNumericUpDown.Value); + Utils.SaveSetting("frequencyShiftEnabled", this.frequencyShiftCheckBox.Checked); + Utils.SaveSetting("swapIQ", this.swapIQCheckBox.Checked); + Utils.SaveSetting("correctIQ", this.correctIQCheckBox.Checked); + Utils.SaveSetting("markPeaks", this.markPeaksCheckBox.Checked); + Utils.SaveSetting("fmStereo", this.fmStereoCheckBox.Checked); + Utils.SaveSetting("filterAudio", this.filterAudioCheckBox.Checked); + Utils.SaveSetting("unityGain", this.unityGainCheckBox.Checked); + Utils.SaveSetting("latency", (int)this.latencyNumericUpDown.Value); + Utils.SaveSetting("sampleRate", this.sampleRateComboBox.Text); + Utils.SaveSetting("audioGain", this.audioGainTrackBar.Value); + Utils.SaveSetting("AudioIsMuted", this._vfo.Muted); + Utils.SaveSetting("windowState", (int)base.WindowState); + Utils.SaveSetting("windowPosition", Utils.IntArrayToString(this._lastLocation.X, this._lastLocation.Y)); + Utils.SaveSetting("windowSize", Utils.IntArrayToString(this._lastSize.Width, this._lastSize.Height)); + Utils.SaveSetting("collapsiblePanelStates", Utils.IntArrayToString(this.GetCollapsiblePanelStates())); + Utils.SaveSetting("splitterPosition", this.spectrumSplitter.SplitPosition); + Utils.SaveSetting("iqSource", this.iqSourceComboBox.SelectedIndex); + Utils.SaveSetting("waveFile", this._waveFile ?? ""); + Utils.SaveSetting("centerFrequency", this._centerFrequency); + Utils.SaveSetting("vfo", this.vfoFrequencyEdit.Frequency); + Utils.SaveSetting("tuningStyle", (int)this._tuningStyle); + Utils.SaveSetting("fftDisplayOffset", this.fftOffsetTrackBar.Value); + Utils.SaveSetting("fftDisplayRange", this.fftRangeTrackBar.Value); + Utils.SaveSetting("inputDevice", this.inputDeviceComboBox.SelectedItem); + Utils.SaveSetting("outputDevice", this.outputDeviceComboBox.SelectedItem); + Utils.SaveSetting("spectrumWidth", this.spectrumAnalyzer.SpectrumWidth); + Utils.SaveSetting("lockCarrier", this.lockCarrierCheckBox.Checked); + Utils.SaveSetting("useAntiFading", this.useAntiFadingCheckBox.Checked); + Utils.SaveSetting("menuPosition", this.scrollPanel.VerticalScroll.Value); + Utils.SaveSetting("wfmState", Utils.IntArrayToString(this._modeStates[DetectorType.WFM])); + Utils.SaveSetting("nfmState", Utils.IntArrayToString(this._modeStates[DetectorType.NFM])); + Utils.SaveSetting("amState", Utils.IntArrayToString(this._modeStates[DetectorType.AM])); + Utils.SaveSetting("lsbState", Utils.IntArrayToString(this._modeStates[DetectorType.LSB])); + Utils.SaveSetting("usbState", Utils.IntArrayToString(this._modeStates[DetectorType.USB])); + Utils.SaveSetting("dsbState", Utils.IntArrayToString(this._modeStates[DetectorType.DSB])); + Utils.SaveSetting("cwState", Utils.IntArrayToString(this._modeStates[DetectorType.CW])); + Utils.SaveSetting("rawState", Utils.IntArrayToString(this._modeStates[DetectorType.RAW])); + if (this._oldTopSplitterPosition > 0) + { + Utils.SaveSetting("topSplitter", this._oldTopSplitterPosition); + } + if (this._oldBottomSplitterPosition > 0) + { + Utils.SaveSetting("bottomSplitter", this._oldBottomSplitterPosition); + } + if (this._oldLeftSplitterPosition > 0) + { + Utils.SaveSetting("leftSplitter", this._oldLeftSplitterPosition); + } + if (this._oldRightSplitterPosition > 0) + { + Utils.SaveSetting("rightSplitter", this._oldRightSplitterPosition); + } + Utils.SaveSetting("menuIsHidden", !this.scrollPanel.Visible); + } + + private void toggleMenuButton_Click(object sender, EventArgs e) + { + this.scrollPanel.Visible = !this.scrollPanel.Visible; + this.menuSpacerPanel.Visible = this.scrollPanel.Visible; + this.rightTableLayoutPanel.Visible = this.scrollPanel.Visible; + } + + private unsafe void ProcessBuffer(Complex* iqBuffer, float* audioBuffer, int length) + { + if (!this.UseFFTSource && this.spectrumPanel.Visible) + { + this._inputBufferLength = length; + this._fftStream.Write(iqBuffer, length); + } + this._vfo.ProcessBuffer(iqBuffer, audioBuffer, length); + } + + private unsafe void ProcessFFT(object parameter) + { + this._fftIsRunning = true; + while (this._streamControl.IsPlaying && this.spectrumPanel.Visible) + { + this._fftResolutionLock.AcquireReaderLock(300000); + double num = (double)this._fftBins / ((double)this._waterfallTimer.Interval * 0.001); + double num2 = this._streamControl.SampleRate / num; + int num3 = (int)((double)this._fftBins * num2); + int num4 = Math.Min(num3, this._fftBins); + int count = num3 - num4; + if (num4 < this._fftBins) + { + Utils.Memcpy(this._iqPtr, this._iqPtr + num4, (this._fftBins - num4) * sizeof(Complex)); + } + int num5 = num4; + int num6 = 0; + while (this._streamControl.IsPlaying && !this._terminated && num6 < num5) + { + int count2 = num5 - num6; + num6 += this._fftStream.Read(this._iqPtr, this._fftBins - num5 + num6, count2); + } + if (this._streamControl.IsPlaying && !this._terminated) + { + this._fftStream.Advance(count); + float num7 = (float)(10.0 * Math.Log10((double)this._fftBins / 2.0)); + float offset = 24f - num7 + this._fftOffset; + Utils.Memcpy(this._fftPtr, this._iqPtr, this._fftBins * sizeof(Complex)); + Fourier.ApplyFFTWindow(this._fftPtr, this._fftWindowPtr, this._fftBins); + Fourier.ForwardTransform(this._fftPtr, this._fftBins, true); + Fourier.SpectrumPower(this._fftPtr, this._fftSpectrumPtr, this._fftBins, offset); + if (num4 < this._fftBins) + { + int num8 = this._fftBins - num4; + while (this._streamControl.IsPlaying && !this._terminated && this._fftStream.Length > this._inputBufferLength * 2 && this._fftStream.Length >= num8) + { + this._fftStream.Read(this._iqPtr + num4, num8); + } + } + else + { + while (this._streamControl.IsPlaying && !this._terminated && this._fftStream.Length > this._inputBufferLength * 2 && this._fftStream.Length >= this._fftBins) + { + this._fftStream.Advance(this._fftBins); + } + } + this._fftResolutionLock.ReleaseReaderLock(); + if (this._streamControl.IsPlaying && !this._terminated) + { + this._fftEvent.WaitOne(); + } + continue; + } + this._fftResolutionLock.ReleaseReaderLock(); + break; + } + this._fftStream.Flush(); + this._fftIsRunning = false; + } + + private unsafe void frontendController_FFTAvailable(object sender, ByteSamplesEventArgs e) + { + IFFTSource iFFTSource = this._frontendController as IFFTSource; + if (this._fftFrames == null || this._fftFrames.BufferSize != e.Length) + { + this._fftFrames = new FloatCircularBuffer(e.Length, 3); + } + float* ptr = stackalloc float[e.Length]; + for (int i = 0; i < e.Length; i++) + { + ptr[i] = (float)(e.Buffer[i] * iFFTSource.FFTRange) / 255f - (float)iFFTSource.FFTRange + (float)iFFTSource.FFTOffset; + } + if (!this._fftFrames.Write(ptr, e.Length, false) && this._fftcorrectionFPS < 10) + { + this._fftcorrectionFPS++; + } + Interlocked.Increment(ref this._fftFramesCount); + } + + private unsafe void RenderFFT() + { + if (this.spectrumPanel.Visible) + { + if (this.UseFFTSource) + { + FloatCircularBuffer fftFrames = this._fftFrames; + if (fftFrames != null) + { + float* ptr = fftFrames.Acquire(false); + if (ptr != null) + { + Utils.Memcpy(this._fftDisplayPtr, ptr, fftFrames.BufferSize * 4); + fftFrames.Release(); + } + } + } + if (this.waterfall.Visible) + { + this._fftResolutionLock.AcquireReaderLock(300000); + this.waterfall.Render(this._fftDisplayPtr, this._fftDisplaySize); + this._fftResolutionLock.ReleaseReaderLock(); + } + } + } + + private void waterfallTimer_Tick(object sender, EventArgs e) + { + if (this._streamControl.IsPlaying) + { + this.RenderFFT(); + if (this.UseFFTSource) + { + DateTime now = DateTime.Now; + float num = (float)(now - this._lastFFTTick).TotalMilliseconds; + this._lastFFTTick = now; + int num2 = Interlocked.Exchange(ref this._fftFramesCount, 0); + if (num2 == 0 && this._fftcorrectionFPS > -10) + { + this._fftcorrectionFPS--; + } + float num3 = (float)num2 / (num * 0.001f); + this._fftAverageFPS += 0.1f * (num3 - this._fftAverageFPS); + int num4 = (int)this._fftAverageFPS + this._fftcorrectionFPS; + if (num4 > 0 && num4 <= 1000) + { + this._waterfallTimer.Interval = 1000 / num4; + } + } + else + { + this._fftEvent.Set(); + } + } + } + + private unsafe void spectrumAnalyzerTimer_Tick(object sender, EventArgs e) + { + if (this._streamControl.IsPlaying && this.spectrumAnalyzer.Visible && this.spectrumPanel.Visible) + { + this._fftResolutionLock.AcquireReaderLock(300000); + this.spectrumAnalyzer.Render(this._fftDisplayPtr, this._fftDisplaySize); + this._fftResolutionLock.ReleaseReaderLock(); + } + } + + private void iqTimer_Tick(object sender, EventArgs e) + { + if (this._vfo.DetectorType == DetectorType.WFM) + { + if (this._vfo.SignalIsStereo) + { + this.spectrumAnalyzer.StatusText = "((( " + this._vfo.RdsStationName + " )))"; + } + else + { + this.spectrumAnalyzer.StatusText = this._vfo.RdsStationName; + } + if (this._vfo.RdsPICode != 0) + { + SpectrumAnalyzer obj = this.spectrumAnalyzer; + obj.StatusText = obj.StatusText + " - " + string.Format("{0:X4}", this._vfo.RdsPICode); + } + if (!string.IsNullOrEmpty(this._vfo.RdsStationText)) + { + SpectrumAnalyzer obj2 = this.spectrumAnalyzer; + obj2.StatusText = obj2.StatusText + " - " + this._vfo.RdsStationText; + } + } + } + + private unsafe void BuildFFTWindow() + { + if (!this.UseFFTSource) + { + float[] array = FilterBuilder.MakeWindow(this._fftWindowType, this._fftBins); + float[] array2 = array; + fixed (float* src = array2) + { + Utils.Memcpy(this._fftWindow, src, this._fftBins * 4); + } + } + } + + private unsafe void InitFFTBuffers() + { + int length = this.UseFFTSource ? (this._frontendController as IFFTSource).DisplayPixels : this._fftBins; + this._iqBuffer = null; + this._fftBuffer = null; + this._fftWindow = null; + this._fftSpectrum = null; + this._scaledFFTSpectrum = null; + GC.Collect(); + this._iqBuffer = UnsafeBuffer.Create(length, sizeof(Complex)); + this._fftBuffer = UnsafeBuffer.Create(length, sizeof(Complex)); + this._fftWindow = UnsafeBuffer.Create(length, 4); + this._fftSpectrum = UnsafeBuffer.Create(length, 4); + this._scaledFFTSpectrum = UnsafeBuffer.Create(length, 1); + this._iqPtr = (Complex*)(void*)this._iqBuffer; + this._fftPtr = (Complex*)(void*)this._fftBuffer; + this._fftWindowPtr = (float*)(void*)this._fftWindow; + this._fftSpectrumPtr = (float*)(void*)this._fftSpectrum; + this._scaledFFTSpectrumPtr = (byte*)(void*)this._scaledFFTSpectrum; + this.InitDisplayFFT(); + } + + private unsafe void InitDisplayFFT() + { + if (this.UseFFTSource) + { + this._fftDisplaySize = (this._frontendController as IFFTSource).DisplayPixels; + this._fftDisplayPtr = this._fftSpectrumPtr; + } + else + { + double num = 0.5 * (double)this._fftBins * (1.0 - (double)this._usableSpectrumWidth / this._vfo.SampleRate); + double num2 = (double)this._fftBins / this._vfo.SampleRate * (double)this._ifOffset; + double a = num - num2; + this._fftDisplaySize = (int)((double)this._fftBins - 2.0 * num); + this._fftDisplayPtr = this._fftSpectrumPtr + (int)Math.Ceiling(a); + } + } + + private void iqSourceComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + this.sourceCollapsiblePanel.PanelTitle = "Source: " + this.iqSourceComboBox.SelectedItem; + this.Text = MainForm._baseTitle + " - " + this.iqSourceComboBox.SelectedItem; + if (this._streamControl.IsPlaying) + { + this.StopRadio(); + } + try + { + this.Open(true); + } + catch (Exception ex) + { + if (this.SourceIsWaveFile && !this._initializing) + { + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + this.NotifyPropertyChanged("SourceName"); + } + + private void SelectWaveFile() + { + if (this.openDlg.ShowDialog() == DialogResult.OK) + { + this.StopRadio(); + this._waveFile = this.openDlg.FileName; + } + } + + private void OpenWaveSource(bool refreshSource) + { + if (!this._initializing & refreshSource) + { + this.SelectWaveFile(); + } + this._tooltip.SetToolTip(this.configureSourceButton, "Select File"); + this.configureSourceButton.Enabled = true; + this.sampleRateComboBox.Enabled = false; + this.inputDeviceComboBox.Enabled = false; + this.outputDeviceComboBox.Enabled = true; + this.latencyNumericUpDown.Enabled = true; + this.frequencyShiftCheckBox.Enabled = false; + this.frequencyShiftCheckBox.Checked = false; + this.frequencyShiftNumericUpDown.Enabled = false; + this._tuningStyle = TuningStyle.Free; + this.UpdateTuningStyle(); + StreamControl.ReducedBandwidth = false; + AudioDevice audioDevice = (AudioDevice)this.outputDeviceComboBox.SelectedItem; + if (audioDevice == null) + { + throw new ApplicationException("No audio playback device found."); + } + this._streamControl.OpenFile(this._waveFile, audioDevice.Index, (int)this.latencyNumericUpDown.Value); + string input = Path.GetFileName(this._waveFile) ?? ""; + Match match = Regex.Match(input, "([0-9]+)kHz", RegexOptions.IgnoreCase); + long num; + if (match.Success) + { + num = int.Parse(match.Groups[1].Value) * 1000; + } + else + { + match = Regex.Match(input, "([\\-0-9]+)Hz", RegexOptions.IgnoreCase); + num = ((!match.Success) ? 0 : long.Parse(match.Groups[1].Value)); + } + this._ifOffset = 0; + if (num > 0) + { + match = Regex.Match(input, "([\\-0-9]+)o", RegexOptions.IgnoreCase); + if (match.Success) + { + this._ifOffset = int.Parse(match.Groups[1].Value); + num -= this._ifOffset; + } + } + if (refreshSource) + { + this.ResetFrequency(num); + } + this._usableSpectrumRatio = 0.9f; + this._usableSpectrumWidth = (int)Math.Ceiling(this._streamControl.SampleRate * (double)this._usableSpectrumRatio); + this.NotifyPropertyChanged("TunableBandwidth"); + this.InitDisplayFFT(); + this.NotifyPropertyChanged("IFOffset"); + } + + private void OpenSoundCardSource() + { + this._tooltip.SetToolTip(this.configureSourceButton, string.Empty); + this.configureSourceButton.Enabled = false; + this.inputDeviceComboBox.Enabled = true; + this.outputDeviceComboBox.Enabled = true; + this.sampleRateComboBox.Enabled = true; + this.frequencyShiftCheckBox.Checked = false; + this.frequencyShiftCheckBox.Enabled = false; + this.frequencyShiftNumericUpDown.Enabled = false; + this.tuningStyleButton.Enabled = false; + this._tuningStyle = TuningStyle.Free; + this.UpdateTuningStyle(); + StreamControl.ReducedBandwidth = false; + AudioDevice audioDevice = (AudioDevice)this.outputDeviceComboBox.SelectedItem; + if (audioDevice == null) + { + throw new ApplicationException("No audio playback device found."); + } + AudioDevice audioDevice2 = (AudioDevice)this.inputDeviceComboBox.SelectedItem; + if (audioDevice == null) + { + throw new ApplicationException("No audio recording device found."); + } + double audioInputSampleRate = this.GetAudioInputSampleRate(); + this._streamControl.OpenSoundDevice(audioDevice2.Index, audioDevice.Index, audioInputSampleRate, (int)this.latencyNumericUpDown.Value); + this._usableSpectrumRatio = 0.9f; + this._usableSpectrumWidth = (int)Math.Ceiling(this._streamControl.SampleRate * (double)this._usableSpectrumRatio); + this.NotifyPropertyChanged("TunableBandwidth"); + this._ifOffset = 0; + this.NotifyPropertyChanged("IFOffset"); + this.ResetFrequency(0L); + } + + private void OpenFrontEndSource(bool refreshSource, FrequencyInitType init) + { + AudioDevice audioDevice = (AudioDevice)this.outputDeviceComboBox.SelectedItem; + if (audioDevice == null) + { + throw new ApplicationException("No audio playback device found."); + } + string key = (string)this.iqSourceComboBox.SelectedItem; + this._frontendController = this._frontendControllers[key]; + this.UpdateVFOSource(); + if (refreshSource) + { + try + { + this._frontendController.Open(); + } + catch (Exception) + { + } + if (this._builtinControllers.Contains(this._frontendController)) + { + IConfigurationPanelProvider configurationPanelProvider = this._frontendController as IConfigurationPanelProvider; + if (configurationPanelProvider != null && configurationPanelProvider.Gui != null) + { + this.ShowControllerPanel(configurationPanelProvider.Gui); + } + } + } + bool flag = this._frontendController is ITunableSource && ((ITunableSource)this._frontendController).CanTune; + if (flag) + { + this.tuningStyleButton.Enabled = true; + } + else + { + this.frequencyShiftCheckBox.Checked = false; + this.tuningStyleButton.Enabled = false; + this._tuningStyle = TuningStyle.Free; + this.UpdateTuningStyle(); + } + this._tooltip.SetToolTip(this.configureSourceButton, "Configure Source"); + this.configureSourceButton.Enabled = true; + this.frequencyShiftCheckBox.Enabled = flag; + this.frequencyShiftNumericUpDown.Enabled = this.frequencyShiftCheckBox.Checked; + this.sampleRateComboBox.Enabled = (this._frontendController is ISoundcardController); + this.inputDeviceComboBox.Enabled = (this._frontendController is ISoundcardController); + this.outputDeviceComboBox.Enabled = true; + if (this._frontendController is ISpectrumProvider) + { + this._usableSpectrumRatio = ((ISpectrumProvider)this._frontendController).UsableSpectrumRatio; + } + else + { + this._usableSpectrumRatio = 0.9f; + } + if (this._frontendController is ISoundcardController) + { + string soundCardHint = ((ISoundcardController)this._frontendController).SoundCardHint; + if (!string.IsNullOrEmpty(soundCardHint)) + { + Regex regex = new Regex(soundCardHint, RegexOptions.IgnoreCase); + for (int i = 0; i < this.inputDeviceComboBox.Items.Count; i++) + { + string input = this.inputDeviceComboBox.Items[i].ToString(); + if (regex.IsMatch(input)) + { + this.inputDeviceComboBox.SelectedIndex = i; + break; + } + } + } + AudioDevice audioDevice2 = (AudioDevice)this.inputDeviceComboBox.SelectedItem; + if (audioDevice == null) + { + throw new ApplicationException("No audio recording device found."); + } + double num; + if (refreshSource && !this._initializing) + { + num = ((ISoundcardController)this._frontendController).SampleRateHint; + this.sampleRateComboBox.Text = num + " sample/sec"; + } + else + { + Match match = Regex.Match(this.sampleRateComboBox.Text, "([0-9\\.]+)", RegexOptions.IgnoreCase); + num = ((!match.Success) ? 48000.0 : double.Parse(match.Groups[1].Value)); + } + this._streamControl.OpenSoundDevice(audioDevice2.Index, audioDevice.Index, num, (int)this.latencyNumericUpDown.Value); + } + else + { + this._streamControl.OpenPlugin(this._frontendController, audioDevice.Index, (int)this.latencyNumericUpDown.Value); + } + if (this.UseFFTSource) + { + this._usableSpectrumWidth = (this._frontendController as IFFTSource).DisplayBandwidth; + } + else + { + this._usableSpectrumWidth = (int)Math.Ceiling((double)this._usableSpectrumRatio * this._streamControl.SampleRate); + } + if (this._frontendController is IIQStreamController) + { + int num2 = (this._frontendController is IFrontendOffset) ? ((IFrontendOffset)this._frontendController).Offset : 0; + this._ifOffset = (((((IIQStreamController)this._frontendController).Samplerate - (double)this._usableSpectrumWidth) * 0.5 >= (double)Math.Abs(num2)) ? num2 : 0); + } + else + { + this._ifOffset = 0; + } + switch (init) + { + case FrequencyInitType.Vfo: + this.ResetFrequency(this.vfoFrequencyEdit.Frequency); + break; + case FrequencyInitType.Device: + if (this._frontendController is ITunableSource) + { + this.ResetFrequency(((ITunableSource)this._frontendController).Frequency - this._ifOffset); + } + break; + } + this.NotifyPropertyChanged("IFOffset"); + this.NotifyPropertyChanged("TunableBandwidth"); + } + + public void RefreshSource(bool reload) + { + this.Open(reload); + } + + private void Open(bool refreshSource) + { + bool flag = true; + if (refreshSource) + { + string text = (string)this.iqSourceComboBox.SelectedItem; + if (text != this._lastSourceName) + { + if (this._frontendController != null) + { + if (this._frontendController is IFloatingConfigDialogProvider) + { + ((IFloatingConfigDialogProvider)this._frontendController).HideSettingGUI(); + } + this._frontendController.Close(); + if (this._builtinControllers.Contains(this._frontendController) && this._frontendController is IConfigurationPanelProvider) + { + IConfigurationPanelProvider configurationPanelProvider = (IConfigurationPanelProvider)this._frontendController; + if (configurationPanelProvider.Gui != null) + { + this.HideControllerPanel(configurationPanelProvider.Gui); + } + } + this._frontendController = null; + } + this._lastSourceName = text; + flag = false; + } + } + if (this.SourceIsWaveFile) + { + this.OpenWaveSource(refreshSource); + } + else if (this.SourceIsSoundCard) + { + this.OpenSoundCardSource(); + } + else + { + FrequencyInitType init = flag ? ((!(this._frontendController is IFFTSource) || (this._frontendController as IFFTSource).FFTEnabled) ? (this._changingSampleRate ? FrequencyInitType.Vfo : FrequencyInitType.None) : FrequencyInitType.None) : FrequencyInitType.Device; + this.OpenFrontEndSource(refreshSource, init); + } + if (this.UseFFTSource) + { + this.fftResolutionComboBox.Enabled = false; + this.fftWindowComboBox.Enabled = false; + this.fftSpeedTrackBar.Enabled = false; + this.sAttackTrackBar.Enabled = false; + this.sDecayTrackBar.Enabled = false; + this.wAttackTrackBar.Enabled = false; + this.wDecayTrackBar.Enabled = false; + this.spectrumAnalyzer.Attack = 0.25f; + this.spectrumAnalyzer.Decay = 0.15f; + this.waterfall.Attack = 0.95f; + this.waterfall.Decay = 0.95f; + this._fftAverageFPS = 50f; + this._fftcorrectionFPS = 0; + this._lastFFTTick = DateTime.Now; + } + else + { + this.fftResolutionComboBox.Enabled = true; + this.fftWindowComboBox.Enabled = true; + this.fftSpeedTrackBar.Enabled = true; + this.sAttackTrackBar.Enabled = true; + this.sDecayTrackBar.Enabled = true; + this.wAttackTrackBar.Enabled = true; + this.fftSpeedTrackBar_ValueChanged(null, null); + this.sAttackTrackBar_ValueChanged(null, null); + this.sDecayTrackBar_ValueChanged(null, null); + this.wAttackTrackBar_ValueChanged(null, null); + this.wDecayTrackBar.Enabled = true; + this.wDecayTrackBar_ValueChanged(null, null); + } + if (this._streamControl.SampleRate > 0.0) + { + this._vfo.SampleRate = this._streamControl.SampleRate; + this._vfo.DecimationStageCount = this._streamControl.DecimationStageCount; + this.spectrumAnalyzer.SpectrumWidth = this._usableSpectrumWidth; + this.waterfall.SpectrumWidth = this._usableSpectrumWidth; + this.UpdateFilterBandwidth(); + } + if (refreshSource) + { + this.fftZoomTrackBar.Value = 0; + this.fftZoomTrackBar_ValueChanged(null, null); + } + this._frequencySet = 0L; + this.InitFFTBuffers(); + this.BuildFFTWindow(); + this.UpdateVfoFrequency(); + this._sharpControlProxy.Enabled = (this.SourceIsSoundCard || this.SourceIsWaveFile || this._builtinControllers.Contains(this._frontendController)); + this._iqBalancerProcessor.Engine.Enabled = (this.correctIQCheckBox.Checked && this._sharpControlProxy.Enabled); + this.spectrumAnalyzer.EnableSNR = this._sharpControlProxy.Enabled; + this._vfo.HookdEnabled = this._sharpControlProxy.Enabled; + if (this._vfo.SampleRate > 0.0) + { + this._vfo.Init(); + } + this._vfo.RdsReset(); + } + + private double GetAudioInputSampleRate() + { + double result = 0.0; + Match match = Regex.Match(this.sampleRateComboBox.Text, "([0-9\\.]+)", RegexOptions.IgnoreCase); + if (match.Success) + { + result = double.Parse(match.Groups[1].Value); + } + return result; + } + + private void audioGainTrackBar_ValueChanged(object sender, EventArgs e) + { + this._streamControl.AudioGain = (float)this.audioGainTrackBar.Value; + if (this.audioGainTrackBar.Value == this.audioGainTrackBar.Minimum) + { + this._vfo.Muted = true; + this._tooltip.SetToolTip(this.audioGainTrackBar, "Muted"); + } + else + { + this._vfo.Muted = false; + this._tooltip.SetToolTip(this.audioGainTrackBar, this.audioGainTrackBar.Value + " dB"); + } + this.UpdateMuteButton(); + this.NotifyPropertyChanged("AudioGain"); + } + + private void filterAudioCheckBox_CheckStateChanged(object sender, EventArgs e) + { + this._vfo.FilterAudio = this.filterAudioCheckBox.Checked; + this.NotifyPropertyChanged("FilterAudio"); + } + + private void unityGainCheckBox_CheckStateChanged(object sender, EventArgs e) + { + this._streamControl.ScaleOutput = !this.unityGainCheckBox.Checked; + this.audioGainTrackBar.Enabled = !this.unityGainCheckBox.Checked; + this.NotifyPropertyChanged("UnityGain"); + } + + private void muteButton_Click(object sender, EventArgs e) + { + if (this._vfo.Muted && this.audioGainTrackBar.Value == this.audioGainTrackBar.Minimum) + { + this.audioGainTrackBar.Value = 30; + this._vfo.Muted = false; + } + else + { + this._vfo.Muted = !this._vfo.Muted; + } + this.UpdateMuteButton(); + } + + private void UpdateMuteButton() + { + if (this._vfo.Muted) + { + this.muteButton.Image = Resources.audio_muted; + this._tooltip.SetToolTip(this.muteButton, "Unmute"); + } + else + { + this.muteButton.Image = Resources.audio_unmuted; + this._tooltip.SetToolTip(this.muteButton, "Mute"); + } + } + + private void playStopButton_Click(object sender, EventArgs e) + { + try + { + if (this._streamControl.IsPlaying) + { + this.StopRadio(); + } + else + { + this.StartRadio(); + } + } + catch (Exception ex) + { + this.StopRadio(); + MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + + private void centerButton_Click(object sender, EventArgs e) + { + int num = (int)(this._tuningStyle = (TuningStyle)((int)(this._tuningStyle + 1) % 3)); + this.UpdateTuningStyle(); + } + + private void UpdateTuningStyle() + { + this.tuningStyleButton.Enabled = !this._tuningStyleFreezed; + switch (this._tuningStyle) + { + case TuningStyle.Free: + this.tuningStyleButton.Image = Resources.free_tuning; + this._tooltip.SetToolTip(this.tuningStyleButton, "Free tuning"); + break; + case TuningStyle.Sticky: + this.tuningStyleButton.Image = Resources.sticky; + this._tooltip.SetToolTip(this.tuningStyleButton, "Sticky tuning"); + break; + case TuningStyle.Center: + this.tuningStyleButton.Image = Resources.center_24; + this._tooltip.SetToolTip(this.tuningStyleButton, "Center tuning"); + if (this.SourceIsTunable) + { + this.ResetFrequency(this.Frequency); + } + this.waterfall.CenterZoom(); + this.spectrumAnalyzer.CenterZoom(); + break; + } + this.NotifyPropertyChanged("TuningStyle"); + } + + private void UpdateVfoFrequency() + { + if (this.UseFFTSource && this._frontendController is IVFOSource) + { + IVFOSource iVFOSource = this._frontendController as IVFOSource; + iVFOSource.VFOFrequency = this.vfoFrequencyEdit.Frequency - this._frequencyShift; + this._vfo.Frequency = 0; + } + else + { + this._vfo.Frequency = (int)(this.vfoFrequencyEdit.Frequency - this._centerFrequency); + } + } + + private void vfoFrequencyEdit_FrequencyChanged(object sender, EventArgs e) + { + this.waterfall.Frequency = this.vfoFrequencyEdit.Frequency; + this.spectrumAnalyzer.Frequency = this.vfoFrequencyEdit.Frequency; + if (this._tuningStyle == TuningStyle.Center) + { + this.waterfall.CenterZoom(); + this.spectrumAnalyzer.CenterZoom(); + } + this.UpdateVfoFrequency(); + this._vfo.IFOffset = -this._ifOffset; + if (this._vfo.DetectorType == DetectorType.WFM) + { + this._vfo.RdsReset(); + } + else + { + this._vfo.CarrierLockerReset(); + } + this.NotifyPropertyChanged("Frequency"); + } + + private void vfoFrequencyEdit_FrequencyChanging(object sender, FrequencyChangingEventArgs e) + { + if (!this._initializing) + { + if (!this.SourceIsTunable) + { + float num = (float)this.spectrumAnalyzer.DisplayCenterFrequency - 0.5f * (float)this.spectrumAnalyzer.DisplayedBandwidth; + float num2 = (float)this.spectrumAnalyzer.DisplayCenterFrequency + 0.5f * (float)this.spectrumAnalyzer.DisplayedBandwidth; + if ((float)e.Frequency > num2) + { + e.Frequency = (long)num2; + } + else if ((float)e.Frequency < num) + { + e.Frequency = (long)num; + } + } + else + { + e.Frequency = this.ApplyFrequencyBoundaries(e.Frequency, this.spectrumAnalyzer.DisplayedBandwidth / 2); + long num3 = this._centerFrequency; + switch (this._tuningStyle) + { + case TuningStyle.Center: + if (!this._changingCenterSpot) + { + e.Accept = this.UpdateCenterFrequency(e.Frequency, false, true); + num3 = e.Frequency; + } + break; + case TuningStyle.Sticky: + if (!this._changingStickySpot) + { + long num4 = e.Frequency - this.vfoFrequencyEdit.Frequency; + num3 = this._centerFrequency + num4; + e.Accept = this.UpdateCenterFrequency(num3, false, false); + } + break; + case TuningStyle.Free: + { + float val = (float)this.spectrumAnalyzer.DisplayCenterFrequency - this._tuningLimit * (float)this.spectrumAnalyzer.DisplayedBandwidth; + val = Math.Max(val, (float)this._centerFrequency - this._tuningLimit * (float)this._usableSpectrumWidth); + float val2 = (float)this.spectrumAnalyzer.DisplayCenterFrequency + this._tuningLimit * (float)this.spectrumAnalyzer.DisplayedBandwidth; + val2 = Math.Min(val2, (float)this._centerFrequency + this._tuningLimit * (float)this._usableSpectrumWidth); + if (!((float)e.Frequency < val) && !((float)e.Frequency > val2)) + { + break; + } + long num4 = e.Frequency - this.vfoFrequencyEdit.Frequency; + num3 = this._centerFrequency + num4; + e.Accept = this.UpdateCenterFrequency(num3, false, false); + break; + } + } + if (e.Accept && this._centerFrequency != num3) + { + e.Frequency = Math.Max(e.Frequency, 0L); + this.fftZoomTrackBar.Value = 0; + if (this._tuningStyle == TuningStyle.Center) + { + this._tuningStyle = TuningStyle.Free; + this.UpdateTuningStyle(); + } + } + } + } + } + + public void SetFrequency(long frequency, bool onlyMoveCenterFrequency) + { + if (onlyMoveCenterFrequency && this._tuningStyle == TuningStyle.Free) + { + long num = frequency - this.vfoFrequencyEdit.Frequency; + this.UpdateCenterFrequency(this._centerFrequency + num, false, false); + } + this.vfoFrequencyEdit.Frequency = frequency; + } + + private void SetCenterFrequency(long newCenterFreq) + { + this.UpdateCenterFrequency(newCenterFreq, true, true); + } + + private void panview_FrequencyChanged(object sender, FrequencyEventArgs e) + { + this._changingStickySpot = (e.Source != FrequencyChangeSource.Scroll); + this.vfoFrequencyEdit.Frequency = e.Frequency; + this._changingStickySpot = false; + if (this.vfoFrequencyEdit.Frequency != e.Frequency) + { + e.Cancel = true; + } + } + + private void panview_CenterFrequencyChanged(object sender, FrequencyEventArgs e) + { + if (!this.SourceIsTunable) + { + e.Cancel = true; + } + else + { + e.Cancel = !this.UpdateCenterFrequency(e.Frequency, true, false); + e.Cancel |= (this._centerFrequency != e.Frequency); + } + } + + public void ResetFrequency(long frequency, long centerFrequency) + { + if (this._tuningStyle == TuningStyle.Center && this.SourceIsTunable) + { + frequency = Math.Max(frequency, (long)((float)this._usableSpectrumWidth * this._tuningLimit)); + } + if (this.SourceIsTunable) + { + this._centerFrequency = centerFrequency; + this.waterfall.CenterFrequency = centerFrequency; + this.spectrumAnalyzer.CenterFrequency = centerFrequency; + this.vfoFrequencyEdit.Frequency = frequency; + } + else + { + this._centerFrequency = centerFrequency; + this.waterfall.Frequency = frequency; + this.waterfall.CenterFrequency = centerFrequency; + this.spectrumAnalyzer.Frequency = frequency; + this.spectrumAnalyzer.CenterFrequency = centerFrequency; + this.vfoFrequencyEdit.DisableFrequencyEvents = true; + this.vfoFrequencyEdit.Frequency = frequency; + this.vfoFrequencyEdit.DisableFrequencyEvents = false; + this._vfo.Frequency = 0; + this._vfo.IFOffset = -this._ifOffset; + } + } + + public void ResetFrequency(long frequency) + { + this.ResetFrequency(frequency, frequency); + } + + private long ApplyFrequencyBoundaries(long frequency, long delta = 0L) + { + if (this.SourceIsTunable) + { + ITunableSource tunableSource = this._frontendController as ITunableSource; + long num = tunableSource.MinimumTunableFrequency - delta + this._frequencyShift; + long num2 = tunableSource.MaximumTunableFrequency + delta + this._frequencyShift; + if (num < 0) + { + num = 0L; + } + if (num2 < 0) + { + num2 = 0L; + } + if (frequency < num) + { + frequency = num; + } + else if (frequency > num2) + { + frequency = num2; + } + } + return frequency; + } + + private bool UpdateCenterFrequency(long frequency, bool setVFO, bool centerZoom = true) + { + if (!this.SourceIsTunable) + { + return false; + } + frequency = this.ApplyFrequencyBoundaries(frequency, 0L); + frequency = Math.Max(frequency, (long)((float)this._usableSpectrumWidth * this._tuningLimit)); + this.waterfall.CenterFrequency = frequency; + this.spectrumAnalyzer.CenterFrequency = frequency; + long num = frequency - this._centerFrequency; + Interlocked.Exchange(ref this._centerFrequency, frequency); + if (setVFO) + { + this._changingStickySpot = (this._tuningStyle == TuningStyle.Sticky); + this._changingCenterSpot = (this._tuningStyle == TuningStyle.Center); + this.vfoFrequencyEdit.Frequency += num; + this._changingStickySpot = false; + this._changingCenterSpot = false; + } + if (this._vfo.DetectorType == DetectorType.WFM) + { + this._vfo.RdsReset(); + } + else + { + this._vfo.CarrierLockerReset(); + } + if (centerZoom) + { + this.waterfall.CenterZoom(); + this.spectrumAnalyzer.CenterZoom(); + } + this.NotifyPropertyChanged("CenterFrequency"); + return true; + } + + private void UpdateTunableBandwidth() + { + this.ResetFrequency(this.vfoFrequencyEdit.Frequency); + this.NotifyPropertyChanged("TuningLimit"); + this.NotifyPropertyChanged("TunableBandwidth"); + } + + private void TuneThreadProc(object state) + { + while (!this._terminated) + { + long num = Interlocked.Read(ref this._centerFrequency) + this._ifOffset; + long num2 = Interlocked.Read(ref this._frequencyShift); + long num3 = num - num2; + IFrontendController frontendController = this._frontendController; + ITunableSource tunableSource = frontendController as ITunableSource; + if (tunableSource != null && this._frequencySet != num3) + { + try + { + tunableSource.Frequency = num3; + this._frequencySet = num3; + } + catch + { + } + } + Thread.Sleep(1); + } + } + + private void filterBandwidthNumericUpDown_ValueChanged(object sender, EventArgs e) + { + this._vfo.Bandwidth = (int)this.filterBandwidthNumericUpDown.Value; + this.waterfall.FilterBandwidth = this._vfo.Bandwidth; + this.spectrumAnalyzer.FilterBandwidth = this._vfo.Bandwidth; + this.NotifyPropertyChanged("FilterBandwidth"); + } + + private void filterOrderNumericUpDown_ValueChanged(object sender, EventArgs e) + { + this._vfo.FilterOrder = (int)this.filterOrderNumericUpDown.Value; + this.NotifyPropertyChanged("FilterOrder"); + } + + private void filterTypeComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + this._vfo.WindowType = (WindowType)(this.filterTypeComboBox.SelectedIndex + 1); + this.NotifyPropertyChanged("FilterType"); + } + + private void autoCorrectIQCheckBox_CheckStateChanged(object sender, EventArgs e) + { + this._iqBalancerProcessor.Engine.Enabled = (this.correctIQCheckBox.Checked && this._sharpControlProxy.Enabled); + this.NotifyPropertyChanged("CorrectIQ"); + } + + private void UpdateFrequencyShift() + { + long num = 0L; + if (this.frequencyShiftCheckBox.Checked) + { + num = (long)this.frequencyShiftNumericUpDown.Value; + } + long num2 = num - this._frequencyShift; + this._frequencyShift = num; + long frequency = Math.Max(this._usableSpectrumWidth / 2, this._centerFrequency + num2); + this.UpdateCenterFrequency(frequency, false, false); + if (Math.Abs(num2) > 10000) + { + long frequency2 = Math.Max(0L, this.vfoFrequencyEdit.Frequency + num2); + this.SetFrequency(frequency2, false); + } + this.UpdateVfoFrequency(); + } + + private void frequencyShiftCheckBox_CheckStateChanged(object sender, EventArgs e) + { + this.frequencyShiftNumericUpDown.Enabled = this.frequencyShiftCheckBox.Checked; + this.UpdateFrequencyShift(); + this.NotifyPropertyChanged("FrequencyShiftEnabled"); + } + + private void frequencyShiftNumericUpDown_ValueChanged(object sender, EventArgs e) + { + this.UpdateFrequencyShift(); + this.NotifyPropertyChanged("FrequencyShift"); + } + + private void modeRadioButton_CheckStateChanged(object sender, EventArgs e) + { + this.agcCheckBox.Enabled = (!this.wfmRadioButton.Checked && !this.rawRadioButton.Checked); + this.agcDecayNumericUpDown.Enabled = this.agcCheckBox.Enabled; + this.agcSlopeNumericUpDown.Enabled = this.agcCheckBox.Enabled; + this.agcThresholdNumericUpDown.Enabled = this.agcCheckBox.Enabled; + this.agcUseHangCheckBox.Enabled = this.agcCheckBox.Enabled; + this.fmStereoCheckBox.Enabled = this.wfmRadioButton.Checked; + this.useSquelchCheckBox.Enabled = (this.nfmRadioButton.Checked || this.amRadioButton.Checked); + this.squelchNumericUpDown.Enabled = (this.useSquelchCheckBox.Enabled && this.useSquelchCheckBox.Checked); + this.cwShiftNumericUpDown.Enabled = this.cwRadioButton.Checked; + this._streamControl.ScaleOutput = !this.unityGainCheckBox.Checked; + this.audioGainTrackBar.Enabled = !this.unityGainCheckBox.Checked; + this.filterAudioCheckBox.Enabled = !this.rawRadioButton.Checked; + this.lockCarrierCheckBox.Enabled = (this.dsbRadioButton.Checked || this.amRadioButton.Checked || this.usbRadioButton.Checked || this.lsbRadioButton.Checked); + this.useAntiFadingCheckBox.Enabled = (this.lockCarrierCheckBox.Checked && this.lockCarrierCheckBox.Enabled && (this.amRadioButton.Checked || this.dsbRadioButton.Checked)); + this.spectrumAnalyzer.StatusText = string.Empty; + if (!this._initializing) + { + this._modeStates[this._vfo.DetectorType] = this.GetModeState(); + } + if (this.wfmRadioButton.Checked) + { + this._vfo.DetectorType = DetectorType.WFM; + this.waterfall.BandType = BandType.Center; + this.spectrumAnalyzer.BandType = BandType.Center; + this.waterfall.FilterOffset = 0; + this.spectrumAnalyzer.FilterOffset = 0; + } + else if (this.nfmRadioButton.Checked) + { + this._vfo.DetectorType = DetectorType.NFM; + this.waterfall.BandType = BandType.Center; + this.spectrumAnalyzer.BandType = BandType.Center; + this.waterfall.FilterOffset = 0; + this.spectrumAnalyzer.FilterOffset = 0; + } + else if (this.amRadioButton.Checked) + { + this._vfo.DetectorType = DetectorType.AM; + this.waterfall.BandType = BandType.Center; + this.spectrumAnalyzer.BandType = BandType.Center; + this.waterfall.FilterOffset = 0; + this.spectrumAnalyzer.FilterOffset = 0; + } + else if (this.lsbRadioButton.Checked) + { + this._vfo.DetectorType = DetectorType.LSB; + this.waterfall.BandType = BandType.Lower; + this.spectrumAnalyzer.BandType = BandType.Lower; + this.waterfall.FilterOffset = -100; + this.spectrumAnalyzer.FilterOffset = -100; + } + else if (this.usbRadioButton.Checked) + { + this._vfo.DetectorType = DetectorType.USB; + this.waterfall.BandType = BandType.Upper; + this.spectrumAnalyzer.BandType = BandType.Upper; + this.waterfall.FilterOffset = 100; + this.spectrumAnalyzer.FilterOffset = 100; + } + else if (this.dsbRadioButton.Checked) + { + this._vfo.DetectorType = DetectorType.DSB; + this.waterfall.BandType = BandType.Center; + this.spectrumAnalyzer.BandType = BandType.Center; + this.waterfall.FilterOffset = 0; + this.spectrumAnalyzer.FilterOffset = 0; + } + else if (this.cwRadioButton.Checked) + { + this._vfo.DetectorType = DetectorType.CW; + this.waterfall.BandType = BandType.Center; + this.spectrumAnalyzer.BandType = BandType.Center; + this.waterfall.FilterOffset = 0; + this.spectrumAnalyzer.FilterOffset = 0; + } + else if (this.rawRadioButton.Checked) + { + this._vfo.DetectorType = DetectorType.RAW; + this.waterfall.BandType = BandType.Center; + this.spectrumAnalyzer.BandType = BandType.Center; + this.waterfall.FilterOffset = 0; + this.spectrumAnalyzer.FilterOffset = 0; + } + this._vfo.RdsReset(); + this.UpdateVFOSource(); + this.UpdateFilterBandwidth(); + this.SetModeState(this._modeStates[this._vfo.DetectorType]); + this.NotifyPropertyChanged("DetectorType"); + } + + private void UpdateVFOSource() + { + if (this.UseFFTSource && this._frontendController is IVFOSource) + { + StreamControl.ReducedBandwidth = true; + IVFOSource iVFOSource = this._frontendController as IVFOSource; + int num = iVFOSource.VFOMinIQDecimation + StreamControl.GetDecimationStageCount(iVFOSource.VFOMaxSampleRate / (double)(1 << iVFOSource.VFOMinIQDecimation), this._vfo.DetectorType); + StreamControl.ReducedBandwidth = (this._vfo.DetectorType != DetectorType.WFM); + if (iVFOSource.VFODecimation != num) + { + bool isPlaying = this.IsPlaying; + if (isPlaying) + { + this.StopRadio(); + } + iVFOSource.VFODecimation = num; + this._vfo.DecimationStageCount = iVFOSource.VFOMinIQDecimation + StreamControl.GetDecimationStageCount(iVFOSource.VFOMaxSampleRate / (double)(1 << iVFOSource.VFOMinIQDecimation), DetectorType.AM) - iVFOSource.VFODecimation; + this._vfo.SampleRate = iVFOSource.VFOMaxSampleRate / (double)(1 << iVFOSource.VFODecimation); + if (isPlaying) + { + this.StartRadio(); + } + } + } + else + { + StreamControl.ReducedBandwidth = false; + } + } + + private void UpdateFilterBandwidth() + { + switch (this._vfo.DetectorType) + { + case DetectorType.WFM: + this.filterBandwidthNumericUpDown.Maximum = ((this._streamControl.SampleRate == 0.0) ? 250000 : ((int)Math.Min(this._streamControl.SampleRate, 250000.0))); + break; + case DetectorType.NFM: + case DetectorType.AM: + case DetectorType.DSB: + case DetectorType.CW: + case DetectorType.RAW: + this.filterBandwidthNumericUpDown.Maximum = ((this._streamControl.AudioSampleRate == 0.0) ? this._minOutputSampleRate : ((int)Math.Min(this._streamControl.AudioSampleRate, (double)this._minOutputSampleRate))); + break; + case DetectorType.LSB: + case DetectorType.USB: + this.filterBandwidthNumericUpDown.Maximum = ((this._streamControl.AudioSampleRate == 0.0) ? (this._minOutputSampleRate / 2) : ((int)Math.Min(this._streamControl.AudioSampleRate, (double)this._minOutputSampleRate) / 2)); + break; + } + } + + private void fmStereoCheckBox_CheckedChanged(object sender, EventArgs e) + { + this._vfo.FmStereo = this.fmStereoCheckBox.Checked; + this.NotifyPropertyChanged("FmStereo"); + } + + private void cwShiftNumericUpDown_ValueChanged(object sender, EventArgs e) + { + this._vfo.CWToneShift = (int)this.cwShiftNumericUpDown.Value; + this.NotifyPropertyChanged("CWShift"); + } + + private void squelchNumericUpDown_ValueChanged(object sender, EventArgs e) + { + if (!this._configuringSquelch) + { + this._vfo.SquelchThreshold = (int)this.squelchNumericUpDown.Value; + this.NotifyPropertyChanged("SquelchThreshold"); + } + } + + private void useSquelchCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (!this._configuringSquelch) + { + this.squelchNumericUpDown.Enabled = this.useSquelchCheckBox.Checked; + if (this.useSquelchCheckBox.Checked) + { + this._vfo.SquelchThreshold = (int)this.squelchNumericUpDown.Value; + } + else + { + this._vfo.SquelchThreshold = 0; + } + this.NotifyPropertyChanged("SquelchEnabled"); + } + } + + private static int ParseStepSize(string s) + { + int result = 0; + Match match = Regex.Match(s, "([0-9\\.]+) ([kMG]?)Hz", RegexOptions.IgnoreCase); + if (match.Success) + { + int num; + switch (match.Groups[2].Value.ToLower()) + { + default: + num = 1; + break; + case "k": + num = 1000; + break; + case "m": + num = 1000000; + break; + case "g": + num = 1000000000; + break; + } + result = (int)(double.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture) * (double)num); + } + return result; + } + + private bool SetStepSize(int stepSize) + { + for (int i = 0; i < this.stepSizeComboBox.Items.Count; i++) + { + int num = MainForm.ParseStepSize(this.stepSizeComboBox.Items[i].ToString()); + if (stepSize == num) + { + this.stepSizeComboBox.SelectedIndex = i; + this.stepSizeComboBox_SelectedIndexChanged(null, null); + return true; + } + } + return false; + } + + private void stepSizeComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + if (!this._configuringSnap) + { + this.waterfall.UseSnap = this.snapFrequencyCheckBox.Checked; + this.spectrumAnalyzer.UseSnap = this.snapFrequencyCheckBox.Checked; + int num = MainForm.ParseStepSize(this.stepSizeComboBox.Text); + if (num > 0 && num != this._stepSize) + { + this.waterfall.StepSize = num; + this.spectrumAnalyzer.StepSize = num; + if (this.snapFrequencyCheckBox.Checked && this.SourceIsTunable) + { + long frequency = (this._centerFrequency + num / 2) / num * num; + this.UpdateCenterFrequency(frequency, false, false); + long num2 = (this.vfoFrequencyEdit.Frequency + num / 2) / num * num; + if (this.vfoFrequencyEdit.Frequency != num2) + { + this.vfoFrequencyEdit.Frequency = num2; + } + } + this._stepSize = num; + if (sender == this.snapFrequencyCheckBox) + { + this.NotifyPropertyChanged("SnapToGrid"); + } + this.NotifyPropertyChanged("StepSize"); + } + } + } + + private void panview_BandwidthChanged(object sender, BandwidthEventArgs e) + { + if ((decimal)e.Bandwidth < this.filterBandwidthNumericUpDown.Minimum) + { + e.Bandwidth = (int)this.filterBandwidthNumericUpDown.Minimum; + } + else if ((decimal)e.Bandwidth > this.filterBandwidthNumericUpDown.Maximum) + { + e.Bandwidth = (int)this.filterBandwidthNumericUpDown.Maximum; + } + this.filterBandwidthNumericUpDown.Value = e.Bandwidth; + } + + private void frontendGuiButton_Click(object sender, EventArgs e) + { + if (this.SourceIsWaveFile) + { + if (this._streamControl.IsPlaying) + { + this.StopRadio(); + } + try + { + this.Open(true); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + } + else if (this.SourceIsFrontEnd) + { + if (this._frontendController is IConfigurationPanelProvider) + { + if (this.scrollPanel.Visible && this.sourceCollapsiblePanel.PanelState == PanelStateOptions.Expanded) + { + this.sourceCollapsiblePanel.PanelState = PanelStateOptions.Collapsed; + } + else + { + this.scrollPanel.Visible = true; + this.menuSpacerPanel.Visible = true; + this.rightTableLayoutPanel.Visible = true; + this.sourceCollapsiblePanel.PanelState = PanelStateOptions.Expanded; + } + this.scrollPanel.ScrollControlIntoView(this.sourceCollapsiblePanel); + } + else if (this._frontendController is IFloatingConfigDialogProvider) + { + ((IFloatingConfigDialogProvider)this._frontendController).ShowSettingGUI(this); + } + } + } + + private int[] GetModeState() + { + return new int[12] + { + this.FilterBandwidth, + this.FilterOrder, + (int)this.FilterType, + this.SquelchThreshold, + this.SquelchEnabled ? 1 : 0, + this.CWShift, + this.SnapToGrid ? 1 : 0, + this.stepSizeComboBox.SelectedIndex, + this.unityGainCheckBox.Checked ? 1 : 0, + this.agcCheckBox.Checked ? 1 : 0, + this.lockCarrierCheckBox.Checked ? 1 : 0, + this.useAntiFadingCheckBox.Checked ? 1 : 0 + }; + } + + private void SetModeState(int[] state) + { + this.FilterBandwidth = Math.Min(state[0], (int)this.filterBandwidthNumericUpDown.Maximum); + this.FilterOrder = state[1]; + this.FilterType = (WindowType)state[2]; + this._configuringSquelch = true; + this.SquelchThreshold = state[3]; + this.SquelchEnabled = (state[4] == 1); + this._configuringSquelch = false; + this.useSquelchCheckBox_CheckedChanged(null, null); + this.CWShift = state[5]; + this._configuringSnap = true; + this.SnapToGrid = (state[6] == 1); + this.stepSizeComboBox.SelectedIndex = Math.Min(this.stepSizeComboBox.Items.Count - 1, state[7]); + this._configuringSnap = false; + this.stepSizeComboBox_SelectedIndexChanged(null, null); + this.unityGainCheckBox.Checked = (state[8] == 1); + this.unityGainCheckBox_CheckStateChanged(null, null); + this.agcCheckBox.Checked = (state[9] == 1); + this.agcCheckBox_CheckedChanged(null, null); + this.lockCarrierCheckBox.Checked = (state[10] == 1); + this.lockCarrierCheckBox_CheckedChanged(null, null); + this.useAntiFadingCheckBox.Checked = (state[11] == 1); + this.useAntiFadingCheckBox_CheckedChanged(null, null); + } + + private void lockCarrierCheckBox_CheckedChanged(object sender, EventArgs e) + { + this._vfo.LockCarrier = this.lockCarrierCheckBox.Checked; + this.useAntiFadingCheckBox.Enabled = (this.lockCarrierCheckBox.Checked && this.lockCarrierCheckBox.Enabled && (this.amRadioButton.Checked || this.dsbRadioButton.Checked)); + } + + private void useAntiFadingCheckBox_CheckedChanged(object sender, EventArgs e) + { + this._vfo.UseAntiFading = this.useAntiFadingCheckBox.Checked; + } + + private void agcCheckBox_CheckedChanged(object sender, EventArgs e) + { + this._vfo.UseAGC = this.agcCheckBox.Checked; + this.agcThresholdNumericUpDown.Enabled = (this.agcCheckBox.Checked && this.agcCheckBox.Enabled); + this.agcDecayNumericUpDown.Enabled = (this.agcCheckBox.Checked && this.agcCheckBox.Enabled); + this.agcSlopeNumericUpDown.Enabled = (this.agcCheckBox.Checked && this.agcCheckBox.Enabled); + this.agcUseHangCheckBox.Enabled = (this.agcCheckBox.Checked && this.agcCheckBox.Enabled); + this.NotifyPropertyChanged("UseAgc"); + } + + private void agcUseHangCheckBox_CheckedChanged(object sender, EventArgs e) + { + this._vfo.AgcHang = this.agcUseHangCheckBox.Checked; + this.NotifyPropertyChanged("UseHang"); + } + + private void agcDecayNumericUpDown_ValueChanged(object sender, EventArgs e) + { + this._vfo.AgcDecay = (float)(int)this.agcDecayNumericUpDown.Value; + this.NotifyPropertyChanged("AgcDecay"); + } + + private void agcThresholdNumericUpDown_ValueChanged(object sender, EventArgs e) + { + this._vfo.AgcThreshold = (float)(int)this.agcThresholdNumericUpDown.Value; + this.NotifyPropertyChanged("AgcThreshold"); + } + + private void agcSlopeNumericUpDown_ValueChanged(object sender, EventArgs e) + { + this._vfo.AgcSlope = (float)(int)this.agcSlopeNumericUpDown.Value; + this.NotifyPropertyChanged("AgcSlope"); + } + + private void swapIQCheckBox_CheckedChanged(object sender, EventArgs e) + { + this._streamControl.SwapIQ = this.swapIQCheckBox.Checked; + this.NotifyPropertyChanged("SwapIq"); + } + + private void viewComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + bool flag = false; + bool flag2 = false; + if (this._streamControl.IsPlaying) + { + if (this.viewComboBox.SelectedIndex < 3 && !this.spectrumPanel.Visible) + { + flag = true; + } + else if (this.viewComboBox.SelectedIndex == 3 && this.spectrumPanel.Visible) + { + flag2 = true; + } + } + switch (this.viewComboBox.SelectedIndex) + { + case 0: + this.spectrumPanel.Visible = true; + this.spectrumAnalyzer.Visible = true; + this.waterfall.Visible = false; + this.spectrumAnalyzer.Dock = DockStyle.Fill; + this.spectrumSplitter.Visible = false; + break; + case 1: + this.spectrumPanel.Visible = true; + this.spectrumAnalyzer.Visible = false; + this.waterfall.Visible = true; + this.spectrumAnalyzer.Dock = DockStyle.Top; + this.spectrumSplitter.Visible = false; + break; + case 2: + this.spectrumPanel.Visible = true; + this.spectrumAnalyzer.Visible = true; + this.waterfall.Visible = true; + this.spectrumAnalyzer.Dock = DockStyle.Top; + this.spectrumSplitter.Visible = true; + break; + case 3: + this.spectrumPanel.Visible = false; + break; + } + if (!this.UseFFTSource) + { + if (flag) + { + this._fftStream.Open(); + ThreadPool.QueueUserWorkItem(this.ProcessFFT); + } + else if (flag2) + { + this._fftStream.Close(); + this._fftEvent.Set(); + } + } + } + + private void fftResolutionComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + this._fftResolutionLock.AcquireWriterLock(300000); + this._fftBins = int.Parse(this.fftResolutionComboBox.SelectedItem.ToString()); + this.InitFFTBuffers(); + this.BuildFFTWindow(); + this._fftResolutionLock.ReleaseWriterLock(); + this.NotifyPropertyChanged("FFTResolution"); + } + + private void spectrumStyleComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + this.spectrumAnalyzer.SpectrumStyle = (SpectrumStyle)this.spectrumStyleComboBox.SelectedIndex; + this.NotifyPropertyChanged("FFTSpectrumStyle"); + } + + private void fftWindowComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + this._fftWindowType = (WindowType)this.fftWindowComboBox.SelectedIndex; + this.BuildFFTWindow(); + } + + private void gradientButton_Click(object sender, EventArgs e) + { + ColorBlend gradient = GradientDialog.GetGradient(this.waterfall.GradientColorBlend); + if (gradient != null && gradient.Positions.Length != 0) + { + this.waterfall.GradientColorBlend = gradient; + this.spectrumAnalyzer.VerticalLinesGradient = gradient; + Utils.SaveSetting("waterfall.gradient", MainForm.GradientToString(gradient.Colors)); + this.NotifyPropertyChanged("Gradient"); + } + } + + private static string GradientToString(Color[] colors) + { + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < colors.Length; i++) + { + stringBuilder.AppendFormat(",{0:X2}{1:X2}{2:X2}", colors[i].R, colors[i].G, colors[i].B); + } + return stringBuilder.ToString().Substring(1); + } + + private void fftContrastTrackBar_Changed(object sender, EventArgs e) + { + this.waterfall.Contrast = this.fftContrastTrackBar.Value * 100 / (this.fftContrastTrackBar.Maximum - this.fftContrastTrackBar.Minimum); + this.spectrumAnalyzer.Contrast = this.waterfall.Contrast; + this.NotifyPropertyChanged("FFTContrast"); + } + + private void sAttackTrackBar_ValueChanged(object sender, EventArgs e) + { + this.spectrumAnalyzer.Attack = (float)this.sAttackTrackBar.Value / (float)this.sAttackTrackBar.Maximum; + this.NotifyPropertyChanged("SAttack"); + } + + private void sDecayTrackBar_ValueChanged(object sender, EventArgs e) + { + this.spectrumAnalyzer.Decay = (float)this.sDecayTrackBar.Value / (float)this.sDecayTrackBar.Maximum; + this.NotifyPropertyChanged("SDecay"); + } + + private void wAttackTrackBar_ValueChanged(object sender, EventArgs e) + { + this.waterfall.Attack = (float)this.wAttackTrackBar.Value / (float)this.wAttackTrackBar.Maximum; + this.NotifyPropertyChanged("WAttack"); + } + + private void wDecayTrackBar_ValueChanged(object sender, EventArgs e) + { + this.waterfall.Decay = (float)this.wDecayTrackBar.Value / (float)this.wDecayTrackBar.Maximum; + this.NotifyPropertyChanged("WDecay"); + } + + private void markPeaksCheckBox_CheckedChanged(object sender, EventArgs e) + { + this.spectrumAnalyzer.MarkPeaks = this.markPeaksCheckBox.Checked; + this.NotifyPropertyChanged("MarkPeaks"); + } + + private void useTimestampCheckBox_CheckedChanged(object sender, EventArgs e) + { + this.waterfall.UseTimestamps = this.useTimestampsCheckBox.Checked; + this.NotifyPropertyChanged("UseTimeMarkers"); + } + + private void fftSpeedTrackBar_ValueChanged(object sender, EventArgs e) + { + this._waterfallTimer.Interval = (int)(1.0 / (double)this.fftSpeedTrackBar.Value * 1000.0); + } + + private void fftZoomTrackBar_ValueChanged(object sender, EventArgs e) + { + this.spectrumAnalyzer.Zoom = this.fftZoomTrackBar.Value * 100 / this.fftZoomTrackBar.Maximum; + this.waterfall.Zoom = this.spectrumAnalyzer.Zoom; + this.NotifyPropertyChanged("Zoom"); + } + + private void MainForm_Move(object sender, EventArgs e) + { + if (base.WindowState == FormWindowState.Normal) + { + this._lastLocation = base.Location; + } + } + + private void MainForm_Resize(object sender, EventArgs e) + { + if (base.WindowState == FormWindowState.Normal) + { + this._lastSize = base.Size; + } + } + + private int[] GetCollapsiblePanelStates() + { + List list = new List(); + for (SDRSharp.CollapsiblePanel.CollapsiblePanel nextPanel = this.sourceCollapsiblePanel; nextPanel != null; nextPanel = nextPanel.NextPanel) + { + list.Add((int)nextPanel.PanelState); + } + return list.ToArray(); + } + + private void fftOffsetTrackBar_Scroll(object sender, EventArgs e) + { + this.spectrumAnalyzer.DisplayOffset = -this.fftOffsetTrackBar.Value * 10; + this.waterfall.DisplayOffset = this.spectrumAnalyzer.DisplayOffset; + this.NotifyPropertyChanged("FFTOffset"); + } + + private void fftRangeTrackBar_Scroll(object sender, EventArgs e) + { + this.spectrumAnalyzer.DisplayRange = this.fftRangeTrackBar.Value * 10; + this.waterfall.DisplayRange = this.spectrumAnalyzer.DisplayRange; + this.NotifyPropertyChanged("FFTRange"); + } + + private void InitialiseSharpPlugins() + { + NameValueCollection nameValueCollection = (NameValueCollection)ConfigurationManager.GetSection("sharpPlugins"); + if (nameValueCollection == null) + { + MessageBox.Show("Configuration section 'sharpPlugins' was not found. Please check 'SDRSharp.exe.config'.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Hand); + } + else + { + this._oldTopSplitterPosition = Utils.GetIntSetting("topSplitter", this._oldTopSplitterPosition); + this._oldBottomSplitterPosition = Utils.GetIntSetting("bottomSplitter", this._oldBottomSplitterPosition); + this._oldLeftSplitterPosition = Utils.GetIntSetting("leftSplitter", this._oldLeftSplitterPosition); + this._oldRightSplitterPosition = Utils.GetIntSetting("rightSplitter", this._oldRightSplitterPosition); + this.topSplitter.Visible = false; + this.bottomSplitter.Visible = false; + this.leftSplitter.Visible = false; + this.rightSplitter.Visible = false; + foreach (string key in nameValueCollection.Keys) + { + try + { + string fqtn = nameValueCollection[key]; + ISharpPlugin sharpPlugin = (ISharpPlugin)this.LoadExtension(fqtn); + this._sharpPlugins.Add(key, sharpPlugin); + sharpPlugin.Initialize(this._sharpControlProxy); + if (sharpPlugin.Gui != null) + { + this.CreatePluginCollapsiblePanel(sharpPlugin); + } + } + catch (Exception) + { + } + } + this.sourceCollapsiblePanel.PanelState = PanelStateOptions.Collapsed; + int[] intArraySetting = Utils.GetIntArraySetting("collapsiblePanelStates", null); + if (intArraySetting != null) + { + SDRSharp.CollapsiblePanel.CollapsiblePanel nextPanel = this.sourceCollapsiblePanel; + for (int i = 0; i < intArraySetting.Length; i++) + { + if (nextPanel == null) + { + break; + } + nextPanel.PanelState = (PanelStateOptions)intArraySetting[i]; + nextPanel = nextPanel.NextPanel; + } + } + else + { + this.sourceCollapsiblePanel.PanelState = PanelStateOptions.Expanded; + } + } + } + + private void ShowControllerPanel(UserControl gui) + { + if (this.sourceTableLayoutPanel.Controls.Count == 1) + { + this.sourceCollapsiblePanel.Height = this._sourcePanelHeight + gui.Height; + this.sourceTableLayoutPanel.Controls.Add(gui, 0, 1); + gui.Dock = DockStyle.Fill; + } + } + + private void HideControllerPanel(UserControl gui) + { + if (this.sourceTableLayoutPanel.Controls.Count > 1) + { + this.sourceTableLayoutPanel.Controls.Remove(gui); + this.sourceCollapsiblePanel.Height = this._sourcePanelHeight; + } + } + + private void CreatePluginCollapsiblePanel(ISharpPlugin plugin) + { + UserControl gui = plugin.Gui; + if (gui != null) + { + SDRSharp.CollapsiblePanel.CollapsiblePanel collapsiblePanel = new SDRSharp.CollapsiblePanel.CollapsiblePanel(); + collapsiblePanel.PanelTitle = plugin.DisplayName + " *"; + collapsiblePanel.AutoHeight = true; + collapsiblePanel.Content.Controls.Add(gui); + collapsiblePanel.Height = gui.Height; + collapsiblePanel.Width = this.fftCollapsiblePanel.Width; + collapsiblePanel.PanelState = PanelStateOptions.Collapsed; + gui.Dock = DockStyle.Fill; + SDRSharp.CollapsiblePanel.CollapsiblePanel nextPanel = this.fftCollapsiblePanel; + while (nextPanel.NextPanel != null) + { + nextPanel = nextPanel.NextPanel; + } + nextPanel.NextPanel = collapsiblePanel; + this.controlPanel.Controls.Add(collapsiblePanel); + } + } + + public void RegisterFrontControl(UserControl c, PluginPosition position) + { + SizeType sizeType = c.Visible ? SizeType.Absolute : SizeType.AutoSize; + SizeType sizeType2 = c.Visible ? SizeType.Percent : SizeType.AutoSize; + switch (position) + { + case PluginPosition.Top: + if (this.topPluginPanel.Controls.Count > 0) + { + this.topPluginPanel.ColumnCount++; + this.topPluginPanel.ColumnStyles.Add(new ColumnStyle(sizeType, 4f)); + this.topPluginPanel.ColumnCount++; + this.topPluginPanel.ColumnStyles.Add(new ColumnStyle(sizeType2, 100f)); + } + else + { + this.topPluginPanel.ColumnStyles[0].SizeType = sizeType2; + } + this._oldTopSplitterPosition = Math.Max(this._oldTopSplitterPosition, c.Height); + this.topPluginPanel.Controls.Add(c, this.topPluginPanel.ColumnCount - 1, 0); + break; + case PluginPosition.Bottom: + if (this.bottomPluginPanel.Controls.Count > 0) + { + this.bottomPluginPanel.ColumnCount++; + this.bottomPluginPanel.ColumnStyles.Add(new ColumnStyle(sizeType, 4f)); + this.bottomPluginPanel.ColumnCount++; + this.bottomPluginPanel.ColumnStyles.Add(new ColumnStyle(sizeType2, 100f)); + } + else + { + this.bottomPluginPanel.ColumnStyles[0].SizeType = sizeType2; + } + this._oldBottomSplitterPosition = Math.Max(this._oldBottomSplitterPosition, c.Height); + this.bottomPluginPanel.Controls.Add(c, this.bottomPluginPanel.ColumnCount - 1, 0); + break; + case PluginPosition.Left: + if (this.leftPluginPanel.Controls.Count > 0) + { + this.leftPluginPanel.RowCount++; + this.leftPluginPanel.RowStyles.Add(new RowStyle(sizeType, 4f)); + this.leftPluginPanel.RowCount++; + this.leftPluginPanel.RowStyles.Add(new RowStyle(sizeType2, 100f)); + } + else + { + this.leftPluginPanel.RowStyles[0].SizeType = sizeType2; + } + this._oldLeftSplitterPosition = Math.Max(this._oldLeftSplitterPosition, c.Width); + this.leftPluginPanel.Controls.Add(c, 0, this.leftPluginPanel.RowCount - 1); + break; + case PluginPosition.Right: + if (this.rightPluginPanel.Controls.Count > 0) + { + this.rightPluginPanel.RowCount++; + this.rightPluginPanel.RowStyles.Add(new RowStyle(sizeType, 4f)); + this.rightPluginPanel.RowCount++; + this.rightPluginPanel.RowStyles.Add(new RowStyle(sizeType2, 100f)); + } + else + { + this.rightPluginPanel.RowStyles[0].SizeType = sizeType2; + } + this._oldRightSplitterPosition = Math.Max(this._oldRightSplitterPosition, c.Width); + this.rightPluginPanel.Controls.Add(c, 0, this.rightPluginPanel.RowCount - 1); + break; + } + c.Margin = new Padding(0); + c.Dock = DockStyle.Fill; + c.VisibleChanged += this.plugin_VisibleChanged; + this.plugin_VisibleChanged(c, null); + } + + private void plugin_VisibleChanged(object sender, EventArgs e) + { + UserControl userControl = (UserControl)sender; + TableLayoutPanel tableLayoutPanel = (TableLayoutPanel)userControl.Parent; + int index = tableLayoutPanel.Controls.IndexOf(userControl) * 2; + bool flag = tableLayoutPanel == this.leftPluginPanel || tableLayoutPanel == this.rightPluginPanel; + if (userControl.Visible) + { + if (flag) + { + tableLayoutPanel.RowStyles[index].SizeType = SizeType.Percent; + } + else + { + tableLayoutPanel.ColumnStyles[index].SizeType = SizeType.Percent; + } + } + else if (flag) + { + tableLayoutPanel.RowStyles[index].SizeType = SizeType.AutoSize; + } + else + { + tableLayoutPanel.ColumnStyles[index].SizeType = SizeType.AutoSize; + } + for (int i = 0; i < tableLayoutPanel.ColumnStyles.Count - 1; i += 2) + { + if (tableLayoutPanel.ColumnStyles[i].SizeType == SizeType.Percent) + { + SizeType sizeType = SizeType.AutoSize; + int num = i + 2; + while (num < tableLayoutPanel.ColumnStyles.Count) + { + if (tableLayoutPanel.ColumnStyles[num].SizeType != SizeType.Percent) + { + num += 2; + continue; + } + sizeType = SizeType.Absolute; + break; + } + tableLayoutPanel.ColumnStyles[i + 1].SizeType = sizeType; + } + else + { + tableLayoutPanel.ColumnStyles[i + 1].SizeType = SizeType.AutoSize; + } + } + for (int j = 0; j < tableLayoutPanel.RowStyles.Count - 1; j += 2) + { + if (tableLayoutPanel.RowStyles[j].SizeType == SizeType.Percent) + { + SizeType sizeType2 = SizeType.AutoSize; + int num2 = j + 2; + while (num2 < tableLayoutPanel.RowStyles.Count) + { + if (tableLayoutPanel.RowStyles[num2].SizeType != SizeType.Percent) + { + num2 += 2; + continue; + } + sizeType2 = SizeType.Absolute; + break; + } + tableLayoutPanel.RowStyles[j + 1].SizeType = sizeType2; + } + else + { + tableLayoutPanel.RowStyles[j + 1].SizeType = SizeType.AutoSize; + } + } + this.UpdatePluginPanel(tableLayoutPanel); + } + + private void UpdatePluginPanel(TableLayoutPanel panel) + { + bool flag = true; + int num = 0; + while (num < panel.Controls.Count) + { + if (!((Control.ControlCollection)panel.Controls)[num].Visible) + { + num++; + continue; + } + flag = false; + break; + } + if (panel == this.topPluginPanel) + { + if (flag) + { + this.topSplitter.Visible = false; + this.topSplitter.SplitPosition = 0; + } + else + { + this.topSplitter.Visible = true; + this.topSplitter.SplitPosition = this._oldTopSplitterPosition; + } + } + else if (panel == this.bottomPluginPanel) + { + if (flag) + { + this.bottomSplitter.Visible = false; + this.bottomSplitter.SplitPosition = 0; + } + else + { + this.bottomSplitter.Visible = true; + this.bottomSplitter.SplitPosition = this._oldBottomSplitterPosition; + } + } + else if (panel == this.leftPluginPanel) + { + if (flag) + { + this.leftSplitter.Visible = false; + this.leftSplitter.SplitPosition = 0; + } + else + { + this.leftSplitter.Visible = true; + this.leftSplitter.SplitPosition = this._oldLeftSplitterPosition; + } + } + else if (panel == this.rightPluginPanel) + { + if (flag) + { + this.rightSplitter.Visible = false; + this.rightSplitter.SplitPosition = 0; + } + else + { + this.rightSplitter.Visible = true; + this.rightSplitter.SplitPosition = this._oldRightSplitterPosition; + } + } + } + + private void pluginSplitter_SplitterMoved(object sender, SplitterEventArgs e) + { + if (this.topSplitter.Visible) + { + this._oldTopSplitterPosition = this.topSplitter.SplitPosition; + } + if (this.bottomSplitter.Visible) + { + this._oldBottomSplitterPosition = this.bottomSplitter.SplitPosition; + } + if (this.leftSplitter.Visible) + { + this._oldLeftSplitterPosition = this.leftSplitter.SplitPosition; + } + if (this.rightSplitter.Visible) + { + this._oldRightSplitterPosition = this.rightSplitter.SplitPosition; + } + } + + private void ConnectSource() + { + if (this.SourceIsFrontEnd && this._frontendController is IConnectableSource) + { + IConnectableSource connectableSource = this._frontendController as IConnectableSource; + if (!connectableSource.Connected) + { + connectableSource.Connect(); + } + } + } + + public void StartRadio() + { + this.playStopButton.Image = Resources.sdr_stop; + this._tooltip.SetToolTip(this.playStopButton, "Stop"); + try + { + this.ConnectSource(); + this.Open(false); + this._streamControl.Play(); + } + catch + { + this.ConnectSource(); + this.Open(true); + this._streamControl.Play(); + } + this._fftStream.Open(); + if (!this.UseFFTSource) + { + ThreadPool.QueueUserWorkItem(this.ProcessFFT); + } + this.sampleRateComboBox.Enabled = false; + this.inputDeviceComboBox.Enabled = false; + this.outputDeviceComboBox.Enabled = false; + this.latencyNumericUpDown.Enabled = false; + this.NotifyPropertyChanged("StartRadio"); + } + + public void StopRadio() + { + this.playStopButton.Image = Resources.sdr_start; + this._tooltip.SetToolTip(this.playStopButton, "Start"); + this._streamControl.Stop(); + this._iqBalancerProcessor.Engine.Reset(); + this._fftStream.Close(); + if (!this.SourceIsWaveFile) + { + this.inputDeviceComboBox.Enabled = (this._frontendController == null || this._frontendController is ISoundcardController); + this.sampleRateComboBox.Enabled = (this._frontendController == null || this._frontendController is ISoundcardController); + } + this.outputDeviceComboBox.Enabled = true; + this.latencyNumericUpDown.Enabled = true; + this._fftEvent.Set(); + while (this._fftIsRunning) + { + } + this.NotifyPropertyChanged("StopRadio"); + GC.Collect(); + } + + public unsafe void GetSpectrumSnapshot(byte[] destArray) + { + this._fftResolutionLock.AcquireReaderLock(300000); + float[] array = new float[destArray.Length]; + fixed (byte* dest = destArray) + { + float[] array2 = array; + fixed (float* ptr = array2) + { + Fourier.SmoothMaxCopy(this._fftDisplayPtr, ptr, this._fftDisplaySize, array.Length, 1f, 0f); + Fourier.ScaleFFT(ptr, dest, array.Length, -130f, 0f); + } + } + this._fftResolutionLock.ReleaseReaderLock(); + } + + public unsafe void GetSpectrumSnapshot(float[] destArray, float scale = 1f, float offset = 0f) + { + this._fftResolutionLock.AcquireReaderLock(300000); + fixed (float* dstPtr = destArray) + { + Fourier.SmoothMaxCopy(this._fftDisplayPtr, dstPtr, this._fftDisplaySize, destArray.Length, scale, offset); + } + this._fftResolutionLock.ReleaseReaderLock(); + } + + public void RegisterStreamHook(object streamHook, ProcessorType processorType) + { + this._hookManager.RegisterStreamHook(streamHook, processorType); + } + + public void UnregisterStreamHook(object streamHook) + { + this._hookManager.UnregisterStreamHook(streamHook); + } + + private void NotifyPropertyChanged(string property) + { + PropertyChangedEventHandler propertyChanged = this.PropertyChanged; + if (propertyChanged != null) + { + this.PropertyChanged(this, new PropertyChangedEventArgs(property)); + } + } + + private void waterfall_CustomPaint(object sender, CustomPaintEventArgs e) + { + CustomPaintEventHandler waterfallCustomPaint = this.WaterfallCustomPaint; + if (waterfallCustomPaint != null) + { + waterfallCustomPaint(sender, e); + } + } + + private void spectrumAnalyzer_CustomPaint(object sender, CustomPaintEventArgs e) + { + CustomPaintEventHandler spectrumAnalyzerCustomPaint = this.SpectrumAnalyzerCustomPaint; + if (spectrumAnalyzerCustomPaint != null) + { + spectrumAnalyzerCustomPaint(sender, e); + } + } + + private void spectrumAnalyzer_BackgroundCustomPaint(object sender, CustomPaintEventArgs e) + { + CustomPaintEventHandler spectrumAnalyzerBackgroundCustomPaint = this.SpectrumAnalyzerBackgroundCustomPaint; + if (spectrumAnalyzerBackgroundCustomPaint != null) + { + spectrumAnalyzerBackgroundCustomPaint(sender, e); + } + } + + public void Perform() + { + this.spectrumAnalyzer.Perform(); + this.waterfall.Perform(); + } + + private void logoPictureBox_Click(object sender, EventArgs e) + { + Process.Start("http://airspy.com"); + } + } +} diff --git a/SDRSharp/SDRSharp/MainForm.resource b/SDRSharp/SDRSharp/MainForm.resource new file mode 100644 index 0000000..4b38d0b --- /dev/null +++ b/SDRSharp/SDRSharp/MainForm.resource @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + rGyUeAVvAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/SDRSharp/SDRSharp/MainForm.resx b/SDRSharp/SDRSharp/MainForm.resx new file mode 100644 index 0000000..4b38d0b --- /dev/null +++ b/SDRSharp/SDRSharp/MainForm.resx @@ -0,0 +1,283 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + rGyUeAVvAAAAAElFTkSuQmCC + + + \ No newline at end of file diff --git a/SDRSharp/SDRSharp/Program.cs b/SDRSharp/SDRSharp/Program.cs new file mode 100644 index 0000000..7bea792 --- /dev/null +++ b/SDRSharp/SDRSharp/Program.cs @@ -0,0 +1,48 @@ +using SDRSharp.Radio; +using System; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Windows.Forms; + +namespace SDRSharp +{ + public static class Program + { + [STAThread] + private static void Main() + { + AppDomain.CurrentDomain.UnhandledException += Program.CurrentDomain_UnhandledException; + if (Environment.OSVersion.Platform == PlatformID.Win32Windows || Environment.OSVersion.Platform == PlatformID.Win32NT) + { + Process currentProcess = Process.GetCurrentProcess(); + currentProcess.PriorityBoostEnabled = true; + currentProcess.PriorityClass = (ProcessPriorityClass)Utils.GetIntSetting("processPriority", 256); + Utils.TimeBeginPeriod(1u); + } + DSPThreadPool.Initialize(); + Control.CheckForIllegalCrossThreadCalls = false; + Application.EnableVisualStyles(); + Application.Run(new MainForm()); + if (Environment.OSVersion.Platform == PlatformID.Win32Windows || Environment.OSVersion.Platform == PlatformID.Win32NT) + { + Utils.TimeEndPeriod(1u); + } + DSPThreadPool.Terminate(); + Application.Exit(); + } + + private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + Exception ex = (Exception)e.ExceptionObject; + StackTrace stackTrace = new StackTrace(ex); + StringBuilder stringBuilder = new StringBuilder(); + StackFrame[] frames = stackTrace.GetFrames(); + foreach (StackFrame stackFrame in frames) + { + stringBuilder.AppendLine("at " + stackFrame.GetMethod().Module.Name + "." + stackFrame.GetMethod().ReflectedType.Name + "." + stackFrame.GetMethod().Name + " (IL offset: 0x" + stackFrame.GetILOffset().ToString("x") + ")"); + } + File.WriteAllText("crash.txt", ex.Message + Environment.NewLine + stringBuilder); + } + } +} diff --git a/SDRSharp/SDRSharp/SDRSharp.ico b/SDRSharp/SDRSharp/SDRSharp.ico new file mode 100644 index 0000000000000000000000000000000000000000..6033e987080eb51028719af91d43b697e4d0aae3 GIT binary patch literal 24838 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 + + + + + + + + + + + \ No newline at end of file diff --git a/SDRSharp/refs Panel Common FreqEdit PanView Radio & airspy.dll airspyhf.dll .txt b/SDRSharp/refs Panel Common FreqEdit PanView Radio & airspy.dll airspyhf.dll .txt new file mode 100644 index 0000000..e69de29 diff --git a/SDRSharp/ver 1.0.0.1632.txt b/SDRSharp/ver 1.0.0.1632.txt new file mode 100644 index 0000000..e69de29