From 493faa7cd6e35525a78a1bc495ce028f63ca7a76 Mon Sep 17 00:00:00 2001 From: attila Date: Thu, 25 Apr 2024 12:38:01 +0200 Subject: [PATCH 01/19] AU Client: Suppress EnumCastOutOfRange Clang Analyzer warning --- .../native/juce_CoreAudioLayouts_mac.h | 11 +++++++++++ .../juce_audio_plugin_client_AU_1.mm | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/modules/juce_audio_basics/native/juce_CoreAudioLayouts_mac.h b/modules/juce_audio_basics/native/juce_CoreAudioLayouts_mac.h index 44ebd4d93c09..1375a0b1ef9c 100644 --- a/modules/juce_audio_basics/native/juce_CoreAudioLayouts_mac.h +++ b/modules/juce_audio_basics/native/juce_CoreAudioLayouts_mac.h @@ -106,7 +106,12 @@ struct CoreAudioLayouts List { kAudioChannelLayoutTag_MPEG_5_1_D, { centre, left, right, leftSurround, rightSurround, LFE } }, List { kAudioChannelLayoutTag_MPEG_7_1_B, { centre, leftCentre, rightCentre, left, right, leftSurround, rightSurround, LFE } }, List { kAudioChannelLayoutTag_Emagic_Default_7_1, { left, right, leftSurround, rightSurround, centre, LFE, leftCentre, rightCentre } }, + + // Suppressing clang-analyzer-optin.core.EnumCastOutOfRange + #ifndef __clang_analyzer__ List { kAudioChannelLayoutTag_SMPTE_DTV, { left, right, centre, LFE, leftSurround, rightSurround, discreteChannel0 /* leftMatrixTotal */, (ChannelType) (discreteChannel0 + 1) /* rightMatrixTotal */} }, + #endif + List { kAudioChannelLayoutTag_ITU_2_2, { left, right, leftSurround, rightSurround } }, List { kAudioChannelLayoutTag_DVD_4, { left, right, LFE } }, List { kAudioChannelLayoutTag_DVD_5, { left, right, LFE, centreSurround } }, @@ -227,10 +232,13 @@ struct CoreAudioLayouts for (UInt32 i = 0; i < layout.mNumberChannelDescriptions; ++i) channels.addIfNotAlreadyThere (getChannelTypeFromAudioChannelLabel (layout.mChannelDescriptions[i].mChannelLabel)); + // Suppressing clang-analyzer-optin.core.EnumCastOutOfRange + #ifndef __clang_analyzer__ // different speaker mappings may point to the same JUCE speaker so fill up // this array with discrete channels for (int j = 0; channels.size() < static_cast (layout.mNumberChannelDescriptions); ++j) channels.addIfNotAlreadyThere (static_cast (AudioChannelSet::discreteChannel0 + j)); + #endif return channels; } @@ -273,8 +281,11 @@ struct CoreAudioLayouts return AudioChannelSet::ambisonic (ambisonicOrder).getChannelTypes(); } + // Suppressing clang-analyzer-optin.core.EnumCastOutOfRange + #ifndef __clang_analyzer__ for (UInt32 i = 0; i < numChannels; ++i) speakers.add (static_cast (AudioChannelSet::discreteChannel0 + i)); + #endif return speakers; } diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm index c1ed41aa97c9..10aa30b6a5df 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm @@ -869,9 +869,14 @@ bool busIgnoresLayout ([[maybe_unused]] bool isInput, [[maybe_unused]] int busNr if (const AudioProcessor::Bus* bus = juceFilter->getBus (isInput, busNr)) { AudioChannelSet discreteRangeSet; + + // Suppressing clang-analyzer-optin.core.EnumCastOutOfRange + #ifndef __clang_analyzer__ const int n = bus->getDefaultLayout().size(); + for (int i = 0; i < n; ++i) discreteRangeSet.addChannel ((AudioChannelSet::ChannelType) (256 + i)); + #endif // if the audioprocessor supports this it cannot // really be interested in the bus layouts From f46c72e854b5ad52f1959430a55142a2fb9c6ab1 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 25 Apr 2024 11:35:39 +0100 Subject: [PATCH 02/19] VBlank: Avoid hogging the message queue with repaint messages when repaints take longer than a vblank period --- .../native/juce_Windowing_windows.cpp | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp index f898fa3c2060..2979dcb963e4 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp @@ -1442,8 +1442,16 @@ class VSyncThread final : private Thread, ~VSyncThread() override { - stopThread (-1); cancelPendingUpdate(); + + { + const std::scoped_lock lock { mutex }; + threadState = ThreadState::exit; + } + + condvar.notify_one(); + + stopThread (-1); } void updateMonitor() @@ -1489,12 +1497,23 @@ class VSyncThread final : private Thread, //============================================================================== void run() override { - while (! threadShouldExit()) + for (;;) { if (output->WaitForVBlank() == S_OK) + { + std::unique_lock lock { mutex }; + condvar.wait (lock, [this] { return threadState != ThreadState::sleep; }); + + if (threadState == ThreadState::exit) + return; + + threadState = ThreadState::sleep; triggerAsyncUpdate(); + } else + { Thread::sleep (1); + } } } @@ -1502,6 +1521,15 @@ class VSyncThread final : private Thread, { for (auto& listener : listeners) listener.get().onVBlank(); + + { + const std::scoped_lock lock { mutex }; + + if (threadState == ThreadState::sleep) + threadState = ThreadState::paint; + } + + condvar.notify_one(); } //============================================================================== @@ -1509,6 +1537,17 @@ class VSyncThread final : private Thread, HMONITOR monitor = nullptr; std::vector> listeners; + enum class ThreadState + { + sleep, + paint, + exit, + }; + + ThreadState threadState = ThreadState::paint; + std::condition_variable condvar; + std::mutex mutex; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VSyncThread) JUCE_DECLARE_NON_MOVEABLE (VSyncThread) }; From 0422d42f7daee583d20f0a96ceb6f09b699a0674 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 25 Apr 2024 11:39:26 +0100 Subject: [PATCH 03/19] VBlankDispatcher: Ensure the result of CreateDXGIFactory is non-null before use --- modules/juce_gui_basics/native/juce_Windowing_windows.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp index 2979dcb963e4..a4bc47ea5c77 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp @@ -1629,9 +1629,15 @@ class VBlankDispatcher final : public DeletedAtShutdown ComSmartPtr factory; JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wlanguage-extension-token") - CreateDXGIFactory (__uuidof (IDXGIFactory), (void**)factory.resetAndGetPointerAddress()); + CreateDXGIFactory (__uuidof (IDXGIFactory), (void**) factory.resetAndGetPointerAddress()); JUCE_END_IGNORE_WARNINGS_GCC_LIKE + if (factory == nullptr) + { + jassertfalse; + return; + } + UINT i = 0; ComSmartPtr adapter; From eac95d5905cf714176977fe7e9a7ac265946b2f2 Mon Sep 17 00:00:00 2001 From: Anthony Nicholls Date: Fri, 26 Apr 2024 17:15:22 +0100 Subject: [PATCH 04/19] AudioDeviceSelector: Fix a bug with the input and output device selectors The bug presented when selecting none for either input or output, when the opposite input or output was a device that had the same name for both the input and output --- .../gui/juce_AudioDeviceSelectorComponent.cpp | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp index 6d964bb0ef16..473e609cd6fd 100644 --- a/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_AudioDeviceSelectorComponent.cpp @@ -430,9 +430,8 @@ class AudioDeviceSettingsPanel : public Component, error = setup.manager->setAudioDeviceSetup (config, true); - showCorrectDeviceName (inputDeviceDropDown.get(), true); - showCorrectDeviceName (outputDeviceDropDown.get(), false); - + updateSelectedInput(); + updateSelectedOutput(); updateControlPanelButton(); resized(); } @@ -601,18 +600,34 @@ class AudioDeviceSettingsPanel : public Component, std::unique_ptr inputLevelMeter; std::unique_ptr showUIButton, showAdvancedSettingsButton, resetDeviceButton; - void showCorrectDeviceName (ComboBox* box, bool isInput) + int findSelectedDeviceIndex (bool isInput) const { - if (box != nullptr) - { - auto* currentDevice = setup.manager->getCurrentAudioDevice(); - auto index = type.getIndexOfDevice (currentDevice, isInput); + const auto device = setup.manager->getAudioDeviceSetup(); + const auto deviceName = isInput ? device.inputDeviceName : device.outputDeviceName; + return type.getDeviceNames (isInput).indexOf (deviceName); + } - box->setSelectedId (index < 0 ? index : index + 1, dontSendNotification); + void updateSelectedInput() + { + showCorrectDeviceName (inputDeviceDropDown.get(), true); + } - if (testButton != nullptr && ! isInput) - testButton->setEnabled (index >= 0); - } + void updateSelectedOutput() + { + constexpr auto isInput = false; + showCorrectDeviceName (outputDeviceDropDown.get(), isInput); + + if (testButton != nullptr) + testButton->setEnabled (findSelectedDeviceIndex (isInput) >= 0); + } + + void showCorrectDeviceName (ComboBox* box, bool isInput) + { + if (box == nullptr) + return; + + const auto index = findSelectedDeviceIndex (isInput); + box->setSelectedId (index < 0 ? index : index + 1, dontSendNotification); } void addNamesToDeviceBox (ComboBox& combo, bool isInputs) @@ -702,7 +717,7 @@ class AudioDeviceSettingsPanel : public Component, addNamesToDeviceBox (*outputDeviceDropDown, false); } - showCorrectDeviceName (outputDeviceDropDown.get(), false); + updateSelectedOutput(); } void updateInputsComboBox() @@ -725,7 +740,7 @@ class AudioDeviceSettingsPanel : public Component, addNamesToDeviceBox (*inputDeviceDropDown, true); } - showCorrectDeviceName (inputDeviceDropDown.get(), true); + updateSelectedInput(); } void updateSampleRateComboBox (AudioIODevice* currentDevice) From da0c137336b8711cdbb0a034e9278f475f39f7fa Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 7 May 2024 14:29:25 +0100 Subject: [PATCH 05/19] CoreAudioIODevice: Make stopAndGetLastCallback() private --- .../native/juce_CoreAudio_mac.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp index 01992c07f4f4..9b190abedea5 100644 --- a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp +++ b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp @@ -1323,16 +1323,6 @@ class CoreAudioIODevice final : public AudioIODevice, stopAndGetLastCallback(); } - AudioIODeviceCallback* stopAndGetLastCallback() const - { - auto* lastCallback = internal->stop (true); - - if (lastCallback != nullptr) - lastCallback->audioDeviceStopped(); - - return lastCallback; - } - AudioIODeviceCallback* stopInternal() { restartDevice = true; @@ -1401,6 +1391,16 @@ class CoreAudioIODevice final : public AudioIODevice, BigInteger inputChannelsRequested, outputChannelsRequested; CriticalSection closeLock; + AudioIODeviceCallback* stopAndGetLastCallback() const + { + auto* lastCallback = internal->stop (true); + + if (lastCallback != nullptr) + lastCallback->audioDeviceStopped(); + + return lastCallback; + } + void timerCallback() override { stopTimer(); From 5b98bfdc0fbe6bee2804c6b7f748c9782870bcc3 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 7 May 2024 14:47:34 +0100 Subject: [PATCH 06/19] CoreAudio: Allow non-combined devices to restart successfully --- .../native/juce_CoreAudio_mac.cpp | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp index 9b190abedea5..3938bd197d20 100644 --- a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp +++ b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp @@ -1112,8 +1112,8 @@ class CoreAudioInternal final : private Timer, auto oldBufferSize = bufferSize; if (! updateDetailsFromDevice()) - owner.stopInternal(); - else if ((oldBufferSize != bufferSize || ! approximatelyEqual (oldSampleRate, sampleRate)) && owner.shouldRestartDevice()) + owner.stopWithPendingCallback(); + else if (oldBufferSize != bufferSize || ! approximatelyEqual (oldSampleRate, sampleRate)) owner.restart(); } @@ -1314,19 +1314,21 @@ class CoreAudioIODevice final : public AudioIODevice, void start (AudioIODeviceCallback* callback) override { if (internal->start (callback)) - previousCallback = callback; + pendingCallback = nullptr; } void stop() override { - restartDevice = false; stopAndGetLastCallback(); + pendingCallback = nullptr; } - AudioIODeviceCallback* stopInternal() + void stopWithPendingCallback() { - restartDevice = true; - return stopAndGetLastCallback(); + const ScopedLock sl (closeLock); + + if (pendingCallback == nullptr) + pendingCallback = stopAndGetLastCallback(); } AudioWorkgroup getWorkgroup() const override @@ -1359,11 +1361,7 @@ class CoreAudioIODevice final : public AudioIODevice, return; } - { - const ScopedLock sl (closeLock); - previousCallback = stopInternal(); - } - + stopWithPendingCallback(); startTimer (100); } @@ -1377,16 +1375,16 @@ class CoreAudioIODevice final : public AudioIODevice, restarter = restarterIn; } - bool shouldRestartDevice() const noexcept { return restartDevice; } - WeakReference deviceType; bool hadDiscontinuity; private: std::unique_ptr internal; - bool isOpen_ = false, restartDevice = true; + bool isOpen_ = false; String lastError; - AudioIODeviceCallback* previousCallback = nullptr; + // When non-null, this indicates that the device has been stopped with the intent to restart + // using the same callback. That is, this should only be non-null when the device is stopped. + AudioIODeviceCallback* pendingCallback = nullptr; AsyncRestarter* restarter = nullptr; BigInteger inputChannelsRequested, outputChannelsRequested; CriticalSection closeLock; @@ -1405,13 +1403,16 @@ class CoreAudioIODevice final : public AudioIODevice, { stopTimer(); - stopInternal(); + stopWithPendingCallback(); internal->updateDetailsFromDevice(); - open (inputChannelsRequested, outputChannelsRequested, - getCurrentSampleRate(), getCurrentBufferSizeSamples()); - start (previousCallback); + open (inputChannelsRequested, + outputChannelsRequested, + getCurrentSampleRate(), + getCurrentBufferSizeSamples()); + + start (pendingCallback); } static OSStatus hardwareListenerProc (AudioDeviceID /*inDevice*/, @@ -1724,7 +1725,7 @@ class AudioIODeviceCombiner final : public AudioIODevice, } for (auto& d : getDeviceWrappers()) - d->stopInternal(); + d->stop(); if (lastCallback != nullptr) { @@ -1990,7 +1991,7 @@ class AudioIODeviceCombiner final : public AudioIODevice, int getCurrentBitDepth() const { return device->getCurrentBitDepth(); } int getDefaultBufferSize() const { return device->getDefaultBufferSize(); } void start (AudioIODeviceCallback* callbackToNotify) const { return device->start (callbackToNotify); } - AudioIODeviceCallback* stopInternal() const { return device->stopInternal(); } + void stop() const { return device->stop(); } void close() const { return device->close(); } AudioWorkgroup getWorkgroup() const { return device->getWorkgroup(); } From bbc63ba151265d9199b5d1cfd3f70fb24442563f Mon Sep 17 00:00:00 2001 From: Anthony Nicholls Date: Wed, 8 May 2024 13:38:45 +0100 Subject: [PATCH 07/19] Timer: Ensure the timer thread is deleted before any static or global destructors run In cases where there was a static or global instance of a class that inherited from Timer, due to the order of events when a dll is unloaded on windows, there was a risk of an infinite hang. Deleting the timer thread before the dll is unloaded avoids this occurring. --- modules/juce_events/timers/juce_Timer.cpp | 43 ++++++++++++++--------- modules/juce_events/timers/juce_Timer.h | 1 - 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/modules/juce_events/timers/juce_Timer.cpp b/modules/juce_events/timers/juce_Timer.cpp index 10430f91f758..62cfa2ec8606 100644 --- a/modules/juce_events/timers/juce_Timer.cpp +++ b/modules/juce_events/timers/juce_Timer.cpp @@ -23,21 +23,20 @@ namespace juce { -class Timer::TimerThread final : private Thread +class Timer::TimerThread final : private Thread, + private DeletedAtShutdown { public: - using LockType = CriticalSection; // (mysteriously, using a SpinLock here causes problems on some XP machines..) + using LockType = CriticalSection; - TimerThread() : Thread ("JUCE Timer") - { - timers.reserve (32); - } + JUCE_DECLARE_SINGLETON (TimerThread, true) ~TimerThread() override { signalThreadShouldExit(); callbackArrived.signal(); stopThread (-1); + clearSingletonInstance(); } void run() override @@ -204,8 +203,8 @@ class Timer::TimerThread final : private Thread void messageCallback() override { - if (auto instance = SharedResourcePointer::getSharedObjectWithoutCreating()) - (*instance)->callTimers(); + if (auto* instance = TimerThread::getInstanceWithoutCreating()) + instance->callTimers(); } }; @@ -273,9 +272,14 @@ class Timer::TimerThread final : private Thread return timers.front().countdownMs; } + //============================================================================== + TimerThread() : Thread ("JUCE Timer") { timers.reserve (32); } + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimerThread) }; +JUCE_IMPLEMENT_SINGLETON (Timer::TimerThread) + //============================================================================== Timer::Timer() noexcept {} Timer::Timer (const Timer&) noexcept {} @@ -299,13 +303,16 @@ void Timer::startTimer (int interval) noexcept // running, then you're not going to get any timer callbacks! JUCE_ASSERT_MESSAGE_MANAGER_EXISTS - bool wasStopped = (timerPeriodMs == 0); - timerPeriodMs = jmax (1, interval); + if (auto* instance = TimerThread::getInstance()) + { + bool wasStopped = (timerPeriodMs == 0); + timerPeriodMs = jmax (1, interval); - if (wasStopped) - timerThread->addTimer (this); - else - timerThread->resetTimerCounter (this); + if (wasStopped) + instance->addTimer (this); + else + instance->resetTimerCounter (this); + } } void Timer::startTimerHz (int timerFrequencyHz) noexcept @@ -320,15 +327,17 @@ void Timer::stopTimer() noexcept { if (timerPeriodMs > 0) { - timerThread->removeTimer (this); + if (auto* instance = TimerThread::getInstanceWithoutCreating()) + instance->removeTimer (this); + timerPeriodMs = 0; } } void JUCE_CALLTYPE Timer::callPendingTimersSynchronously() { - if (auto instance = SharedResourcePointer::getSharedObjectWithoutCreating()) - (*instance)->callTimersSynchronously(); + if (auto* instance = TimerThread::getInstanceWithoutCreating()) + instance->callTimersSynchronously(); } struct LambdaInvoker final : private Timer, diff --git a/modules/juce_events/timers/juce_Timer.h b/modules/juce_events/timers/juce_Timer.h index 24761624d9f9..7c3962cb0446 100644 --- a/modules/juce_events/timers/juce_Timer.h +++ b/modules/juce_events/timers/juce_Timer.h @@ -129,7 +129,6 @@ class JUCE_API Timer class TimerThread; size_t positionInQueue = (size_t) -1; int timerPeriodMs = 0; - SharedResourcePointer timerThread; Timer& operator= (const Timer&) = delete; }; From 590795d3b5ca69d7b14cf8165cf348c86ac95460 Mon Sep 17 00:00:00 2001 From: Anthony Nicholls Date: Mon, 20 May 2024 15:31:31 +0100 Subject: [PATCH 08/19] Timer: Stop the timer thread on shutdown to prevent a potential hang on windows This commit reverts the previous commit as it introduced a regression. On windows when exit is called on a dll it forcibly kills any threads still running before destroying any static objects. This means if a Timer object is static the timer thread will be killed. Later when the static object is destroyed it will wait for the thread to exit, which because the OS forcibly killed it will never come true. --- modules/juce_events/timers/juce_Timer.cpp | 101 +++++++++++++++++----- modules/juce_events/timers/juce_Timer.h | 1 + 2 files changed, 78 insertions(+), 24 deletions(-) diff --git a/modules/juce_events/timers/juce_Timer.cpp b/modules/juce_events/timers/juce_Timer.cpp index 62cfa2ec8606..88c3540d3508 100644 --- a/modules/juce_events/timers/juce_Timer.cpp +++ b/modules/juce_events/timers/juce_Timer.cpp @@ -23,20 +23,70 @@ namespace juce { +class ShutdownDetector : private DeletedAtShutdown +{ +public: + ShutdownDetector() = default; + + ~ShutdownDetector() override + { + getListeners().call (&Listener::applicationShuttingDown); + } + + struct Listener + { + virtual ~Listener() = default; + virtual void applicationShuttingDown() = 0; + }; + + static void addListener (Listener* listenerToAdd) + { + // Only try to create an instance of the ShutdownDetector when a listener is added + [[maybe_unused]] auto* instance = getInstance(); + getListeners().add (listenerToAdd); + } + + static void removeListener (Listener* listenerToRemove) + { + getListeners().remove (listenerToRemove); + } + +private: + using ListenerListType = ListenerList>; + + // By having a static ListenerList it can outlive the ShutdownDetector instance preventing + // issues for objects trying to remove themselves after the instance has been deleted + static ListenerListType& getListeners() + { + static ListenerListType listeners; + return listeners; + } + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ShutdownDetector) + JUCE_DECLARE_NON_MOVEABLE (ShutdownDetector) + JUCE_DECLARE_SINGLETON (ShutdownDetector, false) +}; + +JUCE_IMPLEMENT_SINGLETON (ShutdownDetector) + class Timer::TimerThread final : private Thread, - private DeletedAtShutdown + private ShutdownDetector::Listener { public: using LockType = CriticalSection; - JUCE_DECLARE_SINGLETON (TimerThread, true) + TimerThread() + : Thread ("JUCE Timer") + { + timers.reserve (32); + ShutdownDetector::addListener (this); + } ~TimerThread() override { - signalThreadShouldExit(); - callbackArrived.signal(); + stopThreadAsync(); + ShutdownDetector::removeListener (this); stopThread (-1); - clearSingletonInstance(); } void run() override @@ -203,8 +253,8 @@ class Timer::TimerThread final : private Thread, void messageCallback() override { - if (auto* instance = TimerThread::getInstanceWithoutCreating()) - instance->callTimers(); + if (auto instance = SharedResourcePointer::getSharedObjectWithoutCreating()) + (*instance)->callTimers(); } }; @@ -273,13 +323,21 @@ class Timer::TimerThread final : private Thread, } //============================================================================== - TimerThread() : Thread ("JUCE Timer") { timers.reserve (32); } + void applicationShuttingDown() final + { + stopThreadAsync(); + } + + void stopThreadAsync() + { + signalThreadShouldExit(); + callbackArrived.signal(); + } + //============================================================================== JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TimerThread) }; -JUCE_IMPLEMENT_SINGLETON (Timer::TimerThread) - //============================================================================== Timer::Timer() noexcept {} Timer::Timer (const Timer&) noexcept {} @@ -303,16 +361,13 @@ void Timer::startTimer (int interval) noexcept // running, then you're not going to get any timer callbacks! JUCE_ASSERT_MESSAGE_MANAGER_EXISTS - if (auto* instance = TimerThread::getInstance()) - { - bool wasStopped = (timerPeriodMs == 0); - timerPeriodMs = jmax (1, interval); + bool wasStopped = (timerPeriodMs == 0); + timerPeriodMs = jmax (1, interval); - if (wasStopped) - instance->addTimer (this); - else - instance->resetTimerCounter (this); - } + if (wasStopped) + timerThread->addTimer (this); + else + timerThread->resetTimerCounter (this); } void Timer::startTimerHz (int timerFrequencyHz) noexcept @@ -327,17 +382,15 @@ void Timer::stopTimer() noexcept { if (timerPeriodMs > 0) { - if (auto* instance = TimerThread::getInstanceWithoutCreating()) - instance->removeTimer (this); - + timerThread->removeTimer (this); timerPeriodMs = 0; } } void JUCE_CALLTYPE Timer::callPendingTimersSynchronously() { - if (auto* instance = TimerThread::getInstanceWithoutCreating()) - instance->callTimersSynchronously(); + if (auto instance = SharedResourcePointer::getSharedObjectWithoutCreating()) + (*instance)->callTimersSynchronously(); } struct LambdaInvoker final : private Timer, diff --git a/modules/juce_events/timers/juce_Timer.h b/modules/juce_events/timers/juce_Timer.h index 7c3962cb0446..24761624d9f9 100644 --- a/modules/juce_events/timers/juce_Timer.h +++ b/modules/juce_events/timers/juce_Timer.h @@ -129,6 +129,7 @@ class JUCE_API Timer class TimerThread; size_t positionInQueue = (size_t) -1; int timerPeriodMs = 0; + SharedResourcePointer timerThread; Timer& operator= (const Timer&) = delete; }; From 69ddb29d739183f73dadf2d257953891092fd68d Mon Sep 17 00:00:00 2001 From: Anthony Nicholls Date: Thu, 23 May 2024 10:30:12 +0100 Subject: [PATCH 09/19] Timer: Prevent assertion from the Shutdown detector --- modules/juce_events/timers/juce_Timer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/juce_events/timers/juce_Timer.cpp b/modules/juce_events/timers/juce_Timer.cpp index 88c3540d3508..482256707a00 100644 --- a/modules/juce_events/timers/juce_Timer.cpp +++ b/modules/juce_events/timers/juce_Timer.cpp @@ -31,6 +31,7 @@ class ShutdownDetector : private DeletedAtShutdown ~ShutdownDetector() override { getListeners().call (&Listener::applicationShuttingDown); + clearSingletonInstance(); } struct Listener From eafbfee336a82318be43d199a5059c53acc9aa7b Mon Sep 17 00:00:00 2001 From: Anthony Nicholls Date: Thu, 23 May 2024 11:38:27 +0100 Subject: [PATCH 10/19] Timer: Add a leak detector --- modules/juce_events/timers/juce_Timer.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/juce_events/timers/juce_Timer.h b/modules/juce_events/timers/juce_Timer.h index 24761624d9f9..787f623797a1 100644 --- a/modules/juce_events/timers/juce_Timer.h +++ b/modules/juce_events/timers/juce_Timer.h @@ -132,6 +132,8 @@ class JUCE_API Timer SharedResourcePointer timerThread; Timer& operator= (const Timer&) = delete; + + JUCE_LEAK_DETECTOR (Timer) }; } // namespace juce From a87126227fc37f63036d0bc1668fb68cf480a080 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 30 May 2024 11:48:41 +0100 Subject: [PATCH 11/19] VST3: Update SDK to 3.7.11 --- .../juce_audio_plugin_client_VST3.cpp | 4 + .../format_types/VST3_SDK/LICENSE.txt | 2 +- .../format_types/VST3_SDK/README.md | 24 +- .../VST3_SDK/VST3_License_Agreement.pdf | Bin 135822 -> 196498 bytes .../format_types/VST3_SDK/base/LICENSE.txt | 2 +- .../VST3_SDK/base/source/baseiids.cpp | 2 +- .../base/source/classfactoryhelpers.h | 2 +- .../VST3_SDK/base/source/fbuffer.cpp | 2 +- .../VST3_SDK/base/source/fbuffer.h | 2 +- .../VST3_SDK/base/source/fcommandline.h | 580 +++++++++--------- .../VST3_SDK/base/source/fdebug.cpp | 2 +- .../VST3_SDK/base/source/fdebug.h | 2 +- .../VST3_SDK/base/source/fobject.cpp | 2 +- .../VST3_SDK/base/source/fobject.h | 66 +- .../VST3_SDK/base/source/fstreamer.cpp | 6 +- .../VST3_SDK/base/source/fstreamer.h | 2 +- .../VST3_SDK/base/source/fstring.cpp | 5 +- .../VST3_SDK/base/source/fstring.h | 2 +- .../VST3_SDK/base/source/updatehandler.cpp | 7 +- .../VST3_SDK/base/source/updatehandler.h | 2 +- .../VST3_SDK/base/thread/include/flock.h | 9 +- .../VST3_SDK/base/thread/source/flock.cpp | 10 +- .../VST3_SDK/pluginterfaces/LICENSE.txt | 2 +- .../VST3_SDK/pluginterfaces/base/coreiids.cpp | 2 +- .../VST3_SDK/pluginterfaces/base/fplatform.h | 4 + .../VST3_SDK/pluginterfaces/base/fstrdefs.h | 2 +- .../VST3_SDK/pluginterfaces/base/ftypes.h | 2 +- .../pluginterfaces/base/smartpointer.h | 4 +- .../VST3_SDK/pluginterfaces/gui/iplugview.h | 6 +- .../pluginterfaces/vst/ivstaudioprocessor.h | 7 +- .../pluginterfaces/vst/ivstdataexchange.h | 221 +++++++ .../pluginterfaces/vst/ivsteditcontroller.h | 61 +- .../pluginterfaces/vst/ivstremapparamid.h | 75 +++ .../VST3_SDK/pluginterfaces/vst/vstspeaker.h | 74 ++- .../VST3_SDK/pluginterfaces/vst/vsttypes.h | 23 +- .../VST3_SDK/public.sdk/LICENSE.txt | 2 +- .../VST3_SDK/public.sdk/README.md | 1 - .../moduleinfotool/source/main.cpp | 57 +- .../public.sdk/source/common/memorystream.cpp | 2 +- .../public.sdk/source/common/memorystream.h | 2 +- .../public.sdk/source/common/pluginview.cpp | 3 +- .../public.sdk/source/common/pluginview.h | 5 +- .../public.sdk/source/common/readfile.cpp | 7 +- .../public.sdk/source/common/readfile.h | 1 - .../source/vst/hosting/hostclasses.cpp | 2 +- .../source/vst/hosting/hostclasses.h | 2 +- .../public.sdk/source/vst/hosting/module.cpp | 2 +- .../public.sdk/source/vst/hosting/module.h | 2 +- .../source/vst/hosting/module_linux.cpp | 2 +- .../source/vst/hosting/module_mac.mm | 9 +- .../source/vst/hosting/module_win32.cpp | 2 +- .../vst/hosting/pluginterfacesupport.cpp | 2 +- .../source/vst/hosting/pluginterfacesupport.h | 2 +- .../source/vst/moduleinfo/jsoncxx.h | 2 +- .../source/vst/moduleinfo/moduleinfo.h | 2 +- .../vst/moduleinfo/moduleinfocreator.cpp | 2 +- .../source/vst/moduleinfo/moduleinfocreator.h | 2 +- .../vst/moduleinfo/moduleinfoparser.cpp | 2 +- .../source/vst/moduleinfo/moduleinfoparser.h | 2 +- .../public.sdk/source/vst/utility/optional.h | 4 +- .../source/vst/utility/stringconvert.cpp | 2 +- .../source/vst/utility/stringconvert.h | 4 +- .../public.sdk/source/vst/utility/uid.h | 14 +- .../VST3_SDK/public.sdk/source/vst/vstbus.cpp | 2 +- .../VST3_SDK/public.sdk/source/vst/vstbus.h | 2 +- .../public.sdk/source/vst/vstcomponent.cpp | 2 +- .../public.sdk/source/vst/vstcomponent.h | 2 +- .../source/vst/vstcomponentbase.cpp | 2 +- .../public.sdk/source/vst/vstcomponentbase.h | 2 +- .../source/vst/vsteditcontroller.cpp | 2 +- .../public.sdk/source/vst/vsteditcontroller.h | 2 +- .../public.sdk/source/vst/vstinitiids.cpp | 13 +- .../public.sdk/source/vst/vstparameters.cpp | 4 +- .../public.sdk/source/vst/vstparameters.h | 4 +- .../public.sdk/source/vst/vstpresetfile.cpp | 2 +- .../public.sdk/source/vst/vstpresetfile.h | 2 +- 76 files changed, 925 insertions(+), 475 deletions(-) create mode 100644 modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h create mode 100644 modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp index 39dc1c50b9bf..c6976780dfef 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp @@ -1748,6 +1748,8 @@ class JuceVST3EditController final : public Vst::EditController, #endif } + ~JuceVST3Editor() override = default; // NOLINT + tresult PLUGIN_API queryInterface (const TUID targetIID, void** obj) override { const auto result = testFor (*this, targetIID, UniqueBase{}); @@ -1758,7 +1760,9 @@ class JuceVST3EditController final : public Vst::EditController, return Vst::EditorView::queryInterface (targetIID, obj); } + // NOLINTBEGIN REFCOUNT_METHODS (Vst::EditorView) + // NOLINTEND //============================================================================== tresult PLUGIN_API isPlatformTypeSupported (FIDString type) override diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/LICENSE.txt b/modules/juce_audio_processors/format_types/VST3_SDK/LICENSE.txt index 6daa072e68e6..f5df1de43803 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/LICENSE.txt +++ b/modules/juce_audio_processors/format_types/VST3_SDK/LICENSE.txt @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- This license applies only to files referencing this license, for other files of the Software Development Kit the respective embedded license text diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/README.md b/modules/juce_audio_processors/format_types/VST3_SDK/README.md index 191fe7994842..3befbc0642d9 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/README.md +++ b/modules/juce_audio_processors/format_types/VST3_SDK/README.md @@ -19,10 +19,10 @@ - VST 3 API - VST 3 Implementation Helper Classes -- AAX, AU, AUv3 and VST 2 wrappers +- AAX, AUv3 and AU Wrappers - VST 3 plug-ins Examples -The full VST 3 SDK is available [here!](https://www.steinberg.net/en/company/developers.html). It contains : +The full VST 3 SDK is available [here!](https://www.steinberg.net/en/company/developers.html). It contains: - VST 3 plug-in Test Host Application/Validator, - the **Steinberg VST 3 Plug-In SDK Licensing Agreement** that you have to sign if you want to develop or host **VST 3** plug-ins. @@ -146,25 +146,6 @@ Some more features implemented specifically for developers include: git clone --recursive https://github.com/steinbergmedia/vst3sdk.git ``` -### Adding VST2 version - -The **VST 2 SDK** is not part anymore of the **VST 3 SDK**, you have to use an older version of the SDK and copy the vst2sdk folder into the VST_SDK folder. -In order to build a VST2 version of the plug-in and a VST3 at the same time, you need to copy the VST2 folder into the VST3 folder, simply run the following commands: - -- for macOS: - -```c -cd TheFolderWhereYouDownloadTheSDK -./copy_vst2_to_vst3_sdk.sh -``` - -- for Windows: - -```c -cd TheFolderWhereYouDownloadTheSDK -copy_vst2_to_vst3_sdk.bat -``` - ### Build the examples on Windows - Create a folder for the build and move to this folder (using cd): @@ -192,6 +173,7 @@ msbuild.exe vstsdk.sln // (or alternatively for example for release) cmake --build . --config Release ``` +Note: If you have any issue with symbolic links, check [Preparation on Windows](https://steinbergmedia.github.io/vst3_dev_portal/pages/Getting+Started/Preparation+on+Windows.html) for potential solutions. ### Build the examples on macOS diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/VST3_License_Agreement.pdf b/modules/juce_audio_processors/format_types/VST3_SDK/VST3_License_Agreement.pdf index ad8c399b48ea9a2c29ff06d8457a76abe6c5fdfc..ec7da498273fddabadaec5a88e8fb1243c71196d 100644 GIT binary patch literal 196498 zcma&NWmp_d6fPK?!QC~uy9FQI-Q9w_yAAFdf@^ShcL+X^;7)?Od${x6y}NsV+-INd zUp?K`(^aRc&Uw%K_MuUglxE>zzzM z6$v$!$qV2eP+ky23m3k#%r(XPenF~&u=@5|%c$N&mcE`%LWJr)?37Z2-+#%pPzBnX zo7w#L_IAA-Ws)EF5;c6_UWBB@cozZqA!&_dB7V$*bNK7v&^dNoNkS!IyoW^uUn`;v zwa8^QeJtwp(*mA;Mi=>`o(Pvv@EZcUE9bz8>f4R2`{O2^21!9|yKBPhuaErgLcfo@ zUAC87_;+#>qDeOD_!jP0N|69C7GrGHe2W;1TwtNA9Z zh@l3lyY1#zn7VeT4EBB4ym)OR^Hr4AU5(#y(wI~w4>s`f z?0R{|=4y72*e`5RdA?&PA+?W>)U*T5VhEWkR3CN_(P~yX7wjnbxpC5^8?7$9a?b2> zTA~C#m#@{*h>E0r|MpuF50{Bi%?im;2@n*9xSS%dgHsrJDpfT`6Hl~y$MR5Z9m?rv z5Ycp_ks&QeHIQOFGBXk^3CQCOkL1@|cT{)e(T3fT3oR0lQ=~{VmefxpdB1(X>=oDZ zp)RXpAd)4jZk8>#X=u~Och&5q380^`1R(KCmM39318Ex8qS;ftWjRB*H5Bv^V^X+o zB0uaDK7{2>b#Do0_Ch65$y)JAv+j23{e?7+_>7YS1V=z{(%heWx$9B=M1!T5liQ@T z*+OJ1TID&beKZDWr%7RW5ffh5Ln}Lb1~vA5zbE*^WJhUHE^3jZjTX7bVF^Mpcpa~g z3rH@~EXbMK>)EDa7?b{}*;6)C_mga9P}I;U$E9J7DRlTOy722&!K(DozG@2olobbm zVJ`(XCLV)36Z(KvjG;NUEtz&w%HT*YLvF|?ao~mz$y2U@ey(+Jk{6vrm%y|%oZ^^5 zt{>3}nm7@3$9&I8#HnjEiLsu+pK?yBYJX8C!wW>m8750_0Cj6@U<)L>(XL!{fj_lu zGI+N59{028cnqn+hZ2VOT3WY7f%8ZH0-0?mzLLa2L0h!(L?gzdvG$554fyduTMMw! z1b0YUyD&?vwWs{%Z*1P2OjX;Pbv&aChoMr`w{^*+O<5rvhwpczv7BfQQ|$^cWMG8m z#+u5um{^Z{Ss85mjuhM4_)F&qPtIOnlt*6CoH})EyIfeAF%Cs3@M5`4?J&tnHfVSx zb9ts@mNVvHiGiF;d(4usAe~xynDzo8bObRf3h|=Hn!4jYf*z|h4jgURv9xFJV!Wz8 zLlLbmmk^Jowjd2mtEx^@#Plh*-mvfsN!(77-@UwjWfr-W7~Mb3ds{E4j^+BXk7EmFL?-J#9>T zQX{I-u~am+oG*+OZ)++6+xo_5J7`J>D5cm0iq9G=a4I=`wi8lN1EOW8SBqR>b{pF! zn|`MQ;rxF8mZ7gq6AiL6!WqS|KLP`)>OmRId1{Yb&8Hb=G*jjq7FA_WMyrH6L_COH zD9zF{HJgNsxCaC*^Y$ZumP_j=o5PA9ynCikzt&HtLhEy~lPC23)I&RmqXwaU=DF%T zfinypEd1JGr0A0o;Zw-?2bZ&_^GBPm@eMxI9&vdZoC~+t4vMOueW*s49I!)o)Nzs2dUR;ch zxf@~Yd^}9W=P&KjnZZ%wb%y1cV&_JXnPuUaVqK&eW-)yv&j42rbC#2cWqzwd{X1R) z_tg>;Himi6bMCX&Qe}6%dgUo7?GDT;pX6b-$V~2~r6)#BxKj(tHO5pmteT!Hu-Q=^2HfVN2(T^eM1RVoyO!^;;59B$a>aKG#Akn*4a0tiqZ zn8n!I1$w`kp&$i1E;Re+8h|B|`HYlWGooUzci-ivPiM2y3RMxlhSgDhP|7 zzCODSB3&*B%C=H3?&v0DU;yJ+uaFDm<>|KP?lQsR1XTVL`N)#`H!-d9?CAByp)AP0 z@-Hhn-&b>r2f~u(X3y=wpCh)If=c-e)T&$4T|ZcM-`B*f=D)*aDPp@+n});_&e^Fr;ykFl6ZC}rN+Zvi9NUAJjXYL61@{j ztUGf{kETE~&n*oNIZlhEf7NP#|Gk@h2yech?zSf-q0f;QknwqozF+_QE^1$ppRaN_ zA!1*e{``9RZ=oiSUhQ?$+R(-z>5ggswmpRxAv4kI>gL$ZSx$R`etXwCgVUo zEt$5=iC~g)O*5LprUeiU-w1l_Q&PSKj^0pM&;-krXbHW!frYQppQX9@Gza%Ey4hhD z_mWj3;gIQmFNx%d-nVAk@GIZ{5#=pKI*K}gWz=F^VdSsWJ^u^4C4Q{vDuR2@_k99O z%}XLL&0mvDKAajwf$H9en%_3=S23+2pMeqW6(A<9~oZLKo|K0wd7kU0)(5LC^V#TJbVs2+;;lZZiY3}jgZ#hRZ zYb!P#TT2KWc8{tb~x8kZVoC2TpaX#AZvf5D`!_%qxMNpCDFETE^U4DLkeawUinusYr z!jC%_n{S^~e5V;eUKfNPE5!QP1QR&@wK&M;c@Vpg6&DRH@gZuhV&uyH`hmX};<>cO+Zke==$ zwhR7yKsnz~Nc#>KEp(p87HFjZUt|1(y{2g5%iCzXu6wzl{gS44nS{CB2MnL_oTrD}ap3B`&M(G!}IT36eJ3Bkc#gr^eHG+=4sp^RR zKTI|XDKo}rk*B^H=0&%xIV2pU&iJGBlUH~%-A5B&w7Qo6H;tH+=y@I`zwkFNpZ7ck zd2px>UwtD*g^ui^@N487Ubt}}YoX-5_~r@jTkc2b0JC{Tu#O}dh&BL5yQnmt9z-LP%#ne6- z6KMg9m;N1WN&$ZUfVh$Vp5dQZmCkU_+L}2NIDyOV@g;Ur_TEq0`jFYumfl@RU`DG0 zLzZ;w;Fx>XGcWwSk4AX2P6MvD=q@ zJA1gjB2J}JK~@Xt$C;rC@(M~$!e=^I1*wdBslSCoU%9qkqQB&LUg&vpPA@l2QaCTk z<0(&(h|Dji8qartkF|@C3o%lS|JB#SIfTtvVu@T#7UMB*?${Fw*wDYYMtz}tI+brH zziTax{Ymg8Gc?(s$I|juUp?W|60LBHu;GyhahX@D$@9-;Xx_oEcBM%cILzxukf(7d zHOYr>CN^xR0$3`Mus&|c7Y!xhg%){Li7LlFiz(+Vh%^j}3Of~piFuy+3ghXW3 zjo8qykDJyk#psS>sKp-5DCrk{MHNa6ee1OlYmWl!K$a2|{vuZ&V%}!Gk7~hV6b#6u zo}d5iD0@jqc{wh?py)r}l>Gxb&~gFV_sjY_r^m|uspqn4{eDab|98%y#I95;AMw65 zi!2m7TW1hZ+dE{p=&f_zuHx@qT3_ZtxVwy6Xg%pN72cOQPvruTI0>NAQx-FQ(g3*NKqXwY@(-TK>HPe=pHO}5c`*nFJMbEW zSDrZd%&(Dlrr}!$atZrSpAGHjRI?I9oL{bWY{$(srb7R1(I*Wy!d@W-x|iBaPO@zE zl-ry?gh`z;B^7uZJ_5zX7j>C=B3B^Ww$Y9vM4D%2vpuc~Gc2Q?7w-J)kYq35=poARpm42)v%A{UJ@o^&!yR_;HK4#z}a+o!=R^CvsyUOT17wg%gL#z4;9JEcuEz`k` z{L_|IAPPBg0f=p$LZB6yx5|c9^jW)Vz9a~xwd^gzD}{x%7=+wR&sNb zVntVWH!EdED|d^;U0!g8{9d`j$CZKm_ndXvg>qMk?z^g(=tW*+*wIt3<6uwx-sG}D z6Yrv5=idvIY?v7{M!vE#O#S;x3(%t~pXc-A+z{dq{zoK7zuHvrxuLT~=zeCmD9^v^ zv&$uNo|A>>_9|+70>oP$Z>Zz+EMC~0;YX>UoR_i+X@0RucOm%BNdQ3Y5&+8{M-E!$ zcm6P0Wbo$mYS4GLu5r2d83!wS8)mosTw19h>a`1sTmDcabLz-~fuj#7ksIs2S6gdd zGc=^dQNz#p3|$M;im)}@4!TTn`>|txk(+$|Fiw9BGu*9ql25hQ{>VgcCbs3^?PVIC zgsA$Nro2<*n_WI~#mJFJu&dl-u05)L`xEHfON*k)=MjvLksNtWlXKw z->Yc;uolgyvg-Gup0!-rzjjlzx5)e|3!o9uL!2=*tlFdAF{}-ON|w<64rUluMgnDWIk8S9T2hAq5@gak?Gwp)-vKYFl! znOHx)7fzbYb`q6etDtMRAq6ryHt(p4W|UdhKtkq0^aMez4uIwQ`BBJ>3rkap#~DNa zBAo_|v5}0&uX=o?y$GMr^|j5|F(OZ$edF$v|09?Gor5%TGTs|BYtWbc)YvaYjw?nz zuI+m;v!JidqoNOy#PVdkJ)q&Ent9TPJdZ(pH zbv7etOWIKq8+#CZ(bIU|Y)seofRQiLX%3-$mnLz>01<8_QRJb7;A2fp{4!@hfh0)V z^)6ngAFc_6xA;mp$%M(bRjxU^6{!Gh_HM>zvMf;0Mrm%4fY~WV}%1{_|bpsJPLb;3g%&HK|7#)@hne zJ%PH#y?#YJc+TX>VtACqUCq|f@~w;LKFcY%KI zp^A=+KB#!ooGp#}M(Riax!yt@i%aE1o$+D4tddnT!RfTv9HqU&z_w%qC{}EugGL3h zJ(KOSCw!?5*(v9Tb}r#>Jr3T8Mn8YIhgllIg#hA~FJn6{$YP{NH(ohsS_kaPUW))m zZW<-r(YYIYErR838%fv&5RjXfB1famLi#!KAv)zFe8#-dgHC)}bhji>w+6 zSn~Y7&`oX)41QtU>M-z17Cqlgxg+#K{BH8L^R`#UprDCse5^YbdFSxLOaR)O@!y!O z53r%-rqEjS*|E=hn;gfLQO=oSq}UuQUWiTRVyH*A$VJbfYazZU+kccPAT>KCD>4gF zQCaKnOHRlP@^E{3HSuTlg+K!axlaNWW2%^LnE^|G$b#~=GPI2tlHa`7W^oUOu)6jl zOn%L&8%e|!b;Qrwa=;jS1x@*bw0q>%WFx$nFV!DIu)ao=&Q8apl2k1ks!KD_G%RW6 zl+VPV9Osyb57)<)zeMZTGXCl_f}ydHzrfBeK>Lf?(?bHn^Cg}koKD%!Up!1`QePe| zt9TT|K}>K0Yj<1_72yg|a-+PEd4E}lZ$$5r_mv8FTgQ`VW@IhUH;H~FLDD+dXfE@3s{|2FTTPm3KjlAZ3%HbC#a>`U-rg-4|Ly~5e6nK z2rI>nnCN)6jfTkWP8Qfa-!EsJi&SOPXT5vuo~9Y(s-0pL9oP3UT?{U}m9sfdGl85^ zt^{0|u|vGd_cG4QnKpg1K6^<>qZw5Xrz0kuMCf8;mgt)shaG|-k(1C%^{X1OtV*sIW_Vd> zc|TulS+re(>s`fy=$rIgz?svoYi86vfw9{eKXWdDP1k*7WQ#OmlFeV zh=b>6vv;EtM@OvXrH!Gj>aU|@iBpTe^OjLBj_v)xow(hiXjutm+@>0gid_=hpyUpG z6gjI7LG34&T}Hj3CJ^%ATkFxQIkl1xT2uJ-oM}P948nT^pUT@(7GL@$R_XNK9@J^$ zcHgWBybP4|M0h3K@J;o52g-NTwGdh4@~_1w^_2)Y^xR{jQkSDC#K!6%@R)a4xePUb z%o1{SzwH1Xwa5K|Hnx`maykU6&e9x6c(vu+u!q-Pkl^ufq~}3t0pFuIQ!fZQNS&ot z6+|pD^3$uzIcSD0K(GRa6V=Blm?^eUQsvB|n44&L0#BEsf^>Tt{FBy%Qrwq~@yv{D zQ#$7NYj{Q`Xn!MtL13(cK$#(|nBX!NyiZiy?i23iES@s@{hy9F#7{$%IRf`PVDmAu zCo2+7#D>zGIU=+Cjf)#lEo(*gi}`KYYWGXO;ReDk3InH5vPbl_y!=<|s9K;Om%ryE zJk+RZ>PQD0z5Q|K)K+?<`Y7+pjuGz1Tt+WEoHsOW5iu;6He)R(5 zplg93A4`9E0I2FrmlIXDFi{_L*7-N#S*i-#u1Xw&;Zga}IgJ=qdDev}TmDNdRh5@^ z=tu`2;EOUGgvHpHj?&bPy_3M8gtIKDHq_q2pA;$!apW!Pi-wDWa++&Z&pdAzP<~{@ zw@9r`wk6QEXfRG4jySby&wqWwqsT3 z_p8%|uYwQ2a?y7E#c0AYcVKm&X(=84qJh;pV<>x~cr_a#B=%oAr|aAazi{fLkGUj( z-#ktI0Dn&Gz#6pTVtEyP9IQps)+n=@$(k9N?$OdIz{a)YuU2h63(X;8uUePz$&IZwn z{89>MwU*`;7O3|UsFt8QuI$z~(GN`l{}*DWJ*tZxwmG^)?Arn{LT9wwP8+^<9oD-W zoBS~Xo)T4PMMF@I>j`Nj*pN)3Kk ze-ZIowoX*C)05-<{{R5fVi}<(V8-WknAt!$PF&QLK=bD!ONyRZ^LMu!^^Z%gVI}mA zF5({Q5s|AZYNy9>aIE~1g^g=?WJn;IRk50l*@-s+u$rU81t;QIU8FYX-4nw6%mIIQ{E_auj5EPq_xJ_|ZPFQ%yCiQi|0IN%HojeW zOqVl6^F;g8UTej5(!aES)D{A9gKik5hoG-I?ul3@kF6@2RGm-Huzu9?pdTlzvwc5- z5~V%7EfH5ner0bKS)EyJ63C>G{A2;CT!C#BRmcEaOzHSCp?Fy;>lbT!6-Zj(fVQfA z@*jFrx4H%ef8xvOK$Y_}OR4Cp8RAUYeZO?oHHPaitAfQEwxB{CrRx`?v*XW0_2d|W zSBv^oN^?AvEedIPRaK2;P1#s5ny{PwG>YHBL``nTKOmkdRwmyUJ+ldkbI`HpKBcSF z1D%R{LnykA^6r*!^V1Ra@4j1F9gm7H4H*~w)Ir91;QZ%yb$#2*dF^xw2*V+LY@}zH zpLs$=@G)YLp78q%N|AU)AI5|_|CPXx@igJDyuJh?26x(kji0IX;3|uh*2+8IZn!R0m$ktq8+a-`-SLy_?+2}F zfIDsSkLaFn-*OsOIYr3AIZplWJdaBcDniONvy(*h-+CJGvbr8MA-R3}LRfui)f#&p z6+8}{v*%Lo)A&Dz?obz*&)kQ-l9oko=Fui%aV2$*ytv9&%Z&xvhTo1x*o|OHUW85^ zLhXSzUTrKyg|?a|>}|S4+ctG7v(c*SX{DWgIEbiS)x&fP+cRWT!P1KUp)Q;hO5d^` zCM_anGT$CQT5bIPb=`dgjdPP(wJyA;i=me}S72tdGt{4z%B(w$Vv2F;IV{H}H^*Xk z1a+nJMJa3$f59pmgn_`>g)~-CkJP>)zTa$OO~!1y*L;im9x9on6-3CfxYc7O2-2-S z4oXZwCgbk#z*DzfU63Fdf|C0&yE#(P;wbGeR0381Ov4r>?oz9&X(~wKUc1oreTD<( z?`BSDB~qqiaR&>J<$?6p1AQ-6-m;TeY~jjXyO@@nbsdDeq9afP-?6?otQhKt)*sGk zt;V54(-Q~YaR&d>$A!w(=Juusy2mdZ&gd4UJ3*+0lWxf`EL=DNl3MNimmAf*^4B$D zVvDxIf$T`Xu?Uic`{V!H0*qHes)(qjPwy0Kr~kSjR0#ps!qTT+GQSDx-n$}5Vy;B{ z!l1ummzp2kZ*!hVWFbVaZlvzFU)hlB>JA~Gb4Hy_R?^o2%!f#=$%AYm%svQICRXj1 zD4Q>(y@K*ha+PJpjNW6hM+4Sc)R$`pP2S19!ru-6!LO9)M)w z)Q|}59gDoXo8YoPKHB#4*^aL0eLwtG{C2BYSogo>fkEdI!na+T6a4=c+$?Cz{q$>c0 zbwYF``zSt0o^g)Y|M%O+sa?=2V1`w&rpl-gJA1}K&B!N92-GGRxGp(z--5b5WT+Qi z1f8R__&zqQ+N2cJU%#j1Z}#eJk4n@^D5cEvOnYt%*{D>|a@Q<5uIu4=H@T9(e?Em^ zZgmDV4duR*ALA_CgE8P5&-=ST*$w0&hG8VG-?`vy;PODW%ZZvKZ_eb{kW)nT_7>av z?m{m3Eb)9qOZk^O+7S03w%TuON-e<5Y||f;WibP)Q<2-g2yldshSZa+?*;Z}aY#`Hzor(rKf*&EnNp6B_^apT_V6p><41o(aN;J};=jd)`2 zkpz-fP6t$4Po>*sNILIJb^nqc7Y1*4ZG}KeulqxU6vl+`Pl47~S+;Qo8Jkb`f#E05 z4e^|Z$_CQ-9m5#eC4b3X%M0H;Qwd>-YL-gBiT)NVd4pEpCKHz%ha}4o@@b}^d+lmG z3MjbA+M%^0R$w6{(BiJ5nggQSX594jRRKbx($}^IP06L@Uz@X^$O>pWR|X{@FpANSeDJ<5v~`~QkOs_WR!!47>XABT{x%#AtU#F@QrM_F9B;I~S{tB@yTjxq?3+TdiRUq`HX$ z%H;|Qs*c^S7}-k@4L>)7q!~}sQX6+-PxmnY$yly`0wZ$}#M|NYIV!%qgC+1&n^%dD z6;Afl858qERed>YD5(r=Wa?}*uMdR5-gp~o*?tHtlNit~=|9)Wr${(ft-g_U4Nb}0 zX!uVN$5i#v_%2z>2RYJfx{jbeLU|u|KQ4Zpur`dx2M5p}JAdGgeej&%XclmdY<X8r=I@96w0FDe&Sj8=Lfa$?P}YGQ*3?Fnx+2 zUT{P}{^rc6`&kne98uP@5Oq`W!e*4+6HP<*g0~@-bM{%>InP!eS~1VneRHOL%q8A} zJ!@O|f_uN>l5Ko&aF=Y4>;<70mGc5lykNP+fr={bua3yqMz4@xSOq#8uGOBVtkoF2 zm8QgOEc)%g+85khJRB?&vuf5l?HgO8Nf?6!6t=|}oF5o<;562Fmjpm2e1()u%bU4rau z&#|^oXZ>+S_Mg+qi>0A_=+jA0JcUR-V5FfRCCq*MMlfl{Z(=LA4L@eTa_SK)LNvg! zq15;!nd&-Io{ha9kI|hiz{|b6zy!6aQOTQzRitl@>YH+6B%hswH%>~Zp85IfxGmw8 z%$;+F)Wji_On|*Vhq4Twv!;nz5eR~b?lqtdsLSIzuKSvdWVo3NrW$mS@cvamG>FXW zV2*-Y1_89hCCL$`Y3qn?f<1EoVTo0{&*sO1Vw14JdDnAE2g-WIa=R-L?$iogB82#^ z@4a?F2E_*v4%!ub|}fpRwA+)(4~PN2f)*ONL;h*%3HnBmddK z!NEiY4Lq5xYoDw?vN%iHXXVKK7x^6sCelm|JEUaAncw!JEJg+oP+Rfzj<-W(G*GF9hGN~9|S%tc|xU{(IGFD^f z`*77%t5nuN80l{s1bi}kkRB8cryC#!3fGej(-A{F1N!^*gWEI|0)mWSSZArwaT$8V zjBIbfjSfW3d}{T!4ipT3{cv}2@gXi-M<0W1=7T8m2mxL!m7x1Su@(VXX%LN6Yd%Xy zv+pCzB>)=2$7T@xi|)tr@uZPSzbyjShT{^i*J4%h4I2#=oY z;DEnSe7iTPZ#-}QJ-?sd!vP{Vx%-yQ47I=SLKMw3igFfRN?oN@Ur*PGgJSh@mF3w8 z$c_K+1p7ZP;Nm1y18jZWhLfz)2c(c z3g70Jz?bwH76jtv)qs=V3_krugTFTCM{j;cc6EJuH0S-Un3&aD2BTfQsD@bHgVTRN z&&n#|aRiRVohtHVHt9P%nlHhdYYT_x2|+4uZ{mVhK0GiMxy835nM7r!rKR;t^@~FI zJ?p(4NQ}d6NFtr|Z#Ip8_g+Pmw9WUHcI>eKHOQh5CN_D~M+_IAs9T{|{5 zwmU33Zcq^TP`Ox(x)o|!s7sOG)WrD&2o`;|qz6@1G3u0r=~F>Enwv|)M-3aoj&U1} zDSpvgheY9?zR{Z$1}lbE5O5<(zbJj_@Ee1e_;nPYirNZ!0&1$0)Y{Rp)(#-Scr_h^ zJwAb}DjmDrF8Wn)r zLIm{mY>i4S`4;G7_fJvGQ?up9ICVCsl zNKa3W19yMB`(i}Htuy}v(eeGoQ|zWhIss=J`WDxTMXw3gkx>azNy4=K2#K1z-h4O` zb!8Ce(R%Ps>UlFU6Fd7cq?c?WSwT_~G$PqqjOe&nmBC*@-v{?lWnp@5t!zV9Oo~ag zc9ME+307COaU}fDQ0WWtgj_!}6uz-KZg$}c7O9pZpq-679d~((UTpWXF)<;N!<0Dv z8AF}=#)gh&O!K`7004y2Sy)(HA71|%Pb3k5CS|hudAd|<&}4bNRLc^%oD4=nLc+qr z(yrBSby#gO2?C`21jM%3{`w&mhgYZ9d@vMoyJzqUcQ*WyL?#S9w?nsR-Y6!G$7XdRx-U!S;V5>V*2)UeWjwWPt*yQj%Me;PLK;=p`;{}g#H6D&;9)Td@4Vi zaZiWaek>d^UWh40Mi%(w^z`uyMgE;o@V||l{i%c5JQz4!GO{}ADp-iVLPSJFLV^+j zI4I+1L!_UZ$%(iz?D9As3`h9s$x$RF2?}SQ%489CKj8K)tf)Y=yIpBC+4(@mXB9iI zH|)e3$s9p%z5MwUPyxPj5$>XAcxVN&T^Wcwn-Q?RSa@sgHJUl$; z(F8)SY)k8H5e!q&w}R|!Xep@Ud?8=x%aeOE)eu#*JuD3DwMq@TqJZ7+Sy=?GjJe>A zv9r}?*Ogy3=>kIb5I2&_KxT9A6*ZfzX7d)M$zi(D(U>R~T5v^2B(&b{jGbgU%=Ooo zn%l;3piZ_Sv9Sj3FO;f6K+0PlzbkZS+}yAzm-TFj0Y>!HObiTww6S=VEOxRFwQQUaJeHUQ zSM$;DU<&-yijbwBMij;loTXoW((_Sr7Ybf`!047giTU|`F+_+g;B~Beg1VMLdXnMP zg3=o{m<4$qfyHAI#l=&)85kyfFg;;Ta4v>ao*q{BY2iW)MzR6H<%-XtBk-NcI119z zk?NJj`eEv7@?O!^2kuv@#w5 z9)!=KOR(3M8=ctISy`;$jW81IdegsRu`6)!!|0dhf6JBg!h$InpF)PXt|-T}Km9;V zHgIxcwM%3yn#tzDmI)u!r)b|fY~K#j(AQ_A<=&xjP%2j`h{S1b;#3PA#2IPd!9`e1 z3N^2(tsPWX|IF=!>?E!hj{1pkyVG4J*+M#_ESQm!I~qxWpK}2*OniO3VB{BiCE1td z#651a>%CK1o0Y|?%F590G&&VDEL8DNMP?3HN}+84bW`3@3mkfMf~#cAr?|O48&O`K$|#Pehf9MT|F)kblB zAA&s1T9(pi94+)3|%ps8(;@Z9pwf3qFB5S z5q*^lL~wtfC5sW25a>4Vad3lmRZ;ey@NseB&=vEA0Kt=3L|IFzh(#(O(G)Nmxd^lG zr%g6-8daeugi9bkmFy9%%6NefzQ-p&R%-Yo4O1>k9aTmxU^x00n;%bdKRYDeX@R>T z4_Lr(-iWk(OEAG%GKJZsPrK3Y09Ip%J;$R*HD>Ny+07nbE)f*hy;IWz1^{y%8b{G! zJJ~tO%_lbo50^7E`N6%<>0#QaXo46J!HeYb;IAPTA0N;LMCOVIs6q(_isA$f$wZYV zk{3eU_(~ok>XaliN;=mDTw9}HU-?g+QW^L?%Fv%!L>?~44+&Ywg^;m0Fx)LX5e4vsN5_pvBH%_~ zZ?@8)GQyRQXbl{`p%a~-rs`GJ17ZtCS-gHOp^>%Oivc)5A8jHnkCO9umoP=4NPt4w zgZ~LNP7{Q86tsGtYU2T6cF)lgpod}VFW2d&f3xYblXI&o+E~x!OHCz=gtXD5Vr3&- zv18zG!72TCD#{aZhtH=I7L|>e%UJO0|o&N((nKp7p2|;ThQ+gQMEb?3<+si zzZcA$=khnj6IZdjOE`*!#k48KOG+?^-V{|-hRy7v$x(415mC3{8Yf`*FFbZa*u4UG z!;+Pbj#9c!X=ic;NV`{>nsX~~v+Sw4&68G1B`IlJGMIE=TS+uX1-(!>x~M^3XDe(^ ztdy`G;gTXFY|%bfgIgOZ-)OjdMVNnb%!-kr0RWU$&~v5>rl4xP%3hkH&};RUNf<-{S`$(YD!PcMO5!#=BPCd?pHOtz zrA9!~0nBQQh*_@G+$7jA@Ki=zPm|3xIME3S;k)8Vo-KEM!AY1`8bu?ix%3g&mkJ3hq0m zWF=(-AWUl`ANu^|O5^YaScN&ErRDc-ahZy&%@OVnv#y$2kpc)lk0{rXgwKh&#Uy&f z5jf0BhY?p}x^g1OUbIV)T~kFN7TP$nBX^yMhh@60y%+WM5VRCYsbEvlXf9~dHYMlk zxs(V7Q3i4pO$OxY-O1_HQq$7uk+c_V3#zSrH|AbiFAu+?4o@ z6wH+227WRPx8i4hAKcESfM-r=;IONdWsc`*5GamLCEp`mF*gfbXuCs~KN2$aeclm9 z_{WG7v9GW1iclT^m2QV3L?9Nuggo0H1n-MtC-4+LTYc1)lAX=?EH)4oo|T=CO*HEk z+pE{W3fb*W-k)0_s7m$??DENFtH;+X<+RD?RwckF6N~~6)8&Yvg5sek=?6ihF(nv@ z$yn0idP|QBTW_6F)+0frNBoBZMR2VfH;CjEw6JvCk0EtM;-7avx^GE_mV>4s?SaBZTGVD)DQ98Y$D55Z{)cj>fqz9BpkxqO=YQ^j# zh-ZR}hL%WzF&7KFkGG~x%jD<(85iu)Qb)% zQSuD~I-U9;0*uzS*J{7KqtetQmkHikkGcbjd_GETcRy72ZirIOjo=v!@Cy zA{+iTw7Yh6EEe@-3?gp1yZVrygKty{GBLCzN(8^pw!_ew68gvsmJgy^L0z>?J7XiD$$7McfK2z)<}( z*PV+|_zlX70`HrT6#^Z%%BOQQoqxr>P<{l2gbYES98j7>8Cj1$Il^)QWI!&ibv`Xf zRR>dSGRcdRD*+=YG3ioc8-=6dc|a+cdo!RITIp@X#7q`Po-AU0I41C-I92d+o(K~Y zievcp3ZLE_5_Ua+$f&4N3h?-|)O2)3M8hU6tMSrQCuH-+6g2F+(WVrldK{MCD7--X z(QXO}J3FLjd{^%b-Axh!a=;&xun*0Tn zCL&g9o=;e5DC-E5yy4Kp`T7y)fLC5YL0o`|k?`HiNOnHgmT!k?fXG5gh30p{+MIDisBH8R>m$l%uyAT0{(zWUBI<)i=OU zL%m;1Pm_=WAmkqe+G9D_!Q~;_AX<_WC$^zK)hT6N3EzDl^}_KwO8*%fULpZKeNPdE zjp-%*^CWUfv@~fLdk1lSHc#-1?t+~nA9sJJ1M8DeBvrK~4*n2igKw-0=M3vmAaA>v zGX9(}$%atHgAgVF7-cn`#i3EIJa0J_n7AZkWwj3>N5+yqf`&lX5Qb|nPYF`{kcbxZ zfiRv!s{Vhd2Kv8hbpERW;^5-o=KOyOf;ia!x00a$RR_+&&intP5`4x`FKJ^8GicjH zT+G?G@P*>_6Ff4CHGgzCLG&)%4aHyaHp^jgW~oV{n2*4!DsVvJ_rYxLB0SM>h-|pq8Df;Ed?UQ^Axk%qD=|A7H4d)NPkLQdVTlmqL zoq%<=uc`^@EdoWQxZ1g+QbbS7n+o1xGY>bB+n@|-!l#1>7!Jc7O?j=1p=ab+Ur z8sJ0!3~jspFh*mqDrp`5h1_^4C-1B<$*(Hfp02sZHZjEjcS>p+A&zF9J{7oK&?2o@ zM6!dX&>eI08L%Sfgs{Bsda4z;Jvka?W$Z%tWfd7!gQ!S+z*yEZ(u!UR!JX|K5Ol9T zSWgu|w7X3FMjUjl9*1^!xx(r1^gZv&W-ixIg+dxV3w^0u%f2=60LkFS>f(OzpzJVk&XmUG2T`6-U~6Q9l->{M@^ z6ts>NG#U44Z8@wtJAvr5xmEoe@7_!7g3Y>qyW~b(s{4Gv$J4`bcYDFM6$(DCUb@6r z7N{vYSeW=^z99jXN!F|BD@!x3T?f))vmxFt@^-(-a)j?GxFjl#fkPR{#~>IFuIZEaN29NG!i!z?A1x5``K2W)I>V*0@@j|)+n7h zHpN9$=K3Fuy;GDXjg~E%w(UyWw)LfL+qP}nwry70HY#n~b^qOc?&%(*_Z_!iBc5Ze zIb%)e_na^e`-*du9f|cd@SzQ3(?ZLGiH3Yd+&G$ug*3Ar@9v;ohPgmawydwLJwGM6 z!sNc%wiEdp`RS9RVvHRMY5(ae&18ba3Ahh3kTwga3}FO_qfu?rtJwd30ADe%9B?k; zjYXiz4z!bPMR@RECRg%%KJf*K^9azYx3 zUp+YYxR+7D4!*5U=xwkwNH8^T1Ul0PRfK*S&4argsOQWoK7%+r&OPY?CDm$lOz{`f zY&cwM5B=ImH57kD&|bVZQ4s0mC6W^27pmOD?$eQ+vV){0M!_rEQ>e*g=5JwKC5|Uc zjW}@mZX~qfkQko0e6~3_L;tZme{xn;{(X17>>~6b&%wGyKMWJjB@WCN>V#cQ>=uEy zUCvE3BQo5f8j+lIY)y}**30QC2rnz~o2F6vrpQeq8>deJEA_5}1s;2~`xD%_PcUmp zT_O0w@h?0;?bN;`U7`Eb8GcEmmIAXBZ@BDQZutzw!MGxiZZUS9_-{#IC2`t}!BswOk&@P{r}+y^dN=rlgc0MBM7 zA;~=|p;aLuP%X?}9IbIl1(!%Hz9UI0M+ly7`W49nHgaFl0-l~o7_zezP19)kC1I4~ z*f$O&{7E@tuBT8IiH^I#@!^1=Ge$*Sm&3Q6o0xTqgov^X$p9iRo61d85!@08D;ydy zjuVfH-4(puQRofN#|9KHi@E86J-cKdNhxa#C#lT z>(~-J6(O3pi3I<-NS&o3V*m!NOaKlXAfe2T0PYu*PM>HrwViITzAnpUixA47si&Hz zB>C}6M4#+ijE>1jV&bBrPIwSoDXLf>0oH7c4#qJqbqh&H==eQKvq?1byPD=lMTf=@ z@`&kEly$z^1u%1<_o3%fsr-sPZ4|YD!ohv^}`>{MD5a5kzGA5;Zw7}HP>R_7H2T|OTUY= z!N$%;WR04}rJuO@_7LjYNm^g!U0ZqhhlhbNS`kYmRyA(v5Cuwd?#v3ZBW^`)i4%Onx=>%2+pex+KfL)bT&3>AECy>IhGPG%-Bd*;s|E=fMUgr?jMA>U!_Lq#-dwA*PdShd^9h|!gb z%_Wx4+%n!_SpxDjni*<(iE3%qd}XO=BSv&^R%A3m=GLXAiAvhje$G6BROyaG!wYJZ z{Ty7;ZulC7Tbs9zy-jSxC|TCmpITm~@0bWhda2fY73#E`V!cLUcRsxb*v9iTeiU=k z?zfT!zYz!ho9&rn&|bTmo`p#Bgng?_FNJ09jzjjDk=xs1fp!|{rpoZtrL=GCBE+QO z@0U-)h-adJMdj|MgFolR!knJFr7MmsN?c`Tpvft%FU0D2LTcI7qJ&}CSwuPndWzAk zX+zl4ek)VsSnw$0aVKkvs+iPFL^^>3m7(g_qLfJ^b7C~`ST7iuGkaKpu3Ck`B&U|; z_j11;!>emS$p~HxRT|%G0e0-@PeM1&oA*{4^9nBE+oon#`$N{gp*9-lcLHJ7WjAOU z-Rz%Jj{>jQ*1X)&TJZm%71&f`IHL{jK{TXtG6!nO$le{3LVz56vjL4;j#|tcQwM=p zB%&!SUbV_0j&VmMTqkPD*K$#96}vU_)d^dei^x64F?Y7FobmZ%*4mi=(L|8fQXQyr z;`^JwddbnCcK6!{hvk8`#|Srj18tJ2`8k!BY5Wj?{Jo1tTSwMRcbd_Qp44M_qpHz& z%x=%%Prz5*%cR~zX6{rkEM<}HOMgV8szh}~-Q?%&HP~B1>booAN8v(Zn6eo`(P>Yf zrUYv--CpYC6t=D*LiK)LLVbCoF&AyDnxj3@e&Fdd7ZQ>9kmd=iY%<@bzeTVix2|PJ z&#`9{!RSTtAj_T(RaV_e!J#f`1ne?*LOo*B?uQ7gN?*$1>}kEbrsJQ>hi%OsQ#qE% zVCw=iCiUGf#xhR4pf&EGn3U~BWX8Z#Puf@Mq=9%6(pc}1Y7y&6g%_%g=h=|f3L{Pv zb>KbgSdhi7hZW8H1}9X!f{{pue~A^EkIvZkFpJLkSAb7Y60!g9XxV!hq>v94C@@I*sE{y{iLIS^ zKrl}yfNo(Yemw_#j?j-gvhG5LI`nu9Ha5&S0PGl@UpH}gP_MGoU)q%WPvM-Anr9He z9^_ZQZR@XsV&h-vUXRGl_Yo-B@gBp9ZlTWnZ@Q2Afl_I_|CTNOivj+NEwZq&F#Q)< zWc#0?VN7iQo7k`wZE5?XarnO1dL+hnydy7x0C7;dR-6q&Sd#{b7sm0y<`;VMaWCdL z%!!}RgqkERL@8TW?;K4y2(?R9(&(?ZL{*eh+Mnjm4FNv?kN2DM)1r^QT^}k@BB?@Q z!(zJBb}_~#I5`Y?#Oz;xRe0@iI;`KOKM$l0W2kjwLSNfjh%lH^>gJ1tJ{CA_I*nUef#Q%)m4q-m)cX)&Kf-h_2fGHkt-ip9 zIOg4f`setbp3}-er@Q-mtgLfqT0@c?7QU5Zb$}PKB^~gIsO^a4NAaz8EtFB*LI_Af z8Ez;-rYr~?9J;w}_XiXs{IPMR1^qm!jhITJmRsbNr%qFhCrcH_N{|Y+k+Vpkg@IO5 z7p~MYrQ5SgfvID6SRPm*`I1#HS}us@w)`zs%2k=dREib3(kY+UW@-xmsf9cLscAY0 zSyGX-cjmuj$z2?AEWQk5oU~SqZFRR6|JO$UxIFFxxzBGE2sa0VnD9WhNibIjN!(^wNcy-0Opuwe zDx?{B0wO1HN-LrQcn~coJ$8}jnlUnnV2=lZHNZPXB6nYnE9vfKzklvFrpE7j-`-C4?)PqBqXn{LY&&r723*ju zfi*%wS7Uh9^b+;c))&2tu=ERM7xX;bnmR!O^x@ptOWZ>jRjv@BvIVG}IEHX|%3Ld@ zXSy$n0i>jecY5~4BQ&CnS~HZC?{gIqILeT{PZA_JbW zTu9s@*VB8G0@Au+30Sgf%VUa+?%)YUI* zTQFvX(AZ|g47(BzCmL56a*VYH;i zj&xVTl;gLK020_D8LDGfxeNf^AE)+iikO2#_zR!G=vCylmk)U$JAsPcB-SGFNqeRd zXj+vlueY~gTTG#8&Gm-G(g@9w4Sg3OR3v0Yn2Hk`h*oL8GEH50D$-OBq99*g-FKga zn{?k8j@}&X>3Crg3(A$w)kAt2JB%7?LW+)UlH`qIE67gi4A3m;y{)0`wDp^y;CAkfCT0;y=e`z{^1<*}w8#jMIQ#c?DRQrsR z24VUr2wYpHC;*g61Q8RP3_fxuqr6R?yvx$re$9g18hrCQ?68Tb^FSPqEscBJ{dNdUU{-X?5atLc%JK3$X2gNxnAOKTJico$qHY`KMYDULLqYd_}=_>)r~-pi}46 z#f&HvA&fJzVQA!x;HYFnEH@?tx-_&1T{gn3JV~`>CSZP*X;~Ea@L1}Xp>iox5u8Y> ze*57FR8vBZ3(&_yRxZ7nM;{-uSY_ByGkhH@S;vatf>G6azP*#HWkXRaZVkJV?m~hx zr3-$QhFRVyPlQ2<7Ns(#OM8o5+bR(3gm||`6f{@G;{|H1@_to9&uC+IYGKzr#JqUA zAG=EV6TEe=%&yb=Z-%vMVENROjXRlU4j*9`q0L}udy5q(B~BTry|=j5$F6ypc`at0 zH}G|Ibslf$!hLOVy`@DU_GU&pS7{)1!+c!}F$?UBxGh{EpKAX7U{0WUU@3)`CGNJ# zlI~J?1CR@;mRP&iKGp_U72pKF$&0e@1jUK1OKo``vL~=6*bcesv0el@x3Va$=j${^ z%6f|n=b=8^Pnss_wPwIt7e3g8>FR!zt_5pF1x1b}&&xOl&>1Goxx!2fb77WDwO0Ta zMX>*%s~ zzS7DzvCW$d8A-&z+CZd#evqmv-j%U+3F-Ftom+a&Cbn`IcIC$g7%_AuA5PhA zJUTifoM&|BkKe#2oE)II#q?rggM3ra@gOUM$RKvBTr;fnOHi-#9<5W5A;*USP zls}giux?wsdE~@6k-h7v4O??HoMVVTOUY@>$pP_dW#{S+Rf@$m>U<$`LV==1<+xm3 zgIe__?KL&lm320|c28Q~_=X+w<@d_ZoBw9(SZ!95yA+P3>^0xB>^YN|vI?%p23z5w z&gojO9pHg)XkFV;D-pE>_N#h1*V&~BdJdzs%~gX{y2(k)UPcZ-S9)m)CksZyzQ5W< zAEksnE^skZ;)s90judmTCVRTf=t{Z7+i2#3@zAdf`~Ag4xb(O+mNSAjfcr{3{bWMeTgmuK$Xw<(!X$<~}aUq2$#Kd*Nb_LjzkI(QJ0Y=b$W z9ErX{#8lV%*xR5EOC0vc7`4nO08>URQx`$fB8f51>S&pubVZ2zBzsq`4}nG^Tfk`Z zQ(_sRJSKt7mb0`nqGciFPKq6qRq9LW2E2;#8qox<9402h`oeLctwtsLSaoih%|boT z@>7rZ7<;kMmTuKE&@3;^ga2JoGL+L6xnhM5q(1?Wf&8NZ>`L|w1)D2&+cC$d7wGxK zKhe=p-NgT)h0(Ce4|^>xY2c*AiI5!)`WMTGXVPjtd**qUS%~Uu&!S0T!*>~$diUq2 zK0LdB=lkLO{^ot@bZlk@vESEc)Ol#}1^hi=Sn*ey`+F>oA0guDUYQ}9N-nk;K+ zQ%;ID))VF3y>U1($v2@r=Zm7D*)KARen*BS}_}7uYKt>I_W&aN2{|9jY z7shAiVrBoo7@wJu@xL(nUU##aS-a&){fp8NA}CtC%V%nIO>zK;>1f}iy6A8|zYPRhlJL{Kv)6tuu4JrPc(0=KKdFw7d!$3qS7DyW9VKA5?!btnd&V&i(pv?CkmW`?~2< zTDx?Z1MOwy`v>9se!kmzbS!DD^jYl_;2rK8KfjpK*j9z-(_1lreB8ZupYPKnyxl$J zpK^%%zCGM?yxqp0`+cu1wR4b{XjzadMdXt&d~6@73{hy)RE; zW(Ld7uDj#booSh|R1kwLn?n*q&=R;n@y0r+Z+|E7m&^i|g^l9$sDumq@}eP6`GMyH zEXHw>LJw~wbn~;g^i`@l5L0}8lk5CQ7#A4>$6$YohV4mUuL)8I0&6Guo=2Rr0Qbj? zd$ft*DmGuS7T*=OxG3D3BuHF2hVbWok_)#D{OPQ0wHwNoOL#7JF|wF5)I%dK3BNTy z>My8Oa0G>cEX5|s9vZ&rFl&P4ykhT4Vjd1DvFW(w*%`#oZCzKlg+s@+;R&2~hY@ba z?Jh#t56BS*mT|)79>61>xHw-sUJd+|TD#k>n@~_seo8}@$`C^l^6e@%$kcs!;&8g% z1-+4Xpd_)Ck7$WR|M2;k=U(~1Mc6)jw=7{}AKwygCkw);G*=eh9o|Er2l;Sh$YxL{ z2it+bJXU2~QC7jV{nble1U{e%qdZ`Dr8#ka&V!8hZyE)I(V(W3-I+6@v>*kTZ!nLD z9(}opeRwbMvt%Wr1g?rT91g-n@X|K&$7~irCSXCvR{fGM%}dKGeyLdKwqCYlpcR@I zBD#n-j#qq&6^DEm%NlcZQm1(^77wog`_6YLh6YYT@F^n^rkThmkzk;`p*ljf*h?Ys z>GyR{AdF{+rQm^W=95CcjJ2I^1UKD@s+vu#^@UxwEs!WhrdBk7ja~%n;J#_is;hYY zdOThlNdnjSEMe?}?0jZ>C@{re0=8B2_&J3IGPR==vcmjD(!NIv(s1%tw>brexT@=s z03+F#72X23`I&Kv=Pe~6hK10_Q?x+%;TDxk&;kMGck;>B?CW$*8m(j?FVVL_!{IH9 zyHUx4w&ipUOPmVhI=m*kGTPx^bZ!|;QBh-7RSs+9762)rW2tDMlQbM|5Uj8@RR}l} zUS^V!1|o)*m(w7na%k0*ad%@Rx{8Qi59^>&;phr9Jg~UAn2E9iY%)M{FlGFKa44ht z)#8;e^M*yj0G=4~bfSO>9R7f)H_La|Lo5drY;{S?U|<|Nk8w}C5UTZu7D9%IOG<>d z%%nroskx)vV0aH90HMXZxipeX%*kV@l^|adkc>>S2m5FKu{)Vt_Hb!EkyC+V-c_o^ zoKH_OWY^tw-5e>}2)bNy8Z4QDfES6Lw#F$ybOwrCFbp>tXW&jjg?fEFU45wnzzo@eI6|TYJo)Anpm!Zln|Uc#)rdER)esBFz2s3Cnc#YVS&~)mk8Kz zT6;CTrlSa25ru7(_)|te5r@<?hqduTwN>;MyjY4Y0VKx zwoUX4wqp4Hc9--OpLqGbuetVoC_$99&h?9q+Eq-gbX)N*#BS^{g1flU8#AhFO{zKZ zxGXh&_#L#BTtnuu66ImjAajh)rZEpSi3_dad<2a^{9sUvi{35HbUZ^724pH=KTW2= zNMJ(-n#^RKU&&wi493u0<4Kix2}6{8UFTvYDPECM{GOA{EV2m*6SJveT4*#(3Sexf zB;HfP{#E8lio;lA0(JQoCd2)3DlBufLH`>5Qn93`^W(XWu2RJkJI|fB)wBJ=M_x=v z$sXI#VCh5}Fx#eEqTA&BD;vX!KdT*nLON@6rV<>D2MW3G?6Fyp_Gv1oP53ioM@9k8 zIZ~cbX>+e1E0^-t=sO!YQkUdj6ZZ{}q}B1}K)MU&9K8{|AHPtkpNI@Y7NG34Mvu`I zp(sCN8>eYaW<(%4YSipQp_HTcY6arAp(5KRo8^jf#d_$iiHM00IqEDRnaV7wqL zB|-{vKuF?Z@MeI+Cqw`T(LTP-W>Im&wxiCvQ~pmnF2BGOJ6fszi!)gs?~sokdym z3b5)CcrRs!dCZ!<<3+SjKa<(Uf-z%rl)gTntGy?ojSHj&rC`)&a6^}h^2Xw3-Z02i zYB%FW66!jkG~8Pk!)L(}!$5u>1jwZ<*(mu(P(f`AJ-RAju8VM9?BG@eQR=|107r{x zF}+{Ibj$;_q;}XDuqu34L_RvdGEM;Ow^?mV@AK;)`;@#@!`6Tvt7cBcrorH8z;*1$99jf4MVCu$k}6V>svY-?D-=5XZ6?ZG69(xzy`r+KT|W151%L3rGXloSM<@3f?$rr;^S z)qfkfTvm5`Rr0`S$4ORugxZ|J&)WwzHqev*7HEH#)6v@Q{*K_Jr&}4ylbziBt63aX zOpZ0H`O`L~v{sT<0_Vtc%w{J+*|IvE8DXpDP?tgFSI1bi!BE>^4(w4cZ&hb`#t1}H zN4&iWGAC0a{U&ZQLAq$?!#1GvO0*Ld-sIUX{ZQ#2qaprZoS_WUY@$(uRm#p)-Qf$o z!Vd3txmyZ&@~CVb0}%t%LkeTb~_o1gg4--31*Yj<*Q4Fe-%1SL}2_*_I8@l&U=Gq1Nt zbY$FeyaCI_`c3eev;?TfS;eu8#@A|`*5sWx<6P$OstOv61r9;u9$Glr#@o_M*8r+2 ziFVrIeZF4ul4IxLU8MwQ7Km1U`3aY4Ku5k|2Pj6-aX?}Xf4AqwG06ygUTW%0`@)iL z%{FB+Hb!ctI=^|(??7mVlaq0-*{eCO>!~J8OwDomMI;8i3=KSgt~o#>N7J#%Uli)j zyNxuyY}qCU6)n?^=d7D{OlJ$$d}v|hW+`FHdJ$g7&?yyXZF1}RuuVR?>-wH$=>{7? zp}P7N73n1ZV|v42H{!Kpe%_f_j%hDD>pZ?92D2**+MTQD^kb$4i)`d*Y%SRgbHrw@ zD{$NUn0hcOUrL{IxA%X09%9k!_I-c&db+;xs*T&6GuzdQ>-xv@h6@sDwoabh zwP4k_y&95+>vt=J>-x_J&Ou4OqhL~ucfsm6QCglW6X7rXBzQZ(&z{inn;v16w{Y3T zb#P@=y18edfFm^i4|5j#B@0adF*$D+rDIz>D`Y&D>zic7&>-B}#hdQ4J{zcw+rQyM z|4DNG$lsGegEha4cL3mlZBU1f<%L>ZR)a$fi9nc ze;7Os#@T~l#_D!+SUleHuzW2-j&wUEmM~uJq>3i;^0GLaNk*%&|K;b+>F4!-+rNID zo4MQZc-#I*AP4d>%DEK8CR=a1<=*uE;PQ6KF*7!Vo}bn3x#MHk64vHi*SOkJ<{o>w zRi{{_TDfE1XLk1e1Hsm~U7%d|{!>0Q)Gm;D@=)n{{psQJG51J=bj#oS7hFJ3=`*&jtE z*d9oiwJPM8ySc?%;C@_32q4g)ykt-T311zd0Yb>1o3q>l+S;B-;CijWInX<{KVt#D zxPBnFc|R|2V?)pP4is67#hRipI+x3Mm4`m#$Iwepds25u8V}U=KXs&Uv&(8)XAN|^ zBkp_69^e$n1A~9y5O+BQ|Gqq#g_r^j_U@|=Py`sb{1%2t!7vPg6$-aM2MtM+5I%$@ zF>aWB+ueV9bB|xe0}hr+(niWyKBNC9dZe+1u4V%31THr$nMp!CMRE@bfa|CEB_>an z1!RnDUNKuGvZ;r*G}(_BDOw?x^8sy{F#qHE5%$XP1~J9z;viIvwZSUR9!yZzk+ims zu;p?SaX9E&_ImK4R83zuAtzh~qb1xtmr)$bhjX&Aj78i`Om5y6)gzpIjn#O*v@n1| zAcguTf@OR6#MOXg^j*<^ocf=35NXcvwC@+59?$US=D{e4g4IF5m8g_G$qLs-7kGVK zl58O6f+-A?n4X*#xyBelSRJb6xQ(R;90h{~dEx$P6Xf(995zgm<%1V{M*tAdlG6z< zvnlWR(c#y_G5DsrXIW5!Yps@ZWVn=%Fnc-RCri!gB0+s^Wb*I%j=%w0*CHCD8+DE_ z#im{BILx0mSW<1^%K4$};{1wucg|k=PBo*^2#1L4h>3nq9|gt%`RtwEcwZ0m2%SOq zkqk+@y7(!SoVC;$Oza{@=--sH%P_a_CV7GPgTTz$Ma?}BVZOH8S2Pvpedsh+gTyNL zF(+=A+Y6+k-%%ySiARKq;;m3(zWkg4IG93$xT?Z)QFrzzM!?? zMa5p|rIuAO09{^^j%{i+q5?w>uCrWuq;96nnye!{BX7I5%|NqNsv-r)v@<^#GEp>v zpdeSFIXqJ(2}H-hdE%!ary;gp6?1!Lll>z$kpR+WeAzf*SAP}T6cV8xP8cllB01r7 z)9QxOiH2M(-#hl6>P*P+A4QyC&`7`JmhG!*%=4}@w7~c1oO^og2V9I?2 zu3uL}Y1An2s~$|5#FSR&(p7e5*$<|Bl+BCl(j=Kv5xU@yCAVc=5=}A*$YMcWd>p`+~@1U}l zn%R&!H-kHD+3`r<$|3rud)sU9k%sf!^ijO^pIc~BmBlM1Ozqj|T5yu+E8`k2%Y9qQ zit0+3{AFBjwI{o(UeHrOuKBa|WS4J}giZCyJTs?klvT+Ig#N*{y=tmL4Ucw0bthPp zVsV56r<{kKb^jzkXJ;c|#wGWsX7O0VtB(Op{4bAui^CDv;)MB`3G zU9!Rzz#;m$?SfU#5V<3}p<-F1wEb9JKglnmE%VAe{QJ+o+QKq0?IKBzG>V zq1)dSCa#VAK0be+?mK&|#P)+{N7*OWg>BY!p(qy$yA+<~>+a)#m?wyRTd7vPDuX~o zG?o{}jOvDC7T#EdeC)Ut!Q;HZlaukpz&IgO@h;YL>UW!oltFE!U5G3;(TcpO+hh4} z<-w;FP#{sG_mgFFuzXb9f$>FlznHX2bc^FaNg&8-=pC&?~S57>O;UyuPzHA9% zmgj*g4RLRtJk(3{iIee`O3TLW7sws-BuB#~(OR*xI0|pweHM!wf@E3jZW7W#4lfyL z(>Ds(Ms_b-*+Nwn0X|2NN}JWp4ePk?s;0)p%VH5XU4@ye9NzVj-#Fq_NvNbm+H zV>nLu2d1aU2LZ)cf*2!T&tx}eIji7y@2SvDRgz?aRQ+}270tUDZ3=!#Rs&!kT{x2= z&|MWAAgC@x_&fQl=TbfNu8C}We7pu6{Ik;jJ^BJChjf0&JzC_Lv)OQ431}kr0bnqh zH-4HmG-QuTn5oRU-$z)%Nm=oK9Ppv)J7^Pqbtz$O5TIRRgyyOx ziw;vl-Hey)G-nezqFt)&Kk0hhSI=FJ13-UkNhPIs9IL$QIEe~DiEES6&O*p`eIJ| ztByi+$w@#cx$1kOPnKu*+_DQxfR+F%U9Y2JsfLe$_;~Uqe-mD}U&^L-D8S7J7E&Ij zd7dhE_QJ8HUiB}7=N5Vv?w(~{G?&twaQ68y(a79mV_t%q&;rme3J0}Af3FfgCU&I1 z)*oJqL`s%;{qVVWAw)s&H*pX*Mn@goxrLpYaQOT^}dN56yfv5!;mku!3<<>RV9 z4wH;D<2LF<-<$bY85Z;gsEK7K?OfkJIg?ApayllFUOVcg@mcQK%9^$guDmXluG0$2 zP&Q!sOceY0yC*0--loyg2Ytv)o=&UUTx60iRcx?4=n^T;Gp=R!B=}H6`F1nS`P%5u zWW}@$$h)}niS4=vYbc|I5$)qXMISI?{>}xt)Hklo3b|F2kd1ji-|+Kg{b<7=T;8Yq z^YeYZU&sIBhVcElJ3rjtXAtQ3F0*cz&(F*6!;>pFs}_Xi(nOTtVtkm6XY^cgM&}sK z>FGPtJ;uGJl1Ac?>ZSBd$0w1I!1UJ1&gNy2p0`;ih46z+4VecuAij9J%c%axGa%P) zAXPkkMBrF-(q8*_R&XpnN>;3Wqh!kh#HcyadS?{s6w*kK<1cu)T?O~QV*>vH@Bi~M z!pZu7FC#3B|5N?M@}Jc=|EBrozjxfEYHZnUi^KW;sYgm^=eIcZ1IB>0XwmwI2e6KV z_(FXcP{{2SMdGdrW%n~oWG0HIr`BRMpaWP)=kSukjo9jccCNF>%0J~fe&to&mF@Ue zYm8Wt>y-A^g|4J3_qc_r$Gdm`@vrK;;r6iZIkA1NRgzjB{hZX&wLYb}wNeJCP5JF` zbd@{)eFI9@&@w2g=l9vT*7sjnIWP3Wwf*w?T-$H(U+Uvmz4Cx7w>aZ^J%fMq{OW;C z$G4$(H629Zc74~lo+~=&>GI*G9P2tfp3`;TAPY|K{+p)sjzsW`JLH_v+0cKSRZ$Q$foq)s=%)w)!AtQsKG{qdAh3fPU+Z4+%{O^>Q^CBk%wP7A=9n;#UOx#91wsgm7jr=9MQcN>?1(^0( zvH=cE(ACUX9oi>SDycLAacmcyc@PsEJ}Pu14>Z0I-t!`ysq|A6w!VV%;yube%t0Li zDW3L#@jAjvR7rq{j!iNxD4NERf;0udJQFK`&=9~4j}3X_iWc$*M~7O1ZX=MJV367n zrx|>W=EzDUQ}0SyE%1s-9&ZO`JF1V+l(X7cMQt$qprL}s^Wj^pLa&zJN6~utp}3aF zm**iYm)&|!OfwNgj}iD_DRn1<*sdWn24`zZGk}h9{(_)>7_Nq0rQ7QWj%Z8J>BCbu znwW({s_M3qJ~DBSM$B4jYlc=+QEGF1bB-Dr>x$78D5VdLT2He6#va#1MsPH z8T8ajRs?9ZNK%nmhqMcdN{B)VqO)|tii(>gKx`%iHI!(O$<}%c#X*eA5<2-hMjG`P zgDQSW78Tr4DkKbLdep721gKat?~Zv2NR)lRH5s;>niRaDRMt}Sp)3}kS(||j%AP{W zk0lx-RU-(Hku{T|Apt6ELxqG*8OTXnaO+ijMo-MrRVj8DZVc%KP^@xH zGAkQ^*ci)hj8~xV6y;QG=-`_3f()%2>TttW`R!|Va9YP-L$3jo)%?htH^5^RZW$*r7A`*QUjZP z-Qky8>`zP(+kE*YYBm32d!DCQU%zkjiS}Ns@Ku77z4aWRAU0gsT{s)M5>Zn;AD*Nj zE7i0uPnDY;zG!Bwrz|ByWvFr)SRbw={WDrDqy%kw1=hPX0>k)^H%_%6db@a2Qhrj1 z<2=X&7#JO**$Bk!Zzs+{@7LR>-QTU5)6aSi`By}J_fPjf_W5_a@B91bH;(SSYU+Ks zlf(jKF@#J4hZ1!)^Kuzk_mL!VI3CK*i=^Q*(TDHWe=4{sL{_Lsy!;6=bk4q`nU!NyJiNvxfsnT-N4%Aw!3(a0StOEKKpTXZH z$+E)}$`KcD2lv{CNeI*tD}$t_#`E)ZipjxduFeZGh1Ux1a7RXHhose8l+EM}GDzxA z<~w+jo`ZfB>_irqDNNkCO5fzoxh%J)ZLa$}(``v|ncqr(|1y2lk67rxrg|x?M!ir~ zBIUR-Rid@3hqY{|o{4y#I+4}?9Vae?@*wo>wWb%?=3>*Vs%9Jg`k1}{uVjcfL(zj7RduFcl}zKx;W z10%{PFqDqVi5bJ*g!ON&a6jDn>0UfY0A1v1TtXn}+f8S(WFf*VUio41(mv3&^L{e^ zWO8C7T`cw;+Cbf`?+aKj(LmbRcCgZ1(PW3e*&1G8=BW>B8#?!bZX%Q5@KnBxCMDJ1EFj#ipeB zTjXvgr{;FP(j+0SJd5S=RUMwlvQ7hQ?OBJp3E73tw<4-Gn+Yd+R7gpYvZPz((}k;R zvphq?-)^Cyf85(6H*Izd+PHX&GdWuhCV5SrAsE9ccFj280(8EnE_X$d>jpS0o|}EU ziP*tqMF?Nn0F(L zM`=H6n2j++co`2VyNj39`=_~Al}D8`XP>%l6Rva8>qcx+rrH_c!_xt+_9*oDXIc$U zGe)Q_rGU_1>DlJkC5#9P2VS1&h=E(9_gBblfO+w?0n#pOM93e6SYf=p{xOM>n>)De zcL9G|djFmuH*f#mF5Lry&+~eQ>My%CojQ#88H*CV)ku+L^pl^*xJGRJLe^+z);k_5 zGUlBY7QBY}Mb4v9BWP!o>k$X~YN}5ss4PPXQNB5kn68_G!YQ;n`PIOb109{@962n7 zO1x}0K&ySRY@6swX)2wdd8c@x(`7oSUs5kGCAEau7c%nE5>sM|y-fW;O2kasKPZ%R z1FoaBD!He&We>!el4PoeK=?_yaO?rd|qrnO`UojzNM%<`2~Q|d<@ z&~=)`?g;op4d|x;0F>#>Jm@WLHZ@_llGrS9b~lE_Jtj+rkw%DpEHt9Cdp0i zx3@p8@y@fE?=9TN?S3{Gronmzg?3E!(BJ&U&24Q z1^nMAB>OSm6~%@?7c?NbSjEPj5N#19xQDENZQsMJ28Y}YL4kf1r{hF3Yn^&Ts*tNw zHmg|4wy9B^Im3x3Zy3$A&P+7(41a-`8!9>i&UGICo|Ewj$CLoNQY-)&eC9e|mPTY0 z(3u|*tMme>*5!R~{u80Z@7zKJ6y_7i4+tA+R(Hq(=S1DeNuJ*kUnqr756N^#RLoBt z<9Xz#4SbQ9q!N{+>OEgaz)oR3+{S1E=Oi3N40B2D2K?{XU6VlXXlO^;N9ZLVRKM%` zP^jo}f9ck&rvm$?^A6*aS9eBhZ~?SAG0RC9lEV#ol;R3=B+AJ29@vW9leF(TBVCgD zG|bXn&ei+LCoB64RN50(j@X-Wp3I&+fC-M9=ly1m6qnEAv8Ge)QaJ9{9OoRjNoQG| z5H}*-p%mP1p!&b;EzbIV@99KAo!^OzdX#9?MOq>mIxZ@ueTXKA>6B3|*O#*@`|k=x z`%7e*CAw4|HaTL6x+NCFdncA5BePNP7hM;}7PRD%4m3Mmr3+e1J(ot|f1WSv^t#QS ztIAUQM#Io|kMllErPFEqs_YhigSS3b>!hL|my(T$h0X@~gpUxOwQS(1rYRAn1ITzG zOLSsH8klA=BZC-@Y+S;!s3%9nrQJouJpZZFjEN>tk4Cg5lCa(W0gVz1CNhE zW((&!{Ee%Hi)-`#9vJnYdT(P6YE4XoHPK-srZX!U#h2phq=85G3%BbtC+-R=t&%4P zztCFy&lxYaD=m+7y(!N@!a&Wur55zM{a=w4G$(a8)thT&2_d=vDJ%m zJK}=;M~&3c?&5u@t>gAaPzUoWtQv%B!54RJ*qPnNHr82;zmX>d=}Y}~THj;}v&`|! zzdEx(OM$Cm|I4Q;Z0MBN1XArF7*{LVHSwx}PlUIwNiYX?F|E-hx-qm3u1veE8#32o zi!EC#{2-}F6@ONI`E6gp#{tr7&2^bkPM7zSMZ3>gk|Dyi4rmBHv04?M&qzlrM(Vd- zCjPv=MLH3FwTXY4kFU)Ta1?m2#;GWCid=CsQ^rSo`Bo5^sEUiS<|1;I_F*0bt%opG zG+UfnXM+S~1jMDK!Dvi(&VI+>d2SoMX?3HyGRjWKL}^ z@P%7NVdo+H2_EnX%}lK|JJ*`c`eGO5h-6b>QZgFbEb*aDE7?Q==qS1vOk-;EJ+SC9 zk>Hcz;JI$lTt|;&U^@c(Y{9Z)uk^55Ln14C6LLNcyBmASorN!iB9&`7x~!!Yvz8b) zO_t4j;Mb9=;;dnF1`d`tWrb4qqAXTfgHYg4XHjHe1wGyJ`G}f%Im_M^#vy?}O=@ga zxFuI9T-jqvZI<~mb4sWc@%wsCor3A8uW6gi@u+&!hfAxa+GCYVGiQlI-3F^@B#$x} zv{N6oTm`H*1~fYc>{*DL(G|KYXX!==0nW3>naNFG6pCZr1(uVYmG18bro3&V?!>rK z3Tp$|=Jp~yk!<&6=y3KJuf6#)x>|u{Lp_g*&Sz|d4s;=VgBGMMEq}^`qQL^ZP$k0J zh!$Zg+u^97{Vl&UB9nwxDXf5%tvO&rMll?Sl5f29knY$FCWZ8cqDKk=Tlv0Cv7pc#;gRRGajM{Kg%D_);#F&6;N0L|#iFsa5gc(C z#l(JL+LTDUjU`|4=*q@u9%n+j-v2|`HvnnUbZfSI+L|_}Ic?jRwr$(CZQDI<+veN0 zZQJhc@Ba6{_ipTNY(-RMR%V`4Q5EM@Rc1WrIma}~)=Vrklu`PSPKgy~x&4B4$2ZLW7!JC1gbh|0sa5 zNA?Nkw0Lh?RnHheFZ-b0KwW2l;5jF!?G~P^0IEeT78j{y4&EvpY4%M;HA)#IE>9T$&&(1#9^}=WNTG5$60Ez6z|v9 zKfG3$^3m>D>aL*xMF8Lj;P;#{Y6Yj^RkO&UJlay3oD$(EkWkEN=4mvC78ZYU!WgRC zLMM{t|H9s9aO3g0FJH>$y&EXwc9{+Ha7wqYwe4hy z1$JBew^%WJ_!Jc6!<}(bSaR`=6Qb}^g#QAmv0St5G;#znWlU}25^y0d#QR(mq zR>7dgvPx`07cpndube!7isTncN7EM?%1)^JaK^$`$eo@;S(0b z>BcZ)smHJp#GoaRQ%(RZ6Qw4nPbLtyUDiMedv_?d20}**(6xY3g^h>$Ud`C&;f8LDUjMB8>Y1%}-*>h-56Cm^p?swmi=aGl_i4Cmf(P6i7kC-m$KBZ+W({rMBvQ z)~m6WBHi(^95I%q1-Nq6HGBIEcw0;PH0yX;qMp91C_g!_lv+zsQKVVz@L3ynFbd<% zR^LF^>~b?}wYXVa3*hx`XUiEeN_`D2kM)d59Tt}nQ+96R3OSlU3sWzAgiN$gTI36@ z`Nbz0qfTJ$=MK|CrI;w{zSzD&4l{ppR#sjLT!7&MW@5$N5@nsQK$p6{028$Wbmnix zx-qNvRsGf0a#|)e2^u^s{r$p>Z{D)bUhiHn*RZyu^LfnA_IjsmnaUB2c5PAxZfJ$h zM-xm)dInW5?+>psXe@hhPvFg6DlNnYF`rAt-KC;|Thp6{*F(#Fr_!drtCv+Wf}DZp z;FP4}5?XDHP$xoO>7w?^6Rp>@SY;cpora$0P{e2m^o2kMC(3oYwFu|0bNreF2b7g{ zb-!#ZdEX%46XPA@`Fd0bx!enqeYh_WiX4a#e4Nh-EeX3mhbfpy%d3rD=ZWOV=QV8I zI3hKwlm0M9sa_9sKy&1>xyN|;^pz_|YXE_^VM^uK4{nn%#$W+OXAzu+^=5P(r!x+2 z!4y_iVhWgq9e_oF^)E?FCD(Hyp)K=cDf(XjmA0pD(v;zHY2_yzCL!>EtoO+%OG1rR66=kq4F5@ zE!P`PIWL_^MgVHUApS4|=0oVn84HB#205o@L;sjFU!lagY)F!UbLdK5Km3HVX^mhM zF7$=2!Gx(7&D^8u&7E_qbA*{|(Y2M>n~t;pyf|sg%K3ooFj}Kxi3}(3kR2?YfIK8q z+gQ-pt7*$CepTDeq3G_b21|owtC!Din^rsD1mxIRm)Ft0T^VAPlY+*k;bem~o4ddu zFA=vtPpk+8H}<`~8y@{p+C{WxA#bcj{K*3ZX!kGOX)`+k^DqE#06YPF3AVHEB=8?&=_Pa%B%zDY5zi~CH_CcgqzvNueG-0oiZ^zK3r^UybW+AGdV33WzwC#NJ|?OiFaXwmp*RtM+UwqoNF)` z(Ldh7R=4apukQ#YhqP$!u5T{f=NcvWD=d%??hf5*fypjX^@7xJZ{#!!#cy zuq@Xdaiv2t_A4BdWs{4ebcJE;$VRKmy2@YMp{_PNb5&^Eyr90s|85zl-xo1=x4)`8 zUkj?E@OxY@pHoX>zLWl0uz4jk~+0%9%gE7$N z+gE^n>5<$gCcWt+q17}TrkxVHe8!q+lblyDD;TdO(Gg6=o9(w1qP68LQF&bD%)6TiW6q4{gVA)fy@6pfZpv_DSiNg*ueI zd^dzngB6FNq+b#LLv|-nzdn$Ue`I3NV;ntxOWzcp{#=F6+dQK(#Yzn{7xw1-_1SK~ zYXQAj>9HS|!=>}nLDLpbn|`U8!Ol|qVj_UomBp^e=Irq@8<+p`5rDU}NwbVF;Erd# zGN;mBPk*$!YNFhIw~ew|;a9iAtn;ww1`S!pQr()i<~8;i&`t;mzs~ou$@RcVJ`qqi zGQ}OTkQu0Aw8P`KXGddVC(m94w~`uj%WlPCd%TT;%T*ch!J%3m;ErqRL{}K_3PXfjQK3wx$33;7qGRMpvqCn_N@gpux#uu+qiF&32-fu!QBo$V@G zX^?DmD}gj~zGfJ$*?ZRr!g|6LchAaHpIr++N!7&1F0H(jwUyPS%Afc4*2a2*h=srdyJld&zg$kfxOhf%8kV*u=`c99>VT0eGB!7|gZIln@W z+ag2v+SNVM5Hju|O*e38nJ%CLRn4Ig(BeNPQdO`+**Lx_12vK*vI=xpZW`-=HVyZO z=P)=)76Ri%_h#*K#HtB3J_OtH(Wh1KbFD?iv*%huHPiJV#eN}WY0W&r?IjE2TALsH zHywO?0R!f++jf$gd_CFSd)-KJ*I;ED7tybp`%_w{c!icpYT>t|`daE#a9HGgCQ1p5`9t+22Br@A z{H1)*V<#(M?wrB}(=`yRj~UJ792n5n?a@JE#Lcmw6#E@H2(=uT2UwoLZ5ujWY(b60 z0go^z=||6Wr?sh9HVmOSy|5KyF+f29lKjc`(xR9m*AUvtfm6ukW#)S_WX{^m$G!{7 z*=Dxq#mw9_xaWQM=P;oA>tZATL0jB)h2}GEeRbec=bfUF=G68=B_6<~S4ts4-k+H< zodD|N%i2}wpQ2=|3|_2gD+vy%h^W9H0u8OCE9)l|6qln1TTX|n$S(`-jq0jMSLELU z{ryoW2Knm`rTnKuvH_DPT^!V8;C#$G^zV1}&9=-#*l9}}Fi)Pgba8f=i5tsQfabQ$ z9?!0~4EBr#F>;}{S(B)PB>SiDdO?ychqVD;K4U3;wH&qx6`i#oJeG{L5o2Z1a->ABvUgOc;BbaV)(1`&%Ij;M;zn z4q1{Q0dkB2g19~sa?Qj(4S6=oAO(3gf}qr&SOvC{&;jxd2|xYiuO)hkz|Tp={Y3Mu z1)vS&F;e>6ltU%-0`o#JH@(R%+i_@S(ahJHs2PI`qP?f3*)dX<>>=2^Z;21wm|vIS zGhHZT-9E+2`7Wx^O5%w~vqY5(8aYPi?BA5~k35z4g*8opi_+roTX@U|(`sO@H z+xuCKkP_!$vac~PgsQm>E#+Gq3JYZ&jJG6nySU#X6w5dy&wbv%S4JKm>M)4cerbk%;*ArvV-EjzN@R1=vIJ)ZxxyPUiQATR$4M6Kr)_iraR4GEr_7zG+C$w*W@mj%I~6U}753VYeQ3=o%9s>rQrDwA z#_cVme`9nfgSTs)8*b#DB#q-PAoa5hcY z6fsvF2oap_2Ok*h7l@|e0Aj76Z@MEW>#v>`pd)Y$6ap$=5nl?w$2p^(J&?#6WnRJO z)qS(EOl>Qb$vu<9>l1_7lM51Vo|1g$IGC3O7>9MwQPTBqy_UB>XKBa14*n^U6#1SCsemG3-mvL+LyPloM^aFmWyEc%7FntcZD!kFX*E4B z_xgU<#njWn=n-bx%`(+ym*Xp{f#rU`HF<1M5=@le+g^&BiP1i9vN%Q1lC8o?XuPhj zE-xx6Ghuu_W5h&uBLG@qm(AG|#T_g%UIU$B9m%uxy`HVVR01?MTJM-%I#w*7AT5n? ztNZ@MvcgRUTyy=H1pVSdJnEgh%eBI*$bmF#^zL8Ly#*^OShNz}G`G-{9U+PN5p_Z& zkgzi8U=#h>c{NfN{$gSMd^5s#)VLr6f8{yMT+LFKcW~NEqkNb$5S8BNK<$XQ96^c?-8)M1hCB3qv(+zR1b3&)p8@RAO%OL|TH3xCAA| z?LtSpyLTZkosLF2uZXNlqS7-cyj9u^MFM$Ja1?N1RUlpq>I`TzxApRQFu3(^$AA$y z23F6*;0SBiF*shQesWeEmwtFw-z_*e>k@re2v*VcY3?{-uCw6OZy-#G-o&!=2;5bh z-Z-3{@SZO=$2vK(7>*X!MF+OFbN^PWUTU7!Rq&uS;+z4MI6U2Ma4vTGoB_r+zgEQ& zJuB?)b#`5(GxnKB9DUCqra&rOOuqTXT)S_R&1U=r%cUj0X@;K=!{nlTNEo?@Xbzb% zo<)Jo&y!N6MpSt~_@uw3^e3wfrk6$bHPhu}`)gEim{(YGyNEqD_E}V4T;P+fgv8l} z2y({LWe^UJsS!0DABe&UTZvbFsg9|`+%@r~=j z|8I#XVcCK*l#aZnVysflFI{@*J{%uDN;WX*2^bJL!?bko{RF)1AwQbU;{Wx7c`A7T|JH*703D+bJ|6>(x+((IS<^vzGCdQzL{W)vvFS55&dJn8)C_Av3G+?)iQRZZ5b_l^9(&IX-I} zA8P}vhX*!-)Yk+7eJ)-TOJ64X_cA`>TpwpFX_jMMObcoVwQ-D38tj^h4$-O;$@LR@oL z>-})>c&l1lnL)qY;XUJ3n%P?&c<+kZ#C(5_cHwc`{!~4=yjPNH)(Wx zxo%0#Uv>PxGdoe&=TEb_u4pLzAx=ufV3NoG^McfaicgXQg(GuhfHFydDR+U5i3YBE zpBbw#saY7bV_o4#0pbvhUIC(ikne)z$;Mol%S*oA;b*LRlz5~u(IiOQ=&TI)D^A;? z06zo%wB6>`*KR;F%6D{9=-wIxSwaS9nQFE%_u?J?Mkv~xlUAdZh*krJeMI5{OI^Eceei!ns$BhmXs>A@m^%fE{2q-}!b=%h<#ijjZ3 z`X%nI*nrE26xwHHe~n~Re|{!tY;}KadUQ;_+YWYaDR^GZAK!)HzPY;uU%A`<5cYoI z0n>Zv?o}$z#NRAzCgBm4wDfkm?Y!dhINdxQzz%aM<)zJj6}Tnme40tnx9@exsq-C= zGd97Fie?9opN%KfqLVFf5nYgXqRUP44^I)NW=B)d=<(N}g2@TUsKogYC5KJv(6{(6tJ_(K zbvN{gKF@h(W{LTrdBI@i3FYpfgWjitzG?#<4w8n3dGl^tO0`*PH^flp0 zcN_IQGM?xD`Xj>V<9?sjK#g3~=xa<@@AiHp*^{5;>9nn}$`jC+zNiF)f&j5|UOQm& z)cc4V=8+6(0G0FEnCmu@jpB)s;<2_5FQCr^Y^OydQ_Nae`w zu7=5@(%!;O?hyFU&DNBag%Q%7|BTA>ijEG`tUL-NjZ-Eub_heghlEWucO*P3@8ZAa zve19$F5I|1f3fKu+8j8N)sU0Z3ob{=9}0)Y&GhvsIV0u)$92jYPzV!0Wi7X(enY&= z!+E@L@8thWs9Y}nx1Q79@slr_{$)fx8Y*AYWDq{nP0*JS39{n8{%T(79EMrUr>5&R zg8Vmc%>_O!K9lX^*V_4Nh_-hckJ@lS+hH&VGN%j)s0&p zy{qn0G9U3xk`2uJB`@&!3nZ-?Mb~p)BZ#)ojZdO2J~Y)3;o4$?5(2k-hgAE1^+4Qv zH~!bU?I(JQ&q~hqNQL|>FX7L74<510kx(w)8PTdVVSlwRT-~aQXhf)ACbeT(&zt^F z@EsC2o0MVk?JXSo+cAi|U1Nxc@v_R4>ZNi4Dr;W*##J&PeLO!BZ6|SdH-NoH41(;Y_iClAtE|B zl#L^?pNJ>9W%hfO)`8i<7mmvR{Y55kggFy`RXl2MPsE-$E}2wFtYU9cMn&X2;-X;0-b(C7uB03*f0CxC7RJ8NUTTl_gni;uG)hq?dShHx zLApetR9Y9TSu7coBxRo1ZF#)1f^ybcTQ7M2V^Bce9pj1{|c2!gsr^{0? z;aL7f)(37DQmsH{6n%SFD>6tzQjS1_zZry(<5L&)+c0{Ys1bWS&hs2MOrLoNAYYq3HH$Il2SVaV6cyx-A5naof32ts3nog3U28@rpbis#3XkLTxr zA>6ltG%q1bxIC(l4^WTT{p?Bm{dUS(%!|vDEpp+~;nGe03eKPT0#8mugxnW-o10#y zbzO9it9~r2Yba+!es3K4yKR%5yF-3mvR?{GV#>0tS|tj##k4q>%l)nup-mzjoNsnD zvLdD;GBz@>rA{G)dCv0~WtGL;qfGwci2Zq=;X@m7ezs)x?h~VpDM)d>1uXfXogTJ^ z;Tu~kEBqotO;3)G`eZmQF1p+96f#SEV3-%7PAZ1Bo6OVr{Z*j)CHbJ>B35t>SC{$D z0?dHf@t{>A&}FnsxWQO)orXG2G#H%&`-_eCW`;xtDNgkwWb*c|QtBq!^|U&XK>3q1 zt%$>`;-a;QbBUnk2J^}mp2*jmUk>`vd76?Qhwq~=rN3mOxOY?=7*^*r*b!Gw)UPxo zutfiXoxomUi;p z<|F-Owa7Bi;~S}0Xz0>N1^QsJwDOs*BKZZ{!16%Ndj;8oP-N8NR84v{-L5-MEzDap zqeKz?8m84LlGrGy>ZSC_J;%IDpxt!uYoSrZ?yydCPm-4b%APd>_MJII@xyP6JALl- zc*@dxM6GPN?}e^E!iN+g+lhM z3%ZB!O3MdZ@bI&Qy4&G0;haLK8MoO9k7X47x^v*u?pD`4)tO)=F<><=UBqLh;#^v6 z9dI0Oh}-qVP>rGMd^Sa^%hFYmRIue(_^xQ^)vt=DD_`)S+G{CDa$=Y{D<3-Xj=P+n z5|y=Inc*f9y3)jGbcT^YP+1+FSde%|7oZp`e2DJYN1nV}7&8%LedwoWk4lHJ*tdXQurc3ur7|+2Z9sb2b^@Y9L|JgH<2f{lj*^+m(1Yp!V~) zA`O@Es6LflA-sU~QI~t@IgCL|nE}&T|IHmok6P?t*YK2}&N0YB@kFN!lmm*7^?bkz z-+Ez~!<2}+CX)&rp^JO@aPSGbV$OwxiXPJbuVX_ zTo4A0XS@6ZbVZ6m4C^)2dC|0c;Ovum1?!H7(dmVtD^VA=!h@13fECIgC*j)t(G!X| zn~{zO%0|+k4eG5M>??)t`Q*BIJ%{X&BRkvG%wOY6Y>iCDr%%NTWL1WbpJ&nQ{EO|` z?s+dR#z<{7hEM7fH1G+4&c3PPo_EkJ;WH;dlWT}xM)OPys~xHns}0n3z}hjAhm8U# z8|pI%FgOAX0Z4~_2GGKH4}Z+T(1bjK17I@u#$OrVrmlO*_}&8dpeDa$uYXxT>rL~V zyDmS_eQl4314fdZ0iXa0oIL+Jy+-Y50!jXbx)3K z=bcWxE8y=Z66Jv>ln2MsK2hVs&O$)> zi&9r>bWu_S&T3M0QdN>og{RE{8KsdG<&NC@k;m#&e9Y7HVVfsj4)+#o@yMdSJ+=ne zbkp(rDjNLswDs)nth5<>Ws_99&X|Q5_YQ;O$T;Pfu##3NV7$a< z9wG|+sz>_)s8nlTtZ86vqyHE1>Aw)A{{cRwV`X9fFSI-pBinzY4?Lfqft8JbosB_@R?Jb)(#(M0+Qia`fDW3L-@(Ah+L3^bogSL@pNsu- zLd`(`twm7JR@BJM#MJRy?z>aL(a1`ffbCo4AN9g!mPQN&|3b{lLw}=RjjRp-xhH5Q zM)v={jsK(vWTK=0{{+Bk#ZOoV(82m%as7$j$ny^bDi4fRS0{#ln`z?)0-yU8sIOC$z^Z6dS)EaV)RxJLWc`DPPcQ& zOuVm0BFZl|U9R8MY&O#z&~AV51jsfdSIkP|QaQ}|TaBaobA?04sVE`&o_uDR<=CIB zO%1ilo(SasP7X5oQz1P}e?@6HfkQ+#j>T>y9m}{IsE-%M7`}p3{IlL<^A~>VNmYE> zC5JuDP1qCTe)t9Mdj2N!*7fz=8UDfiC{pVq zOn;7l73cL;8hzDWq<8Iu3jjHKG+7t&s9%i2f@7V)kY3W=cKJLq8=`XW0)8bOJ^H_y zEz|#?ef%%;q*ZXzcl^gz744mj{-aeu&%x*)1NnbjshPclqoApt{Xfbk6<8Ggm)lD$Ga}B|JM^x3K9#wWkE3=hj@?6JG-dfkSCI6s$}3>%8}yip{?x z1`aA116cqk6I*})s&|AL3`9CpGlYuZgj0!|XpFe^>Z5b&?(>FwYN4dPto)x%I;&DT zYjwHV40Sf&dw|ewP-)D4Qvkoy5AhXAV7X5JPT0)W)(L307zx=%ZKM8>qSIm%IFO1G zY1X;oWV6nFH05bCEcS{`K!$XwO1;Tm{s}-DsO^nEYN`nX<$_?fgY?=3wlveIV%2f^ z3-C^-DdW$O(au_-`Up_LdxsO?Z9%%^^<1bsb59PlDMNH0gj||k7^_l$SWfx{quETT z=pr~3Y{60`G@}>zDM$L`@v8jbxUuO-tJxhEdomUqyd&~?kEoPj5qzL%u03t)jxKvK<%TXY)MY7><~xYk0cGWZT3~r++Us=MIO}V)smM6gad|f)CU` z#%qB5GsCVKqAdiNfxZ8Y6|*|CVM^f+#~l!93geAx_uHQ|4yaJSozwDTEgamCPK47N;mn|FqJQN)wo(30p`DHynUvu_%3vM0Ise_Yj1X_n+U5NnFs5s>s z(Zzm85B-&xW@zyMb%)Wg!=*$Z3nqizLMV;N<7G5EG)fL}FPL#`_~`}g1*g6T=Lqou zerAj0gUSouowLnb0z|kY!J2obXX%Bieno%J#1VdGi@Rr-Ijt_8C;+p)Npt_B;|qu* z$YdAZ6Q{d}=kF*&Bivf>MSnLoo-ng1{k$!LJMg9*-qA0F4nMeh>{g&=IVIj_x97g3 z<6n-@A7H097N$?#x!pTh&mX}rIQ3SpGuM0lR{~mKKZPbtY1I8$awm?}@12ep&}X3T z$=;#z{W7cVXiKY9vammq8?11oeA}k{*6(u9IdfAU^BLYZeXE%apt}BI>iE+RT3pk3 zBGBwLUu#6BL(zARU#$Q?Dm|)b=8H40gOISx0&QaRM@*|9`%Up%_&{|%+1(?%gRj}) zEcKyx0#EsjN9vLGUSW@0j90H{tZ1zlm#qa$BY3ghk6cR+fF?=>IWGrh2P!`kIrHJl zKZ|?9eae))SRWEt82(}DLtD8y_iPI2%<9be0Dd#5itz}43o>srPdg>|UYTAH~? z4iuCaYY zRnOxL-X3)kvekdC_ec$Ihr?P?7P7^(fLjKbuf7%Y#_HC5{{HWRw1D7*@Zk;&<`PVS z+hDx!o4yK0hqv*21;|p53P?2zQeQ!0c!GJ$fDq#e(}G@pvR9tv&<7|1-O%6wn-23; zH|~_Wa=aVwwO(rgb^mdNdQaXtaHW24+VS>8>B8Ld@AmB$@OkQO=JwC&3E6Q0!w=Y+ zy5@Z5e)o7cf$&Y$15P)P^dF%od7cd$S2TuqAb($^!`@!%zo*a03&AshrxQtIRi(r> zuvjs&r1ju^vwHmV==6An({I#*vouP*zi7+qP;JM%v$@YB2dXc&Ua6J zfr@XLi$v`N&3ESnRfPUXRRgU1p*g^n$xL&YK9MOd@q5G=SOb{P&(`~owOIPz(Ro6y zfGg~fr?&r&qe?>Yf@8QKLQbo#N4Q_B#75=}+Uzm(J=;Cfb4APu+Q894tb-L?5o7mN z*Q?L-pN8&5;x;oLrGlS3oGMr%8T253`Bed^CiAgHRxN&L!4Yj+lLE6@G3X}b?7Hs@ zJb`ra^4{b0E|;+?xd3H)MNQ;N$l*CLRR2Z8z`p9Up>Km*$Tt8AXwK(yz;FA;Kvjcv z@M2$+1<6C-!snBukg9vE-t|lft&xl6O4V_ zp9g<_f`6_Q%Cdbxe2ssNJuNnccP1PV6GQ+_{DRg3W;){C`M{fpe$epm8ZydVMAkjj zcHPa(GZPKovN~28&#ja_vZI?^Yc=zAyTa^3?y|+5E>Yt{(cwP}zWRfbcSVES<@OBU z;P`COpOVjPx_Q0l>%)q0B@$)YUKXHMBJKd^YoOCh=8N}%yanv)f%OW$osZ$1x7B~O zCi`VqW-=pvdF0Ev7JP;CiCHJ;5ttX042sGfP$l5w>zpx!ClZt=k?Pg2u#A^0dzIVT z9|H$ji&lwy2{HbL;~uC2e0d@Qyg&rh?qXY>#x>6xgu@0|no|B)!)x+2@bJ!Sg!lP$ z<@5Ew9lj=VK)t26n>Bj|UHOBhfB|x#@lZQg4n1p3Kvy$h@fuLiDfB%@k>E7OAlKXq zz8R_Do{Koo69HQwv9%n0w_P~Th0@!R$^NkI$SpO@1a6f9TkhMpEI>L9Y2rRhAiVeN z+rzK?i>**>1sB(AP_yS+1W#L_nKPX|ycgh@H`qOu+;Ezcz_C=L$G=}`h6QM4TW?5W znYs{g))8jPdm=u5d|>QPeev;vuk4{8r}SieV0D77FPLplZ6=^^wB4k4ZDzx%=qz-8 zjyhQ^RcJSMIP|`=rwm)|4K+oZku$S0qhUioIK5~#u_RQ9k)YhDG9kl@_4;ldJ+x>^ zhfJ8$N08?8SI?P)X;<#5LgbI{4=2)?5o|K|3=+*1EySMAg#9T+ZCo@i7(p`I-Y*DM9FjPs34TT={liht;PYT z2x*AD)d)WT3{=s)2PKWktp_(v$egZch?G`?eVWJRW?yVmwj`g0(U+_$lnS3O4hpo0 zX~Lg$b_uqG4F39_d6wgr`54|z=kR%wbBs`ZGik9pvO?4OWf$044bm-y9quZNX}jYy z@~n^Kr*&G3>)Ua=w)2tU5=WTk<$9|Y)-tEd&2jrL`^#fr28h(<#HuWX?Lij-l*vr8 z-u6@tPBesVjh!Im7x-JL(WT08Nm6nx6>-q?;lSb5EEQ*dfU7fnu0(U-qX*aR%+A~} zquMIFj~y}7^kI}ERmT3Bi6AHKhJ6pU#AU?Qyzyh0aiQ81rc_esCLKqe`95CM%sDa3 z-E5rmV1aPl2@pK!EHspP9UI8jyrgt_`phKiL@eAV2OSr44f3nOhOe>yl5{Qj?4R3r zUkXy;f-E2Y>94qYe67s7iuk|LVLtrC;<<)k)7#$6Jh9RU^Ye&6J7fYe0=R&gGkq&# zhcwL4`%q-CY0nbeRcAF333x2tpM)D8B5J~8JNmgkm-+|l0%M(TahVb>uyk7clQ*Zh zZy@%?-R>s)H&s7+ZurX#8xelo#Q7u~*GOxxG5F$sO8)7~0pW%8c%Q&#J#D$2x$3Bo%6yjQGyei!wPI@}|G8^KP%%Z-2tka4EkO z`6b^EE*a3Yb(OfkW>G1oMldoS(XO;Ac+7N?`&Kw#W+KNGou99^R&cF%a}kEcWr?f| zp6_OHC$yJs=-}}l@smBMfhPr3$B$ZqCrtk!>Jh zs%A$A5=N->N<20ac$s=H35C*|_I3T}^19@~+~Tnr+07>un7z0|zcQg?thEpTbp2k} z@Kh8KEh>c-BMI9VAVeoP>{nf#`oYxwR1zu6+c`D^=HB@?5=jcB%nYOQH=}rZNyl$# z9bzJgOWRT0*7S@3CVsIq6?-zuR`3?0cuoMKES!)Hh0oiz{-?g$8gcWm!M>d&HYl|~ z{G;F~{V*p)KIon;_Tyy$18w1m(R#N{!)F{*3Hu038G&og?G6l$ zXRkj=1VW^sEDyI}G}L~~wnWLmaU9ig zAO`^qO1{;15_rVM%uMBTVo7Ne6)g3>j=4GoiVLve%Rv5-K^3ZVe_*Px*`Hy~4-B-L z{6vyuD!8(-@p33cm^*H-`1mapoz)33TB3Ph*t6ose#zoyn|vP3Ffw1iW;5_~Gbd~l zJh@1pReL83ZWL=zraKt;l2W*+;ppxtQ{~;fIo#$oF6a*EMe_s`;uU(h={-H(j(_>Q z_&OaHrnu$lSwMY_>*5Pg*p^+!bcJtgMTcX8e*%% zDqN+>kutgD6gd9N0akh$kS9a(_*`5E?d4B=$(E*<%F7hcD(8e=_cyIT+I}DJ&cOJP zeSn&TSWT2ymtQ!)M# z9&IR^VDGfl2p{?o2T5u&@B&>5B@K)a;3<1I7oJ#zLqP-VA+%!5qJ{A#Y9=aV z^dhvP4}KiOjv(EcHMTA0E$*#3IUl#3+u*T?6jmBDhB^+d(XzWDLXJ`+Ns6smlau<( z&`rQrN;~hD>!s^$P>8q1*u5RPYoyJJcQ-GPV7&xM4RJ#YSF^N|c6pKE)pYf~(mT1?)!QXc<15JQ3FAqi zszMK`K^duW*w5Hl1#~*`;y*w<2Z3|@S9dvptdeSnU46BBf#%g3Va>Qh4o(g`8y&2` z5oz6E!_G+~3OhH2QXt5mahKPli~6;b7gYwSZG1h-OXIK1PNxiC#Q_^m71Z*FUoG8h zMZmGr{nZnectbC~^WnXdc6Dvjj%>PfJ!=9|eEomaCN z+;QM+exx2o4aIssZG;^$$9u=)4vsIYU6p~Hu(F9=<2C0Sp0kffm5%CX9dz)N75zI% z)y?Q;4{HQEF@9XI7oKs*&S2RAOnb-#;e0wbsYU2>a^kGAk0#V9-@C= zcdqMDe>Uan05#6k|L95jWZQtsg-Dg=l7M$8O_WwxzHtK~ZO5n|1SQ=PIIry=v4N)< z&@T7*bx)(53*z*++cl|u#UofkMfcVY*URt)`QzT`u^F-*4%R;TrT1fFSnH72A4re^ z4CLg_F&$@mCP+UIkJ!gSkPt8Iry#OPZA1r0qVK1WG18wt&w?7d(`yoA^i<->y;@qX zkG|<59czteo+|v;n^uygfpmeTnvJyrNz0>Y7axxMOBWrT%Yd2v0c)-igk>67?nl!5 zWuZfahVD^TjBX3VT$Z(I(nE;7!}sLfho~uw7|g(O#3tK>`opBCsBsWuRJvHs{f+UD zTi|~Fz1qIoFkZ&@j!oSey~W`YOr;N8Q;(1SW3!H>=LC2D5IW&Var}8OSmxis4(Tit zI1^dN2f@wLIoOg|SsE#TKScyGv1??!;oZGlg!snr7LcTwLfrzz*JtC{=OM>}p739P zJfy!&0>V;*_OoEX#{c1FsI(5|Ije04kr<7)v z{7{#-(Q}V|?F)=OI=*!vIVr@yCX~1Qef$Xz@!J&ARNvR%d3#4JA*a9ccVMy}>-N+= zNxts8fj=*&hXxcW%2aL>i(D9dQ#iW!D0qXc3H)mK_7b!^_&Ky6Wu>lKPb~nLK7RXe zM06V$CP+zhj4nVk&)L&j;6lhBcMgo&99s)sFhjX6>2$2W7$Jg0jVamI?fK(l2-!dJ z^6jwLpcv4(12`_oMNK#(JEP zR0qK#Y>xR_)xLvp*6pQW<0`0D>MGR=>9*_(Z4~FY7KKC=c>_T##J;q8I7NP@|a*Rwtz2;%U#PX9P_dz}|zZwhI*T@E& zWdus=h8Sepmz~lwoKixz)~hLlq2#rVX;;@-WQ0%_gU91ZPUF|(i~lIhHmQnN{cRs) z6ils3E66%eKhM5YBjX}ouYM^z0=~+=Mme_IL7G_F(0Ssz{HU@Obx`$Kb{g;+zpHq1 zeKx6zX~b{mxtYJ5(Y;Lueb9nql3XI!BPa}1D5lUO%nOVQMNXe!N;GP&?)}+?^svKI zB;u5R@3v5RsHG|Ecf8A{1($dtvLORBTZs4>6qP(93GW?er(id!l z)PxDIdEdVM4y#fs|2wIAc8Rbr#zK!h2uhD~1b9u(>fU1O=rXNFvUzPul=+h>f`!gf zS%U`iCWAInL>))73LC|{s%}sv))VPe{c;3xf!}L76&#klO><80+gSuL+h1D32|GAY z&H1~KLApx>%1Yo?QP*Wds~_Br{Yl@kq`GO7F7bYQn2w!C5Tv6{n-0l=UNi!mtBJMV zXc>Bzl$mqRsF7C4Vk*K<$BeM2larI1jt4Qe+jOLFxC5K)k7^LSZ?O|_v)Kl0ibOrh>T_ZGw<2=!bmlre$= zSN!x!g5^Sq*x&`3^@gUNk;&htHf^Cfw)y7ZnnG=kSLUbXL>Nq~Os=8_3q`#}Cos}K zgrmgJBkT@)5@o)6%CH>%3KOi4QDLauEdv`0dOvOl#gUMKhfGA@llD{%i-HmjwhDV_ z3#$saxuS&)q#8Uw^OwWfBONnjOdtw!*o==8Y42lZuan9o4F8Hp7^vJ~Jw`!%*+Gf` zCv@V#g!u6*c=T>Sha*T< z8JR|P3&Y>$zdzf3d+Fr!>l*ONTAQlfSK{(icYE%@Va3pWUh@ZjmPQV$W-dKh63}&w zCC;bEpqqQ`$dbk{u1zSG7SQ690aDPGIfG^{9PY7FJ3V!D$)j1rt{DAa08K!$zb*Mn zPB6QCeN$MHh9%;&0^~nj-}2euFE_;W;JSFBj{E3 z>FOQKo$BrSo#L(jZ!k}}4q0Dk-ZK3{JkR_WYqfOoT|y6h-44wQ{0~g$c!9&b;TDF~ z92-83)Bt)j8Z}dxshT;#`OJLHa;A^jVcp@r-}+6>H??IzF9X`|Grwa_>(6U#!YLjj z{uIyjl906BZfLXt0JN=~4doqnQdO&^WLaw8X5V9f$IjX9-k)+9dhpbKTZtpo%SwVb zVL&)7 zsD&qub`I?zaK&b1OWr6O+l?$Tibl!Eo-<-2sfh;K(l{|Nai+q-_V)G79t4^Wgq@J~ zvoK0UA|Le;kV^M~^Z;_o{tb5A*^wp!JjheMeI+uWQFAlUQ#^6;K{dh*)7t?IaAkax zk$n{L@HSnfq?c<;1~>$QiIOE=3DhL;Dpy|RUgb)wTxpdn4ZV_$nvz{~m)w%MWPpS6 z%qTtTk6?vEJg+m`QJH`DP`BN#GkeSYhX=dOypAgi!TsGZPN;N50Fgi=!4Yaj&;e#D z5@w1GmO{P59t*`4(dZX=<;v|#ZmkX4e|X;`AO7j^11}G5$B(N-_lm}OH#1{?v~lB# z>ufuIgYjD*V*b@9TNX!~<4O{gsFp0bAls0SHcy?Lrv*8H*=KS!@K`+kX%FL_Xo+CCy^uMUNBgbQieSp_u>hZYdd+ev+eDZ zc1_x-`@1We^!ETo}sV@uG1MAr& z4-ixU5UQtYqecQPM3RmZj*llCp@Z;)zz$M|kN^>%h~Zh+Y-yU-5RELdTkN%Yt6{>p zq4bonTdOieJi&w(+u3J+{Nst4MB`*z>WZQ1vl8BDH0lr|=61Yd?^vHH+5<4Pa`+7M zGk~c&?#fXxl_*e{D#$t=$XM7#UfbC=B52vz?te2qEYMmbi_8(MiDR zub&iOhZq3R2n5xKObLOjaRe+`6;o5kE5*1iGgWxK>IM~~iq-Iw0(fO$V}J?7Kn5f= z{Il#K5M?qI>OF#yM1_Qf1c^kUULhap6H0i3P?1h@h$l{TwuvV!CAa~VBH)$MWZW6X zV#&(7QYHx;g{?!sB>tdycT}b2wMlKNtI$*EFQ`q0GM41+KviBfylOlVJrVnPna<4BwOcd0@GfQ-+i&mp^n3e#J8E}j4Me}EWi@)WPn-Ec_?3v@ zV;we&&*68cyqWto_iG=Nz8v{-RA)&Wl9?HqIfbQ#>r&TcZZkd}d8Y6_`<_pq66ylz zJHYM*aSk)MjMMwkcd}*dkOd@qM)iEo?RJ&fDYDIxBMr;^2v|wWYoT{Se+;pqGHa7{Jto{`>M`v$v8FO^ zl-&uBI~x?RklB;KU5TDVe}a_~`2>?V2AoPgmiEo84j`gMqm*Kh(1hU-(1cPBQ2qX4 z3{gTg&YUNzkF!)j9Hm|ZSxy^`M4|?r&0x?~m2Dl0wym@8B7GY~6(Bm8l{AJ1l>k|%hTZnvp55NvzWc-XM)uU|iExQ~5l}D4rprZg(K|8^Mjy@osI6s?5K4u)Bu01R%1%+oJo7@=#G5Qc6hGhE7LCZAg?z=7Pha zC=H{D(JDh`cPM`C_)!KGh%^*fv9cZcjwLn!2Xc=_Z-%Z7ekTl?S*jk618(V}Oc z8T!GOubffaoJ?h>uK4=a`vY1Jo_gn9b4!!2*xgcE)O(-PWOM;D(+bp-SKWnlD9miQ zfcuW3C^VX%YV-`0iW))`|Ai?23t3$(NIiczNbsYE;6IW@L-=QM8zMhGOmb@sE<$ff zE{Ob=<{~l(%>|J+4v}0giRcNOb3z+J+h8DtHvmTN0_r1EwIC6$C}|I?tw8PG01o_Q zr}(zQgi|C*&V|>Cq0%SeP|zyW z{q2)&Cp#%8N2-|y&U|+icSU=myQ6!f=b|bp+8$+Oa*9$(y1s#i%`Hk;n^(d}jD~X7 z?P+kO0@fK}Ln>gI5eX&Spq)aP2f&Xm2-M3J?ce5%=I3Qz$>{)BC?evax@#~j0rk1hIl%^ zL1C`~dKW}M4Y^P9dC0?F0tz0^M#06V7YT>}Zh;FuM^KH9L^&>?*DInNU#p0CZ7O=N15%>_(XHb3kS%G=l1E8 z2_FE@eMl_xzdzWGc)%>Hhnf}<&9QhZDiG5}|zGpq(QZJ{_h5oge;&#mA5+P2rO zU$gZ`^NQ;y?73;#=hjVSpLuxuGdFzN|HvKR`rO~I9pCowjXxOr_1^EDzq1SQnI0kb zuKGf*y&0 zRF#r0aJg6HsHT%Nje0>HjnfL$Ddn4@0v%TZMa+Vl3@*XJkR%69atI{J;V3pBKh5c< z34VIhPd}8Trm9#RB7Z(Ya->qlh6^HAMYp2V6y-UK2Q>%zQ`orV9RO zO)%A->Pq#bxc=1c)If?wDKW*QsA|IIXh?N6Ji3iw^E8pz1}VEqLZs*%;oDlxrBVf- zS7z5NE;p;@Vs6&y!z#5)S`BB5v~7UI+@z|?WA zv>fNS+T}Q4f>=nGSdO)ttUA9O2Mzw^bPm3Pnrn!d007b336cSfjsqGtnF0_v)C~>6 z=0VUu*bPnKFY|xd-z^$0sEib)awFw*?Ka*)PU=v&%KSQo;fup(@CNiEaKvNi9IOw?Y8@+U zV5Dp0w&GF^-lKU&!)R{RUwJ(lOO!D}lv?jcYC=N_@GY@XybVSui=OI73NL+CUe@L^B}Cl z$RHb7M#XVu{AJn0GB%cFIM$$&rxsPe1?G8bQTqPj)R zf!G6Bu(z)h^$~9NuvUvW15#6cAiS7#ZbcIqvf~I25j{@g$IQ=%T6^$UhVJOi&oB5@ zv*Q2wF87i*+ogjxIR{iy4P()P_S3ev$*wM7L{Gb*G}*;$MzlxY~O(g=EnMaS@8A^UXMVl)EYE#^(zKu+Il;!JMm zF(!)7RK^OiH#mESSTq5PYbFzGB{ag~QrPw$#428+r5vqBuW+>FD`N%1#FA-DfX^xq zdk)VCSz9k3V!E0gT0Z89P2j%&wNJM9H3yhjjPci9&;07{8YvJ&c=!+aCCc*?V@zY{Ve`FK%oK4vTZ4| zf!W6FVxDJSW8Pu@$Ow!(cnsfl0UFMCMf zkG!3q@#x>j;pN?nrg*Sw=#v@*+DbWPT3HyPfwFU!6szo?BXz4;BU9U_6V|&CLF^7t{00Cx?9)4u- zMP}30j|@fe`MZW5z^nV&n?Ajh`P$%8GIp{ouKn524~Ov8vB@9e^)LNwVCSO`K#vZ8LNo+WCkKk+k1xn& z`vNK=z>7pAQrY0cwN!DXFAu**by*PkluAc5LX`+4zd=zdxSWV%G*%)hnQgKLvf1p& z8`J1Q9g188B1Brz-{ur~=(zZDZnPdD4n?p~1UyHcAs(1{!s3hZ}G7PEC->3`& zkw4JcA-z5xyLeLgWaWJ)%@zIq7BP;$sXnYe#Q#3Xsp3RuAjLPao4MQA?cAg6QvyGg z$1Q>_VHj@>*e1E0z$h+?b-Oyv$ZQ%Oh zG++SqAsQq@9-_w$rwqJ-=wVY?#ee6)d42c+9O2eBnR7e#cYok1RAvE?16_9RwCgOptBO?5!Dq~bwbAEumJ}MtS2TW zL4&7G=FXm|NZM~#;p&1^?RHXm+Ck6uQE_j1_ z?n<~=hu!7&u$Y`|-o2Q$=PR{k^9+O4`XZ^c<2Cy`_CMNL`zo9FM@U!3AITXB#H?)2 zKj3HlfQUFw6}7cnalaKKt7sjt9=D#dp0=v3T|Q#OL)D?J71O*@g$ucC;)o3 zQBI~nG*R(*(HsFR*VNdAXT0%7AsHHHPDJ`AWf#|cvFVyxXNr4a=%-T#zuhq|m0Z4} zuyh5pHsn}0ExwA(nGc^)9c1rD8Fp}#jaobuFdLZ+K~zShiMs?Y84IdSYGPd0)|SgT zOXA=u_&YwzQtc>;L$6GtXvjwuF!byasTxK(yW$!SC28SXGB|@a#c)iwDT$LhrSwdu zHWbR%R&<`^U2UChM5Rw(reG=x2Ht&^ED^(fZAC{y5+!piA!V0l*J*mPAH+UL{w?;m zq@HBhZ!OY%Kkx<{LfLF;WuxEi4tgVEmea=l@l3oFU*LSq`IzgmxS)$QMVk_H&@4Qg zpDs*|PD#v8&Q9IV_ly1JFT`$7-k$2uJ|NyrGRK}3kH(HBpU?gv_JibGvA2?^vO%N* z>TTzoni!wZB-N>+bD}uW+^)KmU+B6twL`Z{yxq0Ky(4ma?Dlwn*127Cn{#`dHE25U zwc@pAPNNax@kA`9#XJ+hqSG7@rAR0sp;RV-Oj={W6m$my!Se8J2ZUroDi3d!WmhaJ z3A~`;qp74Vl}Z9n8%yK`jZF|V0QGKrR2#EtwXsMvns>QvE|)tMkGNe#X*XW}sM4r;b0a>6m}h1Ypyt%Q=eKY1?6B#BWLJeu6g6LUOo zdkXibFwtg7DLFNeI-WX};!|CqEyvCi|CoTCC83C`_zmSQBZ)2n^<(ug8lvDbqU$0ix0IS^7IGMtZe z2Te#FOHyS-TY(tbDrUAIh^rN=Jt7$;6q~)O6<_5VM_9#(&w%@jA@hls8e9oSD?T_a zU=vQgU`v#6Xi;kD$EkOR{t_Gdg}=F#y*tJQe8J4%pYXS~w>ph%EXF#;h|NCuXZ%T{ zWF>;GVcn-6GSdf-u*~#=fvkKQJ2Zv;CHo8-gQlYn1uMxnSsd;6#_w-rQLT6xv$Jr!z(k7Uv}!U)0dsQ%&(~P3HjU69 z!b%TJn2@nC%b%9V+-#-ygEVFg8-aSK` zbK`b*KS*%jVg3UUvWA_FTH%&f&AaE~xtWY<_IKGl%A)|BOK3KmmxE#+Z^-Y;@5!@y z7qM(qbm#eEDa-cH$Meaz8Gw<1$PW*SHX8XgrPK2XN1-(Up`ITL0-h!x?QnV;b|vwg zWKZ&V@>G&b8cEJ%b($ebW*01k2}y2}F3VpgU$z(8Ty+^m*D!D|Gw!-)3Z6mGOK}=DowUt9pOfnVj!$CCI*8AIVTV0-QXPI^uBUU6Lk77d0Rxk-$olPc@ zBjg*|bxSTghOa{*tlbB=ApJ2J6$Bsj4bsTjbl({<-TN`UNcR!DyL7L3<~&^Xk@2pW z;|;z?jPu&WvwZ|OpX?Pey0lq>t0`1sB5TW)#KxH;@MbDd|_<95BtUhd}wBIwuC0&HVKVY zwfRtc?Q9>qG(BI!lU!4LctK*34=-HgZ}CEQ?-(?zZia+s&L}p@%tQ%r_BgK9hcC&^ z^`UvGxe}V}oam#>aJsrGs&X1VcSf`-pQnGguamMS)TmI_W<`L}qG%~)37WA~)<*3U zY-RpqIo1uJ3IMxQz;guLCg7ZagJc#0TUbFYH_pf)uX|#df9FuQ+dV_wN@Hq%ZpK8h z5LNTi<^ld@=@p%oKdQQ_u8UIU1b`P;M10NZ*nldZxcX+ye% z?K4(RYG|Led~#vvZ@GNS%I_R}s?hMjZ}26lFL&I2LRP6YPLEclp4QWU*cLC@%o5MB zDvhD%(%uzcT2$ZYa>XWSRs`#Ukt>+(o3DR((S*M1_bi$4>E{cJWBKT~ZPOYY4ol}I$Rs@TGv&%Ev|d<1G!gSzi_>e zKXe%kF06H`^HcI{qpLAL71-W{p63NtVIR7CVXBW3aUq_{t$5 z^cBjkP<&!9RoX6O(<(y51t8)i;!;M0LZ0Cd#se7(-W;LKSUHI$m&;so!N5R*i_qXx zhnyv6-d0l7Q}pN{q}?m)u`9=F+zti_ZXca2?RGQjSc;|k;sf1DjX=#Dm6@>0>X#5* z@N)5T7h+M5v9jL9{+ZjDoicdd8*9%GCG!iT4x4f2Jlu~z!e?-QZc)_Xi?!zlkLMRf z9D{%1HhsEzYp^C3YmoZb%}bL0MC_Aaa`f`kog+7PesTw5(4^rroJw^U3Zh!3ZB>9f9zeWDx zM(#${POd-qOzwD&mvj9&2IU+z z_VfbP0%3mo9-g1ZV=339ovK}^y^njWW^ax^o;#OjfCHC8#5P_xd|IB|D$S9ukXCEE zrR$|VXpi(Hf0Tc@Mi&>X3H^9Wz&gq9PdLW=0{%%scudD-?6lQ_AZcZStS*RjA-zPH zW{bVc(eHT1!3G_>9gO3{RJ)oQ_-7laP1V$*dSZ6sw#r(|*=Gm)Izgl*e?*1b2cHbW zt76^LLwFyQW8pYa7ywq3D>AHR0)F>^-E_n{LwXGxUaWUnH{#FpiUDj z^B)}S*6?hmEU5N(vm<74WXepf%$He!5)>~eVu)Q(eUnoaDVoVDTf(nG0`vWe{WI=4 z{kQLJnPZY%p0oj*YfT}Cw^lcFE~{=`ky||ZvVrc))=U}u$xAQcsk5K>D%Hz;^7hxJ z`pl8uSMZyYdP;NF{@{l{Cz{>q!)MtYz>U_UvFshAAYW>e2@tnYJ7Bw)&&C8|5fq~) zLouW;P&*z1^92Vr6|Ndz6v$w(6R@p}3s449LZF$04J zM$PMr4oKdh^X)7!mU)fXA_YtRZI5dXYgtR$vK4JD+=lMZ-BDEgEshqkt-p=a_-3hQ zsV7U5!?RlCwjF*!Yvd&qo{nc~r|YH{XEsf2nLc)rZjJ6%%`Mtnbf)=^n;lHBZD||R zB@|FYYc^HeKo(8uiKWnCO-Y~B5!=k;vZtje>f7~<45uzVE74%Hp3}Fw$TE$Tt~AHB z)V0CI=3LucjO%kj5tA>@x5}*ye0C3+2CpqbyAexVGpEZQuf?@pF;p<<^$iULqLC%T zyzneugQ6%#-e@eLSTNQf+a2TN*tr-3tbUAgrm<(4iHJw`;p6**B|8~30dKBU$IHf& z#JBVPJS+0}9FN<1%ugIQam3o4*hZZ{n-&KNtC?;cOjkw7kBJuO{NR~R@oX}^ znoEkwUrxbT`&m6kogKs?#$4qUrxwTfA}VWBb7M23)(BdGQ3G8KGwPzQBq6ik>O&T* zDQNKFaAb_CI*U*AVPhChE$UVup+w3;c!lLl*VNQdCJz|AUfkP9Om+9S zS#W0u(T)<9?_eE#X_g3@A`K23OHC4dJ29ozli;+h)0JG3uH=NnN1)xKD`}xCo025d zLa2pM1EJ=h3}uO3toM-1#Rc>YW&Zs`-FkgKAVTb5H}q$!EEo=U=XG2w)qinSR4{r8 zNleWvIH9Srv8keqwL7cx>SWT7+K^BT(b!~Hbhv6>UBMAkzYuL4yYz-Y>eY`H&1;Lr znOr=U8`yLGC1ZRRtss)=nK_ddHqW}{Dzp2hD<{@Xx^7`~$Ler6(~_-k zs9m@_6`YX1b?B9w$Jls7Yx6ymzKlCt-I=b^G&-*_4k2!Uc&x_(%FDGZ!AqDW{w0C+ zcs;Y;zdj)3LT#Zrq5D+#dLLIk>g5^i4>*EeF%;GWy{1rvcSTT;5lup<%p8}k8k|P5 z)7WM)0U>Tj&yXp6CMkOa4P9oep~O@}v56+^bOh4@x`u~5fdXP+X<%=F3mjvT$T9qp ztfP{aVkZWrACOjdQv09ud4PqZC;))3E0O~C>r4&MW9c(uD_xI#p4xgNSyzOkdh0zp zCq4*}g~eCISLi~ePVZqR5D?(5Z2}!OOp*V__(N=HT2^AXiL*4=c_ymr#D)=FURAc z2c`_4VP^pL4l!Xm&nE8uA0irEC8n^25Uf zqxw#@063ES#5`3gC^rN62&(ZJFGy0rJ*DiLU z9<&<`pyTK?(vSoOJ$a4iW)IWu!FxQ|Q^tDPa*h~Hi)v-MPNkk0o_Lh`qA~&5*E{=c zXJ7ANZ|9j_IZx1BxPOHt<;ONDdO&hxMEU*l)L?8jtg7%(B>87SA#iTmh^0YFel zbP+rLbBC=Z74YGe1?bYK1?U*K3*75HVlrt$Ay(s{h62E0_{)Ot0*7&7iny{G4OQ0{ zCE^t$0g5vKjj%IfZ{GaS`xqbG{_VQVn1ERqiHuu0cJ9}9EWf0w0bhRTdszL>o7lK( zc03oiZw>}#EdSa!Kbe@_QdynG{ul7jjm&pO@e%%JYUe3x&01=MsdZ5UPM4=*5dXKT zLHucDV#h_Neq3>42O1;^@lZoCQHw(yvBV6~GD5X2 zcr7ij76b1)UJLxUMX}dJNjMUy0a$QTko z)wsR6tGS0H$<0_2T&aLrG1II~1rjsD+EhTC5ecONam7rtn8=QA2oxt_Dba}NR{}Vh z&7#)rifVRi@qiYav_0BA+Sjz4mMFPmwI~$L25Z}EyJ~xCx&GSSwah>*Mzvz?@!C_h zTy0mAVxrmkKR3~|d3-8C9rMP0Dz^{wf`|84jWmgsCL#QoED$GLIP|ZUgQ1}X!Ia}o zu_SA@P;_n9R#tdd3^dJ+|JFp4T33wN>o+xyUXC|=!%gEa>G4{P+Ppk8&Mwz$+2Evn z-IX)!r71%#VOYjFAXlNVktKRNW=BFRM!HN{KtqN4{Jpq}@%>D1_ zXwg@fqv*+^6*_Sby!#Xk3dER#HKr0MsgwfHdS$@Uh_Zl0uXj2w0^&9*brSGBvfFvwdCti? zi7eMPrGbQUOKD64cJ4Q^?uht?Q zHRvnFD6DyLOv7$HZr9^3eUE;(ey{$VUZvmf7_|gM0mZh~3yVHFaW5uvADwJJXh$ku zpa8{dM=ay;#fv+tuyTXDVd_v@Th?O?x;#lUHmmOXWc!8Ah27sBuDZjba9TfVSsP{Z zA`&5}7CL=Rd%RdxWdZ$_sybYXVMrG4gGi(}f6I4=2DkU#^I!cl?;IZ-e<@>dU*fl2 zb9%?nwLiLl;p+Wgd3DB?4b4`omsPDFn!k7Mrjy_Lq(+gG=R;_-&qRYS|h zwS4-WzaIGJ_tq_PrRhIuHEeB2E~+_M(H*FWPt(WKO;poB5}GK;G!YE}|x)vl&!n5BLN`zxiZa8<|xCyf|Q( zIe+o+s6H2L4pXA02EzV95@`lcWuJcL%T@QYzpo zGoKy|H>Cn~5RrA^S*gI(8FUpta32RF=~N(JW(@};<5Pht5Ru1479?hmpC4E-Nk}!# zmP@ImfcV(dg^NhX#4>uVj#qOke(IFEyvwQWa5_DrIU34KxJMcw%MEZ*HZ`TP>1cDl z3HLM&G%-yi%`tn?_~@)z!P)Jznf}?kXESKFIGdSG+}hY24YRuzca)hW2SUKNl<~@2 zsb8xR+phD3dpV;7t(Qz*HHpZOa}2JPgX8Y)1`-IQWhy1HD3y8b+SLxG-O}W=#56bV;0~m?#+bUl@%_;58zi- zv(RLG>;nEfGL<4e6az#=Mc`Ni8SWMmZJ=^V10{3~R)SkPM=iWGz1v7rdGLIhf7+}N=?otDYg*7|&2!D0Y8tLgt%hgNRF}nMC5r=_2-=o(ZWYN|FmR zOKD6rVQm^cJFXSL^KiF6lViOe$|prpnLjHVx}kR3ag3I!6}$qqiBhnQvmXAbeg8i@ zLHn$iw9x<2ZyJ7t*-Sm7<(WzOd|GlUuF(dc%g>9u2Y1q2b%W22a+)?7`XK0HevWTh zt9V6oisM&)`jrbV((qS@R*Z6(wtiH$iVw=Q0DDQ)z|5xH+x{qBLLQ?)vptM0x5i(J zyj06hk3Lq*xPs2?>L{zhnpiwG6)naam<`bz@D0p0!E2<=;p<{M@pkFH+NbbSu_N*4 zYKNnCwR8)^8Vxhp#xOYgG$S#5P3jTqyva$b%Zq$F-^H`U z2@%61@6*19GXA1$s!#g;KE`A;VvGa}(JJjgOGq=c};PDhlTCfeyRv_D*2c9c2{yvQl0*hyfIm?Ip8u~z$mmj+~^ zZ50yF0&caGI{R{IVyWo%h-a%l0AZR{{UFaOvdEH0yHB3>HcnCJ@v@x^U@LGW0HE4NJofC(InPWPn-(7NhVE0 zSkd?X)6^+}_j+P3pyr8NL0o^ql2^5M=$@fsK{5nHUwl?^@Y%w`n4S3R#D946eIaV(w>`JRxsBy7!Pgk4`yPq=HN!Qo5b3l*tE4AAG+bT#d_v${P<1V z_E-@!{P&?5>@nan6R5<@8^vd)#?aZLdTk8}i1LHzf2?jKu_-I%6Ri@RJdzZ*KMLPP znM7&Cs$61|X$xmmd&ummlOR%HBeF4LV~3hgP&OUWHMs}_|Mhm7aA0TY^4p8d%#VvN z1Dln*Xa@BtsvrLJ5aDp@wS>o{)1X@Im=>rVm07Kni?T`z!>T5g`h)DHOqT??l4@fD zVYd+~qa(E;6`(ffqM~%cBL?ZGDsIZs#18#)+A&0TS`w#=mx(*f+-(^=Cet=%X6CZY zmF6om*9cq8TQau@kMJJ|f7clDV-^=W8oC=ec?`}8Y%*oB0(<1XEo>!zjUp%!nv)2i zNsJ|(WVtL1GEx(UCv|eWjP-Rv?QSj8rR~=~qh+-pN{p2n6-rV&Q3CgeFj1Z=3R6|6 ztA!Y-D<;0;VAVFAXkLiF1Lugp1J)=KK8ErsQm)7wgjhpdAJ4~%e7%Ho1~?TojS{ZY zWk;q)s|p!nbwkuK2QaU0q_*j5-k2@(zdO`z)H&S>VQ?EO3UtL#osAXjBMT&{-ZD{T zLJE#iN*I;G%8Drf(`eE)EV?d%6Ml=@M(6*DABe+d8YR;NhZ!1WNVJ|t z>&sO)nd!6XkKosqJK0Hr_`>>#fF_OnHZya5J+4OL;K$CYtGa(g`a8m$d7WYTHsvNBx* zkJNZHoL0y{=+U1P}@W`%X8lCVkI1I+%er5T*dv}Kr#yU_3iVcrSj-q|<%OlR+z!SkKO7u{fm zVV^yCCS74|sy@AiQP#1QB}D($81{kzEbb+m1_JrAKCSUX-_=)rOdjk;YJZ|ENc+3} zCPlSC-NTmty}L>3Z&E#KGLUEznsA)jw(9Xy_S)LeJ15P&5KiNoSkk3&58cuD%-k`v zn)0DiQX7~W9Y1u$6mpBs0(*BX;ZIB+s>lCGB`q4AAr|9YA!FO8SKoU3q)bi0VH(%5 zhdB_;M)V@tsvFH1{*B6{T92YwStUF{6Ch6Gb8IenkLmuvH%#BK95x-X=!5_U3bd8I z!G4|N3+ztESJ`_!PqWXmzzP~U#y^eiU{yH*#4xIXIz%;4#OwQE=>b*J$Ko>c&LMMp zK*T@_#~<2d*kfP}Wi}`0hsI-SNTyA=nXoH#Q z8PhYQ5XXQHa*mUgF;rbgB%ic0Ez_9D261IVhU!{ERM!&9(ixYmgXmSVRb5ZEs{P4U z9d1BmNYMmlMQjdoajnx6OVSq+BU|EhFpi2q-z|+)2i@3&;_iya8iF%5dIR;h1UOS$ z!I_n5n?WG=$1hO-%FM{i;)$1uqNOgcOxDv0k)x(ku*6u@B8LAjYrdl0t=p}C(DZ=$ zLCXWdJ*5L$ZOL8oEESiUmj=7V4dxBO2N}(WfwMuTU-Nn6%k0ah510>3XU%`K2yNyz zS6i@IYAa1K^=UVmgd9^NN--&(D>dV0k++Kr@TKB>iHnGf@FLTD;$KA7bn~>}i<%d; z|EX0uH4ZW84+bYQ6HIEI*<>|%^nO#o7*x+=7jW}b9pZfRe5=}R^7{k9c??&f2f0QU zDe**{+TD3c&*TbtT^GVc!YA8$A@saCnb$wE{x;`nJEj5qwuSlX~ z2I*vH#mAzPP9k~b1)>QvW)PM|chD1XXH$VhBCKUJ0WFyuN<zN+?aWYHmbnbCsmnT@lrBF1BqPZN(irIne@$9Lrsy&PQv%9lQwyU{R#@8JP z5hsm++JWmJE89iD0DZ(tl6V{K>>VY!QdNwbd@?a(2EYOShT?Z))n1ZB5W(~n9!L=& z=y^N2cY^1skMX`N#4@x=`m`f%l z&?o_!m)K{ndMK{U_Y!GZ)?ra%6VPsYtwvE)Yt=E2gH0r!y7a2?AAYzzoR7N44NZ)DlS99AXJ-#( zr$p>JlTq^6Ys^?w-Suhj>ys>cz0J=^5|bVC*3i#y2<430XcXJ6&H`RDbgHA-g`-ik z&Ka7^PS`WmYo;?DR}Vdf??XR8PIMKeDv1uJ!+FBNYMfo}Q*IE85zlcZ!GaE3WWA1S zG1-ImemiR~;~H5PG%YnTCb#RMZ&p@j4|Y2wlTM7@<-(Pqn`eflv z&zp%ilUlB&%>3?vX-#7bnUV5^8%QYsr`_35kV6?bxdRRLawG{SufJhZbW&`G=Pmq3 z^cRJ9V>}ndF+;t`+SOi%cy(DoDV-}IvvH&lMcD3}h^tbG7 z5j=TMeLG@B-V+TZ-8oLpumNXaPT}_G1JSn%ywoDMw1WV+g6&dusk`{D{ATqvo@=~4 zfsN5?64xhhQQzjhEwHQ5-}1xUFLED7{}FX}2#Q6tV*gx-B9_abVmcUQ!>Q&>fz5`K z#iGWMN;;hmCYuxljj)?+%mRSkQl!BI67(Nv8{a@K4@{gwL)ixDvzGd>Hjwu*z6D%5 z*qo^&H^j+Bi_Goi7zC%&97`R2X$|HE#9@heLB>CkV;QPv$WWC+hLVmIsuX zcPn_f)bbqu3Eh~$Ro$4Nbv9WmK@8YBdx-#dK#0GNp-#~;)Day+nn*sxVL4q+k?y;& zDF^W-Ll;Cil_loR>LwlIa}ANCD}Z^A*X?E0>UcE9#0v4GD_+1kzOH~Hfp~#!z;y*S z;Y}5AUX?ANm_J-VfqJ%B0IpYTO}C~;`2ed?TvGM|x*-!+BW@$ecB0<>C|oS_A06rr zhc%9Lng4iyweSRdNV6LbdsP35E|Ai^b`rmnXu)nY%=Jb}3uHCR~2&s-p{HjgdaK`*Wd8%oROy?dq?Yc)snX+1Ebq_+*3k8`sVG z(tJ(@xPloz!w!PX6=N2U;%6KQI;$mACc$-5vNE$%@n$RqDjJ3}vX!zt9-7f(p|ePq zsws-4s*8ZgdFrIm60NEpjINkkCmCI8f5xcei3jOJMD-wOQSR;ZNsyC)e6)#YE6Q9& zmrJd;M@^A0;uY80tf19NI+rmTb3&;~kvc5US#qs1OHSv_B@dl5_t426kCuAYvj{?5 zqU(+&wKBUCw~%>$lEqT>$w(rUvRf>P_~`i?IEmEz7&#p$lU8lwNs+27KyIXd(~CGk zCS;@p@!UF);2LyI!4_#+aGIp@2-Z17^AMU7h$SLI0*~hd!X!x-^Mjx@S+;6XEC%G8 ze2-D9)9Q2~YLab40~nid58i`c!yKjtAr`kMYO%CicUzf$I1N}?vgBB*EIL+OyW%fy zyV%Pzaj#MFiJ*)-x_FV)d}LN0Mx5yNnanW3oj0NGnW*kzf7IoqQzbE% zTB|eq%YuG?w^1>dB9kQ}^Y)7Ib#)0cz&2kDRTd_j2_v$D+t58Qp^}Zm2ia;E)^Sy zafnwP!z+*r%Lfz0T(^uT%9>nk1E8503J`}kMinmOI}bXY$lyAL#~}|k9Z|M0Vl8F7 zO17Ysoa#@pa;ht}H+4G2rSLHN;goC`(y!`V%l5r zeNDTf#v2vP`nVYL#Ut^cA+#L%O~m<)05M4ySdP7BIE6K_;_O=Kp%A zo9B%Pm-#nAR5lm`6q^}U7kp?zhdGHCjHar|tfDJofTZIpPO7Yq>b~jpPf}mqw(Cc$ zZ+Q8!YrpjCm%sL1reK+{Wp>AH9pjf~Kj(`vn{f1*Rc{~Jf5#I$pZestLt8$7C3Ezq zOP2lSy1fto^xB0P>NySfGm9A~(Es_g&m>0G?_b%tO+~gBLIW&|7!kMQF1#D>#iy_u zn!n)?>gVP!A^Nq!P6EL>;!~7Pk$CqZwk&w|b)$+$BM|yS^BC3OCyeu6c-tIcG_F_O ziPFsY(LNMv>DrW9>MOREPHA}o(2Z&=7*iD_Xfcw>aSK6kMho34g3>~x`j|31C2NIf zEZ{`Qlrj-l3Kq41a&2dii^tnej+pu!CvG}Uh%b}hMV<} z2fDf%XxP%Cgl%m~7_FnB?C^yeb{jF-5@D&a$9UX$%BVKFGsjpp%U8yXvWdZL==1Xw zYqdh~UgsIboos9CU|(z7pt;nUtNI>{C2Wp(%pQ+9l0KBMMSb`)GZ4g&r!xwa9@zgt zzzlt87J;50?oOH2DnUbOx==AhA``%saWZP9-O}_wQePsCV7smWF_{Fe4a@XJy|(;z6VH%8uTiFQnoN7HXAdlkN>`2-D1NUF`Eb-w&{Q1(bHs3(DTRKovY(VAV zAIN@)xLt7aG{fnydd%ycdPeKJ)wrh70N^(N0MB}i5bn3JsLU3DU~4%eL}Z7@<1}lp z;=bp+3YoF_RK3dR`Xx?YpOIU})Ftj3 zdW)>KA@*F?L2Kxd7ySpt9Ci0v9_OFXJ|S|~;w}7kd^^ug6bwnk+LLOHt2M~xScWVJ zme@QivnqDFpPH++6(zsyXZ+??Q6p&>lP0KPG}C<*br;cg%@%v%oBKxlDyzp{;*-o1 zx5kZnb1m{>S1q>j5Ob&?CTb0}*v-JnBG_w@le5=e?0Xh?PC&`XQ0C79B4*Wg%0H?# z7o5jRWHY!BIX5+uP43LpA(_Q2CgRLlEa01mt{?hv=>4IafA#!d4`03GuB#3_|MwkN ztJV)~7SV8L$S`t0}(+HyII zz`3|R+#bUo;}cw&os zrJt$7H>hyCs!PSF@_O|o6W(aTOHCU zvTmkR)M59~@1kstJ5oPmDE8^=k&Lv4P~YJ*csDzMbih+xM(HK%F5{T&H>_#g?cVEV z)H33U+h>z(XJt*pZu?$4V}B0EkPH0>Mv5=U^UC^o#qUl4QPVxA+_CP6+LE;*Xwin)pQO&M(6Mk-Bb6~E&-8hF+8L-7ax9|nGDdQ<$+^uG9h;P0ltiGTP1 zJ&@6uW_p=m0Fy>S{y@N|F>1XUhtKJC2n_EP>}H$SeqF#Ml5HG(VY6s6_W&ILsozMJ zPn(&5jbQ>o|04(~4Ohm8WW6AoSi8eP^b)=@{)enF!86PwM%i3u@(1PwaG=b5BpW5N z^U*mYYkW*vzmvj=+cVgC)(lM+HqlFb#(!mnM&^=y0U{P z^{DHlLS?5xs_@b=>=T3kb$NKq@}UI_+=X%Y?FfFe)H!ePgSn;T)$e_TUw&gwBADZ2 zF_SC*W$yA%?z?@iDi-6iq0CZjV4{P+LJCgij;LlK3H^rRWUq)sqTa=FcoDOPxt7@} z-7h^M9hLMrT*i0F1>?%b1~}u1$oL`*E1;)w zH&bR#$T`Qq+C){O(bCBaElt%@n-T59p=F&H3`P_?;`7w^4Urembdt?e>2^G6+zIp^ zu@=!p^&%p}`pW$I{oO1_nI~3Jh$ySLNOL;b&!|D{@ro%DFjT-yarcBae)3+`tb$qH zy+{)E^*670=yPlFwfxZTShKW|T~D?^jo})3%coDz3)*ejO~f1DilHfZmueT_tQ0;s z3K!^-R?6gCgJf5R^9Knduc>-N(^R*U&=Bt0s_Z(U>{y{C$%bHgc!)j%k&mi7KK-h? z2h^LghHm|Y)G2C5p-)mfie$>+{jmtr$w{&TU3}wYRhf~lZa0yB88FDd`NltFCY;S)yV#u^iM*>jGyZEDw+fW6qkr(ig)(;G)S&zJEJG~Y zr+Cp@=Fjc#7L_^PHqY70QqRw91~F<@S5dEx+7lv~Zf#B1w6^yDVDDv%>p~u{d0EJn zbzImPVi&z#lWrZ7K3)CcnF*0dy@6j8Tl7Wd&U@2}StLdl;6lGm)@?FP1lA5}P3j<{ zK-@tG4u}S#95DtN2XAC}N>kd1J2b@^nyj~oA?y%zr6(MiqJ5V_6hMxkVJ1gI`DQ87 z@L!fsg6Bf)G3Qa&vz~#_-+9#&?x#J^sSc};@~S6QkEx&FpR_;bP(8@+Htn`N;Mg5f zt+TImZsfLT`$MWFjz!M)&?@yhUUeDYAzY@t!q{O~$)R>MpIxMyr&dX!2CmsY1x+`q zV(Jv16q5F&Lj??IC?Dz~CM^}7&xed5N$c=9Y8LU)sn#TVdyi5!>&@R30WyRoMieWXaX{W z7+$UU#EG51%R6MpZpS$X=XgJFm+kHL0sA?-O0sv^d+hyo&R%9dJS>Io2@zV7KHu5t z2A-}HfTLneIpT-wzuN;7jqGpR+j-%S@?M?FUYN2*>jIulw$MER4~r#1u#!#i-aKqA zX_Lwpfus1gjt;>`S>4MBdweP1OyAGlzx1jePvRd&-*WyU`c~r25rsPSPRmWkIQQ7Q5QN&Q1Wqi0cTgKNO2$B82FWMWq zvj2DIY%&iKSLPw&6GJ`F1;U|VWDFM$NMm5o1QDidV^ErE-+KEnT|Srg?(;{0V?WgG_Y3x#GXJOj-F6!V z3_CNTX{auFPX7x%!#^1(65~b3h4}&=f72JA-9SweZC+xM_@~4FvHO=lsOuYFywtz; z-f6eYFSIi^3~jpD7;)zQ>mNO3oT}A+t$*>oGp&RlDF89Oj>61)lpom;qU19~wPPVU zS#*b%nO8OnK`#>uyMkUzDC`b;aVP@(h&dFom>C8OE;n64;-=nS+#Gq-9oF;+{laO1 z9VQ!PwhLVXyHq$XoD$f|?j*D$1u}_1OoOi?pfDOpsAFq-91{mlHPu|Hj_AY9Y;B_ZgGsd2u&2 zb&gdxc^+ zg48_+Bq?M)hX0OStW}0Ff`5yc--benLqt>U#ZwRUQ|L zs&1b}c4F?6Zo)S)H%aP>v;WGbI=c1T2FuDokE+M7BJL!-`&g+ggbsDHY{=j$3+Q0C z!4P5~X@7T!yGTck`4G=3GiswIn=4Mc2;Ri(mP>}#c3{new=TM6?loJk-;j-X61kbP zH|=})j;o%-oNCsShZ7IqUS5B=KhZR=-j^0b4g0p;@Uxa$o-qN=oXDkflFiP#))RVL~mgt+&skxkx~y?`OUXEFwj{UGL$ zG!57Cj1Ak|*<2ZKJP;xpY+@}p`|MyRaZue^F_deYEuKGHodHl(CDna7HBJ=PC3R** z^lB&S>#Op!eZ*y1VH5`x``5{M%HmmCjlqzyq{hx@n%I3SbJ;3cr_<{)j?~!M%@eM? zO|?FiT{$LVFq+0@@{>0%Soy7Zyyfz7KBG|_ldhZAw_x43hKH*ygjurx8}|(aZP8QL zU&kQK)UYYw;W~+)ZsO1hb{@4x$e~AQJC1$G`%w0YTsilH+y^=J^~O!koyJ?8oXhP? zAk3LULXF;axJHiZ6a$62HeXA7EjHB#Yx`^2TH3gK6FBj`i!2uonB4ig(alN>7e4MJ zcDH2d;~Ds`8WLAplkCB8#D$_YRXYYq{cr6URR1RZnpJIDok8nxIBHsFH%(Z-9j{n4 zTdUO@98NQ|aO0%zTZc~6lsd;k`w2p8IzO#%(YkL(Yid`Gi5LxnFfN^+vI*LlU|lar zQNLsFM$Mc&N_Nr5wXTLZSBreXOpZucwN{a7CZ=1cHegmt;ui&tDI3?ubWweuc9ZVCdfwNPH7#l6vTdq1vCZ5ZZ%dXM z@-5SKbHq93DS_$nS;?6Va?3*Z!dQFDCVrc4o4C!q&9Tk-6@HJn$NZS<*?7RHGKnU$ zDH9Zf=3pkJO*wNdTCrt;W=UgvOV!3I3iaO7jGM`aY|i0aHs0XUawto_A&~X^OWABo zscLzf%PGFi6x&bk8iDrmc+LJ| zHc`gH0aU<+XPFmJ3AHe@4=CzOKo{qUbzWz>_w4zqx}-B*-S(Y$;1cQNE-O<1Tw7KvbBXSe2D9|3|Vt$v0!J+SV%PDl~yrFi2<5aR{0)!4e-D7J1rae@RV zgcCdj0;Ez!XeV9%TQ$=oNwBo!`5 zC|jMzHWhJj%DdpyNMgi%=Lm$Uq=}Sv?y#v8lT2jm`8W5Q2_gRNW_@W!s z%314*H*i@-w6chddRg0TM(Rw^$7XX>Z57Cln5kXlrnkB+D799LD2{rGxmwja4X|0_ zBE?n{5s$t2nN%pEbBv!kEgZ*`X(qw`yyxOvzV`)+?Kh=+s^{L)jS+6f(Y;#^Uz{ ze2m&0GsI(>$Z{MMy~|O^2(hR(z8w23(sC5mOQR>}Ybx7ZdG`tNGXIxD!1|k9%G|t5 zWs=JLf9~%#87}5~>_(Qqu-QN&Zf>wd8w*%*a9UlVq-O8A<*{$9kM92B9Y0!gUvT8hZ}42_-Riqe+LXJMyHnWdyFGV%en;Jx`1^HVwtm@lzvn*h z-N~=y?#@3hJgIq7_oU}>?-RZ!{g34i@CSq=+Op?h{`>jA3xC&r>i@emV{L9#er??j z4cF}L4r~ZsUCXWFR|#u1>`cw9;I!n-9M|Dpl$)Dp+xd23iH_xXq-AwFpCeb}O9kur zl1@{hi+*Go)8fr*e4Ng#w5-=6@H(s$N(l>5tF*QeJ@`v6QPqmGI)9eY_vUl+;a#KUSnR|gn_-0|h>;IhtYNhFgXBqK(r)d~Wy8S}9EkvizJ z{c^ERF+!w9h4I>aLms%n-F57ox}|kpbv^Xrbltf+q3(U*cbZFe-a{VUF-Afj{0~`2 z9QmEnv--zc#*~>W4=9QpB5AnAGcIxPJYA-k9(-?PW}xCMuez@o)$Ck|2wO+#dj6*# z){U)Xi3u-KidNPCpiV04W9mstwk4AeLtB8Hq&%F0gj6ZI0L7r#rt#5%P+|m~rp6p^ z#wv@QB5Bf*RU|!PN^B2Tv_BOEkRo(a4UjdFP!^$#POPYfB1L{{aYDeB9=a_#^y<*b z=+ITQdfVhN_+wYGIfHe-NlJE)!RmHfQ;ZmGZm7i^W-@+9e5`6#EZz{g<&$UG6`y{U zTm3m_9K_drIP$qcp4r}aS$*7Uun1~MN)@&Z2AL0U%sZ2UF-9-}JA8&2r@9Mdj};VS zYmn;I;F?B+ahXlXAeq`2kWPW;$2wHTLD@zo+Pl~ub}xIHRkP3HZ!xcOWxQeEJ7m76 z!nY_p!);ZZKOJCn@Vv4q4`~r*+>pH;f2g|a9}87a65p~zGdRRPgZwDXs7CR}o;cMA z#qAEd)>V!9K*eguNEi$1Pqv~TqHE8MMBPtSN5G*_cRfbcF~wbvEb@M}DPW1jT!9X-^KH4qt}aqK_i(X$e|$KjhQaokDtM8#d`9? zc%5i(w=>V%U!!}SP=A;9iJ7X$SF+91jW~X-YWaz;w%)$xG;!CK?(iP;^NRbQgWbH*6`@nzF5Z$V3yx8Hpnt|G zP(g7aRawY|s8@z2)?77MBczdC?<&j~s<$@#ZLZ61pML94u6}l;YVr8Gp&a;D5a-rcMu?)za1@4M0GOzGgRXJs3VW6?9Q5q$? zBZ8TG3692OU$^OV>o|3KOqqY{V0YT0c0y!-x0+QT#jIf3_yv2Ts%fLbD^V6%vCifl z7qldbY=4m>cxu1YRDD3f#CXfZ(l@WWdY8u<4rc^aOJVvdZ|#+@%xJjsnkmI^Ue~=V z2lAolPBc%vDwzM=bCU|)U%WTg@Wm+&_b=XYDLZq<^=+FTxou%0V9y3kai=ZSxO%!= zGiCM{ueo%|Wrruv?iqjmH+L+K6>>@Mc(dOcSUYxH-OQzTuAh6^#jdC)QnlYWgG_*#{yv7y5T*~a>uPLHa^ik775Vs%JUwR!)rCg#!UjXI0RoE#Ud zX_>gbV+^}0H?|lr22Cbj(^^~ai}%joyo_ubIG2rJ54Gb`sESu>><_GI)De?4Juz7; z>wchnQ}@1((-Uj8BWf083Xg`Es*x?FHCM6yhWT`lx3i_(S!E`Y)V!5WOq1Y%PnK_u`d$qG7Rm3xFB%7wfH(pXOg)x4#-Whm5mxs zqaDbx_oa`eUrxWp{xtmo_ks2k?h~!1N7bX=#%~k)RsHH+{4QXQw3-@*59vYtkIM$Z z%lnC+u&_GBFeD|V@~Vw=l}8}xjfW!XOj0Z8ITgd;2+%WUEsDfZQY8D>Fh7-Jzz#4D zr;tb|pGIUCn|w+pdo-tZtJOgs&*Aa&)L{9LoJB@DSyGu7p`_6m4*2P0iJvC=DKYdv zoL#o!GaezRfjC*WPA!sw+4@7LI9PE;azP`nzd8c3_DR9vNs3xYF_ z4Q2k%hq^I##u42!Egqv9_&8&8x~K-;dC_FY#mhR)bk{0#B+Dq?UjMaE5-Yinzwy@v za}2Q4`V5}J&#jJm^*WQ*;w1wrU7B>|;xVfA>2bwGQBnp} z!58nN0}A2ccZYwkdJ@=VHVqoPMBln>+MKu;8Z zKy*QCSlLvDcnWeSmwmkotew4d5kqB8k0e0+J-S7uq60g7c6((m0syu|w`bsqi8$)) zo48m`YAkL`3b&z>We%EQS&EieHlQml*IORMPvB?qA(Km^RY;k}{Alj)@6RV<;f?`f7 z!QT$qN{nnC@qLXiXn;ECeh^m1t3ixKlhA7fI)XHe%j=^f$U8EJRo_-!>CT4mh+&N~ zg%$biBqB9V_TnCPEZOJ*ze)TgM?byE8=sRON|OB_#*7`~AETP}DbE_K-jYAr!A<(~ zJ0tr&JTp0C)xc<}0bF?y;H`jnQ+R8Wi)(z>`X0uVknbIGj`h}e((D}pI^{CEePtT+sK~gh!^=eJPT#LC%4nGHfNvCq=U6Nc(mK| zwB(h&?|517y!K*Gac_|=B9Y=uk)lVD;!H6di&9XG(!?mmnbC(EP9MeFk>UV5-CA*@ zLlm-|X9hne`~I}j{cFXK06-xaq6TaV0wt(ZF&?ep&A+58`$0n|o3h!oTAkKt(jJdL zjZJ_s3F`Ex71Wuop&W6V@!RONKR~Ld1`Mqn_=EsdsZu;ay>hH-DouB9Iri8svpIik< z_5Db8<4|&iFOnP@za-(5a^toRJsoq3@(Q;1^MPb+=;!O(?IyCu^Ty%#*`2^QyHOnA zMd6%}fvl$~1Pe8Z4TbB&{kndAzo*}OQ>;I}v+#uL5zk|>1NwuWBk^YwFKJ)W{oLT- zkrt~Bj7O7j7@VG%A!eM3@5DD7ZZ$rEjAKv>o{47S>B*(|vc% z%uW}%V&plv!QyeK2AgDU-YGkG125)oIEMdFnQSF9g6HW(>)A8s71LSD{yLR)K=tWd zAZ&JUf;|>eMV6x=?_Z8HwwmQAYsoLiVNP0(17tJow4-)8%9(2wm16~|(DjbQB%u@a zd5?JXD8X6PQkj4EV7FRjtu6Dv+23ug>Ks4IIRk_2topkq^NWomEVRREt@z7Vwouyf zway#mbGuU_3>tZSUt{)MZ$Z;DT4p1Ni4!dsr--#6>w z^|xQLx_8&BTb5n3WZxUzTj#91cJrKuwYj0+O?jm2^ABFXXjeMpBQ zXq&<MPi=;yG?eE%d<{u;i+YxN zi;0UxVu|`lePVKCa^jH$pGuSxOnZK#?grBXiRTl4i>q6WimgU4=yiv}HPlwa8uYqC z5x2_)JSP)N8ZH|(*It>>s} zMNm^*P6)nY%t329sjVpHaZi44ejtB3&*g&>#kP{Nr;p+!BW$s3v*Ha_Y*n_UHPZcR z=}J?pJ9qv9?eDx`b_fiovRB&$168WCuQ;X!+&XjamVHeE44Zf;sWpc~kr1Oc#S*co zQL06vIj&FDVx2Z5#%fVg7bB}QaAn^MqMiqi7LomDh#YZ<^CFh6b_BHSVhk~A;c8Hp zY!oW~^)A?qP)$UFu5}!3N)lj33=t#jPw?qNd)hwt?2mr^US66^mi9KxkGlP{cCEej zKW6(9vsH;$Y+|r?@E1S&&DS2dspBt`8Exqk5#iqos} zWEY?_ogmzwArpzMia~=&_B5%GyZu^V9Qi-*@8*F6&M7NJW9CpXWGC&YxE`%g3G144vEn3B_@oz`m7PJ$6 zGM?QhjGr)}FagcEv~I$925~yhQ!{6Lf#D{4LFk+yYs7JQ+*(9;S)6cWf@w+|P2hdc zvJ>F_UUurCS)XqVOaU;ND>w2}vJH*eOV@DCb#)6C>Za7RdA=oi$(jMy>seT8HcjuJ z&P;#Y+Cn@>%Hj4f7j`dLSjKN12t9O#tBjj&9Wf9A$@XJP7YKX1In%Oi~m7h9o%CyPTSoN5e))q#ciECo^xD+$T zqVZ(R5T7)5`bIRfX}TY&bDSRuwYrVi5ww=^rUS_3_ds|A`@C+C7$a%29~l#nV_M6^ zjd(`$EI(4^c|X#o`HjdHa?+>VJ|(n7Ob{Nz`jlxS9+~aD;68fPpR(1AVt(1&j5>S0 z`?5S;8r3+fENJ(4kDFNLe=VE3z1c=IZX9aNdR6g&Q`rs16bGK^9S}0n2>GI`HK1I& zB&JHBEX4*U8VPg6Ul3Q2khQ>|P&mpIMGGp_a~8XesYqVcy`&T$(@i|_*;*+?@c^Rg z-!$HrmZqQl(j!AZJ^Z_&jlX*p_q>jI{KUqVB}4I{pZsBH?Qj2vpa0}FJp0?<_;kmt z*_ONaPnvr5cOJUtvWXpH=*5|{d)voM&9wC2DK$@LzdO`>`nsr;`4XPC|0x`P@GnCR ze|vA}_7|`Rn}+@{^z?7=SO10u{0hcT4IMdpWa$2HP8;8R*?}v!UHL`4ws+p-$yZzF zY-jf~bb( zCw~y~p`poWQ8m}do$B8u>Js)bPonwUHK?1hddLj2V8sMSj>L`dEq&h)C-P>Anyyf7tMv|LJ&Wy`u^~{ zP+kq(yAkr;1!d~En^BCv0xg3knu+dV8dwAOJMMStFAIA#ujr>34jTUg|&Ra zs<#%bZ`*!lzrp^JpeShqo|rZH8NXwSK>SxWBpns4ic92SCzO1O|+h`#0@-SYl4z7$HKex-V%+I781RaXK;ykMu7Qe%y`Qhdp$+}tsKlWS{V!DF(1!lkDsgDTK%x?dHVjOz#GwrX zos~GWVPIP&4s96tOC=6%7>rfo2BR(b6pd?1J!_w*aUH2!?W;7dr|G|>aU+fYj>bh& zx7z=raVx|vSxnDduP0!J|n>?ExL*rhWXF84hX`T)m57PK58jsTa zN?X;?xbj`K1QN4fAaQ}#zYK6(5qDtu7cc~;k=UOG{A2f zTrG#xRp?qsnL|sz8s1xd&nzf?3zWSH%8{Vl4N&Gfv;yKQAl?J_`bOR(jnqDm3J{Br zTs5H#t-~@Xp$GCx@ZM$c9#X~%w7!ye23)O$RC0F{)bW~;ZzAomj($h?zpc+|+7=RU zUhCkCx@qb%+7cIkqf*X>%9l#?Et}x(3i`d|YBiL7Ej-&tQ#L`am9*s~NU!$Cbf^<) zoptoNt7+Sgq0g_PIaZ;o;GLwUSJJaosZlkrMANT<6w-b@BRzQGJIMWwP>Xf&eMSQOr+mw$koPLulB9pvKwZ0Oy*~>tE&qq7rO!Msp(K>Cj@E9&NSmbo52Y-m zt#r-Emo!1G2_#&2N_pnO6YXdoyl4LZv35$IEu%d^;C&@+UsBWcv@cixUyYUjuTT7Q zz6;}I63uxnFDX85H8Uc+d?5)fxwL;qpF%)qHmXI z`K#!cuc9?uN%QqoMqh^Z#ntpZJ@gxtXIE58sn&QIExU(8#Z{1NBfUqST2AXx9ZjDd z85=84DC4y6pHfzjd_!jB`ohTk=ho?=*DK)}(z=<-C?%Lsd2eRqJ)ix8brkxprR}tW z;;nzxX4h7}bRETL-4u6KaqMT?eglPoEp&vfgAp|vQ~c}Fl{)<2w(V#1v9vm;Ku>RbX$~MNp;S z-3^tq@>NQlP=KBa9U!&cJTlspa!5`>ZT>qLRp{l_m7cj!dUb@XtF&?-rA&mbtgEzh zmQv3u1|i?jO~38}2DliiGqh)x(fG;=9Q-pq`RqtYQo2gMvjyegw~FE|@{aYCYOJEY zx(w1t3$1}1)qA;0nM*%Iqf(X8djVTqGty$!+Wddv0{(|oSMq(Pj9Jw(B>xCBUkPbS zKUJY-73EgCE7bY|bpLmpL=`IkJvTvmu6<$@`episzTMT9)Xl)=mIzOS$y{Ypf5&RXc_%>(r)W2 zxPE12tge94ud0lZ3-nK-6s@}gGs$Wl|9#&gLiH}8?HFnE<2D??;{vXTG~yuM52Hg;8^X5>@*!L-G9v`j*ur*Q-WB z2*F!Q4_yPLU7)Z^t(Viftg29|O(T6d8kZ=2n5*>oHFT78kJO<$t}lkA|9Pv9rtr#F zj;1sh!}NugxR$o#RsWa$SfvJp7r(mFGOI?_U?n}1cV1|hDR8E6jvyHwY>7(|C;75`!_w> zH}dt@R5;3wbo_SH8j$;=Df<5{1XStUG&Gssor9*p)gqvlm(rB!kR|~Zy%g>&gsVxA zItfw|kYirueuDPYB1(s*LB0i)#wlf73g=7Ux`X1l|6hAoAKb=u+~46q5E2EEVq}H3 zEZrkPSdBpXaJH3)ngI_jwECd2jc)~luD*Oi8}S9t~|BtBz9xT zNu;`#JOV*mrDUhlq|C|rhU&i%EvE;M7p_8_MaCuZ=;c+3dL9}A9-)~7(*bWPO6hHaz6W2qFarRk}s-i|@ znQZnVqKIe_cR%Pb^y0$5DsncX9TGY8L2l*}5)qK+4l7qvkLq*4lF%4Yd=VB|l9eiI z&@ZC7S-)P;VMI>$_d=QwuMko642n$SqIw~#W|VD2v~Ff)j#RJ6hN?<62;zDWuy?U` zF@eokVoR(ouiZf*zo}*Br&_pIR4yu7=4kYaRzi#wNxjxs#zY>U^mP z8PX?auNnQq>@=J z(SnvwP@hQZm|iaNoIaUN^R!+#R-`_h%y;eNcM#d-<*`(*Fva^*`Lv#X2;6=8RG#;j zGX{A|Ol1w8TWV)QFY=!3crKex<+$Y$Iy#(kLoXN88puTHXsW33az3LKd5Q7}CwL^A z*7An7hZ~y4wdrv!lhHCfXL5N)Gt$Luff5uxGFmB>%^4ku?6hX^A$W=D)2Vz+n=I#2 z#f7@;{)CuYa^5zWO&4{FWcw#n4roP#ob2l8+9^bk2*GfCF!4!q$SlQ6#Z*R{P8A>G z`oyP?%BKkyd16e0#njPkev(HgCXhJa!Q-V=KBpZ+*J2hW_wobTbP4%KQpJpxFY&wX z-RWD*g&XBUA(utjCiHx%gD3SepH3a)WfZVPLq%*}(s{b5rAnHYXR<~C!{_Cxe1;c_ zSxD1RA;T$y7qsGZwp4<-@nd3`76zjP0mihra4|t1yhO!dE{0Pm>X~x7r{OD9RJ+&mVqi~wdr*q{D&De$L^?dFaZ_92sC&dzVSoo}H%{fHXENVunh`OQN zHyu#-MO%AB1=_OkQqrbrY>HWU&FDw-IX#tGUcHoAD$HG^qr(+&xm3U!$Y_)%=}c+4 z!t#n@UFMHj>NFrQi26)r$FqpJ!{wq0GNI>kx|je~sl9wWWgu2Pzqn2o2BB@LR4VN5 z?9}odN3#!Q3tA?d>d=dmoz&`t=BTxzwqtn3v@j?zGPCj)u+q}~TT3HC8gEgV59`Q@ zN~0aoa#+@)+{-r!D&?|m!sQyK!7;?bLf$BWhF+7!6e^SP@`)mrJZ4XNDpj0B&QxR6 z3L}c{Tp!0$&r?xSVw+l+XaDmoD4>*K=;>^V=0`?Pm!~lzDRVc;=1`e7vbZc;9=Gbb6Lz&(>K{FnmaW-h($yhdik`T$xaZ} zL_rE=BxFp91q;*TWm>!jF|ApG3_Fpyp<(NX1sZFsN-KtHE_k>!7mZbE5ya6cefl$U zq-9Vp<`Il03}kfd=OUKFTDr6_!EVlDO#Vz(EWF+36i9}Fk@qx%ya8ZmV!k>t@nt_~&nKzJzV<)M+`SSTLn(HIX84oAWv@WMmA zk^RB&&|cnyenU~bs)exV8BY6Y=#% zhm*1J-u?vdk4AzaFndCXOznw;Ojk&%H=>3Iy*#K6s(VACR}@xaLd}ZqV1G!k;7`S0 zZz3EWqBMG=Lx~ugUSt_dEOtE@j)%NljfLY>kiJ+H=Bb?M5fw(zZzyD1p;Gf@BLWp_ z?~jLW#u5yv5!i}T=cURWc*CTN4__(qv2UCmlU(>1a~L0kek?wMEyx!B4WBXpy)Hj1 z&&uDGuL3U1SL6%-&j)a81*{&z{kj~&(P*t6#H}90tsca!9>lF4#Qmxq#I3dV<<-Nu zU&q5ZbM#gZ*lRuAM>59B_%o39?qEkBf7sLtxa-0H#H>cQNv*umVg|3cloPKnox zm1OTP)1z1NrT?EYKX7{4|&-AG%G{EN5p3Vb5ER- zD$)xw6MOWh_gVScyyt?k8_h7c!jFoLOa9RIGTXuw`CsIpFhA%|s*Wwny!_8|@|{Yz zdW-x48IM{WeFIQ)Ea>TS3C zzAL|PyMT>O0ps23rp-d~PPM1Uy7wb2`R`Z-U}FLKhjXoW_)cGy{|fRS$lpiG)b0CK*9IR9{-yjUtP$y5 zl3%qXug7J&U z0xZd2mUF_>ET|83+N3DgiE6W3jM0g?&)@1hgOZ*==}(|?Cs4T)%ns4<1)bxj&JOuF zbdE#kICPGqDqXSxe+J!+0o(xK02y^RP~1Ny}O3hR{&|cjkGyt^xH+ zsr&evbS&CuodnNi|I#BG0yBWa0GsrC!w1{~>&3fj-Z2IUkJdtGgK7r6t@~l#*mbt( zR?G(L6p^<|1Nyg~K{o-gva#jxptfVQV|fxA;m4dLWJGjDUFp`gxW9tf-Xi!md!5_% z=sup|{S_5qgYv<;p%XBJav;yc&I7(^iRy!LYn2mVCxF5LUCjG4(PS2gDlPW$vlvaC zq?I;lVsux?^?ACCE5g?X#Q}?8@CkI39>VtitYAkyU>o_Ptk_@d26ZQtui-@4`wt;B zb%0$TMIJzzq5UX${WTuRdmmIDKpRBeMEH%j0-uF9W-q!8x`}k2K@-zG?H?|m@y z;B^D-a6wl|dZ-WAKz#Hz?VaVmH{Y7L=k_m`-1FAw_Lkj&<*+olw1=j?sX(r!$6sf^ zDrzn(pqKe(erHU$MfJfA%=1I?kkql))vrC?o2`gX)#S2u_N-lawXHo4o1M9Hr-n|n zDDH3#%rgUBBfrE7WbeH}54$QjUMlHSNPFo8xi1sns0Fekr}{lf`PSuBd&<6HZb7!$ zC@uBsX0$R27GbOQLfz%6e(S}5m%ZhJzltt>C*O5EI7@bEN#Lt%^D8WB7x||QxLNs| z%;icMy5T)=osgVx9;NZ*ZI{2{6Mxzlem7e9M>TUueuJ{nyk(~j1bxd^ZsV(U@87)X zEP2D|<(lg4K3c0@gYWREKJvlcy{p>89jGh`1LD=ZU8^j@&XZU-C)oY=v_X*^x?6>x z;GFF?J62ed?hZOI&^xQ{xCUAiQ|zH@U#oK{RoNsOqn)Ic*_hrSI+>azKJhBo1GzS$ z4dSZ2`eQJB`|B9^aQm}XaqnWg=S~4XnR;+|FIG9sR=lsQ6~X^RQ;w6RH@R zZCYRHD&!CM2E-xi;nnB6yKepFlvS})pSE@dZY{5ZxBq3%dUi9nmFH#Z`d@2yF6?aB z>Bni;>1Mgoh217@Te+hR3HU?1Qf?u3F02TSi;&B`j()LKv#krOq%5|ooblrWz`p`r z;uS1#b%7%Crt0r~K9?~XhdEDyznov##mz`hpA#)qZF-sM>xUppDC*_xYFOso$0d}G z$H>``dHwDpO_Z?8bfg;t9ra#0Vr7=M{L7T~uPlu+V_n!?*|%DEw|aJsVz#tXit8R9CHWU=}n!m5k5RRp_IaYK;e0FN;{tZv}?W2~*Z|@hB#}+#qjX zGmTpRz>tse48(~`LGdTLD3?wx_M6nX*vOq!eIPu2@5e3Q_bQ|wDcPIP6Heh`Ift|K zX&hFHm;9!Ri*@G9^vne5BHCtT%gG`7Jx^ud*=#_%4|lhw;sxsXdx+BAA+=aIGGWa{ z09s8sP-Qe5itKoL>H&`C{_&-tb}IuldMdtN@6OfE0Q43hawee`@QziWXBu=GQXjY; z&(grdWO>Xhu^T?!Wm>HjZNkXL*}1`7S$LPPUhIj5owwojSN85>Weu;U=J8c|8vx0A z{*{7ch^SP-qrr-HL5cVii+vAKw?!mY-`38R;bj$NGA!K}W|$%qM9RcvU$Ik?L28{x z=00#r&pUjK$_J`{84?CG*>Gcg9tYCPK$-U<^E#W?a!sde+*V0$v-qZ>d=stL^48_m zlS`{>ZnJv_H*dCWw)y2R?OO`laZPW{4-#*2AXxQJ`xn~|{}KOj|8@U4ed7k~+Lo?4 zBW&9_Z8I&o<}ADR)jfiKVB$2OuLWBCmQmA5k@ApS1%(i8uwi^wX;Y~o0helHYba|x zUE&3HWcO;wDoj1)!U^U(O3e~`=Bw1gyD}YN`OTWm?xdW?h2z!k`>_sY*OU%xSNr89 z6`U0ud#){K9rr~C@igKc47X@bs914ad9G=W1TyhNHWIF3(-z`P`l z#A_m-+n~g}yqsj{^%5NLDJV_$*|Ww@H%ZPgWSFEwpn$9q+#DA{_ai`<;WGRNeQYb~ zfHJi+advSsHMIT5*&A6wL9wtf5ik(^V_6v4S(*NqocX`xJUsL&o(`t;V)k|}BBsv9 zPL>WX_D=t)${E_4(hCdz`%tS`+L}7cnYt_4+Zx&_D9frq(Tmv_nmZG){V+eKLPGW) z+O(`}90at?3~U5U3@oe!j0`Lcy7ZDRhBlVQf_COMrUVR7^n%XDrgkm_9Gr|$^#9uX zSD|HM{DBcRbdWH$G`Dd1F=Xb1qE~h?wN)eF__6udfS9F?DH8z;3*%3}m7w_e{?|}` zZYTdU#Gj$anA(}USP-zXGSmMUxS0M7#KzFYRK(QS-o*6B=)b-mk1XBfsn|>gl+b4$ z(1}wckRCQOv0p@o=0v7*_^b=y1Up3%uml4%cTbP)e{75CkbKkk&*Q8e>bbAtgnLo8 zkLr0tNqZlJ*~8yo7+VSX!>##E#O`YB(_D(bFRL>eh^BdYucX^>!zbFbOoyL6u6riq zJ}ehvj&CTbd!}{M-*_6yaQi!_O-OjpVgfCL$`I6 z_QyHvj{fE=U5L)hwroCDw@qFa`^c;<%tkf!+{cxps*%Cvd$W?aG>iUn#w=D5xzLo7 z{(Q7RN3%}V4enx8+hN!T@@c#od}X``sMkTKuhyix-S7ytixj_)`wrWq)`s_p$1?Dbsh;d%VQ-P_@A#pg~P|4p4s z&cD{~;rXO-cKf>TqF2~AzgOH>@^gjfliCC7)0(HS=xbjyni?QVtZ zp|)OM$iLF{g#Il4qrO+jzh6h%KfJr~p_YAT(f{xuE@$=OtFM24+dAwE^-TLs-Gffr z9~@uWA6mY1SI;_|7BeUHi`C0?;k}UcR6oC!?R9W%t~V^R@EZ)1yeiTa_fzyw62Dc) zFU+dLlj|G5jzxbDt~c!|690=(<8SJzy6=Mhhd8YlgN3w6d35uMTw+3d{v%F2a4&#U z&H&^*{DEy|D=hNK`EC1kOk9J1v+V!RrC9&(eET2Qp;vY_a{1>+Do(DZ|B(tAI-CBR zxc^@sWa;GWB5Yyk^v^M54F8K~|M3NNOA{9hXKe-oW@hG}*~~`3&cyT|Vq#?=U}a$V zaRlc7Tw~_oBw%7^|BvjS{2%?74%C0w|9ANxyni}BHvcgHUE}z{_*eeJWMlk4^ed`5w`#PtNvFMVPRqar}qC6N&YL&FcPqEu&^`z@3?Z=4e6t!y2jx%-Q8I0 z{^a{}v~9+iNyD|Q-7=f)LXo#J*6$|Sb(e|t)P`n(e1&8*#PI^91l(pzAX6wJRRzU4 zHAO+uvUPP)+8yh1Xp=kM3OU@b3>HDl|V`A>Nc(6-R z8l+|WbKJM(L3e*#!Uray)i%FljPJd_{NEsLGXzDW*ZAvgm%pidZgfLbutH28v0JaM zu6dl0;}BXA@^e<$9v|&IPQ)O?XB{B!D7HZWS4`a|`g_4X@@4;y)VxH#w)z8p>)m`i zp6|SE1=Z5=N6(I`-RRd>KmW>ipQMGl$pz)_?RMARetL2Lik&S3X?VYy-8or>reKMg zH7=F>n3dR`eaf+&3Ha6xk;x>08I1c7{H%+9!Bitk8AFvy(JEXzV z^6>5AM}P?>p6k-!Nyw#4b^Wasbo{C0UKdiRf3g06dC^ zm8^$4%qP$a;7S0U68{cuKB1rz>ituF!i6J-d%{c+fJR7dCD2+(>~Zy=eZutsg(n~{ za3)?KP+&or!~RL870p$e8^(lCAs9Z_tr6~nP&m+k%1#ij*o4m;>=#rrXXVoR0C6xM znVNUGAYaIO0`9@uW3wK!KI`T}+kx$i#~VJqmw780>Cyq7lJ9B(GEonCT)!gE|BI@) zmNNIZpW_?L9>CXq{5gI`NRjKCElJ+C}6ZDtq_+Al&NcB z<(wiL{22%QCXlT+n0{znL&qt2J}asP?|Sg`4)u-X2)(cD+towLD8wao=x;m$_=4Je z^jUm@R<*9^&D8Q-J&=bA0mwxl(o13Xe0t!c9=Klgdc1c>?1K;153n!N&g@UvgAWL< zaJszSJszHbTGO+P^WtIU6++UE+wA_^4mTy#L_E5G#Y8S%r`N$`{G{aI= z{brN$L^*v963{XV}vQ(wWH ze{oKEt#bUG+?wg3xs~=K^VHwsJ{;r8^)%Pw%}%Gw;A8pBIL(#ME$rR_`&BD0E1;_# zfPW<%KAU~g7;sNM_dFXHc(qm3+jydT68u~bQ#J<33bjKJyXRxEDb)paJpg`#`y%)u z`yuUv=HEvkHVCqVZa$vzI*E1Ubrd%VUiAyM0rmp*!tg2lVw<$Hc=*O!=q>p{cTLk% z^Haxws6`!jA9Z4vYn+7qJQX5(q~Z65|_2VOo(T zFh`Ug@R<*^H@9%b(s%5d_9XJ&0?L#D_>*!N>Lt>ZJ|xEy$m+D;ceZu!n#zZ_2Xq^@ z_xYc8C48_SSorY=|TS%#5z7EU7*EG;CYTjMo|0nfjjOqi5zLr_>fur7@*PFzgNX|g`dLUwt)Y0KEW!84rsN7{?+ao zpU-?DMDd8VBX6ez#c3-HJPYUd#-0IA7(P{oq`K$o!D79hR39ic>qDFVM(>FhjTxes>gS7nm<E$6AD6{ zXG4Ds71~7aP<{trUPvXHWN;)bU3aXll+R7MI<0s{Zj6LThI8b0-Jabp}-8gaGGM9|l zFk!RwN|(x1r9yScQtDvDUTOQ6@%(t^ndu@yj;ExN{Oizxyv#u#qVEwFy(lL+wuSp& zqzOR-F1`_p2!x=RXVv?IG{>x2@ssEW5mJsT}+pI9G?`atp8A&iF(&wH)3* z;{)vL?X8afIKpo;ZFM*=1g7Sgjb5c|Euq+)DU;sMF{WT;Svkb~4HEuSR}H5OZfsr7 zH$o7KM#Xvs!`2$j9W+%0wr|r`>^|smyr)V#Mc3O)oxvZQxeUG%Q)sZ?#wRGKfJ|$q zv&=$QI(!3M#CoFkrSUZeoGamMp(`)cNZ6L|K2_n^(i)X)C?U{3wckQLvrg|t=xn@D z@!4psdl88C4j|tJ4tH_cyF@8$NR(u(X>z7s!^Qr3}+IhB*SFw@m2_7t8uuY)=Nq&tu@BW`i*pGsbeoI#>v! zEd3c_SvAmn*_5G^N)hm7bs&rnS3?Qb9zZV>1D&-+=YUGGU6Ri>mPyc8;A_IXfSq=J zJ*@dm*o4sbX9Pzit_(ufh?(|3$dR`mS@98FkZ&kw8seX(V;|X;M_)S#e}X|zgtG(w zZq=Nj}r zP5oi2iJ1IYa8^^EC^>Vq`9z=dHTnoD?gx!huievzdoXeAG*~0$W9)GvqdUi9XRS8U zm02Ec)4+ljX*UB)_fWGOAvJsMOt9^hcPwD<<#pXbFarvo z1&~4JWl&a3zEXI4YHsHm)9P0Mja3h+4&2OCcB_G~-Sv_lV6WHVwFC+Gu#}lr{o8JLm>o>q>rYTj~3B51g8mP0L5rk50Q%=x;g+Oc8CY~7oHG{(g(3lq2*e|+JgYN zraDqz9X1I_D@x!bm3WLi(+g+@&lD91a-x);L4p*WCm?aS5SeeFVQ&z2JQCR*>S)dm z-J;wQ-QM&{i~Lf7mxD8YfTGF?`wOfgL!EXI-_BYRK7`T(-ySJ>WC^@heE04qN+g4f2Zte5HW#&ZRk0vNqA{2jACeBUVJY?d>Ehmh zcCQxL7F1WQ%bP60hK^aqOrQ z33^bk*RhzJDTqCiVd@Ol*kPN&Bky0*6Dp?>~K5(GZl0)3imRM{7esomcY;MLu zAaVipQ2bn6vlEIz0MncF?JPqup*e|1lAbjnlPIqnqc|Fe>2J8ZgUa&ThxHAyE_45xD7Ti<#gH=txd+-W_0(T-6p03c6ux7b`PN-C1} ztc6Q)Dd!~TM@s8qe5OQ`ylbxRkgL7~Nf`3wF~DYW*NnX4q+2fNA{;s@+a+2TSS`6t zE2mBLr0s)e!h+4CQEmU>FdH-mMM7Vs2#+J~m0aGg9Z&S9Ku-vpEz=3aNw|`+WWB1M zRHPejkzN?_>eW@&3xy4Obweitr`c2Myb*2fmJb{boC)0X>Y!g-*N2?rgX;@w9xfXepJwWwM5Lu$#Kw9=ZZn)3U)kVyD!-EXuD}k{7m|YJwN7b zm=D+<#JVuwbK{FGiU^ZHXns@ILmA9O0Il@~Q=won351g{g_4t$7-bz}j9BfXC8q6$ z9WsG8Hh_#u8lrU~e5%r4lfssGDYVqszc+%|Vr4!)b=BrTJ21eI z%|XlRfGXJrB;)|_z1~u~#mT!QmcoZY4bvp4QpF8*(Vvv}$WMRdmWim7T9|%z;AGN` zl&ui*OTD;c|t>7tSiWtsoR83(p3>PvNRyxM%k;qf6w+4<6C%yt;Bsf$6$l&prwe@Z= zpoa9mrkuKVRHxttSD**QXj#p%rJ$K?w;n+7n~WOmiwze8ju(TDPInGM^|nqfb;Kky zv5AdaTpxj~fi$NKp-F0ca?2>dC%Bcj;Z{#*ny%qdfoq0EMhr7q7WI+%1k)T=IHA@b zz6S5PjUG@{coV+vW*I!FvBB8Kmr;xA?}})zJR~5KE?4S7TRPPcNOxJ8+?2K==mc2N zTO&bx8`ass;7d5+QS;zisMC4#Y$IVFW%A?!XeOr-tp`a49mr!28`nM-<-wS z^$Uz83}i!G#=`Z)^|z~I={zM1gx!P31~`tviaQR35VUaouyfTR6 zfI_%_3Cio9R`RPpAf~z|CThhT0%}1)BOL#fxZ+;XOw&f@ z8U-m~!iZ@LmnJ6T5cqJ?K#CW0998z2q)wdx)olze-7eoujf-W$-5QR`B-l?sgW13o~uNR<%N7OVlDw3z`eW zV@nkx&WD0EQqTo}2&Oaeb=)KK#y#u2-oZk&keX^~=oU7|3crqR(`#Yswx3ffA_Lf!81nDhd|ImQ^mA z!K&AiX$0j%KG~D&_RNFaqNgBvUx(C2d-3WqYRo8VNBpiX)&bfs=1VqMgsaY1xfawz zx%cFtM^7@0S~3$31ozP!U$@o1TzX$vi3l2=A3QD0*L0jAsRoY^}rX?*8cB24L z2!L(?#2H1+6Ec)aX_W7-@b5~?BKwqm z>S$Hq+ZJxEnwldWI5w1IWsONuwpyz)7Fb3v@51;O&RZG6lpypi^}sko>GH~P_%pS= z+!ms@l#>uABDda+-AT7uN`;6fS!LqVO;pjZI$j**5ucPE&mMUSyXfswACgyzB&~FG zs|RaiH@NzxyZCmx5?RYLsTeUcPh7z?WRN(nehpP}k%D5^5aty~G;d2oT(Y?&F>g!V z-zgAijTsTrX7a;^F(XMv8h{uSnP!_oU`3GygOr}qLxs8G!+6HL^?@A^j~_fd_Bq{L zyuMm>0Y!z?BTK_ih@8RVK2BMQ#^tZua18JuZ4S9rew?|>a!Ft~7`R#=rHHRmxEO=DIfQ7ZC#%+tJl6i3!L zM_z;wfaMCf&R#L>#LX6ihshU2QDEQfR>|@Sqt4;nIItt6ZzB~!0i(7?z!}n(QtC;r_?dYt>UmCuai>aI8|4F)2(&rA zR(}-~q=bUn!WkAFz6}%*1GoBg+KInS_g_BCv!V2SlLyyUnVf!*h4(`;k>y6L(3Q@32n(zQkbaoP>lV2BTZqO`Z(#)9xqze}%Op|0$0v~Ng3ss?dwq}h; zm`D~BcwZQ6na`U#5}DZnG8tTf7SkgZ(1-)G#tGa}`|h`WVwvt`Owa&nY+sn;V>Q)Z zoL~9CR!pp{W?ipfI3?F!`g#fqxx%^UgbImk0*H64@au?>8vQI!}1N5eMA%Hy+(v4iAM3$YdkE{P%@{PINR26p; z@SJLE1l53l8AZ!e->AmLP-8*GXYcbq@eciW%5I(NH6xmB#+g}1%apqpG)ox6?$teF zqE#Nh$HOo(g@74f=_sl-hcP8S0#J5f5}+g@2gV0<`v>ss#${JHG)QunI6lOi->!?_ z&g09$G|v!omR?|3#7+3VkU+lro4|67vxD2@U+&BBi>mBnpY&(fx2G4lSCSrc2b{GG zdil53S|a01pJxZ!h-nioKKW460>Ge}Pw^pHKxI^15yX)E5ZF8^U^EfiI*@d#vJjQu z`5SB&@m4|~1xKUneA>#cP8D35$WCWV=XT}VmQfPuW_H`mC+t1n@3O^n4yy&wtM8=C zXT$EhfXu=ni>hJ)_W)r;ospBXAdp7oQQI;e z!23jl@-r2d;PZH2D1QC6DIvdacAS=XG14LbY2X$c~!H}Yz4@jMBBP7b0$SiHkCCODyDC;)2JHe(tXRdw*Y@Gtz+ zvEtR6(u^k|>M%q~^+%F+-T|vbd7;pdWhI1IzaPee#kmegK~(HUg0^gcpwwOe#BN5) zIYia@xD14@x*B!KK!5fEWoajGEq8#A90O3ABGfaJJ+#5<#&rddsWUP>5nn;y(NnF7 z?*5)g-V9b#1uP@I(sWAY&!H@xx-zBw_)9$OuS4FisGussxKcUNIiKAuq~A!fEnD6C85oa33Zr zj@@{9DNu6R(Lad&V^|@{Oyy9K5x=Y#MfO#ru;^3v6N`(_s*a>>2q7x2+pzFejEjyI zqu;1VgwC`aYHV=ijD=(SU#%|0h!^8W)pet z3IfHnZ2G9ItH!?+nQ>ay17UU6$(1#qy_mgR&n3=KS$D)09u3x@z*tz4bDeWZ-0dD~ zRdrJcMZKgx%0#BwkryS9$9edsOg2u?B>lOD+HnVUW~x7(nbe+tT2hRwK3wSff~7o( zdUv3TRP9971iCn8&Gpx-)*m1a>Cy4519nL-sS!B0beu$N*du;zYB4bS9ED|a2GL2X zUihw9Ug_)4Cs^_NjG*s_sh`>NBBU7|9*?L685r@At3cTq0o1N2w(SNE6W&FIlZ2p1v>5>8wM#B_px&<+icbt+L6QF``@p;;-0@m5X+ z;eE24t!;%A(>B5}jkdBX2e)Lsx_(w2-zvD>P7PgpZ+Lz&9RlLg0M@ZyaRrM6Oe_YZ zkqwJ&gFVbPw)C+iI~G`<^QuGZqhOLvx7@UMzzu4bI66cJ^aB@}!jThUDC6m}w-4Tk zaw$dfz8peF?O5);N~%|b4T_4IoQ{#bxY@Lhh1t|$pXT~kUzmzo?4 z8PQPa)GI!>cA)f&4}&0QELkvQ;)$q{f?Epe&J$x3HRuRmv~W=(=ul)GlIZ;*2(JE! z-y1^`0vLJB2x2NxBPt1G{zS%PTZv2!9G-{^49%FdX1Fqhf~m7Kqzb_3po9Y{Rpl$x zl+!C;uM6_Lokz+u`037rR?|Q4a7>m^rLo?QLkGJ|1%~|g_hjA{`}uv{s+EZ|{JvvM z5mWpQ^fsc4bK9A=!IRYk;;WF~3c;Rp1e_ycv(&l5XQ#{q#3|~eD&@+p*Bvt5I^D?E zPvn_m5dDFBe$%o%sYth#AaLSD~yNvfV7LG^fnE>IDK_SXsTgdrI;MQWk~% zEl}~=)1Ebe14*tUs~}YtRlKN7G|mznyZ$tgo$T}O3MlBuPAHq^+}Rg9RP120wh_qd z8;9wPhLIp@CURB(WH&CrqTR(8cwlvz3*}G}fYpjdac;vbZ7$$JGOI#M4>6T9gv&`n zQLWZ;om^bXM$ITs zWhG`Y=iSUIP*bEPmp0YRhIqqG@%7asGQW z4<94bIDNgEt{DSQPamnVWWzxdb4kKY%^=n+fNbcZK%pP*zFQe2tT>jxlRrC1_(Wu^ zg@K@{M1f(T+m9e*NXLV+h0TYQ8n*Bf(s%pC1NMTd#_;O~e$L$SHz$<_eFL3%5d)P- zoX8rdiF#$G-B}=ouOHOX${<4)k&-K_3qZer5K%pLuhv=NI*8o#MV%nT@XbmD-JyzvUa{Shsj=zH<+v2+6sO_|JUEA7Rfbs{wVxAsX55 zEL^}3-dMT)(IABa2I7%FG zVcU?*hTVUU%{GSbXmIM|j!C8DlTyGMz$)ib#&Pp6VxbiG{*I{`vg=}4@N)~Hemf89 zR0E>)S6uB@7)tH94F0NG-c8tL*dzq(?=*TUP;ko>IS@Il+Ohr^*=aO?tM$5kBG;m_ zUQc1loKnZ2&|Oxm&$C#{y->d%nYQQif1i`DuCdZ<%HP_hux*BZDM3Tj+8Vpt9;GewHNan|IB&ECXaL6^&nNp+pg_l_AozTd_)hj zd`uE#wFuA>oh-ZfT&EaU0V)%CVIrO^Fwar>Z8{MttUx(6 z>2z@X0h6t}WaV3a0W$_yxuZ0Y`JN z1~_I1jFANmlMM?~tqKyt`G7+?dj5EJ-hFziFKabf0E;k`1K;7_8h*xqe34zoOr+U?0Yqjs~Uoan%5sK@pEm#Dkz&#h{k^LEc~55x0~sTApDdtR*N^I((SAmA?^ zIILd$P=|a6@ql2yvtu`>&Y<`9%%C{y+@k|`OY&wII8aOwt6=?NWp5R>-c4g=>iR@Q zk7TvrVdG&!R45JcV6RyCUm`drACkc4Y#40>$Pdh(T)Z-EUS{M9O=nWTPuLvYLs$>k zE`1|5g1!XF;QN^SjahxCnhGPTRK-H}!^`G3j}#HmAq2HfC}Lqm-o)ZWrNrh$4GieJ z#6m^LLU5uZ#CO4e1G>W7ukPW@-%-lipRxe1Nw5`^`$}NiCENaLEa^7utH&$!Z9unV zb9Cs-D9EXqen;nBxgX~@U4YMc<+s@@t8SQBQHErqh*)t-N5~Un6c=q@#S+VW^;LMoIg45!p zS17smV*VjT2H9mtII7Mau+q#F1+uLJh8@Evcv!7)B3p*m{3bKIu7*ih>k#6@;M(6Y%j8f?3iS9rpmg~{3TTk+1$)hzJxoo}b1?IQ51;Ag0 z!4whC+&S)9PIW>1dBKidhwwwti3ll0ietw~rHNJXJn1Hh_JqEnwL#?(>}<25Zt{6e zrMoh~&P9e@yC%SyK>IGhe|OTk>8EJ2ACOIBtE>)CV7c%Gzs+ppJ4dAs88kC$s*C5< zc_A*3+nm>~YKf>kg-}u&-{V|9iIb_EJQuafs~GlTQ6!{ZT`-wGq1sSnca9Elu*sTY~ACwat5es=J)4s_*~ z730ps4HKD$za8*ck}eRQ&wl8V5t6X-%!{tA@(i%>qRb^_73-zue4YQC@@Iv;^!WSX zp_92qkUA___S38RWW{{H-G-|!@;klbj7Xj6Oc)&{Ym=51-F@ZDa6*NQ-K4xLcI>iX z{L2yl@$V%&jh1h5?|tm_)|^Qb-F~?f<`ks7k?OpG^=Mn6WH;yG_Zi7RHD#?JxSYV3onKYRQgN*!k$jmO#S zjBPA&()+|Zeo{oFQq9|(NM@s0ud?vbw+)$&t;E!xY`%E1yK#3D2=T(pjPGVNBdzhu zJV~w3{Jc&9wYQT`&;5Rlyb!#$we|{ zU?iEK-|A>on8m`(9?+JT;CX8UMKI0jt^vS>%UiCrwB6lp$y&6u=MsLj1g~;I7x;bI zLV*Kz`=p{0!spjU$$~Z@-2!!Y1|E8aNJY5;Ws^Muvy&KRf94}=OLxx zaO;ZrHRl_f{F(OHIzc+%2uRlGl1)03*8!w1AQf8zSdLG&x^`gWWq?T*0LEAZm|zhQ zNeKG-rpIC4i$NjN^JXWzNPi&^Zw{``yd5HSfRaHTsnwm8YbYD-(xwp~v>bXmOWv6K~rTj~8WAl?k zO1Igi&^s^37LsM9g~q@giu z{l0A+joG!G*W{xGviIj6cIt)p_!YXHo`WxW=R~*jX^iWIT-PAynNgq^I{i)S>)-YH z$vDtrhCehA&N_DNx2p7FN5fHbIQbp*v@9!^ckAf%MxW4H@gk|Mef;c;L1^`50n`Ri z4_LWo)nQ924+p2TyiDbMQzkhoRB7~;a?A@sR88zI6hk4Y^o`2&-tpb|Wj3!3L;%PS zkc4v?22W&gr0GL{^e&{x!24U9E=XgAPI3T?fQ^jek`shwhJw?tsGHlC~hX}H(K4Se>GF{>o*)U6!eUzMWv1?Gv<%WdW`=( z-a8Lm`8x}%FUa*lsuPCtlD{9=d?&~mjNQZ{68jBy)`H3(^6)}G3Ph+DhUnr2nn-o< z`$7-E0XcBtlzW1amef}4!~C@5Ik&BZlpkl>dUJxu-*bE> zd>RR|%lR#B-rX?SG67vobBxR`>C|qiazq`smQ&xk_w2P=k+OB7n{A|~p40Y<0-aTK z%2O^SjmCaG!cbEFIvYegx4Bspo2mZ2xAUED2hk8aBFa&U6+x4mR< z@khzA>PLmzgv0?tdyz|c)ChZvNoqa~j8GGlRVJq0aVk4_xXu2F2WY$GNUq}GP@0^Uk zXwq|tnV~hQf0oopS=XmQdlMZ+Fww+tWVw+OFIdMI_9anA(?U6{nd~rGxENNsG8-5r zjbn+)L1GX<4ZxevU?N(^&`AN@`zjGKt4S^_91FHq8(oZ0!TQK}y}2WYQN_o9L8Kpbf-XBy2Udk$UEje5~yRiFcmHf zpr`p&SjP@BC}Zh{9x^E9T-ImA$b1VFDpW4O1K#}@w%;fg*+`;N6!%sDBjLg&?kI^R zP4;QB3tM!jbvt_rN)WzJG)U^}R|U}V%(Ll5BE6S2`ie6YGLxR<6mTg>=8~_xkw_y) z@+nxUOVt_*jHs=FHU&Pha9RJSo4v2=TDTDKtTksuutlg@twFSb6b>=oI@2QasU>*k;Q9_7Fh@0+hTE2 zF_^*3oS6x}_4YPvtK8dV``y+4&KF8O&iy>2?Mm-VMXBTV&Wr7)zj2`RrtsY19X+sm zwp7^camJkCHhXn^rQh-7K)Y+de5&7YoZq@{QJjagB2L@|UYdaq`II+YV9u~lzd%iF z5||9RQhudw?21*JIr;2yVY$I?c_D$r6F8%=>{>$wnpob3>KSYIIzN@ZcAk|c1LTC6 zO+?qggk$0tuaE6?vJ}HYzu|PeSb`pV>E)z-J}#1>ulyCBqIFOj1C`=l+uE*MI^&WFc&vt0H zlzw;?q`fMiQQTT~Wp=H$Y3P~kt3tXzMT?eS)M&y^ty)iosw@;zBrnZZ=%a9FdN^oS z4o3WH6m!%G6_<6)`y@b6-&S^#_L>u7!#J{?;$`Bug$xZ+4`X?tWwJ{XJ^Y(NyQ)go zu2BvP`a;x`Q73P1)i_$0FzNgd*Qo?AI{2>ePWg`gkcl@#^I(`%9C?O3U8R6;EVY{Nis6vIU-QWPl-MBM3BxwLyX*Zg1U8x)vZx^SEdR z(3DdD~bFk~xbJls*RedS-0T?u**?h)V+b>&TTKFSe8yo$bDf&OSN^q8+-s%;X5$Da;xK}- z=MRi3?*Lm!R;s-#$58DYbj)EWm7H^}q5dnmN19$y!Ea{YNl@UDAX%O+BSl!LU9tqg ztVD4rC3f`7qPl`1vAtj6ud88^i`1ZoiNJ#oHO1or5KJ};%w7Y&CJWQNDlasqKVeDL zBE~rFgQU9H{dTwaOx&-tm9CeJZvHLKyR>k>-<)p`?v5)f@LRnj{iO%6_6!}6Cr zK6@TVf1Y7B8;n;{>Gzi(R&IYMx#p`tBDwF8zz;@D{PD}zrBkf9TLX~TP|8p#`PH|9 zk|3gj=qj?%-%`P~_*s!%k*U%_Z5$4jlgLy2R&tP8u`S_O*g?>pr*wLPvb)QRW*`!E zf4?A;Q^$E0d4j4T7?wR>2;eB)lWy2UUHI;lFQ7n}CXOK+o_gAsa6HIyfkWR13Ss@o zl^Z*^S>-}n1milc6MSiUJZnVE z!uYJaUj3^m5Jdcwb$Fr#2IT(_XZIW=NtiZ@zHNKjw(ag|+qP}nwmCg*PTRI^+qQXn z_U?YW_r#uaBkms=Rhji7vnt<=%FHL9A7)P0@8K%DB_b|UJ_A!oTS+E9Z%(;!&s~3h z7M?=@y9J{_UEPa6yc!d%x43c!J|5ioWE{h$4snjRL=I?oxEvz{X4^cC{PZbf1R{=M z-*>ePtq|Nux*<}*CEa9|@iDHCSO{jdANC!zxzXy@tficllLZJ=LF9?RGi0=DIzjrn z8oEC!f70;KL`~1Gd}qaJ7oP2nOmN8pw8!{#c1UY0O8kJL0mx@=RV#U_Jxv!21kYY} zA;RVmIh_UXQfDS>CGyGVxLsf|8jpC-@#Ox8x>ze}@^(dl@_@LYl^S|muWOyHu9@z0 zVol~=nO=&m1#iFTUQjHnzhRM_Whvbe^h)A7mhoV~JRH4AC~(~wPs6u=|N!4MC6Bp|Ty{pTwf^+_e|HZ&>&w*Os|ero z)e3$pZUg^J>Q{w$7|SA>Y@;bBG=rzLn{=Lny>DFt-xnbkW|SEnAr3B$uGFs7_RkEY zYwN_~&Qe%6{D{A^eSE^X;wq#FCY^YH7WasV;~f4eP|K|#42RsRo#&AP12*2Hrzd;8 zh>t8}-?Y`hX2)vB+wI^#*?j`w$>|5&*vy3x6$Gti{!Z0{2BLy0ftDsE67rS1g$Du9 ziqg&(UC0kaJ~@#7jMd0I2B9KNjxC}N%2hh!WKr{&5x_xq+yX%uIr~RopH2AL*`{4F zORp^D_P%troROY;R$I8ys;qTn6`Y4ezc}-WAI*z->%2Y)C%)aTljC=aBQegzy9EPUKw{=X`s5G$}>D8 zH^jT*U0uM}B(y2KwRH<-6I7*|yNSEWPt}DAa88>q?mCXTtJ%Bg30Ym|rB+VeqVlm* z!@hBo!{4QJsq4)LowBBdMlYl}fez~gQEnr=zg8oYH~+Lt=^IPBn;sAylMutUjor}J zk9CYWBClR;UbPI}l^i|&?($?7Og5$bkv(I2o8E$eo^l%Pk+=y%X{e@7o9PWup0kP! zX(X%pTs9(~j&el-4bau1ZYF@s7K=FQ*fws1pL**Mlz>~cvUfwMb!lJ6doFZfoD(S2 zi`z7l!(Wm&JHSy>C*v&fQIsLiMMa@&=P79(ObOYfpiy3!tfQ+_=GXs2Osgjy=+LOg zd>Rf1HQBr!W_~CO9sbvxH%{6xG7%(WGVq9;^bBuZwxVX{0vhTYG?D^73@C?~AU0%M z$zyy=hi6cj&ORf?=aCm4c%5sgSXzVE<9W~TK|!hCC13l?y!Nsm3%n1NN^P}ViY1b? zql!!j>3X}*Z|4o&dmoRT@RivtRKGm=2;5%+Q(zl+U+pm7Bot4_mKU%j^X|Qh!HJLh z?nSzvP;=4VRnEC#Q5tHe#b|5^)q zz?H@6H5p#qgTfEg39T7A3{BUF!N^q3RW+yu|1)4Yl6DTV5yQ0K5)bX#O78#*q}xmy zmz5EE;;(&Lt03;%s@Nz&ermnyUXsJKqC_njeFI&HMu17kmt z5mF4!WZXXV8u5vp?NTMjru97mpUYU*9;z-<%ZiJLJo?e2U^@L&-s5$nT-KKK3B;ER zl3wpC3L6a}9SG+!twhv8?~`-T0N)5-0ZboY7qk%OZbfg0p0_1$5bs%UECr2s4@=`f zoOw|k-RGK_>1kAm1sU#7AP&zJUJ8uYb$1NObkCor+Nt1CU@5hBa~gC1%?BXUE(M6q z3U4J(fwy{P17;QS>R?s)h0&Ov8fWwd~UM>42)?VL#JHQSNc z>!LHz!z`t9?dZpcqY!VD@@cW@h4aWOL5ZxcMeUWc!%X0l`mk||GYd)yF5=9|=~3`x zv!q5soIInrtUUt+YyKp#t-ujqE#fwArhZjFguk2KI(t4eVPJTq39Qpfhc}@suB=6t zo?i(6LU3h+-92D3SHEm+Y+e(;$^{*ha$;k0#V!r_$d!sOA3smyTIOsqUnwePWw9=k zw}8TWn%Y8Y3{@-?*W4@-M%3OI$ zpThIxHsAzMqW68Jeq(+En(ZamC0*`1=$D6OtyDTD)QH+|4AUx=^8^vE#3KECRPEq7BWE%04Pooy zjO8JJ%z3!pyC>csG(xKqD_JNYNwvjlgOH&z|%T{CO4skvX;+f(DyrO}Xy z5{0#Fir02bMoz7g)@^PL{>&Z=yR?u=sF>z2kDazJ7u34PYg$C+oli1dc;*ocUZEfC zP_BopHE&>^#976fz_aZyQ*o7W3|~06_j}D1uM&a3PG8mFC0#9CF5uNu4cGIm3!@p- zA+zw9nbd>!D^uT~xNxkb$83)$^Q|ws9{j2L<$b0ko+(}YTQ%-pq~TC(d8E_s;tI~| ztO(q06MAbfyyc?nb28riV74iq@#5j3q|F4oh%GM}}Yq5$2B;>{-FAVwNk5eN6CdN+|}=(yQm}9<1u9 zu=BoM_Xwf46^+aD>lOXDxso%s_2B-ODnRErBGiqRHC=j=`D~&mAY`M`lwaYwl8t%d zbioOG3`Wb!MpG~#V-llzspsO#MpdVy)U1->pk3yNs!|{Io#S426VJ(HRjVw%GAG#S zLVYXT@`nIxj16ZFo@ubb)qm^=9LHKy=5rG*DHEd)dP2wB5vt_iYv8l1XetdIrP{pjO(XqyQxIC;1!=-NKy2&_qJ!Wg&I{HHGDE5%`{`utN zBUF@7YRm~q#v;}(@YD3CtUr?Bpc!+Tl-NM2H)Y$>PMxIR70Ioa{0$CRcyDoix?4&5 z$Z4JMb2S}dL9we0rdo)sY%CNoZ_*Um?VYA~`^wRtv{<+iFPQe_UBD8ReloQQ9r~0i zpfY~Zf*wdyd}4K!Q2G_i4~B#v^W2}nU%XS-;U#oEZ|(ax%#bPvqC_s45)@;mKMH8^ zn^Nw^ppLyGMingXd@P_{LhI`J@ns$PGt=@xn*olQTLVKmDBQJ<8DRWbpQ&XCaVZ=f z!yRHBG)B-UL5+(OlsOYX%}oXhzAVS+B3%3K1@xQdcn_S6s!&}bVN4IJoi3Z5l$D?8 zn`@U~P+KfR`dWRR5Jh)q|AdB1#@cB+Bv|tCC`#MT$E)%jGw){c3SRCZ*%MlRDa-vR zD~EDShUJxaI!-WP9Tw^Dn|G33Fp3bV75!5h`+F1FSz`QmmdI7=X9eRac~2E;$g}2S zX?sp#yZXt)d0X#~((aUiTcN`%o5L|h$+XZb$(vR?43M*fbgpaGw}3Q4Y!e*TGoWji zNkod?7k&42nOuhh>Y9Q8=5e>Ci8U2hD=UUFE z%oIz(8`Y{vF-Y65H(UR9Zg~;-_;w+BF|~GJyZUAJ)jhd-5fDSwz=W?;`tZ{EuH@t0 zN!-P;SOEW~NBG7gAi+h!TUZW0>#akv(__%jAW_L+FR-!6DN=G)YIusW>RTL2IprcIwUJop{POK~BUm{=(%VAM! z3da|<&MRCUvX+x>TMwfhK~v^q?FCf`P%$5nxNdw-c`$Zmyr2#1N*a>5t~)5W9M`H$o}-zK^KLYTK%Q7 z6kx|~X50%B!iwBa!A;5zLlKHFhyWO|k3Dca35rn4h|b|gF)O*Nwu%^#H}TENAyD3g zdAJubTZ44To&g(KOU5vs+!WpTp^%U=IGwsMOSm{Pt(P#jq|U5FOd*M91aAow6qa@# zB12|E9HFEDQ*?)r5x$uVL?wGhy#~Tt& zWbA&R9HNX6cf1+<7H;Hj7D6e^yWzGk1k3Q5bEv4B;gFVAPv~RPAk43u?sAr>rh02JzRr=P4 zJ?@2%c4;?j9?RK@ProWNhKeh{s=S*%cFO$jdZ_-SeB5-kS?~&z+>G-)b7%={a-+le z8dhsj^yrGxVXZM!jsQu1pJQ5R?E=3v_sCR=18wo}3B##n@rC+_CkPWLs$WK9ypSAa zzYc-z(`&K(7Md7^byU@QDIDi{8F->&>2@+vQ(S7^8LSDkjl;w^aeoQUfz}eS+5e1L zcZNtn4Ha!r?zHQq*}{b<=~bxPIKK{N6(t5I{7x_cfs~`8jV4R%KLSDe? z!3N?A>KfuAimERzh8ZDrOElu36cb4TB}uN2CsA{M0Zw%_Ljyz1y^MV8!R@e_uZ^+4 zzHII4zK&f27Vjm?h_V=J&u(6qX}uFRfeRUWXQWU^jh!H_|GX^6cyiPHqe4a=!owFc zRTfHtTAE4YCk1r$%Q=n<7-?CUUd_lpt35#;oI2=Pobx(m4R7Cj4Eb_*WK^N4LNmUw zZYTg)d^7(d@Uf=F(eM&apC`R`)mqgsBi1Pbx*eS{bNEUMd8D)J+yl-HXqc~7#aIUf zL!TN%aeNG0a72@dkBK$8E;~uK zQyXYpSRXoe93?^rnS=v;ycnEb!ExL(+%?DzN%yLQ4_a9=SPdsFzbDZE;m-xYm!*#@ z(DYE}A!n&@0h!8grS864;1}I>4!_uXO5K_j#_hZn90i9UZr4!g(rb}-)Kx~WKyG!N zUCFgrZoORmMS)s5Q_S8{frF;SE(J@g4I6dk+JuK?WNow`pKPhBFrmJ-8jebV9J4Ie zz5@HUst5~30lXi>nID%nHy$p*(X2Ge*$U|VIU$F8cp%smHc5EIQx4Isz#&yn45sKn z1JBx(Wvp9*s?jU(|Yv+MY-SSwQ8)iHD{;e%qv~jU_Y&9K~r!aDCqla zX{oCZb3BrcM^uZasInh7NQ4AG@K=HpvH}53t7!F-r9I?e&NPEVp+woVMVwIXLfOJ@ zseUV1nTT4YoMjCNPb43|LV*GM&-`wMU=b?X9G)>s0z-~V#B&Pqj-VMyFC>xOc_If| z3=XH=mhHNGnu5o>U4jgcORtMy4M7`N6jEhKga(}|ba>-TJ4o+>nQv_A8J1+cld7td z(~;KjWB~k{nd`b|M=^b_`5MJAFaSMZ{MOkch9N=*Qi3V+t%9o}D&iO$O%7_$YWS80 zTC*w+?A#?==|>IskQcbV7a5R0>eibQaW4TyiGCRwhxN9zH0GBB5{Ka<^W8=9y-aqZ zeF8Z1{4SGFO#3>4X>E`woT+wBvCIH4xv9CPSR{EcN^>uzBKfY1yH?aV#-eajva~C6v-Y>PwJs))iCC8p?5+5h#=P?GZ0fY7B(t$Z8wd1tpHtkb+4smJTTaIV z8a4YZb+0i^#Wi>caK`l6>lE-B_ndUQgA?7+k*p^|5mG5!rB9Z@`W0~O*p<1*RBT(0 z&4`gd=W4%g1@)C;I3t$OTvM!mLU}W&3do?rCZE%AC^-}uwF|vCdzC#e9Z#9Hs&STK zJ4YRCl(hHQgYX#q5T*0`y&cx$C!Va7%i7ss1`@4Dva6-_p%au07phgN#DVQnte7i8 zd%W|N0PuvyCS@%W>pykp=?3ykApgmZw|HrfDgxaj0z_OYVE*L9JJF>93gzohkUxeU zc(GVPgc0==cI1J1e-rtX3dQ~?((SWsAQT^XnP*g~Fi2lQoq%fO%<&Vgv029y6vm#2a6%BwN z?s`ra>hxG14B%$WZikI_MKvv2dT5i&4AwZDY36EMXK*ALcGk1P6!}Xjolvxn%4 za$T-KTQV+czH`zdY%L)I^^!NQK!P@y^hS5t1kf?#;}5}gA~)aJ20TXa$?(N%vO5Wl zZVlT(;Z1$sre{yZjBqkjOC2N^N!ulF1bw?Qe@SM6(}+th0fR&58mtrS*IPR#%X3lC=1*95t(Y>K@x)?B&+)HmfIk^DGw`(Y(6JcNapg#TV5FsUhhC z?wBKsm;5t6aVYN|H1aBF6TVrvtFomy%UXI=m+Q0Y$y}w~Qfw)FJ2N`0AZtUXmsOX?1*%XQ;9OxJ z+pO?XN>}MDh-aoMXv|U4zZ1TxbFxv`_9V-f7eb&iyH_Y^_yFKw2j9cLi=Ww#0@qdj z0zfX;7qv3c;QYSIeGW=#uhHtHLg^xsB;u=v#Sk>2nTSgUt$|$yT`8zDSpz4U^quM0 z>#TYXLPQKTi-l>xR0eQ)^fV1>r92oqe_&j!)|Mzt66+qq^`ozAlD+3>yy|%jE9q*UjqCm#Ut6?m`%OdUX8Y-()M0M6Q6>A(I(Pm1v#IJ} zd3Z)BldoSmMcdmQ%78A=6gsv<>NpuRl_6`(hVc%KzNZw0>b5pitXPACy~Jn_z=aZj)-i-TBB?owcmn?^oJCE_w$j-!x;<0@gd@+fccULdL<*P~ zDPV%QpAjQQ_dUrkT7ZI>M@Q)uE^`2>tGw^*37eO^snpYC!60-3U|kjC2I`a3Y3#>@uy+ z?0%!bbWH*Sg@AER*?_771)lBd$Uk0jGDn5hs8<@+#zMw*fY_r-j2^tk{~kbZ@>?!0 z1Io|VsJV1>y!{AoO_(#}>QY@!a#zobV5dZmsh%qb|GW$vOAGDd>U`+lh25Cwd-B>r zC%b&$uv!o=eSa=%+|4chL5u_#gJsWS|8k)k+RvQBzz5_m??B!cXePWp2) zy6?;ahrwPiJ@_s^6^yP@hk<>%WQvt3jy-!#klnRLgf`6?Ast7h1dzRy7q%&=frv7| z|7In?2MJjM2XikT33?zM&y-2Wm<*COa-Van1$cuRgicfHL2#d~mRX1JD~GDBVnH>^ zHl-Zqol=VP?g(d90~b>D>klQ~b)Rv%{INqWBP=T-E4pI#m|pb%OczQ}W%tjL`7!$g zM?nKmL8d%pFd0LknvWOOw$3mKj>`3?F?l}~&dXDS)}9*6TS-&c$dD;qFrpza zURR$`;6Ok4GH{=r)z1dLYAEKQ9IjOSluf?i1q8ChE~n~ql9~81v|m+;{`A_6kgtw& z#}J;A$%88f?{3=$(*b^hA_cAfxb0H)hPIzYHRFB$NYKq!@RJ0P;whjq;UNdRp;bqv z1i(m`B81SCnjOX!g(i?@_&zM3qdhNnH{t1V0kQ(xP%RUG7z{T7^deu=fcgr3iep~- zJ8%Nn@Fp!l_z1GXBL|5R=pvZ}RU!0BY->U+GnkBJfa~&zORj=UkPrEIrJb1m5dXtW zk(EN1NT=A03Qw_?Z2PCNw5jar58rfq$wz0UVCoL9DFze4Twqb^gl@f7b!7wW>f1#z z4p~-HGp(bm`=ZCvTkA{kXAHl-99k=70O3*o)j{$QQVrjLDw*A9#Jg#tF0EQp8Rfb} zjZR<+U=^wFeqk_*1|agjcad~XEYdx#v2Sb~#uPgRilpb5q&Ky6p&n(O4H}JpP`PHn zZJMm{h62Jy_DHKSdG?F`B8@0ly3}F?fAG25VucV}4ZO*QMwSrL)C~9{CUmV$l%GYN z4Vbvp-FFKEQjxVbkc^ow-z^j{Y-Bi(#Vt6opQYqu&ZXAcfYxUEq&ic{Cvu3UYH%3Z z1pKNA3a)jkO!@8=N=vddQ%~}smG&$pr}<3fH05XW_=D0S%}>Oox_KHhH^&dgGcc`| z%{&{>Aj|cTzbm?dd#WNp1bo?8j&*&tk>D)IyQx`g)7|y-SdMjj|H*j<_Wm}n&bGaU zKHduW)fw}**qg{A?DJDcsv3nexo;NMl4;b>-*Oa;(>S2*sw* z`C{^TXF>0Xh?2~83^~+_@m5GLI_FTaY_#uhP%s+}r|6QsM|KAKdsB+V`t=hI?~cl` z(u5GLQv-H=2Vo!RioDBmE+{KUTg9KXb{FNIcX8C&AiMlq&AU+W#=a4zUF2g1x$;PP zf)BTCh)g-Wrh*m3lTx)0!S~SZBi4uAb7bjpfGcO&7Glq5`;#?+1On9(=*_< z*w5G~Z!_TF`CePx=f$69c&nfUILuEMayFH}g5%z7hCRXe`vf}!qTQv5Bkr2F!PR~o4Sm#t9}qqkR~%z33K7Vr{dvc*RN7Z+vD*ntQ*xcfgZ?y1OQ zL`+xZ0i8*m>=-)IUJX`d>QP8c7ra)6Qb-=P=`J7zp0LP&i_2Q)dar)*VKROFq4-3+ z+;uZAifaRK;F2T#A^&lWHLQTn@ll)fcZ$%X~|o@ zMjX`#-kCB}B$$|Fe`D0lt;3#4&~5cbk`EZ5%xk0{TGF@$zq;4$qlSpr|a0e(NIwV+$>#ju0KDS#AecfGzQT)J@039E`sR;a-#v_ zBPEURwBB-CC{u7c&|3zMVFn!Jo*aij_Z}AHfC*G2Kza2fl#A9Q|>wTE1oT$wKxr6})Wh6msmBG*MqDN%5#r z%T83GE#{4`N%E+KYz^B(+4GaBd2J_?E3l1Z9_6goNW~^~*M=mz3xcGviolXpe%x6u zdl^f5zA5SvHGE>~@c?Nx20pblLBRkz*dm8Uhf|QCBFST5^{7OVI^R%5y8l*eYqC-@ zrtHO+L8M>H;byFk=OfmQK+QIXo!~)(Q}LE>tYw>_v$?uCPPef%))sG_m%Y)mB-R!a z`v)fW2@V#l+jqYOAPfbaFws+%FTFQpP@%sZ=!b$ zbI~;AE1M;q1Tc?lVZUl3D8biS?wX5#MnE+$p zwO5fBVY$(S9_x-ZEbu0qVS>U}L3{4-{kv80#aNgG&VF7>AK|TGa*F)Coa&%KLFVWS zt&D^Y(5Rmv_h(|0GqMuHWULq8VKgw&FgD9IKGfM{K@jG5;u%_iz-uqsnP7{y z8On9qa>w0|51Ou4_)3|7KDHk#+FsiI)5I|9x(Pykl{MpIAXr6TMTSHGZ2c}HLF4wB z+!y3v_F?%c487OHwxVG8OR>OQt+zOr+jbPrA0kSCUV{%|1myKDF|Y#ct8-(S6T7WW z*EpRhMD(p}wz5FUaDaXQ`LM#4WBGBSn>7USe{Z%8P60@qurqI0r7OxQXS26S`93Fs z?cDORoHOM@Q-|JCcZz>*CoFIWXdn@mVt*>oaKnl`YT#v|5rYJ!NbQRm>$QB}Q>c1a zFvu=yz~MyTG-*IaXO_37zL}zv?kG6~C7nL1hBevAFL}<^oDIJKUaTWVG%Q?9)@iw50r$vz%#vOTQaee!g5Mc(=Q(?v0x8TQSc@Bd!*N8`evUY z*5i1c_z*2jS`;Qc<&V(dOk-OHp%+>z_Ib^9U~*^!%^ z08W%C(zlq1Ei6g=;E3k>yj|9Ief)eiZ{z|YF8qNaY%_q+>Q!q$!LG<5#}y#!=|N%f zE`T55IpR7e4Ni#uP{O&9D_}FLOU+4~uQE4Z=+?)>1mX~_#okUS{e5xpmkbPY_${^3Trw_GT~XPL4BI>cGX(1 zw8tEbx%sKhR-37#Z_SLdQJ?Oj*V9-`9%-sL)0(TdCS9rZHZ{1?T3Py6HwsHbr?NHC zWQ?&1v#x;TdUZBfuMj4fQW>pw zyRuTNFD}-5>GvUZI=&=K#uU=Xc`+Hal~~K4A(0mrb{Nmp0+FNkKBu5=@1#yzsx`-< zEmUJ$bOkL|mFCx3im$D^k3GBNKxb;=SJ!}AEKWC93sXa3F4R}&R`6uo+L+mUDZabX4eE5JN2IJ9W^iwx z36&}kn~S3cy<_Wb)fyT1p``!D?uJ;FoWk^2Gp)}4X!6MMDE#P7AM34^A*uJ3y&&uGvRaf(@Z}XWwF(Ao??zsFi1-9qQit$y~^X$6}wl}_-#;*I(MrBUO91jbLw<=Cj z#jp*Im->mPI9^ygb39Zu-qVoROkIzTjb6X(S(h@}%8#0!Pu z#^b5ul)SazzKAEf+D<(XYah0H(;*uC^x)9tIi7U;bc3|`k4gw~Vq%9zsnx9by9@#m z?ikEXw$V&TS~kBbW*)m{BEK{bKC5D;&vDq8FGT5bVxKLibBvLo9qDfIv-^Sg>Vn== z8+gOb6%KE1%)?C-@~KE4gGN+-rIe7}xn+0yCt}R#JYy7q*Wq?HT-VI^i^XA(Rgxpl z>P3ewy3DLnYm7+*RRL^!DKUC082qYVi4?yskWg$-U4|mL!6H>jg@Ba^2OOmJX9DOd zcoZ^)jJ6?b!N@6OcB*X=mRcYOTQc_lBk2W8aD8_Tc@5j+iqh%2llb!jmK=18;JIig zQ4Y_44S4J4b4<5uNcZeI3dt*2YEU3XOk)95P(BVuYtcri6zh;C#R^yr_+(b4Ln?uEx` zQDl)@R&wG99^kwp0mK;0>=_n}RXNWaM?JACFtdhI0xR&O985`rGSa8g0|LN9pRmro zLpk=37@UxJfnY07)40zV0DPSB)P$flqGZag25{S3Ke@d;)g7+RA=1)bL7ySsxe`gK zMn0R6J%FX34u$kfkJI+g2eM#I9-T|3npW`g@Na9nfYzWNo4Ubz4ZB7L#g5}Y_6iiFPoIV$Cl%hY-_Y7X(*aMZ`B%JNkCrdULGjGRJrqi5c;|EU z=cdP*a|Xbj`;UDrpw8jR@QKK;7+mOT1=cAZIgJ3{>>pntBd_-B&UML`K@*^po&e-v zYDgPecN1YH9svai&V7LgzcN!?d>9qfqcFd(Fv$^k!QekEZNIX#P!4y(RyO5kZiZC4 zW3?Vymkg}&*N5?dGaLbs4s`m5ENABnUT?tLKpM4p0@1q#a0<8&kS$v-{{ci^uk+)A z$z776bS^MamBo-oIk#Z!KFc=L6~?({kb7Ag4#W0J>4;`Mm@e25MtV0BCP zk)+*&vN|e|(Jl8)(UwMTl0KI3nyR_WIk_WmJd{=gs-JYMgA4cRJ)rrdw9g?HDN)Ny z941xh9GI$w_VeLf7DmSMl6x9Jj-wNAHmj{|ZN64_K^z#!gVdFS`AyGJlJ6`)F{?aR zFv@Q+D+P#*421(LV-!k^mCd{s;mu#XP~SkZKS-?!xS;MRj*=|5I`5_=YSHuHc5%b`uup|K+8`(e22 zDczHYCV86TVjU*6ClI8*94wIRS9Zy(Xy4X7ZZ&;%WU;7VC*UM76=O2f3wA+naiwVi z^9FNV+i&j$eVmuJvYl;~8p<|wt$fOGd7ehIZMhx6J}TW#>~o2$n7JyWtCkN0y20~? zk?{WNeP{-jT&xW|$9=@7x~ZXP#5Maln~$q-rCb+m@pGfpgoCBZ1g4w~xhN~~8Wk5Y7h&SdK81USR-E{zwV8nroEQ(#A-fmMD)b@2>8{zh zIK8am7s2Tjpkvr8C_Psx6@&?aeGht2yAPP1XAd_BolXn=FA9#JJ!! z!?-M{YYshe5C(03CFlRq^KIiX-i!1X{MELgb!0%w3 zVg22WNH;W23GH~F9ZpEbJFeTnwLA_bAUYJ}n1(Gt(?`wZFy_XYkby;XGu#~rV}UId z>Pf>E^bFLxyU@C%C+HNvBO!e1H9M+yubmx$nbNq=WnCuuN?(O zlpl*b@Sy4Zm0{B}Xvw$T(6!&NbUOMUO z)in$G4<24Hpvc&n9YZJsOVZt?pY{qn zrybLQp79uXgMR&ZV2XqNoD=#w!uNdlOcJdf=n_Uegsh%JzIXums8{3kL0Z_M2a)yL z7wzt3M+_a^5hdGo*W+PCg!g}_HuKgeyaYbGL;l$3DW8(Q-vV4TC3~F;aJ~}SR7u$4 zA&)(DWQ&mVbjsTRo#{iqAP&t9e?(CWM7}WAvraF0!&L)Db~Y8Cjef=eJ01KWm$6*s zn!zLcnh|FkaatHMxeejuTW7>VN%moh0HW8G{T9mpn~yeTRoeB3wiwlQ&=sA#9?sK8 zjd#`+{Dpa(hj&+~{(HauRwlr!2o5`F!_~vH`qtDNaOYJ&pn%;=Cl1|p2g1sQqVSM=A*7&5O=B6EdMS-@)_1u!EgL$9W* z*J0;Q9DXRni>7ChJ=`t1&4bPf_X7M(Tl~)cCP>U$#M%1?+xv&XtLulP8BAT=uiv)c z*~I$-d{*-sIWZZke8a0yEdUT7h=DBRfSuG~#GyxjlduDs7ng$mXdhTE$ zLhVnDR3%p>(j~I>{z6U;J@9E!wNb%9{UuO5O|AqLEKn3jjsdEGKPdHSnFZor)Gp;PXZ4{g(25CD18oO(la}F6VV?~@8vP#W^B;YoOf5NJVf7F0ZoU& z*MdunnMNkxw-=K^Gf}q*TT6zN`pmuON~6|l@oq1>#AQxIVzsv_BkV82;5Wo=O0JF!i?_0*ZgnBq@+`RS)N=(F+se>W<=%_onri}t&#&nFa?P&r zylr zel$RdNXCwBEtnmIoE}e?-mFzQ^AP=fmM@TTina`h-qUy%Q>rCc;m^|(OC-kuIjfU@ zw6uJ$G`-GWA%_cq?Ga%%vHf8d;+ucX#@Yz{2{4qOPgr?j(65#kJP6#4(L8vJ#~+aC zmCwwK#TVkD^)5*)q{f_Krr})P(J{a~EtPFVTwYp_#Dyu;8#q4ETlH`j-{62S`1xT?q_Pd-*+qEc$XT_)W1E#yv{xzD(wwf%l zIMFo0O1Kd$|NaX+5L4&6%20n6dO~-ydOgt<~@9e*&K*b zVw_l3%PA@%p34l0!Rek5RuE*w$4Yb;@2g*K7~3ve>|Ix~yJ+dZI+1_%z`yh=BReZA z%ij|JBw5-2Ee-yUANg;v@Za>Rz<;GzX#{MojQ&slD$8Ggm5~jfk^b98WT0nZ{r~B& zvatN0{MElq;{PTma{POH{v{`}vHce{@jsnJ?ZkJ5BEi-lcLS7 z!^XQ@96DZ2bm9EPH}Axkny)MEmfe)OmNzp&t+Kt@JaTK~6^JD`tKdIK=fiZ{3GZN) z!(dvDRo4++OWWxBihgY6%Ko||3YJt>1NuW-#vfRYjoUnTJNeKim)-ZSc60Zx!}Is9 zReG;n`^WpS8X2Dr^dDJZWWFQCT>~x5AFz{^C$7>f9L;B|AI#U!lnO!ME{AJ{tGAlE(7%s#Pl0Q{rmY}{PZty z`nTR+Z1wLl_HU5%ANc5Z8~;K}|GxgS>_6brzjgl6{x?+m4?y*wi0WV5^zZV2tj~9y zzkU5<{`>tu+WPMQU+eat%NhQT=>P2OpN0Rcc>4DU^S_Cwe+TLRd)%`8rIi03lK$-` zGqe2VqW`brDLWej>wga90}gjL>;>1b)bA4GhWTdf>w|bko!Ok!y79r5sR6 zU;;=n3UQ6!?bat)^`ypDeL4R=oVfb9JewGgxmObiwps>9a`Pe}Y4t!L|FZ3Jz@fQ!)oT`M!>%Gz1*Iq=YQPF8L#mxd-lC_<3Yza#i^u& z#Lu&5T>C!Bu1p0Ncy0I+c;x&}PgR-K6DF$;tOMfM8JWmapoPU_c(rpz#9mX4q)^3I ze;eEE1K91%jTwICqxKu9d0Rs!c5uGrbK6kT&KrV1f+)t%4vz@P0R8OiDD=Wo&aw?C z;zo;d15y~ERJGzRTHN+jdkxo4Rwt3O&H$H@Pe1E0m!Col_P~yV8~m!T&Ir}1yL5hR zI}n!>L^-Sr=Mzw-=PC#Eoj*5D3!M5vyBT$KTcjC&aV)qL*$%Y*;um;t<#IimC zOn1jVj24)6Nj@%XUlT#d9c#a@)FMGJKdBdN#TMjKcir{W^;IAM#PJqSuD?4~Y8v61(~E;(duz>%r7}8wF z*F5{&u-OSP*lcnlYzkXOIu;DH-OxD&Z= z$Ksly`5QC8?HzWPN+(KVr$tzka+oJLA`^0C=Vp=3M59T9we5;tHiU}t&ug!;AJ|0or-BwJqF_3sYj?=`r9mn z%7^tKXoYh5@L_i|M67T{^mTjv?!V!FN7EU)A#I24B1>APAC#(v8nVEC=oh3VTN|-q zI9DdNt;DT>4eVeqYvU+WNb>BjVj>7j&)fdZrUx-B$1K zw$~P3u3q)zr@^=bCtn!8IAizLsoza|tI{QyOyr9OuF8lVs>N;At z#;gCd-`uTn!wIbyFPO8t^UBvAJ~@5({3Z`Q;(WyQZ|8re4Bxr_aM!Hr+foj-KQw#w zmh>++RQ|@jX3#gg?j3mg?cW-mu5<60IkDy2&wBUWkDonpf9tFF4Qcc0!e=hW9d5q% zOnT0!|0})bmIhxw`oX}PKDn67u*s9r@3cn4y^{0B>wtd&8&BEIkeENM{ z()7I6H9jhrd@1JYp5L21xc=^;ZRf4OJALHv*h#TBmHo15g-HwEt5bRN?z^wuHE@q_ z?#-W^iuJcU_~{P|UZ48aYZG_vu9A^`XyKK_H*;&QoY-pB{F%w04>?(*!-9j^|GqbN z*s|A}z3|5izK^T!>UuddcIdrB-oLr}?#UlF8T`?Y3%8`zZyLLD`o;k#zFROXam>f% zuT}e?#jzH(`|q51WcJY4o0T5%+^E;)?C$gZfmR&u( z!Wlc``7>ITdEU={l)A5aDs^q3>F#evlwG{*3rpfg_V5OYd^f< zigS3bU%4~-h$iec7Hl%?u%6yOj}oNX31M?uh`P)E%%Hm-<-?r zsw{ixz8N!Ke5z9H&R&Dm)|IlHx6B=vboSMXvjS(PbUc%pu1(#Tw6XN)&WD#?oiMR~ z(-n>4>efBB^s!OuU*A4ca^uYLL+%+_;*A%pZa)TBl2u)FG5dI>smq&aIcKMrzBaVM zn!hu*u35J0m5S~Sle;}XFlqdb5m(~3T`oW6wC|5^o4oc!oeA$$>O0=uGCs5S&S#Dc z?VZ@>>bWcP%D%pE;mn~ez5n|uNgCHbxy*{aGv8}ka#N{xa?MhcJ{g~ozagjXd2P?` zY~Q9^YahJatG}aVnKSpg0$sbGshaTSiywCN?mPN}OY&CQwB@l+_no|@%1`$;d;g>D zQ}-HFw-X`zewy?}2U0W#f8^c=m$iMfCQ+FmU`Si2+X1ATY>5q4}&Y94$;rK0I zU%4;)l|Nc4yy{KGc&xWxZ zR+jwg$;1y!5C3%f?botX&K)_By0Yr!durU8(C)>9bGOXO={I&w_QQ+M&78Mj$FQS^ zK2CV4+r}41uWk6Z?~8SPpM84n=gx8OKezmi%j;c(j;w#P>GJ#q2S4eb^vCikt)HB> z=u1@yNS<`~5q8`^(AoJumc^du*BZ##-On z1t;AVtF_tk#lnw*PwdJ0>aAtdx2&AAZuY63zrXZC*-wM-tQdBBcdH*8R?EDwXu-^L z-%Y*z%HPQk58Ii1)w^ZuyQizveP`2#k7xFn_|EJBC6C|T{f(WM?)jlX-`a=X-t|_e zSH|vadedLGb*Xg6>fa~aeV6}q#fi^ljeo;G?St<-mbm(>|0ZX-Ll^4SoOAxl?9%7T z);gBoe@(*3w(ovcuk|~g?f3n4N5cVAS2cL6@1SSCd^Xx+kpV4RA9ol&6=;8fo&maAJ%9?TR%_l$9#+_-fxLnP~&s_U*+gI=G zeQ$QjPID$4`zLc=#>HQU+*zyfw7`xEe{O3tXXTtfU#Qga=EJkD)g9Tb&w-PpXOz2` zTl446&z36r5-H+Ki=PX`hm3#R=l?LuV2s4taiQrCFu-=LDX(ebd-o_n&`s`tI_RJ{#G;N#k$o!P`D|l{k0T z)hx%M`p1uynDzVdQ^3VL|lpzfR zNw>|~@%I-O9sZ=_?f&U;bG_Tno%rYU|E+uObnRJlQg^=l=!I|H$6t*7qFjmhS{F~L&#OIFYuRgWtG0XBwVEC`>ivEP=AHSZvZR$9wY*dH zJI)L^uw>`{Lvw#VU#;wwxRG!E{OJ8}eYEI>pW8NER=soT09W^w{Nxc_3S ztvxgMt$OFJ%H3A2)TE@%Uk%**)9y#xzFcy2pLv}RlXUuE!Ui@KsQt2fF4y-J@`tw$;O0E4&>T-1Z@W(oTHRY*U^-~@x9Y6Z( z=?O0{o3i}L>a9NNT;b^AkF;9j9{8|X)0FrXElYN8I(O%xR~FrVVaMLerAl_04CXr}w?(tIFLTAG34#&2<-D%`3C{jn%)rbav85-FxiM zuladHtw+qaiCPELCH z&$z@B`)^L3bYTD2W$wJQ%b4Xoy3U{a#&b0t2VThg=i;IVDt_00>5?B0ZSByj)t&cu zz32X)P5^X&Y}uuYuJrqHLLJZMl&K%QbR}=$m-$b&?UJ|W{U^t@9Q8@|!aJmDUoCHZ z=_cv;Th&UZZ=U$`wb60!#55c>{cLRPtQ1G1xpR`I&QB#q`{%T z-}~^;Q$yQUct+{}+_=U0`^S}8{`Hq*SB}2Aa$I`f{k5t(Zm&Id#K7MxDqRjut9qxODNbw%$9-=~awv+`~C^m_J|C+3W9He$g13tc8m8QyU~ z-!XT5YoA0SLI^}9Ylf~)DbAQmvJUc7(__SZAzPeA@*Sg8Bg^L%| zdem2@dBwVaP5yOzgHbInoZC5P&ArD)zOm7J^hB>O8|Jm#vE13S!o6jrnAcauzZG|U zihIS9yR{M*55GM9=GPD0=j!@U&n_oxd{lMB$oaGH+F2u}XZz~U-4@$qXKthYpPdM9 ztXXmBiS%*n&iwI2_X%G<_WA+O#43p=2LC>P>ZQjob(>v#nDoiY_&b#$>!14i^sc9S zHy%0r(%|`3zPWHZXUYAOW@X*c=*5nsw{^X|=*hv09dizDZ`@?av)bhUJ^Q~lEqC{c z8T-nF(krSBUF_IcV^#C}=ij}zc9XH6^=-3bb<0+{=hgdaRV?58U(eq3=J!AQ`SxWU z>!0g)|6fv@e=81}bNu^%F8$idd09 z^?O!+V7Tv8?9}#iE=(`A?AER)I~~hzkdm_fX~7^FVvsg31u2A=H^sJ`a@{U04GH?PLlmvUErn>%Cfb6xKr z5$M@vZ|mMYf83XO?Lsj3;T1>c9NYe5jkcAi%zXd5J@;&T{mO5DFP*dZ)+XhZO38<2 z4m~j7@7~Lw9nkX5aSt!Mv}y7iTNdy6`Jvx3tFHd>r@!ibvDEcz=H@R~Em{^>SkL); z!sXJ#-g%YDkQ@6#uD4EeiZ>HphwX~+|Y2h^;%?$q89 z%?^I+`PcEmq|T)tn*Kwpfv0`0xec;k-z&fLO5D{Sp4~8g!`LD7r$2qQ?b8$YSFAi~ z@6V}!Tx@e{b@0^S$AA5J=(@Kz4vc$tz;?&`Jfyx8>e-a8}li`KNYFzGrfWlSz|jo?7>I-@7-zI_LD|@skhE`SyKhYRt~Vd!?Lx zYmZ6S#;0E1n40&2^z)$czh;lm%o*SF1ib!Wd{=*bn;P>!tx;C#Z%I+M#WWxGk2?zL`@P4pe@nwGq!XLohu>Zelw8U5asnNR#Uedvl!y{<%0o{NdVZBgUQ2->`J>@6|SxDd`yh%roQbHm$dO(&gZmXRgk4tQy;IR`#++qjw$s z@YM;!PCL(^IvGExP5Ix~5B#IfA49*MnmS?j&aNBwov1Np;J#@+@}HWzDJx+{^)X!* zoF6_Rb-|=%J$5u&Uu*jI6F0ZdJYA_=_PE*V?^itc zZ;98m<8@6dil|bBs#mH{@`Q`)ni4K*g$j*k#q~H+T<3#a

IYirsE16SCmu3^wVOxEX#Jq^jEfJ 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 Rk{?!F0Y}}saS8E`{|A76o$3Gp delta 109714 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%0D;~|B~GTZ#V(S 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

t=T$!J&+}$|{q2CIvoS~B0i-QP7`_jRw=MGn z)Pmw?`L@YBSS(zNq}W{b$)f=838A?Bj{h+J0vvA;lZo0-5ruKN0CU!AgY|*cqbMC` zM;KtwXyt0JhmVmN#4BZ=|4#Xh{Se_B!c~NqVy=FXJDbm;X_skXlSyLGhoTw(BP6-cutcUO+$n#)mJB@J#Ef|U*|HhE>1Y%S^kE} zaky5QGyp=T&>Z^f;pX&loON^?G;>|~Hk;TliJi(R>#_CiuLcgxCIVQHqm3jsSvQ$5 zn@$p0F14QRNtyaIJh?#LBv`SJ8Y=8|%>lvFj*^aymk!UM@vH97m;W+nj%mqqNT#!x z70-3GV>RY22Z=o8EnFgsyc1`t*jE!G){D$7p=pCxkYgoFa+1$re$a)jWjfjvq8#!= zl+9wz0$YdNGPB*%C3biVXu_bB_3e`_hj0Nh8I_qux#wBud1qP-yrf(8Z;gL}Z+31` zPM!9VW;C`9o_MdnS{*fAM16+cmcMHLa^2kBD(Ded2{`**R&G}h9MM5ubm3TL)Ts;# zN<)<^Xbg%9Ly;hnv1VIQPT3m-Q~8pdkA2D3pNpS0Rq4!h4P~Jh3T^IDdl{$`AoKvv z_8nHQU9TLQQZ%{s(}Xs^JCi!kCvRM!S|PP~nn*g*8QE~mLd zU+QPhy&(o2V>$9(g_BLW=>AI!^`RHi-9lyZMaw?4rp{T8M~%5jnp78a-C%*atf!~v zcQ#3|-)|)QJQTrSlWHgk!x$7VToHLLP0t)tOGXFQ_(vO=)Mf$(k}NR-{zx9M7Yd7w z&{)C8Jz;BtRE;R?W;Ty}0y$cp3M)Ezt69qk4b=oXqzG4xDB*}3W<3~_e@CYLoZq{T z>e?SzhGUDgd+SoUZxUxZuRFJc7cGt>gF*=Osxhps3@3Y59*UsuI+8D-PU7fSW zzjoyb=5l%cjedPxfm#w^i_%sG!4BfphTMw>c8kU(71G=z3ycS!uKptg+rTUs{-;N>-Ev(_g$ReR1n&z;Ua$9va1sQs>IQs{u!F|gQS{?g^0 z`^2zmaedepX7JsXpNal_k^AczIMlt59=5{Ei>!K^sQ`V5mR%G7v7A5os~aIIyyBl!d1oXOkB@mlP;6C zV7HvMbqKH=jOSmn`fGIEB)^LYVQ$F=3mml-VHB{ha5tp(qGra^x|P^lakNZPW0Mm3 zEQZCEQQ(?OotzCN?rlSZuP$!#dB9lle(?}pSs0~6iSnOQ5T;&3o&g`FfZ|-WSF^~0 zc_x&P>xk|bh@5eV0SPl9S}+^q83@=?LJ9AYHN{vB;~-1# zxQdP#QJ^9wIq7Q|Yk7t!Qahy@m9cPR40W?VL*SFcE^q;_2FOpEyAvSh&Ri{1%bMyY zZtR-DHVKMc*su^}yo6VYn52=51+Kc>WR)e?%f%Wr)&af#h>Ji0A9IgSG^CfdKkM`? zYCtK{lAlxS3bzIk?O`865RjJKdj(s2h4|_0l?*U{f^pW8$0kVRxK?fLvKA0yX&ZDd zTfC}`7DM(Qn}6$6GmG*LgrIM(TlhZ~Ph^T7s_L9a?Pt0m?^v>)Ba)oBcRTNT=2LCJ zFt%79!9J)2RB~TWG9`0N63B>NXa2gbD_0i8V<43!noUyQuch7sZ4{vmXR6!ZUWK@w z1cDzXMfi6s_r{C|r-a?RY|_)?`bBgKlGYv@uprfcR-cb*5RM5nPnldeiGtLm<{5kr zfmR%~a;pO3sb;8>JTgfJN$(s%A@ACfd^d>&Q0Zg+F7WhFEj@0Lva9Nv*TJN$kPBr_ zJHiuG(`W0p=0)N|`p`OxJ=Mwd=rAxP=Pd^1+HkitpI)XMYl zaBS~7CuAE%lVLNRa;gMDQ~`bCPo7wx3(|&*KlzScxu>pMHO?fGz)gK3YD!Jn6nY2) zU>gdVZIa!3$hYjy*{+xx%9!m_wxQwyJUFPo6V|i)wRR3!zAe3ZP1H3*JFVFpEO0bGQ^#2`nlDIK_J)8gtmOBSqo3vj+;QsW-XN z>~u7K#NOE>s0CdqX{=!3D7Pyu6_Y9pNV8Ua=W*|i+@x;@7!h6(^Htw|7YV=p^L-Y>1 zIa9~yfJTXfdQep%zC|FP5^)*>=*)E0OKGE()1XL6*Foxkr!Xgl^18^gXA)*t4o5+F z#s{K0%C}i`Yw25~|>GC%FxdjCbsw6QZ>Lapb9 zDUQF~MpeqBA^cReJ`dnv|3#lJ5}V^^`TSzg=c;by%AAxpcw4c1fo#U-{hIAMNiWlH zC@*a;x#2ILI0Z2;L#v>w?}Ry1%vkpXe!&w_vSbxlImMzxV+*1DhEe*&XzbKX@cwp; z*pq-80FXw9-Oe4ci~9d-(LMTusT;DBq>K0lHzQ_>m<2=ZfJ@$?i@bos`8Sk3taV5b z+5s$P3vOAW%vy+8S7{MnT_=lF50S~*%MU>n-r!nlgOL= z7&nWr3ptZhDRTU}jQok1&`q*OVJ0D+m^5^-JJokbqA{Mgash}LU?@4=k7#UL(46JF z-XTJ|BE|{j99)7+_M%&7St4AjFj!ciR`Ib(u_^DaBp;{B0+;iaM|mChEdC<;A~q+c zrrgXoIevs%n&j#S3YV>u@|(RrBoPztxMp){Pa3?YX)sK+pP2?(x}8Ega2~Zs$6*^Z zUs;&4=5HZGnmW_Kxq)N_d&g&N%F+vQj?*`^U9qcbdcP9bZ2op)VWxUiviHLOv27Kio60PwLu+g8F~3ng4h|>J`=c6-AxPfd5~NL4 zk3^hWHnzhs5s}4%BnIrKX8OUYn+ZvK;T0@aG}3Vs!4f>4tC42hc>SW%SywrKTWSn)6!#FI>O|WSlmCXXYi}p2MxYB{6VI03p;w; zqr*m#P4<{k=1}=~NAAUmcL(1VVfhLF@|2^>pPLnyccrsZ0lpX7M2W>F$YdCEgw{EO zP6L9B4uSERZda?Zwgmqp0O!HpuQ*%>d;9C0tvlZP-%k-D?5*E^cYZe+Q%wi!vy+gC zmH3x!!!b_eC($-0=k4pJ$q58Lq?hx8(<36&)`(=6X8WeA{~}M+2P%VXssZ^UU;m<# zx5Fb-NV7RuvR77Z>N)fsI%XTzTh=Ln_La!+~Qz;Zg2^76x2uIDT`t=+9(Ef=fyANxTEVNyO0 z+TWQ^OY0W+J9pD?`LMjsV;uYsFE$jde7=V-;eeK#uD>^z5WZy+5nnX@#(~G9f<;Y~ zD2XHrZX<4wwy3i3fCACJ^rj=~gZMJAC;&M1$S>6>BwVHYjNqzNJntYpJhcu8;=UrF zOG0P498(WM0lzf`nENH-Pbv&5VzJO%RH5UeOw<7@QkyDjJfS0k#x&kUVSe%~iVSTP z$OQPOS`NggvR@LIahM$_Y+@H)3SouCr0FP;bt=9*e$V-&fMV&K0tsS5wbBw8-D@9?{9!Ld|9q^1J$U>Qe7(g~qtTo5T|&M3HX1($cLp!}W3B?Pj{ zN^11*@%;EC+)CAk{h$c7g<48Bu?}2cb+tdl^QWmgQO(2^a&~^J6G)_PuvXz}>ayr?T+F5TYU2v5STCq;SY0 z@~IJ*qO^dJZVY2$qufGz3XSm!z8WGiNP9r?zET;cuM=^_^|nj)ozy!Dj>%_x+@ohT zIea{G0Cw8BRHt`jvTJGPv;G#(2Y+zF+vuS>1F1<5%Di4T?EE<3KDu!I5r4|+2Vn>@ z_lZP7#7}|}U)Dyd-1=i3C`cYK7vpmH3mA|}>$a*GIM@Ik8j zqdtT^?geS?tQ*fip>bJXHRicqp{?tPj6r}z4KO4j7`frC*G!=W_Z$&e!LlKR zeiRW{1N)|bjs@c_+Y6YLQzm0mmRdGF0gzmkBKy=27mnQ2?dgmVi3eb1l0;^DQ{Oth zt)`1jn-Jc8jGqIusT~QMCcU#*)mjf^3ExXE`ouGvJcmu&2z7_%SKWUny<~3u+povr zg7f`+r3dqoRPC&{hxi`MIX;q6KsRXYGuzxhih&UF3Alneif(`;c;jXV-VA7P33W1@k87& zu}ndyDmd$6`Y3%gM@JiB$FNoJ0gpxJ9R0is3{`;OK%n%yFNx=~-?OzEd{f=wnkOEO z_)f$UngM<}Q9gNI7-zuhjLOqqvx)&+2%P)2+PvBJHrs`hWgeJqxfRS@*{a#gZ58%P zE`-lO=$98a!e1fTd_^n7vjNMh1iu)_b9ENL!Y(<3L`370Uy&Y~_W$Vn0_JY<{N6&r z`>f?Z33gBP@6Eg1BE&cbHMhV`7Ge)70{Y}Pf7az=*g_2p$r~CR{X7LZ3MjIIvW-FS z^g=0g<2~`C@sVX>C_2m>=&K2Q}&zoV}4sb zgWD%QbO_w|u>g|0Sm8__;_mv7o^QXykI0t`m2RPAOCho?-TEwI!XAo&h2+zeNlib& z+A6ZZmA(9m0rHXoX1;qwj5};CQL&D3MD2!p&(3i)lDQ!`bOk{+z#6H|gZz5O*aY`B z+}we{-b-~c*03jY-drA6z2>H(9?-&EKVhB1Ul60FV3f;-1nNc*aIYWeoQ9PeK`oe= zHAYAgPQrews|vk9XLHWj{o0BQg}=^9eJ>Rf@yI!9bg6H<_~%O1H7#b}tNp_oW3|jK zI!x9?d$T;^Bbt)Y0JcRaZQ?!d9Q8p#HAtqNx70cU{=27}7hX2atcQm$hG*KHsEfMf zwi+!K#Tpyk`R|TuZ~G_(i@Z*=-2)wc&Ut~q`*3Xrjb#om)jH`0O|CyUe48h=eeP4; zVQwA!yK+7yA594QeWv1P(jgMx0R{)tF-UtA`dCV^*$FMb0A8w|bR2#V0WS^=NCLtg z9i}zc7LJ($U47w1f1HkZghvo9zF+O=gAB5yPV&uxY4O1|QI$}?f>JyTI|O}HOB<8> z4R2El<7u%GqNbe0<2=S*Mij<6+A~RU(hFlPc{XC7iO`(K@@iojOF!s|dN^J#!Sg)f zhDT~b+0nu1&1P@+cI|1oxI)`N$^w-Wj+cDTxklU5dHT~=)!?@lNVoZ-E>8|Bs z&GmxzwSFU^J2iz8ax)e^A8N?QZfexQJ=1-Ff-ytPW4BtkH1a6Z8TK%Dz2pi@9Bi7V zYew5lEf0I`jj#Dwgq`nXwB5H$HHxydcWe&u#y3kUzzTCIXK|p{D#-@0eto7MKxsD^4iXWxzY)LYs` z^P|T#;6}a+?}Mvt(#C^lOTI69mD7zrw{L)NyJx9G=RnUs%*lJpyKSSt6U)$)GPl7w zj9H(;hP6>{S3G4;P|K{R;{MY8u;+r1(K;4A?5C`X}?2XriGsQw&k|{ zagEvZl)CZrl~59_YxY%{>*g2kH;-T;@KmE60IMl+efH8^-%#IV$LM?fR}9Z9ZSMsL zYmSxL9hbgiux|RdAdb9;Kt_i5ZhS7To_5#?_dp2e!$#Nvo*%AQ44yV zG%Z;ezdrt0F9%xr1wW-E;YsTh62m4{2&lhLXxc%Ts6b{8#Qo{uEPUdT#!>N=pN~Lph{~} z+Q=nRn-6-u**e=3Br&>5IBJdkQHEnbJ0qLaE!0ERO z8m4fFj~0iyeG-HlESP;*a4|3s(Ie1>xMwunQyxk44SGtbxs82nT?ZDOa*`$c4^{_82M$3^6Nouf*9Wm^9M5V~&z;QkCY z@^!O4hx8nh5y0DeIt2~Lm*6Mgz^h0G6}ywbFg^bQMpNpI5Y16r2kLK8J*!}d@0NK= zKzs|4ZelV-@)0uyMeR-?n*Me2>>191YD3V;>UEfZh?UJ>{lIn1{ZMZtD- z*qtW3mD9HIv#&^4jRu9LUv}o@#JtK`X|6Igaq%*?f`jYqbyW z2?kfGlpld;DEihFP{L#l#zfS^!S2H$lR*!Ngp^q` zYEN8+dY)Ug2)@?!i=kNb2Dv}mc5ViUmo-J1`Dw)WZ( z!pv<%;!fewJi`UdF2LwkM<1uZ*X~F`mga@{o_T^PD?7uW6^QlC41|N5Pp$0qO1-9W zu_E$Q1nLHe>-2)Mak?Ai0o7;`q<5^Tp=H4Bxj^0vq zOTG%mX}-x%c1s7}EB>63cO?RcxG{FvJMe+StHG}aZm!wroqIie<<>qIqneVjs=`=Q zY(T|KO;yNRTcv6xY+Rs1ebf5sW0X?7qD5+RzOt_F@IdNLR733tX8VjU3|28P^8Md5 zV~o+p=Sw!=#-q;=Freh#_xI%G{Z1YsuRPyEv&_K!H5w+OVLR2a0lsVM%7}?;z59dF zW=_L;>I4g-`bkXLYRu-@;}X!^^t{4;gOFGkBap&^95KG01DKzC1x9kpp|-YZI{>B; zS6|?^GB%}imqzZp)pU@OF05TgFpqaxrz%NI$ppw^awj@8g3!+z)~L~ z;*B9Oq}jnwr@kQ|JQ=n~QNm<_@|8i$rb*-9k>;*bt&x~dUbCY`pd)#jx`6%GRWU)y zdm6Ox~h2dU1DpQMSVHARVah=YjP2$?l3kpT9-E08*lIz_hoDFz~n0C z9^L`OGGESPehhk28nQEE1y#gIqIf{*GNb>yN)9vruBA(NNgFOyx%KdkN!@2c4cE^U zUPy?io;zJ9Q%1{jb{}EGm0lcdGk1iri`&nzcR{9blRnFowWCa_tv#)t=-TMq7^pQQ04guRFo_zFjtRYUC zt5jou*?Y|6AT{N%U&mV-dy4@^;lWws*EaclQ^> zWdzW>``kY-3qAwi*(Y&5=Xlb()4mBme>B`s>_+vZ@}|NOqm5Nx<*1+>qGXkDtGNQ? z(J8Vw)za^y_0r4S&)uWjy4*WG#O>p^@d?JcJuK~At|OWts-n2@zFlDRbM2i-CrEdaGoI6zRA~ugnZAM$>5$5(062UI-!y$v$OvyEf znL(y)o3_hDMSrOHWh| zEZ;3xqUN91;o-$vK=C>G%)$rqZmwuFgoThIkoMcHVj;jPIp@?;QuC#3Ta$^jS!34@ z&rv@dh?*GHY>2|Bfl3?MO1}dPGL^p{GBHBc3sbW+L9~=rbFE~rN)g7y5V6Na?}dKV z4mU0uILATRl5%?VYegmY%hx||$`mJKM%9wVaI#Ne&IBevC+_<;Q&Rt}^(HXn$vfUpDhm!n%np~BNj z!T>4nSGNYnLjo@xZH*pd?EwrKSnnv`qjBoxiLoP^<(LiY;omU=_9->M&umfWN+lr#a}XaA2?d7H2R~qmFtZGLTu+X?~6R7 zb+uMIW;ogGV?GQdS*d{R+_rXi3=g?~@#xp<3<8no@OjR?c&n3(U38knLf zPleMH6#rd!H`y54= z((?R9WFXx&2NDN>5DRdUZde{^q{uUn;)ebK3h_3g{pFeE+dOn;wU#^lkkm7AIH4j% zZ$-+Lyh2q(nu*njNKV?J)kzD;^j+t-bXhS&)f?*XnQs5svGT+w`?YjV3dzppjaSd5 z3CToKl;#Z2$5gJ?jsThI_j_kIZ1eoymS?KD3A2HC>NgtT!J;)tYORV4C=!=!cf8KP zd%fwEI{~ug0~n)3fVenlFZi1Xn=AWTfTZk$zX;>Z-pGm!$vr7F)+5BGar4kyf3xh0uF79}jQY>1%;x|vu8u@1Nmv@N0ZY>WiJXpO95*jnku5sb};K9I?eqHnYTY ztV(0(y|i!T7namFx?HhInw7!2VB`vB$Cm3KUNWiw`hUGkCw=nSLPsngov?jIgTuk8 zl{H%GKda`TJVR%4<@Zc3Y(#?7=r$xxDN_xX=Pl#$_*|!JBVOmaD!0}3CHz3{RoBm5 z@8J(z27?Q0o$CCwJlp7M%ufflH=l6D^Q_vX$~&EG8l~WB9BOfrB^kwhTm8KHb?ADu z#kJMFDSy8U?R4FmzaM=m{{(t8zps9<{)f(2T*vEw>3qv|s{X9=_paZ&PuG8h{^9&< zJ~ji-bWY1H#huQ@xhtL5xnFj@lz+qZM*g?1-{y^`pjQ(LOF^$E6wcDsRZP$;gd$?l z>j*_cbY+#(2bTAj7AU;%I6bFA%7W& z=I&fJEJ>k#p~2Ac(5cYrkUI3RT#xH9Ly9nnCdmZY!}M_7@?R>_Bw4~dSM2(zi$q$1 zuN($KU!m*@#V59Iqbd~$T{M$W=OKTcC1>7NQdDE~=p>}wE95>sGk74kB2KSoZC=ct65QoHEtN`abGDXT7#tQ9f!_{lW2 zqtx$mVpdC6M;${sWj#`kP`pX$Y(sbMM(#${E^Z+AOzwD&mvaL-2IU+z_Vgmv zB4J_rUVomS!DA`cq@Au^ti6wWtY%-1Kb||6W`F~iLS$WoZsfE)wN;uYT_LT}_DI)D zd(mF$N&XoBa*Zx7SQGk*mVkAN-Jftw^acD=g7BD*%h+kF1wqov1X*1W=|XymFwGWw zw`0KZjDrn2_Ba^F2dQ>7U7V3^p!RUni|WbQ$$#4`>tyGi9qR7_k(T@s^>IIZG6=7V zVOGWXn$k5-Jk1G-SX@X+D9yns$;TvIqsmYv3|7=HUCr=E=YVj3UzakoZ$m+yCRXO( zKh&e)*-Tkb9q3_4O&ZB`r&>`wT7VK1FDPP&O;>%BQxz$i$qH#+nFC_JH+f*zy{G^7 z-G8m~Op?o!HehqDDdh0h>W0r{)vYUY9aAqG?73|1wDBLm^b(#v_lYl4z0AjNe`UJQ z9O-)nzd5D1G;iJafABLhPcw7mEV~o9(RwtVy<-gIOKma%;x=l-ZTIrom_V$#V$|F# zhV%t$gGFGz;GkySRl}JA84Pv;_63@^P=DfS$k$RqRnovC*#Zi1sZ72>FKdY1nC$nH zv)Mw`iLc86l1Z=Uw!5&4rn+bjmlzB1tr?Dv5wfO8fz$NK+z{bEUQeHd0dul4W?<03 zsCiw{0m&P6zFh^zvY-)Lq+n^F?QzW!Eo(_zwxMl>+t3}lJBn(*#nB?R4YY9@-+vs{ z9Q9ObYIshI+_uv%XpOvt!ZYz~?M&Uw;_Rl$Ei=b2(XG|ps<}mbi_WyrakGO7wk>O8 zx`hI2Xw9Z-8_0q;J+bmSqABTS*>XC)eJ(R2D%7g=JH(v{}9 zmbo^%*qm#-i*bD>C}Q%(`Bu4=fq&2LB_<5DMQAr-MQ!GE+2ggiwmXIj2ED$ap+GdU zWSAG8!)s9##mF0tB@_$B24Z_+oE$qBV}R995Wg5$UbuXK(J&dgC^k3mFjre zSd#d5et>619-rfJJCFIv6DE(YR3LV3=g+3aA;M~=TZhtB5%MFV1v)=;rhiL3+Xsy0 z5b&Jll47ozQ!v&6R*z9vC$VNSS9!(h#c{rf%G%W2*vzOkf>vPEKv%bQaVfoTEH8qsU0|u`T_w^Gq z>jP~TOr{2uH9&{z;7hYa(0>$ZaKu<@lHl8k8MK}Rr)8b4Mi?;Y;Z>+=B-VuyO5KT~DFaHuD*<65cyi>so7 zvCDsA)yasa#>S?KF4pd}jZRQF75g8GAsU7R=>j(=ZvLm>6)hf5Z; z#o|mZ9?K2xz5bGMK8x0A67}}h-ZgbC_)D32Qx-SRx#cRe`=%==*G;)@adhXJa5&SF zt#7DZyeAc$l)iQNm7B-ectdORy;Hu3yIS3u?$V59WJYQNLfjzPZ2$)-FW0gZFJ+ec zmj*WA4a^4rhJcU@wSR@?h3->*$@{qKQ7_M6f4~v+ilMM3=rx5Ryeoo&jA#-sk`ax+`7q#6=p9feth5`Wix*{pyfX>taJ%5%yBev4DErWNo`usJ ztv#3H3D5)6Mt{z*vjBUCm@u7V7dTwS-;C!X_Ykzz)Q*@*!*_>zLrjRS+k{pP`2pk7 zb(;|R!4ZPd{dI&5AVu$a%W{`>k9m*lQT%o0 znaDx>BK{u#J@@;<8Q<@v^Vp?kW?7b4?g-u?4MfgGc(a6`2OdF!BM1W)`4K^Yc`<~$ zLjxfOg~X5)Y7dd`+B1f4J{K~C*7)BsVbk{1hw6}4t9wV&0x zsDJUT%Trm*@VDw>hSSQ#j*CwHxZ=cyH%JoVp@w3j7Kb=uMH`}Jglg$5Q7u{MM^bC6 z=C-v}9SuZ2luhLET3TK$2Htm~7Wi+AVrz?%a3oLzu;8X5ovAD~qJ-I>;mAB?E=M?U zYJPjMGMh!M+ZEO9(c(cZHfejcd$q4=IW19g#cEL~nhn;r*LK(T)^Y>2 zduo}%T8wJN+T*pSYPs6(CdItA>wj)uYxDS2f;#4n`&4cp<^>P$uNv4A3tK|?F?)=ex`TuA1UjMY=3$+<}n=} zn3}6&YN(F&1Y{~R_rIs3MPFS?q$dlG=)^tn?uY4IzUo^rECe`sWQC!jvyRT<^JD=| znk+`BN~HwG0RF|7$Bcl4mBPM_ikoB-A0Zx7AjTA|F_l0`r4)eHD+88Bl*K=Kz0+|K z5VujOlYsBhJTlTT0^^u=9XnRb#so%g%OZx3kx|$GHzO^7>SO zpB2WbfI1PWPU}OJc(oScs6k&TMq$m1;~Mtpal0OO>wEQk^!xPZ^eX)U$C%|i3MjU< zURbcxh5Im(`{-o*Av;p>0tG0(vQCEr(?tt&s<3i{yJ7lpTU*v+41c;jNi#O9?)rG* z;$}Zxgu}`YPN&_D(TtH_tDaPCKn?h7l*3x6<)&pBcfyloM3?Ahq(-^1yYV`q*VXI3 zu4a#Gk9*KH=+@Qdw&-@~SXX1#)85$IcqjJ_?sOxkXK<Z)9f(#4FH$g)P(zP=gnh zvFae>#rRo#5K#DRd4F=<0~w;cQYSO4F&PG~EEu4Ajfy)SHFd`mHk;cmdn}B}GS9*g zUsl^KBNooW5rDE-$|Gkej9JRe-(;P(wLOka@gSM`0!CUS#l%H&KR&a#YF9-N@9LjB z^bw#|GVDdlik+dB5daOXqrT571HVB^^P&(-CQ^x-1gqA^qkl0|$UF{9LD9^owYA6) zfs-g1$01EZU5j-wW36H-Q8ksQp$LN7N>HNP=asc}bs2^UXB&9lQ)yt|j3@_X_fAh(2 z{P8=($M1>9@a=2bLh*P*?5g4A6Iwp`)?W{P{k!XzxKj2=fq2(JNSz1%a0w@jT{qK7 zX>uo(@ST-q{)^`1tJE`3PzC8nk|LW(*XPqTSGulgT7Nayv}!JrB8Nz>X%nYUr1>UN z6f}{dpow#+V}Lo;=jK$Y^_*$}bI2+gH_1CkONyD3rjMuTb?-E=d>rDlmL_oOss71A^< z-87M2O{7;7=Sal!fuio~Xd=uONp4cOE*kkWy?@)()G>!xu8_nzRoo1bztOvM=5%&c zP_lXSEJDrc0iS^AH=k^4BeP0?7Y7Zq7k0b=!pVDRDjYdD@+0pZ_PE?GU~!bcPOt21 z;7@h_(ZLP?mh2=vN!oz-bOP%kr2?)p^U0xbQz}pg5m^_WlL}0qMLjS8_i-qaP6hI1 z)_-s)GBFjH1`&BeWKm-7#D#%HQ-oC0T)C7=3W$$QU%Z5LOe~|<>UcG$;-^om%e$P~ zPN&l&nxmn-gnOkyvQz{YWm8isn~pZ;n{aQ_U=!0s(j0S_OpMN%6P(*Vml>G5XD);0 zigTH{#3hl<(J;5WqqEE`Js1MMrHohIN`HNljoNmdC)~>!C1|~5>gp*(h9rM&^nWg$ zgs-eaFQHMsrpnobqk5Ae7KumoAs;rH!p7KG&ITBpG+-|>2d-VrPp!|n9jfUw=mdD3 zYq~b3Y6V8;V2@6vxP_=!rot7guO@}R`4?PH#W_TRvN^o-0__@2=Etx<7cDg{;D7d2 zmfCfN#W&j5-Zgt>U&vw5HjW=|wT=rpwVXGxxVT{s!`NG<4cE;n=~SW2yvE{!S~ppI z)K>4I%TkrqM<1>-#cNhAyKeUEMJ+cDZ&@rkfE#jBj}yCkvvP5UEglWdGXChg~=Z7N$M-GlG(!*H;M;jci zgqIqRqS5SlChOBOs0{`Tu~Af3_>q%>CXSy>E3Eu+!c@t9z0>ziKQ;aIbbrn|{b8Tn z*bY$!=(a8t4hOxyP`DxJ&4$8LgWd^r21*->Sc6_~C=v^LYeSJ@&^ta9fmVn>%S;$Q zUZ>MC+1gs4&nsB0VMY$)cfwc-=fl0>ec@B#(_wYE%t*3FoZdbC_;gm9j;BwJg^TSC z-3?5`!_&xo(_9d7$uyHlynk?A#GcbLA=N}la$#mEjfp0#O`~Tgv;ue@>G5ZBtk*;N zq$n!$XJtbV)J{8r(K5AySD-dg3bt|9!#`bH@XrqHKJDQy^ndhuhaX|KP_K4*W=cMv zmYj-PyP@av3*zpfUG!Gn&~sxP-c5x*2)dY`;ak=z9_^gs#8sc%bAQ3T9sct0$}!IF zHjK$u@gKSlU@wUp7{y}yK$I^3k5Qo65yqBV<1a;Cs%2+JAFE|tL1%VNl+|EOEFPPV zI`BqjWAp}m19MIA8fi=Ty4WtfL%Of_Dg0FIX#Dxwk*HlQ-Gc9o-jaAA`Uw6y^Jw&$ z+81iy%>S`=q}E_T4u9-nEJ;t^Q`eGh$*+m7&uMD}#^=L!qInCWSkjAxpw}3RI0z&~ zWF`}fM#BuYF$|7A%}5MilX`?Y-g1)a@*>~Pck}EXYW9u1Px~6m`17)A)0WE&dv5UYSF-JHCW3BdmFAc~d=_(|i1>9;Wb@k`c#8T1i5zkir zJ7P=8H7F%fYIiR&*| z@~YMi-#c6^NQQvui_a+zJy%#9vlCyd_z!QM-2Jtuuz#z2*TzrATYZ}EytMb`mX*x) z493G-27;MbtU0)e?IE$YCpK>@$A@pYtwYb;jUT^h`(7(zM*coLi+vWj%mgYi3&!x7 zsd04ns9sw`0;2pN`X8$sNo>kW`9!NkCyyk>Ws|~pQ6^CuwJMj`WZJ?R)gCf?>LiF1 z*obV**nilm<`a}nM|3?k!oYvMohBUES-N!kA~W;j;>*BhJ~>P{oO&(c zG3hj@Ry(c*YDZ;OE9IiBlESd6Nu~ZEdnwZ;L9V3Qm_XQVgv#hhZAb;E&AF&3UGS(u z`l*VGxiqmu|BQAV(VdpWnc`*QPBV8~29L|Mjenb+xh!*~`O3^S!dCOv%q_wr{QJV+ zHHQ4SjzVWcPXi~9!#ROXrYu%qkKDI~t;8o)1SLZA5&<-Yv80nMmxVz_YQpfOPHva6 zzAmWUqh-3a1KMY_to8$mu~MT#Noprb;DHb(%2P#QstR?t5Ce6^#8(`u+NKlD3-MLq z9Dnsy!5T%v$51{+$`yHo5Nn9*rnlS%zxg(#8vZekvwl43v z<@K`?n?{qaVbOI7obX%JHah=Le0Ur&(+5knvZ#?day@y6$!04c)KC~TEPlJ|1hC`8uK2j3{~Hv6C;t}m zj{FU|N6sP7$hrMmvBHQyr6JZ&#`HZY#@di|tZKYjb*q}uXjB%#EqF9(nwko;+O6(uJ)6AOWp-+Jy6;2xX};vSH~kzs)$m(& zM57VX=}b+H7E}MBZsK$_Q(tj98W$wD$CIzo+8{$Fou=+a(>3r&jYq?2g$#sltwsY=AAI^UHx;W^I* zV;xH<3bgOPHHN)l0E_#Grh!1dtWRtF(0BD!|DcC@klLRp3(|oeze!OoP}jbtfA1=k z`U+K#nG7VFgeDxPwyk>nlz+XpHuTO(GcSbGxF(i#Y23qiG(Izb+?=L-sFc(Orbj0Z zA2o&CqO-u>9ZUEVQ-|yEKT=7HMrVk{I9JHn_Q}<^-aaK$Q*f9jbnayi2D1^pNVZu= zvqpZcGO0G8C{|W@PtpX4!~Yzc3*KwGKkzlv*DOa&M=d%bfPn&SV}Eb3U+4H7yUX!q z_Fm7^>~k!zf<}(<&tN-QRZajgjB20`Qw&2&^G2@`Q&CHlRavaAst&$6yT)?xrC{y8@8CzBHhEANHUm|vW zMCNDC_W@QL>VuAcw}0(yRj)+m^awh$d)0bA=85a#j+ol3sYQA_oCLS37Hge`+E1Y~ z$_sd9qa^u6(Z?`0UzGK!sBcFfYctS=`nIv^BJ)^X5fQVPs;bDT<`nIaC8~5N2xHuj zgTV>!er3ncw{1Cl-z`7b8eB7c?z!P-j_o>v+rIV1-8B}k&3~g)Z5S@Rc4X)9>+h6@ z|GcN~aogd?|MBc6ui}Nz&2U(~c|{Av=~Z{3Cid@Ra8%ku87?FsjcA5%CyZ8 zko)5osDEW<1%S6#qmsck1>4eBJQz=+tENT(M{}(m)X!q#$=pQsaV1Cf@KyYvA zpjKOQmpseFW#(nU9&w|2WAH&n^FiQjkQvZ?*7!2}vTo^p=6%yy^B*ljo4L)^7HpQ< zO4CgJ+RY{*$JB^YOp519&A3_Q?cySQskl($BH|Lf#PqKC7g06SJR|rW&3Cl_sZ}{O z4l(Et2B$KUOlqCkWHos7epA30R4-r`aSK$P;zIL6tJ-by`vbuRm!SdyA}0B5C`;Dy zk?U-AeNwi%J}H|mHIMO)Nup#1>10>MKczQ8taWYHmbnbOwmnT@lrBF1BqPZN(irK;J@$9Lr zsy&MbvU{>jw!67h#@8JT5eJ)q+JWn6C5ui01N0LsN#ZHCt8a|tN>wp#^2x-E82|_P z8;akJReMRJvKF=Es_;OH071_?f5^QPJWu_@_xF)W+_@X}4M784$dI2uUMi3;bx@DMuh{aJb;e-y`eU3%5T z4?b8C&PUx7h9}3p$>HC*vvY^D(;{}A$tZd3HD)ZT?)s$f^(hv;-sWc{iOG(8Yxrk3 zgmOl0G>Yw3X92GrKGoUm!qKQ%=M2qfC+(f?HPe}ntB0S$_o442C%TGKl|(1g={(_J zHO_ALDL074i03$yU_nPLf3jZ3wV3Qd`+%LbmvN1(3!0Xh7?a!e(AO)g!iT!3%SVes zvK9L4J&F<1TP%9IHY8^*P}2;n^7)io99{ei^3&C8`!qbSi&<=SEwdXZt=&ERR3^N; z-D=R-G%ba?Y1b@UyPvG)2m@|?7o_|EN~31xN3`zwrD$njC%Qebf3tAE=gWzwJx?dz z_xwKbyPUomU7y%mc%c6N!Xwcq3vYVfOuU)YaxG=%cLz;t8(YYXlrP*sLis=K&W3^< z%D~ATXsDMXNjQ1^4O601Vmm!=;Wwf`FZ?#fb5R^K)QhZL?e*9Kj;JGP&u8nWMrSoF z!5!|UiF+Bdh{Tpfe|TxMyQQ~fpk-f+;K_UH+Yu}Bo@gNH&T(pn4LAey3b#ieh`v?e zr53rR9R$FYY`3ag-OYFBx2Ui2T;uHxY>Hl!xITG{`Zn)vf!&3HmLKGPp8FvBkEpv- zP%NSq`{zOwv0Mff)4?bkPBmu=Y&M)M7B!Ak(&=GmLd%%kzn9p z+r$QPd2sSH8p<|EpR>$|wSl~k@h#%g!RAaIxgkz1T4Zh?#~?VJ=2+^aO=~bWAP!5! zgEjuK9LrEWLx!ppGL&>=!lKDYR!^8Dy3@qNrIzRMkLjiouIi=|t#ip*31Yz3)kky; zb&8Imj_4TDe?;;j&gSWIigf>l4OPhEb-Ew|4h8Hgn%s%GhDg#Cz`V!n_A+X9JQ`zS zg?Q2xFW?+sSHO`#yudc#x&oWO1`H#oyUIp~K4@3QW5E*44)r#Tq01Y|m#xnV2hj z^x8FFG%@jf+f8$?ecbW!M(@|IoA-r$lEqT>r%57|vRf>P_}KXy zIEmDA9622)lU8lwNs+27KyIWy?~6D=CS;@p@wz*h;2LyI!4_#oaE7Gv2-bN-^AMUB zh$SLI0#D=v!W2mt^Mjx@RkmtTEC%G8e2-D9)9Q2~YLab4gBY7|FW!HPU&9=x1|b%= zCu*^@TlZL*0XPj>S+e9ob{s zCXWw^X0Pb?Av$kDU29R@!-1&FNvBF;F11!?^p^$wfgYn`E=49wM(6Dn9G(@jwq8EWbT>P+AWOw2ao_vO$2Uw1w8%e!l&KoBu#K8)nY z;p?3!QIRGKHza@FQvEFaR)Sl{ZB=a(uGd_vzs|7LdaZPaaI;mb5q77Tae^x03ME`B zHW1?wuX+}*L@q2JN)Th^GM+4JaS7wjQTB=;%jXos z=8D&L3Wzn{s9@H|#h5Q1i3bg#707QQZifVjNxHxa>@~wFtck6txN#UOS$28%^RY7j z*TX$LZ$!Avzj>$!8H@pn%Z;jwe3&?i50Iv+!LXt!V}PN-Rg7F&8`g8v=^v-QynXi% z*WB>(W7mIv;a4wz<=afbGHL7F&f7XCF3Wz#7h^W#=rgO|K6>DeCw4vc@o$E=e)dY{ z*iDx#|MhkI9{$O-i!;>cA0A*j7$b5lSr#!OZpYnt58j7Q zVKp>=!(lYQEnG^pi$h&x{N{)^TslGI-H+I^;MsrQgDSqHtRZ`70izoFm~nmy-Zl?L z$n~l_QJR@J)`LVXU71r$y&Tul2|X_ibE6sy##Ds_Sd7Fpz(UZw(Ly&lp`3tG{j4%K zCu@ahEZ{`Qlrj-V5*D?9a&2dii^tnejv6{0Cr(OEh%b}hMLsr=bs2 zeun#2_Ex>>0S@PCw}--7aD=Uz4(!)dH^-z1V+S#+M%4U5jhW%tr@sO}dOl*^o?Oi^(j0 z!DPZwvMtBK?(PN}wzMc=TbmL_>u4xDe4&OtMoc#ISZ3@s9ygvcs*Ucx|+ExwUnuzqM`1TWkH;KIA4=GwKK!Zq7vg_` z))@sp2ZWzMzzlt87J-{N(vvc)Rf2{hDxqSAMW(;2zJA6`nGn5kq*x#hYLx*)(L9~| zR@?0bJATv`o3LQ$?NoA-`@n&Y!+q;JS{ee*!mMC0o|SzcvU7$W9SCQl(d3jB%+eXH zJHNeoN^NtX7`n=8ty}xXq!}<4Ze@QX%=4-Z$bdWwem`1vf8YIAJxe^;5Kq)Jtj#x& zjlvGr6dO=^U!^kM} zP$Y;)o|BXcvWZcNh-X9Wm=kr;G2i9AO2wYz2TdG`NCh1T)p$Is}8>K_nlX(HVkhZetr1W;dS^f+=?gv zaR1C5j}JdTeCXiqxCT$emp^qoV8Ik%!5-jw?f4Daayg5@xwyT5++M?8;}cw&yEAtT#Fhd-!)zw#FT) zpEVr&5@Mp{d#@5mXvhaE&Z;HfU7^pbU#aZL6b);8{O?{hP18S%tnxk)MhT23!nBrKh|4oi1=uQBa@pr ziG=K+;l4QPVxA+_CP6+LE;*Xwin)zpF^MlBc)<~tf_n9kDhKuSrL;!3h7pd>qK@&UVI z_V6Wt(b`}z>7ekEX_jf4I5RLW)M;8GF0yq5t~9L`*9EqS1KbYdF4GQihh=Br_TYo2 z2gUo%4+f5zj)~v$91FZ^`hoa;{|^GcFuf^$V0uq{FYtHM-^9QB{~pL_OtZaAFn~!T zA%7s?(-^g0jl<{kIs}II3U;&2YrigF63GUCB)+g&w3&N>4u~eBkt`lJGXWdJ1cLrY z5K<{6dqJCezKhHrldV+fa`P^tNZp~@_Aj^JQ_efYZ6{j!R`{nb{YD3W z5bp1S0TeL#{Tfq{I2@JrJ;9*H#PUvCby>ON!m{$}@;NirU4-bm79yKa$5DmK9+_0# zr(@VBhW_jF@VFJjix#;H6Y$#+{AQ_Z!O;8jOUbL>{Sd$W#=Jx@$H!tOSN@CK`ZdMLUJ;2zxsB!U5@s!PEwf9yUwT41Ch2jw zjPH^Q##N1rn9Bo)|3&u)6Qv?|f#F@kJO`Ku_Zyrp%m>bB=$t z{jWx&rBgRrnyRH1Gunqk%eyX^%P3aV=c(r(A}yckBHRAbjil1J3+O#!Eux8kYK26G z^_BVa2YOhJGEc0c4pP>zk>+%=pHc$Z;}t_JV5oqZ;_eM?`uN?dQ3u+B9 z&}Y`+Yx&_lv1Vx#yMb)p8^bm7)=!>Z5VYH}n~5*NmBZ8UZq;tUSt)#O3@*?mt(3{P z2FZRR=MND^UQ_i2r>Sm)q9NRWwN=?KMcHdbOOg%2^2jiK1R@_+_bU5kb@#G2Wewf5 z45?GpibS8JRwT)k!}}uz_&FO4e0}h zu0}cCp5Bvw-1xYEUs^4}#Xy=BA>~w>^$?d<6BB{t6gT-K^&+cBQ{(o3N+~_>Ak)(Z zK!DFQClQkclnG}iC8~7!$C7);R{8Cym3dP6*T_$Td;IaCkwdrW&Q4>9W7*+s1~SIQmBDzwogMdjjEVB z#V3WNJ?T&Z0~*SQx`{zgh3E4jV@T3EJdPR%>);LK6TL=at|SDFWC!WCE^+9kmtG

jR*DWM(E2-Rh4&!+n0KEf@i^qRB?`BhAo`Z`=h3$kZzey8 zs(o_ApA?M5flU|(y?iKQ3VQ9K2=Ysr8h^4aGB3hJBD}pO30=+zykJ2d(UbSco?eg2 zGc#L%*|8pFv78;uGJEM{ESt?>O0+N~Pl`|B4* zuHKcM>$~QXS(vyo3lpzcdRFIL$Oa50OQ~u$?~A6KK36OmPdVcS9QDB|;jSs*m^V@w zvzz_Qg@D2W;ZQI#jtd8*aWH6t2-B58D6P1EaPP--@nG7!-yZ>v{cw-pFW76!{GSf= z*liRr?98a9p}OEZ{V((k|74m;Og9}DW=nYdbzgjL12xFBd5J;hpN{;;o?m>wu76_j zQvbRy&A4S@p`E#5c=N@kn6nRD|L7^>bglL)107$QZ6*9j0f^~!6lUI~{K&=-C7&UG zsvQf-$)Y>7+`Ot$2zr@N*cJ3zLSc8%i$f9MN6ev!#mq2RaJlLF88`KHFmJN)F;!g8rMG!Qx+V)Jx?HcJc* z8S1zQx|VV&K$Hkoq8(2ARk0i=XYT=jn^~kyZDxXuvXwG3y0)G;N%%L`-c|c>=DJTA zbT5dzsiAkQx;^=*_4X%s(>RPg3AmzTs&z<<449?um~Dy-HBYPFz$;`Dm% zIXn{>J^`K2{shq%vl+QgdFG9YZXag6WtzE-M+ZUtEw zqVI~t6u+&MtN3#SiP&7B+#m{b6+<N2*0I z9dTPwpex%bwu_h}W)Myb5McIy*pWwuzQb(3`jO!%K7ZHn19;5l&DWLPlkl5+Tn(=6+bfJ}$j9B?)!>Y;=<7_5;^-j;nZ zO22C|28{zCYLGMy*Yb=F+uYe)8E-lmB3fi(uQ&JXP#1BL-BmHwYnv;7oaMODCkpG5Ix`}=trPY2RTNKq|h6{=P>tsBwV~$p1Fk~#L@w1vH_uR@{wps?^ zUYBvC#?Nh@bmeWT4XNy^aS?;jG(MA`x@pm>Z^Yv*mrw8+jpDd;-HiT4>%TEFQf(p3 zk~O{D*ATQtZ{0v0gD_Kn!=`|b>Z0v9e1cs-?ICjL5!#O9AM!qweIi%ReLwepPJO*` zvvZg6Rww6j`w|FqrjSshcO9vbqdLVzqOQ%?(q4;AwZYnfTDF!p?!E+0eD@;TiGwD0 zzHV%@64Qx~x`^d3S$ug0{;Q_UmDVJ)K}TIET2r;8fYkril0x-=Z_=+>-KNzUv<`=( zrgd)9qzyap$|ZBPTD`&HG(!tFPU*RI_(V;qYdo}{Ahf3QGy0dT|7NtNcJ;W3(I5yD z()nqdp^XXV^TL?@9eX!w=HxN*gFdcxHN?4Ez(eQ@u4d>4jKQCxZ*|;{Qi|YHen|1Hj^S+j>X=x*u zZBw<0ZRX~9Te8%UZ<(o^C(biZ3(SnqNzQJNTNb+)$J$#q^V@aX#qH+pj_uBS_`Tv@ z^JA{(;sK+|B$~{oOi&D(gPD{z<;=Bc#g;{yrH$<^RV%N5DAapvGj1jyvL%Oe*?5CX z%b_g!hCtTuFJ-eWrK;_3E~j``Q>=fLGx?^^#$7HqaMg*1hN4!d*B4w`4bQvd4aJ5+ zF=pBA$br;f1T5yz`?tBKpi?k1z@ujb_p!lMnlX&?mVp z>5u@jn9anvH(M)_yId`+#E?b zXtFf8pJN(<{_%M2fnqjM#==2Vz=h|S7f}hdFmn%oDk?-k7w3t6U{|{D?D?w7qAOkD zI7Q+EOr+Dxz&sK(LflvrlV78tnw~6HIf)HAUXM z2={v$f_k!G#Q--9G==Q(8kfjnhBPyI?#%-_^33T279}v#K=v9+A~b**4kz%{qG&3a z;mFALl2!55>resdmy&sZTPX#HS#S_LHz>?eO37w8?4^2gz?+@q z?QmGe7{LAW-=|$J;froiJ8P{g-oRxU(aIt+>Ve9ckvbFfvDq9|9R;$ZhH@7<3a)M{ zOYP+%imPB^FjuvY18kPKNV(KRL{u++CKZb491~~H2*+__U9@h|wlfQ7l!n`DLFm7K z?Tb@tYlnXt^~RST|K_auVyr9N|JZPOYaJVn+Kf(T*NGFC znOzAc8dcf+*N%MB(*#tZW8^({Kkz0ll*DOD6>2tXwrH<4-lTae_I^yQX7M)mdhU7$ z5QbJEsaCNOchaq9rDXyZ%6Re-DURcRaT6}%&mD9j71@yIpviy{neUE}?Raz^R3q0g za!q&5zM9iDT#Z}V?*ncrwi$V=Y~5qsXXUN#)P-$%KIxh}bf&T|58WKCt+g^OUNxJq zY_+0Od({lxx&xT?j4!6K_| zn#v|=-u*(n%>U&uu-_(^GC%H8nWQrRp9gwOhKuIMvE9h>7q&Y{#LW$sXk!5@E>^2+ zq}1%aw>4beTHzvG8%Z~WmM%fI~vZ2H@Vp&weNPb z(}Pdm`Q+sXvHu93G2AgUWygYl?q5&Jef_?t{vlC{H1cbH8}Q;K_R=wa=QX%F6}OS) zA7r>O3C5?%dpVtj(Fp`^6CaChV?EEyZjIW&>jl8nT5Vok;w?s(wWP1?&U{eNGC z9E5;e2jur4(x@rsW@$RP4$Wg4bzGemGPi}pI*4f-2A*Lk=3u9G(BZsqP2 zcKL44-JaiB_XYlb-50H2blvZ{&wF?Bp4{E}$Au>~PwJlZJnntM_oV-^+(G`Ja8z6N z9Lj$$|99c#r5X)1Klk1XR_ym^g})0vf)^;!g8hjl_JVIiuG z);6Mxe(5Eu-f&juureB-Pta(zKA+bg2na}xy~ygZd9BG@%A2%*=%JKEAnr|+>YBZ! z@<{JNuTCqKM>fi~yueF(oi6N!++L5*7tm<6L<3^?`XIrV^9w?l_;}6d>HuSqJHC7! zT-I4FiDVK4RmAADT0!77;~rK&QU`r@KrYrPW{}jZFXAx4wZ3G zwvoy1Znl@*$DU@@>~r`V%&S}(Z`}V5nRBV|Ey})v+Z6Xx2N@kauWSoMT7;P}Y;VUO zsP6j5V%3wxyY28S4zbT5KT0#IG5oP7PPH;|yMwNOwpC+3P_djb62^jhw5{l9=<0VP zQMps~4R9#bVUSVvtl}_87J0wg6tF~ME_JHYqT`LqT1dqp@`B5t<8&3KvJmpPw}z;) zy){Hr?X98qjV4cEvB=_D>JCD3CE9Bl8RVC*C->EIc~3snR@0oGC(0f0^#>Lk)hO{xJP+7$vf24#Wt8h)c`m}9Y2zl-ZorF3hhjtXdfJbRn%Paw(qV5)=DMjYLUc;=H*y~+-XTO^4d1n+OtfBP8G zQ=Z8J_Y4H?Ki|*ZxG812PLz=VuKyxLow~g)yugTW^L7nAFmIUHW)jCflZX4WwmE8S z<@dGK&nn|Mr$;;ugy{El8cN3#* zC9rTLX`>1g3R4QB2CQbYiE`Cq%lmd_%f0t}vx#e!R)~CH;Qr?KD#UQfo7sCfz?3mzSomdx;F4@xx?2U&3qeV002V z0B`{6qviOG4sZiA!#|>f_5V!DOAwpJlcwbjo)s36u&VQrm8{ zxv9A>EmhiJ;U!JiW3dN$<1iRAz;K0+CL0g$+N>UhOQvqz_GGPAN^nNc7uvkoycHuV zswuoVM%2mKF0Yc%w$A+gH8FKO1@0-43TV}Ot|-rBZDXI+-V|_%x%drhc}2#Jn`Cfl zIaRa2aO!OFStTZ56TJqP03l$j8H90P@>GKVAf>yRs(P!S#8usqOQB-^7Og+4hL>M_ z1_4hwq(=qp3fNq17g+kqO;)N4&!**TSL0`)*`Km3PZ#jfmc7Xnk1XMt?|rAy3wXE6 z&QU#ic?X&z=Hx8>1Po8ft*+KrJFUNuI7Fj^`EpuE@i~+Yaj+ex+qen=CX3{l_*mT? zuLsV%yXwg_M<_bcCj;z^H=p6$>w%lCCZ85Sq8I~@`v&Lx8pfmcCZ+cc=zJ^R1cTVG z%C$g#Yo0Kf?jc0KD%pjV8PpJafSJEyiPWO03v?F5z#Dco4|Q8-*ReAqeBM{j{%q;q zL0`U#+#-DP#hRt?Lh0GR)T}wTTHeC4wGMzb-u($kGHcLGQ4w~jL4Iq7=eI!?o>9z? z5K8nKo2sg(!8a^N9mOX3%xTHL5o@Y6>Vp*=NRUgMXTMheWdDgxao=9<1eEzI4WC91 zuBdPzu!c#AO$?5NAEZ~Tfc1;Ejc=@~URAQI|m`2yC3# zmsSx-O?D=76&|KKzpNZbhW!YC6xK&++0ykRC}JDc$ALL0UMZJEESW_*T6vqBE;dr^ z9{eQ#5Pa%-G`ljZD%M)80BlV;{eV`7INN-8H2&R?jvJ1AD)JsT4&6Kc7FkmFmv?}f zoTBKiJk~8shWI2lg7j2gmF|QGvwsJ6hRup0YCuJmobQxbD8Z};i5aORUYaUL(wr#E zPnMF;ujH|GQG{@M{}y4v`uT6Bge0$tN?Jy4;Vd@N^J!>U4&^Hi3pGe6)1d24O^~KE zl2?aEsVX>V^;HbWt?nG*B0?h5F^ncwm}gsh5eH2z-4cG9%>y2Xy5!hCqS!5imIDtwCT<$e_)kUFQ42WKxe_%5jn zMy99^$GHml2{}7!jux^PI1jR%0a8Qu^*28b}mOeg&P!CQH56T{c&9a0l%BD{rlbUfxO2N{3~TC z;E@rb>0;KRT7-oLJ4r8=*$5p7wOh z;*+3I3CeTj{aBB3ftRC^uUtq=UX+xGQ>G>w8V<^)CX75uT>D#Bg?OuRpvd@Ti>clI zdcqn780)~534CsM+Y_D*$`WWVsJo{8W*_N@(u>aKu&^l9DyC>l?wFgb9`emUhzz{awm1-9C)g@033?ajmGiLJo!6fIvmpTt~Vl1KSQx9 zrOtm%Pzq^?i|-8lyF)t575U5FIZ&E-txOLSP?4VyY^q4pyN&d33c{Z7p(~cjI*|AD zH-_d=g-DD<(u^G>Z!mkz_;~@@2p?~p`nINl-E{a(sdF@IEXE5+oR9wCltBrT^)sqJ43t@dR$UQH`UF{LONsYF0eN5I~KO;4`21 zOW5iuG=3I)!3*lF9QZ{K_5(0Wt0wo;lsZX<&10P`;M!L($7qJ10rsq9{rQqV#490Z zxL$dw-Gz_APVVtko>w~~M9P<6NzQQf?Kkj&(VFQI>j`s}6pdyIgT@ErU+=G_h8m<+ zh*8bN@o(7$v2;MtFt*HBVM+;#ldQX2o{-huE7NUuYQ3X;!w5F91&9|DD+lvpLQKJL zz00-Lu|n~#CQlYGo;64&J$k*{*n@}4D3=ITbWc^4hSTQOLy9 z<$jn*IZiG6q>tZ<3qWxZ_Ih9|Tz)N4ml2*s=bvzJGf)IqlAQ6^;raBBTC!H1e-0wK zS-;Twj3ZaVYHoXY4!Di8&|DtuTJ_AE@`c3x+7M8IsxM}1r*Tap_VbsVQYD{*#UmOI zcDwq;gx%9ZSIlV=jJhe1#fvQ-tn37QDrc9isx8a!U)R9>r-ize6 zxutEfbixZJ1Yqb%tuJQPQS~3%oO8Q=4+nE?p@p+!VZRPn{Y2_wX3Pn5KqAKbmXQu$80A>L1^kE1Z0aIcf zQ_P+pXVp|<5in6paY6Nq;7i|icP58y^5PFY?j6M zbLm3?95(S*S=A0Hf|NwkA&SCOr9eGe+*LoPe2~{cI%YAykWtcp)7j!0GT#^~8!|ya z9+t}M&pl~s^`DTSL(}gpwp7;2-?tGki5z}dZk5re<(?l7DUQJWQE{z?eKYfGo5^mP z7W&5{0d!^nixUs?5D^L-zcM$^9Y5k)y9V?%NU<{TFYsPpkO3blFpg*M2xhAuGW41; zkI0ufPyL@d8A#ou15I*n9ID^_f49fHF~-EQ65tT-MT?`6BLc+|WmS*e@Ma~m+Vo-< z(G@QI2I}Do!;~Ymf3cv5Ne5#80!X>>E>!iE1Dr%iBT#tiBMVyediq>#2~?K7)HiR& zj>##fN937Yqf}(R2?Njhs+IAnvZ(k*Gf%;9FTSV2+iDaSO4Kn)LYWZEfS(?J`Q=8y z5K@*@a>k^I4aT<`Bdv;A4)NFz033&pBOY@4zuaj)=l`D0nLz9W9`?^a$DA>;!!ej+ z05-o;;_{`a0=N?-91qYpJ&f9Y6P%($hDl|+A_9bNLI2PQE(DixYeepux)U;&bAG3D z7L1Ic$#Dn@sYV>}AYwlkE+TbK=m>yi;myPNqS-l)fVN zf5`0y;Jo^H#XZk5+}sjvbnzAT{HJS^06QOs9`^s=ovXOERiP6Ed?DNNVZ@OfBODGX#c^$xZjKvPT1C`F{IG^ zTk$r;{!Zn`s%t3mY2J3CfaEXo_v+{Mrl$Hmqqgw20J$Q4i%Wt$jG7CS*eKU>XMma| zSFF}y$@Cviv$OA-0@X#0VJcR8>3;+m2PbN+`El3=N@8+a;U*o^Po>WAkEKMb9ML@> zt1LQRh+SR;PzVPFYu3qzq|+~?h9D3A%(8l;XD{*($Eka7#WmOjpx1?Ef@qqR;22QR zLnCShE!IM%jw={jhzajY?6vZ-YXKZw1=WJrpY%#U{;*HcAgn5GUifrp6h zQmbJwlqyf_TyPfm@o7DgslH=y-40w^6`>49huRw7iyP^td*30%eg8Tbxdw!DeOzg5 zyzw60qG#x)A`M3X-XnJ1yI=4EcK4TWHk<-3ld@cobgu-NEnXM5eNNKHDLtd|t|zkB zmjxYtiY;~&%e*PyE_b`;mnDiOe%!=BDDB>a0B{_i*W3G>yMGC+u>aez1Q6T(&PBhY z#T;P!d{SG`{{-+K8aNt90vNV_j7{&m`y&)9cCPU{&CB`nt{u7KcluqI%K&?bC4`%l zqt8mZbuDc_qIa-RUf#|CuiYWEfPt$&+r?{$Du|OxpTq}Z{c5v`|6HVei`{Yy6c=XM z;s~vFGl6Hm)ZkKo{sr!`Ok5n#;I~*Ae^_IxiB`pPVj>CPBM?s?14uFKS zo`f@#ZNfbb5S{P%A%=OlkNWwrdRXGJf*mQQ#k^^#?NIhelaX%|Qc#+EJi|zgz_JsF zrw`7+mJPXipQlNf0Q|#=ZN0ZB2mYu}c`rBmuzSPm+juVw$yyNJSHX8~8qaP`a%GCi`>+t^C(s(bqZOVt*?RFJ}t5@^x;0 zdIodMne75en1{Ubu(`+6a72_x-{UG=Rrb;q5$S~22dix3nh=~w|kjp`s zp+mEZPq3*54CpNM%2y2VjNJdEs1{{BdXd#fbolV0m?~hHkV}g zh&cNXi+?*LRUOkgLrkxv=bBH{-Y|AHi|-ePiC+WMakb__66{m+phI@X884z(yWD)R zYb!cuYq75_S^Tw`ud4s0*m zS|bQb?(3>fuN_1TQZ{r#lLZYL@k1$1QFHHFvtEd?blVzo#4PPe15mnOvijc3 z0_4?NbKRo*AicV6VI^X?MF{idJj!1T;=-RKnbDm26}u~;P5FlDtT@%LB#KkxB>n=E z31NKbD#-8TZZw5eVaHr~b|;IrumCNwD~6wj60W#AToBco!e_Q_422T~MMj9%Rb5s{ z$z7OZTi*|*m9HeJT?KUEZc|XM!+bvqt`j8fa-^Vs4NBFdD~B(c@FdS5cvE;?yLchf zm{F`LkMbc@FNx5$w&R?6O`dQicxWqi7aVUdSs^+gz;V|++(-zpyYo0iMgzK4XspZ* zFbkLXUM}WnY%iWRNV=uDPHUYQ33JE<`p=`Mho{HaHB=9&63xSIlbM zD9+7QoamGo5x?th zq({TIt@@iUZN8%E)OkYUo35xPrm|D$HK5&R&CuA_GSw%~c9=73*ii?Tiy`8rwB#J_ zb5)J71_M5VwUZ$tLkDiQ>eiZ4cTBSE(6DJbK&|NOc;;G9f+W1h2S7mETU!40<3lvp zk!_&>*!KtA!OprYgLUprAZmFW(7h{ZerXtSRQulemA-lr#!| z99#qmbb|1bt+X^{%a*)&7}|lNgBtO6=$%s8x+3Q)1PVEXI2p7`)cXxzIjT!B0b-V* z*S?YW3G~olo0@O6P2o=ePR#(!{fiR3A})$ zrB&NxyXv71cbe1p818-}CfimPcedfrNh4H+;V=5O%BGDAN))K3%=&`q>9ehwF0Q=; zcELX*)V1#X%VT&JS;@bs*^S_AWQ8>HEIAG}eP|b60pM<5o|)p9v|j>TB0kmrZU_2o z;ifbnRl>bzW9>_-+FfmP*Ep|}ADFZ?JA}bFsq>FoudVRI@cIv$rTKT^vC8G5i#3E{ z$%iN4Tn{#Wk6*b=l6uxWA0Bg#=X5Or8Wxq+p>s9mF$oADrF@L45^%OrTY@kDZBo$( z#=VkUK(m_Jnl)w-tH6)lG{EQ3S22H-|ML8CdFvO4$G9JSyT#v8NP?T6%RDo4R`#jr4JubwQj0Ys5O?qAs|t(msUYUT3D0)HMXAhrLW z3eYo$TQVqSDUY|BDZJ>*yW)4z&6w8jBK9BsKoCC|CSZ8M7*in0)6g17M>0Id(qJ|Z z2#Ld-=#B~yN!e@E4;=)GMdHy6y)4hg_PuG8O@uv`sn#Jluw#|zzb|lLXi@t&=HG38 zr5`bVaS5ymy*@0fbB`&wy+6+2#=n`-ynZo2s-LcZXHVJ6iYV?~M9WPD&LyYCQ-Wc2 zVqDRO11f0Zd7)I%;>|=31A-qH&}1Vlg}Wq@hiEMH;g98Z+LHEKY^3v-4{SLPx*^9% zrxhg#Km=-e4N&aIMGY6N@w_m7Whs7N-H+9RO;zV@+rv^S4Hmj}XDzb$Zw8U3^im5E zr$w^%oO?;qIt|t;BsOxOU}=mO^4Yv+Y{9v303V<1jJNiT1yU-zLlURU+S<4&OmXQz zQkEMhuf15b$!O|V6g`pMqg1oIa|VN0wBy$GhSX?c3FP@FHm7jn6wh_G>(xse5xM&< zVVM*YH_UADxxeWT_7B8-;EN7}wzmR1S!~cWkX0W?L)l9|=HidJMEw8jb&yf20j z;N=>9IYiF+QG--NB6fsz^+H0NWR~?Q#;bF+o90N<4j;qOTxO zKAjg8I`nG~p?0ROQe7n^0CjTm^&uFE#HFqqdG3!_7;Hg_kvT5rB7(ZDXl+HEC4l^Z^utG?z3eFi1Afk;TL>RbCj4oe4z1~9kY9fMQvId=q`4P4K!8Vs z*-MviU6O<; z?8{nEgXN8gSLDfjq`i0sy(QYqVB1Bj!~~tomJ4y##5u<3l%6`0jdw_; zGll?4`yxK8+>NMU!dx->OGK;S?PK|B(-r;KIoEDdsa31*%*Tu!)eRk_o*O7 zS5CMbvWAUbRj9K)ultsBe zMSU9*yuA8gKM;5-gOVj}5~q?=N2@BSmno!8q%cXOCV-drAC9Th&74pUuh z4D2)=e*|rZ(@zBnGI3ldwY0dCkx1DBf<;#CrTh&#E;!o5D2KjX?EGGqfj-eK>Y#AL zq!&oqB$xY0{#1TTfRYPsLXP;9y4eCeS=5z2(Xi^YstTHEhHj?S*9SdyZm7x0s9W%n zl&lg~2@5HlE0>IwavD}$3#lGq)rFeVH3n)CJGOkr{@-#!p;ShBRNqxMSFK_^iEiqt zLKY>3ZF4%OtA!h4EL4k=qj?`%0TFd{s8P&>coqsQdil5?0GnIffyxOq^Oc|hL_|Fy z`WbDl@&?<|qu>ZR*I9L1hG1^aA|-(2?}qPDFZ98)p+U*NKlBG&#O1KCs8%MuV@7ji zqr;kqGxs8$KT4Y}4x!tL7;sRL8R|AB(^OG$)ZolHs;jhHBP}A2MmvLI>*9w{Om5Q= zKI-9x&#Q!b00p~UD}Qm}Zj6(WCHf+QKLc~Fl?$w|f8OsJR|@$t59Oh%z?eA`UhSV5 zXCgzwd^i$f<3vH`s}TOa*$K*1X8vaQ^Dmd%3=#guutqc|EeEhG3zjY427D34o(70!cEwZ}!{9n~4WA_sWkT zU{6qwaV3Fa?|zV&^^J8mEg_{##9qQq*C+Nha>P3rvoH8B`Aaw`c`fO3 zu0m+!mR2Ky+$)4%h9=sPu#K{A{U2bx!9tjT&RS!y__-5A~HM$90Qve;kDqN(we_1kcnA4FYf zduH3*e2hFdEJv_{&>!M{kb21spLl{6pS}hGirGosR7OzxsWl@%K7q(PO99vIkHtmB%6*Oi?%>ylFkW&Fb6A;9l*XGJ#)99K?(a5b zn|(6gN$`>YeU^va|D2nZl}MSq`tA@eEnQ%xZO#gx#)2p}&sf5G>rf2M7a)B~k(b|m z0^3PKfAxDLO9F2Vy~j04yqh=X)moqXI*$h5HyyH{79Q@}FUSHV0<;2K!Jiod1*aTvx_~X1sz>PDFN@=45UOx%_kx@^y4oaXt7*7atx1j-iC(+jESyc@= zFcdGYn4erTTi~w`@E^F(dLlUz87EqFmjx~=AUgFEoKP7`Ss%0_p~$f;@k2#cI&mrhmixbV zafds&lgz-We@$3}*8<}6dmB1L3sMgl>zQNjRroU&Kg26EDDrE)M+t07SxzvV_exw{ zX+&y_0iJU8;N4$P>FN9qQuZ>5>d0yPh{wOa(NRD_d?prCSFSBR-uC{S6Gbbd+blyS z@8NHoielY1xb}+Wj%AP2w|Bs|icESgPin0L5l#oIuGp~{3(4%-DRmvb57iHi)&B5{ z?`n01j%J2@?S(NuMb&Cn3u<@Vn;#JRFe6~u;Mxh7)X(|>u*^|yF{Gst1C#a0V3K(P zQMmk}V=;BK4Yqk&2%Wk=?Ru-AfM7}Hu*}dS8ih?1qozc2-HK>ENYVhVV7aH`4rITq z>ThqeF1d%o<6u?I^xdMN?mhU-knvF0{@;d>y;PQT65_z@MFR{@=*RpPmhb3te1{ve zR3i!dNdy|z?!4PI;%eYZyShFXPG<&Z7H2X@&aI`9CqoYy+nhQ#)=p6yMkPRvcbA@C zZMKV@snNgeF}$#D2!#Qb@IPU4@p2(5Q=@y}J(`h(xro1GL#gKt(=}KIr9{O%*NaMO zkvCVykB{t%dQV^d_4)R;LT!vi-2VtQ!UXGZf0n-k4BY0zfZ3Dhmf72S$>C;Pf;e{Gt`+HztAVyFgX7xq8m};aP@D6>)7kacU(|hNASi_{&IyRPZ1vTm} z^FnugK9O1g1J%h*q8$rF&oQ$EuH@ z;ET{Xr;Jpu!iU>4VGlJ9vqNCotF^C87FB1Ds~Oefw1~rtBiaJA`@w?kEwfOx!n zSWy6%39=6m_QXqSXSM{|rCq2ro9n#Fb;ut_BbnqM0r*vkhn_#kvG95^D3;2qihN!* zkz~%e9}YD0sT2ip;^ZKT>|{8Zr{r?P6GmTQkbvcx0*LnGvsd9)uWwwN%g07gu^KmZ zZ@YM!8wA^bt4cr@!fu6r)8kA|=aE4Ey;r~xqCRr+qr^)H8IU1P8x;6eM zci`xUvPVP>O1I#%!)i)rSeHRW?`PL+-&ldBT!c4k#QVeSK}9p!s;}(aE^Sdg4h0C~ z(E_66bklgWP5j)Opm=X7Y`Gzm;d0lNCy)=1`aOu0wMdlrA@n}$6M$%8BY3Mwi!+lM z#9}235tGv8;#QsqTH!u+E%TJ_k-IZ6+aIOLhpPhpR=WqPDhlPuk!zt+$z=X~J=SJL z!Ap~SWe4!=%0Xtr0sKBUL zGjBLhP7|QRC66vDskYv7WsVs*&THw1nmC7in-&hQe%P5ine`Xw)o9}wcH8Ri7a>k% zCqfA4b2chapkmQPat0gdp>puIH9MbUo)$%wB3&p<5iX74g4=w}<(ObYg#eUmSK#%j zIbkiqqMKQGmCt;4Zlp)`?x1D6SOEI`ga}b&T}&~&QU(PK1y)sUYM!SIuR3-sI38ho zeO6VQQ;u4ma!)#T5%v9xvvbZ%<=mLSx%|vVtU;v?&jBsZ#kb<+d|#`MlFs_A=q=hL z13=^HB;~ku(iZ!?TboVODZn%-783cl{++i~hM;X?^q)voFd?vR*k;%$AzQ4dBCEhO9D-b#n&E}`p0@)4b`$htAqJE`E8hWhKNIz)~M_>{Z1<`0ke|nCaWhk4l7$( zj%C}e@-o`h>ea2fPN#OqioGVqjA>4Dy!u1?xYg{stlFxA8pWoVMZkeAVMW5Zt(SsT zY>j1Uv20l?whP-g^#W7pikj-RBQ4vdH_X*Nt)o|%Ipp#h+ z1UFban2Ipwo7zq@m=Ltz_rG;a5JHI0NXFURE*TqG*3xff(6^dvGI-|Ge#ZjYzCVP~ z(J5mIIcZFL$}4eGf^8i0M0>_`OyzP+OD5{3hs2d>}{;8>0!ce-qEUi-1vKh*+D_n!*_@0RYR})HPq<#-gC=aM>G19 z^QO5-q%*I(XL819$M}TlC)+3yQuwE#-HFk@x5C|Wc(>Gk8zLCwSHcHpVeDfdTb z+w6A#>fAQqx@TfLue+#Q3XpNP?DML1(*UZujp00uv#JGoYLCxtn|0HFR8^xK#iBbRLETDj+FI#(gcKgihPD<%m zC!|q-jOe<&pj)iz_h)eDPf(3p=8GPI)u##qk^L*{?dhKVi!1rTEy_ z{eJ@FVENwyWK9y${sH(OJ+ct9bF*`D|I@6in~Q~s1H4z}kdZe_#7H>zay)8-(+elQmIgMT$uIZ08}zFvQDqbMve6 zgU1jw-bhQK{1{qU+d)53jmIJrd_k^-R;e#h~{!Te@XPc zI&_Ln3;jH9Mipfu4UIkb{1+D3`B9-1@57AnK!$nk12H@$(%{9~)Q8QBY zb?14R(MGsJ7}UDi6v&8vOmZXWHp{b7`6AC?H~{6td1Y!1|}#g$_o#Hb0wF{(@@ypv+ zF90z%yi~q-trw|~PCP9=Eh7yBT}^3ax#ZW^Efq&6=1U>M>9M6yoIb3=7p`E>H7FzP zWu8d3IoH_o9;CAbIRYPP^vD$Rn1|wnz8RD)vUvgnJk$Uq0mL?*VAG0r4_BS&;!6^o zAW#Qlk-#H+s(m?_5Jue(5j#_ZasCN9?ZQ4}YDT(mEsjRrY}Is&_#ho?}Vgl=o8& zKD;ajtp3)o2=m?Pf=a%49xc--I?Ikn+}Ne}Emw;N)rsx>I?HZsN76|nKigTnBli8f82m>(VDr}#BIG9^dB=AW5&?0 zYEhUs=;wy80`rgyb0KfJPJ`PT&%AzYUFZRx`%Jq`5CMP~K(J9?&Hnb@Q?9}<8CJvz zeQOmeSDbmo?#2n9Bi$pcBbMinUoSlObVpnh+d98F{tEsZGWmT}94$0XNH`q2b>n{%DBS#_xMwXj*ua7pRV-=Z<1 z?AH1G`%d#xac3ieaZ*NLOO!EqD?zI5Ht8PIkBBc!lbi+vFg}vLLi?z^CJvDLqYF%P&#w0%3r#<=ZkzvR_RybN zl6H*mfYrC+TDYg1_{ZbmfkpuYZfQrSn!&shjlzSFcD@=w-*y^Oyb*=Q{D5i5$?x!O zao+F*B2p?u)q!gc!f^%N1=D*;^l?hxHZMi2W{752qZ?BSi*eI@(y~?oG!@~5ypcbY zgr*0IzrGcGEA+)yrZf4i;49!$7N;L7U@N17Z1<=#b9mol02R;yF)!8*N}!1&!tEN5VGGGMWsMQ zGsw>0{yryO08bd*Py|K+y2^h#b5_UY>zSmzKs;`#2Czkji0`AZawH`V*5B58mAVsJ zkzH0|XjLc-BeV)Ef2Boq%&+GjA%9~+D_)i-O7M_DKauhxY09+<^j!su_LNRZyZ`or z9n)`==lzVup0*mO7^Gjj&&&vI%geM$BS7vi{`v=$F-J5OHG|1aVS62J_>S22O*Lfr z9PG!x0}7a~Q|N3G@_q@JEeo>wie_=NKQ1s&@1F@8$sc!U{)1R7AarXG-!P;r(l98& zEX28sa7;^B5MjpU;P~ufQSNq&!ht8K`R zh6Du>uyy>E{TVqU#1FT|umgT0 z#|FvccK^7nJ*y2_r5S4@K!|)t?;<1p#d)K@Ii~q)!!5U{1gDO#T9X4R<5hjs&rKgt z1YLrwzu&Yo<7{8iztFp)TOP+Iofjq>%NH`qu>aebt*n=ulElemIaMn{YkFUF&G-D6zcw$g*n|XOj zYJrWW?0DaDIp+EpZ8);A(qQ{_@$Z!7n>#4jgMJ+Z@%D0C5Un-&`vJYa0^u&OLB6H& zSeOpu!$x>7xQIV_Xk(_)7JvJj#9bjpp@!+(YcKdHiJM7CL7w`!NfSa-IN}3@%cu1Kq*#xp z0w>DfZPeV(4BD(AI`Xy{_7K6?$IJK1Ng5*7Y7{K5w6j4EDc_(02H2{xPJx6t*jk(q z_&en?+%iIph^``^J-)Ei#9p6qz;KYIn7PT7fOux8qNOzAp6k`ExG6s&6*;L>uwWSP zk_teF6=0R#O2s{JYYg_POtk}OYOdggI(d4Nf!R*Pn&G{Pxi;vK1>IX`*@45Ai7#`{ zi_k+OY(G8Y%>%6#zkz9igou)B?Ie)jGyRy?Od z2IDlP ztf~>gtAfDxC`x_-y^O&a;kkw#e+%iS{}$2#{x$xW#-x96>!o#1NOaxb#oi@q{ZK8b zI5o;m)HHzRgUx2!xmD$HPQmxUXXbf+ttC_)pa=vRgE0e+=xBecmpCupYCJ+VbbV~R zTuJEfeLUW89=EA{yu98+>uEeOb7EJNm!mulUm+Z~vv_{?dCw|j4Ot}D80mh-Q6tMf&fow+!n$P$c&Em_tp_ohu#At4f| z;gVqxDKr6gGS1#QHsojw#$&SMa#0TKg~1<9yhksWU7rS6aq&I}mql`{0B;p+9hDPT zO}zfycVt06H?h%Tf2wPPm&g5B_p%Sh5-qyT#4`T_P*dxuad}U-{cy1Ym*8DCoB32U z%Sp<%VQb6JhrRIe#{iql&SP!`2%!j&t@-Qp1OXtC=1YvHVLm%jIFZVoM<@z&JiyXztzc!WV{HhOdvGZXRXobMn!WeePI$e*9NlFp3YObOZ zCAdr~<#g68)-0A<$_Uq4m#F6}@%$!&(zuMX>Z-#)lstrisAiI!)>nxWXNb zj$jQpId8hYswMU*-w8~X(IT6RtcB7P&0tvf+JY@wZt$WdFvw5zokfV(UY@e06g0iR zcw_Nwn5D>-h#lzhkk5Yz-;A;JCs2t4OPZFc*An_vO%ZTot3lr*cp|#*mhfHBBOd`} zSFX`5S5N4XyW(%&!dw*B2x=Jho5$Z8`z68@+M#NC&*9b`knqS{@%#-B*!4PB?0$OJ zPJ%YM%mBHBB9-$7=Gm)opDnYW6U& zFgEddN@JiaCTx8ec7o|oH7@Ih?tTIsEEOrxRe2iug4V18;uxGZ-wx^gh7zmWLuUA# zPx5o!=v2wLUQ>+!;S5&J9-z&|9dm-%TpZIF4%mus*W;iXNOFR>gCFCkKQIFDpc1|- zn@}?_2~hU48js^PPgpC{zy)uhL?ve?s=(XJ7tGrE>q_D^uS1S(L4QMEv={)SAA}Sw zaITgz6eflh?Q{CggeSz-vouveI+Xx#y?r~RI`<7_#`LZQV1KJ^)f=W+&C(c`Z}yX2 zdwL?Hzf;);HSp{Z!5P=w@G1F1c|wR#{bXVOCOX8tq#(S+8Qopkk>4@#O`Eoh%Etn{%7Q4J36 zv9VridT_D?NV0SoNn*(GWf*8H>cfeZ%poN>A0rq3(ZWPA8A_Uklmt#iQKW@%`BKCe zWxj6V1`;k?F+&V0AM8n8nP$Ql*infBRJ7s{_%6KOvXQcpG+4P{O1g5nvMk#Crd&{{ zEZOgOiRC#F=qxw_MEMvuSJJm-0eYmaOyttQ0SGAJ;NAO&#>Si8Z2dT)k%DVS-XXq zWKOfpY0GZNYN0NH$`M8f$sXBj=$u3%IzMpIG-#0GQ*v`zP}x(VVkg1 zZ6#=t{VoNS!kb^Mn!%ypnQjahPPx*Z;r1enK47FSd(nyB#d`MOHE1j#_h0Imxqf*K z$!m<+Yr(753<8)vVqh`g`hjrotcsRYy!yXGAky?(X8b?-Jrxgjn7z>9o`Lb`w7KSi zfqBSQFeC}ddp+ph?bOJT;tdI(c?G|}^VUvxEq|N>D%-PI{(7f z_zbHn_ws>gH z${dPci1)VVJ*8`uqgkX?%4+sACDQgi{*=eL*LXd85v*z<3246SJqS^-H8Cumt%+Ub z8PFUTJ8JvG2`DO~~2Q5I_sR+7|hYGG1l&_kJICBO;9!5Vx2jt_TWO&sx%8E4kQ zPKP;>Fef?^MKk!SYDA+(`%D(;r<#o{dLP!IZPSJF9e8#RbB}yfpY>vOm-cROnL>&f z?K0 zAG+qu>Xyr|+dO*X6=%o0=T~=jl-G79`5pcKs-0iCDvdl-!s`z_`#nHzOs^~^P3z7FU*O7 zAOBi90kXl5Jtt8RI-%MbDm@d#C6dDyh700K8?Leq*dDf}Z4%%I7Q4eiHab1Xp~YH@ z&ZE^R)E^DW|7Kdc{T^Q92SLKCecV8Ft4>J zq*A$Gt3ixhrVIkwpGdZq25mMcdJ-2P8@^63@)`lcdNf$$2n4tK4{o!kasCa7#3GR9 zPDlIHlzmZ4U-KK{Os=-pXsg1cpKMk8+Y1u9tGVYbr27l(#L@j+!f8hwD2k_Mo86+d zALKpxL{fOd&MOS1Dwte$Qvp6af=9ZE@RyBj0XGNogA0=KXPcMHYylpB)srYdB%f2{ ziZz_Eln)4j&cLaFq!1ho{x7-wL(tsqyoU<}l)OhD2>SlZ>HN^^@yVTeh-Wyx0u7PL zAC3zFgINn5 zK?>w&UPKY*N63j3fKL!}3d$EPU^72DA?Tz|Ei$JW(_=iwQV?9XBQ()V18&p}>jR&8V)w#1R zM_i(EoYW!>r(rrZJsL)HbvW`3%z#ES2g?CfWCV}Yf+`I2^zQe&+q1Jd!m7FRbOtW1 ztrgW^U(oEAVs8Nzf3?>FGP{X~k{?iCad~!XUFPRSp3EAus0=bOSIe5Ij?0@|uI6s0 z1BWvA9qRp^-*Dx=eb+PnnVYs(1;XKA<#u+6xXyfG-!}qw=FX`T%xCXBOpX8nB_bvS z7~~Kru|}c|_ZacG5$mN$hB%*;lX09(9rDTO#0iIdQaW+ce}sG-nK)U4kWwa9ArVn= zjhbk@YEk2*^SESbsXD9q5?cs@>N~E+2h|vVQc@OcuZbYZx?>Bb4ICUUsy+!T4;SeXcI;3gD8MM zcM^r5b`O9qe;YazVw4(}Ca!7INUAh|m4SLHBkHM)Xr?lv zl*))wDkD0ojLd&zL^C}t!+II!Wv68fl5sLdM$}YQm-BD|AOfdCmlbgVDSy(P(Xl#5 zFsrcUI){t~vQROjre5ft?IXQ+o@%V{qY5k4SI9CZS-PN$K%hD0`co#(L1>ryvnzDv z71YbVm^UYLebbFgJFbdH>+sd4m@DMTt0Y?GRA>vRlUH}P^h5#yI#e6m_WcuI7-09dvGAA<~@c$&}d*7tZ?dGJ{RMvQ>*CmTWhfX ztO^&Z1l5r0luEJ|3`XVP{Up-m@|2$S<01bkKU3%z{A>Mt{o~+~&41Ymbs{JvI35uZ zoFo4P!C82glp?Gmn3d}w*(t`Dx2I}|oYJYSO;t(eJEF|8HC2VPLW=#=MS=Cj7hiNijv6XQ?O4MnPre#3lB2Wai9; zX4YH|ob|14*NI4bp&3)(`7T00=j(~aR8+WN>F(o~D}c$)4<TqWgmIi0K_?hdlbaX`2m^Em!iZ|on13qLrpFjWjQ)@o=%z-)AujWjyk_T5^v817Y zUO3EK21M*PF3zM+ANJ( z$a$r62;F=Ecz=WftF-Erx~2`cX}4>4qW$PDe3$m-9AS1*xPS`a`Sm$i2MB8VDqLPh?G?qNdVQA;VISjN?6) zH9;Tm2?v7ua$KG&^OQfI!l{Dq)Zl_VeT^A%Asdop%72p7Y0WyF7S(78{{W(|p^GlW zkpgPaVx*YE%{Z+U<&iLBwSW+oIfXfRPEu5{>U>9Ga^k3+^9^PhmADR3;);~Ai0gg> zk=b%?#%us1kx-B+b2phYOURs=y1KJdW~yb)Oq#QvZcb6FsFjnYvaC)7{f#q`>k1 zJO=m`Rxpb2PtX@}nmHy|FS0I2q%bN(k4D)!WLK-3ZtB5Q`oa{duZLkcMP}7i&;bPh z35vvS%>FBu1jr@JNflCU$p;H(;pU|p%9-pzN6+xqLjx)NY9{nC9O~$%DxGrSeMbQU zi>A-9YuRT}5dBHm_MU$Xhm^QW`GEI3%y)vX;NRolFmjaw=QDBhN?*Tnqi?5jr)tD| z*z{G?S7D<3r1^yR$>4Xqr^5z>Ehfb3+-J~Ppx-n2EM_Fw4D#A<0!`8Wt^phVV2`Nf z{&^C$UWauFoZT_Olyxf&rFx8y;&DjfJQjW@%!KuBpPO+P%d>xQ#6FRiC_O_~8ps-~ zMpr6#gt9v-M2T-FTZP?pVW9oo2vz*g4|BB!Pz0;GhpUDufzu5uvRa2nhQoA+1SZ}U zvloT3+aw|<97z1I@^EME1!L|rLv}7DYMypg@Mv#Z50cOR{hETsomK5-Df^~ z>~pKDnip-TcQ}7a+V9!-rux&oMs*>=rYRz?{0!!qrPSZOqJhViK9zYW{Bc zyOCdTzvuqO$zxnNUdffm_p5IY-X3~b{gq%^{a8>98lYAYvuNh37ieUH8U(Ge*oW?B zd>E7UXH3>r?xA{Ji(o=`8&eQan)-9X?sMGj@;RLZX#jt6$cde4yhZRj?zaBfXp}}0 za-%n5R2#)Pl>jObzRUJG%lT7F_{nEHAgWmWT6lJ(=eysT>x2ayUUY zeZeAYzmI<_co$bs)HJ~cNfd(FU$3aO1i`R|!3%B6uCPPb55GS`h#;5L&jW^NQD@!I??XhNe37_2HyVM|>{{N^pdeR&9MaJ^iOin~&J% zp0M-v8n?q=k7lNnU1*prZ~)&S3tF=_!zHt^ZLM?>lx)j zx}!6$F2NQ{@aJ*R`28q^3x(SP9Q08?x0Bly+|S(@ zd_?;MC%;2Gsbz2|$RJP~{3@N=qq6z!9-Dt!iIt4PqqG_<9xD#1P{2AG)N_1LB;p|B zPZ~J0!N3KXpr6Up=|SM?nVmq$PaD<@*d{8FF1dk z?NgxU+H(_lC)t3S0ybsH3E^&IRd>~XT|q(tvKMSSadbbIpq#AA{xJ(zqABNUYvoxf z+>I01FBcCqP&r(IONdamWu-6`xKWm6mu37_?gH25%$&B%TkwCI@LR3PK;6`ktAn@7 z829GypTXDdYfMzRI7K+DUVpcw`h$Omz7+FG!(l7uHJX%-f5tCmlECX0!u)Cn@VZuJ zk>H!lV589|sJs;ly$RK#R-Xx4+bYB56^@V(M90gI1(G3O9ykPZpdsX|4F*L0Pl)0` z$QMmBuRIYHYH&r!R|9S#9&8NxT7yA(AX)C0V~Mx6xL@M!SE(d&)GDj3$%}uQO{#eU zjB&bPz1$lpMe~l%8=rS-o@AcQ=G5u+K0Tw4I~|}nI*5XJkK-A~X$LDf4mudeTmC@2 zAPG@P8kKw|c{<4o$%9EI`4-Yw_$ru+cw+-yWcLJ0dm7F*Fh?848%{N_DKO47unms6 z^U}=HNk38M$f`z8(V+4O`Zr5!!@P^ER1TAs>DpR4`>KaY`+4qsw)?AyN}dp>%Gv!# zy8aPL6}dcWtyESRaYu@z1zs$Zd(=)Z)@W0*VlQ@Syy9U1n0Hf!@LHFKdjTL8>^w%M z3290-!n~iWr5(}^#Uf>g`qY=adjUTIxR?BU0U`=}?bk0_eWkziwwEY;0W5#MBXjN6 zQbi~vjkT;j6itHytq^lto&8@ruem_j`ROv>SzwG!DqO!i9JFHCixgW2YJ zDp*Vk0c3)L>{%66lw&LBFVw79A1n^;%$%m_-ss zu2e}CS`CsYv|6<~jn{vGK8?*#1vSEQg<6Xx=qdamk|Gtu2^s~KDl}ShzKBsg#VR3V zIqnhcDM`JA(Mx<1M&i^XvOtU+y7&GhE)J6&%=Qc7DqKBi1MibbDnX>NYJWjO0$d+d zN)eSNTtbgl`3?RGzoCTLcjc!(l{ufW^x^|}njQG?@afDMTzG$)u|dIWGOg@=(k-YN zEya%t2h`23=4j;b(v$AACq3t>y7YYI&GWBcaPv~OU)b1oeH*)K=|=ZJJ=+p!u5DSs z?i6;m?U>J2EvZ_%$<4-uN};NSjVPj#Se#YYtLLkixFEIk;pRu$9$d`c+4QjMp(gga z#n&&{x0Ky4+_Zn-x=wbNd*{*{>e!ulhjY}$La!}e;BWJ{wWXP#2})s(SrF#9+-~Bl zUX09(7o#~sbz@s-uG{6cFJ8p@7qlRWEN_8-Zm0z7GUsj!FrUg}KZ|G2n2`yh{r(X6Tdk@R7%a?x@0hpjq2#L-Fvo~=l!6cS1 zTSP&Sm-8}S@A74HiB}_TQ8q4LMkvTYSLJ8S?%@=*W|^t;RIx~Pr@CkM15u83=Qany zBH~+@6W_!k*VXRVanBLqEdJr{+#k+v3|=HzI(9_iEy?W#$g*)F+{Hb^>{P6Rsw~p- zY#1(H()xeHdk>#%C@!kg)X!PaAIrNPZ|d2#s(!^IgI{{2xwx>wQCq*N*Ps0Cve2xaA$zkass_9e@&YFm19=jYaz z%oU=xxi(k9it48PnpK0>^sim{<&q_r74=oVShRmMo{9-oZZc~3!zf!1qs)e`{|3_G zui-MJ!1tdBtd$SS8Qh?yA#(gTP(ZEtex%2LK^6$HGK`?pE09zn*JM}6)2ve9bh=Lc zp#GSi<@8wZuU;S>!WTy?6dY{2r00FrsE{N|nzX zxru*hUGB9pc8$$xb4R(TDQeDhs=Q>u&qfSO zdV239*!rxk&Dy}`_X-=pAtO+j7{v ztRB{4FBkSi%n@Z+8gV%7PDZBJ8pD7mR~TCq;IhfUWzgutSnFoM#3q$BjGPiMU~&XM zoIQC%<}XxD2XXY6LT0Rzrl&7}wpYd2ja3@>nDq3U6NW07GyD-ODe-Bml;AtAy*PvD z!ZR}o&}~AP zZs}T0W_#u*nap#U5C8fc*5U$u+rn>tA@geH{s+d21?>0@gsHcaQ{D;C zS#)&WH-w7ta^bUg+OVg}osd zW=gZWARJbjLj@L#nTZ!D6iNl+Iq0p|9A7j_oF$dibUiFgWQ}wbrp%Q2fu%{Xy~fLnX@z7 zeFxt9_Ry_UzrJ<yL0z1U3<8e@Hgx9uh|RG+i|o~P>Cys5#EE-%ufY-&|=XunDLkCl@YRJ$b{=u z_oy*UDb`Kqdp!0u?w@}&b|em-#Ahk%I$xE7nSnShI8Qf0>Gs6zmA^}bfLumJ#6?zy zgUpZfYeNpbdeQTre)Odkb#s==B^A!doJ6I~)>I|UEdWk!diMCP$F{YuTvX+@s1_TX zCU<`KPnn;QjSF#)M)G%PQxRSyoVQ9GN`@~fEEy^}RPvDRW%GZ_wl{2lu_;`5R(DDRVeUHO1ns=-LU zSflxY!XxK-k3A4bEG{bgb-pJdTa57!q#l`{_rwB0EJGT(7Fjq8W3eX87AtF$+pLqu z0(((j3>RoL_85O-SIFdgd54^-2jigpnEbT-b-7GWB#XSbq6N8C8 ziGzuI5{kt2oOQ^0$jVxsLJ2NG;#uQ5Kkq2cZlvTE$KUU6hsiUY1&pM~L`~e3=FXq5 z&B^<2QP}5BK;%wDWbN$UHBf6}n233LN*;)(#1JfCvd4cTh z{P<&;#kr;5HI|^s9nK8iw%2QZl*<)(J$ zjn-S72VH+RyA@juTa3F6yNx#+9+W+#z2Ek{?FTNE%!(pS)&}=p>kYOWUHjZmNS^Yl zQjtx*U9z3povs^APwM3rI)gDZbH&6gfYbl5!KjmN_OQCm7A0PrGGK#qD1sx#@b;6q zm?|(Jrj&Y>PsOO(9gYixIZcYL^Ih3a60e0+RsDZ4d;bFwHG~MIVj`46R<}&60cNC7 z%9V`F713H%VI*^dp|V@vB-eviBC{-$(0Z)Gz{WG7+FR!(seEi8Gj+Btkf9F zEqzH>M)TjjbI(tU>eoE?g}p!9Ir5kLe~~%%#1C-Sw-4U4#=)oL(k+>I`nk{TJbdy* z=4XFLhHl=mYs=ShYx>)G&8fOjssxF9Q<4W@#N}hZ&@PuKRrzcHX53PlRHll6Y>G%C zs)#zG>0nz`9qNA7PSuSn-IcLJ1&>P}SAAFVUDX?sH&pLS-&d)0R77}qj|CXf;{5zH zlP7GBdLnuSR*+$*^eAAuC11=iKakO#s!)F*sF2GejHW}&bl}J{VH|dj7vKVfwR)XT z$LQ)j;z8^>uh-*9nl1TxAtn#!X|&pqS?8%D0b!IE4lx!*vfz@l9WZ8U$%v`FKo8&5 zo~Is6#~63Mn_evuM;iFw;NGA>+0pY}_eX5X3cH81gNTlz$j6;B%5IkA22e?K^+__b^;caQ=7f%F=c~3kLsHPkL09Q@6 zy!F+->SNVxBkutv<`*Xda*~65CI^2xCqF7@G4GL+9D)YkV+#ahxg26NhnO#REXD?b zR|1T1d9Z}{R0VyWPfAS5+w#azzj|a-iwd73)hd{96m$?`qW2 z)4~WXoh?UO##{m2e}){XBY<8$fsSy@QB6_wzvf>p&yLu^YdRKqwB>PQCTJ}WfiO3UiRdcX4CdBv0Zj4KhL=MLvlzm11 zkor5}AH?MIb#`)*V91WWFL>;00`$I%8AA5hu;B$l5GAu%X#lM*d^q9tVa}(u+3f*o zS%TG;1(Y!3H86%c>~)rjJ1tyknK92%TJ{aR6vpXxI`M#6AesG%hXQ};>`zIVYvTP{ zdL9e7D;b!e)RIG$h|BR=+O1TrLWJA45N=z{$7Omo483qP6lG=duqLPsBb}dX#Jo?> z$>QKsMYUn1=e3PU5u?199=WG$mhl9g{S8y9AwxYF2>}CUa{PCOEM$}@WaN$>QGYq) z&)vwA-VkoeT)5}X?=OE_^TW>+Z7jF86a|^v7SwRc>oUJP{H^I{D_SwI-@e89-!Zxi z&A^-k&%O9)=0{(CHuK8^7BhBsrXu06)E6?%&%9AxGw|q^1CQcj`~as|5UV2kAK5eh z1@M6&O5!Vo`sL0M=baW-5wr&vIOn?O272A=19BshA{i&;WRicv)JE4X*RH@#!53XW z2%bqPj#z){{G0s)#|KVnN})+JKYNUxtD_Ebw2mx~RFUI#ZkMQ@C4&KTFc{bqyd}s4 zQQYl!?G2m@TnMmSpfhkLz@7=@On!gN@xJUbqddFKfmuU#@*iY) znD9@{&rbYzzJKn})|OA2i3&n(X@=&HKqK*wjl%xuo=yY$3g^AlIyv98XSDeJQO z*f6u1IWqP2k{h<%{rT)HS-uJApd5DyBVMvIrS@W__bM+_SlLqES@|G(0ZGH|a=Z)e za_{ooi1vTG_j`_b9`gL&^LLMCsPb$j<1_k9J~J2M!cx6aZ_=AVWeh9JWwVb&6;yj7 zf$aGMUo|;AlHxsO0pK?`2~Ei3<}pHfZkO2&teZf_~AP$hriR!WPtw9@O#OBIkf1Boj*Tfm$u zI0M?DqoOj6mx21Y^WqU~y3+xIJTa0Wq8vzuYKr!m9gf=CthT7wUyzUjVJOJa65>eM zMYWH}_U;if^&;1!@IUAKIGDXnL&B`(v!w@n1`jcLqW+U(`@}uph-2ab4Nt3Lt}Chq1@z2T3hQjLoXhD=~lBmDJ+3WK4E~ZpRt&+{lGHT^P9rfiGMg z$cpA+dW2RyK|3Pe7q6d@$=P*fFvzgnFS+_T1cCP4d7eaKKUaJ8bNjjHFdeHf>d^GK zkT8`YJ*TfgBm9tmFTdCSS#(H$h(F|i3_a%8N_dGsE{UoGrnpnarKc~OFqMJz0L*_+ z$|NvzFk_B8gpaz%xpB7wb<^dS1lc=!oKu)xTfnM^mu`|ftV8S^QE%) z`BK^Yd^jQQ_Zh_NSkkiG1!i&okKW7*mYL}OUhaTS1^W}3B3YT)F?X3c-6otc%O8 z!WptUB%XJoHe^lg6F?1W2jTg9AB&cegEF}bu40d8PY1tGPClJS;w9GF^Oxq40Um$% z@nWme=tXw9CrValqu9&pyx63&d68Rci=ymaEbV)uBt!2P<>4yahTFK^8tIU1k7f@y z7F~^5ty?U`ybiku@ElZh!EQ--2$UHA*>NnSZ4Bt7`+V1eKJlii6;=oF$1U7XpBg! zOK^Hk$S3~}Ih`+qaqaTC>Rs$H7j_j#uCw5z?)rQH0a>I<(L25=U+VP~o3ek|oS5o- zg$`G#-5U!CUF~d>OZ5$`k$ZCVcpNQT4PL;-BZ=j3+%DtQeJaL z!ypZ>Db(!M9MT-s$jEhx9_l=!c~>LXIQUdyiYZ8a-~S}ufMsOLJ}jOvNVK1;<<1SC z8-{rrb-ls8pSbWXpbm1#pgVte9|}Z5{dsazE4QddDJZZKwN-875XW*7dCHu!rfl`*dTYI{!`xx*u&t7=GOqA$llH4Ns5cq6Shv_V zc>8@jxhsuVTR&wR_3q}ch#oAsGx3V-P4tHD_xXQC@2TEXzpwisKO$4f)H0oflNuym zp`f#%r$C7@V>B8}CZvDj)IOEn>+snn!1oe)zNq*zfkfd`+Dtsu%w+Z1B7E2v5z^B; zCk-sar>94S0Uyfe6Z!eAKHlu}@g}51G9QC3_j$qVm9R<{vzLn}j({o<(`qn++sH{+ zMxxC3nv5993~C<#f&YMK_(ar~;C){5oR|cw@}m*EO{J9OvkZSy7m$0r`DF$4hCyX1 zwRu0a1-rvpS|E_eDxgiwu>xEGbQ;~kgG@@E5PA$lpbb8SlZZ#koGel9QBEt_LZzVW zRI*A(vLMZ@nDl>Z`NiqoFuh{e?X*uh9odU^-6F%8IX;{_KwMSTJq)hw#XCjr;@z+exb!k!;?jRZO_!W)+D}gz(>rG5oeL^PywhjN4OKFo$l8AuRE8?6!dzv8Pn*bl-@HYE`m?D21W*s)`0`PXub4Ejwa9CFM zsVN818`n(#nSBl9N)f7M)(93E$5lyquBuq5Z7#i~>^Aw`Wh}kL+q0b9{y_4p zwNE6!n|#Ipa`Kh3H?aGDHw~;{T}-<`!ja=>-Im|KeV%UyP)Gr?F>w>)cSm1ek#8{Uy|P(Ytn~( zAjp1?kkU?yPbuqxbe~a5c(538jFO8zoKUy7juGm5>X^EREZE{AtynL?=`?UeRNB~r(nN<#ESH_S|?hA#{!zSYf{%!xUT2OLTzq&!e5;2ZdN#=9*{vj|?a`Y$H>Yu#O~`AAJKd4C zn)>A0Ic&oOaBPWB&6q?~&Hoc1j-An3*DTo~A zm2RYV{e|0Is2B8|dRE`9`#mOyrRZ^M9v{UF5$mThi#tipCTlxNX$@V$XsK7w>PtEL z`pj9cg!AHYXb0o*rZG!7D!HUZ80Q7DzBT2z(0##v9?fWKIR=_YfOCKL^oV~n$0uqV30ZPDE~)>i2soJ zP8DxU;y=?rUHcH zMKkjyFkwRhl)__z!`JkZBlakeO0Jgvs2CT!mC;=U>@(g8-k&eKxtlC^H&l z;fPNylk2z`jtMTOu}GX}7iIOOB038*SxP&L&J;0)MM6<$(NK}3D0{X&t~Cl8T&NK= zotjfHp^|DGg_pcTq7ju5O;#DveB>RHtU^UWi$u_(ENIc}cSy2VSI>WoZwZn0?n|^R zK9UcUif|(0iA2Ns_E;20ykNwg$tccqhi9~_ME2E@nvhUGw=_tMJ@!4`J&`^6k}>lh z$B^e!!J+7$#0}<82k$T+wjc2x3EUle!2EFFk>z)4;$f@G*Z|Ve8Z%=$%h|Q&CCVij5Diy6kJ4+nb6jR;()zmR3cCzJ|4# z`{tF}!(qm6>tTOIUO2jH9-q4IzxUnxhpPh4`>w27_Q(I}s`(t9iD!=Br*R2+1za%v zjlpuI1b-X7Xl&D{BnvEQ+$yMXi4W$-4R&&I5cuweDRRK-!g+rTOq47NnaXmnrpPZj z|I|M=Acx_q@g!yV1XV<^*kp2>xDZi?tb%pOI&PI%pJd)73O4W} zW9iuxE=bY$5`aM@-Y4q;^mVcG!&nHXk&ZWoinnHdX>BN9I3=G;_hvHRTDz!$IpC>Db-s7uGH2j_GU>vw z(i?v&W67ikN@jLrIHu*Rb8t8uFoiywsmDj|C~_GcQo1%*IDJ-nAM|tqW`!@?^^O2z zS49Ky;8nrT=xz-j3;r-T9aI7wgIEso;n*QO#O$%|v7OYtkoQX7n|V5E(4yl4ygw2w z@~;lazwLi7$ULAsp<_xEa&j?$HQ=KM7UFz?2L(dnww&E&!;q(Db4bY<^7uVIyw*4E zV|-T^77B%(g+ql$3#EmMY$wHHopBt$I+fc}6Hlqpb-Q74-EP+FQXdXP;ro zJpy+3@OJI7rhX9>EY59l#y!OW7IKP=gYV~Os6&l1^6MP^169TJcO z03pd9kCtRrdujtHu_wfPJCNo)l{bPnKr#)GOamm-0Le5!1a^Sz0%v712>t|&KQwbE zM7*9e(mjm*tRLn-ga=B3xz{1+la=&5Xvhz2ypp-9Z|e6Yxa-Lyw`MYTJi{zjEZPj7EpoXY{>Gwg{@ae19rPls*G5kX1BQu6|k+3ST4tovGb%@u4E2xgF!!DC=9rA0zK)Hph?9O5WcXwlp zj**w=uKW?9LeFzxa>zqOB1gmx`|ZbnwI`VGX=uFj2iw0tdi76t{R-cf`JSSzz@IFb z*OX|>lWuZ<7ku{g5wFtxU(eil_R5>F;_h?!=C`J{9}o^?GNs`y_hIuuGm$~lzm}6b z??sGEm^`TbYm8~L4>%sSr|mB|-g3MZlULcXJl}@Gs2p_^uPyE@*@6`MVy=XoqZ%sN zTXLx6Xvuhq^4s`y@o&+e(R8tNR5|Jx%ez5&z2hi8deAbCo&~MQ5d-#+Dyc$kd~4AN z8o^4$0hR4VSm|)cl`sY!cBfOJMlR^#|CWHP61RtKMvsBd^Luy%d{LKipaBZILfw%ct=l~SR~vpc};kjdqFu{Z$5Z5p*o!sR&~ zdOWp>W^-53z(QVDDfALz-Y|ne$ zbb*3wq`-_X`oXHbn~rTUl?n;c$kNOY z1eMaMIV8vO_to#6#GfU9`^j%~lhIACp%7hKWU&n4h793`4B>{%42wNy6dB)s$_R7Q zK`HjrSAbr1Q)G8U9>x{66~((G*E9PZcWLhqJ)(UilvbQDYqGC@2iugaMISE;xHMrq z(v+4EOX4daJZ-`#EdcAdOe>x|%du#eP?kXTs8qu))pUl}YeqHKBWYNp)fU@BA*9jU z!$kpPacKlS$1D%qHK2_ei*YDK4z^pg#byA+AvRE~Ez)a4Fs+o$Dr`cgb!Be>xza2W zJeIe16mA14*BM*31`nrP?+ynSsZ5-1pn> z9^7_c^HpEic+=@8_V(PSDE`#^>srcs=e2ziluldl#nBX*$Y&nSh`dy6+0tJqd%;T7{cVONsp5Sot4)G*C8+G zScfA@a0N8Jb=YYHBczJXl1%ZLGY_`1I;KK4YnjGqF*B0v+X&)94n445|G@9|yXsaJ z-u1)59}VvM=`}yhY{oHF+@5me6}zL2iMFWQ9r^r!FK^`?uYK#r*RQ%Mlez!rnJdmS zHw`U6@x_%fYog|X%pX87W%s%sr}#_Y`GP~~lKEs|Wy~hGyDYpVY>z4B3cO3<5eYF0 z)}%~pv=MBDkr0ZMA|X)#MoBpspo0Zd=Q=>kCNXg}YSy^{vO^e!5}QyY>H`*BFsW6P$>-b#RO zS%>4i-{)s!dL5@@WT9X<$jHrg}vhTCLYhx4Rh_;ntbU}&K8>{f6kFt{#%?u=#su0_Lm7@OrfCi|EG**OtsXi_fM zkM!n&xZ%YMFWBkXleyDs5$$PI8h%E|toxvWQHg*TOtG->2mQT)xbBO!thAabaW%`E=q7!%^}e zQ$QK=Y3U2Ye)7Wb`e0tjmmdsb7bHdYeu+Hb_v>_8m4dz}Y&Ma{l}zNFCX+Cy%p^3y zS5*z3!XhxDd0-@xU<5*7czs}ycbZIpSZ~6->9mRAOxQ#gbB(78u&-defJqe$ktYr7 z#BC4Asv!GXQ$hB5rh@GAOa;mBXMleDbB(SuY8Iibu4dA zCQ|G$8WXO(h533@O(sHbyGj>M{dRHFhW$q~w{4+M3HzOW_{(E8{)(22dV?dNp!Zt0 zuqU$jS`m^XaTSoOA`64}QPox2P20 z5&%;V>55qoib1?fR)q=xhUBvd!WNS>vPaNDNK*`XtOmOTzBTae2iQ)3fK7ng3N}f< z81gNE@C1BI!5@)-hK75foDP7S4`nri-;mA21mRK0mxLMND}=BX_!a_oj9K?Q`07bo z(k5s|IrihjOh3y=TBS+pw0xO-nZm8OU)ipFTeVHSRlQ&Rq2@X5k8~Zn4EH6&m*we!Z$~*j$RXeChxJ> zmGRXHoWCOfspQuS7Nx2Rw^FRvpk=_T$sc)XA%#|efV`V|4oS(QiD)VNdxXSz#z~=A z+FM@gV`(Y{Q<-(MXbB@^-4c|?d@k#j!qolAtXqcinV)3ca8q+OVw+vZLhqG=u zsxf^n>sBDU>CLQLiJHtgy41=Ua}(r@B`lPsbG2mM5>((?O5FroD%Z7Hw*(^N~;L7zDbt@oT<2Gd75|r=uP`45q>2lW!->(-=DH>tY1z?aG3fIb(=|jQh&(0p+2dmfzHl(> z2Kd6OsoO!}AI-W6yjT{|kX40$&bpyb3#X{tL+Vo$&AOpJMM>%=_ajtAOS5i(FY2c5 z5b4vR{aH7E^l8y;)Ey`IDS9UB2K*F>I84%f-pRUwNfgm`DJcGD+))2w+NTQIuHv$+ zn}kzZ)lm52;jEj4@1btmFU4QWx}n_S$I-)}SQn#0RD>$PwG3@SePFkvL9`vdF|->E z(U2zajewh&y%0V?AqpU-0d0jJkCs5#Mo2$~MyaoV59~hrKQi{A4HQxfzj@$W2cdmv z7ld@s+_yuyxpEdl?zpz9>(Q1h?0oQTf>08>gZ@uR} zn7Fimjbc87*_QIOlpPSep0=0x`XTRKkamQI>;R|@6mvX;=lY`!>O`;@+krC4i0X&m zK$g15S)Zk}SGPl(`yiEA>IiKa$(4+g6%>9fO9u;S`!-O@Av9lvs$g^#e@tHy>e~T- z^%$bGCQ@BL&2@~9qAp75JjK{!YW*aEnP<9mN)4teF z%Ne3=5Yw*D=8~&%FU@<1(g*oJH^*okNwtpFBR8r(Izq;>Da7$Q@(&^XGi}J9@n0OF z|A?I->fZoq2zK+cqm^((vE2Nbaz5IBf&of>yC|O4Q~vdFINOzN=>X+yTPY9A@!F5# zevneYZaV4)V3f_~wOw~S)&Kr?j+q@o=Anc#&K?TM-lL_+I%dWxGZ`NtyR33bLqcf? zStSmNWMyQ_NPR_RWv}D+IehDuzV~+@zu)6=&p(dWc|V`8@qWF>;c?DWP(1C0dE~mh zhto`ki2LQ1M66bT#~Qm2V9Dm0wN5NQ?bu4^65XAGIBDhaKF&m}_(oeZ%*JK^Uw!54 zg;|p0b5@6rO0J7GrrJHyz$G%MpYT6;`h}MxP#C?$tt06}-Ek?#(<`9ZNnzx+umt@H zxpN ze3xYJIJl*^WyH^)Rt(?H?#>WpX}R~t=ic}?56yjNtv>N*padH_M%L}IQzSj>fwjZ~ z{3F2kA!Ss1+0K{M!S$ww; zGX^2T(ye-ZLrX5mkW>Zcwdwcr>$~2|N3O)*8_;u-q!)MbdtxQly3Emgg(t}`#R5y=IC1=GaJ7)*3eU?@$J=-;#%!7nI5IX zk?(8I+uEKBb3H9g?5Vm(hZ5=tN}&C5A1J9gO6V|1?zOh4TT z>ugREC9a2x$KC|!-PMeSk6OR136Q8&t3Rt^)v*0@FhSO9yDCA~ce{3he|^>iE!kY| zmD8t+`^6Q#0@iioFEsko&2~YPB-iQ!T$tGeNJtr}rt+^zj&y z1^DcA@|;UfuXFVC)S@ubwoj^x!hLl9C9SJEYr0E0?d8t*Zs+u*VogL6Z|dGQG|9Nw zu6>9c*1zqHzRMCvVUwM^Kr6PeZGHT9Vb;aYkSmr6?vGfsrwSy6)t95%NfIaVkB)Ni zG0!-=D-7pu`(~6)r~?$L6*744(wkx5r6>Sd-L7@RafQATbEn*{b{{q@#4tQ!U~U@n zh$Kz0Po$U}e%z3B;`ynV7gy0#$t&HIh{rt|h%U7tI}+M-5ZQZtH&(Tetna*E<>VJV zy=Zy9hZl;^jj>-WH2bo{H7&y^Kko7g%=U&|LHl1Q5FU=K*9dO+s;g0Ko}X16zGzc^ z0T>Q%cO5gRTbKJB8o4z5@-Ay|&pj1N(3zE??um32ipv>$=QEjpZZ>BEAcJ{6`zq{h zKHkeW4b~lW9(?nb!ogT}Y=17PUuRH(Ld+(uAd?(zCnu^ziL0Gem*~GP&4sDI(AE*U zZEtPW~RdpCatBMf|)UK@Y4d! zo$jLMgDB9_xzXtSkoxP2A=OF&IlpQ&WdgCqjH zFO`VA@+H1{dUsN@tGKx;Qs)cz$}{laaJw=x<6=Tz9uneeMHhRyBso&PWjwg!Q@+}* zGZ{f~FW+UcSVaW}Q0sDbd*bHxXLKf?To@N#x=amrK9Kf_e0k1eu(w1w=`uTA@66H; z`meQg%xnSLU})kWV;}0pIGwDCpAZxRdX?z1zly(CIacY%F)>sE{#)9Qj;B_~FVQC0 zEx}r~t!sZLxtSy=C>pBJ_&K12G!&`D1oKr6Nr(&3UP`AVy3-Sh3H_!0g^xT%kxbiL za(5B5Rb?g8x(n5v9-`35XSTJ=`GL2&B{Q3(T|61t-9G!d3z=8A9BcAbOQ-Jxx=8)` z7fjrr%!l=rOpMGh*-6?qLL)_}N8L4*B)dh%ghhoRWsp)u{)0))pN^^{5^!``adYmw zf>21hEDyo=ML}O}CL{FoyY}5>9TiALv1nd+PIO~=T@|6yW&kaCK>FH}C3rFad5|Cf zO>Y)^mc<@)o(J6*%R3!B&@u7%K&ejx&q4l5{c>^4~`7Z zhn}LhV2W7Avd{9fUv@LtZp{koa@0P`UP?}?k$E6kH}bKkvX)~o&0d0^CyLCHisL$T zgXQ$H@4WlPbi>vl*$h~AS@==sqFb3>T4ST3zVxiiu#VS>R+WtrffRrt0#G(-UN$V> zC7j;GP#dyu)Kup!*ORahlv}VY^3#VRx7Jp2U^~8uii%pQw&;%%Ukxpb_TAAwuX!1n zw*#K6?OB#twAv<@dtO${wJ@CvDZ;(-f%swZ6g}~V&Xk;ILvxbwgCK?TU+G#Nm}Bc) zH9mEkKt(k&FD|VXS8>pY|N zTvm$BiqCn7A4=Cb+hUI}+?VhAZm1Y&)k3oS#<@k-&$hB-*`dbweR|%P1j}jL2#kRu z?yu-X&vi&fFFX-`--FZtM7OX@J)$#`{b_pam845T{q1ZyC%gRW-i+S@I$E}yt;)db z^C6>>f@Q-8*N?NnKDt}6RTO6U^wdX4$p`kCQM`0(V~R&o994Sr_*Pp3gB|*w`inM@ zr|I%DZCjrzP%^HP%-d@eoh{mLHkUm9V%hf8TXrx%oa8!b+1&}Xb&pNuS0H&pcdmgYJ7` zl4ezfW7aF4r_0O_0N5St1rHX}3~Sci_6A?MvF=2iZo5btu_DHDF8?w{+qANm zzOsP|;*yiEWt!Lh^eNZu7=41wl(wH1`|H8}vC<*w`_K7GlRZ1P*Jo*3t=1{eo^^3t z=#?&6;Bk&NHj{pkh}Nx_0U4vv~e7vzfI$7uxB465|co-~L3nztJKT5MO~|5Dk+hP&v-keG8anx`^yDUayN6ncX9{eVr-ofw zE~G^ohmcq(#Hn(&H1^W~>7eW)XBCbkEqs~fz1Sk>OFuqJ0Yl2jJ(*VAv)v-qX9~wf zY+}ODB8BCV14hF4?^)fYdn{wZ9Jr8R;lb0v(EDZow(EJx@`d-l+20N6<@L|E6GD9O z7EqP9y}k?n>bn}@>vsSn22T~9~*o;D-xDtFj&7^GG-g1UC4Nm|1=^^ut2}w5-K!=by)2h*@pyOt9joQ;m7aa3h;FX@ zE|>u0N=>+t+-Ct^|LI|-9V@UESyp5{XNFl`$y19xF+r<`zXgSh^{5){?Z^xUZVt)S z7#EQ8EfRL#c?-GHbRS6Vzic*@n35@dwRc#ZLkP>!WI%s1&_o-En@GP`NwtR}L%)kT zE=caHzU7#!$)6`~n|mW~(MY+5dNH)z*z>~o3C0+S&dg)S10Sl@4d}~+uZdSKuD7%) z7-;Q{HB}E^L+=fbhh$RuEi0tD7R%9y~7WjrZ)kiVOdZG_{?(d1)!#XdEto)kh zXssnWg)mt<{w7K!FsA$}_OF)AeodZL??VqD?Wd&X8F!Z@%~rkpW;L%A6YVO?^txi3 z)g55|eCoOLW<;3*`tl0)vM?L5@JaT-$x3NRo&HOMDMQ{8 z!%@9J2?vBZlVC!na-poYBEA|B|QfIeTZfR<`-wuq(A@5 zSxAL{xmcu}O*~Jin5E;DA2-EmXg^!pl?br64xW>^(n3EXu_*Wk!5GYG0HKI2&eK-K zVcLojx#gH_!uj0u1j~rk;_D9qx1DlZu&?dUz#QM1E!8a5EdWd}ra-9Mu|QJGZq4fY~Z`HfznTTBk~$%NVL z$o7B^H}D&G{T`k$YI<~C{Y%D|vvaa@JBz$6ef4~`e2>jPG3b^3n#fT%U(Z>0x!zvI zU(ZTWz&^=OIQ5z}#4J9Pz$qR!AL<`fiWl-?ZA7&LQOg09B6ou!jYeNsLr>^fPBBUV zxz^D4R&cH=?V%`D7DtKcR{{(ZR5li2=nQut`wUx^s0{lyi3ql738srvFC+r@cw?*M zB8@IyJIvA1xUVoJ_n^FWdQl*w8RbwzFynVdfk3tF@dmyLhme5lFU#4_RL`BYRkq}Rnb}%-+Az)TvH_a6dl#>l#-q|t za}j$J?q=@QZb2*xwnIjg+pj_kZkJv*6dd)F$^QE*S%dI#8xg1HDrlNuzKyyP_s2a85^++2DyynM<3vPtlOFjI~Epg3t2z8ip5kIH3eiZ z`JaB0dC$s(xd>o8UBL?qi?(C4uPwHyhS!MIv_% zle-4V4Z6@3e7(zey7#nL<@9=pLC3J7$qXFRa9gHhS+D4}*?2Ph5R)}FUAz9iAd_`O z;p5YiR-g3?^iCtF(erTgiRgKzJWJkj{Yp=x!uSw}ROgDOt~>U#i+BU`z&K7o{5ZD- zYI_C$-Hy9i*P^UBQ@kau{?h;0sBwU$lbLr-ERU+vI?4ETEt+bUH?XS{HQfAjt1R8erH4%jt1TJ_xE?c0 z4@=~Uap&Y3R0r7v`QJ?|yEvB>4N&_kmxndh33(H#Z~FAU?+^X%tm1c6;o$Qbg6hK25#zid3S$QJn@dl`}pC)d*!@qXTOU-v=?r>^xb(@ z=!h2hL8w+ElQuo1OUrPIn|kV5-s=k=v;uFANE%eLK^}WZia}g2M?LS2rZNELS9$$I zh?a=N1*u9)|KbqAu{6>U_mMDrzME01tOqI4R6+BBXexi6uE)F-)#BWlwRB~U0;|DE zTS3+HFBg`%@^V8Q) z4WBN-yzYJnKQ^&Y-^7{`dU%vi=%QY_$s0Z%#*Blk)z|6($t$pC?`sYs`Sv_^df7LK z+(BbkDZ^DZjP&)L&!SIN$^quRc&kM7gcM`Now){bg2%nBiof7rm-v2Q{CK}JgYoO) z^a7dboq5r@xo7C^sMp6`hDI>{^{B}M$O3^rkg+)rjnX(7Z*(y)V2tFhh(+QrI<_|%*nutQerZ5GS zQ)gK`RIH9mLw$xmGO#ciGBci(hhmzT>_}CHeA&_E7okDAa&XSM5GbP^-C~t;0cY#?qV@5Jdy@t zmAk2`i(Ord6*}S4pTE7QJj_z;ZsTDB4+{kjaQZ?(>M<_v0l z8=y?zs-lcck5@TT7jGUF=Pi%XXx@eu*M4*|B}a*(H|l!(+O9^IZSw%u&rqSX*mE)I zsmE>EN8fwn>%N^#Iw2+N+B#LM!IeC!nfch(tP?KlnwS@rQe>mM%c|x1muFB+()xIG zZ*ts8#*D1mza~!?daC<)kG3z4cRjm(1-8msRH0I;7YW53pzS7>2TVgI&e>wA|jgcT}9MwkjAw6@a& zc6h_okT@Px9j}0BhTSL5R1J2~a-CP)YEQ-c5*KS#5qwDI_tHG;pcZcShYf`_K@9S5 z?K31Ei-rHxsa6#eaVGX)t`D z_S@CO{Cj%1IV!f~7T5T>>7G&?O+J`6Yh*Ab|}^L;_*Q1Fzawb$UxpP#$YM^oE#u;N2KUr!zymXttw#Tm9{|R z`wL@}L-)oe6CR9BT2;;Zy=kozFG8=m+AiQ8v^?X zvwi{aHBnFYwSK0XtNDt_s~?C-s&DIeukW}<p$t76B!iW)Kb zwH*6$uumh8m*p#+H8R01U5 z`34cDsSN6q_m4x^04)TlKS>K*Q40yfz&D?vVA#K(p<(FFS9Kg2Krq|XJUmF=UKXqva_u9ixZ){RMQu-#&l!;Tu;LLXpy1$60mmv3$j0SR0rD~h zivF7vf+e>$&}h&!PVFCb5CWOI5-Pie5QS90Z4x3uLNp$$fT9sfkYg*Mgr8BOH=-m5 z(l$6S(cQnsdGw!X!A!vg`6Es=603mQjC1EpDE22UW`h=t_e=#8{VV4Y2;v`DQ3M27 z$A7Vc*&{YtGhh8=1=*%5p?u`mf5$38&TWDU{wM-@bQzR#rA-Zau^Orf1sip54OI1K zM7YgF4{&WJ`a2kcA|qZw_mU%DZz7++{soEOM2>R)6B3F-ZRA7df3peIdGiaDumOeQ z;I#RI{}wM4h28{a)olX1>iz`;0kq~JU;8&cF`H0y!zR?R;TI@k6WYV^BV55oDF4qY zu~2_hsj6`kJkto({ZS>{-%X3#Xxgm-<2JpXe7gyZd;8NXh~H>T+(u*mjst5;Yj^Tk z^CnEV!^10Sc=)+d%!JnaSwipz=8_Ksq#TYlYS*JGWVF?3U z4<{K15BZ~qWmy%~h@K=ZlBYX(lxev*xY_?WqonQ~w2*!`3Os_>rK^2sF57{tAX8uwXpD+Ym@Bg0KZk8%MkL{Dwus z(X=Dtrw#NE2f--Zmh9l*K-#tM=Rn#MBpOcmBV#NE4IVaI#vu?}tBS-Uu;8x$>p0La z4nS-%g4IXhw`2!LAwk?9VEjLgqn$9nI)S6m|KJ!0r(GJs2k@_X2M7L1h(W=(lof#_ zU=V*)fq*A$aSXN{61$}epbd-ut*T)C5hw&$?cbvYZ79NT12@Lu@PCX$B50TBUo!?< z9`oBAgD-*&gMx3ZGzx=40bA!CO&j|=Asn>P)V6pUVz3(rzZd5#o_}+BM~O8w!oxQffFJMfhWR(zG_0C!samgWLG z9rU~vi$HFjVgT%PEb`BR1j5!}P$2e?V34@2I~)Q9M)S+c@%FTJadYsby-_{va^3-k z!z-GRNZ?%)Ts7c3IzUm^!;u67wdQHRDe7v#EMN!J)U^;ubtIgirGda>;A$8R4A>%g zbrfEWpr(!okDLEIgm$CWAQ9D_9f+=8KJG9@v>FDdaY#cGjlihm2?z}oTAiS&Aq7__ j;1C$38lJ$qp-XS;>3z=A!I2g0KsW}+DkY_9ti}32OA*zP diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/LICENSE.txt b/modules/juce_audio_processors/format_types/VST3_SDK/base/LICENSE.txt index f9c531e7455a..ec797c8bd323 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/LICENSE.txt +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/LICENSE.txt @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/baseiids.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/baseiids.cpp index 7d12c713a443..0169c2ec20f0 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/baseiids.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/baseiids.cpp @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/classfactoryhelpers.h b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/classfactoryhelpers.h index 5a531e93d3b4..e4231358b359 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/classfactoryhelpers.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/classfactoryhelpers.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fbuffer.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fbuffer.cpp index 83866ea9bb79..45dd41940a41 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fbuffer.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fbuffer.cpp @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fbuffer.h b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fbuffer.h index 0a8c1ff6b5b8..e1efd2c5c255 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fbuffer.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fbuffer.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fcommandline.h b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fcommandline.h index 653fb7c62949..dfbe364bda98 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fcommandline.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fcommandline.h @@ -9,36 +9,36 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, +// +// * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation +// this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of the Steinberg Media Technologies nor the names of its -// contributors may be used to endorse or promote products derived from this +// contributors may be used to endorse or promote products derived from this // software without specific prior written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // OF THE POSSIBILITY OF SUCH DAMAGE. //----------------------------------------------------------------------------- //------------------------------------------------------------------------ /** @file base/source/fcommandline.h - Very simple command-line parser. - @see Steinberg::CommandLine */ + Very simple command-line parser. + @see Steinberg::CommandLine */ //------------------------------------------------------------------------ #pragma once @@ -57,310 +57,336 @@ namespace Steinberg { Parses the command-line into a CommandLine::VariablesMap.\n The command-line parser uses CommandLine::Descriptions to define the available options. -@b Example: +@b Example: \code #include "base/source/fcommandline.h" #include int main (int argc, char* argv[]) { - using namespace std; + using namespace std; - CommandLine::Descriptions desc; - CommandLine::VariablesMap valueMap; + CommandLine::Descriptions desc; + CommandLine::VariablesMap valueMap; - desc.addOptions ("myTool") - ("help", "produce help message") - ("opt1", string(), "option 1") - ("opt2", string(), "option 2") - ; - CommandLine::parse (argc, argv, desc, valueMap); + desc.addOptions ("myTool") + ("help", "produce help message") + ("opt1", string(), "option 1") + ("opt2", string(), "option 2") + ; + CommandLine::parse (argc, argv, desc, valueMap); - if (valueMap.hasError () || valueMap.count ("help")) - { - cout << desc << "\n"; - return 1; - } - if (valueMap.count ("opt1")) - { - cout << "Value of option 1 " << valueMap["opt1"] << "\n"; - } - if (valueMap.count ("opt2")) - { - cout << "Value of option 2 " << valueMap["opt2"] << "\n"; - } - return 0; + if (valueMap.hasError () || valueMap.count ("help")) + { + cout << desc << "\n"; + return 1; + } + if (valueMap.count ("opt1")) + { + cout << "Value of option 1 " << valueMap["opt1"] << "\n"; + } + if (valueMap.count ("opt2")) + { + cout << "Value of option 2 " << valueMap["opt2"] << "\n"; + } + return 0; } \endcode @note This is a "header only" implementation.\n -If you need the declarations in more than one cpp file, you have to define +If you need the declarations in more than one cpp file, you have to define @c SMTG_NO_IMPLEMENTATION in all but one file. */ //------------------------------------------------------------------------ namespace CommandLine { + +//------------------------------------------------------------------------ +/** Command-line parsing result. + This is the result of the parser.\n + - Use hasError() to check for errors.\n + - To test if a option was specified on the command-line use: count()\n + - To retrieve the value of an options, use operator [](const VariablesMapContainer::key_type + k)\n +*/ +//------------------------------------------------------------------------ +class VariablesMap +{ + bool mParaError; + using VariablesMapContainer = std::map; + VariablesMapContainer mVariablesMapContainer; + +public: + VariablesMap () : mParaError (false) {} ///< Constructor. Creates a empty VariablesMap. + bool hasError () const { return mParaError; } ///< Returns @c true when an error has occurred. + void setError () { mParaError = true; } ///< Sets the error state to @c true. - //------------------------------------------------------------------------ - /** Command-line parsing result. - - This is the result of the parser.\n - - Use hasError() to check for errors.\n - - To test if a option was specified on the command-line use: count()\n - - To retrieve the value of an options, use operator [](const VariablesMapContainer::key_type k)\n - */ - //------------------------------------------------------------------------ - class VariablesMap - { - bool mParaError; - using VariablesMapContainer = std::map; - VariablesMapContainer mVariablesMapContainer; - public: - VariablesMap () : mParaError (false) {} ///< Constructor. Creates a empty VariablesMap. - bool hasError () const { return mParaError; } ///< Returns @c true when an error has occurred. - void setError () { mParaError = true; } ///< Sets the error state to @c true. - std::string& operator [](const VariablesMapContainer::key_type k); ///< Retrieve the value of option @c k. - const std::string& operator [](const VariablesMapContainer::key_type k) const; ///< Retrieve the value of option @c k. - VariablesMapContainer::size_type count (const VariablesMapContainer::key_type k) const; ///< Returns @c != @c 0 if command-line contains option @c k. - }; - - //! type of the list of elements on the command line that are not handled by options parsing - using FilesVector = std::vector; - - //------------------------------------------------------------------------ - /** The description of one single command-line option. - - Normally you rarely use a Description directly.\n - In most cases you will use the Descriptions::addOptions (const std::string&) method to create and add descriptions. - */ - //------------------------------------------------------------------------ - class Description : public std::string - { - public: - Description (const std::string& name, const std::string& help, const std::string& valueType ); ///< Construct a Description - std::string mHelp; ///< The help string for this option. - std::string mType; ///< The type of this option (kBool, kString). - static const std::string kBool; - static const std::string kString; - }; - //------------------------------------------------------------------------ - /** List of command-line option descriptions. + /** Retrieve the value of option @c k.*/ + std::string& operator[] (const VariablesMapContainer::key_type k); - Use addOptions(const std::string&) to add Descriptions. - */ - //------------------------------------------------------------------------ - class Descriptions - { - using DescriptionsList = std::deque; - DescriptionsList mDescriptions; - std::string mCaption; - public: - /** Sets the command-line tool caption and starts adding Descriptions. */ - Descriptions& addOptions (const std::string& caption = "", - std::initializer_list&& options = {}); - /** Parse the command-line. */ - bool parse (int ac, char* av[], VariablesMap& result, FilesVector* files = nullptr) const; - /** Print a brief description for the command-line tool into the stream @c os. */ - void print (std::ostream& os) const; - /** Add a new switch. Only */ - Descriptions& operator() (const std::string& name, const std::string& help); - /** Add a new option of type @c inType. Currently only std::string is supported. */ - template - Descriptions& operator () (const std::string& name, const Type& inType, std::string help); - }; + /** Retrieve the value of option @c k. */ + const std::string& operator[] (const VariablesMapContainer::key_type k) const; + + /** Returns @c != @c 0 if command-line contains option @c k. */ + VariablesMapContainer::size_type count (const VariablesMapContainer::key_type k) const; +}; + +//! type of the list of elements on the command line that are not handled by options parsing +using FilesVector = std::vector; + +//------------------------------------------------------------------------ +/** The description of one single command-line option. + Normally you rarely use a Description directly.\n + In most cases you will use the Descriptions::addOptions (const std::string&) method to create + and add descriptions. +*/ +//------------------------------------------------------------------------ +class Description : public std::string +{ +public: + /** Construct a Description */ + Description (const std::string& name, const std::string& help, + const std::string& valueType); + std::string mHelp; ///< The help string for this option. + std::string mType; ///< The type of this option (kBool, kString). + static const std::string kBool; + static const std::string kString; +}; +//------------------------------------------------------------------------ +/** List of command-line option descriptions. + + Use addOptions (const std::string&) to add Descriptions. +*/ +//------------------------------------------------------------------------ +class Descriptions +{ + using DescriptionsList = std::deque; + DescriptionsList mDescriptions; + std::string mCaption; + +public: + /** Sets the command-line tool caption and starts adding Descriptions. */ + Descriptions& addOptions (const std::string& caption = "", + std::initializer_list&& options = {}); + + /** Parse the command-line. */ + bool parse (int ac, char* av[], VariablesMap& result, FilesVector* files = nullptr) const; + + /** Print a brief description for the command-line tool into the stream @c os. */ + void print (std::ostream& os) const; + + /** Add a new switch. Only */ + Descriptions& operator () (const std::string& name, const std::string& help); + /** Add a new option of type @c inType. Currently only std::string is supported. */ + template + Descriptions& operator () (const std::string& name, const Type& inType, std::string help); +}; + //------------------------------------------------------------------------ // If you need the declarations in more than one cpp file you have to define // SMTG_NO_IMPLEMENTATION in all but one file. //------------------------------------------------------------------------ #ifndef SMTG_NO_IMPLEMENTATION - //------------------------------------------------------------------------ - /*! If command-line contains option @c k more than once, only the last value will survive. */ - //------------------------------------------------------------------------ - std::string& VariablesMap::operator [](const VariablesMapContainer::key_type k) - { - return mVariablesMapContainer[k]; - } +//------------------------------------------------------------------------ +/*! If command-line contains option @c k more than once, only the last value will survive. */ +//------------------------------------------------------------------------ +std::string& VariablesMap::operator[] (const VariablesMapContainer::key_type k) +{ + return mVariablesMapContainer[k]; +} - //------------------------------------------------------------------------ - /*! If command-line contains option @c k more than once, only the last value will survive. */ - //------------------------------------------------------------------------ - const std::string& VariablesMap::operator [](const VariablesMapContainer::key_type k) const - { - return (*const_cast(this))[k]; - } - - //------------------------------------------------------------------------ - VariablesMap::VariablesMapContainer::size_type VariablesMap::count (const VariablesMapContainer::key_type k) const - { - return mVariablesMapContainer.count (k); - } +//------------------------------------------------------------------------ +/*! If command-line contains option @c k more than once, only the last value will survive. */ +//------------------------------------------------------------------------ +const std::string& VariablesMap::operator[] (const VariablesMapContainer::key_type k) const +{ + return (*const_cast (this))[k]; +} - //------------------------------------------------------------------------ - /** Add a new option with a string as parameter. */ - //------------------------------------------------------------------------ - template <> Descriptions& Descriptions::operator() (const std::string& name, const std::string& inType, std::string help) - { - mDescriptions.emplace_back (name, help, inType); - return *this; - } - bool parse (int ac, char* av[], const Descriptions& desc, VariablesMap& result, FilesVector* files = nullptr); ///< Parse the command-line. - std::ostream& operator<< (std::ostream& os, const Descriptions& desc); ///< Make Descriptions stream able. - - const std::string Description::kBool = "bool"; - const std::string Description::kString = "string"; - - //------------------------------------------------------------------------ - /*! In most cases you will use the Descriptions::addOptions (const std::string&) method to create and add descriptions. - - @param[in] name of the option. - @param[in] help a help description for this option. - @param[out] valueType Description::kBool or Description::kString. - */ - Description::Description (const std::string& name, const std::string& help, const std::string& valueType) - : std::string (name) - , mHelp (help) - , mType (valueType) - { - } +//------------------------------------------------------------------------ +VariablesMap::VariablesMapContainer::size_type VariablesMap::count ( + const VariablesMapContainer::key_type k) const +{ + return mVariablesMapContainer.count (k); +} //------------------------------------------------------------------------ - /*! Returning a reference to *this, enables chaining of calls to operator()(const std::string&, - const std::string&). - @param[in] name of the added option. - @param[in] help a help description for this option. - @return a reference to *this. - */ - Descriptions& Descriptions::operator () (const std::string& name, const std::string& help) - { - mDescriptions.emplace_back (name, help, Description::kBool); - return *this; - } +/** Add a new option with a string as parameter. */ +//------------------------------------------------------------------------ +template <> +Descriptions& Descriptions::operator () (const std::string& name, const std::string& inType, + std::string help) +{ + mDescriptions.emplace_back (name, help, inType); + return *this; +} + +/** Parse the command - line. */ +bool parse (int ac, char* av[], const Descriptions& desc, VariablesMap& result, + FilesVector* files = nullptr); + +/** Make Descriptions stream able. */ +std::ostream& operator<< (std::ostream& os, const Descriptions& desc); + +const std::string Description::kBool = "bool"; +const std::string Description::kString = "string"; //------------------------------------------------------------------------ - /*! Usage example: - @code - CommandLine::Descriptions desc; - desc.addOptions ("myTool") // Set caption to "myTool" - ("help", "produce help message") // add switch -help - ("opt1", string(), "option 1") // add string option -opt1 - ("opt2", string(), "option 2") // add string option -opt2 - ; - @endcode - @note - The operator() is used for every additional option. - - Or with initializer list : - @code - CommandLine::Descriptions desc; - desc.addOptions ("myTool", // Set caption to "myTool" - {{"help", "produce help message", Description::kBool}, // add switch -help - {"opt1", "option 1", Description::kString}, // add string option -opt1 - {"opt2", "option 2", Description::kString}} // add string option -opt2 - ); - @endcode - @param[in] caption the caption of the command-line tool. - @param[in] options initializer list with options - @return a reverense to *this. - */ - Descriptions& Descriptions::addOptions (const std::string& caption, - std::initializer_list&& options) - { - mCaption = caption; - std::move (options.begin (), options.end (), std::back_inserter (mDescriptions)); - return *this; - } +/*! In most cases you will use the Descriptions::addOptions (const std::string&) method to create + and add descriptions. + + @param[in] name of the option. + @param[in] help a help description for this option. + @param[out] valueType Description::kBool or Description::kString. +*/ +Description::Description (const std::string& name, const std::string& help, + const std::string& valueType) +: std::string (name), mHelp (help), mType (valueType) +{ +} - //------------------------------------------------------------------------ - /*! @param[in] ac count of command-line parameters - @param[in] av command-line as array of strings - @param[out] result the parsing result - @param[out] files optional list of elements on the command line that are not handled by options parsing - */ - bool Descriptions::parse (int ac, char* av[], VariablesMap& result, FilesVector* files) const - { - using namespace std; - - for (int i = 1; i < ac; i++) - { - string current = av[i]; - if (current[0] == '-') - { - int pos = current[1] == '-' ? 2 : 1; - current = current.substr (pos, string::npos); - - DescriptionsList::const_iterator found = - find (mDescriptions.begin (), mDescriptions.end (), current); - if (found != mDescriptions.end ()) - { - result[*found] = "true"; - if (found->mType != Description::kBool) - { - if (((i + 1) < ac) && *av[i + 1] != '-') - { - result[*found] = av[++i]; - } - else - { - result[*found] = "error!"; - result.setError (); - return false; - } - } - } - else - { - result.setError (); - return false; - } - } - else if (files) - files->push_back (av[i]); - } - return true; - } +//------------------------------------------------------------------------ +/*! Returning a reference to *this, enables chaining of calls to operator()(const std::string&, + const std::string&). + + @param[in] name of the added option. + @param[in] help a help description for this option. + @return a reference to *this. +*/ +Descriptions& Descriptions::operator () (const std::string& name, const std::string& help) +{ + mDescriptions.emplace_back (name, help, Description::kBool); + return *this; +} //------------------------------------------------------------------------ - /*! The description includes the help strings for all options. */ - //------------------------------------------------------------------------ - void Descriptions::print (std::ostream& os) const - { - if (!mCaption.empty ()) - os << mCaption << ":\n"; - - size_t maxLength = 0u; - std::for_each (mDescriptions.begin (), mDescriptions.end (), - [&] (const Description& d) { maxLength = std::max (maxLength, d.size ()); }); - - for (const Description& opt : mDescriptions) - { - os << "-" << opt; - for (auto s = opt.size (); s < maxLength; ++s) - os << " "; - os << " | " << opt.mHelp << "\n"; - } - } +/*! Usage example: + @code +CommandLine::Descriptions desc; +desc.addOptions ("myTool") // Set caption to "myTool" + ("help", "produce help message") // add switch -help + ("opt1", string(), "option 1") // add string option -opt1 + ("opt2", string(), "option 2") // add string option -opt2 +; + @endcode +@note + The operator() is used for every additional option. + +Or with initializer list : + @code +CommandLine::Descriptions desc; +desc.addOptions ("myTool", // Set caption to "myTool" + {{"help", "produce help message", Description::kBool}, // add switch -help + {"opt1", "option 1", Description::kString}, // add string option -opt1 + {"opt2", "option 2", Description::kString}} // add string option -opt2 +); + @endcode +@param[in] caption the caption of the command-line tool. +@param[in] options initializer list with options +@return a reverense to *this. +*/ +Descriptions& Descriptions::addOptions (const std::string& caption, + std::initializer_list&& options) +{ + mCaption = caption; + std::move (options.begin (), options.end (), std::back_inserter (mDescriptions)); + return *this; +} //------------------------------------------------------------------------ - std::ostream& operator<< (std::ostream& os, const Descriptions& desc) +/*! @param[in] ac count of command-line parameters + @param[in] av command-line as array of strings + @param[out] result the parsing result + @param[out] files optional list of elements on the command line that are not handled by options + parsing +*/ +bool Descriptions::parse (int ac, char* av[], VariablesMap& result, FilesVector* files) const +{ + using namespace std; + + for (int i = 1; i < ac; i++) { - desc.print (os); - return os; + string current = av[i]; + if (current[0] == '-') + { + int pos = current[1] == '-' ? 2 : 1; + current = current.substr (pos, string::npos); + + DescriptionsList::const_iterator found = + find (mDescriptions.begin (), mDescriptions.end (), current); + if (found != mDescriptions.end ()) + { + result[*found] = "true"; + if (found->mType != Description::kBool) + { + if (((i + 1) < ac) && *av[i + 1] != '-') + { + result[*found] = av[++i]; + } + else + { + result[*found] = "error!"; + result.setError (); + return false; + } + } + } + else + { + result.setError (); + return false; + } + } + else if (files) + files->push_back (av[i]); } + return true; +} - //------------------------------------------------------------------------ - /*! @param[in] ac count of command-line parameters - @param[in] av command-line as array of strings - @param[in] desc Descriptions including all allowed options - @param[out] result the parsing result - @param[out] files optional list of elements on the command line that are not handled by options parsing - */ - bool parse (int ac, char* av[], const Descriptions& desc, VariablesMap& result, FilesVector* files) +//------------------------------------------------------------------------ +/*! The description includes the help strings for all options. */ +//------------------------------------------------------------------------ +void Descriptions::print (std::ostream& os) const +{ + if (!mCaption.empty ()) + os << mCaption << ":\n"; + + size_t maxLength = 0u; + std::for_each (mDescriptions.begin (), mDescriptions.end (), + [&] (const Description& d) { maxLength = std::max (maxLength, d.size ()); }); + + for (const Description& opt : mDescriptions) { - return desc.parse (ac, av, result, files); + os << "-" << opt; + for (auto s = opt.size (); s < maxLength; ++s) + os << " "; + os << " | " << opt.mHelp << "\n"; } +} + +//------------------------------------------------------------------------ +std::ostream& operator<< (std::ostream& os, const Descriptions& desc) +{ + desc.print (os); + return os; +} + +//------------------------------------------------------------------------ +/*! @param[in] ac count of command-line parameters + @param[in] av command-line as array of strings + @param[in] desc Descriptions including all allowed options + @param[out] result the parsing result + @param[out] files optional list of elements on the command line that are not handled by options + parsing +*/ +bool parse (int ac, char* av[], const Descriptions& desc, VariablesMap& result, FilesVector* files) +{ + return desc.parse (ac, av, result, files); +} #endif -} //namespace CommandLine -} //namespace Steinberg +//------------------------------------------------------------------------ +} // namespace CommandLine +} // namespace Steinberg diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fdebug.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fdebug.cpp index 9fe27d85aada..18fa1c9b442f 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fdebug.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fdebug.cpp @@ -11,7 +11,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fdebug.h b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fdebug.h index 3b376ae6420c..ecfb82fcb7a4 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fdebug.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fdebug.h @@ -11,7 +11,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fobject.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fobject.cpp index a061556b928f..239afb56172b 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fobject.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fobject.cpp @@ -10,7 +10,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fobject.h b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fobject.h index 4165a7b400da..080c05599caf 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fobject.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fobject.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -125,6 +125,9 @@ class FObject : public IDependent // static helper functions static inline bool classIDsEqual (FClassID ci1, FClassID ci2); ///< compares (evaluates) 2 class IDs static inline FObject* unknownToObject (FUnknown* unknown); ///< pointer conversion from FUnknown to FObject + /** convert from FUnknown to FObject */ + template + static inline IPtr fromUnknown (FUnknown* unknown); /** Special UID that is used to cast an FUnknown pointer to a FObject */ static const FUID iid; @@ -140,7 +143,24 @@ class FObject : public IDependent //------------------------------------------------------------------------ -// conversion from FUnknown to FObject +// conversion from FUnknown to FObject subclass +//------------------------------------------------------------------------ +template +inline IPtr FObject::fromUnknown (FUnknown* unknown) +{ + if (unknown) + { + FObject* object = nullptr; + if (unknown->queryInterface (FObject::iid, (void**)&object) == kResultTrue && object) + { + if (object->isTypeOf (C::getFClassID (), true)) + return IPtr (static_cast (object), false); + object->release (); + } + } + return {}; +} + //------------------------------------------------------------------------ inline FObject* FObject::unknownToObject (FUnknown* unknown) { @@ -149,7 +169,10 @@ inline FObject* FObject::unknownToObject (FUnknown* unknown) { unknown->queryInterface (FObject::iid, (void**)&object); if (object) - object->release (); // queryInterface has added ref + { + if (object->release () == 0) + object = nullptr; + } } return object; } @@ -168,7 +191,7 @@ inline C* FCast (const FObject* object) { if (object && object->isTypeOf (C::getFClassID (), true)) return (C*) object; - return 0; + return nullptr; } //----------------------------------------------------------------------- @@ -182,19 +205,48 @@ inline C* FCast (FUnknown* unknown) } //----------------------------------------------------------------------- -/** FUCast - casting from FUnknown to Interface */ +/** ICast - casting from FObject to FUnknown Interface */ +//----------------------------------------------------------------------- +template +inline IPtr ICast (FObject* object) +{ + return FUnknownPtr (object ? object->unknownCast () : nullptr); +} + +//----------------------------------------------------------------------- +/** ICast - casting from FUnknown to another FUnknown Interface */ +//----------------------------------------------------------------------- +template +inline IPtr ICast (FUnknown* object) +{ + return FUnknownPtr (object); +} + +//------------------------------------------------------------------------ +template +inline C* FCastIsA (const FObject* object) +{ + if (object && object->isA (C::getFClassID ())) + return (C*)object; + return nullptr; +} + +#ifndef SMTG_HIDE_DEPRECATED_INLINE_FUNCTIONS +//----------------------------------------------------------------------- +/** \deprecated FUCast - casting from FUnknown to Interface */ //----------------------------------------------------------------------- template -inline C* FUCast (FObject* object) +SMTG_DEPRECATED_MSG("use ICast<>") inline C* FUCast (FObject* object) { return FUnknownPtr (object ? object->unknownCast () : nullptr); } template -inline C* FUCast (FUnknown* object) +SMTG_DEPRECATED_MSG("use ICast<>") inline C* FUCast (FUnknown* object) { return FUnknownPtr (object); } +#endif // SMTG_HIDE_DEPRECATED_FUNCTIONS //------------------------------------------------------------------------ /** @name Convenience methods that call release or delete respectively diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstreamer.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstreamer.cpp index 524956b9efff..3a1a2a5aad1f 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstreamer.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstreamer.cpp @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -607,8 +607,10 @@ TSize FStreamer::readString8 (char8* ptr, TSize size) if (i > 0 && ptr[i - 1] == '\r') i--; } + if (i >= size) + i = size - 1; ptr[i] = 0; - + return i; } diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstreamer.h b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstreamer.h index 8b97bb6cd199..dbec4054bc5e 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstreamer.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstreamer.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.cpp index 907baa7338fe..77024c248e77 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.cpp @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -2245,7 +2245,8 @@ bool String::toMultiByte (uint32 destCodePage) //----------------------------------------------------------------------------- void String::fromUTF8 (const char8* utf8String) { - resize (0, false); + if (buffer8 != utf8String) + resize (0, false); _toWideString (utf8String, static_cast (strlen (utf8String)), kCP_Utf8); } diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.h b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.h index 7fc758aa77a3..b8676d6d86fe 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/fstring.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/updatehandler.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/updatehandler.cpp index f4ac80cc570b..e722d45ed7ac 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/updatehandler.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/updatehandler.cpp @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -299,10 +299,7 @@ tresult PLUGIN_API UpdateHandler::removeDependent (FUnknown* u, IDependent* depe listIsEmpty = true; break; } - else - { - iterList = list.erase (iterList); - } + iterList = list.erase (iterList); } else { diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/updatehandler.h b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/updatehandler.h index e85a9bbcc39c..084105e5f10b 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/source/updatehandler.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/source/updatehandler.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/thread/include/flock.h b/modules/juce_audio_processors/format_types/VST3_SDK/base/thread/include/flock.h index 2ef35ba8d8b0..14ffee41586c 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/thread/include/flock.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/thread/include/flock.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -178,6 +178,7 @@ class FConditionalGuard FLock* lock; ///< guarded lock }; -} // Thread -} // Base -} // Steinberg +//------------------------------------------------------------------------ +} // namespace Thread +} // namespace Base +} // namespace Steinberg diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/base/thread/source/flock.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/base/thread/source/flock.cpp index e7c154bad793..ac9d7d57295e 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/base/thread/source/flock.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/base/thread/source/flock.cpp @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -140,7 +140,7 @@ bool FLock::trylock () #endif } -} // Thread -} // Base -} // Steinberg - +//------------------------------------------------------------------------ +} // namespace Thread +} // namespace Base +} // namespace Steinberg diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/LICENSE.txt b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/LICENSE.txt index 6daa072e68e6..f5df1de43803 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/LICENSE.txt +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/LICENSE.txt @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- This license applies only to files referencing this license, for other files of the Software Development Kit the respective embedded license text diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/coreiids.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/coreiids.cpp index d5935044d475..95d59aed499e 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/coreiids.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/coreiids.cpp @@ -37,4 +37,4 @@ DEF_CLASS_IID (IBStream) DEF_CLASS_IID (ISizeableStream) //------------------------------------------------------------------------ -} // Steinberg +} // namespace Steinberg diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/fplatform.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/fplatform.h index 7b4a78d27aa3..fea5e8d62984 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/fplatform.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/fplatform.h @@ -322,8 +322,12 @@ // Deprecation setting //----------------------------------------------------------------------------- #ifndef SMTG_DEPRECATED_ATTRIBUTE +#if SMTG_CPP17 +#define SMTG_DEPRECATED_ATTRIBUTE(msg) [[deprecated(msg)]] +#else #define SMTG_DEPRECATED_ATTRIBUTE(msg) #endif +#endif #define SMTG_DEPRECATED_MSG(msg) SMTG_DEPRECATED_ATTRIBUTE(msg) //----------------------------------------------------------------------------- diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/fstrdefs.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/fstrdefs.h index fea4522c560f..a365b6959430 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/fstrdefs.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/fstrdefs.h @@ -246,7 +246,7 @@ inline SMTG_CONSTEXPR14 void str8ToStr16 (char16* dst, const char8* src, int32 n int32 i = 0; for (;;) { - if (i == n) + if (i == (n - 1)) { dst[i] = 0; return; diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/ftypes.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/ftypes.h index 133dbba38d3c..e1bf9388cbff 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/ftypes.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/ftypes.h @@ -117,7 +117,7 @@ namespace Steinberg typedef int32 UCoord; static const UCoord kMaxCoord = ((UCoord)0x7FFFFFFF); static const UCoord kMinCoord = ((UCoord)-0x7FFFFFFF); -} // namespace Steinberg +} // namespace Steinberg //---------------------------------------------------------------------------- diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/smartpointer.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/smartpointer.h index 99dd037303d5..ca64ae8f6260 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/smartpointer.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/base/smartpointer.h @@ -381,4 +381,6 @@ Used toUsed (T* obj) { return Detail::Adopt::toOwnerType (obj); } //------------------------------------------------------------------------ } // SKI #endif -} // Steinberg + +//------------------------------------------------------------------------ +} // namespace Steinberg diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/gui/iplugview.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/gui/iplugview.h index 797650198d21..b4a00efd25b3 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/gui/iplugview.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/gui/iplugview.h @@ -253,7 +253,11 @@ DECLARE_CLASS_IID (ITimerHandler, 0x10BDD94F, 0x41424774, 0x821FAD8F, 0xECA72CA9 - [released: 3.6.8] On Linux the host has to provide this interface to the plug-in as there's no global event run loop -defined as on other platforms. +defined as on other platforms. + +This can be done by IPlugFrame and the context which is passed to the plug-in as an argument +in the method IPlugFactory3::setHostContext. This way the plug-in can get a runloop even if +it does not have an editor. A plug-in can register an event handler for a file descriptor. The host has to call the event handler when the file descriptor is marked readable. diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstaudioprocessor.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstaudioprocessor.h index 82d550e32773..03e76b46403d 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstaudioprocessor.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstaudioprocessor.h @@ -48,15 +48,20 @@ namespace PlugType //------------------------------------------------------------------------ SMTG_CONSTEXPR const CString kFx = "Fx"; ///< others type (not categorized) SMTG_CONSTEXPR const CString kFxAnalyzer = "Fx|Analyzer"; ///< Scope, FFT-Display, Loudness Processing... +SMTG_CONSTEXPR const CString kFxBass = "Fx|Bass"; ///< Tools dedicated to Bass Guitar +SMTG_CONSTEXPR const CString kFxChannelStrip = "Fx|Channel Strip"; ///< Tools dedicated to Channel Strip SMTG_CONSTEXPR const CString kFxDelay = "Fx|Delay"; ///< Delay, Multi-tap Delay, Ping-Pong Delay... SMTG_CONSTEXPR const CString kFxDistortion = "Fx|Distortion"; ///< Amp Simulator, Sub-Harmonic, SoftClipper... +SMTG_CONSTEXPR const CString kFxDrums = "Fx|Drums"; ///< Tools dedicated to Drums... SMTG_CONSTEXPR const CString kFxDynamics = "Fx|Dynamics"; ///< Compressor, Expander, Gate, Limiter, Maximizer, Tape Simulator, EnvelopeShaper... SMTG_CONSTEXPR const CString kFxEQ = "Fx|EQ"; ///< Equalization, Graphical EQ... SMTG_CONSTEXPR const CString kFxFilter = "Fx|Filter"; ///< WahWah, ToneBooster, Specific Filter,... SMTG_CONSTEXPR const CString kFxGenerator = "Fx|Generator"; ///< Tone Generator, Noise Generator... +SMTG_CONSTEXPR const CString kFxGuitar = "Fx|Guitar"; ///< Tools dedicated to Guitar SMTG_CONSTEXPR const CString kFxInstrument = "Fx|Instrument"; ///< Fx which could be loaded as Instrument too SMTG_CONSTEXPR const CString kFxInstrumentExternal = "Fx|Instrument|External"; ///< Fx which could be loaded as Instrument too and is external (wrapped Hardware) SMTG_CONSTEXPR const CString kFxMastering = "Fx|Mastering"; ///< Dither, Noise Shaping,... +SMTG_CONSTEXPR const CString kFxMicrophone = "Fx|Microphone"; ///< Tools dedicated to Microphone SMTG_CONSTEXPR const CString kFxModulation = "Fx|Modulation"; ///< Phaser, Flanger, Chorus, Tremolo, Vibrato, AutoPan, Rotary, Cloner... SMTG_CONSTEXPR const CString kFxNetwork = "Fx|Network"; ///< using Network SMTG_CONSTEXPR const CString kFxPitchShift = "Fx|Pitch Shift"; ///< Pitch Processing, Pitch Correction, Vocal Tuning... @@ -65,7 +70,7 @@ SMTG_CONSTEXPR const CString kFxReverb = "Fx|Reverb"; ///< Reverberation, Ro SMTG_CONSTEXPR const CString kFxSpatial = "Fx|Spatial"; ///< MonoToStereo, StereoEnhancer,... SMTG_CONSTEXPR const CString kFxSurround = "Fx|Surround"; ///< dedicated to surround processing: LFE Splitter, Bass Manager... SMTG_CONSTEXPR const CString kFxTools = "Fx|Tools"; ///< Volume, Mixer, Tuner... -SMTG_CONSTEXPR const CString kFxVocals = "Fx|Vocals"; ///< Tools dedicated to vocals +SMTG_CONSTEXPR const CString kFxVocals = "Fx|Vocals"; ///< Tools dedicated to Vocals SMTG_CONSTEXPR const CString kInstrument = "Instrument"; ///< Effect used as instrument (sound generator), not as insert SMTG_CONSTEXPR const CString kInstrumentDrum = "Instrument|Drum"; ///< Instrument for Drum sounds diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h new file mode 100644 index 000000000000..9919c1775931 --- /dev/null +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h @@ -0,0 +1,221 @@ +//------------------------------------------------------------------------ +// Project : VST SDK +// +// Category : Interfaces +// Filename : pluginterfaces/vst/ivstdataexchange.h +// Created by : Steinberg, 06/2022 +// Description : VST Data Exchange Interface +// +//----------------------------------------------------------------------------- +// This file is part of a Steinberg SDK. It is subject to the license terms +// in the LICENSE file found in the top-level directory of this distribution +// and at www.steinberg.net/sdklicenses. +// No part of the SDK, including this file, may be copied, modified, propagated, +// or distributed except according to the terms contained in the LICENSE file. +//----------------------------------------------------------------------------- + +#pragma once + +#include "pluginterfaces/base/funknown.h" + +//------------------------------------------------------------------------ +#include "pluginterfaces/base/falignpush.h" +//------------------------------------------------------------------------ + +//------------------------------------------------------------------------ +namespace Steinberg { +namespace Vst { + +//------------------------------------------------------------------------ +class IAudioProcessor; + +//------------------------------------------------------------------------ +typedef uint32 DataExchangeQueueID; +typedef uint32 DataExchangeBlockID; +typedef uint32 DataExchangeUserContextID; + +//------------------------------------------------------------------------ +static SMTG_CONSTEXPR DataExchangeQueueID InvalidDataExchangeQueueID = kMaxInt32; +static SMTG_CONSTEXPR DataExchangeBlockID InvalidDataExchangeBlockID = kMaxInt32; + +//------------------------------------------------------------------------ +struct DataExchangeBlock +{ + /** pointer to the memory buffer */ + void* data; + /** size of the memory buffer */ + uint32 size; + /** block identifier */ + DataExchangeBlockID blockID; +}; + +//------------------------------------------------------------------------ +/** Host Data Exchange handler interface: Vst::IDataExchangeHandler +\ingroup vstHost vst379 +- [host imp] +- [context interface] +- [released: 3.7.9] +- [optional] + +The IDataExchangeHandler implements a direct and thread-safe connection from the realtime +audio context of the audio processor to the non-realtime audio context of the edit controller. +This should be used when the edit controller needs continuous data from the audio process for +visualization or other use-cases. To circumvent the bottleneck on the main thread it is possible +to configure the connection in a way that the calls to the edit controller will happen on a +background thread. + +Opening a queue: +The main operation for a plug-in is to open a queue via the handler before the plug-in is activated +(but it must be connected to the edit controller via the IConnectionPoint when the plug-in is using +the recommended separation of edit controller and audio processor). The best place to do this is in +the IAudioProcessor::setupProcessing method as this is also the place where the plug-in knows the +sample rate and maximum block size which the plug-in may need to calculate the queue block size. +When a queue is opened the edit controller gets a notification about it and the controller can +decide if it wishes to receive the data on the main thread or the background thread. + +Sending data: +In the IAudioProcessor::process call the plug-in can now lock a block from the handler, fill it and +when done free the block via the handler which then sends the block to the edit controller. The edit +controller then receives the block either on the main thread or on a background thread depending on +the setup of the queue. +The host guarantees that all blocks are send before the plug-in is deactivated. + +Closing a queue: +The audio processor must close an opened queue and this has to be done after the processor was +deactivated and before it is disconnected from the edit controller (see IConnectionPoint). + +What to do when the queue is full and no block can be locked? +The plug-in needs to be prepared for this situation as constraints in the overall system may cause +the queue to get full. If you need to get this information to the controller you can declare a +hidden parameter which you set to a special value and send this parameter change in your audio +process method. +*/ +class IDataExchangeHandler : public FUnknown +{ +public: + /** open a new queue + * + * only allowed to be called from the main thread when the component is not active but + * initialized and connected (see IConnectionPoint) + * + * @param processor the processor who wants to open the queue + * @param blockSize size of one block + * @param numBlocks number of blocks in the queue + * @param alignment data alignment, if zero will use the platform default alignment if any + * @param userContextID an identifier internal to the processor + * @param outID on return the ID of the queue + * @return kResultTrue on success + */ + virtual tresult PLUGIN_API openQueue (IAudioProcessor* processor, uint32 blockSize, + uint32 numBlocks, uint32 alignment, + DataExchangeUserContextID userContextID, + DataExchangeQueueID* outID) = 0; + /** close a queue + * + * closes and frees all memory of a previously opened queue + * if there are locked blocks in the queue, they are freed and made invalid + * + * only allowed to be called from the main thread when the component is not active but + * initialized and connected + * + * @param queueID the ID of the queue to close + * @return kResultTrue on success + */ + virtual tresult PLUGIN_API closeQueue (DataExchangeQueueID queueID) = 0; + + /** lock a block if available + * + * only allowed to be called from within the IAudioProcessor::process call + * + * @param queueID the ID of the queue + * @param block on return will contain the data pointer and size of the block + * @return kResultTrue if a free block was found and kOutOfMemory if all blocks are locked + */ + virtual tresult PLUGIN_API lockBlock (DataExchangeQueueID queueId, + DataExchangeBlock* block) = 0; + + /** free a previously locked block + * + * only allowed to be called from within the IAudioProcessor::process call + * + * @param queueID the ID of the queue + * @param blockID the ID of the block + * @param sendToController if true the block data will be send to the IEditController otherwise + * it will be discarded + * @return kResultTrue on success + */ + virtual tresult PLUGIN_API freeBlock (DataExchangeQueueID queueId, DataExchangeBlockID blockID, + TBool sendToController) = 0; + +//------------------------------------------------------------------------ + static const FUID iid; +}; + +DECLARE_CLASS_IID (IDataExchangeHandler, 0x36D551BD, 0x6FF54F08, 0xB48E830D, 0x8BD5A03B) + +//------------------------------------------------------------------------ +/** Data Exchange Receiver interface: Vst::IDataExchangeReceiver +\ingroup vstPlug vst379 +- [plug imp] +- [released: 3.7.9 +- [optional] + +The receiver interface is required to receive data from the realtime audio process via the +IDataExchangeHandler. + +\see \ref IDataExchangeHandler +*/ +class IDataExchangeReceiver : public FUnknown +{ +public: + /** queue opened notification + * + * called on the main thread when the processor has opened a queue + * + * @param userContextID the user context ID of the queue + * @param blockSize the size of one block of the queue + * @param dispatchedOnBackgroundThread if true on output the blocks are dispatched on a + * background thread [defaults to false in which case the + * blocks are dispatched on the main thread] + */ + virtual void PLUGIN_API queueOpened (DataExchangeUserContextID userContextID, uint32 blockSize, + TBool& dispatchOnBackgroundThread) = 0; + /** queue closed notification + * + * called on the main thread when the processor has closed a queue + * + * @param userContextID the user context ID of the queue + */ + virtual void PLUGIN_API queueClosed (DataExchangeUserContextID userContextID) = 0; + + /** one or more blocks were received + * + * called either on the main thread or a background thread depending on the + * dispatchOnBackgroundThread value in the queueOpened call. + * + * the data of the blocks are only valid inside this call and the blocks only become available + * to the queue afterwards. + * + * @param userContextID the user context ID of the queue + * @param numBlocks number of blocks + * @param blocks the blocks + * @param onBackgroundThread true if the call is done on a background thread + */ + virtual void PLUGIN_API onDataExchangeBlocksReceived (DataExchangeUserContextID userContextID, + uint32 numBlocks, + DataExchangeBlock* blocks, + TBool onBackgroundThread) = 0; + +//------------------------------------------------------------------------ + static const FUID iid; +}; + +DECLARE_CLASS_IID (IDataExchangeReceiver, 0x45A759DC, 0x84FA4907, 0xABCB6175, 0x2FC786B6) + +//------------------------------------------------------------------------ +} // namespace Vst +} // namespace Steinberg + +//------------------------------------------------------------------------ +#include "pluginterfaces/base/falignpop.h" +//------------------------------------------------------------------------ diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h index d7c8925c135c..48128fbe9062 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h @@ -86,7 +86,7 @@ const CString kEditor = "editor"; enum RestartFlags { /** The Component should be reloaded - * The host has to unload completely the plug-in (controller/processor) and reload it. + * The host has to unload completely the plug-in (controller/processor) and reload it. * [SDK 3.0.0] */ kReloadComponent = 1 << 0, @@ -105,7 +105,7 @@ enum RestartFlags /** Latency has changed * The plug informs the host that its latency has changed, getLatencySamples should return the new latency after setActive (true) was called * The host has to deactivate and reactivate the plug-in, then afterwards the host could ask for the current latency (getLatencySamples) - * see IAudioProcessor::getLatencySamples + * See IAudioProcessor::getLatencySamples * [SDK 3.0.0] */ kLatencyChanged = 1 << 3, @@ -121,39 +121,53 @@ enum RestartFlags * and reread program changes parameters (stepCount and associated unitID) * [SDK 3.0.1] */ kMidiCCAssignmentChanged = 1 << 5, - + /** Note Expression has changed (info, count, PhysicalUIMapping, ...) * Either the note expression type info, the count of note expressions or the physical UI mapping has changed. * The host invalidates all caches of note expression infos and asks the edit controller for the current ones. * See INoteExpressionController, NoteExpressionTypeInfo and INoteExpressionPhysicalUIMapping * [SDK 3.5.0] */ kNoteExpressionChanged = 1 << 6, - + /** Input / Output bus titles have changed * The host invalidates all caches of bus titles and asks the edit controller for the current titles. * [SDK 3.5.0] */ kIoTitlesChanged = 1 << 7, - + /** Prefetch support has changed * The plug-in informs the host that its PrefetchSupport has changed - * The host has to deactivate the plug-in, calls IPrefetchableSupport::getPrefetchableSupport and reactivate the plug-in - * see IPrefetchableSupport + * The host has to deactivate the plug-in, calls IPrefetchableSupport::getPrefetchableSupport + * and reactivate the plug-in. + * See IPrefetchableSupport * [SDK 3.6.1] */ - kPrefetchableSupportChanged = 1 << 8, + kPrefetchableSupportChanged = 1 << 8, /** RoutingInfo has changed - * The plug-in informs the host that its internal routing (relation of an event-input-channel to an audio-output-bus) has changed - * The host ask the plug-in for the new routing with IComponent::getRoutingInfo, \ref vst3Routing - * see IComponent + * The plug-in informs the host that its internal routing (relation of an event-input-channel to + * an audio-output-bus) has changed. The host asks the plug-in for the new routing with + * IComponent::getRoutingInfo, \ref vst3Routing + * See IComponent * [SDK 3.6.6] */ kRoutingInfoChanged = 1 << 9, /** Key switches has changed (info, count) * Either the Key switches info, the count of Key switches has changed. - * The host invalidates all caches of Key switches infos and asks the edit controller (IKeyswitchController) for the current ones. + * The host invalidates all caches of Key switches infos and asks the edit controller + * (IKeyswitchController) for the current ones. * See IKeyswitchController * [SDK 3.7.3] */ - kKeyswitchChanged = 1 << 10 + kKeyswitchChanged = 1 << 10, + + /** Mapping of ParamID has changed + * The Plug-in informs the host that its parameters ID has changed. This has to be called by the + * edit controller in the method setComponentState or setState (during projects loading) when the + * plug-in detects that the given state was associated to an older version of the plug-in, or to a + * plug-in to replace (for ex. migrating VST2 => VST3), with a different set of parameter IDs, then + * the host could remap any used parameters like automation by asking the IRemapParamID interface + * (which extends IEditController). + * See IRemapParamID + * [SDK 3.7.11] */ + kParamIDMappingChanged = 1 << 11 }; //------------------------------------------------------------------------ @@ -613,6 +627,27 @@ class IEditControllerHostEditing : public FUnknown DECLARE_CLASS_IID (IEditControllerHostEditing, 0xC1271208, 0x70594098, 0xB9DD34B3, 0x6BB0195E) +//------------------------------------------------------------------------ +/** Extended plug-in interface IComponentHandler for an edit controller +\ingroup vstIHost vst379 +- [host imp] +- [extends IComponentHandler] +- [released: 3.7.9] +- [optional] +*/ +//------------------------------------------------------------------------ +class IComponentHandlerSystemTime : public FUnknown +{ +public: +//------------------------------------------------------------------------ + /** get the current systemTime (the same as the one used in ProcessContext::systemTime). */ + virtual tresult PLUGIN_API getSystemTime (int64& systemTime) = 0; +//------------------------------------------------------------------------ + static const FUID iid; +}; + +DECLARE_CLASS_IID (IComponentHandlerSystemTime, 0xF9E53056, 0xD1554CD5, 0xB7695E1B, 0x7B0F7745) + //------------------------------------------------------------------------ } // namespace Vst } // namespace Steinberg diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h new file mode 100644 index 000000000000..bf655d4e31f9 --- /dev/null +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h @@ -0,0 +1,75 @@ +//------------------------------------------------------------------------ +// Project : VST SDK +// +// Category : Interfaces +// Filename : pluginterfaces/vst/ivstremapparamid.h +// Created by : Steinberg, 02/2024 +// Description : VST Edit Controller Interfaces +// +//----------------------------------------------------------------------------- +// This file is part of a Steinberg SDK. It is subject to the license terms +// in the LICENSE file found in the top-level directory of this distribution +// and at www.steinberg.net/sdklicenses. +// No part of the SDK, including this file, may be copied, modified, propagated, +// or distributed except according to the terms contained in the LICENSE file. +//----------------------------------------------------------------------------- + +#pragma once + +#include "pluginterfaces/base/funknown.h" +#include "pluginterfaces/vst/vsttypes.h" + +//------------------------------------------------------------------------ +#include "pluginterfaces/base/falignpush.h" +//------------------------------------------------------------------------ + +//------------------------------------------------------------------------ +namespace Steinberg { +namespace Vst { + +//------------------------------------------------------------------------ +/** Extended IEditController interface for a component. +\ingroup vstIPlug vst3711 +- [plug imp] +- [extends IEditController] +- [released: 3.7.11] +- [optional] + +When replacing one plug-in with another, the host can ask the new plug-in for remapping paramIDs to +new ones. + +\n +\see Moduleinfo +\see \ref IPluginCompatibility +\see IEditController +*/ +class IRemapParamID : public FUnknown +{ +public: +//------------------------------------------------------------------------ + /** Retrieve the appropriate paramID for a specific plug-in UID and paramID (or index for VST 2 + * plug-ins). + * The retrieved paramID should match the one it replaces, maintaining the same + * behavior during automation playback. Called in UI-Thread context. + * @param[in] pluginToReplaceUID - TUID of plug-in (processor) that will be replaced + * @param[in] oldParamID - paramID (or index for VST 2 plug-ins) to be replaced + * @param[out] newParamID - contains the associated paramID to be used + * Return kResultTrue means that a compatible parameter is available + * Return kResultFalse means that NO compatible parameter is available + */ + virtual tresult PLUGIN_API getCompatibleParamID (const TUID pluginToReplaceUID /*in*/, + ParamID oldParamID /*in*/, + ParamID& newParamID /*out*/) = 0; +//------------------------------------------------------------------------ + static const FUID iid; +}; + +DECLARE_CLASS_IID (IRemapParamID, 0x2B88021E, 0x6286B646, 0xB49DF76A, 0x5663061C) + +//------------------------------------------------------------------------ +} // namespace Vst +} // namespace Steinberg + +//------------------------------------------------------------------------ +#include "pluginterfaces/base/falignpop.h" +//------------------------------------------------------------------------ diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/vstspeaker.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/vstspeaker.h index 0d21684fc13f..ad70211d1a2e 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/vstspeaker.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/vstspeaker.h @@ -103,6 +103,9 @@ const Speaker kSpeakerBsr = (Speaker)1 << 34; ///< Bottom Side Right (Bsr) const Speaker kSpeakerBrl = (Speaker)1 << 35; ///< Bottom Rear Left (Brl) const Speaker kSpeakerBrc = (Speaker)1 << 36; ///< Bottom Rear Center (Brc) const Speaker kSpeakerBrr = (Speaker)1 << 37; ///< Bottom Rear Right (Brr) + +const Speaker kSpeakerLw = (Speaker)1 << 59; ///< Left Wide (Lw) +const Speaker kSpeakerRw = (Speaker)1 << 60; ///< Right Wide (Rw) //------------------------------------------------------------------------ /** @}*/ @@ -118,6 +121,7 @@ namespace SpeakerArr const SpeakerArrangement kEmpty = 0; ///< empty arrangement const SpeakerArrangement kMono = kSpeakerM; ///< M const SpeakerArrangement kStereo = kSpeakerL | kSpeakerR; ///< L R +const SpeakerArrangement kStereoWide = kSpeakerLw | kSpeakerRw; ///< Lw Rw const SpeakerArrangement kStereoSurround = kSpeakerLs | kSpeakerRs; ///< Ls Rs const SpeakerArrangement kStereoCenter = kSpeakerLc | kSpeakerRc; ///< Lc Rc const SpeakerArrangement kStereoSide = kSpeakerSl | kSpeakerSr; ///< Sl Sr @@ -306,6 +310,22 @@ const SpeakerArrangement k90_6 = kSpeakerL | kSpeakerR | kSpeakerC | /** L R C Lfe Ls Rs Lc Rc Sl Sr Tfl Tfr Trl Trr Tsl Tsr */ // 9.1.6 const SpeakerArrangement k91_6 = k90_6 | kSpeakerLfe; +/** L R C Ls Rs Sl Sr Tfl Tfr Trl Trr Lw Rw */ // 9.0.4 (Dolby) +const SpeakerArrangement k90_4_W = kSpeakerL | kSpeakerR | kSpeakerC | + kSpeakerLs | kSpeakerRs | kSpeakerLw | kSpeakerRw | kSpeakerSl | kSpeakerSr | + kSpeakerTfl | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; + +/** L R C Lfe Ls Rs Sl Sr Tfl Tfr Trl Trr Lw Rw */ // 9.1.4 (Dolby) +const SpeakerArrangement k91_4_W = k90_4_W | kSpeakerLfe; + +/** L R C Ls Rs Sl Sr Tfl Tfr Trl Trr Tsl Tsr Lw Rw */ // 9.0.6 (Dolby) +const SpeakerArrangement k90_6_W = kSpeakerL | kSpeakerR | kSpeakerC | + kSpeakerLs | kSpeakerRs | kSpeakerLw | kSpeakerRw | kSpeakerSl | kSpeakerSr | + kSpeakerTfl | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr | kSpeakerTsl | kSpeakerTsr; + +/** L R C Lfe Ls Rs Sl Sr Tfl Tfr Trl Trr Tsl Tsr Lw Rw */ // 9.1.6 (Dolby) +const SpeakerArrangement k91_6_W = k90_6_W | kSpeakerLfe; + /** L R C Ls Rs Tc Tfl Tfr Trl Trr */ // 5.0.5 (10.0 Auro-3D) const SpeakerArrangement k100 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerLs | kSpeakerRs | kSpeakerTc | kSpeakerTfl | kSpeakerTfr | kSpeakerTrl | kSpeakerTrr; @@ -424,6 +444,7 @@ const SpeakerArrangement k50_4_4 = kSpeakerL | kSpeakerR | kSpeakerC | kSpeakerL const CString kStringEmpty = ""; const CString kStringMono = "Mono"; const CString kStringStereo = "Stereo"; +const CString kStringStereoWide = "Stereo (Lw Rw)"; const CString kStringStereoR = "Stereo (Ls Rs)"; const CString kStringStereoC = "Stereo (Lc Rc)"; const CString kStringStereoSide = "Stereo (Sl Sr)"; @@ -487,10 +508,14 @@ const CString kString70_4 = "7.0.4"; const CString kString71_4 = "7.1.4"; const CString kString70_6 = "7.0.6"; const CString kString71_6 = "7.1.6"; -const CString kString90_4 = "9.0.4"; -const CString kString91_4 = "9.1.4"; -const CString kString90_6 = "9.0.6"; -const CString kString91_6 = "9.1.6"; +const CString kString90_4 = "9.0.4 ITU"; +const CString kString91_4 = "9.1.4 ITU"; +const CString kString90_6 = "9.0.6 ITU"; +const CString kString91_6 = "9.1.6 ITU"; +const CString kString90_4_W = "9.0.4"; +const CString kString91_4_W = "9.1.4"; +const CString kString90_6_W = "9.0.6"; +const CString kString91_6_W = "9.1.6"; const CString kString50_5 = "10.0 Auro-3D"; const CString kString51_5 = "10.1 Auro-3D"; const CString kString50_6 = "11.0 Auro-3D"; @@ -514,13 +539,13 @@ const CString kString30_5_2 = "3.0.5.2"; const CString kString40_4_4 = "4.0.4.4"; const CString kString50_4_4 = "5.0.4.4"; -const CString kStringAmbi1stOrder = "1st Order Ambisonics"; -const CString kStringAmbi2cdOrder = "2nd Order Ambisonics"; -const CString kStringAmbi3rdOrder = "3rd Order Ambisonics"; -const CString kStringAmbi4thOrder = "4th Order Ambisonics"; -const CString kStringAmbi5thOrder = "5th Order Ambisonics"; -const CString kStringAmbi6thOrder = "6th Order Ambisonics"; -const CString kStringAmbi7thOrder = "7th Order Ambisonics"; +const CString kStringAmbi1stOrder = "1OA"; +const CString kStringAmbi2cdOrder = "2OA"; +const CString kStringAmbi3rdOrder = "3OA"; +const CString kStringAmbi4thOrder = "4OA"; +const CString kStringAmbi5thOrder = "5OA"; +const CString kStringAmbi6thOrder = "6OA"; +const CString kStringAmbi7thOrder = "7OA"; /*@}*/ //------------------------------------------------------------------------ @@ -529,6 +554,7 @@ const CString kStringAmbi7thOrder = "7th Order Ambisonics"; /*@{*/ const CString kStringMonoS = "M"; const CString kStringStereoS = "L R"; +const CString kStringStereoWideS = "Lw Rw"; const CString kStringStereoRS = "Ls Rs"; const CString kStringStereoCS = "Lc Rc"; const CString kStringStereoSS = "Sl Sr"; @@ -589,6 +615,10 @@ const CString kString90_4S = "L R C Ls Rs Lc Rc Sl Sr Tfl Tfr Trl Trr"; const CString kString91_4S = "L R C LFE Ls Rs Lc Rc Sl Sr Tfl Tfr Trl Trr"; const CString kString90_6S = "L R C Ls Rs Lc Rc Sl Sr Tfl Tfr Trl Trr Tsl Tsr"; const CString kString91_6S = "L R C LFE Ls Rs Lc Rc Sl Sr Tfl Tfr Trl Trr Tsl Tsr"; +const CString kString90_4_WS = "L R C Ls Rs Sl Sr Tfl Tfr Trl Trr Lw Rw"; +const CString kString91_4_WS = "L R C LFE Ls Rs Sl Sr Tfl Tfr Trl Trr Lw Rw"; +const CString kString90_6_WS = "L R C Ls Rs Sl Sr Tfl Tfr Trl Trr Tsl Tsr Lw Rw"; +const CString kString91_6_WS = "L R C LFE Ls Rs Sl Sr Tfl Tfr Trl Trr Tsl Tsr Lw Rw"; const CString kString50_5S = "L R C Ls Rs Tc Tfl Tfr Trl Trr"; const CString kString51_5S = "L R C LFE Ls Rs Tc Tfl Tfr Trl Trr"; const CString kString50_5_SonyS = "L R C Ls Rs Tfl Tfc Tfr Trl Trr"; @@ -730,7 +760,8 @@ inline bool hasMiddleSpeakers (const SpeakerArrangement& arr) if (arr & kSpeakerL || arr & kSpeakerR || arr & kSpeakerC || arr & kSpeakerLs || arr & kSpeakerRs || arr & kSpeakerLc || arr & kSpeakerRc || arr & kSpeakerCs || arr & kSpeakerSl || arr & kSpeakerSr || arr & kSpeakerM || arr & kSpeakerPl || - arr & kSpeakerPr || arr & kSpeakerLcs || arr & kSpeakerRcs) + arr & kSpeakerPr || arr & kSpeakerLcs || arr & kSpeakerRcs || arr & kSpeakerLw || + arr & kSpeakerRw) return true; return false; } @@ -802,6 +833,8 @@ inline SpeakerArrangement getSpeakerArrangementFromString (CString arrStr) return kStereo; if (!strcmp8 (arrStr, kStringStereoR)) return kStereoSurround; + if (!strcmp8 (arrStr, kStringStereoWide)) + return kStereoWide; if (!strcmp8 (arrStr, kStringStereoC)) return kStereoCenter; if (!strcmp8 (arrStr, kStringStereoSide)) @@ -926,6 +959,14 @@ inline SpeakerArrangement getSpeakerArrangementFromString (CString arrStr) return k90_6; if (!strcmp8 (arrStr, kString91_6)) return k91_6; + if (!strcmp8 (arrStr, kString90_4_W)) + return k90_4_W; + if (!strcmp8 (arrStr, kString91_4_W)) + return k91_4_W; + if (!strcmp8 (arrStr, kString90_6_W)) + return k90_6_W; + if (!strcmp8 (arrStr, kString91_6_W)) + return k91_6_W; if (!strcmp8 (arrStr, kString50_5)) return k50_5; if (!strcmp8 (arrStr, kString51_5)) @@ -998,6 +1039,7 @@ inline CString getSpeakerArrangementString (SpeakerArrangement arr, bool withSpe //--- Stereo pairs--- case kStereo: return withSpeakersName ? kStringStereoS : kStringStereo; case kStereoSurround: return withSpeakersName ? kStringStereoRS : kStringStereoR; + case kStereoWide: return withSpeakersName ? kStringStereoWideS : kStringStereoWide; case kStereoCenter: return withSpeakersName ? kStringStereoCS : kStringStereoC; case kStereoSide: return withSpeakersName ? kStringStereoSS : kStringStereoSide; case kStereoCLfe: return withSpeakersName ? kStringStereoCLfeS: kStringStereoCLfe; @@ -1066,6 +1108,10 @@ inline CString getSpeakerArrangementString (SpeakerArrangement arr, bool withSpe case k91_4: return withSpeakersName ? kString91_4S : kString91_4; case k90_6: return withSpeakersName ? kString90_6S : kString90_6; case k91_6: return withSpeakersName ? kString91_6S : kString91_6; + case k90_4_W: return withSpeakersName ? kString90_4_WS : kString90_4_W; + case k91_4_W: return withSpeakersName ? kString91_4_WS : kString91_4_W; + case k90_6_W: return withSpeakersName ? kString90_6_WS : kString90_6_W; + case k91_6_W: return withSpeakersName ? kString91_6_WS : kString91_6_W; case k130: return withSpeakersName ? kString130S : kString130; case k131: return withSpeakersName ? kString131S : kString131; @@ -1257,6 +1303,10 @@ inline CString getSpeakerShortName (const SpeakerArrangement& arr, int32 index) if (speaker == kSpeakerBrr) return "Brr"; + if (speaker == kSpeakerLw) + return "Lw"; + if (speaker == kSpeakerRw) + return "Rw"; return ""; } diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/vsttypes.h b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/vsttypes.h index 081177fa6879..243f02aa7203 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/vsttypes.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/vsttypes.h @@ -24,17 +24,20 @@ namespace Vst { //------------------------------------------------------------------------ /** VST 3 SDK Version */ #ifndef kVstVersionString -#define kVstVersionString "VST 3.7.8" ///< SDK version for PClassInfo2 +#define kVstVersionString "VST 3.7.11" ///< SDK version for PClassInfo2 #endif #define kVstVersionMajor 3 #define kVstVersionMinor 7 -#define kVstVersionSub 8 +#define kVstVersionSub 11 #define VST_VERSION ((kVstVersionMajor << 16) | (kVstVersionMinor << 8) | kVstVersionSub) // Versions History which allows to write such code: // #if VST_VERSION >= VST_3_6_5_VERSION +#define VST_3_7_11_VERSION 0x03070B +#define VST_3_7_10_VERSION 0x03070A +#define VST_3_7_9_VERSION 0x030709 #define VST_3_7_8_VERSION 0x030708 #define VST_3_7_7_VERSION 0x030707 #define VST_3_7_6_VERSION 0x030706 @@ -77,8 +80,11 @@ typedef int32 BusDirection; ///< bus direction (in/out) typedef int32 BusType; ///< bus type (main/aux) typedef int32 IoMode; ///< I/O mode (see \ref vst3IoMode) typedef int32 UnitID; ///< unit identifier -typedef double ParamValue; ///< parameter value type -typedef uint32 ParamID; ///< parameter identifier + +typedef double ParamValue; ///< parameter value type: normalized value => [0.0, 1.0] +typedef uint32 ParamID; ///< parameter identifier: value in range [0, 0x7FFFFFFF]. + /// The range [0x80000000, 0xFFFFFFFF], is reserved for host application. + typedef int32 ProgramListID; ///< program list identifier typedef int16 CtrlNumber; ///< MIDI controller number (see \ref ControllerNumbers for allowed values) @@ -88,8 +94,9 @@ typedef int64 TSamples; ///< time expressed in audio samples typedef uint32 ColorSpec; ///< color defining by 4 component ARGB value (Alpha/Red/Green/Blue) //------------------------------------------------------------------------ -static const ParamID kNoParamId = 0xffffffff; ///< default for uninitialized parameter ID -// static const ParamID kNoParamId = std::numeric_limits::max (); +static const ParamID kNoParamId = 0xFFFFFFFF; ///< default for uninitialized parameter ID +static const ParamID kMinParamId = 0; ///< value min for a parameter ID +static const ParamID kMaxParamId = 0x7FFFFFFF; ///< value max for a parameter ID //------------------------------------------------------------------------ // Audio Types @@ -117,6 +124,10 @@ static SMTG_CONSTEXPR const uint32 SDKVersion = // Versions History which allows to write such code: // if constexpr (SDKVersion >= SDKVersion_3_6_5) { ... } +static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_11 = VST_3_7_11_VERSION; +static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_10 = VST_3_7_10_VERSION; +static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_9 = VST_3_7_9_VERSION; +static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_8 = VST_3_7_8_VERSION; static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_7 = VST_3_7_7_VERSION; static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_6 = VST_3_7_6_VERSION; static SMTG_CONSTEXPR const uint32 SDKVersion_3_7_5 = VST_3_7_5_VERSION; diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/LICENSE.txt b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/LICENSE.txt index f9c531e7455a..ec797c8bd323 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/LICENSE.txt +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/LICENSE.txt @@ -1,6 +1,6 @@ //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/README.md b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/README.md index e7c8a937482b..b06fef1ac7bc 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/README.md +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/README.md @@ -7,7 +7,6 @@ Here are located: - **AAX** Wrapper - **AU** Wrapper - **AUv3** Wrapper -- **VST 2** Wrapper - InterAppAudio ## License & Usage guidelines diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/samples/vst-utilities/moduleinfotool/source/main.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/samples/vst-utilities/moduleinfotool/source/main.cpp index 2d568ae8314b..fccecf518dc0 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/samples/vst-utilities/moduleinfotool/source/main.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/samples/vst-utilities/moduleinfotool/source/main.cpp @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -35,16 +35,14 @@ // OF THE POSSIBILITY OF SUCH DAMAGE. //----------------------------------------------------------------------------- -#include "base/source/fcommandline.h" -#include "pluginterfaces/base/fplatform.h" -#include "pluginterfaces/base/iplugincompatibility.h" -#include "pluginterfaces/vst/vsttypes.h" -#include "public.sdk/source/common/memorystream.h" #include "public.sdk/source/common/readfile.h" #include "public.sdk/source/vst/hosting/module.h" #include "public.sdk/source/vst/moduleinfo/moduleinfocreator.h" #include "public.sdk/source/vst/moduleinfo/moduleinfoparser.h" #include "public.sdk/source/vst/utility/stringconvert.h" +#include "base/source/fcommandline.h" +#include "pluginterfaces/base/fplatform.h" +#include "pluginterfaces/vst/vsttypes.h" #include #include #include @@ -98,35 +96,6 @@ std::optional openAndParseCompatJSON (const std:: return result; } -//------------------------------------------------------------------------ -std::optional loadCompatibilityFromModule (const VST3::Hosting::Module& module) -{ - const auto& factory = module.getFactory(); - const auto& infos = factory.classInfos(); - - const auto iter = std::find_if (infos.begin(), infos.end(), [&] (const auto& info) - { - return info.category() == kPluginCompatibilityClass; - }); - - if (iter == infos.end()) - return {}; - - const auto compatibility = factory.createInstance (iter->ID()); - - if (compatibility == nullptr) - return {}; - - Steinberg::MemoryStream stream; - - if (compatibility->getCompatibilityJSON (&stream) != kResultOk) - return {}; - - const std::string_view streamView (stream.getData(), stream.getSize()); - - return ModuleInfoLib::parseCompatibilityJson (streamView, nullptr); -} - //------------------------------------------------------------------------ int createJSON (const std::optional& compat, const std::string& modulePath, const std::string& moduleVersion, @@ -142,9 +111,6 @@ int createJSON (const std::optional& compat, auto moduleInfo = ModuleInfoLib::createModuleInfo (*module, false); if (compat) moduleInfo.compatibility = *compat; - else if (auto loaded = loadCompatibilityFromModule (*module)) - moduleInfo.compatibility = *loaded; - moduleInfo.version = moduleVersion; std::stringstream output; @@ -358,7 +324,7 @@ int run (int argc, char* argv[]) auto outputFile = valueMap[optOutputPath]; #endif auto ostream = new std::ofstream (outputFile); - + if (ostream->is_open ()) outputStream = ostream; else @@ -388,10 +354,6 @@ int run (int argc, char* argv[]) //------------------------------------------------------------------------ #if SMTG_OS_WINDOWS -//------------------------------------------------------------------------ -#include -#include - //------------------------------------------------------------------------ using Utf8String = std::string; @@ -402,7 +364,7 @@ Utf8Args toUtf8Args (int argc, wchar_t* wargv[]) Utf8Args utf8Args; for (int i = 0; i < argc; i++) { - auto str = reinterpret_cast(wargv[i]); + auto str = reinterpret_cast (wargv[i]); utf8Args.push_back (VST3::StringConvert::convert (str)); } @@ -431,9 +393,14 @@ int wmain (int argc, wchar_t* wargv[]) char** argv = &(utf8ArgPtrs.at (0)); return Steinberg::ModuleInfoTool::run (argc, argv); } + #else + +//------------------------------------------------------------------------ int main (int argc, char* argv[]) { return Steinberg::ModuleInfoTool::run (argc, argv); } -#endif + +//------------------------------------------------------------------------ +#endif // SMTG_OS_WINDOWS diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/memorystream.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/memorystream.cpp index 5b6c245e000e..91bd01478b87 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/memorystream.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/memorystream.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/memorystream.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/memorystream.h index 489ace5fff65..b942f0b1962a 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/memorystream.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/memorystream.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/pluginview.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/pluginview.cpp index 0b42b5eefb61..24c18869ff3b 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/pluginview.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/pluginview.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -51,7 +51,6 @@ CPluginView::CPluginView (const ViewRect* _rect) //------------------------------------------------------------------------ CPluginView::~CPluginView () { - // NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.VirtualCall) setFrame (nullptr); } diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/pluginview.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/pluginview.h index ce131b94cb60..6799fb594e01 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/pluginview.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/pluginview.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -112,4 +112,5 @@ class CPluginView : public FObject, public IPlugView IPtr plugFrame; }; -} // namespace +//------------------------------------------------------------------------ +} // namespace Steinberg diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/readfile.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/readfile.cpp index 5f6045770ad5..f1f0216ed4d7 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/readfile.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/readfile.cpp @@ -36,8 +36,13 @@ //----------------------------------------------------------------------------- #include "readfile.h" -#include "public.sdk/source/vst/utility/stringconvert.h" + #include "pluginterfaces/base/fplatform.h" + +#if SMTG_OS_WINDOWS +#include "public.sdk/source/vst/utility/stringconvert.h" +#endif + #include #include diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/readfile.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/readfile.h index fdc7105eac04..8fe2ab925e75 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/readfile.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/common/readfile.h @@ -51,5 +51,4 @@ Returns entire file content at the given path std::string readFile (const std::string& path); //------------------------------------------------------------------------ - } // namespace Steinberg diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/hostclasses.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/hostclasses.cpp index e04987e16e04..266c08c3b3f9 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/hostclasses.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/hostclasses.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/hostclasses.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/hostclasses.h index 4a254cac1649..bd51f30c2657 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/hostclasses.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/hostclasses.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module.cpp index 9ce5b575222c..88d910f6fffb 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module.h index 36b3afad2e7c..adeb1c287683 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_linux.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_linux.cpp index 404054c82851..96b87979ac74 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_linux.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_linux.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_mac.mm b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_mac.mm index 49a7155543a8..853290672841 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_mac.mm +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_mac.mm @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -180,7 +180,12 @@ bool load (const std::string& path, std::string& errorDescription) override { std::string wd (workDir); wd += "/"; - return loadInternal (wd + path, errorDescription); + if (loadInternal (wd + path, errorDescription)) + { + name = path; + return true; + } + return false; } } return loadInternal (path, errorDescription); diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_win32.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_win32.cpp index 77990fdcca3b..ae1d03a7da9a 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_win32.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/module_win32.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/pluginterfacesupport.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/pluginterfacesupport.cpp index adabdb902801..3e9f8f85ab7d 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/pluginterfacesupport.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/pluginterfacesupport.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/pluginterfacesupport.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/pluginterfacesupport.h index a88cbf6815ab..ef769bb21b58 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/pluginterfacesupport.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/hosting/pluginterfacesupport.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/jsoncxx.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/jsoncxx.h index 979c2f8527e4..79687789a948 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/jsoncxx.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/jsoncxx.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfo.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfo.h index 81b93f74beb1..1a0001a39d1e 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfo.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfo.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfocreator.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfocreator.cpp index 8f12829c7d9d..cd554e411e30 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfocreator.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfocreator.cpp @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfocreator.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfocreator.h index f28716ae2a31..2fad32fa1827 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfocreator.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfocreator.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfoparser.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfoparser.cpp index 0d09d2bb0c1d..eb738822a541 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfoparser.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfoparser.cpp @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfoparser.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfoparser.h index 9b426da3c94e..54d5705e254c 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfoparser.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/moduleinfo/moduleinfoparser.h @@ -9,7 +9,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/optional.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/optional.h index 7ea6a3c37328..1f2244a61e9f 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/optional.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/optional.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -92,7 +92,7 @@ struct Optional T&& value () noexcept { checkValid (); - return move (_value); + return std::move (_value); } const T& value () const noexcept diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/stringconvert.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/stringconvert.cpp index 6bc7f3aa7c85..75cf08c0a7dc 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/stringconvert.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/stringconvert.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/stringconvert.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/stringconvert.h index d2d4678a742a..b3bc1ac65afe 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/stringconvert.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/stringconvert.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -130,7 +130,7 @@ inline const Steinberg::Vst::TChar* toTChar (const std::u16string& str) //------------------------------------------------------------------------ /** - * convert an number to an UTF-16 string + * convert a number to an UTF-16 string * * @param value number * diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/uid.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/uid.h index 2f8ed8b33592..56674afa2913 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/uid.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/utility/uid.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -172,10 +172,7 @@ inline UID& UID::operator= (const UID& uid) noexcept //------------------------------------------------------------------------ inline UID& UID::operator= (const TUID& uid) noexcept { - uint64_t* p1 = reinterpret_cast (_data); - const uint64_t* p2 = reinterpret_cast (uid); - p1[0] = p2[0]; - p1[1] = p2[1]; + memcpy (_data, reinterpret_cast(uid), 16); return *this; } @@ -281,12 +278,7 @@ inline Optional UID::fromString (const StringT& str, bool comFormat) noexce inline UID UID::fromTUID (const TUID _uid) noexcept { UID result; - - uint64_t* p1 = reinterpret_cast (result._data); - const uint64_t* p2 = reinterpret_cast (_uid); - p1[0] = p2[0]; - p1[1] = p2[1]; - + memcpy (result._data, reinterpret_cast(_uid), 16); return result; } diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstbus.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstbus.cpp index 8f6ff44fc82f..70722fa8d527 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstbus.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstbus.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstbus.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstbus.h index f1e7ad4b06be..4820e7701f70 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstbus.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstbus.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponent.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponent.cpp index 57e03d081508..6e999b2e2388 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponent.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponent.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponent.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponent.h index a1009d48716f..e5942690fa97 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponent.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponent.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponentbase.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponentbase.cpp index c82ac39cde15..d2e5ffb1d9a1 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponentbase.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponentbase.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponentbase.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponentbase.h index e71b857be923..4b149bd0f2bb 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponentbase.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstcomponentbase.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vsteditcontroller.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vsteditcontroller.cpp index 4342c7b21c75..be32db509d23 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vsteditcontroller.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vsteditcontroller.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vsteditcontroller.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vsteditcontroller.h index 9fcb0e692206..446914b7d915 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vsteditcontroller.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vsteditcontroller.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstinitiids.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstinitiids.cpp index c5ad8b08fd93..d61803776f1a 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstinitiids.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstinitiids.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -41,6 +41,7 @@ #include "pluginterfaces/vst/ivstautomationstate.h" #include "pluginterfaces/vst/ivstchannelcontextinfo.h" #include "pluginterfaces/vst/ivstcontextmenu.h" +#include "pluginterfaces/vst/ivstdataexchange.h" #include "pluginterfaces/vst/ivsteditcontroller.h" #include "pluginterfaces/vst/ivstevents.h" #include "pluginterfaces/vst/ivsthostapplication.h" @@ -53,6 +54,7 @@ #include "pluginterfaces/vst/ivstpluginterfacesupport.h" #include "pluginterfaces/vst/ivstplugview.h" #include "pluginterfaces/vst/ivstprefetchablesupport.h" +#include "pluginterfaces/vst/ivstremapparamid.h" #include "pluginterfaces/vst/ivstrepresentation.h" #include "pluginterfaces/vst/ivsttestplugprovider.h" #include "pluginterfaces/vst/ivstunits.h" @@ -138,8 +140,15 @@ DEF_CLASS_IID (Vst::IProcessContextRequirements) DEF_CLASS_IID (Vst::IProgress) DEF_CLASS_IID (Vst::ITestPlugProvider2) - //----VST 3.7.5--------------------------------- DEF_CLASS_IID (IPluginCompatibility) +//----VST 3.7.9--------------------------------- +DEF_CLASS_IID (Vst::IComponentHandlerSystemTime) +DEF_CLASS_IID (Vst::IDataExchangeHandler) +DEF_CLASS_IID (Vst::IDataExchangeReceiver) + +//----VST 3.7.11--------------------------------- +DEF_CLASS_IID (Vst::IRemapParamID) + } // Steinberg diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstparameters.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstparameters.cpp index dd0835167dfd..213a73e8b687 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstparameters.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstparameters.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -228,6 +228,8 @@ ParamValue RangeParameter::toNormalized (ParamValue plainValue) const { if (info.stepCount > 1) return ToNormalized (plainValue - getMin (), info.stepCount); + + SMTG_ASSERT (getMax () - getMin () != 0); return (plainValue - getMin ()) / (getMax () - getMin ()); } diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstparameters.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstparameters.h index 88742e20ce46..42d3e92f4243 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstparameters.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstparameters.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: @@ -98,7 +98,7 @@ class Parameter : public FObject OBJ_METHODS (Parameter, FObject) //------------------------------------------------------------------------ protected: - ParameterInfo info {0}; + ParameterInfo info {}; ParamValue valueNormalized {0.}; int32 precision {4}; }; diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstpresetfile.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstpresetfile.cpp index 3a47c175c10e..4d1fb35c12a2 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstpresetfile.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstpresetfile.cpp @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstpresetfile.h b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstpresetfile.h index 2a9f83fce58c..47d23f1e9602 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstpresetfile.h +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/source/vst/vstpresetfile.h @@ -8,7 +8,7 @@ // //----------------------------------------------------------------------------- // LICENSE -// (c) 2023, Steinberg Media Technologies GmbH, All Rights Reserved +// (c) 2024, Steinberg Media Technologies GmbH, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: From ca37d6b29c705549ba475f505806975d33e522bd Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 30 May 2024 11:54:07 +0100 Subject: [PATCH 12/19] VST3 Client: Update moduleinfotool to write compatibility info from plugin Reintegrates changes from 06a2089872905242ead2fc0d4c31cf5c0cea8cc5 --- .../moduleinfotool/source/main.cpp | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/samples/vst-utilities/moduleinfotool/source/main.cpp b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/samples/vst-utilities/moduleinfotool/source/main.cpp index fccecf518dc0..b18b92fcd597 100644 --- a/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/samples/vst-utilities/moduleinfotool/source/main.cpp +++ b/modules/juce_audio_processors/format_types/VST3_SDK/public.sdk/samples/vst-utilities/moduleinfotool/source/main.cpp @@ -35,6 +35,9 @@ // OF THE POSSIBILITY OF SUCH DAMAGE. //----------------------------------------------------------------------------- +#include "pluginterfaces/base/iplugincompatibility.h" +#include "public.sdk/source/common/memorystream.h" + #include "public.sdk/source/common/readfile.h" #include "public.sdk/source/vst/hosting/module.h" #include "public.sdk/source/vst/moduleinfo/moduleinfocreator.h" @@ -96,6 +99,35 @@ std::optional openAndParseCompatJSON (const std:: return result; } +//------------------------------------------------------------------------ +std::optional loadCompatibilityFromModule (const VST3::Hosting::Module& module) +{ + const auto& factory = module.getFactory(); + const auto& infos = factory.classInfos(); + + const auto iter = std::find_if (infos.begin(), infos.end(), [&] (const auto& info) + { + return info.category() == kPluginCompatibilityClass; + }); + + if (iter == infos.end()) + return {}; + + const auto compatibility = factory.createInstance (iter->ID()); + + if (compatibility == nullptr) + return {}; + + Steinberg::MemoryStream stream; + + if (compatibility->getCompatibilityJSON (&stream) != kResultOk) + return {}; + + const std::string_view streamView (stream.getData(), stream.getSize()); + + return ModuleInfoLib::parseCompatibilityJson (streamView, nullptr); +} + //------------------------------------------------------------------------ int createJSON (const std::optional& compat, const std::string& modulePath, const std::string& moduleVersion, @@ -111,6 +143,9 @@ int createJSON (const std::optional& compat, auto moduleInfo = ModuleInfoLib::createModuleInfo (*module, false); if (compat) moduleInfo.compatibility = *compat; + else if (auto loaded = loadCompatibilityFromModule (*module)) + moduleInfo.compatibility = *loaded; + moduleInfo.version = moduleVersion; std::stringstream output; From c0e0f561d386f1edf6cb3588f64dccd62cc0e635 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 30 May 2024 12:01:23 +0100 Subject: [PATCH 13/19] Resave all projects --- examples/DemoRunner/Builds/Android/app/CMakeLists.txt | 4 ++++ .../Builds/VisualStudio2017/DemoRunner_App.vcxproj | 2 ++ .../Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters | 6 ++++++ .../Builds/VisualStudio2019/DemoRunner_App.vcxproj | 2 ++ .../Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters | 6 ++++++ .../Builds/VisualStudio2022/DemoRunner_App.vcxproj | 2 ++ .../Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters | 6 ++++++ .../AudioPerformanceTest/Builds/Android/app/CMakeLists.txt | 4 ++++ .../VisualStudio2022/AudioPerformanceTest_App.vcxproj | 2 ++ .../AudioPerformanceTest_App.vcxproj.filters | 6 ++++++ extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt | 4 ++++ .../Builds/VisualStudio2017/AudioPluginHost_App.vcxproj | 2 ++ .../VisualStudio2017/AudioPluginHost_App.vcxproj.filters | 6 ++++++ .../Builds/VisualStudio2019/AudioPluginHost_App.vcxproj | 2 ++ .../VisualStudio2019/AudioPluginHost_App.vcxproj.filters | 6 ++++++ .../Builds/VisualStudio2022/AudioPluginHost_App.vcxproj | 2 ++ .../VisualStudio2022/AudioPluginHost_App.vcxproj.filters | 6 ++++++ .../NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt | 4 ++++ .../Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj | 2 ++ .../NetworkGraphicsDemo_App.vcxproj.filters | 6 ++++++ .../VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj | 2 ++ .../UnitTestRunner_ConsoleApp.vcxproj.filters | 6 ++++++ .../VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj | 2 ++ .../UnitTestRunner_ConsoleApp.vcxproj.filters | 6 ++++++ .../VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj | 2 ++ .../UnitTestRunner_ConsoleApp.vcxproj.filters | 6 ++++++ .../VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj | 2 ++ .../WindowsDLL_StaticLibrary.vcxproj.filters | 6 ++++++ 28 files changed, 112 insertions(+) diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt index 6ea49f7d1afe..f9ae9a893052 100644 --- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt +++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt @@ -677,6 +677,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstchannelcontextinfo.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcomponent.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcontextmenu.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstevents.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsthostapplication.h" @@ -692,6 +693,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstplugview.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprefetchablesupport.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprocesscontext.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstrepresentation.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsttestplugprovider.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstunits.h" @@ -2773,6 +2775,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstchannelcontextinfo.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcomponent.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcontextmenu.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstevents.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsthostapplication.h" @@ -2788,6 +2791,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstplugview.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprefetchablesupport.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprocesscontext.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstrepresentation.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsttestplugprovider.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstunits.h" diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj index c6e3c0da8aef..fc4b8b45d4b5 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj @@ -3188,6 +3188,7 @@ + @@ -3203,6 +3204,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters index b652c98be60c..36fdef23e121 100644 --- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters @@ -4698,6 +4698,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4743,6 +4746,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj index dd9a4596a1fc..b60416ae4af4 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj @@ -3188,6 +3188,7 @@ + @@ -3203,6 +3204,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters index 2ebfa97940f0..cfd8befb7695 100644 --- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters @@ -4698,6 +4698,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4743,6 +4746,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj index a726d9fb4571..7ad7735303d3 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj @@ -3188,6 +3188,7 @@ + @@ -3203,6 +3204,7 @@ + diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters index aed569e0e88e..33356ed6e577 100644 --- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters +++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters @@ -4698,6 +4698,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4743,6 +4746,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt index 38f54badc60b..6c26ff5b069a 100644 --- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt @@ -649,6 +649,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstchannelcontextinfo.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcomponent.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcontextmenu.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstevents.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsthostapplication.h" @@ -664,6 +665,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstplugview.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprefetchablesupport.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprocesscontext.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstrepresentation.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsttestplugprovider.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstunits.h" @@ -2445,6 +2447,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstchannelcontextinfo.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcomponent.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcontextmenu.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstevents.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsthostapplication.h" @@ -2460,6 +2463,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstplugview.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprefetchablesupport.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprocesscontext.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstrepresentation.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsttestplugprovider.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstunits.h" diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj index 0fb47dd73f80..7a9a8f064a68 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj @@ -2792,6 +2792,7 @@ + @@ -2807,6 +2808,7 @@ + diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters index 7189235092de..4981f9de414a 100644 --- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters +++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters @@ -4122,6 +4122,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4167,6 +4170,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt index 04a18ca1e289..9daac09ccb14 100644 --- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt +++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt @@ -682,6 +682,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstchannelcontextinfo.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcomponent.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcontextmenu.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstevents.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsthostapplication.h" @@ -697,6 +698,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstplugview.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprefetchablesupport.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprocesscontext.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstrepresentation.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsttestplugprovider.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstunits.h" @@ -2631,6 +2633,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstchannelcontextinfo.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcomponent.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcontextmenu.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstevents.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsthostapplication.h" @@ -2646,6 +2649,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstplugview.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprefetchablesupport.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprocesscontext.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstrepresentation.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsttestplugprovider.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstunits.h" diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj index e2e345500315..4308cf3ff61b 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj @@ -2972,6 +2972,7 @@ + @@ -2987,6 +2988,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters index 8ed1c7a7ad5c..da7e15ba9a9d 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters @@ -4398,6 +4398,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4443,6 +4446,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj index 237e6cd69833..907df38d4a85 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj @@ -2972,6 +2972,7 @@ + @@ -2987,6 +2988,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters index 85b5efc6471a..1e7059b59aa1 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters @@ -4398,6 +4398,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4443,6 +4446,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj index bcd461838ab4..bafc862c212f 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj @@ -2972,6 +2972,7 @@ + @@ -2987,6 +2988,7 @@ + diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters index ef1344ea23f3..a413e8a4c7ea 100644 --- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters +++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters @@ -4398,6 +4398,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4443,6 +4446,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt index 544d1f4f5d7f..7bb80dbe4655 100644 --- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt +++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt @@ -653,6 +653,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstchannelcontextinfo.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcomponent.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcontextmenu.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstevents.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsthostapplication.h" @@ -668,6 +669,7 @@ add_library( ${BINARY_NAME} "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstplugview.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprefetchablesupport.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprocesscontext.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstrepresentation.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsttestplugprovider.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstunits.h" @@ -2529,6 +2531,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstchannelcontextinfo.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcomponent.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstcontextmenu.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstdataexchange.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsteditcontroller.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstevents.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsthostapplication.h" @@ -2544,6 +2547,7 @@ set_source_files_properties( "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstplugview.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprefetchablesupport.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstprocesscontext.h" + "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstremapparamid.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstrepresentation.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivsttestplugprovider.h" "../../../../../modules/juce_audio_processors/format_types/VST3_SDK/pluginterfaces/vst/ivstunits.h" diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj index 6129d1f87810..67461904a536 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj @@ -2883,6 +2883,7 @@ + @@ -2898,6 +2899,7 @@ + diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters index 100c39898ab9..841f9e00b33e 100644 --- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters +++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters @@ -4263,6 +4263,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4308,6 +4311,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj index 8d7ae8809ac6..d5629f7e6102 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj @@ -3068,6 +3068,7 @@ + @@ -3083,6 +3084,7 @@ + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters index f8f71aef89f7..563b6878e877 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -4512,6 +4512,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4557,6 +4560,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj index 6c326f929055..e4143833ba0a 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj @@ -3068,6 +3068,7 @@ + @@ -3083,6 +3084,7 @@ + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters index f1766a3e5e13..6f28426612c5 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -4512,6 +4512,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4557,6 +4560,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj index f7eacf08a178..5202cb956930 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj @@ -3068,6 +3068,7 @@ + @@ -3083,6 +3084,7 @@ + diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters index 759ab7224369..0714cd10f8b7 100644 --- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters +++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters @@ -4512,6 +4512,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4557,6 +4560,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj index c0b4ba345377..1eb2039cd790 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj @@ -2859,6 +2859,7 @@ + @@ -2874,6 +2875,7 @@ + diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters index 0a7fc35d2f08..25b9167c2b13 100644 --- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters +++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters @@ -4230,6 +4230,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst @@ -4275,6 +4278,9 @@ JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst + JUCE Modules\juce_audio_processors\format_types\VST3_SDK\pluginterfaces\vst From 3f98bb12c73ee6a0c2726d81cd3bab7c7c1e3719 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 30 May 2024 13:59:23 +0100 Subject: [PATCH 14/19] AudioChannelSet: Add new ITU variants of 9.0.4, 9.1.4, 9.0.6, and 9.1.6 --- .../buffers/juce_AudioChannelSet.cpp | 19 +++++++++++++----- .../buffers/juce_AudioChannelSet.h | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp index 2507ea98ca21..60dac32c4d4b 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp +++ b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp @@ -438,10 +438,14 @@ String AudioChannelSet::getDescription() const if (*this == create7point1point2()) return "7.1.2 Surround"; if (*this == create7point1point4()) return "7.1.4 Surround"; if (*this == create7point1point6()) return "7.1.6 Surround"; - if (*this == create9point0point4()) return "9.0.4 Surround"; - if (*this == create9point1point4()) return "9.1.4 Surround"; - if (*this == create9point0point6()) return "9.0.6 Surround"; - if (*this == create9point1point6()) return "9.1.6 Surround"; + if (*this == create9point0point4()) return "9.0.4 Surround (Atmos)"; + if (*this == create9point1point4()) return "9.1.4 Surround (Atmos)"; + if (*this == create9point0point6()) return "9.0.6 Surround (Atmos)"; + if (*this == create9point1point6()) return "9.1.6 Surround (Atmos)"; + if (*this == create9point0point4ITU()) return "9.0.4 Surround (ITU)"; + if (*this == create9point1point4ITU()) return "9.1.4 Surround (ITU)"; + if (*this == create9point0point6ITU()) return "9.0.6 Surround (ITU)"; + if (*this == create9point1point6ITU()) return "9.1.6 Surround (ITU)"; if (*this == quadraphonic()) return "Quadraphonic"; if (*this == pentagonal()) return "Pentagonal"; @@ -568,6 +572,10 @@ AudioChannelSet AudioChannelSet::create9point0point4() { return AudioChannelSet AudioChannelSet AudioChannelSet::create9point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } AudioChannelSet AudioChannelSet::create9point0point6() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } AudioChannelSet AudioChannelSet::create9point1point6() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create9point0point4ITU() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create9point1point4ITU() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create9point0point6ITU() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topFrontRight, topRearLeft, topRearRight, topSideLeft, topSideRight }); } +AudioChannelSet AudioChannelSet::create9point1point6ITU() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topFrontRight, topRearLeft, topRearRight, topSideLeft, topSideRight }); } AudioChannelSet AudioChannelSet::ambisonic (int order) { @@ -693,7 +701,8 @@ Array AudioChannelSet::channelSetsWithNumberOfChannels (int num case 14: return { AudioChannelSet::create7point1point6() }; case 16: - return { AudioChannelSet::create9point1point6() }; + return { AudioChannelSet::create9point1point6(), + AudioChannelSet::create9point1point6ITU() }; } return {}; diff --git a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h index 989669ddccd2..b1afbf35d3bc 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h +++ b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h @@ -286,6 +286,26 @@ class JUCE_API AudioChannelSet */ static AudioChannelSet JUCE_CALLTYPE create9point1point6(); + /** Creates a set for a 9.0.4 ITU surround setup: + left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topFrontRight, topRearLeft, topRearRight + */ + static AudioChannelSet JUCE_CALLTYPE create9point0point4ITU(); + + /** Creates a set for a 9.1.4 ITU surround setup. + left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topFrontRight, topRearLeft, topRearRight + */ + static AudioChannelSet JUCE_CALLTYPE create9point1point4ITU(); + + /** Creates a set for a 9.0.6 ITU surround setup. + left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topRearRight, topFrontRight, topRearRight, topSideLeft, topSideRight + */ + static AudioChannelSet JUCE_CALLTYPE create9point0point6ITU(); + + /** Creates a set for a 9.1.6 ITU surround setup. + left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topRearRight, topFrontRight, topRearRight, topSideLeft, topSideRight + */ + static AudioChannelSet JUCE_CALLTYPE create9point1point6ITU(); + //============================================================================== /** Creates a set for quadraphonic surround setup (left, right, leftSurround, rightSurround) From 966b69abf991937ae12556f7fc43b7aaef1103c7 Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 30 May 2024 14:26:28 +0100 Subject: [PATCH 15/19] AudioChannelSet: Fix formatting --- .../buffers/juce_AudioChannelSet.cpp | 142 +++++++++--------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp index 60dac32c4d4b..cfcf9a11c9ba 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp +++ b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.cpp @@ -409,48 +409,48 @@ AudioChannelSet AudioChannelSet::fromAbbreviatedString (const String& str) String AudioChannelSet::getDescription() const { - if (isDiscreteLayout()) return "Discrete #" + String (size()); - if (*this == disabled()) return "Disabled"; - if (*this == mono()) return "Mono"; - if (*this == stereo()) return "Stereo"; - - if (*this == createLCR()) return "LCR"; - if (*this == createLRS()) return "LRS"; - if (*this == createLCRS()) return "LCRS"; - - if (*this == create5point0()) return "5.0 Surround"; - if (*this == create5point0point2()) return "5.0.2 Surround"; - if (*this == create5point0point4()) return "5.0.4 Surround"; - if (*this == create5point1()) return "5.1 Surround"; - if (*this == create5point1point2()) return "5.1.2 Surround"; - if (*this == create5point1point4()) return "5.1.4 Surround"; - if (*this == create6point0()) return "6.0 Surround"; - if (*this == create6point1()) return "6.1 Surround"; - if (*this == create6point0Music()) return "6.0 (Music) Surround"; - if (*this == create6point1Music()) return "6.1 (Music) Surround"; - if (*this == create7point0()) return "7.0 Surround"; - if (*this == create7point1()) return "7.1 Surround"; - if (*this == create7point0SDDS()) return "7.0 Surround SDDS"; - if (*this == create7point1SDDS()) return "7.1 Surround SDDS"; - if (*this == create7point0point2()) return "7.0.2 Surround"; - if (*this == create7point0point4()) return "7.0.4 Surround"; - if (*this == create7point0point6()) return "7.0.6 Surround"; - if (*this == create7point1point2()) return "7.1.2 Surround"; - if (*this == create7point1point4()) return "7.1.4 Surround"; - if (*this == create7point1point6()) return "7.1.6 Surround"; - if (*this == create9point0point4()) return "9.0.4 Surround (Atmos)"; - if (*this == create9point1point4()) return "9.1.4 Surround (Atmos)"; - if (*this == create9point0point6()) return "9.0.6 Surround (Atmos)"; - if (*this == create9point1point6()) return "9.1.6 Surround (Atmos)"; + if (isDiscreteLayout()) return "Discrete #" + String (size()); + if (*this == disabled()) return "Disabled"; + if (*this == mono()) return "Mono"; + if (*this == stereo()) return "Stereo"; + + if (*this == createLCR()) return "LCR"; + if (*this == createLRS()) return "LRS"; + if (*this == createLCRS()) return "LCRS"; + + if (*this == create5point0()) return "5.0 Surround"; + if (*this == create5point0point2()) return "5.0.2 Surround"; + if (*this == create5point0point4()) return "5.0.4 Surround"; + if (*this == create5point1()) return "5.1 Surround"; + if (*this == create5point1point2()) return "5.1.2 Surround"; + if (*this == create5point1point4()) return "5.1.4 Surround"; + if (*this == create6point0()) return "6.0 Surround"; + if (*this == create6point1()) return "6.1 Surround"; + if (*this == create6point0Music()) return "6.0 (Music) Surround"; + if (*this == create6point1Music()) return "6.1 (Music) Surround"; + if (*this == create7point0()) return "7.0 Surround"; + if (*this == create7point1()) return "7.1 Surround"; + if (*this == create7point0SDDS()) return "7.0 Surround SDDS"; + if (*this == create7point1SDDS()) return "7.1 Surround SDDS"; + if (*this == create7point0point2()) return "7.0.2 Surround"; + if (*this == create7point0point4()) return "7.0.4 Surround"; + if (*this == create7point0point6()) return "7.0.6 Surround"; + if (*this == create7point1point2()) return "7.1.2 Surround"; + if (*this == create7point1point4()) return "7.1.4 Surround"; + if (*this == create7point1point6()) return "7.1.6 Surround"; + if (*this == create9point0point4()) return "9.0.4 Surround (Atmos)"; + if (*this == create9point1point4()) return "9.1.4 Surround (Atmos)"; + if (*this == create9point0point6()) return "9.0.6 Surround (Atmos)"; + if (*this == create9point1point6()) return "9.1.6 Surround (Atmos)"; if (*this == create9point0point4ITU()) return "9.0.4 Surround (ITU)"; if (*this == create9point1point4ITU()) return "9.1.4 Surround (ITU)"; if (*this == create9point0point6ITU()) return "9.0.6 Surround (ITU)"; if (*this == create9point1point6ITU()) return "9.1.6 Surround (ITU)"; - if (*this == quadraphonic()) return "Quadraphonic"; - if (*this == pentagonal()) return "Pentagonal"; - if (*this == hexagonal()) return "Hexagonal"; - if (*this == octagonal()) return "Octagonal"; + if (*this == quadraphonic()) return "Quadraphonic"; + if (*this == pentagonal()) return "Pentagonal"; + if (*this == hexagonal()) return "Hexagonal"; + if (*this == octagonal()) return "Octagonal"; // ambisonics { @@ -538,40 +538,40 @@ void AudioChannelSet::removeChannel (ChannelType newChannel) channels.clearBit (bit); } -AudioChannelSet AudioChannelSet::disabled() { return {}; } -AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet ({ centre }); } -AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ({ left, right }); } -AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ({ left, right, centre }); } -AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ({ left, right, surround }); } -AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ({ left, right, centre, surround }); } -AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround }); } -AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround }); } -AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, centreSurround }); } -AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, centreSurround }); } -AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ({ left, right, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide }); } -AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ({ left, right, LFE, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide }); } -AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear }); } -AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre }); } -AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear }); } -AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre }); } -AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ({ left, right, leftSurround, rightSurround }); } -AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ({ left, right, centre, leftSurroundRear, rightSurroundRear }); } -AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ({ left, right, centre, centreSurround, leftSurroundRear, rightSurroundRear }); } -AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, centreSurround, wideLeft, wideRight }); } -AudioChannelSet AudioChannelSet::create5point0point2() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, topSideLeft, topSideRight }); } -AudioChannelSet AudioChannelSet::create5point1point2() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, topSideLeft, topSideRight }); } -AudioChannelSet AudioChannelSet::create5point0point4() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } -AudioChannelSet AudioChannelSet::create5point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } -AudioChannelSet AudioChannelSet::create7point0point2() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight }); } -AudioChannelSet AudioChannelSet::create7point1point2() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight }); } -AudioChannelSet AudioChannelSet::create7point0point4() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } -AudioChannelSet AudioChannelSet::create7point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } -AudioChannelSet AudioChannelSet::create7point0point6() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } -AudioChannelSet AudioChannelSet::create7point1point6() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } -AudioChannelSet AudioChannelSet::create9point0point4() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } -AudioChannelSet AudioChannelSet::create9point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } -AudioChannelSet AudioChannelSet::create9point0point6() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } -AudioChannelSet AudioChannelSet::create9point1point6() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::disabled() { return {}; } +AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet ({ centre }); } +AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ({ left, right }); } +AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ({ left, right, centre }); } +AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ({ left, right, surround }); } +AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ({ left, right, centre, surround }); } +AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround }); } +AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround }); } +AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, centreSurround }); } +AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, centreSurround }); } +AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ({ left, right, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide }); } +AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ({ left, right, LFE, leftSurround, rightSurround, leftSurroundSide, rightSurroundSide }); } +AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear }); } +AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre }); } +AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear }); } +AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre }); } +AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ({ left, right, leftSurround, rightSurround }); } +AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ({ left, right, centre, leftSurroundRear, rightSurroundRear }); } +AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ({ left, right, centre, centreSurround, leftSurroundRear, rightSurroundRear }); } +AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, centreSurround, wideLeft, wideRight }); } +AudioChannelSet AudioChannelSet::create5point0point2() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, topSideLeft, topSideRight }); } +AudioChannelSet AudioChannelSet::create5point1point2() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, topSideLeft, topSideRight }); } +AudioChannelSet AudioChannelSet::create5point0point4() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create5point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create7point0point2() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight }); } +AudioChannelSet AudioChannelSet::create7point1point2() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight }); } +AudioChannelSet AudioChannelSet::create7point0point4() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create7point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create7point0point6() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create7point1point6() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create9point0point4() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create9point1point4() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create9point0point6() { return AudioChannelSet ({ left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } +AudioChannelSet AudioChannelSet::create9point1point6() { return AudioChannelSet ({ left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight }); } AudioChannelSet AudioChannelSet::create9point0point4ITU() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } AudioChannelSet AudioChannelSet::create9point1point4ITU() { return AudioChannelSet ({ left, right, centre, LFE, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topFrontRight, topRearLeft, topRearRight }); } AudioChannelSet AudioChannelSet::create9point0point6ITU() { return AudioChannelSet ({ left, right, centre, leftSurround, rightSurround, leftCentre, rightCentre, leftSurroundSide, rightSurroundSide, topFrontLeft, topFrontRight, topRearLeft, topRearRight, topSideLeft, topSideRight }); } From b66079361cad27d14ee8cc32c97c4c58882f757a Mon Sep 17 00:00:00 2001 From: reuk Date: Thu, 30 May 2024 13:57:42 +0100 Subject: [PATCH 16/19] VST3: Add support for new wide/Atmos speaker layouts --- BREAKING_CHANGES.md | 42 +++++++++ .../buffers/juce_AudioChannelSet.h | 44 +++++++--- .../format_types/juce_VST3Common.h | 20 +++-- .../juce_VST3PluginFormat_test.cpp | 86 ++++++++++++++++--- 4 files changed, 158 insertions(+), 34 deletions(-) diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index c2304b75f986..d0fc542420a3 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -1,5 +1,47 @@ # JUCE breaking changes +# Version 7.0.12 + +## Change + +The function AudioChannelSet::create9point0point4, along with variants for +9.1.4, 9.0.6, and 9.1.6, used to correspond to VST3 layouts k90_4, k91_4, +k90_6, and k91_6 respectively. These functions now correspond to k90_4_W, +k91_4_W, k90_6_W, and k91_6_W respectively. + +**Possible Issues** + +VST3 plugins that used these AudioChannelSet layouts to specify initial bus +layouts, or to validate layouts in isBusesLayoutSupported, will now behave +differently. + +For example, if the host wants to check whether the k90_4 layout is supported, +previously isBusesLayoutSupported() would have received the layout created by +create9point0point4(), but will now receive the layout created by +create9point0point4ITU(). + +**Workaround** + +If you already have special-case handling for specific surround layouts, +e.g. to enable or disable them in isBusesLayoutSupported(), you may need to +add cases to handle the new AudioChannelSet::create*ITU() layout variants. + +**Rationale** + +Previously, the VST3 SDK only contained ITU higher-order surround layouts, but +the higher-order layouts specified in JUCE used Atmos speaker positions rather +than ITU speaker positions. This meant that JUCE had to remap speaker layouts +between Atmos/ITU formats when communicating with VST3 plugins. This was +confusing, as it required that the meaning of some channels was changed during +the conversion. + +In newer versions of the VST3 SDK, new "wide" left and right speaker +definitions are available, allowing both ITU and Atmos surround layouts to be +represented. The change in JUCE surfaces this distinction to the user, allowing +them to determine e.g. whether the host has requested an ITU or an Atmos +layout, and to handle these cases separately if necessary. + + # Version 7.0.10 ## Change diff --git a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h index b1afbf35d3bc..8eecea6e464e 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h +++ b/modules/juce_audio_basics/buffers/juce_AudioChannelSet.h @@ -256,33 +256,51 @@ class JUCE_API AudioChannelSet */ static AudioChannelSet JUCE_CALLTYPE create7point1point6(); - /** Creates a set for a 9.0.4 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight). + /** Creates a set for a 9.0.4 Atmos surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight). - Is equivalent to: k90_4 (VST3), AAX_eStemFormat_9_0_4 (AAX). + Is equivalent to: k90_4_W (VST3), AAX_eStemFormat_9_0_4 (AAX). + + @see create9point0point4ITU() */ static AudioChannelSet JUCE_CALLTYPE create9point0point4(); - /** Creates a set for a 9.1.4 surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight). + /** Creates a set for a 9.1.4 Atmos surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topRearLeft, topRearRight). + + Is equivalent to: k91_4_W (VST3), AAX_eStemFormat_9_1_4 (AAX). - Is equivalent to: k91_4 (VST3), AAX_eStemFormat_9_1_4 (AAX). + @see create9point1point4ITU() */ static AudioChannelSet JUCE_CALLTYPE create9point1point4(); - /** Creates a set for a 9.0.6 surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight). + /** Creates a set for a 9.0.6 Atmos surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight). - Is equivalent to: k90_6 (VST3), AAX_eStemFormat_9_0_6 (AAX). + Is equivalent to: k90_6_W (VST3), AAX_eStemFormat_9_0_6 (AAX). + + @see create9point0point6ITU() */ static AudioChannelSet JUCE_CALLTYPE create9point0point6(); - /** Creates a set for a 9.1.6 surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight). + /** Creates a set for a 9.1.6 Atmos surround setup (left, right, centre, LFE, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, wideLeft, wideRight, topFrontLeft, topFrontRight, topSideLeft, topSideRight, topRearLeft, topRearRight). + + Older versions of the VST3 SDK only supported ITU versions of the 9.0.4, 9.1.4, 9.0.6, and + 9.1.6 layouts, which have the front-channel ordering "L Lc C Rc R". + To maintain the correct relative channel ordering, JUCE would perform the following mapping: + L -> wideLeft, Lc -> left, Rc -> right, R -> wideRight + + The version of the VST3 SDK bundled with JUCE now supports Atmos versions of the above + layouts, which have the front-channel ordering "Lw L C R Rw". This order matches the + JUCE ordering, so no remapping is required. + + create9point0point4(), create9point1point4(), create9point0point6(), and + create9point1point6() now correspond to the VST3 k90_4_W, k91_4_W, k90_6_W, and k91_6_W + Atmos layouts respectively. + + If you need to support the old ITU layouts, use create9point0point4ITU(), + create9point1point4ITU(), create9point0point6ITU(), and create9point1point6ITU() instead. - Note that the VST3 layout arranges the front speakers "L Lc C Rc R", but the JUCE layout - uses the arrangement "wideLeft left centre right wideRight". To maintain the relative - positions of the speakers, the channels will be remapped accordingly. This means that the - VST3 host's "L" channel will be received on a JUCE plugin's "wideLeft" channel, the - "Lc" channel will be received on a JUCE plugin's "left" channel, and so on. + Is equivalent to: k91_6_W (VST3), kAudioChannelLayoutTag_Atmos_9_1_6 (CoreAudio). - Is equivalent to: k91_6 (VST3), kAudioChannelLayoutTag_Atmos_9_1_6 (CoreAudio). + @see create9point1point6ITU() */ static AudioChannelSet JUCE_CALLTYPE create9point1point6(); diff --git a/modules/juce_audio_processors/format_types/juce_VST3Common.h b/modules/juce_audio_processors/format_types/juce_VST3Common.h index 2e05413509e4..14fc94055935 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3Common.h +++ b/modules/juce_audio_processors/format_types/juce_VST3Common.h @@ -260,6 +260,8 @@ static std::optional getSpeakerType (const AudioChannel case AudioChannelSet::bottomRearLeft: return Steinberg::Vst::kSpeakerBrl; case AudioChannelSet::bottomRearCentre: return Steinberg::Vst::kSpeakerBrc; case AudioChannelSet::bottomRearRight: return Steinberg::Vst::kSpeakerBrr; + case AudioChannelSet::wideLeft: return Steinberg::Vst::kSpeakerLw; + case AudioChannelSet::wideRight: return Steinberg::Vst::kSpeakerRw; case AudioChannelSet::discreteChannel0: return Steinberg::Vst::kSpeakerM; @@ -302,8 +304,6 @@ static std::optional getSpeakerType (const AudioChannel case AudioChannelSet::ambisonicACN61: case AudioChannelSet::ambisonicACN62: case AudioChannelSet::ambisonicACN63: - case AudioChannelSet::wideLeft: - case AudioChannelSet::wideRight: case AudioChannelSet::unknown: break; } @@ -374,6 +374,8 @@ static std::optional getChannelType (Steinberg::Vs case Steinberg::Vst::kSpeakerBrl: return AudioChannelSet::bottomRearLeft; case Steinberg::Vst::kSpeakerBrc: return AudioChannelSet::bottomRearCentre; case Steinberg::Vst::kSpeakerBrr: return AudioChannelSet::bottomRearRight; + case Steinberg::Vst::kSpeakerLw: return AudioChannelSet::wideLeft; + case Steinberg::Vst::kSpeakerRw: return AudioChannelSet::wideRight; } return {}; @@ -424,11 +426,15 @@ namespace detail { k71_6, { X::left, X::right, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } }, { k70_6, { X::left, X::right, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } }, - // The VST3 layout uses 'left/right' and 'left-of-center/right-of-center', but the JUCE layout uses 'left/right' and 'wide-left/wide-right'. - { k91_4, { X::wideLeft, X::wideRight, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::left, X::right, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } }, - { k90_4, { X::wideLeft, X::wideRight, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::left, X::right, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } }, - { k91_6, { X::wideLeft, X::wideRight, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::left, X::right, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } }, - { k90_6, { X::wideLeft, X::wideRight, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::left, X::right, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } }, + { k90_4_W, { X::left, X::right, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::wideLeft, X::wideRight } }, + { k91_4_W, { X::left, X::right, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::wideLeft, X::wideRight } }, + { k90_6_W, { X::left, X::right, X::centre, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight, X::wideLeft, X::wideRight } }, + { k91_6_W, { X::left, X::right, X::centre, X::LFE, X::leftSurroundRear, X::rightSurroundRear, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight, X::wideLeft, X::wideRight } }, + + { k90_4, { X::left, X::right, X::centre, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } }, + { k91_4, { X::left, X::right, X::centre, X::LFE, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight } }, + { k90_6, { X::left, X::right, X::centre, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } }, + { k91_6, { X::left, X::right, X::centre, X::LFE, X::leftSurround, X::rightSurround, X::leftCentre, X::rightCentre, X::leftSurroundSide, X::rightSurroundSide, X::topFrontLeft, X::topFrontRight, X::topRearLeft, X::topRearRight, X::topSideLeft, X::topSideRight } }, }; #if JUCE_DEBUG diff --git a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp index 734201abc24f..e167f532702b 100644 --- a/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp +++ b/modules/juce_audio_processors/format_types/juce_VST3PluginFormat_test.cpp @@ -48,9 +48,9 @@ class VST3PluginFormatTests final : public UnitTest expect (map.getJuceChannelForVst3Channel (1) == 1); // R -> right } - beginTest ("ChannelMapping for a 9.1.6 bus remaps the channels appropriately"); + beginTest ("ChannelMapping for a k91_6 bus remaps the channels appropriately"); { - ChannelMapping map (AudioChannelSet::create9point1point6()); + ChannelMapping map (AudioChannelSet::create9point1point6ITU()); expect (map.size() == 16); // VST3 order is: @@ -71,6 +71,64 @@ class VST3PluginFormatTests final : public UnitTest // Tsl // Tsr // JUCE order is: + // left + // right + // centre + // LFE + // leftSurround + // rightSurround + // leftCentre + // rightCentre + // leftSurroundSide + // rightSurroundSide + // topFrontLeft + // topRearRight + // topRearLeft + // topRearRight + // topSideLeft + // topSideRight + + expect (map.getJuceChannelForVst3Channel (0) == 0); // L -> left + expect (map.getJuceChannelForVst3Channel (1) == 1); // R -> right + expect (map.getJuceChannelForVst3Channel (2) == 2); // C -> centre + expect (map.getJuceChannelForVst3Channel (3) == 3); // Lfe -> LFE + expect (map.getJuceChannelForVst3Channel (4) == 4); // Ls -> leftSurround + expect (map.getJuceChannelForVst3Channel (5) == 5); // Rs -> rightSurround + expect (map.getJuceChannelForVst3Channel (6) == 6); // Lc -> leftCentre + expect (map.getJuceChannelForVst3Channel (7) == 7); // Rc -> rightCentre + expect (map.getJuceChannelForVst3Channel (8) == 8); // Sl -> leftSurroundSide + expect (map.getJuceChannelForVst3Channel (9) == 9); // Sr -> rightSurroundSide + expect (map.getJuceChannelForVst3Channel (10) == 10); // Tfl -> topFrontLeft + expect (map.getJuceChannelForVst3Channel (11) == 11); // Tfr -> topFrontRight + expect (map.getJuceChannelForVst3Channel (12) == 12); // Trl -> topRearLeft + expect (map.getJuceChannelForVst3Channel (13) == 13); // Trr -> topRearRight + expect (map.getJuceChannelForVst3Channel (14) == 14); // Tsl -> topSideLeft + expect (map.getJuceChannelForVst3Channel (15) == 15); // Tsr -> topSideRight + } + + beginTest ("ChannelMapping for a k91_6_W bus remaps the channels appropriately"); + { + ChannelMapping map (AudioChannelSet::create9point1point6()); + expect (map.size() == 16); + + // VST3 order is: + // L + // R + // C + // Lfe + // Ls + // Rs + // Sl + // Sr + // Tfl + // Tfr + // Trl + // Trr + // Tsl + // Tsr + // Lw + // Rw + // JUCE order is: // Left // Right // Centre @@ -88,22 +146,22 @@ class VST3PluginFormatTests final : public UnitTest // Top Side Left // Top Side Right - expect (map.getJuceChannelForVst3Channel (0) == 12); // L -> wideLeft - expect (map.getJuceChannelForVst3Channel (1) == 13); // R -> wideRight + expect (map.getJuceChannelForVst3Channel (0) == 0); // L -> left + expect (map.getJuceChannelForVst3Channel (1) == 1); // R -> right expect (map.getJuceChannelForVst3Channel (2) == 2); // C -> centre expect (map.getJuceChannelForVst3Channel (3) == 3); // Lfe -> LFE expect (map.getJuceChannelForVst3Channel (4) == 10); // Ls -> leftSurroundRear expect (map.getJuceChannelForVst3Channel (5) == 11); // Rs -> rightSurroundRear - expect (map.getJuceChannelForVst3Channel (6) == 0); // Lc -> left - expect (map.getJuceChannelForVst3Channel (7) == 1); // Rc -> right - expect (map.getJuceChannelForVst3Channel (8) == 4); // Sl -> leftSurroundSide - expect (map.getJuceChannelForVst3Channel (9) == 5); // Sl -> leftSurroundSide - expect (map.getJuceChannelForVst3Channel (10) == 6); // Tfl -> topFrontLeft - expect (map.getJuceChannelForVst3Channel (11) == 7); // Tfr -> topFrontRight - expect (map.getJuceChannelForVst3Channel (12) == 8); // Trl -> topRearLeft - expect (map.getJuceChannelForVst3Channel (13) == 9); // Trr -> topRearRight - expect (map.getJuceChannelForVst3Channel (14) == 14); // Tsl -> topSideLeft - expect (map.getJuceChannelForVst3Channel (15) == 15); // Tsr -> topSideRight + expect (map.getJuceChannelForVst3Channel (6) == 4); // Sl -> leftSurroundSide + expect (map.getJuceChannelForVst3Channel (7) == 5); // Sr -> rightSurroundSide + expect (map.getJuceChannelForVst3Channel (8) == 6); // Tfl -> topFrontLeft + expect (map.getJuceChannelForVst3Channel (9) == 7); // Tfr -> topFrontRight + expect (map.getJuceChannelForVst3Channel (10) == 8); // Trl -> topRearLeft + expect (map.getJuceChannelForVst3Channel (11) == 9); // Trr -> topRearRight + expect (map.getJuceChannelForVst3Channel (12) == 14); // Tsl -> topSideLeft + expect (map.getJuceChannelForVst3Channel (13) == 15); // Tsr -> topSideRight + expect (map.getJuceChannelForVst3Channel (14) == 12); // Lw -> wideLeft + expect (map.getJuceChannelForVst3Channel (15) == 13); // Lw -> wideRight } const auto blockSize = 128; From 113009c07431bdb7952d2564a0039354d03f452b Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 3 Jun 2024 12:04:24 +0100 Subject: [PATCH 17/19] VST3 Client: Avoid returning kResultNotImplemented from setComponentState The base implementation of this function does nothing, and returns 'not implemented'. It is more correct to return 'ok', to indicate that setting the component state succeeded. --- .../juce_audio_plugin_client_VST3.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp index c6976780dfef..fbf0b10841f9 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_VST3.cpp @@ -1031,7 +1031,7 @@ class JuceVST3EditController final : public Vst::EditController, #endif //============================================================================== - tresult PLUGIN_API setComponentState (IBStream* stream) override + tresult PLUGIN_API setComponentState (IBStream*) override { // As an IEditController member, the host should only call this from the message thread. assertHostMessageThread(); @@ -1056,7 +1056,7 @@ class JuceVST3EditController final : public Vst::EditController, if (auto* handler = getComponentHandler()) handler->restartComponent (Vst::kParamValuesChanged); - return Vst::EditController::setComponentState (stream); + return kResultOk; } void setAudioProcessor (JuceAudioProcessor* audioProc) From b7d5f64a8e324943fa0732cf5acc295357defd00 Mon Sep 17 00:00:00 2001 From: Anthony Nicholls Date: Fri, 7 Jun 2024 17:05:44 +0100 Subject: [PATCH 18/19] CoreAudio: Prevent racing between calls to start and stop a device --- .../native/juce_CoreAudio_mac.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp index 3938bd197d20..9b4914523393 100644 --- a/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp +++ b/modules/juce_audio_devices/native/juce_CoreAudio_mac.cpp @@ -1039,7 +1039,7 @@ class CoreAudioInternal final : private Timer, CoreAudioIODevice& owner; int bitDepth = 32; - int xruns = 0; + std::atomic xruns = 0; Array sampleRates; Array bufferSizes; AudioDeviceID deviceID; @@ -1147,7 +1147,7 @@ class CoreAudioInternal final : private Timer, return x.mSelector == kAudioDeviceProcessorOverload; }); - intern.xruns += xruns; + intern.xruns += (int) xruns; const auto detailsChanged = std::any_of (pa, pa + numAddresses, [] (const AudioObjectPropertyAddress& x) { @@ -1313,6 +1313,8 @@ class CoreAudioIODevice final : public AudioIODevice, void start (AudioIODeviceCallback* callback) override { + const ScopedLock sl (startStopLock); + if (internal->start (callback)) pendingCallback = nullptr; } @@ -1320,12 +1322,14 @@ class CoreAudioIODevice final : public AudioIODevice, void stop() override { stopAndGetLastCallback(); + + const ScopedLock sl (startStopLock); pendingCallback = nullptr; } void stopWithPendingCallback() { - const ScopedLock sl (closeLock); + const ScopedLock sl (startStopLock); if (pendingCallback == nullptr) pendingCallback = stopAndGetLastCallback(); @@ -1387,7 +1391,7 @@ class CoreAudioIODevice final : public AudioIODevice, AudioIODeviceCallback* pendingCallback = nullptr; AsyncRestarter* restarter = nullptr; BigInteger inputChannelsRequested, outputChannelsRequested; - CriticalSection closeLock; + CriticalSection startStopLock; AudioIODeviceCallback* stopAndGetLastCallback() const { @@ -1412,6 +1416,7 @@ class CoreAudioIODevice final : public AudioIODevice, getCurrentSampleRate(), getCurrentBufferSizeSamples()); + const ScopedLock sl { startStopLock }; start (pendingCallback); } From 244af32715362ee8fe79994b316f87e2d2aeb187 Mon Sep 17 00:00:00 2001 From: attila Date: Thu, 25 Apr 2024 12:38:01 +0200 Subject: [PATCH 19/19] AU Client: Suppress EnumCastOutOfRange Clang Analyzer warning --- .../native/juce_CoreAudioLayouts_mac.h | 11 +++++++++++ .../juce_audio_plugin_client_AU_1.mm | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/modules/juce_audio_basics/native/juce_CoreAudioLayouts_mac.h b/modules/juce_audio_basics/native/juce_CoreAudioLayouts_mac.h index 44ebd4d93c09..1375a0b1ef9c 100644 --- a/modules/juce_audio_basics/native/juce_CoreAudioLayouts_mac.h +++ b/modules/juce_audio_basics/native/juce_CoreAudioLayouts_mac.h @@ -106,7 +106,12 @@ struct CoreAudioLayouts List { kAudioChannelLayoutTag_MPEG_5_1_D, { centre, left, right, leftSurround, rightSurround, LFE } }, List { kAudioChannelLayoutTag_MPEG_7_1_B, { centre, leftCentre, rightCentre, left, right, leftSurround, rightSurround, LFE } }, List { kAudioChannelLayoutTag_Emagic_Default_7_1, { left, right, leftSurround, rightSurround, centre, LFE, leftCentre, rightCentre } }, + + // Suppressing clang-analyzer-optin.core.EnumCastOutOfRange + #ifndef __clang_analyzer__ List { kAudioChannelLayoutTag_SMPTE_DTV, { left, right, centre, LFE, leftSurround, rightSurround, discreteChannel0 /* leftMatrixTotal */, (ChannelType) (discreteChannel0 + 1) /* rightMatrixTotal */} }, + #endif + List { kAudioChannelLayoutTag_ITU_2_2, { left, right, leftSurround, rightSurround } }, List { kAudioChannelLayoutTag_DVD_4, { left, right, LFE } }, List { kAudioChannelLayoutTag_DVD_5, { left, right, LFE, centreSurround } }, @@ -227,10 +232,13 @@ struct CoreAudioLayouts for (UInt32 i = 0; i < layout.mNumberChannelDescriptions; ++i) channels.addIfNotAlreadyThere (getChannelTypeFromAudioChannelLabel (layout.mChannelDescriptions[i].mChannelLabel)); + // Suppressing clang-analyzer-optin.core.EnumCastOutOfRange + #ifndef __clang_analyzer__ // different speaker mappings may point to the same JUCE speaker so fill up // this array with discrete channels for (int j = 0; channels.size() < static_cast (layout.mNumberChannelDescriptions); ++j) channels.addIfNotAlreadyThere (static_cast (AudioChannelSet::discreteChannel0 + j)); + #endif return channels; } @@ -273,8 +281,11 @@ struct CoreAudioLayouts return AudioChannelSet::ambisonic (ambisonicOrder).getChannelTypes(); } + // Suppressing clang-analyzer-optin.core.EnumCastOutOfRange + #ifndef __clang_analyzer__ for (UInt32 i = 0; i < numChannels; ++i) speakers.add (static_cast (AudioChannelSet::discreteChannel0 + i)); + #endif return speakers; } diff --git a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm index c1ed41aa97c9..10aa30b6a5df 100644 --- a/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm +++ b/modules/juce_audio_plugin_client/juce_audio_plugin_client_AU_1.mm @@ -869,9 +869,14 @@ bool busIgnoresLayout ([[maybe_unused]] bool isInput, [[maybe_unused]] int busNr if (const AudioProcessor::Bus* bus = juceFilter->getBus (isInput, busNr)) { AudioChannelSet discreteRangeSet; + + // Suppressing clang-analyzer-optin.core.EnumCastOutOfRange + #ifndef __clang_analyzer__ const int n = bus->getDefaultLayout().size(); + for (int i = 0; i < n; ++i) discreteRangeSet.addChannel ((AudioChannelSet::ChannelType) (256 + i)); + #endif // if the audioprocessor supports this it cannot // really be interested in the bus layouts