From f9eb564f8fee06eef1c9013c0d837ca8ac54ae90 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 11 Jul 2022 21:22:12 +0100 Subject: [PATCH 001/255] #856 comment metadata on some bluetoothdevice members --- src/bluetoothdevice.h | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/bluetoothdevice.h b/src/bluetoothdevice.h index 316cd4c0e..5c30e7130 100644 --- a/src/bluetoothdevice.h +++ b/src/bluetoothdevice.h @@ -94,6 +94,11 @@ class bluetoothdevice : public QObject { virtual BLUETOOTH_TYPE deviceType(); static QStringList metrics(); virtual uint8_t metrics_override_heartrate(); + + /** + * @brief Overridden in subclasses to specify the maximum resistance level supported by the device. + * @return The device's maximum resistance level. + */ virtual uint8_t maxResistance(); public Q_SLOTS: @@ -129,11 +134,26 @@ class bluetoothdevice : public QObject { metric elapsed; metric moving; // moving time - metric Speed; metric KCal; + + /** + * @brief Flywheel speed. Units: kilometers per hour + */ + metric Speed; + + /** + * @brief Cumulative flywheel revolutions multiplied by the wheel circumference. Units: kilometers + */ metric Distance; + + uint8_t FanSpeed = 0; + + /** + * @brief Heart rate. Unit: beats per minute + */ metric Heart; + int8_t requestStart = -1; int8_t requestStop = -1; int8_t requestIncreaseFan = -1; @@ -145,7 +165,15 @@ class bluetoothdevice : public QObject { metric m_watt; metric WattKg; metric WeightLoss; + + /** + * @brief The speed at which the crank is turning. Units: revolutions per minute (RPM) + */ metric Cadence; + + /** + * @brief The currently requested resistance level. Expected range: 0 to maxResistance() + */ metric Resistance; metric METS; From 481d785ca66ee413dcd5a9765acf85c3145a37bf Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 13 Jul 2022 00:11:45 +0100 Subject: [PATCH 002/255] #856 steering doc --- src/bike.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/bike.h b/src/bike.h index a3650f6da..1179ea23b 100644 --- a/src/bike.h +++ b/src/bike.h @@ -32,6 +32,13 @@ class bike : public bluetoothdevice { uint8_t metrics_override_heartrate(); void setGears(int8_t d); int8_t gears(); + + + /** + * @brief currentSteeringAngle Gets a metric object to get or set the current steering angle + * for the Elite Sterzo or emulating device. Expected range -45 to +45 degrees. + * @return A metric object. + */ metric currentSteeringAngle() { return m_steeringAngle; } virtual bool inclinationAvailableByHardware(); From 170086add6db347150205991d2a21b5dfc41b12d Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 14 Jul 2022 20:22:59 +0100 Subject: [PATCH 003/255] #856 draft comments on public and protected bluetoothdevice members --- src/bluetoothdevice.h | 369 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 365 insertions(+), 4 deletions(-) diff --git a/src/bluetoothdevice.h b/src/bluetoothdevice.h index 5c30e7130..d8015053c 100644 --- a/src/bluetoothdevice.h +++ b/src/bluetoothdevice.h @@ -25,9 +25,19 @@ #define SAME_BLUETOOTH_DEVICE(d1, d2) (d1.address() == d2.address()) #endif +/** + * @brief The MetersByInclination class represents a section of track at a specific inclination. + */ class MetersByInclination { public: + /** + * @brief meters The length of the section. + */ double meters; + + /** + * @brief inclination The inclination of the section. + */ double inclination; }; @@ -36,68 +46,310 @@ class bluetoothdevice : public QObject { Q_OBJECT public: bluetoothdevice(); + /** + * @brief currentHeart Gets a metric object for getting and setting the current heart rate. Units: beats per minute + */ virtual metric currentHeart(); + + /** + * @brief currentSpeed Gets a metric object for getting and setting the speed. Units: km/h + * @return + */ virtual metric currentSpeed(); + + /** + * @brief currentPace Gets the current pace. Units: ? + * @return + */ virtual QTime currentPace(); + + /** + * @brief currentInclination + * @return + */ virtual metric currentInclination(); + + /** + * @brief setInclination Set the protected Inclination metric. + * @param inclination The inclination. Units: degrees (0 is horizontal) + */ void setInclination(double inclination); + + /** + * @brief averagePace Gets the average pace. Units: ? + * @return + */ virtual QTime averagePace(); + + /** + * @brief maxPace Gets the maximum pace for the session. Units: ? + * @return + */ virtual QTime maxPace(); + + /** + * @brief odometer Gets the total distance travelled since ???. Units: km + * @return + */ virtual double odometer(); + + /** + * @brief calories Gets a metric object to get and set the amount of energy expended. + * Default implementation returns the protected KCal property. Units: kcal + * Other implementations could have different units. + * @return + */ virtual metric calories(); + + /** + * @brief jouls Gets a metric object to get and set the number of joules expended. Units: joules + * @return + */ metric jouls(); + + /** + * @brief fanSpeed Gets the current fan speed. Units: revolutions per second + * @return + */ virtual uint8_t fanSpeed(); + + /** + * @brief elapsedTime The elapsed time for the session(?). + * @return + */ virtual QTime elapsedTime(); + + /** + * @brief offsetElapsedTime Shifts the elapsed time (stored in the protected member: elapsed)for the session by the specified offset. + * @param offset The time offset to shift by. Default unit: seconds but this could be overridden. + */ virtual void offsetElapsedTime(int offset); + + /** + * @brief movingTime Gets the time spent moving. + */ virtual QTime movingTime(); + + /** + * @brief lapElapsedTime Gets the time elapsed on the current lap. + */ virtual QTime lapElapsedTime(); + + /** + * @brief connected Gets a value to indicate if the device is connected. + */ virtual bool connected(); + + /** + * @brief currentResistance Gets a metric object to get or set the currently requested resistance. + * Expected range: 0 to maxResistance() + */ virtual metric currentResistance(); + + /** + * @brief currentCadence Gets a metric object to get and set the current cadence. Units: revolutions per minute + */ virtual metric currentCadence(); + + /** + * @brief currentCrankRevolutions Gets the current total number of crank revolutions. + */ virtual double currentCrankRevolutions(); + + /** + * @brief currentCordinate Gets the current geographic coordinates. + */ virtual QGeoCoordinate currentCordinate(); - virtual double currentAzimuth() { return azimuth; } + + + /** + * @brief nextInclination300Meters The next 300m of track sections: length and inclination + * @return A list of MetersByInclination objects + */ virtual QList nextInclination300Meters() { return NextInclination300Meters; } + + /** + * @brief currentAzimuth Gets the current azimuth. Units: degrees (? = North) + */ + virtual double currentAzimuth() { return azimuth; } + + /** + * @brief averageAzimuthNext300m Gets the average azimuth for the next 300m + * Units: degrees (? = North) + */ virtual double averageAzimuthNext300m() { return azimuthAvgNext300m; } + + /** + * @brief setAverageAzimuthNext300m Sets the average azimuth for the next 300m. + * @param azimuth The azimuth. Units: degrees (? = North) + */ virtual void setAverageAzimuthNext300m(double azimuth) { azimuthAvgNext300m = azimuth; } + + /** + * @brief lastCrankEventTime The time of the last crank event. Units: 1/1024s + */ virtual uint16_t lastCrankEventTime(); + + /** + * @brief VirtualDevice ??? + */ virtual void *VirtualDevice(); + + /** + * @brief watts Calculates the amount of power used. Units: watts + * @param weight The weight of the rider. Units: kg + */ uint16_t watts(double weight); + + /** + * @brief wattsMetric Gets a metric object to get or set the amount of power used. Units: watts + */ metric wattsMetric(); + + /** + * @brief changeFanSpeed Tries to change the fan speed to the speed. + * @param speed The requested fan speed. Units: revolutions per second + */ virtual bool changeFanSpeed(uint8_t speed); + + /** + * @brief elevationGain Gets a metric object to get and set the elevation gain. Units: ? + */ virtual metric elevationGain(); + + /** + * @brief clearStats Clear the statistics. + */ virtual void clearStats(); + + /** + * @brief bluetoothDevice The bluetooth device information. + */ QBluetoothDeviceInfo bluetoothDevice; + + /** + * @brief disconnectBluetooth Disconnect from bluetooth (the device or the client software ??) + */ void disconnectBluetooth(); + + /** + * @brief setPaused Sets the paused mode. + * @param p True to pause, false to resume. + */ virtual void setPaused(bool p); + + /** + * @brief isPaused Indicates if the device is currently paused. + */ bool isPaused() { return paused; } + + /** + * @brief setLap Begins a new lap for the statistics calculated by the metrics objects. + */ virtual void setLap(); + + /** + * @brief setAutoResistance Toggles auto-resistance. + */ void setAutoResistance(bool value) { autoResistanceEnable = value; } + + /** + * @brief autoResistance Indicates the state of auto-resistance. + * @return + */ bool autoResistance() { return autoResistanceEnable; } + + /** + * @brief setDifficult Sets the difficulty level. + * @param d The difficulty level. Units: depends on implementation. + */ void setDifficult(double d); + + /** + * @brief difficult Gets the difficulty level. Units: depends on implementation. + * @return + */ double difficult(); + + /** + * @brief weightLoss Gets the value of the weight loss metric. Units: kg + * @return + */ double weightLoss() { return WeightLoss.value(); } + + /** + * @brief wattKg Gets a metric object to get and set the watt kg of something. Units: watt kg + * @return + */ metric wattKg() { return WattKg; } + + /** + * @brief currentMETS Gets a metric object to get and set the current METS (what does METS stand for?) + * Units: ?? + * @return + */ metric currentMETS() { return METS; } + + /** + * @brief currentHeartZone Gets a metric object to get or set the current heart zone. Units: depends on implementation. + */ metric currentHeartZone() { return HeartZone; } + + /** + * @brief currentPowerZone Gets a metric object to get or set the current power zome. Units: depends on implementation. + * @return + */ metric currentPowerZone() { return PowerZone; } + + /** + * @brief setGPXFile Sets the file for GPS data exchange. + * @param filename The file path. + */ void setGPXFile(QString filename); + + /** + * @brief currentGPXBase64 ??? + */ QString currentGPXBase64() { return gpxBase64; } // in the future these 2 should be calculated inside the update_metrics() + + /** + * @brief setHeartZone Set the current heart zone. + * This is equivalent to currentHeartZone().setvalue(hz) + * @param hz The heart zone. Unit: depends on implementation. + */ void setHeartZone(double hz) { HeartZone = hz; } + + /** + * @brief setPowerZone Set the current power zone. + * This is equivalent to currentPowerZone().setvalue(pz) + * @param pz The power zone. Unit: depends on implementation. + */ void setPowerZone(double pz) { PowerZone = pz; } enum BLUETOOTH_TYPE { UNKNOWN = 0, TREADMILL, BIKE, ROWING, ELLIPTICAL }; enum WORKOUT_EVENT_STATE { STARTED = 0, PAUSED = 1, RESUMED = 2, STOPPED = 3 }; + /** + * @brief deviceType The type of device represented by this object. + */ virtual BLUETOOTH_TYPE deviceType(); + + /** + * @brief metrics Gets a list of available metris. + * @return + */ static QStringList metrics(); + + /** + * @brief metrics_override_heartrate Provides a way to override the metrics heart rate with another metric. + * Units: beats per minute + */ virtual uint8_t metrics_override_heartrate(); /** * @brief Overridden in subclasses to specify the maximum resistance level supported by the device. - * @return The device's maximum resistance level. */ virtual uint8_t maxResistance(); @@ -132,21 +384,35 @@ class bluetoothdevice : public QObject { protected: QLowEnergyController *m_control = nullptr; + /** + * @brief elapsed A metric object to get and set the elapsed time for the session. Units: seconds + */ metric elapsed; + + /** + * @brief moving The time spent moving int he current session. Units: seconds + */ metric moving; // moving time + + /** + * @brief KCal The number of kilocalories expended in the session. Units: kcal + */ metric KCal; /** - * @brief Flywheel speed. Units: kilometers per hour + * @brief Flywheel speed. Units: km/h */ metric Speed; /** - * @brief Cumulative flywheel revolutions multiplied by the wheel circumference. Units: kilometers + * @brief Cumulative flywheel revolutions multiplied by the wheel circumference. Units: km */ metric Distance; + /** + * @brief FanSpeed The currently requested fan speed. Units: revolutions per second + */ uint8_t FanSpeed = 0; /** @@ -159,11 +425,35 @@ class bluetoothdevice : public QObject { int8_t requestIncreaseFan = -1; int8_t requestDecreaseFan = -1; double requestFanSpeed = -1; + + /** + * @brief m_difficult The current difficulty. Units: device dependent + */ double m_difficult = 1.0; + + /** + * @brief m_jouls The number of joules expended in the current session. Unit: joules + */ metric m_jouls; + + /** + * @brief elevationAcc The elevation gain. Units: ? + */ metric elevationAcc; + + /** + * @brief m_watt Metric to get and set the power expended in the session. Unit: watts + */ metric m_watt; + + /** + * @brief WattKg Metric to get and set the watt kg for the session (what's this?). Unit: watt kg + */ metric WattKg; + + /** + * @brief WeightLoss Metric to get and set the lost weight in the session (?). Unit: kg + */ metric WeightLoss; /** @@ -175,28 +465,99 @@ class bluetoothdevice : public QObject { * @brief The currently requested resistance level. Expected range: 0 to maxResistance() */ metric Resistance; + + /** + * @brief METS A metric object to get and set the METS (what's this?) for the session(?). Units: ?? + */ metric METS; + /** + * @brief coordinate The geolocation for the device. + */ QGeoCoordinate coordinate; + + /** + * @brief azimuth The azimuth. Units: degrees (? = North) + */ double azimuth; + + /** + * @brief azimuthAvgNext300m The average azimuth for the next 300m. Units: degrees (? = North) + */ double azimuthAvgNext300m; + + /** + * @brief coordinateTS ???. Unit: ??? + */ quint64 coordinateTS = 0; + + /** + * @brief coordinateOdometer ???. Unit: ??? + */ double coordinateOdometer = 0; + + /** + * @brief The currently loaded gpxBase64 GPS exchange data. + */ QString gpxBase64 = ""; + + /** + * @brief gpxFileName The file path of the currently loaded GPS exchange data. + */ QString gpxFileName = ""; + + /** + * @brief NextInclination300Meters A list of the length and inclination of track sections for the next 300m + */ QList NextInclination300Meters; + /** + * @brief Inclination A metric to get and set the currently requested inclinaton. Units: degrees (0 = horizontal) + */ metric Inclination; + + /** + * @brief HeartZone A metrix to get and set the current heart zone. Unit: depends on implementation + */ metric HeartZone; + + /** + * @brief PowerZone A metrix to get and set the current power zone. Unit: depends on implementation + */ metric PowerZone; bluetoothdevice::WORKOUT_EVENT_STATE lastState; + + /** + * @brief paused Indicates if the device is currently paused. + */ bool paused = false; + + /** + * @brief autoResistanceEnable Indicates if auto-resistance is currently enabled. + */ bool autoResistanceEnable = true; + /** + * @brief _lastTimeUpdate The time the (client was last updated / last update was received from the device) ??? + */ QDateTime _lastTimeUpdate; + + /** + * @brief _firstUpdate Indicates if this is the first update. + */ bool _firstUpdate = true; + + /** + * @brief update_metrics Updates the metrics given the specified inputs. + * @param watt_calc ?? + * @param watts ?. Unit: watts + */ void update_metrics(bool watt_calc, const double watts); + + /** + * @brief calculateMETS Calculate the METS (what's that?). Unit: ?? + */ double calculateMETS(); }; From 74ed2912105d312d4282f3212a39c192220c86b2 Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 14 Jul 2022 20:25:58 +0100 Subject: [PATCH 004/255] #856 draft comments on public and protected bluetoothdevice members --- src/bluetoothdevice.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bluetoothdevice.h b/src/bluetoothdevice.h index d8015053c..e4e83d4fe 100644 --- a/src/bluetoothdevice.h +++ b/src/bluetoothdevice.h @@ -31,12 +31,12 @@ class MetersByInclination { public: /** - * @brief meters The length of the section. + * @brief meters The length of the section. Unit: meters */ double meters; /** - * @brief inclination The inclination of the section. + * @brief inclination The inclination of the section. Unit: degrees (0 = horizontal) */ double inclination; }; From acfb4419799c41274050f57fa85aa24a776c4068 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 15 Jul 2022 00:28:57 +0100 Subject: [PATCH 005/255] #856 METs comments --- src/bluetoothdevice.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/bluetoothdevice.h b/src/bluetoothdevice.h index e4e83d4fe..f6ac5aa78 100644 --- a/src/bluetoothdevice.h +++ b/src/bluetoothdevice.h @@ -284,9 +284,8 @@ class bluetoothdevice : public QObject { metric wattKg() { return WattKg; } /** - * @brief currentMETS Gets a metric object to get and set the current METS (what does METS stand for?) - * Units: ?? - * @return + * @brief currentMETS Gets a metric object to get and set the current METS (Metabolic Equivalent of Tasks) + * Units: METs (1 MET is approximately 3.5mL of Oxygen consumed per kg of body weight per minute) */ metric currentMETS() { return METS; } @@ -467,7 +466,8 @@ class bluetoothdevice : public QObject { metric Resistance; /** - * @brief METS A metric object to get and set the METS (what's this?) for the session(?). Units: ?? + * @brief METS A metric object to get and set the METS (Metabolic Equivalent of Tasks) for the session. + * Units: METs (1 MET is approximately 3.5mL of Oxygen consumed per kg of body weight per minute) */ metric METS; @@ -556,7 +556,8 @@ class bluetoothdevice : public QObject { void update_metrics(bool watt_calc, const double watts); /** - * @brief calculateMETS Calculate the METS (what's that?). Unit: ?? + * @brief calculateMETS Calculate the METS (Metabolic Equivalent of Tasks) + * Units: METs (1 MET is approximately 3.5mL of Oxygen consumed per kg of body weight per minute) */ double calculateMETS(); }; From 45e2d6dbbcff1b304115e4fa0dfe94dbb3f78e42 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 15 Jul 2022 23:34:20 +0100 Subject: [PATCH 006/255] #856 adjusted comments, made some bike-specific comments general --- src/bluetoothdevice.h | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/bluetoothdevice.h b/src/bluetoothdevice.h index f6ac5aa78..db926bd8d 100644 --- a/src/bluetoothdevice.h +++ b/src/bluetoothdevice.h @@ -53,42 +53,38 @@ class bluetoothdevice : public QObject { /** * @brief currentSpeed Gets a metric object for getting and setting the speed. Units: km/h - * @return */ virtual metric currentSpeed(); /** - * @brief currentPace Gets the current pace. Units: ? - * @return + * @brief currentPace Gets the current pace. Units: time per km */ virtual QTime currentPace(); /** - * @brief currentInclination - * @return + * @brief currentInclination The current inclination. Expected range: 0 degrees (horizontal) to 90 degrees (vertical) */ virtual metric currentInclination(); /** - * @brief setInclination Set the protected Inclination metric. + * @brief setInclination Set the protected Inclination metric, which could be different from that + * returned by an overridden currentInclination(). * @param inclination The inclination. Units: degrees (0 is horizontal) */ void setInclination(double inclination); /** - * @brief averagePace Gets the average pace. Units: ? - * @return + * @brief averagePace Gets the average time per kilometer travelled. Units: time per km */ virtual QTime averagePace(); /** - * @brief maxPace Gets the maximum pace for the session. Units: ? - * @return + * @brief maxPace Gets the maximum pace (minimum time per kilometer) for the session. Units: time per km */ virtual QTime maxPace(); /** - * @brief odometer Gets the total distance travelled since ???. Units: km + * @brief odometer Gets the total distance travelled. Units: km * @return */ virtual double odometer(); @@ -103,24 +99,22 @@ class bluetoothdevice : public QObject { /** * @brief jouls Gets a metric object to get and set the number of joules expended. Units: joules - * @return */ metric jouls(); /** * @brief fanSpeed Gets the current fan speed. Units: revolutions per second - * @return */ virtual uint8_t fanSpeed(); /** * @brief elapsedTime The elapsed time for the session(?). - * @return */ virtual QTime elapsedTime(); /** - * @brief offsetElapsedTime Shifts the elapsed time (stored in the protected member: elapsed)for the session by the specified offset. + * @brief offsetElapsedTime Shifts the elapsed time (stored in the protected member: elapsed) + * for the session by the specified offset. * @param offset The time offset to shift by. Default unit: seconds but this could be overridden. */ virtual void offsetElapsedTime(int offset); @@ -336,7 +330,7 @@ class bluetoothdevice : public QObject { virtual BLUETOOTH_TYPE deviceType(); /** - * @brief metrics Gets a list of available metris. + * @brief metrics Gets a list of available metrics. * @return */ static QStringList metrics(); @@ -399,12 +393,17 @@ class bluetoothdevice : public QObject { metric KCal; /** - * @brief Flywheel speed. Units: km/h + * @brief Speed The simulated speed of the device. Units: km/h + * e.g. the product of bike flywheel speed and simulated wheel size, or + * the belt speed of a treadmill. */ metric Speed; /** - * @brief Cumulative flywheel revolutions multiplied by the wheel circumference. Units: km + * @brief Distance The simulated distance travelled. Units: km + * Depends on the device. + * e.g. the number of bike flywheel revolutions multiplied by the simulated wheel circumference, or + * the length of belt traversed on a treadmill. */ metric Distance; @@ -456,7 +455,9 @@ class bluetoothdevice : public QObject { metric WeightLoss; /** - * @brief The speed at which the crank is turning. Units: revolutions per minute (RPM) + * @brief The speed at which the crank is turning. Units: device-specific actions per minute + * e.g. crank revolutions on a bike, steps on a treadmill, + * strokes on a rower, stride rate on an elliptical trainer */ metric Cadence; @@ -517,12 +518,12 @@ class bluetoothdevice : public QObject { metric Inclination; /** - * @brief HeartZone A metrix to get and set the current heart zone. Unit: depends on implementation + * @brief HeartZone A metric to get and set the current heart zone. Unit: depends on implementation */ metric HeartZone; /** - * @brief PowerZone A metrix to get and set the current power zone. Unit: depends on implementation + * @brief PowerZone A metric to get and set the current power zone. Unit: depends on implementation */ metric PowerZone; From ee0dae9bacba31f6bbff185dae01cdbadef840e8 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 16 Jul 2022 15:32:35 +0100 Subject: [PATCH 007/255] #856 comment updates from PR review --- src/bluetoothdevice.h | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/bluetoothdevice.h b/src/bluetoothdevice.h index db926bd8d..2281e00fd 100644 --- a/src/bluetoothdevice.h +++ b/src/bluetoothdevice.h @@ -31,12 +31,13 @@ class MetersByInclination { public: /** - * @brief meters The length of the section. Unit: meters + * @brief meters The length of the section. Units: meters */ double meters; /** - * @brief inclination The inclination of the section. Unit: degrees (0 = horizontal) + * @brief inclination The inclination of the section. + * Units: Percentage vertical to horizontal */ double inclination; }; @@ -62,14 +63,16 @@ class bluetoothdevice : public QObject { virtual QTime currentPace(); /** - * @brief currentInclination The current inclination. Expected range: 0 degrees (horizontal) to 90 degrees (vertical) + * @brief currentInclination The current inclination. + * Units: Percentage vertical to horizontal + * Expected range: Depends on device. */ virtual metric currentInclination(); /** * @brief setInclination Set the protected Inclination metric, which could be different from that * returned by an overridden currentInclination(). - * @param inclination The inclination. Units: degrees (0 is horizontal) + * @param inclination The inclination. Units: Percentage vertical to horizontal. Expected range: Depends on device. */ void setInclination(double inclination); @@ -103,7 +106,7 @@ class bluetoothdevice : public QObject { metric jouls(); /** - * @brief fanSpeed Gets the current fan speed. Units: revolutions per second + * @brief fanSpeed Gets the current fan speed. Units: depends on device */ virtual uint8_t fanSpeed(); @@ -185,7 +188,7 @@ class bluetoothdevice : public QObject { virtual uint16_t lastCrankEventTime(); /** - * @brief VirtualDevice ??? + * @brief VirtualDevice The virtual bridge to Zwift for example, or to any 3rd party app. */ virtual void *VirtualDevice(); @@ -201,8 +204,8 @@ class bluetoothdevice : public QObject { metric wattsMetric(); /** - * @brief changeFanSpeed Tries to change the fan speed to the speed. - * @param speed The requested fan speed. Units: revolutions per second + * @brief changeFanSpeed Tries to change the fan speed. + * @param speed The requested fan speed. Units: depends on device */ virtual bool changeFanSpeed(uint8_t speed); @@ -222,7 +225,7 @@ class bluetoothdevice : public QObject { QBluetoothDeviceInfo bluetoothDevice; /** - * @brief disconnectBluetooth Disconnect from bluetooth (the device or the client software ??) + * @brief disconnectBluetooth Disconnect from the device from bluetooth. */ void disconnectBluetooth(); @@ -301,7 +304,7 @@ class bluetoothdevice : public QObject { void setGPXFile(QString filename); /** - * @brief currentGPXBase64 ??? + * @brief currentGPXBase64 Returns the Base64 encode for the current GPX used. */ QString currentGPXBase64() { return gpxBase64; } From eb85ce0f82089dd0d5ff3b99077fd2e1d17a1336 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 16 Jul 2022 16:22:28 +0100 Subject: [PATCH 008/255] #855 support for Trixter X-Dream V1 exercise bike --- docs/10_Installation.md | 2 +- src/trixterxdreamv1bike.cpp | 158 +++++++++++++++++++++++++++++ src/trixterxdreamv1bike.h | 156 +++++++++++++++++++++++++++++ src/trixterxdreamv1client.cpp | 182 ++++++++++++++++++++++++++++++++++ src/trixterxdreamv1client.h | 136 +++++++++++++++++++++++++ src/trixterxdreamv1serial.cpp | 84 ++++++++++++++++ src/trixterxdreamv1serial.h | 57 +++++++++++ 7 files changed, 774 insertions(+), 1 deletion(-) create mode 100644 src/trixterxdreamv1bike.cpp create mode 100644 src/trixterxdreamv1bike.h create mode 100644 src/trixterxdreamv1client.cpp create mode 100644 src/trixterxdreamv1client.h create mode 100644 src/trixterxdreamv1serial.cpp create mode 100644 src/trixterxdreamv1serial.h diff --git a/docs/10_Installation.md b/docs/10_Installation.md index 1119858ab..b3ed3d09a 100644 --- a/docs/10_Installation.md +++ b/docs/10_Installation.md @@ -8,7 +8,7 @@ Once you've installed QDomyos-Zwift, you can access the [operation guide](30_usa ```buildoutcfg $ sudo apt update && sudo apt upgrade # this is very important on raspberry pi: you need the bluetooth firmware updated! -$ sudo apt install git qtquickcontrols2-5-dev libqt5bluetooth5 libqt5widgets5 libqt5positioning5 libqt5xml5 qtconnectivity5-dev qtpositioning5-dev libqt5charts5-dev libqt5charts5 qt5-assistant libqt5networkauth5-dev libqt5websockets5-dev qml-module* libqt5texttospeech5-dev libqt5texttospeech5 libqt5location5-plugins qtlocation5-dev +$ sudo apt install git qtquickcontrols2-5-dev libqt5serialport5-dev libqt5bluetooth5 libqt5widgets5 libqt5positioning5 libqt5xml5 qtconnectivity5-dev qtpositioning5-dev libqt5charts5-dev libqt5charts5 qt5-assistant libqt5networkauth5-dev libqt5websockets5-dev qml-module* libqt5texttospeech5-dev libqt5texttospeech5 libqt5location5-plugins qtlocation5-dev $ git clone https://github.com/cagnulein/qdomyos-zwift.git $ cd qdomyos-zwift $ git submodule update --init src/smtpclient/ diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp new file mode 100644 index 000000000..d3fe5e238 --- /dev/null +++ b/src/trixterxdreamv1bike.cpp @@ -0,0 +1,158 @@ +#include "trixterxdreamv1bike.h" +#include +#include + + +trixterxdreamv1bike::trixterxdreamv1bike(QString portName, bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) +{ + // Set the wheel diameter for speed and distance calculations + this->set_wheelDiameter(DefaultWheelDiamter); + + // QZ things from expected constructor + this->noWriteResistance = noWriteResistance; + this->noHeartService = noHeartService; + this->noVirtualDevice = noVirtualDevice; + this->noSteering = noSteering; + + // Get the current time in milliseconds since ancient times. + // This will be subtracted from further readings from getTime() to get an easier to look at number. + this->t0 = QDateTime::currentDateTime().toMSecsSinceEpoch(); + + // References to objects for callbacks + auto thisObject = this; + auto device=&this->port; + + // tell the client where to get the time + this->client.set_GetTime([&thisObject]()->uint32_t { return thisObject->getTime();} ); + + // tell the client how to send data to the device + if(!noWriteResistance) + this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(bytes, length, "");}); + + // tell the serial port where to send incoming data blocks + this->port.set_bytes_read([&thisObject](QByteArray bytes) -> void {thisObject->update(bytes); }); + + // open the port. This should be at 115200 bits per second. + this->port.open(portName, 1000); + + // create the timer for the resistance. This only needs to be active when a non-zero resistance is requested. + this->resistanceTimer = new QTimer(this); + connect(this->resistanceTimer, &QTimer::timeout, this, &trixterxdreamv1bike::updateResistance); +} + +bool trixterxdreamv1bike::testPort(const QString& portName) +{ + try + { + trixterxdreamv1bike bike(portName, true, true, true, true); // minimal device + QThread::msleep(1000); + return bike.packetsProcessed>10; // >0 is probably okay, they should arrive every approx 12ms + } + catch (...) + { + return false; + } + +} + +QString trixterxdreamv1bike::findPort() +{ + auto availablePorts = trixterxdreamv1serial::availablePorts(); + + for(int i=0; i(QDateTime::currentDateTime().toMSecsSinceEpoch() - this->t0); +} + +bool trixterxdreamv1bike::updateClient(QByteArray bytes, trixterxdreamv1client * client) +{ + bool stateChanged = false; + + for(int i=0; iReceiveChar(bytes[i]); + + return stateChanged; +} + +void trixterxdreamv1bike::update(QByteArray bytes) +{ + // send the bytes to the client and return if there's no change of state + if(!updateClient(bytes, &this->client)) + return; + + // Take the most recent state read + auto state = this->client.getLastState(); + + // update the packet count + this->packetsProcessed++; + + // update the metrics + this->LastCrankEventTime = state.LastEventTime; + if(!this->noHeartService) + this->Heart.setValue(state.HeartRate); + + // set the speed in km/h + constexpr double minutesPerHour = 60.0; + this->Speed.setValue(state.FlywheelRPM * minutesPerHour * this->wheelCircumference); + + // set the distance in km + this->Distance.setValue(state.CumulativeWheelRevolutions * this->wheelCircumference); + + // set the cadence in revolutions per minute + this->Cadence.setValue(state.CrankRPM); + + // set the crank revolutions + this->CrankRevs = state.CumulativeCrankRevolutions; + + // Set the steering + if(!this->noSteering) + this->currentSteeringAngle().setValue(90.0 / 250.0 * state.Steering -45.0); + +} + +void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) +{ + // store the new resistance level. This might be the same as lastRequestedResistance(),Value + // but it doesn't involve a function call and a cast to get the value. + this->resistanceLevel = resistanceLevel; + + // don't do anything if resistance is disabled + if(this->noWriteResistance) + return; + + if(resistanceLevel==0) + this->resistanceTimer->stop(); + else + this->resistanceTimer->start(trixterxdreamv1client::ResistancePulseIntervalMilliseconds); +} + +void trixterxdreamv1bike::updateResistance() +{ + this->client.SendResistance(this->resistanceLevel); +} + +trixterxdreamv1bike::~trixterxdreamv1bike() +{ + this->resistanceTimer->stop(); + this->port.quit(); + + delete this->resistanceTimer; +} + +void trixterxdreamv1bike::set_wheelDiameter(double value) +{ + // clip the value + value = std::min(MaxWheelDiameter, std::max(value, MinWheelDiameter)); + + // stored as km to avoid dividing by 1000 every time it's used + this->wheelCircumference = value * M_PI / 1000.0; +} diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h new file mode 100644 index 000000000..604a1d0bf --- /dev/null +++ b/src/trixterxdreamv1bike.h @@ -0,0 +1,156 @@ +#pragma once +#include "bike.h" +#include "trixterxdreamv1client.h" +#include "trixterxdreamv1serial.h" + +class trixterxdreamv1bike : public bike +{ + Q_OBJECT +private: + /** + * @brief client An object that processes incoming data to CSCS, heart rate and steering data + */ + trixterxdreamv1client client; + + /** + * @brief port An object that monitors a serial port to read incoming data, and to write + * resistance level requests. + */ + trixterxdreamv1serial port; + + /** + * @brief resistanceTimer A timer to push the currently requested resistance level to the device. + */ + QTimer * resistanceTimer; + + /** + * @brief noHeartService Suppress heart rate readings. + */ + bool noHeartService; + + /** + * @brief noVirtualDevice Suppress virtual device. + */ + bool noVirtualDevice; + + /** + * @brief noWriteResistance Suppress sending resistance to device. + */ + bool noWriteResistance; + + /** + * @brief noSteering Suppress steering readings. + */ + bool noSteering; + + /** + * @brief resistanceLevel The last requested resistance level. + */ + uint8_t resistanceLevel; + + /** + * @brief wheelCircumference The simulated circumference of the bike's wheels, for converting + * angular velocity to a speed. Units: kilometers. + */ + double wheelCircumference; + + /** + * @brief t0 The start time in milliseconds. Used to reduce te size of time values processed. + */ + qint64 t0; + + /** + * @brief packetsProcessed The number of packets processed. + */ + uint32_t packetsProcessed; + + /** + * @brief getTime Gets the time in miliseconds since this object was created. + * @return The number of milliseconds since this object was created. + */ + uint32_t getTime(); + + /** + * @brief Temporary method to contain what happens when a new block of data comes in + * from the data source (serial port). + */ + void update(QByteArray bytes); + + /** + * @brief updateResistance Called by the resistanceTimer to send the resistence request to the + * device. + */ + void updateResistance(); + + /** + * @brief updateClient Passes the array of bytes into the client one by one. + * @param bytes The incoming bytes. + * @param client The client object that interprets the incoming bytes into data packets. + * @return True if the state of the client changed due to the input. + */ + static bool updateClient(QByteArray bytes, trixterxdreamv1client * client); + + /** + * @brief testPort Tries to open a port and looks for valid data packets. + * @param portName The name of the serial port. + * @return True if valid data packets were obtained from the port. + */ + static bool testPort(const QString &portName); +protected: + virtual BLUETOOTH_TYPE devicetype() { return BIKE; } + +public Q_SLOTS: + /** + * @brief changeResistance Called to change the requested resistance level. + * @param resistanceLevel The resistance level to request (0..250) + */ + virtual void changeResistance(int8_t resistanceLevel); + +public: + + /** + * @brief MaxWheelDiameter The maximum supported wheel diameter. Unit: meters + */ + constexpr static double MaxWheelDiameter = 2.0; + + /** + * @brief MinWheelDiameter The minimum supported wheel diameter. Unit: meters + */ + constexpr static double MinWheelDiameter = 0.1; + + /** + * @brief DefaultWheelDiameter The default wheel diameter. Unit: meters + */ + constexpr static double DefaultWheelDiamter = 26*0.0254; + + + /** + * @brief trixterxdreamv1bike Constructor + * @param portName The name of the serial port to connect to. + * @param noWriteResistance Option to avoid sending resistance to the device. + * @param noHeartService Option to avoid using the heart rate reading. + * @param noVirtualDevice Option to avoid using a virtual device. + * @param noSteering Option to avoid using the steering reading. + */ + trixterxdreamv1bike(QString portName, bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering); + + ~trixterxdreamv1bike(); + + /** + * @brief set_wheelDiameter Set the simulated wheel diameter to be used for converting angular velocity to speed. Units: meters + * @param value + */ + void set_wheelDiameter(double value); + + /** + * @brief maxResistance The maximum resistance supported. + * @return + */ + virtual uint8_t maxResistance() { return trixterxdreamv1client::MaxResistance; } + + /** + * @brief findPort Looks for an X-Dream V1 bike on known serial ports and returns the port name if it finds one. + */ + static QString findPort(); + +}; diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp new file mode 100644 index 000000000..1c1ab7bed --- /dev/null +++ b/src/trixterxdreamv1client.cpp @@ -0,0 +1,182 @@ + +#include "trixterxdreamv1client.h" + +#include +#include + +trixterxdreamv1client::trixterxdreamv1client() { this->ConfigureResistanceMessages(); } + +void trixterxdreamv1client::ResetBuffer() { + // for the case of an invalid packet, if this was smart, it would store all the input + // and backtrack to the first header bytes after the beginning. + + this->inputBuffer.clear(); + this->byteBuffer.clear(); +} + +trixterxdreamv1client::PacketState trixterxdreamv1client::ProcessChar(char c) { + /* Packet content + * 6A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * (00) Header ---------------+ | | | | | | | | | | | | | | | + * (01) Steering ----------------+ | | | | | | | | | | | | | | + * (02) Unknown --------------------+ | | | | | | | | | | | | | + * (03) Crank position ----------------+ | | | | | | | | | | | | + * (04) Right brake ----------------------+ | | | | | | | | | | | + * (05) Left brake --------------------------+ | | | | | | | | | | + * (06) Unknown --------------------------------+ | | | | | | | | | + * (07) Unknown -----------------------------------+ | | | | | | | | + * (08) Button flags ---------------------------------+ | | | | | | | + * (09) Button flags ------------------------------------+ | | | | | | + * (0A) Crank revolution time (high byte) ------------------+ | | | | | + * (0B) Crank revolution time (low byte) ----------------------+ | | | | + * (0C) Flywheel Revolution Time (high byte) ---------------------+ | | | + * (0D) Flywheel Revolution Time (low byte) -------------------------+ | | + * (0E) Heart rate (BPM) -----------------------------------------------+ | + * (0F) XOR of 00..0E------------------------------------------------------+ + */ + + constexpr int headerLength = 2; + constexpr int packetLength = 16; + constexpr uint8_t header[] = {0x6, 0xA}; + + uint8_t b; + + if (isdigit(c)) { + b = c - '0'; + } else if (c >= 'a' && c <= 'f') { + b = c - 'a' + '\xA'; + } else { + this->ResetBuffer(); + return Invalid; + } + + // make sure the first 2 bytes are the header '6','a' + if (this->byteBuffer.empty() && this->inputBuffer.size() < headerLength && b != header[this->inputBuffer.size()]) { + this->inputBuffer.clear(); + return None; + } + + if (this->inputBuffer.size() == 1) { + this->byteBuffer.push_back((this->inputBuffer.back() << 4) + b); + this->inputBuffer.clear(); + } else + this->inputBuffer.push_back(b); + + if (this->byteBuffer.size() == packetLength) { + // Validate the packet - the last byte should the XOR of the 1st 15. + b = 0; + for (int i = 0, limit = packetLength - 1; i < limit; i++) + b ^= this->byteBuffer[i]; + + if (b != this->byteBuffer.back()) { + // invalid checksum + this->ResetBuffer(); + return Invalid; + } + + return Complete; + } + + return Incomplete; +} + +void trixterxdreamv1client::ConfigureResistanceMessages() { + resistanceMessages = new uint8_t *[251]; + + for (uint8_t level = 0; level <= 250; level++) { + unsigned char *message = new uint8_t[6]; + resistanceMessages[level] = message; + + message[5] = message[0] = 0x6a; + message[5] |= message[1] = level; + message[5] |= message[2] = (level + 60) % 255; + message[5] |= message[3] = (level + 90) % 255; + message[5] |= message[4] = (level + 120) % 255; + } +} + +bool trixterxdreamv1client::ReceiveChar(char c) { + if (this->ProcessChar(c) != Complete) + return false; + + lastPacket.Steering = this->byteBuffer[0x1]; + lastPacket.Flywheel = (static_cast(this->byteBuffer[0xC]) << 8) + this->byteBuffer[0xD]; + lastPacket.Crank = (static_cast(this->byteBuffer[0xA]) << 8) + this->byteBuffer[0xB]; + lastPacket.HeartRate = byteBuffer[0xE]; + + constexpr double millisecondsToBaseUnit = 1024.0 / 1000.0; + constexpr double flywheelToRevolutionsPerMinute = 576000.0; + constexpr double crankToRevolutionsPerMinute = 1.0 / 6e-6; + constexpr double minutesToMilliseconds = 60.0*1000.0; + + double flywheelRevsPerMinute =0, crankRevsPerMinute = 0; + + if (lastPacket.Flywheel < 65534) { + flywheelRevsPerMinute = flywheelToRevolutionsPerMinute / std::max(static_cast(1), lastPacket.Flywheel); + } + + if (lastPacket.Crank > 0 && lastPacket.Crank < 65534) { + crankRevsPerMinute = crankToRevolutionsPerMinute / std::max(static_cast(1), lastPacket.Crank); + } + + const uint32_t t = this->get_time_ms(); + const uint32_t dt = t - this->lastT; + + if (dt <= 0) { + // TODO: error logging - this could be indicative of a problem + // It should usually be about 12ms + this->Reset(); + return false; + } + + // update the internal, precise state + double dt_minutes = dt / minutesToMilliseconds; + this->lastT = t; + this->flywheelRevolutions += dt_minutes * flywheelRevsPerMinute; + this->crankRevolutions += dt_minutes * crankRevsPerMinute; + + state newState{}; + + newState.LastEventTime = static_cast(millisecondsToBaseUnit * t); + newState.Steering = lastPacket.Steering; + newState.HeartRate = lastPacket.HeartRate; + newState.CumulativeCrankRevolutions = static_cast(round(flywheelRevolutions)); + newState.CumulativeWheelRevolutions = static_cast(round(crankRevolutions)); + newState.CrankRPM = static_cast(crankRevsPerMinute); + newState.FlywheelRPM = static_cast(flywheelRevsPerMinute); + + this->stateMutex.lock(); + this->lastState = newState; + this->stateMutex.unlock(); + + return true; +} + +trixterxdreamv1client::state trixterxdreamv1client::getLastState() { + this->stateMutex.lock(); + state result = this->lastState; + this->stateMutex.unlock(); + return result; +} + +void trixterxdreamv1client::SendResistance(int level) { + + // to maintain the resistance, this needs to be resent about every 50ms. + if(level!=0 && this->write_bytes) + { + this->writeMutex.lock(); + try { this->write_bytes(this->resistanceMessages[std::max(250, std::min(0, level))],6); } + catch (...) + { + this->writeMutex.unlock(); + throw; + } + this->writeMutex.unlock(); + } +} + +void trixterxdreamv1client::Reset() { + this->lastT = this->get_time_ms(); + this->flywheelRevolutions = 0.0; + this->crankRevolutions = 0.0; +} diff --git a/src/trixterxdreamv1client.h b/src/trixterxdreamv1client.h new file mode 100644 index 000000000..0f261734b --- /dev/null +++ b/src/trixterxdreamv1client.h @@ -0,0 +1,136 @@ +#pragma once +#include +#include +#include +#include +#include + +class trixterxdreamv1client { + public: + /** + * @brief Device state data: CSCS, heartrate and steering. + */ + struct state { + /** + * @brief Steering Steering value, from 0 (left) to 250 (right) + */ + uint8_t Steering; + + /** + * @brief HeartRate Heart rate in beats per minute. + */ + uint8_t HeartRate; + + /** + * @brief CumulativeWheelRevolutions The number of flywheel revolutions since the last reset event. + */ + uint32_t CumulativeWheelRevolutions; + + /** + * @brief CumulativeCrankRevolutions The number of crank revolutions since the last reset event. + */ + uint16_t CumulativeCrankRevolutions; + + /** + * @brief LastEventTime The time of the last event. Unit: 1/1024 s + */ + uint16_t LastEventTime; + + /** + * @brief FlywheelRPM Flywheel speed. Units: revolutions per minute + */ + uint16_t FlywheelRPM; + + /** + * @brief CrankRPM Crank speed. Units: revolutions per minute + */ + uint16_t CrankRPM; + }; + + private: + unsigned char **resistanceMessages{}; + + enum PacketState { None, Incomplete, Invalid, Complete }; + + /** + * @brief Raw data selected from the incoming packet. + */ + struct Packet { + uint8_t Steering; + uint16_t Flywheel; + uint16_t Crank; + uint8_t HeartRate; + }; + + std::function get_time_ms; + std::function write_bytes; + std::mutex stateMutex, writeMutex; + unsigned long lastT = 0; + double flywheelRevolutions{}, crankRevolutions{}; + Packet lastPacket{}; + std::vector inputBuffer; + std::vector byteBuffer; + state lastState; + + /** + * @brief Clear the input buffer. + */ + void ResetBuffer(); + + /** + * @brief Add the character to the input buffer and process to eventually read the next packet. + * @param c A text character '0'..'9' or 'a'..'f' + */ + PacketState ProcessChar(char c); + + void ConfigureResistanceMessages(); + + public: + /** + * @brief MaxResistance The maximum resistance value supported by the device. + */ + constexpr static uint8_t MaxResistance = 250; + + /** + * @brief The time interval between sending resistance requests to the device. + */ + constexpr static uint8_t ResistancePulseIntervalMilliseconds = 50; + + trixterxdreamv1client(); + + /** + * @brief Receives and processes a character of input from the device. + * @param c Should be '0' to '9' or 'a' to 'f' (lower case) + * @return true if a packet was completed and the state updated, otherwise false. + */ + bool ReceiveChar(char c); + + /** + * @brief set_WriteBytes Sets the function used to write bytes to the serial port. + * @param write_bytes The function that writes bytes to the serial port. + */ + void set_WriteBytes(std::function write_bytes) { this->write_bytes = write_bytes; } + + /** + * @brief set_GetTime Sets the function to get the time in milliseconds since + * a starting point understood by the client. + * @param get_time_ms A function to get the time. + */ + void set_GetTime(std::function get_time_ms) { this->get_time_ms = get_time_ms; } + + /** + * @brief Gets the state of the device as it was last read. This consists of CSCS data, steering and heartbeat. + */ + state getLastState(); + + /** + * @brief Reset the Cycle Speed and Cadence information. + */ + void Reset(); + + /** + * @brief Sends 1 packet indicating a specific resistance level to the device. Needs to be sent every 50ms. + * @param level 0 to 250. + */ + void SendResistance(int level); +}; diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp new file mode 100644 index 000000000..158042981 --- /dev/null +++ b/src/trixterxdreamv1serial.cpp @@ -0,0 +1,84 @@ +#include "trixterxdreamv1serial.h" + +#include +#include +#include + +trixterxdreamv1serial::trixterxdreamv1serial(QObject *parent) : QThread(parent) {} + +trixterxdreamv1serial::~trixterxdreamv1serial() { + m_mutex.lock(); + m_quit = true; + m_mutex.unlock(); + wait(); +} + +QList trixterxdreamv1serial::availablePorts() +{ + return QSerialPortInfo::availablePorts(); +} + +void trixterxdreamv1serial::open(const QString &portName, int waitTimeout) { + const QMutexLocker locker(&m_mutex); + m_portName = portName; + m_waitTimeout = waitTimeout; + if (!isRunning()) + start(); +} + +void trixterxdreamv1serial::write(const uint8_t *buffer, int len, QString info) { + qDebug() << "serial >> " << QByteArray((const char *)buffer, len).toHex(' ') << "//" << info; + qint64 o = serial.write(QByteArray((const char *)buffer, len)); + qDebug() << "serial byte written" << o; +} + +void trixterxdreamv1serial::run() { + + bool currentPortNameChanged = false; + + m_mutex.lock(); + + QString currentPortName; + if (currentPortName != m_portName) { + currentPortName = m_portName; + currentPortNameChanged = true; + } + + int currentWaitTimeout = m_waitTimeout; + m_mutex.unlock(); + + while (!m_quit) { + if (currentPortNameChanged) { + serial.close(); + serial.setPortName(currentPortName); + serial.setBaudRate(QSerialPort::Baud115200); + + if (!serial.open(QIODevice::ReadWrite)) { + qDebug() << tr("Can't open %1, error code %2").arg(m_portName).arg(serial.error()); + emit error(tr("Can't open %1, error code %2").arg(m_portName).arg(serial.error())); + return; + } + qDebug() << "Serial port" << currentPortName << "opened"; + } + + if (serial.waitForReadyRead(currentWaitTimeout)) { + QByteArray requestData = serial.readAll(); + while (serial.waitForReadyRead(1)) + requestData += serial.readAll(); + qDebug() << "serial << " << requestData.toHex(' '); + + // Send the bytes to the client code + if(bytes_read) + bytes_read(requestData); + } + m_mutex.lock(); + if (currentPortName != m_portName) { + currentPortName = m_portName; + currentPortNameChanged = true; + } else { + currentPortNameChanged = false; + } + currentWaitTimeout = m_waitTimeout; + m_mutex.unlock(); + } +} diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h new file mode 100644 index 000000000..6b1d28a99 --- /dev/null +++ b/src/trixterxdreamv1serial.h @@ -0,0 +1,57 @@ +#ifndef TRIXTERXDREAMSERIAL_H +#define TRIXTERXDREAMSERIAL_H + +#include +#include +#include +#include + +class trixterxdreamv1serial : public QThread { + Q_OBJECT + + public: + explicit trixterxdreamv1serial(QObject *parent = nullptr); + ~trixterxdreamv1serial(); + + /** + * @brief Opens the port. + * @param portName The name of the serial port. + * @param waitTimeout The timeout for the serial port. + */ + void open(const QString &portName, int waitTimeout); + + /** + * @brief Writes the array of bytes to the serial port + * @param buffer The bytes to send. + * @param len The number of bytes to send. + * @param info Debug information + */ + void write(const uint8_t *buffer, int len, QString info); + + /** + * @brief Sets the callback function to call when bytes have been read. + * @param bytes_read A callback function to call when a block of bytes has been read. + */ + void set_bytes_read(std::function bytes_read) { this->bytes_read = bytes_read; } + + /** + * @brief availablePorts Returns a list of information objects for the serial ports found in the system. + */ + static QList availablePorts(); +signals: + void request(const QString &s); + void error(const QString &s); + void timeout(const QString &s); + + private: + void run() override; + + QSerialPort serial; + std::function bytes_read; + QString m_portName; + int m_waitTimeout = 1000; + QMutex m_mutex; + bool m_quit = false; +}; + +#endif // TRIXTERXDREAMSERIAL_H From c0beb04cab99488fec86fb464769db4c16271e6d Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 16 Jul 2022 17:21:31 +0100 Subject: [PATCH 009/255] #855 updated project file to include serialport (from dirconn branch) --- src/qdomyos-zwift.pro | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index c2b42f88d..dd363362b 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -2,6 +2,9 @@ QT += bluetooth widgets xml positioning quick networkauth websockets texttospeec QT+= charts +windows: QT += serialport +unix:!android: QT += serialport + unix:android: QT += androidextras gui-private qtHaveModule(httpserver) { QT += httpserver @@ -216,6 +219,9 @@ SOURCES += \ stagesbike.cpp \ toorxtreadmill.cpp \ treadmill.cpp \ + trixterxdreamv1bike.cpp \ + trixterxdreamv1client.cpp \ + trixterxdreamv1serial.cpp \ truetreadmill.cpp \ trxappgateusbbike.cpp \ ultrasportbike.cpp \ @@ -611,6 +617,9 @@ HEADERS += \ treadmill.h \ mainwindow.h \ trainprogram.h \ + trixterxdreamv1bike.h \ + trixterxdreamv1client.h \ + trixterxdreamv1serial.h \ truetreadmill.h \ trxappgateusbbike.h \ trxappgateusbtreadmill.h \ From 2ef3cd23bf0717c3e8ca093bad39c20a7f828fde Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 16 Jul 2022 23:39:52 +0100 Subject: [PATCH 010/255] #855 fixes to trixterxdreamv1client --- src/trixterxdreamv1client.cpp | 60 ++++++++++++++++++++++------------- src/trixterxdreamv1client.h | 23 +++++++++----- 2 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp index 1c1ab7bed..ab417a1df 100644 --- a/src/trixterxdreamv1client.cpp +++ b/src/trixterxdreamv1client.cpp @@ -1,8 +1,9 @@ - +//#include "pch.h" #include "trixterxdreamv1client.h" #include #include +//#include trixterxdreamv1client::trixterxdreamv1client() { this->ConfigureResistanceMessages(); } @@ -37,15 +38,17 @@ trixterxdreamv1client::PacketState trixterxdreamv1client::ProcessChar(char c) { constexpr int headerLength = 2; constexpr int packetLength = 16; - constexpr uint8_t header[] = {0x6, 0xA}; + constexpr uint8_t header[] = { 0x6, 0xA }; uint8_t b; if (isdigit(c)) { b = c - '0'; - } else if (c >= 'a' && c <= 'f') { + } + else if (c >= 'a' && c <= 'f') { b = c - 'a' + '\xA'; - } else { + } + else { this->ResetBuffer(); return Invalid; } @@ -59,7 +62,8 @@ trixterxdreamv1client::PacketState trixterxdreamv1client::ProcessChar(char c) { if (this->inputBuffer.size() == 1) { this->byteBuffer.push_back((this->inputBuffer.back() << 4) + b); this->inputBuffer.clear(); - } else + } + else this->inputBuffer.push_back(b); if (this->byteBuffer.size() == packetLength) { @@ -81,10 +85,10 @@ trixterxdreamv1client::PacketState trixterxdreamv1client::ProcessChar(char c) { } void trixterxdreamv1client::ConfigureResistanceMessages() { - resistanceMessages = new uint8_t *[251]; + resistanceMessages = new uint8_t * [251]; for (uint8_t level = 0; level <= 250; level++) { - unsigned char *message = new uint8_t[6]; + unsigned char* message = new uint8_t[6]; resistanceMessages[level] = message; message[5] = message[0] = 0x6a; @@ -104,39 +108,51 @@ bool trixterxdreamv1client::ReceiveChar(char c) { lastPacket.Crank = (static_cast(this->byteBuffer[0xA]) << 8) + this->byteBuffer[0xB]; lastPacket.HeartRate = byteBuffer[0xE]; + // got the data, now clear the buffer + this->ResetBuffer(); + constexpr double millisecondsToBaseUnit = 1024.0 / 1000.0; constexpr double flywheelToRevolutionsPerMinute = 576000.0; constexpr double crankToRevolutionsPerMinute = 1.0 / 6e-6; - constexpr double minutesToMilliseconds = 60.0*1000.0; + constexpr double minutesToMilliseconds = 60.0 * 1000.0; - double flywheelRevsPerMinute =0, crankRevsPerMinute = 0; + double flywheelRevsPerMinute = 0, crankRevsPerMinute = 0; if (lastPacket.Flywheel < 65534) { - flywheelRevsPerMinute = flywheelToRevolutionsPerMinute / std::max(static_cast(1), lastPacket.Flywheel); + flywheelRevsPerMinute = flywheelToRevolutionsPerMinute / max(static_cast(1), lastPacket.Flywheel); } if (lastPacket.Crank > 0 && lastPacket.Crank < 65534) { - crankRevsPerMinute = crankToRevolutionsPerMinute / std::max(static_cast(1), lastPacket.Crank); + crankRevsPerMinute = crankToRevolutionsPerMinute / max(static_cast(1), lastPacket.Crank); } + const uint32_t t = this->get_time_ms(); - const uint32_t dt = t - this->lastT; + const uint32_t lt = this->lastT ? this->lastT : t; - if (dt <= 0) { + this->lastT = t; + + if(tReset(); return false; } - // update the internal, precise state - double dt_minutes = dt / minutesToMilliseconds; - this->lastT = t; - this->flywheelRevolutions += dt_minutes * flywheelRevsPerMinute; - this->crankRevolutions += dt_minutes * crankRevsPerMinute; + const uint32_t dt = t - lt; + + if (dt > 0) + { + // update the internal, precise state + double dt_minutes = dt / minutesToMilliseconds; - state newState{}; + this->flywheelRevolutions += dt_minutes * flywheelRevsPerMinute; + this->crankRevolutions += dt_minutes * crankRevsPerMinute; + } + state newState{}; newState.LastEventTime = static_cast(millisecondsToBaseUnit * t); newState.Steering = lastPacket.Steering; newState.HeartRate = lastPacket.HeartRate; @@ -159,13 +175,13 @@ trixterxdreamv1client::state trixterxdreamv1client::getLastState() { return result; } -void trixterxdreamv1client::SendResistance(int level) { +void trixterxdreamv1client::SendResistance(uint8_t level) { // to maintain the resistance, this needs to be resent about every 50ms. - if(level!=0 && this->write_bytes) + if (level != 0 && this->write_bytes) { this->writeMutex.lock(); - try { this->write_bytes(this->resistanceMessages[std::max(250, std::min(0, level))],6); } + try { this->write_bytes(this->resistanceMessages[max(250, min(0, level))], 6); } catch (...) { this->writeMutex.unlock(); diff --git a/src/trixterxdreamv1client.h b/src/trixterxdreamv1client.h index 0f261734b..210b9909c 100644 --- a/src/trixterxdreamv1client.h +++ b/src/trixterxdreamv1client.h @@ -3,10 +3,17 @@ #include #include #include +//#include #include +/** + * @brief Basic functionality to interpret character data read from a Trixter X-Dream V1 bike via a serial port. + * Intended to be free from any non-standard C++ library code. + * Requires a time source callback (set_getTime) to timestamp packets and optionally + * a callback to write resistance packets to the serial port. + */ class trixterxdreamv1client { - public: +public: /** * @brief Device state data: CSCS, heartrate and steering. */ @@ -47,8 +54,8 @@ class trixterxdreamv1client { uint16_t CrankRPM; }; - private: - unsigned char **resistanceMessages{}; +private: + unsigned char** resistanceMessages{}; enum PacketState { None, Incomplete, Invalid, Complete }; @@ -63,9 +70,9 @@ class trixterxdreamv1client { }; std::function get_time_ms; - std::function write_bytes; + std::function write_bytes; std::mutex stateMutex, writeMutex; - unsigned long lastT = 0; + uint32_t lastT = 0; double flywheelRevolutions{}, crankRevolutions{}; Packet lastPacket{}; std::vector inputBuffer; @@ -85,7 +92,7 @@ class trixterxdreamv1client { void ConfigureResistanceMessages(); - public: +public: /** * @brief MaxResistance The maximum resistance value supported by the device. */ @@ -109,7 +116,7 @@ class trixterxdreamv1client { * @brief set_WriteBytes Sets the function used to write bytes to the serial port. * @param write_bytes The function that writes bytes to the serial port. */ - void set_WriteBytes(std::function write_bytes) { this->write_bytes = write_bytes; } + void set_WriteBytes(std::function write_bytes) { this->write_bytes = write_bytes; } /** * @brief set_GetTime Sets the function to get the time in milliseconds since @@ -132,5 +139,5 @@ class trixterxdreamv1client { * @brief Sends 1 packet indicating a specific resistance level to the device. Needs to be sent every 50ms. * @param level 0 to 250. */ - void SendResistance(int level); + void SendResistance(uint8_t level); }; From 5294792dc10bb38e78c7e953eafea64f8f2b3859 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 16 Jul 2022 23:53:04 +0100 Subject: [PATCH 011/255] #855 adjustments to time and resistance code --- src/trixterxdreamv1bike.cpp | 11 +++++++++-- src/trixterxdreamv1client.cpp | 9 ++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index d3fe5e238..0515eae45 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -6,7 +6,7 @@ trixterxdreamv1bike::trixterxdreamv1bike(QString portName, bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) { // Set the wheel diameter for speed and distance calculations - this->set_wheelDiameter(DefaultWheelDiamter); + this->set_wheelDiameter(DefaultWheelDiameter); // QZ things from expected constructor this->noWriteResistance = noWriteResistance; @@ -16,7 +16,7 @@ trixterxdreamv1bike::trixterxdreamv1bike(QString portName, bool noWriteResistanc // Get the current time in milliseconds since ancient times. // This will be subtracted from further readings from getTime() to get an easier to look at number. - this->t0 = QDateTime::currentDateTime().toMSecsSinceEpoch(); + this->t0 = this->getTime(); // References to objects for callbacks auto thisObject = this; @@ -68,6 +68,12 @@ QString trixterxdreamv1bike::findPort() return nullptr; } +bool trixterxdreamv1bike::connected() +{ + return (this->getTime()-this->lastPacketProcessedTime) < DisconnectionTimeout; +} + + uint32_t trixterxdreamv1bike::getTime() { return static_cast(QDateTime::currentDateTime().toMSecsSinceEpoch() - this->t0); @@ -94,6 +100,7 @@ void trixterxdreamv1bike::update(QByteArray bytes) // update the packet count this->packetsProcessed++; + this->lastPacketProcessedTime = this->getTime(); // update the metrics this->LastCrankEventTime = state.LastEventTime; diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp index ab417a1df..b2fbec0e9 100644 --- a/src/trixterxdreamv1client.cpp +++ b/src/trixterxdreamv1client.cpp @@ -2,8 +2,7 @@ #include "trixterxdreamv1client.h" #include -#include -//#include +#include trixterxdreamv1client::trixterxdreamv1client() { this->ConfigureResistanceMessages(); } @@ -119,11 +118,11 @@ bool trixterxdreamv1client::ReceiveChar(char c) { double flywheelRevsPerMinute = 0, crankRevsPerMinute = 0; if (lastPacket.Flywheel < 65534) { - flywheelRevsPerMinute = flywheelToRevolutionsPerMinute / max(static_cast(1), lastPacket.Flywheel); + flywheelRevsPerMinute = flywheelToRevolutionsPerMinute / std::max(static_cast(1), lastPacket.Flywheel); } if (lastPacket.Crank > 0 && lastPacket.Crank < 65534) { - crankRevsPerMinute = crankToRevolutionsPerMinute / max(static_cast(1), lastPacket.Crank); + crankRevsPerMinute = crankToRevolutionsPerMinute / std::max(static_cast(1), lastPacket.Crank); } @@ -181,7 +180,7 @@ void trixterxdreamv1client::SendResistance(uint8_t level) { if (level != 0 && this->write_bytes) { this->writeMutex.lock(); - try { this->write_bytes(this->resistanceMessages[max(250, min(0, level))], 6); } + try { this->write_bytes(this->resistanceMessages[std::min(MaxResistance, level)], 6); } catch (...) { this->writeMutex.unlock(); From 9f3ef9536eb12a81d0fcd00c3c02d97f4c3de330 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 17 Jul 2022 01:02:16 +0100 Subject: [PATCH 012/255] #855 header adjustments --- src/trixterxdreamv1client.cpp | 28 +++++++++++++++------------- src/trixterxdreamv1client.h | 8 +++----- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp index b2fbec0e9..97a1d3577 100644 --- a/src/trixterxdreamv1client.cpp +++ b/src/trixterxdreamv1client.cpp @@ -4,6 +4,8 @@ #include #include +using namespace std; + trixterxdreamv1client::trixterxdreamv1client() { this->ConfigureResistanceMessages(); } void trixterxdreamv1client::ResetBuffer() { @@ -87,14 +89,14 @@ void trixterxdreamv1client::ConfigureResistanceMessages() { resistanceMessages = new uint8_t * [251]; for (uint8_t level = 0; level <= 250; level++) { - unsigned char* message = new uint8_t[6]; + uint8_t* message = new uint8_t[6]; resistanceMessages[level] = message; message[5] = message[0] = 0x6a; - message[5] |= message[1] = level; - message[5] |= message[2] = (level + 60) % 255; - message[5] |= message[3] = (level + 90) % 255; - message[5] |= message[4] = (level + 120) % 255; + message[5] ^= message[1] = level; + message[5] ^= message[2] = (level + 60) % 255; + message[5] ^= message[3] = (level + 90) % 255; + message[5] ^= message[4] = (level + 120) % 255; } } @@ -118,14 +120,14 @@ bool trixterxdreamv1client::ReceiveChar(char c) { double flywheelRevsPerMinute = 0, crankRevsPerMinute = 0; if (lastPacket.Flywheel < 65534) { - flywheelRevsPerMinute = flywheelToRevolutionsPerMinute / std::max(static_cast(1), lastPacket.Flywheel); + flywheelRevsPerMinute = flywheelToRevolutionsPerMinute / max(static_cast(1), lastPacket.Flywheel); } if (lastPacket.Crank > 0 && lastPacket.Crank < 65534) { - crankRevsPerMinute = crankToRevolutionsPerMinute / std::max(static_cast(1), lastPacket.Crank); + crankRevsPerMinute = crankToRevolutionsPerMinute / max(static_cast(1), lastPacket.Crank); } - + const uint32_t t = this->get_time_ms(); const uint32_t lt = this->lastT ? this->lastT : t; @@ -135,13 +137,13 @@ bool trixterxdreamv1client::ReceiveChar(char c) { { // TODO: error logging - this could be indicative of a problem // It should usually be about 12ms - + this->Reset(); return false; } const uint32_t dt = t - lt; - + if (dt > 0) { // update the internal, precise state @@ -151,7 +153,7 @@ bool trixterxdreamv1client::ReceiveChar(char c) { this->crankRevolutions += dt_minutes * crankRevsPerMinute; } - state newState{}; + state newState{}; newState.LastEventTime = static_cast(millisecondsToBaseUnit * t); newState.Steering = lastPacket.Steering; newState.HeartRate = lastPacket.HeartRate; @@ -169,7 +171,7 @@ bool trixterxdreamv1client::ReceiveChar(char c) { trixterxdreamv1client::state trixterxdreamv1client::getLastState() { this->stateMutex.lock(); - state result = this->lastState; + const state result = this->lastState; this->stateMutex.unlock(); return result; } @@ -180,7 +182,7 @@ void trixterxdreamv1client::SendResistance(uint8_t level) { if (level != 0 && this->write_bytes) { this->writeMutex.lock(); - try { this->write_bytes(this->resistanceMessages[std::min(MaxResistance, level)], 6); } + try { this->write_bytes(this->resistanceMessages[min(MaxResistance, level)], 6); } catch (...) { this->writeMutex.unlock(); diff --git a/src/trixterxdreamv1client.h b/src/trixterxdreamv1client.h index 210b9909c..b227e89fb 100644 --- a/src/trixterxdreamv1client.h +++ b/src/trixterxdreamv1client.h @@ -1,9 +1,7 @@ #pragma once -#include #include -#include -#include -//#include +#include +#include #include /** @@ -55,7 +53,7 @@ class trixterxdreamv1client { }; private: - unsigned char** resistanceMessages{}; + uint8_t** resistanceMessages{}; enum PacketState { None, Incomplete, Invalid, Complete }; From eb4c5f5255e6db99dc042c5ae0208d457825d497 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 17 Jul 2022 01:14:47 +0100 Subject: [PATCH 013/255] #855 implemented connected() --- src/trixterxdreamv1bike.cpp | 4 ++-- src/trixterxdreamv1bike.h | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 0515eae45..782639ef0 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -45,8 +45,8 @@ bool trixterxdreamv1bike::testPort(const QString& portName) try { trixterxdreamv1bike bike(portName, true, true, true, true); // minimal device - QThread::msleep(1000); - return bike.packetsProcessed>10; // >0 is probably okay, they should arrive every approx 12ms + QThread::msleep(500); + return bike.connected(); } catch (...) { diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 604a1d0bf..a680ca9c1 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -64,9 +64,13 @@ class trixterxdreamv1bike : public bike */ uint32_t packetsProcessed; + /** + * @brief lastPacketProcessedTime The last time (from getTime()) a packet was processed. + */ + uint32_t lastPacketProcessedTime; + /** * @brief getTime Gets the time in miliseconds since this object was created. - * @return The number of milliseconds since this object was created. */ uint32_t getTime(); @@ -123,6 +127,11 @@ public Q_SLOTS: */ constexpr static double DefaultWheelDiamter = 26*0.0254; + /** + * @brief DisconnectionTimeout The number of milliseconds of no packets processed required before + * this object will be considered disconnected from the device. + */ + constexpr static int32_t DisconnectionTimeout = 50; /** * @brief trixterxdreamv1bike Constructor @@ -136,6 +145,11 @@ public Q_SLOTS: ~trixterxdreamv1bike(); + /** + * @brief connected Indicates if a valid packet was received from the device within the DisconnectionTimeout. + */ + virtual bool connected(); + /** * @brief set_wheelDiameter Set the simulated wheel diameter to be used for converting angular velocity to speed. Units: meters * @param value From 487a3980294277d6718a10c6ad4912533e8c5f73 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 17 Jul 2022 01:15:59 +0100 Subject: [PATCH 014/255] #855 fix typo --- src/trixterxdreamv1bike.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index a680ca9c1..5bfd8ed6e 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -125,7 +125,7 @@ public Q_SLOTS: /** * @brief DefaultWheelDiameter The default wheel diameter. Unit: meters */ - constexpr static double DefaultWheelDiamter = 26*0.0254; + constexpr static double DefaultWheelDiameter = 26*0.0254; /** * @brief DisconnectionTimeout The number of milliseconds of no packets processed required before From c2859258b3842dc706d1e1aae340becb865688fe Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 29 Jul 2022 22:26:39 +0100 Subject: [PATCH 015/255] #855 adjustments after getting some packets from the serial port via the "business logic". Added the detector to the bluetooth class. --- src/bluetooth.cpp | 26 ++++++++++++++++++++++++++ src/bluetooth.h | 2 ++ src/settings.qml | 4 ++++ src/trixterxdreamv1bike.cpp | 30 +++++++++++++++++++++--------- src/trixterxdreamv1bike.h | 26 ++++++++++++++++++++++---- src/trixterxdreamv1client.cpp | 6 ++++-- src/trixterxdreamv1client.h | 6 +++--- 7 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 3fd8acad2..3032f71f7 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -337,6 +337,8 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { QString proformtdf4ip = settings.value(QStringLiteral("proformtdf4ip"), "").toString(); QString nordictrack_2950_ip = settings.value(QStringLiteral("nordictrack_2950_ip"), "").toString(); + bool trixterxdreamv1bikeEnabled = settings.value(QStringLiteral("trixter_xdream_v1_bike")).toBool(); + if (!heartRateBeltFound) { heartRateBeltFound = heartRateBeltAvaiable(); @@ -394,6 +396,30 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } #endif + if(trixterxdreamv1bikeEnabled) + { + QString port = trixterxdreamv1bike::findPort(); + + if(port != nullptr) + { + discoveryAgent->stop(); + trixterxdreamv1bike = new class trixterxdreamv1bike(noWriteResistance, noHeartService, false,false); + if(trixterxdreamv1bike->connect(port)) + { + connect(trixterxdreamv1bike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); + // connect(cscBike, SIGNAL(disconnected()), this, SLOT(restart())); + //connect(trixterxdreamv1bike, &trixterxdreamv1bike::debug, this, &bluetooth::debug); + if (!discoveryAgent->isActive()) { + emit searchingStop(); + } + userTemplateManager->start(trixterxdreamv1bike); + innerTemplateManager->start(trixterxdreamv1bike); + } + else + delete trixterxdreamv1bike; + } + } + if ((heartRateBeltFound && ftmsAccessoryFound && cscFound && powerSensorFound && eliteRizerFound && eliteSterzoSmartFound) || forceHeartBeltOffForTimeout) { diff --git a/src/bluetooth.h b/src/bluetooth.h index c8174c7ce..12198563b 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -96,6 +96,7 @@ #include "templateinfosenderbuilder.h" #include "toorxtreadmill.h" #include "treadmill.h" +#include "trixterxdreamv1bike.h" #include "truetreadmill.h" #include "trxappgateusbbike.h" #include "trxappgateusbtreadmill.h" @@ -205,6 +206,7 @@ class bluetooth : public QObject, public SignalHandler { fakeelliptical *fakeElliptical = nullptr; QList fitmetriaFanfit; QString filterDevice = QLatin1String(""); + trixterxdreamv1bike * trixterxdreamv1bike = nullptr; bool testResistance = false; bool noWriteResistance = false; diff --git a/src/settings.qml b/src/settings.qml index 8222dd75a..cb2cd60bf 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -449,6 +449,10 @@ import Qt.labs.settings 1.0 // from the version 2.10.112 property real ss2k_max_resistance: 100 property real ss2k_min_resistance: 0 + + + + property bool trixter_xdream_v1_bike: true } function paddingZeros(text, limit) { diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 782639ef0..6c89e1a8b 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -1,9 +1,10 @@ #include "trixterxdreamv1bike.h" -#include +#include +#include #include -trixterxdreamv1bike::trixterxdreamv1bike(QString portName, bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) +trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) { // Set the wheel diameter for speed and distance calculations this->set_wheelDiameter(DefaultWheelDiameter); @@ -13,7 +14,10 @@ trixterxdreamv1bike::trixterxdreamv1bike(QString portName, bool noWriteResistanc this->noHeartService = noHeartService; this->noVirtualDevice = noVirtualDevice; this->noSteering = noSteering; +} +bool trixterxdreamv1bike::connect(QString portName) +{ // Get the current time in milliseconds since ancient times. // This will be subtracted from further readings from getTime() to get an easier to look at number. this->t0 = this->getTime(); @@ -37,16 +41,19 @@ trixterxdreamv1bike::trixterxdreamv1bike(QString portName, bool noWriteResistanc // create the timer for the resistance. This only needs to be active when a non-zero resistance is requested. this->resistanceTimer = new QTimer(this); - connect(this->resistanceTimer, &QTimer::timeout, this, &trixterxdreamv1bike::updateResistance); + bike::connect(this->resistanceTimer, &QTimer::timeout, this, &trixterxdreamv1bike::updateResistance); + + // wait for some packets to arrive + QThread::msleep(500); + return this->connected(); } bool trixterxdreamv1bike::testPort(const QString& portName) { try { - trixterxdreamv1bike bike(portName, true, true, true, true); // minimal device - QThread::msleep(500); - return bike.connected(); + trixterxdreamv1bike bike(true, true, true, true); // minimal device + return bike.connect(portName); } catch (...) { @@ -122,7 +129,7 @@ void trixterxdreamv1bike::update(QByteArray bytes) // Set the steering if(!this->noSteering) - this->currentSteeringAngle().setValue(90.0 / 250.0 * state.Steering -45.0); + this->m_steeringAngle.setValue(90.0 / 250.0 * state.Steering -45.0); } @@ -149,10 +156,15 @@ void trixterxdreamv1bike::updateResistance() trixterxdreamv1bike::~trixterxdreamv1bike() { - this->resistanceTimer->stop(); + if(this->resistanceTimer) + { + this->resistanceTimer->stop(); + delete this->resistanceTimer; + } + this->port.quit(); - delete this->resistanceTimer; + } void trixterxdreamv1bike::set_wheelDiameter(double value) diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 5bfd8ed6e..2b6824a8d 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -69,14 +69,21 @@ class trixterxdreamv1bike : public bike */ uint32_t lastPacketProcessedTime; + /** + * @brief updateMutex Mutex to syncronize access to + */ + QMutex updateMutex; + + + uint32_t updatesInProgress = 0; + /** * @brief getTime Gets the time in miliseconds since this object was created. */ uint32_t getTime(); /** - * @brief Temporary method to contain what happens when a new block of data comes in - * from the data source (serial port). + * @brief Called by the data source (serial port) when a new block of data arrives. */ void update(QByteArray bytes); @@ -133,18 +140,29 @@ public Q_SLOTS: */ constexpr static int32_t DisconnectionTimeout = 50; + + /** + * @brief SettingsIdentifier The identifier for this device in the QDomyos settings. + */ + inline static const std::string SettingsIdentifier = "trixter-xdream-v1"; + /** * @brief trixterxdreamv1bike Constructor - * @param portName The name of the serial port to connect to. * @param noWriteResistance Option to avoid sending resistance to the device. * @param noHeartService Option to avoid using the heart rate reading. * @param noVirtualDevice Option to avoid using a virtual device. * @param noSteering Option to avoid using the steering reading. */ - trixterxdreamv1bike(QString portName, bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering); + trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering); ~trixterxdreamv1bike(); + /** + * @brief connect Attempt to connect to the specified port. + * @param portName The name of the serial port to connect to. + */ + bool connect(QString portName); + /** * @brief connected Indicates if a valid packet was received from the device within the DisconnectionTimeout. */ diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp index 97a1d3577..88b3c1e07 100644 --- a/src/trixterxdreamv1client.cpp +++ b/src/trixterxdreamv1client.cpp @@ -6,7 +6,9 @@ using namespace std; -trixterxdreamv1client::trixterxdreamv1client() { this->ConfigureResistanceMessages(); } +trixterxdreamv1client::trixterxdreamv1client() { + this->ConfigureResistanceMessages(); +} void trixterxdreamv1client::ResetBuffer() { // for the case of an invalid packet, if this was smart, it would store all the input @@ -178,7 +180,7 @@ trixterxdreamv1client::state trixterxdreamv1client::getLastState() { void trixterxdreamv1client::SendResistance(uint8_t level) { - // to maintain the resistance, this needs to be resent about every 50ms. + // to maintain the resistance, this needs to be resent about every 10ms if (level != 0 && this->write_bytes) { this->writeMutex.lock(); diff --git a/src/trixterxdreamv1client.h b/src/trixterxdreamv1client.h index b227e89fb..dc90598c6 100644 --- a/src/trixterxdreamv1client.h +++ b/src/trixterxdreamv1client.h @@ -73,7 +73,7 @@ class trixterxdreamv1client { uint32_t lastT = 0; double flywheelRevolutions{}, crankRevolutions{}; Packet lastPacket{}; - std::vector inputBuffer; + std::vector inputBuffer; std::vector byteBuffer; state lastState; @@ -99,7 +99,7 @@ class trixterxdreamv1client { /** * @brief The time interval between sending resistance requests to the device. */ - constexpr static uint8_t ResistancePulseIntervalMilliseconds = 50; + constexpr static uint8_t ResistancePulseIntervalMilliseconds = 10; trixterxdreamv1client(); @@ -134,7 +134,7 @@ class trixterxdreamv1client { void Reset(); /** - * @brief Sends 1 packet indicating a specific resistance level to the device. Needs to be sent every 50ms. + * @brief Sends 1 packet indicating a specific resistance level to the device. Needs to be sent at the rate specified by ResistancePulseIntervalMilliseconds. * @param level 0 to 250. */ void SendResistance(uint8_t level); From b3d5163effd6edf68ce13a00e5ebd8c147a997e8 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 30 Jul 2022 01:17:19 +0100 Subject: [PATCH 016/255] #855 use a signal and slot to received serial data instead of delegate - slot doesn't get called. --- src/trixterxdreamv1bike.cpp | 18 ++++++++++-------- src/trixterxdreamv1bike.h | 11 ++++++----- src/trixterxdreamv1serial.cpp | 6 ++++-- src/trixterxdreamv1serial.h | 7 ------- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 6c89e1a8b..f6060f6b9 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -14,6 +14,11 @@ trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartSer this->noHeartService = noHeartService; this->noVirtualDevice = noVirtualDevice; this->noSteering = noSteering; + + if(!bike::connect(&this->port, &trixterxdreamv1serial::request, this, &trixterxdreamv1bike::update)) + { + throw "Failed to connect to request slot"; + } } bool trixterxdreamv1bike::connect(QString portName) @@ -33,9 +38,6 @@ bool trixterxdreamv1bike::connect(QString portName) if(!noWriteResistance) this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(bytes, length, "");}); - // tell the serial port where to send incoming data blocks - this->port.set_bytes_read([&thisObject](QByteArray bytes) -> void {thisObject->update(bytes); }); - // open the port. This should be at 115200 bits per second. this->port.open(portName, 1000); @@ -86,20 +88,20 @@ uint32_t trixterxdreamv1bike::getTime() return static_cast(QDateTime::currentDateTime().toMSecsSinceEpoch() - this->t0); } -bool trixterxdreamv1bike::updateClient(QByteArray bytes, trixterxdreamv1client * client) +bool trixterxdreamv1bike::updateClient(const QString& s, trixterxdreamv1client * client) { bool stateChanged = false; - for(int i=0; iReceiveChar(bytes[i]); + for(int i=0; iReceiveChar(s[i].toLatin1()); return stateChanged; } -void trixterxdreamv1bike::update(QByteArray bytes) +void trixterxdreamv1bike::update(const QString &s) { // send the bytes to the client and return if there's no change of state - if(!updateClient(bytes, &this->client)) + if(!updateClient(s, &this->client)) return; // Take the most recent state read diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 2b6824a8d..57791cf57 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -82,10 +82,6 @@ class trixterxdreamv1bike : public bike */ uint32_t getTime(); - /** - * @brief Called by the data source (serial port) when a new block of data arrives. - */ - void update(QByteArray bytes); /** * @brief updateResistance Called by the resistanceTimer to send the resistence request to the @@ -99,7 +95,7 @@ class trixterxdreamv1bike : public bike * @param client The client object that interprets the incoming bytes into data packets. * @return True if the state of the client changed due to the input. */ - static bool updateClient(QByteArray bytes, trixterxdreamv1client * client); + static bool updateClient(const QString &s, trixterxdreamv1client * client); /** * @brief testPort Tries to open a port and looks for valid data packets. @@ -117,6 +113,11 @@ public Q_SLOTS: */ virtual void changeResistance(int8_t resistanceLevel); + /** + * @brief Called by the data source (serial port) when a new block of data arrives. + */ + void update(const QString& s); + public: /** diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 158042981..80c8ac349 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -68,8 +68,10 @@ void trixterxdreamv1serial::run() { qDebug() << "serial << " << requestData.toHex(' '); // Send the bytes to the client code - if(bytes_read) - bytes_read(requestData); + if(requestData.length()>0) { + const QString request = QString::fromUtf8(requestData); + emit this->request(request); + } } m_mutex.lock(); if (currentPortName != m_portName) { diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index 6b1d28a99..e23990c87 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -28,12 +28,6 @@ class trixterxdreamv1serial : public QThread { */ void write(const uint8_t *buffer, int len, QString info); - /** - * @brief Sets the callback function to call when bytes have been read. - * @param bytes_read A callback function to call when a block of bytes has been read. - */ - void set_bytes_read(std::function bytes_read) { this->bytes_read = bytes_read; } - /** * @brief availablePorts Returns a list of information objects for the serial ports found in the system. */ @@ -47,7 +41,6 @@ class trixterxdreamv1serial : public QThread { void run() override; QSerialPort serial; - std::function bytes_read; QString m_portName; int m_waitTimeout = 1000; QMutex m_mutex; From fc725497d2cd185f3b6be7e58d164c67b2ddb45a Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 30 Jul 2022 17:18:09 +0100 Subject: [PATCH 017/255] #855 - bike now detected in bluetooth class - adjustments to avoid seg faults - changed port finding strategy to return the connected bike object --- src/bluetooth.cpp | 45 +++++++++-------- src/bluetooth.h | 7 +++ src/trixterxdreamv1bike.cpp | 93 ++++++++++++++++++++--------------- src/trixterxdreamv1bike.h | 44 ++++++++--------- src/trixterxdreamv1client.cpp | 8 ++- src/trixterxdreamv1client.h | 7 +-- 6 files changed, 113 insertions(+), 91 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 3032f71f7..a68067582 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -41,6 +41,7 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc this->innerTemplateManager = TemplateInfoSenderBuilder::getInstance(innerId, QStringList({QStringLiteral(":/inner_templates/")}), this); + #ifdef TEST schwinnIC4Bike = (schwinnic4bike *)new bike(); userTemplateManager->start(schwinnIC4Bike); @@ -197,6 +198,17 @@ void bluetooth::debug(const QString &text) { } } + +trixterxdreamv1bike * bluetooth::findTrixterXDreamV1Bike(const QSettings& settings) +{ + bool trixterxdreamv1bikeEnabled = settings.value(QStringLiteral("trixter_xdream_v1_bike")).toBool(); + + if(trixterxdreamv1bikeEnabled) + return trixterxdreamv1bike::tryCreate(this->noWriteResistance, this->noHeartService, false, false); + + return nullptr; +} + bool bluetooth::cscSensorAvaiable() { QSettings settings; @@ -337,7 +349,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { QString proformtdf4ip = settings.value(QStringLiteral("proformtdf4ip"), "").toString(); QString nordictrack_2950_ip = settings.value(QStringLiteral("nordictrack_2950_ip"), "").toString(); - bool trixterxdreamv1bikeEnabled = settings.value(QStringLiteral("trixter_xdream_v1_bike")).toBool(); + if (!heartRateBeltFound) { @@ -386,6 +398,15 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { qDebug() << device.deviceUuid(); #endif + // Try to connect to a Trixter X-Dream V1 bike if the setting is enabled. + this->trixterxdreamv1bike = this->findTrixterXDreamV1Bike(settings); + if(this->trixterxdreamv1bike) { + this->userTemplateManager->start(trixterxdreamv1bike); + this->innerTemplateManager->start(trixterxdreamv1bike); + this->connectedAndDiscovered(); + return; + } + if (onlyDiscover) return; @@ -396,29 +417,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } #endif - if(trixterxdreamv1bikeEnabled) - { - QString port = trixterxdreamv1bike::findPort(); - if(port != nullptr) - { - discoveryAgent->stop(); - trixterxdreamv1bike = new class trixterxdreamv1bike(noWriteResistance, noHeartService, false,false); - if(trixterxdreamv1bike->connect(port)) - { - connect(trixterxdreamv1bike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); - // connect(cscBike, SIGNAL(disconnected()), this, SLOT(restart())); - //connect(trixterxdreamv1bike, &trixterxdreamv1bike::debug, this, &bluetooth::debug); - if (!discoveryAgent->isActive()) { - emit searchingStop(); - } - userTemplateManager->start(trixterxdreamv1bike); - innerTemplateManager->start(trixterxdreamv1bike); - } - else - delete trixterxdreamv1bike; - } - } if ((heartRateBeltFound && ftmsAccessoryFound && cscFound && powerSensorFound && eliteRizerFound && eliteSterzoSmartFound) || diff --git a/src/bluetooth.h b/src/bluetooth.h index 12198563b..a8575c244 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -229,6 +229,13 @@ class bluetooth : public QObject, public SignalHandler { bool eliteSterzoSmartAvaiable(); bool fitmetria_fanfit_isconnected(QString name); + /** + * @brief findTrixterXDreamV1Bike Searches serial ports for a Trixter X-Dream V1 Bike + * @param settings The application settings. + * @return A trixterxdreamv1bike object if a bike has been found, nullptr otherwise. + */ + class trixterxdreamv1bike * findTrixterXDreamV1Bike(const QSettings& settings); + #ifdef Q_OS_WIN QTimer discoveryTimeout; #endif diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index f6060f6b9..954e7e26d 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -3,7 +3,6 @@ #include #include - trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) { // Set the wheel diameter for speed and distance calculations @@ -14,22 +13,28 @@ trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartSer this->noHeartService = noHeartService; this->noVirtualDevice = noVirtualDevice; this->noSteering = noSteering; - - if(!bike::connect(&this->port, &trixterxdreamv1serial::request, this, &trixterxdreamv1bike::update)) - { - throw "Failed to connect to request slot"; - } } bool trixterxdreamv1bike::connect(QString portName) { + if(this->port) delete this->port; + if(this->resistanceTimer) delete this->resistanceTimer; + // Get the current time in milliseconds since ancient times. // This will be subtracted from further readings from getTime() to get an easier to look at number. this->t0 = this->getTime(); + // create the port object and connect it + this->port = new trixterxdreamv1serial(this); + this->moveToThread(this->port); // this appears to be necessary for the slot to be called + if(!bike::connect(this->port, &trixterxdreamv1serial::request, this, &trixterxdreamv1bike::update)) + { + throw "Failed to connect to request slot"; + } + // References to objects for callbacks auto thisObject = this; - auto device=&this->port; + auto device=this->port; // tell the client where to get the time this->client.set_GetTime([&thisObject]()->uint32_t { return thisObject->getTime();} ); @@ -39,7 +44,7 @@ bool trixterxdreamv1bike::connect(QString portName) this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(bytes, length, "");}); // open the port. This should be at 115200 bits per second. - this->port.open(portName, 1000); + this->port->open(portName, 1000); // create the timer for the resistance. This only needs to be active when a non-zero resistance is requested. this->resistanceTimer = new QTimer(this); @@ -50,33 +55,6 @@ bool trixterxdreamv1bike::connect(QString portName) return this->connected(); } -bool trixterxdreamv1bike::testPort(const QString& portName) -{ - try - { - trixterxdreamv1bike bike(true, true, true, true); // minimal device - return bike.connect(portName); - } - catch (...) - { - return false; - } - -} - -QString trixterxdreamv1bike::findPort() -{ - auto availablePorts = trixterxdreamv1serial::availablePorts(); - - for(int i=0; igetTime()-this->lastPacketProcessedTime) < DisconnectionTimeout; @@ -85,7 +63,9 @@ bool trixterxdreamv1bike::connected() uint32_t trixterxdreamv1bike::getTime() { - return static_cast(QDateTime::currentDateTime().toMSecsSinceEpoch() - this->t0); + auto currentDateTime = QDateTime::currentDateTime(); + auto ms = currentDateTime.toMSecsSinceEpoch(); + return static_cast(ms); } bool trixterxdreamv1bike::updateClient(const QString& s, trixterxdreamv1client * client) @@ -158,15 +138,15 @@ void trixterxdreamv1bike::updateResistance() trixterxdreamv1bike::~trixterxdreamv1bike() { - if(this->resistanceTimer) - { + if(this->resistanceTimer) { this->resistanceTimer->stop(); delete this->resistanceTimer; } - this->port.quit(); - - + if(this->port) { + this->port->quit(); + delete this->port; + } } void trixterxdreamv1bike::set_wheelDiameter(double value) @@ -177,3 +157,34 @@ void trixterxdreamv1bike::set_wheelDiameter(double value) // stored as km to avoid dividing by 1000 every time it's used this->wheelCircumference = value * M_PI / 1000.0; } + +trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering, const QString &portName) +{ + // first check if there's a port specified + if(portName!=nullptr && !portName.isEmpty()) + { + trixterxdreamv1bike * result = new trixterxdreamv1bike(noWriteResistance, noHeartService, noVirtualDevice, noSteering); + if(result->connect(portName)) + return result; + delete result; + return nullptr; + } + + // Find the available ports and return the first success + auto availablePorts = trixterxdreamv1serial::availablePorts(); + + for(int i=0; ibyteBuffer.clear(); } +void trixterxdreamv1client::set_GetTime(std::function get_time_ms) { + this->get_time_ms = get_time_ms; + this->t0 = this->get_time_ms ? this->get_time_ms():0; +} + trixterxdreamv1client::PacketState trixterxdreamv1client::ProcessChar(char c) { /* Packet content * 6A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 @@ -129,8 +134,7 @@ bool trixterxdreamv1client::ReceiveChar(char c) { crankRevsPerMinute = crankToRevolutionsPerMinute / max(static_cast(1), lastPacket.Crank); } - - const uint32_t t = this->get_time_ms(); + const uint32_t t = this->get_time_ms() - this->t0; const uint32_t lt = this->lastT ? this->lastT : t; this->lastT = t; diff --git a/src/trixterxdreamv1client.h b/src/trixterxdreamv1client.h index dc90598c6..c2dfe8766 100644 --- a/src/trixterxdreamv1client.h +++ b/src/trixterxdreamv1client.h @@ -67,10 +67,11 @@ class trixterxdreamv1client { uint8_t HeartRate; }; - std::function get_time_ms; - std::function write_bytes; + std::function get_time_ms=nullptr; + std::function write_bytes=nullptr; std::mutex stateMutex, writeMutex; uint32_t lastT = 0; + uint32_t t0 = 0; double flywheelRevolutions{}, crankRevolutions{}; Packet lastPacket{}; std::vector inputBuffer; @@ -121,7 +122,7 @@ class trixterxdreamv1client { * a starting point understood by the client. * @param get_time_ms A function to get the time. */ - void set_GetTime(std::function get_time_ms) { this->get_time_ms = get_time_ms; } + void set_GetTime(std::function get_time_ms); /** * @brief Gets the state of the device as it was last read. This consists of CSCS data, steering and heartbeat. From 4e56dd9b56d0a3442aed3d53af4313f9a1b2480d Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 30 Jul 2022 18:08:46 +0100 Subject: [PATCH 018/255] #855 added Trixter X-Dream V1 Bike to settings UI and changed to disabled by default --- src/settings.qml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/settings.qml b/src/settings.qml index 0952118ce..d2934f38f 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -455,7 +455,7 @@ import Qt.labs.settings 1.0 property bool proform_treadmill_se: false // from the version ? - property bool trixter_xdream_v1_bike: true + property bool trixter_xdream_v1_bike: false } function paddingZeros(text, limit) { @@ -1705,6 +1705,28 @@ import Qt.labs.settings 1.0 onClicked: settings.virtufit_etappe = checked } } + AccordionElement { + id: trixterXDreamV1BikeAccordion + title: qsTr("Trixter X-Dream V1 Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: + SwitchDelegate { + id: trixterXDreamV1 + text: qsTr("Trixter X-Dream V1 Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.trixter_xdream_v1_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.trixter_xdream_v1_bike = checked + } + } AccordionElement { id: flywheelBikeAccordion title: qsTr("Flywheel Bike Options") From b3243e91a480074e2cbdffc7f057d0181c098648 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 1 Aug 2022 01:39:39 +0100 Subject: [PATCH 019/255] #855 return the "used" bluetooth device. Delete the trixter device when finished. --- src/bluetooth.cpp | 15 +++++++++++---- src/bluetooth.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index a68067582..a218ea55b 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -399,10 +399,10 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { #endif // Try to connect to a Trixter X-Dream V1 bike if the setting is enabled. - this->trixterxdreamv1bike = this->findTrixterXDreamV1Bike(settings); - if(this->trixterxdreamv1bike) { - this->userTemplateManager->start(trixterxdreamv1bike); - this->innerTemplateManager->start(trixterxdreamv1bike); + this->trixterXDreamV1Bike = this->findTrixterXDreamV1Bike(settings); + if(this->trixterXDreamV1Bike) { + this->userTemplateManager->start(trixterXDreamV1Bike); + this->innerTemplateManager->start(trixterXDreamV1Bike); this->connectedAndDiscovered(); return; } @@ -2336,6 +2336,10 @@ void bluetooth::restart() { delete eliteSterzoSmart; eliteSterzoSmart = nullptr; } + if (trixterXDreamV1Bike) { + delete trixterXDreamV1Bike; + trixterXDreamV1Bike = nullptr; + } discoveryAgent->start(); } @@ -2483,7 +2487,10 @@ bluetoothdevice *bluetooth::device() { return fitPlusBike; } else if (skandikaWiriBike) { return skandikaWiriBike; + } else if (trixterXDreamV1Bike){ + return trixterXDreamV1Bike; } + return nullptr; } diff --git a/src/bluetooth.h b/src/bluetooth.h index a8575c244..ab7203af9 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -206,7 +206,7 @@ class bluetooth : public QObject, public SignalHandler { fakeelliptical *fakeElliptical = nullptr; QList fitmetriaFanfit; QString filterDevice = QLatin1String(""); - trixterxdreamv1bike * trixterxdreamv1bike = nullptr; + trixterxdreamv1bike * trixterXDreamV1Bike = nullptr; bool testResistance = false; bool noWriteResistance = false; From eb6a891c3edb7e77d243cefbb4af01737fa6126d Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 1 Aug 2022 02:56:59 +0100 Subject: [PATCH 020/255] #855 fix odometer and steering --- src/trixterxdreamv1bike.cpp | 7 ++++++- src/trixterxdreamv1bike.h | 2 +- src/trixterxdreamv1client.cpp | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 954e7e26d..214acd585 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -111,12 +111,17 @@ void trixterxdreamv1bike::update(const QString &s) // Set the steering if(!this->noSteering) - this->m_steeringAngle.setValue(90.0 / 250.0 * state.Steering -45.0); + this->m_steeringAngle.setValue(round(90.0 / 255.0 * state.Steering - 45.0)); + + // set the elapsed time + this->elapsed = (this->getTime() - this->t0) * 0.001; } void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { + bike::changeResistance(resistanceLevel); + // store the new resistance level. This might be the same as lastRequestedResistance(),Value // but it doesn't involve a function call and a cast to get the value. this->resistanceLevel = resistanceLevel; diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 27ff28471..3b4788ebc 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -46,7 +46,7 @@ class trixterxdreamv1bike : public bike /** * @brief resistanceLevel The last requested resistance level. */ - uint8_t resistanceLevel; + uint8_t resistanceLevel = 0; /** * @brief wheelCircumference The simulated circumference of the bike's wheels, for converting diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp index be0d35099..9387446d0 100644 --- a/src/trixterxdreamv1client.cpp +++ b/src/trixterxdreamv1client.cpp @@ -163,8 +163,8 @@ bool trixterxdreamv1client::ReceiveChar(char c) { newState.LastEventTime = static_cast(millisecondsToBaseUnit * t); newState.Steering = lastPacket.Steering; newState.HeartRate = lastPacket.HeartRate; - newState.CumulativeCrankRevolutions = static_cast(round(flywheelRevolutions)); - newState.CumulativeWheelRevolutions = static_cast(round(crankRevolutions)); + newState.CumulativeCrankRevolutions = static_cast(round(crankRevolutions)); + newState.CumulativeWheelRevolutions = static_cast(round(flywheelRevolutions)); newState.CrankRPM = static_cast(crankRevsPerMinute); newState.FlywheelRPM = static_cast(flywheelRevsPerMinute); From 874c35a9dfd5c1c379cfee01cc96804643a04059 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 1 Aug 2022 23:31:20 +0100 Subject: [PATCH 021/255] #855 "Trixter X-Dream V1 Bike found" on the home screen --- src/bluetooth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index a218ea55b..39daec391 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -41,7 +41,6 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc this->innerTemplateManager = TemplateInfoSenderBuilder::getInstance(innerId, QStringList({QStringLiteral(":/inner_templates/")}), this); - #ifdef TEST schwinnIC4Bike = (schwinnic4bike *)new bike(); userTemplateManager->start(schwinnIC4Bike); @@ -403,6 +402,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { if(this->trixterXDreamV1Bike) { this->userTemplateManager->start(trixterXDreamV1Bike); this->innerTemplateManager->start(trixterXDreamV1Bike); + emit deviceFound("Trixter X-Dream V1 Bike"); this->connectedAndDiscovered(); return; } From 71de66fffa4ef328bd6d8e20561a3c764077e256 Mon Sep 17 00:00:00 2001 From: David Mason Date: Tue, 2 Aug 2022 22:20:08 +0100 Subject: [PATCH 022/255] #855 emit deviceConnected on a fake QBluetoothDeviceInfo object to show tiles in UI --- src/bluetooth.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 39daec391..fb6fcfdf9 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -402,7 +402,9 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { if(this->trixterXDreamV1Bike) { this->userTemplateManager->start(trixterXDreamV1Bike); this->innerTemplateManager->start(trixterXDreamV1Bike); - emit deviceFound("Trixter X-Dream V1 Bike"); + this->emit deviceFound("Trixter X-Dream V1 Bike"); + QBluetoothDeviceInfo fakeInfo; + emit this->deviceConnected(fakeInfo); this->connectedAndDiscovered(); return; } From f5d6877c3895273ca4e8f57ec5c4a355746cfe99 Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 4 Aug 2022 22:21:21 +0100 Subject: [PATCH 023/255] #855 renaming some members, made device class produce a QBluetoothInfo object --- src/bluetooth.cpp | 6 +--- src/trixterxdreamv1bike.cpp | 63 ++++++++++++++++++++++------------- src/trixterxdreamv1bike.h | 20 ++++++----- src/trixterxdreamv1serial.cpp | 45 +++++++++++++------------ src/trixterxdreamv1serial.h | 16 +++++---- 5 files changed, 85 insertions(+), 65 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index fb6fcfdf9..fa4d0148e 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -402,9 +402,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { if(this->trixterXDreamV1Bike) { this->userTemplateManager->start(trixterXDreamV1Bike); this->innerTemplateManager->start(trixterXDreamV1Bike); - this->emit deviceFound("Trixter X-Dream V1 Bike"); - QBluetoothDeviceInfo fakeInfo; - emit this->deviceConnected(fakeInfo); + emit this->deviceConnected(this->trixterXDreamV1Bike->bluetoothDeviceInfo); this->connectedAndDiscovered(); return; } @@ -419,8 +417,6 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } #endif - - if ((heartRateBeltFound && ftmsAccessoryFound && cscFound && powerSensorFound && eliteRizerFound && eliteSterzoSmartFound) || forceHeartBeltOffForTimeout) { diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 214acd585..8349ebf5e 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -2,6 +2,9 @@ #include #include #include +#include + +using namespace std; trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) { @@ -26,18 +29,20 @@ bool trixterxdreamv1bike::connect(QString portName) // create the port object and connect it this->port = new trixterxdreamv1serial(this); - this->moveToThread(this->port); // this appears to be necessary for the slot to be called - if(!bike::connect(this->port, &trixterxdreamv1serial::request, this, &trixterxdreamv1bike::update)) + + // Move this to the port access thread. + // This appears to be necessary for the slot to be called without segmentation faults in strange places + this->moveToThread(this->port); + if(!bike::connect(this->port, &trixterxdreamv1serial::receive, this, &trixterxdreamv1bike::update)) { throw "Failed to connect to request slot"; } // References to objects for callbacks - auto thisObject = this; auto device=this->port; // tell the client where to get the time - this->client.set_GetTime([&thisObject]()->uint32_t { return thisObject->getTime();} ); + this->client.set_GetTime(getTime); // tell the client how to send data to the device if(!noWriteResistance) @@ -46,13 +51,27 @@ bool trixterxdreamv1bike::connect(QString portName) // open the port. This should be at 115200 bits per second. this->port->open(portName, 1000); - // create the timer for the resistance. This only needs to be active when a non-zero resistance is requested. + // create the timer for the resistance. this->resistanceTimer = new QTimer(this); - bike::connect(this->resistanceTimer, &QTimer::timeout, this, &trixterxdreamv1bike::updateResistance); + + // PreciseTimer for 1ms resolution + this->resistanceTimer->setTimerType(Qt::PreciseTimer); + this->resistanceTimer->setSingleShot(false); + this->resistanceTimer->moveToThread(this->port); + if(!bike::connect(this->resistanceTimer, &QTimer::timeout, this, &trixterxdreamv1bike::updateResistance)) + { + throw "Failed to connect resistance timer to update resistance slot"; + } // wait for some packets to arrive QThread::msleep(500); - return this->connected(); + + if(this->connected()) + { + this->resistanceTimer->start(trixterxdreamv1client::ResistancePulseIntervalMilliseconds); + return true; + } + return false; } bool trixterxdreamv1bike::connected() @@ -86,10 +105,11 @@ void trixterxdreamv1bike::update(const QString &s) // Take the most recent state read auto state = this->client.getLastState(); + auto currentTime = getTime(); // update the packet count this->packetsProcessed++; - this->lastPacketProcessedTime = this->getTime(); + this->lastPacketProcessedTime = currentTime; // update the metrics this->LastCrankEventTime = state.LastEventTime; @@ -114,44 +134,39 @@ void trixterxdreamv1bike::update(const QString &s) this->m_steeringAngle.setValue(round(90.0 / 255.0 * state.Steering - 45.0)); // set the elapsed time - this->elapsed = (this->getTime() - this->t0) * 0.001; - + this->elapsed = (currentTime - this->t0) * 0.001; } void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { + // Clip the incoming values + if(resistanceLevel<0) resistanceLevel = 0; + if(resistanceLevel>maxResistance()) resistanceLevel = maxResistance(); + bike::changeResistance(resistanceLevel); // store the new resistance level. This might be the same as lastRequestedResistance(),Value // but it doesn't involve a function call and a cast to get the value. this->resistanceLevel = resistanceLevel; + // store the resistance level as a metric for the UI + this->Resistance.setValue(resistanceLevel); + // don't do anything if resistance is disabled if(this->noWriteResistance) return; - - if(resistanceLevel==0) - this->resistanceTimer->stop(); - else - this->resistanceTimer->start(trixterxdreamv1client::ResistancePulseIntervalMilliseconds); } -void trixterxdreamv1bike::updateResistance() + + +void trixterxdreamv1bike::updateResistance(void) { this->client.SendResistance(this->resistanceLevel); } trixterxdreamv1bike::~trixterxdreamv1bike() { - if(this->resistanceTimer) { - this->resistanceTimer->stop(); - delete this->resistanceTimer; - } - if(this->port) { - this->port->quit(); - delete this->port; - } } void trixterxdreamv1bike::set_wheelDiameter(double value) diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 3b4788ebc..c2f87aff7 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -77,14 +77,7 @@ class trixterxdreamv1bike : public bike /** * @brief getTime Gets the time in miliseconds since this object was created. */ - uint32_t getTime(); - - - /** - * @brief updateResistance Called by the resistanceTimer to send the resistence request to the - * device. - */ - void updateResistance(); + static uint32_t getTime(); /** * @brief updateClient Passes the array of bytes into the client one by one. @@ -109,6 +102,12 @@ public Q_SLOTS: */ void update(const QString& s); + /** + * @brief updateResistance Called by the resistanceTimer to send the resistance request to the + * device. + */ + void updateResistance(void); + public: /** @@ -132,6 +131,11 @@ public Q_SLOTS: */ constexpr static int32_t DisconnectionTimeout = 50; + /** + * @brief bluetoothDeviceInfo A QBluetoothDeviceInfo object for functions that need it. + */ + const QBluetoothDeviceInfo bluetoothDeviceInfo { QBluetoothUuid {QStringLiteral("774f25bd-6636-4cdc-9398-839de026be1d")}, "Trixter X-Dream V1 Bike", 0}; + /** * @brief trixterxdreamv1bike Constructor * @param noWriteResistance Option to avoid sending resistance to the device. diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 80c8ac349..08e3f1cf3 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -4,13 +4,13 @@ #include #include -trixterxdreamv1serial::trixterxdreamv1serial(QObject *parent) : QThread(parent) {} +trixterxdreamv1serial::trixterxdreamv1serial(QObject *parent) : QThread(parent){} trixterxdreamv1serial::~trixterxdreamv1serial() { - m_mutex.lock(); - m_quit = true; - m_mutex.unlock(); - wait(); + this->mutex.lock(); + this->quitPending = true; + this->mutex.unlock(); + this->wait(); } QList trixterxdreamv1serial::availablePorts() @@ -19,9 +19,9 @@ QList trixterxdreamv1serial::availablePorts() } void trixterxdreamv1serial::open(const QString &portName, int waitTimeout) { - const QMutexLocker locker(&m_mutex); - m_portName = portName; - m_waitTimeout = waitTimeout; + const QMutexLocker locker(&this->mutex); + this->portName = portName; + this->waitTimeout = waitTimeout; if (!isRunning()) start(); } @@ -36,26 +36,26 @@ void trixterxdreamv1serial::run() { bool currentPortNameChanged = false; - m_mutex.lock(); + this->mutex.lock(); QString currentPortName; - if (currentPortName != m_portName) { - currentPortName = m_portName; + if (currentPortName != this->portName) { + currentPortName = this->portName; currentPortNameChanged = true; } - int currentWaitTimeout = m_waitTimeout; - m_mutex.unlock(); + int currentWaitTimeout = this->waitTimeout; + this->mutex.unlock(); - while (!m_quit) { + while (!this->quitPending) { if (currentPortNameChanged) { serial.close(); serial.setPortName(currentPortName); serial.setBaudRate(QSerialPort::Baud115200); if (!serial.open(QIODevice::ReadWrite)) { - qDebug() << tr("Can't open %1, error code %2").arg(m_portName).arg(serial.error()); - emit error(tr("Can't open %1, error code %2").arg(m_portName).arg(serial.error())); + qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error()); + emit error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error())); return; } qDebug() << "Serial port" << currentPortName << "opened"; @@ -70,17 +70,18 @@ void trixterxdreamv1serial::run() { // Send the bytes to the client code if(requestData.length()>0) { const QString request = QString::fromUtf8(requestData); - emit this->request(request); + emit this->receive(request); } } - m_mutex.lock(); - if (currentPortName != m_portName) { - currentPortName = m_portName; + + this->mutex.lock(); + if (currentPortName != this->portName) { + currentPortName = this->portName; currentPortNameChanged = true; } else { currentPortNameChanged = false; } - currentWaitTimeout = m_waitTimeout; - m_mutex.unlock(); + currentWaitTimeout = this->waitTimeout; + this->mutex.unlock(); } } diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index e23990c87..2fe42d6dc 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -9,7 +9,7 @@ class trixterxdreamv1serial : public QThread { Q_OBJECT - public: +public: explicit trixterxdreamv1serial(QObject *parent = nullptr); ~trixterxdreamv1serial(); @@ -32,19 +32,23 @@ class trixterxdreamv1serial : public QThread { * @brief availablePorts Returns a list of information objects for the serial ports found in the system. */ static QList availablePorts(); + + + signals: - void request(const QString &s); + void receive(const QString &s); void error(const QString &s); void timeout(const QString &s); + private: void run() override; QSerialPort serial; - QString m_portName; - int m_waitTimeout = 1000; - QMutex m_mutex; - bool m_quit = false; + QString portName; + int waitTimeout = 1000; + QMutex mutex; + bool quitPending = false; }; #endif // TRIXTERXDREAMSERIAL_H From 0c3bea42bc56ac83ab1b4c9e1b8e1bef861cd216 Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 4 Aug 2022 22:49:29 +0100 Subject: [PATCH 024/255] #855 avoid QSLOTS for communication with the serial port thread. Now the resistance timer works and resistance is sent to the device. --- src/trixterxdreamv1bike.cpp | 10 +--------- src/trixterxdreamv1bike.h | 19 ++++++++++++++++++- src/trixterxdreamv1serial.cpp | 4 ++-- src/trixterxdreamv1serial.h | 8 ++++---- 4 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 8349ebf5e..9623a191d 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -28,15 +28,7 @@ bool trixterxdreamv1bike::connect(QString portName) this->t0 = this->getTime(); // create the port object and connect it - this->port = new trixterxdreamv1serial(this); - - // Move this to the port access thread. - // This appears to be necessary for the slot to be called without segmentation faults in strange places - this->moveToThread(this->port); - if(!bike::connect(this->port, &trixterxdreamv1serial::receive, this, &trixterxdreamv1bike::update)) - { - throw "Failed to connect to request slot"; - } + this->port = new serialPort(this); // References to objects for callbacks auto device=this->port; diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index c2f87aff7..f07378575 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -7,6 +7,23 @@ class trixterxdreamv1bike : public bike { Q_OBJECT private: + + class serialPort : public trixterxdreamv1serial + { + protected: + trixterxdreamv1bike * bike = nullptr; + + void receive(const QString &s) override + { + this->bike->update(s); + } + + public: + explicit serialPort(trixterxdreamv1bike * bike) { + this->bike = bike; + } + }; + /** * @brief client An object that processes incoming data to CSCS, heart rate and steering data */ @@ -16,7 +33,7 @@ class trixterxdreamv1bike : public bike * @brief port An object that monitors a serial port to read incoming data, and to write * resistance level requests. */ - trixterxdreamv1serial * port = nullptr; + serialPort * port = nullptr; /** * @brief resistanceTimer A timer to push the currently requested resistance level to the device. diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 08e3f1cf3..c0e3bfb01 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -55,7 +55,7 @@ void trixterxdreamv1serial::run() { if (!serial.open(QIODevice::ReadWrite)) { qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error()); - emit error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error())); + this->error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error())); return; } qDebug() << "Serial port" << currentPortName << "opened"; @@ -70,7 +70,7 @@ void trixterxdreamv1serial::run() { // Send the bytes to the client code if(requestData.length()>0) { const QString request = QString::fromUtf8(requestData); - emit this->receive(request); + this->receive(request); } } diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index 2fe42d6dc..c50f441cd 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -35,10 +35,10 @@ class trixterxdreamv1serial : public QThread { -signals: - void receive(const QString &s); - void error(const QString &s); - void timeout(const QString &s); +protected: + virtual void receive(const QString &s) {} + virtual void error(const QString &s) {} + virtual void timeout(const QString &s) {} private: From 942fefd9e88368fbc6c3f7a4af8a514f0fc92cc4 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 5 Aug 2022 00:39:31 +0100 Subject: [PATCH 025/255] #855 adjustments to use of resistanceTimer --- src/trixterxdreamv1bike.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 9623a191d..9792b172b 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -49,7 +49,6 @@ bool trixterxdreamv1bike::connect(QString portName) // PreciseTimer for 1ms resolution this->resistanceTimer->setTimerType(Qt::PreciseTimer); this->resistanceTimer->setSingleShot(false); - this->resistanceTimer->moveToThread(this->port); if(!bike::connect(this->resistanceTimer, &QTimer::timeout, this, &trixterxdreamv1bike::updateResistance)) { throw "Failed to connect resistance timer to update resistance slot"; @@ -131,6 +130,10 @@ void trixterxdreamv1bike::update(const QString &s) void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { + // ignore the resistance if this option was selected + if(this->noWriteResistance) + return; + // Clip the incoming values if(resistanceLevel<0) resistanceLevel = 0; if(resistanceLevel>maxResistance()) resistanceLevel = maxResistance(); @@ -143,14 +146,8 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) // store the resistance level as a metric for the UI this->Resistance.setValue(resistanceLevel); - - // don't do anything if resistance is disabled - if(this->noWriteResistance) - return; } - - void trixterxdreamv1bike::updateResistance(void) { this->client.SendResistance(this->resistanceLevel); From c29bd3db67210f42a24ff1e8139f24f4a040269b Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 5 Aug 2022 00:48:28 +0100 Subject: [PATCH 026/255] #855 only run the resistance timer if the resistance level is non-zero --- src/trixterxdreamv1bike.cpp | 13 ++++++++++++- src/trixterxdreamv1bike.h | 5 ----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 9792b172b..5d0b5644e 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -59,7 +59,7 @@ bool trixterxdreamv1bike::connect(QString portName) if(this->connected()) { - this->resistanceTimer->start(trixterxdreamv1client::ResistancePulseIntervalMilliseconds); + return true; } return false; @@ -146,6 +146,17 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) // store the resistance level as a metric for the UI this->Resistance.setValue(resistanceLevel); + + // run the resistance timer only if the resistance is non-zero + bool isActive = this->resistanceTimer->isActive(); + if(resistanceLevel==0) + { + if(isActive) + this->resistanceTimer->stop(); + } else { + if(!isActive) + this->resistanceTimer->start(trixterxdreamv1client::ResistancePulseIntervalMilliseconds); + } } void trixterxdreamv1bike::updateResistance(void) diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index f07378575..ee8d2d3bd 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -86,11 +86,6 @@ class trixterxdreamv1bike : public bike */ uint32_t lastPacketProcessedTime=0; - /** - * @brief updateMutex Mutex to syncronize access to - */ - QMutex updateMutex; - /** * @brief getTime Gets the time in miliseconds since this object was created. */ From 1f0788e430cbd19180c2917a02ca6ec07a60e741 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 5 Aug 2022 00:59:42 +0100 Subject: [PATCH 027/255] #855 hid serial port monitor in cpp file --- src/trixterxdreamv1bike.cpp | 21 ++++++++++++++++++++- src/trixterxdreamv1bike.h | 20 ++------------------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 5d0b5644e..0cbe4c154 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -1,4 +1,5 @@ #include "trixterxdreamv1bike.h" +#include "trixterxdreamv1serial.h" #include #include #include @@ -6,6 +7,24 @@ using namespace std; + +class trixterxdreamv1bike::serialPortMonitor : public trixterxdreamv1serial +{ + protected: + trixterxdreamv1bike * bike = nullptr; + + void receive(const QString &s) override + { + this->bike->update(s); + } + +public: + explicit serialPortMonitor(trixterxdreamv1bike * bike) { + this->bike = bike; + } +}; + + trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) { // Set the wheel diameter for speed and distance calculations @@ -28,7 +47,7 @@ bool trixterxdreamv1bike::connect(QString portName) this->t0 = this->getTime(); // create the port object and connect it - this->port = new serialPort(this); + this->port = new serialPortMonitor(this); // References to objects for callbacks auto device=this->port; diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index ee8d2d3bd..221bb11ff 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -1,28 +1,12 @@ #pragma once #include "bike.h" #include "trixterxdreamv1client.h" -#include "trixterxdreamv1serial.h" class trixterxdreamv1bike : public bike { Q_OBJECT private: - - class serialPort : public trixterxdreamv1serial - { - protected: - trixterxdreamv1bike * bike = nullptr; - - void receive(const QString &s) override - { - this->bike->update(s); - } - - public: - explicit serialPort(trixterxdreamv1bike * bike) { - this->bike = bike; - } - }; + class serialPortMonitor; /** * @brief client An object that processes incoming data to CSCS, heart rate and steering data @@ -33,7 +17,7 @@ class trixterxdreamv1bike : public bike * @brief port An object that monitors a serial port to read incoming data, and to write * resistance level requests. */ - serialPort * port = nullptr; + serialPortMonitor * port = nullptr; /** * @brief resistanceTimer A timer to push the currently requested resistance level to the device. From daf0de4a344f2baf6ad64fc374ef9653ab82b0ef Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 5 Aug 2022 01:14:21 +0100 Subject: [PATCH 028/255] #855 avoid using a QTimer object, use QObject::startTimer instead --- src/trixterxdreamv1bike.cpp | 48 ++++++++++++++++--------------------- src/trixterxdreamv1bike.h | 7 +++--- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 0cbe4c154..8941468f6 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -1,4 +1,5 @@ #include "trixterxdreamv1bike.h" +#include "qcoreevent.h" #include "trixterxdreamv1serial.h" #include #include @@ -40,7 +41,6 @@ trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartSer bool trixterxdreamv1bike::connect(QString portName) { if(this->port) delete this->port; - if(this->resistanceTimer) delete this->resistanceTimer; // Get the current time in milliseconds since ancient times. // This will be subtracted from further readings from getTime() to get an easier to look at number. @@ -62,26 +62,20 @@ bool trixterxdreamv1bike::connect(QString portName) // open the port. This should be at 115200 bits per second. this->port->open(portName, 1000); - // create the timer for the resistance. - this->resistanceTimer = new QTimer(this); - - // PreciseTimer for 1ms resolution - this->resistanceTimer->setTimerType(Qt::PreciseTimer); - this->resistanceTimer->setSingleShot(false); - if(!bike::connect(this->resistanceTimer, &QTimer::timeout, this, &trixterxdreamv1bike::updateResistance)) - { - throw "Failed to connect resistance timer to update resistance slot"; - } - // wait for some packets to arrive QThread::msleep(500); - if(this->connected()) + if(!this->noWriteResistance) { - - return true; + this->resistanceTimerId = this->startTimer(trixterxdreamv1client::ResistancePulseIntervalMilliseconds, Qt::PreciseTimer); + if(this->resistanceTimerId==0) + { + qDebug() << "Failed to start resistance timer"; + throw "Failed to start resistance timer"; + } } - return false; + + return this->connected(); } bool trixterxdreamv1bike::connected() @@ -107,6 +101,15 @@ bool trixterxdreamv1bike::updateClient(const QString& s, trixterxdreamv1client * return stateChanged; } +void trixterxdreamv1bike::timerEvent(QTimerEvent *event) +{ + if(event->timerId()==this->resistanceTimerId) + { + event->accept(); + this->updateResistance(); + } +} + void trixterxdreamv1bike::update(const QString &s) { // send the bytes to the client and return if there's no change of state @@ -165,20 +168,9 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) // store the resistance level as a metric for the UI this->Resistance.setValue(resistanceLevel); - - // run the resistance timer only if the resistance is non-zero - bool isActive = this->resistanceTimer->isActive(); - if(resistanceLevel==0) - { - if(isActive) - this->resistanceTimer->stop(); - } else { - if(!isActive) - this->resistanceTimer->start(trixterxdreamv1client::ResistancePulseIntervalMilliseconds); - } } -void trixterxdreamv1bike::updateResistance(void) +void trixterxdreamv1bike::updateResistance() { this->client.SendResistance(this->resistanceLevel); } diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 221bb11ff..c18f1df8d 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -19,10 +19,7 @@ class trixterxdreamv1bike : public bike */ serialPortMonitor * port = nullptr; - /** - * @brief resistanceTimer A timer to push the currently requested resistance level to the device. - */ - QTimer * resistanceTimer = nullptr; + int resistanceTimerId = 0; /** * @brief noHeartService Suppress heart rate readings. @@ -86,6 +83,8 @@ class trixterxdreamv1bike : public bike protected: virtual BLUETOOTH_TYPE devicetype() { return BIKE; } + void timerEvent(QTimerEvent *event) override; + public Q_SLOTS: /** * @brief changeResistance Called to change the requested resistance level. From c03ef3abd0bd1250c46e4b73a3286c982a81e848 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 5 Aug 2022 01:33:01 +0100 Subject: [PATCH 029/255] #855 make serial port monitor use QByteArrays instead of char * --- src/trixterxdreamv1bike.cpp | 30 +++++++++++++++--------------- src/trixterxdreamv1bike.h | 8 ++++---- src/trixterxdreamv1serial.cpp | 9 ++++----- src/trixterxdreamv1serial.h | 5 ++--- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 8941468f6..3c568dd20 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -14,9 +14,9 @@ class trixterxdreamv1bike::serialPortMonitor : public trixterxdreamv1serial protected: trixterxdreamv1bike * bike = nullptr; - void receive(const QString &s) override + void receive(const QByteArray &bytes) override { - this->bike->update(s); + this->bike->update(bytes); } public: @@ -57,7 +57,7 @@ bool trixterxdreamv1bike::connect(QString portName) // tell the client how to send data to the device if(!noWriteResistance) - this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(bytes, length, "");}); + this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(QByteArray((const char *)bytes, length), "");}); // open the port. This should be at 115200 bits per second. this->port->open(portName, 1000); @@ -91,16 +91,6 @@ uint32_t trixterxdreamv1bike::getTime() return static_cast(ms); } -bool trixterxdreamv1bike::updateClient(const QString& s, trixterxdreamv1client * client) -{ - bool stateChanged = false; - - for(int i=0; iReceiveChar(s[i].toLatin1()); - - return stateChanged; -} - void trixterxdreamv1bike::timerEvent(QTimerEvent *event) { if(event->timerId()==this->resistanceTimerId) @@ -110,10 +100,20 @@ void trixterxdreamv1bike::timerEvent(QTimerEvent *event) } } -void trixterxdreamv1bike::update(const QString &s) +bool trixterxdreamv1bike::updateClient(const QByteArray& bytes, trixterxdreamv1client * client) +{ + bool stateChanged = false; + + for(int i=0; iReceiveChar(bytes[i]); + + return stateChanged; +} + +void trixterxdreamv1bike::update(const QByteArray &bytes) { // send the bytes to the client and return if there's no change of state - if(!updateClient(s, &this->client)) + if(!updateClient(bytes, &this->client)) return; // Take the most recent state read diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index c18f1df8d..2c46364d9 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -78,7 +78,7 @@ class trixterxdreamv1bike : public bike * @param client The client object that interprets the incoming bytes into data packets. * @return True if the state of the client changed due to the input. */ - static bool updateClient(const QString &s, trixterxdreamv1client * client); + static bool updateClient(const QByteArray &bytes, trixterxdreamv1client * client); protected: virtual BLUETOOTH_TYPE devicetype() { return BIKE; } @@ -90,18 +90,18 @@ public Q_SLOTS: * @brief changeResistance Called to change the requested resistance level. * @param resistanceLevel The resistance level to request (0..250) */ - virtual void changeResistance(int8_t resistanceLevel); + void changeResistance(int8_t resistanceLevel) override; /** * @brief Called by the data source (serial port) when a new block of data arrives. */ - void update(const QString& s); + void update(const QByteArray& bytes); /** * @brief updateResistance Called by the resistanceTimer to send the resistance request to the * device. */ - void updateResistance(void); + void updateResistance(); public: diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index c0e3bfb01..aa0309819 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -26,9 +26,9 @@ void trixterxdreamv1serial::open(const QString &portName, int waitTimeout) { start(); } -void trixterxdreamv1serial::write(const uint8_t *buffer, int len, QString info) { - qDebug() << "serial >> " << QByteArray((const char *)buffer, len).toHex(' ') << "//" << info; - qint64 o = serial.write(QByteArray((const char *)buffer, len)); +void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { + qDebug() << "serial >> " << buffer.toHex(' ') << "//" << info; + qint64 o = serial.write(buffer); qDebug() << "serial byte written" << o; } @@ -69,8 +69,7 @@ void trixterxdreamv1serial::run() { // Send the bytes to the client code if(requestData.length()>0) { - const QString request = QString::fromUtf8(requestData); - this->receive(request); + this->receive(requestData); } } diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index c50f441cd..e35849a6c 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -23,10 +23,9 @@ class trixterxdreamv1serial : public QThread { /** * @brief Writes the array of bytes to the serial port * @param buffer The bytes to send. - * @param len The number of bytes to send. * @param info Debug information */ - void write(const uint8_t *buffer, int len, QString info); + void write(const QByteArray& buffer, QString info); /** * @brief availablePorts Returns a list of information objects for the serial ports found in the system. @@ -36,7 +35,7 @@ class trixterxdreamv1serial : public QThread { protected: - virtual void receive(const QString &s) {} + virtual void receive(const QByteArray &bytes) {} virtual void error(const QString &s) {} virtual void timeout(const QString &s) {} From b3341654ae372bd30154c9c0e64da48650d70629 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 5 Aug 2022 01:47:59 +0100 Subject: [PATCH 030/255] #855 code cleanup, and close serial port when finished --- src/trixterxdreamv1bike.h | 28 +++++++++++++++------------- src/trixterxdreamv1serial.cpp | 13 +++++++------ 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 2c46364d9..611bf1a41 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -19,6 +19,9 @@ class trixterxdreamv1bike : public bike */ serialPortMonitor * port = nullptr; + /** + * @brief resistanceTimerId The id for identifying the resistance timer in void timerEvent(QEvent*). + */ int resistanceTimerId = 0; /** @@ -80,8 +83,17 @@ class trixterxdreamv1bike : public bike */ static bool updateClient(const QByteArray &bytes, trixterxdreamv1client * client); + /** + * @brief Called by the data source (serial port) when a new block of data arrives. + */ + void update(const QByteArray& bytes); + + /** + * @brief updateResistance Called by the resistanceTimer to send the resistance request to the + * device. + */ + void updateResistance(); protected: - virtual BLUETOOTH_TYPE devicetype() { return BIKE; } void timerEvent(QTimerEvent *event) override; @@ -92,16 +104,6 @@ public Q_SLOTS: */ void changeResistance(int8_t resistanceLevel) override; - /** - * @brief Called by the data source (serial port) when a new block of data arrives. - */ - void update(const QByteArray& bytes); - - /** - * @brief updateResistance Called by the resistanceTimer to send the resistance request to the - * device. - */ - void updateResistance(); public: @@ -151,7 +153,7 @@ public Q_SLOTS: /** * @brief connected Indicates if a valid packet was received from the device within the DisconnectionTimeout. */ - virtual bool connected(); + bool connected() override; /** * @brief set_wheelDiameter Set the simulated wheel diameter to be used for converting angular velocity to speed. Units: meters @@ -163,7 +165,7 @@ public Q_SLOTS: * @brief maxResistance The maximum resistance supported. * @return */ - virtual uint8_t maxResistance() { return trixterxdreamv1client::MaxResistance; } + uint8_t maxResistance() override { return trixterxdreamv1client::MaxResistance; } /** * @brief tryCreate Attempt to create an object to interact with an existing Trixter X-Dream V1 bike on a specific serial port, diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index aa0309819..e2e1a0ecc 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -33,11 +33,9 @@ void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { } void trixterxdreamv1serial::run() { - + QMutexLocker locker(&this->mutex); bool currentPortNameChanged = false; - this->mutex.lock(); - QString currentPortName; if (currentPortName != this->portName) { currentPortName = this->portName; @@ -45,7 +43,7 @@ void trixterxdreamv1serial::run() { } int currentWaitTimeout = this->waitTimeout; - this->mutex.unlock(); + locker.unlock(); while (!this->quitPending) { if (currentPortNameChanged) { @@ -73,7 +71,7 @@ void trixterxdreamv1serial::run() { } } - this->mutex.lock(); + locker.relock(); if (currentPortName != this->portName) { currentPortName = this->portName; currentPortNameChanged = true; @@ -81,6 +79,9 @@ void trixterxdreamv1serial::run() { currentPortNameChanged = false; } currentWaitTimeout = this->waitTimeout; - this->mutex.unlock(); + locker.unlock(); } + + if(serial.isOpen()) + serial.close(); } From f69a0cdf3ac905e604f9f230fac9d8884ceab15d Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 5 Aug 2022 02:00:32 +0100 Subject: [PATCH 031/255] #855 replaced magic number, delete unused objects from detection process --- src/trixterxdreamv1bike.cpp | 4 +++- src/trixterxdreamv1client.h | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 3c568dd20..45f447de9 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -143,8 +143,9 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) this->CrankRevs = state.CumulativeCrankRevolutions; // Set the steering + constexpr double steeringScale = 90.0 / trixterxdreamv1client::MaxSteering; if(!this->noSteering) - this->m_steeringAngle.setValue(round(90.0 / 255.0 * state.Steering - 45.0)); + this->m_steeringAngle.setValue(round(steeringScale * state.Steering - 45.0)); // set the elapsed time this->elapsed = (currentTime - this->t0) * 0.001; @@ -208,6 +209,7 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo { trixterxdreamv1bike * result = tryCreate(noWriteResistance, noHeartService, noVirtualDevice, noSteering, availablePorts[i].portName()); if(result) return result; + delete result; } return nullptr; diff --git a/src/trixterxdreamv1client.h b/src/trixterxdreamv1client.h index c2dfe8766..54e70dbaf 100644 --- a/src/trixterxdreamv1client.h +++ b/src/trixterxdreamv1client.h @@ -97,6 +97,11 @@ class trixterxdreamv1client { */ constexpr static uint8_t MaxResistance = 250; + /** + * @brief MaxSteering The maximum steering value supported by the device. + */ + constexpr static uint8_t MaxSteering = 255; + /** * @brief The time interval between sending resistance requests to the device. */ From 97ef577b8499696925473efefe341bafe79d2b7f Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 5 Aug 2022 02:07:20 +0100 Subject: [PATCH 032/255] #855 make baud rate an option --- src/trixterxdreamv1bike.cpp | 2 +- src/trixterxdreamv1serial.cpp | 5 +++-- src/trixterxdreamv1serial.h | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 45f447de9..2014cc091 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -60,7 +60,7 @@ bool trixterxdreamv1bike::connect(QString portName) this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(QByteArray((const char *)bytes, length), "");}); // open the port. This should be at 115200 bits per second. - this->port->open(portName, 1000); + this->port->open(portName, QSerialPort::Baud115200, 1000); // wait for some packets to arrive QThread::msleep(500); diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index e2e1a0ecc..d5b054c92 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -18,9 +18,10 @@ QList trixterxdreamv1serial::availablePorts() return QSerialPortInfo::availablePorts(); } -void trixterxdreamv1serial::open(const QString &portName, int waitTimeout) { +void trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate baudRate, int waitTimeout) { const QMutexLocker locker(&this->mutex); this->portName = portName; + this->baudRate = baudRate; this->waitTimeout = waitTimeout; if (!isRunning()) start(); @@ -49,7 +50,7 @@ void trixterxdreamv1serial::run() { if (currentPortNameChanged) { serial.close(); serial.setPortName(currentPortName); - serial.setBaudRate(QSerialPort::Baud115200); + serial.setBaudRate(this->baudRate); if (!serial.open(QIODevice::ReadWrite)) { qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error()); diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index e35849a6c..1a5ceadfa 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -16,9 +16,10 @@ class trixterxdreamv1serial : public QThread { /** * @brief Opens the port. * @param portName The name of the serial port. + * @param baudRate The baud rate. * @param waitTimeout The timeout for the serial port. */ - void open(const QString &portName, int waitTimeout); + void open(const QString &portName, QSerialPort::BaudRate baudRate, int waitTimeout); /** * @brief Writes the array of bytes to the serial port @@ -45,6 +46,7 @@ class trixterxdreamv1serial : public QThread { QSerialPort serial; QString portName; + QSerialPort::BaudRate baudRate; int waitTimeout = 1000; QMutex mutex; bool quitPending = false; From 5f7b180fdc7590b5ea126f532a5d255f2fa0a902 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 5 Aug 2022 02:49:41 +0100 Subject: [PATCH 033/255] #855 no reconfiguring the serial port monitor while it runs. Use mutex to prevent reading and writing serial port concurrently --- src/trixterxdreamv1serial.cpp | 60 +++++++++++------------------------ 1 file changed, 18 insertions(+), 42 deletions(-) diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index d5b054c92..5ef168bfc 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -7,9 +7,7 @@ trixterxdreamv1serial::trixterxdreamv1serial(QObject *parent) : QThread(parent){} trixterxdreamv1serial::~trixterxdreamv1serial() { - this->mutex.lock(); this->quitPending = true; - this->mutex.unlock(); this->wait(); } @@ -29,60 +27,38 @@ void trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { qDebug() << "serial >> " << buffer.toHex(' ') << "//" << info; + QMutexLocker locker(&this->mutex); qint64 o = serial.write(buffer); + locker.unlock(); qDebug() << "serial byte written" << o; } void trixterxdreamv1serial::run() { - QMutexLocker locker(&this->mutex); - bool currentPortNameChanged = false; - QString currentPortName; - if (currentPortName != this->portName) { - currentPortName = this->portName; - currentPortNameChanged = true; - } + serial.setPortName(this->portName); + serial.setBaudRate(this->baudRate); - int currentWaitTimeout = this->waitTimeout; - locker.unlock(); + if (!serial.open(QIODevice::ReadWrite)) { + qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error()); + this->error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error())); + return; + } + qDebug() << "Serial port" << this->portName << "opened"; while (!this->quitPending) { - if (currentPortNameChanged) { - serial.close(); - serial.setPortName(currentPortName); - serial.setBaudRate(this->baudRate); - - if (!serial.open(QIODevice::ReadWrite)) { - qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error()); - this->error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error())); - return; - } - qDebug() << "Serial port" << currentPortName << "opened"; - } - if (serial.waitForReadyRead(currentWaitTimeout)) { - QByteArray requestData = serial.readAll(); - while (serial.waitForReadyRead(1)) - requestData += serial.readAll(); + if (this->serial.waitForReadyRead(this->waitTimeout)) { + QMutexLocker locker(&this->mutex); + QByteArray requestData = this->serial.readAll(); + while (this->serial.waitForReadyRead(1)) + requestData += this->serial.readAll(); + locker.unlock(); qDebug() << "serial << " << requestData.toHex(' '); // Send the bytes to the client code - if(requestData.length()>0) { - this->receive(requestData); - } - } - - locker.relock(); - if (currentPortName != this->portName) { - currentPortName = this->portName; - currentPortNameChanged = true; - } else { - currentPortNameChanged = false; + this->receive(requestData); } - currentWaitTimeout = this->waitTimeout; - locker.unlock(); } - if(serial.isOpen()) - serial.close(); + this->serial.close(); } From 0cced633dcde68a1e7f43b8300fe54e53c47b6fc Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 6 Aug 2022 01:38:49 +0100 Subject: [PATCH 034/255] #855 various fixes to workaround intermittent seg faults seemingly related to concurrent use of the QSerialPort object --- src/trixterxdreamv1bike.cpp | 82 +++++++++++++++++++++-------------- src/trixterxdreamv1bike.h | 11 ++++- src/trixterxdreamv1serial.cpp | 45 ++++++++++++++----- src/trixterxdreamv1serial.h | 22 +++++++--- 4 files changed, 111 insertions(+), 49 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 2014cc091..9222b8ee0 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -26,8 +26,7 @@ class trixterxdreamv1bike::serialPortMonitor : public trixterxdreamv1serial }; -trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) -{ +trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) { // Set the wheel diameter for speed and distance calculations this->set_wheelDiameter(DefaultWheelDiameter); @@ -38,16 +37,19 @@ trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartSer this->noSteering = noSteering; } -bool trixterxdreamv1bike::connect(QString portName) -{ - if(this->port) delete this->port; +bool trixterxdreamv1bike::connect(QString portName) { + // In case already connected, disconnect. + this->disconnectPort(); // Get the current time in milliseconds since ancient times. // This will be subtracted from further readings from getTime() to get an easier to look at number. this->t0 = this->getTime(); + auto thisObject = this; + // create the port object and connect it - this->port = new serialPortMonitor(this); + this->port = new trixterxdreamv1serial(this); + this->port->set_receiveBytes([thisObject](const QByteArray& bytes)->void{thisObject->update(bytes);}); // References to objects for callbacks auto device=this->port; @@ -75,24 +77,41 @@ bool trixterxdreamv1bike::connect(QString portName) } } + if(!this->connected()) + { + qDebug() << "Failed to connect to device"; + this->disconnectPort(); + return false; + } + return this->connected(); } -bool trixterxdreamv1bike::connected() -{ +void trixterxdreamv1bike::disconnectPort() { + if(this->port) { + qDebug() << "Disconnecting from serial port"; + delete this->port; + this->port = nullptr; + } + if(this->resistanceTimerId) { + qDebug() << "Kiling resistance timer"; + this->killTimer(this->resistanceTimerId); + this->resistanceTimerId = 0; + } +} + +bool trixterxdreamv1bike::connected() { return (this->getTime()-this->lastPacketProcessedTime) < DisconnectionTimeout; } -uint32_t trixterxdreamv1bike::getTime() -{ +uint32_t trixterxdreamv1bike::getTime() { auto currentDateTime = QDateTime::currentDateTime(); auto ms = currentDateTime.toMSecsSinceEpoch(); return static_cast(ms); } -void trixterxdreamv1bike::timerEvent(QTimerEvent *event) -{ +void trixterxdreamv1bike::timerEvent(QTimerEvent *event) { if(event->timerId()==this->resistanceTimerId) { event->accept(); @@ -100,8 +119,7 @@ void trixterxdreamv1bike::timerEvent(QTimerEvent *event) } } -bool trixterxdreamv1bike::updateClient(const QByteArray& bytes, trixterxdreamv1client * client) -{ +bool trixterxdreamv1bike::updateClient(const QByteArray& bytes, trixterxdreamv1client * client) { bool stateChanged = false; for(int i=0; iclient)) return; @@ -151,8 +168,7 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) this->elapsed = (currentTime - this->t0) * 0.001; } -void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) -{ +void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { // ignore the resistance if this option was selected if(this->noWriteResistance) return; @@ -171,18 +187,15 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) this->Resistance.setValue(resistanceLevel); } -void trixterxdreamv1bike::updateResistance() -{ +void trixterxdreamv1bike::updateResistance() { this->client.SendResistance(this->resistanceLevel); } -trixterxdreamv1bike::~trixterxdreamv1bike() -{ - +trixterxdreamv1bike::~trixterxdreamv1bike() { + if(this->port) delete this->port; } -void trixterxdreamv1bike::set_wheelDiameter(double value) -{ +void trixterxdreamv1bike::set_wheelDiameter(double value) { // clip the value value = std::min(MaxWheelDiameter, std::max(value, MinWheelDiameter)); @@ -190,15 +203,20 @@ void trixterxdreamv1bike::set_wheelDiameter(double value) this->wheelCircumference = value * M_PI / 1000.0; } -trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering, const QString &portName) -{ +trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering, const QString &portName) { // first check if there's a port specified if(portName!=nullptr && !portName.isEmpty()) { trixterxdreamv1bike * result = new trixterxdreamv1bike(noWriteResistance, noHeartService, noVirtualDevice, noSteering); - if(result->connect(portName)) - return result; - delete result; + try { + if(result->connect(portName)) + return result; + delete result; + } catch(...) { + // make absolutely sure the object is delete otherwise the serial port it opened will remain blocked. + if(result) delete result; + throw; + } return nullptr; } @@ -209,14 +227,12 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo { trixterxdreamv1bike * result = tryCreate(noWriteResistance, noHeartService, noVirtualDevice, noSteering, availablePorts[i].portName()); if(result) return result; - delete result; } return nullptr; } -trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(const QString& portName) -{ +trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(const QString& portName) { return tryCreate(false, false, false, false, portName); } diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 611bf1a41..323d50ef0 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -1,6 +1,7 @@ #pragma once #include "bike.h" #include "trixterxdreamv1client.h" +#include "trixterxdreamv1serial.h" class trixterxdreamv1bike : public bike { @@ -17,7 +18,7 @@ class trixterxdreamv1bike : public bike * @brief port An object that monitors a serial port to read incoming data, and to write * resistance level requests. */ - serialPortMonitor * port = nullptr; + trixterxdreamv1serial * port = nullptr; /** * @brief resistanceTimerId The id for identifying the resistance timer in void timerEvent(QEvent*). @@ -95,8 +96,16 @@ class trixterxdreamv1bike : public bike void updateResistance(); protected: + /** + * @brief timerEvent Processes timer events, e.g. for resistance. + * @param event + */ void timerEvent(QTimerEvent *event) override; + /** + * @brief disconnectPort Disconnect the serial port and resistance timer. + */ + void disconnectPort(); public Q_SLOTS: /** * @brief changeResistance Called to change the requested resistance level. diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 5ef168bfc..5498fba14 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -11,25 +11,37 @@ trixterxdreamv1serial::~trixterxdreamv1serial() { this->wait(); } -QList trixterxdreamv1serial::availablePorts() -{ +QList trixterxdreamv1serial::availablePorts() { return QSerialPortInfo::availablePorts(); } void trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate baudRate, int waitTimeout) { + if(this->isRunning()) + { + qDebug() << "Port is already being monitored."; + this->error("Port is already being monitored."); + return; + } + const QMutexLocker locker(&this->mutex); this->portName = portName; this->baudRate = baudRate; this->waitTimeout = waitTimeout; if (!isRunning()) - start(); + start(); } void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { qDebug() << "serial >> " << buffer.toHex(' ') << "//" << info; + + // obtain a mutex lock to avoid writing during a read QMutexLocker locker(&this->mutex); - qint64 o = serial.write(buffer); + + // write the data + qint64 o = this->serial.write(buffer); + locker.unlock(); + qDebug() << "serial byte written" << o; } @@ -46,19 +58,32 @@ void trixterxdreamv1serial::run() { qDebug() << "Serial port" << this->portName << "opened"; while (!this->quitPending) { + QByteArray requestData; + + // Obtain a mutex lock so it's not waiting for ready read while trying to write... + QMutexLocker locker(&this->mutex); + + // try to read some bytes, but only block for 1ms because a write attempt could come in. + while (this->serial.waitForReadyRead(1)) + requestData += this->serial.readAll(); + + // release the mutex + locker.unlock(); + + if(requestData.length()>0) { - if (this->serial.waitForReadyRead(this->waitTimeout)) { - QMutexLocker locker(&this->mutex); - QByteArray requestData = this->serial.readAll(); - while (this->serial.waitForReadyRead(1)) - requestData += this->serial.readAll(); - locker.unlock(); qDebug() << "serial << " << requestData.toHex(' '); // Send the bytes to the client code + // Unlike the QtSerialPort example that can be found online, this + // is NOT emitting a signal. This is avoid problems with slots, threads and timers, + // which seem to require an advanced course to get working together! this->receive(requestData); + + qDebug() << requestData.length() << " bytes processed"; } } this->serial.close(); + qDebug() << "Serial port closed"; } diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index 1a5ceadfa..e9ba6236d 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -6,6 +6,10 @@ #include #include +/** + * @brief A basic serial port monitoring thread. + * Avoids using signals to prevent complications with objects, threads and timers. + */ class trixterxdreamv1serial : public QThread { Q_OBJECT @@ -28,18 +32,25 @@ class trixterxdreamv1serial : public QThread { */ void write(const QByteArray& buffer, QString info); + void set_receiveBytes(std::function value) { this->receiveBytes = value; } + /** * @brief availablePorts Returns a list of information objects for the serial ports found in the system. */ static QList availablePorts(); - - protected: - virtual void receive(const QByteArray &bytes) {} - virtual void error(const QString &s) {} - virtual void timeout(const QString &s) {} + /** + * @brief receive Override this to process received data. + * @param bytes + */ + virtual void receive(const QByteArray &bytes) { if(this->receiveBytes) this->receiveBytes(bytes); } + /** + * @brief error Log an error. + * @param s The error text. + */ + virtual void error(const QString &s) {} private: void run() override; @@ -50,6 +61,7 @@ class trixterxdreamv1serial : public QThread { int waitTimeout = 1000; QMutex mutex; bool quitPending = false; + std::function receiveBytes=nullptr; }; #endif // TRIXTERXDREAMSERIAL_H From aebe0da9bd2e9d153f027abf003e88f287f41c28 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 6 Aug 2022 01:48:39 +0100 Subject: [PATCH 035/255] #855 removed serialPortMonitor subclass in favour of using a delegate to receive bytes --- src/trixterxdreamv1bike.cpp | 18 ------------------ src/trixterxdreamv1bike.h | 2 -- src/trixterxdreamv1serial.h | 5 +++++ 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 9222b8ee0..27d57adb4 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -8,24 +8,6 @@ using namespace std; - -class trixterxdreamv1bike::serialPortMonitor : public trixterxdreamv1serial -{ - protected: - trixterxdreamv1bike * bike = nullptr; - - void receive(const QByteArray &bytes) override - { - this->bike->update(bytes); - } - -public: - explicit serialPortMonitor(trixterxdreamv1bike * bike) { - this->bike = bike; - } -}; - - trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) { // Set the wheel diameter for speed and distance calculations this->set_wheelDiameter(DefaultWheelDiameter); diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 323d50ef0..cc94813de 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -7,8 +7,6 @@ class trixterxdreamv1bike : public bike { Q_OBJECT private: - class serialPortMonitor; - /** * @brief client An object that processes incoming data to CSCS, heart rate and steering data */ diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index e9ba6236d..74c6d6271 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -32,6 +32,11 @@ class trixterxdreamv1serial : public QThread { */ void write(const QByteArray& buffer, QString info); + /** + * @brief set_receiveBytes Set a delegate to receive bytes. This is an alternative + * to sublcassing and overrding the virtual receive function. + * @param value + */ void set_receiveBytes(std::function value) { this->receiveBytes = value; } /** From 78facacf42607d9be3c129ee2b9a1ae091fbb645 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 6 Aug 2022 03:15:12 +0100 Subject: [PATCH 036/255] #855 only consider ttyUSB* in Linux --- src/trixterxdreamv1bike.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 27d57adb4..32ed0d9b4 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -207,6 +207,10 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo for(int i=0; i Date: Sat, 6 Aug 2022 12:51:25 +0100 Subject: [PATCH 037/255] #855 fix Linux port name --- src/trixterxdreamv1bike.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 32ed0d9b4..cb405d11e 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -208,7 +208,7 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo for(int i=0; i Date: Sat, 6 Aug 2022 14:32:52 +0100 Subject: [PATCH 038/255] #855 additional logging and serial port configuration --- src/trixterxdreamv1bike.cpp | 19 ++++++++++++++++--- src/trixterxdreamv1serial.cpp | 8 ++++++-- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index cb405d11e..a6ebd206f 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -189,16 +189,25 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo // first check if there's a port specified if(portName!=nullptr && !portName.isEmpty()) { + qDebug() << "Looking for Trixter X-Dream V1 device on port: " << portName; trixterxdreamv1bike * result = new trixterxdreamv1bike(noWriteResistance, noHeartService, noVirtualDevice, noSteering); try { - if(result->connect(portName)) + if(result->connect(portName)) { + qDebug() << "Found Trixter X-Dream V1 device on port: " << portName; return result; + } delete result; } catch(...) { + qDebug() << "Error thrown looking for Trixter X-Dream V1 device on port: " << portName; + // make absolutely sure the object is delete otherwise the serial port it opened will remain blocked. - if(result) delete result; + if(result) { + qDebug() << "Deleting object that was not able to connect"; + delete result; + } throw; } + qDebug() << "No Trixter X-Dream V1 device found on port: " << portName; return nullptr; } @@ -209,10 +218,14 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo { #if defined(Q_OS_LINUX) if(!availablePorts[i].portName().startsWith("/dev/ttyUSB")) + { + qDebug() << "Skipping port: " << availablePorts[i].portName() << " because it doesn't start with /dev/ttyUSB" continue; + } #endif trixterxdreamv1bike * result = tryCreate(noWriteResistance, noHeartService, noVirtualDevice, noSteering, availablePorts[i].portName()); - if(result) return result; + if(result) + return result; } return nullptr; diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 5498fba14..09165cd95 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -47,8 +47,12 @@ void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { void trixterxdreamv1serial::run() { - serial.setPortName(this->portName); - serial.setBaudRate(this->baudRate); + this->serial.setPortName(this->portName); + this->serial.setBaudRate(this->baudRate); + this->serial.setDataBits(QSerialPort::Data8); + this->serial.setStopBits(QSerialPort::OneStop); + this->serial.setFlowControl(QSerialPort::NoFlowControl); + this->serial.setParity(QSerialPort::NoParity); if (!serial.open(QIODevice::ReadWrite)) { qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error()); From debe7fd277b29c059dfcf45b8891698669d94e87 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 6 Aug 2022 14:34:19 +0100 Subject: [PATCH 039/255] #855 fix for Linux build --- src/trixterxdreamv1bike.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index a6ebd206f..25c11a6f1 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -219,7 +219,7 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo #if defined(Q_OS_LINUX) if(!availablePorts[i].portName().startsWith("/dev/ttyUSB")) { - qDebug() << "Skipping port: " << availablePorts[i].portName() << " because it doesn't start with /dev/ttyUSB" + qDebug() << "Skipping port: " << availablePorts[i].portName() << " because it doesn't start with /dev/ttyUSB"; continue; } #endif From a61d8e7eef3cf4c0ec40c50039e1785145f9d367 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 6 Aug 2022 15:25:32 +0100 Subject: [PATCH 040/255] #855 additional debug logging --- src/bluetooth.cpp | 14 ++++++++++---- src/trixterxdreamv1bike.cpp | 18 +++++++++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index fa4d0148e..eb951dc97 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -201,11 +201,17 @@ void bluetooth::debug(const QString &text) { trixterxdreamv1bike * bluetooth::findTrixterXDreamV1Bike(const QSettings& settings) { bool trixterxdreamv1bikeEnabled = settings.value(QStringLiteral("trixter_xdream_v1_bike")).toBool(); + trixterxdreamv1bike * result = nullptr; + if(trixterxdreamv1bikeEnabled) { + debug("Looking for Trixter X-Dream V1 Bike"); + result = trixterxdreamv1bike::tryCreate(this->noWriteResistance, this->noHeartService, false, false); + if(!result) + debug("Failed to find a Trixter X-Dream V1 Bike"); + } else { + debug("Not looking for Trixter X-Dream V1 Bike - disabled in settings"); + } - if(trixterxdreamv1bikeEnabled) - return trixterxdreamv1bike::tryCreate(this->noWriteResistance, this->noHeartService, false, false); - - return nullptr; + return result; } bool bluetooth::cscSensorAvaiable() { diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 25c11a6f1..929fd2936 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -216,14 +216,26 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo for(int i=0; i Date: Sat, 6 Aug 2022 16:14:57 +0100 Subject: [PATCH 041/255] Merge remote-tracking branch 'remotes/origin/master' into trixter-xdream-v1-bike --- src/settings.qml | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/src/settings.qml b/src/settings.qml index d2934f38f..83dbebcbf 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -450,9 +450,11 @@ import Qt.labs.settings 1.0 property real ss2k_max_resistance: 100 property real ss2k_min_resistance: 0 - - // from the version 2.11.10 + // from the version 2.11.10 property bool proform_treadmill_se: false + + // from the version 2.11.14 + property string proformtreadmillip: "" // from the version ? property bool trixter_xdream_v1_bike: false @@ -4434,6 +4436,30 @@ import Qt.labs.settings 1.0 Layout.fillWidth: true onClicked: settings.proform_treadmill_se = checked } + RowLayout { + spacing: 10 + Label { + id: labelproformtreadmillip + text: qsTr("Proform IP:") + Layout.fillWidth: true + } + TextField { + id: proformtreadmillIPTextField + text: settings.proformtreadmillip + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.proformtreadmillip = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okproformtreadmillIPButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.proformtreadmillip = proformtreadmillIPTextField.text + } + } RowLayout { spacing: 10 Label { From 807871c29a2ae8935f32bdc97de249b0df1315f9 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 7 Aug 2022 00:59:48 +0100 Subject: [PATCH 042/255] #855 fix serial port name pattern for Linux --- src/trixterxdreamv1bike.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 929fd2936..7800d2a1a 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -219,9 +219,9 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo auto port = availablePorts[i]; #if defined(Q_OS_LINUX) - if(!port.portName().startsWith("/dev/ttyUSB")) + if(!port.portName().startsWith("ttyUSB")) { - qDebug() << "Skipping port: " << port.portName() << " because it doesn't start with /dev/ttyUSB"; + qDebug() << "Skipping port: " << port.portName() << " because it doesn't start with ttyUSB"; continue; } #endif From 001925638a9b143dce3f97f6d01b0ec56a269128 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 8 Aug 2022 01:08:15 +0100 Subject: [PATCH 043/255] #855 added steering calibration options, encapsulated settings for this device in a class, implemented automatic update of settings. --- src/bluetooth.cpp | 4 +- src/qdomyos-zwift.pro | 2 + src/settings.qml | 142 +++++++++++++++++++++- src/trixterxdreamv1bike.cpp | 85 +++++++++++-- src/trixterxdreamv1bike.h | 47 +++++++- src/trixterxdreamv1serial.cpp | 2 +- src/trixterxdreamv1settings.cpp | 133 +++++++++++++++++++++ src/trixterxdreamv1settings.h | 206 ++++++++++++++++++++++++++++++++ 8 files changed, 600 insertions(+), 21 deletions(-) create mode 100644 src/trixterxdreamv1settings.cpp create mode 100644 src/trixterxdreamv1settings.h diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 3dc505ea7..4341cf629 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -200,11 +200,11 @@ void bluetooth::debug(const QString &text) { trixterxdreamv1bike * bluetooth::findTrixterXDreamV1Bike(const QSettings& settings) { - bool trixterxdreamv1bikeEnabled = settings.value(QStringLiteral("trixter_xdream_v1_bike")).toBool(); + bool trixterxdreamv1bikeEnabled = settings.value(trixterxdreamv1settings::keys::Enabled, false).toBool(); trixterxdreamv1bike * result = nullptr; if(trixterxdreamv1bikeEnabled) { debug("Looking for Trixter X-Dream V1 Bike"); - result = trixterxdreamv1bike::tryCreate(this->noWriteResistance, this->noHeartService, false, false); + result = trixterxdreamv1bike::tryCreate(this->noWriteResistance, this->noHeartService, false); if(!result) debug("Failed to find a Trixter X-Dream V1 Bike"); } else { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index 70a53b226..2e231281f 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -225,6 +225,7 @@ SOURCES += \ trixterxdreamv1bike.cpp \ trixterxdreamv1client.cpp \ trixterxdreamv1serial.cpp \ + trixterxdreamv1settings.cpp \ truetreadmill.cpp \ trxappgateusbbike.cpp \ ultrasportbike.cpp \ @@ -626,6 +627,7 @@ HEADERS += \ trixterxdreamv1bike.h \ trixterxdreamv1client.h \ trixterxdreamv1serial.h \ + trixterxdreamv1settings.h \ truetreadmill.h \ trxappgateusbbike.h \ trxappgateusbtreadmill.h \ diff --git a/src/settings.qml b/src/settings.qml index 83dbebcbf..35f2b0d31 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -458,6 +458,11 @@ import Qt.labs.settings 1.0 // from the version ? property bool trixter_xdream_v1_bike: false + property bool trixter_xdream_v1_bike_steering_enabled: true + property int trixter_xdream_v1_bike_steering_center: 127 + property int trixter_xdream_v1_bike_steering_deadzone_width: 20 + property int trixter_xdream_v1_bike_steering_sensitivity_left: 100 + property int trixter_xdream_v1_bike_steering_sensitivity_right: 100 } function paddingZeros(text, limit) { @@ -1716,7 +1721,9 @@ import Qt.labs.settings 1.0 accordionContent: SwitchDelegate { id: trixterXDreamV1 - text: qsTr("Trixter X-Dream V1 Bike") + text: qsTr("Trixter X-Dream V1 Bike Enabled") + ToolTip.visible: hovered + ToolTip.text: qsTr("Use this to enable or disable detection of the Trixter X-Dream V1 Bike.") spacing: 0 bottomPadding: 0 topPadding: 0 @@ -1728,6 +1735,139 @@ import Qt.labs.settings 1.0 Layout.fillWidth: true onClicked: settings.trixter_xdream_v1_bike = checked } + SwitchDelegate { + id: trixterXDreamV1Steering + text: qsTr("Steering Enabled") + ToolTip.visible: hovered + ToolTip.text: qsTr("Use this to enable or disable steering.") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.trixter_xdream_v1_bike_steering_enabled + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.settings.trixter_xdream_v1_bike_steering_enabled = checked + } + RowLayout { + spacing: 10 + Label { + id: labelTrixterXDreamV1BikeSteeringCenter + text: qsTr("Steering Center") + Layout.fillWidth: true + } + TextField { + id: trixterXDreamV1BikeSteeringCenterTextField + text: settings.trixter_xdream_v1_bike_steering_center + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Use this setting to adjust the steering angle for the resting position of the handle bars. Default=127. Full range of steering is 0 (left) to 255 (right).") + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + // this should be in sync with trixterxdreamv1bikesettings::MinSteeringCenter and MaxSteeringCenter + validator: IntValidator {bottom: 67; top: 187;} + onAccepted: settings.trixter_xdream_v1_bike_steering_center = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: oktrixterXDreamV1BikeSteeringCenterButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trixter_xdream_v1_bike_steering_center = trixterXDreamV1BikeSteeringCenterTextField.text + } + } + RowLayout { + spacing: 10 + Label { + id: labelTrixterXDreamV1BikeSteeringDeadZoneWidth + text: qsTr("Steering Dead Zone Width") + Layout.fillWidth: true + } + TextField { + id: trixterXDreamV1BikeSteeringDeadZoneWidthTextField + text: settings.trixter_xdream_v1_bike_steering_deadzone_width + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("The width from left to right of the region where the steering value will be mapped to 0 degrees. Full range of steering is 0 (left) to 255 (right).") + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + // this should be in sync with trixterxdreamv1bikesettings::MinSteeringDeadZoneWidth and MaxSteeringDeadZoneWidth + validator: IntValidator {bottom: 0; top: 50;} + onAccepted: settings.trixter_xdream_v1_bike_steering_deadzone_width = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: oktrixterXDreamV1BikeSteeringDeadZoneWidthButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trixter_xdream_v1_bike_steering_deadzone_width = trixterXDreamV1BikeSteeringDeadZoneWidthTextField.text + } + } + RowLayout { + spacing: 10 + Label { + id: labelTrixterXDreamV1BikeSteeringSensitivityLeft + text: qsTr("Steering Sensitivity Left (%)") + Layout.fillWidth: true + } + TextField { + id: trixterXDreamV1BikeSteeringSensitivityLeftTextField + text: settings.trixter_xdream_v1_bike_steering_sensitivity_left + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Use this setting to adjust the sensitivity of the steering when turning left.") + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + // this should be in sync with trixterxdreamv1bikesettings::MinSteeringSensitivity and MaxSteeringSensitivity + validator: IntValidator {bottom: 20; top: 200;} + onAccepted: settings.trixter_xdream_v1_bike_steering_sensitivity_left = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: oktrixterXDreamV1BikeSteeringSensitivityLeftButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trixter_xdream_v1_bike_steering_sensitivity_left = trixterXDreamV1BikeSteeringSensitivityLeftTextField.text + } + } + RowLayout { + spacing: 10 + Label { + id: labelTrixterXDreamV1BikeSteeringSensitivityRight + text: qsTr("Steering Sensitivity Right (%)") + Layout.fillWidth: true + } + TextField { + id: trixterXDreamV1BikeSteeringSensitivityRightTextField + text: settings.trixter_xdream_v1_bike_steering_sensitivity_right + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Use this setting to adjust the sensitivity of the steering when turning right.") + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + // this should be in sync with trixterxdreamv1bikesettings::MinSteeringSensitivity and MaxSteeringSensitivity + validator: IntValidator {bottom: 20; top: 200;} + onAccepted: settings.trixter_xdream_v1_bike_steering_sensitivity_left = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: oktrixterXDreamV1BikeSteeringSensitivityRightButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trixter_xdream_v1_bike_steering_sensitivity_right = trixterXDreamV1BikeSteeringSensitivityRightTextField.text + } + } + } AccordionElement { id: flywheelBikeAccordion diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 7800d2a1a..50aeabc01 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -1,6 +1,8 @@ #include "trixterxdreamv1bike.h" -#include "qcoreevent.h" #include "trixterxdreamv1serial.h" +#include "trixterxdreamv1settings.h" +#include "qcoreevent.h" + #include #include #include @@ -8,15 +10,21 @@ using namespace std; -trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering) { +trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice) { // Set the wheel diameter for speed and distance calculations this->set_wheelDiameter(DefaultWheelDiameter); + // Create the settings object and load from QSettings. + this->appSettings = new trixterxdreamv1settings(); + // QZ things from expected constructor this->noWriteResistance = noWriteResistance; this->noHeartService = noHeartService; this->noVirtualDevice = noVirtualDevice; - this->noSteering = noSteering; + this->noSteering = !appSettings->get_steeringEnabled(); + + // Calculate the steering mapping + this->calculateSteeringMap(); } bool trixterxdreamv1bike::connect(QString portName) { @@ -59,6 +67,12 @@ bool trixterxdreamv1bike::connect(QString portName) { } } + this->settingsUpdateTimerId = this->startTimer(SettingsUpdateTimerIntervalMilliseconds, Qt::VeryCoarseTimer); + if(this->settingsUpdateTimerId==0) + { + qDebug() << "Failed to start settings update timer. Too bad."; + } + if(!this->connected()) { qDebug() << "Failed to connect to device"; @@ -80,6 +94,11 @@ void trixterxdreamv1bike::disconnectPort() { this->killTimer(this->resistanceTimerId); this->resistanceTimerId = 0; } + if(this->settingsUpdateTimerId) { + qDebug() << "Kiling settings update timer"; + this->killTimer(this->settingsUpdateTimerId); + this->settingsUpdateTimerId = 0; + } } bool trixterxdreamv1bike::connected() { @@ -94,10 +113,14 @@ uint32_t trixterxdreamv1bike::getTime() { } void trixterxdreamv1bike::timerEvent(QTimerEvent *event) { - if(event->timerId()==this->resistanceTimerId) - { + int timerId = event->timerId(); + + if(timerId==this->resistanceTimerId){ event->accept(); this->updateResistance(); + } else if(timerId==this->settingsUpdateTimerId) { + event->accept(); + this->appSettings->Load(); } } @@ -141,15 +164,53 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // set the crank revolutions this->CrankRevs = state.CumulativeCrankRevolutions; + // check if the settings have been updated and adjust accordingly + if(this->appSettings->get_version()!=this->lastAppSettingsVersion) { + this->noSteering = !this->appSettings->get_steeringEnabled(); + if(this->noSteering) + this->m_steeringAngle.setValue(0.0); + else + this->calculateSteeringMap(); + this->lastAppSettingsVersion = this->appSettings->get_version(); + } + // Set the steering - constexpr double steeringScale = 90.0 / trixterxdreamv1client::MaxSteering; - if(!this->noSteering) - this->m_steeringAngle.setValue(round(steeringScale * state.Steering - 45.0)); + if(!this->noSteering) { + this->m_steeringAngle.setValue(this->steeringMap[state.Steering]); + } // set the elapsed time this->elapsed = (currentTime - this->t0) * 0.001; } +void trixterxdreamv1bike::calculateSteeringMap() { + + constexpr double maxSteeringAngle = 45.0; + + this->steeringMap.clear(); + + int halfDeadZone = this->appSettings->get_steeringDeadZoneWidth()/2; + int deadZoneLeft = this->appSettings->get_steeringCenter()-halfDeadZone; + int deadZoneRight = this->appSettings->get_steeringCenter()+halfDeadZone; + double sensitivityLeft = 0.01 * this->appSettings->get_steeringSensitivityLeft(); + double sensitivityRight = 0.01 * this->appSettings->get_steeringSensitivityRight(); + double scaleLeft = sensitivityLeft * maxSteeringAngle / deadZoneLeft; + double scaleRight = sensitivityRight * maxSteeringAngle / (trixterxdreamv1client::MaxSteering - deadZoneRight); + + for(int i=0; i<=trixterxdreamv1client::MaxSteering; i++) { + double mappedValue; + if(i>=deadZoneLeft && i<=deadZoneRight) { + mappedValue = 0.0; + } else if (isteeringMap.push_back(mappedValue); + } + +} + void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { // ignore the resistance if this option was selected if(this->noWriteResistance) @@ -185,12 +246,12 @@ void trixterxdreamv1bike::set_wheelDiameter(double value) { this->wheelCircumference = value * M_PI / 1000.0; } -trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering, const QString &portName) { +trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, const QString &portName) { // first check if there's a port specified if(portName!=nullptr && !portName.isEmpty()) { qDebug() << "Looking for Trixter X-Dream V1 device on port: " << portName; - trixterxdreamv1bike * result = new trixterxdreamv1bike(noWriteResistance, noHeartService, noVirtualDevice, noSteering); + trixterxdreamv1bike * result = new trixterxdreamv1bike(noWriteResistance, noHeartService, noVirtualDevice); try { if(result->connect(portName)) { qDebug() << "Found Trixter X-Dream V1 device on port: " << portName; @@ -235,7 +296,7 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo << "," << "isNull:" << port.isNull() << "," << "serialNumber:" << port.serialNumber(); - trixterxdreamv1bike * result = tryCreate(noWriteResistance, noHeartService, noVirtualDevice, noSteering, port.portName()); + trixterxdreamv1bike * result = tryCreate(noWriteResistance, noHeartService, noVirtualDevice, port.portName()); if(result) return result; } @@ -244,7 +305,7 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo } trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(const QString& portName) { - return tryCreate(false, false, false, false, portName); + return tryCreate(false, false, false, portName); } diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index cc94813de..9de88103e 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -1,12 +1,20 @@ #pragma once #include "bike.h" +#include "qsettings.h" #include "trixterxdreamv1client.h" #include "trixterxdreamv1serial.h" +#include "trixterxdreamv1settings.h" class trixterxdreamv1bike : public bike { Q_OBJECT + private: + /** + * @brief SettingsUpdateTimerIntervalMilliseconds The object will check for a settings update at this interval. + */ + constexpr static int SettingsUpdateTimerIntervalMilliseconds = 10000; + /** * @brief client An object that processes incoming data to CSCS, heart rate and steering data */ @@ -23,6 +31,11 @@ class trixterxdreamv1bike : public bike */ int resistanceTimerId = 0; + /** + * @brief settingsUpdateTimerId The id for identifying the settings update timer in void timerEvent(QEVent*). + */ + int settingsUpdateTimerId = 0; + /** * @brief noHeartService Suppress heart rate readings. */ @@ -39,7 +52,7 @@ class trixterxdreamv1bike : public bike bool noWriteResistance; /** - * @brief noSteering Suppress steering readings. + * @brief noSteering Suppress steering readings */ bool noSteering; @@ -69,6 +82,21 @@ class trixterxdreamv1bike : public bike */ uint32_t lastPacketProcessedTime=0; + /** + * @brief appSettings The application settings. + */ + trixterxdreamv1settings * appSettings; + + /** + * @brief lastAppSettingsVersion The last app settings version that was used to configure the object. + */ + uint32_t lastAppSettingsVersion=0; + + /** + * @brief steeringMap Stores the mapping between incoming steering values and the steering angles expected by the application. + */ + std::vector steeringMap; + /** * @brief getTime Gets the time in miliseconds since this object was created. */ @@ -92,6 +120,12 @@ class trixterxdreamv1bike : public bike * device. */ void updateResistance(); + + /** + * @brief calculateSteering Calculates the mapping between steering values coming from the device, and + * the steering angles sent to the application. Uses the values in the appSettings field. + */ + void calculateSteeringMap(); protected: /** @@ -145,9 +179,8 @@ public Q_SLOTS: * @param noWriteResistance Option to avoid sending resistance to the device. * @param noHeartService Option to avoid using the heart rate reading. * @param noVirtualDevice Option to avoid using a virtual device. - * @param noSteering Option to avoid using the steering reading. */ - trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering); + trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice); ~trixterxdreamv1bike(); @@ -168,6 +201,11 @@ public Q_SLOTS: */ void set_wheelDiameter(double value); + /** + * @brief get_appSettings Gets the settings object for this device type. + */ + const trixterxdreamv1settings * get_appSettings() { return this->appSettings; } + /** * @brief maxResistance The maximum resistance supported. * @return @@ -180,11 +218,10 @@ public Q_SLOTS: * @param noWriteResistance Option to avoid sending resistance to the device. * @param noHeartService Option to avoid using the heart rate reading. * @param noVirtualDevice Option to avoid using a virtual device. - * @param noSteering Option to avoid using the steering reading. * @param portName (Optional) The specific port to search. * @return nullptr if no device is found, an object if a device is found and connected. */ - static trixterxdreamv1bike * tryCreate(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, bool noSteering, const QString& portName = nullptr); + static trixterxdreamv1bike * tryCreate(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, const QString& portName = nullptr); /** * @brief tryCreate Attempt to create an object to interact with an existing Trixter X-Dream V1 bike on a specific serial port, diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 09165cd95..d0aa16622 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -32,7 +32,7 @@ void trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate } void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { - qDebug() << "serial >> " << buffer.toHex(' ') << "//" << info; + qDebug() << "serial >> " << buffer.toHex() << "//" << info; // obtain a mutex lock to avoid writing during a read QMutexLocker locker(&this->mutex); diff --git a/src/trixterxdreamv1settings.cpp b/src/trixterxdreamv1settings.cpp new file mode 100644 index 000000000..74919db14 --- /dev/null +++ b/src/trixterxdreamv1settings.cpp @@ -0,0 +1,133 @@ +#include "trixterxdreamv1settings.h" + +const QString trixterxdreamv1settings::keys::Enabled = QStringLiteral("trixter_xdream_v1_bike"); +const QString trixterxdreamv1settings::keys::SteeringEnabled = QStringLiteral("trixter_xdream_v1_bike_steering_enabled"); +const QString trixterxdreamv1settings::keys::SteeringCenter = QStringLiteral("trixter_xdream_v1_bike_steering_center"); +const QString trixterxdreamv1settings::keys::SteeringDeadZoneWidth =QStringLiteral("trixter_xdream_v1_bike_steering_deadzone_width"); +const QString trixterxdreamv1settings::keys::SteeringSensitivityLeft = QStringLiteral("trixter_xdream_v1_bike_steering_sensitivity_left"); +const QString trixterxdreamv1settings::keys::SteeringSensitivityRight= QStringLiteral("trixter_xdream_v1_bike_steering_sensitivity_right"); + +uint8_t trixterxdreamv1settings::updateField(uint8_t &member, const uint8_t newValue){ + QMutexLocker locker(&this->mutex); + if(member!=newValue) { + member = newValue; + this->version++; + } + return newValue; +} + +bool trixterxdreamv1settings::updateField(bool &member, const bool newValue){ + QMutexLocker locker(&this->mutex); + if(member!=newValue) { + member = newValue; + this->version++; + } + return newValue; +} + +uint32_t trixterxdreamv1settings::get_version() { + QMutexLocker locker(&this->mutex); + return this->version; +} + +bool trixterxdreamv1settings::get_enabled() { + QMutexLocker locker(&this->mutex); + return this->enabled; +} + +bool trixterxdreamv1settings::set_enabled(bool value) { + return this->updateField(this->enabled, value); +} + +bool trixterxdreamv1settings::get_steeringEnabled() { + QMutexLocker locker(&this->mutex); + return this->steeringEnabled; +} + +bool trixterxdreamv1settings::set_steeringEnabled(bool value) { + return this->updateField(this->steeringEnabled, value); +} + +uint8_t trixterxdreamv1settings::get_steeringCenter() { + QMutexLocker locker(&this->mutex); + return this->steeringCenter; +} + +uint8_t trixterxdreamv1settings::set_steeringCenter(uint8_t value) { + auto newValue = clip(MinSteeringCenter, MaxSteeringCenter, value); + return this->updateField(this->steeringCenter, newValue); +} + +uint8_t trixterxdreamv1settings::get_steeringDeadZoneWidth() { + QMutexLocker locker(&this->mutex); + return this->steeringDeadZoneWidth; +} + +uint8_t trixterxdreamv1settings::set_steeringDeadZoneWidth(uint8_t value) { + auto newValue = clip(MinSteeringDeadZoneWidth, MaxSteeringDeadZoneWidth, value); + return this->updateField(this->steeringDeadZoneWidth, newValue); +} + +uint8_t trixterxdreamv1settings::get_steeringSensitivityLeft() { + QMutexLocker locker(&this->mutex); + return this->steeringSensitivityLeft; +} + +uint8_t trixterxdreamv1settings::set_steeringSensitivityLeft(uint8_t value) { + auto newValue = clip(MinSteeringSensitivityPercentage, MaxSteeringSensitivityPercentage, value); + return this->updateField(this->steeringSensitivityLeft, newValue); +} + +uint8_t trixterxdreamv1settings::get_steeringSensitivityRight() { + QMutexLocker locker(&this->mutex); + return this->steeringSensitivityRight; +} + +uint8_t trixterxdreamv1settings::set_steeringSensitivityRight(uint8_t value) { + auto newValue = clip(MinSteeringSensitivityPercentage, MaxSteeringSensitivityPercentage, value); + return this->updateField(this->steeringSensitivityRight, newValue); +} + +trixterxdreamv1settings::trixterxdreamv1settings() { + QSettings defaultSettings; + this->Load(defaultSettings); + this->version = 1; +} + +trixterxdreamv1settings::trixterxdreamv1settings(const QSettings &settings) { + this->Load(settings); + this->version = 1; +} + +void trixterxdreamv1settings::Load() { + QSettings settings; + this->Load(settings); +} + +void trixterxdreamv1settings::Load(const QSettings &settings) { + QMutexLocker locker(&this->mutex); + this->set_enabled(settings.value(keys::Enabled, DefaultEnabled).toBool()); + this->set_steeringEnabled(settings.value(keys::SteeringEnabled, DefaultSteeringEnabled).toBool()); + this->set_steeringCenter(settings.value(keys::SteeringCenter, DefaultSteeringCenter).toUInt()); + this->set_steeringDeadZoneWidth(settings.value(keys::SteeringDeadZoneWidth, DefaultSteeringDeadZoneWidth).toUInt()); + this->set_steeringSensitivityLeft(settings.value(keys::SteeringSensitivityLeft, DefaultSteeringSensitivity).toUInt()); + this->set_steeringSensitivityRight(settings.value(keys::SteeringSensitivityRight, DefaultSteeringSensitivity).toUInt()); +} + +/* +void trixterxdreamv1bikesettings::Save() { + QSettings settings; + this->Save(settings); +} + +void trixterxdreamv1bikesettings::Save(const QSettings &settings) { + QMutexLocker locker(&this->mutex); + settings.value(keys::Enabled).setValue(this->enabled); + settings.value(keys::SteeringEnabled).setValue(this->steeringEnabled); + settings.value(keys::SteeringCenter).setValue(this->steeringCenter); + settings.value(keys::SteeringDeadZoneWidth).setValue(this->steeringDeadZoneWidth); + settings.value(keys::SteeringSensitivityLeft).setValue(this->steeringSensitivityLeft); + settings.value(keys::SteeringSensitivityRight).setValue(this->steeringSensitivityRight); +} + +*/ diff --git a/src/trixterxdreamv1settings.h b/src/trixterxdreamv1settings.h new file mode 100644 index 000000000..cbe47a37b --- /dev/null +++ b/src/trixterxdreamv1settings.h @@ -0,0 +1,206 @@ +#ifndef TRIXTERXDREAMV1SETTINGS_H +#define TRIXTERXDREAMV1SETTINGS_H + + +#include +#include "qmutex.h" +#include "qsettings.h" +#include "trixterxdreamv1client.h" + + +/** + * @brief The trixterxdreamv1bikesettings class encapsulates the application settings for the Trixter X-Dream V1 Bike. + * Field accessors restrict values to defined limits. + */ +class trixterxdreamv1settings { +public: + constexpr static bool DefaultEnabled =true; + constexpr static bool DefaultSteeringEnabled =true; + constexpr static uint8_t DefaultSteeringCenter = trixterxdreamv1client::MaxSteering/2; + constexpr static uint8_t DefaultSteeringDeadZoneWidth = 20; + constexpr static uint8_t DefaultSteeringSensitivity = 100; + constexpr static uint8_t MinSteeringCenter = DefaultSteeringCenter-60; + constexpr static uint8_t MaxSteeringCenter = DefaultSteeringCenter+60; + constexpr static uint8_t MaxSteeringDeadZoneWidth = 50; + constexpr static uint8_t MinSteeringDeadZoneWidth = 0; + constexpr static uint8_t MinSteeringSensitivityPercentage = 20; + constexpr static uint8_t MaxSteeringSensitivityPercentage = 200; + + /** + * @brief Defines QSettings keys relating to the Trixter X-Dream V1 bike. + */ + class keys { + public: + /** + * @brief Enabled QSettings key to specify if the Trixter X-Dream V1 Bike is enabled in the application. + */ + const static QString Enabled; + const static QString SteeringEnabled; + const static QString SteeringCenter; + const static QString SteeringDeadZoneWidth; + const static QString SteeringSensitivityLeft; + const static QString SteeringSensitivityRight; + }; + +private: + // mutex for thread syncing, may attempt double lock when loading from QSettings, so using recursive mutex + QRecursiveMutex mutex; + bool enabled=DefaultEnabled; + bool steeringEnabled = DefaultSteeringEnabled; + uint8_t steeringCenter = DefaultSteeringCenter; + uint8_t steeringDeadZoneWidth = DefaultSteeringDeadZoneWidth; + uint8_t steeringSensitivityLeft = DefaultSteeringSensitivity; + uint8_t steeringSensitivityRight = DefaultSteeringSensitivity; + uint32_t version=0; + + /** + * @brief clip Clips the value to be within the specified minimum and maximum. + * @param minimum The minimum value. + * @param maximum The maximum value. + * @param value The value to clip. + */ + static uint8_t clip(uint8_t minimum, uint8_t maximum, uint8_t value) { return std::max(minimum, std::min(maximum, value)); } + + /** + * @brief updateField Updates a field and increments the version if the value has changed. + * @param member The member to update. + * @param newValue The new value. + * @return The value set. + */ + uint8_t updateField(uint8_t& member, const uint8_t newValue); + + /** + * @brief updateField Updates a field and increments the version if the value has changed. + * @param member The member to update. + * @param newValue The new value. + * @return The value set. + */ + bool updateField(bool& member, const bool newValue); + +public: + /** + * @brief get_version Incremented if the values are modified. + */ + uint32_t get_version(); + + /** + * @brief get_enabled Indicates if the device is enabled, i.e. should be searched for. + */ + bool get_enabled(); + + /** + * @brief set_enabled Sets whether or not the type of device is enabled in the application. + * @param value The value to set. + * @return The actual value set. + */ + bool set_enabled(bool value); + + /** + * @brief get_steeringEnabled Indicates if the steering is enabled. + */ + bool get_steeringEnabled(); + + /** + * @brief set_steeringEnabled Enables/disables steering. + * @param value True to use steering data, false to ignore it. + * @return The actual value set; + */ + bool set_steeringEnabled(bool value); + + /** + * @brief get_steeringCenter Gets the value considered to be the center position for the steering. + * Defaults to half of trixterxdreamv1client::MaxSteering, but in reality is somewhat different + * due to physical calibration. + */ + uint8_t get_steeringCenter(); + + /** + * @brief set_steeringCenter Sets the steering center value. Used to accomodate the bike's calibration. + * @param value The value, will be clipped to [MinSteeringCenter, MaxSteeringCenter]. + * @return The actual value set. + */ + uint8_t set_steeringCenter(uint8_t value); + + /** + * @brief get_steeringDeadZoneWidth Gets the width of the dead zone. This is the region + * from the left to the right of steeringCenter for which the steering value will be mapped to 0 degrees. + */ + uint8_t get_steeringDeadZoneWidth(); + + /** + * @brief set_steeringDeadZoneWidth Sets the width, left to right, of the "dead zone" surrounding the + * steeringCenter value, for which the steering value will be mapped to 0 degrees. + * @param value The width, left to right, of the dead zone. Clipped to [MinSteeringDeadZoneWidth, MaxSteeringDeadZoneWidth]. + * @return + */ + uint8_t set_steeringDeadZoneWidth(uint8_t value); + + /** + * @brief get_steeringSensitivityLeft Gets the sensitivity, as a percentage for how sensitive the + * steering will be when turning left. + * @return + */ + uint8_t get_steeringSensitivityLeft(); + + /** + * @brief set_steeringSensitivityLeft Sets the sensitivity, as a percentage, for how sensitive the steering + * will be when turning left. + * @param value The value, a percentage clipped to [MinSteeringSensitivityPercentage, MaxSteeringSensitivityPercentage]. + * @return The actual value set. + */ + uint8_t set_steeringSensitivityLeft(uint8_t value); + + /** + * @brief get_steeringSensitivityLeft Gets the sensitivity, as a percentage for how sensitive the + * steering will be when turning right. Valid range 20 to 200. + * @return + */ + uint8_t get_steeringSensitivityRight(); + + + /** + * @brief set_steeringSensitivityRight Sets the sensitivity, as a percentage, for how sensitive the steering + * will be when turning right. + * @param value The value, a percentage clipped to [MinSteeringSensitivityPercentage, MaxSteeringSensitivityPercentage]. + * @return The actual value set. + */ + uint8_t set_steeringSensitivityRight(uint8_t value); + + /** + * @brief trixterxdreamv1bikesettings Constructor, intializes from the default QSettings. + */ + trixterxdreamv1settings(); + + /** + * @brief trixterxdreamv1bikesettings Constructor, initializes from the specified QSettings. + * @param settings + */ + trixterxdreamv1settings(const QSettings& settings); + + /** + * @brief Load Loads the values from the default settings. + */ + void Load(); + + /** + * @brief Load Loads the values from the specified QSettings object. + * @param settings + */ + void Load(const QSettings& settings); + + + ///** + // * @brief Save Saves the values to the default QSettings object. + // */ + //void Save(); + + ///** + // * @brief Save Saves the values to the specified QSettings object. + // * @param settings + // */ + //void Save(const QSettings& settings); + +}; + + +#endif // TRIXTERXDREAMV1SETTINGS_H From 5103bbfc3a427ef001bcc3913de3f0f35b5587e0 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 8 Aug 2022 01:23:53 +0100 Subject: [PATCH 044/255] #855 delete the appSettings value in the destructor --- src/trixterxdreamv1bike.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 50aeabc01..de551cd34 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -236,6 +236,7 @@ void trixterxdreamv1bike::updateResistance() { trixterxdreamv1bike::~trixterxdreamv1bike() { if(this->port) delete this->port; + if(this->appSettings) delete this->appSettings; } void trixterxdreamv1bike::set_wheelDiameter(double value) { From f8cb8333c917ec5b243dae8e2379cc1c17025318 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 8 Aug 2022 02:16:54 +0100 Subject: [PATCH 045/255] #855 added ability to ignore device's heart rate signal. Fixed saving of steering enablement. Reduced 2 functions to 1 template function. --- src/settings.qml | 19 ++++++++++++++++++- src/trixterxdreamv1bike.cpp | 12 ++++++++++-- src/trixterxdreamv1bike.h | 7 ++++++- src/trixterxdreamv1settings.cpp | 24 +++++++++++++++--------- src/trixterxdreamv1settings.h | 32 ++++++++++++++++++++++---------- 5 files changed, 71 insertions(+), 23 deletions(-) diff --git a/src/settings.qml b/src/settings.qml index 35f2b0d31..a4dddbddd 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -458,6 +458,7 @@ import Qt.labs.settings 1.0 // from the version ? property bool trixter_xdream_v1_bike: false + property bool trixter_xdream_v1_bike_heartrate_enabled: true property bool trixter_xdream_v1_bike_steering_enabled: true property int trixter_xdream_v1_bike_steering_center: 127 property int trixter_xdream_v1_bike_steering_deadzone_width: 20 @@ -1735,6 +1736,22 @@ import Qt.labs.settings 1.0 Layout.fillWidth: true onClicked: settings.trixter_xdream_v1_bike = checked } + SwitchDelegate { + id: trixterXDreamV1HeartRate + text: qsTr("Heart Rate Signal Enabled") + ToolTip.visible: hovered + ToolTip.text: qsTr("Use this to enable or disable the heart rate signal.") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.trixter_xdream_v1_bike_heartrate_enabled + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.trixter_xdream_v1_bike_heartrate_enabled = checked + } SwitchDelegate { id: trixterXDreamV1Steering text: qsTr("Steering Enabled") @@ -1749,7 +1766,7 @@ import Qt.labs.settings 1.0 checked: settings.trixter_xdream_v1_bike_steering_enabled Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.settings.trixter_xdream_v1_bike_steering_enabled = checked + onClicked: settings.trixter_xdream_v1_bike_steering_enabled = checked } RowLayout { spacing: 10 diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index de551cd34..71844ab5d 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -148,8 +148,6 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // update the metrics this->LastCrankEventTime = state.LastEventTime; - if(!this->noHeartService) - this->Heart.setValue(state.HeartRate); // set the speed in km/h constexpr double minutesPerHour = 60.0; @@ -166,14 +164,24 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // check if the settings have been updated and adjust accordingly if(this->appSettings->get_version()!=this->lastAppSettingsVersion) { + + this->noHeartRate = this->noHeartService || !this->appSettings->get_heartRateEnabled(); + if(this->noHeartRate) + this->Heart.setValue(0.0); + this->noSteering = !this->appSettings->get_steeringEnabled(); if(this->noSteering) this->m_steeringAngle.setValue(0.0); else this->calculateSteeringMap(); + this->lastAppSettingsVersion = this->appSettings->get_version(); } + // update the heart rate + if(!this->noHeartRate) + this->Heart.setValue(state.HeartRate); + // Set the steering if(!this->noSteering) { this->m_steeringAngle.setValue(this->steeringMap[state.Steering]); diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 9de88103e..7bd833331 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -37,10 +37,15 @@ class trixterxdreamv1bike : public bike int settingsUpdateTimerId = 0; /** - * @brief noHeartService Suppress heart rate readings. + * @brief noHeartService Suppress heart rate readings, QZ level setting. */ bool noHeartService; + /** + * @brief noHeartRate Value from app settings combined with QZ's noHeartService value. + */ + bool noHeartRate; + /** * @brief noVirtualDevice Suppress virtual device. */ diff --git a/src/trixterxdreamv1settings.cpp b/src/trixterxdreamv1settings.cpp index 74919db14..dba90964a 100644 --- a/src/trixterxdreamv1settings.cpp +++ b/src/trixterxdreamv1settings.cpp @@ -1,22 +1,16 @@ #include "trixterxdreamv1settings.h" const QString trixterxdreamv1settings::keys::Enabled = QStringLiteral("trixter_xdream_v1_bike"); +const QString trixterxdreamv1settings::keys::HeartRateEnabled = QStringLiteral("trixter_xdream_v1_bike_heartrate_enabled"); const QString trixterxdreamv1settings::keys::SteeringEnabled = QStringLiteral("trixter_xdream_v1_bike_steering_enabled"); const QString trixterxdreamv1settings::keys::SteeringCenter = QStringLiteral("trixter_xdream_v1_bike_steering_center"); const QString trixterxdreamv1settings::keys::SteeringDeadZoneWidth =QStringLiteral("trixter_xdream_v1_bike_steering_deadzone_width"); const QString trixterxdreamv1settings::keys::SteeringSensitivityLeft = QStringLiteral("trixter_xdream_v1_bike_steering_sensitivity_left"); const QString trixterxdreamv1settings::keys::SteeringSensitivityRight= QStringLiteral("trixter_xdream_v1_bike_steering_sensitivity_right"); -uint8_t trixterxdreamv1settings::updateField(uint8_t &member, const uint8_t newValue){ - QMutexLocker locker(&this->mutex); - if(member!=newValue) { - member = newValue; - this->version++; - } - return newValue; -} -bool trixterxdreamv1settings::updateField(bool &member, const bool newValue){ +template +T trixterxdreamv1settings::updateField(T& member, const T newValue) { QMutexLocker locker(&this->mutex); if(member!=newValue) { member = newValue; @@ -25,6 +19,7 @@ bool trixterxdreamv1settings::updateField(bool &member, const bool newValue){ return newValue; } + uint32_t trixterxdreamv1settings::get_version() { QMutexLocker locker(&this->mutex); return this->version; @@ -39,6 +34,15 @@ bool trixterxdreamv1settings::set_enabled(bool value) { return this->updateField(this->enabled, value); } +bool trixterxdreamv1settings::get_heartRateEnabled(){ + QMutexLocker locker(&this->mutex); + return this->heartRateEnabled; +} + +bool trixterxdreamv1settings::set_heartRateEnabled(bool value) { + return this->updateField(this->heartRateEnabled, value); +} + bool trixterxdreamv1settings::get_steeringEnabled() { QMutexLocker locker(&this->mutex); return this->steeringEnabled; @@ -107,6 +111,7 @@ void trixterxdreamv1settings::Load() { void trixterxdreamv1settings::Load(const QSettings &settings) { QMutexLocker locker(&this->mutex); this->set_enabled(settings.value(keys::Enabled, DefaultEnabled).toBool()); + this->set_heartRateEnabled(settings.value(keys::HeartRateEnabled, DefaultHeartRateEnabled).toBool()); this->set_steeringEnabled(settings.value(keys::SteeringEnabled, DefaultSteeringEnabled).toBool()); this->set_steeringCenter(settings.value(keys::SteeringCenter, DefaultSteeringCenter).toUInt()); this->set_steeringDeadZoneWidth(settings.value(keys::SteeringDeadZoneWidth, DefaultSteeringDeadZoneWidth).toUInt()); @@ -123,6 +128,7 @@ void trixterxdreamv1bikesettings::Save() { void trixterxdreamv1bikesettings::Save(const QSettings &settings) { QMutexLocker locker(&this->mutex); settings.value(keys::Enabled).setValue(this->enabled); + settings.value(keys::HeartRateEnabled).setValue(this->heartRateEnabled); settings.value(keys::SteeringEnabled).setValue(this->steeringEnabled); settings.value(keys::SteeringCenter).setValue(this->steeringCenter); settings.value(keys::SteeringDeadZoneWidth).setValue(this->steeringDeadZoneWidth); diff --git a/src/trixterxdreamv1settings.h b/src/trixterxdreamv1settings.h index cbe47a37b..1832b6ffb 100644 --- a/src/trixterxdreamv1settings.h +++ b/src/trixterxdreamv1settings.h @@ -14,8 +14,12 @@ */ class trixterxdreamv1settings { public: + // these should match the corresponding values in settings.qml + // - the default values where the properties are defined + // - the validations on the text boxes constexpr static bool DefaultEnabled =true; constexpr static bool DefaultSteeringEnabled =true; + constexpr static bool DefaultHeartRateEnabled =true; constexpr static uint8_t DefaultSteeringCenter = trixterxdreamv1client::MaxSteering/2; constexpr static uint8_t DefaultSteeringDeadZoneWidth = 20; constexpr static uint8_t DefaultSteeringSensitivity = 100; @@ -35,6 +39,7 @@ class trixterxdreamv1settings { * @brief Enabled QSettings key to specify if the Trixter X-Dream V1 Bike is enabled in the application. */ const static QString Enabled; + const static QString HeartRateEnabled; const static QString SteeringEnabled; const static QString SteeringCenter; const static QString SteeringDeadZoneWidth; @@ -47,6 +52,7 @@ class trixterxdreamv1settings { QRecursiveMutex mutex; bool enabled=DefaultEnabled; bool steeringEnabled = DefaultSteeringEnabled; + bool heartRateEnabled = DefaultHeartRateEnabled; uint8_t steeringCenter = DefaultSteeringCenter; uint8_t steeringDeadZoneWidth = DefaultSteeringDeadZoneWidth; uint8_t steeringSensitivityLeft = DefaultSteeringSensitivity; @@ -59,7 +65,8 @@ class trixterxdreamv1settings { * @param maximum The maximum value. * @param value The value to clip. */ - static uint8_t clip(uint8_t minimum, uint8_t maximum, uint8_t value) { return std::max(minimum, std::min(maximum, value)); } + template + static T clip(const T minimum, const T maximum, const T value) { return std::max(minimum, std::min(maximum, value)); } /** * @brief updateField Updates a field and increments the version if the value has changed. @@ -67,15 +74,8 @@ class trixterxdreamv1settings { * @param newValue The new value. * @return The value set. */ - uint8_t updateField(uint8_t& member, const uint8_t newValue); - - /** - * @brief updateField Updates a field and increments the version if the value has changed. - * @param member The member to update. - * @param newValue The new value. - * @return The value set. - */ - bool updateField(bool& member, const bool newValue); + template + T updateField(T& member, const T newValue); public: /** @@ -95,6 +95,18 @@ class trixterxdreamv1settings { */ bool set_enabled(bool value); + /** + * @brief get_heartRateEnabled Indicates if the the heart rate signal is enabled. + */ + bool get_heartRateEnabled(); + + /** + * @brief set_heartRateEnabled Enables/disables steering. + * @param value True to use heart rate data, false to ignore it. + * @return The actual value set; + */ + bool set_heartRateEnabled(bool value); + /** * @brief get_steeringEnabled Indicates if the steering is enabled. */ From 8bcba5e73773b2a7c70382df2c1581274b8efce6 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 8 Aug 2022 21:26:31 +0100 Subject: [PATCH 046/255] #855 minor adjustments --- src/trixterxdreamv1bike.cpp | 1 + src/trixterxdreamv1bike.h | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 71844ab5d..74b3cf369 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -301,6 +301,7 @@ trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, boo << "," << "vender identifier:" << port.vendorIdentifier() << "," << "manufacturer:" << port.manufacturer() << "," << "product identifier:" << port.productIdentifier() + << "," << "system location:" << port.systemLocation() << "," << "isBusy:" << port.isBusy() << "," << "isNull:" << port.isNull() << "," << "serialNumber:" << port.serialNumber(); diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 7bd833331..797814475 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -1,6 +1,5 @@ #pragma once #include "bike.h" -#include "qsettings.h" #include "trixterxdreamv1client.h" #include "trixterxdreamv1serial.h" #include "trixterxdreamv1settings.h" @@ -90,7 +89,7 @@ class trixterxdreamv1bike : public bike /** * @brief appSettings The application settings. */ - trixterxdreamv1settings * appSettings; + trixterxdreamv1settings * appSettings = nullptr; /** * @brief lastAppSettingsVersion The last app settings version that was used to configure the object. From 2894b4116e60c7badcf14933ab7c0ee598214249 Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 10 Aug 2022 23:59:11 +0100 Subject: [PATCH 047/255] #855 less waiting, more flag settings. Timings in debug log. --- src/trixterxdreamv1bike.cpp | 39 ++++++++++++++++++++++------------ src/trixterxdreamv1serial.cpp | 40 +++++++++++++++++++++++++++++------ src/trixterxdreamv1serial.h | 5 ++++- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 74b3cf369..589c681ab 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -33,7 +33,7 @@ bool trixterxdreamv1bike::connect(QString portName) { // Get the current time in milliseconds since ancient times. // This will be subtracted from further readings from getTime() to get an easier to look at number. - this->t0 = this->getTime(); + this->t0 = getTime(); auto thisObject = this; @@ -51,11 +51,31 @@ bool trixterxdreamv1bike::connect(QString portName) { if(!noWriteResistance) this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(QByteArray((const char *)bytes, length), "");}); + // Set up a stopwatch to time the connection operations + QElapsedTimer stopWatch; + stopWatch.start(); + // open the port. This should be at 115200 bits per second. - this->port->open(portName, QSerialPort::Baud115200, 1000); + if(!this->port->open(portName, QSerialPort::Baud115200, 1000)) { + qDebug() << "Failed to open port, determined after " << stopWatch.elapsed() << "milliseconds"; + return false; + } - // wait for some packets to arrive - QThread::msleep(500); + // wait for up to 500ms for some packets to arrive + for(uint32_t start = getTime(), t=start, limit=start+500; tconnected()) { + qDebug() << "Connected after " << stopWatch.elapsed() << "milliseconds"; + break; + } + QThread::msleep(20); + } + + if(!this->connected()) + { + qDebug() << "Failed to connect to device, after " << stopWatch.elapsed() << "milliseconds"; + this->disconnectPort(); + return false; + } if(!this->noWriteResistance) { @@ -73,14 +93,7 @@ bool trixterxdreamv1bike::connect(QString portName) { qDebug() << "Failed to start settings update timer. Too bad."; } - if(!this->connected()) - { - qDebug() << "Failed to connect to device"; - this->disconnectPort(); - return false; - } - - return this->connected(); + return true; } void trixterxdreamv1bike::disconnectPort() { @@ -95,7 +108,7 @@ void trixterxdreamv1bike::disconnectPort() { this->resistanceTimerId = 0; } if(this->settingsUpdateTimerId) { - qDebug() << "Kiling settings update timer"; + qDebug() << "Killing settings update timer"; this->killTimer(this->settingsUpdateTimerId); this->settingsUpdateTimerId = 0; } diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index d0aa16622..63ca30965 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -4,6 +4,7 @@ #include #include + trixterxdreamv1serial::trixterxdreamv1serial(QObject *parent) : QThread(parent){} trixterxdreamv1serial::~trixterxdreamv1serial() { @@ -15,20 +16,36 @@ QList trixterxdreamv1serial::availablePorts() { return QSerialPortInfo::availablePorts(); } -void trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate baudRate, int waitTimeout) { +bool trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate baudRate, int waitTimeout) { + + QMutexLocker locker(&this->mutex); + if(this->isRunning()) { qDebug() << "Port is already being monitored."; this->error("Port is already being monitored."); - return; + return false; } - const QMutexLocker locker(&this->mutex); this->portName = portName; this->baudRate = baudRate; this->waitTimeout = waitTimeout; - if (!isRunning()) - start(); + + + + if (!isRunning()) { + this->openAttemptsPending=1; + start(); + } + + locker.unlock(); + + while(this->openAttemptsPending==1){ + QThread::msleep(10); + } + + locker.relock(); + return serial.isOpen(); } void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { @@ -54,11 +71,22 @@ void trixterxdreamv1serial::run() { this->serial.setFlowControl(QSerialPort::NoFlowControl); this->serial.setParity(QSerialPort::NoParity); - if (!serial.open(QIODevice::ReadWrite)) { + bool openResult = false; + + try { + openResult = serial.open(QIODevice::ReadWrite); + this->openAttemptsPending = 0; + } catch(...) { + this->openAttemptsPending = 0; + throw; + } + + if (!openResult) { qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error()); this->error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error())); return; } + qDebug() << "Serial port" << this->portName << "opened"; while (!this->quitPending) { diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index 74c6d6271..5c13ea4cf 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -5,6 +5,7 @@ #include #include #include +#include /** * @brief A basic serial port monitoring thread. @@ -22,8 +23,9 @@ class trixterxdreamv1serial : public QThread { * @param portName The name of the serial port. * @param baudRate The baud rate. * @param waitTimeout The timeout for the serial port. + * @returns True if the port was opened, false if the port wasn't opened, or was already open. */ - void open(const QString &portName, QSerialPort::BaudRate baudRate, int waitTimeout); + bool open(const QString &portName, QSerialPort::BaudRate baudRate, int waitTimeout); /** * @brief Writes the array of bytes to the serial port @@ -65,6 +67,7 @@ class trixterxdreamv1serial : public QThread { QSerialPort::BaudRate baudRate; int waitTimeout = 1000; QMutex mutex; + QAtomicInt openAttemptsPending{0}; bool quitPending = false; std::function receiveBytes=nullptr; }; From 3ad8e865ab295aac18f9f04ef6075c9410d1182f Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 11 Aug 2022 02:06:29 +0100 Subject: [PATCH 048/255] #855 changed steering options to use percentages rather than raw data values --- src/settings.qml | 37 +++++++++++++-------------- src/trixterxdreamv1bike.cpp | 9 ++++--- src/trixterxdreamv1settings.cpp | 26 +++++++++---------- src/trixterxdreamv1settings.h | 45 +++++++++++++++++---------------- 4 files changed, 60 insertions(+), 57 deletions(-) diff --git a/src/settings.qml b/src/settings.qml index f5d1907b4..b3693659c 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -464,8 +464,8 @@ import Qt.labs.settings 1.0 property bool trixter_xdream_v1_bike: false property bool trixter_xdream_v1_bike_heartrate_enabled: true property bool trixter_xdream_v1_bike_steering_enabled: true - property int trixter_xdream_v1_bike_steering_center: 127 - property int trixter_xdream_v1_bike_steering_deadzone_width: 20 + property int trixter_xdream_v1_bike_steering_center_offset: 0 + property int trixter_xdream_v1_bike_steering_deadzone_width: 5 property int trixter_xdream_v1_bike_steering_sensitivity_left: 100 property int trixter_xdream_v1_bike_steering_sensitivity_right: 100 } @@ -1727,6 +1727,7 @@ import Qt.labs.settings 1.0 SwitchDelegate { id: trixterXDreamV1 text: qsTr("Trixter X-Dream V1 Bike Enabled") + hoverEnabled: true ToolTip.visible: hovered ToolTip.text: qsTr("Use this to enable or disable detection of the Trixter X-Dream V1 Bike.") spacing: 0 @@ -1743,6 +1744,7 @@ import Qt.labs.settings 1.0 SwitchDelegate { id: trixterXDreamV1HeartRate text: qsTr("Heart Rate Signal Enabled") + hoverEnabled: true ToolTip.visible: hovered ToolTip.text: qsTr("Use this to enable or disable the heart rate signal.") spacing: 0 @@ -1759,6 +1761,7 @@ import Qt.labs.settings 1.0 SwitchDelegate { id: trixterXDreamV1Steering text: qsTr("Steering Enabled") + hoverEnabled: true ToolTip.visible: hovered ToolTip.text: qsTr("Use this to enable or disable steering.") spacing: 0 @@ -1775,37 +1778,37 @@ import Qt.labs.settings 1.0 RowLayout { spacing: 10 Label { - id: labelTrixterXDreamV1BikeSteeringCenter - text: qsTr("Steering Center") + id: labelTrixterXDreamV1BikeSteeringCenterOffset + text: qsTr("Steering Center Offset (%)") Layout.fillWidth: true } TextField { - id: trixterXDreamV1BikeSteeringCenterTextField - text: settings.trixter_xdream_v1_bike_steering_center + id: trixterXDreamV1BikeSteeringCenterOffsetTextField + text: settings.trixter_xdream_v1_bike_steering_center_offset hoverEnabled: true ToolTip.visible: hovered - ToolTip.text: qsTr("Use this setting to adjust the steering angle for the resting position of the handle bars. Default=127. Full range of steering is 0 (left) to 255 (right).") + ToolTip.text: qsTr("Use this setting to adjust the steering angle offset percentage for the resting position of the handle bars. Use +/- % values to adjust left and right.") horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter inputMethodHints: Qt.ImhDigitsOnly - // this should be in sync with trixterxdreamv1bikesettings::MinSteeringCenter and MaxSteeringCenter - validator: IntValidator {bottom: 67; top: 187;} - onAccepted: settings.trixter_xdream_v1_bike_steering_center = text + // this should be in sync with trixterxdreamv1bikesettings::MinSteeringCenterOffsetPercentage and MaxSteeringCenterOffsetPercentage + validator: IntValidator {bottom: -30; top: 30;} + onAccepted: settings.trixter_xdream_v1_bike_steering_center_offset = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { id: oktrixterXDreamV1BikeSteeringCenterButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trixter_xdream_v1_bike_steering_center = trixterXDreamV1BikeSteeringCenterTextField.text + onClicked: settings.trixter_xdream_v1_bike_steering_center_offset = trixterXDreamV1BikeSteeringCenterOffsetTextField.text } } RowLayout { spacing: 10 Label { id: labelTrixterXDreamV1BikeSteeringDeadZoneWidth - text: qsTr("Steering Dead Zone Width") + text: qsTr("Steering Dead Zone Width (%)") Layout.fillWidth: true } TextField { @@ -1813,13 +1816,13 @@ import Qt.labs.settings 1.0 text: settings.trixter_xdream_v1_bike_steering_deadzone_width hoverEnabled: true ToolTip.visible: hovered - ToolTip.text: qsTr("The width from left to right of the region where the steering value will be mapped to 0 degrees. Full range of steering is 0 (left) to 255 (right).") + ToolTip.text: qsTr("The percentage of the total range where the steering value will be mapped to 0 degrees.") horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter inputMethodHints: Qt.ImhDigitsOnly - // this should be in sync with trixterxdreamv1bikesettings::MinSteeringDeadZoneWidth and MaxSteeringDeadZoneWidth - validator: IntValidator {bottom: 0; top: 50;} + // this should be in sync with trixterxdreamv1bikesettings::MinSteeringDeadZonePercentage and MaxSteeringDeadZonePercentage + validator: IntValidator {bottom: 0; top: 20;} onAccepted: settings.trixter_xdream_v1_bike_steering_deadzone_width = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } @@ -4749,10 +4752,6 @@ import Qt.labs.settings 1.0 Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true onClicked: settings.kingsmith_encrypt_v3 = checked - checked: settings.kingsmith_encrypt_v3 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.kingsmith_encrypt_v3 = checked } } } diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 589c681ab..cf9cddba8 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -207,12 +207,15 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { void trixterxdreamv1bike::calculateSteeringMap() { constexpr double maxSteeringAngle = 45.0; + constexpr int maxSteering = trixterxdreamv1client::MaxSteering; this->steeringMap.clear(); - int halfDeadZone = this->appSettings->get_steeringDeadZoneWidth()/2; - int deadZoneLeft = this->appSettings->get_steeringCenter()-halfDeadZone; - int deadZoneRight = this->appSettings->get_steeringCenter()+halfDeadZone; + int steeringCenterOffset = round(0.5+this->appSettings->get_steeringCenterOffsetPercentage()*maxSteering*0.01); + int steeringCenter = maxSteering / 2 + steeringCenterOffset; + int halfDeadZone = this->appSettings->get_steeringDeadZoneWidthPercentage() * maxSteering * 0.005; + int deadZoneLeft = steeringCenter-halfDeadZone; + int deadZoneRight = steeringCenter+halfDeadZone; double sensitivityLeft = 0.01 * this->appSettings->get_steeringSensitivityLeft(); double sensitivityRight = 0.01 * this->appSettings->get_steeringSensitivityRight(); double scaleLeft = sensitivityLeft * maxSteeringAngle / deadZoneLeft; diff --git a/src/trixterxdreamv1settings.cpp b/src/trixterxdreamv1settings.cpp index dba90964a..2712171a5 100644 --- a/src/trixterxdreamv1settings.cpp +++ b/src/trixterxdreamv1settings.cpp @@ -3,7 +3,7 @@ const QString trixterxdreamv1settings::keys::Enabled = QStringLiteral("trixter_xdream_v1_bike"); const QString trixterxdreamv1settings::keys::HeartRateEnabled = QStringLiteral("trixter_xdream_v1_bike_heartrate_enabled"); const QString trixterxdreamv1settings::keys::SteeringEnabled = QStringLiteral("trixter_xdream_v1_bike_steering_enabled"); -const QString trixterxdreamv1settings::keys::SteeringCenter = QStringLiteral("trixter_xdream_v1_bike_steering_center"); +const QString trixterxdreamv1settings::keys::SteeringCenterOffset = QStringLiteral("trixter_xdream_v1_bike_steering_center_offset"); const QString trixterxdreamv1settings::keys::SteeringDeadZoneWidth =QStringLiteral("trixter_xdream_v1_bike_steering_deadzone_width"); const QString trixterxdreamv1settings::keys::SteeringSensitivityLeft = QStringLiteral("trixter_xdream_v1_bike_steering_sensitivity_left"); const QString trixterxdreamv1settings::keys::SteeringSensitivityRight= QStringLiteral("trixter_xdream_v1_bike_steering_sensitivity_right"); @@ -52,24 +52,24 @@ bool trixterxdreamv1settings::set_steeringEnabled(bool value) { return this->updateField(this->steeringEnabled, value); } -uint8_t trixterxdreamv1settings::get_steeringCenter() { +int8_t trixterxdreamv1settings::get_steeringCenterOffsetPercentage() { QMutexLocker locker(&this->mutex); - return this->steeringCenter; + return this->steeringCenterOffsetPercentage; } -uint8_t trixterxdreamv1settings::set_steeringCenter(uint8_t value) { - auto newValue = clip(MinSteeringCenter, MaxSteeringCenter, value); - return this->updateField(this->steeringCenter, newValue); +int8_t trixterxdreamv1settings::set_steeringCenterOffsetPercentage(int8_t value) { + auto newValue = clip((int8_t)-MaxSteeringCenterOffsetPercentage, MaxSteeringCenterOffsetPercentage, value); + return this->updateField(this->steeringCenterOffsetPercentage, newValue); } -uint8_t trixterxdreamv1settings::get_steeringDeadZoneWidth() { +uint8_t trixterxdreamv1settings::get_steeringDeadZoneWidthPercentage() { QMutexLocker locker(&this->mutex); - return this->steeringDeadZoneWidth; + return this->steeringDeadZoneWidthPercentage; } -uint8_t trixterxdreamv1settings::set_steeringDeadZoneWidth(uint8_t value) { - auto newValue = clip(MinSteeringDeadZoneWidth, MaxSteeringDeadZoneWidth, value); - return this->updateField(this->steeringDeadZoneWidth, newValue); +uint8_t trixterxdreamv1settings::set_steeringDeadZoneWidthPercentage(uint8_t value) { + auto newValue = clip(MinSteeringDeadZoneWidthPercentage, MaxSteeringDeadZoneWidthPercentage, value); + return this->updateField(this->steeringDeadZoneWidthPercentage, newValue); } uint8_t trixterxdreamv1settings::get_steeringSensitivityLeft() { @@ -113,8 +113,8 @@ void trixterxdreamv1settings::Load(const QSettings &settings) { this->set_enabled(settings.value(keys::Enabled, DefaultEnabled).toBool()); this->set_heartRateEnabled(settings.value(keys::HeartRateEnabled, DefaultHeartRateEnabled).toBool()); this->set_steeringEnabled(settings.value(keys::SteeringEnabled, DefaultSteeringEnabled).toBool()); - this->set_steeringCenter(settings.value(keys::SteeringCenter, DefaultSteeringCenter).toUInt()); - this->set_steeringDeadZoneWidth(settings.value(keys::SteeringDeadZoneWidth, DefaultSteeringDeadZoneWidth).toUInt()); + this->set_steeringCenterOffsetPercentage(settings.value(keys::SteeringCenterOffset, DefaultSteeringCenterOffsetPercentage).toUInt()); + this->set_steeringDeadZoneWidthPercentage(settings.value(keys::SteeringDeadZoneWidth, DefaultSteeringDeadZoneWidthPercentage).toUInt()); this->set_steeringSensitivityLeft(settings.value(keys::SteeringSensitivityLeft, DefaultSteeringSensitivity).toUInt()); this->set_steeringSensitivityRight(settings.value(keys::SteeringSensitivityRight, DefaultSteeringSensitivity).toUInt()); } diff --git a/src/trixterxdreamv1settings.h b/src/trixterxdreamv1settings.h index 1832b6ffb..c16476a96 100644 --- a/src/trixterxdreamv1settings.h +++ b/src/trixterxdreamv1settings.h @@ -20,13 +20,13 @@ class trixterxdreamv1settings { constexpr static bool DefaultEnabled =true; constexpr static bool DefaultSteeringEnabled =true; constexpr static bool DefaultHeartRateEnabled =true; - constexpr static uint8_t DefaultSteeringCenter = trixterxdreamv1client::MaxSteering/2; - constexpr static uint8_t DefaultSteeringDeadZoneWidth = 20; + constexpr static int8_t DefaultSteeringCenterOffsetPercentage = 0; + constexpr static uint8_t DefaultSteeringDeadZoneWidthPercentage = 5; constexpr static uint8_t DefaultSteeringSensitivity = 100; - constexpr static uint8_t MinSteeringCenter = DefaultSteeringCenter-60; - constexpr static uint8_t MaxSteeringCenter = DefaultSteeringCenter+60; - constexpr static uint8_t MaxSteeringDeadZoneWidth = 50; - constexpr static uint8_t MinSteeringDeadZoneWidth = 0; + constexpr static int8_t MinSteeringCenterOffsetPercentage = 0; + constexpr static int8_t MaxSteeringCenterOffsetPercentage = 30; + constexpr static uint8_t MaxSteeringDeadZoneWidthPercentage = 50; + constexpr static uint8_t MinSteeringDeadZoneWidthPercentage = 0; constexpr static uint8_t MinSteeringSensitivityPercentage = 20; constexpr static uint8_t MaxSteeringSensitivityPercentage = 200; @@ -41,7 +41,7 @@ class trixterxdreamv1settings { const static QString Enabled; const static QString HeartRateEnabled; const static QString SteeringEnabled; - const static QString SteeringCenter; + const static QString SteeringCenterOffset; const static QString SteeringDeadZoneWidth; const static QString SteeringSensitivityLeft; const static QString SteeringSensitivityRight; @@ -53,8 +53,8 @@ class trixterxdreamv1settings { bool enabled=DefaultEnabled; bool steeringEnabled = DefaultSteeringEnabled; bool heartRateEnabled = DefaultHeartRateEnabled; - uint8_t steeringCenter = DefaultSteeringCenter; - uint8_t steeringDeadZoneWidth = DefaultSteeringDeadZoneWidth; + int8_t steeringCenterOffsetPercentage = DefaultSteeringCenterOffsetPercentage; + uint8_t steeringDeadZoneWidthPercentage = DefaultSteeringDeadZoneWidthPercentage; uint8_t steeringSensitivityLeft = DefaultSteeringSensitivity; uint8_t steeringSensitivityRight = DefaultSteeringSensitivity; uint32_t version=0; @@ -121,31 +121,32 @@ class trixterxdreamv1settings { /** * @brief get_steeringCenter Gets the value considered to be the center position for the steering. - * Defaults to half of trixterxdreamv1client::MaxSteering, but in reality is somewhat different - * due to physical calibration. + * Defaults to 0%, but in reality is somewhat different due to physical calibration. */ - uint8_t get_steeringCenter(); + int8_t get_steeringCenterOffsetPercentage(); /** - * @brief set_steeringCenter Sets the steering center value. Used to accomodate the bike's calibration. - * @param value The value, will be clipped to [MinSteeringCenter, MaxSteeringCenter]. + * @brief set_steeringCenterOffsetPercentage Sets the steering center offset percentage. Used to accommodate + * the bike's calibration. + * @param value The value, will be clipped to [-MaxSteeringCenterOffsetPercentage, MaxSteeringCenterOffsetPercentage]. * @return The actual value set. */ - uint8_t set_steeringCenter(uint8_t value); + int8_t set_steeringCenterOffsetPercentage(int8_t value); /** - * @brief get_steeringDeadZoneWidth Gets the width of the dead zone. This is the region - * from the left to the right of steeringCenter for which the steering value will be mapped to 0 degrees. + * @brief get_steeringDeadZoneWidthPercentage Gets the width of the dead zone as a percentage of the total range. + * This is the region from the left to the right of steering center for which the steering value will be mapped to 0 degrees. */ - uint8_t get_steeringDeadZoneWidth(); + uint8_t get_steeringDeadZoneWidthPercentage(); /** - * @brief set_steeringDeadZoneWidth Sets the width, left to right, of the "dead zone" surrounding the - * steeringCenter value, for which the steering value will be mapped to 0 degrees. - * @param value The width, left to right, of the dead zone. Clipped to [MinSteeringDeadZoneWidth, MaxSteeringDeadZoneWidth]. + * @brief set_steeringDeadZoneWidthPercentage Sets the width, left to right, as a percentage of the total range, + * of the "dead zone" surrounding the steering center, for which the steering value will be mapped to 0 degrees. + * @param value The width, left to right, of the dead zone, as a percentage of the total range. + * Clipped to [MinSteeringDeadZoneWidthPercentage, MaxSteeringDeadZoneWidthPercentage]. * @return */ - uint8_t set_steeringDeadZoneWidth(uint8_t value); + uint8_t set_steeringDeadZoneWidthPercentage(uint8_t value); /** * @brief get_steeringSensitivityLeft Gets the sensitivity, as a percentage for how sensitive the From 1cde0afc3bf771f78aa01ef305fce7bb22b82042 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 12 Aug 2022 22:04:47 +0100 Subject: [PATCH 049/255] #855 - adjusted steering calibration to use angle boundaries obtained from steering angle tile. - changed settings UI to use SpinBoxes instead of text fields - added virtual bike field, but in the wrong place. --- src/settings.qml | 11357 +++++++++++++++--------------- src/trixterxdreamv1bike.cpp | 91 +- src/trixterxdreamv1bike.h | 17 + src/trixterxdreamv1settings.cpp | 65 +- src/trixterxdreamv1settings.h | 154 +- 5 files changed, 5850 insertions(+), 5834 deletions(-) diff --git a/src/settings.qml b/src/settings.qml index b3693659c..478fdec5f 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -5,1541 +5,1543 @@ import QtQuick.Controls.Material 2.0 import Qt.labs.settings 1.0 //Page { - ScrollView { - contentWidth: -1 - focus: true - anchors.horizontalCenter: parent.horizontalCenter - anchors.fill: parent - //anchors.bottom: footerSettings.top - //anchors.bottomMargin: footerSettings.height + 10 - id: settingsPane - - Settings { - id: settings - property real ui_zoom: 100.0 - property bool bike_heartrate_service: false - property int bike_resistance_offset: 4 - property real bike_resistance_gain_f: 1.0 - property bool zwift_erg: false - property real zwift_erg_filter: 10.0 - property real zwift_erg_filter_down: 10.0 - property bool zwift_negative_inclination_x2: false - property real zwift_inclination_offset: 0 - property real zwift_inclination_gain: 1.0 - property real echelon_resistance_offset: 0 - property real echelon_resistance_gain: 1.0 - - property bool speed_power_based: false - property int bike_resistance_start: 1 - property int age: 35.0 - property real weight: 75.0 - property real ftp: 200.0 - property string user_email: "" - property string user_nickname: "" - property bool miles_unit: false - property bool pause_on_start: false - property bool treadmill_force_speed: false - property bool pause_on_start_treadmill: false - property bool continuous_moving: false - property bool bike_cadence_sensor: false - property bool run_cadence_sensor: false - property bool bike_power_sensor: false - property string heart_rate_belt_name: "Disabled" - property bool heart_ignore_builtin: false - property bool kcal_ignore_builtin: false - - property bool ant_cadence: false - property bool ant_heart: false - property bool ant_garmin: false - - property bool top_bar_enabled: true - - property string peloton_username: "username" - property string peloton_password: "password" - property string peloton_difficulty: "lower" - property string peloton_cadence_metric: "Cadence" - property string peloton_heartrate_metric: "Heart Rate" - property string peloton_date: "Before Title" - property bool peloton_description_link: true - - property string pzp_username: "username" - property string pzp_password: "username" - - property bool tile_speed_enabled: true - property int tile_speed_order: 0 - property bool tile_inclination_enabled: true - property int tile_inclination_order: 1 - property bool tile_cadence_enabled: true - property int tile_cadence_order: 2 - property bool tile_elevation_enabled: true - property int tile_elevation_order: 3 - property bool tile_calories_enabled: true - property int tile_calories_order: 4 - property bool tile_odometer_enabled: true - property int tile_odometer_order: 5 - property bool tile_pace_enabled: true - property int tile_pace_order: 6 - property bool tile_resistance_enabled: true - property int tile_resistance_order: 7 - property bool tile_watt_enabled: true - property int tile_watt_order: 8 - property bool tile_weight_loss_enabled: false - property int tile_weight_loss_order: 24 - property bool tile_avgwatt_enabled: true - property int tile_avgwatt_order: 9 - property bool tile_ftp_enabled: true - property int tile_ftp_order: 10 - property bool tile_heart_enabled: true - property int tile_heart_order: 11 - property bool tile_fan_enabled: true - property int tile_fan_order: 12 - property bool tile_jouls_enabled: true - property int tile_jouls_order: 13 - property bool tile_elapsed_enabled: true - property int tile_elapsed_order: 14 - property bool tile_lapelapsed_enabled: false - property int tile_lapelapsed_order: 17 - property bool tile_moving_time_enabled: false - property int tile_moving_time_order: 21 - property bool tile_peloton_offset_enabled: false - property int tile_peloton_offset_order: 22 - property bool tile_peloton_difficulty_enabled: false - property int tile_peloton_difficulty_order: 32 - property bool tile_peloton_resistance_enabled: true - property int tile_peloton_resistance_order: 15 - property bool tile_datetime_enabled: true - property int tile_datetime_order: 16 - property bool tile_target_resistance_enabled: true - property int tile_target_resistance_order: 15 - property bool tile_target_peloton_resistance_enabled: false - property int tile_target_peloton_resistance_order: 21 - property bool tile_target_cadence_enabled: false - property int tile_target_cadence_order: 19 - property bool tile_target_power_enabled: false - property int tile_target_power_order: 20 - property bool tile_target_zone_enabled: false - property int tile_target_zone_order: 24 - property bool tile_target_speed_enabled: false - property int tile_target_speed_order: 27 - property bool tile_target_incline_enabled: false - property int tile_target_incline_order: 28 - property bool tile_strokes_count_enabled: false - property int tile_strokes_count_order: 22 - property bool tile_strokes_length_enabled: false - property int tile_strokes_length_order: 23 - property bool tile_watt_kg_enabled: false - property int tile_watt_kg_order: 25 - property bool tile_gears_enabled: false - property int tile_gears_order: 26 - property bool tile_remainingtimetrainprogramrow_enabled: false - property int tile_remainingtimetrainprogramrow_order: 27 - property bool tile_nextrowstrainprogram_enabled: false - property int tile_nextrowstrainprogram_order: 31 - property bool tile_mets_enabled: false - property int tile_mets_order: 28 - property bool tile_targetmets_enabled: false - property int tile_targetmets_order: 29 - property bool tile_steering_angle_enabled: false - property int tile_steering_angle_order: 30 - property bool tile_pid_hr_enabled: false - property int tile_pid_hr_order: 31 - - property real heart_rate_zone1: 70.0 - property real heart_rate_zone2: 80.0 - property real heart_rate_zone3: 90.0 - property real heart_rate_zone4: 100.0 - property bool heart_max_override_enable: false - property real heart_max_override_value: 195.0 - - property real peloton_gain: 1.0 - property real peloton_offset: 0 - - property string treadmill_pid_heart_zone: "Disabled" - property real pacef_1mile: 250 - property real pacef_5km: 300 - property real pacef_10km: 320 - property real pacef_halfmarathon: 340 - property real pacef_marathon: 360 - property string pace_default: "Half Marathon" - - property bool domyos_treadmill_buttons: false - property bool domyos_treadmill_distance_display: true - property bool domyos_treadmill_display_invert: false - - property real domyos_bike_cadence_filter: 0.0 - property bool domyos_bike_display_calories: true - - property real domyos_elliptical_speed_ratio: 1.0 - - property bool eslinker_cadenza: true - - property string echelon_watttable: "Echelon" - - property real proform_wheel_ratio: 0.33 - property bool proform_tour_de_france_clc: false - property bool proform_tdf_jonseed_watt: false - property bool proform_studio: false - property bool proform_tdf_10: false - - property double horizon_gr7_cadence_multiplier: 1.0 - - property int fitshow_user_id: 0x13AA - - property bool inspire_peloton_formula: false - property bool inspire_peloton_formula2: false - - property bool hammer_racer_s: false - - property bool pafers_treadmill: false - - property bool yesoul_peloton_formula: false - - property bool nordictrack_10_treadmill: true - property bool nordictrack_t65s_treadmill: false - //property bool proform_treadmill_995i: false - - property bool toorx_3_0: false - property bool toorx_65s_evo: false - property bool jtx_fitness_sprint_treadmill: false - property bool dkn_endurun_treadmill: false - property bool trx_route_key: false - property bool bh_spada_2: false - property bool toorx_bike: false - property bool toorx_ftms: false - property bool jll_IC400_bike: false - property bool fytter_ri08_bike: false - property bool asviva_bike: false - property bool hertz_xr_770: false - - property int m3i_bike_id: 256 - property int m3i_bike_speed_buffsize: 90 - property bool m3i_bike_qt_search: false - property bool m3i_bike_kcal: true - - property bool snode_bike: false - property bool fitplus_bike: false - property bool virtufit_etappe: false - - property int flywheel_filter: 2 - property bool flywheel_life_fitness_ic8: false - - property bool sole_treadmill_inclination: false - property bool sole_treadmill_miles: true - property bool sole_treadmill_f65: false - property bool sole_treadmill_f63: false - property bool sole_treadmill_tt8: false - - property bool schwinn_bike_resistance: false - property bool schwinn_bike_resistance_v2: value - - property bool technogym_myrun_treadmill_experimental: false - - property bool trainprogram_random: false - property int trainprogram_total: 60 - property real trainprogram_period_seconds: 60 - property real trainprogram_speed_min: 8 - property real trainprogram_speed_max: 16 - property real trainprogram_incline_min: 0 - property real trainprogram_incline_max: 15 - property real trainprogram_resistance_min: 1 - property real trainprogram_resistance_max: 32 - - property real watt_offset: 0 - property real watt_gain: 1 - property bool power_avg_5s: false - property bool instant_power_on_pause: false - - property real speed_offset: 0 - property real speed_gain: 1 - - property string filter_device: "Disabled" - property string strava_suffix: "#QZ" - - property string cadence_sensor_name: "Disabled" - property bool cadence_sensor_as_bike: false - property real cadence_sensor_speed_ratio: 0.33 - property real power_hr_pwr1: 200 - property real power_hr_hr1: 150 - property real power_hr_pwr2: 230 - property real power_hr_hr2: 170 - - property string power_sensor_name: "Disabled" - property bool power_sensor_as_bike: false - property bool power_sensor_as_treadmill: false - property bool powr_sensor_running_cadence_double: false - - property string elite_rizer_name: "Disabled" - property string elite_sterzo_smart_name: "Disabled" - - property string ftms_accessory_name: "Disabled" - property real ss2k_shift_step: 900 - - property bool fitmetria_fanfit_enable: false - property string fitmetria_fanfit_mode: "Heart" - property real fitmetria_fanfit_min: 0 - property real fitmetria_fanfit_max: 100 - - property bool virtualbike_forceresistance: true - property bool bluetooth_relaxed: false - property bool bluetooth_30m_hangs: false - property bool battery_service: false - property bool service_changed: false - property bool virtual_device_enabled: true - property bool virtual_device_bluetooth: true - property bool ios_peloton_workaround: true - property bool android_wakelock: true - property bool log_debug: false - property bool virtual_device_onlyheart: false - property bool virtual_device_echelon: false - property bool virtual_device_ifit: false - property bool virtual_device_rower: false - property bool virtual_device_force_bike: false - property bool volume_change_gears: false - property bool applewatch_fakedevice: false - - // from version 2.10.15 - property real zwift_erg_resistance_down: 0.0 - property real zwift_erg_resistance_up: 999.0 - - // from version 2.10.16 - property bool horizon_paragon_x: false - - // from version 2.10.18 - property real treadmill_step_speed: 0.5 - property real treadmill_step_incline: 0.5 - - // from version 2.10.19 - property bool fitshow_anyrun: false - - // from version 2.10.21 - property bool nordictrack_s30_treadmill: false - - // from version 2.10.23 - // not used anymore because it's an elliptical not a treadmill. Don't remove this - // it will cause corruption in the settings - property bool nordictrack_fs5i_treadmill: false - - // from version 2.10.26 - property bool renpho_peloton_conversion_v2: false - - // from version 2.10.27 - property real ss2k_resistance_sample_1: 20 - property real ss2k_shift_step_sample_1: 0 - property real ss2k_resistance_sample_2: 30 - property real ss2k_shift_step_sample_2: 0 - property real ss2k_resistance_sample_3: 40 - property real ss2k_shift_step_sample_3: 0 - property real ss2k_resistance_sample_4: 50 - property real ss2k_shift_step_sample_4: 0 - - property bool fitshow_truetimer: false - - // from the version 2.10.28 - property real elite_rizer_gain: 1.0 - property bool tile_ext_incline_enabled: false - property int tile_ext_incline_order: 32 - - // from the version 2.10.41 - property bool reebok_fr30_treadmill: false - - // from the version 2.10.44 - property bool horizon_treadmill_7_8: false - - // from the version 2.10.45 - property string profile_name: "default" - - // from the version 2.10.46 - property bool tile_cadence_color_enabled: false - property bool tile_peloton_remaining_enabled: false - property int tile_peloton_remaining_order: 22 - property bool tile_peloton_resistance_color_enabled: false - - // from the version 2.10.49 - property bool dircon_yes: true - property int dircon_server_base_port: 36866 - - // from the version 2.10.56 - property bool ios_cache_heart_device: true - - // from the version 2.10.57 - property int app_opening: 0 - - // from the version 2.10.62 - property string proformtdf4ip: "" - - // from the version 2.10.72 - property bool fitfiu_mc_v460: false - property real bike_weight: 0 - - // from the version 2.10.77 - property bool kingsmith_encrypt_v2: false - - // from the version 2.10.81 - property bool proform_treadmill_9_0: false - - // from the version 2.10.85 - property bool proform_treadmill_1800i: false - - // from the version 2.10.91 - property real cadence_offset: 0 - property real cadence_gain: 1 - property bool sp_ht_9600ie: false - - // from the version 2.10.92 - property bool tts_enabled: false - property int tts_summary_sec: 120 - property bool tts_act_speed: false - property bool tts_avg_speed: true - property bool tts_max_speed: false - property bool tts_act_inclination: false - property bool tts_act_cadence: false - property bool tts_avg_cadence: true - property bool tts_max_cadence: false - property bool tts_act_elevation: true - property bool tts_act_calories: true - property bool tts_act_odometer: true - property bool tts_act_pace: false - property bool tts_avg_pace: true - property bool tts_max_pace: false - property bool tts_act_resistance: true - property bool tts_avg_resistance: true - property bool tts_max_resistance: false - property bool tts_act_watt: false - property bool tts_avg_watt: true - property bool tts_max_watt: true - property bool tts_act_ftp: false - property bool tts_avg_ftp: true - property bool tts_max_ftp: false - property bool tts_act_heart: true - property bool tts_avg_heart: true - property bool tts_max_heart: false - property bool tts_act_jouls: true - property bool tts_act_elapsed: true - property bool tts_act_peloton_resistance: false - property bool tts_avg_peloton_resistance: false - property bool tts_max_peloton_resistance: false - property bool tts_act_target_peloton_resistance: true - property bool tts_act_target_cadence: true - property bool tts_act_target_power: true - property bool tts_act_target_zone: true - property bool tts_act_target_speed: true - property bool tts_act_target_incline: true - property bool tts_act_watt_kg: false - property bool tts_avg_watt_kg: false - property bool tts_max_watt_kg: false - - // from the version 2.10.96 - property bool fakedevice_elliptical: false - - // from the version 2.10.99 - property string nordictrack_2950_ip: "" - - // from the version 2.10.102 - property bool tile_instantaneous_stride_length_enabled: false - property int tile_instantaneous_stride_length_order: 32 - property bool tile_ground_contact_enabled: false - property int tile_ground_contact_order: 33 - property bool tile_vertical_oscillation_enabled: false - property int tile_vertical_oscillation_order: 34 - property string sex: "Male" - - // from the version 2.10.111 - property string maps_type: "3D" - - // from the version 2.10.112 - property real ss2k_max_resistance: 100 - property real ss2k_min_resistance: 0 - - // from the version 2.11.10 - property bool proform_treadmill_se: false - - // from the version 2.11.14 - property string proformtreadmillip: "" - - // from the version 2.11.22 - property bool kingsmith_encrypt_v3: false - - - // from the version ? - property bool trixter_xdream_v1_bike: false - property bool trixter_xdream_v1_bike_heartrate_enabled: true - property bool trixter_xdream_v1_bike_steering_enabled: true - property int trixter_xdream_v1_bike_steering_center_offset: 0 - property int trixter_xdream_v1_bike_steering_deadzone_width: 5 - property int trixter_xdream_v1_bike_steering_sensitivity_left: 100 - property int trixter_xdream_v1_bike_steering_sensitivity_right: 100 - } +ScrollView { + contentWidth: -1 + focus: true + anchors.horizontalCenter: parent.horizontalCenter + anchors.fill: parent + //anchors.bottom: footerSettings.top + //anchors.bottomMargin: footerSettings.height + 10 + id: settingsPane + + Settings { + id: settings + property real ui_zoom: 100.0 + property bool bike_heartrate_service: false + property int bike_resistance_offset: 4 + property real bike_resistance_gain_f: 1.0 + property bool zwift_erg: false + property real zwift_erg_filter: 10.0 + property real zwift_erg_filter_down: 10.0 + property bool zwift_negative_inclination_x2: false + property real zwift_inclination_offset: 0 + property real zwift_inclination_gain: 1.0 + property real echelon_resistance_offset: 0 + property real echelon_resistance_gain: 1.0 + + property bool speed_power_based: false + property int bike_resistance_start: 1 + property int age: 35.0 + property real weight: 75.0 + property real ftp: 200.0 + property string user_email: "" + property string user_nickname: "" + property bool miles_unit: false + property bool pause_on_start: false + property bool treadmill_force_speed: false + property bool pause_on_start_treadmill: false + property bool continuous_moving: false + property bool bike_cadence_sensor: false + property bool run_cadence_sensor: false + property bool bike_power_sensor: false + property string heart_rate_belt_name: "Disabled" + property bool heart_ignore_builtin: false + property bool kcal_ignore_builtin: false + + property bool ant_cadence: false + property bool ant_heart: false + property bool ant_garmin: false + + property bool top_bar_enabled: true + + property string peloton_username: "username" + property string peloton_password: "password" + property string peloton_difficulty: "lower" + property string peloton_cadence_metric: "Cadence" + property string peloton_heartrate_metric: "Heart Rate" + property string peloton_date: "Before Title" + property bool peloton_description_link: true + + property string pzp_username: "username" + property string pzp_password: "username" + + property bool tile_speed_enabled: true + property int tile_speed_order: 0 + property bool tile_inclination_enabled: true + property int tile_inclination_order: 1 + property bool tile_cadence_enabled: true + property int tile_cadence_order: 2 + property bool tile_elevation_enabled: true + property int tile_elevation_order: 3 + property bool tile_calories_enabled: true + property int tile_calories_order: 4 + property bool tile_odometer_enabled: true + property int tile_odometer_order: 5 + property bool tile_pace_enabled: true + property int tile_pace_order: 6 + property bool tile_resistance_enabled: true + property int tile_resistance_order: 7 + property bool tile_watt_enabled: true + property int tile_watt_order: 8 + property bool tile_weight_loss_enabled: false + property int tile_weight_loss_order: 24 + property bool tile_avgwatt_enabled: true + property int tile_avgwatt_order: 9 + property bool tile_ftp_enabled: true + property int tile_ftp_order: 10 + property bool tile_heart_enabled: true + property int tile_heart_order: 11 + property bool tile_fan_enabled: true + property int tile_fan_order: 12 + property bool tile_jouls_enabled: true + property int tile_jouls_order: 13 + property bool tile_elapsed_enabled: true + property int tile_elapsed_order: 14 + property bool tile_lapelapsed_enabled: false + property int tile_lapelapsed_order: 17 + property bool tile_moving_time_enabled: false + property int tile_moving_time_order: 21 + property bool tile_peloton_offset_enabled: false + property int tile_peloton_offset_order: 22 + property bool tile_peloton_difficulty_enabled: false + property int tile_peloton_difficulty_order: 32 + property bool tile_peloton_resistance_enabled: true + property int tile_peloton_resistance_order: 15 + property bool tile_datetime_enabled: true + property int tile_datetime_order: 16 + property bool tile_target_resistance_enabled: true + property int tile_target_resistance_order: 15 + property bool tile_target_peloton_resistance_enabled: false + property int tile_target_peloton_resistance_order: 21 + property bool tile_target_cadence_enabled: false + property int tile_target_cadence_order: 19 + property bool tile_target_power_enabled: false + property int tile_target_power_order: 20 + property bool tile_target_zone_enabled: false + property int tile_target_zone_order: 24 + property bool tile_target_speed_enabled: false + property int tile_target_speed_order: 27 + property bool tile_target_incline_enabled: false + property int tile_target_incline_order: 28 + property bool tile_strokes_count_enabled: false + property int tile_strokes_count_order: 22 + property bool tile_strokes_length_enabled: false + property int tile_strokes_length_order: 23 + property bool tile_watt_kg_enabled: false + property int tile_watt_kg_order: 25 + property bool tile_gears_enabled: false + property int tile_gears_order: 26 + property bool tile_remainingtimetrainprogramrow_enabled: false + property int tile_remainingtimetrainprogramrow_order: 27 + property bool tile_nextrowstrainprogram_enabled: false + property int tile_nextrowstrainprogram_order: 31 + property bool tile_mets_enabled: false + property int tile_mets_order: 28 + property bool tile_targetmets_enabled: false + property int tile_targetmets_order: 29 + property bool tile_steering_angle_enabled: false + property int tile_steering_angle_order: 30 + property bool tile_pid_hr_enabled: false + property int tile_pid_hr_order: 31 + + property real heart_rate_zone1: 70.0 + property real heart_rate_zone2: 80.0 + property real heart_rate_zone3: 90.0 + property real heart_rate_zone4: 100.0 + property bool heart_max_override_enable: false + property real heart_max_override_value: 195.0 + + property real peloton_gain: 1.0 + property real peloton_offset: 0 + + property string treadmill_pid_heart_zone: "Disabled" + property real pacef_1mile: 250 + property real pacef_5km: 300 + property real pacef_10km: 320 + property real pacef_halfmarathon: 340 + property real pacef_marathon: 360 + property string pace_default: "Half Marathon" + + property bool domyos_treadmill_buttons: false + property bool domyos_treadmill_distance_display: true + property bool domyos_treadmill_display_invert: false + + property real domyos_bike_cadence_filter: 0.0 + property bool domyos_bike_display_calories: true + + property real domyos_elliptical_speed_ratio: 1.0 + + property bool eslinker_cadenza: true + + property string echelon_watttable: "Echelon" + + property real proform_wheel_ratio: 0.33 + property bool proform_tour_de_france_clc: false + property bool proform_tdf_jonseed_watt: false + property bool proform_studio: false + property bool proform_tdf_10: false + + property double horizon_gr7_cadence_multiplier: 1.0 + + property int fitshow_user_id: 0x13AA + + property bool inspire_peloton_formula: false + property bool inspire_peloton_formula2: false + + property bool hammer_racer_s: false + + property bool pafers_treadmill: false + + property bool yesoul_peloton_formula: false + + property bool nordictrack_10_treadmill: true + property bool nordictrack_t65s_treadmill: false + //property bool proform_treadmill_995i: false + + property bool toorx_3_0: false + property bool toorx_65s_evo: false + property bool jtx_fitness_sprint_treadmill: false + property bool dkn_endurun_treadmill: false + property bool trx_route_key: false + property bool bh_spada_2: false + property bool toorx_bike: false + property bool toorx_ftms: false + property bool jll_IC400_bike: false + property bool fytter_ri08_bike: false + property bool asviva_bike: false + property bool hertz_xr_770: false + + property int m3i_bike_id: 256 + property int m3i_bike_speed_buffsize: 90 + property bool m3i_bike_qt_search: false + property bool m3i_bike_kcal: true + + property bool snode_bike: false + property bool fitplus_bike: false + property bool virtufit_etappe: false + + property int flywheel_filter: 2 + property bool flywheel_life_fitness_ic8: false + + property bool sole_treadmill_inclination: false + property bool sole_treadmill_miles: true + property bool sole_treadmill_f65: false + property bool sole_treadmill_f63: false + property bool sole_treadmill_tt8: false + + property bool schwinn_bike_resistance: false + property bool schwinn_bike_resistance_v2: value + + property bool technogym_myrun_treadmill_experimental: false + + property bool trainprogram_random: false + property int trainprogram_total: 60 + property real trainprogram_period_seconds: 60 + property real trainprogram_speed_min: 8 + property real trainprogram_speed_max: 16 + property real trainprogram_incline_min: 0 + property real trainprogram_incline_max: 15 + property real trainprogram_resistance_min: 1 + property real trainprogram_resistance_max: 32 + + property real watt_offset: 0 + property real watt_gain: 1 + property bool power_avg_5s: false + property bool instant_power_on_pause: false + + property real speed_offset: 0 + property real speed_gain: 1 + + property string filter_device: "Disabled" + property string strava_suffix: "#QZ" + + property string cadence_sensor_name: "Disabled" + property bool cadence_sensor_as_bike: false + property real cadence_sensor_speed_ratio: 0.33 + property real power_hr_pwr1: 200 + property real power_hr_hr1: 150 + property real power_hr_pwr2: 230 + property real power_hr_hr2: 170 + + property string power_sensor_name: "Disabled" + property bool power_sensor_as_bike: false + property bool power_sensor_as_treadmill: false + property bool powr_sensor_running_cadence_double: false + + property string elite_rizer_name: "Disabled" + property string elite_sterzo_smart_name: "Disabled" + + property string ftms_accessory_name: "Disabled" + property real ss2k_shift_step: 900 + + property bool fitmetria_fanfit_enable: false + property string fitmetria_fanfit_mode: "Heart" + property real fitmetria_fanfit_min: 0 + property real fitmetria_fanfit_max: 100 + + property bool virtualbike_forceresistance: true + property bool bluetooth_relaxed: false + property bool bluetooth_30m_hangs: false + property bool battery_service: false + property bool service_changed: false + property bool virtual_device_enabled: true + property bool virtual_device_bluetooth: true + property bool ios_peloton_workaround: true + property bool android_wakelock: true + property bool log_debug: false + property bool virtual_device_onlyheart: false + property bool virtual_device_echelon: false + property bool virtual_device_ifit: false + property bool virtual_device_rower: false + property bool virtual_device_force_bike: false + property bool volume_change_gears: false + property bool applewatch_fakedevice: false + + // from version 2.10.15 + property real zwift_erg_resistance_down: 0.0 + property real zwift_erg_resistance_up: 999.0 + + // from version 2.10.16 + property bool horizon_paragon_x: false + + // from version 2.10.18 + property real treadmill_step_speed: 0.5 + property real treadmill_step_incline: 0.5 + + // from version 2.10.19 + property bool fitshow_anyrun: false + + // from version 2.10.21 + property bool nordictrack_s30_treadmill: false + + // from version 2.10.23 + // not used anymore because it's an elliptical not a treadmill. Don't remove this + // it will cause corruption in the settings + property bool nordictrack_fs5i_treadmill: false + + // from version 2.10.26 + property bool renpho_peloton_conversion_v2: false + + // from version 2.10.27 + property real ss2k_resistance_sample_1: 20 + property real ss2k_shift_step_sample_1: 0 + property real ss2k_resistance_sample_2: 30 + property real ss2k_shift_step_sample_2: 0 + property real ss2k_resistance_sample_3: 40 + property real ss2k_shift_step_sample_3: 0 + property real ss2k_resistance_sample_4: 50 + property real ss2k_shift_step_sample_4: 0 + + property bool fitshow_truetimer: false + + // from the version 2.10.28 + property real elite_rizer_gain: 1.0 + property bool tile_ext_incline_enabled: false + property int tile_ext_incline_order: 32 + + // from the version 2.10.41 + property bool reebok_fr30_treadmill: false + + // from the version 2.10.44 + property bool horizon_treadmill_7_8: false + + // from the version 2.10.45 + property string profile_name: "default" + + // from the version 2.10.46 + property bool tile_cadence_color_enabled: false + property bool tile_peloton_remaining_enabled: false + property int tile_peloton_remaining_order: 22 + property bool tile_peloton_resistance_color_enabled: false + + // from the version 2.10.49 + property bool dircon_yes: true + property int dircon_server_base_port: 36866 + + // from the version 2.10.56 + property bool ios_cache_heart_device: true + + // from the version 2.10.57 + property int app_opening: 0 + + // from the version 2.10.62 + property string proformtdf4ip: "" + + // from the version 2.10.72 + property bool fitfiu_mc_v460: false + property real bike_weight: 0 + + // from the version 2.10.77 + property bool kingsmith_encrypt_v2: false + + // from the version 2.10.81 + property bool proform_treadmill_9_0: false + + // from the version 2.10.85 + property bool proform_treadmill_1800i: false + + // from the version 2.10.91 + property real cadence_offset: 0 + property real cadence_gain: 1 + property bool sp_ht_9600ie: false + + // from the version 2.10.92 + property bool tts_enabled: false + property int tts_summary_sec: 120 + property bool tts_act_speed: false + property bool tts_avg_speed: true + property bool tts_max_speed: false + property bool tts_act_inclination: false + property bool tts_act_cadence: false + property bool tts_avg_cadence: true + property bool tts_max_cadence: false + property bool tts_act_elevation: true + property bool tts_act_calories: true + property bool tts_act_odometer: true + property bool tts_act_pace: false + property bool tts_avg_pace: true + property bool tts_max_pace: false + property bool tts_act_resistance: true + property bool tts_avg_resistance: true + property bool tts_max_resistance: false + property bool tts_act_watt: false + property bool tts_avg_watt: true + property bool tts_max_watt: true + property bool tts_act_ftp: false + property bool tts_avg_ftp: true + property bool tts_max_ftp: false + property bool tts_act_heart: true + property bool tts_avg_heart: true + property bool tts_max_heart: false + property bool tts_act_jouls: true + property bool tts_act_elapsed: true + property bool tts_act_peloton_resistance: false + property bool tts_avg_peloton_resistance: false + property bool tts_max_peloton_resistance: false + property bool tts_act_target_peloton_resistance: true + property bool tts_act_target_cadence: true + property bool tts_act_target_power: true + property bool tts_act_target_zone: true + property bool tts_act_target_speed: true + property bool tts_act_target_incline: true + property bool tts_act_watt_kg: false + property bool tts_avg_watt_kg: false + property bool tts_max_watt_kg: false + + // from the version 2.10.96 + property bool fakedevice_elliptical: false + + // from the version 2.10.99 + property string nordictrack_2950_ip: "" + + // from the version 2.10.102 + property bool tile_instantaneous_stride_length_enabled: false + property int tile_instantaneous_stride_length_order: 32 + property bool tile_ground_contact_enabled: false + property int tile_ground_contact_order: 33 + property bool tile_vertical_oscillation_enabled: false + property int tile_vertical_oscillation_order: 34 + property string sex: "Male" + + // from the version 2.10.111 + property string maps_type: "3D" + + // from the version 2.10.112 + property real ss2k_max_resistance: 100 + property real ss2k_min_resistance: 0 + + // from the version 2.11.10 + property bool proform_treadmill_se: false + + // from the version 2.11.14 + property string proformtreadmillip: "" + + // from the version 2.11.22 + property bool kingsmith_encrypt_v3: false + + + // from the version ? + property bool trixter_xdream_v1_bike: false + property bool trixter_xdream_v1_bike_heartrate_enabled: true + property bool trixter_xdream_v1_bike_steering_enabled: true + property int trixter_xdream_v1_bike_steering_L : -45 + property int trixter_xdream_v1_bike_steering_CL : -2 + property int trixter_xdream_v1_bike_steering_CR : 2 + property int trixter_xdream_v1_bike_steering_R : 45 + property int trixter_xdream_v1_bike_steering_MAX : 45 + + } - function paddingZeros(text, limit) { - if (text.length < limit) { + function paddingZeros(text, limit) { + if (text.length < limit) { return paddingZeros("0" + text, limit); - } else { + } else { return text; - } } + } - function formatLimitDecimals(value, decimals) { - const stringValue = value.toString(); - if(stringValue.includes('e')) { - // TODO: remove exponential notation - throw 'invald number'; - } else { + function formatLimitDecimals(value, decimals) { + const stringValue = value.toString(); + if(stringValue.includes('e')) { + // TODO: remove exponential notation + throw 'invald number'; + } else { const [integerPart, decimalPart] = stringValue.split('.'); if(decimalPart) { - return +[integerPart, decimalPart.slice(0, decimals)].join('.') + return +[integerPart, decimalPart.slice(0, decimals)].join('.') } else { - return integerPart; + return integerPart; } - } } + } - ColumnLayout { - id: column1 - spacing: 0 - anchors.fill: parent + ColumnLayout { + id: column1 + spacing: 0 + anchors.fill: parent - Label { - Layout.preferredWidth: parent.width - id: rebootLabel - text: qsTr("Reboot the app in order to apply the settings") - textFormat: Text.PlainText - wrapMode: Text.WordWrap - verticalAlignment: Text.AlignVCenter - color: Material.color(Material.Red) - } + Label { + Layout.preferredWidth: parent.width + id: rebootLabel + text: qsTr("Reboot the app in order to apply the settings") + textFormat: Text.PlainText + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + color: Material.color(Material.Red) + } - AccordionElement { - id: generalOptionsAccordion - title: qsTr("General Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { - spacing: 10 - Label { - id: labelUiZoom - text: qsTr("UI Zoom:") - Layout.fillWidth: true - } - TextField { - id: uiZoomTextField - text: settings.ui_zoom - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.ui_zoom = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okUiZoomButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ui_zoom = uiZoomTextField.text - } + AccordionElement { + id: generalOptionsAccordion + title: qsTr("General Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 + RowLayout { + spacing: 10 + Label { + id: labelUiZoom + text: qsTr("UI Zoom:") + Layout.fillWidth: true } - - RowLayout { - spacing: 10 - Label { - id: labelWeight - text: qsTr("Player Weight") + "(" + (settings.miles_unit?"lbs":"kg") + ")" - Layout.fillWidth: true - } - TextField { - id: weightTextField - text: (settings.miles_unit?settings.weight * 2.20462:settings.weight) - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.weight = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okWeightButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.weight = (settings.miles_unit?weightTextField.text / 2.20462:weightTextField.text) - } + TextField { + id: uiZoomTextField + text: settings.ui_zoom + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.ui_zoom = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - - RowLayout { - spacing: 10 - Label { - id: labelAge - text: qsTr("Player Age:") - Layout.fillWidth: true - } - TextField { - id: ageTextField - text: settings.age - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.age = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okAgeButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.age = ageTextField.text - } + Button { + id: okUiZoomButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ui_zoom = uiZoomTextField.text } + } - RowLayout { - spacing: 10 - Label { - id: labelSex - text: qsTr("Gender:") - Layout.fillWidth: true - } - ComboBox { - id: sexTextField - model: [ "Male", "Female" ] - displayText: settings.sex - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + sexTextField.currentIndex) - displayText = sexTextField.currentValue - } - - } - Button { - id: okSex - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.sex = sexTextField.displayText - } + RowLayout { + spacing: 10 + Label { + id: labelWeight + text: qsTr("Player Weight") + "(" + (settings.miles_unit?"lbs":"kg") + ")" + Layout.fillWidth: true } - - RowLayout { - spacing: 10 - Label { - id: labelFTP - text: qsTr("FTP value:") - Layout.fillWidth: true - } - TextField { - id: ftpTextField - text: settings.ftp - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.ftp = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okFTPButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ftp = ftpTextField.text - } + TextField { + id: weightTextField + text: (settings.miles_unit?settings.weight * 2.20462:settings.weight) + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.weight = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - - RowLayout { - spacing: 10 - Label { - id: labelNickname - text: qsTr("Nickname:") - Layout.fillWidth: true - } - TextField { - id: nicknameTextField - text: settings.user_nickname - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onAccepted: settings.user_nickname = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okNicknameButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.user_nickname = nicknameTextField.text - } + Button { + id: okWeightButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.weight = (settings.miles_unit?weightTextField.text / 2.20462:weightTextField.text) } + } - RowLayout { - spacing: 10 - Label { - id: labelEmail - text: qsTr("Email:") - Layout.fillWidth: true - } - TextField { - id: emailTextField - text: settings.user_email - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onAccepted: settings.user_email = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okEmailButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.user_email = emailTextField.text - } + RowLayout { + spacing: 10 + Label { + id: labelAge + text: qsTr("Player Age:") + Layout.fillWidth: true + } + TextField { + id: ageTextField + text: settings.age + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.age = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okAgeButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.age = ageTextField.text } + } - SwitchDelegate { - id: unitDelegate - text: qsTr("Use Miles unit in UI") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.miles_unit - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelSex + text: qsTr("Gender:") Layout.fillWidth: true - onClicked: settings.miles_unit = checked } + ComboBox { + id: sexTextField + model: [ "Male", "Female" ] + displayText: settings.sex + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + sexTextField.currentIndex) + displayText = sexTextField.currentValue + } - SwitchDelegate { - id: pauseOnStartDelegate - text: qsTr("Pause when App Starts") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.pause_on_start - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.pause_on_start = checked } + Button { + id: okSex + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.sex = sexTextField.displayText + } + } - SwitchDelegate { - id: continuousMovingDelegate - text: qsTr("Continuous Moving") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.continuous_moving - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelFTP + text: qsTr("FTP value:") Layout.fillWidth: true - onClicked: settings.continuous_moving = checked + } + TextField { + id: ftpTextField + text: settings.ftp + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.ftp = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okFTPButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ftp = ftpTextField.text } } - } - - /*Label { - id: zwiftInfoLabel - text: qsTr("Zwift users: keep this setting off") - font.bold: yes - font.italic: yes - font.pixelSize: 8 - textFormat: Text.PlainText - wrapMode: Text.WordWrap - verticalAlignment: Text.AlignVCenter - color: Material.color(Material.Red) - }*/ - AccordionElement { - id: heartRateOptionsAccordion - title: qsTr("Heart Rate Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - accordionContent: ColumnLayout { + RowLayout { spacing: 10 - SwitchDelegate { - id: switchDelegate - text: qsTr("Heart Rate service outside FTMS") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.bike_heartrate_service - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Label { + id: labelNickname + text: qsTr("Nickname:") Layout.fillWidth: true - onClicked: settings.bike_heartrate_service = checked } - SwitchDelegate { - id: switchBultinDelegate - text: qsTr("Disable HRM from Machinery") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.heart_ignore_builtin - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.heart_ignore_builtin = checked + TextField { + id: nicknameTextField + text: settings.user_nickname + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onAccepted: settings.user_nickname = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - SwitchDelegate { - id: switchBultinKcalDelegate - text: qsTr("Disable KCal from Machinery") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.kcal_ignore_builtin - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.kcal_ignore_builtin = checked + Button { + id: okNicknameButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.user_nickname = nicknameTextField.text } - RowLayout { - spacing: 10 - Label { - id: labelHeartRateBelt - text: qsTr("Heart Belt Name:") - Layout.fillWidth: true - } - ComboBox { - id: heartBeltNameTextField - model: rootItem.bluetoothDevices - displayText: settings.heart_rate_belt_name - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + heartBeltNameTextField.currentIndex) - displayText = heartBeltNameTextField.currentValue - } + } - } - Button { - id: okHeartBeltNameButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.heart_rate_belt_name = heartBeltNameTextField.displayText; - } + RowLayout { + spacing: 10 + Label { + id: labelEmail + text: qsTr("Email:") + Layout.fillWidth: true + } + TextField { + id: emailTextField + text: settings.user_email + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onAccepted: settings.user_email = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okEmailButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.user_email = emailTextField.text } + } + + SwitchDelegate { + id: unitDelegate + text: qsTr("Use Miles unit in UI") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.miles_unit + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.miles_unit = checked + } + + SwitchDelegate { + id: pauseOnStartDelegate + text: qsTr("Pause when App Starts") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.pause_on_start + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.pause_on_start = checked + } + + SwitchDelegate { + id: continuousMovingDelegate + text: qsTr("Continuous Moving") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.continuous_moving + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.continuous_moving = checked + } + } + } + + /*Label { + id: zwiftInfoLabel + text: qsTr("Zwift users: keep this setting off") + font.bold: yes + font.italic: yes + font.pixelSize: 8 + textFormat: Text.PlainText + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + color: Material.color(Material.Red) + }*/ + AccordionElement { + id: heartRateOptionsAccordion + title: qsTr("Heart Rate Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 10 + SwitchDelegate { + id: switchDelegate + text: qsTr("Heart Rate service outside FTMS") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.bike_heartrate_service + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.bike_heartrate_service = checked + } + SwitchDelegate { + id: switchBultinDelegate + text: qsTr("Disable HRM from Machinery") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.heart_ignore_builtin + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.heart_ignore_builtin = checked + } + SwitchDelegate { + id: switchBultinKcalDelegate + text: qsTr("Disable KCal from Machinery") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.kcal_ignore_builtin + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.kcal_ignore_builtin = checked + } + RowLayout { + spacing: 10 Label { - id: appleWatchLabel - text: qsTr("Apple Watch users: leave it disabled! Just open the app on your watch") - font.bold: true - font.italic: true - font.pixelSize: 8 - textFormat: Text.PlainText - wrapMode: Text.WordWrap - verticalAlignment: Text.AlignVCenter - color: Material.color(Material.Red) + id: labelHeartRateBelt + text: qsTr("Heart Belt Name:") + Layout.fillWidth: true } + ComboBox { + id: heartBeltNameTextField + model: rootItem.bluetoothDevices + displayText: settings.heart_rate_belt_name + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + heartBeltNameTextField.currentIndex) + displayText = heartBeltNameTextField.currentValue + } + } Button { - id: refreshHeartBeltNameButton - text: "Refresh Devices List" + id: okHeartBeltNameButton + text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: refresh_bluetooth_devices_clicked(); + onClicked: settings.heart_rate_belt_name = heartBeltNameTextField.displayText; } + } - AccordionElement { - id: heartRateZoneAccordion - title: qsTr("Heart Rate Zone Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { - spacing: 10 - Label { - id: labelheartRateZone1Ratio - text: qsTr("Zone 1 %:") - Layout.fillWidth: true - } - TextField { - id: heartRateZone1TextField - text: settings.heart_rate_zone1 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.heart_rate_zone1 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okHeartRateZone1Button - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.heart_rate_zone1 = heartRateZone1TextField.text - } - } + Label { + id: appleWatchLabel + text: qsTr("Apple Watch users: leave it disabled! Just open the app on your watch") + font.bold: true + font.italic: true + font.pixelSize: 8 + textFormat: Text.PlainText + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + color: Material.color(Material.Red) + } - RowLayout { - spacing: 10 - Label { - id: labelheartRateZone2Ratio - text: qsTr("Zone 2 %:") - Layout.fillWidth: true - } - TextField { - id: heartRateZone2TextField - text: settings.heart_rate_zone2 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.heart_rate_zone2 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okHeartRateZone2Button - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.heart_rate_zone2 = heartRateZone2TextField.text - } - } + Button { + id: refreshHeartBeltNameButton + text: "Refresh Devices List" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: refresh_bluetooth_devices_clicked(); + } - RowLayout { - spacing: 10 - Label { - id: labelheartRateZone3Ratio - text: qsTr("Zone 3 %:") - Layout.fillWidth: true - } - TextField { - id: heartRateZone3TextField - text: settings.heart_rate_zone3 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.heart_rate_zone3 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okHeartRateZone3Button - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.heart_rate_zone3 = heartRateZone3TextField.text - } + AccordionElement { + id: heartRateZoneAccordion + title: qsTr("Heart Rate Zone Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + RowLayout { + spacing: 10 + Label { + id: labelheartRateZone1Ratio + text: qsTr("Zone 1 %:") + Layout.fillWidth: true } - - RowLayout { - spacing: 10 - Label { - id: labelheartRateZone4Ratio - text: qsTr("Zone 4 %:") - Layout.fillWidth: true - } - TextField { - id: heartRateZone4TextField - text: settings.heart_rate_zone4 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.heart_rate_zone4 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okHeartRateZone4Button - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.heart_rate_zone4 = heartRateZone4TextField.text - } + TextField { + id: heartRateZone1TextField + text: settings.heart_rate_zone1 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.heart_rate_zone1 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } + Button { + id: okHeartRateZone1Button + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.heart_rate_zone1 = heartRateZone1TextField.text + } + } - AccordionElement { - id: heartRatemaxOverrideAccordion - title: qsTr("Heart Rate Max Override") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Red) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 10 - SwitchDelegate { - id: heartRateMaxOverrideDelegate - text: qsTr("Override Heart Rate Max Calc.") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.heart_max_override_enable - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.heart_max_override_enable = checked - } - - RowLayout { - spacing: 10 - Label { - id: labelHeartRateMaxOverrideValue - text: qsTr("Max Heart Rate") - Layout.fillWidth: true - } - TextField { - id: heartRateMaxOverrideValueTextField - text: settings.heart_max_override_value - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.heart_max_override_value = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okHeartRateMaxOverrideValue - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.heart_max_override_value = heartRateMaxOverrideValueTextField.text - } - } - } + RowLayout { + spacing: 10 + Label { + id: labelheartRateZone2Ratio + text: qsTr("Zone 2 %:") + Layout.fillWidth: true + } + TextField { + id: heartRateZone2TextField + text: settings.heart_rate_zone2 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.heart_rate_zone2 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okHeartRateZone2Button + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.heart_rate_zone2 = heartRateZone2TextField.text } } - } - AccordionElement { - id: powerFromHeartRateAccordion - title: qsTr("Power from Heart Rate Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { - spacing: 10 - Label { - id: labelPowerFromHeartPWR1 - text: qsTr("Session 1 Watt:") - Layout.fillWidth: true - } - TextField { - id: powerFromHeartPWR1TextField - text: settings.power_hr_pwr1 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.power_hr_pwr1 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okPowerFromHeartPWR1 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.power_hr_pwr1 = powerFromHeartPWR1TextField.text - } + RowLayout { + spacing: 10 + Label { + id: labelheartRateZone3Ratio + text: qsTr("Zone 3 %:") + Layout.fillWidth: true } - - RowLayout { - spacing: 10 - Label { - id: labelPowerFromHeartHR1 - text: qsTr("Session 1 HR:") - Layout.fillWidth: true - } - TextField { - id: powerFromHeartHR1TextField - text: settings.power_hr_hr1 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.power_hr_hr1 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okPowerFromHeartHR1 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.power_hr_hr1 = powerFromHeartHR1TextField.text - } + TextField { + id: heartRateZone3TextField + text: settings.heart_rate_zone3 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.heart_rate_zone3 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okHeartRateZone3Button + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.heart_rate_zone3 = heartRateZone3TextField.text } + } - RowLayout { - spacing: 10 - Label { - id: labelPowerFromHeartPWR2 - text: qsTr("Session 2 Watt:") - Layout.fillWidth: true - } - TextField { - id: powerFromHeartPWR2TextField - text: settings.power_hr_pwr2 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.power_hr_pwr2 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okPowerFromHeartPWR2 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.power_hr_pwr2 = powerFromHeartPWR2TextField.text - } + RowLayout { + spacing: 10 + Label { + id: labelheartRateZone4Ratio + text: qsTr("Zone 4 %:") + Layout.fillWidth: true + } + TextField { + id: heartRateZone4TextField + text: settings.heart_rate_zone4 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.heart_rate_zone4 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okHeartRateZone4Button + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.heart_rate_zone4 = heartRateZone4TextField.text } + } - RowLayout { + AccordionElement { + id: heartRatemaxOverrideAccordion + title: qsTr("Heart Rate Max Override") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Red) + color: Material.backgroundColor + accordionContent: ColumnLayout { spacing: 10 - Label { - id: labelPowerFromHeartHR2 - text: qsTr("Session 2 HR:") + SwitchDelegate { + id: heartRateMaxOverrideDelegate + text: qsTr("Override Heart Rate Max Calc.") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.heart_max_override_enable + Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true + onClicked: settings.heart_max_override_enable = checked } - TextField { - id: powerFromHeartHR2TextField - text: settings.power_hr_hr2 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.power_hr_hr2 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okPowerFromHeartHR2 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.power_hr_hr2 = powerFromHeartHR2TextField.text + + RowLayout { + spacing: 10 + Label { + id: labelHeartRateMaxOverrideValue + text: qsTr("Max Heart Rate") + Layout.fillWidth: true + } + TextField { + id: heartRateMaxOverrideValueTextField + text: settings.heart_max_override_value + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.heart_max_override_value = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okHeartRateMaxOverrideValue + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.heart_max_override_value = heartRateMaxOverrideValueTextField.text + } } } } } } - } - AccordionElement { - id: bikeOptionsAccordion - title: qsTr("Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: speedPowerBasedDelegate - text: qsTr("Speed calculates on Power") + AccordionElement { + id: powerFromHeartRateAccordion + title: qsTr("Power from Heart Rate Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.speed_power_based - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.speed_power_based = checked - } - RowLayout { - spacing: 10 - Label { - id: labelBikeWeight - text: qsTr("Bike Weight") + "(" + (settings.miles_unit?"lbs":"kg") + ")" - Layout.fillWidth: true + RowLayout { + spacing: 10 + Label { + id: labelPowerFromHeartPWR1 + text: qsTr("Session 1 Watt:") + Layout.fillWidth: true + } + TextField { + id: powerFromHeartPWR1TextField + text: settings.power_hr_pwr1 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.power_hr_pwr1 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPowerFromHeartPWR1 + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.power_hr_pwr1 = powerFromHeartPWR1TextField.text + } } - TextField { - id: bikeweightTextField - text: (settings.miles_unit?settings.bike_weight * 2.20462:settings.bike_weight) - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.bike_weight = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + + RowLayout { + spacing: 10 + Label { + id: labelPowerFromHeartHR1 + text: qsTr("Session 1 HR:") + Layout.fillWidth: true + } + TextField { + id: powerFromHeartHR1TextField + text: settings.power_hr_hr1 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.power_hr_hr1 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPowerFromHeartHR1 + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.power_hr_hr1 = powerFromHeartHR1TextField.text + } } - Button { - id: okBikeWeightButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.bike_weight = (settings.miles_unit?bikeweightTextField.text / 2.20462:bikeweightTextField.text) + + RowLayout { + spacing: 10 + Label { + id: labelPowerFromHeartPWR2 + text: qsTr("Session 2 Watt:") + Layout.fillWidth: true + } + TextField { + id: powerFromHeartPWR2TextField + text: settings.power_hr_pwr2 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.power_hr_pwr2 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPowerFromHeartPWR2 + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.power_hr_pwr2 = powerFromHeartPWR2TextField.text + } + } + + RowLayout { + spacing: 10 + Label { + id: labelPowerFromHeartHR2 + text: qsTr("Session 2 HR:") + Layout.fillWidth: true + } + TextField { + id: powerFromHeartHR2TextField + text: settings.power_hr_hr2 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.power_hr_hr2 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPowerFromHeartHR2 + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.power_hr_hr2 = powerFromHeartHR2TextField.text + } } } - SwitchDelegate { - id: zwiftErgDelegate - text: qsTr("Zwift Workout/Erg Mode") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.zwift_erg - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + } + } + } + + AccordionElement { + id: bikeOptionsAccordion + title: qsTr("Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: speedPowerBasedDelegate + text: qsTr("Speed calculates on Power") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.speed_power_based + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.speed_power_based = checked + } + RowLayout { + spacing: 10 + Label { + id: labelBikeWeight + text: qsTr("Bike Weight") + "(" + (settings.miles_unit?"lbs":"kg") + ")" Layout.fillWidth: true - onClicked: settings.zwift_erg = checked } - SwitchDelegate { - id: zwiftNegativeIncliantionX2Delegate - text: qsTr("Double Negative Inclination") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.zwift_negative_inclination_x2 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.zwift_negative_inclination_x2 = checked + TextField { + id: bikeweightTextField + text: (settings.miles_unit?settings.bike_weight * 2.20462:settings.bike_weight) + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.bike_weight = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - RowLayout { - spacing: 10 - Label { - id: labelBikeResistanceOffset - text: qsTr("Zwift Resistance Offset:") - Layout.fillWidth: true - } - TextField { - id: bikeResistanceOffsetTextField - text: settings.bike_resistance_offset - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.bike_resistance_offset = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okBikeResistanceOffsetButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.bike_resistance_offset = bikeResistanceOffsetTextField.text - } + Button { + id: okBikeWeightButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.bike_weight = (settings.miles_unit?bikeweightTextField.text / 2.20462:bikeweightTextField.text) + } + } + SwitchDelegate { + id: zwiftErgDelegate + text: qsTr("Zwift Workout/Erg Mode") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.zwift_erg + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.zwift_erg = checked + } + SwitchDelegate { + id: zwiftNegativeIncliantionX2Delegate + text: qsTr("Double Negative Inclination") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.zwift_negative_inclination_x2 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.zwift_negative_inclination_x2 = checked + } + RowLayout { + spacing: 10 + Label { + id: labelBikeResistanceOffset + text: qsTr("Zwift Resistance Offset:") + Layout.fillWidth: true + } + TextField { + id: bikeResistanceOffsetTextField + text: settings.bike_resistance_offset + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.bike_resistance_offset = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okBikeResistanceOffsetButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.bike_resistance_offset = bikeResistanceOffsetTextField.text } + } - RowLayout { - spacing: 10 - Label { - id: labelBikeResistanceGain - text: qsTr("Zwift Resistance Gain:") - Layout.fillWidth: true - } - TextField { - id: bikeResistanceGainTextField - text: settings.bike_resistance_gain_f - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.bike_resistance_gain_f = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okBikeResistanceGainButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.bike_resistance_gain_f = bikeResistanceGainTextField.text - } + RowLayout { + spacing: 10 + Label { + id: labelBikeResistanceGain + text: qsTr("Zwift Resistance Gain:") + Layout.fillWidth: true + } + TextField { + id: bikeResistanceGainTextField + text: settings.bike_resistance_gain_f + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.bike_resistance_gain_f = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okBikeResistanceGainButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.bike_resistance_gain_f = bikeResistanceGainTextField.text } + } - RowLayout { - spacing: 10 - Label { - id: labelZwiftErgFilter - text: qsTr("Zwift ERG Watt Up Filter:") - Layout.fillWidth: true - } - TextField { - id: zwiftErgFilterTextField - text: settings.zwift_erg_filter - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.zwift_erg_filter = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okzwiftErgFilterButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.zwift_erg_filter = zwiftErgFilterTextField.text - } + RowLayout { + spacing: 10 + Label { + id: labelZwiftErgFilter + text: qsTr("Zwift ERG Watt Up Filter:") + Layout.fillWidth: true + } + TextField { + id: zwiftErgFilterTextField + text: settings.zwift_erg_filter + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.zwift_erg_filter = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okzwiftErgFilterButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.zwift_erg_filter = zwiftErgFilterTextField.text + } + } + + RowLayout { + spacing: 10 + Label { + id: labelZwiftErgDownFilter + text: qsTr("Zwift ERG Watt Down Filter:") + Layout.fillWidth: true + } + TextField { + id: zwiftErgDownFilterTextField + text: settings.zwift_erg_filter_down + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.zwift_erg_filter_down = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okzwiftErgDownFilterButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.zwift_erg_filter_down = zwiftErgDownFilterTextField.text + } + } + + RowLayout { + spacing: 10 + Label { + id: labelZwiftErgResistanceDown + text: qsTr("ERG Min. Resistance:") + Layout.fillWidth: true + } + TextField { + id: zwiftErgResistanceDownTextField + text: settings.zwift_erg_resistance_down + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.zwift_erg_resistance_down = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okzwiftErgResistanceDownButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.zwift_erg_resistance_down = zwiftErgResistanceDownTextField.text + } + } + + RowLayout { + spacing: 10 + Label { + id: labelZwiftErgResistanceUp + text: qsTr("ERG Max. Resistance:") + Layout.fillWidth: true + } + TextField { + id: zwiftErgResistanceUpTextField + text: settings.zwift_erg_resistance_up + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.zwift_erg_resistance_up = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okzwiftErgResistanceUpButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.zwift_erg_resistance_up = zwiftErgResistanceUpTextField.text + } + } + + RowLayout { + spacing: 10 + Label { + id: labelBikeResistanceStart + text: qsTr("Resistance at Startup:") + Layout.fillWidth: true + } + TextField { + id: bikeResistanceStartTextField + text: settings.bike_resistance_start + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.bike_resistance_start = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okBikeResistanceStartButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.bike_resistance_start = bikeResistanceStartTextField.text + } + } + } + + AccordionElement { + id: schwinnBikeAccordion + title: qsTr("Schwinn Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: schwinnBikeResistanceDelegate + text: qsTr("Calc. Resistance") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.schwinn_bike_resistance + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.schwinn_bike_resistance = checked + } + SwitchDelegate { + id: schwinnBikeResistanceV2Delegate + text: qsTr("Resistance Alternative Calc.") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.schwinn_bike_resistance_v2 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.schwinn_bike_resistance_v2 = checked + } + } + } + AccordionElement { + id: horizonBikeAccordion + title: qsTr("Horizon Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelHorizonGr7CadenceMultiplier + text: qsTr("GR7 Cadence Multiplier:") + Layout.fillWidth: true + } + TextField { + id: horizonGr7CadenceMultiplierTextField + text: settings.horizon_gr7_cadence_multiplier + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.horizon_gr7_cadence_multiplier = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } + Button { + id: okhorizonGr7CadenceMultiplierButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.horizon_gr7_cadence_multiplier = horizonGr7CadenceMultiplierTextField.text + } + } + } + AccordionElement { + id: echelonBikeOptionsAccordion + title: qsTr("Echelon Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 RowLayout { spacing: 10 Label { - id: labelZwiftErgDownFilter - text: qsTr("Zwift ERG Watt Down Filter:") + id: labelEchelonWattTable + text: qsTr("Watt Profile:") Layout.fillWidth: true } - TextField { - id: zwiftErgDownFilterTextField - text: settings.zwift_erg_filter_down - horizontalAlignment: Text.AlignRight + ComboBox { + id: echelonWattTableTextField + model: [ "Echelon", "mgarcea" ] + displayText: settings.echelon_watttable Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.zwift_erg_filter_down = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onActivated: { + console.log("combomodel activated" + echelonWattTableTextField.currentIndex) + displayText = echelonWattTableTextField.currentValue + } + } Button { - id: okzwiftErgDownFilterButton + id: okEchelonWattTable text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.zwift_erg_filter_down = zwiftErgDownFilterTextField.text + onClicked: settings.echelon_watttable = echelonWattTableTextField.displayText } } - RowLayout { spacing: 10 Label { - id: labelZwiftErgResistanceDown - text: qsTr("ERG Min. Resistance:") + id: labelEchelonResistanceGain + text: qsTr("Resistance Gain:") Layout.fillWidth: true } TextField { - id: zwiftErgResistanceDownTextField - text: settings.zwift_erg_resistance_down + id: echelonResistanceGainTextField + text: settings.echelon_resistance_gain horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.zwift_erg_resistance_down = text + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.echelon_resistance_gain = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okzwiftErgResistanceDownButton + id: okechelonResistanceGainButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.zwift_erg_resistance_down = zwiftErgResistanceDownTextField.text + onClicked: settings.echelon_resistance_gain = echelonResistanceGainTextField.text } } - RowLayout { spacing: 10 Label { - id: labelZwiftErgResistanceUp - text: qsTr("ERG Max. Resistance:") + id: labelEchelonResistanceOffset + text: qsTr("Resistance Offset:") Layout.fillWidth: true } TextField { - id: zwiftErgResistanceUpTextField - text: settings.zwift_erg_resistance_up + id: echelonResistanceOffsetTextField + text: settings.echelon_resistance_offset horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.zwift_erg_resistance_up = text + onAccepted: settings.echelon_resistance_offset = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okzwiftErgResistanceUpButton + id: okechelonResistanceOffsetButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.zwift_erg_resistance_up = zwiftErgResistanceUpTextField.text + onClicked: settings.echelon_resistance_offset = echelonResistanceOffsetTextField.text } } + } + } - RowLayout { - spacing: 10 - Label { - id: labelBikeResistanceStart - text: qsTr("Resistance at Startup:") - Layout.fillWidth: true - } - TextField { - id: bikeResistanceStartTextField - text: settings.bike_resistance_start - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.bike_resistance_start = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okBikeResistanceStartButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.bike_resistance_start = bikeResistanceStartTextField.text - } - } - } - - AccordionElement { - id: schwinnBikeAccordion - title: qsTr("Schwinn Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: schwinnBikeResistanceDelegate - text: qsTr("Calc. Resistance") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.schwinn_bike_resistance - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.schwinn_bike_resistance = checked - } - SwitchDelegate { - id: schwinnBikeResistanceV2Delegate - text: qsTr("Resistance Alternative Calc.") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.schwinn_bike_resistance_v2 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.schwinn_bike_resistance_v2 = checked - } - } - } - AccordionElement { - id: horizonBikeAccordion - title: qsTr("Horizon Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelHorizonGr7CadenceMultiplier - text: qsTr("GR7 Cadence Multiplier:") - Layout.fillWidth: true - } - TextField { - id: horizonGr7CadenceMultiplierTextField - text: settings.horizon_gr7_cadence_multiplier - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.horizon_gr7_cadence_multiplier = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okhorizonGr7CadenceMultiplierButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.horizon_gr7_cadence_multiplier = horizonGr7CadenceMultiplierTextField.text - } - } - } - - AccordionElement { - id: echelonBikeOptionsAccordion - title: qsTr("Echelon Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { - spacing: 10 - Label { - id: labelEchelonWattTable - text: qsTr("Watt Profile:") - Layout.fillWidth: true - } - ComboBox { - id: echelonWattTableTextField - model: [ "Echelon", "mgarcea" ] - displayText: settings.echelon_watttable - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + echelonWattTableTextField.currentIndex) - displayText = echelonWattTableTextField.currentValue - } - - } - Button { - id: okEchelonWattTable - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.echelon_watttable = echelonWattTableTextField.displayText - } - } - RowLayout { - spacing: 10 - Label { - id: labelEchelonResistanceGain - text: qsTr("Resistance Gain:") - Layout.fillWidth: true - } - TextField { - id: echelonResistanceGainTextField - text: settings.echelon_resistance_gain - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.echelon_resistance_gain = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okechelonResistanceGainButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.echelon_resistance_gain = echelonResistanceGainTextField.text - } - } - RowLayout { - spacing: 10 - Label { - id: labelEchelonResistanceOffset - text: qsTr("Resistance Offset:") - Layout.fillWidth: true - } - TextField { - id: echelonResistanceOffsetTextField - text: settings.echelon_resistance_offset - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.echelon_resistance_offset = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okechelonResistanceOffsetButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.echelon_resistance_offset = echelonResistanceOffsetTextField.text - } - } - } - } - - AccordionElement { - id: inspireBikeAccordion - title: qsTr("Inspire Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 + AccordionElement { + id: inspireBikeAccordion + title: qsTr("Inspire Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 SwitchDelegate { id: inspirePelotonFormulaDelegate text: qsTr("Advanced Formula (15/3/2021)") @@ -1568,4900 +1570,4859 @@ import Qt.labs.settings 1.0 Layout.fillWidth: true onClicked: settings.inspire_peloton_formula2 = checked } - } - } - - AccordionElement { - id: renphoBikeAccordion - title: qsTr("Renpho Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: renphoPelotonFormulaDelegate - text: qsTr("New Peloton Formula (11/02/2022)") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.renpho_peloton_conversion_v2 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.renpho_peloton_conversion_v2 = checked - } - } } + } - AccordionElement { - id: hammerBikeAccordion - title: qsTr("Hammer Racer Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: SwitchDelegate { - id: hammerBikeDelegate - text: qsTr("Enable support") + AccordionElement { + id: renphoBikeAccordion + title: qsTr("Renpho Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: renphoPelotonFormulaDelegate + text: qsTr("New Peloton Formula (11/02/2022)") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.hammer_racer_s + checked: settings.renpho_peloton_conversion_v2 Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.hammer_racer_s = checked + onClicked: settings.renpho_peloton_conversion_v2 = checked } } - AccordionElement { - id: cardioFitBikeAccordion - title: qsTr("CardioFIT Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: SwitchDelegate { - id: spht9600iEBikeDelegate - text: qsTr("SP-HT-9600iE") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.sp_ht_9600ie - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.sp_ht_9600ie = checked - } + } + + AccordionElement { + id: hammerBikeAccordion + title: qsTr("Hammer Racer Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: SwitchDelegate { + id: hammerBikeDelegate + text: qsTr("Enable support") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.hammer_racer_s + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.hammer_racer_s = checked } - AccordionElement { - id: yesoulBikeAccordion - title: qsTr("Yesoul Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: SwitchDelegate { - id: yesoulBikeDelegate - text: qsTr("Yesoul New Peloton Formula") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.yesoul_peloton_formula - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.yesoul_peloton_formula = checked - } + } + AccordionElement { + id: cardioFitBikeAccordion + title: qsTr("CardioFIT Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: SwitchDelegate { + id: spht9600iEBikeDelegate + text: qsTr("SP-HT-9600iE") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.sp_ht_9600ie + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.sp_ht_9600ie = checked + } + } + AccordionElement { + id: yesoulBikeAccordion + title: qsTr("Yesoul Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: SwitchDelegate { + id: yesoulBikeDelegate + text: qsTr("Yesoul New Peloton Formula") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.yesoul_peloton_formula + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.yesoul_peloton_formula = checked } + } - AccordionElement { - id: snodeBikeAccordion - title: qsTr("Snode Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: SwitchDelegate { - id: snodeBikeDelegate - text: qsTr("Snode Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.snode_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.snode_bike = checked - } + AccordionElement { + id: snodeBikeAccordion + title: qsTr("Snode Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: SwitchDelegate { + id: snodeBikeDelegate + text: qsTr("Snode Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.snode_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.snode_bike = checked } - AccordionElement { - id: fitplusBikeAccordion - title: qsTr("Fitplus Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: + } + AccordionElement { + id: fitplusBikeAccordion + title: qsTr("Fitplus Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: SwitchDelegate { - id: fitplusBikeDelegate - text: qsTr("Fit Plus Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.fitplus_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.fitplus_bike = checked - } + id: fitplusBikeDelegate + text: qsTr("Fit Plus Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.fitplus_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.fitplus_bike = checked + } + SwitchDelegate { + id: virtufitEtappeBikeDelegate + text: qsTr("Virtufit Etappe 2.0 Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.virtufit_etappe + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.virtufit_etappe = checked + } + } + AccordionElement { + id: trixterXDreamV1BikeAccordion + title: qsTr("Trixter X-Dream V1 Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: SwitchDelegate { - id: virtufitEtappeBikeDelegate - text: qsTr("Virtufit Etappe 2.0 Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.virtufit_etappe - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + id: trixterXDreamV1 + text: qsTr("Trixter X-Dream V1 Bike Enabled") + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Use this to enable or disable detection of the Trixter X-Dream V1 Bike.") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.trixter_xdream_v1_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.trixter_xdream_v1_bike = checked + } + SwitchDelegate { + id: trixterXDreamV1HeartRate + text: qsTr("Heart Rate Signal Enabled") + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Use this to enable or disable the heart rate signal.") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.trixter_xdream_v1_bike_heartrate_enabled + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.trixter_xdream_v1_bike_heartrate_enabled = checked + } + SwitchDelegate { + id: trixterXDreamV1Steering + text: qsTr("Steering Enabled") + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Use this to enable or disable steering.") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.trixter_xdream_v1_bike_steering_enabled + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.trixter_xdream_v1_bike_steering_enabled = checked + } + RowLayout { + id: trixterXDreamV1Calibration + spacing: 10 + Label { + id: labelTrixterXDreamV1BikeSteeringBoundariesAngular + text: qsTr("Steering Calibration (Use values from Steering Tile with default calibration)") Layout.fillWidth: true - onClicked: settings.virtufit_etappe = checked } - } - AccordionElement { - id: trixterXDreamV1BikeAccordion - title: qsTr("Trixter X-Dream V1 Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: - SwitchDelegate { - id: trixterXDreamV1 - text: qsTr("Trixter X-Dream V1 Bike Enabled") + SpinBox { + id: trixterXDreamV1BikeSteeringAngleLeftSpinBox + value: settings.trixter_xdream_v1_bike_steering_L hoverEnabled: true ToolTip.visible: hovered - ToolTip.text: qsTr("Use this to enable or disable detection of the Trixter X-Dream V1 Bike.") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.trixter_xdream_v1_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.trixter_xdream_v1_bike = checked + ToolTip.text: qsTr("Unadjusted steering angle that is 100% left.") + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + + from: -settings.trixter_xdream_v1_bike_steering_MAX + to: trixterXDreamV1BikeSteeringAngleCenterLeftSpinBox.value + onValueChanged: settings.trixter_xdream_v1_bike_steering_L = value } - SwitchDelegate { - id: trixterXDreamV1HeartRate - text: qsTr("Heart Rate Signal Enabled") + SpinBox { + id: trixterXDreamV1BikeSteeringAngleCenterLeftSpinBox + value: settings.trixter_xdream_v1_bike_steering_CL hoverEnabled: true ToolTip.visible: hovered - ToolTip.text: qsTr("Use this to enable or disable the heart rate signal.") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.trixter_xdream_v1_bike_heartrate_enabled - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.trixter_xdream_v1_bike_heartrate_enabled = checked + ToolTip.text: qsTr("Leftmost unadjusted steering angle to be mapped to 0 degrees.") + + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + + from: trixterXDreamV1BikeSteeringAngleLeftSpinBox.value + to: trixterXDreamV1BikeSteeringAngleCenterRightSpinBox.value + onValueChanged: settings.trixter_xdream_v1_bike_steering_CL = value } - SwitchDelegate { - id: trixterXDreamV1Steering - text: qsTr("Steering Enabled") + SpinBox { + id: trixterXDreamV1BikeSteeringAngleCenterRightSpinBox + value: settings.trixter_xdream_v1_bike_steering_CR hoverEnabled: true ToolTip.visible: hovered - ToolTip.text: qsTr("Use this to enable or disable steering.") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.trixter_xdream_v1_bike_steering_enabled - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.trixter_xdream_v1_bike_steering_enabled = checked - } - RowLayout { - spacing: 10 - Label { - id: labelTrixterXDreamV1BikeSteeringCenterOffset - text: qsTr("Steering Center Offset (%)") - Layout.fillWidth: true - } - TextField { - id: trixterXDreamV1BikeSteeringCenterOffsetTextField - text: settings.trixter_xdream_v1_bike_steering_center_offset - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: qsTr("Use this setting to adjust the steering angle offset percentage for the resting position of the handle bars. Use +/- % values to adjust left and right.") - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - // this should be in sync with trixterxdreamv1bikesettings::MinSteeringCenterOffsetPercentage and MaxSteeringCenterOffsetPercentage - validator: IntValidator {bottom: -30; top: 30;} - onAccepted: settings.trixter_xdream_v1_bike_steering_center_offset = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: oktrixterXDreamV1BikeSteeringCenterButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trixter_xdream_v1_bike_steering_center_offset = trixterXDreamV1BikeSteeringCenterOffsetTextField.text - } - } - RowLayout { - spacing: 10 - Label { - id: labelTrixterXDreamV1BikeSteeringDeadZoneWidth - text: qsTr("Steering Dead Zone Width (%)") - Layout.fillWidth: true - } - TextField { - id: trixterXDreamV1BikeSteeringDeadZoneWidthTextField - text: settings.trixter_xdream_v1_bike_steering_deadzone_width - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: qsTr("The percentage of the total range where the steering value will be mapped to 0 degrees.") - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - // this should be in sync with trixterxdreamv1bikesettings::MinSteeringDeadZonePercentage and MaxSteeringDeadZonePercentage - validator: IntValidator {bottom: 0; top: 20;} - onAccepted: settings.trixter_xdream_v1_bike_steering_deadzone_width = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: oktrixterXDreamV1BikeSteeringDeadZoneWidthButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trixter_xdream_v1_bike_steering_deadzone_width = trixterXDreamV1BikeSteeringDeadZoneWidthTextField.text - } - } - RowLayout { - spacing: 10 - Label { - id: labelTrixterXDreamV1BikeSteeringSensitivityLeft - text: qsTr("Steering Sensitivity Left (%)") - Layout.fillWidth: true - } - TextField { - id: trixterXDreamV1BikeSteeringSensitivityLeftTextField - text: settings.trixter_xdream_v1_bike_steering_sensitivity_left - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: qsTr("Use this setting to adjust the sensitivity of the steering when turning left.") - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - // this should be in sync with trixterxdreamv1bikesettings::MinSteeringSensitivity and MaxSteeringSensitivity - validator: IntValidator {bottom: 20; top: 200;} - onAccepted: settings.trixter_xdream_v1_bike_steering_sensitivity_left = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: oktrixterXDreamV1BikeSteeringSensitivityLeftButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trixter_xdream_v1_bike_steering_sensitivity_left = trixterXDreamV1BikeSteeringSensitivityLeftTextField.text - } + ToolTip.text: qsTr("Rightmost unadjusted steering angle to be mapped to 0 degrees.") + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + from: trixterXDreamV1BikeSteeringAngleCenterLeftSpinBox.value + to: trixterXDreamV1BikeSteeringAngleRightSpinBox.value + onValueChanged: settings.trixter_xdream_v1_bike_steering_CR = value } - RowLayout { - spacing: 10 - Label { - id: labelTrixterXDreamV1BikeSteeringSensitivityRight - text: qsTr("Steering Sensitivity Right (%)") - Layout.fillWidth: true - } - TextField { - id: trixterXDreamV1BikeSteeringSensitivityRightTextField - text: settings.trixter_xdream_v1_bike_steering_sensitivity_right - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: qsTr("Use this setting to adjust the sensitivity of the steering when turning right.") - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - // this should be in sync with trixterxdreamv1bikesettings::MinSteeringSensitivity and MaxSteeringSensitivity - validator: IntValidator {bottom: 20; top: 200;} - onAccepted: settings.trixter_xdream_v1_bike_steering_sensitivity_left = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: oktrixterXDreamV1BikeSteeringSensitivityRightButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trixter_xdream_v1_bike_steering_sensitivity_right = trixterXDreamV1BikeSteeringSensitivityRightTextField.text - } + SpinBox { + id: trixterXDreamV1BikeSteeringAngleRightSpinBox + value: settings.trixter_xdream_v1_bike_steering_R + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("Unadjusted steering angle that is 100% right.") + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + from: trixterXDreamV1BikeSteeringAngleCenterRightSpinBox.value + to: 45 + onValueChanged: settings.trixter_xdream_v1_bike_steering_R = value } - - } - AccordionElement { - id: flywheelBikeAccordion - title: qsTr("Flywheel Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { - spacing: 10 - Label { - id: labelflywheelBikeFilter - text: qsTr("Samples Filter:") - Layout.fillWidth: true - } - TextField { - id: flywheelBikeFilterTextField - text: settings.flywheel_filter - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.flywheel_filter = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okflywheelBikeFilterButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.flywheel_filter = flywheelBikeFilterTextField.text - } - } - SwitchDelegate { - id: lifeFitnessIC8Delegate - text: qsTr("Life Fitness IC8") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.flywheel_life_fitness_ic8 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.flywheel_life_fitness_ic8 = checked + Button { + id: resetTrixterXDreamV1BikeSteeringAnglesReset + text: "RESET" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: { + settings.trixter_xdream_v1_bike_steering_L = -settings.trixter_xdream_v1_bike_steering_MAX + settings.trixter_xdream_v1_bike_steering_CL = -2 + settings.trixter_xdream_v1_bike_steering_CR = 2 + settings.trixter_xdream_v1_bike_steering_R = settings.trixter_xdream_v1_bike_steering_MAX + trixterXDreamV1Calibration.update() } } } - AccordionElement { - id: domyosBikeAccordion - title: qsTr("Domyos Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: RowLayout { + } + AccordionElement { + id: flywheelBikeAccordion + title: qsTr("Flywheel Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + RowLayout { spacing: 10 Label { - id: labelDomyosBikeCadenceFilter - text: qsTr("Cadence Filter:") + id: labelflywheelBikeFilter + text: qsTr("Samples Filter:") Layout.fillWidth: true } TextField { - id: domyosBikeCadenceFilterTextField - text: settings.domyos_bike_cadence_filter + id: flywheelBikeFilterTextField + text: settings.flywheel_filter horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.domyos_bike_cadence_filter = text + onAccepted: settings.flywheel_filter = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okDomyosBikeCadenceFilter + id: okflywheelBikeFilterButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.domyos_bike_cadence_filter = domyosBikeCadenceFilterTextField.text + onClicked: settings.flywheel_filter = flywheelBikeFilterTextField.text } } SwitchDelegate { - id: domyosBikeCaloriesDisplayDelegate - text: qsTr("Fix Calories/Km to Console") + id: lifeFitnessIC8Delegate + text: qsTr("Life Fitness IC8") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.domyos_bike_display_calories + checked: settings.flywheel_life_fitness_ic8 Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.domyos_bike_display_calories = checked + onClicked: settings.flywheel_life_fitness_ic8 = checked } } - AccordionElement { - id: proformBikeAccordion - title: qsTr("Proform Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelproformBikeWheelRatio - text: qsTr("Wheel Ratio:") - Layout.fillWidth: true - } - TextField { - id: proformBikeWheelRatioTextField - text: settings.proform_wheel_ratio - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.proform_wheel_ratio = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okproformBikeWheelRatioButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.proform_wheel_ratio = proformBikeWheelRatioTextField.text - } - } - SwitchDelegate { - id: tourDeFranceCLCdelegate - text: qsTr("Tour de France CLC") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.proform_tour_de_france_clc - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + } + AccordionElement { + id: domyosBikeAccordion + title: qsTr("Domyos Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelDomyosBikeCadenceFilter + text: qsTr("Cadence Filter:") Layout.fillWidth: true - onClicked: settings.proform_tour_de_france_clc = checked } - SwitchDelegate { - id: proformStudiodelegate - text: qsTr("Proform Studio Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.proform_studio - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + TextField { + id: domyosBikeCadenceFilterTextField + text: settings.domyos_bike_cadence_filter + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.domyos_bike_cadence_filter = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okDomyosBikeCadenceFilter + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.domyos_bike_cadence_filter = domyosBikeCadenceFilterTextField.text + } + } + SwitchDelegate { + id: domyosBikeCaloriesDisplayDelegate + text: qsTr("Fix Calories/Km to Console") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.domyos_bike_display_calories + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.domyos_bike_display_calories = checked + } + } + AccordionElement { + id: proformBikeAccordion + title: qsTr("Proform Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelproformBikeWheelRatio + text: qsTr("Wheel Ratio:") Layout.fillWidth: true - onClicked: settings.proform_studio = checked } - SwitchDelegate { - id: proformTDF10odelegate - text: qsTr("Proform TDF 1.0") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.proform_tdf_10 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + TextField { + id: proformBikeWheelRatioTextField + text: settings.proform_wheel_ratio + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.proform_wheel_ratio = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okproformBikeWheelRatioButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.proform_wheel_ratio = proformBikeWheelRatioTextField.text + } + } + SwitchDelegate { + id: tourDeFranceCLCdelegate + text: qsTr("Tour de France CLC") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.proform_tour_de_france_clc + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.proform_tour_de_france_clc = checked + } + SwitchDelegate { + id: proformStudiodelegate + text: qsTr("Proform Studio Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.proform_studio + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.proform_studio = checked + } + SwitchDelegate { + id: proformTDF10odelegate + text: qsTr("Proform TDF 1.0") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.proform_tdf_10 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.proform_tdf_10 = checked + } + SwitchDelegate { + id: proformTdfJonseedWattdelegate + text: qsTr("TDF CBC Jonseed Watt table") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.proform_tdf_jonseed_watt + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.proform_tdf_jonseed_watt = checked + } + RowLayout { + spacing: 10 + Label { + id: labelproformTDF4IP + text: qsTr("TDF4 IP:") Layout.fillWidth: true - onClicked: settings.proform_tdf_10 = checked } + TextField { + id: proformTDF4IPTextField + text: settings.proformtdf4ip + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.proformtdf4ip = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okproformTDF4IPButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.proformtdf4ip = proformTDF4IPTextField.text + } + } + } + + AccordionElement { + id: m3iBikeAccordion + title: qsTr("M3i Bike Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 SwitchDelegate { - id: proformTdfJonseedWattdelegate - text: qsTr("TDF CBC Jonseed Watt table") + id: m3iBikeQtSearchDelegate + text: qsTr("Use QT search on Android / iOS") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.proform_tdf_jonseed_watt + checked: settings.m3i_bike_qt_search Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.proform_tdf_jonseed_watt = checked + onClicked: settings.m3i_bike_qt_search = checked } + RowLayout { spacing: 10 Label { - id: labelproformTDF4IP - text: qsTr("TDF4 IP:") + id: labelm3iBikeId + text: qsTr("Bike ID:") Layout.fillWidth: true } TextField { - id: proformTDF4IPTextField - text: settings.proformtdf4ip + id: m3iBikeIdTextField + text: settings.m3i_bike_id horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.proformtdf4ip = text + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.m3i_bike_id = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okproformTDF4IPButton + id: okm3iBikeIdButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.proformtdf4ip = proformTDF4IPTextField.text + onClicked: settings.m3i_bike_id = m3iBikeIdTextField.text } } - } - AccordionElement { - id: m3iBikeAccordion - title: qsTr("M3i Bike Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: m3iBikeQtSearchDelegate - text: qsTr("Use QT search on Android / iOS") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.m3i_bike_qt_search - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelm3iBikeSpeedBuffsize + text: qsTr("Speed Buffer Size:") Layout.fillWidth: true - onClicked: settings.m3i_bike_qt_search = checked - } - - RowLayout { - spacing: 10 - Label { - id: labelm3iBikeId - text: qsTr("Bike ID:") - Layout.fillWidth: true - } - TextField { - id: m3iBikeIdTextField - text: settings.m3i_bike_id - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.m3i_bike_id = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okm3iBikeIdButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.m3i_bike_id = m3iBikeIdTextField.text - } } - - RowLayout { - spacing: 10 - Label { - id: labelm3iBikeSpeedBuffsize - text: qsTr("Speed Buffer Size:") - Layout.fillWidth: true - } - TextField { - id: m3iBikeSpeedBuffsizeTextField - text: settings.m3i_bike_speed_buffsize - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.m3i_bike_speed_buffsize = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okm3iBikeSpeedBuffsizeButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.m3i_bike_speed_buffsize = m3iBikeSpeedBuffsizeTextField.text - } + TextField { + id: m3iBikeSpeedBuffsizeTextField + text: settings.m3i_bike_speed_buffsize + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.m3i_bike_speed_buffsize = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - - SwitchDelegate { - id: m3iBikeKcalDelegate - text: qsTr("Use KCal from the Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.m3i_bike_kcal - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.m3i_bike_kcal = checked + Button { + id: okm3iBikeSpeedBuffsizeButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.m3i_bike_speed_buffsize = m3iBikeSpeedBuffsizeTextField.text } } - } - } - - AccordionElement { - id: uiAntOptionsAccordion - title: qsTr("Ant+ Options (only for some Android)") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: antCadenceDelegate - text: qsTr("Ant+ Cadence") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.ant_cadence - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.ant_cadence = checked - } SwitchDelegate { - id: antHeartDelegate - text: qsTr("Ant+ Heart") + id: m3iBikeKcalDelegate + text: qsTr("Use KCal from the Bike") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.ant_heart + checked: settings.m3i_bike_kcal Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.ant_heart = checked + onClicked: settings.m3i_bike_kcal = checked } } } -/* - SwitchDelegate { - id: antGarminDelegate - text: qsTr("Ant+ Garmin Compatibility") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.ant_garmin - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.ant_garmin = checked - }*/ + } - AccordionElement { - id: tileOptionsAccordion - title: qsTr("Tiles Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { + AccordionElement { + id: uiAntOptionsAccordion + title: qsTr("Ant+ Options (only for some Android)") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: antCadenceDelegate + text: qsTr("Ant+ Cadence") spacing: 0 - AccordionCheckElement { - id: speedEnabledAccordion - title: qsTr("Speed") - linkedBoolSetting: "tile_speed_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelSpeedOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: speedOrderTextField - model: rootItem.tile_order - displayText: settings.tile_speed_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = speedOrderTextField.currentValue - } - } - Button { - id: okSpeedOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_speed_order = speedOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: inclinationEnabledAccordion - title: qsTr("Inclination") - linkedBoolSetting: "tile_inclination_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelinclinationOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: inclinationOrderTextField - model: rootItem.tile_order - displayText: settings.tile_inclination_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = inclinationOrderTextField.currentValue - } - } - Button { - id: okinclinationOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_inclination_order = inclinationOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: cadenceEnabledAccordion - title: qsTr("Cadence") - linkedBoolSetting: "tile_cadence_enabled" - settings: settings - accordionContent: ColumnLayout { - SwitchDelegate { - id: cadenceColorEnabled - text: qsTr("Enable Cadence color") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.tile_cadence_color_enabled - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.tile_cadence_color_enabled = checked - } - RowLayout { - spacing: 10 - Label { - id: labelcadenceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: cadenceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_cadence_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = cadenceOrderTextField.currentValue - } - } - Button { - id: okcadenceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_cadence_order = cadenceOrderTextField.displayText - } - } - } - } - - AccordionCheckElement { - id: elevationEnabledAccordion - title: qsTr("Elevation") - linkedBoolSetting: "tile_elevation_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelelevationOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: elevationOrderTextField - model: rootItem.tile_order - displayText: settings.tile_elevation_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = elevationOrderTextField.currentValue - } - } - Button { - id: okelevationOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_elevation_order = elevationOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: caloriesEnabledAccordion - title: qsTr("Calories") - linkedBoolSetting: "tile_calories_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelcaloriesOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: caloriesOrderTextField - model: rootItem.tile_order - displayText: settings.tile_calories_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = caloriesOrderTextField.currentValue - } - } - Button { - id: okcaloriesOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_calories_order = caloriesOrderTextField.displayText - } - } - } + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.ant_cadence + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.ant_cadence = checked + } - AccordionCheckElement { - id: odometerEnabledAccordion - title: qsTr("Odometer") - linkedBoolSetting: "tile_odometer_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelodometerOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: odometerOrderTextField - model: rootItem.tile_order - displayText: settings.tile_odometer_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = odometerOrderTextField.currentValue - } - } - Button { - id: okodometerOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_odometer_order = odometerOrderTextField.displayText - } - } - } + SwitchDelegate { + id: antHeartDelegate + text: qsTr("Ant+ Heart") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.ant_heart + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.ant_heart = checked + } + } + } + /* + SwitchDelegate { + id: antGarminDelegate + text: qsTr("Ant+ Garmin Compatibility") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.ant_garmin + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.ant_garmin = checked + }*/ - AccordionCheckElement { - id: paceEnabledAccordion - title: qsTr("Pace") - linkedBoolSetting: "tile_pace_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelpaceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: paceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_pace_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = paceOrderTextField.currentValue - } - } - Button { - id: okpaceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_pace_order = paceOrderTextField.displayText - } + AccordionElement { + id: tileOptionsAccordion + title: qsTr("Tiles Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 + AccordionCheckElement { + id: speedEnabledAccordion + title: qsTr("Speed") + linkedBoolSetting: "tile_speed_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelSpeedOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight } - } - - AccordionCheckElement { - id: resistanceEnabledAccordion - title: qsTr("Resistance") - linkedBoolSetting: "tile_resistance_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelresistanceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: resistanceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_resistance_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = resistanceOrderTextField.currentValue - } - } - Button { - id: okresistanceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_resistance_order = resistanceOrderTextField.displayText + ComboBox { + id: speedOrderTextField + model: rootItem.tile_order + displayText: settings.tile_speed_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = speedOrderTextField.currentValue } } - } - - AccordionCheckElement { - id: wattEnabledAccordion - title: qsTr("Watt") - linkedBoolSetting: "tile_watt_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelwattOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: wattOrderTextField - model: rootItem.tile_order - displayText: settings.tile_watt_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = wattOrderTextField.currentValue - } - } - Button { - id: okwattOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_watt_order = wattOrderTextField.displayText - } + Button { + id: okSpeedOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_speed_order = speedOrderTextField.displayText } } + } - AccordionCheckElement { - id: weightLossEnabledAccordion - title: qsTr("Weight loss") - linkedBoolSetting: "tile_weight_loss_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelweightLossOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: weightLossOrderTextField - model: rootItem.tile_order - displayText: settings.tile_weight_loss_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = weightLossOrderTextField.currentValue - } - } - Button { - id: okweightLossOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_weight_loss_order = weightLossOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: avgwattEnabledAccordion - title: qsTr("AVG Watt") - linkedBoolSetting: "tile_avgwatt_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelavgwattOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: avgwattOrderTextField - model: rootItem.tile_order - displayText: settings.tile_avgwatt_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = avgwattOrderTextField.currentValue - } - } - Button { - id: okavgwattOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_avgwatt_order = avgwattOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: ftpEnabledAccordion - title: qsTr("FTP %") - linkedBoolSetting: "tile_ftp_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelftpOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: ftpOrderTextField - model: rootItem.tile_order - displayText: settings.tile_ftp_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = ftpOrderTextField.currentValue - } - } - Button { - id: okftpOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_ftp_order = ftpOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: heartEnabledAccordion - title: qsTr("Heart") - linkedBoolSetting: "tile_heart_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelheartrateOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: heartrateOrderTextField - model: rootItem.tile_order - displayText: settings.tile_heart_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = heartrateOrderTextField.currentValue - } - } - Button { - id: okheartrateOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_heart_order = heartrateOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: fanEnabledAccordion - title: qsTr("Fan") - linkedBoolSetting: "tile_fan_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelfanOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: fanOrderTextField - model: rootItem.tile_order - displayText: settings.tile_fan_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = fanOrderTextField.currentValue - } - } - Button { - id: okfanOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_fan_order = fanOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: joulsEnabledAccordion - title: qsTr("Jouls") - linkedBoolSetting: "tile_jouls_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeljoulsOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: joulsOrderTextField - model: rootItem.tile_order - displayText: settings.tile_jouls_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = joulsOrderTextField.currentValue - } - } - Button { - id: okjoulsOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_jouls_order = joulsOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: elapsedEnabledAccordion - title: qsTr("Elapsed") - linkedBoolSetting: "tile_elapsed_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelelapsedOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: elapsedOrderTextField - model: rootItem.tile_order - displayText: settings.tile_elapsed_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = elapsedOrderTextField.currentValue - } - } - Button { - id: okelapsedOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_elapsed_order = elapsedOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: movingTimeEnabledAccordion - title: qsTr("Moving Time") - linkedBoolSetting: "tile_moving_time_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelmovingTimeOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: movingTimeOrderTextField - model: rootItem.tile_order - displayText: settings.tile_moving_time_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = movingTimeOrderTextField.currentValue - } - } - Button { - id: okmovingTimeOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_moving_time_order = movingTimeOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: pelotonOffsetEnabledAccordion - title: qsTr("Peloton Offset") - linkedBoolSetting: "tile_peloton_offset_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelpelotonOffsetOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: pelotonOffsetOrderTextField - model: rootItem.tile_order - displayText: settings.tile_peloton_offset_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = pelotonOffsetOrderTextField.currentValue - } - } - Button { - id: okpelotonOffsetOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_peloton_offset_order = pelotonOffsetOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: pelotonRemainingEnabledAccordion - title: qsTr("Peloton Remaining") - linkedBoolSetting: "tile_peloton_remaining_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelPelotonRemainingOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: pelotonRemainingOrderTextField - model: rootItem.tile_order - displayText: settings.tile_peloton_remaining_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = pelotonRemainingOrderTextField.currentValue - } - } - Button { - id: okPelotonRemainingOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_peloton_remaining_order = pelotonRemainingOrderTextField.displayText - } - } - } - - /* - AccordionCheckElement { - id: pelotonDifficultyEnabledAccordion - title: qsTr("Peloton Difficulty") - linkedBoolSetting: "tile_peloton_difficulty_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelpelotonDifficultyOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: pelotonDifficultyOrderTextField - model: rootItem.tile_order - displayText: settings.tile_peloton_difficulty_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = pelotonDifficultyOrderTextField.currentValue - } - } - Button { - id: okpelotonDifficultyOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_peloton_difficulty_order = pelotonDifficultyOrderTextField.displayText - } - } - }*/ - - AccordionCheckElement { - id: lapElapsedEnabledAccordion - title: qsTr("Lap Elapsed") - linkedBoolSetting: "tile_lapelapsed_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labellapElapsedOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: lapElapsedOrderTextField - model: rootItem.tile_order - displayText: settings.tile_lapelapsed_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = lapElapsedOrderTextField.currentValue - } - } - Button { - id: oklapElapsedOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_lapelapsed_order = lapElapsedOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: pelotonResistanceEnabledAccordion - title: qsTr("Peloton Resistance") - linkedBoolSetting: "tile_peloton_resistance_enabled" - settings: settings - accordionContent: ColumnLayout { - SwitchDelegate { - id: pelotonResistanceColorEnabled - text: qsTr("Enable Peloton Resistance color") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.tile_peloton_resistance_color_enabled - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.tile_peloton_resistance_color_enabled = checked - } - RowLayout { - spacing: 10 - Label { - id: labelpeloton_resistanceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: peloton_resistanceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_peloton_resistance_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = peloton_resistanceOrderTextField.currentValue - } - } - Button { - id: okpeloton_resistanceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_peloton_resistance_order = peloton_resistanceOrderTextField.displayText - } - } - } - } - - AccordionCheckElement { - id: targetResistanceEnabledAccordion - title: qsTr("Target Resistance") - linkedBoolSetting: "tile_target_resistance_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_resistanceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_resistanceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_resistance_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_resistanceOrderTextField.currentValue - } - } - Button { - id: oktarget_resistanceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_resistance_order = target_resistanceOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: targetPelotonResistanceEnabledAccordion - title: qsTr("Target Peloton Resistance") - linkedBoolSetting: "tile_target_peloton_resistance_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_peloton_resistanceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_peloton_resistanceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_peloton_resistance_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_peloton_resistanceOrderTextField.currentValue - } - } - Button { - id: oktarget_peloton_resistanceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_peloton_resistance_order = target_peloton_resistanceOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: targetCadenceEnabledAccordion - title: qsTr("Target Cadence") - linkedBoolSetting: "tile_target_cadence_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_cadenceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_cadenceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_cadence_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_cadenceOrderTextField.currentValue - } - } - Button { - id: oktarget_cadenceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_cadence_order = target_cadenceOrderTextField.displayText - } - } - } - AccordionCheckElement { - id: targetPowerEnabledAccordion - title: qsTr("Target Power") - linkedBoolSetting: "tile_target_power_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_powerOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_powerOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_power_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_powerOrderTextField.currentValue - } - } - Button { - id: oktarget_powerOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_power_order = target_powerOrderTextField.displayText + AccordionCheckElement { + id: inclinationEnabledAccordion + title: qsTr("Inclination") + linkedBoolSetting: "tile_inclination_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelinclinationOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: inclinationOrderTextField + model: rootItem.tile_order + displayText: settings.tile_inclination_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = inclinationOrderTextField.currentValue } } + Button { + id: okinclinationOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_inclination_order = inclinationOrderTextField.displayText + } } - AccordionCheckElement { - id: targetZoneEnabledAccordion - title: qsTr("Target Power Zone") - linkedBoolSetting: "tile_target_zone_enabled" - settings: settings - accordionContent: RowLayout { + } + + AccordionCheckElement { + id: cadenceEnabledAccordion + title: qsTr("Cadence") + linkedBoolSetting: "tile_cadence_enabled" + settings: settings + accordionContent: ColumnLayout { + SwitchDelegate { + id: cadenceColorEnabled + text: qsTr("Enable Cadence color") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.tile_cadence_color_enabled + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.tile_cadence_color_enabled = checked + } + RowLayout { spacing: 10 Label { - id: labeltarget_zoneOrder + id: labelcadenceOrder text: qsTr("order index:") Layout.fillWidth: true horizontalAlignment: Text.AlignRight } ComboBox { - id: target_zoneOrderTextField + id: cadenceOrderTextField model: rootItem.tile_order - displayText: settings.tile_target_zone_order + displayText: settings.tile_cadence_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter onActivated: { - displayText = target_zoneOrderTextField.currentValue - } + displayText = cadenceOrderTextField.currentValue + } } Button { - id: oktarget_zoneOrderButton + id: okcadenceOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_zone_order = target_zoneOrderTextField.displayText + onClicked: settings.tile_cadence_order = cadenceOrderTextField.displayText } } } - AccordionCheckElement { - id: targetSpeedEnabledAccordion - title: qsTr("Target Speed") - linkedBoolSetting: "tile_target_speed_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltargetspeedOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_speedOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_speed_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_speedOrderTextField.currentValue - } - } - Button { - id: oktarget_speedOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_speed_order = target_speedOrderTextField.displayText + } + + AccordionCheckElement { + id: elevationEnabledAccordion + title: qsTr("Elevation") + linkedBoolSetting: "tile_elevation_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelelevationOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: elevationOrderTextField + model: rootItem.tile_order + displayText: settings.tile_elevation_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = elevationOrderTextField.currentValue } } + Button { + id: okelevationOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_elevation_order = elevationOrderTextField.displayText + } } - AccordionCheckElement { - id: targetInclineEnabledAccordion - title: qsTr("Target Incline") - linkedBoolSetting: "tile_target_incline_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_inclineOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_inclineOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_incline_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_inclineOrderTextField.currentValue - } + } + + AccordionCheckElement { + id: caloriesEnabledAccordion + title: qsTr("Calories") + linkedBoolSetting: "tile_calories_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelcaloriesOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: caloriesOrderTextField + model: rootItem.tile_order + displayText: settings.tile_calories_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = caloriesOrderTextField.currentValue } - Button { - id: oktarget_inclineOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_incline_order = target_inclineOrderTextField.displayText + } + Button { + id: okcaloriesOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_calories_order = caloriesOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: odometerEnabledAccordion + title: qsTr("Odometer") + linkedBoolSetting: "tile_odometer_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelodometerOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: odometerOrderTextField + model: rootItem.tile_order + displayText: settings.tile_odometer_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = odometerOrderTextField.currentValue } } + Button { + id: okodometerOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_odometer_order = odometerOrderTextField.displayText + } } - AccordionCheckElement { - id: wattKgEnabledAccordion - title: qsTr("Watt/Kg") - linkedBoolSetting: "tile_watt_kg_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelwatt_kgOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight + } + + AccordionCheckElement { + id: paceEnabledAccordion + title: qsTr("Pace") + linkedBoolSetting: "tile_pace_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelpaceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: paceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_pace_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = paceOrderTextField.currentValue } - ComboBox { - id: watt_kgOrderTextField - model: rootItem.tile_order - displayText: settings.tile_watt_kg_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = watt_kgOrderTextField.currentValue - } + } + Button { + id: okpaceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_pace_order = paceOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: resistanceEnabledAccordion + title: qsTr("Resistance") + linkedBoolSetting: "tile_resistance_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelresistanceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: resistanceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_resistance_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = resistanceOrderTextField.currentValue } - Button { - id: okwatt_kgOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_watt_kg_order = watt_kgOrderTextField.displayText + } + Button { + id: okresistanceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_resistance_order = resistanceOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: wattEnabledAccordion + title: qsTr("Watt") + linkedBoolSetting: "tile_watt_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelwattOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: wattOrderTextField + model: rootItem.tile_order + displayText: settings.tile_watt_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = wattOrderTextField.currentValue } } + Button { + id: okwattOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_watt_order = wattOrderTextField.displayText + } } + } - AccordionCheckElement { - id: gearsEnabledAccordion - title: qsTr("Gears") - linkedBoolSetting: "tile_gears_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelgearsOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight + AccordionCheckElement { + id: weightLossEnabledAccordion + title: qsTr("Weight loss") + linkedBoolSetting: "tile_weight_loss_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelweightLossOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: weightLossOrderTextField + model: rootItem.tile_order + displayText: settings.tile_weight_loss_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = weightLossOrderTextField.currentValue } - ComboBox { - id: gearsOrderTextField - model: rootItem.tile_order - displayText: settings.tile_gears_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = gearsOrderTextField.currentValue - } + } + Button { + id: okweightLossOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_weight_loss_order = weightLossOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: avgwattEnabledAccordion + title: qsTr("AVG Watt") + linkedBoolSetting: "tile_avgwatt_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelavgwattOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: avgwattOrderTextField + model: rootItem.tile_order + displayText: settings.tile_avgwatt_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = avgwattOrderTextField.currentValue } - Button { - id: okgearsOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_gears_order = gearsOrderTextField.displayText + } + Button { + id: okavgwattOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_avgwatt_order = avgwattOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: ftpEnabledAccordion + title: qsTr("FTP %") + linkedBoolSetting: "tile_ftp_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelftpOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: ftpOrderTextField + model: rootItem.tile_order + displayText: settings.tile_ftp_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = ftpOrderTextField.currentValue } } + Button { + id: okftpOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_ftp_order = ftpOrderTextField.displayText + } } + } - AccordionCheckElement { - id: remainingTimeTrainingProgramRowEnabledAccordion - title: qsTr("Remaining Time/Row") - linkedBoolSetting: "tile_remainingtimetrainprogramrow_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelremainingTimeTrainingProgramRowOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: remainingTimeTrainingProgramRowOrderTextField - model: rootItem.tile_order - displayText: settings.tile_remainingtimetrainprogramrow_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = remainingTimeTrainingProgramRowOrderTextField.currentValue - } - } - Button { - id: okremainingTimeTrainingProgramRowOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_remainingtimetrainprogramrow_order = remainingTimeTrainingProgramRowOrderTextField.displayText + AccordionCheckElement { + id: heartEnabledAccordion + title: qsTr("Heart") + linkedBoolSetting: "tile_heart_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelheartrateOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: heartrateOrderTextField + model: rootItem.tile_order + displayText: settings.tile_heart_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = heartrateOrderTextField.currentValue } } + Button { + id: okheartrateOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_heart_order = heartrateOrderTextField.displayText + } } + } - AccordionCheckElement { - id: nextRowsTrainingProgramRowEnabledAccordion - title: qsTr("Next Rows") - linkedBoolSetting: "tile_nextrowstrainprogram_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelnextRowsTrainingProgramOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: nextRowsTrainingProgramOrderTextField - model: rootItem.tile_order - displayText: settings.tile_nextrowstrainprogram_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = nextRowsTrainingProgramOrderTextField.currentValue - } - } - Button { - id: oknextRowsTrainingProgramOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_nextrowstrainprogram_order = nextRowsTrainingProgramOrderTextField.displayText + AccordionCheckElement { + id: fanEnabledAccordion + title: qsTr("Fan") + linkedBoolSetting: "tile_fan_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelfanOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: fanOrderTextField + model: rootItem.tile_order + displayText: settings.tile_fan_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = fanOrderTextField.currentValue } } + Button { + id: okfanOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_fan_order = fanOrderTextField.displayText + } } + } - AccordionCheckElement { - id: metsEnabledAccordion - title: qsTr("METS") - linkedBoolSetting: "tile_mets_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelmetsOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: metsOrderTextField - model: rootItem.tile_order - displayText: settings.tile_mets_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = metsOrderTextField.currentValue - } - } - Button { - id: okmetsOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_mets_order = metsOrderTextField.displayText + AccordionCheckElement { + id: joulsEnabledAccordion + title: qsTr("Jouls") + linkedBoolSetting: "tile_jouls_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeljoulsOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: joulsOrderTextField + model: rootItem.tile_order + displayText: settings.tile_jouls_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = joulsOrderTextField.currentValue } } + Button { + id: okjoulsOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_jouls_order = joulsOrderTextField.displayText + } } + } - AccordionCheckElement { - id: targetMetsEnabledAccordion - title: qsTr("Target METS") - linkedBoolSetting: "tile_targetmets_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltargetmetsOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: targetmetsOrderTextField - model: rootItem.tile_order - displayText: settings.tile_targetmets_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = targetmetsOrderTextField.currentValue - } - } - Button { - id: oktargetmetsOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_targetmets_order = targetmetsOrderTextField.displayText + AccordionCheckElement { + id: elapsedEnabledAccordion + title: qsTr("Elapsed") + linkedBoolSetting: "tile_elapsed_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelelapsedOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: elapsedOrderTextField + model: rootItem.tile_order + displayText: settings.tile_elapsed_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = elapsedOrderTextField.currentValue } } + Button { + id: okelapsedOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_elapsed_order = elapsedOrderTextField.displayText + } } + } - AccordionCheckElement { - id: datetimeEnabledAccordion - title: qsTr("Time") - linkedBoolSetting: "tile_datetime_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeldatetimeOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: datetimeOrderTextField - model: rootItem.tile_order - displayText: settings.tile_datetime_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = datetimeOrderTextField.currentValue - } - } - Button { - id: okdatetimeOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_datetime_order = datetimeOrderTextField.displayText + AccordionCheckElement { + id: movingTimeEnabledAccordion + title: qsTr("Moving Time") + linkedBoolSetting: "tile_moving_time_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelmovingTimeOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: movingTimeOrderTextField + model: rootItem.tile_order + displayText: settings.tile_moving_time_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = movingTimeOrderTextField.currentValue } } + Button { + id: okmovingTimeOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_moving_time_order = movingTimeOrderTextField.displayText + } } - AccordionCheckElement { - id: targetStrokesCountAccordion - title: qsTr("Strokes Count") - linkedBoolSetting: "tile_strokes_count_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelstrokes_countOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: strokes_countOrderTextField - model: rootItem.tile_order - displayText: settings.tile_strokes_count_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = strokes_countOrderTextField.currentValue - } - } - Button { - id: okstrokes_countOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_strokes_count_order = strokes_countOrderTextField.displayText + } + + AccordionCheckElement { + id: pelotonOffsetEnabledAccordion + title: qsTr("Peloton Offset") + linkedBoolSetting: "tile_peloton_offset_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelpelotonOffsetOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: pelotonOffsetOrderTextField + model: rootItem.tile_order + displayText: settings.tile_peloton_offset_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = pelotonOffsetOrderTextField.currentValue } } + Button { + id: okpelotonOffsetOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_peloton_offset_order = pelotonOffsetOrderTextField.displayText + } } - AccordionCheckElement { - id: targetStrokesLengthAccordion - title: qsTr("Strokes Length") - linkedBoolSetting: "tile_strokes_length_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelstrokes_lengthOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: strokes_lengthOrderTextField - model: rootItem.tile_order - displayText: settings.tile_strokes_length_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = strokes_lengthOrderTextField.currentValue - } - } - Button { - id: okstrokes_lengthOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_strokes_length_order = strokes_lengthOrderTextField.displayText + } + + AccordionCheckElement { + id: pelotonRemainingEnabledAccordion + title: qsTr("Peloton Remaining") + linkedBoolSetting: "tile_peloton_remaining_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelPelotonRemainingOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: pelotonRemainingOrderTextField + model: rootItem.tile_order + displayText: settings.tile_peloton_remaining_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = pelotonRemainingOrderTextField.currentValue } } + Button { + id: okPelotonRemainingOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_peloton_remaining_order = pelotonRemainingOrderTextField.displayText + } } + } + /* AccordionCheckElement { - id: targetSteeringAngleEnabledAccordion - title: qsTr("Steering Angle") - linkedBoolSetting: "tile_steering_angle_enabled" + id: pelotonDifficultyEnabledAccordion + title: qsTr("Peloton Difficulty") + linkedBoolSetting: "tile_peloton_difficulty_enabled" settings: settings accordionContent: RowLayout { spacing: 10 Label { - id: labelsteeringAngleOrder + id: labelpelotonDifficultyOrder text: qsTr("order index:") Layout.fillWidth: true horizontalAlignment: Text.AlignRight } ComboBox { - id: steeringAngleOrderTextField + id: pelotonDifficultyOrderTextField model: rootItem.tile_order - displayText: settings.tile_steering_angle_order + displayText: settings.tile_peloton_difficulty_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter onActivated: { - displayText = steeringAngleOrderTextField.currentValue + displayText = pelotonDifficultyOrderTextField.currentValue } } Button { - id: oksteeringAngleOrderButton + id: okpelotonDifficultyOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_steering_angle_order = steeringAngleOrderTextField.displayText + onClicked: settings.tile_peloton_difficulty_order = pelotonDifficultyOrderTextField.displayText + } + } + }*/ + + AccordionCheckElement { + id: lapElapsedEnabledAccordion + title: qsTr("Lap Elapsed") + linkedBoolSetting: "tile_lapelapsed_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labellapElapsedOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: lapElapsedOrderTextField + model: rootItem.tile_order + displayText: settings.tile_lapelapsed_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = lapElapsedOrderTextField.currentValue } } + Button { + id: oklapElapsedOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_lapelapsed_order = lapElapsedOrderTextField.displayText + } } + } - AccordionCheckElement { - id: targetPIDHrAccordion - title: qsTr("PID HR Zone") - linkedBoolSetting: "tile_pid_hr_enabled" - settings: settings - accordionContent: RowLayout { + AccordionCheckElement { + id: pelotonResistanceEnabledAccordion + title: qsTr("Peloton Resistance") + linkedBoolSetting: "tile_peloton_resistance_enabled" + settings: settings + accordionContent: ColumnLayout { + SwitchDelegate { + id: pelotonResistanceColorEnabled + text: qsTr("Enable Peloton Resistance color") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.tile_peloton_resistance_color_enabled + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.tile_peloton_resistance_color_enabled = checked + } + RowLayout { spacing: 10 Label { - id: labelPIDHROrder + id: labelpeloton_resistanceOrder text: qsTr("order index:") Layout.fillWidth: true horizontalAlignment: Text.AlignRight } ComboBox { - id: pidHROrderTextField + id: peloton_resistanceOrderTextField model: rootItem.tile_order - displayText: settings.tile_pid_hr_order + displayText: settings.tile_peloton_resistance_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter onActivated: { - displayText = pidHROrderTextField.currentValue - } + displayText = peloton_resistanceOrderTextField.currentValue + } } Button { - id: okpidHROrderButton + id: okpeloton_resistanceOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_pid_hr_order = pidHROrderTextField.displayText + onClicked: settings.tile_peloton_resistance_order = peloton_resistanceOrderTextField.displayText } } } + } - AccordionCheckElement { - id: extInclineAccordion - title: qsTr("External Incline") - linkedBoolSetting: "tile_ext_incline_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelExtInclineOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: extInclineOrderTextField - model: rootItem.tile_order - displayText: settings.tile_ext_incline_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = extInclineOrderTextField.currentValue - } + AccordionCheckElement { + id: targetResistanceEnabledAccordion + title: qsTr("Target Resistance") + linkedBoolSetting: "tile_target_resistance_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_resistanceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_resistanceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_resistance_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_resistanceOrderTextField.currentValue } - Button { - id: okextInclineOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_ext_incline_order = extInclineOrderTextField.displayText + } + Button { + id: oktarget_resistanceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_resistance_order = target_resistanceOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: targetPelotonResistanceEnabledAccordion + title: qsTr("Target Peloton Resistance") + linkedBoolSetting: "tile_target_peloton_resistance_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_peloton_resistanceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_peloton_resistanceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_peloton_resistance_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_peloton_resistanceOrderTextField.currentValue } } + Button { + id: oktarget_peloton_resistanceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_peloton_resistance_order = target_peloton_resistanceOrderTextField.displayText + } } + } - AccordionCheckElement { - id: strideLength - title: qsTr("Stride Length") - linkedBoolSetting: "tile_instantaneous_stride_length_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelStrideLengthOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight + AccordionCheckElement { + id: targetCadenceEnabledAccordion + title: qsTr("Target Cadence") + linkedBoolSetting: "tile_target_cadence_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_cadenceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_cadenceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_cadence_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_cadenceOrderTextField.currentValue } - ComboBox { - id: strideLengthOrderTextField - model: rootItem.tile_order - displayText: settings.tile_instantaneous_stride_length_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = strideLengthOrderTextField.currentValue - } + } + Button { + id: oktarget_cadenceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_cadence_order = target_cadenceOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: targetPowerEnabledAccordion + title: qsTr("Target Power") + linkedBoolSetting: "tile_target_power_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_powerOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_powerOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_power_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_powerOrderTextField.currentValue } - Button { - id: okStrideLengthOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_instantaneous_stride_length_order = strideLengthOrderTextField.displayText + } + Button { + id: oktarget_powerOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_power_order = target_powerOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: targetZoneEnabledAccordion + title: qsTr("Target Power Zone") + linkedBoolSetting: "tile_target_zone_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_zoneOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_zoneOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_zone_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_zoneOrderTextField.currentValue } } + Button { + id: oktarget_zoneOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_zone_order = target_zoneOrderTextField.displayText + } } - - AccordionCheckElement { - id: groundContact - title: qsTr("Ground Contact") - linkedBoolSetting: "tile_ground_contact_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelGroundContactOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight + } + AccordionCheckElement { + id: targetSpeedEnabledAccordion + title: qsTr("Target Speed") + linkedBoolSetting: "tile_target_speed_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltargetspeedOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_speedOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_speed_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_speedOrderTextField.currentValue } - ComboBox { - id: groundContactOrderTextField - model: rootItem.tile_order - displayText: settings.tile_ground_contact_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = groundContactOrderTextField.currentValue - } + } + Button { + id: oktarget_speedOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_speed_order = target_speedOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: targetInclineEnabledAccordion + title: qsTr("Target Incline") + linkedBoolSetting: "tile_target_incline_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_inclineOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_inclineOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_incline_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_inclineOrderTextField.currentValue } - Button { - id: okGroundContactOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_ground_contact_order = groundContactOrderTextField.displayText + } + Button { + id: oktarget_inclineOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_incline_order = target_inclineOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: wattKgEnabledAccordion + title: qsTr("Watt/Kg") + linkedBoolSetting: "tile_watt_kg_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelwatt_kgOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: watt_kgOrderTextField + model: rootItem.tile_order + displayText: settings.tile_watt_kg_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = watt_kgOrderTextField.currentValue } } + Button { + id: okwatt_kgOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_watt_kg_order = watt_kgOrderTextField.displayText + } } + } - AccordionCheckElement { - id: verticalOscillation - title: qsTr("Vertical Oscillation") - linkedBoolSetting: "tile_vertical_oscillation_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelVerticalOscillationOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: verticalOscillationOrderTextField - model: rootItem.tile_order - displayText: settings.tile_vertical_oscillation_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = verticalOscillationOrderTextField.currentValue - } - } - Button { - id: okVerticalOscillationOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_vertical_oscillation_order = verticalOscillationOrderTextField.displayText + AccordionCheckElement { + id: gearsEnabledAccordion + title: qsTr("Gears") + linkedBoolSetting: "tile_gears_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelgearsOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: gearsOrderTextField + model: rootItem.tile_order + displayText: settings.tile_gears_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = gearsOrderTextField.currentValue } } + Button { + id: okgearsOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_gears_order = gearsOrderTextField.displayText + } } } - } - AccordionElement { - id: uiGeneralOptionsAccordion - title: qsTr("General UI Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: topBarEnabledDelegate - text: qsTr("Top Bar Enabled") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.top_bar_enabled - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.top_bar_enabled = checked + AccordionCheckElement { + id: remainingTimeTrainingProgramRowEnabledAccordion + title: qsTr("Remaining Time/Row") + linkedBoolSetting: "tile_remainingtimetrainprogramrow_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelremainingTimeTrainingProgramRowOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: remainingTimeTrainingProgramRowOrderTextField + model: rootItem.tile_order + displayText: settings.tile_remainingtimetrainprogramrow_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = remainingTimeTrainingProgramRowOrderTextField.currentValue + } + } + Button { + id: okremainingTimeTrainingProgramRowOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_remainingtimetrainprogramrow_order = remainingTimeTrainingProgramRowOrderTextField.displayText + } } } - } - AccordionElement { - id: pelotonAccordion - title: qsTr("Peloton Options") + "\uD83E\uDD47" - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - - RowLayout { + AccordionCheckElement { + id: nextRowsTrainingProgramRowEnabledAccordion + title: qsTr("Next Rows") + linkedBoolSetting: "tile_nextrowstrainprogram_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelPelotonUsername - text: qsTr("Username:") + id: labelnextRowsTrainingProgramOrder + text: qsTr("order index:") Layout.fillWidth: true - } - TextField { - id: pelotonUsernameTextField - text: settings.peloton_username horizontalAlignment: Text.AlignRight + } + ComboBox { + id: nextRowsTrainingProgramOrderTextField + model: rootItem.tile_order + displayText: settings.tile_nextrowstrainprogram_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onAccepted: settings.peloton_username = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onActivated: { + displayText = nextRowsTrainingProgramOrderTextField.currentValue + } } Button { - id: okPelotonUsernameButton + id: oknextRowsTrainingProgramOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.peloton_username = pelotonUsernameTextField.text + onClicked: settings.tile_nextrowstrainprogram_order = nextRowsTrainingProgramOrderTextField.displayText } } + } - RowLayout { + AccordionCheckElement { + id: metsEnabledAccordion + title: qsTr("METS") + linkedBoolSetting: "tile_mets_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelPelotonPassword - text: qsTr("Password:") + ((rootItem.pelotonLogin===-1)?"":(rootItem.pelotonLogin===1?"\u2705":"\u274c")) + id: labelmetsOrder + text: qsTr("order index:") Layout.fillWidth: true - } - TextField { - id: pelotonPasswordTextField - text: settings.peloton_password horizontalAlignment: Text.AlignRight + } + ComboBox { + id: metsOrderTextField + model: rootItem.tile_order + displayText: settings.tile_mets_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhHiddenText - echoMode: TextInput.PasswordEchoOnEdit - onAccepted: settings.peloton_password = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onActivated: { + displayText = metsOrderTextField.currentValue + } } Button { - id: okPelotonPasswordButton + id: okmetsOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.peloton_password = pelotonPasswordTextField.text + onClicked: settings.tile_mets_order = metsOrderTextField.displayText } } + } - RowLayout { + AccordionCheckElement { + id: targetMetsEnabledAccordion + title: qsTr("Target METS") + linkedBoolSetting: "tile_targetmets_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelPelotonDifficulty - text: qsTr("Difficulty:") + id: labeltargetmetsOrder + text: qsTr("order index:") Layout.fillWidth: true + horizontalAlignment: Text.AlignRight } ComboBox { - id: pelotonDifficultyTextField - model: [ "lower", "upper", "average" ] - displayText: settings.peloton_difficulty + id: targetmetsOrderTextField + model: rootItem.tile_order + displayText: settings.tile_targetmets_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter onActivated: { - console.log("combomodel activated" + pelotonDifficultyTextField.currentIndex) - displayText = pelotonDifficultyTextField.currentValue - } - + displayText = targetmetsOrderTextField.currentValue + } } Button { - id: okPelotonDifficultyButton + id: oktargetmetsOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.peloton_difficulty = pelotonDifficultyTextField.displayText + onClicked: settings.tile_targetmets_order = targetmetsOrderTextField.displayText } } + } - RowLayout { + AccordionCheckElement { + id: datetimeEnabledAccordion + title: qsTr("Time") + linkedBoolSetting: "tile_datetime_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelPZPUsername - text: qsTr("PZP Username:") + id: labeldatetimeOrder + text: qsTr("order index:") Layout.fillWidth: true - } - TextField { - id: pzpUsernameTextField - text: settings.pzp_username horizontalAlignment: Text.AlignRight + } + ComboBox { + id: datetimeOrderTextField + model: rootItem.tile_order + displayText: settings.tile_datetime_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onAccepted: settings.pzp_username = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onActivated: { + displayText = datetimeOrderTextField.currentValue + } } Button { - id: okPZPUsernameButton + id: okdatetimeOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.pzp_username = pzpUsernameTextField.text + onClicked: settings.tile_datetime_order = datetimeOrderTextField.displayText } } - - RowLayout { + } + AccordionCheckElement { + id: targetStrokesCountAccordion + title: qsTr("Strokes Count") + linkedBoolSetting: "tile_strokes_count_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelPZPPassword - text: qsTr("PZP Password:") + ((rootItem.pzpLogin===-1)?"":(rootItem.pzpLogin===1?"\u2705":"\u274c")) + id: labelstrokes_countOrder + text: qsTr("order index:") Layout.fillWidth: true - } - TextField { - id: pzpPasswordTextField - text: settings.pzp_password horizontalAlignment: Text.AlignRight + } + ComboBox { + id: strokes_countOrderTextField + model: rootItem.tile_order + displayText: settings.tile_strokes_count_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhHiddenText - echoMode: TextInput.PasswordEchoOnEdit - onAccepted: settings.pzp_password = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onActivated: { + displayText = strokes_countOrderTextField.currentValue + } } Button { - id: okPZPPasswordButton + id: okstrokes_countOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.pzp_password = pzpPasswordTextField.text + onClicked: settings.tile_strokes_count_order = strokes_countOrderTextField.displayText } } - - RowLayout { + } + AccordionCheckElement { + id: targetStrokesLengthAccordion + title: qsTr("Strokes Length") + linkedBoolSetting: "tile_strokes_length_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelPelotonGain - text: qsTr("Conversion Gain:") + id: labelstrokes_lengthOrder + text: qsTr("order index:") Layout.fillWidth: true - } - TextField { - id: pelotonGainTextField - text: settings.peloton_gain horizontalAlignment: Text.AlignRight + } + ComboBox { + id: strokes_lengthOrderTextField + model: rootItem.tile_order + displayText: settings.tile_strokes_length_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.peloton_gain = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onActivated: { + displayText = strokes_lengthOrderTextField.currentValue + } } Button { - id: okPelotonGainButton + id: okstrokes_lengthOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.peloton_gain = pelotonGainTextField.text + onClicked: settings.tile_strokes_length_order = strokes_lengthOrderTextField.displayText } } + } - RowLayout { + AccordionCheckElement { + id: targetSteeringAngleEnabledAccordion + title: qsTr("Steering Angle") + linkedBoolSetting: "tile_steering_angle_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelPelotonOffset - text: qsTr("Conversion Offset:") + id: labelsteeringAngleOrder + text: qsTr("order index:") Layout.fillWidth: true - } - TextField { - id: pelotonOffsetTextField - text: settings.peloton_offset horizontalAlignment: Text.AlignRight + } + ComboBox { + id: steeringAngleOrderTextField + model: rootItem.tile_order + displayText: settings.tile_steering_angle_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.peloton_offset = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onActivated: { + displayText = steeringAngleOrderTextField.currentValue + } } Button { - id: okPelotonOffsetButton + id: oksteeringAngleOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.peloton_offset = pelotonOffsetTextField.text + onClicked: settings.tile_steering_angle_order = steeringAngleOrderTextField.displayText } } - SwitchDelegate { - id: cadenceSensorDelegate - text: qsTr("Cycling Cadence Sensor (Peloton compatibility)") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.bike_cadence_sensor - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.bike_cadence_sensor = checked - } + } - /* - RowLayout { + AccordionCheckElement { + id: targetPIDHrAccordion + title: qsTr("PID HR Zone") + linkedBoolSetting: "tile_pid_hr_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelPelotonCadenceMetric - text: qsTr("Override Cadence Metric:") + id: labelPIDHROrder + text: qsTr("order index:") Layout.fillWidth: true + horizontalAlignment: Text.AlignRight } ComboBox { - id: pelotonCadenceMetricTextField - model: rootItem.metrics - displayText: settings.peloton_cadence_metric + id: pidHROrderTextField + model: rootItem.tile_order + displayText: settings.tile_pid_hr_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter onActivated: { - console.log("combomodel activated" + pelotonCadenceMetricTextField.currentIndex) - displayText = pelotonCadenceMetricTextField.currentValue - } - + displayText = pidHROrderTextField.currentValue + } } Button { - id: okPelotonCadenceMetric + id: okpidHROrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.peloton_cadence_metric = pelotonCadenceMetricTextField.displayText; + onClicked: settings.tile_pid_hr_order = pidHROrderTextField.displayText } - }*/ + } + } - RowLayout { + AccordionCheckElement { + id: extInclineAccordion + title: qsTr("External Incline") + linkedBoolSetting: "tile_ext_incline_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelPelotonHeartRateMetric - text: qsTr("Override HR Metric:") + id: labelExtInclineOrder + text: qsTr("order index:") Layout.fillWidth: true + horizontalAlignment: Text.AlignRight } ComboBox { - id: pelotonHeartRateMetricTextField - model: rootItem.metrics - displayText: settings.peloton_heartrate_metric + id: extInclineOrderTextField + model: rootItem.tile_order + displayText: settings.tile_ext_incline_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter onActivated: { - console.log("combomodel activated" + pelotonHeartRateMetricTextField.currentIndex) - displayText = pelotonHeartRateMetricTextField.currentValue - } - + displayText = extInclineOrderTextField.currentValue + } } Button { - id: okPelotonHeartRateMetric + id: okextInclineOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.peloton_heartrate_metric = pelotonHeartRateMetricTextField.displayText; + onClicked: settings.tile_ext_incline_order = extInclineOrderTextField.displayText } } + } - RowLayout { + AccordionCheckElement { + id: strideLength + title: qsTr("Stride Length") + linkedBoolSetting: "tile_instantaneous_stride_length_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelpelotonDateOnStrava - text: qsTr("Date on Strava:") + id: labelStrideLengthOrder + text: qsTr("order index:") Layout.fillWidth: true + horizontalAlignment: Text.AlignRight } ComboBox { - id: pelotonDateOnStravaTextField - model: [ "Before Title", "After Title", "Disabled" ] - displayText: settings.peloton_date + id: strideLengthOrderTextField + model: rootItem.tile_order + displayText: settings.tile_instantaneous_stride_length_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter onActivated: { - console.log("combomodel activated" + pelotonDateOnStravaTextField.currentIndex) - displayText = pelotonDateOnStravaTextField.currentValue + displayText = strideLengthOrderTextField.currentValue } - } Button { - id: okPelotonDateOnStrava + id: okStrideLengthOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.peloton_date = pelotonDateOnStravaTextField.displayText + onClicked: settings.tile_instantaneous_stride_length_order = strideLengthOrderTextField.displayText } } - - SwitchDelegate { - id: pelotonDescriptionLinkDelegate - text: qsTr("Activity Link in Strava") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.peloton_description_link - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.peloton_description_link = checked - } } - } - AccordionElement { - id: trainingProgramOptionsAccordion - title: qsTr("Training Program Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { + AccordionCheckElement { + id: groundContact + title: qsTr("Ground Contact") + linkedBoolSetting: "tile_ground_contact_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelGroundContactOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: groundContactOrderTextField + model: rootItem.tile_order + displayText: settings.tile_ground_contact_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = groundContactOrderTextField.currentValue + } + } + Button { + id: okGroundContactOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_ground_contact_order = groundContactOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: verticalOscillation + title: qsTr("Vertical Oscillation") + linkedBoolSetting: "tile_vertical_oscillation_enabled" + settings: settings + accordionContent: RowLayout { spacing: 10 Label { - id: labelTreadmillPidHR - text: qsTr("PID on Heart Zone:") + id: labelVerticalOscillationOrder + text: qsTr("order index:") Layout.fillWidth: true + horizontalAlignment: Text.AlignRight } ComboBox { - id: treadmillPidHRTextField - model: [ "Disabled", "1", "2","3","4","5" ] - displayText: settings.treadmill_pid_heart_zone + id: verticalOscillationOrderTextField + model: rootItem.tile_order + displayText: settings.tile_vertical_oscillation_order Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter onActivated: { - console.log("combomodel activated" + treadmillPidHRTextField.currentIndex) - displayText = treadmillPidHRTextField.currentValue - } - + displayText = verticalOscillationOrderTextField.currentValue + } } Button { - id: okTreadmillPidHR + id: okVerticalOscillationOrderButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.treadmill_pid_heart_zone = treadmillPidHRTextField.displayText + onClicked: settings.tile_vertical_oscillation_order = verticalOscillationOrderTextField.displayText } } } + } + } + + AccordionElement { + id: uiGeneralOptionsAccordion + title: qsTr("General UI Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: topBarEnabledDelegate + text: qsTr("Top Bar Enabled") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.top_bar_enabled + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.top_bar_enabled = checked + } + } + } + AccordionElement { + id: pelotonAccordion + title: qsTr("Peloton Options") + "\uD83E\uDD47" + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 RowLayout { spacing: 10 Label { - id: labelTrainProgramPace1mile - text: qsTr("1 mile pace (total time):") + id: labelPelotonUsername + text: qsTr("Username:") Layout.fillWidth: true } TextField { - id: trainProgramPace1mileTextField - text: (paddingZeros(formatLimitDecimals((settings.pacef_1mile * 1.60934) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_1mile * 1.60934) / 60) % 60,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals((((settings.pacef_1mile * 1.60934) % 60)),0).toString(), 2)) + id: pelotonUsernameTextField + text: settings.peloton_username horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.peloton_username = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okTrainProgramPace1Mile + id: okPelotonUsernameButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: { settings.pacef_1mile = (((parseInt(trainProgramPace1mileTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPace1mileTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPace1mileTextField.text.split(":")[2]))) / 1.60934;} + onClicked: settings.peloton_username = pelotonUsernameTextField.text } } + RowLayout { spacing: 10 Label { - id: labelTrainProgramPace5km - text: qsTr("5 km pace (total time):") + id: labelPelotonPassword + text: qsTr("Password:") + ((rootItem.pelotonLogin===-1)?"":(rootItem.pelotonLogin===1?"\u2705":"\u274c")) Layout.fillWidth: true } TextField { - id: trainProgramPace5kmTextField - text: (paddingZeros(formatLimitDecimals((settings.pacef_5km * 5) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_5km * 5) / 60) % 60,0).toString(), 2) + ":" + paddingZeros((formatLimitDecimals(((settings.pacef_5km * 5) % 60),0)).toString(), 2)) + id: pelotonPasswordTextField + text: settings.peloton_password horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly + inputMethodHints: Qt.ImhHiddenText + echoMode: TextInput.PasswordEchoOnEdit + onAccepted: settings.peloton_password = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okTrainProgramPace5km + id: okPelotonPasswordButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.peloton_password = pelotonPasswordTextField.text + } + } + + RowLayout { + spacing: 10 + Label { + id: labelPelotonDifficulty + text: qsTr("Difficulty:") + Layout.fillWidth: true + } + ComboBox { + id: pelotonDifficultyTextField + model: [ "lower", "upper", "average" ] + displayText: settings.peloton_difficulty + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + pelotonDifficultyTextField.currentIndex) + displayText = pelotonDifficultyTextField.currentValue + } + + } + Button { + id: okPelotonDifficultyButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: { settings.pacef_5km = (((parseInt(trainProgramPace5kmTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPace5kmTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPace5kmTextField.text.split(":")[2]))) / 5;} + onClicked: settings.peloton_difficulty = pelotonDifficultyTextField.displayText } } + RowLayout { spacing: 10 Label { - id: labelTrainProgramPace10km - text: qsTr("10 km pace (total time):") + id: labelPZPUsername + text: qsTr("PZP Username:") Layout.fillWidth: true } TextField { - id: trainProgramPace10kmTextField - text: (paddingZeros(formatLimitDecimals((settings.pacef_10km * 10) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_10km * 10) / 60) % 60,0).toString(), 2) + ":" + paddingZeros((formatLimitDecimals(((settings.pacef_10km * 10) % 60),0)).toString(), 2)) + id: pzpUsernameTextField + text: settings.pzp_username horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.pzp_username = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okTrainProgramPace10KM + id: okPZPUsernameButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: { settings.pacef_10km = (((parseInt(trainProgramPace10kmTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPace10kmTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPace10kmTextField.text.split(":")[2]))) / 10;} + onClicked: settings.pzp_username = pzpUsernameTextField.text } } + RowLayout { spacing: 10 Label { - id: labelTrainProgramPaceHalfMarathon - text: qsTr("Half Marathon pace (total time):") + id: labelPZPPassword + text: qsTr("PZP Password:") + ((rootItem.pzpLogin===-1)?"":(rootItem.pzpLogin===1?"\u2705":"\u274c")) Layout.fillWidth: true } TextField { - id: trainProgramPaceHalfMarathonTextField - text: (paddingZeros(formatLimitDecimals((settings.pacef_halfmarathon * 21) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_halfmarathon * 21) / 60) % 60,0).toString(), 2) + ":" + paddingZeros((formatLimitDecimals(((settings.pacef_halfmarathon * 21) % 60),0)).toString(), 2)) + id: pzpPasswordTextField + text: settings.pzp_password horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly + inputMethodHints: Qt.ImhHiddenText + echoMode: TextInput.PasswordEchoOnEdit + onAccepted: settings.pzp_password = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okTrainProgramPaceHalfMarathon + id: okPZPPasswordButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: { settings.pacef_halfmarathon = (((parseInt(trainProgramPaceHalfMarathonTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPaceHalfMarathonTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPaceHalfMarathonTextField.text.split(":")[2]))) / 21;} + onClicked: settings.pzp_password = pzpPasswordTextField.text } } + RowLayout { spacing: 10 Label { - id: labelTrainProgramPaceMarathon - text: qsTr("Marathon pace (total time):") + id: labelPelotonGain + text: qsTr("Conversion Gain:") Layout.fillWidth: true } TextField { - id: trainProgramPaceMarathonTextField - text: (paddingZeros(formatLimitDecimals((settings.pacef_marathon * 42) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_marathon * 42) / 60) % 60,0).toString(), 2) + ":" + paddingZeros((formatLimitDecimals(((settings.pacef_marathon * 42) % 60),0)).toString(), 2)) + id: pelotonGainTextField + text: settings.peloton_gain horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.peloton_gain = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okTrainProgramPaceMarathon + id: okPelotonGainButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: { settings.pacef_marathon = (((parseInt(trainProgramPaceMarathonTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPaceMarathonTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPaceMarathonTextField.text.split(":")[2]))) / 42;} + onClicked: settings.peloton_gain = pelotonGainTextField.text } } RowLayout { spacing: 10 Label { - id: labelTreadmillPaceDefault - text: qsTr("Default Pace:") + id: labelPelotonOffset + text: qsTr("Conversion Offset:") Layout.fillWidth: true } - ComboBox { - id: treadmillPaceDefaultTextField - model: [ "1 mile", "5 km", "10 km","Half Marathon","Marathon", ] - displayText: settings.pace_default + TextField { + id: pelotonOffsetTextField + text: settings.peloton_offset + horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + treadmillPaceDefaultTextField.currentIndex) - displayText = treadmillPaceDefaultTextField.currentValue - } - + inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.peloton_offset = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okTreadmillPaceDefault + id: okPelotonOffsetButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.pace_default = treadmillPaceDefaultTextField.displayText + onClicked: settings.peloton_offset = pelotonOffsetTextField.text } } + SwitchDelegate { + id: cadenceSensorDelegate + text: qsTr("Cycling Cadence Sensor (Peloton compatibility)") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.bike_cadence_sensor + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.bike_cadence_sensor = checked + } - AccordionCheckElement { - id: trainingProgramRandomAccordion - title: qsTr("Training Program Random Options") - linkedBoolSetting: "trainprogram_random" - settings: settings - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { - spacing: 10 - Label { - id: labelTrainProgramRandomDuration - text: qsTr("Duration (minutes):") - Layout.fillWidth: true - } - TextField { - id: trainProgramRandomDurationTextField - text: settings.trainprogram_total - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.trainprogram_total = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okTrainProgramRandomDuration - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trainprogram_total = trainProgramRandomDurationTextField.text - } - } - - RowLayout { - spacing: 10 - Label { - id: labelTrainProgramRandomPeriod - text: qsTr("Period (seconds):") - Layout.fillWidth: true - } - TextField { - id: trainProgramRandomPeriodTextField - text: settings.trainprogram_period_seconds - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.trainprogram_period_seconds = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okTrainProgramRandomPeriod - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trainprogram_period_seconds = trainProgramRandomPeriodTextField.text - } - } - - RowLayout { - spacing: 10 - Label { - id: labelTrainProgramRandomSpeedMin - text: qsTr("Speed min.:") - Layout.fillWidth: true - } - TextField { - id: trainProgramRandomSpeedMinTextField - text: settings.trainprogram_speed_min - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.trainprogram_speed_min = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okTrainProgramRandomSpeedMin - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trainprogram_speed_min = trainProgramRandomSpeedMinTextField.text - } - } - - RowLayout { - spacing: 10 - Label { - id: labelTrainProgramRandomSpeedMax - text: qsTr("Speed max.:") - Layout.fillWidth: true - } - TextField { - id: trainProgramRandomSpeedMaxTextField - text: settings.trainprogram_speed_max - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.trainprogram_speed_max = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okTrainProgramRandomSpeedMax - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trainprogram_speed_max = trainProgramRandomSpeedMaxTextField.text - } - } - - RowLayout { - spacing: 10 - Label { - id: labelTrainProgramRandomInclineMin - text: qsTr("Incline min.:") - Layout.fillWidth: true - } - TextField { - id: trainProgramRandomInclineMinTextField - text: settings.trainprogram_incline_min - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.trainprogram_incline_min = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okTrainProgramRandomInclineMin - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trainprogram_incline_min = trainProgramRandomInclineMinTextField.text - } - } - - RowLayout { - spacing: 10 - Label { - id: labelTrainProgramRandomInclineMax - text: qsTr("Incline max.:") - Layout.fillWidth: true - } - TextField { - id: trainProgramRandomInclineMaxTextField - text: settings.trainprogram_incline_max - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.trainprogram_incline_max = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okTrainProgramRandomInclineMax - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trainprogram_incline_max = trainProgramRandomInclineMaxTextField.text - } + /* + RowLayout { + spacing: 10 + Label { + id: labelPelotonCadenceMetric + text: qsTr("Override Cadence Metric:") + Layout.fillWidth: true } + ComboBox { + id: pelotonCadenceMetricTextField + model: rootItem.metrics + displayText: settings.peloton_cadence_metric + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + pelotonCadenceMetricTextField.currentIndex) + displayText = pelotonCadenceMetricTextField.currentValue + } - RowLayout { - spacing: 10 - Label { - id: labelTrainProgramRandomResistanceMin - text: qsTr("Resistance min.:") - Layout.fillWidth: true - } - TextField { - id: trainProgramRandomResistanceMinTextField - text: settings.trainprogram_resistance_min - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.trainprogram_resistance_min = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okTrainProgramRandomResistanceMin - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trainprogram_resistance_min = trainProgramRandomResistanceMinTextField.text - } } - - RowLayout { - spacing: 10 - Label { - id: labelTrainProgramRandomResistanceMax - text: qsTr("Resistance max.:") - Layout.fillWidth: true - } - TextField { - id: trainProgramRandomResistanceMaxTextField - text: settings.trainprogram_resistance_max - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.trainprogram_resistance_max = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okTrainProgramRandomResistanceMax - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.trainprogram_resistance_max = trainProgramRandomResistanceMaxTextField.text - } + Button { + id: okPelotonCadenceMetric + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.peloton_cadence_metric = pelotonCadenceMetricTextField.displayText; } - } - } - } + }*/ - AccordionElement { - id:treadmillAccordion - title: qsTr("Treadmill Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: treadmillAsABikeDelegate - text: qsTr("Treadmill as a Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.virtual_device_force_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelPelotonHeartRateMetric + text: qsTr("Override HR Metric:") Layout.fillWidth: true - onClicked: settings.virtual_device_force_bike = checked + } + ComboBox { + id: pelotonHeartRateMetricTextField + model: rootItem.metrics + displayText: settings.peloton_heartrate_metric + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + pelotonHeartRateMetricTextField.currentIndex) + displayText = pelotonHeartRateMetricTextField.currentValue + } + + } + Button { + id: okPelotonHeartRateMetric + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.peloton_heartrate_metric = pelotonHeartRateMetricTextField.displayText; } } - SwitchDelegate { - id: treadmillForceSpeedDelegate - text: qsTr("Treadmill Speed Forcing") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.treadmill_force_speed - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.treadmill_force_speed = checked + RowLayout { + spacing: 10 + Label { + id: labelpelotonDateOnStrava + text: qsTr("Date on Strava:") + Layout.fillWidth: true + } + ComboBox { + id: pelotonDateOnStravaTextField + model: [ "Before Title", "After Title", "Disabled" ] + displayText: settings.peloton_date + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + pelotonDateOnStravaTextField.currentIndex) + displayText = pelotonDateOnStravaTextField.currentValue + } + + } + Button { + id: okPelotonDateOnStrava + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.peloton_date = pelotonDateOnStravaTextField.displayText + } } SwitchDelegate { - id: pauseOnStartTreadmillDelegate - text: qsTr("Pause when App Starts") + id: pelotonDescriptionLinkDelegate + text: qsTr("Activity Link in Strava") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.pause_on_start_treadmill + checked: settings.peloton_description_link Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.pause_on_start_treadmill = checked + onClicked: settings.peloton_description_link = checked } + } + } + AccordionElement { + id: trainingProgramOptionsAccordion + title: qsTr("Training Program Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 RowLayout { spacing: 10 Label { - id: labelTreadmillStepSpeed - text: qsTr("Speed Step:") + id: labelTreadmillPidHR + text: qsTr("PID on Heart Zone:") Layout.fillWidth: true } - TextField { - id: treadmillSpeedStepTextField - text: (settings.miles_unit?settings.treadmill_step_speed * 0.621371:settings.treadmill_step_speed).toFixed(1) - horizontalAlignment: Text.AlignRight + ComboBox { + id: treadmillPidHRTextField + model: [ "Disabled", "1", "2","3","4","5" ] + displayText: settings.treadmill_pid_heart_zone Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.treadmill_step_speed = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onActivated: { + console.log("combomodel activated" + treadmillPidHRTextField.currentIndex) + displayText = treadmillPidHRTextField.currentValue + } + } Button { - id: okTreadmillSpeedStepButton + id: okTreadmillPidHR text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.treadmill_step_speed = (settings.miles_unit?treadmillSpeedStepTextField.text * 1.60934:treadmillSpeedStepTextField.text) + onClicked: settings.treadmill_pid_heart_zone = treadmillPidHRTextField.displayText } } + } - RowLayout { - spacing: 10 - Label { - id: labelTreadmillStepInclination - text: qsTr("Inclination Step:") - Layout.fillWidth: true - } - TextField { - id: treadmillInclinationStepTextField - text: settings.treadmill_step_incline - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.treadmill_step_incline = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okTreadmillInclinationStepButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.treadmill_step_incline = treadmillInclinationStepTextField.text - } + + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramPace1mile + text: qsTr("1 mile pace (total time):") + Layout.fillWidth: true + } + TextField { + id: trainProgramPace1mileTextField + text: (paddingZeros(formatLimitDecimals((settings.pacef_1mile * 1.60934) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_1mile * 1.60934) / 60) % 60,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals((((settings.pacef_1mile * 1.60934) % 60)),0).toString(), 2)) + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramPace1Mile + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: { settings.pacef_1mile = (((parseInt(trainProgramPace1mileTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPace1mileTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPace1mileTextField.text.split(":")[2]))) / 1.60934;} } + } + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramPace5km + text: qsTr("5 km pace (total time):") + Layout.fillWidth: true + } + TextField { + id: trainProgramPace5kmTextField + text: (paddingZeros(formatLimitDecimals((settings.pacef_5km * 5) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_5km * 5) / 60) % 60,0).toString(), 2) + ":" + paddingZeros((formatLimitDecimals(((settings.pacef_5km * 5) % 60),0)).toString(), 2)) + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramPace5km + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: { settings.pacef_5km = (((parseInt(trainProgramPace5kmTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPace5kmTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPace5kmTextField.text.split(":")[2]))) / 5;} + } + } + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramPace10km + text: qsTr("10 km pace (total time):") + Layout.fillWidth: true + } + TextField { + id: trainProgramPace10kmTextField + text: (paddingZeros(formatLimitDecimals((settings.pacef_10km * 10) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_10km * 10) / 60) % 60,0).toString(), 2) + ":" + paddingZeros((formatLimitDecimals(((settings.pacef_10km * 10) % 60),0)).toString(), 2)) + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramPace10KM + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: { settings.pacef_10km = (((parseInt(trainProgramPace10kmTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPace10kmTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPace10kmTextField.text.split(":")[2]))) / 10;} + } + } + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramPaceHalfMarathon + text: qsTr("Half Marathon pace (total time):") + Layout.fillWidth: true + } + TextField { + id: trainProgramPaceHalfMarathonTextField + text: (paddingZeros(formatLimitDecimals((settings.pacef_halfmarathon * 21) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_halfmarathon * 21) / 60) % 60,0).toString(), 2) + ":" + paddingZeros((formatLimitDecimals(((settings.pacef_halfmarathon * 21) % 60),0)).toString(), 2)) + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramPaceHalfMarathon + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: { settings.pacef_halfmarathon = (((parseInt(trainProgramPaceHalfMarathonTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPaceHalfMarathonTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPaceHalfMarathonTextField.text.split(":")[2]))) / 21;} + } + } + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramPaceMarathon + text: qsTr("Marathon pace (total time):") + Layout.fillWidth: true + } + TextField { + id: trainProgramPaceMarathonTextField + text: (paddingZeros(formatLimitDecimals((settings.pacef_marathon * 42) / 3600,0).toString(), 2) + ":" + paddingZeros(formatLimitDecimals(((settings.pacef_marathon * 42) / 60) % 60,0).toString(), 2) + ":" + paddingZeros((formatLimitDecimals(((settings.pacef_marathon * 42) % 60),0)).toString(), 2)) + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramPaceMarathon + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: { settings.pacef_marathon = (((parseInt(trainProgramPaceMarathonTextField.text.split(":")[0]) * 3600) + (parseInt(trainProgramPaceMarathonTextField.text.split(":")[1]) * 60) + parseInt(trainProgramPaceMarathonTextField.text.split(":")[2]))) / 42;} + } + } + RowLayout { + spacing: 10 + Label { + id: labelTreadmillPaceDefault + text: qsTr("Default Pace:") + Layout.fillWidth: true + } + ComboBox { + id: treadmillPaceDefaultTextField + model: [ "1 mile", "5 km", "10 km","Half Marathon","Marathon", ] + displayText: settings.pace_default + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + treadmillPaceDefaultTextField.currentIndex) + displayText = treadmillPaceDefaultTextField.currentValue + } - AccordionElement { - id: proformTreadmillAccordion - title: qsTr("Proform/Nordictrack Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: nordictrack10Delegate - text: qsTr("Nordictrack 10") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.nordictrack_10_treadmill - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.nordictrack_10_treadmill = checked - } - SwitchDelegate { - id: nordictrackT65SDelegate - text: qsTr("Nordictrack T6.5S") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.nordictrack_t65s_treadmill - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + } + Button { + id: okTreadmillPaceDefault + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.pace_default = treadmillPaceDefaultTextField.displayText + } + } + + AccordionCheckElement { + id: trainingProgramRandomAccordion + title: qsTr("Training Program Random Options") + linkedBoolSetting: "trainprogram_random" + settings: settings + accordionContent: ColumnLayout { + spacing: 0 + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramRandomDuration + text: qsTr("Duration (minutes):") Layout.fillWidth: true - onClicked: settings.nordictrack_t65s_treadmill = checked } - SwitchDelegate { - id: nordictrackS30Delegate - text: qsTr("Nordictrack S30") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.nordictrack_s30_treadmill - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.nordictrack_s30_treadmill = checked + TextField { + id: trainProgramRandomDurationTextField + text: settings.trainprogram_total + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.trainprogram_total = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - SwitchDelegate { - id: proform1800iDelegate - text: qsTr("Proform 1800i") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.proform_treadmill_1800i - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.proform_treadmill_1800i = checked + Button { + id: okTrainProgramRandomDuration + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trainprogram_total = trainProgramRandomDurationTextField.text } - SwitchDelegate { - id: proformSEDelegate - text: qsTr("Proform SE") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.proform_treadmill_se - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + } + + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramRandomPeriod + text: qsTr("Period (seconds):") Layout.fillWidth: true - onClicked: settings.proform_treadmill_se = checked - } - RowLayout { - spacing: 10 - Label { - id: labelproformtreadmillip - text: qsTr("Proform IP:") - Layout.fillWidth: true - } - TextField { - id: proformtreadmillIPTextField - text: settings.proformtreadmillip - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.proformtreadmillip = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okproformtreadmillIPButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.proformtreadmillip = proformtreadmillIPTextField.text - } } - RowLayout { - spacing: 10 - Label { - id: labelnordictrack2950IP - text: qsTr("Nordictrack 2950 IP:") - Layout.fillWidth: true - } - TextField { - id: nordictrack2950IPTextField - text: settings.nordictrack_2950_ip - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.nordictrack_2950_ip = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: oknordictrack2950IPButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.nordictrack_2950_ip = nordictrack2950IPTextField.text - } + TextField { + id: trainProgramRandomPeriodTextField + text: settings.trainprogram_period_seconds + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.trainprogram_period_seconds = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - SwitchDelegate { - id: proform90IDelegate - text: qsTr("Proform 9.0") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.proform_treadmill_9_0 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.proform_treadmill_9_0 = checked + Button { + id: okTrainProgramRandomPeriod + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trainprogram_period_seconds = trainProgramRandomPeriodTextField.text } - /* - SwitchDelegate { - id: nordictrackFS5IDelegate - text: qsTr("Nordictrack FS5i") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.nordictrack_fs5i_treadmill - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.nordictrack_fs5i_treadmill = checked - }*/ - /* - SwitchDelegate { - id: proform995iDelegate - text: qsTr("Proform 995i") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.proform_treadmill_995i - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.proform_treadmill_995i = checked - }*/ } - } - AccordionElement { - id: pafersTreadmillAccordion - title: qsTr("Pafers Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: pafersTreadmillDelegate - text: qsTr("Pafers Treadmill") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.pafers_treadmill - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramRandomSpeedMin + text: qsTr("Speed min.:") Layout.fillWidth: true - onClicked: settings.pafers_treadmill = checked + } + TextField { + id: trainProgramRandomSpeedMinTextField + text: settings.trainprogram_speed_min + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.trainprogram_speed_min = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramRandomSpeedMin + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trainprogram_speed_min = trainProgramRandomSpeedMinTextField.text } } - } - AccordionElement { - id: kingsmithTreadmillAccordion - title: qsTr("KingSmith Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: kingSmithTreadmillDelegate - text: qsTr("WalkingPad X21") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramRandomSpeedMax + text: qsTr("Speed max.:") + Layout.fillWidth: true + } + TextField { + id: trainProgramRandomSpeedMaxTextField + text: settings.trainprogram_speed_max + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.trainprogram_speed_max = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramRandomSpeedMax + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trainprogram_speed_max = trainProgramRandomSpeedMaxTextField.text } + } - SwitchDelegate { - id: kingSmithV3TreadmillDelegate - text: qsTr("WalkingPad X21 v2") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.kingsmith_encrypt_v3 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramRandomInclineMin + text: qsTr("Incline min.:") Layout.fillWidth: true - onClicked: settings.kingsmith_encrypt_v3 = checked + } + TextField { + id: trainProgramRandomInclineMinTextField + text: settings.trainprogram_incline_min + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.trainprogram_incline_min = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramRandomInclineMin + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trainprogram_incline_min = trainProgramRandomInclineMinTextField.text } } - } - AccordionElement { - id: runnerTTreadmillAccordion - title: qsTr("RunnerT Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: fitfiuMCV460TreadmillDelegate - text: qsTr("Fitfiu MC-460") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.fitfiu_mc_v460 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramRandomInclineMax + text: qsTr("Incline max.:") Layout.fillWidth: true - onClicked: settings.fitfiu_mc_v460 = checked + } + TextField { + id: trainProgramRandomInclineMaxTextField + text: settings.trainprogram_incline_max + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.trainprogram_incline_max = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramRandomInclineMax + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trainprogram_incline_max = trainProgramRandomInclineMaxTextField.text } } - } - AccordionElement { - id: domyosTreadmillAccordion - title: qsTr("Domyos Treadmill Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: domyosTreadmillButtonsDelegate - text: qsTr("Speed/Inclination Buttons") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.domyos_treadmill_buttons - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramRandomResistanceMin + text: qsTr("Resistance min.:") Layout.fillWidth: true - onClicked: settings.domyos_treadmill_buttons = checked } + TextField { + id: trainProgramRandomResistanceMinTextField + text: settings.trainprogram_resistance_min + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.trainprogram_resistance_min = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramRandomResistanceMin + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trainprogram_resistance_min = trainProgramRandomResistanceMinTextField.text + } + } - SwitchDelegate { - id: domyosTreadmillDistanceDisplayDelegate - text: qsTr("Distance on Console") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.domyos_treadmill_distance_display - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelTrainProgramRandomResistanceMax + text: qsTr("Resistance max.:") Layout.fillWidth: true - onClicked: settings.domyos_treadmill_distance_display = checked } + TextField { + id: trainProgramRandomResistanceMaxTextField + text: settings.trainprogram_resistance_max + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.trainprogram_resistance_max = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTrainProgramRandomResistanceMax + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.trainprogram_resistance_max = trainProgramRandomResistanceMaxTextField.text + } + } + } + } + } - SwitchDelegate { - id: domyosTreadmillDisplayInvertdelegate - text: qsTr("Fix Distance on Display") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.domyos_treadmill_display_invert - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + AccordionElement { + id:treadmillAccordion + title: qsTr("Treadmill Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: treadmillAsABikeDelegate + text: qsTr("Treadmill as a Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.virtual_device_force_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.virtual_device_force_bike = checked + } + } + + SwitchDelegate { + id: treadmillForceSpeedDelegate + text: qsTr("Treadmill Speed Forcing") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.treadmill_force_speed + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.treadmill_force_speed = checked + } + + SwitchDelegate { + id: pauseOnStartTreadmillDelegate + text: qsTr("Pause when App Starts") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.pause_on_start_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.pause_on_start_treadmill = checked + } + + RowLayout { + spacing: 10 + Label { + id: labelTreadmillStepSpeed + text: qsTr("Speed Step:") + Layout.fillWidth: true + } + TextField { + id: treadmillSpeedStepTextField + text: (settings.miles_unit?settings.treadmill_step_speed * 0.621371:settings.treadmill_step_speed).toFixed(1) + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.treadmill_step_speed = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTreadmillSpeedStepButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.treadmill_step_speed = (settings.miles_unit?treadmillSpeedStepTextField.text * 1.60934:treadmillSpeedStepTextField.text) + } + } + + RowLayout { + spacing: 10 + Label { + id: labelTreadmillStepInclination + text: qsTr("Inclination Step:") + Layout.fillWidth: true + } + TextField { + id: treadmillInclinationStepTextField + text: settings.treadmill_step_incline + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.treadmill_step_incline = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTreadmillInclinationStepButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.treadmill_step_incline = treadmillInclinationStepTextField.text + } + } + + + AccordionElement { + id: proformTreadmillAccordion + title: qsTr("Proform/Nordictrack Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: nordictrack10Delegate + text: qsTr("Nordictrack 10") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.nordictrack_10_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.nordictrack_10_treadmill = checked + } + SwitchDelegate { + id: nordictrackT65SDelegate + text: qsTr("Nordictrack T6.5S") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.nordictrack_t65s_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.nordictrack_t65s_treadmill = checked + } + SwitchDelegate { + id: nordictrackS30Delegate + text: qsTr("Nordictrack S30") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.nordictrack_s30_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.nordictrack_s30_treadmill = checked + } + SwitchDelegate { + id: proform1800iDelegate + text: qsTr("Proform 1800i") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.proform_treadmill_1800i + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.proform_treadmill_1800i = checked + } + SwitchDelegate { + id: proformSEDelegate + text: qsTr("Proform SE") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.proform_treadmill_se + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.proform_treadmill_se = checked + } + RowLayout { + spacing: 10 + Label { + id: labelproformtreadmillip + text: qsTr("Proform IP:") Layout.fillWidth: true - onClicked: settings.domyos_treadmill_display_invert = checked + } + TextField { + id: proformtreadmillIPTextField + text: settings.proformtreadmillip + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.proformtreadmillip = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okproformtreadmillIPButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.proformtreadmillip = proformtreadmillIPTextField.text } } - } - - AccordionElement { - id:soleTreadmillAccordion - title: qsTr("Sole Treadmill Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 0 - SwitchDelegate { - id: soleInclinationDelegate - text: qsTr("Inclination (experimental)") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.sole_treadmill_inclination - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelnordictrack2950IP + text: qsTr("Nordictrack 2950 IP:") Layout.fillWidth: true - onClicked: settings.sole_treadmill_inclination = checked } - SwitchDelegate { - id: soleMilesDelegate - text: qsTr("Miles unit from the device") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.sole_treadmill_miles - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.sole_treadmill_miles = checked + TextField { + id: nordictrack2950IPTextField + text: settings.nordictrack_2950_ip + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.nordictrack_2950_ip = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - SwitchDelegate { - id: soleF63Delegate - text: qsTr("Sole F63") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.sole_treadmill_f63 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.sole_treadmill_f63 = checked + Button { + id: oknordictrack2950IPButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.nordictrack_2950_ip = nordictrack2950IPTextField.text } + } + SwitchDelegate { + id: proform90IDelegate + text: qsTr("Proform 9.0") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.proform_treadmill_9_0 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.proform_treadmill_9_0 = checked + } + /* SwitchDelegate { - id: soleF65Delegate - text: qsTr("Sole F65") + id: nordictrackFS5IDelegate + text: qsTr("Nordictrack FS5i") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.sole_treadmill_f65 + checked: settings.nordictrack_fs5i_treadmill Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.sole_treadmill_f65 = checked - } + onClicked: settings.nordictrack_fs5i_treadmill = checked + }*/ + /* SwitchDelegate { - id: soleTT8Delegate - text: qsTr("Sole TT8") + id: proform995iDelegate + text: qsTr("Proform 995i") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.sole_treadmill_tt8 + checked: settings.proform_treadmill_995i Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.sole_treadmill_tt8 = checked - } - } + onClicked: settings.proform_treadmill_995i = checked + }*/ } + } - AccordionElement { - id: technogymTreadmillAccordion - title: qsTr("Technogym Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { + AccordionElement { + id: pafersTreadmillAccordion + title: qsTr("Pafers Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: pafersTreadmillDelegate + text: qsTr("Pafers Treadmill") spacing: 0 - SwitchDelegate { - id: myrunDelegate - text: qsTr("MyRun Experimental") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.technogym_myrun_treadmill_experimental - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.technogym_myrun_treadmill_experimental = checked - } + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.pafers_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.pafers_treadmill = checked } } + } - AccordionElement { - id: fitshowAccordion - title: qsTr("Fitshow Treadmill Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - SwitchDelegate { - id: fitshowAnyrunDelegate - text: qsTr("AnyRun") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.fitshow_anyrun - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.fitshow_anyrun = checked - } - SwitchDelegate { - id: fitshowTruetimerDelegate - text: qsTr("True timer") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.fitshow_truetimer - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.fitshow_truetimer = checked - } - RowLayout { - spacing: 10 - Label { - id: labelfitshowTreadmillUserId - text: qsTr("User ID:") - Layout.fillWidth: true - } - TextField { - id: fitshowTreadmillUserIdTextField - text: settings.fitshow_user_id - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.fitshow_user_id = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okfitshowTreadmillUserIdButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.fitshow_user_id = fitshowTreadmillUserIdTextField.text - } - } + AccordionElement { + id: kingsmithTreadmillAccordion + title: qsTr("KingSmith Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: kingSmithTreadmillDelegate + text: qsTr("WalkingPad X21") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + } + + SwitchDelegate { + id: kingSmithV3TreadmillDelegate + text: qsTr("WalkingPad X21 v2") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.kingsmith_encrypt_v3 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.kingsmith_encrypt_v3 = checked } } + } - AccordionElement { - id: eslinkerTreadmillAccordion - title: qsTr("ESLinker Treadmill Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { + AccordionElement { + id: runnerTTreadmillAccordion + title: qsTr("RunnerT Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: fitfiuMCV460TreadmillDelegate + text: qsTr("Fitfiu MC-460") spacing: 0 - SwitchDelegate { - id: eslinkerTreadmillCadenzaDelegate - text: qsTr("Cadenza Treadmill (Bodytone)") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.eslinker_cadenza - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.eslinker_cadenza = checked - } + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.fitfiu_mc_v460 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.fitfiu_mc_v460 = checked } } + } - AccordionElement { - id: horizonTreadmillAccordion - title: qsTr("Horizon Treadmill Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { + AccordionElement { + id: domyosTreadmillAccordion + title: qsTr("Domyos Treadmill Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: domyosTreadmillButtonsDelegate + text: qsTr("Speed/Inclination Buttons") spacing: 0 - SwitchDelegate { - id: horizonParagonXTreadmillCadenzaDelegate - text: qsTr("Paragon X") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.horizon_paragon_x - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.horizon_paragon_x = checked - } - SwitchDelegate { - id: horizon78TreadmillDelegate - text: qsTr("Horizon 7.8 start issue") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.horizon_treadmill_7_8 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.horizon_treadmill_7_8 = checked - } + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.domyos_treadmill_buttons + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.domyos_treadmill_buttons = checked + } + + SwitchDelegate { + id: domyosTreadmillDistanceDisplayDelegate + text: qsTr("Distance on Console") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.domyos_treadmill_distance_display + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.domyos_treadmill_distance_display = checked } - } + SwitchDelegate { + id: domyosTreadmillDisplayInvertdelegate + text: qsTr("Fix Distance on Display") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.domyos_treadmill_display_invert + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.domyos_treadmill_display_invert = checked + } + } } AccordionElement { - id: toorxTreadmillAccordion - title: qsTr("Toorx/iConsole Options") + id:soleTreadmillAccordion + title: qsTr("Sole Treadmill Options") indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) color: Material.backgroundColor accordionContent: ColumnLayout { spacing: 0 SwitchDelegate { - id: toorxRouteKeyDelegate - text: qsTr("TRX ROUTE KEY Compatibility") + id: soleInclinationDelegate + text: qsTr("Inclination (experimental)") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.trx_route_key + checked: settings.sole_treadmill_inclination Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.trx_route_key = checked + onClicked: settings.sole_treadmill_inclination = checked } SwitchDelegate { - id: trxsevoDelegate - text: qsTr("TRX 65s EVO") + id: soleMilesDelegate + text: qsTr("Miles unit from the device") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.toorx_65s_evo + checked: settings.sole_treadmill_miles Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.toorx_65s_evo = checked + onClicked: settings.sole_treadmill_miles = checked + } + SwitchDelegate { + id: soleF63Delegate + text: qsTr("Sole F63") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.sole_treadmill_f63 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.sole_treadmill_f63 = checked + } + SwitchDelegate { + id: soleF65Delegate + text: qsTr("Sole F65") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.sole_treadmill_f65 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.sole_treadmill_f65 = checked } - SwitchDelegate { - id: bhSpadaDelegate - text: qsTr("BH SPADA Compatibility") + id: soleTT8Delegate + text: qsTr("Sole TT8") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.bh_spada_2 + checked: settings.sole_treadmill_tt8 Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.bh_spada_2 = checked + onClicked: settings.sole_treadmill_tt8 = checked } + } + } + AccordionElement { + id: technogymTreadmillAccordion + title: qsTr("Technogym Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 SwitchDelegate { - id: jtxFitnessSprintTreadmillDelegate - text: qsTr("JTX Fitness Sprint Treadmill") + id: myrunDelegate + text: qsTr("MyRun Experimental") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.jtx_fitness_sprint_treadmill + checked: settings.technogym_myrun_treadmill_experimental Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.jtx_fitness_sprint_treadmill = checked + onClicked: settings.technogym_myrun_treadmill_experimental = checked } + } + } + AccordionElement { + id: fitshowAccordion + title: qsTr("Fitshow Treadmill Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + SwitchDelegate { + id: fitshowAnyrunDelegate + text: qsTr("AnyRun") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.fitshow_anyrun + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.fitshow_anyrun = checked + } SwitchDelegate { - id: reebokFR30TreadmillDelegate - text: qsTr("Reebok FR30 Treadmill") + id: fitshowTruetimerDelegate + text: qsTr("True timer") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.reebok_fr30_treadmill + checked: settings.fitshow_truetimer Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.reebok_fr30_treadmill = checked + onClicked: settings.fitshow_truetimer = checked + } + RowLayout { + spacing: 10 + Label { + id: labelfitshowTreadmillUserId + text: qsTr("User ID:") + Layout.fillWidth: true + } + TextField { + id: fitshowTreadmillUserIdTextField + text: settings.fitshow_user_id + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.fitshow_user_id = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okfitshowTreadmillUserIdButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.fitshow_user_id = fitshowTreadmillUserIdTextField.text + } } + } + } + AccordionElement { + id: eslinkerTreadmillAccordion + title: qsTr("ESLinker Treadmill Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 SwitchDelegate { - id: dknEndurunTreadmillDelegate - text: qsTr("DKN Endurn Treadmill") + id: eslinkerTreadmillCadenzaDelegate + text: qsTr("Cadenza Treadmill (Bodytone)") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.dkn_endurun_treadmill + checked: settings.eslinker_cadenza Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.dkn_endurun_treadmill = checked + onClicked: settings.eslinker_cadenza = checked } + } + } + AccordionElement { + id: horizonTreadmillAccordion + title: qsTr("Horizon Treadmill Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: horizonParagonXTreadmillCadenzaDelegate + text: qsTr("Paragon X") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.horizon_paragon_x + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.horizon_paragon_x = checked + } SwitchDelegate { - id: toorxTreadmill30Delegate - text: qsTr("Toorx 3.0 Compatibility") + id: horizon78TreadmillDelegate + text: qsTr("Horizon 7.8 start issue") spacing: 0 bottomPadding: 0 topPadding: 0 rightPadding: 0 leftPadding: 0 clip: false - checked: settings.toorx_3_0 + checked: settings.horizon_treadmill_7_8 Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true - onClicked: settings.toorx_3_0 = checked + onClicked: settings.horizon_treadmill_7_8 = checked } + } + } + + } + + AccordionElement { + id: toorxTreadmillAccordion + title: qsTr("Toorx/iConsole Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: toorxRouteKeyDelegate + text: qsTr("TRX ROUTE KEY Compatibility") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.trx_route_key + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.trx_route_key = checked + } + SwitchDelegate { + id: trxsevoDelegate + text: qsTr("TRX 65s EVO") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.toorx_65s_evo + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.toorx_65s_evo = checked + } + + SwitchDelegate { + id: bhSpadaDelegate + text: qsTr("BH SPADA Compatibility") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.bh_spada_2 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.bh_spada_2 = checked + } + + SwitchDelegate { + id: jtxFitnessSprintTreadmillDelegate + text: qsTr("JTX Fitness Sprint Treadmill") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.jtx_fitness_sprint_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.jtx_fitness_sprint_treadmill = checked + } + + SwitchDelegate { + id: reebokFR30TreadmillDelegate + text: qsTr("Reebok FR30 Treadmill") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.reebok_fr30_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.reebok_fr30_treadmill = checked + } + + SwitchDelegate { + id: dknEndurunTreadmillDelegate + text: qsTr("DKN Endurn Treadmill") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.dkn_endurun_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.dkn_endurun_treadmill = checked + } + + SwitchDelegate { + id: toorxTreadmill30Delegate + text: qsTr("Toorx 3.0 Compatibility") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.toorx_3_0 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.toorx_3_0 = checked + } + + SwitchDelegate { + id: toorxBikeDelegate + text: qsTr("Toorx/iConsole Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.toorx_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.toorx_bike = checked + } + + SwitchDelegate { + id: toorxFTMSBikeDelegate + text: qsTr("Toorx FTMS Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.toorx_ftms + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.toorx_ftms = checked + } + + SwitchDelegate { + id: toorxBikeJLLIC400Delegate + text: qsTr("JLL IC400 Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.jll_IC400_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.jll_IC400_bike = checked + } + SwitchDelegate { + id: toorxBikeFytterRI08Delegate + text: qsTr("Fytter RI08 Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.fytter_ri08_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.fytter_ri08_bike = checked + } + SwitchDelegate { + id: toorxBikeASVIVADelegate + text: qsTr("Asviva Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.asviva_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.asviva_bike = checked + } + SwitchDelegate { + id: toorxBikeHertzXR770Delegate + text: qsTr("Hertz XR 770 Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.hertz_xr_770 + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.hertz_xr_770 = checked + } + } + } + AccordionElement { + id: domyosEllipticalAccordion + title: qsTr("Domyos Elliptical Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelDomyosEllipticalSpeedRatio + text: qsTr("Speed Ratio:") + Layout.fillWidth: true + } + TextField { + id: domyosEllipticalSpeedRatioTextField + text: settings.domyos_elliptical_speed_ratio + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.domyos_elliptical_speed_ratio = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okDomyosEllipticalRatioButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.domyos_elliptical_speed_ratio = domyosEllipticalSpeedRatioTextField.text + } + } + } - SwitchDelegate { - id: toorxBikeDelegate - text: qsTr("Toorx/iConsole Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.toorx_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + AccordionElement { + id: advancedSettingsAccordion + title: qsTr("Advanced Settings") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 + RowLayout { + spacing: 10 + Label { + id: labelFilterDevice + text: qsTr("Manual Device:") Layout.fillWidth: true - onClicked: settings.toorx_bike = checked } + ComboBox { + id: filterDeviceTextField + model: rootItem.bluetoothDevices + displayText: settings.filter_device + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + filterDeviceTextField.currentIndex) + displayText = filterDeviceTextField.currentValue + } - SwitchDelegate { - id: toorxFTMSBikeDelegate - text: qsTr("Toorx FTMS Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.toorx_ftms - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.toorx_ftms = checked } - - SwitchDelegate { - id: toorxBikeJLLIC400Delegate - text: qsTr("JLL IC400 Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.jll_IC400_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.jll_IC400_bike = checked + Button { + id: okFilterDeviceButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.filter_device = filterDeviceTextField.displayText } - SwitchDelegate { - id: toorxBikeFytterRI08Delegate - text: qsTr("Fytter RI08 Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.fytter_ri08_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + } + + Button { + id: refreshFilterDeviceButton + text: "Refresh Devices List" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: refresh_bluetooth_devices_clicked(); + } + + RowLayout { + spacing: 10 + Label { + id: labelwattOffset + text: qsTr("Watt Offset (only <0):") Layout.fillWidth: true - onClicked: settings.fytter_ri08_bike = checked } - SwitchDelegate { - id: toorxBikeASVIVADelegate - text: qsTr("Asviva Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.asviva_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.asviva_bike = checked + TextField { + id: wattOffsetTextField + text: settings.watt_offset + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.watt_offset = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - SwitchDelegate { - id: toorxBikeHertzXR770Delegate - text: qsTr("Hertz XR 770 Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.hertz_xr_770 - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.hertz_xr_770 = checked + Button { + id: okwattOffsetButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.watt_offset = wattOffsetTextField.text } } - } - AccordionElement { - id: domyosEllipticalAccordion - title: qsTr("Domyos Elliptical Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - accordionContent: RowLayout { + + RowLayout { spacing: 10 Label { - id: labelDomyosEllipticalSpeedRatio - text: qsTr("Speed Ratio:") + id: labelwattGain + text: qsTr("Watt Gain:") Layout.fillWidth: true } TextField { - id: domyosEllipticalSpeedRatioTextField - text: settings.domyos_elliptical_speed_ratio + id: wattGainTextField + text: settings.watt_gain horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.domyos_elliptical_speed_ratio = text + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.watt_gain = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okDomyosEllipticalRatioButton + id: okWattGainButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.domyos_elliptical_speed_ratio = domyosEllipticalSpeedRatioTextField.text + onClicked: settings.watt_gain = wattGainTextField.text } } - } - - AccordionElement { - id: advancedSettingsAccordion - title: qsTr("Advanced Settings") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { - spacing: 10 - Label { - id: labelFilterDevice - text: qsTr("Manual Device:") - Layout.fillWidth: true - } - ComboBox { - id: filterDeviceTextField - model: rootItem.bluetoothDevices - displayText: settings.filter_device - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + filterDeviceTextField.currentIndex) - displayText = filterDeviceTextField.currentValue - } - } - Button { - id: okFilterDeviceButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.filter_device = filterDeviceTextField.displayText - } + RowLayout { + spacing: 10 + Label { + id: labelspeedOffset + text: qsTr("Speed Offset") + Layout.fillWidth: true + } + TextField { + id: speedOffsetTextField + text: settings.speed_offset + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.speed_offset = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - Button { - id: refreshFilterDeviceButton - text: "Refresh Devices List" + id: okspeedOffsetButton + text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: refresh_bluetooth_devices_clicked(); + onClicked: settings.speed_offset = speedOffsetTextField.text } + } - RowLayout { - spacing: 10 - Label { - id: labelwattOffset - text: qsTr("Watt Offset (only <0):") - Layout.fillWidth: true - } - TextField { - id: wattOffsetTextField - text: settings.watt_offset - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.watt_offset = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okwattOffsetButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.watt_offset = wattOffsetTextField.text - } + RowLayout { + spacing: 10 + Label { + id: labelspeedGain + text: qsTr("Speed Gain:") + Layout.fillWidth: true } - - RowLayout { - spacing: 10 - Label { - id: labelwattGain - text: qsTr("Watt Gain:") - Layout.fillWidth: true - } - TextField { - id: wattGainTextField - text: settings.watt_gain - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.watt_gain = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okWattGainButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.watt_gain = wattGainTextField.text - } + TextField { + id: speedGainTextField + text: settings.speed_gain + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.speed_gain = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - - RowLayout { - spacing: 10 - Label { - id: labelspeedOffset - text: qsTr("Speed Offset") - Layout.fillWidth: true - } - TextField { - id: speedOffsetTextField - text: settings.speed_offset - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.speed_offset = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okspeedOffsetButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.speed_offset = speedOffsetTextField.text - } + Button { + id: okSpeedGainButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.speed_gain = speedGainTextField.text } + } - RowLayout { - spacing: 10 - Label { - id: labelspeedGain - text: qsTr("Speed Gain:") - Layout.fillWidth: true - } - TextField { - id: speedGainTextField - text: settings.speed_gain - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.speed_gain = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSpeedGainButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.speed_gain = speedGainTextField.text - } + RowLayout { + spacing: 10 + Label { + id: labelcadenceOffset + text: qsTr("Cadence Offset") + Layout.fillWidth: true } - - RowLayout { - spacing: 10 - Label { - id: labelcadenceOffset - text: qsTr("Cadence Offset") - Layout.fillWidth: true - } - TextField { - id: cadenceOffsetTextField - text: settings.cadence_offset - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.cadence_offset = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okcadenceOffsetButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.cadence_offset = cadenceOffsetTextField.text - } + TextField { + id: cadenceOffsetTextField + text: settings.cadence_offset + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.cadence_offset = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - - RowLayout { - spacing: 10 - Label { - id: labelcadenceGain - text: qsTr("Cadence Gain:") - Layout.fillWidth: true - } - TextField { - id: cadenceGainTextField - text: settings.cadence_gain - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.cadence_gain = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okCadenceGainButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.cadence_gain = speedGainTextField.text - } + Button { + id: okcadenceOffsetButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.cadence_offset = cadenceOffsetTextField.text } + } + RowLayout { + spacing: 10 Label { - id: stravaLabel - text: qsTr("Strava") - textFormat: Text.PlainText - wrapMode: Text.WordWrap - verticalAlignment: Text.AlignVCenter + id: labelcadenceGain + text: qsTr("Cadence Gain:") + Layout.fillWidth: true } - - RowLayout { - spacing: 10 - Label { - id: labelStravaSuffix - text: qsTr("Suffix activity:") - Layout.fillWidth: true - } - TextField { - id: stravaSuffixTextField - text: settings.strava_suffix - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onAccepted: settings.strava_suffix = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okStravaSuffixButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.strava_suffix = stravaSuffixTextField.text - } + TextField { + id: cadenceGainTextField + text: settings.cadence_gain + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.cadence_gain = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okCadenceGainButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.cadence_gain = speedGainTextField.text } + } - SwitchDelegate { - id: volumeChangeGearsDelegate - text: qsTr("Volumes buttons change gears") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.volume_change_gears - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Label { + id: stravaLabel + text: qsTr("Strava") + textFormat: Text.PlainText + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + } + + RowLayout { + spacing: 10 + Label { + id: labelStravaSuffix + text: qsTr("Suffix activity:") Layout.fillWidth: true - onClicked: settings.volume_change_gears = checked } + TextField { + id: stravaSuffixTextField + text: settings.strava_suffix + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onAccepted: settings.strava_suffix = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okStravaSuffixButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.strava_suffix = stravaSuffixTextField.text + } + } - SwitchDelegate { - id: powerAvg5s - text: qsTr("Power Average 5 sec.") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.power_avg_5s - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + SwitchDelegate { + id: volumeChangeGearsDelegate + text: qsTr("Volumes buttons change gears") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.volume_change_gears + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.volume_change_gears = checked + } + + SwitchDelegate { + id: powerAvg5s + text: qsTr("Power Average 5 sec.") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.power_avg_5s + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.power_avg_5s = checked + } + + SwitchDelegate { + id: instantPowerOnPause + text: qsTr("Instant Power on Pause") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.instant_power_on_pause + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.instant_power_on_pause = checked + } + + RowLayout { + spacing: 10 + Label { + id: labelTreadmillInclinationOffset + text: qsTr("Zwift Inclination Offset:") Layout.fillWidth: true - onClicked: settings.power_avg_5s = checked } + TextField { + id: treadmillInclinationOffsetTextField + text: settings.zwift_inclination_offset + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.zwift_inclination_offset = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTreadmillInclinationOffsetButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.zwift_inclination_offset = treadmillInclinationOffsetTextField.text + } + } - SwitchDelegate { - id: instantPowerOnPause - text: qsTr("Instant Power on Pause") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.instant_power_on_pause - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + RowLayout { + spacing: 10 + Label { + id: labelTreadmillInclinationGain + text: qsTr("Zwift Inclination Gain:") Layout.fillWidth: true - onClicked: settings.instant_power_on_pause = checked } + TextField { + id: treadmillInclinationGainTextField + text: settings.zwift_inclination_gain + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.zwift_inclination_gain = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okTreadmillInclinationGainButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.zwift_inclination_gain = treadmillInclinationGainTextField.text + } + } + } + } - RowLayout { + AccordionElement { + id: accesoriesAccordion + title: qsTr("Accessories") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 10 + + AccordionElement { + id: cadenceSensorOptionsAccordion + title: qsTr("Cadence Sensor Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { spacing: 10 + Label { - id: labelTreadmillInclinationOffset - text: qsTr("Zwift Inclination Offset:") + id: cadenceSensorLabel + text: qsTr("Don't touch these settings if your bike works properly!") + font.bold: true + font.italic: true + font.pixelSize: 9 + textFormat: Text.PlainText + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + color: Material.color(Material.Red) + } + + SwitchDelegate { + id: cadenceSensorAsBikeDelegate + text: qsTr("Cadence Sensor as a Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.cadence_sensor_as_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true + onClicked: settings.cadence_sensor_as_bike = checked } - TextField { - id: treadmillInclinationOffsetTextField - text: settings.zwift_inclination_offset - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.zwift_inclination_offset = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + RowLayout { + spacing: 10 + Label { + id: labelCadenceSensorName + text: qsTr("Cadence Sensor:") + Layout.fillWidth: true + } + ComboBox { + id: cadenceSensorNameTextField + model: rootItem.bluetoothDevices + displayText: settings.cadence_sensor_name + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + cadenceSensorNameTextField.currentIndex) + displayText = cadenceSensorNameTextField.currentValue + } + + } + Button { + id: okCadenceSensorNameButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.cadence_sensor_name = cadenceSensorNameTextField.displayText; + } } + Button { - id: okTreadmillInclinationOffsetButton - text: "OK" + id: refreshCadenceSensorNameButton + text: "Refresh Devices List" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.zwift_inclination_offset = treadmillInclinationOffsetTextField.text + onClicked: refresh_bluetooth_devices_clicked(); + } + RowLayout { + spacing: 10 + Label { + id: labelCadenceSpeedRatio + text: qsTr("Wheel Ratio:") + Layout.fillWidth: true + } + TextField { + id: cadenceSpeedRatioTextField + text: settings.cadence_sensor_speed_ratio + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.cadence_sensor_speed_ratio = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okCadenceSpeedRatio + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.cadence_sensor_speed_ratio = cadenceSpeedRatioTextField.text + } } } + } - RowLayout { + AccordionElement { + id: powerSensorOptionsAccordion + title: qsTr("Power Sensor Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { spacing: 10 - Label { - id: labelTreadmillInclinationGain - text: qsTr("Zwift Inclination Gain:") + SwitchDelegate { + id: powerSensorAsBikeDelegate + text: qsTr("Power Sensor as a Bike") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.power_sensor_as_bike + Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillWidth: true + onClicked: settings.power_sensor_as_bike = checked } - TextField { - id: treadmillInclinationGainTextField - text: settings.zwift_inclination_gain - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.zwift_inclination_gain = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + SwitchDelegate { + id: powerSensorAsTreadmillDelegate + text: qsTr("Power Sensor as a Treadmill") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.power_sensor_as_treadmill + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.power_sensor_as_treadmill = checked } - Button { - id: okTreadmillInclinationGainButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.zwift_inclination_gain = treadmillInclinationGainTextField.text + SwitchDelegate { + id: powerSensorRunCadenceDoubleDelegate + text: qsTr("Doubling Cadence for Run") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.powr_sensor_running_cadence_double + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.powr_sensor_running_cadence_double = checked } - } - } - } - - AccordionElement { - id: accesoriesAccordion - title: qsTr("Accessories") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 10 - AccordionElement { - id: cadenceSensorOptionsAccordion - title: qsTr("Cadence Sensor Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { + RowLayout { spacing: 10 - Label { - id: cadenceSensorLabel - text: qsTr("Don't touch these settings if your bike works properly!") - font.bold: true - font.italic: true - font.pixelSize: 9 - textFormat: Text.PlainText - wrapMode: Text.WordWrap - verticalAlignment: Text.AlignVCenter - color: Material.color(Material.Red) + id: labelPowerSensorName + text: qsTr("Power Sensor:") + Layout.fillWidth: true } + ComboBox { + id: powerSensorNameTextField + model: rootItem.bluetoothDevices + displayText: settings.power_sensor_name + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + powerSensorNameTextField.currentIndex) + displayText = powerSensorNameTextField.currentValue + } - SwitchDelegate { - id: cadenceSensorAsBikeDelegate - text: qsTr("Cadence Sensor as a Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.cadence_sensor_as_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.cadence_sensor_as_bike = checked } - RowLayout { + Button { + id: okPowerSensorNameButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.power_sensor_name = powerSensorNameTextField.displayText; + } + } + + Button { + id: refreshPowerSensorNameButton + text: "Refresh Devices List" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: refresh_bluetooth_devices_clicked(); + } + } + } + + AccordionElement { + id: eliteAccesoriesAccordion + title: qsTr("Elite™ Products") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 10 + AccordionElement { + id: eliteRizerOptionsAccordion + title: qsTr("Elite Rizer Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Blue) + color: Material.backgroundColor + accordionContent: ColumnLayout { spacing: 10 - Label { - id: labelCadenceSensorName - text: qsTr("Cadence Sensor:") - Layout.fillWidth: true - } - ComboBox { - id: cadenceSensorNameTextField - model: rootItem.bluetoothDevices - displayText: settings.cadence_sensor_name - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + cadenceSensorNameTextField.currentIndex) - displayText = cadenceSensorNameTextField.currentValue + RowLayout { + spacing: 10 + Label { + id: labelEliteRizerName + text: qsTr("Elite Rizer:") + Layout.fillWidth: true } + ComboBox { + id: eliteRizerNameTextField + model: rootItem.bluetoothDevices + displayText: settings.elite_rizer_name + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + eliteRizerNameTextField.currentIndex) + displayText = eliteRizerNameTextField.currentValue + } + } + Button { + id: okEliteRizerNameButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.elite_rizer_name = eliteRizerNameTextField.displayText; + } } + Button { - id: okCadenceSensorNameButton - text: "OK" + id: refreshEliteRizerNameButton + text: "Refresh Devices List" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.cadence_sensor_name = cadenceSensorNameTextField.displayText; + onClicked: refresh_bluetooth_devices_clicked(); } } - - Button { - id: refreshCadenceSensorNameButton - text: "Refresh Devices List" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: refresh_bluetooth_devices_clicked(); - } RowLayout { spacing: 10 Label { - id: labelCadenceSpeedRatio - text: qsTr("Wheel Ratio:") + id: labelEliteRizerGain + text: qsTr("Difficulty/Gain:") Layout.fillWidth: true } TextField { - id: cadenceSpeedRatioTextField - text: settings.cadence_sensor_speed_ratio + id: eliteRizerGainTextField + text: settings.elite_rizer_gain horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.cadence_sensor_speed_ratio = text + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.elite_rizer_gain = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okCadenceSpeedRatio + id: okEliteRizerGainButton text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.cadence_sensor_speed_ratio = cadenceSpeedRatioTextField.text + onClicked: settings.elite_rizer_gain = eliteRizerGainTextField.text } } } - } - - AccordionElement { - id: powerSensorOptionsAccordion - title: qsTr("Power Sensor Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 10 - SwitchDelegate { - id: powerSensorAsBikeDelegate - text: qsTr("Power Sensor as a Bike") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.power_sensor_as_bike - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.power_sensor_as_bike = checked - } - SwitchDelegate { - id: powerSensorAsTreadmillDelegate - text: qsTr("Power Sensor as a Treadmill") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.power_sensor_as_treadmill - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.power_sensor_as_treadmill = checked - } - SwitchDelegate { - id: powerSensorRunCadenceDoubleDelegate - text: qsTr("Doubling Cadence for Run") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.powr_sensor_running_cadence_double - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.powr_sensor_running_cadence_double = checked - } - - RowLayout { + AccordionElement { + id: eliteSterzoSmartOptionsAccordion + title: qsTr("Elite Sterzo Smart Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Blue) + color: Material.backgroundColor + accordionContent: ColumnLayout { spacing: 10 - Label { - id: labelPowerSensorName - text: qsTr("Power Sensor:") - Layout.fillWidth: true - } - ComboBox { - id: powerSensorNameTextField - model: rootItem.bluetoothDevices - displayText: settings.power_sensor_name - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + powerSensorNameTextField.currentIndex) - displayText = powerSensorNameTextField.currentValue + RowLayout { + spacing: 10 + Label { + id: labelEliteSterzoSmartName + text: qsTr("Elite Sterzo Smart:") + Layout.fillWidth: true } + ComboBox { + id: eliteSterzoSmartNameTextField + model: rootItem.bluetoothDevices + displayText: settings.elite_sterzo_smart_name + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + eliteSterzoSmartNameTextField.currentIndex) + displayText = eliteSterzoSmartNameTextField.currentValue + } + } + Button { + id: okEliteSterzoSmartNameButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.elite_sterzo_smart_name = eliteSterzoSmartNameTextField.displayText; + } } + Button { - id: okPowerSensorNameButton - text: "OK" + id: refreshEliteSterzoSmartNameButton + text: "Refresh Devices List" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.power_sensor_name = powerSensorNameTextField.displayText; + onClicked: refresh_bluetooth_devices_clicked(); } } + } + } + } + + AccordionElement { + id: ftmsAccessoryOptionsAccordion + title: qsTr("SmartSpin2k Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + spacing: 10 + Label { + id: labelFTMSAccessoryName + text: qsTr("SmartSpin2k device:") + Layout.fillWidth: true + } + ComboBox { + id: ftmsAccessoryNameTextField + model: rootItem.bluetoothDevices + displayText: settings.ftms_accessory_name + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + ftmsAccessoryNameTextField.currentIndex) + displayText = ftmsAccessoryNameTextField.currentValue + } + } Button { - id: refreshPowerSensorNameButton - text: "Refresh Devices List" + id: okFTMSAccessoryNameButton + text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: refresh_bluetooth_devices_clicked(); + onClicked: settings.ftms_accessory_name = ftmsAccessoryNameTextField.displayText; } } - } - AccordionElement { - id: eliteAccesoriesAccordion - title: qsTr("Elite™ Products") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { + Button { + id: refreshFTMSAccessoryNameButton + text: "Refresh Devices List" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: refresh_bluetooth_devices_clicked(); + } + + RowLayout { spacing: 10 - AccordionElement { - id: eliteRizerOptionsAccordion - title: qsTr("Elite Rizer Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Blue) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 10 - RowLayout { - spacing: 10 - Label { - id: labelEliteRizerName - text: qsTr("Elite Rizer:") - Layout.fillWidth: true - } - ComboBox { - id: eliteRizerNameTextField - model: rootItem.bluetoothDevices - displayText: settings.elite_rizer_name - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + eliteRizerNameTextField.currentIndex) - displayText = eliteRizerNameTextField.currentValue - } + Label { + id: labelSS2KShiftStep + text: qsTr("Shift Step") + Layout.fillWidth: true + } + TextField { + id: ss2kShiftStepTextField + text: settings.ss2k_shift_step + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.ss2k_shift_step = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okSS2kShiftStep + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ss2k_shift_step = ss2kShiftStepTextField.text + } + } + RowLayout { + spacing: 10 + Label { + id: labelSS2KMaxResistance + text: qsTr("Max Resistance") + Layout.fillWidth: true + } + TextField { + id: ss2kMaxResistanceTextField + text: settings.ss2k_max_resistance + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.ss2k_max_resistance = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okSS2kMaxResistance + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ss2k_max_resistance = ss2kMaxResistanceTextField.text + } + } + RowLayout { + spacing: 10 + Label { + id: labelSS2KMinResistance + text: qsTr("Min Resistance") + Layout.fillWidth: true + } + TextField { + id: ss2kMinResistanceTextField + text: settings.ss2k_min_resistance + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.ss2k_min_resistance = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okSS2kMinResistance + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ss2k_min_resistance = ss2kMinResistanceTextField.text + } + } - } - Button { - id: okEliteRizerNameButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.elite_rizer_name = eliteRizerNameTextField.displayText; - } + AccordionElement { + id: ftmsAccessoryAdvancedOptionsAccordion + title: qsTr("Advanced SmartSpin2k Calibration") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Blue) + color: Material.backgroundColor + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + spacing: 10 + Label { + id: labelSS2KResistanceSample1 + text: qsTr("Resistance Sample 1") + Layout.fillWidth: true + } + TextField { + id: ss2kResistanceSample1TextField + text: settings.ss2k_resistance_sample_1 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.resistance_sample_1 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - Button { - id: refreshEliteRizerNameButton - text: "Refresh Devices List" + id: okSS2kResistanceSample1 + text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: refresh_bluetooth_devices_clicked(); + onClicked: settings.ss2k_resistance_sample_1 = ss2kResistanceSample1TextField.text } } RowLayout { - spacing: 10 Label { - id: labelEliteRizerGain - text: qsTr("Difficulty/Gain:") + id: labelSS2KShiftStepSample1 + text: qsTr("Shift Step Sample 1") Layout.fillWidth: true } TextField { - id: eliteRizerGainTextField - text: settings.elite_rizer_gain + id: ss2kShiftStepSample1TextField + text: settings.ss2k_shift_step_sample_1 horizontalAlignment: Text.AlignRight Layout.fillHeight: false Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - //inputMethodHints: Qt.ImhFormattedNumbersOnly - onAccepted: settings.elite_rizer_gain = text + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.ss2k_shift_step_sample_1 = text onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } Button { - id: okEliteRizerGainButton + id: okSS2kShiftStepSample1 text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.elite_rizer_gain = eliteRizerGainTextField.text + onClicked: settings.ss2k_shift_step_sample_1 = ss2kShiftStepSample1TextField.text } } - } - AccordionElement { - id: eliteSterzoSmartOptionsAccordion - title: qsTr("Elite Sterzo Smart Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Blue) - color: Material.backgroundColor - accordionContent: ColumnLayout { + RowLayout { spacing: 10 - RowLayout { - spacing: 10 - Label { - id: labelEliteSterzoSmartName - text: qsTr("Elite Sterzo Smart:") - Layout.fillWidth: true - } - ComboBox { - id: eliteSterzoSmartNameTextField - model: rootItem.bluetoothDevices - displayText: settings.elite_sterzo_smart_name - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + eliteSterzoSmartNameTextField.currentIndex) - displayText = eliteSterzoSmartNameTextField.currentValue - } - - } - Button { - id: okEliteSterzoSmartNameButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.elite_sterzo_smart_name = eliteSterzoSmartNameTextField.displayText; - } + Label { + id: labelSS2KResistanceSample2 + text: qsTr("Resistance Sample 2") + Layout.fillWidth: true + } + TextField { + id: ss2kResistanceSample2TextField + text: settings.ss2k_resistance_sample_2 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.resistance_sample_2 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - Button { - id: refreshEliteSterzoSmartNameButton - text: "Refresh Devices List" + id: okSS2kResistanceSample2 + text: "OK" Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: refresh_bluetooth_devices_clicked(); + onClicked: settings.ss2k_resistance_sample_2 = ss2kResistanceSample2TextField.text } } - } - } - } - - AccordionElement { - id: ftmsAccessoryOptionsAccordion - title: qsTr("SmartSpin2k Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor - accordionContent: ColumnLayout { - spacing: 10 - RowLayout { - spacing: 10 - Label { - id: labelFTMSAccessoryName - text: qsTr("SmartSpin2k device:") - Layout.fillWidth: true - } - ComboBox { - id: ftmsAccessoryNameTextField - model: rootItem.bluetoothDevices - displayText: settings.ftms_accessory_name - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + ftmsAccessoryNameTextField.currentIndex) - displayText = ftmsAccessoryNameTextField.currentValue + RowLayout { + Label { + id: labelSS2KShiftStepSample2 + text: qsTr("Shift Step Sample 2") + Layout.fillWidth: true + } + TextField { + id: ss2kShiftStepSample2TextField + text: settings.ss2k_shift_step_sample_2 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.ss2k_shift_step_sample_2 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okSS2kShiftStepSample2 + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ss2k_shift_step_sample_2 = ss2kShiftStepSample2TextField.text } - - } - Button { - id: okFTMSAccessoryNameButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ftms_accessory_name = ftmsAccessoryNameTextField.displayText; - } - } - - Button { - id: refreshFTMSAccessoryNameButton - text: "Refresh Devices List" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: refresh_bluetooth_devices_clicked(); - } - - RowLayout { - spacing: 10 - Label { - id: labelSS2KShiftStep - text: qsTr("Shift Step") - Layout.fillWidth: true - } - TextField { - id: ss2kShiftStepTextField - text: settings.ss2k_shift_step - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.ss2k_shift_step = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kShiftStep - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_shift_step = ss2kShiftStepTextField.text - } - } - RowLayout { - spacing: 10 - Label { - id: labelSS2KMaxResistance - text: qsTr("Max Resistance") - Layout.fillWidth: true - } - TextField { - id: ss2kMaxResistanceTextField - text: settings.ss2k_max_resistance - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.ss2k_max_resistance = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kMaxResistance - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_max_resistance = ss2kMaxResistanceTextField.text - } - } - RowLayout { - spacing: 10 - Label { - id: labelSS2KMinResistance - text: qsTr("Min Resistance") - Layout.fillWidth: true - } - TextField { - id: ss2kMinResistanceTextField - text: settings.ss2k_min_resistance - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.ss2k_min_resistance = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kMinResistance - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_min_resistance = ss2kMinResistanceTextField.text } - } - - AccordionElement { - id: ftmsAccessoryAdvancedOptionsAccordion - title: qsTr("Advanced SmartSpin2k Calibration") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Blue) - color: Material.backgroundColor - accordionContent: ColumnLayout { + RowLayout { spacing: 10 - RowLayout { - spacing: 10 - Label { - id: labelSS2KResistanceSample1 - text: qsTr("Resistance Sample 1") - Layout.fillWidth: true - } - TextField { - id: ss2kResistanceSample1TextField - text: settings.ss2k_resistance_sample_1 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.resistance_sample_1 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kResistanceSample1 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_resistance_sample_1 = ss2kResistanceSample1TextField.text - } + Label { + id: labelSS2KResistanceSample3 + text: qsTr("Resistance Sample 3") + Layout.fillWidth: true } - RowLayout { - Label { - id: labelSS2KShiftStepSample1 - text: qsTr("Shift Step Sample 1") - Layout.fillWidth: true - } - TextField { - id: ss2kShiftStepSample1TextField - text: settings.ss2k_shift_step_sample_1 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.ss2k_shift_step_sample_1 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kShiftStepSample1 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_shift_step_sample_1 = ss2kShiftStepSample1TextField.text - } + TextField { + id: ss2kResistanceSample3TextField + text: settings.ss2k_resistance_sample_3 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.resistance_sample_3 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - RowLayout { - spacing: 10 - Label { - id: labelSS2KResistanceSample2 - text: qsTr("Resistance Sample 2") - Layout.fillWidth: true - } - TextField { - id: ss2kResistanceSample2TextField - text: settings.ss2k_resistance_sample_2 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.resistance_sample_2 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kResistanceSample2 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_resistance_sample_2 = ss2kResistanceSample2TextField.text - } + Button { + id: okSS2kResistanceSample3 + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ss2k_resistance_sample_3 = ss2kResistanceSample3TextField.text } - RowLayout { - Label { - id: labelSS2KShiftStepSample2 - text: qsTr("Shift Step Sample 2") - Layout.fillWidth: true - } - TextField { - id: ss2kShiftStepSample2TextField - text: settings.ss2k_shift_step_sample_2 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.ss2k_shift_step_sample_2 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kShiftStepSample2 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_shift_step_sample_2 = ss2kShiftStepSample2TextField.text - } + } + RowLayout { + Label { + id: labelSS2KShiftStepSample3 + text: qsTr("Shift Step Sample 3") + Layout.fillWidth: true } - RowLayout { - spacing: 10 - Label { - id: labelSS2KResistanceSample3 - text: qsTr("Resistance Sample 3") - Layout.fillWidth: true - } - TextField { - id: ss2kResistanceSample3TextField - text: settings.ss2k_resistance_sample_3 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.resistance_sample_3 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kResistanceSample3 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_resistance_sample_3 = ss2kResistanceSample3TextField.text - } + TextField { + id: ss2kShiftStepSample3TextField + text: settings.ss2k_shift_step_sample_3 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.ss2k_shift_step_sample_3 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length } - RowLayout { - Label { - id: labelSS2KShiftStepSample3 - text: qsTr("Shift Step Sample 3") - Layout.fillWidth: true - } - TextField { - id: ss2kShiftStepSample3TextField - text: settings.ss2k_shift_step_sample_3 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.ss2k_shift_step_sample_3 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kShiftStepSample3 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_shift_step_sample_3 = ss2kShiftStepSample3TextField.text - } + Button { + id: okSS2kShiftStepSample3 + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ss2k_shift_step_sample_3 = ss2kShiftStepSample3TextField.text } - RowLayout { - spacing: 10 - Label { - id: labelSS2KResistanceSample4 - text: qsTr("Resistance Sample 4") - Layout.fillWidth: true - } - TextField { - id: ss2kResistanceSample4TextField - text: settings.ss2k_resistance_sample_4 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.resistance_sample_4 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kResistanceSample4 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_resistance_sample_4 = ss2kResistanceSample4TextField.text - } + } + RowLayout { + spacing: 10 + Label { + id: labelSS2KResistanceSample4 + text: qsTr("Resistance Sample 4") + Layout.fillWidth: true } - RowLayout { - Label { - id: labelSS2KShiftStepSample4 - text: qsTr("Shift Step Sample 4") - Layout.fillWidth: true - } - TextField { - id: ss2kShiftStepSample4TextField - text: settings.ss2k_shift_step_sample_4 - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.ss2k_shift_step_sample_4 = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okSS2kShiftStepSample4 - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.ss2k_shift_step_sample_4 = ss2kShiftStepSample4TextField.text - } + TextField { + id: ss2kResistanceSample4TextField + text: settings.ss2k_resistance_sample_4 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.resistance_sample_4 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okSS2kResistanceSample4 + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ss2k_resistance_sample_4 = ss2kResistanceSample4TextField.text + } + } + RowLayout { + Label { + id: labelSS2KShiftStepSample4 + text: qsTr("Shift Step Sample 4") + Layout.fillWidth: true + } + TextField { + id: ss2kShiftStepSample4TextField + text: settings.ss2k_shift_step_sample_4 + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.ss2k_shift_step_sample_4 = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okSS2kShiftStepSample4 + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.ss2k_shift_step_sample_4 = ss2kShiftStepSample4TextField.text } } } } } + } - AccordionElement { - id: fitmetriaFanFitOptionsAccordion - title: qsTr("Fitmetria Fitfan™ Options") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Yellow) - color: Material.backgroundColor + AccordionElement { + id: fitmetriaFanFitOptionsAccordion + title: qsTr("Fitmetria Fitfan™ Options") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Yellow) + color: Material.backgroundColor - accordionContent: ColumnLayout { + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: fitmetriaFanFitDelegate + text: qsTr("Enable") spacing: 0 - SwitchDelegate { - id: fitmetriaFanFitDelegate - text: qsTr("Enable") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.fitmetria_fanfit_enable - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.fitmetria_fanfit_enable + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.fitmetria_fanfit_enable = checked + } + + RowLayout { + spacing: 10 + Label { + id: labelFitmetriaFanFitMode + text: qsTr("Mode:") Layout.fillWidth: true - onClicked: settings.fitmetria_fanfit_enable = checked } - - RowLayout { - spacing: 10 - Label { - id: labelFitmetriaFanFitMode - text: qsTr("Mode:") - Layout.fillWidth: true + ComboBox { + id: fitmetriaFanFitModeTextField + model: [ "Heart", "Power", "Manual" ] + displayText: settings.fitmetria_fanfit_mode + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + fitmetriaFanFitModeTextField.currentIndex) + displayText = fitmetriaFanFitModeTextField.currentValue } - ComboBox { - id: fitmetriaFanFitModeTextField - model: [ "Heart", "Power", "Manual" ] - displayText: settings.fitmetria_fanfit_mode - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + fitmetriaFanFitModeTextField.currentIndex) - displayText = fitmetriaFanFitModeTextField.currentValue - } - } - Button { - id: okFitmetriaFanFitModeTextField - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.fitmetria_fanfit_mode = fitmetriaFanFitModeTextField.displayText - } } - RowLayout { - spacing: 10 - Label { - id: labelFitmetriaFanFitMin - text: qsTr("Min. value (0-100):") - Layout.fillWidth: true - } - TextField { - id: fitmetriaFanFitMinTextField - text: settings.fitmetria_fanfit_min - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.fitmetria_fanfit_min = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okFitmetriaFanFitMin - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.fitmetria_fanfit_min = fitmetriaFanFitMinTextField.text - } + Button { + id: okFitmetriaFanFitModeTextField + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.fitmetria_fanfit_mode = fitmetriaFanFitModeTextField.displayText } - RowLayout { - spacing: 10 - Label { - id: labelFitmetriaFanFitMax - text: qsTr("Max value (0-100):") - Layout.fillWidth: true - } - TextField { - id: fitmetriaFanFitMaxTextField - text: settings.fitmetria_fanfit_max - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.fitmetria_fanfit_max = text - onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length - } - Button { - id: okFitmetriaFanFitMax - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.fitmetria_fanfit_max = fitmetriaFanFitMaxTextField.text - } + } + RowLayout { + spacing: 10 + Label { + id: labelFitmetriaFanFitMin + text: qsTr("Min. value (0-100):") + Layout.fillWidth: true + } + TextField { + id: fitmetriaFanFitMinTextField + text: settings.fitmetria_fanfit_min + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.fitmetria_fanfit_min = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okFitmetriaFanFitMin + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.fitmetria_fanfit_min = fitmetriaFanFitMinTextField.text + } + } + RowLayout { + spacing: 10 + Label { + id: labelFitmetriaFanFitMax + text: qsTr("Max value (0-100):") + Layout.fillWidth: true + } + TextField { + id: fitmetriaFanFitMaxTextField + text: settings.fitmetria_fanfit_max + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.fitmetria_fanfit_max = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okFitmetriaFanFitMax + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.fitmetria_fanfit_max = fitmetriaFanFitMaxTextField.text } } } } } + } - NewPageElement { - id: labelTTSSettings - title: qsTr("TTS (Text to Speech) Settings 🔊") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - accordionContent: "settings-tts.qml" - } + NewPageElement { + id: labelTTSSettings + title: qsTr("TTS (Text to Speech) Settings 🔊") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + accordionContent: "settings-tts.qml" + } - AccordionElement { - id: mapsAccordion - title: qsTr("Maps 🗺️") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { - spacing: 10 - Label { - id: labelMapsType - text: qsTr("Maps Type:") - Layout.fillWidth: true + AccordionElement { + id: mapsAccordion + title: qsTr("Maps 🗺️") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 + RowLayout { + spacing: 10 + Label { + id: labelMapsType + text: qsTr("Maps Type:") + Layout.fillWidth: true + } + ComboBox { + id: mapsTypeTextField + model: [ "2D", "3D" ] + displayText: settings.maps_type + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + console.log("combomodel activated" + mapsTypeTextField.currentIndex) + displayText = mapsTypeTextField.currentValue } - ComboBox { - id: mapsTypeTextField - model: [ "2D", "3D" ] - displayText: settings.maps_type - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - console.log("combomodel activated" + mapsTypeTextField.currentIndex) - displayText = mapsTypeTextField.currentValue - } - } - Button { - id: okMapsType - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.maps_type = mapsTypeTextField.displayText - } } + Button { + id: okMapsType + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.maps_type = mapsTypeTextField.displayText + } + } + } + } + + AccordionElement { + id: experimentalFeatureAccordion + title: qsTr("Experimental Features") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + //width: 640 + //anchors.top: acc1.bottom + //anchors.topMargin: 10 + accordionContent: ColumnLayout { + spacing: 0 + SwitchDelegate { + id: bluetoothRelaxedDelegate + text: qsTr("Relaxed Bluetooth for mad devices") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.bluetooth_relaxed + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.bluetooth_relaxed = checked + } + + SwitchDelegate { + id: bluetooth30mHangsDelegate + text: qsTr("Bluetooth hangs after 30m") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.bluetooth_30m_hangs + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.bluetooth_30m_hangs = checked } - } - AccordionElement { - id: experimentalFeatureAccordion - title: qsTr("Experimental Features") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { + SwitchDelegate { + id: batteryServiceDelegate + text: qsTr("Simulate Battery Service") spacing: 0 - SwitchDelegate { - id: bluetoothRelaxedDelegate - text: qsTr("Relaxed Bluetooth for mad devices") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.bluetooth_relaxed - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.bluetooth_relaxed = checked - } - - SwitchDelegate { - id: bluetooth30mHangsDelegate - text: qsTr("Bluetooth hangs after 30m") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.bluetooth_30m_hangs - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.bluetooth_30m_hangs = checked - } - - SwitchDelegate { - id: batteryServiceDelegate - text: qsTr("Simulate Battery Service") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.battery_service - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.battery_service = checked - } - /* + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.battery_service + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.battery_service = checked + } + /* SwitchDelegate { id: serviceChangedDelegate text: qsTr("Service Changed Service") @@ -6477,301 +6438,301 @@ import Qt.labs.settings 1.0 onClicked: settings.service_changed = checked } */ - AccordionCheckElement { - id: virtualDeviceAccordion - title: qsTr("Enable Virtual Device") - linkedBoolSetting: "virtual_device_enabled" - settings: settings - accordionContent: ColumnLayout { - AccordionCheckElement { - id: virtualBeviceBluetoothAccordion - title: qsTr("Virtual Device Bluetooth") - linkedBoolSetting: "virtual_device_bluetooth" - settings: settings - accordionContent: ColumnLayout { - SwitchDelegate { - id: virtualDeviceOnlyHeartDelegate - text: qsTr("Virtual Heart Only") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.virtual_device_onlyheart - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.virtual_device_onlyheart = checked - } - SwitchDelegate { - id: virtualDeviceEchelonDelegate - text: qsTr("Virtual Echelon") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.virtual_device_echelon - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.virtual_device_echelon = checked - } + AccordionCheckElement { + id: virtualDeviceAccordion + title: qsTr("Enable Virtual Device") + linkedBoolSetting: "virtual_device_enabled" + settings: settings + accordionContent: ColumnLayout { + AccordionCheckElement { + id: virtualBeviceBluetoothAccordion + title: qsTr("Virtual Device Bluetooth") + linkedBoolSetting: "virtual_device_bluetooth" + settings: settings + accordionContent: ColumnLayout { + SwitchDelegate { + id: virtualDeviceOnlyHeartDelegate + text: qsTr("Virtual Heart Only") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.virtual_device_onlyheart + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.virtual_device_onlyheart = checked + } + SwitchDelegate { + id: virtualDeviceEchelonDelegate + text: qsTr("Virtual Echelon") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.virtual_device_echelon + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.virtual_device_echelon = checked + } - SwitchDelegate { - id: virtualDeviceRowerDelegate - text: qsTr("Virtual Rower") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.virtual_device_rower - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.virtual_device_rower = checked - } - SwitchDelegate { - id: virtualBikeForceResistanceDelegate - text: qsTr("Zwift Force Resistance") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.virtualbike_forceresistance - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.virtualbike_forceresistance = checked - } + SwitchDelegate { + id: virtualDeviceRowerDelegate + text: qsTr("Virtual Rower") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.virtual_device_rower + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.virtual_device_rower = checked + } + SwitchDelegate { + id: virtualBikeForceResistanceDelegate + text: qsTr("Zwift Force Resistance") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.virtualbike_forceresistance + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.virtualbike_forceresistance = checked + } - SwitchDelegate { - id: bikePowerSensorDelegate - text: qsTr("Bike Power Sensor") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.bike_power_sensor - Layout.alignment: Qt.AlignLeft | Qt.AlignTop + SwitchDelegate { + id: bikePowerSensorDelegate + text: qsTr("Bike Power Sensor") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.bike_power_sensor + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.bike_power_sensor = checked + } + SwitchDelegate { + id: virtualDeviceIfitDelegate + text: qsTr("Virtual iFit") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.virtual_device_ifit + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.virtual_device_ifit = checked + } + } + } + AccordionCheckElement { + id: dirconAccordion + title: qsTr("Wahoo direct connect") + linkedBoolSetting: "dircon_yes" + settings: settings + accordionContent: ColumnLayout { + spacing: 0 + RowLayout { + spacing: 10 + Label { + id: labelDirconServerPort + text: qsTr("Server Port:") Layout.fillWidth: true - onClicked: settings.bike_power_sensor = checked } - SwitchDelegate { - id: virtualDeviceIfitDelegate - text: qsTr("Virtual iFit") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.virtual_device_ifit - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.virtual_device_ifit = checked + TextField { + id: dirconServerPortTextField + text: settings.dircon_server_base_port + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + onAccepted: settings.dircon_server_base_port = text } - } - } - AccordionCheckElement { - id: dirconAccordion - title: qsTr("Wahoo direct connect") - linkedBoolSetting: "dircon_yes" - settings: settings - accordionContent: ColumnLayout { - spacing: 0 - RowLayout { - spacing: 10 - Label { - id: labelDirconServerPort - text: qsTr("Server Port:") - Layout.fillWidth: true - } - TextField { - id: dirconServerPortTextField - text: settings.dircon_server_base_port - horizontalAlignment: Text.AlignRight - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - inputMethodHints: Qt.ImhDigitsOnly - onAccepted: settings.dircon_server_base_port = text - } - Button { - id: okDirconServerPort - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.dircon_server_base_port = dirconServerPortTextField.text - } + Button { + id: okDirconServerPort + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.dircon_server_base_port = dirconServerPortTextField.text } } } } } + } - SwitchDelegate { - id: runCadenceSensorDelegate - text: qsTr("Run Cadence Sensor") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.run_cadence_sensor - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.run_cadence_sensor = checked - } - - AccordionElement { - id: templateSettingsAccordion - title: qsTr("Template Settings") - indicatRectColor: Material.color(Material.Grey) - textColor: Material.color(Material.Grey) - color: Material.backgroundColor - accordionContent: ColumnLayout { - id: templateSettingsContent - } - Component.onCompleted: function() { - let template_ids = settings.value("template_user_ids", []); - console.log("template_ids current val "+template_ids); - if (template_ids) { - let accordionCheckComponent = Qt.createComponent("AccordionCheckElement.qml"); - let componentMap = {}; - template_ids.forEach(function(template_id) { - console.log("template_id current "+template_id); - let template_type = settings.value("template_" + template_id + "_type", ""); - if (template_type) { - console.log("template_type current "+template_type); - if (!componentMap[template_type]) - componentMap[template_type] = Qt.createComponent("Template" + template_type + ".qml"); - let component = componentMap[template_type]; - if (component) { - let key_enabled = "template_" + template_id + "_enabled"; - console.log("Creating component object for id "+template_id); - let template_object = component.createObject(null, - { - settings: settings, - templateId: template_id - }); - let accordionCheck = accordionCheckComponent.createObject(templateSettingsContent, - { - title: template_id +" (" + template_type +")", - settings: settings, - linkedBoolSetting: key_enabled, - accordionContent: template_object - }); - } + SwitchDelegate { + id: runCadenceSensorDelegate + text: qsTr("Run Cadence Sensor") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.run_cadence_sensor + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.run_cadence_sensor = checked + } + + AccordionElement { + id: templateSettingsAccordion + title: qsTr("Template Settings") + indicatRectColor: Material.color(Material.Grey) + textColor: Material.color(Material.Grey) + color: Material.backgroundColor + accordionContent: ColumnLayout { + id: templateSettingsContent + } + Component.onCompleted: function() { + let template_ids = settings.value("template_user_ids", []); + console.log("template_ids current val "+template_ids); + if (template_ids) { + let accordionCheckComponent = Qt.createComponent("AccordionCheckElement.qml"); + let componentMap = {}; + template_ids.forEach(function(template_id) { + console.log("template_id current "+template_id); + let template_type = settings.value("template_" + template_id + "_type", ""); + if (template_type) { + console.log("template_type current "+template_type); + if (!componentMap[template_type]) + componentMap[template_type] = Qt.createComponent("Template" + template_type + ".qml"); + let component = componentMap[template_type]; + if (component) { + let key_enabled = "template_" + template_id + "_enabled"; + console.log("Creating component object for id "+template_id); + let template_object = component.createObject(null, + { + settings: settings, + templateId: template_id + }); + let accordionCheck = accordionCheckComponent.createObject(templateSettingsContent, + { + title: template_id +" (" + template_type +")", + settings: settings, + linkedBoolSetting: key_enabled, + accordionContent: template_object + }); } - }); - } + } + }); } } + } - SwitchDelegate { - id: androidWakeLockDelegate - text: qsTr("Android WakeLock") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.android_wakelock - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.android_wakelock = checked - } + SwitchDelegate { + id: androidWakeLockDelegate + text: qsTr("Android WakeLock") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.android_wakelock + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.android_wakelock = checked + } - SwitchDelegate { - id: iosPelotonWorkaroundDelegate - text: qsTr("iOS Peloton Workaround") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.ios_peloton_workaround - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.ios_peloton_workaround = checked - } + SwitchDelegate { + id: iosPelotonWorkaroundDelegate + text: qsTr("iOS Peloton Workaround") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.ios_peloton_workaround + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.ios_peloton_workaround = checked + } - SwitchDelegate { - id: appleWatchFakeDeviceDelegate - text: qsTr("Fake Device") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.applewatch_fakedevice - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.applewatch_fakedevice = checked - } + SwitchDelegate { + id: appleWatchFakeDeviceDelegate + text: qsTr("Fake Device") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.applewatch_fakedevice + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.applewatch_fakedevice = checked + } - SwitchDelegate { - id: fakeEllipticalDelegate - text: qsTr("Fake Elliptical") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.fakedevice_elliptical - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.fakedevice_elliptical = checked - } + SwitchDelegate { + id: fakeEllipticalDelegate + text: qsTr("Fake Elliptical") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.fakedevice_elliptical + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.fakedevice_elliptical = checked + } - SwitchDelegate { - id: appleHeartCacheDelegate - text: qsTr("iOS Heart Caching") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.ios_cache_heart_device - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.ios_cache_heart_device = checked - } + SwitchDelegate { + id: appleHeartCacheDelegate + text: qsTr("iOS Heart Caching") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.ios_cache_heart_device + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.ios_cache_heart_device = checked + } - SwitchDelegate { - id: logDebugDelegate - text: qsTr("Debug Log") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.log_debug - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.log_debug = checked - } + SwitchDelegate { + id: logDebugDelegate + text: qsTr("Debug Log") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.log_debug + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.log_debug = checked + } - Button { - id: clearLogs - text: "Clear History" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: rootItem.clearFiles(); - } + Button { + id: clearLogs + text: "Clear History" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: rootItem.clearFiles(); } } } } +} /*##^## Designer { D{i:0;formeditorZoom:0.6600000262260437} diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index cf9cddba8..69efd8c7f 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -93,6 +93,8 @@ bool trixterxdreamv1bike::connect(QString portName) { qDebug() << "Failed to start settings update timer. Too bad."; } + this->configureVirtualBike(); + return true; } @@ -114,6 +116,42 @@ void trixterxdreamv1bike::disconnectPort() { } } +void trixterxdreamv1bike::configureVirtualBike(){ +// ******************************************* virtual bike init ************************************* + + bool haveVirtualBike = this->virtualBike!=nullptr; + + #ifdef Q_OS_IOS + #ifndef IO_UNDER_QT + haveVirtualBike &= !h; + #endif + #endif + + if(!haveVirtualBike){ + QSettings settings; + bool virtual_device_enabled = settings.value(QStringLiteral("virtual_device_enabled"), true).toBool(); + + #ifdef Q_OS_IOS + #ifndef IO_UNDER_QT + bool cadence = settings.value("bike_cadence_sensor", false).toBool(); + bool ios_peloton_workaround = settings.value("ios_peloton_workaround", true).toBool(); + if (ios_peloton_workaround && cadence) { + qDebug() << "ios_peloton_workaround activated!"; + h = new lockscreen(); + h->virtualbike_ios(); + } else + #endif + #endif + if (virtual_device_enabled) { + qDebug() << QStringLiteral("creating virtual bike interface..."); + this->virtualBike = new virtualbike(this, noWriteResistance, noHeartService); + } + } + +// ******************************************************************************************************** +} + + bool trixterxdreamv1bike::connected() { return (this->getTime()-this->lastPacketProcessedTime) < DisconnectionTimeout; } @@ -206,33 +244,43 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { void trixterxdreamv1bike::calculateSteeringMap() { - constexpr double maxSteeringAngle = 45.0; - constexpr int maxSteering = trixterxdreamv1client::MaxSteering; - this->steeringMap.clear(); + trixterxdreamv1settings::steeringCalibrationInfo info = this->appSettings->get_steeringCalibration(); - int steeringCenterOffset = round(0.5+this->appSettings->get_steeringCenterOffsetPercentage()*maxSteering*0.01); - int steeringCenter = maxSteering / 2 + steeringCenterOffset; - int halfDeadZone = this->appSettings->get_steeringDeadZoneWidthPercentage() * maxSteering * 0.005; - int deadZoneLeft = steeringCenter-halfDeadZone; - int deadZoneRight = steeringCenter+halfDeadZone; - double sensitivityLeft = 0.01 * this->appSettings->get_steeringSensitivityLeft(); - double sensitivityRight = 0.01 * this->appSettings->get_steeringSensitivityRight(); - double scaleLeft = sensitivityLeft * maxSteeringAngle / deadZoneLeft; - double scaleRight = sensitivityRight * maxSteeringAngle / (trixterxdreamv1client::MaxSteering - deadZoneRight); + vector newMap; + + // Map the calibration values from [-info.max,+info.max] to [0, 2*info.max] + double mid = info.max, max = 2*mid; + + double l = mid+info.left; + double cl = mid+info.centerLeft; + double cr = mid+info.centerRight; + double r = mid+info.right; + + double scale = max / trixterxdreamv1client::MaxSteering; + double scaleLeft = mid / (cl-l); + double scaleRight = mid / (r-cr); for(int i=0; i<=trixterxdreamv1client::MaxSteering; i++) { - double mappedValue; - if(i>=deadZoneLeft && i<=deadZoneRight) { - mappedValue = 0.0; - } else if (i=cl && mappedValue<=cr) { + mappedValue = mid; + } else if (mappedValue<=l) { + mappedValue = 0; + } else if (mappedValue>=r) { + mappedValue = max; + } else if(mappedValuesteeringMap.push_back(mappedValue); + mappedValue = std::max(0.0, std::min(max, mappedValue)); + newMap.push_back(mappedValue-mid); } + this->steeringMap=newMap; + } void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { @@ -261,6 +309,11 @@ void trixterxdreamv1bike::updateResistance() { trixterxdreamv1bike::~trixterxdreamv1bike() { if(this->port) delete this->port; if(this->appSettings) delete this->appSettings; + if(this->virtualBike) delete this->virtualBike; +} + +void *trixterxdreamv1bike::VirtualDevice() { + return this->virtualBike; } void trixterxdreamv1bike::set_wheelDiameter(double value) { diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 797814475..246725106 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -3,6 +3,7 @@ #include "trixterxdreamv1client.h" #include "trixterxdreamv1serial.h" #include "trixterxdreamv1settings.h" +#include "virtualbike.h" class trixterxdreamv1bike : public bike { @@ -25,6 +26,11 @@ class trixterxdreamv1bike : public bike */ trixterxdreamv1serial * port = nullptr; + /** + * @brief virtualBike The bridge to the client application. + */ + virtualbike * virtualBike = nullptr; + /** * @brief resistanceTimerId The id for identifying the resistance timer in void timerEvent(QEvent*). */ @@ -130,6 +136,11 @@ class trixterxdreamv1bike : public bike * the steering angles sent to the application. Uses the values in the appSettings field. */ void calculateSteeringMap(); + + /** + * @brief configureVirtualBike Set up the bridge to the client application. + */ + void configureVirtualBike(); protected: /** @@ -188,6 +199,12 @@ public Q_SLOTS: ~trixterxdreamv1bike(); + /** + * @brief VirtualDevice Virtual device + * @return + */ + void *VirtualDevice() override; + /** * @brief connect Attempt to connect to the specified port. * @param portName The name of the serial port to connect to. diff --git a/src/trixterxdreamv1settings.cpp b/src/trixterxdreamv1settings.cpp index 2712171a5..55fa786d9 100644 --- a/src/trixterxdreamv1settings.cpp +++ b/src/trixterxdreamv1settings.cpp @@ -3,10 +3,11 @@ const QString trixterxdreamv1settings::keys::Enabled = QStringLiteral("trixter_xdream_v1_bike"); const QString trixterxdreamv1settings::keys::HeartRateEnabled = QStringLiteral("trixter_xdream_v1_bike_heartrate_enabled"); const QString trixterxdreamv1settings::keys::SteeringEnabled = QStringLiteral("trixter_xdream_v1_bike_steering_enabled"); -const QString trixterxdreamv1settings::keys::SteeringCenterOffset = QStringLiteral("trixter_xdream_v1_bike_steering_center_offset"); -const QString trixterxdreamv1settings::keys::SteeringDeadZoneWidth =QStringLiteral("trixter_xdream_v1_bike_steering_deadzone_width"); -const QString trixterxdreamv1settings::keys::SteeringSensitivityLeft = QStringLiteral("trixter_xdream_v1_bike_steering_sensitivity_left"); -const QString trixterxdreamv1settings::keys::SteeringSensitivityRight= QStringLiteral("trixter_xdream_v1_bike_steering_sensitivity_right"); +const QString trixterxdreamv1settings::keys::SteeringCalibrationLeft = QStringLiteral("trixter_xdream_v1_bike_steering_L"); +const QString trixterxdreamv1settings::keys::SteeringCalibrationCenterLeft =QStringLiteral("trixter_xdream_v1_bike_steering_CL"); +const QString trixterxdreamv1settings::keys::SteeringCalibrationCenterRight = QStringLiteral("trixter_xdream_v1_bike_steering_CR"); +const QString trixterxdreamv1settings::keys::SteeringCalibrationRight = QStringLiteral("trixter_xdream_v1_bike_steering_R"); +const QString trixterxdreamv1settings::keys::SteeringCalibrationMAX = QStringLiteral("trixter_xdream_v1_bike_steering_MAX"); template @@ -52,45 +53,22 @@ bool trixterxdreamv1settings::set_steeringEnabled(bool value) { return this->updateField(this->steeringEnabled, value); } -int8_t trixterxdreamv1settings::get_steeringCenterOffsetPercentage() { +trixterxdreamv1settings::steeringCalibrationInfo trixterxdreamv1settings::get_steeringCalibration() { QMutexLocker locker(&this->mutex); - return this->steeringCenterOffsetPercentage; + return this->steeringCalibration; } -int8_t trixterxdreamv1settings::set_steeringCenterOffsetPercentage(int8_t value) { - auto newValue = clip((int8_t)-MaxSteeringCenterOffsetPercentage, MaxSteeringCenterOffsetPercentage, value); - return this->updateField(this->steeringCenterOffsetPercentage, newValue); -} - -uint8_t trixterxdreamv1settings::get_steeringDeadZoneWidthPercentage() { - QMutexLocker locker(&this->mutex); - return this->steeringDeadZoneWidthPercentage; -} - -uint8_t trixterxdreamv1settings::set_steeringDeadZoneWidthPercentage(uint8_t value) { - auto newValue = clip(MinSteeringDeadZoneWidthPercentage, MaxSteeringDeadZoneWidthPercentage, value); - return this->updateField(this->steeringDeadZoneWidthPercentage, newValue); -} - -uint8_t trixterxdreamv1settings::get_steeringSensitivityLeft() { - QMutexLocker locker(&this->mutex); - return this->steeringSensitivityLeft; -} - -uint8_t trixterxdreamv1settings::set_steeringSensitivityLeft(uint8_t value) { - auto newValue = clip(MinSteeringSensitivityPercentage, MaxSteeringSensitivityPercentage, value); - return this->updateField(this->steeringSensitivityLeft, newValue); -} +void trixterxdreamv1settings::set_steeringCalibration(const trixterxdreamv1settings::steeringCalibrationInfo value) { + if(!value.isValid()) + throw "Invalid argument."; -uint8_t trixterxdreamv1settings::get_steeringSensitivityRight() { QMutexLocker locker(&this->mutex); - return this->steeringSensitivityRight; + if(!(this->steeringCalibration==value)) { + this->steeringCalibration = value; + this->version++; + } } -uint8_t trixterxdreamv1settings::set_steeringSensitivityRight(uint8_t value) { - auto newValue = clip(MinSteeringSensitivityPercentage, MaxSteeringSensitivityPercentage, value); - return this->updateField(this->steeringSensitivityRight, newValue); -} trixterxdreamv1settings::trixterxdreamv1settings() { QSettings defaultSettings; @@ -113,10 +91,12 @@ void trixterxdreamv1settings::Load(const QSettings &settings) { this->set_enabled(settings.value(keys::Enabled, DefaultEnabled).toBool()); this->set_heartRateEnabled(settings.value(keys::HeartRateEnabled, DefaultHeartRateEnabled).toBool()); this->set_steeringEnabled(settings.value(keys::SteeringEnabled, DefaultSteeringEnabled).toBool()); - this->set_steeringCenterOffsetPercentage(settings.value(keys::SteeringCenterOffset, DefaultSteeringCenterOffsetPercentage).toUInt()); - this->set_steeringDeadZoneWidthPercentage(settings.value(keys::SteeringDeadZoneWidth, DefaultSteeringDeadZoneWidthPercentage).toUInt()); - this->set_steeringSensitivityLeft(settings.value(keys::SteeringSensitivityLeft, DefaultSteeringSensitivity).toUInt()); - this->set_steeringSensitivityRight(settings.value(keys::SteeringSensitivityRight, DefaultSteeringSensitivity).toUInt()); + + steeringCalibrationInfo sc(settings.value(keys::SteeringCalibrationLeft, DefaultSteeringCalibrationL).toInt(), + settings.value(keys::SteeringCalibrationCenterLeft, DefaultSteeringCalibrationCL).toInt(), + settings.value(keys::SteeringCalibrationCenterRight, DefaultSteeringCalibrationCR).toInt(), + settings.value(keys::SteeringCalibrationRight, DefaultSteeringCalibrationR).toInt()); + this->set_steeringCalibration(sc); } /* @@ -130,10 +110,7 @@ void trixterxdreamv1bikesettings::Save(const QSettings &settings) { settings.value(keys::Enabled).setValue(this->enabled); settings.value(keys::HeartRateEnabled).setValue(this->heartRateEnabled); settings.value(keys::SteeringEnabled).setValue(this->steeringEnabled); - settings.value(keys::SteeringCenter).setValue(this->steeringCenter); - settings.value(keys::SteeringDeadZoneWidth).setValue(this->steeringDeadZoneWidth); - settings.value(keys::SteeringSensitivityLeft).setValue(this->steeringSensitivityLeft); - settings.value(keys::SteeringSensitivityRight).setValue(this->steeringSensitivityRight); + } */ diff --git a/src/trixterxdreamv1settings.h b/src/trixterxdreamv1settings.h index c16476a96..629835a73 100644 --- a/src/trixterxdreamv1settings.h +++ b/src/trixterxdreamv1settings.h @@ -5,7 +5,7 @@ #include #include "qmutex.h" #include "qsettings.h" -#include "trixterxdreamv1client.h" + /** @@ -16,19 +16,14 @@ class trixterxdreamv1settings { public: // these should match the corresponding values in settings.qml // - the default values where the properties are defined - // - the validations on the text boxes + constexpr static int8_t MaxSteeringAngle = 45; constexpr static bool DefaultEnabled =true; constexpr static bool DefaultSteeringEnabled =true; constexpr static bool DefaultHeartRateEnabled =true; - constexpr static int8_t DefaultSteeringCenterOffsetPercentage = 0; - constexpr static uint8_t DefaultSteeringDeadZoneWidthPercentage = 5; - constexpr static uint8_t DefaultSteeringSensitivity = 100; - constexpr static int8_t MinSteeringCenterOffsetPercentage = 0; - constexpr static int8_t MaxSteeringCenterOffsetPercentage = 30; - constexpr static uint8_t MaxSteeringDeadZoneWidthPercentage = 50; - constexpr static uint8_t MinSteeringDeadZoneWidthPercentage = 0; - constexpr static uint8_t MinSteeringSensitivityPercentage = 20; - constexpr static uint8_t MaxSteeringSensitivityPercentage = 200; + constexpr static int8_t DefaultSteeringCalibrationL = -MaxSteeringAngle; + constexpr static int8_t DefaultSteeringCalibrationR = MaxSteeringAngle; + constexpr static int8_t DefaultSteeringCalibrationCL = -2; + constexpr static int8_t DefaultSteeringCalibrationCR = 2; /** * @brief Defines QSettings keys relating to the Trixter X-Dream V1 bike. @@ -41,10 +36,72 @@ class trixterxdreamv1settings { const static QString Enabled; const static QString HeartRateEnabled; const static QString SteeringEnabled; - const static QString SteeringCenterOffset; - const static QString SteeringDeadZoneWidth; - const static QString SteeringSensitivityLeft; - const static QString SteeringSensitivityRight; + const static QString SteeringCalibrationLeft; + const static QString SteeringCalibrationCenterLeft; + const static QString SteeringCalibrationCenterRight; + const static QString SteeringCalibrationRight; + const static QString SteeringCalibrationMAX; + }; + + struct steeringCalibrationInfo { + + public: + + /** + * @brief left The uncalibrated left turning angle that will be mapped to hard left. + */ + int8_t left; + + /** + * @brief centerLeft The lower uncalibrated left turning angle that will be mapped to 0. + */ + int8_t centerLeft; + + /** + * @brief centerRight The higest uncalibrated right turning angle that will be mapped to 0. + */ + int8_t centerRight; + + /** + * @brief right The uncalibrated right turning angle that will be mapped to hard right. + */ + int8_t right; + + /** + * @brief max The maximum turning angle. + */ + static const int8_t max = MaxSteeringAngle; + + /** + * @brief isValid Validates the record. + * @return True if the values are valid, false otherwise. + */ + bool isValid() const { + return left>=-max && leftisValid()) + throw "Arguments are out of range or out of order."; + } + + friend bool operator==(const steeringCalibrationInfo& lhs, const steeringCalibrationInfo& rhs) + { + return rhs.left==lhs.left && + rhs.right==lhs.right && + rhs.centerLeft==lhs.centerLeft && + rhs.centerRight==lhs.centerRight; + + } }; private: @@ -53,10 +110,9 @@ class trixterxdreamv1settings { bool enabled=DefaultEnabled; bool steeringEnabled = DefaultSteeringEnabled; bool heartRateEnabled = DefaultHeartRateEnabled; - int8_t steeringCenterOffsetPercentage = DefaultSteeringCenterOffsetPercentage; - uint8_t steeringDeadZoneWidthPercentage = DefaultSteeringDeadZoneWidthPercentage; - uint8_t steeringSensitivityLeft = DefaultSteeringSensitivity; - uint8_t steeringSensitivityRight = DefaultSteeringSensitivity; + + steeringCalibrationInfo steeringCalibration; + uint32_t version=0; /** @@ -78,6 +134,7 @@ class trixterxdreamv1settings { T updateField(T& member, const T newValue); public: + /** * @brief get_version Incremented if the values are modified. */ @@ -120,64 +177,15 @@ class trixterxdreamv1settings { bool set_steeringEnabled(bool value); /** - * @brief get_steeringCenter Gets the value considered to be the center position for the steering. - * Defaults to 0%, but in reality is somewhat different due to physical calibration. - */ - int8_t get_steeringCenterOffsetPercentage(); - - /** - * @brief set_steeringCenterOffsetPercentage Sets the steering center offset percentage. Used to accommodate - * the bike's calibration. - * @param value The value, will be clipped to [-MaxSteeringCenterOffsetPercentage, MaxSteeringCenterOffsetPercentage]. - * @return The actual value set. - */ - int8_t set_steeringCenterOffsetPercentage(int8_t value); - - /** - * @brief get_steeringDeadZoneWidthPercentage Gets the width of the dead zone as a percentage of the total range. - * This is the region from the left to the right of steering center for which the steering value will be mapped to 0 degrees. - */ - uint8_t get_steeringDeadZoneWidthPercentage(); - - /** - * @brief set_steeringDeadZoneWidthPercentage Sets the width, left to right, as a percentage of the total range, - * of the "dead zone" surrounding the steering center, for which the steering value will be mapped to 0 degrees. - * @param value The width, left to right, of the dead zone, as a percentage of the total range. - * Clipped to [MinSteeringDeadZoneWidthPercentage, MaxSteeringDeadZoneWidthPercentage]. - * @return + * @brief get_steeringCalibration Gets the values for steering calibration. */ - uint8_t set_steeringDeadZoneWidthPercentage(uint8_t value); + steeringCalibrationInfo get_steeringCalibration(); /** - * @brief get_steeringSensitivityLeft Gets the sensitivity, as a percentage for how sensitive the - * steering will be when turning left. - * @return - */ - uint8_t get_steeringSensitivityLeft(); - - /** - * @brief set_steeringSensitivityLeft Sets the sensitivity, as a percentage, for how sensitive the steering - * will be when turning left. - * @param value The value, a percentage clipped to [MinSteeringSensitivityPercentage, MaxSteeringSensitivityPercentage]. - * @return The actual value set. - */ - uint8_t set_steeringSensitivityLeft(uint8_t value); - - /** - * @brief get_steeringSensitivityLeft Gets the sensitivity, as a percentage for how sensitive the - * steering will be when turning right. Valid range 20 to 200. - * @return - */ - uint8_t get_steeringSensitivityRight(); - - - /** - * @brief set_steeringSensitivityRight Sets the sensitivity, as a percentage, for how sensitive the steering - * will be when turning right. - * @param value The value, a percentage clipped to [MinSteeringSensitivityPercentage, MaxSteeringSensitivityPercentage]. - * @return The actual value set. + * @brief set_steeringCalibration sets the values for steering calibration. + * @param value The calibraion values. */ - uint8_t set_steeringSensitivityRight(uint8_t value); + void set_steeringCalibration(const steeringCalibrationInfo value); /** * @brief trixterxdreamv1bikesettings Constructor, intializes from the default QSettings. From 0c1dca62329e15a2399e4da0ecebe752a7e120e5 Mon Sep 17 00:00:00 2001 From: David Mason Date: Fri, 12 Aug 2022 23:29:22 +0100 Subject: [PATCH 050/255] #855 added more thread syncing to attempt to avoid seg fault that occurs when sending resistance (possibly when the app is shutting down) --- src/trixterxdreamv1bike.cpp | 16 ++++++++++++---- src/trixterxdreamv1bike.h | 5 +++++ src/trixterxdreamv1serial.cpp | 9 +++++---- src/trixterxdreamv1serial.h | 6 ++---- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 69efd8c7f..507728ae3 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -35,9 +35,8 @@ bool trixterxdreamv1bike::connect(QString portName) { // This will be subtracted from further readings from getTime() to get an easier to look at number. this->t0 = getTime(); - auto thisObject = this; - // create the port object and connect it + auto thisObject = this; this->port = new trixterxdreamv1serial(this); this->port->set_receiveBytes([thisObject](const QByteArray& bytes)->void{thisObject->update(bytes);}); @@ -56,7 +55,7 @@ bool trixterxdreamv1bike::connect(QString portName) { stopWatch.start(); // open the port. This should be at 115200 bits per second. - if(!this->port->open(portName, QSerialPort::Baud115200, 1000)) { + if(!this->port->open(portName, QSerialPort::Baud115200)) { qDebug() << "Failed to open port, determined after " << stopWatch.elapsed() << "milliseconds"; return false; } @@ -153,6 +152,7 @@ void trixterxdreamv1bike::configureVirtualBike(){ bool trixterxdreamv1bike::connected() { + QMutexLocker locker(&this->updateMutex); return (this->getTime()-this->lastPacketProcessedTime) < DisconnectionTimeout; } @@ -185,6 +185,8 @@ bool trixterxdreamv1bike::updateClient(const QByteArray& bytes, trixterxdreamv1c } void trixterxdreamv1bike::update(const QByteArray &bytes) { + QMutexLocker locker(&this->updateMutex); + // send the bytes to the client and return if there's no change of state if(!updateClient(bytes, &this->client)) return; @@ -224,7 +226,7 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { if(this->noSteering) this->m_steeringAngle.setValue(0.0); else - this->calculateSteeringMap(); + QTimer::singleShot(10ms, this, &trixterxdreamv1bike::calculateSteeringMap); this->lastAppSettingsVersion = this->appSettings->get_version(); } @@ -279,6 +281,7 @@ void trixterxdreamv1bike::calculateSteeringMap() { newMap.push_back(mappedValue-mid); } + QMutexLocker locker(&this->updateMutex); this->steeringMap=newMap; } @@ -288,7 +291,9 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { if(this->noWriteResistance) return; + QMutexLocker locker(&this->updateMutex); // Clip the incoming values + if(resistanceLevel<0) resistanceLevel = 0; if(resistanceLevel>maxResistance()) resistanceLevel = maxResistance(); @@ -303,6 +308,7 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { } void trixterxdreamv1bike::updateResistance() { + QMutexLocker locker(&this->updateMutex); this->client.SendResistance(this->resistanceLevel); } @@ -317,6 +323,8 @@ void *trixterxdreamv1bike::VirtualDevice() { } void trixterxdreamv1bike::set_wheelDiameter(double value) { + QMutexLocker locker(&this->updateMutex); + // clip the value value = std::min(MaxWheelDiameter, std::max(value, MinWheelDiameter)); diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 246725106..7fe664902 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -107,6 +107,11 @@ class trixterxdreamv1bike : public bike */ std::vector steeringMap; + /** + * @brief updateMutex Used to synchronise updates to this object's members. + */ + QRecursiveMutex updateMutex; + /** * @brief getTime Gets the time in miliseconds since this object was created. */ diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 63ca30965..8f512cef2 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -16,7 +16,7 @@ QList trixterxdreamv1serial::availablePorts() { return QSerialPortInfo::availablePorts(); } -bool trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate baudRate, int waitTimeout) { +bool trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate baudRate) { QMutexLocker locker(&this->mutex); @@ -29,8 +29,6 @@ bool trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate this->portName = portName; this->baudRate = baudRate; - this->waitTimeout = waitTimeout; - if (!isRunning()) { @@ -96,12 +94,15 @@ void trixterxdreamv1serial::run() { QMutexLocker locker(&this->mutex); // try to read some bytes, but only block for 1ms because a write attempt could come in. - while (this->serial.waitForReadyRead(1)) + int quit = 0; + while (!(quit=this->quitPending) && this->serial.waitForReadyRead(1)) requestData += this->serial.readAll(); // release the mutex locker.unlock(); + if(quit) break; + if(requestData.length()>0) { qDebug() << "serial << " << requestData.toHex(' '); diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index 5c13ea4cf..48dd7570b 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -22,10 +22,9 @@ class trixterxdreamv1serial : public QThread { * @brief Opens the port. * @param portName The name of the serial port. * @param baudRate The baud rate. - * @param waitTimeout The timeout for the serial port. * @returns True if the port was opened, false if the port wasn't opened, or was already open. */ - bool open(const QString &portName, QSerialPort::BaudRate baudRate, int waitTimeout); + bool open(const QString &portName, QSerialPort::BaudRate baudRate); /** * @brief Writes the array of bytes to the serial port @@ -65,10 +64,9 @@ class trixterxdreamv1serial : public QThread { QSerialPort serial; QString portName; QSerialPort::BaudRate baudRate; - int waitTimeout = 1000; QMutex mutex; QAtomicInt openAttemptsPending{0}; - bool quitPending = false; + QAtomicInt quitPending{0}; std::function receiveBytes=nullptr; }; From 4c3d2ced94dcae18c717f4ef0e88b3e5ae7edf46 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 13 Aug 2022 00:05:53 +0100 Subject: [PATCH 051/255] #855 added Peloton resistance --- src/trixterxdreamv1bike.cpp | 11 ++++++++++- src/trixterxdreamv1bike.h | 7 +++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 507728ae3..114e82d18 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -292,8 +292,8 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { return; QMutexLocker locker(&this->updateMutex); - // Clip the incoming values + // Clip the incoming values if(resistanceLevel<0) resistanceLevel = 0; if(resistanceLevel>maxResistance()) resistanceLevel = maxResistance(); @@ -304,7 +304,10 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { this->resistanceLevel = resistanceLevel; // store the resistance level as a metric for the UI + constexpr double pelotonScaleFactor = 100.0 / trixterxdreamv1client::MaxResistance; this->Resistance.setValue(resistanceLevel); + this->m_pelotonResistance.setValue(round(pelotonScaleFactor * resistanceLevel)); + } void trixterxdreamv1bike::updateResistance() { @@ -332,6 +335,12 @@ void trixterxdreamv1bike::set_wheelDiameter(double value) { this->wheelCircumference = value * M_PI / 1000.0; } + +int trixterxdreamv1bike::pelotonToBikeResistance(int pelotonResistance) { + pelotonResistance = std::max(0, std::min(100, pelotonResistance)); + return round(0.01*pelotonResistance*trixterxdreamv1client::MaxResistance); +} + trixterxdreamv1bike * trixterxdreamv1bike::tryCreate(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, const QString &portName) { // first check if there's a port specified if(portName!=nullptr && !portName.isEmpty()) diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 7fe664902..f76360c4a 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -238,6 +238,13 @@ public Q_SLOTS: */ uint8_t maxResistance() override { return trixterxdreamv1client::MaxResistance; } + /** + * @brief pelotonToBikeResistance Map Peloton 0 to 100% resistance to the bike's range. + * @param pelotonResistance The Peloton resistance. Range: 0 to 100. + * @return The Trixter X-Dream V1 bike resistance. Range 0..250. + */ + int pelotonToBikeResistance(int pelotonResistance) override; + /** * @brief tryCreate Attempt to create an object to interact with an existing Trixter X-Dream V1 bike on a specific serial port, * or if the port is unspecified, any serial port. From 2e896e3d2d6f58765bdc09b4d5177595709a5ee7 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 13 Aug 2022 20:13:00 +0100 Subject: [PATCH 052/255] #855 moved detection of device to a rudimentary alternative discovery mechanism for non-bluetooth devices. Not thread safe. --- src/bluetooth.cpp | 111 +++++++++++++++++++++++------------- src/bluetooth.h | 22 ++++++- src/trixterxdreamv1bike.cpp | 4 ++ src/trixterxdreamv1bike.h | 5 -- 4 files changed, 96 insertions(+), 46 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 4341cf629..a08f684b0 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -15,10 +15,6 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc uint32_t pollDeviceTime, bool noConsole, bool testResistance, uint8_t bikeResistanceOffset, double bikeResistanceGain) { QSettings settings; - bool trx_route_key = settings.value(QStringLiteral("trx_route_key"), false).toBool(); - bool bh_spada_2 = settings.value(QStringLiteral("bh_spada_2"), false).toBool(); - bool technogym_myrun_treadmill_experimental = - settings.value(QStringLiteral("technogym_myrun_treadmill_experimental"), false).toBool(); QLoggingCategory::setFilterRules(QStringLiteral("qt.bluetooth* = true")); filterDevice = deviceName; @@ -48,6 +44,7 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc connectedAndDiscovered(); return; #endif + #if !defined(WIN32) && !defined(Q_OS_IOS) if (QBluetoothLocalDevice::allDevices().isEmpty()) { debug(QStringLiteral("no bluetooth dongle found!")); @@ -104,18 +101,48 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc } #endif -#ifndef Q_OS_IOS - if (!trx_route_key && !bh_spada_2 && !technogym_myrun_treadmill_experimental) -#endif - discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); -#ifndef Q_OS_IOS - else - discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::ClassicMethod | - QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); -#endif + this->startDiscovery(false); + } +} + +void bluetooth::nonBluetoothDeviceDiscovery() { + bluetoothdevice * nonBluetoothDevice = this->discoverNonBluetoothDevices(); + + if(nonBluetoothDevice) { + if(this->discoveryAgent) discoveryAgent->stop(); + this->userTemplateManager->start(nonBluetoothDevice); + this->innerTemplateManager->start(nonBluetoothDevice); + emit this->deviceConnected(nonBluetoothDevice->bluetoothDevice); + connect(nonBluetoothDevice, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); + this->connectedAndDiscovered(); } } +bluetoothdevice * bluetooth::discoverNonBluetoothDevices() { + QSettings settings; + + /* + Calling code expects the returned bluetoothdevice subclass object to have set fake bluetooth device info. + + Do this in the class constructor as follows: + 1. Go to a website and generate a Bluetooth UUID. + 2. Set bluetoothdevice::bluetoothDevice as follows, using the UUID you have obtained, and a user-friendly name. + + this->bluetoothDevice = + QBluetoothDeviceInfo(QBluetoothUuid {QStringLiteral("775f25bd-6636-4cdc-9398-839ae026be1d")}, "Device Name", 0); + */ + + // Try to connect to a Trixter X-Dream V1 bike if the setting is enabled. + this->trixterXDreamV1Bike = this->findTrixterXDreamV1Bike(settings); + if(this->trixterXDreamV1Bike) + return this->trixterXDreamV1Bike; + + // Test for other devices + + // nothing found + return nullptr; +} + bluetooth::~bluetooth() { /*if(device()) @@ -153,12 +180,11 @@ void bluetooth::finished() { powerSensorName.startsWith(QStringLiteral("Disabled")) && !power_as_bike && !power_as_treadmill; bool eliteRizerFound = eliteRizerName.startsWith(QStringLiteral("Disabled")); bool eliteSterzoSmartFound = eliteSterzoSmartName.startsWith(QStringLiteral("Disabled")); - bool trx_route_key = settings.value(QStringLiteral("trx_route_key"), false).toBool(); - bool bh_spada_2 = settings.value(QStringLiteral("bh_spada_2"), false).toBool(); + + bool heartRateBeltFound = heartRateBeltName.startsWith(QStringLiteral("Disabled")); bool ftmsAccessoryFound = ftmsAccessoryName.startsWith(QStringLiteral("Disabled")); - bool technogym_myrun_treadmill_experimental = - settings.value(QStringLiteral("technogym_myrun_treadmill_experimental"), false).toBool(); + // since i can have multiple fanfit i can't wait more because i don't have the full list of the fanfit // devices connected to QZ @@ -172,18 +198,36 @@ void bluetooth::finished() { forceHeartBeltOffForTimeout = true; } -#ifndef Q_OS_IOS - if (!trx_route_key && !bh_spada_2 && !technogym_myrun_treadmill_experimental) { -#endif - discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); -#ifndef Q_OS_IOS - } else { - discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::ClassicMethod | - QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); + this->startDiscovery(false); +} + +void bluetooth::startDiscovery(bool noMode) { + + if(noMode) + this->discoveryAgent->start(); + else { + #ifndef Q_OS_IOS + QSettings settings; + bool technogym_myrun_treadmill_experimental = + settings.value(QStringLiteral("technogym_myrun_treadmill_experimental"), false).toBool(); + bool trx_route_key = settings.value(QStringLiteral("trx_route_key"), false).toBool(); + bool bh_spada_2 = settings.value(QStringLiteral("bh_spada_2"), false).toBool(); + + if (!trx_route_key && !bh_spada_2 && !technogym_myrun_treadmill_experimental) { + #endif + discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); + #ifndef Q_OS_IOS + } else { + discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::ClassicMethod | + QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); + } + #endif } -#endif + + QTimer::singleShot(1, this, &bluetooth::nonBluetoothDeviceDiscovery); } + void bluetooth::canceled() { debug(QStringLiteral("BTLE scanning stops")); @@ -404,16 +448,6 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { qDebug() << device.deviceUuid(); #endif - // Try to connect to a Trixter X-Dream V1 bike if the setting is enabled. - this->trixterXDreamV1Bike = this->findTrixterXDreamV1Bike(settings); - if(this->trixterXDreamV1Bike) { - this->userTemplateManager->start(trixterXDreamV1Bike); - this->innerTemplateManager->start(trixterXDreamV1Bike); - emit this->deviceConnected(this->trixterXDreamV1Bike->bluetoothDeviceInfo); - this->connectedAndDiscovered(); - return; - } - if (onlyDiscover) return; @@ -1947,9 +1981,8 @@ void bluetooth::restart() { QSettings settings; if (onlyDiscover) { - onlyDiscover = false; - discoveryAgent->start(); + this->startDiscovery(true); return; } @@ -2389,7 +2422,7 @@ void bluetooth::restart() { delete trixterXDreamV1Bike; trixterXDreamV1Bike = nullptr; } - discoveryAgent->start(); + this->startDiscovery(true); } bluetoothdevice *bluetooth::device() { diff --git a/src/bluetooth.h b/src/bluetooth.h index 785e2a49a..651da8823 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -121,7 +121,24 @@ class bluetooth : public QObject, public SignalHandler { bool onlyDiscover = false; TemplateInfoSenderBuilder *getUserTemplateManager() const { return userTemplateManager; } TemplateInfoSenderBuilder *getInnerTemplateManager() const { return innerTemplateManager; } +protected: + /** + * @brief startDiscovery Start the Bluetooth docscovery agent and the thread that discovers non-bluetooth devices. + * @param noMode True to start the Bluetooth discovery agent with no options, false to start with options. + */ + void startDiscovery(bool noMode); + + /** + * @brief discoverNonBluetoothDevices Discover non-bluetooth devices and create an object for the first. + * @return An object for the first non-bluetooth device found. + */ + bluetoothdevice * discoverNonBluetoothDevices(); + /** + * @brief nonBluetoothDeviceDiscovery Called by the non-bluetooth discovery thread to identify using + * discoverNonBluetoothDevices() and connect non-Bluetooth devices. + */ + void nonBluetoothDeviceDiscovery(); private: TemplateInfoSenderBuilder *userTemplateManager = nullptr; TemplateInfoSenderBuilder *innerTemplateManager = nullptr; @@ -244,7 +261,7 @@ class bluetooth : public QObject, public SignalHandler { QTimer discoveryTimeout; #endif - signals: +signals: void deviceConnected(QBluetoothDeviceInfo b); void deviceFound(QString name); void searchingStop(); @@ -266,7 +283,8 @@ class bluetooth : public QObject, public SignalHandler { void inclinationChanged(double, double); void connectedAndDiscovered(); - signals: +signals: + }; #endif // BLUETOOTH_H diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 114e82d18..17e8b50ee 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -11,6 +11,10 @@ using namespace std; trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice) { + // Set the fake bluetooth device info + this->bluetoothDevice = + QBluetoothDeviceInfo(QBluetoothUuid {QStringLiteral("774f25bd-6636-4cdc-9398-839de026be1d")}, "Trixter X-Dream V1 Bike", 0); + // Set the wheel diameter for speed and distance calculations this->set_wheelDiameter(DefaultWheelDiameter); diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index f76360c4a..27329141d 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -189,11 +189,6 @@ public Q_SLOTS: */ constexpr static int32_t DisconnectionTimeout = 50; - /** - * @brief bluetoothDeviceInfo A QBluetoothDeviceInfo object for functions that need it. - */ - const QBluetoothDeviceInfo bluetoothDeviceInfo { QBluetoothUuid {QStringLiteral("774f25bd-6636-4cdc-9398-839de026be1d")}, "Trixter X-Dream V1 Bike", 0}; - /** * @brief trixterxdreamv1bike Constructor * @param noWriteResistance Option to avoid sending resistance to the device. From b3b124c9a90bc4766d5b21531451261e1c935d1b Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 13 Aug 2022 20:46:32 +0100 Subject: [PATCH 053/255] #855 made the discovery modes consistent due to comment in #889 --- src/bluetooth.cpp | 15 ++++++--------- src/bluetooth.h | 3 +-- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index a08f684b0..024b1e6aa 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -101,7 +101,7 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc } #endif - this->startDiscovery(false); + this->startDiscovery(); } } @@ -198,14 +198,11 @@ void bluetooth::finished() { forceHeartBeltOffForTimeout = true; } - this->startDiscovery(false); + this->startDiscovery(); } -void bluetooth::startDiscovery(bool noMode) { +void bluetooth::startDiscovery() { - if(noMode) - this->discoveryAgent->start(); - else { #ifndef Q_OS_IOS QSettings settings; bool technogym_myrun_treadmill_experimental = @@ -222,7 +219,7 @@ void bluetooth::startDiscovery(bool noMode) { QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); } #endif - } + QTimer::singleShot(1, this, &bluetooth::nonBluetoothDeviceDiscovery); } @@ -1982,7 +1979,7 @@ void bluetooth::restart() { if (onlyDiscover) { onlyDiscover = false; - this->startDiscovery(true); + this->startDiscovery(); return; } @@ -2422,7 +2419,7 @@ void bluetooth::restart() { delete trixterXDreamV1Bike; trixterXDreamV1Bike = nullptr; } - this->startDiscovery(true); + this->startDiscovery(); } bluetoothdevice *bluetooth::device() { diff --git a/src/bluetooth.h b/src/bluetooth.h index 651da8823..ea4275283 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -124,9 +124,8 @@ class bluetooth : public QObject, public SignalHandler { protected: /** * @brief startDiscovery Start the Bluetooth docscovery agent and the thread that discovers non-bluetooth devices. - * @param noMode True to start the Bluetooth discovery agent with no options, false to start with options. */ - void startDiscovery(bool noMode); + void startDiscovery(); /** * @brief discoverNonBluetoothDevices Discover non-bluetooth devices and create an object for the first. From d87c9bcf476597583a4554d916e87d9301ac3d2f Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 14 Aug 2022 11:22:53 +0100 Subject: [PATCH 054/255] #855 fixed typo --- src/bluetooth.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bluetooth.h b/src/bluetooth.h index ea4275283..a057d6892 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -123,7 +123,7 @@ class bluetooth : public QObject, public SignalHandler { TemplateInfoSenderBuilder *getInnerTemplateManager() const { return innerTemplateManager; } protected: /** - * @brief startDiscovery Start the Bluetooth docscovery agent and the thread that discovers non-bluetooth devices. + * @brief startDiscovery Start the Bluetooth discovery agent and the thread that discovers non-bluetooth devices. */ void startDiscovery(); From 92f661c10f26979b90e1f3a3152b44c1a420d334 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 14 Aug 2022 23:00:26 +0100 Subject: [PATCH 055/255] #855 emit the steeringCHanged signal. Don't delete the virtualBike in the destructor - this is done in bluetooth::restart. --- src/trixterxdreamv1bike.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 17e8b50ee..315c9ce5f 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -240,12 +240,21 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { this->Heart.setValue(state.HeartRate); // Set the steering + bool steeringAngleChanged = false; if(!this->noSteering) { - this->m_steeringAngle.setValue(this->steeringMap[state.Steering]); + double newValue = this->steeringMap[state.Steering]; + steeringAngleChanged = this->m_steeringAngle.value()!=newValue; + if(steeringAngleChanged) + this->m_steeringAngle.setValue(newValue); } // set the elapsed time this->elapsed = (currentTime - this->t0) * 0.001; + + locker.unlock(); + + if(steeringAngleChanged) + emit this->steeringAngleChanged(this->m_steeringAngle.value()); } void trixterxdreamv1bike::calculateSteeringMap() { @@ -322,7 +331,9 @@ void trixterxdreamv1bike::updateResistance() { trixterxdreamv1bike::~trixterxdreamv1bike() { if(this->port) delete this->port; if(this->appSettings) delete this->appSettings; - if(this->virtualBike) delete this->virtualBike; + + // NOTE: bluetooth::restart() deletes this object, then deletes the bike object + //if(this->virtualBike) delete this->virtualBike; } void *trixterxdreamv1bike::VirtualDevice() { From 08b1723151d5ab085f93afb21e8228cc62538710 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 15 Aug 2022 09:29:44 +0100 Subject: [PATCH 056/255] #855 added power --- src/trixterxdreamv1bike.cpp | 304 ++++++++++++++++++++++++++++++++++++ src/trixterxdreamv1bike.h | 27 ++++ 2 files changed, 331 insertions(+) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 315c9ce5f..a5fb333c3 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -10,7 +10,275 @@ using namespace std; +double trixterxdreamv1bike::powerSurface[260][3] = +{ + {30, 0, 4.68}, + {30, 10, 5.77}, + {30, 20, 6.86}, + {30, 30, 7.95}, + {30, 40, 9.04}, + {30, 50, 10.13}, + {30, 60, 13.75}, + {30, 70, 17.38}, + {30, 80, 21}, + {30, 90, 24.63}, + {30, 100, 28.25}, + {30, 110, 32.42}, + {30, 120, 36.59}, + {30, 130, 40.77}, + {30, 140, 44.94}, + {30, 150, 49.11}, + {30, 160, 52.31}, + {30, 170, 55.5}, + {30, 180, 58.7}, + {30, 190, 61.89}, + {30, 200, 65.09}, + {30, 210, 66.87}, + {30, 220, 68.65}, + {30, 230, 70.42}, + {30, 240, 72.2}, + {30, 250, 73.98}, + {40, 0, 5.79}, + {40, 10, 6.96}, + {40, 20, 8.13}, + {40, 30, 9.29}, + {40, 40, 10.46}, + {40, 50, 11.63}, + {40, 60, 17.27}, + {40, 70, 22.91}, + {40, 80, 28.54}, + {40, 90, 34.18}, + {40, 100, 39.82}, + {40, 110, 47.69}, + {40, 120, 55.55}, + {40, 130, 63.42}, + {40, 140, 71.28}, + {40, 150, 79.15}, + {40, 160, 84.57}, + {40, 170, 89.99}, + {40, 180, 95.4}, + {40, 190, 100.82}, + {40, 200, 106.24}, + {40, 210, 109.37}, + {40, 220, 112.5}, + {40, 230, 115.62}, + {40, 240, 118.75}, + {40, 250, 121.88}, + {50, 0, 7.09}, + {50, 10, 8.73}, + {50, 20, 10.37}, + {50, 30, 12.01}, + {50, 40, 13.65}, + {50, 50, 15.29}, + {50, 60, 23.02}, + {50, 70, 30.76}, + {50, 80, 38.49}, + {50, 90, 46.23}, + {50, 100, 53.96}, + {50, 110, 65.73}, + {50, 120, 77.5}, + {50, 130, 89.28}, + {50, 140, 101.05}, + {50, 150, 112.82}, + {50, 160, 121.57}, + {50, 170, 130.32}, + {50, 180, 139.07}, + {50, 190, 147.82}, + {50, 200, 156.57}, + {50, 210, 161.46}, + {50, 220, 166.34}, + {50, 230, 171.23}, + {50, 240, 176.11}, + {50, 250, 181}, + {60, 0, 7.85}, + {60, 10, 9.64}, + {60, 20, 11.43}, + {60, 30, 13.21}, + {60, 40, 15}, + {60, 50, 16.79}, + {60, 60, 26.91}, + {60, 70, 37.04}, + {60, 80, 47.16}, + {60, 90, 57.29}, + {60, 100, 67.41}, + {60, 110, 83.71}, + {60, 120, 100.01}, + {60, 130, 116.32}, + {60, 140, 132.62}, + {60, 150, 148.92}, + {60, 160, 161.5}, + {60, 170, 174.09}, + {60, 180, 186.67}, + {60, 190, 199.26}, + {60, 200, 211.84}, + {60, 210, 219.79}, + {60, 220, 227.75}, + {60, 230, 235.7}, + {60, 240, 243.66}, + {60, 250, 251.61}, + {70, 0, 7.02}, + {70, 10, 9.56}, + {70, 20, 12.1}, + {70, 30, 14.64}, + {70, 40, 17.18}, + {70, 50, 19.72}, + {70, 60, 31.66}, + {70, 70, 43.6}, + {70, 80, 55.55}, + {70, 90, 67.49}, + {70, 100, 79.43}, + {70, 110, 99.66}, + {70, 120, 119.89}, + {70, 130, 140.13}, + {70, 140, 160.36}, + {70, 150, 180.59}, + {70, 160, 199.42}, + {70, 170, 218.25}, + {70, 180, 237.09}, + {70, 190, 255.92}, + {70, 200, 274.75}, + {70, 210, 285.29}, + {70, 220, 295.84}, + {70, 230, 306.38}, + {70, 240, 316.93}, + {70, 250, 327.47}, + {80, 0, 11.21}, + {80, 10, 14.45}, + {80, 20, 17.69}, + {80, 30, 20.94}, + {80, 40, 24.18}, + {80, 50, 27.42}, + {80, 60, 42.48}, + {80, 70, 57.54}, + {80, 80, 72.61}, + {80, 90, 87.67}, + {80, 100, 102.73}, + {80, 110, 128.44}, + {80, 120, 154.15}, + {80, 130, 179.85}, + {80, 140, 205.56}, + {80, 150, 231.27}, + {80, 160, 253.8}, + {80, 170, 276.33}, + {80, 180, 298.85}, + {80, 190, 321.38}, + {80, 200, 343.91}, + {80, 210, 359.11}, + {80, 220, 374.3}, + {80, 230, 389.5}, + {80, 240, 404.69}, + {80, 250, 419.89}, + {90, 0, 13.95}, + {90, 10, 17.98}, + {90, 20, 22.01}, + {90, 30, 26.03}, + {90, 40, 30.06}, + {90, 50, 34.09}, + {90, 60, 52.98}, + {90, 70, 71.87}, + {90, 80, 90.77}, + {90, 90, 109.66}, + {90, 100, 128.55}, + {90, 110, 159.29}, + {90, 120, 190.03}, + {90, 130, 220.76}, + {90, 140, 251.5}, + {90, 150, 282.24}, + {90, 160, 312.59}, + {90, 170, 342.94}, + {90, 180, 373.3}, + {90, 190, 403.65}, + {90, 200, 434}, + {90, 210, 449.53}, + {90, 220, 465.06}, + {90, 230, 480.6}, + {90, 240, 496.13}, + {90, 250, 511.66}, + {100, 0, 10.66}, + {100, 10, 14.86}, + {100, 20, 19.06}, + {100, 30, 23.27}, + {100, 40, 27.47}, + {100, 50, 31.67}, + {100, 60, 50.99}, + {100, 70, 70.32}, + {100, 80, 89.64}, + {100, 90, 108.97}, + {100, 100, 128.29}, + {100, 110, 162.32}, + {100, 120, 196.34}, + {100, 130, 230.37}, + {100, 140, 264.39}, + {100, 150, 298.42}, + {100, 160, 337.06}, + {100, 170, 375.71}, + {100, 180, 414.35}, + {100, 190, 453}, + {100, 200, 491.64}, + {100, 210, 512.57}, + {100, 220, 533.5}, + {100, 230, 554.44}, + {100, 240, 575.37}, + {100, 250, 596.3}, + {110, 0, 10.32}, + {110, 10, 15.17}, + {110, 20, 20.03}, + {110, 30, 24.88}, + {110, 40, 29.74}, + {110, 50, 34.59}, + {110, 60, 56.34}, + {110, 70, 78.09}, + {110, 80, 99.85}, + {110, 90, 121.6}, + {110, 100, 143.35}, + {110, 110, 182.15}, + {110, 120, 220.95}, + {110, 130, 259.76}, + {110, 140, 298.56}, + {110, 150, 337.36}, + {110, 160, 382.87}, + {110, 170, 428.38}, + {110, 180, 473.9}, + {110, 190, 519.41}, + {110, 200, 564.92}, + {110, 210, 591.47}, + {110, 220, 618.03}, + {110, 230, 644.58}, + {110, 240, 671.14}, + {110, 250, 697.69}, + {120, 0, 12.28}, + {120, 10, 18.05}, + {120, 20, 23.84}, + {120, 30, 29.61}, + {120, 40, 35.39}, + {120, 50, 41.16}, + {120, 60, 67.05}, + {120, 70, 92.93}, + {120, 80, 118.83}, + {120, 90, 144.71}, + {120, 100, 170.6}, + {120, 110, 216.77}, + {120, 120, 262.95}, + {120, 130, 309.14}, + {120, 140, 355.31}, + {120, 150, 401.49}, + {120, 160, 455.65}, + {120, 170, 509.81}, + {120, 180, 563.98}, + {120, 190, 618.14}, + {120, 200, 672.3}, + {120, 210, 703.9}, + {120, 220, 735.51}, + {120, 230, 767.1}, + {120, 240, 798.71}, + {120, 250, 830.31}}; + + trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartService, bool noVirtualDevice) { + // Initialize metrics + m_watt.setType(metric::METRIC_WATT); + Speed.setType(metric::METRIC_SPEED); + // Set the fake bluetooth device info this->bluetoothDevice = QBluetoothDeviceInfo(QBluetoothUuid {QStringLiteral("774f25bd-6636-4cdc-9398-839de026be1d")}, "Trixter X-Dream V1 Bike", 0); @@ -154,6 +422,39 @@ void trixterxdreamv1bike::configureVirtualBike(){ // ******************************************************************************************************** } +uint16_t trixterxdreamv1bike::powerFromResistanceRequest(int8_t requestedResistance) +{ + return this->calculatePower((int)this->Cadence.value(), requestedResistance); +} + +uint8_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) +{ + int c = std::max(0, std::min(9, (int)(0.1*(this->Cadence.value()-30) +0.5))); + + double * ps = powerSurface[c*26]; + for(int i=0; i<26; i++, ps++) + if(ps[2]>=power) + return (uint8_t)ps[1]; + return (uint8_t)((ps-1)[1]); +} + +double trixterxdreamv1bike::calculatePower(int cadenceRPM, int resistance) { + if(cadenceRPM<30) + return 0.0; + + int c = std::max(0, std::min(9, (int)(0.1*(cadenceRPM-30) +0.5))); + int r = 0.1*std::max(0, std::min(250, resistance))+0.5; + + double *ps = powerSurface[c*26+r]; + + if(ps[0]!=c*10+30 || ps[1]!=r*10) + { + throw "Unexpected r and c values."; + } + + return ps[2]; +} + bool trixterxdreamv1bike::connected() { QMutexLocker locker(&this->updateMutex); @@ -216,6 +517,9 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // set the cadence in revolutions per minute this->Cadence.setValue(state.CrankRPM); + // update the power output + this->m_watt.setValue(this->calculatePower(state.CrankRPM, this->resistanceLevel)); + // set the crank revolutions this->CrankRevs = state.CumulativeCrankRevolutions; diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 27329141d..a60c3f1a5 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -15,6 +15,11 @@ class trixterxdreamv1bike : public bike */ constexpr static int SettingsUpdateTimerIntervalMilliseconds = 10000; + /** + * @brief powerSurface Mapping from cadence and resistance to power. + */ + static double powerSurface[260][3]; + /** * @brief client An object that processes incoming data to CSCS, heart rate and steering data */ @@ -146,6 +151,14 @@ class trixterxdreamv1bike : public bike * @brief configureVirtualBike Set up the bridge to the client application. */ void configureVirtualBike(); + + /** + * @brief calculatePower Calculate power from cadence RPM and resistance. + * @param cadenceRPM + * @param resistance + * @return + */ + double calculatePower(int cadenceRPM, int resistance); protected: /** @@ -199,6 +212,20 @@ public Q_SLOTS: ~trixterxdreamv1bike(); + /** + * @brief powerFromResistanceRequest Calculate the power for the requested resistance at the current cadence. + * @param requestedResistance + * @return + */ + uint16_t powerFromResistanceRequest(int8_t requestedResistance) override; + + /** + * @brief resistanceFromPowerRequest Calculate the reistance required to produce the requested power at the current cadence. + * @param power + * @return + */ + uint8_t resistanceFromPowerRequest(uint16_t power) override; + /** * @brief VirtualDevice Virtual device * @return From 61d68c191dfebe72bd4ab3f5882d1c53aa80ca0d Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 15 Aug 2022 22:42:25 +0100 Subject: [PATCH 057/255] #855 made the timeout for the initial port search configurable --- src/settings.qml | 24 ++++++++++++++++++++++++ src/trixterxdreamv1bike.cpp | 4 ++-- src/trixterxdreamv1settings.cpp | 12 +++++++++++- src/trixterxdreamv1settings.h | 21 +++++++++++++++++++-- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/settings.qml b/src/settings.qml index 478fdec5f..a6d55efbf 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -469,6 +469,7 @@ ScrollView { property int trixter_xdream_v1_bike_steering_CR : 2 property int trixter_xdream_v1_bike_steering_R : 45 property int trixter_xdream_v1_bike_steering_MAX : 45 + property int trixter_xdream_v1_bike_connection_timeout_ms : 500 } @@ -1743,6 +1744,29 @@ ScrollView { Layout.fillWidth: true onClicked: settings.trixter_xdream_v1_bike = checked } + RowLayout { + id: trixterXDreamV1BikeConnection + spacing: 10 + Label { + id: labelTrixterXDreamV1BikeConnectionTimeout + text: qsTr("Initial connection timeout (ms)") + Layout.fillWidth: true + } + SpinBox { + id: trixterXDreamV1BikeConnectionTimeout + value: settings.trixter_xdream_v1_bike_connection_timeout_ms + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("The number of milliseconds the app will wait for data from the bike when searching a port.") + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + inputMethodHints: Qt.ImhDigitsOnly + stepSize: 100 + from: 100 + to: 10000 + onValueChanged: settings.trixter_xdream_v1_bike_connection_timout_ms = value + } + } SwitchDelegate { id: trixterXDreamV1HeartRate text: qsTr("Heart Rate Signal Enabled") diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index a5fb333c3..641ea3f98 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -333,7 +333,7 @@ bool trixterxdreamv1bike::connect(QString portName) { } // wait for up to 500ms for some packets to arrive - for(uint32_t start = getTime(), t=start, limit=start+500; tappSettings->get_connectionTimeoutMilliseconds(); tconnected()) { qDebug() << "Connected after " << stopWatch.elapsed() << "milliseconds"; break; @@ -449,7 +449,7 @@ double trixterxdreamv1bike::calculatePower(int cadenceRPM, int resistance) { if(ps[0]!=c*10+30 || ps[1]!=r*10) { - throw "Unexpected r and c values."; + qDebug() << "Unexpected (r,c) values: (" << r << "," << c << ")"; } return ps[2]; diff --git a/src/trixterxdreamv1settings.cpp b/src/trixterxdreamv1settings.cpp index 55fa786d9..ac82dfcb7 100644 --- a/src/trixterxdreamv1settings.cpp +++ b/src/trixterxdreamv1settings.cpp @@ -8,6 +8,7 @@ const QString trixterxdreamv1settings::keys::SteeringCalibrationCenterLeft =QStr const QString trixterxdreamv1settings::keys::SteeringCalibrationCenterRight = QStringLiteral("trixter_xdream_v1_bike_steering_CR"); const QString trixterxdreamv1settings::keys::SteeringCalibrationRight = QStringLiteral("trixter_xdream_v1_bike_steering_R"); const QString trixterxdreamv1settings::keys::SteeringCalibrationMAX = QStringLiteral("trixter_xdream_v1_bike_steering_MAX"); +const QString trixterxdreamv1settings::keys::ConnectionTimeoutMilliseconds = QStringLiteral("trixter_xdream_v1_bike_connection_timeout_ms"); template @@ -69,6 +70,15 @@ void trixterxdreamv1settings::set_steeringCalibration(const trixterxdreamv1setti } } +uint16_t trixterxdreamv1settings::get_connectionTimeoutMilliseconds() { + QMutexLocker locker(&this->mutex); + return this->DefaultConnectionTimeoutMilliseconds; +} + +void trixterxdreamv1settings::set_connectionTimeoutMilliseconds(uint16_t value) { + value = this->clip(MinConnectionTimeoutMilliseconds, MaxConnectionTimeoutMilliseconds, value); + this->updateField(this->connectionTimeoutMilliseconds, value); +} trixterxdreamv1settings::trixterxdreamv1settings() { QSettings defaultSettings; @@ -91,7 +101,7 @@ void trixterxdreamv1settings::Load(const QSettings &settings) { this->set_enabled(settings.value(keys::Enabled, DefaultEnabled).toBool()); this->set_heartRateEnabled(settings.value(keys::HeartRateEnabled, DefaultHeartRateEnabled).toBool()); this->set_steeringEnabled(settings.value(keys::SteeringEnabled, DefaultSteeringEnabled).toBool()); - + this->set_connectionTimeoutMilliseconds(settings.value(keys::ConnectionTimeoutMilliseconds, DefaultConnectionTimeoutMilliseconds).toUInt()); steeringCalibrationInfo sc(settings.value(keys::SteeringCalibrationLeft, DefaultSteeringCalibrationL).toInt(), settings.value(keys::SteeringCalibrationCenterLeft, DefaultSteeringCalibrationCL).toInt(), settings.value(keys::SteeringCalibrationCenterRight, DefaultSteeringCalibrationCR).toInt(), diff --git a/src/trixterxdreamv1settings.h b/src/trixterxdreamv1settings.h index 629835a73..86ca0197d 100644 --- a/src/trixterxdreamv1settings.h +++ b/src/trixterxdreamv1settings.h @@ -17,6 +17,8 @@ class trixterxdreamv1settings { // these should match the corresponding values in settings.qml // - the default values where the properties are defined constexpr static int8_t MaxSteeringAngle = 45; + constexpr static uint16_t MinConnectionTimeoutMilliseconds = 20; + constexpr static uint16_t MaxConnectionTimeoutMilliseconds = 10000; constexpr static bool DefaultEnabled =true; constexpr static bool DefaultSteeringEnabled =true; constexpr static bool DefaultHeartRateEnabled =true; @@ -24,6 +26,7 @@ class trixterxdreamv1settings { constexpr static int8_t DefaultSteeringCalibrationR = MaxSteeringAngle; constexpr static int8_t DefaultSteeringCalibrationCL = -2; constexpr static int8_t DefaultSteeringCalibrationCR = 2; + constexpr static uint16_t DefaultConnectionTimeoutMilliseconds = 500; /** * @brief Defines QSettings keys relating to the Trixter X-Dream V1 bike. @@ -41,6 +44,7 @@ class trixterxdreamv1settings { const static QString SteeringCalibrationCenterRight; const static QString SteeringCalibrationRight; const static QString SteeringCalibrationMAX; + const static QString ConnectionTimeoutMilliseconds; }; struct steeringCalibrationInfo { @@ -110,6 +114,7 @@ class trixterxdreamv1settings { bool enabled=DefaultEnabled; bool steeringEnabled = DefaultSteeringEnabled; bool heartRateEnabled = DefaultHeartRateEnabled; + uint16_t connectionTimeoutMilliseconds = DefaultConnectionTimeoutMilliseconds; steeringCalibrationInfo steeringCalibration; @@ -187,6 +192,20 @@ class trixterxdreamv1settings { */ void set_steeringCalibration(const steeringCalibrationInfo value); + /** + * @brief get_ConnectionTimeoutMilliseconds Gets the number of milliseconds the + * detector will wait for valid data from the serial port. + * @return + */ + uint16_t get_connectionTimeoutMilliseconds(); + + /** + * @brief set_connectionTimeoutMilliseconds Sets the number of milliseconds the + * detector will wait for valid data from the serial port. + * @param value + */ + void set_connectionTimeoutMilliseconds(uint16_t value); + /** * @brief trixterxdreamv1bikesettings Constructor, intializes from the default QSettings. */ @@ -209,7 +228,6 @@ class trixterxdreamv1settings { */ void Load(const QSettings& settings); - ///** // * @brief Save Saves the values to the default QSettings object. // */ @@ -220,7 +238,6 @@ class trixterxdreamv1settings { // * @param settings // */ //void Save(const QSettings& settings); - }; From 83bd96f02972449a8a21594eebf0db3ecf72b04a Mon Sep 17 00:00:00 2001 From: David Mason Date: Tue, 16 Aug 2022 21:42:45 +0100 Subject: [PATCH 058/255] #855 adjusted comments --- src/bluetoothdevice.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bluetoothdevice.h b/src/bluetoothdevice.h index 2281e00fd..c58fde046 100644 --- a/src/bluetoothdevice.h +++ b/src/bluetoothdevice.h @@ -443,12 +443,12 @@ class bluetoothdevice : public QObject { metric elevationAcc; /** - * @brief m_watt Metric to get and set the power expended in the session. Unit: watts + * @brief m_watt Metric to get and set the current power being expended. Unit: watts */ metric m_watt; /** - * @brief WattKg Metric to get and set the watt kg for the session (what's this?). Unit: watt kg + * @brief WattKg Metric to get and set the current watt kg. E.g. power x body mass. Unit: watt kg */ metric WattKg; From 7e6ac4006dcdb60f303b111a38f17696a99ef02c Mon Sep 17 00:00:00 2001 From: David Mason Date: Tue, 16 Aug 2022 23:09:33 +0100 Subject: [PATCH 059/255] #855 map bikes 0..255 resistance to 0.100 to fit with int8_t datatype used in QZ. Left it as an option in case this is fixed and the full range can be used. --- src/trixterxdreamv1bike.cpp | 47 ++++++++++++++++++++++++++++--------- src/trixterxdreamv1bike.h | 28 ++++++++++++++++++---- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 641ea3f98..f1ed4455a 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -279,6 +279,9 @@ trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartSer m_watt.setType(metric::METRIC_WATT); Speed.setType(metric::METRIC_SPEED); + // use a percentage resistance until QZ is using more than 7 bits to store the resistance levels. + this->useResistancePercentage = true; + // Set the fake bluetooth device info this->bluetoothDevice = QBluetoothDeviceInfo(QBluetoothUuid {QStringLiteral("774f25bd-6636-4cdc-9398-839de026be1d")}, "Trixter X-Dream V1 Bike", 0); @@ -332,7 +335,7 @@ bool trixterxdreamv1bike::connect(QString portName) { return false; } - // wait for up to 500ms for some packets to arrive + // wait for up to the configured connection timeout for some packets to arrive for(uint32_t start = getTime(), t=start, limit=start+this->appSettings->get_connectionTimeoutMilliseconds(); tconnected()) { qDebug() << "Connected after " << stopWatch.elapsed() << "milliseconds"; @@ -376,7 +379,7 @@ void trixterxdreamv1bike::disconnectPort() { this->port = nullptr; } if(this->resistanceTimerId) { - qDebug() << "Kiling resistance timer"; + qDebug() << "Killing resistance timer"; this->killTimer(this->resistanceTimerId); this->resistanceTimerId = 0; } @@ -424,6 +427,7 @@ void trixterxdreamv1bike::configureVirtualBike(){ uint16_t trixterxdreamv1bike::powerFromResistanceRequest(int8_t requestedResistance) { + requestedResistance = this->adjustedResistance(requestedResistance, true); return this->calculatePower((int)this->Cadence.value(), requestedResistance); } @@ -431,11 +435,17 @@ uint8_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) { int c = std::max(0, std::min(9, (int)(0.1*(this->Cadence.value()-30) +0.5))); + int16_t result = -1; + double * ps = powerSurface[c*26]; - for(int i=0; i<26; i++, ps++) + for(int i=0; result<0 && i<26; i++, ps++) if(ps[2]>=power) - return (uint8_t)ps[1]; - return (uint8_t)((ps-1)[1]); + result = ps[1]; + if(result<0) + result = (ps-1)[1]; + + result = this->adjustedResistance(result, false); + return result; } double trixterxdreamv1bike::calculatePower(int cadenceRPM, int resistance) { @@ -455,6 +465,16 @@ double trixterxdreamv1bike::calculatePower(int cadenceRPM, int resistance) { return ps[2]; } +int16_t trixterxdreamv1bike::adjustedResistance(int16_t input, bool toDevice) { + if(this->useResistancePercentage){ + if(toDevice) + return trixterxdreamv1client::MaxResistance * input / 100; + else + return 100 * input / trixterxdreamv1client::MaxResistance ; + } + return input; +} + bool trixterxdreamv1bike::connected() { QMutexLocker locker(&this->updateMutex); @@ -563,7 +583,6 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { void trixterxdreamv1bike::calculateSteeringMap() { - trixterxdreamv1settings::steeringCalibrationInfo info = this->appSettings->get_steeringCalibration(); vector newMap; @@ -616,15 +635,17 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { bike::changeResistance(resistanceLevel); - // store the new resistance level. This might be the same as lastRequestedResistance(),Value - // but it doesn't involve a function call and a cast to get the value. - this->resistanceLevel = resistanceLevel; - // store the resistance level as a metric for the UI constexpr double pelotonScaleFactor = 100.0 / trixterxdreamv1client::MaxResistance; this->Resistance.setValue(resistanceLevel); - this->m_pelotonResistance.setValue(round(pelotonScaleFactor * resistanceLevel)); + if(this->useResistancePercentage) + this->m_pelotonResistance.setValue(resistanceLevel); + else + this->m_pelotonResistance.setValue(round(pelotonScaleFactor * resistanceLevel)); + // store the new resistance level. This might be the same as lastRequestedResistance(),Value + // but it doesn't involve a function call and a cast to get the value. + this->resistanceLevel = this->adjustedResistance(resistanceLevel, true); } void trixterxdreamv1bike::updateResistance() { @@ -657,6 +678,10 @@ void trixterxdreamv1bike::set_wheelDiameter(double value) { int trixterxdreamv1bike::pelotonToBikeResistance(int pelotonResistance) { pelotonResistance = std::max(0, std::min(100, pelotonResistance)); + + if(this->useResistancePercentage) + return pelotonResistance; + return round(0.01*pelotonResistance*trixterxdreamv1client::MaxResistance); } diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index a60c3f1a5..75acc7c83 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -76,6 +76,12 @@ class trixterxdreamv1bike : public bike */ uint8_t resistanceLevel = 0; + /** + * @brief useResistancePercentage Option to use resistance levels 0..100 instead of + * a full range that exceeds an int8_t. + */ + bool useResistancePercentage = false; + /** * @brief wheelCircumference The simulated circumference of the bike's wheels, for converting * angular velocity to a speed. Units: kilometers. @@ -155,10 +161,22 @@ class trixterxdreamv1bike : public bike /** * @brief calculatePower Calculate power from cadence RPM and resistance. * @param cadenceRPM - * @param resistance + * @param resistance Bike resistance on full, not percentage scale. * @return */ double calculatePower(int cadenceRPM, int resistance); + + + /** + * @brief adjustedResistance Adjust the resistance based on whether the + * object has been configured to use a resistance percentage or the + * raw value. + * @param input 0..100 if the object is using a resistance percentage, + * 0..trixterxdreamclient::MaxResistance otherwise. + * @param toDevice The direction of the conversion. + * @return + */ + int16_t adjustedResistance(int16_t input, bool toDevice); protected: /** @@ -174,7 +192,7 @@ class trixterxdreamv1bike : public bike public Q_SLOTS: /** * @brief changeResistance Called to change the requested resistance level. - * @param resistanceLevel The resistance level to request (0..250) + * @param resistanceLevel The resistance level to request (0..maximumResistance()) */ void changeResistance(int8_t resistanceLevel) override; @@ -220,7 +238,7 @@ public Q_SLOTS: uint16_t powerFromResistanceRequest(int8_t requestedResistance) override; /** - * @brief resistanceFromPowerRequest Calculate the reistance required to produce the requested power at the current cadence. + * @brief resistanceFromPowerRequest Calculate the resistance required to produce the requested power at the current cadence. * @param power * @return */ @@ -258,12 +276,12 @@ public Q_SLOTS: * @brief maxResistance The maximum resistance supported. * @return */ - uint8_t maxResistance() override { return trixterxdreamv1client::MaxResistance; } + uint8_t maxResistance() override { return this->useResistancePercentage ? 100:trixterxdreamv1client::MaxResistance; } /** * @brief pelotonToBikeResistance Map Peloton 0 to 100% resistance to the bike's range. * @param pelotonResistance The Peloton resistance. Range: 0 to 100. - * @return The Trixter X-Dream V1 bike resistance. Range 0..250. + * @return The Trixter X-Dream V1 bike resistance. Range 0..250 if !this->useResistancePercentage. */ int pelotonToBikeResistance(int pelotonResistance) override; From 54a38fb6f1fdfdab62cd0e81a0adc516586e322f Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 17 Aug 2022 22:40:48 +0100 Subject: [PATCH 060/255] #855 - updated "datasource" class to provide the remaining fields (brakes, buttons, crank position). - call bike::update_metrics to see how that affects the ride in Zwift - added feature to use red button on bike control panel to override QZ resistance with 100% to stop a spinning flywheel. --- src/bluetoothdevice.h | 2 +- src/trixterxdreamv1bike.cpp | 8 +++- src/trixterxdreamv1bike.h | 5 +++ src/trixterxdreamv1client.cpp | 7 ++++ src/trixterxdreamv1client.h | 74 ++++++++++++++++++++++++++++++++--- 5 files changed, 88 insertions(+), 8 deletions(-) diff --git a/src/bluetoothdevice.h b/src/bluetoothdevice.h index c58fde046..5ed6be917 100644 --- a/src/bluetoothdevice.h +++ b/src/bluetoothdevice.h @@ -448,7 +448,7 @@ class bluetoothdevice : public QObject { metric m_watt; /** - * @brief WattKg Metric to get and set the current watt kg. E.g. power x body mass. Unit: watt kg + * @brief WattKg Metric to get and set the current watts per kg. E.g. power / mass. Unit: watt/kg */ metric WattKg; diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index f1ed4455a..39f68b5ee 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -524,6 +524,9 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { this->packetsProcessed++; this->lastPacketProcessedTime = currentTime; + // Determine if the user is pressing the button to stop. + this->stopping = (state.Buttons & trixterxdreamv1client::buttons::Red) != 0; + // update the metrics this->LastCrankEventTime = state.LastEventTime; @@ -538,7 +541,7 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { this->Cadence.setValue(state.CrankRPM); // update the power output - this->m_watt.setValue(this->calculatePower(state.CrankRPM, this->resistanceLevel)); + this->update_metrics(true, this->calculatePower(state.CrankRPM, this->resistanceLevel)); // set the crank revolutions this->CrankRevs = state.CumulativeCrankRevolutions; @@ -650,7 +653,8 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { void trixterxdreamv1bike::updateResistance() { QMutexLocker locker(&this->updateMutex); - this->client.SendResistance(this->resistanceLevel); + uint8_t actualResistance = this->stopping ? (trixterxdreamv1client::MaxResistance): this->resistanceLevel; + this->client.SendResistance(actualResistance); } trixterxdreamv1bike::~trixterxdreamv1bike() { diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 75acc7c83..bc9152ca5 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -36,6 +36,11 @@ class trixterxdreamv1bike : public bike */ virtualbike * virtualBike = nullptr; + /** + * @brief stopping Indicates if the deice should be sent full resistance instead of the currently requested resistance. + */ + bool stopping = false; + /** * @brief resistanceTimerId The id for identifying the resistance timer in void timerEvent(QEvent*). */ diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp index 9387446d0..cb6122f1d 100644 --- a/src/trixterxdreamv1client.cpp +++ b/src/trixterxdreamv1client.cpp @@ -111,6 +111,10 @@ bool trixterxdreamv1client::ReceiveChar(char c) { if (this->ProcessChar(c) != Complete) return false; + lastPacket.Buttons = (static_cast(this->byteBuffer[0x8]) << 8) + this->byteBuffer[0x9]; + lastPacket.CrankPosition = this->byteBuffer[0x3]; + lastPacket.Brake1 = this->byteBuffer[0x4]; + lastPacket.Brake2 = this->byteBuffer[0x5]; lastPacket.Steering = this->byteBuffer[0x1]; lastPacket.Flywheel = (static_cast(this->byteBuffer[0xC]) << 8) + this->byteBuffer[0xD]; lastPacket.Crank = (static_cast(this->byteBuffer[0xA]) << 8) + this->byteBuffer[0xB]; @@ -167,6 +171,9 @@ bool trixterxdreamv1client::ReceiveChar(char c) { newState.CumulativeWheelRevolutions = static_cast(round(flywheelRevolutions)); newState.CrankRPM = static_cast(crankRevsPerMinute); newState.FlywheelRPM = static_cast(flywheelRevsPerMinute); + newState.Buttons = (buttons)(0xFFFF-lastPacket.Buttons); + + this->stateMutex.lock(); this->lastState = newState; diff --git a/src/trixterxdreamv1client.h b/src/trixterxdreamv1client.h index 54e70dbaf..d0b406a19 100644 --- a/src/trixterxdreamv1client.h +++ b/src/trixterxdreamv1client.h @@ -12,10 +12,39 @@ */ class trixterxdreamv1client { public: + + /** + * @brief Values for the button state. + */ + enum buttons : uint16_t + { + LeftArrow = 4096, + RightArrow = 16384, + UpArrow = 256, + DownArrow = 1024, + + Blue = 8192, + Red = 512, + Green = 2048, + + Seated = 8, + + FrontGearUp = 32768, + FrontGearDown = 128, + + BackGearUp = 32, + BackGearDown = 64 + }; + /** - * @brief Device state data: CSCS, heartrate and steering. + * @brief Device state data: CSCS, heartrate, steering, buttons. */ struct state { + /** + * @brief Buttons The state of the buttons. + */ + buttons Buttons; + /** * @brief Steering Steering value, from 0 (left) to 250 (right) */ @@ -50,6 +79,22 @@ class trixterxdreamv1client { * @brief CrankRPM Crank speed. Units: revolutions per minute */ uint16_t CrankRPM; + + /** + * @brief CrankPosition Position of the crank. Range: 1 to 60. + */ + uint8_t CrankPosition; + + /** + * @brief Brake 1. Position of brake 1. Range: 135 (on) to 250 (off) + */ + uint8_t Brake1; + + + /** + * @brief Brake 2. Position of brake 1. Range: 135 (on) to 250 (off) + */ + uint8_t Brake2; }; private: @@ -61,10 +106,8 @@ class trixterxdreamv1client { * @brief Raw data selected from the incoming packet. */ struct Packet { - uint8_t Steering; - uint16_t Flywheel; - uint16_t Crank; - uint8_t HeartRate; + uint8_t Steering, Brake1, Brake2, HeartRate, CrankPosition; + uint16_t Flywheel, Crank, Buttons; }; std::function get_time_ms=nullptr; @@ -102,6 +145,27 @@ class trixterxdreamv1client { */ constexpr static uint8_t MaxSteering = 255; + + /** + * @brief MaxBrake The maximum brake value, which indicates fully off. + */ + constexpr static uint8_t MaxBrake = 250; + + /** + * @brief MinBrake The minimum brake value, which indicates fully on. + */ + constexpr static uint8_t MinBrake = 135; + + /** + * @brief MinCrankPosition The minimum CrankPosition value. + */ + constexpr static uint8_t MinCrankPosition = 1; + + /** + * @brief MinCrankPosition The maximum CrankPosition value. + */ + constexpr static uint8_t MaxCrankPosition = 60; + /** * @brief The time interval between sending resistance requests to the device. */ From 9b6cc8c26e56bf3044f159313e7a761e211103bc Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 18 Aug 2022 21:21:39 +0100 Subject: [PATCH 061/255] #855 add ability to toggle debug log of serial data. Reserve 4096 bytes in buffer for reading serial port. --- src/trixterxdreamv1serial.cpp | 21 +++++++++++++++++---- src/trixterxdreamv1serial.h | 13 +++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 8f512cef2..3f002d130 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -47,7 +47,10 @@ bool trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate } void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { - qDebug() << "serial >> " << buffer.toHex() << "//" << info; + bool log = this->get_SendReceiveLog(); + + if(log) + qDebug() << "serial >> " << buffer.toHex() << "//" << info; // obtain a mutex lock to avoid writing during a read QMutexLocker locker(&this->mutex); @@ -57,9 +60,14 @@ void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { locker.unlock(); - qDebug() << "serial byte written" << o; + if(log) + qDebug() << "serial byte written" << o; } +bool trixterxdreamv1serial::get_SendReceiveLog() { return this->sendReceiveLog; } + +void trixterxdreamv1serial::set_SendReceiveLog(bool value) { this->sendReceiveLog = value; } + void trixterxdreamv1serial::run() { this->serial.setPortName(this->portName); @@ -89,6 +97,9 @@ void trixterxdreamv1serial::run() { while (!this->quitPending) { QByteArray requestData; + requestData.reserve(4096); + + bool log = this->get_SendReceiveLog(); // Obtain a mutex lock so it's not waiting for ready read while trying to write... QMutexLocker locker(&this->mutex); @@ -105,7 +116,8 @@ void trixterxdreamv1serial::run() { if(requestData.length()>0) { - qDebug() << "serial << " << requestData.toHex(' '); + if(log) + qDebug() << "serial << " << requestData.toHex(' '); // Send the bytes to the client code // Unlike the QtSerialPort example that can be found online, this @@ -113,7 +125,8 @@ void trixterxdreamv1serial::run() { // which seem to require an advanced course to get working together! this->receive(requestData); - qDebug() << requestData.length() << " bytes processed"; + if(log) + qDebug() << requestData.length() << " bytes processed"; } } diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index 48dd7570b..9254142f4 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -40,6 +40,18 @@ class trixterxdreamv1serial : public QThread { */ void set_receiveBytes(std::function value) { this->receiveBytes = value; } + /** + * @brief get_SendReceiveLog Gets whether or not the bytes sent and received will be written to the debug log. + * @return + */ + bool get_SendReceiveLog(); + + /** + * @brief set_SendReceiveLog Sets whether or not the bytes sent and received will be written to the debug log. + * @param value + */ + void set_SendReceiveLog(bool value); + /** * @brief availablePorts Returns a list of information objects for the serial ports found in the system. */ @@ -61,6 +73,7 @@ class trixterxdreamv1serial : public QThread { private: void run() override; + bool sendReceiveLog = false; QSerialPort serial; QString portName; QSerialPort::BaudRate baudRate; From 9c4d4fec40b58940c3c6860859c0659324fc3958 Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 18 Aug 2022 22:11:26 +0100 Subject: [PATCH 062/255] #855 fixed property name --- src/settings.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings.qml b/src/settings.qml index a6d55efbf..3c6a6569d 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -1764,7 +1764,7 @@ ScrollView { stepSize: 100 from: 100 to: 10000 - onValueChanged: settings.trixter_xdream_v1_bike_connection_timout_ms = value + onValueChanged: settings.trixter_xdream_v1_bike_connection_timeout_ms = value } } SwitchDelegate { From efb742aad57a6ee284da8348bbde18bad65fcecb Mon Sep 17 00:00:00 2001 From: David Mason Date: Tue, 23 Aug 2022 23:03:17 +0100 Subject: [PATCH 063/255] #855 feed brake level into resistance from power calculation. Stop bluetooth and non-bluetooth discovery once first device found. --- src/bluetooth.cpp | 178 +++++++++++++++++++++--------------- src/bluetooth.h | 9 ++ src/trixterxdreamv1bike.cpp | 24 +++-- src/trixterxdreamv1bike.h | 19 ++-- 4 files changed, 141 insertions(+), 89 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 505912643..40e8d76b2 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -81,7 +81,7 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc if (!b.compare(settings.value("filter_device", "Disabled").toString()) && (b.toUpper().startsWith("IC BIKE") || b.toUpper().startsWith("C7-"))) { - discoveryAgent->stop(); + this->stopDiscovery(); schwinnIC4Bike = new schwinnic4bike(noWriteResistance, noHeartService); // stateFileRead(); QBluetoothDeviceInfo bt; @@ -106,10 +106,26 @@ bluetooth::bluetooth(bool logs, const QString &deviceName, bool noWriteResistanc } void bluetooth::nonBluetoothDeviceDiscovery() { - bluetoothdevice * nonBluetoothDevice = this->discoverNonBluetoothDevices(); + bluetoothdevice * nonBluetoothDevice = nullptr; + + this->discoveringNonBluetooth = true; + try { + nonBluetoothDevice = this->discoverNonBluetoothDevices(); + } catch(std::exception const& e) { + this->discoveringNonBluetooth = false; + debug("Exception thrown while looking for non-bluetooth devices"); + debug(e.what()); + throw; + } catch(...) { + this->discoveringNonBluetooth = false; + debug("Error was thrown while looking for non-bluetooth devices"); + throw; + } + + this->discoveringNonBluetooth = false; if(nonBluetoothDevice) { - if(this->discoveryAgent) discoveryAgent->stop(); + this->stopDiscovery(); this->userTemplateManager->start(nonBluetoothDevice); this->innerTemplateManager->start(nonBluetoothDevice); emit this->deviceConnected(nonBluetoothDevice->bluetoothDevice); @@ -132,15 +148,21 @@ bluetoothdevice * bluetooth::discoverNonBluetoothDevices() { QBluetoothDeviceInfo(QBluetoothUuid {QStringLiteral("775f25bd-6636-4cdc-9398-839ae026be1d")}, "Device Name", 0); */ + // Try to connect to a Trixter X-Dream V1 bike if the setting is enabled. this->trixterXDreamV1Bike = this->findTrixterXDreamV1Bike(settings); if(this->trixterXDreamV1Bike) + { return this->trixterXDreamV1Bike; + } + if(!this->discovering) return nullptr; + + // Test for other devices and check that discovery hasn't been cancelled. - // Test for other devices // nothing found return nullptr; + } bluetooth::~bluetooth() { @@ -203,6 +225,8 @@ void bluetooth::finished() { void bluetooth::startDiscovery() { + this->discovering = true; + #ifndef Q_OS_IOS QSettings settings; bool technogym_myrun_treadmill_experimental = @@ -225,6 +249,12 @@ void bluetooth::startDiscovery() { } +void bluetooth::stopDiscovery() +{ + this->discovering = false; + if(this->discoveryAgent) this->discoveryAgent->stop(); +} + void bluetooth::canceled() { debug(QStringLiteral("BTLE scanning stops")); @@ -468,7 +498,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { if (b.name().startsWith(QStringLiteral("M3")) && !m3iBike && filter) { if (m3ibike::isCorrectUnit(b)) { - discoveryAgent->stop(); + this->stopDiscovery(); m3iBike = new m3ibike(noWriteResistance, noHeartService); emit deviceConnected(b); connect(m3iBike, &bluetoothdevice::connectedAndDiscovered, this, @@ -483,7 +513,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(m3iBike); } } else if (fake_bike && !fakeBike) { - discoveryAgent->stop(); + this->stopDiscovery(); fakeBike = new fakebike(noWriteResistance, noHeartService, false); emit deviceConnected(b); connect(fakeBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); @@ -497,7 +527,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(fakeBike); innerTemplateManager->start(fakeBike); } else if (fakedevice_elliptical && !fakeElliptical) { - discoveryAgent->stop(); + this->stopDiscovery(); fakeElliptical = new fakeelliptical(noWriteResistance, noHeartService, false); emit deviceConnected(b); connect(fakeElliptical, &bluetoothdevice::connectedAndDiscovered, this, @@ -512,7 +542,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(fakeElliptical); innerTemplateManager->start(fakeElliptical); } else if (!proformtdf4ip.isEmpty() && !proformWifiBike) { - discoveryAgent->stop(); + this->stopDiscovery(); proformWifiBike = new proformwifibike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -528,7 +558,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(proformWifiBike); innerTemplateManager->start(proformWifiBike); } else if (!proformtreadmillip.isEmpty() && !proformWifiTreadmill) { - discoveryAgent->stop(); + this->stopDiscovery(); proformWifiTreadmill = new proformwifitreadmill(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -544,7 +574,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(proformWifiTreadmill); innerTemplateManager->start(proformWifiTreadmill); } else if (!nordictrack_2950_ip.isEmpty() && !nordictrackifitadbTreadmill) { - discoveryAgent->stop(); + this->stopDiscovery(); nordictrackifitadbTreadmill = new nordictrackifitadbtreadmill(noWriteResistance, noHeartService); emit deviceConnected(b); connect(nordictrackifitadbTreadmill, &bluetoothdevice::connectedAndDiscovered, this, @@ -559,7 +589,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(nordictrackifitadbTreadmill); } else if (csc_as_bike && b.name().startsWith(cscName) && !cscBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); cscBike = new cscbike(noWriteResistance, noHeartService, false); emit deviceConnected(b); connect(cscBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); @@ -574,7 +604,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(cscBike); } else if (power_as_bike && b.name().startsWith(powerSensorName) && !powerBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); powerBike = new stagesbike(noWriteResistance, noHeartService, false); emit deviceConnected(b); connect(powerBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); @@ -589,7 +619,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(powerBike); } else if (power_as_treadmill && b.name().startsWith(powerSensorName) && !powerTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); powerTreadmill = new strydrunpowersensor(noWriteResistance, noHeartService, false); emit deviceConnected(b); connect(powerTreadmill, &bluetoothdevice::connectedAndDiscovered, this, @@ -605,7 +635,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(powerTreadmill); } else if (b.name().toUpper().startsWith(QStringLiteral("DOMYOS-ROW")) && !b.name().startsWith(QStringLiteral("DomyosBridge")) && !domyosRower && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); domyosRower = new domyosrower(noWriteResistance, noHeartService, testResistance, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -622,7 +652,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(domyosRower); } else if (b.name().startsWith(QStringLiteral("Domyos-Bike")) && !b.name().startsWith(QStringLiteral("DomyosBridge")) && !domyosBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); domyosBike = new domyosbike(noWriteResistance, noHeartService, testResistance, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -638,7 +668,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(domyosBike); } else if (b.name().startsWith(QStringLiteral("Domyos-EL")) && !b.name().startsWith(QStringLiteral("DomyosBridge")) && !domyosElliptical && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); domyosElliptical = new domyoselliptical(noWriteResistance, noHeartService, testResistance, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -656,7 +686,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } else if ((b.name().toUpper().startsWith(QStringLiteral("NAUTILUS E"))) && !nautilusElliptical && // NAUTILUS E616 filter) { - discoveryAgent->stop(); + this->stopDiscovery(); nautilusElliptical = new nautiluselliptical(noWriteResistance, noHeartService, testResistance, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -672,7 +702,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(nautilusElliptical); } else if ((b.name().toUpper().startsWith(QStringLiteral("NAUTILUS B"))) && !nautilusBike && filter) { // NAUTILUS B628 - discoveryAgent->stop(); + this->stopDiscovery(); nautilusBike = new nautilusbike(noWriteResistance, noHeartService, testResistance, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -688,7 +718,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(nautilusBike); } else if ((b.name().toUpper().startsWith(QStringLiteral("I_FS"))) && !proformElliptical && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); proformElliptical = new proformelliptical(noWriteResistance, noHeartService); emit deviceConnected(b); connect(proformElliptical, &bluetoothdevice::connectedAndDiscovered, this, @@ -703,7 +733,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(proformElliptical); } else if ((b.name().toUpper().startsWith(QStringLiteral("I_EL"))) && !nordictrackElliptical && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); nordictrackElliptical = new nordictrackelliptical(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -719,7 +749,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(nordictrackElliptical); } else if ((b.name().toUpper().startsWith(QStringLiteral("I_VE"))) && !proformEllipticalTrainer && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); proformEllipticalTrainer = new proformellipticaltrainer(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -735,7 +765,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(proformEllipticalTrainer); innerTemplateManager->start(proformEllipticalTrainer); } else if ((b.name().toUpper().startsWith(QStringLiteral("I_RW"))) && !proformRower && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); proformRower = new proformrower(noWriteResistance, noHeartService); emit deviceConnected(b); connect(proformRower, &bluetoothdevice::connectedAndDiscovered, this, @@ -749,7 +779,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(proformRower); innerTemplateManager->start(proformRower); } else if ((b.name().toUpper().startsWith(QStringLiteral("B01_"))) && !bhFitnessElliptical && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); bhFitnessElliptical = new bhfitnesselliptical(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -772,7 +802,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { b.name().toUpper().startsWith(QStringLiteral("XG400")) || b.name().toUpper().startsWith(QStringLiteral("E98S"))) && !soleElliptical && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); soleElliptical = new soleelliptical(noWriteResistance, noHeartService, testResistance, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -796,7 +826,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { settings.setValue("bluetooth_lastdevice_address", b.deviceUuid().toString()); #endif - discoveryAgent->stop(); + this->stopDiscovery(); domyos = new domyostreadmill(this->pollDeviceTime, noConsole, noHeartService); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) stateFileRead(); @@ -833,7 +863,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { settings.setValue("bluetooth_lastdevice_address", b.deviceUuid().toString()); #endif - discoveryAgent->stop(); + this->stopDiscovery(); kingsmithR2Treadmill = new kingsmithr2treadmill(this->pollDeviceTime, noConsole, noHeartService); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) stateFileRead(); @@ -866,7 +896,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { settings.setValue("bluetooth_lastdevice_address", b.deviceUuid().toString()); #endif - discoveryAgent->stop(); + this->stopDiscovery(); kingsmithR1ProTreadmill = new kingsmithr1protreadmill(this->pollDeviceTime, noConsole, noHeartService); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) stateFileRead(); @@ -895,7 +925,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { settings.setValue("bluetooth_lastdevice_address", b.deviceUuid().toString()); #endif - discoveryAgent->stop(); + this->stopDiscovery(); shuaA5Treadmill = new shuaa5treadmill(noWriteResistance, noHeartService); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) stateFileRead(); @@ -922,7 +952,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { settings.setValue("bluetooth_lastdevice_address", b.deviceUuid().toString()); #endif - discoveryAgent->stop(); + this->stopDiscovery(); trueTreadmill = new truetreadmill(noWriteResistance, noHeartService); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) stateFileRead(); @@ -945,7 +975,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { b.name().toUpper().startsWith(QStringLiteral("F63")) || b.name().toUpper().startsWith(QStringLiteral("F85"))) && !soleF80 && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); soleF80 = new solef80treadmill(noWriteResistance, noHeartService); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) stateFileRead(); @@ -980,7 +1010,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { b.name().toUpper().startsWith(QStringLiteral("TRX4500")) || // FTMS b.name().toUpper().startsWith(QStringLiteral("ESANGLINKER"))) && !horizonTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); horizonTreadmill = new horizontreadmill(noWriteResistance, noHeartService); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) stateFileRead(); @@ -1007,7 +1037,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { b.name().toUpper().startsWith(QStringLiteral("MERACH-U3")) // FTMS ) && !technogymmyrunTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); bool technogym_myrun_treadmill_experimental = settings.value(QStringLiteral("technogym_myrun_treadmill_experimental"), false).toBool(); #ifndef Q_OS_IOS @@ -1066,7 +1096,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } else if ((b.name().toUpper().startsWith("TACX NEO") || (b.name().toUpper().startsWith("TACX SMART BIKE"))) && !tacxneo2Bike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); tacxneo2Bike = new tacxneo2(noWriteResistance, noHeartService); // stateFileRead(); emit(deviceConnected(b)); @@ -1084,7 +1114,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { (b.name().toUpper().startsWith(QStringLiteral("BIKE")) && flywheel_life_fitness_ic8 == false && b.name().length() == 6)) && !npeCableBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); npeCableBike = new npecablebike(noWriteResistance, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1105,7 +1135,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { (b.name().toUpper().startsWith("D2RIDE")) || (b.name().toUpper().startsWith("DIRETO XR")) || (b.name().toUpper().startsWith("SMB1")) || (b.name().toUpper().startsWith("INRIDE"))) && !ftmsBike && !snodeBike && !fitPlusBike && !stagesBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); ftmsBike = new ftmsbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); connect(ftmsBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); @@ -1116,7 +1146,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(ftmsBike); } else if ((b.name().toUpper().startsWith("KICKR SNAP") || b.name().toUpper().startsWith("KICKR BIKE")) && !wahooKickrSnapBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); wahooKickrSnapBike = new wahookickrsnapbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -1130,7 +1160,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } else if (((b.name().toUpper().startsWith("JFIC")) // HORIZON GR7 ) && !horizonGr7Bike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); horizonGr7Bike = new horizongr7bike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -1145,7 +1175,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { (b.name().toUpper().startsWith(QStringLiteral("ASSIOMA")) && powerSensorName.startsWith(QStringLiteral("Disabled")))) && !stagesBike && !ftmsBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); stagesBike = new stagesbike(noWriteResistance, noHeartService, false); // stateFileRead(); emit deviceConnected(b); @@ -1158,7 +1188,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(stagesBike); innerTemplateManager->start(stagesBike); } else if (b.name().startsWith(QStringLiteral("SMARTROW")) && !smartrowRower && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); smartrowRower = new smartrowrower(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); // stateFileRead(); @@ -1175,7 +1205,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } else if ((b.name().toUpper().startsWith(QStringLiteral("PM5")) && b.name().toUpper().endsWith(QStringLiteral("SKI"))) && !concept2Skierg && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); concept2Skierg = new concept2skierg(noWriteResistance, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1195,7 +1225,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { (b.name().toUpper().startsWith(QStringLiteral("PM5")) && b.name().toUpper().contains(QStringLiteral("ROW")))) && !ftmsRower && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); ftmsRower = new ftmsrower(noWriteResistance, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1210,7 +1240,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } else if ((b.name().toUpper().startsWith(QLatin1String("ECH-STRIDE")) || b.name().toUpper().startsWith(QLatin1String("ECH-SD-SPT"))) && !echelonStride && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); echelonStride = new echelonstride(this->pollDeviceTime, noConsole, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1224,7 +1254,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(echelonStride); innerTemplateManager->start(echelonStride); } else if ((b.name().toUpper().startsWith(QLatin1String("ZR7"))) && !octaneTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); octaneTreadmill = new octanetreadmill(this->pollDeviceTime, noConsole, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1240,7 +1270,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } else if ((b.name().startsWith(QStringLiteral("ECH-ROW")) || b.name().startsWith(QStringLiteral("ROW-S"))) && !echelonRower && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); echelonRower = new echelonrower(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); // stateFileRead(); @@ -1256,7 +1286,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(echelonRower); } else if (b.name().startsWith(QStringLiteral("ECH")) && !echelonRower && !echelonStride && !echelonConnectSport && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); echelonConnectSport = new echelonconnectsport(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); // stateFileRead(); @@ -1281,7 +1311,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { #else settings.setValue("bluetooth_lastdevice_address", b.deviceUuid().toString()); #endif - discoveryAgent->stop(); + this->stopDiscovery(); schwinnIC4Bike = new schwinnic4bike(noWriteResistance, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1296,7 +1326,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(schwinnIC4Bike); innerTemplateManager->start(schwinnIC4Bike); } else if (b.name().toUpper().startsWith(QStringLiteral("EW-BK")) && !sportsTechBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); sportsTechBike = new sportstechbike(noWriteResistance, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1311,7 +1341,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(sportsTechBike); innerTemplateManager->start(sportsTechBike); } else if (b.name().toUpper().startsWith(QStringLiteral("CARDIOFIT")) && !sportsPlusBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); sportsPlusBike = new sportsplusbike(noWriteResistance, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1326,7 +1356,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(sportsPlusBike); innerTemplateManager->start(sportsPlusBike); } else if (b.name().startsWith(QStringLiteral("YESOUL")) && !yesoulBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); yesoulBike = new yesoulbike(noWriteResistance, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1341,7 +1371,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(yesoulBike); } else if ((b.name().startsWith(QStringLiteral("I_EB")) || b.name().startsWith(QStringLiteral("I_SB"))) && !proformBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); proformBike = new proformbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); // stateFileRead(); @@ -1356,7 +1386,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(proformBike); innerTemplateManager->start(proformBike); } else if ((b.name().startsWith(QStringLiteral("I_TL"))) && !proformTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); proformTreadmill = new proformtreadmill(noWriteResistance, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1371,7 +1401,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(proformTreadmill); innerTemplateManager->start(proformTreadmill); } else if (b.name().toUpper().startsWith(QStringLiteral("ESLINKER")) && !eslinkerTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); eslinkerTreadmill = new eslinkertreadmill(this->pollDeviceTime, noConsole, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1387,7 +1417,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(eslinkerTreadmill); } else if (b.name().toUpper().startsWith(QStringLiteral("PAFERS_")) && !pafersTreadmill && pafers_treadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); pafersTreadmill = new paferstreadmill(this->pollDeviceTime, noConsole, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1403,7 +1433,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(pafersTreadmill); } else if (b.name().toUpper().startsWith(QStringLiteral("BOWFLEX T216")) && !bowflexT216Treadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); bowflexT216Treadmill = new bowflext216treadmill(this->pollDeviceTime, noConsole, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1418,7 +1448,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(bowflexT216Treadmill); innerTemplateManager->start(bowflexT216Treadmill); } else if (b.name().toUpper().startsWith(QStringLiteral("NAUTILUS T")) && !nautilusTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); nautilusTreadmill = new nautilustreadmill(this->pollDeviceTime, noConsole, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1437,7 +1467,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { (b.name().toUpper().startsWith(QStringLiteral("BIKE")) && flywheel_life_fitness_ic8 == true && b.name().length() == 6)) && !flywheelBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); flywheelBike = new flywheelbike(noWriteResistance, noHeartService); // stateFileRead(); emit deviceConnected(b); @@ -1452,7 +1482,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(flywheelBike); innerTemplateManager->start(flywheelBike); } else if ((b.name().toUpper().startsWith(QStringLiteral("MCF-"))) && !mcfBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); mcfBike = new mcfbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); // stateFileRead(); emit deviceConnected(b); @@ -1466,7 +1496,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(mcfBike); innerTemplateManager->start(mcfBike); } else if ((b.name().startsWith(QStringLiteral("TRX ROUTE KEY"))) && !toorx && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); toorx = new toorxtreadmill(); emit deviceConnected(b); connect(toorx, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); @@ -1476,7 +1506,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(toorx); innerTemplateManager->start(toorx); } else if ((b.name().toUpper().startsWith(QStringLiteral("BH DUALKIT"))) && !iConceptBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); iConceptBike = new iconceptbike(); emit deviceConnected(b); connect(iConceptBike, &bluetoothdevice::connectedAndDiscovered, this, @@ -1490,7 +1520,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { b.name().toUpper().startsWith(QStringLiteral("XT485")) || b.name().toUpper().startsWith(QStringLiteral("XT900"))) && !spiritTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); spiritTreadmill = new spirittreadmill(); emit deviceConnected(b); connect(spiritTreadmill, &bluetoothdevice::connectedAndDiscovered, this, @@ -1501,7 +1531,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(spiritTreadmill); innerTemplateManager->start(spiritTreadmill); } else if (b.name().toUpper().startsWith(QStringLiteral("RUNNERT")) && !activioTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); activioTreadmill = new activiotreadmill(); emit deviceConnected(b); connect(activioTreadmill, &bluetoothdevice::connectedAndDiscovered, this, @@ -1519,7 +1549,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { (b.name().toUpper().startsWith(QStringLiteral("DKN RUN"))) || (b.name().toUpper().startsWith(QStringLiteral("REEBOK")))) && !trxappgateusb && !trxappgateusbBike && !toorx_bike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); trxappgateusb = new trxappgateusbtreadmill(); emit deviceConnected(b); connect(trxappgateusb, &bluetoothdevice::connectedAndDiscovered, this, @@ -1541,7 +1571,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { b.name().toUpper().startsWith(QStringLiteral("DKN MOTION"))) && (toorx_bike))) && !trxappgateusb && !trxappgateusbBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); trxappgateusbBike = new trxappgateusbbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -1553,7 +1583,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(trxappgateusbBike); innerTemplateManager->start(trxappgateusbBike); } else if ((b.name().toUpper().startsWith(QStringLiteral("X-BIKE"))) && !ultraSportBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); ultraSportBike = new ultrasportbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -1565,7 +1595,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(ultraSportBike); innerTemplateManager->start(ultraSportBike); } else if ((b.name().toUpper().startsWith(QStringLiteral("KEEP_BIKE_"))) && !keepBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); keepBike = new keepbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); connect(keepBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); @@ -1577,7 +1607,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { } else if ((b.name().toUpper().startsWith(QStringLiteral("LCB")) || b.name().toUpper().startsWith(QStringLiteral("R92"))) && !soleBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); soleBike = new solebike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); connect(soleBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); @@ -1587,7 +1617,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(soleBike); innerTemplateManager->start(soleBike); } else if (b.name().toUpper().startsWith(QStringLiteral("BFCP")) && !skandikaWiriBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); skandikaWiriBike = new skandikawiribike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -1602,7 +1632,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { (b.name().toUpper().startsWith("SCH130")) || // not a renpho bike an FTMS one ((b.name().startsWith(QStringLiteral("TOORX"))) && toorx_ftms)) && !renphoBike && !snodeBike && !fitPlusBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); renphoBike = new renphobike(noWriteResistance, noHeartService); emit(deviceConnected(b)); connect(renphoBike, SIGNAL(connectedAndDiscovered()), this, SLOT(connectedAndDiscovered())); @@ -1612,7 +1642,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(renphoBike); innerTemplateManager->start(renphoBike); } else if ((b.name().toUpper().startsWith("PAFERS_")) && !pafersBike && !pafers_treadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); pafersBike = new pafersbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit(deviceConnected(b)); @@ -1626,7 +1656,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { b.name().startsWith(QStringLiteral("TF-"))) && // TF-769DF2 !snodeBike && !ftmsBike && !fitPlusBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); snodeBike = new snodebike(noWriteResistance, noHeartService); emit deviceConnected(b); connect(snodeBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); @@ -1637,7 +1667,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(snodeBike); } else if ((b.name().startsWith(QStringLiteral("FS-")) && fitplus_bike) && !fitPlusBike && !ftmsBike && !snodeBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); fitPlusBike = new fitplusbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); emit deviceConnected(b); @@ -1653,7 +1683,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { (b.name().startsWith(QStringLiteral("SW")) && b.name().length() == 14) || (b.name().startsWith(QStringLiteral("BF70")))) && !fitshowTreadmill && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); fitshowTreadmill = new fitshowtreadmill(this->pollDeviceTime, noConsole, noHeartService); emit deviceConnected(b); connect(fitshowTreadmill, &bluetoothdevice::connectedAndDiscovered, this, @@ -1667,7 +1697,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(fitshowTreadmill); } else if (b.name().toUpper().startsWith(QStringLiteral("IC")) && b.name().length() == 8 && !inspireBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); inspireBike = new inspirebike(noWriteResistance, noHeartService); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) stateFileRead(); @@ -1689,7 +1719,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(inspireBike); innerTemplateManager->start(inspireBike); } else if (b.name().toUpper().startsWith(QStringLiteral("CHRONO ")) && !chronoBike && filter) { - discoveryAgent->stop(); + this->stopDiscovery(); chronoBike = new chronobike(noWriteResistance, noHeartService); #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) stateFileRead(); diff --git a/src/bluetooth.h b/src/bluetooth.h index a057d6892..cdd912625 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -127,6 +127,11 @@ class bluetooth : public QObject, public SignalHandler { */ void startDiscovery(); + /** + * @brief stopDiscovery Stop the Bluetooth discovery agent and the thread that discovers non-bluetooth devices. + */ + void stopDiscovery(); + /** * @brief discoverNonBluetoothDevices Discover non-bluetooth devices and create an object for the first. * @return An object for the first non-bluetooth device found. @@ -142,6 +147,10 @@ class bluetooth : public QObject, public SignalHandler { TemplateInfoSenderBuilder *userTemplateManager = nullptr; TemplateInfoSenderBuilder *innerTemplateManager = nullptr; QFile *debugCommsLog = nullptr; + // Indicates generally discovering, bluetooth and others + bool discovering = false; + // Indicates the non-bluetooth discovery is active + bool discoveringNonBluetooth = false; QBluetoothDeviceDiscoveryAgent *discoveryAgent; bhfitnesselliptical *bhFitnessElliptical = nullptr; bowflextreadmill *bowflexTreadmill = nullptr; diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 39f68b5ee..b4a43329c 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -279,8 +279,7 @@ trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartSer m_watt.setType(metric::METRIC_WATT); Speed.setType(metric::METRIC_SPEED); - // use a percentage resistance until QZ is using more than 7 bits to store the resistance levels. - this->useResistancePercentage = true; + this->useResistancePercentage = false; // Set the fake bluetooth device info this->bluetoothDevice = @@ -425,13 +424,13 @@ void trixterxdreamv1bike::configureVirtualBike(){ // ******************************************************************************************************** } -uint16_t trixterxdreamv1bike::powerFromResistanceRequest(int8_t requestedResistance) +uint16_t trixterxdreamv1bike::powerFromResistanceRequest(resistance_t requestedResistance) { requestedResistance = this->adjustedResistance(requestedResistance, true); return this->calculatePower((int)this->Cadence.value(), requestedResistance); } -uint8_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) +resistance_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) { int c = std::max(0, std::min(9, (int)(0.1*(this->Cadence.value()-30) +0.5))); @@ -444,7 +443,10 @@ uint8_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) if(result<0) result = (ps-1)[1]; + result += this->brakeLevel; + result = this->adjustedResistance(result, false); + result = std::min((int16_t)trixterxdreamv1client::MaxResistance, std::max((int16_t)0, result)); return result; } @@ -465,7 +467,7 @@ double trixterxdreamv1bike::calculatePower(int cadenceRPM, int resistance) { return ps[2]; } -int16_t trixterxdreamv1bike::adjustedResistance(int16_t input, bool toDevice) { +resistance_t trixterxdreamv1bike::adjustedResistance(resistance_t input, bool toDevice) { if(this->useResistancePercentage){ if(toDevice) return trixterxdreamv1client::MaxResistance * input / 100; @@ -527,6 +529,11 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // Determine if the user is pressing the button to stop. this->stopping = (state.Buttons & trixterxdreamv1client::buttons::Red) != 0; + constexpr double brakeScale = 125.0/(trixterxdreamv1client::MaxBrake-trixterxdreamv1client::MinBrake); + uint8_t b1 = 125 - (state.Brake1 - trixterxdreamv1client::MinBrake) * brakeScale; + uint8_t b2 = 125 - (state.Brake2 - trixterxdreamv1client::MinBrake) * brakeScale; + this->brakeLevel = b1 + b2; + // update the metrics this->LastCrankEventTime = state.LastEventTime; @@ -625,7 +632,7 @@ void trixterxdreamv1bike::calculateSteeringMap() { } -void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { +void trixterxdreamv1bike::changeResistance(resistance_t resistanceLevel) { // ignore the resistance if this option was selected if(this->noWriteResistance) return; @@ -640,6 +647,7 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { // store the resistance level as a metric for the UI constexpr double pelotonScaleFactor = 100.0 / trixterxdreamv1client::MaxResistance; + this->Resistance.setValue(resistanceLevel); if(this->useResistancePercentage) this->m_pelotonResistance.setValue(resistanceLevel); @@ -653,7 +661,7 @@ void trixterxdreamv1bike::changeResistance(int8_t resistanceLevel) { void trixterxdreamv1bike::updateResistance() { QMutexLocker locker(&this->updateMutex); - uint8_t actualResistance = this->stopping ? (trixterxdreamv1client::MaxResistance): this->resistanceLevel; + resistance_t actualResistance = this->stopping ? (trixterxdreamv1client::MaxResistance): this->resistanceLevel; this->client.SendResistance(actualResistance); } @@ -680,7 +688,7 @@ void trixterxdreamv1bike::set_wheelDiameter(double value) { } -int trixterxdreamv1bike::pelotonToBikeResistance(int pelotonResistance) { +resistance_t trixterxdreamv1bike::pelotonToBikeResistance(int pelotonResistance) { pelotonResistance = std::max(0, std::min(100, pelotonResistance)); if(this->useResistancePercentage) diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index bc9152ca5..6e6d6065d 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -41,6 +41,11 @@ class trixterxdreamv1bike : public bike */ bool stopping = false; + /** + * @brief brakeLevel Sum of brakes 1 and 2 each normalised to 0..125. + */ + uint8_t brakeLevel = 0; + /** * @brief resistanceTimerId The id for identifying the resistance timer in void timerEvent(QEvent*). */ @@ -79,7 +84,7 @@ class trixterxdreamv1bike : public bike /** * @brief resistanceLevel The last requested resistance level. */ - uint8_t resistanceLevel = 0; + resistance_t resistanceLevel = 0; /** * @brief useResistancePercentage Option to use resistance levels 0..100 instead of @@ -181,7 +186,7 @@ class trixterxdreamv1bike : public bike * @param toDevice The direction of the conversion. * @return */ - int16_t adjustedResistance(int16_t input, bool toDevice); + resistance_t adjustedResistance(resistance_t input, bool toDevice); protected: /** @@ -199,7 +204,7 @@ public Q_SLOTS: * @brief changeResistance Called to change the requested resistance level. * @param resistanceLevel The resistance level to request (0..maximumResistance()) */ - void changeResistance(int8_t resistanceLevel) override; + void changeResistance(resistance_t resistanceLevel) override; public: @@ -240,14 +245,14 @@ public Q_SLOTS: * @param requestedResistance * @return */ - uint16_t powerFromResistanceRequest(int8_t requestedResistance) override; + uint16_t powerFromResistanceRequest(resistance_t requestedResistance) override; /** * @brief resistanceFromPowerRequest Calculate the resistance required to produce the requested power at the current cadence. * @param power * @return */ - uint8_t resistanceFromPowerRequest(uint16_t power) override; + resistance_t resistanceFromPowerRequest(uint16_t power) override; /** * @brief VirtualDevice Virtual device @@ -281,14 +286,14 @@ public Q_SLOTS: * @brief maxResistance The maximum resistance supported. * @return */ - uint8_t maxResistance() override { return this->useResistancePercentage ? 100:trixterxdreamv1client::MaxResistance; } + resistance_t maxResistance() override { return this->useResistancePercentage ? 100:trixterxdreamv1client::MaxResistance; } /** * @brief pelotonToBikeResistance Map Peloton 0 to 100% resistance to the bike's range. * @param pelotonResistance The Peloton resistance. Range: 0 to 100. * @return The Trixter X-Dream V1 bike resistance. Range 0..250 if !this->useResistancePercentage. */ - int pelotonToBikeResistance(int pelotonResistance) override; + resistance_t pelotonToBikeResistance(int pelotonResistance) override; /** * @brief tryCreate Attempt to create an object to interact with an existing Trixter X-Dream V1 bike on a specific serial port, From 81741ac7ea4b708ce9e3099c350e5f93a0c0a042 Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 24 Aug 2022 00:47:48 +0100 Subject: [PATCH 064/255] #855 feed brake value into watt output for experimentation --- src/trixterxdreamv1bike.cpp | 4 +--- src/trixterxdreamv1client.cpp | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index b4a43329c..8d348f7db 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -443,8 +443,6 @@ resistance_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) if(result<0) result = (ps-1)[1]; - result += this->brakeLevel; - result = this->adjustedResistance(result, false); result = std::min((int16_t)trixterxdreamv1client::MaxResistance, std::max((int16_t)0, result)); return result; @@ -548,7 +546,7 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { this->Cadence.setValue(state.CrankRPM); // update the power output - this->update_metrics(true, this->calculatePower(state.CrankRPM, this->resistanceLevel)); + this->update_metrics(true, this->brakeLevel + this->calculatePower(state.CrankRPM, this->resistanceLevel)); // set the crank revolutions this->CrankRevs = state.CumulativeCrankRevolutions; diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp index cb6122f1d..fee118336 100644 --- a/src/trixterxdreamv1client.cpp +++ b/src/trixterxdreamv1client.cpp @@ -172,8 +172,8 @@ bool trixterxdreamv1client::ReceiveChar(char c) { newState.CrankRPM = static_cast(crankRevsPerMinute); newState.FlywheelRPM = static_cast(flywheelRevsPerMinute); newState.Buttons = (buttons)(0xFFFF-lastPacket.Buttons); - - + newState.Brake1 = lastPacket.Brake1; + newState.Brake2 = lastPacket.Brake2; this->stateMutex.lock(); this->lastState = newState; From 016ebc5070ddb5e754e0dad5e03b8319d44f59aa Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 27 Aug 2022 23:16:48 +0100 Subject: [PATCH 065/255] #855 do something with the requestedResistance field if it's not -1 --- src/trixterxdreamv1bike.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 8d348f7db..2e1bffc72 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -545,6 +545,12 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // set the cadence in revolutions per minute this->Cadence.setValue(state.CrankRPM); + // check if there's a request for a resistance level + if(this->requestResistance!=-1) { + this->changeResistance(this->requestResistance); + this->requestResistance = -1; + } + // update the power output this->update_metrics(true, this->brakeLevel + this->calculatePower(state.CrankRPM, this->resistanceLevel)); From 3d2658211468f3e6e7f0740e55b1f96350c456fb Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 28 Aug 2022 20:23:36 +0100 Subject: [PATCH 066/255] #855 apply double the power boost from the brake levers. Debug log the requestResistance changes. --- src/trixterxdreamv1bike.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 2e1bffc72..6121457a7 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -547,12 +547,13 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // check if there's a request for a resistance level if(this->requestResistance!=-1) { + qDebug() << "requestResistance=" << this->requestResistance; this->changeResistance(this->requestResistance); this->requestResistance = -1; } // update the power output - this->update_metrics(true, this->brakeLevel + this->calculatePower(state.CrankRPM, this->resistanceLevel)); + this->update_metrics(true, this->brakeLevel + this->brakeLevel + this->calculatePower(state.CrankRPM, this->resistanceLevel)); // set the crank revolutions this->CrankRevs = state.CumulativeCrankRevolutions; From ce2c86bfe6b78d26c2c2a07954cc8edf79ba8b01 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 28 Aug 2022 23:28:50 +0100 Subject: [PATCH 067/255] #855 try a 4kb read buffer on the serial port. --- src/trixterxdreamv1serial.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 3f002d130..71ce00aa6 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -76,6 +76,7 @@ void trixterxdreamv1serial::run() { this->serial.setStopBits(QSerialPort::OneStop); this->serial.setFlowControl(QSerialPort::NoFlowControl); this->serial.setParity(QSerialPort::NoParity); + this->serial.setReadBufferSize(4096); bool openResult = false; @@ -93,7 +94,7 @@ void trixterxdreamv1serial::run() { return; } - qDebug() << "Serial port" << this->portName << "opened"; + qDebug() << "Serial port " << this->portName << " opened with read buffer size=" << this->serial.readBufferSize(); while (!this->quitPending) { QByteArray requestData; From ad6cebae278ddad170d909e3779cf25ef19a325e Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 28 Aug 2022 23:30:20 +0100 Subject: [PATCH 068/255] #855 rework setting of resistance so that UI goes through the slot and resistance sent is updated by watching the requestResistance field. --- src/trixterxdreamv1bike.cpp | 7 ++----- src/trixterxdreamv1bike.h | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 6121457a7..828e062ab 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -547,8 +547,7 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // check if there's a request for a resistance level if(this->requestResistance!=-1) { - qDebug() << "requestResistance=" << this->requestResistance; - this->changeResistance(this->requestResistance); + this->setResistance(this->requestResistance); this->requestResistance = -1; } @@ -637,7 +636,7 @@ void trixterxdreamv1bike::calculateSteeringMap() { } -void trixterxdreamv1bike::changeResistance(resistance_t resistanceLevel) { +void trixterxdreamv1bike::setResistance(resistance_t resistanceLevel) { // ignore the resistance if this option was selected if(this->noWriteResistance) return; @@ -648,8 +647,6 @@ void trixterxdreamv1bike::changeResistance(resistance_t resistanceLevel) { if(resistanceLevel<0) resistanceLevel = 0; if(resistanceLevel>maxResistance()) resistanceLevel = maxResistance(); - bike::changeResistance(resistanceLevel); - // store the resistance level as a metric for the UI constexpr double pelotonScaleFactor = 100.0 / trixterxdreamv1client::MaxResistance; diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 6e6d6065d..177e1f1e3 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -201,10 +201,10 @@ class trixterxdreamv1bike : public bike void disconnectPort(); public Q_SLOTS: /** - * @brief changeResistance Called to change the requested resistance level. + * @brief changeResistance Called to set the resistance level sent to the device. * @param resistanceLevel The resistance level to request (0..maximumResistance()) */ - void changeResistance(resistance_t resistanceLevel) override; + void setResistance(resistance_t resistanceLevel); public: From 69ccfdff49ff58521ba46806c828d8ffcf1da5db Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 3 Sep 2022 17:44:14 +0100 Subject: [PATCH 069/255] #855 move set_resistance out of the slots section --- src/trixterxdreamv1bike.cpp | 6 +++--- src/trixterxdreamv1bike.h | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 828e062ab..5817dd0c9 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -444,7 +444,7 @@ resistance_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) result = (ps-1)[1]; result = this->adjustedResistance(result, false); - result = std::min((int16_t)trixterxdreamv1client::MaxResistance, std::max((int16_t)0, result)); + result = std::min((resistance_t)trixterxdreamv1client::MaxResistance, std::max((resistance_t)0, result)); return result; } @@ -547,7 +547,7 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // check if there's a request for a resistance level if(this->requestResistance!=-1) { - this->setResistance(this->requestResistance); + this->set_resistance(this->requestResistance); this->requestResistance = -1; } @@ -636,7 +636,7 @@ void trixterxdreamv1bike::calculateSteeringMap() { } -void trixterxdreamv1bike::setResistance(resistance_t resistanceLevel) { +void trixterxdreamv1bike::set_resistance(resistance_t resistanceLevel) { // ignore the resistance if this option was selected if(this->noWriteResistance) return; diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 177e1f1e3..85242509e 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -187,6 +187,12 @@ class trixterxdreamv1bike : public bike * @return */ resistance_t adjustedResistance(resistance_t input, bool toDevice); + + /** + * @brief set_resistance Called to set the resistance level sent to the device. + * @param resistanceLevel The resistance level to request (0..maximumResistance()) + */ + void set_resistance(resistance_t resistanceLevel); protected: /** @@ -199,13 +205,6 @@ class trixterxdreamv1bike : public bike * @brief disconnectPort Disconnect the serial port and resistance timer. */ void disconnectPort(); -public Q_SLOTS: - /** - * @brief changeResistance Called to set the resistance level sent to the device. - * @param resistanceLevel The resistance level to request (0..maximumResistance()) - */ - void setResistance(resistance_t resistanceLevel); - public: From e7b53b6c88830e3a2d742156e740a2d2d3625208 Mon Sep 17 00:00:00 2001 From: David Mason Date: Tue, 6 Sep 2022 21:33:59 +0100 Subject: [PATCH 070/255] #855 emit resistanceRead --- src/trixterxdreamv1bike.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 5817dd0c9..27fda2a95 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -649,8 +649,12 @@ void trixterxdreamv1bike::set_resistance(resistance_t resistanceLevel) { // store the resistance level as a metric for the UI constexpr double pelotonScaleFactor = 100.0 / trixterxdreamv1client::MaxResistance; + bool resistanceChanged = false; - this->Resistance.setValue(resistanceLevel); + if(resistanceLevel != (resistance_t)this->Resistance.value()) { + this->Resistance.setValue(resistanceLevel); + resistanceChanged = true; + } if(this->useResistancePercentage) this->m_pelotonResistance.setValue(resistanceLevel); else @@ -659,6 +663,11 @@ void trixterxdreamv1bike::set_resistance(resistance_t resistanceLevel) { // store the new resistance level. This might be the same as lastRequestedResistance(),Value // but it doesn't involve a function call and a cast to get the value. this->resistanceLevel = this->adjustedResistance(resistanceLevel, true); + + // if there's been a change of resistance, signal it. + if(resistanceChanged) + emit this->resistanceRead(resistanceLevel); + } void trixterxdreamv1bike::updateResistance() { From c2efdca6c8526200519df298f7c8175485e7bc1e Mon Sep 17 00:00:00 2001 From: David Mason Date: Tue, 6 Sep 2022 21:46:08 +0100 Subject: [PATCH 071/255] #855 moved some functionality to cpp file --- src/trixterxdreamv1serial.cpp | 9 +++++++++ src/trixterxdreamv1serial.h | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 71ce00aa6..c539a6a7f 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -16,6 +16,15 @@ QList trixterxdreamv1serial::availablePorts() { return QSerialPortInfo::availablePorts(); } +void trixterxdreamv1serial::receive(const QByteArray &bytes) { + if(this->receiveBytes) + this->receiveBytes(bytes); +} + +void trixterxdreamv1serial::error(const QString &s) { + qDebug() << "Error in trixterxdreamv1serial: " << s; +} + bool trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate baudRate) { QMutexLocker locker(&this->mutex); diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index 9254142f4..7a1fa6e22 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -62,13 +62,13 @@ class trixterxdreamv1serial : public QThread { * @brief receive Override this to process received data. * @param bytes */ - virtual void receive(const QByteArray &bytes) { if(this->receiveBytes) this->receiveBytes(bytes); } + virtual void receive(const QByteArray &bytes); /** * @brief error Log an error. * @param s The error text. */ - virtual void error(const QString &s) {} + virtual void error(const QString &s); private: void run() override; From 68d250e7e9ab747ed0ae58709c086631ef00072c Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 7 Sep 2022 00:52:00 +0100 Subject: [PATCH 072/255] Create QSerialPort in run method of parent. Seems more reliable. --- src/trixterxdreamv1serial.cpp | 44 +++++++++++++++++++++-------------- src/trixterxdreamv1serial.h | 2 +- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index c539a6a7f..8fa5b4196 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -8,8 +8,13 @@ trixterxdreamv1serial::trixterxdreamv1serial(QObject *parent) : QThread(parent){} trixterxdreamv1serial::~trixterxdreamv1serial() { - this->quitPending = true; - this->wait(); + if(this->serial) { + this->quitPending = true; + this->wait(); + + if(this->serial) + delete this->serial; + } } QList trixterxdreamv1serial::availablePorts() { @@ -52,7 +57,7 @@ bool trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate } locker.relock(); - return serial.isOpen(); + return this->serial && this->serial->isOpen(); } void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { @@ -65,7 +70,7 @@ void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { QMutexLocker locker(&this->mutex); // write the data - qint64 o = this->serial.write(buffer); + qint64 o = this->serial->write(buffer); locker.unlock(); @@ -79,18 +84,19 @@ void trixterxdreamv1serial::set_SendReceiveLog(bool value) { this->sendReceiveLo void trixterxdreamv1serial::run() { - this->serial.setPortName(this->portName); - this->serial.setBaudRate(this->baudRate); - this->serial.setDataBits(QSerialPort::Data8); - this->serial.setStopBits(QSerialPort::OneStop); - this->serial.setFlowControl(QSerialPort::NoFlowControl); - this->serial.setParity(QSerialPort::NoParity); - this->serial.setReadBufferSize(4096); + this->serial = new QSerialPort(this); + this->serial->setPortName(this->portName); + this->serial->setBaudRate(this->baudRate); + this->serial->setDataBits(QSerialPort::Data8); + this->serial->setStopBits(QSerialPort::OneStop); + this->serial->setFlowControl(QSerialPort::NoFlowControl); + this->serial->setParity(QSerialPort::NoParity); + this->serial->setReadBufferSize(4096); bool openResult = false; try { - openResult = serial.open(QIODevice::ReadWrite); + openResult = serial->open(QIODevice::ReadWrite); this->openAttemptsPending = 0; } catch(...) { this->openAttemptsPending = 0; @@ -98,12 +104,12 @@ void trixterxdreamv1serial::run() { } if (!openResult) { - qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error()); - this->error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error())); + qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial->error()); + this->error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial->error())); return; } - qDebug() << "Serial port " << this->portName << " opened with read buffer size=" << this->serial.readBufferSize(); + qDebug() << "Serial port " << this->portName << " opened with read buffer size=" << this->serial->readBufferSize(); while (!this->quitPending) { QByteArray requestData; @@ -116,8 +122,8 @@ void trixterxdreamv1serial::run() { // try to read some bytes, but only block for 1ms because a write attempt could come in. int quit = 0; - while (!(quit=this->quitPending) && this->serial.waitForReadyRead(1)) - requestData += this->serial.readAll(); + while (!(quit=this->quitPending) && this->serial->waitForReadyRead(1)) + requestData += this->serial->readAll(); // release the mutex locker.unlock(); @@ -140,6 +146,8 @@ void trixterxdreamv1serial::run() { } } - this->serial.close(); + this->serial->close(); qDebug() << "Serial port closed"; + delete this->serial; + this->serial = nullptr; } diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index 7a1fa6e22..21951ec2b 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -74,7 +74,7 @@ class trixterxdreamv1serial : public QThread { void run() override; bool sendReceiveLog = false; - QSerialPort serial; + QSerialPort * serial = nullptr; QString portName; QSerialPort::BaudRate baudRate; QMutex mutex; From 3eafd142e3fff305c807136ef6d656d217f599d0 Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 7 Sep 2022 01:22:03 +0100 Subject: [PATCH 073/255] Doubled power boost from brake levers --- src/trixterxdreamv1bike.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 27fda2a95..6114879a5 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -552,7 +552,8 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { } // update the power output - this->update_metrics(true, this->brakeLevel + this->brakeLevel + this->calculatePower(state.CrankRPM, this->resistanceLevel)); + double powerBoost = 4.0 * this->brakeLevel; + this->update_metrics(true, powerBoost + this->calculatePower(state.CrankRPM, this->resistanceLevel)); // set the crank revolutions this->CrankRevs = state.CumulativeCrankRevolutions; From aee85c6d0d0f8cb35978d12e40f2e6e65319d1aa Mon Sep 17 00:00:00 2001 From: David Mason Date: Thu, 8 Sep 2022 22:02:38 +0100 Subject: [PATCH 074/255] #855 rework trixterxdreamv1serial so that reads and writes are done on the same thread. --- src/trixterxdreamv1bike.cpp | 2 +- src/trixterxdreamv1serial.cpp | 87 ++++++++++++++++------------------- src/trixterxdreamv1serial.h | 7 +-- 3 files changed, 45 insertions(+), 51 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 6114879a5..75542e16d 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -322,7 +322,7 @@ bool trixterxdreamv1bike::connect(QString portName) { // tell the client how to send data to the device if(!noWriteResistance) - this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(QByteArray((const char *)bytes, length), "");}); + this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(QByteArray((const char *)bytes, length));}); // Set up a stopwatch to time the connection operations QElapsedTimer stopWatch; diff --git a/src/trixterxdreamv1serial.cpp b/src/trixterxdreamv1serial.cpp index 8fa5b4196..32fd89a2f 100644 --- a/src/trixterxdreamv1serial.cpp +++ b/src/trixterxdreamv1serial.cpp @@ -8,13 +8,8 @@ trixterxdreamv1serial::trixterxdreamv1serial(QObject *parent) : QThread(parent){} trixterxdreamv1serial::~trixterxdreamv1serial() { - if(this->serial) { - this->quitPending = true; - this->wait(); - - if(this->serial) - delete this->serial; - } + this->quitPending = true; + this->wait(); } QList trixterxdreamv1serial::availablePorts() { @@ -57,25 +52,14 @@ bool trixterxdreamv1serial::open(const QString &portName, QSerialPort::BaudRate } locker.relock(); - return this->serial && this->serial->isOpen(); + return this->isRunning(); } -void trixterxdreamv1serial::write(const QByteArray& buffer, QString info) { - bool log = this->get_SendReceiveLog(); - - if(log) - qDebug() << "serial >> " << buffer.toHex() << "//" << info; - - // obtain a mutex lock to avoid writing during a read - QMutexLocker locker(&this->mutex); - - // write the data - qint64 o = this->serial->write(buffer); - - locker.unlock(); +void trixterxdreamv1serial::write(const QByteArray& buffer) { + QMutexLocker locker(&this->writeBufferMutex); - if(log) - qDebug() << "serial byte written" << o; + this->writeBuffer = buffer; + this->writePending = 1; } bool trixterxdreamv1serial::get_SendReceiveLog() { return this->sendReceiveLog; } @@ -84,19 +68,20 @@ void trixterxdreamv1serial::set_SendReceiveLog(bool value) { this->sendReceiveLo void trixterxdreamv1serial::run() { - this->serial = new QSerialPort(this); - this->serial->setPortName(this->portName); - this->serial->setBaudRate(this->baudRate); - this->serial->setDataBits(QSerialPort::Data8); - this->serial->setStopBits(QSerialPort::OneStop); - this->serial->setFlowControl(QSerialPort::NoFlowControl); - this->serial->setParity(QSerialPort::NoParity); - this->serial->setReadBufferSize(4096); + QSerialPort serial { this }; + + serial.setPortName(this->portName); + serial.setBaudRate(this->baudRate); + serial.setDataBits(QSerialPort::Data8); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + serial.setParity(QSerialPort::NoParity); + serial.setReadBufferSize(4096); bool openResult = false; try { - openResult = serial->open(QIODevice::ReadWrite); + openResult = serial.open(QIODevice::ReadWrite); this->openAttemptsPending = 0; } catch(...) { this->openAttemptsPending = 0; @@ -104,12 +89,12 @@ void trixterxdreamv1serial::run() { } if (!openResult) { - qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial->error()); - this->error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial->error())); + qDebug() << tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error()); + this->error(tr("Can't open %1, error code %2").arg(this->portName).arg(serial.error())); return; } - qDebug() << "Serial port " << this->portName << " opened with read buffer size=" << this->serial->readBufferSize(); + qDebug() << "Serial port " << this->portName << " opened with read buffer size=" << serial.readBufferSize(); while (!this->quitPending) { QByteArray requestData; @@ -117,18 +102,27 @@ void trixterxdreamv1serial::run() { bool log = this->get_SendReceiveLog(); - // Obtain a mutex lock so it's not waiting for ready read while trying to write... - QMutexLocker locker(&this->mutex); + if(this->writePending) { + QMutexLocker locker{&this->writeBufferMutex}; - // try to read some bytes, but only block for 1ms because a write attempt could come in. - int quit = 0; - while (!(quit=this->quitPending) && this->serial->waitForReadyRead(1)) - requestData += this->serial->readAll(); + try { + this->writePending = 0; + serial.write(this->writeBuffer); + } catch(std::exception const& e) { + qDebug() << "Exception thrown by QSerialPort::write : " << e.what(); + throw; + } catch(...) { + qDebug() << "Error thrown by QSerialPort::write"; + throw; + } - // release the mutex - locker.unlock(); + if(log) + qDebug() << "write " << this->writeBuffer.size() << " bytes to serial port"; + } - if(quit) break; + // try to read some bytes, but only block for 1ms because a write attempt could come in. + while (!this->quitPending && serial.waitForReadyRead(1)) + requestData += serial.readAll(); if(requestData.length()>0) { @@ -146,8 +140,7 @@ void trixterxdreamv1serial::run() { } } - this->serial->close(); + serial.close(); qDebug() << "Serial port closed"; - delete this->serial; - this->serial = nullptr; + } diff --git a/src/trixterxdreamv1serial.h b/src/trixterxdreamv1serial.h index 21951ec2b..2afe110aa 100644 --- a/src/trixterxdreamv1serial.h +++ b/src/trixterxdreamv1serial.h @@ -29,9 +29,8 @@ class trixterxdreamv1serial : public QThread { /** * @brief Writes the array of bytes to the serial port * @param buffer The bytes to send. - * @param info Debug information */ - void write(const QByteArray& buffer, QString info); + void write(const QByteArray& buffer); /** * @brief set_receiveBytes Set a delegate to receive bytes. This is an alternative @@ -73,8 +72,10 @@ class trixterxdreamv1serial : public QThread { private: void run() override; + QMutex writeBufferMutex; + QByteArray writeBuffer; + QAtomicInt writePending {0}; bool sendReceiveLog = false; - QSerialPort * serial = nullptr; QString portName; QSerialPort::BaudRate baudRate; QMutex mutex; From 37899a2c3c5bea68b6c2d3907a42041bbeccf69e Mon Sep 17 00:00:00 2001 From: David Mason Date: Tue, 13 Sep 2022 21:30:32 +0100 Subject: [PATCH 075/255] #855 fixed merge conflict --- src/bluetooth.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/bluetooth.h b/src/bluetooth.h index 7e1881f73..4a3b5f127 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -124,16 +124,6 @@ class bluetooth : public QObject, public SignalHandler { TemplateInfoSenderBuilder *getUserTemplateManager() const { return userTemplateManager; } TemplateInfoSenderBuilder *getInnerTemplateManager() const { return innerTemplateManager; } protected: - /** - * @brief startDiscovery Start the Bluetooth discovery agent and the thread that discovers non-bluetooth devices. - */ - void startDiscovery(); - - /** - * @brief stopDiscovery Stop the Bluetooth discovery agent and the thread that discovers non-bluetooth devices. - */ - void stopDiscovery(); - /** * @brief discoverNonBluetoothDevices Discover non-bluetooth devices and create an object for the first. * @return An object for the first non-bluetooth device found. From ccc97392ab41de776396825b4b7c5d71663e0fdd Mon Sep 17 00:00:00 2001 From: David Mason Date: Tue, 13 Sep 2022 23:36:28 +0100 Subject: [PATCH 076/255] #855 attempt to spend less of the serial port thread's time updating the metrics by queuing the read client states and updating the metrics only once every 100ms, instead of probably every 13ms. Will observe effect on bike's response to resistance signals as they may become more regular. --- src/trixterxdreamv1bike.cpp | 64 ++++++++++++----- src/trixterxdreamv1bike.h | 136 ++++++++++++++++++++++-------------- 2 files changed, 130 insertions(+), 70 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 75542e16d..1f1c85717 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -312,7 +312,7 @@ bool trixterxdreamv1bike::connect(QString portName) { // create the port object and connect it auto thisObject = this; this->port = new trixterxdreamv1serial(this); - this->port->set_receiveBytes([thisObject](const QByteArray& bytes)->void{thisObject->update(bytes);}); + this->port->set_receiveBytes([thisObject](const QByteArray& bytes)->void{thisObject->receiveBytes(bytes);}); // References to objects for callbacks auto device=this->port; @@ -334,6 +334,14 @@ bool trixterxdreamv1bike::connect(QString portName) { return false; } + // Start the metrics update timer + this->metricsUpdateTimerId = this->startTimer(UpdateMetricsInterval, Qt::PreciseTimer); + if(this->metricsUpdateTimerId==0) + { + qDebug() << "Failed to start metrics update timer"; + throw "Failed to start metrics timer"; + } + // wait for up to the configured connection timeout for some packets to arrive for(uint32_t start = getTime(), t=start, limit=start+this->appSettings->get_connectionTimeoutMilliseconds(); tconnected()) { @@ -377,6 +385,11 @@ void trixterxdreamv1bike::disconnectPort() { delete this->port; this->port = nullptr; } + if(this->metricsUpdateTimerId) { + qDebug() << "Killing metricsUpdate timer"; + this->killTimer(this->metricsUpdateTimerId); + this->metricsUpdateTimerId = 0; + } if(this->resistanceTimerId) { qDebug() << "Killing resistance timer"; this->killTimer(this->resistanceTimerId); @@ -477,14 +490,13 @@ resistance_t trixterxdreamv1bike::adjustedResistance(resistance_t input, bool to bool trixterxdreamv1bike::connected() { - QMutexLocker locker(&this->updateMutex); - return (this->getTime()-this->lastPacketProcessedTime) < DisconnectionTimeout; + QMutexLocker locker(&this->unprocessedStatesMutex); + return !this->unprocessedStates.empty(); } uint32_t trixterxdreamv1bike::getTime() { - auto currentDateTime = QDateTime::currentDateTime(); - auto ms = currentDateTime.toMSecsSinceEpoch(); + auto ms = QDateTime::currentMSecsSinceEpoch(); return static_cast(ms); } @@ -494,30 +506,52 @@ void trixterxdreamv1bike::timerEvent(QTimerEvent *event) { if(timerId==this->resistanceTimerId){ event->accept(); this->updateResistance(); + } else if(timerId==this->metricsUpdateTimerId) { + event->accept(); + this->update(); } else if(timerId==this->settingsUpdateTimerId) { event->accept(); this->appSettings->Load(); } } -bool trixterxdreamv1bike::updateClient(const QByteArray& bytes, trixterxdreamv1client * client) { +void trixterxdreamv1bike::receiveBytes(const QByteArray &bytes) { + + // send the bytes to the client and return if there's no change of state bool stateChanged = false; for(int i=0; iReceiveChar(bytes[i]); + stateChanged |= this->client.ReceiveChar(bytes[i]); - return stateChanged; + if(!stateChanged) + return; + + QMutexLocker locker(&this->unprocessedStatesMutex); + + auto timeLimit = getTime() - UpdateMetricsInterval; + queue * ups = &this->unprocessedStates; + while(!ups->empty() && ups->front().LastEventTimepop(); + ups->push(this->client.getLastState()); } -void trixterxdreamv1bike::update(const QByteArray &bytes) { +void trixterxdreamv1bike::update() { QMutexLocker locker(&this->updateMutex); - // send the bytes to the client and return if there's no change of state - if(!updateClient(bytes, &this->client)) - return; + QMutexLocker statesLocker(&this->unprocessedStatesMutex); + queue * ups = &this->unprocessedStates; + std::vector pendingStates{ups->size()}; + while(!ups->empty()) { + pendingStates.push_back(ups->front()); + ups->pop(); + } + statesLocker.unlock(); + + for(auto state : pendingStates) + this->update(state); +} - // Take the most recent state read - auto state = this->client.getLastState(); +void trixterxdreamv1bike::update(const trixterxdreamv1client::state &state) { auto currentTime = getTime(); // update the packet count @@ -590,8 +624,6 @@ void trixterxdreamv1bike::update(const QByteArray &bytes) { // set the elapsed time this->elapsed = (currentTime - this->t0) * 0.001; - locker.unlock(); - if(steeringAngleChanged) emit this->steeringAngleChanged(this->m_steeringAngle.value()); } diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 85242509e..1b5ca3cc8 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -4,6 +4,7 @@ #include "trixterxdreamv1serial.h" #include "trixterxdreamv1settings.h" #include "virtualbike.h" +#include class trixterxdreamv1bike : public bike { @@ -16,84 +17,100 @@ class trixterxdreamv1bike : public bike constexpr static int SettingsUpdateTimerIntervalMilliseconds = 10000; /** - * @brief powerSurface Mapping from cadence and resistance to power. + * @brief Mapping from cadence and resistance to power. */ static double powerSurface[260][3]; /** - * @brief client An object that processes incoming data to CSCS, heart rate and steering data + * @brief A queue of states read from the client. + */ + std::queue unprocessedStates; + + /** + * @brief Mutex for accessing the unprocessedStates queue. + */ + QMutex unprocessedStatesMutex; + + /** + * @brief An object that processes incoming data to CSCS, heart rate and steering data */ trixterxdreamv1client client; /** - * @brief port An object that monitors a serial port to read incoming data, and to write + * @brief An object that monitors a serial port to read incoming data, and to write * resistance level requests. */ trixterxdreamv1serial * port = nullptr; /** - * @brief virtualBike The bridge to the client application. + * @brief The bridge to the client application. */ virtualbike * virtualBike = nullptr; /** - * @brief stopping Indicates if the deice should be sent full resistance instead of the currently requested resistance. + * @brief Indicates if the deice should be sent full resistance instead of the currently requested resistance. */ bool stopping = false; /** - * @brief brakeLevel Sum of brakes 1 and 2 each normalised to 0..125. + * @brief Sum of brakes 1 and 2 each normalised to 0..125. */ uint8_t brakeLevel = 0; /** - * @brief resistanceTimerId The id for identifying the resistance timer in void timerEvent(QEvent*). + * @brief The id for identifying the resistance timer in void timerEvent(QEvent*). */ int resistanceTimerId = 0; /** - * @brief settingsUpdateTimerId The id for identifying the settings update timer in void timerEvent(QEVent*). + * @brief The id for identifying the settings update timer in void timerEvent(QEVent*). */ int settingsUpdateTimerId = 0; /** - * @brief noHeartService Suppress heart rate readings, QZ level setting. + * @brief The id for identifying the timer that updates the metrics from the stored queue of states read from the client, + * in void timerEvent(QEvent*), + */ + int metricsUpdateTimerId = 0; + + /** + * @brief Suppress heart rate readings, QZ level setting. */ bool noHeartService; /** - * @brief noHeartRate Value from app settings combined with QZ's noHeartService value. + * @brief Value from app settings combined with QZ's noHeartService value. */ bool noHeartRate; /** - * @brief noVirtualDevice Suppress virtual device. + * @brief Suppress virtual device. */ bool noVirtualDevice; /** - * @brief noWriteResistance Suppress sending resistance to device. + * @brief Suppress sending resistance to device. */ bool noWriteResistance; /** - * @brief noSteering Suppress steering readings + * @brief Suppress steering readings */ bool noSteering; /** - * @brief resistanceLevel The last requested resistance level. + * @brief The last requested resistance level, actual value sent to device. */ resistance_t resistanceLevel = 0; /** - * @brief useResistancePercentage Option to use resistance levels 0..100 instead of + * @brief Option to use resistance levels 0..100 instead of * a full range that exceeds an int8_t. */ bool useResistancePercentage = false; /** - * @brief wheelCircumference The simulated circumference of the bike's wheels, for converting + * @brief The simulated circumference of the bike's wheels, for converting * angular velocity to a speed. Units: kilometers. */ double wheelCircumference; @@ -104,72 +121,77 @@ class trixterxdreamv1bike : public bike qint64 t0=0; /** - * @brief packetsProcessed The number of packets processed. + * @brief The number of packets processed. */ uint32_t packetsProcessed=0; /** - * @brief lastPacketProcessedTime The last time (from getTime()) a packet was processed. + * @brief The last time (from getTime()) a packet was processed. */ uint32_t lastPacketProcessedTime=0; /** - * @brief appSettings The application settings. + * @brief The application settings. */ trixterxdreamv1settings * appSettings = nullptr; /** - * @brief lastAppSettingsVersion The last app settings version that was used to configure the object. + * @brief The last app settings version that was used to configure the object. */ uint32_t lastAppSettingsVersion=0; /** - * @brief steeringMap Stores the mapping between incoming steering values and the steering angles expected by the application. + * @brief Stores the mapping between incoming steering values and the steering angles expected by the application. */ std::vector steeringMap; /** - * @brief updateMutex Used to synchronise updates to this object's members. + * @brief Used to synchronise updates to this object's members. */ QRecursiveMutex updateMutex; /** - * @brief getTime Gets the time in miliseconds since this object was created. + * @brief Processes the state queue */ - static uint32_t getTime(); + void update(); /** - * @brief updateClient Passes the array of bytes into the client one by one. - * @param bytes The incoming bytes. - * @param client The client object that interprets the incoming bytes into data packets. - * @return True if the state of the client changed due to the input. + * @brief Processes a single state. + * @param state The state from the client to process. */ - static bool updateClient(const QByteArray &bytes, trixterxdreamv1client * client); + void update(const trixterxdreamv1client::state &state); + + /** + * @brief Gets the time in miliseconds since this object was created. + */ + static uint32_t getTime(); /** * @brief Called by the data source (serial port) when a new block of data arrives. + * Stores the data and triggers an update. + * @param bytes */ - void update(const QByteArray& bytes); + void receiveBytes(const QByteArray &bytes); /** - * @brief updateResistance Called by the resistanceTimer to send the resistance request to the + * @brief Called by the resistanceTimer to send the resistance request to the * device. */ void updateResistance(); /** - * @brief calculateSteering Calculates the mapping between steering values coming from the device, and + * @brief Calculates the mapping between steering values coming from the device, and * the steering angles sent to the application. Uses the values in the appSettings field. */ void calculateSteeringMap(); /** - * @brief configureVirtualBike Set up the bridge to the client application. + * @brief Set up the bridge to the client application. */ void configureVirtualBike(); /** - * @brief calculatePower Calculate power from cadence RPM and resistance. + * @brief Calculate power from cadence RPM and resistance. * @param cadenceRPM * @param resistance Bike resistance on full, not percentage scale. * @return @@ -178,7 +200,7 @@ class trixterxdreamv1bike : public bike /** - * @brief adjustedResistance Adjust the resistance based on whether the + * @brief Adjust the resistance based on whether the * object has been configured to use a resistance percentage or the * raw value. * @param input 0..100 if the object is using a resistance percentage, @@ -189,48 +211,54 @@ class trixterxdreamv1bike : public bike resistance_t adjustedResistance(resistance_t input, bool toDevice); /** - * @brief set_resistance Called to set the resistance level sent to the device. + * @brief Called to set the resistance level sent to the device. * @param resistanceLevel The resistance level to request (0..maximumResistance()) */ void set_resistance(resistance_t resistanceLevel); + protected: /** - * @brief timerEvent Processes timer events, e.g. for resistance. + * @brief Processes timer events, e.g. for resistance. * @param event */ void timerEvent(QTimerEvent *event) override; /** - * @brief disconnectPort Disconnect the serial port and resistance timer. + * @brief Disconnect the serial port and resistance timer. */ void disconnectPort(); public: /** - * @brief MaxWheelDiameter The maximum supported wheel diameter. Unit: meters + * @brief The maximum supported wheel diameter. Unit: meters */ constexpr static double MaxWheelDiameter = 2.0; /** - * @brief MinWheelDiameter The minimum supported wheel diameter. Unit: meters + * @brief The minimum supported wheel diameter. Unit: meters */ constexpr static double MinWheelDiameter = 0.1; /** - * @brief DefaultWheelDiameter The default wheel diameter. Unit: meters + * @brief The default wheel diameter. Unit: meters */ constexpr static double DefaultWheelDiameter = 26*0.0254; /** - * @brief DisconnectionTimeout The number of milliseconds of no packets processed required before + * @brief The number of milliseconds of no packets processed required before * this object will be considered disconnected from the device. */ constexpr static int32_t DisconnectionTimeout = 50; /** - * @brief trixterxdreamv1bike Constructor + * @brief The number of milliseconds to collect packets from the device before updating the metrics. + */ + constexpr static int32_t UpdateMetricsInterval = 100; + + /** + * @brief Constructor * @param noWriteResistance Option to avoid sending resistance to the device. * @param noHeartService Option to avoid using the heart rate reading. * @param noVirtualDevice Option to avoid using a virtual device. @@ -240,62 +268,62 @@ class trixterxdreamv1bike : public bike ~trixterxdreamv1bike(); /** - * @brief powerFromResistanceRequest Calculate the power for the requested resistance at the current cadence. + * @brief Calculate the power for the requested resistance at the current cadence. * @param requestedResistance * @return */ uint16_t powerFromResistanceRequest(resistance_t requestedResistance) override; /** - * @brief resistanceFromPowerRequest Calculate the resistance required to produce the requested power at the current cadence. + * @brief Calculate the resistance required to produce the requested power at the current cadence. * @param power * @return */ resistance_t resistanceFromPowerRequest(uint16_t power) override; /** - * @brief VirtualDevice Virtual device + * @brief Virtual device * @return */ void *VirtualDevice() override; /** - * @brief connect Attempt to connect to the specified port. + * @brief Attempt to connect to the specified port. * @param portName The name of the serial port to connect to. */ bool connect(QString portName); /** - * @brief connected Indicates if a valid packet was received from the device within the DisconnectionTimeout. + * @brief Indicates if a valid packet was received from the device within the DisconnectionTimeout. */ bool connected() override; /** - * @brief set_wheelDiameter Set the simulated wheel diameter to be used for converting angular velocity to speed. Units: meters + * @brief Set the simulated wheel diameter to be used for converting angular velocity to speed. Units: meters * @param value */ void set_wheelDiameter(double value); /** - * @brief get_appSettings Gets the settings object for this device type. + * @brief Gets the settings object for this device type. */ const trixterxdreamv1settings * get_appSettings() { return this->appSettings; } /** - * @brief maxResistance The maximum resistance supported. + * @brief The maximum resistance supported. * @return */ resistance_t maxResistance() override { return this->useResistancePercentage ? 100:trixterxdreamv1client::MaxResistance; } /** - * @brief pelotonToBikeResistance Map Peloton 0 to 100% resistance to the bike's range. + * @brief Map Peloton 0 to 100% resistance to the bike's range. * @param pelotonResistance The Peloton resistance. Range: 0 to 100. * @return The Trixter X-Dream V1 bike resistance. Range 0..250 if !this->useResistancePercentage. */ resistance_t pelotonToBikeResistance(int pelotonResistance) override; /** - * @brief tryCreate Attempt to create an object to interact with an existing Trixter X-Dream V1 bike on a specific serial port, + * @brief Attempt to create an object to interact with an existing Trixter X-Dream V1 bike on a specific serial port, * or if the port is unspecified, any serial port. * @param noWriteResistance Option to avoid sending resistance to the device. * @param noHeartService Option to avoid using the heart rate reading. @@ -306,7 +334,7 @@ class trixterxdreamv1bike : public bike static trixterxdreamv1bike * tryCreate(bool noWriteResistance, bool noHeartService, bool noVirtualDevice, const QString& portName = nullptr); /** - * @brief tryCreate Attempt to create an object to interact with an existing Trixter X-Dream V1 bike on a specific serial port, + * @brief Attempt to create an object to interact with an existing Trixter X-Dream V1 bike on a specific serial port, * or if the port is unspecified, any serial port. * @param port (Optional) The specific port to search. * @return From 12e7ec3293d17150eb8f88d56d6176650544a336 Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 14 Sep 2022 00:32:37 +0100 Subject: [PATCH 077/255] #855 send resistance gain to virtual device constructor. Hook and process inclination. More logging. --- src/bike.cpp | 1 + src/trixterxdreamv1bike.cpp | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/bike.cpp b/src/bike.cpp index 314a42cdc..fda4f7e96 100644 --- a/src/bike.cpp +++ b/src/bike.cpp @@ -18,6 +18,7 @@ void bike::changeResistance(resistance_t resistance) { void bike::changeInclination(double grade, double percentage) { qDebug() << QStringLiteral("bike::changeInclination") << autoResistanceEnable << grade << percentage; if (autoResistanceEnable) { + qDebug() << QStringLiteral("setting bike::requestInclination") << grade; requestInclination = grade; } emit inclinationChanged(grade, percentage); diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 1f1c85717..a3ede544b 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -430,7 +430,11 @@ void trixterxdreamv1bike::configureVirtualBike(){ #endif if (virtual_device_enabled) { qDebug() << QStringLiteral("creating virtual bike interface..."); - this->virtualBike = new virtualbike(this, noWriteResistance, noHeartService); + + double bikeResistanceOffset = settings.value(QStringLiteral("bike_resistance_offset"), 0).toInt(); + double bikeResistanceGain = settings.value(QStringLiteral("bike_resistance_gain_f"), 1).toDouble(); + this->virtualBike = new virtualbike(this, noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); + bike::connect(this->virtualBike, &virtualbike::changeInclination, this, &trixterxdreamv1bike::changeInclination); } } @@ -585,6 +589,15 @@ void trixterxdreamv1bike::update(const trixterxdreamv1client::state &state) { this->requestResistance = -1; } + // check if there's a request for an inclination grade + if(this->requestInclination>=0) { + qDebug() << "requestInclination="<requestInclination; + // apply a log curve that's pure guesswork + resistance_t inc = (resistance_t)(45.0*log(std::max(1.0, 5.0*this->requestInclination))+2); + this->set_resistance(this->adjustedResistance(inc, false)); + this->requestInclination = -100; + } + // update the power output double powerBoost = 4.0 * this->brakeLevel; this->update_metrics(true, powerBoost + this->calculatePower(state.CrankRPM, this->resistanceLevel)); @@ -670,6 +683,8 @@ void trixterxdreamv1bike::calculateSteeringMap() { } void trixterxdreamv1bike::set_resistance(resistance_t resistanceLevel) { + qDebug() << "setting resistance: " << resistanceLevel << (this->useResistancePercentage ? "%":"") << this->noWriteResistance; + // ignore the resistance if this option was selected if(this->noWriteResistance) return; From 6ec98cdc0e5d5d5e9ebb8eccf99f564f1f974529 Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 14 Sep 2022 00:51:01 +0100 Subject: [PATCH 078/255] #855 adjust "is connected" logic --- src/trixterxdreamv1bike.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index a3ede544b..df83c1548 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -494,8 +494,16 @@ resistance_t trixterxdreamv1bike::adjustedResistance(resistance_t input, bool to bool trixterxdreamv1bike::connected() { - QMutexLocker locker(&this->unprocessedStatesMutex); - return !this->unprocessedStates.empty(); + // If this is called from the connect() method, the timer won't have called the update() method + // so go directly to the queue of states. + QMutexLocker lockerA(&this->unprocessedStatesMutex); + if(!this->unprocessedStates.empty()) + return true; + lockerA.unlock(); + + // Queue of states is empty... + QMutexLocker lockerB(&this->updateMutex); + return (this->getTime()-this->lastPacketProcessedTime) < DisconnectionTimeout; } From 20ea60d7b4888b224503d816ca44d8f9a59a0a77 Mon Sep 17 00:00:00 2001 From: David Mason Date: Wed, 14 Sep 2022 01:24:41 +0100 Subject: [PATCH 079/255] #855 put client on actual time so that the state timestamps mean something outside of it --- src/trixterxdreamv1client.cpp | 3 +-- src/trixterxdreamv1client.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp index fee118336..3cbc95c2a 100644 --- a/src/trixterxdreamv1client.cpp +++ b/src/trixterxdreamv1client.cpp @@ -20,7 +20,6 @@ void trixterxdreamv1client::ResetBuffer() { void trixterxdreamv1client::set_GetTime(std::function get_time_ms) { this->get_time_ms = get_time_ms; - this->t0 = this->get_time_ms ? this->get_time_ms():0; } trixterxdreamv1client::PacketState trixterxdreamv1client::ProcessChar(char c) { @@ -138,7 +137,7 @@ bool trixterxdreamv1client::ReceiveChar(char c) { crankRevsPerMinute = crankToRevolutionsPerMinute / max(static_cast(1), lastPacket.Crank); } - const uint32_t t = this->get_time_ms() - this->t0; + const uint32_t t = this->get_time_ms(); const uint32_t lt = this->lastT ? this->lastT : t; this->lastT = t; diff --git a/src/trixterxdreamv1client.h b/src/trixterxdreamv1client.h index d0b406a19..85b0b8bbc 100644 --- a/src/trixterxdreamv1client.h +++ b/src/trixterxdreamv1client.h @@ -114,7 +114,6 @@ class trixterxdreamv1client { std::function write_bytes=nullptr; std::mutex stateMutex, writeMutex; uint32_t lastT = 0; - uint32_t t0 = 0; double flywheelRevolutions{}, crankRevolutions{}; Packet lastPacket{}; std::vector inputBuffer; From d435faf6a84534d51b4243223814ce4f19f8ef6b Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 17 Sep 2022 20:34:36 +0100 Subject: [PATCH 080/255] #855 working much better now, but only using resistance calculated from inclination from zwift, not the resistance tile. --- src/trixterxdreamv1bike.cpp | 210 +++++++++++++++++++++++----------- src/trixterxdreamv1bike.h | 26 +++-- src/trixterxdreamv1client.cpp | 5 +- src/trixterxdreamv1client.h | 15 ++- 4 files changed, 172 insertions(+), 84 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index df83c1548..338da3789 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -453,15 +453,13 @@ resistance_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) int16_t result = -1; - double * ps = powerSurface[c*26]; - for(int i=0; result<0 && i<26; i++, ps++) - if(ps[2]>=power) - result = ps[1]; - if(result<0) - result = (ps-1)[1]; + for(int i=c*26, L=i+26; i=power) break; + } result = this->adjustedResistance(result, false); - result = std::min((resistance_t)trixterxdreamv1client::MaxResistance, std::max((resistance_t)0, result)); + result = std::min(this->maxResistance(), std::max((resistance_t)0, result)); return result; } @@ -497,7 +495,7 @@ bool trixterxdreamv1bike::connected() { // If this is called from the connect() method, the timer won't have called the update() method // so go directly to the queue of states. QMutexLocker lockerA(&this->unprocessedStatesMutex); - if(!this->unprocessedStates.empty()) + if(!this->unprocessedStates[this->unprocessedStateIndex].empty()) return true; lockerA.unlock(); @@ -531,87 +529,167 @@ void trixterxdreamv1bike::receiveBytes(const QByteArray &bytes) { // send the bytes to the client and return if there's no change of state bool stateChanged = false; + queue * ups = &this->unprocessedStates[this->unprocessedStateIndex]; - for(int i=0; iclient.ReceiveChar(bytes[i]); + for(int i=0; iclient.ReceiveChar(bytes[i])) { + QMutexLocker locker(&this->unprocessedStatesMutex); + ups->push(this->client.getLastState()); + stateChanged = true; + } + } if(!stateChanged) return; QMutexLocker locker(&this->unprocessedStatesMutex); - auto timeLimit = getTime() - UpdateMetricsInterval; - queue * ups = &this->unprocessedStates; - while(!ups->empty() && ups->front().LastEventTimeempty() && ups->front().LastEventTime < timeLimit) ups->pop(); - ups->push(this->client.getLastState()); + } +resistance_t trixterxdreamv1bike::calculateResistanceFromInclination() { + QSettings settings; + + double inclination = this->Inclination.value(); + double cadence = this->Cadence.value(); + double riderMass = settings.value(QStringLiteral("weight"), 75.0).toFloat(); + double bikeMass = settings.value(QStringLiteral("bike_weight"), 0.0).toFloat(); + double totalMass = riderMass+bikeMass; + + double flywheelRPM = cadence * trixterxdreamv1client::GearRatio; // not using the value from device here to avoid freewheeling + double speedMetresPerSecond = flywheelRPM / 60.0 * 1000 * this->wheelCircumference; + double fg = 9.8067*sin(atan(0.01*inclination))*totalMass; + + uint16_t power = (uint16_t)(fg * speedMetresPerSecond); + + resistance_t r = resistanceFromPowerRequest(power); + + qDebug() << "Inclination:" << inclination + << " Cadence:" << cadence << "RPM " + << " Total Mass:"<< totalMass << "kg " + << "= Power:" << power << "W " + << "Resistance:" << r; + + return r; +} + + void trixterxdreamv1bike::update() { QMutexLocker locker(&this->updateMutex); + // get the current time + auto currentTime = getTime(); + + // Switch to the the other queue for continued input on another thread QMutexLocker statesLocker(&this->unprocessedStatesMutex); - queue * ups = &this->unprocessedStates; - std::vector pendingStates{ups->size()}; + queue * ups = &this->unprocessedStates[this->unprocessedStateIndex]; + this->unprocessedStateIndex ^= 1; + statesLocker.unlock(); + + // If there are no states waiting to be processed, clear the metrics and return. + if(ups->empty()) { + qDebug() << "no states in queue"; + this->stopping = false; + this->powerBoost = false; + this->Speed.setValue(0); + this->brakeLevel = 0; + this->m_steeringAngle.setValue(0); + this->Cadence.setValue(0); + this->Heart.setValue(0); + return; + } + + // sweep the unprocessed states calculating some averages over the last update interval + // steering can ba a particularly wobbly signal so smoothing is important + double steering=0, cadence=0, flywheel=0, brakeLevel=0; + int count = ups->size(); + + trixterxdreamv1client::state state{}; + while(!ups->empty()) { - pendingStates.push_back(ups->front()); + // update the packet count + this->packetsProcessed++; + this->lastPacketProcessedTime = currentTime; + + state = ups->front(); ups->pop(); - } - statesLocker.unlock(); - for(auto state : pendingStates) - this->update(state); -} + constexpr double brakeScale = 125.0/(trixterxdreamv1client::MaxBrake-trixterxdreamv1client::MinBrake); + uint8_t b1 = 125 - (state.Brake1 - trixterxdreamv1client::MinBrake) * brakeScale; + uint8_t b2 = 125 - (state.Brake2 - trixterxdreamv1client::MinBrake) * brakeScale; + brakeLevel+= b1+b2; -void trixterxdreamv1bike::update(const trixterxdreamv1client::state &state) { - auto currentTime = getTime(); + flywheel += state.FlywheelRPM; + cadence += state.CrankRPM; + + // Set the steering + if(!this->noSteering) { + steering += this->steeringMap[state.Steering]; + } + } - // update the packet count - this->packetsProcessed++; - this->lastPacketProcessedTime = currentTime; + if(count>1) { + double scale = 1.0/count; + steering *= scale; + cadence *= scale; + flywheel *= scale; + brakeLevel *= scale; + } // Determine if the user is pressing the button to stop. this->stopping = (state.Buttons & trixterxdreamv1client::buttons::Red) != 0; - constexpr double brakeScale = 125.0/(trixterxdreamv1client::MaxBrake-trixterxdreamv1client::MinBrake); - uint8_t b1 = 125 - (state.Brake1 - trixterxdreamv1client::MinBrake) * brakeScale; - uint8_t b2 = 125 - (state.Brake2 - trixterxdreamv1client::MinBrake) * brakeScale; - this->brakeLevel = b1 + b2; + // Determine if the user is pressing the left (front) gear up button, for a power boost. + this->powerBoost = (state.Buttons & trixterxdreamv1client::buttons::FrontGearUp) != 0; // update the metrics + if(!this->noHeartRate) + this->Heart.setValue(state.HeartRate); + this->Distance.setValue(state.CumulativeWheelRevolutions * this->wheelCircumference); + this->Cadence.setValue(cadence); this->LastCrankEventTime = state.LastEventTime; - - // set the speed in km/h + this->CrankRevs = state.CumulativeCrankRevolutions; + this->brakeLevel = brakeLevel; constexpr double minutesPerHour = 60.0; - this->Speed.setValue(state.FlywheelRPM * minutesPerHour * this->wheelCircumference); + this->Speed.setValue(flywheel * minutesPerHour * this->wheelCircumference); - // set the distance in km - this->Distance.setValue(state.CumulativeWheelRevolutions * this->wheelCircumference); + bool steeringAngleChanged = false; + if(!this->noSteering) { + double newValue = steering; + steeringAngleChanged = this->m_steeringAngle.value()!=newValue; + if(steeringAngleChanged) + this->m_steeringAngle.setValue(newValue); + } + + resistance_t newRequestedResistanceLevel = -1; + resistance_t newInclinationResistanceLevel = -1; - // set the cadence in revolutions per minute - this->Cadence.setValue(state.CrankRPM); + qDebug() << "bike::requestResistance=" << this->requestResistance + << "bike::requestInclination="<requestInclination + << "bike::Inclination=" << this->Inclination.value(); - // check if there's a request for a resistance level + // check if there's a request for resistance if(this->requestResistance!=-1) { - this->set_resistance(this->requestResistance); + // ignoring forced resistance requests for now + //newRequestedResistanceLevel = this->requestResistance; this->requestResistance = -1; } - // check if there's a request for an inclination grade - if(this->requestInclination>=0) { - qDebug() << "requestInclination="<requestInclination; - // apply a log curve that's pure guesswork - resistance_t inc = (resistance_t)(45.0*log(std::max(1.0, 5.0*this->requestInclination))+2); - this->set_resistance(this->adjustedResistance(inc, false)); + // Cancel any request for inclination (grade) + if(this->requestInclination!=-100) { this->requestInclination = -100; } - // update the power output - double powerBoost = 4.0 * this->brakeLevel; - this->update_metrics(true, powerBoost + this->calculatePower(state.CrankRPM, this->resistanceLevel)); + // update the inclination and cadence based resistance because either could have changed. + newInclinationResistanceLevel = this->calculateResistanceFromInclination(); - // set the crank revolutions - this->CrankRevs = state.CumulativeCrankRevolutions; + this->set_resistance(std::max(newInclinationResistanceLevel, newRequestedResistanceLevel)); + + // update the power output + double powerBoost = this->powerBoost ? 1000:0; + this->update_metrics(true, powerBoost + this->calculatePower(cadence, this->resistanceLevel)); // check if the settings have been updated and adjust accordingly if(this->appSettings->get_version()!=this->lastAppSettingsVersion) { @@ -621,32 +699,29 @@ void trixterxdreamv1bike::update(const trixterxdreamv1client::state &state) { this->Heart.setValue(0.0); this->noSteering = !this->appSettings->get_steeringEnabled(); - if(this->noSteering) - this->m_steeringAngle.setValue(0.0); - else + if(this->noSteering) { + if(this->m_steeringAngle.value()!=0) { + this->m_steeringAngle.setValue(0.0); + steeringAngleChanged = true; + } + } else QTimer::singleShot(10ms, this, &trixterxdreamv1bike::calculateSteeringMap); this->lastAppSettingsVersion = this->appSettings->get_version(); } - // update the heart rate - if(!this->noHeartRate) - this->Heart.setValue(state.HeartRate); - - // Set the steering - bool steeringAngleChanged = false; - if(!this->noSteering) { - double newValue = this->steeringMap[state.Steering]; - steeringAngleChanged = this->m_steeringAngle.value()!=newValue; - if(steeringAngleChanged) - this->m_steeringAngle.setValue(newValue); - } - // set the elapsed time this->elapsed = (currentTime - this->t0) * 0.001; if(steeringAngleChanged) emit this->steeringAngleChanged(this->m_steeringAngle.value()); + + // get the current time + auto updateTime = getTime()-currentTime; + + // Check the update was quick enough. + if(updateTime>UpdateMetricsInterval/4) + qDebug() << "WARNING: Update took too long: " << updateTime << "ms"; } void trixterxdreamv1bike::calculateSteeringMap() { @@ -687,7 +762,6 @@ void trixterxdreamv1bike::calculateSteeringMap() { QMutexLocker locker(&this->updateMutex); this->steeringMap=newMap; - } void trixterxdreamv1bike::set_resistance(resistance_t resistanceLevel) { diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 1b5ca3cc8..8a56164ad 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -22,9 +22,14 @@ class trixterxdreamv1bike : public bike static double powerSurface[260][3]; /** - * @brief A queue of states read from the client. + * @brief A queue of states read from the client. Syncronized but unprocessedStatesMutex. */ - std::queue unprocessedStates; + std::queue unprocessedStates[2]; + + /** + * @brief The current unprocessed state queue. Syncronized but unprocessedStatesMutex. + */ + uint32_t unprocessedStateIndex = 0; /** * @brief Mutex for accessing the unprocessedStates queue. @@ -52,6 +57,11 @@ class trixterxdreamv1bike : public bike */ bool stopping = false; + /** + * @brief Indicates if a power boost is being applied. + */ + bool powerBoost = false; + /** * @brief Sum of brakes 1 and 2 each normalised to 0..125. */ @@ -155,12 +165,6 @@ class trixterxdreamv1bike : public bike */ void update(); - /** - * @brief Processes a single state. - * @param state The state from the client to process. - */ - void update(const trixterxdreamv1client::state &state); - /** * @brief Gets the time in miliseconds since this object was created. */ @@ -198,6 +202,11 @@ class trixterxdreamv1bike : public bike */ double calculatePower(int cadenceRPM, int resistance); + /** + * @brief Calculate resistance from current inclination and cadence. + * @return + */ + resistance_t calculateResistanceFromInclination(); /** * @brief Adjust the resistance based on whether the @@ -216,6 +225,7 @@ class trixterxdreamv1bike : public bike */ void set_resistance(resistance_t resistanceLevel); + protected: /** diff --git a/src/trixterxdreamv1client.cpp b/src/trixterxdreamv1client.cpp index 3cbc95c2a..664b11796 100644 --- a/src/trixterxdreamv1client.cpp +++ b/src/trixterxdreamv1client.cpp @@ -122,7 +122,6 @@ bool trixterxdreamv1client::ReceiveChar(char c) { // got the data, now clear the buffer this->ResetBuffer(); - constexpr double millisecondsToBaseUnit = 1024.0 / 1000.0; constexpr double flywheelToRevolutionsPerMinute = 576000.0; constexpr double crankToRevolutionsPerMinute = 1.0 / 6e-6; constexpr double minutesToMilliseconds = 60.0 * 1000.0; @@ -163,7 +162,7 @@ bool trixterxdreamv1client::ReceiveChar(char c) { } state newState{}; - newState.LastEventTime = static_cast(millisecondsToBaseUnit * t); + newState.LastEventTime = t; newState.Steering = lastPacket.Steering; newState.HeartRate = lastPacket.HeartRate; newState.CumulativeCrankRevolutions = static_cast(round(crankRevolutions)); @@ -190,7 +189,7 @@ trixterxdreamv1client::state trixterxdreamv1client::getLastState() { void trixterxdreamv1client::SendResistance(uint8_t level) { - // to maintain the resistance, this needs to be resent about every 10ms + // to maintain the resistance, this needs to be resent about every 10ms if (level != 0 && this->write_bytes) { this->writeMutex.lock(); diff --git a/src/trixterxdreamv1client.h b/src/trixterxdreamv1client.h index 85b0b8bbc..d8f470f01 100644 --- a/src/trixterxdreamv1client.h +++ b/src/trixterxdreamv1client.h @@ -66,9 +66,9 @@ class trixterxdreamv1client { uint16_t CumulativeCrankRevolutions; /** - * @brief LastEventTime The time of the last event. Unit: 1/1024 s + * @brief LastEventTime The time of the last event. Unit: milliseconds */ - uint16_t LastEventTime; + uint32_t LastEventTime; /** * @brief FlywheelRPM Flywheel speed. Units: revolutions per minute @@ -134,6 +134,11 @@ class trixterxdreamv1client { void ConfigureResistanceMessages(); public: + /** + * @brief GearRatio The physical gear ratio between the flywheel:crank. + */ + constexpr static uint8_t GearRatio = 5; + /** * @brief MaxResistance The maximum resistance value supported by the device. */ @@ -146,7 +151,7 @@ class trixterxdreamv1client { /** - * @brief MaxBrake The maximum brake value, which indicates fully off. + * @brief MaxBrake The maximum brake value, which indicates fully off. */ constexpr static uint8_t MaxBrake = 250; @@ -161,8 +166,8 @@ class trixterxdreamv1client { constexpr static uint8_t MinCrankPosition = 1; /** - * @brief MinCrankPosition The maximum CrankPosition value. - */ + * @brief MinCrankPosition The maximum CrankPosition value. + */ constexpr static uint8_t MaxCrankPosition = 60; /** From e275ba719263f2a5acc9ce40c625a068e0e04a19 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 17 Sep 2022 20:56:52 +0100 Subject: [PATCH 081/255] Disabled power boost feature --- src/trixterxdreamv1bike.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 338da3789..2206d897f 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -642,7 +642,8 @@ void trixterxdreamv1bike::update() { this->stopping = (state.Buttons & trixterxdreamv1client::buttons::Red) != 0; // Determine if the user is pressing the left (front) gear up button, for a power boost. - this->powerBoost = (state.Buttons & trixterxdreamv1client::buttons::FrontGearUp) != 0; + //this->powerBoost = (state.Buttons & trixterxdreamv1client::buttons::FrontGearUp) != 0; + this->powerBoost = false; // update the metrics if(!this->noHeartRate) From bd1eb2e1f31a3c88593f63d12167071ac2e3e9d8 Mon Sep 17 00:00:00 2001 From: David Mason Date: Sat, 24 Sep 2022 22:19:41 +0100 Subject: [PATCH 082/255] #855 removed 0.100 resistance option. Use inclination for power/resistance while connected to client app, values from resistance tiles directly when not. --- src/trixterxdreamv1bike.cpp | 79 ++++++++++++++----------------------- src/trixterxdreamv1bike.h | 32 ++++----------- 2 files changed, 37 insertions(+), 74 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 2206d897f..6cf5b2e35 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -279,8 +279,6 @@ trixterxdreamv1bike::trixterxdreamv1bike(bool noWriteResistance, bool noHeartSer m_watt.setType(metric::METRIC_WATT); Speed.setType(metric::METRIC_SPEED); - this->useResistancePercentage = false; - // Set the fake bluetooth device info this->bluetoothDevice = QBluetoothDeviceInfo(QBluetoothUuid {QStringLiteral("774f25bd-6636-4cdc-9398-839de026be1d")}, "Trixter X-Dream V1 Bike", 0); @@ -314,16 +312,14 @@ bool trixterxdreamv1bike::connect(QString portName) { this->port = new trixterxdreamv1serial(this); this->port->set_receiveBytes([thisObject](const QByteArray& bytes)->void{thisObject->receiveBytes(bytes);}); - // References to objects for callbacks - auto device=this->port; - // tell the client where to get the time this->client.set_GetTime(getTime); // tell the client how to send data to the device - if(!noWriteResistance) + if(!noWriteResistance) { + auto device=this->port; this->client.set_WriteBytes([device](uint8_t * bytes, int length)->void{ device->write(QByteArray((const char *)bytes, length));}); - + } // Set up a stopwatch to time the connection operations QElapsedTimer stopWatch; stopWatch.start(); @@ -441,14 +437,11 @@ void trixterxdreamv1bike::configureVirtualBike(){ // ******************************************************************************************************** } -uint16_t trixterxdreamv1bike::powerFromResistanceRequest(resistance_t requestedResistance) -{ - requestedResistance = this->adjustedResistance(requestedResistance, true); +uint16_t trixterxdreamv1bike::powerFromResistanceRequest(resistance_t requestedResistance) { return this->calculatePower((int)this->Cadence.value(), requestedResistance); } -resistance_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) -{ +resistance_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) { int c = std::max(0, std::min(9, (int)(0.1*(this->Cadence.value()-30) +0.5))); int16_t result = -1; @@ -458,7 +451,6 @@ resistance_t trixterxdreamv1bike::resistanceFromPowerRequest(uint16_t power) if(powerSurface[i][2]>=power) break; } - result = this->adjustedResistance(result, false); result = std::min(this->maxResistance(), std::max((resistance_t)0, result)); return result; } @@ -480,17 +472,6 @@ double trixterxdreamv1bike::calculatePower(int cadenceRPM, int resistance) { return ps[2]; } -resistance_t trixterxdreamv1bike::adjustedResistance(resistance_t input, bool toDevice) { - if(this->useResistancePercentage){ - if(toDevice) - return trixterxdreamv1client::MaxResistance * input / 100; - else - return 100 * input / trixterxdreamv1client::MaxResistance ; - } - return input; -} - - bool trixterxdreamv1bike::connected() { // If this is called from the connect() method, the timer won't have called the update() method // so go directly to the queue of states. @@ -513,6 +494,7 @@ uint32_t trixterxdreamv1bike::getTime() { void trixterxdreamv1bike::timerEvent(QTimerEvent *event) { int timerId = event->timerId(); + // check the options, most frequent to least frequent if(timerId==this->resistanceTimerId){ event->accept(); this->updateResistance(); @@ -550,10 +532,12 @@ void trixterxdreamv1bike::receiveBytes(const QByteArray &bytes) { } resistance_t trixterxdreamv1bike::calculateResistanceFromInclination() { + return this->calculateResistanceFromInclination(this->Inclination.value(), this->Cadence.value()); +} + +resistance_t trixterxdreamv1bike::calculateResistanceFromInclination(double inclination, double cadence) { QSettings settings; - double inclination = this->Inclination.value(); - double cadence = this->Cadence.value(); double riderMass = settings.value(QStringLiteral("weight"), 75.0).toFloat(); double bikeMass = settings.value(QStringLiteral("bike_weight"), 0.0).toFloat(); double totalMass = riderMass+bikeMass; @@ -664,29 +648,31 @@ void trixterxdreamv1bike::update() { this->m_steeringAngle.setValue(newValue); } - resistance_t newRequestedResistanceLevel = -1; - resistance_t newInclinationResistanceLevel = -1; + resistance_t newResistanceLevel = this->resistanceLevel; qDebug() << "bike::requestResistance=" << this->requestResistance << "bike::requestInclination="<requestInclination << "bike::Inclination=" << this->Inclination.value(); - // check if there's a request for resistance - if(this->requestResistance!=-1) { - // ignoring forced resistance requests for now - //newRequestedResistanceLevel = this->requestResistance; - this->requestResistance = -1; - } + if(this->virtualBike && this->virtualBike->connected()) { + // the virtual bike is connected to the client app, so use inclination to get the power and resistance + + // Update resistance because the requested resistance or cadence could have changed. + newResistanceLevel = this->calculateResistanceFromInclination(); + } else { + // not connected to the client app, so just respond to the resistance tiles - // Cancel any request for inclination (grade) - if(this->requestInclination!=-100) { - this->requestInclination = -100; + // check if there's a request for resistance + if(this->requestResistance!=-1) + newResistanceLevel = this->requestResistance; } - // update the inclination and cadence based resistance because either could have changed. - newInclinationResistanceLevel = this->calculateResistanceFromInclination(); + // Cancel any request for inclination (grade) or resistance + this->requestInclination = -100; + this->requestResistance = -1; - this->set_resistance(std::max(newInclinationResistanceLevel, newRequestedResistanceLevel)); + // apply the nw resistance value. + this->set_resistance(newResistanceLevel); // update the power output double powerBoost = this->powerBoost ? 1000:0; @@ -766,7 +752,7 @@ void trixterxdreamv1bike::calculateSteeringMap() { } void trixterxdreamv1bike::set_resistance(resistance_t resistanceLevel) { - qDebug() << "setting resistance: " << resistanceLevel << (this->useResistancePercentage ? "%":"") << this->noWriteResistance; + qDebug() << "setting resistance: " << resistanceLevel << this->noWriteResistance; // ignore the resistance if this option was selected if(this->noWriteResistance) @@ -786,14 +772,11 @@ void trixterxdreamv1bike::set_resistance(resistance_t resistanceLevel) { this->Resistance.setValue(resistanceLevel); resistanceChanged = true; } - if(this->useResistancePercentage) - this->m_pelotonResistance.setValue(resistanceLevel); - else - this->m_pelotonResistance.setValue(round(pelotonScaleFactor * resistanceLevel)); + this->m_pelotonResistance.setValue(round(pelotonScaleFactor * resistanceLevel)); // store the new resistance level. This might be the same as lastRequestedResistance(),Value // but it doesn't involve a function call and a cast to get the value. - this->resistanceLevel = this->adjustedResistance(resistanceLevel, true); + this->resistanceLevel = resistanceLevel; // if there's been a change of resistance, signal it. if(resistanceChanged) @@ -832,10 +815,6 @@ void trixterxdreamv1bike::set_wheelDiameter(double value) { resistance_t trixterxdreamv1bike::pelotonToBikeResistance(int pelotonResistance) { pelotonResistance = std::max(0, std::min(100, pelotonResistance)); - - if(this->useResistancePercentage) - return pelotonResistance; - return round(0.01*pelotonResistance*trixterxdreamv1client::MaxResistance); } diff --git a/src/trixterxdreamv1bike.h b/src/trixterxdreamv1bike.h index 8a56164ad..dfd436d1b 100644 --- a/src/trixterxdreamv1bike.h +++ b/src/trixterxdreamv1bike.h @@ -113,12 +113,6 @@ class trixterxdreamv1bike : public bike */ resistance_t resistanceLevel = 0; - /** - * @brief Option to use resistance levels 0..100 instead of - * a full range that exceeds an int8_t. - */ - bool useResistancePercentage = false; - /** * @brief The simulated circumference of the bike's wheels, for converting * angular velocity to a speed. Units: kilometers. @@ -126,7 +120,7 @@ class trixterxdreamv1bike : public bike double wheelCircumference; /** - * @brief t0 The start time in milliseconds. Used to reduce te size of time values processed. + * @brief t0 The start time in milliseconds. Used to determine elapsed time. */ qint64 t0=0; @@ -198,26 +192,20 @@ class trixterxdreamv1bike : public bike * @brief Calculate power from cadence RPM and resistance. * @param cadenceRPM * @param resistance Bike resistance on full, not percentage scale. - * @return */ double calculatePower(int cadenceRPM, int resistance); /** * @brief Calculate resistance from current inclination and cadence. - * @return */ resistance_t calculateResistanceFromInclination(); /** - * @brief Adjust the resistance based on whether the - * object has been configured to use a resistance percentage or the - * raw value. - * @param input 0..100 if the object is using a resistance percentage, - * 0..trixterxdreamclient::MaxResistance otherwise. - * @param toDevice The direction of the conversion. - * @return + * @brief Calculate resistance from the specified inclination and cadence. Uses rider and bike weight from settings. + * @param inclination Percentage inclination. + * @param cadence Cadence in RPM. */ - resistance_t adjustedResistance(resistance_t input, bool toDevice); + resistance_t calculateResistanceFromInclination(double inclination, double cadence); /** * @brief Called to set the resistance level sent to the device. @@ -225,7 +213,6 @@ class trixterxdreamv1bike : public bike */ void set_resistance(resistance_t resistanceLevel); - protected: /** @@ -279,15 +266,13 @@ class trixterxdreamv1bike : public bike /** * @brief Calculate the power for the requested resistance at the current cadence. - * @param requestedResistance - * @return + * @param requestedResistance The resistance from 0 to maximumResistance(). */ uint16_t powerFromResistanceRequest(resistance_t requestedResistance) override; /** * @brief Calculate the resistance required to produce the requested power at the current cadence. - * @param power - * @return + * @param power The power in watts. */ resistance_t resistanceFromPowerRequest(uint16_t power) override; @@ -321,9 +306,8 @@ class trixterxdreamv1bike : public bike /** * @brief The maximum resistance supported. - * @return */ - resistance_t maxResistance() override { return this->useResistancePercentage ? 100:trixterxdreamv1client::MaxResistance; } + resistance_t maxResistance() override { return trixterxdreamv1client::MaxResistance; } /** * @brief Map Peloton 0 to 100% resistance to the bike's range. From 150a61c020fb801a55e23e921860e13870e5d33d Mon Sep 17 00:00:00 2001 From: David Mason Date: Sun, 25 Sep 2022 00:23:37 +0100 Subject: [PATCH 083/255] #855 tweaked power calculation --- src/trixterxdreamv1bike.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/trixterxdreamv1bike.cpp b/src/trixterxdreamv1bike.cpp index 6cf5b2e35..f3fa3d676 100644 --- a/src/trixterxdreamv1bike.cpp +++ b/src/trixterxdreamv1bike.cpp @@ -542,8 +542,11 @@ resistance_t trixterxdreamv1bike::calculateResistanceFromInclination(double incl double bikeMass = settings.value(QStringLiteral("bike_weight"), 0.0).toFloat(); double totalMass = riderMass+bikeMass; - double flywheelRPM = cadence * trixterxdreamv1client::GearRatio; // not using the value from device here to avoid freewheeling - double speedMetresPerSecond = flywheelRPM / 60.0 * 1000 * this->wheelCircumference; + // Since we need speed to calculate power, and QZ isn't getting it from Zwift, + // this number is invented to produce a somewhat believable user experience. + constexpr double magicNumber = 0.75; + double cadenceSensorSpeedRatio = settings.value(QStringLiteral("cadence_sensor_speed_ratio"), 0.33).toDouble(); + double speedMetresPerSecond = magicNumber * cadenceSensorSpeedRatio * cadence; double fg = 9.8067*sin(atan(0.01*inclination))*totalMass; uint16_t power = (uint16_t)(fg * speedMetresPerSecond); From bfd677feb7f84aff4bf0977f0d429c192889e658 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sat, 24 Sep 2022 22:36:48 +0200 Subject: [PATCH 084/255] adding acceleration in the calculation of the speed based on wattage --- src/bhfitnesselliptical.cpp | 2 +- src/chronobike.cpp | 2 +- src/cscbike.cpp | 2 +- src/domyosbike.cpp | 2 +- src/echelonconnectsport.cpp | 2 +- src/fitplusbike.cpp | 4 ++-- src/flywheelbike.cpp | 2 +- src/ftmsbike.cpp | 2 +- src/horizongr7bike.cpp | 4 ++-- src/inspirebike.cpp | 2 +- src/keepbike.cpp | 2 +- src/m3ibike.cpp | 2 +- src/mcfbike.cpp | 2 +- src/metric.cpp | 37 ++++++++++++++++++++++++++++++++++--- src/metric.h | 5 ++++- src/npecablebike.cpp | 4 ++-- src/pafersbike.cpp | 2 +- src/proformbike.cpp | 4 ++-- src/renphobike.cpp | 2 +- src/schwinnic4bike.cpp | 2 +- src/skandikawiribike.cpp | 2 +- src/snodebike.cpp | 2 +- src/solebike.cpp | 2 +- src/sportsplusbike.cpp | 4 ++-- src/sportstechbike.cpp | 2 +- src/stagesbike.cpp | 2 +- src/trxappgateusbbike.cpp | 22 ++++++++++------------ src/ultrasportbike.cpp | 2 +- src/wahookickrsnapbike.cpp | 2 +- src/yesoulbike.cpp | 2 +- 30 files changed, 80 insertions(+), 48 deletions(-) diff --git a/src/bhfitnesselliptical.cpp b/src/bhfitnesselliptical.cpp index da04d6b0e..578b9f32c 100644 --- a/src/bhfitnesselliptical.cpp +++ b/src/bhfitnesselliptical.cpp @@ -182,7 +182,7 @@ void bhfitnesselliptical::characteristicChanged(const QLowEnergyCharacteristic & (uint16_t)((uint8_t)newValue.at(index)))) / 100.0;*/ } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/chronobike.cpp b/src/chronobike.cpp index 05ec74a9c..dfbfbe5c9 100644 --- a/src/chronobike.cpp +++ b/src/chronobike.cpp @@ -150,7 +150,7 @@ void chronobike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = ((double)((uint16_t)((uint8_t)newValue.at(6)) + ((uint16_t)((uint8_t)newValue.at(7)) << 8))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } if (watts()) KCal += diff --git a/src/cscbike.cpp b/src/cscbike.cpp index d76985b10..7a0b03ac5 100644 --- a/src/cscbike.cpp +++ b/src/cscbike.cpp @@ -238,7 +238,7 @@ void cscbike::characteristicChanged(const QLowEnergyCharacteristic &characterist if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/domyosbike.cpp b/src/domyosbike.cpp index e96841525..d5ddb47ca 100644 --- a/src/domyosbike.cpp +++ b/src/domyosbike.cpp @@ -427,7 +427,7 @@ void domyosbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } KCal = kcal; Distance = distance; diff --git a/src/echelonconnectsport.cpp b/src/echelonconnectsport.cpp index 1b1441607..870b40c33 100644 --- a/src/echelonconnectsport.cpp +++ b/src/echelonconnectsport.cpp @@ -231,7 +231,7 @@ void echelonconnectsport::characteristicChanged(const QLowEnergyCharacteristic & if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = 0.37497622 * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } if (watts()) KCal += diff --git a/src/fitplusbike.cpp b/src/fitplusbike.cpp index f33238fbc..7769769b4 100644 --- a/src/fitplusbike.cpp +++ b/src/fitplusbike.cpp @@ -272,7 +272,7 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte /*if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) Speed = (double)((((uint8_t)newValue.at(4)) << 10) | ((uint8_t)newValue.at(9))) / 100.0; else*/ - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } else if (newValue.length() == 13) { @@ -298,7 +298,7 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) Speed = (double)((((uint8_t)newValue.at(7)) << 8) | ((uint8_t)newValue.at(6))) / 10.0; else - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } if (watts()) diff --git a/src/flywheelbike.cpp b/src/flywheelbike.cpp index 1ef940daa..c01379b41 100644 --- a/src/flywheelbike.cpp +++ b/src/flywheelbike.cpp @@ -290,7 +290,7 @@ void flywheelbike::characteristicChanged(const QLowEnergyCharacteristic &charact if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = ((double)speed) / 10.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } // https://www.facebook.com/groups/149984563348738/permalink/174268944253633/?comment_id=174366620910532&reply_comment_id=174666314213896 diff --git a/src/ftmsbike.cpp b/src/ftmsbike.cpp index 32b2cabaf..c504e5da3 100644 --- a/src/ftmsbike.cpp +++ b/src/ftmsbike.cpp @@ -204,7 +204,7 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/horizongr7bike.cpp b/src/horizongr7bike.cpp index 3092b0740..86bb2f427 100644 --- a/src/horizongr7bike.cpp +++ b/src/horizongr7bike.cpp @@ -211,7 +211,7 @@ void horizongr7bike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); @@ -234,7 +234,7 @@ void horizongr7bike::characteristicChanged(const QLowEnergyCharacteristic &chara (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/inspirebike.cpp b/src/inspirebike.cpp index f7d1d6b70..91a2de8cf 100644 --- a/src/inspirebike.cpp +++ b/src/inspirebike.cpp @@ -149,7 +149,7 @@ void inspirebike::characteristicChanged(const QLowEnergyCharacteristic &characte if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = 0.37497622 * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } if (watts()) KCal += diff --git a/src/keepbike.cpp b/src/keepbike.cpp index 938478ff2..bf1fef3bc 100644 --- a/src/keepbike.cpp +++ b/src/keepbike.cpp @@ -212,7 +212,7 @@ void keepbike::characteristicChanged(const QLowEnergyCharacteristic &characteris Speed = ((uint8_t)newValue.at(18)); } else*/ { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } m_watt = GetWattFromPacket(newValue); diff --git a/src/m3ibike.cpp b/src/m3ibike.cpp index 31c08cf04..958e5e92d 100644 --- a/src/m3ibike.cpp +++ b/src/m3ibike.cpp @@ -679,7 +679,7 @@ void m3ibike::processAdvertising(const QByteArray &data) { if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = k3.speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } if (settings.value(QZSettings::m3i_bike_kcal, QZSettings::default_m3i_bike_kcal).toBool()) { KCal = k3.calorie; diff --git a/src/mcfbike.cpp b/src/mcfbike.cpp index eb0095ee7..212ef4816 100644 --- a/src/mcfbike.cpp +++ b/src/mcfbike.cpp @@ -203,7 +203,7 @@ void mcfbike::characteristicChanged(const QLowEnergyCharacteristic &characterist if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = (((uint16_t)newValue.at(11) << 8) | (uint16_t)((uint8_t)newValue.at(12))) / 10.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } Distance += ((Speed.value() / 3600000.0) * diff --git a/src/metric.cpp b/src/metric.cpp index e01209dfa..35febc303 100644 --- a/src/metric.cpp +++ b/src/metric.cpp @@ -181,10 +181,8 @@ void metric::clearLap(bool accumulator) { void metric::setLap(bool accumulator) { clearLap(accumulator); } -double metric::calculateSpeedFromPower(double power, double inclination) { +double metric::calculateMaxSpeedFromPower(double power, double inclination) { QSettings settings; - if (inclination < -5) - inclination = -5; double twt = 9.8 * (settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() + settings.value(QZSettings::bike_weight, QZSettings::default_bike_weight).toFloat()); double aero = 0.22691607640851885; @@ -213,6 +211,39 @@ double metric::calculateSpeedFromPower(double power, double inclination) { return 0.0; // failed to converge } +double metric::calculatePowerFromSpeed(double speed, double inclination) { + QSettings settings; + double v = speed / 3.6; // converted to m/s; + double hw = 0; // wind speed + double tv = v + 0; + double tran = 0.95; + const double aero = 0.22691607640851885; + double A2Eff = (tv > 0.0) ? aero : -aero; // wind in face, must reverse effect + double twt = 9.8 * (settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() + + settings.value(QZSettings::bike_weight, QZSettings::default_bike_weight).toFloat()); + double tr = twt * ((inclination / 100.0) + 0.005); + return (v * tr + v * tv * tv * A2Eff) / tran; +} + +double metric::calculateSpeedFromPower(double power, double inclination, double speed, double deltaTimeSeconds) { + QSettings settings; + if (inclination < -5) + inclination = -5; + + double fullWeight = (settings.value(QStringLiteral("weight"), 75.0).toFloat() + + settings.value(QStringLiteral("bike_weight"), 0.0).toFloat()); + double maxSpeed = calculateMaxSpeedFromPower(power, inclination); + double maxPowerFromSpeed = calculatePowerFromSpeed(speed, inclination); + double acceleration = (power - maxPowerFromSpeed) / fullWeight; + double newSpeed = speed + (acceleration * 3.6 * deltaTimeSeconds); + if(maxSpeed > newSpeed) + return newSpeed; + else if(maxSpeed < speed) + return newSpeed; + else + return maxSpeed; +} + double metric::calculateWeightLoss(double kcal) { return kcal / 7716.1854; // comes from 1 lbs = 3500 kcal. Converted to kg } diff --git a/src/metric.h b/src/metric.h index 6c9465d8e..3b87f6ea1 100644 --- a/src/metric.h +++ b/src/metric.h @@ -21,6 +21,7 @@ class metric { void setType(_metric_type t); void setValue(double value, bool applyGainAndOffset = true); double value(); + QDateTime lastChanged() {return m_lastChanged;} double average(); double average5s(); @@ -41,7 +42,9 @@ class metric { void setPaused(bool p); void setLap(bool accumulator); - static double calculateSpeedFromPower(double power, double inclination); + static double calculateMaxSpeedFromPower(double power, double inclination); + static double calculatePowerFromSpeed(double speed, double inclination); + static double calculateSpeedFromPower(double power, double inclination, double speed, double deltaTimeSeconds); static double calculateWeightLoss(double kcal); static double calculateVO2Max(QList *session); static double calculateKCalfromHR(double HR_AVG, double elapsed); diff --git a/src/npecablebike.cpp b/src/npecablebike.cpp index 4c1048dd7..e2b508417 100644 --- a/src/npecablebike.cpp +++ b/src/npecablebike.cpp @@ -180,7 +180,7 @@ void npecablebike::characteristicChanged(const QLowEnergyCharacteristic &charact if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); @@ -249,7 +249,7 @@ void npecablebike::characteristicChanged(const QLowEnergyCharacteristic &charact (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/pafersbike.cpp b/src/pafersbike.cpp index e7cece953..a684f448e 100644 --- a/src/pafersbike.cpp +++ b/src/pafersbike.cpp @@ -208,7 +208,7 @@ void pafersbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = ((uint8_t)newValue.at(3)); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } Resistance = ((uint8_t)newValue.at(5)); diff --git a/src/proformbike.cpp b/src/proformbike.cpp index 3348f4f9a..5a7a0e0c7 100644 --- a/src/proformbike.cpp +++ b/src/proformbike.cpp @@ -663,7 +663,7 @@ void proformbike::characteristicChanged(const QLowEnergyCharacteristic &characte Speed = ((double)((uint16_t)(((uint8_t)newValue.at(13)) << 8) + (uint16_t)((uint8_t)newValue.at(12))) / 100.0); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } double incline = @@ -881,7 +881,7 @@ void proformbike::characteristicChanged(const QLowEnergyCharacteristic &characte .toDouble()) * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } } } diff --git a/src/renphobike.cpp b/src/renphobike.cpp index ff154ff2b..7e5638d83 100644 --- a/src/renphobike.cpp +++ b/src/renphobike.cpp @@ -205,7 +205,7 @@ void renphobike::characteristicChanged(const QLowEnergyCharacteristic &character (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; else - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); index += 2; debug("Current Speed: " + QString::number(Speed.value())); } diff --git a/src/schwinnic4bike.cpp b/src/schwinnic4bike.cpp index b04e0b661..bc2b3d4d7 100644 --- a/src/schwinnic4bike.cpp +++ b/src/schwinnic4bike.cpp @@ -163,7 +163,7 @@ void schwinnic4bike::characteristicChanged(const QLowEnergyCharacteristic &chara (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/skandikawiribike.cpp b/src/skandikawiribike.cpp index f35f645a0..189b110d6 100644 --- a/src/skandikawiribike.cpp +++ b/src/skandikawiribike.cpp @@ -208,7 +208,7 @@ void skandikawiribike::characteristicChanged(const QLowEnergyCharacteristic &cha if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } } else if (newValue.at(1) == 0x10) { if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) diff --git a/src/snodebike.cpp b/src/snodebike.cpp index bf8b2bca2..85c82726b 100644 --- a/src/snodebike.cpp +++ b/src/snodebike.cpp @@ -162,7 +162,7 @@ void snodebike::characteristicChanged(const QLowEnergyCharacteristic &characteri (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/solebike.cpp b/src/solebike.cpp index 8fddc4af7..a028250b5 100644 --- a/src/solebike.cpp +++ b/src/solebike.cpp @@ -254,7 +254,7 @@ void solebike::characteristicChanged(const QLowEnergyCharacteristic &characteris if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = GetSpeedFromPacket(newValue); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } m_watt = GetWattFromPacket(newValue); diff --git a/src/sportsplusbike.cpp b/src/sportsplusbike.cpp index 4bac04ee9..4ee2998cb 100644 --- a/src/sportsplusbike.cpp +++ b/src/sportsplusbike.cpp @@ -143,7 +143,7 @@ void sportsplusbike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } lastTimeCharChanged = QDateTime::currentDateTime(); } else if (newValue.at(1) == 0x30) { @@ -181,7 +181,7 @@ void sportsplusbike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } lastTimeCharChanged = QDateTime::currentDateTime(); kcal = GetKcalFromPacket(newValue); diff --git a/src/sportstechbike.cpp b/src/sportstechbike.cpp index 8adc4d628..bb7a889cb 100644 --- a/src/sportstechbike.cpp +++ b/src/sportstechbike.cpp @@ -163,7 +163,7 @@ void sportstechbike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } Resistance = requestResistance; emit resistanceRead(Resistance.value()); diff --git a/src/stagesbike.cpp b/src/stagesbike.cpp index e766acb1e..b85a5b235 100644 --- a/src/stagesbike.cpp +++ b/src/stagesbike.cpp @@ -253,7 +253,7 @@ void stagesbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/trxappgateusbbike.cpp b/src/trxappgateusbbike.cpp index 6a067383a..e7b3fd806 100644 --- a/src/trxappgateusbbike.cpp +++ b/src/trxappgateusbbike.cpp @@ -329,16 +329,6 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch Distance += ((speed / 3600.0) / (1000.0 / (lastTimeCharChanged.msecsTo(QTime::currentTime())))); } - emit debug(QStringLiteral("Current speed: ") + QString::number(speed)); - emit debug(QStringLiteral("Current cadence: ") + QString::number(cadence)); - emit debug(QStringLiteral("Current heart: ") + QString::number(Heart.value())); - emit debug(QStringLiteral("Current KCal: ") + QString::number(kcal)); - emit debug(QStringLiteral("Current watt: ") + QString::number(watt)); - emit debug(QStringLiteral("Current Elapsed from the bike (not used): ") + - QString::number(GetElapsedFromPacket(newValue))); - emit debug(QStringLiteral("Current Elapsed: ") + QString::number(elapsed.value())); - emit debug(QStringLiteral("Current Distance Calculated: ") + QString::number(Distance.value())); - if (m_control->error() != QLowEnergyController::NoError) { qDebug() << QStringLiteral("QLowEnergyController ERROR!!") << m_control->errorString(); } @@ -346,7 +336,7 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } KCal = kcal; if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) @@ -381,7 +371,15 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch Resistance = resistance; emit resistanceRead(Resistance.value()); - + emit debug(QStringLiteral("Current speed: ") + QString::number(Speed.value())); + emit debug(QStringLiteral("Current cadence: ") + QString::number(cadence)); + emit debug(QStringLiteral("Current heart: ") + QString::number(Heart.value())); + emit debug(QStringLiteral("Current KCal: ") + QString::number(kcal)); + emit debug(QStringLiteral("Current watt: ") + QString::number(watt)); + emit debug(QStringLiteral("Current Elapsed from the bike (not used): ") + + QString::number(GetElapsedFromPacket(newValue))); + emit debug(QStringLiteral("Current Elapsed: ") + QString::number(elapsed.value())); + emit debug(QStringLiteral("Current Distance Calculated: ") + QString::number(Distance.value())); emit debug(QStringLiteral("Current resistance: ") + QString::number(resistance)); lastTimeCharChanged = QTime::currentTime(); diff --git a/src/ultrasportbike.cpp b/src/ultrasportbike.cpp index ad2c9930c..de4c93759 100644 --- a/src/ultrasportbike.cpp +++ b/src/ultrasportbike.cpp @@ -178,7 +178,7 @@ void ultrasportbike::characteristicChanged(const QLowEnergyCharacteristic &chara /*if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = GetSpeedFromPacket(newValue); } else*/ - { Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); } + { Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } if (watts()) KCal += diff --git a/src/wahookickrsnapbike.cpp b/src/wahookickrsnapbike.cpp index 482446771..0006ea7de 100644 --- a/src/wahookickrsnapbike.cpp +++ b/src/wahookickrsnapbike.cpp @@ -371,7 +371,7 @@ void wahookickrsnapbike::characteristicChanged(const QLowEnergyCharacteristic &c if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/yesoulbike.cpp b/src/yesoulbike.cpp index 069745657..04e2f2328 100644 --- a/src/yesoulbike.cpp +++ b/src/yesoulbike.cpp @@ -129,7 +129,7 @@ void yesoulbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = 0.37497622 * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value()); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } if (watts()) KCal += From db252c3ca3412b89924b363b0b1809e6659d5639 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sun, 25 Sep 2022 08:30:57 +0200 Subject: [PATCH 085/255] fixing negative speed values --- src/metric.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/metric.cpp b/src/metric.cpp index 35febc303..35b19ca4a 100644 --- a/src/metric.cpp +++ b/src/metric.cpp @@ -236,6 +236,8 @@ double metric::calculateSpeedFromPower(double power, double inclination, double double maxPowerFromSpeed = calculatePowerFromSpeed(speed, inclination); double acceleration = (power - maxPowerFromSpeed) / fullWeight; double newSpeed = speed + (acceleration * 3.6 * deltaTimeSeconds); + if(newSpeed < 0) + newSpeed = 0; if(maxSpeed > newSpeed) return newSpeed; else if(maxSpeed < speed) From 0472666dd57d65f10a3ac7c86e7ae3c4de791c53 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 26 Sep 2022 09:12:56 +0200 Subject: [PATCH 086/255] rolling resistance setting added --- src/metric.cpp | 13 +++++++------ src/qmdnsengine | 2 +- src/settings.qml | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/metric.cpp b/src/metric.cpp index 35b19ca4a..f7f904ca0 100644 --- a/src/metric.cpp +++ b/src/metric.cpp @@ -183,11 +183,12 @@ void metric::setLap(bool accumulator) { clearLap(accumulator); } double metric::calculateMaxSpeedFromPower(double power, double inclination) { QSettings settings; + double rolling_resistance = settings.value(QZSettings::rolling_resistance, QZSettings::default_rolling_resistance).toFloat(); double twt = 9.8 * (settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() + settings.value(QZSettings::bike_weight, QZSettings::default_bike_weight).toFloat()); double aero = 0.22691607640851885; double hw = 0; // wind speed - double tr = twt * ((inclination / 100.0) + 0.005); + double tr = twt * ((inclination / 100.0) + rolling_resistance); double tran = 0.95; double p = power; double vel = 20; // Initial guess @@ -213,15 +214,15 @@ double metric::calculateMaxSpeedFromPower(double power, double inclination) { double metric::calculatePowerFromSpeed(double speed, double inclination) { QSettings settings; - double v = speed / 3.6; // converted to m/s; - double hw = 0; // wind speed + double rolling_resistance = settings.value(QZSettings::rolling_resistance, QZSettings::default_rolling_resistance).toFloat(); + double v = speed / 3.6; // converted to m/s; double tv = v + 0; double tran = 0.95; const double aero = 0.22691607640851885; double A2Eff = (tv > 0.0) ? aero : -aero; // wind in face, must reverse effect double twt = 9.8 * (settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() + settings.value(QZSettings::bike_weight, QZSettings::default_bike_weight).toFloat()); - double tr = twt * ((inclination / 100.0) + 0.005); + double tr = twt * ((inclination / 100.0) + rolling_resistance); return (v * tr + v * tv * tv * A2Eff) / tran; } @@ -238,9 +239,9 @@ double metric::calculateSpeedFromPower(double power, double inclination, double double newSpeed = speed + (acceleration * 3.6 * deltaTimeSeconds); if(newSpeed < 0) newSpeed = 0; - if(maxSpeed > newSpeed) + if (maxSpeed > newSpeed) return newSpeed; - else if(maxSpeed < speed) + else if (maxSpeed < speed) return newSpeed; else return maxSpeed; diff --git a/src/qmdnsengine b/src/qmdnsengine index a52918803..2be37188d 160000 --- a/src/qmdnsengine +++ b/src/qmdnsengine @@ -1 +1 @@ -Subproject commit a529188038c5b235cf3d58ca2635f227c86f5e49 +Subproject commit 2be37188d0c85b7bfbf302ebaa3b82d7903909aa diff --git a/src/settings.qml b/src/settings.qml index ede5433e2..57ad4204a 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -477,6 +477,9 @@ import Qt.labs.settings 1.0 // from version 2.11.63 property bool nordictrack_gx_2_7: false + + // from version 2.11.65 + property real rolling_resistance: 0.005 // from version ? property bool trixter_xdream_v1_bike: false @@ -1167,6 +1170,38 @@ import Qt.labs.settings 1.0 Layout.fillWidth: true onClicked: settings.speed_power_based = checked } + RowLayout { + spacing: 10 + Label { + id: labelRollingResistance + text: qsTr("Rolling Resistance Factor") + Layout.fillWidth: true + } + TextField { + id: rollingreistanceTextField + text: settings.rolling_resistance + horizontalAlignment: Text.AlignRight + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + //inputMethodHints: Qt.ImhFormattedNumbersOnly + onAccepted: settings.rolling_resistance = text + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okRollingResistanceButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.rolling_resistance = rollingreistanceTextField.text + } + } + Label { + id: labelRollingResistanceInfo + text: qsTr("0.005 = Clinchers\n0.004 = Tubulars\n0.012 = MTB") + font.italic: true + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + font.pixelSize: 9 + color: "steelblue" + } RowLayout { spacing: 10 Label { From 297497fda8f21ce2473ff0c62cad2baee6e3f47b Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 6 Oct 2022 09:05:56 +0200 Subject: [PATCH 087/255] updating ios project --- .../qdomyoszwift.xcodeproj/project.pbxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj index 2fbd3ea55..c540ad1bd 100644 --- a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj +++ b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj @@ -440,6 +440,7 @@ 87EFE45927A518F5006EA1C3 /* nautiluselliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87EFE45827A518F5006EA1C3 /* nautiluselliptical.cpp */; }; 87EFE45B27A51901006EA1C3 /* moc_nautiluselliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87EFE45A27A51900006EA1C3 /* moc_nautiluselliptical.cpp */; }; 87F1179E26A5FBDE00541B3A /* libqtwebview_darwin.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 87420DF7269D7CE1000C5EC6 /* libqtwebview_darwin.a */; }; + 87F527BE28EEB5AA00A9F8D5 /* qzsettings.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F527BC28EEB5AA00A9F8D5 /* qzsettings.cpp */; }; 87F93427278E0EC00088B596 /* domyosrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F93426278E0EC00088B596 /* domyosrower.cpp */; }; 87F93429278E0ECF0088B596 /* moc_domyosrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F93428278E0ECF0088B596 /* moc_domyosrower.cpp */; }; 87FA11AB27C5ECD1008AC5D1 /* ultrasportbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87FA11AA27C5ECD1008AC5D1 /* ultrasportbike.cpp */; }; @@ -1250,6 +1251,8 @@ 87EFE45727A518F5006EA1C3 /* nautiluselliptical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = nautiluselliptical.h; path = ../src/nautiluselliptical.h; sourceTree = ""; }; 87EFE45827A518F5006EA1C3 /* nautiluselliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = nautiluselliptical.cpp; path = ../src/nautiluselliptical.cpp; sourceTree = ""; }; 87EFE45A27A51900006EA1C3 /* moc_nautiluselliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_nautiluselliptical.cpp; sourceTree = ""; }; + 87F527BC28EEB5AA00A9F8D5 /* qzsettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qzsettings.cpp; path = ../src/qzsettings.cpp; sourceTree = ""; }; + 87F527BD28EEB5AA00A9F8D5 /* qzsettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qzsettings.h; path = ../src/qzsettings.h; sourceTree = ""; }; 87F93425278E0EC00088B596 /* domyosrower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = domyosrower.h; path = ../src/domyosrower.h; sourceTree = ""; }; 87F93426278E0EC00088B596 /* domyosrower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = domyosrower.cpp; path = ../src/domyosrower.cpp; sourceTree = ""; }; 87F93428278E0ECF0088B596 /* moc_domyosrower.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_domyosrower.cpp; sourceTree = ""; }; @@ -1782,6 +1785,8 @@ 2EB56BE3C2D93CDAB0C52E67 /* Sources */ = { isa = PBXGroup; children = ( + 87F527BC28EEB5AA00A9F8D5 /* qzsettings.cpp */, + 87F527BD28EEB5AA00A9F8D5 /* qzsettings.h */, 872A20D928C5EC380037774D /* faketreadmill.cpp */, 872A20D828C5EC380037774D /* faketreadmill.h */, 878C9E6828B77E7B00669129 /* nordictrackifitadbbike.cpp */, @@ -2951,6 +2956,7 @@ 87C5F0B726285E5F0067A1B5 /* mimecontentformatter.cpp in Compile Sources */, 23191C28CB29474279752FD3 /* fit_protocol_validator.cpp in Compile Sources */, 275D55B5D956B2E5F1B7E46E /* fit_unicode.cpp in Compile Sources */, + 87F527BE28EEB5AA00A9F8D5 /* qzsettings.cpp in Compile Sources */, 8703BAEB273C67A90058E206 /* pafersbike.cpp in Compile Sources */, 87061399286D8D6500D2446E /* moc_wobjectdefs.cpp in Compile Sources */, 873824BA27E64707004F1B46 /* moc_server_p.cpp in Compile Sources */, From 8f972f31c1c6e26b0380c22d63c4b531719bac1f Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 6 Oct 2022 08:57:51 +0200 Subject: [PATCH 088/255] fixing another merge issue --- src/qzsettings.cpp | 6 ++++-- src/qzsettings.h | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/qzsettings.cpp b/src/qzsettings.cpp index 5e61a42e2..c811eaf76 100644 --- a/src/qzsettings.cpp +++ b/src/qzsettings.cpp @@ -430,8 +430,9 @@ const QString QZSettings:: default_horizon_treadmill_profile_user4 = QStringLite const QString QZSettings:: horizon_treadmill_profile_user5 = QStringLiteral("horizon_treadmill_profile_user5"); const QString QZSettings:: default_horizon_treadmill_profile_user5 = QStringLiteral("user5"); const QString QZSettings:: nordictrack_gx_2_7 = QStringLiteral("nordictrack_gx_2_7"); +const QString QZSettings:: rolling_resistance = QStringLiteral("rolling_resistance"); -const uint32_t allSettingsCount = 366; +const uint32_t allSettingsCount = 367; QVariant allSettings[allSettingsCount][2] = { { QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles }, { QZSettings::bluetooth_no_reconnection, QZSettings::default_bluetooth_no_reconnection }, @@ -798,7 +799,8 @@ QVariant allSettings[allSettingsCount][2] = { { QZSettings::horizon_treadmill_profile_user3, QZSettings::default_horizon_treadmill_profile_user3}, { QZSettings::horizon_treadmill_profile_user4, QZSettings::default_horizon_treadmill_profile_user4}, { QZSettings::horizon_treadmill_profile_user5, QZSettings::default_horizon_treadmill_profile_user5}, - { QZSettings::nordictrack_gx_2_7, QZSettings::default_nordictrack_gx_2_7} + { QZSettings::nordictrack_gx_2_7, QZSettings::default_nordictrack_gx_2_7}, + { QZSettings::rolling_resistance, QZSettings::default_rolling_resistance} }; void QZSettings::qDebugAllSettings(bool showDefaults) { diff --git a/src/qzsettings.h b/src/qzsettings.h index 584324adc..03c5113a1 100644 --- a/src/qzsettings.h +++ b/src/qzsettings.h @@ -1337,6 +1337,9 @@ class QZSettings { static const QString nordictrack_gx_2_7; static const bool default_nordictrack_gx_2_7 = false; + static const QString rolling_resistance; + static constexpr double default_rolling_resistance = 0.005; + /** * @brief Write the QSettings values using the constants from this namespace. * @param showDefaults Optionally indicates if the default should be shown with the key. From 66717a858084b1b862c53c8b2eb066fb7580cc23 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 7 Oct 2022 14:30:34 +0200 Subject: [PATCH 089/255] GPX Issues on Treadmill #973 --- src/horizontreadmill.cpp | 87 +++++++++++++++++++++++++++------------- src/horizontreadmill.h | 57 +++++++++++++------------- 2 files changed, 88 insertions(+), 56 deletions(-) diff --git a/src/horizontreadmill.cpp b/src/horizontreadmill.cpp index 8d71d88e6..01a3e2e01 100644 --- a/src/horizontreadmill.cpp +++ b/src/horizontreadmill.cpp @@ -80,16 +80,22 @@ void horizontreadmill::btinit() { QSettings settings; QStringList horizon_treadmill_profile_users; horizon_treadmill_profile_users.append( - settings.value(QZSettings::horizon_treadmill_profile_user1, QZSettings::default_horizon_treadmill_profile_user1).toString()); + settings.value(QZSettings::horizon_treadmill_profile_user1, QZSettings::default_horizon_treadmill_profile_user1) + .toString()); horizon_treadmill_profile_users.append( - settings.value(QZSettings::horizon_treadmill_profile_user2, QZSettings::default_horizon_treadmill_profile_user2).toString()); + settings.value(QZSettings::horizon_treadmill_profile_user2, QZSettings::default_horizon_treadmill_profile_user2) + .toString()); horizon_treadmill_profile_users.append( - settings.value(QZSettings::horizon_treadmill_profile_user3, QZSettings::default_horizon_treadmill_profile_user3).toString()); + settings.value(QZSettings::horizon_treadmill_profile_user3, QZSettings::default_horizon_treadmill_profile_user3) + .toString()); horizon_treadmill_profile_users.append( - settings.value(QZSettings::horizon_treadmill_profile_user4, QZSettings::default_horizon_treadmill_profile_user4).toString()); + settings.value(QZSettings::horizon_treadmill_profile_user4, QZSettings::default_horizon_treadmill_profile_user4) + .toString()); horizon_treadmill_profile_users.append( - settings.value(QZSettings::horizon_treadmill_profile_user5, QZSettings::default_horizon_treadmill_profile_user5).toString()); - bool horizon_paragon_x = settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); + settings.value(QZSettings::horizon_treadmill_profile_user5, QZSettings::default_horizon_treadmill_profile_user5) + .toString()); + bool horizon_paragon_x = + settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); uint8_t initData01_paragon[] = {0x55, 0xaa, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a}; @@ -746,8 +752,10 @@ void horizontreadmill::update() { /*initDone*/) { QSettings settings; - bool horizon_treadmill_7_8 = settings.value(QZSettings::horizon_treadmill_7_8, QZSettings::default_horizon_treadmill_7_8).toBool(); - bool horizon_paragon_x = settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); + bool horizon_treadmill_7_8 = + settings.value(QZSettings::horizon_treadmill_7_8, QZSettings::default_horizon_treadmill_7_8).toBool(); + bool horizon_paragon_x = + settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); update_metrics(true, watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())); // updating the treadmill console every second @@ -758,7 +766,9 @@ void horizontreadmill::update() { } if (requestSpeed != -1) { - if (requestSpeed != currentSpeed().value() && requestSpeed >= 0 && requestSpeed <= 22) { + if (requestSpeed != currentSpeed().value() && + fabs(requestSpeed - currentSpeed().value()) > minStepSpeed() && requestSpeed >= 0 && + requestSpeed <= 22) { emit debug(QStringLiteral("writing speed ") + QString::number(requestSpeed)); forceSpeed(requestSpeed); } @@ -767,6 +777,8 @@ void horizontreadmill::update() { if (requestInclination != -100) { if (requestInclination < 0) requestInclination = 0; + // the treadmill accepts only .5 steps + requestInclination = floor(requestInclination) + 0.5; if (requestInclination != currentInclination().value() && requestInclination >= 0 && requestInclination <= 15) { emit debug(QStringLiteral("writing incline ") + QString::number(requestInclination)); @@ -900,7 +912,8 @@ void horizontreadmill::update() { // example frame: 55aa320003050400532c00150000 void horizontreadmill::forceSpeed(double requestSpeed) { QSettings settings; - bool horizon_paragon_x = settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); + bool horizon_paragon_x = + settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); if (gattCustomService) { if (!horizon_paragon_x) { @@ -968,7 +981,8 @@ void horizontreadmill::forceSpeed(double requestSpeed) { // example frame: 55aa3800030603005d0b0a0000 void horizontreadmill::forceIncline(double requestIncline) { QSettings settings; - bool horizon_paragon_x = settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); + bool horizon_paragon_x = + settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); if (gattCustomService) { if (!horizon_paragon_x) { @@ -1037,7 +1051,8 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha Q_UNUSED(characteristic); bool distanceEval = false; QSettings settings; - // bool horizon_paragon_x = settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); + // bool horizon_paragon_x = settings.value(QZSettings::horizon_paragon_x, + // QZSettings::default_horizon_paragon_x).toBool(); QString heartRateBeltName = settings.value(QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name).toString(); @@ -1074,7 +1089,8 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha if (firstDistanceCalculated && watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) KCal += - ((((0.048 * ((double)watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) + 1.19) * + ((((0.048 * ((double)watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) + + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / 200.0) / (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( @@ -1100,7 +1116,8 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha if (firstDistanceCalculated && watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) KCal += - ((((0.048 * ((double)watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) + 1.19) * + ((((0.048 * ((double)watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) + + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / 200.0) / (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( @@ -1123,7 +1140,8 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha // emit debug(QStringLiteral("Current Inclination: ") + QString::number(Inclination.value())); if (firstDistanceCalculated && watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) KCal += - ((((0.048 * ((double)watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) + 1.19) * + ((((0.048 * ((double)watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) + + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / 200.0) / (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( @@ -1242,14 +1260,18 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha // energy per minute index += 1; } else { - if (firstDistanceCalculated && watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) - KCal += ((((0.048 * ((double)watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) + 1.19) * - settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / - 200.0) / - (60000.0 / - ((double)lastRefreshCharacteristicChanged.msecsTo( - QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in - // kg * 3.5) / 200 ) / 60 + if (firstDistanceCalculated && + watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) + KCal += + ((((0.048 * + ((double)watts(settings.value(QZSettings::weight, QZSettings::default_weight).toFloat())) + + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / + 200.0) / + (60000.0 / + ((double)lastRefreshCharacteristicChanged.msecsTo( + QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in + // kg * 3.5) / 200 ) / 60 distanceEval = true; } @@ -1291,7 +1313,8 @@ void horizontreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha } if (heartRateBeltName.startsWith(QStringLiteral("Disabled"))) { - if (heart == 0.0 || settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool()) { + if (heart == 0.0 || + settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool()) { #ifdef Q_OS_IOS #ifndef IO_UNDER_QT @@ -1420,8 +1443,11 @@ void horizontreadmill::stateChanged(QLowEnergyService::ServiceState state) { ) { QSettings settings; - bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); - bool virtual_device_force_bike = settings.value(QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike).toBool(); + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_force_bike = + settings.value(QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike) + .toBool(); if (virtual_device_enabled) { if (!virtual_device_force_bike) { debug("creating virtual treadmill interface..."); @@ -1608,8 +1634,10 @@ bool horizontreadmill::autoPauseWhenSpeedIsZero() { bool horizontreadmill::autoStartWhenSpeedIsGreaterThenZero() { QSettings settings; - bool horizon_treadmill_7_8 = settings.value(QZSettings::horizon_treadmill_7_8, QZSettings::default_horizon_treadmill_7_8).toBool(); - bool horizon_paragon_x = settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); + bool horizon_treadmill_7_8 = + settings.value(QZSettings::horizon_treadmill_7_8, QZSettings::default_horizon_treadmill_7_8).toBool(); + bool horizon_paragon_x = + settings.value(QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x).toBool(); // the horizon starts with a strange speed, since that i can auto start (maybe the best way to solve this // is to understand why it's starting with this strange speed) @@ -2213,3 +2241,6 @@ void horizontreadmill::testProfileCRC() { assert(initData7_6[8] == (confirm & 0xff)); assert(initData7_6[9] == (confirm >> 8)); } + +double horizontreadmill::minStepInclination() { return 0.5; } +double horizontreadmill::minStepSpeed() { return 0.1; } diff --git a/src/horizontreadmill.h b/src/horizontreadmill.h index 55012f4ca..bd187f222 100644 --- a/src/horizontreadmill.h +++ b/src/horizontreadmill.h @@ -43,6 +43,8 @@ class horizontreadmill : public treadmill { bool connected(); void forceSpeed(double requestSpeed); void forceIncline(double requestIncline); + double minStepInclination(); + double minStepSpeed(); void *VirtualTreadmill(); void *VirtualDevice(); @@ -88,70 +90,69 @@ class horizontreadmill : public treadmill { int32_t customRecv = 0; int32_t messageID = 0; - + void testProfileCRC(); void updateProfileCRC(); int GenerateCRC_CCITT(uint8_t *PUPtr8, int PU16_Count, int crcStart = 65535); - - + // profiles uint8_t initData7[20] = {0x55, 0xaa, 0x02, 0x00, 0x01, 0x16, 0xdb, 0x02, 0xed, 0xc2, - 0x00, 0x47, 0x75, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00}; + 0x00, 0x47, 0x75, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00}; uint8_t initData8[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t initData9[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x05, 0xc2, 0x07}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x05, 0xc2, 0x07}; uint8_t initData10[20] = {0x01, 0x01, 0x00, 0xd3, 0x8a, 0x0c, 0x00, 0x01, 0x01, 0x02, - 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; + 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; uint8_t initData11[20] = {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; uint8_t initData12[20] = {0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t initData13[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; uint8_t initData14[1] = {0x30}; uint8_t initData7_1[20] = {0x55, 0xaa, 0x03, 0x00, 0x01, 0x16, 0xdb, 0x02, 0xae, 0x2a, - 0x01, 0x41, 0x69, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00}; + 0x01, 0x41, 0x69, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t initData9_1[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0xc4, 0x07}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0xc4, 0x07}; uint8_t initData10_1[20] = {0x09, 0x1c, 0x00, 0x9f, 0xef, 0x0c, 0x00, 0x01, 0x01, 0x02, - 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; + 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; uint8_t initData7_2[20] = {0x55, 0xaa, 0x04, 0x00, 0x01, 0x16, 0xdb, 0x02, 0xae, 0x2a, - 0x01, 0x41, 0x69, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00}; + 0x01, 0x41, 0x69, 0x61, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t initData9_2[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0xc4, 0x07}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0xc4, 0x07}; uint8_t initData10_2[20] = {0x09, 0x1c, 0x00, 0x9f, 0xef, 0x0c, 0x00, 0x01, 0x01, 0x02, - 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; + 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; uint8_t initData7_3[20] = {0x55, 0xaa, 0x05, 0x00, 0x01, 0x16, 0xdb, 0x02, 0xa9, 0xe7, - 0x02, 0x4d, 0x65, 0x67, 0x68, 0x61, 0x00, 0x00, 0x00, 0x00}; + 0x02, 0x4d, 0x65, 0x67, 0x68, 0x61, 0x00, 0x00, 0x00, 0x00}; uint8_t initData9_3[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0xc5, 0x07}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x06, 0xc5, 0x07}; uint8_t initData10_3[20] = {0x0b, 0x0f, 0x00, 0x4b, 0x40, 0x0c, 0x00, 0x01, 0x01, 0x02, - 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; + 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; uint8_t initData7_4[20] = {0x55, 0xaa, 0x06, 0x00, 0x01, 0x16, 0xdb, 0x02, 0xbc, 0x76, - 0x03, 0x44, 0x61, 0x72, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00}; + 0x03, 0x44, 0x61, 0x72, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t initData9_4[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0xca, 0x07}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0xca, 0x07}; uint8_t initData10_4[20] = {0x05, 0x1c, 0x00, 0x07, 0x25, 0x0c, 0x00, 0x01, 0x01, 0x02, - 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; + 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; uint8_t initData7_5[20] = {0x55, 0xaa, 0x07, 0x00, 0x01, 0x16, 0xdb, 0x02, 0x7d, 0xeb, - 0x04, 0x41, 0x68, 0x6f, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00}; + 0x04, 0x41, 0x68, 0x6f, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00}; uint8_t initData9_5[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x04, 0xcc, 0x07}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x04, 0xcc, 0x07}; uint8_t initData10_5[20] = {0x01, 0x08, 0x00, 0xc2, 0x0f, 0x0c, 0x00, 0x01, 0x01, 0x02, - 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; + 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; uint8_t initData7_6[20] = {0x55, 0xaa, 0x08, 0x00, 0x01, 0x16, 0xdb, 0x02, 0x03, 0x0d, - 0x05, 0x55, 0x73, 0x65, 0x72, 0x20, 0x35, 0x00, 0x00, 0x00}; + 0x05, 0x55, 0x73, 0x65, 0x72, 0x20, 0x35, 0x00, 0x00, 0x00}; uint8_t initData9_6[20] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x05, 0xc2, 0x07}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x05, 0xc2, 0x07}; uint8_t initData10_6[20] = {0x01, 0x01, 0x00, 0x8e, 0x6a, 0x0c, 0x00, 0x01, 0x01, 0x02, - 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; + 0x23, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}; // profiles end #ifdef Q_OS_IOS From 8f7d8d100f2fd75861d70cff40d430d813b74c48 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sat, 8 Oct 2022 03:02:45 +0200 Subject: [PATCH 090/255] fixed qzsettings usage --- src/metric.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/metric.cpp b/src/metric.cpp index f7f904ca0..9717df60e 100644 --- a/src/metric.cpp +++ b/src/metric.cpp @@ -231,8 +231,8 @@ double metric::calculateSpeedFromPower(double power, double inclination, double if (inclination < -5) inclination = -5; - double fullWeight = (settings.value(QStringLiteral("weight"), 75.0).toFloat() + - settings.value(QStringLiteral("bike_weight"), 0.0).toFloat()); + double fullWeight = (settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() + + settings.value(QZSettings::bike_weight, QZSettings::default_bike_weight).toFloat()); double maxSpeed = calculateMaxSpeedFromPower(power, inclination); double maxPowerFromSpeed = calculatePowerFromSpeed(speed, inclination); double acceleration = (power - maxPowerFromSpeed) / fullWeight; From c8ec85e3340e1c71655bcd6b0a45b8d959bff62b Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sat, 8 Oct 2022 15:19:05 +0200 Subject: [PATCH 091/255] GPX Issues on Treadmill #973 map icon showed only when speed forcing for treadmill is disabled --- src/homeform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/homeform.cpp b/src/homeform.cpp index 5d693b32e..00bc9c824 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -3514,13 +3514,13 @@ void homeform::gpx_open_clicked(const QUrl &fileName) { r.gpxElapsed = QTime(0, 0, 0).addSecs(p.seconds); list.append(r); - setMapsVisible(true); } } last = p; i++; } + setMapsVisible(true); trainProgram = new trainprogram(list, bluetoothManager); if (g.getVideoURL().isEmpty() == false) { From 6b5234e63aa5afd12e4b8df8227cff5defd29c50 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sat, 8 Oct 2022 19:55:17 +0200 Subject: [PATCH 092/255] fixed crash for nautilus treadmill --- src/nautilustreadmill.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nautilustreadmill.cpp b/src/nautilustreadmill.cpp index 3da327618..8c3071e09 100644 --- a/src/nautilustreadmill.cpp +++ b/src/nautilustreadmill.cpp @@ -321,6 +321,9 @@ void nautilustreadmill::serviceScanDone(void) { QBluetoothUuid _gattCommunicationChannelServiceId(QStringLiteral("89e14b5e-a841-48ad-b580-935f4545fffc")); gattCommunicationChannelService = m_control->createServiceObject(_gattCommunicationChannelServiceId); + if(!gattCommunicationChannelService) { + return; + } connect(gattCommunicationChannelService, &QLowEnergyService::stateChanged, this, &nautilustreadmill::stateChanged); gattCommunicationChannelService->discoverDetails(); } From 56f0f3ba3f9a153c98dd4c0acda0386c45e5cbca Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sun, 9 Oct 2022 08:26:46 +0200 Subject: [PATCH 093/255] GPX Issues on Treadmill #973 --- src/horizontreadmill.cpp | 2 ++ src/treadmill.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/horizontreadmill.cpp b/src/horizontreadmill.cpp index 01a3e2e01..050f11ad9 100644 --- a/src/horizontreadmill.cpp +++ b/src/horizontreadmill.cpp @@ -766,6 +766,7 @@ void horizontreadmill::update() { } if (requestSpeed != -1) { + qDebug() << "requestSpeed=" << requestSpeed; if (requestSpeed != currentSpeed().value() && fabs(requestSpeed - currentSpeed().value()) > minStepSpeed() && requestSpeed >= 0 && requestSpeed <= 22) { @@ -775,6 +776,7 @@ void horizontreadmill::update() { requestSpeed = -1; } if (requestInclination != -100) { + qDebug() << "requestInclination=" << requestInclination; if (requestInclination < 0) requestInclination = 0; // the treadmill accepts only .5 steps diff --git a/src/treadmill.cpp b/src/treadmill.cpp index 7929bed4f..46717c46f 100644 --- a/src/treadmill.cpp +++ b/src/treadmill.cpp @@ -5,12 +5,14 @@ treadmill::treadmill() {} void treadmill::changeSpeed(double speed) { + qDebug() << "changeSpeed" << speed << autoResistanceEnable; RequestedSpeed = speed; if (autoResistanceEnable) requestSpeed = speed; } void treadmill::changeInclination(double grade, double inclination) { Q_UNUSED(inclination); + qDebug() << "changeInclination" << grade << autoResistanceEnable; RequestedInclination = grade; if (autoResistanceEnable) { requestInclination = grade; From bb914984d123dc67a75b32bcf19a9a209e449eec Mon Sep 17 00:00:00 2001 From: Brian Bannister Date: Mon, 10 Oct 2022 18:22:53 +1300 Subject: [PATCH 094/255] Adding ESLinker YPOO Mini Change treadmill --- src/eslinkertreadmill.cpp | 38 +++++++++++++++++++++++++++----------- src/eslinkertreadmill.h | 1 + src/qzsettings.cpp | 4 +++- src/qzsettings.h | 2 ++ src/settings.qml | 16 +++++++++++++++- 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/eslinkertreadmill.cpp b/src/eslinkertreadmill.cpp index 5feb11090..cb3eb91ca 100644 --- a/src/eslinkertreadmill.cpp +++ b/src/eslinkertreadmill.cpp @@ -60,7 +60,7 @@ void eslinkertreadmill::writeCharacteristic(uint8_t *data, uint8_t data_len, con } void eslinkertreadmill::updateDisplay(uint16_t elapsed) { - if (treadmill_type == RHYTHM_FUN) { + if (treadmill_type == RHYTHM_FUN || treadmill_type == YPOO_MINI_CHANGE) { // trying to force a fixed value to keep the connection on uint8_t display[] = {0xa9, 0xa0, 0x03, 0x02, 0x23, 0x00, 0x2b}; @@ -129,7 +129,7 @@ void eslinkertreadmill::update() { updateDisplay(elapsed.value()); } - if (treadmill_type == TYPE::RHYTHM_FUN) { + if (treadmill_type == TYPE::RHYTHM_FUN || treadmill_type == TYPE::YPOO_MINI_CHANGE) { // if (requestSpeed != -1) { if (requestSpeed != currentSpeed().value() && requestSpeed >= 0 && requestSpeed <= 22) { emit debug(QStringLiteral("writing speed ") + QString::number(requestSpeed)); @@ -202,7 +202,7 @@ void eslinkertreadmill::update() { if (lastSpeed == 0.0) { lastSpeed = 0.5; } - if (treadmill_type == TYPE::RHYTHM_FUN) + if (treadmill_type == TYPE::RHYTHM_FUN || treadmill_type == TYPE::YPOO_MINI_CHANGE) btinit(true); requestSpeed = 1.0; requestStart = -1; @@ -311,10 +311,10 @@ void eslinkertreadmill::characteristicChanged(const QLowEnergyCharacteristic &ch } } - if ((newValue.length() != 17 && treadmill_type == RHYTHM_FUN)) + if ((newValue.length() != 17 && (treadmill_type == RHYTHM_FUN || treadmill_type == YPOO_MINI_CHANGE))) return; - if (treadmill_type == RHYTHM_FUN) { + if (treadmill_type == RHYTHM_FUN || treadmill_type == YPOO_MINI_CHANGE) { double speed = GetSpeedFromPacket(value); double incline = GetInclinationFromPacket(value); double kcal = GetKcalFromPacket(value); @@ -379,12 +379,23 @@ void eslinkertreadmill::characteristicChanged(const QLowEnergyCharacteristic &ch double eslinkertreadmill::GetSpeedFromPacket(const QByteArray &packet) { uint8_t convertedData = (uint8_t)packet.at(14); double data = (double)convertedData / 10.0f; + if (treadmill_type == YPOO_MINI_CHANGE && data < 1.0d) { + data = 0.0d; + } return data; } double eslinkertreadmill::GetKcalFromPacket(const QByteArray &packet) { - uint16_t convertedData = (packet.at(7) << 8) | packet.at(8); - return (double)convertedData; + double data; + if (treadmill_type == YPOO_MINI_CHANGE) { + uint16_t convertedData = (((uint8_t)packet.at(5)) << 8) | (uint8_t)packet.at(6);; + data = (double)convertedData / 100.0f; + } + else { + uint16_t convertedData = (packet.at(7) << 8) | packet.at(8); + data = (double)convertedData; + } + return data; } double eslinkertreadmill::GetDistanceFromPacket(const QByteArray &packet) { @@ -394,9 +405,11 @@ double eslinkertreadmill::GetDistanceFromPacket(const QByteArray &packet) { } double eslinkertreadmill::GetInclinationFromPacket(const QByteArray &packet) { - uint16_t convertedData = packet.at(11); - double data = convertedData; - + double data = 0.0d; + if (treadmill_type != YPOO_MINI_CHANGE) { + uint16_t convertedData = packet.at(11); + data = convertedData; + } return data; } @@ -418,7 +431,7 @@ void eslinkertreadmill::btinit(bool startTape) { uint8_t initData2_CADENZA[] = {0x08, 0x01, 0x01}; - if (treadmill_type == RHYTHM_FUN) { + if (treadmill_type == RHYTHM_FUN || treadmill_type == YPOO_MINI_CHANGE) { writeCharacteristic(initData1, sizeof(initData1), QStringLiteral("init"), false, false); writeCharacteristic(initData2, sizeof(initData2), QStringLiteral("init"), false, true); writeCharacteristic(initData3, sizeof(initData3), QStringLiteral("init"), false, true); @@ -543,8 +556,11 @@ void eslinkertreadmill::deviceDiscovered(const QBluetoothDeviceInfo &device) { QSettings settings; bool eslinker_cadenza = settings.value(QZSettings::eslinker_cadenza, QZSettings::default_eslinker_cadenza).toBool(); + bool eslinker_ypoo = settings.value(QZSettings::eslinker_ypoo, QZSettings::default_eslinker_ypoo).toBool(); if (eslinker_cadenza) { treadmill_type = CADENZA_FITNESS_T45; + } else if (eslinker_ypoo) { + treadmill_type = YPOO_MINI_CHANGE; } else treadmill_type = RHYTHM_FUN; diff --git a/src/eslinkertreadmill.h b/src/eslinkertreadmill.h index 4d584568e..f454f5576 100644 --- a/src/eslinkertreadmill.h +++ b/src/eslinkertreadmill.h @@ -68,6 +68,7 @@ class eslinkertreadmill : public treadmill { typedef enum TYPE { RHYTHM_FUN = 0, CADENZA_FITNESS_T45 = 1, // it has the same protocol of RHYTHM_FUN but without the header and the footer + YPOO_MINI_CHANGE = 2, // Similar to RHYTHM_FUN but has no ascension } TYPE; volatile TYPE treadmill_type = RHYTHM_FUN; diff --git a/src/qzsettings.cpp b/src/qzsettings.cpp index c811eaf76..62f5af842 100644 --- a/src/qzsettings.cpp +++ b/src/qzsettings.cpp @@ -199,6 +199,7 @@ const QString QZSettings:: domyos_bike_cadence_filter = QStringLiteral("domyos_b const QString QZSettings:: domyos_bike_display_calories = QStringLiteral("domyos_bike_display_calories"); const QString QZSettings:: domyos_elliptical_speed_ratio = QStringLiteral("domyos_elliptical_speed_ratio"); const QString QZSettings:: eslinker_cadenza = QStringLiteral("eslinker_cadenza"); +const QString QZSettings:: eslinker_ypoo = QStringLiteral("eslinker_ypoo"); const QString QZSettings:: echelon_watttable = QStringLiteral("echelon_watttable"); const QString QZSettings:: default_echelon_watttable = QStringLiteral("Echelon"); const QString QZSettings:: proform_wheel_ratio = QStringLiteral("proform_wheel_ratio"); @@ -432,7 +433,7 @@ const QString QZSettings:: default_horizon_treadmill_profile_user5 = QStringLite const QString QZSettings:: nordictrack_gx_2_7 = QStringLiteral("nordictrack_gx_2_7"); const QString QZSettings:: rolling_resistance = QStringLiteral("rolling_resistance"); -const uint32_t allSettingsCount = 367; +const uint32_t allSettingsCount = 368; QVariant allSettings[allSettingsCount][2] = { { QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles }, { QZSettings::bluetooth_no_reconnection, QZSettings::default_bluetooth_no_reconnection }, @@ -598,6 +599,7 @@ QVariant allSettings[allSettingsCount][2] = { { QZSettings::domyos_bike_display_calories, QZSettings::default_domyos_bike_display_calories }, { QZSettings::domyos_elliptical_speed_ratio, QZSettings::default_domyos_elliptical_speed_ratio }, { QZSettings::eslinker_cadenza, QZSettings::default_eslinker_cadenza }, + { QZSettings::eslinker_ypoo, QZSettings::default_eslinker_ypoo }, { QZSettings::echelon_watttable, QZSettings::default_echelon_watttable }, { QZSettings::proform_wheel_ratio, QZSettings::default_proform_wheel_ratio }, { QZSettings::proform_tour_de_france_clc, QZSettings::default_proform_tour_de_france_clc }, diff --git a/src/qzsettings.h b/src/qzsettings.h index 03c5113a1..2a8373826 100644 --- a/src/qzsettings.h +++ b/src/qzsettings.h @@ -626,6 +626,8 @@ class QZSettings { static const QString eslinker_cadenza; static constexpr bool default_eslinker_cadenza = true; + static const QString eslinker_ypoo; + static constexpr bool default_eslinker_ypoo = false; /** *@brief Choose between the standard and MGARCEA watt table. */ diff --git a/src/settings.qml b/src/settings.qml index 57ad4204a..f2a009036 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -172,6 +172,7 @@ import Qt.labs.settings 1.0 property real domyos_elliptical_speed_ratio: 1.0 property bool eslinker_cadenza: true + property bool eslinker_ypoo: false property string echelon_watttable: "Echelon" @@ -5091,7 +5092,6 @@ import Qt.labs.settings 1.0 textColor: Material.color(Material.Yellow) color: Material.backgroundColor accordionContent: ColumnLayout { - spacing: 0 SwitchDelegate { id: eslinkerTreadmillCadenzaDelegate text: qsTr("Cadenza Treadmill (Bodytone)") @@ -5106,6 +5106,20 @@ import Qt.labs.settings 1.0 Layout.fillWidth: true onClicked: settings.eslinker_cadenza = checked } + SwitchDelegate { + id: eslinkerTreadmillYpooDelegate + text: qsTr("YPOO Mini Change") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.eslinker_ypoo + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.eslinker_ypoo = checked + } } } From 0d7a54c9bd4363a9fde1cb1f4714557a64e65a47 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 10 Oct 2022 16:26:50 +0200 Subject: [PATCH 095/255] GPX Issues on Treadmill #973 --- src/homeform.cpp | 88 ++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/homeform.cpp b/src/homeform.cpp index 00bc9c824..08e4ac704 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -647,56 +647,56 @@ void homeform::trainProgramSignals() { &bluetoothdevice::workoutEventStateChanged); disconnect(trainProgram, &trainprogram::changeTimestamp, this, &homeform::changeTimestamp); - Q_ASSERT(connect(trainProgram, &trainprogram::start, bluetoothManager->device(), &bluetoothdevice::start)); - Q_ASSERT(connect(trainProgram, &trainprogram::stop, bluetoothManager->device(), &bluetoothdevice::stop)); - Q_ASSERT(connect(trainProgram, &trainprogram::lap, this, &homeform::Lap)); + connect(trainProgram, &trainprogram::start, bluetoothManager->device(), &bluetoothdevice::start); + connect(trainProgram, &trainprogram::stop, bluetoothManager->device(), &bluetoothdevice::stop); + connect(trainProgram, &trainprogram::lap, this, &homeform::Lap); if (bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) { - Q_ASSERT(connect(trainProgram, &trainprogram::changeSpeed, ((treadmill *)bluetoothManager->device()), - &treadmill::changeSpeed)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeFanSpeed, ((treadmill *)bluetoothManager->device()), - &treadmill::changeFanSpeed)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeInclination, ((treadmill *)bluetoothManager->device()), - &treadmill::changeInclination)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeSpeedAndInclination, - ((treadmill *)bluetoothManager->device()), &treadmill::changeSpeedAndInclination)); - Q_ASSERT(connect(((treadmill *)bluetoothManager->device()), &treadmill::tapeStarted, trainProgram, - &trainprogram::onTapeStarted)); + connect(trainProgram, &trainprogram::changeSpeed, ((treadmill *)bluetoothManager->device()), + &treadmill::changeSpeed); + connect(trainProgram, &trainprogram::changeFanSpeed, ((treadmill *)bluetoothManager->device()), + &treadmill::changeFanSpeed); + connect(trainProgram, &trainprogram::changeInclination, ((treadmill *)bluetoothManager->device()), + &treadmill::changeInclination); + connect(trainProgram, &trainprogram::changeSpeedAndInclination, + ((treadmill *)bluetoothManager->device()), &treadmill::changeSpeedAndInclination); + connect(((treadmill *)bluetoothManager->device()), &treadmill::tapeStarted, trainProgram, + &trainprogram::onTapeStarted); } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { - Q_ASSERT(connect(trainProgram, &trainprogram::changeCadence, ((bike *)bluetoothManager->device()), - &bike::changeCadence)); - Q_ASSERT(connect(trainProgram, &trainprogram::changePower, ((bike *)bluetoothManager->device()), - &bike::changePower)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeInclination, ((bike *)bluetoothManager->device()), - &bike::changeInclination)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeResistance, ((bike *)bluetoothManager->device()), - &bike::changeResistance)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeRequestedPelotonResistance, - ((bike *)bluetoothManager->device()), &bike::changeRequestedPelotonResistance)); - Q_ASSERT(connect(((bike *)bluetoothManager->device()), &bike::bikeStarted, trainProgram, - &trainprogram::onTapeStarted)); + connect(trainProgram, &trainprogram::changeCadence, ((bike *)bluetoothManager->device()), + &bike::changeCadence); + connect(trainProgram, &trainprogram::changePower, ((bike *)bluetoothManager->device()), + &bike::changePower); + connect(trainProgram, &trainprogram::changeInclination, ((bike *)bluetoothManager->device()), + &bike::changeInclination); + connect(trainProgram, &trainprogram::changeResistance, ((bike *)bluetoothManager->device()), + &bike::changeResistance); + connect(trainProgram, &trainprogram::changeRequestedPelotonResistance, + ((bike *)bluetoothManager->device()), &bike::changeRequestedPelotonResistance); + connect(((bike *)bluetoothManager->device()), &bike::bikeStarted, trainProgram, + &trainprogram::onTapeStarted); } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::ELLIPTICAL) { - Q_ASSERT(connect(trainProgram, &trainprogram::changeCadence, ((elliptical *)bluetoothManager->device()), - &elliptical::changeCadence)); - Q_ASSERT(connect(trainProgram, &trainprogram::changePower, ((elliptical *)bluetoothManager->device()), - &elliptical::changePower)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeInclination, ((elliptical *)bluetoothManager->device()), - &elliptical::changeInclination)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeResistance, ((elliptical *)bluetoothManager->device()), - &elliptical::changeResistance)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeRequestedPelotonResistance, + connect(trainProgram, &trainprogram::changeCadence, ((elliptical *)bluetoothManager->device()), + &elliptical::changeCadence); + connect(trainProgram, &trainprogram::changePower, ((elliptical *)bluetoothManager->device()), + &elliptical::changePower); + connect(trainProgram, &trainprogram::changeInclination, ((elliptical *)bluetoothManager->device()), + &elliptical::changeInclination); + connect(trainProgram, &trainprogram::changeResistance, ((elliptical *)bluetoothManager->device()), + &elliptical::changeResistance); + connect(trainProgram, &trainprogram::changeRequestedPelotonResistance, ((elliptical *)bluetoothManager->device()), - &elliptical::changeRequestedPelotonResistance)); + &elliptical::changeRequestedPelotonResistance); } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::ROWING) { - Q_ASSERT(connect(trainProgram, &trainprogram::changePower, ((rower *)bluetoothManager->device()), - &rower::changePower)); + connect(trainProgram, &trainprogram::changePower, ((rower *)bluetoothManager->device()), + &rower::changePower); } - Q_ASSERT(connect(trainProgram, &trainprogram::changeNextInclination300Meters, bluetoothManager->device(), - &bluetoothdevice::changeNextInclination300Meters)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeGeoPosition, bluetoothManager->device(), - &bluetoothdevice::changeGeoPosition)); - Q_ASSERT(connect(trainProgram, &trainprogram::changeTimestamp, this, &homeform::changeTimestamp)); - Q_ASSERT(connect(this, &homeform::workoutEventStateChanged, bluetoothManager->device(), - &bluetoothdevice::workoutEventStateChanged)); + connect(trainProgram, &trainprogram::changeNextInclination300Meters, bluetoothManager->device(), + &bluetoothdevice::changeNextInclination300Meters); + connect(trainProgram, &trainprogram::changeGeoPosition, bluetoothManager->device(), + &bluetoothdevice::changeGeoPosition); + connect(trainProgram, &trainprogram::changeTimestamp, this, &homeform::changeTimestamp); + connect(this, &homeform::workoutEventStateChanged, bluetoothManager->device(), + &bluetoothdevice::workoutEventStateChanged); qDebug() << QStringLiteral("trainProgram associated to a device"); } else { From 9a64874450ad7a9fc2c108cd046d1b23536dbe6f Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 10 Oct 2022 20:17:11 +0200 Subject: [PATCH 096/255] fixing build error on iOS --- src/eslinkertreadmill.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/eslinkertreadmill.cpp b/src/eslinkertreadmill.cpp index cb3eb91ca..e84f8260a 100644 --- a/src/eslinkertreadmill.cpp +++ b/src/eslinkertreadmill.cpp @@ -379,8 +379,8 @@ void eslinkertreadmill::characteristicChanged(const QLowEnergyCharacteristic &ch double eslinkertreadmill::GetSpeedFromPacket(const QByteArray &packet) { uint8_t convertedData = (uint8_t)packet.at(14); double data = (double)convertedData / 10.0f; - if (treadmill_type == YPOO_MINI_CHANGE && data < 1.0d) { - data = 0.0d; + if (treadmill_type == YPOO_MINI_CHANGE && data < 1.0) { + data = 0.0; } return data; } @@ -405,7 +405,7 @@ double eslinkertreadmill::GetDistanceFromPacket(const QByteArray &packet) { } double eslinkertreadmill::GetInclinationFromPacket(const QByteArray &packet) { - double data = 0.0d; + double data = 0.0; if (treadmill_type != YPOO_MINI_CHANGE) { uint16_t convertedData = packet.at(11); data = convertedData; From 8fc945f76d405dcee027570262325ba457f7b67d Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 10 Oct 2022 20:31:02 +0200 Subject: [PATCH 097/255] fixin avg inclination for treadmill --- src/horizontreadmill.cpp | 6 ++++-- src/trainprogram.cpp | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/horizontreadmill.cpp b/src/horizontreadmill.cpp index 050f11ad9..f708bc946 100644 --- a/src/horizontreadmill.cpp +++ b/src/horizontreadmill.cpp @@ -779,8 +779,10 @@ void horizontreadmill::update() { qDebug() << "requestInclination=" << requestInclination; if (requestInclination < 0) requestInclination = 0; - // the treadmill accepts only .5 steps - requestInclination = floor(requestInclination) + 0.5; + } else { + // the treadmill accepts only .5 steps + requestInclination = floor(requestInclination) + 0.5; + } if (requestInclination != currentInclination().value() && requestInclination >= 0 && requestInclination <= 15) { emit debug(QStringLiteral("writing incline ") + QString::number(requestInclination)); diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index d76f4d246..4d4aaacee 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -138,6 +138,7 @@ double trainprogram::avgInclinationNext100Meters() { double km = 0; double avg = 0; int sum = 0; + double startingAltitude = rows.at(currentStep).altitude; while (1) { if (c < rows.length()) { @@ -148,7 +149,7 @@ double trainprogram::avgInclinationNext100Meters() { km += (rows.at(c).distance - currentStepDistance); else km += (rows.at(c).distance); - avg += rows.at(c).inclination; + avg += (rows.at(c).altitude - startingAltitude); sum++; } else { From 64466da2686b688c2e9a87dbae0fd300eed94bb9 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 10 Oct 2022 20:45:56 +0200 Subject: [PATCH 098/255] fix typo --- src/horizontreadmill.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/horizontreadmill.cpp b/src/horizontreadmill.cpp index f708bc946..271e122c6 100644 --- a/src/horizontreadmill.cpp +++ b/src/horizontreadmill.cpp @@ -779,7 +779,7 @@ void horizontreadmill::update() { qDebug() << "requestInclination=" << requestInclination; if (requestInclination < 0) requestInclination = 0; - } else { + else { // the treadmill accepts only .5 steps requestInclination = floor(requestInclination) + 0.5; } From 722447a21e70c60ffae63e1f26a7654e3ddf8fe1 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 11 Oct 2022 16:59:15 +0200 Subject: [PATCH 099/255] GPX Issues on Treadmill #973 speed on treadmill fixed --- src/gpx.cpp | 13 +- src/homeform.cpp | 414 ++++++++++++++++++++++++++++--------------- src/trainprogram.cpp | 67 ++++--- src/trainprogram.h | 2 +- 4 files changed, 328 insertions(+), 168 deletions(-) diff --git a/src/gpx.cpp b/src/gpx.cpp index 6ad4083b0..8aa87f4f7 100644 --- a/src/gpx.cpp +++ b/src/gpx.cpp @@ -9,7 +9,8 @@ gpx::gpx(QObject *parent) : QObject(parent) {} QList gpx::open(const QString &gpx) { QSettings settings; - bool treadmill_force_speed = settings.value(QZSettings::treadmill_force_speed, QZSettings::default_treadmill_force_speed).toBool(); + bool treadmill_force_speed = + settings.value(QZSettings::treadmill_force_speed, QZSettings::default_treadmill_force_speed).toBool(); QFile input(gpx); input.open(QIODevice::ReadOnly); QDomDocument doc; @@ -46,7 +47,6 @@ QList gpx::open(const QString &gpx) { this->points.append(g); } - const uint8_t secondsInclination = 60; QList inclinationList; if (this->points.isEmpty()) { @@ -58,17 +58,18 @@ QList gpx::open(const QString &gpx) { if (treadmill_force_speed) { for (int32_t i = 1; i < this->points.count(); i++) { qint64 dT = qAbs(pP.time.secsTo(this->points.at(i).time)); - if (dT < secondsInclination) { - continue; - } double distance = this->points.at(i).p.distanceTo(pP.p); double elevation = this->points.at(i).p.altitude() - pP.p.altitude(); + if (distance == 0) { + continue; + } + pP = this->points[i]; gpx_altitude_point_for_treadmill g; - g.seconds = dT; + g.seconds = this->points.constFirst().time.secsTo(pP.time); g.distance = distance / 1000.0; g.speed = (distance / 1000.0) * (3600 / dT); g.inclination = (elevation / distance) * 100; diff --git a/src/homeform.cpp b/src/homeform.cpp index 08e4ac704..8b0b72fe3 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -652,51 +652,49 @@ void homeform::trainProgramSignals() { connect(trainProgram, &trainprogram::lap, this, &homeform::Lap); if (bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) { connect(trainProgram, &trainprogram::changeSpeed, ((treadmill *)bluetoothManager->device()), - &treadmill::changeSpeed); + &treadmill::changeSpeed); connect(trainProgram, &trainprogram::changeFanSpeed, ((treadmill *)bluetoothManager->device()), - &treadmill::changeFanSpeed); + &treadmill::changeFanSpeed); connect(trainProgram, &trainprogram::changeInclination, ((treadmill *)bluetoothManager->device()), - &treadmill::changeInclination); - connect(trainProgram, &trainprogram::changeSpeedAndInclination, - ((treadmill *)bluetoothManager->device()), &treadmill::changeSpeedAndInclination); + &treadmill::changeInclination); + connect(trainProgram, &trainprogram::changeSpeedAndInclination, ((treadmill *)bluetoothManager->device()), + &treadmill::changeSpeedAndInclination); connect(((treadmill *)bluetoothManager->device()), &treadmill::tapeStarted, trainProgram, - &trainprogram::onTapeStarted); + &trainprogram::onTapeStarted); } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { connect(trainProgram, &trainprogram::changeCadence, ((bike *)bluetoothManager->device()), - &bike::changeCadence); - connect(trainProgram, &trainprogram::changePower, ((bike *)bluetoothManager->device()), - &bike::changePower); + &bike::changeCadence); + connect(trainProgram, &trainprogram::changePower, ((bike *)bluetoothManager->device()), &bike::changePower); connect(trainProgram, &trainprogram::changeInclination, ((bike *)bluetoothManager->device()), - &bike::changeInclination); + &bike::changeInclination); connect(trainProgram, &trainprogram::changeResistance, ((bike *)bluetoothManager->device()), - &bike::changeResistance); - connect(trainProgram, &trainprogram::changeRequestedPelotonResistance, - ((bike *)bluetoothManager->device()), &bike::changeRequestedPelotonResistance); + &bike::changeResistance); + connect(trainProgram, &trainprogram::changeRequestedPelotonResistance, ((bike *)bluetoothManager->device()), + &bike::changeRequestedPelotonResistance); connect(((bike *)bluetoothManager->device()), &bike::bikeStarted, trainProgram, - &trainprogram::onTapeStarted); + &trainprogram::onTapeStarted); } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::ELLIPTICAL) { connect(trainProgram, &trainprogram::changeCadence, ((elliptical *)bluetoothManager->device()), - &elliptical::changeCadence); + &elliptical::changeCadence); connect(trainProgram, &trainprogram::changePower, ((elliptical *)bluetoothManager->device()), - &elliptical::changePower); + &elliptical::changePower); connect(trainProgram, &trainprogram::changeInclination, ((elliptical *)bluetoothManager->device()), - &elliptical::changeInclination); + &elliptical::changeInclination); connect(trainProgram, &trainprogram::changeResistance, ((elliptical *)bluetoothManager->device()), - &elliptical::changeResistance); + &elliptical::changeResistance); connect(trainProgram, &trainprogram::changeRequestedPelotonResistance, - ((elliptical *)bluetoothManager->device()), - &elliptical::changeRequestedPelotonResistance); + ((elliptical *)bluetoothManager->device()), &elliptical::changeRequestedPelotonResistance); } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::ROWING) { connect(trainProgram, &trainprogram::changePower, ((rower *)bluetoothManager->device()), - &rower::changePower); + &rower::changePower); } connect(trainProgram, &trainprogram::changeNextInclination300Meters, bluetoothManager->device(), - &bluetoothdevice::changeNextInclination300Meters); + &bluetoothdevice::changeNextInclination300Meters); connect(trainProgram, &trainprogram::changeGeoPosition, bluetoothManager->device(), - &bluetoothdevice::changeGeoPosition); + &bluetoothdevice::changeGeoPosition); connect(trainProgram, &trainprogram::changeTimestamp, this, &homeform::changeTimestamp); connect(this, &homeform::workoutEventStateChanged, bluetoothManager->device(), - &bluetoothdevice::workoutEventStateChanged); + &bluetoothdevice::workoutEventStateChanged); qDebug() << QStringLiteral("trainProgram associated to a device"); } else { @@ -734,7 +732,8 @@ void homeform::ftmsAccessoryConnected(smartspin2k *d) { void homeform::sortTiles() { QSettings settings; - bool pelotoncadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); + bool pelotoncadence = + settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); if (!bluetoothManager || !bluetoothManager->device()) return; @@ -1627,7 +1626,8 @@ void homeform::deviceConnected(QBluetoothDeviceInfo b) { if (settings.value(QZSettings::pause_on_start, QZSettings::default_pause_on_start).toBool() && bluetoothManager->device()->deviceType() != bluetoothdevice::TREADMILL) { Start(); - } else if (settings.value(QZSettings::pause_on_start_treadmill, QZSettings::default_pause_on_start_treadmill).toBool() && + } else if (settings.value(QZSettings::pause_on_start_treadmill, QZSettings::default_pause_on_start_treadmill) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) { Start_inner(false); // because if you sent the start command to a treadmill it could start the tape } @@ -1679,7 +1679,8 @@ void homeform::Plus(const QString &name) { if (requestedspeed != -1) speed = requestedspeed; double minStepSpeed = ((treadmill *)bluetoothManager->device())->minStepSpeed(); - double step = settings.value(QZSettings::treadmill_step_speed, QZSettings::default_treadmill_step_speed).toDouble(); + double step = + settings.value(QZSettings::treadmill_step_speed, QZSettings::default_treadmill_step_speed).toDouble(); if (!miles) step = ((double)qRound(step * 10.0)) / 10.0; if (step > minStepSpeed) @@ -1695,13 +1696,16 @@ void homeform::Plus(const QString &name) { ((treadmill *)bluetoothManager->device())->changeSpeed(speed); } } else if (name.contains(QStringLiteral("external_inclination"))) { - double elite_rizer_gain = settings.value(QZSettings::elite_rizer_gain, QZSettings::default_elite_rizer_gain).toDouble(); + double elite_rizer_gain = + settings.value(QZSettings::elite_rizer_gain, QZSettings::default_elite_rizer_gain).toDouble(); elite_rizer_gain = elite_rizer_gain + 0.1; settings.setValue(QZSettings::elite_rizer_gain, elite_rizer_gain); } else if (name.contains(QStringLiteral("inclination"))) { if (bluetoothManager->device()) { if (bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) { - double step = settings.value(QZSettings::treadmill_step_incline, QZSettings::default_treadmill_step_incline).toDouble(); + double step = + settings.value(QZSettings::treadmill_step_incline, QZSettings::default_treadmill_step_incline) + .toDouble(); if (step < ((treadmill *)bluetoothManager->device())->minStepInclination()) step = ((treadmill *)bluetoothManager->device())->minStepInclination(); double perc = ((treadmill *)bluetoothManager->device())->currentInclination().value() + step; @@ -1719,10 +1723,12 @@ void homeform::Plus(const QString &name) { if (bluetoothManager->device()) { QSettings settings; QString zoneS = - settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone).toString(); - uint8_t zone = settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone) - .toString() - .toUInt(); + settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone) + .toString(); + uint8_t zone = + settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone) + .toString() + .toUInt(); if (!zoneS.compare(QStringLiteral("Disabled"))) zone = 0; @@ -1778,12 +1784,14 @@ void homeform::Plus(const QString &name) { } else if (name.contains(QStringLiteral("fan"))) { QSettings settings; if (bluetoothManager->device()) { - if (settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable).toBool() && + if (settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable) + .toBool() && settings.value(QZSettings::fitmetria_fanfit_mode, QZSettings::default_fitmetria_fanfit_mode) .toString() .compare(QStringLiteral("Manual"))) { fanOverride += 10; - } else if (settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable).toBool()) { + } else if (settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable) + .toBool()) { bluetoothManager->device()->changeFanSpeed(bluetoothManager->device()->fanSpeed() + 10); } else bluetoothManager->device()->changeFanSpeed(bluetoothManager->device()->fanSpeed() + 1); @@ -1821,7 +1829,8 @@ void homeform::Minus(const QString &name) { if (requestedspeed != -1) speed = requestedspeed; double minStepSpeed = ((treadmill *)bluetoothManager->device())->minStepSpeed(); - double step = settings.value(QZSettings::treadmill_step_speed, QZSettings::default_treadmill_step_speed).toDouble(); + double step = settings.value(QZSettings::treadmill_step_speed, QZSettings::default_treadmill_step_speed) + .toDouble(); if (!miles) step = ((double)qRound(step * 10.0)) / 10.0; if (step > minStepSpeed) @@ -1837,14 +1846,17 @@ void homeform::Minus(const QString &name) { } } } else if (name.contains(QStringLiteral("external_inclination"))) { - double elite_rizer_gain = settings.value(QZSettings::elite_rizer_gain, QZSettings::default_elite_rizer_gain).toDouble(); + double elite_rizer_gain = + settings.value(QZSettings::elite_rizer_gain, QZSettings::default_elite_rizer_gain).toDouble(); if (elite_rizer_gain) elite_rizer_gain = elite_rizer_gain - 0.1; settings.setValue(QZSettings::elite_rizer_gain, elite_rizer_gain); } else if (name.contains(QStringLiteral("inclination"))) { if (bluetoothManager->device()) { if (bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) { - double step = settings.value(QZSettings::treadmill_step_incline, QZSettings::default_treadmill_step_incline).toDouble(); + double step = + settings.value(QZSettings::treadmill_step_incline, QZSettings::default_treadmill_step_incline) + .toDouble(); if (step < ((treadmill *)bluetoothManager->device())->minStepInclination()) step = ((treadmill *)bluetoothManager->device())->minStepInclination(); double perc = ((treadmill *)bluetoothManager->device())->currentInclination().value() - step; @@ -1861,9 +1873,10 @@ void homeform::Minus(const QString &name) { } else if (name.contains(QStringLiteral("pid_hr"))) { if (bluetoothManager->device()) { QSettings settings; - uint8_t zone = settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone) - .toString() - .toUInt(); + uint8_t zone = + settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone) + .toString() + .toUInt(); if (zone > 1) { zone--; settings.setValue(QZSettings::treadmill_pid_heart_zone, QString::number(zone)); @@ -1918,12 +1931,14 @@ void homeform::Minus(const QString &name) { if (bluetoothManager->device()) { QSettings settings; - if (settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable).toBool() && + if (settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable) + .toBool() && settings.value(QZSettings::fitmetria_fanfit_mode, QZSettings::default_fitmetria_fanfit_mode) .toString() .compare(QStringLiteral("Manual"))) { fanOverride -= 10; - } else if (settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable).toBool()) { + } else if (settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable) + .toBool()) { bluetoothManager->device()->changeFanSpeed(bluetoothManager->device()->fanSpeed() - 10); } else bluetoothManager->device()->changeFanSpeed(bluetoothManager->device()->fanSpeed() - 1); @@ -2141,7 +2156,8 @@ void homeform::update() { qDebug() << "!!!!QSETTINGS ERROR!" << settings.status(); } - if ((paused || stopped) && settings.value(QZSettings::top_bar_enabled, QZSettings::default_top_bar_enabled).toBool()) { + if ((paused || stopped) && + settings.value(QZSettings::top_bar_enabled, QZSettings::default_top_bar_enabled).toBool()) { emit stopIconChanged(stopIcon()); emit stopTextChanged(stopText()); @@ -2173,9 +2189,12 @@ void homeform::update() { double meter_feet_conversion = 1.0; bool power5s = settings.value(QZSettings::power_avg_5s, QZSettings::default_power_avg_5s).toBool(); uint8_t treadmill_pid_heart_zone = - settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone).toString().toUInt(); + settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone) + .toString() + .toUInt(); QString treadmill_pid_heart_zone_string = - settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone).toString(); + settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone) + .toString(); if (!treadmill_pid_heart_zone_string.compare(QStringLiteral("Disabled"))) treadmill_pid_heart_zone = 0; @@ -2439,7 +2458,8 @@ void homeform::update() { } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { - bool pelotoncadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); + bool pelotoncadence = + settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); if (!pelotoncadence) { inclination = ((bike *)bluetoothManager->device())->currentInclination().value(); @@ -2453,7 +2473,8 @@ void homeform::update() { if (bluetoothManager->externalInclination()) extIncline->setValue( QString::number(bluetoothManager->externalInclination()->currentInclination().value(), 'f', 1)); - double elite_rizer_gain = settings.value(QZSettings::elite_rizer_gain, QZSettings::default_elite_rizer_gain).toDouble(); + double elite_rizer_gain = + settings.value(QZSettings::elite_rizer_gain, QZSettings::default_elite_rizer_gain).toDouble(); extIncline->setSecondLine(QStringLiteral("Gain: ") + QString::number(elite_rizer_gain, 'f', 1)); odometer->setValue(QString::number(bluetoothManager->device()->odometer() * unit_conversion, 'f', 2)); resistance = ((bike *)bluetoothManager->device())->currentResistance().value(); @@ -2482,10 +2503,13 @@ void homeform::update() { QString::number(((bike *)bluetoothManager->device())->pelotonResistance().max(), 'f', 0)); this->target_resistance->setSecondLine( QString::number(bluetoothManager->device()->difficult() * 100.0, 'f', 0) + QStringLiteral("% @0%=") + - QString::number(bluetoothManager->device()->difficult() * - settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f).toDouble() * - settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset).toDouble(), - 'f', 0)); + QString::number( + bluetoothManager->device()->difficult() * + settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f) + .toDouble() * + settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset) + .toDouble(), + 'f', 0)); elevation->setValue( QString::number(((bike *)bluetoothManager->device())->elevationGain().value() * meter_feet_conversion, @@ -2550,10 +2574,13 @@ void homeform::update() { QString::number(((rower *)bluetoothManager->device())->pelotonResistance().max(), 'f', 0)); this->target_resistance->setSecondLine( QString::number(bluetoothManager->device()->difficult() * 100.0, 'f', 0) + QStringLiteral("% @0%=") + - QString::number(bluetoothManager->device()->difficult() * - settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f).toDouble() * - settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset).toDouble(), - 'f', 0)); + QString::number( + bluetoothManager->device()->difficult() * + settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f) + .toDouble() * + settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset) + .toDouble(), + 'f', 0)); this->strokesLength->setSecondLine( QStringLiteral("AVG: ") + QString::number(((rower *)bluetoothManager->device())->currentStrokesLength().average(), 'f', 1) + @@ -2599,10 +2626,13 @@ void homeform::update() { QString::number(((elliptical *)bluetoothManager->device())->pelotonResistance().max(), 'f', 0)); this->target_resistance->setSecondLine( QString::number(bluetoothManager->device()->difficult() * 100.0, 'f', 0) + QStringLiteral("% @0%=") + - QString::number(bluetoothManager->device()->difficult() * - settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f).toDouble() * - settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset).toDouble(), - 'f', 0)); + QString::number( + bluetoothManager->device()->difficult() * + settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f) + .toDouble() * + settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset) + .toDouble(), + 'f', 0)); inclination = ((elliptical *)bluetoothManager->device())->currentInclination().value(); this->inclination->setValue(QString::number(inclination, 'f', 1)); this->inclination->setSecondLine( @@ -2639,7 +2669,10 @@ void homeform::update() { this->target_peloton_resistance->setSecondLine(QLatin1String("")); } - if (settings.value(QZSettings::tile_peloton_resistance_color_enabled, QZSettings::default_tile_peloton_resistance_color_enabled).toBool()) { + if (settings + .value(QZSettings::tile_peloton_resistance_color_enabled, + QZSettings::default_tile_peloton_resistance_color_enabled) + .toBool()) { if (lower_requested_peloton_resistance == -1) { this->peloton_resistance->setValueFontColor(QStringLiteral("white")); } else if (((int8_t)peloton_resistance) < lower_requested_peloton_resistance) { @@ -2660,7 +2693,8 @@ void homeform::update() { this->target_cadence->setSecondLine(QLatin1String("")); } - if (settings.value(QZSettings::tile_cadence_color_enabled, QZSettings::default_tile_cadence_color_enabled).toBool()) { + if (settings.value(QZSettings::tile_cadence_color_enabled, QZSettings::default_tile_cadence_color_enabled) + .toBool()) { if (lower_cadence == -1) { this->cadence->setValueFontColor(QStringLiteral("white")); } else if (cadence < lower_cadence) { @@ -2849,36 +2883,48 @@ void homeform::update() { double maxHeartRate = heartRateMax(); double percHeartRate = (bluetoothManager->device()->currentHeart().value() * 100) / maxHeartRate; - if (percHeartRate < settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble()) { + if (percHeartRate < + settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble()) { currentHRZone = 1; - currentHRZone += (percHeartRate / settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble()); + currentHRZone += + (percHeartRate / + settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble()); if (currentHRZone >= 2) { // double precision could cause unwanted approximation currentHRZone = 1.9999; } heart->setValueFontColor(QStringLiteral("lightsteelblue")); - } else if (percHeartRate < settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble()) { + } else if (percHeartRate < + settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble()) { currentHRZone = 2; - currentHRZone += ((percHeartRate - settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble()) / - (settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble() - - settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble())); + currentHRZone += + ((percHeartRate - + settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble()) / + (settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble() - + settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble())); if (currentHRZone >= 3) { // double precision could cause unwanted approximation currentHRZone = 2.9999; } heart->setValueFontColor(QStringLiteral("green")); - } else if (percHeartRate < settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble()) { + } else if (percHeartRate < + settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble()) { currentHRZone = 3; - currentHRZone += ((percHeartRate - settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble()) / - (settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble() - - settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble())); + currentHRZone += + ((percHeartRate - + settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble()) / + (settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble() - + settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble())); if (currentHRZone >= 4) { // double precision could cause unwanted approximation currentHRZone = 3.9999; } heart->setValueFontColor(QStringLiteral("yellow")); - } else if (percHeartRate < settings.value(QZSettings::heart_rate_zone4, QZSettings::default_heart_rate_zone4).toDouble()) { + } else if (percHeartRate < + settings.value(QZSettings::heart_rate_zone4, QZSettings::default_heart_rate_zone4).toDouble()) { currentHRZone = 4; - currentHRZone += ((percHeartRate - settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble()) / - (settings.value(QZSettings::heart_rate_zone4, QZSettings::default_heart_rate_zone4).toDouble() - - settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble())); + currentHRZone += + ((percHeartRate - + settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble()) / + (settings.value(QZSettings::heart_rate_zone4, QZSettings::default_heart_rate_zone4).toDouble() - + settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble())); if (currentHRZone >= 5) { // double precision could cause unwanted approximation currentHRZone = 4.9999; } @@ -2912,7 +2958,8 @@ void homeform::update() { */ #ifdef Q_OS_ANDROID - if (settings.value(QZSettings::ant_cadence, QZSettings::default_ant_cadence).toBool() && KeepAwakeHelper::antObject(false)) { + if (settings.value(QZSettings::ant_cadence, QZSettings::default_ant_cadence).toBool() && + KeepAwakeHelper::antObject(false)) { KeepAwakeHelper::antObject(false)->callMethod( "setCadenceSpeedPower", "(FII)V", (float)bluetoothManager->device()->currentSpeed().value(), (int)watts, (int)cadence); @@ -2927,61 +2974,118 @@ void homeform::update() { uint32_t seconds = bluetoothManager->device()->elapsedTime().second() + (bluetoothManager->device()->elapsedTime().minute() * 60) + (bluetoothManager->device()->elapsedTime().hour() * 3600); - if ((seconds / 60) < settings.value(QZSettings::trainprogram_total, QZSettings::default_trainprogram_total).toUInt()) { + if ((seconds / 60) < + settings.value(QZSettings::trainprogram_total, QZSettings::default_trainprogram_total).toUInt()) { qDebug() << QStringLiteral("trainprogram random seconds ") + QString::number(seconds) + QStringLiteral(" last_change ") + last_seconds + QStringLiteral(" period ") + - settings.value(QZSettings::trainprogram_period_seconds, QZSettings::default_trainprogram_period_seconds).toUInt(); + settings + .value(QZSettings::trainprogram_period_seconds, + QZSettings::default_trainprogram_period_seconds) + .toUInt(); if (last_seconds == 0 || - ((seconds - last_seconds) >= - settings.value(QZSettings::trainprogram_period_seconds, QZSettings::default_trainprogram_period_seconds).toUInt())) { + ((seconds - last_seconds) >= settings + .value(QZSettings::trainprogram_period_seconds, + QZSettings::default_trainprogram_period_seconds) + .toUInt())) { bool done = false; if (bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL && ((treadmill *)bluetoothManager->device())->currentSpeed().value() > 0.0f) { - double speed = settings.value(QZSettings::trainprogram_speed_min, QZSettings::default_trainprogram_speed_min).toUInt(); - double incline = settings.value(QZSettings::trainprogram_incline_min, QZSettings::default_trainprogram_incline_min).toUInt(); + double speed = settings + .value(QZSettings::trainprogram_speed_min, + QZSettings::default_trainprogram_speed_min) + .toUInt(); + double incline = settings + .value(QZSettings::trainprogram_incline_min, + QZSettings::default_trainprogram_incline_min) + .toUInt(); if (!speed) { speed = 1.0; } - if (settings.value(QZSettings::trainprogram_speed_min, QZSettings::default_trainprogram_speed_min).toUInt() != 0 && - settings.value(QZSettings::trainprogram_speed_min, QZSettings::default_trainprogram_speed_min).toUInt() < - settings.value(QZSettings::trainprogram_speed_max, QZSettings::default_trainprogram_speed_max).toUInt()) { - speed = - (double)r.bounded( - settings.value(QZSettings::trainprogram_speed_min, QZSettings::default_trainprogram_speed_min).toUInt() * 10, - settings.value(QZSettings::trainprogram_speed_max, QZSettings::default_trainprogram_speed_max).toUInt() * 10) / - 10.0; + if (settings.value(QZSettings::trainprogram_speed_min, + QZSettings::default_trainprogram_speed_min) + .toUInt() != 0 && + settings.value(QZSettings::trainprogram_speed_min, + QZSettings::default_trainprogram_speed_min) + .toUInt() < settings + .value(QZSettings::trainprogram_speed_max, + QZSettings::default_trainprogram_speed_max) + .toUInt()) { + speed = (double)r.bounded(settings.value(QZSettings::trainprogram_speed_min, + QZSettings::default_trainprogram_speed_min) + .toUInt() * + 10, + settings.value(QZSettings::trainprogram_speed_max, + QZSettings::default_trainprogram_speed_max) + .toUInt() * + 10) / + 10.0; } - if (settings.value(QZSettings::trainprogram_incline_min, QZSettings::default_trainprogram_incline_min).toUInt() < - settings.value(QZSettings::trainprogram_incline_max, QZSettings::default_trainprogram_incline_max).toUInt()) { - incline = - (double)r.bounded( - settings.value(QZSettings::trainprogram_incline_min, QZSettings::default_trainprogram_incline_min).toUInt() * 10, - settings.value(QZSettings::trainprogram_incline_max, QZSettings::default_trainprogram_incline_max).toUInt() * 10) / - 10.0; + if (settings + .value(QZSettings::trainprogram_incline_min, + QZSettings::default_trainprogram_incline_min) + .toUInt() < settings + .value(QZSettings::trainprogram_incline_max, + QZSettings::default_trainprogram_incline_max) + .toUInt()) { + incline = (double)r.bounded(settings.value(QZSettings::trainprogram_incline_min, + QZSettings::default_trainprogram_incline_min) + .toUInt() * + 10, + settings.value(QZSettings::trainprogram_incline_max, + QZSettings::default_trainprogram_incline_max) + .toUInt() * + 10) / + 10.0; } ((treadmill *)bluetoothManager->device())->changeSpeedAndInclination(speed, incline); done = true; } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { - double resistance = - settings.value(QZSettings::trainprogram_resistance_min, QZSettings::default_trainprogram_resistance_min).toUInt(); - if (settings.value(QZSettings::trainprogram_resistance_min, QZSettings::default_trainprogram_resistance_min).toUInt() < - settings.value(QZSettings::trainprogram_resistance_max, QZSettings::default_trainprogram_resistance_max).toUInt()) { - resistance = (double)r.bounded( - settings.value(QZSettings::trainprogram_resistance_min, QZSettings::default_trainprogram_resistance_min).toUInt(), - settings.value(QZSettings::trainprogram_resistance_max, QZSettings::default_trainprogram_resistance_max).toUInt()); + double resistance = settings + .value(QZSettings::trainprogram_resistance_min, + QZSettings::default_trainprogram_resistance_min) + .toUInt(); + if (settings + .value(QZSettings::trainprogram_resistance_min, + QZSettings::default_trainprogram_resistance_min) + .toUInt() < settings + .value(QZSettings::trainprogram_resistance_max, + QZSettings::default_trainprogram_resistance_max) + .toUInt()) { + resistance = + (double)r.bounded(settings + .value(QZSettings::trainprogram_resistance_min, + QZSettings::default_trainprogram_resistance_min) + .toUInt(), + settings + .value(QZSettings::trainprogram_resistance_max, + QZSettings::default_trainprogram_resistance_max) + .toUInt()); } ((bike *)bluetoothManager->device())->changeResistance(resistance); done = true; } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::ROWING) { - double resistance = - settings.value(QZSettings::trainprogram_resistance_min, QZSettings::default_trainprogram_resistance_min).toUInt(); - if (settings.value(QZSettings::trainprogram_resistance_min, QZSettings::default_trainprogram_resistance_min).toUInt() < - settings.value(QZSettings::trainprogram_resistance_max, QZSettings::default_trainprogram_resistance_max).toUInt()) { - resistance = (double)r.bounded( - settings.value(QZSettings::trainprogram_resistance_min, QZSettings::default_trainprogram_resistance_min).toUInt(), - settings.value(QZSettings::trainprogram_resistance_max, QZSettings::default_trainprogram_resistance_max).toUInt()); + double resistance = settings + .value(QZSettings::trainprogram_resistance_min, + QZSettings::default_trainprogram_resistance_min) + .toUInt(); + if (settings + .value(QZSettings::trainprogram_resistance_min, + QZSettings::default_trainprogram_resistance_min) + .toUInt() < settings + .value(QZSettings::trainprogram_resistance_max, + QZSettings::default_trainprogram_resistance_max) + .toUInt()) { + resistance = + (double)r.bounded(settings + .value(QZSettings::trainprogram_resistance_min, + QZSettings::default_trainprogram_resistance_min) + .toUInt(), + settings + .value(QZSettings::trainprogram_resistance_max, + QZSettings::default_trainprogram_resistance_max) + .toUInt()); } ((rower *)bluetoothManager->device())->changeResistance(resistance); @@ -3033,9 +3137,10 @@ void homeform::update() { last_seconds_pid_heart_zone = seconds; - uint8_t zone = settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone) - .toString() - .toUInt(); + uint8_t zone = + settings.value(QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone) + .toString() + .toUInt(); if (fromTrainProgram) { zone = trainProgram->currentRow().zoneHR; if (trainProgram->currentRow().maxSpeed > 0) { @@ -3148,7 +3253,8 @@ void homeform::update() { if (!stopped && !paused) { if (settings.value(QZSettings::tts_enabled, QZSettings::default_tts_enabled).toBool()) { - if (++tts_summary_count >= settings.value(QZSettings::tts_summary_sec, QZSettings::default_tts_summary_sec).toInt() && + if (++tts_summary_count >= + settings.value(QZSettings::tts_summary_sec, QZSettings::default_tts_summary_sec).toInt() && m_speech.state() == QTextToSpeech::Ready) { tts_summary_count = 0; @@ -3178,7 +3284,8 @@ void homeform::update() { : QString::number( bluetoothManager->device()->currentSpeed().max() * unit_conversion, 'f', 1)) + tr(" miles per hour")); - if (settings.value(QZSettings::tts_act_inclination, QZSettings::default_tts_act_inclination).toBool()) + if (settings.value(QZSettings::tts_act_inclination, QZSettings::default_tts_act_inclination) + .toBool()) s.append(tr(", inclination ") + QString::number(bluetoothManager->device()->currentInclination().value(), 'f', 1)); if (settings.value(QZSettings::tts_act_cadence, QZSettings::default_tts_act_cadence).toBool()) @@ -3187,7 +3294,8 @@ void homeform::update() { if (settings.value(QZSettings::tts_avg_cadence, QZSettings::default_tts_avg_cadence).toBool()) s.append(tr(", Average cadence ") + QString::number(bluetoothManager->device()->currentCadence().average(), 'f', 0)); - if (settings.value(QZSettings::tts_max_cadence, QZSettings::default_tts_max_cadence /* true */).toBool()) + if (settings.value(QZSettings::tts_max_cadence, QZSettings::default_tts_max_cadence /* true */) + .toBool()) s.append(tr(", Max cadence ") + QString::number(bluetoothManager->device()->currentCadence().max())); if (settings.value(QZSettings::tts_act_elevation, QZSettings::default_tts_act_elevation).toBool()) @@ -3253,41 +3361,57 @@ void homeform::update() { s.append(tr(", elapsed ") + QString::number(bluetoothManager->device()->elapsedTime().minute()) + tr(" minutes ") + QString::number(bluetoothManager->device()->elapsedTime().second()) + tr(" seconds")); - if (settings.value(QZSettings::tts_act_peloton_resistance, QZSettings::default_tts_act_peloton_resistance).toBool() && + if (settings + .value(QZSettings::tts_act_peloton_resistance, + QZSettings::default_tts_act_peloton_resistance) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) s.append( tr(", peloton resistance ") + QString::number(((bike *)bluetoothManager->device())->pelotonResistance().value(), 'f', 0)); - if (settings.value(QZSettings::tts_avg_peloton_resistance, QZSettings::default_tts_avg_peloton_resistance).toBool() && + if (settings + .value(QZSettings::tts_avg_peloton_resistance, + QZSettings::default_tts_avg_peloton_resistance) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) s.append(tr(", average peloton resistance ") + QString::number(((bike *)bluetoothManager->device())->pelotonResistance().average(), 'f', 0)); - if (settings.value(QZSettings::tts_max_peloton_resistance, QZSettings::default_tts_max_peloton_resistance).toBool() && + if (settings + .value(QZSettings::tts_max_peloton_resistance, + QZSettings::default_tts_max_peloton_resistance) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) s.append( tr(", max peloton resistance ") + QString::number(((bike *)bluetoothManager->device())->pelotonResistance().max(), 'f', 0)); - if (settings.value(QZSettings::tts_act_target_peloton_resistance, QZSettings::default_tts_act_target_peloton_resistance).toBool() && + if (settings + .value(QZSettings::tts_act_target_peloton_resistance, + QZSettings::default_tts_act_target_peloton_resistance) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) s.append(tr(", target peloton resistance ") + QString::number( ((bike *)bluetoothManager->device())->lastRequestedPelotonResistance().value(), 'f', 0)); - if (settings.value(QZSettings::tts_act_target_cadence, QZSettings::default_tts_act_target_cadence).toBool() && + if (settings.value(QZSettings::tts_act_target_cadence, QZSettings::default_tts_act_target_cadence) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) s.append(tr(", target cadence ") + QString::number(((bike *)bluetoothManager->device())->lastRequestedCadence().value(), 'f', 0)); - if (settings.value(QZSettings::tts_act_target_power, QZSettings::default_tts_act_target_power).toBool() && + if (settings.value(QZSettings::tts_act_target_power, QZSettings::default_tts_act_target_power) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) s.append(tr(", target power ") + QString::number(((bike *)bluetoothManager->device())->lastRequestedPower().value(), 'f', 0)); - if (settings.value(QZSettings::tts_act_target_zone, QZSettings::default_tts_act_target_zone).toBool() && + if (settings.value(QZSettings::tts_act_target_zone, QZSettings::default_tts_act_target_zone) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) s.append(tr(", target zone ") + QString::number(requestedZone, 'f', 1)); - if (settings.value(QZSettings::tts_act_target_speed, QZSettings::default_tts_act_target_speed).toBool() && + if (settings.value(QZSettings::tts_act_target_speed, QZSettings::default_tts_act_target_speed) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) s.append(tr(", target speed ") + (!miles ? QString::number( @@ -3299,7 +3423,8 @@ void homeform::update() { unit_conversion, 'f', 1)) + tr(" miles per hour")); - if (settings.value(QZSettings::tts_act_target_incline, QZSettings::default_tts_act_target_incline).toBool() && + if (settings.value(QZSettings::tts_act_target_incline, QZSettings::default_tts_act_target_incline) + .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) s.append( tr(", target incline ") + @@ -3453,7 +3578,9 @@ void homeform::fit_save_clicked() { lastFitFileSaved = filename; QSettings settings; - if (!settings.value(QZSettings::strava_accesstoken, QZSettings::default_strava_accesstoken).toString().isEmpty()) { + if (!settings.value(QZSettings::strava_accesstoken, QZSettings::default_strava_accesstoken) + .toString() + .isEmpty()) { QFile f(filename); f.open(QFile::OpenModeFlag::ReadOnly); @@ -3489,7 +3616,11 @@ void homeform::gpx_open_clicked(const QUrl &fileName) { for (const auto &p : g_list) { trainrow r; if (p.speed > 0) { + QGeoCoordinate p1(last.latitude, last.longitude); + QGeoCoordinate p2(p.latitude, p.longitude, p.elevation); + r.azimuth = p1.azimuthTo(p2); r.speed = p.speed; + r.distance = p.distance; r.duration = QTime(0, 0, 0, 0); r.duration = r.duration.addSecs(p.seconds); r.forcespeed = true; @@ -3498,6 +3629,7 @@ void homeform::gpx_open_clicked(const QUrl &fileName) { r.inclination = p.inclination; r.latitude = p.latitude; r.longitude = p.longitude; + r.gpxElapsed = QTime(0, 0, 0).addSecs(p.seconds); list.append(r); @@ -3723,7 +3855,8 @@ bool homeform::strava_upload_file(const QByteArray &data, const QString &remoten QStringLiteral(" ") + settings.value(QZSettings::strava_suffix, QZSettings::default_strava_suffix).toString(); if (!stravaPelotonActivityName.isEmpty()) { activityName = stravaPelotonActivityName + QStringLiteral(" - ") + stravaPelotonInstructorName + activityName; - if (pelotonHandler && settings.value(QZSettings::peloton_description_link, QZSettings::default_peloton_description_link).toBool()) + if (pelotonHandler && + settings.value(QZSettings::peloton_description_link, QZSettings::default_peloton_description_link).toBool()) activityDescription = QStringLiteral("https://members.onepeloton.com/classes/cycling?modal=classDetailsModal&classId=") + pelotonHandler->current_ride_id; @@ -4040,7 +4173,8 @@ void homeform::sendMail() { double WeightLoss = 0; // TODO: add a condition to avoid sending mail when the user look at the chart while is riding - if (settings.value(QZSettings::user_email, QZSettings::default_user_email).toString().length() == 0 || !bluetoothManager->device()) { + if (settings.value(QZSettings::user_email, QZSettings::default_user_email).toString().length() == 0 || + !bluetoothManager->device()) { return; } @@ -4353,7 +4487,8 @@ QString homeform::getAndroidDataAppDir() { quint64 homeform::cryptoKeySettingsProfiles() { QSettings settings; - quint64 v = settings.value(QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles).toULongLong(); + quint64 v = settings.value(QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles) + .toULongLong(); if (!v) { QRandomGenerator r = QRandomGenerator(); r.seed(QDateTime::currentMSecsSinceEpoch()); @@ -4369,9 +4504,9 @@ void homeform::saveSettings(const QUrl &filename) { QDir().mkdir(path + QStringLiteral("settings/")); QSettings settings; - QSettings settings2Save(path + QStringLiteral("settings/settings_") + settings.value(QZSettings::profile_name).toString() + - QStringLiteral("_") + QDateTime::currentDateTime().toString("yyyyMMddhhmmss") + - QStringLiteral(".qzs"), + QSettings settings2Save(path + QStringLiteral("settings/settings_") + + settings.value(QZSettings::profile_name).toString() + QStringLiteral("_") + + QDateTime::currentDateTime().toString("yyyyMMddhhmmss") + QStringLiteral(".qzs"), QSettings::IniFormat); auto settigsAllKeys = settings.allKeys(); for (const QString &s : qAsConst(settigsAllKeys)) { @@ -4445,7 +4580,9 @@ double homeform::heartRateMax() { double maxHeartRate = 220.0 - settings.value(QZSettings::age, QZSettings::default_age).toDouble(); if (settings.value(QZSettings::heart_max_override_enable, QZSettings::default_heart_max_override_enable).toBool()) - maxHeartRate = settings.value(QZSettings::heart_max_override_value, QZSettings::default_heart_max_override_value).toDouble(); + maxHeartRate = + settings.value(QZSettings::heart_max_override_value, QZSettings::default_heart_max_override_value) + .toDouble(); if (maxHeartRate == 0) { maxHeartRate = 190.0; } @@ -4492,7 +4629,7 @@ void homeform::licenseRequest() { QUrl url(QStringLiteral("http://robertoviola.cloud:4010/?supporter=") + settings.value(QZSettings::user_email, "").toString()); QNetworkRequest request(url); - mgr->get(request); + // mgr->get(request); } void homeform::licenseTimeout() { setLicensePopupVisible(true); } @@ -4501,7 +4638,8 @@ void homeform::licenseTimeout() { setLicensePopupVisible(true); } void homeform::changeTimestamp(QTime source, QTime actual) { const double filterRate = 0.1; QSettings settings; - int filterSeconds = settings.value(QZSettings::video_playback_window_s, QZSettings::default_video_playback_window_s).toInt(); + int filterSeconds = + settings.value(QZSettings::video_playback_window_s, QZSettings::default_video_playback_window_s).toInt(); QObject *rootObject = engine->rootObjects().constFirst(); auto *videoPlaybackHalf = rootObject->findChild(QStringLiteral("videoplaybackhalf")); @@ -4514,7 +4652,7 @@ void homeform::changeTimestamp(QTime source, QTime actual) { double fullRate = (double)QTime(0, 0, 0).secsTo(source) / (double)QTime(0, 0, 0).secsTo(actual); // calculating the avg speed of the video for the next 5 seconds - double speedOfTheVideoForTheNextXSeconds = trainProgram->avgSpeedNextSecondsGPX(5); + double speedOfTheVideoForTheNextXSeconds = trainProgram->avgSpeedFromGpxStep(0, 5); // to remove using the #945 // adding filterSeconds to the actual video timestamp double timeStampVideoToXSeconds = QTime(0, 0, 0).secsTo(actual.addSecs(filterSeconds)); diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index 4d4aaacee..1c53daa9d 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -111,26 +111,29 @@ QList trainprogram::inclinationNext300Meters() { } // speed in Km/h -double trainprogram::avgSpeedNextSecondsGPX(int seconds) { - int c = currentStep + 1; - double km = 0; - int sum = 0; - double actualGPXElapsed = QTime(0, 0, 0).secsTo(rows.at(currentStep).gpxElapsed); - +double trainprogram::avgSpeedFromGpxStep(int gpxStep, int seconds) { + int start = gpxStep; + if (gpxStep >= rows.length()) + return 0.0; + double km = (rows.at(gpxStep).distance); + int timesum = 0; + if (gpxStep > 0) + timesum = (QTime(0, 0, 0).secsTo(rows.at(gpxStep).gpxElapsed) - + QTime(0, 0, 0).secsTo(rows.at(gpxStep - 1).gpxElapsed)); + else + timesum = QTime(0, 0, 0).secsTo(rows.at(gpxStep).gpxElapsed); + int c = gpxStep + 1; while (1) { - if (c < rows.length()) { - if (sum - actualGPXElapsed > seconds) { - return km / (((double)(sum - actualGPXElapsed)) / 3600.0); - } - km += (rows.at(c).distance); - sum = QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed); - - } else { - return km / (((double)(sum - actualGPXElapsed)) / 3600.0); + if ((timesum >= seconds) || (c >= rows.length())) { + return (km / ((double)timesum) * 3600.0); } + km += (rows.at(c).distance); + if (c > 0) + timesum = (timesum + QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed) - + QTime(0, 0, 0).secsTo(rows.at(c - 1).gpxElapsed)); c++; } - return km / (((double)(sum - actualGPXElapsed)) / 3600.0); + return (km / ((double)timesum) * 3600.0); } double trainprogram::avgInclinationNext100Meters() { @@ -266,8 +269,12 @@ void trainprogram::scheduler() { if (rows.at(0).inclination != -200 && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { // this should be converted in a signal as all the other signals... - double bikeResistanceOffset = settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset).toInt(); - double bikeResistanceGain = settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f).toDouble(); + double bikeResistanceOffset = + settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset) + .toInt(); + double bikeResistanceGain = + settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f) + .toDouble(); double inc; if (!isnan(rows.at(0).latitude) && !isnan(rows.at(0).longitude)) { @@ -347,7 +354,13 @@ void trainprogram::scheduler() { if (rows.at(currentStep).forcespeed && rows.at(currentStep).speed) { qDebug() << QStringLiteral("trainprogram change speed ") + QString::number(rows.at(currentStep).speed); - emit changeSpeed(rows.at(currentStep).speed); + double speed; + if (!isnan(rows.at(currentStep).latitude) && !isnan(rows.at(currentStep).longitude)) { + speed = avgSpeedFromGpxStep(currentStep, 60); + } else { + speed = rows.at(currentStep).speed; + } + emit changeSpeed(speed); } if (rows.at(currentStep).inclination != -200) { double inc; @@ -389,9 +402,13 @@ void trainprogram::scheduler() { bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { // this should be converted in a signal as all the other signals... double bikeResistanceOffset = - settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset).toInt(); + settings + .value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset) + .toInt(); double bikeResistanceGain = - settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f).toDouble(); + settings + .value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f) + .toDouble(); double inc; if (!isnan(rows.at(currentStep).latitude) && !isnan(rows.at(currentStep).longitude)) { @@ -471,8 +488,12 @@ void trainprogram::scheduler() { if (rows.at(currentStep).inclination != -200 && (!isnan(rows.at(currentStep).latitude) && !isnan(rows.at(currentStep).longitude))) { double inc = avgInclinationNext100Meters(); - double bikeResistanceOffset = settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset).toInt(); - double bikeResistanceGain = settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f).toDouble(); + double bikeResistanceOffset = + settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset) + .toInt(); + double bikeResistanceGain = + settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f) + .toDouble(); if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { bluetoothManager->device()->changeResistance((resistance_t)(round(inc * bikeResistanceGain)) + diff --git a/src/trainprogram.h b/src/trainprogram.h index b7f883032..860c97428 100644 --- a/src/trainprogram.h +++ b/src/trainprogram.h @@ -72,7 +72,7 @@ class trainprogram : public QObject { void decreaseElapsedTime(uint32_t i); int32_t offsetElapsedTime() { return offset; } void clearRows(); - double avgSpeedNextSecondsGPX(int seconds); + double avgSpeedFromGpxStep(int gpxStep, int seconds); QList rows; QList loadedRows; // rows as loaded From fd96a3336dee6c0accdae2cb0bdf7186cd5283bb Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 11 Oct 2022 17:03:32 +0200 Subject: [PATCH 100/255] fixed typo --- src/homeform.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/homeform.cpp b/src/homeform.cpp index 8b0b72fe3..eeb083ef4 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -4629,7 +4629,7 @@ void homeform::licenseRequest() { QUrl url(QStringLiteral("http://robertoviola.cloud:4010/?supporter=") + settings.value(QZSettings::user_email, "").toString()); QNetworkRequest request(url); - // mgr->get(request); + mgr->get(request); } void homeform::licenseTimeout() { setLicensePopupVisible(true); } From 8dc28afd98ec84e6354a8da6f2b518241ad93daf Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 11 Oct 2022 17:18:27 +0200 Subject: [PATCH 101/255] license request every 30s --- src/homeform.cpp | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/homeform.cpp b/src/homeform.cpp index eeb083ef4..8301930ca 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -4621,15 +4621,17 @@ void homeform::licenseReply(QNetworkReply *reply) { } void homeform::licenseRequest() { - QSettings settings; - if (!mgr) { - mgr = new QNetworkAccessManager(this); - connect(mgr, &QNetworkAccessManager::finished, this, &homeform::licenseReply); - } - QUrl url(QStringLiteral("http://robertoviola.cloud:4010/?supporter=") + - settings.value(QZSettings::user_email, "").toString()); - QNetworkRequest request(url); - mgr->get(request); + QTimer::singleShot(30000, this, [this]() { + QSettings settings; + if (!mgr) { + mgr = new QNetworkAccessManager(this); + connect(mgr, &QNetworkAccessManager::finished, this, &homeform::licenseReply); + } + QUrl url(QStringLiteral("http://robertoviola.cloud:4010/?supporter=") + + settings.value(QZSettings::user_email, "").toString()); + QNetworkRequest request(url); + mgr->get(request); + }); } void homeform::licenseTimeout() { setLicensePopupVisible(true); } From f93d54ec4c3ac3624f2ba666788f28c1dcf53d38 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 12 Oct 2022 08:18:08 +0200 Subject: [PATCH 102/255] Pro FlexCycle #979 --- src/bluetooth.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index f183b7c0f..344e7137d 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -1207,6 +1207,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { (b.name().toUpper().startsWith("YS_C1_")) || // Yesoul C1H (b.name().toUpper().startsWith("DS25-")) || // Bodytone DS25 (b.name().toUpper().startsWith("SCHWINN 510T")) || + (b.name().toUpper().startsWith("FLXCY-")) || // Pro FlexBike (b.name().toUpper().startsWith("WAHOO KICKR")) || (b.name().toUpper().startsWith("B94")) || (b.name().toUpper().startsWith("STAGES BIKE")) || (b.name().toUpper().startsWith("SUITO")) || (b.name().toUpper().startsWith("D2RIDE")) || (b.name().toUpper().startsWith("DIRETO XR")) || From 6158bc074b9ff737ed1b0af775460130633cbfb4 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 12 Oct 2022 09:46:40 +0200 Subject: [PATCH 103/255] Bike Support Merach MRK-S02-0B8D #978 --- src/bluetooth.cpp | 5 +++-- src/fitplusbike.cpp | 42 ++++++++++++++++++++++++++++-------------- src/fitplusbike.h | 2 ++ 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 344e7137d..0b967ad74 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -1738,8 +1738,9 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { snodeBike->deviceDiscovered(b); userTemplateManager->start(snodeBike); innerTemplateManager->start(snodeBike); - } else if ((b.name().startsWith(QStringLiteral("FS-")) && fitplus_bike) && !fitPlusBike && !ftmsBike && - !snodeBike && filter) { + } else if (((b.name().startsWith(QStringLiteral("FS-")) && fitplus_bike) || + b.name().startsWith(QStringLiteral("MRK-"))) && + !fitPlusBike && !ftmsBike && !snodeBike && filter) { this->stopDiscovery(); fitPlusBike = new fitplusbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); diff --git a/src/fitplusbike.cpp b/src/fitplusbike.cpp index 7769769b4..dd5998e8e 100644 --- a/src/fitplusbike.cpp +++ b/src/fitplusbike.cpp @@ -72,7 +72,7 @@ void fitplusbike::writeCharacteristic(uint8_t *data, uint8_t data_len, const QSt void fitplusbike::forceResistance(resistance_t requestResistance) { QSettings settings; bool virtufit_etappe = settings.value(QZSettings::virtufit_etappe, QZSettings::default_virtufit_etappe).toBool(); - if (virtufit_etappe) { + if (virtufit_etappe || merach_MRK) { if (requestResistance == 1) { uint8_t res[] = {0x02, 0x44, 0x05, 0x01, 0xf9, 0xb9, 0x03}; writeCharacteristic(res, sizeof(res), "force resistance", false, true); @@ -163,9 +163,10 @@ void fitplusbike::update() { gattNotify1Characteristic.isValid() && initDone) { QSettings settings; update_metrics(true, watts()); - bool virtufit_etappe = settings.value(QZSettings::virtufit_etappe, QZSettings::default_virtufit_etappe).toBool(); + bool virtufit_etappe = + settings.value(QZSettings::virtufit_etappe, QZSettings::default_virtufit_etappe).toBool(); - if (virtufit_etappe) { + if (virtufit_etappe || merach_MRK) { } else { @@ -176,10 +177,11 @@ void fitplusbike::update() { settings.value(QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1).toDouble())) / (settings.value(QZSettings::power_hr_hr2, QZSettings::default_power_hr_hr2).toDouble() - settings.value(QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1).toDouble()) + - (Heart.value() * ((settings.value(QZSettings::power_hr_pwr1, QZSettings::default_power_hr_pwr1).toDouble() - - settings.value(QZSettings::power_hr_pwr2, QZSettings::default_power_hr_pwr2).toDouble()) / - (settings.value(QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1).toDouble() - - settings.value(QZSettings::power_hr_hr2, QZSettings::default_power_hr_hr2).toDouble()))); + (Heart.value() * + ((settings.value(QZSettings::power_hr_pwr1, QZSettings::default_power_hr_pwr1).toDouble() - + settings.value(QZSettings::power_hr_pwr2, QZSettings::default_power_hr_pwr2).toDouble()) / + (settings.value(QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1).toDouble() - + settings.value(QZSettings::power_hr_hr2, QZSettings::default_power_hr_hr2).toDouble()))); if (avgP < 50) { avgP = 50; } @@ -255,7 +257,7 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte lastPacket = newValue; bool virtufit_etappe = settings.value(QZSettings::virtufit_etappe, QZSettings::default_virtufit_etappe).toBool(); - if (virtufit_etappe) { + if (virtufit_etappe || merach_MRK) { if (newValue.length() != 15 && newValue.length() != 13) return; @@ -303,7 +305,8 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte if (watts()) KCal += - ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / + ((((0.048 * ((double)watts()) + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / 200.0) / (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in kg @@ -341,7 +344,8 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte #ifdef Q_OS_IOS #ifndef IO_UNDER_QT bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence && h && firstStateChanged) { h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime()); h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate()); @@ -366,7 +370,10 @@ void fitplusbike::btinit() { QSettings settings; bool virtufit_etappe = settings.value(QZSettings::virtufit_etappe, QZSettings::default_virtufit_etappe).toBool(); - if (virtufit_etappe) { + if (merach_MRK) { + uint8_t initData1[] = {0xaa, 0x01, 0x00, 0x01, 0x55}; + writeCharacteristic(initData1, sizeof(initData1), QStringLiteral("init"), false, true); + } else if (virtufit_etappe) { uint8_t initData1[] = {0x02, 0x42, 0x42, 0x03}; uint8_t initData2[] = {0x02, 0x41, 0x02, 0x43, 0x03}; uint8_t initData3[] = {0x02, 0x41, 0x03, 0x42, 0x03}; @@ -448,11 +455,14 @@ void fitplusbike::stateChanged(QLowEnergyService::ServiceState state) { #endif ) { QSettings settings; - bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); #ifdef Q_OS_IOS #ifndef IO_UNDER_QT - bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool cadence = + settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence) { qDebug() << "ios_peloton_workaround activated!"; h = new lockscreen(); @@ -518,6 +528,10 @@ void fitplusbike::deviceDiscovered(const QBluetoothDeviceInfo &device) { { bluetoothDevice = device; + if (device.name().startsWith(QStringLiteral("MRK-"))) { + merach_MRK = true; + } + m_control = QLowEnergyController::createCentral(bluetoothDevice, this); connect(m_control, &QLowEnergyController::serviceDiscovered, this, &fitplusbike::serviceDiscovered); connect(m_control, &QLowEnergyController::discoveryFinished, this, &fitplusbike::serviceScanDone); diff --git a/src/fitplusbike.h b/src/fitplusbike.h index 2916595a4..5548983e6 100644 --- a/src/fitplusbike.h +++ b/src/fitplusbike.h @@ -75,6 +75,8 @@ class fitplusbike : public bike { bool noWriteResistance = false; bool noHeartService = false; + bool merach_MRK = false; + #ifdef Q_OS_IOS lockscreen *h = 0; #endif From 024f14e9ab6ee3378ad6f1e2b92b07e214d40587 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 12 Oct 2022 09:54:24 +0200 Subject: [PATCH 104/255] Average Speed in the Email doesn't match #977 --- src/android/AndroidManifest.xml | 2 +- src/fitshowtreadmill.cpp | 4 ++-- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index dd4bbbb7f..822494960 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/fitshowtreadmill.cpp b/src/fitshowtreadmill.cpp index a871bf008..13c3d52f1 100644 --- a/src/fitshowtreadmill.cpp +++ b/src/fitshowtreadmill.cpp @@ -463,12 +463,12 @@ void fitshowtreadmill::characteristicChanged(const QLowEnergyCharacteristic &cha lastStop = 0; } + Speed = speed; if (Speed.value() != speed) { - Speed = speed; emit speedChanged(speed); } + Inclination = incline; if (Inclination.value() != incline) { - Inclination = incline; emit inclinationChanged(0, incline); } diff --git a/src/main.qml b/src/main.qml index 7ff75f7c5..371cd7b87 100644 --- a/src/main.qml +++ b/src/main.qml @@ -656,7 +656,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.67" + text: "version 2.11.68" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index c8d41f7c2..b2c523ce8 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.67 +VERSION = 2.11.68 From 3fd5575009077ffc0d6ad7668f188662dbf16d3d Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 12 Oct 2022 18:16:34 +0200 Subject: [PATCH 105/255] Update settings.qml --- src/settings.qml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/settings.qml b/src/settings.qml index f2a009036..a26aa050f 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -172,7 +172,6 @@ import Qt.labs.settings 1.0 property real domyos_elliptical_speed_ratio: 1.0 property bool eslinker_cadenza: true - property bool eslinker_ypoo: false property string echelon_watttable: "Echelon" @@ -482,6 +481,9 @@ import Qt.labs.settings 1.0 // from version 2.11.65 property real rolling_resistance: 0.005 + // from version 2.11.67 + property bool eslinker_ypoo: false + // from version ? property bool trixter_xdream_v1_bike: false property bool trixter_xdream_v1_bike_heartrate_enabled: true From b60f1fd77b1b05a4f55b9ac620fdd5afd0c84d65 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 13 Oct 2022 10:48:23 +0200 Subject: [PATCH 106/255] Zwift Workouts Over Cadence #980 --- src/virtualbike.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/virtualbike.cpp b/src/virtualbike.cpp index 9d728339d..24cf4d617 100644 --- a/src/virtualbike.cpp +++ b/src/virtualbike.cpp @@ -1019,12 +1019,12 @@ void virtualbike::bikeProvider() { Q_UNUSED(erg_mode); #endif - qDebug() << QStringLiteral("bikeProvider") << lastFTMSFrameReceived - << (qint64)(lastFTMSFrameReceived + ((qint64)2000)) << erg_mode; + qDebug() << QStringLiteral("bikeProvider") << whenLastFTMSFrameReceived() + << (qint64)(whenLastFTMSFrameReceived() + ((qint64)2000)) << erg_mode; // zwift with the last update, seems to sending power request only when it actually wants to change it // so i need to keep this on to the bike - if (lastFTMSFrameReceived > 0 && - (QDateTime::currentMSecsSinceEpoch() > (qint64)(lastFTMSFrameReceived + ((qint64)2000))) && erg_mode) { + if (whenLastFTMSFrameReceived() > 0 && + (QDateTime::currentMSecsSinceEpoch() > (qint64)(whenLastFTMSFrameReceived() + ((qint64)2000))) && erg_mode) { qDebug() << QStringLiteral("zwift is not sending the power anymore, let's continue with the last value"); writeP2AD9->changePower(((bike *)Bike)->lastRequestedPower().value()); } From 1f75467ce5bce53519a72837c8e0d81e58612a1a Mon Sep 17 00:00:00 2001 From: Bepo7012 <92673064+Bepo7012@users.noreply.github.com> Date: Thu, 13 Oct 2022 10:56:12 +0200 Subject: [PATCH 107/255] Keep Video and Gpx Position synchronized (Addition to #838) (#945) * Speed up debugging on Windows * Added new way for Video Rate * Tried another Variant * Fixed double double Conversion * Splitted Videopos Rate and Frame rate * Fixed new calculation * Very easy possible solution * Simple try * Not really better, another try * Adjust both Endpoints for calculation * Framerate set * Collecting Data * Use average Rate * Adjusted Videoframe Distance * Fixed correction * use weighted mean rate * Played with factor weighting * Found logic Error in Video Rate * Factor weighting and try reduce flickering * Fixed weighting of Rates * New Idea * Bad Idea, changed Factor weighting again * Code cleanup before Pull Request * added Time difference for testing spec. Video * Test should not be in Pull Request * reverted debug on main.cpp * ios version 2.11.54 * Fixed rewinding Video * Variable Weighting Videorate/Framerate * Added changes again for windows debug * Different Aproach again * Fixed wrong speed calc * Add adjustment to rate based on time difference * try higher or lower rate by 10% first * Adjusted the Rate Base * Removed the Rate % adoption * video length added * Implemented Referencepoint at End of Video * Corrected Video start Time * Init Videotimestamp with Traintimestamp at Start * Fixed comparence * Added trainProgram::TotalGPXSecs * Corrected return * Time to finish * Removed Test and Debug changes in main.cpp * Debug Message removed for next Windows Build * Setting Video to correct Pos if length differs * Don't do anything if Video isn't displayed * fixed visible * fixed visible comparison * added videoSeekPosition in order to change the position of the video in realtime * Implemented Video Adjustment on start * Correct Videotimestamp every time if needed * As usual, fixed Typo * Reversed Video Timestamp correction * Implemented case that Video is shorter then gpx * Approach should be smoother * Corrected shorter Video * Fixed Video starting point if hidden/redisplayed * Reverted Debug changes in main.cpp * adding acceleration in the calculation of the speed based on wattage * fixing negative speed values * Windows debugging again * added Debug Info to calculateSpeedFromPower * Moved Watt calc up to have it for Speed calc * Corrected Start for shorter Videos * Try to use smaller Frame for average Video Speed * Use Fullrate if Diff is to high * Changed high difference rate * adjusted factor * Add 1 % of Timediff to Totalrate * Not successfull, removed again * rolling resistance setting added * Hopefully the last approach * Corrected Target * Remarked some Things to get Debug Data * use only 90 % of rate * Only adjust factor one time per gpx Cycle * Try Percent adoption * fixing changeTimestamp callback with milliseconds precision * Removed % in-/decrease * Removed call to changeTimestamp * removed avgInclination for bikes #838 * Test for Debug * fixing distance error on trxappgateusbbike when speed was calculated over wattage * tried fake bike * Use a 2 sec Window * Added changed Header definition * try to fix gaps in gps * Added some Debug Info * Changed Params for Fake * Removed 2 seconds frame * Try Speed without average * Debug Output Trainprogram * Add more Debug for Trainprogram * Removed Trainprogram Debug * Tried avg. Speed -3/+3 secs * Fix Bug in avgSpeedCalculation * try to limit the rate change * Fixed limiting * Fixed again * Fixed init of Limitation * Removed Limitation, not working as hoped * Check speed Deviation between 90 and 110 % * Search for speed in 6 Secs/clearify Property-Names * Fixed Typo * Fixed Bug in gpx average Speed calculation * Changed Filerrange from +/- 15 % * Fixed possible segmentation Fault * improving precision in the debuglog * fixing elapsed time #838 * changeTimestamp again when next point reached * fixing wrong ratiodistance * qzsettings updated * Save currentStepDistance before set to 0 * currentStop is already incremented, use -2 * use Distance from prev.Row too * currentStep -1 distance and -2 time * Don't use Point 1 * just a try * Should be correct now * changed distance * fixing merge issues * fixing another merge issue * updating ios project * fixing circuit gpx for video * caching the odometer for all the scheduler event and removing the changetimestamp not time based * Calc RatioDistance with Timediff between Points * do this only if the point get hits first * Calc distanceRow to gpx Diff * only use currentStepDistance added since last * Ratio Time has to be summed * Redesign the process * fixed typo * Forgot one change * fixed crash * hopefully fixed now * only add ratioDistance one time * Added debug Info * Filter changingTimestamp if Variance to high * added Debug Info * fixed Variance calculation * fixed typo * Store last Tick/TimeStamp Ratio for next cycle * moved ratioDistance in correct scope * Add ratioDistance, not calculated Ratio * Back to Ratio again, better Results * add ms not s * changed Variance Range to -25/+25% * Apply filtering Speed to trainingrows * header definition added * Fixed typo * fixed array access * accessing row data * fixed bug when timetotickratio was 0 * logic Error * fix bug in wma calculation * added more detail to debug * Calculate new distance into temporary array before * fixed typo * removed filter in changing timestamp * Removed some routines no longer needed * Remove peak Filter ompletely, no longer needed * fixed crash at end of program * fixing ios build and applySpeedFilter only on gpx workout * adding running cadence from apple watch to ipad * Fix for iOS Crash? * fixing treadmill force speed setting with applyspeedfilter on * adding speedlimit to bike * Update trainprogram.cpp Max.Speed for Bikes (=2 * avg current Trainprogram Speed) implemented * Update trainprogram.cpp changed to max speed to get a max replay factor of 1.9 * fixing speed limit * removing bad check on the speedlimit * adding a new method to know if the video is visible and reset the speed limit * Fixed Issues on video hiding/redisplaying Also makes the first display a little nicer * Removed no longer needed filterSeconds The Option in the setting can also be removed, it's no longer needed * Try to calculate the Speedlimit +1sec * video_playback_window setting removed * preparing for the merge * removed unuseful coment Co-authored-by: Roberto Viola Co-authored-by: Bernhard Ponemayr --- src/Home.qml | 2 +- src/bhfitnesselliptical.cpp | 2 +- src/bike.h | 4 + src/chronobike.cpp | 2 +- src/cscbike.cpp | 2 +- src/domyosbike.cpp | 2 +- src/echelonconnectsport.cpp | 2 +- src/fakebike.cpp | 13 + src/fitplusbike.cpp | 4 +- src/flywheelbike.cpp | 2 +- src/ftmsbike.cpp | 2 +- src/gpx.cpp | 5 +- src/gpx.h | 2 +- src/homeform.cpp | 105 ++++--- src/homeform.h | 13 +- src/horizongr7bike.cpp | 4 +- src/inspirebike.cpp | 2 +- src/ios/AppDelegate.swift | 2 +- src/ios/AppleWatchToIpad/Connection.swift | 4 + src/keepbike.cpp | 2 +- src/m3ibike.cpp | 2 +- src/main.cpp | 2 - src/main.qml | 5 +- src/mcfbike.cpp | 2 +- src/metric.cpp | 6 +- src/metric.h | 2 +- src/npecablebike.cpp | 4 +- src/pafersbike.cpp | 2 +- src/proformbike.cpp | 4 +- src/renphobike.cpp | 2 +- src/schwinnic4bike.cpp | 2 +- src/settings.qml | 5 +- src/skandikawiribike.cpp | 2 +- src/snodebike.cpp | 2 +- src/solebike.cpp | 2 +- src/sportsplusbike.cpp | 4 +- src/sportstechbike.cpp | 2 +- src/stagesbike.cpp | 2 +- src/trainprogram.cpp | 316 ++++++++++++++++++++-- src/trainprogram.h | 10 + src/trxappgateusbbike.cpp | 27 +- src/ultrasportbike.cpp | 2 +- src/wahookickrsnapbike.cpp | 2 +- src/yesoulbike.cpp | 2 +- 44 files changed, 452 insertions(+), 135 deletions(-) diff --git a/src/Home.qml b/src/Home.qml index 0c5348575..48a182a6a 100644 --- a/src/Home.qml +++ b/src/Home.qml @@ -250,7 +250,7 @@ HomeForm{ footer: Rectangle { objectName: "footerrectangle" - visible: showVideo + visible: rootItem.videoVisible anchors.top: gridView.bottom width: parent.width height: parent.height / 2 diff --git a/src/bhfitnesselliptical.cpp b/src/bhfitnesselliptical.cpp index 578b9f32c..b3a2364fb 100644 --- a/src/bhfitnesselliptical.cpp +++ b/src/bhfitnesselliptical.cpp @@ -182,7 +182,7 @@ void bhfitnesselliptical::characteristicChanged(const QLowEnergyCharacteristic & (uint16_t)((uint8_t)newValue.at(index)))) / 100.0;*/ } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), 0 /* not useful for elliptical*/); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/bike.h b/src/bike.h index 34af5af94..099c76c7c 100644 --- a/src/bike.h +++ b/src/bike.h @@ -32,6 +32,8 @@ class bike : public bluetoothdevice { uint8_t metrics_override_heartrate(); void setGears(int8_t d); int8_t gears(); + void setSpeedLimit(double speed) {m_speedLimit = speed;} + double speedLimit() {return m_speedLimit;} /** @@ -80,6 +82,8 @@ class bike : public bluetoothdevice { metric m_pelotonResistance; metric m_steeringAngle; + + double m_speedLimit = 0; }; #endif // BIKE_H diff --git a/src/chronobike.cpp b/src/chronobike.cpp index dfbfbe5c9..c6d55652b 100644 --- a/src/chronobike.cpp +++ b/src/chronobike.cpp @@ -150,7 +150,7 @@ void chronobike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = ((double)((uint16_t)((uint8_t)newValue.at(6)) + ((uint16_t)((uint8_t)newValue.at(7)) << 8))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += diff --git a/src/cscbike.cpp b/src/cscbike.cpp index 7a0b03ac5..36e762c27 100644 --- a/src/cscbike.cpp +++ b/src/cscbike.cpp @@ -238,7 +238,7 @@ void cscbike::characteristicChanged(const QLowEnergyCharacteristic &characterist if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/domyosbike.cpp b/src/domyosbike.cpp index d5ddb47ca..f2c9b397e 100644 --- a/src/domyosbike.cpp +++ b/src/domyosbike.cpp @@ -427,7 +427,7 @@ void domyosbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } KCal = kcal; Distance = distance; diff --git a/src/echelonconnectsport.cpp b/src/echelonconnectsport.cpp index 870b40c33..e3516e330 100644 --- a/src/echelonconnectsport.cpp +++ b/src/echelonconnectsport.cpp @@ -231,7 +231,7 @@ void echelonconnectsport::characteristicChanged(const QLowEnergyCharacteristic & if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = 0.37497622 * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += diff --git a/src/fakebike.cpp b/src/fakebike.cpp index 8911b257b..67473d17a 100644 --- a/src/fakebike.cpp +++ b/src/fakebike.cpp @@ -33,6 +33,19 @@ void fakebike::update() { QString heartRateBeltName = settings.value(QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name).toString(); + /* + static int updcou = 0; + updcou++; + double w = 250.0; + if (updcou > 20000 ) + updcou = 0; + else if (updcou > 12000) + w = 300; + else if (updcou > 6000) + w = 150; + + Speed = metric::calculateSpeedFromPower(w, Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), speedLimit());*/ + update_metrics(true, watts()); Distance += ((Speed.value() / (double)3600.0) / diff --git a/src/fitplusbike.cpp b/src/fitplusbike.cpp index dd5998e8e..199b1f27a 100644 --- a/src/fitplusbike.cpp +++ b/src/fitplusbike.cpp @@ -274,7 +274,7 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte /*if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) Speed = (double)((((uint8_t)newValue.at(4)) << 10) | ((uint8_t)newValue.at(9))) / 100.0; else*/ - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } else if (newValue.length() == 13) { @@ -300,7 +300,7 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) Speed = (double)((((uint8_t)newValue.at(7)) << 8) | ((uint8_t)newValue.at(6))) / 10.0; else - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) diff --git a/src/flywheelbike.cpp b/src/flywheelbike.cpp index c01379b41..9987ee9dc 100644 --- a/src/flywheelbike.cpp +++ b/src/flywheelbike.cpp @@ -290,7 +290,7 @@ void flywheelbike::characteristicChanged(const QLowEnergyCharacteristic &charact if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = ((double)speed) / 10.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } // https://www.facebook.com/groups/149984563348738/permalink/174268944253633/?comment_id=174366620910532&reply_comment_id=174666314213896 diff --git a/src/ftmsbike.cpp b/src/ftmsbike.cpp index c504e5da3..37668217c 100644 --- a/src/ftmsbike.cpp +++ b/src/ftmsbike.cpp @@ -204,7 +204,7 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/gpx.cpp b/src/gpx.cpp index 8aa87f4f7..42aa7113f 100644 --- a/src/gpx.cpp +++ b/src/gpx.cpp @@ -88,6 +88,7 @@ QList gpx::open(const QString &gpx) { this->points.constLast().p.longitude())) < 300) { // to create the circuit this->points.append(this->points.constFirst()); + this->points.last().time = this->points.at(this->points.count() - 2).time; } for (int32_t i = 1; i < this->points.count(); i++) { @@ -108,8 +109,8 @@ QList gpx::open(const QString &gpx) { g.latitude = pP.p.latitude(); g.longitude = pP.p.longitude(); g.seconds = this->points.constFirst().time.secsTo(pP.time); - // qDebug() << qSetRealNumberPrecision(10) << i << g.distance << g.inclination << g.elevation << g.latitude - // << g.longitude << totDistance; + /*qDebug() << qSetRealNumberPrecision(10) << i << g.distance << g.inclination << g.elevation << g.latitude + << g.longitude << totDistance << pP.time;*/ inclinationList.append(g); } } diff --git a/src/gpx.h b/src/gpx.h index f2fbcc6d1..9ed56f7bc 100644 --- a/src/gpx.h +++ b/src/gpx.h @@ -10,7 +10,7 @@ class gpx_altitude_point_for_treadmill { public: - uint32_t seconds = 0; + uint64_t seconds = 0; float inclination = 0; float elevation = 0; float speed = 0; diff --git a/src/homeform.cpp b/src/homeform.cpp index 8301930ca..7c90136d1 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -3658,11 +3658,11 @@ void homeform::gpx_open_clicked(const QUrl &fileName) { if (g.getVideoURL().isEmpty() == false) { movieFileName = QUrl(g.getVideoURL()); emit videoPathChanged(movieFileName); - setVideoVisible(true); + setVideoIconVisible(true); } else if (QFile::exists(file.fileName().replace(".gpx", ".mp4"))) { movieFileName = QUrl::fromLocalFile(file.fileName().replace(".gpx", ".mp4")); emit videoPathChanged(movieFileName); - setVideoVisible(true); + setVideoIconVisible(true); } } @@ -4135,12 +4135,12 @@ void homeform::setMapsVisible(bool value) { emit mapsVisibleChanged(m_MapsVisible); } -bool homeform::videoVisible() { return m_VideoVisible; } +bool homeform::videoIconVisible() { return m_VideoIconVisible; } -void homeform::setVideoVisible(bool value) { +void homeform::setVideoIconVisible(bool value) { - m_VideoVisible = value; - emit videoVisibleChanged(m_VideoVisible); + m_VideoIconVisible = value; + emit videoIconVisibleChanged(m_VideoIconVisible); } int homeform::videoPosition() { return m_VideoPosition; } @@ -4638,48 +4638,63 @@ void homeform::licenseTimeout() { setLicensePopupVisible(true); } #endif void homeform::changeTimestamp(QTime source, QTime actual) { - const double filterRate = 0.1; QSettings settings; - int filterSeconds = - settings.value(QZSettings::video_playback_window_s, QZSettings::default_video_playback_window_s).toInt(); + // only needed if a gpx is loaded and the video is visible, otherwise do nothing. + if ( (trainProgram) && (videoVisible() == true) ) { + QObject *rootObject = engine->rootObjects().constFirst(); + auto *videoPlaybackHalf = rootObject->findChild(QStringLiteral("videoplaybackhalf")); + auto videoPlaybackHalfPlayer = qvariant_cast(videoPlaybackHalf->property("mediaObject")); + double videoTimeStampSeconds = (double)videoPlaybackHalfPlayer->position() / 1000.0; + // Check for time differences between V1ideo and gpx Data + if (videoTimeStampSeconds != 0.0) { + double videoLengthSeconds = ((double)(videoPlaybackHalfPlayer->duration() / 1000.0)); + double trainProgramLengthSeconds = ((double)(trainProgram->TotalGPXSecs())); + // check if there is a difference >= 1 second + if ((fabs(videoLengthSeconds - trainProgramLengthSeconds))>=1.0) { + // correct Video TimeStamp by difference + videoTimeStampSeconds = (videoTimeStampSeconds - videoLengthSeconds + trainProgramLengthSeconds); + } + + // If videoTimeStamp is 0 init with gpx Timestamp to make sure first Cycle is done correctly + if (videoTimeStampSeconds == 0.0) { + videoTimeStampSeconds = ((double)(QTime(0, 0, 0).secsTo(source))); + } + // Video was just displayed, set the start Position + if (videoMustBeReset) { + int videoStartPos = ((QTime(0, 0, 0).secsTo(source) +((int)(videoLengthSeconds))-((int)(trainProgramLengthSeconds)))); + // if videoStartPos is negativ the Video is shorter then the GPX. Wait for the gpx to reach a point where the Video can be played + if (videoStartPos >= 0) { + videoPlaybackHalfPlayer->setPosition(videoStartPos*1000); + videoTimeStampSeconds=(((double)(videoStartPos)) - videoLengthSeconds + trainProgramLengthSeconds); + videoMustBeReset = false; + } + } + // Video is started now, calculate and set the Rate + if (!videoMustBeReset) { + // calculate and set the new Video Rate + double rate = trainProgram->TimeRateFromGPX(((double)QTime(0, 0, 0).msecsTo(source)) / 1000.0, videoTimeStampSeconds, bluetoothManager->device()->currentSpeed().average5s()); + setVideoRate(rate); + } + } + } + if(!videoVisible()) { + // set the maximum Speed that the player can reached based on the Video speed. + // When Video is not displayed (or not displayed any longer) remove the Limit + if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { + bike * dev = (bike *)bluetoothManager->device(); + dev->setSpeedLimit(0); + } + // Prepare for a possible Video play. Set the Start Position to 1 and a Rate so low that only a few frames are played + setVideoPosition(1); + setVideoRate(0.01); + videoMustBeReset = true; + } +} + +void homeform::videoSeekPosition(int ms) { QObject *rootObject = engine->rootObjects().constFirst(); auto *videoPlaybackHalf = rootObject->findChild(QStringLiteral("videoplaybackhalf")); auto videoPlaybackHalfPlayer = qvariant_cast(videoPlaybackHalf->property("mediaObject")); - - double videoTimeStampSeconds = (double)videoPlaybackHalfPlayer->position() / 1000.0; - - if (trainProgram) { - // only for debug, this is the rate of the video vs the player for the whole ride - double fullRate = (double)QTime(0, 0, 0).secsTo(source) / (double)QTime(0, 0, 0).secsTo(actual); - - // calculating the avg speed of the video for the next 5 seconds - double speedOfTheVideoForTheNextXSeconds = trainProgram->avgSpeedFromGpxStep(0, 5); // to remove using the #945 - - // adding filterSeconds to the actual video timestamp - double timeStampVideoToXSeconds = QTime(0, 0, 0).secsTo(actual.addSecs(filterSeconds)); - - // calculating the rate of the video speed of the next filterSeconds to the actual average 5s speed of the - // player - double playerSpeedVideoRate = - bluetoothManager->device()->currentSpeed().average5s() / speedOfTheVideoForTheNextXSeconds; - - // adding filterSeconds to the actual player timestamp - double timeStampPlayerToXSeconds = - QTime(0, 0, 0).secsTo(source.addSecs((((double)(filterSeconds)) * playerSpeedVideoRate))); - - // calculating the real rate of the video - double rate = timeStampPlayerToXSeconds / timeStampVideoToXSeconds; - - qDebug() << "changeTimestamp" << source << actual << fullRate << speedOfTheVideoForTheNextXSeconds - << timeStampVideoToXSeconds << timeStampPlayerToXSeconds << playerSpeedVideoRate << rate - << bluetoothManager->device()->currentSpeed().average5s() - << bluetoothManager->device()->currentSpeed().value(); - - // this is used by the videoComponent only when the video must be loaded for the first time - setVideoPosition(QTime(0, 0, 0).secsTo(source) * 1000); - - // if (fabs(videoRate() - rate) > filterRate) - setVideoRate(rate); - } + videoPlaybackHalfPlayer->setPosition(ms); } diff --git a/src/homeform.h b/src/homeform.h index a9ee6f2a9..cd9a5a92d 100644 --- a/src/homeform.h +++ b/src/homeform.h @@ -117,6 +117,7 @@ class homeform : public QObject { Q_PROPERTY(bool licensePopupVisible READ licensePopupVisible NOTIFY licensePopupVisibleChanged WRITE setLicensePopupVisible) Q_PROPERTY(bool mapsVisible READ mapsVisible NOTIFY mapsVisibleChanged WRITE setMapsVisible) + Q_PROPERTY(bool videoIconVisible READ videoIconVisible NOTIFY videoIconVisibleChanged WRITE setVideoIconVisible) Q_PROPERTY(bool videoVisible READ videoVisible NOTIFY videoVisibleChanged WRITE setVideoVisible) Q_PROPERTY(QUrl videoPath READ videoPath NOTIFY videoPathChanged) Q_PROPERTY(int videoPosition READ videoPosition NOTIFY videoPositionChanged WRITE setVideoPosition) @@ -339,7 +340,8 @@ class homeform : public QObject { bool generalPopupVisible(); bool licensePopupVisible(); bool mapsVisible(); - bool videoVisible(); + bool videoIconVisible(); + bool videoVisible() { return m_VideoVisible;} int videoPosition(); double videoRate(); double currentSpeed() { @@ -362,8 +364,10 @@ class homeform : public QObject { } } void setLicensePopupVisible(bool value); - void setVideoVisible(bool value); - void setVideoPosition(int position); + void setVideoIconVisible(bool value); + void setVideoVisible(bool value) {m_VideoVisible = value; emit videoVisibleChanged(m_VideoVisible);} + void setVideoPosition(int position); // on startup + void videoSeekPosition(int ms); // in realtime void setVideoRate(double rate); void setMapsVisible(bool value); void setGeneralPopupVisible(bool value); @@ -488,6 +492,7 @@ class homeform : public QObject { bool m_generalPopupVisible = false; bool m_LicensePopupVisible = false; bool m_MapsVisible = false; + bool m_VideoIconVisible = false; bool m_VideoVisible = false; int m_VideoPosition = 0; double m_VideoRate = 1; @@ -599,6 +604,7 @@ class homeform : public QObject { QGeoPath gpx_preview; PathController pathController; + bool videoMustBeReset = true; public slots: void aboutToQuit(); @@ -678,6 +684,7 @@ class homeform : public QObject { void changePelotonProvider(QString value); void generalPopupVisibleChanged(bool value); void licensePopupVisibleChanged(bool value); + void videoIconVisibleChanged(bool value); void videoVisibleChanged(bool value); void videoPositionChanged(int value); void videoPathChanged(QUrl value); diff --git a/src/horizongr7bike.cpp b/src/horizongr7bike.cpp index 86bb2f427..1f2a82656 100644 --- a/src/horizongr7bike.cpp +++ b/src/horizongr7bike.cpp @@ -211,7 +211,7 @@ void horizongr7bike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); @@ -234,7 +234,7 @@ void horizongr7bike::characteristicChanged(const QLowEnergyCharacteristic &chara (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/inspirebike.cpp b/src/inspirebike.cpp index 91a2de8cf..000e5347d 100644 --- a/src/inspirebike.cpp +++ b/src/inspirebike.cpp @@ -149,7 +149,7 @@ void inspirebike::characteristicChanged(const QLowEnergyCharacteristic &characte if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = 0.37497622 * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += diff --git a/src/ios/AppDelegate.swift b/src/ios/AppDelegate.swift index 87e524b2f..992d69f10 100644 --- a/src/ios/AppDelegate.swift +++ b/src/ios/AppDelegate.swift @@ -85,7 +85,7 @@ var pedometer = CMPedometer() } else { sender = "PHONE" } - Server.server?.send("SENDER=\(sender)#HR=\(WatchKitConnection.currentHeartRate)#") + Server.server?.send("SENDER=\(sender)#HR=\(WatchKitConnection.currentHeartRate)#CAD=\(WatchKitConnection.stepCadence)#") } } diff --git a/src/ios/AppleWatchToIpad/Connection.swift b/src/ios/AppleWatchToIpad/Connection.swift index 7e68f1698..e0b4bdd33 100644 --- a/src/ios/AppleWatchToIpad/Connection.swift +++ b/src/ios/AppleWatchToIpad/Connection.swift @@ -86,6 +86,10 @@ class Connection { let hr : String = message.slice(from: "HR=", to: "#") ?? "" WatchKitConnection.currentHeartRate = (Int(hr) ?? 0) } + if sender?.contains("PHONE") ?? false && message.contains("CAD=") { + let cad : String = message.slice(from: "CAD=", to: "#") ?? "" + WatchKitConnection.stepCadence = (Int(cad) ?? 0) + } if sender?.contains("PAD") ?? false && message.contains("KCAL=") { let kcal : String = message.slice(from: "KCAL=", to: "#") ?? "" WatchKitConnection.kcal = (Double(kcal) ?? 0) diff --git a/src/keepbike.cpp b/src/keepbike.cpp index bf1fef3bc..63732b381 100644 --- a/src/keepbike.cpp +++ b/src/keepbike.cpp @@ -212,7 +212,7 @@ void keepbike::characteristicChanged(const QLowEnergyCharacteristic &characteris Speed = ((uint8_t)newValue.at(18)); } else*/ { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } m_watt = GetWattFromPacket(newValue); diff --git a/src/m3ibike.cpp b/src/m3ibike.cpp index 958e5e92d..e67de32ea 100644 --- a/src/m3ibike.cpp +++ b/src/m3ibike.cpp @@ -679,7 +679,7 @@ void m3ibike::processAdvertising(const QByteArray &data) { if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = k3.speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (settings.value(QZSettings::m3i_bike_kcal, QZSettings::default_m3i_bike_kcal).toBool()) { KCal = k3.calorie; diff --git a/src/main.cpp b/src/main.cpp index 99c99745e..94976bad7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -262,10 +262,8 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QS outFile.open(QIODevice::WriteOnly | QIODevice::Append); QTextStream ts(&outFile); ts << txt; - fprintf(stderr, "%s", txt.toLocal8Bit().constData()); } - (*QT_DEFAULT_MESSAGE_HANDLER)(type, context, msg); } diff --git a/src/main.qml b/src/main.qml index 371cd7b87..57b12dd07 100644 --- a/src/main.qml +++ b/src/main.qml @@ -36,7 +36,6 @@ ApplicationWindow { signal keyMediaNext() property bool lockTiles: false - property bool showVideo: false Settings { id: settings @@ -467,7 +466,7 @@ ApplicationWindow { if(rootItem.currentCoordinateValid) { console.log("coordinate is valid for map"); //stackView.push("videoPlayback.qml"); - showVideo = !showVideo + rootItem.videoVisible = !rootItem.videoVisible } else { console.log("coordinate is NOT valid for map"); } @@ -476,7 +475,7 @@ ApplicationWindow { icon.source: ( "icons/icons/video.png" ) onClicked: { loadVideo(); } anchors.right: toolButtonMaps.left - visible: rootItem.videoVisible + visible: rootItem.videoIconVisible } ToolButton { diff --git a/src/mcfbike.cpp b/src/mcfbike.cpp index 212ef4816..7d2cb699a 100644 --- a/src/mcfbike.cpp +++ b/src/mcfbike.cpp @@ -203,7 +203,7 @@ void mcfbike::characteristicChanged(const QLowEnergyCharacteristic &characterist if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = (((uint16_t)newValue.at(11) << 8) | (uint16_t)((uint8_t)newValue.at(12))) / 10.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } Distance += ((Speed.value() / 3600000.0) * diff --git a/src/metric.cpp b/src/metric.cpp index 9717df60e..08f68ab2d 100644 --- a/src/metric.cpp +++ b/src/metric.cpp @@ -226,7 +226,7 @@ double metric::calculatePowerFromSpeed(double speed, double inclination) { return (v * tr + v * tv * tv * A2Eff) / tran; } -double metric::calculateSpeedFromPower(double power, double inclination, double speed, double deltaTimeSeconds) { +double metric::calculateSpeedFromPower(double power, double inclination, double speed, double deltaTimeSeconds, double speedLimit) { QSettings settings; if (inclination < -5) inclination = -5; @@ -237,6 +237,10 @@ double metric::calculateSpeedFromPower(double power, double inclination, double double maxPowerFromSpeed = calculatePowerFromSpeed(speed, inclination); double acceleration = (power - maxPowerFromSpeed) / fullWeight; double newSpeed = speed + (acceleration * 3.6 * deltaTimeSeconds); + if(speedLimit > 0 && newSpeed > speedLimit) + newSpeed = speedLimit; + if(speedLimit > 0 && maxSpeed > speedLimit) + maxSpeed = speedLimit; if(newSpeed < 0) newSpeed = 0; if (maxSpeed > newSpeed) diff --git a/src/metric.h b/src/metric.h index 3b87f6ea1..b67d5e9a6 100644 --- a/src/metric.h +++ b/src/metric.h @@ -44,7 +44,7 @@ class metric { static double calculateMaxSpeedFromPower(double power, double inclination); static double calculatePowerFromSpeed(double speed, double inclination); - static double calculateSpeedFromPower(double power, double inclination, double speed, double deltaTimeSeconds); + static double calculateSpeedFromPower(double power, double inclination, double speed, double deltaTimeSeconds, double speedLimit); static double calculateWeightLoss(double kcal); static double calculateVO2Max(QList *session); static double calculateKCalfromHR(double HR_AVG, double elapsed); diff --git a/src/npecablebike.cpp b/src/npecablebike.cpp index e2b508417..b2b9a866b 100644 --- a/src/npecablebike.cpp +++ b/src/npecablebike.cpp @@ -180,7 +180,7 @@ void npecablebike::characteristicChanged(const QLowEnergyCharacteristic &charact if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); @@ -249,7 +249,7 @@ void npecablebike::characteristicChanged(const QLowEnergyCharacteristic &charact (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/pafersbike.cpp b/src/pafersbike.cpp index a684f448e..be79848bb 100644 --- a/src/pafersbike.cpp +++ b/src/pafersbike.cpp @@ -208,7 +208,7 @@ void pafersbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = ((uint8_t)newValue.at(3)); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } Resistance = ((uint8_t)newValue.at(5)); diff --git a/src/proformbike.cpp b/src/proformbike.cpp index 5a7a0e0c7..16e4d6da2 100644 --- a/src/proformbike.cpp +++ b/src/proformbike.cpp @@ -663,7 +663,7 @@ void proformbike::characteristicChanged(const QLowEnergyCharacteristic &characte Speed = ((double)((uint16_t)(((uint8_t)newValue.at(13)) << 8) + (uint16_t)((uint8_t)newValue.at(12))) / 100.0); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } double incline = @@ -881,7 +881,7 @@ void proformbike::characteristicChanged(const QLowEnergyCharacteristic &characte .toDouble()) * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } } } diff --git a/src/renphobike.cpp b/src/renphobike.cpp index 7e5638d83..41ada5b1d 100644 --- a/src/renphobike.cpp +++ b/src/renphobike.cpp @@ -205,7 +205,7 @@ void renphobike::characteristicChanged(const QLowEnergyCharacteristic &character (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; else - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); index += 2; debug("Current Speed: " + QString::number(Speed.value())); } diff --git a/src/schwinnic4bike.cpp b/src/schwinnic4bike.cpp index bc2b3d4d7..5bc6701ac 100644 --- a/src/schwinnic4bike.cpp +++ b/src/schwinnic4bike.cpp @@ -163,7 +163,7 @@ void schwinnic4bike::characteristicChanged(const QLowEnergyCharacteristic &chara (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/settings.qml b/src/settings.qml index a26aa050f..672391dc9 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -466,7 +466,7 @@ import Qt.labs.settings 1.0 property bool fakedevice_treadmill: false // from version 2.11.43 - property int video_playback_window_s: 12 + property int video_playback_window_s: 12 // not used // from version 2.11.62 property string horizon_treadmill_profile_user1: "user1" @@ -6624,6 +6624,7 @@ import Qt.labs.settings 1.0 } } + /* AccordionElement { id: videoAccordion title: qsTr("Video 🎥") @@ -6660,7 +6661,7 @@ import Qt.labs.settings 1.0 } } } - } + }*/ AccordionElement { id: experimentalFeatureAccordion diff --git a/src/skandikawiribike.cpp b/src/skandikawiribike.cpp index 189b110d6..2168367c2 100644 --- a/src/skandikawiribike.cpp +++ b/src/skandikawiribike.cpp @@ -208,7 +208,7 @@ void skandikawiribike::characteristicChanged(const QLowEnergyCharacteristic &cha if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } } else if (newValue.at(1) == 0x10) { if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) diff --git a/src/snodebike.cpp b/src/snodebike.cpp index 85c82726b..1b829d62b 100644 --- a/src/snodebike.cpp +++ b/src/snodebike.cpp @@ -162,7 +162,7 @@ void snodebike::characteristicChanged(const QLowEnergyCharacteristic &characteri (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/solebike.cpp b/src/solebike.cpp index a028250b5..47be5b86e 100644 --- a/src/solebike.cpp +++ b/src/solebike.cpp @@ -254,7 +254,7 @@ void solebike::characteristicChanged(const QLowEnergyCharacteristic &characteris if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = GetSpeedFromPacket(newValue); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } m_watt = GetWattFromPacket(newValue); diff --git a/src/sportsplusbike.cpp b/src/sportsplusbike.cpp index 4ee2998cb..7f287385a 100644 --- a/src/sportsplusbike.cpp +++ b/src/sportsplusbike.cpp @@ -143,7 +143,7 @@ void sportsplusbike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } lastTimeCharChanged = QDateTime::currentDateTime(); } else if (newValue.at(1) == 0x30) { @@ -181,7 +181,7 @@ void sportsplusbike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } lastTimeCharChanged = QDateTime::currentDateTime(); kcal = GetKcalFromPacket(newValue); diff --git a/src/sportstechbike.cpp b/src/sportstechbike.cpp index bb7a889cb..76d14a0ec 100644 --- a/src/sportstechbike.cpp +++ b/src/sportstechbike.cpp @@ -163,7 +163,7 @@ void sportstechbike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } Resistance = requestResistance; emit resistanceRead(Resistance.value()); diff --git a/src/stagesbike.cpp b/src/stagesbike.cpp index b85a5b235..cf050be26 100644 --- a/src/stagesbike.cpp +++ b/src/stagesbike.cpp @@ -253,7 +253,7 @@ void stagesbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index 1c53daa9d..a4f12cd41 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -8,6 +8,8 @@ using namespace std::chrono_literals; trainprogram::trainprogram(const QList &rows, bluetooth *b, QString *description, QString *tags) { + QSettings settings; + bool treadmill_force_speed = settings.value(QZSettings::treadmill_force_speed, QZSettings::default_treadmill_force_speed).toBool(); this->bluetoothManager = b; this->rows = rows; this->loadedRows = rows; @@ -15,6 +17,28 @@ trainprogram::trainprogram(const QList &rows, bluetooth *b, QString *d this->description = *description; if (tags) this->tags = *tags; + /* + int c = 0; + for (c = 0; c < rows.length(); c++) { + qDebug() << qSetRealNumberPrecision(10)<< "Trainprogramdata" + << c + << QTime(0, 0, 0).secsTo(rows.at(c).duration) + << QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed) + << QTime(0, 0, 0).secsTo(rows.at(c).rampDuration) + << QTime(0, 0, 0).secsTo(rows.at(c).rampElapsed) + << rows.at(c).latitude + << rows.at(c).longitude + << rows.at(c).altitude + << rows.at(c).distance + << rows.at(c).speed + << rows.at(c).inclination; + } + */ + + // speed filter only to GPX workouts + if (rows.length() && !isnan(rows.at(0).latitude) && !isnan(rows.at(0).longitude && !treadmill_force_speed)) + applySpeedFilter(); + connect(&timer, SIGNAL(timeout()), this, SLOT(scheduler())); timer.setInterval(1s); timer.start(); @@ -59,6 +83,52 @@ QString trainrow::toString() const { return rv; } +void trainprogram::applySpeedFilter() { + if (rows.length()==0) return; + int r = 0; + double weight[] = {0.15, 0.15, 0.1, 0.05, 0.05, 0.1, 0.1, 0.15, 0.15}; + QList newdistance; + newdistance.reserve(rows.length() + 1); + + while (r < rows.length()) { + int ws = (r - 4); + int we = (r + 4); + if (ws < 0) ws = 0; + if (we >= rows.length()) we = (rows.length()-1); + int wc = 0; + double wma = 0; + int rowduration=0; + for (wc = 0; wc<=(we-ws); wc++) { + int currow = (ws+wc); + if (currow <= 0) rowduration=QTime(0, 0, 0).secsTo(rows.at(currow).gpxElapsed); + else rowduration = ((QTime(0, 0, 0).secsTo(rows.at(currow).gpxElapsed)) - (QTime(0, 0, 0).secsTo(rows.at(currow-1).gpxElapsed))); + wma += ((rows.at(currow).distance) / ((double)(rowduration)) * weight[wc]); + } + if (r <= 0) rowduration=QTime(0, 0, 0).secsTo(rows.at(r).gpxElapsed); + else rowduration = ((QTime(0, 0, 0).secsTo(rows.at(r).gpxElapsed)) - (QTime(0, 0, 0).secsTo(rows.at(r-1).gpxElapsed))); + + /* it takes a lot of time during the opening of the file*/ + /* + qDebug() << qSetRealNumberPrecision(10)<< "TrainprogramapplySpeedFilter" + << r + << rows.at(r).latitude + << rows.at(r).longitude + << rows.at(r).altitude + << QTime(0, 0, 0).secsTo(rows.at(r).gpxElapsed) + << rows.at(r).distance + << (wma * ((double)(rowduration))) + << wma + << rowduration + << rows.at(r).inclination;*/ + + newdistance.append(wma * ((double)(rowduration))); + r++; + } + for (r = 0; r < rows.length(); r++) { + rows[r].distance=newdistance.at(r); + } +} + uint32_t trainprogram::calculateTimeForRow(int32_t row) { if (row >= rows.length()) return 0; @@ -136,6 +206,176 @@ double trainprogram::avgSpeedFromGpxStep(int gpxStep, int seconds) { return (km / ((double)timesum) * 3600.0); } +int trainprogram::TotalGPXSecs() { + if (rows.length() == 0) + return 0; + return QTime(0, 0, 0).secsTo(rows.at(rows.length() - 1).gpxElapsed); +} + +double trainprogram::TimeRateFromGPX(double gpxsecs, double videosecs, double currentspeed) { + // no rows available, return 1 + if (rows.length() <= 0) { + qDebug() << "TimeRateFromGPX no Rows"; + return 1.0; + } + if (videosecs == 0.0) { + qDebug() << "TimeRateFromGPX Videopos = 0"; + return 1.0; + } + double prevAvgSpeed = lastGpxSpeedSet; + double avgNextSpeed = -1.0; + if (prevAvgSpeed == 0.0) + avgNextSpeed = avgSpeedFromGpxStep(currentStep, 5); + else { + int testpos = currentStep; + while (testpos < (currentStep + 6)) { + double avgTestSpeed = avgSpeedFromGpxStep(testpos, 5); + double deviation = (avgTestSpeed / prevAvgSpeed); + if (deviation >= 0.85 && deviation <= 1.15) { + avgNextSpeed = avgTestSpeed; + testpos = (currentStep + 6); + } + testpos++; + } + } + if (avgNextSpeed == -1.0) { + avgNextSpeed = avgSpeedFromGpxStep(currentStep, 5); + } + // Avoid a Division by Zero + if (avgNextSpeed == 0.0) { + qDebug() << "TimeRateFromGPX Nextspeed = 0"; + return 1.0; + } + + // set the maximum Speed that the player can reached based on the Video speed. + // if Rate get's too high the Video jumps + if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { + double avgSpeedForLimit = avgSpeedFromGpxStep(currentStep + 1, 5); + if (avgSpeedForLimit > 0.0) { + bike * dev = (bike *)bluetoothManager->device(); + dev->setSpeedLimit(avgSpeedForLimit * 1.7); + } + } + if (gpxsecs == lastGpxRateSetAt) { + qDebug() << "TimeRateFromGPX Gpxpos=lastPos" << lastGpxRateSet; + return lastGpxRateSet; + } + // Calculate the Factor between current Players Speed and the next average GPX Speed + double playedToGpxSpeedFactor = (currentspeed / avgNextSpeed); + // Calculate where the gpx would be in 1 Second + double gpxTarget = (gpxsecs + playedToGpxSpeedFactor); + // Get needed Rate for the next second + double rate = (gpxTarget - videosecs); + + // If rate < 0 Video is highly before the gpx and Video would be rewinded. Wait with Video for gpx to reach it + if (rate < 0.0) { + rate = 0.1; + } + + qDebug() << qSetRealNumberPrecision(10) << "TimeRateFromGPX" << gpxsecs << videosecs << (gpxsecs - videosecs) + << currentspeed << avgNextSpeed << gpxTarget << lastGpxRateSetAt << lastGpxRateSet << rate; + + // Save the last Gpx Timestamp and the last Rate for later calls. + lastGpxSpeedSet = avgNextSpeed; + if (lastGpxRateSetAt != gpxsecs) { + lastGpxRateSetAt = gpxsecs; + lastGpxRateSet = rate; + } + return rate; + + /* + + bool loopFinished = false; + double gpxdistance = 0.0; + double videodistance = 0.0; + double gpxframedistance = 0.0; + double videoframedistance = 0.0; + int c = 0; + int framestartsecs = -1; + int frameendsecs = 0; + double lastsec = 0.0; + + // Identify last needed Time + if (videosecs > gpxsecs) { + lastsec = videosecs; + } + else { + lastsec = gpxsecs; + } + // Add the Timeframe to last needed Time + lastsec += ((double)timeFrame); + // Loop through gpx Rows to collect needed Data + while (!loopFinished) { + double cursecs = ((double)QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed)); + // Row is greater then needed Data, jump out + if (cursecs > lastsec) { + loopFinished = true; + } + // Collect Distance Data for elapsed Time and Timeframe in the future + else { + if (cursecs <= gpxsecs) gpxdistance += (rows.at(c).distance); + if (cursecs <= videosecs) videodistance += (rows.at(c).distance); + if ((cursecs > gpxsecs) && (cursecs <= (gpxsecs + ((double)timeFrame)))) { + gpxframedistance += (rows.at(c).distance); + // Get the exact Start and End Times of Frame for correctly calculating average Speed + if (framestartsecs == -1) framestartsecs = QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed); + frameendsecs = QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed); + } + if ((cursecs > videosecs) && (cursecs <= (videosecs + ((double)timeFrame)))) { + videoframedistance += (rows.at(c).distance); + } + } + c++; + // End of Rows reached + if (c >= rows.length()) loopFinished = true; + } + // If no videoframeend found something is totally wrong. Return 1 + if (frameendsecs == 0) { + qDebug() << qSetRealNumberPrecision(10)<< "TimeRateFromGPX no Videoframe End" + << gpxsecs + << videosecs + << timeFrame + << currentspeed + << gpxdistance + << gpxframedistance + << videodistance + << videoframedistance + << framestartsecs + << frameendsecs ; + + return 1.0; + } + // Calculate the average Speed of the gpx Frame + double avgVideoSpeed = (gpxframedistance / (((double)(frameendsecs-framestartsecs+1)) / 3600.0)); + // Calculate the Videospeed to Playerspeed Rate + double speedRate = (currentspeed / avgVideoSpeed); + // Calculate what the played gpx Distance will be assuming player speed doesn't change + double playedgpxdistance = gpxframedistance * speedRate; + // add the current video/player difference to the playedgpxdistance + playedgpxdistance = playedgpxdistance + gpxdistance - videodistance; + // Calculate rate beween Videoframedistance and played distance + double rate = (playedgpxdistance / videoframedistance); + + qDebug() << qSetRealNumberPrecision(10)<< "TimeRateFromGPX" + << gpxsecs + << videosecs + << (gpxsecs-videosecs) + << fullRate + << timeFrame + << currentspeed + << avgVideoSpeed + << gpxdistance + << gpxframedistance + << videodistance + << videoframedistance + << framestartsecs + << frameendsecs + << playedgpxdistance + << rate; + return rate; + */ +} + double trainprogram::avgInclinationNext100Meters() { int c = currentStep; double km = 0; @@ -169,7 +409,7 @@ double trainprogram::avgAzimuthNext300Meters() { double sinTotal = 0; double cosTotal = 0; - if (rows.at(c).latitude != 0 || rows.at(c).longitude != 0) { + if (!isnan(rows.at(c).latitude) && !isnan(rows.at(c).longitude)) { while (1) { if (c < rows.length()) { if (km > 0.3) { @@ -225,10 +465,12 @@ void trainprogram::scheduler() { ticks++; + double odometerFromTheDevice = bluetoothManager->device()->odometer(); + // entry point if (ticks == 1 && currentStep == 0) { currentStepDistance = 0; - lastOdometer = bluetoothManager->device()->odometer(); + lastOdometer = odometerFromTheDevice; if (bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) { if (rows.at(0).forcespeed && rows.at(0).speed) { qDebug() << QStringLiteral("trainprogram change speed") + QString::number(rows.at(0).speed); @@ -276,12 +518,7 @@ void trainprogram::scheduler() { settings.value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f) .toDouble(); - double inc; - if (!isnan(rows.at(0).latitude) && !isnan(rows.at(0).longitude)) { - inc = avgInclinationNext100Meters(); - } else { - inc = rows.at(0).inclination; - } + double inc = rows.at(0).inclination; bluetoothManager->device()->changeResistance((resistance_t)(round(inc * bikeResistanceGain)) + bikeResistanceOffset + 1); // resistance start from 1) if (!((bike *)bluetoothManager->device())->inclinationAvailableByHardware()) @@ -298,7 +535,8 @@ void trainprogram::scheduler() { } if (!isnan(rows.at(0).latitude) || !isnan(rows.at(0).longitude) || !isnan(rows.at(0).altitude)) { - qDebug() << QStringLiteral("trainprogram change GEO position") + QString::number(rows.at(0).latitude) + + qDebug() << qSetRealNumberPrecision(10) + << QStringLiteral("trainprogram change GEO position") + QString::number(rows.at(0).latitude) + " " + QString::number(rows.at(0).longitude) + " " + QString::number(rows.at(0).altitude) + " " + QString::number(rows.at(0).azimuth); QGeoCoordinate p; @@ -330,14 +568,14 @@ void trainprogram::scheduler() { do { - currentStepDistance += (bluetoothManager->device()->odometer() - lastOdometer); - lastOdometer = bluetoothManager->device()->odometer(); + currentStepDistance += (odometerFromTheDevice - lastOdometer); + lastOdometer = odometerFromTheDevice; bool distanceStep = (rows.at(currentStep).distance > 0); distanceEvaluation = (distanceStep && currentStepDistance >= rows.at(currentStep).distance); - qDebug() << QStringLiteral("currentStepDistance") << currentStepDistance << QStringLiteral("distanceStep") - << distanceStep << QStringLiteral("distanceEvaluation") << distanceEvaluation - << QStringLiteral("rows distance") << rows.at(currentStep).distance << QStringLiteral("same iteration") - << sameIteration; + qDebug() << qSetRealNumberPrecision(10) << QStringLiteral("currentStepDistance") << currentStepDistance + << QStringLiteral("distanceStep") << distanceStep << QStringLiteral("distanceEvaluation") + << distanceEvaluation << QStringLiteral("rows distance") << rows.at(currentStep).distance + << QStringLiteral("same iteration") << sameIteration; if ((calculatedLine != currentStep && !distanceStep) || distanceEvaluation) { if (calculateTimeForRow(calculatedLine) || calculateDistanceForRow(currentStep + 1) > 0) { @@ -348,7 +586,6 @@ void trainprogram::scheduler() { currentStep = calculatedLine; else currentStep++; - currentStepDistance = 0; if (bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) { if (rows.at(currentStep).forcespeed && rows.at(currentStep).speed) { @@ -410,12 +647,7 @@ void trainprogram::scheduler() { .value(QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f) .toDouble(); - double inc; - if (!isnan(rows.at(currentStep).latitude) && !isnan(rows.at(currentStep).longitude)) { - inc = avgInclinationNext100Meters(); - } else { - inc = rows.at(currentStep).inclination; - } + double inc = rows.at(currentStep).inclination; bluetoothManager->device()->changeResistance((resistance_t)(round(inc * bikeResistanceGain)) + bikeResistanceOffset + 1); // resistance start from 1) @@ -435,7 +667,8 @@ void trainprogram::scheduler() { if (!isnan(rows.at(currentStep).latitude) || !isnan(rows.at(currentStep).longitude) || !isnan(rows.at(currentStep).altitude)) { - qDebug() << QStringLiteral("trainprogram change GEO position") + + qDebug() << qSetRealNumberPrecision(10) + << QStringLiteral("trainprogram change GEO position") + QString::number(rows.at(currentStep).latitude) + " " + QString::number(rows.at(currentStep).longitude) + " " + QString::number(rows.at(currentStep).altitude) + " " + @@ -446,18 +679,21 @@ void trainprogram::scheduler() { p.setLatitude(rows.at(currentStep).latitude); p.setLongitude(rows.at(currentStep).longitude); p.setAltitude(rows.at(currentStep).altitude); - // qDebug() << c << rows.at(currentStep+1).latitude << rows.at(currentStep + 1).longitude << + // qDebug() << qSetRealNumberPrecision(10)<< c << rows.at(currentStep+1).latitude << + // rows.at(currentStep + 1).longitude << /*QGeoCoordinate c; c.setLatitude(rows.at(currentStep+1).latitude); c.setLongitude(rows.at(currentStep+1).longitude); c.setAltitude(rows.at(currentStep+1).altitude); - qDebug() << "distance" << p.distanceTo(c) << rows.at(currentStep).distance;*/ + qDebug() << qSetRealNumberPrecision(10)<< "distance" << p.distanceTo(c) << + rows.at(currentStep).distance;*/ - if (bluetoothManager->device()->odometer() - lastOdometer > 0) - p = p.atDistanceAndAzimuth((bluetoothManager->device()->odometer() - lastOdometer), + if (odometerFromTheDevice - lastOdometer > 0) + p = p.atDistanceAndAzimuth((odometerFromTheDevice - lastOdometer), rows.at(currentStep).azimuth); + qDebug() << qSetRealNumberPrecision(10) << "positionOffset" + << (odometerFromTheDevice - lastOdometer); emit changeGeoPosition(p, rows.at(currentStep).azimuth, avgAzimuthNext300Meters()); - emit changeTimestamp(rows.at(currentStep).gpxElapsed, QTime(0, 0, 0).addSecs(ticks)); } } else { qDebug() << QStringLiteral("trainprogram ends!"); @@ -504,7 +740,29 @@ void trainprogram::scheduler() { qDebug() << QStringLiteral("trainprogram change inclination due to gps") + QString::number(inc); emit changeInclination(inc, inc); emit changeNextInclination300Meters(inclinationNext300Meters()); - emit changeTimestamp(rows.at(currentStep).gpxElapsed, QTime(0, 0, 0).addSecs(ticks)); + + double ratioDistance = 0.0; + double distanceRow = rows.at(currentStep).distance; + int steptime = 0; + if (lastStepTimestampChanged != currentStep) { + lastCurrentStepDistance = 0.0; + lastCurrentStepTime = QTime(0, 0, 0); + if (currentStep > 0) { + lastCurrentStepTime = rows.at(currentStep - 1).gpxElapsed; + } + lastStepTimestampChanged = currentStep; + } + if ( (currentStep > 1) && (distanceRow != 0.0) ) { + steptime = ((QTime(0, 0, 0).secsTo(rows.at(currentStep).gpxElapsed)) - (QTime(0, 0, 0).secsTo(rows.at(currentStep-1).gpxElapsed))); + if (steptime == 0) steptime=1; + distanceRow = (distanceRow / ((double)(steptime))); + ratioDistance = ((currentStepDistance - lastCurrentStepDistance) / distanceRow); + lastCurrentStepTime = lastCurrentStepTime.addMSecs(ratioDistance*1000.0); + } + lastCurrentStepDistance = currentStepDistance; + qDebug() << qSetRealNumberPrecision(10) << QStringLiteral("changingTimestamp") << currentStep + << distanceRow << currentStepDistance << lastCurrentStepDistance << ratioDistance << rows.at(currentStep).gpxElapsed << lastCurrentStepTime << ticks; + emit changeTimestamp(lastCurrentStepTime, QTime(0, 0, 0).addSecs(ticks)); } } sameIteration++; diff --git a/src/trainprogram.h b/src/trainprogram.h index 860c97428..c2ebb311e 100644 --- a/src/trainprogram.h +++ b/src/trainprogram.h @@ -73,6 +73,8 @@ class trainprogram : public QObject { int32_t offsetElapsedTime() { return offset; } void clearRows(); double avgSpeedFromGpxStep(int gpxStep, int seconds); + double TimeRateFromGPX(double gpxsecs, double videosecs, double currentspeed); + int TotalGPXSecs(); QList rows; QList loadedRows; // rows as loaded @@ -84,6 +86,8 @@ class trainprogram : public QObject { bool isStarted() { return started; } void scheduler(int tick); + void applySpeedFilter(); + public slots: void onTapeStarted(); void scheduler(); @@ -120,6 +124,12 @@ class trainprogram : public QObject { double lastOdometer = 0; double currentStepDistance = 0; QTimer timer; + double lastGpxRateSetAt = 0.0; + double lastGpxRateSet = 0.0; + double lastGpxSpeedSet = 0.0; + int lastStepTimestampChanged = 0; + double lastCurrentStepDistance =0.0; + QTime lastCurrentStepTime = QTime(0, 0, 0); }; #endif // TRAINPROGRAM_H diff --git a/src/trxappgateusbbike.cpp b/src/trxappgateusbbike.cpp index e7b3fd806..a16928616 100644 --- a/src/trxappgateusbbike.cpp +++ b/src/trxappgateusbbike.cpp @@ -192,10 +192,11 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch emit debug(QStringLiteral(" << ") + newValue.toHex(' ')); lastPacket = newValue; - if ((newValue.length() != 21 && - (bike_type != JLL_IC400 && bike_type != ASVIVA && bike_type != FYTTER_RI08 && bike_type != TUNTURI && bike_type != TUNTURI_2)) || + if ((newValue.length() != 21 && (bike_type != JLL_IC400 && bike_type != ASVIVA && bike_type != FYTTER_RI08 && + bike_type != TUNTURI && bike_type != TUNTURI_2)) || (newValue.length() != 19 && (bike_type == JLL_IC400 || bike_type == ASVIVA || bike_type == FYTTER_RI08)) || - (newValue.length() != 20 && newValue.length() != 21 && (bike_type == TUNTURI || bike_type == TYPE::TUNTURI_2))) { + (newValue.length() != 20 && newValue.length() != 21 && + (bike_type == TUNTURI || bike_type == TYPE::TUNTURI_2))) { return; } @@ -325,18 +326,24 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch FanSpeed = 0; - if (!firstCharChanged) { - Distance += ((speed / 3600.0) / (1000.0 / (lastTimeCharChanged.msecsTo(QTime::currentTime())))); - } - if (m_control->error() != QLowEnergyController::NoError) { qDebug() << QStringLiteral("QLowEnergyController ERROR!!") << m_control->errorString(); } + // moved up to have the Watt for the Speed calc + if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) + .toString() + .startsWith(QStringLiteral("Disabled"))) + m_watt = watt; if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = + metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(), + fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + } + if (!firstCharChanged) { + Distance += ((Speed.value() / 3600.0) / (1000.0 / (lastTimeCharChanged.msecsTo(QTime::currentTime())))); } KCal = kcal; if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) @@ -344,10 +351,6 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch .startsWith(QStringLiteral("Disabled"))) { Cadence = cadence; } - if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) - .toString() - .startsWith(QStringLiteral("Disabled"))) - m_watt = watt; double ac = 0.01243107769; double bc = 1.145964912; diff --git a/src/ultrasportbike.cpp b/src/ultrasportbike.cpp index de4c93759..0849b1137 100644 --- a/src/ultrasportbike.cpp +++ b/src/ultrasportbike.cpp @@ -178,7 +178,7 @@ void ultrasportbike::characteristicChanged(const QLowEnergyCharacteristic &chara /*if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = GetSpeedFromPacket(newValue); } else*/ - { Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); } + { Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += diff --git a/src/wahookickrsnapbike.cpp b/src/wahookickrsnapbike.cpp index 0006ea7de..f7590029a 100644 --- a/src/wahookickrsnapbike.cpp +++ b/src/wahookickrsnapbike.cpp @@ -371,7 +371,7 @@ void wahookickrsnapbike::characteristicChanged(const QLowEnergyCharacteristic &c if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/yesoulbike.cpp b/src/yesoulbike.cpp index 04e2f2328..070e33708 100644 --- a/src/yesoulbike.cpp +++ b/src/yesoulbike.cpp @@ -129,7 +129,7 @@ void yesoulbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = 0.37497622 * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0)); + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += From f546782ba628d0020365abcc281a4ea8bad55f2c Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 13 Oct 2022 11:49:12 +0200 Subject: [PATCH 108/255] Wahoo Direct Connect #476 RGT compatibility fixed Tested with RGT and Zwift on iOS --- .../qdomyoszwift.xcodeproj/project.pbxproj | 12 ++++++------ src/dirconprocessor.cpp | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj index c540ad1bd..1b625ee79 100644 --- a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj +++ b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj @@ -3492,7 +3492,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.62; + CURRENT_PROJECT_VERSION = 2.11.69; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = ( @@ -3660,7 +3660,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.62; + CURRENT_PROJECT_VERSION = 2.11.69; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; @@ -3864,7 +3864,7 @@ CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.62; + CURRENT_PROJECT_VERSION = 2.11.69; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -3956,7 +3956,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.62; + CURRENT_PROJECT_VERSION = 2.11.69; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; @@ -4043,7 +4043,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.62; + CURRENT_PROJECT_VERSION = 2.11.69; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; ENABLE_PREVIEWS = YES; @@ -4153,7 +4153,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.62; + CURRENT_PROJECT_VERSION = 2.11.69; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; diff --git a/src/dirconprocessor.cpp b/src/dirconprocessor.cpp index 7f88c001e..344201880 100644 --- a/src/dirconprocessor.cpp +++ b/src/dirconprocessor.cpp @@ -205,7 +205,7 @@ bool DirconProcessor::sendCharacteristicNotification(quint16 uuid, const QByteAr pkt.uuid = uuid; for (QHash::iterator i = clientsMap.begin(); i != clientsMap.end(); ++i) { client = i.value(); - /*if (client->char_notify.indexOf(uuid) >= 0)*/ { + if (client->char_notify.indexOf(uuid) >= 0) { socket = i.key(); rvs = socket->write(pkt.encode(0)) < 0; if (rvs) diff --git a/src/main.qml b/src/main.qml index 57b12dd07..cbd5d9503 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.68" + text: "version 2.11.69" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index b2c523ce8..d4121a303 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.68 +VERSION = 2.11.69 From ea04794384c33270000de2521e5fa20130c14e85 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 13 Oct 2022 13:33:58 +0200 Subject: [PATCH 109/255] adding a setting for zwift compatibility #476 --- src/dirconprocessor.cpp | 5 +- src/qzsettings.cpp | 6 +- src/qzsettings.h | 1585 ++++++++++++++++++++------------------- src/settings.qml | 31 +- 4 files changed, 832 insertions(+), 795 deletions(-) diff --git a/src/dirconprocessor.cpp b/src/dirconprocessor.cpp index 344201880..201a5f67d 100644 --- a/src/dirconprocessor.cpp +++ b/src/dirconprocessor.cpp @@ -1,5 +1,7 @@ #include "dirconprocessor.h" #include "dirconpacket.h" +#include "qzsettings.h" +#include DirconProcessor::DirconProcessor(const QList &my_services, const QString &serv_name, quint16 serv_port, const QString &serv_sn, const QString &my_mac, QObject *parent) @@ -198,6 +200,7 @@ bool DirconProcessor::sendCharacteristicNotification(quint16 uuid, const QByteAr DirconPacket pkt; QTcpSocket *socket; DirconProcessorClient *client; + QSettings settings; bool rv = true, rvs; pkt.additional_data = data; pkt.Identifier = DPKT_MSGID_UNSOLICITED_CHARACTERISTIC_NOTIFICATION; @@ -205,7 +208,7 @@ bool DirconProcessor::sendCharacteristicNotification(quint16 uuid, const QByteAr pkt.uuid = uuid; for (QHash::iterator i = clientsMap.begin(); i != clientsMap.end(); ++i) { client = i.value(); - if (client->char_notify.indexOf(uuid) >= 0) { + if (client->char_notify.indexOf(uuid) >= 0 || !settings.value(QZSettings::wahoo_rgt_dircon, QZSettings::default_wahoo_rgt_dircon).toBool()) { socket = i.key(); rvs = socket->write(pkt.encode(0)) < 0; if (rvs) diff --git a/src/qzsettings.cpp b/src/qzsettings.cpp index 62f5af842..899b5607c 100644 --- a/src/qzsettings.cpp +++ b/src/qzsettings.cpp @@ -432,8 +432,9 @@ const QString QZSettings:: horizon_treadmill_profile_user5 = QStringLiteral("hor const QString QZSettings:: default_horizon_treadmill_profile_user5 = QStringLiteral("user5"); const QString QZSettings:: nordictrack_gx_2_7 = QStringLiteral("nordictrack_gx_2_7"); const QString QZSettings:: rolling_resistance = QStringLiteral("rolling_resistance"); +const QString QZSettings:: wahoo_rgt_dircon = QStringLiteral("wahoo_rgt_dircon"); -const uint32_t allSettingsCount = 368; +const uint32_t allSettingsCount = 369; QVariant allSettings[allSettingsCount][2] = { { QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles }, { QZSettings::bluetooth_no_reconnection, QZSettings::default_bluetooth_no_reconnection }, @@ -802,7 +803,8 @@ QVariant allSettings[allSettingsCount][2] = { { QZSettings::horizon_treadmill_profile_user4, QZSettings::default_horizon_treadmill_profile_user4}, { QZSettings::horizon_treadmill_profile_user5, QZSettings::default_horizon_treadmill_profile_user5}, { QZSettings::nordictrack_gx_2_7, QZSettings::default_nordictrack_gx_2_7}, - { QZSettings::rolling_resistance, QZSettings::default_rolling_resistance} + { QZSettings::rolling_resistance, QZSettings::default_rolling_resistance}, + { QZSettings::wahoo_rgt_dircon, QZSettings::default_wahoo_rgt_dircon} }; void QZSettings::qDebugAllSettings(bool showDefaults) { diff --git a/src/qzsettings.h b/src/qzsettings.h index 2a8373826..129744a8b 100644 --- a/src/qzsettings.h +++ b/src/qzsettings.h @@ -17,69 +17,69 @@ class QZSettings { static constexpr int default_cryptoKeySettingsProfiles = 0; /** *@brief Disable (true) reconnection when the device disconnects from Bluetooth. - */ - static const QString bluetooth_no_reconnection; + */ + static const QString bluetooth_no_reconnection; static constexpr bool default_bluetooth_no_reconnection = false; /** *@brief Choose between wheel revolutions (true) and wheel and crank revolutions (false) *when configuring the CSC feature BLE characteristic. - */ - static const QString bike_wheel_revs; + */ + static const QString bike_wheel_revs; static constexpr bool default_bike_wheel_revs = false; - static const QString bluetooth_lastdevice_name; + static const QString bluetooth_lastdevice_name; static const QString default_bluetooth_lastdevice_name; - static const QString bluetooth_lastdevice_address; + static const QString bluetooth_lastdevice_address; static const QString default_bluetooth_lastdevice_address; - static const QString hrm_lastdevice_name; - static const QString default_hrm_lastdevice_name; + static const QString hrm_lastdevice_name; + static const QString default_hrm_lastdevice_name; - static const QString hrm_lastdevice_address; - static const QString default_hrm_lastdevice_address; + static const QString hrm_lastdevice_address; + static const QString default_hrm_lastdevice_address; - static const QString ftms_accessory_address; + static const QString ftms_accessory_address; static const QString default_ftms_accessory_address; - static const QString ftms_accessory_lastdevice_name; + static const QString ftms_accessory_lastdevice_name; static const QString default_ftms_accessory_lastdevice_name; - static const QString csc_sensor_address; - static const QString default_csc_sensor_address; + static const QString csc_sensor_address; + static const QString default_csc_sensor_address; - static const QString csc_sensor_lastdevice_name; - static const QString default_csc_sensor_lastdevice_name; + static const QString csc_sensor_lastdevice_name; + static const QString default_csc_sensor_lastdevice_name; - static const QString power_sensor_lastdevice_name; - static const QString default_power_sensor_lastdevice_name; + static const QString power_sensor_lastdevice_name; + static const QString default_power_sensor_lastdevice_name; - static const QString power_sensor_address; - static const QString default_power_sensor_address; + static const QString power_sensor_address; + static const QString default_power_sensor_address; - static const QString elite_rizer_lastdevice_name; - static const QString default_elite_rizer_lastdevice_name; + static const QString elite_rizer_lastdevice_name; + static const QString default_elite_rizer_lastdevice_name; - static const QString elite_rizer_address; - static const QString default_elite_rizer_address; + static const QString elite_rizer_address; + static const QString default_elite_rizer_address; - static const QString elite_sterzo_smart_lastdevice_name; - static const QString default_elite_sterzo_smart_lastdevice_name; + static const QString elite_sterzo_smart_lastdevice_name; + static const QString default_elite_sterzo_smart_lastdevice_name; - static const QString elite_sterzo_smart_address; - static const QString default_elite_sterzo_smart_address; + static const QString elite_sterzo_smart_address; + static const QString default_elite_sterzo_smart_address; - static const QString strava_accesstoken; + static const QString strava_accesstoken; static const QString default_strava_accesstoken; - static const QString strava_refreshtoken; + static const QString strava_refreshtoken; static const QString default_strava_refreshtoken; - static const QString strava_lastrefresh; + static const QString strava_lastrefresh; static const QString default_strava_lastrefresh; - static const QString strava_expires; + static const QString strava_expires; static const QString default_strava_expires; static const QString code; @@ -89,40 +89,40 @@ class QZSettings { /** *@brief Zoom percentage for the user interface. - */ - static const QString ui_zoom; - static constexpr float default_ui_zoom = 100.0; + */ + static const QString ui_zoom; + static constexpr float default_ui_zoom = 100.0; - /** + /** *@brief Disable (true) or use (false) the device's heart rate service. - */ - static const QString bike_heartrate_service; - static constexpr bool default_bike_heartrate_service = false; + */ + static const QString bike_heartrate_service; + static constexpr bool default_bike_heartrate_service = false; - /** + /** *@brief An offset that can be applied to the resistance from the device. * calculated_resistance = raw_resitance * bike_resistance_gain_f + bike_resistance_offset - */ - static const QString bike_resistance_offset; - static constexpr int default_bike_resistance_offset = 4; + */ + static const QString bike_resistance_offset; + static constexpr int default_bike_resistance_offset = 4; /** *@brief A gain that can be applied to the resistance from the device. * calculated_resistance = raw_resitance * bike_resistance_gain_f + bike_resistance_offset - */ - static const QString bike_resistance_gain_f; - static constexpr float default_bike_resistance_gain_f = 1.0; + */ + static const QString bike_resistance_gain_f; + static constexpr float default_bike_resistance_gain_f = 1.0; - /** + /** *@brief Used to specify of QZ is using Zwift in ERG (workout) Mode. * When supporting this, QZ should communicate the target resistance * (or automatically adjust the device's resistance if it has this capability) to match the target * watts based on the cadence (RPM). In ERG Mode, the changes in inclination should not affect target resistance, * as is the case in Simulation Mode. Default is false. * - */ - static const QString zwift_erg; - static constexpr bool default_zwift_erg = false; + */ + static const QString zwift_erg; + static constexpr bool default_zwift_erg = false; /** *@brief In ERG Mode, Zwift sends a “target output” request. If the output requested doesn’t match the current output @@ -132,9 +132,9 @@ class QZSettings { * The zwift_erg_filter and zwift_erg_filter_down settings are the upper and lower margin before the adjustment of resistance * is communicated. Example: if the zwift_erg_filter and zwift_erg_filter_down filters are set to 10 and the target output is 100 watts, * a change of resistance will only be communicated if the device produces less than 90 Watts or more than 110 Watts. - */ - static const QString zwift_erg_filter; - static constexpr float default_zwift_erg_filter = 10.0; + */ + static const QString zwift_erg_filter; + static constexpr float default_zwift_erg_filter = 10.0; /** *@brief In ERG Mode, Zwift sends a “target output” request. If the output requested doesn’t match the current output @@ -145,70 +145,70 @@ class QZSettings { *is communicated. Example: if the zwift_erg_filter and zwift_erg_filter_down filters are set to 10 and the target output is 100 watts, *a change of resistance will only be communicated if the device produces less than 90 Watts or more than 110 Watts. */ - static const QString zwift_erg_filter_down; - static constexpr float default_zwift_erg_filter_down = 10.0; + static const QString zwift_erg_filter_down; + static constexpr float default_zwift_erg_filter_down = 10.0; - /** + /** *@brief Used to invoke a workaround whereby negative inclination is multiplied by 2. - */ - static const QString zwift_negative_inclination_x2; - static constexpr bool default_zwift_negative_inclination_x2 = false; + */ + static const QString zwift_negative_inclination_x2; + static constexpr bool default_zwift_negative_inclination_x2 = false; /** *@brief An offset that will be applied to the inclination received from the client application. * calculated_inclination = raw_inclination * zwift_inclination_gain + zwift_inclination_offset - */ - static const QString zwift_inclination_offset; - static constexpr float default_zwift_inclination_offset = 0; + */ + static const QString zwift_inclination_offset; + static constexpr float default_zwift_inclination_offset = 0; /** *@brief A gain that will be applied to the inclination received from the client application. * calculated_inclination = raw_inclination * zwift_inclination_gain + zwift_inclination_offset */ - static const QString zwift_inclination_gain; - static constexpr float default_zwift_inclination_gain = 1.0; + static const QString zwift_inclination_gain; + static constexpr float default_zwift_inclination_gain = 1.0; - static const QString echelon_resistance_offset; - static constexpr float default_echelon_resistance_offset = 0; + static const QString echelon_resistance_offset; + static constexpr float default_echelon_resistance_offset = 0; - static const QString echelon_resistance_gain; - static constexpr float default_echelon_resistance_gain = 1.0; + static const QString echelon_resistance_gain; + static constexpr float default_echelon_resistance_gain = 1.0; - /** + /** *@brief Used for some devices to specify that speed should be calculated from power. - */ - static const QString speed_power_based; - static constexpr bool default_speed_power_based = false; + */ + static const QString speed_power_based; + static constexpr bool default_speed_power_based = false; - /** + /** *@brief The resistance to be set when a bike or elliptical trainer first connects. - */ - static const QString bike_resistance_start; - static constexpr int default_bike_resistance_start = 1; + */ + static const QString bike_resistance_start; + static constexpr int default_bike_resistance_start = 1; - /** + /** *@brief The age of the user in years. - */ - static const QString age; - static constexpr int default_age = 35.0; + */ + static const QString age; + static constexpr int default_age = 35.0; /** *@brief The mass of the user in kilograms. Used for power calculations. - */ - static const QString weight; - static constexpr float default_weight = 75.0; + */ + static const QString weight; + static constexpr float default_weight = 75.0; /** *@brief The user's Functional Threshold Power in watts per kilogram. This is a measure of the best average power output the user * could sustain for 1 hour in a time-trial scenario. - */ - static const QString ftp; - static constexpr float default_ftp = 200.0; + */ + static const QString ftp; + static constexpr float default_ftp = 200.0; /** *@brief Email address of the user. - */ - static const QString user_email; + */ + static const QString user_email; /** * @brief Default email address of user. Empty Latin1 string. @@ -216,825 +216,825 @@ class QZSettings { */ static const QString default_user_email; - static const QString user_nickname; - static const QString default_user_nickname; + static const QString user_nickname; + static const QString default_user_nickname; /** *@brief Specifies whether or not to use miles (false) or kilometers (true) as the unit of distance. - */ - static const QString miles_unit; - static constexpr bool default_miles_unit = false; + */ + static const QString miles_unit; + static constexpr bool default_miles_unit = false; - static const QString pause_on_start; - static constexpr bool default_pause_on_start = false; + static const QString pause_on_start; + static constexpr bool default_pause_on_start = false; /** *@brief value for peloton trainrow.forcespeed. - */ - static const QString treadmill_force_speed; - static constexpr bool default_treadmill_force_speed = false; + */ + static const QString treadmill_force_speed; + static constexpr bool default_treadmill_force_speed = false; - static const QString pause_on_start_treadmill; - static constexpr bool default_pause_on_start_treadmill = false; + static const QString pause_on_start_treadmill; + static constexpr bool default_pause_on_start_treadmill = false; /** *@brief Flag to indicate if it should be ignored (true) that the user has stopped doing work. - */ - static const QString continuous_moving; - static constexpr bool default_continuous_moving = false; + */ + static const QString continuous_moving; + static constexpr bool default_continuous_moving = false; - static const QString bike_cadence_sensor; - static constexpr bool default_bike_cadence_sensor = false; + static const QString bike_cadence_sensor; + static constexpr bool default_bike_cadence_sensor = false; - static const QString run_cadence_sensor; - static constexpr bool default_run_cadence_sensor = false; + static const QString run_cadence_sensor; + static constexpr bool default_run_cadence_sensor = false; - static const QString bike_power_sensor; - static constexpr bool default_bike_power_sensor = false; + static const QString bike_power_sensor; + static constexpr bool default_bike_power_sensor = false; static const QString heart_rate_belt_name; - static const QString default_heart_rate_belt_name; + static const QString default_heart_rate_belt_name; /** *@brief Used to ignore the heart rate from some devices. - */ - static const QString heart_ignore_builtin; - static constexpr bool default_heart_ignore_builtin = false; + */ + static const QString heart_ignore_builtin; + static constexpr bool default_heart_ignore_builtin = false; /** * @brief Used to ignore an energy reading from some devices. */ - static const QString kcal_ignore_builtin; - static constexpr bool default_kcal_ignore_builtin = false; + static const QString kcal_ignore_builtin; + static constexpr bool default_kcal_ignore_builtin = false; - static const QString ant_cadence; - static constexpr bool default_ant_cadence = false; + static const QString ant_cadence; + static constexpr bool default_ant_cadence = false; - static const QString ant_heart; - static constexpr bool default_ant_heart = false; + static const QString ant_heart; + static constexpr bool default_ant_heart = false; - static const QString ant_garmin; - static constexpr bool default_ant_garmin = false; + static const QString ant_garmin; + static constexpr bool default_ant_garmin = false; - static const QString top_bar_enabled; - static constexpr bool default_top_bar_enabled = true; - /** + static const QString top_bar_enabled; + static constexpr bool default_top_bar_enabled = true; + /** *@brief The username for logging in to Peloton. - */ - static const QString peloton_username; - static const QString default_peloton_username; + */ + static const QString peloton_username; + static const QString default_peloton_username; - /** + /** *@brief The password for logging in to Peloton. - */ - static const QString peloton_password; - static const QString default_peloton_password; + */ + static const QString peloton_password; + static const QString default_peloton_password; - static const QString peloton_difficulty; - static const QString default_peloton_difficulty; + static const QString peloton_difficulty; + static const QString default_peloton_difficulty; - static const QString peloton_cadence_metric; - static const QString default_peloton_cadence_metric; + static const QString peloton_cadence_metric; + static const QString default_peloton_cadence_metric; - static const QString peloton_heartrate_metric; + static const QString peloton_heartrate_metric; static const QString default_peloton_heartrate_metric; - static const QString peloton_date; + static const QString peloton_date; static const QString default_peloton_date; - static const QString peloton_description_link; - static constexpr bool default_peloton_description_link = true; + static const QString peloton_description_link; + static constexpr bool default_peloton_description_link = true; - static const QString pzp_username; - static const QString default_pzp_username; + static const QString pzp_username; + static const QString default_pzp_username; - static const QString pzp_password; - static const QString default_pzp_password; + static const QString pzp_password; + static const QString default_pzp_password; - static const QString tile_speed_enabled; - static constexpr bool default_tile_speed_enabled = true; + static const QString tile_speed_enabled; + static constexpr bool default_tile_speed_enabled = true; - static const QString tile_speed_order; - static constexpr int default_tile_speed_order = 0; + static const QString tile_speed_order; + static constexpr int default_tile_speed_order = 0; - static const QString tile_inclination_enabled; - static constexpr bool default_tile_inclination_enabled = true; + static const QString tile_inclination_enabled; + static constexpr bool default_tile_inclination_enabled = true; - static const QString tile_inclination_order; - static constexpr int default_tile_inclination_order = 1; + static const QString tile_inclination_order; + static constexpr int default_tile_inclination_order = 1; - static const QString tile_cadence_enabled; - static constexpr bool default_tile_cadence_enabled = true; + static const QString tile_cadence_enabled; + static constexpr bool default_tile_cadence_enabled = true; - static const QString tile_cadence_order; - static constexpr int default_tile_cadence_order = 2; + static const QString tile_cadence_order; + static constexpr int default_tile_cadence_order = 2; - static const QString tile_elevation_enabled; - static constexpr bool default_tile_elevation_enabled = true; + static const QString tile_elevation_enabled; + static constexpr bool default_tile_elevation_enabled = true; - static const QString tile_elevation_order; - static constexpr int default_tile_elevation_order = 3; + static const QString tile_elevation_order; + static constexpr int default_tile_elevation_order = 3; - static const QString tile_calories_enabled; - static constexpr bool default_tile_calories_enabled = true; + static const QString tile_calories_enabled; + static constexpr bool default_tile_calories_enabled = true; - static const QString tile_calories_order; - static constexpr int default_tile_calories_order = 4; + static const QString tile_calories_order; + static constexpr int default_tile_calories_order = 4; - static const QString tile_odometer_enabled; - static constexpr bool default_tile_odometer_enabled = true; + static const QString tile_odometer_enabled; + static constexpr bool default_tile_odometer_enabled = true; - static const QString tile_odometer_order; - static constexpr int default_tile_odometer_order = 5; + static const QString tile_odometer_order; + static constexpr int default_tile_odometer_order = 5; - static const QString tile_pace_enabled; - static constexpr bool default_tile_pace_enabled = true; + static const QString tile_pace_enabled; + static constexpr bool default_tile_pace_enabled = true; - static const QString tile_pace_order; - static constexpr int default_tile_pace_order = 6; + static const QString tile_pace_order; + static constexpr int default_tile_pace_order = 6; - static const QString tile_resistance_enabled; - static constexpr bool default_tile_resistance_enabled = true; + static const QString tile_resistance_enabled; + static constexpr bool default_tile_resistance_enabled = true; - static const QString tile_resistance_order; - static constexpr int default_tile_resistance_order = 7; + static const QString tile_resistance_order; + static constexpr int default_tile_resistance_order = 7; - static const QString tile_watt_enabled; - static constexpr bool default_tile_watt_enabled = true; + static const QString tile_watt_enabled; + static constexpr bool default_tile_watt_enabled = true; - static const QString tile_watt_order; - static constexpr int default_tile_watt_order = 8; + static const QString tile_watt_order; + static constexpr int default_tile_watt_order = 8; - static const QString tile_weight_loss_enabled; - static constexpr bool default_tile_weight_loss_enabled = false; + static const QString tile_weight_loss_enabled; + static constexpr bool default_tile_weight_loss_enabled = false; - static const QString tile_weight_loss_order; - static constexpr int default_tile_weight_loss_order = 24; + static const QString tile_weight_loss_order; + static constexpr int default_tile_weight_loss_order = 24; - static const QString tile_avgwatt_enabled; - static constexpr bool default_tile_avgwatt_enabled = true; + static const QString tile_avgwatt_enabled; + static constexpr bool default_tile_avgwatt_enabled = true; - static const QString tile_avgwatt_order; - static constexpr int default_tile_avgwatt_order = 9; + static const QString tile_avgwatt_order; + static constexpr int default_tile_avgwatt_order = 9; - static const QString tile_ftp_enabled; - static constexpr bool default_tile_ftp_enabled = true; + static const QString tile_ftp_enabled; + static constexpr bool default_tile_ftp_enabled = true; - static const QString tile_ftp_order; - static constexpr int default_tile_ftp_order = 10; + static const QString tile_ftp_order; + static constexpr int default_tile_ftp_order = 10; - static const QString tile_heart_enabled; - static constexpr bool default_tile_heart_enabled = true; + static const QString tile_heart_enabled; + static constexpr bool default_tile_heart_enabled = true; - static const QString tile_heart_order; - static constexpr int default_tile_heart_order = 11; + static const QString tile_heart_order; + static constexpr int default_tile_heart_order = 11; - static const QString tile_fan_enabled; - static constexpr bool default_tile_fan_enabled = true; + static const QString tile_fan_enabled; + static constexpr bool default_tile_fan_enabled = true; - static const QString tile_fan_order; - static constexpr int default_tile_fan_order = 12; + static const QString tile_fan_order; + static constexpr int default_tile_fan_order = 12; - static const QString tile_jouls_enabled; - static constexpr bool default_tile_jouls_enabled = true; + static const QString tile_jouls_enabled; + static constexpr bool default_tile_jouls_enabled = true; - static const QString tile_jouls_order; - static constexpr int default_tile_jouls_order = 13; + static const QString tile_jouls_order; + static constexpr int default_tile_jouls_order = 13; - static const QString tile_elapsed_enabled; - static constexpr bool default_tile_elapsed_enabled = true; + static const QString tile_elapsed_enabled; + static constexpr bool default_tile_elapsed_enabled = true; - static const QString tile_elapsed_order; - static constexpr int default_tile_elapsed_order = 14; + static const QString tile_elapsed_order; + static constexpr int default_tile_elapsed_order = 14; - static const QString tile_lapelapsed_enabled; - static constexpr bool default_tile_lapelapsed_enabled = false; + static const QString tile_lapelapsed_enabled; + static constexpr bool default_tile_lapelapsed_enabled = false; - static const QString tile_lapelapsed_order; - static constexpr int default_tile_lapelapsed_order = 17; + static const QString tile_lapelapsed_order; + static constexpr int default_tile_lapelapsed_order = 17; - static const QString tile_moving_time_enabled; - static constexpr bool default_tile_moving_time_enabled = false; + static const QString tile_moving_time_enabled; + static constexpr bool default_tile_moving_time_enabled = false; - static const QString tile_moving_time_order; - static constexpr int default_tile_moving_time_order = 21; + static const QString tile_moving_time_order; + static constexpr int default_tile_moving_time_order = 21; - static const QString tile_peloton_offset_enabled; - static constexpr bool default_tile_peloton_offset_enabled = false; + static const QString tile_peloton_offset_enabled; + static constexpr bool default_tile_peloton_offset_enabled = false; - static const QString tile_peloton_offset_order; - static constexpr int default_tile_peloton_offset_order = 22; + static const QString tile_peloton_offset_order; + static constexpr int default_tile_peloton_offset_order = 22; - static const QString tile_peloton_difficulty_enabled; - static constexpr bool default_tile_peloton_difficulty_enabled = false; + static const QString tile_peloton_difficulty_enabled; + static constexpr bool default_tile_peloton_difficulty_enabled = false; - static const QString tile_peloton_difficulty_order; - static constexpr int default_tile_peloton_difficulty_order = 32; + static const QString tile_peloton_difficulty_order; + static constexpr int default_tile_peloton_difficulty_order = 32; - static const QString tile_peloton_resistance_enabled; - static constexpr bool default_tile_peloton_resistance_enabled = true; + static const QString tile_peloton_resistance_enabled; + static constexpr bool default_tile_peloton_resistance_enabled = true; - static const QString tile_peloton_resistance_order; - static constexpr int default_tile_peloton_resistance_order = 15; + static const QString tile_peloton_resistance_order; + static constexpr int default_tile_peloton_resistance_order = 15; - static const QString tile_datetime_enabled; - static constexpr bool default_tile_datetime_enabled = true; + static const QString tile_datetime_enabled; + static constexpr bool default_tile_datetime_enabled = true; - static const QString tile_datetime_order; - static constexpr int default_tile_datetime_order = 16; + static const QString tile_datetime_order; + static constexpr int default_tile_datetime_order = 16; - static const QString tile_target_resistance_enabled; - static constexpr bool default_tile_target_resistance_enabled = true; + static const QString tile_target_resistance_enabled; + static constexpr bool default_tile_target_resistance_enabled = true; - static const QString tile_target_resistance_order; - static constexpr int default_tile_target_resistance_order = 15; + static const QString tile_target_resistance_order; + static constexpr int default_tile_target_resistance_order = 15; - static const QString tile_target_peloton_resistance_enabled; - static constexpr bool default_tile_target_peloton_resistance_enabled = false; + static const QString tile_target_peloton_resistance_enabled; + static constexpr bool default_tile_target_peloton_resistance_enabled = false; - static const QString tile_target_peloton_resistance_order; - static constexpr int default_tile_target_peloton_resistance_order = 21; + static const QString tile_target_peloton_resistance_order; + static constexpr int default_tile_target_peloton_resistance_order = 21; - static const QString tile_target_cadence_enabled; - static constexpr bool default_tile_target_cadence_enabled = false; + static const QString tile_target_cadence_enabled; + static constexpr bool default_tile_target_cadence_enabled = false; - static const QString tile_target_cadence_order; - static constexpr int default_tile_target_cadence_order = 19; + static const QString tile_target_cadence_order; + static constexpr int default_tile_target_cadence_order = 19; - static const QString tile_target_power_enabled; - static constexpr bool default_tile_target_power_enabled = false; + static const QString tile_target_power_enabled; + static constexpr bool default_tile_target_power_enabled = false; - static const QString tile_target_power_order; - static constexpr int default_tile_target_power_order = 20; + static const QString tile_target_power_order; + static constexpr int default_tile_target_power_order = 20; - static const QString tile_target_zone_enabled; - static constexpr bool default_tile_target_zone_enabled = false; + static const QString tile_target_zone_enabled; + static constexpr bool default_tile_target_zone_enabled = false; - static const QString tile_target_zone_order; - static constexpr int default_tile_target_zone_order = 24; + static const QString tile_target_zone_order; + static constexpr int default_tile_target_zone_order = 24; - static const QString tile_target_speed_enabled; - static constexpr bool default_tile_target_speed_enabled = false; + static const QString tile_target_speed_enabled; + static constexpr bool default_tile_target_speed_enabled = false; - static const QString tile_target_speed_order; - static constexpr int default_tile_target_speed_order = 27; + static const QString tile_target_speed_order; + static constexpr int default_tile_target_speed_order = 27; - static const QString tile_target_incline_enabled; - static constexpr bool default_tile_target_incline_enabled = false; + static const QString tile_target_incline_enabled; + static constexpr bool default_tile_target_incline_enabled = false; - static const QString tile_target_incline_order; - static constexpr int default_tile_target_incline_order = 28; + static const QString tile_target_incline_order; + static constexpr int default_tile_target_incline_order = 28; - static const QString tile_strokes_count_enabled; - static constexpr bool default_tile_strokes_count_enabled = false; + static const QString tile_strokes_count_enabled; + static constexpr bool default_tile_strokes_count_enabled = false; - static const QString tile_strokes_count_order; - static constexpr int default_tile_strokes_count_order = 22; + static const QString tile_strokes_count_order; + static constexpr int default_tile_strokes_count_order = 22; - static const QString tile_strokes_length_enabled; - static constexpr bool default_tile_strokes_length_enabled = false; + static const QString tile_strokes_length_enabled; + static constexpr bool default_tile_strokes_length_enabled = false; - static const QString tile_strokes_length_order; - static constexpr int default_tile_strokes_length_order = 23; + static const QString tile_strokes_length_order; + static constexpr int default_tile_strokes_length_order = 23; - static const QString tile_watt_kg_enabled; - static constexpr bool default_tile_watt_kg_enabled = false; + static const QString tile_watt_kg_enabled; + static constexpr bool default_tile_watt_kg_enabled = false; - static const QString tile_watt_kg_order; - static constexpr int default_tile_watt_kg_order = 25; + static const QString tile_watt_kg_order; + static constexpr int default_tile_watt_kg_order = 25; - static const QString tile_gears_enabled; - static constexpr bool default_tile_gears_enabled = false; + static const QString tile_gears_enabled; + static constexpr bool default_tile_gears_enabled = false; - static const QString tile_gears_order; - static constexpr int default_tile_gears_order = 26; + static const QString tile_gears_order; + static constexpr int default_tile_gears_order = 26; - static const QString tile_remainingtimetrainprogramrow_enabled; - static constexpr bool default_tile_remainingtimetrainprogramrow_enabled = false; + static const QString tile_remainingtimetrainprogramrow_enabled; + static constexpr bool default_tile_remainingtimetrainprogramrow_enabled = false; - static const QString tile_remainingtimetrainprogramrow_order; - static constexpr int default_tile_remainingtimetrainprogramrow_order = 27; + static const QString tile_remainingtimetrainprogramrow_order; + static constexpr int default_tile_remainingtimetrainprogramrow_order = 27; - static const QString tile_nextrowstrainprogram_enabled; - static constexpr bool default_tile_nextrowstrainprogram_enabled = false; + static const QString tile_nextrowstrainprogram_enabled; + static constexpr bool default_tile_nextrowstrainprogram_enabled = false; - static const QString tile_nextrowstrainprogram_order; - static constexpr int default_tile_nextrowstrainprogram_order = 31; + static const QString tile_nextrowstrainprogram_order; + static constexpr int default_tile_nextrowstrainprogram_order = 31; - static const QString tile_mets_enabled; - static constexpr bool default_tile_mets_enabled = false; + static const QString tile_mets_enabled; + static constexpr bool default_tile_mets_enabled = false; - static const QString tile_mets_order; - static constexpr int default_tile_mets_order = 28; + static const QString tile_mets_order; + static constexpr int default_tile_mets_order = 28; - static const QString tile_targetmets_enabled; - static constexpr bool default_tile_targetmets_enabled = false; + static const QString tile_targetmets_enabled; + static constexpr bool default_tile_targetmets_enabled = false; - static const QString tile_targetmets_order; - static constexpr int default_tile_targetmets_order = 29; + static const QString tile_targetmets_order; + static constexpr int default_tile_targetmets_order = 29; - static const QString tile_steering_angle_enabled; - static constexpr bool default_tile_steering_angle_enabled = false; + static const QString tile_steering_angle_enabled; + static constexpr bool default_tile_steering_angle_enabled = false; - static const QString tile_steering_angle_order; - static constexpr int default_tile_steering_angle_order = 30; + static const QString tile_steering_angle_order; + static constexpr int default_tile_steering_angle_order = 30; - static const QString tile_pid_hr_enabled; - static constexpr bool default_tile_pid_hr_enabled = false; + static const QString tile_pid_hr_enabled; + static constexpr bool default_tile_pid_hr_enabled = false; - static const QString tile_pid_hr_order; - static constexpr int default_tile_pid_hr_order = 31; + static const QString tile_pid_hr_order; + static constexpr int default_tile_pid_hr_order = 31; - static const QString heart_rate_zone1; - static constexpr float default_heart_rate_zone1 = 70.0; + static const QString heart_rate_zone1; + static constexpr float default_heart_rate_zone1 = 70.0; - static const QString heart_rate_zone2; - static constexpr float default_heart_rate_zone2 = 80.0; + static const QString heart_rate_zone2; + static constexpr float default_heart_rate_zone2 = 80.0; - static const QString heart_rate_zone3; - static constexpr float default_heart_rate_zone3 = 90.0; + static const QString heart_rate_zone3; + static constexpr float default_heart_rate_zone3 = 90.0; - static const QString heart_rate_zone4; - static constexpr float default_heart_rate_zone4 = 100.0; + static const QString heart_rate_zone4; + static constexpr float default_heart_rate_zone4 = 100.0; - static const QString heart_max_override_enable; - static constexpr bool default_heart_max_override_enable = false; + static const QString heart_max_override_enable; + static constexpr bool default_heart_max_override_enable = false; - static const QString heart_max_override_value; - static constexpr float default_heart_max_override_value = 195.0; + static const QString heart_max_override_value; + static constexpr float default_heart_max_override_value = 195.0; - static const QString peloton_gain; - static constexpr float default_peloton_gain = 1.0; + static const QString peloton_gain; + static constexpr float default_peloton_gain = 1.0; - static const QString peloton_offset; - static constexpr float default_peloton_offset = 0; + static const QString peloton_offset; + static constexpr float default_peloton_offset = 0; - static const QString treadmill_pid_heart_zone; - static const QString default_treadmill_pid_heart_zone; + static const QString treadmill_pid_heart_zone; + static const QString default_treadmill_pid_heart_zone; /** *@brief 1 mile time goal, for a training program with the speed control. - */ - static const QString pacef_1mile; - static constexpr float default_pacef_1mile = 250; + */ + static const QString pacef_1mile; + static constexpr float default_pacef_1mile = 250; /** *@brief 5 km time goal, for a training program with the speed control. - */ - static const QString pacef_5km; - static constexpr float default_pacef_5km = 300; + */ + static const QString pacef_5km; + static constexpr float default_pacef_5km = 300; /** *@brief 10 km time goal, for a training program with the speed control. - */ - static const QString pacef_10km; - static constexpr float default_pacef_10km = 320; + */ + static const QString pacef_10km; + static constexpr float default_pacef_10km = 320; /** *@brief pacef_1mile, but for half-marathon distance, for a training program with the speed control. - */ - static const QString pacef_halfmarathon; - static constexpr float default_pacef_halfmarathon = 340; + */ + static const QString pacef_halfmarathon; + static constexpr float default_pacef_halfmarathon = 340; /** *@brief pacef_1mile, but for marathon distance, for a training program with the speed control. - */ - static const QString pacef_marathon; - static constexpr float default_pacef_marathon = 360; + */ + static const QString pacef_marathon; + static constexpr float default_pacef_marathon = 360; - /** + /** *@brief default pace to be used when the ZWO file does not indicate a precise pace. *Text values, i.e. "1 mile", "5 km", "10 km", "Half Marathon" - */ - static const QString pace_default; + */ + static const QString pace_default; static const QString default_pace_default; - static const QString domyos_treadmill_buttons; - static constexpr bool default_domyos_treadmill_buttons = false; + static const QString domyos_treadmill_buttons; + static constexpr bool default_domyos_treadmill_buttons = false; - static const QString domyos_treadmill_distance_display; - static constexpr bool default_domyos_treadmill_distance_display = true; + static const QString domyos_treadmill_distance_display; + static constexpr bool default_domyos_treadmill_distance_display = true; - static const QString domyos_treadmill_display_invert; - static constexpr bool default_domyos_treadmill_display_invert = false; + static const QString domyos_treadmill_display_invert; + static constexpr bool default_domyos_treadmill_display_invert = false; - static const QString domyos_bike_cadence_filter; - static constexpr float default_domyos_bike_cadence_filter = 0.0; + static const QString domyos_bike_cadence_filter; + static constexpr float default_domyos_bike_cadence_filter = 0.0; - static const QString domyos_bike_display_calories; - static constexpr bool default_domyos_bike_display_calories = true; + static const QString domyos_bike_display_calories; + static constexpr bool default_domyos_bike_display_calories = true; - static const QString domyos_elliptical_speed_ratio; - static constexpr float default_domyos_elliptical_speed_ratio = 1.0; + static const QString domyos_elliptical_speed_ratio; + static constexpr float default_domyos_elliptical_speed_ratio = 1.0; - static const QString eslinker_cadenza; - static constexpr bool default_eslinker_cadenza = true; - static const QString eslinker_ypoo; - static constexpr bool default_eslinker_ypoo = false; - /** + static const QString eslinker_cadenza; + static constexpr bool default_eslinker_cadenza = true; + static const QString eslinker_ypoo; + static constexpr bool default_eslinker_ypoo = false; + /** *@brief Choose between the standard and MGARCEA watt table. - */ - static const QString echelon_watttable; - static const QString default_echelon_watttable; + */ + static const QString echelon_watttable; + static const QString default_echelon_watttable; - static const QString proform_wheel_ratio; - static constexpr float default_proform_wheel_ratio = 0.33; + static const QString proform_wheel_ratio; + static constexpr float default_proform_wheel_ratio = 0.33; - static const QString proform_tour_de_france_clc; - static constexpr bool default_proform_tour_de_france_clc = false; + static const QString proform_tour_de_france_clc; + static constexpr bool default_proform_tour_de_france_clc = false; - static const QString proform_tdf_jonseed_watt; - static constexpr bool default_proform_tdf_jonseed_watt = false; + static const QString proform_tdf_jonseed_watt; + static constexpr bool default_proform_tdf_jonseed_watt = false; - static const QString proform_studio; - static constexpr bool default_proform_studio = false; + static const QString proform_studio; + static constexpr bool default_proform_studio = false; - static const QString proform_tdf_10; - static constexpr bool default_proform_tdf_10 = false; + static const QString proform_tdf_10; + static constexpr bool default_proform_tdf_10 = false; - static const QString horizon_gr7_cadence_multiplier; - static constexpr double default_horizon_gr7_cadence_multiplier = 1.0; + static const QString horizon_gr7_cadence_multiplier; + static constexpr double default_horizon_gr7_cadence_multiplier = 1.0; - static const QString fitshow_user_id; - static constexpr int default_fitshow_user_id = 0x13AA; + static const QString fitshow_user_id; + static constexpr int default_fitshow_user_id = 0x13AA; - static const QString inspire_peloton_formula; - static constexpr bool default_inspire_peloton_formula = false; + static const QString inspire_peloton_formula; + static constexpr bool default_inspire_peloton_formula = false; - static const QString inspire_peloton_formula2; - static constexpr bool default_inspire_peloton_formula2 = false; + static const QString inspire_peloton_formula2; + static constexpr bool default_inspire_peloton_formula2 = false; - static const QString hammer_racer_s; - static constexpr bool default_hammer_racer_s = false; + static const QString hammer_racer_s; + static constexpr bool default_hammer_racer_s = false; - static const QString pafers_treadmill; - static constexpr bool default_pafers_treadmill = false; + static const QString pafers_treadmill; + static constexpr bool default_pafers_treadmill = false; - static const QString yesoul_peloton_formula; - static constexpr bool default_yesoul_peloton_formula = false; + static const QString yesoul_peloton_formula; + static constexpr bool default_yesoul_peloton_formula = false; - static const QString nordictrack_10_treadmill; - static constexpr bool default_nordictrack_10_treadmill = true; + static const QString nordictrack_10_treadmill; + static constexpr bool default_nordictrack_10_treadmill = true; - static const QString nordictrack_t65s_treadmill; - static constexpr bool default_nordictrack_t65s_treadmill = false; + static const QString nordictrack_t65s_treadmill; + static constexpr bool default_nordictrack_t65s_treadmill = false; - //static const QString proform_treadmill_995i; - //static constexpr bool default_proform_treadmill_995i = false; + //static const QString proform_treadmill_995i; + //static constexpr bool default_proform_treadmill_995i = false; - static const QString toorx_3_0; - static constexpr bool default_toorx_3_0 = false; + static const QString toorx_3_0; + static constexpr bool default_toorx_3_0 = false; - static const QString toorx_65s_evo; - static constexpr bool default_toorx_65s_evo = false; + static const QString toorx_65s_evo; + static constexpr bool default_toorx_65s_evo = false; - static const QString jtx_fitness_sprint_treadmill; - static constexpr bool default_jtx_fitness_sprint_treadmill = false; + static const QString jtx_fitness_sprint_treadmill; + static constexpr bool default_jtx_fitness_sprint_treadmill = false; - static const QString dkn_endurun_treadmill; - static constexpr bool default_dkn_endurun_treadmill = false; + static const QString dkn_endurun_treadmill; + static constexpr bool default_dkn_endurun_treadmill = false; - static const QString trx_route_key; - static constexpr bool default_trx_route_key = false; + static const QString trx_route_key; + static constexpr bool default_trx_route_key = false; - static const QString bh_spada_2; - static constexpr bool default_bh_spada_2 = false; + static const QString bh_spada_2; + static constexpr bool default_bh_spada_2 = false; - static const QString toorx_bike; - static constexpr bool default_toorx_bike = false; + static const QString toorx_bike; + static constexpr bool default_toorx_bike = false; - static const QString toorx_ftms; - static constexpr bool default_toorx_ftms = false; + static const QString toorx_ftms; + static constexpr bool default_toorx_ftms = false; - static const QString jll_IC400_bike; - static constexpr bool default_jll_IC400_bike = false; + static const QString jll_IC400_bike; + static constexpr bool default_jll_IC400_bike = false; - static const QString fytter_ri08_bike; - static constexpr bool default_fytter_ri08_bike = false; + static const QString fytter_ri08_bike; + static constexpr bool default_fytter_ri08_bike = false; - static const QString asviva_bike; - static constexpr bool default_asviva_bike = false; + static const QString asviva_bike; + static constexpr bool default_asviva_bike = false; - static const QString hertz_xr_770; - static constexpr bool default_hertz_xr_770 = false; + static const QString hertz_xr_770; + static constexpr bool default_hertz_xr_770 = false; - static const QString m3i_bike_id; - static constexpr int default_m3i_bike_id = 256; + static const QString m3i_bike_id; + static constexpr int default_m3i_bike_id = 256; - static const QString m3i_bike_speed_buffsize; - static constexpr int default_m3i_bike_speed_buffsize = 90; + static const QString m3i_bike_speed_buffsize; + static constexpr int default_m3i_bike_speed_buffsize = 90; - static const QString m3i_bike_qt_search; - static constexpr bool default_m3i_bike_qt_search = false; + static const QString m3i_bike_qt_search; + static constexpr bool default_m3i_bike_qt_search = false; - static const QString m3i_bike_kcal; - static constexpr bool default_m3i_bike_kcal = true; + static const QString m3i_bike_kcal; + static constexpr bool default_m3i_bike_kcal = true; - static const QString snode_bike; - static constexpr bool default_snode_bike = false; + static const QString snode_bike; + static constexpr bool default_snode_bike = false; - static const QString fitplus_bike; - static constexpr bool default_fitplus_bike = false; + static const QString fitplus_bike; + static constexpr bool default_fitplus_bike = false; - static const QString virtufit_etappe; - static constexpr bool default_virtufit_etappe = false; + static const QString virtufit_etappe; + static constexpr bool default_virtufit_etappe = false; - static const QString flywheel_filter; - static constexpr int default_flywheel_filter = 2; + static const QString flywheel_filter; + static constexpr int default_flywheel_filter = 2; - static const QString flywheel_life_fitness_ic8; - static constexpr bool default_flywheel_life_fitness_ic8 = false; + static const QString flywheel_life_fitness_ic8; + static constexpr bool default_flywheel_life_fitness_ic8 = false; - static const QString sole_treadmill_inclination; - static constexpr bool default_sole_treadmill_inclination = false; + static const QString sole_treadmill_inclination; + static constexpr bool default_sole_treadmill_inclination = false; - static const QString sole_treadmill_miles; - static constexpr bool default_sole_treadmill_miles = true; + static const QString sole_treadmill_miles; + static constexpr bool default_sole_treadmill_miles = true; - static const QString sole_treadmill_f65; - static constexpr bool default_sole_treadmill_f65 = false; + static const QString sole_treadmill_f65; + static constexpr bool default_sole_treadmill_f65 = false; - static const QString sole_treadmill_f63; - static constexpr bool default_sole_treadmill_f63 = false; + static const QString sole_treadmill_f63; + static constexpr bool default_sole_treadmill_f63 = false; - static const QString sole_treadmill_tt8; - static constexpr bool default_sole_treadmill_tt8 = false; + static const QString sole_treadmill_tt8; + static constexpr bool default_sole_treadmill_tt8 = false; - static const QString schwinn_bike_resistance; - static constexpr bool default_schwinn_bike_resistance = false; + static const QString schwinn_bike_resistance; + static constexpr bool default_schwinn_bike_resistance = false; - static const QString schwinn_bike_resistance_v2; + static const QString schwinn_bike_resistance_v2; static constexpr bool default_schwinn_bike_resistance_v2 = false; - static const QString technogym_myrun_treadmill_experimental; - static constexpr bool default_technogym_myrun_treadmill_experimental = false; + static const QString technogym_myrun_treadmill_experimental; + static constexpr bool default_technogym_myrun_treadmill_experimental = false; - static const QString trainprogram_random; - static constexpr bool default_trainprogram_random = false; + static const QString trainprogram_random; + static constexpr bool default_trainprogram_random = false; - static const QString trainprogram_total; - static constexpr int default_trainprogram_total = 60; + static const QString trainprogram_total; + static constexpr int default_trainprogram_total = 60; - static const QString trainprogram_period_seconds; - static constexpr float default_trainprogram_period_seconds = 60; + static const QString trainprogram_period_seconds; + static constexpr float default_trainprogram_period_seconds = 60; - static const QString trainprogram_speed_min; - static constexpr float default_trainprogram_speed_min = 8; + static const QString trainprogram_speed_min; + static constexpr float default_trainprogram_speed_min = 8; - static const QString trainprogram_speed_max; - static constexpr float default_trainprogram_speed_max = 16; + static const QString trainprogram_speed_max; + static constexpr float default_trainprogram_speed_max = 16; - static const QString trainprogram_incline_min; - static constexpr float default_trainprogram_incline_min = 0; + static const QString trainprogram_incline_min; + static constexpr float default_trainprogram_incline_min = 0; - static const QString trainprogram_incline_max; - static constexpr float default_trainprogram_incline_max = 15; + static const QString trainprogram_incline_max; + static constexpr float default_trainprogram_incline_max = 15; - static const QString trainprogram_resistance_min; - static constexpr float default_trainprogram_resistance_min = 1; + static const QString trainprogram_resistance_min; + static constexpr float default_trainprogram_resistance_min = 1; - static const QString trainprogram_resistance_max; - static constexpr float default_trainprogram_resistance_max = 32; + static const QString trainprogram_resistance_max; + static constexpr float default_trainprogram_resistance_max = 32; /** * @brief Adjusts value in a metric object that's configured specifically for measuring WATTS. */ - static const QString watt_offset; - static constexpr float default_watt_offset = 0; + static const QString watt_offset; + static constexpr float default_watt_offset = 0; /** * @brief Adjusts value in a metric object that's configured specifically for measuring WATTS. */ - static const QString watt_gain; - static constexpr float default_watt_gain = 1; + static const QString watt_gain; + static constexpr float default_watt_gain = 1; - static const QString power_avg_5s; - static constexpr bool default_power_avg_5s = false; + static const QString power_avg_5s; + static constexpr bool default_power_avg_5s = false; - static const QString instant_power_on_pause; - static constexpr bool default_instant_power_on_pause = false; + static const QString instant_power_on_pause; + static constexpr bool default_instant_power_on_pause = false; /** * @brief Adjusts value in a metric object that's configured specifically for measuring SPEED. */ - static const QString speed_offset; - static constexpr float default_speed_offset = 0; + static const QString speed_offset; + static constexpr float default_speed_offset = 0; /** * @brief Adjusts value in a metric object that's configured specifically for measuring SPEED. */ - static const QString speed_gain; - static constexpr float default_speed_gain = 1; + static const QString speed_gain; + static constexpr float default_speed_gain = 1; - static const QString filter_device; - static const QString default_filter_device; + static const QString filter_device; + static const QString default_filter_device; - static const QString strava_suffix; + static const QString strava_suffix; static const QString default_strava_suffix; - static const QString cadence_sensor_name; - static const QString default_cadence_sensor_name; + static const QString cadence_sensor_name; + static const QString default_cadence_sensor_name; - static const QString cadence_sensor_as_bike; - static constexpr bool default_cadence_sensor_as_bike = false; + static const QString cadence_sensor_as_bike; + static constexpr bool default_cadence_sensor_as_bike = false; - static const QString cadence_sensor_speed_ratio; - static constexpr float default_cadence_sensor_speed_ratio = 0.33; + static const QString cadence_sensor_speed_ratio; + static constexpr float default_cadence_sensor_speed_ratio = 0.33; - static const QString power_hr_pwr1; - static constexpr float default_power_hr_pwr1 = 200; + static const QString power_hr_pwr1; + static constexpr float default_power_hr_pwr1 = 200; - static const QString power_hr_hr1; - static constexpr float default_power_hr_hr1 = 150; + static const QString power_hr_hr1; + static constexpr float default_power_hr_hr1 = 150; - static const QString power_hr_pwr2; - static constexpr float default_power_hr_pwr2 = 230; + static const QString power_hr_pwr2; + static constexpr float default_power_hr_pwr2 = 230; - static const QString power_hr_hr2; - static constexpr float default_power_hr_hr2 = 170; + static const QString power_hr_hr2; + static constexpr float default_power_hr_hr2 = 170; - static const QString power_sensor_name; - static const QString default_power_sensor_name; + static const QString power_sensor_name; + static const QString default_power_sensor_name; - static const QString power_sensor_as_bike; - static constexpr bool default_power_sensor_as_bike = false; + static const QString power_sensor_as_bike; + static constexpr bool default_power_sensor_as_bike = false; - static const QString power_sensor_as_treadmill; - static constexpr bool default_power_sensor_as_treadmill = false; + static const QString power_sensor_as_treadmill; + static constexpr bool default_power_sensor_as_treadmill = false; - static const QString powr_sensor_running_cadence_double; - static constexpr bool default_powr_sensor_running_cadence_double = false; + static const QString powr_sensor_running_cadence_double; + static constexpr bool default_powr_sensor_running_cadence_double = false; - static const QString elite_rizer_name; - static const QString default_elite_rizer_name; + static const QString elite_rizer_name; + static const QString default_elite_rizer_name; - static const QString elite_sterzo_smart_name; - static const QString default_elite_sterzo_smart_name; + static const QString elite_sterzo_smart_name; + static const QString default_elite_sterzo_smart_name; - static const QString ftms_accessory_name; - static const QString default_ftms_accessory_name; + static const QString ftms_accessory_name; + static const QString default_ftms_accessory_name; - static const QString ss2k_shift_step; - static constexpr float default_ss2k_shift_step = 900; + static const QString ss2k_shift_step; + static constexpr float default_ss2k_shift_step = 900; - static const QString fitmetria_fanfit_enable; - static constexpr bool default_fitmetria_fanfit_enable = false; + static const QString fitmetria_fanfit_enable; + static constexpr bool default_fitmetria_fanfit_enable = false; - static const QString fitmetria_fanfit_mode; - static const QString default_fitmetria_fanfit_mode; + static const QString fitmetria_fanfit_mode; + static const QString default_fitmetria_fanfit_mode; - static const QString fitmetria_fanfit_min; - static constexpr float default_fitmetria_fanfit_min = 0; + static const QString fitmetria_fanfit_min; + static constexpr float default_fitmetria_fanfit_min = 0; - static const QString fitmetria_fanfit_max; - static constexpr float default_fitmetria_fanfit_max = 100; - /** + static const QString fitmetria_fanfit_max; + static constexpr float default_fitmetria_fanfit_max = 100; + /** *@brief Indicates if the virtual device should send resistance requests to the bike. - */ - static const QString virtualbike_forceresistance; - static constexpr bool default_virtualbike_forceresistance = true; - /** + */ + static const QString virtualbike_forceresistance; + static constexpr bool default_virtualbike_forceresistance = true; + /** *@brief Troubleshooting setting. Should be false unless advised by QZ tech support. - */ - static const QString bluetooth_relaxed; - static constexpr bool default_bluetooth_relaxed = false; - /** + */ + static const QString bluetooth_relaxed; + static constexpr bool default_bluetooth_relaxed = false; + /** *@brief Troubleshooting setting. Should be false unless advised by QZ tech support. - */ - static const QString bluetooth_30m_hangs; - static constexpr bool default_bluetooth_30m_hangs = false; + */ + static const QString bluetooth_30m_hangs; + static constexpr bool default_bluetooth_30m_hangs = false; - static const QString battery_service; - static constexpr bool default_battery_service = false; + static const QString battery_service; + static constexpr bool default_battery_service = false; /** *@brief Experimental feature. Not recommended to use. - */ - static const QString service_changed; - static constexpr bool default_service_changed = false; + */ + static const QString service_changed; + static constexpr bool default_service_changed = false; /** *@brief Enable/disable the virtual device that connects QZ to the client app. - */ - static const QString virtual_device_enabled; - static constexpr bool default_virtual_device_enabled = true; - /** + */ + static const QString virtual_device_enabled; + static constexpr bool default_virtual_device_enabled = true; + /** *@brief Enable/disable the Bluetooth connectivity of the virtual device that connects QZ to the client app. - */ - static const QString virtual_device_bluetooth; - static constexpr bool default_virtual_device_bluetooth = true; + */ + static const QString virtual_device_bluetooth; + static constexpr bool default_virtual_device_bluetooth = true; - static const QString ios_peloton_workaround; - static constexpr bool default_ios_peloton_workaround = true; + static const QString ios_peloton_workaround; + static constexpr bool default_ios_peloton_workaround = true; - static const QString android_wakelock; - static constexpr bool default_android_wakelock = true; - /** + static const QString android_wakelock; + static constexpr bool default_android_wakelock = true; + /** *@brief Specifies if the debug log file will be written. - */ - static const QString log_debug; - static constexpr bool default_log_debug = false; - /** + */ + static const QString log_debug; + static constexpr bool default_log_debug = false; + /** *@brief Force QZ to communicate ONLY the Heart Rate metric to third-party apps. - */ - static const QString virtual_device_onlyheart; - static constexpr bool default_virtual_device_onlyheart = false; - /** + */ + static const QString virtual_device_onlyheart; + static constexpr bool default_virtual_device_onlyheart = false; + /** *@brief Enables QZ to communicate with the Echelon app. *This setting can only be used with iOS running QZ and iOS running the Echelon app. - */ - static const QString virtual_device_echelon; - static constexpr bool default_virtual_device_echelon = false; - /** + */ + static const QString virtual_device_echelon; + static constexpr bool default_virtual_device_echelon = false; + /** *@brief Enables a virtual bluetooth bridge to the iFit App. - */ - static const QString virtual_device_ifit; - static constexpr bool default_virtual_device_ifit = false; - /** + */ + static const QString virtual_device_ifit; + static constexpr bool default_virtual_device_ifit = false; + /** *@brief Instructs QZ to send a rower Bluetooth profile instead of a bike profile to third party apps that support rowing *(examples: Kinomap and BitGym). This should be off for Zwift. - */ - static const QString virtual_device_rower; - static constexpr bool default_virtual_device_rower = false; - /** + */ + static const QString virtual_device_rower; + static constexpr bool default_virtual_device_rower = false; + /** *@brief Used to force a non-bike device to be presented to client apps as a bike. - */ - static const QString virtual_device_force_bike; - static constexpr bool default_virtual_device_force_bike = false; + */ + static const QString virtual_device_force_bike; + static constexpr bool default_virtual_device_force_bike = false; - static const QString volume_change_gears; - static constexpr bool default_volume_change_gears = false; + static const QString volume_change_gears; + static constexpr bool default_volume_change_gears = false; - static const QString applewatch_fakedevice; - static constexpr bool default_applewatch_fakedevice = false; + static const QString applewatch_fakedevice; + static constexpr bool default_applewatch_fakedevice = false; /** *@brief Minimum target resistance for ERG mode. - */ - static const QString zwift_erg_resistance_down; - static constexpr float default_zwift_erg_resistance_down = 0.0; + */ + static const QString zwift_erg_resistance_down; + static constexpr float default_zwift_erg_resistance_down = 0.0; /** *@brief Maximum targe resistance for ERG mode. - */ - static const QString zwift_erg_resistance_up; - static constexpr float default_zwift_erg_resistance_up = 999.0; + */ + static const QString zwift_erg_resistance_up; + static constexpr float default_zwift_erg_resistance_up = 999.0; - static const QString horizon_paragon_x; - static constexpr bool default_horizon_paragon_x = false; + static const QString horizon_paragon_x; + static constexpr bool default_horizon_paragon_x = false; - static const QString treadmill_step_speed; - static constexpr float default_treadmill_step_speed = 0.5; + static const QString treadmill_step_speed; + static constexpr float default_treadmill_step_speed = 0.5; - static const QString treadmill_step_incline; - static constexpr float default_treadmill_step_incline = 0.5; + static const QString treadmill_step_incline; + static constexpr float default_treadmill_step_incline = 0.5; - static const QString fitshow_anyrun; - static constexpr bool default_fitshow_anyrun = false; + static const QString fitshow_anyrun; + static constexpr bool default_fitshow_anyrun = false; - static const QString nordictrack_s30_treadmill; - static constexpr bool default_nordictrack_s30_treadmill = false; + static const QString nordictrack_s30_treadmill; + static constexpr bool default_nordictrack_s30_treadmill = false; // from version 2.10.23 - // not used anymore because it's an elliptical not a treadmill. Don't remove this - // it will cause corruption in the settings + // not used anymore because it's an elliptical not a treadmill. Don't remove this + // it will cause corruption in the settings //static const QString nordictrack_fs5i_treadmill; //static constexpr bool default_nordictrack_fs5i_treadmill = false; - static const QString renpho_peloton_conversion_v2; - static constexpr bool default_renpho_peloton_conversion_v2 = false; + static const QString renpho_peloton_conversion_v2; + static constexpr bool default_renpho_peloton_conversion_v2 = false; - static const QString ss2k_resistance_sample_1; - static constexpr float default_ss2k_resistance_sample_1 = 20; + static const QString ss2k_resistance_sample_1; + static constexpr float default_ss2k_resistance_sample_1 = 20; - static const QString ss2k_shift_step_sample_1; - static constexpr float default_ss2k_shift_step_sample_1 = 0; + static const QString ss2k_shift_step_sample_1; + static constexpr float default_ss2k_shift_step_sample_1 = 0; - static const QString ss2k_resistance_sample_2; - static constexpr float default_ss2k_resistance_sample_2 = 30; + static const QString ss2k_resistance_sample_2; + static constexpr float default_ss2k_resistance_sample_2 = 30; - static const QString ss2k_shift_step_sample_2; - static constexpr float default_ss2k_shift_step_sample_2 = 0; + static const QString ss2k_shift_step_sample_2; + static constexpr float default_ss2k_shift_step_sample_2 = 0; - static const QString ss2k_resistance_sample_3; - static constexpr float default_ss2k_resistance_sample_3 = 40; + static const QString ss2k_resistance_sample_3; + static constexpr float default_ss2k_resistance_sample_3 = 40; - static const QString ss2k_shift_step_sample_3; - static constexpr float default_ss2k_shift_step_sample_3 = 0; + static const QString ss2k_shift_step_sample_3; + static constexpr float default_ss2k_shift_step_sample_3 = 0; - static const QString ss2k_resistance_sample_4; - static constexpr float default_ss2k_resistance_sample_4 = 50; + static const QString ss2k_resistance_sample_4; + static constexpr float default_ss2k_resistance_sample_4 = 50; - static const QString ss2k_shift_step_sample_4; - static constexpr float default_ss2k_shift_step_sample_4 = 0; + static const QString ss2k_shift_step_sample_4; + static constexpr float default_ss2k_shift_step_sample_4 = 0; - static const QString fitshow_truetimer; - static constexpr bool default_fitshow_truetimer = false; + static const QString fitshow_truetimer; + static constexpr bool default_fitshow_truetimer = false; - static const QString elite_rizer_gain; - static constexpr float default_elite_rizer_gain = 1.0; + static const QString elite_rizer_gain; + static constexpr float default_elite_rizer_gain = 1.0; static const QString tile_ext_incline_enabled; static constexpr bool default_tile_ext_incline_enabled = false; @@ -1043,282 +1043,282 @@ class QZSettings { static constexpr int default_tile_ext_incline_order = 32; - static const QString reebok_fr30_treadmill; - static constexpr bool default_reebok_fr30_treadmill = false; + static const QString reebok_fr30_treadmill; + static constexpr bool default_reebok_fr30_treadmill = false; - static const QString horizon_treadmill_7_8; - static constexpr bool default_horizon_treadmill_7_8 = false; + static const QString horizon_treadmill_7_8; + static constexpr bool default_horizon_treadmill_7_8 = false; - /** + /** *@brief The name of the profile for this settings file. - */ - static const QString profile_name; - static const QString default_profile_name; + */ + static const QString profile_name; + static const QString default_profile_name; - static const QString tile_cadence_color_enabled; - static constexpr bool default_tile_cadence_color_enabled = false; + static const QString tile_cadence_color_enabled; + static constexpr bool default_tile_cadence_color_enabled = false; - static const QString tile_peloton_remaining_enabled; - static constexpr bool default_tile_peloton_remaining_enabled = false; + static const QString tile_peloton_remaining_enabled; + static constexpr bool default_tile_peloton_remaining_enabled = false; - static const QString tile_peloton_remaining_order; - static constexpr int default_tile_peloton_remaining_order = 22; + static const QString tile_peloton_remaining_order; + static constexpr int default_tile_peloton_remaining_order = 22; - static const QString tile_peloton_resistance_color_enabled; - static constexpr bool default_tile_peloton_resistance_color_enabled = false; + static const QString tile_peloton_resistance_color_enabled; + static constexpr bool default_tile_peloton_resistance_color_enabled = false; - /** + /** *@brief Enable the Wahoo Dircon device. - */ - static const QString dircon_yes; - static constexpr bool default_dircon_yes = true; + */ + static const QString dircon_yes; + static constexpr bool default_dircon_yes = true; - static const QString dircon_server_base_port; - static constexpr int default_dircon_server_base_port = 36866; + static const QString dircon_server_base_port; + static constexpr int default_dircon_server_base_port = 36866; - static const QString ios_cache_heart_device; - static constexpr bool default_ios_cache_heart_device = true; + static const QString ios_cache_heart_device; + static constexpr bool default_ios_cache_heart_device = true; - /** + /** *@brief Count of the number of times the app has been opened. - */ - static const QString app_opening; - static constexpr int default_app_opening = 0; + */ + static const QString app_opening; + static constexpr int default_app_opening = 0; - static const QString proformtdf4ip; - static const QString default_proformtdf4ip; + static const QString proformtdf4ip; + static const QString default_proformtdf4ip; - static const QString fitfiu_mc_v460; - static constexpr bool default_fitfiu_mc_v460 = false; + static const QString fitfiu_mc_v460; + static constexpr bool default_fitfiu_mc_v460 = false; /** *@brief The mass of the bike in kilograms. - */ - static const QString bike_weight; - static constexpr float default_bike_weight = 0; + */ + static const QString bike_weight; + static constexpr float default_bike_weight = 0; - static const QString kingsmith_encrypt_v2; - static constexpr bool default_kingsmith_encrypt_v2 = false; + static const QString kingsmith_encrypt_v2; + static constexpr bool default_kingsmith_encrypt_v2 = false; - static const QString proform_treadmill_9_0; - static constexpr bool default_proform_treadmill_9_0 = false; + static const QString proform_treadmill_9_0; + static constexpr bool default_proform_treadmill_9_0 = false; - static const QString proform_treadmill_1800i; - static constexpr bool default_proform_treadmill_1800i = false; + static const QString proform_treadmill_1800i; + static constexpr bool default_proform_treadmill_1800i = false; - static const QString cadence_offset; - static constexpr float default_cadence_offset = 0; + static const QString cadence_offset; + static constexpr float default_cadence_offset = 0; - static const QString cadence_gain; - static constexpr float default_cadence_gain = 1; + static const QString cadence_gain; + static constexpr float default_cadence_gain = 1; - static const QString sp_ht_9600ie; - static constexpr bool default_sp_ht_9600ie = false; + static const QString sp_ht_9600ie; + static constexpr bool default_sp_ht_9600ie = false; /** * @brief Enable text to speech. */ - static const QString tts_enabled; - static constexpr bool default_tts_enabled = false; + static const QString tts_enabled; + static constexpr bool default_tts_enabled = false; - static const QString tts_summary_sec; - static constexpr int default_tts_summary_sec = 120; + static const QString tts_summary_sec; + static constexpr int default_tts_summary_sec = 120; - static const QString tts_act_speed; - static constexpr bool default_tts_act_speed = false; + static const QString tts_act_speed; + static constexpr bool default_tts_act_speed = false; - static const QString tts_avg_speed; - static constexpr bool default_tts_avg_speed = true; + static const QString tts_avg_speed; + static constexpr bool default_tts_avg_speed = true; - static const QString tts_max_speed; - static constexpr bool default_tts_max_speed = false; + static const QString tts_max_speed; + static constexpr bool default_tts_max_speed = false; - static const QString tts_act_inclination; - static constexpr bool default_tts_act_inclination = false; + static const QString tts_act_inclination; + static constexpr bool default_tts_act_inclination = false; - static const QString tts_act_cadence; - static constexpr bool default_tts_act_cadence = false; + static const QString tts_act_cadence; + static constexpr bool default_tts_act_cadence = false; - static const QString tts_avg_cadence; - static constexpr bool default_tts_avg_cadence = true; + static const QString tts_avg_cadence; + static constexpr bool default_tts_avg_cadence = true; - static const QString tts_max_cadence; - static constexpr bool default_tts_max_cadence = false; + static const QString tts_max_cadence; + static constexpr bool default_tts_max_cadence = false; - static const QString tts_act_elevation; - static constexpr bool default_tts_act_elevation = true; + static const QString tts_act_elevation; + static constexpr bool default_tts_act_elevation = true; - static const QString tts_act_calories; - static constexpr bool default_tts_act_calories = true; + static const QString tts_act_calories; + static constexpr bool default_tts_act_calories = true; - static const QString tts_act_odometer; - static constexpr bool default_tts_act_odometer = true; + static const QString tts_act_odometer; + static constexpr bool default_tts_act_odometer = true; - static const QString tts_act_pace; - static constexpr bool default_tts_act_pace = false; + static const QString tts_act_pace; + static constexpr bool default_tts_act_pace = false; - static const QString tts_avg_pace; - static constexpr bool default_tts_avg_pace = true; + static const QString tts_avg_pace; + static constexpr bool default_tts_avg_pace = true; - static const QString tts_max_pace; - static constexpr bool default_tts_max_pace = false; + static const QString tts_max_pace; + static constexpr bool default_tts_max_pace = false; - static const QString tts_act_resistance; - static constexpr bool default_tts_act_resistance = true; + static const QString tts_act_resistance; + static constexpr bool default_tts_act_resistance = true; - static const QString tts_avg_resistance; - static constexpr bool default_tts_avg_resistance = true; + static const QString tts_avg_resistance; + static constexpr bool default_tts_avg_resistance = true; - static const QString tts_max_resistance; - static constexpr bool default_tts_max_resistance = false; + static const QString tts_max_resistance; + static constexpr bool default_tts_max_resistance = false; - static const QString tts_act_watt; - static constexpr bool default_tts_act_watt = false; + static const QString tts_act_watt; + static constexpr bool default_tts_act_watt = false; - static const QString tts_avg_watt; - static constexpr bool default_tts_avg_watt = true; + static const QString tts_avg_watt; + static constexpr bool default_tts_avg_watt = true; - static const QString tts_max_watt; - static constexpr bool default_tts_max_watt = true; + static const QString tts_max_watt; + static constexpr bool default_tts_max_watt = true; - static const QString tts_act_ftp; - static constexpr bool default_tts_act_ftp = false; + static const QString tts_act_ftp; + static constexpr bool default_tts_act_ftp = false; - static const QString tts_avg_ftp; - static constexpr bool default_tts_avg_ftp = true; + static const QString tts_avg_ftp; + static constexpr bool default_tts_avg_ftp = true; - static const QString tts_max_ftp; - static constexpr bool default_tts_max_ftp = false; + static const QString tts_max_ftp; + static constexpr bool default_tts_max_ftp = false; - static const QString tts_act_heart; - static constexpr bool default_tts_act_heart = true; + static const QString tts_act_heart; + static constexpr bool default_tts_act_heart = true; - static const QString tts_avg_heart; - static constexpr bool default_tts_avg_heart = true; + static const QString tts_avg_heart; + static constexpr bool default_tts_avg_heart = true; - static const QString tts_max_heart; - static constexpr bool default_tts_max_heart = false; + static const QString tts_max_heart; + static constexpr bool default_tts_max_heart = false; - static const QString tts_act_jouls; - static constexpr bool default_tts_act_jouls = true; + static const QString tts_act_jouls; + static constexpr bool default_tts_act_jouls = true; - static const QString tts_act_elapsed; - static constexpr bool default_tts_act_elapsed = true; + static const QString tts_act_elapsed; + static constexpr bool default_tts_act_elapsed = true; - static const QString tts_act_peloton_resistance; - static constexpr bool default_tts_act_peloton_resistance = false; + static const QString tts_act_peloton_resistance; + static constexpr bool default_tts_act_peloton_resistance = false; - static const QString tts_avg_peloton_resistance; - static constexpr bool default_tts_avg_peloton_resistance = false; + static const QString tts_avg_peloton_resistance; + static constexpr bool default_tts_avg_peloton_resistance = false; - static const QString tts_max_peloton_resistance; - static constexpr bool default_tts_max_peloton_resistance = false; + static const QString tts_max_peloton_resistance; + static constexpr bool default_tts_max_peloton_resistance = false; - static const QString tts_act_target_peloton_resistance; - static constexpr bool default_tts_act_target_peloton_resistance = true; + static const QString tts_act_target_peloton_resistance; + static constexpr bool default_tts_act_target_peloton_resistance = true; - static const QString tts_act_target_cadence; - static constexpr bool default_tts_act_target_cadence = true; + static const QString tts_act_target_cadence; + static constexpr bool default_tts_act_target_cadence = true; - static const QString tts_act_target_power; - static constexpr bool default_tts_act_target_power = true; + static const QString tts_act_target_power; + static constexpr bool default_tts_act_target_power = true; - static const QString tts_act_target_zone; - static constexpr bool default_tts_act_target_zone = true; + static const QString tts_act_target_zone; + static constexpr bool default_tts_act_target_zone = true; - static const QString tts_act_target_speed; - static constexpr bool default_tts_act_target_speed = true; + static const QString tts_act_target_speed; + static constexpr bool default_tts_act_target_speed = true; - static const QString tts_act_target_incline; - static constexpr bool default_tts_act_target_incline = true; + static const QString tts_act_target_incline; + static constexpr bool default_tts_act_target_incline = true; - static const QString tts_act_watt_kg; - static constexpr bool default_tts_act_watt_kg = false; + static const QString tts_act_watt_kg; + static constexpr bool default_tts_act_watt_kg = false; - static const QString tts_avg_watt_kg; - static constexpr bool default_tts_avg_watt_kg = false; + static const QString tts_avg_watt_kg; + static constexpr bool default_tts_avg_watt_kg = false; - static const QString tts_max_watt_kg; - static constexpr bool default_tts_max_watt_kg = false; + static const QString tts_max_watt_kg; + static constexpr bool default_tts_max_watt_kg = false; - /** + /** *@brief Enable the fake device, emulating an elliptical trainer. - */ - static const QString fakedevice_elliptical; - static constexpr bool default_fakedevice_elliptical = false; + */ + static const QString fakedevice_elliptical; + static constexpr bool default_fakedevice_elliptical = false; - static const QString nordictrack_2950_ip; - static const QString default_nordictrack_2950_ip; + static const QString nordictrack_2950_ip; + static const QString default_nordictrack_2950_ip; - static const QString tile_instantaneous_stride_length_enabled; - static constexpr bool default_tile_instantaneous_stride_length_enabled = false; + static const QString tile_instantaneous_stride_length_enabled; + static constexpr bool default_tile_instantaneous_stride_length_enabled = false; - static const QString tile_instantaneous_stride_length_order; - static constexpr int default_tile_instantaneous_stride_length_order = 32; + static const QString tile_instantaneous_stride_length_order; + static constexpr int default_tile_instantaneous_stride_length_order = 32; - static const QString tile_ground_contact_enabled; - static constexpr bool default_tile_ground_contact_enabled = false; + static const QString tile_ground_contact_enabled; + static constexpr bool default_tile_ground_contact_enabled = false; - static const QString tile_ground_contact_order; - static constexpr int default_tile_ground_contact_order = 33; + static const QString tile_ground_contact_order; + static constexpr int default_tile_ground_contact_order = 33; - static const QString tile_vertical_oscillation_enabled; - static constexpr bool default_tile_vertical_oscillation_enabled = false; + static const QString tile_vertical_oscillation_enabled; + static constexpr bool default_tile_vertical_oscillation_enabled = false; - static const QString tile_vertical_oscillation_order; - static constexpr int default_tile_vertical_oscillation_order = 34; + static const QString tile_vertical_oscillation_order; + static constexpr int default_tile_vertical_oscillation_order = 34; - /** + /** *@brief The gender of the user. - */ - static const QString sex; - static const QString default_sex; + */ + static const QString sex; + static const QString default_sex; - static const QString maps_type; - static const QString default_maps_type; + static const QString maps_type; + static const QString default_maps_type; - static const QString ss2k_max_resistance; - static constexpr float default_ss2k_max_resistance = 100; + static const QString ss2k_max_resistance; + static constexpr float default_ss2k_max_resistance = 100; - static const QString ss2k_min_resistance; - static constexpr float default_ss2k_min_resistance = 0; + static const QString ss2k_min_resistance; + static constexpr float default_ss2k_min_resistance = 0; - static const QString proform_treadmill_se; - static constexpr bool default_proform_treadmill_se = false; + static const QString proform_treadmill_se; + static constexpr bool default_proform_treadmill_se = false; /** *@brief The IP address for the Proform Treadmill. - */ - static const QString proformtreadmillip; - static const QString default_proformtreadmillip; - // from version 2.11.22 - /** - *@brief - */ - static const QString kingsmith_encrypt_v3; - static constexpr bool default_kingsmith_encrypt_v3 = false; - - /** + */ + static const QString proformtreadmillip; + static const QString default_proformtreadmillip; + // from version 2.11.22 + /** + *@brief + */ + static const QString kingsmith_encrypt_v3; + static constexpr bool default_kingsmith_encrypt_v3 = false; + + /** *@brief IP address for the TDF 10. - */ - static const QString tdf_10_ip; - static const QString default_tdf_10_ip; + */ + static const QString tdf_10_ip; + static const QString default_tdf_10_ip; - /** - *@brief - */ - static const QString fakedevice_treadmill; - static constexpr bool default_fakedevice_treadmill = false; + /** + *@brief + */ + static const QString fakedevice_treadmill; + static constexpr bool default_fakedevice_treadmill = false; - /** + /** *@brief The number of seconds to add to the video timestamp. - */ - static const QString video_playback_window_s; - static constexpr int default_video_playback_window_s = 12; + */ + static const QString video_playback_window_s; + static constexpr int default_video_playback_window_s = 12; static const QString horizon_treadmill_profile_user1; static const QString default_horizon_treadmill_profile_user1; @@ -1342,6 +1342,9 @@ class QZSettings { static const QString rolling_resistance; static constexpr double default_rolling_resistance = 0.005; + static const QString wahoo_rgt_dircon; + static constexpr bool default_wahoo_rgt_dircon = false; + /** * @brief Write the QSettings values using the constants from this namespace. * @param showDefaults Optionally indicates if the default should be shown with the key. diff --git a/src/settings.qml b/src/settings.qml index 672391dc9..75cef9fac 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -480,9 +480,12 @@ import Qt.labs.settings 1.0 // from version 2.11.65 property real rolling_resistance: 0.005 - + // from version 2.11.67 property bool eslinker_ypoo: false + + // from version 2.11.69 + property bool wahoo_rgt_dircon: false // from version ? property bool trixter_xdream_v1_bike: false @@ -6841,6 +6844,32 @@ import Qt.labs.settings 1.0 settings: settings accordionContent: ColumnLayout { spacing: 0 + SwitchDelegate { + id: wahooRGTDirconDelegate + text: qsTr("Wahoo RGT Compatibility") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.wahoo_rgt_dircon + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.wahoo_rgt_dircon = checked + } + Label { + Layout.preferredWidth: parent.width + id: wahooRGTDirconLabel + text: qsTr("Leave the RGT compatibility disabled in order to use Zwift") + font.bold: true + font.italic: true + font.pixelSize: 8 + textFormat: Text.PlainText + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + color: Material.color(Material.Red) + } RowLayout { spacing: 10 Label { From d567c9c4128345abbf1e144532c5fde9e567ad96 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 13 Oct 2022 13:38:40 +0200 Subject: [PATCH 110/255] adding debug on ftmsbike --- src/ftmsbike.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ftmsbike.cpp b/src/ftmsbike.cpp index 37668217c..ae8175056 100644 --- a/src/ftmsbike.cpp +++ b/src/ftmsbike.cpp @@ -164,7 +164,7 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris settings.value(QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name).toString(); bool disable_hr_frommachinery = settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); - emit debug(QStringLiteral(" << ") + newValue.toHex(' ')); + qDebug() << characteristic.uuid() << QStringLiteral(" << ") << newValue.toHex(' '); if (characteristic.uuid() != QBluetoothUuid((quint16)0x2AD2)) { return; From 16e1d53ee6b5f8b55d173caf47471002b7bc3c63 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 13 Oct 2022 14:46:43 +0200 Subject: [PATCH 111/255] Pro FlexCycle #979 --- ...ooth.characteristic.cross_trainer_data.xml | 272 ++++++++++ src/ftmsbike.cpp | 498 ++++++++++++------ 2 files changed, 616 insertions(+), 154 deletions(-) create mode 100644 docs/specs/org.bluetooth.characteristic.cross_trainer_data.xml diff --git a/docs/specs/org.bluetooth.characteristic.cross_trainer_data.xml b/docs/specs/org.bluetooth.characteristic.cross_trainer_data.xml new file mode 100644 index 000000000..afd2d3b0d --- /dev/null +++ b/docs/specs/org.bluetooth.characteristic.cross_trainer_data.xml @@ -0,0 +1,272 @@ + + + + + The Cross Trainer Data characteristic is used to send + training-related data to the Client from a cross trainer + (Server). + + + + Mandatory + 24bit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Kilometer per hour with a resolution of + 0.01 + C1 + uint16 + org.bluetooth.unit.velocity.kilometre_per_hour + -2 + + + Kilometer per hour with a resolution of + 0.01 + C2 + uint16 + org.bluetooth.unit.velocity.kilometre_per_hour + -2 + + + Meters with a resolution of + 1 + C3 + uint24 + org.bluetooth.unit.length.metre + + + Step/minute with a resolution of + 1 + C4 + uint16 + org.bluetooth.unit.step_per_minute + + + Step/minute with a resolution of + 1 + C4 + uint16 + org.bluetooth.unit.step_per_minute + + + Unitless with a resolution of + 0.1 + C5 + uint16 + -1 + org.bluetooth.unit.unitless + + + Meters with a resolution of + 1 + C6 + uint16 + org.bluetooth.unit.length.metre + + + Meters with a resolution of + 1 + C6 + uint16 + org.bluetooth.unit.length.metre + + + Percent with a resolution of + 0.1 + C7 + sint16 + org.bluetooth.unit.percentage + -1 + + + Degree with a resolution of + 0.1 + C7 + sint16 + org.bluetooth.unit.plane_angle.degree + -1 + + + Unitless with a resolution of + 0.1 + C8 + sint16 + -1 + org.bluetooth.unit.unitless + + + Watts with a resolution of + 1 + C9 + sint16 + org.bluetooth.unit.power.watt + + + Watts with a resolution of + 1 + C10 + sint16 + org.bluetooth.unit.power.watt + + + Kilo Calorie with a resolution of + 1 + C11 + uint16 + org.bluetooth.unit.energy.kilogram_calorie + + + Kilo Calorie with a resolution of + 1 + C11 + uint16 + org.bluetooth.unit.energy.kilogram_calorie + + + Kilo Calorie with a resolution of + 1 + C11 + uint8 + org.bluetooth.unit.energy.kilogram_calorie + + + Beats per minute with a resolution of + 1 + C12 + uint8 + org.bluetooth.unit.period.beats_per_minute + + + Metabolic Equivalent with a resolution of + 0.1 + C13 + uint8 + -1 + org.bluetooth.unit.metabolic_equivalent + + + Second with a resolution of + 1 + C14 + uint16 + org.bluetooth.unit.time.second + + + Second with a resolution of + 1 + C15 + uint16 + org.bluetooth.unit.time.second + + + The fields in the above table, reading from top to bottom, + are shown in the order of LSO to MSO, where LSO = Least + Significant Octet and MSO = Most Significant Octet. The Least + Significant Octet represents the eight bits numbered 0 to + 7. + diff --git a/src/ftmsbike.cpp b/src/ftmsbike.cpp index ae8175056..8c2608f9a 100644 --- a/src/ftmsbike.cpp +++ b/src/ftmsbike.cpp @@ -163,190 +163,380 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris QString heartRateBeltName = settings.value(QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name).toString(); bool disable_hr_frommachinery = settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); + bool heart = false; qDebug() << characteristic.uuid() << QStringLiteral(" << ") << newValue.toHex(' '); - if (characteristic.uuid() != QBluetoothUuid((quint16)0x2AD2)) { - return; - } - lastPacket = newValue; - union flags { - struct { - uint16_t moreData : 1; - uint16_t avgSpeed : 1; - uint16_t instantCadence : 1; - uint16_t avgCadence : 1; - uint16_t totDistance : 1; - uint16_t resistanceLvl : 1; - uint16_t instantPower : 1; - uint16_t avgPower : 1; - uint16_t expEnergy : 1; - uint16_t heartRate : 1; - uint16_t metabolic : 1; - uint16_t elapsedTime : 1; - uint16_t remainingTime : 1; - uint16_t spare : 3; + if (characteristic.uuid() == QBluetoothUuid((quint16)0x2AD2)) { + + union flags { + struct { + uint16_t moreData : 1; + uint16_t avgSpeed : 1; + uint16_t instantCadence : 1; + uint16_t avgCadence : 1; + uint16_t totDistance : 1; + uint16_t resistanceLvl : 1; + uint16_t instantPower : 1; + uint16_t avgPower : 1; + uint16_t expEnergy : 1; + uint16_t heartRate : 1; + uint16_t metabolic : 1; + uint16_t elapsedTime : 1; + uint16_t remainingTime : 1; + uint16_t spare : 3; + }; + + uint16_t word_flags; }; - uint16_t word_flags; - }; + flags Flags; + int index = 0; + Flags.word_flags = (newValue.at(1) << 8) | newValue.at(0); + index += 2; - flags Flags; - int index = 0; - Flags.word_flags = (newValue.at(1) << 8) | newValue.at(0); - index += 2; + if (!Flags.moreData) { + if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { + Speed = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))) / + 100.0; + } else { + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + } + index += 2; + emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); + } - if (!Flags.moreData) { - if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { - Speed = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | - (uint16_t)((uint8_t)newValue.at(index)))) / - 100.0; + if (Flags.avgSpeed) { + double avgSpeed; + avgSpeed = + ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / + 100.0; + index += 2; + emit debug(QStringLiteral("Current Average Speed: ") + QString::number(avgSpeed)); + } + + if (Flags.instantCadence) { + if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) + .toString() + .startsWith(QStringLiteral("Disabled"))) { + Cadence = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))) / + 2.0; + } + index += 2; + emit debug(QStringLiteral("Current Cadence: ") + QString::number(Cadence.value())); + } + + if (Flags.avgCadence) { + double avgCadence; + avgCadence = + ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / + 2.0; + index += 2; + emit debug(QStringLiteral("Current Average Cadence: ") + QString::number(avgCadence)); + } + + if (Flags.totDistance) { + Distance = ((double)((((uint32_t)((uint8_t)newValue.at(index + 2)) << 16) | + (uint32_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint32_t)((uint8_t)newValue.at(index)))) / + 1000.0; + index += 3; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Distance += ((Speed.value() / 3600000.0) * + ((double)lastRefreshCharacteristicChanged.msecsTo(QDateTime::currentDateTime()))); } - index += 2; - emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); - } - if (Flags.avgSpeed) { - double avgSpeed; - avgSpeed = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / - 100.0; - index += 2; - emit debug(QStringLiteral("Current Average Speed: ") + QString::number(avgSpeed)); - } + emit debug(QStringLiteral("Current Distance: ") + QString::number(Distance.value())); - if (Flags.instantCadence) { - if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) - .toString() - .startsWith(QStringLiteral("Disabled"))) { - Cadence = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | - (uint16_t)((uint8_t)newValue.at(index)))) / - 2.0; + if (Flags.resistanceLvl) { + Resistance = + ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + emit resistanceRead(Resistance.value()); + index += 2; + emit debug(QStringLiteral("Current Resistance: ") + QString::number(Resistance.value())); + } else { + double ac = 0.01243107769; + double bc = 1.145964912; + double cc = -23.50977444; + + double ar = 0.1469553975; + double br = -5.841344538; + double cr = 97.62165482; + + if (Cadence.value() && m_watt.value()) { + m_pelotonResistance = + (((sqrt(pow(br, 2.0) - 4.0 * ar * + (cr - (m_watt.value() * 132.0 / + (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - + br) / + (2.0 * ar)) * + settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + + settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + Resistance = m_pelotonResistance; + emit resistanceRead(Resistance.value()); + } } - index += 2; - emit debug(QStringLiteral("Current Cadence: ") + QString::number(Cadence.value())); - } - if (Flags.avgCadence) { - double avgCadence; - avgCadence = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / - 2.0; - index += 2; - emit debug(QStringLiteral("Current Average Cadence: ") + QString::number(avgCadence)); - } + if (Flags.instantPower) { + if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) + .toString() + .startsWith(QStringLiteral("Disabled"))) + m_watt = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); + index += 2; + emit debug(QStringLiteral("Current Watt: ") + QString::number(m_watt.value())); + } - if (Flags.totDistance) { - Distance = ((double)((((uint32_t)((uint8_t)newValue.at(index + 2)) << 16) | - (uint32_t)((uint8_t)newValue.at(index + 1)) << 8) | - (uint32_t)((uint8_t)newValue.at(index)))) / - 1000.0; - index += 3; - } else { - Distance += ((Speed.value() / 3600000.0) * - ((double)lastRefreshCharacteristicChanged.msecsTo(QDateTime::currentDateTime()))); - } + if (Flags.avgPower) { + double avgPower; + avgPower = + ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + index += 2; + emit debug(QStringLiteral("Current Average Watt: ") + QString::number(avgPower)); + } - emit debug(QStringLiteral("Current Distance: ") + QString::number(Distance.value())); + if (Flags.expEnergy && newValue.length() > index + 1) { + KCal = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + index += 2; - if (Flags.resistanceLvl) { - Resistance = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); - emit resistanceRead(Resistance.value()); - index += 2; - emit debug(QStringLiteral("Current Resistance: ") + QString::number(Resistance.value())); - } else { - double ac = 0.01243107769; - double bc = 1.145964912; - double cc = -23.50977444; - - double ar = 0.1469553975; - double br = -5.841344538; - double cr = 97.62165482; - - if (Cadence.value() && m_watt.value()) { - m_pelotonResistance = - (((sqrt(pow(br, 2.0) - 4.0 * ar * - (cr - (m_watt.value() * 132.0 / - (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - - br) / - (2.0 * ar)) * - settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + - settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); - Resistance = m_pelotonResistance; - emit resistanceRead(Resistance.value()); + // energy per hour + index += 2; + + // energy per minute + index += 1; + } else { + if (watts()) + KCal += + ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * + 3.5) / + 200.0) / + (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( + QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in + // kg * 3.5) / 200 ) / 60 } - } - if (Flags.instantPower) { - if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) - .toString() - .startsWith(QStringLiteral("Disabled"))) - m_watt = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | - (uint16_t)((uint8_t)newValue.at(index)))); - index += 2; - emit debug(QStringLiteral("Current Watt: ") + QString::number(m_watt.value())); - } + emit debug(QStringLiteral("Current KCal: ") + QString::number(KCal.value())); + + #ifdef Q_OS_ANDROID + if (settings.value(QZSettings::ant_heart, QZSettings::default_ant_heart).toBool()) + Heart = (uint8_t)KeepAwakeHelper::heart(); + else + #endif + { + if (Flags.heartRate && !disable_hr_frommachinery && newValue.length() > index) { + Heart = ((double)((newValue.at(index)))); + // index += 1; // NOTE: clang-analyzer-deadcode.DeadStores + emit debug(QStringLiteral("Current Heart: ") + QString::number(Heart.value())); + } else { + Flags.heartRate = false; + } + heart = Flags.heartRate; + } - if (Flags.avgPower) { - double avgPower; - avgPower = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); - index += 2; - emit debug(QStringLiteral("Current Average Watt: ") + QString::number(avgPower)); - } + if (Flags.metabolic) { + // todo + } - if (Flags.expEnergy && newValue.length() > index + 1) { - KCal = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); - index += 2; + if (Flags.elapsedTime) { + // todo + } - // energy per hour - index += 2; + if (Flags.remainingTime) { + // todo + } + } else if(characteristic.uuid() == QBluetoothUuid((quint16)0x2ACE)) { + union flags { + struct { + uint32_t moreData : 1; + uint32_t avgSpeed : 1; + uint32_t totDistance : 1; + uint32_t stepCount: 1; + uint32_t strideCount : 1; + uint32_t elevationGain : 1; + uint32_t rampAngle : 1; + uint32_t resistanceLvl : 1; + uint32_t instantPower : 1; + uint32_t avgPower : 1; + uint32_t expEnergy : 1; + uint32_t heartRate : 1; + uint32_t metabolicEq : 1; + uint32_t elapsedTime : 1; + uint32_t remainingTime : 1; + uint32_t movementDirection : 1; + uint32_t spare : 8; + }; + + uint32_t word_flags; + }; + + flags Flags; + int index = 0; + Flags.word_flags = (newValue.at(2) << 16) | (newValue.at(1) << 8) | newValue.at(0); + index += 3; + + if (!Flags.moreData) { + if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { + Speed = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))) / + 100.0; + } else { + Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + } + emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); + index += 2; + } - // energy per minute - index += 1; - } else { - if (watts()) - KCal += - ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * - 3.5) / - 200.0) / - (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( - QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in - // kg * 3.5) / 200 ) / 60 - } + if (Flags.avgSpeed) { + double avgSpeed; + avgSpeed = + ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / + 100.0; + index += 2; + emit debug(QStringLiteral("Current Average Speed: ") + QString::number(avgSpeed)); + } + + if (Flags.totDistance) { + Distance = ((double)((((uint32_t)((uint8_t)newValue.at(index + 2)) << 16) | + (uint32_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint32_t)((uint8_t)newValue.at(index)))) / + 1000.0; + index += 3; + } else { + Distance += ((Speed.value() / 3600000.0) * + ((double)lastRefreshCharacteristicChanged.msecsTo(QDateTime::currentDateTime()))); + } + + emit debug(QStringLiteral("Current Distance: ") + QString::number(Distance.value())); - emit debug(QStringLiteral("Current KCal: ") + QString::number(KCal.value())); + if (Flags.stepCount) { + if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) + .toString() + .startsWith(QStringLiteral("Disabled"))) { + Cadence = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); + } + emit debug(QStringLiteral("Current Cadence: ") + QString::number(Cadence.value())); + + index += 2; + index += 2; + } + + if (Flags.strideCount) { + index += 2; + } + + if (Flags.elevationGain) { + index += 2; + index += 2; + } + + if (Flags.rampAngle) { + index += 2; + index += 2; + } + + if (Flags.resistanceLvl) { + Resistance = + ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + emit resistanceRead(Resistance.value()); + index += 2; + emit debug(QStringLiteral("Current Resistance: ") + QString::number(Resistance.value())); + } else { + double ac = 0.01243107769; + double bc = 1.145964912; + double cc = -23.50977444; + + double ar = 0.1469553975; + double br = -5.841344538; + double cr = 97.62165482; + + if (Cadence.value() && m_watt.value()) { + m_pelotonResistance = + (((sqrt(pow(br, 2.0) - 4.0 * ar * + (cr - (m_watt.value() * 132.0 / + (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - + br) / + (2.0 * ar)) * + settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + + settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + Resistance = m_pelotonResistance; + emit resistanceRead(Resistance.value()); + } + } + + if (Flags.instantPower) { + if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) + .toString() + .startsWith(QStringLiteral("Disabled"))) + m_watt = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); + emit debug(QStringLiteral("Current Watt: ") + QString::number(m_watt.value())); + index += 2; + } + + if (Flags.avgPower) { + double avgPower; + avgPower = + ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + emit debug(QStringLiteral("Current Average Watt: ") + QString::number(avgPower)); + index += 2; + } + + if (Flags.expEnergy && newValue.length() > index + 1) { + KCal = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + index += 2; + + // energy per hour + index += 2; + + // energy per minute + index += 1; + } else { + if (watts()) + KCal += + ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * + 3.5) / + 200.0) / + (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( + QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in + // kg * 3.5) / 200 ) / 60 + } + + emit debug(QStringLiteral("Current KCal: ") + QString::number(KCal.value())); #ifdef Q_OS_ANDROID - if (settings.value(QZSettings::ant_heart, QZSettings::default_ant_heart).toBool()) - Heart = (uint8_t)KeepAwakeHelper::heart(); - else + if (settings.value(QZSettings::ant_heart, QZSettings::default_ant_heart).toBool()) + Heart = (uint8_t)KeepAwakeHelper::heart(); + else #endif - { - if (Flags.heartRate && !disable_hr_frommachinery && newValue.length() > index) { - Heart = ((double)((newValue.at(index)))); - // index += 1; // NOTE: clang-analyzer-deadcode.DeadStores - emit debug(QStringLiteral("Current Heart: ") + QString::number(Heart.value())); - } else { - Flags.heartRate = false; - } - } + { + if (Flags.heartRate && !disable_hr_frommachinery && newValue.length() > index) { + Heart = ((double)((newValue.at(index)))); + // index += 1; // NOTE: clang-analyzer-deadcode.DeadStores + emit debug(QStringLiteral("Current Heart: ") + QString::number(Heart.value())); + } else { + Flags.heartRate = false; + } + heart = Flags.heartRate; + } - if (Flags.metabolic) { - // todo - } + if (Flags.metabolicEq) { + // todo + } - if (Flags.elapsedTime) { - // todo - } + if (Flags.elapsedTime) { + // todo + } - if (Flags.remainingTime) { - // todo + if (Flags.remainingTime) { + // todo + } + } else { + return; } if (Cadence.value() > 0) { @@ -357,7 +547,7 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris lastRefreshCharacteristicChanged = QDateTime::currentDateTime(); if (heartRateBeltName.startsWith(QStringLiteral("Disabled")) && - (!Flags.heartRate || Heart.value() == 0 || disable_hr_frommachinery)) { + (!heart || Heart.value() == 0 || disable_hr_frommachinery)) { #ifdef Q_OS_IOS #ifndef IO_UNDER_QT lockscreen h; From d225d7be16bf7b9c9d8a998360e7d1e1afac00a9 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sun, 16 Oct 2022 09:36:24 +0200 Subject: [PATCH 112/255] GPX Issues on Treadmill (Issue #973 --- src/horizontreadmill.cpp | 19 ++++++++++++++++++- src/horizontreadmill.h | 1 + 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/horizontreadmill.cpp b/src/horizontreadmill.cpp index 271e122c6..439612ec8 100644 --- a/src/horizontreadmill.cpp +++ b/src/horizontreadmill.cpp @@ -769,7 +769,7 @@ void horizontreadmill::update() { qDebug() << "requestSpeed=" << requestSpeed; if (requestSpeed != currentSpeed().value() && fabs(requestSpeed - currentSpeed().value()) > minStepSpeed() && requestSpeed >= 0 && - requestSpeed <= 22) { + requestSpeed <= 22 && checkIfForceSpeedNeeding(requestSpeed, currentSpeed().value())) { emit debug(QStringLiteral("writing speed ") + QString::number(requestSpeed)); forceSpeed(requestSpeed); } @@ -913,6 +913,23 @@ void horizontreadmill::update() { } } +bool horizontreadmill::checkIfForceSpeedNeeding(double requestSpeed, double currentSpeed) { + QSettings settings; + bool miles = settings.value(QZSettings::miles_unit, QZSettings::default_miles_unit).toBool(); + const double miles_conversion = 0.621371; + + if (gattCustomService && miles) { + requestSpeed *= miles_conversion; + currentSpeed *= miles_conversion; + + uint8_t uReqSpeed = (uint8_t)(requestSpeed * 10); + uint8_t uCurSpeed = (uint8_t)(currentSpeed * 10); + + return uReqSpeed != uCurSpeed; + } + return true; +} + // example frame: 55aa320003050400532c00150000 void horizontreadmill::forceSpeed(double requestSpeed) { QSettings settings; diff --git a/src/horizontreadmill.h b/src/horizontreadmill.h index bd187f222..64346fea0 100644 --- a/src/horizontreadmill.h +++ b/src/horizontreadmill.h @@ -94,6 +94,7 @@ class horizontreadmill : public treadmill { void testProfileCRC(); void updateProfileCRC(); int GenerateCRC_CCITT(uint8_t *PUPtr8, int PU16_Count, int crcStart = 65535); + bool checkIfForceSpeedNeeding(double requestSpeed, double currentSpeed); // profiles uint8_t initData7[20] = {0x55, 0xaa, 0x02, 0x00, 0x01, 0x16, 0xdb, 0x02, 0xed, 0xc2, From 7ee7eaec35f4fd20541c5ea2236e971132c776e8 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 14 Oct 2022 08:02:42 +0200 Subject: [PATCH 113/255] calling watts() instead of m_watt on speed based on power formula --- src/bhfitnesselliptical.cpp | 25 ++++++++++++++++--------- src/chronobike.cpp | 19 +++++++++++++------ src/cscbike.cpp | 2 +- src/domyosbike.cpp | 2 +- src/echelonconnectsport.cpp | 26 ++++++++++++++++++-------- src/fitplusbike.cpp | 4 ++-- src/flywheelbike.cpp | 2 +- src/ftmsbike.cpp | 4 ++-- src/horizongr7bike.cpp | 4 ++-- src/inspirebike.cpp | 2 +- src/keepbike.cpp | 2 +- src/m3ibike.cpp | 2 +- src/mcfbike.cpp | 2 +- src/npecablebike.cpp | 4 ++-- src/pafersbike.cpp | 2 +- src/proformbike.cpp | 4 ++-- src/renphobike.cpp | 2 +- src/schwinnic4bike.cpp | 2 +- src/skandikawiribike.cpp | 2 +- src/snodebike.cpp | 2 +- src/solebike.cpp | 2 +- src/sportsplusbike.cpp | 4 ++-- src/sportstechbike.cpp | 2 +- src/stagesbike.cpp | 2 +- src/trxappgateusbbike.cpp | 2 +- src/ultrasportbike.cpp | 2 +- src/wahookickrsnapbike.cpp | 2 +- src/yesoulbike.cpp | 2 +- 28 files changed, 78 insertions(+), 54 deletions(-) diff --git a/src/bhfitnesselliptical.cpp b/src/bhfitnesselliptical.cpp index b3a2364fb..a4ecfff2d 100644 --- a/src/bhfitnesselliptical.cpp +++ b/src/bhfitnesselliptical.cpp @@ -132,7 +132,8 @@ void bhfitnesselliptical::characteristicChanged(const QLowEnergyCharacteristic & QSettings settings; QString heartRateBeltName = settings.value(QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name).toString(); - bool disable_hr_frommachinery = settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); + bool disable_hr_frommachinery = + settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); emit debug(QStringLiteral(" << ") + newValue.toHex(' ')); @@ -182,7 +183,10 @@ void bhfitnesselliptical::characteristicChanged(const QLowEnergyCharacteristic & (uint16_t)((uint8_t)newValue.at(index)))) / 100.0;*/ } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), 0 /* not useful for elliptical*/); + Speed = metric::calculateSpeedFromPower( + watts(), Inclination.value(), Speed.value(), + fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), + 0 /* not useful for elliptical*/); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); @@ -274,8 +278,8 @@ void bhfitnesselliptical::characteristicChanged(const QLowEnergyCharacteristic & } else { if (watts()) KCal += - ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * - 3.5) / + ((((0.048 * ((double)watts()) + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / 200.0) / (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in @@ -336,9 +340,9 @@ void bhfitnesselliptical::characteristicChanged(const QLowEnergyCharacteristic & #ifndef IO_UNDER_QT /* bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); - if (ios_peloton_workaround && cadence && h && firstStateChanged) { - h->virtualTreadmill_setCadence(currentCrankRevolutions(), lastCrankEventTime()); + bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, + QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence && h && + firstStateChanged) { h->virtualTreadmill_setCadence(currentCrankRevolutions(), lastCrankEventTime()); h->virtualTreadmill_setHeartRate((uint8_t)metrics_override_heartrate()); } */ @@ -443,8 +447,11 @@ void bhfitnesselliptical::stateChanged(QLowEnergyService::ServiceState state) { ) { QSettings settings; if (!virtualTreadmill && !virtualBike) { - bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); - bool virtual_device_force_bike = settings.value(QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike).toBool(); + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_force_bike = + settings.value(QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike) + .toBool(); if (virtual_device_enabled) { if (!virtual_device_force_bike) { debug("creating virtual treadmill interface..."); diff --git a/src/chronobike.cpp b/src/chronobike.cpp index c6d55652b..66c109667 100644 --- a/src/chronobike.cpp +++ b/src/chronobike.cpp @@ -150,11 +150,14 @@ void chronobike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = ((double)((uint16_t)((uint8_t)newValue.at(6)) + ((uint16_t)((uint8_t)newValue.at(7)) << 8))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower( + watts(), Inclination.value(), Speed.value(), + fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += - ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / + ((((0.048 * ((double)watts()) + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / 200.0) / (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in kg @@ -211,7 +214,8 @@ void chronobike::characteristicChanged(const QLowEnergyCharacteristic &character #ifdef Q_OS_IOS #ifndef IO_UNDER_QT bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence && h && firstStateChanged) { h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime()); h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate()); @@ -268,11 +272,14 @@ void chronobike::stateChanged(QLowEnergyService::ServiceState state) { #endif ) { QSettings settings; - bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); #ifdef Q_OS_IOS #ifndef IO_UNDER_QT - bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool cadence = + settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence) { qDebug() << "ios_peloton_workaround activated!"; h = new lockscreen(); diff --git a/src/cscbike.cpp b/src/cscbike.cpp index 36e762c27..8c2d5aec8 100644 --- a/src/cscbike.cpp +++ b/src/cscbike.cpp @@ -238,7 +238,7 @@ void cscbike::characteristicChanged(const QLowEnergyCharacteristic &characterist if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/domyosbike.cpp b/src/domyosbike.cpp index f2c9b397e..2c4c95e81 100644 --- a/src/domyosbike.cpp +++ b/src/domyosbike.cpp @@ -427,7 +427,7 @@ void domyosbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } KCal = kcal; Distance = distance; diff --git a/src/echelonconnectsport.cpp b/src/echelonconnectsport.cpp index e3516e330..8894b46ec 100644 --- a/src/echelonconnectsport.cpp +++ b/src/echelonconnectsport.cpp @@ -189,7 +189,8 @@ double echelonconnectsport::bikeResistanceToPeloton(double resistance) { if (p < 0) { p = 0; } - return (p * settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + return (p * settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + + settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); } void echelonconnectsport::characteristicChanged(const QLowEnergyCharacteristic &characteristic, @@ -231,11 +232,14 @@ void echelonconnectsport::characteristicChanged(const QLowEnergyCharacteristic & if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = 0.37497622 * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower( + watts(), Inclination.value(), Speed.value(), + fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += - ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / + ((((0.048 * ((double)watts()) + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / 200.0) / (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in kg @@ -273,7 +277,8 @@ void echelonconnectsport::characteristicChanged(const QLowEnergyCharacteristic & #ifdef Q_OS_IOS #ifndef IO_UNDER_QT bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence && h && firstStateChanged) { h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime()); h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate()); @@ -380,11 +385,14 @@ void echelonconnectsport::stateChanged(QLowEnergyService::ServiceState state) { #endif ) { QSettings settings; - bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); #ifdef Q_OS_IOS #ifndef IO_UNDER_QT - bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool cadence = + settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence) { qDebug() << "ios_peloton_workaround activated!"; h = new lockscreen(); @@ -595,7 +603,9 @@ uint16_t echelonconnectsport::wattsFromResistance(double resistance) { } double *watts_of_level; QSettings settings; - if (!settings.value(QZSettings::echelon_watttable, QZSettings::default_echelon_watttable).toString().compare("mgarcea")) + if (!settings.value(QZSettings::echelon_watttable, QZSettings::default_echelon_watttable) + .toString() + .compare("mgarcea")) watts_of_level = wattTable_mgarcea[level]; else watts_of_level = wattTable[level]; diff --git a/src/fitplusbike.cpp b/src/fitplusbike.cpp index 199b1f27a..86e40dfcb 100644 --- a/src/fitplusbike.cpp +++ b/src/fitplusbike.cpp @@ -274,7 +274,7 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte /*if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) Speed = (double)((((uint8_t)newValue.at(4)) << 10) | ((uint8_t)newValue.at(9))) / 100.0; else*/ - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } else if (newValue.length() == 13) { @@ -300,7 +300,7 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) Speed = (double)((((uint8_t)newValue.at(7)) << 8) | ((uint8_t)newValue.at(6))) / 10.0; else - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) diff --git a/src/flywheelbike.cpp b/src/flywheelbike.cpp index 9987ee9dc..004cc4fcc 100644 --- a/src/flywheelbike.cpp +++ b/src/flywheelbike.cpp @@ -290,7 +290,7 @@ void flywheelbike::characteristicChanged(const QLowEnergyCharacteristic &charact if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = ((double)speed) / 10.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } // https://www.facebook.com/groups/149984563348738/permalink/174268944253633/?comment_id=174366620910532&reply_comment_id=174666314213896 diff --git a/src/ftmsbike.cpp b/src/ftmsbike.cpp index 8c2608f9a..e101e57ae 100644 --- a/src/ftmsbike.cpp +++ b/src/ftmsbike.cpp @@ -203,7 +203,7 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); @@ -384,7 +384,7 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); index += 2; diff --git a/src/horizongr7bike.cpp b/src/horizongr7bike.cpp index 1f2a82656..c5cd1d1a4 100644 --- a/src/horizongr7bike.cpp +++ b/src/horizongr7bike.cpp @@ -211,7 +211,7 @@ void horizongr7bike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); @@ -234,7 +234,7 @@ void horizongr7bike::characteristicChanged(const QLowEnergyCharacteristic &chara (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/inspirebike.cpp b/src/inspirebike.cpp index 000e5347d..84de75364 100644 --- a/src/inspirebike.cpp +++ b/src/inspirebike.cpp @@ -149,7 +149,7 @@ void inspirebike::characteristicChanged(const QLowEnergyCharacteristic &characte if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = 0.37497622 * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += diff --git a/src/keepbike.cpp b/src/keepbike.cpp index 63732b381..06ef7d425 100644 --- a/src/keepbike.cpp +++ b/src/keepbike.cpp @@ -212,7 +212,7 @@ void keepbike::characteristicChanged(const QLowEnergyCharacteristic &characteris Speed = ((uint8_t)newValue.at(18)); } else*/ { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } m_watt = GetWattFromPacket(newValue); diff --git a/src/m3ibike.cpp b/src/m3ibike.cpp index e67de32ea..8cb1f8052 100644 --- a/src/m3ibike.cpp +++ b/src/m3ibike.cpp @@ -679,7 +679,7 @@ void m3ibike::processAdvertising(const QByteArray &data) { if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = k3.speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (settings.value(QZSettings::m3i_bike_kcal, QZSettings::default_m3i_bike_kcal).toBool()) { KCal = k3.calorie; diff --git a/src/mcfbike.cpp b/src/mcfbike.cpp index 7d2cb699a..470af0d13 100644 --- a/src/mcfbike.cpp +++ b/src/mcfbike.cpp @@ -203,7 +203,7 @@ void mcfbike::characteristicChanged(const QLowEnergyCharacteristic &characterist if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = (((uint16_t)newValue.at(11) << 8) | (uint16_t)((uint8_t)newValue.at(12))) / 10.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } Distance += ((Speed.value() / 3600000.0) * diff --git a/src/npecablebike.cpp b/src/npecablebike.cpp index b2b9a866b..182f56690 100644 --- a/src/npecablebike.cpp +++ b/src/npecablebike.cpp @@ -180,7 +180,7 @@ void npecablebike::characteristicChanged(const QLowEnergyCharacteristic &charact if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); @@ -249,7 +249,7 @@ void npecablebike::characteristicChanged(const QLowEnergyCharacteristic &charact (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/pafersbike.cpp b/src/pafersbike.cpp index be79848bb..2a3cec7b6 100644 --- a/src/pafersbike.cpp +++ b/src/pafersbike.cpp @@ -208,7 +208,7 @@ void pafersbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = ((uint8_t)newValue.at(3)); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } Resistance = ((uint8_t)newValue.at(5)); diff --git a/src/proformbike.cpp b/src/proformbike.cpp index 16e4d6da2..21d19c0e6 100644 --- a/src/proformbike.cpp +++ b/src/proformbike.cpp @@ -663,7 +663,7 @@ void proformbike::characteristicChanged(const QLowEnergyCharacteristic &characte Speed = ((double)((uint16_t)(((uint8_t)newValue.at(13)) << 8) + (uint16_t)((uint8_t)newValue.at(12))) / 100.0); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } double incline = @@ -881,7 +881,7 @@ void proformbike::characteristicChanged(const QLowEnergyCharacteristic &characte .toDouble()) * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } } } diff --git a/src/renphobike.cpp b/src/renphobike.cpp index 41ada5b1d..15cc37076 100644 --- a/src/renphobike.cpp +++ b/src/renphobike.cpp @@ -205,7 +205,7 @@ void renphobike::characteristicChanged(const QLowEnergyCharacteristic &character (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; else - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); index += 2; debug("Current Speed: " + QString::number(Speed.value())); } diff --git a/src/schwinnic4bike.cpp b/src/schwinnic4bike.cpp index 5bc6701ac..e48b76a02 100644 --- a/src/schwinnic4bike.cpp +++ b/src/schwinnic4bike.cpp @@ -163,7 +163,7 @@ void schwinnic4bike::characteristicChanged(const QLowEnergyCharacteristic &chara (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/skandikawiribike.cpp b/src/skandikawiribike.cpp index 2168367c2..949a0f7af 100644 --- a/src/skandikawiribike.cpp +++ b/src/skandikawiribike.cpp @@ -208,7 +208,7 @@ void skandikawiribike::characteristicChanged(const QLowEnergyCharacteristic &cha if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } } else if (newValue.at(1) == 0x10) { if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) diff --git a/src/snodebike.cpp b/src/snodebike.cpp index 1b829d62b..a69889326 100644 --- a/src/snodebike.cpp +++ b/src/snodebike.cpp @@ -162,7 +162,7 @@ void snodebike::characteristicChanged(const QLowEnergyCharacteristic &characteri (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/solebike.cpp b/src/solebike.cpp index 47be5b86e..9e6e9b8ec 100644 --- a/src/solebike.cpp +++ b/src/solebike.cpp @@ -254,7 +254,7 @@ void solebike::characteristicChanged(const QLowEnergyCharacteristic &characteris if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = GetSpeedFromPacket(newValue); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } m_watt = GetWattFromPacket(newValue); diff --git a/src/sportsplusbike.cpp b/src/sportsplusbike.cpp index 7f287385a..33382c857 100644 --- a/src/sportsplusbike.cpp +++ b/src/sportsplusbike.cpp @@ -143,7 +143,7 @@ void sportsplusbike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } lastTimeCharChanged = QDateTime::currentDateTime(); } else if (newValue.at(1) == 0x30) { @@ -181,7 +181,7 @@ void sportsplusbike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } lastTimeCharChanged = QDateTime::currentDateTime(); kcal = GetKcalFromPacket(newValue); diff --git a/src/sportstechbike.cpp b/src/sportstechbike.cpp index 76d14a0ec..74ca0f79c 100644 --- a/src/sportstechbike.cpp +++ b/src/sportstechbike.cpp @@ -163,7 +163,7 @@ void sportstechbike::characteristicChanged(const QLowEnergyCharacteristic &chara if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } Resistance = requestResistance; emit resistanceRead(Resistance.value()); diff --git a/src/stagesbike.cpp b/src/stagesbike.cpp index cf050be26..a3b605a68 100644 --- a/src/stagesbike.cpp +++ b/src/stagesbike.cpp @@ -253,7 +253,7 @@ void stagesbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/trxappgateusbbike.cpp b/src/trxappgateusbbike.cpp index a16928616..3909cf358 100644 --- a/src/trxappgateusbbike.cpp +++ b/src/trxappgateusbbike.cpp @@ -339,7 +339,7 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch Speed = speed; } else { Speed = - metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(), + metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(), fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (!firstCharChanged) { diff --git a/src/ultrasportbike.cpp b/src/ultrasportbike.cpp index 0849b1137..3f8e52726 100644 --- a/src/ultrasportbike.cpp +++ b/src/ultrasportbike.cpp @@ -178,7 +178,7 @@ void ultrasportbike::characteristicChanged(const QLowEnergyCharacteristic &chara /*if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = GetSpeedFromPacket(newValue); } else*/ - { Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } + { Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += diff --git a/src/wahookickrsnapbike.cpp b/src/wahookickrsnapbike.cpp index f7590029a..f7f10a971 100644 --- a/src/wahookickrsnapbike.cpp +++ b/src/wahookickrsnapbike.cpp @@ -371,7 +371,7 @@ void wahookickrsnapbike::characteristicChanged(const QLowEnergyCharacteristic &c if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = Cadence.value() * settings.value(QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio).toDouble(); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); diff --git a/src/yesoulbike.cpp b/src/yesoulbike.cpp index 070e33708..0b0fde02a 100644 --- a/src/yesoulbike.cpp +++ b/src/yesoulbike.cpp @@ -129,7 +129,7 @@ void yesoulbike::characteristicChanged(const QLowEnergyCharacteristic &character if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = 0.37497622 * ((double)Cadence.value()); } else { - Speed = metric::calculateSpeedFromPower(m_watt.value(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (watts()) KCal += From c403f4d1f287dc478c3a73c902e5cc45fabe9288 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 14 Oct 2022 08:03:38 +0200 Subject: [PATCH 114/255] android version 2.11.70 --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 822494960..ead2f30a3 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index cbd5d9503..bac7a270e 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.69" + text: "version 2.11.70" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index d4121a303..09aca12c2 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.69 +VERSION = 2.11.70 From d47a88f0f4121cb1c346901d0c62f82f8830ab59 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sun, 16 Oct 2022 10:43:05 +0200 Subject: [PATCH 115/255] Merach MRK-S02-0B8D Resistance Change #984 --- src/fitplusbike.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/fitplusbike.cpp b/src/fitplusbike.cpp index 86e40dfcb..01a338cf3 100644 --- a/src/fitplusbike.cpp +++ b/src/fitplusbike.cpp @@ -263,7 +263,28 @@ void fitplusbike::characteristicChanged(const QLowEnergyCharacteristic &characte if (newValue.length() == 15) { Resistance = newValue.at(5); - m_pelotonResistance = (100 * Resistance.value()) / max_resistance; + if(merach_MRK) { + // if we change this, also change the wattsFromResistance function. We can create a standard function in order to + // have all the costants in one place (I WANT MORE TIME!!!) + double ac = 0.01243107769; + double bc = 1.145964912; + double cc = -23.50977444; + + double ar = 0.1469553975; + double br = -5.841344538; + double cr = 97.62165482; + + m_pelotonResistance = + (((sqrt(pow(br, 2.0) - + 4.0 * ar * + (cr - (m_watt.value() * 132.0 / (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - + br) / + (2.0 * ar)) * + settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + + settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + } else { + m_pelotonResistance = (100 * Resistance.value()) / max_resistance; + } if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) .toString() From c5530525fedaaa4c1c8f0755715ae34b65864ff7 Mon Sep 17 00:00:00 2001 From: Brad Stoney Date: Sun, 16 Oct 2022 01:39:01 -0700 Subject: [PATCH 116/255] Update 30_usage.md (#985) Updated -qml default and added -noqml --- docs/30_usage.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/30_usage.md b/docs/30_usage.md index 2d6548ddf..8b3bfbd2f 100644 --- a/docs/30_usage.md +++ b/docs/30_usage.md @@ -24,7 +24,8 @@ This is the list of settings available in the application. These settings needs | **Option** | **Type** | **Default** | **Function** | |:------------------------------|:---------|:------------|:-----------------------------------------------------------------------------| | -no-gui | Boolean | False | Disable GUI | -| -qml | Boolean | False | Enables the QML interface | +| -qml | Boolean | True | Enables the QML interface | +| -noqml | Boolean | False | Enables the NativeQT interface | | -miles | Boolean | False | Swithes to Imperial Units System | | -no-console | Boolean | False | Not in use | | -test-resistance | Boolean | False | | @@ -42,7 +43,7 @@ This is the list of settings available in the application. These settings needs | -service-changed | Boolean | False | | | -bike-wheel-revs | Boolean | False | | | -run-cadence-sensor | Boolean | False | | -| -nordictrack-10-treadmill | Boolean | False | Enable NordicTrack compatibility mode | +| -nordictrack-10-treadmill | Boolean | False | Enable NordicTrack compatibility mode | | -train | String | | Force training program | | -name | String | | Force bluetooth device name (if QZ struggles finding your fitness equipment) | | -poll-device-time | Int | 200 (ms) | Frequency to refresh informations from QZ to Fitness equipment | From 1fabd60559e97080c42dc90efb09094eb211bd32 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sun, 16 Oct 2022 14:24:31 +0200 Subject: [PATCH 117/255] GPX Issues on Treadmill #973 --- src/horizontreadmill.cpp | 9 +++++---- src/horizontreadmill.h | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/horizontreadmill.cpp b/src/horizontreadmill.cpp index 439612ec8..5428037d2 100644 --- a/src/horizontreadmill.cpp +++ b/src/horizontreadmill.cpp @@ -769,7 +769,7 @@ void horizontreadmill::update() { qDebug() << "requestSpeed=" << requestSpeed; if (requestSpeed != currentSpeed().value() && fabs(requestSpeed - currentSpeed().value()) > minStepSpeed() && requestSpeed >= 0 && - requestSpeed <= 22 && checkIfForceSpeedNeeding(requestSpeed, currentSpeed().value())) { + requestSpeed <= 22 && checkIfForceSpeedNeeding(requestSpeed)) { emit debug(QStringLiteral("writing speed ") + QString::number(requestSpeed)); forceSpeed(requestSpeed); } @@ -913,17 +913,18 @@ void horizontreadmill::update() { } } -bool horizontreadmill::checkIfForceSpeedNeeding(double requestSpeed, double currentSpeed) { +bool horizontreadmill::checkIfForceSpeedNeeding(double requestSpeed) { QSettings settings; bool miles = settings.value(QZSettings::miles_unit, QZSettings::default_miles_unit).toBool(); const double miles_conversion = 0.621371; if (gattCustomService && miles) { requestSpeed *= miles_conversion; - currentSpeed *= miles_conversion; uint8_t uReqSpeed = (uint8_t)(requestSpeed * 10); - uint8_t uCurSpeed = (uint8_t)(currentSpeed * 10); + uint8_t uCurSpeed = (uint8_t)(lastHorizonForceSpeed * 10); + + lastHorizonForceSpeed = requestSpeed; return uReqSpeed != uCurSpeed; } diff --git a/src/horizontreadmill.h b/src/horizontreadmill.h index 64346fea0..ee061c0ba 100644 --- a/src/horizontreadmill.h +++ b/src/horizontreadmill.h @@ -81,6 +81,7 @@ class horizontreadmill : public treadmill { int64_t lastStart = 0; int64_t lastStop = 0; bool horizonPaused = false; + double lastHorizonForceSpeed = 0; bool initDone = false; bool initRequest = false; @@ -94,7 +95,7 @@ class horizontreadmill : public treadmill { void testProfileCRC(); void updateProfileCRC(); int GenerateCRC_CCITT(uint8_t *PUPtr8, int PU16_Count, int crcStart = 65535); - bool checkIfForceSpeedNeeding(double requestSpeed, double currentSpeed); + bool checkIfForceSpeedNeeding(double requestSpeed); // profiles uint8_t initData7[20] = {0x55, 0xaa, 0x02, 0x00, 0x01, 0x16, 0xdb, 0x02, 0xed, 0xc2, From 0deb6002dc83bfcbb4d586d0cb445e65abdf26a3 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sun, 16 Oct 2022 20:22:04 +0200 Subject: [PATCH 118/255] adding wifi permissions on android in order to collect the ip address of the wifi for dircon --- src/android/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index ead2f30a3..53d98aa1d 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -81,5 +81,6 @@ + From 6f0f22cf0a42cfa59424f8f5b7d7832e2b5eb490 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 17 Oct 2022 10:59:15 +0200 Subject: [PATCH 119/255] Android 2 Android Wahoo Kickr direct no data #983 --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 53d98aa1d..e005e34d2 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index bac7a270e..a4536f2cd 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.70" + text: "version 2.11.72" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index 09aca12c2..8bbba609d 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.70 +VERSION = 2.11.72 From 8bab3ee7d14e9b71365ceab466b0481238259a6b Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 17 Oct 2022 11:58:10 +0200 Subject: [PATCH 120/255] Android 2 Android Wahoo Kickr direct no data #983 --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index e005e34d2..7f03fec5f 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index a4536f2cd..31402ae6e 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.72" + text: "version 2.11.73" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index 8bbba609d..369e957eb 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.72 +VERSION = 2.11.73 From ff8f4fb8f7897cfa55138f9c77c1422f2c560aac Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 17 Oct 2022 14:41:29 +0200 Subject: [PATCH 121/255] Disable TTS prefixes for frequent repetitions #986 --- src/homeform.cpp | 142 ++-- src/qzsettings.cpp | 1629 +++++++++++++++++++++--------------------- src/qzsettings.h | 181 +++-- src/settings-tts.qml | 15 + src/settings.qml | 3 + 5 files changed, 999 insertions(+), 971 deletions(-) diff --git a/src/homeform.cpp b/src/homeform.cpp index 7c90136d1..f0f3818f0 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -3253,6 +3253,9 @@ void homeform::update() { if (!stopped && !paused) { if (settings.value(QZSettings::tts_enabled, QZSettings::default_tts_enabled).toBool()) { + bool description = + settings.value(QZSettings::tts_description_enabled, QZSettings::default_tts_description_enabled) + .toBool(); if (++tts_summary_count >= settings.value(QZSettings::tts_summary_sec, QZSettings::default_tts_summary_sec).toInt() && m_speech.state() == QTextToSpeech::Ready) { @@ -3260,121 +3263,124 @@ void homeform::update() { QString s; if (settings.value(QZSettings::tts_act_speed, QZSettings::default_tts_act_speed).toBool()) - s.append(tr(", speed ") + + s.append((description ? tr(", speed ") : "") + (!miles ? QString::number(bluetoothManager->device()->currentSpeed().value(), 'f', 1) + - tr(" kilometers per hour") + (description ? tr(" kilometers per hour") : "") : QString::number(bluetoothManager->device()->currentSpeed().value() * unit_conversion, 'f', 1)) + - tr(" miles per hour")); + (description ? tr(" miles per hour") : "")); if (settings.value(QZSettings::tts_avg_speed, QZSettings::default_tts_avg_speed).toBool()) - s.append(tr(", Average speed ") + + s.append((description ? tr(", Average speed ") : "") + (!miles ? QString::number(bluetoothManager->device()->currentSpeed().average(), 'f', 1) + - tr("kilometers per hour") + (description ? tr("kilometers per hour") : "") : QString::number(bluetoothManager->device()->currentSpeed().average() * unit_conversion, 'f', 1)) + - tr(" miles per hour")); + (description ? tr(" miles per hour") : "")); if (settings.value(QZSettings::tts_max_speed, QZSettings::default_tts_max_speed).toBool()) s.append( - tr(", Max speed ") + + (description ? tr(", Max speed ") : "") + (!miles ? QString::number(bluetoothManager->device()->currentSpeed().max(), 'f', 1) + - " kilometers per hour" + (description ? tr(" kilometers per hour") : "") : QString::number( bluetoothManager->device()->currentSpeed().max() * unit_conversion, 'f', 1)) + - tr(" miles per hour")); + (description ? tr(" miles per hour") : "")); if (settings.value(QZSettings::tts_act_inclination, QZSettings::default_tts_act_inclination) .toBool()) - s.append(tr(", inclination ") + + s.append((description ? tr(", inclination ") : "") + QString::number(bluetoothManager->device()->currentInclination().value(), 'f', 1)); if (settings.value(QZSettings::tts_act_cadence, QZSettings::default_tts_act_cadence).toBool()) - s.append(tr(", cadence ") + + s.append((description ? tr(", cadence ") : "") + QString::number(bluetoothManager->device()->currentCadence().value(), 'f', 0)); if (settings.value(QZSettings::tts_avg_cadence, QZSettings::default_tts_avg_cadence).toBool()) - s.append(tr(", Average cadence ") + + s.append((description ? tr(", Average cadence ") : "") + QString::number(bluetoothManager->device()->currentCadence().average(), 'f', 0)); if (settings.value(QZSettings::tts_max_cadence, QZSettings::default_tts_max_cadence /* true */) .toBool()) - s.append(tr(", Max cadence ") + + s.append((description ? tr(", Max cadence ") : "") + QString::number(bluetoothManager->device()->currentCadence().max())); if (settings.value(QZSettings::tts_act_elevation, QZSettings::default_tts_act_elevation).toBool()) - s.append(tr(", elevation ") + + s.append((description ? tr(", elevation ") : "") + (!miles ? QString::number(bluetoothManager->device()->elevationGain().value(), 'f', 1) + - tr(" meters") + (description ? tr(" meters") : "") : QString::number(bluetoothManager->device()->elevationGain().value() * meter_feet_conversion, 'f', 1)) + - tr(" feet")); + (description ? tr(" feet") : "")); if (settings.value(QZSettings::tts_act_calories, QZSettings::default_tts_act_calories).toBool()) - s.append(tr(", calories burned ") + + s.append((description ? tr(", calories burned ") : "") + QString::number(bluetoothManager->device()->calories().value(), 'f', 0)); if (settings.value(QZSettings::tts_act_odometer, QZSettings::default_tts_act_odometer).toBool()) - s.append( - tr(", distance ") + - (!miles - ? QString::number(bluetoothManager->device()->odometer(), 'f', 1) + tr("kilometers") - : QString::number(bluetoothManager->device()->odometer() * unit_conversion, 'f', 1)) + - tr(" miles")); + s.append((description ? tr(", distance ") : "") + + (!miles ? QString::number(bluetoothManager->device()->odometer(), 'f', 1) + + (description ? tr("kilometers") : "") + : QString::number(bluetoothManager->device()->odometer() * unit_conversion, + 'f', 1)) + + (description ? tr(" miles") : "")); if (settings.value(QZSettings::tts_act_pace, QZSettings::default_tts_act_pace).toBool()) - s.append(tr(", pace ") + + s.append((description ? tr(", pace ") : "") + bluetoothManager->device()->currentPace().toString(QStringLiteral("m:ss"))); if (settings.value(QZSettings::tts_avg_pace, QZSettings::default_tts_avg_pace).toBool()) - s.append(tr(", pace ") + + s.append((description ? tr(", pace ") : "") + bluetoothManager->device()->averagePace().toString(QStringLiteral("m:ss"))); if (settings.value(QZSettings::tts_max_pace, QZSettings::default_tts_max_pace).toBool()) - s.append(tr(", pace ") + + s.append((description ? tr(", pace ") : "") + bluetoothManager->device()->maxPace().toString(QStringLiteral("m:ss"))); if (settings.value(QZSettings::tts_act_resistance, QZSettings::default_tts_act_resistance).toBool()) - s.append(tr(", resistance ") + + s.append((description ? tr(", resistance ") : "") + QString::number(bluetoothManager->device()->currentResistance().value(), 'f', 0)); if (settings.value(QZSettings::tts_avg_resistance, QZSettings::default_tts_avg_resistance).toBool()) - s.append(tr(", average resistance ") + + s.append((description ? tr(", average resistance ") : "") + QString::number(bluetoothManager->device()->currentResistance().average(), 'f', 0)); if (settings.value(QZSettings::tts_max_resistance, QZSettings::default_tts_max_resistance).toBool()) - s.append(tr(", max resistance ") + + s.append((description ? tr(", max resistance ") : "") + QString::number(bluetoothManager->device()->currentResistance().max(), 'f', 0)); if (settings.value(QZSettings::tts_act_watt, QZSettings::default_tts_act_watt).toBool()) - s.append(tr(", watt ") + + s.append((description ? tr(", watt ") : "") + QString::number(bluetoothManager->device()->wattsMetric().value(), 'f', 0)); if (settings.value(QZSettings::tts_avg_watt, QZSettings::default_tts_avg_watt).toBool()) - s.append(tr(", average watt ") + + s.append((description ? tr(", average watt ") : "") + QString::number(bluetoothManager->device()->wattsMetric().average(), 'f', 0)); if (settings.value(QZSettings::tts_max_watt, QZSettings::default_tts_max_watt).toBool()) - s.append(tr(", max watt ") + + s.append((description ? tr(", max watt ") : "") + QString::number(bluetoothManager->device()->wattsMetric().max(), 'f', 0)); if (settings.value(QZSettings::tts_act_ftp, QZSettings::default_tts_act_ftp /* true */).toBool()) - s.append(tr(", ftp ") + QString::number(ftpZone, 'f', 1)); + s.append((description ? tr(", ftp ") : "") + QString::number(ftpZone, 'f', 1)); if (settings.value(QZSettings::tts_act_heart, QZSettings::default_tts_act_heart).toBool()) - s.append(tr(", heart rate ") + + s.append((description ? tr(", heart rate ") : "") + QString::number(bluetoothManager->device()->currentHeart().value(), 'f', 0)); if (settings.value(QZSettings::tts_avg_heart, QZSettings::default_tts_avg_heart).toBool()) - s.append(tr(", average heart rate ") + + s.append((description ? tr(", average heart rate ") : "") + QString::number(bluetoothManager->device()->currentHeart().average(), 'f', 0)); if (settings.value(QZSettings::tts_max_heart, QZSettings::default_tts_max_heart).toBool()) - s.append(tr(", max heart rate ") + + s.append((description ? tr(", max heart rate ") : "") + QString::number(bluetoothManager->device()->currentHeart().max(), 'f', 0)); if (settings.value(QZSettings::tts_act_jouls, QZSettings::default_tts_act_jouls).toBool()) - s.append(tr(", jouls ") + QString::number(bluetoothManager->device()->jouls().max(), 'f', 0)); + s.append((description ? tr(", jouls ") : "") + + QString::number(bluetoothManager->device()->jouls().max(), 'f', 0)); if (settings.value(QZSettings::tts_act_elapsed, QZSettings::default_tts_act_elapsed).toBool()) - s.append(tr(", elapsed ") + - QString::number(bluetoothManager->device()->elapsedTime().minute()) + tr(" minutes ") + - QString::number(bluetoothManager->device()->elapsedTime().second()) + tr(" seconds")); + s.append((description ? tr(", elapsed ") : "") + + QString::number(bluetoothManager->device()->elapsedTime().minute()) + + (description ? tr(" minutes ") : "") + + QString::number(bluetoothManager->device()->elapsedTime().second()) + + (description ? tr(" seconds") : "")); if (settings .value(QZSettings::tts_act_peloton_resistance, QZSettings::default_tts_act_peloton_resistance) .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) s.append( - tr(", peloton resistance ") + + (description ? tr(", peloton resistance ") : "") + QString::number(((bike *)bluetoothManager->device())->pelotonResistance().value(), 'f', 0)); if (settings .value(QZSettings::tts_avg_peloton_resistance, QZSettings::default_tts_avg_peloton_resistance) .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) - s.append(tr(", average peloton resistance ") + + s.append((description ? tr(", average peloton resistance ") : "") + QString::number(((bike *)bluetoothManager->device())->pelotonResistance().average(), 'f', 0)); if (settings @@ -3383,61 +3389,61 @@ void homeform::update() { .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) s.append( - tr(", max peloton resistance ") + + (description ? tr(", max peloton resistance ") : "") + QString::number(((bike *)bluetoothManager->device())->pelotonResistance().max(), 'f', 0)); if (settings .value(QZSettings::tts_act_target_peloton_resistance, QZSettings::default_tts_act_target_peloton_resistance) .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) - s.append(tr(", target peloton resistance ") + + s.append((description ? tr(", target peloton resistance ") : "") + QString::number( ((bike *)bluetoothManager->device())->lastRequestedPelotonResistance().value(), 'f', 0)); if (settings.value(QZSettings::tts_act_target_cadence, QZSettings::default_tts_act_target_cadence) .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) - s.append(tr(", target cadence ") + + s.append((description ? tr(", target cadence ") : "") + QString::number(((bike *)bluetoothManager->device())->lastRequestedCadence().value(), 'f', 0)); if (settings.value(QZSettings::tts_act_target_power, QZSettings::default_tts_act_target_power) .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) - s.append(tr(", target power ") + + s.append((description ? tr(", target power ") : "") + QString::number(((bike *)bluetoothManager->device())->lastRequestedPower().value(), 'f', 0)); if (settings.value(QZSettings::tts_act_target_zone, QZSettings::default_tts_act_target_zone) .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) - s.append(tr(", target zone ") + QString::number(requestedZone, 'f', 1)); + s.append((description ? tr(", target zone ") : "") + QString::number(requestedZone, 'f', 1)); if (settings.value(QZSettings::tts_act_target_speed, QZSettings::default_tts_act_target_speed) .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) - s.append(tr(", target speed ") + + s.append((description ? tr(", target speed ") : "") + (!miles ? QString::number( ((treadmill *)bluetoothManager->device())->lastRequestedSpeed().value(), 'f', 1) + - tr(" kilometers per hour") + (description ? tr(" kilometers per hour") : "") : QString::number( ((treadmill *)bluetoothManager->device())->lastRequestedSpeed().value() * unit_conversion, 'f', 1)) + - tr(" miles per hour")); + (description ? tr(" miles per hour") : "")); if (settings.value(QZSettings::tts_act_target_incline, QZSettings::default_tts_act_target_incline) .toBool() && bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) s.append( - tr(", target incline ") + + (description ? tr(", target incline ") : "") + QString::number( ((treadmill *)bluetoothManager->device())->lastRequestedInclination().value(), 'f', 1)); if (settings.value(QZSettings::tts_act_watt_kg, QZSettings::default_tts_act_watt_kg).toBool()) - s.append(tr(", watt for kilograms ") + + s.append((description ? tr(", watt for kilograms ") : "") + QString::number(bluetoothManager->device()->wattKg().value(), 'f', 1)); if (settings.value(QZSettings::tts_avg_watt_kg, QZSettings::default_tts_avg_watt_kg).toBool()) - s.append(tr(", average watt for kilograms") + + s.append((description ? tr(", average watt for kilograms") : "") + QString::number(bluetoothManager->device()->wattKg().average(), 'f', 1)); if (settings.value(QZSettings::tts_max_watt_kg, QZSettings::default_tts_max_watt_kg).toBool()) - s.append(tr(", max watt for kilograms") + + s.append((description ? tr(", max watt for kilograms") : "") + QString::number(bluetoothManager->device()->wattKg().max(), 'f', 1)); qDebug() << "tts" << s; @@ -4640,7 +4646,7 @@ void homeform::licenseTimeout() { setLicensePopupVisible(true); } void homeform::changeTimestamp(QTime source, QTime actual) { QSettings settings; // only needed if a gpx is loaded and the video is visible, otherwise do nothing. - if ( (trainProgram) && (videoVisible() == true) ) { + if ((trainProgram) && (videoVisible() == true)) { QObject *rootObject = engine->rootObjects().constFirst(); auto *videoPlaybackHalf = rootObject->findChild(QStringLiteral("videoplaybackhalf")); auto videoPlaybackHalfPlayer = qvariant_cast(videoPlaybackHalf->property("mediaObject")); @@ -4650,7 +4656,7 @@ void homeform::changeTimestamp(QTime source, QTime actual) { double videoLengthSeconds = ((double)(videoPlaybackHalfPlayer->duration() / 1000.0)); double trainProgramLengthSeconds = ((double)(trainProgram->TotalGPXSecs())); // check if there is a difference >= 1 second - if ((fabs(videoLengthSeconds - trainProgramLengthSeconds))>=1.0) { + if ((fabs(videoLengthSeconds - trainProgramLengthSeconds)) >= 1.0) { // correct Video TimeStamp by difference videoTimeStampSeconds = (videoTimeStampSeconds - videoLengthSeconds + trainProgramLengthSeconds); } @@ -4661,31 +4667,37 @@ void homeform::changeTimestamp(QTime source, QTime actual) { } // Video was just displayed, set the start Position if (videoMustBeReset) { - int videoStartPos = ((QTime(0, 0, 0).secsTo(source) +((int)(videoLengthSeconds))-((int)(trainProgramLengthSeconds)))); - // if videoStartPos is negativ the Video is shorter then the GPX. Wait for the gpx to reach a point where the Video can be played + int videoStartPos = ((QTime(0, 0, 0).secsTo(source) + ((int)(videoLengthSeconds)) - + ((int)(trainProgramLengthSeconds)))); + // if videoStartPos is negativ the Video is shorter then the GPX. Wait for the gpx to reach a point + // where the Video can be played if (videoStartPos >= 0) { - videoPlaybackHalfPlayer->setPosition(videoStartPos*1000); - videoTimeStampSeconds=(((double)(videoStartPos)) - videoLengthSeconds + trainProgramLengthSeconds); + videoPlaybackHalfPlayer->setPosition(videoStartPos * 1000); + videoTimeStampSeconds = + (((double)(videoStartPos)) - videoLengthSeconds + trainProgramLengthSeconds); videoMustBeReset = false; } } // Video is started now, calculate and set the Rate if (!videoMustBeReset) { // calculate and set the new Video Rate - double rate = trainProgram->TimeRateFromGPX(((double)QTime(0, 0, 0).msecsTo(source)) / 1000.0, videoTimeStampSeconds, bluetoothManager->device()->currentSpeed().average5s()); + double rate = trainProgram->TimeRateFromGPX(((double)QTime(0, 0, 0).msecsTo(source)) / 1000.0, + videoTimeStampSeconds, + bluetoothManager->device()->currentSpeed().average5s()); setVideoRate(rate); } } } - if(!videoVisible()) { + if (!videoVisible()) { // set the maximum Speed that the player can reached based on the Video speed. // When Video is not displayed (or not displayed any longer) remove the Limit if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { - bike * dev = (bike *)bluetoothManager->device(); - dev->setSpeedLimit(0); + bike *dev = (bike *)bluetoothManager->device(); + dev->setSpeedLimit(0); } - // Prepare for a possible Video play. Set the Start Position to 1 and a Rate so low that only a few frames are played + // Prepare for a possible Video play. Set the Start Position to 1 and a Rate so low that only a few frames are + // played setVideoPosition(1); setVideoRate(0.01); videoMustBeReset = true; diff --git a/src/qzsettings.cpp b/src/qzsettings.cpp index 899b5607c..129520c89 100644 --- a/src/qzsettings.cpp +++ b/src/qzsettings.cpp @@ -1,835 +1,842 @@ -#include -#include #include "qzsettings.h" -const QString QZSettings:: cryptoKeySettingsProfiles = QStringLiteral("cryptoKeySettingsProfiles"); -const QString QZSettings:: bluetooth_no_reconnection = QStringLiteral("bluetooth_no_reconnection"); -const QString QZSettings:: bike_wheel_revs = QStringLiteral("bike_wheel_revs"); -const QString QZSettings:: bluetooth_lastdevice_name = QStringLiteral("bluetooth_lastdevice_name"); -const QString QZSettings:: default_bluetooth_lastdevice_name = QStringLiteral(""); -const QString QZSettings:: bluetooth_lastdevice_address = QStringLiteral("bluetooth_lastdevice_address"); -const QString QZSettings:: default_bluetooth_lastdevice_address = QStringLiteral(""); -const QString QZSettings:: hrm_lastdevice_name = QStringLiteral("hrm_lastdevice_name"); -const QString QZSettings:: default_hrm_lastdevice_name = QStringLiteral(""); -const QString QZSettings:: hrm_lastdevice_address = QStringLiteral("hrm_lastdevice_address"); -const QString QZSettings:: default_hrm_lastdevice_address = QStringLiteral(""); -const QString QZSettings:: ftms_accessory_address = QStringLiteral("ftms_accessory_address"); -const QString QZSettings:: default_ftms_accessory_address = QStringLiteral(""); -const QString QZSettings:: ftms_accessory_lastdevice_name = QStringLiteral("ftms_accessory_lastdevice_name"); -const QString QZSettings:: default_ftms_accessory_lastdevice_name = QStringLiteral(""); -const QString QZSettings:: csc_sensor_address = QStringLiteral("csc_sensor_address"); -const QString QZSettings:: default_csc_sensor_address = QStringLiteral(""); -const QString QZSettings:: csc_sensor_lastdevice_name = QStringLiteral("csc_sensor_lastdevice_name"); -const QString QZSettings:: default_csc_sensor_lastdevice_name = QStringLiteral(""); -const QString QZSettings:: power_sensor_lastdevice_name = QStringLiteral("power_sensor_lastdevice_name"); -const QString QZSettings:: default_power_sensor_lastdevice_name = QStringLiteral(""); -const QString QZSettings:: power_sensor_address = QStringLiteral("power_sensor_address"); -const QString QZSettings:: default_power_sensor_address = QStringLiteral(""); -const QString QZSettings:: elite_rizer_lastdevice_name = QStringLiteral("elite_rizer_lastdevice_name"); -const QString QZSettings:: default_elite_rizer_lastdevice_name = QStringLiteral(""); -const QString QZSettings:: elite_rizer_address = QStringLiteral("elite_rizer_address"); -const QString QZSettings:: default_elite_rizer_address = QStringLiteral(""); -const QString QZSettings:: elite_sterzo_smart_lastdevice_name = QStringLiteral("elite_sterzo_smart_lastdevice_name"); -const QString QZSettings:: default_elite_sterzo_smart_lastdevice_name = QStringLiteral(""); -const QString QZSettings:: elite_sterzo_smart_address = QStringLiteral("elite_sterzo_smart_address"); -const QString QZSettings:: default_elite_sterzo_smart_address = QStringLiteral(""); -const QString QZSettings:: strava_accesstoken = QStringLiteral("strava_accesstoken"); -const QString QZSettings:: default_strava_accesstoken = QStringLiteral(""); -const QString QZSettings:: strava_refreshtoken = QStringLiteral("strava_refreshtoken"); -const QString QZSettings:: default_strava_refreshtoken = QStringLiteral(""); -const QString QZSettings:: strava_lastrefresh = QStringLiteral("strava_lastrefresh"); -const QString QZSettings:: default_strava_lastrefresh = QStringLiteral(""); -const QString QZSettings:: strava_expires = QStringLiteral("strava_expires"); -const QString QZSettings:: default_strava_expires = QStringLiteral(""); -const QString QZSettings:: code = QStringLiteral("code"); -const QString QZSettings:: default_code = QStringLiteral(""); +#include +#include +const QString QZSettings::cryptoKeySettingsProfiles = QStringLiteral("cryptoKeySettingsProfiles"); +const QString QZSettings::bluetooth_no_reconnection = QStringLiteral("bluetooth_no_reconnection"); +const QString QZSettings::bike_wheel_revs = QStringLiteral("bike_wheel_revs"); +const QString QZSettings::bluetooth_lastdevice_name = QStringLiteral("bluetooth_lastdevice_name"); +const QString QZSettings::default_bluetooth_lastdevice_name = QStringLiteral(""); +const QString QZSettings::bluetooth_lastdevice_address = QStringLiteral("bluetooth_lastdevice_address"); +const QString QZSettings::default_bluetooth_lastdevice_address = QStringLiteral(""); +const QString QZSettings::hrm_lastdevice_name = QStringLiteral("hrm_lastdevice_name"); +const QString QZSettings::default_hrm_lastdevice_name = QStringLiteral(""); +const QString QZSettings::hrm_lastdevice_address = QStringLiteral("hrm_lastdevice_address"); +const QString QZSettings::default_hrm_lastdevice_address = QStringLiteral(""); +const QString QZSettings::ftms_accessory_address = QStringLiteral("ftms_accessory_address"); +const QString QZSettings::default_ftms_accessory_address = QStringLiteral(""); +const QString QZSettings::ftms_accessory_lastdevice_name = QStringLiteral("ftms_accessory_lastdevice_name"); +const QString QZSettings::default_ftms_accessory_lastdevice_name = QStringLiteral(""); +const QString QZSettings::csc_sensor_address = QStringLiteral("csc_sensor_address"); +const QString QZSettings::default_csc_sensor_address = QStringLiteral(""); +const QString QZSettings::csc_sensor_lastdevice_name = QStringLiteral("csc_sensor_lastdevice_name"); +const QString QZSettings::default_csc_sensor_lastdevice_name = QStringLiteral(""); +const QString QZSettings::power_sensor_lastdevice_name = QStringLiteral("power_sensor_lastdevice_name"); +const QString QZSettings::default_power_sensor_lastdevice_name = QStringLiteral(""); +const QString QZSettings::power_sensor_address = QStringLiteral("power_sensor_address"); +const QString QZSettings::default_power_sensor_address = QStringLiteral(""); +const QString QZSettings::elite_rizer_lastdevice_name = QStringLiteral("elite_rizer_lastdevice_name"); +const QString QZSettings::default_elite_rizer_lastdevice_name = QStringLiteral(""); +const QString QZSettings::elite_rizer_address = QStringLiteral("elite_rizer_address"); +const QString QZSettings::default_elite_rizer_address = QStringLiteral(""); +const QString QZSettings::elite_sterzo_smart_lastdevice_name = QStringLiteral("elite_sterzo_smart_lastdevice_name"); +const QString QZSettings::default_elite_sterzo_smart_lastdevice_name = QStringLiteral(""); +const QString QZSettings::elite_sterzo_smart_address = QStringLiteral("elite_sterzo_smart_address"); +const QString QZSettings::default_elite_sterzo_smart_address = QStringLiteral(""); +const QString QZSettings::strava_accesstoken = QStringLiteral("strava_accesstoken"); +const QString QZSettings::default_strava_accesstoken = QStringLiteral(""); +const QString QZSettings::strava_refreshtoken = QStringLiteral("strava_refreshtoken"); +const QString QZSettings::default_strava_refreshtoken = QStringLiteral(""); +const QString QZSettings::strava_lastrefresh = QStringLiteral("strava_lastrefresh"); +const QString QZSettings::default_strava_lastrefresh = QStringLiteral(""); +const QString QZSettings::strava_expires = QStringLiteral("strava_expires"); +const QString QZSettings::default_strava_expires = QStringLiteral(""); +const QString QZSettings::code = QStringLiteral("code"); +const QString QZSettings::default_code = QStringLiteral(""); //-------------------------------------------------------------------------------------------- -const QString QZSettings:: ui_zoom = QStringLiteral("ui_zoom"); -const QString QZSettings:: bike_heartrate_service = QStringLiteral("bike_heartrate_service"); -const QString QZSettings:: bike_resistance_offset = QStringLiteral("bike_resistance_offset"); -const QString QZSettings:: bike_resistance_gain_f = QStringLiteral("bike_resistance_gain_f"); -const QString QZSettings:: zwift_erg = QStringLiteral("zwift_erg"); -const QString QZSettings:: zwift_erg_filter = QStringLiteral("zwift_erg_filter"); -const QString QZSettings:: zwift_erg_filter_down = QStringLiteral("zwift_erg_filter_down"); -const QString QZSettings:: zwift_negative_inclination_x2 = QStringLiteral("zwift_negative_inclination_x2"); -const QString QZSettings:: zwift_inclination_offset = QStringLiteral("zwift_inclination_offset"); -const QString QZSettings:: zwift_inclination_gain = QStringLiteral("zwift_inclination_gain"); -const QString QZSettings:: echelon_resistance_offset = QStringLiteral("echelon_resistance_offset"); -const QString QZSettings:: echelon_resistance_gain = QStringLiteral("echelon_resistance_gain"); -const QString QZSettings:: speed_power_based = QStringLiteral("speed_power_based"); -const QString QZSettings:: bike_resistance_start = QStringLiteral("bike_resistance_start"); -const QString QZSettings:: age = QStringLiteral("age"); -const QString QZSettings:: weight = QStringLiteral("weight"); -const QString QZSettings:: ftp = QStringLiteral("ftp"); -const QString QZSettings:: user_email = QStringLiteral("user_email"); -const QString QZSettings:: default_user_email = QLatin1String(""); -const QString QZSettings:: user_nickname = QStringLiteral("user_nickname"); -const QString QZSettings:: default_user_nickname = QStringLiteral(""); -const QString QZSettings:: miles_unit = QStringLiteral("miles_unit"); -const QString QZSettings:: pause_on_start = QStringLiteral("pause_on_start"); -const QString QZSettings:: treadmill_force_speed = QStringLiteral("treadmill_force_speed"); -const QString QZSettings:: pause_on_start_treadmill = QStringLiteral("pause_on_start_treadmill"); -const QString QZSettings:: continuous_moving = QStringLiteral("continuous_moving"); -const QString QZSettings:: bike_cadence_sensor = QStringLiteral("bike_cadence_sensor"); -const QString QZSettings:: run_cadence_sensor = QStringLiteral("run_cadence_sensor"); -const QString QZSettings:: bike_power_sensor = QStringLiteral("bike_power_sensor"); -const QString QZSettings:: heart_rate_belt_name = QStringLiteral("heart_rate_belt_name"); -const QString QZSettings:: default_heart_rate_belt_name = QStringLiteral("Disabled"); -const QString QZSettings:: heart_ignore_builtin = QStringLiteral("heart_ignore_builtin"); -const QString QZSettings:: kcal_ignore_builtin = QStringLiteral("kcal_ignore_builtin"); -const QString QZSettings:: ant_cadence = QStringLiteral("ant_cadence"); -const QString QZSettings:: ant_heart = QStringLiteral("ant_heart"); -const QString QZSettings:: ant_garmin = QStringLiteral("ant_garmin"); -const QString QZSettings:: top_bar_enabled = QStringLiteral("top_bar_enabled"); -const QString QZSettings:: peloton_username = QStringLiteral("peloton_username"); -const QString QZSettings:: default_peloton_username = QStringLiteral("username"); -const QString QZSettings:: peloton_password = QStringLiteral("peloton_password"); -const QString QZSettings:: default_peloton_password = QStringLiteral("password"); -const QString QZSettings:: peloton_difficulty = QStringLiteral("peloton_difficulty"); -const QString QZSettings:: default_peloton_difficulty = QStringLiteral("lower"); -const QString QZSettings:: peloton_cadence_metric = QStringLiteral("peloton_cadence_metric"); -const QString QZSettings:: default_peloton_cadence_metric = QStringLiteral("Cadence"); -const QString QZSettings:: peloton_heartrate_metric = QStringLiteral("peloton_heartrate_metric"); -const QString QZSettings:: default_peloton_heartrate_metric = QStringLiteral("Heart Rate"); -const QString QZSettings:: peloton_date = QStringLiteral("peloton_date"); -const QString QZSettings:: default_peloton_date = QStringLiteral("Before Title"); -const QString QZSettings:: peloton_description_link = QStringLiteral("peloton_description_link"); -const QString QZSettings:: pzp_username = QStringLiteral("pzp_username"); -const QString QZSettings:: default_pzp_username = QStringLiteral("username"); -const QString QZSettings:: pzp_password = QStringLiteral("pzp_password"); -const QString QZSettings:: default_pzp_password = QStringLiteral("username"); -const QString QZSettings:: tile_speed_enabled = QStringLiteral("tile_speed_enabled"); -const QString QZSettings:: tile_speed_order = QStringLiteral("tile_speed_order"); -const QString QZSettings:: tile_inclination_enabled = QStringLiteral("tile_inclination_enabled"); -const QString QZSettings:: tile_inclination_order = QStringLiteral("tile_inclination_order"); -const QString QZSettings:: tile_cadence_enabled = QStringLiteral("tile_cadence_enabled"); -const QString QZSettings:: tile_cadence_order = QStringLiteral("tile_cadence_order"); -const QString QZSettings:: tile_elevation_enabled = QStringLiteral("tile_elevation_enabled"); -const QString QZSettings:: tile_elevation_order = QStringLiteral("tile_elevation_order"); -const QString QZSettings:: tile_calories_enabled = QStringLiteral("tile_calories_enabled"); -const QString QZSettings:: tile_calories_order = QStringLiteral("tile_calories_order"); -const QString QZSettings:: tile_odometer_enabled = QStringLiteral("tile_odometer_enabled"); -const QString QZSettings:: tile_odometer_order = QStringLiteral("tile_odometer_order"); -const QString QZSettings:: tile_pace_enabled = QStringLiteral("tile_pace_enabled"); -const QString QZSettings:: tile_pace_order = QStringLiteral("tile_pace_order"); -const QString QZSettings:: tile_resistance_enabled = QStringLiteral("tile_resistance_enabled"); -const QString QZSettings:: tile_resistance_order = QStringLiteral("tile_resistance_order"); -const QString QZSettings:: tile_watt_enabled = QStringLiteral("tile_watt_enabled"); -const QString QZSettings:: tile_watt_order = QStringLiteral("tile_watt_order"); -const QString QZSettings:: tile_weight_loss_enabled = QStringLiteral("tile_weight_loss_enabled"); -const QString QZSettings:: tile_weight_loss_order = QStringLiteral("tile_weight_loss_order"); -const QString QZSettings:: tile_avgwatt_enabled = QStringLiteral("tile_avgwatt_enabled"); -const QString QZSettings:: tile_avgwatt_order = QStringLiteral("tile_avgwatt_order"); -const QString QZSettings:: tile_ftp_enabled = QStringLiteral("tile_ftp_enabled"); -const QString QZSettings:: tile_ftp_order = QStringLiteral("tile_ftp_order"); -const QString QZSettings:: tile_heart_enabled = QStringLiteral("tile_heart_enabled"); -const QString QZSettings:: tile_heart_order = QStringLiteral("tile_heart_order"); -const QString QZSettings:: tile_fan_enabled = QStringLiteral("tile_fan_enabled"); -const QString QZSettings:: tile_fan_order = QStringLiteral("tile_fan_order"); -const QString QZSettings:: tile_jouls_enabled = QStringLiteral("tile_jouls_enabled"); -const QString QZSettings:: tile_jouls_order = QStringLiteral("tile_jouls_order"); -const QString QZSettings:: tile_elapsed_enabled = QStringLiteral("tile_elapsed_enabled"); -const QString QZSettings:: tile_elapsed_order = QStringLiteral("tile_elapsed_order"); -const QString QZSettings:: tile_lapelapsed_enabled = QStringLiteral("tile_lapelapsed_enabled"); -const QString QZSettings:: tile_lapelapsed_order = QStringLiteral("tile_lapelapsed_order"); -const QString QZSettings:: tile_moving_time_enabled = QStringLiteral("tile_moving_time_enabled"); -const QString QZSettings:: tile_moving_time_order = QStringLiteral("tile_moving_time_order"); -const QString QZSettings:: tile_peloton_offset_enabled = QStringLiteral("tile_peloton_offset_enabled"); -const QString QZSettings:: tile_peloton_offset_order = QStringLiteral("tile_peloton_offset_order"); -const QString QZSettings:: tile_peloton_difficulty_enabled = QStringLiteral("tile_peloton_difficulty_enabled"); -const QString QZSettings:: tile_peloton_difficulty_order = QStringLiteral("tile_peloton_difficulty_order"); -const QString QZSettings:: tile_peloton_resistance_enabled = QStringLiteral("tile_peloton_resistance_enabled"); -const QString QZSettings:: tile_peloton_resistance_order = QStringLiteral("tile_peloton_resistance_order"); -const QString QZSettings:: tile_datetime_enabled = QStringLiteral("tile_datetime_enabled"); -const QString QZSettings:: tile_datetime_order = QStringLiteral("tile_datetime_order"); -const QString QZSettings:: tile_target_resistance_enabled = QStringLiteral("tile_target_resistance_enabled"); -const QString QZSettings:: tile_target_resistance_order = QStringLiteral("tile_target_resistance_order"); -const QString QZSettings:: tile_target_peloton_resistance_enabled = QStringLiteral("tile_target_peloton_resistance_enabled"); -const QString QZSettings:: tile_target_peloton_resistance_order = QStringLiteral("tile_target_peloton_resistance_order"); -const QString QZSettings:: tile_target_cadence_enabled = QStringLiteral("tile_target_cadence_enabled"); -const QString QZSettings:: tile_target_cadence_order = QStringLiteral("tile_target_cadence_order"); -const QString QZSettings:: tile_target_power_enabled = QStringLiteral("tile_target_power_enabled"); -const QString QZSettings:: tile_target_power_order = QStringLiteral("tile_target_power_order"); -const QString QZSettings:: tile_target_zone_enabled = QStringLiteral("tile_target_zone_enabled"); -const QString QZSettings:: tile_target_zone_order = QStringLiteral("tile_target_zone_order"); -const QString QZSettings:: tile_target_speed_enabled = QStringLiteral("tile_target_speed_enabled"); -const QString QZSettings:: tile_target_speed_order = QStringLiteral("tile_target_speed_order"); -const QString QZSettings:: tile_target_incline_enabled = QStringLiteral("tile_target_incline_enabled"); -const QString QZSettings:: tile_target_incline_order = QStringLiteral("tile_target_incline_order"); -const QString QZSettings:: tile_strokes_count_enabled = QStringLiteral("tile_strokes_count_enabled"); -const QString QZSettings:: tile_strokes_count_order = QStringLiteral("tile_strokes_count_order"); -const QString QZSettings:: tile_strokes_length_enabled = QStringLiteral("tile_strokes_length_enabled"); -const QString QZSettings:: tile_strokes_length_order = QStringLiteral("tile_strokes_length_order"); -const QString QZSettings:: tile_watt_kg_enabled = QStringLiteral("tile_watt_kg_enabled"); -const QString QZSettings:: tile_watt_kg_order = QStringLiteral("tile_watt_kg_order"); -const QString QZSettings:: tile_gears_enabled = QStringLiteral("tile_gears_enabled"); -const QString QZSettings:: tile_gears_order = QStringLiteral("tile_gears_order"); -const QString QZSettings:: tile_remainingtimetrainprogramrow_enabled = QStringLiteral("tile_remainingtimetrainprogramrow_enabled"); -const QString QZSettings:: tile_remainingtimetrainprogramrow_order = QStringLiteral("tile_remainingtimetrainprogramrow_order"); -const QString QZSettings:: tile_nextrowstrainprogram_enabled = QStringLiteral("tile_nextrowstrainprogram_enabled"); -const QString QZSettings:: tile_nextrowstrainprogram_order = QStringLiteral("tile_nextrowstrainprogram_order"); -const QString QZSettings:: tile_mets_enabled = QStringLiteral("tile_mets_enabled"); -const QString QZSettings:: tile_mets_order = QStringLiteral("tile_mets_order"); -const QString QZSettings:: tile_targetmets_enabled = QStringLiteral("tile_targetmets_enabled"); -const QString QZSettings:: tile_targetmets_order = QStringLiteral("tile_targetmets_order"); -const QString QZSettings:: tile_steering_angle_enabled = QStringLiteral("tile_steering_angle_enabled"); -const QString QZSettings:: tile_steering_angle_order = QStringLiteral("tile_steering_angle_order"); -const QString QZSettings:: tile_pid_hr_enabled = QStringLiteral("tile_pid_hr_enabled"); -const QString QZSettings:: tile_pid_hr_order = QStringLiteral("tile_pid_hr_order"); -const QString QZSettings:: heart_rate_zone1 = QStringLiteral("heart_rate_zone1"); -const QString QZSettings:: heart_rate_zone2 = QStringLiteral("heart_rate_zone2"); -const QString QZSettings:: heart_rate_zone3 = QStringLiteral("heart_rate_zone3"); -const QString QZSettings:: heart_rate_zone4 = QStringLiteral("heart_rate_zone4"); -const QString QZSettings:: heart_max_override_enable = QStringLiteral("heart_max_override_enable"); -const QString QZSettings:: heart_max_override_value = QStringLiteral("heart_max_override_value"); -const QString QZSettings:: peloton_gain = QStringLiteral("peloton_gain"); -const QString QZSettings:: peloton_offset = QStringLiteral("peloton_offset"); -const QString QZSettings:: treadmill_pid_heart_zone = QStringLiteral("treadmill_pid_heart_zone"); -const QString QZSettings:: default_treadmill_pid_heart_zone = QStringLiteral("Disabled"); -const QString QZSettings:: pacef_1mile = QStringLiteral("pacef_1mile"); -const QString QZSettings:: pacef_5km = QStringLiteral("pacef_5km"); -const QString QZSettings:: pacef_10km = QStringLiteral("pacef_10km"); -const QString QZSettings:: pacef_halfmarathon = QStringLiteral("pacef_halfmarathon"); -const QString QZSettings:: pacef_marathon = QStringLiteral("pacef_marathon"); -const QString QZSettings:: pace_default = QStringLiteral("pace_default"); -const QString QZSettings:: default_pace_default = QStringLiteral("Half Marathon"); -const QString QZSettings:: domyos_treadmill_buttons = QStringLiteral("domyos_treadmill_buttons"); -const QString QZSettings:: domyos_treadmill_distance_display = QStringLiteral("domyos_treadmill_distance_display"); -const QString QZSettings:: domyos_treadmill_display_invert = QStringLiteral("domyos_treadmill_display_invert"); -const QString QZSettings:: domyos_bike_cadence_filter = QStringLiteral("domyos_bike_cadence_filter"); -const QString QZSettings:: domyos_bike_display_calories = QStringLiteral("domyos_bike_display_calories"); -const QString QZSettings:: domyos_elliptical_speed_ratio = QStringLiteral("domyos_elliptical_speed_ratio"); -const QString QZSettings:: eslinker_cadenza = QStringLiteral("eslinker_cadenza"); -const QString QZSettings:: eslinker_ypoo = QStringLiteral("eslinker_ypoo"); -const QString QZSettings:: echelon_watttable = QStringLiteral("echelon_watttable"); -const QString QZSettings:: default_echelon_watttable = QStringLiteral("Echelon"); -const QString QZSettings:: proform_wheel_ratio = QStringLiteral("proform_wheel_ratio"); -const QString QZSettings:: proform_tour_de_france_clc = QStringLiteral("proform_tour_de_france_clc"); -const QString QZSettings:: proform_tdf_jonseed_watt = QStringLiteral("proform_tdf_jonseed_watt"); -const QString QZSettings:: proform_studio = QStringLiteral("proform_studio"); -const QString QZSettings:: proform_tdf_10 = QStringLiteral("proform_tdf_10"); -const QString QZSettings:: horizon_gr7_cadence_multiplier = QStringLiteral("horizon_gr7_cadence_multiplier"); -const QString QZSettings:: fitshow_user_id = QStringLiteral("fitshow_user_id"); -const QString QZSettings:: inspire_peloton_formula = QStringLiteral("inspire_peloton_formula"); -const QString QZSettings:: inspire_peloton_formula2 = QStringLiteral("inspire_peloton_formula2"); -const QString QZSettings:: hammer_racer_s = QStringLiteral("hammer_racer_s"); -const QString QZSettings:: pafers_treadmill = QStringLiteral("pafers_treadmill"); -const QString QZSettings:: yesoul_peloton_formula = QStringLiteral("yesoul_peloton_formula"); -const QString QZSettings:: nordictrack_10_treadmill = QStringLiteral("nordictrack_10_treadmill"); -const QString QZSettings:: nordictrack_t65s_treadmill = QStringLiteral("nordictrack_t65s_treadmill"); -//const QString QZSettings:: proform_treadmill_995i = QStringLiteral("proform_treadmill_995i"); +const QString QZSettings::ui_zoom = QStringLiteral("ui_zoom"); +const QString QZSettings::bike_heartrate_service = QStringLiteral("bike_heartrate_service"); +const QString QZSettings::bike_resistance_offset = QStringLiteral("bike_resistance_offset"); +const QString QZSettings::bike_resistance_gain_f = QStringLiteral("bike_resistance_gain_f"); +const QString QZSettings::zwift_erg = QStringLiteral("zwift_erg"); +const QString QZSettings::zwift_erg_filter = QStringLiteral("zwift_erg_filter"); +const QString QZSettings::zwift_erg_filter_down = QStringLiteral("zwift_erg_filter_down"); +const QString QZSettings::zwift_negative_inclination_x2 = QStringLiteral("zwift_negative_inclination_x2"); +const QString QZSettings::zwift_inclination_offset = QStringLiteral("zwift_inclination_offset"); +const QString QZSettings::zwift_inclination_gain = QStringLiteral("zwift_inclination_gain"); +const QString QZSettings::echelon_resistance_offset = QStringLiteral("echelon_resistance_offset"); +const QString QZSettings::echelon_resistance_gain = QStringLiteral("echelon_resistance_gain"); +const QString QZSettings::speed_power_based = QStringLiteral("speed_power_based"); +const QString QZSettings::bike_resistance_start = QStringLiteral("bike_resistance_start"); +const QString QZSettings::age = QStringLiteral("age"); +const QString QZSettings::weight = QStringLiteral("weight"); +const QString QZSettings::ftp = QStringLiteral("ftp"); +const QString QZSettings::user_email = QStringLiteral("user_email"); +const QString QZSettings::default_user_email = QLatin1String(""); +const QString QZSettings::user_nickname = QStringLiteral("user_nickname"); +const QString QZSettings::default_user_nickname = QStringLiteral(""); +const QString QZSettings::miles_unit = QStringLiteral("miles_unit"); +const QString QZSettings::pause_on_start = QStringLiteral("pause_on_start"); +const QString QZSettings::treadmill_force_speed = QStringLiteral("treadmill_force_speed"); +const QString QZSettings::pause_on_start_treadmill = QStringLiteral("pause_on_start_treadmill"); +const QString QZSettings::continuous_moving = QStringLiteral("continuous_moving"); +const QString QZSettings::bike_cadence_sensor = QStringLiteral("bike_cadence_sensor"); +const QString QZSettings::run_cadence_sensor = QStringLiteral("run_cadence_sensor"); +const QString QZSettings::bike_power_sensor = QStringLiteral("bike_power_sensor"); +const QString QZSettings::heart_rate_belt_name = QStringLiteral("heart_rate_belt_name"); +const QString QZSettings::default_heart_rate_belt_name = QStringLiteral("Disabled"); +const QString QZSettings::heart_ignore_builtin = QStringLiteral("heart_ignore_builtin"); +const QString QZSettings::kcal_ignore_builtin = QStringLiteral("kcal_ignore_builtin"); +const QString QZSettings::ant_cadence = QStringLiteral("ant_cadence"); +const QString QZSettings::ant_heart = QStringLiteral("ant_heart"); +const QString QZSettings::ant_garmin = QStringLiteral("ant_garmin"); +const QString QZSettings::top_bar_enabled = QStringLiteral("top_bar_enabled"); +const QString QZSettings::peloton_username = QStringLiteral("peloton_username"); +const QString QZSettings::default_peloton_username = QStringLiteral("username"); +const QString QZSettings::peloton_password = QStringLiteral("peloton_password"); +const QString QZSettings::default_peloton_password = QStringLiteral("password"); +const QString QZSettings::peloton_difficulty = QStringLiteral("peloton_difficulty"); +const QString QZSettings::default_peloton_difficulty = QStringLiteral("lower"); +const QString QZSettings::peloton_cadence_metric = QStringLiteral("peloton_cadence_metric"); +const QString QZSettings::default_peloton_cadence_metric = QStringLiteral("Cadence"); +const QString QZSettings::peloton_heartrate_metric = QStringLiteral("peloton_heartrate_metric"); +const QString QZSettings::default_peloton_heartrate_metric = QStringLiteral("Heart Rate"); +const QString QZSettings::peloton_date = QStringLiteral("peloton_date"); +const QString QZSettings::default_peloton_date = QStringLiteral("Before Title"); +const QString QZSettings::peloton_description_link = QStringLiteral("peloton_description_link"); +const QString QZSettings::pzp_username = QStringLiteral("pzp_username"); +const QString QZSettings::default_pzp_username = QStringLiteral("username"); +const QString QZSettings::pzp_password = QStringLiteral("pzp_password"); +const QString QZSettings::default_pzp_password = QStringLiteral("username"); +const QString QZSettings::tile_speed_enabled = QStringLiteral("tile_speed_enabled"); +const QString QZSettings::tile_speed_order = QStringLiteral("tile_speed_order"); +const QString QZSettings::tile_inclination_enabled = QStringLiteral("tile_inclination_enabled"); +const QString QZSettings::tile_inclination_order = QStringLiteral("tile_inclination_order"); +const QString QZSettings::tile_cadence_enabled = QStringLiteral("tile_cadence_enabled"); +const QString QZSettings::tile_cadence_order = QStringLiteral("tile_cadence_order"); +const QString QZSettings::tile_elevation_enabled = QStringLiteral("tile_elevation_enabled"); +const QString QZSettings::tile_elevation_order = QStringLiteral("tile_elevation_order"); +const QString QZSettings::tile_calories_enabled = QStringLiteral("tile_calories_enabled"); +const QString QZSettings::tile_calories_order = QStringLiteral("tile_calories_order"); +const QString QZSettings::tile_odometer_enabled = QStringLiteral("tile_odometer_enabled"); +const QString QZSettings::tile_odometer_order = QStringLiteral("tile_odometer_order"); +const QString QZSettings::tile_pace_enabled = QStringLiteral("tile_pace_enabled"); +const QString QZSettings::tile_pace_order = QStringLiteral("tile_pace_order"); +const QString QZSettings::tile_resistance_enabled = QStringLiteral("tile_resistance_enabled"); +const QString QZSettings::tile_resistance_order = QStringLiteral("tile_resistance_order"); +const QString QZSettings::tile_watt_enabled = QStringLiteral("tile_watt_enabled"); +const QString QZSettings::tile_watt_order = QStringLiteral("tile_watt_order"); +const QString QZSettings::tile_weight_loss_enabled = QStringLiteral("tile_weight_loss_enabled"); +const QString QZSettings::tile_weight_loss_order = QStringLiteral("tile_weight_loss_order"); +const QString QZSettings::tile_avgwatt_enabled = QStringLiteral("tile_avgwatt_enabled"); +const QString QZSettings::tile_avgwatt_order = QStringLiteral("tile_avgwatt_order"); +const QString QZSettings::tile_ftp_enabled = QStringLiteral("tile_ftp_enabled"); +const QString QZSettings::tile_ftp_order = QStringLiteral("tile_ftp_order"); +const QString QZSettings::tile_heart_enabled = QStringLiteral("tile_heart_enabled"); +const QString QZSettings::tile_heart_order = QStringLiteral("tile_heart_order"); +const QString QZSettings::tile_fan_enabled = QStringLiteral("tile_fan_enabled"); +const QString QZSettings::tile_fan_order = QStringLiteral("tile_fan_order"); +const QString QZSettings::tile_jouls_enabled = QStringLiteral("tile_jouls_enabled"); +const QString QZSettings::tile_jouls_order = QStringLiteral("tile_jouls_order"); +const QString QZSettings::tile_elapsed_enabled = QStringLiteral("tile_elapsed_enabled"); +const QString QZSettings::tile_elapsed_order = QStringLiteral("tile_elapsed_order"); +const QString QZSettings::tile_lapelapsed_enabled = QStringLiteral("tile_lapelapsed_enabled"); +const QString QZSettings::tile_lapelapsed_order = QStringLiteral("tile_lapelapsed_order"); +const QString QZSettings::tile_moving_time_enabled = QStringLiteral("tile_moving_time_enabled"); +const QString QZSettings::tile_moving_time_order = QStringLiteral("tile_moving_time_order"); +const QString QZSettings::tile_peloton_offset_enabled = QStringLiteral("tile_peloton_offset_enabled"); +const QString QZSettings::tile_peloton_offset_order = QStringLiteral("tile_peloton_offset_order"); +const QString QZSettings::tile_peloton_difficulty_enabled = QStringLiteral("tile_peloton_difficulty_enabled"); +const QString QZSettings::tile_peloton_difficulty_order = QStringLiteral("tile_peloton_difficulty_order"); +const QString QZSettings::tile_peloton_resistance_enabled = QStringLiteral("tile_peloton_resistance_enabled"); +const QString QZSettings::tile_peloton_resistance_order = QStringLiteral("tile_peloton_resistance_order"); +const QString QZSettings::tile_datetime_enabled = QStringLiteral("tile_datetime_enabled"); +const QString QZSettings::tile_datetime_order = QStringLiteral("tile_datetime_order"); +const QString QZSettings::tile_target_resistance_enabled = QStringLiteral("tile_target_resistance_enabled"); +const QString QZSettings::tile_target_resistance_order = QStringLiteral("tile_target_resistance_order"); +const QString QZSettings::tile_target_peloton_resistance_enabled = + QStringLiteral("tile_target_peloton_resistance_enabled"); +const QString QZSettings::tile_target_peloton_resistance_order = QStringLiteral("tile_target_peloton_resistance_order"); +const QString QZSettings::tile_target_cadence_enabled = QStringLiteral("tile_target_cadence_enabled"); +const QString QZSettings::tile_target_cadence_order = QStringLiteral("tile_target_cadence_order"); +const QString QZSettings::tile_target_power_enabled = QStringLiteral("tile_target_power_enabled"); +const QString QZSettings::tile_target_power_order = QStringLiteral("tile_target_power_order"); +const QString QZSettings::tile_target_zone_enabled = QStringLiteral("tile_target_zone_enabled"); +const QString QZSettings::tile_target_zone_order = QStringLiteral("tile_target_zone_order"); +const QString QZSettings::tile_target_speed_enabled = QStringLiteral("tile_target_speed_enabled"); +const QString QZSettings::tile_target_speed_order = QStringLiteral("tile_target_speed_order"); +const QString QZSettings::tile_target_incline_enabled = QStringLiteral("tile_target_incline_enabled"); +const QString QZSettings::tile_target_incline_order = QStringLiteral("tile_target_incline_order"); +const QString QZSettings::tile_strokes_count_enabled = QStringLiteral("tile_strokes_count_enabled"); +const QString QZSettings::tile_strokes_count_order = QStringLiteral("tile_strokes_count_order"); +const QString QZSettings::tile_strokes_length_enabled = QStringLiteral("tile_strokes_length_enabled"); +const QString QZSettings::tile_strokes_length_order = QStringLiteral("tile_strokes_length_order"); +const QString QZSettings::tile_watt_kg_enabled = QStringLiteral("tile_watt_kg_enabled"); +const QString QZSettings::tile_watt_kg_order = QStringLiteral("tile_watt_kg_order"); +const QString QZSettings::tile_gears_enabled = QStringLiteral("tile_gears_enabled"); +const QString QZSettings::tile_gears_order = QStringLiteral("tile_gears_order"); +const QString QZSettings::tile_remainingtimetrainprogramrow_enabled = + QStringLiteral("tile_remainingtimetrainprogramrow_enabled"); +const QString QZSettings::tile_remainingtimetrainprogramrow_order = + QStringLiteral("tile_remainingtimetrainprogramrow_order"); +const QString QZSettings::tile_nextrowstrainprogram_enabled = QStringLiteral("tile_nextrowstrainprogram_enabled"); +const QString QZSettings::tile_nextrowstrainprogram_order = QStringLiteral("tile_nextrowstrainprogram_order"); +const QString QZSettings::tile_mets_enabled = QStringLiteral("tile_mets_enabled"); +const QString QZSettings::tile_mets_order = QStringLiteral("tile_mets_order"); +const QString QZSettings::tile_targetmets_enabled = QStringLiteral("tile_targetmets_enabled"); +const QString QZSettings::tile_targetmets_order = QStringLiteral("tile_targetmets_order"); +const QString QZSettings::tile_steering_angle_enabled = QStringLiteral("tile_steering_angle_enabled"); +const QString QZSettings::tile_steering_angle_order = QStringLiteral("tile_steering_angle_order"); +const QString QZSettings::tile_pid_hr_enabled = QStringLiteral("tile_pid_hr_enabled"); +const QString QZSettings::tile_pid_hr_order = QStringLiteral("tile_pid_hr_order"); +const QString QZSettings::heart_rate_zone1 = QStringLiteral("heart_rate_zone1"); +const QString QZSettings::heart_rate_zone2 = QStringLiteral("heart_rate_zone2"); +const QString QZSettings::heart_rate_zone3 = QStringLiteral("heart_rate_zone3"); +const QString QZSettings::heart_rate_zone4 = QStringLiteral("heart_rate_zone4"); +const QString QZSettings::heart_max_override_enable = QStringLiteral("heart_max_override_enable"); +const QString QZSettings::heart_max_override_value = QStringLiteral("heart_max_override_value"); +const QString QZSettings::peloton_gain = QStringLiteral("peloton_gain"); +const QString QZSettings::peloton_offset = QStringLiteral("peloton_offset"); +const QString QZSettings::treadmill_pid_heart_zone = QStringLiteral("treadmill_pid_heart_zone"); +const QString QZSettings::default_treadmill_pid_heart_zone = QStringLiteral("Disabled"); +const QString QZSettings::pacef_1mile = QStringLiteral("pacef_1mile"); +const QString QZSettings::pacef_5km = QStringLiteral("pacef_5km"); +const QString QZSettings::pacef_10km = QStringLiteral("pacef_10km"); +const QString QZSettings::pacef_halfmarathon = QStringLiteral("pacef_halfmarathon"); +const QString QZSettings::pacef_marathon = QStringLiteral("pacef_marathon"); +const QString QZSettings::pace_default = QStringLiteral("pace_default"); +const QString QZSettings::default_pace_default = QStringLiteral("Half Marathon"); +const QString QZSettings::domyos_treadmill_buttons = QStringLiteral("domyos_treadmill_buttons"); +const QString QZSettings::domyos_treadmill_distance_display = QStringLiteral("domyos_treadmill_distance_display"); +const QString QZSettings::domyos_treadmill_display_invert = QStringLiteral("domyos_treadmill_display_invert"); +const QString QZSettings::domyos_bike_cadence_filter = QStringLiteral("domyos_bike_cadence_filter"); +const QString QZSettings::domyos_bike_display_calories = QStringLiteral("domyos_bike_display_calories"); +const QString QZSettings::domyos_elliptical_speed_ratio = QStringLiteral("domyos_elliptical_speed_ratio"); +const QString QZSettings::eslinker_cadenza = QStringLiteral("eslinker_cadenza"); +const QString QZSettings::eslinker_ypoo = QStringLiteral("eslinker_ypoo"); +const QString QZSettings::echelon_watttable = QStringLiteral("echelon_watttable"); +const QString QZSettings::default_echelon_watttable = QStringLiteral("Echelon"); +const QString QZSettings::proform_wheel_ratio = QStringLiteral("proform_wheel_ratio"); +const QString QZSettings::proform_tour_de_france_clc = QStringLiteral("proform_tour_de_france_clc"); +const QString QZSettings::proform_tdf_jonseed_watt = QStringLiteral("proform_tdf_jonseed_watt"); +const QString QZSettings::proform_studio = QStringLiteral("proform_studio"); +const QString QZSettings::proform_tdf_10 = QStringLiteral("proform_tdf_10"); +const QString QZSettings::horizon_gr7_cadence_multiplier = QStringLiteral("horizon_gr7_cadence_multiplier"); +const QString QZSettings::fitshow_user_id = QStringLiteral("fitshow_user_id"); +const QString QZSettings::inspire_peloton_formula = QStringLiteral("inspire_peloton_formula"); +const QString QZSettings::inspire_peloton_formula2 = QStringLiteral("inspire_peloton_formula2"); +const QString QZSettings::hammer_racer_s = QStringLiteral("hammer_racer_s"); +const QString QZSettings::pafers_treadmill = QStringLiteral("pafers_treadmill"); +const QString QZSettings::yesoul_peloton_formula = QStringLiteral("yesoul_peloton_formula"); +const QString QZSettings::nordictrack_10_treadmill = QStringLiteral("nordictrack_10_treadmill"); +const QString QZSettings::nordictrack_t65s_treadmill = QStringLiteral("nordictrack_t65s_treadmill"); +// const QString QZSettings:: proform_treadmill_995i = QStringLiteral("proform_treadmill_995i"); // -const QString QZSettings:: toorx_3_0 = QStringLiteral("toorx_3_0"); -const QString QZSettings:: toorx_65s_evo = QStringLiteral("toorx_65s_evo"); -const QString QZSettings:: jtx_fitness_sprint_treadmill = QStringLiteral("jtx_fitness_sprint_treadmill"); -const QString QZSettings:: dkn_endurun_treadmill = QStringLiteral("dkn_endurun_treadmill"); -const QString QZSettings:: trx_route_key = QStringLiteral("trx_route_key"); -const QString QZSettings:: bh_spada_2 = QStringLiteral("bh_spada_2"); -const QString QZSettings:: toorx_bike = QStringLiteral("toorx_bike"); -const QString QZSettings:: toorx_ftms = QStringLiteral("toorx_ftms"); -const QString QZSettings:: jll_IC400_bike = QStringLiteral("jll_IC400_bike"); -const QString QZSettings:: fytter_ri08_bike = QStringLiteral("fytter_ri08_bike"); -const QString QZSettings:: asviva_bike = QStringLiteral("asviva_bike"); -const QString QZSettings:: hertz_xr_770 = QStringLiteral("hertz_xr_770"); -const QString QZSettings:: m3i_bike_id = QStringLiteral("m3i_bike_id"); -const QString QZSettings:: m3i_bike_speed_buffsize = QStringLiteral("m3i_bike_speed_buffsize"); -const QString QZSettings:: m3i_bike_qt_search = QStringLiteral("m3i_bike_qt_search"); -const QString QZSettings:: m3i_bike_kcal = QStringLiteral("m3i_bike_kcal"); -const QString QZSettings:: snode_bike = QStringLiteral("snode_bike"); -const QString QZSettings:: fitplus_bike = QStringLiteral("fitplus_bike"); -const QString QZSettings:: virtufit_etappe = QStringLiteral("virtufit_etappe"); -const QString QZSettings:: flywheel_filter = QStringLiteral("flywheel_filter"); -const QString QZSettings:: flywheel_life_fitness_ic8 = QStringLiteral("flywheel_life_fitness_ic8"); -const QString QZSettings:: sole_treadmill_inclination = QStringLiteral("sole_treadmill_inclination"); -const QString QZSettings:: sole_treadmill_miles = QStringLiteral("sole_treadmill_miles"); -const QString QZSettings:: sole_treadmill_f65 = QStringLiteral("sole_treadmill_f65"); -const QString QZSettings:: sole_treadmill_f63 = QStringLiteral("sole_treadmill_f63"); -const QString QZSettings:: sole_treadmill_tt8 = QStringLiteral("sole_treadmill_tt8"); -const QString QZSettings:: schwinn_bike_resistance = QStringLiteral("schwinn_bike_resistance"); -const QString QZSettings:: schwinn_bike_resistance_v2 = QStringLiteral("schwinn_bike_resistance_v2"); -const QString QZSettings:: technogym_myrun_treadmill_experimental = QStringLiteral("technogym_myrun_treadmill_experimental"); -const QString QZSettings:: trainprogram_random = QStringLiteral("trainprogram_random"); -const QString QZSettings:: trainprogram_total = QStringLiteral("trainprogram_total"); -const QString QZSettings:: trainprogram_period_seconds = QStringLiteral("trainprogram_period_seconds"); -const QString QZSettings:: trainprogram_speed_min = QStringLiteral("trainprogram_speed_min"); -const QString QZSettings:: trainprogram_speed_max = QStringLiteral("trainprogram_speed_max"); -const QString QZSettings:: trainprogram_incline_min = QStringLiteral("trainprogram_incline_min"); -const QString QZSettings:: trainprogram_incline_max = QStringLiteral("trainprogram_incline_max"); -const QString QZSettings:: trainprogram_resistance_min = QStringLiteral("trainprogram_resistance_min"); -const QString QZSettings:: trainprogram_resistance_max = QStringLiteral("trainprogram_resistance_max"); -const QString QZSettings:: watt_offset = QStringLiteral("watt_offset"); -const QString QZSettings:: watt_gain = QStringLiteral("watt_gain"); -const QString QZSettings:: power_avg_5s = QStringLiteral("power_avg_5s"); -const QString QZSettings:: instant_power_on_pause = QStringLiteral("instant_power_on_pause"); -const QString QZSettings:: speed_offset = QStringLiteral("speed_offset"); -const QString QZSettings:: speed_gain = QStringLiteral("speed_gain"); -const QString QZSettings:: filter_device = QStringLiteral("filter_device"); -const QString QZSettings:: default_filter_device = QStringLiteral("Disabled"); -const QString QZSettings:: strava_suffix = QStringLiteral("strava_suffix"); -const QString QZSettings:: default_strava_suffix = QStringLiteral("#QZ"); -const QString QZSettings:: cadence_sensor_name = QStringLiteral("cadence_sensor_name"); -const QString QZSettings:: default_cadence_sensor_name = QStringLiteral("Disabled"); -const QString QZSettings:: cadence_sensor_as_bike = QStringLiteral("cadence_sensor_as_bike"); -const QString QZSettings:: cadence_sensor_speed_ratio = QStringLiteral("cadence_sensor_speed_ratio"); -const QString QZSettings:: power_hr_pwr1 = QStringLiteral("power_hr_pwr1"); -const QString QZSettings:: power_hr_hr1 = QStringLiteral("power_hr_hr1"); -const QString QZSettings:: power_hr_pwr2 = QStringLiteral("power_hr_pwr2"); -const QString QZSettings:: power_hr_hr2 = QStringLiteral("power_hr_hr2"); -const QString QZSettings:: power_sensor_name = QStringLiteral("power_sensor_name"); -const QString QZSettings:: default_power_sensor_name = QStringLiteral("Disabled"); -const QString QZSettings:: power_sensor_as_bike = QStringLiteral("power_sensor_as_bike"); -const QString QZSettings:: power_sensor_as_treadmill = QStringLiteral("power_sensor_as_treadmill"); -const QString QZSettings:: powr_sensor_running_cadence_double = QStringLiteral("powr_sensor_running_cadence_double"); -const QString QZSettings:: elite_rizer_name = QStringLiteral("elite_rizer_name"); -const QString QZSettings:: default_elite_rizer_name = QStringLiteral("Disabled"); -const QString QZSettings:: elite_sterzo_smart_name = QStringLiteral("elite_sterzo_smart_name"); -const QString QZSettings:: default_elite_sterzo_smart_name = QStringLiteral("Disabled"); -const QString QZSettings:: ftms_accessory_name = QStringLiteral("ftms_accessory_name"); -const QString QZSettings:: default_ftms_accessory_name = QStringLiteral("Disabled"); -const QString QZSettings:: ss2k_shift_step = QStringLiteral("ss2k_shift_step"); -const QString QZSettings:: fitmetria_fanfit_enable = QStringLiteral("fitmetria_fanfit_enable"); -const QString QZSettings:: fitmetria_fanfit_mode = QStringLiteral("fitmetria_fanfit_mode"); -const QString QZSettings:: default_fitmetria_fanfit_mode = QStringLiteral("Heart"); -const QString QZSettings:: fitmetria_fanfit_min = QStringLiteral("fitmetria_fanfit_min"); -const QString QZSettings:: fitmetria_fanfit_max = QStringLiteral("fitmetria_fanfit_max"); -const QString QZSettings:: virtualbike_forceresistance = QStringLiteral("virtualbike_forceresistance"); -const QString QZSettings:: bluetooth_relaxed = QStringLiteral("bluetooth_relaxed"); -const QString QZSettings:: bluetooth_30m_hangs = QStringLiteral("bluetooth_30m_hangs"); -const QString QZSettings:: battery_service = QStringLiteral("battery_service"); -const QString QZSettings:: service_changed = QStringLiteral("service_changed"); -const QString QZSettings:: virtual_device_enabled = QStringLiteral("virtual_device_enabled"); -const QString QZSettings:: virtual_device_bluetooth = QStringLiteral("virtual_device_bluetooth"); -const QString QZSettings:: ios_peloton_workaround = QStringLiteral("ios_peloton_workaround"); -const QString QZSettings:: android_wakelock = QStringLiteral("android_wakelock"); -const QString QZSettings:: log_debug = QStringLiteral("log_debug"); -const QString QZSettings:: virtual_device_onlyheart = QStringLiteral("virtual_device_onlyheart"); -const QString QZSettings:: virtual_device_echelon = QStringLiteral("virtual_device_echelon"); -const QString QZSettings:: virtual_device_ifit = QStringLiteral("virtual_device_ifit"); -const QString QZSettings:: virtual_device_rower = QStringLiteral("virtual_device_rower"); -const QString QZSettings:: virtual_device_force_bike = QStringLiteral("virtual_device_force_bike"); -const QString QZSettings:: volume_change_gears = QStringLiteral("volume_change_gears"); -const QString QZSettings:: applewatch_fakedevice = QStringLiteral("applewatch_fakedevice"); -const QString QZSettings:: zwift_erg_resistance_down = QStringLiteral("zwift_erg_resistance_down"); -const QString QZSettings:: zwift_erg_resistance_up = QStringLiteral("zwift_erg_resistance_up"); -const QString QZSettings:: horizon_paragon_x = QStringLiteral("horizon_paragon_x"); -const QString QZSettings:: treadmill_step_speed = QStringLiteral("treadmill_step_speed"); -const QString QZSettings:: treadmill_step_incline = QStringLiteral("treadmill_step_incline"); -const QString QZSettings:: fitshow_anyrun = QStringLiteral("fitshow_anyrun"); -const QString QZSettings:: nordictrack_s30_treadmill = QStringLiteral("nordictrack_s30_treadmill"); +const QString QZSettings::toorx_3_0 = QStringLiteral("toorx_3_0"); +const QString QZSettings::toorx_65s_evo = QStringLiteral("toorx_65s_evo"); +const QString QZSettings::jtx_fitness_sprint_treadmill = QStringLiteral("jtx_fitness_sprint_treadmill"); +const QString QZSettings::dkn_endurun_treadmill = QStringLiteral("dkn_endurun_treadmill"); +const QString QZSettings::trx_route_key = QStringLiteral("trx_route_key"); +const QString QZSettings::bh_spada_2 = QStringLiteral("bh_spada_2"); +const QString QZSettings::toorx_bike = QStringLiteral("toorx_bike"); +const QString QZSettings::toorx_ftms = QStringLiteral("toorx_ftms"); +const QString QZSettings::jll_IC400_bike = QStringLiteral("jll_IC400_bike"); +const QString QZSettings::fytter_ri08_bike = QStringLiteral("fytter_ri08_bike"); +const QString QZSettings::asviva_bike = QStringLiteral("asviva_bike"); +const QString QZSettings::hertz_xr_770 = QStringLiteral("hertz_xr_770"); +const QString QZSettings::m3i_bike_id = QStringLiteral("m3i_bike_id"); +const QString QZSettings::m3i_bike_speed_buffsize = QStringLiteral("m3i_bike_speed_buffsize"); +const QString QZSettings::m3i_bike_qt_search = QStringLiteral("m3i_bike_qt_search"); +const QString QZSettings::m3i_bike_kcal = QStringLiteral("m3i_bike_kcal"); +const QString QZSettings::snode_bike = QStringLiteral("snode_bike"); +const QString QZSettings::fitplus_bike = QStringLiteral("fitplus_bike"); +const QString QZSettings::virtufit_etappe = QStringLiteral("virtufit_etappe"); +const QString QZSettings::flywheel_filter = QStringLiteral("flywheel_filter"); +const QString QZSettings::flywheel_life_fitness_ic8 = QStringLiteral("flywheel_life_fitness_ic8"); +const QString QZSettings::sole_treadmill_inclination = QStringLiteral("sole_treadmill_inclination"); +const QString QZSettings::sole_treadmill_miles = QStringLiteral("sole_treadmill_miles"); +const QString QZSettings::sole_treadmill_f65 = QStringLiteral("sole_treadmill_f65"); +const QString QZSettings::sole_treadmill_f63 = QStringLiteral("sole_treadmill_f63"); +const QString QZSettings::sole_treadmill_tt8 = QStringLiteral("sole_treadmill_tt8"); +const QString QZSettings::schwinn_bike_resistance = QStringLiteral("schwinn_bike_resistance"); +const QString QZSettings::schwinn_bike_resistance_v2 = QStringLiteral("schwinn_bike_resistance_v2"); +const QString QZSettings::technogym_myrun_treadmill_experimental = + QStringLiteral("technogym_myrun_treadmill_experimental"); +const QString QZSettings::trainprogram_random = QStringLiteral("trainprogram_random"); +const QString QZSettings::trainprogram_total = QStringLiteral("trainprogram_total"); +const QString QZSettings::trainprogram_period_seconds = QStringLiteral("trainprogram_period_seconds"); +const QString QZSettings::trainprogram_speed_min = QStringLiteral("trainprogram_speed_min"); +const QString QZSettings::trainprogram_speed_max = QStringLiteral("trainprogram_speed_max"); +const QString QZSettings::trainprogram_incline_min = QStringLiteral("trainprogram_incline_min"); +const QString QZSettings::trainprogram_incline_max = QStringLiteral("trainprogram_incline_max"); +const QString QZSettings::trainprogram_resistance_min = QStringLiteral("trainprogram_resistance_min"); +const QString QZSettings::trainprogram_resistance_max = QStringLiteral("trainprogram_resistance_max"); +const QString QZSettings::watt_offset = QStringLiteral("watt_offset"); +const QString QZSettings::watt_gain = QStringLiteral("watt_gain"); +const QString QZSettings::power_avg_5s = QStringLiteral("power_avg_5s"); +const QString QZSettings::instant_power_on_pause = QStringLiteral("instant_power_on_pause"); +const QString QZSettings::speed_offset = QStringLiteral("speed_offset"); +const QString QZSettings::speed_gain = QStringLiteral("speed_gain"); +const QString QZSettings::filter_device = QStringLiteral("filter_device"); +const QString QZSettings::default_filter_device = QStringLiteral("Disabled"); +const QString QZSettings::strava_suffix = QStringLiteral("strava_suffix"); +const QString QZSettings::default_strava_suffix = QStringLiteral("#QZ"); +const QString QZSettings::cadence_sensor_name = QStringLiteral("cadence_sensor_name"); +const QString QZSettings::default_cadence_sensor_name = QStringLiteral("Disabled"); +const QString QZSettings::cadence_sensor_as_bike = QStringLiteral("cadence_sensor_as_bike"); +const QString QZSettings::cadence_sensor_speed_ratio = QStringLiteral("cadence_sensor_speed_ratio"); +const QString QZSettings::power_hr_pwr1 = QStringLiteral("power_hr_pwr1"); +const QString QZSettings::power_hr_hr1 = QStringLiteral("power_hr_hr1"); +const QString QZSettings::power_hr_pwr2 = QStringLiteral("power_hr_pwr2"); +const QString QZSettings::power_hr_hr2 = QStringLiteral("power_hr_hr2"); +const QString QZSettings::power_sensor_name = QStringLiteral("power_sensor_name"); +const QString QZSettings::default_power_sensor_name = QStringLiteral("Disabled"); +const QString QZSettings::power_sensor_as_bike = QStringLiteral("power_sensor_as_bike"); +const QString QZSettings::power_sensor_as_treadmill = QStringLiteral("power_sensor_as_treadmill"); +const QString QZSettings::powr_sensor_running_cadence_double = QStringLiteral("powr_sensor_running_cadence_double"); +const QString QZSettings::elite_rizer_name = QStringLiteral("elite_rizer_name"); +const QString QZSettings::default_elite_rizer_name = QStringLiteral("Disabled"); +const QString QZSettings::elite_sterzo_smart_name = QStringLiteral("elite_sterzo_smart_name"); +const QString QZSettings::default_elite_sterzo_smart_name = QStringLiteral("Disabled"); +const QString QZSettings::ftms_accessory_name = QStringLiteral("ftms_accessory_name"); +const QString QZSettings::default_ftms_accessory_name = QStringLiteral("Disabled"); +const QString QZSettings::ss2k_shift_step = QStringLiteral("ss2k_shift_step"); +const QString QZSettings::fitmetria_fanfit_enable = QStringLiteral("fitmetria_fanfit_enable"); +const QString QZSettings::fitmetria_fanfit_mode = QStringLiteral("fitmetria_fanfit_mode"); +const QString QZSettings::default_fitmetria_fanfit_mode = QStringLiteral("Heart"); +const QString QZSettings::fitmetria_fanfit_min = QStringLiteral("fitmetria_fanfit_min"); +const QString QZSettings::fitmetria_fanfit_max = QStringLiteral("fitmetria_fanfit_max"); +const QString QZSettings::virtualbike_forceresistance = QStringLiteral("virtualbike_forceresistance"); +const QString QZSettings::bluetooth_relaxed = QStringLiteral("bluetooth_relaxed"); +const QString QZSettings::bluetooth_30m_hangs = QStringLiteral("bluetooth_30m_hangs"); +const QString QZSettings::battery_service = QStringLiteral("battery_service"); +const QString QZSettings::service_changed = QStringLiteral("service_changed"); +const QString QZSettings::virtual_device_enabled = QStringLiteral("virtual_device_enabled"); +const QString QZSettings::virtual_device_bluetooth = QStringLiteral("virtual_device_bluetooth"); +const QString QZSettings::ios_peloton_workaround = QStringLiteral("ios_peloton_workaround"); +const QString QZSettings::android_wakelock = QStringLiteral("android_wakelock"); +const QString QZSettings::log_debug = QStringLiteral("log_debug"); +const QString QZSettings::virtual_device_onlyheart = QStringLiteral("virtual_device_onlyheart"); +const QString QZSettings::virtual_device_echelon = QStringLiteral("virtual_device_echelon"); +const QString QZSettings::virtual_device_ifit = QStringLiteral("virtual_device_ifit"); +const QString QZSettings::virtual_device_rower = QStringLiteral("virtual_device_rower"); +const QString QZSettings::virtual_device_force_bike = QStringLiteral("virtual_device_force_bike"); +const QString QZSettings::volume_change_gears = QStringLiteral("volume_change_gears"); +const QString QZSettings::applewatch_fakedevice = QStringLiteral("applewatch_fakedevice"); +const QString QZSettings::zwift_erg_resistance_down = QStringLiteral("zwift_erg_resistance_down"); +const QString QZSettings::zwift_erg_resistance_up = QStringLiteral("zwift_erg_resistance_up"); +const QString QZSettings::horizon_paragon_x = QStringLiteral("horizon_paragon_x"); +const QString QZSettings::treadmill_step_speed = QStringLiteral("treadmill_step_speed"); +const QString QZSettings::treadmill_step_incline = QStringLiteral("treadmill_step_incline"); +const QString QZSettings::fitshow_anyrun = QStringLiteral("fitshow_anyrun"); +const QString QZSettings::nordictrack_s30_treadmill = QStringLiteral("nordictrack_s30_treadmill"); // from version 2.10.23 // not used anymore because it's an elliptical not a treadmill. Don't remove this // it will cause corruption in the settings -//const QString QZSettings:: nordictrack_fs5i_treadmill = QStringLiteral("nordictrack_fs5i_treadmill"); +// const QString QZSettings:: nordictrack_fs5i_treadmill = QStringLiteral("nordictrack_fs5i_treadmill"); // -const QString QZSettings:: renpho_peloton_conversion_v2 = QStringLiteral("renpho_peloton_conversion_v2"); -const QString QZSettings:: ss2k_resistance_sample_1 = QStringLiteral("ss2k_resistance_sample_1"); -const QString QZSettings:: ss2k_shift_step_sample_1 = QStringLiteral("ss2k_shift_step_sample_1"); -const QString QZSettings:: ss2k_resistance_sample_2 = QStringLiteral("ss2k_resistance_sample_2"); -const QString QZSettings:: ss2k_shift_step_sample_2 = QStringLiteral("ss2k_shift_step_sample_2"); -const QString QZSettings:: ss2k_resistance_sample_3 = QStringLiteral("ss2k_resistance_sample_3"); -const QString QZSettings:: ss2k_shift_step_sample_3 = QStringLiteral("ss2k_shift_step_sample_3"); -const QString QZSettings:: ss2k_resistance_sample_4 = QStringLiteral("ss2k_resistance_sample_4"); -const QString QZSettings:: ss2k_shift_step_sample_4 = QStringLiteral("ss2k_shift_step_sample_4"); -const QString QZSettings:: fitshow_truetimer = QStringLiteral("fitshow_truetimer"); -const QString QZSettings:: elite_rizer_gain = QStringLiteral("elite_rizer_gain"); -const QString QZSettings:: tile_ext_incline_enabled = QStringLiteral("tile_ext_incline_enabled"); -const QString QZSettings:: tile_ext_incline_order = QStringLiteral("tile_ext_incline_order"); -const QString QZSettings:: reebok_fr30_treadmill = QStringLiteral("reebok_fr30_treadmill"); -const QString QZSettings:: horizon_treadmill_7_8 = QStringLiteral("horizon_treadmill_7_8"); -const QString QZSettings:: profile_name = QStringLiteral("profile_name"); -const QString QZSettings:: default_profile_name = QStringLiteral("default"); -const QString QZSettings:: tile_cadence_color_enabled = QStringLiteral("tile_cadence_color_enabled"); -const QString QZSettings:: tile_peloton_remaining_enabled = QStringLiteral("tile_peloton_remaining_enabled"); -const QString QZSettings:: tile_peloton_remaining_order = QStringLiteral("tile_peloton_remaining_order"); -const QString QZSettings:: tile_peloton_resistance_color_enabled = QStringLiteral("tile_peloton_resistance_color_enabled"); -const QString QZSettings:: dircon_yes = QStringLiteral("dircon_yes"); -const QString QZSettings:: dircon_server_base_port = QStringLiteral("dircon_server_base_port"); -const QString QZSettings:: ios_cache_heart_device = QStringLiteral("ios_cache_heart_device"); -const QString QZSettings:: app_opening = QStringLiteral("app_opening"); -const QString QZSettings:: proformtdf4ip = QStringLiteral("proformtdf4ip"); -const QString QZSettings:: default_proformtdf4ip = QStringLiteral(""); -const QString QZSettings:: fitfiu_mc_v460 = QStringLiteral("fitfiu_mc_v460"); -const QString QZSettings:: bike_weight = QStringLiteral("bike_weight"); -const QString QZSettings:: kingsmith_encrypt_v2 = QStringLiteral("kingsmith_encrypt_v2"); -const QString QZSettings:: proform_treadmill_9_0 = QStringLiteral("proform_treadmill_9_0"); -const QString QZSettings:: proform_treadmill_1800i = QStringLiteral("proform_treadmill_1800i"); -const QString QZSettings:: cadence_offset = QStringLiteral("cadence_offset"); -const QString QZSettings:: cadence_gain = QStringLiteral("cadence_gain"); -const QString QZSettings:: sp_ht_9600ie = QStringLiteral("sp_ht_9600ie"); -const QString QZSettings:: tts_enabled = QStringLiteral("tts_enabled"); -const QString QZSettings:: tts_summary_sec = QStringLiteral("tts_summary_sec"); -const QString QZSettings:: tts_act_speed = QStringLiteral("tts_act_speed"); -const QString QZSettings:: tts_avg_speed = QStringLiteral("tts_avg_speed"); -const QString QZSettings:: tts_max_speed = QStringLiteral("tts_max_speed"); -const QString QZSettings:: tts_act_inclination = QStringLiteral("tts_act_inclination"); -const QString QZSettings:: tts_act_cadence = QStringLiteral("tts_act_cadence"); -const QString QZSettings:: tts_avg_cadence = QStringLiteral("tts_avg_cadence"); -const QString QZSettings:: tts_max_cadence = QStringLiteral("tts_max_cadence"); -const QString QZSettings:: tts_act_elevation = QStringLiteral("tts_act_elevation"); -const QString QZSettings:: tts_act_calories = QStringLiteral("tts_act_calories"); -const QString QZSettings:: tts_act_odometer = QStringLiteral("tts_act_odometer"); -const QString QZSettings:: tts_act_pace = QStringLiteral("tts_act_pace"); -const QString QZSettings:: tts_avg_pace = QStringLiteral("tts_avg_pace"); -const QString QZSettings:: tts_max_pace = QStringLiteral("tts_max_pace"); -const QString QZSettings:: tts_act_resistance = QStringLiteral("tts_act_resistance"); -const QString QZSettings:: tts_avg_resistance = QStringLiteral("tts_avg_resistance"); -const QString QZSettings:: tts_max_resistance = QStringLiteral("tts_max_resistance"); -const QString QZSettings:: tts_act_watt = QStringLiteral("tts_act_watt"); -const QString QZSettings:: tts_avg_watt = QStringLiteral("tts_avg_watt"); -const QString QZSettings:: tts_max_watt = QStringLiteral("tts_max_watt"); -const QString QZSettings:: tts_act_ftp = QStringLiteral("tts_act_ftp"); -const QString QZSettings:: tts_avg_ftp = QStringLiteral("tts_avg_ftp"); -const QString QZSettings:: tts_max_ftp = QStringLiteral("tts_max_ftp"); -const QString QZSettings:: tts_act_heart = QStringLiteral("tts_act_heart"); -const QString QZSettings:: tts_avg_heart = QStringLiteral("tts_avg_heart"); -const QString QZSettings:: tts_max_heart = QStringLiteral("tts_max_heart"); -const QString QZSettings:: tts_act_jouls = QStringLiteral("tts_act_jouls"); -const QString QZSettings:: tts_act_elapsed = QStringLiteral("tts_act_elapsed"); -const QString QZSettings:: tts_act_peloton_resistance = QStringLiteral("tts_act_peloton_resistance"); -const QString QZSettings:: tts_avg_peloton_resistance = QStringLiteral("tts_avg_peloton_resistance"); -const QString QZSettings:: tts_max_peloton_resistance = QStringLiteral("tts_max_peloton_resistance"); -const QString QZSettings:: tts_act_target_peloton_resistance = QStringLiteral("tts_act_target_peloton_resistance"); -const QString QZSettings:: tts_act_target_cadence = QStringLiteral("tts_act_target_cadence"); -const QString QZSettings:: tts_act_target_power = QStringLiteral("tts_act_target_power"); -const QString QZSettings:: tts_act_target_zone = QStringLiteral("tts_act_target_zone"); -const QString QZSettings:: tts_act_target_speed = QStringLiteral("tts_act_target_speed"); -const QString QZSettings:: tts_act_target_incline = QStringLiteral("tts_act_target_incline"); -const QString QZSettings:: tts_act_watt_kg = QStringLiteral("tts_act_watt_kg"); -const QString QZSettings:: tts_avg_watt_kg = QStringLiteral("tts_avg_watt_kg"); -const QString QZSettings:: tts_max_watt_kg = QStringLiteral("tts_max_watt_kg"); -const QString QZSettings:: fakedevice_elliptical = QStringLiteral("fakedevice_elliptical"); -const QString QZSettings:: nordictrack_2950_ip = QStringLiteral("nordictrack_2950_ip"); -const QString QZSettings:: default_nordictrack_2950_ip = QStringLiteral(""); -const QString QZSettings:: tile_instantaneous_stride_length_enabled = QStringLiteral("tile_instantaneous_stride_length_enabled"); -const QString QZSettings:: tile_instantaneous_stride_length_order = QStringLiteral("tile_instantaneous_stride_length_order"); -const QString QZSettings:: tile_ground_contact_enabled = QStringLiteral("tile_ground_contact_enabled"); -const QString QZSettings:: tile_ground_contact_order = QStringLiteral("tile_ground_contact_order"); -const QString QZSettings:: tile_vertical_oscillation_enabled = QStringLiteral("tile_vertical_oscillation_enabled"); -const QString QZSettings:: tile_vertical_oscillation_order = QStringLiteral("tile_vertical_oscillation_order"); -const QString QZSettings:: sex = QStringLiteral("sex"); -const QString QZSettings:: default_sex = QStringLiteral("Male"); -const QString QZSettings:: maps_type = QStringLiteral("maps_type"); -const QString QZSettings:: default_maps_type = QStringLiteral("3D"); -const QString QZSettings:: ss2k_max_resistance = QStringLiteral("ss2k_max_resistance"); -const QString QZSettings:: ss2k_min_resistance = QStringLiteral("ss2k_min_resistance"); -const QString QZSettings:: proform_treadmill_se = QStringLiteral("proform_treadmill_se"); -const QString QZSettings:: proformtreadmillip = QStringLiteral("proformtreadmillip"); -const QString QZSettings:: default_proformtreadmillip = QStringLiteral(""); +const QString QZSettings::renpho_peloton_conversion_v2 = QStringLiteral("renpho_peloton_conversion_v2"); +const QString QZSettings::ss2k_resistance_sample_1 = QStringLiteral("ss2k_resistance_sample_1"); +const QString QZSettings::ss2k_shift_step_sample_1 = QStringLiteral("ss2k_shift_step_sample_1"); +const QString QZSettings::ss2k_resistance_sample_2 = QStringLiteral("ss2k_resistance_sample_2"); +const QString QZSettings::ss2k_shift_step_sample_2 = QStringLiteral("ss2k_shift_step_sample_2"); +const QString QZSettings::ss2k_resistance_sample_3 = QStringLiteral("ss2k_resistance_sample_3"); +const QString QZSettings::ss2k_shift_step_sample_3 = QStringLiteral("ss2k_shift_step_sample_3"); +const QString QZSettings::ss2k_resistance_sample_4 = QStringLiteral("ss2k_resistance_sample_4"); +const QString QZSettings::ss2k_shift_step_sample_4 = QStringLiteral("ss2k_shift_step_sample_4"); +const QString QZSettings::fitshow_truetimer = QStringLiteral("fitshow_truetimer"); +const QString QZSettings::elite_rizer_gain = QStringLiteral("elite_rizer_gain"); +const QString QZSettings::tile_ext_incline_enabled = QStringLiteral("tile_ext_incline_enabled"); +const QString QZSettings::tile_ext_incline_order = QStringLiteral("tile_ext_incline_order"); +const QString QZSettings::reebok_fr30_treadmill = QStringLiteral("reebok_fr30_treadmill"); +const QString QZSettings::horizon_treadmill_7_8 = QStringLiteral("horizon_treadmill_7_8"); +const QString QZSettings::profile_name = QStringLiteral("profile_name"); +const QString QZSettings::default_profile_name = QStringLiteral("default"); +const QString QZSettings::tile_cadence_color_enabled = QStringLiteral("tile_cadence_color_enabled"); +const QString QZSettings::tile_peloton_remaining_enabled = QStringLiteral("tile_peloton_remaining_enabled"); +const QString QZSettings::tile_peloton_remaining_order = QStringLiteral("tile_peloton_remaining_order"); +const QString QZSettings::tile_peloton_resistance_color_enabled = + QStringLiteral("tile_peloton_resistance_color_enabled"); +const QString QZSettings::dircon_yes = QStringLiteral("dircon_yes"); +const QString QZSettings::dircon_server_base_port = QStringLiteral("dircon_server_base_port"); +const QString QZSettings::ios_cache_heart_device = QStringLiteral("ios_cache_heart_device"); +const QString QZSettings::app_opening = QStringLiteral("app_opening"); +const QString QZSettings::proformtdf4ip = QStringLiteral("proformtdf4ip"); +const QString QZSettings::default_proformtdf4ip = QStringLiteral(""); +const QString QZSettings::fitfiu_mc_v460 = QStringLiteral("fitfiu_mc_v460"); +const QString QZSettings::bike_weight = QStringLiteral("bike_weight"); +const QString QZSettings::kingsmith_encrypt_v2 = QStringLiteral("kingsmith_encrypt_v2"); +const QString QZSettings::proform_treadmill_9_0 = QStringLiteral("proform_treadmill_9_0"); +const QString QZSettings::proform_treadmill_1800i = QStringLiteral("proform_treadmill_1800i"); +const QString QZSettings::cadence_offset = QStringLiteral("cadence_offset"); +const QString QZSettings::cadence_gain = QStringLiteral("cadence_gain"); +const QString QZSettings::sp_ht_9600ie = QStringLiteral("sp_ht_9600ie"); +const QString QZSettings::tts_enabled = QStringLiteral("tts_enabled"); +const QString QZSettings::tts_summary_sec = QStringLiteral("tts_summary_sec"); +const QString QZSettings::tts_act_speed = QStringLiteral("tts_act_speed"); +const QString QZSettings::tts_avg_speed = QStringLiteral("tts_avg_speed"); +const QString QZSettings::tts_max_speed = QStringLiteral("tts_max_speed"); +const QString QZSettings::tts_act_inclination = QStringLiteral("tts_act_inclination"); +const QString QZSettings::tts_act_cadence = QStringLiteral("tts_act_cadence"); +const QString QZSettings::tts_avg_cadence = QStringLiteral("tts_avg_cadence"); +const QString QZSettings::tts_max_cadence = QStringLiteral("tts_max_cadence"); +const QString QZSettings::tts_act_elevation = QStringLiteral("tts_act_elevation"); +const QString QZSettings::tts_act_calories = QStringLiteral("tts_act_calories"); +const QString QZSettings::tts_act_odometer = QStringLiteral("tts_act_odometer"); +const QString QZSettings::tts_act_pace = QStringLiteral("tts_act_pace"); +const QString QZSettings::tts_avg_pace = QStringLiteral("tts_avg_pace"); +const QString QZSettings::tts_max_pace = QStringLiteral("tts_max_pace"); +const QString QZSettings::tts_act_resistance = QStringLiteral("tts_act_resistance"); +const QString QZSettings::tts_avg_resistance = QStringLiteral("tts_avg_resistance"); +const QString QZSettings::tts_max_resistance = QStringLiteral("tts_max_resistance"); +const QString QZSettings::tts_act_watt = QStringLiteral("tts_act_watt"); +const QString QZSettings::tts_avg_watt = QStringLiteral("tts_avg_watt"); +const QString QZSettings::tts_max_watt = QStringLiteral("tts_max_watt"); +const QString QZSettings::tts_act_ftp = QStringLiteral("tts_act_ftp"); +const QString QZSettings::tts_avg_ftp = QStringLiteral("tts_avg_ftp"); +const QString QZSettings::tts_max_ftp = QStringLiteral("tts_max_ftp"); +const QString QZSettings::tts_act_heart = QStringLiteral("tts_act_heart"); +const QString QZSettings::tts_avg_heart = QStringLiteral("tts_avg_heart"); +const QString QZSettings::tts_max_heart = QStringLiteral("tts_max_heart"); +const QString QZSettings::tts_act_jouls = QStringLiteral("tts_act_jouls"); +const QString QZSettings::tts_act_elapsed = QStringLiteral("tts_act_elapsed"); +const QString QZSettings::tts_act_peloton_resistance = QStringLiteral("tts_act_peloton_resistance"); +const QString QZSettings::tts_avg_peloton_resistance = QStringLiteral("tts_avg_peloton_resistance"); +const QString QZSettings::tts_max_peloton_resistance = QStringLiteral("tts_max_peloton_resistance"); +const QString QZSettings::tts_act_target_peloton_resistance = QStringLiteral("tts_act_target_peloton_resistance"); +const QString QZSettings::tts_act_target_cadence = QStringLiteral("tts_act_target_cadence"); +const QString QZSettings::tts_act_target_power = QStringLiteral("tts_act_target_power"); +const QString QZSettings::tts_act_target_zone = QStringLiteral("tts_act_target_zone"); +const QString QZSettings::tts_act_target_speed = QStringLiteral("tts_act_target_speed"); +const QString QZSettings::tts_act_target_incline = QStringLiteral("tts_act_target_incline"); +const QString QZSettings::tts_act_watt_kg = QStringLiteral("tts_act_watt_kg"); +const QString QZSettings::tts_avg_watt_kg = QStringLiteral("tts_avg_watt_kg"); +const QString QZSettings::tts_max_watt_kg = QStringLiteral("tts_max_watt_kg"); +const QString QZSettings::fakedevice_elliptical = QStringLiteral("fakedevice_elliptical"); +const QString QZSettings::nordictrack_2950_ip = QStringLiteral("nordictrack_2950_ip"); +const QString QZSettings::default_nordictrack_2950_ip = QStringLiteral(""); +const QString QZSettings::tile_instantaneous_stride_length_enabled = + QStringLiteral("tile_instantaneous_stride_length_enabled"); +const QString QZSettings::tile_instantaneous_stride_length_order = + QStringLiteral("tile_instantaneous_stride_length_order"); +const QString QZSettings::tile_ground_contact_enabled = QStringLiteral("tile_ground_contact_enabled"); +const QString QZSettings::tile_ground_contact_order = QStringLiteral("tile_ground_contact_order"); +const QString QZSettings::tile_vertical_oscillation_enabled = QStringLiteral("tile_vertical_oscillation_enabled"); +const QString QZSettings::tile_vertical_oscillation_order = QStringLiteral("tile_vertical_oscillation_order"); +const QString QZSettings::sex = QStringLiteral("sex"); +const QString QZSettings::default_sex = QStringLiteral("Male"); +const QString QZSettings::maps_type = QStringLiteral("maps_type"); +const QString QZSettings::default_maps_type = QStringLiteral("3D"); +const QString QZSettings::ss2k_max_resistance = QStringLiteral("ss2k_max_resistance"); +const QString QZSettings::ss2k_min_resistance = QStringLiteral("ss2k_min_resistance"); +const QString QZSettings::proform_treadmill_se = QStringLiteral("proform_treadmill_se"); +const QString QZSettings::proformtreadmillip = QStringLiteral("proformtreadmillip"); +const QString QZSettings::default_proformtreadmillip = QStringLiteral(""); // from version 2.11.22 -const QString QZSettings:: kingsmith_encrypt_v3 = QStringLiteral("kingsmith_encrypt_v3"); -const QString QZSettings:: tdf_10_ip = QStringLiteral("tdf_10_ip"); -const QString QZSettings:: default_tdf_10_ip = QStringLiteral(""); -const QString QZSettings:: fakedevice_treadmill = QStringLiteral("fakedevice_treadmill"); -const QString QZSettings:: video_playback_window_s = QStringLiteral("video_playback_window_s"); -const QString QZSettings:: horizon_treadmill_profile_user1 = QStringLiteral("horizon_treadmill_profile_user1"); -const QString QZSettings:: default_horizon_treadmill_profile_user1 = QStringLiteral("user1"); -const QString QZSettings:: horizon_treadmill_profile_user2 = QStringLiteral("horizon_treadmill_profile_user2"); -const QString QZSettings:: default_horizon_treadmill_profile_user2 = QStringLiteral("user2"); -const QString QZSettings:: horizon_treadmill_profile_user3 = QStringLiteral("horizon_treadmill_profile_user3"); -const QString QZSettings:: default_horizon_treadmill_profile_user3 = QStringLiteral("user3"); -const QString QZSettings:: horizon_treadmill_profile_user4 = QStringLiteral("horizon_treadmill_profile_user4"); -const QString QZSettings:: default_horizon_treadmill_profile_user4 = QStringLiteral("user4"); -const QString QZSettings:: horizon_treadmill_profile_user5 = QStringLiteral("horizon_treadmill_profile_user5"); -const QString QZSettings:: default_horizon_treadmill_profile_user5 = QStringLiteral("user5"); -const QString QZSettings:: nordictrack_gx_2_7 = QStringLiteral("nordictrack_gx_2_7"); -const QString QZSettings:: rolling_resistance = QStringLiteral("rolling_resistance"); -const QString QZSettings:: wahoo_rgt_dircon = QStringLiteral("wahoo_rgt_dircon"); +const QString QZSettings::kingsmith_encrypt_v3 = QStringLiteral("kingsmith_encrypt_v3"); +const QString QZSettings::tdf_10_ip = QStringLiteral("tdf_10_ip"); +const QString QZSettings::default_tdf_10_ip = QStringLiteral(""); +const QString QZSettings::fakedevice_treadmill = QStringLiteral("fakedevice_treadmill"); +const QString QZSettings::video_playback_window_s = QStringLiteral("video_playback_window_s"); +const QString QZSettings::horizon_treadmill_profile_user1 = QStringLiteral("horizon_treadmill_profile_user1"); +const QString QZSettings::default_horizon_treadmill_profile_user1 = QStringLiteral("user1"); +const QString QZSettings::horizon_treadmill_profile_user2 = QStringLiteral("horizon_treadmill_profile_user2"); +const QString QZSettings::default_horizon_treadmill_profile_user2 = QStringLiteral("user2"); +const QString QZSettings::horizon_treadmill_profile_user3 = QStringLiteral("horizon_treadmill_profile_user3"); +const QString QZSettings::default_horizon_treadmill_profile_user3 = QStringLiteral("user3"); +const QString QZSettings::horizon_treadmill_profile_user4 = QStringLiteral("horizon_treadmill_profile_user4"); +const QString QZSettings::default_horizon_treadmill_profile_user4 = QStringLiteral("user4"); +const QString QZSettings::horizon_treadmill_profile_user5 = QStringLiteral("horizon_treadmill_profile_user5"); +const QString QZSettings::default_horizon_treadmill_profile_user5 = QStringLiteral("user5"); +const QString QZSettings::nordictrack_gx_2_7 = QStringLiteral("nordictrack_gx_2_7"); +const QString QZSettings::rolling_resistance = QStringLiteral("rolling_resistance"); +const QString QZSettings::wahoo_rgt_dircon = QStringLiteral("wahoo_rgt_dircon"); +const QString QZSettings::tts_description_enabled = QStringLiteral("tts_description_enabled"); -const uint32_t allSettingsCount = 369; -QVariant allSettings[allSettingsCount][2] = { - { QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles }, - { QZSettings::bluetooth_no_reconnection, QZSettings::default_bluetooth_no_reconnection }, - { QZSettings::bike_wheel_revs, QZSettings::default_bike_wheel_revs }, - { QZSettings::bluetooth_lastdevice_name, QZSettings::default_bluetooth_lastdevice_name }, - { QZSettings::bluetooth_lastdevice_address, QZSettings::default_bluetooth_lastdevice_address }, - { QZSettings::hrm_lastdevice_name, QZSettings::default_hrm_lastdevice_name }, - { QZSettings::hrm_lastdevice_address, QZSettings::default_hrm_lastdevice_address }, - { QZSettings::ftms_accessory_address, QZSettings::default_ftms_accessory_address }, - { QZSettings::ftms_accessory_lastdevice_name, QZSettings::default_ftms_accessory_lastdevice_name }, - { QZSettings::csc_sensor_address, QZSettings::default_csc_sensor_address }, - { QZSettings::csc_sensor_lastdevice_name, QZSettings::default_csc_sensor_lastdevice_name }, - { QZSettings::power_sensor_lastdevice_name, QZSettings::default_power_sensor_lastdevice_name }, - { QZSettings::power_sensor_address, QZSettings::default_power_sensor_address }, - { QZSettings::elite_rizer_lastdevice_name, QZSettings::default_elite_rizer_lastdevice_name }, - { QZSettings::elite_rizer_address, QZSettings::default_elite_rizer_address }, - { QZSettings::elite_sterzo_smart_lastdevice_name, QZSettings::default_elite_sterzo_smart_lastdevice_name }, - { QZSettings::elite_sterzo_smart_address, QZSettings::default_elite_sterzo_smart_address }, - { QZSettings::strava_accesstoken, QZSettings::default_strava_accesstoken }, - { QZSettings::strava_refreshtoken, QZSettings::default_strava_refreshtoken }, - { QZSettings::strava_lastrefresh, QZSettings::default_strava_lastrefresh }, - { QZSettings::strava_expires, QZSettings::default_strava_expires }, - { QZSettings::ui_zoom, QZSettings::default_ui_zoom }, - { QZSettings::bike_heartrate_service, QZSettings::default_bike_heartrate_service }, - { QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset }, - { QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f }, - { QZSettings::zwift_erg, QZSettings::default_zwift_erg }, - { QZSettings::zwift_erg_filter, QZSettings::default_zwift_erg_filter }, - { QZSettings::zwift_erg_filter_down, QZSettings::default_zwift_erg_filter_down }, - { QZSettings::zwift_negative_inclination_x2, QZSettings::default_zwift_negative_inclination_x2 }, - { QZSettings::zwift_inclination_offset, QZSettings::default_zwift_inclination_offset }, - { QZSettings::zwift_inclination_gain, QZSettings::default_zwift_inclination_gain }, - { QZSettings::echelon_resistance_offset, QZSettings::default_echelon_resistance_offset }, - { QZSettings::echelon_resistance_gain, QZSettings::default_echelon_resistance_gain }, - { QZSettings::speed_power_based, QZSettings::default_speed_power_based }, - { QZSettings::bike_resistance_start, QZSettings::default_bike_resistance_start }, - { QZSettings::age, QZSettings::default_age }, - { QZSettings::weight, QZSettings::default_weight }, - { QZSettings::ftp, QZSettings::default_ftp }, - { QZSettings::user_email, QZSettings::default_user_email }, - { QZSettings::user_nickname, QZSettings::default_user_nickname }, - { QZSettings::miles_unit, QZSettings::default_miles_unit }, - { QZSettings::pause_on_start, QZSettings::default_pause_on_start }, - { QZSettings::treadmill_force_speed, QZSettings::default_treadmill_force_speed }, - { QZSettings::pause_on_start_treadmill, QZSettings::default_pause_on_start_treadmill }, - { QZSettings::continuous_moving, QZSettings::default_continuous_moving }, - { QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor }, - { QZSettings::run_cadence_sensor, QZSettings::default_run_cadence_sensor }, - { QZSettings::bike_power_sensor, QZSettings::default_bike_power_sensor }, - { QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name }, - { QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin }, - { QZSettings::kcal_ignore_builtin, QZSettings::default_kcal_ignore_builtin }, - { QZSettings::ant_cadence, QZSettings::default_ant_cadence }, - { QZSettings::ant_heart, QZSettings::default_ant_heart }, - { QZSettings::ant_garmin, QZSettings::default_ant_garmin }, - { QZSettings::top_bar_enabled, QZSettings::default_top_bar_enabled }, - { QZSettings::peloton_username, QZSettings::default_peloton_username }, - { QZSettings::peloton_password, QZSettings::default_peloton_password }, - { QZSettings::peloton_difficulty, QZSettings::default_peloton_difficulty }, - { QZSettings::peloton_cadence_metric, QZSettings::default_peloton_cadence_metric }, - { QZSettings::peloton_heartrate_metric, QZSettings::default_peloton_heartrate_metric }, - { QZSettings::peloton_date, QZSettings::default_peloton_date }, - { QZSettings::peloton_description_link, QZSettings::default_peloton_description_link }, - { QZSettings::pzp_username, QZSettings::default_pzp_username }, - { QZSettings::pzp_password, QZSettings::default_pzp_password }, - { QZSettings::tile_speed_enabled, QZSettings::default_tile_speed_enabled }, - { QZSettings::tile_speed_order, QZSettings::default_tile_speed_order }, - { QZSettings::tile_inclination_enabled, QZSettings::default_tile_inclination_enabled }, - { QZSettings::tile_inclination_order, QZSettings::default_tile_inclination_order }, - { QZSettings::tile_cadence_enabled, QZSettings::default_tile_cadence_enabled }, - { QZSettings::tile_cadence_order, QZSettings::default_tile_cadence_order }, - { QZSettings::tile_elevation_enabled, QZSettings::default_tile_elevation_enabled }, - { QZSettings::tile_elevation_order, QZSettings::default_tile_elevation_order }, - { QZSettings::tile_calories_enabled, QZSettings::default_tile_calories_enabled }, - { QZSettings::tile_calories_order, QZSettings::default_tile_calories_order }, - { QZSettings::tile_odometer_enabled, QZSettings::default_tile_odometer_enabled }, - { QZSettings::tile_odometer_order, QZSettings::default_tile_odometer_order }, - { QZSettings::tile_pace_enabled, QZSettings::default_tile_pace_enabled }, - { QZSettings::tile_pace_order, QZSettings::default_tile_pace_order }, - { QZSettings::tile_resistance_enabled, QZSettings::default_tile_resistance_enabled }, - { QZSettings::tile_resistance_order, QZSettings::default_tile_resistance_order }, - { QZSettings::tile_watt_enabled, QZSettings::default_tile_watt_enabled }, - { QZSettings::tile_watt_order, QZSettings::default_tile_watt_order }, - { QZSettings::tile_weight_loss_enabled, QZSettings::default_tile_weight_loss_enabled }, - { QZSettings::tile_weight_loss_order, QZSettings::default_tile_weight_loss_order }, - { QZSettings::tile_avgwatt_enabled, QZSettings::default_tile_avgwatt_enabled }, - { QZSettings::tile_avgwatt_order, QZSettings::default_tile_avgwatt_order }, - { QZSettings::tile_ftp_enabled, QZSettings::default_tile_ftp_enabled }, - { QZSettings::tile_ftp_order, QZSettings::default_tile_ftp_order }, - { QZSettings::tile_heart_enabled, QZSettings::default_tile_heart_enabled }, - { QZSettings::tile_heart_order, QZSettings::default_tile_heart_order }, - { QZSettings::tile_fan_enabled, QZSettings::default_tile_fan_enabled }, - { QZSettings::tile_fan_order, QZSettings::default_tile_fan_order }, - { QZSettings::tile_jouls_enabled, QZSettings::default_tile_jouls_enabled }, - { QZSettings::tile_jouls_order, QZSettings::default_tile_jouls_order }, - { QZSettings::tile_elapsed_enabled, QZSettings::default_tile_elapsed_enabled }, - { QZSettings::tile_elapsed_order, QZSettings::default_tile_elapsed_order }, - { QZSettings::tile_lapelapsed_enabled, QZSettings::default_tile_lapelapsed_enabled }, - { QZSettings::tile_lapelapsed_order, QZSettings::default_tile_lapelapsed_order }, - { QZSettings::tile_moving_time_enabled, QZSettings::default_tile_moving_time_enabled }, - { QZSettings::tile_moving_time_order, QZSettings::default_tile_moving_time_order }, - { QZSettings::tile_peloton_offset_enabled, QZSettings::default_tile_peloton_offset_enabled }, - { QZSettings::tile_peloton_offset_order, QZSettings::default_tile_peloton_offset_order }, - { QZSettings::tile_peloton_difficulty_enabled, QZSettings::default_tile_peloton_difficulty_enabled }, - { QZSettings::tile_peloton_difficulty_order, QZSettings::default_tile_peloton_difficulty_order }, - { QZSettings::tile_peloton_resistance_enabled, QZSettings::default_tile_peloton_resistance_enabled }, - { QZSettings::tile_peloton_resistance_order, QZSettings::default_tile_peloton_resistance_order }, - { QZSettings::tile_datetime_enabled, QZSettings::default_tile_datetime_enabled }, - { QZSettings::tile_datetime_order, QZSettings::default_tile_datetime_order }, - { QZSettings::tile_target_resistance_enabled, QZSettings::default_tile_target_resistance_enabled }, - { QZSettings::tile_target_resistance_order, QZSettings::default_tile_target_resistance_order }, - { QZSettings::tile_target_peloton_resistance_enabled, QZSettings::default_tile_target_peloton_resistance_enabled }, - { QZSettings::tile_target_peloton_resistance_order, QZSettings::default_tile_target_peloton_resistance_order }, - { QZSettings::tile_target_cadence_enabled, QZSettings::default_tile_target_cadence_enabled }, - { QZSettings::tile_target_cadence_order, QZSettings::default_tile_target_cadence_order }, - { QZSettings::tile_target_power_enabled, QZSettings::default_tile_target_power_enabled }, - { QZSettings::tile_target_power_order, QZSettings::default_tile_target_power_order }, - { QZSettings::tile_target_zone_enabled, QZSettings::default_tile_target_zone_enabled }, - { QZSettings::tile_target_zone_order, QZSettings::default_tile_target_zone_order }, - { QZSettings::tile_target_speed_enabled, QZSettings::default_tile_target_speed_enabled }, - { QZSettings::tile_target_speed_order, QZSettings::default_tile_target_speed_order }, - { QZSettings::tile_target_incline_enabled, QZSettings::default_tile_target_incline_enabled }, - { QZSettings::tile_target_incline_order, QZSettings::default_tile_target_incline_order }, - { QZSettings::tile_strokes_count_enabled, QZSettings::default_tile_strokes_count_enabled }, - { QZSettings::tile_strokes_count_order, QZSettings::default_tile_strokes_count_order }, - { QZSettings::tile_strokes_length_enabled, QZSettings::default_tile_strokes_length_enabled }, - { QZSettings::tile_strokes_length_order, QZSettings::default_tile_strokes_length_order }, - { QZSettings::tile_watt_kg_enabled, QZSettings::default_tile_watt_kg_enabled }, - { QZSettings::tile_watt_kg_order, QZSettings::default_tile_watt_kg_order }, - { QZSettings::tile_gears_enabled, QZSettings::default_tile_gears_enabled }, - { QZSettings::tile_gears_order, QZSettings::default_tile_gears_order }, - { QZSettings::tile_remainingtimetrainprogramrow_enabled, QZSettings::default_tile_remainingtimetrainprogramrow_enabled }, - { QZSettings::tile_remainingtimetrainprogramrow_order, QZSettings::default_tile_remainingtimetrainprogramrow_order }, - { QZSettings::tile_nextrowstrainprogram_enabled, QZSettings::default_tile_nextrowstrainprogram_enabled }, - { QZSettings::tile_nextrowstrainprogram_order, QZSettings::default_tile_nextrowstrainprogram_order }, - { QZSettings::tile_mets_enabled, QZSettings::default_tile_mets_enabled }, - { QZSettings::tile_mets_order, QZSettings::default_tile_mets_order }, - { QZSettings::tile_targetmets_enabled, QZSettings::default_tile_targetmets_enabled }, - { QZSettings::tile_targetmets_order, QZSettings::default_tile_targetmets_order }, - { QZSettings::tile_steering_angle_enabled, QZSettings::default_tile_steering_angle_enabled }, - { QZSettings::tile_steering_angle_order, QZSettings::default_tile_steering_angle_order }, - { QZSettings::tile_pid_hr_enabled, QZSettings::default_tile_pid_hr_enabled }, - { QZSettings::tile_pid_hr_order, QZSettings::default_tile_pid_hr_order }, - { QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1 }, - { QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2 }, - { QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3 }, - { QZSettings::heart_rate_zone4, QZSettings::default_heart_rate_zone4 }, - { QZSettings::heart_max_override_enable, QZSettings::default_heart_max_override_enable }, - { QZSettings::heart_max_override_value, QZSettings::default_heart_max_override_value }, - { QZSettings::peloton_gain, QZSettings::default_peloton_gain }, - { QZSettings::peloton_offset, QZSettings::default_peloton_offset }, - { QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone }, - { QZSettings::pacef_1mile, QZSettings::default_pacef_1mile }, - { QZSettings::pacef_5km, QZSettings::default_pacef_5km }, - { QZSettings::pacef_10km, QZSettings::default_pacef_10km }, - { QZSettings::pacef_halfmarathon, QZSettings::default_pacef_halfmarathon }, - { QZSettings::pacef_marathon, QZSettings::default_pacef_marathon }, - { QZSettings::pace_default, QZSettings::default_pace_default }, - { QZSettings::domyos_treadmill_buttons, QZSettings::default_domyos_treadmill_buttons }, - { QZSettings::domyos_treadmill_distance_display, QZSettings::default_domyos_treadmill_distance_display }, - { QZSettings::domyos_treadmill_display_invert, QZSettings::default_domyos_treadmill_display_invert }, - { QZSettings::domyos_bike_cadence_filter, QZSettings::default_domyos_bike_cadence_filter }, - { QZSettings::domyos_bike_display_calories, QZSettings::default_domyos_bike_display_calories }, - { QZSettings::domyos_elliptical_speed_ratio, QZSettings::default_domyos_elliptical_speed_ratio }, - { QZSettings::eslinker_cadenza, QZSettings::default_eslinker_cadenza }, - { QZSettings::eslinker_ypoo, QZSettings::default_eslinker_ypoo }, - { QZSettings::echelon_watttable, QZSettings::default_echelon_watttable }, - { QZSettings::proform_wheel_ratio, QZSettings::default_proform_wheel_ratio }, - { QZSettings::proform_tour_de_france_clc, QZSettings::default_proform_tour_de_france_clc }, - { QZSettings::proform_tdf_jonseed_watt, QZSettings::default_proform_tdf_jonseed_watt }, - { QZSettings::proform_studio, QZSettings::default_proform_studio }, - { QZSettings::proform_tdf_10, QZSettings::default_proform_tdf_10 }, - { QZSettings::horizon_gr7_cadence_multiplier, QZSettings::default_horizon_gr7_cadence_multiplier }, - { QZSettings::fitshow_user_id, QZSettings::default_fitshow_user_id }, - { QZSettings::inspire_peloton_formula, QZSettings::default_inspire_peloton_formula }, - { QZSettings::inspire_peloton_formula2, QZSettings::default_inspire_peloton_formula2 }, - { QZSettings::hammer_racer_s, QZSettings::default_hammer_racer_s }, - { QZSettings::pafers_treadmill, QZSettings::default_pafers_treadmill }, - { QZSettings::yesoul_peloton_formula, QZSettings::default_yesoul_peloton_formula }, - { QZSettings::nordictrack_10_treadmill, QZSettings::default_nordictrack_10_treadmill }, - { QZSettings::nordictrack_t65s_treadmill, QZSettings::default_nordictrack_t65s_treadmill }, - { QZSettings::toorx_3_0, QZSettings::default_toorx_3_0 }, - { QZSettings::toorx_65s_evo, QZSettings::default_toorx_65s_evo }, - { QZSettings::jtx_fitness_sprint_treadmill, QZSettings::default_jtx_fitness_sprint_treadmill }, - { QZSettings::dkn_endurun_treadmill, QZSettings::default_dkn_endurun_treadmill }, - { QZSettings::trx_route_key, QZSettings::default_trx_route_key }, - { QZSettings::bh_spada_2, QZSettings::default_bh_spada_2 }, - { QZSettings::toorx_bike, QZSettings::default_toorx_bike }, - { QZSettings::toorx_ftms, QZSettings::default_toorx_ftms }, - { QZSettings::jll_IC400_bike, QZSettings::default_jll_IC400_bike }, - { QZSettings::fytter_ri08_bike, QZSettings::default_fytter_ri08_bike }, - { QZSettings::asviva_bike, QZSettings::default_asviva_bike }, - { QZSettings::hertz_xr_770, QZSettings::default_hertz_xr_770 }, - { QZSettings::m3i_bike_id, QZSettings::default_m3i_bike_id }, - { QZSettings::m3i_bike_speed_buffsize, QZSettings::default_m3i_bike_speed_buffsize }, - { QZSettings::m3i_bike_qt_search, QZSettings::default_m3i_bike_qt_search }, - { QZSettings::m3i_bike_kcal, QZSettings::default_m3i_bike_kcal }, - { QZSettings::snode_bike, QZSettings::default_snode_bike }, - { QZSettings::fitplus_bike, QZSettings::default_fitplus_bike }, - { QZSettings::virtufit_etappe, QZSettings::default_virtufit_etappe }, - { QZSettings::flywheel_filter, QZSettings::default_flywheel_filter }, - { QZSettings::flywheel_life_fitness_ic8, QZSettings::default_flywheel_life_fitness_ic8 }, - { QZSettings::sole_treadmill_inclination, QZSettings::default_sole_treadmill_inclination }, - { QZSettings::sole_treadmill_miles, QZSettings::default_sole_treadmill_miles }, - { QZSettings::sole_treadmill_f65, QZSettings::default_sole_treadmill_f65 }, - { QZSettings::sole_treadmill_f63, QZSettings::default_sole_treadmill_f63 }, - { QZSettings::sole_treadmill_tt8, QZSettings::default_sole_treadmill_tt8 }, - { QZSettings::schwinn_bike_resistance, QZSettings::default_schwinn_bike_resistance }, - { QZSettings::schwinn_bike_resistance_v2, QZSettings::default_schwinn_bike_resistance_v2 }, - { QZSettings::technogym_myrun_treadmill_experimental, QZSettings::default_technogym_myrun_treadmill_experimental }, - { QZSettings::trainprogram_random, QZSettings::default_trainprogram_random }, - { QZSettings::trainprogram_total, QZSettings::default_trainprogram_total }, - { QZSettings::trainprogram_period_seconds, QZSettings::default_trainprogram_period_seconds }, - { QZSettings::trainprogram_speed_min, QZSettings::default_trainprogram_speed_min }, - { QZSettings::trainprogram_speed_max, QZSettings::default_trainprogram_speed_max }, - { QZSettings::trainprogram_incline_min, QZSettings::default_trainprogram_incline_min }, - { QZSettings::trainprogram_incline_max, QZSettings::default_trainprogram_incline_max }, - { QZSettings::trainprogram_resistance_min, QZSettings::default_trainprogram_resistance_min }, - { QZSettings::trainprogram_resistance_max, QZSettings::default_trainprogram_resistance_max }, - { QZSettings::watt_offset, QZSettings::default_watt_offset }, - { QZSettings::watt_gain, QZSettings::default_watt_gain }, - { QZSettings::power_avg_5s, QZSettings::default_power_avg_5s }, - { QZSettings::instant_power_on_pause, QZSettings::default_instant_power_on_pause }, - { QZSettings::speed_offset, QZSettings::default_speed_offset }, - { QZSettings::speed_gain, QZSettings::default_speed_gain }, - { QZSettings::filter_device, QZSettings::default_filter_device }, - { QZSettings::strava_suffix, QZSettings::default_strava_suffix }, - { QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name }, - { QZSettings::cadence_sensor_as_bike, QZSettings::default_cadence_sensor_as_bike }, - { QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio }, - { QZSettings::power_hr_pwr1, QZSettings::default_power_hr_pwr1 }, - { QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1 }, - { QZSettings::power_hr_pwr2, QZSettings::default_power_hr_pwr2 }, - { QZSettings::power_hr_hr2, QZSettings::default_power_hr_hr2 }, - { QZSettings::power_sensor_name, QZSettings::default_power_sensor_name }, - { QZSettings::power_sensor_as_bike, QZSettings::default_power_sensor_as_bike }, - { QZSettings::power_sensor_as_treadmill, QZSettings::default_power_sensor_as_treadmill }, - { QZSettings::powr_sensor_running_cadence_double, QZSettings::default_powr_sensor_running_cadence_double }, - { QZSettings::elite_rizer_name, QZSettings::default_elite_rizer_name }, - { QZSettings::elite_sterzo_smart_name, QZSettings::default_elite_sterzo_smart_name }, - { QZSettings::ftms_accessory_name, QZSettings::default_ftms_accessory_name }, - { QZSettings::ss2k_shift_step, QZSettings::default_ss2k_shift_step }, - { QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable }, - { QZSettings::fitmetria_fanfit_mode, QZSettings::default_fitmetria_fanfit_mode }, - { QZSettings::fitmetria_fanfit_min, QZSettings::default_fitmetria_fanfit_min }, - { QZSettings::fitmetria_fanfit_max, QZSettings::default_fitmetria_fanfit_max }, - { QZSettings::virtualbike_forceresistance, QZSettings::default_virtualbike_forceresistance }, - { QZSettings::bluetooth_relaxed, QZSettings::default_bluetooth_relaxed }, - { QZSettings::bluetooth_30m_hangs, QZSettings::default_bluetooth_30m_hangs }, - { QZSettings::battery_service, QZSettings::default_battery_service }, - { QZSettings::service_changed, QZSettings::default_service_changed }, - { QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled }, - { QZSettings::virtual_device_bluetooth, QZSettings::default_virtual_device_bluetooth }, - { QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround }, - { QZSettings::android_wakelock, QZSettings::default_android_wakelock }, - { QZSettings::log_debug, QZSettings::default_log_debug }, - { QZSettings::virtual_device_onlyheart, QZSettings::default_virtual_device_onlyheart }, - { QZSettings::virtual_device_echelon, QZSettings::default_virtual_device_echelon }, - { QZSettings::virtual_device_ifit, QZSettings::default_virtual_device_ifit }, - { QZSettings::virtual_device_rower, QZSettings::default_virtual_device_rower }, - { QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike }, - { QZSettings::volume_change_gears, QZSettings::default_volume_change_gears }, - { QZSettings::applewatch_fakedevice, QZSettings::default_applewatch_fakedevice }, - { QZSettings::zwift_erg_resistance_down, QZSettings::default_zwift_erg_resistance_down }, - { QZSettings::zwift_erg_resistance_up, QZSettings::default_zwift_erg_resistance_up }, - { QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x }, - { QZSettings::treadmill_step_speed, QZSettings::default_treadmill_step_speed }, - { QZSettings::treadmill_step_incline, QZSettings::default_treadmill_step_incline }, - { QZSettings::fitshow_anyrun, QZSettings::default_fitshow_anyrun }, - { QZSettings::nordictrack_s30_treadmill, QZSettings::default_nordictrack_s30_treadmill }, - { QZSettings::renpho_peloton_conversion_v2, QZSettings::default_renpho_peloton_conversion_v2 }, - { QZSettings::ss2k_resistance_sample_1, QZSettings::default_ss2k_resistance_sample_1 }, - { QZSettings::ss2k_shift_step_sample_1, QZSettings::default_ss2k_shift_step_sample_1 }, - { QZSettings::ss2k_resistance_sample_2, QZSettings::default_ss2k_resistance_sample_2 }, - { QZSettings::ss2k_shift_step_sample_2, QZSettings::default_ss2k_shift_step_sample_2 }, - { QZSettings::ss2k_resistance_sample_3, QZSettings::default_ss2k_resistance_sample_3 }, - { QZSettings::ss2k_shift_step_sample_3, QZSettings::default_ss2k_shift_step_sample_3 }, - { QZSettings::ss2k_resistance_sample_4, QZSettings::default_ss2k_resistance_sample_4 }, - { QZSettings::ss2k_shift_step_sample_4, QZSettings::default_ss2k_shift_step_sample_4 }, - { QZSettings::fitshow_truetimer, QZSettings::default_fitshow_truetimer }, - { QZSettings::elite_rizer_gain, QZSettings::default_elite_rizer_gain }, - { QZSettings::tile_ext_incline_enabled, QZSettings::default_tile_ext_incline_enabled }, - { QZSettings::tile_ext_incline_order, QZSettings::default_tile_ext_incline_order }, - { QZSettings::reebok_fr30_treadmill, QZSettings::default_reebok_fr30_treadmill }, - { QZSettings::horizon_treadmill_7_8, QZSettings::default_horizon_treadmill_7_8 }, - { QZSettings::profile_name, QZSettings::default_profile_name }, - { QZSettings::tile_cadence_color_enabled, QZSettings::default_tile_cadence_color_enabled }, - { QZSettings::tile_peloton_remaining_enabled, QZSettings::default_tile_peloton_remaining_enabled }, - { QZSettings::tile_peloton_remaining_order, QZSettings::default_tile_peloton_remaining_order }, - { QZSettings::tile_peloton_resistance_color_enabled, QZSettings::default_tile_peloton_resistance_color_enabled }, - { QZSettings::dircon_yes, QZSettings::default_dircon_yes }, - { QZSettings::dircon_server_base_port, QZSettings::default_dircon_server_base_port }, - { QZSettings::ios_cache_heart_device, QZSettings::default_ios_cache_heart_device }, - { QZSettings::app_opening, QZSettings::default_app_opening }, - { QZSettings::proformtdf4ip, QZSettings::default_proformtdf4ip }, - { QZSettings::fitfiu_mc_v460, QZSettings::default_fitfiu_mc_v460 }, - { QZSettings::bike_weight, QZSettings::default_bike_weight }, - { QZSettings::kingsmith_encrypt_v2, QZSettings::default_kingsmith_encrypt_v2 }, - { QZSettings::proform_treadmill_9_0, QZSettings::default_proform_treadmill_9_0 }, - { QZSettings::proform_treadmill_1800i, QZSettings::default_proform_treadmill_1800i }, - { QZSettings::cadence_offset, QZSettings::default_cadence_offset }, - { QZSettings::cadence_gain, QZSettings::default_cadence_gain }, - { QZSettings::sp_ht_9600ie, QZSettings::default_sp_ht_9600ie }, - { QZSettings::tts_enabled, QZSettings::default_tts_enabled }, - { QZSettings::tts_summary_sec, QZSettings::default_tts_summary_sec }, - { QZSettings::tts_act_speed, QZSettings::default_tts_act_speed }, - { QZSettings::tts_avg_speed, QZSettings::default_tts_avg_speed }, - { QZSettings::tts_max_speed, QZSettings::default_tts_max_speed }, - { QZSettings::tts_act_inclination, QZSettings::default_tts_act_inclination }, - { QZSettings::tts_act_cadence, QZSettings::default_tts_act_cadence }, - { QZSettings::tts_avg_cadence, QZSettings::default_tts_avg_cadence }, - { QZSettings::tts_max_cadence, QZSettings::default_tts_max_cadence }, - { QZSettings::tts_act_elevation, QZSettings::default_tts_act_elevation }, - { QZSettings::tts_act_calories, QZSettings::default_tts_act_calories }, - { QZSettings::tts_act_odometer, QZSettings::default_tts_act_odometer }, - { QZSettings::tts_act_pace, QZSettings::default_tts_act_pace }, - { QZSettings::tts_avg_pace, QZSettings::default_tts_avg_pace }, - { QZSettings::tts_max_pace, QZSettings::default_tts_max_pace }, - { QZSettings::tts_act_resistance, QZSettings::default_tts_act_resistance }, - { QZSettings::tts_avg_resistance, QZSettings::default_tts_avg_resistance }, - { QZSettings::tts_max_resistance, QZSettings::default_tts_max_resistance }, - { QZSettings::tts_act_watt, QZSettings::default_tts_act_watt }, - { QZSettings::tts_avg_watt, QZSettings::default_tts_avg_watt }, - { QZSettings::tts_max_watt, QZSettings::default_tts_max_watt }, - { QZSettings::tts_act_ftp, QZSettings::default_tts_act_ftp }, - { QZSettings::tts_avg_ftp, QZSettings::default_tts_avg_ftp }, - { QZSettings::tts_max_ftp, QZSettings::default_tts_max_ftp }, - { QZSettings::tts_act_heart, QZSettings::default_tts_act_heart }, - { QZSettings::tts_avg_heart, QZSettings::default_tts_avg_heart }, - { QZSettings::tts_max_heart, QZSettings::default_tts_max_heart }, - { QZSettings::tts_act_jouls, QZSettings::default_tts_act_jouls }, - { QZSettings::tts_act_elapsed, QZSettings::default_tts_act_elapsed }, - { QZSettings::tts_act_peloton_resistance, QZSettings::default_tts_act_peloton_resistance }, - { QZSettings::tts_avg_peloton_resistance, QZSettings::default_tts_avg_peloton_resistance }, - { QZSettings::tts_max_peloton_resistance, QZSettings::default_tts_max_peloton_resistance }, - { QZSettings::tts_act_target_peloton_resistance, QZSettings::default_tts_act_target_peloton_resistance }, - { QZSettings::tts_act_target_cadence, QZSettings::default_tts_act_target_cadence }, - { QZSettings::tts_act_target_power, QZSettings::default_tts_act_target_power }, - { QZSettings::tts_act_target_zone, QZSettings::default_tts_act_target_zone }, - { QZSettings::tts_act_target_speed, QZSettings::default_tts_act_target_speed }, - { QZSettings::tts_act_target_incline, QZSettings::default_tts_act_target_incline }, - { QZSettings::tts_act_watt_kg, QZSettings::default_tts_act_watt_kg }, - { QZSettings::tts_avg_watt_kg, QZSettings::default_tts_avg_watt_kg }, - { QZSettings::tts_max_watt_kg, QZSettings::default_tts_max_watt_kg }, - { QZSettings::fakedevice_elliptical, QZSettings::default_fakedevice_elliptical }, - { QZSettings::nordictrack_2950_ip, QZSettings::default_nordictrack_2950_ip }, - { QZSettings::tile_instantaneous_stride_length_enabled, QZSettings::default_tile_instantaneous_stride_length_enabled }, - { QZSettings::tile_instantaneous_stride_length_order, QZSettings::default_tile_instantaneous_stride_length_order }, - { QZSettings::tile_ground_contact_enabled, QZSettings::default_tile_ground_contact_enabled }, - { QZSettings::tile_ground_contact_order, QZSettings::default_tile_ground_contact_order }, - { QZSettings::tile_vertical_oscillation_enabled, QZSettings::default_tile_vertical_oscillation_enabled }, - { QZSettings::tile_vertical_oscillation_order, QZSettings::default_tile_vertical_oscillation_order }, - { QZSettings::sex, QZSettings::default_sex }, - { QZSettings::maps_type, QZSettings::default_maps_type }, - { QZSettings::ss2k_max_resistance, QZSettings::default_ss2k_max_resistance }, - { QZSettings::ss2k_min_resistance, QZSettings::default_ss2k_min_resistance }, - { QZSettings::proform_treadmill_se, QZSettings::default_proform_treadmill_se }, - { QZSettings::proformtreadmillip, QZSettings::default_proformtreadmillip }, - { QZSettings::kingsmith_encrypt_v3, QZSettings::default_kingsmith_encrypt_v3 }, - { QZSettings::tdf_10_ip, QZSettings::default_tdf_10_ip }, - { QZSettings::fakedevice_treadmill, QZSettings::default_fakedevice_treadmill }, - { QZSettings::video_playback_window_s, QZSettings::default_video_playback_window_s }, - { QZSettings::horizon_treadmill_profile_user1, QZSettings::default_horizon_treadmill_profile_user1}, - { QZSettings::horizon_treadmill_profile_user2, QZSettings::default_horizon_treadmill_profile_user2}, - { QZSettings::horizon_treadmill_profile_user3, QZSettings::default_horizon_treadmill_profile_user3}, - { QZSettings::horizon_treadmill_profile_user4, QZSettings::default_horizon_treadmill_profile_user4}, - { QZSettings::horizon_treadmill_profile_user5, QZSettings::default_horizon_treadmill_profile_user5}, - { QZSettings::nordictrack_gx_2_7, QZSettings::default_nordictrack_gx_2_7}, - { QZSettings::rolling_resistance, QZSettings::default_rolling_resistance}, - { QZSettings::wahoo_rgt_dircon, QZSettings::default_wahoo_rgt_dircon} -}; +const uint32_t allSettingsCount = 370; +QVariant allSettings[allSettingsCount][2] = { + {QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles}, + {QZSettings::bluetooth_no_reconnection, QZSettings::default_bluetooth_no_reconnection}, + {QZSettings::bike_wheel_revs, QZSettings::default_bike_wheel_revs}, + {QZSettings::bluetooth_lastdevice_name, QZSettings::default_bluetooth_lastdevice_name}, + {QZSettings::bluetooth_lastdevice_address, QZSettings::default_bluetooth_lastdevice_address}, + {QZSettings::hrm_lastdevice_name, QZSettings::default_hrm_lastdevice_name}, + {QZSettings::hrm_lastdevice_address, QZSettings::default_hrm_lastdevice_address}, + {QZSettings::ftms_accessory_address, QZSettings::default_ftms_accessory_address}, + {QZSettings::ftms_accessory_lastdevice_name, QZSettings::default_ftms_accessory_lastdevice_name}, + {QZSettings::csc_sensor_address, QZSettings::default_csc_sensor_address}, + {QZSettings::csc_sensor_lastdevice_name, QZSettings::default_csc_sensor_lastdevice_name}, + {QZSettings::power_sensor_lastdevice_name, QZSettings::default_power_sensor_lastdevice_name}, + {QZSettings::power_sensor_address, QZSettings::default_power_sensor_address}, + {QZSettings::elite_rizer_lastdevice_name, QZSettings::default_elite_rizer_lastdevice_name}, + {QZSettings::elite_rizer_address, QZSettings::default_elite_rizer_address}, + {QZSettings::elite_sterzo_smart_lastdevice_name, QZSettings::default_elite_sterzo_smart_lastdevice_name}, + {QZSettings::elite_sterzo_smart_address, QZSettings::default_elite_sterzo_smart_address}, + {QZSettings::strava_accesstoken, QZSettings::default_strava_accesstoken}, + {QZSettings::strava_refreshtoken, QZSettings::default_strava_refreshtoken}, + {QZSettings::strava_lastrefresh, QZSettings::default_strava_lastrefresh}, + {QZSettings::strava_expires, QZSettings::default_strava_expires}, + {QZSettings::ui_zoom, QZSettings::default_ui_zoom}, + {QZSettings::bike_heartrate_service, QZSettings::default_bike_heartrate_service}, + {QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset}, + {QZSettings::bike_resistance_gain_f, QZSettings::default_bike_resistance_gain_f}, + {QZSettings::zwift_erg, QZSettings::default_zwift_erg}, + {QZSettings::zwift_erg_filter, QZSettings::default_zwift_erg_filter}, + {QZSettings::zwift_erg_filter_down, QZSettings::default_zwift_erg_filter_down}, + {QZSettings::zwift_negative_inclination_x2, QZSettings::default_zwift_negative_inclination_x2}, + {QZSettings::zwift_inclination_offset, QZSettings::default_zwift_inclination_offset}, + {QZSettings::zwift_inclination_gain, QZSettings::default_zwift_inclination_gain}, + {QZSettings::echelon_resistance_offset, QZSettings::default_echelon_resistance_offset}, + {QZSettings::echelon_resistance_gain, QZSettings::default_echelon_resistance_gain}, + {QZSettings::speed_power_based, QZSettings::default_speed_power_based}, + {QZSettings::bike_resistance_start, QZSettings::default_bike_resistance_start}, + {QZSettings::age, QZSettings::default_age}, + {QZSettings::weight, QZSettings::default_weight}, + {QZSettings::ftp, QZSettings::default_ftp}, + {QZSettings::user_email, QZSettings::default_user_email}, + {QZSettings::user_nickname, QZSettings::default_user_nickname}, + {QZSettings::miles_unit, QZSettings::default_miles_unit}, + {QZSettings::pause_on_start, QZSettings::default_pause_on_start}, + {QZSettings::treadmill_force_speed, QZSettings::default_treadmill_force_speed}, + {QZSettings::pause_on_start_treadmill, QZSettings::default_pause_on_start_treadmill}, + {QZSettings::continuous_moving, QZSettings::default_continuous_moving}, + {QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor}, + {QZSettings::run_cadence_sensor, QZSettings::default_run_cadence_sensor}, + {QZSettings::bike_power_sensor, QZSettings::default_bike_power_sensor}, + {QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name}, + {QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin}, + {QZSettings::kcal_ignore_builtin, QZSettings::default_kcal_ignore_builtin}, + {QZSettings::ant_cadence, QZSettings::default_ant_cadence}, + {QZSettings::ant_heart, QZSettings::default_ant_heart}, + {QZSettings::ant_garmin, QZSettings::default_ant_garmin}, + {QZSettings::top_bar_enabled, QZSettings::default_top_bar_enabled}, + {QZSettings::peloton_username, QZSettings::default_peloton_username}, + {QZSettings::peloton_password, QZSettings::default_peloton_password}, + {QZSettings::peloton_difficulty, QZSettings::default_peloton_difficulty}, + {QZSettings::peloton_cadence_metric, QZSettings::default_peloton_cadence_metric}, + {QZSettings::peloton_heartrate_metric, QZSettings::default_peloton_heartrate_metric}, + {QZSettings::peloton_date, QZSettings::default_peloton_date}, + {QZSettings::peloton_description_link, QZSettings::default_peloton_description_link}, + {QZSettings::pzp_username, QZSettings::default_pzp_username}, + {QZSettings::pzp_password, QZSettings::default_pzp_password}, + {QZSettings::tile_speed_enabled, QZSettings::default_tile_speed_enabled}, + {QZSettings::tile_speed_order, QZSettings::default_tile_speed_order}, + {QZSettings::tile_inclination_enabled, QZSettings::default_tile_inclination_enabled}, + {QZSettings::tile_inclination_order, QZSettings::default_tile_inclination_order}, + {QZSettings::tile_cadence_enabled, QZSettings::default_tile_cadence_enabled}, + {QZSettings::tile_cadence_order, QZSettings::default_tile_cadence_order}, + {QZSettings::tile_elevation_enabled, QZSettings::default_tile_elevation_enabled}, + {QZSettings::tile_elevation_order, QZSettings::default_tile_elevation_order}, + {QZSettings::tile_calories_enabled, QZSettings::default_tile_calories_enabled}, + {QZSettings::tile_calories_order, QZSettings::default_tile_calories_order}, + {QZSettings::tile_odometer_enabled, QZSettings::default_tile_odometer_enabled}, + {QZSettings::tile_odometer_order, QZSettings::default_tile_odometer_order}, + {QZSettings::tile_pace_enabled, QZSettings::default_tile_pace_enabled}, + {QZSettings::tile_pace_order, QZSettings::default_tile_pace_order}, + {QZSettings::tile_resistance_enabled, QZSettings::default_tile_resistance_enabled}, + {QZSettings::tile_resistance_order, QZSettings::default_tile_resistance_order}, + {QZSettings::tile_watt_enabled, QZSettings::default_tile_watt_enabled}, + {QZSettings::tile_watt_order, QZSettings::default_tile_watt_order}, + {QZSettings::tile_weight_loss_enabled, QZSettings::default_tile_weight_loss_enabled}, + {QZSettings::tile_weight_loss_order, QZSettings::default_tile_weight_loss_order}, + {QZSettings::tile_avgwatt_enabled, QZSettings::default_tile_avgwatt_enabled}, + {QZSettings::tile_avgwatt_order, QZSettings::default_tile_avgwatt_order}, + {QZSettings::tile_ftp_enabled, QZSettings::default_tile_ftp_enabled}, + {QZSettings::tile_ftp_order, QZSettings::default_tile_ftp_order}, + {QZSettings::tile_heart_enabled, QZSettings::default_tile_heart_enabled}, + {QZSettings::tile_heart_order, QZSettings::default_tile_heart_order}, + {QZSettings::tile_fan_enabled, QZSettings::default_tile_fan_enabled}, + {QZSettings::tile_fan_order, QZSettings::default_tile_fan_order}, + {QZSettings::tile_jouls_enabled, QZSettings::default_tile_jouls_enabled}, + {QZSettings::tile_jouls_order, QZSettings::default_tile_jouls_order}, + {QZSettings::tile_elapsed_enabled, QZSettings::default_tile_elapsed_enabled}, + {QZSettings::tile_elapsed_order, QZSettings::default_tile_elapsed_order}, + {QZSettings::tile_lapelapsed_enabled, QZSettings::default_tile_lapelapsed_enabled}, + {QZSettings::tile_lapelapsed_order, QZSettings::default_tile_lapelapsed_order}, + {QZSettings::tile_moving_time_enabled, QZSettings::default_tile_moving_time_enabled}, + {QZSettings::tile_moving_time_order, QZSettings::default_tile_moving_time_order}, + {QZSettings::tile_peloton_offset_enabled, QZSettings::default_tile_peloton_offset_enabled}, + {QZSettings::tile_peloton_offset_order, QZSettings::default_tile_peloton_offset_order}, + {QZSettings::tile_peloton_difficulty_enabled, QZSettings::default_tile_peloton_difficulty_enabled}, + {QZSettings::tile_peloton_difficulty_order, QZSettings::default_tile_peloton_difficulty_order}, + {QZSettings::tile_peloton_resistance_enabled, QZSettings::default_tile_peloton_resistance_enabled}, + {QZSettings::tile_peloton_resistance_order, QZSettings::default_tile_peloton_resistance_order}, + {QZSettings::tile_datetime_enabled, QZSettings::default_tile_datetime_enabled}, + {QZSettings::tile_datetime_order, QZSettings::default_tile_datetime_order}, + {QZSettings::tile_target_resistance_enabled, QZSettings::default_tile_target_resistance_enabled}, + {QZSettings::tile_target_resistance_order, QZSettings::default_tile_target_resistance_order}, + {QZSettings::tile_target_peloton_resistance_enabled, QZSettings::default_tile_target_peloton_resistance_enabled}, + {QZSettings::tile_target_peloton_resistance_order, QZSettings::default_tile_target_peloton_resistance_order}, + {QZSettings::tile_target_cadence_enabled, QZSettings::default_tile_target_cadence_enabled}, + {QZSettings::tile_target_cadence_order, QZSettings::default_tile_target_cadence_order}, + {QZSettings::tile_target_power_enabled, QZSettings::default_tile_target_power_enabled}, + {QZSettings::tile_target_power_order, QZSettings::default_tile_target_power_order}, + {QZSettings::tile_target_zone_enabled, QZSettings::default_tile_target_zone_enabled}, + {QZSettings::tile_target_zone_order, QZSettings::default_tile_target_zone_order}, + {QZSettings::tile_target_speed_enabled, QZSettings::default_tile_target_speed_enabled}, + {QZSettings::tile_target_speed_order, QZSettings::default_tile_target_speed_order}, + {QZSettings::tile_target_incline_enabled, QZSettings::default_tile_target_incline_enabled}, + {QZSettings::tile_target_incline_order, QZSettings::default_tile_target_incline_order}, + {QZSettings::tile_strokes_count_enabled, QZSettings::default_tile_strokes_count_enabled}, + {QZSettings::tile_strokes_count_order, QZSettings::default_tile_strokes_count_order}, + {QZSettings::tile_strokes_length_enabled, QZSettings::default_tile_strokes_length_enabled}, + {QZSettings::tile_strokes_length_order, QZSettings::default_tile_strokes_length_order}, + {QZSettings::tile_watt_kg_enabled, QZSettings::default_tile_watt_kg_enabled}, + {QZSettings::tile_watt_kg_order, QZSettings::default_tile_watt_kg_order}, + {QZSettings::tile_gears_enabled, QZSettings::default_tile_gears_enabled}, + {QZSettings::tile_gears_order, QZSettings::default_tile_gears_order}, + {QZSettings::tile_remainingtimetrainprogramrow_enabled, + QZSettings::default_tile_remainingtimetrainprogramrow_enabled}, + {QZSettings::tile_remainingtimetrainprogramrow_order, QZSettings::default_tile_remainingtimetrainprogramrow_order}, + {QZSettings::tile_nextrowstrainprogram_enabled, QZSettings::default_tile_nextrowstrainprogram_enabled}, + {QZSettings::tile_nextrowstrainprogram_order, QZSettings::default_tile_nextrowstrainprogram_order}, + {QZSettings::tile_mets_enabled, QZSettings::default_tile_mets_enabled}, + {QZSettings::tile_mets_order, QZSettings::default_tile_mets_order}, + {QZSettings::tile_targetmets_enabled, QZSettings::default_tile_targetmets_enabled}, + {QZSettings::tile_targetmets_order, QZSettings::default_tile_targetmets_order}, + {QZSettings::tile_steering_angle_enabled, QZSettings::default_tile_steering_angle_enabled}, + {QZSettings::tile_steering_angle_order, QZSettings::default_tile_steering_angle_order}, + {QZSettings::tile_pid_hr_enabled, QZSettings::default_tile_pid_hr_enabled}, + {QZSettings::tile_pid_hr_order, QZSettings::default_tile_pid_hr_order}, + {QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1}, + {QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2}, + {QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3}, + {QZSettings::heart_rate_zone4, QZSettings::default_heart_rate_zone4}, + {QZSettings::heart_max_override_enable, QZSettings::default_heart_max_override_enable}, + {QZSettings::heart_max_override_value, QZSettings::default_heart_max_override_value}, + {QZSettings::peloton_gain, QZSettings::default_peloton_gain}, + {QZSettings::peloton_offset, QZSettings::default_peloton_offset}, + {QZSettings::treadmill_pid_heart_zone, QZSettings::default_treadmill_pid_heart_zone}, + {QZSettings::pacef_1mile, QZSettings::default_pacef_1mile}, + {QZSettings::pacef_5km, QZSettings::default_pacef_5km}, + {QZSettings::pacef_10km, QZSettings::default_pacef_10km}, + {QZSettings::pacef_halfmarathon, QZSettings::default_pacef_halfmarathon}, + {QZSettings::pacef_marathon, QZSettings::default_pacef_marathon}, + {QZSettings::pace_default, QZSettings::default_pace_default}, + {QZSettings::domyos_treadmill_buttons, QZSettings::default_domyos_treadmill_buttons}, + {QZSettings::domyos_treadmill_distance_display, QZSettings::default_domyos_treadmill_distance_display}, + {QZSettings::domyos_treadmill_display_invert, QZSettings::default_domyos_treadmill_display_invert}, + {QZSettings::domyos_bike_cadence_filter, QZSettings::default_domyos_bike_cadence_filter}, + {QZSettings::domyos_bike_display_calories, QZSettings::default_domyos_bike_display_calories}, + {QZSettings::domyos_elliptical_speed_ratio, QZSettings::default_domyos_elliptical_speed_ratio}, + {QZSettings::eslinker_cadenza, QZSettings::default_eslinker_cadenza}, + {QZSettings::eslinker_ypoo, QZSettings::default_eslinker_ypoo}, + {QZSettings::echelon_watttable, QZSettings::default_echelon_watttable}, + {QZSettings::proform_wheel_ratio, QZSettings::default_proform_wheel_ratio}, + {QZSettings::proform_tour_de_france_clc, QZSettings::default_proform_tour_de_france_clc}, + {QZSettings::proform_tdf_jonseed_watt, QZSettings::default_proform_tdf_jonseed_watt}, + {QZSettings::proform_studio, QZSettings::default_proform_studio}, + {QZSettings::proform_tdf_10, QZSettings::default_proform_tdf_10}, + {QZSettings::horizon_gr7_cadence_multiplier, QZSettings::default_horizon_gr7_cadence_multiplier}, + {QZSettings::fitshow_user_id, QZSettings::default_fitshow_user_id}, + {QZSettings::inspire_peloton_formula, QZSettings::default_inspire_peloton_formula}, + {QZSettings::inspire_peloton_formula2, QZSettings::default_inspire_peloton_formula2}, + {QZSettings::hammer_racer_s, QZSettings::default_hammer_racer_s}, + {QZSettings::pafers_treadmill, QZSettings::default_pafers_treadmill}, + {QZSettings::yesoul_peloton_formula, QZSettings::default_yesoul_peloton_formula}, + {QZSettings::nordictrack_10_treadmill, QZSettings::default_nordictrack_10_treadmill}, + {QZSettings::nordictrack_t65s_treadmill, QZSettings::default_nordictrack_t65s_treadmill}, + {QZSettings::toorx_3_0, QZSettings::default_toorx_3_0}, + {QZSettings::toorx_65s_evo, QZSettings::default_toorx_65s_evo}, + {QZSettings::jtx_fitness_sprint_treadmill, QZSettings::default_jtx_fitness_sprint_treadmill}, + {QZSettings::dkn_endurun_treadmill, QZSettings::default_dkn_endurun_treadmill}, + {QZSettings::trx_route_key, QZSettings::default_trx_route_key}, + {QZSettings::bh_spada_2, QZSettings::default_bh_spada_2}, + {QZSettings::toorx_bike, QZSettings::default_toorx_bike}, + {QZSettings::toorx_ftms, QZSettings::default_toorx_ftms}, + {QZSettings::jll_IC400_bike, QZSettings::default_jll_IC400_bike}, + {QZSettings::fytter_ri08_bike, QZSettings::default_fytter_ri08_bike}, + {QZSettings::asviva_bike, QZSettings::default_asviva_bike}, + {QZSettings::hertz_xr_770, QZSettings::default_hertz_xr_770}, + {QZSettings::m3i_bike_id, QZSettings::default_m3i_bike_id}, + {QZSettings::m3i_bike_speed_buffsize, QZSettings::default_m3i_bike_speed_buffsize}, + {QZSettings::m3i_bike_qt_search, QZSettings::default_m3i_bike_qt_search}, + {QZSettings::m3i_bike_kcal, QZSettings::default_m3i_bike_kcal}, + {QZSettings::snode_bike, QZSettings::default_snode_bike}, + {QZSettings::fitplus_bike, QZSettings::default_fitplus_bike}, + {QZSettings::virtufit_etappe, QZSettings::default_virtufit_etappe}, + {QZSettings::flywheel_filter, QZSettings::default_flywheel_filter}, + {QZSettings::flywheel_life_fitness_ic8, QZSettings::default_flywheel_life_fitness_ic8}, + {QZSettings::sole_treadmill_inclination, QZSettings::default_sole_treadmill_inclination}, + {QZSettings::sole_treadmill_miles, QZSettings::default_sole_treadmill_miles}, + {QZSettings::sole_treadmill_f65, QZSettings::default_sole_treadmill_f65}, + {QZSettings::sole_treadmill_f63, QZSettings::default_sole_treadmill_f63}, + {QZSettings::sole_treadmill_tt8, QZSettings::default_sole_treadmill_tt8}, + {QZSettings::schwinn_bike_resistance, QZSettings::default_schwinn_bike_resistance}, + {QZSettings::schwinn_bike_resistance_v2, QZSettings::default_schwinn_bike_resistance_v2}, + {QZSettings::technogym_myrun_treadmill_experimental, QZSettings::default_technogym_myrun_treadmill_experimental}, + {QZSettings::trainprogram_random, QZSettings::default_trainprogram_random}, + {QZSettings::trainprogram_total, QZSettings::default_trainprogram_total}, + {QZSettings::trainprogram_period_seconds, QZSettings::default_trainprogram_period_seconds}, + {QZSettings::trainprogram_speed_min, QZSettings::default_trainprogram_speed_min}, + {QZSettings::trainprogram_speed_max, QZSettings::default_trainprogram_speed_max}, + {QZSettings::trainprogram_incline_min, QZSettings::default_trainprogram_incline_min}, + {QZSettings::trainprogram_incline_max, QZSettings::default_trainprogram_incline_max}, + {QZSettings::trainprogram_resistance_min, QZSettings::default_trainprogram_resistance_min}, + {QZSettings::trainprogram_resistance_max, QZSettings::default_trainprogram_resistance_max}, + {QZSettings::watt_offset, QZSettings::default_watt_offset}, + {QZSettings::watt_gain, QZSettings::default_watt_gain}, + {QZSettings::power_avg_5s, QZSettings::default_power_avg_5s}, + {QZSettings::instant_power_on_pause, QZSettings::default_instant_power_on_pause}, + {QZSettings::speed_offset, QZSettings::default_speed_offset}, + {QZSettings::speed_gain, QZSettings::default_speed_gain}, + {QZSettings::filter_device, QZSettings::default_filter_device}, + {QZSettings::strava_suffix, QZSettings::default_strava_suffix}, + {QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name}, + {QZSettings::cadence_sensor_as_bike, QZSettings::default_cadence_sensor_as_bike}, + {QZSettings::cadence_sensor_speed_ratio, QZSettings::default_cadence_sensor_speed_ratio}, + {QZSettings::power_hr_pwr1, QZSettings::default_power_hr_pwr1}, + {QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1}, + {QZSettings::power_hr_pwr2, QZSettings::default_power_hr_pwr2}, + {QZSettings::power_hr_hr2, QZSettings::default_power_hr_hr2}, + {QZSettings::power_sensor_name, QZSettings::default_power_sensor_name}, + {QZSettings::power_sensor_as_bike, QZSettings::default_power_sensor_as_bike}, + {QZSettings::power_sensor_as_treadmill, QZSettings::default_power_sensor_as_treadmill}, + {QZSettings::powr_sensor_running_cadence_double, QZSettings::default_powr_sensor_running_cadence_double}, + {QZSettings::elite_rizer_name, QZSettings::default_elite_rizer_name}, + {QZSettings::elite_sterzo_smart_name, QZSettings::default_elite_sterzo_smart_name}, + {QZSettings::ftms_accessory_name, QZSettings::default_ftms_accessory_name}, + {QZSettings::ss2k_shift_step, QZSettings::default_ss2k_shift_step}, + {QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable}, + {QZSettings::fitmetria_fanfit_mode, QZSettings::default_fitmetria_fanfit_mode}, + {QZSettings::fitmetria_fanfit_min, QZSettings::default_fitmetria_fanfit_min}, + {QZSettings::fitmetria_fanfit_max, QZSettings::default_fitmetria_fanfit_max}, + {QZSettings::virtualbike_forceresistance, QZSettings::default_virtualbike_forceresistance}, + {QZSettings::bluetooth_relaxed, QZSettings::default_bluetooth_relaxed}, + {QZSettings::bluetooth_30m_hangs, QZSettings::default_bluetooth_30m_hangs}, + {QZSettings::battery_service, QZSettings::default_battery_service}, + {QZSettings::service_changed, QZSettings::default_service_changed}, + {QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled}, + {QZSettings::virtual_device_bluetooth, QZSettings::default_virtual_device_bluetooth}, + {QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround}, + {QZSettings::android_wakelock, QZSettings::default_android_wakelock}, + {QZSettings::log_debug, QZSettings::default_log_debug}, + {QZSettings::virtual_device_onlyheart, QZSettings::default_virtual_device_onlyheart}, + {QZSettings::virtual_device_echelon, QZSettings::default_virtual_device_echelon}, + {QZSettings::virtual_device_ifit, QZSettings::default_virtual_device_ifit}, + {QZSettings::virtual_device_rower, QZSettings::default_virtual_device_rower}, + {QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike}, + {QZSettings::volume_change_gears, QZSettings::default_volume_change_gears}, + {QZSettings::applewatch_fakedevice, QZSettings::default_applewatch_fakedevice}, + {QZSettings::zwift_erg_resistance_down, QZSettings::default_zwift_erg_resistance_down}, + {QZSettings::zwift_erg_resistance_up, QZSettings::default_zwift_erg_resistance_up}, + {QZSettings::horizon_paragon_x, QZSettings::default_horizon_paragon_x}, + {QZSettings::treadmill_step_speed, QZSettings::default_treadmill_step_speed}, + {QZSettings::treadmill_step_incline, QZSettings::default_treadmill_step_incline}, + {QZSettings::fitshow_anyrun, QZSettings::default_fitshow_anyrun}, + {QZSettings::nordictrack_s30_treadmill, QZSettings::default_nordictrack_s30_treadmill}, + {QZSettings::renpho_peloton_conversion_v2, QZSettings::default_renpho_peloton_conversion_v2}, + {QZSettings::ss2k_resistance_sample_1, QZSettings::default_ss2k_resistance_sample_1}, + {QZSettings::ss2k_shift_step_sample_1, QZSettings::default_ss2k_shift_step_sample_1}, + {QZSettings::ss2k_resistance_sample_2, QZSettings::default_ss2k_resistance_sample_2}, + {QZSettings::ss2k_shift_step_sample_2, QZSettings::default_ss2k_shift_step_sample_2}, + {QZSettings::ss2k_resistance_sample_3, QZSettings::default_ss2k_resistance_sample_3}, + {QZSettings::ss2k_shift_step_sample_3, QZSettings::default_ss2k_shift_step_sample_3}, + {QZSettings::ss2k_resistance_sample_4, QZSettings::default_ss2k_resistance_sample_4}, + {QZSettings::ss2k_shift_step_sample_4, QZSettings::default_ss2k_shift_step_sample_4}, + {QZSettings::fitshow_truetimer, QZSettings::default_fitshow_truetimer}, + {QZSettings::elite_rizer_gain, QZSettings::default_elite_rizer_gain}, + {QZSettings::tile_ext_incline_enabled, QZSettings::default_tile_ext_incline_enabled}, + {QZSettings::tile_ext_incline_order, QZSettings::default_tile_ext_incline_order}, + {QZSettings::reebok_fr30_treadmill, QZSettings::default_reebok_fr30_treadmill}, + {QZSettings::horizon_treadmill_7_8, QZSettings::default_horizon_treadmill_7_8}, + {QZSettings::profile_name, QZSettings::default_profile_name}, + {QZSettings::tile_cadence_color_enabled, QZSettings::default_tile_cadence_color_enabled}, + {QZSettings::tile_peloton_remaining_enabled, QZSettings::default_tile_peloton_remaining_enabled}, + {QZSettings::tile_peloton_remaining_order, QZSettings::default_tile_peloton_remaining_order}, + {QZSettings::tile_peloton_resistance_color_enabled, QZSettings::default_tile_peloton_resistance_color_enabled}, + {QZSettings::dircon_yes, QZSettings::default_dircon_yes}, + {QZSettings::dircon_server_base_port, QZSettings::default_dircon_server_base_port}, + {QZSettings::ios_cache_heart_device, QZSettings::default_ios_cache_heart_device}, + {QZSettings::app_opening, QZSettings::default_app_opening}, + {QZSettings::proformtdf4ip, QZSettings::default_proformtdf4ip}, + {QZSettings::fitfiu_mc_v460, QZSettings::default_fitfiu_mc_v460}, + {QZSettings::bike_weight, QZSettings::default_bike_weight}, + {QZSettings::kingsmith_encrypt_v2, QZSettings::default_kingsmith_encrypt_v2}, + {QZSettings::proform_treadmill_9_0, QZSettings::default_proform_treadmill_9_0}, + {QZSettings::proform_treadmill_1800i, QZSettings::default_proform_treadmill_1800i}, + {QZSettings::cadence_offset, QZSettings::default_cadence_offset}, + {QZSettings::cadence_gain, QZSettings::default_cadence_gain}, + {QZSettings::sp_ht_9600ie, QZSettings::default_sp_ht_9600ie}, + {QZSettings::tts_enabled, QZSettings::default_tts_enabled}, + {QZSettings::tts_summary_sec, QZSettings::default_tts_summary_sec}, + {QZSettings::tts_act_speed, QZSettings::default_tts_act_speed}, + {QZSettings::tts_avg_speed, QZSettings::default_tts_avg_speed}, + {QZSettings::tts_max_speed, QZSettings::default_tts_max_speed}, + {QZSettings::tts_act_inclination, QZSettings::default_tts_act_inclination}, + {QZSettings::tts_act_cadence, QZSettings::default_tts_act_cadence}, + {QZSettings::tts_avg_cadence, QZSettings::default_tts_avg_cadence}, + {QZSettings::tts_max_cadence, QZSettings::default_tts_max_cadence}, + {QZSettings::tts_act_elevation, QZSettings::default_tts_act_elevation}, + {QZSettings::tts_act_calories, QZSettings::default_tts_act_calories}, + {QZSettings::tts_act_odometer, QZSettings::default_tts_act_odometer}, + {QZSettings::tts_act_pace, QZSettings::default_tts_act_pace}, + {QZSettings::tts_avg_pace, QZSettings::default_tts_avg_pace}, + {QZSettings::tts_max_pace, QZSettings::default_tts_max_pace}, + {QZSettings::tts_act_resistance, QZSettings::default_tts_act_resistance}, + {QZSettings::tts_avg_resistance, QZSettings::default_tts_avg_resistance}, + {QZSettings::tts_max_resistance, QZSettings::default_tts_max_resistance}, + {QZSettings::tts_act_watt, QZSettings::default_tts_act_watt}, + {QZSettings::tts_avg_watt, QZSettings::default_tts_avg_watt}, + {QZSettings::tts_max_watt, QZSettings::default_tts_max_watt}, + {QZSettings::tts_act_ftp, QZSettings::default_tts_act_ftp}, + {QZSettings::tts_avg_ftp, QZSettings::default_tts_avg_ftp}, + {QZSettings::tts_max_ftp, QZSettings::default_tts_max_ftp}, + {QZSettings::tts_act_heart, QZSettings::default_tts_act_heart}, + {QZSettings::tts_avg_heart, QZSettings::default_tts_avg_heart}, + {QZSettings::tts_max_heart, QZSettings::default_tts_max_heart}, + {QZSettings::tts_act_jouls, QZSettings::default_tts_act_jouls}, + {QZSettings::tts_act_elapsed, QZSettings::default_tts_act_elapsed}, + {QZSettings::tts_act_peloton_resistance, QZSettings::default_tts_act_peloton_resistance}, + {QZSettings::tts_avg_peloton_resistance, QZSettings::default_tts_avg_peloton_resistance}, + {QZSettings::tts_max_peloton_resistance, QZSettings::default_tts_max_peloton_resistance}, + {QZSettings::tts_act_target_peloton_resistance, QZSettings::default_tts_act_target_peloton_resistance}, + {QZSettings::tts_act_target_cadence, QZSettings::default_tts_act_target_cadence}, + {QZSettings::tts_act_target_power, QZSettings::default_tts_act_target_power}, + {QZSettings::tts_act_target_zone, QZSettings::default_tts_act_target_zone}, + {QZSettings::tts_act_target_speed, QZSettings::default_tts_act_target_speed}, + {QZSettings::tts_act_target_incline, QZSettings::default_tts_act_target_incline}, + {QZSettings::tts_act_watt_kg, QZSettings::default_tts_act_watt_kg}, + {QZSettings::tts_avg_watt_kg, QZSettings::default_tts_avg_watt_kg}, + {QZSettings::tts_max_watt_kg, QZSettings::default_tts_max_watt_kg}, + {QZSettings::fakedevice_elliptical, QZSettings::default_fakedevice_elliptical}, + {QZSettings::nordictrack_2950_ip, QZSettings::default_nordictrack_2950_ip}, + {QZSettings::tile_instantaneous_stride_length_enabled, + QZSettings::default_tile_instantaneous_stride_length_enabled}, + {QZSettings::tile_instantaneous_stride_length_order, QZSettings::default_tile_instantaneous_stride_length_order}, + {QZSettings::tile_ground_contact_enabled, QZSettings::default_tile_ground_contact_enabled}, + {QZSettings::tile_ground_contact_order, QZSettings::default_tile_ground_contact_order}, + {QZSettings::tile_vertical_oscillation_enabled, QZSettings::default_tile_vertical_oscillation_enabled}, + {QZSettings::tile_vertical_oscillation_order, QZSettings::default_tile_vertical_oscillation_order}, + {QZSettings::sex, QZSettings::default_sex}, + {QZSettings::maps_type, QZSettings::default_maps_type}, + {QZSettings::ss2k_max_resistance, QZSettings::default_ss2k_max_resistance}, + {QZSettings::ss2k_min_resistance, QZSettings::default_ss2k_min_resistance}, + {QZSettings::proform_treadmill_se, QZSettings::default_proform_treadmill_se}, + {QZSettings::proformtreadmillip, QZSettings::default_proformtreadmillip}, + {QZSettings::kingsmith_encrypt_v3, QZSettings::default_kingsmith_encrypt_v3}, + {QZSettings::tdf_10_ip, QZSettings::default_tdf_10_ip}, + {QZSettings::fakedevice_treadmill, QZSettings::default_fakedevice_treadmill}, + {QZSettings::video_playback_window_s, QZSettings::default_video_playback_window_s}, + {QZSettings::horizon_treadmill_profile_user1, QZSettings::default_horizon_treadmill_profile_user1}, + {QZSettings::horizon_treadmill_profile_user2, QZSettings::default_horizon_treadmill_profile_user2}, + {QZSettings::horizon_treadmill_profile_user3, QZSettings::default_horizon_treadmill_profile_user3}, + {QZSettings::horizon_treadmill_profile_user4, QZSettings::default_horizon_treadmill_profile_user4}, + {QZSettings::horizon_treadmill_profile_user5, QZSettings::default_horizon_treadmill_profile_user5}, + {QZSettings::nordictrack_gx_2_7, QZSettings::default_nordictrack_gx_2_7}, + {QZSettings::rolling_resistance, QZSettings::default_rolling_resistance}, + {QZSettings::wahoo_rgt_dircon, QZSettings::default_wahoo_rgt_dircon}, + {QZSettings::tts_description_enabled, QZSettings::default_tts_description_enabled}}; void QZSettings::qDebugAllSettings(bool showDefaults) { QSettings settings; // make a copy of the settings for sorting - std::vector sorted; - for(uint32_t i=0; i sorted; + for (uint32_t i = 0; i < allSettingsCount; i++) { sorted.push_back(allSettings[i]); } // sort the settings alphabetically - struct { bool operator()(QVariant * a, QVariant * b) { return a[0].toString() < b[0].toString(); }} comparer; + struct { + bool operator()(QVariant *a, QVariant *b) { return a[0].toString() < b[0].toString(); } + } comparer; std::sort(sorted.begin(), sorted.end(), comparer); - for(uint32_t i=0; i Date: Mon, 17 Oct 2022 16:54:42 +0200 Subject: [PATCH 122/255] version 2.11.74 for android --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 7f03fec5f..ef1527896 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index 31402ae6e..2ad42ddb4 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.73" + text: "version 2.11.74" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index 369e957eb..aa5b5cd08 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.73 +VERSION = 2.11.74 From a87062e4bc179aa8f6ea3a48ad62e3503840503f Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 17 Oct 2022 23:19:31 +0200 Subject: [PATCH 123/255] gpx without timestamp fixed --- src/trainprogram.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index a4f12cd41..b5af38089 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -35,9 +35,13 @@ trainprogram::trainprogram(const QList &rows, bluetooth *b, QString *d } */ - // speed filter only to GPX workouts - if (rows.length() && !isnan(rows.at(0).latitude) && !isnan(rows.at(0).longitude && !treadmill_force_speed)) + // speed filter only to GPX workouts with timestamp + + if (rows.length() && !isnan(rows.at(0).latitude) && !isnan(rows.at(0).longitude) && + QTime(0, 0, 0).secsTo(rows.at(0).gpxElapsed) != 0 && !treadmill_force_speed) { applySpeedFilter(); + } + connect(&timer, SIGNAL(timeout()), this, SLOT(scheduler())); timer.setInterval(1s); From 4db86b7fc4d55f6b6a4cb755e989d22418422832 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 18 Oct 2022 08:03:27 +0200 Subject: [PATCH 124/255] version 2.11.75 --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index ef1527896..02b1cefa9 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index 2ad42ddb4..982731853 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.74" + text: "version 2.11.75" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index aa5b5cd08..20383cdb2 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.74 +VERSION = 2.11.75 From fa8707369d2369c538ef1a7d116418895bc37b56 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 18 Oct 2022 14:33:48 +0200 Subject: [PATCH 125/255] Differences in the GPX starting point #988 --- .../qdomyoszwift.xcodeproj/project.pbxproj | 12 +- src/android/AndroidManifest.xml | 2 +- src/gpx.cpp | 26 +++-- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- src/trainprogram.cpp | 110 ++---------------- 6 files changed, 32 insertions(+), 122 deletions(-) diff --git a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj index 1b625ee79..37529e4e6 100644 --- a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj +++ b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj @@ -3492,7 +3492,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.75; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = ( @@ -3660,7 +3660,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.75; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; @@ -3864,7 +3864,7 @@ CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.75; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -3956,7 +3956,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.75; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; @@ -4043,7 +4043,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.75; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; ENABLE_PREVIEWS = YES; @@ -4153,7 +4153,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.75; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 02b1cefa9..0c46b77e6 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/gpx.cpp b/src/gpx.cpp index 42aa7113f..222a83ea8 100644 --- a/src/gpx.cpp +++ b/src/gpx.cpp @@ -66,16 +66,17 @@ QList gpx::open(const QString &gpx) { continue; } - pP = this->points[i]; - gpx_altitude_point_for_treadmill g; + g.latitude = pP.p.latitude(); + g.longitude = pP.p.longitude(); + g.elevation = pP.p.altitude(); + + pP = this->points[i]; + g.seconds = this->points.constFirst().time.secsTo(pP.time); g.distance = distance / 1000.0; g.speed = (distance / 1000.0) * (3600 / dT); - g.inclination = (elevation / distance) * 100; - g.elevation = this->points.at(i).p.altitude(); - g.latitude = pP.p.latitude(); - g.longitude = pP.p.longitude(); + g.inclination = (elevation / distance) * 100; inclinationList.append(g); } } @@ -99,15 +100,16 @@ QList gpx::open(const QString &gpx) { continue; } - pP = this->points[i]; - gpx_altitude_point_for_treadmill g; - g.distance = distance / 1000.0; - totDistance += g.distance; - g.inclination = (elevation / distance) * 100; - g.elevation = this->points.at(i).p.altitude(); g.latitude = pP.p.latitude(); g.longitude = pP.p.longitude(); + g.elevation = pP.p.altitude(); + + pP = this->points[i]; + + g.distance = distance / 1000.0; + totDistance += g.distance; + g.inclination = (elevation / distance) * 100; g.seconds = this->points.constFirst().time.secsTo(pP.time); /*qDebug() << qSetRealNumberPrecision(10) << i << g.distance << g.inclination << g.elevation << g.latitude << g.longitude << totDistance << pP.time;*/ diff --git a/src/main.qml b/src/main.qml index 982731853..44e4e5735 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.75" + text: "version 2.11.76" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index 20383cdb2..d49d01cd8 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.75 +VERSION = 2.11.76 diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index b5af38089..41a7775fe 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -286,98 +286,6 @@ double trainprogram::TimeRateFromGPX(double gpxsecs, double videosecs, double cu lastGpxRateSet = rate; } return rate; - - /* - - bool loopFinished = false; - double gpxdistance = 0.0; - double videodistance = 0.0; - double gpxframedistance = 0.0; - double videoframedistance = 0.0; - int c = 0; - int framestartsecs = -1; - int frameendsecs = 0; - double lastsec = 0.0; - - // Identify last needed Time - if (videosecs > gpxsecs) { - lastsec = videosecs; - } - else { - lastsec = gpxsecs; - } - // Add the Timeframe to last needed Time - lastsec += ((double)timeFrame); - // Loop through gpx Rows to collect needed Data - while (!loopFinished) { - double cursecs = ((double)QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed)); - // Row is greater then needed Data, jump out - if (cursecs > lastsec) { - loopFinished = true; - } - // Collect Distance Data for elapsed Time and Timeframe in the future - else { - if (cursecs <= gpxsecs) gpxdistance += (rows.at(c).distance); - if (cursecs <= videosecs) videodistance += (rows.at(c).distance); - if ((cursecs > gpxsecs) && (cursecs <= (gpxsecs + ((double)timeFrame)))) { - gpxframedistance += (rows.at(c).distance); - // Get the exact Start and End Times of Frame for correctly calculating average Speed - if (framestartsecs == -1) framestartsecs = QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed); - frameendsecs = QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed); - } - if ((cursecs > videosecs) && (cursecs <= (videosecs + ((double)timeFrame)))) { - videoframedistance += (rows.at(c).distance); - } - } - c++; - // End of Rows reached - if (c >= rows.length()) loopFinished = true; - } - // If no videoframeend found something is totally wrong. Return 1 - if (frameendsecs == 0) { - qDebug() << qSetRealNumberPrecision(10)<< "TimeRateFromGPX no Videoframe End" - << gpxsecs - << videosecs - << timeFrame - << currentspeed - << gpxdistance - << gpxframedistance - << videodistance - << videoframedistance - << framestartsecs - << frameendsecs ; - - return 1.0; - } - // Calculate the average Speed of the gpx Frame - double avgVideoSpeed = (gpxframedistance / (((double)(frameendsecs-framestartsecs+1)) / 3600.0)); - // Calculate the Videospeed to Playerspeed Rate - double speedRate = (currentspeed / avgVideoSpeed); - // Calculate what the played gpx Distance will be assuming player speed doesn't change - double playedgpxdistance = gpxframedistance * speedRate; - // add the current video/player difference to the playedgpxdistance - playedgpxdistance = playedgpxdistance + gpxdistance - videodistance; - // Calculate rate beween Videoframedistance and played distance - double rate = (playedgpxdistance / videoframedistance); - - qDebug() << qSetRealNumberPrecision(10)<< "TimeRateFromGPX" - << gpxsecs - << videosecs - << (gpxsecs-videosecs) - << fullRate - << timeFrame - << currentspeed - << avgVideoSpeed - << gpxdistance - << gpxframedistance - << videodistance - << videoframedistance - << framestartsecs - << frameendsecs - << playedgpxdistance - << rate; - return rate; - */ } double trainprogram::avgInclinationNext100Meters() { @@ -540,9 +448,9 @@ void trainprogram::scheduler() { if (!isnan(rows.at(0).latitude) || !isnan(rows.at(0).longitude) || !isnan(rows.at(0).altitude)) { qDebug() << qSetRealNumberPrecision(10) - << QStringLiteral("trainprogram change GEO position") + QString::number(rows.at(0).latitude) + - " " + QString::number(rows.at(0).longitude) + " " + QString::number(rows.at(0).altitude) + - " " + QString::number(rows.at(0).azimuth); + << QStringLiteral("trainprogram change GEO position") << rows.at(0).latitude + << rows.at(0).longitude << rows.at(0).altitude + << rows.at(0).azimuth; QGeoCoordinate p; p.setAltitude(rows.at(0).altitude); p.setLatitude(rows.at(0).latitude); @@ -672,12 +580,12 @@ void trainprogram::scheduler() { if (!isnan(rows.at(currentStep).latitude) || !isnan(rows.at(currentStep).longitude) || !isnan(rows.at(currentStep).altitude)) { qDebug() << qSetRealNumberPrecision(10) - << QStringLiteral("trainprogram change GEO position") + - QString::number(rows.at(currentStep).latitude) + " " + - QString::number(rows.at(currentStep).longitude) + " " + - QString::number(rows.at(currentStep).altitude) + " " + - QString::number(rows.at(currentStep).distance) + " " + - QString::number(rows.at(currentStep).azimuth); + << QStringLiteral("trainprogram change GEO position") << + rows.at(currentStep).latitude << + rows.at(currentStep).longitude << + rows.at(currentStep).altitude << + rows.at(currentStep).distance << + rows.at(currentStep).azimuth; QGeoCoordinate p; p.setLatitude(rows.at(currentStep).latitude); From da8e8a0f0985d9e18efef270ba67feb663ceb8e0 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 18 Oct 2022 21:39:11 +0200 Subject: [PATCH 126/255] Revert "Differences in the GPX starting point #988" This reverts commit 2b19896498ee93780c1288af1b8a24ccd9ab8753. --- .../qdomyoszwift.xcodeproj/project.pbxproj | 12 +- src/android/AndroidManifest.xml | 2 +- src/gpx.cpp | 26 ++--- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- src/trainprogram.cpp | 110 ++++++++++++++++-- 6 files changed, 122 insertions(+), 32 deletions(-) diff --git a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj index 37529e4e6..1b625ee79 100644 --- a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj +++ b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj @@ -3492,7 +3492,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.75; + CURRENT_PROJECT_VERSION = 2.11.69; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = ( @@ -3660,7 +3660,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.75; + CURRENT_PROJECT_VERSION = 2.11.69; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; @@ -3864,7 +3864,7 @@ CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.75; + CURRENT_PROJECT_VERSION = 2.11.69; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -3956,7 +3956,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.75; + CURRENT_PROJECT_VERSION = 2.11.69; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; @@ -4043,7 +4043,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.75; + CURRENT_PROJECT_VERSION = 2.11.69; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; ENABLE_PREVIEWS = YES; @@ -4153,7 +4153,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.75; + CURRENT_PROJECT_VERSION = 2.11.69; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 0c46b77e6..02b1cefa9 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/gpx.cpp b/src/gpx.cpp index 222a83ea8..42aa7113f 100644 --- a/src/gpx.cpp +++ b/src/gpx.cpp @@ -66,17 +66,16 @@ QList gpx::open(const QString &gpx) { continue; } - gpx_altitude_point_for_treadmill g; - g.latitude = pP.p.latitude(); - g.longitude = pP.p.longitude(); - g.elevation = pP.p.altitude(); - pP = this->points[i]; - + + gpx_altitude_point_for_treadmill g; g.seconds = this->points.constFirst().time.secsTo(pP.time); g.distance = distance / 1000.0; g.speed = (distance / 1000.0) * (3600 / dT); - g.inclination = (elevation / distance) * 100; + g.inclination = (elevation / distance) * 100; + g.elevation = this->points.at(i).p.altitude(); + g.latitude = pP.p.latitude(); + g.longitude = pP.p.longitude(); inclinationList.append(g); } } @@ -100,16 +99,15 @@ QList gpx::open(const QString &gpx) { continue; } - gpx_altitude_point_for_treadmill g; - g.latitude = pP.p.latitude(); - g.longitude = pP.p.longitude(); - g.elevation = pP.p.altitude(); - pP = this->points[i]; - + + gpx_altitude_point_for_treadmill g; g.distance = distance / 1000.0; totDistance += g.distance; - g.inclination = (elevation / distance) * 100; + g.inclination = (elevation / distance) * 100; + g.elevation = this->points.at(i).p.altitude(); + g.latitude = pP.p.latitude(); + g.longitude = pP.p.longitude(); g.seconds = this->points.constFirst().time.secsTo(pP.time); /*qDebug() << qSetRealNumberPrecision(10) << i << g.distance << g.inclination << g.elevation << g.latitude << g.longitude << totDistance << pP.time;*/ diff --git a/src/main.qml b/src/main.qml index 44e4e5735..982731853 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.76" + text: "version 2.11.75" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index d49d01cd8..20383cdb2 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.76 +VERSION = 2.11.75 diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index 41a7775fe..b5af38089 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -286,6 +286,98 @@ double trainprogram::TimeRateFromGPX(double gpxsecs, double videosecs, double cu lastGpxRateSet = rate; } return rate; + + /* + + bool loopFinished = false; + double gpxdistance = 0.0; + double videodistance = 0.0; + double gpxframedistance = 0.0; + double videoframedistance = 0.0; + int c = 0; + int framestartsecs = -1; + int frameendsecs = 0; + double lastsec = 0.0; + + // Identify last needed Time + if (videosecs > gpxsecs) { + lastsec = videosecs; + } + else { + lastsec = gpxsecs; + } + // Add the Timeframe to last needed Time + lastsec += ((double)timeFrame); + // Loop through gpx Rows to collect needed Data + while (!loopFinished) { + double cursecs = ((double)QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed)); + // Row is greater then needed Data, jump out + if (cursecs > lastsec) { + loopFinished = true; + } + // Collect Distance Data for elapsed Time and Timeframe in the future + else { + if (cursecs <= gpxsecs) gpxdistance += (rows.at(c).distance); + if (cursecs <= videosecs) videodistance += (rows.at(c).distance); + if ((cursecs > gpxsecs) && (cursecs <= (gpxsecs + ((double)timeFrame)))) { + gpxframedistance += (rows.at(c).distance); + // Get the exact Start and End Times of Frame for correctly calculating average Speed + if (framestartsecs == -1) framestartsecs = QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed); + frameendsecs = QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed); + } + if ((cursecs > videosecs) && (cursecs <= (videosecs + ((double)timeFrame)))) { + videoframedistance += (rows.at(c).distance); + } + } + c++; + // End of Rows reached + if (c >= rows.length()) loopFinished = true; + } + // If no videoframeend found something is totally wrong. Return 1 + if (frameendsecs == 0) { + qDebug() << qSetRealNumberPrecision(10)<< "TimeRateFromGPX no Videoframe End" + << gpxsecs + << videosecs + << timeFrame + << currentspeed + << gpxdistance + << gpxframedistance + << videodistance + << videoframedistance + << framestartsecs + << frameendsecs ; + + return 1.0; + } + // Calculate the average Speed of the gpx Frame + double avgVideoSpeed = (gpxframedistance / (((double)(frameendsecs-framestartsecs+1)) / 3600.0)); + // Calculate the Videospeed to Playerspeed Rate + double speedRate = (currentspeed / avgVideoSpeed); + // Calculate what the played gpx Distance will be assuming player speed doesn't change + double playedgpxdistance = gpxframedistance * speedRate; + // add the current video/player difference to the playedgpxdistance + playedgpxdistance = playedgpxdistance + gpxdistance - videodistance; + // Calculate rate beween Videoframedistance and played distance + double rate = (playedgpxdistance / videoframedistance); + + qDebug() << qSetRealNumberPrecision(10)<< "TimeRateFromGPX" + << gpxsecs + << videosecs + << (gpxsecs-videosecs) + << fullRate + << timeFrame + << currentspeed + << avgVideoSpeed + << gpxdistance + << gpxframedistance + << videodistance + << videoframedistance + << framestartsecs + << frameendsecs + << playedgpxdistance + << rate; + return rate; + */ } double trainprogram::avgInclinationNext100Meters() { @@ -448,9 +540,9 @@ void trainprogram::scheduler() { if (!isnan(rows.at(0).latitude) || !isnan(rows.at(0).longitude) || !isnan(rows.at(0).altitude)) { qDebug() << qSetRealNumberPrecision(10) - << QStringLiteral("trainprogram change GEO position") << rows.at(0).latitude - << rows.at(0).longitude << rows.at(0).altitude - << rows.at(0).azimuth; + << QStringLiteral("trainprogram change GEO position") + QString::number(rows.at(0).latitude) + + " " + QString::number(rows.at(0).longitude) + " " + QString::number(rows.at(0).altitude) + + " " + QString::number(rows.at(0).azimuth); QGeoCoordinate p; p.setAltitude(rows.at(0).altitude); p.setLatitude(rows.at(0).latitude); @@ -580,12 +672,12 @@ void trainprogram::scheduler() { if (!isnan(rows.at(currentStep).latitude) || !isnan(rows.at(currentStep).longitude) || !isnan(rows.at(currentStep).altitude)) { qDebug() << qSetRealNumberPrecision(10) - << QStringLiteral("trainprogram change GEO position") << - rows.at(currentStep).latitude << - rows.at(currentStep).longitude << - rows.at(currentStep).altitude << - rows.at(currentStep).distance << - rows.at(currentStep).azimuth; + << QStringLiteral("trainprogram change GEO position") + + QString::number(rows.at(currentStep).latitude) + " " + + QString::number(rows.at(currentStep).longitude) + " " + + QString::number(rows.at(currentStep).altitude) + " " + + QString::number(rows.at(currentStep).distance) + " " + + QString::number(rows.at(currentStep).azimuth); QGeoCoordinate p; p.setLatitude(rows.at(currentStep).latitude); From 21fadc3184f98fa4c33f387ea63059cae6fa8eeb Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 18 Oct 2022 21:40:08 +0200 Subject: [PATCH 127/255] keeping useful modification --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- src/trainprogram.cpp | 110 +++----------------------------- 4 files changed, 12 insertions(+), 104 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 02b1cefa9..0c46b77e6 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index 982731853..44e4e5735 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.75" + text: "version 2.11.76" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index 20383cdb2..d49d01cd8 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.75 +VERSION = 2.11.76 diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index b5af38089..41a7775fe 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -286,98 +286,6 @@ double trainprogram::TimeRateFromGPX(double gpxsecs, double videosecs, double cu lastGpxRateSet = rate; } return rate; - - /* - - bool loopFinished = false; - double gpxdistance = 0.0; - double videodistance = 0.0; - double gpxframedistance = 0.0; - double videoframedistance = 0.0; - int c = 0; - int framestartsecs = -1; - int frameendsecs = 0; - double lastsec = 0.0; - - // Identify last needed Time - if (videosecs > gpxsecs) { - lastsec = videosecs; - } - else { - lastsec = gpxsecs; - } - // Add the Timeframe to last needed Time - lastsec += ((double)timeFrame); - // Loop through gpx Rows to collect needed Data - while (!loopFinished) { - double cursecs = ((double)QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed)); - // Row is greater then needed Data, jump out - if (cursecs > lastsec) { - loopFinished = true; - } - // Collect Distance Data for elapsed Time and Timeframe in the future - else { - if (cursecs <= gpxsecs) gpxdistance += (rows.at(c).distance); - if (cursecs <= videosecs) videodistance += (rows.at(c).distance); - if ((cursecs > gpxsecs) && (cursecs <= (gpxsecs + ((double)timeFrame)))) { - gpxframedistance += (rows.at(c).distance); - // Get the exact Start and End Times of Frame for correctly calculating average Speed - if (framestartsecs == -1) framestartsecs = QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed); - frameendsecs = QTime(0, 0, 0).secsTo(rows.at(c).gpxElapsed); - } - if ((cursecs > videosecs) && (cursecs <= (videosecs + ((double)timeFrame)))) { - videoframedistance += (rows.at(c).distance); - } - } - c++; - // End of Rows reached - if (c >= rows.length()) loopFinished = true; - } - // If no videoframeend found something is totally wrong. Return 1 - if (frameendsecs == 0) { - qDebug() << qSetRealNumberPrecision(10)<< "TimeRateFromGPX no Videoframe End" - << gpxsecs - << videosecs - << timeFrame - << currentspeed - << gpxdistance - << gpxframedistance - << videodistance - << videoframedistance - << framestartsecs - << frameendsecs ; - - return 1.0; - } - // Calculate the average Speed of the gpx Frame - double avgVideoSpeed = (gpxframedistance / (((double)(frameendsecs-framestartsecs+1)) / 3600.0)); - // Calculate the Videospeed to Playerspeed Rate - double speedRate = (currentspeed / avgVideoSpeed); - // Calculate what the played gpx Distance will be assuming player speed doesn't change - double playedgpxdistance = gpxframedistance * speedRate; - // add the current video/player difference to the playedgpxdistance - playedgpxdistance = playedgpxdistance + gpxdistance - videodistance; - // Calculate rate beween Videoframedistance and played distance - double rate = (playedgpxdistance / videoframedistance); - - qDebug() << qSetRealNumberPrecision(10)<< "TimeRateFromGPX" - << gpxsecs - << videosecs - << (gpxsecs-videosecs) - << fullRate - << timeFrame - << currentspeed - << avgVideoSpeed - << gpxdistance - << gpxframedistance - << videodistance - << videoframedistance - << framestartsecs - << frameendsecs - << playedgpxdistance - << rate; - return rate; - */ } double trainprogram::avgInclinationNext100Meters() { @@ -540,9 +448,9 @@ void trainprogram::scheduler() { if (!isnan(rows.at(0).latitude) || !isnan(rows.at(0).longitude) || !isnan(rows.at(0).altitude)) { qDebug() << qSetRealNumberPrecision(10) - << QStringLiteral("trainprogram change GEO position") + QString::number(rows.at(0).latitude) + - " " + QString::number(rows.at(0).longitude) + " " + QString::number(rows.at(0).altitude) + - " " + QString::number(rows.at(0).azimuth); + << QStringLiteral("trainprogram change GEO position") << rows.at(0).latitude + << rows.at(0).longitude << rows.at(0).altitude + << rows.at(0).azimuth; QGeoCoordinate p; p.setAltitude(rows.at(0).altitude); p.setLatitude(rows.at(0).latitude); @@ -672,12 +580,12 @@ void trainprogram::scheduler() { if (!isnan(rows.at(currentStep).latitude) || !isnan(rows.at(currentStep).longitude) || !isnan(rows.at(currentStep).altitude)) { qDebug() << qSetRealNumberPrecision(10) - << QStringLiteral("trainprogram change GEO position") + - QString::number(rows.at(currentStep).latitude) + " " + - QString::number(rows.at(currentStep).longitude) + " " + - QString::number(rows.at(currentStep).altitude) + " " + - QString::number(rows.at(currentStep).distance) + " " + - QString::number(rows.at(currentStep).azimuth); + << QStringLiteral("trainprogram change GEO position") << + rows.at(currentStep).latitude << + rows.at(currentStep).longitude << + rows.at(currentStep).altitude << + rows.at(currentStep).distance << + rows.at(currentStep).azimuth; QGeoCoordinate p; p.setLatitude(rows.at(currentStep).latitude); From 487eda2bdeec0ee93c056eda39cfa99a07b5a37a Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 19 Oct 2022 10:24:42 +0200 Subject: [PATCH 128/255] Differences in the GPX starting point #988 --- src/android/AndroidManifest.xml | 2 +- src/gpx.cpp | 25 +++++++++- src/homeform.cpp | 13 +++--- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- src/trainprogram.cpp | 81 +++++++++++++++++++-------------- src/trainprogram.h | 5 +- 7 files changed, 84 insertions(+), 46 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 0c46b77e6..40254d328 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/gpx.cpp b/src/gpx.cpp index 42aa7113f..46a624831 100644 --- a/src/gpx.cpp +++ b/src/gpx.cpp @@ -56,13 +56,24 @@ QList gpx::open(const QString &gpx) { gpx_point pP = this->points.constFirst(); if (treadmill_force_speed) { + + // starting point + gpx_altitude_point_for_treadmill g; + g.distance = 0; + g.inclination = 0; + g.elevation = pP.p.altitude(); + g.latitude = pP.p.latitude(); + g.longitude = pP.p.longitude(); + g.seconds = 0; + inclinationList.append(g); + for (int32_t i = 1; i < this->points.count(); i++) { qint64 dT = qAbs(pP.time.secsTo(this->points.at(i).time)); double distance = this->points.at(i).p.distanceTo(pP.p); double elevation = this->points.at(i).p.altitude() - pP.p.altitude(); - if (distance == 0) { + if (distance == 0 || dT == 0) { continue; } @@ -91,6 +102,18 @@ QList gpx::open(const QString &gpx) { this->points.last().time = this->points.at(this->points.count() - 2).time; } + // starting point + gpx_altitude_point_for_treadmill g; + g.distance = 0; + g.inclination = 0; + g.elevation = pP.p.altitude(); + g.latitude = pP.p.latitude(); + g.longitude = pP.p.longitude(); + g.seconds = 0; + /*qDebug() << qSetRealNumberPrecision(10) << i << g.distance << g.inclination << g.elevation << g.latitude + << g.longitude << totDistance << pP.time;*/ + inclinationList.append(g); + for (int32_t i = 1; i < this->points.count(); i++) { double distance = this->points.at(i).p.distanceTo(pP.p); double elevation = this->points.at(i).p.altitude() - pP.p.altitude(); diff --git a/src/homeform.cpp b/src/homeform.cpp index f0f3818f0..945d90904 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -3621,7 +3621,7 @@ void homeform::gpx_open_clicked(const QUrl &fileName) { list.reserve(g_list.size() + 1); for (const auto &p : g_list) { trainrow r; - if (p.speed > 0) { + if (p.speed > 0 && i > 0) { QGeoCoordinate p1(last.latitude, last.longitude); QGeoCoordinate p2(p.latitude, p.longitude, p.elevation); r.azimuth = p1.azimuthTo(p2); @@ -3631,10 +3631,10 @@ void homeform::gpx_open_clicked(const QUrl &fileName) { r.duration = r.duration.addSecs(p.seconds); r.forcespeed = true; - r.altitude = p.elevation; + r.altitude = last.elevation; r.inclination = p.inclination; - r.latitude = p.latitude; - r.longitude = p.longitude; + r.latitude = last.latitude; + r.longitude = last.longitude; r.gpxElapsed = QTime(0, 0, 0).addSecs(p.seconds); list.append(r); @@ -3645,7 +3645,7 @@ void homeform::gpx_open_clicked(const QUrl &fileName) { QGeoCoordinate p2(p.latitude, p.longitude, p.elevation); r.azimuth = p1.azimuthTo(p2); r.distance = p.distance; - r.altitude = p.elevation; + r.altitude = last.elevation; r.inclination = p.inclination; r.latitude = last.latitude; r.longitude = last.longitude; @@ -3659,8 +3659,6 @@ void homeform::gpx_open_clicked(const QUrl &fileName) { i++; } setMapsVisible(true); - trainProgram = new trainprogram(list, bluetoothManager); - if (g.getVideoURL().isEmpty() == false) { movieFileName = QUrl(g.getVideoURL()); emit videoPathChanged(movieFileName); @@ -3670,6 +3668,7 @@ void homeform::gpx_open_clicked(const QUrl &fileName) { emit videoPathChanged(movieFileName); setVideoIconVisible(true); } + trainProgram = new trainprogram(list, bluetoothManager, nullptr, nullptr, videoIconVisible()); } trainProgramSignals(); diff --git a/src/main.qml b/src/main.qml index 44e4e5735..fc34b7214 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.76" + text: "version 2.11.77" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index d49d01cd8..e19e599a0 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.76 +VERSION = 2.11.77 diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index 41a7775fe..a46162b1a 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -7,9 +7,11 @@ using namespace std::chrono_literals; -trainprogram::trainprogram(const QList &rows, bluetooth *b, QString *description, QString *tags) { +trainprogram::trainprogram(const QList &rows, bluetooth *b, QString *description, QString *tags, + bool videoAvailable) { QSettings settings; - bool treadmill_force_speed = settings.value(QZSettings::treadmill_force_speed, QZSettings::default_treadmill_force_speed).toBool(); + bool treadmill_force_speed = + settings.value(QZSettings::treadmill_force_speed, QZSettings::default_treadmill_force_speed).toBool(); this->bluetoothManager = b; this->rows = rows; this->loadedRows = rows; @@ -36,12 +38,11 @@ trainprogram::trainprogram(const QList &rows, bluetooth *b, QString *d */ // speed filter only to GPX workouts with timestamp - + if (rows.length() && !isnan(rows.at(0).latitude) && !isnan(rows.at(0).longitude) && - QTime(0, 0, 0).secsTo(rows.at(0).gpxElapsed) != 0 && !treadmill_force_speed) { + QTime(0, 0, 0).secsTo(rows.at(0).gpxElapsed) != 0 && !treadmill_force_speed && videoAvailable) { applySpeedFilter(); } - connect(&timer, SIGNAL(timeout()), this, SLOT(scheduler())); timer.setInterval(1s); @@ -88,7 +89,8 @@ QString trainrow::toString() const { } void trainprogram::applySpeedFilter() { - if (rows.length()==0) return; + if (rows.length() == 0) + return; int r = 0; double weight[] = {0.15, 0.15, 0.1, 0.05, 0.05, 0.1, 0.1, 0.15, 0.15}; QList newdistance; @@ -97,19 +99,34 @@ void trainprogram::applySpeedFilter() { while (r < rows.length()) { int ws = (r - 4); int we = (r + 4); - if (ws < 0) ws = 0; - if (we >= rows.length()) we = (rows.length()-1); + + // filtering starting point + if (ws < 1) + ws = 1; + + if (we >= rows.length()) + we = (rows.length() - 1); int wc = 0; double wma = 0; - int rowduration=0; - for (wc = 0; wc<=(we-ws); wc++) { - int currow = (ws+wc); - if (currow <= 0) rowduration=QTime(0, 0, 0).secsTo(rows.at(currow).gpxElapsed); - else rowduration = ((QTime(0, 0, 0).secsTo(rows.at(currow).gpxElapsed)) - (QTime(0, 0, 0).secsTo(rows.at(currow-1).gpxElapsed))); + int rowduration = 0; + for (wc = 0; wc <= (we - ws); wc++) { + int currow = (ws + wc); + + // filtering starting point + if (currow <= 1) + rowduration = QTime(0, 0, 0).secsTo(rows.at(currow).gpxElapsed); + else + rowduration = ((QTime(0, 0, 0).secsTo(rows.at(currow).gpxElapsed)) - + (QTime(0, 0, 0).secsTo(rows.at(currow - 1).gpxElapsed))); wma += ((rows.at(currow).distance) / ((double)(rowduration)) * weight[wc]); } - if (r <= 0) rowduration=QTime(0, 0, 0).secsTo(rows.at(r).gpxElapsed); - else rowduration = ((QTime(0, 0, 0).secsTo(rows.at(r).gpxElapsed)) - (QTime(0, 0, 0).secsTo(rows.at(r-1).gpxElapsed))); + + // filtering starting point + if (r <= 1) + rowduration = QTime(0, 0, 0).secsTo(rows.at(r).gpxElapsed); + else + rowduration = + ((QTime(0, 0, 0).secsTo(rows.at(r).gpxElapsed)) - (QTime(0, 0, 0).secsTo(rows.at(r - 1).gpxElapsed))); /* it takes a lot of time during the opening of the file*/ /* @@ -129,7 +146,7 @@ void trainprogram::applySpeedFilter() { r++; } for (r = 0; r < rows.length(); r++) { - rows[r].distance=newdistance.at(r); + rows[r].distance = newdistance.at(r); } } @@ -256,7 +273,7 @@ double trainprogram::TimeRateFromGPX(double gpxsecs, double videosecs, double cu if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { double avgSpeedForLimit = avgSpeedFromGpxStep(currentStep + 1, 5); if (avgSpeedForLimit > 0.0) { - bike * dev = (bike *)bluetoothManager->device(); + bike *dev = (bike *)bluetoothManager->device(); dev->setSpeedLimit(avgSpeedForLimit * 1.7); } } @@ -447,10 +464,8 @@ void trainprogram::scheduler() { } if (!isnan(rows.at(0).latitude) || !isnan(rows.at(0).longitude) || !isnan(rows.at(0).altitude)) { - qDebug() << qSetRealNumberPrecision(10) - << QStringLiteral("trainprogram change GEO position") << rows.at(0).latitude - << rows.at(0).longitude << rows.at(0).altitude - << rows.at(0).azimuth; + qDebug() << qSetRealNumberPrecision(10) << QStringLiteral("trainprogram change GEO position") + << rows.at(0).latitude << rows.at(0).longitude << rows.at(0).altitude << rows.at(0).azimuth; QGeoCoordinate p; p.setAltitude(rows.at(0).altitude); p.setLatitude(rows.at(0).latitude); @@ -579,13 +594,10 @@ void trainprogram::scheduler() { if (!isnan(rows.at(currentStep).latitude) || !isnan(rows.at(currentStep).longitude) || !isnan(rows.at(currentStep).altitude)) { - qDebug() << qSetRealNumberPrecision(10) - << QStringLiteral("trainprogram change GEO position") << - rows.at(currentStep).latitude << - rows.at(currentStep).longitude << - rows.at(currentStep).altitude << - rows.at(currentStep).distance << - rows.at(currentStep).azimuth; + qDebug() << qSetRealNumberPrecision(10) << QStringLiteral("trainprogram change GEO position") + << rows.at(currentStep).latitude << rows.at(currentStep).longitude + << rows.at(currentStep).altitude << rows.at(currentStep).distance + << rows.at(currentStep).azimuth; QGeoCoordinate p; p.setLatitude(rows.at(currentStep).latitude); @@ -664,16 +676,19 @@ void trainprogram::scheduler() { } lastStepTimestampChanged = currentStep; } - if ( (currentStep > 1) && (distanceRow != 0.0) ) { - steptime = ((QTime(0, 0, 0).secsTo(rows.at(currentStep).gpxElapsed)) - (QTime(0, 0, 0).secsTo(rows.at(currentStep-1).gpxElapsed))); - if (steptime == 0) steptime=1; + if ((currentStep > 1) && (distanceRow != 0.0)) { + steptime = ((QTime(0, 0, 0).secsTo(rows.at(currentStep).gpxElapsed)) - + (QTime(0, 0, 0).secsTo(rows.at(currentStep - 1).gpxElapsed))); + if (steptime == 0) + steptime = 1; distanceRow = (distanceRow / ((double)(steptime))); ratioDistance = ((currentStepDistance - lastCurrentStepDistance) / distanceRow); - lastCurrentStepTime = lastCurrentStepTime.addMSecs(ratioDistance*1000.0); + lastCurrentStepTime = lastCurrentStepTime.addMSecs(ratioDistance * 1000.0); } lastCurrentStepDistance = currentStepDistance; qDebug() << qSetRealNumberPrecision(10) << QStringLiteral("changingTimestamp") << currentStep - << distanceRow << currentStepDistance << lastCurrentStepDistance << ratioDistance << rows.at(currentStep).gpxElapsed << lastCurrentStepTime << ticks; + << distanceRow << currentStepDistance << lastCurrentStepDistance << ratioDistance + << rows.at(currentStep).gpxElapsed << lastCurrentStepTime << ticks; emit changeTimestamp(lastCurrentStepTime, QTime(0, 0, 0).addSecs(ticks)); } } diff --git a/src/trainprogram.h b/src/trainprogram.h index c2ebb311e..7e31b6be0 100644 --- a/src/trainprogram.h +++ b/src/trainprogram.h @@ -54,7 +54,8 @@ class trainprogram : public QObject { Q_OBJECT public: - trainprogram(const QList &, bluetooth *b, QString *description = nullptr, QString *tags = nullptr); + trainprogram(const QList &, bluetooth *b, QString *description = nullptr, QString *tags = nullptr, + bool videoAvailable = false); void save(const QString &filename); static trainprogram *load(const QString &filename, bluetooth *b); static QList loadXML(const QString &filename); @@ -128,7 +129,7 @@ class trainprogram : public QObject { double lastGpxRateSet = 0.0; double lastGpxSpeedSet = 0.0; int lastStepTimestampChanged = 0; - double lastCurrentStepDistance =0.0; + double lastCurrentStepDistance = 0.0; QTime lastCurrentStepTime = QTime(0, 0, 0); }; From b534fdd9fbe3ff0b294e83ffdde7472d79640611 Mon Sep 17 00:00:00 2001 From: Jaroslaw Watral Date: Thu, 20 Oct 2022 00:01:30 +0200 Subject: [PATCH 129/255] fixed speed value conversion in SpeedChannelController --- src/android/src/SpeedChannelController.java | 27 +++++++++------------ 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/android/src/SpeedChannelController.java b/src/android/src/SpeedChannelController.java index db8896f9b..054bb7aea 100644 --- a/src/android/src/SpeedChannelController.java +++ b/src/android/src/SpeedChannelController.java @@ -42,16 +42,12 @@ public class SpeedChannelController { private static final String TAG = SpeedChannelController.class.getSimpleName(); public static final int SPEED_SENSOR_ID = 0x9e3d4b65; - private static Random randGen = new Random(); - private AntChannel mAntChannel; private ChannelEventCallback mChannelEventCallback = new ChannelEventCallback(); - private boolean mIsOpen; double speed = 0.0; - double cadence = 0.0; public SpeedChannelController(AntChannel antChannel) { mAntChannel = antChannel; @@ -111,7 +107,7 @@ void channelError(RemoteException e) { String logString = "Remote service communication failed."; Log.e(TAG, logString); - } + } void channelError(String error, AntCommandFailedException e) { StringBuilder logString; @@ -174,7 +170,6 @@ public class ChannelEventCallback implements IAntChannelEventHandler { int rev; double remWay; double wheel = 0.1; - long unixTime = 0; @Override public void onChannelDeath() { @@ -207,11 +202,15 @@ public void onReceiveMessage(MessageFromAntType messageType, AntMessageParcel an // Switching on event code to handle the different types of channel events switch (code) { case TX: - if(speed > 0) - { - revCounts++; - unixTime += (long)(1024.0 / (((double)(speed)) / 60.0)); - } + long unixTime = System.currentTimeMillis() / 1000L; + + if (lastTime != 0) { + way = speed * (unixTime - lastTime) / 3.6 + remWay; + rev = (int) (way / wheel + 0.5); + remWay = way - rev * wheel; + revCounts += rev; + } + lastTime = unixTime; ucPageChange += 0x20; ucPageChange &= 0xF0; @@ -228,14 +227,12 @@ public void onReceiveMessage(MessageFromAntType messageType, AntMessageParcel an payload[1] = (byte) (halfunixTime & 0xFF); payload[2] = (byte) ((halfunixTime >> 8) & 0xFF); payload[3] = (byte) ((halfunixTime >> 16) & 0xFF); - } - else if (ucExtMesgType == 2) { + } else if (ucExtMesgType == 2) { payload[0] = (byte) ((byte) 0x02 | (byte) (ucPageChange & (byte) 0x80)); payload[1] = (byte) 0xFF; payload[2] = (byte) ((SPEED_SENSOR_ID >> 16) & 0xFF); payload[3] = (byte) ((SPEED_SENSOR_ID >> 24) & 0xFF); - } - else if (ucExtMesgType == 3) { + } else if (ucExtMesgType == 3) { payload[0] = (byte) ((byte) 0x03 | (byte) (ucPageChange & (byte) 0x80)); payload[1] = (byte) 0x01; payload[2] = (byte) 0x01; From 7fde807e286a52be920a32de53bfa42b709757be Mon Sep 17 00:00:00 2001 From: Jaroslaw Watral Date: Thu, 20 Oct 2022 00:09:54 +0200 Subject: [PATCH 130/255] removed cadence reference usage in ChannelService --- src/android/src/ChannelService.java | 74 ++++++++++++++--------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/src/android/src/ChannelService.java b/src/android/src/ChannelService.java index 7731e6c88..ab1216f11 100644 --- a/src/android/src/ChannelService.java +++ b/src/android/src/ChannelService.java @@ -47,7 +47,7 @@ public class ChannelService extends Service { private AntChannelProvider mAntChannelProvider = null; private boolean mAllowAddChannel = false; - HeartChannelController heartChannelController = null; + HeartChannelController heartChannelController = null; PowerChannelController powerChannelController = null; SpeedChannelController speedChannelController = null; @@ -116,17 +116,14 @@ void setCadence(int cadence) { if (null != powerChannelController) { powerChannelController.cadence = cadence; } - if (null != speedChannelController) { - speedChannelController.cadence = cadence; - } } - int getHeart() { - if (null != heartChannelController) { - return heartChannelController.heart; - } - return 0; - } + int getHeart() { + if (null != heartChannelController) { + return heartChannelController.heart; + } + return 0; + } /** * Closes all channels currently added. @@ -134,28 +131,28 @@ int getHeart() { void clearAllChannels() { closeAllChannels(); } - } + } public void openAllChannels() throws ChannelNotAvailableException { - if(Ant.heartRequest) - heartChannelController = new HeartChannelController(acquireChannel()); + if (Ant.heartRequest) + heartChannelController = new HeartChannelController(acquireChannel()); - if(Ant.speedRequest) { - powerChannelController = new PowerChannelController(acquireChannel()); - speedChannelController = new SpeedChannelController(acquireChannel()); - } + if (Ant.speedRequest) { + powerChannelController = new PowerChannelController(acquireChannel()); + speedChannelController = new SpeedChannelController(acquireChannel()); + } } private void closeAllChannels() { - if(heartChannelController != null) - heartChannelController.close(); - if(powerChannelController != null) - powerChannelController.close(); - if(speedChannelController != null) - speedChannelController.close(); - heartChannelController = null; - powerChannelController = null; - speedChannelController = null; + if (heartChannelController != null) + heartChannelController.close(); + if (powerChannelController != null) + powerChannelController.close(); + if (speedChannelController != null) + speedChannelController.close(); + heartChannelController = null; + powerChannelController = null; + speedChannelController = null; } AntChannel acquireChannel() throws ChannelNotAvailableException { @@ -171,19 +168,18 @@ AntChannel acquireChannel() throws ChannelNotAvailableException { * acquireChannel(context, PredefinedNetwork, * requiredCapabilities, desiredCapabilities). */ - if(Ant.garminKey == false) - mAntChannel = mAntChannelProvider.acquireChannel(this, PredefinedNetwork.ANT_PLUS_1); - else - { - NetworkKey mNK = new NetworkKey(new byte[] { (byte)0xb9, (byte)0xa5, (byte)0x21, (byte)0xfb, - (byte)0xbd, (byte)0x72, (byte)0xc3, (byte)0x45 }); - Log.v(TAG, mNK.toString()); - mAntChannel = mAntChannelProvider.acquireChannelOnPrivateNetwork(this, mNK); - } - } catch (RemoteException e) { - Log.v(TAG, "ACP Remote Ex"); - } catch (UnsupportedFeatureException e) { - Log.v(TAG, "ACP UnsupportedFeature Ex"); + if (Ant.garminKey == false) + mAntChannel = mAntChannelProvider.acquireChannel(this, PredefinedNetwork.ANT_PLUS_1); + else { + NetworkKey mNK = new NetworkKey(new byte[]{(byte) 0xb9, (byte) 0xa5, (byte) 0x21, (byte) 0xfb, + (byte) 0xbd, (byte) 0x72, (byte) 0xc3, (byte) 0x45}); + Log.v(TAG, mNK.toString()); + mAntChannel = mAntChannelProvider.acquireChannelOnPrivateNetwork(this, mNK); + } + } catch (RemoteException e) { + Log.v(TAG, "ACP Remote Ex"); + } catch (UnsupportedFeatureException e) { + Log.v(TAG, "ACP UnsupportedFeature Ex"); } } return mAntChannel; From e5ee4636440c19f886098fa89970982764ce7338 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 20 Oct 2022 08:29:15 +0200 Subject: [PATCH 131/255] helper label added --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- src/settings.qml | 13 +++++++++++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 40254d328..1a69b67af 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index fc34b7214..7ef4824fd 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.77" + text: "version 2.11.78" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index e19e599a0..e7c2da849 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.77 +VERSION = 2.11.78 diff --git a/src/settings.qml b/src/settings.qml index 1dc2b597c..4b667e59b 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -2288,6 +2288,19 @@ import Qt.labs.settings 1.0 //anchors.topMargin: 10 accordionContent: ColumnLayout { spacing: 0 + + Label { + id: antSpeedLabel + text: qsTr("Set 100mm as wheel circumference in settings of ant+ speed sensor") + font.bold: true + font.italic: true + font.pixelSize: 8 + textFormat: Text.PlainText + wrapMode: Text.WordWrap + verticalAlignment: Text.AlignVCenter + color: Material.color(Material.Red) + } + SwitchDelegate { id: antCadenceDelegate text: qsTr("Ant+ Cadence") From c4f10b1a142f0841c3ed805a71b0eeac909a212d Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sat, 22 Oct 2022 13:07:53 +0200 Subject: [PATCH 132/255] Spirit XT385 not able to get working, Gets discovered but can't see Qdomyos in Zwift Discovery. #833 --- src/android/AndroidManifest.xml | 2 +- src/bluetooth.cpp | 1 + src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 1a69b67af..f58f5f8b8 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 0b967ad74..f0a6a24e8 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -1601,6 +1601,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { &bluetooth::connectedAndDiscovered); // connect(spiritTreadmill, SIGNAL(disconnected()), this, SLOT(restart())); connect(spiritTreadmill, &spirittreadmill::debug, this, &bluetooth::debug); + connect(spiritTreadmill, &spirittreadmill::inclinationChanged, this, &bluetooth::inclinationChanged); spiritTreadmill->deviceDiscovered(b); userTemplateManager->start(spiritTreadmill); innerTemplateManager->start(spiritTreadmill); diff --git a/src/main.qml b/src/main.qml index 7ef4824fd..b59c2303f 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.78" + text: "version 2.11.79" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index e7c2da849..2cc2a7d7c 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.78 +VERSION = 2.11.79 From b26955cc7d786db5810c5ec2f05736d7ed1ede2d Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 24 Oct 2022 08:45:43 +0200 Subject: [PATCH 133/255] Spirit XT385 not able to get working, Gets discovered but can't see Qdomyos in Zwift Discovery. #833 --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- src/spirittreadmill.cpp | 35 +++++++++++++++++++++++++++------ src/spirittreadmill.h | 3 +++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index f58f5f8b8..c6edb4d4d 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index b59c2303f..cee798107 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.79" + text: "version 2.11.80" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index 2cc2a7d7c..af9efeb41 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.79 +VERSION = 2.11.80 diff --git a/src/spirittreadmill.cpp b/src/spirittreadmill.cpp index 4a6f76858..770e5299a 100644 --- a/src/spirittreadmill.cpp +++ b/src/spirittreadmill.cpp @@ -222,7 +222,8 @@ void spirittreadmill::characteristicChanged(const QLowEnergyCharacteristic &char Inclination = GetInclinationFromPacket(newValue); double kcal = GetKcalFromPacket(newValue); // double distance = GetDistanceFromPacket(newValue) * - // settings.value(QZSettings::domyos_elliptical_speed_ratio, QZSettings::default_domyos_elliptical_speed_ratio).toDouble(); + // settings.value(QZSettings::domyos_elliptical_speed_ratio, + // QZSettings::default_domyos_elliptical_speed_ratio).toDouble(); #ifdef Q_OS_ANDROID if (settings.value(QZSettings::ant_heart, QZSettings::default_ant_heart).toBool()) @@ -415,13 +416,27 @@ void spirittreadmill::stateChanged(QLowEnergyService::ServiceState state) { &spirittreadmill::descriptorWritten); // ******************************************* virtual treadmill init ************************************* - if (!firstVirtualTreadmill && !virtualTreadMill) { + if (!firstVirtualTreadmill && !virtualTreadMill && !virtualBike) { QSettings settings; - bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_force_bike = + settings.value(QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike) + .toBool(); if (virtual_device_enabled) { - emit debug(QStringLiteral("creating virtual treadmill interface...")); - virtualTreadMill = new virtualtreadmill(this, false); - connect(virtualTreadMill, &virtualtreadmill::debug, this, &spirittreadmill::debug); + if (!virtual_device_force_bike) { + debug("creating virtual treadmill interface..."); + virtualTreadMill = new virtualtreadmill(this, false); + connect(virtualTreadMill, &virtualtreadmill::debug, this, &spirittreadmill::debug); + connect(virtualTreadMill, &virtualtreadmill::changeInclination, this, + &spirittreadmill::changeInclinationRequested); + } else { + debug("creating virtual bike interface..."); + virtualBike = new virtualbike(this); + connect(virtualBike, &virtualbike::changeInclination, this, + &spirittreadmill::changeInclinationRequested); + } + firstVirtualTreadmill = 1; } } firstVirtualTreadmill = 1; @@ -435,6 +450,14 @@ void spirittreadmill::stateChanged(QLowEnergyService::ServiceState state) { } } +void spirittreadmill::changeInclinationRequested(double grade, double percentage) { + if (percentage < 0) + percentage = 0; + if (grade < 0) + grade = 0; + changeInclination(grade, percentage); +} + void spirittreadmill::descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &newValue) { emit debug(QStringLiteral("descriptorWritten ") + descriptor.name() + QStringLiteral(" ") + newValue.toHex(' ')); diff --git a/src/spirittreadmill.h b/src/spirittreadmill.h index bb3754db2..00f190d7a 100644 --- a/src/spirittreadmill.h +++ b/src/spirittreadmill.h @@ -26,6 +26,7 @@ #include #include "treadmill.h" +#include "virtualbike.h" #include "virtualtreadmill.h" class spirittreadmill : public treadmill { @@ -53,6 +54,7 @@ class spirittreadmill : public treadmill { QTimer *refresh; virtualtreadmill *virtualTreadMill = nullptr; + virtualbike *virtualBike = nullptr; uint8_t firstVirtualTreadmill = 0; bool firstCharChanged = true; @@ -87,6 +89,7 @@ class spirittreadmill : public treadmill { void descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &newValue); void stateChanged(QLowEnergyService::ServiceState state); void controllerStateChanged(QLowEnergyController::ControllerState state); + void changeInclinationRequested(double grade, double percentage); void serviceDiscovered(const QBluetoothUuid &gatt); void serviceScanDone(void); From a416ea75c56555f99393d646b9ecb54c673b48a8 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 24 Oct 2022 15:27:18 +0200 Subject: [PATCH 134/255] Preset resistance tiles (#493) --- .gitignore | 1 + src/Home.qml | 20 +- src/homeform.cpp | 614 ++++++++- src/homeform.h | 84 +- src/qml.qrc | 1 + src/qzsettings.cpp | 140 +- src/qzsettings.h | 180 +++ src/settings-tiles.qml | 2734 ++++++++++++++++++++++++++++++++++++++++ src/settings.qml | 1504 +--------------------- 9 files changed, 3810 insertions(+), 1468 deletions(-) create mode 100644 src/settings-tiles.qml diff --git a/.gitignore b/.gitignore index b94dc18ac..be14f1279 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,4 @@ template-examples/train-program-saver/debug.js *build-* !build-qdomyos-zwift-Qt_*_for_iOS-Debug # Needed for Apple Watch src/inner_templates/googlemaps/cesium-key.js +*.autosave diff --git a/src/Home.qml b/src/Home.qml index 48a182a6a..e1b8671a7 100644 --- a/src/Home.qml +++ b/src/Home.qml @@ -16,6 +16,7 @@ HomeForm{ signal peloton_abort_workout; signal plus_clicked(string name) signal minus_clicked(string name) + signal largeButton_clicked(string name) Settings { id: settings @@ -174,6 +175,7 @@ HomeForm{ width: 48 * settings.ui_zoom / 100 height: 48 * settings.ui_zoom / 100 source: icon + visible: !largeButton } Text { objectName: "value" @@ -187,6 +189,7 @@ HomeForm{ horizontalAlignment: Text.AlignHCenter font.pointSize: valueFontSize * settings.ui_zoom / 100 font.bold: true + visible: !largeButton } Text { objectName: "secondLine" @@ -201,6 +204,7 @@ HomeForm{ horizontalAlignment: Text.AlignHCenter font.pointSize: 12 * settings.ui_zoom / 100 font.bold: false + visible: !largeButton } Text { id: myText @@ -214,13 +218,14 @@ HomeForm{ anchors.left: parent.left anchors.leftMargin: 55 * settings.ui_zoom / 100 anchors.topMargin: 20 * settings.ui_zoom / 100 + visible: !largeButton } RoundButton { objectName: minusName autoRepeat: true text: "-" onClicked: minus_clicked(objectName) - visible: writable + visible: writable && !largeButton anchors.top: myValue.top anchors.left: parent.left anchors.leftMargin: 2 @@ -232,13 +237,24 @@ HomeForm{ objectName: plusName text: "+" onClicked: plus_clicked(objectName) - visible: writable + visible: writable && !largeButton anchors.top: myValue.top anchors.right: parent.right anchors.rightMargin: 2 width: 48 * settings.ui_zoom / 100 height: 48 * settings.ui_zoom / 100 } + RoundButton { + autoRepeat: true + objectName: identificator + text: largeButtonLabel + onClicked: largeButton_clicked(objectName) + visible: largeButton + anchors.fill: rect + font.pointSize: 16 * settings.ui_zoom / 100 + //width: 48 * settings.ui_zoom / 100 + //height: 48 * settings.ui_zoom / 100 + } /*MouseArea { anchors.fill: parent diff --git a/src/homeform.cpp b/src/homeform.cpp index 945d90904..df1ddbf83 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -62,7 +62,7 @@ using namespace std::chrono_literals; DataObject::DataObject(const QString &name, const QString &icon, const QString &value, bool writable, const QString &id, int valueFontSize, int labelFontSize, const QString &valueFontColor, const QString &secondLine, - const int gridId) { + const int gridId, bool largeButton, QString largeButtonLabel) { m_name = name; m_icon = icon; m_value = value; @@ -73,9 +73,14 @@ DataObject::DataObject(const QString &name, const QString &icon, const QString & m_valueFontColor = valueFontColor; m_labelFontSize = labelFontSize; m_gridId = gridId; + m_largeButton = largeButton; + m_largeButtonLabel = largeButtonLabel; emit plusNameChanged(plusName()); // NOTE: clazy-incorrecrt-emit emit minusNameChanged(minusName()); // NOTE: clazy-incorrecrt-emit + emit identificatorChanged(identificator()); + emit largeButtonChanged(this->largeButton()); + emit largeButtonLabelChanged(this->largeButtonLabel()); } void DataObject::setName(const QString &v) { @@ -247,6 +252,82 @@ homeform::homeform(QQmlApplicationEngine *engine, bluetooth *bl) { new DataObject(QStringLiteral("Vert.Osc.(mm)"), QStringLiteral("icons/icons/inclination.png"), QStringLiteral("0"), false, QStringLiteral("vertical_oscillation"), 48, labelFontSize); + preset_resistance_1 = new DataObject( + "", "", "", false, QStringLiteral("preset_resistance_1"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_resistance_1_label, QZSettings::default_tile_preset_resistance_1_label) + .toString()); + preset_resistance_2 = new DataObject( + "", "", "", false, QStringLiteral("preset_resistance_2"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_resistance_2_label, QZSettings::default_tile_preset_resistance_2_label) + .toString()); + preset_resistance_3 = new DataObject( + "", "", "", false, QStringLiteral("preset_resistance_3"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_resistance_3_label, QZSettings::default_tile_preset_resistance_3_label) + .toString()); + preset_resistance_4 = new DataObject( + "", "", "", false, QStringLiteral("preset_resistance_4"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_resistance_4_label, QZSettings::default_tile_preset_resistance_4_label) + .toString()); + preset_resistance_5 = new DataObject( + "", "", "", false, QStringLiteral("preset_resistance_5"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_resistance_5_label, QZSettings::default_tile_preset_resistance_5_label) + .toString()); + preset_speed_1 = new DataObject( + "", "", "", false, QStringLiteral("preset_speed_1"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_speed_1_label, QZSettings::default_tile_preset_speed_1_label) + .toString()); + preset_speed_2 = new DataObject( + "", "", "", false, QStringLiteral("preset_speed_2"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_speed_2_label, QZSettings::default_tile_preset_speed_2_label) + .toString()); + preset_speed_3 = new DataObject( + "", "", "", false, QStringLiteral("preset_speed_3"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_speed_3_label, QZSettings::default_tile_preset_speed_3_label) + .toString()); + preset_speed_4 = new DataObject( + "", "", "", false, QStringLiteral("preset_speed_4"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_speed_4_label, QZSettings::default_tile_preset_speed_4_label) + .toString()); + preset_speed_5 = new DataObject( + "", "", "", false, QStringLiteral("preset_speed_5"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_speed_5_label, QZSettings::default_tile_preset_speed_5_label) + .toString()); + preset_inclination_1 = new DataObject( + "", "", "", false, QStringLiteral("preset_inclination_1"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_inclination_1_label, QZSettings::default_tile_preset_inclination_1_label) + .toString()); + preset_inclination_2 = new DataObject( + "", "", "", false, QStringLiteral("preset_inclination_2"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_inclination_2_label, QZSettings::default_tile_preset_inclination_2_label) + .toString()); + preset_inclination_3 = new DataObject( + "", "", "", false, QStringLiteral("preset_inclination_3"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_inclination_3_label, QZSettings::default_tile_preset_inclination_3_label) + .toString()); + preset_inclination_4 = new DataObject( + "", "", "", false, QStringLiteral("preset_inclination_4"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_inclination_4_label, QZSettings::default_tile_preset_inclination_4_label) + .toString()); + preset_inclination_5 = new DataObject( + "", "", "", false, QStringLiteral("preset_inclination_5"), 48, labelFontSize, QStringLiteral("white"), + QLatin1String(""), 0, true, + settings.value(QZSettings::tile_preset_inclination_5_label, QZSettings::default_tile_preset_inclination_5_label) + .toString()); + if (!settings.value(QZSettings::top_bar_enabled, QZSettings::default_top_bar_enabled).toBool()) { m_topBarHeight = 0; @@ -931,6 +1012,92 @@ void homeform::sortTiles() { verticalOscillationMM->setGridId(i); dataList.append(verticalOscillationMM); } + + if (settings.value(QZSettings::tile_preset_speed_1_enabled, QZSettings::default_tile_preset_speed_1_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_speed_1_order, QZSettings::default_tile_preset_speed_1_order) + .toInt() == i) { + preset_speed_1->setGridId(i); + dataList.append(preset_speed_1); + } + if (settings.value(QZSettings::tile_preset_speed_2_enabled, QZSettings::default_tile_preset_speed_2_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_speed_2_order, QZSettings::default_tile_preset_speed_2_order) + .toInt() == i) { + preset_speed_2->setGridId(i); + dataList.append(preset_speed_2); + } + if (settings.value(QZSettings::tile_preset_speed_3_enabled, QZSettings::default_tile_preset_speed_3_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_speed_3_order, QZSettings::default_tile_preset_speed_3_order) + .toInt() == i) { + preset_speed_3->setGridId(i); + dataList.append(preset_speed_3); + } + if (settings.value(QZSettings::tile_preset_speed_4_enabled, QZSettings::default_tile_preset_speed_4_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_speed_4_order, QZSettings::default_tile_preset_speed_4_order) + .toInt() == i) { + preset_speed_4->setGridId(i); + dataList.append(preset_speed_4); + } + if (settings.value(QZSettings::tile_preset_speed_5_enabled, QZSettings::default_tile_preset_speed_5_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_speed_5_order, QZSettings::default_tile_preset_speed_5_order) + .toInt() == i) { + preset_speed_5->setGridId(i); + dataList.append(preset_speed_5); + } + if (settings + .value(QZSettings::tile_preset_inclination_1_enabled, + QZSettings::default_tile_preset_inclination_1_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_1_order, + QZSettings::default_tile_preset_inclination_1_order) + .toInt() == i) { + preset_inclination_1->setGridId(i); + dataList.append(preset_inclination_1); + } + if (settings + .value(QZSettings::tile_preset_inclination_2_enabled, + QZSettings::default_tile_preset_inclination_2_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_2_order, + QZSettings::default_tile_preset_inclination_2_order) + .toInt() == i) { + preset_inclination_2->setGridId(i); + dataList.append(preset_inclination_2); + } + if (settings + .value(QZSettings::tile_preset_inclination_3_enabled, + QZSettings::default_tile_preset_inclination_3_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_3_order, + QZSettings::default_tile_preset_inclination_3_order) + .toInt() == i) { + preset_inclination_3->setGridId(i); + dataList.append(preset_inclination_3); + } + if (settings + .value(QZSettings::tile_preset_inclination_4_enabled, + QZSettings::default_tile_preset_inclination_4_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_4_order, + QZSettings::default_tile_preset_inclination_4_order) + .toInt() == i) { + preset_inclination_4->setGridId(i); + dataList.append(preset_inclination_4); + } + if (settings + .value(QZSettings::tile_preset_inclination_5_enabled, + QZSettings::default_tile_preset_inclination_5_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_5_order, + QZSettings::default_tile_preset_inclination_5_order) + .toInt() == i) { + preset_inclination_5->setGridId(i); + dataList.append(preset_inclination_5); + } } } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { for (int i = 0; i < 100; i++) { @@ -1151,6 +1318,108 @@ void homeform::sortTiles() { extIncline->setGridId(i); dataList.append(extIncline); } + + if (settings + .value(QZSettings::tile_preset_inclination_1_enabled, + QZSettings::default_tile_preset_inclination_1_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_1_order, + QZSettings::default_tile_preset_inclination_1_order) + .toInt() == i) { + preset_inclination_1->setGridId(i); + dataList.append(preset_inclination_1); + } + if (settings + .value(QZSettings::tile_preset_inclination_2_enabled, + QZSettings::default_tile_preset_inclination_2_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_2_order, + QZSettings::default_tile_preset_inclination_2_order) + .toInt() == i) { + preset_inclination_2->setGridId(i); + dataList.append(preset_inclination_2); + } + if (settings + .value(QZSettings::tile_preset_inclination_3_enabled, + QZSettings::default_tile_preset_inclination_3_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_3_order, + QZSettings::default_tile_preset_inclination_3_order) + .toInt() == i) { + preset_inclination_3->setGridId(i); + dataList.append(preset_inclination_3); + } + if (settings + .value(QZSettings::tile_preset_inclination_4_enabled, + QZSettings::default_tile_preset_inclination_4_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_4_order, + QZSettings::default_tile_preset_inclination_4_order) + .toInt() == i) { + preset_inclination_4->setGridId(i); + dataList.append(preset_inclination_4); + } + if (settings + .value(QZSettings::tile_preset_inclination_5_enabled, + QZSettings::default_tile_preset_inclination_5_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_5_order, + QZSettings::default_tile_preset_inclination_5_order) + .toInt() == i) { + preset_inclination_5->setGridId(i); + dataList.append(preset_inclination_5); + } + + if (settings + .value(QZSettings::tile_preset_resistance_1_enabled, + QZSettings::default_tile_preset_resistance_1_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_1_order, + QZSettings::default_tile_preset_resistance_1_order) + .toInt() == i) { + preset_resistance_1->setGridId(i); + dataList.append(preset_resistance_1); + } + if (settings + .value(QZSettings::tile_preset_resistance_2_enabled, + QZSettings::default_tile_preset_resistance_2_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_2_order, + QZSettings::default_tile_preset_resistance_2_order) + .toInt() == i) { + preset_resistance_2->setGridId(i); + dataList.append(preset_resistance_2); + } + if (settings + .value(QZSettings::tile_preset_resistance_3_enabled, + QZSettings::default_tile_preset_resistance_3_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_3_order, + QZSettings::default_tile_preset_resistance_3_order) + .toInt() == i) { + preset_resistance_3->setGridId(i); + dataList.append(preset_resistance_3); + } + if (settings + .value(QZSettings::tile_preset_resistance_4_enabled, + QZSettings::default_tile_preset_resistance_4_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_4_order, + QZSettings::default_tile_preset_resistance_4_order) + .toInt() == i) { + preset_resistance_4->setGridId(i); + dataList.append(preset_resistance_4); + } + if (settings + .value(QZSettings::tile_preset_resistance_5_enabled, + QZSettings::default_tile_preset_resistance_5_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_5_order, + QZSettings::default_tile_preset_resistance_5_order) + .toInt() == i) { + preset_resistance_5->setGridId(i); + dataList.append(preset_resistance_5); + } } } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::ROWING) { for (int i = 0; i < 100; i++) { @@ -1542,6 +1811,108 @@ void homeform::sortTiles() { target_speed->setGridId(i); dataList.append(target_speed); } + + if (settings + .value(QZSettings::tile_preset_inclination_1_enabled, + QZSettings::default_tile_preset_inclination_1_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_1_order, + QZSettings::default_tile_preset_inclination_1_order) + .toInt() == i) { + preset_inclination_1->setGridId(i); + dataList.append(preset_inclination_1); + } + if (settings + .value(QZSettings::tile_preset_inclination_2_enabled, + QZSettings::default_tile_preset_inclination_2_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_2_order, + QZSettings::default_tile_preset_inclination_2_order) + .toInt() == i) { + preset_inclination_2->setGridId(i); + dataList.append(preset_inclination_2); + } + if (settings + .value(QZSettings::tile_preset_inclination_3_enabled, + QZSettings::default_tile_preset_inclination_3_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_3_order, + QZSettings::default_tile_preset_inclination_3_order) + .toInt() == i) { + preset_inclination_3->setGridId(i); + dataList.append(preset_inclination_3); + } + if (settings + .value(QZSettings::tile_preset_inclination_4_enabled, + QZSettings::default_tile_preset_inclination_4_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_4_order, + QZSettings::default_tile_preset_inclination_4_order) + .toInt() == i) { + preset_inclination_4->setGridId(i); + dataList.append(preset_inclination_4); + } + if (settings + .value(QZSettings::tile_preset_inclination_5_enabled, + QZSettings::default_tile_preset_inclination_5_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_inclination_5_order, + QZSettings::default_tile_preset_inclination_5_order) + .toInt() == i) { + preset_inclination_5->setGridId(i); + dataList.append(preset_inclination_5); + } + + if (settings + .value(QZSettings::tile_preset_resistance_1_enabled, + QZSettings::default_tile_preset_resistance_1_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_1_order, + QZSettings::default_tile_preset_resistance_1_order) + .toInt() == i) { + preset_resistance_1->setGridId(i); + dataList.append(preset_resistance_1); + } + if (settings + .value(QZSettings::tile_preset_resistance_2_enabled, + QZSettings::default_tile_preset_resistance_2_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_2_order, + QZSettings::default_tile_preset_resistance_2_order) + .toInt() == i) { + preset_resistance_2->setGridId(i); + dataList.append(preset_resistance_2); + } + if (settings + .value(QZSettings::tile_preset_resistance_3_enabled, + QZSettings::default_tile_preset_resistance_3_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_3_order, + QZSettings::default_tile_preset_resistance_3_order) + .toInt() == i) { + preset_resistance_3->setGridId(i); + dataList.append(preset_resistance_3); + } + if (settings + .value(QZSettings::tile_preset_resistance_4_enabled, + QZSettings::default_tile_preset_resistance_4_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_4_order, + QZSettings::default_tile_preset_resistance_4_order) + .toInt() == i) { + preset_resistance_4->setGridId(i); + dataList.append(preset_resistance_4); + } + if (settings + .value(QZSettings::tile_preset_resistance_5_enabled, + QZSettings::default_tile_preset_resistance_5_enabled) + .toBool() && + settings.value(QZSettings::tile_preset_resistance_5_order, + QZSettings::default_tile_preset_resistance_5_order) + .toInt() == i) { + preset_resistance_5->setGridId(i); + dataList.append(preset_resistance_5); + } } } @@ -1638,6 +2009,7 @@ void homeform::deviceConnected(QBluetoothDeviceInfo b) { QObject *home = rootObject->findChild(QStringLiteral("home")); QObject::connect(home, SIGNAL(plus_clicked(QString)), this, SLOT(Plus(QString))); QObject::connect(home, SIGNAL(minus_clicked(QString)), this, SLOT(Minus(QString))); + QObject::connect(home, SIGNAL(largeButton_clicked(QString)), this, SLOT(LargeButton(QString))); emit workoutNameChanged(workoutName()); emit instructorNameChanged(instructorName()); @@ -1662,6 +2034,246 @@ void homeform::deviceFound(const QString &name) { emit infoChanged(m_info); } +void homeform::LargeButton(const QString &name) { + QSettings settings; + qDebug() << QStringLiteral("LargeButton") << name; + if (!bluetoothManager || !bluetoothManager->device()) + return; + + if (bluetoothManager->device()->deviceType() == bluetoothdevice::BIKE) { + if (name.contains(QStringLiteral("preset_resistance_1"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_1_value, + QZSettings::default_tile_preset_resistance_1_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_resistance_2"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_2_value, + QZSettings::default_tile_preset_resistance_2_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_resistance_3"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_3_value, + QZSettings::default_tile_preset_resistance_3_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_resistance_4"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_4_value, + QZSettings::default_tile_preset_resistance_4_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_resistance_5"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_5_value, + QZSettings::default_tile_preset_resistance_5_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_1"))) { + ((bike *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_1_value, + QZSettings::default_tile_preset_inclination_1_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_1_value, + QZSettings::default_tile_preset_inclination_1_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_2"))) { + ((bike *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_2_value, + QZSettings::default_tile_preset_inclination_2_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_2_value, + QZSettings::default_tile_preset_inclination_2_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_3"))) { + ((bike *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_3_value, + QZSettings::default_tile_preset_inclination_3_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_3_value, + QZSettings::default_tile_preset_inclination_3_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_4"))) { + ((bike *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_4_value, + QZSettings::default_tile_preset_inclination_4_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_4_value, + QZSettings::default_tile_preset_inclination_4_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_5"))) { + ((bike *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_5_value, + QZSettings::default_tile_preset_inclination_5_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_5_value, + QZSettings::default_tile_preset_inclination_5_value) + .toDouble()); + } + } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) { + if (name.contains(QStringLiteral("preset_speed_1"))) { + ((treadmill *)bluetoothManager->device()) + ->changeSpeed( + settings.value(QZSettings::tile_preset_speed_1_value, QZSettings::default_tile_preset_speed_1_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_speed_2"))) { + ((treadmill *)bluetoothManager->device()) + ->changeSpeed( + settings.value(QZSettings::tile_preset_speed_2_value, QZSettings::default_tile_preset_speed_2_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_speed_3"))) { + ((treadmill *)bluetoothManager->device()) + ->changeSpeed( + settings.value(QZSettings::tile_preset_speed_3_value, QZSettings::default_tile_preset_speed_3_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_speed_4"))) { + ((treadmill *)bluetoothManager->device()) + ->changeSpeed( + settings.value(QZSettings::tile_preset_speed_4_value, QZSettings::default_tile_preset_speed_4_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_speed_5"))) { + ((treadmill *)bluetoothManager->device()) + ->changeSpeed( + settings.value(QZSettings::tile_preset_speed_5_value, QZSettings::default_tile_preset_speed_5_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_1"))) { + ((treadmill *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_1_value, + QZSettings::default_tile_preset_inclination_1_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_1_value, + QZSettings::default_tile_preset_inclination_1_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_2"))) { + ((treadmill *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_2_value, + QZSettings::default_tile_preset_inclination_2_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_2_value, + QZSettings::default_tile_preset_inclination_2_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_3"))) { + ((treadmill *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_3_value, + QZSettings::default_tile_preset_inclination_3_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_3_value, + QZSettings::default_tile_preset_inclination_3_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_4"))) { + ((treadmill *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_4_value, + QZSettings::default_tile_preset_inclination_4_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_4_value, + QZSettings::default_tile_preset_inclination_4_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_5"))) { + ((treadmill *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_5_value, + QZSettings::default_tile_preset_inclination_5_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_5_value, + QZSettings::default_tile_preset_inclination_5_value) + .toDouble()); + } + } else if (bluetoothManager->device()->deviceType() == bluetoothdevice::ELLIPTICAL) { + if (name.contains(QStringLiteral("preset_resistance_1"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_1_value, + QZSettings::default_tile_preset_resistance_1_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_resistance_2"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_2_value, + QZSettings::default_tile_preset_resistance_2_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_resistance_3"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_3_value, + QZSettings::default_tile_preset_resistance_3_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_resistance_4"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_4_value, + QZSettings::default_tile_preset_resistance_4_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_resistance_5"))) { + bluetoothManager->device()->changeResistance(settings + .value(QZSettings::tile_preset_resistance_5_value, + QZSettings::default_tile_preset_resistance_5_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_1"))) { + ((elliptical *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_1_value, + QZSettings::default_tile_preset_inclination_1_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_1_value, + QZSettings::default_tile_preset_inclination_1_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_2"))) { + ((elliptical *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_2_value, + QZSettings::default_tile_preset_inclination_2_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_2_value, + QZSettings::default_tile_preset_inclination_2_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_3"))) { + ((elliptical *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_3_value, + QZSettings::default_tile_preset_inclination_3_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_3_value, + QZSettings::default_tile_preset_inclination_3_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_4"))) { + ((elliptical *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_4_value, + QZSettings::default_tile_preset_inclination_4_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_4_value, + QZSettings::default_tile_preset_inclination_4_value) + .toDouble()); + } else if (name.contains(QStringLiteral("preset_inclination_5"))) { + ((elliptical *)bluetoothManager->device()) + ->changeInclination(settings + .value(QZSettings::tile_preset_inclination_5_value, + QZSettings::default_tile_preset_inclination_5_value) + .toDouble(), + settings + .value(QZSettings::tile_preset_inclination_5_value, + QZSettings::default_tile_preset_inclination_5_value) + .toDouble()); + } + } +} + void homeform::Plus(const QString &name) { QSettings settings; bool miles = settings.value(QZSettings::miles_unit, QZSettings::default_miles_unit).toBool(); diff --git a/src/homeform.h b/src/homeform.h index cd9a5a92d..053f65a50 100644 --- a/src/homeform.h +++ b/src/homeform.h @@ -35,14 +35,17 @@ class DataObject : public QObject { Q_PROPERTY(int labelFontSize READ labelFontSize WRITE setLabelFontSize NOTIFY labelFontSizeChanged) Q_PROPERTY(bool writable READ writable NOTIFY writableChanged) Q_PROPERTY(bool visibleItem READ visibleItem NOTIFY visibleChanged) + Q_PROPERTY(bool largeButton READ largeButton NOTIFY largeButtonChanged) + Q_PROPERTY(QString largeButtonLabel READ largeButtonLabel NOTIFY largeButtonLabelChanged) Q_PROPERTY(QString plusName READ plusName NOTIFY plusNameChanged) Q_PROPERTY(QString minusName READ minusName NOTIFY minusNameChanged) - Q_PROPERTY(QString identificator READ identificator) + Q_PROPERTY(QString identificator READ identificator NOTIFY identificatorChanged) public: DataObject(const QString &name, const QString &icon, const QString &value, bool writable, const QString &id, int valueFontSize, int labelFontSize, const QString &valueFontColor = QStringLiteral("white"), - const QString &secondLine = QLatin1String(""), const int gridId = 0); + const QString &secondLine = QLatin1String(""), const int gridId = 0, const bool largeButton = false, + const QString largeButtonLabel = QLatin1String("")); void setName(const QString &value); void setValue(const QString &value); void setSecondLine(const QString &value); @@ -64,6 +67,8 @@ class DataObject : public QObject { QString plusName() { return m_id + QStringLiteral("_plus"); } QString minusName() { return m_id + QStringLiteral("_minus"); } QString identificator() { return m_id; } + bool largeButton() { return m_largeButton; } + QString largeButtonLabel() { return m_largeButtonLabel; } QString m_id; QString m_name; @@ -76,6 +81,8 @@ class DataObject : public QObject { int m_labelFontSize; bool m_writable; bool m_visible = true; + bool m_largeButton = false; + QString m_largeButtonLabel = QLatin1String(""); signals: void valueChanged(QString value); @@ -90,6 +97,9 @@ class DataObject : public QObject { void visibleChanged(bool value); void plusNameChanged(QString value); void minusNameChanged(QString value); + void identificatorChanged(QString value); + void largeButtonChanged(bool value); + void largeButtonLabelChanged(QString value); }; class homeform : public QObject { @@ -230,14 +240,14 @@ class homeform : public QObject { /*backgroundGradient.setStart(QPointF(0, 0)); backgroundGradient.setFinalStop(QPointF(0, 1)); backgroundGradient.setColorAt((220 - (maxHeartRate * - settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble() / 100)) / 220, QColor("lightsteelblue")); - backgroundGradient.setColorAt((220 - (maxHeartRate * - settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble() / 100)) / 220, QColor("green")); - backgroundGradient.setColorAt((220 - (maxHeartRate * - settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble() / 100)) / 220, QColor("yellow")); - backgroundGradient.setColorAt((220 - (maxHeartRate * settings.value(QZSettings::heart_rate_zone4, - QZSettings::default_heart_rate_zone4).toDouble() / 100)) / 220, QColor("orange")); - backgroundGradient.setColorAt(0.0, QColor("red")); */ + settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble() / + 100)) / 220, QColor("lightsteelblue")); backgroundGradient.setColorAt((220 - (maxHeartRate * + settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble() / + 100)) / 220, QColor("green")); backgroundGradient.setColorAt((220 - (maxHeartRate * + settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble() / + 100)) / 220, QColor("yellow")); backgroundGradient.setColorAt((220 - (maxHeartRate * + settings.value(QZSettings::heart_rate_zone4, QZSettings::default_heart_rate_zone4).toDouble() / + 100)) / 220, QColor("orange")); backgroundGradient.setColorAt(0.0, QColor("red")); */ // backgroundGradient.setCoordinateMode(QGradient::ObjectBoundingMode); // chart->setBackgroundBrush(backgroundGradient); @@ -246,23 +256,31 @@ class homeform : public QObject { plotAreaGradient.setStart(QPointF(0, 0)); plotAreaGradient.setFinalStop(QPointF(0, 1)); plotAreaGradient.setColorAt( - (220 - - (maxHeartRate * settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1).toDouble() / 100)) / + (220 - (maxHeartRate * + settings.value(QZSettings::heart_rate_zone1, QZSettings::default_heart_rate_zone1) + .toDouble() / + 100)) / 160, QColor(QStringLiteral("lightsteelblue"))); plotAreaGradient.setColorAt( - (220 - - (maxHeartRate * settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2).toDouble() / 100)) / + (220 - (maxHeartRate * + settings.value(QZSettings::heart_rate_zone2, QZSettings::default_heart_rate_zone2) + .toDouble() / + 100)) / 160, QColor(QStringLiteral("green"))); plotAreaGradient.setColorAt( - (220 - - (maxHeartRate * settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3).toDouble() / 100)) / + (220 - (maxHeartRate * + settings.value(QZSettings::heart_rate_zone3, QZSettings::default_heart_rate_zone3) + .toDouble() / + 100)) / 160, QColor(QStringLiteral("yellow"))); plotAreaGradient.setColorAt( - (220 - - (maxHeartRate * settings.value(QZSettings::heart_rate_zone4, QZSettings::default_heart_rate_zone4).toDouble() / 100)) / + (220 - (maxHeartRate * + settings.value(QZSettings::heart_rate_zone4, QZSettings::default_heart_rate_zone4) + .toDouble() / + 100)) / 160, QColor(QStringLiteral("orange"))); plotAreaGradient.setColorAt(0.0, QColor(QStringLiteral("red"))); @@ -289,7 +307,9 @@ class homeform : public QObject { Q_INVOKABLE bool autoInclinationEnabled() { QSettings settings; - bool virtual_bike = settings.value(QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike).toBool(); + bool virtual_bike = + settings.value(QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike) + .toBool(); return bluetoothManager && bluetoothManager->device() && bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL && !virtual_bike && bluetoothManager->device()->VirtualDevice() && @@ -341,7 +361,7 @@ class homeform : public QObject { bool licensePopupVisible(); bool mapsVisible(); bool videoIconVisible(); - bool videoVisible() { return m_VideoVisible;} + bool videoVisible() { return m_VideoVisible; } int videoPosition(); double videoRate(); double currentSpeed() { @@ -365,7 +385,10 @@ class homeform : public QObject { } void setLicensePopupVisible(bool value); void setVideoIconVisible(bool value); - void setVideoVisible(bool value) {m_VideoVisible = value; emit videoVisibleChanged(m_VideoVisible);} + void setVideoVisible(bool value) { + m_VideoVisible = value; + emit videoVisibleChanged(m_VideoVisible); + } void setVideoPosition(int position); // on startup void videoSeekPosition(int ms); // in realtime void setVideoRate(double rate); @@ -569,6 +592,21 @@ class homeform : public QObject { DataObject *instantaneousStrideLengthCM; DataObject *groundContactMS; DataObject *verticalOscillationMM; + DataObject *preset_resistance_1; + DataObject *preset_resistance_2; + DataObject *preset_resistance_3; + DataObject *preset_resistance_4; + DataObject *preset_resistance_5; + DataObject *preset_speed_1; + DataObject *preset_speed_2; + DataObject *preset_speed_3; + DataObject *preset_speed_4; + DataObject *preset_speed_5; + DataObject *preset_inclination_1; + DataObject *preset_inclination_2; + DataObject *preset_inclination_3; + DataObject *preset_inclination_4; + DataObject *preset_inclination_5; QTimer *timer; QTimer *backupTimer; @@ -581,7 +619,6 @@ class homeform : public QObject { const QUrl &clientIdentifierSharedKey); bool strava_upload_file(const QByteArray &data, const QString &remotename); - quint64 cryptoKeySettingsProfiles(); int16_t fanOverride = 0; @@ -595,7 +632,7 @@ class homeform : public QObject { QTextToSpeech m_speech; int tts_summary_count = 0; - + #if defined(Q_OS_WIN) || (defined(Q_OS_MAC) && !defined(Q_OS_IOS)) QTimer tLicense; QNetworkAccessManager *mgr = nullptr; @@ -620,6 +657,7 @@ class homeform : public QObject { void Lap(); void Minus(const QString &); void Plus(const QString &); + void LargeButton(const QString &); void volumeDown(); void volumeUp(); void keyMediaPrevious(); diff --git a/src/qml.qrc b/src/qml.qrc index c1ed9f897..a37555b8e 100644 --- a/src/qml.qrc +++ b/src/qml.qrc @@ -85,5 +85,6 @@ gpx/St Andrews to Pittenweem.gpx GPXList.qml videoPlayback.qml + settings-tiles.qml diff --git a/src/qzsettings.cpp b/src/qzsettings.cpp index 129520c89..5a9fdb7d9 100644 --- a/src/qzsettings.cpp +++ b/src/qzsettings.cpp @@ -441,8 +441,83 @@ const QString QZSettings::nordictrack_gx_2_7 = QStringLiteral("nordictrack_gx_2_ const QString QZSettings::rolling_resistance = QStringLiteral("rolling_resistance"); const QString QZSettings::wahoo_rgt_dircon = QStringLiteral("wahoo_rgt_dircon"); const QString QZSettings::tts_description_enabled = QStringLiteral("tts_description_enabled"); +const QString QZSettings::tile_preset_resistance_1_enabled = QStringLiteral("tile_preset_resistance_1_enabled"); +const QString QZSettings::tile_preset_resistance_1_order = QStringLiteral("tile_preset_resistance_1_order"); +const QString QZSettings::tile_preset_resistance_1_value = QStringLiteral("tile_preset_resistance_1_value"); +const QString QZSettings::tile_preset_resistance_1_label = QStringLiteral("tile_preset_resistance_1_label"); +const QString QZSettings::default_tile_preset_resistance_1_label = QStringLiteral("Res. 1"); +const QString QZSettings::tile_preset_resistance_2_enabled = QStringLiteral("tile_preset_resistance_2_enabled"); +const QString QZSettings::tile_preset_resistance_2_order = QStringLiteral("tile_preset_resistance_2_order"); +const QString QZSettings::tile_preset_resistance_2_value = QStringLiteral("tile_preset_resistance_2_value"); +const QString QZSettings::tile_preset_resistance_2_label = QStringLiteral("tile_preset_resistance_2_label"); +const QString QZSettings::default_tile_preset_resistance_2_label = QStringLiteral("Res. 10"); +const QString QZSettings::tile_preset_resistance_3_enabled = QStringLiteral("tile_preset_resistance_3_enabled"); +const QString QZSettings::tile_preset_resistance_3_order = QStringLiteral("tile_preset_resistance_3_order"); +const QString QZSettings::tile_preset_resistance_3_value = QStringLiteral("tile_preset_resistance_3_value"); +const QString QZSettings::tile_preset_resistance_3_label = QStringLiteral("tile_preset_resistance_3_label"); +const QString QZSettings::default_tile_preset_resistance_3_label = QStringLiteral("Res. 20"); +const QString QZSettings::tile_preset_resistance_4_enabled = QStringLiteral("tile_preset_resistance_4_enabled"); +const QString QZSettings::tile_preset_resistance_4_order = QStringLiteral("tile_preset_resistance_4_order"); +const QString QZSettings::tile_preset_resistance_4_value = QStringLiteral("tile_preset_resistance_4_value"); +const QString QZSettings::tile_preset_resistance_4_label = QStringLiteral("tile_preset_resistance_4_label"); +const QString QZSettings::default_tile_preset_resistance_4_label = QStringLiteral("Res. 25"); +const QString QZSettings::tile_preset_resistance_5_enabled = QStringLiteral("tile_preset_resistance_5_enabled"); +const QString QZSettings::tile_preset_resistance_5_order = QStringLiteral("tile_preset_resistance_5_order"); +const QString QZSettings::tile_preset_resistance_5_value = QStringLiteral("tile_preset_resistance_5_value"); +const QString QZSettings::tile_preset_resistance_5_label = QStringLiteral("tile_preset_resistance_5_label"); +const QString QZSettings::default_tile_preset_resistance_5_label = QStringLiteral("Res. 30"); +const QString QZSettings::tile_preset_speed_1_enabled = QStringLiteral("tile_preset_speed_1_enabled"); +const QString QZSettings::tile_preset_speed_1_order = QStringLiteral("tile_preset_speed_1_order"); +const QString QZSettings::tile_preset_speed_1_value = QStringLiteral("tile_preset_speed_1_value"); +const QString QZSettings::tile_preset_speed_1_label = QStringLiteral("tile_preset_speed_1_label"); +const QString QZSettings::default_tile_preset_speed_1_label = QStringLiteral("5km/h"); +const QString QZSettings::tile_preset_speed_2_enabled = QStringLiteral("tile_preset_speed_2_enabled"); +const QString QZSettings::tile_preset_speed_2_order = QStringLiteral("tile_preset_speed_2_order"); +const QString QZSettings::tile_preset_speed_2_value = QStringLiteral("tile_preset_speed_2_value"); +const QString QZSettings::tile_preset_speed_2_label = QStringLiteral("tile_preset_speed_2_label"); +const QString QZSettings::default_tile_preset_speed_2_label = QStringLiteral("7 km/h"); +const QString QZSettings::tile_preset_speed_3_enabled = QStringLiteral("tile_preset_speed_3_enabled"); +const QString QZSettings::tile_preset_speed_3_order = QStringLiteral("tile_preset_speed_3_order"); +const QString QZSettings::tile_preset_speed_3_value = QStringLiteral("tile_preset_speed_3_value"); +const QString QZSettings::tile_preset_speed_3_label = QStringLiteral("tile_preset_speed_3_label"); +const QString QZSettings::default_tile_preset_speed_3_label = QStringLiteral("10 km/h"); +const QString QZSettings::tile_preset_speed_4_enabled = QStringLiteral("tile_preset_speed_4_enabled"); +const QString QZSettings::tile_preset_speed_4_order = QStringLiteral("tile_preset_speed_4_order"); +const QString QZSettings::tile_preset_speed_4_value = QStringLiteral("tile_preset_speed_4_value"); +const QString QZSettings::tile_preset_speed_4_label = QStringLiteral("tile_preset_speed_4_label"); +const QString QZSettings::default_tile_preset_speed_4_label = QStringLiteral("11 km/h"); +const QString QZSettings::tile_preset_speed_5_enabled = QStringLiteral("tile_preset_speed_5_enabled"); +const QString QZSettings::tile_preset_speed_5_order = QStringLiteral("tile_preset_speed_5_order"); +const QString QZSettings::tile_preset_speed_5_value = QStringLiteral("tile_preset_speed_5_value"); +const QString QZSettings::tile_preset_speed_5_label = QStringLiteral("tile_preset_speed_5_label"); +const QString QZSettings::default_tile_preset_speed_5_label = QStringLiteral("12 km/h"); +const QString QZSettings::tile_preset_inclination_1_enabled = QStringLiteral("tile_preset_inclination_1_enabled"); +const QString QZSettings::tile_preset_inclination_1_order = QStringLiteral("tile_preset_inclination_1_order"); +const QString QZSettings::tile_preset_inclination_1_value = QStringLiteral("tile_preset_inclination_1_value"); +const QString QZSettings::tile_preset_inclination_1_label = QStringLiteral("tile_preset_inclination_1_label"); +const QString QZSettings::default_tile_preset_inclination_1_label = QStringLiteral("0%"); +const QString QZSettings::tile_preset_inclination_2_enabled = QStringLiteral("tile_preset_inclination_2_enabled"); +const QString QZSettings::tile_preset_inclination_2_order = QStringLiteral("tile_preset_inclination_2_order"); +const QString QZSettings::tile_preset_inclination_2_value = QStringLiteral("tile_preset_inclination_2_value"); +const QString QZSettings::tile_preset_inclination_2_label = QStringLiteral("tile_preset_inclination_2_label"); +const QString QZSettings::default_tile_preset_inclination_2_label = QStringLiteral("1%"); +const QString QZSettings::tile_preset_inclination_3_enabled = QStringLiteral("tile_preset_inclination_3_enabled"); +const QString QZSettings::tile_preset_inclination_3_order = QStringLiteral("tile_preset_inclination_3_order"); +const QString QZSettings::tile_preset_inclination_3_value = QStringLiteral("tile_preset_inclination_3_value"); +const QString QZSettings::tile_preset_inclination_3_label = QStringLiteral("tile_preset_inclination_3_label"); +const QString QZSettings::default_tile_preset_inclination_3_label = QStringLiteral("2%"); +const QString QZSettings::tile_preset_inclination_4_enabled = QStringLiteral("tile_preset_inclination_4_enabled"); +const QString QZSettings::tile_preset_inclination_4_order = QStringLiteral("tile_preset_inclination_4_order"); +const QString QZSettings::tile_preset_inclination_4_value = QStringLiteral("tile_preset_inclination_4_value"); +const QString QZSettings::tile_preset_inclination_4_label = QStringLiteral("tile_preset_inclination_4_label"); +const QString QZSettings::default_tile_preset_inclination_4_label = QStringLiteral("3%"); +const QString QZSettings::tile_preset_inclination_5_enabled = QStringLiteral("tile_preset_inclination_5_enabled"); +const QString QZSettings::tile_preset_inclination_5_order = QStringLiteral("tile_preset_inclination_5_order"); +const QString QZSettings::tile_preset_inclination_5_value = QStringLiteral("tile_preset_inclination_5_value"); +const QString QZSettings::tile_preset_inclination_5_label = QStringLiteral("tile_preset_inclination_5_label"); +const QString QZSettings::default_tile_preset_inclination_5_label = QStringLiteral("4%"); -const uint32_t allSettingsCount = 370; +const uint32_t allSettingsCount = 430; QVariant allSettings[allSettingsCount][2] = { {QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles}, {QZSettings::bluetooth_no_reconnection, QZSettings::default_bluetooth_no_reconnection}, @@ -815,7 +890,68 @@ QVariant allSettings[allSettingsCount][2] = { {QZSettings::nordictrack_gx_2_7, QZSettings::default_nordictrack_gx_2_7}, {QZSettings::rolling_resistance, QZSettings::default_rolling_resistance}, {QZSettings::wahoo_rgt_dircon, QZSettings::default_wahoo_rgt_dircon}, - {QZSettings::tts_description_enabled, QZSettings::default_tts_description_enabled}}; + {QZSettings::tts_description_enabled, QZSettings::default_tts_description_enabled}, + {QZSettings::tile_preset_resistance_1_enabled, QZSettings::default_tile_preset_resistance_1_enabled}, + {QZSettings::tile_preset_resistance_1_order, QZSettings::default_tile_preset_resistance_1_order}, + {QZSettings::tile_preset_resistance_1_value, QZSettings::default_tile_preset_resistance_1_value}, + {QZSettings::tile_preset_resistance_1_label, QZSettings::default_tile_preset_resistance_1_label}, + {QZSettings::tile_preset_resistance_2_enabled, QZSettings::default_tile_preset_resistance_2_enabled}, + {QZSettings::tile_preset_resistance_2_order, QZSettings::default_tile_preset_resistance_2_order}, + {QZSettings::tile_preset_resistance_2_value, QZSettings::default_tile_preset_resistance_2_value}, + {QZSettings::tile_preset_resistance_2_label, QZSettings::default_tile_preset_resistance_2_label}, + {QZSettings::tile_preset_resistance_3_enabled, QZSettings::default_tile_preset_resistance_3_enabled}, + {QZSettings::tile_preset_resistance_3_order, QZSettings::default_tile_preset_resistance_3_order}, + {QZSettings::tile_preset_resistance_3_value, QZSettings::default_tile_preset_resistance_3_value}, + {QZSettings::tile_preset_resistance_3_label, QZSettings::default_tile_preset_resistance_3_label}, + {QZSettings::tile_preset_resistance_4_enabled, QZSettings::default_tile_preset_resistance_4_enabled}, + {QZSettings::tile_preset_resistance_4_order, QZSettings::default_tile_preset_resistance_4_order}, + {QZSettings::tile_preset_resistance_4_value, QZSettings::default_tile_preset_resistance_4_value}, + {QZSettings::tile_preset_resistance_4_label, QZSettings::default_tile_preset_resistance_4_label}, + {QZSettings::tile_preset_resistance_5_enabled, QZSettings::default_tile_preset_resistance_5_enabled}, + {QZSettings::tile_preset_resistance_5_order, QZSettings::default_tile_preset_resistance_5_order}, + {QZSettings::tile_preset_resistance_5_value, QZSettings::default_tile_preset_resistance_5_value}, + {QZSettings::tile_preset_resistance_5_label, QZSettings::default_tile_preset_resistance_5_label}, + {QZSettings::tile_preset_speed_1_enabled, QZSettings::default_tile_preset_speed_1_enabled}, + {QZSettings::tile_preset_speed_1_order, QZSettings::default_tile_preset_speed_1_order}, + {QZSettings::tile_preset_speed_1_value, QZSettings::default_tile_preset_speed_1_value}, + {QZSettings::tile_preset_speed_1_label, QZSettings::default_tile_preset_speed_1_label}, + {QZSettings::tile_preset_speed_2_enabled, QZSettings::default_tile_preset_speed_2_enabled}, + {QZSettings::tile_preset_speed_2_order, QZSettings::default_tile_preset_speed_2_order}, + {QZSettings::tile_preset_speed_2_value, QZSettings::default_tile_preset_speed_2_value}, + {QZSettings::tile_preset_speed_2_label, QZSettings::default_tile_preset_speed_2_label}, + {QZSettings::tile_preset_speed_3_enabled, QZSettings::default_tile_preset_speed_3_enabled}, + {QZSettings::tile_preset_speed_3_order, QZSettings::default_tile_preset_speed_3_order}, + {QZSettings::tile_preset_speed_3_value, QZSettings::default_tile_preset_speed_3_value}, + {QZSettings::tile_preset_speed_3_label, QZSettings::default_tile_preset_speed_3_label}, + {QZSettings::tile_preset_speed_4_enabled, QZSettings::default_tile_preset_speed_4_enabled}, + {QZSettings::tile_preset_speed_4_order, QZSettings::default_tile_preset_speed_4_order}, + {QZSettings::tile_preset_speed_4_value, QZSettings::default_tile_preset_speed_4_value}, + {QZSettings::tile_preset_speed_4_label, QZSettings::default_tile_preset_speed_4_label}, + {QZSettings::tile_preset_speed_5_enabled, QZSettings::default_tile_preset_speed_5_enabled}, + {QZSettings::tile_preset_speed_5_order, QZSettings::default_tile_preset_speed_5_order}, + {QZSettings::tile_preset_speed_5_value, QZSettings::default_tile_preset_speed_5_value}, + {QZSettings::tile_preset_speed_5_label, QZSettings::default_tile_preset_speed_5_label}, + {QZSettings::tile_preset_inclination_1_enabled, QZSettings::default_tile_preset_inclination_1_enabled}, + {QZSettings::tile_preset_inclination_1_order, QZSettings::default_tile_preset_inclination_1_order}, + {QZSettings::tile_preset_inclination_1_value, QZSettings::default_tile_preset_inclination_1_value}, + {QZSettings::tile_preset_inclination_1_label, QZSettings::default_tile_preset_inclination_1_label}, + {QZSettings::tile_preset_inclination_2_enabled, QZSettings::default_tile_preset_inclination_2_enabled}, + {QZSettings::tile_preset_inclination_2_order, QZSettings::default_tile_preset_inclination_2_order}, + {QZSettings::tile_preset_inclination_2_value, QZSettings::default_tile_preset_inclination_2_value}, + {QZSettings::tile_preset_inclination_2_label, QZSettings::default_tile_preset_inclination_2_label}, + {QZSettings::tile_preset_inclination_3_enabled, QZSettings::default_tile_preset_inclination_3_enabled}, + {QZSettings::tile_preset_inclination_3_order, QZSettings::default_tile_preset_inclination_3_order}, + {QZSettings::tile_preset_inclination_3_value, QZSettings::default_tile_preset_inclination_3_value}, + {QZSettings::tile_preset_inclination_3_label, QZSettings::default_tile_preset_inclination_3_label}, + {QZSettings::tile_preset_inclination_4_enabled, QZSettings::default_tile_preset_inclination_4_enabled}, + {QZSettings::tile_preset_inclination_4_order, QZSettings::default_tile_preset_inclination_4_order}, + {QZSettings::tile_preset_inclination_4_value, QZSettings::default_tile_preset_inclination_4_value}, + {QZSettings::tile_preset_inclination_4_label, QZSettings::default_tile_preset_inclination_4_label}, + {QZSettings::tile_preset_inclination_5_enabled, QZSettings::default_tile_preset_inclination_5_enabled}, + {QZSettings::tile_preset_inclination_5_order, QZSettings::default_tile_preset_inclination_5_order}, + {QZSettings::tile_preset_inclination_5_value, QZSettings::default_tile_preset_inclination_5_value}, + {QZSettings::tile_preset_inclination_5_label, QZSettings::default_tile_preset_inclination_5_label}, +}; void QZSettings::qDebugAllSettings(bool showDefaults) { QSettings settings; diff --git a/src/qzsettings.h b/src/qzsettings.h index 8e8257297..914e0e581 100644 --- a/src/qzsettings.h +++ b/src/qzsettings.h @@ -1336,6 +1336,186 @@ class QZSettings { static const QString tts_description_enabled; static constexpr bool default_tts_description_enabled = true; + static const QString tile_preset_resistance_1_enabled; + static constexpr bool default_tile_preset_resistance_1_enabled = false; + + static const QString tile_preset_resistance_1_order; + static constexpr int default_tile_preset_resistance_1_order = 33; + + static const QString tile_preset_resistance_1_value; + static constexpr double default_tile_preset_resistance_1_value = 1; + + static const QString tile_preset_resistance_1_label; + static const QString default_tile_preset_resistance_1_label; + + static const QString tile_preset_resistance_2_enabled; + static constexpr bool default_tile_preset_resistance_2_enabled = false; + + static const QString tile_preset_resistance_2_order; + static constexpr int default_tile_preset_resistance_2_order = 34; + + static const QString tile_preset_resistance_2_value; + static constexpr double default_tile_preset_resistance_2_value = 10; + + static const QString tile_preset_resistance_2_label; + static const QString default_tile_preset_resistance_2_label; + + static const QString tile_preset_resistance_3_enabled; + static constexpr bool default_tile_preset_resistance_3_enabled = false; + + static const QString tile_preset_resistance_3_order; + static constexpr int default_tile_preset_resistance_3_order = 35; + + static const QString tile_preset_resistance_3_value; + static constexpr double default_tile_preset_resistance_3_value = 20; + + static const QString tile_preset_resistance_3_label; + static const QString default_tile_preset_resistance_3_label; + + static const QString tile_preset_resistance_4_enabled; + static constexpr bool default_tile_preset_resistance_4_enabled = false; + + static const QString tile_preset_resistance_4_order; + static constexpr int default_tile_preset_resistance_4_order = 36; + + static const QString tile_preset_resistance_4_value; + static constexpr double default_tile_preset_resistance_4_value = 25; + + static const QString tile_preset_resistance_4_label; + static const QString default_tile_preset_resistance_4_label; + + static const QString tile_preset_resistance_5_enabled; + static constexpr bool default_tile_preset_resistance_5_enabled = false; + + static const QString tile_preset_resistance_5_order; + static constexpr int default_tile_preset_resistance_5_order = 37; + + static const QString tile_preset_resistance_5_value; + static constexpr double default_tile_preset_resistance_5_value = 30; + + static const QString tile_preset_resistance_5_label; + static const QString default_tile_preset_resistance_5_label; + + static const QString tile_preset_speed_1_enabled; + static constexpr bool default_tile_preset_speed_1_enabled = false; + + static const QString tile_preset_speed_1_order; + static constexpr int default_tile_preset_speed_1_order = 38; + + static const QString tile_preset_speed_1_value; + static constexpr double default_tile_preset_speed_1_value = 5; + + static const QString tile_preset_speed_1_label; + static const QString default_tile_preset_speed_1_label; + + static const QString tile_preset_speed_2_enabled; + static constexpr bool default_tile_preset_speed_2_enabled = false; + + static const QString tile_preset_speed_2_order; + static constexpr int default_tile_preset_speed_2_order = 39; + + static const QString tile_preset_speed_2_value; + static constexpr double default_tile_preset_speed_2_value = 7; + + static const QString tile_preset_speed_2_label; + static const QString default_tile_preset_speed_2_label; + + static const QString tile_preset_speed_3_enabled; + static constexpr bool default_tile_preset_speed_3_enabled = false; + + static const QString tile_preset_speed_3_order; + static constexpr int default_tile_preset_speed_3_order = 40; + + static const QString tile_preset_speed_3_value; + static constexpr double default_tile_preset_speed_3_value = 10; + + static const QString tile_preset_speed_3_label; + static const QString default_tile_preset_speed_3_label; + + static const QString tile_preset_speed_4_enabled; + static constexpr bool default_tile_preset_speed_4_enabled = false; + + static const QString tile_preset_speed_4_order; + static constexpr int default_tile_preset_speed_4_order = 41; + + static const QString tile_preset_speed_4_value; + static constexpr double default_tile_preset_speed_4_value = 11; + + static const QString tile_preset_speed_4_label; + static const QString default_tile_preset_speed_4_label; + + static const QString tile_preset_speed_5_enabled; + static constexpr bool default_tile_preset_speed_5_enabled = false; + + static const QString tile_preset_speed_5_order; + static constexpr int default_tile_preset_speed_5_order = 42; + + static const QString tile_preset_speed_5_value; + static constexpr double default_tile_preset_speed_5_value = 12; + + static const QString tile_preset_speed_5_label; + static const QString default_tile_preset_speed_5_label; + + static const QString tile_preset_inclination_1_enabled; + static constexpr bool default_tile_preset_inclination_1_enabled = false; + + static const QString tile_preset_inclination_1_order; + static constexpr int default_tile_preset_inclination_1_order = 43; + + static const QString tile_preset_inclination_1_value; + static constexpr double default_tile_preset_inclination_1_value = 0; + + static const QString tile_preset_inclination_1_label; + static const QString default_tile_preset_inclination_1_label; + + static const QString tile_preset_inclination_2_enabled; + static constexpr bool default_tile_preset_inclination_2_enabled = false; + + static const QString tile_preset_inclination_2_order; + static constexpr int default_tile_preset_inclination_2_order = 44; + + static const QString tile_preset_inclination_2_value; + static constexpr double default_tile_preset_inclination_2_value = 1; + + static const QString tile_preset_inclination_2_label; + static const QString default_tile_preset_inclination_2_label; + + static const QString tile_preset_inclination_3_enabled; + static constexpr bool default_tile_preset_inclination_3_enabled = false; + + static const QString tile_preset_inclination_3_order; + static constexpr int default_tile_preset_inclination_3_order = 45; + + static const QString tile_preset_inclination_3_value; + static constexpr double default_tile_preset_inclination_3_value = 2; + + static const QString tile_preset_inclination_3_label; + static const QString default_tile_preset_inclination_3_label; + + static const QString tile_preset_inclination_4_enabled; + static constexpr bool default_tile_preset_inclination_4_enabled = false; + + static const QString tile_preset_inclination_4_order; + static constexpr int default_tile_preset_inclination_4_order = 46; + + static const QString tile_preset_inclination_4_value; + static constexpr double default_tile_preset_inclination_4_value = 3; + + static const QString tile_preset_inclination_4_label; + static const QString default_tile_preset_inclination_4_label; + + static const QString tile_preset_inclination_5_enabled; + static constexpr bool default_tile_preset_inclination_5_enabled = false; + + static const QString tile_preset_inclination_5_order; + static constexpr int default_tile_preset_inclination_5_order = 47; + + static const QString tile_preset_inclination_5_value; + static constexpr double default_tile_preset_inclination_5_value = 4; + + static const QString tile_preset_inclination_5_label; + static const QString default_tile_preset_inclination_5_label; + /** * @brief Write the QSettings values using the constants from this namespace. * @param showDefaults Optionally indicates if the default should be shown with the key. diff --git a/src/settings-tiles.qml b/src/settings-tiles.qml new file mode 100644 index 000000000..009ac7e45 --- /dev/null +++ b/src/settings-tiles.qml @@ -0,0 +1,2734 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 +import QtQuick.Controls 2.15 +import QtQuick.Controls.Material 2.0 +import Qt.labs.settings 1.0 + +ScrollView { + contentWidth: -1 + focus: true + anchors.horizontalCenter: parent.horizontalCenter + anchors.fill: parent + //anchors.bottom: footerSettings.top + //anchors.bottomMargin: footerSettings.height + 10 + id: settingsTilesPane + + Settings { + id: settings + property bool tile_speed_enabled: true + property int tile_speed_order: 0 + property bool tile_inclination_enabled: true + property int tile_inclination_order: 1 + property bool tile_cadence_enabled: true + property int tile_cadence_order: 2 + property bool tile_elevation_enabled: true + property int tile_elevation_order: 3 + property bool tile_calories_enabled: true + property int tile_calories_order: 4 + property bool tile_odometer_enabled: true + property int tile_odometer_order: 5 + property bool tile_pace_enabled: true + property int tile_pace_order: 6 + property bool tile_resistance_enabled: true + property int tile_resistance_order: 7 + property bool tile_watt_enabled: true + property int tile_watt_order: 8 + property bool tile_weight_loss_enabled: false + property int tile_weight_loss_order: 24 + property bool tile_avgwatt_enabled: true + property int tile_avgwatt_order: 9 + property bool tile_ftp_enabled: true + property int tile_ftp_order: 10 + property bool tile_heart_enabled: true + property int tile_heart_order: 11 + property bool tile_fan_enabled: true + property int tile_fan_order: 12 + property bool tile_jouls_enabled: true + property int tile_jouls_order: 13 + property bool tile_elapsed_enabled: true + property int tile_elapsed_order: 14 + property bool tile_lapelapsed_enabled: false + property int tile_lapelapsed_order: 17 + property bool tile_moving_time_enabled: false + property int tile_moving_time_order: 21 + property bool tile_peloton_offset_enabled: false + property int tile_peloton_offset_order: 22 + property bool tile_peloton_difficulty_enabled: false + property int tile_peloton_difficulty_order: 32 + property bool tile_peloton_resistance_enabled: true + property int tile_peloton_resistance_order: 15 + property bool tile_datetime_enabled: true + property int tile_datetime_order: 16 + property bool tile_target_resistance_enabled: true + property int tile_target_resistance_order: 15 + property bool tile_target_peloton_resistance_enabled: false + property int tile_target_peloton_resistance_order: 21 + property bool tile_target_cadence_enabled: false + property int tile_target_cadence_order: 19 + property bool tile_target_power_enabled: false + property int tile_target_power_order: 20 + property bool tile_target_zone_enabled: false + property int tile_target_zone_order: 24 + property bool tile_target_speed_enabled: false + property int tile_target_speed_order: 27 + property bool tile_target_incline_enabled: false + property int tile_target_incline_order: 28 + property bool tile_strokes_count_enabled: false + property int tile_strokes_count_order: 22 + property bool tile_strokes_length_enabled: false + property int tile_strokes_length_order: 23 + property bool tile_watt_kg_enabled: false + property int tile_watt_kg_order: 25 + property bool tile_gears_enabled: false + property int tile_gears_order: 26 + property bool tile_remainingtimetrainprogramrow_enabled: false + property int tile_remainingtimetrainprogramrow_order: 27 + property bool tile_nextrowstrainprogram_enabled: false + property int tile_nextrowstrainprogram_order: 31 + property bool tile_mets_enabled: false + property int tile_mets_order: 28 + property bool tile_targetmets_enabled: false + property int tile_targetmets_order: 29 + property bool tile_steering_angle_enabled: false + property int tile_steering_angle_order: 30 + property bool tile_pid_hr_enabled: false + property int tile_pid_hr_order: 31 + property bool tile_ext_incline_enabled: false + property int tile_ext_incline_order: 32 + property bool tile_cadence_color_enabled: false + property bool tile_peloton_remaining_enabled: false + property int tile_peloton_remaining_order: 22 + property bool tile_peloton_resistance_color_enabled: false + property bool tile_instantaneous_stride_length_enabled: false + property int tile_instantaneous_stride_length_order: 32 + property bool tile_ground_contact_enabled: false + property int tile_ground_contact_order: 33 + property bool tile_vertical_oscillation_enabled: false + property int tile_vertical_oscillation_order: 34 + property bool tile_preset_resistance_1_enabled: false + property int tile_preset_resistance_1_order: 33 + property real tile_preset_resistance_1_value: 1.0 + property string tile_preset_resistance_1_label: "Res. 1" + property bool tile_preset_resistance_2_enabled: false + property int tile_preset_resistance_2_order: 34 + property real tile_preset_resistance_2_value: 10.0 + property string tile_preset_resistance_2_label: "Res. 10" + property bool tile_preset_resistance_3_enabled: false + property int tile_preset_resistance_3_order: 35 + property real tile_preset_resistance_3_value: 20.0 + property string tile_preset_resistance_3_label: "Res. 20" + property bool tile_preset_resistance_4_enabled: false + property int tile_preset_resistance_4_order: 36 + property real tile_preset_resistance_4_value: 25.0 + property string tile_preset_resistance_4_label: "Res. 25" + property bool tile_preset_resistance_5_enabled: false + property int tile_preset_resistance_5_order: 37 + property real tile_preset_resistance_5_value: 30.0 + property string tile_preset_resistance_5_label: "Res. 30" + property bool tile_preset_speed_1_enabled: false + property int tile_preset_speed_1_order: 38 + property real tile_preset_speed_1_value: 5.0 + property string tile_preset_speed_1_label: "5 km/h" + property bool tile_preset_speed_2_enabled: false + property int tile_preset_speed_2_order: 39 + property real tile_preset_speed_2_value: 7.0 + property string tile_preset_speed_2_label: "7 km/h" + property bool tile_preset_speed_3_enabled: false + property int tile_preset_speed_3_order: 40 + property real tile_preset_speed_3_value: 10.0 + property string tile_preset_speed_3_label: "10 km/h" + property bool tile_preset_speed_4_enabled: false + property int tile_preset_speed_4_order: 41 + property real tile_preset_speed_4_value: 11.0 + property string tile_preset_speed_4_label: "11 km/h" + property bool tile_preset_speed_5_enabled: false + property int tile_preset_speed_5_order: 42 + property real tile_preset_speed_5_value: 12.0 + property string tile_preset_speed_5_label: "12 km/h" + property bool tile_preset_inclination_1_enabled: false + property int tile_preset_inclination_1_order: 43 + property real tile_preset_inclination_1_value: 0.0 + property string tile_preset_inclination_1_label: "0%" + property bool tile_preset_inclination_2_enabled: false + property int tile_preset_inclination_2_order: 44 + property real tile_preset_inclination_2_value: 1.0 + property string tile_preset_inclination_2_label: "1%" + property bool tile_preset_inclination_3_enabled: false + property int tile_preset_inclination_3_order: 45 + property real tile_preset_inclination_3_value: 2.0 + property string tile_preset_inclination_3_label: "2%" + property bool tile_preset_inclination_4_enabled: false + property int tile_preset_inclination_4_order: 46 + property real tile_preset_inclination_4_value: 3.0 + property string tile_preset_inclination_4_label: "3%" + property bool tile_preset_inclination_5_enabled: false + property int tile_preset_inclination_5_order: 47 + property real tile_preset_inclination_5_value: 4.0 + property string tile_preset_inclination_5_label: "4%" + } + + + ColumnLayout { + spacing: 0 + anchors.fill: parent + + AccordionCheckElement { + id: speedEnabledAccordion + title: qsTr("Speed") + linkedBoolSetting: "tile_speed_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelSpeedOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: speedOrderTextField + model: rootItem.tile_order + displayText: settings.tile_speed_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = speedOrderTextField.currentValue + } + } + Button { + id: okSpeedOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_speed_order = speedOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: inclinationEnabledAccordion + title: qsTr("Inclination") + linkedBoolSetting: "tile_inclination_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelinclinationOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: inclinationOrderTextField + model: rootItem.tile_order + displayText: settings.tile_inclination_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = inclinationOrderTextField.currentValue + } + } + Button { + id: okinclinationOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_inclination_order = inclinationOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: cadenceEnabledAccordion + title: qsTr("Cadence") + linkedBoolSetting: "tile_cadence_enabled" + settings: settings + accordionContent: ColumnLayout { + SwitchDelegate { + id: cadenceColorEnabled + text: qsTr("Enable Cadence color") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.tile_cadence_color_enabled + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.tile_cadence_color_enabled = checked + } + RowLayout { + spacing: 10 + Label { + id: labelcadenceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: cadenceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_cadence_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = cadenceOrderTextField.currentValue + } + } + Button { + id: okcadenceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_cadence_order = cadenceOrderTextField.displayText + } + } + } + } + + AccordionCheckElement { + id: elevationEnabledAccordion + title: qsTr("Elevation") + linkedBoolSetting: "tile_elevation_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelelevationOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: elevationOrderTextField + model: rootItem.tile_order + displayText: settings.tile_elevation_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = elevationOrderTextField.currentValue + } + } + Button { + id: okelevationOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_elevation_order = elevationOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: caloriesEnabledAccordion + title: qsTr("Calories") + linkedBoolSetting: "tile_calories_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelcaloriesOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: caloriesOrderTextField + model: rootItem.tile_order + displayText: settings.tile_calories_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = caloriesOrderTextField.currentValue + } + } + Button { + id: okcaloriesOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_calories_order = caloriesOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: odometerEnabledAccordion + title: qsTr("Odometer") + linkedBoolSetting: "tile_odometer_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelodometerOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: odometerOrderTextField + model: rootItem.tile_order + displayText: settings.tile_odometer_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = odometerOrderTextField.currentValue + } + } + Button { + id: okodometerOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_odometer_order = odometerOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: paceEnabledAccordion + title: qsTr("Pace") + linkedBoolSetting: "tile_pace_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelpaceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: paceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_pace_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = paceOrderTextField.currentValue + } + } + Button { + id: okpaceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_pace_order = paceOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: resistanceEnabledAccordion + title: qsTr("Resistance") + linkedBoolSetting: "tile_resistance_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelresistanceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: resistanceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_resistance_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = resistanceOrderTextField.currentValue + } + } + Button { + id: okresistanceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_resistance_order = resistanceOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: wattEnabledAccordion + title: qsTr("Watt") + linkedBoolSetting: "tile_watt_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelwattOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: wattOrderTextField + model: rootItem.tile_order + displayText: settings.tile_watt_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = wattOrderTextField.currentValue + } + } + Button { + id: okwattOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_watt_order = wattOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: weightLossEnabledAccordion + title: qsTr("Weight loss") + linkedBoolSetting: "tile_weight_loss_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelweightLossOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: weightLossOrderTextField + model: rootItem.tile_order + displayText: settings.tile_weight_loss_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = weightLossOrderTextField.currentValue + } + } + Button { + id: okweightLossOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_weight_loss_order = weightLossOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: avgwattEnabledAccordion + title: qsTr("AVG Watt") + linkedBoolSetting: "tile_avgwatt_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelavgwattOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: avgwattOrderTextField + model: rootItem.tile_order + displayText: settings.tile_avgwatt_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = avgwattOrderTextField.currentValue + } + } + Button { + id: okavgwattOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_avgwatt_order = avgwattOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: ftpEnabledAccordion + title: qsTr("FTP %") + linkedBoolSetting: "tile_ftp_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelftpOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: ftpOrderTextField + model: rootItem.tile_order + displayText: settings.tile_ftp_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = ftpOrderTextField.currentValue + } + } + Button { + id: okftpOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_ftp_order = ftpOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: heartEnabledAccordion + title: qsTr("Heart") + linkedBoolSetting: "tile_heart_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelheartrateOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: heartrateOrderTextField + model: rootItem.tile_order + displayText: settings.tile_heart_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = heartrateOrderTextField.currentValue + } + } + Button { + id: okheartrateOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_heart_order = heartrateOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: fanEnabledAccordion + title: qsTr("Fan") + linkedBoolSetting: "tile_fan_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelfanOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: fanOrderTextField + model: rootItem.tile_order + displayText: settings.tile_fan_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = fanOrderTextField.currentValue + } + } + Button { + id: okfanOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_fan_order = fanOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: joulsEnabledAccordion + title: qsTr("Jouls") + linkedBoolSetting: "tile_jouls_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeljoulsOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: joulsOrderTextField + model: rootItem.tile_order + displayText: settings.tile_jouls_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = joulsOrderTextField.currentValue + } + } + Button { + id: okjoulsOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_jouls_order = joulsOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: elapsedEnabledAccordion + title: qsTr("Elapsed") + linkedBoolSetting: "tile_elapsed_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelelapsedOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: elapsedOrderTextField + model: rootItem.tile_order + displayText: settings.tile_elapsed_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = elapsedOrderTextField.currentValue + } + } + Button { + id: okelapsedOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_elapsed_order = elapsedOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: movingTimeEnabledAccordion + title: qsTr("Moving Time") + linkedBoolSetting: "tile_moving_time_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelmovingTimeOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: movingTimeOrderTextField + model: rootItem.tile_order + displayText: settings.tile_moving_time_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = movingTimeOrderTextField.currentValue + } + } + Button { + id: okmovingTimeOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_moving_time_order = movingTimeOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: pelotonOffsetEnabledAccordion + title: qsTr("Peloton Offset") + linkedBoolSetting: "tile_peloton_offset_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelpelotonOffsetOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: pelotonOffsetOrderTextField + model: rootItem.tile_order + displayText: settings.tile_peloton_offset_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = pelotonOffsetOrderTextField.currentValue + } + } + Button { + id: okpelotonOffsetOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_peloton_offset_order = pelotonOffsetOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: pelotonRemainingEnabledAccordion + title: qsTr("Peloton Remaining") + linkedBoolSetting: "tile_peloton_remaining_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelPelotonRemainingOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: pelotonRemainingOrderTextField + model: rootItem.tile_order + displayText: settings.tile_peloton_remaining_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = pelotonRemainingOrderTextField.currentValue + } + } + Button { + id: okPelotonRemainingOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_peloton_remaining_order = pelotonRemainingOrderTextField.displayText + } + } + } + + /* + AccordionCheckElement { + id: pelotonDifficultyEnabledAccordion + title: qsTr("Peloton Difficulty") + linkedBoolSetting: "tile_peloton_difficulty_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelpelotonDifficultyOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: pelotonDifficultyOrderTextField + model: rootItem.tile_order + displayText: settings.tile_peloton_difficulty_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = pelotonDifficultyOrderTextField.currentValue + } + } + Button { + id: okpelotonDifficultyOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_peloton_difficulty_order = pelotonDifficultyOrderTextField.displayText + } + } + }*/ + + AccordionCheckElement { + id: lapElapsedEnabledAccordion + title: qsTr("Lap Elapsed") + linkedBoolSetting: "tile_lapelapsed_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labellapElapsedOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: lapElapsedOrderTextField + model: rootItem.tile_order + displayText: settings.tile_lapelapsed_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = lapElapsedOrderTextField.currentValue + } + } + Button { + id: oklapElapsedOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_lapelapsed_order = lapElapsedOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: pelotonResistanceEnabledAccordion + title: qsTr("Peloton Resistance") + linkedBoolSetting: "tile_peloton_resistance_enabled" + settings: settings + accordionContent: ColumnLayout { + SwitchDelegate { + id: pelotonResistanceColorEnabled + text: qsTr("Enable Peloton Resistance color") + spacing: 0 + bottomPadding: 0 + topPadding: 0 + rightPadding: 0 + leftPadding: 0 + clip: false + checked: settings.tile_peloton_resistance_color_enabled + Layout.alignment: Qt.AlignLeft | Qt.AlignTop + Layout.fillWidth: true + onClicked: settings.tile_peloton_resistance_color_enabled = checked + } + RowLayout { + spacing: 10 + Label { + id: labelpeloton_resistanceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: peloton_resistanceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_peloton_resistance_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = peloton_resistanceOrderTextField.currentValue + } + } + Button { + id: okpeloton_resistanceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_peloton_resistance_order = peloton_resistanceOrderTextField.displayText + } + } + } + } + + AccordionCheckElement { + id: targetResistanceEnabledAccordion + title: qsTr("Target Resistance") + linkedBoolSetting: "tile_target_resistance_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_resistanceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_resistanceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_resistance_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_resistanceOrderTextField.currentValue + } + } + Button { + id: oktarget_resistanceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_resistance_order = target_resistanceOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: targetPelotonResistanceEnabledAccordion + title: qsTr("Target Peloton Resistance") + linkedBoolSetting: "tile_target_peloton_resistance_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_peloton_resistanceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_peloton_resistanceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_peloton_resistance_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_peloton_resistanceOrderTextField.currentValue + } + } + Button { + id: oktarget_peloton_resistanceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_peloton_resistance_order = target_peloton_resistanceOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: targetCadenceEnabledAccordion + title: qsTr("Target Cadence") + linkedBoolSetting: "tile_target_cadence_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_cadenceOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_cadenceOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_cadence_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_cadenceOrderTextField.currentValue + } + } + Button { + id: oktarget_cadenceOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_cadence_order = target_cadenceOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: targetPowerEnabledAccordion + title: qsTr("Target Power") + linkedBoolSetting: "tile_target_power_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_powerOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_powerOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_power_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_powerOrderTextField.currentValue + } + } + Button { + id: oktarget_powerOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_power_order = target_powerOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: targetZoneEnabledAccordion + title: qsTr("Target Power Zone") + linkedBoolSetting: "tile_target_zone_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_zoneOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_zoneOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_zone_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_zoneOrderTextField.currentValue + } + } + Button { + id: oktarget_zoneOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_zone_order = target_zoneOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: targetSpeedEnabledAccordion + title: qsTr("Target Speed") + linkedBoolSetting: "tile_target_speed_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltargetspeedOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_speedOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_speed_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_speedOrderTextField.currentValue + } + } + Button { + id: oktarget_speedOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_speed_order = target_speedOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: targetInclineEnabledAccordion + title: qsTr("Target Incline") + linkedBoolSetting: "tile_target_incline_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltarget_inclineOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: target_inclineOrderTextField + model: rootItem.tile_order + displayText: settings.tile_target_incline_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = target_inclineOrderTextField.currentValue + } + } + Button { + id: oktarget_inclineOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_target_incline_order = target_inclineOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: wattKgEnabledAccordion + title: qsTr("Watt/Kg") + linkedBoolSetting: "tile_watt_kg_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelwatt_kgOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: watt_kgOrderTextField + model: rootItem.tile_order + displayText: settings.tile_watt_kg_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = watt_kgOrderTextField.currentValue + } + } + Button { + id: okwatt_kgOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_watt_kg_order = watt_kgOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: gearsEnabledAccordion + title: qsTr("Gears") + linkedBoolSetting: "tile_gears_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelgearsOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: gearsOrderTextField + model: rootItem.tile_order + displayText: settings.tile_gears_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = gearsOrderTextField.currentValue + } + } + Button { + id: okgearsOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_gears_order = gearsOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: remainingTimeTrainingProgramRowEnabledAccordion + title: qsTr("Remaining Time/Row") + linkedBoolSetting: "tile_remainingtimetrainprogramrow_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelremainingTimeTrainingProgramRowOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: remainingTimeTrainingProgramRowOrderTextField + model: rootItem.tile_order + displayText: settings.tile_remainingtimetrainprogramrow_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = remainingTimeTrainingProgramRowOrderTextField.currentValue + } + } + Button { + id: okremainingTimeTrainingProgramRowOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_remainingtimetrainprogramrow_order = remainingTimeTrainingProgramRowOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: nextRowsTrainingProgramRowEnabledAccordion + title: qsTr("Next Rows") + linkedBoolSetting: "tile_nextrowstrainprogram_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelnextRowsTrainingProgramOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: nextRowsTrainingProgramOrderTextField + model: rootItem.tile_order + displayText: settings.tile_nextrowstrainprogram_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = nextRowsTrainingProgramOrderTextField.currentValue + } + } + Button { + id: oknextRowsTrainingProgramOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_nextrowstrainprogram_order = nextRowsTrainingProgramOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: metsEnabledAccordion + title: qsTr("METS") + linkedBoolSetting: "tile_mets_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelmetsOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: metsOrderTextField + model: rootItem.tile_order + displayText: settings.tile_mets_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = metsOrderTextField.currentValue + } + } + Button { + id: okmetsOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_mets_order = metsOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: targetMetsEnabledAccordion + title: qsTr("Target METS") + linkedBoolSetting: "tile_targetmets_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeltargetmetsOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: targetmetsOrderTextField + model: rootItem.tile_order + displayText: settings.tile_targetmets_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = targetmetsOrderTextField.currentValue + } + } + Button { + id: oktargetmetsOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_targetmets_order = targetmetsOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: datetimeEnabledAccordion + title: qsTr("Time") + linkedBoolSetting: "tile_datetime_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labeldatetimeOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: datetimeOrderTextField + model: rootItem.tile_order + displayText: settings.tile_datetime_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = datetimeOrderTextField.currentValue + } + } + Button { + id: okdatetimeOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_datetime_order = datetimeOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: targetStrokesCountAccordion + title: qsTr("Strokes Count") + linkedBoolSetting: "tile_strokes_count_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelstrokes_countOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: strokes_countOrderTextField + model: rootItem.tile_order + displayText: settings.tile_strokes_count_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = strokes_countOrderTextField.currentValue + } + } + Button { + id: okstrokes_countOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_strokes_count_order = strokes_countOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: targetStrokesLengthAccordion + title: qsTr("Strokes Length") + linkedBoolSetting: "tile_strokes_length_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelstrokes_lengthOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: strokes_lengthOrderTextField + model: rootItem.tile_order + displayText: settings.tile_strokes_length_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = strokes_lengthOrderTextField.currentValue + } + } + Button { + id: okstrokes_lengthOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_strokes_length_order = strokes_lengthOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: targetSteeringAngleEnabledAccordion + title: qsTr("Steering Angle") + linkedBoolSetting: "tile_steering_angle_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelsteeringAngleOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: steeringAngleOrderTextField + model: rootItem.tile_order + displayText: settings.tile_steering_angle_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = steeringAngleOrderTextField.currentValue + } + } + Button { + id: oksteeringAngleOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_steering_angle_order = steeringAngleOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: targetPIDHrAccordion + title: qsTr("PID HR Zone") + linkedBoolSetting: "tile_pid_hr_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelPIDHROrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: pidHROrderTextField + model: rootItem.tile_order + displayText: settings.tile_pid_hr_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = pidHROrderTextField.currentValue + } + } + Button { + id: okpidHROrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_pid_hr_order = pidHROrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: extInclineAccordion + title: qsTr("External Incline") + linkedBoolSetting: "tile_ext_incline_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelExtInclineOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: extInclineOrderTextField + model: rootItem.tile_order + displayText: settings.tile_ext_incline_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = extInclineOrderTextField.currentValue + } + } + Button { + id: okextInclineOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_ext_incline_order = extInclineOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: strideLength + title: qsTr("Stride Length") + linkedBoolSetting: "tile_instantaneous_stride_length_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelStrideLengthOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: strideLengthOrderTextField + model: rootItem.tile_order + displayText: settings.tile_instantaneous_stride_length_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = strideLengthOrderTextField.currentValue + } + } + Button { + id: okStrideLengthOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_instantaneous_stride_length_order = strideLengthOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: groundContact + title: qsTr("Ground Contact") + linkedBoolSetting: "tile_ground_contact_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelGroundContactOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: groundContactOrderTextField + model: rootItem.tile_order + displayText: settings.tile_ground_contact_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = groundContactOrderTextField.currentValue + } + } + Button { + id: okGroundContactOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_ground_contact_order = groundContactOrderTextField.displayText + } + } + } + + AccordionCheckElement { + id: verticalOscillation + title: qsTr("Vertical Oscillation") + linkedBoolSetting: "tile_vertical_oscillation_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelVerticalOscillationOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: verticalOscillationOrderTextField + model: rootItem.tile_order + displayText: settings.tile_vertical_oscillation_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = verticalOscillationOrderTextField.currentValue + } + } + Button { + id: okVerticalOscillationOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_vertical_oscillation_order = verticalOscillationOrderTextField.displayText + } + } + } + AccordionCheckElement { + id: presetResistance1EnabledAccordion + title: qsTr("Preset Resistance 1") + linkedBoolSetting: "tile_preset_resistance_1_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetResistance1Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetResistance1TextField + model: rootItem.tile_order + displayText: settings.tile_preset_resistance_1_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetResistance1TextField.currentValue + } + } + Button { + id: okPresetResistance1OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_1_order = presetResistance1TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance1Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance1ValueTextField + text: settings.tile_preset_resistance_1_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance1ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_1_value = presetResistance1ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance1Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance1LabelTextField + text: settings.tile_preset_resistance_1_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance1LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_1_label = presetResistance1LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetResistance2EnabledAccordion + title: qsTr("Preset Resistance 2") + linkedBoolSetting: "tile_preset_resistance_2_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetResistance2Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetResistance2TextField + model: rootItem.tile_order + displayText: settings.tile_preset_resistance_2_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetResistance2TextField.currentValue + } + } + Button { + id: okPresetResistance2OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_2_order = presetResistance2TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance2Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance2ValueTextField + text: settings.tile_preset_resistance_2_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance2ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_2_value = presetResistance2ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance2Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance2LabelTextField + text: settings.tile_preset_resistance_2_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance2LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_2_label = presetResistance2LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetResistance3EnabledAccordion + title: qsTr("Preset Resistance 3") + linkedBoolSetting: "tile_preset_resistance_3_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetResistance3Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetResistance3TextField + model: rootItem.tile_order + displayText: settings.tile_preset_resistance_3_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetResistance3TextField.currentValue + } + } + Button { + id: okPresetResistance3OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_3_order = presetResistance3TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance3Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance3ValueTextField + text: settings.tile_preset_resistance_3_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance3ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_3_value = presetResistance3ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance3Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance3LabelTextField + text: settings.tile_preset_resistance_3_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance3LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_3_label = presetResistance3LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetResistance4EnabledAccordion + title: qsTr("Preset Resistance 4") + linkedBoolSetting: "tile_preset_resistance_4_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetResistance4Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetResistance4TextField + model: rootItem.tile_order + displayText: settings.tile_preset_resistance_4_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetResistance4TextField.currentValue + } + } + Button { + id: okPresetResistance4OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_4_order = presetResistance4TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance4Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance4ValueTextField + text: settings.tile_preset_resistance_4_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance4ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_4_value = presetResistance4ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance4Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance4LabelTextField + text: settings.tile_preset_resistance_4_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance4LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_4_label = presetResistance4LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetResistance5EnabledAccordion + title: qsTr("Preset Resistance 5") + linkedBoolSetting: "tile_preset_resistance_5_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetResistance5Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetResistance5TextField + model: rootItem.tile_order + displayText: settings.tile_preset_resistance_5_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetResistance5TextField.currentValue + } + } + Button { + id: okPresetResistance5OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_5_order = presetResistance5TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance5Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance5ValueTextField + text: settings.tile_preset_resistance_5_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance5ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_5_value = presetResistance5ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetResistance5Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetResistance5LabelTextField + text: settings.tile_preset_resistance_5_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetResistance5LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_5_label = presetResistance5LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetSpeed1EnabledAccordion + title: qsTr("Preset Speed 1") + linkedBoolSetting: "tile_preset_speed_1_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetSpeed1Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetSpeed1TextField + model: rootItem.tile_order + displayText: settings.tile_preset_speed_1_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetSpeed1TextField.currentValue + } + } + Button { + id: okPresetSpeed1OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_1_order = presetSpeed1TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed1Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed1ValueTextField + text: settings.tile_preset_speed_1_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed1ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_1_value = presetSpeed1ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed1Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed1LabelTextField + text: settings.tile_preset_speed_1_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed1LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_1_label = presetSpeed1LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetSpeed2EnabledAccordion + title: qsTr("Preset Speed 2") + linkedBoolSetting: "tile_preset_speed_2_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetSpeed2Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetSpeed2TextField + model: rootItem.tile_order + displayText: settings.tile_preset_speed_2_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetSpeed2TextField.currentValue + } + } + Button { + id: okPresetSpeed2OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_2_order = presetSpeed2TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed2Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed2ValueTextField + text: settings.tile_preset_speed_2_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed2ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_2_value = presetSpeed2ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed2Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed2LabelTextField + text: settings.tile_preset_speed_2_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed2LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_2_label = presetSpeed2LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetSpeed3EnabledAccordion + title: qsTr("Preset Speed 3") + linkedBoolSetting: "tile_preset_speed_3_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetSpeed3Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetSpeed3TextField + model: rootItem.tile_order + displayText: settings.tile_preset_speed_3_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetSpeed3TextField.currentValue + } + } + Button { + id: okPresetSpeed3OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_3_order = presetSpeed3TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed3Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed3ValueTextField + text: settings.tile_preset_speed_3_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed3ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_3_value = presetSpeed3ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed3Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed3LabelTextField + text: settings.tile_preset_speed_3_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed3LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_3_label = presetSpeed3LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetSpeed4EnabledAccordion + title: qsTr("Preset Speed 4") + linkedBoolSetting: "tile_preset_speed_4_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetSpeed4Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetSpeed4TextField + model: rootItem.tile_order + displayText: settings.tile_preset_speed_4_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetSpeed4TextField.currentValue + } + } + Button { + id: okPresetSpeed4OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_4_order = presetSpeed4TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed4Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed4ValueTextField + text: settings.tile_preset_speed_4_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed4ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_4_value = presetSpeed4ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed4Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed4LabelTextField + text: settings.tile_preset_speed_4_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed4LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_4_label = presetSpeed4LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetSpeed5EnabledAccordion + title: qsTr("Preset Speed 5") + linkedBoolSetting: "tile_preset_speed_5_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetSpeed5Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetSpeed5TextField + model: rootItem.tile_order + displayText: settings.tile_preset_speed_5_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetSpeed5TextField.currentValue + } + } + Button { + id: okPresetSpeed5OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_5_order = presetSpeed5TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed5Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed5ValueTextField + text: settings.tile_preset_speed_5_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed5ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_5_value = presetSpeed5ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetSpeed5Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetSpeed5LabelTextField + text: settings.tile_preset_speed_5_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetSpeed5LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_5_label = presetSpeed5LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetInclination1EnabledAccordion + title: qsTr("Preset Inclination 1") + linkedBoolSetting: "tile_preset_inclination_1_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetInclination1Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetInclination1TextField + model: rootItem.tile_order + displayText: settings.tile_preset_inclination_1_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetInclination1TextField.currentValue + } + } + Button { + id: okPresetInclination1OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_1_order = presetInclination1TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination1Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination1ValueTextField + text: settings.tile_preset_inclination_1_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination1ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_1_value = presetInclination1ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination1Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination1LabelTextField + text: settings.tile_preset_inclination_1_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination1LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_1_label = presetInclination1LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetInclination2EnabledAccordion + title: qsTr("Preset Inclination 2") + linkedBoolSetting: "tile_preset_inclination_2_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetInclination2Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetInclination2TextField + model: rootItem.tile_order + displayText: settings.tile_preset_inclination_2_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetInclination2TextField.currentValue + } + } + Button { + id: okPresetInclination2OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_2_order = presetInclination2TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination2Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination2ValueTextField + text: settings.tile_preset_inclination_2_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination2ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_2_value = presetInclination2ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination2Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination2LabelTextField + text: settings.tile_preset_inclination_2_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination2LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_2_label = presetInclination2LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetInclination3EnabledAccordion + title: qsTr("Preset Inclination 3") + linkedBoolSetting: "tile_preset_inclination_3_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetInclination3Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetInclination3TextField + model: rootItem.tile_order + displayText: settings.tile_preset_inclination_3_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetInclination3TextField.currentValue + } + } + Button { + id: okPresetInclination3OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_3_order = presetInclination3TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination3Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination3ValueTextField + text: settings.tile_preset_inclination_3_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination3ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_3_value = presetInclination3ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination3Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination3LabelTextField + text: settings.tile_preset_inclination_3_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination3LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_3_label = presetInclination3LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetInclination4EnabledAccordion + title: qsTr("Preset Inclination 4") + linkedBoolSetting: "tile_preset_inclination_4_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetInclination4Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetInclination4TextField + model: rootItem.tile_order + displayText: settings.tile_preset_inclination_4_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetInclination4TextField.currentValue + } + } + Button { + id: okPresetInclination4OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_4_order = presetInclination4TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination4Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination4ValueTextField + text: settings.tile_preset_inclination_4_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination4ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_4_value = presetInclination4ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination4Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination4LabelTextField + text: settings.tile_preset_inclination_4_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination4LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_4_label = presetInclination4LabelTextField.displayText + } + } + } + } + AccordionCheckElement { + id: presetInclination5EnabledAccordion + title: qsTr("Preset Inclination 5") + linkedBoolSetting: "tile_preset_inclination_5_enabled" + settings: settings + accordionContent: ColumnLayout { + spacing: 10 + RowLayout { + Label { + id: labelPresetInclination5Order + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: presetInclination5TextField + model: rootItem.tile_order + displayText: settings.tile_preset_inclination_5_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = presetInclination5TextField.currentValue + } + } + Button { + id: okPresetInclination5OrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_5_order = presetInclination5TextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination5Value + text: qsTr("value:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination5ValueTextField + text: settings.tile_preset_inclination_5_value + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination5ValueButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_5_value = presetInclination5ValueTextField.displayText + } + } + RowLayout { + Label { + id: labelPresetInclination5Label + text: qsTr("label:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + TextField { + id: presetInclination5LabelTextField + text: settings.tile_preset_inclination_5_label + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + } + Button { + id: okPresetInclination5LabelButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_5_label = presetInclination5LabelTextField.displayText + } + } + } + } + } +} diff --git a/src/settings.qml b/src/settings.qml index 4b667e59b..3cec68919 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -489,6 +489,68 @@ import Qt.labs.settings 1.0 // from version 2.11.73 property bool tts_description_enabled: true + + // from version 2.11.80 + property bool tile_preset_resistance_1_enabled: false + property int tile_preset_resistance_1_order: 33 + property real tile_preset_resistance_1_value: 1.0 + property string tile_preset_resistance_1_label: "Res. 1" + property bool tile_preset_resistance_2_enabled: false + property int tile_preset_resistance_2_order: 34 + property real tile_preset_resistance_2_value: 10.0 + property string tile_preset_resistance_2_label: "Res. 10" + property bool tile_preset_resistance_3_enabled: false + property int tile_preset_resistance_3_order: 35 + property real tile_preset_resistance_3_value: 20.0 + property string tile_preset_resistance_3_label: "Res. 20" + property bool tile_preset_resistance_4_enabled: false + property int tile_preset_resistance_4_order: 36 + property real tile_preset_resistance_4_value: 25.0 + property string tile_preset_resistance_4_label: "Res. 25" + property bool tile_preset_resistance_5_enabled: false + property int tile_preset_resistance_5_order: 37 + property real tile_preset_resistance_5_value: 30.0 + property string tile_preset_resistance_5_label: "Res. 30" + property bool tile_preset_speed_1_enabled: false + property int tile_preset_speed_1_order: 38 + property real tile_preset_speed_1_value: 5.0 + property string tile_preset_speed_1_label: "5 km/h" + property bool tile_preset_speed_2_enabled: false + property int tile_preset_speed_2_order: 39 + property real tile_preset_speed_2_value: 7.0 + property string tile_preset_speed_2_label: "7 km/h" + property bool tile_preset_speed_3_enabled: false + property int tile_preset_speed_3_order: 40 + property real tile_preset_speed_3_value: 10.0 + property string tile_preset_speed_3_label: "10 km/h" + property bool tile_preset_speed_4_enabled: false + property int tile_preset_speed_4_order: 41 + property real tile_preset_speed_4_value: 11.0 + property string tile_preset_speed_4_label: "11 km/h" + property bool tile_preset_speed_5_enabled: false + property int tile_preset_speed_5_order: 42 + property real tile_preset_speed_5_value: 12.0 + property string tile_preset_speed_5_label: "12 km/h" + property bool tile_preset_inclination_1_enabled: false + property int tile_preset_inclination_1_order: 43 + property real tile_preset_inclination_1_value: 0.0 + property string tile_preset_inclination_1_label: "0%" + property bool tile_preset_inclination_2_enabled: false + property int tile_preset_inclination_2_order: 44 + property real tile_preset_inclination_2_value: 1.0 + property string tile_preset_inclination_2_label: "1%" + property bool tile_preset_inclination_3_enabled: false + property int tile_preset_inclination_3_order: 45 + property real tile_preset_inclination_3_value: 2.0 + property string tile_preset_inclination_3_label: "2%" + property bool tile_preset_inclination_4_enabled: false + property int tile_preset_inclination_4_order: 46 + property real tile_preset_inclination_4_value: 3.0 + property string tile_preset_inclination_4_label: "3%" + property bool tile_preset_inclination_5_enabled: false + property int tile_preset_inclination_5_order: 47 + property real tile_preset_inclination_5_value: 4.0 + property string tile_preset_inclination_5_label: "4%" // from version ? property bool trixter_xdream_v1_bike: false @@ -2348,1451 +2410,13 @@ import Qt.labs.settings 1.0 onClicked: settings.ant_garmin = checked }*/ - AccordionElement { + NewPageElement { id: tileOptionsAccordion title: qsTr("Tiles Options") indicatRectColor: Material.color(Material.Grey) textColor: Material.color(Material.Grey) color: Material.backgroundColor - //width: 640 - //anchors.top: acc1.bottom - //anchors.topMargin: 10 - accordionContent: ColumnLayout { - spacing: 0 - AccordionCheckElement { - id: speedEnabledAccordion - title: qsTr("Speed") - linkedBoolSetting: "tile_speed_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelSpeedOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: speedOrderTextField - model: rootItem.tile_order - displayText: settings.tile_speed_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = speedOrderTextField.currentValue - } - } - Button { - id: okSpeedOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_speed_order = speedOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: inclinationEnabledAccordion - title: qsTr("Inclination") - linkedBoolSetting: "tile_inclination_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelinclinationOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: inclinationOrderTextField - model: rootItem.tile_order - displayText: settings.tile_inclination_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = inclinationOrderTextField.currentValue - } - } - Button { - id: okinclinationOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_inclination_order = inclinationOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: cadenceEnabledAccordion - title: qsTr("Cadence") - linkedBoolSetting: "tile_cadence_enabled" - settings: settings - accordionContent: ColumnLayout { - SwitchDelegate { - id: cadenceColorEnabled - text: qsTr("Enable Cadence color") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.tile_cadence_color_enabled - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.tile_cadence_color_enabled = checked - } - RowLayout { - spacing: 10 - Label { - id: labelcadenceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: cadenceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_cadence_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = cadenceOrderTextField.currentValue - } - } - Button { - id: okcadenceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_cadence_order = cadenceOrderTextField.displayText - } - } - } - } - - AccordionCheckElement { - id: elevationEnabledAccordion - title: qsTr("Elevation") - linkedBoolSetting: "tile_elevation_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelelevationOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: elevationOrderTextField - model: rootItem.tile_order - displayText: settings.tile_elevation_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = elevationOrderTextField.currentValue - } - } - Button { - id: okelevationOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_elevation_order = elevationOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: caloriesEnabledAccordion - title: qsTr("Calories") - linkedBoolSetting: "tile_calories_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelcaloriesOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: caloriesOrderTextField - model: rootItem.tile_order - displayText: settings.tile_calories_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = caloriesOrderTextField.currentValue - } - } - Button { - id: okcaloriesOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_calories_order = caloriesOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: odometerEnabledAccordion - title: qsTr("Odometer") - linkedBoolSetting: "tile_odometer_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelodometerOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: odometerOrderTextField - model: rootItem.tile_order - displayText: settings.tile_odometer_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = odometerOrderTextField.currentValue - } - } - Button { - id: okodometerOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_odometer_order = odometerOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: paceEnabledAccordion - title: qsTr("Pace") - linkedBoolSetting: "tile_pace_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelpaceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: paceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_pace_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = paceOrderTextField.currentValue - } - } - Button { - id: okpaceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_pace_order = paceOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: resistanceEnabledAccordion - title: qsTr("Resistance") - linkedBoolSetting: "tile_resistance_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelresistanceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: resistanceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_resistance_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = resistanceOrderTextField.currentValue - } - } - Button { - id: okresistanceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_resistance_order = resistanceOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: wattEnabledAccordion - title: qsTr("Watt") - linkedBoolSetting: "tile_watt_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelwattOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: wattOrderTextField - model: rootItem.tile_order - displayText: settings.tile_watt_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = wattOrderTextField.currentValue - } - } - Button { - id: okwattOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_watt_order = wattOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: weightLossEnabledAccordion - title: qsTr("Weight loss") - linkedBoolSetting: "tile_weight_loss_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelweightLossOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: weightLossOrderTextField - model: rootItem.tile_order - displayText: settings.tile_weight_loss_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = weightLossOrderTextField.currentValue - } - } - Button { - id: okweightLossOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_weight_loss_order = weightLossOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: avgwattEnabledAccordion - title: qsTr("AVG Watt") - linkedBoolSetting: "tile_avgwatt_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelavgwattOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: avgwattOrderTextField - model: rootItem.tile_order - displayText: settings.tile_avgwatt_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = avgwattOrderTextField.currentValue - } - } - Button { - id: okavgwattOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_avgwatt_order = avgwattOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: ftpEnabledAccordion - title: qsTr("FTP %") - linkedBoolSetting: "tile_ftp_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelftpOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: ftpOrderTextField - model: rootItem.tile_order - displayText: settings.tile_ftp_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = ftpOrderTextField.currentValue - } - } - Button { - id: okftpOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_ftp_order = ftpOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: heartEnabledAccordion - title: qsTr("Heart") - linkedBoolSetting: "tile_heart_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelheartrateOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: heartrateOrderTextField - model: rootItem.tile_order - displayText: settings.tile_heart_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = heartrateOrderTextField.currentValue - } - } - Button { - id: okheartrateOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_heart_order = heartrateOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: fanEnabledAccordion - title: qsTr("Fan") - linkedBoolSetting: "tile_fan_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelfanOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: fanOrderTextField - model: rootItem.tile_order - displayText: settings.tile_fan_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = fanOrderTextField.currentValue - } - } - Button { - id: okfanOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_fan_order = fanOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: joulsEnabledAccordion - title: qsTr("Jouls") - linkedBoolSetting: "tile_jouls_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeljoulsOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: joulsOrderTextField - model: rootItem.tile_order - displayText: settings.tile_jouls_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = joulsOrderTextField.currentValue - } - } - Button { - id: okjoulsOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_jouls_order = joulsOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: elapsedEnabledAccordion - title: qsTr("Elapsed") - linkedBoolSetting: "tile_elapsed_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelelapsedOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: elapsedOrderTextField - model: rootItem.tile_order - displayText: settings.tile_elapsed_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = elapsedOrderTextField.currentValue - } - } - Button { - id: okelapsedOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_elapsed_order = elapsedOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: movingTimeEnabledAccordion - title: qsTr("Moving Time") - linkedBoolSetting: "tile_moving_time_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelmovingTimeOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: movingTimeOrderTextField - model: rootItem.tile_order - displayText: settings.tile_moving_time_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = movingTimeOrderTextField.currentValue - } - } - Button { - id: okmovingTimeOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_moving_time_order = movingTimeOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: pelotonOffsetEnabledAccordion - title: qsTr("Peloton Offset") - linkedBoolSetting: "tile_peloton_offset_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelpelotonOffsetOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: pelotonOffsetOrderTextField - model: rootItem.tile_order - displayText: settings.tile_peloton_offset_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = pelotonOffsetOrderTextField.currentValue - } - } - Button { - id: okpelotonOffsetOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_peloton_offset_order = pelotonOffsetOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: pelotonRemainingEnabledAccordion - title: qsTr("Peloton Remaining") - linkedBoolSetting: "tile_peloton_remaining_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelPelotonRemainingOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: pelotonRemainingOrderTextField - model: rootItem.tile_order - displayText: settings.tile_peloton_remaining_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = pelotonRemainingOrderTextField.currentValue - } - } - Button { - id: okPelotonRemainingOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_peloton_remaining_order = pelotonRemainingOrderTextField.displayText - } - } - } - - /* - AccordionCheckElement { - id: pelotonDifficultyEnabledAccordion - title: qsTr("Peloton Difficulty") - linkedBoolSetting: "tile_peloton_difficulty_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelpelotonDifficultyOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: pelotonDifficultyOrderTextField - model: rootItem.tile_order - displayText: settings.tile_peloton_difficulty_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = pelotonDifficultyOrderTextField.currentValue - } - } - Button { - id: okpelotonDifficultyOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_peloton_difficulty_order = pelotonDifficultyOrderTextField.displayText - } - } - }*/ - - AccordionCheckElement { - id: lapElapsedEnabledAccordion - title: qsTr("Lap Elapsed") - linkedBoolSetting: "tile_lapelapsed_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labellapElapsedOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: lapElapsedOrderTextField - model: rootItem.tile_order - displayText: settings.tile_lapelapsed_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = lapElapsedOrderTextField.currentValue - } - } - Button { - id: oklapElapsedOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_lapelapsed_order = lapElapsedOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: pelotonResistanceEnabledAccordion - title: qsTr("Peloton Resistance") - linkedBoolSetting: "tile_peloton_resistance_enabled" - settings: settings - accordionContent: ColumnLayout { - SwitchDelegate { - id: pelotonResistanceColorEnabled - text: qsTr("Enable Peloton Resistance color") - spacing: 0 - bottomPadding: 0 - topPadding: 0 - rightPadding: 0 - leftPadding: 0 - clip: false - checked: settings.tile_peloton_resistance_color_enabled - Layout.alignment: Qt.AlignLeft | Qt.AlignTop - Layout.fillWidth: true - onClicked: settings.tile_peloton_resistance_color_enabled = checked - } - RowLayout { - spacing: 10 - Label { - id: labelpeloton_resistanceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: peloton_resistanceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_peloton_resistance_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = peloton_resistanceOrderTextField.currentValue - } - } - Button { - id: okpeloton_resistanceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_peloton_resistance_order = peloton_resistanceOrderTextField.displayText - } - } - } - } - - AccordionCheckElement { - id: targetResistanceEnabledAccordion - title: qsTr("Target Resistance") - linkedBoolSetting: "tile_target_resistance_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_resistanceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_resistanceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_resistance_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_resistanceOrderTextField.currentValue - } - } - Button { - id: oktarget_resistanceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_resistance_order = target_resistanceOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: targetPelotonResistanceEnabledAccordion - title: qsTr("Target Peloton Resistance") - linkedBoolSetting: "tile_target_peloton_resistance_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_peloton_resistanceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_peloton_resistanceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_peloton_resistance_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_peloton_resistanceOrderTextField.currentValue - } - } - Button { - id: oktarget_peloton_resistanceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_peloton_resistance_order = target_peloton_resistanceOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: targetCadenceEnabledAccordion - title: qsTr("Target Cadence") - linkedBoolSetting: "tile_target_cadence_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_cadenceOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_cadenceOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_cadence_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_cadenceOrderTextField.currentValue - } - } - Button { - id: oktarget_cadenceOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_cadence_order = target_cadenceOrderTextField.displayText - } - } - } - AccordionCheckElement { - id: targetPowerEnabledAccordion - title: qsTr("Target Power") - linkedBoolSetting: "tile_target_power_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_powerOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_powerOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_power_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_powerOrderTextField.currentValue - } - } - Button { - id: oktarget_powerOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_power_order = target_powerOrderTextField.displayText - } - } - } - AccordionCheckElement { - id: targetZoneEnabledAccordion - title: qsTr("Target Power Zone") - linkedBoolSetting: "tile_target_zone_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_zoneOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_zoneOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_zone_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_zoneOrderTextField.currentValue - } - } - Button { - id: oktarget_zoneOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_zone_order = target_zoneOrderTextField.displayText - } - } - } - AccordionCheckElement { - id: targetSpeedEnabledAccordion - title: qsTr("Target Speed") - linkedBoolSetting: "tile_target_speed_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltargetspeedOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_speedOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_speed_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_speedOrderTextField.currentValue - } - } - Button { - id: oktarget_speedOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_speed_order = target_speedOrderTextField.displayText - } - } - } - AccordionCheckElement { - id: targetInclineEnabledAccordion - title: qsTr("Target Incline") - linkedBoolSetting: "tile_target_incline_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltarget_inclineOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: target_inclineOrderTextField - model: rootItem.tile_order - displayText: settings.tile_target_incline_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = target_inclineOrderTextField.currentValue - } - } - Button { - id: oktarget_inclineOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_target_incline_order = target_inclineOrderTextField.displayText - } - } - } - AccordionCheckElement { - id: wattKgEnabledAccordion - title: qsTr("Watt/Kg") - linkedBoolSetting: "tile_watt_kg_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelwatt_kgOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: watt_kgOrderTextField - model: rootItem.tile_order - displayText: settings.tile_watt_kg_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = watt_kgOrderTextField.currentValue - } - } - Button { - id: okwatt_kgOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_watt_kg_order = watt_kgOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: gearsEnabledAccordion - title: qsTr("Gears") - linkedBoolSetting: "tile_gears_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelgearsOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: gearsOrderTextField - model: rootItem.tile_order - displayText: settings.tile_gears_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = gearsOrderTextField.currentValue - } - } - Button { - id: okgearsOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_gears_order = gearsOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: remainingTimeTrainingProgramRowEnabledAccordion - title: qsTr("Remaining Time/Row") - linkedBoolSetting: "tile_remainingtimetrainprogramrow_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelremainingTimeTrainingProgramRowOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: remainingTimeTrainingProgramRowOrderTextField - model: rootItem.tile_order - displayText: settings.tile_remainingtimetrainprogramrow_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = remainingTimeTrainingProgramRowOrderTextField.currentValue - } - } - Button { - id: okremainingTimeTrainingProgramRowOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_remainingtimetrainprogramrow_order = remainingTimeTrainingProgramRowOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: nextRowsTrainingProgramRowEnabledAccordion - title: qsTr("Next Rows") - linkedBoolSetting: "tile_nextrowstrainprogram_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelnextRowsTrainingProgramOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: nextRowsTrainingProgramOrderTextField - model: rootItem.tile_order - displayText: settings.tile_nextrowstrainprogram_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = nextRowsTrainingProgramOrderTextField.currentValue - } - } - Button { - id: oknextRowsTrainingProgramOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_nextrowstrainprogram_order = nextRowsTrainingProgramOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: metsEnabledAccordion - title: qsTr("METS") - linkedBoolSetting: "tile_mets_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelmetsOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: metsOrderTextField - model: rootItem.tile_order - displayText: settings.tile_mets_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = metsOrderTextField.currentValue - } - } - Button { - id: okmetsOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_mets_order = metsOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: targetMetsEnabledAccordion - title: qsTr("Target METS") - linkedBoolSetting: "tile_targetmets_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeltargetmetsOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: targetmetsOrderTextField - model: rootItem.tile_order - displayText: settings.tile_targetmets_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = targetmetsOrderTextField.currentValue - } - } - Button { - id: oktargetmetsOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_targetmets_order = targetmetsOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: datetimeEnabledAccordion - title: qsTr("Time") - linkedBoolSetting: "tile_datetime_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labeldatetimeOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: datetimeOrderTextField - model: rootItem.tile_order - displayText: settings.tile_datetime_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = datetimeOrderTextField.currentValue - } - } - Button { - id: okdatetimeOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_datetime_order = datetimeOrderTextField.displayText - } - } - } - AccordionCheckElement { - id: targetStrokesCountAccordion - title: qsTr("Strokes Count") - linkedBoolSetting: "tile_strokes_count_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelstrokes_countOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: strokes_countOrderTextField - model: rootItem.tile_order - displayText: settings.tile_strokes_count_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = strokes_countOrderTextField.currentValue - } - } - Button { - id: okstrokes_countOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_strokes_count_order = strokes_countOrderTextField.displayText - } - } - } - AccordionCheckElement { - id: targetStrokesLengthAccordion - title: qsTr("Strokes Length") - linkedBoolSetting: "tile_strokes_length_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelstrokes_lengthOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: strokes_lengthOrderTextField - model: rootItem.tile_order - displayText: settings.tile_strokes_length_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = strokes_lengthOrderTextField.currentValue - } - } - Button { - id: okstrokes_lengthOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_strokes_length_order = strokes_lengthOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: targetSteeringAngleEnabledAccordion - title: qsTr("Steering Angle") - linkedBoolSetting: "tile_steering_angle_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelsteeringAngleOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: steeringAngleOrderTextField - model: rootItem.tile_order - displayText: settings.tile_steering_angle_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = steeringAngleOrderTextField.currentValue - } - } - Button { - id: oksteeringAngleOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_steering_angle_order = steeringAngleOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: targetPIDHrAccordion - title: qsTr("PID HR Zone") - linkedBoolSetting: "tile_pid_hr_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelPIDHROrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: pidHROrderTextField - model: rootItem.tile_order - displayText: settings.tile_pid_hr_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = pidHROrderTextField.currentValue - } - } - Button { - id: okpidHROrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_pid_hr_order = pidHROrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: extInclineAccordion - title: qsTr("External Incline") - linkedBoolSetting: "tile_ext_incline_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelExtInclineOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: extInclineOrderTextField - model: rootItem.tile_order - displayText: settings.tile_ext_incline_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = extInclineOrderTextField.currentValue - } - } - Button { - id: okextInclineOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_ext_incline_order = extInclineOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: strideLength - title: qsTr("Stride Length") - linkedBoolSetting: "tile_instantaneous_stride_length_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelStrideLengthOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: strideLengthOrderTextField - model: rootItem.tile_order - displayText: settings.tile_instantaneous_stride_length_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = strideLengthOrderTextField.currentValue - } - } - Button { - id: okStrideLengthOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_instantaneous_stride_length_order = strideLengthOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: groundContact - title: qsTr("Ground Contact") - linkedBoolSetting: "tile_ground_contact_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelGroundContactOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: groundContactOrderTextField - model: rootItem.tile_order - displayText: settings.tile_ground_contact_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = groundContactOrderTextField.currentValue - } - } - Button { - id: okGroundContactOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_ground_contact_order = groundContactOrderTextField.displayText - } - } - } - - AccordionCheckElement { - id: verticalOscillation - title: qsTr("Vertical Oscillation") - linkedBoolSetting: "tile_vertical_oscillation_enabled" - settings: settings - accordionContent: RowLayout { - spacing: 10 - Label { - id: labelVerticalOscillationOrder - text: qsTr("order index:") - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - } - ComboBox { - id: verticalOscillationOrderTextField - model: rootItem.tile_order - displayText: settings.tile_vertical_oscillation_order - Layout.fillHeight: false - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onActivated: { - displayText = verticalOscillationOrderTextField.currentValue - } - } - Button { - id: okVerticalOscillationOrderButton - text: "OK" - Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - onClicked: settings.tile_vertical_oscillation_order = verticalOscillationOrderTextField.displayText - } - } - } - } + accordionContent: "settings-tiles.qml" } AccordionElement { From caf433ec52aa3a27842399dd93e0c440e1d65ff3 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 24 Oct 2022 16:46:27 +0200 Subject: [PATCH 135/255] fixing typo --- src/spirittreadmill.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/spirittreadmill.cpp b/src/spirittreadmill.cpp index 770e5299a..6af867cf9 100644 --- a/src/spirittreadmill.cpp +++ b/src/spirittreadmill.cpp @@ -436,7 +436,6 @@ void spirittreadmill::stateChanged(QLowEnergyService::ServiceState state) { connect(virtualBike, &virtualbike::changeInclination, this, &spirittreadmill::changeInclinationRequested); } - firstVirtualTreadmill = 1; } } firstVirtualTreadmill = 1; From 7797ca749d68fb3132070fe730e3a422405a61c1 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 25 Oct 2022 11:52:29 +0200 Subject: [PATCH 136/255] Differences in the GPX starting point #988 --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- src/trainprogram.cpp | 9 +++++++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index c6edb4d4d..320ce4ca3 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index cee798107..6352e565a 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.80" + text: "version 2.11.81" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index af9efeb41..ba38a4b12 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.80 +VERSION = 2.11.81 diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index a46162b1a..728627b0d 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -315,6 +315,9 @@ double trainprogram::avgInclinationNext100Meters() { while (1) { if (c < rows.length()) { if (km > 0.1) { + if (sum == 1) { + return rows.at(currentStep).inclination; + } return avg / (double)sum; } if (c == currentStep) @@ -325,10 +328,16 @@ double trainprogram::avgInclinationNext100Meters() { sum++; } else { + if (sum == 1) { + return rows.at(currentStep).inclination; + } return avg / (double)sum; } c++; } + if (sum == 1) { + return rows.at(currentStep).inclination; + } return avg / (double)sum; } From 751084d00a9a38607184a0583d7862964564f3ac Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 24 Oct 2022 21:22:19 +0200 Subject: [PATCH 137/255] yesoul target resistance fixed on zwift --- src/bluetooth.cpp | 3 ++- src/yesoulbike.cpp | 7 +++++-- src/yesoulbike.h | 5 ++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index f0a6a24e8..5778770d4 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -1431,7 +1431,8 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(sportsPlusBike); } else if (b.name().startsWith(yesoulbike::bluetoothName) && !yesoulBike && filter) { this->stopDiscovery(); - yesoulBike = new yesoulbike(noWriteResistance, noHeartService); + yesoulBike = new yesoulbike(noWriteResistance, noHeartService, bikeResistanceOffset, + bikeResistanceGain); // stateFileRead(); emit deviceConnected(b); connect(yesoulBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); diff --git a/src/yesoulbike.cpp b/src/yesoulbike.cpp index 0b0fde02a..aebd24a3a 100644 --- a/src/yesoulbike.cpp +++ b/src/yesoulbike.cpp @@ -12,12 +12,15 @@ using namespace std::chrono_literals; -yesoulbike::yesoulbike(bool noWriteResistance, bool noHeartService) { +yesoulbike::yesoulbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, + double bikeResistanceGain) { m_watt.setType(metric::METRIC_WATT); Speed.setType(metric::METRIC_SPEED); refresh = new QTimer(this); this->noWriteResistance = noWriteResistance; this->noHeartService = noHeartService; + this->bikeResistanceGain = bikeResistanceGain; + this->bikeResistanceOffset = bikeResistanceOffset; initDone = false; connect(refresh, &QTimer::timeout, this, &yesoulbike::update); refresh->start(200ms); @@ -272,7 +275,7 @@ void yesoulbike::stateChanged(QLowEnergyService::ServiceState state) { #endif if (virtual_device_enabled) { emit debug(QStringLiteral("creating virtual bike interface...")); - virtualBike = new virtualbike(this, noWriteResistance, noHeartService); + virtualBike = new virtualbike(this, noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); // connect(virtualBike,&virtualbike::debug ,this,&yesoulbike::debug); connect(virtualBike, &virtualbike::changeInclination, this, &yesoulbike::changeInclination); } diff --git a/src/yesoulbike.h b/src/yesoulbike.h index 3e4a5fc2e..f146e8db2 100644 --- a/src/yesoulbike.h +++ b/src/yesoulbike.h @@ -41,7 +41,8 @@ class yesoulbike : public bike { static constexpr uint16_t manufacturerDataId = 637; static constexpr const char* bluetoothName = "YESOUL"; - yesoulbike(bool noWriteResistance, bool noHeartService); + yesoulbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, + double bikeResistanceGain); bool connected(); void *VirtualBike(); @@ -75,6 +76,8 @@ class yesoulbike : public bike { bool noWriteResistance = false; bool noHeartService = false; + uint8_t bikeResistanceOffset = 4; + double bikeResistanceGain = 1.0; #ifdef Q_OS_IOS lockscreen *h = 0; From 1e3e3c645098232f51f05afc953d5bd9a9994911 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 24 Oct 2022 21:25:40 +0100 Subject: [PATCH 138/255] #1000 removed searchStopped check from virtual device setup --- src/kingsmithr1protreadmill.cpp | 2 +- src/kingsmithr2treadmill.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kingsmithr1protreadmill.cpp b/src/kingsmithr1protreadmill.cpp index 7833fe882..3f913401c 100644 --- a/src/kingsmithr1protreadmill.cpp +++ b/src/kingsmithr1protreadmill.cpp @@ -104,7 +104,7 @@ void kingsmithr1protreadmill::update() { QSettings settings; // ******************************************* virtual treadmill init ************************************* - if (!firstInit && searchStopped && !virtualTreadMill && !virtualBike) { + if (!firstInit && !virtualTreadMill && !virtualBike) { bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); bool virtual_device_force_bike = settings.value(QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike).toBool(); if (virtual_device_enabled) { diff --git a/src/kingsmithr2treadmill.cpp b/src/kingsmithr2treadmill.cpp index d841960d6..031d7d918 100644 --- a/src/kingsmithr2treadmill.cpp +++ b/src/kingsmithr2treadmill.cpp @@ -117,7 +117,7 @@ void kingsmithr2treadmill::update() { QSettings settings; // ******************************************* virtual treadmill init ************************************* - if (!firstInit && searchStopped && !virtualTreadMill && !virtualBike) { + if (!firstInit && !virtualTreadMill && !virtualBike) { bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); bool virtual_device_force_bike = settings.value(QZSettings::virtual_device_force_bike, QZSettings::default_virtual_device_force_bike).toBool(); if (virtual_device_enabled) { From 1f850463ceae1e0c1c41a3c9c28af625e87c1d38 Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 24 Oct 2022 20:54:50 +0100 Subject: [PATCH 139/255] #998 only attempt to set up virtual device on first update --- src/iconceptbike.cpp | 6 ++++-- src/iconceptbike.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/iconceptbike.cpp b/src/iconceptbike.cpp index 4f00cc380..098e6d913 100644 --- a/src/iconceptbike.cpp +++ b/src/iconceptbike.cpp @@ -78,15 +78,17 @@ void iconceptbike::update() { if (initDone) { // ******************************************* virtual treadmill init ************************************* - if (!virtualBike) { + if (!firstStateChanged && !virtualBike) { QSettings settings; bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); if (virtual_device_enabled) { - emit debug(QStringLiteral("creating virtual treadmill interface...")); + emit debug(QStringLiteral("creating virtual bike interface...")); virtualBike = new virtualbike(this, true); connect(virtualBike, &virtualbike::changeInclination, this, &iconceptbike::changeInclination); } } + firstStateChanged = 1; + // ******************************************************************************************************** if (requestResistance != -1) { diff --git a/src/iconceptbike.h b/src/iconceptbike.h index a2e8bd2fd..fe83873c2 100644 --- a/src/iconceptbike.h +++ b/src/iconceptbike.h @@ -56,6 +56,7 @@ class iconceptbike : public bike { QTimer *refresh; bool initDone = false; + uint8_t firstStateChanged = 0; uint16_t GetElapsedTimeFromPacket(const QByteArray &packet); uint16_t GetDistanceFromPacket(const QByteArray &packet); From 5d5dcf61666595dbf49e14cd2e173fc658dc0bd1 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 25 Oct 2022 14:24:45 +0200 Subject: [PATCH 140/255] Spirit XT385 not able to get working, Gets discovered but can't see Qdomyos in Zwift Discovery. #833 --- src/spirittreadmill.cpp | 37 ++++++++++++++++++++++++++++++++----- src/spirittreadmill.h | 3 +++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/spirittreadmill.cpp b/src/spirittreadmill.cpp index 6af867cf9..50ae3e50f 100644 --- a/src/spirittreadmill.cpp +++ b/src/spirittreadmill.cpp @@ -76,13 +76,32 @@ void spirittreadmill::forceIncline(double requestIncline) { if (XT385) { uint8_t increase[] = {0x5b, 0x04, 0x00, 0x06, 0x4f, 0x4b, 0x5d}; if (requestIncline > Inclination.value()) { + if (requestInclinationState == IDLE) + requestInclinationState = UP; + else if (requestInclinationState == DOWN) { + requestInclinationState = IDLE; + this->requestInclination = -100; + return; + } uint8_t increaseSpeed[] = {0x5b, 0x02, 0xF1, 0x04, 0x5d}; writeCharacteristic(increaseSpeed, sizeof(increaseSpeed), QStringLiteral("increaseIncline"), false, true); writeCharacteristic(increase, sizeof(increase), QStringLiteral("increaseIncline"), false, true); - } else { + + } else if (requestIncline < Inclination.value()) { + if (requestInclinationState == IDLE) + requestInclinationState = DOWN; + else if (requestInclinationState == UP) { + requestInclinationState = IDLE; + this->requestInclination = -100; + return; + } uint8_t decreaseSpeed[] = {0x5b, 0x02, 0xF1, 0x05, 0x5d}; writeCharacteristic(decreaseSpeed, sizeof(decreaseSpeed), QStringLiteral("decreaseIncline"), false, true); writeCharacteristic(increase, sizeof(increase), QStringLiteral("decreaseIncline"), false, true); + + } else { + this->requestInclination = -100; + requestInclinationState = IDLE; } } } @@ -153,11 +172,19 @@ void spirittreadmill::update() { requestSpeed = -1; } if (requestInclination != -100) { - if (requestInclination != currentInclination().value()) { - emit debug(QStringLiteral("writing incline ") + QString::number(requestInclination)); - forceIncline(requestInclination); + if (requestInclination < 0) + requestInclination = 0; + double inc = qRound(requestInclination / 0.5) * 0.5; + // this treadmill has 0.5% step inclination + if (inc != currentInclination().value() && inc >= 0 && inc <= 15) { + emit debug(QStringLiteral("writing incline ") + QString::number(inc)); + forceIncline(inc); + } else if (inc == currentInclination().value()) { + qDebug() << "int inclination match the current one" << inc << currentInclination().value(); + requestInclination = -100; } - requestInclination = -100; + // i have to do the reset on when the inclination is equal to the current + // requestInclination = -100; } if (requestStart != -1) { emit debug(QStringLiteral("starting...")); diff --git a/src/spirittreadmill.h b/src/spirittreadmill.h index 00f190d7a..e9d472125 100644 --- a/src/spirittreadmill.h +++ b/src/spirittreadmill.h @@ -74,6 +74,9 @@ class spirittreadmill : public treadmill { bool XT385 = false; bool XT485 = false; + enum _REQUEST_STATE { IDLE = 0, UP = 1, DOWN = 2 }; + _REQUEST_STATE requestInclinationState = IDLE; + signals: void disconnected(); void debug(QString string); From c8f719da19610007c1054dc768e7bc437652512e Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Tue, 25 Oct 2022 16:12:11 +0200 Subject: [PATCH 141/255] android version 2.11.82 --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 320ce4ca3..acbfc049a 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index 6352e565a..05b7ab07f 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.81" + text: "version 2.11.82" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index ba38a4b12..bb5601a4d 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.81 +VERSION = 2.11.82 From 75d70b87eeda95a0d4bb514159c2e960cc779e3a Mon Sep 17 00:00:00 2001 From: Bepo7012 <92673064+Bepo7012@users.noreply.github.com> Date: Tue, 25 Oct 2022 15:42:42 +0200 Subject: [PATCH 142/255] Update trainprogram.cpp Fix for INF Calculation in cagnulein#973 --- src/trainprogram.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index 728627b0d..1081c0d40 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -105,7 +105,7 @@ void trainprogram::applySpeedFilter() { ws = 1; if (we >= rows.length()) - we = (rows.length() - 1); + we = (rows.length() - 2); // Subtract 2 Points because duration is calculated with row+1! Fixes inf calculation in #973 int wc = 0; double wma = 0; int rowduration = 0; @@ -118,7 +118,8 @@ void trainprogram::applySpeedFilter() { else rowduration = ((QTime(0, 0, 0).secsTo(rows.at(currow).gpxElapsed)) - (QTime(0, 0, 0).secsTo(rows.at(currow - 1).gpxElapsed))); - wma += ((rows.at(currow).distance) / ((double)(rowduration)) * weight[wc]); + // generally avoid a devision by 0 or negative (who knows what's coming from gpx) + if (rowduration > 0) wma += ((rows.at(currow).distance) / ((double)(rowduration)) * weight[wc]); } // filtering starting point From 11171e8e03978ba0cbc1a84ee46cf81885b89f64 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 26 Oct 2022 08:27:38 +0200 Subject: [PATCH 143/255] Differences in the GPX starting point #988 --- src/trainprogram.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index 1081c0d40..e702d9967 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -105,7 +105,8 @@ void trainprogram::applySpeedFilter() { ws = 1; if (we >= rows.length()) - we = (rows.length() - 2); // Subtract 2 Points because duration is calculated with row+1! Fixes inf calculation in #973 + we = (rows.length() - + 2); // Subtract 2 Points because duration is calculated with row+1! Fixes inf calculation in #973 int wc = 0; double wma = 0; int rowduration = 0; @@ -119,7 +120,8 @@ void trainprogram::applySpeedFilter() { rowduration = ((QTime(0, 0, 0).secsTo(rows.at(currow).gpxElapsed)) - (QTime(0, 0, 0).secsTo(rows.at(currow - 1).gpxElapsed))); // generally avoid a devision by 0 or negative (who knows what's coming from gpx) - if (rowduration > 0) wma += ((rows.at(currow).distance) / ((double)(rowduration)) * weight[wc]); + if (rowduration > 0) + wma += ((rows.at(currow).distance) / ((double)(rowduration)) * weight[wc]); } // filtering starting point @@ -311,7 +313,6 @@ double trainprogram::avgInclinationNext100Meters() { double km = 0; double avg = 0; int sum = 0; - double startingAltitude = rows.at(currentStep).altitude; while (1) { if (c < rows.length()) { @@ -325,7 +326,7 @@ double trainprogram::avgInclinationNext100Meters() { km += (rows.at(c).distance - currentStepDistance); else km += (rows.at(c).distance); - avg += (rows.at(c).altitude - startingAltitude); + avg += rows.at(c).inclination; sum++; } else { From 0b6dacca2d4dbf4538f76f383e472ff4cc7dd41c Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 26 Oct 2022 08:28:11 +0200 Subject: [PATCH 144/255] version 2.11.83 --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index acbfc049a..256132262 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index 05b7ab07f..e6fbafacf 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.82" + text: "version 2.11.83" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index bb5601a4d..b751b7c98 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.82 +VERSION = 2.11.83 From 0c45f738e130c0e1a60321c5efe685a63e35e40c Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 26 Oct 2022 09:46:29 +0200 Subject: [PATCH 145/255] inCondi ET660i support #1007 --- src/bluetooth.cpp | 22 +- src/bluetooth.h | 4 +- src/mepanelbike.cpp | 491 ++++++++++++++++++++++++++++++++++++++++++ src/mepanelbike.h | 102 +++++++++ src/qdomyos-zwift.pro | 2 + 5 files changed, 618 insertions(+), 3 deletions(-) create mode 100644 src/mepanelbike.cpp create mode 100644 src/mepanelbike.h diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 5778770d4..1e7156510 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -1380,6 +1380,17 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { echelonConnectSport->deviceDiscovered(b); userTemplateManager->start(echelonConnectSport); innerTemplateManager->start(echelonConnectSport); + } else if (b.name().toUpper().startsWith(QStringLiteral("MEPANEL")) && !mepanelBike && filter) { + this->stopDiscovery(); + mepanelBike = + new mepanelbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); + // stateFileRead(); + emit deviceConnected(b); + connect(mepanelBike, &bluetoothdevice::connectedAndDiscovered, this, + &bluetooth::connectedAndDiscovered); + mepanelBike->deviceDiscovered(b); + userTemplateManager->start(mepanelBike); + innerTemplateManager->start(mepanelBike); } else if ((b.name().toUpper().startsWith(QStringLiteral("IC BIKE")) || (b.name().toUpper().startsWith(QStringLiteral("C7-")) && b.name().length() != 17) || b.name().toUpper().startsWith(QStringLiteral("C9/C10"))) && @@ -1431,8 +1442,8 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { innerTemplateManager->start(sportsPlusBike); } else if (b.name().startsWith(yesoulbike::bluetoothName) && !yesoulBike && filter) { this->stopDiscovery(); - yesoulBike = new yesoulbike(noWriteResistance, noHeartService, bikeResistanceOffset, - bikeResistanceGain); + yesoulBike = + new yesoulbike(noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); // stateFileRead(); emit deviceConnected(b); connect(yesoulBike, &bluetoothdevice::connectedAndDiscovered, this, &bluetooth::connectedAndDiscovered); @@ -2334,6 +2345,11 @@ void bluetooth::restart() { delete ultraSportBike; ultraSportBike = nullptr; } + if (mepanelBike) { + + delete mepanelBike; + mepanelBike = nullptr; + } if (echelonConnectSport) { delete echelonConnectSport; @@ -2643,6 +2659,8 @@ bluetoothdevice *bluetooth::device() { return shuaA5Treadmill; } else if (trueTreadmill) { return trueTreadmill; + } else if (mepanelBike) { + return mepanelBike; } else if (echelonConnectSport) { return echelonConnectSport; } else if (echelonRower) { diff --git a/src/bluetooth.h b/src/bluetooth.h index c403084f0..411c4c4dc 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -57,6 +57,7 @@ #include "kingsmithr2treadmill.h" #include "m3ibike.h" #include "mcfbike.h" +#include "mepanelbike.h" #include "nautilusbike.h" #include "nautiluselliptical.h" #include "nautilustreadmill.h" @@ -192,6 +193,7 @@ class bluetooth : public QObject, public SignalHandler { snodebike *snodeBike = nullptr; eslinkertreadmill *eslinkerTreadmill = nullptr; m3ibike *m3iBike = nullptr; + mepanelbike *mepanelBike = nullptr; skandikawiribike *skandikaWiriBike = nullptr; cscbike *cscBike = nullptr; mcfbike *mcfBike = nullptr; @@ -280,7 +282,7 @@ class bluetooth : public QObject, public SignalHandler { * @param b The bluetooth device info. */ void setLastBluetoothDevice(const QBluetoothDeviceInfo &b); -signals: + signals: void deviceConnected(QBluetoothDeviceInfo b); void deviceFound(QString name); void searchingStop(); diff --git a/src/mepanelbike.cpp b/src/mepanelbike.cpp new file mode 100644 index 000000000..efc219f06 --- /dev/null +++ b/src/mepanelbike.cpp @@ -0,0 +1,491 @@ +#include "mepanelbike.h" +#include "ios/lockscreen.h" +#include "keepawakehelper.h" +#include "virtualbike.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace std::chrono_literals; + +#ifdef Q_OS_IOS +extern quint8 QZ_EnableDiscoveryCharsAndDescripttors; +#endif + +mepanelbike::mepanelbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, + double bikeResistanceGain) { +#ifdef Q_OS_IOS + QZ_EnableDiscoveryCharsAndDescripttors = true; +#endif + m_watt.setType(metric::METRIC_WATT); + Speed.setType(metric::METRIC_SPEED); + refresh = new QTimer(this); + this->noWriteResistance = noWriteResistance; + this->noHeartService = noHeartService; + this->bikeResistanceGain = bikeResistanceGain; + this->bikeResistanceOffset = bikeResistanceOffset; + initDone = false; + connect(refresh, &QTimer::timeout, this, &mepanelbike::update); + refresh->start(200ms); +} + +void mepanelbike::writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log, + bool wait_for_response) { + QEventLoop loop; + QTimer timeout; + + // if there are some crash here, maybe it's better to use 2 separate event for the characteristicChanged. + // one for the resistance changed event (spontaneous), and one for the other ones. + if (wait_for_response) { + connect(gattCommunicationChannelService, &QLowEnergyService::characteristicChanged, &loop, &QEventLoop::quit); + timeout.singleShot(300ms, &loop, &QEventLoop::quit); + } else { + connect(gattCommunicationChannelService, &QLowEnergyService::characteristicWritten, &loop, &QEventLoop::quit); + timeout.singleShot(300ms, &loop, &QEventLoop::quit); + } + + if (gattCommunicationChannelService->state() != QLowEnergyService::ServiceState::ServiceDiscovered || + m_control->state() == QLowEnergyController::UnconnectedState) { + qDebug() << QStringLiteral("writeCharacteristic error because the connection is closed"); + return; + } + + if (!gattWriteCharacteristic.isValid()) { + qDebug() << QStringLiteral("gattWriteCharacteristic is invalid"); + return; + } + + gattCommunicationChannelService->writeCharacteristic(gattWriteCharacteristic, + QByteArray((const char *)data, data_len)); + + if (!disable_log) { + qDebug() << QStringLiteral(" >> ") + QByteArray((const char *)data, data_len).toHex(' ') + + QStringLiteral(" // ") + info; + } + + loop.exec(); +} + +void mepanelbike::forceResistance(resistance_t requestResistance) {} + +void mepanelbike::update() { + if (m_control->state() == QLowEnergyController::UnconnectedState) { + emit disconnected(); + return; + } + + if (initRequest) { + initRequest = false; + btinit(); + } else if (bluetoothDevice.isValid() && m_control->state() == QLowEnergyController::DiscoveredState && + gattCommunicationChannelService && gattWriteCharacteristic.isValid() && + gattNotify1Characteristic.isValid() && initDone) { + update_metrics(false, watts()); + + // sending poll every 2 seconds + if (sec1Update++ >= (2000 / refresh->interval())) { + sec1Update = 0; + + // updateDisplay(elapsed); + } + + if (requestResistance != -1) { + if (requestResistance > max_resistance) + requestResistance = max_resistance; + else if (requestResistance <= 0) + requestResistance = 1; + + if (requestResistance != currentResistance().value()) { + qDebug() << QStringLiteral("writing resistance ") + QString::number(requestResistance); + forceResistance(requestResistance); + } + requestResistance = -1; + } + if (requestStart != -1) { + qDebug() << QStringLiteral("starting..."); + + // btinit(); + + requestStart = -1; + emit bikeStarted(); + } + if (requestStop != -1) { + qDebug() << QStringLiteral("stopping..."); + // writeCharacteristic(initDataF0C800B8, sizeof(initDataF0C800B8), "stop tape"); + requestStop = -1; + } + } +} + +void mepanelbike::serviceDiscovered(const QBluetoothUuid &gatt) { + qDebug() << QStringLiteral("serviceDiscovered ") + gatt.toString(); +} + +void mepanelbike::characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue) { + // qDebug() << "characteristicChanged" << characteristic.uuid() << newValue << newValue.length(); + Q_UNUSED(characteristic); + QSettings settings; + bool disable_hr_frommachinery = + settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); + QString heartRateBeltName = + settings.value(QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name).toString(); + + qDebug() << " << " + newValue.toHex(' '); + + lastPacket = newValue; + + if (newValue.length() < 3) + return; + + QString str; + + switch ((uint8_t)newValue.at(0)) { + case 30: { + double intValue = (double)((double)(newValue.at(1) * 256) + (double)newValue.at(2)); + if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { + Speed = intValue; + } else { + Speed = metric::calculateSpeedFromPower( + watts(), Inclination.value(), Speed.value(), + fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + } + + break; + } + case 45: + if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) + .toString() + .startsWith(QStringLiteral("Disabled"))) { + Cadence = ((double)(newValue.at(1) * 256) + (double)newValue.at(2)); + } + break; + case 60: + // str = "RECEIVED_TIME,Min:" + newValue.at(1) + " Sec:" + newValue.at(2); + break; + case 75: + /* + double intValue2 = (double)((newValue.at(1).intValue() * 256) + newValue.at(2).intValue()); + Double.isNaN(intValue2); + str = "RECEIVED_DISTANCE," + (intValue2 / 10.0d);*/ + break; + case 90: + /* + double intValue3 = (double)((newValue.at(1).intValue() * 256) + newValue.at(2).intValue()); + Double.isNaN(intValue3); + str = "RECEIVED_CALORIES," + (intValue3 / 10.0d);*/ + break; + case 105: + m_watt = ((double)(newValue.at(1) * 256) + (double)newValue.at(2)); + break; + case 120: + if (!disable_hr_frommachinery) + Heart = newValue.at(1); + break; + case 135: + // str = "RECEIVED_FAT_CHECK"; + break; + case /*RECEIVED_HEART_REPLY*/ 150: + // str = "RECEIVED_HEART_REPLY"; + break; + case 165: + // str = "RECEIVED_ERROR"; + break; + case /*RECEIVED_REQUEST_PROGRAM*/ 180: + + break; + case /*RECEIVED_REQUEST_STATE*/ 195: + + break; + case /*RECEIVED_REQUEST_UNIT*/ 210: + /* + boolean z2 = newValue.at(1).intValue() == 0; + if (newValue.at(2).intValue() != 1) { + z = false; + } + str = "RECEIVED_REQUEST_UNIT,isInch:" + z2 + " isMale:" + z;*/ + break; + case /*RECEIVED_REQUEST_HEIGHT*/ 225: + // str = "RECEIVED_REQUEST_HEIGHT," + ((newValue.at(2).intValue() * 256) + newValue.at(1).intValue()); + break; + case /*RECEIVED_REQUEST_WEIGHT*/ 226: + // str = "RECEIVED_REQUEST_WEIGHT," + ((newValue.at(2).intValue() * 256) + newValue.at(1).intValue()); + break; + case /*RECEIVED_REQUEST_AGE*/ 227: + // str = "RECEIVED_REQUEST_AGE," + ((newValue.at(2).intValue() * 256) + newValue.at(1).intValue()); + break; + default: + str = ""; + break; + } + + // resistance value is in another frame + if (newValue.length() == 5 && ((unsigned char)newValue.at(0)) == 0xf0 && ((unsigned char)newValue.at(1)) == 0xd2) { + Resistance = newValue.at(3); + emit resistanceRead(Resistance.value()); + m_pelotonResistance = bikeResistanceToPeloton(Resistance.value()); + + qDebug() << QStringLiteral("Current resistance: ") + QString::number(Resistance.value()); + return; + } + + double distance = GetDistanceFromPacket(newValue); + + if (watts()) + KCal += + ((((0.048 * ((double)watts()) + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / + 200.0) / + (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( + QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in kg + //* 3.5) / 200 ) / 60 + Distance += ((Speed.value() / 3600000.0) * + ((double)lastRefreshCharacteristicChanged.msecsTo(QDateTime::currentDateTime()))); + + if (Cadence.value() > 0) { + CrankRevs++; + LastCrankEventTime += (uint16_t)(1024.0 / (((double)(Cadence.value())) / 60.0)); + } + + lastRefreshCharacteristicChanged = QDateTime::currentDateTime(); + +#ifdef Q_OS_ANDROID + if (settings.value(QZSettings::ant_heart, QZSettings::default_ant_heart).toBool() && disable_hr_frommachinery) { + Heart = (uint8_t)KeepAwakeHelper::heart(); + } else +#endif + { + if (heartRateBeltName.startsWith(QLatin1String("Disabled")) && disable_hr_frommachinery) { +#ifdef Q_OS_IOS +#ifndef IO_UNDER_QT + lockscreen h; + long appleWatchHeartRate = h.heartRate(); + h.setKcal(KCal.value()); + h.setDistance(Distance.value()); + Heart = appleWatchHeartRate; + qDebug() << "Current Heart from Apple Watch: " + QString::number(appleWatchHeartRate); +#endif +#endif + } + } + +#ifdef Q_OS_IOS +#ifndef IO_UNDER_QT + bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + if (ios_peloton_workaround && cadence && h && firstStateChanged) { + h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime()); + h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate()); + } +#endif +#endif + + // these useless lines are needed to calculate the AVG resistance and AVG peloton resistance since + // echelon just send the resistance values when it changes + Resistance = Resistance.value(); + m_pelotonResistance = m_pelotonResistance.value(); + + qDebug() << QStringLiteral("Current Local elapsed: ") + GetElapsedFromPacket(newValue).toString(); + qDebug() << QStringLiteral("Current Speed: ") + QString::number(Speed.value()); + qDebug() << QStringLiteral("Current Calculate Distance: ") + QString::number(Distance.value()); + qDebug() << QStringLiteral("Current Cadence: ") + QString::number(Cadence.value()); + qDebug() << QStringLiteral("Current Distance: ") + QString::number(distance); + qDebug() << QStringLiteral("Current CrankRevs: ") + QString::number(CrankRevs); + qDebug() << QStringLiteral("Last CrankEventTime: ") + QString::number(LastCrankEventTime); + qDebug() << QStringLiteral("Current Watt: ") + QString::number(watts()); + + if (m_control->error() != QLowEnergyController::NoError) { + qDebug() << QStringLiteral("QLowEnergyController ERROR!!") << m_control->errorString(); + } +} + +uint8_t mepanelbike::getCheckNum(uint8_t i, uint8_t i2) { return (i + i2); } + +void mepanelbike::btinit() { + uint8_t initData1[] = {0x1E, 0x11, 0x00, 0x00}; + initData1[3] = getCheckNum(initData1[1], initData1[2]); + writeCharacteristic(initData1, sizeof(initData1), QStringLiteral("init"), false, true); + + initDone = true; + + if (lastResistanceBeforeDisconnection != -1) { + qDebug() << QStringLiteral("forcing resistance to ") + QString::number(lastResistanceBeforeDisconnection) + + QStringLiteral(". It was the last value before the disconnection."); + forceResistance(lastResistanceBeforeDisconnection); + lastResistanceBeforeDisconnection = -1; + } +} + +void mepanelbike::stateChanged(QLowEnergyService::ServiceState state) { + QBluetoothUuid _gattWriteCharacteristicId(QStringLiteral("0000fff1-0000-1000-8000-00805f9b34fb")); + QBluetoothUuid _gattNotify1CharacteristicId(QStringLiteral("0000fff2-0000-1000-8000-00805f9b34fb")); + + QMetaEnum metaEnum = QMetaEnum::fromType(); + qDebug() << QStringLiteral("BTLE stateChanged ") + QString::fromLocal8Bit(metaEnum.valueToKey(state)); + + if (state == QLowEnergyService::ServiceDiscovered) { + // qDebug() << gattCommunicationChannelService->characteristics(); + + gattWriteCharacteristic = gattCommunicationChannelService->characteristic(_gattWriteCharacteristicId); + gattNotify1Characteristic = gattCommunicationChannelService->characteristic(_gattNotify1CharacteristicId); + Q_ASSERT(gattWriteCharacteristic.isValid()); + Q_ASSERT(gattNotify1Characteristic.isValid()); + + // establish hook into notifications + connect(gattCommunicationChannelService, &QLowEnergyService::characteristicChanged, this, + &mepanelbike::characteristicChanged); + connect(gattCommunicationChannelService, &QLowEnergyService::characteristicWritten, this, + &mepanelbike::characteristicWritten); + connect(gattCommunicationChannelService, + static_cast(&QLowEnergyService::error), + this, &mepanelbike::errorService); + connect(gattCommunicationChannelService, &QLowEnergyService::descriptorWritten, this, + &mepanelbike::descriptorWritten); + + // ******************************************* virtual bike init ************************************* + if (!firstStateChanged && !virtualBike +#ifdef Q_OS_IOS +#ifndef IO_UNDER_QT + && !h +#endif +#endif + ) { + QSettings settings; + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); +#ifdef Q_OS_IOS +#ifndef IO_UNDER_QT + bool cadence = + settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + if (ios_peloton_workaround && cadence) { + qDebug() << "ios_peloton_workaround activated!"; + h = new lockscreen(); + h->virtualbike_ios(); + } else +#endif +#endif + if (virtual_device_enabled) { + qDebug() << QStringLiteral("creating virtual bike interface..."); + virtualBike = + new virtualbike(this, noWriteResistance, noHeartService, bikeResistanceOffset, bikeResistanceGain); + // connect(virtualBike,&virtualbike::debug ,this,&mepanelbike::debug); + connect(virtualBike, &virtualbike::changeInclination, this, &mepanelbike::changeInclination); + } + } + firstStateChanged = 1; + // ******************************************************************************************************** + + QByteArray descriptor; + descriptor.append((char)0x01); + descriptor.append((char)0x00); + gattCommunicationChannelService->writeDescriptor( + gattNotify1Characteristic.descriptor(QBluetoothUuid::ClientCharacteristicConfiguration), descriptor); + } +} + +void mepanelbike::descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &newValue) { + qDebug() << QStringLiteral("descriptorWritten ") + descriptor.name() + QStringLiteral(" ") + newValue.toHex(' '); + + initRequest = true; + emit connectedAndDiscovered(); +} + +void mepanelbike::characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue) { + Q_UNUSED(characteristic); + qDebug() << QStringLiteral("characteristicWritten ") + newValue.toHex(' '); +} + +void mepanelbike::serviceScanDone(void) { + qDebug() << QStringLiteral("serviceScanDone"); + + QBluetoothUuid _gattCommunicationChannelServiceId(QStringLiteral("0000fff0-0000-1000-8000-00805f9b34fb")); + + gattCommunicationChannelService = m_control->createServiceObject(_gattCommunicationChannelServiceId); + connect(gattCommunicationChannelService, &QLowEnergyService::stateChanged, this, &mepanelbike::stateChanged); + gattCommunicationChannelService->discoverDetails(); +} + +void mepanelbike::errorService(QLowEnergyService::ServiceError err) { + QMetaEnum metaEnum = QMetaEnum::fromType(); + qDebug() << QStringLiteral("mepanelbike::errorService") + QString::fromLocal8Bit(metaEnum.valueToKey(err)) + + m_control->errorString(); +} + +void mepanelbike::error(QLowEnergyController::Error err) { + QMetaEnum metaEnum = QMetaEnum::fromType(); + qDebug() << QStringLiteral("mepanelbike::error") + QString::fromLocal8Bit(metaEnum.valueToKey(err)) + + m_control->errorString(); +} + +void mepanelbike::deviceDiscovered(const QBluetoothDeviceInfo &device) { + qDebug() << QStringLiteral("Found new device: ") + device.name() + QStringLiteral(" (") + + device.address().toString() + ')'; + { + bluetoothDevice = device; + + m_control = QLowEnergyController::createCentral(bluetoothDevice, this); + connect(m_control, &QLowEnergyController::serviceDiscovered, this, &mepanelbike::serviceDiscovered); + connect(m_control, &QLowEnergyController::discoveryFinished, this, &mepanelbike::serviceScanDone); + connect(m_control, + static_cast(&QLowEnergyController::error), + this, &mepanelbike::error); + connect(m_control, &QLowEnergyController::stateChanged, this, &mepanelbike::controllerStateChanged); + + connect(m_control, + static_cast(&QLowEnergyController::error), + this, [this](QLowEnergyController::Error error) { + Q_UNUSED(error); + Q_UNUSED(this); + qDebug() << QStringLiteral("Cannot connect to remote device."); + emit disconnected(); + }); + connect(m_control, &QLowEnergyController::connected, this, [this]() { + Q_UNUSED(this); + qDebug() << QStringLiteral("Controller connected. Search services..."); + m_control->discoverServices(); + }); + connect(m_control, &QLowEnergyController::disconnected, this, [this]() { + Q_UNUSED(this); + qDebug() << QStringLiteral("LowEnergy controller disconnected"); + emit disconnected(); + }); + + // Connect + m_control->connectToDevice(); + return; + } +} + +bool mepanelbike::connected() { + if (!m_control) { + return false; + } + return m_control->state() == QLowEnergyController::DiscoveredState; +} + +void *mepanelbike::VirtualBike() { return virtualBike; } + +void *mepanelbike::VirtualDevice() { return VirtualBike(); } + +uint16_t mepanelbike::watts() { + if (currentCadence().value() == 0) { + return 0; + } + return m_watt.value(); +} + +void mepanelbike::controllerStateChanged(QLowEnergyController::ControllerState state) { + qDebug() << QStringLiteral("controllerStateChanged") << state; + if (state == QLowEnergyController::UnconnectedState && m_control) { + lastResistanceBeforeDisconnection = Resistance.value(); + qDebug() << QStringLiteral("trying to connect back again..."); + initDone = false; + m_control->connectToDevice(); + } +} diff --git a/src/mepanelbike.h b/src/mepanelbike.h new file mode 100644 index 000000000..d83481dfc --- /dev/null +++ b/src/mepanelbike.h @@ -0,0 +1,102 @@ +#ifndef MEPANELBIKE_H +#define MEPANELBIKE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef Q_OS_ANDROID +#include +#else +#include +#endif +#include +#include +#include +#include + +#include +#include +#include + +#include "bike.h" +#include "virtualbike.h" + +#ifdef Q_OS_IOS +#include "ios/lockscreen.h" +#endif + +class mepanelbike : public bike { + Q_OBJECT + public: + mepanelbike(bool noWriteResistance, bool noHeartService, uint8_t bikeResistanceOffset, double bikeResistanceGain); + bool connected(); + + void *VirtualBike(); + void *VirtualDevice(); + + private: + const resistance_t max_resistance = 32; + void btinit(); + void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, + bool wait_for_response = false); + void startDiscover(); + void forceResistance(resistance_t requestResistance); + uint16_t watts(); + uint8_t getCheckNum(uint8_t i, uint8_t i2); + + QTimer *refresh; + virtualbike *virtualBike = nullptr; + + QLowEnergyService *gattCommunicationChannelService = nullptr; + QLowEnergyCharacteristic gattWriteCharacteristic; + QLowEnergyCharacteristic gattNotify1Characteristic; + + uint8_t bikeResistanceOffset = 4; + double bikeResistanceGain = 1.0; + uint8_t counterPoll = 1; + uint8_t sec1Update = 0; + QByteArray lastPacket; + QDateTime lastRefreshCharacteristicChanged = QDateTime::currentDateTime(); + uint8_t firstStateChanged = 0; + resistance_t lastResistanceBeforeDisconnection = -1; + + bool initDone = false; + bool initRequest = false; + + bool noWriteResistance = false; + bool noHeartService = false; + +#ifdef Q_OS_IOS + lockscreen *h = 0; +#endif + + Q_SIGNALS: + void disconnected(); + + public slots: + void deviceDiscovered(const QBluetoothDeviceInfo &device); + + private slots: + + void characteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue); + void characteristicWritten(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue); + void descriptorWritten(const QLowEnergyDescriptor &descriptor, const QByteArray &newValue); + void stateChanged(QLowEnergyService::ServiceState state); + void controllerStateChanged(QLowEnergyController::ControllerState state); + + void serviceDiscovered(const QBluetoothUuid &gatt); + void serviceScanDone(void); + void update(); + void error(QLowEnergyController::Error err); + void errorService(QLowEnergyService::ServiceError); +}; + +#endif // MEPANELBIKE_H diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index b751b7c98..88246d121 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -75,6 +75,7 @@ SOURCES += \ fakeelliptical.cpp \ faketreadmill.cpp \ kmlworkout.cpp \ + mepanelbike.cpp \ nautilusbike.cpp \ nordictrackelliptical.cpp \ nordictrackifitadbbike.cpp \ @@ -264,6 +265,7 @@ HEADERS += \ fakeelliptical.h \ faketreadmill.h \ kmlworkout.h \ + mepanelbike.h \ nautilusbike.h \ nordictrackelliptical.h \ nordictrackifitadbbike.h \ From 3f40f34982ba3f19c6c0ea59e056e368f02387e0 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 26 Oct 2022 10:23:51 +0200 Subject: [PATCH 146/255] build issues --- src/mepanelbike.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/mepanelbike.cpp b/src/mepanelbike.cpp index efc219f06..5875078f4 100644 --- a/src/mepanelbike.cpp +++ b/src/mepanelbike.cpp @@ -222,18 +222,6 @@ void mepanelbike::characteristicChanged(const QLowEnergyCharacteristic &characte break; } - // resistance value is in another frame - if (newValue.length() == 5 && ((unsigned char)newValue.at(0)) == 0xf0 && ((unsigned char)newValue.at(1)) == 0xd2) { - Resistance = newValue.at(3); - emit resistanceRead(Resistance.value()); - m_pelotonResistance = bikeResistanceToPeloton(Resistance.value()); - - qDebug() << QStringLiteral("Current resistance: ") + QString::number(Resistance.value()); - return; - } - - double distance = GetDistanceFromPacket(newValue); - if (watts()) KCal += ((((0.048 * ((double)watts()) + 1.19) * @@ -289,11 +277,9 @@ void mepanelbike::characteristicChanged(const QLowEnergyCharacteristic &characte Resistance = Resistance.value(); m_pelotonResistance = m_pelotonResistance.value(); - qDebug() << QStringLiteral("Current Local elapsed: ") + GetElapsedFromPacket(newValue).toString(); qDebug() << QStringLiteral("Current Speed: ") + QString::number(Speed.value()); qDebug() << QStringLiteral("Current Calculate Distance: ") + QString::number(Distance.value()); qDebug() << QStringLiteral("Current Cadence: ") + QString::number(Cadence.value()); - qDebug() << QStringLiteral("Current Distance: ") + QString::number(distance); qDebug() << QStringLiteral("Current CrankRevs: ") + QString::number(CrankRevs); qDebug() << QStringLiteral("Last CrankEventTime: ") + QString::number(LastCrankEventTime); qDebug() << QStringLiteral("Current Watt: ") + QString::number(watts()); From 25dc0efcb3a64d9aae1ae0207d87599ade673692 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 26 Oct 2022 14:26:05 +0200 Subject: [PATCH 147/255] Apple Watch Miles and Km conversion #1006 --- .../watchkit Extension/MainController.swift | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/watchkit Extension/MainController.swift b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/watchkit Extension/MainController.swift index b9049813f..40442a0ac 100644 --- a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/watchkit Extension/MainController.swift +++ b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/watchkit Extension/MainController.swift @@ -105,7 +105,11 @@ extension MainController: WorkoutTrackingDelegate { WorkoutTracking.distance = WatchKitConnection.distance WorkoutTracking.kcal = WatchKitConnection.kcal - self.distanceLabel.setText("Distance \(String(format:"%.2f", WorkoutTracking.distance))") + if Locale.current.measurementSystem != "Metric" { + self.distanceLabel.setText("Distance \(String(format:"%.2f", WorkoutTracking.distance))") + } else { + self.distanceLabel.setText("Distance \(String(format:"%.2f", WorkoutTracking.distance * 1.60934))") + } self.caloriesLabel.setText("KCal \(Int(WorkoutTracking.kcal))") //WorkoutTracking.cadenceSteps = pedometer. } @@ -123,3 +127,11 @@ extension MainController: WatchKitConnectionDelegate { userNameLabel.setText(userName) } } + +extension Locale +{ + var measurementSystem : String? + { + return (self as NSLocale).object(forKey: NSLocale.Key.measurementSystem) as? String + } +} From 922a2c31463fde3e2f3296747d8ea595d3733dc5 Mon Sep 17 00:00:00 2001 From: Bepo7012 <92673064+Bepo7012@users.noreply.github.com> Date: Wed, 26 Oct 2022 11:19:15 +0200 Subject: [PATCH 148/255] Added Debug for Video Jump Issues --- src/homeform.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/homeform.cpp b/src/homeform.cpp index df1ddbf83..ec32060b8 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -5262,10 +5262,11 @@ void homeform::changeTimestamp(QTime source, QTime actual) { auto *videoPlaybackHalf = rootObject->findChild(QStringLiteral("videoplaybackhalf")); auto videoPlaybackHalfPlayer = qvariant_cast(videoPlaybackHalf->property("mediaObject")); double videoTimeStampSeconds = (double)videoPlaybackHalfPlayer->position() / 1000.0; - // Check for time differences between V1ideo and gpx Data + // Check for time differences between Video and gpx Data if (videoTimeStampSeconds != 0.0) { double videoLengthSeconds = ((double)(videoPlaybackHalfPlayer->duration() / 1000.0)); double trainProgramLengthSeconds = ((double)(trainProgram->TotalGPXSecs())); + double playerTimeStampSeconds = videoTimeStampSeconds; // check if there is a difference >= 1 second if ((fabs(videoLengthSeconds - trainProgramLengthSeconds)) >= 1.0) { // correct Video TimeStamp by difference @@ -5276,6 +5277,7 @@ void homeform::changeTimestamp(QTime source, QTime actual) { if (videoTimeStampSeconds == 0.0) { videoTimeStampSeconds = ((double)(QTime(0, 0, 0).secsTo(source))); } + qDebug() << playerTimeStampSeconds << videoTimeStampSeconds; // Video was just displayed, set the start Position if (videoMustBeReset) { int videoStartPos = ((QTime(0, 0, 0).secsTo(source) + ((int)(videoLengthSeconds)) - @@ -5283,6 +5285,7 @@ void homeform::changeTimestamp(QTime source, QTime actual) { // if videoStartPos is negativ the Video is shorter then the GPX. Wait for the gpx to reach a point // where the Video can be played if (videoStartPos >= 0) { + qDebug() << "SetVideoStartPosition" << (videoStartPos * 1000); videoPlaybackHalfPlayer->setPosition(videoStartPos * 1000); videoTimeStampSeconds = (((double)(videoStartPos)) - videoLengthSeconds + trainProgramLengthSeconds); @@ -5297,6 +5300,14 @@ void homeform::changeTimestamp(QTime source, QTime actual) { bluetoothManager->device()->currentSpeed().average5s()); setVideoRate(rate); } + else + { + qDebug() << "videoMustBeReset = True"; + } + } + else + { + qDebug() << "videoTimeStampSeconds = 0"; } } From c4b1d4c7dfc7ed23f81d6c334d7f60363911d0a2 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 26 Oct 2022 15:13:22 +0200 Subject: [PATCH 149/255] fixing speed gain and offset to the calculateSpeedFromPower function --- src/metric.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/metric.cpp b/src/metric.cpp index 08f68ab2d..19e3104df 100644 --- a/src/metric.cpp +++ b/src/metric.cpp @@ -1,7 +1,7 @@ #include "metric.h" #include "qdebugfixup.h" -#include #include "qzsettings.h" +#include #ifdef TEST static uint32_t random_value_uint32 = 0; @@ -27,9 +27,9 @@ void metric::setValue(double v, bool applyGainAndOffset) { } if (settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble() < 0) { if (settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble() != 0.0) { - qDebug() << QStringLiteral("watt value was ") << v - << QStringLiteral("but it will be transformed to") - << v + settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble(); + qDebug() + << QStringLiteral("watt value was ") << v << QStringLiteral("but it will be transformed to") + << v + settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble(); } v += settings.value(QZSettings::watt_offset, QZSettings::default_watt_offset).toDouble(); } @@ -183,7 +183,8 @@ void metric::setLap(bool accumulator) { clearLap(accumulator); } double metric::calculateMaxSpeedFromPower(double power, double inclination) { QSettings settings; - double rolling_resistance = settings.value(QZSettings::rolling_resistance, QZSettings::default_rolling_resistance).toFloat(); + double rolling_resistance = + settings.value(QZSettings::rolling_resistance, QZSettings::default_rolling_resistance).toFloat(); double twt = 9.8 * (settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() + settings.value(QZSettings::bike_weight, QZSettings::default_bike_weight).toFloat()); double aero = 0.22691607640851885; @@ -214,7 +215,8 @@ double metric::calculateMaxSpeedFromPower(double power, double inclination) { double metric::calculatePowerFromSpeed(double speed, double inclination) { QSettings settings; - double rolling_resistance = settings.value(QZSettings::rolling_resistance, QZSettings::default_rolling_resistance).toFloat(); + double rolling_resistance = + settings.value(QZSettings::rolling_resistance, QZSettings::default_rolling_resistance).toFloat(); double v = speed / 3.6; // converted to m/s; double tv = v + 0; double tran = 0.95; @@ -226,22 +228,29 @@ double metric::calculatePowerFromSpeed(double speed, double inclination) { return (v * tr + v * tv * tv * A2Eff) / tran; } -double metric::calculateSpeedFromPower(double power, double inclination, double speed, double deltaTimeSeconds, double speedLimit) { +double metric::calculateSpeedFromPower(double power, double inclination, double speed, double deltaTimeSeconds, + double speedLimit) { QSettings settings; + double speed_gain = settings.value(QZSettings::speed_gain, QZSettings::default_speed_gain).toDouble(); + double speed_offset = settings.value(QZSettings::speed_offset, QZSettings::default_speed_offset).toDouble(); if (inclination < -5) inclination = -5; + if (speed_offset != QZSettings::default_speed_offset) + speed -= speed_offset; + if (speed_gain != QZSettings::default_speed_gain) + speed /= speed_gain; double fullWeight = (settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() + - settings.value(QZSettings::bike_weight, QZSettings::default_bike_weight).toFloat()); + settings.value(QZSettings::bike_weight, QZSettings::default_bike_weight).toFloat()); double maxSpeed = calculateMaxSpeedFromPower(power, inclination); double maxPowerFromSpeed = calculatePowerFromSpeed(speed, inclination); double acceleration = (power - maxPowerFromSpeed) / fullWeight; double newSpeed = speed + (acceleration * 3.6 * deltaTimeSeconds); - if(speedLimit > 0 && newSpeed > speedLimit) + if (speedLimit > 0 && newSpeed > speedLimit) newSpeed = speedLimit; - if(speedLimit > 0 && maxSpeed > speedLimit) + if (speedLimit > 0 && maxSpeed > speedLimit) maxSpeed = speedLimit; - if(newSpeed < 0) + if (newSpeed < 0) newSpeed = 0; if (maxSpeed > newSpeed) return newSpeed; From b80aac7c5ceb44070eee00cd56be6a46c0e07be3 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 26 Oct 2022 17:40:19 +0200 Subject: [PATCH 150/255] adding ECH-UK as another name of echelon stride --- src/bluetooth.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 1e7156510..451f887d1 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -1317,6 +1317,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { userTemplateManager->start(ftmsRower); innerTemplateManager->start(ftmsRower); } else if ((b.name().toUpper().startsWith(QLatin1String("ECH-STRIDE")) || + b.name().toUpper().startsWith(QLatin1String("ECH-UK-")) || b.name().toUpper().startsWith(QLatin1String("ECH-SD-SPT"))) && !echelonStride && filter) { this->stopDiscovery(); From 169753ab26e3341b164dce24b4a0978ed7106411 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 26 Oct 2022 18:26:09 +0200 Subject: [PATCH 151/255] iOS version 2.11.83 --- .../qdomyoszwift.xcodeproj/project.pbxproj | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj index 1b625ee79..13c852025 100644 --- a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj +++ b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj @@ -395,6 +395,8 @@ 87CC3B9E25A08812001EC5A8 /* moc_elliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87CC3B9C25A08812001EC5A8 /* moc_elliptical.cpp */; }; 87CC3BA325A0885F001EC5A8 /* domyoselliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87CC3B9F25A0885D001EC5A8 /* domyoselliptical.cpp */; }; 87CC3BA425A0885F001EC5A8 /* elliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87CC3BA025A0885D001EC5A8 /* elliptical.cpp */; }; + 87D10552290996EA00B3935B /* mepanelbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D10550290996EA00B3935B /* mepanelbike.cpp */; }; + 87D105542909971100B3935B /* moc_mepanelbike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D105532909971100B3935B /* moc_mepanelbike.cpp */; }; 87D2699F25F535200076AA48 /* m3ibike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D2699A25F535160076AA48 /* m3ibike.cpp */; }; 87D269A025F535200076AA48 /* skandikawiribike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D2699D25F535180076AA48 /* skandikawiribike.cpp */; }; 87D269A325F535340076AA48 /* moc_skandikawiribike.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87D269A125F535300076AA48 /* moc_skandikawiribike.cpp */; }; @@ -1187,6 +1189,9 @@ 87CC3BA025A0885D001EC5A8 /* elliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = elliptical.cpp; path = ../src/elliptical.cpp; sourceTree = ""; }; 87CC3BA125A0885E001EC5A8 /* elliptical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = elliptical.h; path = ../src/elliptical.h; sourceTree = ""; }; 87CC3BA225A0885E001EC5A8 /* domyoselliptical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = domyoselliptical.h; path = ../src/domyoselliptical.h; sourceTree = ""; }; + 87D10550290996EA00B3935B /* mepanelbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mepanelbike.cpp; path = ../src/mepanelbike.cpp; sourceTree = ""; }; + 87D10551290996EA00B3935B /* mepanelbike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mepanelbike.h; path = ../src/mepanelbike.h; sourceTree = ""; }; + 87D105532909971100B3935B /* moc_mepanelbike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_mepanelbike.cpp; sourceTree = ""; }; 87D2699925F535160076AA48 /* m3ibike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = m3ibike.h; path = ../src/m3ibike.h; sourceTree = ""; }; 87D2699A25F535160076AA48 /* m3ibike.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = m3ibike.cpp; path = ../src/m3ibike.cpp; sourceTree = ""; }; 87D2699C25F535170076AA48 /* skandikawiribike.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = skandikawiribike.h; path = ../src/skandikawiribike.h; sourceTree = ""; }; @@ -1632,6 +1637,7 @@ 25B08E2869634E9BCBA333A2 /* Generated Sources */ = { isa = PBXGroup; children = ( + 87D105532909971100B3935B /* moc_mepanelbike.cpp */, 872A20DB28C5F5CE0037774D /* moc_faketreadmill.cpp */, 878C9E6A28B77E9800669129 /* moc_nordictrackifitadbbike.cpp */, 872261EF289EA887006A6F75 /* moc_nordictrackelliptical.cpp */, @@ -1785,6 +1791,8 @@ 2EB56BE3C2D93CDAB0C52E67 /* Sources */ = { isa = PBXGroup; children = ( + 87D10550290996EA00B3935B /* mepanelbike.cpp */, + 87D10551290996EA00B3935B /* mepanelbike.h */, 87F527BC28EEB5AA00A9F8D5 /* qzsettings.cpp */, 87F527BD28EEB5AA00A9F8D5 /* qzsettings.h */, 872A20D928C5EC380037774D /* faketreadmill.cpp */, @@ -3072,6 +3080,7 @@ 873824BD27E64707004F1B46 /* moc_resolver_p.cpp in Compile Sources */, 876ED21A25C3E9010065F3DC /* moc_material.cpp in Compile Sources */, 87A4B76125AF27CB0027EF3C /* metric.cpp in Compile Sources */, + 87D10552290996EA00B3935B /* mepanelbike.cpp in Compile Sources */, 9D9484EED654597C394345DE /* moc_echelonconnectsport.cpp in Compile Sources */, 87DED80627D1273900BE4FBB /* filedownloader.cpp in Compile Sources */, 7DEEAF0C3D671FBFD84ACFCE /* moc_homeform.cpp in Compile Sources */, @@ -3083,6 +3092,7 @@ E62DA5FF2436135448C94671 /* moc_toorxtreadmill.cpp in Compile Sources */, 87586A4325B8341B00A243C4 /* moc_proformbike.cpp in Compile Sources */, 87CC3BA325A0885F001EC5A8 /* domyoselliptical.cpp in Compile Sources */, + 87D105542909971100B3935B /* moc_mepanelbike.cpp in Compile Sources */, 87B617F325F260150094A1CB /* moc_snodebike.cpp in Compile Sources */, 87DA8467284933DE00B550E9 /* moc_fakeelliptical.cpp in Compile Sources */, 87C5F0D726285E7E0067A1B5 /* moc_mimefile.cpp in Compile Sources */, @@ -3492,7 +3502,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.83; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = ( @@ -3660,7 +3670,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.83; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; @@ -3864,7 +3874,7 @@ CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.83; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -3956,7 +3966,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.83; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; @@ -4043,7 +4053,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.83; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; ENABLE_PREVIEWS = YES; @@ -4153,7 +4163,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.69; + CURRENT_PROJECT_VERSION = 2.11.83; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; From dacd6621a83b5bc4264a903bc9eea1915dca3579 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 28 Oct 2022 08:35:45 +0200 Subject: [PATCH 152/255] Differences in the GPX starting point #988 chartjs color typo --- src/inner_templates/googlemaps/chart.js | 4 ++-- src/proformwifibike.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/inner_templates/googlemaps/chart.js b/src/inner_templates/googlemaps/chart.js index a01b6601f..f9340e581 100644 --- a/src/inner_templates/googlemaps/chart.js +++ b/src/inner_templates/googlemaps/chart.js @@ -49,14 +49,14 @@ const data = { ctx.p1.parsed.y - ctx.p0.parsed.y< 5 ? window.chartColors.gold : ctx.p1.parsed.y - ctx.p0.parsed.y < 7 ? window.chartColors.orange : ctx.p1.parsed.y - ctx.p0.parsed.y < 9 ? window.chartColors.darkorange : - ctx.p1.parsed.y - ctx.p0.parsed.y < 1 ? window.chartColors.orangered : + ctx.p1.parsed.y - ctx.p0.parsed.y < 10 ? window.chartColors.orangered : window.chartColors.red, backgroundColor: ctx => ctx.p1.parsed.y - ctx.p0.parsed.y < 0 ? window.chartColors.green: ctx.p1.parsed.y - ctx.p0.parsed.y < 3 ? window.chartColors.limegreen : ctx.p1.parsed.y - ctx.p0.parsed.y< 5 ? window.chartColors.gold : ctx.p1.parsed.y - ctx.p0.parsed.y < 7 ? window.chartColors.orange : ctx.p1.parsed.y - ctx.p0.parsed.y < 9 ? window.chartColors.darkorange : - ctx.p1.parsed.y - ctx.p0.parsed.y < 1 ? window.chartColors.orangered : + ctx.p1.parsed.y - ctx.p0.parsed.y < 10 ? window.chartColors.orangered : window.chartColors.red, } }] diff --git a/src/proformwifibike.h b/src/proformwifibike.h index 2f4e510e9..098da5f98 100644 --- a/src/proformwifibike.h +++ b/src/proformwifibike.h @@ -58,7 +58,7 @@ class proformwifibike : public bike { private: QWebSocket websocket; resistance_t max_resistance = 100; - resistance_t min_resistance = -8; + resistance_t min_resistance = -20; void connectToDevice(); uint16_t wattsFromResistance(resistance_t resistance); double GetDistanceFromPacket(QByteArray packet); From 8beb57a7f89bb774aa6587a2f28e45bd711dc6ba Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 28 Oct 2022 08:36:35 +0200 Subject: [PATCH 153/255] preparing version 2.11.84 --- src/android/AndroidManifest.xml | 2 +- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 256132262..2ad04c966 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/main.qml b/src/main.qml index e6fbafacf..e713f761e 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.83" + text: "version 2.11.84" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index 88246d121..717d8b510 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -731,4 +731,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.83 +VERSION = 2.11.84 From 3b855e690a47b9ce09650a64cd7fee4d7d57d9da Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 28 Oct 2022 09:17:47 +0200 Subject: [PATCH 154/255] Differences in the GPX starting point (Issue #988) --- src/trainprogram.cpp | 49 ++++++++++++++++++++++++++++++++++++-------- src/trainprogram.h | 3 ++- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/trainprogram.cpp b/src/trainprogram.cpp index e702d9967..586905a2b 100644 --- a/src/trainprogram.cpp +++ b/src/trainprogram.cpp @@ -204,6 +204,36 @@ QList trainprogram::inclinationNext300Meters() { return next300; } +// meters, inclination +QList trainprogram::avgInclinationNext300Meters() { + int c = currentStep; + double km = 0; + QList next300; + + while (1) { + if (c < rows.length()) { + if (km > 0.3) { + return next300; + } + MetersByInclination p; + if (c == currentStep) { + p.meters = (rows.at(c).distance - currentStepDistance) * 1000.0; + km += (rows.at(c).distance - currentStepDistance); + } else { + p.meters = (rows.at(c).distance) * 1000.0; + km += (rows.at(c).distance); + } + p.inclination = avgInclinationNext100Meters(c); + next300.append(p); + + } else { + return next300; + } + c++; + } + return next300; +} + // speed in Km/h double trainprogram::avgSpeedFromGpxStep(int gpxStep, int seconds) { int start = gpxStep; @@ -308,8 +338,8 @@ double trainprogram::TimeRateFromGPX(double gpxsecs, double videosecs, double cu return rate; } -double trainprogram::avgInclinationNext100Meters() { - int c = currentStep; +double trainprogram::avgInclinationNext100Meters(int step) { + int c = step; double km = 0; double avg = 0; int sum = 0; @@ -419,13 +449,13 @@ void trainprogram::scheduler() { if (rows.at(0).inclination != -200) { double inc; if (!isnan(rows.at(0).latitude) && !isnan(rows.at(0).longitude)) { - inc = avgInclinationNext100Meters(); + inc = avgInclinationNext100Meters(currentStep); } else { inc = rows.at(0).inclination; } qDebug() << QStringLiteral("trainprogram change inclination") + QString::number(inc); emit changeInclination(inc, inc); - emit changeNextInclination300Meters(inclinationNext300Meters()); + emit changeNextInclination300Meters(avgInclinationNext300Meters()); } } else { if (rows.at(0).resistance != -1) { @@ -540,13 +570,13 @@ void trainprogram::scheduler() { if (rows.at(currentStep).inclination != -200) { double inc; if (!isnan(rows.at(currentStep).latitude) && !isnan(rows.at(currentStep).longitude)) { - inc = avgInclinationNext100Meters(); + inc = avgInclinationNext100Meters(currentStep); } else { inc = rows.at(currentStep).inclination; } qDebug() << QStringLiteral("trainprogram change inclination") + QString::number(inc); emit changeInclination(inc, inc); - emit changeNextInclination300Meters(inclinationNext300Meters()); + emit changeNextInclination300Meters(avgInclinationNext300Meters()); } } else { if (rows.at(currentStep).resistance != -1) { @@ -658,7 +688,7 @@ void trainprogram::scheduler() { if (rows.at(currentStep).inclination != -200 && (!isnan(rows.at(currentStep).latitude) && !isnan(rows.at(currentStep).longitude))) { - double inc = avgInclinationNext100Meters(); + double inc = avgInclinationNext100Meters(currentStep); double bikeResistanceOffset = settings.value(QZSettings::bike_resistance_offset, QZSettings::default_bike_resistance_offset) .toInt(); @@ -674,7 +704,10 @@ void trainprogram::scheduler() { } qDebug() << QStringLiteral("trainprogram change inclination due to gps") + QString::number(inc); emit changeInclination(inc, inc); - emit changeNextInclination300Meters(inclinationNext300Meters()); + if (bluetoothManager->device()->deviceType() == bluetoothdevice::TREADMILL) + emit changeNextInclination300Meters(avgInclinationNext300Meters()); + else + emit changeNextInclination300Meters(inclinationNext300Meters()); double ratioDistance = 0.0; double distanceRow = rows.at(currentStep).distance; diff --git a/src/trainprogram.h b/src/trainprogram.h index 7e31b6be0..0cd948d04 100644 --- a/src/trainprogram.h +++ b/src/trainprogram.h @@ -113,7 +113,8 @@ class trainprogram : public QObject { mutable QRecursiveMutex schedulerMutex; double avgAzimuthNext300Meters(); QList inclinationNext300Meters(); - double avgInclinationNext100Meters(); + QList avgInclinationNext300Meters(); + double avgInclinationNext100Meters(int step); uint32_t calculateTimeForRow(int32_t row); uint32_t calculateTimeForRowMergingRamps(int32_t row); double calculateDistanceForRow(int32_t row); From 059a38ebfdace48569283608e92a47dccb86f2b1 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 28 Oct 2022 09:57:13 +0200 Subject: [PATCH 155/255] fixing a problem with the speed based on power setting enabled if the wattage was evaluated after the speed in the bike module, the speed was always 0 --- src/bluetoothdevice.cpp | 15 ++++++++----- src/trxappgateusbbike.cpp | 47 ++++++++++++++++++++++----------------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/bluetoothdevice.cpp b/src/bluetoothdevice.cpp index b0e49456b..5d557d6b1 100644 --- a/src/bluetoothdevice.cpp +++ b/src/bluetoothdevice.cpp @@ -139,8 +139,10 @@ void bluetoothdevice::update_metrics(bool watt_calc, const double watts) { QDateTime current = QDateTime::currentDateTime(); double deltaTime = (((double)_lastTimeUpdate.msecsTo(current)) / ((double)1000.0)); QSettings settings; - bool power_as_bike = settings.value(QZSettings::power_sensor_as_bike, QZSettings::default_power_sensor_as_bike).toBool(); - bool power_as_treadmill = settings.value(QZSettings::power_sensor_as_treadmill, QZSettings::default_power_sensor_as_treadmill).toBool(); + bool power_as_bike = + settings.value(QZSettings::power_sensor_as_bike, QZSettings::default_power_sensor_as_bike).toBool(); + bool power_as_treadmill = + settings.value(QZSettings::power_sensor_as_treadmill, QZSettings::default_power_sensor_as_treadmill).toBool(); if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) .toString() @@ -149,7 +151,7 @@ void bluetoothdevice::update_metrics(bool watt_calc, const double watts) { watt_calc = false; if (!_firstUpdate && !paused) { - if (currentSpeed().value() > 0.0 || settings.value(QZSettings::continuous_moving, true).toBool()) { + if (currentSpeed().value() > 0.0 || settings.value(QZSettings::continuous_moving, true).toBool()) { elapsed += deltaTime; } @@ -164,10 +166,13 @@ void bluetoothdevice::update_metrics(bool watt_calc, const double watts) { WattKg = m_watt.value() / settings.value(QZSettings::weight, QZSettings::default_weight).toFloat(); } else if (m_watt.value() > 0) { - m_watt = 0; + if (watt_calc) { + m_watt = 0; + } WattKg = 0; } - } else if (paused && settings.value(QZSettings::instant_power_on_pause, QZSettings::default_instant_power_on_pause).toBool()) { + } else if (paused && settings.value(QZSettings::instant_power_on_pause, QZSettings::default_instant_power_on_pause) + .toBool()) { // useful for FTP test if (watt_calc) { m_watt = watts; diff --git a/src/trxappgateusbbike.cpp b/src/trxappgateusbbike.cpp index 3909cf358..5b244358c 100644 --- a/src/trxappgateusbbike.cpp +++ b/src/trxappgateusbbike.cpp @@ -259,10 +259,11 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch settings.value(QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1).toDouble())) / (settings.value(QZSettings::power_hr_hr2, QZSettings::default_power_hr_hr2).toDouble() - settings.value(QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1).toDouble()) + - (Heart.value() * ((settings.value(QZSettings::power_hr_pwr1, QZSettings::default_power_hr_pwr1).toDouble() - - settings.value(QZSettings::power_hr_pwr2, QZSettings::default_power_hr_pwr2).toDouble()) / - (settings.value(QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1).toDouble() - - settings.value(QZSettings::power_hr_hr2, QZSettings::default_power_hr_hr2).toDouble()))); + (Heart.value() * + ((settings.value(QZSettings::power_hr_pwr1, QZSettings::default_power_hr_pwr1).toDouble() - + settings.value(QZSettings::power_hr_pwr2, QZSettings::default_power_hr_pwr2).toDouble()) / + (settings.value(QZSettings::power_hr_hr1, QZSettings::default_power_hr_hr1).toDouble() - + settings.value(QZSettings::power_hr_hr2, QZSettings::default_power_hr_hr2).toDouble()))); if (Speed.value() > 0) { watt = avgP; } else { @@ -270,12 +271,13 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch } if (watt) - kcal = KCal.value() + ((((0.048 * ((double)watts()) + 1.19) * - settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / - 200.0) / - (60000.0 / ((double)lastTimeCharChanged.msecsTo( - QTime::currentTime())))); //(( (0.048* Output in watts +1.19) * - // body weight in kg * 3.5) / 200 ) / 60 + kcal = + KCal.value() + ((((0.048 * ((double)watts()) + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / + 200.0) / + (60000.0 / ((double)lastTimeCharChanged.msecsTo( + QTime::currentTime())))); //(( (0.048* Output in watts +1.19) * + // body weight in kg * 3.5) / 200 ) / 60 else kcal = KCal.value(); } @@ -294,7 +296,8 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch } else { heart = ((uint8_t)(newValue.at(17))) + (((uint8_t)(newValue.at(16))) * 83); } - if (heart == 0.0 || settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool()) { + if (heart == 0.0 || + settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool()) { #ifdef Q_OS_IOS #ifndef IO_UNDER_QT @@ -316,7 +319,8 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch #ifdef Q_OS_IOS #ifndef IO_UNDER_QT bool cad = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cad && h && firstVirtualBike) { h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime()); h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate()); @@ -329,18 +333,13 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch if (m_control->error() != QLowEnergyController::NoError) { qDebug() << QStringLiteral("QLowEnergyController ERROR!!") << m_control->errorString(); } - // moved up to have the Watt for the Speed calc - if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) - .toString() - .startsWith(QStringLiteral("Disabled"))) - m_watt = watt; if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { Speed = speed; } else { - Speed = - metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(), - fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower( + watts(), Inclination.value(), Speed.value(), + fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } if (!firstCharChanged) { Distance += ((Speed.value() / 3600.0) / (1000.0 / (lastTimeCharChanged.msecsTo(QTime::currentTime())))); @@ -352,6 +351,11 @@ void trxappgateusbbike::characteristicChanged(const QLowEnergyCharacteristic &ch Cadence = cadence; } + if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) + .toString() + .startsWith(QStringLiteral("Disabled"))) + m_watt = watt; + double ac = 0.01243107769; double bc = 1.145964912; double cc = -23.50977444; @@ -785,7 +789,8 @@ void trxappgateusbbike::stateChanged(QLowEnergyService::ServiceState state) { if (!firstVirtualBike && !virtualBike) { QSettings settings; - bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); if (virtual_device_enabled) { emit debug(QStringLiteral("creating virtual bike interface...")); From 9ee8dc44bd5af890aafb914a7566904ac048084e Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 28 Oct 2022 11:49:27 +0200 Subject: [PATCH 156/255] erg mode added to proformwifiibike --- src/proformwifibike.cpp | 46 ++++++++++++++++++++++++++++++++++------- src/proformwifibike.h | 1 + 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/proformwifibike.cpp b/src/proformwifibike.cpp index 1ed9c2a28..31bece574 100644 --- a/src/proformwifibike.cpp +++ b/src/proformwifibike.cpp @@ -35,9 +35,11 @@ proformwifibike::proformwifibike(bool noWriteResistance, bool noHeartService, ui connectToDevice(); }); + ergModeSupported = true; // IMPORTANT, only for this bike + connectToDevice(); - initRequest = true; + initRequest = true; // ******************************************* virtual bike init ************************************* if (!firstStateChanged && !virtualBike @@ -48,11 +50,14 @@ proformwifibike::proformwifibike(bool noWriteResistance, bool noHeartService, ui #endif ) { QSettings settings; - bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); #ifdef Q_OS_IOS #ifndef IO_UNDER_QT - bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool cadence = + settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence) { qDebug() << "ios_peloton_workaround activated!"; h = new lockscreen(); @@ -75,7 +80,9 @@ proformwifibike::proformwifibike(bool noWriteResistance, bool noHeartService, ui void proformwifibike::connectToDevice() { QSettings settings; // https://github.com/dawsontoth/zwifit/blob/e846501149a6c8fbb03af8d7b9eab20474624883/src/ifit.js - websocket.open(QUrl("ws://" + settings.value(QZSettings::proformtdf4ip, QZSettings::default_proformtdf4ip).toString() + "/control")); + websocket.open(QUrl("ws://" + + settings.value(QZSettings::proformtdf4ip, QZSettings::default_proformtdf4ip).toString() + + "/control")); } /* @@ -224,6 +231,20 @@ void proformwifibike::innerWriteResistance() { } requestResistance = -1; + if (requestPower > 0) { + QSettings settings; + double erg_filter_upper = + settings.value(QZSettings::zwift_erg_filter, QZSettings::default_zwift_erg_filter).toDouble(); + if (fabs(target_watts - requestPower) > erg_filter_upper) { + qDebug() << "change inclination due to request power = " << requestPower; + if (target_watts > requestPower) { + requestInclination = currentInclination().value() - 1; + } else { + requestInclination = currentInclination().value() + 1; + } + } + } + if (requestInclination != -100) { emit debug(QStringLiteral("writing inclination ") + QString::number(requestInclination)); forceResistance(requestInclination + gears()); // since this bike doesn't have the concept of resistance, @@ -341,7 +362,8 @@ void proformwifibike::characteristicChanged(const QString &newValue) { QSettings settings; QString heartRateBeltName = settings.value(QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name).toString(); - bool disable_hr_frommachinery = settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); + bool disable_hr_frommachinery = + settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); emit debug(QStringLiteral(" << ") + newValue); @@ -402,9 +424,16 @@ void proformwifibike::characteristicChanged(const QString &newValue) { emit debug(QStringLiteral("Current Inclination: ") + QString::number(incline)); } + if (!values[QStringLiteral("Target Watts")].isUndefined()) { + double watt = values[QStringLiteral("Target Watts")].toString().toDouble(); + target_watts = watt; + emit debug(QStringLiteral("Target Watts: ") + QString::number(watts())); + } + if (watts()) KCal += - ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / + ((((0.048 * ((double)watts()) + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / 200.0) / (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in kg @@ -445,7 +474,8 @@ void proformwifibike::characteristicChanged(const QString &newValue) { #ifdef Q_OS_IOS #ifndef IO_UNDER_QT bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence && h && firstStateChanged) { h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime()); h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate()); diff --git a/src/proformwifibike.h b/src/proformwifibike.h index 098da5f98..566bfc4ef 100644 --- a/src/proformwifibike.h +++ b/src/proformwifibike.h @@ -83,6 +83,7 @@ class proformwifibike : public bike { QDateTime lastRefreshCharacteristicChanged = QDateTime::currentDateTime(); uint8_t firstStateChanged = 0; uint16_t m_watts = 0; + double target_watts = 0; bool initDone = false; bool initRequest = false; From daeaa90a79842f5d368ad66e4b6a944b24f3438c Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 28 Oct 2022 14:43:43 +0200 Subject: [PATCH 157/255] optimizing bluetooth traffic over fitmetria --- src/fitmetria_fanfit.cpp | 117 +++++++++++++++++++++++++-------------- src/fitmetria_fanfit.h | 4 +- 2 files changed, 77 insertions(+), 44 deletions(-) diff --git a/src/fitmetria_fanfit.cpp b/src/fitmetria_fanfit.cpp index 7110e710a..1a5b210ea 100644 --- a/src/fitmetria_fanfit.cpp +++ b/src/fitmetria_fanfit.cpp @@ -9,9 +9,7 @@ using namespace std::chrono_literals; -fitmetria_fanfit::fitmetria_fanfit(bluetoothdevice *parentDevice) { - this->parentDevice = parentDevice; -} +fitmetria_fanfit::fitmetria_fanfit(bluetoothdevice *parentDevice) { this->parentDevice = parentDevice; } void fitmetria_fanfit::update() {} @@ -47,7 +45,7 @@ void fitmetria_fanfit::fanSpeedRequest(uint8_t speed) { const uint8_t brightness = 5; const uint8_t leds_max = 15; - uint8_t leds[leds_max] = {30,30,30,15,15,15,13,24,24,8,27,27,27,26,26}; + uint8_t leds[leds_max] = {30, 30, 30, 15, 15, 15, 13, 24, 24, 8, 27, 27, 27, 26, 26}; // 0~5~30~30~30~15~15~15~13~24~24~8~27~27~27~26~26 // 0 - fans peed // 1 - brightness @@ -88,52 +86,85 @@ void fitmetria_fanfit::fanSpeedRequest(uint8_t speed) { myCollorDict['Yellow'] = 31 */ - QString s = QString::number((speed16)) + - "~" + QString::number(brightness); + QString s = QString::number((speed16)) + "~" + QString::number(brightness); - if(!settings.value(QZSettings::fitmetria_fanfit_mode, QZSettings::default_fitmetria_fanfit_mode) - .toString() - .compare(QStringLiteral("Power")) && parentDevice) { + if (!settings.value(QZSettings::fitmetria_fanfit_mode, QZSettings::default_fitmetria_fanfit_mode) + .toString() + .compare(QStringLiteral("Power")) && + parentDevice) { double ftp = parentDevice->currentPowerZone().value(); - if(ftp < 1.3) memset(&leds[1], 0, leds_max - 1); - else if(ftp < 1.6) memset(&leds[2], 0, leds_max - 2); - else if(ftp < 2) memset(&leds[3], 0, leds_max - 3); - else if(ftp < 2.4) memset(&leds[4], 0, leds_max - 4); - else if(ftp < 3) memset(&leds[5], 0, leds_max - 5); - else if(ftp < 3.3) memset(&leds[6], 0, leds_max - 6); - else if(ftp < 3.6) memset(&leds[7], 0, leds_max - 7); - else if(ftp < 4) memset(&leds[8], 0, leds_max - 8); - else if(ftp < 5) memset(&leds[9], 0, leds_max - 9); - else if(ftp < 5.6) memset(&leds[10], 0, leds_max - 10); - else if(ftp < 6) memset(&leds[11], 0, leds_max - 11); - else if(ftp < 6.6) memset(&leds[12], 0, leds_max - 12); - else if(ftp < 7) memset(&leds[13], 0, leds_max - 13); - else if(ftp < 7.1) memset(&leds[14], 0, leds_max - 14); - } else if(!settings.value(QZSettings::fitmetria_fanfit_mode, QZSettings::default_fitmetria_fanfit_mode) - .toString() - .compare(QStringLiteral("Heart")) && parentDevice) { + if (ftp < 1.3) + memset(&leds[1], 0, leds_max - 1); + else if (ftp < 1.6) + memset(&leds[2], 0, leds_max - 2); + else if (ftp < 2) + memset(&leds[3], 0, leds_max - 3); + else if (ftp < 2.4) + memset(&leds[4], 0, leds_max - 4); + else if (ftp < 3) + memset(&leds[5], 0, leds_max - 5); + else if (ftp < 3.3) + memset(&leds[6], 0, leds_max - 6); + else if (ftp < 3.6) + memset(&leds[7], 0, leds_max - 7); + else if (ftp < 4) + memset(&leds[8], 0, leds_max - 8); + else if (ftp < 5) + memset(&leds[9], 0, leds_max - 9); + else if (ftp < 5.6) + memset(&leds[10], 0, leds_max - 10); + else if (ftp < 6) + memset(&leds[11], 0, leds_max - 11); + else if (ftp < 6.6) + memset(&leds[12], 0, leds_max - 12); + else if (ftp < 7) + memset(&leds[13], 0, leds_max - 13); + else if (ftp < 7.1) + memset(&leds[14], 0, leds_max - 14); + } else if (!settings.value(QZSettings::fitmetria_fanfit_mode, QZSettings::default_fitmetria_fanfit_mode) + .toString() + .compare(QStringLiteral("Heart")) && + parentDevice) { double ftp = parentDevice->currentHeartZone().value(); - if(ftp < 1.3) memset(&leds[1], 0, leds_max - 1); - else if(ftp < 1.6) memset(&leds[2], 0, leds_max - 2); - else if(ftp < 1.9) memset(&leds[3], 0, leds_max - 3); - else if(ftp < 2) memset(&leds[4], 0, leds_max - 4); - else if(ftp < 2.3) memset(&leds[5], 0, leds_max - 5); - else if(ftp < 2.6) memset(&leds[6], 0, leds_max - 6); - else if(ftp < 2.9) memset(&leds[7], 0, leds_max - 7); - else if(ftp < 3.3) memset(&leds[8], 0, leds_max - 8); - else if(ftp < 3.6) memset(&leds[9], 0, leds_max - 9); - else if(ftp < 4) memset(&leds[10], 0, leds_max - 10); - else if(ftp < 4.3) memset(&leds[11], 0, leds_max - 11); - else if(ftp < 4.9) memset(&leds[12], 0, leds_max - 12); - else if(ftp < 5) memset(&leds[13], 0, leds_max - 13); - else if(ftp < 5.1) memset(&leds[14], 0, leds_max - 14); + if (ftp < 1.3) + memset(&leds[1], 0, leds_max - 1); + else if (ftp < 1.6) + memset(&leds[2], 0, leds_max - 2); + else if (ftp < 1.9) + memset(&leds[3], 0, leds_max - 3); + else if (ftp < 2) + memset(&leds[4], 0, leds_max - 4); + else if (ftp < 2.3) + memset(&leds[5], 0, leds_max - 5); + else if (ftp < 2.6) + memset(&leds[6], 0, leds_max - 6); + else if (ftp < 2.9) + memset(&leds[7], 0, leds_max - 7); + else if (ftp < 3.3) + memset(&leds[8], 0, leds_max - 8); + else if (ftp < 3.6) + memset(&leds[9], 0, leds_max - 9); + else if (ftp < 4) + memset(&leds[10], 0, leds_max - 10); + else if (ftp < 4.3) + memset(&leds[11], 0, leds_max - 11); + else if (ftp < 4.9) + memset(&leds[12], 0, leds_max - 12); + else if (ftp < 5) + memset(&leds[13], 0, leds_max - 13); + else if (ftp < 5.1) + memset(&leds[14], 0, leds_max - 14); } else { memset(&leds, 0, leds_max); } - for(int i=0;icreateServiceObject(_gattCommunicationChannelServiceId); connect(gattCommunicationChannelService, &QLowEnergyService::stateChanged, this, &fitmetria_fanfit::stateChanged); gattCommunicationChannelService->discoverDetails(); + + lastValueSent = ""; } void fitmetria_fanfit::errorService(QLowEnergyService::ServiceError err) { diff --git a/src/fitmetria_fanfit.h b/src/fitmetria_fanfit.h index 4046ee238..ad2165458 100644 --- a/src/fitmetria_fanfit.h +++ b/src/fitmetria_fanfit.h @@ -1,7 +1,6 @@ #ifndef FITMETRIA_FANFIT_H #define FITMETRIA_FANFIT_H - #include #include #include @@ -36,13 +35,14 @@ class fitmetria_fanfit : public bluetoothdevice { private: QLowEnergyService *gattCommunicationChannelService = nullptr; - //QLowEnergyCharacteristic gattNotifyCharacteristic; + // QLowEnergyCharacteristic gattNotifyCharacteristic; QLowEnergyCharacteristic gattWriteCharacteristic; void writeCharacteristic(uint8_t *data, uint8_t data_len, const QString &info, bool disable_log = false, bool wait_for_response = false); bluetoothdevice *parentDevice = nullptr; + QString lastValueSent = ""; signals: void disconnected(); From ba8eddea486b619994c4ea0c77841e3ab039ad39 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 28 Oct 2022 14:53:48 +0200 Subject: [PATCH 158/255] proformwifibike: send only 0.5 inclination --- src/proformwifibike.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/proformwifibike.cpp b/src/proformwifibike.cpp index 31bece574..d2d9cb3de 100644 --- a/src/proformwifibike.cpp +++ b/src/proformwifibike.cpp @@ -207,7 +207,8 @@ uint16_t proformwifibike::wattsFromResistance(resistance_t resistance) { void proformwifibike::forceResistance(resistance_t requestResistance) { - QString send = "{\"type\":\"set\",\"values\":{\"Incline\":\"" + QString::number(requestResistance) + "\"}}"; + double inc = qRound(requestResistance / 0.5) * 0.5; + QString send = "{\"type\":\"set\",\"values\":{\"Incline\":\"" + QString::number(inc) + "\"}}"; qDebug() << "forceResistance" << send; websocket.sendTextMessage(send); } From 085377ed901b2157b21e5027092a6260dd7ecb11 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Fri, 28 Oct 2022 23:46:43 +0200 Subject: [PATCH 159/255] ios dircon permission fixed #1011 --- .../qdomyoszwift.xcodeproj/project.pbxproj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj index 13c852025..ddd99b724 100644 --- a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj +++ b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj @@ -3502,7 +3502,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.83; + CURRENT_PROJECT_VERSION = 2.11.84; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = ( @@ -3670,7 +3670,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.83; + CURRENT_PROJECT_VERSION = 2.11.84; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; @@ -3874,7 +3874,7 @@ CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.83; + CURRENT_PROJECT_VERSION = 2.11.84; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -3966,7 +3966,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.83; + CURRENT_PROJECT_VERSION = 2.11.84; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; @@ -4053,7 +4053,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.83; + CURRENT_PROJECT_VERSION = 2.11.84; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; ENABLE_PREVIEWS = YES; @@ -4163,7 +4163,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.83; + CURRENT_PROJECT_VERSION = 2.11.84; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; From 2f7d5c76244aad579fa057fa20ecc19165aeeea7 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Mon, 31 Oct 2022 11:05:59 +0100 Subject: [PATCH 160/255] new raspberry install #1014 --- src/qdomyos-zwift.pro | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index 717d8b510..ab517f5f2 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -74,7 +74,6 @@ SOURCES += \ characteristicnotifier2ad9.cpp \ fakeelliptical.cpp \ faketreadmill.cpp \ - kmlworkout.cpp \ mepanelbike.cpp \ nautilusbike.cpp \ nordictrackelliptical.cpp \ @@ -264,7 +263,6 @@ HEADERS += \ definitions.h \ fakeelliptical.h \ faketreadmill.h \ - kmlworkout.h \ mepanelbike.h \ nautilusbike.h \ nordictrackelliptical.h \ From 6e2747e50afa57f2fddf2a4183072e9b065d7af9 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 2 Nov 2022 08:42:55 +0100 Subject: [PATCH 161/255] inCondi ET660i support #1007 --- src/mepanelbike.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mepanelbike.cpp b/src/mepanelbike.cpp index 5875078f4..ff22d1ed2 100644 --- a/src/mepanelbike.cpp +++ b/src/mepanelbike.cpp @@ -147,7 +147,7 @@ void mepanelbike::characteristicChanged(const QLowEnergyCharacteristic &characte case 30: { double intValue = (double)((double)(newValue.at(1) * 256) + (double)newValue.at(2)); if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { - Speed = intValue; + Speed = intValue / 100.0; } else { Speed = metric::calculateSpeedFromPower( watts(), Inclination.value(), Speed.value(), From d044800e0b30404c9bd89484793fb586a61fa977 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 2 Nov 2022 14:36:43 +0100 Subject: [PATCH 162/255] Preset resistance tiles #493 --- src/Home.qml | 4 + src/homeform.cpp | 47 +++- src/homeform.h | 7 +- src/qzsettings.cpp | 47 +++- src/qzsettings.h | 45 ++++ src/settings-tiles.qml | 528 ++++++++++++++++++++++++++++++++++++++++- src/settings.qml | 17 ++ 7 files changed, 680 insertions(+), 15 deletions(-) diff --git a/src/Home.qml b/src/Home.qml index e1b8671a7..0a17e662f 100644 --- a/src/Home.qml +++ b/src/Home.qml @@ -251,6 +251,10 @@ HomeForm{ onClicked: largeButton_clicked(objectName) visible: largeButton anchors.fill: rect + background: Rectangle { + color: largeButtonColor + radius: 20 + } font.pointSize: 16 * settings.ui_zoom / 100 //width: 48 * settings.ui_zoom / 100 //height: 48 * settings.ui_zoom / 100 diff --git a/src/homeform.cpp b/src/homeform.cpp index ec32060b8..c3dbd4647 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -62,7 +62,7 @@ using namespace std::chrono_literals; DataObject::DataObject(const QString &name, const QString &icon, const QString &value, bool writable, const QString &id, int valueFontSize, int labelFontSize, const QString &valueFontColor, const QString &secondLine, - const int gridId, bool largeButton, QString largeButtonLabel) { + const int gridId, bool largeButton, QString largeButtonLabel, QString largeButtonColor) { m_name = name; m_icon = icon; m_value = value; @@ -75,12 +75,14 @@ DataObject::DataObject(const QString &name, const QString &icon, const QString & m_gridId = gridId; m_largeButton = largeButton; m_largeButtonLabel = largeButtonLabel; + m_largeButtonColor = largeButtonColor; emit plusNameChanged(plusName()); // NOTE: clazy-incorrecrt-emit emit minusNameChanged(minusName()); // NOTE: clazy-incorrecrt-emit emit identificatorChanged(identificator()); emit largeButtonChanged(this->largeButton()); emit largeButtonLabelChanged(this->largeButtonLabel()); + emit largeButtonColorChanged(this->largeButtonColor()); } void DataObject::setName(const QString &v) { @@ -256,76 +258,101 @@ homeform::homeform(QQmlApplicationEngine *engine, bluetooth *bl) { "", "", "", false, QStringLiteral("preset_resistance_1"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_resistance_1_label, QZSettings::default_tile_preset_resistance_1_label) + .toString(), + settings.value(QZSettings::tile_preset_resistance_1_color, QZSettings::default_tile_preset_resistance_1_color) .toString()); preset_resistance_2 = new DataObject( "", "", "", false, QStringLiteral("preset_resistance_2"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_resistance_2_label, QZSettings::default_tile_preset_resistance_2_label) + .toString(), + settings.value(QZSettings::tile_preset_resistance_2_color, QZSettings::default_tile_preset_resistance_2_color) .toString()); preset_resistance_3 = new DataObject( "", "", "", false, QStringLiteral("preset_resistance_3"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_resistance_3_label, QZSettings::default_tile_preset_resistance_3_label) + .toString(), + settings.value(QZSettings::tile_preset_resistance_3_color, QZSettings::default_tile_preset_resistance_3_color) .toString()); preset_resistance_4 = new DataObject( "", "", "", false, QStringLiteral("preset_resistance_4"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_resistance_4_label, QZSettings::default_tile_preset_resistance_4_label) + .toString(), + settings.value(QZSettings::tile_preset_resistance_4_color, QZSettings::default_tile_preset_resistance_4_color) .toString()); preset_resistance_5 = new DataObject( "", "", "", false, QStringLiteral("preset_resistance_5"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_resistance_5_label, QZSettings::default_tile_preset_resistance_5_label) + .toString(), + settings.value(QZSettings::tile_preset_resistance_5_color, QZSettings::default_tile_preset_resistance_5_color) .toString()); preset_speed_1 = new DataObject( "", "", "", false, QStringLiteral("preset_speed_1"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, - settings.value(QZSettings::tile_preset_speed_1_label, QZSettings::default_tile_preset_speed_1_label) + settings.value(QZSettings::tile_preset_speed_1_label, QZSettings::default_tile_preset_speed_1_label).toString(), + settings.value(QZSettings::tile_preset_speed_1_color, QZSettings::default_tile_preset_speed_1_color) .toString()); preset_speed_2 = new DataObject( "", "", "", false, QStringLiteral("preset_speed_2"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, - settings.value(QZSettings::tile_preset_speed_2_label, QZSettings::default_tile_preset_speed_2_label) + settings.value(QZSettings::tile_preset_speed_2_label, QZSettings::default_tile_preset_speed_2_label).toString(), + settings.value(QZSettings::tile_preset_speed_2_color, QZSettings::default_tile_preset_speed_2_color) .toString()); preset_speed_3 = new DataObject( "", "", "", false, QStringLiteral("preset_speed_3"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, - settings.value(QZSettings::tile_preset_speed_3_label, QZSettings::default_tile_preset_speed_3_label) + settings.value(QZSettings::tile_preset_speed_3_label, QZSettings::default_tile_preset_speed_3_label).toString(), + settings.value(QZSettings::tile_preset_speed_3_color, QZSettings::default_tile_preset_speed_3_color) .toString()); preset_speed_4 = new DataObject( "", "", "", false, QStringLiteral("preset_speed_4"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, - settings.value(QZSettings::tile_preset_speed_4_label, QZSettings::default_tile_preset_speed_4_label) + settings.value(QZSettings::tile_preset_speed_4_label, QZSettings::default_tile_preset_speed_4_label).toString(), + settings.value(QZSettings::tile_preset_speed_4_color, QZSettings::default_tile_preset_speed_4_color) .toString()); preset_speed_5 = new DataObject( "", "", "", false, QStringLiteral("preset_speed_5"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, - settings.value(QZSettings::tile_preset_speed_5_label, QZSettings::default_tile_preset_speed_5_label) + settings.value(QZSettings::tile_preset_speed_5_label, QZSettings::default_tile_preset_speed_5_label).toString(), + settings.value(QZSettings::tile_preset_speed_5_color, QZSettings::default_tile_preset_speed_5_color) .toString()); preset_inclination_1 = new DataObject( "", "", "", false, QStringLiteral("preset_inclination_1"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_inclination_1_label, QZSettings::default_tile_preset_inclination_1_label) + .toString(), + settings.value(QZSettings::tile_preset_inclination_1_color, QZSettings::default_tile_preset_inclination_1_color) .toString()); preset_inclination_2 = new DataObject( "", "", "", false, QStringLiteral("preset_inclination_2"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_inclination_2_label, QZSettings::default_tile_preset_inclination_2_label) + .toString(), + settings.value(QZSettings::tile_preset_inclination_2_color, QZSettings::default_tile_preset_inclination_2_color) .toString()); preset_inclination_3 = new DataObject( "", "", "", false, QStringLiteral("preset_inclination_3"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_inclination_3_label, QZSettings::default_tile_preset_inclination_3_label) + .toString(), + settings.value(QZSettings::tile_preset_inclination_3_color, QZSettings::default_tile_preset_inclination_3_color) .toString()); preset_inclination_4 = new DataObject( "", "", "", false, QStringLiteral("preset_inclination_4"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_inclination_4_label, QZSettings::default_tile_preset_inclination_4_label) + .toString(), + settings.value(QZSettings::tile_preset_inclination_4_color, QZSettings::default_tile_preset_inclination_4_color) .toString()); preset_inclination_5 = new DataObject( "", "", "", false, QStringLiteral("preset_inclination_5"), 48, labelFontSize, QStringLiteral("white"), QLatin1String(""), 0, true, settings.value(QZSettings::tile_preset_inclination_5_label, QZSettings::default_tile_preset_inclination_5_label) + .toString(), + settings.value(QZSettings::tile_preset_inclination_5_color, QZSettings::default_tile_preset_inclination_5_color) .toString()); if (!settings.value(QZSettings::top_bar_enabled, QZSettings::default_top_bar_enabled).toBool()) { @@ -5299,14 +5326,10 @@ void homeform::changeTimestamp(QTime source, QTime actual) { videoTimeStampSeconds, bluetoothManager->device()->currentSpeed().average5s()); setVideoRate(rate); - } - else - { + } else { qDebug() << "videoMustBeReset = True"; } - } - else - { + } else { qDebug() << "videoTimeStampSeconds = 0"; } } diff --git a/src/homeform.h b/src/homeform.h index 053f65a50..230b11c3b 100644 --- a/src/homeform.h +++ b/src/homeform.h @@ -36,6 +36,7 @@ class DataObject : public QObject { Q_PROPERTY(bool writable READ writable NOTIFY writableChanged) Q_PROPERTY(bool visibleItem READ visibleItem NOTIFY visibleChanged) Q_PROPERTY(bool largeButton READ largeButton NOTIFY largeButtonChanged) + Q_PROPERTY(QString largeButtonColor READ largeButtonColor NOTIFY largeButtonColorChanged) Q_PROPERTY(QString largeButtonLabel READ largeButtonLabel NOTIFY largeButtonLabelChanged) Q_PROPERTY(QString plusName READ plusName NOTIFY plusNameChanged) Q_PROPERTY(QString minusName READ minusName NOTIFY minusNameChanged) @@ -45,7 +46,8 @@ class DataObject : public QObject { DataObject(const QString &name, const QString &icon, const QString &value, bool writable, const QString &id, int valueFontSize, int labelFontSize, const QString &valueFontColor = QStringLiteral("white"), const QString &secondLine = QLatin1String(""), const int gridId = 0, const bool largeButton = false, - const QString largeButtonLabel = QLatin1String("")); + const QString largeButtonLabel = QLatin1String(""), + const QString largeButtonColor = QZSettings::default_tile_preset_resistance_1_color); void setName(const QString &value); void setValue(const QString &value); void setSecondLine(const QString &value); @@ -69,6 +71,7 @@ class DataObject : public QObject { QString identificator() { return m_id; } bool largeButton() { return m_largeButton; } QString largeButtonLabel() { return m_largeButtonLabel; } + QString largeButtonColor() { return m_largeButtonColor; } QString m_id; QString m_name; @@ -83,6 +86,7 @@ class DataObject : public QObject { bool m_visible = true; bool m_largeButton = false; QString m_largeButtonLabel = QLatin1String(""); + QString m_largeButtonColor = QZSettings::default_tile_preset_resistance_1_color; signals: void valueChanged(QString value); @@ -100,6 +104,7 @@ class DataObject : public QObject { void identificatorChanged(QString value); void largeButtonChanged(bool value); void largeButtonLabelChanged(QString value); + void largeButtonColorChanged(QString value); }; class homeform : public QObject { diff --git a/src/qzsettings.cpp b/src/qzsettings.cpp index 5a9fdb7d9..fc6cf2612 100644 --- a/src/qzsettings.cpp +++ b/src/qzsettings.cpp @@ -516,8 +516,38 @@ const QString QZSettings::tile_preset_inclination_5_order = QStringLiteral("tile const QString QZSettings::tile_preset_inclination_5_value = QStringLiteral("tile_preset_inclination_5_value"); const QString QZSettings::tile_preset_inclination_5_label = QStringLiteral("tile_preset_inclination_5_label"); const QString QZSettings::default_tile_preset_inclination_5_label = QStringLiteral("4%"); +const QString QZSettings::tile_preset_resistance_1_color = QStringLiteral("tile_preset_resistance_1_color"); +const QString QZSettings::default_tile_preset_resistance_1_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_resistance_2_color = QStringLiteral("tile_preset_resistance_2_color"); +const QString QZSettings::default_tile_preset_resistance_2_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_resistance_3_color = QStringLiteral("tile_preset_resistance_3_color"); +const QString QZSettings::default_tile_preset_resistance_3_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_resistance_4_color = QStringLiteral("tile_preset_resistance_4_color"); +const QString QZSettings::default_tile_preset_resistance_4_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_resistance_5_color = QStringLiteral("tile_preset_resistance_5_color"); +const QString QZSettings::default_tile_preset_resistance_5_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_speed_1_color = QStringLiteral("tile_preset_speed_1_color"); +const QString QZSettings::default_tile_preset_speed_1_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_speed_2_color = QStringLiteral("tile_preset_speed_2_color"); +const QString QZSettings::default_tile_preset_speed_2_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_speed_3_color = QStringLiteral("tile_preset_speed_3_color"); +const QString QZSettings::default_tile_preset_speed_3_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_speed_4_color = QStringLiteral("tile_preset_speed_4_color"); +const QString QZSettings::default_tile_preset_speed_4_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_speed_5_color = QStringLiteral("tile_preset_speed_5_color"); +const QString QZSettings::default_tile_preset_speed_5_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_inclination_1_color = QStringLiteral("tile_preset_inclination_1_color"); +const QString QZSettings::default_tile_preset_inclination_1_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_inclination_2_color = QStringLiteral("tile_preset_inclination_2_color"); +const QString QZSettings::default_tile_preset_inclination_2_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_inclination_3_color = QStringLiteral("tile_preset_inclination_3_color"); +const QString QZSettings::default_tile_preset_inclination_3_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_inclination_4_color = QStringLiteral("tile_preset_inclination_4_color"); +const QString QZSettings::default_tile_preset_inclination_4_color = QStringLiteral("grey"); +const QString QZSettings::tile_preset_inclination_5_color = QStringLiteral("tile_preset_inclination_5_color"); +const QString QZSettings::default_tile_preset_inclination_5_color = QStringLiteral("grey"); -const uint32_t allSettingsCount = 430; +const uint32_t allSettingsCount = 445; QVariant allSettings[allSettingsCount][2] = { {QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles}, {QZSettings::bluetooth_no_reconnection, QZSettings::default_bluetooth_no_reconnection}, @@ -951,6 +981,21 @@ QVariant allSettings[allSettingsCount][2] = { {QZSettings::tile_preset_inclination_5_order, QZSettings::default_tile_preset_inclination_5_order}, {QZSettings::tile_preset_inclination_5_value, QZSettings::default_tile_preset_inclination_5_value}, {QZSettings::tile_preset_inclination_5_label, QZSettings::default_tile_preset_inclination_5_label}, + {QZSettings::tile_preset_resistance_1_color, QZSettings::default_tile_preset_resistance_1_color}, + {QZSettings::tile_preset_resistance_2_color, QZSettings::default_tile_preset_resistance_2_color}, + {QZSettings::tile_preset_resistance_3_color, QZSettings::default_tile_preset_resistance_3_color}, + {QZSettings::tile_preset_resistance_4_color, QZSettings::default_tile_preset_resistance_4_color}, + {QZSettings::tile_preset_resistance_5_color, QZSettings::default_tile_preset_resistance_5_color}, + {QZSettings::tile_preset_speed_1_color, QZSettings::default_tile_preset_speed_1_color}, + {QZSettings::tile_preset_speed_2_color, QZSettings::default_tile_preset_speed_2_color}, + {QZSettings::tile_preset_speed_3_color, QZSettings::default_tile_preset_speed_3_color}, + {QZSettings::tile_preset_speed_4_color, QZSettings::default_tile_preset_speed_4_color}, + {QZSettings::tile_preset_speed_5_color, QZSettings::default_tile_preset_speed_5_color}, + {QZSettings::tile_preset_inclination_1_color, QZSettings::default_tile_preset_inclination_1_color}, + {QZSettings::tile_preset_inclination_2_color, QZSettings::default_tile_preset_inclination_2_color}, + {QZSettings::tile_preset_inclination_3_color, QZSettings::default_tile_preset_inclination_3_color}, + {QZSettings::tile_preset_inclination_4_color, QZSettings::default_tile_preset_inclination_4_color}, + {QZSettings::tile_preset_inclination_5_color, QZSettings::default_tile_preset_inclination_5_color}, }; void QZSettings::qDebugAllSettings(bool showDefaults) { diff --git a/src/qzsettings.h b/src/qzsettings.h index 914e0e581..4a1bee726 100644 --- a/src/qzsettings.h +++ b/src/qzsettings.h @@ -1516,6 +1516,51 @@ class QZSettings { static const QString tile_preset_inclination_5_label; static const QString default_tile_preset_inclination_5_label; + static const QString tile_preset_resistance_1_color; + static const QString default_tile_preset_resistance_1_color; + + static const QString tile_preset_resistance_2_color; + static const QString default_tile_preset_resistance_2_color; + + static const QString tile_preset_resistance_3_color; + static const QString default_tile_preset_resistance_3_color; + + static const QString tile_preset_resistance_4_color; + static const QString default_tile_preset_resistance_4_color; + + static const QString tile_preset_resistance_5_color; + static const QString default_tile_preset_resistance_5_color; + + static const QString tile_preset_speed_1_color; + static const QString default_tile_preset_speed_1_color; + + static const QString tile_preset_speed_2_color; + static const QString default_tile_preset_speed_2_color; + + static const QString tile_preset_speed_3_color; + static const QString default_tile_preset_speed_3_color; + + static const QString tile_preset_speed_4_color; + static const QString default_tile_preset_speed_4_color; + + static const QString tile_preset_speed_5_color; + static const QString default_tile_preset_speed_5_color; + + static const QString tile_preset_inclination_1_color; + static const QString default_tile_preset_inclination_1_color; + + static const QString tile_preset_inclination_2_color; + static const QString default_tile_preset_inclination_2_color; + + static const QString tile_preset_inclination_3_color; + static const QString default_tile_preset_inclination_3_color; + + static const QString tile_preset_inclination_4_color; + static const QString default_tile_preset_inclination_4_color; + + static const QString tile_preset_inclination_5_color; + static const QString default_tile_preset_inclination_5_color; + /** * @brief Write the QSettings values using the constants from this namespace. * @param showDefaults Optionally indicates if the default should be shown with the key. diff --git a/src/settings-tiles.qml b/src/settings-tiles.qml index 009ac7e45..3c46820e0 100644 --- a/src/settings-tiles.qml +++ b/src/settings-tiles.qml @@ -1,4 +1,5 @@ import QtQuick 2.7 +import QtQuick.Dialogs 1.0 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.15 import QtQuick.Controls.Material 2.0 @@ -165,6 +166,21 @@ ScrollView { property int tile_preset_inclination_5_order: 47 property real tile_preset_inclination_5_value: 4.0 property string tile_preset_inclination_5_label: "4%" + property string tile_preset_resistance_1_color: "grey" + property string tile_preset_resistance_2_color: "grey" + property string tile_preset_resistance_3_color: "grey" + property string tile_preset_resistance_4_color: "grey" + property string tile_preset_resistance_5_color: "grey" + property string tile_preset_speed_1_color: "grey" + property string tile_preset_speed_2_color: "grey" + property string tile_preset_speed_3_color: "grey" + property string tile_preset_speed_4_color: "grey" + property string tile_preset_speed_5_color: "grey" + property string tile_preset_inclination_1_color: "grey" + property string tile_preset_inclination_2_color: "grey" + property string tile_preset_inclination_3_color: "grey" + property string tile_preset_inclination_4_color: "grey" + property string tile_preset_inclination_5_color: "grey" } @@ -1678,6 +1694,40 @@ ScrollView { onClicked: settings.tile_preset_resistance_1_label = presetResistance1LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetResistance1Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetResistance1 + title: "Please choose a color" + onAccepted: { + presetResistance1ColorTextField.text = colorPresetResistance1.color + } + onRejected: { + + } + } + TextField { + id: presetResistance1ColorTextField + text: settings.tile_preset_resistance_1_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetResistance1.visible = true + } + } + Button { + id: okPresetResistance1ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_1_color = presetResistance1ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -1753,6 +1803,40 @@ ScrollView { onClicked: settings.tile_preset_resistance_2_label = presetResistance2LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetResistance2Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetResistance2 + title: "Please choose a color" + onAccepted: { + presetResistance2ColorTextField.text = colorPresetResistance2.color + } + onRejected: { + + } + } + TextField { + id: presetResistance2ColorTextField + text: settings.tile_preset_resistance_2_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetResistance2.visible = true + } + } + Button { + id: okPresetResistance2ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_2_color = presetResistance2ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -1828,6 +1912,40 @@ ScrollView { onClicked: settings.tile_preset_resistance_3_label = presetResistance3LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetResistance3Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetResistance3 + title: "Please choose a color" + onAccepted: { + presetResistance3ColorTextField.text = colorPresetResistance3.color + } + onRejected: { + + } + } + TextField { + id: presetResistance3ColorTextField + text: settings.tile_preset_resistance_3_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetResistance3.visible = true + } + } + Button { + id: okPresetResistance3ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_3_color = presetResistance3ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -1903,6 +2021,40 @@ ScrollView { onClicked: settings.tile_preset_resistance_4_label = presetResistance4LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetResistance4Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetResistance4 + title: "Please choose a color" + onAccepted: { + presetResistance4ColorTextField.text = colorPresetResistance4.color + } + onRejected: { + + } + } + TextField { + id: presetResistance4ColorTextField + text: settings.tile_preset_resistance_4_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetResistance4.visible = true + } + } + Button { + id: okPresetResistance4ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_4_color = presetResistance4ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -1978,6 +2130,40 @@ ScrollView { onClicked: settings.tile_preset_resistance_5_label = presetResistance5LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetResistance5Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetResistance5 + title: "Please choose a color" + onAccepted: { + presetResistance5ColorTextField.text = colorPresetResistance5.color + } + onRejected: { + + } + } + TextField { + id: presetResistance5ColorTextField + text: settings.tile_preset_resistance_5_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetResistance5.visible = true + } + } + Button { + id: okPresetResistance5ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_resistance_5_color = presetResistance5ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -2053,6 +2239,40 @@ ScrollView { onClicked: settings.tile_preset_speed_1_label = presetSpeed1LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetSpeed1Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetSpeed1 + title: "Please choose a color" + onAccepted: { + presetSpeed1ColorTextField.text = colorPresetSpeed1.color + } + onRejected: { + + } + } + TextField { + id: presetSpeed1ColorTextField + text: settings.tile_preset_speed_1_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetSpeed1.visible = true + } + } + Button { + id: okPresetSpeed1ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_1_color = presetSpeed1ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -2128,6 +2348,40 @@ ScrollView { onClicked: settings.tile_preset_speed_2_label = presetSpeed2LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetSpeed2Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetSpeed2 + title: "Please choose a color" + onAccepted: { + presetSpeed2ColorTextField.text = colorPresetSpeed2.color + } + onRejected: { + + } + } + TextField { + id: presetSpeed2ColorTextField + text: settings.tile_preset_speed_2_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetSpeed2.visible = true + } + } + Button { + id: okPresetSpeed2ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_2_color = presetSpeed2ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -2203,6 +2457,40 @@ ScrollView { onClicked: settings.tile_preset_speed_3_label = presetSpeed3LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetSpeed3Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetSpeed3 + title: "Please choose a color" + onAccepted: { + presetSpeed3ColorTextField.text = colorPresetSpeed3.color + } + onRejected: { + + } + } + TextField { + id: presetSpeed3ColorTextField + text: settings.tile_preset_speed_3_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetSpeed3.visible = true + } + } + Button { + id: okPresetSpeed3ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_3_color = presetSpeed3ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -2278,6 +2566,40 @@ ScrollView { onClicked: settings.tile_preset_speed_4_label = presetSpeed4LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetSpeed4Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetSpeed4 + title: "Please choose a color" + onAccepted: { + presetSpeed4ColorTextField.text = colorPresetSpeed4.color + } + onRejected: { + + } + } + TextField { + id: presetSpeed4ColorTextField + text: settings.tile_preset_speed_4_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetSpeed4.visible = true + } + } + Button { + id: okPresetSpeed4ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_4_color = presetSpeed4ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -2353,6 +2675,40 @@ ScrollView { onClicked: settings.tile_preset_speed_5_label = presetSpeed5LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetSpeed5Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetSpeed5 + title: "Please choose a color" + onAccepted: { + presetSpeed5ColorTextField.text = colorPresetSpeed5.color + } + onRejected: { + + } + } + TextField { + id: presetSpeed5ColorTextField + text: settings.tile_preset_speed_5_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetSpeed5.visible = true + } + } + Button { + id: okPresetSpeed5ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_speed_5_color = presetSpeed5ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -2428,6 +2784,40 @@ ScrollView { onClicked: settings.tile_preset_inclination_1_label = presetInclination1LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetInclination1Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetInclination1 + title: "Please choose a color" + onAccepted: { + presetInclination1ColorTextField.text = colorPresetInclination1.color + } + onRejected: { + + } + } + TextField { + id: presetInclination1ColorTextField + text: settings.tile_preset_inclination_1_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetInclination1.visible = true + } + } + Button { + id: okPresetInclination1ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_1_color = presetInclination1ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -2504,6 +2894,40 @@ ScrollView { } } } + RowLayout { + Label { + id: labelPresetInclination2Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetInclination2 + title: "Please choose a color" + onAccepted: { + presetInclination2ColorTextField.text = colorPresetInclination2.color + } + onRejected: { + + } + } + TextField { + id: presetInclination2ColorTextField + text: settings.tile_preset_inclination_2_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetInclination2.visible = true + } + } + Button { + id: okPresetInclination2ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_2_color = presetInclination2ColorTextField.displayText + } + } } AccordionCheckElement { id: presetInclination3EnabledAccordion @@ -2578,6 +3002,40 @@ ScrollView { onClicked: settings.tile_preset_inclination_3_label = presetInclination3LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetInclination3Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetInclination3 + title: "Please choose a color" + onAccepted: { + presetInclination3ColorTextField.text = colorPresetInclination3.color + } + onRejected: { + + } + } + TextField { + id: presetInclination3ColorTextField + text: settings.tile_preset_inclination_3_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetInclination3.visible = true + } + } + Button { + id: okPresetInclination3ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_3_color = presetInclination3ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -2652,7 +3110,41 @@ ScrollView { Layout.alignment: Qt.AlignRight | Qt.AlignVCenter onClicked: settings.tile_preset_inclination_4_label = presetInclination4LabelTextField.displayText } - } + } + RowLayout { + Label { + id: labelPresetInclination4Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetInclination4 + title: "Please choose a color" + onAccepted: { + presetInclination4ColorTextField.text = colorPresetInclination4.color + } + onRejected: { + + } + } + TextField { + id: presetInclination4ColorTextField + text: settings.tile_preset_inclination_4_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetInclination4.visible = true + } + } + Button { + id: okPresetInclination4ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_4_color = presetInclination4ColorTextField.displayText + } + } } } AccordionCheckElement { @@ -2728,6 +3220,40 @@ ScrollView { onClicked: settings.tile_preset_inclination_5_label = presetInclination5LabelTextField.displayText } } + RowLayout { + Label { + id: labelPresetInclination5Color + text: qsTr("color:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ColorDialog { + id: colorPresetInclination5 + title: "Please choose a color" + onAccepted: { + presetInclination5ColorTextField.text = colorPresetInclination5.color + } + onRejected: { + + } + } + TextField { + id: presetInclination5ColorTextField + text: settings.tile_preset_inclination_5_color + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActiveFocusChanged: if(this.focus) this.cursorPosition = this.text.length + onPressed: { + colorPresetInclination5.visible = true + } + } + Button { + id: okPresetInclination5ColorButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_preset_inclination_5_color = presetInclination5ColorTextField.displayText + } + } } } } diff --git a/src/settings.qml b/src/settings.qml index 3cec68919..83309cea5 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -551,6 +551,23 @@ import Qt.labs.settings 1.0 property int tile_preset_inclination_5_order: 47 property real tile_preset_inclination_5_value: 4.0 property string tile_preset_inclination_5_label: "4%" + + // from version 2.11.85 + property string tile_preset_resistance_1_color: "grey" + property string tile_preset_resistance_2_color: "grey" + property string tile_preset_resistance_3_color: "grey" + property string tile_preset_resistance_4_color: "grey" + property string tile_preset_resistance_5_color: "grey" + property string tile_preset_speed_1_color: "grey" + property string tile_preset_speed_2_color: "grey" + property string tile_preset_speed_3_color: "grey" + property string tile_preset_speed_4_color: "grey" + property string tile_preset_speed_5_color: "grey" + property string tile_preset_inclination_1_color: "grey" + property string tile_preset_inclination_2_color: "grey" + property string tile_preset_inclination_3_color: "grey" + property string tile_preset_inclination_4_color: "grey" + property string tile_preset_inclination_5_color: "grey" // from version ? property bool trixter_xdream_v1_bike: false From be037d8fdfac7a88da8844039c3c26c37b132574 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 2 Nov 2022 15:03:48 +0100 Subject: [PATCH 163/255] AVG Watts per Lap #1009 --- src/homeform.cpp | 27 +++++++++++++++++++++++++++ src/homeform.h | 1 + src/qzsettings.cpp | 6 +++++- src/qzsettings.h | 6 ++++++ src/settings-tiles.qml | 36 +++++++++++++++++++++++++++++++++++- src/settings.qml | 3 +++ 6 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/homeform.cpp b/src/homeform.cpp index c3dbd4647..c7f755ab1 100644 --- a/src/homeform.cpp +++ b/src/homeform.cpp @@ -193,6 +193,8 @@ homeform::homeform(QQmlApplicationEngine *engine, bluetooth *bl) { QStringLiteral("weight_loss"), 48, labelFontSize); avgWatt = new DataObject(QStringLiteral("AVG Watt"), QStringLiteral("icons/icons/watt.png"), QStringLiteral("0"), false, QStringLiteral("avgWatt"), 48, labelFontSize); + avgWattLap = new DataObject(QStringLiteral("AVG Watt Lap"), QStringLiteral("icons/icons/watt.png"), + QStringLiteral("0"), false, QStringLiteral("avgWattLap"), 48, labelFontSize); wattKg = new DataObject(QStringLiteral("Watt/Kg"), QStringLiteral("icons/icons/watt.png"), QStringLiteral("0"), false, QStringLiteral("watt_kg"), 48, labelFontSize); ftp = new DataObject(QStringLiteral("FTP Zone"), QStringLiteral("icons/icons/watt.png"), QStringLiteral("0"), false, @@ -929,6 +931,12 @@ void homeform::sortTiles() { dataList.append(avgWatt); } + if (settings.value(QZSettings::tile_avg_watt_lap_enabled, true).toBool() && + settings.value(QZSettings::tile_avg_watt_lap_order, 0).toInt() == i) { + avgWattLap->setGridId(i); + dataList.append(avgWattLap); + } + if (settings.value(QZSettings::tile_ftp_enabled, true).toBool() && settings.value(QZSettings::tile_ftp_order, 0).toInt() == i) { ftp->setGridId(i); @@ -1213,6 +1221,12 @@ void homeform::sortTiles() { dataList.append(avgWatt); } + if (settings.value(QZSettings::tile_avg_watt_lap_enabled, true).toBool() && + settings.value(QZSettings::tile_avg_watt_lap_order, 0).toInt() == i) { + avgWattLap->setGridId(i); + dataList.append(avgWattLap); + } + if (settings.value(QZSettings::tile_ftp_enabled, true).toBool() && settings.value(QZSettings::tile_ftp_order, 0).toInt() == i) { ftp->setGridId(i); @@ -1536,6 +1550,12 @@ void homeform::sortTiles() { dataList.append(avgWatt); } + if (settings.value(QZSettings::tile_avg_watt_lap_enabled, true).toBool() && + settings.value(QZSettings::tile_avg_watt_lap_order, 0).toInt() == i) { + avgWattLap->setGridId(i); + dataList.append(avgWattLap); + } + if (settings.value(QZSettings::tile_ftp_enabled, true).toBool() && settings.value(QZSettings::tile_ftp_order, 0).toInt() == i) { ftp->setGridId(i); @@ -1749,6 +1769,12 @@ void homeform::sortTiles() { dataList.append(avgWatt); } + if (settings.value(QZSettings::tile_avg_watt_lap_enabled, true).toBool() && + settings.value(QZSettings::tile_avg_watt_lap_order, 0).toInt() == i) { + avgWattLap->setGridId(i); + dataList.append(avgWattLap); + } + if (settings.value(QZSettings::tile_ftp_enabled, true).toBool() && settings.value(QZSettings::tile_ftp_order, 0).toInt() == i) { ftp->setGridId(i); @@ -2950,6 +2976,7 @@ void homeform::update() { QStringLiteral("MAX: ") + QString::number(bluetoothManager->device()->currentMETS().max(), 'f', 1)); lapElapsed->setValue(bluetoothManager->device()->lapElapsedTime().toString(QStringLiteral("h:mm:ss"))); avgWatt->setValue(QString::number(bluetoothManager->device()->wattsMetric().average(), 'f', 0)); + avgWattLap->setValue(QString::number(bluetoothManager->device()->wattsMetric().lapAverage(), 'f', 0)); wattKg->setValue(QString::number(bluetoothManager->device()->wattKg().value(), 'f', 1)); wattKg->setSecondLine( QStringLiteral("AVG: ") + QString::number(bluetoothManager->device()->wattKg().average(), 'f', 1) + diff --git a/src/homeform.h b/src/homeform.h index 230b11c3b..4832dcbfc 100644 --- a/src/homeform.h +++ b/src/homeform.h @@ -565,6 +565,7 @@ class homeform : public QObject { DataObject *resistance; DataObject *watt; DataObject *avgWatt; + DataObject *avgWattLap; DataObject *heart; DataObject *fan; DataObject *jouls; diff --git a/src/qzsettings.cpp b/src/qzsettings.cpp index fc6cf2612..6801eec92 100644 --- a/src/qzsettings.cpp +++ b/src/qzsettings.cpp @@ -546,8 +546,10 @@ const QString QZSettings::tile_preset_inclination_4_color = QStringLiteral("tile const QString QZSettings::default_tile_preset_inclination_4_color = QStringLiteral("grey"); const QString QZSettings::tile_preset_inclination_5_color = QStringLiteral("tile_preset_inclination_5_color"); const QString QZSettings::default_tile_preset_inclination_5_color = QStringLiteral("grey"); +const QString QZSettings::tile_avg_watt_lap_enabled = QStringLiteral("tile_avg_watt_lap_enabled"); +const QString QZSettings::tile_avg_watt_lap_order = QStringLiteral("tile_avg_watt_lap_order"); -const uint32_t allSettingsCount = 445; +const uint32_t allSettingsCount = 447; QVariant allSettings[allSettingsCount][2] = { {QZSettings::cryptoKeySettingsProfiles, QZSettings::default_cryptoKeySettingsProfiles}, {QZSettings::bluetooth_no_reconnection, QZSettings::default_bluetooth_no_reconnection}, @@ -996,6 +998,8 @@ QVariant allSettings[allSettingsCount][2] = { {QZSettings::tile_preset_inclination_3_color, QZSettings::default_tile_preset_inclination_3_color}, {QZSettings::tile_preset_inclination_4_color, QZSettings::default_tile_preset_inclination_4_color}, {QZSettings::tile_preset_inclination_5_color, QZSettings::default_tile_preset_inclination_5_color}, + {QZSettings::tile_avg_watt_lap_enabled, QZSettings::default_tile_avg_watt_lap_enabled}, + {QZSettings::tile_avg_watt_lap_order, QZSettings::default_tile_avg_watt_lap_order}, }; void QZSettings::qDebugAllSettings(bool showDefaults) { diff --git a/src/qzsettings.h b/src/qzsettings.h index 4a1bee726..7aff8dde3 100644 --- a/src/qzsettings.h +++ b/src/qzsettings.h @@ -1561,6 +1561,12 @@ class QZSettings { static const QString tile_preset_inclination_5_color; static const QString default_tile_preset_inclination_5_color; + static const QString tile_avg_watt_lap_enabled; + static constexpr bool default_tile_avg_watt_lap_enabled = false; + + static const QString tile_avg_watt_lap_order; + static constexpr int default_tile_avg_watt_lap_order = 48; + /** * @brief Write the QSettings values using the constants from this namespace. * @param showDefaults Optionally indicates if the default should be shown with the key. diff --git a/src/settings-tiles.qml b/src/settings-tiles.qml index 3c46820e0..02fda387d 100644 --- a/src/settings-tiles.qml +++ b/src/settings-tiles.qml @@ -181,6 +181,8 @@ ScrollView { property string tile_preset_inclination_3_color: "grey" property string tile_preset_inclination_4_color: "grey" property string tile_preset_inclination_5_color: "grey" + property bool tile_avg_watt_lap_enabled: false + property int tile_avg_watt_lap_order: 48 } @@ -556,6 +558,38 @@ ScrollView { } } + AccordionCheckElement { + id: avgwattLapEnabledAccordion + title: qsTr("AVG Watt Lap") + linkedBoolSetting: "tile_avg_watt_lap_enabled" + settings: settings + accordionContent: RowLayout { + spacing: 10 + Label { + id: labelavgwattLapOrder + text: qsTr("order index:") + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + } + ComboBox { + id: avgwattLapOrderTextField + model: rootItem.tile_order + displayText: settings.tile_avg_watt_lap_order + Layout.fillHeight: false + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onActivated: { + displayText = avgwattLapOrderTextField.currentValue + } + } + Button { + id: okavgwattLapOrderButton + text: "OK" + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + onClicked: settings.tile_avg_watt_lap_order = avgwattLapOrderTextField.displayText + } + } + } + AccordionCheckElement { id: ftpEnabledAccordion title: qsTr("FTP %") @@ -2902,7 +2936,7 @@ ScrollView { horizontalAlignment: Text.AlignRight } ColorDialog { - id: colorPresetInclination2 + id: colorPresetInclination2 title: "Please choose a color" onAccepted: { presetInclination2ColorTextField.text = colorPresetInclination2.color diff --git a/src/settings.qml b/src/settings.qml index 83309cea5..2e3107cc3 100644 --- a/src/settings.qml +++ b/src/settings.qml @@ -568,6 +568,9 @@ import Qt.labs.settings 1.0 property string tile_preset_inclination_3_color: "grey" property string tile_preset_inclination_4_color: "grey" property string tile_preset_inclination_5_color: "grey" + + property bool tile_avg_watt_lap_enabled: false + property int tile_avg_watt_lap_order: 48 // from version ? property bool trixter_xdream_v1_bike: false From 818712fd86b0601ed434c837dcd803895b112421 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Wed, 2 Nov 2022 16:01:11 +0100 Subject: [PATCH 164/255] bluetooth discovery fitfan improvement --- src/bluetooth.cpp | 27 ++++++++++++++++++++++----- src/bluetooth.h | 1 + src/fitmetria_fanfit.cpp | 3 ++- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index 451f887d1..e74075023 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -218,13 +218,14 @@ void bluetooth::finished() { // since i can have multiple fanfit i can't wait more because i don't have the full list of the fanfit - // devices connected to QZ - // bool fitmetriaFanfitEnabled = settings.value(QZSettings::fitmetria_fanfit_enable, - // QZSettings::default_fitmetria_fanfit_enable).toBool(); + // devices connected to QZ. edit: let's wait at the last one item + bool fitmetriaFanfitFound = + !settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable).toBool(); if ((!heartRateBeltFound && !heartRateBeltAvaiable()) || (!ftmsAccessoryFound && !ftmsAccessoryAvaiable()) || (!cscFound && !cscSensorAvaiable()) || (!powerSensorFound && !powerSensorAvaiable()) || - (!eliteRizerFound && !eliteRizerAvaiable()) || (!eliteSterzoSmartFound && !eliteSterzoSmartAvaiable())) { + (!eliteRizerFound && !eliteRizerAvaiable()) || (!eliteSterzoSmartFound && !eliteSterzoSmartAvaiable()) || + (!fitmetriaFanfitFound && !fitmetriaFanfitAvaiable())) { // force heartRateBelt off forceHeartBeltOffForTimeout = true; @@ -333,6 +334,16 @@ bool bluetooth::ftmsAccessoryAvaiable() { return false; } +bool bluetooth::fitmetriaFanfitAvaiable() { + + Q_FOREACH (QBluetoothDeviceInfo b, devices) { + if (!b.name().compare("FITFAN-", Qt::CaseInsensitive)) { + return true; + } + } + return false; +} + bool bluetooth::powerSensorAvaiable() { QSettings settings; @@ -420,6 +431,8 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { settings.value(QZSettings::ftms_accessory_name, QZSettings::default_ftms_accessory_name).toString(); bool heartRateBeltFound = heartRateBeltName.startsWith(QStringLiteral("Disabled")); bool ftmsAccessoryFound = ftmsAccessoryName.startsWith(QStringLiteral("Disabled")); + bool fitmetriaFanfitFound = + !settings.value(QZSettings::fitmetria_fanfit_enable, QZSettings::default_fitmetria_fanfit_enable).toBool(); bool toorx_ftms = settings.value(QZSettings::toorx_ftms, QZSettings::default_toorx_ftms).toBool(); bool toorx_bike = (settings.value(QZSettings::toorx_bike, QZSettings::default_toorx_bike).toBool() || settings.value(QZSettings::jll_IC400_bike, QZSettings::default_jll_IC400_bike).toBool() || @@ -471,6 +484,10 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { heartRateBeltFound = heartRateBeltAvaiable(); } + if (!fitmetriaFanfitFound) { + + fitmetriaFanfitFound = fitmetriaFanfitAvaiable(); + } if (!ftmsAccessoryFound) { ftmsAccessoryFound = ftmsAccessoryAvaiable(); @@ -559,7 +576,7 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { #endif if ((heartRateBeltFound && ftmsAccessoryFound && cscFound && powerSensorFound && eliteRizerFound && - eliteSterzoSmartFound) || + eliteSterzoSmartFound && fitmetriaFanfitFound) || forceHeartBeltOffForTimeout) { for (const QBluetoothDeviceInfo &b : qAsConst(devices)) { diff --git a/src/bluetooth.h b/src/bluetooth.h index 411c4c4dc..8dc462a22 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -264,6 +264,7 @@ class bluetooth : public QObject, public SignalHandler { bool powerSensorAvaiable(); bool eliteRizerAvaiable(); bool eliteSterzoSmartAvaiable(); + bool fitmetriaFanfitAvaiable(); bool fitmetria_fanfit_isconnected(QString name); /** diff --git a/src/fitmetria_fanfit.cpp b/src/fitmetria_fanfit.cpp index 1a5b210ea..646f18967 100644 --- a/src/fitmetria_fanfit.cpp +++ b/src/fitmetria_fanfit.cpp @@ -207,7 +207,8 @@ void fitmetria_fanfit::writeCharacteristic(uint8_t *data, uint8_t data_len, cons QStringLiteral(" // ") + info; } - loop.exec(); + // not necessary, since the communication is one way only. also it could lead to crashes + // loop.exec(); } void fitmetria_fanfit::stateChanged(QLowEnergyService::ServiceState state) { From 259203692d2df1e2cbf728225fcb3367fccd0554 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Sun, 6 Nov 2022 07:02:02 +0100 Subject: [PATCH 165/255] iOS project updated --- .../qdomyoszwift.xcodeproj/project.pbxproj | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj index ddd99b724..358fca75f 100644 --- a/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj +++ b/build-qdomyos-zwift-Qt_5_15_2_for_iOS-Debug/qdomyoszwift.xcodeproj/project.pbxproj @@ -441,6 +441,8 @@ 87EFB57025BD704A0039DD5A /* moc_proformtreadmill.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87EFB56F25BD704A0039DD5A /* moc_proformtreadmill.cpp */; }; 87EFE45927A518F5006EA1C3 /* nautiluselliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87EFE45827A518F5006EA1C3 /* nautiluselliptical.cpp */; }; 87EFE45B27A51901006EA1C3 /* moc_nautiluselliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87EFE45A27A51900006EA1C3 /* moc_nautiluselliptical.cpp */; }; + 87F02E4029178524000DB52C /* octaneelliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F02E3E29178523000DB52C /* octaneelliptical.cpp */; }; + 87F02E4229178545000DB52C /* moc_octaneelliptical.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F02E4129178545000DB52C /* moc_octaneelliptical.cpp */; }; 87F1179E26A5FBDE00541B3A /* libqtwebview_darwin.a in Link Binary With Libraries */ = {isa = PBXBuildFile; fileRef = 87420DF7269D7CE1000C5EC6 /* libqtwebview_darwin.a */; }; 87F527BE28EEB5AA00A9F8D5 /* qzsettings.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F527BC28EEB5AA00A9F8D5 /* qzsettings.cpp */; }; 87F93427278E0EC00088B596 /* domyosrower.cpp in Compile Sources */ = {isa = PBXBuildFile; fileRef = 87F93426278E0EC00088B596 /* domyosrower.cpp */; }; @@ -1256,6 +1258,9 @@ 87EFE45727A518F5006EA1C3 /* nautiluselliptical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = nautiluselliptical.h; path = ../src/nautiluselliptical.h; sourceTree = ""; }; 87EFE45827A518F5006EA1C3 /* nautiluselliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = nautiluselliptical.cpp; path = ../src/nautiluselliptical.cpp; sourceTree = ""; }; 87EFE45A27A51900006EA1C3 /* moc_nautiluselliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_nautiluselliptical.cpp; sourceTree = ""; }; + 87F02E3E29178523000DB52C /* octaneelliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = octaneelliptical.cpp; path = ../src/octaneelliptical.cpp; sourceTree = ""; }; + 87F02E3F29178524000DB52C /* octaneelliptical.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = octaneelliptical.h; path = ../src/octaneelliptical.h; sourceTree = ""; }; + 87F02E4129178545000DB52C /* moc_octaneelliptical.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = moc_octaneelliptical.cpp; sourceTree = ""; }; 87F527BC28EEB5AA00A9F8D5 /* qzsettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qzsettings.cpp; path = ../src/qzsettings.cpp; sourceTree = ""; }; 87F527BD28EEB5AA00A9F8D5 /* qzsettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qzsettings.h; path = ../src/qzsettings.h; sourceTree = ""; }; 87F93425278E0EC00088B596 /* domyosrower.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = domyosrower.h; path = ../src/domyosrower.h; sourceTree = ""; }; @@ -1637,6 +1642,7 @@ 25B08E2869634E9BCBA333A2 /* Generated Sources */ = { isa = PBXGroup; children = ( + 87F02E4129178545000DB52C /* moc_octaneelliptical.cpp */, 87D105532909971100B3935B /* moc_mepanelbike.cpp */, 872A20DB28C5F5CE0037774D /* moc_faketreadmill.cpp */, 878C9E6A28B77E9800669129 /* moc_nordictrackifitadbbike.cpp */, @@ -1791,6 +1797,8 @@ 2EB56BE3C2D93CDAB0C52E67 /* Sources */ = { isa = PBXGroup; children = ( + 87F02E3E29178523000DB52C /* octaneelliptical.cpp */, + 87F02E3F29178524000DB52C /* octaneelliptical.h */, 87D10550290996EA00B3935B /* mepanelbike.cpp */, 87D10551290996EA00B3935B /* mepanelbike.h */, 87F527BC28EEB5AA00A9F8D5 /* qzsettings.cpp */, @@ -2855,6 +2863,7 @@ C6B3CD471768392E18F85819 /* fit_accumulated_field.cpp in Compile Sources */, 3D7395B0A17915A06361C7F3 /* fit_accumulator.cpp in Compile Sources */, 2A61806454201575EDB3F94F /* fit_buffer_encode.cpp in Compile Sources */, + 87F02E4229178545000DB52C /* moc_octaneelliptical.cpp in Compile Sources */, 87917A7328E768D200F8D9AC /* Browser.swift in Compile Sources */, 873CD20B27EF8D8A000131BC /* inapptransaction.cpp in Compile Sources */, 873824EF27E647A9004F1B46 /* query.cpp in Compile Sources */, @@ -3062,6 +3071,7 @@ 873824E527E647A8004F1B46 /* message.cpp in Compile Sources */, 210F6A0A7E2FA7CDD3CA0084 /* qdomyoszwift_qml_plugin_import.cpp in Compile Sources */, 87062644259480A600D06586 /* APIFetcher.swift in Compile Sources */, + 87F02E4029178524000DB52C /* octaneelliptical.cpp in Compile Sources */, 878531682711A3EC004B153D /* moc_activiotreadmill.cpp in Compile Sources */, 87C5F0D626285E7E0067A1B5 /* moc_emailaddress.cpp in Compile Sources */, 39FAA19B9285AB16AE3A39BA /* qrc_icons.cpp in Compile Sources */, @@ -3502,7 +3512,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.84; + CURRENT_PROJECT_VERSION = 2.11.86; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; HEADER_SEARCH_PATHS = ( @@ -3670,7 +3680,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "../src/ios/qdomyos-zwift.entitlements"; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 2.11.84; + CURRENT_PROJECT_VERSION = 2.11.86; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = NO; @@ -3874,7 +3884,7 @@ CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.84; + CURRENT_PROJECT_VERSION = 2.11.86; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -3966,7 +3976,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.84; + CURRENT_PROJECT_VERSION = 2.11.86; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 6335M7T29D; ENABLE_BITCODE = YES; @@ -4053,7 +4063,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.84; + CURRENT_PROJECT_VERSION = 2.11.86; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; ENABLE_PREVIEWS = YES; @@ -4163,7 +4173,7 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_ENTITLEMENTS = "watchkit Extension/WatchKit Extension.entitlements"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 2.11.84; + CURRENT_PROJECT_VERSION = 2.11.86; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"watchkit Extension/Preview Content\""; ENABLE_BITCODE = YES; From d8e708ce375d09d235da3be05fa9cb37a5277f59 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 3 Nov 2022 08:06:03 +0100 Subject: [PATCH 166/255] Life Fitness Treadmill FTMS #1018 --- src/android/AndroidManifest.xml | 2 +- src/bluetooth.cpp | 7 ++++--- src/main.qml | 2 +- src/qdomyos-zwift.pro | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/android/AndroidManifest.xml b/src/android/AndroidManifest.xml index 2ad04c966..dc2b58f38 100644 --- a/src/android/AndroidManifest.xml +++ b/src/android/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/bluetooth.cpp b/src/bluetooth.cpp index e74075023..49cbe417b 100644 --- a/src/bluetooth.cpp +++ b/src/bluetooth.cpp @@ -1089,9 +1089,10 @@ void bluetooth::deviceDiscovered(const QBluetoothDeviceInfo &device) { b.name().toUpper().startsWith(QStringLiteral("AFG SPORT")) || b.name().toUpper().startsWith(QStringLiteral("WLT2541")) || b.name().toUpper().startsWith(QStringLiteral("S77")) || - b.name().toUpper().startsWith(QStringLiteral("T318_")) || // FTMS - b.name().toUpper().startsWith(QStringLiteral("T218_")) || // FTMS - b.name().toUpper().startsWith(QStringLiteral("TRX3500")) || // FTMS + (b.name().toUpper().startsWith(QStringLiteral("LF")) && b.name().length() == 18) || // FTMS + b.name().toUpper().startsWith(QStringLiteral("T318_")) || // FTMS + b.name().toUpper().startsWith(QStringLiteral("T218_")) || // FTMS + b.name().toUpper().startsWith(QStringLiteral("TRX3500")) || // FTMS b.name().toUpper().startsWith(QStringLiteral("JFTMPARAGON")) || b.name().toUpper().startsWith(QStringLiteral("JFTM")) || // FTMS b.name().toUpper().startsWith(QStringLiteral("CT800")) || // FTMS diff --git a/src/main.qml b/src/main.qml index e713f761e..1619ecc72 100644 --- a/src/main.qml +++ b/src/main.qml @@ -655,7 +655,7 @@ ApplicationWindow { } ItemDelegate { - text: "version 2.11.84" + text: "version 2.11.85" width: parent.width } FileDialog { diff --git a/src/qdomyos-zwift.pro b/src/qdomyos-zwift.pro index ab517f5f2..d541ec23e 100644 --- a/src/qdomyos-zwift.pro +++ b/src/qdomyos-zwift.pro @@ -729,4 +729,4 @@ INCLUDEPATH += purchasing/inapp WINRT_MANIFEST = AppxManifest.xml -VERSION = 2.11.84 +VERSION = 2.11.85 From 2ccc6dd9273f44dcdd7501cd0d18be1b08c5ae42 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 3 Nov 2022 08:20:23 +0100 Subject: [PATCH 167/255] Fitshow FTMS bike doesn't send metrics #1019 --- src/ftmsbike.cpp | 397 +++++++++++++++++++++++++---------------------- 1 file changed, 213 insertions(+), 184 deletions(-) diff --git a/src/ftmsbike.cpp b/src/ftmsbike.cpp index e101e57ae..521a7ae0c 100644 --- a/src/ftmsbike.cpp +++ b/src/ftmsbike.cpp @@ -162,7 +162,8 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris QSettings settings; QString heartRateBeltName = settings.value(QZSettings::heart_rate_belt_name, QZSettings::default_heart_rate_belt_name).toString(); - bool disable_hr_frommachinery = settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); + bool disable_hr_frommachinery = + settings.value(QZSettings::heart_ignore_builtin, QZSettings::default_heart_ignore_builtin).toBool(); bool heart = false; qDebug() << characteristic.uuid() << QStringLiteral(" << ") << newValue.toHex(' '); @@ -203,7 +204,9 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris (uint16_t)((uint8_t)newValue.at(index)))) / 100.0; } else { - Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); + Speed = metric::calculateSpeedFromPower( + watts(), Inclination.value(), Speed.value(), + fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } index += 2; emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); @@ -211,9 +214,9 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris if (Flags.avgSpeed) { double avgSpeed; - avgSpeed = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / - 100.0; + avgSpeed = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))) / + 100.0; index += 2; emit debug(QStringLiteral("Current Average Speed: ") + QString::number(avgSpeed)); } @@ -232,9 +235,9 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris if (Flags.avgCadence) { double avgCadence; - avgCadence = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / - 2.0; + avgCadence = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))) / + 2.0; index += 2; emit debug(QStringLiteral("Current Average Cadence: ") + QString::number(avgCadence)); } @@ -253,8 +256,8 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris emit debug(QStringLiteral("Current Distance: ") + QString::number(Distance.value())); if (Flags.resistanceLvl) { - Resistance = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + Resistance = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); emit resistanceRead(Resistance.value()); index += 2; emit debug(QStringLiteral("Current Resistance: ") + QString::number(Resistance.value())); @@ -293,14 +296,15 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris if (Flags.avgPower) { double avgPower; - avgPower = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + avgPower = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); index += 2; emit debug(QStringLiteral("Current Average Watt: ") + QString::number(avgPower)); } if (Flags.expEnergy && newValue.length() > index + 1) { - KCal = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + KCal = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); index += 2; // energy per hour @@ -310,22 +314,22 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris index += 1; } else { if (watts()) - KCal += - ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * - 3.5) / - 200.0) / - (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( - QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in - // kg * 3.5) / 200 ) / 60 + KCal += ((((0.048 * ((double)watts()) + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / + 200.0) / + (60000.0 / + ((double)lastRefreshCharacteristicChanged.msecsTo( + QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in + // kg * 3.5) / 200 ) / 60 } emit debug(QStringLiteral("Current KCal: ") + QString::number(KCal.value())); - #ifdef Q_OS_ANDROID +#ifdef Q_OS_ANDROID if (settings.value(QZSettings::ant_heart, QZSettings::default_ant_heart).toBool()) Heart = (uint8_t)KeepAwakeHelper::heart(); else - #endif +#endif { if (Flags.heartRate && !disable_hr_frommachinery && newValue.length() > index) { Heart = ((double)((newValue.at(index)))); @@ -348,193 +352,196 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris if (Flags.remainingTime) { // todo } - } else if(characteristic.uuid() == QBluetoothUuid((quint16)0x2ACE)) { + } else if (characteristic.uuid() == QBluetoothUuid((quint16)0x2ACE)) { union flags { - struct { - uint32_t moreData : 1; - uint32_t avgSpeed : 1; - uint32_t totDistance : 1; - uint32_t stepCount: 1; - uint32_t strideCount : 1; - uint32_t elevationGain : 1; - uint32_t rampAngle : 1; - uint32_t resistanceLvl : 1; - uint32_t instantPower : 1; - uint32_t avgPower : 1; - uint32_t expEnergy : 1; - uint32_t heartRate : 1; - uint32_t metabolicEq : 1; - uint32_t elapsedTime : 1; - uint32_t remainingTime : 1; - uint32_t movementDirection : 1; - uint32_t spare : 8; - }; - - uint32_t word_flags; + struct { + uint32_t moreData : 1; + uint32_t avgSpeed : 1; + uint32_t totDistance : 1; + uint32_t stepCount : 1; + uint32_t strideCount : 1; + uint32_t elevationGain : 1; + uint32_t rampAngle : 1; + uint32_t resistanceLvl : 1; + uint32_t instantPower : 1; + uint32_t avgPower : 1; + uint32_t expEnergy : 1; + uint32_t heartRate : 1; + uint32_t metabolicEq : 1; + uint32_t elapsedTime : 1; + uint32_t remainingTime : 1; + uint32_t movementDirection : 1; + uint32_t spare : 8; }; - flags Flags; - int index = 0; - Flags.word_flags = (newValue.at(2) << 16) | (newValue.at(1) << 8) | newValue.at(0); - index += 3; - - if (!Flags.moreData) { - if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { - Speed = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | - (uint16_t)((uint8_t)newValue.at(index)))) / - 100.0; - } else { - Speed = metric::calculateSpeedFromPower(watts(), Inclination.value(), Speed.value(),fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); - } - emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); - index += 2; - } + uint32_t word_flags; + }; - if (Flags.avgSpeed) { - double avgSpeed; - avgSpeed = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))) / - 100.0; - index += 2; - emit debug(QStringLiteral("Current Average Speed: ") + QString::number(avgSpeed)); - } + flags Flags; + int index = 0; + Flags.word_flags = (newValue.at(2) << 16) | (newValue.at(1) << 8) | newValue.at(0); + index += 3; - if (Flags.totDistance) { - Distance = ((double)((((uint32_t)((uint8_t)newValue.at(index + 2)) << 16) | - (uint32_t)((uint8_t)newValue.at(index + 1)) << 8) | - (uint32_t)((uint8_t)newValue.at(index)))) / - 1000.0; - index += 3; + if (!Flags.moreData) { + if (!settings.value(QZSettings::speed_power_based, QZSettings::default_speed_power_based).toBool()) { + Speed = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))) / + 100.0; } else { - Distance += ((Speed.value() / 3600000.0) * - ((double)lastRefreshCharacteristicChanged.msecsTo(QDateTime::currentDateTime()))); + Speed = metric::calculateSpeedFromPower( + watts(), Inclination.value(), Speed.value(), + fabs(QDateTime::currentDateTime().msecsTo(Speed.lastChanged()) / 1000.0), this->speedLimit()); } + emit debug(QStringLiteral("Current Speed: ") + QString::number(Speed.value())); + index += 2; + } - emit debug(QStringLiteral("Current Distance: ") + QString::number(Distance.value())); + if (Flags.avgSpeed) { + double avgSpeed; + avgSpeed = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))) / + 100.0; + index += 2; + emit debug(QStringLiteral("Current Average Speed: ") + QString::number(avgSpeed)); + } - if (Flags.stepCount) { - if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) - .toString() - .startsWith(QStringLiteral("Disabled"))) { - Cadence = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | - (uint16_t)((uint8_t)newValue.at(index)))); - } - emit debug(QStringLiteral("Current Cadence: ") + QString::number(Cadence.value())); + if (Flags.totDistance) { + Distance = ((double)((((uint32_t)((uint8_t)newValue.at(index + 2)) << 16) | + (uint32_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint32_t)((uint8_t)newValue.at(index)))) / + 1000.0; + index += 3; + } else { + Distance += ((Speed.value() / 3600000.0) * + ((double)lastRefreshCharacteristicChanged.msecsTo(QDateTime::currentDateTime()))); + } - index += 2; - index += 2; - } + emit debug(QStringLiteral("Current Distance: ") + QString::number(Distance.value())); - if (Flags.strideCount) { - index += 2; + if (Flags.stepCount) { + if (settings.value(QZSettings::cadence_sensor_name, QZSettings::default_cadence_sensor_name) + .toString() + .startsWith(QStringLiteral("Disabled"))) { + Cadence = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); } + emit debug(QStringLiteral("Current Cadence: ") + QString::number(Cadence.value())); - if (Flags.elevationGain) { - index += 2; - index += 2; - } + index += 2; + index += 2; + } - if (Flags.rampAngle) { - index += 2; - index += 2; - } + if (Flags.strideCount) { + index += 2; + } - if (Flags.resistanceLvl) { - Resistance = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); + if (Flags.elevationGain) { + index += 2; + index += 2; + } + + if (Flags.rampAngle) { + index += 2; + index += 2; + } + + if (Flags.resistanceLvl) { + Resistance = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); + emit resistanceRead(Resistance.value()); + index += 2; + emit debug(QStringLiteral("Current Resistance: ") + QString::number(Resistance.value())); + } else { + double ac = 0.01243107769; + double bc = 1.145964912; + double cc = -23.50977444; + + double ar = 0.1469553975; + double br = -5.841344538; + double cr = 97.62165482; + + if (Cadence.value() && m_watt.value()) { + m_pelotonResistance = + (((sqrt(pow(br, 2.0) - 4.0 * ar * + (cr - (m_watt.value() * 132.0 / + (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - + br) / + (2.0 * ar)) * + settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + + settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); + Resistance = m_pelotonResistance; emit resistanceRead(Resistance.value()); - index += 2; - emit debug(QStringLiteral("Current Resistance: ") + QString::number(Resistance.value())); - } else { - double ac = 0.01243107769; - double bc = 1.145964912; - double cc = -23.50977444; - - double ar = 0.1469553975; - double br = -5.841344538; - double cr = 97.62165482; - - if (Cadence.value() && m_watt.value()) { - m_pelotonResistance = - (((sqrt(pow(br, 2.0) - 4.0 * ar * - (cr - (m_watt.value() * 132.0 / - (ac * pow(Cadence.value(), 2.0) + bc * Cadence.value() + cc)))) - - br) / - (2.0 * ar)) * - settings.value(QZSettings::peloton_gain, QZSettings::default_peloton_gain).toDouble()) + - settings.value(QZSettings::peloton_offset, QZSettings::default_peloton_offset).toDouble(); - Resistance = m_pelotonResistance; - emit resistanceRead(Resistance.value()); - } } + } - if (Flags.instantPower) { - if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) - .toString() - .startsWith(QStringLiteral("Disabled"))) - m_watt = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | - (uint16_t)((uint8_t)newValue.at(index)))); - emit debug(QStringLiteral("Current Watt: ") + QString::number(m_watt.value())); - index += 2; - } + if (Flags.instantPower) { + if (settings.value(QZSettings::power_sensor_name, QZSettings::default_power_sensor_name) + .toString() + .startsWith(QStringLiteral("Disabled"))) + m_watt = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); + emit debug(QStringLiteral("Current Watt: ") + QString::number(m_watt.value())); + index += 2; + } - if (Flags.avgPower) { - double avgPower; - avgPower = - ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); - emit debug(QStringLiteral("Current Average Watt: ") + QString::number(avgPower)); - index += 2; - } + if (Flags.avgPower) { + double avgPower; + avgPower = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); + emit debug(QStringLiteral("Current Average Watt: ") + QString::number(avgPower)); + index += 2; + } - if (Flags.expEnergy && newValue.length() > index + 1) { - KCal = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | (uint16_t)((uint8_t)newValue.at(index)))); - index += 2; + if (Flags.expEnergy && newValue.length() > index + 1) { + KCal = ((double)(((uint16_t)((uint8_t)newValue.at(index + 1)) << 8) | + (uint16_t)((uint8_t)newValue.at(index)))); + index += 2; - // energy per hour - index += 2; + // energy per hour + index += 2; - // energy per minute - index += 1; - } else { - if (watts()) - KCal += - ((((0.048 * ((double)watts()) + 1.19) * settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * - 3.5) / + // energy per minute + index += 1; + } else { + if (watts()) + KCal += ((((0.048 * ((double)watts()) + 1.19) * + settings.value(QZSettings::weight, QZSettings::default_weight).toFloat() * 3.5) / 200.0) / - (60000.0 / ((double)lastRefreshCharacteristicChanged.msecsTo( - QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in - // kg * 3.5) / 200 ) / 60 - } + (60000.0 / + ((double)lastRefreshCharacteristicChanged.msecsTo( + QDateTime::currentDateTime())))); //(( (0.048* Output in watts +1.19) * body weight in + // kg * 3.5) / 200 ) / 60 + } - emit debug(QStringLiteral("Current KCal: ") + QString::number(KCal.value())); + emit debug(QStringLiteral("Current KCal: ") + QString::number(KCal.value())); #ifdef Q_OS_ANDROID - if (settings.value(QZSettings::ant_heart, QZSettings::default_ant_heart).toBool()) - Heart = (uint8_t)KeepAwakeHelper::heart(); - else + if (settings.value(QZSettings::ant_heart, QZSettings::default_ant_heart).toBool()) + Heart = (uint8_t)KeepAwakeHelper::heart(); + else #endif - { - if (Flags.heartRate && !disable_hr_frommachinery && newValue.length() > index) { - Heart = ((double)((newValue.at(index)))); - // index += 1; // NOTE: clang-analyzer-deadcode.DeadStores - emit debug(QStringLiteral("Current Heart: ") + QString::number(Heart.value())); - } else { - Flags.heartRate = false; - } - heart = Flags.heartRate; + { + if (Flags.heartRate && !disable_hr_frommachinery && newValue.length() > index) { + Heart = ((double)((newValue.at(index)))); + // index += 1; // NOTE: clang-analyzer-deadcode.DeadStores + emit debug(QStringLiteral("Current Heart: ") + QString::number(Heart.value())); + } else { + Flags.heartRate = false; } + heart = Flags.heartRate; + } - if (Flags.metabolicEq) { - // todo - } + if (Flags.metabolicEq) { + // todo + } - if (Flags.elapsedTime) { - // todo - } + if (Flags.elapsedTime) { + // todo + } - if (Flags.remainingTime) { - // todo - } + if (Flags.remainingTime) { + // todo + } } else { return; } @@ -563,7 +570,8 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris #ifdef Q_OS_IOS #ifndef IO_UNDER_QT bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence && h && firstStateChanged) { h->virtualbike_setCadence(currentCrankRevolutions(), lastCrankEventTime()); h->virtualbike_setHeartRate((uint8_t)metrics_override_heartrate()); @@ -580,6 +588,7 @@ void ftmsbike::characteristicChanged(const QLowEnergyCharacteristic &characteris } void ftmsbike::stateChanged(QLowEnergyService::ServiceState state) { + QSettings settings; QMetaEnum metaEnum = QMetaEnum::fromType(); emit debug(QStringLiteral("BTLE stateChanged ") + QString::fromLocal8Bit(metaEnum.valueToKey(state))); @@ -612,6 +621,16 @@ void ftmsbike::stateChanged(QLowEnergyService::ServiceState state) { qDebug() << s->serviceUuid() << QStringLiteral("connected!"); + if (settings.value(QZSettings::hammer_racer_s, QZSettings::default_hammer_racer_s).toBool()) { + QBluetoothUuid ftmsService((quint16)0x1826); + if (s->serviceUuid() != ftmsService) { + qDebug() << QStringLiteral("hammer racer bike wants to be subscribed only to FTMS service in order " + "to send metrics") + << s->serviceUuid(); + continue; + } + } + auto characteristics_list = s->characteristics(); for (const QLowEnergyCharacteristic &c : qAsConst(characteristics_list)) { qDebug() << QStringLiteral("char uuid") << c.uuid() << QStringLiteral("handle") << c.handle(); @@ -664,6 +683,11 @@ void ftmsbike::stateChanged(QLowEnergyService::ServiceState state) { } } + if (gattFTMSService && gattWriteCharControlPointId.isValid() && + settings.value(QZSettings::hammer_racer_s, QZSettings::default_hammer_racer_s).toBool()) { + init(); + } + // ******************************************* virtual bike init ************************************* if (!firstStateChanged && !virtualBike #ifdef Q_OS_IOS @@ -673,11 +697,14 @@ void ftmsbike::stateChanged(QLowEnergyService::ServiceState state) { #endif ) { QSettings settings; - bool virtual_device_enabled = settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); + bool virtual_device_enabled = + settings.value(QZSettings::virtual_device_enabled, QZSettings::default_virtual_device_enabled).toBool(); #ifdef Q_OS_IOS #ifndef IO_UNDER_QT - bool cadence = settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); - bool ios_peloton_workaround = settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); + bool cadence = + settings.value(QZSettings::bike_cadence_sensor, QZSettings::default_bike_cadence_sensor).toBool(); + bool ios_peloton_workaround = + settings.value(QZSettings::ios_peloton_workaround, QZSettings::default_ios_peloton_workaround).toBool(); if (ios_peloton_workaround && cadence) { qDebug() << "ios_peloton_workaround activated!"; h = new lockscreen(); @@ -771,14 +798,16 @@ void ftmsbike::error(QLowEnergyController::Error err) { m_control->errorString()); } -resistance_t ftmsbike::pelotonToBikeResistance(int pelotonResistance) { return (pelotonResistance * max_resistance) / 100; } +resistance_t ftmsbike::pelotonToBikeResistance(int pelotonResistance) { + return (pelotonResistance * max_resistance) / 100; +} void ftmsbike::deviceDiscovered(const QBluetoothDeviceInfo &device) { emit debug(QStringLiteral("Found new device: ") + device.name() + QStringLiteral(" (") + device.address().toString() + ')'); { bluetoothDevice = device; - if(bluetoothDevice.name().toUpper().startsWith("SUITO")) { + if (bluetoothDevice.name().toUpper().startsWith("SUITO")) { qDebug() << QStringLiteral("SUITO found"); max_resistance = 16; } From 820831e8d3a18eb878afc38bdb1e505ee160d189 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 3 Nov 2022 10:04:52 +0100 Subject: [PATCH 168/255] Differences in the GPX starting point #988 new pin point in the 3d map --- src/inner_templates/googlemaps/bike.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inner_templates/googlemaps/bike.js b/src/inner_templates/googlemaps/bike.js index f1e22fc1f..9ad835156 100644 --- a/src/inner_templates/googlemaps/bike.js +++ b/src/inner_templates/googlemaps/bike.js @@ -1 +1 @@ -const bikeUri = "data:@file/octet-stream;base64,Z2xURgIAAACkxgIA3BIAAEpTT057ImFzc2V0Ijp7ImdlbmVyYXRvciI6Iktocm9ub3MgZ2xURiBCbGVuZGVyIEkvTyB2MS4zLjQ4IiwidmVyc2lvbiI6IjIuMCJ9LCJzY2VuZSI6MCwic2NlbmVzIjpbeyJuYW1lIjoiU2NlbmUiLCJub2RlcyI6WzBdfV0sIm5vZGVzIjpbeyJtZXNoIjowLCJuYW1lIjoiYmo3eW5sZ2g3aDRkIiwicm90YXRpb24iOlswLjcwNzEwNjgyODY4OTU3NTIsMCwwLDAuNzA3MTA2NzA5NDgwMjg1Nl0sInNjYWxlIjpbMC4wMTg3NDYzNzYwMzc1OTc2NTYsMC4wMTg3NDYzNzYwMzc1OTc2NTYsMC4wMTg3NDYzNzYwMzc1OTc2NTZdfV0sIm1hdGVyaWFscyI6W3siZG91YmxlU2lkZWQiOnRydWUsImVtaXNzaXZlRmFjdG9yIjpbMCwwLDBdLCJuYW1lIjoiQ0QtTUVUQUxfQkxBQ0siLCJwYnJNZXRhbGxpY1JvdWdobmVzcyI6eyJiYXNlQ29sb3JGYWN0b3IiOlswLjgwMDAwMDAxMTkyMDkyOSwwLjgwMDAwMDAxMTkyMDkyOSwwLjgwMDAwMDAxMTkyMDkyOSwxXSwibWV0YWxsaWNGYWN0b3IiOjAsInJvdWdobmVzc0ZhY3RvciI6MC41fX0seyJkb3VibGVTaWRlZCI6dHJ1ZSwiZW1pc3NpdmVGYWN0b3IiOlswLDAsMF0sIm5hbWUiOiJDRC1DSFJPTUUyIiwicGJyTWV0YWxsaWNSb3VnaG5lc3MiOnsiYmFzZUNvbG9yRmFjdG9yIjpbMC44MDAwMDAwMTE5MjA5MjksMC44MDAwMDAwMTE5MjA5MjksMC44MDAwMDAwMTE5MjA5MjksMV0sIm1ldGFsbGljRmFjdG9yIjowLCJyb3VnaG5lc3NGYWN0b3IiOjAuNX19LHsiZG91YmxlU2lkZWQiOnRydWUsImVtaXNzaXZlRmFjdG9yIjpbMCwwLDBdLCJuYW1lIjoiQ0QtUExBU1RfUkVEIiwicGJyTWV0YWxsaWNSb3VnaG5lc3MiOnsiYmFzZUNvbG9yRmFjdG9yIjpbMC44MDAwMDAwMTE5MjA5MjksMC44MDAwMDAwMTE5MjA5MjksMC44MDAwMDAwMTE5MjA5MjksMV0sIm1ldGFsbGljRmFjdG9yIjowLCJyb3VnaG5lc3NGYWN0b3IiOjAuNX19LHsiZG91YmxlU2lkZWQiOnRydWUsImVtaXNzaXZlRmFjdG9yIjpbMCwwLDBdLCJuYW1lIjoiQ0QtUExBU1RfQkxBQ0siLCJwYnJNZXRhbGxpY1JvdWdobmVzcyI6eyJiYXNlQ29sb3JGYWN0b3IiOlswLjgwMDAwMDAxMTkyMDkyOSwwLjgwMDAwMDAxMTkyMDkyOSwwLjgwMDAwMDAxMTkyMDkyOSwxXSwibWV0YWxsaWNGYWN0b3IiOjAsInJvdWdobmVzc0ZhY3RvciI6MC41fX0seyJkb3VibGVTaWRlZCI6dHJ1ZSwiZW1pc3NpdmVGYWN0b3IiOlswLDAsMF0sIm5hbWUiOiJDRC1NQVRURV9CTEFDSyIsInBick1ldGFsbGljUm91Z2huZXNzIjp7ImJhc2VDb2xvckZhY3RvciI6WzAuODAwMDAwMDExOTIwOTI5LDAuODAwMDAwMDExOTIwOTI5LDAuODAwMDAwMDExOTIwOTI5LDFdLCJtZXRhbGxpY0ZhY3RvciI6MCwicm91Z2huZXNzRmFjdG9yIjowLjV9fV0sIm1lc2hlcyI6W3sibmFtZSI6ImJqN3lubGdoN2g0ZCIsInByaW1pdGl2ZXMiOlt7ImF0dHJpYnV0ZXMiOnsiUE9TSVRJT04iOjAsIk5PUk1BTCI6MSwiVEVYQ09PUkRfMCI6Mn0sImluZGljZXMiOjMsIm1hdGVyaWFsIjowfSx7ImF0dHJpYnV0ZXMiOnsiUE9TSVRJT04iOjQsIk5PUk1BTCI6NSwiVEVYQ09PUkRfMCI6Nn0sImluZGljZXMiOjcsIm1hdGVyaWFsIjoxfSx7ImF0dHJpYnV0ZXMiOnsiUE9TSVRJT04iOjgsIk5PUk1BTCI6OSwiVEVYQ09PUkRfMCI6MTB9LCJpbmRpY2VzIjoxMSwibWF0ZXJpYWwiOjJ9LHsiYXR0cmlidXRlcyI6eyJQT1NJVElPTiI6MTIsIk5PUk1BTCI6MTMsIlRFWENPT1JEXzAiOjE0fSwiaW5kaWNlcyI6MTUsIm1hdGVyaWFsIjozfSx7ImF0dHJpYnV0ZXMiOnsiUE9TSVRJT04iOjE2LCJOT1JNQUwiOjE3LCJURVhDT09SRF8wIjoxOH0sImluZGljZXMiOjE5LCJtYXRlcmlhbCI6NH1dfV0sImFjY2Vzc29ycyI6W3siYnVmZmVyVmlldyI6MCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjQyLCJtYXgiOlstMjg3LjM5MzY3Njc1NzgxMjUsNy4zMTgxODEwMzc5MDI4MzIsLTYyLjMxNjAyNDc4MDI3MzQ0XSwibWluIjpbLTQzNS4zMzY2Mzk0MDQyOTY5LDcuMzE4MTc2MjY5NTMxMjUsLTEyMS40MTY1NDk2ODI2MTcxOV0sInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3IjoxLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6NDIsInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3IjoyLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6NDIsInR5cGUiOiJWRUMyIn0seyJidWZmZXJWaWV3IjozLCJjb21wb25lbnRUeXBlIjo1MTIzLCJjb3VudCI6NDIsInR5cGUiOiJTQ0FMQVIifSx7ImJ1ZmZlclZpZXciOjQsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50Ijo1MzIsIm1heCI6Wy04NS44NTY3ODEwMDU4NTkzOCw1My44MTY2NTQyMDUzMjIyNjYsLTM1LjMwOTE4ODg0Mjc3MzQ0XSwibWluIjpbLTQyNC44MzAzNTI3ODMyMDMxLC01NC4yNzE1MDcyNjMxODM1OTQsLTI4NC43MTk3MjY1NjI1XSwidHlwZSI6IlZFQzMifSx7ImJ1ZmZlclZpZXciOjUsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50Ijo1MzIsInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3Ijo2LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6NTMyLCJ0eXBlIjoiVkVDMiJ9LHsiYnVmZmVyVmlldyI6NywiY29tcG9uZW50VHlwZSI6NTEyMywiY291bnQiOjU0MCwidHlwZSI6IlNDQUxBUiJ9LHsiYnVmZmVyVmlldyI6OCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjY4MCwibWF4IjpbLTk2LjY4Nzc0NDE0MDYyNSw1NC4yMTg0OTgyMjk5ODA0NywtODYuNTQ0MDU5NzUzNDE3OTddLCJtaW4iOlstNDE3LjMwNjcwMTY2MDE1NjI1LC01NC4zOTI3NzY0ODkyNTc4MSwtMjg4LjIwMzE1NTUxNzU3ODFdLCJ0eXBlIjoiVkVDMyJ9LHsiYnVmZmVyVmlldyI6OSwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjY4MCwidHlwZSI6IlZFQzMifSx7ImJ1ZmZlclZpZXciOjEwLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6NjgwLCJ0eXBlIjoiVkVDMiJ9LHsiYnVmZmVyVmlldyI6MTEsImNvbXBvbmVudFR5cGUiOjUxMjMsImNvdW50Ijo2OTYsInR5cGUiOiJTQ0FMQVIifSx7ImJ1ZmZlclZpZXciOjEyLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTc0LCJtYXgiOlstMjg0LjcwMjIwOTQ3MjY1NjI1LDI0LjU5NzI0NjE3MDA0Mzk0NSwtMjYwLjU0MTIyOTI0ODA0NjldLCJtaW4iOlstMzU3Ljc1NDA1ODgzNzg5MDYsLTI0Ljc3MTUxODcwNzI3NTM5LC0yODUuNjg0MTQzMDY2NDA2MjVdLCJ0eXBlIjoiVkVDMyJ9LHsiYnVmZmVyVmlldyI6MTMsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxNzQsInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3IjoxNCwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE3NCwidHlwZSI6IlZFQzIifSx7ImJ1ZmZlclZpZXciOjE1LCJjb21wb25lbnRUeXBlIjo1MTIzLCJjb3VudCI6MTc0LCJ0eXBlIjoiU0NBTEFSIn0seyJidWZmZXJWaWV3IjoxNiwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjM3NzgsIm1heCI6Wy01LjQwMjA5OTYwOTM3NSwxMDEuMTE4ODIwMTkwNDI5NjksLTEuMTU5MDI3MDk5NjA5Mzc1XSwibWluIjpbLTUwNS44MTAzNjM3Njk1MzEyNSwtMTAxLjI5MzExMzcwODQ5NjEsLTI4OC4yMDMxNTU1MTc1NzgxXSwidHlwZSI6IlZFQzMifSx7ImJ1ZmZlclZpZXciOjE3LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6Mzc3OCwidHlwZSI6IlZFQzMifSx7ImJ1ZmZlclZpZXciOjE4LCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6Mzc3OCwidHlwZSI6IlZFQzIifSx7ImJ1ZmZlclZpZXciOjE5LCJjb21wb25lbnRUeXBlIjo1MTIzLCJjb3VudCI6Mzc4NiwidHlwZSI6IlNDQUxBUiJ9XSwiYnVmZmVyVmlld3MiOlt7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6NTA0LCJieXRlT2Zmc2V0IjowfSx7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6NTA0LCJieXRlT2Zmc2V0Ijo1MDR9LHsiYnVmZmVyIjowLCJieXRlTGVuZ3RoIjozMzYsImJ5dGVPZmZzZXQiOjEwMDh9LHsiYnVmZmVyIjowLCJieXRlTGVuZ3RoIjo4NCwiYnl0ZU9mZnNldCI6MTM0NH0seyJidWZmZXIiOjAsImJ5dGVMZW5ndGgiOjYzODQsImJ5dGVPZmZzZXQiOjE0Mjh9LHsiYnVmZmVyIjowLCJieXRlTGVuZ3RoIjo2Mzg0LCJieXRlT2Zmc2V0Ijo3ODEyfSx7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6NDI1NiwiYnl0ZU9mZnNldCI6MTQxOTZ9LHsiYnVmZmVyIjowLCJieXRlTGVuZ3RoIjoxMDgwLCJieXRlT2Zmc2V0IjoxODQ1Mn0seyJidWZmZXIiOjAsImJ5dGVMZW5ndGgiOjgxNjAsImJ5dGVPZmZzZXQiOjE5NTMyfSx7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6ODE2MCwiYnl0ZU9mZnNldCI6Mjc2OTJ9LHsiYnVmZmVyIjowLCJieXRlTGVuZ3RoIjo1NDQwLCJieXRlT2Zmc2V0IjozNTg1Mn0seyJidWZmZXIiOjAsImJ5dGVMZW5ndGgiOjEzOTIsImJ5dGVPZmZzZXQiOjQxMjkyfSx7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6MjA4OCwiYnl0ZU9mZnNldCI6NDI2ODR9LHsiYnVmZmVyIjowLCJieXRlTGVuZ3RoIjoyMDg4LCJieXRlT2Zmc2V0Ijo0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rY4jwKSNg8O4VCDDcS7qQKSNg8MIuRzDqI4jwMhcecMIuRzDdi7qQMhcecMIuRzDqI4jwMhcecO4VCDDcS7qQKSNg8PITQ20AACAP88WNrTITQ20AACAP88WNrTITQ20AACAP88WNrQAAAAAAACAPwTFMLQAAAAAAACAPwTFMLQAAAAAAACAPwTFMLQAAAAAAACAP9GXyrMAAAAAAACAP9GXyrMAAAAAAACAP9GXyrMAAAAA//9/P/m6J7MAAAAA//9/P/m6J7MAAAAA//9/P/m6J7N2wjK0//9/P5dzhDN2wjK0//9/P5dzhDN2wjK0//9/P5dzhDMmgQc1AACAP5uGUbMmgQc1AACAP5uGUbMmgQc1AACAP5uGUbPLLnwyAACAP4xwtbPLLnwyAACAP4xwtbPLLnwyAACAP4xwtbNctguzAACAP/47r7NctguzAACAP/47r7NctguzAACAP/47r7MAAAAAAACAP+HSt7MAAAAAAACAP+HSt7MAAAAAAACAP+HSt7MAAAAAAACAP18IjzQAAAAAAACAP18IjzQAAAAAAACAP18IjzTXKcW+8UFsPwAAmDQAAAAAAACAP0rksDQAAAAAAACAP0rksDQAAAAAAACAP/isFbQe2Lq8Teh/P0NdabwLmhU+8kFsP1dstj4sH5K8Teh/P9vXpDwAAAAAAACAP6LjELQAAAAAAACAP6LjELQAAAAAAACAPz8sErQAAAAAAACAPz8sErQAAAAAAACAPz8sErQAAAAA//9/PwzIE7QAAAAA//9/PwzIE7QAAAAA//9/PwzIE7QAAAAA//9/P5JNvLQAAAAA//9/P5JNvLQAAAAA//9/P5JNvLT5mb00AACAP4jeCzP5mb00AACAP4jeCzP5mb00AACAP4jeCzNNfT41AACAPysy6TRNfT41AACAPysy6TRNfT41AACAPysy6TSdUd80AACAv1V8mTSdUd80AACAv1V8mTSdUd80AACAv1V8mTTe2aG0AACAv1fgXzPe2aG0AACAv1fgXzPe2aG0AACAv1fgXzPKYAwyAACAv6koATTKYAwyAACAv6koATTKYAwyAACAv6koATSztYOyAACAvwAAAICztYOyAACAvwAAAICztYOyAACAvwAAAIC1k+6yAACAv28hFjS1k+6yAACAv28hFjS1k+6yAACAv28hFjTpZ6gy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sDzIthi1fL9cQCg/AAAAALfxQD9cQCg/AAAAALfxQD9cQCg/AAAAALfxQD9MQCg/AAAAAMbxQD9MQCg/AAAAAMbxQD9MQCg/AAAAAMbxQD8QnHc/AAAAANkBgr4QnHc/AAAAANkBgr4QnHc/AAAAANkBgr4fnHc/AAAAAGoBgr4fnHc/AAAAAGoBgr4fnHc/AAAAAGoBgr4AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQBiAGMAZABlAGYAZwBoAGkAagBrAGwAbQBuAG8AcABxAHIAcwB0AHUAdgB3AHgAeQB6AHsAfAB9AH4AfwCAAIEAggCDAIQAhQCGAIcAiACJAIoAiwCMAI0AjgCPAJAAkQCSAJMAlACVAJYAlwCYAJkAmgCbAJwAnQCeAJ8AoAChAKIAowCkAKUApgCnAKgAqQCqAKsArACtAK4ArwCwALEAsgCzALQAtQC2ALcAuAC5ALoAuwC8AL0AvgC/AMAAwQDCAMMAxADFAMYAxwDIAMkAygDLAMwAzQDOAM8AzgDNANAA0QDSANMA1ADVANYA1wDYANkA2gDbANwA3QDeAN8A4ADhAOIA4wDkAOUA5gDnAOgA6QDqAOsA7ADtAO4A7wDwAPEA8gDzAPQA9QD2APcA+AD5APoA+wD8AP0A/gD/AAABAQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BDgENARABEQESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BLwEwATEBMgEzATQBNQE2ATYBNwE0ATgBOQE6ATsBPAE9AT4BPwFAAUEBQgFDAUQBRQFGAUcBSAFJAUoBSwFMAU0BTgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBoAGfAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBuAG5AboBuwG8Ab0BvgG/AcABwQHCAcMBxAHFAcYBxwHIAckBygHLAcwBzQHOAc8B0AHRAdIB0wHUAdUB1gHXAdgB2QHaAdsB3AHdAd4B3wHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMB9AH1AfYB9wH4AfkB+gH7AfwB/QH+Af8BAAIBAgICAwIEAgUCBgIHAggCCQIKAgsCDAINAg4CDwIQAhECEgITAghQxsLEXx/BfNmywiBgwcLEXx/BU8m3wmqu98LHXx/BQff3wrLO7cLHXx/BF+f8wmqu98LHXx/BQff3wiBgwcLEXx/BU8m3wmqu98LHXx/BQff3wrLO7cLHXx/BF+f8wvg+A8PKXx/BlxIcw/g+A8PKXx/BlxIcw6MeDcPKXx/BlxIcw2qu98LHXx/BQff3wk3+FsO2xKDAjSk8w6MeDcPKXx/BlxIcwxjIC8O4xKDA4MI/wxjIC8O4xKDA4MI/w6MeDcPKXx/BlxIcw/g+A8PKXx/BlxIcw0J2GcOf1ghBjSk8wzFQCcOi1ghB4MI/w8hFKMOZ1ghBo2d3w0J2GcOZ1ghBjt95w8hFKMOZ1ghBo2d3wzFQCcOi1ghB4MI/w1DkI8MJMZtAMiBmw1g6JsMHMZtA4P9vw3Uom8MHMZtA4P9vw3Uom8MHMZtA4P9vwwxAmsMJMZtAMiBmw1DkI8MJMZtAMiBmw4+4m8MHMZtAtu90w2uooMMHMZtAtu90w9gUk8MjMZtAAanBwtgUk8MjMZtAAanBwgMljsMiMZtA2JjGwo+4m8MHMZtAtu90wzzqGsMQMZtAxlRDwyNiHcMOMZtAdTRNwyJxisMkMZtAU8m3wluRjcMiMZtA+hPJwiJxisMkMZtAU8m3wiNiHcMOMZtAdTRNw3d4nsPVb7K9jhewwqjapcMWwu/ADJixwop6pcMZwu/A2h3Dwnd4nsPVb7K9jhewwop6pcMZwu/A2h3Dwm9YnsM+cLK9hR3CwsFdsMPFXx/B2h3Dwop6pcMZwu/A2h3DwrI9sMPEXx/B4Ri0wrI9sMPEXx/B4Ri0wop6pcMZwu/A2h3DwqjapcMWwu/ADJixwsFdsMPFXx/B2h3DwrI9sMPEXx/B4Ri0wkKn0MOmxKDANBu7wsFdsMPFXx/B2h3DwkKn0MOmxKDANBu7wm570MOmxKDATw/GwgyqD8MGFlnCIOGLw3knB8MGFlnCrCqKw/E+DsMGFlnCbwyKw/CUCsMGFlnCIGaJw/E+DsMGFlnCbwyKw3knB8MGFlnCrCqKwy9dDsMGFlnCdYiNw5zaBcMGFlnCAdKLwwyqD8MGFlnCIOGLw/CUCsMGFlnCH1yOw3knB8MGFlnCk5eNwy9dDsMGFlnCdYiNw5zaBcMGFlnCAdKLwy9dDsMGFlnCdYiNw3knB8MGFlnCk5eNwzFQCcNtjv/A4MI/w0J2GcNyjv/AjSk8w8hFKMN9jv/Ao2d3w8hFKMN9jv/Ao2d3w0J2GcN9jv/Ajt95wzFQCcNtjv/A4MI/w1g6JsPBxKDA4P9vw1DkI8O/xKDAMiBmw3Uom8PBxKDA4P9vwwxAmsO/xKDAMiBmw3Uom8PBxKDA4P9vw1DkI8O/xKDAMiBmwyNiHcO5xKDAdTRNwzzqGsO4xKDAxlRDwyJxisOjxKDAU8m3wiJxisOjxKDAU8m3wluRjcOmxKDA+hPJwiNiHcO5xKDAdTRNw2uooMPBxKDAtu90w4+4m8PBxKDAtu90w9gUk8OlxKDAAanBwgMljsOmxKDA2JjGwtgUk8OlxKDAAanBwo+4m8PBxKDAtu90w6MeDcM8XW7BlxIcw03+FsOF3kbBjSk8wxjIC8OD3kbB4MI/w6MeDcM8XW7BlxIcwxjIC8OD3kbB4MI/w/g+A8M8XW7BlxIcw7LO7cI5XW7BF+f8wmqu98I3XW7BQff3wvg+A8M8XW7BlxIcw6MeDcM8XW7BlxIcw/g+A8M8XW7BlxIcw2qu98I3XW7BQff3wiBgwcJ83kbBU8m3wghQxsJ93kbBfNmywmqu98I3XW7BQff3wiBgwcJ83kbBU8m3wmqu98I3XW7BQff3wrLO7cI5XW7BF+f8wrI9sMM1XW7B4Ri0wsFdsMM3XW7B2h3DwkKn0MMWwu/ANBu7wkKn0MMWwu/ANBu7wsFdsMM3XW7B2h3Dwm570MMZwu/ATw/Gwop6pcN+3kbB2h3DwsFdsMM3XW7B2h3DwrI9sMM1XW7B4Ri0wop6pcN+3kbB2h3DwrI9sMM1XW7B4Ri0wqjapcN93kbBDJixwi9Vk8OkxKDAjxatwgnVksOlxKDAWp3Bwm9YnsOlxKDAhR3Cwm9YnsOlxKDAhR3Cwnd4nsOkxKDAjhewwi9Vk8OkxKDAjxatwqjapcN93kbBDJixwnd4nsOkxKDAjhewwop6pcN+3kbB2h3Dwop6pcN+3kbB2h3Dwnd4nsOkxKDAjhewwm9YnsOlxKDAhR3CwlDkI8O/xKDAMiBmw1DkI8MJMZtAMiBmwwxAmsO/xKDAMiBmwwxAmsMJMZtAMiBmw3Uom8PBxKDA4P9vw3Uom8MHMZtA4P9vw1g6JsPBxKDA4P9vw1g6JsMHMZtA4P9vw0J2GcN9jv/Ajt95w0J2GcOZ1ghBjt95wzFQCcOi1ghB4MI/wzFQCcOi1ghB4MI/wzFQCcNtjv/A4MI/w0J2GcN9jv/Ajt95w8hFKMOZ1ghBo2d3w8hFKMN9jv/Ao2d3w0J2GcNyjv/AjSk8w0J2GcNyjv/AjSk8w0J2GcOf1ghBjSk8w8hFKMOZ1ghBo2d3wzzqGsO4xKDAxlRDwzzqGsMQMZtAxlRDwyZqisMjMZtAVtm3wjzqGsO4xKDAxlRDwyZqisMjMZtAVtm3wiJxisOjxKDAU8m3wluRjcOmxKDA+hPJwluRjcMiMZtA+hPJwiNiHcMOMZtAdTRNwyNiHcMOMZtAdTRNwyNiHcO5xKDAdTRNw1uRjcOmxKDA+hPJwo+4m8PBxKDAtu90w4+4m8MHMZtAtu90wwMljsOmxKDA2JjGwgMljsMiMZtA2JjGwmuooMMHMZtAtu90w2uooMPBxKDAtu90w9gUk8OlxKDAAanBwtgUk8OlxKDAAanBwtgUk8MjMZtAAanBwmuooMMHMZtAtu90w4+4m8MHMZtAtu90w4+4m8PBxKDAtu90w2uooMPBxKDAtu90w2uooMMHMZtAtu90wxjIC8OD3kbB4MI/wxjIC8O4xKDA4MI/w/g+A8M8XW7BlxIcw/g+A8PKXx/BlxIcw/g+A8M8XW7BlxIcwxjIC8O4xKDA4MI/w/g+A8M8XW7BlxIcw/g+A8PKXx/BlxIcw7LO7cLHXx/BF+f8wrLO7cLHXx/BF+f8wrLO7cI5XW7BF+f8wvg+A8M8XW7BlxIcw7LO7cI5XW7BF+f8wrLO7cLHXx/BF+f8wiBgwcJ83kbBU8m3wiBgwcLEXx/BU8m3wiBgwcJ83kbBU8m3wrLO7cLHXx/BF+f8wghQxsJ93kbBfNmywghQxsLEXx/BfNmywmqu98I3XW7BQff3wmqu98LHXx/BQff3wmqu98I3XW7BQff3wghQxsLEXx/BfNmywmqu98I3XW7BQff3wmqu98LHXx/BQff3wqMeDcPKXx/BlxIcw6MeDcPKXx/BlxIcw6MeDcM8XW7BlxIcw2qu98I3XW7BQff3wqMeDcM8XW7BlxIcw6MeDcPKXx/BlxIcw03+FsOF3kbBjSk8w03+FsO2xKDAjSk8w03+FsOF3kbBjSk8w6MeDcPKXx/BlxIcw1Sdn8Mwwu/A1lVpw1Sdn8OXjiPA1lVpw77pnsMuwu/AuJFiw77pnsOUjiPAuJFiw77pnsMuwu/AuJFiw1Sdn8OXjiPA1lVpw6MeDcP/lRxBlxIcw6MeDcNxk2tBlxIcw03+FsO1FERBjSk8w03+FsO1FERBjSk8w03+FsMRMZtAjSk8w6MeDcP/lRxBlxIcwxjIC8MQMZtA4MI/wxjIC8O4FERB4MI/w/g+A8Nxk2tBlxIcw/g+A8Nxk2tBlxIcw/g+A8P/lRxBlxIcwxjIC8MQMZtA4MI/w03+FsO1FERBjSk8w6MeDcNxk2tBlxIcwxjIC8O4FERB4MI/wxjIC8O4FERB4MI/w6MeDcNxk2tBlxIcw/g+A8Nxk2tBlxIcw6MeDcP/lRxBlxIcw03+FsMRMZtAjSk8wxjIC8MQMZtA4MI/w6MeDcP/lRxBlxIcwxjIC8MQMZtA4MI/w/g+A8P/lRxBlxIcw2qu98IClhxBQff3wmqu98J2k2tBQff3wqMeDcP/lRxBlxIcw6MeDcNxk2tBlxIcw6MeDcP/lRxBlxIcw2qu98J2k2tBQff3wghQxsIFlhxBfNmywghQxsK9FERBfNmywmqu98J2k2tBQff3wmqu98J2k2tBQff3wmqu98IClhxBQff3wghQxsIFlhxBfNmywrLO7cIClhxBF+f8wrLO7cJ0k2tBF+f8wiBgwcK+FERBU8m3wiBgwcK+FERBU8m3wiBgwcIFlhxBU8m3wrLO7cIClhxBF+f8wvg+A8P/lRxBlxIcw/g+A8Nxk2tBlxIcw7LO7cIClhxBF+f8wrLO7cJ0k2tBF+f8wrLO7cIClhxBF+f8wvg+A8Nxk2tBlxIcwwhQxsK9FERBfNmywiBgwcK+FERBU8m3wmqu98J2k2tBQff3wmqu98J2k2tBQff3wiBgwcK+FERBU8m3wrLO7cJ0k2tBF+f8wmqu98J2k2tBQff3wrLO7cJ0k2tBF+f8wvg+A8Nxk2tBlxIcw/g+A8Nxk2tBlxIcw6MeDcNxk2tBlxIcw2qu98J2k2tBQff3wrLO7cIClhxBF+f8wmqu98IClhxBQff3wvg+A8P/lRxBlxIcw6MeDcP/lRxBlxIcw/g+A8P/lRxBlxIcw2qu98IClhxBQff3wiBgwcIFlhxBU8m3wghQxsIFlhxBfNmywmqu98IClhxBQff3wmqu98IClhxBQff3wrLO7cIClhxBF+f8wiBgwcIFlhxBU8m3wgnVksOlxKDAWp3BwgnVksM8cLK9Wp3Bwm9YnsOlxKDAhR3Cwm9YnsM+cLK9hR3Cwm9YnsOlxKDAhR3CwgnVksM8cLK9Wp3Bwm9YnsOlxKDAhR3Cwm9YnsM+cLK9hR3Cwop6pcMZwu/A2h3Dwop6pcMZwu/A2h3Dwop6pcN+3kbB2h3Dwm9YnsOlxKDAhR3Cwop6pcN+3kbB2h3Dwop6pcMZwu/A2h3DwsFdsMM3XW7B2h3DwsFdsMPFXx/B2h3DwsFdsMM3XW7B2h3Dwop6pcMZwu/A2h3DwsFdsMM3XW7B2h3DwsFdsMPFXx/B2h3Dwm570MOmxKDATw/Gwm570MOmxKDATw/Gwm570MMZwu/ATw/GwsFdsMM3XW7B2h3DwkKn0MMWwu/ANBu7wkKn0MOmxKDANBu7wrI9sMPEXx/B4Ri0wrI9sMPEXx/B4Ri0wrI9sMM1XW7B4Ri0wkKn0MMWwu/ANBu7wrI9sMM1XW7B4Ri0wrI9sMPEXx/B4Ri0wqjapcN93kbBDJixwqjapcMWwu/ADJixwqjapcN93kbBDJixwrI9sMPEXx/B4Ri0wqjapcN93kbBDJixwqjapcMWwu/ADJixwnd4nsPVb7K9jhewwnd4nsPVb7K9jhewwnd4nsOkxKDAjhewwqjapcN93kbBDJixwnd4nsOkxKDAjhewwnd4nsPVb7K9jhewwi9Vk8OkxKDAjxatwi9Vk8PCb7K9jxatwi9Vk8OkxKDAjxatwnd4nsPVb7K9jhewwmIMuMPgnVrBvy4mw2570MMZwu/ATw/Gwm570MOmxKDATw/Gwm570MOmxKDATw/GwmIMuMPMXx/Bvy4mw2IMuMPgnVrBvy4mw4hvtsPLXx/Br8wiw2IMuMPMXx/Bvy4mw1j1zcOmxKDATw/Gwlj1zcOmxKDATw/GwmIMuMPMXx/Bvy4mw2570MOmxKDATw/GwohvtsPLXx/Br8wiw1j1zcOmxKDATw/Gwlj1zcMZwu/ATw/Gwlj1zcMZwu/ATw/GwohvtsPgnVrBr8wiw4hvtsPLXx/Br8wiw4hvtsPgnVrBr8wiw1j1zcMZwu/ATw/GwmIMuMPgnVrBvy4mw2IMuMPgnVrBvy4mw1j1zcMZwu/ATw/Gwm570MMZwu/ATw/Gwr7pnsMuwu/AuJFiw6CsqsPEwAHBNK9Cw9nUq8PDwAHBS8JHw77pnsMuwu/AuJFiw9nUq8PDwAHBS8JHw1Sdn8Mwwu/A1lVpw1Sdn8Mwwu/A1lVpw9nUq8PDwAHBS8JHw1Sdn8OXjiPA1lVpw9nUq8P/i3LAS8JHw1Sdn8OXjiPA1lVpw9nUq8PDwAHBS8JHw9nUq8P/i3LAS8JHw6CsqsP9i3LANK9Cw77pnsOUjiPAuJFiw9nUq8P/i3LAS8JHw77pnsOUjiPAuJFiw1Sdn8OXjiPA1lVpw77pnsOUjiPAuJFiw6CsqsP9i3LANK9Cw77pnsMuwu/AuJFiw6CsqsPEwAHBNK9Cw77pnsMuwu/AuJFiw6CsqsP9i3LANK9Cw6CsqsPEwAHBNK9Cw4hvtsPgnVrBr8wiw2IMuMPgnVrBvy4mw6CsqsPEwAHBNK9Cw2IMuMPgnVrBvy4mw9nUq8PDwAHBS8JHw9nUq8PDwAHBS8JHw2IMuMPgnVrBvy4mw9nUq8P/i3LAS8JHw2IMuMPMXx/Bvy4mw9nUq8P/i3LAS8JHw2IMuMPgnVrBvy4mw2IMuMPMXx/Bvy4mw4hvtsPLXx/Br8wiw6CsqsP9i3LANK9Cw2IMuMPMXx/Bvy4mw6CsqsP9i3LANK9Cw9nUq8P/i3LAS8JHw6CsqsP9i3LANK9Cw4hvtsPLXx/Br8wiw6CsqsPEwAHBNK9Cw4hvtsPgnVrBr8wiw6CsqsPEwAHBNK9Cw4hvtsPLXx/Br8wiw4hvtsP+lRxBr8wiw6CsqsOyZGdANK9Cw6CsqsPf7f1ANK9Cw4hvtsMS1FdBr8wiw4hvtsP+lRxBr8wiw2IMuMP+lRxBvy4mw6CsqsOyZGdANK9Cw6CsqsOyZGdANK9Cw2IMuMP+lRxBvy4mw9nUq8OxZGdAS8JHw2IMuMMS1FdBvy4mw9nUq8Pf7f1AS8JHw9nUq8OxZGdAS8JHw9nUq8OxZGdAS8JHw2IMuMP+lRxBvy4mw2IMuMMS1FdBvy4mw4hvtsMS1FdBr8wiw6CsqsPf7f1ANK9Cw2IMuMMS1FdBvy4mw2IMuMMS1FdBvy4mw6CsqsPf7f1ANK9Cw9nUq8Pf7f1AS8JHw6CsqsOyZGdANK9Cw77pnsMyZxhAuJFiw77pnsOALupAuJFiw77pnsOALupAuJFiw6CsqsPf7f1ANK9Cw6CsqsOyZGdANK9Cw6CsqsOyZGdANK9Cw9nUq8OxZGdAS8JHw77pnsMyZxhAuJFiw77pnsMyZxhAuJFiw9nUq8OxZGdAS8JHw1Sdn8MvZxhA1lVpw9nUq8Pf7f1AS8JHw1Sdn8N+LupA1lVpw1Sdn8MvZxhA1lVpw9nUq8OxZGdAS8JHw1Sdn8MvZxhA1lVpw9nUq8Pf7f1AS8JHw6CsqsPf7f1ANK9Cw77pnsOALupAuJFiw9nUq8Pf7f1AS8JHw9nUq8Pf7f1AS8JHw77pnsOALupAuJFiw1Sdn8N+LupA1lVpw1j1zcOULupATw/GwohvtsMS1FdBr8wiw2IMuMMS1FdBvy4mw1j1zcOULupATw/GwmIMuMMS1FdBvy4mw2570MOULupATw/Gwlj1zcMiMZtATw/GwohvtsP+lRxBr8wiw1j1zcOULupATw/GwohvtsMS1FdBr8wiw1j1zcOULupATw/GwohvtsP+lRxBr8wiw2IMuMP+lRxBvy4mw4hvtsP+lRxBr8wiw1j1zcMiMZtATw/GwmIMuMP+lRxBvy4mw1j1zcMiMZtATw/Gwm570MMiMZtATw/Gwm570MOULupATw/GwmIMuMMS1FdBvy4mw2570MMiMZtATw/GwmIMuMP+lRxBvy4mw2570MMiMZtATw/GwmIMuMMS1FdBvy4mw3d4nsPVb7K9jhewwnd4nsMkMZtAjhewwi9Vk8MkMZtAjxatwi9Vk8MkMZtAjxatwi9Vk8PCb7K9jxatwnd4nsPVb7K9jhewwqjapcOYLupADJixwqjapcO9FERBDJixwnd4nsPVb7K9jhewwnd4nsMkMZtAjhewwnd4nsPVb7K9jhewwqjapcO9FERBDJixwrI9sMMFlhxB4Ri0wrI9sMN3k2tB4Ri0wqjapcO9FERBDJixwqjapcO9FERBDJixwqjapcOYLupADJixwrI9sMMFlhxB4Ri0wkKn0MMiMZtANBu7wkKn0MOYLupANBu7wrI9sMMFlhxB4Ri0wrI9sMN3k2tB4Ri0wrI9sMMFlhxB4Ri0wkKn0MOYLupANBu7wsFdsMMElhxB2h3DwsFdsMN2k2tB2h3Dwm570MMiMZtATw/Gwm570MOULupATw/Gwm570MMiMZtATw/GwsFdsMN2k2tB2h3Dwop6pcOULupA2h3Dwop6pcO8FERB2h3DwsFdsMN2k2tB2h3DwsFdsMN2k2tB2h3DwsFdsMMElhxB2h3Dwop6pcOULupA2h3Dwm9YnsM+cLK9hR3Cwm9YnsMjMZtAhR3Cwop6pcOULupA2h3Dwop6pcO8FERB2h3Dwop6pcOULupA2h3Dwm9YnsMjMZtAhR3CwgnVksMjMZtAWp3Bwm9YnsMjMZtAhR3Cwm9YnsMjMZtAhR3Cwm9YnsM+cLK9hR3CwgnVksM8cLK9Wp3BwlSdn8MvZxhA1lVpw1Sdn8N+LupA1lVpw77pnsOALupAuJFiw77pnsOALupAuJFiw77pnsMyZxhAuJFiw1Sdn8MvZxhA1lVpw3d4nsMkMZtAjhewwqjapcO9FERBDJixwop6pcO8FERB2h3Dwnd4nsMkMZtAjhewwop6pcO8FERB2h3Dwm9YnsMjMZtAhR3CwgnVksMjMZtAWp3Bwi9Vk8MkMZtAjxatwm9YnsMjMZtAhR3Cwnd4nsMkMZtAjhewwm9YnsMjMZtAhR3Cwi9Vk8MkMZtAjxatwsFdsMN2k2tB2h3Dwop6pcO8FERB2h3DwrI9sMN3k2tB4Ri0wrI9sMN3k2tB4Ri0wop6pcO8FERB2h3DwqjapcO9FERBDJixwsFdsMN2k2tB2h3DwrI9sMN3k2tB4Ri0wkKn0MOYLupANBu7wsFdsMN2k2tB2h3DwkKn0MOYLupANBu7wm570MOULupATw/GwrI9sMMFlhxB4Ri0wsFdsMMElhxB2h3DwkKn0MMiMZtANBu7wkKn0MMiMZtANBu7wsFdsMMElhxB2h3Dwm570MMiMZtATw/Gwop6pcOULupA2h3DwsFdsMMElhxB2h3DwrI9sMMFlhxB4Ri0wop6pcOULupA2h3DwrI9sMMFlhxB4Ri0wqjapcOYLupADJixwqjapcOYLupADJixwnd4nsPVb7K9jhewwop6pcOULupA2h3Dwop6pcOULupA2h3Dwnd4nsPVb7K9jhewwm9YnsM+cLK9hR3CwkKn0MOmxKDANBu7wkKn0MMWwu/ANBu7wm570MOmxKDATw/Gwm570MMZwu/ATw/Gwm570MOmxKDATw/GwkKn0MMWwu/ANBu7wkKn0MOYLupANBu7wkKn0MMiMZtANBu7wm570MOULupATw/Gwm570MOULupATw/Gwm570MMiMZtATw/GwkKn0MMiMZtANBu7wtnUq8OxZGdAS8JHw9nUq8P/i3LAS8JHw1Sdn8MvZxhA1lVpw1Sdn8OXjiPA1lVpw1Sdn8MvZxhA1lVpw9nUq8P/i3LAS8JHw9nUq8P/i3LAS8JHw9nUq8OxZGdAS8JHw6CsqsOyZGdANK9Cw6CsqsP9i3LANK9Cw6CsqsOyZGdANK9Cw9nUq8P/i3LAS8JHwxiJCsM0klnCARqQw5nSBMM0klnCbdKOw9rWEMM0klnCOrmOw9ynAsM0klnCet6Lw9rWEMM0klnCOrmOw5nSBMM0klnCbdKOw9rWEMM0klnCOrmOw9ynAsM0klnCet6Lw5nSBMM0klnC7ByJw5nSBMM0klnC7ByJw5YBE8M0klnCrfeLw9rWEMM0klnCOrmOw5YBE8M0klnCrfeLw5nSBMM0klnC7ByJw2akEMM0klnCh+qIwxiJCsM0klnCWdWHw2akEMM0klnCh+qIw5nSBMM0klnC7ByJw/CUCsNBRFdCIFyOw3knB8NBRFdCk5eNwy9dDsNBRFdCdoiNw5zaBcNBRFdCAtKLwy9dDsNBRFdCdoiNw3knB8NBRFdCk5eNwy9dDsNBRFdCdoiNw5zaBcNBRFdCAtKLw3knB8NBRFdCrSqKw3knB8NBRFdCrSqKwwyqD8NBRFdCIOGLwy9dDsNBRFdCdoiNwwyqD8NBRFdCIOGLw3knB8NBRFdCrSqKw/E+DsNBRFdCcAyKw/CUCsNBRFdCIWaJw/E+DsNBRFdCcAyKw3knB8NBRFdCrSqKw5YBE8O+31hCrveLw5nSBMO+31hC7RyJw2akEMO+31hCh+qIwxiJCsO+31hCWdWHw2akEMO+31hCh+qIw5nSBMO+31hC7RyJw9rWEMO+31hCO7mOw9ynAsO+31hCet6Lw5nSBMO+31hC7RyJw5YBE8O+31hCrveLwxiJCsO+31hCARqQw5nSBMO+31hCbtKOw9rWEMO+31hCO7mOw9ynAsO+31hCet6Lw9rWEMO+31hCO7mOw5nSBMO+31hCbtKOw/CUCsOfolZCIFyOw3knB8OfolZCk5eNwy9dDsOfolZCdoiNw5zaBcOfolZCAtKLwy9dDsOfolZCdoiNw3knB8OfolZCk5eNwy9dDsOfolZCdoiNw5zaBcOfolZCAtKLw3knB8OfolZCrSqKw3knB8OfolZCrSqKwwyqD8OfolZCIOGLwy9dDsOfolZCdoiNwwyqD8OfolZCIOGLw3knB8OfolZCrSqKw/E+DsOfolZCcAyKw/CUCsOfolZCIWaJw/E+DsOfolZCcAyKw3knB8OfolZCrSqKwwAAAAAAAIA/ZWxPswAAAAAAAIA/ZWxPswAAAAAAAIA/ZWxPswAAAAAAAIA/zIqGswAAAAAAAIA/zIqGswAAAAAAAIA/zIqGs39wubQAAIA/Qqirs39wubQAAIA/Qqirs1d6PDrg/38/ELzvOpnJwDfg/38/ZcsAO/4YGDzA938/BtNSPAAAAAAAAIA/pXa/s8UiNj2wRn0/GNoNPrDlNT3ezn0/yHz7PRkMAT1SbX0/US0NPlzOwLtUKH0/Tg0YPk1zfzwVqH0/3k8JPpBS/rqCmH0/Xv8LPqapQrT//38/fsBUs6apQrT//38/fsBUs6apQrT//38/fsBUs22MkbMAAIA/+pEXtG2MkbMAAIA/+pEXtG2MkbMAAIA/+pEXtAAAAAAAAIA/AGvPswAAAAAAAIA/AGvPswAAAAAAAIA/AGvPswAAAAAAAIA/LWvPswAAAAAAAIA/LWvPswAAAAAAAIA/LWvPswAAAAAAAIA/GpfBswAAAAAAAIA/GpfBswAAAAAAAIA/GpfBs2QurjMAAIA/ttzHs2QurjMAAIA/ttzHs2QurjMAAIA/ttzHswAAAAAAAIA/L8XNswAAAAAAAIA/L8XNswAAAAAAAIA/L8XNswAAAAD//38/JWXdswAAAAD//38/JWXdswAAAAD//38/JWXdszXF4z4GAWW/nbIxPdpS5T7z0GS/A3+0PMnG3z7ax2W/pSlsPXC46T70u2O/IEKDPJkS8T5htWG/tk79PCCu6z7/PWO/Q3hRPBpI6z1S632/AgtgPc/Bvj083X6/R6NavOSX2z3ndH6/3ZG7vOisCD6MtX2/cB3Cuq0UxD1m0H6/xscPPLFTzz26rH6/xGoRPAtZCb5brn2/TnDZO1C+w73D0n6/C+7GOwafnr34OX+/YkjDO2XwCb5zqX2/FmXHu5Som71iQn+/IyGUutq4nL0SP3+/08WcuyW7GzUAAIC/AAAAgCW7GzUAAIC/AAAAgCW7GzUAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgEh2sjMAAIC/AAAAgEh2sjMAAIC/AAAAgEh2sjMAAIC/AAAAgN1TKbUAAIC/AAAAgN1TKbUAAIC/AAAAgN1TKbUAAIC/AAAAgKypQjT//3+/5AlSM6ypQjT//3+/5AlSM6ypQjT//3+/5AlSMwAAAAAAAIC/nroGNAAAAAAAAIC/nroGNAAAAAAAAIC/nroGNAAAAAAAAIC/AGvPMwAAAAAAAIC/AGvPMwAAAAAAAIC/AGvPMwAAAAAAAIC/LWvPMwAAAAAAAIC/LWvPMwAAAAAAAIC/LWvPMwAAAAAAAIC/Cd5zMwAAAAAAAIC/Cd5zMwAAAAAAAIC/Cd5zM3OFljP//3+/L9QRNHOFljP//3+/L9QRNHOFljP//3+/L9QRNAAAAAAAAIC/H5fBMwAAAAAAAIC/H5fBMwAAAAAAAIC/H5fBMwAAAAAAAIC/ttzHMwAAAAAAAIC/ttzHMwAAAAAAAIC/ttzHM/qZCLyGr3+/XgZIvU+Zt7yQT3+/wP2OvTWNQrwtXX+/VTaOvZT+IrxrRH+/On+ZvejbQbw4XX+/ozWOvacfEzm0X3+/OyePvU/ERruk/3+/RQutOtj63Dl7/3+/oKOBu0jxb7n5/3+/kipnOkgflDuX+3+/5wovvGITYLr5/3+/39mkuRYc2Lp7/3+/0E5tuy6aCj0ijn+/KpVFPWldKj2Fjn+/mF8qPcidND2/fn+/JgE3PXZwpzyFrH+/B/U8PexN/Tz9gn+/NN1aPRNd6jw6e3+/qsJoPV034z0iTX4/uzr4vEtI7D3flX0/82KXPd9PZz9Sntk+OU9dvURl7z2ZdQU/gGZYv/dUFz2hzn8/nplCPNT8PDwVFw0/I5dVP7Z1DL7/j30/DA9APFSkD70U138/FJ6NOyGCtL2U/34/MDnTu7jb+L1ZEn4/9Fd/PFctur0C7n4/57MSvGtH673DMn4/UMfrvIdj8jEAAIA/vFVHs4dj8jEAAIA/vFVHs3Dk3j2ken4/gCC9OmGOyD2ken4/oZhCPY5EHTsHxX8/yHEtvQAAAAAAAIA/JtZis5/o2767/mY/KoMVvdS4974CzV8/XgAmvarf2r5BWmc/eNS+vHnS377COWY/fMo1vEi9+75ivF4/qXsQvVtB7L7lx2E/ucDEPQAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAv0yndj8AAAAApxWJvkyndj8AAAAApxWJvkyndj8AAAAApxWJvkundj8AAAAAqxWJvkundj8AAAAAqxWJvkundj8AAAAAqxWJvkBbeL8AAAAAW1t4PkBbeL8AAAAAW1t4PkBbeL8AAAAAW1t4PkJbeL8AAAAAQ1t4PkJbeL8AAAAAQ1t4PkJbeL8AAAAAQ1t4PkyVJT9Q+/m5IT1DP8mXJT8AAAAACDtDP++LJT/HaQk6EkVDP/SdJT9vgdG6sjVDPyuXJT9uVhq6jTtDPy6UJT+6Kpi6Cj5DP+/EI78AAAAAScNEv+/EI78AAAAAScNEv+/EI78AAAAAScNEv/LEI78AAAAASMNEv/LEI78AAAAASMNEv/LEI78AAAAASMNEv9qpez8AAAAAM647vtqpez8AAAAAM647vtqpez8AAAAAM647vtqpez8AAAAAM647vqPNe78AAAAA8qc4PqPNe78AAAAA8qc4PqPNe78AAAAA8qc4PqDNe78AAAAAFKg4PqDNe78AAAAAFKg4PqDNe78AAAAAFKg4PgAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAv1n6eD8AAAAAUjFuvln6eD8AAAAAUjFuvsGEdD8AfLy2Bp2Xvjj6eD86YA27CDFuvojqeD92mLY8BiJuvl76eD8AAAAALDFuvv9qbj+bHl47kXa6vvWEbD+FeFMvaOfDvrlObD8AAAAAhuzEvrZObD8AAAAAmezEvqn/aj9jXKCwpRfLvoVxbj8AACAxSFe6vr1SVz8EalY8E2wKv3ZXVz8AAAAAHG8Kv3ZXVz8AAAAAHG8Kv3VXVz8AAAAAH28Kv3VXVz8AAAAAH28Kv9/rYj+HPtcx+QDtvtNQUL8AAAAADcwUP9NQUL8AAAAADcwUPz/dWb8ABAg22m0GP1idT79ShHG0EcYVP85QUL8ffOg65csUP+NQUL8AAAAA9MsUPxydYb9Vp3k5IvLxPvVlYb8y8Zm7XbzyPqJcYL/sYh27I472PsWCYb9jnw+8qEnyPuEzYb+Ld2ovF3nzPp2dYb8AAAAASPDxPuOtdL9+otU6KJKWPmtVdb8wf6g5cECSPvitdL8AAAAANZKWPvmtdL8AAAAAMZKWPvmtdL8AAAAAMZKWPnbYbL8AELY2QlLCPs+qej8AAAAAvOtPvs+qej8AAAAAvOtPvs+qej8AAAAAvOtPvv+qej8AAAAAIehPvv+qej8AAAAAIehPvv+qej8AAAAAIehPvnDcdL9wELM5zWKVPuGtdL8I69u6I5KWPvitdL8AAAAAMZKWPvitdL8AAAAANZKWPvitdL8AAAAANZKWPnfcdL+5D665pmKVPl76eD8AAAAANTFuvl76eD8AAAAANTFuvnH9dz9WN427OBx+vpvxeD8x34e8pChuvjj6eD+BhBA74TBuvmD6eD8AAAAABzFuvquZt7yRT38/vf2Ovdux8rwuOn8/YfmSvQoOhLxTXn8//OyLvRntyjvwWX8/oSaRvYcUqruhSX8/bE+YvWAEGzl8X38//z+PvaYIiDz1v36/YkXHPboiNj2vRn2/G9oNPoTgwDzve32/JioNPst5wzxYp32/ViUIPoarwDz5e32/LyoNPpJS/rqAmH2/dP8LPvRlYb8y8Zk7ZbzyPmHAYb+5y825ZW7xPhUbYb8qbqQ5ttTzPmQyYb8q/q+tk37zPpNhYb/K5R87587yPjjBYb+SVNKvS2vxPtxQUL8AAAAAAMwUP9xQUL8AAAAAAMwUP/zhT78uCLG5vWYVP6NQUL+JpD+70csUP1OdT78f/q0vGMYVP95QUL8AAAAA+8sUP3+ZVz9pluo4KwgKv7tSVz8Fala8FGwKv3RXVz8AAAAAHW8Kv3VXVz8AAAAAHm8Kv3VXVz8AAAAAHm8Kv5+ZVz8ALby0/QcKvyaGbD9oDTcvoOHDvprjbT8uSCW7Oya9vgggbD9VOpU5CMzFvqv/aj+RliuvnhfLvp9ObD80DfU6c+zEvnjobT/gPMsw6w69vmldKj2Ejn8/d2AqPbsWBj3SjX8/ixFJPSy8Zjzg6n8/1gWtPKAC/DyzgX8/gr1cPQAMBj3RjX8/AxtJPZxd6jw7e38/FsJoPUz2WTqI/38/Ayhyu5+/Rruk/38/3vesOiZkfLn4/38/1jRzOnTba7r4/38/esCtuVTJmzsr/n8/Dim9u6I5w7qI/38/lDNku39wuTQAAIC/QqirM39wuTQAAIC/QqirM8GoPDrg/3+/ZcHvOmUJZDzM7H+/Pj6iPLDJwDfg/3+/Y84AOwAAAAAAAIC/nHa/M6QR4DQAAIC/ZWxPM6QR4DQAAIC/ZWxPM6QR4DQAAIC/ZWxPMwAAAAAAAIC/34qGMwAAAAAAAIC/34qGMwAAAAAAAIC/34qGM8UaMrwAAAAAIvx/P8UaMrwAAAAAIvx/P3Cy07sAAAAAo/5/P3RUKryi0Pi5dfx/P2Ho1ruBWnI6kf5/P8YaMrwAAAAAIvx/P2umD71nhJA7DNd/Pw8UEb1+Vxa63dZ/P3Pc7bxXqTg7HOR/PzXd6LxYDOi5g+V/P8SmD70AAAAAr9d/P4hwIb1B/kS6D81/PwAAAAAAAAAAAACAP1hrk7qBNte7jP5/P9dQczuOCBA7ZP9/P7SjaTncW7y76v5/P9YyQbozTIs7ZP9/P/ew0LsjawC7jP5/PwT33rwu7W64uOd/P5S16ryT22k5GOV/P5aiu7wAAAAAzu5/P5+iu7wAAAAAzu5/P5+iu7wAAAAAzu5/P3nM3rziON25wOd/P0cdXT0AAAAAcKB/v0cdXT0AAAAAcKB/v9DVVz3EfMs486R/v+bRVz3jTe819aR/v9TYVj1oKp24xqV/vy0dXT0AAAAAb6B/v7lSdT1wasY6Rop/v3qDdj3wjqm6Jol/v7pWdj0AAAAAX4l/v60rdT1KJ7+6bIp/v7BWdj0AAAAAX4l/v8yYez0OnBi5P4R/vyUHUD0AAAAAbKt/v1f+VT3IvZU5fqZ/v9sKTj3owFi6Aa1/v/g2UT3JhW+6bKp/v5sGUD11EzM7Lat/v84GUD0AAAAAbKt/v31bjz2NUwOvPl9/v8i6iz3EF304SWd/v0LGiT0AAAAAiWt/v1bGiT0AAAAAimt/v1bGiT0AAAAAimt/v6Y8ij3j9oE5imp/v1v+Tr8AAAAAgKEWv1v+Tr8AAAAAgKEWv1v+Tr8AAAAAgKEWv1f+Tr8AAAAAiKEWv1f+Tr8AAAAAiKEWv1f+Tr8AAAAAiKEWv/ArCD1YTn8/w2+GvVLJwj1EuX4/ZMb1vKYOwjySf38/hDltvS4swjyXf38/Yi9tvTmEBb3y238/c4zIuwAAAACcT38/eSiWvYYBTj8AAAAAkPoXP4YBTj8AAAAAkPoXP4YBTj8AAAAAkPoXP4EBTj8AAAAAl/oXP4EBTj8AAAAAl/oXP4EBTj8AAAAAl/oXP8yZlL1sqn6/27eSPeDuHL2kuH+/ABHaPFT3mL0rGH6/iAHFPfEG2bzRyn2/NGwDPnet6LxgM3+/lOOWPQAAAAAE7X6/Cmq7PfmEczye93+/EDXBu+GzlzwH5n+/HKWtvByRjzxp9H+/CTTfu02DlTwV9H+/QOe0uyS3qDw68X+/wBWpuxf9oDzM8n+/4oSFu3D+Tr8AAAAAZaEWv3D+Tr8AAAAAZaEWv3D+Tr8AAAAAZaEWv1X+Tr8AAAAAi6EWv1X+Tr8AAAAAi6EWv1X+Tr8AAAAAi6EWvzgim73cJ38/xnTuPGzyzb3zLX4/1H2CPX7i6Lxr3n8/7wRxPLSuIb3BbX8/+ZJcPd8mFr3iz38/RXg2PIzjIL1Ay38/zXAFPK8BTj8AAAAAWvoXP68BTj8AAAAAWvoXP68BTj8AAAAAWvoXP6ABTj8AAAAAbvoXP6ABTj8AAAAAbvoXP6ABTj8AAAAAbvoXP4iAvj1v7H2/UWixvRebsj0IUH2/BwHsvSfrDj7p1Hy/sIqSvc6B/z0KbH2/jfyIvY5YLD7dI3u/SEvFvVIYDT5CEX2/n0t8vVj+Tr8AAAAAh6EWv1j+Tr8AAAAAh6EWv1j+Tr8AAAAAh6EWv0n+Tr8AAAAAm6EWv0n+Tr8AAAAAm6EWv0n+Tr8AAAAAm6EWvxvPzr1xQX4/JkluPa8Bv709yX0/rBK9PRomyb2XUH4/PXxxPUIBH76y2Xw/r+yXPKXo0b0cH34/rWaDPa5nmr31JX8/OLH9PJQBTj8AAAAAgPoXP5QBTj8AAAAAgPoXP5QBTj8AAAAAgPoXP4QBTj8AAAAAlPoXP4QBTj8AAAAAlPoXP4QBTj8AAAAAlPoXP4sBTj8AAAAAjPoXP4sBTj8AAAAAjPoXP4sBTj8AAAAAjPoXP4sBTj8AAAAAjPoXP2UAv71AyX2/3RK9Pbco0b2UM36/xMd0PV0tyb1UUH6/SKlxPaAB0r3BHn6/NmuDPSTrH74Ozny/YTynPOdnmr3yJX+/WLj9PD/+Tr8AAAAApqEWvz/+Tr8AAAAApqEWvz/+Tr8AAAAApqEWv0z+Tr8AAAAAmKEWv0z+Tr8AAAAAmKEWv0z+Tr8AAAAAmKEWv82asj0LUH0/mgDsvaSAvj1w7H0/OGixveMNED7M1Hw/rhOOvQjeLT5GCXs/Q2TIvZeB/z0LbH0/efyIvTYYDT5DEX0/eEt8vaUBTj8AAAAAZvoXP6UBTj8AAAAAZvoXP6UBTj8AAAAAZvoXP58BTj8AAAAAcPoXP58BTj8AAAAAcPoXP58BTj8AAAAAcPoXP2ryzb3zLX6/An6CPTcim73cJ3+/fHXuPAJ+6LyC3n+/1AJxPMAFFr3wz3+/JRA3PJmuIb3BbX+/JJNcPYrjIL1Ay3+/dXEFPFP+Tr8AAAAAjKEWv1P+Tr8AAAAAjKEWv1P+Tr8AAAAAjKEWv2n+Tj8AAAAAbaEWP2n+Tj8AAAAAbaEWP2n+Tj8AAAAAbaEWP4m0lzwH5n8/7qStvD6Gczyd938/djTBu8WRjzxp9H8/VzPfu9m1qDw68X8/DRepu2mClTwV9H8/G+q0u8z7oDzM8n8/MIaFu59k8rysN38/XheUPTSZlL1sqn4/Q7iSPeh9nL1vBX4/LEDIPVxQ8ryqN38/lhmUPbiBxDzH4X8/C4uYPAAAAAAE7X4/A2q7PYoBTj8AAAAAjPoXP4oBTj8AAAAAjPoXP4oBTj8AAAAAjPoXP4UBTj8AAAAAk/oXP4UBTj8AAAAAk/oXP4UBTj8AAAAAk/oXPyScvz1owH6/kO7/vH0vCD1VTn+/qnCGvVprUD1OoX+/IYWNvOA00Dtg63+/qdLGvMgovDxyen+/ntdzvQAAAACeT3+/HyiWvVv+Tr8AAAAAgKEWv1v+Tr8AAAAAgKEWv1v+Tr8AAAAAgKEWv1f+Tr8AAAAAhqEWv1f+Tr8AAAAAhqEWv1f+Tr8AAAAAhqEWv5BYiT32Sok5dmx/v5Bbjz0AAAAAP19/v1XGiT0AAAAAimt/v0fGiT0AAAAAiGt/v0fGiT0AAAAAiGt/v80dij2egJg5ymp/v67+VT3JvZW5fqZ/v3wHUD0AAAAAbKt/vza/Tj1DL/u4dqx/vz8GUD10EzO7Lat/v2SnTj3IAYC3iax/v3IGUD0AAAAAbKt/v7mBdj1HR6M6KIl/v6FSdT1yasa6RYp/v6JWdj0AAAAAX4l/v7pWdj0AAAAAX4l/v7grdT1LJ786bIp/v/pmez1M9RI5cIR/vzcdXT0AAAAAb6B/vzcdXT0AAAAAb6B/v88HWD2L9MO4yKR/v+zYVj0XKp04x6V/vzEEWD1gc+a1y6R/v0UdXT0AAAAAb6B/v4q16ryW22m5GOV/P1MR4LwOkJg5e+d/P42iu7wAAAAAz+5/P5+iu7wAAAAAzu5/P5+iu7wAAAAAzu5/P+EhgbwAuCi12/d/P1drk7qANtc7jP5/PwAAAAAAAAAAAACAPyk6cTsy2iS7Wf9/P6K+grpqYo67Wf9/P7CjaTnbW7w76v5/P/Ow0Ls0awA7jP5/PywUEb1GWBY639Z/P42mD71ohJC7Ddd/P7fc7bxgqTi7HeR/P6amD70AAAAAsNd/P/rc6Lx4DOg5hOV/P2pwIb1Q/kQ6EM1/P8YaMrwAAAAAIvx/P3Ky07sAAKCwo/5/P17o1rugWnK6j/5/P1tUKryVzfg5c/x/P8UaMrwAAAAAIPx/P/Kqej8AAAAAAOlPvvKqej8AAAAAAOlPvvKqej8AAAAAAOlPvuSqej8AAAAAJ+pPvuSqej8AAAAAJ+pPvuSqej8AAAAAJ+pPvs+4974GzV+/UP8lvZno276//ma/HoIVvbPf2r5CWme/5tC+vDm9+75ivF6/T4EQvW/S377DOWa/p981vNlLx748E2q/e2XkPQAAAAAAAIC/vFVHMwAAAAAAAIC/vFVHMxCy770/PX6/ZO5Uu5dEHTsHxX+/rXEtvchyEj7ZSH2/HpTQvAAAAAAAAIC/JtZiM5qkD70U13+/CsONO8l1DL7+j32/MBFAPF+ZtL1V/36/8JjSu21Gur227X6/BroSvEfc+L1WEn6/lVl/PIFH673CMn6/LsbrvGZG7D3llX2/AmOXPQE64z0xTX6/w9b3vOXi8z3SLH6/+4uku9VUFz2izn+/i5pCPNl/6T2SVH6/EOfROl456j1NUH6/v0/qO1W+w73D0n4/AO7GOwwrDL4gl30/AME8OIkvnL0jQX8/2JcJupsvnL0iQX8/8OEJuqgtOr06vH8/siCMuui4nL0UP38/4cWcu77Bvj083X4/46RavImr3T29En4/jZ9qPdOX2z3ndH4/pJK7vLMUxD1n0H4/TMQPPOusCD6NtX0/qDjCurhTzz27rH4/VGcRPOBS5T7x0GQ/cH+0PFbF4z78AGU/ILMxPc7G3z7Xx2U/2ClsPZ0S8T5htWE/zEf9PIK46T7vu2M/mjyDPCOu6z7+PWM/X2pRPEuAfz8AAAAAe5V/Pa09Bj/D2Fk/YBj0PEuAfz8AAAAAe5V/Pbm/DT9s/VQ/ccsNPUuAfz8AAAAAaZV/PeqYEj/gObI+wgI+v16Afz8AAAAAlYJ/PV6Afz8AAAAAlYJ/PV6Afz8AAAAAlYJ/PUuAf78AAAAAdpV/vUuAf78AAAAAdpV/vUuAf78AAAAAdpV/vVf+Tj8AAAAAiKEWP1f+Tj8AAAAAiKEWP1f+Tj8AAAAAiKEWP2T+Tj8AAAAAcqEWP2T+Tj8AAAAAcqEWP2T+Tj8AAAAAcqEWP+jraD8AAAAAxnLUvujraD8AAAAAxnLUvujraD8AAAAAxnLUvkrsaL8AAAAAD3HUPkrsaL8AAAAAD3HUPkrsaL8AAAAAD3HUPvq8wDQAAIC/AAAAgPq8wDQAAIC/AAAAgPq8wDQAAIC/AAAAgNJdWD51FxC/LpFMP5YcLLQAAIC/AAAAgJYcLLQAAIC/AAAAgMnuNDUAAIC/AAAAgBB4Uz9oFxC/EEjsPD9gET+IpwS/obgjP47pWj+OpwS/4LSAvAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgOAvKLQAAIC/AAAAgGwoST+UpwS/X+isvuAvKLQAAIC/AAAAgMxJErQAAIC/AAAAgMxJErQAAIC/AAAAgF3eFj+SpwS/i6wev6UmHLUAAIC/AAAAgKUmHLUAAIC/AAAAgKUmHLUAAIC/AAAAgJtKs7QAAIC/AAAAgJtKs7QAAIC/AAAAgJtKs7QAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgDpKezUAAIC/AAAAgDpKezUAAIC/AAAAgDpKezUAAIC/AAAAgIoyL7UAAIC/AAAAgIoyL7UAAIC/AAAAgIoyL7UAAIC/AAAAgNEuSzQAAIC/AAAAgNEuSzQAAIC/AAAAgNEuSzQAAIC/AAAAgLA+YDMAAIC/AAAAgLA+YDMAAIC/AAAAgLA+YDMAAIC/AAAAgKxv2zQAAIC/AAAAgKxv2zQAAIC/AAAAgKxv2zQAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgHt9gDMAAIC/AAAAgHt9gDMAAIC/AAAAgHt9gDMAAIC/AAAAgLwj1zQAAIC/AAAAgLwj1zQAAIC/AAAAgLwj1zQAAIC/AAAAgE91srQAAIC/AAAAgE91srQAAIC/AAAAgE91srQAAIC/AAAAgMNeHzQAAIC/AAAAgMNeHzQAAIC/AAAAgMNeHzQAAIC/AAAAgAhMe7UAAIC/AAAAgAhMe7UAAIC/AAAAgAhMe7UAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgAAAAAAAAIC/AAAAgFMhVjUAAIC/AAAAgFMhVjUAAIC/AAAAgFMhVjUAAIC/AAAAgIX6fTUAAIC/AAAAgIX6fTUAAIC/AAAAgIX6fTUAAIC/AAAAgAAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAAVABYAFwAYABkAGgAbABwAHQAeAB8AIAAhACIAIwAkACUAJgAnACgAKQAqACsALAAtAC4ALwAwADEAMgAzADQANQA2ADcAOAA5ADoAOwA8AD0APgA/AEAAQQBCAEMAQQBBAEQAQgBFAEYARwBIAEkASgBLAEwATQBOAE8AUABRAFIAUwBUAFUAVgBXAFgAWQBaAFsAXABdAF4AXwBgAGEAYgBjAGQAZQBmAGcAaABpAGoAawBsAG0AbgBvAHAAcQByAHMAdAB1AHYAdwB4AHkAegB7AHwAfQB+AH8AgACBAIIAgwCEAIUAhgCHAIgAiQCKAIsAjACNAI4AjwCQAI8AjgCRAJIAkwCUAJMAkgCVAJYAlwCYAJkAmgCbAJwAnQCeAJ8AoAChAKIAowCkAKUApgCnAKgAqQCqAKsArACtAK4ArwCwAK8ArgCxALIAswC0ALUAtgC3ALgAuQC5ALoAtwC7ALwAvQC+AL8AwADBAMIAwwDEAMUAxgDHAMgAyQDKAMsAzADNAM4AzwDQANEA0gDTANQA1QDWANcA2ADZANoA2wDcAN0A3gDfAOAA4QDiAOMA5ADlAOYA5wDoAOkA6gDrAOwA7QDuAO8A8ADxAPIA8wD0APUA9gD3APgA+QD6APsA/AD9AP4A/wAAAQEBAgEDAQQBBQEGAQcBCAEJAQoBCwEMAQ0BDgEPARABEQESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BLwEwATEBMgEzATQBNQE2ATcBOAE5AToBOwE8AT0BPgE/AUABQQFCAUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRAVIBUwFUAVUBVgFXAVgBWQFaAVsBXAFdAV4BXwFgAWEBYgFjAWQBZQFmAWcBaAFpAWoBawFsAW0BbgFvAXABcQFyAXMBdAF1AXYBdwF4AXkBegF7AXwBfQF+AX8BgAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEBkgGTAZQBlQGWAZcBmAGZAZoBmwGcAZ0BngGfAaABoQGiAaMBpAGlAaYBpwGnAagBpQGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9Af4B/wEAAgECAgIDAgQCBQIGAgcCCAIJAgoCCwIMAg0CDgIPAhACEQISAhMCFAIyARUCFgIXAhgCGQIaAhsCHAIdAh4CHwIgAiECIgIjAiQCJQImAicCKAIpAioCKwIsAi0CLgIvAjACMQIyAjMCNAI1AjYCNwI4AjkCOgI7AjwCPQI+Aj8CQAJBAkICQwJEAkUCRgJHAkgCSQJKAksCTAJNAk4CTwJQAlECUgJTAlQCVQJWAlcCWAJZAloCWwJcAl0CXgJfAmACYQJiAmMCZAJlAmYCZwJoAmkCagJrAmwCbQJuAm8CcAJxAnICcwJ0AnUCdgJ3AngCeQJ6AnsCfAJ9An4CfwKAAoECggKDAoQChQKGAocCiAKJAooCiwKMAo0CjgKOAo8CjAKQApECkgKTApQClQKWApcCmAKZApoCmwKcAp0CngKfAqACoQKiAqMCpAKlAqYCpwKRjI7DinSyveRJisPiWY7Dho4jwLbph8PDOJHDKsLvwGR3jMPDOJHDKsLvwGR3jMPiWY7Dho4jwLbph8O67JDDzl8fwQ0DiMO67JDDzl8fwQ0DiMN8qpbDhd5GwQ0DiMPQw5bDzl8fwbuQjMO67JDDzl8fwQ0DiMPQw5bDzl8fwbuQjMPDOJHDKsLvwGR3jMPQw5bDzl8fwbuQjMN8qpbD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AACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/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AACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAAAAAIA/AAAAAAAAgD8AAAAAAACAPwAAAQACAAMABAAFAAYABwAIAAgACQAGAAoACwAMAA0ADgAPABAAEQASABMAEgARABQAFQAWABcAGAAZABoAGwAcAB0AHAAbAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQBiAGMAZABlAGYAZwBoAGkAagBrAGwAbQBuAG8AcABxAHIAcwB0AHUAdgB3AHgAeQB6AHsAfAB9AH4AfwCAAIEAggCDAIQAhQCGAIcAiACJAIoAiwCMAI0AjgCPAJAAkQCSAJMAlACVAJYAlwCYAJkAmgCbAJwAnQCeAJ8AoAChAKIAowCkAKUApgCnAKgAqQCqAKsArACtAK4ArwCwALEAsgCzALQAtQC2ALcAuAC5ALoAuwC8AL0AvgC/AMAAwQDCAMMAxADFAMYAxwDIAMkAygDLAMwAzQDOAM8A0ADRANIA0wDUANUA1gDXANgA2QDaANsA3ADdAN4A3wDgAOEA4gDjAOQA5QDmAOcA6ADpAOoA6wDsAO0A7gDvAPAA8QDyAPMA9AD1APYA9wD4APkA+gD7APwA/QD+AP8AAAEBAQIBAwEEAQUBBgEHAQgBCQEKAQsBDAENAQ4BDwEQAREBEgETARQBFQEWARcBGAEZARoBGwEcAR0BHgEfASABIQEiASMBJAElASYBJwEoASkBKgErASwBLQEuAS8BMAExATIBMwE0ATUBNgE3ATgBOQE6ATsBPAE9AT4BPwFAAUEBQgFDAUQBRQFGAUcBSAFJAUoBSwFMAU0BTgFPAVABUQFSAVMBVAFVAVYBVwFYAVkBWgFbAVwBXQFeAV8BYAFhAWIBYwFkAWUBZgFnAWgBaQFqAWsBbAFtAW4BbwFwAXEBcgFzAXQBdQF2AXcBeAF5AXoBewF8AX0BfgF/AYABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9Af4B/wEAAgECAgIDAgQCBQIGAgcCCAIJAgoCCwIMAg0CDgIPAhACEQISAhMCFAIVAhYCFwIYAhkCGgIbAhwCHQIeAh8CIAIhAiICIwIkAiUCJgInAigCKQIqAisCLAItAi4CLwIwAjECMgIzAjQCNQI2AjcCOAI5AjoCOwI8Aj0CPgI/AkACQQJCAkMCRAJFAkYCRwJIAkkCSgJLAkwCTQJOAk8CUAJRAlICUwJUAlUCVgJXAlgCWQJaAlsCXAJdAl4CXwJgAmECYgJjAmQCZQJmAmcCaAJpAmoCawJsAm0CbgJvAnACcQJyAnMCdAJ1AnYCdwJ4AnkCegJ7AnwCfQJ+An8CgAKBAoICgwKEAoUChgKHAogCiQKKAosCjAKNAo4CjwKQApECkgKTApQClQKWApcCmAKZApoCmwKcAp0CngKfAqACoQKiAqMCpAKlAqYCpwKoAqkCqgKrAqwCrQKuAq8CsAKxArICswK0ArUCtgK3ArgCuQK6ArsCvAK9Ar4CvwLAAsECwgLDAsQCxQLGAscCyALJAsoCywLMAs0CzgLPAtAC0QLSAtMC1ALVAtYC1wLYAtkC2gLbAtwC3QLeAt8C4ALhAuIC4wLkAuUC5gLnAugC6QLqAusC7ALtAu4C7wLwAvEC8gLzAvQC9QL2AvcC+AL5AvoC+wL8Av0C/gL/AgADAQMCAwMDBAMFAwYDBwMIAwkDCgMLAwwDDQMOAw8DEAMRAxIDEwMUAxUDFgMXAxgDGQMaAxsDHAMdAx4DHwMgAyEDIgMjAyQDJQMmAycDKAMpAyoDKwMsAy0DLgMvAzADMQMyAzMDNAM1AzYDNwM4AzkDOgM7AzwDPQM+Az8DQANBA0IDQwNEA0UDRgNHA0gDSQNKA0sDTANNA04DTwNQA1EDUgNTA1QDVQNWA1cDWANZA1oDWwNcA10DXgNfA2ADYQNiA2MDZANlA2YDZwNoA2kDagNrA2wDbQNuA28DcANxA3IDcwN0A3UDdgN3A3gDeQN6A3sDfAN9A34DfwOAA4EDggODA4QDhQOGA4cDiAOJA4oDiwOMA40DjgOPA5ADkQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhA6IDowOkA6UDpgOnA6gDqQOqA6sDrAOtA64DrwOwA7EDsgOzA7QDtQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPCA8MDxAPFA8YDxwPIA8kDygPLA8wDzQPOA88D0APRA9ID0wPUA9UD1gPXA9gD2QPaA9sD3APdA94D3wPgA+ED4gPjA+QD5QPmA+cD6APpA+oD6wPsA+0D7gPvA/AD8QPyA/MD9AP1A/YD9wP4A/kD+gP7A/wD/QP+A/8DAAQBBAIEAwQEBAUEBgQHBAgECQQKBAsEDAQNBA4EDwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBFAEUQRSBFMEVARVBFYEVwRYBFkEWgRbBFwEXQReBF8EYARhBGIEYwRkBGUEZgRnBGgEaQRqBGsEbARtBG4EbwRwBHEEcgRzBHQEdQR2BHcEeAR5BHoEewR8BH0EfgR/BIAEgQSCBIMEhASFBIYEhwSIBIkEigSLBIwEjQSOBI8EkASRBJIEkwSUBJUElgSXBJgEmQSaBJsEnASdBJ4EnwSgBKEEogSjBKQEpQSmBKcEqASpBKoEqwSsBK0ErgSvBLAEsQSyBLMEtAS1BLYEtwS4BLkEugS7BLwEvQS+BL8EwATBBMIEwwTEBMUExgTHBMgEyQTKBMsEzATNBM4EzwTQBNEE0gTTBNQE1QTWBNcE2ATZBNoE2wTcBN0E3gTfBOAE4QTiBOME5ATlBOYE5wToBOkE6gTrBOwE7QTuBO8E8ATxBPIE8wT0BPUE9gT3BPgE+QT6BPsE/AT9BP4E/wQABQEFAgUDBQQFBQUGBQcFCAUJBQoFCwUMBQ0FDgUPBRAFEQUSBRMFFAUVBRYFFwUYBRkFGgUbBRwFHQUeBR8FIAUhBSIFIwUkBSUFJgUnBSgFKQUqBSsFLAUtBS4FLwUwBTEFMgUzBTQFNQU2BTcFOAU5BToFOwU8BT0FPgU/BUAFQQVCBUMFRAVFBUYFRwVIBUkFSgVLBUwFTQVOBU8FUAVRBVIFUwVUBVUFVgVXBVgFWQVaBVsFXAVdBV4FXwVgBWEFYgVjBWQFZQVmBWcFaAVpBWoFawVsBW0FbgVvBXAFcQVyBXMFdAV1BXYFdwV4BXkFegV7BXwFfQV+BX8FgAWBBYIFgwWEBYUFhgWHBYgFiQWKBYsFjAWNBY4FjwWQBZEFkgWTBZQFlQWWBZcFmAWZBZoFmwWcBZ0FngWfBaAFoQWiBaMFpAWlBaYFpwWoBakFqgWrBawFrQWuBa8FsAWxBbIFswW0BbUFtgW3BbgFuQW6BbsFvAW9Bb4FvwXABcEFwgXDBcQFxQXGBccFyAXJBcoFywXMBc0FzgXPBdAF0QXSBdMF1AXVBdYF1wXYBdkF2gXbBdwF3QXeBd8F4AXhBeIF4wXkBeUF5gXnBegF6QXqBesF7AXtBe4F7wXwBfEF8gXzBfQF9QX2BfcF+AX5BfoF+wX8Bf0F/gX/BQAGAQYCBgMGBAYFBgYGBwYIBgkGCgYLBgwGDQYOBg8GEAYRBhIGEwYUBhUGFgYXBhgGGQYaBhsGHAYdBh4GHwYgBiEGIgYjBiQGJQYmBicGKAYpBioGKwYsBi0GLgYvBjAGMQYyBjMGNAY1BjYGNwY4BjkGOgY7BjwGPQY+Bj8GQAZBBkIGQwZEBkUGRgZHBkgGSQZKBksGTAZNBk4GTwZQBlEGUgZTBlQGVQZWBlcGWAZZBloGWwZcBl0GXgZfBmAGYQZiBmMGZAZlBmYGZwZoBmkGagZrBmwGbQZuBm8GcAZxBnIGcwZ0BnUGdgZ3BngGeQZ6BnsGfAZ9Bn4GfwaABoEGggaDBoQGhQaGBocGiAaJBooGiwaMBo0GjgaPBpAGkQaSBpMGlAaVBpYGlwaYBpkGmgabBpwGnQaeBp8GoAahBqIGowakBqUGpganBqgGqQaqBqsGrAatBq4GrwawBrEGsgazBrQGtQa2BrcGuAa5BroGuwa8Br0Gvga/BsAGwQbCBsMGxAbFBsYGxwbIBskGygbLBswGzQbOBs8G0AbRBtIG0wbUBtUG1gbXBtgG2QbaBtsG3AbdBt4G3wbgBuEG4gbjBuQG5QbmBucG6AbpBuoG6wbsBu0G7gbvBvAG8QbyBvMG9Ab1BvYG9wb4BvkG+gb7BvwG/Qb+Bv8GAAcBBwIHAwcEBwUHBgcHBwgHCQcKBwsHDAcNBw4HDwcQBxEHEgcTBxQHFQcWBxcHGAcZBxoHGwccBx0HHgcfByAHIQciByMHJAclByYHJwcoBykHKgcrBywHLQcuBy8HMAcxBzIHMwc0BzUHNgc3BzgHOQc6BzsHPAc9Bz4HPwdAB0EHQgdDB0QHRQdGB0cHSAdJB0oHSwdMB00HTgdPB1AHUQdSB1MHVAdVB1YHVwdYB1kHWgdbB1wHXQdeB18HYAdhB2IHYwdkB2UHZgdnB2gHaQdqB2sHbAdtB24HbwdwB3EHcgdzB3QHdQd2B3cHeAd5B3oHewd8B30Hfgd/B4AHgQeCB4MHhAeFB4YHhweIB4kHigeLB4wHjQeOB48HkAeRB5IHkweUB5UHlgeXB5gHmQeaB5sHnAedB54HnwegB6EHogejB6QHpQemB6cHqAepB6oHqwesB60HrgevB7AHsQeyB7MHtAe1B7YHtwe4B7kHuge7B7wHvQe+B78HwAfBB8IHwwfEB8UHxgfHB8gHyQfKB8sHzAfNB84HzwfQB9EH0gfTB9QH1QfWB9cH2AfZB9oH2wfcB90H3gffB+AH4QfiB+MH5AflB+YH5wfoB+kH6gfrB+wH7QfuB+8H8AfxB/IH8wf0B/UH9gf3B/gH+Qf6B/sH/Af9B/4H/wcACAEIAggDCAQIBQgGCAcICAgJCAoICwgMCA0IDggPCBAIEQgSCBMIFAgVCBYIFwgYCBkIGggbCBwIHQgeCB8IIAghCCIIIwgkCCUIJggnCCgIKQgqCCsILAgtCC4ILwgwCDEIMggzCDQINQg2CDcIOAg5CDoIOwg8CD0IPgg/CEAIQQhCCEMIRAhFCEYIRwhICEkISghLCEwITQhOCE8IUAhRCFIIUwhUCFUIVghXCFgIWQhaCFsIXAhdCF4IXwhgCGEIYghjCGQIZQhmCGcIaAhpCGoIawhsCG0IbghvCHAIcQhyCHMIdAh1CHYIdwh4CHkIegh7CHwIfQh+CH8IgAiBCIIIgwiECIUIhgiHCIgIiQiKCIsIjAiNCI4IjwiQCJEIkgiTCJQIlQiWCJcImAiZCJoImwicCJ0IngifCKAIoQiiCKMIpAilCKYIpwioCKkIqgirCKwIrQiuCK8IsAixCLIIswi0CLUItgi3CLgIuQi6CLsIvAi9CL4IvwjACMEIwgjDCMQIxQjGCMcIyAjJCMoIywjMCM0IzgjPCNAI0QjSCNMI1AjVCNYI1wjYCNkI2gjbCNwI3QjeCN8I4AjhCOII4wjkCOUI5gjnCOgI6QjqCOsI7AjtCO4I7wjwCPEI8gjzCPQI9Qj2CPcI+Aj5CPoI+wj8CP0I/gj/CAAJAQkCCQMJBAkFCQYJBwkICQkJCgkLCQwJDQkOCQ8JEAkRCRIJEwkUCRUJFgkXCRgJGQkaCRsJHAkdCR4JHwkgCSEJIgkjCSQJJQkmCScJKAkpCSoJKwksCS0JLgkvCTAJMQkyCTMJNAk1CTYJNwk4CTkJOgk7CTwJPQk+CT8JQAlBCUIJQwlECUUJRglHCUgJSQlKCUsJTAlNCU4JTwlQCVEJUglTCVQJVQlWCVcJWAlZCVoJWwlcCV0JXglfCWAJYQliCWMJZAllCWYJZwloCWkJaglrCWwJbQluCW8JcAlxCXIJcwl0CXUJdgl3CXgJeQl6CXsJfAl9CX4JfwmACYEJggmDCYQJhQmGCYcJiAmJCYoJiwmMCY0JjgmPCZAJkQmSCZMJlAmVCZYJlwmYCZkJmgmbCZwJnQmeCZ8JoAmhCaIJowmkCaUJpgmnCagJqQmqCasJrAmtCa4JrwmwCbEJsgmzCbQJtQm2CbcJuAm5CboJuwm8Cb0Jvgm/CcAJwQnCCcMJxAnFCcYJxwnICckJygnLCcwJzQnOCc8J0AnRCdIJ0wnUCdUJ1gnXCdgJ2QnaCdsJ3AndCd4J3wngCeEJ4gnjCeQJ5QnmCecJ6AnpCeoJ6wnsCe0J7gnvCfAJvgm9CfEJ8gnzCfQJ9Qn2CfcJ+An5CfoJ+wn8Cf0J/gn/CQAKAQoCCgMKBAoFCgYKBwoICgkKCgoLCgwKDQoOCg8KEAoRChIKEwoUChUKFgoXChgKGQoaChsKHAodCh4KHwogCiEKIgojCiQKJQomCicKKAopCioKKwosCi0KLgovCjAKMQoyCjMKNAo1CjYKNwo4CjkKOgo7CjwKPQo+Cj8KQApBCkIKQwpECkUKRgpHCkgKSQpKCksKTApNCk4KTwpQClEKUgpTClQKVQpWClcKWApZCloKWwpcCl0KXgpfCmAKYQpiCmMKZAplCmYKZwpoCmkKagprCmwKbQpuCm8KcApxCnIKcwp0CnUKdgp3CngKeQp6CnsKfAp9Cn4KfwqACoEKggqDCoQKhQqGCocKiAqJCooKiwqMCo0KjgqPCpAKkQqSCpMKlAqVCpYKlwqYCpkKmgqbCpwKnQqeCp8KoAqhCqIKowqkCqUKpgqnCqgKqQqqCqsKrAqtCq4KrwqwCrEKsgqzCrQKtQq2CrcKuAq5CroKuwq8Cr0Kvgq/CsAKwQrCCsMKxArFCsYKxwrICskKygrLCswKzQrOCs8K0ArRCtIK0wrUCtUK1grXCtgK2QraCtsK3ArdCt4K3wrgCuEK4grjCuQK5QrmCucK6ArpCuoK6wrsCu0K7grvCvAK8QryCvMK9Ar1CvYK9wr4CvkK+gr7CvwK/Qr+Cv8KAAsBCwILAwsECwULBgsHCwgLCQsKCwsLDAsNCw4LDwsQCxELEgsTCxQLFQsWCxcLGAsZCxoLGwscCx0LHgsfCyALIQsiCyMLJAslCyYLJwsoCykLKgsrCywLLQsuCy8LMAsxCzILMws0CzULNgs3CzgLOQs6CzsLPAs9Cz4LPwtAC0ELQgtDC0QLRQtGC0cLSAtJC0oLSwtMC00LTgtPC1ALUQtSC1MLVAtVC1YLVwtYC1kLWgtbC1wLXQteC18LYAthC2ILYwtkC2ULZgtnC2gLaQtqC2sLbAttC24LbwtwC3ELcgtzC3QLdQt2C3cLeAt5C3oLewt8C30Lfgt/C4ALgQuCC4MLhAuFC4YLhwuIC4kLiguLC4wLjQuOC48LkAuRC5ILkwuUC5ULlguXC5gLmQuaC5sLnAudC54LnwugC6ELogujC6QLpQumC6cLqAupC6oLqwusC60LrguvC7ALsQuyC7MLtAu1C7YLtwu4C7kLugu7C7wLvQu+C78LwAvBC8ILwwvEC8ULxgvHC8gLyQvKC8sLzAvNC84LzwvQC9EL0gvTC9QL1QvWC9cL2AvZC9oL2wvcC90L3gvfC+AL4QviC+ML5AvlC+YL5wvoC+kL6gvrC+wL7QvuC+8L8AvxC/IL8wv0C/UL9gv3C/gL+Qv6C/sL/Av9C/4L/wsADAEMAgwDDAQMBQwGDAcMCAwJDAoMCwwMDA0MDgwPDBAMEQwSDBMMFAwVDBYMFwwYDBkMGgwbDBwMHQweDB8MIAwhDCIMIwwkDCUMJgwnDCgMKQwqDCsMLAwtDC4MLwwwDDEMMgwzDDQMNQw2DDcMOAw5DDoMOww8DD0MPgw/DEAMQQxCDEMMRAxFDEYMRwxIDEkMSgxLDEwMTQxODE8MUAxRDFIMUwxUDFUMVgxXDFgMWQxaDFsMXAxdDF4MXwxgDGEMYgxjDGQMZQxmDGcMaAxpDGoMawxsDG0MbgxvDHAMcQxyDHMMdAx1DHYMdwx4DHkMegx7DHwMfQx+DH8MgAyBDIIMgwyEDIUMhgyHDIgMiQyKDIsMjAyNDI4MjwyQDJEMkgyTDJQMlQyWDJcMmAyZDJoMmwycDJ0MngyfDKAMoQyiDKMMpAylDKYMpwyoDKkMqgyrDKwMrQyuDK8MsAyxDLIMswy0DLUMtgy3DLgMuQy6DLsMvAy9DL4MvwzADMEMwgzDDMQMxQzGDMcMyAzJDMoMywzMDM0MzgzPDNAM0QzSDNMM1AzVDNYM1wzYDNkM2gzbDNwM3QzeDN8M4AzhDOIM4wzkDOUM5gznDOgM6QzqDOsM7AztDO4M7wzwDPEM8gzzDPQM9Qz2DPcM+Az5DPoM+wz8DP0M/gz/DAANAQ0CDQMNBA0FDQYNBw0IDQkNCg0LDQwNDQ0ODQ8NEA0RDRINEw0UDRUNFg0XDRgNGQ0aDRsNHA0dDR4NHw0gDSENIg0jDSQNJQ0mDScNKA0pDSoNKw0sDS0NLg0vDTANMQ0yDTMNNA01DTYNNw04DTkNOg07DTwNPQ0+DT8NQA1BDUINQw1EDUUNRg1HDUgNSQ1KDUsNTA1NDU4NTw1QDVENUg1TDVQNVQ1WDVcNWA1ZDVoNWw1cDV0NXg1fDWANYQ1iDWMNZA1lDWYNZw1oDWkNag1rDWwNbQ1uDW8NcA1xDXINcw10DXUNdg13DXgNeQ16DXsNfA19DX4Nfw2ADYENgg2DDYQNhQ2GDYcNiA2JDYoNiw2MDY0Njg2PDZANkQ2SDZMNlA2VDZYNlw2YDZkNmg2bDZwNnQ2eDZ8NoA2hDaINow2kDaUNpg2nDagNqQ2qDasNrA2tDa4Nrw2wDbENsg2zDbQNtQ22DbcNuA25DboNuw28Db0Nvg2/DcANwQ3CDcMNxA3FDcYNxw3IDckNyg3LDcwNzQ3ODc8N0A3RDdIN0w3UDdUN1g3XDdgN2Q3aDdsN3A3dDd4N3w3gDeEN4g3jDeQN5Q3mDecN6A3pDeoN6w3sDe0N7g3vDfAN8Q3yDfMN9A31DfYN9w34DfkN+g37DfwN/Q3+Df8NAA4BDgIOAw4EDgUOBg4HDggOCQ4KDgsODA4NDg4ODw4QDhEOEg4TDhQOFQ4WDhcOGA4ZDhoOGw4cDh0OHg4fDiAOIQ4iDiMOJA4lDiYOJw4oDikOKg4rDiwOLQ4uDi8OMA4xDjIOMw40DjUONg43DjgOOQ46DjsOPA49Dj4OPw5ADkEOQg5DDkQORQ5GDkcOSA5JDkoOSw5MDk0OTg5PDlAOUQ5SDlMOVA5VDlYOVw5YDlkOWg5bDlwOXQ5eDl8OYA5hDmIOYw5kDmUOZg5nDmgOaQ5qDmsObA5tDm4Obw5wDnEOcg5zDnQOdQ52DncOeA55DnoOew58Dn0Ofg5/DoAOgQ6CDoMOhA6FDoYOhw6IDokOig6LDowOjQ6ODo8OkA6RDpIOkw6UDpUOlg6XDpgOmQ6aDpsOnA6dDp4Onw6gDqEOog6jDqQOpQ6mDqcOqA6pDqoOqw6sDq0Org6vDrAOsQ6yDrMOtA61DrYOtw64DrkOug67DrwOvQ6+Dr8OwA7BDg==" +const bikeUri = "data:@file/octet-stream;base64,Z2xURgIAAACEdwwAqAgAAEpTT057ImFjY2Vzc29ycyI6W3siYnVmZmVyVmlldyI6MiwiY29tcG9uZW50VHlwZSI6NTEyNiwiY291bnQiOjE1NjM0LCJtYXgiOlswLjA5Nzc4MTQwNDg1Mjg2NzEzLDAuMDExMzU1OTkzMzM3OTI5MjQ5LDIuNzQ5OTUxMDIyNDUxNTY5ZS0wN10sIm1pbiI6WzAuMDIyNDM3ODQyNTYyNzk0Njg1LDAuMCwtMC4xMjAxNzg5NzUxNjQ4OTAyOV0sInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3IjoyLCJieXRlT2Zmc2V0IjoxODc2MDgsImNvbXBvbmVudFR5cGUiOjUxMjYsImNvdW50IjoxNTYzNCwibWF4IjpbMS4wLDEuMCwxLjBdLCJtaW4iOlstMS4wLC0xLjAsLTEuMF0sInR5cGUiOiJWRUMzIn0seyJidWZmZXJWaWV3IjoxLCJjb21wb25lbnRUeXBlIjo1MTI2LCJjb3VudCI6MTU2MzQsIm1heCI6WzAuOTk0MzkxMTQzMzIxOTkxLDAuMF0sIm1pbiI6WzAuMDA2NDEwMTc3Nzk3MDc5MDg2LDAuMF0sInR5cGUiOiJWRUMyIn0seyJidWZmZXJWaWV3IjowLCJjb21wb25lbnRUeXBlIjo1MTI1LCJjb3VudCI6Nzg2MjQsInR5cGUiOiJTQ0FMQVIifV0sImFzc2V0Ijp7ImV4dHJhcyI6eyJhdXRob3IiOiJJbHlhcy5LaW5nIChodHRwczovL3NrZXRjaGZhYi5jb20vSWx5YXMuS2luZykiLCJsaWNlbnNlIjoiQ0MtQlktNC4wIChodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS80LjAvKSIsInNvdXJjZSI6Imh0dHBzOi8vc2tldGNoZmFiLmNvbS8zZC1tb2RlbHMvbWFwLXBpbi02NjdlYzk5ODYwNjc0ZTU3ODkyODIzYTE5YTFkOGYxNSIsInRpdGxlIjoiTWFwIFBpbiJ9LCJnZW5lcmF0b3IiOiJTa2V0Y2hmYWItMTIuNjUuMCIsInZlcnNpb24iOiIyLjAifSwiYnVmZmVyVmlld3MiOlt7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6MzE0NDk2LCJuYW1lIjoiZmxvYXRCdWZmZXJWaWV3cyIsInRhcmdldCI6MzQ5NjN9LHsiYnVmZmVyIjowLCJieXRlTGVuZ3RoIjoxMjUwNzIsImJ5dGVPZmZzZXQiOjMxNDQ5NiwiYnl0ZVN0cmlkZSI6OCwibmFtZSI6ImZsb2F0QnVmZmVyVmlld3MiLCJ0YXJnZXQiOjM0OTYyfSx7ImJ1ZmZlciI6MCwiYnl0ZUxlbmd0aCI6Mzc1MjE2LCJieXRlT2Zmc2V0Ijo0Mzk1NjgsImJ5dGVTdHJpZGUiOjEyLCJuYW1lIjoiZmxvYXRCdWZmZXJWaWV3cyIsInRhcmdldCI6MzQ5NjJ9XSwiYnVmZmVycyI6W3siYnl0ZUxlbmd0aCI6ODE0Nzg0fV0sIm1hdGVyaWFscyI6W3siZG91YmxlU2lkZWQiOnRydWUsIm5hbWUiOiJNYXRlcmlhbCIsInBick1ldGFsbGljUm91Z2huZXNzIjp7ImJhc2VDb2xvckZhY3RvciI6WzAuOCwwLjAsMC4wMTA0NDQ3LDEuMF0sIm1ldGFsbGljRmFjdG9yIjowLjAsInJvdWdobmVzc0ZhY3RvciI6MC40fX1dLCJtZXNoZXMiOlt7Im5hbWUiOiJPYmplY3RfMCIsInByaW1pdGl2ZXMiOlt7ImF0dHJpYnV0ZXMiOnsiTk9STUFMIjoxLCJQT1NJVElPTiI6MCwiVEVYQ09PUkRfMCI6Mn0sImluZGljZXMiOjMsIm1hdGVyaWFsIjowLCJtb2RlIjo0fV19XSwibm9kZXMiOlt7ImNoaWxkcmVuIjpbMV0sIm1hdHJpeCI6WzEuMCwwLjAsMC4wLDAuMCwwLjAsMi4yMjA0NDYwNDkyNTAzMTNlLTE2LC0xLjAsMC4wLDAuMCwxLjAsMi4yMjA0NDYwNDkyNTAzMTNlLTE2LDAuMCwwLjAsMC4wLDAuMCwxLjBdLCJuYW1lIjoiU2tldGNoZmFiX21vZGVsIn0seyJjaGlsZHJlbiI6WzJdLCJuYW1lIjoicm9vdCJ9LHsiY2hpbGRyZW4iOlszXSwibWF0cml4IjpbMS4wLDAuMCwwLjAsMC4wLDAuMCwyLjIyMDQ0NjA0OTI1MDMxM2UtMTYsMS4wLDAuMCwwLjAsLTEuMCwyLjIyMDQ0NjA0OTI1MDMxM2UtMTYsMC4wLDAuMCww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RQAAAE4AAABAAAAAVgAAAFcAAABPAAAAVgAAAE8AAABYAAAAVwAAAFMAAABQAAAAVwAAAFAAAABPAAAAWAAAAE8AAABNAAAAWAAAAE0AAABVAAAAWQAAAFoAAABbAAAAWQAAAFsAAABcAAAAXQAAAF4AAABbAAAAXQAAAFsAAABfAAAAYAAAAGEAAABbAAAAYAAAAFsAAABeAAAAYgAAAGMAAABZAAAAYgAAAFkAAABkAAAAYwAAAGUAAABaAAAAYwAAAFoAAABZAAAAZAAAAFkAAABcAAAAZAAAAFwAAABmAAAALwAAAFIAAABdAAAALwAAAF0AAABnAAAAUgAAAGgAAABeAAAAUgAAAF4AAABdAAAAZwAAAF0AAABfAAAAZwAAAF8AAABlAAAAVgAAAGkAAABgAAAAVgAAAGAAAABqAAAAaQAAAGYAAABhAAAAaQAAAGEAAABgAAAAagAAAGAAAABeAAAAagAAAF4AAABrAAAAbAAAAG0AAABuAAAAbAAAAG4AAABvAAAAcAAAAHEAAABuAAAAcAAAAG4AAAByAAAAcwAAAHQAAABuAAAAcwAAAG4AAAB1AAAAYgAAAGQAAABsAAAAYgAAAGwAAAB2AAAAZAAAAGYAAABtAAAAZAAAAG0AAABsAAAAdgAAAGwAAABvAAAAdgAAAG8AAAB3AAAAVgAAAHgAAABwAAAAVgAAAHAAAAB5AAAAeAAAAHoAAABxAAAAeAAAAHEAAABwAAAAeQAAAHAAAAByAAAAeQAAAHIAAABmAAAAewAAAHwAAABzAAAAewAAAHMAAAB9AAAAfAAAAHcAAAB0AAAAfAAAAHQAAABzAAAAfQAAAHMAAAB1AAAAfQAAAHUAAAB6AAAAfgAAAH8AAACAAAAAfgAAAIAAAACBAAAAggAAAIMAAACAAAAAggAAAIAAAACEAAAAhQAAAIEAAACAAAAAhQAAAIAAAACDAAAAhgAAAIcAAAB+AAAAhgAAAH4AAACIAAAAhwAAAIkAAAB/AAAAhwAAAH8AAAB+AAAAiAAAAH4AAACBAAAAiAAAAIEAAACKAAAAYgAAAIsAAACCAAAAYgAAAIIAAACMAAAAiwAAAI0AAACDAAAAiwAAAIMAAACCAAAAjAAAAIIAAACEAAAAjAAAAIQAAACOAAAAewAAAI8AAACFAAAAewAAAIUAAACQAAAAjwAAAIoAAACBAAAAjwAAAIEAAACFAAAAkAAAAIUAAACDAAAAkAAAAIMAAACNAAAAkQAAAJIAAACTAAAAkQAAAJMAAACUAAAAlQAAAJYAAACTAAAAlQAAAJMAAACSAAAAlwAAAJgAAACTAAAAlwAAAJMAAACZAAAAhgAAAIgAAACRAAAAhgAAAJEAAACaAAAAiAAAAJsAAACSAAAAiAAAAJIAAACRAAAAmgAAAJEAAACUAAAAmgAAAJQAAACcAAAAewAAAJ0AAACVAAAAewAAAJUAAACPAAAAnQAAAJ4AAACWAAAAnQAAAJYAAACVAAAAjwAAAJUAAACSAAAAjwAAAJIAAACbAAAAnwAAAKAAAACXAAAAnwAAAJcAAAChAAAAoAAAAKIAAACYAAAAoAAAAJgAAACXAAAAoQAAAJcAAACZAAAAoQAAAJkAAACjAAAApAAAAKUAAACmAAAApAAAAKYAAACnAAAAqAAAAKkAAACmAAAAqAAAAKYAAAClAAAAqgAAAKcAAACmAAAAqgAAAKYAAACpAAAAqwAAAKwAAACkAAAAqwAAAKQAAACtAAAArAAAAK4AAAClAAAArAAAAKUAAACkAAAArQAAAKQAAACnAAAArQAAAKcAAACvAAAAhgAAAJoAAACoAAAAhgAAAKgAAACwAAAAmgAAAKIAAACpAAAAmgAAAKkAAACoAAAAsAAAAKgAAAClAAAAsAAAAKUAAACxAAAAnwAAALIAAACqAAAAnwAAAKoAAACgAAAAsgAAAK8AAACnAAAAsgAAAKcAAACqAAAAoAAAAKoAAACpAAAAoAAAAKkAAACiAAAAswAAALQAAAC1AAAAswAAALUAAAC2AAAAtwAAALgAAAC1AAAAtwAAALUAAAC5AAAAugAAALYAAAC1AAAAugAAALUAAAC7AAAAqwAAAK0AAACzAAAAqwAAALMAAAC8AAAArQAAAK8AAAC0AAAArQAAALQAAACzAAAAvAAAALMAAAC2AAAAvAAAALYAAAC9AAAAnwAAAL4AAAC3AAAAnwAAALcAAACyAAAAvgAAAL8AAAC4AAAAvgAAALgAAAC3AAAAsgAAALcAAAC5AAAAsgAAALkAAACvAAAAwAAAAMEAAAC6AAAAwAAAALoAAADCAAAAwQAAAMMAAAC2AAAAwQAAALYAAAC6AAAAwgAAALoAAAC7AAAAwgAAALsAAAC/AAAAxAAAAMUAAADGAAAAxAAAAMYAAADHAAAAyAAAAMkAAADGAAAAyAAAAMYAAADFAAAAygAAAMcAAADGAAAAygAAAMYAAADLAAAAzAAAAM0AAADEAAAAzAAAAMQAAADOAAAAzQAAAM8AAADFAAAAzQAAAMUAAADEAAAAzgAAAMQAAADHAAAAzgAAAMcAAADQAAAAqwAAALwAAADIAAAAqwAAAMgAAADRAAAAvAAAAMMAAADJAAAAvAAAAMkAAADIAAAA0QAAAMgAAADFAAAA0QAAAMUAAADPAAAAwAAAANIAAADKAAAAwAAAAMoAAADTAAAA0gAAANQAAADHAAAA0gAAAMcAAADKAAAA0wAAAMoAAADLAAAA0wAAAMsAAADDAAAA1QAAANYAAADXAAAA1QAAANcAAADYAAAA2QAAANoAAADXAAAA2QAAANcAAADWAAAA2wAAANgAAADXAAAA2wAAANcAAADcAAAAzAAAAM4AAADVAAAAzAAAANUAAADdAAAAzgAAANAAAADWAAAAzgAAANYAAADVAAAA3QAAANUAAADYAAAA3QAAANgAAADeAAAAwAAAAN8AAADZAAAAwAAAANkAAADgAAAA3wAAAOEAAADaAAAA3wAAANoAAADZAAAA4AAAANkAAADWAAAA4AAAANYAAADUAAAA4gAAAOMAAADbAAAA4gAAANsAAADkAAAA4wAAAOUAAADYAAAA4wAAANgAAADbAAAA5AAAANsAAADcAAAA5AAAANwAAADmAAAA5wAAAOgAAADpAAAA5wAAAOkAAADqAAAA6wAAAOwAAADpAAAA6wAAAOkAAADtAAAA7gAAAO8AAADpAAAA7gAAAOkAAADwAAAA8QAAAPIAAADnAAAA8QAAAOcAAADzAAAA8gAAAPQAAADoAAAA8gAAAOgAAADnAAAA8wAAAOcAAADqAAAA8wAAAOoAAAD1AAAAzAAAAN0AAADrAAAAzAAAAOsAAAD2AAAA3QAAAPcAAADsAAAA3QAAAOwAAADrAAAA9gAAAOsAAADtAAAA9gAAAO0AAAD0AAAA4gAAAPgAAADuAAAA4gAAAO4AAADjAAAA+AAAAPkAAADvAAAA+AAAAO8AAADuAAAA4wAAAO4AAADwAAAA4wAAAPAAAADlAAAA+gAAAPsAAAD8AAAA+gAAAPwAAAD9AAAA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bAEAAG4BAABkAQAAbAEAAGQBAABjAQAAbQEAAGMBAABmAQAAbQEAAGYBAABvAQAAPQEAAEgBAABnAQAAPQEAAGcBAABwAQAASAEAAE4BAABoAQAASAEAAGgBAABnAQAAcAEAAGcBAABpAQAAcAEAAGkBAABuAQAAKgEAAHEBAABqAQAAKgEAAGoBAABMAQAAcQEAAG8BAABmAQAAcQEAAGYBAABqAQAATAEAAGoBAABoAQAATAEAAGgBAAByAQAAcwEAAHQBAAB1AQAAcwEAAHUBAAB2AQAAdwEAAHgBAAB1AQAAdwEAAHUBAAB0AQAAeQEAAHoBAAB1AQAAeQEAAHUBAAB4AQAAewEAAHwBAABzAQAAewEAAHMBAAB9AQAAfAEAAH4BAAB0AQAAfAEAAHQBAABzAQAAfQEAAHMBAAB2AQAAfQEAAHYBAAB/AQAAawEAAIABAAB3AQAAawEAAHcBAACBAQAAgAEAAIIBAAB4AQAAgAEAAHgBAAB3AQAAgQEAAHcBAAB0AQAAgQEAAHQBAAB+AQAAKgEAAIMBAAB5AQAAKgEAAHkBAACEAQAAgwEAAIUBAAB6AQAAgwEAAHoBAAB5AQAAhAEAAHkBAAB4AQAAhAEAAHgBAABvAQAAhgEAAIcBAACIAQAAhgEAAIgBAACJAQAAigEAAIsBAACIAQAAigEAAIgBAACHAQAAjAEAAI0BAACIAQAAjAEAAIgBAACOAQAANQEAAFkBAACGAQAANQEAAIYBAACPAQAAWQEAAGIBAACHAQAAWQEAAIcBAACGAQAAjwEAAIYBAACJAQAAjwEAAIkBAACQAQAAXwEAAJEBAACKAQAAXwEAAIoBAACSAQAAkQEAAJMBAACLAQAAkQEAAIsBAACKAQAAkgEAAIoBAACHAQAAkgEAAIcBAABbAQAAlAEAAJUBAACMAQAAlAEAAIwBAACWAQAAlQEAAJcBAACNAQAAlQEAAI0BAACMAQAAlgEAAIwBAACOAQAAlgEAAI4BAACYAQAAmQEAAJoBAACbAQAAmQEAAJsBAACcAQAAnQEAAJ4BAACbAQAAnQEAAJsBAACaAQAAnwEAAJwBAACbAQAAnwEAAJsBAACeAQAAoAEAAKEBAACZAQAAoAEAAJkBAACiAQAAoQEAAKMBAACaAQAAoQEAAJoBAACZAQAAogEAAJkBAACcAQAAogEAAJwBAACkAQAAewEAAKUBAACdAQAAewEAAJ0BAACmAQAApQEAAKcBAACeAQAApQEAAJ4BAACdAQAApgEAAJ0BAACaAQAApgEAAJoBAACjAQAAKgEAAKgBAACfAQAAKgEAAJ8BAACDAQAAqAEAAKkBAACcAQAAqAEAAJwBAACfAQAAgwEAAJ8BAACeAQAAgwEAAJ4BAACFAQAAqgEAAKsBAACsAQAAqgEAAKwBAACtAQAArgEAAK8BAACsAQAArgEAAKwBAACrAQAAsAEAAK0BAACsAQAAsAEAAKwBAACxAQAANQEAAI8BAACqAQAANQEAAKoBAACyAQAAjwEAAJcBAACrAQAAjwEAAKsBAACqAQAAsgEAAKoBAACtAQAAsgEAAK0BAACzAQAAtAEAALUBAACuAQAAtAEAAK4BAACVAQAAtQEAALYBAACvAQAAtQEAAK8BAACuAQAAlQEAAK4BAACrAQAAlQEAAKsBAACXAQAAtwEAALgBAACwAQAAtwEAALABAAC5AQAAuAEAALMBAACtAQAAuAEAAK0BAACwAQAAuQEAALABAACxAQAAuQEAALEBAAC6AQAAuwEAALwBAAC9AQAAuwEAAL0BAAC+AQAAvwEAAMABAAC9AQAAvwEAAL0BAADBAQAAwgEAAL4BAAC9AQAAwgEAAL0BAADDAQAAxAEAAMUBAAC7AQAAxAEAALsBAADGAQAAxQEAAMcBAAC8AQAAxQEAALwBAAC7AQAAxgEAALsBAAC+AQAAxgEAAL4BAADIAQAAyQEAAKIBAAC/AQAAyQEAAL8BAADKAQAAogEAAKQBAADAAQAAogEAAMABAAC/AQAAygEAAL8BAADBAQAAygEAAMEBAADHAQAAKgEAAMsBAADCAQAAKgEAAMIBAADMAQAAywEAAM0BAAC+AQAAywEAAL4BAADCAQAAzAEAAMIBAADDAQAAzAEAAMMBAACpAQAAzgEAAM8BAADQAQAAzgEAANABAADRAQAA0gEAANMBAADQAQAA0gEAANABAADPAQAA1AEAANUBAADQAQAA1AEAANABAADTAQAANQEAALIBAADOAQAANQEAAM4BAADWAQAAsgEAALMBAADPAQAAsgEAAM8BAADOAQAA1gEAAM4BAADRAQAA1gEAANEBAADXAQAA2AEAANkBAADSAQAA2AEAANIBAAC4AQAA2QEAANoBAADTAQAA2QEAANMBAADSAQAAuAEAANIBAADPAQAAuAEAAM8BAACzAQAA2wEAANwBAADUAQAA2wEAANQBAADdAQAA3AEAAN4BAADVAQAA3AEAANUBAADUAQAA3QEAANQBAADTAQAA3QEAANMBAADfAQAA4AEAAOEBAADiAQAA4AEAAOIBAADjAQAA5AEAAOUBAADiAQAA5AEAAOIBAADhAQAA5gEAAOcBAADiAQAA5gEAAOIBAADoAQAAxAEAAMYBAADgAQAAxAEAAOABAADpAQAAxgEAAMgBAADhAQAAxgEAAOEBAADgAQAA6QEAAOABAADjAQAA6QEAAOMBAADqAQAAKgEAAOsBAADkAQAAKgEAAOQBAADsAQAA6wEAAO0BAADlAQAA6wEAAOUBAADkAQAA7AEAAOQBAADhAQAA7AEAAOEBAADNAQAA7gEAAO8BAADmAQAA7gEAAOYBAADwAQAA7wEAAOoBAADnAQAA7wEAAOcBAADmAQAA8AEAAOYBAADoAQAA8AEAAOgBAADxAQAA8gEAAPMBAAD0AQAA8gEAAPQBAAD1AQAA9gEAAPcBAAD0AQAA9gEAAPQBAAD4AQAA+QEAAPoBAAD0AQAA+QEAAPQBAAD3AQAA+wEAAPwBAADyAQAA+wEAAPIBAAD9AQAA/AEAAP4BAADzAQAA/AEAAPMBAADyAQAA/QEAAPIBAAD1AQAA/QEAAPUBAAD/AQAANQEAANYBAAD2AQAANQEAAPYBAAAAAgAA1gEAANcBAAD3AQAA1gEAAPcBAAD2AQAAAAIAAPYBAAD4AQAAAAIAAPgBAAABAgAA2wEAAAICAAD5AQAA2wEAAPkBAADcAQAAAgIAAP8BAAD6AQAAAgIAAPoBAAD5AQAA3AEAAPkBAAD3AQAA3AEAAPcBAAADAgAABAIAAAUCAAAGAgAABAIAAAYCAAAHAgAACAIAAAkCAAAGAgAACAIAAAYCAAAFAgAACgIAAAsCAAAGAgAACgIAAAYCAAAJAgAADAIAAA0CAAAEAgAADAIAAAQCAAAOAgAADQIAAA8CAAAFAgAADQIAAAUCAAAEAgAADgIAAAQCAAAHAgAADgIAAAcCAAAQAgAAxAEAAOkBAAAIAgAAxAEAAAgCAAARAgAA6QEAAOoBAAAJAgAA6QEAAAkCAAAIAgAAEQIAAAgCAAAFAgAAEQIAAAUCAAASAgAA7gEAABMCAAAKAgAA7gEAAAoCAADvAQAAEwIAABQCAAALAgAAEwIAAAsCAAAKAgAA7wEAAAoCAAAJAgAA7wEAAAkCAADqAQAAFQIAABYCAAAXAgAAFQIAABcCAAAYAgAAGQIAABoCAAAXAgAAGQIAABcCAAAWAgAAGwIAABwCAAAXAgAAGwIAABcCAAAdAgAA+wEAAP0BAAAVAgAA+wEAABUCAAAeAgAA/QEAAP8BAAAWAgAA/QEAABYCAAAVAgAAHgIAABUCAAAYAgAAHgIAABgCAAAfAgAA2wEAACACAAAZAgAA2wEAABkCAAACAgAAIAIAACECAAAaAgAAIAIAABoCAAAZAgAAAgIAABkCAAAWAgAAAgIAABYCAAAiAgAAIwIAACQCAAAbAgAAIwIAABsCAAAlAgAAJAIAAB8CAAAcAgAAJAIAABwCAAAbAgAAJQIAABsCAAAdAgAAJQIAAB0CAAAhAgAAJgIAACcCAAAoAgAAJgIAACgCAAApAgAAKgIAACsCAAAoAgAAKgIAACgCAAAsAgAALQIAAC4CAAAoAgAALQIAACgCAAAvAgAAMAIAADECAAAmAgAAMAIAACYCAAAyAgAAMQIAADMCAAAnAgAAMQIAACcCAAAmAgAAMgIAACYCAAApAgAAMgIAACkCAAA0AgAANQIAAA4CAAAqAgAANQIAACoCAAA2AgAADgIAABQCAAArAgAADgIAACsCAAAqAgAANgIAACoCAAAsAgAANgIAACwCAAA3AgAA7gEAADgCAAAtAgAA7gEAAC0CAAA5AgAAOAIAADQCAAAuAgAAOAIAAC4CAAAtAgAAOQIAAC0CAAAvAgAAOQIAAC8CAAAUAgAAOgIAADsCAAA8AgAAOgIAADwCAAA9AgAAOwIAAD4CAAA/AgAAOwIAAD8CAAA8AgAAPQIAADwCAABAAgAAPQIAAEACAABBAgAAPAIAAD8CAABCAgAAPAIAAEICAABAAgAA+wEAAEMCAAA6AgAA+wEAADoCAABEAgAAQwIAAEUCAAA7AgAAQwIAADsCAAA6AgAARQIAAEYCAAA+AgAARQIAAD4CAAA7AgAARgIAAEcCAABIAgAARgIAAEgCAAA+AgAAPgIAAEgCAABJAgAAPgIAAEkCAAA/AgAAPwIAAEkCAABKAgAAPwIAAEoCAABCAgAAQgIAAEoCAABLAgAAQgIAAEsCAABMAgAAQAIAAEICAABMAgAAQAIAAEwCAABNAgAAQQIAAEACAABNAgAAQQIAAE0CAABOAgAATwIAAEECAABOAgAATwIAAE4CAABQAgAAUQIAAD0CAABBAgAAUQIAAEECAABPAgAARAIAADoCAAA9AgAARAIAAD0CAABRAgAAUgIAAFMCAABUAgAAUgIAAFQCAABVAgAAVgIAAFcCAABUAgAAVgIAAFQCAABTAgAAWAIAAFkCAABUAgAAWAIAAFQCAABXAgAAWgIAAFsCAABSAgAAWgIAAFICAABcAgAAWwIAAF0CAABTAgAAWwIAAFMCAABSAgAAXAIAAFICAABVAgAAXAIAAFUCAABeAgAAXwIAADICAABWAgAAXwIAAFYCAABgAgAAMgIAADQCAABXAgAAMgIAAFcCAABWAgAAYAIAAFYCAABTAgAAYAIAAFMCAABdAgAA7gEAAGECAABYAgAA7gEAAFgCAABiAgAAYQIAAF4CAABZAgAAYQIAAFkCAABYAgAAYgIAAFgCAABXAgAAYgIAAFcCAABjAgAAZAIAAGUCAABmAgAAZAIAAGYCAABnAgAAaAIAAGkCAABmAgAAaAIAAGYCAABqAgAAawIAAGwCAABmAgAAawIAAGYCAABpAgAA+wEAAG0CAABkAgAA+wEAAGQCAABuAgAAbQIAAG8CAABlAgAAbQIAAGUCAABkAgAAbgIAAGQCAABnAgAAbgIAAGcCAABwAgAAUAIAAHECAABoAgAAUAIAAGgCAAByAgAAcQIAAHMCAABpAgAAcQIAAGkCAABoAgAAcgIAAGgCAABqAgAAcgIAAGoCAAB0AgAAdQIAAHYCAABrAgAAdQIAAGsCAAB3AgAAdgIAAHgCAABsAgAAdgIAAGwCAABrAgAAdwIAAGsCAABpAgAAdwIAAGkCAABzAgAAeQIAAHoCAAB7AgAAeQIAAHsCAAB8AgAAfQIAAH4CAAB7AgAAfQIAAHsCAAB/AgAAgAIAAHwCAAB7AgAAgAIAAHsCAACBAgAAWgIAAIICAAB5AgAAWgIAAHkCAACDAgAAggIAAIQCAAB6AgAAggIAAHoCAAB5AgAAgwIAAHkCAAB8AgAAgwIAAHwCAACFAgAA7gEAAIYCAAB9AgAA7gEAAH0CAABhAgAAhgIAAIcCAAB+AgAAhgIAAH4CAAB9AgAAYQIAAH0CAAB/AgAAYQIAAH8CAACEAgAAiAIAAIkCAACAAgAAiAIAAIACAACKAgAAiQIAAIsCAAB8AgAAiQIAAHwCAACAAgAAigIAAIACAACBAgAAigIAAIECAACMAgAAjQIAAI4CAACPAgAAjQIAAI8CAACQAgAAkQIAAJICAACPAgAAkQIAAI8CAACOAgAAkwIAAJACAACPAgAAkwIAAI8CAACSAgAAlAIAAJUCAACNAgAAlAIAAI0CAACWAgAAlQIAAJcCAACOAgAAlQIAAI4CAACNAgAAlgIAAI0CAACQAgAAlgIAAJACAACYAgAA+wEAAJkCAACRAgAA+wEAAJECAACaAgAAmQIAAHgCAACSAgAAmQIAAJICAACRAgAAmgIAAJECAACOAgAAmgIAAI4CAACXAgAAdQIAAJsCAACTAgAAdQIAAJMCAAB2AgAAmwIAAJwCAACQAgAAmwIAAJACAACTAgAAdgIAAJMCAACSAgAAdgIAAJICAAB4AgAAnQIAAJ4CAACfAgAAnQIAAJ8CAACgAgAAoQIAAKICAACfAgAAoQIAAJ8CAACjAgAApAIAAKACAACfAgAApAIAAJ8CAAClAgAApgIAAKcCAACdAgAApgIAAJ0CAACoAgAApwIAAKkCAACeAgAApwIAAJ4CAACdAgAAqAIAAJ0CAACgAgAAqAIAAKACAACqAgAAWgIAAIMCAAChAgAAWgIAAKECAACrAgAAgwIAAKwCAACiAgAAgwIAAKICAAChAgAAqwIAAKECAACjAgAAqwIAAKMCAACtAgAAiAIAAK4CAACkAgAAiAIAAKQCAACvAgAArgIAAKoCAACgAgAArgIAAKACAACkAgAArwIAAKQCAAClAgAArwIAAKUCAACLAgAAsAIAALECAACyAgAAsAIAALICAACzAgAAtAIAALUCAACyAgAAtAIAALICAAC2AgAAtwIAALgCAACyAgAAtwIAALICAAC5AgAAlAIAAJYCAACwAgAAlAIAALACAAC6AgAAlgIAAJgCAACxAgAAlgIAALECAACwAgAAugIAALACAACzAgAAugIAALMCAAC7AgAAdQIAALwCAAC0AgAAdQIAALQCAAC9AgAAvAIAAL4CAAC1AgAAvAIAALUCAAC0AgAAvQIAALQCAAC2AgAAvQIAALYCAACcAgAAvwIAAMACAAC3AgAAvwIAALcCAADBAgAAwAIAALsCAAC4AgAAwAIAALgCAAC3AgAAwQIAALcCAAC5AgAAwQIAALkCAAC+AgAAwgIAAMMCAADEAgAAwgIAAMQCAADFAgAAxgIAAMcCAADEAgAAxgIAAMQCAADDAgAAyAIAAMkCAADEAgAAyAIAAMQCAADKAgAAywIAAMwCAADCAgAAywIAAMICAADNAgAAzAIAAM4CAADDAgAAzAIAAMMCAADCAgAAzQIAAMICAADFAgAAzQIAAMUCAADPAgAA0AIAAKgCAADGAgAA0AIAAMYCAADRAgAAqAIAAKoCAADHAgAAqAIAAMcCAADGAgAA0QIAAMYCAADDAgAA0QIAAMMCAADOAgAAiAIAANICAADIAgAAiAIAAMgCAACuAgAA0gIAANMCAADJAgAA0gIAAMkCAADIAgAArgIAAMgCAADKAgAArgIAAMoCAACqAgAA1AIAANUCAADWAgAA1AIAANYCAADXAgAA2AIAANkCAADWAgAA2AIAANYCAADaAgAA2wIAANcCAADWAgAA2wIAANYCAADZAgAAlAIAANwCAADUAgAAlAIAANQCAADdAgAA3AIAALsCAADVAgAA3AIAANUCAADUAgAA3QIAANQCAADXAgAA3QIAANcCAADeAgAAvwIAAN8CAADYAgAAvwIAANgCAADAAgAA3wIAAOACAADZAgAA3wIAANkCAADYAgAAwAIAANgCAADaAgAAwAIAANoCAADhAgAA4gIAAOMCAADbAgAA4gIAANsCAADkAgAA4wIAAN4CAADXAgAA4wIAANcCAADbAgAA5AIAANsCAADZAgAA5AIAANkCAADlAgAA5gIAAOcCAADoAgAA5gIAAOgCAADpAgAA6gIAAOsCAADoAgAA6gIAAOgCAADnAgAA7AIAAO0CAADoAgAA7AIAAOgCAADuAgAA7wIAAPACAADmAgAA7wIAAOYCAADxAgAA8AIAAPICAADnAgAA8AIAAOcCAADmAgAA8QIAAOYCAADpAgAA8QIAAOkCAADzAgAA9AIAAM0CAADqAgAA9AIAAOoCAAD1AgAAzQIAANMCAADrAgAAzQIAAOsCAADqAgAA9QIAAOoCAADnAgAA9QIAAOcCAADyAgAAiAIAAPYCAADsAgAAiAIAAOwCAAD3AgAA9gIAAPgCAADtAgAA9gIAAO0CAADsAgAA9wIAAOwCAADuAgAA9wIAAO4CAADTAgAA+QIAAPoCAAD7AgAA+QIAAPsCAAD8AgAA/QIAAP4CAAD7AgAA/QIAAPsCAAD/AgAAAAMAAAEDAAD7AgAAAAMAAPsCAAACAwAAlAIAAN0CAAD5AgAAlAIAAPkCAAADAwAA3QIAAAQDAAD6AgAA3QIAAPoCAAD5AgAAAwMAAPkCAAD8AgAAAwMAAPwCAAAFAwAA4gIAAAYDAAD9AgAA4gIAAP0CAADjAgAABgMAAAcDAAD+AgAABgMAAP4CAAD9AgAA4wIAAP0CAAD/AgAA4wIAAP8CAAAIAwAACQMAAAoDAAAAAwAACQMAAAADAAALAwAACgMAAAwDAAABAwAACgMAAAEDAAAAAwAACwMAAAADAAACAwAACwMAAAIDAAAHAwAADQMAAA4DAAAPAwAADQMAAA8DAAAQAwAAEQMAABIDAAAPAwAAEQMAAA8DAAATAwAAFAMAABADAAAPAwAAFAMAAA8DAAAVAwAA7wIAABYDAAANAwAA7wIAAA0DAAAXAwAAFgMAAPMCAAAOAwAAFgMAAA4DAAANAwAAFwMAAA0DAAAQAwAAFwMAABADAAAYAwAAiAIAABkDAAARAwAAiAIAABEDAAAaAwAAGQMAABsDAAASAwAAGQMAABIDAAARAwAAGgMAABEDAAATAwAAGgMAABMDAAAcAwAAHQMAAB4DAAAUAwAAHQMAABQDAAAfAwAAHgMAABgDAAAQAwAAHgMAABADAAAUAwAAHwMAABQDAAAVAwAAHwMAABUDAAAgAwAAIQMAACIDAAAjAwAAIQMAACMDAAAkAwAAJQMAACYDAAAjAwAAJQMAACMDAAAnAwAAKAMAACkDAAAjAwAAKAMAACMDAAAqAwAAKwMAACwDAAAhAwAAKwMAACEDAAAtAwAALAMAAC4DAAAiAwAALAMAACIDAAAhAwAALQMAACEDAAAkAwAALQMAACQDAAAvAwAAlAIAADADAAAlAwAAlAIAACUDAAAxAwAAMAMAAAwDAAAmAwAAMAMAACYDAAAlAwAAMQMAACUDAAAnAwAAMQMAACcDAAAuAwAACQMAADIDAAAoAwAACQMAACgDAAAKAwAAMgMAADMDAAApAwAAMgMAACkDAAAoAwAACgMAACgDAAAqAwAACgMAACoDAAAMAwAANAMAADUDAAA2AwAANAMAADYDAAA3AwAAOAMAADkDAAA2AwAAOAMAADYDAAA6AwAAOwMAADcDAAA2AwAAOwMAADYDAAA5AwAAPAMAAD0DAAA0AwAAPAMAADQDAAA+AwAAPQMAAD8DAAA1AwAAPQMAADUDAAA0AwAAPgMAADQDAAA3AwAAPgMAADcDAABAAwAA7wIAAEEDAAA4AwAA7wIAADgDAABCAwAAQQMAABgDAAA5AwAAQQMAADkDAAA4AwAAQgMAADgDAAA6AwAAQgMAADoDAABDAwAAHQMAAEQDAAA7AwAAHQMAADsDAABFAwAARAMAAEYDAAA3AwAARAMAADcDAAA7AwAARQMAADsDAAA5AwAARQMAADkDAAAYAwAARwMAAEgDAABJAwAARwMAAEkDAABKAwAASwMAAEwDAABJAwAASwMAAEkDAABNAwAATgMAAEoDAABJAwAATgMAAEkDAABMAwAAKwMAAC0DAABHAwAAKwMAAEcDAABPAwAALQMAAFADAABIAwAALQMAAEgDAABHAwAATwMAAEcDAABKAwAATwMAAEoDAABRAwAACQMAAFIDAABLAwAACQMAAEsDAABTAwAAUgMAAFQDAABMAwAAUgMAAEwDAABLAwAAUwMAAEsDAABNAwAAUwMAAE0DAAAvAwAAVQMAAFYDAABOAwAAVQMAAE4DAABXAwAAVgMAAFgDAABKAwAAVgMAAEoDAABOAwAAVwMAAE4DAABMAwAAVwMAAEwDAABZAwAAWgMAAFsDAABcAwAAWgMAAFwDAABdAwAAXgMAAF8DAABcAwAAXgMAAFwDAABbAwAAYAMAAGEDAABcAwAAYAMAAFwDAABfAwAAYgMAAGMDAABaAwAAYgMAAFoDAABkAwAAYwMAAGUDAABbAwAAYwMAAFsDAABaAwAAZAMAAFoDAABdAwAAZAMAAF0DAABmAwAAZwMAAD4DAABeAwAAZwMAAF4DAABoAwAAPgMAAEADAABfAwAAPgMAAF8DAABeAwAAaAMAAF4DAABbAwAAaAMAAFsDAABpAwAAHQMAAGoDAABgAwAAHQMAAGADAABrAwAAagMAAGwDAABhAwAAagMAAGEDAABgAwAAawMAAGADAABfAwAAawMAAF8DAABGAwAAbQMAAG4DAABvAwAAbQMAAG8DAABwAwAAcQMAAHIDAABvAwAAcQMAAG8DAABuAwAAcwMAAHADAABvAwAAcwMAAG8DAAByAwAAKwMAAE8DAABtAwAAKwMAAG0DAAB0AwAATwMAAFgDAABuAwAATwMAAG4DAABtAwAAdAMAAG0DAABwAwAAdAMAAHADAAB1AwAAVQMAAHYDAABxAwAAVQMAAHEDAAB3AwAAdgMAAHgDAAByAwAAdgMAAHIDAABxAwAAdwMAAHEDAABuAwAAdwMAAG4DAABYAwAAeQMAAHoDAABzAwAAeQMAAHMDAAB7AwAAegMAAHwDAABwAwAAegMAAHADAABzAwAAewMAAHMDAAByAwAAewMAAHIDAAB4AwAAfQMAAH4DAAB/AwAAfQMAAH8DAACAAwAAgQMAAIIDAAB/AwAAgQMAAH8DAACDAwAAhAMAAIUDAAB/AwAAhAMAAH8DAACGAwAAhwMAAIgDAAB9AwAAhwMAAH0DAACJAwAAiAMAAIoDAAB+AwAAiAMAAH4DAAB9AwAAiQMAAH0DAACAAwAAiQMAAIADAACLAwAAKwMAAHQDAACBAwAAKwMAAIEDAACMAwAAdAMAAHwDAACCAwAAdAMAAIIDAACBAwAAjAMAAIEDAACDAwAAjAMAAIMDAACNAwAAeQMAAI4DAACEAwAAeQMAAIQDAAB6AwAAjgMAAIsDAACFAwAAjgMAAIUDAACEAwAAegMAAIQDAACGAwAAegMAAIYDAAB1AwAAjwMAAJADAACRAwAAjwMAAJEDAACSAwAAkwMAAJQDAACRAwAAkwMAAJEDAACQAwAAlQMAAJIDAACRAwAAlQMAAJEDAACUAwAAYgMAAGQDAACPAwAAYgMAAI8DAACWAwAAZAMAAGYDAACQAwAAZAMAAJADAACPAwAAlgMAAI8DAACSAwAAlgMAAJIDAACXAwAAHQMAAJgDAACTAwAAHQMAAJMDAABqAwAAmAMAAJkDAACUAwAAmAMAAJQDAACTAwAAagMAAJMDAACQAwAAagMAAJADAABmAwAAmgMAAJsDAACVAwAAmgMAAJUDAACcAwAAmwMAAJ0DAACSAwAAmwMAAJIDAACVAwAAnAMAAJUDAACUAwAAnAMAAJQDAACZAwAAngMAAJ8DAACgAwAAngMAAKADAAChAwAAogMAAKMDAACgAwAAogMAAKADAACfAwAApAMAAKUDAACgAwAApAMAAKADAACjAwAAhwMAAIkDAACeAwAAhwMAAJ4DAACmAwAAiQMAAIsDAACfAwAAiQMAAJ8DAACeAwAApgMAAJ4DAAChAwAApgMAAKEDAACnAwAAeQMAAKgDAACiAwAAeQMAAKIDAACOAwAAqAMAAKkDAACjAwAAqAMAAKMDAACiAwAAjgMAAKIDAACfAwAAjgMAAJ8DAACqAwAAqwMAAKwDAACkAwAAqwMAAKQDAACtAwAArAMAAK4DAAClAwAArAMAAKUDAACkAwAArQMAAKQDAACjAwAArQMAAKMDAACpAwAArwMAALADAACxAwAArwMAALEDAACyAwAAswMAALQDAACxAwAAswMAALEDAACwAwAAtQMAALYDAACxAwAAtQMAALEDAAC0AwAAtwMAALgDAACvAwAAtwMAAK8DAAC5AwAAuAMAALoDAACwAwAAuAMAALADAACvAwAAuQMAAK8DAACyAwAAuQMAALIDAAC7AwAAYgMAALwDAACzAwAAYgMAALMDAAC9AwAAvAMAAJcDAAC0AwAAvAMAALQDAACzAwAAvQMAALMDAACwAwAAvQMAALADAAC+AwAAmgMAAL8DAAC1AwAAmgMAALUDAACbAwAAvwMAAMADAAC2AwAAvwMAALYDAAC1AwAAmwMAALUDAAC0AwAAmwMAALQDAADBAwAAwgMAAMMDAADEAwAAwgMAAMQDAADFAwAAxgMAAMcDAADEAwAAxgMAAMQDAADIAwAAyQMAAMoDAADEAwAAyQMAAMQDAADLAwAAtwMAALkDAADCAwAAtwMAAMIDAADMAwAAuQMAALsDAADDAwAAuQMAAMMDAADCAwAAzAMAAMIDAADFAwAAzAMAAMUDAADNAwAAmgMAAM4DAADGAwAAmgMAAMYDAADPAwAAzgMAANADAADHAwAAzgMAAMcDAADGAwAAzwMAAMYDAADIAwAAzwMAAMgDAAC7AwAA0QMAANIDAADJAwAA0QMAAMkDAADTAwAA0gMAAM0DAADKAwAA0gMAAMoDAADJAwAA0wMAAMkDAADLAwAA0wMAAMsDAADQAwAA1AMAANUDAADWAwAA1AMAANYDAADXAwAA2AMAANkDAADWAwAA2AMAANYDAADaAwAA2wMAANwDAADWAwAA2wMAANYDAADZAwAAhwMAAN0DAADUAwAAhwMAANQDAADeAwAA3QMAAK4DAADVAwAA3QMAANUDAADUAwAA3gMAANQDAADXAwAA3gMAANcDAADfAwAA4AMAAOEDAADYAwAA4AMAANgDAACsAwAA4QMAAOIDAADZAwAA4QMAANkDAADYAwAArAMAANgDAADaAwAArAMAANoDAACnAwAA4wMAAOQDAADbAwAA4wMAANsDAADlAwAA5AMAAN8DAADcAwAA5AMAANwDAADbAwAA5QMAANsDAADZAwAA5QMAANkDAADmAwAA5wMAAOgDAADpAwAA5wMAAOkDAADqAwAA6wMAAOwDAADpAwAA6wMAAOkDAADoAwAA7QMAAO4DAADpAwAA7QMAAOkDAADvAwAA8AMAAPEDAADnAwAA8AMAAOcDAADyAwAA8QMAAPMDAADoAwAA8QMAAOgDAADnAwAA8gMAAOcDAADqAwAA8gMAAOoDAAD0AwAAtwMAAMwDAADrAwAAtwMAAOsDAAD1AwAAzAMAAM0DAADsAwAAzAMAAOwDAADrAwAA9QMAAOsDAADoAwAA9QMAAOgDAAD2AwAA0QMAAPcDAADtAwAA0QMAAO0DAAD4AwAA9wMAAPQDAADuAwAA9wMAAO4DAADtAwAA+AMAAO0DAADvAwAA+AMAAO8DAAD5AwAA+gMAAPsDAAD8AwAA+gMAAPwDAAD9AwAA/gMAAP8DAAD8AwAA/gMAAPwDAAD7AwAAAAQAAAEEAAD8AwAAAAQAAPwDAAD/AwAAAgQAAAMEAAD6AwAAAgQAAPoDAAAEBAAAAwQAAAUEAAD7AwAAAwQAAPsDAAD6AwAABAQAAPoDAAD9AwAABAQAAP0DAAAGBAAAhwMAAAcEAAD+AwAAhwMAAP4DAAAIBAAABwQAAN8DAAD/AwAABwQAAP8DAAD+AwAACAQAAP4DAAD7AwAACAQAAPsDAAAJBAAA4wMAAAoEAAAABAAA4wMAAAAEAAALBAAACgQAAAwEAAABBAAACgQAAAEEAAAABAAACwQAAAAEAAD/AwAACwQAAP8DAAANBAAADgQAAA8EAAAQBAAADgQAABAEAAARBAAAEgQAABMEAAAQBAAAEgQAABAEAAAUBAAAFQQAABEEAAAQBAAAFQQAABAEAAAWBAAAAgQAABcEAAAOBAAAAgQAAA4EAAAYBAAAFwQAABkEAAAPBAAAFwQAAA8EAAAOBAAAGAQAAA4EAAARBAAAGAQAABEEAAAaBAAA4wMAABsEAAASBAAA4wMAABIEAAAKBAAAGwQAABwEAAATBAAAGwQAABMEAAASBAAACgQAABIEAAAUBAAACgQAABQEAAAZBAAAHQQAAB4EAAAVBAAAHQQAABUEAAAfBAAAHgQAABoEAAARBAAAHgQAABEEAAAVBAAAHwQAABUEAAAWBAAAHwQAABYEAAAcBAAAIAQAACEEAAAiBAAAIAQAACIEAAAjBAAAJAQAACUEAAAiBAAAJAQAACIEAAAhBAAAJgQAACcEAAAiBAAAJgQAACIEAAAlBAAAKAQAACkEAAAgBAAAKAQAACAEAAAqBAAAKQQAACsEAAAhBAAAKQQAACEEAAAgBAAAKgQAACAEAAAjBAAAKgQAACMEAAAsBAAALQQAAC4EAAAkBAAALQQAACQEAAAvBAAALgQAAPQDAAAlBAAALgQAACUEAAAkBAAALwQAACQEAAAhBAAALwQAACEEAAAwBAAA0QMAADEEAAAmBAAA0QMAACYEAAD3AwAAMQQAADIEAAAnBAAAMQQAACcEAAAmBAAA9wMAACYEAAAlBAAA9wMAACUEAAD0AwAAMwQAADQEAAA1BAAAMwQAADUEAAA2BAAANwQAADgEAAA1BAAANwQAADUEAAA5BAAAOgQAADYEAAA1BAAAOgQAADUEAAA7BAAAKAQAADwEAAAzBAAAKAQAADMEAAA9BAAAPAQAACwEAAA0BAAAPAQAADQEAAAzBAAAPQQAADMEAAA2BAAAPQQAADYEAAA+BAAA0QMAAD8EAAA3BAAA0QMAADcEAAAxBAAAPwQAAEAEAAA4BAAAPwQAADgEAAA3BAAAMQQAADcEAAA5BAAAMQQAADkEAABBBAAAQgQAAEMEAAA6BAAAQgQAADoEAABEBAAAQwQAAEUEAAA2BAAAQwQAADYEAAA6BAAARAQAADoEAAA7BAAARAQAADsEAABGBAAARwQAAEgEAABJBAAARwQAAEkEAABKBAAASwQAAEwEAABJBAAASwQAAEkEAABNBAAATgQAAEoEAABJBAAATgQAAEkEAABMBAAATwQAAFAEAABHBAAATwQAAEcEAABRBAAAUAQAAFIEAABIBAAAUAQAAEgEAABHBAAAUQQAAEcEAABKBAAAUQQAAEoEAABTBAAAAgQAAFQEAABLBAAAAgQAAEsEAABVBAAAVAQAABoEAABMBAAAVAQAAEwEAABLBAAAVQQAAEsEAABNBAAAVQQAAE0EAABWBAAAHQQAAFcEAABOBAAAHQQAAE4EAABYBAAAVwQAAFkEAABKBAAAVwQAAEoEAABOBAAAWAQAAE4EAABMBAAAWAQAAEwEAAAaBAAAWgQAAFsEAABcBAAAWgQAAFwEAABdBAAAXgQAAF8EAABcBAAAXgQAAFwEAABgBAAAYQQAAGIEAABcBAAAYQQAAFwEAABjBAAATwQAAGQEAABaBAAATwQAAFoEAABlBAAAZAQAAFMEAABbBAAAZAQAAFsEAABaBAAAZQQAAFoEAABdBAAAZQQAAF0EAABmBAAAHQQAAGcEAABeBAAAHQQAAF4EAABXBAAAZwQAAGgEAABfBAAAZwQAAF8EAABeBAAAVwQAAF4EAABgBAAAVwQAAGAEAABTBAAAaQQAAGoEAABhBAAAaQQAAGEEAABrBAAAagQAAGYEAABiBAAAagQAAGIEAABhBAAAawQAAGEEAABjBAAAawQAAGMEAABoBAAAbAQAAG0EAABuBAAAbAQAAG4EAABvBAAAcAQAAHEEAABuBAAAcAQAAG4EAABtBAAAcgQAAHMEAABuBAAAcgQAAG4EAABxBAAAdAQAAHUEAABsBAAAdAQAAGwEAAB2BAAAdQQAAHcEAABtBAAAdQQAAG0EAABsBAAAdgQAAGwEAABvBAAAdgQAAG8EAAB4BAAAKAQAAD0EAABwBAAAKAQAAHAEAAB5BAAAPQQAAHoEAABxBAAAPQQAAHEEAABwBAAAeQQAAHAEAABtBAAAeQQAAG0EAAB7BAAAQgQAAHwEAAByBAAAQgQAAHIEAABDBAAAfAQAAHgEAABzBAAAfAQAAHMEAAByBAAAQwQAAHIEAABxBAAAQwQAAHEEAAA+BAAAfQQAAH4EAAB/BAAAfQQAAH8EAACABAAAgQQAAIIEAAB/BAAAgQQAAH8EAAB+BAAAgwQAAIAEAAB/BAAAgwQAAH8EAACEBAAAdAQAAIUEAAB9BAAAdAQAAH0EAACGBAAAhQQAAHgEAAB+BAAAhQQAAH4EAAB9BAAAhgQAAH0EAACABAAAhgQAAIAEAACHBAAAQgQAAIgEAACBBAAAQgQAAIEEAACJBAAAiAQAAIoEAACCBAAAiAQAAIIEAACBBAAAiQQAAIEEAAB+BAAAiQQAAH4EAACLBAAAjAQAAI0EAACDBAAAjAQAAIMEAACOBAAAjQQAAIcEAACABAAAjQQAAIAEAACDBAAAjgQAAIMEAACEBAAAjgQAAIQEAACPBAAAkAQAAJEEAACSBAAAkAQAAJIEAACTBAAAlAQAAJUEAACSBAAAlAQAAJIEAACWBAAAlwQAAJMEAACSBAAAlwQAAJIEAACYBAAATwQAAJkEAACQBAAATwQAAJAEAACaBAAAmQQAAGYEAACRBAAAmQQAAJEEAACQBAAAmgQAAJAEAACTBAAAmgQAAJMEAACbBAAAnAQAAJ0EAACUBAAAnAQAAJQEAABqBAAAnQQAAJ4EAACVBAAAnQQAAJUEAACUBAAAagQAAJQEAACWBAAAagQAAJYEAABmBAAAnwQAAKAEAACXBAAAnwQAAJcEAAChBAAAoAQAAJsEAACTBAAAoAQAAJMEAACXBAAAoQQAAJcEAACYBAAAoQQAAJgEAACeBAAAogQAAKMEAACkBAAAogQAAKQEAAClBAAApgQAAKcEAACkBAAApgQAAKQEAACoBAAAqQQAAKoEAACkBAAAqQQAAKQEAACrBAAArAQAAK0EAACiBAAArAQAAKIEAACuBAAArQQAAK8EAACjBAAArQQAAKMEAACiBAAArgQAAKIEAAClBAAArgQAAKUEAACwBAAAdAQAAIYEAACmBAAAdAQAAKYEAACxBAAAhgQAALIEAACnBAAAhgQAAKcEAACmBAAAsQQAAKYEAACoBAAAsQQAAKgEAACzBAAAjAQAALQEAACpBAAAjAQAAKkEAACNBAAAtAQAALUEAACqBAAAtAQAAKoEAACpBAAAjQQAAKkEAACrBAAAjQQAAKsEAACyBAAAtgQAALcEAAC4BAAAtgQAALgEAAC5BAAAugQAALsEAAC4BAAAugQAALgEAAC3BAAAvAQAALkEAAC4BAAAvAQAALgEAAC7BAAAvQQAAL4EAAC2BAAAvQQAALYEAAC/BAAAvgQAAMAEAAC3BAAAvgQAALcEAAC2BAAAvwQAALYEAAC5BAAAvwQAALkEAADBBAAATwQAAMIEAAC6BAAATwQAALoEAADDBAAAwgQAAMQEAAC7BAAAwgQAALsEAAC6BAAAwwQAALoEAAC3BAAAwwQAALcEAADABAAAnwQAAMUEAAC8BAAAnwQAALwEAADGBAAAxQQAAMcEAAC5BAAAxQQAALkEAAC8BAAAxgQAALwEAAC7BAAAxgQAALsEAADEBAAAyAQAAMkEAADKBAAAyAQAAMoEAADLBAAAzAQAAM0EAADKBAAAzAQAAMoEAADJBAAAzgQAAM8EAADKBAAAzgQAAMoEAADQBAAAvQQAAL8EAADIBAAAvQQAAMgEAADRBAAAvwQAAMEEAADJBAAAvwQAAMkEAADIBAAA0QQAAMgEAADLBAAA0QQAAMsEAADSBAAAnwQAANMEAADMBAAAnwQAAMwEAADUBAAA0wQAANUEAADNBAAA0wQAAM0EAADMBAAA1AQAAMwEAADJBAAA1AQAAMkEAADBBAAA1gQAANcEAADOBAAA1gQAAM4EAADYBAAA1wQAANIEAADPBAAA1wQAAM8EAADOBAAA2AQAAM4EAADQBAAA2AQAANAEAADZBAAA2gQAANsEAADcBAAA2gQAANwEAADdBAAA3gQAAN8EAADcBAAA3gQAANwEAADgBAAA4QQAAOIEAADcBAAA4QQAANwEAADfBAAA4wQAAOQEAADaBAAA4wQAANoEAADlBAAA5AQAAOYEAADbBAAA5AQAANsEAADaBAAA5QQAANoEAADdBAAA5QQAAN0EAADnBAAArAQAAOgEAADeBAAArAQAAN4EAADpBAAA6AQAALAEAADfBAAA6AQAAN8EAADeBAAA6QQAAN4EAADgBAAA6QQAAOAEAADqBAAAjAQAAOsEAADhBAAAjAQAAOEEAADsBAAA6wQAAOcEAADiBAAA6wQAAOIEAADhBAAA7AQAAOEEAADfBAAA7AQAAN8EAACwBAAA7QQAAO4EAADvBAAA7QQAAO8EAADwBAAA8QQAAPIEAADvBAAA8QQAAO8EAADuBAAA8wQAAPAEAADvBAAA8wQAAO8EAADyBAAA4wQAAPQEAADtBAAA4wQAAO0EAAD1BAAA9AQAAPYEAADuBAAA9AQAAO4EAADtBAAA9QQAAO0EAADwBAAA9QQAAPAEAAD3BAAAjAQAAPgEAADxBAAAjAQAAPEEAADrBAAA+AQAAPkEAADyBAAA+AQAAPIEAADxBAAA6wQAAPEEAADuBAAA6wQAAO4EAADnBAAA+gQAAPsEAADzBAAA+gQAAPMEAAD8BAAA+wQAAP0EAADwBAAA+wQAAPAEAADzBAAA/AQAAPMEAADyBAAA/AQAAPIEAAD+BAAA/wQAAAAFAAABBQAA/wQAAAEFAAACBQAAAwUAAAQFAAABBQAAAwUAAAEFAAAFBQAABgUAAAIFAAABBQAABgUAAAEFAAAHBQAAvQQAAAgFAAD/BAAAvQQAAP8EAAAJBQAACAUAAAoFAAAABQAACAUAAAAFAAD/BAAACQUAAP8EAAACBQAACQUAAAIFAAALBQAA1gQAAAwFAAADBQAA1gQAAAMFAADXBAAADAUAAA0FAAAEBQAADAUAAAQFAAADBQAA1wQAAAMFAAAFBQAA1wQAAAUFAADSBAAADgUAAA8FAAAGBQAADgUAAAYFAAAQBQAADwUAABEFAAACBQAADwUAAAIFAAAGBQAAEAUAAAYFAAAHBQAAEAUAAAcFAAASBQAAEwUAABQFAAAVBQAAEwUAABUFAAAWBQAAFwUAABgFAAAVBQAAFwUAABUFAAAUBQAAGQUAABYFAAAVBQAAGQUAABUFAAAYBQAAGgUAABsFAAATBQAAGgUAABMFAAAcBQAAGwUAAB0FAAAUBQAAGwUAABQFAAATBQAAHAUAABMFAAAWBQAAHAUAABYFAAAeBQAA4wQAAB8FAAAXBQAA4wQAABcFAAAgBQAAHwUAACEFAAAYBQAAHwUAABgFAAAXBQAAIAUAABcFAAAUBQAAIAUAABQFAAAiBQAA+gQAACMFAAAZBQAA+gQAABkFAAAkBQAAIwUAAB4FAAAWBQAAIwUAABYFAAAZBQAAJAUAABkFAAAYBQAAJAUAABgFAAD9BAAAJQUAACYFAAAnBQAAJQUAACcFAAAoBQAAKQUAACoFAAAnBQAAKQUAACcFAAArBQAALAUAACgFAAAnBQAALAUAACcFAAAqBQAAvQQAAAkFAAAlBQAAvQQAACUFAAAtBQAACQUAAAsFAAAmBQAACQUAACYFAAAlBQAALQUAACUFAAAoBQAALQUAACgFAAAuBQAADgUAAC8FAAApBQAADgUAACkFAAAwBQAALwUAADEFAAAqBQAALwUAACoFAAApBQAAMAUAACkFAAArBQAAMAUAACsFAAALBQAAMgUAADMFAAAsBQAAMgUAACwFAAA0BQAAMwUAADUFAAAoBQAAMwUAACgFAAAsBQAANAUAACwFAAAqBQAANAUAACoFAAA2BQAANwUAADgFAAA5BQAANwUAADkFAAA6BQAAOwUAADwFAAA5BQAAOwUAADkFAAA9BQAAPgUAADoFAAA5BQAAPgUAADkFAAA8BQAAPwUAAEAFAAA3BQAAPwUAADcFAABBBQAAQAUAAEIFAAA4BQAAQAUAADgFAAA3BQAAQQUAADcFAAA6BQAAQQUAADoFAABDBQAAGgUAAEQFAAA7BQAAGgUAADsFAABFBQAARAUAAB4FAAA8BQAARAUAADwFAAA7BQAARQUAADsFAAA9BQAARQUAAD0FAABGBQAA+gQAAEcFAAA+BQAA+gQAAD4FAAAjBQAARwUAAEMFAAA6BQAARwUAADoFAAA+BQAAIwUAAD4FAAA8BQAAIwUAADwFAAAeBQAASAUAAEkFAABKBQAASAUAAEoFAABLBQAATAUAAE0FAABKBQAATAUAAEoFAABOBQAATwUAAFAFAABKBQAATwUAAEoFAABNBQAAUQUAAFIFAABIBQAAUQUAAEgFAABTBQAAUgUAAFQFAABJBQAAUgUAAEkFAABIBQAAUwUAAEgFAABLBQAAUwUAAEsFAABVBQAAvQQAAC0FAABMBQAAvQQAAEwFAABWBQAALQUAAFcFAABNBQAALQUAAE0FAABMBQAAVgUAAEwFAABOBQAAVgUAAE4FAABYBQAAMgUAAFkFAABPBQAAMgUAAE8FAAAzBQAAWQUAAFUFAABQBQAAWQUAAFAFAABPBQAAMwUAAE8FAABNBQAAMwUAAE0FAABXBQAAWgUAAFsFAABcBQAAWgUAAFwFAABdBQAAXgUAAF8FAABcBQAAXgUAAFwFAABbBQAAYAUAAGEFAABcBQAAYAUAAFwFAABiBQAAUQUAAFMFAABaBQAAUQUAAFoFAABjBQAAUwUAAFUFAABbBQAAUwUAAFsFAABaBQAAYwUAAFoFAABdBQAAYwUAAF0FAABkBQAAMgUAAGUFAABeBQAAMgUAAF4FAABZBQAAZQUAAGYFAABfBQAAZQUAAF8FAABeBQAAWQUAAF4FAABbBQAAWQUAAFsFAABVBQAAZwUAAGgFAABgBQAAZwUAAGAFAABpBQAAaAUAAGoFAABhBQAAaAUAAGEFAABgBQAAaQUAAGAFAABiBQAAaQUAAGIFAABrBQAAbAUAAG0FAABuBQAAbAUAAG4FAABvBQAAcAUAAHEFAABuBQAAcAUAAG4FAABtBQAAcgUAAHMFAABuBQAAcgUAAG4FAABxBQAAdAUAAHUFAABsBQAAdAUAAGwFAAB2BQAAdQUAAHcFAABtBQAAdQUAAG0FAABsBQAAdgUAAGwFAABvBQAAdgUAAG8FAAB4BQAAeQUAAEEFAABwBQAAeQUAAHAFAAB6BQAAQQUAAHsFAABxBQAAQQUAAHEFAABwBQAAegUAAHAFAABtBQAAegUAAG0FAAB8BQAA+gQAAH0FAAByBQAA+gQAAHIFAABHBQAAfQUAAHgFAABzBQAAfQUAAHMFAAByBQAARwUAAHIFAABxBQAARwUAAHEFAAB7BQAAfgUAAH8FAACABQAAfgUAAIAFAACBBQAAggUAAIMFAACABQAAggUAAIAFAAB/BQAAhAUAAIEFAACABQAAhAUAAIAFAACDBQAAUQUAAIUFAAB+BQAAUQUAAH4FAACGBQAAhQUAAGQFAAB/BQAAhQUAAH8FAAB+BQAAhgUAAH4FAACBBQAAhgUAAIEFAACHBQAAZwUAAIgFAACCBQAAZwUAAIIFAABoBQAAiAUAAIkFAACDBQAAiAUAAIMFAACCBQAAaAUAAIIFAAB/BQAAaAUAAH8FAABqBQAAigUAAIsFAACEBQAAigUAAIQFAACMBQAAiwUAAI0FAACBBQAAiwUAAIEFAACEBQAAjAUAAIQFAACDBQAAjAUAAIMFAACJBQAAjgUAAI8FAACQBQAAjgUAAJAFAACRBQAAkgUAAJMFAACQBQAAkgUAAJAFAACPBQAAlAUAAJUFAACQBQAAlAUAAJAFAACTBQAAlgUAAJcFAACOBQAAlgUAAI4FAACYBQAAlwUAAJkFAACPBQAAlwUAAI8FAACOBQAAmAUAAI4FAACRBQAAmAUAAJEFAACaBQAAdAUAAHYFAACSBQAAdAUAAJIFAACbBQAAdgUAAJwFAACTBQAAdgUAAJMFAACSBQAAmwUAAJIFAACPBQAAmwUAAI8FAACZBQAA+gQAAJ0FAACUBQAA+gQAAJQFAACeBQAAnQUAAJ8FAACVBQAAnQUAAJUFAACUBQAAngUAAJQFAACTBQAAngUAAJMFAACcBQAAoAUAAKEFAACiBQAAoAUAAKIFAACjBQAApAUAAKUFAACiBQAApAUAAKIFAAChBQAApgUAAKcFAACiBQAApgUAAKIFAACoBQAAlgUAAJgFAACgBQAAlgUAAKAFAACpBQAAmAUAAJoFAAChBQAAmAUAAKEFAACgBQAAqQUAAKAFAACjBQAAqQUAAKMFAACqBQAA+gQAAKsFAACkBQAA+gQAAKQFAACdBQAAqwUAAKwFAAClBQAAqwUAAKUFAACkBQAAnQUAAKQFAAChBQAAnQUAAKEFAACfBQAArQUAAK4FAACmBQAArQUAAKYFAACvBQAArgUAAKoFAACnBQAArgUAAKcFAACmBQAArwUAAKYFAACoBQAArwUAAKgFAACsBQAAsAUAALEFAACyBQAAsAUAALIFAACzBQAAtAUAALUFAACyBQAAtAUAALIFAAC2BQAAtwUAALgFAACyBQAAtwUAALIFAAC5BQAAUQUAALoFAACwBQAAUQUAALAFAAC7BQAAugUAAI0FAACxBQAAugUAALEFAACwBQAAuwUAALAFAACzBQAAuwUAALMFAAC8BQAAvQUAAL4FAAC0BQAAvQUAALQFAACLBQAAvgUAAL8FAAC1BQAAvgUAALUFAAC0BQAAiwUAALQFAAC2BQAAiwUAALYFAADABQAAwQUAAMIFAAC3BQAAwQUAALcFAADDBQAAwgUAAMQFAAC4BQAAwgUAALgFAAC3BQAAwwUAALcFAAC5BQAAwwUAALkFAADFBQAAxgUAAMcFAADIBQAAxgUAAMgFAADJBQAAygUAAMsFAADIBQAAygUAAMgFAADHBQAAzAUAAM0FAADIBQAAzAUAAMgFAADOBQAAzwUAANAFAADGBQAAzwUAAMYFAADRBQAA0AUAANIFAADHBQAA0AUAAMcFAADGBQAA0QUAAMYFAADJBQAA0QUAAMkFAADTBQAAlgUAANQFAADKBQAAlgUAAMoFAADVBQAA1AUAANYFAADLBQAA1AUAAMsFAADKBQAA1QUAAMoFAADHBQAA1QUAAMcFAADXBQAArQUAANgFAADMBQAArQUAAMwFAADZBQAA2AUAANMFAADNBQAA2AUAAM0FAADMBQAA2QUAAMwFAADOBQAA2QUAAM4FAADaBQAA2wUAANwFAADdBQAA2wUAAN0FAADeBQAA3wUAAOAFAADdBQAA3wUAAN0FAADhBQAA4gUAAN4FAADdBQAA4gUAAN0FAADgBQAA4wUAAOQFAADbBQAA4wUAANsFAADlBQAA5AUAAOYFAADcBQAA5AUAANwFAADbBQAA5QUAANsFAADeBQAA5QUAAN4FAADnBQAA6AUAANEFAADfBQAA6AUAAN8FAADpBQAA0QUAANMFAADgBQAA0QUAAOAFAADfBQAA6QUAAN8FAADhBQAA6QUAAOEFAADqBQAArQUAAOsFAADiBQAArQUAAOIFAADsBQAA6wUAAO0FAADeBQAA6wUAAN4FAADiBQAA7AUAAOIFAADgBQAA7AUAAOAFAADTBQAA7gUAAO8FAADwBQAA7gUAAPAFAADxBQAA8gUAAPMFAADwBQAA8gUAAPAFAADvBQAA9AUAAPUFAADwBQAA9AUAAPAFAAD2BQAAUQUAALsFAADuBQAAUQUAAO4FAAD3BQAAuwUAALwFAADvBQAAuwUAAO8FAADuBQAA9wUAAO4FAADxBQAA9wUAAPEFAAD4BQAAwQUAAPkFAADyBQAAwQUAAPIFAAD6BQAA+QUAAPsFAADzBQAA+QUAAPMFAADyBQAA+gUAAPIFAADvBQAA+gUAAO8FAAC8BQAA4wUAAPwFAAD0BQAA4wUAAPQFAAD9BQAA/AUAAP4FAAD1BQAA/AUAAPUFAAD0BQAA/QUAAPQFAAD2BQAA/QUAAPYFAAD/BQAAAAYAAAEGAAACBgAAAAYAAAIGAAADBgAABAYAAAUGAAACBgAABAYAAAIGAAAGBgAABwYAAAgGAAACBgAABwYAAAIGAAAJBgAAUQUAAPcFAAAABgAAUQUAAAAGAAAKBgAA9wUAAAsGAAABBgAA9wUAAAEGAAAABgAACgYAAAAGAAADBgAACgYAAAMGAAAMBgAA4wUAAA0GAAAEBgAA4wUAAAQGAAD8BQAADQYAAO0FAAAFBgAADQYAAAUGAAAEBgAA/AUAAAQGAAAGBgAA/AUAAAYGAAD+BQAArQUAAA4GAAAHBgAArQUAAAcGAADrBQAADgYAAAwGAAAIBgAADgYAAAgGAAAHBgAA6wUAAAcGAAAJBgAA6wUAAAkGAADtBQAADwYAABAGAAARBgAADwYAABEGAAASBgAAEwYAABQGAAARBgAAEwYAABEGAAAVBgAAFgYAABIGAAARBgAAFgYAABEGAAAUBgAAFwYAABgGAAAPBgAAFwYAAA8GAAAZBgAAGAYAABoGAAAQBgAAGAYAABAGAAAPBgAAGQYAAA8GAAASBgAAGQYAABIGAAAbBgAAUQUAAAoGAAATBgAAUQUAABMGAAAcBgAACgYAAB0GAAAUBgAACgYAABQGAAATBgAAHAYAABMGAAAVBgAAHAYAABUGAAAeBgAArQUAAB8GAAAWBgAArQUAABYGAAAgBgAAHwYAACEGAAASBgAAHwYAABIGAAAWBgAAIAYAABYGAAAUBgAAIAYAABQGAAAdBgAAIgYAACMGAAAkBgAAIgYAACQGAAAlBgAAJgYAACcGAAAkBgAAJgYAACQGAAAoBgAAKQYAACoGAAAkBgAAKQYAACQGAAArBgAAFwYAACwGAAAiBgAAFwYAACIGAAAtBgAALAYAACEGAAAjBgAALAYAACMGAAAiBgAALQYAACIGAAAlBgAALQYAACUGAAAuBgAArQUAAC8GAAAmBgAArQUAACYGAAAfBgAALwYAADAGAAAnBgAALwYAACcGAAAmBgAAHwYAACYGAAAoBgAAHwYAACgGAAAxBgAAMgYAADMGAAApBgAAMgYAACkGAAA0BgAAMwYAADUGAAAqBgAAMwYAACoGAAApBgAANAYAACkGAAArBgAANAYAACsGAAAwBgAANgYAADcGAAA4BgAANgYAADgGAAA5BgAAOgYAADsGAAA4BgAAOgYAADgGAAA8BgAAPQYAADkGAAA4BgAAPQYAADgGAAA+BgAAPwYAAEAGAAA2BgAAPwYAADYGAABBBgAAQAYAAEIGAAA3BgAAQAYAADcGAAA2BgAAQQYAADYGAAA5BgAAQQYAADkGAABDBgAAFwYAAC0GAAA6BgAAFwYAADoGAABEBgAALQYAAC4GAAA7BgAALQYAADsGAAA6BgAARAYAADoGAAA8BgAARAYAADwGAABFBgAAMgYAAEYGAAA9BgAAMgYAAD0GAABHBgAARgYAAEgGAAA5BgAARgYAADkGAAA9BgAARwYAAD0GAAA+BgAARwYAAD4GAAAuBgAASQYAAEoGAABLBgAASQYAAEsGAABMBgAATQYAAE4GAABLBgAATQYAAEsGAABPBgAAUAYAAFEGAABLBgAAUAYAAEsGAABSBgAAPwYAAEEGAABJBgAAPwYAAEkGAABTBgAAQQYAAEgGAABKBgAAQQYAAEoGAABJBgAAUwYAAEkGAABMBgAAUwYAAEwGAABUBgAAMgYAAFUGAABNBgAAMgYAAE0GAABGBgAAVQYAAFYGAABOBgAAVQYAAE4GAABNBgAARgYAAE0GAABPBgAARgYAAE8GAABXBgAAWAYAAFkGAABQBgAAWAYAAFAGAABaBgAAWQYAAFsGAABRBgAAWQYAAFEGAABQBgAAWgYAAFAGAABSBgAAWgYAAFIGAABWBgAAXAYAAF0GAABeBgAAXAYAAF4GAABfBgAAYAYAAGEGAABeBgAAYAYAAF4GAABiBgAAYwYAAGQGAABeBgAAYwYAAF4GAABhBgAAZQYAAGYGAABcBgAAZQYAAFwGAABnBgAAZgYAAGgGAABdBgAAZgYAAF0GAABcBgAAZwYAAFwGAABfBgAAZwYAAF8GAABpBgAAPwYAAFMGAABgBgAAPwYAAGAGAABqBgAAUwYAAFsGAABhBgAAUwYAAGEGAABgBgAAagYAAGAGAABiBgAAagYAAGIGAABrBgAAWAYAAGwGAABjBgAAWAYAAGMGAABZBgAAbAYAAGkGAABkBgAAbAYAAGQGAABjBgAAWQYAAGMGAABhBgAAWQYAAGEGAABbBgAAbQYAAG4GAABvBgAAbQYAAG8GAABwBgAAcQYAAHIGAABvBgAAcQYAAG8GAABuBgAAcwYAAHQGAABvBgAAcwYAAG8GAAByBgAAZQYAAGcGAABtBgAAZQYAAG0GAAB1BgAAZwYAAGkGAABuBgAAZwYAAG4GAABtBgAAdQYAAG0GAABwBgAAdQYAAHAGAAB2BgAAWAYAAHcGAABxBgAAWAYAAHEGAAB4BgAAdwYAAHkGAAByBgAAdwYAAHIGAABxBgAAeAYAAHEGAABuBgAAeAYAAG4GAABpBgAAegYAAHsGAABzBgAAegYAAHMGAAB8BgAAewYAAH0GAAB0BgAAewYAAHQGAABzBgAAfAYAAHMGAAByBgAAfAYAAHIGAAB5BgAAfgYAAH8GAACABgAAfgYAAIAGAACBBgAAggYAAIMGAACABgAAggYAAIAGAAB/BgAAhAYAAIUGAACABgAAhAYAAIAGAACDBgAAhgYAAIcGAAB+BgAAhgYAAH4GAACIBgAAhwYAAIkGAAB/BgAAhwYAAH8GAAB+BgAAiAYAAH4GAACBBgAAiAYAAIEGAACKBgAAZQYAAHUGAACCBgAAZQYAAIIGAACLBgAAdQYAAH0GAACDBgAAdQYAAIMGAACCBgAAiwYAAIIGAAB/BgAAiwYAAH8GAACJBgAAegYAAIwGAACEBgAAegYAAIQGAACNBgAAjAYAAIoGAACFBgAAjAYAAIUGAACEBgAAjQYAAIQGAACDBgAAjQYAAIMGAAB2BgAAjgYAAI8GAACQBgAAjgYAAJAGAACRBgAAkgYAAJMGAACQBgAAkgYAAJAGAACUBgAAlQYAAJYGAACQBgAAlQYAAJAGAACXBgAAhgYAAJgGAACOBgAAhgYAAI4GAACZBgAAmAYAAJoGAACPBgAAmAYAAI8GAACOBgAAmQYAAI4GAACRBgAAmQYAAJEGAACbBgAAegYAAJwGAACSBgAAegYAAJIGAACdBgAAnAYAAJ4GAACTBgAAnAYAAJMGAACSBgAAnQYAAJIGAACUBgAAnQYAAJQGAACaBgAAnwYAAKAGAACVBgAAnwYAAJUGAAChBgAAoAYAAKIGAACWBgAAoAYAAJYGAACVBgAAoQYAAJUGAACXBgAAoQYAAJcGAACjBgAApAYAAKUGAACmBgAApAYAAKYGAACnBgAAqAYAAKkGAACmBgAAqAYAAKYGAACqBgAAqwYAAKcGAACmBgAAqwYAAKYGAACsBgAArQYAAK4GAACkBgAArQYAAKQGAACvBgAArgYAALAGAAClBgAArgYAAKUGAACkBgAArwYAAKQGAACnBgAArwYAAKcGAACxBgAAhgYAAJkGAACoBgAAhgYAAKgGAACyBgAAmQYAAJsGAACpBgAAmQYAAKkGAACoBgAAsgYAAKgGAACqBgAAsgYAAKoGAACzBgAAnwYAALQGAACrBgAAnwYAAKsGAAC1BgAAtAYAALYGAACnBgAAtAYAAKcGAACrBgAAtQYAAKsGAACsBgAAtQYAAKwGAAC3BgAAuAYAALkGAAC6BgAAuAYAALoGAAC7BgAAvAYAAL0GAAC6BgAAvAYAALoGAAC+BgAAvwYAALsGAAC6BgAAvwYAALoGAAC9BgAArQYAAK8GAAC4BgAArQYAALgGAADABgAArwYAALEGAAC5BgAArwYAALkGAAC4BgAAwAYAALgGAAC7BgAAwAYAALsGAADBBgAAnwYAAMIGAAC8BgAAnwYAALwGAAC0BgAAwgYAAMMGAAC9BgAAwgYAAL0GAAC8BgAAtAYAALwGAAC+BgAAtAYAAL4GAACxBgAAxAYAAMUGAAC/BgAAxAYAAL8GAADGBgAAxQYAAMEGAAC7BgAAxQYAALsGAAC/BgAAxgYAAL8GAAC9BgAAxgYAAL0GAADHBgAAyAYAAMkGAADKBgAAyAYAAMoGAADLBgAAzAYAAM0GAADKBgAAzAYAAMoGAADOBgAAzwYAANAGAADKBgAAzwYAAMoGAADRBgAA0gYAANMGAADIBgAA0gYAAMgGAADUBgAA0wYAANUGAADJBgAA0wYAAMkGAADIBgAA1AYAAMgGAADLBgAA1AYAAMsGAADWBgAArQYAAMAGAADMBgAArQYAAMwGAADXBgAAwAYAAMEGAADNBgAAwAYAAM0GAADMBgAA1wYAAMwGAADOBgAA1wYAAM4GAADVBgAAxAYAANgGAADPBgAAxAYAAM8GAADZBgAA2AYAANoGAADQBgAA2AYAANAGAADPBgAA2QYAAM8GAADRBgAA2QYAANEGAADBBgAA2wYAANwGAADdBgAA2wYAAN0GAADeBgAA3wYAAOAGAADdBgAA3wYAAN0GAADhBgAA4gYAAOMGAADdBgAA4gYAAN0GAADgBgAA0gYAAOQGAADbBgAA0gYAANsGAADlBgAA5AYAANoGAADcBgAA5AYAANwGAADbBgAA5QYAANsGAADeBgAA5QYAAN4GAADmBgAAxAYAAOcGAADfBgAAxAYAAN8GAADoBgAA5wYAAOkGAADgBgAA5wYAAOAGAADfBgAA6AYAAN8GAADhBgAA6AYAAOEGAADWBgAA6gYAAOsGAADiBgAA6gYAAOIGAADsBgAA6wYAAO0GAADjBgAA6wYAAOMGAADiBgAA7AYAAOIGAADgBgAA7AYAAOAGAADpBgAA7gYAAO8GAADwBgAA7gYAAPAGAADxBgAA8gYAAPMGAADwBgAA8gYAAPAGAAD0BgAA9QYAAPEGAADwBgAA9QYAAPAGAAD2BgAA9wYAAPgGAADuBgAA9wYAAO4GAAD5BgAA+AYAAPoGAADvBgAA+AYAAO8GAADuBgAA+QYAAO4GAADxBgAA+QYAAPEGAAD7BgAA0gYAAOUGAADyBgAA0gYAAPIGAAD8BgAA5QYAAO0GAADzBgAA5QYAAPMGAADyBgAA/AYAAPIGAAD0BgAA/AYAAPQGAAD6BgAA6gYAAP0GAAD1BgAA6gYAAPUGAAD+BgAA/QYAAP8GAADxBgAA/QYAAPEGAAD1BgAA/gYAAPUGAAD2BgAA/gYAAPYGAADtBgAAAAcAAAEHAAACBwAAAAcAAAIHAAADBwAABAcAAAUHAAACBwAABAcAAAIHAAAGBwAABwcAAAMHAAACBwAABwcAAAIHAAAFBwAA9wYAAPkGAAAABwAA9wYAAAAHAAAIBwAA+QYAAPsGAAABBwAA+QYAAAEHAAAABwAACAcAAAAHAAADBwAACAcAAAMHAAAJBwAA6gYAAAoHAAAEBwAA6gYAAAQHAAD9BgAACgcAAAsHAAAFBwAACgcAAAUHAAAEBwAA/QYAAAQHAAAGBwAA/QYAAAYHAAD/BgAADAcAAA0HAAAHBwAADAcAAAcHAAAOBwAADQcAAAkHAAADBwAADQcAAAMHAAAHBwAADgcAAAcHAAAFBwAADgcAAAUHAAALBwAADwcAABAHAAARBwAADwcAABEHAAASBwAAEwcAABQHAAARBwAAEwcAABEHAAAQBwAAFQcAABYHAAARBwAAFQcAABEHAAAXBwAAGAcAABkHAAAPBwAAGAcAAA8HAAAaBwAAGQcAABsHAAAQBwAAGQcAABAHAAAPBwAAGgcAAA8HAAASBwAAGgcAABIHAAAcBwAA9wYAAAgHAAATBwAA9wYAABMHAAAdBwAACAcAAB4HAAAUBwAACAcAABQHAAATBwAAHQcAABMHAAAQBwAAHQcAABAHAAAbBwAADAcAAB8HAAAVBwAADAcAABUHAAANBwAAHwcAABwHAAAWBwAAHwcAABYHAAAVBwAADQcAABUHAAAXBwAADQcAABcHAAAeBwAAIAcAACEHAAAiBwAAIAcAACIHAAAjBwAAJAcAACUHAAAiBwAAJAcAACIHAAAhBwAAJgcAACcHAAAiBwAAJgcAACIHAAAoBwAAGAcAACkHAAAgBwAAGAcAACAHAAAqBwAAKQcAACsHAAAhBwAAKQcAACEHAAAgBwAAKgcAACAHAAAjBwAAKgcAACMHAAAsBwAADAcAAC0HAAAkBwAADAcAACQHAAAfBwAALQcAAC4HAAAlBwAALQcAACUHAAAkBwAAHwcAACQHAAAhBwAAHwcAACEHAAAcBwAALwcAADAHAAAmBwAALwcAACYHAAAxBwAAMAcAACwHAAAnBwAAMAcAACcHAAAmBwAAMQcAACYHAAAoBwAAMQcAACgHAAAyBwAAMwcAADQHAAA1BwAAMwcAADUHAAA2BwAANwcAADgHAAA1BwAANwcAADUHAAA0BwAAOQcAADYHAAA1BwAAOQcAADUHAAA6BwAAOwcAADwHAAAzBwAAOwcAADMHAAA9BwAAPAcAAD4HAAA0BwAAPAcAADQHAAAzBwAAPQcAADMHAAA2BwAAPQcAADYHAAA/BwAAGAcAACoHAAA3BwAAGAcAADcHAABABwAAKgcAAEEHAAA4BwAAKgcAADgHAAA3BwAAQAcAADcHAAA0BwAAQAcAADQHAAA+BwAALwcAAEIHAAA5BwAALwcAADkHAABDBwAAQgcAAEQHAAA2BwAAQgcAADYHAAA5BwAAQwcAADkHAAA6BwAAQwcAADoHAABBBwAARQcAAEYHAABHBwAARQcAAEcHAABIBwAASQcAAEoHAABHBwAASQcAAEcHAABLBwAATAcAAEgHAABHBwAATAcAAEcHAABNBwAAOwcAAE4HAABFBwAAOwcAAEUHAABPBwAATgcAAD8HAABGBwAATgcAAEYHAABFBwAATwcAAEUHAABIBwAATwcAAEgHAABQBwAALwcAAFEHAABJBwAALwcAAEkHAABSBwAAUQcAAFMHAABKBwAAUQcAAEoHAABJBwAAUgcAAEkHAABLBwAAUgcAAEsHAABUBwAAVQcAAFYHAABMBwAAVQcAAEwHAABXBwAAVgcAAFgHAABIBwAAVgcAAEgHAABMBwAAVwcAAEwHAABNBwAAVwcAAE0HAABZBwAAWgcAAFsHAABcBwAAWgcAAFwHAABdBwAAXgcAAF8HAABcBwAAXgcAAFwHAABgBwAAYQcAAF0HAABcBwAAYQcAAFwHAABfBwAAYgcAAGMHAABaBwAAYgcAAFoHAABkBwAAYwcAAGUHAABbBwAAYwcAAFsHAABaBwAAZAcAAFoHAABdBwAAZAcAAF0HAABmBwAAOwcAAGcHAABeBwAAOwcAAF4HAABoBwAAZwcAAFAHAABfBwAAZwcAAF8HAABeBwAAaAcAAF4HAABgBwAAaAcAAGAHAABlBwAAVQcAAGkHAABhBwAAVQcAAGEHAABqBwAAaQcAAGsHAABdBwAAaQcAAF0HAABhBwAAagcAAGEHAABfBwAAagcAAF8HAABsBwAAbQcAAG4HAABvBwAAbQcAAG8HAABwBwAAcQcAAHIHAABvBwAAcQcAAG8HAABzBwAAdAcAAHUHAABvBwAAdAcAAG8HAAB2BwAAYgcAAGQHAABtBwAAYgcAAG0HAAB3BwAAZAcAAGsHAABuBwAAZAcAAG4HAABtBwAAdwcAAG0HAABwBwAAdwcAAHAHAAB4BwAAVQcAAHkHAABxBwAAVQcAAHEHAAB6BwAAeQcAAHsHAAByBwAAeQcAAHIHAABxBwAAegcAAHEHAABzBwAAegcAAHMHAABrBwAAfAcAAH0HAAB0BwAAfAcAAHQHAAB+BwAAfQcAAH8HAAB1BwAAfQcAAHUHAAB0BwAAfgcAAHQHAAB2BwAAfgcAAHYHAACABwAAgQcAAIIHAACDBwAAgQcAAIMHAACEBwAAhQcAAIYHAACDBwAAhQcAAIMHAACHBwAAiAcAAIkHAACDBwAAiAcAAIMHAACKBwAAiwcAAIwHAACBBwAAiwcAAIEHAACNBwAAjAcAAI4HAACCBwAAjAcAAIIHAACBBwAAjQcAAIEHAACEBwAAjQcAAIQHAACPBwAAYgcAAHcHAACFBwAAYgcAAIUHAACQBwAAdwcAAJEHAACGBwAAdwcAAIYHAACFBwAAkAcAAIUHAACHBwAAkAcAAIcHAACOBwAAfAcAAJIHAACIBwAAfAcAAIgHAACTBwAAkgcAAI8HAACJBwAAkgcAAIkHAACIBwAAkwcAAIgHAACKBwAAkwcAAIoHAACUBwAAlQcAAJYHAACXBwAAlQcAAJcHAACYBwAAmQcAAJoHAACXBwAAmQcAAJcHAACWBwAAmwcAAJwHAACXBwAAmwcAAJcHAACdBwAAiwcAAI0HAACVBwAAiwcAAJUHAACeBwAAjQcAAJ8HAACWBwAAjQcAAJYHAACVBwAAngcAAJUHAACYBwAAngcAAJgHAACgBwAAfAcAAKEHAACZBwAAfAcAAJkHAACSBwAAoQcAAKIHAACaBwAAoQcAAJoHAACZBwAAkgcAAJkHAACWBwAAkgcAAJYHAACfBwAAowcAAKQHAACbBwAAowcAAJsHAAClBwAApAcAAKAHAACcBwAApAcAAJwHAACbBwAApQcAAJsHAACdBwAApQcAAJ0HAACiBwAApgcAAKcHAACoBwAApgcAAKgHAACpBwAAqgcAAKsHAACoBwAAqgcAAKgHAACsBwAArQcAAK4HAACoBwAArQcAAKgHAACrBwAArwcAALAHAACmBwAArwcAAKYHAACxBwAAsAcAALIHAACnBwAAsAcAAKcHAACmBwAAsQcAAKYHAACpBwAAsQcAAKkHAACzBwAAiwcAALQHAACqBwAAiwcAAKoHAAC1BwAAtAcAALYHAACrBwAAtAcAAKsHAACqBwAAtQcAAKoHAACsBwAAtQcAAKwHAACyBwAAowcAALcHAACtBwAAowcAAK0HAACkBwAAtwcAALgHAACuBwAAtwcAAK4HAACtBwAApAcAAK0HAACrBwAApAcAAKsHAAC2BwAAuQcAALoHAAC7BwAAuQcAALsHAAC8BwAAvQcAAL4HAAC7BwAAvQcAALsHAAC6BwAAvwcAALwHAAC7BwAAvwcAALsHAAC+BwAArwcAALEHAAC5BwAArwcAALkHAADABwAAsQcAALMHAAC6BwAAsQcAALoHAAC5BwAAwAcAALkHAAC8BwAAwAcAALwHAADBBwAAowcAAMIHAAC9BwAAowcAAL0HAADDBwAAwgcAAMQHAAC+BwAAwgcAAL4HAAC9BwAAwwcAAL0HAAC6BwAAwwcAALoHAADFBwAAxgcAAMcHAAC/BwAAxgcAAL8HAADIBwAAxwcAAMkHAAC8BwAAxwcAALwHAAC/BwAAyAcAAL8HAAC+BwAAyAcAAL4HAADEBwAAygcAAMsHAADMBwAAygcAAMwHAADNBwAAzgcAAM8HAADMBwAAzgcAAMwHAADLBwAA0AcAAM0HAADMBwAA0AcAAMwHAADRBwAA0gcAANMHAADKBwAA0gcAAMoHAADUBwAA0wcAANUHAADLBwAA0wcAAMsHAADKBwAA1AcAAMoHAADNBwAA1AcAAM0HAADWBwAArwcAANcHAADOBwAArwcAAM4HAADYBwAA1wcAAMEHAADPBwAA1wcAAM8HAADOBwAA2AcAAM4HAADLBwAA2AcAAMsHAADVBwAAxgcAANkHAADQBwAAxgcAANAHAADHBwAA2QcAANYHAADNBwAA2QcAAM0HAADQBwAAxwcAANAHAADRBwAAxwcAANEHAADJBwAA2gcAANsHAADcBwAA2gcAANwHAADdBwAA3gcAAN8HAADcBwAA3gcAANwHAADbBwAA4AcAAOEHAADcBwAA4AcAANwHAADiBwAA0gcAAOMHAADaBwAA0gcAANoHAADkBwAA4wcAAOUHAADbBwAA4wcAANsHAADaBwAA5AcAANoHAADdBwAA5AcAAN0HAADmBwAAxgcAAOcHAADeBwAAxgcAAN4HAADZBwAA5wcAAOgHAADfBwAA5wcAAN8HAADeBwAA2QcAAN4HAADbBwAA2QcAANsHAADlBwAA6QcAAOoHAADgBwAA6QcAAOAHAADrBwAA6gcAAOwHAADhBwAA6gcAAOEHAADgBwAA6wcAAOAHAADiBwAA6wcAAOIHAADoBwAA7QcAAO4HAADvBwAA7QcAAO8HAADwBwAA8QcAAPIHAADvBwAA8QcAAO8HAADuBwAA8wcAAPAHAADvBwAA8wcAAO8HAADyBwAA9AcAAPUHAADtBwAA9AcAAO0HAAD2BwAA9QcAAPcHAADuBwAA9QcAAO4HAADtBwAA9gcAAO0HAADwBwAA9gcAAPAHAAD4BwAA0gcAAOQHAADxBwAA0gcAAPEHAAD5BwAA5AcAAOwHAADyBwAA5AcAAPIHAADxBwAA+QcAAPEHAADuBwAA+QcAAO4HAAD6BwAA6QcAAPsHAADzBwAA6QcAAPMHAADqBwAA+wcAAPwHAADwBwAA+wcAAPAHAADzBwAA6gcAAPMHAADyBwAA6gcAAPIHAADsBwAA/QcAAP4HAAD/BwAA/QcAAP8HAAAACAAAAQgAAAIIAAD/BwAAAQgAAP8HAAADCAAABAgAAAAIAAD/BwAABAgAAP8HAAAFCAAA9AcAAPYHAAD9BwAA9AcAAP0HAAAGCAAA9gcAAPwHAAD+BwAA9gcAAP4HAAD9BwAABggAAP0HAAAACAAABggAAAAIAAAHCAAA6QcAAAgIAAABCAAA6QcAAAEIAAAJCAAACAgAAAoIAAACCAAACAgAAAIIAAABCAAACQgAAAEIAAADCAAACQgAAAMIAAD8BwAACwgAAAwIAAAECAAACwgAAAQIAAANCAAADAgAAA4IAAAACAAADAgAAAAIAAAECAAADQgAAAQIAAAFCAAADQgAAAUIAAAKCAAADwgAABAIAAARCAAADwgAABEIAAASCAAAEwgAABQIAAARCAAAEwgAABEIAAAVCAAAFggAABIIAAARCAAAFggAABEIAAAUCAAAFwgAABgIAAAPCAAAFwgAAA8IAAAZCAAAGAgAABoIAAAQCAAAGAgAABAIAAAPCAAAGQgAAA8IAAASCAAAGQgAABIIAAAbCAAA9AcAABwIAAATCAAA9AcAABMIAAAdCAAAHAgAAA4IAAAUCAAAHAgAABQIAAATCAAAHQgAABMIAAAVCAAAHQgAABUIAAAeCAAACwgAAB8IAAAWCAAACwgAABYIAAAMCAAAHwgAACAIAAASCAAAHwgAABIIAAAWCAAADAgAABYIAAAUCAAADAgAABQIAAAHCAAAIQgAACIIAAAjCAAAIQgAACMIAAAkCAAAJQgAACYIAAAjCAAAJQgAACMIAAAiCAAAJwgAACQIAAAjCAAAJwgAACMIAAAoCAAAFwgAABkIAAAhCAAAFwgAACEIAAApCAAAGQgAACAIAAAiCAAAGQgAACIIAAAhCAAAKQgAACEIAAAkCAAAKQgAACQIAAAqCAAACwgAACsIAAAlCAAACwgAACUIAAAsCAAAKwgAAC0IAAAmCAAAKwgAACYIAAAlCAAALAgAACUIAAAiCAAALAgAACIIAAAbCAAALggAAC8IAAAnCAAALggAACcIAAAwCAAALwgAADEIAAAkCAAALwgAACQIAAAnCAAAMAgAACcIAAAoCAAAMAgAACgIAAAtCAAAMggAADMIAAA0CAAAMggAADQIAAA1CAAANggAADcIAAA0CAAANggAADQIAAAzCAAAOAgAADUIAAA0CAAAOAgAADQIAAA5CAAAOggAADsIAAAyCAAAOggAADIIAAA8CAAAOwgAAD0IAAAzCAAAOwgAADMIAAAyCAAAPAgAADIIAAA1CAAAPAgAADUIAAA+CAAAFwgAAD8IAAA2CAAAFwgAADYIAABACAAAPwgAACoIAAA3CAAAPwgAADcIAAA2CAAAQAgAADYIAAAzCAAAQAgAADMIAABBCAAALggAAEIIAAA4CAAALggAADgIAAAvCAAAQggAAD4IAAA1CAAAQggAADUIAAA4CAAALwgAADgIAAA5CAAALwgAADkIAAAqCAAAQwgAAEQIAABFCAAAQwgAAEUIAABGCAAARwgAAEgIAABFCAAARwgAAEUIAABECAAASQgAAEYIAABFCAAASQgAAEUIAABICAAAOggAADwIAABDCAAAOggAAEMIAABKCAAAPAgAAEsIAABECAAAPAgAAEQIAABDCAAASggAAEMIAABGCAAASggAAEYIAABMCAAALggAAE0IAABHCAAALggAAEcIAABCCAAATQgAAE4IAABICAAATQgAAEgIAABHCAAAQggAAEcIAABECAAAQggAAEQIAABLCAAATwgAAFAIAABJCAAATwgAAEkIAABRCAAAUAgAAEwIAABGCAAAUAgAAEYIAABJCAAAUQgAAEkIAABICAAAUQgAAEgIAABOCAAAUggAAFMIAABUCAAAUggAAFQIAABVCAAAVggAAFcIAABUCAAAVggAAFQIAABYCAAAWQgAAFUIAABUCAAAWQgAAFQIAABaCAAAWwgAAFwIAABSCAAAWwgAAFIIAABdCAAAXAgAAF4IAABTCAAAXAgAAFMIAABSCAAAXQgAAFIIAABVCAAAXQgAAFUIAABfCAAAOggAAEoIAABWCAAAOggAAFYIAABgCAAASggAAEwIAABXCAAASggAAFcIAABWCAAAYAgAAFYIAABYCAAAYAgAAFgIAABeCAAATwgAAGEIAABZCAAATwgAAFkIAABQCAAAYQgAAGIIAABVCAAAYQgAAFUIAABZCAAAUAgAAFkIAABaCAAAUAgAAFoIAABMCAAAYwgAAGQIAABlCAAAYwgAAGUIAABmCAAAZwgAAGgIAABlCAAAZwgAAGUIAABpCAAAaggAAGsIAABlCAAAaggAAGUIAABsCAAAWwgAAF0IAABjCAAAWwgAAGMIAABtCAAAXQgAAGIIAABkCAAAXQgAAGQIAABjCAAAbQgAAGMIAABmCAAAbQgAAGYIAABuCAAATwgAAG8IAABnCAAATwgAAGcIAABhCAAAbwgAAHAIAABoCAAAbwgAAGgIAABnCAAAYQgAAGcIAABpCAAAYQgAAGkIAABfCAAAcQgAAHIIAABqCAAAcQgAAGoIAABzCAAAcggAAG4IAABrCAAAcggAAGsIAABqCAAAcwgAAGoIAABsCAAAcwgAAGwIAAB0CAAAdQgAAHYIAAB3CAAAdQgAAHcIAAB4CAAAeQgAAHoIAAB3CAAAeQgAAHcIAAB7CAAAfAgAAHgIAAB3CAAAfAgAAHcIAAB9CAAAfggAAH8IAAB1CAAAfggAAHUIAACACAAAfwgAAIEIAAB2CAAAfwgAAHYIAAB1CAAAgAgAAHUIAAB4CAAAgAgAAHgIAACCCAAAWwgAAG0IAAB5CAAAWwgAAHkIAACDCAAAbQgAAG4IAAB6CAAAbQgAAHoIAAB5CAAAgwgAAHkIAAB7CAAAgwgAAHsIAACBCAAAcQgAAIQIAAB8CAAAcQgAAHwIAAByCAAAhAgAAIUIAAB4CAAAhAgAAHgIAAB8CAAAcggAAHwIAAB9CAAAcggAAH0IAACGCAAAhwgAAIgIAACJCAAAhwgAAIkIAACKCAAAiwgAAIwIAACJCAAAiwgAAIkIAACNCAAAjggAAI8IAACJCAAAjggAAIkIAACMCAAAfggAAJAIAACHCAAAfggAAIcIAACRCAAAkAgAAIIIAACICAAAkAgAAIgIAACHCAAAkQgAAIcIAACKCAAAkQgAAIoIAACSCAAAcQgAAJMIAACLCAAAcQgAAIsIAACUCAAAkwgAAJUIAACMCAAAkwgAAIwIAACLCAAAlAgAAIsIAACNCAAAlAgAAI0IAACCCAAAlggAAJcIAACOCAAAlggAAI4IAACYCAAAlwgAAJkIAACPCAAAlwgAAI8IAACOCAAAmAgAAI4IAACMCAAAmAgAAIwIAACVCAAAmggAAJsIAACcCAAAmggAAJwIAACdCAAAnggAAJ8IAACcCAAAnggAAJwIAACbCAAAoAgAAJ0IAACcCAAAoAgAAJwIAAChCAAAoggAAKMIAACaCAAAoggAAJoIAACkCAAAowgAAKUIAACbCAAAowgAAJsIAACaCAAApAgAAJoIAACdCAAApAgAAJ0IAACmCAAAfggAAJEIAACeCAAAfggAAJ4IAACnCAAAkQgAAJIIAACfCAAAkQgAAJ8IAACeCAAApwgAAJ4IAACbCAAApwgAAJsIAACoCAAAlggAAKkIAACgCAAAlggAAKAIAACqCAAAqQgAAKYIAACdCAAAqQgAAJ0IAACgCAAAqggAAKAIAAChCAAAqggAAKEIAACZCAAAqwgAAKwIAACtCAAAqwgAAK0IAACuCAAArwgAALAIAACtCAAArwgAAK0IAACxCAAAsggAALMIAACtCAAAsggAAK0IAAC0CAAAoggAALUIAACrCAAAoggAAKsIAAC2CAAAtQgAAKYIAACsCAAAtQgAAKwIAACrCAAAtggAAKsIAACuCAAAtggAAK4IAAC3CAAAlggAALgIAACvCAAAlggAAK8IAACpCAAAuAgAALkIAACwCAAAuAgAALAIAACvCAAAqQgAAK8IAACxCAAAqQgAALEIAACmCAAAuggAALsIAACyCAAAuggAALIIAAC8CAAAuwgAALcIAACzCAAAuwgAALMIAACyCAAAvAgAALIIAAC0CAAAvAgAALQIAAC9CAAAvggAAL8IAADACAAAvggAAMAIAADBCAAAwggAAMMIAADACAAAwggAAMAIAADECAAAxQgAAMYIAADACAAAxQgAAMAIAADHCAAAyAgAAMkIAAC+CAAAyAgAAL4IAADKCAAAyQgAAMsIAAC/CAAAyQgAAL8IAAC+CAAAyggAAL4IAADBCAAAyggAAMEIAADMCAAAoggAAM0IAADCCAAAoggAAMIIAADOCAAAzQgAALcIAADDCAAAzQgAAMMIAADCCAAAzggAAMIIAADECAAAzggAAMQIAADPCAAAuggAANAIAADFCAAAuggAAMUIAAC7CAAA0AgAANEIAADGCAAA0AgAAMYIAADFCAAAuwgAAMUIAADHCAAAuwgAAMcIAADSCAAA0wgAANQIAADVCAAA0wgAANUIAADWCAAA1wgAANgIAADVCAAA1wgAANUIAADZCAAA2ggAANYIAADVCAAA2ggAANUIAADYCAAAyAgAANsIAADTCAAAyAgAANMIAADcCAAA2wgAAMwIAADUCAAA2wgAANQIAADTCAAA3AgAANMIAADWCAAA3AgAANYIAADdCAAAuggAAN4IAADXCAAAuggAANcIAADfCAAA3ggAAOAIAADYCAAA3ggAANgIAADXCAAA3wgAANcIAADZCAAA3wgAANkIAADRCAAA4QgAAOIIAADaCAAA4QgAANoIAADjCAAA4ggAAN0IAADWCAAA4ggAANYIAADaCAAA4wgAANoIAADYCAAA4wgAANgIAADkCAAA5QgAAOYIAADnCAAA5QgAAOcIAADoCAAA6QgAAOoIAADnCAAA6QgAAOcIAADmCAAA6wgAAOwIAADnCAAA6wgAAOcIAADqCAAA7QgAAO4IAADlCAAA7QgAAOUIAADvCAAA7ggAAPAIAADmCAAA7ggAAOYIAADlCAAA7wgAAOUIAADoCAAA7wgAAOgIAADxCAAAyAgAAPIIAADpCAAAyAgAAOkIAADzCAAA8ggAAPQIAADqCAAA8ggAAOoIAADpCAAA8wgAAOkIAADmCAAA8wgAAOYIAADwCAAA4QgAAPUIAADrCAAA4QgAAOsIAAD2CAAA9QgAAPcIAADsCAAA9QgAAOwIAADrCAAA9ggAAOsIAADqCAAA9ggAAOoIAAD0CAAA+AgAAPkIAAD6CAAA+AgAAPoIAAD7CAAA/AgAAP0IAAD6CAAA/AgAAPoIAAD+CAAA/wgAAAAJAAD6CAAA/wgAAPoIAAD9CAAA7QgAAAEJAAD4CAAA7QgAAPgIAAACCQAAAQkAAPcIAAD5CAAAAQkAAPkIAAD4CAAAAgkAAPgIAAD7CAAAAgkAAPsIAAADCQAA4QgAAAQJAAD8CAAA4QgAAPwIAAAFCQAABAkAAAYJAAD9CAAABAkAAP0IAAD8CAAABQkAAPwIAAD+CAAABQkAAP4IAAD3CAAABwkAAAgJAAD/CAAABwkAAP8IAAAJCQAACAkAAAMJAAAACQAACAkAAAAJAAD/CAAACQkAAP8IAAD9CAAACQkAAP0IAAAGCQAACgkAAAsJAAAMCQAACgkAAAwJAAANCQAADgkAAA8JAAAMCQAADgkAAAwJAAALCQAAEAkAAA0JAAAMCQAAEAkAAAwJAAARCQAAEgkAABMJAAAKCQAAEgkAAAoJAAAUCQAAEwkAABUJAAALCQAAEwkAAAsJAAAKCQAAFAkAAAoJAAANCQAAFAkAAA0JAAAWCQAA7QgAABcJAAAOCQAA7QgAAA4JAAAYCQAAFwkAABkJAAAPCQAAFwkAAA8JAAAOCQAAGAkAAA4JAAALCQAAGAkAAAsJAAAVCQAABwkAABoJAAAQCQAABwkAABAJAAAbCQAAGgkAABYJAAANCQAAGgkAAA0JAAAQCQAAGwkAABAJAAARCQAAGwkAABEJAAAcCQAAHQkAAB4JAAAfCQAAHQkAAB8JAAAgCQAAIQkAACIJAAAfCQAAIQkAAB8JAAAeCQAAIwkAACQJAAAfCQAAIwkAAB8JAAAiCQAAEgkAABQJAAAdCQAAEgkAAB0JAAAlCQAAFAkAACYJAAAeCQAAFAkAAB4JAAAdCQAAJQkAAB0JAAAgCQAAJQkAACAJAAAnCQAABwkAACgJAAAhCQAABwkAACEJAAApCQAAKAkAACoJAAAiCQAAKAkAACIJAAAhCQAAKQkAACEJAAAeCQAAKQkAAB4JAAArCQAALAkAAC0JAAAjCQAALAkAACMJAAAuCQAALQkAAC8JAAAkCQAALQkAACQJAAAjCQAALgkAACMJAAAiCQAALgkAACIJAAAwCQAAMQkAADIJAAAzCQAAMQkAADMJAAA0CQAANQkAADYJAAAzCQAANQkAADMJAAA3CQAAOAkAADkJAAAzCQAAOAkAADMJAAA2CQAAOgkAADsJAAAxCQAAOgkAADEJAAA8CQAAOwkAAD0JAAAyCQAAOwkAADIJAAAxCQAAPAkAADEJAAA0CQAAPAkAADQJAAA+CQAAEgkAACUJAAA1CQAAEgkAADUJAAA/CQAAJQkAACcJAAA2CQAAJQkAADYJAAA1CQAAPwkAADUJAAA3CQAAPwkAADcJAAA9CQAALAkAAEAJAAA4CQAALAkAADgJAAAtCQAAQAkAAEEJAAA5CQAAQAkAADkJAAA4CQAALQkAADgJAAA2CQAALQkAADYJAABCCQAAQwkAAEQJAABFCQAAQwkAAEUJAABGCQAARwkAAEgJAABFCQAARwkAAEUJAABJCQAASgkAAEsJAABFCQAASgkAAEUJAABMCQAAOgkAADwJAABDCQAAOgkAAEMJAABNCQAAPAkAAD4JAABECQAAPAkAAEQJAABDCQAATQkAAEMJAABGCQAATQkAAEYJAABOCQAALAkAAE8JAABHCQAALAkAAEcJAABACQAATwkAAFAJAABICQAATwkAAEgJAABHCQAAQAkAAEcJAABJCQAAQAkAAEkJAAA+CQAAUQkAAFIJAABKCQAAUQkAAEoJAABTCQAAUgkAAFQJAABLCQAAUgkAAEsJAABKCQAAUwkAAEoJAABMCQAAUwkAAEwJAABQCQAAVQkAAFYJAABXCQAAVQkAAFcJAABYCQAAWQkAAFoJAABXCQAAWQkAAFcJAABWCQAAWwkAAFwJAABXCQAAWwkAAFcJAABdCQAAXgkAAF8JAABVCQAAXgkAAFUJAABgCQAAXwkAAGEJAABWCQAAXwkAAFYJAABVCQAAYAkAAFUJAABYCQAAYAkAAFgJAABiCQAAOgkAAE0JAABZCQAAOgkAAFkJAABjCQAATQkAAE4JAABaCQAATQkAAFoJAABZCQAAYwkAAFkJAABWCQAAYwkAAFYJAABkCQAAUQkAAGUJAABbCQAAUQkAAFsJAABmCQAAZQkAAGcJAABcCQAAZQkAAFwJAABbCQAAZgkAAFsJAABdCQAAZgkAAF0JAABOCQAAaAkAAGkJAABqCQAAaAkAAGoJAABrCQAAbAkAAG0JAABqCQAAbAkAAGoJAABuCQAAbwkAAHAJAABqCQAAbwkAAGoJAABtCQAAXgkAAGAJAABoCQAAXgkAAGgJAABxCQAAYAkAAGIJAABpCQAAYAkAAGkJAABoCQAAcQkAAGgJAABrCQAAcQkAAGsJAAByCQAAUQkAAHMJAABsCQAAUQkAAGwJAABlCQAAcwkAAHQJAABtCQAAcwkAAG0JAABsCQAAZQkAAGwJAABuCQAAZQkAAG4JAABnCQAAdQkAAHYJAABvCQAAdQkAAG8JAAB3CQAAdgkAAHIJAABwCQAAdgkAAHAJAABvCQAAdwkAAG8JAABtCQAAdwkAAG0JAAB4CQAAeQkAAHoJAAB7CQAAeQkAAHsJAAB8CQAAfQkAAH4JAAB7CQAAfQkAAHsJAAB/CQAAgAkAAHwJAAB7CQAAgAkAAHsJAAB+CQAAgQkAAIIJAAB5CQAAgQkAAHkJAACDCQAAggkAAIQJAAB6CQAAggkAAHoJAAB5CQAAgwkAAHkJAAB8CQAAgwkAAHwJAACFCQAAXgkAAHEJAAB9CQAAXgkAAH0JAACGCQAAcQkAAHIJAAB+CQAAcQkAAH4JAAB9CQAAhgkAAH0JAAB/CQAAhgkAAH8JAACECQAAdQkAAIcJAACACQAAdQkAAIAJAAB2CQAAhwkAAIUJAAB8CQAAhwkAAHwJAACACQAAdgkAAIAJAAB+CQAAdgkAAH4JAAByCQAAiAkAAIkJAACKCQAAiAkAAIoJAACLCQAAjAkAAI0JAACKCQAAjAkAAIoJAACOCQAAjwkAAIsJAACKCQAAjwkAAIoJAACQCQAAgQkAAIMJAACICQAAgQkAAIgJAACRCQAAgwkAAJIJAACJCQAAgwkAAIkJAACICQAAkQkAAIgJAACLCQAAkQkAAIsJAACTCQAAdQkAAJQJAACMCQAAdQkAAIwJAACVCQAAlAkAAJYJAACNCQAAlAkAAI0JAACMCQAAlQkAAIwJAACOCQAAlQkAAI4JAACFCQAAlwkAAJgJAACPCQAAlwkAAI8JAACZCQAAmAkAAJoJAACLCQAAmAkAAIsJAACPCQAAmQkAAI8JAACQCQAAmQkAAJAJAACWCQAAmwkAAJwJAACdCQAAmwkAAJ0JAACeCQAAnwkAAKAJAACdCQAAnwkAAJ0JAACcCQAAoQkAAJ4JAACdCQAAoQkAAJ0JAACgCQAAogkAAKMJAACbCQAAogkAAJsJAACkCQAAowkAAKUJAACcCQAAowkAAJwJAACbCQAApAkAAJsJAACeCQAApAkAAJ4JAACmCQAAgQkAAKcJAACfCQAAgQkAAJ8JAACoCQAApwkAAKkJAACgCQAApwkAAKAJAACfCQAAqAkAAJ8JAACcCQAAqAkAAJwJAAClCQAAlwkAAKoJAAChCQAAlwkAAKEJAACrCQAAqgkAAKYJAACeCQAAqgkAAJ4JAAChCQAAqwkAAKEJAACgCQAAqwkAAKAJAACTCQAArAkAAK0JAACuCQAArAkAAK4JAACvCQAAsAkAALEJAACuCQAAsAkAAK4JAACyCQAAswkAAK8JAACuCQAAswkAAK4JAACxCQAAogkAALQJAACsCQAAogkAAKwJAAC1CQAAtAkAAKYJAACtCQAAtAkAAK0JAACsCQAAtQkAAKwJAACvCQAAtQkAAK8JAAC2CQAAlwkAALcJAACwCQAAlwkAALAJAACqCQAAtwkAALgJAACxCQAAtwkAALEJAACwCQAAqgkAALAJAACyCQAAqgkAALIJAACmCQAAuQkAALoJAACzCQAAuQkAALMJAAC7CQAAugkAALwJAACvCQAAugkAAK8JAACzCQAAuwkAALMJAACxCQAAuwkAALEJAAC9CQAAvgkAAL8JAADACQAAvgkAAMAJAADBCQAAwgkAAMMJAADACQAAwgkAAMAJAAC/CQAAxAkAAMUJAADACQAAxAkAAMAJAADGCQAAxwkAAMgJAAC+CQAAxwkAAL4JAADJCQAAyAkAAMoJAAC/CQAAyAkAAL8JAAC+CQAAyQkAAL4JAADBCQAAyQkAAMEJAADLCQAAogkAALUJAADCCQAAogkAAMIJAADMCQAAtQkAALYJAADDCQAAtQkAAMMJAADCCQAAzAkAAMIJAAC/CQAAzAkAAL8JAADKCQAAuQkAAM0JAADECQAAuQkAAMQJAADOCQAAzQkAAM8JAADFCQAAzQkAAMUJAADECQAAzgkAAMQJAADGCQAAzgkAAMYJAAC8CQAA0AkAANEJAADSCQAA0AkAANIJAADTCQAA1AkAANUJAADSCQAA1AkAANIJAADRCQAA1gkAANMJAADSCQAA1gkAANIJAADVCQAAxwkAAMkJAADQCQAAxwkAANAJAADXCQAAyQkAAMsJAADRCQAAyQkAANEJAADQCQAA1wkAANAJAADTCQAA1wkAANMJAADYCQAAuQkAANkJAADUCQAAuQkAANQJAADNCQAA2QkAANoJAADVCQAA2QkAANUJAADUCQAAzQkAANQJAADRCQAAzQkAANEJAADLCQAA2wkAANwJAADWCQAA2wkAANYJAADdCQAA3AkAANgJAADTCQAA3AkAANMJAADWCQAA3QkAANYJAADVCQAA3QkAANUJAADaCQAA3gkAAN8JAADgCQAA3gkAAOAJAADhCQAA4gkAAOMJAADgCQAA4gkAAOAJAADfCQAA5AkAAOEJAADgCQAA5AkAAOAJAADlCQAA5gkAAOcJAADeCQAA5gkAAN4JAADoCQAA5wkAAOkJAADfCQAA5wkAAN8JAADeCQAA6AkAAN4JAADhCQAA6AkAAOEJAADqCQAAxwkAANcJAADiCQAAxwkAAOIJAADrCQAA1wkAANgJAADjCQAA1wkAAOMJAADiCQAA6wkAAOIJAADfCQAA6wkAAN8JAADpCQAA2wkAAOwJAADkCQAA2wkAAOQJAADtCQAA7AkAAO4JAADhCQAA7AkAAOEJAADkCQAA7QkAAOQJAADlCQAA7QkAAOUJAADvCQAA8AkAAPEJAADyCQAA8AkAAPIJAADzCQAA9AkAAPUJAADyCQAA9AkAAPIJAAD2CQAA9wkAAPgJAADyCQAA9wkAAPIJAAD5CQAA5gkAAOgJAADwCQAA5gkAAPAJAAD6CQAA6AkAAO4JAADxCQAA6AkAAPEJAADwCQAA+gkAAPAJAADzCQAA+gkAAPMJAAD7CQAA2wkAAPwJAAD0CQAA2wkAAPQJAAD9CQAA/AkAAP4JAAD1CQAA/AkAAPUJAAD0CQAA/QkAAPQJAAD2CQAA/QkAAPYJAADuCQAA/wkAAAAKAAD3CQAA/wkAAPcJAAABCgAAAAoAAAIKAAD4CQAAAAoAAPgJAAD3CQAAAQoAAPcJAAD5CQAAAQoAAPkJAAD+CQAAAwoAAAQKAAAFCgAAAwoAAAUKAAAGCgAABwoAAAgKAAAFCgAABwoAAAUKAAAECgAACQoAAAoKAAAFCgAACQoAAAUKAAALCgAADAoAAA0KAAADCgAADAoAAAMKAAAOCgAADQoAAA8KAAAECgAADQoAAAQKAAADCgAADgoAAAMKAAAGCgAADgoAAAYKAAAQCgAA5gkAAPoJAAAHCgAA5gkAAAcKAAARCgAA+gkAABIKAAAICgAA+gkAAAgKAAAHCgAAEQoAAAcKAAAECgAAEQoAAAQKAAAPCgAA/wkAABMKAAAJCgAA/wkAAAkKAAAACgAAEwoAABQKAAAKCgAAEwoAAAoKAAAJCgAAAAoAAAkKAAALCgAAAAoAAAsKAAASCgAAFQoAABYKAAAXCgAAFQoAABcKAAAYCgAAGQoAABoKAAAXCgAAGQoAABcKAAAWCgAAGwoAABwKAAAXCgAAGwoAABcKAAAaCgAADAoAAA4KAAAVCgAADAoAABUKAAAdCgAADgoAABAKAAAWCgAADgoAABYKAAAVCgAAHQoAABUKAAAYCgAAHQoAABgKAAAeCgAA/wkAAB8KAAAZCgAA/wkAABkKAAAgCgAAHwoAACEKAAAaCgAAHwoAABoKAAAZCgAAIAoAABkKAAAWCgAAIAoAABYKAAAQCgAAIgoAACMKAAAbCgAAIgoAABsKAAAkCgAAIwoAACUKAAAcCgAAIwoAABwKAAAbCgAAJAoAABsKAAAaCgAAJAoAABoKAAAhCgAAJgoAACcKAAAoCgAAJgoAACgKAAApCgAAKgoAACsKAAAoCgAAKgoAACgKAAAnCgAALAoAAC0KAAAoCgAALAoAACgKAAArCgAALgoAAC8KAAAmCgAALgoAACYKAAAwCgAALwoAADEKAAAnCgAALwoAACcKAAAmCgAAMAoAACYKAAApCgAAMAoAACkKAAAyCgAADAoAADMKAAAqCgAADAoAACoKAAA0CgAAMwoAAB4KAAArCgAAMwoAACsKAAAqCgAANAoAACoKAAAnCgAANAoAACcKAAAxCgAAIgoAADUKAAAsCgAAIgoAACwKAAAjCgAANQoAADIKAAAtCgAANQoAAC0KAAAsCgAAIwoAACwKAAArCgAAIwoAACsKAAAlCgAANgoAADcKAAA4CgAANgoAADgKAAA5CgAAOgoAADsKAAA4CgAAOgoAADgKAAA8CgAAPQoAAD4KAAA4CgAAPQoAADgKAAA/CgAALgoAADAKAAA2CgAALgoAADYKAABACgAAMAoAADIKAAA3CgAAMAoAADcKAAA2CgAAQAoAADYKAAA5CgAAQAoAADkKAABBCgAAIgoAAEIKAAA6CgAAIgoAADoKAABDCgAAQgoAAEQKAAA7CgAAQgoAADsKAAA6CgAAQwoAADoKAAA8CgAAQwoAADwKAAAyCgAARQoAAEYKAAA9CgAARQoAAD0KAABHCgAARgoAAEgKAAA+CgAARgoAAD4KAAA9CgAARwoAAD0KAAA/CgAARwoAAD8KAABJCgAASgoAAEsKAABMCgAASgoAAEwKAABNCgAATgoAAE8KAABMCgAATgoAAEwKAABQCgAAUQoAAFIKAABMCgAAUQoAAEwKAABTCgAAVAoAAFUKAABKCgAAVAoAAEoKAABWCgAAVQoAAFcKAABLCgAAVQoAAEsKAABKCgAAVgoAAEoKAABNCgAAVgoAAE0KAABYCgAALgoAAFkKAABOCgAALgoAAE4KAABaCgAAWQoAAEgKAABPCgAAWQoAAE8KAABOCgAAWgoAAE4KAABQCgAAWgoAAFAKAABXCgAARQoAAFsKAABRCgAARQoAAFEKAABcCgAAWwoAAFgKAABSCgAAWwoAAFIKAABRCgAAXAoAAFEKAABTCgAAXAoAAFMKAABICgAAXQoAAF4KAABfCgAAXQoAAF8KAABgCgAAYQoAAGIKAABfCgAAYQoAAF8KAABjCgAAZAoAAGAKAABfCgAAZAoAAF8KAABlCgAAVAoAAFYKAABdCgAAVAoAAF0KAABmCgAAVgoAAGcKAABeCgAAVgoAAF4KAABdCgAAZgoAAF0KAABgCgAAZgoAAGAKAABoCgAARQoAAGkKAABhCgAARQoAAGEKAABqCgAAaQoAAGsKAABiCgAAaQoAAGIKAABhCgAAagoAAGEKAABjCgAAagoAAGMKAABYCgAAbAoAAG0KAABkCgAAbAoAAGQKAABuCgAAbQoAAG8KAABgCgAAbQoAAGAKAABkCgAAbgoAAGQKAABlCgAAbgoAAGUKAABwCgAAcQoAAHIKAABzCgAAcQoAAHMKAAB0CgAAdQoAAHYKAABzCgAAdQoAAHMKAAB3CgAAeAoAAHkKAABzCgAAeAoAAHMKAAB6CgAAVAoAAHsKAABxCgAAVAoAAHEKAAB8CgAAewoAAGgKAAByCgAAewoAAHIKAABxCgAAfAoAAHEKAAB0CgAAfAoAAHQKAAB9CgAAbAoAAH4KAAB1CgAAbAoAAHUKAABtCgAAfgoAAH8KAAB2CgAAfgoAAHYKAAB1CgAAbQoAAHUKAAB3CgAAbQoAAHcKAABvCgAAgAoAAIEKAAB4CgAAgAoAAHgKAACCCgAAgQoAAH0KAAB5CgAAgQoAAHkKAAB4CgAAggoAAHgKAAB6CgAAggoAAHoKAAB/CgAAgwoAAIQKAACFCgAAgwoAAIUKAACGCgAAhwoAAIgKAACFCgAAhwoAAIUKAACJCgAAigoAAIsKAACFCgAAigoAAIUKAACICgAAVAoAAHwKAACDCgAAVAoAAIMKAACMCgAAfAoAAI0KAACECgAAfAoAAIQKAACDCgAAjAoAAIMKAACGCgAAjAoAAIYKAACOCgAAjwoAAJAKAACHCgAAjwoAAIcKAACRCgAAkAoAAJIKAACICgAAkAoAAIgKAACHCgAAkQoAAIcKAACJCgAAkQoAAIkKAAB9CgAAkwoAAJQKAACKCgAAkwoAAIoKAACVCgAAlAoAAI4KAACLCgAAlAoAAIsKAACKCgAAlQoAAIoKAACICgAAlQoAAIgKAACWCgAAlwoAAJgKAACZCgAAlwoAAJkKAACaCgAAmwoAAJwKAACZCgAAmwoAAJkKAACdCgAAngoAAJoKAACZCgAAngoAAJkKAACcCgAAVAoAAJ8KAACXCgAAVAoAAJcKAACgCgAAnwoAAI4KAACYCgAAnwoAAJgKAACXCgAAoAoAAJcKAACaCgAAoAoAAJoKAAChCgAAkwoAAKIKAACbCgAAkwoAAJsKAACUCgAAogoAAKMKAACcCgAAogoAAJwKAACbCgAAlAoAAJsKAACdCgAAlAoAAJ0KAACOCgAApAoAAKUKAACeCgAApAoAAJ4KAACmCgAApQoAAKEKAACaCgAApQoAAJoKAACeCgAApgoAAJ4KAACcCgAApgoAAJwKAACnCgAAqAoAAKkKAACqCgAAqAoAAKoKAACrCgAArAoAAK0KAACqCgAArAoAAKoKAACuCgAArwoAAKsKAACqCgAArwoAAKoKAACwCgAAVAoAAKAKAACoCgAAVAoAAKgKAACxCgAAoAoAALIKAACpCgAAoAoAAKkKAACoCgAAsQoAAKgKAACrCgAAsQoAAKsKAACzCgAApAoAALQKAACsCgAApAoAAKwKAAClCgAAtAoAALUKAACtCgAAtAoAAK0KAACsCgAApQoAAKwKAACuCgAApQoAAK4KAACyCgAAtgoAALcKAACvCgAAtgoAAK8KAAC4CgAAtwoAALkKAACrCgAAtwoAAKsKAACvCgAAuAoAAK8KAACwCgAAuAoAALAKAAC1CgAAugoAALsKAAC8CgAAugoAALwKAAC9CgAAvgoAAL8KAAC8CgAAvgoAALwKAAC7CgAAwAoAAL0KAAC8CgAAwAoAALwKAAC/CgAAVAoAAMEKAAC6CgAAVAoAALoKAADCCgAAwQoAALkKAAC7CgAAwQoAALsKAAC6CgAAwgoAALoKAAC9CgAAwgoAAL0KAADDCgAAxAoAAMUKAAC+CgAAxAoAAL4KAAC3CgAAxQoAAMYKAAC/CgAAxQoAAL8KAAC+CgAAtwoAAL4KAAC7CgAAtwoAALsKAAC5CgAAxwoAAMgKAADACgAAxwoAAMAKAADJCgAAyAoAAMoKAAC9CgAAyAoAAL0KAADACgAAyQoAAMAKAAC/CgAAyQoAAL8KAADGCgAAywoAAMwKAADNCgAAywoAAM0KAADOCgAAzwoAANAKAADNCgAAzwoAAM0KAADRCgAA0goAANMKAADNCgAA0goAAM0KAADQCgAAVAoAANQKAADLCgAAVAoAAMsKAADVCgAA1AoAAMMKAADMCgAA1AoAAMwKAADLCgAA1QoAAMsKAADOCgAA1QoAAM4KAADWCgAAxwoAANcKAADPCgAAxwoAAM8KAADYCgAA1woAANkKAADQCgAA1woAANAKAADPCgAA2AoAAM8KAADRCgAA2AoAANEKAADDCgAA2goAANsKAADSCgAA2goAANIKAADcCgAA2woAAN0KAADTCgAA2woAANMKAADSCgAA3AoAANIKAADQCgAA3AoAANAKAADZCgAA3goAAN8KAADgCgAA3goAAOAKAADhCgAA4goAAOMKAADgCgAA4goAAOAKAADkCgAA5QoAAOEKAADgCgAA5QoAAOAKAADmCgAAVAoAANUKAADeCgAAVAoAAN4KAADnCgAA1QoAANYKAADfCgAA1QoAAN8KAADeCgAA5woAAN4KAADhCgAA5woAAOEKAADoCgAA6QoAAOoKAADiCgAA6QoAAOIKAADbCgAA6goAAOsKAADjCgAA6goAAOMKAADiCgAA2woAAOIKAADkCgAA2woAAOQKAADdCgAA7AoAAO0KAADlCgAA7AoAAOUKAADuCgAA7QoAAOgKAADhCgAA7QoAAOEKAADlCgAA7goAAOUKAADmCgAA7goAAOYKAADvCgAA8AoAAPEKAADyCgAA8AoAAPIKAADzCgAA9AoAAPUKAADyCgAA9AoAAPIKAADxCgAA9goAAPcKAADyCgAA9goAAPIKAAD4CgAAVAoAAPkKAADwCgAAVAoAAPAKAAD6CgAA+QoAAPsKAADxCgAA+QoAAPEKAADwCgAA+goAAPAKAADzCgAA+goAAPMKAAD8CgAA/QoAAP4KAAD0CgAA/QoAAPQKAADtCgAA/goAAP8KAAD1CgAA/goAAPUKAAD0CgAA7QoAAPQKAADxCgAA7QoAAPEKAAD7CgAAAAsAAAELAAD2CgAAAAsAAPYKAAACCwAAAQsAAPwKAAD3CgAAAQsAAPcKAAD2CgAAAgsAAPYKAAD4CgAAAgsAAPgKAAD/CgAAAwsAAAQLAAAFCwAAAwsAAAULAAAGCwAABwsAAAgLAAAFCwAABwsAAAULAAAJCwAACgsAAAsLAAAFCwAACgsAAAULAAAMCwAAVAoAAA0LAAADCwAAVAoAAAMLAAAOCwAADQsAAPwKAAAECwAADQsAAAQLAAADCwAADgsAAAMLAAAGCwAADgsAAAYLAAAPCwAAAAsAABALAAAHCwAAAAsAAAcLAAARCwAAEAsAABILAAAICwAAEAsAAAgLAAAHCwAAEQsAAAcLAAAJCwAAEQsAAAkLAAD8CgAAEwsAABQLAAAKCwAAEwsAAAoLAAAVCwAAFAsAABYLAAALCwAAFAsAAAsLAAAKCwAAFQsAAAoLAAAMCwAAFQsAAAwLAAASCwAAFwsAABgLAAAZCwAAFwsAABkLAAAaCwAAGwsAABwLAAAZCwAAGwsAABkLAAAdCwAAHgsAABoLAAAZCwAAHgsAABkLAAAcCwAAVAoAAA4LAAAXCwAAVAoAABcLAAAfCwAADgsAABYLAAAYCwAADgsAABgLAAAXCwAAHwsAABcLAAAaCwAAHwsAABoLAAAgCwAAEwsAACELAAAbCwAAEwsAABsLAAAiCwAAIQsAACMLAAAcCwAAIQsAABwLAAAbCwAAIgsAABsLAAAdCwAAIgsAAB0LAAAWCwAAJAsAACULAAAeCwAAJAsAAB4LAAAmCwAAJQsAACALAAAaCwAAJQsAABoLAAAeCwAAJgsAAB4LAAAcCwAAJgsAABwLAAAnCwAAKAsAACkLAAAqCwAAKAsAACoLAAArCwAAKQsAACwLAAAtCwAAKQsAAC0LAAAqCwAAKwsAACoLAAAuCwAAKwsAAC4LAAAvCwAAKgsAAC0LAAAwCwAAKgsAADALAAAuCwAAMQsAADILAAAoCwAAMQsAACgLAAAzCwAAMgsAADQLAAApCwAAMgsAACkLAAAoCwAANAsAADULAAAsCwAANAsAACwLAAApCwAANQsAADYLAAA3CwAANQsAADcLAAAsCwAALAsAADcLAAA4CwAALAsAADgLAAAtCwAALQsAADgLAAA5CwAALQsAADkLAAAwCwAAMAsAADkLAAA6CwAAMAsAADoLAAA7CwAALgsAADALAAA7CwAALgsAADsLAAA8CwAALwsAAC4LAAA8CwAALwsAADwLAAA9CwAAPgsAAC8LAAA9CwAAPgsAAD0LAAA/CwAAQAsAACsLAAAvCwAAQAsAAC8LAAA+CwAAMwsAACgLAAArCwAAMwsAACsLAABACwAAQQsAAEILAABDCwAAQQsAAEMLAABECwAAQgsAAEULAABGCwAAQgsAAEYLAABDCwAARAsAAEMLAABHCwAARAsAAEcLAABICwAAQwsAAEYLAABJCwAAQwsAAEkLAABHCwAASgsAAEsLAABBCwAASgsAAEELAABMCwAASwsAAE0LAABCCwAASwsAAEILAABBCwAATQsAAE4LAABFCwAATQsAAEULAABCCwAATgsAAE8LAABQCwAATgsAAFALAABFCwAARQsAAFALAABRCwAARQsAAFELAABGCwAARgsAAFELAABSCwAARgsAAFILAABJCwAASQsAAFILAABTCwAASQsAAFMLAABUCwAARwsAAEkLAABUCwAARwsAAFQLAABVCwAASAsAAEcLAABVCwAASAsAAFULAABWCwAAVwsAAEgLAABWCwAAVwsAAFYLAABYCwAAWQsAAEQLAABICwAAWQsAAEgLAABXCwAATAsAAEELAABECwAATAsAAEQLAABZCwAAWgsAAFsLAABcCwAAWgsAAFwLAABdCwAAWwsAAF4LAABfCwAAWwsAAF8LAABcCwAAXQsAAFwLAABgCwAAXQsAAGALAABhCwAAXAsAAF8LAABiCwAAXAsAAGILAABgCwAAYwsAAGQLAABaCwAAYwsAAFoLAABlCwAAZAsAAGYLAABbCwAAZAsAAFsLAABaCwAAZgsAAGcLAABeCwAAZgsAAF4LAABbCwAAZwsAAGgLAABpCwAAZwsAAGkLAABeCwAAXgsAAGkLAABqCwAAXgsAAGoLAABfCwAAXwsAAGoLAABrCwAAXwsAAGsLAABiCwAAYgsAAGsLAABsCwAAYgsAAGwLAABtCwAAYAsAAGILAABtCwAAYAsAAG0LAABuCwAAYQsAAGALAABuCwAAYQsAAG4LAABvCwAAcAsAAGELAABvCwAAcAsAAG8LAABxCwAAcgsAAF0LAABhCwAAcgsAAGELAABwCwAAZQsAAFoLAABdCwAAZQsAAF0LAAByCwAAcwsAAHQLAAB1CwAAcwsAAHULAAB2CwAAdAsAAHcLAAB4CwAAdAsAAHgLAAB1CwAAdgsAAHULAAB5CwAAdgsAAHkLAAB6CwAAdQsAAHgLAAB7CwAAdQsAAHsLAAB5CwAAfAsAAH0LAABzCwAAfAsAAHMLAAB+CwAAfQsAAH8LAAB0CwAAfQsAAHQLAABzCwAAfwsAAIALAAB3CwAAfwsAAHcLAAB0CwAAgAsAAIELAACCCwAAgAsAAIILAAB3CwAAdwsAAIILAACDCwAAdwsAAIMLAAB4CwAAeAsAAIMLAACECwAAeAsAAIQLAAB7CwAAewsAAIQLAACFCwAAewsAAIULAACGCwAAeQsAAHsLAACGCwAAeQsAAIYLAACHCwAAegsAAHkLAACHCwAAegsAAIcLAACICwAAiQsAAHoLAACICwAAiQsAAIgLAACKCwAAiwsAAHYLAAB6CwAAiwsAAHoLAACJCwAAfgsAAHMLAAB2CwAAfgsAAHYLAACLCwAAjAsAAI0LAACOCwAAjAsAAI4LAACPCwAAjQsAAJALAACRCwAAjQsAAJELAACOCwAAjwsAAI4LAACSCwAAjwsAAJILAACTCwAAjgsAAJELAACUCwAAjgsAAJQLAACSCwAAlQsAAJYLAACMCwAAlQsAAIwLAACXCwAAlgsAAJgLAACNCwAAlgsAAI0LAACMCwAAmAsAAJkLAACQCwAAmAsAAJALAACNCwAAmQsAAJoLAACbCwAAmQsAAJsLAACQCwAAkAsAAJsLAACcCwAAkAsAAJwLAACRCwAAkQsAAJwLAACdCwAAkQsAAJ0LAACUCwAAlAsAAJ0LAACeCwAAlAsAAJ4LAACfCwAAkgsAAJQLAACfCwAAkgsAAJ8LAACgCwAAkwsAAJILAACgCwAAkwsAAKALAAChCwAAogsAAJMLAAChCwAAogsAAKELAACjCwAApAsAAI8LAACTCwAApAsAAJMLAACiCwAAlwsAAIwLAACPCwAAlwsAAI8LAACkCwAApQsAAKYLAACnCwAApQsAAKcLAACoCwAApgsAAKkLAACqCwAApgsAAKoLAACnCwAAqAsAAKcLAACrCwAAqAsAAKsLAACsCwAApwsAAKoLAACtCwAApwsAAK0LAACrCwAArgsAAK8LAAClCwAArgsAAKULAACwCwAArwsAALELAACmCwAArwsAAKYLAAClCwAAsQsAALILAACpCwAAsQsAAKkLAACmCwAAsgsAALMLAAC0CwAAsgsAALQLAACpCwAAqQsAALQLAAC1CwAAqQsAALULAACqCwAAqgsAALULAAC2CwAAqgsAALYLAACtCwAArQsAALYLAAC3CwAArQsAALcLAAC4CwAAqwsAAK0LAAC4CwAAqwsAALgLAAC5CwAArAsAAKsLAAC5CwAArAsAALkLAAC6CwAAuwsAAKwLAAC6CwAAuwsAALoLAAC8CwAAvQsAAKgLAACsCwAAvQsAAKwLAAC7CwAAsAsAAKULAACoCwAAsAsAAKgLAAC9CwAAvgsAAL8LAADACwAAvgsAAMALAADBCwAAvwsAAMILAADDCwAAvwsAAMMLAADACwAAwQsAAMALAADECwAAwQsAAMQLAADFCwAAwAsAAMMLAADGCwAAwAsAAMYLAADECwAAxwsAAMgLAAC+CwAAxwsAAL4LAADJCwAAyAsAAMoLAAC/CwAAyAsAAL8LAAC+CwAAygsAAMsLAADCCwAAygsAAMILAAC/CwAAywsAAMwLAADNCwAAywsAAM0LAADCCwAAwgsAAM0LAADOCwAAwgsAAM4LAADDCwAAwwsAAM4LAADPCwAAwwsAAM8LAADGCwAAxgsAAM8LAADQCwAAxgsAANALAADRCwAAxAsAAMYLAADRCwAAxAsAANELAADSCwAAxQsAAMQLAADSCwAAxQsAANILAADTCwAA1AsAAMULAADTCwAA1AsAANMLAADVCwAA1gsAAMELAADFCwAA1gsAAMULAADUCwAAyQsAAL4LAADBCwAAyQsAAMELAADWCwAA1wsAANgLAADZCwAA1wsAANkLAADaCwAA2AsAANsLAADcCwAA2AsAANwLAADZCwAA2gsAANkLAADdCwAA2gsAAN0LAADeCwAA2QsAANwLAADfCwAA2QsAAN8LAADdCwAA4AsAAOELAADXCwAA4AsAANcLAADiCwAA4QsAAOMLAADYCwAA4QsAANgLAADXCwAA4wsAAOQLAADbCwAA4wsAANsLAADYCwAA5AsAAOULAADmCwAA5AsAAOYLAADbCwAA2wsAAOYLAADnCwAA2wsAAOcLAADcCwAA3AsAAOcLAADoCwAA3AsAAOgLAADfCwAA3wsAAOgLAADpCwAA3wsAAOkLAADqCwAA3QsAAN8LAADqCwAA3QsAAOoLAADrCwAA3gsAAN0LAADrCwAA3gsAAOsLAADsCwAA7QsAAN4LAADsCwAA7QsAAOwLAADuCwAA7wsAANoLAADeCwAA7wsAAN4LAADtCwAA4gsAANcLAADaCwAA4gsAANoLAADvCwAA8AsAAPELAADyCwAA8AsAAPILAADzCwAA8QsAAPQLAAD1CwAA8QsAAPULAADyCwAA8wsAAPILAAD2CwAA8wsAAPYLAAD3CwAA8gsAAPULAAD4CwAA8gsAAPgLAAD2CwAA+QsAAPoLAADwCwAA+QsAAPALAAD7CwAA+gsAAPwLAADxCwAA+gsAAPELAADwCwAA/AsAAP0LAAD0CwAA/AsAAPQLAADxCwAA/QsAAP4LAAD/CwAA/QsAAP8LAAD0CwAA9AsAAP8LAAAADAAA9AsAAAAMAAD1CwAA9QsAAAAMAAABDAAA9QsAAAEMAAD4CwAA+AsAAAEMAAACDAAA+AsAAAIMAAADDAAA9gsAAPgLAAADDAAA9gsAAAMMAAAEDAAA9wsAAPYLAAAEDAAA9wsAAAQMAAAFDAAABgwAAPcLAAAFDAAABgwAAAUMAAAHDAAACAwAAPMLAAD3CwAACAwAAPcLAAAGDAAA+wsAAPALAADzCwAA+wsAAPMLAAAIDAAACQwAAAoMAAALDAAACQwAAAsMAAAMDAAACgwAAA0MAAAODAAACgwAAA4MAAALDAAADAwAAAsMAAAPDAAADAwAAA8MAAAQDAAACwwAAA4MAAARDAAACwwAABEMAAAPDAAAEgwAABMMAAAJDAAAEgwAAAkMAAAUDAAAEwwAABUMAAAKDAAAEwwAAAoMAAAJDAAAFQwAABYMAAANDAAAFQwAAA0MAAAKDAAAFgwAABcMAAAYDAAAFgwAABgMAAANDAAADQwAABgMAAAZDAAADQwAABkMAAAODAAADgwAABkMAAAaDAAADgwAABoMAAARDAAAEQwAABoMAAAbDAAAEQwAABsMAAAcDAAADwwAABEMAAAcDAAADwwAABwMAAAdDAAAEAwAAA8MAAAdDAAAEAwAAB0MAAAeDAAAHwwAABAMAAAeDAAAHwwAAB4MAAAgDAAAIQwAAAwMAAAQDAAAIQwAABAMAAAfDAAAFAwAAAkMAAAMDAAAFAwAAAwMAAAhDAAAIgwAACMMAAAkDAAAIgwAACQMAAAlDAAAIwwAACYMAAAnDAAAIwwAACcMAAAkDAAAJQwAACQMAAAoDAAAJQwAACgMAAApDAAAJAwAACcMAAAqDAAAJAwAACoMAAAoDAAAKwwAACwMAAAiDAAAKwwAACIMAAAtDAAALAwAAC4MAAAjDAAALAwAACMMAAAiDAAALgwAAC8MAAAmDAAALgwAACYMAAAjDAAALwwAAGMLAABlCwAALwwAAGULAAAmDAAAJgwAAGULAAByCwAAJgwAAHILAAAnDAAAJwwAAHILAABwCwAAJwwAAHALAAAqDAAAKgwAAHALAABxCwAAKgwAAHELAAAwDAAAKAwAACoMAAAwDAAAKAwAADAMAAAxDAAAKQwAACgMAAAxDAAAKQwAADEMAAAyDAAAMwwAACkMAAAyDAAAMwwAADIMAAA0DAAANQwAACUMAAApDAAANQwAACkMAAAzDAAALQwAACIMAAAlDAAALQwAACUMAAA1DAAANgwAADcMAAA4DAAANgwAADgMAAA5DAAANwwAADoMAAA7DAAANwwAADsMAAA4DAAAOQwAADgMAAA8DAAAOQwAADwMAAA9DAAAOAwAADsMAAA+DAAAOAwAAD4MAAA8DAAAPwwAAEAMAAA2DAAAPwwAADYMAABBDAAAQAwAAEIMAAA3DAAAQAwAADcMAAA2DAAAQgwAAEMMAAA6DAAAQgwAADoMAAA3DAAAQwwAAEQMAABFDAAAQwwAAEUMAAA6DAAAOgwAAEUMAABGDAAAOgwAAEYMAAA7DAAAOwwAAEYMAABHDAAAOwwAAEcMAAA+DAAAPgwAAEcMAABIDAAAPgwAAEgMAABJDAAAPAwAAD4MAABJDAAAPAwAAEkMAABKDAAAPQwAADwMAABKDAAAPQwAAEoMAABLDAAATAwAAD0MAABLDAAATAwAAEsMAABNDAAATgwAADkMAAA9DAAATgwAAD0MAABMDAAAQQwAADYMAAA5DAAAQQwAADkMAABODAAATwwAAFAMAABRDAAATwwAAFEMAABSDAAAUAwAAFMMAABUDAAAUAwAAFQMAABRDAAAUgwAAFEMAABVDAAAUgwAAFUMAABWDAAAUQwAAFQMAABXDAAAUQwAAFcMAABVDAAAWAwAAFkMAABPDAAAWAwAAE8MAABaDAAAWQwAAFsMAABQDAAAWQwAAFAMAABPDAAAWwwAAFwMAABTDAAAWwwAAFMMAABQDAAAXAwAAF0MAABeDAAAXAwAAF4MAABTDAAAUwwAAF4MAABfDAAAUwwAAF8MAABUDAAAVAwAAF8MAABgDAAAVAwAAGAMAABXDAAAVwwAAGAMAABhDAAAVwwAAGEMAABiDAAAVQwAAFcMAABiDAAAVQwAAGIMAABjDAAAVgwAAFUMAABjDAAAVgwAAGMMAABkDAAAZQwAAFYMAABkDAAAZQwAAGQMAABmDAAAZwwAAFIMAABWDAAAZwwAAFYMAABlDAAAWgwAAE8MAABSDAAAWgwAAFIMAABnDAAAaAwAAGkMAABqDAAAaAwAAGoMAABrDAAAaQwAAGwMAABtDAAAaQwAAG0MAABqDAAAawwAAGoMAABuDAAAawwAAG4MAABvDAAAagwAAG0MAABwDAAAagwAAHAMAABuDAAATwsAAHEMAABoDAAATwsAAGgMAABQCwAAcQwAAHIMAABpDAAAcQwAAGkMAABoDAAAcgwAAHMMAABsDAAAcgwAAGwMAABpDAAAcwwAAHQMAAB1DAAAcwwAAHUMAABsDAAAbAwAAHUMAAB2DAAAbAwAAHYMAABtDAAAbQwAAHYMAAB3DAAAbQwAAHcMAABwDAAAcAwAAHcMAAB4DAAAcAwAAHgMAAB5DAAAbgwAAHAMAAB5DAAAbgwAAHkMAAB6DAAAbwwAAG4MAAB6DAAAbwwAAHoMAAB7DAAAUgsAAG8MAAB7DAAAUgsAAHsMAABTCwAAUQsAAGsMAABvDAAAUQsAAG8MAABSCwAAUAsAAGgMAABrDAAAUAsAAGsMAABRCwAAfAwAAH0MAAB+DAAAfAwAAH4MAAB/DAAAfQwAAIAMAACBDAAAfQwAAIEMAAB+DAAAfwwAAH4MAACCDAAAfwwAAIIMAACDDAAAfgwAAIEMAACEDAAAfgwAAIQMAACCDAAAhQwAAIYMAAB8DAAAhQwAAHwMAACHDAAAhgwAAIgMAAB9DAAAhgwAAH0MAAB8DAAAiAwAAIkMAACADAAAiAwAAIAMAAB9DAAAiQwAAJULAACXCwAAiQwAAJcLAACADAAAgAwAAJcLAACkCwAAgAwAAKQLAACBDAAAgQwAAKQLAACiCwAAgQwAAKILAACEDAAAhAwAAKILAACjCwAAhAwAAKMLAACKDAAAggwAAIQMAACKDAAAggwAAIoMAACLDAAAgwwAAIIMAACLDAAAgwwAAIsMAACMDAAAjQwAAIMMAACMDAAAjQwAAIwMAACODAAAjwwAAH8MAACDDAAAjwwAAIMMAACNDAAAhwwAAHwMAAB/DAAAhwwAAH8MAACPDAAAkAwAAJEMAACSDAAAkAwAAJIMAACTDAAAkQwAAJQMAACVDAAAkQwAAJUMAACSDAAAkwwAAJIMAACWDAAAkwwAAJYMAACXDAAAkgwAAJUMAACYDAAAkgwAAJgMAACWDAAAmQwAAJoMAACQDAAAmQwAAJAMAACbDAAAmgwAAJwMAACRDAAAmgwAAJEMAACQDAAAnAwAAJ0MAACUDAAAnAwAAJQMAACRDAAAnQwAACsMAAAtDAAAnQwAAC0MAACUDAAAlAwAAC0MAAA1DAAAlAwAADUMAACVDAAAlQwAADUMAAAzDAAAlQwAADMMAACYDAAAmAwAADMMAAA0DAAAmAwAADQMAACeDAAAlgwAAJgMAACeDAAAlgwAAJ4MAACfDAAAlwwAAJYMAACfDAAAlwwAAJ8MAACgDAAAoQwAAJcMAACgDAAAoQwAAKAMAACiDAAAowwAAJMMAACXDAAAowwAAJcMAAChDAAAmwwAAJAMAACTDAAAmwwAAJMMAACjDAAApAwAAKUMAACmDAAApAwAAKYMAACnDAAApQwAAKgMAACpDAAApQwAAKkMAACmDAAApwwAAKYMAACqDAAApwwAAKoMAACrDAAApgwAAKkMAACsDAAApgwAAKwMAACqDAAArQwAAK4MAACkDAAArQwAAKQMAACvDAAArgwAALAMAAClDAAArgwAAKUMAACkDAAAsAwAALEMAACoDAAAsAwAAKgMAAClDAAAsQwAAK4LAACwCwAAsQwAALALAACoDAAAqAwAALALAAC9CwAAqAwAAL0LAACpDAAAqQwAAL0LAAC7CwAAqQwAALsLAACsDAAArAwAALsLAAC8CwAArAwAALwLAACyDAAAqgwAAKwMAACyDAAAqgwAALIMAACzDAAAqwwAAKoMAACzDAAAqwwAALMMAAC0DAAAtQwAAKsMAAC0DAAAtQwAALQMAAC2DAAAtwwAAKcMAACrDAAAtwwAAKsMAAC1DAAArwwAAKQMAACnDAAArwwAAKcMAAC3DAAAuAwAALkMAAC6DAAAuAwAALoMAAC7DAAAuQwAALwMAAC9DAAAuQwAAL0MAAC6DAAAuwwAALoMAAC+DAAAuwwAAL4MAAC/DAAAugwAAL0MAADADAAAugwAAMAMAAC+DAAAwQwAAMIMAAC4DAAAwQwAALgMAADDDAAAwgwAAMQMAAC5DAAAwgwAALkMAAC4DAAAxAwAAMUMAAC8DAAAxAwAALwMAAC5DAAAxQwAADELAAAzCwAAxQwAADMLAAC8DAAAvAwAADMLAABACwAAvAwAAEALAAC9DAAAvQwAAEALAAA+CwAAvQwAAD4LAADADAAAwAwAAD4LAAA/CwAAwAwAAD8LAADGDAAAvgwAAMAMAADGDAAAvgwAAMYMAADHDAAAvwwAAL4MAADHDAAAvwwAAMcMAADIDAAAyQwAAL8MAADIDAAAyQwAAMgMAADKDAAAywwAALsMAAC/DAAAywwAAL8MAADJDAAAwwwAALgMAAC7DAAAwwwAALsMAADLDAAAzAwAAM0MAADODAAAzAwAAM4MAADPDAAAzQwAANAMAADRDAAAzQwAANEMAADODAAAzwwAAM4MAADSDAAAzwwAANIMAADTDAAAzgwAANEMAADUDAAAzgwAANQMAADSDAAAdAwAANUMAADMDAAAdAwAAMwMAAB1DAAA1QwAANYMAADNDAAA1QwAAM0MAADMDAAA1gwAANcMAADQDAAA1gwAANAMAADNDAAA1wwAANgMAADZDAAA1wwAANkMAADQDAAA0AwAANkMAADaDAAA0AwAANoMAADRDAAA0QwAANoMAADbDAAA0QwAANsMAADUDAAA1AwAANsMAADcDAAA1AwAANwMAADdDAAA0gwAANQMAADdDAAA0gwAAN0MAADeDAAA0wwAANIMAADeDAAA0wwAAN4MAADfDAAAdwwAANMMAADfDAAAdwwAAN8MAAB4DAAAdgwAAM8MAADTDAAAdgwAANMMAAB3DAAAdQwAAMwMAADPDAAAdQwAAM8MAAB2DAAA4AwAAOEMAADiDAAA4AwAAOIMAADjDAAA4QwAAOQMAADlDAAA4QwAAOUMAADiDAAA4wwAAOIMAADmDAAA4wwAAOYMAADnDAAA4gwAAOUMAADoDAAA4gwAAOgMAADmDAAAzAsAAOkMAADgDAAAzAsAAOAMAADNCwAA6QwAAOoMAADhDAAA6QwAAOEMAADgDAAA6gwAAOsMAADkDAAA6gwAAOQMAADhDAAA6wwAAOwMAADtDAAA6wwAAO0MAADkDAAA5AwAAO0MAADuDAAA5AwAAO4MAADlDAAA5QwAAO4MAADvDAAA5QwAAO8MAADoDAAA6AwAAO8MAADwDAAA6AwAAPAMAADxDAAA5gwAAOgMAADxDAAA5gwAAPEMAADyDAAA5wwAAOYMAADyDAAA5wwAAPIMAADzDAAAzwsAAOcMAADzDAAAzwsAAPMMAADQCwAAzgsAAOMMAADnDAAAzgsAAOcMAADPCwAAzQsAAOAMAADjDAAAzQsAAOMMAADOCwAA9AwAAPUMAAD2DAAA9AwAAPYMAAD3DAAA9QwAAPgMAAD5DAAA9QwAAPkMAAD2DAAA9wwAAPYMAAD6DAAA9wwAAPoMAAD7DAAA9gwAAPkMAAD8DAAA9gwAAPwMAAD6DAAAaAsAAP0MAAD0DAAAaAsAAPQMAABpCwAA/QwAAP4MAAD1DAAA/QwAAPUMAAD0DAAA/gwAAP8MAAD4DAAA/gwAAPgMAAD1DAAA/wwAAAANAAABDQAA/wwAAAENAAD4DAAA+AwAAAENAAACDQAA+AwAAAINAAD5DAAA+QwAAAINAAADDQAA+QwAAAMNAAD8DAAA/AwAAAMNAAAEDQAA/AwAAAQNAAAFDQAA+gwAAPwMAAAFDQAA+gwAAAUNAAAGDQAA+wwAAPoMAAAGDQAA+wwAAAYNAAAHDQAAawsAAPsMAAAHDQAAawsAAAcNAABsCwAAagsAAPcMAAD7DAAAagsAAPsMAABrCwAAaQsAAPQMAAD3DAAAaQsAAPcMAABqCwAACA0AAAkNAAAKDQAACA0AAAoNAAALDQAACQ0AAAwNAAANDQAACQ0AAA0NAAAKDQAACw0AAAoNAAAODQAACw0AAA4NAAAPDQAACg0AAA0NAAAQDQAACg0AABANAAAODQAAEQ0AABINAAAIDQAAEQ0AAAgNAAATDQAAEg0AABQNAAAJDQAAEg0AAAkNAAAIDQAAFA0AABUNAAAMDQAAFA0AAAwNAAAJDQAAFQ0AAOALAADiCwAAFQ0AAOILAAAMDQAADA0AAOILAADvCwAADA0AAO8LAAANDQAADQ0AAO8LAADtCwAADQ0AAO0LAAAQDQAAEA0AAO0LAADuCwAAEA0AAO4LAAAWDQAADg0AABANAAAWDQAADg0AABYNAAAXDQAADw0AAA4NAAAXDQAADw0AABcNAAAYDQAAGQ0AAA8NAAAYDQAAGQ0AABgNAAAaDQAAGw0AAAsNAAAPDQAAGw0AAA8NAAAZDQAAEw0AAAgNAAALDQAAEw0AAAsNAAAbDQAAHA0AAB0NAAAeDQAAHA0AAB4NAAAfDQAAHQ0AACANAAAhDQAAHQ0AACENAAAeDQAAHw0AAB4NAAAiDQAAHw0AACINAAAjDQAAHg0AACENAAAkDQAAHg0AACQNAAAiDQAA/gsAACUNAAAcDQAA/gsAABwNAAD/CwAAJQ0AACYNAAAdDQAAJQ0AAB0NAAAcDQAAJg0AACcNAAAgDQAAJg0AACANAAAdDQAAJw0AACgNAAApDQAAJw0AACkNAAAgDQAAIA0AACkNAAAqDQAAIA0AACoNAAAhDQAAIQ0AACoNAAArDQAAIQ0AACsNAAAkDQAAJA0AACsNAAAsDQAAJA0AACwNAAAtDQAAIg0AACQNAAAtDQAAIg0AAC0NAAAuDQAAIw0AACINAAAuDQAAIw0AAC4NAAAvDQAAAQwAACMNAAAvDQAAAQwAAC8NAAACDAAAAAwAAB8NAAAjDQAAAAwAACMNAAABDAAA/wsAABwNAAAfDQAA/wsAAB8NAAAADAAAMA0AADENAAAyDQAAMA0AADINAAAzDQAAMQ0AADQNAAA1DQAAMQ0AADUNAAAyDQAAMw0AADINAAA2DQAAMw0AADYNAAA3DQAAMg0AADUNAAA4DQAAMg0AADgNAAA2DQAAgQsAADkNAAAwDQAAgQsAADANAACCCwAAOQ0AADoNAAAxDQAAOQ0AADENAAAwDQAAOg0AADsNAAA0DQAAOg0AADQNAAAxDQAAOw0AADwNAAA9DQAAOw0AAD0NAAA0DQAANA0AAD0NAAA+DQAANA0AAD4NAAA1DQAANQ0AAD4NAAA/DQAANQ0AAD8NAAA4DQAAOA0AAD8NAABADQAAOA0AAEANAABBDQAANg0AADgNAABBDQAANg0AAEENAABCDQAANw0AADYNAABCDQAANw0AAEINAABDDQAAhAsAADcNAABDDQAAhAsAAEMNAACFCwAAgwsAADMNAAA3DQAAgwsAADcNAACECwAAggsAADANAAAzDQAAggsAADMNAACDCwAARA0AAEUNAABGDQAARA0AAEYNAABHDQAARQ0AAEgNAABJDQAARQ0AAEkNAABGDQAARw0AAEYNAABKDQAARw0AAEoNAABLDQAARg0AAEkNAABMDQAARg0AAEwNAABKDQAATQ0AAE4NAABEDQAATQ0AAEQNAABPDQAATg0AAFANAABFDQAATg0AAEUNAABEDQAAUA0AAFENAABIDQAAUA0AAEgNAABFDQAAUQ0AAFINAABTDQAAUQ0AAFMNAABIDQAASA0AAFMNAABUDQAASA0AAFQNAABJDQAASQ0AAFQNAABVDQAASQ0AAFUNAABMDQAATA0AAFUNAABWDQAATA0AAFYNAABXDQAASg0AAEwNAABXDQAASg0AAFcNAABYDQAASw0AAEoNAABYDQAASw0AAFgNAABZDQAAWg0AAEsNAABZDQAAWg0AAFkNAABbDQAAXA0AAEcNAABLDQAAXA0AAEsNAABaDQAATw0AAEQNAABHDQAATw0AAEcNAABcDQAAXQ0AAF4NAABfDQAAXQ0AAF8NAABgDQAAXg0AAGENAABiDQAAXg0AAGINAABfDQAAYA0AAF8NAABjDQAAYA0AAGMNAABkDQAAXw0AAGINAABlDQAAXw0AAGUNAABjDQAAZg0AAGcNAABdDQAAZg0AAF0NAABoDQAAZw0AAGkNAABeDQAAZw0AAF4NAABdDQAAaQ0AAGoNAABhDQAAaQ0AAGENAABeDQAAag0AAGsNAABsDQAAag0AAGwNAABhDQAAYQ0AAGwNAABtDQAAYQ0AAG0NAABiDQAAYg0AAG0NAABuDQAAYg0AAG4NAABlDQAAZQ0AAG4NAABvDQAAZQ0AAG8NAABwDQAAYw0AAGUNAABwDQAAYw0AAHANAABxDQAAZA0AAGMNAABxDQAAZA0AAHENAAByDQAAcw0AAGQNAAByDQAAcw0AAHINAAB0DQAAdQ0AAGANAABkDQAAdQ0AAGQNAABzDQAAaA0AAF0NAABgDQAAaA0AAGANAAB1DQAAdg0AAHcNAAB4DQAAdg0AAHgNAAB5DQAAdw0AAHoNAAB7DQAAdw0AAHsNAAB4DQAAeQ0AAHgNAAB8DQAAeQ0AAHwNAAB9DQAAeA0AAHsNAAB+DQAAeA0AAH4NAAB8DQAAfw0AAIANAAB2DQAAfw0AAHYNAACBDQAAgA0AAIINAAB3DQAAgA0AAHcNAAB2DQAAgg0AAIMNAAB6DQAAgg0AAHoNAAB3DQAAgw0AAIQNAACFDQAAgw0AAIUNAAB6DQAAeg0AAIUNAACGDQAAeg0AAIYNAAB7DQAAew0AAIYNAACHDQAAew0AAIcNAAB+DQAAfg0AAIcNAACIDQAAfg0AAIgNAACJDQAAfA0AAH4NAACJDQAAfA0AAIkNAACKDQAAfQ0AAHwNAACKDQAAfQ0AAIoNAACLDQAAjA0AAH0NAACLDQAAjA0AAIsNAACNDQAAjg0AAHkNAAB9DQAAjg0AAH0NAACMDQAAgQ0AAHYNAAB5DQAAgQ0AAHkNAACODQAAjw0AAJANAACRDQAAjw0AAJENAACSDQAAkA0AAJMNAACUDQAAkA0AAJQNAACRDQAAkg0AAJENAACVDQAAkg0AAJUNAACWDQAAkQ0AAJQNAACXDQAAkQ0AAJcNAACVDQAAmA0AAJkNAACPDQAAmA0AAI8NAACaDQAAmQ0AAJsNAACQDQAAmQ0AAJANAACPDQAAmw0AAJwNAACTDQAAmw0AAJMNAACQDQAAnA0AABIMAAAUDAAAnA0AABQMAACTDQAAkw0AABQMAAAhDAAAkw0AACEMAACUDQAAlA0AACEMAAAfDAAAlA0AAB8MAACXDQAAlw0AAB8MAAAgDAAAlw0AACAMAACdDQAAlQ0AAJcNAACdDQAAlQ0AAJ0NAACeDQAAlg0AAJUNAACeDQAAlg0AAJ4NAACfDQAAoA0AAJYNAACfDQAAoA0AAJ8NAAChDQAAog0AAJINAACWDQAAog0AAJYNAACgDQAAmg0AAI8NAACSDQAAmg0AAJINAACiDQAAow0AAKQNAAClDQAAow0AAKUNAACmDQAApA0AAKcNAACoDQAApA0AAKgNAAClDQAApg0AAKUNAACpDQAApg0AAKkNAACqDQAApQ0AAKgNAACrDQAApQ0AAKsNAACpDQAArA0AAK0NAACjDQAArA0AAKMNAACuDQAArQ0AAK8NAACkDQAArQ0AAKQNAACjDQAArw0AALANAACnDQAArw0AAKcNAACkDQAAsA0AAIUMAACHDAAAsA0AAIcMAACnDQAApw0AAIcMAACPDAAApw0AAI8MAACoDQAAqA0AAI8MAACNDAAAqA0AAI0MAACrDQAAqw0AAI0MAACODAAAqw0AAI4MAACxDQAAqQ0AAKsNAACxDQAAqQ0AALENAACyDQAAqg0AAKkNAACyDQAAqg0AALINAACzDQAAtA0AAKoNAACzDQAAtA0AALMNAAC1DQAAtg0AAKYNAACqDQAAtg0AAKoNAAC0DQAArg0AAKMNAACmDQAArg0AAKYNAAC2DQAAtw0AALgNAAC5DQAAtw0AALkNAAC6DQAAuA0AALsNAAC8DQAAuA0AALwNAAC5DQAAug0AALkNAAC9DQAAug0AAL0NAAC+DQAAuQ0AALwNAAC/DQAAuQ0AAL8NAAC9DQAAwA0AAMENAAC3DQAAwA0AALcNAADCDQAAwQ0AAMMNAAC4DQAAwQ0AALgNAAC3DQAAww0AAMQNAAC7DQAAww0AALsNAAC4DQAAxA0AAMUNAADGDQAAxA0AAMYNAAC7DQAAuw0AAMYNAADHDQAAuw0AAMcNAAC8DQAAvA0AAMcNAADIDQAAvA0AAMgNAAC/DQAAvw0AAMgNAADJDQAAvw0AAMkNAADKDQAAvQ0AAL8NAADKDQAAvQ0AAMoNAADLDQAAvg0AAL0NAADLDQAAvg0AAMsNAADMDQAAzQ0AAL4NAADMDQAAzQ0AAMwNAADODQAAzw0AALoNAAC+DQAAzw0AAL4NAADNDQAAwg0AALcNAAC6DQAAwg0AALoNAADPDQAA0A0AANENAADSDQAA0A0AANINAADTDQAA0Q0AANQNAADVDQAA0Q0AANUNAADSDQAA0w0AANINAADWDQAA0w0AANYNAADXDQAA0g0AANUNAADYDQAA0g0AANgNAADWDQAA2Q0AANoNAADQDQAA2Q0AANANAADbDQAA2g0AANwNAADRDQAA2g0AANENAADQDQAA3A0AAN0NAADUDQAA3A0AANQNAADRDQAA3Q0AAN4NAADfDQAA3Q0AAN8NAADUDQAA1A0AAN8NAADgDQAA1A0AAOANAADVDQAA1Q0AAOANAADhDQAA1Q0AAOENAADYDQAA2A0AAOENAADiDQAA2A0AAOINAADjDQAA1g0AANgNAADjDQAA1g0AAOMNAADkDQAA1w0AANYNAADkDQAA1w0AAOQNAADlDQAA5g0AANcNAADlDQAA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MREAADMRAAA0EQAAMhEAADURAAA2EQAAMhEAADYRAAAzEQAANBEAADMRAAA3EQAANBEAADcRAAA4EQAAMxEAADYRAAA5EQAAMxEAADkRAAA3EQAAOhEAADsRAAAxEQAAOhEAADERAAA8EQAAOxEAAD0RAAAyEQAAOxEAADIRAAAxEQAAPREAAD4RAAA1EQAAPREAADURAAAyEQAAPhEAADEQAAAzEAAAPhEAADMQAAA1EQAANREAADMQAAA7EAAANREAADsQAAA2EQAANhEAADsQAAA5EAAANhEAADkQAAA5EQAAOREAADkQAAA6EAAAOREAADoQAAA/EQAANxEAADkRAAA/EQAANxEAAD8RAABAEQAAOBEAADcRAABAEQAAOBEAAEARAABBEQAAQhEAADgRAABBEQAAQhEAAEERAABDEQAARBEAADQRAAA4EQAARBEAADgRAABCEQAAPBEAADERAAA0EQAAPBEAADQRAABEEQAARREAAEYRAABHEQAARREAAEcRAABIEQAARhEAAEkRAABKEQAARhEAAEoRAABHEQAASBEAAEcRAABLEQAASBEAAEsRAABMEQAARxEAAEoRAABNEQAARxEAAE0RAABLEQAASBAAAE4RAABFEQAASBAAAEURAABJEAAAThEAAE8RAABGEQAAThEAAEYRAABFEQAATxEAAFARAABJEQAATxEAAEkRAABGEQAAUBEAAFERAABSEQAAUBEAAFIRAABJEQAASREAAFIRAABTEQAASREAAFMRAABKEQAAShEAAFMRAABUEQAAShEAAFQRAABNEQAATREAAFQRAABVEQAATREAAFURAABWEQAASxEAAE0RAABWEQAASxEAAFYRAABXEQAATBEAAEsRAABXEQAATBEAAFcRAABYEQAASxAAAEwRAABYEQAASxAAAFgRAABMEAAAShAAAEgRAABMEQAAShAAAEwRAABLEAAASRAAAEURAABIEQAASRAAAEgRAABKEAAAWREAAFoRAABbEQAAWREAAFsRAABcEQAAWhEAAF0RAABeEQAAWhEAAF4RAABbEQAAXBEAAFsRAABfEQAAXBEAAF8RAABgEQAAWxEAAF4RAABhEQAAWxEAAGERAABfEQAAXBAAAGIRAABZEQAAXBAAAFkRAABdEAAAYhEAAGMRAABaEQAAYhEAAFoRAABZEQAAYxEAAGQRAABdEQAAYxEAAF0RAABaEQAAZBEAAGURAABmEQAAZBEAAGYRAABdEQAAXREAAGYRAABnEQAAXREAAGcRAABeEQAAXhEAAGcRAABoEQAAXhEAAGgRAABhEQAAYREAAGgRAABpEQAAYREAAGkRAABqEQAAXxEAAGERAABqEQAAXxEAAGoRAABrEQAAYBEAAF8RAABrEQAAYBEAAGsRAABsEQAAXxAAAGARAABsEQAAXxAAAGwRAABgEAAAXhAAAFwRAABgEQAAXhAAAGARAABfEAAAXRAAAFkRAABcEQAAXRAAAFwRAABeEAAAbREAAG4RAABvEQAAbREAAG8RAABwEQAAbhEAAHERAAByEQAAbhEAAHIRAABvEQAAcBEAAG8RAABzEQAAcBEAAHMRAAB0EQAAbxEAAHIRAAB1EQAAbxEAAHURAABzEQAA2RAAAHYRAABtEQAA2RAAAG0RAADaEAAAdhEAAHcRAABuEQAAdhEAAG4RAABtEQAAdxEAAHgRAABxEQAAdxEAAHERAABuEQAAeBEAAHkRAAB6EQAAeBEAAHoRAABxEQAAcREAAHoRAAB7EQAAcREAAHsRAAByEQAAchEAAHsRAAB8EQAAchEAAHwRAAB1EQAAdREAAHwRAAB9EQAAdREAAH0RAAB+EQAAcxEAAHURAAB+EQAAcxEAAH4RAAB/EQAAdBEAAHMRAAB/EQAAdBEAAH8RAACAEQAA3BAAAHQRAACAEQAA3BAAAIARAADdEAAA2xAAAHARAAB0EQAA2xAAAHQRAADcEAAA2hAAAG0RAABwEQAA2hAAAHARAADbEAAAgREAAIIRAACDEQAAgREAAIMRAACEEQAAghEAAIURAACGEQAAghEAAIYRAACDEQAAhBEAAIMRAACHEQAAhBEAAIcRAACIEQAAgxEAAIYRAACJEQAAgxEAAIkRAACHEQAAihEAAIsRAACBEQAAihEAAIERAACMEQAAixEAAI0RAACCEQAAixEAAIIRAACBEQAAjREAAI4RAACFEQAAjREAAIURAACCEQAAjhEAADoRAAA8EQAAjhEAADwRAACFEQAAhREAADwRAABEEQAAhREAAEQRAACGEQAAhhEAAEQRAABCEQAAhhEAAEIRAACJEQAAiREAAEIRAABDEQAAiREAAEMRAACPEQAAhxEAAIkRAACPEQAAhxEAAI8RAACQEQAAiBEAAIcRAACQEQAAiBEAAJARAACREQAAkhEAAIgRAACREQAAkhEAAJERAACTEQAAlBEAAIQRAACIEQAAlBEAAIgRAACSEQAAjBEAAIERAACEEQAAjBEAAIQRAACUEQAAlREAAJYRAACXEQAAlREAAJcRAACYEQAAlhEAAJkRAACaEQAAlhEAAJoRAACXEQAAmBEAAJcRAACbEQAAmBEAAJsRAACcEQAAlxEAAJoRAACdEQAAlxEAAJ0RAACbEQAAnhEAAJ8RAACVEQAAnhEAAJURAACgEQAAnxEAAKERAACWEQAAnxEAAJYRAACVEQAAoREAAKIRAACZEQAAoREAAJkRAACWEQAAohEAAK4QAACwEAAAohEAALAQAACZEQAAmREAALAQAAC4EAAAmREAALgQAACaEQAAmhEAALgQAAC2EAAAmhEAALYQAACdEQAAnREAALYQAAC3EAAAnREAALcQAACjEQAAmxEAAJ0RAACjEQAAmxEAAKMRAACkEQAAnBEAAJsRAACkEQAAnBEAAKQRAAClEQAAphEAAJwRAAClEQAAphEAAKURAACnEQAAqBEAAJgRAACcEQAAqBEAAJwRAACmEQAAoBEAAJURAACYEQAAoBEAAJgRAACoEQAAqREAAKoRAACrEQAAqREAAKsRAACsEQAAqhEAAK0RAACuEQAAqhEAAK4RAACrEQAArBEAAKsRAACvEQAArBEAAK8RAACwEQAAqxEAAK4RAACxEQAAqxEAALERAACvEQAAshEAALMRAACpEQAAshEAAKkRAAC0EQAAsxEAALURAACqEQAAsxEAAKoRAACpEQAAtREAALYRAACtEQAAtREAAK0RAACqEQAAthEAAMIQAADEEAAAthEAAMQQAACtEQAArREAAMQQAADMEAAArREAAMwQAACuEQAArhEAAMwQAADKEAAArhEAAMoQAACxEQAAsREAAMoQAADLEAAAsREAAMsQAAC3EQAArxEAALERAAC3EQAArxEAALcRAAC4EQAAsBEAAK8RAAC4EQAAsBEAALgRAAC5EQAAuhEAALARAAC5EQAAuhEAALkRAAC7EQAAvBEAAKwRAACwEQAAvBEAALARAAC6EQAAtBEAAKkRAACsEQAAtBEAAKwRAAC8EQAAvREAAL4RAAC/EQAAvREAAL8RAADAEQAAvhEAAMERAADCEQAAvhEAAMIRAAC/EQAAwBEAAL8RAADDEQAAwBEAAMMRAADEEQAAvxEAAMIRAADFEQAAvxEAAMURAADDEQAAiRAAAMYRAAC9EQAAiRAAAL0RAACKEAAAxhEAAMcRAAC+EQAAxhEAAL4RAAC9EQAAxxEAAMgRAADBEQAAxxEAAMERAAC+EQAAyBEAAIoRAACMEQAAyBEAAIwRAADBEQAAwREAAIwRAACUEQAAwREAAJQRAADCEQAAwhEAAJQRAACSEQAAwhEAAJIRAADFEQAAxREAAJIRAACTEQAAxREAAJMRAADJEQAAwxEAAMURAADJEQAAwxEAAMkRAADKEQAAxBEAAMMRAADKEQAAxBEAAMoRAADLEQAAjBAAAMQRAADLEQAAjBAAAMsRAACNEAAAixAAAMARAADEEQAAixAAAMQRAACMEAAAihAAAL0RAADAEQAAihAAAMARAACLEAAAzBEAAM0RAADOEQAAzBEAAM4RAADPEQAAzREAANARAADREQAAzREAANERAADOEQAAzxEAAM4RAADSEQAAzxEAANIRAADTEQAAzhEAANERAADUEQAAzhEAANQRAADSEQAAeREAANURAADMEQAAeREAAMwRAAB6EQAA1REAANYRAADNEQAA1REAAM0RAADMEQAA1hEAANcRAADQEQAA1hEAANARAADNEQAA1xEAANgRAADZEQAA1xEAANkRAADQEQAA0BEAANkRAADaEQAA0BEAANoRAADREQAA0REAANoRAADbEQAA0REAANsRAADUEQAA1BEAANsRAADcEQAA1BEAANwRAADdEQAA0hEAANQRAADdEQAA0hEAAN0RAADeEQAA0xEAANIRAADeEQAA0xEAAN4RAADfEQAAfBEAANMRAADfEQAAfBEAAN8RAAB9EQAAexEAAM8RAADTEQAAexEAANMRAAB8EQAAehEAAMwRAADPEQAAehEAAM8RAAB7EQAA4BEAAOERAADiEQAA4BEAAOIRAADjEQAA4REAAOQRAADlEQAA4REAAOURAADiEQAA4xEAAOIRAADmEQAA4xEAAOYRAADnEQAA4hEAAOURAADoEQAA4hEAAOgRAADmEQAA6REAAOoRAADgEQAA6REAAOARAADrEQAA6hEAAOwRAADhEQAA6hEAAOERAADgEQAA7BEAAO0RAADkEQAA7BEAAOQRAADhEQAA7REAAOoQAADsEAAA7REAAOwQAADkEQAA5BEAAOwQAAD0EAAA5BEAAPQQAADlEQAA5REAAPQQAADyEAAA5REAAPIQAADoEQAA6BEAAPIQAADzEAAA6BEAAPMQAADuEQAA5hEAAOgRAADuEQAA5hEAAO4RAADvEQAA5xEAAOYRAADvEQAA5xEAAO8RAADwEQAA8REAAOcRAADwEQAA8REAAPARAADyEQAA8xEAAOMRAADnEQAA8xEAAOcRAADxEQAA6xEAAOARAADjEQAA6xEAAOMRAADzEQAA9BEAAPURAAD2EQAA9BEAAPYRAAD3EQAA9REAAPgRAAD5EQAA9REAAPkRAAD2EQAA9xEAAPYRAAD6EQAA9xEAAPoRAAD7EQAA9hEAAPkRAAD8EQAA9hEAAPwRAAD6EQAA/REAAP4RAAD0EQAA/REAAPQRAAD/EQAA/hEAAAASAAD1EQAA/hEAAPURAAD0EQAAABIAAAESAAD4EQAAABIAAPgRAAD1EQAAARIAAP4QAAAAEQAAARIAAAARAAD4EQAA+BEAAAARAAAIEQAA+BEAAAgRAAD5EQAA+REAAAgRAAAGEQAA+REAAAYRAAD8EQAA/BEAAAYRAAAHEQAA/BEAAAcRAAACEgAA+hEAAPwRAAACEgAA+hEAAAISAAADEgAA+xEAAPoRAAADEgAA+xEAAAMSAAAEEgAABRIAAPsRAAAEEgAABRIAAAQSAAAGEgAABxIAAPcRAAD7EQAABxIAAPsRAAAFEgAA/xEAAPQRAAD3EQAA/xEAAPcRAAAHEgAACBIAAAkSAAAKEgAACBIAAAoSAAALEgAACRIAAAwSAAANEgAACRIAAA0SAAAKEgAACxIAAAoSAAAOEgAACxIAAA4SAAAPEgAAChIAAA0SAAAQEgAAChIAABASAAAOEgAAFREAABESAAAIEgAAFREAAAgSAAAWEQAAERIAABISAAAJEgAAERIAAAkSAAAIEgAAEhIAABMSAAAMEgAAEhIAAAwSAAAJEgAAExIAABQSAAAVEgAAExIAABUSAAAMEgAADBIAABUSAAAWEgAADBIAABYSAAANEgAADRIAABYSAAAXEgAADRIAABcSAAAQEgAAEBIAABcSAAAYEgAAEBIAABgSAAAZEgAADhIAABASAAAZEgAADhIAABkSAAAaEgAADxIAAA4SAAAaEgAADxIAABoSAAAbEgAAGBEAAA8SAAAbEgAAGBEAABsSAAAZEQAAFxEAAAsSAAAPEgAAFxEAAA8SAAAYEQAAFhEAAAgSAAALEgAAFhEAAAsSAAAXEQAAHBIAAB0SAAAeEgAAHBIAAB4SAAAfEgAAHRIAACASAAAhEgAAHRIAACESAAAeEgAAHxIAAB4SAAAiEgAAHxIAACISAAAjEgAAHhIAACESAAAkEgAAHhIAACQSAAAiEgAAKREAACUSAAAcEgAAKREAABwSAAAqEQAAJRIAACYSAAAdEgAAJRIAAB0SAAAcEgAAJhIAACcSAAAgEgAAJhIAACASAAAdEgAAJxIAACgSAAApEgAAJxIAACkSAAAgEgAAIBIAACkSAAAqEgAAIBIAACoSAAAhEgAAIRIAACoSAAArEgAAIRIAACsSAAAkEgAAJBIAACsSAAAsEgAAJBIAACwSAAAtEgAAIhIAACQSAAAtEgAAIhIAAC0SAAAuEgAAIxIAACISAAAuEgAAIxIAAC4SAAAvEgAALBEAACMSAAAvEgAALBEAAC8SAAAtEQAAKxEAAB8SAAAjEgAAKxEAACMSAAAsEQAAKhEAABwSAAAfEgAAKhEAAB8SAAArEQAAMBIAADESAAAyEgAAMBIAADISAAAzEgAAMRIAADQSAAA1EgAAMRIAADUSAAAyEgAAMxIAADISAAA2EgAAMxIAADYSAAA3EgAAMhIAADUSAAA4EgAAMhIAADgSAAA2EgAAUREAADkSAAAwEgAAUREAADASAABSEQAAORIAADoSAAAxEgAAORIAADESAAAwEgAAOhIAADsSAAA0EgAAOhIAADQSAAAxEgAAOxIAADwSAAA9EgAAOxIAAD0SAAA0EgAANBIAAD0SAAA+EgAANBIAAD4SAAA1EgAANRIAAD4SAAA/EgAANRIAAD8SAAA4EgAAOBIAAD8SAABAEgAAOBIAAEASAABBEgAANhIAADgSAABBEgAANhIAAEESAABCEgAANxIAADYSAABCEgAANxIAAEISAABDEgAAVBEAADcSAABDEgAAVBEAAEMSAABVEQAAUxEAADMSAAA3EgAAUxEAADcSAABUEQAAUhEAADASAAAzEgAAUhEAADMSAABTEQAARBIAAEUSAABGEgAARBIAAEYSAABHEgAARRIAAEgSAABJEgAARRIAAEkSAABGEgAARxIAAEYSAABKEgAARxIAAEoSAABLEgAARhIAAEkSAABMEgAARhIAAEwSAABKEgAA2BEAAE0SAABEEgAA2BEAAEQSAADZEQAATRIAAE4SAABFEgAATRIAAEUSAABEEgAAThIAAE8SAABIEgAAThIAAEgSAABFEgAATxIAAFASAABREgAATxIAAFESAABIEgAASBIAAFESAABSEgAASBIAAFISAABJEgAASRIAAFISAABTEgAASRIAAFMSAABMEgAATBIAAFMSAABUEgAATBIAAFQSAABVEgAAShIAAEwSAABVEgAAShIAAFUSAABWEgAASxIAAEoSAABWEgAASxIAAFYSAABXEgAA2xEAAEsSAABXEgAA2xEAAFcSAADcEQAA2hEAAEcSAABLEgAA2hEAAEsSAADbEQAA2REAAEQSAABHEgAA2REAAEcSAADaEQAAWBIAAFkSAABaEgAAWBIAAFoSAABbEgAAWRIAAFwSAABdEgAAWRIAAF0SAABaEgAAWxIAAFoSAABeEgAAWxIAAF4SAABfEgAAWhIAAF0SAABgEgAAWhIAAGASAABeEgAAYRIAAGISAABYEgAAYRIAAFgSAABjEgAAYhIAAGQSAABZEgAAYhIAAFkSAABYEgAAZBIAAGUSAABcEgAAZBIAAFwSAABZEgAAZRIAAAkQAAALEAAAZRIAAAsQAABcEgAAXBIAAAsQAAATEAAAXBIAABMQAABdEgAAXRIAABMQAAAREAAAXRIAABEQAABgEgAAYBIAABEQAAASEAAAYBIAABIQAABmEgAAXhIAAGASAABmEgAAXhIAAGYSAABnEgAAXxIAAF4SAABnEgAAXxIAAGcSAABoEgAAaRIAAF8SAABoEgAAaRIAAGgSAABqEgAAaxIAAFsSAABfEgAAaxIAAF8SAABpEgAAYxIAAFgSAABbEgAAYxIAAFsSAABrEgAAbBIAAG0SAABuEgAAbBIAAG4SAABvEgAAbRIAAHASAABxEgAAbRIAAHESAABuEgAAbxIAAG4SAAByEgAAbxIAAHISAABzEgAAbhIAAHESAAB0EgAAbhIAAHQSAAByEgAAUg0AAHUSAABsEgAAUg0AAGwSAABTDQAAdRIAAHYSAABtEgAAdRIAAG0SAABsEgAAdhIAAHcSAABwEgAAdhIAAHASAABtEgAAdxIAAHgSAAB5EgAAdxIAAHkSAABwEgAAcBIAAHkSAAB6EgAAcBIAAHoSAABxEgAAcRIAAHoSAAB7EgAAcRIAAHsSAAB0EgAAdBIAAHsSAAB8EgAAdBIAAHwSAAB9EgAAchIAAHQSAAB9EgAAchIAAH0SAAB+EgAAcxIAAHISAAB+EgAAcxIAAH4SAAB/EgAAVQ0AAHMSAAB/EgAAVQ0AAH8SAABWDQAAVA0AAG8SAABzEgAAVA0AAHMSAABVDQAAUw0AAGwSAABvEgAAUw0AAG8SAABUDQAAgBIAAIESAACCEgAAgBIAAIISAACDEgAAgRIAAIQSAACFEgAAgRIAAIUSAACCEgAAgxIAAIISAACGEgAAgxIAAIYSAACHEgAAghIAAIUSAACIEgAAghIAAIgSAACGEgAAbA8AAIkSAACAEgAAbA8AAIASAABtDwAAiRIAAIoSAACBEgAAiRIAAIESAACAEgAAihIAAIsSAACEEgAAihIAAIQSAACBEgAAixIAAIwSAACNEgAAixIAAI0SAACEEgAAhBIAAI0SAACOEgAAhBIAAI4SAACFEgAAhRIAAI4SAACPEgAAhRIAAI8SAACIEgAAiBIAAI8SAACQEgAAiBIAAJASAACREgAAhhIAAIgSAACREgAAhhIAAJESAACSEgAAhxIAAIYSAACSEgAAhxIAAJISAACTEgAAbw8AAIcSAACTEgAAbw8AAJMSAABwDwAAbg8AAIMSAACHEgAAbg8AAIcSAABvDwAAbQ8AAIASAACDEgAAbQ8AAIMSAABuDwAAlBIAAJUSAACWEgAAlBIAAJYSAACXEgAAlRIAAJgSAACZEgAAlRIAAJkSAACWEgAAlxIAAJYSAACaEgAAlxIAAJoSAACbEgAAlhIAAJkSAACcEgAAlhIAAJwSAACaEgAAnRIAAJ4SAACUEgAAnRIAAJQSAACfEgAAnhIAAKASAACVEgAAnhIAAJUSAACUEgAAoBIAAKESAACYEgAAoBIAAJgSAACVEgAAoRIAAJ4RAACgEQAAoRIAAKARAACYEgAAmBIAAKARAACoEQAAmBIAAKgRAACZEgAAmRIAAKgRAACmEQAAmRIAAKYRAACcEgAAnBIAAKYRAACnEQAAnBIAAKcRAACiEgAAmhIAAJwSAACiEgAAmhIAAKISAACjEgAAmxIAAJoSAACjEgAAmxIAAKMSAACkEgAApRIAAJsSAACkEgAApRIAAKQSAACmEgAApxIAAJcSAACbEgAApxIAAJsSAAClEgAAnxIAAJQSAACXEgAAnxIAAJcSAACnEgAAqBIAAKkSAACqEgAAqBIAAKoSAACrEgAAqRIAAKwSAACtEgAAqRIAAK0SAACqEgAAqxIAAKoSAACuEgAAqxIAAK4SAACvEgAAqhIAAK0SAACwEgAAqhIAALASAACuEgAAUBIAALESAACoEgAAUBIAAKgSAABREgAAsRIAALISAACpEgAAsRIAAKkSAACoEgAAshIAALMSAACsEgAAshIAAKwSAACpEgAAsxIAALQSAAC1EgAAsxIAALUSAACsEgAArBIAALUSAAC2EgAArBIAALYSAACtEgAArRIAALYSAAC3EgAArRIAALcSAACwEgAAsBIAALcSAAC4EgAAsBIAALgSAAC5EgAArhIAALASAAC5EgAArhIAALkSAAC6EgAArxIAAK4SAAC6EgAArxIAALoSAAC7EgAAUxIAAK8SAAC7EgAAUxIAALsSAABUEgAAUhIAAKsSAACvEgAAUhIAAK8SAABTEgAAURIAAKgSAACrEgAAURIAAKsSAABSEgAAvBIAAL0SAAC+EgAAvBIAAL4SAAC/EgAAvRIAAMASAADBEgAAvRIAAMESAAC+EgAAvxIAAL4SAADCEgAAvxIAAMISAADDEgAAvhIAAMESAADEEgAAvhIAAMQSAADCEgAAxRIAAMYSAAC8EgAAxRIAALwSAADHEgAAxhIAAMgSAAC9EgAAxhIAAL0SAAC8EgAAyBIAAMkSAADAEgAAyBIAAMASAAC9EgAAyRIAAOkRAADrEQAAyRIAAOsRAADAEgAAwBIAAOsRAADzEQAAwBIAAPMRAADBEgAAwRIAAPMRAADxEQAAwRIAAPERAADEEgAAxBIAAPERAADyEQAAxBIAAPIRAADKEgAAwhIAAMQSAADKEgAAwhIAAMoSAADLEgAAwxIAAMISAADLEgAAwxIAAMsSAADMEgAAzRIAAMMSAADMEgAAzRIAAMwSAADOEgAAzxIAAL8SAADDEgAAzxIAAMMSAADNEgAAxxIAALwSAAC/EgAAxxIAAL8SAADPEgAA0BIAANESAADSEgAA0BIAANISAADTEgAA0RIAANQSAADVEgAA0RIAANUSAADSEgAA0xIAANISAADWEgAA0xIAANYSAADXEgAA0hIAANUSAADYEgAA0hIAANgSAADWEgAAFBIAANkSAADQEgAAFBIAANASAAAVEgAA2RIAANoSAADREgAA2RIAANESAADQEgAA2hIAANsSAADUEgAA2hIAANQSAADREgAA2xIAANwSAADdEgAA2xIAAN0SAADUEgAA1BIAAN0SAADeEgAA1BIAAN4SAADVEgAA1RIAAN4SAADfEgAA1RIAAN8SAADYEgAA2BIAAN8SAADgEgAA2BIAAOASAADhEgAA1hIAANgSAADhEgAA1hIAAOESAADiEgAA1xIAANYSAADiEgAA1xIAAOISAADjEgAAFxIAANcSAADjEgAAFxIAAOMSAAAYEgAAFhIAANMSAADXEgAAFhIAANcSAAAXEgAAFRIAANASAADTEgAAFRIAANMSAAAWEgAA5BIAAOUSAADmEgAA5BIAAOYSAADnEgAA5RIAAOgSAADpEgAA5RIAAOkSAADmEgAA5xIAAOYSAADqEgAA5xIAAOoSAADrEgAA5hIAAOkSAADsEgAA5hIAAOwSAADqEgAA7RIAAO4SAADkEgAA7RIAAOQSAADvEgAA7hIAAPASAADlEgAA7hIAAOUSAADkEgAA8BIAAPESAADoEgAA8BIAAOgSAADlEgAA8RIAAGYNAABoDQAA8RIAAGgNAADoEgAA6BIAAGgNAAB1DQAA6BIAAHUNAADpEgAA6RIAAHUNAABzDQAA6RIAAHMNAADsEgAA7BIAAHMNAAB0DQAA7BIAAHQNAADyEgAA6hIAAOwSAADyEgAA6hIAAPISAADzEgAA6xIAAOoSAADzEgAA6xIAAPMSAAD0EgAA9RIAAOsSAAD0EgAA9RIAAPQSAAD2EgAA9xIAAOcSAADrEgAA9xIAAOsSAAD1EgAA7xIAAOQSAADnEgAA7xIAAOcSAAD3EgAA+BIAAPkSAAD6EgAA+BIAAPoSAAD7EgAA+RIAAPwSAAD9EgAA+RIAAP0SAAD6EgAA+xIAAPoSAAD+EgAA+xIAAP4SAAD/EgAA+hIAAP0SAAAAEwAA+hIAAAATAAD+EgAAPBIAAAETAAD4EgAAPBIAAPgSAAA9EgAAARMAAAITAAD5EgAAARMAAPkSAAD4EgAAAhMAAAMTAAD8EgAAAhMAAPwSAAD5EgAAAxMAAAQTAAAFEwAAAxMAAAUTAAD8EgAA/BIAAAUTAAAGEwAA/BIAAAYTAAD9EgAA/RIAAAYTAAAHEwAA/RIAAAcTAAAAEwAAABMAAAcTAAAIEwAAABMAAAgTAAAJEwAA/hIAAAATAAAJEwAA/hIAAAkTAAAKEwAA/xIAAP4SAAAKEwAA/xIAAAoTAAALEwAAPxIAAP8SAAALEwAAPxIAAAsTAABAEgAAPhIAAPsSAAD/EgAAPhIAAP8SAAA/EgAAPRIAAPgSAAD7EgAAPRIAAPsSAAA+EgAADBMAAA0TAAAOEwAADBMAAA4TAAAPEwAADRMAABATAAAREwAADRMAABETAAAOEwAADxMAAA4TAAASEwAADxMAABITAAATEwAADhMAABETAAAUEwAADhMAABQTAAASEwAAZREAABUTAAAMEwAAZREAAAwTAABmEQAAFRMAABYTAAANEwAAFRMAAA0TAAAMEwAAFhMAABcTAAAQEwAAFhMAABATAAANEwAAFxMAABgTAAAZEwAAFxMAABkTAAAQEwAAEBMAABkTAAAaEwAAEBMAABoTAAAREwAAERMAABoTAAAbEwAAERMAABsTAAAUEwAAFBMAABsTAAAcEwAAFBMAABwTAAAdEwAAEhMAABQTAAAdEwAAEhMAAB0TAAAeEwAAExMAABITAAAeEwAAExMAAB4TAAAfEwAAaBEAABMTAAAfEwAAaBEAAB8TAABpEQAAZxEAAA8TAAATEwAAZxEAABMTAABoEQAAZhEAAAwTAAAPEwAAZhEAAA8TAABnEQAAIBMAACETAAAiEwAAIBMAACITAAAjEwAAIRMAACQTAAAlEwAAIRMAACUTAAAiEwAAIxMAACITAAAmEwAAIxMAACYTAAAnEwAAIhMAACUTAAAoEwAAIhMAACgTAAAmEwAAKRMAACoTAAAgEwAAKRMAACATAAArEwAAKhMAACwTAAAhEwAAKhMAACETAAAgEwAALBMAAC0TAAAkEwAALBMAACQTAAAhEwAALRMAALIRAAC0EQAALRMAALQRAAAkEwAAJBMAALQRAAC8EQAAJBMAALwRAAAlEwAAJRMAALwRAAC6EQAAJRMAALoRAAAoEwAAKBMAALoRAAC7EQAAKBMAALsRAAAuEwAAJhMAACgTAAAuEwAAJhMAAC4TAAAvEwAAJxMAACYTAAAvEwAAJxMAAC8TAAAwEwAAMRMAACcTAAAwEwAAMRMAADATAAAyEwAAMxMAACMTAAAnEwAAMxMAACcTAAAxEwAAKxMAACATAAAjEwAAKxMAACMTAAAzEwAANBMAADUTAAA2EwAANBMAADYTAAA3EwAANRMAADgTAAA5EwAANRMAADkTAAA2EwAANxMAADYTAAA6EwAANxMAADoTAAA7EwAANhMAADkTAAA8EwAANhMAADwTAAA6EwAAxQ0AAD0TAAA0EwAAxQ0AADQTAADGDQAAPRMAAD4TAAA1EwAAPRMAADUTAAA0EwAAPhMAAD8TAAA4EwAAPhMAADgTAAA1EwAAPxMAAEATAABBEwAAPxMAAEETAAA4EwAAOBMAAEETAABCEwAAOBMAAEITAAA5EwAAORMAAEITAABDEwAAORMAAEMTAAA8EwAAPBMAAEMTAABEEwAAPBMAAEQTAABFEwAAOhMAADwTAABFEwAAOhMAAEUTAABGEwAAOxMAADoTAABGEwAAOxMAAEYTAABHEwAAyA0AADsTAABHEwAAyA0AAEcTAADJDQAAxw0AADcTAAA7EwAAxw0AADsTAADIDQAAxg0AADQTAAA3EwAAxg0AADcTAADHDQAASBMAAEkTAABKEwAASBMAAEoTAABLEwAASRMAAEwTAABNEwAASRMAAE0TAABKEwAASxMAAEoTAABOEwAASxMAAE4TAABPEwAAShMAAE0TAABQEwAAShMAAFATAABOEwAAKBIAAFETAABIEwAAKBIAAEgTAAApEgAAURMAAFITAABJEwAAURMAAEkTAABIEwAAUhMAAFMTAABMEwAAUhMAAEwTAABJEwAAUxMAAFQTAABVEwAAUxMAAFUTAABMEwAATBMAAFUTAABWEwAATBMAAFYTAABNEwAATRMAAFYTAABXEwAATRMAAFcTAABQEwAAUBMAAFcTAABYEwAAUBMAAFgTAABZEwAAThMAAFATAABZEwAAThMAAFkTAABaEwAATxMAAE4TAABaEwAATxMAAFoTAABbEwAAKxIAAE8TAABbEwAAKxIAAFsTAAAsEgAAKhIAAEsTAABPEwAAKhIAAE8TAAArEgAAKRIAAEgTAABLEwAAKRIAAEsTAAAqEgAAXBMAAF0TAABeEwAAXBMAAF4TAABfEwAAXRMAAGATAABhEwAAXRMAAGETAABeEwAAXxMAAF4TAABiEwAAXxMAAGITAABjEwAAXhMAAGETAABkEwAAXhMAAGQTAABiEwAAZRMAAGYTAABcEwAAZRMAAFwTAABnEwAAZhMAAGgTAABdEwAAZhMAAF0TAABcEwAAaBMAAGkTAABgEwAAaBMAAGATAABdEwAAaRMAAC4OAAAwDgAAaRMAADAOAABgEwAAYBMAADAOAAA4DgAAYBMAADgOAABhEwAAYRMAADgOAAA2DgAAYRMAADYOAABkEwAAZBMAADYOAAA3DgAAZBMAADcOAABqEwAAYhMAAGQTAABqEwAAYhMAAGoTAABrEwAAYxMAAGITAABrEwAAYxMAAGsTAABsEwAAbRMAAGMTAABsEwAAbRMAAGwTAABuEwAAbxMAAF8TAABjEwAAbxMAAGMTAABtEwAAZxMAAFwTAABfEwAAZxMAAF8TAABvEwAAcBMAAHETAAByEwAAcBMAAHITAABzEwAAcRMAAHQTAAB1EwAAcRMAAHUTAAByEwAAcxMAAHITAAB2EwAAcxMAAHYTAAB3EwAAchMAAHUTAAB4EwAAchMAAHgTAAB2EwAAeRMAAHoTAABwEwAAeRMAAHATAAB7EwAAehMAAHwTAABxEwAAehMAAHETAABwEwAAfBMAAH0TAAB0EwAAfBMAAHQTAABxEwAAfRMAAJ0SAACfEgAAfRMAAJ8SAAB0EwAAdBMAAJ8SAACnEgAAdBMAAKcSAAB1EwAAdRMAAKcSAAClEgAAdRMAAKUSAAB4EwAAeBMAAKUSAACmEgAAeBMAAKYSAAB+EwAAdhMAAHgTAAB+EwAAdhMAAH4TAAB/EwAAdxMAAHYTAAB/EwAAdxMAAH8TAACAEwAAgRMAAHcTAACAEwAAgRMAAIATAACCEwAAgxMAAHMTAAB3EwAAgxMAAHcTAACBEwAAexMAAHATAABzEwAAexMAAHMTAACDEwAAhBMAAIUTAACGEwAAhBMAAIYTAACHEwAAhRMAAIgTAACJEwAAhRMAAIkTAACGEwAAhxMAAIYTAACKEwAAhxMAAIoTAACLEwAAhhMAAIkTAACMEwAAhhMAAIwTAACKEwAAtBIAAI0TAACEEwAAtBIAAIQTAAC1EgAAjRMAAI4TAACFEwAAjRMAAIUTAACEEwAAjhMAAI8TAACIEwAAjhMAAIgTAACFEwAAjxMAAJATAACREwAAjxMAAJETAACIEwAAiBMAAJETAACSEwAAiBMAAJITAACJEwAAiRMAAJITAACTEwAAiRMAAJMTAACMEwAAjBMAAJMTAACUEwAAjBMAAJQTAACVEwAAihMAAIwTAACVEwAAihMAAJUTAACWEwAAixMAAIoTAACWEwAAixMAAJYTAACXEwAAtxIAAIsTAACXEwAAtxIAAJcTAAC4EgAAthIAAIcTAACLEwAAthIAAIsTAAC3EgAAtRIAAIQTAACHEwAAtRIAAIcTAAC2EgAAmBMAAJkTAACaEwAAmBMAAJoTAACbEwAAmRMAAJwTAACdEwAAmRMAAJ0TAACaEwAAmxMAAJoTAACeEwAAmxMAAJ4TAACfEwAAmhMAAJ0TAACgEwAAmhMAAKATAACeEwAAoRMAAKITAACYEwAAoRMAAJgTAACjEwAAohMAAKQTAACZEwAAohMAAJkTAACYEwAApBMAAKUTAACcEwAApBMAAJwTAACZEwAApRMAAMUSAADHEgAApRMAAMcSAACcEwAAnBMAAMcSAADPEgAAnBMAAM8SAACdEwAAnRMAAM8SAADNEgAAnRMAAM0SAACgEwAAoBMAAM0SAADOEgAAoBMAAM4SAACmEwAAnhMAAKATAACmEwAAnhMAAKYTAACnEwAAnxMAAJ4TAACnEwAAnxMAAKcTAACoEwAAqRMAAJ8TAACoEwAAqRMAAKgTAACqEwAAqxMAAJsTAACfEwAAqxMAAJ8TAACpEwAAoxMAAJgTAACbEwAAoxMAAJsTAACrEwAArBMAAK0TAACuEwAArBMAAK4TAACvEwAArRMAALATAACxEwAArRMAALETAACuEwAArxMAAK4TAACyEwAArxMAALITAACzEwAArhMAALETAAC0EwAArhMAALQTAACyEwAAtRMAALYTAACsEwAAtRMAAKwTAAC3EwAAthMAALgTAACtEwAAthMAAK0TAACsEwAAuBMAALkTAACwEwAAuBMAALATAACtEwAAuRMAAP0RAAD/EQAAuRMAAP8RAACwEwAAsBMAAP8RAAAHEgAAsBMAAAcSAACxEwAAsRMAAAcSAAAFEgAAsRMAAAUSAAC0EwAAtBMAAAUSAAAGEgAAtBMAAAYSAAC6EwAAshMAALQTAAC6EwAAshMAALoTAAC7EwAAsxMAALITAAC7EwAAsxMAALsTAAC8EwAAvRMAALMTAAC8EwAAvRMAALwTAAC+EwAAvxMAAK8TAACzEwAAvxMAALMTAAC9EwAAtxMAAKwTAACvEwAAtxMAAK8TAAC/EwAAwBMAAMETAADCEwAAwBMAAMITAADDEwAAwRMAAMQTAADFEwAAwRMAAMUTAADCEwAAwxMAAMITAADGEwAAwxMAAMYTAADHEwAAwhMAAMUTAADIEwAAwhMAAMgTAADGEwAA3BIAAMkTAADAEwAA3BIAAMATAADdEgAAyRMAAMoTAADBEwAAyRMAAMETAADAEwAAyhMAAMsTAADEEwAAyhMAAMQTAADBEwAAyxMAAMwTAADNEwAAyxMAAM0TAADEEwAAxBMAAM0TAADOEwAAxBMAAM4TAADFEwAAxRMAAM4TAADPEwAAxRMAAM8TAADIEwAAyBMAAM8TAADQEwAAyBMAANATAADREwAAxhMAAMgTAADREwAAxhMAANETAADSEwAAxxMAAMYTAADSEwAAxxMAANITAADTEwAA3xIAAMcTAADTEwAA3xIAANMTAADgEgAA3hIAAMMTAADHEwAA3hIAAMcTAADfEgAA3RIAAMATAADDEwAA3RIAAMMTAADeEgAA1BMAANUTAADWEwAA1BMAANYTAADXEwAA1RMAANgTAADZEwAA1RMAANkTAADWEwAA1xMAANYTAADaEwAA1xMAANoTAADbEwAA1hMAANkTAADcEwAA1hMAANwTAADaEwAA3RMAAN4TAADUEwAA3RMAANQTAADfEwAA3hMAAOATAADVEwAA3hMAANUTAADUEwAA4BMAAOETAADYEwAA4BMAANgTAADVEwAA4RMAAO0SAADvEgAA4RMAAO8SAADYEwAA2BMAAO8SAAD3EgAA2BMAAPcSAADZEwAA2RMAAPcSAAD1EgAA2RMAAPUSAADcEwAA3BMAAPUSAAD2EgAA3BMAAPYSAADiEwAA2hMAANwTAADiEwAA2hMAAOITAADjEwAA2xMAANoTAADjEwAA2xMAAOMTAADkEwAA5RMAANsTAADkEwAA5RMAAOQTAADmEwAA5xMAANcTAADbEwAA5xMAANsTAADlEwAA3xMAANQTAADXEwAA3xMAANcTAADnEwAA6BMAAOkTAADqEwAA6BMAAOoTAADrEwAA6RMAAOwTAADtEwAA6RMAAO0TAADqEwAA6xMAAOoTAADuEwAA6xMAAO4TAADvEwAA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SxQAADsUAAA/FAAASxQAAD8UAABJFAAAQxQAADgUAAA7FAAAQxQAADsUAABLFAAATBQAAE0UAABOFAAATBQAAE4UAABPFAAATRQAAFAUAABRFAAATRQAAFEUAABOFAAATxQAAE4UAABSFAAATxQAAFIUAABTFAAAThQAAFEUAABUFAAAThQAAFQUAABSFAAAVRQAAFYUAABMFAAAVRQAAEwUAABXFAAAVhQAAFgUAABNFAAAVhQAAE0UAABMFAAAWBQAAFkUAABQFAAAWBQAAFAUAABNFAAAWRQAAHkTAAB7EwAAWRQAAHsTAABQFAAAUBQAAHsTAACDEwAAUBQAAIMTAABRFAAAURQAAIMTAACBEwAAURQAAIETAABUFAAAVBQAAIETAACCEwAAVBQAAIITAABaFAAAUhQAAFQUAABaFAAAUhQAAFoUAABbFAAAUxQAAFIUAABbFAAAUxQAAFsUAABcFAAAXRQAAFMUAABcFAAAXRQAAFwUAABeFAAAXxQAAE8UAABTFAAAXxQAAFMUAABdFAAAVxQAAEwUAABPFAAAVxQAAE8UAABfFAAAYBQAAGEUAABiFAAAYBQAAGIUAABjFAAAYRQAAGQUAABlFAAAYRQAAGUUAABiFAAAYxQAAGIUAABmFAAAYxQAAGYUAABnFAAAYhQAAGUUAABoFAAAYhQAAGgUAABmFAAAaRQAAGoUAABgFAAAaRQAAGAUAABrFAAAahQAAGwUAABhFAAAahQAAGEUAABgFAAAbBQAAG0UAABkFAAAbBQAAGQUAABhFAAAbRQAACkTAAArEwAAbRQAACsTAABkFAAAZBQAACsTAAAzEwAAZBQAADMTAABlFAAAZRQAADMTAAAxEwAAZRQAADETAABoFAAAaBQAADETAAAyEwAAaBQAADITAABuFAAAZhQAAGgUAABuFAAAZhQAAG4UAABvFAAAZxQAAGYUAABvFAAAZxQAAG8UAABwFAAAcRQAAGcUAABwFAAAcRQAAHAUAAByFAAAcxQAAGMUAABnFAAAcxQAAGcUAABxFAAAaxQAAGAUAABjFAAAaxQAAGMUAABzFAAAdBQAAHUUAAB2FAAAdBQAAHYUAAB3FAAAdRQAAHgUAAB5FAAAdRQAAHkUAAB2FAAAdxQAAHYUAAB6FAAAdxQAAHoUAAB7FAAAdhQAAHkUAAB8FAAAdhQAAHwUAAB6FAAAkBMAAH0UAAB0FAAAkBMAAHQUAACREwAAfRQAAH4UAAB1FAAAfRQAAHUUAAB0FAAAfhQAAH8UAAB4FAAAfhQAAHgUAAB1FAAAfxQAAIAUAACBFAAAfxQAAIEUAAB4FAAAeBQAAIEUAACCFAAAeBQAAIIUAAB5FAAAeRQAAIIUAACDFAAAeRQAAIMUAAB8FAAAfBQAAIMUAACEFAAAfBQAAIQUAACFFAAAehQAAHwUAACFFAAAehQAAIUUAACGFAAAexQAAHoUAACGFAAAexQAAIYUAACHFAAAkxMAAHsUAACHFAAAkxMAAIcUAACUEwAAkhMAAHcUAAB7FAAAkhMAAHsUAACTEwAAkRMAAHQUAAB3FAAAkRMAAHcUAACSEwAAiBQAAIkUAACKFAAAiBQAAIoUAACLFAAAiRQAAIwUAACNFAAAiRQAAI0UAACKFAAAixQAAIoUAACOFAAAixQAAI4UAACPFAAAihQAAI0UAACQFAAAihQAAJAUAACOFAAAkRQAAJIUAACIFAAAkRQAAIgUAACTFAAAkhQAAJQUAACJFAAAkhQAAIkUAACIFAAAlBQAAJUUAACMFAAAlBQAAIwUAACJFAAAlRQAAKETAACjEwAAlRQAAKMTAACMFAAAjBQAAKMTAACrEwAAjBQAAKsTAACNFAAAjRQAAKsTAACpEwAAjRQAAKkTAACQFAAAkBQAAKkTAACqEwAAkBQAAKoTAACWFAAAjhQAAJAUAACWFAAAjhQAAJYUAACXFAAAjxQAAI4UAACXFAAAjxQAAJcUAACYFAAAmRQAAI8UAACYFAAAmRQAAJgUAACaFAAAmxQAAIsUAACPFAAAmxQAAI8UAACZFAAAkxQAAIgUAACLFAAAkxQAAIsUAACbFAAAnBQAAJ0UAACeFAAAnBQAAJ4UAACfFAAAnRQAAKAUAAChFAAAnRQAAKEUAACeFAAAnxQAAJ4UAACiFAAAnxQAAKIUAACjFAAAnhQAAKEUAACkFAAAnhQAAKQUAACiFAAApRQAAKYUAACcFAAApRQAAJwUAACnFAAAphQAAKgUAACdFAAAphQAAJ0UAACcFAAAqBQAAKkUAACgFAAAqBQAAKAUAACdFAAAqRQAALUTAAC3EwAAqRQAALcTAACgFAAAoBQAALcTAAC/EwAAoBQAAL8TAAChFAAAoRQAAL8TAAC9EwAAoRQAAL0TAACkFAAApBQAAL0TAAC+EwAApBQAAL4TAACqFAAAohQAAKQUAACqFAAAohQAAKoUAACrFAAAoxQAAKIUAACrFAAAoxQAAKsUAACsFAAArRQAAKMUAACsFAAArRQAAKwUAACuFAAArxQAAJ8UAACjFAAArxQAAKMUAACtFAAApxQAAJwUAACfFAAApxQAAJ8UAACvFAAAsBQAALEUAACyFAAAsBQAALIUAACzFAAAsRQAALQUAAC1FAAAsRQAALUUAACyFAAAsxQAALIUAAC2FAAAsxQAALYUAAC3FAAAshQAALUUAAC4FAAAshQAALgUAAC2FAAAzBMAALkUAACwFAAAzBMAALAUAADNEwAAuRQAALoUAACxFAAAuRQAALEUAACwFAAAuhQAALsUAAC0FAAAuhQAALQUAACxFAAAuxQAALwUAAC9FAAAuxQAAL0UAAC0FAAAtBQAAL0UAAC+FAAAtBQAAL4UAAC1FAAAtRQAAL4UAAC/FAAAtRQAAL8UAAC4FAAAuBQAAL8UAADAFAAAuBQAAMAUAADBFAAAthQAALgUAADBFAAAthQAAMEUAADCFAAAtxQAALYUAADCFAAAtxQAAMIUAADDFAAAzxMAALcUAADDFAAAzxMAAMMUAADQEwAAzhMAALMUAAC3FAAAzhMAALcUAADPEwAAzRMAALAUAACzFAAAzRMAALMUAADOEwAAxBQAAMUUAADGFAAAxBQAAMYUAADHFAAAxRQAAMgUAADJFAAAxRQAAMkUAADGFAAAxxQAAMYUAADKFAAAxxQAAMoUAADLFAAAxhQAAMkUAADMFAAAxhQAAMwUAADKFAAAVBMAAM0UAADEFAAAVBMAAMQUAABVEwAAzRQAAM4UAADFFAAAzRQAAMUUAADEFAAAzhQAAM8UAADIFAAAzhQAAMgUAADFFAAAzxQAANAUAADRFAAAzxQAANEUAADIFAAAyBQAANEUAADSFAAAyBQAANIUAADJFAAAyRQAANIUAADTFAAAyRQAANMUAADMFAAAzBQAANMUAADUFAAAzBQAANQUAADVFAAAyhQAAMwUAADVFAAAyhQAANUUAADWFAAAyxQAAMoUAADWFAAAyxQAANYUAADXFAAAVxMAAMsUAADXFAAAVxMAANcUAABYEwAAVhMAAMcUAADLFAAAVhMAAMsUAABXEwAAVRMAAMQUAADHFAAAVRMAAMcUAABWEwAA2BQAANkUAADaFAAA2BQAANoUAADbFAAA2RQAANwUAADdFAAA2RQAAN0UAADaFAAA2xQAANoUAADeFAAA2xQAAN4UAADfFAAA2hQAAN0UAADgFAAA2hQAAOAUAADeFAAA4RQAAOIUAADYFAAA4RQAANgUAADjFAAA4hQAAOQUAADZFAAA4hQAANkUAADYFAAA5BQAAOUUAADcFAAA5BQAANwUAADZFAAA5RQAAN0TAADfEwAA5RQAAN8TAADcFAAA3BQAAN8TAADnEwAA3BQAAOcTAADdFAAA3RQAAOcTAADlEwAA3RQAAOUTAADgFAAA4BQAAOUTAADmEwAA4BQAAOYTAADmFAAA3hQAAOAUAADmFAAA3hQAAOYUAADnFAAA3xQAAN4UAADnFAAA3xQAAOcUAADoFAAA6RQAAN8UAADoFAAA6RQAAOgUAADqFAAA6xQAANsUAADfFAAA6xQAAN8UAADpFAAA4xQAANgUAADbFAAA4xQAANsUAADrFAAA7BQAAO0UAADuFAAA7BQAAO4UAADvFAAA7RQAAPAUAADxFAAA7RQAAPEUAADuFAAA7xQAAO4UAADyFAAA7xQAAPIUAADzFAAA7hQAAPEUAAD0FAAA7hQAAPQUAADyFAAA9BMAAPUUAADsFAAA9BMAAOwUAAD1EwAA9RQAAPYUAADtFAAA9RQAAO0UAADsFAAA9hQAAPcUAADwFAAA9hQAAPAUAADtFAAA9xQAAPgUAAD5FAAA9xQAAPkUAADwFAAA8BQAAPkUAAD6FAAA8BQAAPoUAADxFAAA8RQAAPoUAAD7FAAA8RQAAPsUAAD0FAAA9BQAAPsUAAD8FAAA9BQAAPwUAAD9FAAA8hQAAPQUAAD9FAAA8hQAAP0UAAD+FAAA8xQAAPIUAAD+FAAA8xQAAP4UAAD/FAAA9xMAAPMUAAD/FAAA9xMAAP8UAAD4EwAA9hMAAO8UAADzFAAA9hMAAPMUAAD3EwAA9RMAAOwUAADvFAAA9RMAAO8UAAD2EwAAABUAAAEVAAACFQAAABUAAAIVAAADFQAAARUAAAQVAAAFFQAAARUAAAUVAAACFQAAAxUAAAIVAAAGFQAAAxUAAAYVAAAHFQAAAhUAAAUVAAAIFQAAAhUAAAgVAAAGFQAACBQAAAkVAAAAFQAACBQAAAAVAAAJFAAACRUAAAoVAAABFQAACRUAAAEVAAAAFQAAChUAAAsVAAAEFQAAChUAAAQVAAABFQAACxUAAAwVAAANFQAACxUAAA0VAAAEFQAABBUAAA0VAAAOFQAABBUAAA4VAAAFFQAABRUAAA4VAAAPFQAABRUAAA8VAAAIFQAACBUAAA8VAAAQFQAACBUAABAVAAARFQAABhUAAAgVAAARFQAABhUAABEVAAASFQAABxUAAAYVAAASFQAABxUAABIVAAATFQAACxQAAAcVAAATFQAACxQAABMVAAAMFAAAChQAAAMVAAAHFQAAChQAAAcVAAALFAAACRQAAAAVAAADFQAACRQAAAMVAAAKFAAAFBUAABUVAAAWFQAAFBUAABYVAAAXFQAAFRUAABgVAAAZFQAAFRUAABkVAAAWFQAAFxUAABYVAAAaFQAAFxUAABoVAAAbFQAAFhUAABkVAAAcFQAAFhUAABwVAAAaFQAAMBQAAB0VAAAUFQAAMBQAABQVAAAxFAAAHRUAAB4VAAAVFQAAHRUAABUVAAAUFQAAHhUAAB8VAAAYFQAAHhUAABgVAAAVFQAAHxUAACAVAAAhFQAAHxUAACEVAAAYFQAAGBUAACEVAAAiFQAAGBUAACIVAAAZFQAAGRUAACIVAAAjFQAAGRUAACMVAAAcFQAAHBUAACMVAAAkFQAAHBUAACQVAAAlFQAAGhUAABwVAAAlFQAAGhUAACUVAAAmFQAAGxUAABoVAAAmFQAAGxUAACYVAAAnFQAAMxQAABsVAAAnFQAAMxQAACcVAAA0FAAAMhQAABcVAAAbFQAAMhQAABsVAAAzFAAAMRQAABQVAAAXFQAAMRQAABcVAAAyFAAAKBUAACkVAAAqFQAAKBUAACoVAAArFQAAKRUAACwVAAAtFQAAKRUAAC0VAAAqFQAAKxUAACoVAAAuFQAAKxUAAC4VAAAvFQAAKhUAAC0VAAAwFQAAKhUAADAVAAAuFQAAeBIAADEVAAAoFQAAeBIAACgVAAB5EgAAMRUAADIVAAApFQAAMRUAACkVAAAoFQAAMhUAADMVAAAsFQAAMhUAACwVAAApFQAAMxUAADQVAAA1FQAAMxUAADUVAAAsFQAALBUAADUVAAA2FQAALBUAADYVAAAtFQAALRUAADYVAAA3FQAALRUAADcVAAAwFQAAMBUAADcVAAA4FQAAMBUAADgVAAA5FQAALhUAADAVAAA5FQAALhUAADkVAAA6FQAALxUAAC4VAAA6FQAALxUAADoVAAA7FQAAexIAAC8VAAA7FQAAexIAADsVAAB8EgAAehIAACsVAAAvFQAAehIAAC8VAAB7EgAAeRIAACgVAAArFQAAeRIAACsVAAB6EgAAPBUAAD0VAAA+FQAAPBUAAD4VAAA/FQAAPRUAAEAVAABBFQAAPRUAAEEVAAA+FQAAPxUAAD4VAABCFQAAPxUAAEIVAABDFQAAPhUAAEEVAABEFQAAPhUAAEQVAABCFQAARRUAAEYVAAA8FQAARRUAADwVAABHFQAARhUAAEgVAAA9FQAARhUAAD0VAAA8FQAASBUAAEkVAABAFQAASBUAAEAVAAA9FQAASRUAAEEUAABDFAAASRUAAEMUAABAFQAAQBUAAEMUAABLFAAAQBUAAEsUAABBFQAAQRUAAEsUAABJFAAAQRUAAEkUAABEFQAARBUAAEkUAABKFAAARBUAAEoUAABKFQAAQhUAAEQVAABKFQAAQhUAAEoVAABLFQAAQxUAAEIVAABLFQAAQxUAAEsVAABMFQAATRUAAEMVAABMFQAATRUAAEwVAABOFQAATxUAAD8VAABDFQAATxUAAEMVAABNFQAARxUAADwVAAA/FQAARxUAAD8VAABPFQAAUBUAAFEVAABSFQAAUBUAAFIVAABTFQAAURUAAFQVAABVFQAAURUAAFUVAABSFQAAUxUAAFIVAABWFQAAUxUAAFYVAABXFQAAUhUAAFUVAABYFQAAUhUAAFgVAABWFQAAWRUAAFoVAABQFQAAWRUAAFAVAABbFQAAWhUAAFwVAABRFQAAWhUAAFEVAABQFQAAXBUAAF0VAABUFQAAXBUAAFQVAABRFQAAXRUAAFUUAABXFAAAXRUAAFcUAABUFQAAVBUAAFcUAABfFAAAVBUAAF8UAABVFQAAVRUAAF8UAABdFAAAVRUAAF0UAABYFQAAWBUAAF0UAABeFAAAWBUAAF4UAABeFQAAVhUAAFgVAABeFQAAVhUAAF4VAABfFQAAVxUAAFYVAABfFQAAVxUAAF8VAABgFQAAYRUAAFcVAABgFQAAYRUAAGAVAABiFQAAYxUAAFMVAABXFQAAYxUAAFcVAABhFQAAWxUAAFAVAABTFQAAWxUAAFMVAABjFQAAZBUAAGUVAABmFQAAZBUAAGYVAABnFQAAZRUAAGgVAABpFQAAZRUAAGkVAABmFQAAZxUAAGYVAABqFQAAZxUAAGoVAABrFQAAZhUAAGkVAABsFQAAZhUAAGwVAABqFQAAgBQAAG0VAABkFQAAgBQAAGQVAACBFAAAbRUAAG4VAABlFQAAbRUAAGUVAABkFQAAbhUAAG8VAABoFQAAbhUAAGgVAABlFQAAbxUAAHAVAABxFQAAbxUAAHEVAABoFQAAaBUAAHEVAAByFQAAaBUAAHIVAABpFQAAaRUAAHIVAABzFQAAaRUAAHMVAABsFQAAbBUAAHMVAAB0FQAAbBUAAHQVAAB1FQAAahUAAGwVAAB1FQAAahUAAHUVAAB2FQAAaxUAAGoVAAB2FQAAaxUAAHYVAAB3FQAAgxQAAGsVAAB3FQAAgxQAAHcVAACEFAAAghQAAGcVAABrFQAAghQAAGsVAACDFAAAgRQAAGQVAABnFQAAgRQAAGcVAACCFAAAeBUAAHkVAAB6FQAAeBUAAHoVAAB7FQAAeRUAAHwVAAB9FQAAeRUAAH0VAAB6FQAAexUAAHoVAAB+FQAAexUAAH4VAAB/FQAAehUAAH0VAACAFQAAehUAAIAVAAB+FQAAgRUAAIIVAAB4FQAAgRUAAHgVAACDFQAAghUAAIQVAAB5FQAAghUAAHkVAAB4FQAAhBUAAIUVAAB8FQAAhBUAAHwVAAB5FQAAhRUAAJEUAACTFAAAhRUAAJMUAAB8FQAAfBUAAJMUAACbFAAAfBUAAJsUAAB9FQAAfRUAAJsUAACZFAAAfRUAAJkUAACAFQAAgBUAAJkUAACaFAAAgBUAAJoUAACGFQAAfhUAAIAVAACGFQAAfhUAAIYVAACHFQAAfxUAAH4VAACHFQAAfxUAAIcVAACIFQAAiRUAAH8VAACIFQAAiRUAAIgVAACKFQAAixUAAHsVAAB/FQAAixUAAH8VAACJFQAAgxUAAHgVAAB7FQAAgxUAAHsVAACLFQAAjBUAAI0VAACOFQAAjBUAAI4VAACPFQAAjRUAAJAVAACRFQAAjRUAAJEVAACOFQAAjxUAAI4VAACSFQAAjxUAAJIVAACTFQAAjhUAAJEVAACUFQAAjhUAAJQVAACSFQAAlRUAAJYVAACMFQAAlRUAAIwVAACXFQAAlhUAAJgVAACNFQAAlhUAAI0VAACMFQAAmBUAAJkVAACQFQAAmBUAAJAVAACNFQAAmRUAAKUUAACnFAAAmRUAAKcUAACQFQAAkBUAAKcUAACvFAAAkBUAAK8UAACRFQAAkRUAAK8UAACtFAAAkRUAAK0UAACUFQAAlBUAAK0UAACuFAAAlBUAAK4UAACaFQAAkhUAAJQVAACaFQAAkhUAAJoVAACbFQAAkxUAAJIVAACbFQAAkxUAAJsVAACcFQAAnRUAAJMVAACcFQAAnRUAAJwVAACeFQAAnxUAAI8VAACTFQAAnxUAAJMVAACdFQAAlxUAAIwVAACPFQAAlxUAAI8VAACfFQAAoBUAAKEVAACiFQAAoBUAAKIVAACjFQAAoRUAAKQVAAClFQAAoRUAAKUVAACiFQAAoxUAAKIVAACmFQAAoxUAAKYVAACnFQAAohUAAKUVAACoFQAAohUAAKgVAACmFQAAvBQAAKkVAACgFQAAvBQAAKAVAAC9FAAAqRUAAKoVAAChFQAAqRUAAKEVAACgFQAAqhUAAKsVAACkFQAAqhUAAKQVAAChFQAAqxUAAKwVAACtFQAAqxUAAK0VAACkFQAApBUAAK0VAACuFQAApBUAAK4VAAClFQAApRUAAK4VAACvFQAApRUAAK8VAACoFQAAqBUAAK8VAACwFQAAqBUAALAVAACxFQAAphUAAKgVAACxFQAAphUAALEVAACyFQAApxUAAKYVAACyFQAApxUAALIVAACzFQAAvxQAAKcVAACzFQAAvxQAALMVAADAFAAAvhQAAKMVAACnFQAAvhQAAKcVAAC/FAAAvRQAAKAVAACjFQAAvRQAAKMVAAC+FAAAtBUAALUVAAC2FQAAtBUAALYVAAC3FQAAtRUAALgVAAC5FQAAtRUAALkVAAC2FQAAtxUAALYVAAC6FQAAtxUAALoVAAC7FQAAthUAALkVAAC8FQAAthUAALwVAAC6FQAAvRUAAL4VAAC0FQAAvRUAALQVAAC/FQAAvhUAAMAVAAC1FQAAvhUAALUVAAC0FQAAwBUAAMEVAAC4FQAAwBUAALgVAAC1FQAAwRUAAOEUAADjFAAAwRUAAOMUAAC4FQAAuBUAAOMUAADrFAAAuBUAAOsUAAC5FQAAuRUAAOsUAADpFAAAuRUAAOkUAAC8FQAAvBUAAOkUAADqFAAAvBUAAOoUAADCFQAAuhUAALwVAADCFQAAuhUAAMIVAADDFQAAuxUAALoVAADDFQAAuxUAAMMVAADEFQAAxRUAALsVAADEFQAAxRUAAMQVAADGFQAAxxUAALcVAAC7FQAAxxUAALsVAADFFQAAvxUAALQVAAC3FQAAvxUAALcVAADHFQAAyBUAAMkVAADKFQAAyBUAAMoVAADLFQAAyRUAAMwVAADNFQAAyRUAAM0VAADKFQAAyxUAAMoVAADOFQAAyxUAAM4VAADPFQAAyhUAAM0VAADQFQAAyhUAANAVAADOFQAA+BQAANEVAADIFQAA+BQAAMgVAAD5FAAA0RUAANIVAADJFQAA0RUAAMkVAADIFQAA0hUAANMVAADMFQAA0hUAAMwVAADJFQAA0xUAANQVAADVFQAA0xUAANUVAADMFQAAzBUAANUVAADWFQAAzBUAANYVAADNFQAAzRUAANYVAADXFQAAzRUAANcVAADQFQAA0BUAANcVAADYFQAA0BUAANgVAADZFQAAzhUAANAVAADZFQAAzhUAANkVAADaFQAAzxUAAM4VAADaFQAAzxUAANoVAADbFQAA+xQAAM8VAADbFQAA+xQAANsVAAD8FAAA+hQAAMsVAADPFQAA+hQAAM8VAAD7FAAA+RQAAMgVAADLFQAA+RQAAMsVAAD6FAAA3BUAAN0VAADeFQAA3BUAAN4VAADfFQAA3RUAAOAVAADhFQAA3RUAAOEVAADeFQAA3xUAAN4VAADiFQAA3xUAAOIVAADjFQAA3hUAAOEVAADkFQAA3hUAAOQVAADiFQAANgsAAOUVAADcFQAANgsAANwVAAA3CwAA5RUAAOYVAADdFQAA5RUAAN0VAADcFQAA5hUAAOcVAADgFQAA5hUAAOAVAADdFQAA5xUAAGkUAABrFAAA5xUAAGsUAADgFQAA4BUAAGsUAABzFAAA4BUAAHMUAADhFQAA4RUAAHMUAABxFAAA4RUAAHEUAADkFQAA5BUAAHEUAAByFAAA5BUAAHIUAADoFQAA4hUAAOQVAADoFQAA4hUAAOgVAADpFQAA4xUAAOIVAADpFQAA4xUAAOkVAADqFQAAOQsAAOMVAADqFQAAOQsAAOoVAAA6CwAAOAsAAN8VAADjFQAAOAsAAOMVAAA5CwAANwsAANwVAADfFQAANwsAAN8VAAA4CwAA6xUAAOwVAADtFQAA6xUAAO0VAADuFQAA7BUAAO8VAADwFQAA7BUAAPAVAADtFQAA7hUAAO0VAADxFQAA7hUAAPEVAADyFQAA7RUAAPAVAADzFQAA7RUAAPMVAADxFQAAIBUAAPQVAADrFQAAIBUAAOsVAAAhFQAA9BUAAPUVAADsFQAA9BUAAOwVAADrFQAA9RUAAPYVAADvFQAA9RUAAO8VAADsFQAA9hUAAPcVAAD4FQAA9hUAAPgVAADvFQAA7xUAAPgVAAD5FQAA7xUAAPkVAADwFQAA8BUAAPkVAAD6FQAA8BUAAPoVAADzFQAA8xUAAPoVAAD7FQAA8xUAAPsVAAD8FQAA8RUAAPMVAAD8FQAA8RUAAPwVAAD9FQAA8hUAAPEVAAD9FQAA8hUAAP0VAAD+FQAAIxUAAPIVAAD+FQAAIxUAAP4VAAAkFQAAIhUAAO4VAADyFQAAIhUAAPIVAAAjFQAAIRUAAOsVAADuFQAAIRUAAO4VAAAiFQAA/xUAAAAWAAABFgAA/xUAAAEWAAACFgAAABYAAAMWAAAEFgAAABYAAAQWAAABFgAAAhYAAAEWAAAFFgAAAhYAAAUWAAAGFgAAARYAAAQWAAAHFgAAARYAAAcWAAAFFgAAaw0AAAgWAAD/FQAAaw0AAP8VAABsDQAACBYAAAkWAAAAFgAACBYAAAAWAAD/FQAACRYAAAoWAAADFgAACRYAAAMWAAAAFgAAChYAAGESAABjEgAAChYAAGMSAAADFgAAAxYAAGMSAABrEgAAAxYAAGsSAAAEFgAABBYAAGsSAABpEgAABBYAAGkSAAAHFgAABxYAAGkSAABqEgAABxYAAGoSAAALFgAABRYAAAcWAAALFgAABRYAAAsWAAAMFgAABhYAAAUWAAAMFgAABhYAAAwWAAANFgAAbg0AAAYWAAANFgAAbg0AAA0WAABvDQAAbQ0AAAIWAAAGFgAAbQ0AAAYWAABuDQAAbA0AAP8VAAACFgAAbA0AAAIWAABtDQAADhYAAA8WAAAQFgAADhYAABAWAAARFgAADxYAABIWAAATFgAADxYAABMWAAAQFgAAERYAABAWAAAUFgAAERYAABQWAAAVFgAAEBYAABMWAAAWFgAAEBYAABYWAAAUFgAA0BQAABcWAAAOFgAA0BQAAA4WAADRFAAAFxYAABgWAAAPFgAAFxYAAA8WAAAOFgAAGBYAABkWAAASFgAAGBYAABIWAAAPFgAAGRYAAHwLAAB+CwAAGRYAAH4LAAASFgAAEhYAAH4LAACLCwAAEhYAAIsLAAATFgAAExYAAIsLAACJCwAAExYAAIkLAAAWFgAAFhYAAIkLAACKCwAAFhYAAIoLAAAaFgAAFBYAABYWAAAaFgAAFBYAABoWAAAbFgAAFRYAABQWAAAbFgAAFRYAABsWAAAcFgAA0xQAABUWAAAcFgAA0xQAABwWAADUFAAA0hQAABEWAAAVFgAA0hQAABUWAADTFAAA0RQAAA4WAAARFgAA0RQAABEWAADSFAAAHRYAAB4WAAAfFgAAHRYAAB8WAAAgFgAAHhYAACEWAAAiFgAAHhYAACIWAAAfFgAAIBYAAB8WAAAjFgAAIBYAACMWAAAkFgAAHxYAACIWAAAlFgAAHxYAACUWAAAjFgAAJhYAACcWAAAdFgAAJhYAAB0WAAAoFgAAJxYAACkWAAAeFgAAJxYAAB4WAAAdFgAAKRYAACoWAAAhFgAAKRYAACEWAAAeFgAAKhYAAEUVAABHFQAAKhYAAEcVAAAhFgAAIRYAAEcVAABPFQAAIRYAAE8VAAAiFgAAIhYAAE8VAABNFQAAIhYAAE0VAAAlFgAAJRYAAE0VAABOFQAAJRYAAE4VAAArFgAAIxYAACUWAAArFgAAIxYAACsWAAAsFgAAJBYAACMWAAAsFgAAJBYAACwWAAAtFgAALhYAACQWAAAtFgAALhYAAC0WAAAvFgAAMBYAACAWAAAkFgAAMBYAACQWAAAuFgAAKBYAAB0WAAAgFgAAKBYAACAWAAAwFgAAMRYAADIWAAAzFgAAMRYAADMWAAA0FgAAMhYAADUWAAA2FgAAMhYAADYWAAAzFgAANBYAADMWAAA3FgAANBYAADcWAAA4FgAAMxYAADYWAAA5FgAAMxYAADkWAAA3FgAAjBIAADoWAAAxFgAAjBIAADEWAACNEgAAOhYAADsWAAAyFgAAOhYAADIWAAAxFgAAOxYAADwWAAA1FgAAOxYAADUWAAAyFgAAPBYAAMANAADCDQAAPBYAAMINAAA1FgAANRYAAMINAADPDQAANRYAAM8NAAA2FgAANhYAAM8NAADNDQAANhYAAM0NAAA5FgAAORYAAM0NAADODQAAORYAAM4NAAA9FgAANxYAADkWAAA9FgAANxYAAD0WAAA+FgAAOBYAADcWAAA+FgAAOBYAAD4WAAA/FgAAjxIAADgWAAA/FgAAjxIAAD8WAACQEgAAjhIAADQWAAA4FgAAjhIAADgWAACPEgAAjRIAADEWAAA0FgAAjRIAADQWAACOEgAAQBYAAEEWAABCFgAAQBYAAEIWAABDFgAAQRYAAEQWAABFFgAAQRYAAEUWAABCFgAAQxYAAEIWAABGFgAAQxYAAEYWAABHFgAAQhYAAEUWAABIFgAAQhYAAEgWAABGFgAASRYAAEoWAABAFgAASRYAAEAWAABLFgAAShYAAEwWAABBFgAAShYAAEEWAABAFgAATBYAAE0WAABEFgAATBYAAEQWAABBFgAATRYAAFkVAABbFQAATRYAAFsVAABEFgAARBYAAFsVAABjFQAARBYAAGMVAABFFgAARRYAAGMVAABhFQAARRYAAGEVAABIFgAASBYAAGEVAABiFQAASBYAAGIVAABOFgAARhYAAEgWAABOFgAARhYAAE4WAABPFgAARxYAAEYWAABPFgAARxYAAE8WAABQFgAAURYAAEcWAABQFgAAURYAAFAWAABSFgAAUxYAAEMWAABHFgAAUxYAAEcWAABRFgAASxYAAEAWAABDFgAASxYAAEMWAABTFgAAVBYAAFUWAABWFgAAVBYAAFYWAABXFgAAVRYAAFgWAABZFgAAVRYAAFkWAABWFgAAVxYAAFYWAABaFgAAVxYAAFoWAABbFgAAVhYAAFkWAABcFgAAVhYAAFwWAABaFgAAcBUAAF0WAABUFgAAcBUAAFQWAABxFQAAXRYAAF4WAABVFgAAXRYAAFUWAABUFgAAXhYAAF8WAABYFgAAXhYAAFgWAABVFgAAXxYAAGAWAABhFgAAXxYAAGEWAABYFgAAWBYAAGEWAABiFgAAWBYAAGIWAABZFgAAWRYAAGIWAABjFgAAWRYAAGMWAABcFgAAXBYAAGMWAABkFgAAXBYAAGQWAABlFgAAWhYAAFwWAABlFgAAWhYAAGUWAABmFgAAWxYAAFoWAABmFgAAWxYAAGYWAABnFgAAcxUAAFsWAABnFgAAcxUAAGcWAAB0FQAAchUAAFcWAABbFgAAchUAAFsWAABzFQAAcRUAAFQWAABXFgAAcRUAAFcWAAByFQAAaBYAAGkWAABqFgAAaBYAAGoWAABrFgAAaRYAAGwWAABtFgAAaRYAAG0WAABqFgAAaxYAAGoWAABuFgAAaxYAAG4WAABvFgAAahYAAG0WAABwFgAAahYAAHAWAABuFgAAcRYAAHIWAABoFgAAcRYAAGgWAABzFgAAchYAAHQWAABpFgAAchYAAGkWAABoFgAAdBYAAHUWAABsFgAAdBYAAGwWAABpFgAAdRYAAIEVAACDFQAAdRYAAIMVAABsFgAAbBYAAIMVAACLFQAAbBYAAIsVAABtFgAAbRYAAIsVAACJFQAAbRYAAIkVAABwFgAAcBYAAIkVAACKFQAAcBYAAIoVAAB2FgAAbhYAAHAWAAB2FgAAbhYAAHYWAAB3FgAAbxYAAG4WAAB3FgAAbxYAAHcWAAB4FgAAeRYAAG8WAAB4FgAAeRYAAHgWAAB6FgAAexYAAGsWAABvFgAAexYAAG8WAAB5FgAAcxYAAGgWAABrFgAAcxYAAGsWAAB7FgAAfBYAAH0WAAB+FgAAfBYAAH4WAAB/FgAAfRYAAIAWAACBFgAAfRYAAIEWAAB+FgAAfxYAAH4WAACCFgAAfxYAAIIWAACDFgAAfhYAAIEWAACEFgAAfhYAAIQWAACCFgAArBUAAIUWAAB8FgAArBUAAHwWAACtFQAAhRYAAIYWAAB9FgAAhRYAAH0WAAB8FgAAhhYAAIcWAACAFgAAhhYAAIAWAAB9FgAAhxYAAIgWAACJFgAAhxYAAIkWAACAFgAAgBYAAIkWAACKFgAAgBYAAIoWAACBFgAAgRYAAIoWAACLFgAAgRYAAIsWAACEFgAAhBYAAIsWAACMFgAAhBYAAIwWAACNFgAAghYAAIQWAACNFgAAghYAAI0WAACOFgAAgxYAAIIWAACOFgAAgxYAAI4WAACPFgAArxUAAIMWAACPFgAArxUAAI8WAACwFQAArhUAAH8WAACDFgAArhUAAIMWAACvFQAArRUAAHwWAAB/FgAArRUAAH8WAACuFQAAkBYAAJEWAACSFgAAkBYAAJIWAACTFgAAkRYAAJQWAACVFgAAkRYAAJUWAACSFgAAkxYAAJIWAACWFgAAkxYAAJYWAACXFgAAkhYAAJUWAACYFgAAkhYAAJgWAACWFgAAmRYAAJoWAACQFgAAmRYAAJAWAACbFgAAmhYAAJwWAACRFgAAmhYAAJEWAACQFgAAnBYAAJ0WAACUFgAAnBYAAJQWAACRFgAAnRYAAL0VAAC/FQAAnRYAAL8VAACUFgAAlBYAAL8VAADHFQAAlBYAAMcVAACVFgAAlRYAAMcVAADFFQAAlRYAAMUVAACYFgAAmBYAAMUVAADGFQAAmBYAAMYVAACeFgAAlhYAAJgWAACeFgAAlhYAAJ4WAACfFgAAlxYAAJYWAACfFgAAlxYAAJ8WAACgFgAAoRYAAJcWAACgFgAAoRYAAKAWAACiFgAAoxYAAJMWAACXFgAAoxYAAJcWAAChFgAAmxYAAJAWAACTFgAAmxYAAJMWAACjFgAApBYAAKUWAACmFgAApBYAAKYWAACnFgAApRYAAKgWAACpFgAApRYAAKkWAACmFgAApxYAAKYWAACqFgAApxYAAKoWAACrFgAAphYAAKkWAACsFgAAphYAAKwWAACqFgAA1BUAAK0WAACkFgAA1BUAAKQWAADVFQAArRYAAK4WAAClFgAArRYAAKUWAACkFgAArhYAAK8WAACoFgAArhYAAKgWAAClFgAArxYAAE0NAABPDQAArxYAAE8NAACoFgAAqBYAAE8NAABcDQAAqBYAAFwNAACpFgAAqRYAAFwNAABaDQAAqRYAAFoNAACsFgAArBYAAFoNAABbDQAArBYAAFsNAACwFgAAqhYAAKwWAACwFgAAqhYAALAWAACxFgAAqxYAAKoWAACxFgAAqxYAALEWAACyFgAA1xUAAKsWAACyFgAA1xUAALIWAADYFQAA1hUAAKcWAACrFgAA1hUAAKsWAADXFQAA1RUAAKQWAACnFgAA1RUAAKcWAADWFQAAsxYAALQWAAC1FgAAsxYAALUWAAC2FgAAtBYAALcWAAC4FgAAtBYAALgWAAC1FgAAthYAALUWAAC5FgAAthYAALkWAAC6FgAAtRYAALgWAAC7FgAAtRYAALsWAAC5FgAADBUAALwWAACzFgAADBUAALMWAAANFQAAvBYAAL0WAAC0FgAAvBYAALQWAACzFgAAvRYAAL4WAAC3FgAAvRYAALcWAAC0FgAAvhYAAL8WAADAFgAAvhYAAMAWAAC3FgAAtxYAAMAWAADBFgAAtxYAAMEWAAC4FgAAuBYAAMEWAADCFgAAuBYAAMIWAAC7FgAAuxYAAMIWAADDFgAAuxYAAMMWAADEFgAAuRYAALsWAADEFgAAuRYAAMQWAADFFgAAuhYAALkWAADFFgAAuhYAAMUWAADGFgAADxUAALoWAADGFgAADxUAAMYWAAAQFQAADhUAALYWAAC6FgAADhUAALoWAAAPFQAADRUAALMWAAC2FgAADRUAALYWAAAOFQAAxxYAAMgWAADJFgAAxxYAAMkWAADKFgAAyBYAAMsWAADMFgAAyBYAAMwWAADJFgAAyhYAAMkWAADNFgAAyhYAAM0WAADOFgAAyRYAAMwWAADPFgAAyRYAAM8WAADNFgAAXQwAANAWAADHFgAAXQwAAMcWAABeDAAA0BYAANEWAADIFgAA0BYAAMgWAADHFgAA0RYAANIWAADLFgAA0RYAAMsWAADIFgAA0hYAABkUAAAbFAAA0hYAABsUAADLFgAAyxYAABsUAAAjFAAAyxYAACMUAADMFgAAzBYAACMUAAAhFAAAzBYAACEUAADPFgAAzxYAACEUAAAiFAAAzxYAACIUAADTFgAAzRYAAM8WAADTFgAAzRYAANMWAADUFgAAzhYAAM0WAADUFgAAzhYAANQWAADVFgAAYAwAAM4WAADVFgAAYAwAANUWAABhDAAAXwwAAMoWAADOFgAAXwwAAM4WAABgDAAAXgwAAMcWAADKFgAAXgwAAMoWAABfDAAA1hYAANcWAADYFgAA1hYAANgWAADZFgAA1xYAANoWAADbFgAA1xYAANsWAADYFgAA2RYAANgWAADcFgAA2RYAANwWAADdFgAA2BYAANsWAADeFgAA2BYAAN4WAADcFgAA9xUAAN8WAADWFgAA9xUAANYWAAD4FQAA3xYAAOAWAADXFgAA3xYAANcWAADWFgAA4BYAAOEWAADaFgAA4BYAANoWAADXFgAA4RYAAEoLAABMCwAA4RYAAEwLAADaFgAA2hYAAEwLAABZCwAA2hYAAFkLAADbFgAA2xYAAFkLAABXCwAA2xYAAFcLAADeFgAA3hYAAFcLAABYCwAA3hYAAFgLAADiFgAA3BYAAN4WAADiFgAA3BYAAOIWAADjFgAA3RYAANwWAADjFgAA3RYAAOMWAADkFgAA+hUAAN0WAADkFgAA+hUAAOQWAAD7FQAA+RUAANkWAADdFgAA+RUAAN0WAAD6FQAA+BUAANYWAADZFgAA+BUAANkWAAD5FQAA5RYAAOYWAADnFgAA5RYAAOcWAADoFgAA5hYAAOkWAADqFgAA5hYAAOoWAADnFgAA6BYAAOcWAADrFgAA6BYAAOsWAADsFgAA5xYAAOoWAADtFgAA5xYAAO0WAADrFgAANBUAAO4WAADlFgAANBUAAOUWAAA1FQAA7hYAAO8WAADmFgAA7hYAAOYWAADlFgAA7xYAAPAWAADpFgAA7xYAAOkWAADmFgAA8BYAAH8NAACBDQAA8BYAAIENAADpFgAA6RYAAIENAACODQAA6RYAAI4NAADqFgAA6hYAAI4NAACMDQAA6hYAAIwNAADtFgAA7RYAAIwNAACNDQAA7RYAAI0NAADxFgAA6xYAAO0WAADxFgAA6xYAAPEWAADyFgAA7BYAAOsWAADyFgAA7BYAAPIWAADzFgAANxUAAOwWAADzFgAANxUAAPMWAAA4FQAANhUAAOgWAADsFgAANhUAAOwWAAA3FQAANRUAAOUWAADoFgAANRUAAOgWAAA2FQAA9BYAAPUWAAD2FgAA9BYAAPYWAAD3FgAA9RYAAPgWAAD5FgAA9RYAAPkWAAD2FgAA9xYAAPYWAAD6FgAA9xYAAPoWAAD7FgAA9hYAAPkWAAD8FgAA9hYAAPwWAAD6FgAAmgsAAP0WAAD0FgAAmgsAAPQWAACbCwAA/RYAAP4WAAD1FgAA/RYAAPUWAAD0FgAA/hYAAP8WAAD4FgAA/hYAAPgWAAD1FgAA/xYAACYWAAAoFgAA/xYAACgWAAD4FgAA+BYAACgWAAAwFgAA+BYAADAWAAD5FgAA+RYAADAWAAAuFgAA+RYAAC4WAAD8FgAA/BYAAC4WAAAvFgAA/BYAAC8WAAAAFwAA+hYAAPwWAAAAFwAA+hYAAAAXAAABFwAA+xYAAPoWAAABFwAA+xYAAAEXAAACFwAAnQsAAPsWAAACFwAAnQsAAAIXAACeCwAAnAsAAPcWAAD7FgAAnAsAAPsWAACdCwAAmwsAAPQWAAD3FgAAmwsAAPcWAACcCwAAAxcAAAQXAAAFFwAAAxcAAAUXAAAGFwAABBcAAAcXAAAIFwAABBcAAAgXAAAFFwAABhcAAAUXAAAJFwAABhcAAAkXAAAKFwAABRcAAAgXAAALFwAABRcAAAsXAAAJFwAAswsAAAwXAAADFwAAswsAAAMXAAC0CwAADBcAAA0XAAAEFwAADBcAAAQXAAADFwAADRcAAA4XAAAHFwAADRcAAAcXAAAEFwAADhcAAEkWAABLFgAADhcAAEsWAAAHFwAABxcAAEsWAABTFgAABxcAAFMWAAAIFwAACBcAAFMWAABRFgAACBcAAFEWAAALFwAACxcAAFEWAABSFgAACxcAAFIWAAAPFwAACRcAAAsXAAAPFwAACRcAAA8XAAAQFwAAChcAAAkXAAAQFwAAChcAABAXAAARFwAAtgsAAAoXAAARFwAAtgsAABEXAAC3CwAAtQsAAAYXAAAKFwAAtQsAAAoXAAC2CwAAtAsAAAMXAAAGFwAAtAsAAAYXAAC1CwAAEhcAABMXAAAUFwAAEhcAABQXAAAVFwAAExcAABYXAAAXFwAAExcAABcXAAAUFwAAFRcAABQXAAAYFwAAFRcAABgXAAAZFwAAFBcAABcXAAAaFwAAFBcAABoXAAAYFwAAYBYAABsXAAASFwAAYBYAABIXAABhFgAAGxcAABwXAAATFwAAGxcAABMXAAASFwAAHBcAAB0XAAAWFwAAHBcAABYXAAATFwAAHRcAAMcLAADJCwAAHRcAAMkLAAAWFwAAFhcAAMkLAADWCwAAFhcAANYLAAAXFwAAFxcAANYLAADUCwAAFxcAANQLAAAaFwAAGhcAANQLAADVCwAAGhcAANULAAAeFwAAGBcAABoXAAAeFwAAGBcAAB4XAAAfFwAAGRcAABgXAAAfFwAAGRcAAB8XAAAgFwAAYxYAABkXAAAgFwAAYxYAACAXAABkFgAAYhYAABUXAAAZFwAAYhYAABkXAABjFgAAYRYAABIXAAAVFwAAYRYAABUXAABiFgAAIRcAACIXAAAjFwAAIRcAACMXAAAkFwAAIhcAACUXAAAmFwAAIhcAACYXAAAjFwAAJBcAACMXAAAnFwAAJBcAACcXAAAoFwAAIxcAACYXAAApFwAAIxcAACkXAAAnFwAAchAAACoXAAAhFwAAchAAACEXAABzEAAAKhcAACsXAAAiFwAAKhcAACIXAAAhFwAAKxcAACwXAAAlFwAAKxcAACUXAAAiFwAALBcAAHEWAABzFgAALBcAAHMWAAAlFwAAJRcAAHMWAAB7FgAAJRcAAHsWAAAmFwAAJhcAAHsWAAB5FgAAJhcAAHkWAAApFwAAKRcAAHkWAAB6FgAAKRcAAHoWAAAtFwAAJxcAACkXAAAtFwAAJxcAAC0XAAAuFwAAKBcAACcXAAAuFwAAKBcAAC4XAAAvFwAAdRAAACgXAAAvFwAAdRAAAC8XAAB2EAAAdBAAACQXAAAoFwAAdBAAACgXAAB1EAAAcxAAACEXAAAkFwAAcxAAACQXAAB0EAAAMBcAADEXAAAyFwAAMBcAADIXAAAzFwAAMRcAADQXAAA1FwAAMRcAADUXAAAyFwAAMxcAADIXAAA2FwAAMxcAADYXAAA3FwAAMhcAADUXAAA4FwAAMhcAADgXAAA2FwAA5QsAADkXAAAwFwAA5QsAADAXAADmCwAAORcAADoXAAAxFwAAORcAADEXAAAwFwAAOhcAADsXAAA0FwAAOhcAADQXAAAxFwAAOxcAAJUVAACXFQAAOxcAAJcVAAA0FwAANBcAAJcVAACfFQAANBcAAJ8VAAA1FwAANRcAAJ8VAACdFQAANRcAAJ0VAAA4FwAAOBcAAJ0VAACeFQAAOBcAAJ4VAAA8FwAANhcAADgXAAA8FwAANhcAADwXAAA9FwAANxcAADYXAAA9FwAANxcAAD0XAAA+FwAA6AsAADcXAAA+FwAA6AsAAD4XAADpCwAA5wsAADMXAAA3FwAA5wsAADcXAADoCwAA5gsAADAXAAAzFwAA5gsAADMXAADnCwAAPxcAAEAXAABBFwAAPxcAAEEXAABCFwAAQBcAAEMXAABEFwAAQBcAAEQXAABBFwAAQhcAAEEXAABFFwAAQhcAAEUXAABGFwAAQRcAAEQXAABHFwAAQRcAAEcXAABFFwAAiBYAAEgXAAA/FwAAiBYAAD8XAACJFgAASBcAAEkXAABAFwAASBcAAEAXAAA/FwAASRcAAEoXAABDFwAASRcAAEMXAABAFwAAShcAAPkLAAD7CwAAShcAAPsLAABDFwAAQxcAAPsLAAAIDAAAQxcAAAgMAABEFwAARBcAAAgMAAAGDAAARBcAAAYMAABHFwAARxcAAAYMAAAHDAAARxcAAAcMAABLFwAARRcAAEcXAABLFwAARRcAAEsXAABMFwAARhcAAEUXAABMFwAARhcAAEwXAABNFwAAixYAAEYXAABNFwAAixYAAE0XAACMFgAAihYAAEIXAABGFwAAihYAAEYXAACLFgAAiRYAAD8XAABCFwAAiRYAAEIXAACKFgAAThcAAE8XAABQFwAAThcAAFAXAABRFwAATxcAAFIXAABTFwAATxcAAFMXAABQFwAAURcAAFAXAABUFwAAURcAAFQXAABVFwAAUBcAAFMXAABWFwAAUBcAAFYXAABUFwAAFwwAAFcXAABOFwAAFwwAAE4XAAAYDAAAVxcAAFgXAABPFwAAVxcAAE8XAABOFwAAWBcAAFkXAABSFwAAWBcAAFIXAABPFwAAWRcAAJkWAACbFgAAWRcAAJsWAABSFwAAUhcAAJsWAACjFgAAUhcAAKMWAABTFwAAUxcAAKMWAAChFgAAUxcAAKEWAABWFwAAVhcAAKEWAACiFgAAVhcAAKIWAABaFwAAVBcAAFYXAABaFwAAVBcAAFoXAABbFwAAVRcAAFQXAABbFwAAVRcAAFsXAABcFwAAGgwAAFUXAABcFwAAGgwAAFwXAAAbDAAAGQwAAFEXAABVFwAAGQwAAFUXAAAaDAAAGAwAAE4XAABRFwAAGAwAAFEXAAAZDAAAXRcAAF4XAABfFwAAXRcAAF8XAABgFwAAXhcAAGEXAABiFwAAXhcAAGIXAABfFwAAYBcAAF8XAABjFwAAYBcAAGMXAABkFwAAXxcAAGIXAABlFwAAXxcAAGUXAABjFwAAZhcAAGcXAABdFwAAZhcAAF0XAABoFwAAZxcAAGkXAABeFwAAZxcAAF4XAABdFwAAaRcAAGoXAABhFwAAaRcAAGEXAABeFwAAahcAAD8MAABBDAAAahcAAEEMAABhFwAAYRcAAEEMAABODAAAYRcAAE4MAABiFwAAYhcAAE4MAABMDAAAYhcAAEwMAABlFwAAZRcAAEwMAABNDAAAZRcAAE0MAABrFwAAYxcAAGUXAABrFwAAYxcAAGsXAABsFwAAZBcAAGMXAABsFwAAZBcAAGwXAABtFwAAbhcAAGQXAABtFwAAbhcAAG0XAABvFwAAcBcAAGAXAABkFwAAcBcAAGQXAABuFwAAaBcAAF0XAABgFwAAaBcAAGAXAABwFwAAcRcAAHIXAABzFwAAcRcAAHMXAAB0FwAAchcAAHUXAAB2FwAAchcAAHYXAABzFwAAdBcAAHMXAAB3FwAAdBcAAHcXAAB4FwAAcxcAAHYXAAB5FwAAcxcAAHkXAAB3FwAAehcAAHsXAABxFwAAehcAAHEXAAB8FwAAexcAAH0XAAByFwAAexcAAHIXAABxFwAAfRcAAH4XAAB1FwAAfRcAAHUXAAByFwAAfhcAAH8XAACAFwAAfhcAAIAXAAB1FwAAdRcAAIAXAACBFwAAdRcAAIEXAAB2FwAAdhcAAIEXAACCFwAAdhcAAIIXAAB5FwAAeRcAAIIXAACDFwAAeRcAAIMXAABfFgAAdxcAAHkXAABfFgAAdxcAAF8WAABeFgAAeBcAAHcXAABeFgAAeBcAAF4WAACEFwAAhRcAAHgXAACEFwAAhRcAAIQXAABwFQAAhhcAAHQXAAB4FwAAhhcAAHgXAACFFwAAfBcAAHEXAAB0FwAAfBcAAHQXAACGFwAAhxcAAIgXAACJFwAAhxcAAIkXAACKFwAAiBcAAIsXAACMFwAAiBcAAIwXAACJFwAAihcAAIkXAACNFwAAihcAAI0XAACOFwAAiRcAAIwXAACPFwAAiRcAAI8XAACNFwAAkBcAAJEXAACHFwAAkBcAAIcXAACSFwAAkRcAAJMXAACIFwAAkRcAAIgXAACHFwAAkxcAAJQXAACLFwAAkxcAAIsXAACIFwAAlBcAAJUXAACWFwAAlBcAAJYXAACLFwAAixcAAJYXAACXFwAAixcAAJcXAACMFwAAjBcAAJcXAACYFwAAjBcAAJgXAACPFwAAjxcAAJgXAABZFQAAjxcAAFkVAABNFgAAjRcAAI8XAABNFgAAjRcAAE0WAACZFwAAjhcAAI0XAACZFwAAjhcAAJkXAACaFwAAmxcAAI4XAACaFwAAmxcAAJoXAACcFwAAnRcAAIoXAACOFwAAnRcAAI4XAACbFwAAkhcAAIcXAACKFwAAkhcAAIoXAACdFwAAnhcAAJ8XAACgFwAAnhcAAKAXAAChFwAAnxcAAKIXAACjFwAAnxcAAKMXAACgFwAAoRcAAKAXAACkFwAAoRcAAKQXAAClFwAAoBcAAKMXAACmFwAAoBcAAKYXAACkFwAApxcAAKgXAACeFwAApxcAAJ4XAACpFwAAqBcAAKoXAACfFwAAqBcAAJ8XAACeFwAAqhcAAKsXAACiFwAAqhcAAKIXAACfFwAAqxcAAKwXAACtFwAAqxcAAK0XAACiFwAAohcAAK0XAACuFwAAohcAAK4XAACjFwAAoxcAAK4XAACvFwAAoxcAAK8XAACmFwAAphcAAK8XAADADQAAphcAAMANAAA8FgAApBcAAKYXAAA8FgAApBcAADwWAAA7FgAApRcAAKQXAAA7FgAApRcAADsWAACwFwAAsRcAAKUXAACwFwAAsRcAALAXAACyFwAAsxcAAKEXAAClFwAAsxcAAKUXAACxFwAAqRcAAJ4XAAChFwAAqRcAAKEXAACzFwAAtBcAALUXAAC2FwAAtBcAALYXAAC3FwAAtRcAALgXAAC5FwAAtRcAALkXAAC2FwAAtxcAALYXAAC6FwAAtxcAALoXAAC7FwAAthcAALkXAAC8FwAAthcAALwXAAC6FwAAvRcAAL4XAAC0FwAAvRcAALQXAAC/FwAAvhcAAMAXAAC1FwAAvhcAALUXAAC0FwAAwBcAAMEXAAC4FwAAwBcAALgXAAC1FwAAwRcAAMIXAADDFwAAwRcAAMMXAAC4FwAAuBcAAMMXAADEFwAAuBcAAMQXAAC5FwAAuRcAAMQXAADFFwAAuRcAAMUXAAC8FwAAvBcAAMUXAABFFQAAvBcAAEUVAADGFwAAuhcAALwXAADGFwAAuhcAAMYXAADHFwAAuxcAALoXAADHFwAAuxcAAMcXAADIFwAAyRcAALsXAADIFwAAyRcAAMgXAADKFwAAyxcAALcXAAC7FwAAyxcAALsXAADJFwAAvxcAALQXAAC3FwAAvxcAALcXAADLFwAAzBcAAM0XAADOFwAAzBcAAM4XAADPFwAAzRcAANAXAADRFwAAzRcAANEXAADOFwAAzxcAAM4XAADSFwAAzxcAANIXAADTFwAAzhcAANEXAADUFwAAzhcAANQXAADSFwAA1RcAANYXAADMFwAA1RcAAMwXAADXFwAA1hcAANgXAADNFwAA1hcAAM0XAADMFwAA2BcAANkXAADQFwAA2BcAANAXAADNFwAA2RcAANoXAADbFwAA2RcAANsXAADQFwAA0BcAANsXAADcFwAA0BcAANwXAADRFwAA0RcAANwXAADdFwAA0RcAAN0XAADUFwAA1BcAAN0XAAB8CwAA1BcAAHwLAADeFwAA0hcAANQXAADeFwAA0hcAAN4XAAAYFgAA0xcAANIXAAAYFgAA0xcAABgWAADfFwAA4BcAANMXAADfFwAA4BcAAN8XAADhFwAA4hcAAM8XAADTFwAA4hcAANMXAADgFwAA1xcAAMwXAADPFwAA1xcAAM8XAADiFwAA4xcAAOQXAADlFwAA4xcAAOUXAADmFwAA5BcAAOcXAADoFwAA5BcAAOgXAADlFwAA5hcAAOUXAADpFwAA5hcAAOkXAADqFwAA5RcAAOgXAADrFwAA5RcAAOsXAADpFwAA7BcAAO0XAADjFwAA7BcAAOMXAADuFwAA7RcAAO8XAADkFwAA7RcAAOQXAADjFwAA7xcAAPAXAADnFwAA7xcAAOcXAADkFwAA8BcAAPEXAADyFwAA8BcAAPIXAADnFwAA5xcAAPIXAADzFwAA5xcAAPMXAADoFwAA6BcAAPMXAAD0FwAA6BcAAPQXAADrFwAA6xcAAPQXAABhEgAA6xcAAGESAAAKFgAA6RcAAOsXAAAKFgAA6RcAAAoWAAAJFgAA6hcAAOkXAAAJFgAA6hcAAAkWAAAIFgAA9RcAAOoXAAAIFgAA9RcAAAgWAABrDQAA9hcAAOYXAADqFwAA9hcAAOoXAAD1FwAA7hcAAOMXAADmFwAA7hcAAOYXAAD2FwAA9xcAAPgXAAD5FwAA9xcAAPkXAAD6FwAA+BcAAPsXAAD8FwAA+BcAAPwXAAD5FwAA+hcAAPkXAAD9FwAA+hcAAP0XAAD+FwAA+RcAAPwXAAD/FwAA+RcAAP8XAAD9FwAAABgAAAEYAAD3FwAAABgAAPcXAAACGAAAARgAAAMYAAD4FwAAARgAAPgXAAD3FwAAAxgAAAQYAAD7FwAAAxgAAPsXAAD4FwAABBgAAAUYAAAGGAAABBgAAAYYAAD7FwAA+xcAAAYYAAAHGAAA+xcAAAcYAAD8FwAA/BcAAAcYAAAIGAAA/BcAAAgYAAD/FwAA/xcAAAgYAAAJGAAA/xcAAAkYAAD2FQAA/RcAAP8XAAD2FQAA/RcAAPYVAAAKGAAA/hcAAP0XAAAKGAAA/hcAAAoYAAD0FQAACxgAAP4XAAD0FQAACxgAAPQVAAAMGAAADRgAAPoXAAD+FwAADRgAAP4XAAALGAAAAhgAAPcXAAD6FwAAAhgAAPoXAAANGAAADhgAAA8YAAAQGAAADhgAABAYAAARGAAADxgAABIYAAATGAAADxgAABMYAAAQGAAAERgAABAYAAAUGAAAERgAABQYAAAVGAAAEBgAABMYAAAWGAAAEBgAABYYAAAUGAAAFxgAABgYAAAOGAAAFxgAAA4YAAAZGAAAGBgAABoYAAAPGAAAGBgAAA8YAAAOGAAAGhgAABsYAAASGAAAGhgAABIYAAAPGAAAGxgAABwYAAAdGAAAGxgAAB0YAAASGAAAEhgAAB0YAAAeGAAAEhgAAB4YAAATGAAAExgAAB4YAAAfGAAAExgAAB8YAAAWGAAAFhgAAB8YAABpFAAAFhgAAGkUAAAgGAAAFBgAABYYAAAgGAAAFBgAACAYAADmFQAAFRgAABQYAADmFQAAFRgAAOYVAAAhGAAAIhgAABUYAAAhGAAAIhgAACEYAAA2CwAAIxgAABEYAAAVGAAAIxgAABUYAAAiGAAAGRgAAA4YAAARGAAAGRgAABEYAAAjGAAAJBgAACUYAAAmGAAAJBgAACYYAAAnGAAAJRgAACgYAAApGAAAJRgAACkYAAAmGAAAJxgAACYYAAAqGAAAJxgAACoYAAArGAAAJhgAACkYAAAsGAAAJhgAACwYAAAqGAAALRgAAC4YAAAkGAAALRgAACQYAAAvGAAALhgAADAYAAAlGAAALhgAACUYAAAkGAAAMBgAADEYAAAoGAAAMBgAACgYAAAlGAAAMRgAADIYAAAzGAAAMRgAADMYAAAoGAAAKBgAADMYAAA0GAAAKBgAADQYAAApGAAAKRgAADQYAAA1GAAAKRgAADUYAAAsGAAALBgAADUYAAA2GAAALBgAADYYAAA3GAAAKhgAACwYAAA3GAAAKhgAADcYAAA4GAAAKxgAACoYAAA4GAAAKxgAADgYAADRFQAAORgAACsYAADRFQAAORgAANEVAAD4FAAAOhgAACcYAAArGAAAOhgAACsYAAA5GAAALxgAACQYAAAnGAAALxgAACcYAAA6GAAAOxgAADwYAAA9GAAAOxgAAD0YAAA+GAAAPBgAAD8YAABAGAAAPBgAAEAYAAA9GAAAPhgAAD0YAABBGAAAPhgAAEEYAABCGAAAPRgAAEAYAABDGAAAPRgAAEMYAABBGAAARBgAAEUYAAA7GAAARBgAADsYAABGGAAARRgAAEcYAAA8GAAARRgAADwYAAA7GAAARxgAAEgYAAA/GAAARxgAAD8YAAA8GAAASBgAAEkYAABKGAAASBgAAEoYAAA/GAAAPxgAAEoYAABLGAAAPxgAAEsYAABAGAAAQBgAAEsYAABMGAAAQBgAAEwYAABDGAAAQxgAAEwYAABNGAAAQxgAAE0YAABOGAAAQRgAAEMYAABOGAAAQRgAAE4YAADAFQAAQhgAAEEYAADAFQAAQhgAAMAVAABPGAAAUBgAAEIYAABPGAAAUBgAAE8YAAC9FQAAURgAAD4YAABCGAAAURgAAEIYAABQGAAARhgAADsYAAA+GAAARhgAAD4YAABRGAAAUhgAAFMYAABUGAAAUhgAAFQYAABVGAAAUxgAAFYYAABXGAAAUxgAAFcYAABUGAAAVRgAAFQYAABYGAAAVRgAAFgYAABZGAAAVBgAAFcYAABaGAAAVBgAAFoYAABYGAAAWxgAAFwYAABSGAAAWxgAAFIYAABdGAAAXBgAAF4YAABTGAAAXBgAAFMYAABSGAAAXhgAAF8YAABWGAAAXhgAAFYYAABTGAAAXxgAAGAYAABhGAAAXxgAAGEYAABWGAAAVhgAAGEYAABiGAAAVhgAAGIYAABXGAAAVxgAAGIYAABjGAAAVxgAAGMYAABaGAAAWhgAAGMYAACsFQAAWhgAAKwVAACrFQAAWBgAAFoYAACrFQAAWBgAAKsVAACqFQAAWRgAAFgYAACqFQAAWRgAAKoVAABkGAAAZRgAAFkYAABkGAAAZRgAAGQYAAC8FAAAZhgAAFUYAABZGAAAZhgAAFkYAABlGAAAXRgAAFIYAABVGAAAXRgAAFUYAABmGAAAZxgAAGgYAABpGAAAZxgAAGkYAABqGAAAaBgAAGsYAABsGAAAaBgAAGwYAABpGAAAahgAAGkYAABtGAAAahgAAG0YAABuGAAAaRgAAGwYAABvGAAAaRgAAG8YAABtGAAAcBgAAHEYAABnGAAAcBgAAGcYAAByGAAAcRgAAHMYAABoGAAAcRgAAGgYAABnGAAAcxgAAHQYAABrGAAAcxgAAGsYAABoGAAAdBgAAHUYAAB2GAAAdBgAAHYYAABrGAAAaxgAAHYYAAB3GAAAaxgAAHcYAABsGAAAbBgAAHcYAAB4GAAAbBgAAHgYAABvGAAAbxgAAHgYAAB5GAAAbxgAAHkYAAB6GAAAbRgAAG8YAAB6GAAAbRgAAHoYAAB7GAAAbhgAAG0YAAB7GAAAbhgAAHsYAAB8GAAAfRgAAG4YAAB8GAAAfRgAAHwYAAB+GAAAfxgAAGoYAABuGAAAfxgAAG4YAAB9GAAAchgAAGcYAABqGAAAchgAAGoYAAB/GAAAgBgAAIEYAACCGAAAgBgAAIIYAACDGAAAgRgAAIQYAACFGAAAgRgAAIUYAACCGAAAgxgAAIIYAACGGAAAgxgAAIYYAACHGAAAghgAAIUYAACIGAAAghgAAIgYAACGGAAAiRgAAIoYAACAGAAAiRgAAIAYAACLGAAAihgAAIwYAACBGAAAihgAAIEYAACAGAAAjBgAAI0YAACEGAAAjBgAAIQYAACBGAAAjRgAAI4YAACPGAAAjRgAAI8YAACEGAAAhBgAAI8YAACQGAAAhBgAAJAYAACFGAAAhRgAAJAYAACRGAAAhRgAAJEYAACIGAAAiBgAAJEYAACSGAAAiBgAAJIYAACFFQAAhhgAAIgYAACFFQAAhhgAAIUVAACEFQAAhxgAAIYYAACEFQAAhxgAAIQVAACCFQAAkxgAAIcYAACCFQAAkxgAAIIVAACUGAAAlRgAAIMYAACHGAAAlRgAAIcYAACTGAAAixgAAIAYAACDGAAAixgAAIMYAACVGAAAlhgAAJcYAACYGAAAlhgAAJgYAACZGAAAlxgAAJoYAACbGAAAlxgAAJsYAACYGAAAmRgAAJgYAACcGAAAmRgAAJwYAACdGAAAmBgAAJsYAACeGAAAmBgAAJ4YAACcGAAAnxgAAKAYAACWGAAAnxgAAJYYAAChGAAAoBgAAKIYAACXGAAAoBgAAJcYAACWGAAAohgAAKMYAACaGAAAohgAAJoYAACXGAAAoxgAAHoXAAB8FwAAoxgAAHwXAACaGAAAmhgAAHwXAACGFwAAmhgAAIYXAACbGAAAmxgAAIYXAACFFwAAmxgAAIUXAACeGAAAnhgAAIUXAABwFQAAnhgAAHAVAACkGAAAnBgAAJ4YAACkGAAAnBgAAKQYAAClGAAAnRgAAJwYAAClGAAAnRgAAKUYAABtFQAAphgAAJ0YAABtFQAAphgAAG0VAACnGAAAqBgAAJkYAACdGAAAqBgAAJ0YAACmGAAAoRgAAJYYAACZGAAAoRgAAJkYAACoGAAAqRgAAKoYAACrGAAAqRgAAKsYAACsGAAAqhgAAK0YAACuGAAAqhgAAK4YAACrGAAArBgAAKsYAACvGAAArBgAAK8YAACwGAAAqxgAAK4YAACxGAAAqxgAALEYAACvGAAAlRcAALIYAACpGAAAlRcAAKkYAACWFwAAshgAALMYAACqGAAAshgAAKoYAACpGAAAsxgAALQYAACtGAAAsxgAAK0YAACqGAAAtBgAALUYAAC2GAAAtBgAALYYAACtGAAArRgAALYYAAC3GAAArRgAALcYAACuGAAArhgAALcYAAC4GAAArhgAALgYAACxGAAAsRgAALgYAAC5GAAAsRgAALkYAABdFQAArxgAALEYAABdFQAArxgAAF0VAABcFQAAsBgAAK8YAABcFQAAsBgAAFwVAAC6GAAAmBcAALAYAAC6GAAAmBcAALoYAABZFQAAlxcAAKwYAACwGAAAlxcAALAYAACYFwAAlhcAAKkYAACsGAAAlhcAAKwYAACXFwAAuxgAALwYAAC9GAAAuxgAAL0YAAC+GAAAvBgAAL8YAADAGAAAvBgAAMAYAAC9GAAAvhgAAL0YAADBGAAAvhgAAMEYAADCGAAAvRgAAMAYAADDGAAAvRgAAMMYAADBGAAAwhcAAMQYAAC7GAAAwhcAALsYAADDFwAAxBgAAMUYAAC8GAAAxBgAALwYAAC7GAAAxRgAAMYYAAC/GAAAxRgAAL8YAAC8GAAAxhgAAMcYAADIGAAAxhgAAMgYAAC/GAAAvxgAAMgYAADJGAAAvxgAAMkYAADAGAAAwBgAAMkYAADKGAAAwBgAAMoYAADDGAAAwxgAAMoYAADLGAAAwxgAAMsYAADMGAAAwRgAAMMYAADMGAAAwRgAAMwYAADNGAAAwhgAAMEYAADNGAAAwhgAAM0YAADOGAAAxRcAAMIYAADOGAAAxRcAAM4YAABFFQAAxBcAAL4YAADCGAAAxBcAAMIYAADFFwAAwxcAALsYAAC+GAAAwxcAAL4YAADEFwAAzxgAANAYAADRGAAAzxgAANEYAADSGAAA0BgAANMYAADUGAAA0BgAANQYAADRGAAA0hgAANEYAADVGAAA0hgAANUYAADWGAAA0RgAANQYAADXGAAA0RgAANcYAADVGAAA2BgAANkYAADPGAAA2BgAAM8YAADaGAAA2RgAANsYAADQGAAA2RgAANAYAADPGAAA2xgAANwYAADTGAAA2xgAANMYAADQGAAA3BgAAN0YAADeGAAA3BgAAN4YAADTGAAA0xgAAN4YAADfGAAA0xgAAN8YAADUGAAA1BgAAN8YAADgGAAA1BgAAOAYAADXGAAA1xgAAOAYAAA0FQAA1xgAADQVAADhGAAA1RgAANcYAADhGAAA1RgAAOEYAAAyFQAA1hgAANUYAAAyFQAA1hgAADIVAADiGAAA4xgAANYYAADiGAAA4xgAAOIYAADkGAAA5RgAANIYAADWGAAA5RgAANYYAADjGAAA2hgAAM8YAADSGAAA2hgAANIYAADlGAAA5hgAAOcYAADoGAAA5hgAAOgYAADpGAAA5xgAAOoYAADrGAAA5xgAAOsYAADoGAAA6RgAAOgYAADsGAAA6RgAAOwYAADtGAAA6BgAAOsYAADuGAAA6BgAAO4YAADsGAAA7xgAAPAYAADmGAAA7xgAAOYYAADxGAAA8BgAAPIYAADnGAAA8BgAAOcYAADmGAAA8hgAAPMYAADqGAAA8hgAAOoYAADnGAAA8xgAAAAYAAACGAAA8xgAAAIYAADqGAAA6hgAAAIYAAANGAAA6hgAAA0YAADrGAAA6xgAAA0YAAALGAAA6xgAAAsYAADuGAAA7hgAAAsYAAAMGAAA7hgAAAwYAAAfFQAA7BgAAO4YAAAfFQAA7BgAAB8VAAD0GAAA7RgAAOwYAAD0GAAA7RgAAPQYAAAdFQAA9RgAAO0YAAAdFQAA9RgAAB0VAAAwFAAA9hgAAOkYAADtGAAA9hgAAO0YAAD1GAAA8RgAAOYYAADpGAAA8RgAAOkYAAD2GAAA9xgAAPgYAAD5GAAA9xgAAPkYAAD6GAAA+BgAAPsYAAD8GAAA+BgAAPwYAAD5GAAA+hgAAPkYAAD9GAAA+hgAAP0YAAD+GAAA+RgAAPwYAAD/GAAA+RgAAP8YAAD9GAAAABkAAAEZAAD3GAAAABkAAPcYAAACGQAAARkAAAMZAAD4GAAAARkAAPgYAAD3GAAAAxkAAAQZAAD7GAAAAxkAAPsYAAD4GAAABBkAAAUZAAAGGQAABBkAAAYZAAD7GAAA+xgAAAYZAAAHGQAA+xgAAAcZAAD8GAAA/BgAAAcZAAAIGQAA/BgAAAgZAAD/GAAA/xgAAAgZAAAMFQAA/xgAAAwVAAAJGQAA/RgAAP8YAAAJGQAA/RgAAAkZAAAKGQAA/hgAAP0YAAAKGQAA/hgAAAoZAAALGQAADBkAAP4YAAALGQAADBkAAAsZAAAIFAAADRkAAPoYAAD+GAAADRkAAP4YAAAMGQAAAhkAAPcYAAD6GAAAAhkAAPoYAAANGQAADhkAAA8ZAAAQGQAADhkAABAZAAARGQAADxkAABIZAAATGQAADxkAABMZAAAQGQAAERkAABAZAAAUGQAAERkAABQZAAAVGQAAEBkAABMZAAAWGQAAEBkAABYZAAAUGQAAFxkAABgZAAAOGQAAFxkAAA4ZAAAZGQAAGBkAABoZAAAPGQAAGBkAAA8ZAAAOGQAAGhkAABsZAAASGQAAGhkAABIZAAAPGQAAGxkAAC0YAAAvGAAAGxkAAC8YAAASGQAAEhkAAC8YAAA6GAAAEhkAADoYAAATGQAAExkAADoYAAA5GAAAExkAADkYAAAWGQAAFhkAADkYAAD4FAAAFhkAAPgUAAAcGQAAFBkAABYZAAAcGQAAFBkAABwZAAAdGQAAFRkAABQZAAAdGQAAFRkAAB0ZAAAeGQAAHxkAABUZAAAeGQAAHxkAAB4ZAAD0EwAAIBkAABEZAAAVGQAAIBkAABUZAAAfGQAAGRkAAA4ZAAARGQAAGRkAABEZAAAgGQAAIRkAACIZAAAjGQAAIRkAACMZAAAkGQAAIhkAACUZAAAmGQAAIhkAACYZAAAjGQAAJBkAACMZAAAnGQAAJBkAACcZAAAoGQAAIxkAACYZAAApGQAAIxkAACkZAAAnGQAASRgAACoZAAAhGQAASRgAACEZAABKGAAAKhkAACsZAAAiGQAAKhkAACIZAAAhGQAAKxkAACwZAAAlGQAAKxkAACUZAAAiGQAALBkAAC0ZAAAuGQAALBkAAC4ZAAAlGQAAJRkAAC4ZAAAvGQAAJRkAAC8ZAAAmGQAAJhkAAC8ZAAAwGQAAJhkAADAZAAApGQAAKRkAADAZAAAxGQAAKRkAADEZAAAyGQAAJxkAACkZAAAyGQAAJxkAADIZAAAzGQAAKBkAACcZAAAzGQAAKBkAADMZAAA0GQAATBgAACgZAAA0GQAATBgAADQZAABNGAAASxgAACQZAAAoGQAASxgAACgZAABMGAAAShgAACEZAAAkGQAAShgAACQZAABLGAAANRkAADYZAAA3GQAANRkAADcZAAA4GQAANhkAADkZAAA6GQAANhkAADoZAAA3GQAAOBkAADcZAAA7GQAAOBkAADsZAAA8GQAANxkAADoZAAA9GQAANxkAAD0ZAAA7GQAAPhkAAD8ZAAA1GQAAPhkAADUZAABAGQAAPxkAAEEZAAA2GQAAPxkAADYZAAA1GQAAQRkAAEIZAAA5GQAAQRkAADkZAAA2GQAAQhkAANUXAADXFwAAQhkAANcXAAA5GQAAORkAANcXAADiFwAAORkAAOIXAAA6GQAAOhkAAOIXAADgFwAAOhkAAOAXAAA9GQAAPRkAAOAXAADhFwAAPRkAAOEXAABDGQAAOxkAAD0ZAABDGQAAOxkAAEMZAABEGQAAPBkAADsZAABEGQAAPBkAAEQZAABFGQAARhkAADwZAABFGQAARhkAAEUZAABUEwAARxkAADgZAAA8GQAARxkAADwZAABGGQAAQBkAADUZAAA4GQAAQBkAADgZAABHGQAASBkAAEkZAABKGQAASBkAAEoZAABLGQAASRkAAEwZAABNGQAASRkAAE0ZAABKGQAASxkAAEoZAABOGQAASxkAAE4ZAABPGQAAShkAAE0ZAABQGQAAShkAAFAZAABOGQAAURkAAFIZAABIGQAAURkAAEgZAABTGQAAUhkAAFQZAABJGQAAUhkAAEkZAABIGQAAVBkAAFUZAABMGQAAVBkAAEwZAABJGQAAVRkAAFsYAABdGAAAVRkAAF0YAABMGQAATBkAAF0YAABmGAAATBkAAGYYAABNGQAATRkAAGYYAABlGAAATRkAAGUYAABQGQAAUBkAAGUYAAC8FAAAUBkAALwUAABWGQAAThkAAFAZAABWGQAAThkAAFYZAABXGQAATxkAAE4ZAABXGQAATxkAAFcZAAC5FAAAWBkAAE8ZAAC5FAAAWBkAALkUAADMEwAAWRkAAEsZAABPGQAAWRkAAE8ZAABYGQAAUxkAAEgZAABLGQAAUxkAAEsZAABZGQAAWhkAAFsZAABcGQAAWhkAAFwZAABdGQAAWxkAAF4ZAABfGQAAWxkAAF8ZAABcGQAAXRkAAFwZAABgGQAAXRkAAGAZAABhGQAAXBkAAF8ZAABiGQAAXBkAAGIZAABgGQAAdRgAAGMZAABaGQAAdRgAAFoZAAB2GAAAYxkAAGQZAABbGQAAYxkAAFsZAABaGQAAZBkAAGUZAABeGQAAZBkAAF4ZAABbGQAAZRkAAGYZAABnGQAAZRkAAGcZAABeGQAAXhkAAGcZAABoGQAAXhkAAGgZAABfGQAAXxkAAGgZAABpGQAAXxkAAGkZAABiGQAAYhkAAGkZAAC1EwAAYhkAALUTAABqGQAAYBkAAGIZAABqGQAAYBkAAGoZAACoFAAAYRkAAGAZAACoFAAAYRkAAKgUAABrGQAAeBgAAGEZAABrGQAAeBgAAGsZAAB5GAAAdxgAAF0ZAABhGQAAdxgAAGEZAAB4GAAAdhgAAFoZAABdGQAAdhgAAF0ZAAB3GAAAbBkAAG0ZAABuGQAAbBkAAG4ZAABvGQAAbRkAAHAZAABxGQAAbRkAAHEZAABuGQAAbxkAAG4ZAAByGQAAbxkAAHIZAABzGQAAbhkAAHEZAAB0GQAAbhkAAHQZAAByGQAAjhgAAHUZAABsGQAAjhgAAGwZAACPGAAAdRkAAHYZAABtGQAAdRkAAG0ZAABsGQAAdhkAAHcZAABwGQAAdhkAAHAZAABtGQAAdxkAAHgZAAB5GQAAdxkAAHkZAABwGQAAcBkAAHkZAAB6GQAAcBkAAHoZAABxGQAAcRkAAHoZAAB7GQAAcRkAAHsZAAB0GQAAdBkAAHsZAAChEwAAdBkAAKETAAB8GQAAchkAAHQZAAB8GQAAchkAAHwZAACUFAAAcxkAAHIZAACUFAAAcxkAAJQUAAB9GQAAkRgAAHMZAAB9GQAAkRgAAH0ZAACSGAAAkBgAAG8ZAABzGQAAkBgAAHMZAACRGAAAjxgAAGwZAABvGQAAjxgAAG8ZAACQGAAAfhkAAH8ZAACAGQAAfhkAAIAZAACBGQAAfxkAAIIZAACDGQAAfxkAAIMZAACAGQAAgRkAAIAZAACEGQAAgRkAAIQZAACFGQAAgBkAAIMZAACGGQAAgBkAAIYZAACEGQAAhxkAAIgZAAB+GQAAhxkAAH4ZAACJGQAAiBkAAIoZAAB/GQAAiBkAAH8ZAAB+GQAAihkAAIsZAACCGQAAihkAAIIZAAB/GQAAixkAAJ8YAAChGAAAixkAAKEYAACCGQAAghkAAKEYAACoGAAAghkAAKgYAACDGQAAgxkAAKgYAACmGAAAgxkAAKYYAACGGQAAhhkAAKYYAACnGAAAhhkAAKcYAAB/FAAAhBkAAIYZAAB/FAAAhBkAAH8UAAB+FAAAhRkAAIQZAAB+FAAAhRkAAH4UAACMGQAAjRkAAIUZAACMGQAAjRkAAIwZAACOGQAAjxkAAIEZAACFGQAAjxkAAIUZAACNGQAAiRkAAH4ZAACBGQAAiRkAAIEZAACPGQAAkBkAAJEZAACSGQAAkBkAAJIZAACTGQAAkRkAAJQZAACVGQAAkRkAAJUZAACSGQAAkxkAAJIZAACWGQAAkxkAAJYZAACXGQAAkhkAAJUZAACYGQAAkhkAAJgZAACWGQAAHBgAAJkZAACQGQAAHBgAAJAZAAAdGAAAmRkAAJoZAACRGQAAmRkAAJEZAACQGQAAmhkAAJsZAACUGQAAmhkAAJQZAACRGQAAmxkAAJwZAACdGQAAmxkAAJ0ZAACUGQAAlBkAAJ0ZAACeGQAAlBkAAJ4ZAACVGQAAlRkAAJ4ZAACfGQAAlRkAAJ8ZAACYGQAAmBkAAJ8ZAACgGQAAmBkAAKAZAABtFAAAlhkAAJgZAABtFAAAlhkAAG0UAAChGQAAlxkAAJYZAAChGQAAlxkAAKEZAACiGQAAHxgAAJcZAACiGQAAHxgAAKIZAABpFAAAHhgAAJMZAACXGQAAHhgAAJcZAAAfGAAAHRgAAJAZAACTGQAAHRgAAJMZAAAeGAAAoxkAAKQZAAClGQAAoxkAAKUZAACmGQAApBkAAKcZAACoGQAApBkAAKgZAAClGQAAphkAAKUZAACpGQAAphkAAKkZAACqGQAApRkAAKgZAACrGQAApRkAAKsZAACpGQAAtRgAAKwZAACjGQAAtRgAAKMZAAC2GAAArBkAAK0ZAACkGQAArBkAAKQZAACjGQAArRkAAK4ZAACnGQAArRkAAKcZAACkGQAArhkAAK8ZAACwGQAArhkAALAZAACnGQAApxkAALAZAACxGQAApxkAALEZAACoGQAAqBkAALEZAACyGQAAqBkAALIZAACrGQAAqxkAALIZAACzGQAAqxkAALMZAAC0GQAAqRkAAKsZAAC0GQAAqRkAALQZAAC1GQAAqhkAAKkZAAC1GQAAqhkAALUZAAC2GQAAuBgAAKoZAAC2GQAAuBgAALYZAAC5GAAAtxgAAKYZAACqGQAAtxgAAKoZAAC4GAAAthgAAKMZAACmGQAAthgAAKYZAAC3GAAAtxkAALgZAAC5GQAAtxkAALkZAAC6GQAAuBkAALsZAAC8GQAAuBkAALwZAAC5GQAAuhkAALkZAAC9GQAAuhkAAL0ZAAC+GQAAuRkAALwZAAC/GQAAuRkAAL8ZAAC9GQAAxxgAAMAZAAC3GQAAxxgAALcZAADIGAAAwBkAAMEZAAC4GQAAwBkAALgZAAC3GQAAwRkAAMIZAAC7GQAAwRkAALsZAAC4GQAAwhkAAMMZAADEGQAAwhkAAMQZAAC7GQAAuxkAAMQZAADFGQAAuxkAAMUZAAC8GQAAvBkAAMUZAADGGQAAvBkAAMYZAAC/GQAAvxkAAMYZAABlEwAAvxkAAGUTAADHGQAAvRkAAL8ZAADHGQAAvRkAAMcZAABEFAAAvhkAAL0ZAABEFAAAvhkAAEQUAADIGQAAyhgAAL4ZAADIGQAAyhgAAMgZAADLGAAAyRgAALoZAAC+GQAAyRgAAL4ZAADKGAAAyBgAALcZAAC6GQAAyBgAALoZAADJGAAAyRkAAMoZAADLGQAAyRkAAMsZAADMGQAAyhkAAM0ZAADOGQAAyhkAAM4ZAADLGQAAzBkAAMsZAADPGQAAzBkAAM8ZAADQGQAAyxkAAM4ZAADRGQAAyxkAANEZAADPGQAA0hkAANMZAADJGQAA0hkAAMkZAADUGQAA0xkAANUZAADKGQAA0xkAAMoZAADJGQAA1RkAANYZAADNGQAA1RkAAM0ZAADKGQAA1hkAAO8YAADxGAAA1hkAAPEYAADNGQAAzRkAAPEYAAD2GAAAzRkAAPYYAADOGQAAzhkAAPYYAAD1GAAAzhkAAPUYAADRGQAA0RkAAPUYAAAwFAAA0RkAADAUAAAvFAAAzxkAANEZAAAvFAAAzxkAAC8UAAAuFAAA0BkAAM8ZAAAuFAAA0BkAAC4UAADXGQAA2BkAANAZAADXGQAA2BkAANcZAABAEwAA2RkAAMwZAADQGQAA2RkAANAZAADYGQAA1BkAAMkZAADMGQAA1BkAAMwZAADZGQAA2hkAANsZAADcGQAA2hkAANwZAADdGQAA2xkAAN4ZAADfGQAA2xkAAN8ZAADcGQAA3RkAANwZAADgGQAA3RkAAOAZAADhGQAA3BkAAN8ZAADiGQAA3BkAAOIZAADgGQAA4xkAAOQZAADaGQAA4xkAANoZAADlGQAA5BkAAOYZAADbGQAA5BkAANsZAADaGQAA5hkAAOcZAADeGQAA5hkAAN4ZAADbGQAA5xkAAOgZAADpGQAA5xkAAOkZAADeGQAA3hkAAOkZAADqGQAA3hkAAOoZAADfGQAA3xkAAOoZAADrGQAA3xkAAOsZAADiGQAA4hkAAOsZAADsGQAA4hkAAOwZAAAdFAAA4BkAAOIZAAAdFAAA4BkAAB0UAADtGQAA4RkAAOAZAADtGQAA4RkAAO0ZAAAaFAAA7hkAAOEZAAAaFAAA7hkAABoUAADvGQAA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QxoAAEwaAABNGgAAQxoAAE0aAABGGgAARhoAAE0aAABOGgAARhoAAE4aAAC5EwAARBoAAEYaAAC5EwAARBoAALkTAAC4EwAARRoAAEQaAAC4EwAARRoAALgTAABPGgAAaRkAAEUaAABPGgAAaRkAAE8aAAC1EwAAaBkAAEEaAABFGgAAaBkAAEUaAABpGQAAZxkAAD4aAABBGgAAZxkAAEEaAABoGQAAUBoAAFEaAABSGgAAUBoAAFIaAABTGgAAURoAAFQaAABVGgAAURoAAFUaAABSGgAAUxoAAFIaAABWGgAAUxoAAFYaAABXGgAAUhoAAFUaAABYGgAAUhoAAFgaAABWGgAAeBkAAFkaAABQGgAAeBkAAFAaAAB5GQAAWRoAAFoaAABRGgAAWRoAAFEaAABQGgAAWhoAAFsaAABUGgAAWhoAAFQaAABRGgAAWxoAAFwaAABdGgAAWxoAAF0aAABUGgAAVBoAAF0aAABeGgAAVBoAAF4aAABVGgAAVRoAAF4aAABfGgAAVRoAAF8aAABYGgAAWBoAAF8aAABgGgAAWBoAAGAaAABhGgAAVhoAAFgaAABhGgAAVhoAAGEaAACkEwAAVxoAAFYaAACkEwAAVxoAAKQTAACiEwAAexkAAFcaAACiEwAAexkAAKITAAChEwAAehkAAFMaAABXGgAAehkAAFcaAAB7GQAAeRkAAFAaAABTGgAAeRkAAFMaAAB6GQAAYhoAAGMaAABkGgAAYhoAAGQaAABlGgAAYxoAAGYaAABnGgAAYxoAAGcaAABkGgAAZRoAAGQaAABoGgAAZRoAAGgaAABpGgAAZBoAAGcaAABqGgAAZBoAAGoaAABoGgAAaxoAAGwaAABiGgAAaxoAAGIaAABtGgAAbBoAAG4aAABjGgAAbBoAAGMaAABiGgAAbhoAAG8aAABmGgAAbhoAAGYaAABjGgAAbxoAAIcZAACJGQAAbxoAAIkZAABmGgAAZhoAAIkZAACPGQAAZhoAAI8ZAABnGgAAZxoAAI8ZAACNGQAAZxoAAI0ZAABqGgAAahoAAI0ZAACOGQAAahoAAI4ZAABwGgAAaBoAAGoaAABwGgAAaBoAAHAaAABxGgAAaRoAAGgaAABxGgAAaRoAAHEaAACNEwAAchoAAGkaAACNEwAAchoAAI0TAAC0EgAAcxoAAGUaAABpGgAAcxoAAGkaAAByGgAAbRoAAGIaAABlGgAAbRoAAGUaAABzGgAAdBoAAHUaAAB2GgAAdBoAAHYaAAB3GgAAdRoAAHgaAAB5GgAAdRoAAHkaAAB2GgAAdxoAAHYaAAB6GgAAdxoAAHoaAAB7GgAAdhoAAHkaAAB8GgAAdhoAAHwaAAB6GgAArxkAAH0aAAB0GgAArxkAAHQaAACwGQAAfRoAAH4aAAB1GgAAfRoAAHUaAAB0GgAAfhoAAH8aAAB4GgAAfhoAAHgaAAB1GgAAfxoAAIAaAACBGgAAfxoAAIEaAAB4GgAAeBoAAIEaAACCGgAAeBoAAIIaAAB5GgAAeRoAAIIaAACDGgAAeRoAAIMaAAB8GgAAfBoAAIMaAACEGgAAfBoAAIQaAACFGgAAehoAAHwaAACFGgAAehoAAIUaAACGGgAAexoAAHoaAACGGgAAexoAAIYaAACHGgAAshkAAHsaAACHGgAAshkAAIcaAACzGQAAsRkAAHcaAAB7GgAAsRkAAHsaAACyGQAAsBkAAHQaAAB3GgAAsBkAAHcaAACxGQAAiBoAAIkaAACKGgAAiBoAAIoaAACLGgAAiRoAAIwaAACNGgAAiRoAAI0aAACKGgAAixoAAIoaAACOGgAAixoAAI4aAACPGgAAihoAAI0aAACQGgAAihoAAJAaAACOGgAAwxkAAJEaAACIGgAAwxkAAIgaAADEGQAAkRoAAJIaAACJGgAAkRoAAIkaAACIGgAAkhoAAJMaAACMGgAAkhoAAIwaAACJGgAAkxoAAJQaAACVGgAAkxoAAJUaAACMGgAAjBoAAJUaAACWGgAAjBoAAJYaAACNGgAAjRoAAJYaAACXGgAAjRoAAJcaAACQGgAAkBoAAJcaAACYGgAAkBoAAJgaAABpEwAAjhoAAJAaAABpEwAAjhoAAGkTAABoEwAAjxoAAI4aAABoEwAAjxoAAGgTAABmEwAAxhkAAI8aAABmEwAAxhkAAGYTAABlEwAAxRkAAIsaAACPGgAAxRkAAI8aAADGGQAAxBkAAIgaAACLGgAAxBkAAIsaAADFGQAAmRoAAJoaAACbGgAAmRoAAJsaAACcGgAAmhoAAJ0aAACeGgAAmhoAAJ4aAACbGgAAnBoAAJsaAACfGgAAnBoAAJ8aAACgGgAAmxoAAJ4aAAChGgAAmxoAAKEaAACfGgAAohoAAKMaAACZGgAAohoAAJkaAACkGgAAoxoAAKUaAACaGgAAoxoAAJoaAACZGgAApRoAAKYaAACdGgAApRoAAJ0aAACaGgAAphoAAD4ZAABAGQAAphoAAEAZAACdGgAAnRoAAEAZAABHGQAAnRoAAEcZAACeGgAAnhoAAEcZAABGGQAAnhoAAEYZAAChGgAAoRoAAEYZAABUEwAAoRoAAFQTAACnGgAAnxoAAKEaAACnGgAAnxoAAKcaAABSEwAAoBoAAJ8aAABSEwAAoBoAAFITAACoGgAAqRoAAKAaAACoGgAAqRoAAKgaAACqGgAAqxoAAJwaAACgGgAAqxoAAKAaAACpGgAApBoAAJkaAACcGgAApBoAAJwaAACrGgAArBoAAK0aAACuGgAArBoAAK4aAACvGgAArRoAALAaAACxGgAArRoAALEaAACuGgAArxoAAK4aAACyGgAArxoAALIaAACzGgAArhoAALEaAAC0GgAArhoAALQaAACyGgAAtRoAALYaAACsGgAAtRoAAKwaAAC3GgAAthoAALgaAACtGgAAthoAAK0aAACsGgAAuBoAALkaAACwGgAAuBoAALAaAACtGgAAuRoAANIZAADUGQAAuRoAANQZAACwGgAAsBoAANQZAADZGQAAsBoAANkZAACxGgAAsRoAANkZAADYGQAAsRoAANgZAAC0GgAAtBoAANgZAABAEwAAtBoAAEATAAC6GgAAshoAALQaAAC6GgAAshoAALoaAAC7GgAAsxoAALIaAAC7GgAAsxoAALsaAAC8GgAAvRoAALMaAAC8GgAAvRoAALwaAAC+GgAAvxoAAK8aAACzGgAAvxoAALMaAAC9GgAAtxoAAKwaAACvGgAAtxoAAK8aAAC/GgAAwBoAAMEaAADCGgAAwBoAAMIaAADDGgAAwRoAAMQaAADFGgAAwRoAAMUaAADCGgAAwxoAAMIaAADGGgAAwxoAAMYaAADHGgAAwhoAAMUaAADIGgAAwhoAAMgaAADGGgAAnBkAAMkaAADAGgAAnBkAAMAaAACdGQAAyRoAAMoaAADBGgAAyRoAAMEaAADAGgAAyhoAAMsaAADEGgAAyhoAAMQaAADBGgAAyxoAAMwaAADNGgAAyxoAAM0aAADEGgAAxBoAAM0aAADOGgAAxBoAAM4aAADFGgAAxRoAAM4aAADPGgAAxRoAAM8aAADIGgAAyBoAAM8aAACyEQAAyBoAALIRAADQGgAAxhoAAMgaAADQGgAAxhoAANAaAADRGgAAxxoAAMYaAADRGgAAxxoAANEaAADSGgAAnxkAAMcaAADSGgAAnxkAANIaAACgGQAAnhkAAMMaAADHGgAAnhkAAMcaAACfGQAAnRkAAMAaAADDGgAAnRkAAMMaAACeGQAA0xoAANQaAADVGgAA0xoAANUaAADWGgAA1BoAANcaAADYGgAA1BoAANgaAADVGgAA1hoAANUaAADZGgAA1hoAANkaAADaGgAA1RoAANgaAADbGgAA1RoAANsaAADZGgAA3BoAAN0aAADTGgAA3BoAANMaAADeGgAA3RoAAN8aAADUGgAA3RoAANQaAADTGgAA3xoAAOAaAADXGgAA3xoAANcaAADUGgAA4BoAAPoZAAD8GQAA4BoAAPwZAADXGgAA1xoAAPwZAAADGgAA1xoAAAMaAADYGgAA2BoAAAMaAAABGgAA2BoAAAEaAADbGgAA2xoAAAEaAAACGgAA2xoAAAIaAAAXEwAA2RoAANsaAAAXEwAA2RoAABcTAADhGgAA2hoAANkaAADhGgAA2hoAAOEaAADiGgAA4xoAANoaAADiGgAA4xoAAOIaAADkGgAA5RoAANYaAADaGgAA5RoAANoaAADjGgAA3hoAANMaAADWGgAA3hoAANYaAADlGgAA5hoAAOcaAADoGgAA5hoAAOgaAADpGgAA5xoAAOoaAADrGgAA5xoAAOsaAADoGgAA6RoAAOgaAADsGgAA6RoAAOwaAADtGgAA6BoAAOsaAADuGgAA6BoAAO4aAADsGgAA7xoAAPAaAADmGgAA7xoAAOYaAADxGgAA8BoAAPIaAADnGgAA8BoAAOcaAADmGgAA8hoAAPMaAADqGgAA8hoAAOoaAADnGgAA8xoAAA0aAAAPGgAA8xoAAA8aAADqGgAA6hoAAA8aAAAWGgAA6hoAABYaAADrGgAA6xoAABYaAAAVGgAA6xoAABUaAADuGgAA7hoAABUaAAAEEwAA7hoAAAQTAAADEwAA7BoAAO4aAAADEwAA7BoAAAMTAAACEwAA7RoAAOwaAAACEwAA7RoAAAITAAD0GgAA9RoAAO0aAAD0GgAA9RoAAPQaAAD2GgAA9xoAAOkaAADtGgAA9xoAAO0aAAD1GgAA8RoAAOYaAADpGgAA8RoAAOkaAAD3GgAA+BoAAPkaAAD6GgAA+BoAAPoaAAD7GgAA+RoAAPwaAAD9GgAA+RoAAP0aAAD6GgAA+xoAAPoaAAD+GgAA+xoAAP4aAAD/GgAA+hoAAP0aAAAAGwAA+hoAAAAbAAD+GgAAIxoAAAEbAAD4GgAAIxoAAPgaAAAkGgAAARsAAAIbAAD5GgAAARsAAPkaAAD4GgAAAhsAAAMbAAD8GgAAAhsAAPwaAAD5GgAAAxsAAAQbAAAFGwAAAxsAAAUbAAD8GgAA/BoAAAUbAAAGGwAA/BoAAAYbAAD9GgAA/RoAAAYbAAAHGwAA/RoAAAcbAAAAGwAAABsAAAcbAAAIGwAAABsAAAgbAADxEgAA/hoAAAAbAADxEgAA/hoAAPESAADwEgAA/xoAAP4aAADwEgAA/xoAAPASAAAJGwAAJhoAAP8aAAAJGwAAJhoAAAkbAAAnGgAAJRoAAPsaAAD/GgAAJRoAAP8aAAAmGgAAJBoAAPgaAAD7GgAAJBoAAPsaAAAlGgAAChsAAAsbAAAMGwAAChsAAAwbAAANGwAACxsAAA4bAAAPGwAACxsAAA8bAAAMGwAADRsAAAwbAAAQGwAADRsAABAbAAARGwAADBsAAA8bAAASGwAADBsAABIbAAAQGwAAExsAABQbAAAKGwAAExsAAAobAAAVGwAAFBsAABYbAAALGwAAFBsAAAsbAAAKGwAAFhsAABcbAAAOGwAAFhsAAA4bAAALGwAAFxsAADMaAAA1GgAAFxsAADUaAAAOGwAADhsAADUaAAA9GgAADhsAAD0aAAAPGwAADxsAAD0aAAA7GgAADxsAADsaAAASGwAAEhsAADsaAAA8GgAAEhsAADwaAAAYGwAAEBsAABIbAAAYGwAAEBsAABgbAAAZGwAAERsAABAbAAAZGwAAERsAABkbAAAaGwAAGxsAABEbAAAaGwAAGxsAABobAAAcGwAAHRsAAA0bAAARGwAAHRsAABEbAAAbGwAAFRsAAAobAAANGwAAFRsAAA0bAAAdGwAAHhsAAB8bAAAgGwAAHhsAACAbAAAhGwAAHxsAACIbAAAjGwAAHxsAACMbAAAgGwAAIRsAACAbAAAkGwAAIRsAACQbAAAlGwAAIBsAACMbAAAmGwAAIBsAACYbAAAkGwAAXBoAACcbAAAeGwAAXBoAAB4bAABdGgAAJxsAACgbAAAfGwAAJxsAAB8bAAAeGwAAKBsAACkbAAAiGwAAKBsAACIbAAAfGwAAKRsAACobAAArGwAAKRsAACsbAAAiGwAAIhsAACsbAAAsGwAAIhsAACwbAAAjGwAAIxsAACwbAAAtGwAAIxsAAC0bAAAmGwAAJhsAAC0bAAAuGwAAJhsAAC4bAAAvGwAAJBsAACYbAAAvGwAAJBsAAC8bAADIEgAAJRsAACQbAADIEgAAJRsAAMgSAAAwGwAAXxoAACUbAAAwGwAAXxoAADAbAABgGgAAXhoAACEbAAAlGwAAXhoAACUbAABfGgAAXRoAAB4bAAAhGwAAXRoAACEbAABeGgAAMRsAADIbAAAzGwAAMRsAADMbAAA0GwAAMhsAADUbAAA2GwAAMhsAADYbAAAzGwAANBsAADMbAAA3GwAANBsAADcbAAA4GwAAMxsAADYbAAA5GwAAMxsAADkbAAA3GwAAOhsAADsbAAAxGwAAOhsAADEbAAA8GwAAOxsAAD0bAAAyGwAAOxsAADIbAAAxGwAAPRsAAD4bAAA1GwAAPRsAADUbAAAyGwAAPhsAAGsaAABtGgAAPhsAAG0aAAA1GwAANRsAAG0aAABzGgAANRsAAHMaAAA2GwAANhsAAHMaAAByGgAANhsAAHIaAAA5GwAAORsAAHIaAAC0EgAAORsAALQSAAA/GwAANxsAADkbAAA/GwAANxsAAD8bAABAGwAAOBsAADcbAABAGwAAOBsAAEAbAABBGwAAQhsAADgbAABBGwAAQhsAAEEbAABDGwAARBsAADQbAAA4GwAARBsAADgbAABCGwAAPBsAADEbAAA0GwAAPBsAADQbAABEGwAARRsAAEYbAABHGwAARRsAAEcbAABIGwAARhsAAEkbAABKGwAARhsAAEobAABHGwAASBsAAEcbAABLGwAASBsAAEsbAABMGwAARxsAAEobAABNGwAARxsAAE0bAABLGwAAgBoAAE4bAABFGwAAgBoAAEUbAACBGgAAThsAAE8bAABGGwAAThsAAEYbAABFGwAATxsAAFAbAABJGwAATxsAAEkbAABGGwAAUBsAAFEbAABSGwAAUBsAAFIbAABJGwAASRsAAFIbAABTGwAASRsAAFMbAABKGwAAShsAAFMbAABUGwAAShsAAFQbAABNGwAATRsAAFQbAABVGwAATRsAAFUbAABWGwAASxsAAE0bAABWGwAASxsAAFYbAABXGwAATBsAAEsbAABXGwAATBsAAFcbAACeEgAAgxoAAEwbAACeEgAAgxoAAJ4SAACEGgAAghoAAEgbAABMGwAAghoAAEwbAACDGgAAgRoAAEUbAABIGwAAgRoAAEgbAACCGgAAWBsAAFkbAABaGwAAWBsAAFobAABbGwAAWRsAAFwbAABdGwAAWRsAAF0bAABaGwAAWxsAAFobAABeGwAAWxsAAF4bAABfGwAAWhsAAF0bAABgGwAAWhsAAGAbAABeGwAAYRsAAGIbAABYGwAAYRsAAFgbAABjGwAAYhsAAGQbAABZGwAAYhsAAFkbAABYGwAAZBsAAGUbAABcGwAAZBsAAFwbAABZGwAAZRsAAKcXAACpFwAAZRsAAKkXAABcGwAAXBsAAKkXAACzFwAAXBsAALMXAABdGwAAXRsAALMXAACxFwAAXRsAALEXAABgGwAAYBsAALEXAACyFwAAYBsAALIXAABmGwAAXhsAAGAbAABmGwAAXhsAAGYbAACKEgAAXxsAAF4bAACKEgAAXxsAAIoSAABnGwAAaBsAAF8bAABnGwAAaBsAAGcbAABpGwAAahsAAFsbAABfGwAAahsAAF8bAABoGwAAYxsAAFgbAABbGwAAYxsAAFsbAABqGwAAaxsAAGwbAABtGwAAaxsAAG0bAABuGwAAbBsAAG8bAABwGwAAbBsAAHAbAABtGwAAbhsAAG0bAABxGwAAbhsAAHEbAAByGwAAbRsAAHAbAABzGwAAbRsAAHMbAABxGwAAdBsAAHUbAABrGwAAdBsAAGsbAAB2GwAAdRsAAHcbAABsGwAAdRsAAGwbAABrGwAAdxsAAHgbAABvGwAAdxsAAG8bAABsGwAAeBsAANgYAADaGAAAeBsAANoYAABvGwAAbxsAANoYAADlGAAAbxsAAOUYAABwGwAAcBsAAOUYAADjGAAAcBsAAOMYAABzGwAAcxsAAOMYAADkGAAAcxsAAOQYAAB5GwAAcRsAAHMbAAB5GwAAcRsAAHkbAAB6GwAAchsAAHEbAAB6GwAAchsAAHobAAB7GwAAfBsAAHIbAAB7GwAAfBsAAHsbAABSDQAAfRsAAG4bAAByGwAAfRsAAHIbAAB8GwAAdhsAAGsbAABuGwAAdhsAAG4bAAB9GwAAfhsAAH8bAACAGwAAfhsAAIAbAACBGwAAfxsAAIIbAACDGwAAfxsAAIMbAACAGwAAgRsAAIAbAACEGwAAgRsAAIQbAACFGwAAgBsAAIMbAACGGwAAgBsAAIYbAACEGwAA8RcAAIcbAAB+GwAA8RcAAH4bAADyFwAAhxsAAIgbAAB/GwAAhxsAAH8bAAB+GwAAiBsAAIkbAACCGwAAiBsAAIIbAAB/GwAAiRsAAIobAACLGwAAiRsAAIsbAACCGwAAghsAAIsbAACMGwAAghsAAIwbAACDGwAAgxsAAIwbAACNGwAAgxsAAI0bAACGGwAAhhsAAI0bAACOGwAAhhsAAI4bAACPGwAAhBsAAIYbAACPGwAAhBsAAI8bAACQGwAAhRsAAIQbAACQGwAAhRsAAJAbAACRGwAA9BcAAIUbAACRGwAA9BcAAJEbAABhEgAA8xcAAIEbAACFGwAA8xcAAIUbAAD0FwAA8hcAAH4bAACBGwAA8hcAAIEbAADzFwAAkhsAAJMbAACUGwAAkhsAAJQbAACVGwAAkxsAAJYbAACXGwAAkxsAAJcbAACUGwAAlRsAAJQbAACYGwAAlRsAAJgbAACZGwAAlBsAAJcbAACaGwAAlBsAAJobAACYGwAAmxsAAJwbAACSGwAAmxsAAJIbAACdGwAAnBsAAJ4bAACTGwAAnBsAAJMbAACSGwAAnhsAAJ8bAACWGwAAnhsAAJYbAACTGwAAnxsAADobAAA8GwAAnxsAADwbAACWGwAAlhsAADwbAABEGwAAlhsAAEQbAACXGwAAlxsAAEQbAABCGwAAlxsAAEIbAACaGwAAmhsAAEIbAABDGwAAmhsAAEMbAACgGwAAmBsAAJobAACgGwAAmBsAAKAbAABOEgAAmRsAAJgbAABOEgAAmRsAAE4SAAChGwAAohsAAJkbAAChGwAAohsAAKEbAACjGwAApBsAAJUbAACZGwAApBsAAJkbAACiGwAAnRsAAJIbAACVGwAAnRsAAJUbAACkGwAApRsAAKYbAACnGwAApRsAAKcbAACoGwAAphsAAKkbAACqGwAAphsAAKobAACnGwAAqBsAAKcbAACrGwAAqBsAAKsbAACsGwAApxsAAKobAACtGwAApxsAAK0bAACrGwAArhsAAK8bAAClGwAArhsAAKUbAACwGwAArxsAALEbAACmGwAArxsAAKYbAAClGwAAsRsAALIbAACpGwAAsRsAAKkbAACmGwAAshsAAO8aAADxGgAAshsAAPEaAACpGwAAqRsAAPEaAAD3GgAAqRsAAPcaAACqGwAAqhsAAPcaAAD1GgAAqhsAAPUaAACtGwAArRsAAPUaAAD2GgAArRsAAPYaAAA7EgAAqxsAAK0bAAA7EgAAqxsAADsSAAA6EgAArBsAAKsbAAA6EgAArBsAADoSAACzGwAAtBsAAKwbAACzGwAAtBsAALMbAAC1GwAAthsAAKgbAACsGwAAthsAAKwbAAC0GwAAsBsAAKUbAACoGwAAsBsAAKgbAAC2GwAAtxsAALgbAAC5GwAAtxsAALkbAAC6GwAAuBsAALsbAAC8GwAAuBsAALwbAAC5GwAAuhsAALkbAAC9GwAAuhsAAL0bAAC+GwAAuRsAALwbAAC/GwAAuRsAAL8bAAC9GwAAwBsAAMEbAAC3GwAAwBsAALcbAADCGwAAwRsAAMMbAAC4GwAAwRsAALgbAAC3GwAAwxsAAMQbAAC7GwAAwxsAALsbAAC4GwAAxBsAAKIaAACkGgAAxBsAAKQaAAC7GwAAuxsAAKQaAACrGgAAuxsAAKsaAAC8GwAAvBsAAKsaAACpGgAAvBsAAKkaAAC/GwAAvxsAAKkaAACqGgAAvxsAAKoaAADFGwAAvRsAAL8bAADFGwAAvRsAAMUbAADGGwAAvhsAAL0bAADGGwAAvhsAAMYbAADHGwAAyBsAAL4bAADHGwAAyBsAAMcbAADJGwAAyhsAALobAAC+GwAAyhsAAL4bAADIGwAAwhsAALcbAAC6GwAAwhsAALobAADKGwAAyxsAAMwbAADNGwAAyxsAAM0bAADOGwAAzBsAAM8bAADQGwAAzBsAANAbAADNGwAAzhsAAM0bAADRGwAAzhsAANEbAADSGwAAzRsAANAbAADTGwAAzRsAANMbAADRGwAA1BsAANUbAADLGwAA1BsAAMsbAADWGwAA1RsAANcbAADMGwAA1RsAAMwbAADLGwAA1xsAANgbAADPGwAA1xsAAM8bAADMGwAA2BsAABMbAAAVGwAA2BsAABUbAADPGwAAzxsAABUbAAAdGwAAzxsAAB0bAADQGwAA0BsAAB0bAAAbGwAA0BsAABsbAADTGwAA0xsAABsbAAAcGwAA0xsAABwbAAATEgAA0RsAANMbAAATEgAA0RsAABMSAAASEgAA0hsAANEbAAASEgAA0hsAABISAAAREgAA2RsAANIbAAAREgAA2RsAABESAADaGwAA2xsAAM4bAADSGwAA2xsAANIbAADZGwAA1hsAAMsbAADOGwAA1hsAAM4bAADbGwAA3BsAAN0bAADeGwAA3BsAAN4bAADfGwAA3RsAAOAbAADhGwAA3RsAAOEbAADeGwAA3xsAAN4bAADiGwAA3xsAAOIbAADjGwAA3hsAAOEbAADkGwAA3hsAAOQbAADiGwAAShoAAOUbAADcGwAAShoAANwbAABLGgAA5RsAAOYbAADdGwAA5RsAAN0bAADcGwAA5hsAAOcbAADgGwAA5hsAAOAbAADdGwAA5xsAAOgbAADpGwAA5xsAAOkbAADgGwAA4BsAAOkbAADqGwAA4BsAAOobAADhGwAA4RsAAOobAADrGwAA4RsAAOsbAADkGwAA5BsAAOsbAADsGwAA5BsAAOwbAADtGwAA4hsAAOQbAADtGwAA4hsAAO0bAAAAEgAA4xsAAOIbAAAAEgAA4xsAAAASAADuGwAATRoAAOMbAADuGwAATRoAAO4bAABOGgAATBoAAN8bAADjGwAATBoAAOMbAABNGgAASxoAANwbAADfGwAASxoAAN8bAABMGgAA7xsAAPAbAADxGwAA7xsAAPEbAADyGwAA8BsAAPMbAAD0GwAA8BsAAPQbAADxGwAA8hsAAPEbAAD1GwAA8hsAAPUbAAD2GwAA8RsAAPQbAAD3GwAA8RsAAPcbAAD1GwAAKhsAAPgbAADvGwAAKhsAAO8bAAArGwAA+BsAAPkbAADwGwAA+BsAAPAbAADvGwAA+RsAAPobAADzGwAA+RsAAPMbAADwGwAA+hsAAPsbAAD8GwAA+hsAAPwbAADzGwAA8xsAAPwbAAD9GwAA8xsAAP0bAAD0GwAA9BsAAP0bAAD+GwAA9BsAAP4bAAD3GwAA9xsAAP4bAADqEAAA9xsAAOoQAAD/GwAA9RsAAPcbAAD/GwAA9RsAAP8bAADsEQAA9hsAAPUbAADsEQAA9hsAAOwRAAAAHAAALRsAAPYbAAAAHAAALRsAAAAcAAAuGwAALBsAAPIbAAD2GwAALBsAAPYbAAAtGwAAKxsAAO8bAADyGwAAKxsAAPIbAAAsGwAAARwAAAIcAAADHAAAARwAAAMcAAAEHAAAAhwAAAUcAAAGHAAAAhwAAAYcAAADHAAABBwAAAMcAAAHHAAABBwAAAccAAAIHAAAAxwAAAYcAAAJHAAAAxwAAAkcAAAHHAAAChwAAAscAAABHAAAChwAAAEcAAAMHAAACxwAAA0cAAACHAAACxwAAAIcAAABHAAADRwAAA4cAAAFHAAADRwAAAUcAAACHAAADhwAAJsbAACdGwAADhwAAJ0bAAAFHAAABRwAAJ0bAACkGwAABRwAAKQbAAAGHAAABhwAAKQbAACiGwAABhwAAKIbAAAJHAAACRwAAKIbAACjGwAACRwAAKMbAAAPHAAABxwAAAkcAAAPHAAABxwAAA8cAADWEQAACBwAAAccAADWEQAACBwAANYRAAAQHAAAERwAAAgcAAAQHAAAERwAABAcAAASHAAAExwAAAQcAAAIHAAAExwAAAgcAAARHAAADBwAAAEcAAAEHAAADBwAAAQcAAATHAAAFBwAABUcAAAWHAAAFBwAABYcAAAXHAAAFRwAABgcAAAZHAAAFRwAABkcAAAWHAAAFxwAABYcAAAaHAAAFxwAABocAAAbHAAAFhwAABkcAAAcHAAAFhwAABwcAAAaHAAAHRwAAB4cAAAUHAAAHRwAABQcAAAfHAAAHhwAACAcAAAVHAAAHhwAABUcAAAUHAAAIBwAACEcAAAYHAAAIBwAABgcAAAVHAAAIRwAACIcAAAjHAAAIRwAACMcAAAYHAAAGBwAACMcAAAkHAAAGBwAACQcAAAZHAAAGRwAACQcAAAlHAAAGRwAACUcAAAcHAAAHBwAACUcAAAmHAAAHBwAACYcAADIEQAAGhwAABwcAADIEQAAGhwAAMgRAAAnHAAAGxwAABocAAAnHAAAGxwAACccAADGEQAAKBwAABscAADGEQAAKBwAAMYRAAApHAAAKhwAABccAAAbHAAAKhwAABscAAAoHAAAHxwAABQcAAAXHAAAHxwAABccAAAqHAAAKxwAACwcAAAtHAAAKxwAAC0cAAAuHAAALBwAAC8cAAAwHAAALBwAADAcAAAtHAAALhwAAC0cAAAxHAAALhwAADEcAAAyHAAALRwAADAcAAAzHAAALRwAADMcAAAxHAAAzBoAADQcAAArHAAAzBoAACscAADNGgAANBwAADUcAAAsHAAANBwAACwcAAArHAAANRwAADYcAAAvHAAANRwAAC8cAAAsHAAANhwAADccAAA4HAAANhwAADgcAAAvHAAALxwAADgcAAA5HAAALxwAADkcAAAwHAAAMBwAADkcAAA6HAAAMBwAADocAAAzHAAAMxwAADocAAA7HAAAMxwAADscAAA8HAAAMRwAADMcAAA8HAAAMRwAADwcAAA9HAAAMhwAADEcAAA9HAAAMhwAAD0cAAA+HAAAzxoAADIcAAA+HAAAzxoAAD4cAACyEQAAzhoAAC4cAAAyHAAAzhoAADIcAADPGgAAzRoAACscAAAuHAAAzRoAAC4cAADOGgAAPxwAAEAcAABBHAAAPxwAAEEcAABCHAAAQBwAAEMcAABEHAAAQBwAAEQcAABBHAAAQhwAAEEcAABFHAAAQhwAAEUcAABGHAAAQRwAAEQcAABHHAAAQRwAAEccAABFHAAAURsAAEgcAAA/HAAAURsAAD8cAABSGwAASBwAAEkcAABAHAAASBwAAEAcAAA/HAAASRwAAEocAABDHAAASRwAAEMcAABAHAAAShwAAEscAABMHAAAShwAAEwcAABDHAAAQxwAAEwcAABNHAAAQxwAAE0cAABEHAAARBwAAE0cAABOHAAARBwAAE4cAABHHAAARxwAAE4cAABPHAAARxwAAE8cAABQHAAARRwAAEccAABQHAAARRwAAFAcAABRHAAARhwAAEUcAABRHAAARhwAAFEcAABSHAAAVBsAAEYcAABSHAAAVBsAAFIcAABVGwAAUxsAAEIcAABGHAAAUxsAAEYcAABUGwAAUhsAAD8cAABCHAAAUhsAAEIcAABTGwAAUxwAAFQcAABVHAAAUxwAAFUcAABWHAAAVBwAAFccAABYHAAAVBwAAFgcAABVHAAAVhwAAFUcAABZHAAAVhwAAFkcAABaHAAAVRwAAFgcAABbHAAAVRwAAFscAABZHAAAIhwAAFwcAABTHAAAIhwAAFMcAAAjHAAAXBwAAF0cAABUHAAAXBwAAFQcAABTHAAAXRwAAF4cAABXHAAAXRwAAFccAABUHAAAXhwAAF8cAABgHAAAXhwAAGAcAABXHAAAVxwAAGAcAABhHAAAVxwAAGEcAABYHAAAWBwAAGEcAABiHAAAWBwAAGIcAABbHAAAWxwAAGIcAABjHAAAWxwAAGMcAABkHAAAWRwAAFscAABkHAAAWRwAAGQcAABlHAAAWhwAAFkcAABlHAAAWhwAAGUcAABmHAAAJRwAAFocAABmHAAAJRwAAGYcAAAmHAAAJBwAAFYcAABaHAAAJBwAAFocAAAlHAAAIxwAAFMcAABWHAAAIxwAAFYcAAAkHAAAZxwAAGgcAABpHAAAZxwAAGkcAABqHAAAaBwAAGscAABsHAAAaBwAAGwcAABpHAAAahwAAGkcAABtHAAAahwAAG0cAABuHAAAaRwAAGwcAABvHAAAaRwAAG8cAABtHAAAcBwAAHEcAABnHAAAcBwAAGccAAByHAAAcRwAAHMcAABoHAAAcRwAAGgcAABnHAAAcxwAAHQcAABrHAAAcxwAAGscAABoHAAAdBwAAAocAAAMHAAAdBwAAAwcAABrHAAAaxwAAAwcAAATHAAAaxwAABMcAABsHAAAbBwAABMcAAARHAAAbBwAABEcAABvHAAAbxwAABEcAAASHAAAbxwAABIcAAB1HAAAbRwAAG8cAAB1HAAAbRwAAHUcAAB2HAAAbhwAAG0cAAB2HAAAbhwAAHYcAAB3HAAAeBwAAG4cAAB3HAAAeBwAAHccAAB5HAAAehwAAGocAABuHAAAehwAAG4cAAB4HAAAchwAAGccAABqHAAAchwAAGocAAB6HAAAexwAAHwcAAB9HAAAexwAAH0cAAB+HAAAfBwAAH8cAACAHAAAfBwAAIAcAAB9HAAAfhwAAH0cAACBHAAAfhwAAIEcAACCHAAAfRwAAIAcAACDHAAAfRwAAIMcAACBHAAAhBwAAIUcAAB7HAAAhBwAAHscAACGHAAAhRwAAIccAAB8HAAAhRwAAHwcAAB7HAAAhxwAAIgcAAB/HAAAhxwAAH8cAAB8HAAAiBwAANwaAADeGgAAiBwAAN4aAAB/HAAAfxwAAN4aAADlGgAAfxwAAOUaAACAHAAAgBwAAOUaAADjGgAAgBwAAOMaAACDHAAAgxwAAOMaAADkGgAAgxwAAOQaAACJHAAAgRwAAIMcAACJHAAAgRwAAIkcAACKHAAAghwAAIEcAACKHAAAghwAAIocAABiEQAAixwAAIIcAABiEQAAixwAAGIRAACMHAAAjRwAAH4cAACCHAAAjRwAAIIcAACLHAAAhhwAAHscAAB+HAAAhhwAAH4cAACNHAAAjhwAAI8cAACQHAAAjhwAAJAcAACRHAAAjxwAAJIcAACTHAAAjxwAAJMcAACQHAAAkRwAAJAcAACUHAAAkRwAAJQcAACVHAAAkBwAAJMcAACWHAAAkBwAAJYcAACUHAAAlxwAAJgcAACOHAAAlxwAAI4cAACZHAAAmBwAAJocAACPHAAAmBwAAI8cAACOHAAAmhwAAJscAACSHAAAmhwAAJIcAACPHAAAmxwAAK4bAACwGwAAmxwAALAbAACSHAAAkhwAALAbAAC2GwAAkhwAALYbAACTHAAAkxwAALYbAAC0GwAAkxwAALQbAACWHAAAlhwAALQbAAC1GwAAlhwAALUbAABQEQAAlBwAAJYcAABQEQAAlBwAAFARAABPEQAAlRwAAJQcAABPEQAAlRwAAE8RAACcHAAAnRwAAJUcAACcHAAAnRwAAJwcAABIEAAAnhwAAJEcAACVHAAAnhwAAJUcAACdHAAAmRwAAI4cAACRHAAAmRwAAJEcAACeHAAAnxwAAKAcAAChHAAAnxwAAKEcAACiHAAAoBwAAKMcAACkHAAAoBwAAKQcAAChHAAAohwAAKEcAAClHAAAohwAAKUcAACmHAAAoRwAAKQcAACnHAAAoRwAAKccAAClHAAAXxwAAKgcAACfHAAAXxwAAJ8cAABgHAAAqBwAAKkcAACgHAAAqBwAAKAcAACfHAAAqRwAAKocAACjHAAAqRwAAKMcAACgHAAAqhwAAKscAACsHAAAqhwAAKwcAACjHAAAoxwAAKwcAACtHAAAoxwAAK0cAACkHAAApBwAAK0cAACuHAAApBwAAK4cAACnHAAApxwAAK4cAAAxEAAApxwAADEQAAA+EQAApRwAAKccAAA+EQAApRwAAD4RAACvHAAAphwAAKUcAACvHAAAphwAAK8cAACwHAAAYhwAAKYcAACwHAAAYhwAALAcAABjHAAAYRwAAKIcAACmHAAAYRwAAKYcAABiHAAAYBwAAJ8cAACiHAAAYBwAAKIcAABhHAAAsRwAALIcAACzHAAAsRwAALMcAAC0HAAAshwAALUcAAC2HAAAshwAALYcAACzHAAAtBwAALMcAAC3HAAAtBwAALccAAC4HAAAsxwAALYcAAC5HAAAsxwAALkcAAC3HAAAuhwAALscAACxHAAAuhwAALEcAAC8HAAAuxwAAL0cAACyHAAAuxwAALIcAACxHAAAvRwAAL4cAAC1HAAAvRwAALUcAACyHAAAvhwAAMAbAADCGwAAvhwAAMIbAAC1HAAAtRwAAMIbAADKGwAAtRwAAMobAAC2HAAAthwAAMobAADIGwAAthwAAMgbAAC5HAAAuRwAAMgbAADJGwAAuRwAAMkbAAAoEQAAtxwAALkcAAAoEQAAtxwAACgRAAC/HAAAuBwAALccAAC/HAAAuBwAAL8cAADAHAAAwRwAALgcAADAHAAAwRwAAMAcAADCHAAAwxwAALQcAAC4HAAAwxwAALgcAADBHAAAvBwAALEcAAC0HAAAvBwAALQcAADDHAAAxBwAAMUcAADGHAAAxBwAAMYcAADHHAAAxRwAAMgcAADJHAAAxRwAAMkcAADGHAAAxxwAAMYcAADKHAAAxxwAAMocAADLHAAAxhwAAMkcAADMHAAAxhwAAMwcAADKHAAAzRwAAM4cAADEHAAAzRwAAMQcAADPHAAAzhwAANAcAADFHAAAzhwAAMUcAADEHAAA0BwAANEcAADIHAAA0BwAAMgcAADFHAAA0RwAANQbAADWGwAA0RwAANYbAADIHAAAyBwAANYbAADbGwAAyBwAANsbAADJHAAAyRwAANsbAADZGwAAyRwAANkbAADMHAAAzBwAANkbAADaGwAAzBwAANobAADSHAAAyhwAAMwcAADSHAAAyhwAANIcAAATEQAAyxwAAMocAAATEQAAyxwAABMRAADTHAAA1BwAAMscAADTHAAA1BwAANMcAADVHAAA1hwAAMccAADLHAAA1hwAAMscAADUHAAAzxwAAMQcAADHHAAAzxwAAMccAADWHAAA1xwAANgcAADZHAAA1xwAANkcAADaHAAA2BwAANscAADcHAAA2BwAANwcAADZHAAA2hwAANkcAADdHAAA2hwAAN0cAADeHAAA2RwAANwcAADfHAAA2RwAAN8cAADdHAAA6BsAAOAcAADXHAAA6BsAANccAADpGwAA4BwAAOEcAADYHAAA4BwAANgcAADXHAAA4RwAAOIcAADbHAAA4RwAANscAADYHAAA4hwAAOMcAADkHAAA4hwAAOQcAADbHAAA2xwAAOQcAADlHAAA2xwAAOUcAADcHAAA3BwAAOUcAADmHAAA3BwAAOYcAADfHAAA3xwAAOYcAADnHAAA3xwAAOccAADoHAAA3RwAAN8cAADoHAAA3RwAAOgcAADpHAAA3hwAAN0cAADpHAAA3hwAAOkcAADqHAAA6xsAAN4cAADqHAAA6xsAAOocAADsGwAA6hsAANocAADeHAAA6hsAAN4cAADrGwAA6RsAANccAADaHAAA6RsAANocAADqGwAA6xwAAOwcAADtHAAA6xwAAO0cAADuHAAA7BwAAO8cAADwHAAA7BwAAPAcAADtHAAA7hwAAO0cAADxHAAA7hwAAPEcAADyHAAA7RwAAPAcAADzHAAA7RwAAPMcAADxHAAA+xsAAPQcAADrHAAA+xsAAOscAAD8GwAA9BwAAPUcAADsHAAA9BwAAOwcAADrHAAA9RwAAPYcAADvHAAA9RwAAO8cAADsHAAA9hwAAPccAAD4HAAA9hwAAPgcAADvHAAA7xwAAPgcAAD5HAAA7xwAAPkcAADwHAAA8BwAAPkcAAD6HAAA8BwAAPocAADzHAAA8xwAAPocAAD7HAAA8xwAAPscAAD8HAAA8RwAAPMcAAD8HAAA8RwAAPwcAADtEAAA8hwAAPEcAADtEAAA8hwAAO0QAADrEAAA/hsAAPIcAADrEAAA/hsAAOsQAADqEAAA/RsAAO4cAADyHAAA/RsAAPIcAAD+GwAA/BsAAOscAADuHAAA/BsAAO4cAAD9GwAA/RwAAP4cAAD/HAAA/RwAAP8cAAAAHQAA/hwAAAEdAAACHQAA/hwAAAIdAAD/HAAAAB0AAP8cAAADHQAAAB0AAAMdAAAEHQAA/xwAAAIdAAAFHQAA/xwAAAUdAAADHQAABh0AAAcdAAD9HAAABh0AAP0cAAAIHQAABx0AAAkdAAD+HAAABx0AAP4cAAD9HAAACR0AAAodAAABHQAACR0AAAEdAAD+HAAACh0AAHAcAAByHAAACh0AAHIcAAABHQAAAR0AAHIcAAB6HAAAAR0AAHocAAACHQAAAh0AAHocAAB4HAAAAh0AAHgcAAAFHQAABR0AAHgcAAB5HAAABR0AAHkcAADYEAAAAx0AAAUdAADYEAAAAx0AANgQAADXEAAABB0AAAMdAADXEAAABB0AANcQAADWEAAACx0AAAQdAADWEAAACx0AANYQAAAMHQAADR0AAAAdAAAEHQAADR0AAAQdAAALHQAACB0AAP0cAAAAHQAACB0AAAAdAAANHQAADh0AAA8dAAAQHQAADh0AABAdAAARHQAADx0AABIdAAATHQAADx0AABMdAAAQHQAAER0AABAdAAAUHQAAER0AABQdAAAVHQAAEB0AABMdAAAWHQAAEB0AABYdAAAUHQAANxwAABcdAAAOHQAANxwAAA4dAAA4HAAAFx0AABgdAAAPHQAAFx0AAA8dAAAOHQAAGB0AABkdAAASHQAAGB0AABIdAAAPHQAAGR0AABodAAAbHQAAGR0AABsdAAASHQAAEh0AABsdAAAcHQAAEh0AABwdAAATHQAAEx0AABwdAAAdHQAAEx0AAB0dAAAWHQAAFh0AAB0dAAB9DwAAFh0AAH0PAAAeHQAAFB0AABYdAAAeHQAAFB0AAB4dAADFEAAAFR0AABQdAADFEAAAFR0AAMUQAAAfHQAAOhwAABUdAAAfHQAAOhwAAB8dAAA7HAAAORwAABEdAAAVHQAAORwAABUdAAA6HAAAOBwAAA4dAAARHQAAOBwAABEdAAA5HAAAIB0AACEdAAAiHQAAIB0AACIdAAAjHQAAIR0AACQdAAAlHQAAIR0AACUdAAAiHQAAIx0AACIdAAAmHQAAIx0AACYdAAAnHQAAIh0AACUdAAAoHQAAIh0AACgdAAAmHQAASxwAACkdAAAgHQAASxwAACAdAABMHAAAKR0AACodAAAhHQAAKR0AACEdAAAgHQAAKh0AACsdAAAkHQAAKh0AACQdAAAhHQAAKx0AACwdAAAtHQAAKx0AAC0dAAAkHQAAJB0AAC0dAAAuHQAAJB0AAC4dAAAlHQAAJR0AAC4dAAAvHQAAJR0AAC8dAAAoHQAAKB0AAC8dAADNDwAAKB0AAM0PAAAwHQAAJh0AACgdAAAwHQAAJh0AADAdAAAxHQAAJx0AACYdAAAxHQAAJx0AADEdAACvEAAAThwAACcdAACvEAAAThwAAK8QAABPHAAATRwAACMdAAAnHQAATRwAACcdAABOHAAATBwAACAdAAAjHQAATBwAACMdAABNHAAAMh0AADMdAAA0HQAAMh0AADQdAAA1HQAAMx0AADYdAAA3HQAAMx0AADcdAAA0HQAANR0AADQdAAA4HQAANR0AADgdAAA5HQAANB0AADcdAAA6HQAANB0AADodAAA4HQAAOx0AADwdAAAyHQAAOx0AADIdAAA9HQAAPB0AAD4dAAAzHQAAPB0AADMdAAAyHQAAPh0AAD8dAAA2HQAAPh0AADYdAAAzHQAAPx0AAAYdAAAIHQAAPx0AAAgdAAA2HQAANh0AAAgdAAANHQAANh0AAA0dAAA3HQAANx0AAA0dAAALHQAANx0AAAsdAAA6HQAAOh0AAAsdAAAMHQAAOh0AAAwdAABAHQAAOB0AADodAABAHQAAOB0AAEAdAACbEAAAOR0AADgdAACbEAAAOR0AAJsQAABBHQAAQh0AADkdAABBHQAAQh0AAEEdAABDHQAARB0AADUdAAA5HQAARB0AADkdAABCHQAAPR0AADIdAAA1HQAAPR0AADUdAABEHQAARR0AAEYdAABHHQAARR0AAEcdAABIHQAARh0AAEkdAABKHQAARh0AAEodAABHHQAASB0AAEcdAABLHQAASB0AAEsdAABMHQAARx0AAEodAABNHQAARx0AAE0dAABLHQAATh0AAE8dAABFHQAATh0AAEUdAABQHQAATx0AAFEdAABGHQAATx0AAEYdAABFHQAAUR0AAFIdAABJHQAAUR0AAEkdAABGHQAAUh0AAB0cAAAfHAAAUh0AAB8cAABJHQAASR0AAB8cAAAqHAAASR0AACocAABKHQAASh0AACocAAAoHAAASh0AACgcAABNHQAATR0AACgcAAApHAAATR0AACkcAABTHQAASx0AAE0dAABTHQAASx0AAFMdAACHEAAATB0AAEsdAACHEAAATB0AAIcQAABUHQAAVR0AAEwdAABUHQAAVR0AAFQdAACUDwAAVh0AAEgdAABMHQAAVh0AAEwdAABVHQAAUB0AAEUdAABIHQAAUB0AAEgdAABWHQAAVx0AAFgdAABZHQAAVx0AAFkdAABaHQAAWB0AAFsdAABcHQAAWB0AAFwdAABZHQAAWh0AAFkdAABdHQAAWh0AAF0dAABeHQAAWR0AAFwdAABfHQAAWR0AAF8dAABdHQAA6BkAAGAdAABXHQAA6BkAAFcdAADpGQAAYB0AAGEdAABYHQAAYB0AAFgdAABXHQAAYR0AAGIdAABbHQAAYR0AAFsdAABYHQAAYh0AAGMdAABkHQAAYh0AAGQdAABbHQAAWx0AAGQdAABlHQAAWx0AAGUdAABcHQAAXB0AAGUdAABmHQAAXB0AAGYdAABfHQAAXx0AAGYdAABnHQAAXx0AAGcdAABoHQAAXR0AAF8dAABoHQAAXR0AAGgdAABwEAAAXh0AAF0dAABwEAAAXh0AAHAQAABpHQAA6xkAAF4dAABpHQAA6xkAAGkdAADsGQAA6hkAAFodAABeHQAA6hkAAF4dAADrGQAA6RkAAFcdAABaHQAA6RkAAFodAADqGQAAah0AAGsdAABsHQAAah0AAGwdAABtHQAAax0AAG4dAABvHQAAax0AAG8dAABsHQAAbR0AAGwdAABwHQAAbR0AAHAdAABxHQAAbB0AAG8dAAByHQAAbB0AAHIdAABwHQAAcx0AAHQdAABqHQAAcx0AAGodAAB1HQAAdB0AAHYdAABrHQAAdB0AAGsdAABqHQAAdh0AAHcdAABuHQAAdh0AAG4dAABrHQAAdx0AAIQcAACGHAAAdx0AAIYcAABuHQAAbh0AAIYcAACNHAAAbh0AAI0cAABvHQAAbx0AAI0cAACLHAAAbx0AAIscAAByHQAAch0AAIscAACMHAAAch0AAIwcAAB4HQAAcB0AAHIdAAB4HQAAcB0AAHgdAABaEAAAcR0AAHAdAABaEAAAcR0AAFoQAAB5HQAAeh0AAHEdAAB5HQAAeh0AAHkdAAB7HQAAfB0AAG0dAABxHQAAfB0AAHEdAAB6HQAAdR0AAGodAABtHQAAdR0AAG0dAAB8HQAAfR0AAH4dAAB/HQAAfR0AAH8dAACAHQAAfh0AAIEdAACCHQAAfh0AAIIdAAB/HQAAgB0AAH8dAACDHQAAgB0AAIMdAACEHQAAfx0AAIIdAACFHQAAfx0AAIUdAACDHQAAhh0AAIcdAAB9HQAAhh0AAH0dAACIHQAAhx0AAIkdAAB+HQAAhx0AAH4dAAB9HQAAiR0AAIodAACBHQAAiR0AAIEdAAB+HQAAih0AAJccAACZHAAAih0AAJkcAACBHQAAgR0AAJkcAACeHAAAgR0AAJ4cAACCHQAAgh0AAJ4cAACdHAAAgh0AAJ0cAACFHQAAhR0AAJ0cAABIEAAAhR0AAEgQAABHEAAAgx0AAIUdAABHEAAAgx0AAEcQAACLHQAAhB0AAIMdAACLHQAAhB0AAIsdAACMHQAAjR0AAIQdAACMHQAAjR0AAIwdAACOHQAAjx0AAIAdAACEHQAAjx0AAIQdAACNHQAAiB0AAH0dAACAHQAAiB0AAIAdAACPHQAAkB0AAJEdAACSHQAAkB0AAJIdAACTHQAAkR0AAJQdAACVHQAAkR0AAJUdAACSHQAAkx0AAJIdAACWHQAAkx0AAJYdAACXHQAAkh0AAJUdAACYHQAAkh0AAJgdAACWHQAAqxwAAJkdAACQHQAAqxwAAJAdAACsHAAAmR0AAJodAACRHQAAmR0AAJEdAACQHQAAmh0AAJsdAACUHQAAmh0AAJQdAACRHQAAmx0AAJwdAACdHQAAmx0AAJ0dAACUHQAAlB0AAJ0dAACeHQAAlB0AAJ4dAACVHQAAlR0AAJ4dAACfHQAAlR0AAJ8dAACYHQAAmB0AAJ8dAACgHQAAmB0AAKAdAAChHQAAlh0AAJgdAAChHQAAlh0AAKEdAAA0EAAAlx0AAJYdAAA0EAAAlx0AADQQAACiHQAArhwAAJcdAACiHQAArhwAAKIdAAAxEAAArRwAAJMdAACXHQAArRwAAJcdAACuHAAArBwAAJAdAACTHQAArBwAAJMdAACtHAAAox0AAKQdAAClHQAAox0AAKUdAACmHQAApB0AAKcdAACoHQAApB0AAKgdAAClHQAAph0AAKUdAACpHQAAph0AAKkdAACqHQAApR0AAKgdAACrHQAApR0AAKsdAACpHQAArB0AAK0dAACjHQAArB0AAKMdAACuHQAArR0AAK8dAACkHQAArR0AAKQdAACjHQAArx0AALAdAACnHQAArx0AAKcdAACkHQAAsB0AAM0cAADPHAAAsB0AAM8cAACnHQAApx0AAM8cAADWHAAApx0AANYcAACoHQAAqB0AANYcAADUHAAAqB0AANQcAACrHQAAqx0AANQcAADVHAAAqx0AANUcAACxHQAAqR0AAKsdAACxHQAAqR0AALEdAACyHQAAqh0AAKkdAACyHQAAqh0AALIdAAAdEAAAsx0AAKodAAAdEAAAsx0AAB0QAAAwDwAAtB0AAKYdAACqHQAAtB0AAKodAACzHQAArh0AAKMdAACmHQAArh0AAKYdAAC0HQAAtR0AALYdAAC3HQAAtR0AALcdAAC4HQAAth0AALkdAAC6HQAAth0AALodAAC3HQAAuB0AALcdAAC7HQAAuB0AALsdAAC8HQAAtx0AALodAAC9HQAAtx0AAL0dAAC7HQAAihsAAL4dAAC1HQAAihsAALUdAACLGwAAvh0AAL8dAAC2HQAAvh0AALYdAAC1HQAAvx0AAMAdAAC5HQAAvx0AALkdAAC2HQAAwB0AAMEdAADCHQAAwB0AAMIdAAC5HQAAuR0AAMIdAADDHQAAuR0AAMMdAAC6HQAAuh0AAMMdAADEHQAAuh0AAMQdAAC9HQAAvR0AAMQdAADFHQAAvR0AAMUdAADGHQAAux0AAL0dAADGHQAAux0AAMYdAAAMEAAAvB0AALsdAAAMEAAAvB0AAAwQAADHHQAAjRsAALwdAADHHQAAjRsAAMcdAACOGwAAjBsAALgdAAC8HQAAjBsAALwdAACNGwAAixsAALUdAAC4HQAAixsAALgdAACMGwAAyB0AAMkdAADKHQAAyB0AAModAADLHQAAyR0AAMwdAADNHQAAyR0AAM0dAADKHQAAyx0AAModAADOHQAAyx0AAM4dAADPHQAAyh0AAM0dAADQHQAAyh0AANAdAADOHQAA9xwAANEdAADIHQAA9xwAAMgdAAD4HAAA0R0AANIdAADJHQAA0R0AAMkdAADIHQAA0h0AANMdAADMHQAA0h0AAMwdAADJHQAA0x0AANQdAADVHQAA0x0AANUdAADMHQAAzB0AANUdAADWHQAAzB0AANYdAADNHQAAzR0AANYdAADXHQAAzR0AANcdAADQHQAA0B0AANcdAADYHQAA0B0AANgdAADZHQAAzh0AANAdAADZHQAAzh0AANkdAAD4DwAAzx0AAM4dAAD4DwAAzx0AAPgPAADaHQAA+hwAAM8dAADaHQAA+hwAANodAAD7HAAA+RwAAMsdAADPHQAA+RwAAM8dAAD6HAAA+BwAAMgdAADLHQAA+BwAAMsdAAD5HAAA2x0AANwdAADdHQAA2x0AAN0dAADeHQAA3B0AAN8dAADgHQAA3B0AAOAdAADdHQAA3h0AAN0dAADhHQAA3h0AAOEdAADiHQAA3R0AAOAdAADjHQAA3R0AAOMdAADhHQAA5B0AAOUdAADbHQAA5B0AANsdAADmHQAA5R0AAOcdAADcHQAA5R0AANwdAADbHQAA5x0AAOgdAADfHQAA5x0AAN8dAADcHQAA6B0AADsdAAA9HQAA6B0AAD0dAADfHQAA3x0AAD0dAABEHQAA3x0AAEQdAADgHQAA4B0AAEQdAABCHQAA4B0AAEIdAADjHQAA4x0AAEIdAABDHQAA4x0AAEMdAADjDwAA4R0AAOMdAADjDwAA4R0AAOMPAADpHQAA4h0AAOEdAADpHQAA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RR4AAEceAAA+HgAAPh4AAEceAABIHgAAPh4AAEgeAAA/HgAAPx4AAEgeAABJHgAAPx4AAEkeAABCHgAAQh4AAEkeAABKHgAAQh4AAEoeAABLHgAAQB4AAEIeAABLHgAAQB4AAEseAABMHgAAQR4AAEAeAABMHgAAQR4AAEweAAB+DwAAHR0AAEEeAAB+DwAAHR0AAH4PAAB9DwAAHB0AAD0eAABBHgAAHB0AAEEeAAAdHQAAGx0AADoeAAA9HgAAGx0AAD0eAAAcHQAATR4AAE4eAABPHgAATR4AAE8eAABQHgAATh4AAFEeAABSHgAATh4AAFIeAABPHgAAUB4AAE8eAABTHgAAUB4AAFMeAABUHgAATx4AAFIeAABVHgAATx4AAFUeAABTHgAAVh4AAFceAABNHgAAVh4AAE0eAABYHgAAVx4AAFkeAABOHgAAVx4AAE4eAABNHgAAWR4AAFoeAABRHgAAWR4AAFEeAABOHgAAWh4AAGEbAABjGwAAWh4AAGMbAABRHgAAUR4AAGMbAABqGwAAUR4AAGobAABSHgAAUh4AAGobAABoGwAAUh4AAGgbAABVHgAAVR4AAGgbAABpGwAAVR4AAGkbAABbHgAAUx4AAFUeAABbHgAAUx4AAFseAABqDwAAVB4AAFMeAABqDwAAVB4AAGoPAABcHgAAXR4AAFQeAABcHgAAXR4AAFweAACEDQAAXh4AAFAeAABUHgAAXh4AAFQeAABdHgAAWB4AAE0eAABQHgAAWB4AAFAeAABeHgAAXx4AAGAeAABhHgAAXx4AAGEeAABiHgAAYB4AAGMeAABkHgAAYB4AAGQeAABhHgAAYh4AAGEeAABlHgAAYh4AAGUeAABmHgAAYR4AAGQeAABnHgAAYR4AAGceAABlHgAAaB4AAGkeAABfHgAAaB4AAF8eAABqHgAAaR4AAGseAABgHgAAaR4AAGAeAABfHgAAax4AAGweAABjHgAAax4AAGMeAABgHgAAbB4AAIYdAACIHQAAbB4AAIgdAABjHgAAYx4AAIgdAACPHQAAYx4AAI8dAABkHgAAZB4AAI8dAACNHQAAZB4AAI0dAABnHgAAZx4AAI0dAACOHQAAZx4AAI4dAABXDwAAZR4AAGceAABXDwAAZR4AAFcPAABWDwAAZh4AAGUeAABWDwAAZh4AAFYPAABVDwAAbR4AAGYeAABVDwAAbR4AAFUPAABuHgAAbx4AAGIeAABmHgAAbx4AAGYeAABtHgAAah4AAF8eAABiHgAAah4AAGIeAABvHgAAcB4AAHEeAAByHgAAcB4AAHIeAABzHgAAcR4AAHQeAAB1HgAAcR4AAHUeAAByHgAAcx4AAHIeAAB2HgAAcx4AAHYeAAB3HgAAch4AAHUeAAB4HgAAch4AAHgeAAB2HgAAnB0AAHkeAABwHgAAnB0AAHAeAACdHQAAeR4AAHoeAABxHgAAeR4AAHEeAABwHgAAeh4AAHseAAB0HgAAeh4AAHQeAABxHgAAex4AAHweAAB9HgAAex4AAH0eAAB0HgAAdB4AAH0eAAB+HgAAdB4AAH4eAAB1HgAAdR4AAH4eAAB/HgAAdR4AAH8eAAB4HgAAeB4AAH8eAACAHgAAeB4AAIAeAACBHgAAdh4AAHgeAACBHgAAdh4AAIEeAACCHgAAdx4AAHYeAACCHgAAdx4AAIIeAACDHgAAnx0AAHceAACDHgAAnx0AAIMeAACgHQAAnh0AAHMeAAB3HgAAnh0AAHceAACfHQAAnR0AAHAeAABzHgAAnR0AAHMeAACeHQAAhB4AAIUeAACGHgAAhB4AAIYeAACHHgAAhR4AAIgeAACJHgAAhR4AAIkeAACGHgAAhx4AAIYeAACKHgAAhx4AAIoeAACLHgAAhh4AAIkeAACMHgAAhh4AAIweAACKHgAAjR4AAI4eAACEHgAAjR4AAIQeAACPHgAAjh4AAJAeAACFHgAAjh4AAIUeAACEHgAAkB4AAJEeAACIHgAAkB4AAIgeAACFHgAAkR4AAKwdAACuHQAAkR4AAK4dAACIHgAAiB4AAK4dAAC0HQAAiB4AALQdAACJHgAAiR4AALQdAACzHQAAiR4AALMdAACMHgAAjB4AALMdAAAwDwAAjB4AADAPAACSHgAAih4AAIweAACSHgAAih4AAJIeAAAuDwAAix4AAIoeAAAuDwAAix4AAC4PAAAtDwAAkx4AAIseAAAtDwAAkx4AAC0PAAAdDgAAlB4AAIceAACLHgAAlB4AAIseAACTHgAAjx4AAIQeAACHHgAAjx4AAIceAACUHgAAlR4AAJYeAACXHgAAlR4AAJceAACYHgAAlh4AAJkeAACaHgAAlh4AAJoeAACXHgAAmB4AAJceAACbHgAAmB4AAJseAACcHgAAlx4AAJoeAACdHgAAlx4AAJ0eAACbHgAAnh4AAJ8eAACVHgAAnh4AAJUeAACgHgAAnx4AAKEeAACWHgAAnx4AAJYeAACVHgAAoR4AAKIeAACZHgAAoR4AAJkeAACWHgAAoh4AAKMeAACkHgAAoh4AAKQeAACZHgAAmR4AAKQeAAClHgAAmR4AAKUeAACaHgAAmh4AAKUeAACmHgAAmh4AAKYeAACdHgAAnR4AAKYeAACYDQAAnR4AAJgNAAAgDwAAmx4AAJ0eAAAgDwAAmx4AACAPAACnHgAAnB4AAJseAACnHgAAnB4AAKceAACoHgAAqR4AAJweAACoHgAAqR4AAKgeAACqHgAAqx4AAJgeAACcHgAAqx4AAJweAACpHgAAoB4AAJUeAACYHgAAoB4AAJgeAACrHgAArB4AAK0eAACuHgAArB4AAK4eAACvHgAArR4AALAeAACxHgAArR4AALEeAACuHgAArx4AAK4eAACyHgAArx4AALIeAACzHgAArh4AALEeAAC0HgAArh4AALQeAACyHgAA1B0AALUeAACsHgAA1B0AAKweAADVHQAAtR4AALYeAACtHgAAtR4AAK0eAACsHgAAth4AALceAACwHgAAth4AALAeAACtHgAAtx4AALgeAAC5HgAAtx4AALkeAACwHgAAsB4AALkeAAC6HgAAsB4AALoeAACxHgAAsR4AALoeAAC7HgAAsR4AALseAAC0HgAAtB4AALseAAC8HgAAtB4AALweAAC9HgAAsh4AALQeAAC9HgAAsh4AAL0eAAANDwAAsx4AALIeAAANDwAAsx4AAA0PAAC+HgAA1x0AALMeAAC+HgAA1x0AAL4eAADYHQAA1h0AAK8eAACzHgAA1h0AALMeAADXHQAA1R0AAKweAACvHgAA1R0AAK8eAADWHQAAvx4AAMAeAADBHgAAvx4AAMEeAADCHgAAwB4AAMMeAADEHgAAwB4AAMQeAADBHgAAwh4AAMEeAADFHgAAwh4AAMUeAADGHgAAwR4AAMQeAADHHgAAwR4AAMceAADFHgAAyB4AAMkeAAC/HgAAyB4AAL8eAADKHgAAyR4AAMseAADAHgAAyR4AAMAeAAC/HgAAyx4AAMweAADDHgAAyx4AAMMeAADAHgAAzB4AAB4eAAAgHgAAzB4AACAeAADDHgAAwx4AACAeAAAmHgAAwx4AACYeAADEHgAAxB4AACYeAAAlHgAAxB4AACUeAADHHgAAxx4AACUeAAD5DgAAxx4AAPkOAAD4DgAAxR4AAMceAAD4DgAAxR4AAPgOAAD3DgAAxh4AAMUeAAD3DgAAxh4AAPcOAAD2DgAAzR4AAMYeAAD2DgAAzR4AAPYOAADOHgAAzx4AAMIeAADGHgAAzx4AAMYeAADNHgAAyh4AAL8eAADCHgAAyh4AAMIeAADPHgAA0B4AANEeAADSHgAA0B4AANIeAADTHgAA0R4AANQeAADVHgAA0R4AANUeAADSHgAA0x4AANIeAADWHgAA0x4AANYeAADXHgAA0h4AANUeAADYHgAA0h4AANgeAADWHgAA+h0AANkeAADQHgAA+h0AANAeAAD7HQAA2R4AANoeAADRHgAA2R4AANEeAADQHgAA2h4AANseAADUHgAA2h4AANQeAADRHgAA2x4AANweAADdHgAA2x4AAN0eAADUHgAA1B4AAN0eAADeHgAA1B4AAN4eAADVHgAA1R4AAN4eAADfHgAA1R4AAN8eAADYHgAA2B4AAN8eAADgHgAA2B4AAOAeAADhHgAA1h4AANgeAADhHgAA1h4AAOEeAADiHgAA1x4AANYeAADiHgAA1x4AAOIeAADjDgAA/R0AANceAADjDgAA/R0AAOMOAADiDgAA/B0AANMeAADXHgAA/B0AANceAAD9HQAA+x0AANAeAADTHgAA+x0AANMeAAD8HQAA4x4AAOQeAADlHgAA4x4AAOUeAADmHgAA5B4AAOceAADoHgAA5B4AAOgeAADlHgAA5h4AAOUeAADpHgAA5h4AAOkeAADqHgAA5R4AAOgeAADrHgAA5R4AAOseAADpHgAA7B4AAO0eAADjHgAA7B4AAOMeAADuHgAA7R4AAO8eAADkHgAA7R4AAOQeAADjHgAA7x4AAPAeAADnHgAA7x4AAOceAADkHgAA8B4AAHMdAAB1HQAA8B4AAHUdAADnHgAA5x4AAHUdAAB8HQAA5x4AAHwdAADoHgAA6B4AAHwdAAB6HQAA6B4AAHodAADrHgAA6x4AAHodAAB7HQAA6x4AAHsdAADxHgAA6R4AAOseAADxHgAA6R4AAPEeAADPDgAA6h4AAOkeAADPDgAA6h4AAM8OAADODgAA8h4AAOoeAADODgAA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QB8AADkeAABBHwAAQR8AADkeAAA4HgAAQR8AADgeAABEHwAARB8AADgeAABtDgAARB8AAG0OAABsDgAAQh8AAEQfAABsDgAAQh8AAGwOAABKHwAAQx8AAEIfAABKHwAAQx8AAEofAABqDgAASx8AAEMfAABqDgAASx8AAGoOAABMHwAATR8AAD8fAABDHwAATR8AAEMfAABLHwAARx8AADwfAAA/HwAARx8AAD8fAABNHwAATh8AAE8fAABQHwAATh8AAFAfAABRHwAATx8AAFIfAABTHwAATx8AAFMfAABQHwAAUR8AAFAfAABUHwAAUR8AAFQfAABVHwAAUB8AAFMfAABWHwAAUB8AAFYfAABUHwAARh4AAFcfAABOHwAARh4AAE4fAABHHgAAVx8AAFgfAABPHwAAVx8AAE8fAABOHwAAWB8AAFkfAABSHwAAWB8AAFIfAABPHwAAWR8AAFofAABbHwAAWR8AAFsfAABSHwAAUh8AAFsfAABcHwAAUh8AAFwfAABTHwAAUx8AAFwfAABdHwAAUx8AAF0fAABWHwAAVh8AAF0fAABeHwAAVh8AAF4fAABfHwAAVB8AAFYfAABfHwAAVB8AAF8fAABZDgAAVR8AAFQfAABZDgAAVR8AAFkOAABgHwAASR4AAFUfAABgHwAASR4AAGAfAABKHgAASB4AAFEfAABVHwAASB4AAFUfAABJHgAARx4AAE4fAABRHwAARx4AAFEfAABIHgAAYR8AAGIfAABjHwAAYR8AAGMfAABkHwAAYh8AAGUfAABmHwAAYh8AAGYfAABjHwAAZB8AAGMfAABnHwAAZB8AAGcfAABoHwAAYx8AAGYfAABpHwAAYx8AAGkfAABnHwAAah8AAGsfAABhHwAAah8AAGEfAABsHwAAax8AAG0fAABiHwAAax8AAGIfAABhHwAAbR8AAG4fAABlHwAAbR8AAGUfAABiHwAAbh8AAGgeAABqHgAAbh8AAGoeAABlHwAAZR8AAGoeAABvHgAAZR8AAG8eAABmHwAAZh8AAG8eAABtHgAAZh8AAG0eAABpHwAAaR8AAG0eAABuHgAAaR8AAG4eAABvHwAAZx8AAGkfAABvHwAAZx8AAG8fAABwHwAAaB8AAGcfAABwHwAAaB8AAHAfAABxHwAAch8AAGgfAABxHwAAch8AAHEfAABzHwAAdB8AAGQfAABoHwAAdB8AAGgfAAByHwAAbB8AAGEfAABkHwAAbB8AAGQfAAB0HwAAdR8AAHYfAAB3HwAAdR8AAHcfAAB4HwAAdh8AAHkfAAB6HwAAdh8AAHofAAB3HwAAeB8AAHcfAAB7HwAAeB8AAHsfAAB8HwAAdx8AAHofAAB9HwAAdx8AAH0fAAB7HwAAlBoAAH4fAAB1HwAAlBoAAHUfAACVGgAAfh8AAH8fAAB2HwAAfh8AAHYfAAB1HwAAfx8AAIAfAAB5HwAAfx8AAHkfAAB2HwAAgB8AAIEfAACCHwAAgB8AAIIfAAB5HwAAeR8AAIIfAACDHwAAeR8AAIMfAAB6HwAAeh8AAIMfAACEHwAAeh8AAIQfAAB9HwAAfR8AAIQfAACFHwAAfR8AAIUfAACGHwAAex8AAH0fAACGHwAAex8AAIYfAACHHwAAfB8AAHsfAACHHwAAfB8AAIcfAACIHwAAlxoAAHwfAACIHwAAlxoAAIgfAACYGgAAlhoAAHgfAAB8HwAAlhoAAHwfAACXGgAAlRoAAHUfAAB4HwAAlRoAAHgfAACWGgAAiR8AAIofAACLHwAAiR8AAIsfAACMHwAAih8AAI0fAACOHwAAih8AAI4fAACLHwAAjB8AAIsfAACPHwAAjB8AAI8fAACQHwAAix8AAI4fAACRHwAAix8AAJEfAACPHwAAkh8AAJMfAACJHwAAkh8AAIkfAACUHwAAkx8AAJUfAACKHwAAkx8AAIofAACJHwAAlR8AAJYfAACNHwAAlR8AAI0fAACKHwAAlh8AAI0eAACPHgAAlh8AAI8eAACNHwAAjR8AAI8eAACUHgAAjR8AAJQeAACOHwAAjh8AAJQeAACTHgAAjh8AAJMeAACRHwAAkR8AAJMeAAAdDgAAkR8AAB0OAACXHwAAjx8AAJEfAACXHwAAjx8AAJcfAAAbDgAAkB8AAI8fAAAbDgAAkB8AABsOAACYHwAAmR8AAJAfAACYHwAAmR8AAJgfAACaHwAAmx8AAIwfAACQHwAAmx8AAJAfAACZHwAAlB8AAIkfAACMHwAAlB8AAIwfAACbHwAAnB8AAJ0fAACeHwAAnB8AAJ4fAACfHwAAnR8AAKAfAAChHwAAnR8AAKEfAACeHwAAnx8AAJ4fAACiHwAAnx8AAKIfAACjHwAAnh8AAKEfAACkHwAAnh8AAKQfAACiHwAApR8AAKYfAACcHwAApR8AAJwfAACnHwAAph8AAKgfAACdHwAAph8AAJ0fAACcHwAAqB8AAKkfAACgHwAAqB8AAKAfAACdHwAAqR8AABAfAAASHwAAqR8AABIfAACgHwAAoB8AABIfAAAWHwAAoB8AABYfAAChHwAAoR8AABYfAAAVHwAAoR8AABUfAACkHwAApB8AABUfAAAJDgAApB8AAAkOAACqHwAAoh8AAKQfAACqHwAAoh8AAKofAACrHwAAox8AAKIfAACrHwAAox8AAKsfAAAGDgAArB8AAKMfAAAGDgAArB8AAAYOAADYDAAArR8AAJ8fAACjHwAArR8AAKMfAACsHwAApx8AAJwfAACfHwAApx8AAJ8fAACtHwAArh8AAK8fAACwHwAArh8AALAfAACxHwAArx8AALIfAACzHwAArx8AALMfAACwHwAAsR8AALAfAAC0HwAAsR8AALQfAAC1HwAAsB8AALMfAAC2HwAAsB8AALYfAAC0HwAAuB4AALcfAACuHwAAuB4AAK4fAAC5HgAAtx8AALgfAACvHwAAtx8AAK8fAACuHwAAuB8AALkfAACyHwAAuB8AALIfAACvHwAAuR8AALofAAC7HwAAuR8AALsfAACyHwAAsh8AALsfAAC8HwAAsh8AALwfAACzHwAAsx8AALwfAAC9HwAAsx8AAL0fAAC2HwAAth8AAL0fAACtDAAAth8AAK0MAAD2DQAAtB8AALYfAAD2DQAAtB8AAPYNAAC+HwAAtR8AALQfAAC+HwAAtR8AAL4fAAC/HwAAux4AALUfAAC/HwAAux4AAL8fAAC8HgAAuh4AALEfAAC1HwAAuh4AALUfAAC7HgAAuR4AAK4fAACxHwAAuR4AALEfAAC6HgAAwB8AAMEfAADCHwAAwB8AAMIfAADDHwAAwR8AAMQfAADFHwAAwR8AAMUfAADCHwAAwx8AAMIfAADGHwAAwx8AAMYfAADHHwAAwh8AAMUfAADIHwAAwh8AAMgfAADGHwAAgR8AAMkfAADAHwAAgR8AAMAfAACCHwAAyR8AAMofAADBHwAAyR8AAMEfAADAHwAAyh8AAMsfAADEHwAAyh8AAMQfAADBHwAAyx8AADQfAAA2HwAAyx8AADYfAADEHwAAxB8AADYfAAA7HwAAxB8AADsfAADFHwAAxR8AADsfAAA6HwAAxR8AADofAADIHwAAyB8AADofAADeDQAAyB8AAN4NAADMHwAAxh8AAMgfAADMHwAAxh8AAMwfAADNHwAAxx8AAMYfAADNHwAAxx8AAM0fAADOHwAAhB8AAMcfAADOHwAAhB8AAM4fAACFHwAAgx8AAMMfAADHHwAAgx8AAMcfAACEHwAAgh8AAMAfAADDHwAAgh8AAMMfAACDHwAAzx8AANAfAADRHwAAzx8AANEfAADSHwAA0B8AANMfAADUHwAA0B8AANQfAADRHwAA0h8AANEfAADVHwAA0h8AANUfAADWHwAA0R8AANQfAADXHwAA0R8AANcfAADVHwAArBcAANgfAADPHwAArBcAAM8fAACtFwAA2B8AANkfAADQHwAA2B8AANAfAADPHwAA2R8AANofAADTHwAA2R8AANMfAADQHwAA2h8AALUaAAC3GgAA2h8AALcaAADTHwAA0x8AALcaAAC/GgAA0x8AAL8aAADUHwAA1B8AAL8aAAC9GgAA1B8AAL0aAADXHwAA1x8AAL0aAAC+GgAA1x8AAL4aAADbHwAA1R8AANcfAADbHwAA1R8AANsfAADcHwAA1h8AANUfAADcHwAA1h8AANwfAADBDQAArxcAANYfAADBDQAArxcAAMENAADADQAArhcAANIfAADWHwAArhcAANYfAACvFwAArRcAAM8fAADSHwAArRcAANIfAACuFwAA3R8AAN4fAADfHwAA3R8AAN8fAADgHwAA3h8AAOEfAADiHwAA3h8AAOIfAADfHwAA4B8AAN8fAADjHwAA4B8AAOMfAADkHwAA3x8AAOIfAADlHwAA3x8AAOUfAADjHwAA3B4AAOYfAADdHwAA3B4AAN0fAADdHgAA5h8AAOcfAADeHwAA5h8AAN4fAADdHwAA5x8AAOgfAADhHwAA5x8AAOEfAADeHwAA6B8AAOkfAADqHwAA6B8AAOofAADhHwAA4R8AAOofAADrHwAA4R8AAOsfAADiHwAA4h8AAOsfAADsHwAA4h8AAOwfAADlHwAA5R8AAOwfAACFDAAA5R8AAIUMAADtHwAA4x8AAOUfAADtHwAA4x8AAO0fAADuHwAA5B8AAOMfAADuHwAA5B8AAO4fAADvHwAA3x4AAOQfAADvHwAA3x4AAO8fAADgHgAA3h4AAOAfAADkHwAA3h4AAOQfAADfHgAA3R4AAN0fAADgHwAA3R4AAOAfAADeHgAA8B8AAPEfAADyHwAA8B8AAPIfAADzHwAA8R8AAPQfAAD1HwAA8R8AAPUfAADyHwAA8x8AAPIfAAD2HwAA8x8AAPYfAAD3HwAA8h8AAPUfAAD4HwAA8h8AAPgfAAD2HwAAox4AAPkfAADwHwAAox4AAPAfAACkHgAA+R8AAPofAADxHwAA+R8AAPEfAADwHwAA+h8AAPsfAAD0HwAA+h8AAPQfAADxHwAA+x8AAPwfAAD9HwAA+x8AAP0fAAD0HwAA9B8AAP0fAAD+HwAA9B8AAP4fAAD1HwAA9R8AAP4fAAD/HwAA9R8AAP8fAAD4HwAA+B8AAP8fAAASDAAA+B8AABIMAACcDQAA9h8AAPgfAACcDQAA9h8AAJwNAAAAIAAA9x8AAPYfAAAAIAAA9x8AAAAgAACZDQAAph4AAPcfAACZDQAAph4AAJkNAACYDQAApR4AAPMfAAD3HwAApR4AAPcfAACmHgAApB4AAPAfAADzHwAApB4AAPMfAAClHgAAASAAAAIgAAADIAAAASAAAAMgAAAEIAAAAiAAAAUgAAAGIAAAAiAAAAYgAAADIAAABCAAAAMgAAAHIAAABCAAAAcgAAAIIAAAAyAAAAYgAAAJIAAAAyAAAAkgAAAHIAAACiAAAAsgAAABIAAACiAAAAEgAAAMIAAACyAAAA0gAAACIAAACyAAAAIgAAABIAAADSAAAA4gAAAFIAAADSAAAAUgAAACIAAADiAAAFYeAABYHgAADiAAAFgeAAAFIAAABSAAAFgeAABeHgAABSAAAF4eAAAGIAAABiAAAF4eAABdHgAABiAAAF0eAAAJIAAACSAAAF0eAACEDQAACSAAAIQNAACDDQAAByAAAAkgAACDDQAAByAAAIMNAAAPIAAACCAAAAcgAAAPIAAACCAAAA8gAAAQIAAAESAAAAggAAAQIAAAESAAABAgAAB/DQAAEiAAAAQgAAAIIAAAEiAAAAggAAARIAAADCAAAAEgAAAEIAAADCAAAAQgAAASIAAAEyAAABQgAAAVIAAAEyAAABUgAAAWIAAAFCAAABcgAAAYIAAAFCAAABggAAAVIAAAFiAAABUgAAAZIAAAFiAAABkgAAAaIAAAFSAAABggAAAbIAAAFSAAABsgAAAZIAAABBsAABwgAAATIAAABBsAABMgAAAFGwAAHCAAAB0gAAAUIAAAHCAAABQgAAATIAAAHSAAAB4gAAAXIAAAHSAAABcgAAAUIAAAHiAAAOwXAADuFwAAHiAAAO4XAAAXIAAAFyAAAO4XAAD2FwAAFyAAAPYXAAAYIAAAGCAAAPYXAAD1FwAAGCAAAPUXAAAbIAAAGyAAAPUXAABrDQAAGyAAAGsNAABqDQAAGSAAABsgAABqDQAAGSAAAGoNAAAfIAAAGiAAABkgAAAfIAAAGiAAAB8gAABnDQAABxsAABogAABnDQAABxsAAGcNAAAIGwAABhsAABYgAAAaIAAABhsAABogAAAHGwAABRsAABMgAAAWIAAABRsAABYgAAAGGwAAICAAACEgAAAiIAAAICAAACIgAAAjIAAAISAAACQgAAAlIAAAISAAACUgAAAiIAAAIyAAACIgAAAmIAAAIyAAACYgAAAnIAAAIiAAACUgAAAoIAAAIiAAACggAAAmIAAAKSAAACogAAAgIAAAKSAAACAgAAArIAAAKiAAACwgAAAhIAAAKiAAACEgAAAgIAAALCAAAC0gAAAkIAAALCAAACQgAAAhIAAALSAAAHQbAAB2GwAALSAAAHYbAAAkIAAAJCAAAHYbAAB9GwAAJCAAAH0bAAAlIAAAJSAAAH0bAAB8GwAAJSAAAHwbAAAoIAAAKCAAAHwbAABSDQAAKCAAAFINAAAuIAAAJiAAACggAAAuIAAAJiAAAC4gAAAvIAAAJyAAACYgAAAvIAAAJyAAAC8gAAAwIAAAMSAAACcgAAAwIAAAMSAAADAgAABNDQAAMiAAACMgAAAnIAAAMiAAACcgAAAxIAAAKyAAACAgAAAjIAAAKyAAACMgAAAyIAAAMyAAADQgAAA1IAAAMyAAADUgAAA2IAAANCAAADcgAAA4IAAANCAAADggAAA1IAAANiAAADUgAAA5IAAANiAAADkgAAA6IAAANSAAADggAAA7IAAANSAAADsgAAA5IAAAPCAAAD0gAAAzIAAAPCAAADMgAAA+IAAAPSAAAD8gAAA0IAAAPSAAADQgAAAzIAAAPyAAAEAgAAA3IAAAPyAAADcgAAA0IAAAQCAAAOweAADuHgAAQCAAAO4eAAA3IAAANyAAAO4eAAD0HgAANyAAAPQeAAA4IAAAOCAAAPQeAADyHgAAOCAAAPIeAAA7IAAAOyAAAPIeAADzHgAAOyAAAPMeAABBIAAAOSAAADsgAABBIAAAOSAAAEEgAABCIAAAOiAAADkgAABCIAAAOiAAAEIgAABDIAAARCAAADogAABDIAAARCAAAEMgAACBCwAARSAAADYgAAA6IAAARSAAADogAABEIAAAPiAAADMgAAA2IAAAPiAAADYgAABFIAAARiAAAEcgAABIIAAARiAAAEggAABJIAAARyAAAEogAABLIAAARyAAAEsgAABIIAAASSAAAEggAABMIAAASSAAAEwgAABNIAAASCAAAEsgAABOIAAASCAAAE4gAABMIAAATyAAAFAgAABGIAAATyAAAEYgAABRIAAAUCAAAFIgAABHIAAAUCAAAEcgAABGIAAAUiAAAFMgAABKIAAAUiAAAEogAABHIAAAUyAAAGofAABsHwAAUyAAAGwfAABKIAAASiAAAGwfAAB0HwAASiAAAHQfAABLIAAASyAAAHQfAAByHwAASyAAAHIfAABOIAAATiAAAHIfAABzHwAATiAAAHMfAABUIAAATCAAAE4gAABUIAAATCAAAFQgAABVIAAATSAAAEwgAABVIAAATSAAAFUgAABWIAAAVyAAAE0gAABWIAAAVyAAAFYgAAD+CwAAWCAAAEkgAABNIAAAWCAAAE0gAABXIAAAUSAAAEYgAABJIAAAUSAAAEkgAABYIAAAWSAAAFogAABbIAAAWSAAAFsgAABcIAAAWiAAAF0gAABeIAAAWiAAAF4gAABbIAAAXCAAAFsgAABfIAAAXCAAAF8gAABgIAAAWyAAAF4gAABhIAAAWyAAAGEgAABfIAAAfB4AAGIgAABZIAAAfB4AAFkgAAB9HgAAYiAAAGMgAABaIAAAYiAAAFogAABZIAAAYyAAAGQgAABdIAAAYyAAAF0gAABaIAAAZCAAAGUgAABmIAAAZCAAAGYgAABdIAAAXSAAAGYgAABnIAAAXSAAAGcgAABeIAAAXiAAAGcgAABoIAAAXiAAAGggAABhIAAAYSAAAGggAADgCwAAYSAAAOALAAAVDQAAXyAAAGEgAAAVDQAAXyAAABUNAABpIAAAYCAAAF8gAABpIAAAYCAAAGkgAABqIAAAfx4AAGAgAABqIAAAfx4AAGogAACAHgAAfh4AAFwgAABgIAAAfh4AAGAgAAB/HgAAfR4AAFkgAABcIAAAfR4AAFwgAAB+HgAAayAAAGwgAABtIAAAayAAAG0gAABuIAAAbCAAAG8gAABwIAAAbCAAAHAgAABtIAAAbiAAAG0gAABxIAAAbiAAAHEgAAByIAAAbSAAAHAgAABzIAAAbSAAAHMgAABxIAAAdCAAAHUgAABrIAAAdCAAAGsgAAB2IAAAdSAAAHcgAABsIAAAdSAAAGwgAABrIAAAdyAAAHggAABvIAAAdyAAAG8gAABsIAAAeCAAAP4eAAAAHwAAeCAAAAAfAABvIAAAbyAAAAAfAAAGHwAAbyAAAAYfAABwIAAAcCAAAAYfAAAFHwAAcCAAAAUfAABzIAAAcyAAAAUfAAAADQAAcyAAAAANAAB5IAAAcSAAAHMgAAB5IAAAcSAAAHkgAAB6IAAAciAAAHEgAAB6IAAAciAAAHogAAD9DAAAeyAAAHIgAAD9DAAAeyAAAP0MAAB8IAAAfSAAAG4gAAByIAAAfSAAAHIgAAB7IAAAdiAAAGsgAABuIAAAdiAAAG4gAAB9IAAAfiAAAH8gAACAIAAAfiAAAIAgAACBIAAAfyAAAIIgAACDIAAAfyAAAIMgAACAIAAAgSAAAIAgAACEIAAAgSAAAIQgAACFIAAAgCAAAIMgAACGIAAAgCAAAIYgAACEIAAAhyAAAIggAAB+IAAAhyAAAH4gAACJIAAAiCAAAIogAAB/IAAAiCAAAH8gAAB+IAAAiiAAAIsgAACCIAAAiiAAAIIgAAB/IAAAiyAAAJIfAACUHwAAiyAAAJQfAACCIAAAgiAAAJQfAACbHwAAgiAAAJsfAACDIAAAgyAAAJsfAACZHwAAgyAAAJkfAACGIAAAhiAAAJkfAACaHwAAhiAAAJofAADrDAAAhCAAAIYgAADrDAAAhCAAAOsMAADqDAAAhSAAAIQgAADqDAAAhSAAAOoMAADpDAAAjCAAAIUgAADpDAAAjCAAAOkMAACNIAAAjiAAAIEgAACFIAAAjiAAAIUgAACMIAAAiSAAAH4gAACBIAAAiSAAAIEgAACOIAAAjyAAAJAgAACRIAAAjyAAAJEgAACSIAAAkCAAAJMgAACUIAAAkCAAAJQgAACRIAAAkiAAAJEgAACVIAAAkiAAAJUgAACWIAAAkSAAAJQgAACXIAAAkSAAAJcgAACVIAAAmCAAAJkgAACPIAAAmCAAAI8gAACaIAAAmSAAAJsgAACQIAAAmSAAAJAgAACPIAAAmyAAAJwgAACTIAAAmyAAAJMgAACQIAAAnCAAAKUfAACnHwAAnCAAAKcfAACTIAAAkyAAAKcfAACtHwAAkyAAAK0fAACUIAAAlCAAAK0fAACsHwAAlCAAAKwfAACXIAAAlyAAAKwfAADYDAAAlyAAANgMAACdIAAAlSAAAJcgAACdIAAAlSAAAJ0gAACeIAAAliAAAJUgAACeIAAAliAAAJ4gAADVDAAAnyAAAJYgAADVDAAAnyAAANUMAAB0DAAAoCAAAJIgAACWIAAAoCAAAJYgAACfIAAAmiAAAI8gAACSIAAAmiAAAJIgAACgIAAAoSAAAKIgAACjIAAAoSAAAKMgAACkIAAAoiAAAKUgAACmIAAAoiAAAKYgAACjIAAApCAAAKMgAACnIAAApCAAAKcgAACoIAAAoyAAAKYgAACpIAAAoyAAAKkgAACnIAAAIx8AAKogAAChIAAAIx8AAKEgAAAkHwAAqiAAAKsgAACiIAAAqiAAAKIgAAChIAAAqyAAAKwgAAClIAAAqyAAAKUgAACiIAAArCAAAK0gAACuIAAArCAAAK4gAAClIAAApSAAAK4gAACvIAAApSAAAK8gAACmIAAApiAAAK8gAACwIAAApiAAALAgAACpIAAAqSAAALAgAACxIAAAqSAAALEgAADFDAAApyAAAKkgAADFDAAApyAAAMUMAADEDAAAqCAAAKcgAADEDAAAqCAAAMQMAACyIAAAJh8AAKggAACyIAAAJh8AALIgAAAnHwAAJR8AAKQgAACoIAAAJR8AAKggAAAmHwAAJB8AAKEgAACkIAAAJB8AAKQgAAAlHwAAsyAAALQgAAC1IAAAsyAAALUgAAC2IAAAtCAAALcgAAC4IAAAtCAAALggAAC1IAAAtiAAALUgAAC5IAAAtiAAALkgAAC6IAAAtSAAALggAAC7IAAAtSAAALsgAAC5IAAAuh8AALwgAACzIAAAuh8AALMgAAC7HwAAvCAAAL0gAAC0IAAAvCAAALQgAACzIAAAvSAAAL4gAAC3IAAAvSAAALcgAAC0IAAAviAAAL8gAADAIAAAviAAAMAgAAC3IAAAtyAAAMAgAADBIAAAtyAAAMEgAAC4IAAAuCAAAMEgAADCIAAAuCAAAMIgAAC7IAAAuyAAAMIgAADDIAAAuyAAAMMgAADEIAAAuSAAALsgAADEIAAAuSAAAMQgAADFIAAAuiAAALkgAADFIAAAuiAAAMUgAADGIAAAvR8AALogAADGIAAAvR8AAMYgAACtDAAAvB8AALYgAAC6IAAAvB8AALogAAC9HwAAux8AALMgAAC2IAAAux8AALYgAAC8HwAAxyAAAMggAADJIAAAxyAAAMkgAADKIAAAyCAAAMsgAADMIAAAyCAAAMwgAADJIAAAyiAAAMkgAADNIAAAyiAAAM0gAADOIAAAySAAAMwgAADPIAAAySAAAM8gAADNIAAAWh8AANAgAADHIAAAWh8AAMcgAABbHwAA0CAAANEgAADIIAAA0CAAAMggAADHIAAA0SAAANIgAADLIAAA0SAAAMsgAADIIAAA0iAAANMgAADUIAAA0iAAANQgAADLIAAAyyAAANQgAADVIAAAyyAAANUgAADMIAAAzCAAANUgAADWIAAAzCAAANYgAADPIAAAzyAAANYgAAArDAAAzyAAACsMAADXIAAAzSAAAM8gAADXIAAAzSAAANcgAADYIAAAziAAAM0gAADYIAAAziAAANggAACaDAAAXR8AAM4gAACaDAAAXR8AAJoMAABeHwAAXB8AAMogAADOIAAAXB8AAM4gAABdHwAAWx8AAMcgAADKIAAAWx8AAMogAABcHwAA2SAAANogAADbIAAA2SAAANsgAADcIAAA2iAAAN0gAADeIAAA2iAAAN4gAADbIAAA3CAAANsgAADfIAAA3CAAAN8gAADgIAAA2yAAAN4gAADhIAAA2yAAAOEgAADfIAAA6R8AAOIgAADZIAAA6R8AANkgAADqHwAA4iAAAOMgAADaIAAA4iAAANogAADZIAAA4yAAAOQgAADdIAAA4yAAAN0gAADaIAAA5CAAAOUgAADmIAAA5CAAAOYgAADdIAAA3SAAAOYgAADnIAAA3SAAAOcgAADeIAAA3iAAAOcgAADoIAAA3iAAAOggAADhIAAA4SAAAOggAADpIAAA4SAAAOkgAADqIAAA3yAAAOEgAADqIAAA3yAAAOogAACIDAAA4CAAAN8gAACIDAAA4CAAAIgMAADrIAAA7B8AAOAgAADrIAAA7B8AAOsgAACFDAAA6x8AANwgAADgIAAA6x8AAOAgAADsHwAA6h8AANkgAADcIAAA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QCEAABcMAABIIQAAPiEAAEAhAABIIQAAPiEAAEghAABJIQAAPyEAAD4hAABJIQAAPyEAAEkhAAATDAAA/x8AAD8hAAATDAAA/x8AABMMAAASDAAA/h8AADshAAA/IQAA/h8AAD8hAAD/HwAA/R8AADghAAA7IQAA/R8AADshAAD+HwAASiEAAEshAABMIQAASiEAAEwhAABNIQAASyEAAE4hAABPIQAASyEAAE8hAABMIQAATSEAAEwhAABQIQAATSEAAFAhAABRIQAATCEAAE8hAABSIQAATCEAAFIhAABQIQAAUyEAAFQhAABKIQAAUyEAAEohAABVIQAAVCEAAFYhAABLIQAAVCEAAEshAABKIQAAViEAAFchAABOIQAAViEAAE4hAABLIQAAVyEAAE8gAABRIAAAVyEAAFEgAABOIQAATiEAAFEgAABYIAAATiEAAFggAABPIQAATyEAAFggAABXIAAATyEAAFcgAABSIQAAUiEAAFcgAAD+CwAAUiEAAP4LAAD9CwAAUCEAAFIhAAD9CwAAUCEAAP0LAABYIQAAUSEAAFAhAABYIQAAUSEAAFghAAD6CwAAWSEAAFEhAAD6CwAAWSEAAPoLAAD5CwAAWiEAAE0hAABRIQAAWiEAAFEhAABZIQAAVSEAAEohAABNIQAAVSEAAE0hAABaIQAAWyEAAFwhAABdIQAAWyEAAF0hAABeIQAAXCEAAF8hAABgIQAAXCEAAGAhAABdIQAAXiEAAF0hAABhIQAAXiEAAGEhAABiIQAAXSEAAGAhAABjIQAAXSEAAGMhAABhIQAAZSAAAGQhAABbIQAAZSAAAFshAABmIAAAZCEAAGUhAABcIQAAZCEAAFwhAABbIQAAZSEAAGYhAABfIQAAZSEAAF8hAABcIQAAZiEAAGchAABoIQAAZiEAAGghAABfIQAAXyEAAGghAABpIQAAXyEAAGkhAABgIQAAYCEAAGkhAABqIQAAYCEAAGohAABjIQAAYyEAAGohAABrIQAAYyEAAGshAABsIQAAYSEAAGMhAABsIQAAYSEAAGwhAADjCwAAYiEAAGEhAADjCwAAYiEAAOMLAADhCwAAaCAAAGIhAADhCwAAaCAAAOELAADgCwAAZyAAAF4hAABiIQAAZyAAAGIhAABoIAAAZiAAAFshAABeIQAAZiAAAF4hAABnIAAAbSEAAG4hAABvIQAAbSEAAG8hAABwIQAAbiEAAHEhAAByIQAAbiEAAHIhAABvIQAAcCEAAG8hAABzIQAAcCEAAHMhAAB0IQAAbyEAAHIhAAB1IQAAbyEAAHUhAABzIQAAdiEAAHchAABtIQAAdiEAAG0hAAB4IQAAdyEAAHkhAABuIQAAdyEAAG4hAABtIQAAeSEAAHohAABxIQAAeSEAAHEhAABuIQAAeiEAAIcgAACJIAAAeiEAAIkgAABxIQAAcSEAAIkgAACOIAAAcSEAAI4gAAByIQAAciEAAI4gAACMIAAAciEAAIwgAAB1IQAAdSEAAIwgAACNIAAAdSEAAI0gAAB7IQAAcyEAAHUhAAB7IQAAcyEAAHshAADKCwAAdCEAAHMhAADKCwAAdCEAAMoLAADICwAAfCEAAHQhAADICwAAfCEAAMgLAADHCwAAfSEAAHAhAAB0IQAAfSEAAHQhAAB8IQAAeCEAAG0hAABwIQAAeCEAAHAhAAB9IQAAfiEAAH8hAACAIQAAfiEAAIAhAACBIQAAfyEAAIIhAACDIQAAfyEAAIMhAACAIQAAgSEAAIAhAACEIQAAgSEAAIQhAACFIQAAgCEAAIMhAACGIQAAgCEAAIYhAACEIQAAvyAAAIchAAB+IQAAvyAAAH4hAADAIAAAhyEAAIghAAB/IQAAhyEAAH8hAAB+IQAAiCEAAIkhAACCIQAAiCEAAIIhAAB/IQAAiSEAAIohAACLIQAAiSEAAIshAACCIQAAgiEAAIshAACMIQAAgiEAAIwhAACDIQAAgyEAAIwhAACNIQAAgyEAAI0hAACGIQAAhiEAAI0hAACOIQAAhiEAAI4hAACPIQAAhCEAAIYhAACPIQAAhCEAAI8hAACQIQAAhSEAAIQhAACQIQAAhSEAAJAhAACRIQAAwiAAAIUhAACRIQAAwiAAAJEhAADDIAAAwSAAAIEhAACFIQAAwSAAAIUhAADCIAAAwCAAAH4hAACBIQAAwCAAAIEhAADBIAAAkiEAAJMhAACUIQAAkiEAAJQhAACVIQAAkyEAAJYhAACXIQAAkyEAAJchAACUIQAAlSEAAJQhAACYIQAAlSEAAJghAACZIQAAlCEAAJchAACaIQAAlCEAAJohAACYIQAA5SAAAJshAACSIQAA5SAAAJIhAADmIAAAmyEAAJwhAACTIQAAmyEAAJMhAACSIQAAnCEAAJ0hAACWIQAAnCEAAJYhAACTIQAAnSEAAJ4hAACfIQAAnSEAAJ8hAACWIQAAliEAAJ8hAACgIQAAliEAAKAhAACXIQAAlyEAAKAhAAChIQAAlyEAAKEhAACaIQAAmiEAAKEhAACaCwAAmiEAAJoLAACZCwAAmCEAAJohAACZCwAAmCEAAJkLAACYCwAAmSEAAJghAACYCwAAmSEAAJgLAACWCwAA6CAAAJkhAACWCwAA6CAAAJYLAADpIAAA5yAAAJUhAACZIQAA5yAAAJkhAADoIAAA5iAAAJIhAACVIQAA5iAAAJUhAADnIAAAoiEAAKMhAACkIQAAoiEAAKQhAAClIQAAoyEAAKYhAACnIQAAoyEAAKchAACkIQAApSEAAKQhAACoIQAApSEAAKghAACpIQAApCEAAKchAACqIQAApCEAAKohAACoIQAA2hcAAKshAACiIQAA2hcAAKIhAADbFwAAqyEAAKwhAACjIQAAqyEAAKMhAACiIQAArCEAAK0hAACmIQAArCEAAKYhAACjIQAArSEAADwgAAA+IAAArSEAAD4gAACmIQAApiEAAD4gAABFIAAApiEAAEUgAACnIQAApyEAAEUgAABEIAAApyEAAEQgAACqIQAAqiEAAEQgAACBCwAAqiEAAIELAACuIQAAqCEAAKohAACuIQAAqCEAAK4hAACvIQAAqSEAAKghAACvIQAAqSEAAK8hAACwIQAA3RcAAKkhAACwIQAA3RcAALAhAAB8CwAA3BcAAKUhAACpIQAA3BcAAKkhAADdFwAA2xcAAKIhAAClIQAA2xcAAKUhAADcFwAAsSEAALIhAACzIQAAsSEAALMhAAC0IQAAsiEAALUhAAC2IQAAsiEAALYhAACzIQAAtCEAALMhAAC3IQAAtCEAALchAAC4IQAAsyEAALYhAAC5IQAAsyEAALkhAAC3IQAAMiEAALohAACxIQAAMiEAALEhAAAzIQAAuiEAALshAACyIQAAuiEAALIhAACxIQAAuyEAALwhAAC1IQAAuyEAALUhAACyIQAAvCEAAHQgAAB2IAAAvCEAAHYgAAC1IQAAtSEAAHYgAAB9IAAAtSEAAH0gAAC2IQAAtiEAAH0gAAB7IAAAtiEAAHsgAAC5IQAAuSEAAHsgAAB8IAAAuSEAAHwgAABnCwAAtyEAALkhAABnCwAAtyEAAGcLAAC9IQAAuCEAALchAAC9IQAAuCEAAL0hAABkCwAANSEAALghAABkCwAANSEAAGQLAABjCwAANCEAALQhAAC4IQAANCEAALghAAA1IQAAMyEAALEhAAC0IQAAMyEAALQhAAA0IQAAviEAAL8hAADAIQAAviEAAMAhAADBIQAAvyEAAMIhAADDIQAAvyEAAMMhAADAIQAAwSEAAMAhAADEIQAAwSEAAMQhAADFIQAAwCEAAMMhAADGIQAAwCEAAMYhAADEIQAAxyEAAMghAAC+IQAAxyEAAL4hAADJIQAAyCEAAMohAAC/IQAAyCEAAL8hAAC+IQAAyiEAAMshAADCIQAAyiEAAMIhAAC/IQAAyyEAAPUgAAD3IAAAyyEAAPcgAADCIQAAwiEAAPcgAAD+IAAAwiEAAP4gAADDIQAAwyEAAP4gAAD9IAAAwyEAAP0gAADGIQAAxiEAAP0gAABPCwAAxiEAAE8LAADMIQAAxCEAAMYhAADMIQAAxCEAAMwhAADNIQAAxSEAAMQhAADNIQAAxSEAAM0hAABLCwAAziEAAMUhAABLCwAAziEAAEsLAADPIQAA0CEAAMEhAADFIQAA0CEAAMUhAADOIQAAySEAAL4hAADBIQAAySEAAMEhAADQIQAA0SEAANIhAADTIQAA0SEAANMhAADUIQAA0iEAANUhAADWIQAA0iEAANYhAADTIQAA1CEAANMhAADXIQAA1CEAANchAADYIQAA0yEAANYhAADZIQAA0yEAANkhAADXIQAArSAAANohAADRIQAArSAAANEhAACuIAAA2iEAANshAADSIQAA2iEAANIhAADRIQAA2yEAANwhAADVIQAA2yEAANUhAADSIQAA3CEAABcYAAAZGAAA3CEAABkYAADVIQAA1SEAABkYAAAjGAAA1SEAACMYAADWIQAA1iEAACMYAAAiGAAA1iEAACIYAADZIQAA2SEAACIYAAA2CwAA2SEAADYLAAA1CwAA1yEAANkhAAA1CwAA1yEAADULAAA0CwAA2CEAANchAAA0CwAA2CEAADQLAADdIQAAsCAAANghAADdIQAAsCAAAN0hAACxIAAAryAAANQhAADYIQAAryAAANghAACwIAAAriAAANEhAADUIQAAriAAANQhAACvIAAA3iEAAN8hAADgIQAA3iEAAOAhAADhIQAA3yEAAOIhAADjIQAA3yEAAOMhAADgIQAA4SEAAOAhAADkIQAA4SEAAOQhAADlIQAA4CEAAOMhAADmIQAA4CEAAOYhAADkIQAA5yEAAOghAADeIQAA5yEAAN4hAADpIQAA6CEAAOohAADfIQAA6CEAAN8hAADeIQAA6iEAAOshAADiIQAA6iEAAOIhAADfIQAA6yEAABshAAAdIQAA6yEAAB0hAADiIQAA4iEAAB0hAAAlIQAA4iEAACUhAADjIQAA4yEAACUhAAAjIQAA4yEAACMhAADmIQAA5iEAACMhAAAkIQAA5iEAACQhAADsIQAA5CEAAOYhAADsIQAA5CEAAOwhAADtIQAA5SEAAOQhAADtIQAA5SEAAO0hAADuIQAA7yEAAOUhAADuIQAA7yEAAO4hAADwIQAA8SEAAOEhAADlIQAA8SEAAOUhAADvIQAA6SEAAN4hAADhIQAA6SEAAOEhAADxIQAA8iEAAPMhAAD0IQAA8iEAAPQhAAD1IQAA8yEAAPYhAAD3IQAA8yEAAPchAAD0IQAA9SEAAPQhAAD4IQAA9SEAAPghAAD5IQAA9CEAAPchAAD6IQAA9CEAAPohAAD4IQAARCEAAPshAADyIQAARCEAAPIhAABFIQAA+yEAAPwhAADzIQAA+yEAAPMhAADyIQAA/CEAAP0hAAD2IQAA/CEAAPYhAADzIQAA/SEAAP4hAAD/IQAA/SEAAP8hAAD2IQAA9iEAAP8hAAAAIgAA9iEAAAAiAAD3IQAA9yEAAAAiAAABIgAA9yEAAAEiAAD6IQAA+iEAAAEiAACZFgAA+iEAAJkWAAACIgAA+CEAAPohAAACIgAA+CEAAAIiAABYFwAA+SEAAPghAABYFwAA+SEAAFgXAAADIgAARyEAAPkhAAADIgAARyEAAAMiAAAXDAAARiEAAPUhAAD5IQAARiEAAPkhAABHIQAARSEAAPIhAAD1IQAARSEAAPUhAABGIQAABCIAAAUiAAAGIgAABCIAAAYiAAAHIgAABSIAAAgiAAAJIgAABSIAAAkiAAAGIgAAByIAAAYiAAAKIgAAByIAAAoiAAALIgAABiIAAAkiAAAMIgAABiIAAAwiAAAKIgAADSIAAA4iAAAEIgAADSIAAAQiAAAPIgAADiIAABAiAAAFIgAADiIAAAUiAAAEIgAAECIAABEiAAAIIgAAECIAAAgiAAAFIgAAESIAAFMhAABVIQAAESIAAFUhAAAIIgAACCIAAFUhAABaIQAACCIAAFohAAAJIgAACSIAAFohAABZIQAACSIAAFkhAAAMIgAADCIAAFkhAAD5CwAADCIAAPkLAABKFwAACiIAAAwiAABKFwAACiIAAEoXAAASIgAACyIAAAoiAAASIgAACyIAABIiAABIFwAAEyIAAAsiAABIFwAAEyIAAEgXAAAUIgAAFSIAAAciAAALIgAAFSIAAAsiAAATIgAADyIAAAQiAAAHIgAADyIAAAciAAAVIgAAFiIAABciAAAYIgAAFiIAABgiAAAZIgAAFyIAABoiAAAbIgAAFyIAABsiAAAYIgAAGSIAABgiAAAcIgAAGSIAABwiAAAdIgAAGCIAABsiAAAeIgAAGCIAAB4iAAAcIgAAZyEAAB8iAAAWIgAAZyEAABYiAABoIQAAHyIAACAiAAAXIgAAHyIAABciAAAWIgAAICIAACEiAAAaIgAAICIAABoiAAAXIgAAISIAAHAYAAByGAAAISIAAHIYAAAaIgAAGiIAAHIYAAB/GAAAGiIAAH8YAAAbIgAAGyIAAH8YAAB9GAAAGyIAAH0YAAAeIgAAHiIAAH0YAAB+GAAAHiIAAH4YAAAiIgAAHCIAAB4iAAAiIgAAHCIAACIiAAAjIgAAHSIAABwiAAAjIgAAHSIAACMiAAAkIgAAaiEAAB0iAAAkIgAAaiEAACQiAABrIQAAaSEAABkiAAAdIgAAaSEAAB0iAABqIQAAaCEAABYiAAAZIgAAaCEAABkiAABpIQAAJSIAACYiAAAnIgAAJSIAACciAAAoIgAAJiIAACkiAAAqIgAAJiIAACoiAAAnIgAAKCIAACciAAArIgAAKCIAACsiAAAsIgAAJyIAACoiAAAtIgAAJyIAAC0iAAArIgAAYx0AAC4iAAAlIgAAYx0AACUiAABkHQAALiIAAC8iAAAmIgAALiIAACYiAAAlIgAALyIAADAiAAApIgAALyIAACkiAAAmIgAAMCIAADEiAAAyIgAAMCIAADIiAAApIgAAKSIAADIiAAAzIgAAKSIAADMiAAAqIgAAKiIAADMiAAA0IgAAKiIAADQiAAAtIgAALSIAADQiAAA1IgAALSIAADUiAAAsFwAAKyIAAC0iAAAsFwAAKyIAACwXAAA2IgAALCIAACsiAAA2IgAALCIAADYiAAA3IgAAZh0AACwiAAA3IgAAZh0AADciAABnHQAAZR0AACgiAAAsIgAAZR0AACwiAABmHQAAZB0AACUiAAAoIgAAZB0AACgiAABlHQAAOCIAADkiAAA6IgAAOCIAADoiAAA7IgAAOSIAADwiAAA9IgAAOSIAAD0iAAA6IgAAOyIAADoiAAA+IgAAOyIAAD4iAAA/IgAAOiIAAD0iAABAIgAAOiIAAEAiAAA+IgAAfxcAAEEiAAA4IgAAfxcAADgiAACAFwAAQSIAAEIiAAA5IgAAQSIAADkiAAA4IgAAQiIAAEMiAAA8IgAAQiIAADwiAAA5IgAAQyIAAHYhAAB4IQAAQyIAAHghAAA8IgAAPCIAAHghAAB9IQAAPCIAAH0hAAA9IgAAPSIAAH0hAAB8IQAAPSIAAHwhAABAIgAAQCIAAHwhAADHCwAAQCIAAMcLAAAdFwAAPiIAAEAiAAAdFwAAPiIAAB0XAABEIgAAPyIAAD4iAABEIgAAPyIAAEQiAABFIgAAghcAAD8iAABFIgAAghcAAEUiAACDFwAAgRcAADsiAAA/IgAAgRcAAD8iAACCFwAAgBcAADgiAAA7IgAAgBcAADsiAACBFwAARiIAAEciAABIIgAARiIAAEgiAABJIgAARyIAAEoiAABLIgAARyIAAEsiAABIIgAASSIAAEgiAABMIgAASSIAAEwiAABNIgAASCIAAEsiAABOIgAASCIAAE4iAABMIgAAiiEAAE8iAABGIgAAiiEAAEYiAACLIQAATyIAAFAiAABHIgAATyIAAEciAABGIgAAUCIAAFEiAABKIgAAUCIAAEoiAABHIgAAUSIAAJAXAACSFwAAUSIAAJIXAABKIgAASiIAAJIXAACdFwAASiIAAJ0XAABLIgAASyIAAJ0XAACbFwAASyIAAJsXAABOIgAATiIAAJsXAACcFwAATiIAAJwXAABSIgAATCIAAE4iAABSIgAATCIAAFIiAABTIgAATSIAAEwiAABTIgAATSIAAFMiAABUIgAAjSEAAE0iAABUIgAAjSEAAFQiAACOIQAAjCEAAEkiAABNIgAAjCEAAE0iAACNIQAAiyEAAEYiAABJIgAAiyEAAEkiAACMIQAAVSIAAFYiAABXIgAAVSIAAFciAABYIgAAViIAAFkiAABaIgAAViIAAFoiAABXIgAAWCIAAFciAABbIgAAWCIAAFsiAABcIgAAVyIAAFoiAABdIgAAVyIAAF0iAABbIgAAniEAAF4iAABVIgAAniEAAFUiAACfIQAAXiIAAF8iAABWIgAAXiIAAFYiAABVIgAAXyIAAGAiAABZIgAAXyIAAFkiAABWIgAAYCIAAL0XAAC/FwAAYCIAAL8XAABZIgAAWSIAAL8XAADLFwAAWSIAAMsXAABaIgAAWiIAAMsXAADJFwAAWiIAAMkXAABdIgAAXSIAAMkXAADKFwAAXSIAAMoXAABhIgAAWyIAAF0iAABhIgAAWyIAAGEiAAD+FgAAXCIAAFsiAAD+FgAAXCIAAP4WAAD9FgAAoSEAAFwiAAD9FgAAoSEAAP0WAACaCwAAoCEAAFgiAABcIgAAoCEAAFwiAAChIQAAnyEAAFUiAABYIgAAnyEAAFgiAACgIQAAYiIAAGMiAABkIgAAYiIAAGQiAABlIgAAYyIAAGYiAABnIgAAYyIAAGciAABkIgAAZSIAAGQiAABoIgAAZSIAAGgiAABpIgAAZCIAAGciAABqIgAAZCIAAGoiAABoIgAA3RgAAGsiAABiIgAA3RgAAGIiAADeGAAAayIAAGwiAABjIgAAayIAAGMiAABiIgAAbCIAAG0iAABmIgAAbCIAAGYiAABjIgAAbSIAAAogAAAMIAAAbSIAAAwgAABmIgAAZiIAAAwgAAASIAAAZiIAABIgAABnIgAAZyIAABIgAAARIAAAZyIAABEgAABqIgAAaiIAABEgAAB/DQAAaiIAAH8NAABuIgAAaCIAAGoiAABuIgAAaCIAAG4iAADvFgAAaSIAAGgiAADvFgAAaSIAAO8WAABvIgAA4BgAAGkiAABvIgAA4BgAAG8iAAA0FQAA3xgAAGUiAABpIgAA3xgAAGkiAADgGAAA3hgAAGIiAABlIgAA3hgAAGUiAADfGAAAcCIAAHEiAAByIgAAcCIAAHIiAABzIgAAcSIAAHQiAAB1IgAAcSIAAHUiAAByIgAAcyIAAHIiAAB2IgAAcyIAAHYiAAB3IgAAciIAAHUiAAB4IgAAciIAAHgiAAB2IgAABRgAAHkiAABwIgAABRgAAHAiAAAGGAAAeSIAAHoiAABxIgAAeSIAAHEiAABwIgAAeiIAAHsiAAB0IgAAeiIAAHQiAABxIgAAeyIAAMchAADJIQAAeyIAAMkhAAB0IgAAdCIAAMkhAADQIQAAdCIAANAhAAB1IgAAdSIAANAhAADOIQAAdSIAAM4hAAB4IgAAeCIAAM4hAADPIQAAeCIAAM8hAADhFgAAdiIAAHgiAADhFgAAdiIAAOEWAAB8IgAAdyIAAHYiAAB8IgAAdyIAAHwiAAB9IgAACBgAAHciAAB9IgAACBgAAH0iAAAJGAAABxgAAHMiAAB3IgAABxgAAHciAAAIGAAABhgAAHAiAABzIgAABhgAAHMiAAAHGAAAfiIAAH8iAACAIgAAfiIAAIAiAACBIgAAfyIAAIIiAACDIgAAfyIAAIMiAACAIgAAgSIAAIAiAACEIgAAgSIAAIQiAACFIgAAgCIAAIMiAACGIgAAgCIAAIYiAACEIgAACyEAAIciAAB+IgAACyEAAH4iAAAMIQAAhyIAAIgiAAB/IgAAhyIAAH8iAAB+IgAAiCIAAIkiAACCIgAAiCIAAIIiAAB/IgAAiSIAAOMZAADlGQAAiSIAAOUZAACCIgAAgiIAAOUZAADwGQAAgiIAAPAZAACDIgAAgyIAAPAZAADuGQAAgyIAAO4ZAACGIgAAhiIAAO4ZAADvGQAAhiIAAO8ZAADSFgAAhCIAAIYiAADSFgAAhCIAANIWAACKIgAAhSIAAIQiAACKIgAAhSIAAIoiAADQFgAADiEAAIUiAADQFgAADiEAANAWAAAPIQAADSEAAIEiAACFIgAADSEAAIUiAAAOIQAADCEAAH4iAACBIgAADCEAAIEiAAANIQAAiyIAAIwiAACNIgAAiyIAAI0iAACOIgAAjCIAAI8iAACQIgAAjCIAAJAiAACNIgAAjiIAAI0iAACRIgAAjiIAAJEiAACSIgAAjSIAAJAiAACTIgAAjSIAAJMiAACRIgAABRkAAJQiAACLIgAABRkAAIsiAAAGGQAAlCIAAJUiAACMIgAAlCIAAIwiAACLIgAAlSIAAJYiAACPIgAAlSIAAI8iAACMIgAAliIAAJciAACYIgAAliIAAJgiAACPIgAAjyIAAJgiAACZIgAAjyIAAJkiAACQIgAAkCIAAJkiAACaIgAAkCIAAJoiAACTIgAAkyIAAJoiAACbIgAAkyIAAJsiAAC+FgAAkSIAAJMiAAC+FgAAkSIAAL4WAAC9FgAAkiIAAJEiAAC9FgAAkiIAAL0WAACcIgAACBkAAJIiAACcIgAACBkAAJwiAAAMFQAABxkAAI4iAACSIgAABxkAAJIiAAAIGQAABhkAAIsiAACOIgAABhkAAI4iAAAHGQAAnSIAAJ4iAACfIgAAnSIAAJ8iAACgIgAAniIAAKEiAACiIgAAniIAAKIiAACfIgAAoCIAAJ8iAACjIgAAoCIAAKMiAACkIgAAnyIAAKIiAAClIgAAnyIAAKUiAACjIgAAMhgAAKYiAACdIgAAMhgAAJ0iAAAzGAAApiIAAKciAACeIgAApiIAAJ4iAACdIgAApyIAAKgiAAChIgAApyIAAKEiAACeIgAAqCIAACkgAAArIAAAqCIAACsgAAChIgAAoSIAACsgAAAyIAAAoSIAADIgAACiIgAAoiIAADIgAAAxIAAAoiIAADEgAAClIgAApSIAADEgAABNDQAApSIAAE0NAACpIgAAoyIAAKUiAACpIgAAoyIAAKkiAACqIgAApCIAAKMiAACqIgAApCIAAKoiAACrIgAANRgAAKQiAACrIgAANRgAAKsiAAA2GAAANBgAAKAiAACkIgAANBgAAKQiAAA1GAAAMxgAAJ0iAACgIgAAMxgAAKAiAAA0GAAArCIAAK0iAACuIgAArCIAAK4iAACvIgAArSIAALAiAACxIgAArSIAALEiAACuIgAAryIAAK4iAACyIgAAryIAALIiAACzIgAAriIAALEiAAC0IgAAriIAALQiAACyIgAA/iEAALUiAACsIgAA/iEAAKwiAAD/IQAAtSIAALYiAACtIgAAtSIAAK0iAACsIgAAtiIAALciAACwIgAAtiIAALAiAACtIgAAtyIAAEQYAABGGAAAtyIAAEYYAACwIgAAsCIAAEYYAABRGAAAsCIAAFEYAACxIgAAsSIAAFEYAABQGAAAsSIAAFAYAAC0IgAAtCIAAFAYAAC9FQAAtCIAAL0VAAC4IgAAsiIAALQiAAC4IgAAsiIAALgiAAC5IgAAsyIAALIiAAC5IgAAsyIAALkiAAC6IgAAASIAALMiAAC6IgAAASIAALoiAACZFgAAACIAAK8iAACzIgAAACIAALMiAAABIgAA/yEAAKwiAACvIgAA/yEAAK8iAAAAIgAAuyIAALwiAAC9IgAAuyIAAL0iAAC+IgAAvCIAAL8iAADAIgAAvCIAAMAiAAC9IgAAviIAAL0iAADBIgAAviIAAMEiAADCIgAAvSIAAMAiAADDIgAAvSIAAMMiAADBIgAAYBgAAMQiAAC7IgAAYBgAALsiAABhGAAAxCIAAMUiAAC8IgAAxCIAALwiAAC7IgAAxSIAAMYiAAC/IgAAxSIAAL8iAAC8IgAAxiIAAA0iAAAPIgAAxiIAAA8iAAC/IgAAvyIAAA8iAAAVIgAAvyIAABUiAADAIgAAwCIAABUiAAATIgAAwCIAABMiAADDIgAAwyIAABMiAAAUIgAAwyIAABQiAADHIgAAwSIAAMMiAADHIgAAwSIAAMciAADIIgAAwiIAAMEiAADIIgAAwiIAAMgiAACFFgAAYxgAAMIiAACFFgAAYxgAAIUWAACsFQAAYhgAAL4iAADCIgAAYhgAAMIiAABjGAAAYRgAALsiAAC+IgAAYRgAAL4iAABiGAAAySIAAMoiAADLIgAAySIAAMsiAADMIgAAyiIAAM0iAADOIgAAyiIAAM4iAADLIgAAzCIAAMsiAADPIgAAzCIAAM8iAADQIgAAyyIAAM4iAADRIgAAyyIAANEiAADPIgAAMSIAANIiAADJIgAAMSIAAMkiAAAyIgAA0iIAANMiAADKIgAA0iIAAMoiAADJIgAA0yIAANQiAADNIgAA0yIAAM0iAADKIgAA1CIAAIkYAACLGAAA1CIAAIsYAADNIgAAzSIAAIsYAACVGAAAzSIAAJUYAADOIgAAziIAAJUYAACTGAAAziIAAJMYAADRIgAA0SIAAJMYAACUGAAA0SIAAJQYAAB1FgAAzyIAANEiAAB1FgAAzyIAAHUWAADVIgAA0CIAAM8iAADVIgAA0CIAANUiAADWIgAANCIAANAiAADWIgAANCIAANYiAAA1IgAAMyIAAMwiAADQIgAAMyIAANAiAAA0IgAAMiIAAMkiAADMIgAAMiIAAMwiAAAzIgAA1yIAANgiAADZIgAA1yIAANkiAADaIgAA2yIAANwiAADZIgAA2yIAANkiAADYIgAA3SIAAN4iAADZIgAA3SIAANkiAADcIgAAoQ0AAN8iAADXIgAAoQ0AANciAAAhDwAA3yIAAOAiAADYIgAA3yIAANgiAADXIgAAIQ8AANciAADaIgAAIQ8AANoiAADhIgAA4iIAAOMiAADbIgAA4iIAANsiAADkIgAA4yIAAK8OAADcIgAA4yIAANwiAADbIgAA5CIAANsiAADYIgAA5CIAANgiAADgIgAArQ4AACMPAADdIgAArQ4AAN0iAADlIgAAIw8AACIPAADeIgAAIw8AAN4iAADdIgAA5SIAAN0iAADcIgAA5SIAANwiAACvDgAA5iIAAOciAADoIgAA5iIAAOgiAADpIgAA6iIAAOsiAADoIgAA6iIAAOgiAADnIgAA7CIAAOkiAADoIgAA7CIAAOgiAADrIgAAoQ0AAO0iAADmIgAAoQ0AAOYiAADfIgAA7SIAAO4iAADnIgAA7SIAAOciAADmIgAA3yIAAOYiAADpIgAA3yIAAOkiAADvIgAA3AwAABAOAADqIgAA3AwAAOoiAADwIgAAEA4AAPEiAADrIgAAEA4AAOsiAADqIgAA8CIAAOoiAADnIgAA8CIAAOciAADyIgAA4iIAAPMiAADsIgAA4iIAAOwiAAD0IgAA8yIAAO8iAADpIgAA8yIAAOkiAADsIgAA9CIAAOwiAADrIgAA9CIAAOsiAAAPDgAA9SIAAPYiAAD3IgAA9SIAAPciAAD4IgAA+SIAAPoiAAD3IgAA+SIAAPciAAD7IgAA/CIAAPgiAAD3IgAA/CIAAPciAAD6IgAAIAwAAP0iAAD1IgAAIAwAAPUiAAD+IgAA/SIAAP8iAAD2IgAA/SIAAPYiAAD1IgAA/iIAAPUiAAD4IgAA/iIAAPgiAAAAIwAA3AwAAPAiAAD5IgAA3AwAAPkiAAABIwAA8CIAAO4iAAD6IgAA8CIAAPoiAAD5IgAAASMAAPkiAAD7IgAAASMAAPsiAAD/IgAAoQ0AAJ8NAAD8IgAAoQ0AAPwiAAACIwAAnw0AAJ4NAAD4IgAAnw0AAPgiAAD8IgAAAiMAAPwiAAD6IgAAAiMAAPoiAADyIgAAAyMAAAQjAAAFIwAAAyMAAAUjAAAGIwAAByMAAAgjAAAFIwAAByMAAAUjAAAJIwAACiMAAAYjAAAFIwAACiMAAAUjAAALIwAAIAwAAAwjAAADIwAAIAwAAAMjAAD9IgAADCMAAA0jAAAEIwAADCMAAAQjAAADIwAA/SIAAAMjAAAGIwAA/SIAAAYjAAD/IgAADiMAAA8jAAAHIwAADiMAAAcjAAAQIwAADyMAAN4MAAAIIwAADyMAAAgjAAAHIwAAECMAAAcjAAAJIwAAECMAAAkjAAARIwAA3AwAAAEjAAAKIwAA3AwAAAojAAASIwAAASMAAP8iAAAGIwAAASMAAAYjAAAKIwAAEiMAAAojAAALIwAAEiMAAAsjAADeDAAAEyMAABQjAAAVIwAAEyMAABUjAAAWIwAAFyMAABgjAAAVIwAAFyMAABUjAAAZIwAAGiMAABYjAAAVIwAAGiMAABUjAAAYIwAAIAwAABsjAAATIwAAIAwAABMjAAAcIwAAGyMAAB0jAAAUIwAAGyMAABQjAAATIwAAHCMAABMjAAAWIwAAHCMAABYjAAANIwAAUwsAAHsMAAAXIwAAUwsAABcjAAAeIwAAewwAAB8jAAAYIwAAewwAABgjAAAXIwAAHiMAABcjAAAZIwAAHiMAABkjAAAgIwAADiMAABAjAAAaIwAADiMAABojAAAhIwAAECMAABEjAAAWIwAAECMAABYjAAAaIwAAISMAABojAAAYIwAAISMAABgjAAB6DAAAIiMAACMjAAAkIwAAIiMAACQjAAAlIwAAJiMAACcjAAAkIwAAJiMAACQjAAAjIwAAKCMAACkjAAAkIwAAKCMAACQjAAAnIwAAGwwAACojAAAiIwAAGwwAACIjAAAcDAAAKiMAACsjAAAjIwAAKiMAACMjAAAiIwAAHAwAACIjAAAlIwAAHAwAACUjAAAdDAAAUwsAAB4jAAAmIwAAUwsAACYjAAAsIwAAHiMAAB0jAAAnIwAAHiMAACcjAAAmIwAALCMAACYjAAAjIwAALCMAACMjAAAtIwAAIAwAAB4MAAAoIwAAIAwAACgjAAAbIwAAHgwAAB0MAAApIwAAHgwAACkjAAAoIwAAGyMAACgjAAAnIwAAGyMAACcjAAAdIwAALiMAAC8jAAAwIwAALiMAADAjAAAxIwAAMiMAADMjAAAwIwAAMiMAADAjAAA0IwAANSMAADEjAAAwIwAANSMAADAjAAA2IwAAGwwAADcjAAAuIwAAGwwAAC4jAAAqIwAANyMAADgjAAAvIwAANyMAAC8jAAAuIwAAKiMAAC4jAAAxIwAAKiMAADEjAAArIwAAWAsAAFYLAAAyIwAAWAsAADIjAAA5IwAAVgsAAFULAAAzIwAAVgsAADMjAAAyIwAAOSMAADIjAAA0IwAAOSMAADQjAAA4IwAAUwsAADojAAA1IwAAUwsAADUjAABUCwAAOiMAACsjAAAxIwAAOiMAADEjAAA1IwAAVAsAADUjAAA2IwAAVAsAADYjAABVCwAAOyMAADwjAAA9IwAAOyMAAD0jAAA+IwAAPyMAAEAjAAA9IwAAPyMAAD0jAABBIwAAQiMAAEMjAAA9IwAAQiMAAD0jAABEIwAAohYAAEUjAAA7IwAAohYAADsjAABaFwAARSMAAEYjAAA8IwAARSMAADwjAAA7IwAAWhcAADsjAAA+IwAAWhcAAD4jAABHIwAAWAsAAEgjAAA/IwAAWAsAAD8jAABJIwAASCMAAEojAABAIwAASCMAAEAjAAA/IwAASSMAAD8jAABBIwAASSMAAEEjAABLIwAAGwwAAFwXAABCIwAAGwwAAEIjAABMIwAAXBcAAFsXAABDIwAAXBcAAEMjAABCIwAATCMAAEIjAABEIwAATCMAAEQjAABKIwAATSMAAE4jAABPIwAATSMAAE8jAABQIwAAUSMAAFIjAABPIwAAUSMAAE8jAABTIwAAVCMAAFUjAABPIwAAVCMAAE8jAABWIwAAohYAAFcjAABNIwAAohYAAE0jAABFIwAAVyMAAFgjAABOIwAAVyMAAE4jAABNIwAARSMAAE0jAABQIwAARSMAAFAjAABLIwAA+xUAAOQWAABRIwAA+xUAAFEjAABZIwAA5BYAAOMWAABSIwAA5BYAAFIjAABRIwAAWSMAAFEjAABTIwAAWSMAAFMjAABYIwAAWAsAAFojAABUIwAAWAsAAFQjAABbIwAAWiMAAEsjAABVIwAAWiMAAFUjAABUIwAAWyMAAFQjAABWIwAAWyMAAFYjAADjFgAAXCMAAF0jAABeIwAAXCMAAF4jAABfIwAAYCMAAGEjAABeIwAAYCMAAF4jAABdIwAAYiMAAGMjAABeIwAAYiMAAF4jAABkIwAAxhUAAGUjAABcIwAAxhUAAFwjAACeFgAAZSMAAGYjAABdIwAAZSMAAF0jAABcIwAAnhYAAFwjAABfIwAAnhYAAF8jAABnIwAA+xUAAGgjAABgIwAA+xUAAGAjAABpIwAAaCMAAFgjAABhIwAAaCMAAGEjAABgIwAAaSMAAGAjAABdIwAAaSMAAF0jAABmIwAAohYAAKAWAABiIwAAohYAAGIjAABqIwAAoBYAAJ8WAABjIwAAoBYAAGMjAABiIwAAaiMAAGIjAABkIwAAaiMAAGQjAABYIwAAayMAAGwjAABtIwAAayMAAG0jAABuIwAAbyMAAHAjAABtIwAAbyMAAG0jAABxIwAAciMAAG4jAABtIwAAciMAAG0jAABwIwAAxhUAAHMjAABrIwAAxhUAAGsjAAB0IwAAcyMAAHUjAABsIwAAcyMAAGwjAABrIwAAdCMAAGsjAABuIwAAdCMAAG4jAABmIwAAJBUAAP4VAABvIwAAJBUAAG8jAAB2IwAA/hUAAP0VAABwIwAA/hUAAHAjAABvIwAAdiMAAG8jAABxIwAAdiMAAHEjAAB1IwAA+xUAAGkjAAByIwAA+xUAAHIjAAD8FQAAaSMAAGYjAABuIwAAaSMAAG4jAAByIwAA/BUAAHIjAABwIwAA/BUAAHAjAAB3IwAAeCMAAHkjAAB6IwAAeCMAAHojAAB7IwAAfCMAAH0jAAB6IwAAfCMAAHojAAB+IwAAfyMAAHsjAAB6IwAAfyMAAHojAAB9IwAA6hQAAIAjAAB4IwAA6hQAAHgjAADCFQAAgCMAAIEjAAB5IwAAgCMAAHkjAAB4IwAAwhUAAHgjAAB7IwAAwhUAAHsjAADDFQAAJBUAAIIjAAB8IwAAJBUAAHwjAACDIwAAgiMAAIQjAAB9IwAAgiMAAH0jAAB8IwAAgyMAAHwjAAB+IwAAgyMAAH4jAACFIwAAxhUAAMQVAAB/IwAAxhUAAH8jAABzIwAAxBUAAMMVAAB7IwAAxBUAAHsjAAB/IwAAcyMAAH8jAAB9IwAAcyMAAH0jAACEIwAAhiMAAIcjAACIIwAAhiMAAIgjAACJIwAAiiMAAIsjAACIIwAAiiMAAIgjAACHIwAAjCMAAIkjAACIIwAAjCMAAIgjAACNIwAA6hQAAI4jAACGIwAA6hQAAIYjAACPIwAAjiMAAJAjAACHIwAAjiMAAIcjAACGIwAAjyMAAIYjAACJIwAAjyMAAIkjAACBIwAANBQAACcVAACKIwAANBQAAIojAACRIwAAJxUAACYVAACLIwAAJxUAAIsjAACKIwAAkSMAAIojAACHIwAAkSMAAIcjAACSIwAAJBUAAIMjAACMIwAAJBUAAIwjAAAlFQAAgyMAAIEjAACJIwAAgyMAAIkjAACMIwAAJRUAAIwjAACNIwAAJRUAAI0jAAAmFQAAkyMAAJQjAACVIwAAkyMAAJUjAACWIwAAlyMAAJgjAACVIwAAlyMAAJUjAACUIwAAmSMAAJojAACVIwAAmSMAAJUjAACbIwAA5hMAAJwjAACTIwAA5hMAAJMjAADmFAAAnCMAAJ0jAACUIwAAnCMAAJQjAACTIwAA5hQAAJMjAACWIwAA5hQAAJYjAADnFAAANBQAAJ4jAACXIwAANBQAAJcjAACfIwAAniMAAJAjAACYIwAAniMAAJgjAACXIwAAnyMAAJcjAACUIwAAnyMAAJQjAACdIwAA6hQAAOgUAACZIwAA6hQAAJkjAACOIwAA6BQAAOcUAACaIwAA6BQAAJojAACZIwAAjiMAAJkjAACbIwAAjiMAAJsjAACQIwAAoCMAAKEjAACiIwAAoCMAAKIjAACjIwAApCMAAKUjAACiIwAApCMAAKIjAACmIwAApyMAAKMjAACiIwAApyMAAKIjAACoIwAA5hMAAKkjAACgIwAA5hMAAKAjAACcIwAAqSMAAKojAAChIwAAqSMAAKEjAACgIwAAnCMAAKAjAACjIwAAnCMAAKMjAACdIwAARBMAADcUAACkIwAARBMAAKQjAACrIwAANxQAADYUAAClIwAANxQAAKUjAACkIwAAqyMAAKQjAACmIwAAqyMAAKYjAACsIwAANBQAAK0jAACnIwAANBQAAKcjAAA1FAAArSMAAJ0jAACjIwAArSMAAKMjAACnIwAANRQAAKcjAACoIwAANRQAAKgjAAA2FAAAriMAAK8jAACwIwAAriMAALAjAACxIwAAsiMAALMjAACwIwAAsiMAALAjAACvIwAAtCMAALUjAACwIwAAtCMAALAjAAC2IwAA9hIAALcjAACuIwAA9hIAAK4jAADiEwAAtyMAALgjAACvIwAAtyMAAK8jAACuIwAA4hMAAK4jAACxIwAA4hMAALEjAADjEwAARBMAALkjAACyIwAARBMAALIjAAC6IwAAuSMAAKwjAACzIwAAuSMAALMjAACyIwAAuiMAALIjAACvIwAAuiMAAK8jAAC7IwAA5hMAAOQTAAC0IwAA5hMAALQjAACpIwAA5BMAAOMTAAC1IwAA5BMAALUjAAC0IwAAqSMAALQjAAC2IwAAqSMAALYjAACqIwAAvCMAAL0jAAC+IwAAvCMAAL4jAAC/IwAAwCMAAMEjAAC+IwAAwCMAAL4jAADCIwAAwyMAAMQjAAC+IwAAwyMAAL4jAADFIwAA9hIAAMYjAAC8IwAA9hIAALwjAAC3IwAAxiMAAMcjAAC9IwAAxiMAAL0jAAC8IwAAtyMAALwjAAC/IwAAtyMAAL8jAAC4IwAAyQ0AAEcTAADAIwAAyQ0AAMAjAADIIwAARxMAAEYTAADBIwAARxMAAMEjAADAIwAAyCMAAMAjAADCIwAAyCMAAMIjAADJIwAARBMAALojAADDIwAARBMAAMMjAADKIwAAuiMAALgjAADEIwAAuiMAAMQjAADDIwAAyiMAAMMjAADFIwAAyiMAAMUjAABGEwAAyyMAAMwjAADNIwAAyyMAAM0jAADOIwAAzyMAANAjAADNIwAAzyMAAM0jAADMIwAA0SMAANIjAADNIwAA0SMAAM0jAADTIwAAdA0AANQjAADLIwAAdA0AAMsjAADyEgAA1CMAANUjAADMIwAA1CMAAMwjAADLIwAA8hIAAMsjAADOIwAA8hIAAM4jAADWIwAAkxEAANcjAADPIwAAkxEAAM8jAADYIwAA1yMAANkjAADQIwAA1yMAANAjAADPIwAA2CMAAM8jAADMIwAA2CMAAMwjAADaIwAA9hIAAPQSAADRIwAA9hIAANEjAADbIwAA9BIAAPMSAADSIwAA9BIAANIjAADRIwAA2yMAANEjAADTIwAA2yMAANMjAADcIwAA3SMAAN4jAADfIwAA3SMAAN8jAADgIwAA4SMAAOIjAADfIwAA4SMAAN8jAADeIwAA4yMAAOAjAADfIwAA4yMAAN8jAADiIwAAkxEAAOQjAADdIwAAkxEAAN0jAADlIwAA5CMAAOYjAADeIwAA5CMAAN4jAADdIwAA5SMAAN0jAADgIwAA5SMAAOAjAADcIwAAyQ0AAMgjAADhIwAAyQ0AAOEjAADnIwAAyCMAAMkjAADiIwAAyCMAAOIjAADhIwAA5yMAAOEjAADeIwAA5yMAAN4jAADoIwAA9hIAANsjAADjIwAA9hIAAOMjAADGIwAA2yMAANwjAADgIwAA2yMAAOAjAADjIwAAxiMAAOMjAADiIwAAxiMAAOIjAADJIwAA6SMAAOojAADrIwAA6SMAAOsjAADsIwAA7SMAAO4jAADrIwAA7SMAAOsjAADvIwAA8CMAAPEjAADrIwAA8CMAAOsjAADyIwAAdA0AAPMjAADpIwAAdA0AAOkjAADUIwAA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OyQAADgkAABXJAAAOyQAAFckAABWJAAAXyQAAFYkAABYJAAAXyQAAFgkAABeJAAANSQAAGAkAABZJAAANSQAAFkkAABhJAAAYCQAAEcPAABaJAAAYCQAAFokAABZJAAAYSQAAFkkAABbJAAAYSQAAFskAAA4JAAAYiQAAGMkAABkJAAAYiQAAGQkAABlJAAAZiQAAGckAABkJAAAZiQAAGQkAABjJAAAaCQAAGkkAABkJAAAaCQAAGQkAABnJAAAdA0AAGokAABiJAAAdA0AAGIkAABJJAAAaiQAAGskAABjJAAAaiQAAGMkAABiJAAASSQAAGIkAABlJAAASSQAAGUkAABsJAAASAwAAHQOAABmJAAASAwAAGYkAABtJAAAdA4AAHMOAABnJAAAdA4AAGckAABmJAAAbSQAAGYkAABjJAAAbSQAAGMkAABuJAAATCQAAE4kAABoJAAATCQAAGgkAAByDgAATiQAAEskAABpJAAATiQAAGkkAABoJAAAcg4AAGgkAABnJAAAcg4AAGckAABvJAAAcCQAAHEkAAByJAAAcCQAAHIkAABzJAAAdCQAAHUkAAByJAAAdCQAAHIkAAB2JAAAdyQAAHMkAAByJAAAdyQAAHIkAAB4JAAAGg0AAHkkAABwJAAAGg0AAHAkAAB6JAAAeSQAAHskAABxJAAAeSQAAHEkAABwJAAAeiQAAHAkAABzJAAAeiQAAHMkAAB8JAAAzg0AAMwNAAB0JAAAzg0AAHQkAAB9JAAAzA0AAMsNAAB1JAAAzA0AAHUkAAB0JAAAfSQAAHQkAAB2JAAAfSQAAHYkAAB+JAAAyQ0AAH8kAAB3JAAAyQ0AAHckAACAJAAAfyQAAF4kAABzJAAAfyQAAHMkAAB3JAAAgCQAAHckAAB4JAAAgCQAAHgkAACBJAAAgiQAAIMkAACEJAAAgiQAAIQkAACFJAAAhiQAAIckAACEJAAAhiQAAIQkAACDJAAAiCQAAIUkAACEJAAAiCQAAIQkAACHJAAAbw0AAIkkAACCJAAAbw0AAIIkAABwDQAAiSQAAIokAACDJAAAiSQAAIMkAACCJAAAcA0AAIIkAACFJAAAcA0AAIUkAABxDQAASAwAAG0kAACGJAAASAwAAIYkAACLJAAAbSQAAG4kAACHJAAAbSQAAIckAACGJAAAiyQAAIYkAACDJAAAiyQAAIMkAACMJAAAdA0AAHINAACIJAAAdA0AAIgkAABqJAAAcg0AAHENAACFJAAAcg0AAIUkAACIJAAAaiQAAIgkAACHJAAAaiQAAIckAABuJAAAjSQAAI4kAACPJAAAjSQAAI8kAACQJAAAkSQAAJIkAACPJAAAkSQAAI8kAACTJAAAlCQAAJUkAACPJAAAlCQAAI8kAACWJAAAlyQAAJgkAACNJAAAlyQAAI0kAAAWDQAAmCQAAJkkAACOJAAAmCQAAI4kAACNJAAAFg0AAI0kAACQJAAAFg0AAJAkAAAXDQAAzg0AAH0kAACRJAAAzg0AAJEkAACaJAAAfSQAAHskAACSJAAAfSQAAJIkAACRJAAAmiQAAJEkAACTJAAAmiQAAJMkAACZJAAAGg0AABgNAACUJAAAGg0AAJQkAACbJAAAGA0AAJwkAACVJAAAGA0AAJUkAACUJAAAmyQAAJQkAACWJAAAmyQAAJYkAAB7JAAAnSQAAJ4kAACfJAAAnSQAAJ8kAACgJAAAoSQAAKIkAACfJAAAoSQAAJ8kAACjJAAApCQAAKUkAACfJAAApCQAAJ8kAACmJAAAbw0AAKckAACdJAAAbw0AAJ0kAACJJAAApyQAAKgkAACeJAAApyQAAJ4kAACdJAAAiSQAAJ0kAACgJAAAiSQAAKAkAACKJAAAqSQAAKokAAChJAAAqSQAAKEkAACrJAAAqiQAAEoMAACiJAAAqiQAAKIkAAChJAAAqyQAAKEkAACjJAAAqyQAAKMkAACsJAAASAwAAK0kAACkJAAASAwAAKQkAACuJAAArSQAAIwkAAClJAAArSQAAKUkAACkJAAAriQAAKQkAACmJAAAriQAAKYkAACvJAAAsCQAALEkAACyJAAAsCQAALIkAACzJAAAtCQAALUkAACyJAAAtCQAALIkAAC2JAAAtyQAALMkAACyJAAAtyQAALIkAAC4JAAA6QsAALkkAACwJAAA6QsAALAkAAC6JAAAuSQAALskAACxJAAAuSQAALEkAACwJAAAuiQAALAkAACzJAAAuiQAALMkAAC8JAAAzg0AAJokAAC0JAAAzg0AALQkAAC9JAAAmiQAAJkkAAC1JAAAmiQAALUkAAC0JAAAvSQAALQkAAC2JAAAvSQAALYkAAC+JAAA7gsAAL8kAAC3JAAA7gsAALckAADAJAAAvyQAAOsLAACzJAAAvyQAALMkAAC3JAAAwCQAALckAAC4JAAAwCQAALgkAADBJAAAwiQAAMMkAADEJAAAwiQAAMQkAADFJAAAwyQAAMYkAADHJAAAwyQAAMckAADEJAAAxSQAAMQkAADIJAAAxSQAAMgkAADJJAAAxCQAAMckAADKJAAAxCQAAMokAADIJAAAbw0AAMskAADCJAAAbw0AAMIkAACnJAAAyyQAAMwkAADDJAAAyyQAAMMkAADCJAAAzCQAAM0kAADGJAAAzCQAAMYkAADDJAAAzSQAAMMWAADOJAAAzSQAAM4kAADGJAAAxiQAAM4kAADPJAAAxiQAAM8kAADHJAAAxyQAAM8kAADQJAAAxyQAANAkAADKJAAAyiQAANAkAABvFwAAyiQAAG8XAABtFwAAyCQAAMokAABtFwAAyCQAAG0XAADRJAAAySQAAMgkAADRJAAAySQAANEkAADSJAAAqyQAAMkkAADSJAAAqyQAANIkAADTJAAA1CQAAMUkAADJJAAA1CQAAMkkAACrJAAApyQAAMIkAADFJAAApyQAAMUkAADUJAAA1SQAANYkAADXJAAA1SQAANckAADYJAAA2SQAANokAADXJAAA2SQAANckAADbJAAA3CQAANgkAADXJAAA3CQAANckAADdJAAAnhUAAN4kAADVJAAAnhUAANUkAADfJAAA3iQAAOAkAADWJAAA3iQAANYkAADVJAAA3yQAANUkAADYJAAA3yQAANgkAADhJAAAzg0AAL0kAADZJAAAzg0AANkkAADiJAAAvSQAAL4kAADaJAAAvSQAANokAADZJAAA4iQAANkkAADbJAAA4iQAANskAADgJAAA6QsAAOMkAADcJAAA6QsAANwkAADkJAAA4yQAAD0XAADYJAAA4yQAANgkAADcJAAA5CQAANwkAADdJAAA5CQAAN0kAAC+JAAA5SQAAOYkAADnJAAA5SQAAOckAADoJAAA6SQAAOokAADnJAAA6SQAAOckAADmJAAA6yQAAOgkAADnJAAA6yQAAOckAADqJAAAbw0AAOwkAADlJAAAbw0AAOUkAADLJAAA7CQAAO0kAADmJAAA7CQAAOYkAADlJAAAyyQAAOUkAADoJAAAyyQAAOgkAADMJAAAEBUAAMYWAADpJAAAEBUAAOkkAADuJAAAxhYAAO8kAADqJAAAxhYAAOokAADpJAAA7iQAAOkkAADmJAAA7iQAAOYkAADtJAAA8CQAAPEkAADrJAAA8CQAAOskAADyJAAA8SQAAPMkAADoJAAA8SQAAOgkAADrJAAA8iQAAOskAADqJAAA8iQAAOokAADvJAAA9CQAAPUkAAD2JAAA9CQAAPYkAAD3JAAA+CQAAPkkAAD2JAAA+CQAAPYkAAD6JAAA+yQAAPwkAAD2JAAA+yQAAPYkAAD9JAAAnhUAAP4kAAD0JAAAnhUAAPQkAAD/JAAA/iQAAAAlAAD1JAAA/iQAAPUkAAD0JAAA/yQAAPQkAAD3JAAA/yQAAPckAADgJAAAkBIAAD8WAAD4JAAAkBIAAPgkAAABJQAAPxYAAD4WAAD5JAAAPxYAAPkkAAD4JAAAASUAAPgkAAD6JAAAASUAAPokAAAAJQAAzg0AAOIkAAD7JAAAzg0AAPskAAACJQAA4iQAAOAkAAD8JAAA4iQAAPwkAAD7JAAAAiUAAPskAAD9JAAAAiUAAP0kAAA+FgAAAyUAAAQlAAAFJQAAAyUAAAUlAAAGJQAAByUAAAglAAAFJQAAByUAAAUlAAAEJQAACSUAAAYlAAAFJQAACSUAAAUlAAAIJQAAahIAAAolAAADJQAAahIAAAMlAAALJQAACiUAAAwlAAAEJQAACiUAAAQlAAADJQAACyUAAAMlAAAGJQAACyUAAAYlAAANJQAAEBUAAA4lAAAHJQAAEBUAAAclAAAPJQAADiUAABAlAAAIJQAADiUAAAglAAAHJQAADyUAAAclAAAEJQAADyUAAAQlAAARJQAAbw0AAA0WAAAJJQAAbw0AAAklAADsJAAADRYAAAwWAAAGJQAADRYAAAYlAAAJJQAA7CQAAAklAAAIJQAA7CQAAAglAAAQJQAAEiUAABMlAAAUJQAAEiUAABQlAAAVJQAAFiUAABclAAAUJQAAFiUAABQlAAAYJQAAGSUAABolAAAUJQAAGSUAABQlAAAXJQAAGyUAABwlAAASJQAAGyUAABIlAACaFQAAHCUAAB0lAAATJQAAHCUAABMlAAASJQAAmhUAABIlAAAVJQAAmhUAABUlAAAeJQAAkBIAAB8lAAAWJQAAkBIAABYlAAAgJQAAHyUAACElAAAXJQAAHyUAABclAAAWJQAAICUAABYlAAAYJQAAICUAABglAAAiJQAAnhUAAJwVAAAZJQAAnhUAABklAAAjJQAAnBUAACQlAAAaJQAAnBUAABolAAAZJQAAIyUAABklAAAXJQAAIyUAABclAAAhJQAAJSUAACYlAAAnJQAAJSUAACclAAAoJQAAKSUAAColAAAnJQAAKSUAACclAAAmJQAAKyUAACwlAAAnJQAAKyUAACclAAAqJQAAahIAAC0lAAAlJQAAahIAACUlAAAKJQAALSUAAC4lAAAmJQAALSUAACYlAAAlJQAACiUAACUlAAAoJQAACiUAACglAAAvJQAADBQAABMVAAApJQAADBQAACklAAAwJQAAExUAABIVAAAqJQAAExUAAColAAApJQAAMCUAACklAAAmJQAAMCUAACYlAAAxJQAAEBUAADIlAAArJQAAEBUAACslAAARFQAAMiUAAAwlAAAsJQAAMiUAACwlAAArJQAAERUAACslAAAqJQAAERUAAColAAAzJQAANCUAADUlAAA2JQAANCUAADYlAAA3JQAAOCUAADklAAA2JQAAOCUAADYlAAA1JQAAOiUAADclAAA2JQAAOiUAADYlAAA7JQAAvhMAADwlAAA0JQAAvhMAADQlAAA9JQAAPCUAAD4lAAA1JQAAPCUAADUlAAA0JQAAPSUAADQlAAA3JQAAPSUAADclAACrFAAAkBIAACAlAAA4JQAAkBIAADglAAA/JQAAICUAACIlAAA5JQAAICUAADklAAA4JQAAPyUAADglAAA1JQAAPyUAADUlAABAJQAAGyUAAEElAAA6JQAAGyUAADolAABCJQAAQSUAAKsUAAA3JQAAQSUAADclAAA6JQAAQiUAADolAAA7JQAAQiUAADslAAAdJQAAQyUAAEQlAABFJQAAQyUAAEUlAABGJQAARyUAAEglAABFJQAARyUAAEUlAABJJQAASiUAAEYlAABFJQAASiUAAEUlAABLJQAAahIAAEwlAABDJQAAahIAAEMlAABNJQAATCUAAE4lAABEJQAATCUAAEQlAABDJQAATSUAAEMlAABGJQAATSUAAEYlAAAuJQAAHBMAAA8UAABHJQAAHBMAAEclAABPJQAADxQAAFAlAABIJQAADxQAAEglAABHJQAATyUAAEclAABJJQAATyUAAEklAABOJQAAUSUAADAlAABKJQAAUSUAAEolAABSJQAAMCUAAC4lAABGJQAAMCUAAEYlAABKJQAAUiUAAEolAABLJQAAUiUAAEslAABTJQAAVCUAAFUlAABWJQAAVCUAAFYlAABXJQAAWCUAAFklAABWJQAAWCUAAFYlAABVJQAAWiUAAFclAABWJQAAWiUAAFYlAABbJQAABhIAAFwlAABUJQAABhIAAFQlAABdJQAAXCUAAF4lAABVJQAAXCUAAFUlAABUJQAAXSUAAFQlAABXJQAAXSUAAFclAABfJQAAkBIAAGAlAABYJQAAkBIAAFglAABhJQAAYCUAAD4lAABZJQAAYCUAAFklAABYJQAAYSUAAFglAABVJQAAYSUAAFUlAABeJQAAYiUAAGMlAABaJQAAYiUAAFolAABkJQAAYyUAALsTAABXJQAAYyUAAFclAABaJQAAZCUAAFolAABbJQAAZCUAAFslAAA+JQAAZSUAAGYlAABnJQAAZSUAAGclAABoJQAAaSUAAGolAABnJQAAaSUAAGclAABmJQAAayUAAGglAABnJQAAayUAAGclAABqJQAAahIAAGwlAABlJQAAahIAAGUlAABtJQAAbCUAAG4lAABmJQAAbCUAAGYlAABlJQAAbSUAAGUlAABoJQAAbSUAAGglAABvJQAAaREAAB8TAABpJQAAaREAAGklAABwJQAAHxMAAHElAABqJQAAHxMAAGolAABpJQAAcCUAAGklAABmJQAAcCUAAGYlAAByJQAAHBMAAHMlAABrJQAAHBMAAGslAAB0JQAAcyUAAE4lAABoJQAAcyUAAGglAABrJQAAdCUAAGslAABqJQAAdCUAAGolAAAeEwAAdSUAAHYlAAB3JQAAdSUAAHclAAB4JQAAeSUAAHolAAB3JQAAeSUAAHclAAB7JQAAfCUAAH0lAAB3JQAAfCUAAHclAAB+JQAABhIAAH8lAAB1JQAABhIAAHUlAACAJQAAfyUAAIElAAB2JQAAfyUAAHYlAAB1JQAAgCUAAHUlAAB4JQAAgCUAAHglAACCJQAAcA8AAJMSAAB5JQAAcA8AAHklAACDJQAAkxIAAJISAAB6JQAAkxIAAHolAAB5JQAAgyUAAHklAAB7JQAAgyUAAHslAACBJQAAkBIAAGElAAB8JQAAkBIAAHwlAACREgAAYSUAAIIlAAB9JQAAYSUAAH0lAAB8JQAAkRIAAHwlAAB+JQAAkRIAAH4lAACSEgAAhCUAAIUlAACGJQAAhCUAAIYlAACHJQAAiCUAAIklAACGJQAAiCUAAIYlAACKJQAAiyUAAIwlAACGJQAAiyUAAIYlAACNJQAAEhAAAI4lAACEJQAAEhAAAIQlAACPJQAAjiUAAJAlAACFJQAAjiUAAIUlAACEJQAAjyUAAIQlAACHJQAAjyUAAIclAABnEgAAaREAAJElAACIJQAAaREAAIglAACSJQAAkSUAAG4lAACJJQAAkSUAAIklAACIJQAAkiUAAIglAACKJQAAkiUAAIolAACTJQAAahIAAGgSAACLJQAAahIAAIslAACUJQAAaBIAAGcSAACMJQAAaBIAAIwlAACLJQAAlCUAAIslAACNJQAAlCUAAI0lAABuJQAAlSUAAJYlAACXJQAAlSUAAJclAACYJQAAmSUAAJolAACXJQAAmSUAAJclAACbJQAAnCUAAJglAACXJQAAnCUAAJclAACdJQAAniUAAJ8lAACVJQAAniUAAJUlAAACEgAAnyUAAKAlAACWJQAAnyUAAJYlAACVJQAAAhIAAJUlAACYJQAAAhIAAJglAAChJQAAcA8AAKIlAACZJQAAcA8AAJklAACjJQAAoiUAAIElAACaJQAAoiUAAJolAACZJQAAoyUAAJklAACbJQAAoyUAAJslAACgJQAABhIAAAQSAACcJQAABhIAAJwlAACkJQAABBIAAKUlAACYJQAABBIAAJglAACcJQAApCUAAJwlAACdJQAApCUAAJ0lAACBJQAApiUAAKclAACoJQAApiUAAKglAACpJQAAqiUAAKslAACoJQAAqiUAAKglAACnJQAArCUAAKklAACoJQAArCUAAKglAACtJQAAEhAAAK4lAACmJQAAEhAAAKYlAACOJQAAriUAAK8lAACnJQAAriUAAKclAACmJQAAjiUAAKYlAACpJQAAjiUAAKklAACTJQAAYBAAALAlAACqJQAAYBAAAKolAACxJQAAsCUAAGsRAACrJQAAsCUAAKslAACqJQAAsSUAAKolAACnJQAAsSUAAKclAACyJQAAaREAALMlAACsJQAAaREAAKwlAAC0JQAAsyUAALUlAACpJQAAsyUAAKklAACsJQAAtCUAAKwlAACtJQAAtCUAAK0lAAC2JQAAtyUAALglAAC5JQAAtyUAALklAAC6JQAAuyUAALwlAAC5JQAAuyUAALklAAC9JQAAviUAALolAAC5JQAAviUAALklAAC8JQAAmw4AAL8lAAC3JQAAmw4AALclAADAJQAAvyUAAMElAAC4JQAAvyUAALglAAC3JQAAwCUAALclAAC6JQAAwCUAALolAADCJQAAcA8AAKMlAAC7JQAAcA8AALslAADDJQAAoyUAAKAlAAC8JQAAoyUAALwlAAC7JQAAwyUAALslAAC9JQAAwyUAAL0lAADEJQAABxEAAAURAAC+JQAABxEAAL4lAADFJQAABREAAAQRAAC6JQAABREAALolAAC+JQAAxSUAAL4lAAC8JQAAxSUAALwlAADGJQAAxyUAAMglAADJJQAAxyUAAMklAADKJQAAyyUAAMwlAADJJQAAyyUAAMklAADNJQAAziUAAM8lAADJJQAAziUAAMklAADQJQAAEhAAANElAADHJQAAEhAAAMclAACuJQAA0SUAANIlAADIJQAA0SUAAMglAADHJQAAriUAAMclAADKJQAAriUAAMolAACvJQAA1Q4AAGMQAADLJQAA1Q4AAMslAADTJQAAYxAAANQlAADMJQAAYxAAAMwlAADLJQAA0yUAAMslAADNJQAA0yUAAM0lAADSJQAAYBAAANUlAADOJQAAYBAAAM4lAADWJQAA1SUAAK8lAADPJQAA1SUAAM8lAADOJQAA1iUAAM4lAADQJQAA1iUAANAlAADUJQAA1yUAANglAADZJQAA1yUAANklAADaJQAA2yUAANwlAADZJQAA2yUAANklAADYJQAA3SUAAN4lAADZJQAA3SUAANklAADfJQAAZgwAAOAlAADXJQAAZgwAANclAADhJQAA4CUAAOIlAADYJQAA4CUAANglAADXJQAA4SUAANclAADaJQAA4SUAANolAADjJQAA1Q4AANMlAADbJQAA1Q4AANslAADkJQAA0yUAAOUlAADcJQAA0yUAANwlAADbJQAA5CUAANslAADYJQAA5CUAANglAADmJQAAEhAAABAQAADdJQAAEhAAAN0lAADRJQAAEBAAAA8QAADeJQAAEBAAAN4lAADdJQAA0SUAAN0lAADfJQAA0SUAAN8lAADlJQAA5yUAAOglAADpJQAA5yUAAOklAADqJQAA6yUAAOwlAADpJQAA6yUAAOklAADtJQAA7iUAAOolAADpJQAA7iUAAOklAADsJQAAmw4AAO8lAADnJQAAmw4AAOclAADwJQAA7yUAAPElAADoJQAA7yUAAOglAADnJQAA8CUAAOclAADqJQAA8CUAAOolAADBJQAAiA0AAHMPAADrJQAAiA0AAOslAADyJQAAcw8AAHIPAADsJQAAcw8AAOwlAADrJQAA8iUAAOslAADtJQAA8iUAAO0lAADzJQAAcA8AAMMlAADuJQAAcA8AAO4lAABxDwAAwyUAAMQlAADqJQAAwyUAAOolAADuJQAAcQ8AAO4lAADsJQAAcQ8AAOwlAAD0JQAA9SUAAPYlAAD3JQAA9SUAAPclAAD4JQAA+SUAAPolAAD3JQAA+SUAAPclAAD7JQAA/CUAAP0lAAD3JQAA/CUAAPclAAD6JQAAZgwAAP4lAAD1JQAAZgwAAPUlAADgJQAA/iUAAP8lAAD2JQAA/iUAAPYlAAD1JQAA4CUAAPUlAAD4JQAA4CUAAPglAADmJQAAACYAAAEmAAD5JQAAACYAAPklAAACJgAAASYAANcOAAD6JQAAASYAAPolAAD5JQAAAiYAAPklAAD7JQAAAiYAAPslAAD/JQAA1Q4AAAMmAAD8JQAA1Q4AAPwlAADWDgAAAyYAAAQmAAD9JQAAAyYAAP0lAAD8JQAA1g4AAPwlAAD6JQAA1g4AAPolAAAFJgAABiYAAAcmAAAIJgAABiYAAAgmAAAJJgAACiYAAAsmAAAIJgAACiYAAAgmAAAMJgAADSYAAA4mAAAIJgAADSYAAAgmAAAPJgAAygwAABAmAAAGJgAAygwAAAYmAAARJgAAECYAABImAAAHJgAAECYAAAcmAAAGJgAAESYAAAYmAAAJJgAAESYAAAkmAAATJgAAiA0AAPIlAAAKJgAAiA0AAAomAAAUJgAA8iUAAPElAAALJgAA8iUAAAsmAAAKJgAAFCYAAAomAAAMJgAAFCYAAAwmAAASJgAAmw4AAJkOAAANJgAAmw4AAA0mAADvJQAAmQ4AAJgOAAAOJgAAmQ4AAA4mAAANJgAA7yUAAA0mAAAPJgAA7yUAAA8mAADzJQAAFSYAABYmAAAXJgAAFSYAABcmAAAYJgAAGSYAABomAAAXJgAAGSYAABcmAAAbJgAAHCYAAB0mAAAXJgAAHCYAABcmAAAeJgAAygwAAB8mAAAVJgAAygwAABUmAAAgJgAAHyYAACEmAAAWJgAAHyYAABYmAAAVJgAAICYAABUmAAAYJgAAICYAABgmAAASJgAAjQ0AAIsNAAAZJgAAjQ0AABkmAAAiJgAAiw0AAIoNAAAaJgAAiw0AABomAAAZJgAAIiYAABkmAAAbJgAAIiYAABsmAAAhJgAAiA0AACMmAAAcJgAAiA0AABwmAACJDQAAIyYAABImAAAdJgAAIyYAAB0mAAAcJgAAiQ0AABwmAAAeJgAAiQ0AAB4mAAAkJgAAJSYAACYmAAAnJgAAJSYAACcmAAAoJgAAKSYAAComAAAnJgAAKSYAACcmAAAmJgAAKyYAACgmAAAnJgAAKyYAACcmAAAqJgAAZgwAACwmAAAlJgAAZgwAACUmAAD+JQAALCYAAC0mAAAmJgAALCYAACYmAAAlJgAA/iUAACUmAAAoJgAA/iUAACgmAAAuJgAAhQsAAEMNAAApJgAAhQsAACkmAAAvJgAAQw0AADAmAAAqJgAAQw0AAComAAApJgAALyYAACkmAAAmJgAALyYAACYmAAAtJgAAMSYAAAImAAArJgAAMSYAACsmAABBDQAAAiYAAC4mAAAoJgAAAiYAACgmAAArJgAAQQ0AACsmAAAqJgAAQQ0AAComAAAyJgAAMyYAADQmAAA1JgAAMyYAADUmAAA2JgAANyYAADgmAAA1JgAANyYAADUmAAA5JgAAOiYAADYmAAA1JgAAOiYAADUmAAA7JgAAPCYAAD0mAAAzJgAAPCYAADMmAADGDAAAPSYAAD4mAAA0JgAAPSYAADQmAAAzJgAAxgwAADMmAAA2JgAAxgwAADYmAAA/JgAAjQ0AAEAmAAA3JgAAjQ0AADcmAABBJgAAQCYAACEmAAA4JgAAQCYAADgmAAA3JgAAQSYAADcmAAA5JgAAQSYAADkmAABCJgAAygwAAMgMAAA6JgAAygwAADomAAAfJgAAyAwAAEMmAAA2JgAAyAwAADYmAAA6JgAAHyYAADomAAA7JgAAHyYAADsmAAAhJgAARCYAAEUmAABGJgAARCYAAEYmAABHJgAASCYAAEkmAABGJgAASCYAAEYmAABKJgAASyYAAEcmAABGJgAASyYAAEYmAABJJgAAYQwAAEwmAABEJgAAYQwAAEQmAABNJgAATCYAAE4mAABFJgAATCYAAEUmAABEJgAATSYAAEQmAABHJgAATSYAAEcmAABPJgAAhQsAAC8mAABIJgAAhQsAAEgmAABQJgAALyYAAC0mAABJJgAALyYAAEkmAABIJgAAUCYAAEgmAABKJgAAUCYAAEomAABRJgAAZgwAAGQMAABLJgAAZgwAAEsmAAAsJgAAZAwAAGMMAABHJgAAZAwAAEcmAABLJgAALCYAAEsmAABJJgAALCYAAEkmAAAtJgAAUiYAAFMmAABUJgAAUiYAAFQmAABVJgAAViYAAFcmAABUJgAAViYAAFQmAABYJgAAWSYAAFomAABUJgAAWSYAAFQmAABbJgAAYQwAAFwmAABSJgAAYQwAAFImAABMJgAAXCYAAF0mAABTJgAAXCYAAFMmAABSJgAATCYAAFImAABVJgAATCYAAFUmAABOJgAAigsAAIgLAABWJgAAigsAAFYmAABeJgAAiAsAAIcLAABXJgAAiAsAAFcmAABWJgAAXiYAAFYmAABYJgAAXiYAAFgmAABdJgAAhQsAAFAmAABZJgAAhQsAAFkmAABfJgAAUCYAAFEmAABaJgAAUCYAAFomAABZJgAAXyYAAFkmAABbJgAAXyYAAFsmAABgJgAAYSYAAGImAABjJgAAYSYAAGMmAABkJgAAZSYAAGYmAABjJgAAZSYAAGMmAABiJgAAZyYAAGQmAABjJgAAZyYAAGMmAABoJgAAOgsAAGkmAABhJgAAOgsAAGEmAABqJgAAaSYAAGsmAABiJgAAaSYAAGImAABhJgAAaiYAAGEmAABkJgAAaiYAAGQmAAA8CwAAjQ0AAEEmAABlJgAAjQ0AAGUmAABsJgAAQSYAAEImAABmJgAAQSYAAGYmAABlJgAAbCYAAGUmAABiJgAAbCYAAGImAABrJgAAPwsAAD0LAABnJgAAPwsAAGcmAABtJgAAPQsAADwLAABkJgAAPQsAAGQmAABnJgAAbSYAAGcmAABoJgAAbSYAAGgmAABCJgAAbiYAAG8mAABwJgAAbiYAAHAmAABxJgAAciYAAHMmAABwJgAAciYAAHAmAABvJgAAdCYAAHEmAABwJgAAdCYAAHAmAAB1JgAAOgsAAHYmAABuJgAAOgsAAG4mAAB3JgAAdiYAAHgmAABvJgAAdiYAAG8mAABuJgAAdyYAAG4mAABxJgAAdyYAAHEmAAB5JgAAOBUAAPMWAAByJgAAOBUAAHImAAB6JgAA8xYAAPIWAABzJgAA8xYAAHMmAAByJgAAeiYAAHImAABvJgAAeiYAAG8mAAB7JgAAjQ0AAGwmAAB0JgAAjQ0AAHQmAAB8JgAAbCYAAHkmAABxJgAAbCYAAHEmAAB0JgAAfCYAAHQmAAB1JgAAfCYAAHUmAADyFgAAfSYAAH4mAAB/JgAAfSYAAH8mAACAJgAAgSYAAIImAAB/JgAAgSYAAH8mAACDJgAAhCYAAIUmAAB/JgAAhCYAAH8mAACGJgAAIhQAAIcmAAB9JgAAIhQAAH0mAACIJgAAhyYAAIkmAAB+JgAAhyYAAH4mAAB9JgAAiCYAAH0mAACAJgAAiCYAAIAmAADUFgAAigsAAF4mAACBJgAAigsAAIEmAACKJgAAXiYAAF0mAACCJgAAXiYAAIImAACBJgAAiiYAAIEmAACDJgAAiiYAAIMmAACLJgAAYQwAANUWAACEJgAAYQwAAIQmAACMJgAA1RYAANQWAACFJgAA1RYAAIUmAACEJgAAjCYAAIQmAACGJgAAjCYAAIYmAACNJgAAjiYAAI8mAACQJgAAjiYAAJAmAACRJgAAkiYAAJMmAACQJgAAkiYAAJAmAACPJgAAlCYAAJEmAACQJgAAlCYAAJAmAACVJgAAIhQAAJYmAACOJgAAIhQAAI4mAACHJgAAliYAAJcmAACPJgAAliYAAI8mAACOJgAAhyYAAI4mAACRJgAAhyYAAJEmAACJJgAAmCYAAJkmAACSJgAAmCYAAJImAACaJgAAmSYAABsWAACTJgAAmSYAAJMmAACSJgAAmiYAAJImAACPJgAAmiYAAI8mAACXJgAAigsAAJsmAACUJgAAigsAAJQmAAAaFgAAmyYAAIsmAACRJgAAmyYAAJEmAACUJgAAGhYAAJQmAACVJgAAGhYAAJUmAAAbFgAAnCYAAJ0mAACeJgAAnCYAAJ4mAACfJgAAoCYAAKEmAACeJgAAoCYAAJ4mAACiJgAAoyYAAKQmAACeJgAAoyYAAJ4mAAChJgAAchQAAKUmAACcJgAAchQAAJwmAACmJgAApSYAAKcmAACdJgAApSYAAJ0mAACcJgAApiYAAJwmAACfJgAApiYAAJ8mAACoJgAAOBUAAKkmAACgJgAAOBUAAKAmAACqJgAAqSYAAKsmAAChJgAAqSYAAKEmAACgJgAAqiYAAKAmAACiJgAAqiYAAKImAACnJgAAOgsAAOoVAACjJgAAOgsAAKMmAACsJgAA6hUAAOkVAACkJgAA6hUAAKQmAACjJgAArCYAAKMmAAChJgAArCYAAKEmAAB7JgAArSYAAK4mAACvJgAArSYAAK8mAACwJgAAsSYAALImAACvJgAAsSYAAK8mAACuJgAAsyYAALAmAACvJgAAsyYAAK8mAACyJgAAchQAALQmAACtJgAAchQAAK0mAAClJgAAtCYAALUmAACuJgAAtCYAAK4mAACtJgAApSYAAK0mAACwJgAApSYAALAmAAC2JgAAfBIAADsVAACxJgAAfBIAALEmAAC3JgAAOxUAADoVAACyJgAAOxUAALImAACxJgAAtyYAALEmAACuJgAAtyYAAK4mAAC1JgAAOBUAAKomAACzJgAAOBUAALMmAAA5FQAAqiYAALYmAACwJgAAqiYAALAmAACzJgAAORUAALMmAACyJgAAORUAALImAAA6FQAAuCYAALkmAAC6JgAAuCYAALomAAC7JgAAvCYAAL0mAAC6JgAAvCYAALomAAC+JgAAvyYAAMAmAAC6JgAAvyYAALomAAC9JgAAIhQAAMEmAAC4JgAAIhQAALgmAADCJgAAwSYAAMMmAAC5JgAAwSYAALkmAAC4JgAAwiYAALgmAAC7JgAAwiYAALsmAADEJgAAWBMAANcUAAC8JgAAWBMAALwmAADFJgAA1xQAAMYmAAC9JgAA1xQAAL0mAAC8JgAAxSYAALwmAAC+JgAAxSYAAL4mAADDJgAAxyYAAMgmAAC/JgAAxyYAAL8mAADJJgAAyCYAAMomAADAJgAAyCYAAMAmAAC/JgAAySYAAL8mAAC9JgAAySYAAL0mAADGJgAAyyYAAMwmAADNJgAAyyYAAM0mAADOJgAAzyYAANAmAADNJgAAzyYAAM0mAADMJgAA0SYAAM4mAADNJgAA0SYAAM0mAADQJgAA0iYAANMmAADLJgAA0iYAAMsmAABuFAAA0yYAANQmAADMJgAA0yYAAMwmAADLJgAAbhQAAMsmAADOJgAAbhQAAM4mAADVJgAAfBIAANYmAADPJgAAfBIAAM8mAADXJgAA1iYAALUmAADQJgAA1iYAANAmAADPJgAA1yYAAM8mAADMJgAA1yYAAMwmAADYJgAAchQAAHAUAADRJgAAchQAANEmAADZJgAAcBQAANomAADOJgAAcBQAAM4mAADRJgAA2SYAANEmAADQJgAA2SYAANAmAADbJgAA3CYAAN0mAADeJgAA3CYAAN4mAADfJgAA4CYAAOEmAADeJgAA4CYAAN4mAADdJgAA4iYAAN8mAADeJgAA4iYAAN4mAADjJgAAexAAAOQmAADcJgAAexAAANwmAADlJgAA5CYAAOYmAADdJgAA5CYAAN0mAADcJgAA5SYAANwmAADfJgAA5SYAAN8mAADnJgAAWBMAAOgmAADgJgAAWBMAAOAmAADpJgAA6CYAAMMmAADhJgAA6CYAAOEmAADgJgAA6SYAAOAmAADdJgAA6SYAAN0mAADmJgAAIhQAACAUAADiJgAAIhQAAOImAADqJgAAIBQAAB8UAADfJgAAIBQAAN8mAADiJgAA6iYAAOImAADjJgAA6iYAAOMmAADDJgAA6yYAAOwmAADtJgAA6yYAAO0mAADuJgAA7yYAAPAmAADtJgAA7yYAAO0mAADxJgAA8iYAAPMmAADtJgAA8iYAAO0mAAD0JgAAexAAAPUmAADrJgAAexAAAOsmAAD2JgAA9SYAAPcmAADsJgAA9SYAAOwmAADrJgAA9iYAAOsmAADuJgAA9iYAAO4mAADmJgAA+CYAAPkmAADvJgAA+CYAAO8mAAD6JgAA+SYAAFoTAADwJgAA+SYAAPAmAADvJgAA+iYAAO8mAADxJgAA+iYAAPEmAAD7JgAAWBMAAPwmAADyJgAAWBMAAPImAAD9JgAA/CYAAP4mAADzJgAA/CYAAPMmAADyJgAA/SYAAPImAAD0JgAA/SYAAPQmAABaEwAA/yYAAAAnAAABJwAA/yYAAAEnAAACJwAAAycAAAQnAAABJwAAAycAAAEnAAAAJwAABScAAAYnAAABJwAABScAAAEnAAAHJwAAuxEAAAgnAAD/JgAAuxEAAP8mAAAuEwAACCcAAAknAAAAJwAACCcAAAAnAAD/JgAALhMAAP8mAAACJwAALhMAAAInAAAKJwAAfBIAANcmAAADJwAAfBIAAAMnAAALJwAA1yYAANgmAAAEJwAA1yYAAAQnAAADJwAACycAAAMnAAAAJwAACycAAAAnAAAJJwAAMhMAAAwnAAAFJwAAMhMAAAUnAADTJgAADCcAAC8TAAAGJwAADCcAAAYnAAAFJwAA0yYAAAUnAAAHJwAA0yYAAAcnAADYJgAADScAAA4nAAAPJwAADScAAA8nAAAQJwAAEScAABInAAAPJwAAEScAAA8nAAATJwAAFCcAABUnAAAPJwAAFCcAAA8nAAASJwAAuxEAABYnAAANJwAAuxEAAA0nAAAXJwAAFicAABgnAAAOJwAAFicAAA4nAAANJwAAFycAAA0nAAAQJwAAFycAABAnAAAJJwAAVg0AAH8SAAARJwAAVg0AABEnAAAZJwAAfxIAAH4SAAASJwAAfxIAABInAAARJwAAGScAABEnAAATJwAAGScAABMnAAAaJwAAfBIAAAsnAAAUJwAAfBIAABQnAAB9EgAACycAABsnAAAVJwAACycAABUnAAAUJwAAfRIAABQnAAASJwAAfRIAABInAAB+EgAAHCcAAB0nAAAeJwAAHCcAAB4nAAAfJwAAICcAACEnAAAeJwAAICcAAB4nAAAdJwAAIicAACMnAAAeJwAAIicAAB4nAAAhJwAAexAAACQnAAAcJwAAexAAABwnAAAlJwAAJCcAACYnAAAdJwAAJCcAAB0nAAAcJwAAJScAABwnAAAfJwAAJScAAB8nAAD7JgAALREAACcnAAAgJwAALREAACAnAAAoJwAAJycAAC4SAAAhJwAAJycAACEnAAAgJwAAKCcAACAnAAAdJwAAKCcAAB0nAAApJwAALBIAAPomAAAiJwAALBIAACInAAAqJwAA+iYAAPsmAAAjJwAA+iYAACMnAAAiJwAAKicAACInAAAhJwAAKicAACEnAAArJwAALCcAAC0nAAAuJwAALCcAAC4nAAAvJwAAMCcAADEnAAAuJwAAMCcAAC4nAAAtJwAAMicAAC8nAAAuJwAAMicAAC4nAAAxJwAAMycAADQnAAAsJwAAMycAACwnAAA1JwAANCcAADYnAAAtJwAANCcAAC0nAAAsJwAANScAACwnAAAvJwAANScAAC8nAAA3JwAAVg0AABknAAAwJwAAVg0AADAnAAA4JwAAGScAABonAAAxJwAAGScAADEnAAAwJwAAOCcAADAnAAAtJwAAOCcAAC0nAAA5JwAAuxEAALkRAAAyJwAAuxEAADInAAAWJwAAuREAALgRAAAvJwAAuREAAC8nAAAyJwAAFicAADInAAAxJwAAFicAADEnAAAYJwAAOicAADsnAAA8JwAAOicAADwnAAA9JwAAPicAAD8nAAA8JwAAPicAADwnAABAJwAAQScAAD0nAAA8JwAAQScAADwnAAA/JwAAexAAAEInAAA6JwAAexAAADonAAAkJwAAQicAAEMnAAA7JwAAQicAADsnAAA6JwAAJCcAADonAAA9JwAAJCcAAD0nAAApJwAAwA8AADARAAA+JwAAwA8AAD4nAABEJwAAMBEAAC8RAAA/JwAAMBEAAD8nAAA+JwAARCcAAD4nAABAJwAARCcAAEAnAABFJwAARicAACgnAABBJwAARicAAEEnAAAuEQAAKCcAACYnAAA9JwAAKCcAAD0nAABBJwAALhEAAEEnAAA/JwAALhEAAD8nAABHJwAASCcAAEknAABKJwAASCcAAEonAABLJwAATCcAAE0nAABKJwAATCcAAEonAABJJwAATicAAEsnAABKJwAATicAAEonAABPJwAAhg8AAFAnAABIJwAAhg8AAEgnAABRJwAAUCcAAFInAABJJwAAUCcAAEknAABIJwAAUScAAEgnAABLJwAAUScAAEsnAADIEAAAVg0AADgnAABMJwAAVg0AAEwnAABTJwAAOCcAADknAABNJwAAOCcAAE0nAABMJwAAUycAAEwnAABJJwAAUycAAEknAABUJwAAVScAAFYnAABOJwAAVScAAE4nAABXJwAAVicAAMgQAABLJwAAVicAAEsnAABOJwAAVycAAE4nAABPJwAAVycAAE8nAAA5JwAAWCcAAFknAABaJwAAWCcAAFonAABbJwAAXCcAAF0nAABaJwAAXCcAAFonAABZJwAAXicAAFsnAABaJwAAXicAAFonAABfJwAAdhAAAGAnAABYJwAAdhAAAFgnAABhJwAAYCcAAGInAABZJwAAYCcAAFknAABYJwAAYScAAFgnAABbJwAAYScAAFsnAABjJwAAwA8AAEQnAABcJwAAwA8AAFwnAABkJwAARCcAAEUnAABdJwAARCcAAF0nAABcJwAAZCcAAFwnAABZJwAAZCcAAFknAABlJwAAexAAAHkQAABeJwAAexAAAF4nAABCJwAAeRAAAHgQAABbJwAAeRAAAFsnAABeJwAAQicAAF4nAABfJwAAQicAAF8nAABFJwAAZicAAGcnAABoJwAAZicAAGgnAABpJwAAaicAAGsnAABoJwAAaicAAGgnAABnJwAAbCcAAGknAABoJwAAbCcAAGgnAABtJwAAdhAAAG4nAABmJwAAdhAAAGYnAABgJwAAbicAAG8nAABnJwAAbicAAGcnAABmJwAAYCcAAGYnAABpJwAAYCcAAGknAABwJwAAcScAAHInAABqJwAAcScAAGonAABzJwAAcicAAMIPAABrJwAAcicAAGsnAABqJwAAcycAAGonAABnJwAAcycAAGcnAABvJwAAwA8AAGQnAABsJwAAwA8AAGwnAAB0JwAAZCcAAGInAABpJwAAZCcAAGknAABsJwAAdCcAAGwnAABtJwAAdCcAAG0nAAB1JwAAdicAAHcnAAB4JwAAdicAAHgnAAB5JwAAeicAAHsnAAB4JwAAeicAAHgnAAB3JwAAfCcAAHknAAB4JwAAfCcAAHgnAAB7JwAAfScAAH4nAAB2JwAAfScAAHYnAACCDwAAficAAH8nAAB3JwAAficAAHcnAAB2JwAAgg8AAHYnAAB5JwAAgg8AAHknAACAJwAAVg0AAFMnAAB6JwAAVg0AAHonAACBJwAAUycAAIInAAB7JwAAUycAAHsnAAB6JwAAgScAAHonAAB3JwAAgScAAHcnAACDJwAAhg8AAIQPAAB8JwAAhg8AAHwnAABQJwAAhA8AAIAnAAB5JwAAhA8AAHknAAB8JwAAUCcAAHwnAAB7JwAAUCcAAHsnAACCJwAAhCcAAIUnAACGJwAAhCcAAIYnAACHJwAAiCcAAIknAACGJwAAiCcAAIYnAACFJwAAiicAAIsnAACGJwAAiicAAIYnAACMJwAAdhAAAI0nAACEJwAAdhAAAIQnAABuJwAAjScAAI4nAACFJwAAjScAAIUnAACEJwAAbicAAIQnAACHJwAAbicAAIcnAABvJwAABA0AAI8nAACIJwAABA0AAIgnAACQJwAAjycAAMMOAACJJwAAjycAAIknAACIJwAAkCcAAIgnAACFJwAAkCcAAIUnAACOJwAAcScAAHMnAACKJwAAcScAAIonAACRJwAAcycAAG8nAACLJwAAcycAAIsnAACKJwAAkScAAIonAACMJwAAkScAAIwnAADDDgAAkicAAJMnAACUJwAAkicAAJQnAACVJwAAlicAAJcnAACUJwAAlicAAJQnAACTJwAAmCcAAJUnAACUJwAAmCcAAJQnAACZJwAAogwAAJonAACSJwAAogwAAJInAABbDgAAmicAAJsnAACTJwAAmicAAJMnAACSJwAAWw4AAJInAACVJwAAWw4AAJUnAABcDgAAVg0AAIEnAACWJwAAVg0AAJYnAACcJwAAgScAAIMnAACXJwAAgScAAJcnAACWJwAAnCcAAJYnAACTJwAAnCcAAJMnAACdJwAAfScAAF0OAACYJwAAfScAAJgnAACeJwAAXQ4AAFwOAACVJwAAXQ4AAJUnAACYJwAAnicAAJgnAACZJwAAnicAAJknAACDJwAAnycAAKAnAAChJwAAnycAAKEnAACiJwAAoycAAKQnAAChJwAAoycAAKEnAACgJwAApScAAKInAAChJwAApScAAKEnAACkJwAAogwAAKYnAACfJwAAogwAAJ8nAACaJwAApicAAKcnAACgJwAApicAAKAnAACfJwAAmicAAJ8nAACiJwAAmicAAKInAACoJwAAWw0AAFkNAACjJwAAWw0AAKMnAACpJwAAWQ0AAFgNAACkJwAAWQ0AAKQnAACjJwAAqScAAKMnAACgJwAAqScAAKAnAACqJwAAVg0AAKsnAAClJwAAVg0AAKUnAACsJwAAqycAAJ0nAACiJwAAqycAAKInAAClJwAArCcAAKUnAACkJwAArCcAAKQnAABYDQAArScAAK4nAACvJwAArScAAK8nAACwJwAAsScAALInAACvJwAAsScAAK8nAACuJwAAsycAALAnAACvJwAAsycAAK8nAAC0JwAAdhAAALUnAACtJwAAdhAAAK0nAACNJwAAtScAALYnAACuJwAAtScAAK4nAACtJwAAjScAAK0nAACwJwAAjScAALAnAACOJwAAtycAALgnAACxJwAAtycAALEnAAC5JwAAuCcAALonAACyJwAAuCcAALInAACxJwAAuScAALEnAACuJwAAuScAAK4nAAC7JwAABA0AAJAnAACzJwAABA0AALMnAAC8JwAAkCcAAI4nAACwJwAAkCcAALAnAACzJwAAvCcAALMnAAC0JwAAvCcAALQnAAAGDQAAvScAAL4nAAC/JwAAvScAAL8nAADAJwAAwScAAMInAAC/JwAAwScAAL8nAADDJwAAxCcAAMAnAAC/JwAAxCcAAL8nAADCJwAAxScAAMYnAAC9JwAAxScAAL0nAADHJwAAxicAAMgnAAC+JwAAxicAAL4nAAC9JwAAxycAAL0nAADAJwAAxycAAMAnAACfDAAAWw0AAKknAADBJwAAWw0AAMEnAADJJwAAqScAAKonAADCJwAAqScAAMInAADBJwAAyScAAMEnAADDJwAAyScAAMMnAADKJwAAogwAAKAMAADEJwAAogwAAMQnAADLJwAAoAwAAMwnAADAJwAAoAwAAMAnAADEJwAAyycAAMQnAADCJwAAyycAAMInAACnJwAAzScAAM4nAADPJwAAzScAAM8nAADQJwAA0ScAANInAADPJwAA0ScAAM8nAADTJwAA1CcAANAnAADPJwAA1CcAAM8nAADVJwAAcQsAANYnAADNJwAAcQsAAM0nAAAwDAAA1icAANcnAADOJwAA1icAAM4nAADNJwAAMAwAAM0nAADQJwAAMAwAANAnAADYJwAAWw0AAMknAADRJwAAWw0AANEnAADZJwAAyScAAMonAADSJwAAyScAANInAADRJwAA2ScAANEnAADTJwAA2ScAANMnAADXJwAAxScAANonAADUJwAAxScAANQnAADGJwAA2icAADEMAADQJwAA2icAANAnAADUJwAAxicAANQnAADVJwAAxicAANUnAADIJwAA2ycAANwnAADdJwAA2ycAAN0nAADeJwAA3ycAAOAnAADdJwAA3ycAAN0nAADhJwAA4icAAN4nAADdJwAA4icAAN0nAADgJwAAdhAAAOMnAADbJwAAdhAAANsnAADkJwAA4ycAAOUnAADcJwAA4ycAANwnAADbJwAA5CcAANsnAADeJwAA5CcAAN4nAAC7JwAAcQsAAG8LAADfJwAAcQsAAN8nAADmJwAAbwsAAOcnAADgJwAAbwsAAOAnAADfJwAA5icAAN8nAADhJwAA5icAAOEnAADlJwAAtycAAOgnAADiJwAAtycAAOInAADpJwAA6CcAAOonAADeJwAA6CcAAN4nAADiJwAA6ScAAOInAADgJwAA6ScAAOAnAADnJwAA6ycAAOwnAADtJwAA6ycAAO0nAADuJwAA7ycAAPAnAADtJwAA7ycAAO0nAADxJwAA8icAAO4nAADtJwAA8icAAO0nAADzJwAAdhAAAPQnAADrJwAAdhAAAOsnAADjJwAA9CcAAPUnAADsJwAA9CcAAOwnAADrJwAA4ycAAOsnAADuJwAA4ycAAO4nAAD2JwAAWw0AAPcnAADvJwAAWw0AAO8nAAD4JwAA9ycAANcnAADwJwAA9ycAAPAnAADvJwAA+CcAAO8nAADxJwAA+CcAAPEnAAD1JwAAcQsAAPknAADyJwAAcQsAAPInAAD6JwAA+ScAAPsnAADuJwAA+ScAAO4nAADyJwAA+icAAPInAADzJwAA+icAAPMnAADXJwAA/CcAAP0nAAD+JwAA/CcAAP4nAAD/JwAAACgAAAEoAAD+JwAAACgAAP4nAAD9JwAAAigAAP8nAAD+JwAAAigAAP4nAAABKAAAehYAAAMoAAD8JwAAehYAAPwnAAAtFwAAAygAAAQoAAD9JwAAAygAAP0nAAD8JwAALRcAAPwnAAD/JwAALRcAAP8nAAAuFwAAWw0AAAUoAAAAKAAAWw0AAAAoAAAGKAAABSgAAAcoAAABKAAABSgAAAEoAAAAKAAABigAAAAoAAD9JwAABigAAP0nAAAIKAAAdhAAAC8XAAACKAAAdhAAAAIoAAAJKAAALxcAAC4XAAD/JwAALxcAAP8nAAACKAAACSgAAAIoAAABKAAACSgAAAEoAAD1JwAACigAAAsoAAAMKAAACigAAAwoAAANKAAADigAAA8oAAAMKAAADigAAAwoAAAQKAAAESgAABIoAAAMKAAAESgAAAwoAAAPKAAAehYAABMoAAAKKAAAehYAAAooAAADKAAAEygAABQoAAALKAAAEygAAAsoAAAKKAAAAygAAAooAAANKAAAAygAAA0oAAAEKAAA2BUAALIWAAAOKAAA2BUAAA4oAAAVKAAAshYAALEWAAAPKAAAshYAAA8oAAAOKAAAFSgAAA4oAAAQKAAAFSgAABAoAAAWKAAAWw0AAAYoAAARKAAAWw0AABEoAACwFgAABigAAAQoAAASKAAABigAABIoAAARKAAAsBYAABEoAAAPKAAAsBYAAA8oAACxFgAAFygAABgoAAAZKAAAFygAABkoAAAaKAAAGygAABwoAAAZKAAAGygAABkoAAAYKAAAHSgAAB4oAAAZKAAAHSgAABkoAAAcKAAAihUAAB8oAAAXKAAAihUAABcoAAB2FgAAHygAACAoAAAYKAAAHygAABgoAAAXKAAAdhYAABcoAAAaKAAAdhYAABooAAB3FgAA2BUAACEoAAAbKAAA2BUAABsoAAAiKAAAISgAABYoAAAcKAAAISgAABwoAAAbKAAAIigAABsoAAAYKAAAIigAABgoAAAjKAAAehYAAHgWAAAdKAAAehYAAB0oAAAkKAAAeBYAAHcWAAAeKAAAeBYAAB4oAAAdKAAAJCgAAB0oAAAcKAAAJCgAABwoAAAWKAAAJSgAACYoAAAnKAAAJSgAACcoAAAoKAAAKSgAACooAAAnKAAAKSgAACcoAAArKAAALCgAAC0oAAAnKAAALCgAACcoAAAuKAAAihUAAC8oAAAlKAAAihUAACUoAAAwKAAALygAADEoAAAmKAAALygAACYoAAAlKAAAMCgAACUoAAAoKAAAMCgAACgoAAAjKAAA/BQAANsVAAApKAAA/BQAACkoAAAyKAAA2xUAANoVAAAqKAAA2xUAACooAAApKAAAMigAACkoAAArKAAAMigAACsoAAAzKAAA2BUAACIoAAAsKAAA2BUAACwoAADZFQAAIigAACAoAAAtKAAAIigAAC0oAAAsKAAA2RUAACwoAAAuKAAA2RUAAC4oAADaFQAANCgAADUoAAA2KAAANCgAADYoAAA3KAAAOCgAADkoAAA2KAAAOCgAADYoAAA1KAAAOigAADsoAAA2KAAAOigAADYoAAA8KAAAmhQAAD0oAAA0KAAAmhQAADQoAAA+KAAAPSgAAD8oAAA1KAAAPSgAADUoAAA0KAAAPigAADQoAAA3KAAAPigAADcoAACHFQAA/BQAAEAoAAA4KAAA/BQAADgoAABBKAAAQCgAADEoAAA5KAAAQCgAADkoAAA4KAAAQSgAADgoAAA1KAAAQSgAADUoAABCKAAAihUAAIgVAAA6KAAAihUAADooAAAvKAAAiBUAAIcVAAA7KAAAiBUAADsoAAA6KAAALygAADooAAA8KAAALygAADwoAAAzKAAAQygAAEQoAABFKAAAQygAAEUoAABGKAAARygAAEgoAABFKAAARygAAEUoAABJKAAASigAAEsoAABFKAAASigAAEUoAABMKAAAmhQAAE0oAABDKAAAmhQAAEMoAAA9KAAATSgAAE4oAABEKAAATSgAAEQoAABDKAAAPSgAAEMoAABGKAAAPSgAAEYoAABPKAAA+BMAAP8UAABHKAAA+BMAAEcoAABQKAAA/xQAAP4UAABIKAAA/xQAAEgoAABHKAAAUCgAAEcoAABJKAAAUCgAAEkoAABRKAAA/BQAAEEoAABKKAAA/BQAAEooAABSKAAAQSgAAE8oAABLKAAAQSgAAEsoAABKKAAAUigAAEooAABMKAAAUigAAEwoAAD+FAAAUygAAFQoAABVKAAAUygAAFUoAABWKAAAVygAAFgoAABVKAAAVygAAFUoAABUKAAAWSgAAFooAABVKAAAWSgAAFUoAABYKAAAqhMAAFsoAABTKAAAqhMAAFMoAABcKAAAWygAAF0oAABUKAAAWygAAFQoAABTKAAAXCgAAFMoAABWKAAAXCgAAFYoAACXFAAA+BMAAF4oAABXKAAA+BMAAFcoAABfKAAAXigAAFEoAABYKAAAXigAAFgoAABXKAAAXygAAFcoAABUKAAAXygAAFQoAABgKAAAmhQAAJgUAABZKAAAmhQAAFkoAABhKAAAmBQAAJcUAABaKAAAmBQAAFooAABZKAAAYSgAAFkoAABYKAAAYSgAAFgoAABRKAAAYigAAGMoAABkKAAAYigAAGQoAABlKAAAZigAAGcoAABkKAAAZigAAGQoAABoKAAAaSgAAGUoAABkKAAAaSgAAGQoAABnKAAAqhMAAGooAABiKAAAqhMAAGIoAABbKAAAaigAAGsoAABjKAAAaigAAGMoAABiKAAAWygAAGIoAABlKAAAWygAAGUoAABgKAAACBMAAPsTAABmKAAACBMAAGYoAABsKAAA+xMAAPoTAABnKAAA+xMAAGcoAABmKAAAbCgAAGYoAABoKAAAbCgAAGgoAABrKAAA+BMAAG0oAABpKAAA+BMAAGkoAABuKAAAbSgAAG8oAABlKAAAbSgAAGUoAABpKAAAbigAAGkoAABnKAAAbigAAGcoAAD6EwAAcCgAAHEoAAByKAAAcCgAAHIoAABzKAAAdCgAAHUoAAByKAAAdCgAAHIoAABxKAAAdigAAHMoAAByKAAAdigAAHIoAAB3KAAAzhIAAHgoAABwKAAAzhIAAHAoAAB5KAAAeCgAAHooAABxKAAAeCgAAHEoAABwKAAAeSgAAHAoAABzKAAAeSgAAHMoAACnEwAACBMAAHsoAAB0KAAACBMAAHQoAAB8KAAAeygAAH0oAAB1KAAAeygAAHUoAAB0KAAAfCgAAHQoAABxKAAAfCgAAHEoAAB+KAAAqhMAAKgTAAB2KAAAqhMAAHYoAAB/KAAAqBMAAKcTAABzKAAAqBMAAHMoAAB2KAAAfygAAHYoAAB3KAAAfygAAHcoAABrKAAAgCgAAIEoAACCKAAAgCgAAIIoAACDKAAAhCgAAIUoAACCKAAAhCgAAIIoAACGKAAAhygAAIgoAACCKAAAhygAAIIoAACFKAAAzhIAAIkoAACAKAAAzhIAAIAoAAB4KAAAiSgAAIooAACBKAAAiSgAAIEoAACAKAAAeCgAAIAoAACDKAAAeCgAAIMoAAB+KAAAQBIAAAsTAACEKAAAQBIAAIQoAACLKAAACxMAAAoTAACFKAAACxMAAIUoAACEKAAAiygAAIQoAACGKAAAiygAAIYoAACKKAAACBMAAIwoAACHKAAACBMAAIcoAACNKAAAjCgAAI4oAACIKAAAjCgAAIgoAACHKAAAjSgAAIcoAACFKAAAjSgAAIUoAAAKEwAAjygAAJAoAACRKAAAjygAAJEoAACSKAAAkygAAJQoAACRKAAAkygAAJEoAACVKAAAligAAJIoAACRKAAAligAAJEoAACXKAAA8hEAAJgoAACPKAAA8hEAAI8oAACZKAAAmCgAAJooAACQKAAAmCgAAJAoAACPKAAAmSgAAI8oAACSKAAAmSgAAJIoAADLEgAAQBIAAJsoAACTKAAAQBIAAJMoAACcKAAAmygAAIooAACUKAAAmygAAJQoAACTKAAAnCgAAJMoAACVKAAAnCgAAJUoAACdKAAAzhIAAMwSAACWKAAAzhIAAJYoAACJKAAAzBIAAMsSAACSKAAAzBIAAJIoAACWKAAAiSgAAJYoAACXKAAAiSgAAJcoAACKKAAAnigAAJ8oAACgKAAAnigAAKAoAAChKAAAoigAAKMoAACgKAAAoigAAKAoAACfKAAApCgAAKUoAACgKAAApCgAAKAoAACmKAAA8hEAAKcoAACeKAAA8hEAAJ4oAACYKAAApygAAKgoAACfKAAApygAAJ8oAACeKAAAmCgAAJ4oAAChKAAAmCgAAKEoAACaKAAAVREAAEMSAACiKAAAVREAAKIoAACpKAAAQxIAAEISAACjKAAAQxIAAKMoAACiKAAAqSgAAKIoAACfKAAAqSgAAJ8oAACqKAAAQBIAAKsoAACkKAAAQBIAAKQoAABBEgAAqygAAJ0oAAClKAAAqygAAKUoAACkKAAAQRIAAKQoAACmKAAAQRIAAKYoAABCEgAArCgAAK0oAACuKAAArCgAAK4oAACvKAAAsCgAALEoAACuKAAAsCgAAK4oAACyKAAAsygAAK8oAACuKAAAsygAAK4oAACxKAAA8xAAALQoAACsKAAA8xAAAKwoAAC1KAAAtCgAALYoAACtKAAAtCgAAK0oAACsKAAAtSgAAKwoAACvKAAAtSgAAK8oAAC3KAAAVREAAKkoAACwKAAAVREAALAoAAC4KAAAqSgAAKgoAACxKAAAqSgAALEoAACwKAAAuCgAALAoAACyKAAAuCgAALIoAAC5KAAA8hEAAPARAACzKAAA8hEAALMoAAC6KAAA8BEAAO8RAACvKAAA8BEAAK8oAACzKAAAuigAALMoAACxKAAAuigAALEoAACoKAAAuygAALwoAAC9KAAAuygAAL0oAAC+KAAAvygAAMAoAAC9KAAAvygAAL0oAADBKAAAwigAAL4oAAC9KAAAwigAAL0oAADAKAAA8xAAAMMoAAC7KAAA8xAAALsoAAC0KAAAwygAAMQoAAC8KAAAwygAALwoAAC7KAAAtCgAALsoAAC+KAAAtCgAAL4oAAC2KAAATBAAAFgRAAC/KAAATBAAAL8oAADFKAAAWBEAAFcRAADAKAAAWBEAAMAoAAC/KAAAxSgAAL8oAADBKAAAxSgAAMEoAADGKAAAVREAAMcoAADCKAAAVREAAMIoAABWEQAAxygAALkoAAC+KAAAxygAAL4oAADCKAAAVhEAAMIoAADAKAAAVhEAAMAoAABXEQAAyCgAAMkoAADKKAAAyCgAAMooAADLKAAAzCgAAM0oAADKKAAAzCgAAMooAADOKAAAzygAANAoAADKKAAAzygAAMooAADRKAAA/g8AANIoAADIKAAA/g8AAMgoAADTKAAA0igAANQoAADJKAAA0igAAMkoAADIKAAA0ygAAMgoAADLKAAA0ygAAMsoAADwEAAATBAAANUoAADMKAAATBAAAMwoAADWKAAA1SgAANcoAADNKAAA1SgAAM0oAADMKAAA1igAAMwoAADOKAAA1igAAM4oAADUKAAA8xAAAPEQAADPKAAA8xAAAM8oAADYKAAA8RAAAPAQAADQKAAA8RAAANAoAADPKAAA2CgAAM8oAADRKAAA2CgAANEoAADEKAAA2SgAANooAADbKAAA2SgAANsoAADcKAAA3SgAAN4oAADbKAAA3SgAANsoAADaKAAA3ygAAOAoAADbKAAA3ygAANsoAADhKAAA/g8AAOIoAADZKAAA/g8AANkoAADSKAAA4igAAOMoAADaKAAA4igAANooAADZKAAA0igAANkoAADcKAAA0igAANwoAADUKAAAXA8AAE8QAADdKAAAXA8AAN0oAADkKAAATxAAAE4QAADeKAAATxAAAN4oAADdKAAA5CgAAN0oAADaKAAA5CgAANooAADlKAAATBAAANYoAADfKAAATBAAAN8oAABNEAAA1igAANQoAADgKAAA1igAAOAoAADfKAAATRAAAN8oAADhKAAATRAAAOEoAADmKAAA5ygAAOgoAADpKAAA5ygAAOkoAADqKAAA6ygAAOwoAADpKAAA6ygAAOkoAADoKAAA7SgAAO4oAADpKAAA7SgAAOkoAADsKAAAEw8AAO8oAADnKAAAEw8AAOcoAAD6DwAA7ygAAPAoAADoKAAA7ygAAOgoAADnKAAA+g8AAOcoAADqKAAA+g8AAOooAAD7DwAAXA8AAOQoAADrKAAAXA8AAOsoAADxKAAA5CgAAOMoAADsKAAA5CgAAOwoAADrKAAA8SgAAOsoAADoKAAA8SgAAOgoAADyKAAA/g8AAPwPAADtKAAA/g8AAO0oAADiKAAA/A8AAPsPAADuKAAA/A8AAO4oAADtKAAA4igAAO0oAADsKAAA4igAAOwoAADjKAAA8ygAAPQoAAD1KAAA8ygAAPUoAAD2KAAA9ygAAPgoAAD1KAAA9ygAAPUoAAD0KAAA+SgAAPYoAAD1KAAA+SgAAPUoAAD4KAAAEw8AAPooAADzKAAAEw8AAPMoAAD7KAAA+igAAPwoAAD0KAAA+igAAPQoAADzKAAA+ygAAPMoAAD2KAAA+ygAAPYoAAD9KAAASQ4AAF8PAAD3KAAASQ4AAPcoAAD+KAAAXw8AAF4PAAD4KAAAXw8AAPgoAAD3KAAA/igAAPcoAAD0KAAA/igAAPQoAAD8KAAAXA8AAPEoAAD5KAAAXA8AAPkoAAD/KAAA8SgAAAApAAD2KAAA8SgAAPYoAAD5KAAA/ygAAPkoAAD4KAAA/ygAAPgoAABeDwAAASkAAAIpAAADKQAAASkAAAMpAAAEKQAABSkAAAYpAAADKQAABSkAAAMpAAACKQAABykAAAgpAAADKQAABykAAAMpAAAJKQAA+w0AAAopAAABKQAA+w0AAAEpAAAPDwAACikAAAspAAACKQAACikAAAIpAAABKQAADw8AAAEpAAAEKQAADw8AAAQpAAAQDwAASQ4AAAwpAAAFKQAASQ4AAAUpAAANKQAADCkAAA4pAAAGKQAADCkAAAYpAAAFKQAADSkAAAUpAAACKQAADSkAAAIpAAAPKQAAEw8AABEPAAAHKQAAEw8AAAcpAAD6KAAAEQ8AABAPAAAIKQAAEQ8AAAgpAAAHKQAA+igAAAcpAAAJKQAA+igAAAkpAAD8KAAAECkAABEpAAASKQAAECkAABIpAAATKQAAFCkAABUpAAASKQAAFCkAABIpAAARKQAAFikAABMpAAASKQAAFikAABIpAAAVKQAA+w0AABcpAAAQKQAA+w0AABApAAAKKQAAFykAABgpAAARKQAAFykAABEpAAAQKQAACikAABApAAATKQAACikAABMpAAALKQAALA0AAEwOAAAUKQAALA0AABQpAAAZKQAATA4AAEsOAAAVKQAATA4AABUpAAAUKQAAGSkAABQpAAARKQAAGSkAABEpAAAaKQAASQ4AAA0pAAAWKQAASQ4AABYpAAAbKQAADSkAAA8pAAATKQAADSkAABMpAAAWKQAAGykAABYpAAAVKQAAGykAABUpAAAcKQAAHSkAAB4pAAAfKQAAHSkAAB8pAAAgKQAAISkAACIpAAAfKQAAISkAAB8pAAAjKQAAJCkAACApAAAfKQAAJCkAAB8pAAAiKQAAtgwAACUpAAAdKQAAtgwAAB0pAAAmKQAAJSkAACcpAAAeKQAAJSkAAB4pAAAdKQAAJikAAB0pAAAgKQAAJikAACApAAD4DQAALA0AABkpAAAhKQAALA0AACEpAAAoKQAAGSkAACkpAAAiKQAAGSkAACIpAAAhKQAAKCkAACEpAAAjKQAAKCkAACMpAAAqKQAA+w0AAPkNAAAkKQAA+w0AACQpAAAXKQAA+Q0AAPgNAAAgKQAA+Q0AACApAAAkKQAAFykAACQpAAAiKQAAFykAACIpAAAaKQAAKykAACwpAAAtKQAAKykAAC0pAAAuKQAALykAADApAAAtKQAALykAAC0pAAAsKQAAMSkAAC4pAAAtKQAAMSkAAC0pAAAwKQAAtgwAADIpAAArKQAAtgwAACspAAAzKQAAMikAADQpAAAsKQAAMikAACwpAAArKQAAMykAACspAAAuKQAAMykAAC4pAAAqKQAAAgwAAC8NAAAvKQAAAgwAAC8pAAA1KQAALw0AAC4NAAAwKQAALw0AADApAAAvKQAANSkAAC8pAAAsKQAANSkAACwpAAA2KQAALA0AACgpAAAxKQAALA0AADEpAAAtDQAAKCkAACopAAAuKQAAKCkAAC4pAAAxKQAALQ0AADEpAAAwKQAALQ0AADApAAAuDQAANykAADgpAAA5KQAANykAADkpAAA6KQAAOykAADwpAAA5KQAAOykAADkpAAA4KQAAPSkAADopAAA5KQAAPSkAADkpAAA8KQAAvAsAAD4pAAA3KQAAvAsAADcpAACyDAAAPikAAD8pAAA4KQAAPikAADgpAAA3KQAAsgwAADcpAAA6KQAAsgwAADopAACzDAAAAgwAADUpAAA7KQAAAgwAADspAABAKQAANSkAADYpAAA8KQAANSkAADwpAAA7KQAAQCkAADspAAA4KQAAQCkAADgpAABBKQAAtgwAALQMAAA9KQAAtgwAAD0pAABCKQAAtAwAALMMAAA6KQAAtAwAADopAAA9KQAAQikAAD0pAAA8KQAAQikAADwpAAA0KQAAQykAAEQpAABFKQAAQykAAEUpAABGKQAARykAAEgpAABFKQAARykAAEUpAABEKQAASSkAAEopAABFKQAASSkAAEUpAABIKQAAvAsAAEspAABDKQAAvAsAAEMpAAA+KQAASykAAEwpAABEKQAASykAAEQpAABDKQAAPikAAEMpAABGKQAAPikAAEYpAAA/KQAABwwAAAUMAABHKQAABwwAAEcpAABNKQAABQwAAAQMAABIKQAABQwAAEgpAABHKQAATSkAAEcpAABEKQAATSkAAEQpAABMKQAAAgwAAE4pAABJKQAAAgwAAEkpAABPKQAATikAAEEpAABKKQAATikAAEopAABJKQAATykAAEkpAABIKQAATykAAEgpAABQKQAAUSkAAFIpAABTKQAAUSkAAFMpAABUKQAAVSkAAFYpAABTKQAAVSkAAFMpAABXKQAAWCkAAFkpAABTKQAAWCkAAFMpAABaKQAAtwsAAFspAABRKQAAtwsAAFEpAABcKQAAWykAAF0pAABSKQAAWykAAFIpAABRKQAAXCkAAFEpAABUKQAAXCkAAFQpAABeKQAABwwAAE0pAABVKQAABwwAAFUpAABfKQAATSkAAGApAABWKQAATSkAAFYpAABVKQAAXykAAFUpAABXKQAAXykAAFcpAABhKQAAvAsAALoLAABYKQAAvAsAAFgpAABLKQAAugsAALkLAABZKQAAugsAAFkpAABYKQAASykAAFgpAABaKQAASykAAFopAABMKQAAYikAAGMpAABkKQAAYikAAGQpAABlKQAAZikAAGcpAABkKQAAZikAAGQpAABoKQAAaSkAAGUpAABkKQAAaSkAAGQpAABnKQAAtwsAAGopAABiKQAAtwsAAGIpAABbKQAAaikAAGspAABjKQAAaikAAGMpAABiKQAAWykAAGIpAABlKQAAWykAAGUpAABsKQAAjBYAAE0XAABmKQAAjBYAAGYpAABtKQAATRcAAEwXAABnKQAATRcAAGcpAABmKQAAbSkAAGYpAABoKQAAbSkAAGgpAABrKQAABwwAAF8pAABpKQAABwwAAGkpAABuKQAAXykAAGEpAABlKQAAXykAAGUpAABpKQAAbikAAGkpAABnKQAAbikAAGcpAABMFwAAbykAAHApAABxKQAAbykAAHEpAAByKQAAcykAAHQpAABxKQAAcykAAHEpAAB1KQAAdikAAHcpAABxKQAAdikAAHEpAAB4KQAAUhYAAHkpAABvKQAAUhYAAG8pAAB6KQAAeSkAAHspAABwKQAAeSkAAHApAABvKQAAeikAAG8pAAByKQAAeikAAHIpAAB8KQAAjBYAAG0pAABzKQAAjBYAAHMpAAB9KQAAbSkAAGspAAB0KQAAbSkAAHQpAABzKQAAfSkAAHMpAAB1KQAAfSkAAHUpAAB7KQAAtwsAABEXAAB2KQAAtwsAAHYpAABqKQAAERcAABAXAAB3KQAAERcAAHcpAAB2KQAAaikAAHYpAAB4KQAAaikAAHgpAAB+KQAAfykAAIApAACBKQAAfykAAIEpAACCKQAAgykAAIQpAACBKQAAgykAAIEpAACAKQAAhSkAAIIpAACBKQAAhSkAAIEpAACEKQAAUhYAAIYpAAB/KQAAUhYAAH8pAACHKQAAhikAAIgpAACAKQAAhikAAIApAAB/KQAAhykAAH8pAACCKQAAhykAAIIpAAB7KQAAsBUAAI8WAACDKQAAsBUAAIMpAACJKQAAjxYAAI4WAACEKQAAjxYAAIQpAACDKQAAiSkAAIMpAACAKQAAiSkAAIApAACIKQAAjBYAAIopAACFKQAAjBYAAIUpAACNFgAAiikAAIspAACCKQAAiikAAIIpAACFKQAAjRYAAIUpAACEKQAAjRYAAIQpAACMKQAAjSkAAI4pAACPKQAAjSkAAI8pAACQKQAAkSkAAJIpAACPKQAAkSkAAI8pAACOKQAAkykAAJApAACPKQAAkykAAI8pAACSKQAAYhUAAJQpAACNKQAAYhUAAI0pAABOFgAAlCkAAJUpAACOKQAAlCkAAI4pAACNKQAAThYAAI0pAACQKQAAThYAAJApAACWKQAAsBUAAIkpAACRKQAAsBUAAJEpAACXKQAAiSkAAIgpAACSKQAAiSkAAJIpAACRKQAAlykAAJEpAACOKQAAlykAAI4pAACYKQAAUhYAAFAWAACTKQAAUhYAAJMpAACZKQAAUBYAAE8WAACQKQAAUBYAAJApAACTKQAAmSkAAJMpAACSKQAAmSkAAJIpAACaKQAAmykAAJwpAACdKQAAmykAAJ0pAACeKQAAnykAAKApAACdKQAAnykAAJ0pAAChKQAAoikAAKMpAACdKQAAoikAAJ0pAACgKQAAYhUAAKQpAACbKQAAYhUAAJspAACUKQAApCkAAKUpAACcKQAApCkAAJwpAACbKQAAlCkAAJspAACeKQAAlCkAAJ4pAACmKQAAwBQAALMVAACfKQAAwBQAAJ8pAACnKQAAsxUAALIVAACgKQAAsxUAAKApAACfKQAApykAAJ8pAAChKQAApykAAKEpAAClKQAAsBUAAKgpAACiKQAAsBUAAKIpAACpKQAAqCkAAKYpAACjKQAAqCkAAKMpAACiKQAAqSkAAKIpAACgKQAAqSkAAKApAACqKQAAqykAAKwpAACtKQAAqykAAK0pAACuKQAArykAALApAACtKQAArykAAK0pAACxKQAAsikAAK4pAACtKQAAsikAAK0pAACzKQAAXhQAALQpAACrKQAAXhQAAKspAABeFQAAtCkAALUpAACsKQAAtCkAAKwpAACrKQAAXhUAAKspAACuKQAAXhUAAK4pAABfFQAAwBQAAKcpAACvKQAAwBQAAK8pAAC2KQAApykAALcpAACwKQAApykAALApAACvKQAAtikAAK8pAACxKQAAtikAALEpAAC1KQAAYhUAAGAVAACyKQAAYhUAALIpAAC4KQAAYBUAAF8VAACuKQAAYBUAAK4pAACyKQAAuCkAALIpAACzKQAAuCkAALMpAAC5KQAAuikAALspAAC8KQAAuikAALwpAAC9KQAAvikAAL8pAAC8KQAAvikAALwpAADAKQAAwSkAAMIpAAC8KQAAwSkAALwpAAC/KQAAXhQAAMMpAAC6KQAAXhQAALopAAC0KQAAwykAAMQpAAC7KQAAwykAALspAAC6KQAAtCkAALopAAC9KQAAtCkAAL0pAADFKQAA0BMAAMMUAAC+KQAA0BMAAL4pAADGKQAAwxQAAMIUAAC/KQAAwxQAAL8pAAC+KQAAxikAAL4pAADAKQAAxikAAMApAADEKQAAwBQAAMcpAADBKQAAwBQAAMEpAADIKQAAxykAALUpAADCKQAAxykAAMIpAADBKQAAyCkAAMEpAAC/KQAAyCkAAL8pAADJKQAAyikAAMspAADMKQAAyikAAMwpAADNKQAAzikAAM8pAADMKQAAzikAAMwpAADQKQAA0SkAANIpAADMKQAA0SkAAMwpAADTKQAAghMAANQpAADKKQAAghMAAMopAADVKQAA1CkAANYpAADLKQAA1CkAAMspAADKKQAA1SkAAMopAADNKQAA1SkAAM0pAABbFAAA0BMAAMYpAADOKQAA0BMAAM4pAADXKQAAxikAANgpAADPKQAAxikAAM8pAADOKQAA1ykAAM4pAADQKQAA1ykAANApAADWKQAAXhQAAFwUAADRKQAAXhQAANEpAADZKQAAXBQAAFsUAADSKQAAXBQAANIpAADRKQAA2SkAANEpAADTKQAA2SkAANMpAADEKQAA2ikAANspAADcKQAA2ikAANwpAADdKQAA3ikAAN8pAADcKQAA3ikAANwpAADgKQAA4SkAAOIpAADcKQAA4SkAANwpAADjKQAAghMAAOQpAADaKQAAghMAANopAADUKQAA5CkAAOUpAADbKQAA5CkAANspAADaKQAA1CkAANopAADdKQAA1CkAAN0pAADWKQAA4BIAANMTAADeKQAA4BIAAN4pAADmKQAA0xMAANITAADfKQAA0xMAAN8pAADeKQAA5ikAAN4pAADgKQAA5ikAAOApAADnKQAA0BMAAOgpAADhKQAA0BMAAOEpAADpKQAA6CkAANYpAADiKQAA6CkAAOIpAADhKQAA6SkAAOEpAADjKQAA6SkAAOMpAADSEwAA6ikAAOspAADsKQAA6ikAAOwpAADtKQAA7ikAAO8pAADsKQAA7ikAAOwpAADwKQAA8SkAAPIpAADsKQAA8SkAAOwpAADzKQAAphIAAPQpAADqKQAAphIAAOopAAB+EwAA9CkAAPUpAADrKQAA9CkAAOspAADqKQAAfhMAAOopAADtKQAAfhMAAO0pAAB/EwAA4BIAAOYpAADuKQAA4BIAAO4pAAD2KQAA5ikAAOUpAADvKQAA5ikAAO8pAADuKQAA9ikAAO4pAADwKQAA9ikAAPApAAD3KQAAghMAAIATAADxKQAAghMAAPEpAADkKQAAgBMAAH8TAADyKQAAgBMAAPIpAADxKQAA5CkAAPEpAADzKQAA5CkAAPMpAADlKQAA+CkAAPkpAAD6KQAA+CkAAPopAAD7KQAA/CkAAP0pAAD6KQAA/CkAAPopAAD+KQAA/ykAAPspAAD6KQAA/ykAAPopAAAAKgAAphIAAAEqAAD4KQAAphIAAPgpAAD0KQAAASoAAAIqAAD5KQAAASoAAPkpAAD4KQAA9CkAAPgpAAD7KQAA9CkAAPspAAADKgAAGBIAAOMSAAD8KQAAGBIAAPwpAAAEKgAA4xIAAOISAAD9KQAA4xIAAP0pAAD8KQAABCoAAPwpAAD+KQAABCoAAP4pAAAFKgAA4BIAAPYpAAD/KQAA4BIAAP8pAAAGKgAA9ikAAPcpAAD7KQAA9ikAAPspAAD/KQAABioAAP8pAAAAKgAABioAAAAqAAAHKgAACCoAAAkqAAAKKgAACCoAAAoqAAALKgAADCoAAA0qAAAKKgAADCoAAAoqAAAJKgAADioAAAsqAAAKKgAADioAAAoqAAANKgAApxEAAA8qAAAIKgAApxEAAAgqAACiEgAADyoAABAqAAAJKgAADyoAAAkqAAAIKgAAohIAAAgqAAALKgAAohIAAAsqAACjEgAAGBIAAAQqAAAMKgAAGBIAAAwqAAARKgAABCoAAAIqAAANKgAABCoAAA0qAAAMKgAAESoAAAwqAAAJKgAAESoAAAkqAAASKgAAphIAAKQSAAAOKgAAphIAAA4qAAABKgAApBIAAKMSAAALKgAApBIAAAsqAAAOKgAAASoAAA4qAAANKgAAASoAAA0qAAACKgAAEyoAABQqAAAVKgAAEyoAABUqAAAWKgAAFyoAABgqAAAVKgAAFyoAABUqAAAUKgAAGSoAABoqAAAVKgAAGSoAABUqAAAbKgAApxEAABwqAAATKgAApxEAABMqAAAPKgAAHCoAAB0qAAAUKgAAHCoAABQqAAATKgAADyoAABMqAAAWKgAADyoAABYqAAAQKgAAGREAABsSAAAXKgAAGREAABcqAAAeKgAAGxIAABoSAAAYKgAAGxIAABgqAAAXKgAAHioAABcqAAAUKgAAHioAABQqAAAfKgAAGBIAABEqAAAZKgAAGBIAABkqAAAgKgAAESoAACEqAAAaKgAAESoAABoqAAAZKgAAICoAABkqAAAbKgAAICoAABsqAAAaEgAAIioAACMqAAAkKgAAIioAACQqAAAlKgAAJioAACcqAAAkKgAAJioAACQqAAAoKgAAKSoAACUqAAAkKgAAKSoAACQqAAAnKgAAtxAAACoqAAAiKgAAtxAAACIqAAArKgAAKioAACwqAAAjKgAAKioAACMqAAAiKgAAKyoAACIqAAAlKgAAKyoAACUqAACkEQAAGREAAC0qAAAmKgAAGREAACYqAAAuKgAALSoAAB8qAAAnKgAALSoAACcqAAAmKgAALioAACYqAAAoKgAALioAACgqAAAvKgAApxEAAKURAAApKgAApxEAACkqAAAcKgAApREAAKQRAAAlKgAApREAACUqAAApKgAAHCoAACkqAAAnKgAAHCoAACcqAAAfKgAAMCoAADEqAAAyKgAAMCoAADIqAAAzKgAANCoAADUqAAAyKgAANCoAADIqAAAxKgAANioAADMqAAAyKgAANioAADIqAAA1KgAAtxAAADcqAAAwKgAAtxAAADAqAAA4KgAANyoAADkqAAAxKgAANyoAADEqAAAwKgAAOCoAADAqAAAzKgAAOCoAADMqAAAsKgAAJBAAABwRAAA0KgAAJBAAADQqAAA6KgAAHBEAABsRAAA1KgAAHBEAADUqAAA0KgAAOioAADQqAAAxKgAAOioAADEqAAA7KgAAGREAAC4qAAA2KgAAGREAADYqAAA8KgAALioAACwqAAAzKgAALioAADMqAAA2KgAAPCoAADYqAAA1KgAAPCoAADUqAAA9KgAAPioAAD8qAABAKgAAPioAAEAqAABBKgAAQioAAEMqAABAKgAAQioAAEAqAAA/KgAARCoAAEEqAABAKgAARCoAAEAqAABFKgAA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ngsAAAIXAAD9KgAAngsAAP0qAAAEKwAAAhcAAAEXAAD6KgAAAhcAAPoqAAD9KgAABCsAAP0qAAD+KgAABCsAAP4qAAD0KgAABSsAAAYrAAAHKwAABSsAAAcrAAAIKwAACSsAAAorAAAHKwAACSsAAAcrAAAGKwAACysAAAgrAAAHKwAACysAAAcrAAAMKwAALxYAAA0rAAAFKwAALxYAAAUrAAAOKwAADSsAAA8rAAAGKwAADSsAAAYrAAAFKwAADisAAAUrAAAIKwAADisAAAgrAAAQKwAAdBUAAGcWAAAJKwAAdBUAAAkrAAARKwAAZxYAAGYWAAAKKwAAZxYAAAorAAAJKwAAESsAAAkrAAAGKwAAESsAAAYrAAAPKwAAZBYAAAIrAAALKwAAZBYAAAsrAAASKwAAAisAABArAAAIKwAAAisAAAgrAAALKwAAEisAAAsrAAAMKwAAEisAAAwrAABmFgAAEysAABQrAAAVKwAAEysAABUrAAAWKwAAFysAABgrAAAVKwAAFysAABUrAAAZKwAAGisAABsrAAAVKwAAGisAABUrAAAYKwAAThUAABwrAAATKwAAThUAABMrAAArFgAAHCsAAB0rAAAUKwAAHCsAABQrAAATKwAAKxYAABMrAAAWKwAAKxYAABYrAAAsFgAAdBUAABErAAAXKwAAdBUAABcrAAAeKwAAESsAAB8rAAAYKwAAESsAABgrAAAXKwAAHisAABcrAAAZKwAAHisAABkrAAAgKwAALxYAAC0WAAAaKwAALxYAABorAAANKwAALRYAACwWAAAbKwAALRYAABsrAAAaKwAADSsAABorAAAYKwAADSsAABgrAAAPKwAAISsAACIrAAAjKwAAISsAACMrAAAkKwAAJSsAACYrAAAjKwAAJSsAACMrAAAiKwAAJysAACQrAAAjKwAAJysAACMrAAAmKwAAThUAACgrAAAhKwAAThUAACErAAApKwAAKCsAACorAAAiKwAAKCsAACIrAAAhKwAAKSsAACErAAAkKwAAKSsAACQrAAAgKwAAhBQAAHcVAAAlKwAAhBQAACUrAAArKwAAdxUAAHYVAAAmKwAAdxUAACYrAAAlKwAAKysAACUrAAAiKwAAKysAACIrAAAsKwAAdBUAAC0rAAAnKwAAdBUAACcrAAAuKwAALSsAACArAAAkKwAALSsAACQrAAAnKwAALisAACcrAAAmKwAALisAACYrAAB2FQAALysAADArAAAxKwAALysAADErAAAyKwAAMysAADQrAAAxKwAAMysAADErAAAwKwAANSsAADYrAAAxKwAANSsAADErAAA0KwAAShQAADcrAAAvKwAAShQAAC8rAAA4KwAANysAADkrAAAwKwAANysAADArAAAvKwAAOCsAAC8rAAAyKwAAOCsAADIrAAA6KwAAhBQAADsrAAAzKwAAhBQAADMrAAA8KwAAOysAACorAAA0KwAAOysAADQrAAAzKwAAPCsAADMrAAAwKwAAPCsAADArAAA5KwAAThUAAEwVAAA1KwAAThUAADUrAAAoKwAATBUAAEsVAAA2KwAATBUAADYrAAA1KwAAKCsAADUrAAA0KwAAKCsAADQrAAA9KwAAPisAAD8rAABAKwAAPisAAEArAABBKwAAQisAAEMrAABAKwAAQisAAEArAAA/KwAARCsAAEErAABAKwAARCsAAEArAABFKwAAShQAAEYrAAA+KwAAShQAAD4rAABHKwAARisAAEgrAAA/KwAARisAAD8rAAA+KwAARysAAD4rAABBKwAARysAAEErAAA5KwAAlBMAAIcUAABCKwAAlBMAAEIrAABJKwAAhxQAAIYUAABDKwAAhxQAAEMrAABCKwAASSsAAEIrAAA/KwAASSsAAD8rAABIKwAAhBQAAEorAABEKwAAhBQAAEQrAABLKwAASisAADkrAABBKwAASisAAEErAABEKwAASysAAEQrAABFKwAASysAAEUrAACGFAAATCsAAE0rAABOKwAATCsAAE4rAABPKwAAUCsAAFErAABOKwAAUCsAAE4rAABNKwAAUisAAE8rAABOKwAAUisAAE4rAABTKwAAbhMAAFQrAABMKwAAbhMAAEwrAABVKwAAVCsAAFYrAABNKwAAVCsAAE0rAABMKwAAVSsAAEwrAABPKwAAVSsAAE8rAABHFAAAlBMAAEkrAABQKwAAlBMAAFArAABXKwAASSsAAEgrAABRKwAASSsAAFErAABQKwAAVysAAFArAABNKwAAVysAAE0rAABYKwAAShQAAEgUAABSKwAAShQAAFIrAABGKwAASBQAAEcUAABPKwAASBQAAE8rAABSKwAARisAAFIrAABTKwAARisAAFMrAABIKwAAWSsAAForAABbKwAAWSsAAFsrAABcKwAAXSsAAF4rAABbKwAAXSsAAFsrAABaKwAAXysAAGArAABbKwAAXysAAFsrAABhKwAAbhMAAGIrAABZKwAAbhMAAFkrAABjKwAAYisAAGQrAABaKwAAYisAAForAABZKwAAYysAAFkrAABcKwAAYysAAFwrAABWKwAAuBIAAJcTAABdKwAAuBIAAF0rAABlKwAAlxMAAJYTAABeKwAAlxMAAF4rAABdKwAAZSsAAF0rAABaKwAAZSsAAForAABmKwAAlBMAAGcrAABfKwAAlBMAAF8rAACVEwAAZysAAGgrAABgKwAAZysAAGArAABfKwAAlRMAAF8rAABhKwAAlRMAAGErAABpKwAAaisAAGsrAABsKwAAaisAAGwrAABtKwAAbisAAG8rAABsKwAAbisAAGwrAABrKwAAcCsAAHErAABsKwAAcCsAAGwrAAByKwAANw4AAHMrAABqKwAANw4AAGorAAB0KwAAcysAAHUrAABrKwAAcysAAGsrAABqKwAAdCsAAGorAABtKwAAdCsAAG0rAAB2KwAAuBIAAGUrAABuKwAAuBIAAG4rAAB3KwAAZSsAAGYrAABvKwAAZSsAAG8rAABuKwAAdysAAG4rAABrKwAAdysAAGsrAAB1KwAAbhMAAGwTAABwKwAAbhMAAHArAABiKwAAbBMAAGsTAABxKwAAbBMAAHErAABwKwAAYisAAHArAAByKwAAYisAAHIrAABkKwAAeCsAAHkrAAB6KwAAeCsAAHorAAB7KwAAfCsAAH0rAAB6KwAAfCsAAHorAAB5KwAAfisAAHsrAAB6KwAAfisAAHorAAB9KwAANw4AAH8rAAB4KwAANw4AAHgrAABzKwAAfysAAIArAAB5KwAAfysAAHkrAAB4KwAAcysAAHgrAAB7KwAAcysAAHsrAACBKwAAgisAALsSAAB8KwAAgisAAHwrAACDKwAAuxIAALoSAAB9KwAAuxIAAH0rAAB8KwAAgysAAHwrAAB5KwAAgysAAHkrAACEKwAAuBIAAHcrAAB+KwAAuBIAAH4rAAC5EgAAdysAAIErAAB7KwAAdysAAHsrAAB+KwAAuRIAAH4rAAB9KwAAuRIAAH0rAACFKwAAhisAAIcrAACIKwAAhisAAIgrAACJKwAAiisAAIsrAACIKwAAiisAAIgrAACMKwAAjSsAAI4rAACIKwAAjSsAAIgrAACLKwAANw4AAI8rAACGKwAANw4AAIYrAACQKwAAjysAAJErAACHKwAAjysAAIcrAACGKwAAkCsAAIYrAACJKwAAkCsAAIkrAACAKwAAkisAAJMrAACKKwAAkisAAIorAACUKwAAkysAAFYSAACLKwAAkysAAIsrAACKKwAAlCsAAIorAACMKwAAlCsAAIwrAACVKwAAgisAAIMrAACNKwAAgisAAI0rAACWKwAAgysAAIQrAACOKwAAgysAAI4rAACNKwAAlisAAI0rAACLKwAAlisAAIsrAACXKwAAmCsAAJkrAACaKwAAmCsAAJorAACbKwAAnCsAAJ0rAACaKwAAnCsAAJorAACZKwAAnisAAJsrAACaKwAAnisAAJorAACdKwAANw4AAJ8rAACYKwAANw4AAJgrAACgKwAAnysAAKErAACZKwAAnysAAJkrAACYKwAAoCsAAJgrAACbKwAAoCsAAJsrAACiKwAAfREAAN8RAACcKwAAfREAAJwrAACjKwAA3xEAAN4RAACdKwAA3xEAAJ0rAACcKwAAoysAAJwrAACZKwAAoysAAJkrAAChKwAAkisAAJQrAACeKwAAkisAAJ4rAADdEQAAlCsAAKIrAACbKwAAlCsAAJsrAACeKwAA3REAAJ4rAACdKwAA3REAAJ0rAADeEQAApCsAAKUrAACmKwAApCsAAKYrAACnKwAAqCsAAKkrAACmKwAAqCsAAKYrAAClKwAAqisAAKcrAACmKwAAqisAAKYrAACpKwAANw4AAKsrAACkKwAANw4AAKQrAACfKwAAqysAAKwrAAClKwAAqysAAKUrAACkKwAAnysAAKQrAACnKwAAnysAAKcrAACtKwAArisAAK8rAACoKwAArisAAKgrAACwKwAArysAALErAACpKwAArysAAKkrAACoKwAAsCsAAKgrAAClKwAAsCsAAKUrAACsKwAAfREAAKMrAACqKwAAfREAAKorAACyKwAAoysAALMrAACnKwAAoysAAKcrAACqKwAAsisAAKorAACpKwAAsisAAKkrAACxKwAAtCsAALUrAAC2KwAAtCsAALYrAAC3KwAAuCsAALkrAAC2KwAAuCsAALYrAAC1KwAAuisAALcrAAC2KwAAuisAALYrAAC5KwAANw4AALsrAAC0KwAANw4AALQrAACrKwAAuysAALwrAAC1KwAAuysAALUrAAC0KwAAqysAALQrAAC3KwAAqysAALcrAAC9KwAAvisAAOAQAAC4KwAAvisAALgrAAC/KwAA4BAAAMArAAC5KwAA4BAAALkrAAC4KwAAvysAALgrAAC1KwAAvysAALUrAAC8KwAAwSsAAMIrAAC6KwAAwSsAALorAADeEAAAwisAAL0rAAC3KwAAwisAALcrAAC6KwAA3hAAALorAAC5KwAA3hAAALkrAADfEAAAwysAAMQrAADFKwAAwysAAMUrAADGKwAAxysAAMgrAADFKwAAxysAAMUrAADJKwAAyisAAMsrAADFKwAAyisAAMUrAADMKwAANw4AAM0rAADDKwAANw4AAMMrAADOKwAAzSsAAM8rAADEKwAAzSsAAMQrAADDKwAAzisAAMMrAADGKwAAzisAAMYrAADQKwAA0SsAAKQQAADHKwAA0SsAAMcrAADSKwAApBAAAKMQAADIKwAApBAAAMgrAADHKwAA0isAAMcrAADJKwAA0isAAMkrAADTKwAA1CsAANUrAADKKwAA1CsAAMorAACiEAAA1SsAALwrAADLKwAA1SsAAMsrAADKKwAAohAAAMorAADMKwAAohAAAMwrAADWKwAA1ysAANgrAADZKwAA1ysAANkrAADaKwAA2ysAANwrAADZKwAA2ysAANkrAADYKwAA3SsAANorAADZKwAA3SsAANkrAADeKwAANw4AAN8rAADXKwAANw4AANcrAADNKwAA3ysAAOArAADYKwAA3ysAANgrAADXKwAAzSsAANcrAADaKwAAzSsAANorAADTKwAA4SsAAOIrAADbKwAA4SsAANsrAADjKwAA4isAAOoPAADcKwAA4isAANwrAADbKwAA4ysAANsrAADYKwAA4ysAANgrAADkKwAA0SsAAOUrAADdKwAA0SsAAN0rAADpDwAA5SsAANMrAADaKwAA5SsAANorAADdKwAA6Q8AAN0rAADeKwAA6Q8AAN4rAADqDwAA5isAAOcrAADoKwAA5isAAOgrAADpKwAA6isAAOsrAADoKwAA6isAAOgrAADnKwAA7CsAAO0rAADoKwAA7CsAAOgrAADrKwAANw4AAO4rAADmKwAANw4AAOYrAADfKwAA7isAAO8rAADnKwAA7isAAOcrAADmKwAA3ysAAOYrAADpKwAA3ysAAOkrAADgKwAA8CsAAK8PAADqKwAA8CsAAOorAADxKwAArw8AAK4PAADrKwAArw8AAOsrAADqKwAA8SsAAOorAADnKwAA8SsAAOcrAADvKwAA8isAAOMrAADsKwAA8isAAOwrAACtDwAA4ysAAOArAADtKwAA4ysAAO0rAADsKwAArQ8AAOwrAADrKwAArQ8AAOsrAACuDwAA8ysAAPQrAAD1KwAA8ysAAPUrAAD2KwAA9ysAAPgrAAD1KwAA9ysAAPUrAAD5KwAA+isAAPsrAAD1KwAA+isAAPUrAAD4KwAANw4AAPwrAADzKwAANw4AAPMrAAD9KwAA/CsAAP4rAAD0KwAA/CsAAPQrAADzKwAA/SsAAPMrAAD2KwAA/SsAAPYrAAD/KwAAhQ4AAAAsAAD3KwAAhQ4AAPcrAAABLAAAACwAAAIsAAD4KwAAACwAAPgrAAD3KwAAASwAAPcrAAD5KwAAASwAAPkrAAD+KwAA8CsAAAMsAAD6KwAA8CsAAPorAAAELAAAAywAAP8rAAD7KwAAAywAAPsrAAD6KwAABCwAAPorAAD4KwAABCwAAPgrAAD/DgAABSwAAAYsAAAHLAAABSwAAAcsAAAILAAACSwAAAosAAAHLAAACSwAAAcsAAAGLAAACywAAAgsAAAHLAAACywAAAcsAAAKLAAANw4AAAwsAAAFLAAANw4AAAUsAAANLAAADCwAAA4sAAAGLAAADCwAAAYsAAAFLAAADSwAAAUsAAAILAAADSwAAAgsAAD+KwAA4g0AAA8sAAAJLAAA4g0AAAksAAAQLAAADywAABEsAAAKLAAADywAAAosAAAJLAAAECwAAAksAAAGLAAAECwAAAYsAAASLAAAEywAABQsAAALLAAAEywAAAssAAAVLAAAFCwAAP4rAAAILAAAFCwAAAgsAAALLAAAFSwAAAssAAAKLAAAFSwAAAosAAARLAAAFiwAABcsAAAYLAAAFiwAABgsAAAZLAAAGiwAABssAAAYLAAAGiwAABgsAAAXLAAAHCwAABksAAAYLAAAHCwAABgsAAAdLAAANw4AADUOAAAWLAAANw4AABYsAAAeLAAANQ4AADQOAAAXLAAANQ4AABcsAAAWLAAAHiwAABYsAAAZLAAAHiwAABksAAASLAAA5w0AAOUNAAAaLAAA5w0AABosAAAzDgAA5Q0AAB8sAAAbLAAA5Q0AABssAAAaLAAAMw4AABosAAAXLAAAMw4AABcsAAA0DgAA4g0AABAsAAAcLAAA4g0AABwsAAAgLAAAECwAABIsAAAZLAAAECwAABksAAAcLAAAICwAABwsAAAdLAAAICwAAB0sAAAhLAAAIiwAACMsAAAkLAAAIiwAACQsAAAlLAAAIywAACYsAAAnLAAAIywAACcsAAAkLAAAJSwAACQsAAAoLAAAJSwAACgsAAApLAAAJCwAACcsAAAqLAAAJCwAACosAAAoLAAAFwYAAEQGAAAiLAAAFwYAACIsAAArLAAARAYAAEIGAAAjLAAARAYAACMsAAAiLAAAQgYAACwsAAAmLAAAQgYAACYsAAAjLAAALCwAAD8GAAAtLAAALCwAAC0sAAAmLAAAJiwAAC0sAAAuLAAAJiwAAC4sAAAnLAAAJywAAC4sAAAvLAAAJywAAC8sAAAqLAAAKiwAAC8sAAAwLAAAKiwAADAsAAAxLAAAKCwAACosAAAxLAAAKCwAADEsAAAyLAAAKSwAACgsAAAyLAAAKSwAADIsAAAzLAAANCwAACksAAAzLAAANCwAADMsAAA1LAAANiwAACUsAAApLAAANiwAACksAAA0LAAAKywAACIsAAAlLAAAKywAACUsAAA2LAAANywAADgsAAA5LAAANywAADksAAA6LAAAOCwAADssAAA8LAAAOCwAADwsAAA5LAAAOiwAADksAAA9LAAAOiwAAD0sAAA+LAAAOSwAADwsAAA/LAAAOSwAAD8sAAA9LAAACwgAAA0IAAA3LAAACwgAADcsAABALAAADQgAAEEsAAA4LAAADQgAADgsAAA3LAAAQSwAAAgIAAA7LAAAQSwAADssAAA4LAAACAgAAOkHAABCLAAACAgAAEIsAAA7LAAAOywAAEIsAABDLAAAOywAAEMsAAA8LAAAPCwAAEMsAABELAAAPCwAAEQsAAA/LAAAPywAAEQsAABFLAAAPywAAEUsAABGLAAAPSwAAD8sAABGLAAAPSwAAEYsAABHLAAAPiwAAD0sAABHLAAAPiwAAEcsAABILAAASSwAAD4sAABILAAASSwAAEgsAABKLAAASywAADosAAA+LAAASywAAD4sAABJLAAAQCwAADcsAAA6LAAAQCwAADosAABLLAAATCwAAE0sAABOLAAATCwAAE4sAABPLAAATSwAAFAsAABRLAAATSwAAFEsAABOLAAATywAAE4sAABSLAAATywAAFIsAABTLAAATiwAAFEsAABULAAATiwAAFQsAABSLAAAhgAAALAAAABMLAAAhgAAAEwsAABVLAAAsAAAAK4AAABNLAAAsAAAAE0sAABMLAAArgAAAKwAAABQLAAArgAAAFAsAABNLAAArAAAAKsAAABWLAAArAAAAFYsAABQLAAAUCwAAFYsAABXLAAAUCwAAFcsAABRLAAAUSwAAFcsAABYLAAAUSwAAFgsAABULAAAVCwAAFgsAABZLAAAVCwAAFksAABaLAAAUiwAAFQsAABaLAAAUiwAAFosAABbLAAAUywAAFIsAABbLAAAUywAAFssAABcLAAAXSwAAFMsAABcLAAAXSwAAFwsAABeLAAAXywAAE8sAABTLAAAXywAAFMsAABdLAAAVSwAAEwsAABPLAAAVSwAAE8sAABfLAAAYCwAAGEsAABiLAAAYCwAAGIsAABjLAAAYSwAAGQsAABlLAAAYSwAAGUsAABiLAAAYywAAGIsAABmLAAAYywAAGYsAABnLAAAYiwAAGUsAABoLAAAYiwAAGgsAABmLAAAMgYAADQGAABgLAAAMgYAAGAsAABpLAAANAYAADAGAABhLAAANAYAAGEsAABgLAAAMAYAAC8GAABkLAAAMAYAAGQsAABhLAAALwYAAK0FAABqLAAALwYAAGosAABkLAAAZCwAAGosAABrLAAAZCwAAGssAABlLAAAZSwAAGssAABsLAAAZSwAAGwsAABoLAAAaCwAAGwsAABtLAAAaCwAAG0sAABuLAAAZiwAAGgsAABuLAAAZiwAAG4sAABvLAAAZywAAGYsAABvLAAAZywAAG8sAABwLAAAcSwAAGcsAABwLAAAcSwAAHAsAAByLAAAcywAAGMsAABnLAAAcywAAGcsAABxLAAAaSwAAGAsAABjLAAAaSwAAGMsAABzLAAAdCwAAHUsAAB2LAAAdCwAAHYsAAB3LAAAdSwAAHgsAAB5LAAAdSwAAHksAAB2LAAAdywAAHYsAAB6LAAAdywAAHosAAB7LAAAdiwAAHksAAB8LAAAdiwAAHwsAAB6LAAAAgQAAFUEAAB0LAAAAgQAAHQsAAB9LAAAVQQAAFYEAAB1LAAAVQQAAHUsAAB0LAAAVgQAAH4sAAB4LAAAVgQAAHgsAAB1LAAAfiwAAE8EAAB/LAAAfiwAAH8sAAB4LAAAeCwAAH8sAACALAAAeCwAAIAsAAB5LAAAeSwAAIAsAACBLAAAeSwAAIEsAAB8LAAAfCwAAIEsAACCLAAAfCwAAIIsAACDLAAAeiwAAHwsAACDLAAAeiwAAIMsAACELAAAeywAAHosAACELAAAeywAAIQsAACFLAAAhiwAAHssAACFLAAAhiwAAIUsAACHLAAAiCwAAHcsAAB7LAAAiCwAAHssAACGLAAAfSwAAHQsAAB3LAAAfSwAAHcsAACILAAAiSwAAIosAACLLAAAiSwAAIssAACMLAAAiiwAAI0sAACOLAAAiiwAAI4sAACLLAAAjCwAAIssAACPLAAAjCwAAI8sAACQLAAAiywAAI4sAACRLAAAiywAAJEsAACPLAAAnwAAAKEAAACJLAAAnwAAAIksAACSLAAAoQAAAKMAAACKLAAAoQAAAIosAACJLAAAowAAAJ0AAACNLAAAowAAAI0sAACKLAAAnQAAAHsAAACTLAAAnQAAAJMsAACNLAAAjSwAAJMsAACULAAAjSwAAJQsAACOLAAAjiwAAJQsAACVLAAAjiwAAJUsAACRLAAAkSwAAJUsAACWLAAAkSwAAJYsAACXLAAAjywAAJEsAACXLAAAjywAAJcsAACYLAAAkCwAAI8sAACYLAAAkCwAAJgsAACZLAAAmiwAAJAsAACZLAAAmiwAAJksAACbLAAAnCwAAIwsAACQLAAAnCwAAJAsAACaLAAAkiwAAIksAACMLAAAkiwAAIwsAACcLAAAnSwAAJ4sAACfLAAAnSwAAJ8sAACgLAAAniwAAKEsAACiLAAAniwAAKIsAACfLAAAoCwAAJ8sAACjLAAAoCwAAKMsAACkLAAAnywAAKIsAAClLAAAnywAAKUsAACjLAAAQgQAAEQEAACdLAAAQgQAAJ0sAACmLAAARAQAAEYEAACeLAAARAQAAJ4sAACdLAAARgQAAKcsAAChLAAARgQAAKEsAACeLAAApywAANEDAACoLAAApywAAKgsAAChLAAAoSwAAKgsAACpLAAAoSwAAKksAACiLAAAoiwAAKksAACqLAAAoiwAAKosAAClLAAApSwAAKosAACrLAAApSwAAKssAACsLAAAoywAAKUsAACsLAAAoywAAKwsAACtLAAApCwAAKMsAACtLAAApCwAAK0sAACuLAAArywAAKQsAACuLAAArywAAK4sAACwLAAAsSwAAKAsAACkLAAAsSwAAKQsAACvLAAApiwAAJ0sAACgLAAApiwAAKAsAACxLAAAsiwAALMsAAC0LAAAsiwAALQsAAC1LAAAsywAALYsAAC3LAAAsywAALcsAAC0LAAAtSwAALQsAAC4LAAAtSwAALgsAAC5LAAAtCwAALcsAAC6LAAAtCwAALosAAC4LAAAogkAAMwJAACyLAAAogkAALIsAAC7LAAAzAkAALwsAACzLAAAzAkAALMsAACyLAAAvCwAAMgJAAC2LAAAvCwAALYsAACzLAAAyAkAAMcJAAC9LAAAyAkAAL0sAAC2LAAAtiwAAL0sAAC+LAAAtiwAAL4sAAC3LAAAtywAAL4sAAC/LAAAtywAAL8sAAC6LAAAuiwAAL8sAADALAAAuiwAAMAsAADBLAAAuCwAALosAADBLAAAuCwAAMEsAADCLAAAuSwAALgsAADCLAAAuSwAAMIsAADDLAAAxCwAALksAADDLAAAxCwAAMMsAADFLAAAxiwAALUsAAC5LAAAxiwAALksAADELAAAuywAALIsAAC1LAAAuywAALUsAADGLAAAxywAAMgsAADJLAAAxywAAMksAADKLAAAyCwAAMssAADMLAAAyCwAAMwsAADJLAAAyiwAAMksAADNLAAAyiwAAM0sAADOLAAAySwAAMwsAADPLAAAySwAAM8sAADNLAAA0gcAANAsAADHLAAA0gcAAMcsAADRLAAA0CwAAPoHAADILAAA0CwAAMgsAADHLAAA+gcAAPUHAADLLAAA+gcAAMssAADILAAA9QcAAPQHAADSLAAA9QcAANIsAADLLAAAyywAANIsAADTLAAAyywAANMsAADMLAAAzCwAANMsAADULAAAzCwAANQsAADPLAAAzywAANQsAADVLAAAzywAANUsAADWLAAAzSwAAM8sAADWLAAAzSwAANYsAADXLAAAziwAAM0sAADXLAAAziwAANcsAADYLAAA2SwAAM4sAADYLAAA2SwAANgsAADaLAAA2ywAAMosAADOLAAA2ywAAM4sAADZLAAA0SwAAMcsAADKLAAA0SwAAMosAADbLAAA3CwAAN0sAADeLAAA3CwAAN4sAADfLAAA3SwAAOAsAADhLAAA3SwAAOEsAADeLAAA3ywAAN4sAADiLAAA3ywAAOIsAADjLAAA3iwAAOEsAADkLAAA3iwAAOQsAADiLAAAuQkAAOUsAADcLAAAuQkAANwsAADmLAAA5SwAAL0JAADdLAAA5SwAAN0sAADcLAAAvQkAAOcsAADgLAAAvQkAAOAsAADdLAAA5ywAAJcJAADoLAAA5ywAAOgsAADgLAAA4CwAAOgsAADpLAAA4CwAAOksAADhLAAA4SwAAOksAADqLAAA4SwAAOosAADkLAAA5CwAAOosAADrLAAA5CwAAOssAADsLAAA4iwAAOQsAADsLAAA4iwAAOwsAADtLAAA4ywAAOIsAADtLAAA4ywAAO0sAADuLAAA7ywAAOMsAADuLAAA7ywAAO4sAADwLAAA8SwAAN8sAADjLAAA8SwAAOMsAADvLAAA5iwAANwsAADfLAAA5iwAAN8sAADxLAAA8iwAAPMsAAD0LAAA8iwAAPQsAAD1LAAA8ywAAPYsAAD3LAAA8ywAAPcsAAD0LAAA9SwAAPQsAAD4LAAA9SwAAPgsAAD5LAAA9CwAAPcsAAD6LAAA9CwAAPosAAD4LAAAUQUAABwGAADyLAAAUQUAAPIsAAD7LAAAHAYAAB4GAADzLAAAHAYAAPMsAADyLAAAHgYAAPwsAAD2LAAAHgYAAPYsAADzLAAA/CwAABcGAAArLAAA/CwAACssAAD2LAAA9iwAACssAAA2LAAA9iwAADYsAAD3LAAA9ywAADYsAAA0LAAA9ywAADQsAAD6LAAA+iwAADQsAAA1LAAA+iwAADUsAAD9LAAA+CwAAPosAAD9LAAA+CwAAP0sAAD+LAAA+SwAAPgsAAD+LAAA+SwAAP4sAAD/LAAAAC0AAPksAAD/LAAAAC0AAP8sAAABLQAAAi0AAPUsAAD5LAAAAi0AAPksAAAALQAA+ywAAPIsAAD1LAAA+ywAAPUsAAACLQAAAy0AAAQtAAAFLQAAAy0AAAUtAAAGLQAABC0AAActAAAILQAABC0AAAgtAAAFLQAABi0AAAUtAAAJLQAABi0AAAktAAAKLQAABS0AAAgtAAALLQAABS0AAAstAAAJLQAA6QcAAAwtAAADLQAA6QcAAAMtAABCLAAADC0AAOgHAAAELQAADC0AAAQtAAADLQAA6AcAAA0tAAAHLQAA6AcAAActAAAELQAADS0AAMYHAAAOLQAADS0AAA4tAAAHLQAABy0AAA4tAAAPLQAABy0AAA8tAAAILQAACC0AAA8tAAAQLQAACC0AABAtAAALLQAACy0AABAtAAARLQAACy0AABEtAAASLQAACS0AAAstAAASLQAACS0AABItAAATLQAACi0AAAktAAATLQAACi0AABMtAAAULQAARCwAAAotAAAULQAARCwAABQtAABFLAAAQywAAAYtAAAKLQAAQywAAAotAABELAAAQiwAAAMtAAAGLQAAQiwAAAYtAABDLAAAFS0AABYtAAAXLQAAFS0AABctAAAYLQAAFi0AABktAAAaLQAAFi0AABotAAAXLQAAGC0AABctAAAbLQAAGC0AABstAAAcLQAAFy0AABotAAAdLQAAFy0AAB0tAAAbLQAAYgAAAIwAAAAVLQAAYgAAABUtAAAeLQAAjAAAAI4AAAAWLQAAjAAAABYtAAAVLQAAjgAAAIcAAAAZLQAAjgAAABktAAAWLQAAhwAAAIYAAABVLAAAhwAAAFUsAAAZLQAAGS0AAFUsAABfLAAAGS0AAF8sAAAaLQAAGi0AAF8sAABdLAAAGi0AAF0sAAAdLQAAHS0AAF0sAABeLAAAHS0AAF4sAAAfLQAAGy0AAB0tAAAfLQAAGy0AAB8tAAAgLQAAHC0AABstAAAgLQAAHC0AACAtAAAhLQAAIi0AABwtAAAhLQAAIi0AACEtAAAjLQAAJC0AABgtAAAcLQAAJC0AABwtAAAiLQAAHi0AABUtAAAYLQAAHi0AABgtAAAkLQAAJS0AACYtAAAnLQAAJS0AACctAAAoLQAAJi0AACktAAAqLQAAJi0AACotAAAnLQAAKC0AACctAAArLQAAKC0AACstAAAsLQAAJy0AACotAAAtLQAAJy0AAC0tAAArLQAAewAAAH0AAAAlLQAAewAAACUtAACTLAAAfQAAAHoAAAAmLQAAfQAAACYtAAAlLQAAegAAAHgAAAApLQAAegAAACktAAAmLQAAeAAAAFYAAAAuLQAAeAAAAC4tAAApLQAAKS0AAC4tAAAvLQAAKS0AAC8tAAAqLQAAKi0AAC8tAAAwLQAAKi0AADAtAAAtLQAALS0AADAtAAAxLQAALS0AADEtAAAyLQAAKy0AAC0tAAAyLQAAKy0AADItAAAzLQAALC0AACstAAAzLQAALC0AADMtAAA0LQAAlSwAACwtAAA0LQAAlSwAADQtAACWLAAAlCwAACgtAAAsLQAAlCwAACwtAACVLAAAkywAACUtAAAoLQAAkywAACgtAACULAAANS0AADYtAAA3LQAANS0AADctAAA4LQAANi0AADktAAA6LQAANi0AADotAAA3LQAAOC0AADctAAA7LQAAOC0AADstAAA8LQAANy0AADotAAA9LQAANy0AAD0tAAA7LQAAgQkAAD4tAAA1LQAAgQkAADUtAAA/LQAAPi0AAKUJAAA2LQAAPi0AADYtAAA1LQAApQkAAKMJAAA5LQAApQkAADktAAA2LQAAowkAAKIJAAC7LAAAowkAALssAAA5LQAAOS0AALssAADGLAAAOS0AAMYsAAA6LQAAOi0AAMYsAADELAAAOi0AAMQsAAA9LQAAPS0AAMQsAADFLAAAPS0AAMUsAABALQAAOy0AAD0tAABALQAAOy0AAEAtAABBLQAAPC0AADstAABBLQAAPC0AAEEtAABCLQAAQy0AADwtAABCLQAAQy0AAEItAABELQAARS0AADgtAAA8LQAARS0AADwtAABDLQAAPy0AADUtAAA4LQAAPy0AADgtAABFLQAARi0AAEctAABILQAARi0AAEgtAABJLQAARy0AAEotAABLLQAARy0AAEstAABILQAASS0AAEgtAABMLQAASS0AAEwtAABNLQAASC0AAEstAABOLQAASC0AAE4tAABMLQAArwcAAE8tAABGLQAArwcAAEYtAABQLQAATy0AANUHAABHLQAATy0AAEctAABGLQAA1QcAAFEtAABKLQAA1QcAAEotAABHLQAAUS0AANIHAADRLAAAUS0AANEsAABKLQAASi0AANEsAADbLAAASi0AANssAABLLQAASy0AANssAADZLAAASy0AANksAABOLQAATi0AANksAADaLAAATi0AANosAABSLQAATC0AAE4tAABSLQAATC0AAFItAABTLQAATS0AAEwtAABTLQAATS0AAFMtAABULQAAVS0AAE0tAABULQAAVS0AAFQtAABWLQAAVy0AAEktAABNLQAAVy0AAE0tAABVLQAAUC0AAEYtAABJLQAAUC0AAEktAABXLQAAWC0AAFktAABaLQAAWC0AAFotAABbLQAAWS0AAFwtAABdLQAAWS0AAF0tAABaLQAAWy0AAFotAABeLQAAWy0AAF4tAABfLQAAWi0AAF0tAABgLQAAWi0AAGAtAABeLQAAlwkAAGEtAABYLQAAlwkAAFgtAADoLAAAYS0AAGItAABZLQAAYS0AAFktAABYLQAAYi0AAGMtAABcLQAAYi0AAFwtAABZLQAAYy0AAHUJAABkLQAAYy0AAGQtAABcLQAAXC0AAGQtAABlLQAAXC0AAGUtAABdLQAAXS0AAGUtAABmLQAAXS0AAGYtAABgLQAAYC0AAGYtAABnLQAAYC0AAGctAABoLQAAXi0AAGAtAABoLQAAXi0AAGgtAABpLQAAXy0AAF4tAABpLQAAXy0AAGktAABqLQAA6iwAAF8tAABqLQAA6iwAAGotAADrLAAA6SwAAFstAABfLQAA6SwAAF8tAADqLAAA6CwAAFgtAABbLQAA6CwAAFstAADpLAAAay0AAGwtAABtLQAAay0AAG0tAABuLQAAbC0AAG8tAABwLQAAbC0AAHAtAABtLQAAbi0AAG0tAABxLQAAbi0AAHEtAAByLQAAbS0AAHAtAABzLQAAbS0AAHMtAABxLQAAxgcAAHQtAABrLQAAxgcAAGstAAAOLQAAdC0AAHUtAABsLQAAdC0AAGwtAABrLQAAdS0AAHYtAABvLQAAdS0AAG8tAABsLQAAdi0AAKMHAAB3LQAAdi0AAHctAABvLQAAby0AAHctAAB4LQAAby0AAHgtAABwLQAAcC0AAHgtAAB5LQAAcC0AAHktAABzLQAAcy0AAHktAAB6LQAAcy0AAHotAAB7LQAAcS0AAHMtAAB7LQAAcS0AAHstAAB8LQAAci0AAHEtAAB8LQAAci0AAHwtAAB9LQAAEC0AAHItAAB9LQAAEC0AAH0tAAARLQAADy0AAG4tAAByLQAADy0AAHItAAAQLQAADi0AAGstAABuLQAADi0AAG4tAAAPLQAAfi0AAH8tAACALQAAfi0AAIAtAACBLQAAfy0AAIItAACDLQAAfy0AAIMtAACALQAAgS0AAIAtAACELQAAgS0AAIQtAACFLQAAgC0AAIMtAACGLQAAgC0AAIYtAACELQAALwAAAIctAAB+LQAALwAAAH4tAACILQAAhy0AAIktAAB/LQAAhy0AAH8tAAB+LQAAiS0AAGMAAACCLQAAiS0AAIItAAB/LQAAYwAAAGIAAAAeLQAAYwAAAB4tAACCLQAAgi0AAB4tAAAkLQAAgi0AACQtAACDLQAAgy0AACQtAAAiLQAAgy0AACItAACGLQAAhi0AACItAAAjLQAAhi0AACMtAACKLQAAhC0AAIYtAACKLQAAhC0AAIotAACLLQAAhS0AAIQtAACLLQAAhS0AAIstAACMLQAAjS0AAIUtAACMLQAAjS0AAIwtAACOLQAAjy0AAIEtAACFLQAAjy0AAIUtAACNLQAAiC0AAH4tAACBLQAAiC0AAIEtAACPLQAAkC0AAJEtAACSLQAAkC0AAJItAACTLQAAkS0AAJQtAACVLQAAkS0AAJUtAACSLQAAky0AAJItAACWLQAAky0AAJYtAACXLQAAki0AAJUtAACYLQAAki0AAJgtAACWLQAAhwMAAJktAACQLQAAhwMAAJAtAACaLQAAmS0AAAkEAACRLQAAmS0AAJEtAACQLQAACQQAAJstAACULQAACQQAAJQtAACRLQAAmy0AAAIEAAB9LAAAmy0AAH0sAACULQAAlC0AAH0sAACILAAAlC0AAIgsAACVLQAAlS0AAIgsAACGLAAAlS0AAIYsAACYLQAAmC0AAIYsAACHLAAAmC0AAIcsAACcLQAAli0AAJgtAACcLQAAli0AAJwtAACdLQAAly0AAJYtAACdLQAAly0AAJ0tAACeLQAAny0AAJctAACeLQAAny0AAJ4tAACgLQAAoS0AAJMtAACXLQAAoS0AAJctAACfLQAAmi0AAJAtAACTLQAAmi0AAJMtAAChLQAAoi0AAKMtAACkLQAAoi0AAKQtAAClLQAAoy0AAKYtAACnLQAAoy0AAKctAACkLQAApS0AAKQtAACoLQAApS0AAKgtAACpLQAApC0AAKctAACqLQAApC0AAKotAACoLQAAVgAAAFgAAACiLQAAVgAAAKItAAAuLQAAWAAAAKstAACjLQAAWAAAAKMtAACiLQAAqy0AAKwtAACmLQAAqy0AAKYtAACjLQAArC0AAK0tAACuLQAArC0AAK4tAACmLQAApi0AAK4tAACvLQAApi0AAK8tAACnLQAApy0AAK8tAACwLQAApy0AALAtAACqLQAAqi0AALAtAACxLQAAqi0AALEtAACyLQAAqC0AAKotAACyLQAAqC0AALItAACzLQAAqS0AAKgtAACzLQAAqS0AALMtAAC0LQAAMC0AAKktAAC0LQAAMC0AALQtAAAxLQAALy0AAKUtAACpLQAALy0AAKktAAAwLQAALi0AAKItAAClLQAALi0AAKUtAAAvLQAAtS0AALYtAAC3LQAAtS0AALctAAC4LQAAti0AALktAAC6LQAAti0AALotAAC3LQAAuC0AALctAAC7LQAAuC0AALstAAC8LQAAty0AALotAAC9LQAAty0AAL0tAAC7LQAAXgkAAIYJAAC1LQAAXgkAALUtAAC+LQAAhgkAAIQJAAC2LQAAhgkAALYtAAC1LQAAhAkAAIIJAAC5LQAAhAkAALktAAC2LQAAggkAAIEJAAA/LQAAggkAAD8tAAC5LQAAuS0AAD8tAABFLQAAuS0AAEUtAAC6LQAAui0AAEUtAABDLQAAui0AAEMtAAC9LQAAvS0AAEMtAABELQAAvS0AAEQtAAC/LQAAuy0AAL0tAAC/LQAAuy0AAL8tAADALQAAvC0AALstAADALQAAvC0AAMAtAADBLQAAwi0AALwtAADBLQAAwi0AAMEtAADDLQAAxC0AALgtAAC8LQAAxC0AALwtAADCLQAAvi0AALUtAAC4LQAAvi0AALgtAADELQAAxS0AAMYtAADHLQAAxS0AAMctAADILQAAxi0AAMktAADKLQAAxi0AAMotAADHLQAAyC0AAMctAADLLQAAyC0AAMstAADMLQAAxy0AAMotAADNLQAAxy0AAM0tAADLLQAAiwcAAM4tAADFLQAAiwcAAMUtAADPLQAAzi0AALIHAADGLQAAzi0AAMYtAADFLQAAsgcAANAtAADJLQAAsgcAAMktAADGLQAA0C0AAK8HAABQLQAA0C0AAFAtAADJLQAAyS0AAFAtAABXLQAAyS0AAFctAADKLQAAyi0AAFctAABVLQAAyi0AAFUtAADNLQAAzS0AAFUtAABWLQAAzS0AAFYtAADRLQAAyy0AAM0tAADRLQAAyy0AANEtAADSLQAAzC0AAMstAADSLQAAzC0AANItAADTLQAA1C0AAMwtAADTLQAA1C0AANMtAADVLQAA1i0AAMgtAADMLQAA1i0AAMwtAADULQAAzy0AAMUtAADILQAAzy0AAMgtAADWLQAA1y0AANgtAADZLQAA1y0AANktAADaLQAA2C0AANstAADcLQAA2C0AANwtAADZLQAA2i0AANktAADdLQAA2i0AAN0tAADeLQAA2S0AANwtAADfLQAA2S0AAN8tAADdLQAArS0AAOAtAADXLQAArS0AANctAACuLQAA4C0AAEcAAADYLQAA4C0AANgtAADXLQAARwAAAEEAAADbLQAARwAAANstAADYLQAAQQAAACQAAADhLQAAQQAAAOEtAADbLQAA2y0AAOEtAADiLQAA2y0AAOItAADcLQAA3C0AAOItAADjLQAA3C0AAOMtAADfLQAA3y0AAOMtAADkLQAA3y0AAOQtAADlLQAA3S0AAN8tAADlLQAA3S0AAOUtAADmLQAA3i0AAN0tAADmLQAA3i0AAOYtAADnLQAAsC0AAN4tAADnLQAAsC0AAOctAACxLQAAry0AANotAADeLQAAry0AAN4tAACwLQAAri0AANctAADaLQAAri0AANotAACvLQAA6C0AAOktAADqLQAA6C0AAOotAADrLQAA6S0AAOwtAADtLQAA6S0AAO0tAADqLQAA6y0AAOotAADuLQAA6y0AAO4tAADvLQAA6i0AAO0tAADwLQAA6i0AAPAtAADuLQAAdQkAAPEtAADoLQAAdQkAAOgtAABkLQAA8S0AAHgJAADpLQAA8S0AAOktAADoLQAAeAkAAHMJAADsLQAAeAkAAOwtAADpLQAAcwkAAFEJAADyLQAAcwkAAPItAADsLQAA7C0AAPItAADzLQAA7C0AAPMtAADtLQAA7S0AAPMtAAD0LQAA7S0AAPQtAADwLQAA8C0AAPQtAAD1LQAA8C0AAPUtAAD2LQAA7i0AAPAtAAD2LQAA7i0AAPYtAAD3LQAA7y0AAO4tAAD3LQAA7y0AAPctAAD4LQAAZi0AAO8tAAD4LQAAZi0AAPgtAABnLQAAZS0AAOstAADvLQAAZS0AAO8tAABmLQAAZC0AAOgtAADrLQAAZC0AAOstAABlLQAA+S0AAPotAAD7LQAA+S0AAPstAAD8LQAA+i0AAP0tAAD+LQAA+i0AAP4tAAD7LQAA/C0AAPstAAD/LQAA/C0AAP8tAAAALgAA+y0AAP4tAAABLgAA+y0AAAEuAAD/LQAAowcAAAIuAAD5LQAAowcAAPktAAB3LQAAAi4AAKIHAAD6LQAAAi4AAPotAAD5LQAAogcAAAMuAAD9LQAAogcAAP0tAAD6LQAAAy4AAHwHAAAELgAAAy4AAAQuAAD9LQAA/S0AAAQuAAAFLgAA/S0AAAUuAAD+LQAA/i0AAAUuAAAGLgAA/i0AAAYuAAABLgAAAS4AAAYuAAAHLgAAAS4AAAcuAAAILgAA/y0AAAEuAAAILgAA/y0AAAguAAAJLgAAAC4AAP8tAAAJLgAAAC4AAAkuAAAKLgAAeS0AAAAuAAAKLgAAeS0AAAouAAB6LQAAeC0AAPwtAAAALgAAeC0AAAAuAAB5LQAAdy0AAPktAAD8LQAAdy0AAPwtAAB4LQAACy4AAAwuAAANLgAACy4AAA0uAAAOLgAADC4AAA8uAAAQLgAADC4AABAuAAANLgAADi4AAA0uAAARLgAADi4AABEuAAASLgAADS4AABAuAAATLgAADS4AABMuAAARLgAArQUAAK8FAAALLgAArQUAAAsuAABqLAAArwUAAKwFAAAMLgAArwUAAAwuAAALLgAArAUAABQuAAAPLgAArAUAAA8uAAAMLgAAFC4AAPoEAAAVLgAAFC4AABUuAAAPLgAADy4AABUuAAAWLgAADy4AABYuAAAQLgAAEC4AABYuAAAXLgAAEC4AABcuAAATLgAAEy4AABcuAAAYLgAAEy4AABguAAAZLgAAES4AABMuAAAZLgAAES4AABkuAAAaLgAAEi4AABEuAAAaLgAAEi4AABouAAAbLgAAbCwAABIuAAAbLgAAbCwAABsuAABtLAAAaywAAA4uAAASLgAAaywAABIuAABsLAAAaiwAAAsuAAAOLgAAaiwAAA4uAABrLAAAHC4AAB0uAAAeLgAAHC4AAB4uAAAfLgAAHS4AACAuAAAhLgAAHS4AACEuAAAeLgAAHy4AAB4uAAAiLgAAHy4AACIuAAAjLgAAHi4AACEuAAAkLgAAHi4AACQuAAAiLgAANQEAACUuAAAcLgAANQEAABwuAAAmLgAAJS4AAP4BAAAdLgAAJS4AAB0uAAAcLgAA/gEAACcuAAAgLgAA/gEAACAuAAAdLgAAJy4AAPsBAAAoLgAAJy4AACguAAAgLgAAIC4AACguAAApLgAAIC4AACkuAAAhLgAAIS4AACkuAAAqLgAAIS4AACouAAAkLgAAJC4AACouAAArLgAAJC4AACsuAAAsLgAAIi4AACQuAAAsLgAAIi4AACwuAAAtLgAAIy4AACIuAAAtLgAAIy4AAC0uAAAuLgAALy4AACMuAAAuLgAALy4AAC4uAAAwLgAAMS4AAB8uAAAjLgAAMS4AACMuAAAvLgAAJi4AABwuAAAfLgAAJi4AAB8uAAAxLgAAMi4AADMuAAA0LgAAMi4AADQuAAA1LgAAMy4AADYuAAA3LgAAMy4AADcuAAA0LgAANS4AADQuAAA4LgAANS4AADguAAA5LgAANC4AADcuAAA6LgAANC4AADouAAA4LgAA0QMAANMDAAAyLgAA0QMAADIuAACoLAAA0wMAADsuAAAzLgAA0wMAADMuAAAyLgAAOy4AADwuAAA2LgAAOy4AADYuAAAzLgAAPC4AAJoDAAA9LgAAPC4AAD0uAAA2LgAANi4AAD0uAAA+LgAANi4AAD4uAAA3LgAANy4AAD4uAAA/LgAANy4AAD8uAAA6LgAAOi4AAD8uAABALgAAOi4AAEAuAABBLgAAOC4AADouAABBLgAAOC4AAEEuAABCLgAAOS4AADguAABCLgAAOS4AAEIuAABDLgAAqiwAADkuAABDLgAAqiwAAEMuAACrLAAAqSwAADUuAAA5LgAAqSwAADkuAACqLAAAqCwAADIuAAA1LgAAqCwAADUuAACpLAAARC4AAEUuAABGLgAARC4AAEYuAABHLgAARS4AAEguAABJLgAARS4AAEkuAABGLgAARy4AAEYuAABKLgAARy4AAEouAABLLgAARi4AAEkuAABMLgAARi4AAEwuAABKLgAACQAAAE0uAABELgAACQAAAEQuAABOLgAATS4AADIAAABFLgAATS4AAEUuAABELgAAMgAAAE8uAABILgAAMgAAAEguAABFLgAATy4AAC8AAACILQAATy4AAIgtAABILgAASC4AAIgtAACPLQAASC4AAI8tAABJLgAASS4AAI8tAACNLQAASS4AAI0tAABMLgAATC4AAI0tAACOLQAATC4AAI4tAABQLgAASi4AAEwuAABQLgAASi4AAFAuAABRLgAASy4AAEouAABRLgAASy4AAFEuAABSLgAAUy4AAEsuAABSLgAAUy4AAFIuAABULgAAVS4AAEcuAABLLgAAVS4AAEsuAABTLgAATi4AAEQuAABHLgAATi4AAEcuAABVLgAAVi4AAFcuAABYLgAAVi4AAFguAABZLgAAVy4AAFouAABbLgAAVy4AAFsuAABYLgAAWS4AAFguAABcLgAAWS4AAFwuAABdLgAAWC4AAFsuAABeLgAAWC4AAF4uAABcLgAAOgkAAGMJAABWLgAAOgkAAFYuAABfLgAAYwkAAGQJAABXLgAAYwkAAFcuAABWLgAAZAkAAF8JAABaLgAAZAkAAFouAABXLgAAXwkAAF4JAAC+LQAAXwkAAL4tAABaLgAAWi4AAL4tAADELQAAWi4AAMQtAABbLgAAWy4AAMQtAADCLQAAWy4AAMItAABeLgAAXi4AAMItAADDLQAAXi4AAMMtAABgLgAAXC4AAF4uAABgLgAAXC4AAGAuAABhLgAAXS4AAFwuAABhLgAAXS4AAGEuAABiLgAAYy4AAF0uAABiLgAAYy4AAGIuAABkLgAAZS4AAFkuAABdLgAAZS4AAF0uAABjLgAAXy4AAFYuAABZLgAAXy4AAFkuAABlLgAAZi4AAGcuAABoLgAAZi4AAGguAABpLgAAZy4AAGouAABrLgAAZy4AAGsuAABoLgAAaS4AAGguAABsLgAAaS4AAGwuAABtLgAAaC4AAGsuAABuLgAAaC4AAG4uAABsLgAA7gEAAPABAABmLgAA7gEAAGYuAABvLgAA8AEAAPEBAABnLgAA8AEAAGcuAABmLgAA8QEAAOsBAABqLgAA8QEAAGouAABnLgAA6wEAACoBAABwLgAA6wEAAHAuAABqLgAAai4AAHAuAABxLgAAai4AAHEuAABrLgAAay4AAHEuAAByLgAAay4AAHIuAABuLgAAbi4AAHIuAABzLgAAbi4AAHMuAAB0LgAAbC4AAG4uAAB0LgAAbC4AAHQuAAB1LgAAbS4AAGwuAAB1LgAAbS4AAHUuAAB2LgAAdy4AAG0uAAB2LgAAdy4AAHYuAAB4LgAAeS4AAGkuAABtLgAAeS4AAG0uAAB3LgAAby4AAGYuAABpLgAAby4AAGkuAAB5LgAAei4AAHsuAAB8LgAAei4AAHwuAAB9LgAAey4AAH4uAAB/LgAAey4AAH8uAAB8LgAAfS4AAHwuAACALgAAfS4AAIAuAACBLgAAfC4AAH8uAACCLgAAfC4AAIIuAACALgAAJAsAACYLAAB6LgAAJAsAAHouAACDLgAAJgsAACMLAAB7LgAAJgsAAHsuAAB6LgAAIwsAAIQuAAB+LgAAIwsAAH4uAAB7LgAAhC4AABMLAACFLgAAhC4AAIUuAAB+LgAAfi4AAIUuAACGLgAAfi4AAIYuAAB/LgAAfy4AAIYuAACHLgAAfy4AAIcuAACCLgAAgi4AAIcuAACILgAAgi4AAIguAACJLgAAgC4AAIIuAACJLgAAgC4AAIkuAACKLgAAgS4AAIAuAACKLgAAgS4AAIouAACLLgAAjC4AAIEuAACLLgAAjC4AAIsuAACNLgAAji4AAH0uAACBLgAAji4AAIEuAACMLgAAgy4AAHouAAB9LgAAgy4AAH0uAACOLgAAjy4AAJAuAACRLgAAjy4AAJEuAACSLgAAkC4AAJMuAACULgAAkC4AAJQuAACRLgAAki4AAJEuAACVLgAAki4AAJUuAACWLgAAkS4AAJQuAACXLgAAkS4AAJcuAACVLgAAYgcAAJguAACPLgAAYgcAAI8uAACZLgAAmC4AAJouAACQLgAAmC4AAJAuAACPLgAAmi4AAIwHAACTLgAAmi4AAJMuAACQLgAAjAcAAIsHAADPLQAAjAcAAM8tAACTLgAAky4AAM8tAADWLQAAky4AANYtAACULgAAlC4AANYtAADULQAAlC4AANQtAACXLgAAly4AANQtAADVLQAAly4AANUtAACbLgAAlS4AAJcuAACbLgAAlS4AAJsuAACcLgAAli4AAJUuAACcLgAAli4AAJwuAACdLgAAni4AAJYuAACdLgAAni4AAJ0uAACfLgAAoC4AAJIuAACWLgAAoC4AAJYuAACeLgAAmS4AAI8uAACSLgAAmS4AAJIuAACgLgAAoS4AAKIuAACjLgAAoS4AAKMuAACkLgAAoi4AAKUuAACmLgAAoi4AAKYuAACjLgAApC4AAKMuAACnLgAApC4AAKcuAACoLgAAoy4AAKYuAACpLgAAoy4AAKkuAACnLgAAJAAAAKouAAChLgAAJAAAAKEuAADhLQAAqi4AACMAAACiLgAAqi4AAKIuAAChLgAAIwAAACEAAAClLgAAIwAAAKUuAACiLgAAIQAAAKsuAACsLgAAIQAAAKwuAAClLgAApS4AAKwuAACtLgAApS4AAK0uAACmLgAApi4AAK0uAACuLgAApi4AAK4uAACpLgAAqS4AAK4uAACvLgAAqS4AAK8uAACwLgAApy4AAKkuAACwLgAApy4AALAuAACxLgAAqC4AAKcuAACxLgAAqC4AALEuAACyLgAA4y0AAKguAACyLgAA4y0AALIuAADkLQAA4i0AAKQuAACoLgAA4i0AAKguAADjLQAA4S0AAKEuAACkLgAA4S0AAKQuAADiLQAAsy4AALQuAAC1LgAAsy4AALUuAAC2LgAAtC4AALcuAAC4LgAAtC4AALguAAC1LgAAti4AALUuAAC5LgAAti4AALkuAAC6LgAAtS4AALguAAC7LgAAtS4AALsuAAC5LgAAUQkAAFMJAACzLgAAUQkAALMuAADyLQAAUwkAALwuAAC0LgAAUwkAALQuAACzLgAAvC4AAE8JAAC3LgAAvC4AALcuAAC0LgAATwkAACwJAAC9LgAATwkAAL0uAAC3LgAAty4AAL0uAAC+LgAAty4AAL4uAAC4LgAAuC4AAL4uAAC/LgAAuC4AAL8uAAC7LgAAuy4AAL8uAADALgAAuy4AAMAuAADBLgAAuS4AALsuAADBLgAAuS4AAMEuAADCLgAAui4AALkuAADCLgAAui4AAMIuAADDLgAA9C0AALouAADDLgAA9C0AAMMuAAD1LQAA8y0AALYuAAC6LgAA8y0AALouAAD0LQAA8i0AALMuAAC2LgAA8i0AALYuAADzLQAAxC4AAMUuAADGLgAAxC4AAMYuAADHLgAAxS4AAMguAADJLgAAxS4AAMkuAADGLgAAxy4AAMYuAADKLgAAxy4AAMouAADLLgAAxi4AAMkuAADMLgAAxi4AAMwuAADKLgAAVAoAAB8LAADELgAAVAoAAMQuAADNLgAAHwsAACALAADFLgAAHwsAAMUuAADELgAAIAsAACULAADILgAAIAsAAMguAADFLgAAJQsAACQLAACDLgAAJQsAAIMuAADILgAAyC4AAIMuAACOLgAAyC4AAI4uAADJLgAAyS4AAI4uAACMLgAAyS4AAIwuAADMLgAAzC4AAIwuAACNLgAAzC4AAI0uAADOLgAAyi4AAMwuAADOLgAAyi4AAM4uAADPLgAAyy4AAMouAADPLgAAyy4AAM8uAADQLgAA0S4AAMsuAADQLgAA0S4AANAuAADSLgAA0y4AAMcuAADLLgAA0y4AAMsuAADRLgAAzS4AAMQuAADHLgAAzS4AAMcuAADTLgAA1C4AANUuAADWLgAA1C4AANYuAADXLgAA1S4AANguAADZLgAA1S4AANkuAADWLgAA1y4AANYuAADaLgAA1y4AANouAADbLgAA1i4AANkuAADcLgAA1i4AANwuAADaLgAAfAcAAN0uAADULgAAfAcAANQuAAAELgAA3S4AAN4uAADVLgAA3S4AANUuAADULgAA3i4AAN8uAADYLgAA3i4AANguAADVLgAA3y4AAFUHAADgLgAA3y4AAOAuAADYLgAA2C4AAOAuAADhLgAA2C4AAOEuAADZLgAA2S4AAOEuAADiLgAA2S4AAOIuAADcLgAA3C4AAOIuAADjLgAA3C4AAOMuAADkLgAA2i4AANwuAADkLgAA2i4AAOQuAADlLgAA2y4AANouAADlLgAA2y4AAOUuAADmLgAABi4AANsuAADmLgAABi4AAOYuAAAHLgAABS4AANcuAADbLgAABS4AANsuAAAGLgAABC4AANQuAADXLgAABC4AANcuAAAFLgAA5y4AAOguAADpLgAA5y4AAOkuAADqLgAA6C4AAOsuAADsLgAA6C4AAOwuAADpLgAA6i4AAOkuAADtLgAA6i4AAO0uAADuLgAA6S4AAOwuAADvLgAA6S4AAO8uAADtLgAAEwsAABULAADnLgAAEwsAAOcuAACFLgAAFQsAAPAuAADoLgAAFQsAAOguAADnLgAA8C4AABALAADrLgAA8C4AAOsuAADoLgAAEAsAAAALAADxLgAAEAsAAPEuAADrLgAA6y4AAPEuAADyLgAA6y4AAPIuAADsLgAA7C4AAPIuAADzLgAA7C4AAPMuAADvLgAA7y4AAPMuAAD0LgAA7y4AAPQuAAD1LgAA7S4AAO8uAAD1LgAA7S4AAPUuAAD2LgAA7i4AAO0uAAD2LgAA7i4AAPYuAAD3LgAAhy4AAO4uAAD3LgAAhy4AAPcuAACILgAAhi4AAOouAADuLgAAhi4AAO4uAACHLgAAhS4AAOcuAADqLgAAhS4AAOouAACGLgAA+C4AAPkuAAD6LgAA+C4AAPouAAD7LgAA+S4AAPwuAAD9LgAA+S4AAP0uAAD6LgAA+y4AAPouAAD+LgAA+y4AAP4uAAD/LgAA+i4AAP0uAAAALwAA+i4AAAAvAAD+LgAAqy4AAAEvAAD4LgAAqy4AAPguAACsLgAAAS8AAAIvAAD5LgAAAS8AAPkuAAD4LgAAAi8AAAMvAAD8LgAAAi8AAPwuAAD5LgAAAy8AAA4AAAAELwAA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UC8AAFMvAABULwAATy8AAFIvAABVLwAATy8AAFUvAABTLwAALAkAAFYvAABNLwAALAkAAE0vAAC9LgAAVi8AACoJAABOLwAAVi8AAE4vAABNLwAAKgkAACgJAABRLwAAKgkAAFEvAABOLwAAKAkAAAcJAABXLwAAKAkAAFcvAABRLwAAUS8AAFcvAABYLwAAUS8AAFgvAABSLwAAUi8AAFgvAABZLwAAUi8AAFkvAABVLwAAVS8AAFkvAABaLwAAVS8AAFovAABbLwAAUy8AAFUvAABbLwAAUy8AAFsvAABcLwAAVC8AAFMvAABcLwAAVC8AAFwvAABdLwAAvy4AAFQvAABdLwAAvy4AAF0vAADALgAAvi4AAFAvAABULwAAvi4AAFQvAAC/LgAAvS4AAE0vAABQLwAAvS4AAFAvAAC+LgAAXi8AAF8vAABgLwAAXi8AAGAvAABhLwAAXy8AAGIvAABjLwAAXy8AAGMvAABgLwAAYS8AAGAvAABkLwAAYS8AAGQvAABlLwAAYC8AAGMvAABmLwAAYC8AAGYvAABkLwAAVQcAAFcHAABeLwAAVQcAAF4vAADgLgAAVwcAAFkHAABfLwAAVwcAAF8vAABeLwAAWQcAAGcvAABiLwAAWQcAAGIvAABfLwAAZy8AAC8HAABoLwAAZy8AAGgvAABiLwAAYi8AAGgvAABpLwAAYi8AAGkvAABjLwAAYy8AAGkvAABqLwAAYy8AAGovAABmLwAAZi8AAGovAABrLwAAZi8AAGsvAABsLwAAZC8AAGYvAABsLwAAZC8AAGwvAABtLwAAZS8AAGQvAABtLwAAZS8AAG0vAABuLwAA4i4AAGUvAABuLwAA4i4AAG4vAADjLgAA4S4AAGEvAABlLwAA4S4AAGUvAADiLgAA4C4AAF4vAABhLwAA4C4AAGEvAADhLgAAby8AAHAvAABxLwAAby8AAHEvAAByLwAAcC8AAHMvAAB0LwAAcC8AAHQvAABxLwAAci8AAHEvAAB1LwAAci8AAHUvAAB2LwAAcS8AAHQvAAB3LwAAcS8AAHcvAAB1LwAAmgMAAHgvAABvLwAAmgMAAG8vAAA9LgAAeC8AAHkvAABwLwAAeC8AAHAvAABvLwAAeS8AAHovAABzLwAAeS8AAHMvAABwLwAAei8AAB0DAAB7LwAAei8AAHsvAABzLwAAcy8AAHsvAAB8LwAAcy8AAHwvAAB0LwAAdC8AAHwvAAB9LwAAdC8AAH0vAAB3LwAAdy8AAH0vAAB+LwAAdy8AAH4vAAB/LwAAdS8AAHcvAAB/LwAAdS8AAH8vAACALwAAdi8AAHUvAACALwAAdi8AAIAvAACBLwAAPy4AAHYvAACBLwAAPy4AAIEvAABALgAAPi4AAHIvAAB2LwAAPi4AAHYvAAA/LgAAPS4AAG8vAAByLwAAPS4AAHIvAAA+LgAAgi8AAIMvAACELwAAgi8AAIQvAACFLwAAgy8AAIYvAACHLwAAgy8AAIcvAACELwAAhS8AAIQvAACILwAAhS8AAIgvAACJLwAAhC8AAIcvAACKLwAAhC8AAIovAACILwAA7AoAAIsvAACCLwAA7AoAAIIvAAAmLwAAiy8AAIwvAACDLwAAiy8AAIMvAACCLwAAjC8AAOoKAACGLwAAjC8AAIYvAACDLwAA6goAAI0vAACOLwAA6goAAI4vAACGLwAAhi8AAI4vAACPLwAAhi8AAI8vAACHLwAAhy8AAI8vAACQLwAAhy8AAJAvAACKLwAAii8AAJAvAACRLwAAii8AAJEvAACSLwAAiC8AAIovAACSLwAAiC8AAJIvAACTLwAAiS8AAIgvAACTLwAAiS8AAJMvAACULwAAKC8AAIkvAACULwAAKC8AAJQvAAApLwAAJy8AAIUvAACJLwAAJy8AAIkvAAAoLwAAJi8AAIIvAACFLwAAJi8AAIUvAAAnLwAAlS8AAJYvAACXLwAAlS8AAJcvAACYLwAAli8AAJkvAACaLwAAli8AAJovAACXLwAAmC8AAJcvAACbLwAAmC8AAJsvAACcLwAAly8AAJovAACdLwAAly8AAJ0vAACbLwAA7QgAAJ4vAACVLwAA7QgAAJUvAACfLwAAni8AABUJAACWLwAAni8AAJYvAACVLwAAFQkAAKAvAACZLwAAFQkAAJkvAACWLwAAoC8AABIJAAAULwAAoC8AABQvAACZLwAAmS8AABQvAAAbLwAAmS8AABsvAACaLwAAmi8AABsvAAAZLwAAmi8AABkvAACdLwAAnS8AABkvAAAaLwAAnS8AABovAAChLwAAmy8AAJ0vAAChLwAAmy8AAKEvAACiLwAAnC8AAJsvAACiLwAAnC8AAKIvAACjLwAApC8AAJwvAACjLwAApC8AAKMvAAClLwAApi8AAJgvAACcLwAApi8AAJwvAACkLwAAny8AAJUvAACYLwAAny8AAJgvAACmLwAApy8AAKgvAACpLwAApy8AAKkvAACqLwAAqC8AAKsvAACsLwAAqC8AAKwvAACpLwAAqi8AAKkvAACtLwAAqi8AAK0vAACuLwAAqS8AAKwvAACvLwAAqS8AAK8vAACtLwAAjS8AANwKAACnLwAAjS8AAKcvAACOLwAA3AoAALAvAACoLwAA3AoAAKgvAACnLwAAsC8AANcKAACrLwAAsC8AAKsvAACoLwAA1woAAMcKAACxLwAA1woAALEvAACrLwAAqy8AALEvAACyLwAAqy8AALIvAACsLwAArC8AALIvAACzLwAArC8AALMvAACvLwAAry8AALMvAAC0LwAAry8AALQvAAC1LwAArS8AAK8vAAC1LwAArS8AALUvAAC2LwAAri8AAK0vAAC2LwAAri8AALYvAAC3LwAAkC8AAK4vAAC3LwAAkC8AALcvAACRLwAAjy8AAKovAACuLwAAjy8AAK4vAACQLwAAji8AAKcvAACqLwAAji8AAKovAACPLwAAuC8AALkvAAC6LwAAuC8AALovAAC7LwAAuS8AALwvAAC9LwAAuS8AAL0vAAC6LwAAuy8AALovAAC+LwAAuy8AAL4vAAC/LwAAui8AAL0vAADALwAAui8AAMAvAAC+LwAAGAcAAMEvAAC4LwAAGAcAALgvAADCLwAAwS8AAD4HAAC5LwAAwS8AALkvAAC4LwAAPgcAAMMvAAC8LwAAPgcAALwvAAC5LwAAwy8AADsHAAA3LwAAwy8AADcvAAC8LwAAvC8AADcvAAA+LwAAvC8AAD4vAAC9LwAAvS8AAD4vAAA8LwAAvS8AADwvAADALwAAwC8AADwvAAA9LwAAwC8AAD0vAADELwAAvi8AAMAvAADELwAAvi8AAMQvAADFLwAAvy8AAL4vAADFLwAAvy8AAMUvAADGLwAAxy8AAL8vAADGLwAAxy8AAMYvAADILwAAyS8AALsvAAC/LwAAyS8AAL8vAADHLwAAwi8AALgvAAC7LwAAwi8AALsvAADJLwAAyi8AAMsvAADMLwAAyi8AAMwvAADNLwAAyy8AAM4vAADPLwAAyy8AAM8vAADMLwAAzS8AAMwvAADQLwAAzS8AANAvAADRLwAAzC8AAM8vAADSLwAAzC8AANIvAADQLwAAKwMAANMvAADKLwAAKwMAAMovAADULwAA0y8AAI0DAADLLwAA0y8AAMsvAADKLwAAjQMAANUvAADOLwAAjQMAAM4vAADLLwAA1S8AAIcDAACaLQAA1S8AAJotAADOLwAAzi8AAJotAAChLQAAzi8AAKEtAADPLwAAzy8AAKEtAACfLQAAzy8AAJ8tAADSLwAA0i8AAJ8tAACgLQAA0i8AAKAtAADWLwAA0C8AANIvAADWLwAA0C8AANYvAADXLwAA0S8AANAvAADXLwAA0S8AANcvAADYLwAA2S8AANEvAADYLwAA2S8AANgvAADaLwAA2y8AAM0vAADRLwAA2y8AANEvAADZLwAA1C8AAMovAADNLwAA1C8AAM0vAADbLwAA3C8AAN0vAADeLwAA3C8AAN4vAADfLwAA3S8AAOAvAADhLwAA3S8AAOEvAADeLwAA3y8AAN4vAADiLwAA3y8AAOIvAADjLwAA3i8AAOEvAADkLwAA3i8AAOQvAADiLwAABwkAAAkJAADcLwAABwkAANwvAABXLwAACQkAAOUvAADdLwAACQkAAN0vAADcLwAA5S8AAAQJAADgLwAA5S8AAOAvAADdLwAABAkAAOEIAADmLwAABAkAAOYvAADgLwAA4C8AAOYvAADnLwAA4C8AAOcvAADhLwAA4S8AAOcvAADoLwAA4S8AAOgvAADkLwAA5C8AAOgvAADpLwAA5C8AAOkvAADqLwAA4i8AAOQvAADqLwAA4i8AAOovAADrLwAA4y8AAOIvAADrLwAA4y8AAOsvAADsLwAAWS8AAOMvAADsLwAAWS8AAOwvAABaLwAAWC8AAN8vAADjLwAAWC8AAOMvAABZLwAAVy8AANwvAADfLwAAVy8AAN8vAABYLwAA7S8AAO4vAADvLwAA7S8AAO8vAADwLwAA7i8AAPEvAADyLwAA7i8AAPIvAADvLwAA8C8AAO8vAADzLwAA8C8AAPMvAAD0LwAA7y8AAPIvAAD1LwAA7y8AAPUvAADzLwAALwcAADEHAADtLwAALwcAAO0vAABoLwAAMQcAADIHAADuLwAAMQcAAO4vAADtLwAAMgcAAC0HAADxLwAAMgcAAPEvAADuLwAALQcAAAwHAAD2LwAALQcAAPYvAADxLwAA8S8AAPYvAAD3LwAA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RTAAAEswAABJMAAA9wYAAEwwAABDMAAA9wYAAEMwAABNMAAATDAAAE4wAABEMAAATDAAAEQwAABDMAAATjAAAE8wAABHMAAATjAAAEcwAABEMAAATzAAABgHAADCLwAATzAAAMIvAABHMAAARzAAAMIvAADJLwAARzAAAMkvAABIMAAASDAAAMkvAADHLwAASDAAAMcvAABLMAAASzAAAMcvAADILwAASzAAAMgvAABQMAAASTAAAEswAABQMAAASTAAAFAwAABRMAAASjAAAEkwAABRMAAASjAAAFEwAABSMAAAUzAAAEowAABSMAAAUzAAAFIwAABUMAAAVTAAAEYwAABKMAAAVTAAAEowAABTMAAATTAAAEMwAABGMAAATTAAAEYwAABVMAAAVjAAAFcwAABYMAAAVjAAAFgwAABZMAAAVzAAAFowAABbMAAAVzAAAFswAABYMAAAWTAAAFgwAABcMAAAWTAAAFwwAABdMAAAWDAAAFswAABeMAAAWDAAAF4wAABcMAAA4QgAAOMIAABWMAAA4QgAAFYwAADmLwAA4wgAAOAIAABXMAAA4wgAAFcwAABWMAAA4AgAAF8wAABaMAAA4AgAAFowAABXMAAAXzAAALoIAABgMAAAXzAAAGAwAABaMAAAWjAAAGAwAABhMAAAWjAAAGEwAABbMAAAWzAAAGEwAABiMAAAWzAAAGIwAABeMAAAXjAAAGIwAABjMAAAXjAAAGMwAABkMAAAXDAAAF4wAABkMAAAXDAAAGQwAABlMAAAXTAAAFwwAABlMAAAXTAAAGUwAABmMAAA6C8AAF0wAABmMAAA6C8AAGYwAADpLwAA5y8AAFkwAABdMAAA5y8AAF0wAADoLwAA5i8AAFYwAABZMAAA5i8AAFkwAADnLwAAZzAAAGgwAABpMAAAZzAAAGkwAABqMAAAaDAAAGswAABsMAAAaDAAAGwwAABpMAAAajAAAGkwAABtMAAAajAAAG0wAABuMAAAaTAAAGwwAABvMAAAaTAAAG8wAABtMAAADAcAAA4HAABnMAAADAcAAGcwAAD2LwAADgcAAAsHAABoMAAADgcAAGgwAABnMAAACwcAAHAwAABrMAAACwcAAGswAABoMAAAcDAAAOoGAABxMAAAcDAAAHEwAABrMAAAazAAAHEwAAByMAAAazAAAHIwAABsMAAAbDAAAHIwAABzMAAAbDAAAHMwAABvMAAAbzAAAHMwAAB0MAAAbzAAAHQwAAB1MAAAbTAAAG8wAAB1MAAAbTAAAHUwAAB2MAAAbjAAAG0wAAB2MAAAbjAAAHYwAAB3MAAA+C8AAG4wAAB3MAAA+C8AAHcwAAD5LwAA9y8AAGowAABuMAAA9y8AAG4wAAD4LwAA9i8AAGcwAABqMAAA9i8AAGowAAD3LwAAeDAAAHkwAAB6MAAAeDAAAHowAAB7MAAAeTAAAHwwAAB9MAAAeTAAAH0wAAB6MAAAezAAAHowAAB+MAAAezAAAH4wAAB/MAAAejAAAH0wAACAMAAAejAAAIAwAAB+MAAAOzAAAIEwAAB4MAAAOzAAAHgwAAA8MAAAgTAAAIIwAAB5MAAAgTAAAHkwAAB4MAAAgjAAAIMwAAB8MAAAgjAAAHwwAAB5MAAAgzAAAIQwAACFMAAAgzAAAIUwAAB8MAAAfDAAAIUwAACGMAAAfDAAAIYwAAB9MAAAfTAAAIYwAACHMAAAfTAAAIcwAACAMAAAgDAAAIcwAACIMAAAgDAAAIgwAACJMAAAfjAAAIAwAACJMAAAfjAAAIkwAACKMAAAfzAAAH4wAACKMAAAfzAAAIowAACLMAAAPjAAAH8wAACLMAAAPjAAAIswAAA/MAAAPTAAAHswAAB/MAAAPTAAAH8wAAA+MAAAPDAAAHgwAAB7MAAAPDAAAHswAAA9MAAAjDAAAI0wAACOMAAAjDAAAI4wAACPMAAAjTAAAJAwAACRMAAAjTAAAJEwAACOMAAAjzAAAI4wAACSMAAAjzAAAJIwAACTMAAAjjAAAJEwAACUMAAAjjAAAJQwAACSMAAAoggAAM4IAACMMAAAoggAAIwwAACVMAAAzggAAMsIAACNMAAAzggAAI0wAACMMAAAywgAAMkIAACQMAAAywgAAJAwAACNMAAAyQgAAMgIAAAoMAAAyQgAACgwAACQMAAAkDAAACgwAAAwMAAAkDAAADAwAACRMAAAkTAAADAwAAAuMAAAkTAAAC4wAACUMAAAlDAAAC4wAAAvMAAAlDAAAC8wAACWMAAAkjAAAJQwAACWMAAAkjAAAJYwAACXMAAAkzAAAJIwAACXMAAAkzAAAJcwAACYMAAAmTAAAJMwAACYMAAAmTAAAJgwAACaMAAAmzAAAI8wAACTMAAAmzAAAJMwAACZMAAAlTAAAIwwAACPMAAAlTAAAI8wAACbMAAAnDAAAJ0wAACeMAAAnDAAAJ4wAACfMAAAnTAAAKAwAAChMAAAnTAAAKEwAACeMAAAnzAAAJ4wAACiMAAAnzAAAKIwAACjMAAAnjAAAKEwAACkMAAAnjAAAKQwAACiMAAAhDAAAJUKAACcMAAAhDAAAJwwAACFMAAAlQoAAJIKAACdMAAAlQoAAJ0wAACcMAAAkgoAAKUwAACgMAAAkgoAAKAwAACdMAAApTAAAKYwAACnMAAApTAAAKcwAACgMAAAoDAAAKcwAACoMAAAoDAAAKgwAAChMAAAoTAAAKgwAACpMAAAoTAAAKkwAACkMAAApDAAAKkwAACqMAAApDAAAKowAACrMAAAojAAAKQwAACrMAAAojAAAKswAACsMAAAozAAAKIwAACsMAAAozAAAKwwAACtMAAAhzAAAKMwAACtMAAAhzAAAK0wAACIMAAAhjAAAJ8wAACjMAAAhjAAAKMwAACHMAAAhTAAAJwwAACfMAAAhTAAAJ8wAACGMAAArjAAAK8wAACwMAAArjAAALAwAACxMAAArzAAALIwAACzMAAArzAAALMwAACwMAAAsTAAALAwAAC0MAAAsTAAALQwAAC1MAAAsDAAALMwAAC2MAAAsDAAALYwAAC0MAAA0gYAALcwAACuMAAA0gYAAK4wAAC4MAAAtzAAALkwAACvMAAAtzAAAK8wAACuMAAAuTAAALowAACyMAAAuTAAALIwAACvMAAAujAAAPcGAABNMAAAujAAAE0wAACyMAAAsjAAAE0wAABVMAAAsjAAAFUwAACzMAAAszAAAFUwAABTMAAAszAAAFMwAAC2MAAAtjAAAFMwAABUMAAAtjAAAFQwAAC7MAAAtDAAALYwAAC7MAAAtDAAALswAAC8MAAAtTAAALQwAAC8MAAAtTAAALwwAAC9MAAAvjAAALUwAAC9MAAAvjAAAL0wAAC/MAAAwDAAALEwAAC1MAAAwDAAALUwAAC+MAAAuDAAAK4wAACxMAAAuDAAALEwAADAMAAAwTAAAMIwAADDMAAAwTAAAMMwAADEMAAAwjAAAMUwAADGMAAAwjAAAMYwAADDMAAAxDAAAMMwAADHMAAAxDAAAMcwAADIMAAAwzAAAMYwAADJMAAAwzAAAMkwAADHMAAAuggAALwIAADBMAAAuggAAMEwAABgMAAAvAgAAMowAADCMAAAvAgAAMIwAADBMAAAyjAAAMswAADFMAAAyjAAAMUwAADCMAAAyzAAAJYIAADMMAAAyzAAAMwwAADFMAAAxTAAAMwwAADNMAAAxTAAAM0wAADGMAAAxjAAAM0wAADOMAAAxjAAAM4wAADJMAAAyTAAAM4wAADPMAAAyTAAAM8wAADQMAAAxzAAAMkwAADQMAAAxzAAANAwAADRMAAAyDAAAMcwAADRMAAAyDAAANEwAADSMAAAYjAAAMgwAADSMAAAYjAAANIwAABjMAAAYTAAAMQwAADIMAAAYTAAAMgwAABiMAAAYDAAAMEwAADEMAAAYDAAAMQwAABhMAAA0zAAANQwAADVMAAA0zAAANUwAADWMAAA1DAAANcwAADYMAAA1DAAANgwAADVMAAA1jAAANUwAADZMAAA1jAAANkwAADaMAAA1TAAANgwAADbMAAA1TAAANswAADZMAAA6gYAAOwGAADTMAAA6gYAANMwAABxMAAA7AYAANwwAADUMAAA7AYAANQwAADTMAAA3DAAAN0wAADXMAAA3DAAANcwAADUMAAA3TAAAMQGAADeMAAA3TAAAN4wAADXMAAA1zAAAN4wAADfMAAA1zAAAN8wAADYMAAA2DAAAN8wAADgMAAA2DAAAOAwAADbMAAA2zAAAOAwAADhMAAA2zAAAOEwAADiMAAA2TAAANswAADiMAAA2TAAAOIwAADjMAAA2jAAANkwAADjMAAA2jAAAOMwAADkMAAAczAAANowAADkMAAAczAAAOQwAAB0MAAAcjAAANYwAADaMAAAcjAAANowAABzMAAAcTAAANMwAADWMAAAcTAAANYwAAByMAAA5TAAAOYwAADnMAAA5TAAAOcwAADoMAAA5jAAAOkwAADqMAAA5jAAAOowAADnMAAA6DAAAOcwAADrMAAA6DAAAOswAADsMAAA5zAAAOowAADtMAAA5zAAAO0wAADrMAAApjAAAO4wAADlMAAApjAAAOUwAACnMAAA7jAAAH8KAADmMAAA7jAAAOYwAADlMAAAfwoAAO8wAADpMAAAfwoAAOkwAADmMAAA7zAAAPAwAADxMAAA7zAAAPEwAADpMAAA6TAAAPEwAADyMAAA6TAAAPIwAADqMAAA6jAAAPIwAADzMAAA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8DAAAD0xAADxMAAARjEAAHAKAAA+MQAARjEAAD4xAAA9MQAAcAoAAEcxAABBMQAAcAoAAEExAAA+MQAARzEAAEUKAABIMQAARzEAAEgxAABBMQAAQTEAAEgxAABJMQAAQTEAAEkxAABCMQAAQjEAAEkxAABKMQAAQjEAAEoxAABFMQAARTEAAEoxAABLMQAARTEAAEsxAABMMQAAQzEAAEUxAABMMQAAQzEAAEwxAABNMQAARDEAAEMxAABNMQAARDEAAE0xAABOMQAA8zAAAEQxAABOMQAA8zAAAE4xAAD0MAAA8jAAAEAxAABEMQAA8jAAAEQxAADzMAAA8TAAAD0xAABAMQAA8TAAAEAxAADyMAAATzEAAFAxAABRMQAATzEAAFExAABSMQAAUDEAAFMxAABUMQAAUDEAAFQxAABRMQAAUjEAAFExAABVMQAAUjEAAFUxAABWMQAAUTEAAFQxAABXMQAAUTEAAFcxAABVMQAArQYAAFgxAABPMQAArQYAAE8xAABZMQAAWDEAAFoxAABQMQAAWDEAAFAxAABPMQAAWjEAAFsxAABTMQAAWjEAAFMxAABQMQAAWzEAANIGAAC4MAAAWzEAALgwAABTMQAAUzEAALgwAADAMAAAUzEAAMAwAABUMQAAVDEAAMAwAAC+MAAAVDEAAL4wAABXMQAAVzEAAL4wAAC/MAAAVzEAAL8wAABcMQAAVTEAAFcxAABcMQAAVTEAAFwxAABdMQAAVjEAAFUxAABdMQAAVjEAAF0xAABeMQAAXzEAAFYxAABeMQAAXzEAAF4xAABgMQAAYTEAAFIxAABWMQAAYTEAAFYxAABfMQAAWTEAAE8xAABSMQAAWTEAAFIxAABhMQAAYjEAAGMxAABkMQAAYjEAAGQxAABlMQAAYzEAAGYxAABnMQAAYzEAAGcxAABkMQAAZTEAAGQxAABoMQAAZTEAAGgxAABpMQAAZDEAAGcxAABqMQAAZDEAAGoxAABoMQAAlggAAJgIAABiMQAAlggAAGIxAADMMAAAmAgAAJUIAABjMQAAmAgAAGMxAABiMQAAlQgAAGsxAABmMQAAlQgAAGYxAABjMQAAazEAAHEIAABsMQAAazEAAGwxAABmMQAAZjEAAGwxAABtMQAAZjEAAG0xAABnMQAAZzEAAG0xAABuMQAAZzEAAG4xAABqMQAAajEAAG4xAABvMQAAajEAAG8xAABwMQAAaDEAAGoxAABwMQAAaDEAAHAxAABxMQAAaTEAAGgxAABxMQAAaTEAAHExAAByMQAAzjAAAGkxAAByMQAAzjAAAHIxAADPMAAAzTAAAGUxAABpMQAAzTAAAGkxAADOMAAAzDAAAGIxAABlMQAAzDAAAGUxAADNMAAAczEAAHQxAAB1MQAAczEAAHUxAAB2MQAAdDEAAHcxAAB4MQAAdDEAAHgxAAB1MQAAdjEAAHUxAAB5MQAAdjEAAHkxAAB6MQAAdTEAAHgxAAB7MQAAdTEAAHsxAAB5MQAAEgEAAHwxAABzMQAAEgEAAHMxAAB9MQAAfDEAADgBAAB0MQAAfDEAAHQxAABzMQAAOAEAAH4xAAB3MQAAOAEAAHcxAAB0MQAAfjEAADUBAAAmLgAAfjEAACYuAAB3MQAAdzEAACYuAAAxLgAAdzEAADEuAAB4MQAAeDEAADEuAAAvLgAAeDEAAC8uAAB7MQAAezEAAC8uAAAwLgAAezEAADAuAAB/MQAAeTEAAHsxAAB/MQAAeTEAAH8xAACAMQAAejEAAHkxAACAMQAAejEAAIAxAACBMQAAgjEAAHoxAACBMQAAgjEAAIExAACDMQAAhDEAAHYxAAB6MQAAhDEAAHoxAACCMQAAfTEAAHMxAAB2MQAAfTEAAHYxAACEMQAAhTEAAIYxAACHMQAAhTEAAIcxAACIMQAAhjEAAIkxAACKMQAAhjEAAIoxAACHMQAAiDEAAIcxAACLMQAAiDEAAIsxAACMMQAAhzEAAIoxAACNMQAAhzEAAI0xAACLMQAAxAYAAI4xAACFMQAAxAYAAIUxAADeMAAAjjEAAMcGAACGMQAAjjEAAIYxAACFMQAAxwYAAI8xAACJMQAAxwYAAIkxAACGMQAAjzEAAJ8GAACQMQAAjzEAAJAxAACJMQAAiTEAAJAxAACRMQAAiTEAAJExAACKMQAAijEAAJExAACSMQAAijEAAJIxAACNMQAAjTEAAJIxAACTMQAAjTEAAJMxAACUMQAAizEAAI0xAACUMQAAizEAAJQxAACVMQAAjDEAAIsxAACVMQAAjDEAAJUxAACWMQAA4DAAAIwxAACWMQAA4DAAAJYxAADhMAAA3zAAAIgxAACMMQAA3zAAAIwxAADgMAAA3jAAAIUxAACIMQAA3jAAAIgxAADfMAAAlzEAAJgxAACZMQAAlzEAAJkxAACaMQAAmDEAAJsxAACcMQAAmDEAAJwxAACZMQAAmjEAAJkxAACdMQAAmjEAAJ0xAACeMQAAmTEAAJwxAACfMQAAmTEAAJ8xAACdMQAAKgEAAKAxAACXMQAAKgEAAJcxAABwLgAAoDEAAC0BAACYMQAAoDEAAJgxAACXMQAALQEAACcBAACbMQAALQEAAJsxAACYMQAAJwEAAAcBAAChMQAAJwEAAKExAACbMQAAmzEAAKExAACiMQAAmzEAAKIxAACcMQAAnDEAAKIxAACjMQAAnDEAAKMxAACfMQAAnzEAAKMxAACkMQAAnzEAAKQxAAClMQAAnTEAAJ8xAAClMQAAnTEAAKUxAACmMQAAnjEAAJ0xAACmMQAAnjEAAKYxAACnMQAAci4AAJ4xAACnMQAAci4AAKcxAABzLgAAcS4AAJoxAACeMQAAcS4AAJ4xAAByLgAAcC4AAJcxAACaMQAAcC4AAJoxAABxLgAAqDEAAKkxAACqMQAAqDEAAKoxAACrMQAAqTEAAKwxAACtMQAAqTEAAK0xAACqMQAAqzEAAKoxAACuMQAAqzEAAK4xAACvMQAAqjEAAK0xAACwMQAAqjEAALAxAACuMQAALgoAAFoKAACoMQAALgoAAKgxAACxMQAAWgoAAFcKAACpMQAAWgoAAKkxAACoMQAAVwoAAFUKAACsMQAAVwoAAKwxAACpMQAAVQoAAFQKAADNLgAAVQoAAM0uAACsMQAArDEAAM0uAADTLgAArDEAANMuAACtMQAArTEAANMuAADRLgAArTEAANEuAACwMQAAsDEAANEuAADSLgAAsDEAANIuAACyMQAArjEAALAxAACyMQAArjEAALIxAACzMQAArzEAAK4xAACzMQAArzEAALMxAAC0MQAAtTEAAK8xAAC0MQAAtTEAALQxAAC2MQAAtzEAAKsxAACvMQAAtzEAAK8xAAC1MQAAsTEAAKgxAACrMQAAsTEAAKsxAAC3MQAAuDEAALkxAAC6MQAAuDEAALoxAAC7MQAAuTEAALwxAAC9MQAAuTEAAL0xAAC6MQAAuzEAALoxAAC+MQAAuzEAAL4xAAC/MQAAujEAAL0xAADAMQAAujEAAMAxAAC+MQAAWwgAAMExAAC4MQAAWwgAALgxAADCMQAAwTEAAIEIAAC5MQAAwTEAALkxAAC4MQAAgQgAAMMxAAC8MQAAgQgAALwxAAC5MQAAwzEAAH4IAAA1MQAAwzEAADUxAAC8MQAAvDEAADUxAAA8MQAAvDEAADwxAAC9MQAAvTEAADwxAAA6MQAAvTEAADoxAADAMQAAwDEAADoxAAA7MQAAwDEAADsxAADEMQAAvjEAAMAxAADEMQAAvjEAAMQxAADFMQAAvzEAAL4xAADFMQAAvzEAAMUxAADGMQAAxzEAAL8xAADGMQAAxzEAAMYxAADIMQAAyTEAALsxAAC/MQAAyTEAAL8xAADHMQAAwjEAALgxAAC7MQAAwjEAALsxAADJMQAAyjEAAMsxAADMMQAAyjEAAMwxAADNMQAAyzEAAM4xAADPMQAAyzEAAM8xAADMMQAAzTEAAMwxAADQMQAAzTEAANAxAADRMQAAzDEAAM8xAADSMQAAzDEAANIxAADQMQAARQoAANMxAADKMQAARQoAAMoxAABIMQAA0zEAAEQKAADLMQAA0zEAAMsxAADKMQAARAoAANQxAADOMQAARAoAAM4xAADLMQAA1DEAACIKAADVMQAA1DEAANUxAADOMQAAzjEAANUxAADWMQAAzjEAANYxAADPMQAAzzEAANYxAADXMQAAzzEAANcxAADSMQAA0jEAANcxAADYMQAA0jEAANgxAADZMQAA0DEAANIxAADZMQAA0DEAANkxAADaMQAA0TEAANAxAADaMQAA0TEAANoxAADbMQAASjEAANExAADbMQAASjEAANsxAABLMQAASTEAAM0xAADRMQAASTEAANExAABKMQAASDEAAMoxAADNMQAASDEAAM0xAABJMQAA3DEAAN0xAADeMQAA3DEAAN4xAADfMQAA3TEAAOAxAADhMQAA3TEAAOExAADeMQAA3zEAAN4xAADiMQAA3zEAAOIxAADjMQAA3jEAAOExAADkMQAA3jEAAOQxAADiMQAAhgYAAOUxAADcMQAAhgYAANwxAADmMQAA5TEAALAGAADdMQAA5TEAAN0xAADcMQAAsAYAAOcxAADgMQAAsAYAAOAxAADdMQAA5zEAAK0GAABZMQAA5zEAAFkxAADgMQAA4DEAAFkxAABhMQAA4DEAAGExAADhMQAA4TEAAGExAABfMQAA4TEAAF8xAADkMQAA5DEAAF8xAABgMQAA5DEAAGAxAADoMQAA4jEAAOQxAADoMQAA4jEAAOgxAADpMQAA4zEAAOIxAADpMQAA4zEAAOkxAADqMQAA6zEAAOMxAADqMQAA6zEAAOoxAADsMQAA7TEAAN8xAADjMQAA7TEAAOMxAADrMQAA5jEAANwxAADfMQAA5jEAAN8xAADtMQAA7jEAAO8xAADwMQAA7jEAAPAxAADxMQAA7zEAAPIxAADzMQAA7zEAAPMxAADwMQAA8TEAAPAxAAD0MQAA8TEAAPQxAAD1MQAA8DEAAPMxAAD2MQAA8DEAAPYxAAD0MQAAcQgAAPcxAADuMQAAcQgAAO4xAABsMQAA9zEAAHQIAADvMQAA9zEAAO8xAADuMQAAdAgAAG8IAADyMQAAdAgAAPIxAADvMQAAbwgAAE8IAAD4MQAAbwgAAPgxAADyMQAA8jEAAPgxAAD5MQAA8jEAAPkxAADzMQAA8zEAAPkxAAD6MQAA8zEAAPoxAAD2MQAA9jEAAPoxAAD7MQAA9jEAAPsxAAD8MQAA9DEAAPYxAAD8MQAA9DEAAPwxAAD9MQAA9TEAAPQxAAD9MQAA9TEAAP0xAAD+MQAAbjEAAPUxAAD+MQAAbjEAAP4xAABvMQAAbTEAAPExAAD1MQAAbTEAAPUxAABuMQAAbDEAAO4xAADxMQAAbDEAAPExAABtMQAA/zEAAAAyAAABMgAA/zEAAAEyAAACMgAAADIAAAMyAAAEMgAAADIAAAQyAAABMgAAAjIAAAEyAAAFMgAAAjIAAAUyAAAGMgAAATIAAAQyAAAHMgAAATIAAAcyAAAFMgAA8QAAAAgyAAD/MQAA8QAAAP8xAAAJMgAACDIAABkBAAAAMgAACDIAAAAyAAD/MQAAGQEAAAoyAAADMgAAGQEAAAMyAAAAMgAACjIAABIBAAB9MQAACjIAAH0xAAADMgAAAzIAAH0xAACEMQAAAzIAAIQxAAAEMgAABDIAAIQxAACCMQAABDIAAIIxAAAHMgAABzIAAIIxAACDMQAABzIAAIMxAAALMgAABTIAAAcyAAALMgAABTIAAAsyAAAMMgAABjIAAAUyAAAMMgAABjIAAAwyAAANMgAADjIAAAYyAAANMgAADjIAAA0yAAAPMgAAEDIAAAIyAAAGMgAAEDIAAAYyAAAOMgAACTIAAP8xAAACMgAACTIAAAIyAAAQMgAAETIAABIyAAATMgAAETIAABMyAAAUMgAAEjIAABUyAAAWMgAAEjIAABYyAAATMgAAFDIAABMyAAAXMgAAFDIAABcyAAAYMgAAEzIAABYyAAAZMgAAEzIAABkyAAAXMgAAnwYAABoyAAARMgAAnwYAABEyAACQMQAAGjIAAKMGAAASMgAAGjIAABIyAAARMgAAowYAABsyAAAVMgAAowYAABUyAAASMgAAGzIAAHoGAAAcMgAAGzIAABwyAAAVMgAAFTIAABwyAAAdMgAAFTIAAB0yAAAWMgAAFjIAAB0yAAAeMgAAFjIAAB4yAAAZMgAAGTIAAB4yAAAfMgAAGTIAAB8yAAAgMgAAFzIAABkyAAAgMgAAFzIAACAyAAAhMgAAGDIAABcyAAAhMgAAGDIAACEyAAAiMgAAkjEAABgyAAAiMgAAkjEAACIyAACTMQAAkTEAABQyAAAYMgAAkTEAABgyAACSMQAAkDEAABEyAAAUMgAAkDEAABQyAACRMQAAIzIAACQyAAAlMgAAIzIAACUyAAAmMgAAJDIAACcyAAAoMgAAJDIAACgyAAAlMgAAJjIAACUyAAApMgAAJjIAACkyAAAqMgAAJTIAACgyAAArMgAAJTIAACsyAAApMgAATwQAACwyAAAjMgAATwQAACMyAAB/LAAALDIAAMAEAAAkMgAALDIAACQyAAAjMgAAwAQAAL4EAAAnMgAAwAQAACcyAAAkMgAAvgQAAL0EAAAGMAAAvgQAAAYwAAAnMgAAJzIAAAYwAAANMAAAJzIAAA0wAAAoMgAAKDIAAA0wAAALMAAAKDIAAAswAAArMgAAKzIAAAswAAAMMAAAKzIAAAwwAAAtMgAAKTIAACsyAAAtMgAAKTIAAC0yAAAuMgAAKjIAACkyAAAuMgAAKjIAAC4yAAAvMgAAgSwAACoyAAAvMgAAgSwAAC8yAACCLAAAgCwAACYyAAAqMgAAgCwAACoyAACBLAAAfywAACMyAAAmMgAAfywAACYyAACALAAAMDIAADEyAAAyMgAAMDIAADIyAAAzMgAAMTIAADQyAAA1MgAAMTIAADUyAAAyMgAAMzIAADIyAAA2MgAAMzIAADYyAAA3MgAAMjIAADUyAAA4MgAAMjIAADgyAAA2MgAABwEAADkyAAAwMgAABwEAADAyAAChMQAAOTIAADoyAAAxMgAAOTIAADEyAAAwMgAAOjIAADsyAAA0MgAAOjIAADQyAAAxMgAAOzIAAOIAAAA8MgAAOzIAADwyAAA0MgAANDIAADwyAAA9MgAANDIAAD0yAAA1MgAANTIAAD0yAAA+MgAANTIAAD4yAAA4MgAAODIAAD4yAAA/MgAAODIAAD8yAABAMgAANjIAADgyAABAMgAANjIAAEAyAABBMgAANzIAADYyAABBMgAANzIAAEEyAABCMgAAozEAADcyAABCMgAAozEAAEIyAACkMQAAojEAADMyAAA3MgAAojEAADcyAACjMQAAoTEAADAyAAAzMgAAoTEAADMyAACiMQAAQzIAAEQyAABFMgAAQzIAAEUyAABGMgAARDIAAEcyAABIMgAARDIAAEgyAABFMgAARjIAAEUyAABJMgAARjIAAEkyAABKMgAARTIAAEgyAABLMgAARTIAAEsyAABJMgAADAoAADQKAABDMgAADAoAAEMyAABMMgAANAoAAE0yAABEMgAANAoAAEQyAABDMgAATTIAAC8KAABHMgAATTIAAEcyAABEMgAALwoAAC4KAACxMQAALwoAALExAABHMgAARzIAALExAAC3MQAARzIAALcxAABIMgAASDIAALcxAAC1MQAASDIAALUxAABLMgAASzIAALUxAAC2MQAASzIAALYxAABOMgAASTIAAEsyAABOMgAASTIAAE4yAABPMgAASjIAAEkyAABPMgAASjIAAE8yAABQMgAAUTIAAEoyAABQMgAAUTIAAFAyAABSMgAAUzIAAEYyAABKMgAAUzIAAEoyAABRMgAATDIAAEMyAABGMgAATDIAAEYyAABTMgAAVDIAAFUyAABWMgAAVDIAAFYyAABXMgAAVTIAAFgyAABZMgAAVTIAAFkyAABWMgAAVzIAAFYyAABaMgAAVzIAAFoyAABbMgAAVjIAAFkyAABcMgAAVjIAAFwyAABaMgAAOggAAGAIAABUMgAAOggAAFQyAABdMgAAYAgAAF4IAABVMgAAYAgAAFUyAABUMgAAXggAAFwIAABYMgAAXggAAFgyAABVMgAAXAgAAFsIAADCMQAAXAgAAMIxAABYMgAAWDIAAMIxAADJMQAAWDIAAMkxAABZMgAAWTIAAMkxAADHMQAAWTIAAMcxAABcMgAAXDIAAMcxAADIMQAAXDIAAMgxAABeMgAAWjIAAFwyAABeMgAAWjIAAF4yAABfMgAAWzIAAFoyAABfMgAAWzIAAF8yAABgMgAAYTIAAFsyAABgMgAAYTIAAGAyAABiMgAAYzIAAFcyAABbMgAAYzIAAFsyAABhMgAAXTIAAFQyAABXMgAAXTIAAFcyAABjMgAAZDIAAGUyAABmMgAAZDIAAGYyAABnMgAAZTIAAGgyAABpMgAAZTIAAGkyAABmMgAAZzIAAGYyAABqMgAAZzIAAGoyAABrMgAAZjIAAGkyAABsMgAAZjIAAGwyAABqMgAAIgoAACQKAABkMgAAIgoAAGQyAADVMQAAJAoAACEKAABlMgAAJAoAAGUyAABkMgAAIQoAAG0yAABoMgAAIQoAAGgyAABlMgAAbTIAAP8JAABuMgAAbTIAAG4yAABoMgAAaDIAAG4yAABvMgAAaDIAAG8yAABpMgAAaTIAAG8yAABwMgAAaTIAAHAyAABsMgAAbDIAAHAyAABxMgAAbDIAAHEyAAByMgAAajIAAGwyAAByMgAAajIAAHIyAABzMgAAazIAAGoyAABzMgAAazIAAHMyAAB0MgAA1zEAAGsyAAB0MgAA1zEAAHQyAADYMQAA1jEAAGcyAABrMgAA1jEAAGsyAADXMQAA1TEAAGQyAABnMgAA1TEAAGcyAADWMQAAdTIAAHYyAAB3MgAAdTIAAHcyAAB4MgAAdjIAAHkyAAB6MgAAdjIAAHoyAAB3MgAAeDIAAHcyAAB7MgAAeDIAAHsyAAB8MgAAdzIAAHoyAAB9MgAAdzIAAH0yAAB7MgAAZQYAAH4yAAB1MgAAZQYAAHUyAAB/MgAAfjIAAIAyAAB2MgAAfjIAAHYyAAB1MgAAgDIAAIEyAAB5MgAAgDIAAHkyAAB2MgAAgTIAAIYGAADmMQAAgTIAAOYxAAB5MgAAeTIAAOYxAADtMQAAeTIAAO0xAAB6MgAAejIAAO0xAADrMQAAejIAAOsxAAB9MgAAfTIAAOsxAADsMQAAfTIAAOwxAACCMgAAezIAAH0yAACCMgAAezIAAIIyAACDMgAAfDIAAHsyAACDMgAAfDIAAIMyAACEMgAAhTIAAHwyAACEMgAAhTIAAIQyAACGMgAAhzIAAHgyAAB8MgAAhzIAAHwyAACFMgAAfzIAAHUyAAB4MgAAfzIAAHgyAACHMgAAiDIAAIkyAACKMgAAiDIAAIoyAACLMgAAiTIAAIwyAACNMgAAiTIAAI0yAACKMgAAizIAAIoyAACOMgAAizIAAI4yAACPMgAAijIAAI0yAACQMgAAijIAAJAyAACOMgAATwgAAJEyAACIMgAATwgAAIgyAAD4MQAAkTIAAE4IAACJMgAAkTIAAIkyAACIMgAATggAAJIyAACMMgAATggAAIwyAACJMgAAkjIAAC4IAACTMgAAkjIAAJMyAACMMgAAjDIAAJMyAACUMgAAjDIAAJQyAACNMgAAjTIAAJQyAACVMgAAjTIAAJUyAACQMgAAkDIAAJUyAACWMgAAkDIAAJYyAACXMgAAjjIAAJAyAACXMgAAjjIAAJcyAACYMgAAjzIAAI4yAACYMgAAjzIAAJgyAACZMgAA+jEAAI8yAACZMgAA+jEAAJkyAAD7MQAA+TEAAIsyAACPMgAA+TEAAI8yAAD6MQAA+DEAAIgyAACLMgAA+DEAAIsyAAD5MQAAmjIAAJsyAACcMgAAmjIAAJwyAACdMgAAmzIAAJ4yAACfMgAAmzIAAJ8yAACcMgAAnTIAAJwyAACgMgAAnTIAAKAyAAChMgAAnDIAAJ8yAACiMgAAnDIAAKIyAACgMgAAzAAAAPYAAACaMgAAzAAAAJoyAACjMgAA9gAAAPQAAACbMgAA9gAAAJsyAACaMgAA9AAAAPIAAACeMgAA9AAAAJ4yAACbMgAA8gAAAPEAAAAJMgAA8gAAAAkyAACeMgAAnjIAAAkyAAAQMgAAnjIAABAyAACfMgAAnzIAABAyAAAOMgAAnzIAAA4yAACiMgAAojIAAA4yAAAPMgAAojIAAA8yAACkMgAAoDIAAKIyAACkMgAAoDIAAKQyAAClMgAAoTIAAKAyAAClMgAAoTIAAKUyAACmMgAApzIAAKEyAACmMgAApzIAAKYyAACoMgAAqTIAAJ0yAAChMgAAqTIAAKEyAACnMgAAozIAAJoyAACdMgAAozIAAJ0yAACpMgAAqjIAAKsyAACsMgAAqjIAAKwyAACtMgAAqzIAAK4yAACvMgAAqzIAAK8yAACsMgAArTIAAKwyAACwMgAArTIAALAyAACxMgAArDIAAK8yAACyMgAArDIAALIyAACwMgAAegYAAHwGAACqMgAAegYAAKoyAAAcMgAAfAYAAHkGAACrMgAAfAYAAKsyAACqMgAAeQYAAHcGAACuMgAAeQYAAK4yAACrMgAAdwYAAFgGAACzMgAAdwYAALMyAACuMgAArjIAALMyAAC0MgAArjIAALQyAACvMgAArzIAALQyAAC1MgAArzIAALUyAACyMgAAsjIAALUyAAC2MgAAsjIAALYyAAC3MgAAsDIAALIyAAC3MgAAsDIAALcyAAC4MgAAsTIAALAyAAC4MgAAsTIAALgyAAC5MgAAHjIAALEyAAC5MgAAHjIAALkyAAAfMgAAHTIAAK0yAACxMgAAHTIAALEyAAAeMgAAHDIAAKoyAACtMgAAHDIAAK0yAAAdMgAAujIAALsyAAC8MgAAujIAALwyAAC9MgAAuzIAAL4yAAC/MgAAuzIAAL8yAAC8MgAAvTIAALwyAADAMgAAvTIAAMAyAADBMgAAvDIAAL8yAADCMgAAvDIAAMIyAADAMgAA4gAAAOQAAAC6MgAA4gAAALoyAAA8MgAA5AAAAOEAAAC7MgAA5AAAALsyAAC6MgAA4QAAAMMyAAC+MgAA4QAAAL4yAAC7MgAAwzIAAMAAAADEMgAAwzIAAMQyAAC+MgAAvjIAAMQyAADFMgAAvjIAAMUyAAC/MgAAvzIAAMUyAADGMgAAvzIAAMYyAADCMgAAwjIAAMYyAADHMgAAwjIAAMcyAADIMgAAwDIAAMIyAADIMgAAwDIAAMgyAADJMgAAwTIAAMAyAADJMgAAwTIAAMkyAADKMgAAPjIAAMEyAADKMgAAPjIAAMoyAAA/MgAAPTIAAL0yAADBMgAAPTIAAMEyAAA+MgAAPDIAALoyAAC9MgAAPDIAAL0yAAA9MgAAyzIAAMwyAADNMgAAyzIAAM0yAADOMgAAzDIAAM8yAADQMgAAzDIAANAyAADNMgAAzjIAAM0yAADRMgAAzjIAANEyAADSMgAAzTIAANAyAADTMgAAzTIAANMyAADRMgAAjAQAAI4EAADLMgAAjAQAAMsyAAAUMQAAjgQAANQyAADMMgAAjgQAAMwyAADLMgAA1DIAANUyAADPMgAA1DIAAM8yAADMMgAA1TIAAEIEAACmLAAA1TIAAKYsAADPMgAAzzIAAKYsAACxLAAAzzIAALEsAADQMgAA0DIAALEsAACvLAAA0DIAAK8sAADTMgAA0zIAAK8sAACwLAAA0zIAALAsAADWMgAA0TIAANMyAADWMgAA0TIAANYyAADXMgAA0jIAANEyAADXMgAA0jIAANcyAADYMgAAFjEAANIyAADYMgAAFjEAANgyAAAXMQAAFTEAAM4yAADSMgAAFTEAANIyAAAWMQAAFDEAAMsyAADOMgAAFDEAAM4yAAAVMQAA2TIAANoyAADbMgAA2TIAANsyAADcMgAA2jIAAN0yAADeMgAA2jIAAN4yAADbMgAA3DIAANsyAADfMgAA3DIAAN8yAADgMgAA2zIAAN4yAADhMgAA2zIAAOEyAADfMgAA5gkAAOIyAADZMgAA5gkAANkyAADjMgAA4jIAAOQyAADaMgAA4jIAANoyAADZMgAA5DIAAOUyAADdMgAA5DIAAN0yAADaMgAA5TIAAAwKAABMMgAA5TIAAEwyAADdMgAA3TIAAEwyAABTMgAA3TIAAFMyAADeMgAA3jIAAFMyAABRMgAA3jIAAFEyAADhMgAA4TIAAFEyAABSMgAA4TIAAFIyAADmMgAA3zIAAOEyAADmMgAA3zIAAOYyAADnMgAA4DIAAN8yAADnMgAA4DIAAOcyAADoMgAA6TIAAOAyAADoMgAA6TIAAOgyAADqMgAA6zIAANwyAADgMgAA6zIAAOAyAADpMgAA4zIAANkyAADcMgAA4zIAANwyAADrMgAA7DIAAO0yAADuMgAA7DIAAO4yAADvMgAA7TIAAPAyAADxMgAA7TIAAPEyAADuMgAA7zIAAO4yAADyMgAA7zIAAPIyAADzMgAA7jIAAPEyAAD0MgAA7jIAAPQyAADyMgAAFwgAAEAIAADsMgAAFwgAAOwyAAD1MgAAQAgAAEEIAADtMgAAQAgAAO0yAADsMgAAQQgAADsIAADwMgAAQQgAAPAyAADtMgAAOwgAADoIAABdMgAAOwgAAF0yAADwMgAA8DIAAF0yAABjMgAA8DIAAGMyAADxMgAA8TIAAGMyAABhMgAA8TIAAGEyAAD0MgAA9DIAAGEyAABiMgAA9DIAAGIyAAD2MgAA8jIAAPQyAAD2MgAA8jIAAPYyAAD3MgAA8zIAAPIyAAD3MgAA8zIAAPcyAAD4MgAA+TIAAPMyAAD4MgAA+TIAAPgyAAD6MgAA+zIAAO8yAADzMgAA+zIAAPMyAAD5MgAA9TIAAOwyAADvMgAA9TIAAO8yAAD7MgAA/DIAAP0yAAD+MgAA/DIAAP4yAAD/MgAA/TIAAAAzAAABMwAA/TIAAAEzAAD+MgAA/zIAAP4yAAACMwAA/zIAAAIzAAADMwAA/jIAAAEzAAAEMwAA/jIAAAQzAAACMwAA/wkAAAEKAAD8MgAA/wkAAPwyAABuMgAAAQoAAP4JAAD9MgAAAQoAAP0yAAD8MgAA/gkAAAUzAAAAMwAA/gkAAAAzAAD9MgAABTMAANsJAAAGMwAABTMAAAYzAAAAMwAAADMAAAYzAAAHMwAAADMAAAczAAABMwAAATMAAAczAAAIMwAAATMAAAgzAAAEMwAABDMAAAgzAAAJMwAABDMAAAkzAAAKMwAAAjMAAAQzAAAKMwAAAjMAAAozAAALMwAAAzMAAAIzAAALMwAAAzMAAAszAAAMMwAAcDIAAAMzAAAMMwAAcDIAAAwzAABxMgAAbzIAAP8yAAADMwAAbzIAAAMzAABwMgAAbjIAAPwyAAD/MgAAbjIAAP8yAABvMgAADTMAAA4zAAAPMwAADTMAAA8zAAAQMwAADjMAABEzAAASMwAADjMAABIzAAAPMwAAEDMAAA8zAAATMwAAEDMAABMzAAAUMwAADzMAABIzAAAVMwAADzMAABUzAAATMwAAPwYAAGoGAAANMwAAPwYAAA0zAAAtLAAAagYAAGsGAAAOMwAAagYAAA4zAAANMwAAawYAABYzAAARMwAAawYAABEzAAAOMwAAFjMAAGUGAAB/MgAAFjMAAH8yAAARMwAAETMAAH8yAACHMgAAETMAAIcyAAASMwAAEjMAAIcyAACFMgAAEjMAAIUyAAAVMwAAFTMAAIUyAACGMgAAFTMAAIYyAAAXMwAAEzMAABUzAAAXMwAAEzMAABczAAAYMwAAFDMAABMzAAAYMwAAFDMAABgzAAAZMwAALywAABQzAAAZMwAALywAABkzAAAwLAAALiwAABAzAAAUMwAALiwAABQzAAAvLAAALSwAAA0zAAAQMwAALSwAABAzAAAuLAAAGjMAABszAAAcMwAAGjMAABwzAAAdMwAAGzMAAB4zAAAfMwAAGzMAAB8zAAAcMwAAHTMAABwzAAAgMwAAHTMAACAzAAAhMwAAHDMAAB8zAAAiMwAAHDMAACIzAAAgMwAALggAADAIAAAaMwAALggAABozAACTMgAAMAgAAC0IAAAbMwAAMAgAABszAAAaMwAALQgAACMzAAAeMwAALQgAAB4zAAAbMwAAIzMAAAsIAABALAAAIzMAAEAsAAAeMwAAHjMAAEAsAABLLAAAHjMAAEssAAAfMwAAHzMAAEssAABJLAAAHzMAAEksAAAiMwAAIjMAAEksAABKLAAAIjMAAEosAAAkMwAAIDMAACIzAAAkMwAAIDMAACQzAAAlMwAAITMAACAzAAAlMwAAITMAACUzAAAmMwAAlTIAACEzAAAmMwAAlTIAACYzAACWMgAAlDIAAB0zAAAhMwAAlDIAACEzAACVMgAAkzIAABozAAAdMwAAkzIAAB0zAACUMgAAJzMAACgzAAApMwAAJzMAACkzAAAqMwAAKDMAACszAAAsMwAAKDMAACwzAAApMwAAKjMAACkzAAAtMwAAKjMAAC0zAAAuMwAAKTMAACwzAAAvMwAAKTMAAC8zAAAtMwAAqwAAADAzAAAnMwAAqwAAACczAABWLAAAMDMAADEzAAAoMwAAMDMAACgzAAAnMwAAMTMAADIzAAArMwAAMTMAACszAAAoMwAAMjMAAMwAAACjMgAAMjMAAKMyAAArMwAAKzMAAKMyAACpMgAAKzMAAKkyAAAsMwAALDMAAKkyAACnMgAALDMAAKcyAAAvMwAALzMAAKcyAACoMgAALzMAAKgyAAAzMwAALTMAAC8zAAAzMwAALTMAADMzAAA0MwAALjMAAC0zAAA0MwAALjMAADQzAAA1MwAAWCwAAC4zAAA1MwAAWCwAADUzAABZLAAAVywAACozAAAuMwAAVywAAC4zAABYLAAAViwAACczAAAqMwAAViwAACozAABXLAAANjMAADczAAA4MwAANjMAADgzAAA5MwAANzMAADozAAA7MwAANzMAADszAAA4MwAAOTMAADgzAAA8MwAAOTMAADwzAAA9MwAAODMAADszAAA+MwAAODMAAD4zAAA8MwAAWAYAAFoGAAA2MwAAWAYAADYzAACzMgAAWgYAAD8zAAA3MwAAWgYAADczAAA2MwAAPzMAAFUGAAA6MwAAPzMAADozAAA3MwAAVQYAADIGAABpLAAAVQYAAGksAAA6MwAAOjMAAGksAABzLAAAOjMAAHMsAAA7MwAAOzMAAHMsAABxLAAAOzMAAHEsAAA+MwAAPjMAAHEsAAByLAAAPjMAAHIsAABAMwAAPDMAAD4zAABAMwAAPDMAAEAzAABBMwAAPTMAADwzAABBMwAAPTMAAEEzAABCMwAAtTIAAD0zAABCMwAAtTIAAEIzAAC2MgAAtDIAADkzAAA9MwAAtDIAAD0zAAC1MgAAszIAADYzAAA5MwAAszIAADkzAAC0MgAAQzMAAEQzAABFMwAAQzMAAEUzAABGMwAARDMAAEczAABIMwAARDMAAEgzAABFMwAARjMAAEUzAABJMwAARjMAAEkzAABKMwAARTMAAEgzAABLMwAARTMAAEszAABJMwAAwAAAAMIAAABDMwAAwAAAAEMzAADEMgAAwgAAAL8AAABEMwAAwgAAAEQzAABDMwAAvwAAAEwzAABHMwAAvwAAAEczAABEMwAATDMAAJ8AAACSLAAATDMAAJIsAABHMwAARzMAAJIsAACcLAAARzMAAJwsAABIMwAASDMAAJwsAACaLAAASDMAAJosAABLMwAASzMAAJosAACbLAAASzMAAJssAABNMwAASTMAAEszAABNMwAASTMAAE0zAABOMwAASjMAAEkzAABOMwAASjMAAE4zAABPMwAAxjIAAEozAABPMwAAxjIAAE8zAADHMgAAxTIAAEYzAABKMwAAxTIAAEozAADGMgAAxDIAAEMzAABGMwAAxDIAAEYzAADFMgAAUDMAAFEzAABSMwAAUDMAAFIzAABTMwAAUTMAAFQzAABVMwAAUTMAAFUzAABSMwAAUzMAAFIzAABWMwAAUzMAAFYzAABXMwAAUjMAAFUzAABYMwAAUjMAAFgzAABWMwAA+wEAAFkzAABQMwAA+wEAAFAzAAAoLgAAWTMAAJcCAABRMwAAWTMAAFEzAABQMwAAlwIAAFozAABUMwAAlwIAAFQzAABRMwAAWjMAAJQCAAACMQAAWjMAAAIxAABUMwAAVDMAAAIxAAAJMQAAVDMAAAkxAABVMwAAVTMAAAkxAAAHMQAAVTMAAAcxAABYMwAAWDMAAAcxAAAIMQAAWDMAAAgxAABbMwAAVjMAAFgzAABbMwAAVjMAAFszAABcMwAAVzMAAFYzAABcMwAAVzMAAFwzAABdMwAAKi4AAFczAABdMwAAKi4AAF0zAAArLgAAKS4AAFMzAABXMwAAKS4AAFczAAAqLgAAKC4AAFAzAABTMwAAKC4AAFMzAAApLgAAXjMAAF8zAABgMwAAXjMAAGAzAABhMwAAXzMAAGIzAABjMwAAXzMAAGMzAABgMwAAYTMAAGAzAABkMwAAYTMAAGQzAABlMwAAYDMAAGMzAABmMwAAYDMAAGYzAABkMwAAxwkAAOsJAABeMwAAxwkAAF4zAAC9LAAA6wkAAGczAABfMwAA6wkAAF8zAABeMwAAZzMAAGgzAABiMwAAZzMAAGIzAABfMwAAaDMAAOYJAADjMgAAaDMAAOMyAABiMwAAYjMAAOMyAADrMgAAYjMAAOsyAABjMwAAYzMAAOsyAADpMgAAYzMAAOkyAABmMwAAZjMAAOkyAADqMgAAZjMAAOoyAABpMwAAZDMAAGYzAABpMwAAZDMAAGkzAABqMwAAZTMAAGQzAABqMwAAZTMAAGozAABrMwAAvywAAGUzAABrMwAAvywAAGszAADALAAAviwAAGEzAABlMwAAviwAAGUzAAC/LAAAvSwAAF4zAABhMwAAvSwAAGEzAAC+LAAAbDMAAG0zAABuMwAAbDMAAG4zAABvMwAAbTMAAHAzAABxMwAAbTMAAHEzAABuMwAAbzMAAG4zAAByMwAAbzMAAHIzAABzMwAAbjMAAHEzAAB0MwAAbjMAAHQzAAByMwAAiAIAAHUzAABsMwAAiAIAAGwzAAAkMQAAdTMAAIwCAABtMwAAdTMAAG0zAABsMwAAjAIAAHYzAABwMwAAjAIAAHAzAABtMwAAdjMAAO4BAABvLgAAdjMAAG8uAABwMwAAcDMAAG8uAAB5LgAAcDMAAHkuAABxMwAAcTMAAHkuAAB3LgAAcTMAAHcuAAB0MwAAdDMAAHcuAAB4LgAAdDMAAHguAAB3MwAAcjMAAHQzAAB3MwAAcjMAAHczAAB4MwAAczMAAHIzAAB4MwAAczMAAHgzAAB5MwAAJjEAAHMzAAB5MwAAJjEAAHkzAAAnMQAAJTEAAG8zAABzMwAAJTEAAHMzAAAmMQAAJDEAAGwzAABvMwAAJDEAAG8zAAAlMQAAejMAAHszAAB8MwAAejMAAHwzAAB9MwAAezMAAH4zAAB/MwAAezMAAH8zAAB8MwAAfTMAAHwzAACAMwAAfTMAAIAzAACBMwAAfDMAAH8zAACCMwAAfDMAAIIzAACAMwAA9AcAAIMzAAB6MwAA9AcAAHozAADSLAAAgzMAAIQzAAB7MwAAgzMAAHszAAB6MwAAhDMAABgIAAB+MwAAhDMAAH4zAAB7MwAAGAgAABcIAAD1MgAAGAgAAPUyAAB+MwAAfjMAAPUyAAD7MgAAfjMAAPsyAAB/MwAAfzMAAPsyAAD5MgAAfzMAAPkyAACCMwAAgjMAAPkyAAD6MgAAgjMAAPoyAACFMwAAgDMAAIIzAACFMwAAgDMAAIUzAACGMwAAgTMAAIAzAACGMwAAgTMAAIYzAACHMwAA1CwAAIEzAACHMwAA1CwAAIczAADVLAAA0ywAAH0zAACBMwAA0ywAAIEzAADULAAA0iwAAHozAAB9MwAA0iwAAH0zAADTLAAAiDMAAIkzAACKMwAAiDMAAIozAACLMwAAiTMAAIwzAACNMwAAiTMAAI0zAACKMwAAizMAAIozAACOMwAAizMAAI4zAACPMwAAijMAAI0zAACQMwAAijMAAJAzAACOMwAA2wkAAJEzAACIMwAA2wkAAIgzAAAGMwAAkTMAAJIzAACJMwAAkTMAAIkzAACIMwAAkjMAAJMzAACMMwAAkjMAAIwzAACJMwAAkzMAALkJAADmLAAAkzMAAOYsAACMMwAAjDMAAOYsAADxLAAAjDMAAPEsAACNMwAAjTMAAPEsAADvLAAAjTMAAO8sAACQMwAAkDMAAO8sAADwLAAAkDMAAPAsAACUMwAAjjMAAJAzAACUMwAAjjMAAJQzAACVMwAAjzMAAI4zAACVMwAAjzMAAJUzAACWMwAACDMAAI8zAACWMwAACDMAAJYzAAAJMwAABzMAAIszAACPMwAABzMAAI8zAAAIMwAABjMAAIgzAACLMwAABjMAAIszAAAHMwAAlzMAAJgzAACZMwAAlzMAAJkzAACaMwAAmDMAAJszAACcMwAAmDMAAJwzAACZMwAAmjMAAJkzAACdMwAAmjMAAJ0zAACeMwAAmTMAAJwzAACfMwAAmTMAAJ8zAACdMwAAlyIAAKAzAACXMwAAlyIAAJczAACYIgAAoDMAAKEzAACYMwAAoDMAAJgzAACXMwAAoTMAAKIzAACbMwAAoTMAAJszAACYMwAAojMAAOchAADpIQAAojMAAOkhAACbMwAAmzMAAOkhAADxIQAAmzMAAPEhAACcMwAAnDMAAPEhAADvIQAAnDMAAO8hAACfMwAAnzMAAO8hAADwIQAAnzMAAPAhAACjMwAAnTMAAJ8zAACjMwAAnTMAAKMzAACkMwAAnjMAAJ0zAACkMwAAnjMAAKQzAAClMwAAmiIAAJ4zAAClMwAAmiIAAKUzAACbIgAAmSIAAJozAACeMwAAmSIAAJ4zAACaIgAAmCIAAJczAACaMwAAmCIAAJozAACZIgAApjMAAKczAACoMwAApjMAAKgzAACpMwAApzMAAKozAACrMwAApzMAAKszAACoMwAAqTMAAKgzAACsMwAAqTMAAKwzAACtMwAAqDMAAKszAACuMwAAqDMAAK4zAACsMwAAvxYAAK8zAACmMwAAvxYAAKYzAADAFgAArzMAAKQzAACnMwAArzMAAKczAACmMwAApDMAALAzAACqMwAApDMAAKozAACnMwAAsDMAAGYXAABoFwAAsDMAAGgXAACqMwAAqjMAAGgXAABwFwAAqjMAAHAXAACrMwAAqzMAAHAXAABuFwAAqzMAAG4XAACuMwAArjMAAG4XAABvFwAArjMAAG8XAACxMwAArDMAAK4zAACxMwAArDMAALEzAACyMwAArTMAAKwzAACyMwAArTMAALIzAADOJAAAwhYAAK0zAADOJAAAwhYAAM4kAADDFgAAwRYAAKkzAACtMwAAwRYAAK0zAADCFgAAwBYAAKYzAACpMwAAwBYAAKkzAADBFgAAszMAALQzAAC1MwAAszMAALUzAAC2MwAAtDMAALczAAC4MwAAtDMAALgzAAC1MwAAtjMAALUzAAC5MwAAtjMAALkzAAC6MwAAtTMAALgzAAC7MwAAtTMAALszAAC5MwAAUAIAAE4CAACzMwAAUAIAALMzAAC8MwAATgIAAE0CAAC0MwAATgIAALQzAACzMwAATQIAAEwCAAC3MwAATQIAALczAAC0MwAATAIAAEsCAAC9MwAATAIAAL0zAAC3MwAAtzMAAL0zAAC+MwAAtzMAAL4zAAC4MwAAuDMAAL4zAAC/MwAAuDMAAL8zAAC7MwAAuzMAAL8zAADAMwAAuzMAAMAzAACiMwAAuTMAALszAACiMwAAuTMAAKIzAADBMwAAujMAALkzAADBMwAAujMAAMEzAADCMwAAwzMAALozAADCMwAAwzMAAMIzAADEMwAAxTMAALYzAAC6MwAAxTMAALozAADDMwAAvDMAALMzAAC2MwAAvDMAALYzAADFMwAAxjMAAMczAADIMwAAxjMAAMgzAADJMwAAxzMAAMozAADLMwAAxzMAAMszAADIMwAAyTMAAMgzAADMMwAAyTMAAMwzAADNMwAAyDMAAMszAADOMwAAyDMAAM4zAADMMwAAdQIAAM8zAADGMwAAdQIAAMYzAADQMwAAzzMAANEzAADHMwAAzzMAAMczAADGMwAA0TMAANIzAADKMwAA0TMAAMozAADHMwAA0jMAAFACAAC8MwAA0jMAALwzAADKMwAAyjMAALwzAADFMwAAyjMAAMUzAADLMwAAyzMAAMUzAADDMwAAyzMAAMMzAADOMwAAzjMAAMMzAADEMwAAzjMAAMQzAACWIgAAzDMAAM4zAACWIgAAzDMAAJYiAACVIgAAzTMAAMwzAACVIgAAzTMAAJUiAACUIgAA0zMAAM0zAACUIgAA0zMAAJQiAAAFGQAA1DMAAMkzAADNMwAA1DMAAM0zAADTMwAA0DMAAMYzAADJMwAA0DMAAMkzAADUMwAA1TMAANYzAADXMwAA1TMAANczAADYMwAA1jMAANkzAADaMwAA1jMAANozAADXMwAA2DMAANczAADbMwAA2DMAANszAADcMwAA1zMAANozAADdMwAA1zMAAN0zAADbMwAA3jMAAN8zAADVMwAA3jMAANUzAADgMwAA3zMAAOEzAADWMwAA3zMAANYzAADVMwAA4TMAAOIzAADZMwAA4TMAANkzAADWMwAA4jMAAFoCAADjMwAA4jMAAOMzAADZMwAA2TMAAOMzAADkMwAA2TMAAOQzAADaMwAA2jMAAOQzAADlMwAA2jMAAOUzAADdMwAA3TMAAOUzAADmMwAA3TMAAOYzAAAhIgAA2zMAAN0zAAAhIgAA2zMAACEiAADnMwAA3DMAANszAADnMwAA3DMAAOczAAAfIgAA6DMAANwzAAAfIgAA6DMAAB8iAADpMwAA6jMAANgzAADcMwAA6jMAANwzAADoMwAA4DMAANUzAADYMwAA4DMAANgzAADqMwAA6zMAAOwzAADtMwAA6zMAAO0zAADuMwAA7DMAAO8zAADwMwAA7DMAAPAzAADtMwAA7jMAAO0zAADxMwAA7jMAAPEzAADyMwAA7TMAAPAzAADzMwAA7TMAAPMzAADxMwAASwIAAEoCAADrMwAASwIAAOszAAC9MwAASgIAAPQzAADsMwAASgIAAOwzAADrMwAA9DMAAPUzAADvMwAA9DMAAO8zAADsMwAA9TMAAPYzAAD3MwAA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STQAAEw0AABNNAAASDQAAEs0AABONAAASDQAAE40AABMNAAATzQAAOkFAABGNAAATzQAAEY0AABQNAAA6QUAAOYFAABHNAAA6QUAAEc0AABGNAAA5gUAAOQFAABKNAAA5gUAAEo0AABHNAAA5AUAAOMFAAAZNAAA5AUAABk0AABKNAAASjQAABk0AAAkNAAASjQAACQ0AABLNAAASzQAACQ0AAAiNAAASzQAACI0AABONAAATjQAACI0AAAjNAAATjQAACM0AAAxIQAATDQAAE40AAAxIQAATDQAADEhAABRNAAATTQAAEw0AABRNAAATTQAAFE0AABSNAAAUzQAAE00AABSNAAAUzQAAFI0AADTIAAAVDQAAEk0AABNNAAAVDQAAE00AABTNAAAUDQAAEY0AABJNAAAUDQAAEk0AABUNAAAVTQAAFY0AABXNAAAVTQAAFc0AABYNAAAVjQAAFk0AABaNAAAVjQAAFo0AABXNAAAWDQAAFc0AABbNAAAWDQAAFs0AABcNAAAVzQAAFo0AABdNAAAVzQAAF00AABbNAAA9jMAAF40AABVNAAA9jMAAFU0AAD3MwAAXjQAACECAABWNAAAXjQAAFY0AABVNAAAIQIAAF80AABZNAAAIQIAAFk0AABWNAAAXzQAANsBAABgNAAAXzQAAGA0AABZNAAAWTQAAGA0AABhNAAAWTQAAGE0AABaNAAAWjQAAGE0AABiNAAAWjQAAGI0AABdNAAAXTQAAGI0AABjNAAAXTQAAGM0AABkNAAAWzQAAF00AABkNAAAWzQAAGQ0AABlNAAAXDQAAFs0AABlNAAAXDQAAGU0AABmNAAA+TMAAFw0AABmNAAA+TMAAGY0AAD6MwAA+DMAAFg0AABcNAAA+DMAAFw0AAD5MwAA9zMAAFU0AABYNAAA9zMAAFg0AAD4MwAAZzQAAGg0AABpNAAAZzQAAGk0AABqNAAAaDQAAGs0AABsNAAAaDQAAGw0AABpNAAAajQAAGk0AABtNAAAajQAAG00AABuNAAAaTQAAGw0AABvNAAAaTQAAG80AABtNAAAlgUAAHA0AABnNAAAlgUAAGc0AABxNAAAcDQAAHI0AABoNAAAcDQAAGg0AABnNAAAcjQAAHM0AABrNAAAcjQAAGs0AABoNAAAczQAAE80AABQNAAAczQAAFA0AABrNAAAazQAAFA0AABUNAAAazQAAFQ0AABsNAAAbDQAAFQ0AABTNAAAbDQAAFM0AABvNAAAbzQAAFM0AADTIAAAbzQAANMgAAB0NAAAbTQAAG80AAB0NAAAbTQAAHQ0AAB1NAAAbjQAAG00AAB1NAAAbjQAAHU0AADQIAAAdjQAAG40AADQIAAAdjQAANAgAAB3NAAAeDQAAGo0AABuNAAAeDQAAG40AAB2NAAAcTQAAGc0AABqNAAAcTQAAGo0AAB4NAAAeTQAAHo0AAB7NAAAeTQAAHs0AAB8NAAAejQAAH00AAB+NAAAejQAAH40AAB7NAAAfDQAAHs0AAB/NAAAfDQAAH80AACANAAAezQAAH40AACBNAAAezQAAIE0AAB/NAAAtwMAAII0AAB5NAAAtwMAAHk0AACDNAAAgjQAAPMDAAB6NAAAgjQAAHo0AAB5NAAA8wMAAPEDAAB9NAAA8wMAAH00AAB6NAAA8QMAAPADAAAHNAAA8QMAAAc0AAB9NAAAfTQAAAc0AAAPNAAAfTQAAA80AAB+NAAAfjQAAA80AAANNAAAfjQAAA00AACBNAAAgTQAAA00AAAONAAAgTQAAA40AACsIAAAfzQAAIE0AACsIAAAfzQAAKwgAACrIAAAgDQAAH80AACrIAAAgDQAAKsgAACENAAAhTQAAIA0AACENAAAhTQAAIQ0AAAjHwAAhjQAAHw0AACANAAAhjQAAIA0AACFNAAAgzQAAHk0AAB8NAAAgzQAAHw0AACGNAAAhzQAAIg0AACJNAAAhzQAAIk0AACKNAAAiDQAAIs0AACMNAAAiDQAAIw0AACJNAAAijQAAIk0AACNNAAAijQAAI00AACONAAAiTQAAIw0AACPNAAAiTQAAI80AACNNAAAwQUAAJA0AACHNAAAwQUAAIc0AAAbNAAAkDQAAJE0AACINAAAkDQAAIg0AACHNAAAkTQAAJI0AACLNAAAkTQAAIs0AACINAAAkjQAAIoFAACTNAAAkjQAAJM0AACLNAAAizQAAJM0AACUNAAAizQAAJQ0AACMNAAAjDQAAJQ0AACVNAAAjDQAAJU0AACPNAAAjzQAAJU0AACWNAAAjzQAAJY0AAB4IAAAjTQAAI80AAB4IAAAjTQAAHggAACXNAAAjjQAAI00AACXNAAAjjQAAJc0AAB1IAAAHTQAAI40AAB1IAAAHTQAAHUgAAAeNAAAHDQAAIo0AACONAAAHDQAAI40AAAdNAAAGzQAAIc0AACKNAAAGzQAAIo0AAAcNAAAmDQAAJk0AACaNAAAmDQAAJo0AACbNAAAmTQAAJw0AACdNAAAmTQAAJ00AACaNAAAmzQAAJo0AACeNAAAmzQAAJ40AACfNAAAmjQAAJ00AACgNAAAmjQAAKA0AACeNAAAxAEAAKE0AACYNAAAxAEAAJg0AACiNAAAoTQAAKM0AACZNAAAoTQAAJk0AACYNAAAozQAAA0CAACcNAAAozQAAJw0AACZNAAADQIAADUCAABBNAAADQIAAEE0AACcNAAAnDQAAEE0AABFNAAAnDQAAEU0AACdNAAAnTQAAEU0AABENAAAnTQAAEQ0AACgNAAAoDQAAEQ0AABlIAAAoDQAAGUgAABkIAAAnjQAAKA0AABkIAAAnjQAAGQgAACkNAAAnzQAAJ40AACkNAAAnzQAAKQ0AAClNAAApjQAAJ80AAClNAAApjQAAKU0AACnNAAAqDQAAJs0AACfNAAAqDQAAJ80AACmNAAAojQAAJg0AACbNAAAojQAAJs0AACoNAAAqTQAAKo0AACrNAAAqTQAAKs0AACsNAAAqjQAAK00AACuNAAAqjQAAK40AACrNAAArDQAAKs0AACvNAAArDQAAK80AACwNAAAqzQAAK40AACxNAAAqzQAALE0AACvNAAA4wMAAOUDAACpNAAA4wMAAKk0AAAvNAAA5QMAALI0AACqNAAA5QMAAKo0AACpNAAAsjQAALM0AACtNAAAsjQAAK00AACqNAAAszQAALQ0AAC1NAAAszQAALU0AACtNAAArTQAALU0AAC2NAAArTQAALY0AACuNAAArjQAALY0AAC3NAAArjQAALc0AACxNAAAsTQAALc0AAC4NAAAsTQAALg0AAC5NAAArzQAALE0AAC5NAAArzQAALk0AAC6NAAAsDQAAK80AAC6NAAAsDQAALo0AAC7NAAAMTQAALA0AAC7NAAAMTQAALs0AAA8IAAAMDQAAKw0AACwNAAAMDQAALA0AAAxNAAALzQAAKk0AACsNAAALzQAAKw0AAAwNAAAvDQAAL00AAC+NAAAvDQAAL40AAC/NAAAvTQAAMA0AADBNAAAvTQAAME0AAC+NAAAvzQAAL40AADCNAAAvzQAAMI0AADDNAAAvjQAAME0AADENAAAvjQAAMQ0AADCNAAAxTQAAMY0AAC8NAAAxTQAALw0AADHNAAAxjQAAMg0AAC9NAAAxjQAAL00AAC8NAAAyDQAAJcFAADANAAAyDQAAMA0AAC9NAAAlwUAAJYFAABxNAAAlwUAAHE0AADANAAAwDQAAHE0AAB4NAAAwDQAAHg0AADBNAAAwTQAAHg0AAB2NAAAwTQAAHY0AADENAAAxDQAAHY0AAB3NAAAxDQAAHc0AABZHwAAwjQAAMQ0AABZHwAAwjQAAFkfAABYHwAAwzQAAMI0AABYHwAAwzQAAFgfAADJNAAAyjQAAMM0AADJNAAAyjQAAMk0AADLNAAAzDQAAL80AADDNAAAzDQAAMM0AADKNAAAxzQAALw0AAC/NAAAxzQAAL80AADMNAAAzTQAAM40AADPNAAAzTQAAM80AADQNAAAzjQAANE0AADSNAAAzjQAANI0AADPNAAA0DQAAM80AADTNAAA0DQAANM0AADUNAAAzzQAANI0AADVNAAAzzQAANU0AADTNAAA2wEAAN0BAADNNAAA2wEAAM00AABgNAAA3QEAAN8BAADONAAA3QEAAM40AADNNAAA3wEAANkBAADRNAAA3wEAANE0AADONAAA2QEAANY0AADXNAAA2QEAANc0AADRNAAA0TQAANc0AADYNAAA0TQAANg0AADSNAAA0jQAANg0AADZNAAA0jQAANk0AADVNAAA1TQAANk0AAAwHgAA1TQAADAeAABJHwAA0zQAANU0AABJHwAA0zQAAEkfAADaNAAA1DQAANM0AADaNAAA1DQAANo0AABGHwAAYjQAANQ0AABGHwAAYjQAAEYfAABjNAAAYTQAANA0AADUNAAAYTQAANQ0AABiNAAAYDQAAM00AADQNAAAYDQAANA0AABhNAAA2zQAANw0AADdNAAA2zQAAN00AADeNAAA3DQAAN80AADgNAAA3DQAAOA0AADdNAAA3jQAAN00AADhNAAA3jQAAOE0AADiNAAA3TQAAOA0AADjNAAA3TQAAOM0AADhNAAAYgMAAOQ0AADbNAAAYgMAANs0AADlNAAA5DQAAOY0AADcNAAA5DQAANw0AADbNAAA5jQAAOc0AADfNAAA5jQAAN80AADcNAAA5zQAALcDAACDNAAA5zQAAIM0AADfNAAA3zQAAIM0AACGNAAA3zQAAIY0AADgNAAA4DQAAIY0AACFNAAA4DQAAIU0AADjNAAA4zQAAIU0AAAjHwAA4zQAACMfAADoNAAA4TQAAOM0AADoNAAA4TQAAOg0AADpNAAA4jQAAOE0AADpNAAA4jQAAOk0AADqNAAA6zQAAOI0AADqNAAA6zQAAOo0AADjHAAA7DQAAN40AADiNAAA7DQAAOI0AADrNAAA5TQAANs0AADeNAAA5TQAAN40AADsNAAA7TQAAO40AADvNAAA7TQAAO80AADwNAAA7jQAAPE0AADyNAAA7jQAAPI0AADvNAAA8DQAAO80AADzNAAA8DQAAPM0AAD0NAAA7zQAAPI0AAD1NAAA7zQAAPU0AADzNAAAigUAAPY0AADtNAAAigUAAO00AACTNAAA9jQAAPc0AADuNAAA9jQAAO40AADtNAAA9zQAAIgFAADxNAAA9zQAAPE0AADuNAAAiAUAAGcFAAD4NAAAiAUAAPg0AADxNAAA8TQAAPg0AAD5NAAA8TQAAPk0AADyNAAA8jQAAPk0AAD6NAAA8jQAAPo0AAD1NAAA9TQAAPo0AAD7NAAA9TQAAPs0AAD8NAAA8zQAAPU0AAD8NAAA8zQAAPw0AAABHwAA9DQAAPM0AAABHwAA9DQAAAEfAAD/HgAAlTQAAPQ0AAD/HgAAlTQAAP8eAACWNAAAlDQAAPA0AAD0NAAAlDQAAPQ0AACVNAAAkzQAAO00AADwNAAAkzQAAPA0AACUNAAA/TQAAP40AAD/NAAA/TQAAP80AAAANQAA/jQAAAE1AAACNQAA/jQAAAI1AAD/NAAAADUAAP80AAADNQAAADUAAAM1AAAENQAA/zQAAAI1AAAFNQAA/zQAAAU1AAADNQAAtDQAAAY1AAD9NAAAtDQAAP00AAC1NAAABjUAAAc1AAD+NAAABjUAAP40AAD9NAAABzUAAAg1AAABNQAABzUAAAE1AAD+NAAACDUAAHkDAAAJNQAACDUAAAk1AAABNQAAATUAAAk1AAAKNQAAATUAAAo1AAACNQAAAjUAAAo1AAALNQAAAjUAAAs1AAAFNQAABTUAAAs1AABzHQAABTUAAHMdAAAMNQAAAzUAAAU1AAAMNQAAAzUAAAw1AAANNQAABDUAAAM1AAANNQAABDUAAA01AAAONQAAtzQAAAQ1AAAONQAAtzQAAA41AAC4NAAAtjQAAAA1AAAENQAAtjQAAAQ1AAC3NAAAtTQAAP00AAAANQAAtTQAAAA1AAC2NAAADzUAABA1AAARNQAADzUAABE1AAASNQAAEDUAABM1AAAUNQAAEDUAABQ1AAARNQAAEjUAABE1AAAVNQAAEjUAABU1AAAWNQAAETUAABQ1AAAXNQAAETUAABc1AAAVNQAAoAEAAMoBAAAPNQAAoAEAAA81AAAYNQAAygEAABk1AAAQNQAAygEAABA1AAAPNQAAGTUAABo1AAATNQAAGTUAABM1AAAQNQAAGjUAAMQBAACiNAAAGjUAAKI0AAATNQAAEzUAAKI0AACoNAAAEzUAAKg0AAAUNQAAFDUAAKg0AACmNAAAFDUAAKY0AAAXNQAAFzUAAKY0AACnNAAAFzUAAKc0AAAbNQAAFTUAABc1AAAbNQAAFTUAABs1AAAcNQAAFjUAABU1AAAcNQAAFjUAABw1AAAdNQAAHjUAABY1AAAdNQAAHjUAAB01AAAfNQAAIDUAABI1AAAWNQAAIDUAABY1AAAeNQAAGDUAAA81AAASNQAAGDUAABI1AAAgNQAAITUAACI1AAAjNQAAITUAACM1AAAkNQAAIjUAACU1AAAmNQAAIjUAACY1AAAjNQAAJDUAACM1AAAnNQAAJDUAACc1AAAoNQAAIzUAACY1AAApNQAAIzUAACk1AAAnNQAAeQUAAHoFAAAhNQAAeQUAACE1AAAqNQAAegUAAHwFAAAiNQAAegUAACI1AAAhNQAAfAUAACs1AAAlNQAAfAUAACU1AAAiNQAAKzUAAMU0AADHNAAAKzUAAMc0AAAlNQAAJTUAAMc0AADMNAAAJTUAAMw0AAAmNQAAJjUAAMw0AADKNAAAJjUAAMo0AAApNQAAKTUAAMo0AADLNAAAKTUAAMs0AAAsNQAAJzUAACk1AAAsNQAAJzUAACw1AAAtNQAAKDUAACc1AAAtNQAAKDUAAC01AABDHgAALjUAACg1AABDHgAALjUAAEMeAAAaHQAALzUAACQ1AAAoNQAALzUAACg1AAAuNQAAKjUAACE1AAAkNQAAKjUAACQ1AAAvNQAAMDUAADE1AAAyNQAAMDUAADI1AAAzNQAAMTUAADQ1AAA1NQAAMTUAADU1AAAyNQAAMzUAADI1AAA2NQAAMzUAADY1AAA3NQAAMjUAADU1AAA4NQAAMjUAADg1AAA2NQAA1jQAADk1AAAwNQAA1jQAADA1AADXNAAAOTUAALYBAAAxNQAAOTUAADE1AAAwNQAAtgEAALUBAAA0NQAAtgEAADQ1AAAxNQAAtQEAADo1AAA7NQAAtQEAADs1AAA0NQAANDUAADs1AAA8NQAANDUAADw1AAA1NQAANTUAADw1AAA9NQAANTUAAD01AAA4NQAAODUAAD01AABOHQAAODUAAE4dAAA0HgAANjUAADg1AAA0HgAANjUAADQeAAAzHgAANzUAADY1AAAzHgAANzUAADMeAAA+NQAA2TQAADc1AAA+NQAA2TQAAD41AAAwHgAA2DQAADM1AAA3NQAA2DQAADc1AADZNAAA1zQAADA1AAAzNQAA1zQAADM1AADYNAAAPzUAAEA1AABBNQAAPzUAAEE1AABCNQAAQDUAAEM1AABENQAAQDUAAEQ1AABBNQAAQjUAAEE1AABFNQAAQjUAAEU1AABGNQAAQTUAAEQ1AABHNQAAQTUAAEc1AABFNQAAZwUAAEg1AAA/NQAAZwUAAD81AAD4NAAASDUAAGYFAABANQAASDUAAEA1AAA/NQAAZgUAAEk1AABDNQAAZgUAAEM1AABANQAASTUAADIFAABKNQAASTUAAEo1AABDNQAAQzUAAEo1AABLNQAAQzUAAEs1AABENQAARDUAAEs1AABMNQAARDUAAEw1AABHNQAARzUAAEw1AABNNQAARzUAAE01AABONQAARTUAAEc1AABONQAARTUAAE41AABPNQAARjUAAEU1AABPNQAARjUAAE81AABQNQAA+jQAAEY1AABQNQAA+jQAAFA1AAD7NAAA+TQAAEI1AABGNQAA+TQAAEY1AAD6NAAA+DQAAD81AABCNQAA+DQAAEI1AAD5NAAAUTUAAFI1AABTNQAAUTUAAFM1AABUNQAAUjUAAFU1AABWNQAAUjUAAFY1AABTNQAAVDUAAFM1AABXNQAAVDUAAFc1AABYNQAAUzUAAFY1AABZNQAAUzUAAFk1AABXNQAAWjUAAFs1AABRNQAAWjUAAFE1AABcNQAAWzUAAF01AABSNQAAWzUAAFI1AABRNQAAXTUAAKEBAABVNQAAXTUAAFU1AABSNQAAoQEAAKABAAAYNQAAoQEAABg1AABVNQAAVTUAABg1AAAgNQAAVTUAACA1AABWNQAAVjUAACA1AAAeNQAAVjUAAB41AABZNQAAWTUAAB41AAAfNQAAWTUAAB81AABeNQAAVzUAAFk1AABeNQAAVzUAAF41AACaHQAAWDUAAFc1AACaHQAAWDUAAJodAABfNQAAYDUAAFg1AABfNQAAYDUAAF81AACrHAAAYTUAAFQ1AABYNQAAYTUAAFg1AABgNQAAXDUAAFE1AABUNQAAXDUAAFQ1AABhNQAAYjUAAGM1AABkNQAAYjUAAGQ1AABlNQAAYzUAAGY1AABnNQAAYzUAAGc1AABkNQAAZTUAAGQ1AABoNQAAZTUAAGg1AABpNQAAZDUAAGc1AABqNQAAZDUAAGo1AABoNQAAeQMAAGs1AABiNQAAeQMAAGI1AAAJNQAAazUAAGw1AABjNQAAazUAAGM1AABiNQAAbDUAAG01AABmNQAAbDUAAGY1AABjNQAAbTUAAFUDAABuNQAAbTUAAG41AABmNQAAZjUAAG41AABvNQAAZjUAAG81AABnNQAAZzUAAG81AABwNQAAZzUAAHA1AABqNQAAajUAAHA1AABxNQAAajUAAHE1AAB3HQAAaDUAAGo1AAB3HQAAaDUAAHcdAAB2HQAAaTUAAGg1AAB2HQAAaTUAAHYdAAByNQAACzUAAGk1AAByNQAACzUAAHI1AABzHQAACjUAAGU1AABpNQAACjUAAGk1AAALNQAACTUAAGI1AABlNQAACTUAAGU1AAAKNQAAczUAAHQ1AAB1NQAAczUAAHU1AAB2NQAAdDUAAHc1AAB4NQAAdDUAAHg1AAB1NQAAdjUAAHU1AAB5NQAAdjUAAHk1AAB6NQAAdTUAAHg1AAB7NQAAdTUAAHs1AAB5NQAAOjUAAJYBAABzNQAAOjUAAHM1AAA7NQAAlgEAAJMBAAB0NQAAlgEAAHQ1AABzNQAAkwEAAHw1AAB3NQAAkwEAAHc1AAB0NQAAfDUAAH01AAB+NQAAfDUAAH41AAB3NQAAdzUAAH41AAB/NQAAdzUAAH81AAB4NQAAeDUAAH81AACANQAAeDUAAIA1AAB7NQAAezUAAIA1AAAdHAAAezUAAB0cAACBNQAAeTUAAHs1AACBNQAAeTUAAIE1AACCNQAAejUAAHk1AACCNQAAejUAAII1AACDNQAAPTUAAHo1AACDNQAAPTUAAIM1AABOHQAAPDUAAHY1AAB6NQAAPDUAAHo1AAA9NQAAOzUAAHM1AAB2NQAAOzUAAHY1AAA8NQAAhDUAAIU1AACGNQAAhDUAAIY1AACHNQAAhTUAAIg1AACJNQAAhTUAAIk1AACGNQAAhzUAAIY1AACKNQAAhzUAAIo1AACLNQAAhjUAAIk1AACMNQAAhjUAAIw1AACKNQAAjTUAAI41AACENQAAjTUAAIQ1AACPNQAAjjUAAJA1AACFNQAAjjUAAIU1AACENQAAkDUAAJE1AACINQAAkDUAAIg1AACFNQAAkTUAAHkFAAAqNQAAkTUAACo1AACINQAAiDUAACo1AAAvNQAAiDUAAC81AACJNQAAiTUAAC81AAAuNQAAiTUAAC41AACMNQAAjDUAAC41AAAaHQAAjDUAABodAACSNQAAijUAAIw1AACSNQAAijUAAJI1AAAYHQAAizUAAIo1AAAYHQAAizUAABgdAACTNQAAlDUAAIs1AACTNQAAlDUAAJM1AACVNQAAljUAAIc1AACLNQAAljUAAIs1AACUNQAAjzUAAIQ1AACHNQAAjzUAAIc1AACWNQAAlzUAAJg1AACZNQAAlzUAAJk1AACaNQAAmDUAAJs1AACcNQAAmDUAAJw1AACZNQAAmjUAAJk1AACdNQAAmjUAAJ01AACeNQAAmTUAAJw1AACfNQAAmTUAAJ81AACdNQAAZwMAAKA1AACXNQAAZwMAAJc1AAChNQAAoDUAAGkDAACYNQAAoDUAAJg1AACXNQAAaQMAAKI1AACbNQAAaQMAAJs1AACYNQAAojUAAGIDAADlNAAAojUAAOU0AACbNQAAmzUAAOU0AADsNAAAmzUAAOw0AACcNQAAnDUAAOw0AADrNAAAnDUAAOs0AACfNQAAnzUAAOs0AADjHAAAnzUAAOMcAACjNQAAnTUAAJ81AACjNQAAnTUAAKM1AACkNQAAnjUAAJ01AACkNQAAnjUAAKQ1AAClNQAApjUAAJ41AAClNQAApjUAAKU1AACnNQAAqDUAAJo1AACeNQAAqDUAAJ41AACmNQAAoTUAAJc1AACaNQAAoTUAAJo1AACoNQAAqTUAAKo1AACrNQAAqTUAAKs1AACsNQAAqjUAAK01AACuNQAAqjUAAK41AACrNQAArDUAAKs1AACvNQAArDUAAK81AACwNQAAqzUAAK41AACxNQAAqzUAALE1AACvNQAAMgUAADQFAACpNQAAMgUAAKk1AABKNQAANAUAALI1AACqNQAANAUAAKo1AACpNQAAsjUAALM1AACtNQAAsjUAAK01AACqNQAAszUAALQ1AAC1NQAAszUAALU1AACtNQAArTUAALU1AAC2NQAArTUAALY1AACuNQAArjUAALY1AAC3NQAArjUAALc1AACxNQAAsTUAALc1AADAGwAAsTUAAMAbAAC+HAAArzUAALE1AAC+HAAArzUAAL4cAAC4NQAAsDUAAK81AAC4NQAAsDUAALg1AAC5NQAATDUAALA1AAC5NQAATDUAALk1AABNNQAASzUAAKw1AACwNQAASzUAALA1AABMNQAASjUAAKk1AACsNQAASjUAAKw1AABLNQAAujUAALs1AAC8NQAAujUAALw1AAC9NQAAuzUAAL41AAC/NQAAuzUAAL81AAC8NQAAvTUAALw1AADANQAAvTUAAMA1AADBNQAAvDUAAL81AADCNQAAvDUAAMI1AADANQAAwzUAAMQ1AAC6NQAAwzUAALo1AADFNQAAxDUAAH4BAAC7NQAAxDUAALs1AAC6NQAAfgEAAHwBAAC+NQAAfgEAAL41AAC7NQAAfAEAAFo1AABcNQAAfAEAAFw1AAC+NQAAvjUAAFw1AABhNQAAvjUAAGE1AAC/NQAAvzUAAGE1AABgNQAAvzUAAGA1AADCNQAAwjUAAGA1AACrHAAAwjUAAKscAADGNQAAwDUAAMI1AADGNQAAwDUAAMY1AADHNQAAwTUAAMA1AADHNQAAwTUAAMc1AADINQAAyTUAAME1AADINQAAyTUAAMg1AABfHAAAyjUAAL01AADBNQAAyjUAAME1AADJNQAAxTUAALo1AAC9NQAAxTUAAL01AADKNQAAyzUAAMw1AADNNQAAyzUAAM01AADONQAAzDUAAM81AADQNQAAzDUAANA1AADNNQAAzjUAAM01AADRNQAAzjUAANE1AADSNQAAzTUAANA1AADTNQAAzTUAANM1AADRNQAAVQMAANQ1AADLNQAAVQMAAMs1AABuNQAA1DUAAFkDAADMNQAA1DUAAMw1AADLNQAAWQMAANU1AADPNQAAWQMAAM81AADMNQAA1TUAAAkDAADWNQAA1TUAANY1AADPNQAAzzUAANY1AADXNQAAzzUAANc1AADQNQAA0DUAANc1AADYNQAA0DUAANg1AADTNQAA0zUAANg1AADcGgAA0zUAANwaAADZNQAA0TUAANM1AADZNQAA0TUAANk1AADaNQAA0jUAANE1AADaNQAA0jUAANo1AACFHAAAcDUAANI1AACFHAAAcDUAAIUcAABxNQAAbzUAAM41AADSNQAAbzUAANI1AABwNQAAbjUAAMs1AADONQAAbjUAAM41AABvNQAA2zUAANw1AADdNQAA2zUAAN01AADeNQAA3DUAAN81AADgNQAA3DUAAOA1AADdNQAA3jUAAN01AADhNQAA3jUAAOE1AADiNQAA3TUAAOA1AADjNQAA3TUAAOM1AADhNQAAPQEAAOQ1AADbNQAAPQEAANs1AADlNQAA5DUAAOY1AADcNQAA5DUAANw1AADbNQAA5jUAAOc1AADfNQAA5jUAAN81AADcNQAA5zUAAMM1AADFNQAA5zUAAMU1AADfNQAA3zUAAMU1AADKNQAA3zUAAMo1AADgNQAA4DUAAMo1AADJNQAA4DUAAMk1AADjNQAA4zUAAMk1AABfHAAA4zUAAF8cAADoNQAA4TUAAOM1AADoNQAA4TUAAOg1AADpNQAA4jUAAOE1AADpNQAA4jUAAOk1AABcHAAA6jUAAOI1AABcHAAA6jUAAFwcAADrNQAA7DUAAN41AADiNQAA7DUAAOI1AADqNQAA5TUAANs1AADeNQAA5TUAAN41AADsNQAA7TUAAO41AADvNQAA7TUAAO81AADwNQAA7jUAAPE1AADyNQAA7jUAAPI1AADvNQAA8DUAAO81AADzNQAA8DUAAPM1AAD0NQAA7zUAAPI1AAD1NQAA7zUAAPU1AADzNQAA4wQAAPY1AADtNQAA4wQAAO01AAD3NQAA9jUAAB0FAADuNQAA9jUAAO41AADtNQAAHQUAAPg1AADxNQAAHQUAAPE1AADuNQAA+DUAAI01AACPNQAA+DUAAI81AADxNQAA8TUAAI81AACWNQAA8TUAAJY1AADyNQAA8jUAAJY1AACUNQAA8jUAAJQ1AAD1NQAA9TUAAJQ1AACVNQAA9TUAAJU1AAD5NQAA8zUAAPU1AAD5NQAA8zUAAPk1AAD6NQAA9DUAAPM1AAD6NQAA9DUAAPo1AAD7NQAA/DUAAPQ1AAD7NQAA/DUAAPs1AADMGgAA/TUAAPA1AAD0NQAA/TUAAPQ1AAD8NQAA9zUAAO01AADwNQAA9zUAAPA1AAD9NQAA/jUAAP81AAAANgAA/jUAAAA2AAABNgAA/zUAAAI2AAADNgAA/zUAAAM2AAAANgAAATYAAAA2AAAENgAAATYAAAQ2AAAFNgAAADYAAAM2AAAGNgAAADYAAAY2AAAENgAAfTUAAAc2AAD+NQAAfTUAAP41AAB+NQAABzYAAAg2AAD/NQAABzYAAP81AAD+NQAACDYAAFwBAAACNgAACDYAAAI2AAD/NQAAXAEAAD0BAADlNQAAXAEAAOU1AAACNgAAAjYAAOU1AADsNQAAAjYAAOw1AAADNgAAAzYAAOw1AADqNQAAAzYAAOo1AAAGNgAABjYAAOo1AADrNQAABjYAAOs1AAAhHAAABDYAAAY2AAAhHAAABDYAACEcAAAJNgAABTYAAAQ2AAAJNgAABTYAAAk2AAAKNgAAgDUAAAU2AAAKNgAAgDUAAAo2AAAdHAAAfzUAAAE2AAAFNgAAfzUAAAU2AACANQAAfjUAAP41AAABNgAAfjUAAAE2AAB/NQAACzYAAAw2AAANNgAACzYAAA02AAAONgAADDYAAA82AAAQNgAADDYAABA2AAANNgAADjYAAA02AAARNgAADjYAABE2AAASNgAADTYAABA2AAATNgAADTYAABM2AAARNgAA7wIAAEIDAAALNgAA7wIAAAs2AAAUNgAAQgMAABU2AAAMNgAAQgMAAAw2AAALNgAAFTYAAD0DAAAPNgAAFTYAAA82AAAMNgAAPQMAAGcDAAChNQAAPQMAAKE1AAAPNgAADzYAAKE1AACoNQAADzYAAKg1AAAQNgAAEDYAAKg1AACmNQAAEDYAAKY1AAATNgAAEzYAAKY1AACnNQAAEzYAAKc1AAAWNgAAETYAABM2AAAWNgAAETYAABY2AADmGwAAEjYAABE2AADmGwAAEjYAAOYbAAAXNgAAGDYAABI2AAAXNgAAGDYAABc2AAAZNgAAGjYAAA42AAASNgAAGjYAABI2AAAYNgAAFDYAAAs2AAAONgAAFDYAAA42AAAaNgAAGzYAABw2AAAdNgAAGzYAAB02AAAeNgAAHDYAAB82AAAgNgAAHDYAACA2AAAdNgAAHjYAAB02AAAhNgAAHjYAACE2AAAiNgAAHTYAACA2AAAjNgAAHTYAACM2AAAhNgAAtDUAACQ2AAAbNgAAtDUAABs2AAC1NQAAJDYAABIFAAAcNgAAJDYAABw2AAAbNgAAEgUAACU2AAAfNgAAEgUAAB82AAAcNgAAJTYAACY2AAAnNgAAJTYAACc2AAAfNgAAHzYAACc2AAAoNgAAHzYAACg2AAAgNgAAIDYAACg2AAApNgAAIDYAACk2AAAjNgAAIzYAACk2AACiGgAAIzYAAKIaAAAqNgAAITYAACM2AAAqNgAAITYAACo2AAArNgAAIjYAACE2AAArNgAAIjYAACs2AAAsNgAAtzUAACI2AAAsNgAAtzUAACw2AADAGwAAtjUAAB42AAAiNgAAtjUAACI2AAC3NQAAtTUAABs2AAAeNgAAtTUAAB42AAC2NQAALTYAAC42AAAvNgAALTYAAC82AAAwNgAALjYAADE2AAAyNgAALjYAADI2AAAvNgAAMDYAAC82AAAzNgAAMDYAADM2AAA0NgAALzYAADI2AAA1NgAALzYAADU2AAAzNgAACQMAADY2AAAtNgAACQMAAC02AADWNQAANjYAADc2AAAuNgAANjYAAC42AAAtNgAANzYAAAYDAAAxNgAANzYAADE2AAAuNgAABgMAAOICAAA4NgAABgMAADg2AAAxNgAAMTYAADg2AAA5NgAAMTYAADk2AAAyNgAAMjYAADk2AAA6NgAAMjYAADo2AAA1NgAANTYAADo2AAD6GQAANTYAAPoZAADgGgAAMzYAADU2AADgGgAAMzYAAOAaAAA7NgAANDYAADM2AAA7NgAANDYAADs2AAA8NgAA2DUAADQ2AAA8NgAA2DUAADw2AADcGgAA1zUAADA2AAA0NgAA1zUAADQ2AADYNQAA1jUAAC02AAAwNgAA1jUAADA2AADXNQAAPTYAAD42AAA/NgAAPTYAAD82AABANgAAPjYAAEE2AABCNgAAPjYAAEI2AAA/NgAAQDYAAD82AABDNgAAQDYAAEM2AABENgAAPzYAAEI2AABFNgAAPzYAAEU2AABDNgAARjYAAEc2AAA9NgAARjYAAD02AABINgAARzYAAOYEAAA+NgAARzYAAD42AAA9NgAA5gQAAEk2AABBNgAA5gQAAEE2AAA+NgAASTYAAOMEAAD3NQAASTYAAPc1AABBNgAAQTYAAPc1AAD9NQAAQTYAAP01AABCNgAAQjYAAP01AAD8NQAAQjYAAPw1AABFNgAARTYAAPw1AADMGgAARTYAAMwaAABKNgAAQzYAAEU2AABKNgAAQzYAAEo2AABLNgAARDYAAEM2AABLNgAARDYAAEs2AABMNgAATTYAAEQ2AABMNgAATTYAAEw2AABONgAATzYAAEA2AABENgAATzYAAEQ2AABNNgAASDYAAD02AABANgAASDYAAEA2AABPNgAAUDYAAFE2AABSNgAAUDYAAFI2AABTNgAAUTYAAFQ2AABVNgAAUTYAAFU2AABSNgAAUzYAAFI2AABWNgAAUzYAAFY2AABXNgAAUjYAAFU2AABYNgAAUjYAAFg2AABWNgAAJjYAAFk2AABQNgAAJjYAAFA2AAAnNgAAWTYAAFo2AABRNgAAWTYAAFE2AABQNgAAWjYAAFs2AABUNgAAWjYAAFQ2AABRNgAAWzYAAJ8EAABcNgAAWzYAAFw2AABUNgAAVDYAAFw2AABdNgAAVDYAAF02AABVNgAAVTYAAF02AABeNgAAVTYAAF42AABYNgAAWDYAAF42AABfNgAAWDYAAF82AABgNgAAVjYAAFg2AABgNgAAVjYAAGA2AAClGgAAVzYAAFY2AAClGgAAVzYAAKUaAABhNgAAKTYAAFc2AABhNgAAKTYAAGE2AACiGgAAKDYAAFM2AABXNgAAKDYAAFc2AAApNgAAJzYAAFA2AABTNgAAJzYAAFM2AAAoNgAAYjYAAGM2AABkNgAAYjYAAGQ2AABlNgAAYzYAAGY2AABnNgAAYzYAAGc2AABkNgAAZTYAAGQ2AABoNgAAZTYAAGg2AABpNgAAZDYAAGc2AABqNgAAZDYAAGo2AABoNgAA9AIAAGs2AABiNgAA9AIAAGI2AABsNgAAazYAAPICAABjNgAAazYAAGM2AABiNgAA8gIAAG02AABmNgAA8gIAAGY2AABjNgAAbTYAAO8CAAAUNgAAbTYAABQ2AABmNgAAZjYAABQ2AAAaNgAAZjYAABo2AABnNgAAZzYAABo2AAAYNgAAZzYAABg2AABqNgAAajYAABg2AAAZNgAAajYAABk2AABJGgAAaDYAAGo2AABJGgAAaDYAAEkaAABIGgAAaTYAAGg2AABIGgAAaTYAAEgaAABuNgAAbzYAAGk2AABuNgAAbzYAAG42AABwNgAAcTYAAGU2AABpNgAAcTYAAGk2AABvNgAAbDYAAGI2AABlNgAAbDYAAGU2AABxNgAAcjYAAHM2AAB0NgAAcjYAAHQ2AAB1NgAAczYAAHY2AAB3NgAAczYAAHc2AAB0NgAAdTYAAHQ2AAB4NgAAdTYAAHg2AAB5NgAAdDYAAHc2AAB6NgAAdDYAAHo2AAB4NgAA4gIAAHs2AAByNgAA4gIAAHI2AAA4NgAAezYAAHw2AABzNgAAezYAAHM2AAByNgAAfDYAAN8CAAB2NgAAfDYAAHY2AABzNgAA3wIAAH02AAB+NgAA3wIAAH42AAB2NgAAdjYAAH42AAB/NgAAdjYAAH82AAB3NgAAdzYAAH82AACANgAAdzYAAIA2AAB6NgAAejYAAIA2AACBNgAAejYAAIE2AAD+GQAAeDYAAHo2AAD+GQAAeDYAAP4ZAACCNgAAeTYAAHg2AACCNgAAeTYAAII2AAD7GQAAOjYAAHk2AAD7GQAAOjYAAPsZAAD6GQAAOTYAAHU2AAB5NgAAOTYAAHk2AAA6NgAAODYAAHI2AAB1NgAAODYAAHU2AAA5NgAAgzYAAIQ2AACFNgAAgzYAAIU2AACGNgAAhDYAAIc2AACINgAAhDYAAIg2AACFNgAAhjYAAIU2AACJNgAAhjYAAIk2AACKNgAAhTYAAIg2AACLNgAAhTYAAIs2AACJNgAAdAQAALEEAACDNgAAdAQAAIM2AACMNgAAsQQAAI02AACENgAAsQQAAIQ2AACDNgAAjTYAAI42AACHNgAAjTYAAIc2AACENgAAjjYAAEY2AABINgAAjjYAAEg2AACHNgAAhzYAAEg2AABPNgAAhzYAAE82AACINgAAiDYAAE82AABNNgAAiDYAAE02AACLNgAAizYAAE02AABONgAAizYAAE42AACPNgAAiTYAAIs2AACPNgAAiTYAAI82AACaGQAAijYAAIk2AACaGQAAijYAAJoZAACQNgAAkTYAAIo2AACQNgAAkTYAAJA2AAAcGAAAkjYAAIY2AACKNgAAkjYAAIo2AACRNgAAjDYAAIM2AACGNgAAjDYAAIY2AACSNgAAkzYAAJQ2AACVNgAAkzYAAJU2AACWNgAAlDYAAJc2AACYNgAAlDYAAJg2AACVNgAAljYAAJU2AACZNgAAljYAAJk2AACaNgAAlTYAAJg2AACbNgAAlTYAAJs2AACZNgAA0AIAANECAACTNgAA0AIAAJM2AACcNgAA0QIAAJ02AACUNgAA0QIAAJQ2AACTNgAAnTYAAJ42AACXNgAAnTYAAJc2AACUNgAAnjYAAPQCAABsNgAAnjYAAGw2AACXNgAAlzYAAGw2AABxNgAAlzYAAHE2AACYNgAAmDYAAHE2AABvNgAAmDYAAG82AACbNgAAmzYAAG82AABwNgAAmzYAAHA2AABlGQAAmTYAAJs2AABlGQAAmTYAAGUZAABkGQAAmjYAAJk2AABkGQAAmjYAAGQZAACfNgAAoDYAAJo2AACfNgAAoDYAAJ82AAB1GAAAoTYAAJY2AACaNgAAoTYAAJo2AACgNgAAnDYAAJM2AACWNgAAnDYAAJY2AAChNgAAojYAAKM2AACkNgAAojYAAKQ2AAClNgAAozYAAKY2AACnNgAAozYAAKc2AACkNgAApTYAAKQ2AACoNgAApTYAAKg2AACpNgAApDYAAKc2AACqNgAApDYAAKo2AACoNgAAnwQAAKs2AACiNgAAnwQAAKI2AABcNgAAqzYAAKw2AACjNgAAqzYAAKM2AACiNgAArDYAAK02AACmNgAArDYAAKY2AACjNgAArTYAAGkEAACuNgAArTYAAK42AACmNgAApjYAAK42AACvNgAApjYAAK82AACnNgAApzYAAK82AACwNgAApzYAALA2AACqNgAAqjYAALA2AACxNgAAqjYAALE2AABCGQAAqDYAAKo2AABCGQAAqDYAAEIZAABBGQAAqTYAAKg2AABBGQAAqTYAAEEZAACyNgAAXjYAAKk2AACyNgAAXjYAALI2AABfNgAAXTYAAKU2AACpNgAAXTYAAKk2AABeNgAAXDYAAKI2AAClNgAAXDYAAKU2AABdNgAAszYAALQ2AAC1NgAAszYAALU2AAC2NgAAtDYAALc2AAC4NgAAtDYAALg2AAC1NgAAtjYAALU2AAC5NgAAtjYAALk2AAC6NgAAtTYAALg2AAC7NgAAtTYAALs2AAC5NgAAfTYAALw2AACzNgAAfTYAALM2AAB+NgAAvDYAAL02AAC0NgAAvDYAALQ2AACzNgAAvTYAAL42AAC3NgAAvTYAALc2AAC0NgAAvjYAAHUCAADQMwAAvjYAANAzAAC3NgAAtzYAANAzAADUMwAAtzYAANQzAAC4NgAAuDYAANQzAADTMwAAuDYAANMzAAC7NgAAuzYAANMzAAAFGQAAuzYAAAUZAAC/NgAAuTYAALs2AAC/NgAAuTYAAL82AADANgAAujYAALk2AADANgAAujYAAMA2AAABGQAAgDYAALo2AAABGQAAgDYAAAEZAACBNgAAfzYAALY2AAC6NgAAfzYAALo2AACANgAAfjYAALM2AAC2NgAAfjYAALY2AAB/NgAAwTYAAMI2AADDNgAAwTYAAMM2AADENgAAwjYAAMU2AADGNgAAwjYAAMY2AADDNgAAxDYAAMM2AADHNgAAxDYAAMc2AADINgAAwzYAAMY2AADJNgAAwzYAAMk2AADHNgAAWgIAAKsCAADBNgAAWgIAAME2AADjMwAAqwIAAKkCAADCNgAAqwIAAMI2AADBNgAAqQIAAMo2AADFNgAAqQIAAMU2AADCNgAAyjYAANACAACcNgAAyjYAAJw2AADFNgAAxTYAAJw2AAChNgAAxTYAAKE2AADGNgAAxjYAAKE2AACgNgAAxjYAAKA2AADJNgAAyTYAAKA2AAB1GAAAyTYAAHUYAADLNgAAxzYAAMk2AADLNgAAxzYAAMs2AADMNgAAyDYAAMc2AADMNgAAyDYAAMw2AADNNgAA5TMAAMg2AADNNgAA5TMAAM02AADmMwAA5DMAAMQ2AADINgAA5DMAAMg2AADlMwAA4zMAAME2AADENgAA4zMAAMQ2AADkMwAAzjYAAM82AADQNgAAzjYAANA2AADRNgAAzzYAANI2AADTNgAAzzYAANM2AADQNgAA0TYAANA2AADUNgAA0TYAANQ2AADVNgAA0DYAANM2AADWNgAA0DYAANY2AADUNgAAKAQAANc2AADONgAAKAQAAM42AAAJNAAA1zYAAHcEAADPNgAA1zYAAM82AADONgAAdwQAANg2AADSNgAAdwQAANI2AADPNgAA2DYAAHQEAACMNgAA2DYAAIw2AADSNgAA0jYAAIw2AACSNgAA0jYAAJI2AADTNgAA0zYAAJI2AACRNgAA0zYAAJE2AADWNgAA1jYAAJE2AAAcGAAA1jYAABwYAADZNgAA1DYAANY2AADZNgAA1DYAANk2AAAaGAAA1TYAANQ2AAAaGAAA1TYAABoYAADaNgAACzQAANU2AADaNgAACzQAANo2AAAXGAAACjQAANE2AADVNgAACjQAANU2AAALNAAACTQAAM42AADRNgAACTQAANE2AAAKNAAA2zYAANw2AADdNgAA2zYAAN02AADeNgAA3DYAAN82AADgNgAA3DYAAOA2AADdNgAA3jYAAN02AADhNgAA3jYAAOE2AADiNgAA3TYAAOA2AADjNgAA3TYAAOM2AADhNgAAaQQAAOQ2AADbNgAAaQQAANs2AACuNgAA5DYAAGgEAADcNgAA5DYAANw2AADbNgAAaAQAAOU2AADfNgAAaAQAAN82AADcNgAA5TYAAB0EAAAuNAAA5TYAAC40AADfNgAA3zYAAC40AAA2NAAA3zYAADY0AADgNgAA4DYAADY0AAA1NAAA4DYAADU0AADjNgAA4zYAADU0AADaFwAA4zYAANoXAADmNgAA4TYAAOM2AADmNgAA4TYAAOY2AADnNgAA4jYAAOE2AADnNgAA4jYAAOc2AADWFwAAsDYAAOI2AADWFwAAsDYAANYXAACxNgAArzYAAN42AADiNgAArzYAAOI2AACwNgAArjYAANs2AADeNgAArjYAAN42AACvNgAA6DYAAOk2AADqNgAA6DYAAOo2AADrNgAA6TYAAOw2AADtNgAA6TYAAO02AADqNgAA6zYAAOo2AADuNgAA6zYAAO42AADvNgAA6jYAAO02AADwNgAA6jYAAPA2AADuNgAA8TYAAPI2AADoNgAA8TYAAOg2AADzNgAA8jYAADIsAADpNgAA8jYAAOk2AADoNgAAMiwAADEsAADsNgAAMiwAAOw2AADpNgAAMSwAAPQ2AAD1NgAAMSwAAPU2AADsNgAA7DYAAPU2AAD2NgAA7DYAAPY2AADtNgAA7TYAAPY2AAD3NgAA7TYAAPc2AADwNgAA8DYAAPc2AACJGAAA8DYAAIkYAADUIgAA7jYAAPA2AADUIgAA7jYAANQiAADTIgAA7zYAAO42AADTIgAA7zYAANMiAADSIgAA+DYAAO82AADSIgAA+DYAANIiAAAxIgAA+TYAAOs2AADvNgAA+TYAAO82AAD4NgAA8zYAAOg2AADrNgAA8zYAAOs2AAD5NgAA+jYAAPs2AAD8NgAA+jYAAPw2AAD9NgAA+zYAAP42AAD/NgAA+zYAAP82AAD8NgAA/TYAAPw2AAAANwAA/TYAAAA3AAABNwAA/DYAAP82AAACNwAA/DYAAAI3AAAANwAASiwAAEgsAAD6NgAASiwAAPo2AAADNwAASCwAAAQ3AAD7NgAASCwAAPs2AAD6NgAABDcAAAU3AAD+NgAABDcAAP42AAD7NgAABTcAAAY3AAAHNwAABTcAAAc3AAD+NgAA/jYAAAc3AAAINwAA/jYAAAg3AAD/NgAA/zYAAAg3AAAJNwAA/zYAAAk3AAACNwAAAjcAAAk3AAANIgAAAjcAAA0iAADGIgAAADcAAAI3AADGIgAAADcAAMYiAADFIgAAATcAAAA3AADFIgAAATcAAMUiAADEIgAACjcAAAE3AADEIgAACjcAAMQiAABgGAAACzcAAP02AAABNwAACzcAAAE3AAAKNwAAAzcAAPo2AAD9NgAAAzcAAP02AAALNwAADDcAAA03AAAONwAADDcAAA43AAAPNwAADTcAABA3AAARNwAADTcAABE3AAAONwAADzcAAA43AAASNwAADzcAABI3AAATNwAADjcAABE3AAAUNwAADjcAABQ3AAASNwAAXiwAABU3AAAMNwAAXiwAAAw3AAAWNwAAFTcAABc3AAANNwAAFTcAAA03AAAMNwAAFzcAAFosAAAQNwAAFzcAABA3AAANNwAAWiwAAFksAAAYNwAAWiwAABg3AAAQNwAAEDcAABg3AAAZNwAAEDcAABk3AAARNwAAETcAABk3AAAaNwAAETcAABo3AAAUNwAAFDcAABo3AABEGAAAFDcAAEQYAAC3IgAAEjcAABQ3AAC3IgAAEjcAALciAAC2IgAAEzcAABI3AAC2IgAAEzcAALYiAAC1IgAAGzcAABM3AAC1IgAAGzcAALUiAAD+IQAAHDcAAA83AAATNwAAHDcAABM3AAAbNwAAFjcAAAw3AAAPNwAAFjcAAA83AAAcNwAAHTcAAB43AAAfNwAAHTcAAB83AAAgNwAAHjcAACE3AAAiNwAAHjcAACI3AAAfNwAAIDcAAB83AAAjNwAAIDcAACM3AAAkNwAAHzcAACI3AAAlNwAAHzcAACU3AAAjNwAAJjcAACc3AAAdNwAAJjcAAB03AAAoNwAAJzcAAG8sAAAeNwAAJzcAAB43AAAdNwAAbywAACk3AAAhNwAAbywAACE3AAAeNwAAKTcAAG0sAAAqNwAAKTcAACo3AAAhNwAAITcAACo3AAArNwAAITcAACs3AAAiNwAAIjcAACs3AAAsNwAAIjcAACw3AAAlNwAAJTcAACw3AAApIAAAJTcAACkgAACoIgAAIzcAACU3AACoIgAAIzcAAKgiAACnIgAAJDcAACM3AACnIgAAJDcAAKciAACmIgAALTcAACQ3AACmIgAALTcAAKYiAAAyGAAALjcAACA3AAAkNwAALjcAACQ3AAAtNwAAKDcAAB03AAAgNwAAKDcAACA3AAAuNwAALzcAADA3AAAxNwAALzcAADE3AAAyNwAAMDcAADM3AAA0NwAAMDcAADQ3AAAxNwAAMjcAADE3AAA1NwAAMjcAADU3AAA2NwAAMTcAADQ3AAA3NwAAMTcAADc3AAA1NwAAODcAAIUsAAAvNwAAODcAAC83AAA5NwAAhSwAAIQsAAAwNwAAhSwAADA3AAAvNwAAhCwAAIMsAAAzNwAAhCwAADM3AAAwNwAAgywAADo3AAA7NwAAgywAADs3AAAzNwAAMzcAADs3AAA8NwAAMzcAADw3AAA0NwAANDcAADw3AAA9NwAANDcAAD03AAA3NwAANzcAAD03AADjGQAANzcAAOMZAACJIgAANTcAADc3AACJIgAANTcAAIkiAACIIgAANjcAADU3AACIIgAANjcAAIgiAACHIgAAPjcAADY3AACHIgAAPjcAAIciAAALIQAAPzcAADI3AAA2NwAAPzcAADY3AAA+NwAAOTcAAC83AAAyNwAAOTcAADI3AAA/NwAAQDcAAEE3AABCNwAAQDcAAEI3AABDNwAAQTcAAEQ3AABFNwAAQTcAAEU3AABCNwAAQzcAAEI3AABGNwAAQzcAAEY3AABHNwAAQjcAAEU3AABINwAAQjcAAEg3AABGNwAAmywAAEk3AABANwAAmywAAEA3AABKNwAASTcAAJgsAABBNwAASTcAAEE3AABANwAAmCwAAJcsAABENwAAmCwAAEQ3AABBNwAAlywAAJYsAABLNwAAlywAAEs3AABENwAARDcAAEs3AABMNwAARDcAAEw3AABFNwAARTcAAEw3AABNNwAARTcAAE03AABINwAASDcAAE03AADHIQAASDcAAMchAAB7IgAARjcAAEg3AAB7IgAARjcAAHsiAAB6IgAARzcAAEY3AAB6IgAARzcAAHoiAAB5IgAATjcAAEc3AAB5IgAATjcAAHkiAAAFGAAATzcAAEM3AABHNwAATzcAAEc3AABONwAASjcAAEA3AABDNwAASjcAAEM3AABPNwAAUDcAAFE3AABSNwAAUDcAAFI3AABTNwAAUTcAAFQ3AABVNwAAUTcAAFU3AABSNwAAUzcAAFI3AABWNwAAUzcAAFY3AABXNwAAUjcAAFU3AABYNwAAUjcAAFg3AABWNwAAWTcAAFo3AABQNwAAWTcAAFA3AABbNwAAWjcAAK0sAABRNwAAWjcAAFE3AABQNwAArSwAAFw3AABUNwAArSwAAFQ3AABRNwAAXDcAAF03AABeNwAAXDcAAF43AABUNwAAVDcAAF43AABfNwAAVDcAAF83AABVNwAAVTcAAF83AABgNwAAVTcAAGA3AABYNwAAWDcAAGA3AAAKIAAAWDcAAAogAABtIgAAVjcAAFg3AABtIgAAVjcAAG0iAABsIgAAVzcAAFY3AABsIgAAVzcAAGwiAABrIgAAYTcAAFc3AABrIgAAYTcAAGsiAADdGAAAYjcAAFM3AABXNwAAYjcAAFc3AABhNwAAWzcAAFA3AABTNwAAWzcAAFM3AABiNwAAYzcAAGQ3AABlNwAAYzcAAGU3AABmNwAAZDcAAGc3AABoNwAAZDcAAGg3AABlNwAAZjcAAGU3AABpNwAAZjcAAGk3AABqNwAAZTcAAGg3AABrNwAAZTcAAGs3AABpNwAAbDcAAG03AABjNwAAbDcAAGM3AABuNwAAbTcAAMIsAABkNwAAbTcAAGQ3AABjNwAAwiwAAG83AABnNwAAwiwAAGc3AABkNwAAbzcAAMAsAABwNwAAbzcAAHA3AABnNwAAZzcAAHA3AABxNwAAZzcAAHE3AABoNwAAaDcAAHE3AAByNwAAaDcAAHI3AABrNwAAazcAAHI3AAC9FwAAazcAAL0XAABgIgAAaTcAAGs3AABgIgAAaTcAAGAiAABfIgAAajcAAGk3AABfIgAAajcAAF8iAABeIgAAczcAAGo3AABeIgAAczcAAF4iAACeIQAAdDcAAGY3AABqNwAAdDcAAGo3AABzNwAAbjcAAGM3AABmNwAAbjcAAGY3AAB0NwAAdTcAAHY3AAB3NwAAdTcAAHc3AAB4NwAAdjcAAHk3AAB6NwAAdjcAAHo3AAB3NwAAeDcAAHc3AAB7NwAAeDcAAHs3AAB8NwAAdzcAAHo3AAB9NwAAdzcAAH03AAB7NwAAfjcAAH83AAB1NwAAfjcAAHU3AACANwAAfzcAAIE3AAB2NwAAfzcAAHY3AAB1NwAAgTcAAII3AAB5NwAAgTcAAHk3AAB2NwAAgjcAAIM3AACENwAAgjcAAIQ3AAB5NwAAeTcAAIQ3AACFNwAAeTcAAIU3AAB6NwAAejcAAIU3AACGNwAAejcAAIY3AAB9NwAAfTcAAIY3AACQFwAAfTcAAJAXAABRIgAAezcAAH03AABRIgAAezcAAFEiAABQIgAAfDcAAHs3AABQIgAAfDcAAFAiAABPIgAAhzcAAHw3AABPIgAAhzcAAE8iAACKIQAAiDcAAHg3AAB8NwAAiDcAAHw3AACHNwAAgDcAAHU3AAB4NwAAgDcAAHg3AACINwAAiTcAAIo3AACLNwAAiTcAAIs3AACMNwAAijcAAI03AACONwAAijcAAI43AACLNwAAjDcAAIs3AACPNwAAjDcAAI83AACQNwAAizcAAI43AACRNwAAizcAAJE3AACPNwAAkjcAAJM3AACJNwAAkjcAAIk3AACUNwAAkzcAAJU3AACKNwAAkzcAAIo3AACJNwAAlTcAAOwsAACNNwAAlTcAAI03AACKNwAA7CwAAJY3AACXNwAA7CwAAJc3AACNNwAAjTcAAJc3AACYNwAAjTcAAJg3AACONwAAjjcAAJg3AACZNwAAjjcAAJk3AACRNwAAkTcAAJk3AAB2IQAAkTcAAHYhAABDIgAAjzcAAJE3AABDIgAAjzcAAEMiAABCIgAAkDcAAI83AABCIgAAkDcAAEIiAABBIgAAmjcAAJA3AABBIgAAmjcAAEEiAAB/FwAAmzcAAIw3AACQNwAAmzcAAJA3AACaNwAAlDcAAIk3AACMNwAAlDcAAIw3AACbNwAAnDcAAJ03AACeNwAAnDcAAJ43AACfNwAAnTcAAKA3AAChNwAAnTcAAKE3AACeNwAAnzcAAJ43AACiNwAAnzcAAKI3AACjNwAAnjcAAKE3AACkNwAAnjcAAKQ3AACiNwAApTcAAKY3AACcNwAApTcAAJw3AACnNwAApjcAAKg3AACdNwAApjcAAJ03AACcNwAAqDcAAP0sAACgNwAAqDcAAKA3AACdNwAA/SwAAPE2AADzNgAA/SwAAPM2AACgNwAAoDcAAPM2AAD5NgAAoDcAAPk2AAChNwAAoTcAAPk2AAD4NgAAoTcAAPg2AACkNwAApDcAAPg2AAAxIgAApDcAADEiAAAwIgAAojcAAKQ3AAAwIgAAojcAADAiAAAvIgAAozcAAKI3AAAvIgAAozcAAC8iAAAuIgAAqTcAAKM3AAAuIgAAqTcAAC4iAABjHQAAqjcAAJ83AACjNwAAqjcAAKM3AACpNwAApzcAAJw3AACfNwAApzcAAJ83AACqNwAAqzcAAKw3AACtNwAAqzcAAK03AACuNwAArDcAAK83AACwNwAArDcAALA3AACtNwAArjcAAK03AACxNwAArjcAALE3AACyNwAArTcAALA3AACzNwAArTcAALM3AACxNwAABjcAABQtAACrNwAABjcAAKs3AAAHNwAAFC0AALQ3AACsNwAAFC0AAKw3AACrNwAAtDcAABItAACvNwAAtDcAAK83AACsNwAAEi0AABEtAAC1NwAAEi0AALU3AACvNwAArzcAALU3AAC2NwAArzcAALY3AACwNwAAsDcAALY3AAC3NwAAsDcAALc3AACzNwAAszcAALc3AABTIQAAszcAAFMhAAARIgAAsTcAALM3AAARIgAAsTcAABEiAAAQIgAAsjcAALE3AAAQIgAAsjcAABAiAAAOIgAACTcAALI3AAAOIgAACTcAAA4iAAANIgAACDcAAK43AACyNwAACDcAALI3AAAJNwAABzcAAKs3AACuNwAABzcAAK43AAAINwAAuDcAALk3AAC6NwAAuDcAALo3AAC7NwAAuTcAALw3AAC9NwAAuTcAAL03AAC6NwAAuzcAALo3AAC+NwAAuzcAAL43AAC/NwAAujcAAL03AADANwAAujcAAMA3AAC+NwAAIy0AACEtAAC4NwAAIy0AALg3AADBNwAAIS0AACAtAAC5NwAAIS0AALk3AAC4NwAAIC0AAMI3AAC8NwAAIC0AALw3AAC5NwAAwjcAAF4sAAAWNwAAwjcAABY3AAC8NwAAvDcAABY3AAAcNwAAvDcAABw3AAC9NwAAvTcAABw3AAAbNwAAvTcAABs3AADANwAAwDcAABs3AAD+IQAAwDcAAP4hAAD9IQAAvjcAAMA3AAD9IQAAvjcAAP0hAAD8IQAAvzcAAL43AAD8IQAAvzcAAPwhAAD7IQAAwzcAAL83AAD7IQAAwzcAAPshAABEIQAAxDcAALs3AAC/NwAAxDcAAL83AADDNwAAwTcAALg3AAC7NwAAwTcAALs3AADENwAAxTcAAMY3AADHNwAAxTcAAMc3AADINwAAxjcAAMk3AADKNwAAxjcAAMo3AADHNwAAyDcAAMc3AADLNwAAyDcAAMs3AADMNwAAxzcAAMo3AADNNwAAxzcAAM03AADLNwAAliwAADQtAADFNwAAliwAAMU3AABLNwAANC0AADMtAADGNwAANC0AAMY3AADFNwAAMy0AAM43AADJNwAAMy0AAMk3AADGNwAAzjcAADEtAADPNwAAzjcAAM83AADJNwAAyTcAAM83AADQNwAAyTcAANA3AADKNwAAyjcAANA3AADRNwAAyjcAANE3AADNNwAAzTcAANE3AAD1IAAAzTcAAPUgAADLIQAAyzcAAM03AADLIQAAyzcAAMshAADKIQAAzDcAAMs3AADKIQAAzDcAAMohAADIIQAATTcAAMw3AADIIQAATTcAAMghAADHIQAATDcAAMg3AADMNwAATDcAAMw3AABNNwAASzcAAMU3AADINwAASzcAAMg3AABMNwAA0jcAANM3AADUNwAA0jcAANQ3AADVNwAA0zcAANY3AADXNwAA0zcAANc3AADUNwAA1TcAANQ3AADYNwAA1TcAANg3AADZNwAA1DcAANc3AADaNwAA1DcAANo3AADYNwAARC0AANs3AADSNwAARC0AANI3AADcNwAA2zcAAN03AADTNwAA2zcAANM3AADSNwAA3TcAAN43AADWNwAA3TcAANY3AADTNwAA3jcAAGw3AABuNwAA3jcAAG43AADWNwAA1jcAAG43AAB0NwAA1jcAAHQ3AADXNwAA1zcAAHQ3AABzNwAA1zcAAHM3AADaNwAA2jcAAHM3AACeIQAA2jcAAJ4hAACdIQAA2DcAANo3AACdIQAA2DcAAJ0hAACcIQAA2TcAANg3AACcIQAA2TcAAJwhAACbIQAA3zcAANk3AACbIQAA3zcAAJshAADlIAAA4DcAANU3AADZNwAA4DcAANk3AADfNwAA3DcAANI3AADVNwAA3DcAANU3AADgNwAA4TcAAOI3AADjNwAA4TcAAOM3AADkNwAA4jcAAOU3AADmNwAA4jcAAOY3AADjNwAA5DcAAOM3AADnNwAA5DcAAOc3AADoNwAA4zcAAOY3AADpNwAA4zcAAOk3AADnNwAAVi0AAOo3AADhNwAAVi0AAOE3AADrNwAA6jcAAFMtAADiNwAA6jcAAOI3AADhNwAAUy0AAOw3AADlNwAAUy0AAOU3AADiNwAA7DcAAH43AACANwAA7DcAAIA3AADlNwAA5TcAAIA3AACINwAA5TcAAIg3AADmNwAA5jcAAIg3AACHNwAA5jcAAIc3AADpNwAA6TcAAIc3AACKIQAA6TcAAIohAACJIQAA5zcAAOk3AACJIQAA5zcAAIkhAACIIQAA6DcAAOc3AACIIQAA6DcAAIghAACHIQAA7TcAAOg3AACHIQAA7TcAAIchAAC/IAAA7jcAAOQ3AADoNwAA7jcAAOg3AADtNwAA6zcAAOE3AADkNwAA6zcAAOQ3AADuNwAA7zcAAPA3AADxNwAA7zcAAPE3AADyNwAA8DcAAPM3AAD0NwAA8DcAAPQ3AADxNwAA8jcAAPE3AAD1NwAA8jcAAPU3AAD2NwAA8TcAAPQ3AAD3NwAA8TcAAPc3AAD1NwAAljcAAGotAADvNwAAljcAAO83AACXNwAAai0AAGktAADwNwAAai0AAPA3AADvNwAAaS0AAPg3AADzNwAAaS0AAPM3AADwNwAA+DcAAPk3AAD6NwAA+DcAAPo3AADzNwAA8zcAAPo3AAD7NwAA8zcAAPs3AAD0NwAA9DcAAPs3AAD8NwAA9DcAAPw3AAD3NwAA9zcAAPw3AACHIAAA9zcAAIcgAAB6IQAA9TcAAPc3AAB6IQAA9TcAAHohAAB5IQAA9jcAAPU3AAB5IQAA9jcAAHkhAAB3IQAAmTcAAPY3AAB3IQAAmTcAAHchAAB2IQAAmDcAAPI3AAD2NwAAmDcAAPY3AACZNwAAlzcAAO83AADyNwAAlzcAAPI3AACYNwAA/TcAAP43AAD/NwAA/TcAAP83AAAAOAAA/jcAAAE4AAACOAAA/jcAAAI4AAD/NwAAADgAAP83AAADOAAAADgAAAM4AAAEOAAA/zcAAAI4AAAFOAAA/zcAAAU4AAADOAAAES0AAAY4AAD9NwAAES0AAP03AAC1NwAABjgAAAc4AAD+NwAABjgAAP43AAD9NwAABzgAAHstAAABOAAABzgAAAE4AAD+NwAAey0AAHotAAAIOAAAey0AAAg4AAABOAAAATgAAAg4AAAJOAAAATgAAAk4AAACOAAAAjgAAAk4AAAKOAAAAjgAAAo4AAAFOAAABTgAAAo4AABPIAAABTgAAE8gAABXIQAAAzgAAAU4AABXIQAAAzgAAFchAABWIQAABDgAAAM4AABWIQAABDgAAFYhAABUIQAAtzcAAAQ4AABUIQAAtzcAAFQhAABTIQAAtjcAAAA4AAAEOAAAtjcAAAQ4AAC3NwAAtTcAAP03AAAAOAAAtTcAAAA4AAC2NwAACzgAAAw4AAANOAAACzgAAA04AAAOOAAADDgAAA84AAAQOAAADDgAABA4AAANOAAADjgAAA04AAAROAAADjgAABE4AAASOAAADTgAABA4AAATOAAADTgAABM4AAAROAAAji0AABQ4AAALOAAAji0AAAs4AAAVOAAAFDgAABY4AAAMOAAAFDgAAAw4AAALOAAAFjgAABc4AAAPOAAAFjgAAA84AAAMOAAAFzgAACMtAADBNwAAFzgAAME3AAAPOAAADzgAAME3AADENwAADzgAAMQ3AAAQOAAAEDgAAMQ3AADDNwAAEDgAAMM3AAATOAAAEzgAAMM3AABEIQAAEzgAAEQhAABDIQAAETgAABM4AABDIQAAETgAAEMhAABCIQAAEjgAABE4AABCIQAAEjgAAEIhAABBIQAAGDgAABI4AABBIQAAGDgAAEEhAAD8HwAAGTgAAA44AAASOAAAGTgAABI4AAAYOAAAFTgAAAs4AAAOOAAAFTgAAA44AAAZOAAAGjgAABs4AAAcOAAAGjgAABw4AAAdOAAAGzgAAB44AAAfOAAAGzgAAB84AAAcOAAAHTgAABw4AAAgOAAAHTgAACA4AAAhOAAAHDgAAB84AAAiOAAAHDgAACI4AAAgOAAAIzgAACQ4AAAaOAAAIzgAABo4AAAlOAAAJDgAACY4AAAbOAAAJDgAABs4AAAaOAAAJjgAACc4AAAeOAAAJjgAAB44AAAbOAAAJzgAADg3AAA5NwAAJzgAADk3AAAeOAAAHjgAADk3AAA/NwAAHjgAAD83AAAfOAAAHzgAAD83AAA+NwAAHzgAAD43AAAiOAAAIjgAAD43AAALIQAAIjgAAAshAAAKIQAAIDgAACI4AAAKIQAAIDgAAAohAAAJIQAAITgAACA4AAAJIQAAITgAAAkhAAAIIQAAKDgAACE4AAAIIQAAKDgAAAghAADBHQAAKTgAAB04AAAhOAAAKTgAACE4AAAoOAAAJTgAABo4AAAdOAAAJTgAAB04AAApOAAAKjgAACs4AAAsOAAAKjgAACw4AAAtOAAAKzgAAC44AAAvOAAAKzgAAC84AAAsOAAALTgAACw4AAAwOAAALTgAADA4AAAxOAAALDgAAC84AAAyOAAALDgAADI4AAAwOAAAMS0AALQtAAAqOAAAMS0AACo4AADPNwAAtC0AADM4AAArOAAAtC0AACs4AAAqOAAAMzgAALItAAAuOAAAMzgAAC44AAArOAAAsi0AALEtAAA0OAAAsi0AADQ4AAAuOAAALjgAADQ4AAA1OAAALjgAADU4AAAvOAAALzgAADU4AAA2OAAALzgAADY4AAAyOAAAMjgAADY4AACYIAAAMjgAAJggAAD5IAAAMDgAADI4AAD5IAAAMDgAAPkgAAD4IAAAMTgAADA4AAD4IAAAMTgAAPggAAD2IAAA0TcAADE4AAD2IAAA0TcAAPYgAAD1IAAA0DcAAC04AAAxOAAA0DcAADE4AADRNwAAzzcAACo4AAAtOAAAzzcAAC04AADQNwAANzgAADg4AAA5OAAANzgAADk4AAA6OAAAODgAADs4AAA8OAAAODgAADw4AAA5OAAAOjgAADk4AAA9OAAAOjgAAD04AAA+OAAAOTgAADw4AAA/OAAAOTgAAD84AAA9OAAAQDgAAEE4AAA3OAAAQDgAADc4AABCOAAAQTgAAEM4AAA4OAAAQTgAADg4AAA3OAAAQzgAAEQ4AAA7OAAAQzgAADs4AAA4OAAARDgAAEQtAADcNwAARDgAANw3AAA7OAAAOzgAANw3AADgNwAAOzgAAOA3AAA8OAAAPDgAAOA3AADfNwAAPDgAAN83AAA/OAAAPzgAAN83AADlIAAAPzgAAOUgAADkIAAAPTgAAD84AADkIAAAPTgAAOQgAADjIAAAPjgAAD04AADjIAAAPjgAAOMgAADiIAAARTgAAD44AADiIAAARTgAAOIgAADpHwAARjgAADo4AAA+OAAARjgAAD44AABFOAAAQjgAADc4AAA6OAAAQjgAADo4AABGOAAARzgAAEg4AABJOAAARzgAAEk4AABKOAAASDgAAEs4AABMOAAASDgAAEw4AABJOAAASjgAAEk4AABNOAAASjgAAE04AABOOAAASTgAAEw4AABPOAAASTgAAE84AABNOAAAUDgAANMtAABHOAAAUDgAAEc4AABROAAA0y0AAFI4AABIOAAA0y0AAEg4AABHOAAAUjgAANEtAABLOAAAUjgAAEs4AABIOAAA0S0AAFYtAADrNwAA0S0AAOs3AABLOAAASzgAAOs3AADuNwAASzgAAO43AABMOAAATDgAAO43AADtNwAATDgAAO03AABPOAAATzgAAO03AAC/IAAATzgAAL8gAAC+IAAATTgAAE84AAC+IAAATTgAAL4gAAC9IAAATjgAAE04AAC9IAAATjgAAL0gAAC8IAAAUzgAAE44AAC8IAAAUzgAALwgAAC6HwAAVDgAAEo4AABOOAAAVDgAAE44AABTOAAAUTgAAEc4AABKOAAAUTgAAEo4AABUOAAAVTgAAFY4AABXOAAAVTgAAFc4AABYOAAAVjgAAFk4AABaOAAAVjgAAFo4AABXOAAAWDgAAFc4AABbOAAAWDgAAFs4AABcOAAAVzgAAFo4AABdOAAAVzgAAF04AABbOAAAsS0AAOctAABVOAAAsS0AAFU4AAA0OAAA5y0AAOYtAABWOAAA5y0AAFY4AABVOAAA5i0AAOUtAABZOAAA5i0AAFk4AABWOAAA5S0AAF44AABfOAAA5S0AAF84AABZOAAAWTgAAF84AABgOAAAWTgAAGA4AABaOAAAWjgAAGA4AABhOAAAWjgAAGE4AABdOAAAXTgAAGE4AAClHwAAXTgAAKUfAACcIAAAWzgAAF04AACcIAAAWzgAAJwgAACbIAAAXDgAAFs4AACbIAAAXDgAAJsgAACZIAAANjgAAFw4AACZIAAANjgAAJkgAACYIAAANTgAAFg4AABcOAAANTgAAFw4AAA2OAAANDgAAFU4AABYOAAANDgAAFg4AAA1OAAAYjgAAGM4AABkOAAAYjgAAGQ4AABlOAAAYzgAAGY4AABnOAAAYzgAAGc4AABkOAAAZTgAAGQ4AABoOAAAZTgAAGg4AABpOAAAZDgAAGc4AABqOAAAZDgAAGo4AABoOAAA+TcAAGs4AABiOAAA+TcAAGI4AAD6NwAAazgAAPctAABjOAAAazgAAGM4AABiOAAA9y0AAGw4AABmOAAA9y0AAGY4AABjOAAAbDgAAG04AABuOAAAbDgAAG44AABmOAAAZjgAAG44AABvOAAAZjgAAG84AABnOAAAZzgAAG84AABwOAAAZzgAAHA4AABqOAAAajgAAHA4AACSHwAAajgAAJIfAACLIAAAaDgAAGo4AACLIAAAaDgAAIsgAACKIAAAaTgAAGg4AACKIAAAaTgAAIogAACIIAAA/DcAAGk4AACIIAAA/DcAAIggAACHIAAA+zcAAGU4AABpOAAA+zcAAGk4AAD8NwAA+jcAAGI4AABlOAAA+jcAAGU4AAD7NwAAcTgAAHI4AABzOAAAcTgAAHM4AAB0OAAAcjgAAHU4AAB2OAAAcjgAAHY4AABzOAAAdDgAAHM4AAB3OAAAdDgAAHc4AAB4OAAAczgAAHY4AAB5OAAAczgAAHk4AAB3OAAAei0AAHo4AABxOAAAei0AAHE4AAAIOAAAejgAAAkuAAByOAAAejgAAHI4AABxOAAACS4AAHs4AAB1OAAACS4AAHU4AAByOAAAezgAAAcuAAB8OAAAezgAAHw4AAB1OAAAdTgAAHw4AAB9OAAAdTgAAH04AAB2OAAAdjgAAH04AAB+OAAAdjgAAH44AAB5OAAAeTgAAH44AABqHwAAeTgAAGofAABTIAAAdzgAAHk4AABTIAAAdzgAAFMgAABSIAAAeDgAAHc4AABSIAAAeDgAAFIgAABQIAAACjgAAHg4AABQIAAACjgAAFAgAABPIAAACTgAAHQ4AAB4OAAACTgAAHg4AAAKOAAACDgAAHE4AAB0OAAACDgAAHQ4AAAJOAAAfzgAAIA4AACBOAAAfzgAAIE4AACCOAAAgDgAAIM4AACEOAAAgDgAAIQ4AACBOAAAgjgAAIE4AACFOAAAgjgAAIU4AACGOAAAgTgAAIQ4AACHOAAAgTgAAIc4AACFOAAAbSwAAIg4AAB/OAAAbSwAAH84AAAqNwAAiDgAAIk4AACAOAAAiDgAAIA4AAB/OAAAiTgAAIo4AACDOAAAiTgAAIM4AACAOAAAijgAABguAACLOAAAijgAAIs4AACDOAAAgzgAAIs4AACMOAAAgzgAAIw4AACEOAAAhDgAAIw4AACNOAAAhDgAAI04AACHOAAAhzgAAI04AAB0GwAAhzgAAHQbAAAtIAAAhTgAAIc4AAAtIAAAhTgAAC0gAAAsIAAAhjgAAIU4AAAsIAAAhjgAACwgAAAqIAAALDcAAIY4AAAqIAAALDcAACogAAApIAAAKzcAAII4AACGOAAAKzcAAIY4AAAsNwAAKjcAAH84AACCOAAAKjcAAII4AAArNwAAjjgAAI84AACQOAAAjjgAAJA4AACROAAAjzgAAJI4AACTOAAAjzgAAJM4AACQOAAAkTgAAJA4AACUOAAAkTgAAJQ4AACVOAAAkDgAAJM4AACWOAAAkDgAAJY4AACUOAAAMC4AAC4uAACOOAAAMC4AAI44AACXOAAALi4AAC0uAACPOAAALi4AAI84AACOOAAALS4AACwuAACSOAAALS4AAJI4AACPOAAALC4AACsuAACYOAAALC4AAJg4AACSOAAAkjgAAJg4AACZOAAAkjgAAJk4AACTOAAAkzgAAJk4AACaOAAAkzgAAJo4AACWOAAAljgAAJo4AADsFwAAljgAAOwXAAAeIAAAlDgAAJY4AAAeIAAAlDgAAB4gAAAdIAAAlTgAAJQ4AAAdIAAAlTgAAB0gAAAcIAAAmzgAAJU4AAAcIAAAmzgAABwgAAAEGwAAnDgAAJE4AACVOAAAnDgAAJU4AACbOAAAlzgAAI44AACROAAAlzgAAJE4AACcOAAAnTgAAJ44AACfOAAAnTgAAJ84AACgOAAAnjgAAKE4AACiOAAAnjgAAKI4AACfOAAAoDgAAJ84AACjOAAAoDgAAKM4AACkOAAAnzgAAKI4AAClOAAAnzgAAKU4AACjOAAAXTcAAKY4AACdOAAAXTcAAJ04AABeNwAApjgAAEIuAACeOAAApjgAAJ44AACdOAAAQi4AAEEuAAChOAAAQi4AAKE4AACeOAAAQS4AAEAuAACnOAAAQS4AAKc4AAChOAAAoTgAAKc4AACoOAAAoTgAAKg4AACiOAAAojgAAKg4AACpOAAAojgAAKk4AAClOAAApTgAAKk4AABWHgAApTgAAFYeAAAOIAAAozgAAKU4AAAOIAAAozgAAA4gAAANIAAApDgAAKM4AAANIAAApDgAAA0gAAALIAAAYDcAAKQ4AAALIAAAYDcAAAsgAAAKIAAAXzcAAKA4AACkOAAAXzcAAKQ4AABgNwAAXjcAAJ04AACgOAAAXjcAAKA4AABfNwAAqjgAAKs4AACsOAAAqjgAAKw4AACtOAAAqzgAAK44AACvOAAAqzgAAK84AACsOAAArTgAAKw4AACwOAAArTgAALA4AACxOAAArDgAAK84AACyOAAArDgAALI4AACwOAAAszgAALQ4AACqOAAAszgAAKo4AAC1OAAAtDgAAFEuAACrOAAAtDgAAKs4AACqOAAAUS4AAFAuAACuOAAAUS4AAK44AACrOAAAUC4AAI4tAAAVOAAAUC4AABU4AACuOAAArjgAABU4AAAZOAAArjgAABk4AACvOAAArzgAABk4AAAYOAAArzgAABg4AACyOAAAsjgAABg4AAD8HwAAsjgAAPwfAAD7HwAAsDgAALI4AAD7HwAAsDgAAPsfAAD6HwAAsTgAALA4AAD6HwAAsTgAAPofAAD5HwAAtjgAALE4AAD5HwAAtjgAAPkfAACjHgAAtzgAAK04AACxOAAAtzgAALE4AAC2OAAAtTgAAKo4AACtOAAAtTgAAK04AAC3OAAAuDgAALk4AAC6OAAAuDgAALo4AAC7OAAAuTgAALw4AAC9OAAAuTgAAL04AAC6OAAAuzgAALo4AAC+OAAAuzgAAL44AAC/OAAAujgAAL04AADAOAAAujgAAMA4AAC+OAAAZC4AAME4AAC4OAAAZC4AALg4AADCOAAAwTgAAMM4AAC5OAAAwTgAALk4AAC4OAAAwzgAAMQ4AAC8OAAAwzgAALw4AAC5OAAAxDgAAEA4AABCOAAAxDgAAEI4AAC8OAAAvDgAAEI4AABGOAAAvDgAAEY4AAC9OAAAvTgAAEY4AABFOAAAvTgAAEU4AADAOAAAwDgAAEU4AADpHwAAwDgAAOkfAADoHwAAvjgAAMA4AADoHwAAvjgAAOgfAADnHwAAvzgAAL44AADnHwAAvzgAAOcfAADmHwAAxTgAAL84AADmHwAAxTgAAOYfAADcHgAAxjgAALs4AAC/OAAAxjgAAL84AADFOAAAwjgAALg4AAC7OAAAwjgAALs4AADGOAAAxzgAAMg4AADJOAAAxzgAAMk4AADKOAAAyDgAAMs4AADMOAAAyDgAAMw4AADJOAAAyjgAAMk4AADNOAAAyjgAAM04AADOOAAAyTgAAMw4AADPOAAAyTgAAM84AADNOAAAeC4AAHYuAADHOAAAeC4AAMc4AADQOAAAdi4AANE4AADIOAAAdi4AAMg4AADHOAAA0TgAANI4AADLOAAA0TgAAMs4AADIOAAA0jgAANM4AADUOAAA0jgAANQ4AADLOAAAyzgAANQ4AADVOAAAyzgAANU4AADMOAAAzDgAANU4AADWOAAAzDgAANY4AADPOAAAzzgAANY4AAC1GgAAzzgAALUaAADaHwAAzTgAAM84AADaHwAAzTgAANofAADZHwAAzjgAAM04AADZHwAAzjgAANkfAADYHwAA1zgAAM44AADYHwAA1zgAANgfAACsFwAA2DgAAMo4AADOOAAA2DgAAM44AADXOAAA0DgAAMc4AADKOAAA0DgAAMo4AADYOAAA2TgAANo4AADbOAAA2TgAANs4AADcOAAA2jgAAN04AADeOAAA2jgAAN44AADbOAAA3DgAANs4AADfOAAA3DgAAN84AADgOAAA2zgAAN44AADhOAAA2zgAAOE4AADfOAAA4jgAAOM4AADZOAAA4jgAANk4AADkOAAA4zgAAOU4AADaOAAA4zgAANo4AADZOAAA5TgAAOY4AADdOAAA5TgAAN04AADaOAAA5jgAAOc4AADoOAAA5jgAAOg4AADdOAAA3TgAAOg4AADpOAAA3TgAAOk4AADeOAAA3jgAAOk4AADqOAAA3jgAAOo4AADhOAAA4TgAAOo4AAA0HwAA4TgAADQfAADLHwAA3zgAAOE4AADLHwAA3zgAAMsfAADKHwAA4DgAAN84AADKHwAA4DgAAMofAADJHwAA6zgAAOA4AADJHwAA6zgAAMkfAACBHwAA7DgAANw4AADgOAAA7DgAAOA4AADrOAAA5DgAANk4AADcOAAA5DgAANw4AADsOAAA7TgAAO44AADvOAAA7TgAAO84AADwOAAA7jgAAPE4AADyOAAA7jgAAPI4AADvOAAA8DgAAO84AADzOAAA8DgAAPM4AAD0OAAA7zgAAPI4AAD1OAAA7zgAAPU4AADzOAAA9jgAAPc4AADtOAAA9jgAAO04AAD4OAAA9zgAAPk4AADuOAAA9zgAAO44AADtOAAA+TgAAJsuAADxOAAA+TgAAPE4AADuOAAAmy4AAFA4AABROAAAmy4AAFE4AADxOAAA8TgAAFE4AABUOAAA8TgAAFQ4AADyOAAA8jgAAFQ4AABTOAAA8jgAAFM4AAD1OAAA9TgAAFM4AAC6HwAA9TgAALofAAC5HwAA8zgAAPU4AAC5HwAA8zgAALkfAAC4HwAA9DgAAPM4AAC4HwAA9DgAALgfAAC3HwAA+jgAAPQ4AAC3HwAA+jgAALcfAAC4HgAA+zgAAPA4AAD0OAAA+zgAAPQ4AAD6OAAA+DgAAO04AADwOAAA+DgAAPA4AAD7OAAA/DgAAP04AAD+OAAA/DgAAP44AAD/OAAA/TgAAAA5AAABOQAA/TgAAAE5AAD+OAAA/zgAAP44AAACOQAA/zgAAAI5AAADOQAA/jgAAAE5AAAEOQAA/jgAAAQ5AAACOQAAXjgAAAU5AAD8OAAAXjgAAPw4AABfOAAABTkAAAY5AAD9OAAABTkAAP04AAD8OAAABjkAALAuAAAAOQAABjkAAAA5AAD9OAAAsC4AAAc5AAAIOQAAsC4AAAg5AAAAOQAAADkAAAg5AAAJOQAAADkAAAk5AAABOQAAATkAAAk5AAAKOQAAATkAAAo5AAAEOQAABDkAAAo5AAAQHwAABDkAABAfAACpHwAAAjkAAAQ5AACpHwAAAjkAAKkfAACoHwAAAzkAAAI5AACoHwAAAzkAAKgfAACmHwAAYTgAAAM5AACmHwAAYTgAAKYfAAClHwAAYDgAAP84AAADOQAAYDgAAAM5AABhOAAAXzgAAPw4AAD/OAAAXzgAAP84AABgOAAACzkAAAw5AAANOQAACzkAAA05AAAOOQAADDkAAA85AAAQOQAADDkAABA5AAANOQAADjkAAA05AAAROQAADjkAABE5AAASOQAADTkAABA5AAATOQAADTkAABM5AAAROQAAbTgAAMMuAAALOQAAbTgAAAs5AABuOAAAwy4AABQ5AAAMOQAAwy4AAAw5AAALOQAAFDkAAMEuAAAPOQAAFDkAAA85AAAMOQAAwS4AABU5AAAWOQAAwS4AABY5AAAPOQAADzkAABY5AAAXOQAADzkAABc5AAAQOQAAEDkAABc5AAAYOQAAEDkAABg5AAATOQAAEzkAABg5AACNHgAAEzkAAI0eAACWHwAAETkAABM5AACWHwAAETkAAJYfAACVHwAAEjkAABE5AACVHwAAEjkAAJUfAACTHwAAcDgAABI5AACTHwAAcDgAAJMfAACSHwAAbzgAAA45AAASOQAAbzgAABI5AABwOAAAbjgAAAs5AAAOOQAAbjgAAA45AABvOAAAGTkAABo5AAAbOQAAGTkAABs5AAAcOQAAGjkAAB05AAAeOQAAGjkAAB45AAAbOQAAHDkAABs5AAAfOQAAHDkAAB85AAAgOQAAGzkAAB45AAAhOQAAGzkAACE5AAAfOQAAIjkAACM5AAAZOQAAIjkAABk5AAAkOQAAIzkAAM8uAAAaOQAAIzkAABo5AAAZOQAAzy4AACU5AAAdOQAAzy4AAB05AAAaOQAAJTkAAOI4AADkOAAAJTkAAOQ4AAAdOQAAHTkAAOQ4AADsOAAAHTkAAOw4AAAeOQAAHjkAAOw4AADrOAAAHjkAAOs4AAAhOQAAITkAAOs4AACBHwAAITkAAIEfAACAHwAAHzkAACE5AACAHwAAHzkAAIAfAAB/HwAAIDkAAB85AAB/HwAAIDkAAH8fAAB+HwAAJjkAACA5AAB+HwAAJjkAAH4fAACUGgAAJzkAABw5AAAgOQAAJzkAACA5AAAmOQAAJDkAABk5AAAcOQAAJDkAABw5AAAnOQAAKDkAACk5AAAqOQAAKDkAACo5AAArOQAAKTkAACw5AAAtOQAAKTkAAC05AAAqOQAAKzkAACo5AAAuOQAAKzkAAC45AAAvOQAAKjkAAC05AAAwOQAAKjkAADA5AAAuOQAABy4AADE5AAAoOQAABy4AACg5AAB8OAAAMTkAADI5AAApOQAAMTkAACk5AAAoOQAAMjkAADM5AAAsOQAAMjkAACw5AAApOQAAMzkAADQ5AAA1OQAAMzkAADU5AAAsOQAALDkAADU5AAA2OQAALDkAADY5AAAtOQAALTkAADY5AAA3OQAALTkAADc5AAAwOQAAMDkAADc5AABoHgAAMDkAAGgeAABuHwAALjkAADA5AABuHwAALjkAAG4fAABtHwAALzkAAC45AABtHwAALzkAAG0fAABrHwAAfjgAAC85AABrHwAAfjgAAGsfAABqHwAAfTgAACs5AAAvOQAAfTgAAC85AAB+OAAAfDgAACg5AAArOQAAfDgAACs5AAB9OAAAODkAADk5AAA6OQAAODkAADo5AAA7OQAAOTkAADw5AAA9OQAAOTkAAD05AAA6OQAAOzkAADo5AAA+OQAAOzkAAD45AAA/OQAAOjkAAD05AABAOQAAOjkAAEA5AAA+OQAA5zgAAEE5AAA4OQAA5zgAADg5AADoOAAAQTkAAPYuAAA5OQAAQTkAADk5AAA4OQAA9i4AAEI5AAA8OQAA9i4AADw5AAA5OQAAQjkAAPQuAABDOQAAQjkAAEM5AAA8OQAAPDkAAEM5AABEOQAAPDkAAEQ5AAA9OQAAPTkAAEQ5AABFOQAAPTkAAEU5AABAOQAAQDkAAEU5AADIHgAAQDkAAMgeAAA4HwAAPjkAAEA5AAA4HwAAPjkAADgfAAA3HwAAPzkAAD45AAA3HwAAPzkAADcfAAA1HwAA6jgAAD85AAA1HwAA6jgAADUfAAA0HwAA6TgAADs5AAA/OQAA6TgAAD85AADqOAAA6DgAADg5AAA7OQAA6DgAADs5AADpOAAARjkAAEc5AABIOQAARjkAAEg5AABJOQAARzkAAEo5AABLOQAARzkAAEs5AABIOQAASTkAAEg5AABMOQAASTkAAEw5AABNOQAASDkAAEs5AABOOQAASDkAAE45AABMOQAABzkAAE85AABGOQAABzkAAEY5AAAIOQAATzkAAAkvAABHOQAATzkAAEc5AABGOQAACS8AAFA5AABKOQAACS8AAEo5AABHOQAAUDkAAFE5AABSOQAAUDkAAFI5AABKOQAASjkAAFI5AABTOQAASjkAAFM5AABLOQAASzkAAFM5AABUOQAASzkAAFQ5AABOOQAATjkAAFQ5AACeHgAATjkAAJ4eAAAUHwAATDkAAE45AAAUHwAATDkAABQfAAATHwAATTkAAEw5AAATHwAATTkAABMfAAARHwAACjkAAE05AAARHwAACjkAABEfAAAQHwAACTkAAEk5AABNOQAACTkAAE05AAAKOQAACDkAAEY5AABJOQAACDkAAEk5AAAJOQAAVTkAAFY5AABXOQAAVTkAAFc5AABYOQAAVjkAAFk5AABaOQAAVjkAAFo5AABXOQAAWDkAAFc5AABbOQAAWDkAAFs5AABcOQAAVzkAAFo5AABdOQAAVzkAAF05AABbOQAAGi8AAF45AABVOQAAGi8AAFU5AABfOQAAXjkAAGA5AABWOQAAXjkAAFY5AABVOQAAYDkAABYvAABZOQAAYDkAAFk5AABWOQAAFi8AAGQuAADCOAAAFi8AAMI4AABZOQAAWTkAAMI4AADGOAAAWTkAAMY4AABaOQAAWjkAAMY4AADFOAAAWjkAAMU4AABdOQAAXTkAAMU4AADcHgAAXTkAANweAADbHgAAWzkAAF05AADbHgAAWzkAANseAADaHgAAXDkAAFs5AADaHgAAXDkAANoeAADZHgAAYTkAAFw5AADZHgAAYTkAANkeAAD6HQAAYjkAAFg5AABcOQAAYjkAAFw5AABhOQAAXzkAAFU5AABYOQAAXzkAAFg5AABiOQAAYzkAAGQ5AABlOQAAYzkAAGU5AABmOQAAZDkAAGc5AABoOQAAZDkAAGg5AABlOQAAZjkAAGU5AABpOQAAZjkAAGk5AABqOQAAZTkAAGg5AABrOQAAZTkAAGs5AABpOQAA9C4AAGw5AABjOQAA9C4AAGM5AABDOQAAbDkAAG05AABkOQAAbDkAAGQ5AABjOQAAbTkAACovAABnOQAAbTkAAGc5AABkOQAAKi8AACkvAABuOQAAKi8AAG45AABnOQAAZzkAAG45AABvOQAAZzkAAG85AABoOQAAaDkAAG85AABwOQAAaDkAAHA5AABrOQAAazkAAHA5AAAeHgAAazkAAB4eAADMHgAAaTkAAGs5AADMHgAAaTkAAMweAADLHgAAajkAAGk5AADLHgAAajkAAMseAADJHgAARTkAAGo5AADJHgAARTkAAMkeAADIHgAARDkAAGY5AABqOQAARDkAAGo5AABFOQAAQzkAAGM5AABmOQAAQzkAAGY5AABEOQAAcTkAAHI5AABzOQAAcTkAAHM5AAB0OQAAcjkAAHU5AAB2OQAAcjkAAHY5AABzOQAAdDkAAHM5AAB3OQAAdDkAAHc5AAB4OQAAczkAAHY5AAB5OQAAczkAAHk5AAB3OQAAejkAAHs5AABxOQAAejkAAHE5AAB8OQAAezkAADovAAByOQAAezkAAHI5AABxOQAAOi8AADkvAAB1OQAAOi8AAHU5AAByOQAAOS8AAPY4AAD4OAAAOS8AAPg4AAB1OQAAdTkAAPg4AAD7OAAAdTkAAPs4AAB2OQAAdjkAAPs4AAD6OAAAdjkAAPo4AAB5OQAAeTkAAPo4AAC4HgAAeTkAALgeAAC3HgAAdzkAAHk5AAC3HgAAdzkAALceAAC2HgAAeDkAAHc5AAC2HgAAeDkAALYeAAC1HgAAfTkAAHg5AAC1HgAAfTkAALUeAADUHQAAfjkAAHQ5AAB4OQAAfjkAAHg5AAB9OQAAfDkAAHE5AAB0OQAAfDkAAHQ5AAB+OQAAfzkAAIA5AACBOQAAfzkAAIE5AACCOQAAgDkAAIM5AACEOQAAgDkAAIQ5AACBOQAAgjkAAIE5AACFOQAAgjkAAIU5AACGOQAAgTkAAIQ5AACHOQAAgTkAAIc5AACFOQAAUTkAAEwvAAB/OQAAUTkAAH85AABSOQAATC8AAIg5AACAOQAATC8AAIA5AAB/OQAAiDkAAIk5AACDOQAAiDkAAIM5AACAOQAAiTkAALM4AAC1OAAAiTkAALU4AACDOQAAgzkAALU4AAC3OAAAgzkAALc4AACEOQAAhDkAALc4AAC2OAAAhDkAALY4AACHOQAAhzkAALY4AACjHgAAhzkAAKMeAACiHgAAhTkAAIc5AACiHgAAhTkAAKIeAAChHgAAhjkAAIU5AAChHgAAhjkAAKEeAACfHgAAVDkAAIY5AACfHgAAVDkAAJ8eAACeHgAAUzkAAII5AACGOQAAUzkAAIY5AABUOQAAUjkAAH85AACCOQAAUjkAAII5AABTOQAAijkAAIs5AACMOQAAijkAAIw5AACNOQAAizkAAI45AACPOQAAizkAAI85AACMOQAAjTkAAIw5AACQOQAAjTkAAJA5AACROQAAjDkAAI85AACSOQAAjDkAAJI5AACQOQAAFTkAAJM5AACKOQAAFTkAAIo5AAAWOQAAkzkAAJQ5AACLOQAAkzkAAIs5AACKOQAAlDkAAJU5AACOOQAAlDkAAI45AACLOQAAlTkAAJY5AACXOQAAlTkAAJc5AACOOQAAjjkAAJc5AACYOQAAjjkAAJg5AACPOQAAjzkAAJg5AACZOQAAjzkAAJk5AACSOQAAkjkAAJk5AACsHQAAkjkAAKwdAACRHgAAkDkAAJI5AACRHgAAkDkAAJEeAACQHgAAkTkAAJA5AACQHgAAkTkAAJAeAACOHgAAGDkAAJE5AACOHgAAGDkAAI4eAACNHgAAFzkAAI05AACROQAAFzkAAJE5AAAYOQAAFjkAAIo5AACNOQAAFjkAAI05AAAXOQAAmjkAAJs5AACcOQAAmjkAAJw5AACdOQAAmzkAAJ45AACfOQAAmzkAAJ85AACcOQAAnTkAAJw5AACgOQAAnTkAAKA5AAChOQAAnDkAAJ85AACiOQAAnDkAAKI5AACgOQAANDkAAG4vAACaOQAANDkAAJo5AAA1OQAAbi8AAG0vAACbOQAAbi8AAJs5AACaOQAAbS8AAGwvAACeOQAAbS8AAJ45AACbOQAAbC8AAKM5AACkOQAAbC8AAKQ5AACeOQAAnjkAAKQ5AAClOQAAnjkAAKU5AACfOQAAnzkAAKU5AACmOQAAnzkAAKY5AACiOQAAojkAAKY5AACGHQAAojkAAIYdAABsHgAAoDkAAKI5AABsHgAAoDkAAGweAABrHgAAoTkAAKA5AABrHgAAoTkAAGseAABpHgAANzkAAKE5AABpHgAANzkAAGkeAABoHgAANjkAAJ05AAChOQAANjkAAKE5AAA3OQAANTkAAJo5AACdOQAANTkAAJ05AAA2OQAApzkAAKg5AACpOQAApzkAAKk5AACqOQAAqDkAAKs5AACsOQAAqDkAAKw5AACpOQAAqjkAAKk5AACtOQAAqjkAAK05AACuOQAAqTkAAKw5AACvOQAAqTkAAK85AACtOQAAQC4AAIEvAACnOQAAQC4AAKc5AACnOAAAgS8AALA5AACoOQAAgS8AAKg5AACnOQAAsDkAALE5AACrOQAAsDkAAKs5AACoOQAAsTkAAH4vAACyOQAAsTkAALI5AACrOQAAqzkAALI5AACzOQAAqzkAALM5AACsOQAArDkAALM5AAC0OQAArDkAALQ5AACvOQAArzkAALQ5AABhGwAArzkAAGEbAABaHgAArTkAAK85AABaHgAArTkAAFoeAABZHgAArjkAAK05AABZHgAArjkAAFkeAABXHgAAqTgAAK45AABXHgAAqTgAAFceAABWHgAAqDgAAKo5AACuOQAAqDgAAK45AACpOAAApzgAAKc5AACqOQAApzgAAKo5AACoOAAAtTkAALY5AAC3OQAAtTkAALc5AAC4OQAAtjkAALk5AAC6OQAAtjkAALo5AAC3OQAAuDkAALc5AAC7OQAAuDkAALs5AAC8OQAAtzkAALo5AAC9OQAAtzkAAL05AAC7OQAAKS8AAL45AAC1OQAAKS8AALU5AABuOQAAvjkAAL85AAC2OQAAvjkAALY5AAC1OQAAvzkAAJIvAAC5OQAAvzkAALk5AAC2OQAAki8AAMA5AADBOQAAki8AAME5AAC5OQAAuTkAAME5AADCOQAAuTkAAMI5AAC6OQAAujkAAMI5AADDOQAAujkAAMM5AAC9OQAAvTkAAMM5AADkHQAAvTkAAOQdAAAiHgAAuzkAAL05AAAiHgAAuzkAACIeAAAhHgAAvDkAALs5AAAhHgAAvDkAACEeAAAfHgAAcDkAALw5AAAfHgAAcDkAAB8eAAAeHgAAbzkAALg5AAC8OQAAbzkAALw5AABwOQAAbjkAALU5AAC4OQAAbjkAALg5AABvOQAAxDkAAMU5AADGOQAAxDkAAMY5AADHOQAAxTkAAMg5AADJOQAAxTkAAMk5AADGOQAAxzkAAMY5AADKOQAAxzkAAMo5AADLOQAAxjkAAMk5AADMOQAAxjkAAMw5AADKOQAApS8AAKMvAADEOQAApS8AAMQ5AADNOQAAoy8AAKIvAADFOQAAoy8AAMU5AADEOQAAoi8AAM45AADIOQAAoi8AAMg5AADFOQAAzjkAABovAABfOQAAzjkAAF85AADIOQAAyDkAAF85AABiOQAAyDkAAGI5AADJOQAAyTkAAGI5AABhOQAAyTkAAGE5AADMOQAAzDkAAGE5AAD6HQAAzDkAAPodAAD5HQAAyjkAAMw5AAD5HQAAyjkAAPkdAAD4HQAAyzkAAMo5AAD4HQAAyzkAAPgdAAD3HQAAzzkAAMs5AAD3HQAAzzkAAPcdAAAsHQAA0DkAAMc5AADLOQAA0DkAAMs5AADPOQAAzTkAAMQ5AADHOQAAzTkAAMc5AADQOQAA0TkAANI5AADTOQAA0TkAANM5AADUOQAA0jkAANU5AADWOQAA0jkAANY5AADTOQAA1DkAANM5AADXOQAA1DkAANc5AADYOQAA0zkAANY5AADZOQAA0zkAANk5AADXOQAAwDkAANo5AADROQAAwDkAANE5AADBOQAA2jkAALYvAADSOQAA2jkAANI5AADROQAAti8AANs5AADVOQAAti8AANU5AADSOQAA2zkAANw5AADdOQAA2zkAAN05AADVOQAA1TkAAN05AADeOQAA1TkAAN45AADWOQAA1jkAAN45AADfOQAA1jkAAN85AADZOQAA2TkAAN85AAA7HQAA2TkAADsdAADoHQAA1zkAANk5AADoHQAA1zkAAOgdAADnHQAA2DkAANc5AADnHQAA2DkAAOcdAADlHQAAwzkAANg5AADlHQAAwzkAAOUdAADkHQAAwjkAANQ5AADYOQAAwjkAANg5AADDOQAAwTkAANE5AADUOQAAwTkAANQ5AADCOQAA4DkAAOE5AADiOQAA4DkAAOI5AADjOQAA4TkAAOQ5AADlOQAA4TkAAOU5AADiOQAA4zkAAOI5AADmOQAA4zkAAOY5AADnOQAA4jkAAOU5AADoOQAA4jkAAOg5AADmOQAA6TkAAOo5AADgOQAA6TkAAOA5AADrOQAA6jkAAOw5AADhOQAA6jkAAOE5AADgOQAA7DkAAO05AADkOQAA7DkAAOQ5AADhOQAA7TkAAHo5AAB8OQAA7TkAAHw5AADkOQAA5DkAAHw5AAB+OQAA5DkAAH45AADlOQAA5TkAAH45AAB9OQAA5TkAAH05AADoOQAA6DkAAH05AADUHQAA6DkAANQdAADTHQAA5jkAAOg5AADTHQAA5jkAANMdAADSHQAA5zkAAOY5AADSHQAA5zkAANIdAADRHQAA7jkAAOc5AADRHQAA7jkAANEdAAD3HAAA7zkAAOM5AADnOQAA7zkAAOc5AADuOQAA6zkAAOA5AADjOQAA6zkAAOM5AADvOQAA8DkAAPE5AADyOQAA8DkAAPI5AADzOQAA8TkAAPQ5AAD1OQAA8TkAAPU5AADyOQAA8zkAAPI5AAD2OQAA8zkAAPY5AAD3OQAA8jkAAPU5AAD4OQAA8jkAAPg5AAD2OQAA+TkAAPo5AADwOQAA+TkAAPA5AAD7OQAA+jkAAPw5AADxOQAA+jkAAPE5AADwOQAA/DkAAP05AAD0OQAA/DkAAPQ5AADxOQAA/TkAACM4AAAlOAAA/TkAACU4AAD0OQAA9DkAACU4AAApOAAA9DkAACk4AAD1OQAA9TkAACk4AAAoOAAA9TkAACg4AAD4OQAA+DkAACg4AADBHQAA+DkAAMEdAADAHQAA9jkAAPg5AADAHQAA9jkAAMAdAAC/HQAA9zkAAPY5AAC/HQAA9zkAAL8dAAC+HQAA/jkAAPc5AAC+HQAA/jkAAL4dAACKGwAA/zkAAPM5AAD3OQAA/zkAAPc5AAD+OQAA+zkAAPA5AADzOQAA+zkAAPM5AAD/OQAAADoAAAE6AAACOgAAADoAAAI6AAADOgAAAToAAAQ6AAAFOgAAAToAAAU6AAACOgAAAzoAAAI6AAAGOgAAAzoAAAY6AAAHOgAAAjoAAAU6AAAIOgAAAjoAAAg6AAAGOgAAljkAAAk6AAAAOgAAljkAAAA6AACXOQAACToAAAo6AAABOgAACToAAAE6AAAAOgAACjoAAOovAAAEOgAACjoAAAQ6AAABOgAA6i8AAAs6AAAMOgAA6i8AAAw6AAAEOgAABDoAAAw6AAANOgAABDoAAA06AAAFOgAABToAAA06AAAOOgAABToAAA46AAAIOgAACDoAAA46AADNHAAACDoAAM0cAACwHQAABjoAAAg6AACwHQAABjoAALAdAACvHQAABzoAAAY6AACvHQAABzoAAK8dAACtHQAAmTkAAAc6AACtHQAAmTkAAK0dAACsHQAAmDkAAAM6AAAHOgAAmDkAAAc6AACZOQAAlzkAAAA6AAADOgAAlzkAAAM6AACYOQAADzoAABA6AAAROgAADzoAABE6AAASOgAAEDoAABM6AAAUOgAAEDoAABQ6AAAROgAAEjoAABE6AAAVOgAAEjoAABU6AAAWOgAAEToAABQ6AAAXOgAAEToAABc6AAAVOgAAozkAAPwvAAAPOgAAozkAAA86AACkOQAA/C8AABg6AAAQOgAA/C8AABA6AAAPOgAAGDoAAPovAAATOgAAGDoAABM6AAAQOgAA+i8AAPkvAAAZOgAA+i8AABk6AAATOgAAEzoAABk6AAAaOgAAEzoAABo6AAAUOgAAFDoAABo6AAAbOgAAFDoAABs6AAAXOgAAFzoAABs6AACXHAAAFzoAAJccAACKHQAAFToAABc6AACKHQAAFToAAIodAACJHQAAFjoAABU6AACJHQAAFjoAAIkdAACHHQAApjkAABY6AACHHQAApjkAAIcdAACGHQAApTkAABI6AAAWOgAApTkAABY6AACmOQAApDkAAA86AAASOgAApDkAABI6AAClOQAAHDoAAB06AAAeOgAAHDoAAB46AAAfOgAAHToAACA6AAAhOgAAHToAACE6AAAeOgAAHzoAAB46AAAiOgAAHzoAACI6AAAjOgAAHjoAACE6AAAkOgAAHjoAACQ6AAAiOgAAJToAACY6AAAcOgAAJToAABw6AAAnOgAAJjoAACg6AAAdOgAAJjoAAB06AAAcOgAAKDoAAAgwAAAgOgAAKDoAACA6AAAdOgAACDAAAKU3AACnNwAACDAAAKc3AAAgOgAAIDoAAKc3AACqNwAAIDoAAKo3AAAhOgAAIToAAKo3AACpNwAAIToAAKk3AAAkOgAAJDoAAKk3AABjHQAAJDoAAGMdAABiHQAAIjoAACQ6AABiHQAAIjoAAGIdAABhHQAAIzoAACI6AABhHQAAIzoAAGEdAABgHQAAKToAACM6AABgHQAAKToAAGAdAADoGQAAKjoAAB86AAAjOgAAKjoAACM6AAApOgAAJzoAABw6AAAfOgAAJzoAAB86AAAqOgAAKzoAACw6AAAtOgAAKzoAAC06AAAuOgAALDoAAC86AAAwOgAALDoAADA6AAAtOgAALjoAAC06AAAxOgAALjoAADE6AAAyOgAALToAADA6AAAzOgAALToAADM6AAAxOgAA3DkAADQ6AAArOgAA3DkAACs6AADdOQAANDoAADU6AAAsOgAANDoAACw6AAArOgAANToAADY6AAAvOgAANToAAC86AAAsOgAANjoAADc6AAA4OgAANjoAADg6AAAvOgAALzoAADg6AAA5OgAALzoAADk6AAAwOgAAMDoAADk6AAA6OgAAMDoAADo6AAAzOgAAMzoAADo6AAAGHQAAMzoAAAYdAAA/HQAAMToAADM6AAA/HQAAMToAAD8dAAA+HQAAMjoAADE6AAA+HQAAMjoAAD4dAAA8HQAA3zkAADI6AAA8HQAA3zkAADwdAAA7HQAA3jkAAC46AAAyOgAA3jkAADI6AADfOQAA3TkAACs6AAAuOgAA3TkAAC46AADeOQAAOzoAADw6AAA9OgAAOzoAAD06AAA+OgAAPDoAAD86AABAOgAAPDoAAEA6AAA9OgAAPjoAAD06AABBOgAAPjoAAEE6AABCOgAAPToAAEA6AABDOgAAPToAAEM6AABBOgAARDoAAEU6AAA7OgAARDoAADs6AABGOgAARToAACwwAAA8OgAARToAADw6AAA7OgAALDAAAEc6AAA/OgAALDAAAD86AAA8OgAARzoAAKUvAADNOQAARzoAAM05AAA/OgAAPzoAAM05AADQOQAAPzoAANA5AABAOgAAQDoAANA5AADPOQAAQDoAAM85AABDOgAAQzoAAM85AAAsHQAAQzoAACwdAAArHQAAQToAAEM6AAArHQAAQToAACsdAAAqHQAAQjoAAEE6AAAqHQAAQjoAACodAAApHQAASDoAAEI6AAApHQAASDoAACkdAABLHAAASToAAD46AABCOgAASToAAEI6AABIOgAARjoAADs6AAA+OgAARjoAAD46AABJOgAASjoAAEs6AABMOgAASjoAAEw6AABNOgAASzoAAE46AABPOgAASzoAAE86AABMOgAATToAAEw6AABQOgAATToAAFA6AABROgAATDoAAE86AABSOgAATDoAAFI6AABQOgAANzoAAFM6AABKOgAANzoAAEo6AAA4OgAAUzoAAFQ6AABLOgAAUzoAAEs6AABKOgAAVDoAAFU6AABOOgAAVDoAAE46AABLOgAAVToAAFY6AABXOgAAVToAAFc6AABOOgAATjoAAFc6AABYOgAATjoAAFg6AABPOgAATzoAAFg6AABZOgAA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mjAAAJM6AACcOgAAmDAAAJ06AACUOgAAmDAAAJQ6AACTOgAAnToAAJ46AACXOgAAnToAAJc6AACUOgAAnjoAAEQ6AABGOgAAnjoAAEY6AACXOgAAlzoAAEY6AABJOgAAlzoAAEk6AACYOgAAmDoAAEk6AABIOgAAmDoAAEg6AACbOgAAmzoAAEg6AABLHAAAmzoAAEscAABKHAAAmToAAJs6AABKHAAAmToAAEocAABJHAAAmjoAAJk6AABJHAAAmjoAAEkcAABIHAAAnzoAAJo6AABIHAAAnzoAAEgcAABRGwAAoDoAAJY6AACaOgAAoDoAAJo6AACfOgAAnDoAAJM6AACWOgAAnDoAAJY6AACgOgAAoToAAKI6AACjOgAAoToAAKM6AACkOgAAojoAAKU6AACmOgAAojoAAKY6AACjOgAApDoAAKM6AACnOgAApDoAAKc6AACoOgAAozoAAKY6AACpOgAAozoAAKk6AACnOgAAiDAAAKo6AAChOgAAiDAAAKE6AACQOgAAqjoAAKs6AACiOgAAqjoAAKI6AAChOgAAqzoAAKswAAClOgAAqzoAAKU6AACiOgAAqzAAAKowAACsOgAAqzAAAKw6AAClOgAApToAAKw6AACtOgAApToAAK06AACmOgAApjoAAK06AACuOgAApjoAAK46AACpOgAAqToAAK46AACbGwAAqToAAJsbAAAOHAAApzoAAKk6AAAOHAAApzoAAA4cAAANHAAAqDoAAKc6AAANHAAAqDoAAA0cAAALHAAAkjoAAKg6AAALHAAAkjoAAAscAAAKHAAAkToAAKQ6AACoOgAAkToAAKg6AACSOgAAkDoAAKE6AACkOgAAkDoAAKQ6AACROgAArzoAALA6AACxOgAArzoAALE6AACyOgAAsDoAALM6AAC0OgAAsDoAALQ6AACxOgAAsjoAALE6AAC1OgAAsjoAALU6AAC2OgAAsToAALQ6AAC3OgAAsToAALc6AAC1OgAAuDoAAL0wAACvOgAAuDoAAK86AAC5OgAAvTAAALwwAACwOgAAvTAAALA6AACvOgAAvDAAALo6AACzOgAAvDAAALM6AACwOgAAujoAAGM6AABkOgAAujoAAGQ6AACzOgAAszoAAGQ6AABnOgAAszoAAGc6AAC0OgAAtDoAAGc6AABmOgAAtDoAAGY6AAC3OgAAtzoAAGY6AAD7GwAAtzoAAPsbAAD6GwAAtToAALc6AAD6GwAAtToAAPobAAD5GwAAtjoAALU6AAD5GwAAtjoAAPkbAAD4GwAAuzoAALY6AAD4GwAAuzoAAPgbAAAqGwAAvDoAALI6AAC2OgAAvDoAALY6AAC7OgAAuToAAK86AACyOgAAuToAALI6AAC8OgAAvToAAL46AAC/OgAAvToAAL86AADAOgAAvjoAAME6AADCOgAAvjoAAMI6AAC/OgAAwDoAAL86AADDOgAAwDoAAMM6AADEOgAAvzoAAMI6AADFOgAAvzoAAMU6AADDOgAAYzAAAMY6AAC9OgAAYzAAAL06AABzOgAAxjoAAMc6AAC+OgAAxjoAAL46AAC9OgAAxzoAAMg6AADBOgAAxzoAAME6AAC+OgAAyDoAAMk6AADKOgAAyDoAAMo6AADBOgAAwToAAMo6AADLOgAAwToAAMs6AADCOgAAwjoAAMs6AADMOgAAwjoAAMw6AADFOgAAxToAAMw6AAATGwAAxToAABMbAADYGwAAwzoAAMU6AADYGwAAwzoAANgbAADXGwAAxDoAAMM6AADXGwAAxDoAANcbAADVGwAAdToAAMQ6AADVGwAAdToAANUbAADUGwAAdDoAAMA6AADEOgAAdDoAAMQ6AAB1OgAAczoAAL06AADAOgAAczoAAMA6AAB0OgAAzToAAM46AADPOgAAzToAAM86AADQOgAAzjoAANE6AADSOgAAzjoAANI6AADPOgAA0DoAAM86AADTOgAA0DoAANM6AADUOgAAzzoAANI6AADVOgAAzzoAANU6AADTOgAAgDoAANY6AADNOgAAgDoAAM06AACBOgAA1joAAOMwAADOOgAA1joAAM46AADNOgAA4zAAAOIwAADROgAA4zAAANE6AADOOgAA4jAAAOEwAADXOgAA4jAAANc6AADROgAA0ToAANc6AADYOgAA0ToAANg6AADSOgAA0joAANg6AADZOgAA0joAANk6AADVOgAA1ToAANk6AADvGgAA1ToAAO8aAACyGwAA0zoAANU6AACyGwAA0zoAALIbAACxGwAA1DoAANM6AACxGwAA1DoAALEbAACvGwAAgzoAANQ6AACvGwAAgzoAAK8bAACuGwAAgjoAANA6AADUOgAAgjoAANQ6AACDOgAAgToAAM06AADQOgAAgToAANA6AACCOgAA2joAANs6AADcOgAA2joAANw6AADdOgAA2zoAAN46AADfOgAA2zoAAN86AADcOgAA3ToAANw6AADgOgAA3ToAAOA6AADhOgAA3DoAAN86AADiOgAA3DoAAOI6AADgOgAAqjAAAPcwAADaOgAAqjAAANo6AACsOgAA9zAAAOM6AADbOgAA9zAAANs6AADaOgAA4zoAAOQ6AADeOgAA4zoAAN46AADbOgAA5DoAAOU6AADmOgAA5DoAAOY6AADeOgAA3joAAOY6AADnOgAA3joAAOc6AADfOgAA3zoAAOc6AADoOgAA3zoAAOg6AADiOgAA4joAAOg6AAA6GwAA4joAADobAACfGwAA4DoAAOI6AACfGwAA4DoAAJ8bAACeGwAA4ToAAOA6AACeGwAA4ToAAJ4bAACcGwAArjoAAOE6AACcGwAArjoAAJwbAACbGwAArToAAN06AADhOgAArToAAOE6AACuOgAArDoAANo6AADdOgAArDoAAN06AACtOgAA6ToAAOo6AADrOgAA6ToAAOs6AADsOgAA6joAAO06AADuOgAA6joAAO46AADrOgAA7DoAAOs6AADvOgAA7DoAAO86AADwOgAA6zoAAO46AADxOgAA6zoAAPE6AADvOgAACDEAAPI6AADpOgAACDEAAOk6AADzOgAA8joAAPQ6AADqOgAA8joAAOo6AADpOgAA9DoAAPU6AADtOgAA9DoAAO06AADqOgAA9ToAAPk5AAD7OQAA9ToAAPs5AADtOgAA7ToAAPs5AAD/OQAA7ToAAP85AADuOgAA7joAAP85AAD+OQAA7joAAP45AADxOgAA8ToAAP45AACKGwAA8ToAAIobAACJGwAA7zoAAPE6AACJGwAA7zoAAIkbAACIGwAA8DoAAO86AACIGwAA8DoAAIgbAACHGwAA9joAAPA6AACHGwAA9joAAIcbAADxFwAA9zoAAOw6AADwOgAA9zoAAPA6AAD2OgAA8zoAAOk6AADsOgAA8zoAAOw6AAD3OgAA+DoAAPk6AAD6OgAA+DoAAPo6AAD7OgAA+ToAAPw6AAD9OgAA+ToAAP06AAD6OgAA+zoAAPo6AAD+OgAA+zoAAP46AAD/OgAA+joAAP06AAAAOwAA+joAAAA7AAD+OgAAGC4AAAE7AAD4OgAAGC4AAPg6AACLOAAAATsAAAI7AAD5OgAAATsAAPk6AAD4OgAAAjsAAAM7AAD8OgAAAjsAAPw6AAD5OgAAAzsAAAQ7AAAFOwAAAzsAAAU7AAD8OgAA/DoAAAU7AAAGOwAA/DoAAAY7AAD9OgAA/ToAAAY7AAAHOwAA/ToAAAc7AAAAOwAAADsAAAc7AADYGAAAADsAANgYAAB4GwAA/joAAAA7AAB4GwAA/joAAHgbAAB3GwAA/zoAAP46AAB3GwAA/zoAAHcbAAB1GwAAjTgAAP86AAB1GwAAjTgAAHUbAAB0GwAAjDgAAPs6AAD/OgAAjDgAAP86AACNOAAAizgAAPg6AAD7OgAAizgAAPs6AACMOAAACDsAAAk7AAAKOwAACDsAAAo7AAALOwAACTsAAAw7AAANOwAACTsAAA07AAAKOwAACzsAAAo7AAAOOwAACzsAAA47AAAPOwAACjsAAA07AAAQOwAACjsAABA7AAAOOwAAfi8AABE7AAAIOwAAfi8AAAg7AACyOQAAETsAACkxAAAJOwAAETsAAAk7AAAIOwAAKTEAABI7AAAMOwAAKTEAAAw7AAAJOwAAEjsAABM7AAAUOwAAEjsAABQ7AAAMOwAADDsAABQ7AAAVOwAADDsAABU7AAANOwAADTsAABU7AAAWOwAADTsAABY7AAAQOwAAEDsAABY7AACnFwAAEDsAAKcXAABlGwAADjsAABA7AABlGwAADjsAAGUbAABkGwAADzsAAA47AABkGwAADzsAAGQbAABiGwAAtDkAAA87AABiGwAAtDkAAGIbAABhGwAAszkAAAs7AAAPOwAAszkAAA87AAC0OQAAsjkAAAg7AAALOwAAsjkAAAs7AACzOQAAFzsAABg7AAAZOwAAFzsAABk7AAAaOwAAGDsAABs7AAAcOwAAGDsAABw7AAAZOwAAGjsAABk7AAAdOwAAGjsAAB07AAAeOwAAGTsAABw7AAAfOwAAGTsAAB87AAAdOwAAOzEAACA7AAAXOwAAOzEAABc7AAAhOwAAIDsAADgxAAAYOwAAIDsAABg7AAAXOwAAODEAACI7AAAbOwAAODEAABs7AAAYOwAAIjsAAJowAACcOgAAIjsAAJw6AAAbOwAAGzsAAJw6AACgOgAAGzsAAKA6AAAcOwAAHDsAAKA6AACfOgAAHDsAAJ86AAAfOwAAHzsAAJ86AABRGwAAHzsAAFEbAABQGwAAHTsAAB87AABQGwAAHTsAAFAbAABPGwAAHjsAAB07AABPGwAAHjsAAE8bAABOGwAAIzsAAB47AABOGwAAIzsAAE4bAACAGgAAJDsAABo7AAAeOwAAJDsAAB47AAAjOwAAITsAABc7AAAaOwAAITsAABo7AAAkOwAAJTsAACY7AAAnOwAAJTsAACc7AAAoOwAAJjsAACk7AAAqOwAAJjsAACo7AAAnOwAAKDsAACc7AAArOwAAKDsAACs7AAAsOwAAJzsAACo7AAAtOwAAJzsAAC07AAArOwAA5ToAAE4xAAAlOwAA5ToAACU7AADmOgAATjEAAC47AAAmOwAATjEAACY7AAAlOwAALjsAAC87AAApOwAALjsAACk7AAAmOwAALzsAADA7AAAxOwAALzsAADE7AAApOwAAKTsAADE7AAAyOwAAKTsAADI7AAAqOwAAKjsAADI7AAAzOwAAKjsAADM7AAAtOwAALTsAADM7AABrGgAALTsAAGsaAAA+GwAAKzsAAC07AAA+GwAAKzsAAD4bAAA9GwAALDsAACs7AAA9GwAALDsAAD0bAAA7GwAA6DoAACw7AAA7GwAA6DoAADsbAAA6GwAA5zoAACg7AAAsOwAA5zoAACw7AADoOgAA5joAACU7AAAoOwAA5joAACg7AADnOgAANDsAADU7AAA2OwAANDsAADY7AAA3OwAANTsAADg7AAA5OwAANTsAADk7AAA2OwAANzsAADY7AAA6OwAANzsAADo7AAA7OwAANjsAADk7AAA8OwAANjsAADw7AAA6OwAAYDEAAF4xAAA0OwAAYDEAADQ7AAA9OwAAXjEAAD47AAA1OwAAXjEAADU7AAA0OwAAPjsAAFwxAAA4OwAAPjsAADg7AAA1OwAAXDEAALg6AAC5OgAAXDEAALk6AAA4OwAAODsAALk6AAC8OgAAODsAALw6AAA5OwAAOTsAALw6AAC7OgAAOTsAALs6AAA8OwAAPDsAALs6AAAqGwAAPDsAACobAAApGwAAOjsAADw7AAApGwAAOjsAACkbAAAoGwAAOzsAADo7AAAoGwAAOzsAACgbAAAnGwAAPzsAADs7AAAnGwAAPzsAACcbAABcGgAAQDsAADc7AAA7OwAAQDsAADs7AAA/OwAAPTsAADQ7AAA3OwAAPTsAADc7AABAOwAAQTsAAEI7AABDOwAAQTsAAEM7AABEOwAAQjsAAEU7AABGOwAAQjsAAEY7AABDOwAARDsAAEM7AABHOwAARDsAAEc7AABIOwAAQzsAAEY7AABJOwAAQzsAAEk7AABHOwAAyToAAHIxAABBOwAAyToAAEE7AADKOgAAcjEAAEo7AABCOwAAcjEAAEI7AABBOwAASjsAAHAxAABFOwAASjsAAEU7AABCOwAAcDEAAEs7AABMOwAAcDEAAEw7AABFOwAARTsAAEw7AABNOwAARTsAAE07AABGOwAARjsAAE07AABOOwAARjsAAE47AABJOwAASTsAAE47AAAzGgAASTsAADMaAAAXGwAARzsAAEk7AAAXGwAARzsAABcbAAAWGwAASDsAAEc7AAAWGwAASDsAABYbAAAUGwAAzDoAAEg7AAAUGwAAzDoAABQbAAATGwAAyzoAAEQ7AABIOwAAyzoAAEg7AADMOgAAyjoAAEE7AABEOwAAyjoAAEQ7AADLOgAATzsAAFA7AABROwAATzsAAFE7AABSOwAAUDsAAFM7AABUOwAAUDsAAFQ7AABROwAAUjsAAFE7AABVOwAAUjsAAFU7AABWOwAAUTsAAFQ7AABXOwAAUTsAAFc7AABVOwAAWDsAAFk7AABPOwAAWDsAAE87AABaOwAAWTsAAIAxAABQOwAAWTsAAFA7AABPOwAAgDEAAH8xAABTOwAAgDEAAFM7AABQOwAAfzEAADAuAACXOAAAfzEAAJc4AABTOwAAUzsAAJc4AACcOAAAUzsAAJw4AABUOwAAVDsAAJw4AACbOAAAVDsAAJs4AABXOwAAVzsAAJs4AAAEGwAAVzsAAAQbAAADGwAAVTsAAFc7AAADGwAAVTsAAAMbAAACGwAAVjsAAFU7AAACGwAAVjsAAAIbAAABGwAAWzsAAFY7AAABGwAAWzsAAAEbAAAjGgAAXDsAAFI7AABWOwAAXDsAAFY7AABbOwAAWjsAAE87AABSOwAAWjsAAFI7AABcOwAAXTsAAF47AABfOwAAXTsAAF87AABgOwAAXjsAAGE7AABiOwAAXjsAAGI7AABfOwAAYDsAAF87AABjOwAAYDsAAGM7AABkOwAAXzsAAGI7AABlOwAAXzsAAGU7AABjOwAA4TAAAJYxAABdOwAA4TAAAF07AADXOgAAljEAAJUxAABeOwAAljEAAF47AABdOwAAlTEAAGY7AABhOwAAlTEAAGE7AABeOwAAZjsAAJMxAABnOwAAZjsAAGc7AABhOwAAYTsAAGc7AABoOwAAYTsAAGg7AABiOwAAYjsAAGg7AABpOwAAYjsAAGk7AABlOwAAZTsAAGk7AAANGgAAZTsAAA0aAADzGgAAYzsAAGU7AADzGgAAYzsAAPMaAADyGgAAZDsAAGM7AADyGgAAZDsAAPIaAADwGgAA2ToAAGQ7AADwGgAA2ToAAPAaAADvGgAA2DoAAGA7AABkOwAA2DoAAGQ7AADZOgAA1zoAAF07AABgOwAA1zoAAGA7AADYOgAAajsAAGs7AABsOwAAajsAAGw7AABtOwAAazsAAG47AABvOwAAazsAAG87AABsOwAAbTsAAGw7AABwOwAAbTsAAHA7AABxOwAAbDsAAG87AAByOwAAbDsAAHI7AABwOwAA0zgAAHM7AABqOwAA0zgAAGo7AADUOAAAczsAAKYxAABrOwAAczsAAGs7AABqOwAApjEAAHQ7AABuOwAApjEAAG47AABrOwAAdDsAAKQxAAB1OwAAdDsAAHU7AABuOwAAbjsAAHU7AAB2OwAAbjsAAHY7AABvOwAAbzsAAHY7AAB3OwAAbzsAAHc7AAByOwAAcjsAAHc7AADSGQAAcjsAANIZAAC5GgAAcDsAAHI7AAC5GgAAcDsAALkaAAC4GgAAcTsAAHA7AAC4GgAAcTsAALgaAAC2GgAA1jgAAHE7AAC2GgAA1jgAALYaAAC1GgAA1TgAAG07AABxOwAA1TgAAHE7AADWOAAA1DgAAGo7AABtOwAA1DgAAG07AADVOAAAeDsAAHk7AAB6OwAAeDsAAHo7AAB7OwAAeTsAAHw7AAB9OwAAeTsAAH07AAB6OwAAezsAAHo7AAB+OwAAezsAAH47AAB/OwAAejsAAH07AACAOwAAejsAAIA7AAB+OwAAtjEAAIE7AAB4OwAAtjEAAHg7AACCOwAAgTsAALMxAAB5OwAAgTsAAHk7AAB4OwAAszEAALIxAAB8OwAAszEAAHw7AAB5OwAAsjEAACI5AAAkOQAAsjEAACQ5AAB8OwAAfDsAACQ5AAAnOQAAfDsAACc5AAB9OwAAfTsAACc5AAAmOQAAfTsAACY5AACAOwAAgDsAACY5AACUGgAAgDsAAJQaAACTGgAAfjsAAIA7AACTGgAAfjsAAJMaAACSGgAAfzsAAH47AACSGgAAfzsAAJIaAACRGgAAgzsAAH87AACRGgAAgzsAAJEaAADDGQAAhDsAAHs7AAB/OwAAhDsAAH87AACDOwAAgjsAAHg7AAB7OwAAgjsAAHs7AACEOwAAhTsAAIY7AACHOwAAhTsAAIc7AACIOwAAhjsAAIk7AACKOwAAhjsAAIo7AACHOwAAiDsAAIc7AACLOwAAiDsAAIs7AACMOwAAhzsAAIo7AACNOwAAhzsAAI07AACLOwAAyDEAAI47AACFOwAAyDEAAIU7AACPOwAAjjsAAJA7AACGOwAAjjsAAIY7AACFOwAAkDsAAJE7AACJOwAAkDsAAIk7AACGOwAAkTsAADsxAAAhOwAAkTsAACE7AACJOwAAiTsAACE7AAAkOwAAiTsAACQ7AACKOwAAijsAACQ7AAAjOwAAijsAACM7AACNOwAAjTsAACM7AACAGgAAjTsAAIAaAAB/GgAAizsAAI07AAB/GgAAizsAAH8aAAB+GgAAjDsAAIs7AAB+GgAAjDsAAH4aAAB9GgAAkjsAAIw7AAB9GgAAkjsAAH0aAACvGQAAkzsAAIg7AACMOwAAkzsAAIw7AACSOwAAjzsAAIU7AACIOwAAjzsAAIg7AACTOwAAlDsAAJU7AACWOwAAlDsAAJY7AACXOwAAlTsAAJg7AACZOwAAlTsAAJk7AACWOwAAlzsAAJY7AACaOwAAlzsAAJo7AACbOwAAljsAAJk7AACcOwAAljsAAJw7AACaOwAAMDsAAJ07AACUOwAAMDsAAJQ7AAAxOwAAnTsAANoxAACVOwAAnTsAAJU7AACUOwAA2jEAAJ47AACYOwAA2jEAAJg7AACVOwAAnjsAANgxAACfOwAAnjsAAJ87AACYOwAAmDsAAJ87AACgOwAAmDsAAKA7AACZOwAAmTsAAKA7AAChOwAAmTsAAKE7AACcOwAAnDsAAKE7AACHGQAAnDsAAIcZAABvGgAAmjsAAJw7AABvGgAAmjsAAG8aAABuGgAAmzsAAJo7AABuGgAAmzsAAG4aAABsGgAAMzsAAJs7AABsGgAAMzsAAGwaAABrGgAAMjsAAJc7AACbOwAAMjsAAJs7AAAzOwAAMTsAAJQ7AACXOwAAMTsAAJc7AAAyOwAAojsAAKM7AACkOwAAojsAAKQ7AAClOwAAozsAAKY7AACnOwAAozsAAKc7AACkOwAApTsAAKQ7AACoOwAApTsAAKg7AACpOwAApDsAAKc7AACqOwAApDsAAKo7AACoOwAAqzsAAOoxAACiOwAAqzsAAKI7AACsOwAA6jEAAOkxAACjOwAA6jEAAKM7AACiOwAA6TEAAOgxAACmOwAA6TEAAKY7AACjOwAA6DEAAGAxAAA9OwAA6DEAAD07AACmOwAApjsAAD07AABAOwAApjsAAEA7AACnOwAApzsAAEA7AAA/OwAApzsAAD87AACqOwAAqjsAAD87AABcGgAAqjsAAFwaAABbGgAAqDsAAKo7AABbGgAAqDsAAFsaAABaGgAAqTsAAKg7AABaGgAAqTsAAFoaAABZGgAArTsAAKk7AABZGgAArTsAAFkaAAB4GQAArjsAAKU7AACpOwAArjsAAKk7AACtOwAArDsAAKI7AAClOwAArDsAAKU7AACuOwAArzsAALA7AACxOwAArzsAALE7AACyOwAAsDsAALM7AAC0OwAAsDsAALQ7AACxOwAAsjsAALE7AAC1OwAAsjsAALU7AAC2OwAAsTsAALQ7AAC3OwAAsTsAALc7AAC1OwAASzsAALg7AACvOwAASzsAAK87AABMOwAAuDsAALk7AACwOwAAuDsAALA7AACvOwAAuTsAAPwxAACzOwAAuTsAALM7AACwOwAA/DEAALo7AAC7OwAA/DEAALs7AACzOwAAszsAALs7AAC8OwAAszsAALw7AAC0OwAAtDsAALw7AAC9OwAAtDsAAL07AAC3OwAAtzsAAL07AABRGQAAtzsAAFEZAAA3GgAAtTsAALc7AAA3GgAAtTsAADcaAAA2GgAAtjsAALU7AAA2GgAAtjsAADYaAAA0GgAATjsAALY7AAA0GgAATjsAADQaAAAzGgAATTsAALI7AAC2OwAATTsAALY7AABOOwAATDsAAK87AACyOwAATDsAALI7AABNOwAAvjsAAL87AADAOwAAvjsAAMA7AADBOwAAvzsAAMI7AADDOwAAvzsAAMM7AADAOwAAwTsAAMA7AADEOwAAwTsAAMQ7AADFOwAAwDsAAMM7AADGOwAAwDsAAMY7AADEOwAAxzsAAMg7AAC+OwAAxzsAAL47AADJOwAAyDsAAMo7AAC/OwAAyDsAAL87AAC+OwAAyjsAAMs7AADCOwAAyjsAAMI7AAC/OwAAyzsAAFg7AABaOwAAyzsAAFo7AADCOwAAwjsAAFo7AABcOwAAwjsAAFw7AADDOwAAwzsAAFw7AABbOwAAwzsAAFs7AADGOwAAxjsAAFs7AAAjGgAAxjsAACMaAAAiGgAAxDsAAMY7AAAiGgAAxDsAACIaAAAhGgAAxTsAAMQ7AAAhGgAAxTsAACEaAAAgGgAAzDsAAMU7AAAgGgAAzDsAACAaAAAtGQAAzTsAAME7AADFOwAAzTsAAMU7AADMOwAAyTsAAL47AADBOwAAyTsAAME7AADNOwAAzjsAAM87AADQOwAAzjsAANA7AADROwAAzzsAANI7AADTOwAAzzsAANM7AADQOwAA0TsAANA7AADUOwAA0TsAANQ7AADVOwAA0DsAANM7AADWOwAA0DsAANY7AADUOwAAkzEAACIyAADOOwAAkzEAAM47AABnOwAAIjIAANc7AADPOwAAIjIAAM87AADOOwAA1zsAACAyAADSOwAA1zsAANI7AADPOwAAIDIAANg7AADZOwAAIDIAANk7AADSOwAA0jsAANk7AADaOwAA0jsAANo7AADTOwAA0zsAANo7AADbOwAA0zsAANs7AADWOwAA1jsAANs7AAAXGQAA1jsAABcZAAARGgAA1DsAANY7AAARGgAA1DsAABEaAAAQGgAA1TsAANQ7AAAQGgAA1TsAABAaAAAOGgAAaTsAANU7AAAOGgAAaTsAAA4aAAANGgAAaDsAANE7AADVOwAAaDsAANU7AABpOwAAZzsAAM47AADROwAAZzsAANE7AABoOwAA3DsAAN07AADeOwAA3DsAAN47AADfOwAA3TsAAOA7AADhOwAA3TsAAOE7AADeOwAA3zsAAN47AADiOwAA3zsAAOI7AADjOwAA3jsAAOE7AADkOwAA3jsAAOQ7AADiOwAAOjcAAC8yAADcOwAAOjcAANw7AAA7NwAALzIAAOU7AADdOwAALzIAAN07AADcOwAA5TsAAC0yAADgOwAA5TsAAOA7AADdOwAALTIAACU6AAAnOgAALTIAACc6AADgOwAA4DsAACc6AAAqOgAA4DsAACo6AADhOwAA4TsAACo6AAApOgAA4TsAACk6AADkOwAA5DsAACk6AADoGQAA5DsAAOgZAADnGQAA4jsAAOQ7AADnGQAA4jsAAOcZAADmGQAA4zsAAOI7AADmGQAA4zsAAOYZAADkGQAAPTcAAOM7AADkGQAAPTcAAOQZAADjGQAAPDcAAN87AADjOwAAPDcAAOM7AAA9NwAAOzcAANw7AADfOwAAOzcAAN87AAA8NwAA5jsAAOc7AADoOwAA5jsAAOg7AADpOwAA5zsAAOo7AADrOwAA5zsAAOs7AADoOwAA6TsAAOg7AADsOwAA6TsAAOw7AADtOwAA6DsAAOs7AADuOwAA6DsAAO47AADsOwAApDEAAO87AADmOwAApDEAAOY7AAB1OwAA7zsAAEEyAADnOwAA7zsAAOc7AADmOwAAQTIAAEAyAADqOwAAQTIAAOo7AADnOwAAQDIAAPA7AADxOwAAQDIAAPE7AADqOwAA6jsAAPE7AADyOwAA6jsAAPI7AADrOwAA6zsAAPI7AADzOwAA6zsAAPM7AADuOwAA7jsAAPM7AADvGAAA7jsAAO8YAADWGQAA7DsAAO47AADWGQAA7DsAANYZAADVGQAA7TsAAOw7AADVGQAA7TsAANUZAADTGQAAdzsAAO07AADTGQAAdzsAANMZAADSGQAAdjsAAOk7AADtOwAAdjsAAO07AAB3OwAAdTsAAOY7AADpOwAAdTsAAOk7AAB2OwAA9DsAAPU7AAD2OwAA9DsAAPY7AAD3OwAA9TsAAPg7AAD5OwAA9TsAAPk7AAD2OwAA9zsAAPY7AAD6OwAA9zsAAPo7AAD7OwAA9jsAAPk7AAD8OwAA9jsAAPw7AAD6OwAAUjIAAFAyAAD0OwAAUjIAAPQ7AAD9OwAAUDIAAP47AAD1OwAAUDIAAPU7AAD0OwAA/jsAAP87AAD4OwAA/jsAAPg7AAD1OwAA/zsAALYxAACCOwAA/zsAAII7AAD4OwAA+DsAAII7AACEOwAA+DsAAIQ7AAD5OwAA+TsAAIQ7AACDOwAA+TsAAIM7AAD8OwAA/DsAAIM7AADDGQAA/DsAAMMZAADCGQAA+jsAAPw7AADCGQAA+jsAAMIZAADBGQAA+zsAAPo7AADBGQAA+zsAAMEZAADAGQAAADwAAPs7AADAGQAAADwAAMAZAADHGAAAATwAAPc7AAD7OwAAATwAAPs7AAAAPAAA/TsAAPQ7AAD3OwAA/TsAAPc7AAABPAAAAjwAAAM8AAAEPAAAAjwAAAQ8AAAFPAAAAzwAAAY8AAAHPAAAAzwAAAc8AAAEPAAABTwAAAQ8AAAIPAAABTwAAAg8AAAJPAAABDwAAAc8AAAKPAAABDwAAAo8AAAIPAAACzwAAAw8AAACPAAACzwAAAI8AAANPAAADDwAAA48AAADPAAADDwAAAM8AAACPAAADjwAAA88AAAGPAAADjwAAAY8AAADPAAADzwAAMgxAACPOwAADzwAAI87AAAGPAAABjwAAI87AACTOwAABjwAAJM7AAAHPAAABzwAAJM7AACSOwAABzwAAJI7AAAKPAAACjwAAJI7AACvGQAACjwAAK8ZAACuGQAACDwAAAo8AACuGQAACDwAAK4ZAACtGQAACTwAAAg8AACtGQAACTwAAK0ZAACsGQAAEDwAAAk8AACsGQAAEDwAAKwZAAC1GAAAETwAAAU8AAAJPAAAETwAAAk8AAAQPAAADTwAAAI8AAAFPAAADTwAAAU8AAARPAAAEjwAABM8AAAUPAAAEjwAABQ8AAAVPAAAEzwAABY8AAAXPAAAEzwAABc8AAAUPAAAFTwAABQ8AAAYPAAAFTwAABg8AAAZPAAAFDwAABc8AAAaPAAAFDwAABo8AAAYPAAA2DEAABs8AAASPAAA2DEAABI8AACfOwAAGzwAAHMyAAATPAAAGzwAABM8AAASPAAAczIAABw8AAAWPAAAczIAABY8AAATPAAAHDwAAHEyAAAdPAAAHDwAAB08AAAWPAAAFjwAAB08AAAePAAAFjwAAB48AAAXPAAAFzwAAB48AAAfPAAAFzwAAB88AAAaPAAAGjwAAB88AACfGAAAGjwAAJ8YAACLGQAAGDwAABo8AACLGQAAGDwAAIsZAACKGQAAGTwAABg8AACKGQAAGTwAAIoZAACIGQAAoTsAABk8AACIGQAAoTsAAIgZAACHGQAAoDsAABU8AAAZPAAAoDsAABk8AAChOwAAnzsAABI8AAAVPAAAnzsAABU8AACgOwAAIDwAACE8AAAiPAAAIDwAACI8AAAjPAAAITwAACQ8AAAlPAAAITwAACU8AAAiPAAAIzwAACI8AAAmPAAAIzwAACY8AAAnPAAAIjwAACU8AAAoPAAAIjwAACg8AAAmPAAAhjIAACk8AAAgPAAAhjIAACA8AAAqPAAAKTwAACs8AAAhPAAAKTwAACE8AAAgPAAAKzwAACw8AAAkPAAAKzwAACQ8AAAhPAAALDwAAKs7AACsOwAALDwAAKw7AAAkPAAAJDwAAKw7AACuOwAAJDwAAK47AAAlPAAAJTwAAK47AACtOwAAJTwAAK07AAAoPAAAKDwAAK07AAB4GQAAKDwAAHgZAAB3GQAAJjwAACg8AAB3GQAAJjwAAHcZAAB2GQAAJzwAACY8AAB2GQAAJzwAAHYZAAB1GQAALTwAACc8AAB1GQAALTwAAHUZAACOGAAALjwAACM8AAAnPAAALjwAACc8AAAtPAAAKjwAACA8AAAjPAAAKjwAACM8AAAuPAAALzwAADA8AAAxPAAALzwAADE8AAAyPAAAMDwAADM8AAA0PAAAMDwAADQ8AAAxPAAAMjwAADE8AAA1PAAAMjwAADU8AAA2PAAAMTwAADQ8AAA3PAAAMTwAADc8AAA1PAAAujsAADg8AAAvPAAAujsAAC88AAC7OwAAODwAADk8AAAwPAAAODwAADA8AAAvPAAAOTwAADo8AAAzPAAAOTwAADM8AAAwPAAAOjwAADs8AAA8PAAAOjwAADw8AAAzPAAAMzwAADw8AAA9PAAAMzwAAD08AAA0PAAANDwAAD08AAA+PAAANDwAAD48AAA3PAAANzwAAD48AABbGAAANzwAAFsYAABVGQAANTwAADc8AABVGQAANTwAAFUZAABUGQAANjwAADU8AABUGQAANjwAAFQZAABSGQAAvTsAADY8AABSGQAAvTsAAFIZAABRGQAAvDsAADI8AAA2PAAAvDsAADY8AAC9OwAAuzsAAC88AAAyPAAAuzsAADI8AAC8OwAAPzwAAEA8AABBPAAAPzwAAEE8AABCPAAAQDwAAEM8AABEPAAAQDwAAEQ8AABBPAAAQjwAAEE8AABFPAAAQjwAAEU8AABGPAAAQTwAAEQ8AABHPAAAQTwAAEc8AABFPAAASDwAAEk8AAA/PAAASDwAAD88AABKPAAASTwAAEs8AABAPAAASTwAAEA8AAA/PAAASzwAAEw8AABDPAAASzwAAEM8AABAPAAATDwAAMc7AADJOwAATDwAAMk7AABDPAAAQzwAAMk7AADNOwAAQzwAAM07AABEPAAARDwAAM07AADMOwAARDwAAMw7AABHPAAARzwAAMw7AAAtGQAARzwAAC0ZAAAsGQAARTwAAEc8AAAsGQAARTwAACwZAAArGQAARjwAAEU8AAArGQAARjwAACsZAAAqGQAATTwAAEY8AAAqGQAATTwAACoZAABJGAAATjwAAEI8AABGPAAATjwAAEY8AABNPAAASjwAAD88AABCPAAASjwAAEI8AABOPAAATzwAAFA8AABRPAAATzwAAFE8AABSPAAAUDwAAFM8AABUPAAAUDwAAFQ8AABRPAAAUjwAAFE8AABVPAAAUjwAAFU8AABWPAAAUTwAAFQ8AABXPAAAUTwAAFc8AABVPAAA2DsAAFg8AABPPAAA2DsAAE88AADZOwAAWDwAAFk8AABQPAAAWDwAAFA8AABPPAAAWTwAALcyAABTPAAAWTwAAFM8AABQPAAAtzIAALYyAABaPAAAtzIAAFo8AABTPAAAUzwAAFo8AABbPAAAUzwAAFs8AABUPAAAVDwAAFs8AABcPAAAVDwAAFw8AABXPAAAVzwAAFw8AAAtGAAAVzwAAC0YAAAbGQAAVTwAAFc8AAAbGQAAVTwAABsZAAAaGQAAVjwAAFU8AAAaGQAAVjwAABoZAAAYGQAA2zsAAFY8AAAYGQAA2zsAABgZAAAXGQAA2jsAAFI8AABWPAAA2jsAAFY8AADbOwAA2TsAAE88AABSPAAA2TsAAFI8AADaOwAAXTwAAF48AABfPAAAXTwAAF88AABgPAAAXjwAAGE8AABiPAAAXjwAAGI8AABfPAAAYDwAAF88AABjPAAAYDwAAGM8AABkPAAAXzwAAGI8AABlPAAAXzwAAGU8AABjPAAA8DsAAMoyAABdPAAA8DsAAF08AADxOwAAyjIAAGY8AABePAAAyjIAAF48AABdPAAAZjwAAGc8AABhPAAAZjwAAGE8AABePAAAZzwAAGg8AABpPAAAZzwAAGk8AABhPAAAYTwAAGk8AABqPAAAYTwAAGo8AABiPAAAYjwAAGo8AABrPAAAYjwAAGs8AABlPAAAZTwAAGs8AAAAGAAAZTwAAAAYAADzGAAAYzwAAGU8AADzGAAAYzwAAPMYAADyGAAAZDwAAGM8AADyGAAAZDwAAPIYAADwGAAA8zsAAGQ8AADwGAAA8zsAAPAYAADvGAAA8jsAAGA8AABkPAAA8jsAAGQ8AADzOwAA8TsAAF08AABgPAAA8TsAAGA8AADyOwAAbDwAAG08AABuPAAAbDwAAG48AABvPAAAbTwAAHA8AABxPAAAbTwAAHE8AABuPAAAbzwAAG48AAByPAAAbzwAAHI8AABzPAAAbjwAAHE8AAB0PAAAbjwAAHQ8AAByPAAABDsAAHU8AABsPAAABDsAAGw8AAAFOwAAdTwAAHY8AABtPAAAdTwAAG08AABsPAAAdjwAAHc8AABwPAAAdjwAAHA8AABtPAAAdzwAAFk3AABbNwAAdzwAAFs3AABwPAAAcDwAAFs3AABiNwAAcDwAAGI3AABxPAAAcTwAAGI3AABhNwAAcTwAAGE3AAB0PAAAdDwAAGE3AADdGAAAdDwAAN0YAADcGAAAcjwAAHQ8AADcGAAAcjwAANwYAADbGAAAczwAAHI8AADbGAAAczwAANsYAADZGAAABzsAAHM8AADZGAAABzsAANkYAADYGAAABjsAAG88AABzPAAABjsAAHM8AAAHOwAABTsAAGw8AABvPAAABTsAAG88AAAGOwAAeDwAAHk8AAB6PAAAeDwAAHo8AAB7PAAAeTwAAHw8AAB9PAAAeTwAAH08AAB6PAAAezwAAHo8AAB+PAAAezwAAH48AAB/PAAAejwAAH08AACAPAAAejwAAIA8AAB+PAAAgTwAAII8AAB4PAAAgTwAAHg8AACDPAAAgjwAAIQ8AAB5PAAAgjwAAHk8AAB4PAAAhDwAAIU8AAB8PAAAhDwAAHw8AAB5PAAAhTwAAFIyAAD9OwAAhTwAAP07AAB8PAAAfDwAAP07AAABPAAAfDwAAAE8AAB9PAAAfTwAAAE8AAAAPAAAfTwAAAA8AACAPAAAgDwAAAA8AADHGAAAgDwAAMcYAADGGAAAfjwAAIA8AADGGAAAfjwAAMYYAADFGAAAfzwAAH48AADFGAAAfzwAAMUYAADEGAAAhjwAAH88AADEGAAAhjwAAMQYAADCFwAAhzwAAHs8AAB/PAAAhzwAAH88AACGPAAAgzwAAHg8AAB7PAAAgzwAAHs8AACHPAAAiDwAAIk8AACKPAAAiDwAAIo8AACLPAAAiTwAAIw8AACNPAAAiTwAAI08AACKPAAAizwAAIo8AACOPAAAizwAAI48AACPPAAAijwAAI08AACQPAAAijwAAJA8AACOPAAA+jIAAJE8AACIPAAA+jIAAIg8AACSPAAAkTwAAPcyAACJPAAAkTwAAIk8AACIPAAA9zIAAPYyAACMPAAA9zIAAIw8AACJPAAA9jIAAAs8AAANPAAA9jIAAA08AACMPAAAjDwAAA08AAARPAAAjDwAABE8AACNPAAAjTwAABE8AAAQPAAAjTwAABA8AACQPAAAkDwAABA8AAC1GAAAkDwAALUYAAC0GAAAjjwAAJA8AAC0GAAAjjwAALQYAACzGAAAjzwAAI48AACzGAAAjzwAALMYAACyGAAAkzwAAI88AACyGAAAkzwAALIYAACVFwAAlDwAAIs8AACPPAAAlDwAAI88AACTPAAAkjwAAIg8AACLPAAAkjwAAIs8AACUPAAAlTwAAJY8AACXPAAAlTwAAJc8AACYPAAAljwAAJk8AACaPAAAljwAAJo8AACXPAAAmDwAAJc8AACbPAAAmDwAAJs8AACcPAAAlzwAAJo8AACdPAAAlzwAAJ08AACbPAAAcTIAAAwzAACVPAAAcTIAAJU8AAAdPAAADDMAAJ48AACWPAAADDMAAJY8AACVPAAAnjwAAJ88AACZPAAAnjwAAJk8AACWPAAAnzwAAAkzAACgPAAAnzwAAKA8AACZPAAAmTwAAKA8AAChPAAAmTwAAKE8AACaPAAAmjwAAKE8AACiPAAAmjwAAKI8AACdPAAAnTwAAKI8AAB6FwAAnTwAAHoXAACjGAAAmzwAAJ08AACjGAAAmzwAAKMYAACiGAAAnDwAAJs8AACiGAAAnDwAAKIYAACgGAAAHzwAAJw8AACgGAAAHzwAAKAYAACfGAAAHjwAAJg8AACcPAAAHjwAAJw8AAAfPAAAHTwAAJU8AACYPAAAHTwAAJg8AAAePAAAozwAAKQ8AAClPAAAozwAAKU8AACmPAAApDwAAKc8AACoPAAApDwAAKg8AAClPAAApjwAAKU8AACpPAAApjwAAKk8AACqPAAApTwAAKg8AACrPAAApTwAAKs8AACpPAAA9DYAABkzAACjPAAA9DYAAKM8AAD1NgAAGTMAABgzAACkPAAAGTMAAKQ8AACjPAAAGDMAAKw8AACnPAAAGDMAAKc8AACkPAAArDwAAIYyAAAqPAAArDwAACo8AACnPAAApzwAACo8AAAuPAAApzwAAC48AACoPAAAqDwAAC48AAAtPAAAqDwAAC08AACrPAAAqzwAAC08AACOGAAAqzwAAI4YAACNGAAAqTwAAKs8AACNGAAAqTwAAI0YAACMGAAAqjwAAKk8AACMGAAAqjwAAIwYAACKGAAA9zYAAKo8AACKGAAA9zYAAIoYAACJGAAA9jYAAKY8AACqPAAA9jYAAKo8AAD3NgAA9TYAAKM8AACmPAAA9TYAAKY8AAD2NgAArTwAAK48AACvPAAArTwAAK88AACwPAAArjwAALE8AACyPAAArjwAALI8AACvPAAAsDwAAK88AACzPAAAsDwAALM8AAC0PAAArzwAALI8AAC1PAAArzwAALU8AACzPAAAOzwAACYzAACtPAAAOzwAAK08AAA8PAAAJjMAALY8AACuPAAAJjMAAK48AACtPAAAtjwAALc8AACxPAAAtjwAALE8AACuPAAAtzwAAEosAAADNwAAtzwAAAM3AACxPAAAsTwAAAM3AAALNwAAsTwAAAs3AACyPAAAsjwAAAs3AAAKNwAAsjwAAAo3AAC1PAAAtTwAAAo3AABgGAAAtTwAAGAYAABfGAAAszwAALU8AABfGAAAszwAAF8YAABeGAAAtDwAALM8AABeGAAAtDwAAF4YAABcGAAAPjwAALQ8AABcGAAAPjwAAFwYAABbGAAAPTwAALA8AAC0PAAAPTwAALQ8AAA+PAAAPDwAAK08AACwPAAAPDwAALA8AAA9PAAAuDwAALk8AAC6PAAAuDwAALo8AAC7PAAAuTwAALw8AAC9PAAAuTwAAL08AAC6PAAAuzwAALo8AAC+PAAAuzwAAL48AAC/PAAAujwAAL08AADAPAAAujwAAMA8AAC+PAAAWSwAAME8AAC4PAAAWSwAALg8AAAYNwAAwTwAADQzAAC5PAAAwTwAALk8AAC4PAAANDMAAMI8AAC8PAAANDMAALw8AAC5PAAAwjwAAEg8AABKPAAAwjwAAEo8AAC8PAAAvDwAAEo8AABOPAAAvDwAAE48AAC9PAAAvTwAAE48AABNPAAAvTwAAE08AADAPAAAwDwAAE08AABJGAAAwDwAAEkYAABIGAAAvjwAAMA8AABIGAAAvjwAAEgYAABHGAAAvzwAAL48AABHGAAAvzwAAEcYAABFGAAAGjcAAL88AABFGAAAGjcAAEUYAABEGAAAGTcAALs8AAC/PAAAGTcAAL88AAAaNwAAGDcAALg8AAC7PAAAGDcAALs8AAAZNwAAwzwAAMQ8AADFPAAAwzwAAMU8AADGPAAAxDwAAMc8AADIPAAAxDwAAMg8AADFPAAAxjwAAMU8AADJPAAAxjwAAMk8AADKPAAAxTwAAMg8AADLPAAAxTwAAMs8AADJPAAAtjIAAMw8AADDPAAAtjIAAMM8AABaPAAAzDwAAM08AADEPAAAzDwAAMQ8AADDPAAAzTwAAM48AADHPAAAzTwAAMc8AADEPAAAzjwAACY3AAAoNwAAzjwAACg3AADHPAAAxzwAACg3AAAuNwAAxzwAAC43AADIPAAAyDwAAC43AAAtNwAAyDwAAC03AADLPAAAyzwAAC03AAAyGAAAyzwAADIYAAAxGAAAyTwAAMs8AAAxGAAAyTwAADEYAAAwGAAAyjwAAMk8AAAwGAAAyjwAADAYAAAuGAAAXDwAAMo8AAAuGAAAXDwAAC4YAAAtGAAAWzwAAMY8AADKPAAAWzwAAMo8AABcPAAAWjwAAMM8AADGPAAAWjwAAMY8AABbPAAAzzwAANA8AADRPAAAzzwAANE8AADSPAAA0DwAANM8AADUPAAA0DwAANQ8AADRPAAA0jwAANE8AADVPAAA0jwAANU8AADWPAAA0TwAANQ8AADXPAAA0TwAANc8AADVPAAAaDwAANg8AADPPAAAaDwAAM88AABpPAAA2DwAANk8AADQPAAA2DwAANA8AADPPAAA2TwAANo8AADTPAAA2TwAANM8AADQPAAA2jwAAJssAABKNwAA2jwAAEo3AADTPAAA0zwAAEo3AABPNwAA0zwAAE83AADUPAAA1DwAAE83AABONwAA1DwAAE43AADXPAAA1zwAAE43AAAFGAAA1zwAAAUYAAAEGAAA1TwAANc8AAAEGAAA1TwAAAQYAAADGAAA1jwAANU8AAADGAAA1jwAAAMYAAABGAAAazwAANY8AAABGAAAazwAAAEYAAAAGAAAajwAANI8AADWPAAAajwAANY8AABrPAAAaTwAAM88AADSPAAAaTwAANI8AABqPAAA2zwAANw8AADdPAAA2zwAAN08AADePAAA3DwAAN88AADgPAAA3DwAAOA8AADdPAAA3jwAAN08AADhPAAA3jwAAOE8AADiPAAA3TwAAOA8AADjPAAA3TwAAOM8AADhPAAAKy4AAF0zAADbPAAAKy4AANs8AACYOAAAXTMAAOQ8AADcPAAAXTMAANw8AADbPAAA5DwAAOU8AADfPAAA5DwAAN88AADcPAAA5TwAAAgxAADzOgAA5TwAAPM6AADfPAAA3zwAAPM6AAD3OgAA3zwAAPc6AADgPAAA4DwAAPc6AAD2OgAA4DwAAPY6AADjPAAA4zwAAPY6AADxFwAA4zwAAPEXAADwFwAA4TwAAOM8AADwFwAA4TwAAPAXAADvFwAA4jwAAOE8AADvFwAA4jwAAO8XAADtFwAAmjgAAOI8AADtFwAAmjgAAO0XAADsFwAAmTgAAN48AADiPAAAmTgAAOI8AACaOAAAmDgAANs8AADePAAAmDgAAN48AACZOAAA5jwAAOc8AADoPAAA5jwAAOg8AADpPAAA5zwAAOo8AADrPAAA5zwAAOs8AADoPAAA6TwAAOg8AADsPAAA6TwAAOw8AADtPAAA6DwAAOs8AADuPAAA6DwAAO48AADsPAAAwCwAAO88AADmPAAAwCwAAOY8AABwNwAA7zwAAGozAADnPAAA7zwAAOc8AADmPAAAajMAAPA8AADqPAAAajMAAOo8AADnPAAA8DwAAIE8AACDPAAA8DwAAIM8AADqPAAA6jwAAIM8AACHPAAA6jwAAIc8AADrPAAA6zwAAIc8AACGPAAA6zwAAIY8AADuPAAA7jwAAIY8AADCFwAA7jwAAMIXAADBFwAA7DwAAO48AADBFwAA7DwAAMEXAADAFwAA7TwAAOw8AADAFwAA7TwAAMAXAAC+FwAAcjcAAO08AAC+FwAAcjcAAL4XAAC9FwAAcTcAAOk8AADtPAAAcTcAAO08AAByNwAAcDcAAOY8AADpPAAAcDcAAOk8AABxNwAA8TwAAPI8AADzPAAA8TwAAPM8AAD0PAAA8jwAAPU8AAD2PAAA8jwAAPY8AADzPAAA9DwAAPM8AAD3PAAA9DwAAPc8AAD4PAAA8zwAAPY8AAD5PAAA8zwAAPk8AAD3PAAAEzsAAPo8AADxPAAAEzsAAPE8AAAUOwAA+jwAAPs8AADyPAAA+jwAAPI8AADxPAAA+zwAAPw8AAD1PAAA+zwAAPU8AADyPAAA/DwAAHguAADQOAAA/DwAANA4AAD1PAAA9TwAANA4AADYOAAA9TwAANg4AAD2PAAA9jwAANg4AADXOAAA9jwAANc4AAD5PAAA+TwAANc4AACsFwAA+TwAAKwXAACrFwAA9zwAAPk8AACrFwAA9zwAAKsXAACqFwAA+DwAAPc8AACqFwAA+DwAAKoXAACoFwAAFjsAAPg8AACoFwAAFjsAAKgXAACnFwAAFTsAAPQ8AAD4PAAAFTsAAPg8AAAWOwAAFDsAAPE8AAD0PAAAFDsAAPQ8AAAVOwAA/TwAAP48AAD/PAAA/TwAAP88AAAAPQAA/jwAAAE9AAACPQAA/jwAAAI9AAD/PAAAAD0AAP88AAADPQAAAD0AAAM9AAAEPQAA/zwAAAI9AAAFPQAA/zwAAAU9AAADPQAAgzcAAAY9AAD9PAAAgzcAAP08AACENwAABj0AAAc9AAD+PAAABj0AAP48AAD9PAAABz0AAIUzAAABPQAABz0AAAE9AAD+PAAAhTMAAPoyAACSPAAAhTMAAJI8AAABPQAAAT0AAJI8AACUPAAAAT0AAJQ8AAACPQAAAj0AAJQ8AACTPAAAAj0AAJM8AAAFPQAABT0AAJM8AACVFwAABT0AAJUXAACUFwAAAz0AAAU9AACUFwAAAz0AAJQXAACTFwAABD0AAAM9AACTFwAABD0AAJMXAACRFwAAhjcAAAQ9AACRFwAAhjcAAJEXAACQFwAAhTcAAAA9AAAEPQAAhTcAAAQ9AACGNwAAhDcAAP08AAAAPQAAhDcAAAA9AACFNwAACD0AAAk9AAAKPQAACD0AAAo9AAALPQAACT0AAAw9AAANPQAACT0AAA09AAAKPQAACz0AAAo9AAAOPQAACz0AAA49AAAPPQAACj0AAA09AAAQPQAACj0AABA9AAAOPQAACTMAAJYzAAAIPQAACTMAAAg9AACgPAAAljMAABE9AAAJPQAAljMAAAk9AAAIPQAAET0AAJQzAAAMPQAAET0AAAw9AAAJPQAAlDMAAJI3AACUNwAAlDMAAJQ3AAAMPQAADD0AAJQ3AACbNwAADD0AAJs3AAANPQAADT0AAJs3AACaNwAADT0AAJo3AAAQPQAAED0AAJo3AAB/FwAAED0AAH8XAAB+FwAADj0AABA9AAB+FwAADj0AAH4XAAB9FwAADz0AAA49AAB9FwAADz0AAH0XAAB7FwAAojwAAA89AAB7FwAAojwAAHsXAAB6FwAAoTwAAAs9AAAPPQAAoTwAAA89AACiPAAAoDwAAAg9AAALPQAAoDwAAAs9AAChPAAAJXobPQAAAAAfm4k8AAAAAKuBrTwAAAAA7lomPQAAAABqFBE8AAAAAP5ikDwAAAAAHpuJPAAAAAC/kTE9AAAAAP9ikDwAAAAAALCZPQAAAADH0QY9AAAAAHrhrT0AAAAAiMd4PAAAAABcAbQ9AAAAAPsM0jsAAAAASlDpOwAAAAB4gAU8AAAAADURjTwAAAAAVmbXPQAAAACc0cM9AAAAAKs2Pz0AAAAAXQG0PQAAAABDHCk+AAAAACANJj4AAAAAXkdrPgAAAACPnIM+AAAAAIMlNT4AAAAAF4yIPgAAAAB+qq4+AAAAAI6cgz4AAAAAe+GtPQAAAADoiy4+AAAAALZujD4AAAAAf8RJPgAAAACd0cM9AAAAABhvnD4AAAAA7qr7PgAAAABatME+AAAAAJGw0T4AAAAApe9MPgAAAADsETE+AAAAAAK+dj4AAAAAlsaSPgAAAAD3ri0+AAAAAPynhj4AAAAA6xExPgAAAABVgbQ+AAAAABqAJD4AAAAAmMjuPQAAAACGpYI+AAAAAFLCyT0AAAAAZLGyPgAAAAC2wbc9AAAAAMU53j4AAAAAtW6MPgAAAAA6Ia8+AAAAAGuh0z4AAAAA3dvrPgAAAACASt8+AAAAAIBD/T4AAAAAddUGPwAAAACt7AY/AAAAAIFK3z4AAAAAF8GcPgAAAADQA9c+AAAAADC1ED8AAAAAdLYYPwAAAABjsbI+AAAAAGB3GT8AAAAA8jMFPwAAAAD7PBo/AAAAAHW2GD8AAAAA/1yuPgAAAADzWN4+AAAAAOkL6z4AAAAA98rTPgAAAAB2bwY/AAAAAITOBj8AAAAA8VjePgAAAAD8rQA/AAAAAPjK0z4AAAAAGMGcPgAAAABLXYI+AAAAAGKXtD4AAAAAHMcZPwAAAADQZxk/AAAAAOmMDj8AAAAA0V3oPgAAAACt6hU/AAAAAFv3Tj4AAAAAPXA8PgAAAADfQII+AAAAAJK6lj4AAAAA7DZPPgAAAABFtJY+AAAAADxwPD4AAAAABYDCPgAAAACTupY+AAAAANCfFj4AAAAAAfLzPQAAAAARUn8+AAAAAM7Q3z0AAAAAadWzPgAAAABKP/Q9AAAAAGGXtD4AAAAA4x/oPgAAAADSXeg+AAAAAGCXtD4AAAAAKhClPgAAAAA5q9A+AAAAAHi85D4AAAAAumLQPgAAAABs2f8+AAAAADZABD8AAAAAOqvQPgAAAAAnLf8+AAAAALli0D4AAAAAN0AEPwAAAABZi38+AAAAABGNsz4AAAAAHi4VPwAAAADkH+g+AAAAAGY6Fz8AAAAApIUNPwAAAABYNuc+AAAAAMmhFD8AAAAAHOlRPgAAAADnbz8+AAAAALMhgz4AAAAAeUiXPgAAAACOkFA+AAAAAPr/lj4AAAAA6G8/PgAAAABrLcI+AAAAAN+8Gj4AAAAARSP9PQAAAAA5r4A+AAAAADeN6D0AAAAAa9WzPgAAAABYi38+AAAAAKDA+D0AAAAAEI2zPgAAAAA2jeg9AAAAALQZ5z4AAAAAWTbnPgAAAAD1WaU+AAAAAMQZ0D4AAAAAFMXjPgAAAABG0c8+AAAAAPVa/j4AAAAATmoDPwAAAACxrv0+AAAAAEXRzz4AAAAAT2oDPwAAAADcy4A+AAAAAGrVsz4AAAAAEY2zPgAAAAAzBBQ/AAAAAMYEFj8AAAAAYX4MPwAAAAApMOY+AAAAAN53Ez8AAAAAEI2zPgAAAADFBBY/AAAAAAfmVD4AAAAAhcdCPgAAAAAXGYQ+AAAAAO3Zlz4AAAAAfo1TPgAAAABukZc+AAAAAJ/jwT4AAAAA7tkePgAAAABOOQM+AAAAAGe1gT4AAAAAQjryPQAAAABq1bM+AAAAAPsHAT4AAAAARDryPQAAAACGE+Y+AAAAAL+jpT4AAAAAUYjPPgAAAACuzeI+AAAAANE/zz4AAAAAgNz8PgAAAABolAI/AAAAAFCIzz4AAAAAOTD8PgAAAABnlAI/AAAAAArSgT4AAAAAEI2zPgAAAABI2hI/AAAAACPPFD8AAAAAHXcLPwAAAAD5KeU+AAAAAPNNEj8AAAAAD42zPgAAAAD34lc+AAAAACIfRj4AAAAAfBCFPgAAAABga5g+AAAAAGmKVj4AAAAA4iKYPgAAAADTmcE+AAAAAOEimD4AAAAA/vYiPgAAAAD54Ac+AAAAAJe7gj4AAAAATuf7PQAAAABo1bM+AAAAAKavBT4AAAAAVg3lPgAAAAD6KeU+AAAAAGfVsz4AAAAAi+2lPgAAAADc9s4+AAAAAEvW4T4AAAAAXa7OPgAAAAAGXvs+AAAAAIG+AT8AAAAAw7H6PgAAAACAvgE/AAAAADvYgj4AAAAAEo2zPgAAAABdsBE/AAAAAFUN5T4AAAAAgZkTPwAAAADZbwo/AAAAAMoj5D4AAAAACCQRPwAAAAAQjbM+AAAAAIKZEz8AAAAA5d9aPgAAAAC/dkk+AAAAAOIHhj4AAAAA1fyYPgAAAABYh1k+AAAAAFW0mD4AAAAAvnZJPgAAAAAHUME+AAAAANT8mD4AAAAAVrSYPgAAAAAKFCc+AAAAAKaIDD4AAAAAxsGDPgAAAAAtygI+AAAAAGvVsz4AAAAAU1cKPgAAAAARjbM+AAAAACYH5D4AAAAAatWzPgAAAABXN6Y+AAAAAGhlzj4AAAAA5d7gPgAAAADqHM4+AAAAAJHf+T4AAAAAmegAPwAAAABOM/k+AAAAAJjoAD8AAAAAat6DPgAAAAAQjbM+AAAAAHOGED8AAAAAJwfkPgAAAADgYxI/AAAAAJdoCT8AAAAAnB3jPgAAAAAe+g8/AAAAAGXGYj4AAAAA4ixOPgAAAAAyWYc+AAAAAF5emj4AAAAA0LBcPgAAAADyU5k+AAAAAJ0gwT4AAAAAX16aPgAAAABJIk8+AAAAAGi1GD4AAAAAyZiLPgAAAABIgAk+AAAAAMPLtT4AAAAA8joPPgAAAAARjbM+AAAAAEeACT4AAAAAwT/jPgAAAACdHeM+AAAAAMLLtT4AAAAAPIO0PgAAAADqJdI+AAAAAPd26D4AAAAANbXhPgAAAADysPk+AAAAAHjCAz8AAAAA6SXSPgAAAABkxwc/AAAAAJ4Krj4AAAAACGjlPgAAAACixA8/AAAAAMI/4z4AAAAAFW8UPwAAAADP2iw/AAAAAH/xDT8AAAAA5VcaPwAAAAAUbxQ/AAAAALphmD4AAAAA1y+KPgAAAADF4rk+AAAAAHbc1j4AAAAA8K2RPgAAAAAqudE+AAAAAB7sBz8AAAAAkMGCPgAAAACNkUA+AAAAAMDguz4AAAAAFKcvPgAAAACwXP8+AAAAAFJTqT4AAAAA9Ro0PgAAAAB2bu8+AAAAAFVIST8AAAAAfQojPwAAAABVTB0/AAAAAHVu7z4AAAAAmIcjPwAAAADJogM/AAAAAHs4Cz8AAAAA5UsgPwAAAAB7ws8+AAAAAOsH/D4AAAAAHB4XPwAAAAAj5EA/AAAAAPg1OD8AAAAACWjlPgAAAAB3bu8+AAAAAMSqLz8AAAAAfvENPwAAAAD5NTg/AAAAAGtr9T4AAAAAq/UTPwAAAABbuiI/AAAAAA3gGT8AAAAAquYyPwAAAAARizk/AAAAAKr1Ez8AAAAANw04PwAAAAAO4Bk/AAAAAMHguz4AAAAA7vTfPgAAAACvXP8+AAAAABvZFD8AAAAA/Y5PPwAAAAB+CiM/AAAAAL7vUT8AAAAAb81PPwAAAAAGujU/AAAAADYbUT8AAAAAHNkUPwAAAACEw1w/AAAAAIjmWj8AAAAAELdSPwAAAAB+SVE/AAAAAOrEUj8AAAAAFIpJPwAAAACH5lo/AAAAACz7Qj8AAAAA7c1lPwAAAADbf2U/AAAAAEW+XD8AAAAAu3RjPwAAAAA9sFA/AAAAAFq5XD8AAAAA6eBBPwAAAAD6NTg/AAAAAAyKXj8AAAAAkiZfPwAAAAANk1c/AAAAAKURVD8AAAAAWu9dPwAAAADanVM/AAAAAKZ/ST8AAAAAphFUPwAAAACSO2c/AAAAAN45Zz8AAAAA4QlePwAAAACfOWc/AAAAAH0rUj8AAAAARr5cPwAAAACAhGY/AAAAADywUD8AAAAAeA1EPwAAAADs4EE/AAAAAH4rUj8AAAAAQFz/PgAAAAC83Ro/AAAAAGTJJD8AAAAAAIsaPwAAAABqwzc/AAAAALoHOj8AAAAA3Sw3PwAAAAD/iho/AAAAALkHOj8AAAAA0s7hPgAAAABaZhQ/AAAAAPF0UD8AAAAABbo1PwAAAADpHVE/AAAAAMpfTj8AAAAAeY80PwAAAACVv08/AAAAAFtmFD8AAAAA6B1RPwAAAAARyV8/AAAAAHlrYD8AAAAAT61YPwAAAABHEFU/AAAAADYxXz8AAAAAGrNUPwAAAAAtXUo/AAAAADapaD8AAAAAdqloPwAAAADiPl8/AAAAACiraD8AAAAA4vFSPwAAAADgCV4/AAAAABn0Zz8AAAAAfytSPwAAAAABIUQ/AAAAAODxUj8AAAAAudD9PgAAAACP6Rk/AAAAACGvIz8AAAAAfXYZPwAAAACyhTY/AAAAAM/COD8AAAAAGus1PwAAAADQwjg/AAAAAKqY3T4AAAAA7vASPwAAAADLX04/AAAAAFoFTz8AAAAAX6xPPwAAAAAk8kw/AAAAAJdEMz8AAAAA/E9OPwAAAABgrE8/AAAAAAFEXj8AAAAAMd1gPwAAAADOg1g/AAAAABT4Uj8AAAAA6EdgPwAAAACmE1U/AAAAADLdYD8AAAAAkPtIPwAAAACnE1U/AAAAAIhZZT8AAAAAy3FoPwAAAABHfFg/AAAAAEalaT8AAAAAB4FLPwAAAAA3qWg/AAAAAMJUaT8AAAAAJso9PwAAAAACIUQ/AAAAAAaBSz8AAAAAY1LxPgAAAABKRRc/AAAAAHxiHz8AAAAAppIQPwAAAAAS3jQ/AAAAAL1oNT8AAAAAM6wtPwAAAAClkhA/AAAAAK4PuT4AAAAA3Gn5PgAAAAAl8kw/AAAAAC1wTT8AAAAAKA5NPwAAAADCaD8/AAAAAL/OHT8AAAAA2bNIPwAAAADbafk+AAAAACcOTT8AAAAAdWpPPwAAAAC1fkQ/AAAAALi3Pz8AAAAAxNFEPwAAAACwNjg/AAAAAHDJNj8AAAAADmE5PwAAAADF0UQ/AAAAAG7JNj8AAAAAfKFYPwAAAAD4E0w/AAAAAC4lLT8AAAAAJco9PwAAAACYXy0/AAAAAP89NT8AAAAAa+4/PwAAAACDDy8/AAAAAJdfLT8AAAAAtk6YPgAAAAAfoos+AAAAAMeWuT4AAAAAKPLTPgAAAABtHJc+AAAAAMB60z4AAAAAHqKLPgAAAAC7uwU/AAAAACby0z4AAAAAOH+DPgAAAABxNUU+AAAAANwwuz4AAAAASbY1PgAAAADNH/o+AAAAAEWpQT4AAAAASLY1PgAAAABGxx0/AAAAANpp+T4AAAAADtBhPwAAAAAE22E/AAAAAFNuWT8AAAAAQ3BWPwAAAAAvw14/AAAAAAS0Uz8AAAAAzLNKPwAAAABCcFY/AAAAAAtOaz8AAAAAKkZrPwAAAABUZGE/AAAAAAXsaj8AAAAAYvVUPwAAAACFEWk/AAAAAATsaj8AAAAA2xxHPwAAAABh9VQ/AAAAAJ/v8z4AAAAAoNQQPwAAAABwjR8/AAAAABxPGD8AAAAAI1ktPwAAAACD9DQ/AAAAAILsND8AAAAAHU8YPwAAAACE9DQ/AAAAAP1n4z4AAAAA4gUWPwAAAABOHEg/AAAAAM4ITD8AAAAAzB/6PgAAAAB+WEw/AAAAAFnMND8AAAAAfFtMPwAAAAChNWM/AAAAACPmYz8AAAAAArlbPwAAAAD7CFg/AAAAABqdYj8AAAAAcaZXPwAAAAAk5mM/AAAAAAJ2TT8AAAAA+ghYPwAAAABwplc/AAAAALC7bD8AAAAAt8NsPwAAAACunmI/AAAAADLNbD8AAAAAjeZVPwAAAAAMTms/AAAAAFkObD8AAAAAMc1sPwAAAAA0q0c/AAAAANwcRz8AAAAAgLMDPwAAAADyDSA/AAAAAH+kMT8AAAAA7ZwfPwAAAABDdzo/AAAAADRVRD8AAAAA+PpDPwAAAADmqjk/AAAAAG02Tz8AAAAA/GfjPgAAAAAeSeI+AAAAAOMFFj8AAAAAWsw0PwAAAAB/WEw/AAAAAFgWTz8AAAAAVttTPwAAAAAh6Fg/AAAAAAMjXD8AAAAAtqpYPwAAAAA6QFM/AAAAAB4GTj8AAAAAYXczPwAAAAAtvEo/AAAAAPcLFT8AAAAABHlhPwAAAABRR2Q/AAAAACJ2Wz8AAAAASbJVPwAAAABPsWM/AAAAAPL/Vz8AAAAAY/VLPwAAAABIslU/AAAAACoMaT8AAAAA5WpsPwAAAACIO1s/AAAAAPu9bT8AAAAA4cxNPwAAAACxu2w/AAAAANhtbT8AAAAAR8tAPwAAAAA1q0c/AAAAAI7mVT8AAAAAe2vxPgAAAACtuxY/AAAAAP+DHT8AAAAAF9YOPwAAAAADADM/AAAAANWEMj8AAAAArrsWPwAAAADjoio/AAAAABjWDj8AAAAAHEniPgAAAAAkd7k+AAAAAPYLFT8AAAAA+a32PgAAAAAdIEo/AAAAAGJ3Mz8AAAAAAzFJPwAAAAD1CxU/AAAAACO2Oz8AAAAAOi0bPwAAAAAxwkQ/AAAAAPqt9j4AAAAAv2dRPwAAAACkCUY/AAAAAA6iQD8AAAAA8+5FPwAAAACC0Dk/AAAAAN45Nz8AAAAAowlGPwAAAAC6mDk/AAAAAOA5Nz8AAAAAiTtbPwAAAABTTFs/AAAAAOLMTT8AAAAAeLxNPwAAAAAi1S4/AAAAAM48LT8AAAAAUA81PwAAAADbnEA/AAAAAN94Lj8AAAAAebxNPwAAAADPPC0/AAAAAOXElz4AAAAAd+CLPgAAAABvVbg+AAAAAHm50T4AAAAAUJSXPgAAAACbmdE+AAAAALHQAz8AAAAAIzCCPgAAAADHSUc+AAAAAGDRuD4AAAAAVlM5PgAAAADqe/Y+AAAAACN3uT4AAAAANYFGPgAAAABCFxs/AAAAAOt79j4AAAAASSplPwAAAACBO2U/AAAAAGUjXD8AAAAAKuVYPwAAAAAG6WE/AAAAANP2VT8AAAAAgDtlPwAAAABPPEw/AAAAANL2VT8AAAAAhWBvPwAAAABCX28/AAAAALevZD8AAAAAuQRvPwAAAAC0Rlc/AAAAAKAKbT8AAAAAd7xNPwAAAAC4BG8/AAAAAAxXSD8AAAAA3JxAPwAAAABqPe4+AAAAAIEjDj8AAAAAkQwcPwAAAABgAxQ/AAAAAG8ZKj8AAAAABxYxPwAAAACAIw4/AAAAAPANMD8AAAAAYQMUPwAAAAAIFjE/AAAAANZ92j4AAAAAlWAPPwAAAAAEG0Q/AAAAAEEXGz8AAAAAta5HPwAAAADXOkY/AAAAAFPsLT8AAAAArWVHPwAAAAAEk2Y/AAAAAClXZz8AAAAAdodePwAAAABEilo/AAAAAH36ZT8AAAAAvCdaPwAAAADhKE8/AAAAAEWKWj8AAAAAvidaPwAAAAArznA/AAAAAPjdcD8AAAAADuplPwAAAAA773A/AAAAAN43WD8AAAAAhmBvPwAAAACaKHA/AAAAAGLlSD8AAAAA3zdYPwAAAADdSPc+AAAAAKLuFD8AAAAAph4ePwAAAAAZjBQ/AAAAAO3LLz8AAAAAvOIxPwAAAACj7hQ/AAAAAGczLz8AAAAA1X3aPgAAAAAmYdk+AAAAAGlvDj8AAAAA2NBGPwAAAABOaEc/AAAAAJZgDz8AAAAAMs1EPwAAAAD5sSw/AAAAAHsbRj8AAAAATGhHPwAAAADanmQ/AAAAAMynZz8AAAAAMytePwAAAAAZ9Vc/AAAAAIkLZz8AAAAA2HRaPwAAAADmfU0/AAAAABj1Vz8AAAAA2XRaPwAAAADLvmw/AAAAAAJkcD8AAAAAX+ZdPwAAAACu1nE/AAAAAGF1Tz8AAAAAKs5wPwAAAADuhnE/AAAAALZ5QT8AAAAAYeVIPwAAAABgdU8/AAAAADu66z4AAAAAsXMSPwAAAADDBBo/AAAAADolDD8AAAAAsSwuPwAAAAC7qS4/AAAAALJzEj8AAAAAnGMnPwAAAAA7JQw/AAAAALypLj8AAAAAqhe3PgAAAABobw4/AAAAABkK8z4AAAAAAD5FPwAAAADA3EQ/AAAAAGpvDj8AAAAAgQM4PwAAAAA3fRg/AAAAAKPBQD8AAAAAGgrzPgAAAADsS1M/AAAAAFQXRz8AAAAA+ylBPwAAAAA4tEY/AAAAAMvvOT8AAAAAe+o2PwAAAABSF0c/AAAAALfQOD8AAAAAeuo2PwAAAABd5l0/AAAAAPDkXT8AAAAAMdNOPwAAAACvHS4/AAAAALd5QT8AAAAAkBMsPwAAAABidU8/AAAAAMslLj8AAAAAhz8/PwAAAADeTiw/AAAAAI8TLD8AAAAA27iXPgAAAACE+4s+AAAAAP8Btz4AAAAAQK3PPgAAAAADBpc+AAAAABRezz4AAAAAg/uLPgAAAADt4gE/AAAAAD+tzz4AAAAAE17PPgAAAADez30+AAAAAGmJSj4AAAAARrK3PgAAAADYjzw+AAAAAEtR8z4AAAAAqxe3PgAAAAB5iUg+AAAAANJuGD8AAAAATFHzPgAAAABOIWQ/AAAAAAE7Zz8AAAAA9DpdPwAAAABtjVc/AAAAACLMZD8AAAAAUUtXPwAAAAAAO2c/AAAAAM61Sj8AAAAAmcdnPwAAAAALjG4/AAAAADCOXT8AAAAAAKhxPwAAAAAXOFA/AAAAAO/kXT8AAAAADtVwPwAAAAD/p3E/AAAAAOe0QD8AAAAAiT8/PwAAAAAWOFA/AAAAAEc26z4AAAAAtu4LPwAAAACxXhk/AAAAACeOET8AAAAAYvUmPwAAAACuti0/AAAAALXuCz8AAAAAs7MsPwAAAACvltU+AAAAAEpR8z4AAAAAsq8MPwAAAADqIUA/AAAAANFuGD8AAAAAA5ZDPwAAAABdKEI/AAAAAP+UKj8AAAAAlkxDPwAAAACxrww/AAAAAAKWQz8AAAAAmzBAPwAAAADbzks/AAAAAPM+Rj8AAAAAxMc8PwAAAADvbVU/AAAAAPkoSj8AAAAAyKc8PwAAAADDxzw/AAAAAN5xNz8AAAAAHJJEPwAAAADkBjU/AAAAAPTuUT8AAAAAYhoyPwAAAACbx2c/AAAAACAAXj8AAAAA8+5RPwAAAAAW5S8/AAAAAOa0QD8AAAAAYxoyPwAAAABvKeo+AAAAAFj/ED8AAAAAzWoYPwAAAACI5Qo/AAAAAFoRLD8AAAAAKYssPwAAAAB1cSU/AAAAAETytj4AAAAAEHnxPgAAAAA1lEI/AAAAAP6UKj8AAAAAQDNCPwAAAACNpjU/AAAAALfnFj8AAAAA1y8+PwAAAAAPefE+AAAAACdPmD4AAAAAL+qMPgAAAAC92bY+AAAAAO3izj4AAAAAPMWXPgAAAACJpc4+AAAAADHqjD4AAAAAhNoAPwAAAADs4s4+AAAAAIqlzj4AAAAAdhmAPgAAAACCMk4+AAAAALp9tz4AAAAAIbhAPgAAAADLpfE+AAAAAONoTD4AAAAAILhAPgAAAACq1xY/AAAAANUTLT8AAAAAoMAqPwAAAADROyc/AAAAAO/fJz8AAAAAMhQoPwAAAACFnCQ/AAAAAFsKJD8AAAAA3r8uPwAAAAByXik/AAAAAJUqJT8AAAAAOgwiPwAAAACBrCE/AAAAADRKJT8AAAAAHzEhPwAAAABxXik/AAAAALa76T4AAAAAWKUKPwAAAADGvxc/AAAAAJMfED8AAAAAAAIlPwAAAABSlys/AAAAAA+ZKj8AAAAAlB8QPwAAAAAGotQ+AAAAAD9eCz8AAAAAHJA9PwAAAACB7EA/AAAAAMql8T4AAAAAhoM/PwAAAADMhSg/AAAAAMyiQD8AAAAAQF4LPwAAAADJ4y0/AAAAAD3CLj8AAAAAHh4sPwAAAABGpCo/AAAAAPwOLz8AAAAAQfQqPwAAAAB6tCc/AAAAAEWkKj8AAAAANBIwPwAAAADz2zA/AAAAAM1MLD8AAAAA4LExPwAAAACiryg/AAAAAN+/Lj8AAAAA41gzPwAAAADhsTE/AAAAAIIhJT8AAAAAoa8oPwAAAABwXik/AAAAAP+pKT8AAAAA1aAmPwAAAAB1HyU/AAAAAKWDJj8AAAAA2l4jPwAAAAANlCI/AAAAANSgJj8AAAAAhh4jPwAAAACkgyY/AAAAAAyUIj8AAAAAOV4sPwAAAAA5pCg/AAAAALV0ID8AAAAAgyElPwAAAAD53x8/AAAAAIt3IT8AAAAAaAIlPwAAAAC7CCA/AAAAAN+u6D4AAAAAxpAPPwAAAADgyxY/AAAAACmcCT8AAAAAt/YpPwAAAADMayo/AAAAAMWQDz8AAAAAEX4jPwAAAAAonAk/AAAAAAei1D4AAAAAub22PgAAAACRze8+AAAAAIeDPz8AAAAAa+o/PwAAAADBiT8/AAAAAJtJMz8AAAAAkVAVPwAAAAAJnjs/AAAAAMOJPz8AAAAA240vPwAAAABwYi8/AAAAAETRLD8AAAAA+QEsPwAAAAC6Sy4/AAAAAFj+Kj8AAAAAmVQoPwAAAAD4ASw/AAAAAFn+Kj8AAAAAEMAyPwAAAABUfjI/AAAAAP+hLz8AAAAAlicyPwAAAAD+rSs/AAAAAIthMT8AAAAAlScyPwAAAAC1Mic/AAAAAGkCJT8AAAAAOKQoPwAAAADMGpg+AAAAAHmejT4AAAAAiJO2PgAAAACI1M0+AAAAABtUmD4AAAAAgNbNPgAAAABgmf8+AAAAAIfUzT4AAAAAzPtvPgAAAACAjE8+AAAAAG+Rsz4AAAAApEBEPgAAAAAa6e4+AAAAALi9tj4AAAAAAv5PPgAAAAClQEQ+AAAAAHEvFT8AAAAAkFAVPwAAAAAb6e4+AAAAAJLN7z4AAAAATB/ePgAAAACN3Ac/AAAAAPZJEz8AAAAAS7gHPwAAAAAvsSI/AAAAAGKjJz8AAAAAjNwHPwAAAAAMWyI/AAAAAGGjJz8AAAAAcJGzPgAAAAASrrM+AAAAABzp7j4AAAAAwqDuPgAAAABk3To/AAAAAKo7PT8AAAAAVkIyPwAAAACsuhQ/AAAAAA9ROj8AAAAAqs8vPwAAAAD2jTA/AAAAACrFLT8AAAAAigcsPwAAAAA0MDA/AAAAAMaQLD8AAAAABtsoPwAAAACJByw/AAAAACdvMj8AAAAAnVMzPwAAAABU5S0/AAAAAFiKMz8AAAAAVZApPwAAAAASwDI/AAAAAACiLz8AAAAAtDYzPwAAAABWijM/AAAAAGxiJT8AAAAAVpApPwAAAADBsio/AAAAANEHJz8AAAAAojUlPwAAAAAt4SY/AAAAANcYIz8AAAAAtCAiPwAAAADSByc/AAAAAFm7Ij8AAAAAsiAiPwAAAABV5S0/AAAAAM/xLT8AAAAAgl0pPwAAAACKkR8/AAAAAFrbHj8AAAAAV5ApPwAAAABm7B8/AAAAACa6JD8AAAAAxvoePwAAAACDXSk/AAAAAFvbHj8AAAAAc1eaPgAAAABJP48+AAAAAEaFtz4AAAAARKPOPgAAAACW65g+AAAAAJgczj4AAAAASj+PPgAAAADpTf8+AAAAAL8ugz4AAAAA22BWPgAAAAA6Prg+AAAAABb5SD4AAAAAYPXvPgAAAAATrrM+AAAAABj/UT4AAAAAFflIPgAAAAAevRQ/AAAAAK26FD8AAAAAX/XvPgAAAADTXOg+AAAAAGwMCT8AAAAAQZgVPwAAAAClSA4/AAAAALpNIj8AAAAAw5koPwAAAABtDAk/AAAAAF2jJz8AAAAApkgOPwAAAADEmSg/AAAAADk+uD4AAAAAVyLUPgAAAADhtwk/AAAAAM/TOT8AAAAAtQg9PwAAAACCpzs/AAAAAC2jJT8AAAAAgr48PwAAAACOgzA/AAAAADQqMT8AAAAAyOctPwAAAABwIiw/AAAAAG0tMD8AAAAAMf4rPwAAAABMGig/AAAAAG8iLD8AAAAAanYzPwAAAACBeTQ/AAAAAJZmLj8AAAAArp80PwAAAACtgSk/AAAAACrtMz8AAAAAgF0pPwAAAACtnzQ/AAAAANKrJD8AAAAAfNgqPwAAAAAjvSY/AAAAAMG8JD8AAAAAcKEmPwAAAADxUiI/AAAAAEtQIT8AAAAALBciPwAAAABMUCE/AAAAAJdmLj8AAAAAxnguPwAAAABufCk/AAAAACJeHj8AAAAA06skPwAAAAA+rR0/AAAAAK6BKT8AAAAA5+wfPwAAAAAsoiQ/AAAAANX4HT8AAAAAP60dPwAAAAD+T+c+AAAAANm5DT8AAAAAXqQUPwAAAAA+Awg/AAAAAAUBJz8AAAAAPG4nPwAAAADYuQ0/AAAAAMrJID8AAAAAPW4nPwAAAABYItQ+AAAAADZ+tz4AAAAAJh3uPgAAAACDpzs/AAAAACAGPD8AAAAA9KU7PwAAAABk5S8/AAAAAAE2Ez8AAAAAuOE3PwAAAACOgzI/AAAAAAJgMj8AAAAAx/guPwAAAADm2C0/AAAAAAEAMT8AAAAARJcsPwAAAAABYDI/AAAAAAkEKT8AAAAA59gtPwAAAABFlyw/AAAAABWcNj8AAAAAnGI2PwAAAACghDI/AAAAAGALNj8AAAAAXlQtPwAAAADaHTU/AAAAAG18KT8AAAAAYQs2PwAAAACOcic/AAAAAF1ULT8AAAAAuK+aPgAAAAA6MZA+AAAAALNetz4AAAAAZcHNPgAAAAA9ZJo+AAAAANSbzT4AAAAAGkH9PgAAAAB7qIc+AAAAAAqFWT4AAAAAXc+3PgAAAABOKk0+AAAAAG0m7j4AAAAAN363PgAAAABwQVg+AAAAACUd7j4AAAAAvyMTPwAAAAACNhM/AAAAAGwm7j4AAAAA09fmPgAAAAAYtgc/AAAAALLyEz8AAAAAHdoMPwAAAACwWCA/AAAAAFt5Jj8AAAAAtYglPwAAAAAf2gw/AAAAAFx5Jj8AAAAAv2PVPgAAAADDvAg/AAAAAP9BNz8AAAAAwCMTPwAAAAA1Xzo/AAAAAK4COT8AAAAAxZ4jPwAAAAC3FDo/AAAAADZfOj8AAAAA8IMyPwAAAACIizM/AAAAAKvsLz8AAAAAc6AtPwAAAADmJTM/AAAAALNnLj8AAAAAh4szPwAAAAB1iik/AAAAAHSgLT8AAAAAW9M1PwAAAADtDzc/AAAAAOP/Lz8AAAAAI243PwAAAACMaCo/AAAAAJ+EMj8AAAAA/Bo3PwAAAAAibjc/AAAAAC0CJT8AAAAAjXInPwAAAAAr4is/AAAAAPIlJz8AAAAAENUkPwAAAADOBCc/AAAAAAYSIj8AAAAAGuEgPwAAAADsxyE/AAAAAOL/Lz8AAAAAeQ8wPwAAAACLaCo/AAAAAIdOKj8AAAAAW4IdPwAAAABRrhw/AAAAAMctID8AAAAA3rskPwAAAABQDh0/AAAAAIlOKj8AAAAAUq4cPwAAAACPpe4+AAAAAOSWDT8AAAAAm6UVPwAAAABaNA0/AAAAANk6JT8AAAAABQgnPwAAAADjlg0/AAAAAFGiJD8AAAAABggnPwAAAADAY9U+AAAAAA9H1D4AAAAAwrwIPwAAAACXywc/AAAAAIF7OT8AAAAAzPU5PwAAAAAIlTc/AAAAAGxkIj8AAAAAJMY4PwAAAACWywc/AAAAAMv1OT8AAAAAQZ40PwAAAAAlfzQ/AAAAAFeWMD8AAAAAGEgvPwAAAAAM8zI/AAAAAPrdLT8AAAAA0sIpPwAAAADqQDk/AAAAAGcMOT8AAAAApZY0PwAAAADitDg/AAAAAGy8Lj8AAAAAeA8wPwAAAACnrzc/AAAAAIhOKj8AAAAA4bQ4PwAAAAC/PCg/AAAAAN27JD8AAAAAo1TkPgAAAABvSgs/AAAAAOXqET8AAAAA07cFPwAAAAB1pyM/AAAAAA8NJD8AAAAAbkoLPwAAAADcoh0/AAAAAKUVtj4AAAAAl7TqPgAAAAAJ7Tc/AAAAAG1kIj8AAAAAQY03PwAAAADFMiw/AAAAALSJED8AAAAAn+gzPwAAAACZtOo+AAAAAECNNz8AAAAA7u41PwAAAACcGjY/AAAAALM1Mj8AAAAAiZAwPwAAAAD4VTU/AAAAAJgqMD8AAAAAnRo2PwAAAABPbis/AAAAAJCuOj8AAAAAEoI6PwAAAABl1DU/AAAAAAtXOj8AAAAA08gvPwAAAACkljQ/AAAAALTMOT8AAAAADFc6PwAAAAC/HCk/AAAAAL65mD4AAAAAG6KPPgAAAAD0s7U+AAAAABgNyz4AAAAAN9uZPgAAAAA/WMs+AAAAAByijz4AAAAA6lD5PgAAAAAZDcs+AAAAALDEgz4AAAAAnSBXPgAAAADb8LM+AAAAACmVTj4AAAAAHhbqPgAAAACHilo+AAAAAJi06j4AAAAAKpVOPgAAAAD1bBA/AAAAAP4j4j4AAAAAXy0FPwAAAADCGRE/AAAAAE4fCj8AAAAA+SkdPwAAAAA7EyM/AAAAAJglIj8AAAAATR8KPwAAAAA6EyM/AAAAACl60D4AAAAAygsGPwAAAADkSDM/AAAAAIFGNj8AAAAAM/A0PwAAAABvRyA/AAAAAKD7NT8AAAAAyQsGPwAAAACCRjY/AAAAAEkuNz8AAAAAhV83PwAAAAD0TzM/AAAAANaRMT8AAAAAF5Y2PwAAAAD5MTE/AAAAABQ0LD8AAAAA15ExPwAAAAA1HDw/AAAAAKnxOz8AAAAAEQw3PwAAAACSyDs/AAAAAJekMD8AAAAAj646PwAAAABMPDs/AAAAANLILz8AAAAAk8g7PwAAAADgaik/AAAAALLR6T4AAAAArs8KPwAAAABJsxI/AAAAAIt5Cj8AAAAAk9QhPwAAAABckSM/AAAAAJg9IT8AAAAAKnrQPgAAAABtudE+AAAAAM99BT8AAAAAQGE1PwAAAADD0zU/AAAAAI6CMz8AAAAAfBkfPwAAAADjqzQ/AAAAANB9BT8AAAAAxdo2PwAAAAA3LDg/AAAAAA6yMz8AAAAAVtEwPwAAAACBvjc/AAAAAGLZMT8AAAAAIcErPwAAAABV0TA/AAAAAK3bOj8AAAAAVHA8PwAAAAB2vDM/AAAAAAr2PD8AAAAAP9QsPwAAAABgozw/AAAAAJikMD8AAAAA8RUmPwAAAADhaik/AAAAAEDULD8AAAAAvpsuPwAAAAC7zCg/AAAAACSxJT8AAAAAhAsoPwAAAABpdCI/AAAAAPh7ID8AAAAApx4gPwAAAACFCyg/AAAAAPd7ID8AAAAARa4zPwAAAAD7yys/AAAAAELFHD8AAAAAghEbPwAAAAD8DxE/AAAAAElIIj8AAAAA3egYPwAAAABca+g+AAAAABrYCT8AAAAAB5kRPwAAAAAxcQk/AAAAAG6WID8AAAAAdEwiPwAAAAAZ2Ak/AAAAAFv9Hz8AAAAAMHEJPwAAAABzTCI/AAAAAG+50T4AAAAA0crPPgAAAAChaQQ/AAAAAI+CMz8AAAAAqPEzPwAAAAA5YjQ/AAAAANF9BT8AAAAA6hQyPwAAAADE2h0/AAAAAEs8Mz8AAAAAomkEPwAAAAA6YjQ/AAAAAOEeOT8AAAAAxRE5PwAAAABfAjQ/AAAAAM/8MT8AAAAAwzM3PwAAAAC4YDA/AAAAADG4KT8AAAAAzvwxPwAAAAC3YDA/AAAAAAnBPj8AAAAAy5Q+PwAAAAB68Tg/AAAAAMc8Pj8AAAAAwacwPwAAAABErjM/AAAAAA4QPT8AAAAA+ssrPwAAAADIPD4/AAAAAGxCJT8AAAAASkgiPwAAAAD5yys/AAAAAAW7Mz8AAAAAcLc4PwAAAAAi/jI/AAAAAEagLD8AAAAApnw5PwAAAAALpTE/AAAAAG+3OD8AAAAA6iUnPwAAAACJMTI/AAAAAIgDOz8AAAAAZj0oPwAAAAB3eT4/AAAAAMoVID8AAAAAC8E+PwAAAABpKD8/AAAAAHh5Pj8AAAAA9u8XPwAAAABrQiU/AAAAAMkVID8AAAAAQlnkPgAAAABWfQg/AAAAACn2Dz8AAAAABPsGPwAAAAAHSx8/AAAAAAfsID8AAAAA1z0ePwAAAAAD+wY/AAAAAAbsID8AAAAAKQ/FPgAAAAA2xf0+AAAAAGiJMj8AAAAAw9odPwAAAABsKzM/AAAAAE+vGT8AAAAA0IYyPwAAAAA1xf0+AAAAAGsrMz8AAAAA+vjIPgAAAADb4fk+AAAAAPZM/T4AAAAASIfiPgAAAACulhQ/AAAAAB1cDj8AAAAA3eH5PgAAAABzHQQ/AAAAAEeH4j4AAAAAHlwOPwAAAAAE3pw+AAAAADTF/T4AAAAA3bTBPgAAAABlPSg/AAAAAClB7D4AAAAAtMV8PgAAAABvVnE+AAAAANdwkz4AAAAASS2iPgAAAACwWII+AAAAAJg8pT4AAAAAcFZxPgAAAACTZMc+AAAAAKtTVD4AAAAAlwVAPgAAAAAKbI8+AAAAAGJGOj4AAAAAPwe3PgAAAAC1+UY+AAAAAN60wT4AAAAAYUY6PgAAAAB3DOQ+AAAAAChB7D4AAAAAQAe3PgAAAACvqqk+AAAAAARZyj4AAAAAGFvXPgAAAADgCcg+AAAAADIq8D4AAAAA2pvxPgAAAAADWco+AAAAAOkK6T4AAAAA3wnIPgAAAADcm/E+AAAAAAlsjz4AAAAAcyKPPgAAAAAPjbM+AAAAANINCT8AAAAAppIGPwAAAABBB7c+AAAAAFwx/D4AAAAAk9nXPgAAAACbXAM/AAAAABCNsz4AAAAACbt+PgAAAAAaknE+AAAAAJugkT4AAAAAQ86fPgAAAAB6Yn0+AAAAAMSFnz4AAAAAG5JxPgAAAAB+2r0+AAAAAMWFnz4AAAAAu3BYPgAAAAC2ZEQ+AAAAAP4LkD4AAAAAetg8PgAAAABp1bM+AAAAAGIzQj4AAAAAedg8PgAAAADvvNc+AAAAAJLZ1z4AAAAAatWzPgAAAADerKk+AAAAAPqTxz4AAAAALEbVPgAAAAB5S8c+AAAAAAHy5z4AAAAAg8PtPgAAAAD5k8c+AAAAALlF5z4AAAAAeEvHPgAAAACEw+0+AAAAAKIokD4AAAAAD42zPgAAAABujwI/AAAAAE3gAz8AAAAAaNWzPgAAAADVIvo+AAAAAGPT1j4AAAAAGQMCPwAAAAAQjbM+AAAAAPrbgD4AAAAAuOl0PgAAAAABmJI+AAAAALlfoD4AAAAAtC+APgAAAAA5F6A+AAAAALnpdD4AAAAAs5C9PgAAAAC4X6A+AAAAAMiNXD4AAAAAYgxJPgAAAAAuEpE+AAAAAP+uQT4AAAAAatWzPgAAAAAQ20Y+AAAAAACvQT4AAAAAv7bWPgAAAACr9qk+AAAAAIYCxz4AAAAAxk7UPgAAAAAHusY+AAAAAIpz5j4AAAAAuBfsPgAAAABFx+U+AAAAAAa6xj4AAAAA0i6RPgAAAAAPjbM+AAAAAINlAT8AAAAAwLbWPgAAAACsqgI/AAAAAFAU+D4AAAAANc3VPgAAAAAu2QA/AAAAABCNsz4AAAAAcVqCPgAAAABVQXg+AAAAAGSPkz4AAAAALfGgPgAAAAArroE+AAAAAK6ooD4AAAAA50a9PgAAAAAu8aA+AAAAANeqYD4AAAAADbRNPgAAAABdGJI+AAAAAIeFRj4AAAAAatWzPgAAAAC7gks+AAAAAJCw1T4AAAAAM83VPgAAAAB2QKo+AAAAABFxxj4AAAAAYFfTPgAAAACSKMY+AAAAABH15D4AAAAA52vqPgAAAAAQccY+AAAAAMxI5D4AAAAAkSjGPgAAAADma+o+AAAAAFwYkj4AAAAAADWSPgAAAABp1bM+AAAAABGNsz4AAAAAmTsAPwAAAACRsNU+AAAAAAp1AT8AAAAAxwX2PgAAAAAEx9Q+AAAAAIVe/z4AAAAAEI2zPgAAAAALdQE/AAAAAOfYgz4AAAAA8Zh7PgAAAADKhpQ+AAAAAKCCoT4AAAAAoiyDPgAAAAAiOqE+AAAAAPKYez4AAAAAG/28PgAAAAAhOqE+AAAAAObHZD4AAAAAuVtSPgAAAACMHpM+AAAAAAxcSz4AAAAAadWzPgAAAABlKlA+AAAAAA1cSz4AAAAAYKrUPgAAAAAFx9Q+AAAAAGrVsz4AAAAAD42zPgAAAABBiqo+AAAAAJzfxT4AAAAA/F/SPgAAAAAel8U+AAAAAJt24z4AAAAAGcDoPgAAAACd38U+AAAAAFXK4j4AAAAAMDuTPgAAAAAPjbM+AAAAAFoj/j4AAAAAaT8APwAAAAA/9/M+AAAAANXA0z4AAAAAsQr9PgAAAABoPwA/AAAAAF5XhT4AAAAAjvB+PgAAAAAwfpU+AAAAABQUoj4AAAAAF6uEPgAAAACUy6E+AAAAAI/wfj4AAAAAULO8PgAAAAAVFKI+AAAAAJPLoT4AAAAA9ORoPgAAAABlA1c+AAAAALsklD4AAAAAkzJQPgAAAABq1bM+AAAAABHSVD4AAAAAM6TTPgAAAADWwNM+AAAAAGnVsz4AAAAADdSqPgAAAAAqTsU+AAAAAJlo0T4AAAAAqgXFPgAAAAAk+OE+AAAAAEsU5z4AAAAAKU7FPgAAAADeS+E+AAAAAKsFxT4AAAAAvCSUPgAAAABgQZQ+AAAAABCNsz4AAAAAhc/7PgAAAAAypNM+AAAAAI0T/j4AAAAAuOjxPgAAAAClutI+AAAAANu2+j4AAAAAD42zPgAAAADV1YY+AAAAABYkgT4AAAAAknWWPgAAAACIpaI+AAAAAJEphj4AAAAACF2iPgAAAAAVJIE+AAAAAIVpvD4AAAAACV2iPgAAAAAEAm0+AAAAABCrWz4AAAAA7CqVPgAAAAAZCVU+AAAAAGrVsz4AAAAAv3lZPgAAAAACntI+AAAAAKa60j4AAAAAa9WzPgAAAADZHas+AAAAALa8xD4AAAAAM3HQPgAAAAA3dMQ+AAAAAK554D4AAAAAfGjlPgAAAAC1vMQ+AAAAAGrN3z4AAAAAj0eVPgAAAAARjbM+AAAAAK17+T4AAAAASaj7PgAAAAAx2u8+AAAAAHe00T4AAAAABWP4PgAAAABNVIg+AAAAAOTPgj4AAAAA+WyXPgAAAAD8NqM+AAAAAAeohz4AAAAAfu6iPgAAAAC7H7w+AAAAAPs2oz4AAAAAfe6iPgAAAAASH3E+AAAAAL5SYD4AAAAAGjGWPgAAAACh31k+AAAAAGrVsz4AAAAAayFePgAAAAAQjbM+AAAAANOX0T4AAAAApWerPgAAAABCK8Q+AAAAANB5zz4AAAAAwuLDPgAAAAA3+94+AAAAAK684z4AAAAA8k7ePgAAAADD4sM+AAAAAK284z4AAAAAGzGWPgAAAAC+TZY+AAAAAGnVsz4AAAAAEI2zPgAAAADZJ/c+AAAAAAc9+T4AAAAAqMvtPgAAAABHrtA+AAAAAC8P9j4AAAAACD35PgAAAADD0ok+AAAAALR7hD4AAAAAW2SYPgAAAABvyKM+AAAAAH0miT4AAAAA8H+jPgAAAADv1bs+AAAAAPF/oz4AAAAAIjx1PgAAAABp+mQ+AAAAAEo3lz4AAAAAJrZePgAAAABp1bM+AAAAABbJYj4AAAAAD42zPgAAAACkkdA+AAAAAEiu0D4AAAAAaNWzPgAAAABwsas+AAAAAM6Zwz4AAAAAaYLOPgAAAABOUcM+AAAAAMB83T4AAAAA3RDiPgAAAADNmcM+AAAAAHnQ3D4AAAAA3hDiPgAAAABJN5c+AAAAAO5Tlz4AAAAAEY2zPgAAAAAB1PQ+AAAAAKOR0D4AAAAAwtH2PgAAAABq1bM+AAAAACK96z4AAAAAGajPPgAAAABYu/M+AAAAABCNsz4AAAAAw9H2PgAAAAA7UYs+AAAAAIEnhj4AAAAAwVuZPgAAAADkWaQ+AAAAAPOkij4AAAAAYxGkPgAAAACCJ4Y+AAAAACWMuz4AAAAALll5PgAAAAAUomk+AAAAAHk9mD4AAAAArIxjPgAAAABr1bM+AAAAAO1Tlz4AAAAAwXBnPgAAAAB1i88+AAAAABiozz4AAAAAatWzPgAAAAASjbM+AAAAADr7qz4AAAAAWQjDPgAAAAAFi80+AAAAANy/wj4AAAAASf7bPgAAAAAQZeA+AAAAAFoIwz4AAAAAAlLbPgAAAADav8I+AAAAABFl4D4AAAAAHVqYPgAAAAARjbM+AAAAACyA8j4AAAAAdIvPPgAAAACAZvQ+AAAAAJyu6T4AAAAA6aHOPgAAAACDZ/E+AAAAAA+Nsz4AAAAAgWb0PgAAAACyz4w+AAAAAFDThz4AAAAAJVOaPgAAAABX66Q+AAAAAGojjD4AAAAA2aKkPgAAAABR04c+AAAAAFlCuz4AAAAAWOukPgAAAADYoqQ+AAAAAD12fT4AAAAAwUluPgAAAACoQ5k+AAAAADNjaD4AAAAAatWzPgAAAABtGGw+AAAAABKNsz4AAAAARYXOPgAAAADqoc4+AAAAABCNsz4AAAAABkWsPgAAAADldsI+AAAAAKCTzD4AAAAAZy7CPgAAAADVf9o+AAAAAEK53j4AAAAAjNPZPgAAAABmLsI+AAAAAEO53j4AAAAATGCZPgAAAABp1bM+AAAAAA+Nsz4AAAAAVizwPgAAAAA9+/E+AAAAABSg5z4AAAAAupvNPgAAAACuE+8+AAAAACdOjj4AAAAAH3+JPgAAAACLSps+AAAAAMx8pT4AAAAA4qGNPgAAAABNNKU+AAAAAB5/iT4AAAAAjfi6PgAAAADLfKU+AAAAAKfJgD4AAAAAbfFyPgAAAADYSZo+AAAAALk5bT4AAAAAadWzPgAAAABLYJk+AAAAABvAcD4AAAAAEI2zPgAAAAAVf80+AAAAAGrVsz4AAAAA0o6sPgAAAABx5cE+AAAAADqcyz4AAAAA85zBPgAAAABcAdk+AAAAAHUN3T4AAAAAF1XYPgAAAAB8Zpo+AAAAABGNsz4AAAAAgdjtPgAAAAAWf80+AAAAAPuP7z4AAAAAaNWzPgAAAACLkeU+AAAAAIqVzD4AAAAA2L/sPgAAAAAQjbM+AAAAAJ7Mjz4AAAAA7CqLPgAAAADwQZw+AAAAAD8Opj4AAAAAWSCPPgAAAADCxaU+AAAAAMCuuj4AAAAAwcWlPgAAAAAt2II+AAAAABiZdz4AAAAABlCbPgAAAABAEHI+AAAAAGnVsz4AAAAAe2aaPgAAAADHZ3U+AAAAAOZ4zD4AAAAAndisPgAAAAD9U8E+AAAAANakyj4AAAAAgAvBPgAAAADkgtc+AAAAAKRh2z4AAAAAn9bWPgAAAAB/C8E+AAAAAKVh2z4AAAAAB1CbPgAAAACqbJs+AAAAAGrVsz4AAAAADo2zPgAAAACphOs+AAAAALck7T4AAAAABIPjPgAAAABaj8s+AAAAAABs6j4AAAAAD42zPgAAAAAVS5E+AAAAALzWjD4AAAAAVTmdPgAAAAC0n6Y+AAAAANCekD4AAAAANFemPgAAAAD3ZLo+AAAAALTmhD4AAAAAxEB8PgAAAAA2Vpw+AAAAAMbmdj4AAAAAaNWzPgAAAAByD3o+AAAAAMXmdj4AAAAAt3LLPgAAAABp1bM+AAAAAGgirT4AAAAAicLAPgAAAABxrck+AAAAAAh6wD4AAAAAbgTWPgAAAADWtdk+AAAAAIrCwD4AAAAAKVjVPgAAAADVtdk+AAAAANpynD4AAAAAD42zPgAAAADUMOk+AAAAALZyyz4AAAAAc7nqPgAAAAB+dOE+AAAAACyJyj4AAAAAKhjoPgAAAAAQjbM+AAAAAIzJkj4AAAAAioKOPgAAAAC5MJ4+AAAAACgxpz4AAAAARh2SPgAAAACo6KY+AAAAAIuCjj4AAAAAKhu6PgAAAAA89YY+AAAAADh0gD4AAAAAZVydPgAAAABLvXs+AAAAAGrVsz4AAAAA2XKcPgAAAAAdt34+AAAAAEy9ez4AAAAAh2zKPgAAAABp1bM+AAAAADRsrT4AAAAAFjHAPgAAAAALtsg+AAAAAJfovz4AAAAA+IXUPgAAAAAJCtg+AAAAALHZ0z4AAAAACArYPgAAAAAJeZ0+AAAAABCNsz4AAAAAAN3mPgAAAACIbMo+AAAAADJO6D4AAAAA9mXfPgAAAAD8gsk+AAAAAFbE5T4AAAAAEY2zPgAAAAADSJQ+AAAAAFgukD4AAAAAICifPgAAAACcwqc+AAAAAL2bkz4AAAAAHXqnPgAAAABd0bk+AAAAAB56pz4AAAAAxAOJPgAAAAAPyII+AAAAAJRinj4AAAAA6UmAPgAAAABo1bM+AAAAAAh5nT4AAAAAZa+BPgAAAADqSYA+AAAAAFhmyT4AAAAA/rWtPgAAAACin78+AAAAAKm+xz4AAAAAIle/PgAAAACBB9M+AAAAADhe1j4AAAAAPFvSPgAAAAA4f54+AAAAAGnVsz4AAAAADo2zPgAAAAAnieQ+AAAAAO7i5T4AAAAAb1fdPgAAAADNfMg+AAAAAH5w4z4AAAAAecaVPgAAAAAn2pE+AAAAAIUfoD4AAAAAEFSoPgAAAAA0GpU+AAAAAJILqD4AAAAAJtqRPgAAAACUh7k+AAAAAJELqD4AAAAAShKLPgAAAADkG4U+AAAAAMRonz4AAAAALLWCPgAAAABo1bM+AAAAADsDhD4AAAAAKWDIPgAAAABp1bM+AAAAAMz/rT4AAAAALg6/PgAAAABBx8Y+AAAAALHFvj4AAAAAConRPgAAAABrstQ+AAAAAC8Ovz4AAAAAxNzQPgAAAACwxb4+AAAAAGqy1D4AAAAAZ4WfPgAAAAAQjbM+AAAAAFI14j4AAAAAq3fjPgAAAADoSNs+AAAAAJ12xz4AAAAAqRzhPgAAAACqd+M+AAAAAPJElz4AAAAA94WTPgAAAADoFqE+AAAAAIPlqD4AAAAAqpiWPgAAAAAGnag+AAAAAPaFkz4AAAAAxz25PgAAAAAFnag+AAAAANIgjT4AAAAAu2+HPgAAAADzbqA+AAAAAHAghT4AAAAAadWzPgAAAAARV4Y+AAAAAPtZxz4AAAAAatWzPgAAAAARjbM+AAAAAJZJrj4AAAAAu3y+PgAAAADez8U+AAAAADk0vj4AAAAAkwrQPgAAAACcBtM+AAAAALp8vj4AAAAATV7PPgAAAAA6NL4+AAAAAPRuoD4AAAAAl4ugPgAAAAAQjbM+AAAAAHzh3z4AAAAA+lnHPgAAAABoDOE+AAAAAF062T4AAAAAbnDGPgAAAADTyN4+AAAAAA+Nsz4AAAAAaMOYPgAAAADDMZU+AAAAAEwOoj4AAAAA+HapPgAAAAAhF5g+AAAAAHcuqT4AAAAA/PO4PgAAAAB4Lqk+AAAAAFovjz4AAAAAkcOJPgAAAAAidaE+AAAAALOLhz4AAAAAadWzPgAAAADmqog+AAAAALKLhz4AAAAAyVPGPgAAAABtcMY+AAAAAGGTrj4AAAAAROu9PgAAAAB32MQ+AAAAAMaivT4AAAAAGIzOPgAAAADFWtE+AAAAAEXrvT4AAAAAz9/NPgAAAADEor0+AAAAAMZa0T4AAAAAI3WhPgAAAADHkaE+AAAAAA+Nsz4AAAAAno3dPgAAAAAXod4+AAAAAMor1z4AAAAAOWrFPgAAAADrdNw+AAAAABWh3j4AAAAA40GaPgAAAACU3ZY+AAAAALAFoz4AAAAAbAiqPgAAAACalZk+AAAAAOu/qT4AAAAAld2WPgAAAAAvqrg+AAAAAG0Iqj4AAAAA6r+pPgAAAADqPZE+AAAAAG4XjD4AAAAAVXuiPgAAAAD89ok+AAAAAGnVsz4AAAAAxZGhPgAAAADA/oo+AAAAAPv2iT4AAAAAlU3FPgAAAABo1bM+AAAAAA6Nsz4AAAAALt2uPgAAAADRWb0+AAAAABLhwz4AAAAAUhG9PgAAAACeDc0+AAAAAPquzz4AAAAA0lm9PgAAAABcYcw+AAAAAFZ7oj4AAAAA+JeiPgAAAAARjbM+AAAAAL852z4AAAAAlE3FPgAAAADUNdw+AAAAAFQd1T4AAAAAD2TEPgAAAAAhIdo+AAAAANM13D4AAAAAWMCbPgAAAABmiZg+AAAAABn9oz4AAAAA4ZmqPgAAAAAVFJs+AAAAAGNRqj4AAAAAZWC4PgAAAADgmao+AAAAAHBMkz4AAAAASGuOPgAAAACFgaM+AAAAAEZijD4AAAAAatWzPgAAAAD5l6I+AAAAAJ9SjT4AAAAAEI2zPgAAAABtR8Q+AAAAAA5kxD4AAAAAa9WzPgAAAAD7Jq8+AAAAAGHIvD4AAAAAtOnCPgAAAADgf7w+AAAAADOPyz4AAAAANQPOPgAAAABgyLw+AAAAAO3iyj4AAAAA4n+8PgAAAACGgaM+AAAAACaeoz4AAAAAE42zPgAAAAAD5tg+AAAAAGxHxD4AAAAAqsrZPgAAAADTDtM+AAAAAORdwz4AAAAAXc3XPgAAAADMPp0+AAAAADA1mj4AAAAAe/SkPgAAAABUK6s+AAAAAImSnD4AAAAA1uKqPgAAAACdFrg+AAAAANTiqj4AAAAA7FqVPgAAAAATv5A+AAAAAK+HpD4AAAAAgM2OPgAAAABs1bM+AAAAACieoz4AAAAAcaaPPgAAAAARjbM+AAAAAD9Bwz4AAAAA413DPgAAAAASjbM+AAAAAMRwrz4AAAAA6za8PgAAAABK8sE+AAAAAGnuuz4AAAAAuhDKPgAAAABjV8w+AAAAAHFkyT4AAAAAau67PgAAAABSpKQ+AAAAAGrVsz4AAAAADo2zPgAAAAAqktY+AAAAAD5Bwz4AAAAAW1/XPgAAAABr1bM+AAAAAD0A0T4AAAAArlfCPgAAAAB0edU+AAAAAA+Nsz4AAAAAXF/XPgAAAABAvZ4+AAAAAPvgmz4AAAAA3uulPgAAAADFvKs+AAAAAPoQnj4AAAAARnSrPgAAAAD84Js+AAAAAM3Mtz4AAAAAxryrPgAAAAB0aZc+AAAAAOISkz4AAAAA3Y2lPgAAAAC4OJE+AAAAAGnVsz4AAAAAOfqRPgAAAAAJO8I+AAAAAGjVsz4AAAAADY2zPgAAAACPuq8+AAAAAHWluz4AAAAA5frAPgAAAAD4XLs+AAAAAD6SyD4AAAAAkavKPgAAAAB2pbs+AAAAAPvlxz4AAAAA+Vy7PgAAAACTq8o+AAAAAIKqpT4AAAAAEY2zPgAAAABHPtQ+AAAAABX01D4AAAAAwPHOPgAAAACDUcE+AAAAAKYl0z4AAAAAEI2zPgAAAAC9O6A+AAAAAM+MnT4AAAAAReOmPgAAAAA9Tqw+AAAAAHOPnz4AAAAAvQWsPgAAAAAFg7c+AAAAADxOrD4AAAAAvAWsPgAAAAAGeJk+AAAAAMRmlT4AAAAAEpSmPgAAAAAHpJM+AAAAAGzVsz4AAAAAFU6UPgAAAAAGpJM+AAAAAOA0wT4AAAAAglHBPgAAAABr1bM+AAAAAF0EsD4AAAAAAxS7PgAAAACDA8A+AAAAAITLuj4AAAAAzBPHPgAAAADH/8g+AAAAAAQUuz4AAAAAhWfGPgAAAACFy7o+AAAAALWwpj4AAAAAEI2zPgAAAAB96tE+AAAAANaI0j4AAAAAMOPMPgAAAABRS8A+AAAAAM3R0D4AAAAA14jSPgAAAAAyuqE+AAAAAJ04nz4AAAAAq9qnPgAAAACv36w+AAAAAO4NoT4AAAAAMZesPgAAAACeOJ8+AAAAADg5tz4AAAAAhIabPgAAAACXupc+AAAAAD6apz4AAAAATA+WPgAAAABp1bM+AAAAAPOhlj4AAAAArC7APgAAAAAmTrA+AAAAAI2Cuj4AAAAAGQy/PgAAAAAOOro+AAAAAFCVxT4AAAAA9FPHPgAAAACMgro+AAAAAArpxD4AAAAA81PHPgAAAADgtqc+AAAAAGrVsz4AAAAADo2zPgAAAACals8+AAAAAKsuwD4AAAAAhh3QPgAAAACj1Mo+AAAAAB9Fvz4AAAAA7n3OPgAAAAANjbM+AAAAAKI4oz4AAAAAY+SgPgAAAAAK0qg+AAAAACFxrT4AAAAAX4yiPgAAAACkKK0+AAAAAGvvtj4AAAAAAZWdPgAAAABaDpo+AAAAAGigqD4AAAAAe3qYPgAAAABm1bM+AAAAAN+2pz4AAAAAuPWYPgAAAAAQjbM+AAAAAHoovz4AAAAAHkW/PgAAAADvl7A+AAAAABjxuT4AAAAAthS+PgAAAACaqLk+AAAAANgWxD4AAAAAJKjFPgAAAAAX8bk+AAAAAJRqwz4AAAAAaaCoPgAAAAAPvag+AAAAAA+Nsz4AAAAAwELNPgAAAABAss0+AAAAACTGyD4AAAAA8T6+PgAAAAAaKsw+AAAAAA6Nsz4AAAAAQbLNPgAAAAAht6Q+AAAAADmQoj4AAAAAdMmpPgAAAACaAq4+AAAAANYKpD4AAAAAGbqtPgAAAACipbY+AAAAAJkCrj4AAAAAGLqtPgAAAACeo58+AAAAAEhinD4AAAAAoKapPgAAAADL5Zo+AAAAAGrVsz4AAAAAj0mbPgAAAABQIr4+AAAAAPI+vj4AAAAAadWzPgAAAADA4bA+AAAAAKlfuT4AAAAAVR29PgAAAAApF7k+AAAAAGiYwj4AAAAAYPzDPgAAAAAn7ME+AAAAAEXDqT4AAAAAFI2zPgAAAAD87so+AAAAABtHyz4AAAAAtLfGPgAAAADLOL0+AAAAAGTWyT4AAAAAlzWmPgAAAAALPKQ+AAAAANrAqj4AAAAADZSuPgAAAABUiaU+AAAAAI9Lrj4AAAAA2lu2PgAAAACQS64+AAAAABmyoT4AAAAAGraePgAAAADNrKo+AAAAABhRnT4AAAAAbdWzPgAAAAB6nZ0+AAAAACkcvT4AAAAAzDi9PgAAAABs1bM+AAAAABONsz4AAAAAiSuxPgAAAAA3zrg+AAAAAPIlvD4AAAAAs4W4PgAAAAD4GcE+AAAAAJJQwj4AAAAANM64PgAAAACsbcA+AAAAALSFuD4AAAAAk1DCPgAAAABvyao+AAAAAA+Nsz4AAAAAOJvIPgAAAAAoHL0+AAAAANjbyD4AAAAAGKnEPgAAAACVMrw+AAAAAICCxz4AAAAAEI2zPgAAAAAItKc+AAAAAM/npT4AAAAAPLirPgAAAAB+Ja8+AAAAAMIHpz4AAAAAAN2uPgAAAAAKErY+AAAAAH0lrz4AAAAA/9yuPgAAAACcwKM+AAAAAOEJoT4AAAAA+rKrPgAAAABJvJ8+AAAAAGnVsz4AAAAAO/GfPgAAAAAOjbM+AAAAAPIVvD4AAAAAaNWzPgAAAABAdbE+AAAAALI8uD4AAAAAPy67PgAAAACr87c+AAAAAGCbvz4AAAAABKTAPgAAAAAL7b4+AAAAAKzztz4AAAAAhc+rPgAAAABIjLM+AAAAAAtHxj4AAAAA8RW8PgAAAACFbsY+AAAAAIOMwj4AAAAAJim7PgAAAAAcKMU+AAAAAEeMsz4AAAAAqTCpPgAAAAACk6c+AAAAABmvrD4AAAAAxbWvPgAAAAAUhqg+AAAAANhtrz4AAAAACsa1PgAAAADEta8+AAAAALvDpT4AAAAAdVijPgAAAABItqw+AAAAAPMloj4AAAAAx9KzPgAAAACEz6s+AAAAAOBEoj4AAAAAKAm7PgAAAABkubE+AAAAAGCktz4AAAAA7yK6PgAAAAAlRrc+AAAAADALvj4AAAAA1Mi+PgAAAABfpLc+AAAAAIgKvT4AAAAAJka3PgAAAADTyL4+AAAAADvMrD4AAAAARmmzPgAAAABzx8M+AAAAACYJuz4AAAAAy4fDPgAAAABoV74+AAAAAA+cuT4AAAAA36/BPgAAAABHabM+AAAAAMyHwz4AAAAAn9+pPgAAAABd66g+AAAAAGh0rT4AAAAAHOuvPgAAAAC07ak+AAAAAPberz4AAAAAXuuoPgAAAAANHbU+AAAAAB3rrz4AAAAA9d6vPgAAAAC46KQ+AAAAAHD9oz4AAAAA4b+sPgAAAAAg8aM+AAAAACBCsz4AAAAAPMysPgAAAACtbaQ+AAAAAGgAuT4AAAAADpy5PgAAAAA60rE+AAAAAGFYtj4AAAAAKQG4PgAAAAA5LLY+AAAAAOl0uj4AAAAAOPm5PgAAAABgWLY+AAAAAP0PuD4AAAAAOfm5PgAAAAC3J68+AAAAAB9Csz4AAAAAt4W0PgAAAAA1X7w+AAAAAGkAuT4AAAAA9Fi5PgAAAABHbLI+AAAAAKQXtj4AAAAAArO1PgAAAAC2hbQ+AAAAAPNYuT4AAAAAmzexPgAAAACxqrQ+AAAAALYLtT4AAAAA1MizPgAAAACKK7U+AAAAAHeTtD4AAAAAsKq0PgAAAADQkbM+AAAAANPIsz4AAAAAdpO0PgAAAAC2J68+AAAAAOgqrj4AAAAAeWKyPgAAAAC7WrA+AAAAAHcQrz4AAAAA5hytPgAAAACsm7I+AAAAAGn3rT4AAAAAl6yvPgAAAACYiLI+AAAAAPjTsj4AAAAAGcaxPgAAAACuTbI+AAAAAGwCsj4AAAAAl4iyPgAAAAAtK7E+AAAAABrGsT4AAAAAM+esPgAAAAB4YrI+AAAAAEZ7sD4AAAAA5RytPgAAAAATm6w+AAAAAKubsj4AAAAALBysPgAAAACkh6o+AAAAANNCsD4AAAAAXlOrPgAAAAAtHKw+AAAAABcfrj4AAAAAcIiwPgAAAACWrLA+AAAAAPHFrz4AAAAAxOuvPgAAAAC4lq8+AAAAAG+IsD4AAAAAQ8muPgAAAAA056w+AAAAAMuhqz4AAAAAEpSuPgAAAADuAao+AAAAACF/qT4AAAAAX/KnPgAAAAD26a0+AAAAADW6qD4AAAAAIn+pPgAAAACTkaw+AAAAAEiIrj4AAAAANIWuPgAAAADJxa0+AAAAANmJrT4AAAAABCutPgAAAABHiK4+AAAAAFlnrD4AAAAAAyutPgAAAABiXKo+AAAAABOUrj4AAAAA4KysPgAAAADDaKc+AAAAABXipj4AAAAAGl2lPgAAAAAbkas+AAAAAAwhpj4AAAAA36ysPgAAAAARBKs+AAAAAB+IrD4AAAAA0V2sPgAAAAChxas+AAAAAPAnqz4AAAAAT7+qPgAAAABvBao+AAAAAGFcqj4AAAAA+xapPgAAAACsxao+AAAAABldpT4AAAAAnM+kPgAAAAAKRaQ+AAAAANjHoj4AAAAAQjipPgAAAADnh6M+AAAAAK3Fqj4AAAAAj3apPgAAAAD2h6o+AAAAAHE2qj4AAAAAesWpPgAAAAAIxqg+AAAAAJxTqD4AAAAA94eqPgAAAACHo6c+AAAAAHnFqT4AAAAA+hapPgAAAACR0ac+AAAAAHreqD4AAAAAdzaiPgAAAABDOKk+AAAAAAGooT4AAAAAmDKgPgAAAABp36Y+AAAAAMLuoD4AAAAAed6oPgAAAAAM6ac+AAAAAM+HqD4AAAAADw+oPgAAAABQxac+AAAAACBkpj4AAAAA6uelPgAAAADOh6g+AAAAAJ1BpT4AAAAA6eelPgAAAAAojKY+AAAAAEX3pj4AAAAAljKgPgAAAABSnZ8+AAAAAPUKnz4AAAAAUZ2dPgAAAACNhqQ+AAAAAJtVnj4AAAAA9gqfPgAAAACJW6Y+AAAAAKWHpj4AAAAAreelPgAAAAAnxaU+AAAAADUCpD4AAAAAM3yjPgAAAACz36I+AAAAACjFpT4AAAAANHyjPgAAAAAnjKY+AAAAAHFEpT4AAAAARvemPgAAAAASEKU+AAAAAFKdnT4AAAAAKASdPgAAAADrbZw+AAAAAA0Imz4AAAAAsi2iPgAAAABxvJs+AAAAADzEpD4AAAAAfYekPgAAAABLwKM+AAAAAGXAoz4AAAAASqChPgAAAACBEKE+AAAAAHyHpD4AAAAANX2gPgAAAABkwKM+AAAAAIIQoT4AAAAAcESlPgAAAABQmaM+AAAAAAMEoz4AAAAAAWuaPgAAAACzLaI+AAAAAN/QmT4AAAAAzHKYPgAAAAA80J8+AAAAAEwjmT4AAAAABASjPgAAAABVwaE+AAAAABAHoj4AAAAA6ICgPgAAAAC3Op8+AAAAAKAWnz4AAAAAar+dPgAAAAAPB6I+AAAAAGdJmz4AAAAAFPCePgAAAACWMJs+AAAAAAO+lz4AAAAAO9CfPgAAAAAQlZY+AAAAACatkj4AAAAAgMOWPgAAAACro5Q+AAAAAA+Vlj4AAAAAAIM2PwAAAACW6zY/AAAAAJKKNj8AAAAAFCU2PwAAAABUUjc/AAAAAF7hNj8AAAAAQoQ1PwAAAABHJjU/AAAAAPisNT8AAAAAYyc2PwAAAABqkDY/AAAAAMYZNj8AAAAAcfk2PwAAAAB4Yjc/AAAAAH7LNz8AAAAAn7k3PwAAAACKPDc/AAAAAGTaNT8AAAAAJ28yPwAAAACeUzM/AAAAAFaKMz8AAAAAtDYzPwAAAADOtzQ/AAAAABDAMj8AAAAAebo1PwAAAAAgWCw/AAAAAP7HLD8AAAAAJloqPwAAAABtuik/AAAAAA4pLT8AAAAAboMqPwAAAAArzCM/AAAAADGVIj8AAAAA9UgjPwAAAADGTiw/AAAAAM23LD8AAAAAKugrPwAAAADUIC0/AAAAANuJLT8AAAAA4PItPwAAAAA2ii0/AAAAAJatKj8AAAAAUJMiPwAAAADqjA4/AAAAAB0uFT8AAAAAZjoXPwAAAADJoRQ/AAAAAAMoIT8AAAAApYUNPwAAAADSGSk/AAAAAKmtRj8AAAAAZxNHPwAAAAD76UQ/AAAAADWbRD8AAAAAr3ZHPwAAAAAIJUU/AAAAAG79Pj8AAAAAHc4+PwAAAADk1z4/AAAAAGqQRj8AAAAAcflGPwAAAACDTEY/AAAAAHZiRz8AAAAAfstHPwAAAACENEg/AAAAAAbcRz8AAAAAkHBFPwAAAAAw3z4/AAAAAOgUMj8AAAAAaYkyPwAAAABsKzM/AAAAAM+GMj8AAAAAci8/PwAAAACKMTI/AAAAADRxRD8AAAAAalFVPwAAAABNwlU/AAAAALH+Uj8AAAAAzFZSPwAAAABXIlY/AAAAAM8fUz8AAAAARYlLPwAAAADLM0o/AAAAAI7nSj8AAAAAV1VVPwAAAABcvlU/AAAAAG7gVD8AAAAAZCdWPwAAAABpkFY/AAAAAHD5Vj8AAAAAe4JWPwAAAADLQVM/AAAAADMMSj8AAAAAnEkzPwAAAABj3To/AAAAAKo7PT8AAAAAD1E6PwAAAADooEg/AAAAAFdCMj8AAAAABq5RPwAAAACnHo4+AAAAAEjsjj4AAAAAAACQPgAAAAA/UY8+AAAAAHvAjz4AAAAAQeOQPgAAAADw55I+AAAAADKWkj4AAAAAuf2TPgAAAADTII0+AAAAANfyjT4AAAAA0VCNPgAAAADbxI4+AAAAAOSWjz4AAAAA8GiQPgAAAADmlJA+AAAAAETIkT4AAAAAeC6VPgAAAAAOlZ0+AAAAAGsOmj4AAAAAiXqYPgAAAADB9Zg+AAAAAORXkj4AAAAAhYabPgAAAADBoI4+AAAAAJ9KRz4AAAAAUN5IPgAAAADbgk0+AAAAAAhiTD4AAAAATY5KPgAAAAAPhk8+AAAAAAYKWj4AAAAAFUlaPgAAAAAnGF0+AAAAAFHsRD4AAAAAbJBGPgAAAAB9tkU+AAAAAIc0SD4AAAAAnthJPgAAAAC4fEs+AAAAALs+TD4AAAAAxYxRPgAAAADHkWA+AAAAAC7Ygj4AAAAAGJl3PgAAAAA+EHI+AAAAAMdndT4AAAAAn+RaPgAAAACmyYA+AAAAALU9Sz4AAAAAJETZPgAAAAB+GNo+AAAAAJD42D4AAAAAIRTYPgAAAAD85do+AAAAACWm2T4AAAAAkO/VPgAAAABr1dQ+AAAAAPM81j4AAAAAfJ3YPgAAAACLb9k+AAAAAJJv2D4AAAAAmUHaPgAAAACpE9s+AAAAALjl2z4AAAAAtbPbPgAAAAB7Vdo+AAAAAOF11j4AAAAANuPMPgAAAACils8+AAAAAJId0D4AAAAA+X3OPgAAAABMn9M+AAAAAK7Uyj4AAAAA8i3XPgAAAABjZnY/AAAAAMDQdj8AAAAA6bN1PwAAAAAnQHU/AAAAAP43dz8AAAAAnw52PwAAAADHrnI/AAAAAIshcj8AAAAAf+dyPwAAAABkJ3Y/AAAAAGqQdj8AAAAA/ft1PwAAAABx+XY/AAAAAHhidz8AAAAAfst3PwAAAABAn3c/AAAAAINpdj8AAAAA1CBzPwAAAACxu2w/AAAAALfDbD8AAAAAMc1sPwAAAABaDmw/AAAAALSTcT8AAAAADE5rPwAAAAA5zHQ/AAAAAMPeAT8AAAAA1koCPwAAAACTGwE/AAAAADCaAD8AAAAAr68CPwAAAAAzYwE/AAAAAIDS+z4AAAAAEkf6PgAAAACcrvs+AAAAABukAT8AAAAAIg0CPwAAAACVcgE/AAAAACl2Aj8AAAAAL98CPwAAAAA2SAM/AAAAAKYUAz8AAAAAsasBPwAAAAB3W/s+AAAAABag5z4AAAAAgdjtPgAAAAD6j+8+AAAAANe/7D4AAAAA34T4PgAAAACLkeU+AAAAAO0XAD8AAAAAqDm3PAAAAABIIMM8AAAAAOA4CT0AAAAAR5EHPQAAAADrA9E8AAAAAI3UEj0AAAAAqwJ0PQAAAADI2H89AAAAAEQzgz0AAAAA2omdPAAAAACsqqo8AAAAAOY7qzwAAAAAf8u3PAAAAABS7MQ8AAAAACIN0jwAAAAAnAHfPAAAAAB52Bw9AAAAAJacjj0AAAAA0Z8WPgAAAAAB8vM9AAAAAM/Q3z0AAAAASj/0PQAAAACN9Ic9AAAAABqAJD4AAAAAGI0FPQAAAABPPEU/AAAAAK+eRT8AAAAA5MBEPwAAAAAdjUQ/AAAAAMb1RT8AAAAAcppEPwAAAADBe0I/AAAAADG0Qj8AAAAAVAlBPwAAAABQ7EQ/AAAAAFZVRT8AAAAAo9NEPwAAAABevkU/AAAAAGMnRj8AAAAAiAM7PwAAAAB4eT4/AAAAAGkoPz8AAAAAD1JCPwAAAAAJwT4/AAAAAOcmRD8AAAAAo85lPwAAAADLKWY/AAAAANM8Yz8AAAAAA/piPwAAAABsf2Y/AAAAAIclYz8AAAAAYFJbPwAAAAD7S1s/AAAAAM/9WT8AAAAAYOFlPwAAAAApNmY/AAAAADx7ZT8AAAAAypRmPwAAAAD8+WY/AAAAAHdiZz8AAAAANd1mPwAAAAB0OGM/AAAAAIvnWD8AAAAAxGg/PwAAAABMHEg/AAAAAM4ITD8AAAAAe1tMPwAAAAChG1s/AAAAAIBYTD8AAAAAQ7BiPwAAAAA/pL49AAAAAAmUwT0AAAAA7BzYPQAAAAAWmNc9AAAAAFEUxT0AAAAAwSXdPQAAAAB/ZQo+AAAAAHfwDT4AAAAAUW8PPgAAAAB/y7c9AAAAALQTuz0AAAAAAK67PQAAAADnW749AAAAAB6kwT0AAAAAT+zEPQAAAADLm8g9AAAAAClo4j0AAAAAhLkVPgAAAADO+28+AAAAAIKMTz4AAAAApkBEPgAAAAAD/k8+AAAAAMeuEj4AAAAAdhmAPgAAAACD39Y9AAAAAOf6LT8AAAAA3m4uPwAAAABsFCw/AAAAAOBTKz8AAAAARdguPwAAAAB+gCw/AAAAABq2JT8AAAAAexQkPwAAAAAfJSY/AAAAAOZbLj8AAAAA7cQuPwAAAAD0LS8/AAAAAPuWLz8AAAAAfD4vPwAAAAAG0yw/AAAAAKZBJj8AAAAAX3cZPwAAAAAexxk/AAAAANFnGT8AAAAAreoVPwAAAABL2oo+AAAAAKWniz4AAAAA0tOMPgAAAABnJ4w+AAAAAB58jD4AAAAAabmNPgAAAADe/Y8+AAAAANa0jz4AAAAAXxyRPgAAAAC22Ik+AAAAAMWqij4AAAAAvQyKPgAAAADNfIs+AAAAANJOjD4AAAAAk7qXPgAAAABFD5Y+AAAAAOuhlj4AAAAAT4GPPgAAAAD/d5k+AAAAADx5iz4AAAAA8ZZDPwAAAACmAkQ/AAAAAFxdQz8AAAAA6d5CPwAAAACMa0Q/AAAAAFTFQz8AAAAA8p1BPwAAAADk50A/AAAAAFECQj8AAAAANUhDPwAAAAA8sUM/AAAAACEsQz8AAAAARBpEPwAAAABLg0Q/AAAAAMyUPj8AAAAAyTw+PwAAAAAOED0/AAAAAA47QD8AAAAArts6PwAAAACUZ0I/AAAAAMrBQD4AAAAA5lRCPgAAAAB1Kkc+AAAAAE0ORj4AAAAAeQVEPgAAAABVMkk+AAAAAOM1VD4AAAAAXYZUPgAAAABvVVc+AAAAAOdbPj4AAAAAAgBAPgAAAAA+Lj8+AAAAABukQT4AAAAAN0hDPgAAAABt8XI+AAAAALg5bT4AAAAAG8BwPgAAAAByN1U+AAAAAD92fT4AAAAAp+5EPgAAAABH3jQ/AAAAAI1INT8AAAAACO80PwAAAAAJfDQ/AAAAAFmxNT8AAAAASFY1PwAAAACm/DM/AAAAAG5vMz8AAAAALF80PwAAAABIgzQ/AAAAAE7sND8AAAAAenQ0PwAAAABWVTU/AAAAAFy+NT8AAAAAVH4yPwAAAACWJzI/AAAAAIlhMT8AAAAAaOcyPwAAAAA1EjA/AAAAANcMND8AAAAAsjMvPwAAAAAhYCw/AAAAALU3Kj8AAAAAQOAsPwAAAAC08yM/AAAAABXpIT8AAAAAilQkPwAAAAAWjyY/AAAAAIM9HD8AAAAAwogvPwAAAAAMryw/AAAAAF4+JD8AAAAAOGsTPwAAAAD6JhM/AAAAAExJET8AAAAA4OcLPwAAAADwqvs+AAAAADC1ED8AAAAAdLYYPwAAAAD7PBo/AAAAAJKI3D4AAAAAN13dPgAAAADCJNw+AAAAAP492z4AAAAAbSrePgAAAAAG0Nw+AAAAAKPZ2D4AAAAAx7bXPgAAAABQHtk+AAAAAMq33D4AAAAA24ndPgAAAADsW94+AAAAAPst3z4AAAAA2ffePgAAAAAFfd0+AAAAAHZM2T4AAAAAvfHOPgAAAAB46tE+AAAAANSI0j4AAAAAz9HQPgAAAAAGSEg/AAAAAAG0SD8AAAAAB3JGPwAAAABk8UU/AAAAAKAZST8AAAAA279GPwAAAAA9UUA/AAAAAIWYPz8AAAAAdl5APwAAAACLnUg/AAAAAJEGST8AAAAAmW9JPwAAAACe2Ek/AAAAAEh/ST8AAAAA3Q1HPwAAAABRbEA/AAAAAI+CMz8AAAAAqvEzPwAAAAA4YjQ/AAAAAEw8Mz8AAAAAR710PwAAAABoK3U/AAAAAOMFdD8AAAAADXRzPwAAAABylHU/AAAAAA9vdD8AAAAAeutwPwAAAABU8G8/AAAAAPpScT8AAAAASYN0PwAAAABR7HQ/AAAAAL5QdD8AAAAAVlV1PwAAAABdvnU/AAAAACtGaz8AAAAABuxqPwAAAACEEWk/AAAAADYFbz8AAAAAiFllPwAAAADw7nI/AAAAAPiAAz8AAAAAMO0DPwAAAACssQI/AAAAAB4vAj8AAAAA5VEEPwAAAAAg+AI/AAAAAJG8/j4AAAAAcCj9PgAAAAD4j/4+AAAAADyxAz8AAAAAQxoEPwAAAABKgwQ/AAAAAFDsBD8AAAAAtbYEPwAAAAB2PwM/AAAAAAoy/j4AAAAAnq7pPgAAAABWLPA+AAAAAD378T4AAAAArhPvPgAAAABE9FY/AAAAAMdpVz8AAAAAvL1UPwAAAADZ8FM/AAAAAEbTVz8AAAAAkCpVPwAAAACZgk0/AAAAAAG1Sz8AAAAAnfNNPwAAAAB4Ylc/AAAAAH7LVz8AAAAAhjRYPwAAAACMnVg/AAAAACM5WD8AAAAAS3pVPwAAAACSBk4/AAAAAIiDPz8AAAAAa+o/PwAAAADCiT8/AAAAAAieOz8AAAAAJcEVPwAAAABONxY/AAAAALamFj8AAAAAoNQVPwAAAAC+pxY/AAAAAApLFz8AAAAAEfMXPwAAAACjRhY/AAAAACgVGT8AAAAAVlUVPwAAAABdvhU/AAAAAC1HFT8AAAAAZCcWPwAAAABqkBY/AAAAAHH5Fj8AAAAAhBIXPwAAAAACwhc/AAAAAHDGGT8AAAAAyC0gPwAAAAA/xRw/AAAAAIIRGz8AAAAA3egYPwAAAABwyRM/AAAAAPwPET8AAAAAC+QUPwAAAACRbIo9AAAAAOdsjT0AAAAA33qmPQAAAAClcaU9AAAAADUIkT0AAAAA1lusPQAAAAB3DOo9AAAAAPcY8D0AAAAA3pD3PQAAAAA1SIM9AAAAAGqQhj0AAAAAPnOHPQAAAACe2Ik9AAAAANMgjT0AAAAACGmQPQAAAAA6nZQ9AAAAAJcKsj0AAAAAXxMEPgAAAAA4f4M+AAAAAHE1RT4AAAAASbY1PgAAAABEqUE+AAAAALJ7+j0AAAAAkMGCPgAAAAB2oKQ9AAAAAMFdHD8AAAAAt8QcPwAAAAAiHx0/AAAAAJ/GHD8AAAAACi4dPwAAAACEih0/AAAAAEISHj8AAAAAz+QdPwAAAAAqhx4/AAAAAL7lGz8AAAAAx04cPwAAAACa9hs/AAAAAMy3HD8AAAAA0yAdPwAAAADaiR0/AAAAAKOXHT8AAAAAIfgdPwAAAABUCR8/AAAAAIKsIT8AAAAAtnQgPwAAAAD53x8/AAAAALsIID8AAAAALMEdPwAAAACLdyE/AAAAAJlsHD8AAAAAc3J9PAAAAACZl408AAAAAEvD1TwAAAAAFba6PAAAAACZ8Zw8AAAAAJCt9DwAAAAAVNJNPQAAAACQlzI9AAAAALW7cj0AAAAAIg1SPAAAAADHTmw8AAAAAEtTXzwAAAAANkiDPAAAAAAHaZA8AAAAAJvI7j0AAAAAUsLJPQAAAAC2wbc9AAAAALTUED0AAAAAAbCZPQAAAAA4H548AAAAANeVhz4AAAAA6WKIPgAAAACdp4k+AAAAAIb9iD4AAAAAuDeJPgAAAACMj4o+AAAAAMsTjT4AAAAAetOMPgAAAAACO44+AAAAAF2Qhj4AAAAAcmKHPgAAAACOyIY+AAAAAIk0iD4AAAAAogaJPgAAAAC9ZpU+AAAAAAKkkz4AAAAAFE6UPgAAAAC4qow+AAAAAHZplz4AAAAArlGIPgAAAAA3DyM/AAAAANFuIz8AAAAAGn0kPwAAAAB6XyQ/AAAAANjOIz8AAAAAJJ4kPwAAAAC+aCc/AAAAALb9Jz8AAAAAXA4nPwAAAAAodiI/AAAAAC7fIj8AAAAAj6siPwAAAAA1SCM/AAAAADuxIz8AAAAAQRokPwAAAAByJiQ/AAAAALl7JD8AAAAAhKglPwAAAADO2iw/AAAAADAlLT8AAAAAmF8tPwAAAACEDy8/AAAAADhlKD8AAAAA/z01PwAAAABjISQ/AAAAALNznz4AAAAAWPefPgAAAAA4+KM+AAAAAAFFoz4AAAAAZqegPgAAAAD9uaQ+AAAAAMZOpT4AAAAABpmkPgAAAADPCqY+AAAAAJt5mD4AAAAA4/aXPgAAAAB8Mp8+AAAAAG8RmD4AAAAA05SYPgAAAAChTJk+AAAAANptoT4AAAAAgoSlPgAAAAA6zqY+AAAAAKOIpj4AAAAAhdelPgAAAABbMaU+AAAAADaRpD4AAAAAwOujPgAAAABCGqQ+AAAAAC6moj4AAAAA+Tg6PgAAAAB+yzs+AAAAAA/SQD4AAAAAk7o/PgAAAACmfD0+AAAAAJveQj4AAAAAvGFOPgAAAACmw04+AAAAALeSUT4AAAAAfcs3PgAAAACYbzk+AAAAAACmOD4AAAAAshM7PgAAAADNtzw+AAAAAMFJbj4AAAAAM2NoPgAAAABuGGw+AAAAAEeKTz4AAAAAMFl5PgAAAACWnz4+AAAAACAx8T4AAAAAM+2wPgAAAAAJzK4+AAAAAN4q7j4AAAAAjk5hPgAAAABtul4+AAAAANvZqD4AAAAA7HnlPgAAAAAKsFc+AAAAALuf8T4AAAAAFTuxPgAAAADbrGE+AAAAAOV+7j0AAAAAhSLuPQAAAADXm+s9AAAAAI/A5D0AAAAAXWbXPQAAAACCxEk+AAAAABlvnD4AAAAAkbDRPgAAAAAAzd8+AAAAAO+h4D4AAAAA9lDfPgAAAADdZ94+AAAAANVu4T4AAAAA4PnfPgAAAAC3w9s+AAAAACSY2j4AAAAArv/bPgAAAAAJAOA+AAAAABXS4D4AAAAAIKThPgAAAAAoduI+AAAAAPU74j4AAAAAiqTgPgAAAAALI9w+AAAAAEQA0T4AAAAATj7UPgAAAAAZ9NQ+AAAAAKcl0z4AAAAAprSfPgAAAAC9eJ8+AAAAAFKtoT4AAAAAnkahPgAAAADlPp8+AAAAAJwfoj4AAAAAgbGiPgAAAADRR6I+AAAAADVFoz4AAAAALDyePgAAAABH/Zw+AAAAAN7Fnz4AAAAA1lebPgAAAADss5k+AAAAAICpoz4AAAAAnzSjPgAAAACNG6M+AAAAANgFoj4AAAAAFEGlPgAAAACs16A+AAAAAC0jBT8AAAAAio8FPwAAAADGRwQ/AAAAAA7EAz8AAAAAGfQFPwAAAAAQjQQ/AAAAAFLTAD8AAAAA5QQAPwAAAACquAA/AAAAAFdVBT8AAAAAXL4FPwAAAABlJwY/AAAAAGqQBj8AAAAAw1gGPwAAAAA40wQ/AAAAAFCEAD8AAAAAJL3rPgAAAAArgPI+AAAAAIBm9D4AAAAAg2fxPgAAAAB290E/AAAAAPpfQj8AAAAAr8RBPwAAAAC7X0E/AAAAAJ/FQj8AAAAAqRJCPwAAAAClIEA/AAAAABfEPz8AAAAA8ylAPwAAAAAapEE/AAAAACINQj8AAAAA/I1BPwAAAAApdkI/AAAAADDfQj8AAAAAVHA8PwAAAAAK9jw/AAAAAGCjPD8AAAAAxk4/PwAAAAA0HDw/AAAAAB/zQD8AAAAAFlBnPwAAAAAlx2c/AAAAAIDJZD8AAAAARfBjPwAAAAC8MGg/AAAAABk3ZT8AAAAAjrFcPwAAAAD/t1o/AAAAAI4kXT8AAAAAfctnPwAAAACDNGg/AAAAAIudaD8AAAAAkgZpPwAAAABAlmg/AAAAAASEZT8AAAAA9S1dPwAAAAAm8kw/AAAAAC5wTT8AAAAAJg5NPwAAAADas0g/AAAAAEM4oj4AAAAAogKjPgAAAADbH6c+AAAAAF5Spj4AAAAAs8yjPgAAAADq6qc+AAAAAANjqD4AAAAAPZmnPgAAAACVJKk+AAAAACwNmj4AAAAAtc2aPgAAAABBjps+AAAAAM1OnD4AAAAAzpakPgAAAABXtqg+AAAAAGLnqT4AAAAA7WOpPgAAAABetag+AAAAALoJqD4AAAAAo0qnPgAAAAAOuzg/AAAAAOhFNT8AAAAA4Nk0PwAAAAAPGjg/AAAAAPRAND8AAAAAO+AzPwAAAACuuzM/AAAAAJ1sNj8AAAAABtkyPwAAAAAAAEA/AAAAAA/SOD8AAAAA2uE/PwAAAABXVTU/AAAAAMdOND8AAAAA8tswPwAAAADgsTE/AAAAAONYMz8AAAAAOcQ8PwAAAADccTc/AAAAAMsOPz8AAAAABIlPPQAAAAAibZE8AAAAAJvhkDwAAAAAzLdNPQAAAAAHVNk7AAAAAOl92jsAAAAAWXiPPAAAAAAhykg9AAAAABY73jsAAAAAc8tPPQAAAAAFgZE8AAAAAFwp2TsAAAAAAA3SOwAAAAAVDdI7AAAAAB8N0jsAAAAAIw3SOwAAAAAiDdI7AAAAAHpQ6TsAAAAARBGNPAAAAAC2Nj89AAAAAE/rST8AAAAAUVdKPwAAAADPD0g/AAAAAO6ORz8AAAAA6bxKPwAAAABlXUg/AAAAAAHgQT8AAAAAdiZBPwAAAABq7EE/AAAAAKdBSj8AAAAArapKPwAAAACyE0s/AAAAALd8Sz8AAAAAhyJLPwAAAAAnq0g/AAAAAHL5QT8AAAAANPA0PwAAAABBYTU/AAAAAMPTNT8AAAAA5as0PwAAAADqpFg/AAAAAM8MWT8AAAAARVlWPwAAAABc+VU/AAAAAFFoWT8AAAAALFZWPwAAAAA0Ck8/AAAAALe6Tj8AAAAAivJNPwAAAACSBlk/AAAAAJlvWT8AAAAAoNhZPwAAAACmQVo/AAAAAKDHWT8AAAAAfXFWPwAAAAAu/0w/AAAAAI6mNT8AAAAAHJA9PwAAAACA7EA/AAAAAMyiQD8AAAAAcFGEPgAAAAAwHoU+AAAAAGd7hj4AAAAAqNOFPgAAAABA84U+AAAAAKplhz4AAAAAuSmKPgAAAAAf8ok+AAAAAKdZiz4AAAAAPEiDPgAAAABCGoQ+AAAAAHeEgz4AAAAASOyEPgAAAABQvoU+AAAAAOkSkz4AAAAAwDiRPgAAAAA++pE+AAAAACPUiT4AAAAA8FqVPgAAAAAqKoU+AAAAAEdhpT4AAAAAtyumPgAAAACqUqo+AAAAALCEqT4AAAAAuPWmPgAAAAA+Has+AAAAAHZ/qz4AAAAACLSqPgAAAABjP6w+AAAAAFgPnT4AAAAA48+dPgAAAABvkJ4+AAAAAPtQnz4AAAAAxb+nPgAAAAAu6Ks+AAAAAIwArT4AAAAANj+sPgAAAACMlKs+AAAAAMzsqj4AAAAA0SmqPgAAAAAlsDM+AAAAABVCNT4AAAAAqnk6PgAAAADXZjk+AAAAANPzNj4AAAAA34o8PgAAAACXjUg+AAAAAO8AST4AAAAAAdBLPgAAAAAWOzE+AAAAADDfMj4AAAAAxR0yPgAAAABJgzQ+AAAAAGQnNj4AAAAAFKJpPgAAAACrjGM+AAAAAMFwZz4AAAAAHN1JPgAAAAAgPHU+AAAAAIZQOD4AAAAAAnkDPAAAAABv4h88AAAAAJNOMDwAAAAAv84EPAAAAABuVT88AAAAAAgbdDwAAAAAzIRVPAAAAACjPAc8AAAAAE1suzwAAAAALEgDPAAAAADViR08AAAAAHzLNzwAAAAAyNEGPQAAAACOx3g8AAAAAISABTwAAAAAZBHjPgAAAACd5uM+AAAAACh94j4AAAAAuZHhPgAAAAA7s+Q+AAAAAL4j4z4AAAAAya3ePgAAAACAed0+AAAAAAbh3j4AAAAAMUjjPgAAAAA7GuQ+AAAAAEns5D4AAAAAV77lPgAAAAARgOU+AAAAABLM4z4AAAAAoPnePgAAAADLDtM+AAAAACWS1j4AAAAAW1/XPgAAAAB6edU+AAAAAF4gcz8AAAAAvYhzPwAAAAA1bXI/AAAAAHcJcj8AAAAA9etzPwAAAADOp3I/AAAAADBubz8AAAAAwBRvPwAAAABjMm8/AAAAAC3fcj8AAAAANUhzPwAAAABXtnI/AAAAADyxcz8AAAAARBp0PwAAAADLcWg/AAAAAEalaT8AAAAAw1RpPwAAAABrkG4/AAAAADepaD8AAAAAb5hxPwAAAABhxQY/AAAAAOMxBz8AAAAA4N0FPwAAAAD9WAU/AAAAAEyWBz8AAAAA/iEGPwAAAABbSAI/AAAAAJN1AT8AAAAAVykCPwAAAABw+QY/AAAAAHdiBz8AAAAAfssHPwAAAACENAg/AAAAANP6Bz8AAAAA/GYGPwAAAACb7wE/AAAAAKrL7T4AAAAAAtT0PgAAAADD0fY+AAAAAFm78z4AAAAAHAAePwAAAABSbR4/AAAAADnnHj8AAAAAsVwePwAAAACM4x4/AAAAANu5Hz8AAAAA1BwgPwAAAADCVh8/AAAAANvkIT8AAAAA4fIdPwAAAADnWx4/AAAAAO/EHj8AAAAA9S0fPwAAAABPWR8/AAAAAMqIID8AAAAA8/0jPwAAAADKJS4/AAAAAJUqJT8AAAAAOgwiPwAAAAAgMSE/AAAAAFZUQD8AAAAA6L1APwAAAADfMEA/AAAAAHHDPz8AAAAA7iVBPwAAAADnkUA/AAAAAA+yPj8AAAAAKTo+PwAAAAAcAD8/AAAAAAEAQD8AAAAAB2lAPwAAAAC96j8/AAAAAA/SQD8AAAAAFTtBPwAAAACp8Ts/AAAAAJTIOz8AAAAATDw7PwAAAAClwT0/AAAAAJCuOj8AAAAA01U/PwAAAAAbA2k/AAAAAO5vaT8AAAAAGJNmPwAAAAClC2Y/AAAAALPUaT8AAAAAHdpmPwAAAAD1zV4/AAAAAEL+XT8AAAAANcRePwAAAACbb2k/AAAAAJ/YaT8AAAAApkFqPwAAAACsqmo/AAAAAII5aj8AAAAAUCFnPwAAAAAWu14/AAAAAMxfTj8AAAAAWgVPPwAAAABerE8/AAAAAP5PTj8AAAAAT4qoPgAAAADNVKk+AAAAAHqFrT4AAAAAA7esPgAAAAC+Hqo+AAAAAJFPrj4AAAAA55uuPgAAAADYzq0+AAAAADJarz4AAAAAiRGgPgAAAAAT0qA+AAAAAJ+SoT4AAAAAKVOiPgAAAAC76Ko+AAAAAAYarz4AAAAAtxmwPgAAAACAGq8+AAAAALpzrj4AAAAA3s+tPgAAAAAACa0+AAAAAAGOSz8AAAAA+vVLPwAAAABliEk/AAAAANAnST8AAAAAzlJMPwAAAADdj0k/AAAAAJb2Qj8AAAAAZKVCPwAAAACcBEI/AAAAAL/lSz8AAAAAxk5MPwAAAADOt0w/AAAAANQgTT8AAAAAELNMPwAAAACxskk/AAAAADwzQT8AAAAAxDIsPwAAAADmSDM/AAAAAIJGNj8AAAAAovs1PwAAAAALDYE+AAAAAIXZgT4AAAAAOE+DPgAAAADOqYI+AAAAAOKugj4AAAAA0juEPgAAAACnP4c+AAAAAMMQhz4AAAAATHiIPgAAAAAPAIA+AAAAAB3SgD4AAAAAW0CAPgAAAAAppIE+AAAAADN2gj4AAAAAEr+QPgAAAAB8zY4+AAAAAGmmjz4AAAAAjv2GPgAAAABoTJM+AAAAAKMCgj4AAAAAVLOrPgAAAADhfaw+AAAAAEm4sD4AAAAAVemvPgAAAADER60+AAAAAOOBsT4AAAAAWbixPgAAAACl6bA+AAAAAP90sj4AAAAAtROjPgAAAABA1KM+AAAAAMuUpD4AAAAAVVWlPgAAAACyEa4+AAAAANtLsj4AAAAA4DKzPgAAAADK9bE+AAAAAOhSsT4AAAAA8LKwPgAAAAAv6K8+AAAAAFEnLT4AAAAArbguPgAAAABFITQ+AAAAAB8TMz4AAAAAA2swPgAAAAAlNzY+AAAAAHS5Qj4AAAAAOD5DPgAAAABHDUY+AAAAAKuqKj4AAAAAxk4sPgAAAACFlSs+AAAAAOHyLT4AAAAA/ZYvPgAAAABo+mQ+AAAAACe2Xj4AAAAAF8liPgAAAADzL0Q+AAAAABMfcT4AAAAAdwEyPgAAAACZm7E9AAAAAEiPtD0AAAAArdzLPQAAAACnOMs9AAAAAOgduD0AAAAAQljRPQAAAADBQAU+AAAAAJemCD4AAAAAHTYLPgAAAACsqqo9AAAAAOLyrT0AAAAAdaauPQAAAAAVO7E9AAAAAEuDtD0AAAAAgjJOPgAAAAAhuEA+AAAAAOJoTD4AAAAA8IINPgAAAADez30+AAAAAPaIyj0AAAAA0FXmPgAAAABWK+c+AAAAAFyp5T4AAAAAmLvkPgAAAACs9+c+AAAAAJ1N5j4AAAAA25fhPgAAAADaWuA+AAAAAGPC4T4AAAAAapDmPgAAAAB8Yuc+AAAAAJA06D4AAAAAnQbpPgAAAAA3xOg+AAAAAJzz5j4AAAAANdDhPgAAAABTHdU+AAAAAPnl2D4AAAAAnsrZPgAAAABSzdc+AAAAAFt9cT8AAAAAmudxPwAAAADi4HA/AAAAABxucD8AAAAA9U5yPwAAAACRPHE/AAAAAMwXbj8AAAAA241tPwAAAADOU24/AAAAABY7cT8AAAAAHKRxPwAAAAAYE3E/AAAAACINcj8AAAAAJ3ZyPwAAAAB3qWg/AAAAACmraD8AAAAAGfRnPwAAAABMA20/AAAAAJI7Zz8AAAAAJftvPwAAAACWZwg/AAAAAD3UCD8AAAAA+HMHPwAAAADq7QY/AAAAAIM4CT8AAAAA7bYHPwAAAABkvQM/AAAAAEDmAj8AAAAABZoDPwAAAACKnQg/AAAAAJAGCT8AAAAAmG8JPwAAAACf2Ak/AAAAAOScCT8AAAAAwvoHPwAAAADlWgM/AAAAADLa7z4AAAAA2Cf3PgAAAAAHPfk+AAAAAC8P9j4AAAAApDlaPwAAAAB6r1o/AAAAAPTxVz8AAAAAbCJXPwAAAAD+GFs/AAAAAPFeWD8AAAAAgIdQPwAAAAB9sE4/AAAAAPH4UD8AAAAArapaPwAAAACyE1s/AAAAALd8Wz8AAAAAv+VbPwAAAADLfls/AAAAABOuWD8AAAAA2wlRPwAAAABdKEI/AAAAADaUQj8AAAAAQjNCPwAAAADVLz4/AAAAAAe25T0AAAAA9p3oPQAAAAAku/w9AAAAAC51/D0AAAAAeO7rPQAAAADtIgA+AAAAABqiGT4AAAAAS4QdPgAAAADumhw+AAAAAPMt3z0AAAAAKXbiPQAAAABUuuI9AAAAAF2+5T0AAAAAkQbpPQAAAADETuw9AAAAACw87z0AAAAA99wBPgAAAADLUSA+AAAAAK/Egz4AAAAAnCBXPgAAAAAolU4+AAAAAIaKWj4AAAAAWw4iPgAAAAB7qIc+AAAAAPeQ+z0AAAAAYaZqPwAAAAA+E2s/AAAAAOAwaD8AAAAAMKlnPwAAAAD9d2s/AAAAAKZ3aD8AAAAAulxgPwAAAAA1jF8/AAAAAChSYD8AAAAAtBNrPwAAAAC5fGs/AAAAAMHlaz8AAAAAx05sPwAAAADB3Gs/AAAAAJ2+aD8AAAAANkhgPwAAAABwzU8/AAAAAPN0UD8AAAAA6h1RPwAAAACWv08/AAAAAFncrj4AAAAA9qavPgAAAAAY67M+AAAAAKgbsz4AAAAAx3CwPgAAAAA1tLQ+AAAAAMrUtD4AAAAAdAS0PgAAAADMj7U+AAAAAOEVpj4AAAAAbNamPgAAAAD4lqc+AAAAAIJXqD4AAAAApjqxPgAAAACxfbU+AAAAAAtMtj4AAAAAFtG0PgAAAAAWMrQ+AAAAAAGWsz4AAAAAXMeyPgAAAAA+kXs+AAAAAJspfT4AAAAABCOAPgAAAADe/34+AAAAAPHUfj4AAAAA8xGBPgAAAACVVYQ+AAAAAGcvhD4AAAAA8JaFPgAAAACfb3k+AAAAAL8Tez4AAAAAcPh5PgAAAADft3w+AAAAAABcfj4AAAAAPWuOPgAAAAA5Yow+AAAAAJNSjT4AAAAA+CaEPgAAAADhPZE+AAAAADO2fT4AAAAADrE+PwAAAACYGj8/AAAAABiTPj8AAAAA5yU+PwAAAACngj8/AAAAAF/0Pj8AAAAASiM9PwAAAAA2rDw/AAAAAClyPT8AAAAA5ls+PwAAAADvxD4/AAAAAHxHPj8AAAAA9C0/PwAAAAD6lj8/AAAAABKCOj8AAAAAClc6PwAAAAC1zDk/AAAAAIQ0PD8AAAAA7EA5PwAAAACHuD0/AAAAAF8Fsj4AAAAAC9CyPgAAAADoHbc+AAAAAPxNtj4AAAAAzpmzPgAAAACK5rc+AAAAADzxtz4AAAAAQR+3PgAAAACaqrg+AAAAAA8YqT4AAAAAmtipPgAAAAAmmao+AAAAALJZqz4AAAAAnWO0PgAAAACHr7g+AAAAADRluT4AAAAAYKy3PgAAAABFEbc+AAAAABR5tj4AAAAAiqa1PgAAAAB+niY+AAAAAEMvKD4AAAAA38gtPgAAAABjvyw+AAAAACziKT4AAAAAa+MvPgAAAABP5Tw+AAAAAIF7PT4AAAAAkUpAPgAAAABDGiQ+AAAAAF6+JT4AAAAARw0lPgAAAAB4Yic+AAAAAJEGKT4AAAAAvFJgPgAAAACg31k+AAAAAGshXj4AAAAAyII+PgAAAAAEAm0+AAAAAGiyKz4AAAAAuzxnPwAAAAAMUFk/AAAAADxzWD8AAAAAozRmPwAAAACxXUs/AAAAAHqESj8AAAAAKChWPwAAAABVaWM/AAAAAEBLSD8AAAAAL99yPwAAAAB4Ymc/AAAAANKycj8AAAAAmG9ZPwAAAAC5fEs/AAAAABySRD8AAAAA8+5RPwAAAAAgAF4/AAAAAD4xbj8AAAAAmsdnPwAAAAA+fHE/AAAAAD2a6T4AAAAABnDqPgAAAACN1eg+AAAAAHXl5z4AAAAACjzrPgAAAAB2d+k+AAAAAO6B5D4AAAAANzzjPgAAAADAo+Q+AAAAAKLY6T4AAAAApqrqPgAAAACofOs+AAAAAK5O7D4AAAAARwjsPgAAAAAfG+o+AAAAAMum5D4AAAAA2ivXPgAAAADROds+AAAAAOI13D4AAAAAKCHaPgAAAAAhJE0/AAAAAKiYTT8AAAAAESFLPwAAAAAcXEo/AAAAABcCTj8AAAAAaY1LPwAAAADhc0Q/AAAAAI7CQj8AAAAAneNEPwAAAADaiU0/AAAAAOLyTT8AAAAA51tOPwAAAADuxE4/AAAAAC5oTj8AAAAA795LPwAAAAC4/EQ/AAAAAAmVNz8AAAAACu03PwAAAABAjTc/AAAAAJ/oMz8AAAAAFNpvPwAAAABLRHA/AAAAABpDbz8AAAAAktBuPwAAAACtq3A/AAAAAAmfbz8AAAAACYlsPwAAAADo/2s/AAAAANrFbD8AAAAA+pZvPwAAAAACAHA/AAAAANZvbz8AAAAACGlwPwAAAAAO0nA/AAAAAN85Zz8AAAAAnzlnPwAAAACDhGY/AAAAACt2az8AAAAA7c1lPwAAAADYXW4/AAAAAMwJCj8AAAAAmXYKPwAAAAASCgk/AAAAANqCCD8AAAAAt9oKPwAAAADcSwk/AAAAAG0yBT8AAAAA71YEPwAAAACzCgU/AAAAAKZBCj8AAAAArKoKPwAAAACyEws/AAAAALh8Cz8AAAAA8j4LPwAAAACFjgk/AAAAADDGBD8AAAAAuejxPgAAAACue/k+AAAAAEmo+z4AAAAABGP4PgAAAACl6ls/AAAAAIRSXD8AAAAAf41ZPwAAAAC+LVk/AAAAALGtXD8AAAAAwYdZPwAAAAAbD1I/AAAAAA3AUT8AAAAAB+5QPwAAAADGTlw/AAAAAMy3XD8AAAAA1CBdPwAAAADaiV0/AAAAAMYMXT8AAAAAMaFZPwAAAAAs8k8/AAAAAIIDOD8AAAAA6yFAPwAAAAADlkM/AAAAAJVMQz8AAAAAZS61PgAAAAAh+bU+AAAAALhQuj4AAAAAT4C5PgAAAADVwrY+AAAAANwYuz4AAAAArw27PgAAAAAQOro+AAAAAGjFuz4AAAAAPRqsPgAAAADJ2qw+AAAAAFebrT4AAAAA4luuPgAAAACTjLc+AAAAAF3huz4AAAAAXn68PgAAAACph7o+AAAAAHPwuT4AAAAAJFy5PgAAAAC4hbg+AAAAALoLbj8AAAAAepJuPwAAAABNMW0/AAAAAInaaz8AAAAAlQZvPwAAAAD/8m0/AAAAAEycaT8AAAAAdBdmPwAAAAApDGs/AAAAAOHybT8AAAAA6FtuPwAAAACkh20/AAAAAO7Ebj8AAAAA9i1vPwAAAADcf2U/AAAAALp0Yz8AAAAAWrlcPwAAAACYEGI/AAAAAFZIST8AAAAA8ZhqPwAAAABmCHU+AAAAAC2gdj4AAAAAoO15PgAAAAAkrHg+AAAAABZMeD4AAAAAKdB7PgAAAACCa4E+AAAAAAtOgT4AAAAAlLWCPgAAAAAz33I+AAAAAFCDdD4AAAAAMHBzPgAAAABoJ3Y+AAAAAIXLdz4AAAAAZheMPgAAAAD29ok+AAAAALz+ij4AAAAAY1CBPgAAAABZL48+AAAAACNndz4AAAAAPws9PwAAAABodj0/AAAAAELuPD8AAAAANXQ8PwAAAABD3z0/AAAAAPRVPT8AAAAAsn07PwAAAABZ1zo/AAAAAFrhOz8AAAAAzLc8PwAAAADTID0/AAAAANKgPD8AAAAA2ok9PwAAAADh8j0/AAAAAGgMOT8AAAAA4bQ4PwAAAACmrzc/AAAAAK04Oj8AAAAAXdM1PwAAAAD//zs/AAAAAJBJbD8AAAAAu7VsPwAAAAAJyGk/AAAAAOVFaT8AAAAAQhptPwAAAAAaDWo/AAAAAM/HYT8AAAAAtBVhPwAAAAA6gGE/AAAAAM23bD8AAAAA0yBtPwAAAADaiW0/AAAAAP2OTz8AAAAAve9RPwAAAAA2G1E/AAAAAGxXuD4AAAAANiK5PgAAAACHg70+AAAAAKKyvD4AAAAA2eu5PgAAAAAvS74+AAAAACAqvj4AAAAA3FS9PgAAAAA24L4+AAAAAG0crz4AAAAA99yvPgAAAACBnbA+AAAAAApesT4AAAAAiLW6PgAAAAAzE78+AAAAAIiXvz4AAAAA82K9PgAAAACgz7w+AAAAADc/vD4AAAAA5WS7PgAAAACrFSA+AAAAANylIT4AAAAAeXAnPgAAAACoayY+AAAAAFlZIz4AAAAAsI8pPgAAAAAqETc+AAAAAMu4Nz4AAAAA2oc6PgAAAADZiR0+AAAAAPQtHz4AAAAACoUePgAAAAAO0iA+AAAAACl2Ij4AAAAAEqtbPgAAAAAaCVU+AAAAAL95WT4AAAAAntU4PgAAAAD05Gg+AAAAAFhjJT4AAAAA7Vl+PwAAAAD+WX0/AAAAAPIKfD8AAAAAitx8PwAAAAAT33k/AAAAAKqceD8AAAAAOoB4PwAAAABPyng/AAAAAOAxdT8AAAAA5lt+PwAAAABrkH4/AAAAADEhfj8AAAAA2ol9PwAAAAAjDXo/AAAAAAuMbj8AAAAAAKhxPwAAAAAN1XA/AAAAAJb6dz8AAAAAzL5sPwAAAAA0hnw/AAAAAJre7D4AAAAAtrTtPgAAAAC9Aew+AAAAAE4P6z4AAAAAd4DuPgAAAABVoew+AAAAAP5r5z4AAAAAkR3mPgAAAAAbhec+AAAAAL0g7T4AAAAAz/LtPgAAAADjxO4+AAAAAPWW7z4AAAAAbkzvPgAAAACqQu0+AAAAAGB95z4AAAAAYTrZPgAAAACmjd0+AAAAACOh3j4AAAAA/XTcPgAAAABT1E4/AAAAAHdATz8AAAAA1eJMPwAAAAD6YEw/AAAAAPClTz8AAAAAci9NPwAAAAD7dkY/AAAAACi6RT8AAAAAHIBGPwAAAAD1LU8/AAAAAPuWTz8AAAAAAwBQPwAAAAAJaVA/AAAAAHALUD8AAAAAPXxNPwAAAADbiUY/AAAAAK0COT8AAAAAgns5PwAAAADL9Tk/AAAAACXGOD8AAAAA/qsLPwAAAADzGAw/AAAAACugCj8AAAAAyBcKPwAAAADsfAw/AAAAAMvgCj8AAAAAdqcGPwAAAACexwU/AAAAAGF7Bj8AAAAAwOULPwAAAADGTgw/AAAAAM23DD8AAAAA0yANPwAAAAAC4Qw/AAAAAEgiCz8AAAAAezEGPwAAAABB9/M+AAAAAIbP+z4AAAAAjhP+PgAAAADbtvo+AAAAAAKFuz4AAAAA7m+8PgAAAAAwwcA+AAAAAE/mvz4AAAAAjZC9PgAAAAAnosE+AAAAAO1HwT4AAAAA1m/APgAAAACX/8E+AAAAAHIpsj4AAAAA/jWzPgAAAADZxLQ+AAAAACkXtz4AAAAArAO/PgAAAADpm8I+AAAAAI27wj4AAAAAPj7APgAAAADOrr8+AAAAAEkivz4AAAAAFUS+PgAAAAC7iKQ9AAAAAI6Apz0AAAAAjEy/PQAAAABwh749AAAAAAMUqz0AAAAA1u7EPQAAAABbUv89AAAAAIv9Aj4AAAAA5N0FPgAAAADaiZ09AAAAAA7SoD0AAAAAqpKhPQAAAABDGqQ9AAAAAHhipz0AAAAAaolKPgAAAADYjzw+AAAAAHqJSD4AAAAAFCYIPgAAAAAkMII+AAAAAFfQvT0AAAAA73gXPwAAAABx3xc/AAAAAAlrGD8AAAAALhYYPwAAAACASRg/AAAAAGXcGD8AAAAAw+IZPwAAAADexhk/AAAAAF9vGj8AAAAAeGIXPwAAAAB/yxc/AAAAAIY0GD8AAAAAi50YPwAAAACtsxg/AAAAAIhOGT8AAAAAig0bPwAAAADn7B8/AAAAAFuCHT8AAAAAUa4cPwAAAABODh0/AAAAALHFHz8AAAAAsC8gPwAAAAB5fSE/AAAAAKMMIT8AAAAAsp4gPwAAAABWFiI/AAAAAHMMJT8AAAAADqUkPwAAAADNIiY/AAAAAPqWHz8AAAAAAQAgPwAAAAAHaSA/AAAAAA7SID8AAAAAmgshPwAAAAB3niI/AAAAABk3Jz8AAAAAUA81PwAAAACwHS4/AAAAAJETLD8AAAAA304sPwAAAACRf24+AAAAAMUWcD4AAAAAO5VzPgAAAABnWHI+AAAAAELDcT4AAAAAbnx1PgAAAADfAn0+AAAAAGLZfD4AAAAAcah/PgAAAADETmw+AAAAAODybT4AAAAA7udsPgAAAAD8lm8+AAAAABo7cT4AAAAAkMOJPgAAAACyi4c+AAAAAOeqiD4AAAAAmvN8PgAAAADSII0+AAAAABIYcT4AAAAAatjAPgAAAACc5MI+AAAAAJjkxD4AAAAAubvDPgAAAAAA8cQ+AAAAACb5xT4AAAAATGTEPgAAAABBm8M+AAAAAOTgxD4AAAAAFk66PgAAAACvCr4+AAAAAAzOwT4AAAAAQBnFPgAAAAB9y8Y+AAAAAOQExz4AAAAA82HFPgAAAAALjMA+AAAAAMWkwT4AAAAAO8PBPgAAAAD9GsE+AAAAANeMGT4AAAAAchwbPgAAAAAUGCE+AAAAAO4XID4AAAAAhtAcPgAAAAD2OyM+AAAAAAc9MT4AAAAAEvYxPgAAAAAjxTQ+AAAAAHD5Fj4AAAAAi50YPgAAAADM/Bc+AAAAAKRBGj4AAAAAv+UbPgAAAABlA1c+AAAAAJMyUD4AAAAAEtJUPgAAAABzKDM+AAAAAObHZD4AAAAASBQfPgAAAAALI/A+AAAAAHH58D4AAAAA8i3vPgAAAAAwOe4+AAAAAOXE8T4AAAAAM8vvPgAAAAASVuo+AAAAAO7+6D4AAAAAdWbqPgAAAAAHafA+AAAAABY78T4AAAAAIQ3yPgAAAAAu3/I+AAAAAJCQ8j4AAAAAMmrwPgAAAAD0U+o+AAAAAOlI2z4AAAAAfeHfPgAAAABoDOE+AAAAANPI3j4AAAAA0/x5PQAAAABOPYA9AAAAANXjmD0AAAAAKOaVPQAAAABA5YM9AAAAAPspnz0AAAAALfPbPQAAAAD0C9s9AAAAAMi36j0AAAAAx05sPQAAAAAw33I9AAAAAPNscz0AAAAAmW95PQAAAAABAIA9AAAAAIyRQD4AAAAAFKcvPgAAAAD2GjQ+AAAAAIxC2j0AAAAARyJPPgAAAAAVoJI9AAAAADdODT8AAAAATbsNPwAAAABFNgw/AAAAALasCz8AAAAAIB8OPwAAAAC4dQw/AAAAAH8cCD8AAAAASzgHPwAAAAAP7Ac/AAAAANqJDT8AAAAA3/INPwAAAADmWw4/AAAAAO3EDj8AAAAAEIMOPwAAAAAMtgw/AAAAAMWcBz8AAAAAyAX2PgAAAABZI/4+AAAAAGg/AD8AAAAAsgr9PgAAAAAFf10/AAAAADD1XT8AAAAALSZbPwAAAAAAVFo/AAAAALteXj8AAAAAVpNbPwAAAABpjFM/AAAAAPirUT8AAAAARv5TPwAAAADi8l0/AAAAAOdbXj8AAAAA7sRePwAAAAD0LV8/AAAAAHHEXj8AAAAA2+FbPwAAAAAiDVQ/AAAAADLNRD8AAAAAAD5FPwAAAADB3EQ/AAAAAKbBQD8AAAAALGs7PwAAAAC70zs/AAAAAJNVOz8AAAAAWvA6PwAAAADsOTw/AAAAAPanOz8AAAAAZQA6PwAAAAAjozk/AAAAAGcZOj8AAAAAsRM7PwAAAAC4fDs/AAAAANQBOz8AAAAAvuU7PwAAAADHTjw/AAAAAOwPNz8AAAAAI243PwAAAAD/Gjc/AAAAADwxOT8AAAAAFpw2PwAAAAC9hDo/AAAAAD1uJD8AAAAAJ7IkPwAAAAAMGyM/AAAAAOjaIz8AAAAAwQAlPwAAAACzsCI/AAAAAKWLHj8AAAAAndQhPwAAAACmVhw/AAAAAEmDJD8AAAAAT+wkPwAAAABWVSU/AAAAAF2+JT8AAAAA6l8lPwAAAADEyiI/AAAAANp6Gz8AAAAAl2gJPwAAAACixA8/AAAAABVvFD8AAAAA5FcaPwAAAAADd1A/AAAAAPXeUD8AAAAADlpOPwAAAACy+U0/AAAAAFg7UT8AAAAAAF5OPwAAAAAoiUc/AAAAAIc4Rz8AAAAAoIpGPwAAAAAO0lA/AAAAABU7UT8AAAAAG6RRPwAAAAAiDVI/AAAAAEibUT8AAAAAVH5OPwAAAADprUU/AAAAAGXlLz8AAAAAAUI3PwAAAAA1Xzo/AAAAALgUOj8AAAAA4GOePgAAAABqDZ8+AAAAACC5nz4AAAAAHBufPgAAAAB/ip8+AAAAADZQoD4AAAAAbD2hPgAAAAAA9aA+AAAAAE2moT4AAAAAvnydPgAAAACyNJ4+AAAAAOSfnT4AAAAACLOePgAAAAAVxp4+AAAAABiZpD4AAAAA00CkPgAAAACtjqQ+AAAAAJiIoD4AAAAAKs+lPgAAAADFZJ4+AAAAAL32Zz4AAAAAWY1pPgAAAADUPG0+AAAAAKwEbD4AAAAAbTprPgAAAAC0KG8+AAAAALsudz4AAAAAqRZ3PgAAAAC65Xk+AAAAAF2+ZT4AAAAAdWJnPgAAAACyX2Y+AAAAAI8GaT4AAAAAqqpqPgAAAAC6b4c+AAAAAG8ghT4AAAAAEFeGPgAAAABxRnc+AAAAAEsSiz4AAAAABMlqPgAAAACSTsg+AAAAADeCyT4AAAAA+AjJPgAAAACLE8g+AAAAALx7yj4AAAAA2M7JPgAAAADkWsc+AAAAALloxj4AAAAAadXHPgAAAABpjMc+AAAAAM5DyT4AAAAAx3rKPgAAAAClbMs+AAAAAFNYyz4AAAAA043KPgAAAAC2RMg+AAAAAJKawj4AAAAAdfPDPgAAAABBBcQ+AAAAAM3awj4AAAAABAQTPgAAAAAKkxQ+AAAAAK6/Gj4AAAAAM8QZPgAAAACyRxY+AAAAADroHD4AAAAA42grPgAAAABcMyw+AAAAAG0CLz4AAAAACGkQPgAAAAAiDRI+AAAAAI50ET4AAAAAPLETPgAAAABWVRU+AAAAALpbUj4AAAAADFxLPgAAAABnKlA+AAAAAEh7LT4AAAAA2KpgPgAAAAA5xRg+AAAAAGDyfD8AAAAAsVp9PwAAAACIEHw/AAAAADqtez8AAAAAB719PwAAAAAVRHw/AAAAAFWTeD8AAAAACTt4PwAAAABoPng/AAAAAM23fD8AAAAA1SB9PwAAAAAmiHw/AAAAANqJfT8AAAAA4PJ9PwAAAAAAZHA/AAAAAK/WcT8AAAAA8IZxPwAAAAA7sXc/AAAAACrOcD8AAAAAmDp7PwAAAAB2Z/M+AAAAACU+9D4AAAAAJ1ryPgAAAAAOY/E+AAAAAE8J9T4AAAAAEPXyPgAAAAAjQO0+AAAAAEng6z4AAAAA0kftPgAAAAA7sfM+AAAAAEiD9D4AAAAAV1X1PgAAAABkJ/Y+AAAAAK7U9T4AAAAAu5HzPgAAAACKKu0+AAAAAHBX3T4AAAAAUjXiPgAAAACqd+M+AAAAAKoc4T4AAAAAVylePQAAAAA4eWQ9AAAAAAjEhD0AAAAA9X2CPQAAAADe52s9AAAAADGFiz0AAAAALE+2PQAAAADYcLc9AAAAAA/PxT0AAAAAIw1SPQAAAACLnVg9AAAAAKsEWD0AAAAA9C1fPQAAAABdvmU9AAAAAGi1GD4AAAAAR4AJPgAAAADxOg8+AAAAAOsFvD0AAAAACxQnPgAAAAC65IA9AAAAAGrwDj8AAAAApl0PPwAAAABdzA0/AAAAAKVBDT8AAAAAVsEPPwAAAACmCg4/AAAAAIiRCT8AAAAA+KgIPwAAAAC8XAk/AAAAAPQtDz8AAAAA+5YPPwAAAAABABA/AAAAAAdpED8AAAAAISUQPwAAAADQSQ4/AAAAABAICT8AAAAAUBT4PgAAAACYOwA/AAAAAAp1AT8AAAAAhl7/PgAAAAAMMV8/AAAAAKOdXz8AAAAAC+1cPwAAAACMZ1w/AAAAAKYCYD8AAAAAATZdPwAAAAABoFU/AAAAAODWVD8AAAAA1JxVPwAAAAD7ll8/AAAAAAAAYD8AAAAACGlgPwAAAAAP0mA/AAAAALBnYD8AAAAAJ39dPwAAAABCmlU/AAAAANc6Rj8AAAAA2NBGPwAAAABOaEc/AAAAAHobRj8AAAAARL/YPQAAAABDtNs9AAAAAENT8T0AAAAAyqTwPQAAAABDNd89AAAAAOhh9j0AAAAAA8IVPgAAAABIBBk+AAAAAOcVGz4AAAAAIQ3SPQAAAABXVdU9AAAAAH/F1T0AAAAAjJ3YPQAAAAC/5ds9AAAAAAqFWT4AAAAATipNPgAAAABxQVg+AAAAAFF9HT4AAAAAvi6DPgAAAAAI0O89AAAAAE3PJT8AAAAAlD4mPwAAAADAASQ/AAAAALNmIz8AAAAAOaAmPwAAAACzLyQ/AAAAAAf4HT8AAAAAedIcPwAAAAA9hh0/AAAAAGMnJj8AAAAAapAmPwAAAABx+SY/AAAAAHdiJz8AAAAA+AEnPwAAAACGXiQ/AAAAACPmHD8AAAAA3G8KPwAAAAByhhA/AAAAAOFjEj8AAAAAHfoPPwAAAABAMZs+AAAAAMT/mz4AAAAA/LCcPgAAAAD7+Js+AAAAAPTQnD4AAAAAXYqdPgAAAAA+kJ4+AAAAAKgbnj4AAAAAHIOfPgAAAADvQpo+AAAAAOYVmz4AAAAA2GGaPgAAAABE55s+AAAAAOy0nD4AAAAAw12jPgAAAACVJ6I+AAAAABlFoj4AAAAAPLKdPgAAAACjwKM+AAAAAAg/mz4AAAAA6m1hPgAAAADxA2M+AAAAAG/kZj4AAAAA8LBlPgAAAACZsWQ+AAAAAPrUaD4AAAAAl1pxPgAAAADxU3E+AAAAAAIjdD4AAAAA9S1fPgAAAAAN0mA+AAAAAHTXXz4AAAAAKHZiPgAAAABDGmQ+AAAAAOQbhT4AAAAALLWCPgAAAAA7A4Q+AAAAAEaZcT4AAAAAxAOJPgAAAADzeWQ+AAAAAN7FOT8AAAAAsjA6PwAAAAAJujk/AAAAAKNCOT8AAAAAh5k6PwAAAACPITo/AAAAAMt4OD8AAAAA3ts3PwAAAAAG3Dg/AAAAAJhvOT8AAAAAn9g5PwAAAACwWzk/AAAAAKVBOj8AAAAAq6o6PwAAAACdYjY/AAAAAGILNj8AAAAA2h01PwAAAACwRTc/AAAAAGt2Mz8AAAAAT9A4PwAAAAAJMcw+AAAAAIEGzT4AAAAABUjMPgAAAAA+bMs+AAAAAIfVzT4AAAAACv/MPgAAAABRR8o+AAAAAO9PyT4AAAAAkLfKPgAAAABHS8w+AAAAAL4izT4AAAAApfXNPgAAAACWxs4+AAAAAO6jzj4AAAAAkbfNPgAAAACRG8s+AAAAABipxD4AAAAAS0fGPgAAAACEcMY+AAAAAKMuxT4AAAAAL3sMPgAAAAChCQ4+AAAAAElnFD4AAAAAeXATPgAAAADgvg8+AAAAAIGUFj4AAAAAvpQlPgAAAACkcCY+AAAAALU/KT4AAAAAn9gJPgAAAAC5fAs+AAAAAFDsCj4AAAAA0yANPgAAAADtxA4+AAAAAA20TT4AAAAAhYVGPgAAAAC6gks+AAAAAB/OJz4AAAAAyo1cPgAAAAApdhI+AAAAAGhPez8AAAAA5rl7PwAAAADvhno/AAAAADUSej8AAAAABCF8PwAAAACs4Ho/AAAAAL9Fdz8AAAAAOrV2PwAAAAAve3c/AAAAALMTez8AAAAAuXx7PwAAAADm5Ho/AAAAAMDlez8AAAAAx058PwAAAAD33XA/AAAAADrvcD8AAAAAmihwPwAAAAAbJHY/AAAAAIZgbz8AAAAATZ15PwAAAADgq/Y+AAAAANqC9z4AAAAAWob1PgAAAADrjPQ+AAAAALdN+D4AAAAA7h72PgAAAAA1KvA+AAAAAKXB7j4AAAAALSnwPgAAAABx+fY+AAAAAH3L9z4AAAAAjJ34PgAAAACYb/k+AAAAAM8Y+T4AAAAAQ7n2PgAAAAAhAfA+AAAAAPZl3z4AAAAAKonkPgAAAADu4uU+AAAAAH5w4z4AAAAAqwxSPwAAAACggVI/AAAAALryTz8AAAAAQCpPPwAAAAAY61I/AAAAAEtfUD8AAAAAdgZJPwAAAACSSEc/AAAAAMJ2ST8AAAAAKnZSPwAAAAAv31I/AAAAADRIUz8AAAAAO7FTPwAAAAAWUVM/AAAAAAWwUD8AAAAAI41JPwAAAACCpzs/AAAAACMGPD8AAAAA9aU7PwAAAAC54Tc/AAAAAIz+Qz0AAAAApBdKPQAAAADmRm49AAAAAA1xaz0AAAAASA1RPQAAAAAsAXg9AAAAAID1pz0AAAAAPZWrPQAAAABfM7E9AAAAAH7LNz0AAAAA51s+PQAAAAC04z09AAAAAFDsRD0AAAAAu3xLPQAAAACmiAw+AAAAAC7KAj4AAAAAVVcKPgAAAACVq7A9AAAAAP32Ij4AAAAANI1oPQAAAACfkhA/AAAAAAEAET8AAAAAd2IPPwAAAACU1g4/AAAAAItjET8AAAAAlp8PPwAAAACSBgs/AAAAAKcZCj8AAAAAas0KPwAAAAAP0hA/AAAAABQ7ET8AAAAAG6QRPwAAAAAiDRI/AAAAADHHET8AAAAAlN0PPwAAAABacwo/AAAAANUi+j4AAAAAhGUBPwAAAACrqgI/AAAAAC7ZAD8AAAAApNNgPwAAAAB/O2E/AAAAACpfXj8AAAAAn/9dPwAAAAA5lmE/AAAAAORVXj8AAAAAr6FWPwAAAAAuU1Y/AAAAAAd0VT8AAAAAFTthPwAAAAAbpGE/AAAAACENYj8AAAAAKHZiPwAAAAD/9GE/AAAAANFsXj8AAAAA2mxUPwAAAAAjtjs/AAAAAAQbRD8AAAAAtK5HPwAAAACtZUc/AAAAAIFxJz8AAAAA7+AnPwAAAADblyU/AAAAAKH7JD8AAAAAbUIoPwAAAACkxCU/AAAAABBtHz8AAAAAJ0MePwAAAADr9h4/AAAAAH7LJz8AAAAAgzQoPwAAAACKnSg/AAAAAJEGKT8AAAAACKQoPwAAAABL8iU/AAAAAG1RHj8AAAAAHncLPwAAAABdsBE/AAAAAIGZEz8AAAAACCQRPwAAAABoGhk/AAAAAO+AGT8AAAAARPoZPwAAAABFpRk/AAAAAJPqGT8AAAAARmgaPwAAAAClQBs/AAAAAIsgGz8AAAAAob8bPwAAAACSBhk/AAAAAJhvGT8AAAAAn9gZPwAAAACmQRo/AAAAAIlUGj8AAAAAw9gaPwAAAAAmTxw/AAAAAGfsHz8AAAAAIF4ePwAAAAA/rR0/AAAAANT4HT8AAAAA7euXPgAAAAB9upg+AAAAAJ2EmT4AAAAA2c6YPgAAAAD6jZk+AAAAAOxgmj4AAAAAJ6abPgAAAABEOps+AAAAAM+hnD4AAAAAePmWPgAAAACEy5c+AAAAADAdlz4AAAAAr52YPgAAAAAdcJk+AAAAAOwJoT4AAAAAU7yfPgAAAABC8Z8+AAAAAKPbmj4AAAAAG7KhPgAAAABYF5g+AAAAABflWj4AAAAAiHpcPgAAAAAKjGA+AAAAADZdXz4AAAAAxShePgAAAAA+gWI+AAAAAHKGaz4AAAAAO5FrPgAAAABOYG4+AAAAAIydWD4AAAAApkFaPgAAAAA2T1k+AAAAAL/lWz4AAAAA2YldPgAAAAAPyII+AAAAAOlJgD4AAAAAZK+BPgAAAAAd7Gs+AAAAAD31hj4AAAAA5CpePgAAAAA7d88+AAAAAIJK0D4AAAAAAXTPPgAAAACils4+AAAAANAY0T4AAAAAkijQPgAAAABcMc0+AAAAAF0xzD4AAAAA4pjNPgAAAAC0l88+AAAAAExp0D4AAAAAMzvRPgAAAAA8DdI+AAAAAGbn0T4AAAAA597QPgAAAAAh8s0+AAAAAKC3xj4AAAAAIZvIPgAAAADI28g+AAAAAHiCxz4AAAAAXvIFPgAAAAA5gAc+AAAAAOMODj4AAAAAvhwNPgAAAAAMNgk+AAAAAMVAED4AAAAAmcAfPgAAAADsrSA+AAAAAP58Iz4AAAAANkgDPgAAAABQ7AQ+AAAAABJkBD4AAAAAapAGPgAAAACFNAg+AAAAAGQMST4AAAAA/65BPgAAAAAP20Y+AAAAAPQgIj4AAAAAvHBYPgAAAAAZJww+AAAAANCleT8AAAAAZBR6PwAAAACN13g/AAAAAC5CeD8AAAAAcn16PwAAAADwQHk/AAAAAA1+dT8AAAAAWHZ0PwAAAAAg5nU/AAAAAJpveT8AAAAAoNh5PwAAAAD4OHk/AAAAAKZBej8AAAAArqp6PwAAAABBX28/AAAAALcEbz8AAAAAoAptPwAAAADnf3M/AAAAACsMaT8AAAAAkrp3PwAAAABL8Pk+AAAAAI7H+j4AAAAAjLL4PgAAAADItvc+AAAAACCS+z4AAAAAzEj5PgAAAABHFPM+AAAAAACj8T4AAAAAhwrzPgAAAACmQfo+AAAAALMT+z4AAAAAwOX7PgAAAADMt/w+AAAAAOxc/D4AAAAAyuD5PgAAAAC01/I+AAAAAH904T4AAAAA/9zmPgAAAAAxTug+AAAAAFXE5T4AAAAAQNspPQAAAAAC8i89AAAAAFDlVD0AAAAAJCJSPQAAAAD66TY9AAAAAEOyXj0AAAAAOE2cPQAAAADPD6A9AAAAAPKtpT0AAAAA2okdPQAAAABEGiQ9AAAAAL3CIz0AAAAArKoqPQAAAAAXOzE9AAAAAPrgBz4AAAAATuf7PQAAAACorwU+AAAAAEJRpT0AAAAA7tkePgAAAAD3UE89AAAAANM0Ej8AAAAAW6ISPwAAAACR+BA/AAAAAINrED8AAAAAvwUTPwAAAACDNBE/AAAAAJl7DD8AAAAAVIoLPwAAAAAXPgw/AAAAACh2Ej8AAAAAL98SPwAAAAA2SBM/AAAAADuxEz8AAAAAP2kTPwAAAABYcRE/AAAAAKTeCz8AAAAAXTH8PgAAAABujwI/AAAAAE3gAz8AAAAAGgMCPwAAAACJIzg/AAAAAFmNOD8AAAAAAhw4PwAAAAC3rDc/AAAAAHb0OD8AAAAAuHU4PwAAAAAr6jY/AAAAAP1nNj8AAAAAwRs3PwAAAACGNDg/AAAAAIudOD8AAAAAkwY5PwAAAACAeTQ/AAAAAK6fND8AAAAAK+0zPwAAAAC2Eyk/AAAAAEiDKT8AAAAA9C0nPwAAAACPkCY/AAAAAKLkKT8AAAAAkVknPwAAAAAa4iA/AAAAANazHz8AAAAAmGcgPwAAAACYbyk/AAAAAJ/YKT8AAAAApUEqPwAAAACtqio/AAAAABhGKj8AAAAADoYnPwAAAAC4vB8/AAAAAGJ+DD8AAAAAR9oSPwAAAAAjzxQ/AAAAAPJNEj8AAAAAXY2XPQAAAAC/eZo9AAAAANj7sj0AAAAAQJKyPQAAAABTBJ49AAAAAA9XuD0AAAAAzfT0PQAAAACu0vw9AAAAAFBlAD4AAAAAPLGTPQAAAABx+ZY9AAAAAKVBmj0AAAAAx0lHPgAAAABWUzk+AAAAADSBRj4AAAAAvbxTPwAAAACpJFQ/AAAAAEeOUT8AAAAAFS5RPwAAAAC4gFQ/AAAAAJaPUT8AAAAAEo5KPwAAAADdPUo/AAAAABuGST8AAAAAQhpUPwAAAABJg1Q/AAAAAFDsVD8AAAAAztM5PwAAAAC1CD0/AAAAAIO+PD8AAAAAg6eUPgAAAAC+dZU+AAAAAGpYlj4AAAAA/KSVPgAAAABbSZY+AAAAAAA3lz4AAAAAFbyYPgAAAADpWJg+AAAAAHLAmT4AAAAAQrGTPgAAAABVg5Q+AAAAABHZkz4AAAAAYlWVPgAAAABvJ5Y+AAAAABa2nj4AAAAAD1GdPgAAAABtnZ0+AAAAAA4FmD4AAAAAlKOfPgAAAADQ75Q+AAAAAJhvIT8AAAAAXNMhPwAAAAAZHiM/AAAAADPfIj8AAAAAVz8iPwAAAADQniM/AAAAAOyYJj8AAAAA9NAmPwAAAAAkZyc/AAAAABQ7IT8AAAAAG6QhPwAAAAAiDSI/AAAAACLVLj8AAAAAzzwtPwAAAADfeC4/AAAAAEVcVD4AAAAAIPFVPgAAAAClM1o+AAAAAH4JWT4AAAAA9J9XPgAAAACDLVw+AAAAAE+yZT4AAAAAhM5lPgAAAACVnWg+AAAAACMNUj4AAAAAPLFTPgAAAAD5xlI+AAAAAFZVVT4AAAAAcflWPgAAAAA4dIA+AAAAAEq9ez4AAAAAHrd+PgAAAADxPmY+AAAAALXmhD4AAAAA1NtXPgAAAABfu9I+AAAAACCP0z4AAAAALaDSPgAAAABqwNE+AAAAADBd1D4AAAAAa1LTPgAAAABtG9A+AAAAALUSzz4AAAAAPnrQPgAAAABG39I+AAAAAEix0z4AAAAAS4PUPgAAAABPVdU+AAAAAHYr1T4AAAAAagbUPgAAAAC2yNA+AAAAACfGyD4AAAAA9u7KPgAAAAALR8s+AAAAAE7WyT4AAAAAFNP+PQAAAADQ9gA+AAAAAHy2Bz4AAAAAA8kGPgAAAAA5rQI+AAAAAAvtCT4AAAAAdewZPgAAAAA16xo+AAAAAEe6HT4AAAAAmW/5PQAAAADOt/w9AAAAAKe3+z0AAAAAAAAAPgAAAAAcpAE+AAAAALVkRD4AAAAAetg8PgAAAABiM0I+AAAAAMlzHD4AAAAAq1NUPgAAAAAJ2AU+AAAAALM0/T4AAAAAQwz+PgAAAADA3vs+AAAAAKbg+j4AAAAAjNb+PgAAAACocvw+AAAAAFr+9T4AAAAAXIT0PgAAAADm6/U+AAAAANqJ/T4AAAAA6Fv+PgAAAAD1Lf8+AAAAAAEAAD8AAAAADKH/PgAAAABSCP0+AAAAAEuu9T4AAAAABoPjPgAAAADUMOk+AAAAAHS56j4AAAAAKRjoPgAAAADytw89AAAAAF/MFT0AAAAAuYM7PQAAAAA60zg9AAAAAK3GHD0AAAAAV2NFPQAAAADvpJA9AAAAAGGKlD0AAAAAgiiaPQAAAAA2SAM9AAAAAJ/YCT0AAAAAxaEJPQAAAAAIaRA9AAAAAHH5Fj0AAAAATzkDPgAAAABDOvI9AAAAAPwHAT4AAAAA7faZPQAAAADgvBo+AAAAALgUNj0AAAAAhdgTPwAAAACcUBQ/AAAAANjtEj8AAAAAVgwSPwAAAACyyxQ/AAAAAF3nEz8AAAAARwIPPwAAAAA2HQ0/AAAAABQdET8AAAAAQxoUPwAAAABIgxQ/AAAAAFDsFD8AAAAA0w0JPwAAAACmkgY/AAAAAJtcAz8AAAAAIGdiPwAAAADK2mI/AAAAAHP7Xz8AAAAAliJfPwAAAABVPGM/AAAAAGtxYD8AAAAAlDVYPwAAAADONFY/AAAAAK7dWD8AAAAApd5iPwAAAADVQ2M/AAAAAHeiYz8AAAAAQfdjPwAAAABVkmM/AAAAAN7PYD8AAAAAVVJZPwAAAAAtvEo/AAAAAB4gSj8AAAAABTFJPwAAAAAwwkQ/AAAAAFyeyz0AAAAA+KTOPQAAAACrvuQ9AAAAAEWD4z0AAAAAnDfSPQAAAABrWuo9AAAAAAQkED4AAAAAQ2ASPgAAAADEOhY+AAAAAIQ0yD0AAAAAuXzLPQAAAADuxM49AAAAANpgVj4AAAAAFvlIPgAAAAAY/1E+AAAAAO21Kj8AAAAApCUrPwAAAAANxCg/AAAAAH4lKD8AAAAA2IYrPwAAAAB+7ig/AAAAACJXIj8AAAAAgyQhPwAAAABH2CE/AAAAALITKz8AAAAAunwrPwAAAAC/5Ss/AAAAADIEFD8AAAAAxQQWPwAAAADfdxM/AAAAANS7Gj8AAAAADCMbPwAAAAB8jhs/AAAAAPYzGz8AAAAA0owbPwAAAACP/Rs/AAAAAEewHD8AAAAA3HscPwAAAAAeMx0/AAAAAKuqGj8AAAAAshMbPwAAAAC5fBs/AAAAAIuRHz8AAAAAWtsePwAAAADG+h4/AAAAAA9jkT4AAAAAADGSPgAAAAAyLJM+AAAAABt7kj4AAAAA7ASTPgAAAAAiDZQ+AAAAAAHSlT4AAAAAjXeVPgAAAAAW35Y+AAAAAAE7kT4AAAAAFw2SPgAAAAAu35I+AAAAAEFinD4AAAAAzOWaPgAAAACWSZs+AAAAAHLTTT4AAAAAuWdPPgAAAAA/21M+AAAAAMG1Uj4AAAAAIhdRPgAAAADK2VU+AAAAACreXz4AAAAAzAtgPgAAAADd2mI+AAAAANQgTT4AAAAA78ROPgAAAAAJaVA+AAAAAMRAfD4AAAAAxeZ2PgAAAABxD3o+AAAAALr/1T4AAAAAyNPWPgAAAABbzNU+AAAAAEPq1D4AAAAAkKHXPgAAAABGfNY+AAAAAIAF0z4AAAAAD/TRPgAAAACZW9M+AAAAAFcn1j4AAAAAYvnWPgAAAABty9c+AAAAAM1CzT4AAAAAT7LNPgAAAAAjKsw+AAAAAHYZ8j0AAAAACfj0PQAAAAD/0gE+AAAAAG7VAT4AAAAAc0z4PQAAAADspwM+AAAAAId2FT4AAAAAgdsZPgAAAABVIxg+AAAAAPqW7z0AAAAAL9/yPQAAAABjJ/Y9AAAAAJcFQD4AAAAAYkY6PgAAAAC2+UY+AAAAAGEJeD8AAAAAtXF4PwAAAADgPnc/AAAAAFjbdj8AAAAAftR4PwAAAADxdXc/AAAAAMIAdD8AAAAA5adzPwAAAABmuHM/AAAAAIU0eD8AAAAAi514PwAAAACSBnk/AAAAAOdqbD8AAAAA+71tPwAAAADZbW0/AAAAAI48AD8AAAAAfKgAPwAAAADxCv8+AAAAAIEK/j4AAAAAeQ0BPwAAAACEnP8+AAAAAGvo+D4AAAAAt2X3PgAAAAA/zfg+AAAAAAdpAD8AAAAADdIAPwAAAAAUOwE/AAAAAKuE6z4AAAAAtyTtPgAAAAAAbOo+AAAAAEsp6zwAAAAAd033PAAAAAAjIiI9AAAAAE6EHz0AAAAAYqMCPQAAAABsFCw9AAAAAKb8hD0AAAAA8gSJPQAAAAATo449AAAAAPYt3zwAAAAAx07sPAAAAACab/k8AAAAAEYj/T0AAAAANo3oPQAAAACgwPg9AAAAAKvsZD8AAAAApBJlPwAAAAAUIWM/AAAAAMx7Yz8AAAAAcz5lPwAAAAA8x2I/AAAAAGrjXT8AAAAAr65fPwAAAAAJF1w/AAAAAFDsZD8AAAAAYCFlPwAAAAAPwGQ/AAAAALhZZT8AAAAAoJhlPwAAAABbFk8/AAAAAFXbUz8AAAAAI+hYPwAAAADMb2A/AAAAAAQjXD8AAAAAQopjPwAAAACM39I+AAAAAHOx0z4AAAAAY7HTPgAAAABy39I+AAAAAFKD1D4AAAAAT4PUPgAAAABUsdM+AAAAAFnf0j4AAAAAS4PUPgAAAACoDdI+AAAAAKLf0j4AAAAAjw3SPgAAAACAsdM+AAAAAFWD1D4AAAAAMlXVPgAAAAA4VdU+AAAAAD9V1T4AAAAARlXVPgAAAABOVdU+AAAAAEXf0j4AAAAAVQ3SPgAAAABwDdI+AAAAAD2xUz4AAAAAWVVVPgAAAABWVVU+AAAAAD2xUz4AAAAAb/lWPgAAAABx+VY+AAAAAFdVVT4AAAAAPbFTPgAAAABv+VY+AAAAACENUj4AAAAAO7FTPgAAAAAjDVI+AAAAAFdVVT4AAAAAcflWPgAAAACLnVg+AAAAAIqdWD4AAAAAip1YPgAAAACKnVg+AAAAAFdVVT4AAAAAO7FTPgAAAAAjDVI+AAAAACENUj4AAAAAIw1SPgAAAAAUOyE/AAAAABukIT8AAAAAHKQhPwAAAAAUOyE/AAAAACINIj8AAAAAIg0iPwAAAAAbpCE/AAAAABQ7IT8AAAAAIQ0iPwAAAAAM0iA/AAAAABU7IT8AAAAADtIgPwAAAAAbpCE/AAAAACINIj8AAAAAKHYiPwAAAAAodiI/AAAAACh2Ij8AAAAAKHYiPwAAAAAVOyE/AAAAAA7SID8AAAAADdIgPwAAAAAN0iA/AAAAAHuDlD4AAAAAiVWVPgAAAAB/VZU+AAAAAGyDlD4AAAAAjieWPgAAAACEJ5Y+AAAAAHBVlT4AAAAAX4OUPgAAAAB5J5Y+AAAAAGaxkz4AAAAAhoOUPgAAAABbsZM+AAAAAJVVlT4AAAAAlSeWPgAAAACK+ZY+AAAAAIn5lj4AAAAAhPmWPgAAAAB9+ZY+AAAAAG4nlj4AAAAAY1WVPgAAAABUg5Q+AAAAAEmxkz4AAAAAQ7GTPgAAAABRsZM+AAAAAEYaVD8AAAAASoNUPwAAAABKg1Q/AAAAAEMaVD8AAAAAT+xUPwAAAABR7FQ/AAAAAEqDVD8AAAAARBpUPwAAAABQ7FQ/AAAAAD6xUz8AAAAAQxpUPwAAAAA9sVM/AAAAAEmDVD8AAAAAT+xUPwAAAABXVVU/AAAAAFZVVT8AAAAAWFVVPwAAAABWVVU/AAAAAE/sVD8AAAAAQRpUPwAAAAA8sVM/AAAAAD6xUz8AAAAAPbFTPwAAAAA8sZM9AAAAAHL5lj0AAAAAcfmWPQAAAAA9sZM9AAAAAKVBmj0AAAAApkGaPQAAAABy+ZY9AAAAADyxkz0AAAAApUGaPQAAAAAIaZA9AAAAAD2xkz0AAAAACGmQPQAAAABx+ZY9AAAAAKVBmj0AAAAA2omdPQAAAADbiZ09AAAAANqJnT0AAAAA2omdPQAAAAAIaZA9AAAAAAhpkD0AAAAAmG8pPwAAAACg2Ck/AAAAAJ7YKT8AAAAAmG8pPwAAAAClQSo/AAAAAKZBKj8AAAAAn9gpPwAAAACYbyk/AAAAAKZBKj8AAAAAkAYpPwAAAACWbyk/AAAAAJEGKT8AAAAAntgpPwAAAACkQSo/AAAAAKyqKj8AAAAAq6oqPwAAAACsqio/AAAAAKuqKj8AAAAArKoqPwAAAACe2Ck/AAAAAJEGKT8AAAAAkAYpPwAAAACQBik/AAAAAIQ0OD8AAAAAjJ04PwAAAACLnTg/AAAAAIU0OD8AAAAAkgY5PwAAAACTBjk/AAAAAIqdOD8AAAAAhTQ4PwAAAACRBjk/AAAAAH7LNz8AAAAAhDQ4PwAAAAB+yzc/AAAAAIudOD8AAAAAkQY5PwAAAACYbzk/AAAAAJhvOT8AAAAAmG85PwAAAACXbzk/AAAAAJEGOT8AAAAAhDQ4PwAAAAB+yzc/AAAAAH3LNz8AAAAAJ3YSPwAAAAAv3xI/AAAAAC/fEj8AAAAAKHYSPwAAAAA1SBM/AAAAADZIEz8AAAAALt8SPwAAAAAodhI/AAAAADRIEz8AAAAAIw0SPwAAAAAodhI/AAAAACINEj8AAAAAMN8SPwAAAAA1SBM/AAAAADyxEz8AAAAAO7ETPwAAAAA9sRM/AAAAADuxEz8AAAAAPLETPwAAAAA1SBM/AAAAADDfEj8AAAAAIw0SPwAAAAAiDRI/AAAAAEEaJD0AAAAArKoqPQAAAACrqio9AAAAAEQaJD0AAAAAFTsxPQAAAAAVOzE9AAAAAKyqKj0AAAAAQhokPQAAAAAWOzE9AAAAANqJHT0AAAAAQxokPQAAAADYiR09AAAAAKuqKj0AAAAAFDsxPQAAAAB9yzc9AAAAAH7LNz0AAAAAfss3PQAAAAB+yzc9AAAAAH3LNz0AAAAAFDsxPQAAAABDGiQ9AAAAANqJHT0AAAAA2okdPQAAAACnQfo+AAAAALMT+z4AAAAAtRP7PgAAAACnQfo+AAAAAMDl+z4AAAAAwOX7PgAAAACyE/s+AAAAAKVB+j4AAAAAwOX7PgAAAACZb/k+AAAAAKdB+j4AAAAAmW/5PgAAAAC0E/s+AAAAAMDl+z4AAAAAzbf8PgAAAADNt/w+AAAAAM63/D4AAAAAzLf8PgAAAAClQfo+AAAAAJhv+T4AAAAAm2/5PgAAAACf2Hk/AAAAAKVBej8AAAAApUF6PwAAAACf2Hk/AAAAAKyqej8AAAAArKp6PwAAAACmQXo/AAAAAKDYeT8AAAAArqp6PwAAAACZb3k/AAAAAJ3YeT8AAAAAl295PwAAAAClQXo/AAAAAKyqej8AAAAAsxN7PwAAAACxE3s/AAAAALQTez8AAAAAsRN7PwAAAACxE3s/AAAAAKyqej8AAAAApUF6PwAAAACd2Hk/AAAAAJdveT8AAAAAmG95PwAAAACZb3k/AAAAAFDsBD4AAAAAapAGPgAAAABrkAY+AAAAAE/sBD4AAAAAhDQIPgAAAACDNAg+AAAAAGqQBj4AAAAAUOwEPgAAAACENAg+AAAAADVIAz4AAAAAUOwEPgAAAAA2SAM+AAAAAGqQBj4AAAAAhTQIPgAAAACe2Ak+AAAAAJ/YCT4AAAAAn9gJPgAAAACe2Ak+AAAAAJ7YCT4AAAAANkgDPgAAAAA1SAM+AAAAADZIAz4AAAAAp5nPPgAAAAANatA+AAAAAM5p0D4AAAAAEpnPPgAAAACPO9E+AAAAAG870T4AAAAAiWnQPgAAAABYmM8+AAAAAE470T4AAAAAj8vOPgAAAADomc8+AAAAAAPLzj4AAAAALWrQPgAAAACmO9E+AAAAADI70T4AAAAATWnQPgAAAAAOyM4+AAAAAJXGzj4AAAAAsMnOPgAAAACmQVo+AAAAAMDlWz4AAAAAwOVbPgAAAACmQVo+AAAAANiJXT4AAAAA2oldPgAAAAC/5Vs+AAAAAKRBWj4AAAAA2oldPgAAAACkQVo+AAAAAL7lWz4AAAAA2IldPgAAAADzLV8+AAAAAPMtXz4AAAAA8y1fPgAAAADzLV8+AAAAAPQtXz4AAAAApUFaPgAAAACRy5c+AAAAAA2emD4AAAAA9J2YPgAAAACNy5c+AAAAAHxxmT4AAAAAF3GZPgAAAADPnZg+AAAAAIjLlz4AAAAAk3CZPgAAAACOy5c+AAAAABSemD4AAAAAonGZPgAAAADBRpo+AAAAAFlGmj4AAAAAV0WaPgAAAAAURJo+AAAAAO5Cmj4AAAAAHHCZPgAAAACwnZg+AAAAAIPLlz4AAAAAkwYZPwAAAACYbxk/AAAAAJZvGT8AAAAAkwYZPwAAAACe2Bk/AAAAAKDYGT8AAAAAmG8ZPwAAAACRBhk/AAAAAJ/YGT8AAAAAip0YPwAAAACQBhk/AAAAAIqdGD8AAAAAmG8ZPwAAAACd2Bk/AAAAAKZBGj8AAAAApEEaPwAAAAClQRo/AAAAAKVBGj8AAAAAndgZPwAAAACQBhk/AAAAAIqdGD8AAAAAip0YPwAAAACLnRg/AAAAAH3LJz8AAAAAhDQoPwAAAACENCg/AAAAAH7LJz8AAAAAjJ0oPwAAAACKnSg/AAAAAIM0KD8AAAAAfssnPwAAAACJnSg/AAAAAHdiJz8AAAAAfssnPwAAAAB3Yic/AAAAAIU0KD8AAAAAip0oPwAAAACFNCg/AAAAAHdiJz8AAAAAd2InPwAAAAAWO2E/AAAAABykYT8AAAAAG6RhPwAAAAAVO2E/AAAAACINYj8AAAAAIw1iPwAAAAAcpGE/AAAAABQ7YT8AAAAAIQ1iPwAAAAAP0mA/AAAAABU7YT8AAAAAD9JgPwAAAAAcpGE/AAAAACINYj8AAAAAKHZiPwAAAAAndmI/AAAAACh2Yj8AAAAAKHZiPwAAAAAiDWI/AAAAABykYT8AAAAAEzthPwAAAAAP0mA/AAAAABDSYD8AAAAAD9IQPwAAAAAWOxE/AAAAABU7ET8AAAAAD9IQPwAAAAAapBE/AAAAABykET8AAAAAFDsRPwAAAAAO0hA/AAAAABukET8AAAAACGkQPwAAAAAP0hA/AAAAAAhpED8AAAAAFTsRPwAAAAAcpBE/AAAAABykET8AAAAAFTsRPwAAAAAO0hA/AAAAAAdpED8AAAAACGkQPwAAAADmWz49AAAAAFDsRD0AAAAAUOxEPQAAAADnWz49AAAAALp8Sz0AAAAAuXxLPQAAAABQ7EQ9AAAAAOhbPj0AAAAAuXxLPQAAAADoWz49AAAAAFHsRD0AAAAAt3xLPQAAAAAhDVI9AAAAACINUj0AAAAAIg1SPQAAAAAiDVI9AAAAACENUj0AAAAAuHxLPQAAAABR7EQ9AAAAAOlbPj0AAAAAKnZSPwAAAAAy31I/AAAAAC/fUj8AAAAAKnZSPwAAAAA3SFM/AAAAADdIUz8AAAAAMN9SPwAAAAApdlI/AAAAADZIUz8AAAAAIw1SPwAAAAApdlI/AAAAACINUj8AAAAAMd9SPwAAAAA2SFM/AAAAADZIUz8AAAAAMN9SPwAAAAApdlI/AAAAACMNUj8AAAAAIw1SPwAAAABx+fY+AAAAAIHL9z4AAAAAfsv3PgAAAABy+fY+AAAAAI2d+D4AAAAAjZ34PgAAAAB/y/c+AAAAAHH59j4AAAAAjJ34PgAAAABkJ/Y+AAAAAHP59j4AAAAAYyf2PgAAAACBy/c+AAAAAI2d+D4AAAAAi534PgAAAAB/y/c+AAAAAGQn9j4AAAAAZSf2PgAAAAC6fHs/AAAAAMDlez8AAAAAvuV7PwAAAAC5fHs/AAAAAMVOfD8AAAAAx058PwAAAADA5Xs/AAAAALh8ez8AAAAAxk58PwAAAAC4fHs/AAAAAMDlez8AAAAAxk58PwAAAADMt3w/AAAAAMu3fD8AAAAAzbd8PwAAAADMt3w/AAAAAMZOfD8AAAAAuHx7PwAAAAC4fAs+AAAAANUgDT4AAAAA0yANPgAAAAC5fAs+AAAAAO7EDj4AAAAA7cQOPgAAAADTIA0+AAAAALl8Cz4AAAAA7sQOPgAAAAC5fAs+AAAAANMgDT4AAAAA7cQOPgAAAAAIaRA+AAAAAAhpED4AAAAACGkQPgAAAAAHaRA+AAAAAOzEDj4AAAAAuHwLPgAAAAB4Psw+AAAAANkmzT4AAAAACybNPgAAAAC1Q8w+AAAAAOn8zT4AAAAAzPrNPgAAAABrJM0+AAAAAAtIzD4AAAAAGvjNPgAAAADiKMs+AAAAAJI4zD4AAAAAcznLPgAAAAAQJs0+AAAAAKP9zT4AAAAASEvMPgAAAAAGXss+AAAAAKRsyz4AAAAADkzLPgAAAACg2Dk/AAAAAKZBOj8AAAAApUE6PwAAAACf2Dk/AAAAAKyqOj8AAAAAq6o6PwAAAAClQTo/AAAAAKDYOT8AAAAArao6PwAAAACe2Dk/AAAAAKZBOj8AAAAAq6o6PwAAAACzEzs/AAAAALITOz8AAAAAsxM7PwAAAACyEzs/AAAAALITOz8AAAAApkE6PwAAAACe2Dk/AAAAAA3SYD4AAAAAKHZiPgAAAAAodmI+AAAAAA/SYD4AAAAAQhpkPgAAAABCGmQ+AAAAACl2Yj4AAAAAD9JgPgAAAABDGmQ+AAAAAA7SYD4AAAAAKHZiPgAAAABBGmQ+AAAAAFu+ZT4AAAAAXL5lPgAAAABcvmU+AAAAAFy+ZT4AAAAAXL5lPgAAAABBGmQ+AAAAACl2Yj4AAAAAD9JgPgAAAACpG5s+AAAAAHvqmz4AAAAA2+mbPgAAAAD+GZs+AAAAAGeqnD4AAAAAsa6cPgAAAACW6Js+AAAAANoXmz4AAAAAQLKcPgAAAAA4HJs+AAAAANTpmz4AAAAAlqWcPgAAAACORZ0+AAAAAAhTnT4AAAAAMWKdPgAAAADTcJ0+AAAAAOu0nD4AAAAA5BWbPgAAAABkJyY/AAAAAGmQJj8AAAAAapAmPwAAAABlJyY/AAAAAHD5Jj8AAAAAcPkmPwAAAABpkCY/AAAAAGInJj8AAAAAcPkmPwAAAABdviU/AAAAAGQnJj8AAAAAXb4lPwAAAABqkCY/AAAAAHH5Jj8AAAAAZCcmPwAAAABcviU/AAAAAF2+JT8AAAAAV1XVPQAAAACMndg9AAAAAIyd2D0AAAAAWFXVPQAAAADB5ds9AAAAAMDl2z0AAAAAi53YPQAAAABXVdU9AAAAAMDl2z0AAAAAJA3SPQAAAABXVdU9AAAAACIN0j0AAAAAjZ3YPQAAAAC/5ds9AAAAAPUt3z0AAAAA9i3fPQAAAAD0Ld89AAAAAPMt3z0AAAAA9S3fPQAAAACNndg9AAAAACIN0j0AAAAAIw3SPQAAAAAkDdI9AAAAAPuWXz8AAAAAAgBgPwAAAAACAGA/AAAAAPuWXz8AAAAACGlgPwAAAAAIaWA/AAAAAAAAYD8AAAAA+5ZfPwAAAAAJaWA/AAAAAPUtXz8AAAAA+5ZfPwAAAAD0LV8/AAAAAAIAYD8AAAAACGlgPwAAAAAHaWA/AAAAAAIAYD8AAAAA8y1fPwAAAAD1LV8/AAAAAPUtXz8AAAAA8y0PPwAAAAD7lg8/AAAAAPmWDz8AAAAA9C0PPwAAAAACABA/AAAAAAIAED8AAAAA+pYPPwAAAAD0LQ8/AAAAAAIAED8AAAAA7cQOPwAAAAD0LQ8/AAAAAOzEDj8AAAAA+pYPPwAAAAABABA/AAAAAAAAED8AAAAA+pYPPwAAAADzLQ8/AAAAAOzEDj8AAAAA7sQOPwAAAACMnVg9AAAAAPUtXz0AAAAA8y1fPQAAAACMnVg9AAAAAF2+ZT0AAAAAXb5lPQAAAADzLV89AAAAAIydWD0AAAAAX75lPQAAAACJnVg9AAAAAPYtXz0AAAAAXb5lPQAAAADGTmw9AAAAAMVObD0AAAAAx05sPQAAAADFTmw9AAAAAMZObD0AAAAA9i1fPQAAAACJnVg9AAAAADmx8z4AAAAASYP0PgAAAABIg/Q+AAAAADqx8z4AAAAAVFX1PgAAAABVVfU+AAAAAEmD9D4AAAAAObHzPgAAAABVVfU+AAAAACzf8j4AAAAAOLHzPgAAAAAt3/I+AAAAAEeD9D4AAAAAVFX1PgAAAABWVfU+AAAAAEmD9D4AAAAAOrHzPgAAAAAt3/I+AAAAAC/f8j4AAAAALt/yPgAAAADUIH0/AAAAANuJfT8AAAAA2ol9PwAAAADUIH0/AAAAAOHyfT8AAAAA4fJ9PwAAAADZiX0/AAAAANQgfT8AAAAA3/J9PwAAAADSIH0/AAAAANqJfT8AAAAA4PJ9PwAAAADoW34/AAAAAOVbfj8AAAAA5lt+PwAAAADmW34/AAAAAOhbfj8AAAAA0iB9PwAAAAAjDRI+AAAAADyxEz4AAAAAPLETPgAAAAAiDRI+AAAAAFZVFT4AAAAAV1UVPgAAAAA8sRM+AAAAACINEj4AAAAAVlUVPgAAAAAiDRI+AAAAAD2xEz4AAAAAV1UVPgAAAABx+RY+AAAAAHH5Fj4AAAAAcfkWPgAAAABx+RY+AAAAAHH5Fj4AAAAAV1UVPgAAAAAX/sI+AAAAAEd5xz4AAAAAvBrIPgAAAAArmcQ+AAAAAJbmyT4AAAAA/RrKPgAAAAAGvcg+AAAAANU1xj4AAAAAYE/KPgAAAABBt7g+AAAAAFSswT4AAAAAkoG7PgAAAAD19MY+AAAAACW7yT4AAAAAyHrKPgAAAADPQ8k+AAAAALhIwj4AAAAAHOS+PgAAAAB0Ymc+AAAAAI0GaT4AAAAAiwZpPgAAAAB1Ymc+AAAAAKOqaj4AAAAAp6pqPgAAAACOBmk+AAAAAHViZz4AAAAAqKpqPgAAAABzYmc+AAAAAIwGaT4AAAAApKpqPgAAAADATmw+AAAAAMFObD4AAAAAwk5sPgAAAADDTmw+AAAAAMVObD4AAAAAqapqPgAAAACRBmk+AAAAAHZiZz4AAAAAZLudPgAAAAA+OJ0+AAAAAKK9nT4AAAAASOadPgAAAADQ/Zo+AAAAABlTnD4AAAAAsUOePgAAAAApEZ4+AAAAALKpnT4AAAAA1pedPgAAAADoypw+AAAAAFTlmT4AAAAAp+2TPgAAAABKQJY+AAAAAIsRmT4AAAAAgOSbPgAAAAAtPJ4+AAAAAA7SUD8AAAAAFztRPwAAAAAVO1E/AAAAAA/SUD8AAAAAHKRRPwAAAAAcpFE/AAAAABU7UT8AAAAADtJQPwAAAAAcpFE/AAAAAAlpUD8AAAAAD9JQPwAAAAAIaVA/AAAAABU7UT8AAAAAHKRRPwAAAAAcpFE/AAAAAA/SUD8AAAAAB2lQPwAAAAAIaVA/AAAAAAlpUD8AAAAASYMkPwAAAABQ7CQ/AAAAAFDsJD8AAAAASYMkPwAAAABWVSU/AAAAAFdVJT8AAAAAUOwkPwAAAABJgyQ/AAAAAFhVJT8AAAAAQxokPwAAAABKgyQ/AAAAAEIaJD8AAAAAUOwkPwAAAABXVSU/AAAAAFdVJT8AAAAAUOwkPwAAAABKgyQ/AAAAAEIaJD8AAAAAQxokPwAAAABDGiQ/AAAAALp8Oz8AAAAAwOU7PwAAAADA5Ts/AAAAALl8Oz8AAAAAxU48PwAAAADFTjw/AAAAAMDlOz8AAAAAuHw7PwAAAADFTjw/AAAAALl8Oz8AAAAAwOU7PwAAAADGTjw/AAAAAMy3PD8AAAAAy7c8PwAAAADLtzw/AAAAAMy3PD8AAAAAxk48PwAAAADA5Ts/AAAAALl8Oz8AAAAA4PJdPwAAAADnW14/AAAAAOhbXj8AAAAA4fJdPwAAAADwxF4/AAAAAO7EXj8AAAAA51tePwAAAADh8l0/AAAAAO/EXj8AAAAA24ldPwAAAADh8l0/AAAAANqJXT8AAAAA6FtePwAAAADuxF4/AAAAAOhbXj8AAAAA4fJdPwAAAADaiV0/AAAAANuJXT8AAAAA24ldPwAAAADZiQ0/AAAAAODyDT8AAAAA4PINPwAAAADZiQ0/AAAAAOdbDj8AAAAA5lsOPwAAAADg8g0/AAAAANqJDT8AAAAA5lsOPwAAAADTIA0/AAAAANmJDT8AAAAA0yANPwAAAADf8g0/AAAAAOZbDj8AAAAA2YkNPwAAAADTIA0/AAAAANIgDT8AAAAA0yANPwAAAAAw33I9AAAAAJpveT0AAAAAmm95PQAAAAAw33I9AAAAAAAAgD0AAAAAAgCAPQAAAACbb3k9AAAAADDfcj0AAAAAAQCAPQAAAAAu33I9AAAAAJlveT0AAAAAAQCAPQAAAAA2SIM9AAAAADdIgz0AAAAANkiDPQAAAAA2SIM9AAAAADZIgz0AAAAALt9yPQAAAAAGafA+AAAAABc78T4AAAAAFzvxPgAAAAAHafA+AAAAACMN8j4AAAAAIw3yPgAAAAAVO/E+AAAAAAZp8D4AAAAAIg3yPgAAAADmlu8+AAAAAARp8D4AAAAA6pbvPgAAAAAYO/E+AAAAACMN8j4AAAAAIw3yPgAAAAAXO/E+AAAAAAZp8D4AAAAA85bvPgAAAAD2lu8+AAAAAO+W7z4AAAAAip0YPgAAAAClQRo+AAAAAKZBGj4AAAAAip0YPgAAAAC+5Rs+AAAAAL7lGz4AAAAApEEaPgAAAACLnRg+AAAAAL/lGz4AAAAAi50YPgAAAACkQRo+AAAAAL/lGz4AAAAA2YkdPgAAAADZiR0+AAAAANqJHT4AAAAA2okdPgAAAADaiR0+AAAAAMDlGz4AAAAAip0YPgAAAAA77ZY+AAAAALmwoz4AAAAAVgCtPgAAAABEbqM+AAAAAIKPsD4AAAAAmKa2PgAAAAChUbY+AAAAAGvwrz4AAAAAt7+8PgAAAACDi38+AAAAAO+SjD4AAAAAFU2MPgAAAACw/Js+AAAAAFyHqz4AAAAADc7BPgAAAACwCr4+AAAAABROuj4AAAAADY6qPgAAAAAqF7c+AAAAAEVtmz4AAAAA4PJtPgAAAAAEl28+AAAAAACXbz4AAAAA4fJtPgAAAAAkO3E+AAAAACE7cT4AAAAA/ZZvPgAAAADg8m0+AAAAABw7cT4AAAAA4fJtPgAAAAACl28+AAAAACY7cT4AAAAAR99yPgAAAABD33I+AAAAAD/fcj4AAAAAN99yPgAAAAA133I+AAAAABk7cT4AAAAA/ZZvPgAAAAD5lh8/AAAAAAEAID8AAAAAAAAgPwAAAAD7lh8/AAAAAAdpID8AAAAABmkgPwAAAAABACA/AAAAAPmWHz8AAAAACGkgPwAAAAD0LR8/AAAAAPuWHz8AAAAA8i0fPwAAAAABACA/AAAAAAZpID8AAAAACGkgPwAAAAD7lh8/AAAAAPQtHz8AAAAA9C0fPwAAAAD1LR8/AAAAAHZiFz8AAAAAfssXPwAAAAB+yxc/AAAAAHdiFz8AAAAAhDQYPwAAAACFNBg/AAAAAH7LFz8AAAAAeGIXPwAAAACENBg/AAAAAHH5Fj8AAAAAd2IXPwAAAABx+RY/AAAAAH7LFz8AAAAAhDQYPwAAAACENBg/AAAAAH7LFz8AAAAAd2IXPwAAAABw+RY/AAAAAHH5Fj8AAAAADtKgPQAAAABDGqQ9AAAAAEQapD0AAAAADtKgPQAAAAB4Yqc9AAAAAHhipz0AAAAAQxqkPQAAAAAO0qA9AAAAAHlipz0AAAAAD9KgPQAAAABEGqQ9AAAAAHdipz0AAAAArKqqPQAAAACsqqo9AAAAAK6qqj0AAAAAraqqPQAAAACrqqo9AAAAAHdipz0AAAAAQhqkPQAAAAAP0qA9AAAAAEN4fz4AAAAA0H2BPgAAAACdEZM+AAAAAAWQkT4AAAAALVWFPgAAAAAzGpY+AAAAAH6lpD4AAAAA62OjPgAAAAB236Y+AAAAAJ2LYD4AAAAARu1hPgAAAACZCn4+AAAAABDbZT4AAAAAGOFuPgAAAADaxLQ+AAAAAHMpsj4AAAAAjp6iPgAAAAAMXrE+AAAAAO3RkD4AAAAAv+ULPwAAAADGTgw/AAAAAMZODD8AAAAAv+ULPwAAAADLtww/AAAAAMy3DD8AAAAAx04MPwAAAAC+5Qs/AAAAAMy3DD8AAAAAuXwLPwAAAAC/5Qs/AAAAALl8Cz8AAAAAxk4MPwAAAADNtww/AAAAAL/lCz8AAAAAuXwLPwAAAAC5fAs/AAAAALp8Cz8AAAAA9S1PPwAAAAD8lk8/AAAAAPuWTz8AAAAA9C1PPwAAAAADAFA/AAAAAAIAUD8AAAAA+5ZPPwAAAAD1LU8/AAAAAAIAUD8AAAAA7sROPwAAAADzLU8/AAAAAO7ETj8AAAAA+pZPPwAAAAACAFA/AAAAAAEAUD8AAAAA+pZPPwAAAADzLU8/AAAAAO3ETj8AAAAA7cROPwAAAADuxE4/AAAAAHYg7T4AAAAAmvLtPgAAAACr8u0+AAAAAI8g7T4AAAAAw8TuPgAAAADQxO4+AAAAAL7y7T4AAAAApyDtPgAAAADYxO4+AAAAAFRO7D4AAAAAYyDtPgAAAABpTuw+AAAAAIry7T4AAAAAucTuPgAAAACaTuw+AAAAAK9O7D4AAAAAg07sPgAAAABpkH4/AAAAANqJfT8AAAAA2Yl9PwAAAABqkH4/AAAAACMNej8AAAAAIw16PwAAAADbiX0/AAAAAGmQfj8AAAAAIQ16PwAAAABpkH4/AAAAANiJfT8AAAAAIQ16PwAAAAAu33I/AAAAAC7fcj8AAAAAL99yPwAAAAAv33I/AAAAAC7fcj8AAAAAIQ16PwAAAABpkH4/AAAAAPQtHz4AAAAADtIgPgAAAAAP0iA+AAAAAPQtHz4AAAAAKXYiPgAAAAApdiI+AAAAAA/SID4AAAAA9C0fPgAAAAApdiI+AAAAAPQtHz4AAAAADtIgPgAAAAAodiI+AAAAAEMaJD4AAAAAQxokPgAAAABDGiQ+AAAAAEMaJD4AAAAAKHYiPgAAAAD1LR8+AAAAAGLMej4AAAAAH+F7PgAAAADilo8+AAAAAF35jj4AAAAA3fV8PgAAAABpNJA+AAAAADY9oT4AAAAAiYygPgAAAADi7aE+AAAAAJS3XD4AAAAAm6xdPgAAAACet3k+AAAAAJ+hXj4AAAAAoJZfPgAAAACCnbA+AAAAAGscrz4AAAAA3NufPgAAAADhW64+AAAAANVbjj4AAAAAzbdsPwAAAADUIG0/AAAAANMgbT8AAAAAzbdsPwAAAADZiW0/AAAAANqJbT8AAAAA1CBtPwAAAADOt2w/AAAAANqJbT8AAAAAxk5sPwAAAADOt2w/AAAAAMdObD8AAAAA1SBtPwAAAADaiW0/AAAAAOHybT8AAAAA4fJtPwAAAADh8m0/AAAAAN/ybT8AAAAA4PJtPwAAAADVIG0/AAAAAMdObD8AAAAAxk5sPwAAAADJTmw/AAAAANMgPT8AAAAA24k9PwAAAADYiT0/AAAAANIgPT8AAAAA4fI9PwAAAADh8j0/AAAAANqJPT8AAAAA0yA9PwAAAADf8j0/AAAAANIgPT8AAAAA24k9PwAAAADg8j0/AAAAAOhbPj8AAAAA5Vs+PwAAAADnWz4/AAAAAOZbPj8AAAAA6Fs+PwAAAADg8j0/AAAAANuJPT8AAAAA0SA9PwAAAABhg3Q+AAAAAH8ndj4AAAAAdyd2PgAAAABbg3Q+AAAAAJ3Ldz4AAAAAk8t3PgAAAABvJ3Y+AAAAAFSDdD4AAAAAi8t3PgAAAABng3Q+AAAAAIgndj4AAAAArMt3PgAAAADVb3k+AAAAAMJveT4AAAAAtW95PgAAAACpb3k+AAAAAKFveT4AAAAAhMt3PgAAAABpJ3Y+AAAAAE6DdD4AAAAA51tuPwAAAADuxG4/AAAAAO/Ebj8AAAAA6FtuPwAAAAD0LW8/AAAAAPQtbz8AAAAA78RuPwAAAADmW24/AAAAAPUtbz8AAAAA6FtuPwAAAADvxG4/AAAAAPUtbz8AAAAA+pZvPwAAAAD7lm8/AAAAAPqWbz8AAAAA+5ZvPwAAAAD5lm8/AAAAAPQtbz8AAAAA78RuPwAAAADnW24/AAAAAEZ5dj4AAAAAEI53PgAAAADEII0+AAAAADuDjD4AAAAA2aJ4PgAAAABNvo0+AAAAAIB6nj4AAAAA0cmdPgAAAAAuK58+AAAAAF7jWD4AAAAAbthZPgAAAAB/ZHU+AAAAAHzNWj4AAAAAicJbPgAAAABVm60+AAAAAMrarD4AAAAAPBqsPgAAAAAhGZ0+AAAAALFZqz4AAAAAseWLPgAAAADGTlw/AAAAAM+3XD8AAAAAzLdcPwAAAADITlw/AAAAANMgXT8AAAAA1CBdPwAAAADOt1w/AAAAAMZOXD8AAAAA1CBdPwAAAADA5Vs/AAAAAMdOXD8AAAAAv+VbPwAAAADNt1w/AAAAANMgXT8AAAAA0yBdPwAAAADNt1w/AAAAAMHlWz8AAAAAwOVbPwAAAADA5Vs/AAAAAKVBCj8AAAAAq6oKPwAAAACrqgo/AAAAAKVBCj8AAAAAsxMLPwAAAACxEws/AAAAAKyqCj8AAAAApEEKPwAAAACzEws/AAAAAJ/YCT8AAAAApUEKPwAAAACf2Ak/AAAAAKyqCj8AAAAAshMLPwAAAAClQQo/AAAAAJ7YCT8AAAAAn9gJPwAAAAACAHA/AAAAAAlpcD8AAAAACGlwPwAAAAADAHA/AAAAAA7ScD8AAAAAENJwPwAAAAAJaXA/AAAAAAAAcD8AAAAADtJwPwAAAAAAAHA/AAAAAAlpcD8AAAAAD9JwPwAAAAAWO3E/AAAAABU7cT8AAAAAFjtxPwAAAAAVO3E/AAAAAAlpcD8AAAAAAABwPwAAAADaiU0/AAAAAOHyTT8AAAAA4PJNPwAAAADZiU0/AAAAAOZbTj8AAAAA5ltOPwAAAADf8k0/AAAAANuJTT8AAAAA5ltOPwAAAADTIE0/AAAAANiJTT8AAAAA0yBNPwAAAADh8k0/AAAAAOdbTj8AAAAA4fJNPwAAAADYiU0/AAAAANMgTT8AAAAA0yBNPwAAAADSIE0/AAAAAK3Y6T4AAAAAkqrqPgAAAACaquo+AAAAAKvY6T4AAAAAdHzrPgAAAACIfOs+AAAAAKGq6j4AAAAAp9jpPgAAAACafOs+AAAAAMAG6T4AAAAArNjpPgAAAAC8Buk+AAAAAIaq6j4AAAAAZXzrPgAAAACpfOs+AAAAAKTY6T4AAAAApwbpPgAAAACbBuk+AAAAALEG6T4AAAAAeGJnPwAAAACYb1k/AAAAAJlvWT8AAAAAd2JnPwAAAAC5fEs/AAAAALl8Sz8AAAAAmG9ZPwAAAAB3Ymc/AAAAALh8Sz8AAAAAdmJnPwAAAACZb1k/AAAAALl8Sz8AAAAAAgBAPwAAAAACAEA/AAAAAAEAQD8AAAAAAQBAPwAAAAABAEA/AAAAALh8Sz8AAAAAmW9ZPwAAAAB3Ymc/AAAAAF2+JT4AAAAAeGInPgAAAAB4Yic+AAAAAF6+JT4AAAAAkgYpPgAAAACSBik+AAAAAHhiJz4AAAAAXb4lPgAAAACSBik+AAAAAF6+JT4AAAAAeGInPgAAAACSBik+AAAAAK2qKj4AAAAArKoqPgAAAACtqio+AAAAAKyqKj4AAAAAraoqPgAAAACSBik+AAAAACQmcj4AAAAA7TpzPgAAAACeqoo+AAAAABQNij4AAAAAtU90PgAAAAAnSIs+AAAAAMK3mz4AAAAAFQebPgAAAABxaJw+AAAAACYPVT4AAAAAMwRWPgAAAABgEXE+AAAAAD75Vj4AAAAATu5XPgAAAABmVpo+AAAAAINXqD4AAAAAi2+JPgAAAADuxD4/AAAAAPUtPz8AAAAA9C0/PwAAAADvxD4/AAAAAPuWPz8AAAAA/JY/PwAAAAD0LT8/AAAAAO7EPj8AAAAA+5Y/PwAAAADsxD4/AAAAAPQtPz8AAAAA+ZY/PwAAAAABAEA/AAAAAP//Pz8AAAAAAQBAPwAAAAABAEA/AAAAAPmWPz8AAAAA7MQ+PwAAAADvE3s+AAAAAB+4fD4AAAAABrh8PgAAAADeE3s+AAAAAExcfj4AAAAAMVx+PgAAAADxt3w+AAAAAMsTez4AAAAAFVx+PgAAAAADFHs+AAAAADW4fD4AAAAAY1x+PgAAAABFAIA+AAAAADoAgD4AAAAAKwCAPgAAAAAcAIA+AAAAAP9bfj4AAAAA4Ld8PgAAAAAe020+AAAAANvnbj4AAAAAfTSIPgAAAAD4loc+AAAAAJ38bz4AAAAABNKIPgAAAAAK9Zg+AAAAAF9EmD4AAAAAuqWZPgAAAAAXO1E+AAAAABgwUj4AAAAAXb5sPgAAAAAcJVM+AAAAACAaVD4AAAAA9panPgAAAADgFaY+AAAAALGTlz4AAAAAVlWlPgAAAABy+YY+AAAAALMTaz8AAAAAunxrPwAAAAC5fGs/AAAAALITaz8AAAAAwOVrPwAAAADB5Ws/AAAAALh8az8AAAAAshNrPwAAAAC+5Ws/AAAAAKyqaj8AAAAAshNrPwAAAACrqmo/AAAAALh8az8AAAAAwOVrPwAAAADA5Ws/AAAAALITaz8AAAAArKpqPwAAAACsqmo/AAAAACp24j0AAAAAXr7lPQAAAABevuU9AAAAACl24j0AAAAAkgbpPQAAAACRBuk9AAAAAF2+5T0AAAAAKXbiPQAAAACSBuk9AAAAACh24j0AAAAAXr7lPQAAAACSBuk9AAAAAMZO7D0AAAAAxU7sPQAAAADITuw9AAAAAMZO7D0AAAAAxk7sPQAAAACSBuk9AAAAACh24j0AAAAArKpaPwAAAAC2E1s/AAAAALMTWz8AAAAArapaPwAAAAC5fFs/AAAAALt8Wz8AAAAAsxNbPwAAAACqqlo/AAAAALh8Wz8AAAAApkFaPwAAAACtqlo/AAAAAKZBWj8AAAAAsxNbPwAAAAC6fFs/AAAAALl8Wz8AAAAArKpaPwAAAAClQVo/AAAAAKVBWj8AAAAApUFaPwAAAACKnQg/AAAAAJEGCT8AAAAAkgYJPwAAAACKnQg/AAAAAJhvCT8AAAAAl28JPwAAAACRBgk/AAAAAIudCD8AAAAAmG8JPwAAAACDNAg/AAAAAIudCD8AAAAAhDQIPwAAAACSBgk/AAAAAJhvCT8AAAAAkgYJPwAAAACLnQg/AAAAAIQ0CD8AAAAAgzQIPwAAAACENAg/AAAAABukcT8AAAAAIw1yPwAAAAAiDXI/AAAAAB6kcT8AAAAAKnZyPwAAAAApdnI/AAAAACMNcj8AAAAAHKRxPwAAAAAodnI/AAAAABukcT8AAAAAIg1yPwAAAAAodnI/AAAAADDfcj8AAAAAL99yPwAAAAAu33I/AAAAAC/fcj8AAAAAMN9yPwAAAAAodnI/AAAAABukcT8AAAAAb5DmPgAAAACUYuc+AAAAAIti5z4AAAAAa5DmPgAAAACxNOg+AAAAAKY06D4AAAAAhGLnPgAAAABpkOY+AAAAAJo06D4AAAAAUb7lPgAAAAB2kOY+AAAAAEy+5T4AAAAAnWLnPgAAAAC5NOg+AAAAAI406D4AAAAAf2LnPgAAAABRvuU+AAAAAE2+5T4AAAAA4fKtPQAAAAAVO7E9AAAAABQ7sT0AAAAA4fKtPQAAAABJg7Q9AAAAAEqDtD0AAAAAFjuxPQAAAADg8q09AAAAAEqDtD0AAAAA4PKtPQAAAAAXO7E9AAAAAEqDtD0AAAAAfsu3PQAAAAB/y7c9AAAAAH/Ltz0AAAAAf8u3PQAAAAB+y7c9AAAAAEqDtD0AAAAA4PKtPQAAAADHTiw+AAAAAODyLT4AAAAA4PItPgAAAADGTiw+AAAAAPyWLz4AAAAA+5YvPgAAAADh8i0+AAAAAMZOLD4AAAAA/JYvPgAAAADHTiw+AAAAAOHyLT4AAAAA+pYvPgAAAAAUOzE+AAAAABU7MT4AAAAAFTsxPgAAAAAVOzE+AAAAABQ7MT4AAAAA+pYvPgAAAADHTiw+AAAAACGAaT4AAAAA4ZRqPgAAAABmvoU+AAAAAN4ghT4AAAAAn6lrPgAAAADqW4Y+AAAAAFoylj4AAAAArIGVPgAAAAAG45Y+AAAAAAVnTT4AAAAADVxOPgAAAABea2g+AAAAABJRTz4AAAAAFUZQPgAAAABC1KM+AAAAALYToz4AAAAAANGUPgAAAAArU6I+AAAAAFeDhD4AAAAAStKAPgAAAABRpIE+AAAAAEakgT4AAAAAOtKAPgAAAABTdoI+AAAAAEl2gj4AAAAAN6SBPgAAAAAr0oA+AAAAAD52gj4AAAAAU9KAPgAAAABZpIE+AAAAAFZ2gj4AAAAAS0iDPgAAAABMSIM+AAAAAEhIgz4AAAAAQkiDPgAAAAA0doI+AAAAACqkgT4AAAAAHtKAPgAAAADA5Us/AAAAAMdOTD8AAAAAxU5MPwAAAADA5Us/AAAAAM23TD8AAAAAzbdMPwAAAADFTkw/AAAAAL/lSz8AAAAAy7dMPwAAAAC5fEs/AAAAAMDlSz8AAAAAuXxLPwAAAADFTkw/AAAAAMy3TD8AAAAAzLdMPwAAAADFTkw/AAAAAMDlSz8AAAAAuXxLPwAAAAC5fEs/AAAAALp8Sz8AAAAACC1lPgAAAADSQWY+AAAAAEVIgz4AAAAAvKqCPgAAAACZVmc+AAAAAM/lgz4AAAAAom+TPgAAAADyvpI+AAAAAFEglD4AAAAA0ZJJPgAAAADhh0o+AAAAAEAYZD4AAAAA73xLPgAAAAD8cUw+AAAAABTSoD4AAAAAiBGgPgAAAABDDpI+AAAAADINgj4AAAAAmG9pPwAAAACf2Gk/AAAAAKDYaT8AAAAAmG9pPwAAAACmQWo/AAAAAKZBaj8AAAAAnthpPwAAAACYb2k/AAAAAKZBaj8AAAAAkQZpPwAAAACYb2k/AAAAAJEGaT8AAAAAnthpPwAAAACkQWo/AAAAAKRBaj8AAAAAnthpPwAAAACYb2k/AAAAAJAGaT8AAAAAkQZpPwAAAAAGaUA/AAAAAA/SQD8AAAAAD9JAPwAAAAAHaUA/AAAAABQ7QT8AAAAAFjtBPwAAAAAN0kA/AAAAAAZpQD8AAAAAFDtBPwAAAAAHaUA/AAAAAA7SQD8AAAAAFDtBPwAAAAAbpEE/AAAAABqkQT8AAAAAHKRBPwAAAAAbpEE/AAAAABukQT8AAAAAFDtBPwAAAAAO0kA/AAAAAODyHT8AAAAA51sePwAAAADmWx4/AAAAAOHyHT8AAAAA7cQePwAAAADuxB4/AAAAAOZbHj8AAAAA4PIdPwAAAADuxB4/AAAAANqJHT8AAAAA4PIdPwAAAADaiR0/AAAAAOZbHj8AAAAA7MQePwAAAADsxB4/AAAAAODyHT8AAAAA2YkdPwAAAADZiR0/AAAAAHD5Bj8AAAAAdmIHPwAAAAB2Ygc/AAAAAHH5Bj8AAAAAfssHPwAAAAB9ywc/AAAAAHZiBz8AAAAAcPkGPwAAAAB8ywc/AAAAAGmQBj8AAAAAcPkGPwAAAABpkAY/AAAAAHdiBz8AAAAAfssHPwAAAABqkAY/AAAAAGmQBj8AAAAAaZAGPwAAAAA1SHM/AAAAAD6xcz8AAAAAPbFzPwAAAAA3SHM/AAAAAEMadD8AAAAARBp0PwAAAAA9sXM/AAAAADZIcz8AAAAAQxp0PwAAAAA2SHM/AAAAAD2xcz8AAAAAQhp0PwAAAABKg3Q/AAAAAEmDdD8AAAAAS4N0PwAAAABJg3Q/AAAAAEqDdD8AAAAAQhp0PwAAAAA9sXM/AAAAADZIcz8AAAAAJkjjPgAAAAAqGuQ+AAAAAC4a5D4AAAAAKUjjPgAAAAA17OQ+AAAAADrs5D4AAAAANhrkPgAAAAAsSOM+AAAAAEDs5D4AAAAAHnbiPgAAAAAeSOM+AAAAACJ24j4AAAAAJxrkPgAAAAA27OQ+AAAAAEfs5D4AAAAAJ3biPgAAAAAmduI+AAAAABJIAzwAAAAAyokdPAAAAADNiR08AAAAABxIAzwAAAAAecs3PAAAAAB5yzc8AAAAANKJHTwAAAAAJkgDPAAAAAB7yzc8AAAAAIQM0jsAAAAADEgDPAAAAACeDNI7AAAAAMiJHTwAAAAAdcs3PAAAAAAeDVI8AAAAAB8NUjwAAAAAIQ1SPAAAAAAhDVI8AAAAANeJHTwAAAAALUgDPAAAAADjDNI7AAAAAAEN0jsAAAAAwAzSOwAAAAAv3zI+AAAAAEqDND4AAAAASoM0PgAAAAAv3zI+AAAAAGMnNj4AAAAAZCc2PgAAAABKgzQ+AAAAAC/fMj4AAAAAYyc2PgAAAAAv3zI+AAAAAEmDND4AAAAAZCc2PgAAAAB+yzc+AAAAAH7LNz4AAAAAfss3PgAAAAB+yzc+AAAAAH7LNz4AAAAAZSc2PgAAAAAv3zI+AAAAAObZYD4AAAAArO5hPgAAAAAf0oA+AAAAAJY0gD4AAAAAdwNjPgAAAACob4E+AAAAAOaskD4AAAAAOfyPPgAAAACVXZE+AAAAAJ2+RT4AAAAAp7NGPgAAAAAixV8+AAAAALWoRz4AAAAAwp1IPgAAAACKS48+AAAAAMxOnD4AAAAAHC5/PgAAAAA9GoQ+AAAAAC7shD4AAAAAN+yEPgAAAAA/GoQ+AAAAACm+hT4AAAAANb6FPgAAAABA7IQ+AAAAAEAahD4AAAAAQ76FPgAAAAA5GoQ+AAAAACjshD4AAAAAIb6FPgAAAAAxkIY+AAAAADeQhj4AAAAARJCGPgAAAABRkIY+AAAAAFyQhj4AAAAAT76FPgAAAABH7IQ+AAAAAJIGWT8AAAAAmm9ZPwAAAACab1k/AAAAAJMGWT8AAAAAn9hZPwAAAACe2Fk/AAAAAJpvWT8AAAAAkQZZPwAAAACg2Fk/AAAAAIudWD8AAAAAkQZZPwAAAACLnVg/AAAAAJpvWT8AAAAAnthZPwAAAACe2Fk/AAAAAIudWD8AAAAAi51YPwAAAACMnVg/AAAAAKZBSj8AAAAArqpKPwAAAACtqko/AAAAAKdBSj8AAAAAsxNLPwAAAACzE0s/AAAAAKyqSj8AAAAApkFKPwAAAAC0E0s/AAAAAKDYST8AAAAAp0FKPwAAAACh2Ek/AAAAAK2qSj8AAAAAtBNLPwAAAAC0E0s/AAAAAKyqSj8AAAAAn9hJPwAAAACg2Ek/AAAAAE3LTz0AAAAAyoCRPAAAAADdgJE8AAAAAFnLTz0AAAAAtSjZOwAAAADuKNk7AAAAAPOAkTwAAAAAZstPPQAAAAApKdk7AAAAAM1+7j0AAAAARstPPQAAAADRfu49AAAAALqAkTwAAAAAiCjZOwAAAADefu49AAAAANh+7j0AAAAAD9I4PwAAAABYVTU/AAAAAFhVNT8AAAAAD9I4PwAAAADGTjQ/AAAAAMdOND8AAAAAWFU1PwAAAAAO0jg/AAAAAMZOND8AAAAAD9I4PwAAAABWVTU/AAAAAMZOND8AAAAASYM0PwAAAABIgzQ/AAAAAEqDND8AAAAASIM0PwAAAABJgzQ/AAAAAMZOND8AAAAAVVU1PwAAAAAO0jg/AAAAAOCGXD4AAAAAn5tdPgAAAAD+t3w+AAAAAPN8ez4AAAAAX7BePgAAAAAL830+AAAAAC/qjT4AAAAAgzmNPgAAAADbmo4+AAAAAIzqQT4AAAAAkN9CPgAAAAAicls+AAAAAJLUQz4AAAAAlclEPgAAAABCjps+AAAAANeIjD4AAAAA50F6PgAAAAB+y2c/AAAAAIQ0aD8AAAAAhDRoPwAAAAB+y2c/AAAAAImdaD8AAAAAi51oPwAAAACENGg/AAAAAH3LZz8AAAAAip1oPwAAAAB2Ymc/AAAAAH3LZz8AAAAAdWJnPwAAAACENGg/AAAAAIudaD8AAAAAhDRoPwAAAAB2Ymc/AAAAAHZiZz8AAAAAdmJnPwAAAAAjDUI/AAAAACt2Qj8AAAAAJ3ZCPwAAAAAjDUI/AAAAAC7fQj8AAAAAMN9CPwAAAAApdkI/AAAAACMNQj8AAAAAL99CPwAAAAAhDUI/AAAAACl2Qj8AAAAAL99CPwAAAAA2SEM/AAAAADVIQz8AAAAANkhDPwAAAAA1SEM/AAAAADZIQz8AAAAAL99CPwAAAAAhDUI/AAAAAFdVBT8AAAAAXL4FPwAAAABcvgU/AAAAAFZVBT8AAAAAYScGPwAAAABjJwY/AAAAAF2+BT8AAAAAVlUFPwAAAABjJwY/AAAAAE/sBD8AAAAAVVUFPwAAAABQ7AQ/AAAAAF2+BT8AAAAAYycGPwAAAABjJwY/AAAAAF2+BT8AAAAAVVUFPwAAAABQ7AQ/AAAAAE/sBD8AAAAAUewEPwAAAADqnI4+AAAAABVVhT4AAAAAGByNPgAAAAC8sJM+AAAAAGEmeD4AAAAA8ouGPgAAAAB45JQ+AAAAADvGmD4AAAAAmgWRPgAAAADgaoo+AAAAAJTLfT4AAAAAN89mPgAAAAAl81M+AAAAAFcDaT4AAAAAnziBPgAAAAAN8I0+AAAAAJp5mD4AAAAA67OZPgAAAADVV5s+AAAAAEn9nD4AAAAAHQDgPgAAAAAi0uA+AAAAAB7S4D4AAAAAFwDgPgAAAAAlpOE+AAAAACOk4T4AAAAAGNLgPgAAAAAPAOA+AAAAACGk4T4AAAAAFy7fPgAAAAAgAOA+AAAAABEu3z4AAAAAI9LgPgAAAAAfpOE+AAAAAB6k4T4AAAAACADgPgAAAAABLt8+AAAAAP0t3z4AAAAACy7fPgAAAAC8n/E+AAAAABM7sT4AAAAAEjuxPgAAAAC7n/E+AAAAANSsYT4AAAAA1qxhPgAAAAATO7E+AAAAALyf8T4AAAAA2axhPgAAAAA5axM/AAAAALyf8T4AAAAAOWsTPwAAAAASO7E+AAAAANKsYT4AAAAA2qxhPgAAAAAUO7E+AAAAADhrEz8AAAAAN2sTPwAAAACYbzk+AAAAALITOz4AAAAAshM7PgAAAACYbzk+AAAAAMy3PD4AAAAAzbc8PgAAAACzEzs+AAAAAJlvOT4AAAAAy7c8PgAAAACWbzk+AAAAALQTOz4AAAAAzLc8PgAAAADmWz4+AAAAAOhbPj4AAAAA6Fs+PgAAAADmWz4+AAAAALQTOz4AAAAAl285PgAAAAAswF8+AAAAAC2FWz4AAAAAQG95PgAAAABiGHw+AAAAAPSkWj4AAAAASjt5PgAAAAC6rIs+AAAAAH84jD4AAAAA0uiLPgAAAACZREg+AAAAAB68Qj4AAAAA/kxBPgAAAADSlJg+AAAAAHARmD4AAAAA5vaXPgAAAAAu3yI/AAAAADZIIz8AAAAANUgjPwAAAAAv3yI/AAAAAD2xIz8AAAAAPbEjPwAAAAA1SCM/AAAAAC/fIj8AAAAAO7EjPwAAAAAu3yI/AAAAADZIIz8AAAAAPLEjPwAAAAA8sSM/AAAAADZIIz8AAAAAYGKHPgAAAACXNIg+AAAAAJI0iD4AAAAAZWKHPgAAAADPBok+AAAAAMAGiT4AAAAAjTSIPgAAAABtYoc+AAAAALAGiT4AAAAAXmKHPgAAAACcNIg+AAAAANgGiT4AAAAABtmJPgAAAAD52Ik+AAAAAOTYiT4AAAAAytiJPgAAAAChBok+AAAAAIo0iD4AAAAAcWKHPgAAAADFTmw8AAAAADZIgzwAAAAANkiDPAAAAADHTmw8AAAAAAZpkDwAAAAAB2mQPAAAAAA1SIM8AAAAAMZObDwAAAAAB2mQPAAAAADFTmw8AAAAADVIgzwAAAAAB2mQPAAAAADaiZ08AAAAANmJnTwAAAAA2omdPAAAAADZiZ08AAAAADVIgzwAAAAAxk4cPwAAAADNtxw/AAAAAM63HD8AAAAAx04cPwAAAADUIB0/AAAAANIgHT8AAAAAzLccPwAAAADFThw/AAAAANIgHT8AAAAAvuUbPwAAAADFThw/AAAAAL/lGz8AAAAAzbccPwAAAADTIB0/AAAAAM23HD8AAAAAxU4cPwAAAAC/5Rs/AAAAAL/lGz8AAAAAa5CGPQAAAACg2Ik9AAAAAJ/YiT0AAAAAapCGPQAAAADUII09AAAAANQgjT0AAAAAoNiJPQAAAABqkIY9AAAAANMgjT0AAAAAapCGPQAAAACf2Ik9AAAAANQgjT0AAAAAn9iJPQAAAABcvhU/AAAAAGMnFj8AAAAAYicWPwAAAABdvhU/AAAAAGqQFj8AAAAAapAWPwAAAABjJxY/AAAAAFy+FT8AAAAAaZAWPwAAAABVVRU/AAAAAFu+FT8AAAAAVVUVPwAAAABiJxY/AAAAAGqQFj8AAAAAa5AWPwAAAABjJxY/AAAAAFu+FT8AAAAAVlUVPwAAAABWVRU/AAAAAHZiVz8AAAAAfstXPwAAAAB+y1c/AAAAAHliVz8AAAAAhTRYPwAAAACGNFg/AAAAAH/LVz8AAAAAeWJXPwAAAACENFg/AAAAAHD5Vj8AAAAAd2JXPwAAAABx+VY/AAAAAH3LVz8AAAAAhTRYPwAAAACFNFg/AAAAAH3LVz8AAAAAd2JXPwAAAABy+VY/AAAAAHD5Vj8AAAAAPbEDPwAAAABDGgQ/AAAAAEQaBD8AAAAAPLEDPwAAAABKgwQ/AAAAAEqDBD8AAAAAQxoEPwAAAAA8sQM/AAAAAEmDBD8AAAAANkgDPwAAAAA9sQM/AAAAADZIAz8AAAAAQhoEPwAAAABJgwQ/AAAAAEmDBD8AAAAAQhoEPwAAAAA9sQM/AAAAADZIAz8AAAAANkgDPwAAAABQ7HQ/AAAAAFdVdT8AAAAAVlV1PwAAAABQ7HQ/AAAAAF2+dT8AAAAAXL51PwAAAABWVXU/AAAAAFDsdD8AAAAAXb51PwAAAABP7HQ/AAAAAFdVdT8AAAAAXb51PwAAAABkJ3Y/AAAAAGMndj8AAAAAZCd2PwAAAABjJ3Y/AAAAAFdVdT8AAAAAT+x0PwAAAACLnUg/AAAAAJMGST8AAAAAkgZJPwAAAACMnUg/AAAAAJlvST8AAAAAmm9JPwAAAACSBkk/AAAAAIqdSD8AAAAAmW9JPwAAAACFNEg/AAAAAIudSD8AAAAAhDRIPwAAAACTBkk/AAAAAJpvST8AAAAAmG9JPwAAAACSBkk/AAAAAIU0SD8AAAAAhTRIPwAAAACENEg/AAAAAMS33D4AAAAA4IndPgAAAADfid0+AAAAAMa33D4AAAAA/FvePgAAAAD1W94+AAAAANyJ3T4AAAAAybfcPgAAAADwW94+AAAAAKDl2z4AAAAAwbfcPgAAAACl5ds+AAAAAOOJ3T4AAAAAAFzePgAAAACz5ds+AAAAALnl2z4AAAAAreXbPgAAAADBiC8/AAAAAAyvLD8AAAAADK8sPwAAAADCiC8/AAAAAF8+JD8AAAAAXT4kPwAAAAANryw/AAAAAMGILz8AAAAAXT4kPwAAAAD7li8/AAAAAMOILz8AAAAA+5YvPwAAAAAOryw/AAAAAF4+JD8AAAAAXT4kPwAAAAANryw/AAAAAPuWLz8AAAAA/JYvPwAAAABQ7DQ/AAAAAFZVNT8AAAAAVlU1PwAAAABQ7DQ/AAAAAF2+NT8AAAAAXL41PwAAAABWVTU/AAAAAE/sND8AAAAAXr41PwAAAABQ7DQ/AAAAAFZVNT8AAAAAXL41PwAAAABkJzY/AAAAAGMnNj8AAAAAZCc2PwAAAABjJzY/AAAAAGQnNj8AAAAAUOw0PwAAAAABAEA+AAAAAB2kQT4AAAAAHKRBPgAAAAACAEA+AAAAADZIQz4AAAAANkhDPgAAAAAcpEE+AAAAAAEAQD4AAAAANkhDPgAAAAAAAEA+AAAAAB6kQT4AAAAANkhDPgAAAABR7EQ+AAAAAFDsRD4AAAAAUexEPgAAAABR7EQ+AAAAAE/sRD4AAAAANkhDPgAAAAAepEE+AAAAAAEAQD4AAAAAPLFDPwAAAABEGkQ/AAAAAEMaRD8AAAAAPbFDPwAAAABKg0Q/AAAAAEqDRD8AAAAAQxpEPwAAAAA9sUM/AAAAAEuDRD8AAAAAPLFDPwAAAABCGkQ/AAAAAEmDRD8AAAAAUOxEPwAAAABQ7EQ/AAAAAFDsRD8AAAAAUexEPwAAAABJg0Q/AAAAAEIaRD8AAAAACquKPgAAAAADfYs+AAAAAPN8iz4AAAAA8qqKPgAAAADyTow+AAAAAOZOjD4AAAAA3nyLPgAAAADaqoo+AAAAANxOjD4AAAAAF6uKPgAAAAAPfYs+AAAAAPdOjD4AAAAA1iCNPgAAAADXII0+AAAAANYgjT4AAAAA1SCNPgAAAADUII0+AAAAANFOjD4AAAAAxKqKPgAAAADnWy4/AAAAAO3ELj8AAAAA7MQuPwAAAADoWy4/AAAAAPQtLz8AAAAA9S0vPwAAAADuxC4/AAAAAOZbLj8AAAAA9S0vPwAAAADg8i0/AAAAAOdbLj8AAAAA4fItPwAAAADuxC4/AAAAAPQtLz8AAAAA8y0vPwAAAADuxC4/AAAAAOdbLj8AAAAA3/ItPwAAAADh8i0/AAAAALETuz0AAAAA6Fu+PQAAAADoW749AAAAALMTuz0AAAAAHaTBPQAAAAAcpME9AAAAAOdbvj0AAAAAtBO7PQAAAAAcpME9AAAAALMTuz0AAAAA51u+PQAAAAAdpME9AAAAAFDsxD0AAAAAUOzEPQAAAABR7MQ9AAAAAE/sxD0AAAAAUOzEPQAAAAAdpME9AAAAALMTuz0AAAAAJzZmPwAAAADMlGY/AAAAAMmUZj8AAAAAKjZmPwAAAAD7+WY/AAAAAP35Zj8AAAAAypRmPwAAAAAoNmY/AAAAAPz5Zj8AAAAAXuFlPwAAAAAmNmY/AAAAAGDhZT8AAAAAy5RmPwAAAAD9+WY/AAAAAP35Zj8AAAAAy5RmPwAAAAAoNmY/AAAAAF7hZT8AAAAAX+FlPwAAAABh4WU/AAAAAFZVRT8AAAAAX75FPwAAAABdvkU/AAAAAFdVRT8AAAAAYydGPwAAAABkJ0Y/AAAAAF6+RT8AAAAAVVVFPwAAAABiJ0Y/AAAAAFlVRT8AAAAAXr5FPwAAAABlJ0Y/AAAAAGqQRj8AAAAAa5BGPwAAAABqkEY/AAAAAGqQRj8AAAAAZSdGPwAAAABXVUU/AAAAAKuqqjwAAAAAfsu3PAAAAAB8y7c8AAAAAKyqqjwAAAAAUezEPAAAAABR7MQ8AAAAAH3LtzwAAAAAq6qqPAAAAABR7MQ8AAAAAKuqqjwAAAAAfsu3PAAAAABP7MQ8AAAAACIN0jwAAAAAIQ3SPAAAAAAjDdI8AAAAACMN0jwAAAAAT+zEPAAAAAB+y7c8AAAAACANAj8AAAAAKHYCPwAAAAApdgI/AAAAACENAj8AAAAAL98CPwAAAAAu3wI/AAAAACl2Aj8AAAAAIQ0CPwAAAAAv3wI/AAAAABukAT8AAAAAIQ0CPwAAAAAapAE/AAAAACh2Aj8AAAAAL98CPwAAAAAodgI/AAAAABukAT8AAAAAGqQBPwAAAABqkHY/AAAAAHH5dj8AAAAAcPl2PwAAAABpkHY/AAAAAHdidz8AAAAAdmJ3PwAAAABx+XY/AAAAAGqQdj8AAAAAd2J3PwAAAABqkHY/AAAAAHH5dj8AAAAAd2J3PwAAAAB9y3c/AAAAAH7Ldz8AAAAAf8t3PwAAAAB9y3c/AAAAAH3Ldz8AAAAAd2J3PwAAAABgb9k+AAAAAHdB2j4AAAAAgUHaPgAAAABwb9k+AAAAAI0T2z4AAAAAlhPbPgAAAACPQdo+AAAAAH1v2T4AAAAAoRPbPgAAAABAndg+AAAAAFVv2T4AAAAATJ3YPgAAAABqQdo+AAAAAIMT2z4AAAAApxPbPgAAAABtndg+AAAAAFyd2D4AAAAAapBGPgAAAACGNEg+AAAAAIU0SD4AAAAAapBGPgAAAACf2Ek+AAAAAKDYST4AAAAAhTRIPgAAAABqkEY+AAAAAKDYST4AAAAAa5BGPgAAAACFNEg+AAAAAKHYST4AAAAAu3xLPgAAAAC6fEs+AAAAALp8Sz4AAAAAuXxLPgAAAAC5fEs+AAAAAKDYST4AAAAAhDRIPgAAAABrkEY+AAAAAL3yjT4AAAAAqMSOPgAAAAC5xI4+AAAAAMbyjT4AAAAAn5aPPgAAAAC2lo8+AAAAAMvEjj4AAAAA0PKNPgAAAADOlo8+AAAAALTyjT4AAAAAmMSOPgAAAACNlo8+AAAAAJhokD4AAAAAqWiQPgAAAADBaJA+AAAAANpokD4AAAAAW75VPwAAAABkJ1Y/AAAAAGQnVj8AAAAAXb5VPwAAAABrkFY/AAAAAGuQVj8AAAAAYydWPwAAAABcvlU/AAAAAGmQVj8AAAAAXb5VPwAAAABjJ1Y/AAAAAGqQVj8AAAAAapBWPwAAAABjJ1Y/AAAAAF2+VT8AAAAAcflGPwAAAAB4Ykc/AAAAAHdiRz8AAAAAcvlGPwAAAAB9y0c/AAAAAH/LRz8AAAAAeWJHPwAAAABw+UY/AAAAAHzLRz8AAAAAcflGPwAAAAB4Ykc/AAAAAH/LRz8AAAAAeGJHPwAAAADOtyw/AAAAANQgLT8AAAAA1SAtPwAAAADNtyw/AAAAANmJLT8AAAAA24ktPwAAAADTIC0/AAAAAMy3LD8AAAAA2YktPwAAAADFTiw/AAAAAM23LD8AAAAAx04sPwAAAADTIC0/AAAAANyJLT8AAAAA2oktPwAAAADTIC0/AAAAAMZOLD8AAAAAxU4sPwAAAADGTiw/AAAAAGmQNj8AAAAAcPk2PwAAAABx+TY/AAAAAGuQNj8AAAAAd2I3PwAAAAB3Yjc/AAAAAHH5Nj8AAAAAapA2PwAAAAB3Yjc/AAAAAGmQNj8AAAAAcfk2PwAAAAB4Yjc/AAAAAGmQNj8AAAAAXiFlPwAAAAC3WWU/AAAAALdZZT8AAAAAXyFlPwAAAACemGU/AAAAAJ+YZT8AAAAAuFllPwAAAABgIWU/AAAAAJ6YZT8AAAAATuxkPwAAAABdIWU/AAAAAE3sZD8AAAAAtlllPwAAAACdmGU/AAAAAJ2YZT8AAAAAt1llPwAAAABfIWU/AAAAAFDsZD8AAAAAT+xkPwAAAABP7GQ/AAAAAPUt3zwAAAAAyU7sPAAAAADHTuw8AAAAAPct3zwAAAAAmW/5PAAAAACbb/k8AAAAAMhO7DwAAAAA9C3fPAAAAACab/k8AAAAAPUt3zwAAAAAyU7sPAAAAACZb/k8AAAAADZIAz0AAAAANUgDPQAAAAA2SAM9AAAAADZIAz0AAAAAmW/5PAAAAAD1Ld88AAAAAAZpAD8AAAAADtIAPwAAAAAN0gA/AAAAAAdpAD8AAAAAFDsBPwAAAAAVOwE/AAAAAA7SAD8AAAAABmkAPwAAAAAUOwE/AAAAAAAAAD8AAAAABmkAPwAAAAAAAAA/AAAAAA3SAD8AAAAAFDsBPwAAAAAO0gA/AAAAAAAAAD8AAAAAAAAAPwAAAAABAAA/AAAAAIQ0eD8AAAAAi514PwAAAACMnXg/AAAAAIU0eD8AAAAAkgZ5PwAAAACSBnk/AAAAAIqdeD8AAAAAhjR4PwAAAACRBnk/AAAAAIQ0eD8AAAAAjJ14PwAAAACRBnk/AAAAAJEGeT8AAAAAjJ14PwAAAACENHg/AAAAAPuW7z0AAAAAL9/yPQAAAAAv3/I9AAAAAPqW7z0AAAAAZCf2PQAAAABlJ/Y9AAAAAC7f8j0AAAAA+5bvPQAAAABkJ/Y9AAAAAPuW7z0AAAAAMN/yPQAAAABjJ/Y9AAAAAJdv+T0AAAAAl2/5PQAAAACZb/k9AAAAAJdv+T0AAAAAmG/5PQAAAAAw3/I9AAAAAPuW7z0AAAAAKyfWPgAAAAAu+dY+AAAAAED51j4AAAAAOyfWPgAAAAA8y9c+AAAAAE7L1z4AAAAAU/nWPgAAAABJJ9Y+AAAAAF7L1z4AAAAAICfWPgAAAAAi+dY+AAAAAC3L1z4AAAAAYfnWPgAAAABUJ9Y+AAAAANIgTT4AAAAA78ROPgAAAADuxE4+AAAAANQgTT4AAAAACWlQPgAAAAAIaVA+AAAAAO7ETj4AAAAA0yBNPgAAAAAHaVA+AAAAANUgTT4AAAAA7sROPgAAAAAIaVA+AAAAAAhpUD4AAAAA7sROPgAAAADVIE0+AAAAAMo6kT4AAAAA+wySPgAAAAACDZI+AAAAAN06kT4AAAAAL9+SPgAAAAAs35I+AAAAAA0Nkj4AAAAA8DqRPgAAAAAt35I+AAAAAL06kT4AAAAA9gySPgAAAAAy35I+AAAAAC3fkj4AAAAAq6oaPwAAAACzExs/AAAAALITGz8AAAAArKoaPwAAAAC5fBs/AAAAALp8Gz8AAAAAsxMbPwAAAACqqho/AAAAALd8Gz8AAAAAqqoaPwAAAACyExs/AAAAALh8Gz8AAAAAuHwbPwAAAACqqho/AAAAALETKz8AAAAAuXwrPwAAAAC5fCs/AAAAALETKz8AAAAAweUrPwAAAADB5Ss/AAAAALh8Kz8AAAAAshMrPwAAAAC+5Ss/AAAAALMTKz8AAAAAuXwrPwAAAAC/5Ss/AAAAALl8Kz8AAAAAsxMrPwAAAACGNMg9AAAAALt8yz0AAAAAuHzLPQAAAACFNMg9AAAAAO7Ezj0AAAAA7sTOPQAAAAC5fMs9AAAAAIY0yD0AAAAA78TOPQAAAACENMg9AAAAALx8yz0AAAAA78TOPQAAAAC7fMs9AAAAAKTeYj8AAAAA10NjPwAAAADWQ2M/AAAAAKTeYj8AAAAAdqJjPwAAAAB3omM/AAAAANZDYz8AAAAApN5iPwAAAAB3omM/AAAAAKPeYj8AAAAA1UNjPwAAAAB3omM/AAAAAED3Yz8AAAAAQfdjPwAAAABC92M/AAAAAED3Yz8AAAAAQPdjPwAAAACj3mI/AAAAAEMaFD8AAAAASYMUPwAAAABIgxQ/AAAAAEMaFD8AAAAAUOwUPwAAAABP7BQ/AAAAAEmDFD8AAAAAQhoUPwAAAABQ7BQ/AAAAAEIaFD8AAAAASYMUPwAAAABO7BQ/AAAAAE/sFD8AAAAASoMUPwAAAABCGhQ/AAAAAJ/YCT0AAAAACGkQPQAAAAAHaRA9AAAAAJ7YCT0AAAAAcfkWPQAAAABw+RY9AAAAAAdpED0AAAAAn9gJPQAAAABx+RY9AAAAAJ7YCT0AAAAAB2kQPQAAAABw+RY9AAAAAHD5Fj0AAAAAB2kQPQAAAACe2Ak9AAAAANuJ/T4AAAAA6Vv+PgAAAADoW/4+AAAAANyJ/T4AAAAA9S3/PgAAAAD0Lf8+AAAAAOdb/j4AAAAA2on9PgAAAADyLf8+AAAAANqJ/T4AAAAA6Fv+PgAAAADzLf8+AAAAAPMt/z4AAAAA51v+PgAAAADOt/w9AAAAAAEAAD4AAAAAAQAAPgAAAADNt/w9AAAAABukAT4AAAAAG6QBPgAAAAABAAA+AAAAAMy3/D0AAAAAG6QBPgAAAADNt/w9AAAAAAEAAD4AAAAAHKQBPgAAAAABAAA+AAAAAM23/D0AAAAAJ3obPQAAAADwWiY9AAAAAK6BrTwAAAAAIZuJPAAAAADCkTE9AAAAAAVjkDwAAAAAdhQRPAAAAAAgm4k8AAAAAHrhrT0AAAAAXgG0PQAAAACNx3g8AAAAAFxm1z0AAAAAtTY/PQAAAACe0cM9AAAAAHlQ6TsAAAAARBwpPgAAAACOnIM+AAAAAF5Haz4AAAAAIA0mPgAAAAB8qq4+AAAAABeMiD4AAAAAgiU1PgAAAADoiy4+AAAAALVujD4AAAAAXQG0PQAAAABatME+AAAAABhvnD4AAAAAtm6MPgAAAACf0cM9AAAAAIDEST4AAAAApO9MPgAAAACWxpI+AAAAAAC+dj4AAAAA7BExPgAAAABWgbQ+AAAAAPynhj4AAAAAlMaSPgAAAAD3ri0+AAAAAIalgj4AAAAAmMjuPQAAAABksbI+AAAAAFHCyT0AAAAAxTnePgAAAADniy4+AAAAADkhrz4AAAAAgUrfPgAAAADe2+s+AAAAAGqh0z4AAAAArewGPwAAAAB11QY/AAAAAIBK3z4AAAAAgEP9PgAAAAB21QY/AAAAABbBnD4AAAAA0QPXPgAAAABgdxk/AAAAAPo8Gj8AAAAA8zMFPwAAAADQA9c+AAAAADG1ED8AAAAA/1yuPgAAAAD2ytM+AAAAAOkL6z4AAAAA8VjePgAAAAD7rQA/AAAAAIPOBj8AAAAA9crTPgAAAAB2bwY/AAAAAEtdgj4AAAAAGMGcPgAAAABjl7Q+AAAAANJd6D4AAAAA0GcZPwAAAABil7Q+AAAAAB3HGT8AAAAAWvdOPgAAAACSupY+AAAAAN1Agj4AAAAAPXA8PgAAAAAEgMI+AAAAAEa0lj4AAAAA7DZPPgAAAAA7cDw+AAAAABFSfz4AAAAAadWzPgAAAADkH+g+AAAAAGjVsz4AAAAAKRClPgAAAAC6YtA+AAAAAHm85D4AAAAAOKvQPgAAAAAnLf8+AAAAADdABD8AAAAAuWLQPgAAAABt2f8+AAAAADZABD8AAAAAV4t/PgAAAAARjbM+AAAAAFk25z4AAAAA4x/oPgAAAAAd6VE+AAAAAHlIlz4AAAAAsyGDPgAAAADnbz8+AAAAAGotwj4AAAAA+/+WPgAAAAB6SJc+AAAAAI+QUD4AAAAA6G8/PgAAAAD6/5Y+AAAAADivgD4AAAAAadWzPgAAAAA1jeg9AAAAAFg25z4AAAAAtRnnPgAAAAAQjbM+AAAAAGrVsz4AAAAAWIt/PgAAAAD0WaU+AAAAAEXRzz4AAAAAE8XjPgAAAADFGdA+AAAAALGu/T4AAAAAUGoDPwAAAABE0c8+AAAAAPVa/j4AAAAAxBnQPgAAAABOagM/AAAAAN3LgD4AAAAAEY2zPgAAAAApMOY+AAAAALYZ5z4AAAAAMwQUPwAAAAAJ5lQ+AAAAAO3Zlz4AAAAAFhmEPgAAAACGx0I+AAAAAJ/jwT4AAAAAbZGXPgAAAAB+jVM+AAAAAIXHQj4AAAAAbpGXPgAAAABotYE+AAAAAGvVsz4AAAAAQjryPQAAAAAoMOY+AAAAAIYT5j4AAAAA3MuAPgAAAAC/o6U+AAAAANI/zz4AAAAArs3iPgAAAABRiM8+AAAAADgw/D4AAAAAaJQCPwAAAADTP88+AAAAAH/c/D4AAAAAC9KBPgAAAABntYE+AAAAAA+Nsz4AAAAA+inlPgAAAAAkzxQ/AAAAAPfiVz4AAAAAYGuYPgAAAAB8EIU+AAAAACEfRj4AAAAA05nBPgAAAADhIpg+AAAAAGFrmD4AAAAAa4pWPgAAAACWu4I+AAAAAGjVsz4AAAAA+SnlPgAAAABXDeU+AAAAAA6Nsz4AAAAAZ9WzPgAAAACL7aU+AAAAAF2uzj4AAAAAS9bhPgAAAADc9s4+AAAAAMOx+j4AAAAAgL4BPwAAAAAHXvs+AAAAAIG+AT8AAAAAO9iCPgAAAACXu4I+AAAAABCNsz4AAAAAyiPkPgAAAAAPjbM+AAAAAOTfWj4AAAAA1PyYPgAAAADiB4Y+AAAAAL52ST4AAAAAB1DBPgAAAABVtJg+AAAAAFaHWT4AAAAAvXZJPgAAAABUtJg+AAAAAMbBgz4AAAAAatWzPgAAAADJI+Q+AAAAACcH5D4AAAAAVjemPgAAAADqHM4+AAAAAOTe4D4AAAAAaGXOPgAAAABNM/k+AAAAAJjoAD8AAAAA6RzOPgAAAACS3/k+AAAAAJnoAD8AAAAAat6DPgAAAAAPjbM+AAAAAJwd4z4AAAAAEI2zPgAAAAAmB+Q+AAAAAGXGYj4AAAAAXl6aPgAAAAAwWYc+AAAAAOIsTj4AAAAAnCDBPgAAAADxU5k+AAAAANGwXD4AAAAA4SxOPgAAAADyU5k+AAAAAMmYiz4AAAAAw8u1PgAAAACbHeM+AAAAAMM/4z4AAAAAxMu1PgAAAAA8g7Q+AAAAADa14T4AAAAA9nboPgAAAADoJdI+AAAAAGTHBz8AAAAAeMIDPwAAAAA1teE+AAAAAPSw+T4AAAAA6SXSPgAAAAB5wgM/AAAAAJ0Krj4AAAAACWjlPgAAAAB/8Q0/AAAAAAho5T4AAAAAocQPPwAAAAC5YZg+AAAAAHXc1j4AAAAAxeK5PgAAAADYL4o+AAAAAB3sBz8AAAAAK7nRPgAAAADvrZE+AAAAANcvij4AAAAAKrnRPgAAAADB4Ls+AAAAAK5c/z4AAAAAFacvPgAAAABVTB0/AAAAAH4KIz8AAAAAdm7vPgAAAACvXP8+AAAAAFJTqT4AAAAAd27vPgAAAACXhyM/AAAAAOVLID8AAAAAezgLPwAAAADKogM/AAAAABweFz8AAAAA6wf8PgAAAAB7ws8+AAAAACLkQD8AAAAAVEwdPwAAAAD6NTg/AAAAAMWqLz8AAAAA+zU4PwAAAABra/U+AAAAAA/gGT8AAAAAW7oiPwAAAACr9RM/AAAAADcNOD8AAAAAEYs5PwAAAAAO4Bk/AAAAAKzmMj8AAAAArPUTPwAAAAASizk/AAAAAO703z4AAAAAGtkUPwAAAACwXP8+AAAAAAa6NT8AAAAAG9kUPwAAAAD8jk8/AAAAALzvUT8AAAAAhMNcPwAAAAB+SVE/AAAAABC3Uj8AAAAAieZaPwAAAAAr+0I/AAAAABSKST8AAAAA6sRSPwAAAACI5lo/AAAAABOKST8AAAAARb5cPwAAAADaf2U/AAAAADywUD8AAAAAu3RjPwAAAADr4EE/AAAAAD2wUD8AAAAAI+RAPwAAAAC8dGM/AAAAAAyKXj8AAAAAphFUPwAAAAALk1c/AAAAAJEmXz8AAAAApn9JPwAAAADZnVM/AAAAAKgRVD8AAAAAWu9dPwAAAACTO2c/AAAAAOEJXj8AAAAA3jlnPwAAAAB+K1I/AAAAAOzgQT8AAAAAeA1EPwAAAACAhGY/AAAAAEa+XD8AAAAAoDlnPwAAAABAXP8+AAAAAACLGj8AAAAAY8kkPwAAAAC83Ro/AAAAAN0sNz8AAAAAuQc6PwAAAABqwzc/AAAAAL3dGj8AAAAAugc6PwAAAADTzuE+AAAAAFpmFD8AAAAAHNkUPwAAAACVv08/AAAAAHmPND8AAAAA6B1RPwAAAABbZhQ/AAAAAAW6NT8AAAAA8nRQPwAAAAASyV8/AAAAAEgQVT8AAAAATq1YPwAAAAB5a2A/AAAAACxdSj8AAAAAF7NUPwAAAAA1MV8/AAAAADapaD8AAAAA4j5fPwAAAAB2qWg/AAAAAOHxUj8AAAAAJ6toPwAAAAB5DUQ/AAAAAAMhRD8AAAAAfytSPwAAAADg8VI/AAAAAJE7Zz8AAAAAutD9PgAAAAB9dhk/AAAAACKvIz8AAAAAj+kZPwAAAAAZ6zU/AAAAANDCOD8AAAAAfnYZPwAAAACzhTY/AAAAAJDpGT8AAAAA0cI4PwAAAACqmN0+AAAAANLO4T4AAAAA7vASPwAAAAAl8kw/AAAAAPxPTj8AAAAAl0QzPwAAAABgrE8/AAAAAMtfTj8AAAAAWwVPPwAAAAABRF4/AAAAABX4Uj8AAAAAzoNYPwAAAAAy3WA/AAAAAI/7SD8AAAAApRNVPwAAAAAW+FI/AAAAAOhHYD8AAAAAMd1gPwAAAACmE1U/AAAAAEd8WD8AAAAAzXFoPwAAAAAGgUs/AAAAACbKPT8AAAAAwlRpPwAAAADhPl8/AAAAAGRS8T4AAAAApZIQPwAAAAB7Yh8/AAAAAEtFFz8AAAAANawtPwAAAAC8aDU/AAAAABLeND8AAAAASkUXPwAAAACuD7k+AAAAANxp+T4AAAAA7fASPwAAAAC+zh0/AAAAANtp+T4AAAAAJw5NPwAAAAB1ak8/AAAAAMTRRD8AAAAAt7c/PwAAAAC0fkQ/AAAAAA9hOT8AAAAAb8k2PwAAAADD0UQ/AAAAALE2OD8AAAAAcMk2PwAAAAB8oVg/AAAAAEZ8WD8AAAAA9hNMPwAAAAAHgUs/AAAAAGvuPz8AAAAA9xNMPwAAAAAlyj0/AAAAAC8lLT8AAAAAmV8tPwAAAAC0Tpg+AAAAACjy0z4AAAAAxZa5PgAAAAAeoos+AAAAALq7BT8AAAAAwHrTPgAAAABuHJc+AAAAANswuz4AAAAAzR/6PgAAAABGxx0/AAAAAMwf+j4AAAAAD9BhPwAAAABEcFY/AAAAAFRuWT8AAAAABNthPwAAAADNs0o/AAAAAAO0Uz8AAAAAQ3BWPwAAAAAvw14/AAAAAAPbYT8AAAAABLRTPwAAAAALTms/AAAAAFNkYT8AAAAAYfVUPwAAAADbHEc/AAAAAH2hWD8AAAAABOxqPwAAAACe7/M+AAAAABxPGD8AAAAAb40fPwAAAACf1BA/AAAAAILsND8AAAAAg/Q0PwAAAAAbTxg/AAAAACRZLT8AAAAAntQQPwAAAACC9DQ/AAAAAPxn4z4AAAAA5AUWPwAAAAB+WEw/AAAAAHxbTD8AAAAAWcw0PwAAAADjBRY/AAAAAEfHHT8AAAAATRxIPwAAAADPCEw/AAAAAKI1Yz8AAAAA+ghYPwAAAAAEuVs/AAAAACPmYz8AAAAA/3VNPwAAAABwplc/AAAAAPkIWD8AAAAAGZ1iPwAAAABxplc/AAAAAK6eYj8AAAAAuMNsPwAAAACO5lU/AAAAADLNbD8AAAAANatHPwAAAACN5lU/AAAAAFsObD8AAAAAVWRhPwAAAABg9VQ/AAAAAIGzAz8AAAAA7ZwfPwAAAAB9pDE/AAAAAPINID8AAAAA5ao5PwAAAAD5+kM/AAAAADRVRD8AAAAAQXc6PwAAAABsNk8/AAAAABxJ4j4AAAAA9wsVPwAAAABjdzM/AAAAAB8GTj8AAAAAOkBTPwAAAAC4qlg/AAAAAFfbUz8AAAAAWRZPPwAAAAB/WEw/AAAAAOIFFj8AAAAAA3lhPwAAAABJslU/AAAAACF2Wz8AAAAAUUdkPwAAAABj9Us/AAAAAPP/Vz8AAAAASrJVPwAAAABPsWM/AAAAAPL/Vz8AAAAAiDtbPwAAAADlamw/AAAAAOLMTT8AAAAA+r1tPwAAAABIy0A/AAAAANhtbT8AAAAAr55iPwAAAAB9a/E+AAAAABbWDj8AAAAA/4MdPwAAAACtuxY/AAAAAOOiKj8AAAAA1oQyPwAAAAAEADM/AAAAACR3uT4AAAAA+a32PgAAAAA5LRs/AAAAAAMxST8AAAAALLxKPwAAAABidzM/AAAAABwgSj8AAAAA9gsVPwAAAAC+Z1E/AAAAAPPuRT8AAAAADaJAPwAAAACkCUY/AAAAALmYOT8AAAAA3jk3PwAAAADx7kU/AAAAAIHQOT8AAAAAowlGPwAAAADfOTc/AAAAAFJMWz8AAAAAijtbPwAAAAB4vE0/AAAAANycQD8AAAAAI9UuPwAAAADkxJc+AAAAAHq50T4AAAAAb1W4PgAAAAB24Is+AAAAALHQAz8AAAAAmpnRPgAAAABQlJc+AAAAAGDRuD4AAAAAyElHPgAAAADre/Y+AAAAAFVTOT4AAAAAOi0bPwAAAABCFxs/AAAAAPit9j4AAAAA7Hv2PgAAAABJKmU/AAAAACrlWD8AAAAAZCNcPwAAAAB+O2U/AAAAAE88TD8AAAAA0vZVPwAAAAAr5Vg/AAAAAATpYT8AAAAAfztlPwAAAACFYG8/AAAAALavZD8AAAAAtEZXPwAAAAC6BG8/AAAAANucQD8AAAAAC1dIPwAAAAB5vE0/AAAAALNGVz8AAAAAU0xbPwAAAAC5BG8/AAAAAGs97j4AAAAAYAMUPwAAAACSDBw/AAAAAIAjDj8AAAAA8A0wPwAAAAAHFjE/AAAAAG4ZKj8AAAAAgSMOPwAAAADWfdo+AAAAAJVgDz8AAAAA6nv2PgAAAABT7C0/AAAAAJZgDz8AAAAAQRcbPwAAAAC1rkc/AAAAAAWTZj8AAAAARYpaPwAAAAB2h14/AAAAACpXZz8AAAAA4ChPPwAAAAC9J1o/AAAAAH36ZT8AAAAAvCdaPwAAAAAO6mU/AAAAAPndcD8AAAAA3jdYPwAAAABi5Ug/AAAAAN83WD8AAAAAmyhwPwAAAAC3r2Q/AAAAANxI9z4AAAAAGIwUPwAAAACoHh4/AAAAAKPuFD8AAAAAZzMvPwAAAAC74jE/AAAAABqMFD8AAAAA78svPwAAAAC84jE/AAAAACVh2T4AAAAA1X3aPgAAAABqbw4/AAAAAPqxLD8AAAAATWhHPwAAAADWOkY/AAAAANfQRj8AAAAATGhHPwAAAADanmQ/AAAAABj1Vz8AAAAAMytePwAAAADMp2c/AAAAAOV9TT8AAAAA2HRaPwAAAACIC2c/AAAAANl0Wj8AAAAAXuZdPwAAAAACZHA/AAAAAGJ1Tz8AAAAArtZxPwAAAABj5Ug/AAAAALd5QT8AAAAAK85wPwAAAADvhnE/AAAAAA/qZT8AAAAAPLrrPgAAAAA7JQw/AAAAAMMEGj8AAAAAsnMSPwAAAACcYyc/AAAAALupLj8AAAAAsSwuPwAAAACpF7c+AAAAACZh2T4AAAAAGQrzPgAAAABpbw4/AAAAADd9GD8AAAAAwNxEPwAAAAAaCvM+AAAAAPmxLD8AAAAA/z1FPwAAAADsS1M/AAAAADm0Rj8AAAAA/ClBPwAAAABTF0c/AAAAALbQOD8AAAAAe+o2PwAAAAA4tEY/AAAAAMzvOT8AAAAAVBdHPwAAAAB86jY/AAAAAO7kXT8AAAAAX+ZdPwAAAAAx004/AAAAAGF1Tz8AAAAAiD8/PwAAAADbuJc+AAAAAD6tzz4AAAAAAAK3PgAAAACE+4s+AAAAAOziAT8AAAAAFF7PPgAAAAA8rc8+AAAAAAMGlz4AAAAAg/uLPgAAAAAVXs8+AAAAAEaytz4AAAAAaIlKPgAAAABMUfM+AAAAADZ9GD8AAAAA0W4YPwAAAABLUfM+AAAAAKoXtz4AAAAATyFkPwAAAABrjVc/AAAAAPU6XT8AAAAAATtnPwAAAADPtUo/AAAAAFJLVz8AAAAAbI1XPwAAAAAjzGQ/AAAAAFBLVz8AAAAAmMdnPwAAAAAxjl0/AAAAABU4UD8AAAAAAahxPwAAAACJPz8/AAAAAOe0QD8AAAAA7+RdPwAAAAD/p3E/AAAAAEc26z4AAAAAJo4RPwAAAACxXhk/AAAAALbuCz8AAAAAs7MsPwAAAACtti0/AAAAAGP1Jj8AAAAAr7YtPwAAAACvltU+AAAAALGvDD8AAAAAl0xDPwAAAAD+lCo/AAAAALKvDD8AAAAA024YPwAAAADpIUA/AAAAAEpR8z4AAAAAApZDPwAAAACZMEA/AAAAAMTHPD8AAAAA8z5GPwAAAADazks/AAAAAMinPD8AAAAA+ShKPwAAAADDxzw/AAAAAPBtVT8AAAAA5QY1PwAAAAAekkQ/AAAAAGQaMj8AAAAA9O5RPwAAAAAW5S8/AAAAAGMaMj8AAAAAMI5dPwAAAAAWOFA/AAAAAHIp6j4AAAAAiOUKPwAAAADNahg/AAAAAFj/ED8AAAAAc3ElPwAAAAAoiyw/AAAAAIflCj8AAAAAWhEsPwAAAABZ/xA/AAAAACmLLD8AAAAAQ/K2PgAAAAAQefE+AAAAALfnFj8AAAAAQDNCPwAAAAAAlSo/AAAAADeUQj8AAAAAJ0+YPgAAAADt4s4+AAAAAL3Ztj4AAAAALuqMPgAAAACE2gA/AAAAAIilzj4AAAAAPMWXPgAAAAAw6ow+AAAAAImlzj4AAAAAun23PgAAAACBMk4+AAAAAMql8T4AAAAAILhAPgAAAACq1xY/AAAAAA958T4AAAAAy6XxPgAAAADTEy0/AAAAAO7fJz8AAAAA0jsnPwAAAACgwCo/AAAAAFsKJD8AAAAAhZwkPwAAAADv3yc/AAAAADEUKD8AAAAA3r8uPwAAAADkBjU/AAAAAHFeKT8AAAAANEolPwAAAABwXik/AAAAADkMIj8AAAAAtrvpPgAAAACSHxA/AAAAAMe/Fz8AAAAAWKUKPwAAAAAOmSo/AAAAAFKXKz8AAAAAkx8QPwAAAAABAiU/AAAAAFmlCj8AAAAAB6LUPgAAAAA/Xgs/AAAAAIeDPz8AAAAAyqJAPwAAAADMhSg/AAAAAKvXFj8AAAAAzKXxPgAAAACB7EA/AAAAAMnjLT8AAAAARqQqPwAAAAAdHiw/AAAAADzCLj8AAAAAe7QnPwAAAABB9Co/AAAAAEWkKj8AAAAA/A4vPwAAAAA9wi4/AAAAAED0Kj8AAAAAzkwsPwAAAADx2zA/AAAAAKKvKD8AAAAA37ExPwAAAACDISU/AAAAAACqKT8AAAAApYMmPwAAAAB2HyU/AAAAANSgJj8AAAAAhh4jPwAAAAAOlCI/AAAAAKSDJj8AAAAA2l4jPwAAAADVoCY/AAAAAA2UIj8AAAAAOF4sPwAAAADNTCw/AAAAADikKD8AAAAAaAIlPwAAAACEISU/AAAAAPrfHz8AAAAA4K7oPgAAAAAonAk/AAAAAODLFj8AAAAAxZAPPwAAAAARfiM/AAAAAMtrKj8AAAAAt/YpPwAAAAC4vbY+AAAAAJHN7z4AAAAAQF4LPwAAAACQUBU/AAAAAL+JPz8AAAAAiYM/PwAAAADAiT8/AAAAANqNLz8AAAAA9wEsPwAAAABE0Sw/AAAAAG9iLz8AAAAAmVQoPwAAAABY/io/AAAAAPgBLD8AAAAAuksuPwAAAABZ/io/AAAAAA/AMj8AAAAAAKIvPwAAAAD9rSs/AAAAAJQnMj8AAAAAaQIlPwAAAAC1Mic/AAAAAP6tKz8AAAAAlScyPwAAAADLGpg+AAAAAIfUzT4AAAAAh5O2PgAAAAB4no0+AAAAAGCZ/z4AAAAAgdbNPgAAAACG1M0+AAAAABxUmD4AAAAAb5GzPgAAAACAjE8+AAAAABvp7j4AAAAApEBEPgAAAABxLxU/AAAAABzp7j4AAAAASx/ePgAAAABLuAc/AAAAAPZJEz8AAAAAi9wHPwAAAAANWyI/AAAAAGKjJz8AAAAATLgHPwAAAAAtsSI/AAAAAIzcBz8AAAAAYaMnPwAAAAATrrM+AAAAAMGg7j4AAAAArLoUPwAAAABk3To/AAAAAKk7PT8AAAAAqs8vPwAAAACJByw/AAAAACrFLT8AAAAA9o0wPwAAAAAG2yg/AAAAAMaQLD8AAAAANDAwPwAAAADHkCw/AAAAAFPlLT8AAAAAnVMzPwAAAABWkCk/AAAAAGxiJT8AAAAA/6EvPwAAAADCsio/AAAAAC3hJj8AAAAAoTUlPwAAAADSByc/AAAAAFi7Ij8AAAAAsiAiPwAAAADXGCM/AAAAALMgIj8AAAAAz/EtPwAAAABU5S0/AAAAAINdKT8AAAAAVZApPwAAAAAluiQ/AAAAAIFdKT8AAAAAipEfPwAAAAByV5o+AAAAAESjzj4AAAAARoW3PgAAAABKP48+AAAAAOlN/z4AAAAAmBzOPgAAAABDo84+AAAAAJfrmD4AAAAAST+PPgAAAACZHM4+AAAAADo+uD4AAAAA22BWPgAAAABg9e8+AAAAAB69FD8AAAAAXvXvPgAAAAASrrM+AAAAAMCg7j4AAAAA1FzoPgAAAACmSA4/AAAAAEOYFT8AAAAAbQwJPwAAAABdoyc/AAAAAMOZKD8AAAAAuk0iPwAAAADCmSg/AAAAAFci1D4AAAAA4bcJPwAAAACDpzs/AAAAAIK+PD8AAAAALaMlPwAAAAAdvRQ/AAAAAI+DMD8AAAAAbyIsPwAAAADI5y0/AAAAADQqMT8AAAAATBooPwAAAAAx/is/AAAAAHAiLD8AAAAAbC0wPwAAAAAzKjE/AAAAAJZmLj8AAAAAf3k0PwAAAACugSk/AAAAAK2fND8AAAAAJrokPwAAAADTqyQ/AAAAAIBdKT8AAAAA0PEtPwAAAAB92Co/AAAAAHChJj8AAAAAwrwkPwAAAAAkvSY/AAAAACwXIj8AAAAAS1AhPwAAAADyUiI/AAAAAMZ4Lj8AAAAAbnwpPwAAAACtgSk/AAAAACuiJD8AAAAA/U/nPgAAAAA+Awg/AAAAAF6kFD8AAAAA2LkNPwAAAADKySA/AAAAADxuJz8AAAAAPQMIPwAAAAAFASc/AAAAANe5DT8AAAAAN363PgAAAABYItQ+AAAAACYd7j4AAAAA4rcJPwAAAAACNhM/AAAAAPSlOz8AAAAAhKc7PwAAAAAsoyU/AAAAACEGPD8AAAAA4LcJPwAAAACNgzI/AAAAAOfYLT8AAAAAyPguPwAAAAACYDI/AAAAAAoEKT8AAAAARJcsPwAAAAABADE/AAAAABWcNj8AAAAAn4QyPwAAAABdVC0/AAAAAGALNj8AAAAALKIkPwAAAACNcic/AAAAAF5ULT8AAAAAxXguPwAAAABhCzY/AAAAAG18KT8AAAAAuK+aPgAAAABlwc0+AAAAALNetz4AAAAAOjGQPgAAAAAbQf0+AAAAANObzT4AAAAAPGSaPgAAAADUm80+AAAAAF3Ptz4AAAAACYVZPgAAAABtJu4+AAAAAE0qTT4AAAAAAzYTPwAAAADAIxM/AAAAADZ+tz4AAAAA0dfmPgAAAAAe2gw/AAAAALPyEz8AAAAAGLYHPwAAAAC1iCU/AAAAAFp5Jj8AAAAAH9oMPwAAAACvWCA/AAAAABm2Bz8AAAAAW3kmPwAAAADAY9U+AAAAAFzPtz4AAAAAw7wIPwAAAACuAjk/AAAAALcUOj8AAAAAxZ4jPwAAAADCvAg/AAAAAL8jEz8AAAAAAEI3PwAAAABsJu4+AAAAAPCDMj8AAAAAc6AtPwAAAACs7C8/AAAAAIeLMz8AAAAAdYopPwAAAAC1Zy4/AAAAAOclMz8AAAAAiIszPwAAAAC0Zy4/AAAAAOD/Lz8AAAAAjGgqPwAAAAAhbjc/AAAAACwCJT8AAAAA/Bo3PwAAAAAq4is/AAAAAM4EJz8AAAAADtUkPwAAAADyJSc/AAAAAOzHIT8AAAAAGuEgPwAAAADNBCc/AAAAAAcSIj8AAAAA8SUnPwAAAAB3DzA/AAAAAOH/Lz8AAAAAh04qPwAAAADduyQ/AAAAAIhOKj8AAAAAi2gqPwAAAACNpe4+AAAAAFo0DT8AAAAAmqUVPwAAAADjlg0/AAAAAFKiJD8AAAAABggnPwAAAADZOiU/AAAAAOSWDT8AAAAAD0fUPgAAAAC/Y9U+AAAAAJfLBz8AAAAAI8Y4PwAAAABtZCI/AAAAAJbLBz8AAAAAgXs5PwAAAADM9Tk/AAAAAEKeND8AAAAAF0gvPwAAAABWljA/AAAAACV/ND8AAAAA0MIpPwAAAAD63S0/AAAAAA3zMj8AAAAA6kA5PwAAAACmljQ/AAAAAGUMOT8AAAAAbLwuPwAAAADgtDg/AAAAAL88KD8AAAAAa7wuPwAAAACjVOQ+AAAAANK3BT8AAAAA5eoRPwAAAABvSgs/AAAAANuiHT8AAAAADg0kPwAAAADTtwU/AAAAAHWnIz8AAAAApRW2PgAAAACZtOo+AAAAALSJED8AAAAAmLTqPgAAAAAIlTc/AAAAAEGNNz8AAAAA7+41PwAAAACIkDA/AAAAALM1Mj8AAAAAnRo2PwAAAABRbis/AAAAAJkqMD8AAAAA+FU1PwAAAACYKjA/AAAAAGXUNT8AAAAAEII6PwAAAADSyC8/AAAAAL8cKT8AAAAA0MgvPwAAAADrQDk/AAAAALTMOT8AAAAApZY0PwAAAAC9uZg+AAAAABkNyz4AAAAA8rO1PgAAAAAboo8+AAAAAOtQ+T4AAAAAP1jLPgAAAAA325k+AAAAAEBYyz4AAAAA2/CzPgAAAACeIFc+AAAAAB4W6j4AAAAAKZVOPgAAAAD1bBA/AAAAAB0W6j4AAAAA/iPiPgAAAABMHwo/AAAAAMEZET8AAAAAXy0FPwAAAACYJSI/AAAAADsTIz8AAAAA+CkdPwAAAAA8EyM/AAAAACl60D4AAAAAygsGPwAAAAAfFuo+AAAAADPwND8AAAAAoPs1PwAAAABvRyA/AAAAAOVIMz8AAAAAgUY2PwAAAABLLjc/AAAAANaRMT8AAAAA9E8zPwAAAACEXzc/AAAAABQ0LD8AAAAA+TExPwAAAAAXljY/AAAAADUcPD8AAAAAEgw3PwAAAACXpDA/AAAAAJPIOz8AAAAA4GopPwAAAADRyC8/AAAAAJikMD8AAAAAr9HpPgAAAACKeQo/AAAAAEezEj8AAAAArs8KPwAAAACZPSE/AAAAAFuRIz8AAAAAk9QhPwAAAACtzwo/AAAAAFyRIz8AAAAAbrnRPgAAAADQfQU/AAAAAOGrND8AAAAAfBkfPwAAAABAYTU/AAAAAMXaNj8AAAAAVNEwPwAAAAAPsjM/AAAAADcsOD8AAAAAIcErPwAAAABj2TE/AAAAAIC+Nz8AAAAAYtkxPwAAAAB1vDM/AAAAAEDULD8AAAAA8BUmPwAAAAA+1Cw/AAAAABEMNz8AAAAAv5suPwAAAACECyg/AAAAACSxJT8AAAAAvMwoPwAAAACmHiA/AAAAAPh7ID8AAAAAaXQiPwAAAABFrjM/AAAAAPvLKz8AAAAAP9QsPwAAAABKSCI/AAAAAPrLKz8AAAAA8RUmPwAAAABCxRw/AAAAAFxr6D4AAAAAL3EJPwAAAAAGmRE/AAAAABrYCT8AAAAAXP0fPwAAAAB0TCI/AAAAAG+WID8AAAAAdUwiPwAAAADSys8+AAAAAKFpBD8AAAAA6hQyPwAAAABLPDM/AAAAAMPaHT8AAAAAOmI0PwAAAACiaQQ/AAAAAKjxMz8AAAAA4R45PwAAAADQ/DE/AAAAAF8CND8AAAAAxBE5PwAAAAAxuCk/AAAAALhgMD8AAAAAz/wxPwAAAADCMzc/AAAAAArBPj8AAAAAevE4PwAAAADLlD4/AAAAAMKnMD8AAAAAa0IlPwAAAADBpzA/AAAAAESuMz8AAAAAxzw+PwAAAAADuzM/AAAAAEagLD8AAAAAIv4yPwAAAABvtzg/AAAAAOslJz8AAAAADKUxPwAAAABHoCw/AAAAAKV8OT8AAAAAC6UxPwAAAABmPSg/AAAAAMoVID8AAAAAd3k+PwAAAAD27xc/AAAAAGooPz8AAAAAQlnkPgAAAAAC+wY/AAAAACj2Dz8AAAAAVn0IPwAAAADXPR4/AAAAAAbsID8AAAAAA/sGPwAAAAAHSx8/AAAAACkPxT4AAAAA0crPPgAAAAA2xf0+AAAAAE+vGT8AAAAAbSszPwAAAADC2h0/AAAAAGiJMj8AAAAAoGkEPwAAAAD5+Mg+AAAAAEeH4j4AAAAA90z9PgAAAADb4fk+AAAAAHIdBD8AAAAAHVwOPwAAAABIh+I+AAAAAK6WFD8AAAAAH1wOPwAAAAAE3pw+AAAAAN+0wT4AAAAANMX9PgAAAAD37xc/AAAAAClB7D4AAAAAUK8ZPwAAAABlPSg/AAAAADXF/T4AAAAAtsV8PgAAAABILaI+AAAAANdwkz4AAAAAb1ZxPgAAAACTZMc+AAAAAJg8pT4AAAAAr1iCPgAAAAAJbI8+AAAAAEAHtz4AAAAAKEHsPgAAAAB3DOQ+AAAAAN60wT4AAAAAQQe3PgAAAAAF3pw+AAAAAK+qqT4AAAAA4AnIPgAAAAAYW9c+AAAAAAJZyj4AAAAA6QrpPgAAAADcm/E+AAAAAN8JyD4AAAAAMyrwPgAAAAADWco+AAAAAHIijz4AAAAAEI2zPgAAAACT2dc+AAAAAA+Nsz4AAAAABrt+PgAAAABEzp8+AAAAAJqgkT4AAAAAGpJxPgAAAAB+2r0+AAAAAMWFnz4AAAAAemJ9PgAAAAAZknE+AAAAAP8LkD4AAAAAatWzPgAAAACS2dc+AAAAAO681z4AAAAAadWzPgAAAABzIo8+AAAAAN+sqT4AAAAAekvHPgAAAAAsRtU+AAAAAPqTxz4AAAAAuEXnPgAAAACFw+0+AAAAAHhLxz4AAAAAAfLnPgAAAAD5k8c+AAAAAITD7T4AAAAAoiiQPgAAAAD+C5A+AAAAAA+Nsz4AAAAAZNPWPgAAAAAQjbM+AAAAAPvbgD4AAAAAuF+gPgAAAAD/l5I+AAAAALfpdD4AAAAAs5C9PgAAAAA5F6A+AAAAALUvgD4AAAAAuel0PgAAAAA6F6A+AAAAAC4SkT4AAAAAYgxJPgAAAABr1bM+AAAAAGPT1j4AAAAAv7bWPgAAAABq1bM+AAAAAKv2qT4AAAAAB7rGPgAAAADHTtQ+AAAAAIYCxz4AAAAAQ8flPgAAAAC3F+w+AAAAAAa6xj4AAAAAiXPmPgAAAACFAsc+AAAAALgX7D4AAAAA0i6RPgAAAAARjbM+AAAAAGnVsz4AAAAAM83VPgAAAAAQjbM+AAAAAINlAT8AAAAAcVqCPgAAAAAs8aA+AAAAAGOPkz4AAAAAVUF4PgAAAADoRr0+AAAAAK6ooD4AAAAAK66BPgAAAABUQXg+AAAAAF0Ykj4AAAAADrRNPgAAAABr1bM+AAAAADTN1T4AAAAAkLDVPgAAAABq1bM+AAAAANMukT4AAAAAdUCqPgAAAACRKMY+AAAAAGBX0z4AAAAAEHHGPgAAAADNSOQ+AAAAAOZr6j4AAAAAkCjGPgAAAAAR9eQ+AAAAAAA1kj4AAAAAD42zPgAAAAAEx9Q+AAAAAJGw1T4AAAAAmTsAPwAAAABo1bM+AAAAAOfYgz4AAAAAoIKhPgAAAADJhpQ+AAAAAPGYez4AAAAAHP28PgAAAAAiOqE+AAAAAKEsgz4AAAAAITqhPgAAAACMHpM+AAAAALlbUj4AAAAAatWzPgAAAAADx9Q+AAAAAGCq1D4AAAAAEI2zPgAAAABp1bM+AAAAAAE1kj4AAAAAQYqqPgAAAAAdl8U+AAAAAPtf0j4AAAAAnd/FPgAAAABVyuI+AAAAABjA6D4AAAAAHpfFPgAAAACaduM+AAAAAJzfxT4AAAAAMDuTPgAAAAAPjbM+AAAAANXA0z4AAAAAYarUPgAAAABbI/4+AAAAAGjVsz4AAAAAXleFPgAAAAAVFKI+AAAAAC5+lT4AAAAAkPB+PgAAAABPs7w+AAAAAJXLoT4AAAAAFhSiPgAAAAAYq4Q+AAAAAJPLoT4AAAAAvCSUPgAAAABmA1c+AAAAAGrVsz4AAAAA1sDTPgAAAAAzpNM+AAAAAGnVsz4AAAAADdSqPgAAAACqBcU+AAAAAJdo0T4AAAAAKE7FPgAAAADeS+E+AAAAAEsU5z4AAAAAJPjhPgAAAAApTsU+AAAAAEoU5z4AAAAAX0GUPgAAAAAPjbM+AAAAAKa60j4AAAAADo2zPgAAAAAypNM+AAAAANXVhj4AAAAAiKWiPgAAAACRdZY+AAAAABYkgT4AAAAAhmm8PgAAAAAJXaI+AAAAAIeloj4AAAAAkCmGPgAAAADsKpU+AAAAABGrWz4AAAAAa9WzPgAAAAAZCVU+AAAAAAOe0j4AAAAAatWzPgAAAABgQZQ+AAAAANkdqz4AAAAANnTEPgAAAAA0cdA+AAAAALe8xD4AAAAAaM3fPgAAAAB8aOU+AAAAADd0xD4AAAAArnngPgAAAACOR5U+AAAAABCNsz4AAAAAd7TRPgAAAAAPjbM+AAAAAAGe0j4AAAAATFSIPgAAAAD7NqM+AAAAAPlslz4AAAAA5M+CPgAAAAC8H7w+AAAAAH3uoj4AAAAA/DajPgAAAAAGqIc+AAAAAOXPgj4AAAAAfu6iPgAAAAAaMZY+AAAAAL5SYD4AAAAAadWzPgAAAAB4tNE+AAAAANOX0T4AAAAADo2zPgAAAACPR5U+AAAAAKRnqz4AAAAAwuLDPgAAAADQec8+AAAAAEErxD4AAAAA8E7ePgAAAACsvOM+AAAAADf73j4AAAAAQivEPgAAAACuvOM+AAAAAL5Nlj4AAAAAEI2zPgAAAABHrtA+AAAAAA+Nsz4AAAAACD35PgAAAADE0ok+AAAAAG/Ioz4AAAAAW2SYPgAAAAC0e4Q+AAAAAO7Vuz4AAAAA8H+jPgAAAAB9Jok+AAAAALN7hD4AAAAASTeXPgAAAABr1bM+AAAAAKOR0D4AAAAAatWzPgAAAABvsas+AAAAAE5Rwz4AAAAAaYLOPgAAAADOmcM+AAAAAHnQ3D4AAAAA3hDiPgAAAADAfN0+AAAAAO1Tlz4AAAAASjeXPgAAAAARjbM+AAAAAGnVsz4AAAAAGajPPgAAAAAB1PQ+AAAAAGjVsz4AAAAAOVGLPgAAAADkWaQ+AAAAAMFbmT4AAAAAgSeGPgAAAAAljLs+AAAAAGQRpD4AAAAA86SKPgAAAACCJ4Y+AAAAAGURpD4AAAAAeT2YPgAAAABr1bM+AAAAABiozz4AAAAAdYvPPgAAAAAQjbM+AAAAAGrVsz4AAAAAOvurPgAAAADav8I+AAAAAAWLzT4AAAAAWgjDPgAAAAAEUts+AAAAABFl4D4AAAAASv7bPgAAAAAcWpg+AAAAAA+Nsz4AAAAA6aHOPgAAAAAQjbM+AAAAAC2A8j4AAAAAgWb0PgAAAACxz4w+AAAAAFnrpD4AAAAAJVOaPgAAAABQ04c+AAAAAFlCuz4AAAAA2aKkPgAAAABa66Q+AAAAAGsjjD4AAAAAqUOZPgAAAADCSW4+AAAAAGrVsz4AAAAARYXOPgAAAAARjbM+AAAAAGnVsz4AAAAABUWsPgAAAABmLsI+AAAAAKCTzD4AAAAA5nbCPgAAAACM09k+AAAAAEK53j4AAAAA03/aPgAAAABMYJk+AAAAAKhDmT4AAAAAD42zPgAAAAC6m80+AAAAABCNsz4AAAAAKE6OPgAAAADLfKU+AAAAAIpKmz4AAAAAH3+JPgAAAACN+Lo+AAAAAE00pT4AAAAA46GNPgAAAADYSZo+AAAAAGnVsz4AAAAAFX/NPgAAAABq1bM+AAAAAEtgmT4AAAAA0o6sPgAAAADznME+AAAAADqcyz4AAAAAcuXBPgAAAAAWVdg+AAAAAHUN3T4AAAAAXAHZPgAAAABx5cE+AAAAAHtmmj4AAAAAD42zPgAAAACKlcw+AAAAABZ/zT4AAAAAgtjtPgAAAAD7j+8+AAAAAJ7Mjz4AAAAAPw6mPgAAAADwQZw+AAAAAO0qiz4AAAAAwa66PgAAAADBxaU+AAAAAEAOpj4AAAAAWSCPPgAAAADsKos+AAAAAMDFpT4AAAAAB1CbPgAAAAAXmXc+AAAAAGvVsz4AAAAAPxByPgAAAADneMw+AAAAABCNsz4AAAAAatWzPgAAAACd2Kw+AAAAAH8LwT4AAAAA1qTKPgAAAAD8U8E+AAAAAKDW1j4AAAAApWHbPgAAAAB+C8E+AAAAAOSC1z4AAAAAqmybPgAAAAAPjbM+AAAAAGnVsz4AAAAAWo/LPgAAAACqhOs+AAAAABVLkT4AAAAAtZ+mPgAAAABUOZ0+AAAAALvWjD4AAAAA9mS6PgAAAAAzV6Y+AAAAALOfpj4AAAAAzp6QPgAAAAC81ow+AAAAADRXpj4AAAAAN1acPgAAAADDQHw+AAAAAGjVsz4AAAAAxuZ2PgAAAAC3css+AAAAAA6Nsz4AAAAAaSKtPgAAAAAJesA+AAAAAHCtyT4AAAAAicLAPgAAAAAnWNU+AAAAANW12T4AAAAAbgTWPgAAAADZcpw+AAAAADZWnD4AAAAAD42zPgAAAAAsico+AAAAALhyyz4AAAAAadWzPgAAAAB1ueo+AAAAAI3Jkj4AAAAAKTGnPgAAAAC6MJ4+AAAAAIqCjj4AAAAAKhu6PgAAAACp6KY+AAAAAEYdkj4AAAAAZlydPgAAAABo1bM+AAAAAEu9ez4AAAAAiGzKPgAAAABq1bM+AAAAANpynD4AAAAAEI2zPgAAAAA1bK0+AAAAAJXovz4AAAAAC7bIPgAAAAAWMcA+AAAAALHZ0z4AAAAACQrYPgAAAACW6L8+AAAAAPiF1D4AAAAAFzHAPgAAAAAJeZ0+AAAAABCNsz4AAAAAadWzPgAAAAD8gsk+AAAAAIlsyj4AAAAA/tzmPgAAAAAyTug+AAAAAANIlD4AAAAAncKnPgAAAAAeKJ8+AAAAAFgukD4AAAAAX9G5PgAAAAAceqc+AAAAAJzCpz4AAAAAvZuTPgAAAAAdeqc+AAAAAJRinj4AAAAAaNWzPgAAAABYZsk+AAAAAA6Nsz4AAAAACHmdPgAAAAAPjbM+AAAAAP61rT4AAAAAI1e/PgAAAACpvsc+AAAAAKGfvz4AAAAAPFvSPgAAAAA6XtY+AAAAACJXvz4AAAAAgAfTPgAAAACgn78+AAAAADl/nj4AAAAAD42zPgAAAABp1bM+AAAAAMx8yD4AAAAAWWbJPgAAAAAnieQ+AAAAAO3i5T4AAAAAecaVPgAAAAAQVKg+AAAAAIQfoD4AAAAAJ9qRPgAAAACTh7k+AAAAAJELqD4AAAAAD1SoPgAAAAAzGpU+AAAAACbakT4AAAAAkAuoPgAAAADDaJ8+AAAAAOMbhT4AAAAAadWzPgAAAAAqYMg+AAAAAA6Nsz4AAAAAOH+ePgAAAADL/60+AAAAALDFvj4AAAAAQsfGPgAAAAAuDr8+AAAAAMTc0D4AAAAAbLLUPgAAAACvxb4+AAAAAAqJ0T4AAAAALQ6/PgAAAABrstQ+AAAAAGeFnz4AAAAAD42zPgAAAACedsc+AAAAABCNsz4AAAAAKWDIPgAAAABTNeI+AAAAAPFElz4AAAAAg+WoPgAAAADoFqE+AAAAAPaFkz4AAAAAyD25PgAAAAAGnag+AAAAAITlqD4AAAAAq5iWPgAAAAD1hZM+AAAAAAWdqD4AAAAA826gPgAAAABp1bM+AAAAAPpZxz4AAAAAatWzPgAAAACWSa4+AAAAADs0vj4AAAAA38/FPgAAAAC6fL4+AAAAAE5ezz4AAAAAmwbTPgAAAAA6NL4+AAAAAJIK0D4AAAAAnAbTPgAAAACXi6A+AAAAABCNsz4AAAAAaNWzPgAAAABucMY+AAAAAA+Nsz4AAAAAfOHfPgAAAABnDOE+AAAAAGjDmD4AAAAA93apPgAAAABMDqI+AAAAAMMxlT4AAAAA/PO4PgAAAAB4Lqk+AAAAACEXmD4AAAAAInWhPgAAAABp1bM+AAAAAMpTxj4AAAAAatWzPgAAAABik64+AAAAAMiivT4AAAAAedjEPgAAAABH670+AAAAANbfzT4AAAAAz1rRPgAAAAAdjM4+AAAAAEbrvT4AAAAAzlrRPgAAAADGkaE+AAAAABCNsz4AAAAAP2rFPgAAAAAPjbM+AAAAAKWN3T4AAAAAaNWzPgAAAADeQZo+AAAAAG0Iqj4AAAAAsAWjPgAAAACS3ZY+AAAAADGquD4AAAAA7L+pPgAAAABsCKo+AAAAAJiVmT4AAAAAUXuiPgAAAABlF4w+AAAAAGnVsz4AAAAAQGrFPgAAAACcTcU+AAAAAGjVsz4AAAAALt2uPgAAAABTEb0+AAAAABXhwz4AAAAA01m9PgAAAABeYcw+AAAAAP6uzz4AAAAApg3NPgAAAAD2l6I+AAAAAFJ7oj4AAAAAEI2zPgAAAAAOZMQ+AAAAAA+Nsz4AAAAA0jnbPgAAAADhNdw+AAAAAFTAmz4AAAAA4JmqPgAAAAAW/aM+AAAAAGGJmD4AAAAAZmC4PgAAAABfUao+AAAAAA4Umz4AAAAAYFGqPgAAAACBgaM+AAAAADtrjj4AAAAAadWzPgAAAAAPZMQ+AAAAAGtHxD4AAAAAatWzPgAAAAD1l6I+AAAAAPkmrz4AAAAA4H+8PgAAAACw6cI+AAAAAF3IvD4AAAAA6OLKPgAAAAAwA84+AAAAAN9/vD4AAAAALY/LPgAAAABeyLw+AAAAADEDzj4AAAAAI56jPgAAAACAgaM+AAAAABCNsz4AAAAA3l3DPgAAAAD85dg+AAAAAGvVsz4AAAAAzD6dPgAAAABUK6s+AAAAAHr0pD4AAAAAMDWaPgAAAACbFrg+AAAAANbiqj4AAAAAhZKcPgAAAAAvNZo+AAAAANXiqj4AAAAAsIekPgAAAABo1bM+AAAAAN9dwz4AAAAAO0HDPgAAAAAOjbM+AAAAAA+Nsz4AAAAAxXCvPgAAAABs7rs+AAAAAErywT4AAAAA6ja8PgAAAABxZMk+AAAAAGJXzD4AAAAAa+67PgAAAAC5EMo+AAAAAOs2vD4AAAAAY1fMPgAAAABTpKQ+AAAAAK+HpD4AAAAAEI2zPgAAAABp1bM+AAAAALBXwj4AAAAAPEHDPgAAAAAkktY+AAAAAGrVsz4AAAAAQ72ePgAAAADHvKs+AAAAAN/rpT4AAAAA/eCbPgAAAADOzLc+AAAAAEh0qz4AAAAA/RCePgAAAADgjaU+AAAAAOgSkz4AAAAAaNWzPgAAAACxV8I+AAAAAAw7wj4AAAAAD42zPgAAAABq1bM+AAAAAJC6rz4AAAAA+Fy7PgAAAADm+sA+AAAAAHeluz4AAAAA/OXHPgAAAACTq8o+AAAAAEKSyD4AAAAAdqW7PgAAAACDqqU+AAAAAN6NpT4AAAAAEI2zPgAAAABp1bM+AAAAAIBRwT4AAAAAD42zPgAAAAANO8I+AAAAAE8+1D4AAAAAujugPgAAAAA7Tqw+AAAAAEXjpj4AAAAAy4ydPgAAAAAFg7c+AAAAAL0FrD4AAAAAc4+fPgAAAADMjJ0+AAAAABCUpj4AAAAAvmaVPgAAAABq1bM+AAAAAIFRwT4AAAAA3jTBPgAAAACCqqU+AAAAAFsEsD4AAAAAg8u6PgAAAACBA8A+AAAAAAMUuz4AAAAAhGfGPgAAAADG/8g+AAAAAITLuj4AAAAAyxPHPgAAAAAEFLs+AAAAAMf/yD4AAAAAsrCmPgAAAAAPjbM+AAAAAGvVsz4AAAAAUkvAPgAAAAAOjbM+AAAAAHnq0T4AAAAA04jSPgAAAAAwuqE+AAAAAK/frD4AAAAAqdqnPgAAAACbOJ8+AAAAADg5tz4AAAAAMZesPgAAAADqDaE+AAAAADCXrD4AAAAAPpqnPgAAAACUupc+AAAAAGrVsz4AAAAAri7APgAAAABr1bM+AAAAABCNsz4AAAAAKE6wPgAAAAAPOro+AAAAABoMvz4AAAAAjoK6PgAAAAAO6cQ+AAAAAPhTxz4AAAAAEDq6PgAAAABSlcU+AAAAAI+Cuj4AAAAA91PHPgAAAADhtqc+AAAAABCNsz4AAAAAadWzPgAAAAAiRb8+AAAAAK8uwD4AAAAAo5bPPgAAAACnOKM+AAAAACRxrT4AAAAADNKoPgAAAABq5KA+AAAAAG7vtj4AAAAApSitPgAAAAAjca0+AAAAAGKMoj4AAAAAaeSgPgAAAABtoKg+AAAAAGoOmj4AAAAAatWzPgAAAAB+KL8+AAAAAGnVsz4AAAAAEY2zPgAAAADyl7A+AAAAAJyouT4AAAAAuRS+PgAAAAAb8bk+AAAAAJdqwz4AAAAAKajFPgAAAACbqLk+AAAAAN0WxD4AAAAAKKjFPgAAAAARvag+AAAAABGNsz4AAAAA9D6+PgAAAAAQjbM+AAAAAIAovz4AAAAAzkLNPgAAAAAet6Q+AAAAAJgCrj4AAAAAdMmpPgAAAAA4kKI+AAAAAKOltj4AAAAAGbqtPgAAAADXCqQ+AAAAABi6rT4AAAAAnaapPgAAAABAYpw+AAAAAGnVsz4AAAAAUCK+PgAAAABo1bM+AAAAABK9qD4AAAAAveGwPgAAAAAnF7k+AAAAAFIdvT4AAAAApl+5PgAAAAAg7ME+AAAAAFv8wz4AAAAAZpjCPgAAAABa/MM+AAAAAEDDqT4AAAAAnKapPgAAAAAQjbM+AAAAAGrVsz4AAAAAxDi9PgAAAAD47so+AAAAAJU1pj4AAAAADZSuPgAAAADXwKo+AAAAAAY8pD4AAAAA1lu2PgAAAACNS64+AAAAAAyUrj4AAAAATomlPgAAAAAHPKQ+AAAAAM2sqj4AAAAAadWzPgAAAAAhHL0+AAAAAA+Nsz4AAAAAatWzPgAAAACIK7E+AAAAALOFuD4AAAAA7yW8PgAAAAAzzrg+AAAAAKltwD4AAAAAi1DCPgAAAADvGcE+AAAAAHDJqj4AAAAAzKyqPgAAAAAQjbM+AAAAAJYyvD4AAAAAEY2zPgAAAAAgHL0+AAAAACCbyD4AAAAAC7SnPgAAAACAJa8+AAAAADy4qz4AAAAA1eelPgAAAAALErY+AAAAAADdrj4AAAAAxgenPgAAAADU56U+AAAAAP2yqz4AAAAA6wmhPgAAAABp1bM+AAAAAFK8nz4AAAAAlTK8PgAAAADyFbw+AAAAAA+Nsz4AAAAAVHWxPgAAAAA/9Lc+AAAAAIsuuz4AAAAAvjy4PgAAAAAy774+AAAAAL2kwD4AAAAAeZu/PgAAAAC8pMA+AAAAAJ/Pqz4AAAAA/LKrPgAAAAAPjbM+AAAAAGUsuz4AAAAA8RW8PgAAAABMR8Y+AAAAAIIyqT4AAAAA87avPgAAAACgr6w+AAAAAKSTpz4AAAAAP8i1PgAAAAB1bq8+AAAAADyGqD4AAAAAdG6vPgAAAAAsuaw+AAAAAMJdoz4AAAAAatWzPgAAAADCD7s+AAAAAGnVsz4AAAAAH7+xPgAAAADMYrc+AAAAACQ3uj4AAAAAS6u3PgAAAAC7cL0+AAAAAO/4vj4AAAAAAh2+PgAAAABMq7c+AAAAAO74vj4AAAAAz9WsPgAAAAAruaw+AAAAAA6Nsz4AAAAANya6PgAAAAAPjbM+AAAAAMEPuz4AAAAAa9WzPgAAAABABcQ+AAAAALcAqj4AAAAApA6wPgAAAABDiK0+AAAAAIADqT4AAAAAGne1PgAAAAAP+68+AAAAABT9qT4AAAAAfwOpPgAAAAAQ+68+AAAAAH7drD4AAAAAGZmkPgAAAADjlLM+AAAAANJApD4AAAAAggG6PgAAAACeG7I+AAAAADiwtz4AAAAA65K5PgAAAADSF7c+AAAAANbjvD4AAAAAJZK9PgAAAABXpbw+AAAAAHptrz4AAAAAckO2PgAAAADklLM+AAAAAD0+wD4AAAAAqOy7PgAAAABzQ7Y+AAAAADnDwT4AAAAADbyxPgAAAADHALY+AAAAAFwQuD4AAAAAKMS2PgAAAADaero+AAAAALF8uz4AAAAAyAC2PgAAAAC2q7s+AAAAACnEtj4AAAAAbXquPgAAAAB7ba8+AAAAALputD4AAAAA9GK9PgAAAAASRL4+AAAAAKt5uT4AAAAAuG60PgAAAADNrr8+AAAAAEoivz4AAAAAnzOwPgAAAAAe97M+AAAAANnbtT4AAAAA5b20PgAAAABC+7c+AAAAAOLyuD4AAAAAiSy5PgAAAACgNa0+AAAAAG56rj4AAAAAxX6yPgAAAAC5brQ+AAAAAEQDtz4AAAAA96OuPgAAAAB17bE+AAAAAFensz4AAAAAPLSyPgAAAACqe7U+AAAAABFptj4AAAAA8Ky2PgAAAAAg76s+AAAAANKOsD4AAAAAxH6yPgAAAABfrLc+AAAAALeFuD4AAAAA34y0PgAAAAAlXLk+AAAAAHHwuT4AAAAAxn6yPgAAAABPFK0+AAAAAMvjrz4AAAAA03KxPgAAAACTqrA+AAAAABL8sj4AAAAAQd+zPgAAAABXLbQ+AAAAAKCoqj4AAAAA3J6uPgAAAADRjrA+AAAAABTRtD4AAAAAeRayPgAAAAATebY+AAAAAF6stz4AAAAA4Iy0PgAAAACmhKs+AAAAACParT4AAAAATz6vPgAAAADqoK4+AAAAAHl8sD4AAAAAc1WxPgAAAAAi2q0+AAAAAMGtsT4AAAAA66CuPgAAAAByVbE+AAAAAB5iqT4AAAAAn6iqPgAAAADprqw+AAAAAN2erj4AAAAAzPWxPgAAAAAVoK8+AAAAAOiurD4AAAAAE9G0PgAAAAB6FrI+AAAAAAKWsz4AAAAA/vSpPgAAAAB60Ks+AAAAAMwJrT4AAAAAQpesPgAAAADh/K0+AAAAAKHLrj4AAAAAJy6vPgAAAACgy64+AAAAAJ0bqD4AAAAA9b6qPgAAAACCGq8+AAAAAC3orz4AAAAArimtPgAAAAD0vqo+AAAAABSgrz4AAAAAV2WoPgAAAADSxqk+AAAAAErVqj4AAAAAmI2qPgAAAABHfas+AAAAANFBrD4AAAAAjq6sPgAAAACZjao+AAAAAB3Vpj4AAAAA/86oPgAAAAA3P6w+AAAAAEqzqj4AAAAAgRqvPgAAAACt1aY+AAAAACe9pz4AAAAAxqCoPgAAAADwg6g+AAAAAK79qD4AAAAAAbipPgAAAAAovac+AAAAAPUuqj4AAAAA74OoPgAAAACrjqU+AAAAABzVpj4AAAAAC9+mPgAAAAAAz6g+AAAAANMpqj4AAAAA4zyoPgAAAADN7Ko+AAAAAEmzqj4AAAAAjZSrPgAAAABGRqU+AAAAAJ+zpT4AAAAAQ2ymPgAAAABHeqY+AAAAABl+pj4AAAAAMS6nPgAAAABdr6c+AAAAAMZKpD4AAAAAqo6lPgAAAAAP8KQ+AAAAAKRKpz4AAAAAncalPgAAAAC7Cag+AAAAABDwpD4AAAAA7mOpPgAAAADkPKg+AAAAAGC1qD4AAAAA0cCjPgAAAADvv6M+AAAAADpBpD4AAAAAVHSkPgAAAADZIKQ+AAAAAKGupD4AAAAAWjGlPgAAAACgrqQ+AAAAAMdKpD4AAAAAXDGlPgAAAACG16U+AAAAAF0xpT4AAAAANesaPgAAAAB17Bk+AAAAAH22Bz4AAAAAA8kGPgAAAABGuh0+AAAAAAztCT4AAAAA0PYAPgAAAAAT0/49AAAAADqtAj4AAAAAyHMcPgAAAAC1ZEQ+AAAAAPQgIj4AAAAAGicMPgAAAAASZAQ+AAAAADZIAz4AAAAAHKQBPgAAAAABAAA+AAAAAM23/D0AAAAAprf7PQAAAACXb/k9AAAAAAjYBT4AAAAAXIT0PgAAAABZ/vU+AAAAAMDe+z4AAAAApuD6PgAAAADl6/U+AAAAAKly/D4AAAAAQgz+PgAAAAC0NP0+AAAAAIrW/j4AAAAAtdfyPgAAAAByueo+AAAAAEqu9T4AAAAAUQj9PgAAAAANof8+AAAAAAEAAD8AAAAA9S3/PgAAAADoW/4+AAAAANqJ/T4AAAAA7Vz8PgAAAADMt/w+AAAAAMrg+T4AAAAAX4qUPQAAAADwpJA9AAAAALqDOz0AAAAAOtM4PQAAAACBKJo9AAAAAFhjRT0AAAAAXswVPQAAAADytw89AAAAAK7GHD0AAAAA6/aZPQAAAABAUaU9AAAAAPdQTz0AAAAAvsIjPQAAAADaiR09AAAAAHH5Fj0AAAAAB2kQPQAAAACf2Ak9AAAAAMahCT0AAAAANkgDPQAAAAC5FDY9AAAAADUdDT8AAAAARwIPPwAAAADX7RI/AAAAAFcMEj8AAAAAFR0RPwAAAABe5xM/AAAAAJxQFD8AAAAAhdgTPwAAAACwyxQ/AAAAAKXeCz8AAAAAcMkTPwAAAAAL5BQ/AAAAAC1HFT8AAAAAVlUVPwAAAABQ7BQ/AAAAAEiDFD8AAAAAQxoUPwAAAAA/aRM/AAAAADyxEz8AAAAAWHERPwAAAABDYBI+AAAAAAUkED4AAAAArb7kPQAAAABFg+M9AAAAAMU6Fj4AAAAAalrqPQAAAAD4pM49AAAAAF6eyz0AAAAAnjfSPQAAAACGuRU+AAAAANhgVj4AAAAAUn0dPgAAAAAH0O89AAAAAIDF1T0AAAAAIQ3SPQAAAADuxM49AAAAALt8yz0AAAAAhTTIPQAAAADMm8g9AAAAAFHsxD0AAAAAKWjiPQAAAACDJCE/AAAAACNXIj8AAAAADsQoPwAAAAB+JSg/AAAAAEbYIT8AAAAAf+4oPwAAAACjJSs/AAAAAOy1Kj8AAAAA2oYrPwAAAAC6vB8/AAAAAAMoIT8AAAAA0hkpPwAAAAAo6Cs/AAAAAMZOLD8AAAAAv+UrPwAAAAC5fCs/AAAAALITKz8AAAAAGEYqPwAAAACsqio/AAAAAA+GJz8AAAAA3XscPwAAAABHsBw/AAAAAH2OGz8AAAAA9zMbPwAAAAAeMx0/AAAAAJH9Gz8AAAAACyMbPwAAAADVuxo/AAAAANSMGz8AAAAAJk8cPwAAAACMkR8/AAAAACzBHT8AAAAAmGwcPwAAAACb9hs/AAAAAMDlGz8AAAAAuXwbPwAAAACyExs/AAAAAKuqGj8AAAAAilQaPwAAAAClQRo/AAAAAMXYGj8AAAAAe3eVPgAAAAAB0pU+AAAAADIskz4AAAAAAHuSPgAAAAAl35Y+AAAAADsNlD4AAAAAADGSPgAAAADrYpE+AAAAAA4Fkz4AAAAAWy6VPgAAAADM5Zo+AAAAACgFmD4AAAAA+u+UPgAAAABI2ZM+AAAAAH6xkz4AAAAAUt+SPgAAAAAWDZI+AAAAANs6kT4AAAAAq5SQPgAAAACvaJA+AAAAABfIkT4AAAAAzAtgPgAAAAAq3l8+AAAAAD/bUz4AAAAAwrVSPgAAAADc2mI+AAAAAMvZVT4AAAAAuWdPPgAAAABx000+AAAAACAXUT4AAAAAcw96PgAAAADJkWA+AAAAAPI+Zj4AAAAA1dtXPgAAAAD4xlI+AAAAACMNUj4AAAAACWlQPgAAAADvxE4+AAAAANMgTT4AAAAAuj5MPgAAAAC5fEs+AAAAAMSMUT4AAAAA/PPRPgAAAABmBdM+AAAAADXM1T4AAAAAKOrUPgAAAAB/W9M+AAAAAB581j4AAAAAl9PWPgAAAACV/9U+AAAAAF2h1z4AAAAAGSrMPgAAAACvyNA+AAAAAL9CzT4AAAAAMZ/TPgAAAADLLdc+AAAAAF9v2D4AAAAARJ3YPgAAAAA1y9c+AAAAACz51j4AAAAALSfWPgAAAABoK9U+AAAAAEBV1T4AAAAAYQbUPgAAAACA2xk+AAAAAId2FT4AAAAA/tIBPgAAAABu1QE+AAAAAFUjGD4AAAAA7acDPgAAAAAI+PQ9AAAAAHgZ8j0AAAAAc0z4PQAAAADLUSA+AAAAAJYFQD4AAAAAYyf2PQAAAAAu3/I9AAAAAPqW7z0AAAAALDzvPQAAAADFTuw9AAAAAPbcAT4AAAAAtWX3PgAAAABr6Pg+AAAAAPIK/z4AAAAAggr+PgAAAAA/zfg+AAAAAIac/z4AAAAAfKgAPwAAAACPPAA/AAAAAHoNAT8AAAAAAWzqPgAAAACrhOs+AAAAAN6E+D4AAAAA7RcAPwAAAACWcgE/AAAAABukAT8AAAAAFDsBPwAAAAAN0gA/AAAAAAdpAD8AAAAA8gSJPQAAAACl/IQ9AAAAACQiIj0AAAAAUIQfPQAAAAATo449AAAAAGwULD0AAAAAeE33PAAAAABKKes8AAAAAGGjAj0AAAAAlpyOPQAAAACab/k8AAAAAMhO7DwAAAAA9i3fPAAAAACeAd88AAAAACIN0jwAAAAAetgcPQAAAAAxlSI/AAAAACvMIz8AAAAAJ1oqPwAAAABtuik/AAAAAPVIIz8AAAAAcYMqPwAAAAD9xyw/AAAAACFYLD8AAAAACyktPwAAAABPkyI/AAAAAJetKj8AAAAAOIotPwAAAADh8i0/AAAAANuJLT8AAAAA0yAtPwAAAADNtyw/AAAAACGWkj4AAAAA1OeSPgAAAADV/48+AAAAACdRjz4AAAAAmv2TPgAAAAAQ45A+AAAAABTsjj4AAAAAiB6OPgAAAAA6wI8+AAAAALf1mD4AAAAA3VeSPgAAAACflo8+AAAAAKLEjj4AAAAAtfKNPgAAAADHUI0+AAAAAMogjT4AAAAAuKCOPgAAAAAWSVo+AAAAAAUKWj4AAAAA24JNPgAAAAAJYkw+AAAAACUYXT4AAAAAD4ZPPgAAAABQ3kg+AAAAAKBKRz4AAAAATI5KPgAAAADGZ3U+AAAAAJ3kWj4AAAAAGZl3PgAAAACf2Ek+AAAAAIU0SD4AAAAAbZBGPgAAAAB+tkU+AAAAAFHsRD4AAAAAtT1LPgAAAABV1dQ+AAAAAH7v1T4AAAAAcPjYPgAAAAD9E9g+AAAAAOU81j4AAAAADabZPgAAAABYGNo+AAAAAPVD2T4AAAAA3+XaPgAAAADtfc4+AAAAAIUd0D4AAAAAnJbPPgAAAADXddY+AAAAAG1V2j4AAAAAorPbPgAAAACl5ds+AAAAAIgT2z4AAAAAbkHaPgAAAABYb9k+AAAAABNH+j4AAAAAgNL7PgAAAACTGwE/AAAAADCaAD8AAAAAnK77PgAAAAAyYwE/AAAAANZKAj8AAAAAw94BPwAAAACxrwI/AAAAANe/7D4AAAAA/I/vPgAAAACC2O0+AAAAAHZb+z4AAAAAsasBPwAAAACmFAM/AAAAADZIAz8AAAAAL98CPwAAAAApdgI/AAAAACINAj8AAAAAx9h/PQAAAACrAnQ9AAAAAOA4CT0AAAAARpEHPQAAAABEM4M9AAAAAI7UEj0AAAAARyDDPAAAAACoObc8AAAAAOsD0TwAAAAAST/0PQAAAACN9Ic9AAAAAM/Q3z0AAAAAUuzEPAAAAAB/y7c8AAAAAKuqqjwAAAAA5TurPAAAAADZiZ08AAAAABeNBT0AAAAAdvANPgAAAAB/ZQo+AAAAAOwc2D0AAAAAF5jXPQAAAABQbw8+AAAAAMQl3T0AAAAACZTBPQAAAAA+pL49AAAAAFEUxT0AAAAAAf5PPgAAAADHrhI+AAAAAIKMTz4AAAAAHqTBPQAAAADoW749AAAAALQTuz0AAAAA/627PQAAAAB/y7c9AAAAAIPf1j0AAAAAexQkPwAAAAAatiU/AAAAAG0ULD8AAAAA4VMrPwAAAAAiJSY/AAAAAH+ALD8AAAAA3m4uPwAAAADo+i0/AAAAAEbYLj8AAAAA0WcZPwAAAAAexxk/AAAAAF93GT8AAAAApkEmPwAAAAAG0yw/AAAAAH0+Lz8AAAAA+5YvPwAAAAD0LS8/AAAAAO3ELj8AAAAA51suPwAAAADntI8+AAAAAOv9jz4AAAAA5dOMPgAAAACAJ4w+AAAAAGQckT4AAAAAcbmNPgAAAAC+p4s+AAAAAG7aij4AAAAAKXyMPgAAAABegY8+AAAAAN5OjD4AAAAA6HyLPgAAAADqqoo+AAAAAN0Mij4AAAAA29iJPgAAAABWeYs+AAAAAF6GVD4AAAAA4jVUPgAAAAB0Kkc+AAAAAE0ORj4AAAAAblVXPgAAAABVMkk+AAAAAOZUQj4AAAAAysFAPgAAAAB6BUQ+AAAAABrAcD4AAAAAcjdVPgAAAABv8XI+AAAAADZIQz4AAAAAG6RBPgAAAAABAEA+AAAAAD4uPz4AAAAA51s+PgAAAACl7kQ+AAAAABePJj8AAAAAjFQkPwAAAAC2Nyo/AAAAAEHgLD8AAAAAhT0cPwAAAAAX6SE/AAAAACNgLD8AAAAAszMvPwAAAAC38yM/AAAAAPo8Gj8AAAAA4ecLPwAAAABMSRE/AAAAAPsmEz8AAAAAOWsTPwAAAABfPiQ/AAAAAA6vLD8AAAAAw4gvPwAAAADGttc+AAAAAKjZ2D4AAAAAyyTcPgAAAAD9Pds+AAAAAFse2T4AAAAAE9DcPgAAAABBXd0+AAAAAI2I3D4AAAAAfyrePgAAAADO0dA+AAAAAIFM2T4AAAAAEn3dPgAAAADt994+AAAAABEu3z4AAAAAAlzePgAAAADnid0+AAAAAMe33D4AAAAAcCj9PgAAAACSvP4+AAAAAKyxAj8AAAAAHy8CPwAAAAD3j/4+AAAAACH4Aj8AAAAAMO0DPwAAAAD4gAM/AAAAAOJRBD8AAAAArRPvPgAAAABXLPA+AAAAAAsy/j4AAAAAdT8DPwAAAAC1tgQ/AAAAAE/sBD8AAAAASYMEPwAAAABDGgQ/AAAAADyxAz8AAAAAo0YWPwAAAAAQ8xc/AAAAALimFj8AAAAAotQVPwAAAAAmFRk/AAAAAAtLFz8AAAAATjcWPwAAAAAlwRU/AAAAAL+nFj8AAAAAQMUcPwAAAABxxhk/AAAAAAPCFz8AAAAAgxIXPwAAAABx+RY/AAAAAGmQFj8AAAAAZCcWPwAAAABdvhU/AAAAAPcY8D0AAAAAeAzqPQAAAADgeqY9AAAAAKNxpT0AAAAA3JD3PQAAAADWW6w9AAAAAOdsjT0AAAAAk2yKPQAAAAA0CJE9AAAAAESpQT4AAAAAsXv6PQAAAAByNUU+AAAAAGATBD4AAAAAmAqyPQAAAAA6nZQ9AAAAAAhpkD0AAAAA1CCNPQAAAACf2Ik9AAAAAGqQhj0AAAAAPnOHPQAAAAA2SIM9AAAAAHagpD0AAAAAzuQdPwAAAABBEh4/AAAAACQfHT8AAAAAoMYcPwAAAAAnhx4/AAAAAIOKHT8AAAAAt8QcPwAAAADBXRw/AAAAAAkuHT8AAAAA+t8fPwAAAAC3dCA/AAAAAFMJHz8AAAAAIPgdPwAAAACjlx0/AAAAANqJHT8AAAAA0yAdPwAAAADNtxw/AAAAAMhOHD8AAAAAjpcyPQAAAABV0k09AAAAAErD1TwAAAAAFba6PAAAAAC0u3I9AAAAAI+t9DwAAAAAmJeNPAAAAABvcn08AAAAAJjxnDwAAAAAt8G3PQAAAACy1BA9AAAAAJrI7j0AAAAAB2mQPAAAAAA1SIM8AAAAAMZObDwAAAAASFNfPAAAAAAdDVI8AAAAADcfnjwAAAAAedOMPgAAAADSE40+AAAAAKaniT4AAAAAhf2IPgAAAAAQO44+AAAAAKCPij4AAAAA92KIPgAAAADWlYc+AAAAANM3iT4AAAAAsaqMPgAAAAC+Bok+AAAAAJg0iD4AAAAAb2KHPgAAAAB/yIY+AAAAAE6Qhj4AAAAApFGIPgAAAAC2/Sc/AAAAAL5oJz8AAAAAGH0kPwAAAAB6XyQ/AAAAAF4OJz8AAAAAIZ4kPwAAAADQbiM/AAAAADkPIz8AAAAA2M4jPwAAAAA3ZSg/AAAAAISoJT8AAAAAuXskPwAAAAByJiQ/AAAAAEEaJD8AAAAAO7EjPwAAAAA1SCM/AAAAAC7fIj8AAAAAjqsiPwAAAAAodiI/AAAAAGMhJD8AAAAAKmCKPgAAAACg3oo+AAAAAAjreD4AAAAA7Op6PgAAAAB+iIs+AAAAAPMAeT4AAAAAhXZbPgAAAADQoF8+AAAAAOSdWj4AAAAAjWqLPgAAAAAFvpc+AAAAAPEsjD4AAAAAcgt6PgAAAABTa1s+AAAAAI3qQT4AAAAAPU1BPgAAAAAOvkI+AAAAACJLSD4AAAAApeFoPgAAAACdAlQ+AAAAANh1gD4AAAAApcNOPgAAAAC8YU4+AAAAAA7SQD4AAAAAkro/PgAAAAC3klE+AAAAAJreQj4AAAAAfss7PgAAAAD4ODo+AAAAAKZ8PT4AAAAAbhhsPgAAAABGik8+AAAAADRjaD4AAAAAzbc8PgAAAACxEzs+AAAAAJhvOT4AAAAAAKY4PgAAAAB8yzc+AAAAAJWfPj4AAAAA7HnlPgAAAADZ2ag+AAAAAAjMrj4AAAAA4CruPgAAAAAIsFc+AAAAAGm6Xj4AAAAAMu2wPgAAAAAfMfE+AAAAAIhOYT4AAAAAkrDRPgAAAABXZtc9AAAAAIbA5D0AAAAAy5vrPQAAAAB1Iu49AAAAANN+7j0AAAAA1KxhPgAAAAASO7E+AAAAAL2f8T4AAAAAJpjaPgAAAACxw9s+AAAAAO5Q3z4AAAAA42fePgAAAACe/9s+AAAAAMz53z4AAAAA4qHgPgAAAAAIzd8+AAAAALpu4T4AAAAAFPTUPgAAAAD7Itw+AAAAAHKk4D4AAAAA1TviPgAAAAAGduI+AAAAAACk4T4AAAAAB9LgPgAAAAAPAOA+AAAAACPUmT4AAAAAu8uUPgAAAABTIo0+AAAAAIYWlD4AAAAA63CPPgAAAABdE4Y+AAAAAOxqhT4AAAAAhMOOPgAAAAB1JHg+AAAAAF/InT4AAAAAV+xmPgAAAAAM930+AAAAAJeFij4AAAAAa22WPgAAAACTCJQ+AAAAAOOpmT4AAAAA5QQAPwAAAABR0wA/AAAAAMVHBD8AAAAADcQDPwAAAACpuAA/AAAAABCNBD8AAAAAio8FPwAAAAAuIwU/AAAAABn0BT8AAAAAgmfxPgAAAACCZvQ+AAAAAC2A8j4AAAAAUIQAPwAAAAA50wQ/AAAAAMRYBj8AAAAAapAGPwAAAABkJwY/AAAAAFy+BT8AAAAAVlUFPwAAAADX1ow+AAAAAIV/jT4AAAAAyXh8PgAAAAB7Qns+AAAAAP4fjj4AAAAAO6p9PgAAAAC4k10+AAAAAJF/XD4AAAAAR6dePgAAAADg0Jk+AAAAALHBjj4AAAAAbNx+PgAAAADtul8+AAAAAJy+RT4AAAAAlslEPgAAAACT1EM+AAAAAJDfQj4AAAAADspIPQAAAAA7eI88AAAAAG/hkDwAAAAAs7dNPQAAAAC/Ot47AAAAAGp92jsAAAAA6WyRPAAAAADhiE89AAAAAGhT2TsAAAAArDY/PQAAAAA0EY08AAAAAElQ6TsAAAAA6wzSOwAAAADPDNI7AAAAALMM0jsAAAAAlwzSOwAAAACtKNk7AAAAAMiAkTwAAAAAT8tPPQAAAAAT8ok+AAAAAKspij4AAAAAVXuGPgAAAACX04U+AAAAAJtZiz4AAAAAmWWHPgAAAAAXHoU+AAAAAFlRhD4AAAAAK/OFPgAAAAAd1Ik+AAAAAOMSkz4AAAAAN76FPgAAAAAs7IQ+AAAAACoahD4AAAAAaISDPgAAAAAsSIM+AAAAAB8qhT4AAAAAP22PPgAAAACRF5A+AAAAAOClgD4AAAAAOQqAPgAAAABntpA+AAAAAB8+gT4AAAAAn+NhPgAAAABPz2A+AAAAABb3Yj4AAAAA6m2cPgAAAAB5VpE+AAAAAL3WgT4AAAAAogpkPgAAAADSkkk+AAAAAMOdSD4AAAAAs6hHPgAAAACns0Y+AAAAAO4AST4AAAAAlo1IPgAAAACoeTo+AAAAANhmOT4AAAAAANBLPgAAAADgijw+AAAAABZCNT4AAAAAJbAzPgAAAADT8zY+AAAAAMJwZz4AAAAAHd1JPgAAAACtjGM+AAAAAGQnNj4AAAAASYM0PgAAAAAv3zI+AAAAAMMdMj4AAAAAFTsxPgAAAACGUDg+AAAAAJQ8BzwAAAAAwoRVPAAAAACKTjA8AAAAAKnOBDwAAAAASmy7PAAAAAAGG3Q8AAAAAGPiHzwAAAAA6XgDPAAAAABnVT88AAAAAInHeDwAAAAAyNEGPQAAAAB3yzc8AAAAAMeJHTwAAAAAEUgDPAAAAAB1ed0+AAAAAMqt3j4AAAAAKn3iPgAAAACqkeE+AAAAABTh3j4AAAAA0SPjPgAAAACf5uM+AAAAAFAR4z4AAAAAWLPkPgAAAAB2edU+AAAAALf53j4AAAAANszjPgAAAAA/gOU+AAAAAIm+5T4AAAAAZOzkPgAAAAA+GuQ+AAAAABxI4z4AAAAAk3UBPwAAAABbSAI/AAAAAN/dBT8AAAAA/FgFPwAAAABXKQI/AAAAAP8hBj8AAAAA4zEHPwAAAABhxQY/AAAAAE2WBz8AAAAAAtT0PgAAAACZ7wE/AAAAAP1mBj8AAAAA1PoHPwAAAACENAg/AAAAAH7LBz8AAAAAd2IHPwAAAABw+QY/AAAAAMJWHz8AAAAA1BwgPwAAAAA55x4/AAAAALBcHj8AAAAA2eQhPwAAAADduR8/AAAAAFJtHj8AAAAAGwAePwAAAACL4x4/AAAAACExIT8AAAAAOQwiPwAAAACWKiU/AAAAAPL9Iz8AAAAAzYggPwAAAABPWR8/AAAAAPMtHz8AAAAA7sQePwAAAADnWx4/AAAAAODyHT8AAAAAqwOSPgAAAACir5I+AAAAAGIPgz4AAAAAPnOCPgAAAADUTJM+AAAAACSngz4AAAAAmzNmPgAAAAAsH2U+AAAAAO5GZz4AAAAAmlWePgAAAAD4Cp8+AAAAAJcyoD4AAAAAQOuTPgAAAABEP4Q+AAAAAFpaaD4AAAAAB2dNPgAAAAD8cUw+AAAAAO58Sz4AAAAA4YdKPgAAAADSEIc+AAAAAK8/hz4AAAAAQ0+DPgAAAADkqYI+AAAAAEx4iD4AAAAA0DuEPgAAAACT2YE+AAAAACoNgT4AAAAA4q6CPgAAAABwpo8+AAAAAKL9hj4AAAAAEr+QPgAAAAAzdoI+AAAAADmkgT4AAAAAPtKAPgAAAACGQIA+AAAAAD4AgD4AAAAAxAKCPgAAAAAVmpQ+AAAAAK5HlT4AAAAA3HiFPgAAAABA3IQ+AAAAADnjlT4AAAAAIRCGPgAAAACAg2o+AAAAAPhuaT4AAAAAr5ZrPgAAAAACqKE+AAAAAAGAlj4AAAAAwaeGPgAAAADzqWw+AAAAABg7UT4AAAAAFUZQPgAAAAASUU8+AAAAAAxcTj4AAAAAOD5DPgAAAAB0uUI+AAAAAEMhND4AAAAAHBMzPgAAAABJDUY+AAAAACY3Nj4AAAAArbguPgAAAABQJy0+AAAAAABrMD4AAAAAF8liPgAAAADzL0Q+AAAAAGj6ZD4AAAAA+5YvPgAAAADg8i0+AAAAAMVOLD4AAAAAhZUrPgAAAACrqio+AAAAAHUBMj4AAAAAl6YIPgAAAADBQAU+AAAAAKzcyz0AAAAApzjLPQAAAAAcNgs+AAAAAENY0T0AAAAASY+0PQAAAACZm7E9AAAAAOoduD0AAAAA4mhMPgAAAADwgg0+AAAAAIMyTj4AAAAAS4O0PQAAAAAVO7E9AAAAAOLyrT0AAAAAdqauPQAAAACtqqo9AAAAAPeIyj0AAAAA9FrgPgAAAADzl+E+AAAAAIKp5T4AAAAAwbvkPgAAAABywuE+AAAAALZN5j4AAAAAhyvnPgAAAAAFVuY+AAAAAMz35z4AAAAAqcrZPgAAAAA50OE+AAAAAKTz5j4AAAAAQsToPgAAAACoBuk+AAAAALM06D4AAAAAsmLnPgAAAACkkOY+AAAAAEHmAj8AAAAAZL0DPwAAAAD3cwc/AAAAAOrtBj8AAAAABpoDPwAAAADstgc/AAAAAD7UCD8AAAAAlmcIPwAAAACCOAk/AAAAAOZaAz8AAAAAwfoHPwAAAADjnAk/AAAAAJ/YCT8AAAAAmG8JPwAAAACQBgk/AAAAAIudCD8AAAAATYQdPgAAAAAaohk+AAAAACW7/D0AAAAALXX8PQAAAADvmhw+AAAAAO0iAD4AAAAA953oPQAAAAAKtuU9AAAAAHnu6z0AAAAAWg4iPgAAAACbIFc+AAAAAJIG6T0AAAAAXb7lPQAAAAApduI9AAAAAFS64j0AAAAA8y3fPQAAAAD3kPs9AAAAAHowlz4AAAAAtt+XPgAAAABQ4oc+AAAAADhFhz4AAAAAoHmYPgAAAAAZeYg+AAAAAFLTbj4AAAAArr5tPgAAAABi5m8+AAAAABtdpT4AAAAAwhSZPgAAAAA/EIk+AAAAAI35cD4AAAAAKA9VPgAAAAAiGlQ+AAAAABolUz4AAAAAGjBSPgAAAACBL4Q+AAAAAK9VhD4AAAAALiOAPgAAAAAwAH8+AAAAAAmXhT4AAAAAHBKBPgAAAAAIKn0+AAAAAKWRez4AAAAAVtV+PgAAAAAOJ4Q+AAAAAEdijD4AAAAASWuOPgAAAABuXH4+AAAAAFS4fD4AAAAAMhR7PgAAAADM+Hk+AAAAAAVweT4AAAAAe7Z9PgAAAADgxpk+AAAAAMN3mj4AAAAAzUuKPgAAAAA1rok+AAAAAAgQmz4AAAAAG+KKPgAAAAA5I3M+AAAAAHAOcj4AAAAAMzZ0PgAAAADEaKc+AAAAAGDypz4AAAAAiqmbPgAAAADHeIs+AAAAAERJdT4AAAAAX+NYPgAAAABQ7lc+AAAAAD/5Vj4AAAAANARWPgAAAACBez0+AAAAAE/lPD4AAAAA3sgtPgAAAABjvyw+AAAAAJJKQD4AAAAAaeMvPgAAAABDLyg+AAAAAH6eJj4AAAAALOIpPgAAAABqIV4+AAAAAMmCPj4AAAAAoN9ZPgAAAAC9UmA+AAAAAJEGKT4AAAAAeGInPgAAAABeviU+AAAAAEcNJT4AAAAAQhokPgAAAABmsis+AAAAAC084z4AAAAA04HkPgAAAABn1eg+AAAAAGbl5z4AAAAAm6PkPgAAAAA/d+k+AAAAANRv6j4AAAAAJ5rpPgAAAADBO+s+AAAAAMA52z4AAAAAoqbkPgAAAADhGuo+AAAAAPUH7D4AAAAAVk7sPgAAAABYfOs+AAAAAHCq6j4AAAAAjtjpPgAAAADvVgQ/AAAAAGwyBT8AAAAAEgoJPwAAAADaggg/AAAAALMKBT8AAAAA20sJPwAAAACYdgo/AAAAAM0JCj8AAAAAuNoKPwAAAACue/k+AAAAADDGBD8AAAAAhI4JPwAAAADyPgs/AAAAALh8Cz8AAAAAshMLPwAAAACsqgo/AAAAAKZBCj8AAAAATF2cPgAAAADUD50+AAAAAE+1jD4AAAAAOReMPgAAAAB3pp0+AAAAACBLjT4AAAAAN3N3PgAAAABJXnY+AAAAABCGeD4AAAAAN7qoPgAAAAAjf6k+AAAAAO8Bqj4AAAAApYeqPgAAAABRPp4+AAAAAE7hjT4AAAAA/Jh5PgAAAACUt1w+AAAAAIrCWz4AAAAAfc1aPgAAAABw2Fk+AAAAABNOgT4AAAAAj2uBPgAAAADK7Xk+AAAAADqseD4AAAAAprWCPgAAAABk0Hs+AAAAAGKgdj4AAAAAhgh1PgAAAABfTHg+AAAAAGZQgT4AAAAA1st3PgAAAACiJ3Y+AAAAAHGDdD4AAAAAQHBzPgAAAABD33I+AAAAAC1ndz4AAAAAt/OePgAAAADgp58+AAAAAMoejz4AAAAAO4COPgAAAADcPKA+AAAAABq0jz4AAAAAG8N7PgAAAAAYrno+AAAAAMrVfD4AAAAAFJusPgAAAADkHK0+AAAAABDToD4AAAAAyUmQPgAAAACQ6H0+AAAAAJ2LYD4AAAAAoJZfPgAAAACfoV4+AAAAAJysXT4AAAAAyrg3PgAAAAAsETc+AAAAAHlwJz4AAAAAqGsmPgAAAADbhzo+AAAAALCPKT4AAAAA26UhPgAAAACrFSA+AAAAAFlZIz4AAAAAvnlZPgAAAACe1Tg+AAAAABsJVT4AAAAAEqtbPgAAAAApdiI+AAAAAA7SID4AAAAA9C0fPgAAAAAKhR4+AAAAANmJHT4AAAAAV2MlPgAAAABrHeY+AAAAAOBr5z4AAAAAkwHsPgAAAAAUD+s+AAAAAAiF5z4AAAAAO6HsPgAAAAB9tO0+AAAAAE7e7D4AAAAAVoDuPgAAAAAWod4+AAAAAJ2N3T4AAAAAWX3nPgAAAACfQu0+AAAAAGFM7z4AAAAA55bvPgAAAAC/xO4+AAAAAJHy7T4AAAAAaiDtPgAAAACexwU/AAAAAHanBj8AAAAAK6AKPwAAAADIFwo/AAAAAGF7Bj8AAAAAyuAKPwAAAAD0GAw/AAAAAP+rCz8AAAAA7HwMPwAAAACOE/4+AAAAAIPP+z4AAAAAezEGPwAAAABJIgs/AAAAAALhDD8AAAAA0yANPwAAAADNtww/AAAAAMZODD8AAAAAwOULPwAAAADjnqE+AAAAADzmoj4AAAAA942SPgAAAADlCZE+AAAAAKUEpT4AAAAAc5CVPgAAAACCboE+AAAAAAZXfz4AAAAA3EeFPgAAAABq960+AAAAALxasD4AAAAARmyyPgAAAACTmqg+AAAAAELgmj4AAAAAskSMPgAAAACYnn8+AAAAACbpbj4AAAAAc91lPgAAAACT7WE+AAAAAIr9Aj4AAAAAW1L/PQAAAACLTL89AAAAAHKHvj0AAAAA5N0FPgAAAADY7sQ9AAAAAI2Apz0AAAAAvIikPQAAAAAEFKs9AAAAAHiJSD4AAAAAFSYIPgAAAABoiUo+AAAAAHhipz0AAAAAQxqkPQAAAAAQ0qA9AAAAAKuSoT0AAAAA2omdPQAAAABZ0L09AAAAAN7GGT8AAAAAw+IZPwAAAAAKaxg/AAAAAC8WGD8AAAAAXm8aPwAAAABm3Bg/AAAAAG/fFz8AAAAA73gXPwAAAACASRg/AAAAAE8OHT8AAAAAiQ0bPwAAAACIThk/AAAAAKuzGD8AAAAAi50YPwAAAACGNBg/AAAAAH/LFz8AAAAAeGIXPwAAAAANpSQ/AAAAAHIMJT8AAAAAe30hPwAAAACkDCE/AAAAAMsiJj8AAAAAVRYiPwAAAACxLyA/AAAAAK/FHz8AAAAAsZ4gPwAAAAAaNyc/AAAAAHaeIj8AAAAAmgshPwAAAAAN0iA/AAAAAAdpID8AAAAAAQAgPwAAAAD6lh8/AAAAAF/ZfD4AAAAA4AJ9PgAAAAA6lXM+AAAAAGdYcj4AAAAAcqh/PgAAAAByfHU+AAAAAMMWcD4AAAAAkX9uPgAAAABGw3E+AAAAAOeqiD4AAAAAnPN8PgAAAACQw4k+AAAAAB47cT4AAAAA/JZvPgAAAADh8m0+AAAAAPDnbD4AAAAAxU5sPgAAAAATGHE+AAAAAPIHrj4AAAAAqmW0PgAAAABtgqw+AAAAALLqoj4AAAAA9pK6PgAAAABVG7Y+AAAAAPK6oz4AAAAALe6WPgAAAAACnrA+AAAAAAGztT4AAAAANl+8PgAAAAAe278+AAAAANZIvj4AAAAAT467PgAAAABy2Lg+AAAAAEqoqz4AAAAAfRecPgAAAADjpIw+AAAAABL2MT4AAAAACD0xPgAAAAASGCE+AAAAAO4XID4AAAAAJMU0PgAAAAD1OyM+AAAAAHQcGz4AAAAA14wZPgAAAACF0Bw+AAAAABPSVD4AAAAAdCgzPgAAAACSMlA+AAAAAGQDVz4AAAAAv+UbPgAAAAClQRo+AAAAAIudGD4AAAAAzPwXPgAAAABx+RY+AAAAAEgUHz4AAAAA7f7oPgAAAAARVuo+AAAAAPct7z4AAAAALjnuPgAAAAB2Zuo+AAAAADXL7z4AAAAAdPnwPgAAAAAKI/A+AAAAAOXE8T4AAAAAfuHfPgAAAAD0U+o+AAAAADFq8D4AAAAAjpDyPgAAAAAt3/I+AAAAACMN8j4AAAAAFjvxPgAAAAAEafA+AAAAAPEL2z0AAAAALfPbPQAAAADW45g9AAAAACnmlT0AAAAAxrfqPQAAAAD7KZ89AAAAAE09gD0AAAAA1Px5PQAAAABB5YM9AAAAAPYaND4AAAAAjELaPQAAAACLkUA+AAAAAAEAgD0AAAAAmW95PQAAAAAx33I9AAAAAPVscz0AAAAAx05sPQAAAAAUoJI9AAAAAEo4Bz8AAAAAfxwIPwAAAABENgw/AAAAALesCz8AAAAADuwHPwAAAAC5dQw/AAAAAE67DT8AAAAANk4NPwAAAAAhHw4/AAAAALIK/T4AAAAAWCP+PgAAAADEnAc/AAAAAAy2DD8AAAAAEYMOPwAAAADtxA4/AAAAAOdbDj8AAAAA3/INPwAAAADaiQ0/AAAAAJzUIT8AAAAAposePwAAAAALGyM/AAAAAOfaIz8AAAAApFYcPwAAAACxsCI/AAAAACeyJD8AAAAAO24kPwAAAADBACU/AAAAAORXGj8AAAAA2nobPwAAAADCyiI/AAAAAOtfJT8AAAAAXb4lPwAAAABWVSU/AAAAAFDsJD8AAAAAS4MkPwAAAAAmr6A+AAAAAEV4oD4AAAAA5muePgAAAADIq54+AAAAACO8nz4AAAAA5PmcPgAAAABnWJ0+AAAAAPrTnT4AAAAA0yabPgAAAADqa6A+AAAAACX6mT4AAAAAndWcPgAAAAC8l50+AAAAAKllnT4AAAAAQj2dPgAAAAB+N54+AAAAAKkWdz4AAAAAvC53PgAAAADWPG0+AAAAAK8EbD4AAAAAueV5PgAAAAC1KG8+AAAAAFuNaT4AAAAAwPZnPgAAAABvOms+AAAAABBXhj4AAAAAcUZ3PgAAAAC5b4c+AAAAAKyqaj4AAAAAlAZpPgAAAAB6Ymc+AAAAALVfZj4AAAAAX75lPgAAAAAEyWo+AAAAAOLXwz4AAAAAd1fGPgAAAAB8bsc+AAAAADz6wz4AAAAAaH3HPgAAAADbRck+AAAAAH1wxz4AAAAADwPDPgAAAAC+y8k+AAAAAN6vwT4AAAAAcsfDPgAAAABwIcg+AAAAACVWyj4AAAAAthDLPgAAAACQHss+AAAAAPC6yT4AAAAAGgLHPgAAAAD2xcE+AAAAAF0zLD4AAAAA42grPgAAAACtvxo+AAAAADTEGT4AAAAAbAIvPgAAAAA66Bw+AAAAAAuTFD4AAAAABAQTPgAAAAC1RxY+AAAAAGYqUD4AAAAASXstPgAAAAC6W1I+AAAAAFdVFT4AAAAAPLETPgAAAAAiDRI+AAAAAI50ET4AAAAACWkQPgAAAAA4xRg+AAAAAEjg6z4AAAAAIkDtPgAAAAAmWvI+AAAAAAxj8T4AAAAA0kftPgAAAAAR9fI+AAAAACU+9D4AAAAAdGfzPgAAAABMCfU+AAAAAKgc4T4AAAAAiyrtPgAAAAC6kfM+AAAAALDU9T4AAAAAZCf2PgAAAABVVfU+AAAAAEaD9D4AAAAAO7HzPgAAAADXcLc9AAAAAC1Ptj0AAAAACMSEPQAAAAD2fYI9AAAAAA7PxT0AAAAAMYWLPQAAAAA2eWQ9AAAAAFgpXj0AAAAA3+drPQAAAADxOg8+AAAAAOsFvD0AAAAAZ7UYPgAAAABevmU9AAAAAPQtXz0AAAAAjJ1YPQAAAACtBFg9AAAAACMNUj0AAAAAuuSAPQAAAAD3qAg/AAAAAIiRCT8AAAAAXswNPwAAAAClQQ0/AAAAALxcCT8AAAAApwoOPwAAAACnXQ8/AAAAAGvwDj8AAAAAVsEPPwAAAACGXv8+AAAAAJg7AD8AAAAADwgJPwAAAADRSQ4/AAAAACIlED8AAAAACWkQPwAAAAACABA/AAAAAPuWDz8AAAAA9C0PPwAAAABHBBk+AAAAAAPCFT4AAAAARlPxPQAAAADLpPA9AAAAAOUVGz4AAAAA5mH2PQAAAABCtNs9AAAAAEW/2D0AAAAARDXfPQAAAABxQVg+AAAAAL/l2z0AAAAAjJ3YPQAAAABXVdU9AAAAAHrSHD8AAAAAB/gdPwAAAADBASQ/AAAAALFmIz8AAAAAPoYdPwAAAAC1LyQ/AAAAAJQ+Jj8AAAAATc8lPwAAAAA5oCY/AAAAAB36Dz8AAAAA4WMSPwAAAAByhhA/AAAAACXmHD8AAAAAh14kPwAAAAD5ASc/AAAAAHdiJz8AAAAAcfkmPwAAAABqkCY/AAAAAGMnJj8AAAAALxuePgAAAAC9jJ4+AAAAAFyrnD4AAAAAOfibPgAAAABFd58+AAAAAGJ3nT4AAAAAevibPgAAAABFMJs+AAAAAGu4nD4AAAAALLKdPgAAAAD1JaI+AAAAACeanD4AAAAAT9+bPgAAAADSFJs+AAAAALVhmj4AAAAAykKaPgAAAADuPps+AAAAAPFTcT4AAAAAmFpxPgAAAABx5GY+AAAAAPOwZT4AAAAAAyN0PgAAAAD61Gg+AAAAAPIDYz4AAAAA6m1hPgAAAACasWQ+AAAAAEeZcT4AAAAARRpkPgAAAAAqdmI+AAAAAA/SYD4AAAAAdddfPgAAAAD1LV8+AAAAAPR5ZD4AAAAAYEHJPgAAAAAGQ8o+AAAAABtBzD4AAAAA5lTLPgAAAAAGt8o+AAAAACr+zD4AAAAAj/3MPgAAAADcEsw+AAAAAGTUzT4AAAAACkfGPgAAAACVG8s+AAAAAJa3zT4AAAAA86POPgAAAACZxs4+AAAAAGn0zT4AAAAA/RjNPgAAAABcKsw+AAAAAKRwJj4AAAAAv5QlPgAAAABHZxQ+AAAAAHlwEz4AAAAAtT8pPgAAAAB/lBY+AAAAAKIJDj4AAAAAMnsMPgAAAADfvg8+AAAAALyCSz4AAAAAHs4nPgAAAACGhUY+AAAAAA60TT4AAAAA7cQOPgAAAADUIA0+AAAAALp8Cz4AAAAAUuwKPgAAAACf2Ak+AAAAACl2Ej4AAAAApsHuPgAAAAA2KvA+AAAAAFqG9T4AAAAA7Iz0PgAAAAAtKfA+AAAAAPAe9j4AAAAA24L3PgAAAADhq/Y+AAAAALpN+D4AAAAAf3DjPgAAAAAqieQ+AAAAACAB8D4AAAAAQrn2PgAAAADQGPk+AAAAAJtv+T4AAAAAjp34PgAAAACAy/c+AAAAAHP59j4AAAAAPJWrPQAAAACA9ac9AAAAAOZGbj0AAAAADnFrPQAAAABfM7E9AAAAAC0BeD0AAAAApBdKPQAAAACM/kM9AAAAAEcNUT0AAAAAlauwPQAAAAC7fEs9AAAAAFDsRD0AAAAA51s+PQAAAAC14z09AAAAAH7LNz0AAAAANI1oPQAAAACmGQo/AAAAAJIGCz8AAAAAeGIPPwAAAACV1g4/AAAAAGnNCj8AAAAAlp8PPwAAAAACABE/AAAAAJ6SED8AAAAAjGMRPwAAAABZcwo/AAAAAJXdDz8AAAAAMMcRPwAAAAAjDRI/AAAAABykET8AAAAAFTsRPwAAAAAQ0hA/AAAAAChDHj8AAAAAEW0fPwAAAADZlyU/AAAAAKH7JD8AAAAA7PYePwAAAACixCU/AAAAAO/gJz8AAAAAg3EnPwAAAABtQig/AAAAAFywET8AAAAAb1EePwAAAABL8iU/AAAAAAmkKD8AAAAAkgYpPwAAAACLnSg/AAAAAIQ0KD8AAAAAfssnPwAAAACLIBs/AAAAAKZAGz8AAAAARPoZPwAAAABGpRk/AAAAAKC/Gz8AAAAAR2gaPwAAAADugBk/AAAAAGgaGT8AAAAAlOoZPwAAAABArR0/AAAAACFeHj8AAAAAn9gZPwAAAACYbxk/AAAAAJIGGT8AAAAANjqbPgAAAAATpps+AAAAAICEmT4AAAAAxM6YPgAAAAC7oZw+AAAAAM5gmj4AAAAAVrqYPgAAAADR65c+AAAAANCNmT4AAAAAOvGfPgAAAACd25o+AAAAAEi8nz4AAAAA4gmhPgAAAADzb5k+AAAAAIadmD4AAAAAZ8uXPgAAAAAoHZc+AAAAAG75lj4AAAAAUheYPgAAAAA7kWs+AAAAAHGGaz4AAAAACoxgPgAAAAA4XV8+AAAAAExgbj4AAAAAP4FiPgAAAACKelw+AAAAABjlWj4AAAAAxyhePgAAAAAc7Gs+AAAAANmJXT4AAAAAv+VbPgAAAACmQVo+AAAAADZPWT4AAAAAjJ1YPgAAAADkKl4+AAAAAGwxzD4AAAAAfjHNPgAAAAA1dM8+AAAAALqWzj4AAAAAEJnNPgAAAADeKNA+AAAAAMVK0D4AAAAAWnfPPgAAAAAyGdE+AAAAADebyD4AAAAAVvLNPgAAAAA939A+AAAAANPn0T4AAAAAsw3SPgAAAACcO9E+AAAAAJRp0D4AAAAA1ZfPPgAAAADtrSA+AAAAAJnAHz4AAAAA4g4OPgAAAAC/HA0+AAAAAP18Iz4AAAAAxkAQPgAAAAA5gAc+AAAAAF/yBT4AAAAADDYJPgAAAABjDEk+AAAAAIY0CD4AAAAAapAGPgAAAABQ7AQ+AAAAAAGj8T4AAAAASBTzPgAAAACMsvg+AAAAAMe29z4AAAAAiQrzPgAAAADMSPk+AAAAAJDH+j4AAAAASvD5PgAAAAAhkvs+AAAAAP/c5j4AAAAAweX7PgAAAAC0E/s+AAAAAKZB+j4AAAAAzg+gPQAAAAA3TZw9AAAAAE/lVD0AAAAAJCJSPQAAAADwraU9AAAAAEOyXj0AAAAAAvIvPQAAAABA2yk9AAAAAPrpNj0AAAAAp68FPgAAAABN5/s9AAAAAPrgBz4AAAAAFzsxPQAAAACsqio9AAAAAEQaJD0AAAAAVIoLPwAAAACaeww/AAAAAJH4ED8AAAAAgmsQPwAAAAAYPgw/AAAAAIU0ET8AAAAAXKISPwAAAADUNBI/AAAAAL8FEz8AAAAATOADPwAAAAA2SBM/AAAAAC/fEj8AAAAAKHYSPwAAAADVsx8/AAAAABniID8AAAAA9C0nPwAAAACPkCY/AAAAAJlnID8AAAAAkVknPwAAAABKgyk/AAAAALgTKT8AAAAAouQpPwAAAABH2hI/AAAAAKRBKj8AAAAAn9gpPwAAAACZbyk/AAAAAK/S/D0AAAAAzvT0PQAAAADY+7I9AAAAAEGSsj0AAAAATmUAPgAAAAAPV7g9AAAAAL55mj0AAAAAXo2XPQAAAABVBJ49AAAAADSBRj4AAAAAyUlHPgAAAACmQZo9AAAAAHL5lj0AAAAAPbGTPQAAAAAEWZg+AAAAACi8mD4AAAAAh1iWPgAAAAAopZU+AAAAAHrAmT4AAAAADTeXPgAAAADmdZU+AAAAALqnlD4AAAAAa0mWPgAAAAAZUZ0+AAAAABu2nj4AAAAAgSeWPgAAAACOVZU+AAAAAJGDlD4AAAAA9NAmPwAAAADrmCY/AAAAABgeIz8AAAAAM98iPwAAAAAiZyc/AAAAANKeIz8AAAAAW9MhPwAAAACXbyE/AAAAAFc/Ij8AAAAA3nguPwAAAAAj1S4/AAAAACINIj8AAAAAGqQhPwAAAAAUOyE/AAAAAILOZT4AAAAATrJlPgAAAACkM1o+AAAAAHwJWT4AAAAAlZ1oPgAAAACELVw+AAAAACDxVT4AAAAARFxUPgAAAAD0n1c+AAAAAB63fj4AAAAASr17PgAAAABx+VY+AAAAAFZVVT4AAAAAPLFTPgAAAADkEs8+AAAAAI0b0D4AAAAAXqDSPgAAAAC1wNE+AAAAAEl60D4AAAAAfVLTPgAAAABej9M+AAAAAL670j4AAAAARl3UPgAAAABi1sk+AAAAABpHyz4AAAAA/u7KPgAAAABjg9Q+AAAAAI2x0z4AAAAArd/SPgAAAAAAQGQ/AAAAAOp+ZD8AAAAA6H5kPwAAAAABQGQ/AAAAAEG3ZD8AAAAAQLdkPwAAAADofmQ/AAAAAABAZD8AAAAAQLdkPwAAAAD/P2Q/AAAAAOl+ZD8AAAAAP7dkPwAAAABBt2Q/AAAAAOl+ZD8AAAAAAEBkPwAAAAD05mM/AAAAAMM4ZD8AAAAAsE1iPwAAAACad2E/AAAAABODZD8AAAAA4xVjPwAAAAAsIl0/AAAAAMrcWj8AAAAA7lNfPwAAAAACQGQ/AAAAAEC3ZD8AAAAAuapYPwAAAAA7QFM/AAAAAM3cWj8AAAAALCJdPwAAAACwTWI/AAAAAJh3YT8AAAAA7lNfPwAAAADjFWM/AAAAAME4ZD8AAAAA9eZjPwAAAAASg2Q/AAAAAFRSWT8AAAAAy29gPwAAAABBimM/AAAAAAzAZD8AAAAAT+xkPwAAAADofmQ/AAAAAABAZD8AAAAAVJJjPwAAAABB92M/AAAAAN7PYD8AAAAAzjRWPwAAAACVNVg/AAAAAHP7Xz8AAAAAmSJfPwAAAACw3Vg/AAAAAGtxYD8AAAAAydpiPwAAAAAhZ2I/AAAAAFY8Yz8AAAAAMMJEPwAAAADbbFQ/AAAAAAUxST8AAAAAHyBKPwAAAAD+9GE/AAAAANJsXj8AAAAA5qdzPwAAAADDAHQ/AAAAAOA+dz8AAAAAWdt2PwAAAABkuHM/AAAAAPF1dz8AAAAAtXF4PwAAAABfCXg/AAAAAH3UeD8AAAAAsrtsPwAAAADZbW0/AAAAANQgcz8AAAAA+r1tPwAAAADmamw/AAAAAOV/cz8AAAAAkbp3PwAAAAD3OHk/AAAAAJdveT8AAAAAip14PwAAAAA/n3c/AAAAAH7Ldz8AAAAAg2l2PwAAAACtrl8/AAAAAGjjXT8AAAAAFCFjPwAAAADNe2M/AAAAAAcXXD8AAAAAPMdiPwAAAACiEmU/AAAAAKvsZD8AAAAAcT5lPwAAAABV21M/AAAAAFkWTz8AAAAAgFhMPwAAAACgG1s/AAAAAESwYj8AAAAAO3tlPwAAAABg4WU/AAAAAJ+YZT8AAAAAXiFlPwAAAABIJjU/AAAAAEKENT8AAAAAlIo2PwAAAAAUJTY/AAAAAPesNT8AAAAAX+E2PwAAAACV6zY/AAAAAACDNj8AAAAAU1I3PwAAAAC1NjM/AAAAAMy3ND8AAAAAnlMzPwAAAABl2jU/AAAAAIo8Nz8AAAAAoLk3PwAAAABqkDY/AAAAAMUZNj8AAAAAYyc2PwAAAAB5ujU/AAAAAB7OPj8AAAAAbf0+PwAAAAD66UQ/AAAAADebRD8AAAAA49c+PwAAAAAIJUU/AAAAAGgTRz8AAAAAq61GPwAAAACvdkc/AAAAAHMvPz8AAAAAaYkyPwAAAAAw3z4/AAAAAJFwRT8AAAAAB9xHPwAAAACENEg/AAAAAH7LRz8AAAAAdmJHPwAAAABy+UY/AAAAAIRMRj8AAAAAa5BGPwAAAAA0cUQ/AAAAAMozSj8AAAAARIlLPwAAAACy/lI/AAAAAMxWUj8AAAAAj+dKPwAAAADNH1M/AAAAAE7CVT8AAAAAalFVPwAAAABWIlY/AAAAAOegSD8AAAAAMgxKPwAAAADJQVM/AAAAAHuCVj8AAAAAaZBWPwAAAABkJ1Y/AAAAAFy+VT8AAAAAbeBUPwAAAAAHrlE/AAAAAIkhcj8AAAAAyK5yPwAAAADqs3U/AAAAAChAdT8AAAAAgOdyPwAAAACgDnY/AAAAAMPQdj8AAAAAYWZ2PwAAAAD9N3c/AAAAAFoObD8AAAAAs5NxPwAAAAC4w2w/AAAAAHhidz8AAAAA//t1PwAAAAA6zHQ/AAAAADC0Qj8AAAAAwHtCPwAAAADlwEQ/AAAAAB2NRD8AAAAAVAlBPwAAAABzmkQ/AAAAAK6eRT8AAAAATjxFPwAAAADF9UU/AAAAAArBPj8AAAAAD1JCPwAAAABfvkU/AAAAAFdVRT8AAAAApNNEPwAAAADnJkQ/AAAAAPtLWz8AAAAAYVJbPwAAAADUPGM/AAAAAAP6Yj8AAAAAzv1ZPwAAAACIJWM/AAAAAM0pZj8AAAAAo85lPwAAAABuf2Y/AAAAAHtbTD8AAAAASxxIPwAAAACL51g/AAAAAHQ4Yz8AAAAANd1mPwAAAAB1Ymc/AAAAAPz5Zj8AAAAAyZRmPwAAAAAnNmY/AAAAAOPnQD8AAAAA8p1BPwAAAABeXUM/AAAAAOreQj8AAAAAUAJCPwAAAABUxUM/AAAAAKgCRD8AAAAA8pZDPwAAAACMa0Q/AAAAAA8QPT8AAAAADjtAPwAAAADKPD4/AAAAAMyUPj8AAAAAS4NEPwAAAABEGkQ/AAAAACEsQz8AAAAANUhDPwAAAACSZ0I/AAAAAG1vMz8AAAAAp/wzPwAAAAAJ7zQ/AAAAAAl8ND8AAAAALF80PwAAAABJVjU/AAAAAI5INT8AAAAARt40PwAAAABasTU/AAAAAIlhMT8AAAAAZ+cyPwAAAABP7DQ/AAAAAHt0ND8AAAAA1ww0PwAAAACEmD8/AAAAAD1RQD8AAAAAB3JGPwAAAABk8UU/AAAAAHheQD8AAAAA3L9GPwAAAAABtEg/AAAAAAZISD8AAAAAoBlJPwAAAABMPDM/AAAAADhiND8AAAAAqvEzPwAAAABSbEA/AAAAANwNRz8AAAAASH9JPwAAAACf2Ek/AAAAAJIGST8AAAAAVPBvPwAAAAB863A/AAAAAOMFdD8AAAAADnRzPwAAAAD6UnE/AAAAAA1vdD8AAAAAZyt1PwAAAABIvXQ/AAAAAHKUdT8AAAAAhBFpPwAAAAA2BW8/AAAAAAbsaj8AAAAAVlV1PwAAAABR7HQ/AAAAAL9QdD8AAAAASYN0PwAAAADv7nI/AAAAAAG1Sz8AAAAAmYJNPwAAAAC8vVQ/AAAAANnwUz8AAAAAnfNNPwAAAACRKlU/AAAAAMdpVz8AAAAARPRWPwAAAABG01c/AAAAAMKJPz8AAAAAbOo/PwAAAACIgz8/AAAAAJIGTj8AAAAATHpVPwAAAAAjOVg/AAAAAIydWD8AAAAAhjRYPwAAAAB+y1c/AAAAAHZiVz8AAAAAF8Q/PwAAAACkIEA/AAAAALDEQT8AAAAAvF9BPwAAAADxKUA/AAAAAKsSQj8AAAAA+l9CPwAAAAB290E/AAAAAKDFQj8AAAAANBw8PwAAAABhozw/AAAAAMdOPz8AAAAAC/Y8PwAAAAAiDUI/AAAAAPyNQT8AAAAAHKRBPwAAAAAe80A/AAAAAPy3Wj8AAAAAjbFcPwAAAAB+yWQ/AAAAAEbwYz8AAAAAjyRdPwAAAAAYN2U/AAAAACPHZz8AAAAAFVBnPwAAAAC9MGg/AAAAACbyTD8AAAAA9C1dPwAAAAAEhGU/AAAAAD+WaD8AAAAAgzRoPwAAAACebDY/AAAAAK+7Mz8AAAAA4dk0PwAAAAAQGjg/AAAAAAfZMj8AAAAAPOAzPwAAAADpRTU/AAAAABC7OD8AAAAA9kA0PwAAAADkWDM/AAAAADrEPD8AAAAA4rExPwAAAADy2zA/AAAAAMdOND8AAAAAWVU1PwAAAAAQ0jg/AAAAANvhPz8AAAAAzA4/PwAAAAB3JkE/AAAAAAPgQT8AAAAAzw9IPwAAAADvjkc/AAAAAGrsQT8AAAAAZF1IPwAAAABSV0o/AAAAAE/rST8AAAAA6LxKPwAAAADlqzQ/AAAAAMLTNT8AAAAAcflBPwAAAAAnq0g/AAAAAIYiSz8AAAAAt3xLPwAAAACyE0s/AAAAALa6Tj8AAAAANApPPwAAAABHWVY/AAAAAFr5VT8AAAAAi/JNPwAAAAAuVlY/AAAAANAMWT8AAAAA6qRYPwAAAABSaFk/AAAAAMuiQD8AAAAAguxAPwAAAAAbkD0/AAAAADD/TD8AAAAAfnFWPwAAAACix1k/AAAAAKDYWT8AAAAAmW9ZPwAAAACSBlk/AAAAAMEUbz8AAAAALm5vPwAAAAA2bXI/AAAAAHUJcj8AAAAAYjJvPwAAAADPp3I/AAAAALuIcz8AAAAAXSBzPwAAAAD063M/AAAAAGuQbj8AAAAAR6VpPwAAAADNcWg/AAAAAEQadD8AAAAAPLFzPwAAAAA1SHM/AAAAAFa2cj8AAAAALd9yPwAAAABwmHE/AAAAACg6Pj8AAAAAD7I+PwAAAADfMEA/AAAAAHDDPz8AAAAAGgA/PwAAAADokUA/AAAAAOm9QD8AAAAAVFRAPwAAAADuJUE/AAAAAKbBPT8AAAAAqvE7PwAAAAAWO0E/AAAAAA/SQD8AAAAAvOo/PwAAAADTVT8/AAAAAET+XT8AAAAA9c1ePwAAAAAXk2Y/AAAAAKYLZj8AAAAANMRePwAAAAAc2mY/AAAAAO5vaT8AAAAAGgNpPwAAAACz1Gk/AAAAAP9PTj8AAAAAzF9OPwAAAAAWu14/AAAAAE8hZz8AAAAAgDlqPwAAAACZb2k/AAAAAGWlQj8AAAAAlfZCPwAAAABkiEk/AAAAANAnST8AAAAAnARCPwAAAADgj0k/AAAAAPr1Sz8AAAAAAo5LPwAAAADOUkw/AAAAAKH7NT8AAAAA50gzPwAAAAA5M0E/AAAAALKyST8AAAAAELNMPwAAAADUIE0/AAAAAM63TD8AAAAAxk5MPwAAAAC+5Us/AAAAANqNbT8AAAAAzRduPwAAAADj4HA/AAAAABxucD8AAAAAzVNuPwAAAACSPHE/AAAAAJnncT8AAAAAW31xPwAAAAD1TnI/AAAAAJM7Zz8AAAAAGvRnPwAAAABMA20/AAAAACmraD8AAAAAJ3ZyPwAAAAAcpHE/AAAAABgTcT8AAAAAJvtvPwAAAAB9sE4/AAAAAH+HUD8AAAAA9fFXPwAAAABuIlc/AAAAAPL4UD8AAAAA8l5YPwAAAAB7r1o/AAAAAKU5Wj8AAAAAABlbPwAAAADWLz4/AAAAAEEzQj8AAAAANpRCPwAAAADbCVE/AAAAABOuWD8AAAAAzH5bPwAAAADB5Vs/AAAAAK6qWj8AAAAAN4xfPwAAAAC6XGA/AAAAAN8waD8AAAAAMKlnPwAAAAArUmA/AAAAAKd3aD8AAAAAPxNrPwAAAABjpmo/AAAAAPx3az8AAAAA83RQPwAAAABwzU8/AAAAADdIYD8AAAAAnL5oPwAAAADB3Gs/AAAAAMHlaz8AAAAAuXxrPwAAAACzE2s/AAAAADasPD8AAAAASSM9PwAAAAAXkz4/AAAAAOklPj8AAAAAKnI9PwAAAABd9D4/AAAAAJgaPz8AAAAADbE+PwAAAACogj8/AAAAAOxAOT8AAAAAt8w5PwAAAACFNDw/AAAAAApXOj8AAAAAEYI6PwAAAAD6lj8/AAAAAO/EPj8AAAAAfEc+PwAAAADmWz4/AAAAAIi4PT8AAAAAU2ljPwAAAAAoKFY/AAAAADtzWD8AAAAAozRmPwAAAAA/S0g/AAAAAHuESj8AAAAADlBZPwAAAAC7PGc/AAAAALBdSz8AAAAAHwBePwAAAAA9MW4/AAAAAB2SRD8AAAAAunxLPwAAAACYb1k/AAAAAHdiZz8AAAAA0rJyPwAAAAAv33I/AAAAADx8cT8AAAAAj8JCPwAAAADgc0Q/AAAAABIhSz8AAAAAHlxKPwAAAACe40Q/AAAAAGeNSz8AAAAApphNPwAAAAAhJE0/AAAAABgCTj8AAAAAQo03PwAAAAAK7Tc/AAAAAAmVNz8AAAAAuvxEPwAAAADw3ks/AAAAAC5oTj8AAAAA4vJNPwAAAADaiU0/AAAAAOn/az8AAAAACIlsPwAAAAAaQ28/AAAAAJHQbj8AAAAA28VsPwAAAAAIn28/AAAAAEpEcD8AAAAAFNpvPwAAAACuq3A/AAAAAO7NZT8AAAAAgYRmPwAAAAAqdms/AAAAAA7ScD8AAAAACGlwPwAAAAACAHA/AAAAANdvbz8AAAAA2V1uPwAAAAAOwFE/AAAAABwPUj8AAAAAgI1ZPwAAAAC/LVk/AAAAAAbuUD8AAAAAwodZPwAAAACEUlw/AAAAAKfqWz8AAAAAsq1cPwAAAACVTEM/AAAAAOkhQD8AAAAALPJPPwAAAAAyoVk/AAAAAMYMXT8AAAAA1CBdPwAAAADPt1w/AAAAAHMXZj8AAAAATJxpPwAAAABPMW0/AAAAAIjaaz8AAAAAKAxrPwAAAAD/8m0/AAAAAHySbj8AAAAAvAtuPwAAAACVBm8/AAAAAFu5XD8AAAAAmhBiPwAAAAC6dGM/AAAAANx/ZT8AAAAA9i1vPwAAAADuxG4/AAAAAKSHbT8AAAAA4vJtPwAAAAD0mGo/AAAAAFjXOj8AAAAAs307PwAAAABC7jw/AAAAADZ0PD8AAAAAW+E7PwAAAADzVT0/AAAAAGZ2PT8AAAAAPgs9PwAAAABC3z0/AAAAAKavNz8AAAAArTg6PwAAAABoDDk/AAAAAOHyPT8AAAAA2ok9PwAAAADTID0/AAAAANOgPD8AAAAAAAA8PwAAAACzFWE/AAAAANHHYT8AAAAACMhpPwAAAADlRWk/AAAAADuAYT8AAAAAGg1qPwAAAAC7tWw/AAAAAJFJbD8AAAAAQxptPwAAAAA1G1E/AAAAAMDvUT8AAAAA0yBtPwAAAADNt2w/AAAAAE7KeD8AAAAAOYB4PwAAAADxCnw/AAAAAIvcfD8AAAAA4DF1PwAAAACqnHg/AAAAAP1ZfT8AAAAA7ll+PwAAAAAS33k/AAAAAJb6dz8AAAAA/adxPwAAAAAjDXo/AAAAAGuQfj8AAAAAMSF+PwAAAADnW34/AAAAADWGfD8AAAAAKLpFPwAAAAD7dkY/AAAAANXiTD8AAAAA+2BMPwAAAAAcgEY/AAAAAHMvTT8AAAAAdkBPPwAAAABV1E4/AAAAAO+lTz8AAAAAJcY4PwAAAACDezk/AAAAAK8COT8AAAAA3IlGPwAAAAA/fE0/AAAAAHILUD8AAAAABABQPwAAAAD7lk8/AAAAAPUtTz8AAAAA9qtRPwAAAABojFM/AAAAAC0mWz8AAAAAAlRaPwAAAABH/lM/AAAAAFaTWz8AAAAAMPVdPwAAAAAEf10/AAAAALxeXj8AAAAApMFAPwAAAADC3EQ/AAAAACINVD8AAAAA3OFbPwAAAABxxF4/AAAAAOlbXj8AAAAA4vJdPwAAAAAiozk/AAAAAGYAOj8AAAAAlVU7PwAAAABb8Do/AAAAAGYZOj8AAAAA96c7PwAAAAC60zs/AAAAAC1rOz8AAAAA6jk8PwAAAAAWnDY/AAAAAP4aNz8AAAAAPTE5PwAAAADrDzc/AAAAAMdOPD8AAAAAv+U7PwAAAAC6fDs/AAAAANUBOz8AAAAAtBM7PwAAAAC+hDo/AAAAAIk4Rz8AAAAAKIlHPwAAAAAOWk4/AAAAALL5TT8AAAAAoIpGPwAAAAADXk4/AAAAAPbeUD8AAAAABHdQPwAAAABXO1E/AAAAALgUOj8AAAAANF86PwAAAAAAQjc/AAAAAOmtRT8AAAAAVH5OPwAAAABJm1E/AAAAACINUj8AAAAAG6RRPwAAAAAQ0lA/AAAAAAk7eD8AAAAAVpN4PwAAAACJEHw/AAAAADutez8AAAAAZz54PwAAAAAURHw/AAAAALBafT8AAAAAYPJ8PwAAAAAGvX0/AAAAAPCGcT8AAAAAPbF3PwAAAAABZHA/AAAAANQgfT8AAAAAJoh8PwAAAADNt3w/AAAAAJc6ez8AAAAA4tZUPwAAAAACoFU/AAAAAArtXD8AAAAAi2dcPwAAAADTnFU/AAAAAAI2XT8AAAAApJ1fPwAAAAANMV8/AAAAAKgCYD8AAAAAeRtGPwAAAABNaEc/AAAAANY6Rj8AAAAAQ5pVPwAAAAAnf10/AAAAALJnYD8AAAAAENJgPwAAAAAAAGA/AAAAAN/bNz8AAAAAy3g4PwAAAAAKujk/AAAAAKNCOT8AAAAACNw4PwAAAACQITo/AAAAALEwOj8AAAAA3sU5PwAAAACKmTo/AAAAALJFNz8AAAAAYgs2PwAAAACdYjY/AAAAAKyqOj8AAAAAn9g5PwAAAACwWzk/AAAAAE7QOD8AAAAAPLV2PwAAAAC/RXc/AAAAAO+Gej8AAAAANBJ6PwAAAAAve3c/AAAAAKvgej8AAAAA5rl7PwAAAABoT3s/AAAAAAMhfD8AAAAAHCR2PwAAAAA673A/AAAAAPndcD8AAAAAunx7PwAAAADn5Ho/AAAAAE2deT8AAAAAj0hHPwAAAAB1Bkk/AAAAALvyTz8AAAAAQipPPwAAAADEdkk/AAAAAElfUD8AAAAAooFSPwAAAACrDFI/AAAAABrrUj8AAAAAueE3PwAAAAD1pTs/AAAAACIGPD8AAAAAIY1JPwAAAAAGsFA/AAAAABVRUz8AAAAAPLFTPwAAAAArdlI/AAAAADFTVj8AAAAArqFWPwAAAAApX14/AAAAAJ//XT8AAAAACnRVPwAAAADjVV4/AAAAAH07YT8AAAAAp9NgPwAAAAA5lmE/AAAAAK5lRz8AAAAAtK5HPwAAAAAFG0Q/AAAAACENYj8AAAAAG6RhPwAAAABYdnQ/AAAAAA9+dT8AAAAAjtd4PwAAAAAwQng/AAAAAB7mdT8AAAAA8EB5PwAAAABjFHo/AAAAANCleT8AAAAAdH16PwAAAABDX28/AAAAAK6qej8AAAAApkF6PwAAAACg2Hk/AAAAAP5nNj8AAAAALeo2PwAAAAADHDg/AAAAALesNz8AAAAAwRs3PwAAAAC6dTg/AAAAAFqNOD8AAAAAjSM4PwAAAAB29Dg/AAAAACvtMz8AAAAAf3k0PwAAAACTBjk/AAAAAIY0OD8AAAAA3T1KPwAAAAAPjko/AAAAAEeOUT8AAAAAFS5RPwAAAAAbhkk/AAAAAJaPUT8AAAAAqSRUPwAAAAC8vFM/AAAAALiAVD8AAAAAg748PwAAAADO0zk/AAAAAFDsVD8AAAAASoNUPwAAAADOt/w9AAAAAAEAAD4AAAAAAQAAPgAAAADPt/w9AAAAABykAT4AAAAAG6QBPgAAAAABAAA+AAAAAMy3/D0AAAAAG6QBPgAAAACYb/k9AAAAAMy3/D0AAAAAmG/5PQAAAAA1SAM+AAAAADZIAz4AAAAANkgDPgAAAAA2SAM+AAAAAJdv+T0AAAAAmW/5PQAAAADbif0+AAAAAOdb/j4AAAAA6Fv+PgAAAADbif0+AAAAAPUt/z4AAAAA9C3/PgAAAADpW/4+AAAAANqJ/T4AAAAA8i3/PgAAAADOt/w+AAAAAOdb/j4AAAAA8y3/PgAAAAAAAAA/AAAAAP///z4AAAAAAQAAPwAAAAAAAAA/AAAAAM63/D4AAAAAzLf8PgAAAACf2Ak9AAAAAAhpED0AAAAAB2kQPQAAAACe2Ak9AAAAAHH5Fj0AAAAAcPkWPQAAAAAIaRA9AAAAAJ7YCT0AAAAAcfkWPQAAAACe2Ak9AAAAADVIAz0AAAAACGkQPQAAAADZiR09AAAAANqJHT0AAAAA2YkdPQAAAAA2SAM9AAAAADZIAz0AAAAAQxoUPwAAAABJgxQ/AAAAAEiDFD8AAAAAQhoUPwAAAABQ7BQ/AAAAAE/sFD8AAAAASYMUPwAAAABBGhQ/AAAAAE/sFD8AAAAAO7ETPwAAAABCGhQ/AAAAADuxEz8AAAAAT+wUPwAAAABVVRU/AAAAAFZVFT8AAAAAVVUVPwAAAAA7sRM/AAAAADyxEz8AAAAAhjTIPQAAAAC7fMs9AAAAALp8yz0AAAAAhTTIPQAAAADvxM49AAAAAO/Ezj0AAAAAuXzLPQAAAACGNMg9AAAAAO/Ezj0AAAAAUOzEPQAAAABQ7MQ9AAAAACQN0j0AAAAAIg3SPQAAAAAkDdI9AAAAACMN0j0AAAAAT+zEPQAAAABR7MQ9AAAAALATKz8AAAAAuXwrPwAAAAC5fCs/AAAAALETKz8AAAAAv+UrPwAAAADA5Ss/AAAAALh8Kz8AAAAAshMrPwAAAAC+5Ss/AAAAALMTKz8AAAAAq6oqPwAAAADHTiw/AAAAAMZOLD8AAAAAx04sPwAAAACrqio/AAAAAKyqKj8AAAAAq6oaPwAAAACzExs/AAAAALITGz8AAAAArKoaPwAAAAC5fBs/AAAAALp8Gz8AAAAAsxMbPwAAAACqqho/AAAAALd8Gz8AAAAApkEaPwAAAACqqho/AAAAAKRBGj8AAAAAuHwbPwAAAAC+5Rs/AAAAAL/lGz8AAAAAv+UbPwAAAAC/5Rs/AAAAAKVBGj8AAAAApUEaPwAAAADOOpE+AAAAAA0Nkj4AAAAAAg2SPgAAAADCOpE+AAAAAE7fkj4AAAAARt+SPgAAAAD6DJI+AAAAAL06kT4AAAAAO9+SPgAAAACwaJA+AAAAANo6kT4AAAAAoGiQPgAAAABR35I+AAAAAH6xkz4AAAAAerGTPgAAAABxsZM+AAAAAJFokD4AAAAAlWiQPgAAAADSIE0+AAAAAO/ETj4AAAAA7sROPgAAAADUIE0+AAAAAAlpUD4AAAAACWlQPgAAAADuxE4+AAAAANMgTT4AAAAAB2lQPgAAAAC7fEs+AAAAANUgTT4AAAAAunxLPgAAAADuxE4+AAAAAAhpUD4AAAAAIQ1SPgAAAAAjDVI+AAAAACMNUj4AAAAAIw1SPgAAAAC5fEs+AAAAALp8Sz4AAAAAJCfWPgAAAAAh+dY+AAAAABv51j4AAAAAHyfWPgAAAAAqy9c+AAAAACbL1z4AAAAAG/nWPgAAAAAcJ9Y+AAAAACXL1z4AAAAAP1XVPgAAAAAsJ9Y+AAAAADpV1T4AAAAAKvnWPgAAAABGndg+AAAAADqd2D4AAAAAN53YPgAAAAA5ndg+AAAAADJV1T4AAAAANFXVPgAAAAD7lu89AAAAAC/f8j0AAAAAL9/yPQAAAAD6lu89AAAAAGQn9j0AAAAAZSf2PQAAAAAt3/I9AAAAAPuW7z0AAAAAZCf2PQAAAADGTuw9AAAAAPuW7z0AAAAAxU7sPQAAAAAw3/I9AAAAAMZO7D0AAAAAyE7sPQAAAAAHaQA/AAAAAA7SAD8AAAAADdIAPwAAAAAHaQA/AAAAABQ7AT8AAAAAFDsBPwAAAAAN0gA/AAAAAAZpAD8AAAAAEzsBPwAAAAAO0gA/AAAAABukAT8AAAAAG6QBPwAAAAAbpAE/AAAAAPQt3zwAAAAAyE7sPAAAAADGTuw8AAAAAPct3zwAAAAAmW/5PAAAAACab/k8AAAAAMhO7DwAAAAA9S3fPAAAAACab/k8AAAAACIN0jwAAAAAmW/5PAAAAAAjDdI8AAAAACQN0jwAAAAAzrcsPwAAAADUIC0/AAAAANUgLT8AAAAAzbcsPwAAAADZiS0/AAAAANuJLT8AAAAA1CAtPwAAAADOtyw/AAAAANqJLT8AAAAA3IktPwAAAADh8i0/AAAAAOLyLT8AAAAA4PItPwAAAACv8o0+AAAAAJfEjj4AAAAAksSOPgAAAACs8o0+AAAAAJCWjz4AAAAAhZaPPgAAAACQxI4+AAAAAK/yjT4AAAAAhZaPPgAAAACz8o0+AAAAAMsgjT4AAAAAo8SOPgAAAACelo8+AAAAANMgjT4AAAAAzyCNPgAAAABqkEY+AAAAAIc0SD4AAAAAhjRIPgAAAABrkEY+AAAAAKHYST4AAAAAoNhJPgAAAACFNEg+AAAAAGqQRj4AAAAAoNhJPgAAAABskEY+AAAAAFDsRD4AAAAAoNhJPgAAAABR7EQ+AAAAAFHsRD4AAAAAT2/ZPgAAAABpQdo+AAAAAGRB2j4AAAAATW/ZPgAAAACAE9s+AAAAAIET2z4AAAAAZkHaPgAAAABNb9k+AAAAAIET2z4AAAAAhxPbPgAAAACm5ds+AAAAAJ/l2z4AAAAAn+XbPgAAAACf5ds+AAAAACENAj8AAAAAKXYCPwAAAAAodgI/AAAAACENAj8AAAAAMN8CPwAAAAAv3wI/AAAAACl2Aj8AAAAAIQ0CPwAAAAAv3wI/AAAAACENAj8AAAAAKHYCPwAAAAA2SAM/AAAAADZIAz8AAAAANkgDPwAAAACrqqo8AAAAAH7LtzwAAAAAfcu3PAAAAACsqqo8AAAAAFHsxDwAAAAAUezEPAAAAAB9y7c8AAAAAKuqqjwAAAAAUezEPAAAAACsqqo8AAAAANmJnTwAAAAAfsu3PAAAAABP7MQ8AAAAANmJnTwAAAAA2YmdPAAAAACyE7s9AAAAAOhbvj0AAAAA6Fu+PQAAAACzE7s9AAAAAB2kwT0AAAAAHKTBPQAAAADoW749AAAAALQTuz0AAAAAHKTBPQAAAAB+y7c9AAAAALMTuz0AAAAAf8u3PQAAAADnW749AAAAAB2kwT0AAAAAf8u3PQAAAAB/y7c9AAAAAOhbLj8AAAAA7cQuPwAAAADsxC4/AAAAAOhbLj8AAAAA9S0vPwAAAAD1LS8/AAAAAO7ELj8AAAAA51suPwAAAAD1LS8/AAAAAO7ELj8AAAAA+5YvPwAAAAD8li8/AAAAAPyWLz8AAAAA/KqKPgAAAAD3fIs+AAAAAAZ9iz4AAAAAC6uKPgAAAADlTow+AAAAAO1OjD4AAAAADn2LPgAAAAAXq4o+AAAAAPdOjD4AAAAA3NiJPgAAAADpqoo+AAAAAO3YiT4AAAAA6XyLPgAAAADcTow+AAAAAAbZiT4AAAAA/tiJPgAAAAACAEA+AAAAABykQT4AAAAAG6RBPgAAAAACAEA+AAAAADZIQz4AAAAAN0hDPgAAAAAcpEE+AAAAAAEAQD4AAAAANkhDPgAAAADmWz4+AAAAAOdbPj4AAAAAHqRBPgAAAADmWz4+AAAAAOhbPj4AAAAAwogvPwAAAAANryw/AAAAAA2vLD8AAAAAw4gvPwAAAABfPiQ/AAAAAF8+JD8AAAAADq8sPwAAAADCiC8/AAAAAF4+JD8AAAAAOmsTPwAAAAA6axM/AAAAADhrEz8AAAAAOWsTPwAAAADEt9w+AAAAAOeJ3T4AAAAA54ndPgAAAADEt9w+AAAAAAVc3j4AAAAAA1zePgAAAADkid0+AAAAAMK33D4AAAAAA1zePgAAAADGt9w+AAAAAABc3j4AAAAAEC7fPgAAAAAULt8+AAAAABku3z4AAAAAFy7fPgAAAAA9sQM/AAAAAEIaBD8AAAAARBoEPwAAAAA8sQM/AAAAAEmDBD8AAAAASoMEPwAAAABDGgQ/AAAAADyxAz8AAAAASYMEPwAAAAA9sQM/AAAAAEiDBD8AAAAAUOwEPwAAAABR7AQ/AAAAAE/sBD8AAAAAXL4VPwAAAABjJxY/AAAAAGInFj8AAAAAXb4VPwAAAABqkBY/AAAAAGqQFj8AAAAAYycWPwAAAABcvhU/AAAAAGmQFj8AAAAAW74VPwAAAABjJxY/AAAAAGuQFj8AAAAAcfkWPwAAAABx+RY/AAAAAHH5Fj8AAAAAa5CGPQAAAACg2Ik9AAAAAJ/YiT0AAAAAapCGPQAAAADUII09AAAAANQgjT0AAAAAoNiJPQAAAABqkIY9AAAAANMgjT0AAAAAN0iDPQAAAAAIaZA9AAAAAAhpkD0AAAAACWmQPQAAAAA2SIM9AAAAADZIgz0AAAAAxk4cPwAAAADNtxw/AAAAAM63HD8AAAAAx04cPwAAAADUIB0/AAAAANIgHT8AAAAAzLccPwAAAADFThw/AAAAANIgHT8AAAAAxU4cPwAAAADaiR0/AAAAANmJHT8AAAAA2YkdPwAAAADFTmw8AAAAADZIgzwAAAAANUiDPAAAAADFTmw8AAAAAAZpkDwAAAAAB2mQPAAAAAA1SIM8AAAAAMVObDwAAAAAB2mQPAAAAAAeDVI8AAAAAMVObDwAAAAAHQ1SPAAAAAAfDVI8AAAAAB8NUjwAAAAAamKHPgAAAACdNIg+AAAAAJw0iD4AAAAAZGKHPgAAAADKBok+AAAAANMGiT4AAAAAnDSIPgAAAABhYoc+AAAAANsGiT4AAAAAcGKHPgAAAABCkIY+AAAAAJk0iD4AAAAAvwaJPgAAAAAykIY+AAAAADqQhj4AAAAAL98iPwAAAAA2SCM/AAAAADVIIz8AAAAAL98iPwAAAAA9sSM/AAAAAD2xIz8AAAAANUgjPwAAAAAv3yI/AAAAADuxIz8AAAAAKHYiPwAAAAA2SCM/AAAAADyxIz8AAAAAQxokPwAAAABCGiQ/AAAAAEMaJD8AAAAAQhokPwAAAAAodiI/AAAAACh2Ij8AAAAAUrY5PgAAAABNWzM+AAAAAPA5Lj4AAAAAj9g0PgAAAAArkjE+AAAAAMJTLD4AAAAAJlozPgAAAABzsjk+AAAAAAaSMT4AAAAAnAJUPgAAAAAhS0g+AAAAAC/sRj4AAAAADb5CPgAAAAA7TUE+AAAAAI/qQT4AAAAA/BEyPgAAAADLySw+AAAAAPwRMj4AAAAA/uJGPgAAAADVi0I+AAAAAJhvOT4AAAAAsRM7PgAAAACyEzs+AAAAAJdvOT4AAAAAzLc8PgAAAADMtzw+AAAAALITOz4AAAAAmW85PgAAAADLtzw+AAAAAH3LNz4AAAAAl285PgAAAAB9yzc+AAAAALQTOz4AAAAAfcs3PgAAAAB9yzc+AAAAAL2f8T4AAAAAFDuxPgAAAAATO7E+AAAAALyf8T4AAAAA0qxhPgAAAADSrGE+AAAAABI7sT4AAAAAvJ/xPgAAAADSrGE+AAAAALyf8T4AAAAAEzuxPgAAAADSfu49AAAAAM1+7j0AAAAAzX7uPQAAAADMfu49AAAAABcA4D4AAAAADtLgPgAAAAAW0uA+AAAAABwA4D4AAAAAB6ThPgAAAAANpOE+AAAAABzS4D4AAAAAHwDgPgAAAAAZpOE+AAAAAAjS4D4AAAAABXbiPgAAAAAGduI+AAAAAA524j4AAAAAF3biPgAAAADR5Ic+AAAAACzwdT4AAAAAQjlzPgAAAABz/oY+AAAAAFQiXD4AAAAA/YJYPgAAAABd1nU+AAAAAPfUhz4AAAAACRFcPgAAAACUCJQ+AAAAAJWFij4AAAAAU5GSPgAAAABW7GY+AAAAAFiBkj4AAAAAEg6SPgAAAABXVQU/AAAAAFu+BT8AAAAAW74FPwAAAABWVQU/AAAAAGEnBj8AAAAAYycGPwAAAABdvgU/AAAAAFZVBT8AAAAAYicGPwAAAABVVQU/AAAAAF2+BT8AAAAAYycGPwAAAABpkAY/AAAAAGmQBj8AAAAAaZAGPwAAAABqkAY/AAAAAErzMj4AAAAAnNQzPgAAAABJfy4+AAAAAIukLT4AAAAA7LU0PgAAAAAKWi8+AAAAAJzUMz4AAAAAS/MyPgAAAADttTQ+AAAAAI/fQj4AAAAAlclEPgAAAABBlzU+AAAAAM80MD4AAAAAQZc1PgAAAABGy089AAAAALuAkTwAAAAAs4CRPAAAAABBy089AAAAAIko2TsAAAAAdijZOwAAAACzgJE8AAAAAEHLTz0AAAAAdCjZOwAAAABOy089AAAAAK4o2TsAAAAAmAzSOwAAAACDDNI7AAAAAHgM0jsAAAAAeAzSOwAAAAArGoQ+AAAAACbshD4AAAAAJOyEPgAAAAAtGoQ+AAAAACy+hT4AAAAAJL6FPgAAAAAk7IQ+AAAAADMahD4AAAAAIL6FPgAAAAAoGoQ+AAAAADNIgz4AAAAALeyEPgAAAABFSIM+AAAAAD1Igz4AAAAAmXg2PgAAAADzWTc+AAAAAF7qMT4AAAAAlQ8xPgAAAABSOzg+AAAAACzFMj4AAAAA9lk3PgAAAACZeDY+AAAAAFI7OD4AAAAAprNGPgAAAAC1qEc+AAAAAK4cOT4AAAAA+p8zPgAAAACwHDk+AAAAAC/fMj4AAAAASYM0PgAAAABKgzQ+AAAAAC/fMj4AAAAAYyc2PgAAAABkJzY+AAAAAEmDND4AAAAALt8yPgAAAABjJzY+AAAAABM7MT4AAAAALt8yPgAAAAAVOzE+AAAAABQ7MT4AAAAAFTsxPgAAAAALSAM8AAAAAMaJHTwAAAAAxIkdPAAAAAAISAM8AAAAAHbLNzwAAAAAdcs3PAAAAADEiR08AAAAAAlIAzwAAAAAdss3PAAAAADIiR08AAAAAHXLNzwAAAAAGUjjPgAAAAA4GuQ+AAAAAC8a5D4AAAAAGkjjPgAAAABc7OQ+AAAAAE7s5D4AAAAAKRrkPgAAAAAcSOM+AAAAAEDs5D4AAAAAG0jjPgAAAAA/GuQ+AAAAAGbs5D4AAAAAir7lPgAAAACBvuU+AAAAAHG+5T4AAAAAXr7lPgAAAABw+QY/AAAAAHZiBz8AAAAAdmIHPwAAAABx+QY/AAAAAH7LBz8AAAAAfcsHPwAAAAB2Ygc/AAAAAHD5Bj8AAAAAfMsHPwAAAACDNAg/AAAAAIQ0CD8AAAAAhDQIPwAAAACENAg/AAAAAODyHT8AAAAA5lsePwAAAADmWx4/AAAAAOHyHT8AAAAA7MQePwAAAADuxB4/AAAAAOZbHj8AAAAA4PIdPwAAAADuxB4/AAAAAOZbHj8AAAAA7MQePwAAAADyLR8/AAAAAPUtHz8AAAAA8y0fPwAAAAAN/jk+AAAAAGzfOj4AAAAAlFU1PgAAAADIejQ+AAAAAMfAOz4AAAAAXzA2PgAAAABr3zo+AAAAAA3+OT4AAAAAx8A7PgAAAADgh0o+AAAAAPB8Sz4AAAAABmdNPgAAAAAfojw+AAAAACgLNz4AAAAAH6I8PgAAAABI0oA+AAAAAESkgT4AAAAAUaSBPgAAAABQ0oA+AAAAAD12gj4AAAAAR3aCPgAAAABXpIE+AAAAAFXSgD4AAAAAUnaCPgAAAABGAIA+AAAAADJ2gj4AAAAASwCAPgAAAABMAIA+AAAAAHSDPT4AAAAAxmQ+PgAAAACswDg+AAAAAOvlNz4AAAAAFkY/PgAAAABsmzk+AAAAAMZkPj4AAAAAdYM9PgAAAAAWRj8+AAAAAA1cTj4AAAAAFEZQPgAAAAAWO1E+AAAAAGUnQD4AAAAAK3Y6PgAAAABlJ0A+AAAAAMVOLD4AAAAA4PItPgAAAADg8i0+AAAAAMZOLD4AAAAA+pYvPgAAAAD6li8+AAAAAOHyLT4AAAAAxk4sPgAAAAD8li8+AAAAAKyqKj4AAAAAx04sPgAAAACsqio+AAAAAOHyLT4AAAAA+pYvPgAAAACrqio+AAAAAK2qKj4AAAAA4fKtPQAAAAAVO7E9AAAAABQ7sT0AAAAA4/KtPQAAAABJg7Q9AAAAAEqDtD0AAAAAFjuxPQAAAADh8q09AAAAAEqDtD0AAAAArKqqPQAAAADg8q09AAAAAKyqqj0AAAAAFzuxPQAAAABKg7Q9AAAAAK2qqj0AAAAArqqqPQAAAACgkOY+AAAAALNi5z4AAAAAr2LnPgAAAACTkOY+AAAAALs06D4AAAAAvzToPgAAAACoYuc+AAAAAIWQ5j4AAAAAvjToPgAAAAClkOY+AAAAALNi5z4AAAAApgbpPgAAAACwBuk+AAAAALgG6T4AAAAAvwbpPgAAAACKnQg/AAAAAJEGCT8AAAAAkgYJPwAAAACKnQg/AAAAAJhvCT8AAAAAl28JPwAAAACRBgk/AAAAAIudCD8AAAAAmG8JPwAAAACSBgk/AAAAAJ/YCT8AAAAAn9gJPwAAAACe2Ak/AAAAACp24j0AAAAAXr7lPQAAAABevuU9AAAAACl24j0AAAAAkgbpPQAAAACRBuk9AAAAAF2+5T0AAAAAKXbiPQAAAACSBuk9AAAAAPUt3z0AAAAAKHbiPQAAAAD2Ld89AAAAAF6+5T0AAAAA9C3fPQAAAAD0Ld89AAAAALUIQT4AAAAABOpBPgAAAACoKzw+AAAAAOdQOz4AAAAAWctCPgAAAABpBj0+AAAAAAXqQT4AAAAAtQhBPgAAAABXy0I+AAAAABkwUj4AAAAAHSVTPgAAAAAgGlQ+AAAAACcPVT4AAAAArKxDPgAAAAAu4T0+AAAAAK2sQz4AAAAAMxR7PgAAAABduHw+AAAAAFe4fD4AAAAALBR7PgAAAAB8XH4+AAAAAHxcfj4AAAAASbh8PgAAAAAYFHs+AAAAAHRcfj4AAAAABnB5PgAAAAAxFHs+AAAAAAVweT4AAAAAb1x+PgAAAADpb3k+AAAAAPpveT4AAAAABI5EPgAAAABhb0U+AAAAAMGWPz4AAAAA9rs+PgAAAAC8UEY+AAAAAI5xQD4AAAAAYW9FPgAAAAADjkQ+AAAAAL5QRj4AAAAAMwRWPgAAAABA+VY+AAAAAE7uVz4AAAAAXeNYPgAAAAAdMkc+AAAAAF1MQT4AAAAAHTJHPgAAAABdviU+AAAAAHhiJz4AAAAAd2InPgAAAABeviU+AAAAAJIGKT4AAAAAkgYpPgAAAAB3Yic+AAAAAF2+JT4AAAAAkgYpPgAAAABDGiQ+AAAAAEMaJD4AAAAAkgYpPgAAAABDGiQ+AAAAAEQaJD4AAAAAk9jpPgAAAABwquo+AAAAAHSq6j4AAAAAndjpPgAAAABRfOs+AAAAAFJ86z4AAAAAfarqPgAAAACl2Ok+AAAAAFd86z4AAAAAjdjpPgAAAABZfOs+AAAAAEhO7D4AAAAARE7sPgAAAABITuw+AAAAAKVBCj8AAAAAq6oKPwAAAACrqgo/AAAAAKVBCj8AAAAAsxMLPwAAAACxEws/AAAAAKyqCj8AAAAApEEKPwAAAACzEws/AAAAAKVBCj8AAAAAuXwLPwAAAAC5fAs/AAAAALp8Cz8AAAAAuXwLPwAAAAB7E0g+AAAAANj0SD4AAAAA+AFDPgAAAAAqJ0I+AAAAADTWST4AAAAAwtxDPgAAAADZ9Eg+AAAAAHsTSD4AAAAANNZJPgAAAABs2Fk+AAAAAHzNWj4AAAAAicJbPgAAAACNt0o+AAAAAIy3RD4AAAAAjbdKPgAAAABzg3Q+AAAAAKMndj4AAAAAnid2PgAAAAByg3Q+AAAAANTLdz4AAAAAy8t3PgAAAACUJ3Y+AAAAAG2DdD4AAAAAu8t3PgAAAABG33I+AAAAAKQndj4AAAAA1ct3PgAAAABJ33I+AAAAAEnfcj4AAAAA5JhLPgAAAAAyekw+AAAAABFtRj4AAAAAUJJFPgAAAACBW00+AAAAAMxHRz4AAAAANHpMPgAAAADjmEs+AAAAAIFbTT4AAAAAm6xdPgAAAACgoV4+AAAAAMo8Tj4AAAAAhiJIPgAAAADKPE4+AAAAAPQtHz4AAAAAD9IgPgAAAAAP0iA+AAAAAPQtHz4AAAAAKXYiPgAAAAApdiI+AAAAAA/SID4AAAAA8y0fPgAAAAApdiI+AAAAANqJHT4AAAAA2YkdPgAAAAAodiI+AAAAANqJHT4AAAAA2IkdPgAAAABdIO0+AAAAAIjy7T4AAAAAgfLtPgAAAABXIO0+AAAAALnE7j4AAAAAtsTuPgAAAACC8u0+AAAAAFgg7T4AAAAAtcTuPgAAAABpIO0+AAAAAJLy7T4AAAAAvcTuPgAAAADplu8+AAAAAOSW7z4AAAAA5ZbvPgAAAADklu8+AAAAAL/lCz8AAAAAxk4MPwAAAADGTgw/AAAAAL/lCz8AAAAAzLcMPwAAAADMtww/AAAAAMdODD8AAAAAv+ULPwAAAADMtww/AAAAAL/lCz8AAAAA0yANPwAAAADTIA0/AAAAANMgDT8AAAAAPZdPPgAAAACwyFM+AAAAADnBTT4AAAAAZXpJPgAAAAAsqF0+AAAAAADmVz4AAAAARsdTPgAAAAARl08+AAAAAGWjXT4AAAAAct1lPgAAAAAk6W4+AAAAAJWefz4AAAAAtQxwPgAAAAC412o+AAAAAGEBcD4AAAAADtKgPQAAAABDGqQ9AAAAAEQapD0AAAAADtKgPQAAAAB4Yqc9AAAAAHhipz0AAAAAQxqkPQAAAAAO0qA9AAAAAHlipz0AAAAAD9KgPQAAAADbiZ09AAAAAEQapD0AAAAAd2KnPQAAAADaiZ09AAAAANqJnT0AAAAAd2IXPwAAAAB+yxc/AAAAAH7LFz8AAAAAd2IXPwAAAACENBg/AAAAAIU0GD8AAAAAfssXPwAAAAB4Yhc/AAAAAIQ0GD8AAAAAd2IXPwAAAAB+yxc/AAAAAIQ0GD8AAAAAip0YPwAAAACKnRg/AAAAAIydGD8AAAAAip0YPwAAAAD5lh8/AAAAAAEAID8AAAAAAAAgPwAAAAD7lh8/AAAAAAdpID8AAAAABmkgPwAAAAABACA/AAAAAPmWHz8AAAAACGkgPwAAAAD5lh8/AAAAAAZpID8AAAAADNIgPwAAAAAO0iA/AAAAAA3SID8AAAAADdIgPwAAAADh8m0+AAAAAACXbz4AAAAAAZdvPgAAAADg8m0+AAAAAB87cT4AAAAAJDtxPgAAAAABl28+AAAAAODybT4AAAAAJTtxPgAAAADf8m0+AAAAAMRObD4AAAAAHTtxPgAAAADBTmw+AAAAAMNObD4AAAAAxDOGPgAAAABWSZc+AAAAACOplT4AAAAA8gmEPgAAAAAygag+AAAAAKFspz4AAAAAbDmXPgAAAAAaKYY+AAAAAKVtqD4AAAAAfxecPgAAAABJqKs+AAAAAHHYuD4AAAAAeRW3PgAAAACNd7Y+AAAAAMUBtz4AAAAAip0YPgAAAAClQRo+AAAAAKZBGj4AAAAAip0YPgAAAAC+5Rs+AAAAAL7lGz4AAAAApEEaPgAAAACLnRg+AAAAAL7lGz4AAAAAcfkWPgAAAACkQRo+AAAAAHH5Fj4AAAAAcfkWPgAAAAAEafA+AAAAABc78T4AAAAAGDvxPgAAAAAFafA+AAAAACUN8j4AAAAAIw3yPgAAAAAZO/E+AAAAAARp8D4AAAAAIg3yPgAAAAAZO/E+AAAAAC7f8j4AAAAAK9/yPgAAAAAt3/I+AAAAACzf8j4AAAAAMN9yPQAAAACab3k9AAAAAJpveT0AAAAAMN9yPQAAAAAAAIA9AAAAAAIAgD0AAAAAm295PQAAAAAw33I9AAAAAAEAgD0AAAAAxk5sPQAAAAAu33I9AAAAAMVObD0AAAAAxE5sPQAAAADHTmw9AAAAANqJDT8AAAAA4PINPwAAAADg8g0/AAAAANmJDT8AAAAA51sOPwAAAADnWw4/AAAAAODyDT8AAAAA2okNPwAAAADmWw4/AAAAAOZbDj8AAAAA7cQOPwAAAADuxA4/AAAAAO3EDj8AAAAASYMkPwAAAABQ7CQ/AAAAAFDsJD8AAAAASYMkPwAAAABWVSU/AAAAAFdVJT8AAAAAUOwkPwAAAABJgyQ/AAAAAFhVJT8AAAAASoMkPwAAAABXVSU/AAAAAF2+JT8AAAAAXb4lPwAAAABcviU/AAAAALGBnT4AAAAATI+cPgAAAABodZw+AAAAAF56nT4AAAAASUeZPgAAAADlBpk+AAAAAPOInD4AAAAAwIGdPgAAAADtOpk+AAAAAL2XnT4AAAAAyjadPgAAAAC4O50+AAAAAIs2nT4AAAAAd2JnPgAAAACSBmk+AAAAAI4GaT4AAAAAd2JnPgAAAACoqmo+AAAAAKiqaj4AAAAAjgZpPgAAAAB1Ymc+AAAAAKaqaj4AAAAAeWJnPgAAAABdvmU+AAAAAJMGaT4AAAAAq6pqPgAAAABbvmU+AAAAAF2+ZT4AAAAAcu7APgAAAAD2rMY+AAAAAJCNxj4AAAAAvKDAPgAAAAAGoMk+AAAAABqXyT4AAAAAKaXGPgAAAAA338A+AAAAACWgyT4AAAAA9cXBPgAAAADyusk+AAAAAKUWyz4AAAAAYRbLPgAAAADIHMs+AAAAACMNEj4AAAAAPbETPgAAAAA8sRM+AAAAACINEj4AAAAAVlUVPgAAAABXVRU+AAAAADyxEz4AAAAAIg0SPgAAAABWVRU+AAAAAAhpED4AAAAACGkQPgAAAAAIaRA+AAAAAAhpED4AAAAAOLHzPgAAAABGg/Q+AAAAAEaD9D4AAAAAOLHzPgAAAABTVfU+AAAAAFRV9T4AAAAASIP0PgAAAAA3sfM+AAAAAFVV9T4AAAAAObHzPgAAAABIg/Q+AAAAAGMn9j4AAAAAYyf2PgAAAABlJ/Y+AAAAAGUn9j4AAAAAi51YPQAAAAD1LV89AAAAAPMtXz0AAAAAjJ1YPQAAAABdvmU9AAAAAF2+ZT0AAAAA8y1fPQAAAACMnVg9AAAAAF++ZT0AAAAAIQ1SPQAAAACLnVg9AAAAACINUj0AAAAA9i1fPQAAAABdvmU9AAAAACINUj0AAAAAIg1SPQAAAADzLQ8/AAAAAPuWDz8AAAAA+ZYPPwAAAAD0LQ8/AAAAAAIAED8AAAAAAgAQPwAAAAD6lg8/AAAAAPQtDz8AAAAAAwAQPwAAAAD6lg8/AAAAAAhpED8AAAAACGkQPwAAAAAIaRA/AAAAAAhpED8AAAAAV1XVPQAAAACMndg9AAAAAIyd2D0AAAAAWFXVPQAAAADB5ds9AAAAAMDl2z0AAAAAjJ3YPQAAAABXVdU9AAAAAMLl2z0AAAAAjZ3YPQAAAABkJyY/AAAAAGuQJj8AAAAAapAmPwAAAABlJyY/AAAAAHD5Jj8AAAAAcPkmPwAAAABpkCY/AAAAAGMnJj8AAAAAcPkmPwAAAABkJyY/AAAAAHhiJz8AAAAAd2InPwAAAAB3Yic/AAAAAHdiJz8AAAAA3RabPgAAAABQ4Zs+AAAAAGPkmz4AAAAAQBmbPgAAAADKmZw+AAAAAEqcnD4AAAAAj+ebPgAAAABDG5s+AAAAAJOgnD4AAAAA8kOaPgAAAABQ35s+AAAAACianD4AAAAATkaaPgAAAAA/RZo+AAAAAA7SYD4AAAAAKnZiPgAAAAAqdmI+AAAAAA/SYD4AAAAAQxpkPgAAAABFGmQ+AAAAACl2Yj4AAAAADdJgPgAAAABEGmQ+AAAAAPQtXz4AAAAAENJgPgAAAAD0LV8+AAAAACt2Yj4AAAAARBpkPgAAAADzLV8+AAAAAPMtXz4AAAAA8SnMPgAAAACBG80+AAAAAFQfzT4AAAAAEy3MPgAAAAD69s0+AAAAAPP5zT4AAAAAQyPNPgAAAABjMsw+AAAAAHT8zT4AAAAAXSrMPgAAAABo9M0+AAAAABLIzj4AAAAAtMnOPgAAAAADy84+AAAAALh8Cz4AAAAA1SANPgAAAADTIA0+AAAAALl8Cz4AAAAA7sQOPgAAAADuxA4+AAAAANMgDT4AAAAAuXwLPgAAAADvxA4+AAAAALl8Cz4AAAAAn9gJPgAAAADTIA0+AAAAAO7EDj4AAAAAn9gJPgAAAACf2Ak+AAAAAHL59j4AAAAAgMv3PgAAAACAy/c+AAAAAHL59j4AAAAAj534PgAAAACNnfg+AAAAAIHL9z4AAAAAc/n2PgAAAACMnfg+AAAAAHD59j4AAAAAgcv3PgAAAACNnfg+AAAAAJpv+T4AAAAAmW/5PgAAAACbb/k+AAAAAJlv+T4AAAAA5ls+PQAAAABQ7EQ9AAAAAFDsRD0AAAAA6Fs+PQAAAAC6fEs9AAAAALl8Sz0AAAAAUOxEPQAAAADoWz49AAAAALl8Sz0AAAAAfcs3PQAAAADpWz49AAAAAH7LNz0AAAAAUexEPQAAAAC4fEs9AAAAAH7LNz0AAAAAfss3PQAAAAAP0hA/AAAAABc7ET8AAAAAFTsRPwAAAAAQ0hA/AAAAABukET8AAAAAHaQRPwAAAAAUOxE/AAAAAA7SED8AAAAAHKQRPwAAAAAP0hA/AAAAABY7ET8AAAAAIg0SPwAAAAAiDRI/AAAAACINEj8AAAAAfcsnPwAAAACENCg/AAAAAIQ0KD8AAAAAfssnPwAAAACMnSg/AAAAAIqdKD8AAAAAgzQoPwAAAAB+yyc/AAAAAImdKD8AAAAAhTQoPwAAAACKnSg/AAAAAJAGKT8AAAAAkQYpPwAAAACQBik/AAAAAJEGKT8AAAAAkwYZPwAAAACYbxk/AAAAAJhvGT8AAAAAkwYZPwAAAACe2Bk/AAAAAKDYGT8AAAAAmG8ZPwAAAACRBhk/AAAAAJ/YGT8AAAAAkQYZPwAAAACZbxk/AAAAAJ3YGT8AAAAAbsuXPgAAAACqnZg+AAAAANedmD4AAAAAecuXPgAAAABrcJk+AAAAAPhwmT4AAAAA/p2YPgAAAACFy5c+AAAAAGxxmT4AAAAAbfmWPgAAAABmy5c+AAAAAHX5lj4AAAAAh52YPgAAAADxb5k+AAAAAIX5lj4AAAAAfvmWPgAAAACmQVo+AAAAAMDlWz4AAAAAv+VbPgAAAACmQVo+AAAAANmJXT4AAAAA2oldPgAAAAC/5Vs+AAAAAKVBWj4AAAAA2YldPgAAAAClQVo+AAAAAIqdWD4AAAAAip1YPgAAAACLnVg+AAAAAHeYzz4AAAAAzWnQPgAAAAD/adA+AAAAACmZzz4AAAAArjvRPgAAAAC5O9E+AAAAACRq0D4AAAAAspnPPgAAAAC1O9E+AAAAAJVp0D4AAAAAnTvRPgAAAADADdI+AAAAAMMN0j4AAAAAuw3SPgAAAABR7AQ+AAAAAGqQBj4AAAAAbJAGPgAAAABP7AQ+AAAAAIQ0CD4AAAAAgzQIPgAAAABqkAY+AAAAAFDsBD4AAAAAhDQIPgAAAACFNAg+AAAAAKhB+j4AAAAAsxP7PgAAAAC2E/s+AAAAAKdB+j4AAAAAwOX7PgAAAADA5fs+AAAAALMT+z4AAAAAp0H6PgAAAADB5fs+AAAAALMT+z4AAAAAwOX7PgAAAABBGiQ9AAAAAKyqKj0AAAAAq6oqPQAAAABEGiQ9AAAAABQ7MT0AAAAAFTsxPQAAAACsqio9AAAAAEIaJD0AAAAAFjsxPQAAAABDGiQ9AAAAABQ7MT0AAAAAKHYSPwAAAAAv3xI/AAAAAC/fEj8AAAAAKHYSPwAAAAA1SBM/AAAAADVIEz8AAAAALt8SPwAAAAApdhI/AAAAADRIEz8AAAAAKXYSPwAAAAAw3xI/AAAAADVIEz8AAAAAmG8pPwAAAACg2Ck/AAAAAJ3YKT8AAAAAmG8pPwAAAACkQSo/AAAAAKZBKj8AAAAAn9gpPwAAAACYbyk/AAAAAKZBKj8AAAAAlm8pPwAAAACe2Ck/AAAAAKVBKj8AAAAAPLGTPQAAAABy+ZY9AAAAAHH5lj0AAAAAPrGTPQAAAAClQZo9AAAAAKZBmj0AAAAAcvmWPQAAAAA8sZM9AAAAAKVBmj0AAAAAcfmWPQAAAAClQZo9AAAAAJeDlD4AAAAAlFWVPgAAAACbVZU+AAAAAJWDlD4AAAAAiCeWPgAAAACRJ5Y+AAAAAJtVlT4AAAAAkIOUPgAAAACVJ5Y+AAAAAJCDlD4AAAAAfyeWPgAAAAAUOyE/AAAAABukIT8AAAAAHKQhPwAAAAATOyE/AAAAACINIj8AAAAAIw0iPwAAAAAbpCE/AAAAABQ7IT8AAAAAIQ0iPwAAAAAVOyE/AAAAABukIT8AAAAAIQ0iPwAAAAA9sVM+AAAAAFlVVT4AAAAAVlVVPgAAAAA9sVM+AAAAAG/5Vj4AAAAAcflWPgAAAABXVVU+AAAAAD2xUz4AAAAAb/lWPgAAAAA7sVM+AAAAAFdVVT4AAAAAut/SPgAAAACUsdM+AAAAAJKx0z4AAAAAu9/SPgAAAABkg9Q+AAAAAGGD1D4AAAAAjLHTPgAAAACx39I+AAAAAFmD1D4AAAAAjrHTPgAAAAB7Vmw9AAAAAGi99b1JE249AAAAAA3c9b15k289AAAAAMbm9b3QYW89AAAAAHDZ9b3dZXA9AAAAAI319b15h3E9AAAAAJ/59b1JE249AAAAAA3c9b3lYXI9AAAAAF7y9b15h3E9AAAAAJ/59b29B2c9AAAAAH9f9b2gh2k9AAAAAE2i9b2TZWw9AAAAAAif9b0ljGw9AAAAABPP9b3BT3A9AAAAAJvG9b0xXnE9AAAAAND/9b2reXI9AAAAAPoH9r0Ma289AAAAAE/u9b0st3M9AAAAAAQM9r0dwHY9AAAAAMn19b3P3HM9AAAAALzi9b0w7XQ9AAAAALkF9r3BT3A9AAAAAJvG9b0OoW89AAAAAJGM9b2Y/3I9AAAAAKm09b2ex3U9AAAAANqk9b3Ss3Q9AAAAAJCC9b2ujnY9AAAAAJ7N9b1hSHk9AAAAAGuu9b3QdHo9AAAAADt+9b3Ss3Q9AAAAAJCC9b2TZWw9AAAAAAif9b0iuWs9AAAAACJQ9b1E+HE9AAAAAI1I9b0JsXk9AAAAAP/c9b3P3HM9AAAAALzi9b3ZCH09AAAAAMq29b3ox4A9AAAAAJod9b0x83g9AAAAADk79b3G3H89AAAAAL589b2suWM9AAAAAA1C9L1e9mM9AAAAANyg9L2XhWk9AAAAAMu+9L3K82s9AAAAACGW9L07S2c9AAAAALD99L2KfW09AAAAAJH/9L1e9mM9AAAAANyg9L14fHM9AAAAACzr9L3qb149AAAAAEE1870tC1w9AAAAAM35871B3Wc9AAAAAJTt873XCl49AAAAAGp/9L2ozXA9AAAAAP1g9L0E82E9AAAAAGzy9L2Lwnk9AAAAAIfA9L1E+HE9AAAAAI1I9b2AnHE9AAAAAFPE871pr3c9AAAAAO0u9L3iyn09AAAAAKoH9L07A309AAAAAES2872J5H89AAAAANJ89L3OcII9AAAAAOcm9L3a54M9AAAAAIi78707A309AAAAAES2870gYXA9AAAAALs7873ocX49AAAAAAg+87260IM9AAAAAHqy9L1LToY9AAAAABpE9L2ozXA9AAAAAP1g9L0BU4o9AAAAAFg2873hbYU9AAAAADU7872CVIg9AAAAAPjF871LToY9AAAAABpE9L283Hc9AAAAALKh8r2k04E9AAAAABu48r0ckYQ9AAAAAK1L8r35AYI9AAAAADoP8r05roc9AAAAACqs8r15Z4k9AAAAAJMa8r2k04E9AAAAABu48r2N9og9AAAAAE2Q8b35AYI9AAAAADoP8r0gYXA9AAAAALs7870ZVGw9AAAAAMti8r2lx3s9AAAAAHO98b37nYw9AAAAAIiV8r13jY49AAAAAIDm8b3j0449AAAAAFZG8L2j94U9AAAAAI0W8b21Y489AAAAAAAq8b1Prl89AAAAAEqe8L1WmF49AAAAAJpS8b3ui2o9AAAAAGEj8b2+d3A9AAAAAGqk8L3IdWM9AAAAACDq8b0TGHI9AAAAAKRo8b1WmF49AAAAAJpS8b1KyH89AAAAANTK8L2+d3A9AAAAAGqk8L3/MVI9AAAAAHKM770TYFA9AAAAAICm8L2F42Y9AAAAAArS770z7FE9AAAAACaC8b1wBHo9AAAAAAXy7700gFY9AAAAAEZL8r2lx3s9AAAAAHO98b09PoY9AAAAAAwN8L2j94U9AAAAAI0W8b2lx3s9AAAAAHO98b2CBXU9AAAAADcE771qk4I9AAAAAEgz772Y34Y9AAAAAAad7r3fUoM9AAAAAK5F7r06LIs9AAAAAFw0773T0Y09AAAAAJJf7r1qk4I9AAAAAEgz773e+Iw9AAAAAGKf7b3fUoM9AAAAAK5F7r3T0Y09AAAAAJJf7r1HL2Y9AAAAAOaj7r09bHs9AAAAAMPU7b0jzpI9AAAAAGQh7709PoY9AAAAAAwN8L3PMJU9AAAAAHYc7r0RV5Q9AAAAAAvs673apYg9AAAAAML77L12wZU9AAAAAHAY7b1RQ1c9AAAAALlc7L05JFU9AAAAAPhG7b3C8WQ9AAAAALEJ7b1bFG09AAAAAOFj7L1T91o9AAAAAIMI7r0IqW49AAAAAAlk7b05JFU9AAAAAPhG7b3AiIA9AAAAALSW7L0X7UY9AAAAAMr86r0NckM9AAAAABFp7L3JFmE9AAAAABlU670WX0Q9AAAAAC2G7b0av3k9AAAAAFl8671HL2Y9AAAAAOaj7r2Lbkk9AAAAAKaE7r09bHs9AAAAAMPU7b0WX0Q9AAAAAC2G7b1F5Yg9AAAAAAyg673apYg9AAAAAML77L1mJXM9AAAAADZO6r0I8oM9AAAAAC2J6r3yRIk9AAAAAFzM6b0/oYQ9AAAAAJNf6b1YC489AAAAAIWL6r2dFpI9AAAAADOA6b1EspA9AAAAALKR6L0/oYQ9AAAAAJNf6b2dFpI9AAAAADOA6b38amA9AAAAAA7W6b0av3k9AAAAAFl8670cA3s9AAAAAKTT6L2C75g9AAAAABx16r1icps9AAAAAKUt6b2jZ5k9AAAAAIR95r1vGIs9AAAAACzI570kpps9AAAAACLs570cA3s9AAAAAKTT6L1icps9AAAAAKUt6b3qbE89AAAAAFYF572aQkw9AAAAAFgk6L2DqF89AAAAAFvY573A4Wk9AAAAAEIN571C2VI9AAAAABMU6b0CWWs9AAAAAOBH6L0+F4E9AAAAAKtL572ShDw9AAAAAFBd5b32cjc9AAAAAKwV570KsVs9AAAAANfE5b3GrDc9AAAAAFJz6L32b3k9AAAAAKz05b0q+Tw9AAAAAL+v6b3GrDc9AAAAAFJz6L3aT4s9AAAAAFYg5r0DWnE9AAAAAJqL5L2uK4U9AAAAAHHR5L3RbYs9AAAAAFTx472ayIU9AAAAAPpw472fkpI9AAAAAPbU5L0k95U9AAAAAMCX472uK4U9AAAAAHHR5L34DpQ9AAAAAPF+4r0k95U9AAAAAMCX471RD1s9AAAAAKP9470bjHo9AAAAAFfM4r2Ei549AAAAAG+75L14JaE9AAAAABY3473A9p09AAAAAHYS4L39R409AAAAANGS4b2P/aA9AAAAAG+94b0bjHo9AAAAAFfM4r0GQ0g9AAAAAFOv4L3nHUQ9AAAAAHP+4b2Hx1o9AAAAAAOl4b2d6WY9AAAAAOu34L35XUs9AAAAAGQY471dP2g9AAAAAOAn4r2AjoE9AAAAAOcA4b1dP2g9AAAAAOAn4r0mFjM9AAAAALzF3r2Shyw9AAAAAFPD4L0UwVY9AAAAAPg73707ESw9AAAAANlb4r0JF3k9AAAAAKpy372khzE9AAAAAOPQ472ado09AAAAAJil3739R409AAAAANGS4b0JF3k9AAAAAKpy372Ap289AAAAABDU3b1BPIY9AAAAAMcj3r06U409AAAAAKYj3b3axIY9AAAAAIuR3L1It5U9AAAAAGMo3r1YZ5k9AAAAAOe93L0xBJc9AAAAAMh+271YZ5k9AAAAAOe93L0KK1Y9AAAAAFoy3b05B3o9AAAAAJPW271ekaM9AAAAAA8M3r2ado09AAAAAJil372dOKY9AAAAAIBQ3L2M9aE9AAAAAI3C2L0eLY89AAAAAGFz2r3jtqU9AAAAAAek2r05B3o9AAAAAJPW272dOKY9AAAAAIBQ3L0020E9AAAAAGFy2b1Czjw9AAAAAP3s2r2/XFY9AAAAAGOH2r0kNGQ9AAAAAI572b0Pm0Q9AAAAAB8t3L1NZGU9AAAAALwb271Czjw9AAAAAP3s2r1x7IE9AAAAABfO2b0kNGQ9AAAAAI572b1NZGU9AAAAALwb272Ivyo9AAAAALxN17130SI9AAAAAL6J2b20VVI9AAAAACjR171fryE9AAAAAHZX271QtHg9AAAAAAYO2L2TOyc9AAAAAMX/3L05B3o9AAAAAJPW270eUo89AAAAAINH2L1QtHg9AAAAAAYO2L0GEm49AAAAAEs/1r2nH4c9AAAAANqX1r037o49AAAAAAJ71b3ekYc9AAAAAPzY1L2Kbpg9AAAAAHmd1r0lW5w9AAAAAF0K1b0kh5k9AAAAAO2o070lW5w9AAAAAF0K1b32zFE9AAAAAN2L1b14dHk9AAAAAP8J1L0+8Kc9AAAAAKd+1r0eUo89AAAAAINH2L1Vmqo9AAAAAI+R1L0wVaU9AAAAAHyl0L1vwJA9AAAAAIiB0r1Vwak9AAAAAJm30r19Mzs9AAAAAFhk0b1bBTY9AAAAAO4G072WQVI9AAAAAMSW0r2tbWE9AAAAAHJv0b0KmT49AAAAAOJp1L3Ax2I9AAAAABI7070kKYI9AAAAAOHK0b2tbWE9AAAAAHJv0b3YtyA9AAAAANzqzr2Xrxg9AAAAAEZ80b1UvU09AAAAAHGez73/HRg9AAAAANx8070MEHg9AAAAAMbfz70VJR49AAAAAPZT1b14dHk9AAAAAP8J1L3/HRg9AAAAANx8072D15A9AAAAAPEd0L1vwJA9AAAAAIiB0r0MEHg9AAAAAMbfz73VQm89AAAAAAj7zb3XNog9AAAAANpLzr16gJE9AAAAAMoazb0gNIs9AAAAAEJ+zL293Zo9AAAAAPtMzr3yEKA9AAAAALmYzL3XNog9AAAAANpLzr1/pJ89AAAAACsmy73gP1g9AAAAAEVnzb0O9YM9AAAAAPney72Jvqs9AAAAAJ4qzr2D15A9AAAAAPEd0L2ycq89AAAAAHoPzL0vsLE9AAAAAMG9x729/Jo9AAAAAAQwyr2fMrE9AAAAAOMHyr2ycq89AAAAAHoPzL1kPxA9AAAAAN4Dyr3gDhA9AAAAAE5Ry705uB89AAAAAG48y70nOiY9AAAAAFCIyr2qbho9AAAAAMqCzL2AAS09AAAAABrLy72S1z09AAAAAPwKy72YsQM9AAAAAHp8x707svs8AAAAAMuJyb1U9xg9AAAAANQOyb0Z0/88AAAAANVjy70bpTA9AAAAAMXcyb27XTE9AAAAAHMhzb0qxwg9AAAAALInzb2F2kM9AAAAAG8czL2UxGw9AAAAAOW2yr2AMks9AAAAAJNxyr1vNlg9AAAAAJ1Iy72F2kM9AAAAAG8czL3rgHM9AAAAACQNy72QrmA9AAAAAIPTy719W3k9AAAAAKpNy73AsoY9AAAAAJCTyr2n9lU9AAAAAGaczL0zMH49AAAAAMl8y71IsJE9AAAAABAvyr2kBYM9AAAAAGFyyr2JFpA9AAAAACnjyb0O9YM9AAAAAPney72F2kM9AAAAAG8czL38Dp49AAAAAGMmyb29/Jo9AAAAAAQwyr2JFpA9AAAAACnjyb1yrSk9AAAAAKIByb3DXzs9AAAAAE2eyb2fREM9AAAAAPmlyb2hXjw9AAAAAJ5fyb2C+lA9AAAAABslyr1v7VE9AAAAAA8Ayr3DXzs9AAAAAE2eyb1ry049AAAAAP3Tyb2hXjw9AAAAAJ5fyb1U9xg9AAAAANQOyb36DSE9AAAAAAaFyL0bpTA9AAAAAMXcyb0fpDc9AAAAACkjyb0ckWQ9AAAAAK2Fyr2AMks9AAAAAJNxyr1+b2E9AAAAAHxgyr0AXVs9AAAAAFIVyr3mmUs9AAAAAP2qyb3vK149AAAAAPo6yr0fpDc9AAAAACkjyb2chI49AAAAAFjUyb1PvIs9AAAAAEoAyr3jaZI9AAAAAGWnyb0Z5JY9AAAAAFxiyb28vog9AAAAAIElyr3eRpM9AAAAAF6hyb1PvIs9AAAAAEoAyr3omZ09AAAAAOoKyb1Yhog9AAAAAFcVyr0C/4Y9AAAAAPw6yr3/WZA9AAAAAHeryb0xfoQ9AAAAAH9gyr1f85k9AAAAAOomyb0heYA9AAAAAK6Fyr3VPKQ9AAAAAFSTyL2JFpA9AAAAACnjyb2VTZI9AAAAACo4yb1wuJA9AAAAACZxyb3C5ZY9AAAAAGgjyb0rWJo9AAAAAJTfyL39nJA9AAAAADyQyb1UOpk9AAAAAEAZyb2IdaE9AAAAANaZyL0rWJo9AAAAAJTfyL0GkYw9AAAAALdCyb0aRYs9AAAAAEmIyb1w2pM9AAAAAJH1yL0Q+ok9AAAAAJLEyb1z1Zw9AAAAACGVyL3/WZA9AAAAAHeryb2/Q4k9AAAAAObwyb1f85k9AAAAAOomyb0hd6Y9AAAAAOMryL3VPKQ9AAAAAFSTyL1z1Zw9AAAAACGVyL3uvSg9AAAAAECRyL0Qsjk9AAAAAIIWyb0Bhj49AAAAAPohyb0oijc9AAAAANXcyL1NJ0s9AAAAAN6Pyb0Q9Uo9AAAAAOlwyb2ZyEc9AAAAAM03yb0oijc9AAAAANXcyL0Q9Uo9AAAAAOlwyb0xdB49AAAAAL8dyL00fjI9AAAAAGGRyL014lk9AAAAAOLwyb3mmUs9AAAAAP2qyb2UdVg9AAAAAI3Eyb2yR1M9AAAAALRCyb3SrEQ9AAAAABT1yL2F31U9AAAAAEaIyb00fjI9AAAAAGGRyL2UdVg9AAAAAI3Eyb1htZU9AAAAAEEryL09OZQ9AAAAAEF7yL3A8Jk9AAAAAN5NyL19JJ09AAAAAGEIyL0cG5Q9AAAAAIa5yL3MFZw9AAAAAGFlyL21rqM9AAAAADgByL1rZpA9AAAAAEzux701Lo89AAAAAC9SyL1JLJc9AAAAALrPx70Q9o09AAAAAOKsyL0Hjp89AAAAAPOqx71w2pM9AAAAAJH1yL1IR409AAAAAC77yL1z1Zw9AAAAACGVyL17jqg9AAAAALaJx70Hjp89AAAAAPOqx72idSQ9AAAAAKP4x73wDjQ9AAAAAKRiyL0OcDg9AAAAAHFMyL2R8TE9AAAAAKQFyL2SLUQ9AAAAACi5yL2E80M9AAAAAAV7yL0M+UA9AAAAAOUqyL2E80M9AAAAAAV7yL1lTxo9AAAAAJN7x70UDS09AAAAADWnx72yR1M9AAAAALRCyb0v21E9AAAAACv7yL2ffVA9AAAAAN6syL3wnEs9AAAAAEjux70pCT49AAAAAD7Px71YDU49AAAAACtSyL2ffVA9AAAAAN6syL3ztZo9AAAAALFmxr1cEJg9AAAAALv+xr1InZ09AAAAAG38xr2nvKE9AAAAAACZxr1fgpc9AAAAAINvx71jLJ89AAAAAA5Lx71cEJg9AAAAALv+xr1PEqc9AAAAANT+xr1jLJ89AAAAAA5Lx73+V5c9AAAAABtSxb1A/pM9AAAAAAtaxr2kaZ89AAAAALSGxb1iCZI9AAAAAK8Cx73iTKc9AAAAAMzRxb1rZpA9AAAAAEzux70SHZE9AAAAAOOCx721gq49AAAAAKxLxr17jqg9AAAAALaJx73iTKc9AAAAAMzRxb12rh09AAAAAD/2xr3O4S09AAAAAFBIx70LFzE9AAAAAAL7xr1GwSg9AAAAAEGWxr0TXz09AAAAACdvx71NRTw9AAAAAH/+xr349zY9AAAAAFNmxr1GwSg9AAAAAEGWxr0CZw49AAAAAIg9xr1xjx09AAAAAAzOxb3wnEs9AAAAAEjux72lL0o9AAAAAN+Cx70LV0g9AAAAAKwCx73cuT09AAAAABdSxb2Iji09AAAAADeGxb1SbUQ9AAAAAAhaxr1xjx09AAAAAAzOxb0LV0g9AAAAAKwCx73MHaY9AAAAAMFVxL3nv6w9AAAAAIarxL0aj7A9AAAAAAagw71pq609AAAAAG0Hw71F3LM9AAAAAIjaxL03YrY9AAAAAKg4w700qLU9AAAAACbJwb1pq609AAAAAG0Hw703YrY9AAAAAKg4w73NfaA9AAAAAJn1w73gV6k9AAAAANCCwr1TRbo9AAAAACf2xL21gq49AAAAAKxLxr2yk7w9AAAAAO7Jwr3GLro9AAAAAId1vr2hALI9AAAAAIDkwL0sxbw9AAAAADi3wL2yk7w9AAAAAO7Jwr1nIwE9AAAAAHHJwb3w8/48AAAAAAs2w71vNQs9AAAAAKqew73tFBE9AAAAAGkHw70jGwQ9AAAAAPXRxL0wuxI9AAAAAMeoxL3w8/48AAAAAAs2w70WKSA9AAAAAGhVxL3tFBE9AAAAAGkHw71w6PA8AAAAAP55vr192eU8AAAAAJ23wL1jpwg9AAAAADHnwL3vDeY8AAAAAGHGwr1Pzhk9AAAAAKiDwr0cu+08AAAAANbnxL3vDeY8AAAAAGHGwr3ZcCs9AAAAAK71w71xjx09AAAAAAzOxb2KyJw9AAAAAAeUwr3s5ps9AAAAAPApw73cgaE9AAAAAIZswr0yCqQ9AAAAACvCwb0kIp09AAAAAE2Uw71l1aQ9AAAAABxdwr3LZKs9AAAAAM8Uwb0yCqQ9AAAAACvCwb3xuJc9AAAAAOCqwr3ds5Y9AAAAANhOw71I+Z09AAAAAJD3wb1H5ZU9AAAAABryw73R16U9AAAAAF4Swb0CEJY9AAAAAHmOxL1H5ZU9AAAAABryw73Jqq49AAAAAFIIwL3R16U9AAAAAF4Swb0PRBY9AAAAAEwcwb0C9SI9AAAAAKZfwr3Byyk9AAAAAEpywr0hQCU9AAAAAHnPwb3yMjI9AAAAADaVw7093zQ9AAAAAKQvw71lqTM9AAAAAG2mwr0hQCU9AAAAAHnPwb093zQ9AAAAAKQvw71AphA9AAAAALUawL0m4iI9AAAAAKYxwb0hT0A9AAAAAEyPxL21yUA9AAAAAMj4w71Pzhk9AAAAAKiDwr1WSz49AAAAAGrgwr2/YzI9AAAAAB0jwr1KkT89AAAAAG5lw71NXZ89AAAAAJBdwL3PJ549AAAAAO/5wL0bFaM9AAAAAC+LwL1E0aU9AAAAADv5v71RHp49AAAAAGh2wb1kAqU9AAAAAGGwwL3PJ549AAAAAO/5wL0Sqas9AAAAANrGv71E0aU9AAAAADv5v71kAqU9AAAAAGGwwL0VtZo9AAAAAHEKwL2AwJk9AAAAAE7CwL0Xi6A9AAAAAKCzv71KyZg9AAAAAHxxwb311qc9AAAAANBHv73xuJc9AAAAAOCqwr1VRZg9AAAAAPsPwr1KyZg9AAAAAHxxwb0I6q89AAAAANTUvr3Jqq49AAAAAFIIwL3aKhg9AAAAACfpv73qqSY9AAAAAEDswL1CUS49AAAAANfmwL2FzyQ9AAAAAGcawL23FDQ9AAAAAD3Nwb2z/jc9AAAAANSewb0chTY9AAAAAKn4wL2zvTA9AAAAANtUwL0mlzw9AAAAAOmIwb1AphA9AAAAALUawL0yIw49AAAAADDlvr0m4iI9AAAAAKYxwb2/YzI9AAAAAB0jwr1WSz49AAAAAGrgwr3pij49AAAAAHx5wr3W9z89AAAAAJctwr0cuEE9AAAAAFT1wb2V1UI9AAAAAAzPwb3rtkA9AAAAACCEwb2Sbj09AAAAANwPwb0MGDo9AAAAAFOEwL2p0Cw9AAAAABeuv72Qjzc9AAAAAO/pv707vx49AAAAAPdWv70rTaM9AAAAADuHvb3qHaE9AAAAAH9ivr0G86U9AAAAANJEvr1XfKk9AAAAAEWsvb3XvKA9AAAAAIwQv72TZac9AAAAAAKwvr0GV649AAAAAK8Yvr1XfKk9AAAAAEWsvb12LqA9AAAAAF8qvL1LdZ09AAAAAMuMvb2VQKc9AAAAAJJjvL1i5ps9AAAAAOGEvr0VOq49AAAAAPelvL0VtZo9AAAAAHEKwL3iN5s9AAAAAA1Rv7363LQ9AAAAAPEWvb0I6q89AAAAANTUvr311qc9AAAAANBHv72iXRA9AAAAAE4fvr2yeR49AAAAAGi2vr2b4iA9AAAAAJFHvr0Uphk9AAAAAFSuvb20kSs9AAAAADoOv70eYyo9AAAAAPphvr2yeR49AAAAAGi2vr0k2yU9AAAAAFuHvb0Uphk9AAAAAFSuvb0yIw49AAAAADDlvr267gI9AAAAAKMZvb07vx49AAAAAPdWv734CRA9AAAAANKmvL3PNjY9AAAAAFRDv72p0Cw9AAAAABeuv70brzQ9AAAAAMyAvr07vx49AAAAAPdWv70CDSw9AAAAAFoqvL1c6x09AAAAAKhjvL2SgTE9AAAAAEWMvb34CRA9AAAAANKmvL0W7qw9AAAAAEz5ur1NzLI9AAAAAKhLu7179bU9AAAAAPodur33WLM9AAAAAJZ6ub2EKbk9AAAAAGBsu70TA7s9AAAAABmhub1NzLI9AAAAAKhLu72BJ7o9AAAAAA4QuL0TA7s9AAAAABmhub2VQKc9AAAAAJJjvL2596c9AAAAACmMur0VOq49AAAAAPelvL2ggK89AAAAALTkuL1o7L49AAAAAJ91u71uX8A9AAAAACgcub3gnb09AAAAAB9ItL291rY9AAAAAJINt71AOcA9AAAAAJjbtr2ggK89AAAAALTkuL1uX8A9AAAAACgcub17N/A8AAAAAAoQuL2Dz+w8AAAAADihub0bgQA9AAAAAAgeur2PuAU9AAAAAJF6ub3NTfQ8AAAAAAZtu70P1wY9AAAAAN1Lu72djhI9AAAAAE35ur04XeI8AAAAABpItL0F8dc8AAAAAJfbtr2aef08AAAAAIsNt73gYNc8AAAAAFQcub3paA09AAAAAK7kuL267gI9AAAAAKMZvb3zTN08AAAAAH52u72Zehw9AAAAACOMur3paA09AAAAAK7kuL0dYqQ9AAAAAMeeuL2gwqM9AAAAALprub3tk6g9AAAAAN+guL1Wqqo9AAAAAOrOt71I86Q9AAAAAH4Gur05hKs9AAAAAHSnuL2gwqM9AAAAALprub3lDbE9AAAAAPArt705hKs9AAAAAHSnuL1K1Z89AAAAAAN0uL0KIJ89AAAAAL9aub34QaU9AAAAADvHt72Rl549AAAAAKxAur3QE6w9AAAAAE3otr165Z49AAAAADsfu72ggK89AAAAALTkuL2Rl549AAAAAKxAur3RtLM9AAAAAA/htb291rY9AAAAAJINt71mTgo9AAAAAOort72qYRU9AAAAAG+nuL01Qhs9AAAAANuguL1pFRc9AAAAAOTOt711gyI9AAAAAHwGur2+5CQ9AAAAALZrub2qYRU9AAAAAG+nuL3GpSM9AAAAAMWeuL1pFRc9AAAAAOTOt72+5CQ9AAAAALZrub2YAAU9AAAAAAvhtb17QhQ9AAAAAErotr34ni49AAAAADgfu72Zehw9AAAAACOMur3JOi89AAAAAKpAur1avyw9AAAAAP9zuL0R5iE9AAAAADjHt73XKS49AAAAALxaub3N96U9AAAAAHqLtb09FaU9AAAAAPpXtr1RZqk9AAAAACn9tb27rqs9AAAAAO9Ttb1sN6U9AAAAAPAKt70AMqs9AAAAAJZNtr3u6LA9AAAAAGtctb27rqs9AAAAAO9Ttb0AMqs9AAAAAJZNtr0LoqE9AAAAAK7dtL0gBKE9AAAAANDPtb2PzqY9AAAAAKWvtL2IYKA9AAAAAB26tr2yR609AAAAALF5tL1K1Z89AAAAAAN0uL1xH6A9AAAAAHeXt71jdLQ9AAAAADBItL2yR609AAAAALF5tL1UmAo9AAAAAGhctb0YBhY9AAAAAJFNtr1rnRk9AAAAACX9tb2lDBU9AAAAAOtTtb0o+yE9AAAAAOwKt72DPyI9AAAAAPhXtr0YBhY9AAAAAJFNtr1peiA9AAAAAHWLtb2YAAU9AAAAAAvhtb13gQM9AAAAACpItL262hE9AAAAAK15tL0KKyw9AAAAAHOXt73bqCs9AAAAABu6tr17QhQ9AAAAAErotr3XJSk9AAAAAKrdtL3mzB49AAAAAKKvtL2tYSo9AAAAAM3Ptb3bqCs9AAAAABu6tr0Vpag9AAAAANcEsr1g5aY9AAAAAMD4sr0OP6s9AAAAAC0Os726TK49AAAAAO5+sr38w6Y9AAAAAM3Vs71Rr6w9AAAAAJWps70i0bI9AAAAAC9Cs726TK49AAAAAO5+sr1Rr6w9AAAAAJWps700dKU9AAAAANs6sL1GVaM9AAAAALfBsb1f/Ks9AAAAAPDhsL1mNKI9AAAAABnmsr22ZLI9AAAAACuKsb0LoqE9AAAAAK7dtL2q2KE9AAAAAPTos71fhbg9AAAAAIxlsr1jdLQ9AAAAADBItL22ZLI9AAAAACuKsb3yxwY9AAAAAClCs716CxM9AAAAAJGps73z6xU9AAAAACoOs72x0A89AAAAAOt+sr0M4h49AAAAAMnVs71Bnx49AAAAAL34sr16CxM9AAAAAJGps73eHxs9AAAAANQEsr2x0A89AAAAAOt+sr1Bnx49AAAAAL34sr0pv/Y8AAAAAIZlsr262hE9AAAAAK15tL3KoAc9AAAAACiKsb2YuCg9AAAAAPLos70gASg9AAAAABPmsr262hE9AAAAAK15tL2UgSE9AAAAANc6sL1dcRQ9AAAAAOzhsL1ovyU9AAAAALPBsb3KoAc9AAAAACiKsb1M6rA9AAAAAP+ar73SU7Y9AAAAAF1FsL0uBrk9AAAAAD4rr73ch7Y9AAAAAO9arr3/Jrw9AAAAAOTBsL1zjr09AAAAABTvrr3SU7Y9AAAAAF1FsL2egrw9AAAAAB1Jrb1zjr09AAAAABTvrr1f/Ks9AAAAAPDhsL20Rqw9AAAAAM/Yrr3r4rI9AAAAAO6Arb3yZsE9AAAAANoasb1fhbg9AAAAAIxlsr3kXcI9AAAAAECwrr22ZLI9AAAAACuKsb16ZL89AAAAAMsPqr3CR7k9AAAAAC4RrL2b4ME9AAAAADJzrL3kXcI9AAAAAECwrr1zyuY8AAAAABpFrb0Vm+I8AAAAALztrr3zu/Q8AAAAAJ4qr708tf48AAAAALhZrr3MOOg8AAAAALTBsL1Rhf88AAAAAEJFsL0Vm+I8AAAAALztrr2blQo9AAAAANWar708tf48AAAAALhZrr1Rhf88AAAAAEJFsL1EQ9s8AAAAAEz4qb26UtE8AAAAAB9qrL3HtfM8AAAAAAQLrL2FXc88AAAAAJStrr1ypAY9AAAAAEd/rb0pv/Y8AAAAAIZlsr0oOdM8AAAAAIAasb283BM9AAAAAJjYrr1ypAY9AAAAAEd/rb24Vag9AAAAAFhErL2YBqg9AAAAAOUzrb1gWKw9AAAAAHOorL3vD649AAAAAJfaq71zVqk9AAAAAAAIrr26H689AAAAAEfxrL2YBqg9AAAAAOUzrb3V7LM9AAAAAF+1q72e4KM9AAAAAIKjq73sjaM9AAAAAKG0rL3c2qg9AAAAAGhLq73dYKM9AAAAAEnIrb2FKK89AAAAAOrhqr20Rqw9AAAAAM/Yrr3O9KM9AAAAADjhrr3dYKM9AAAAAEnIrb0XSrY9AAAAAMt3qr3CR7k9AAAAAC4RrL2FKK89AAAAAOrhqr2ikAQ9AAAAAHSxq73AKg49AAAAABDwrL1guRM9AAAAANSnrL1RShA9AAAAAE3Zq70uvRk9AAAAANgHrr3dXBw9AAAAAMozrb3AKg49AAAAABDwrL2hvhs9AAAAAC5ErL1nrP88AAAAAKlvqr1ypAY9AAAAAEd/rb0qGQ49AAAAAJffqr1bgCQ9AAAAADfhrr283BM9AAAAAJjYrr09qCU9AAAAAEfIrb26qCQ9AAAAAIKjq71atBo9AAAAABtLq70cTiU9AAAAAJ20rL0qGQ49AAAAAJffqr09qCU9AAAAAEfIrb36/6k9AAAAAISOqL35gKg9AAAAAAl8qb3Gvqw9AAAAAEJ4qb3WmK89AAAAACPmqL0Elqg9AAAAAJ1fqr35Sq49AAAAAM4Kqr2rLLQ9AAAAAGiEqb3WmK89AAAAACPmqL1Th6Y9AAAAAAL/pr04xaQ9AAAAAPphqL3lDq09AAAAADaXp71G76M9AAAAAAGGqb13bbM9AAAAAJsXqL2e4KM9AAAAAIKjq71W1qM9AAAAAC6Xqr1G76M9AAAAAAGGqb1uk7k9AAAAAFm7qL0XSrY9AAAAAMt3qr13bbM9AAAAAJsXqL3/EAQ9AAAAAPV4qb1A1A89AAAAAE0Hqr2Y7BI9AAAAAMtyqb2SOA09AAAAADHZqL0JPhs9AAAAAMpeqr0gaBs9AAAAADB4qb0tahg9AAAAABmCqL1Jh/I8AAAAAPqbqL11jwU9AAAAADP3p71JvSQ9AAAAANGWqr1atBo9AAAAABtLq71oiyQ9AAAAACyDqb1sWx89AAAAAN/jpr11TBI9AAAAACN3p72P3yI9AAAAACVYqL11jwU9AAAAADP3p73pkOU8AAAAADywpL0lq+A8AAAAANbxpb2OWvI8AAAAAEkepr3cjfw8AAAAAEx+pb3ESuU8AAAAAOdPp70HZ/w8AAAAAD3zpr0lq+A8AAAAANbxpb0A/wg9AAAAALhvpr3cjfw8AAAAAEx+pb0HZ/w8AAAAAD3zpr3N89s8AAAAAHYDor1Y1tA8AAAAAHIMpL14/fI8AAAAAByuo7205M08AAAAABPEpb3KtAU9AAAAAAzIpL3leNA8AAAAAB+Up7205M08AAAAABPEpb0eXRI9AAAAAEXJpb3TtrE9AAAAAO6ypr35G7c9AAAAAE80p72Wobk9AAAAAB+Apr2VGrc9AAAAAH3vpb1e47w9AAAAADqVp71AEL49AAAAAPBmpr1+67w9AAAAALtVpb2rCq09AAAAAEgOpr1Ye7M9AAAAAKRBpb0mGMI9AAAAAHTgp70BxMI9AAAAADRNpr1bV8A9AAAAADFXo70Y57k9AAAAAGdtpL3PJsI9AAAAAIrgpL1Ye7M9AAAAAKRBpb3MTAQ9AAAAAFQ7o72IYw09AAAAAFU0pL08FRM9AAAAAP3To70CBBA9AAAAAAEgo704gxg9AAAAAIj9pL1rhBs9AAAAAH8lpL2pXRs9AAAAANM7o70CBBA9AAAAAAEgo73nHAA9AAAAAIEhor1RTQ49AAAAAFw2or386SI9AAAAAOuTpb3PmSQ9AAAAACt5pL3KtAU9AAAAAAzIpL1AuiQ9AAAAAKBVor221Ro9AAAAAPlHor32zSQ9AAAAALdlo71RTQ49AAAAAFw2or055qk9AAAAALxeo73q26g9AAAAAL9bpL2OTq09AAAAANkrpL2mxa89AAAAAEV+o72lCKo9AAAAABU/pb392q89AAAAAMChpL2fNrU9AAAAAPbUo72mxa89AAAAAEV+o73sKqY9AAAAAODnob1xnaQ9AAAAAKdco737w6w9AAAAAD5Jor2aIqQ9AAAAAEKOpL0UR7M9AAAAAJyKor2rCq09AAAAAEgOpr1Zx6Q9AAAAAJKypb2aIqQ9AAAAAEKOpL0yx7k9AAAAAEfSor0UR7M9AAAAAJyKor1Ye7M9AAAAAKRBpb1PTLE9AAAAAG40ob0Cw7Y9AAAAAPaDob0ULbk9AAAAANWzoL3ekLY9AAAAAIszoL3en7w9AAAAAC+eob0olr09AAAAAONpoL0Cw7Y9AAAAAPaDob1fPbw9AAAAAERRn73ekLY9AAAAAIszoL0olr09AAAAAONpoL1qjKw9AAAAAJe1oL1yyLI9AAAAACign73t4sE9AAAAAOaeob0yx7k9AAAAAEfSor1YRMI9AAAAAAMcoL0XZ749AAAAAOPGnL3Cybg9AAAAANp1nr3wXcE9AAAAAN+Znr2V1AQ9AAAAAD0Wob17fBA9AAAAALpTob1G5xM9AAAAAHCroL1qYg49AAAAALc7oL323hs9AAAAACNYob01fRw9AAAAAIxzoL17fBA9AAAAALpTob1/4xk9AAAAAGaXn71qYg49AAAAALc7oL3nHAA9AAAAAIEhor2KYvQ8AAAAAAyAoL0R6wY9AAAAADmPn71AuiQ9AAAAAKBVor0oXyU9AAAAANRIob2yuSU9AAAAAFc7oL3yniE9AAAAANTSnb3kDxQ9AAAAAPC5nr1tlSQ9AAAAAC0kn72yuSU9AAAAAFc7oL3LvKc9AAAAAONenr0kxqc9AAAAALE+n72p+Ks9AAAAAF7cnr1Oba09AAAAADMpnr2qYak9AAAAADcFoL1t3649AAAAAKgpn72yUrM9AAAAAFAmnr1Oba09AAAAADMpnr1t3649AAAAAKgpn70i66I9AAAAAHeYnb2vA6M9AAAAACidnr1g4qc9AAAAAEh0nb1WQKM9AAAAAJ2kn73xLK49AAAAAPRFnb1/O6Q9AAAAAG6voL1WQKM9AAAAAJ2kn71uTLU9AAAAACwQnb3Cybg9AAAAANp1nr1yyLI9AAAAACign70Tk+g8AAAAAMnNnL3xY+M8AAAAAHQXnr0kdfU8AAAAACUInr2bCgA9AAAAAEtHnb2tl+c8AAAAAEBin71WYv88AAAAALi7nr1B2go9AAAAAFXwnb2bCgA9AAAAAEtHnb2vdNs8AAAAAECWmr32WdM8AAAAAJB1nL0+bPU8AAAAAHaom70JOdA8AAAAAI0mnr3yqQc9AAAAABRjnL2KYvQ8AAAAAAyAoL3ZONI8AAAAAPfhn70JOdA8AAAAAI0mnr3BoBQ9AAAAAOYOnb3kDxQ9AAAAAPC5nr3yqQc9AAAAABRjnL0R6wY9AAAAADmPn73pkQQ9AAAAAKPmmr0nWg89AAAAAMOhm71qzBQ9AAAAACUem7338w89AAAAAB53mr2hIRs9AAAAAFgknL1O7R09AAAAAN88m70nWg89AAAAAMOhm70zLBw9AAAAAL5Fmr1O7R09AAAAAN88m70+bPU8AAAAAHaom71h3fY8AAAAANLgmb3yqQc9AAAAABRjnL3a/wg9AAAAAHCAmb3YyCU9AAAAAHl7nL0Inyc9AAAAAG1dm73PgCQ9AAAAALrNmL1wnBY9AAAAAJwvmb0NJSc9AAAAAKM4mr16Cqg9AAAAAIjimr0S1KY9AAAAAFa5m71FLKs9AAAAAKjam70h5609AAAAAApkm70RP6c9AAAAAJaRnL0b+Kw9AAAAAN5ynL1mzrI9AAAAAFYdnL0h5609AAAAAApkm70Y9aM9AAAAAAZImb0Vm6I9AAAAAKCNmr0N5Ko9AAAAAFUEmr07KKI9AAAAAD2Zm72BmbE9AAAAAGCwmr0i66I9AAAAAHeYnb1g4qc9AAAAAEh0nb2BdqI9AAAAACOZnL07KKI9AAAAAD2Zm704G7g9AAAAAAN3m72BmbE9AAAAAGCwmr3heK89AAAAAKUymb0kLbU9AAAAAKjZmb3ioLc9AAAAAF8mmb1H4rQ9AAAAAKt8mL0tPbs9AAAAAEtcmr0VM7w9AAAAAFUhmb0kLbU9AAAAAKjZmb2pyro9AAAAAEHxl70VM7w9AAAAAFUhmb0N5Ko9AAAAAFUEmr32c6o9AAAAAKpzmL1e9LA9AAAAAHq2l73vrMA9AAAAAJa8mr11DME9AAAAAMQamb2BmbE9AAAAAGCwmr2Y8r09AAAAAOzLlb2Xc7c9AAAAAA3rlr1tIsA9AAAAAFSHl71e9LA9AAAAAHq2l711DME9AAAAAMQamb0UPe48AAAAACTnlb2aJeg8AAAAAJcnl73kYvo8AAAAAHJ4l73SvwI9AAAAAPbmlr0/ous8AAAAAC6KmL0TCAI9AAAAAAJjmL2aJeg8AAAAAJcnl71TfA09AAAAAGgGmL1bb+Y8AAAAAEAYk702Jdk8AAAAAEwUlb2VHv08AAAAAAL9lL0sydQ8AAAAAG3Slr1Y0Ao9AAAAAHlMlr1h3fY8AAAAANLgmb3VxtU8AAAAAI+XmL0sydQ8AAAAAG3Slr3FjRc9AAAAADyEl71wnBY9AAAAAJwvmb1Y0Ao9AAAAAHlMlr1kLQo9AAAAAA7LlL0qMRM9AAAAANjllb16cBk9AAAAAHuwlb0MphY9AAAAAJr9lL3DdB49AAAAACThlr3eKSI9AAAAAIgvlr0qMRM9AAAAANjllb2SnSI9AAAAAIpilb0MphY9AAAAAJr9lL3eKSI9AAAAAIgvlr2VHv08AAAAAAL9lL3VagY9AAAAAJuyk73jcBU9AAAAAEoolL0ODyk9AAAAAN+nl71Rkis9AAAAAHW1lr0ULi09AAAAAL7glL1rtSI9AAAAAHqPlL0jhiw9AAAAAA/Ilb0ZW6Y9AAAAAErjlb3nj6U9AAAAAFnQlr0hLqo9AAAAAD2glr12k6w9AAAAAC34lb1FEqc9AAAAAKmkl73Y/aw9AAAAANsQl70GZLI9AAAAAF5Jlr12k6w9AAAAAC34lb0f+6E9AAAAAOyRlL2Tx6A9AAAAACjulb2dFKk9AAAAAPrPlL11qKA9AAAAAEgDl72XBbA9AAAAAHr/lL1ztaE9AAAAABYNmL1e9LA9AAAAAHq2l711qKA9AAAAAEgDl73u8LY9AAAAAMU9lb08oK09AAAAAJ+hk73DebM9AAAAAObgk71p3rU9AAAAANz2kr2nALM9AAAAAFd4kr2Rsbk9AAAAAMDrk72Ee7o9AAAAAPGVkr192Lg9AAAAAPJqkb2Ee7o9AAAAAPGVkr2dFKk9AAAAAPrPlL0idqg9AAAAAJg8k73p2a49AAAAALf3kb20P789AAAAALngk73u8LY9AAAAAMU9lb1kYb89AAAAAI4vkr2XBbA9AAAAAHr/lL0goLo9AAAAAMy0jr06/bQ9AAAAACWdkL1AJ749AAAAACqKkL1kYb89AAAAAI4vkr2TEQw9AAAAAKvmkr3lWBg9AAAAAIV1k72mZRw9AAAAAG/8kr1HwRY9AAAAAGdskr1ZciQ9AAAAADPMk71UrSU9AAAAAFoMk73lWBg9AAAAAIV1k70gZyM9AAAAACc0kr1UrSU9AAAAAFoMk73VagY9AAAAAJuyk73I+QA9AAAAAP/+kb1sEw89AAAAAJuGkb0ULi09AAAAAL7glL0TlS49AAAAAPcClL1JpS89AAAAAGogk71eoiw9AAAAADHbkL3ulR09AAAAAL0wkb3xFi89AAAAALgkkr3Um6I9AAAAAANYkb0b7KI9AAAAAOkVkr0YVac9AAAAAJOIkb1isKg9AAAAAEnakL1g4qQ9AAAAAB+zkr00i6o9AAAAANuqkb0b7KI9AAAAAOkVkr1SC689AAAAAJ2KkL1isKg9AAAAAEnakL00i6o9AAAAANuqkb0uJp09AAAAAED8kL2vlJ09AAAAAObQkb1VeaI9AAAAAIiUkL1CKp49AAAAAIqrkr2ZOKk9AAAAALwQkL2Yi589AAAAACuIk73p2a49AAAAALf3kb1CKp49AAAAAIqrkr2S3LA9AAAAAD16j72ZOKk9AAAAALwQkL0vlPg8AAAAAHTSjb1Lj/E8AAAAAHUjj71EiQI9AAAAAHp2j739nQg9AAAAALXhjr23EfU8AAAAANWckL3Cngc9AAAAAAFpkL3R+xM9AAAAABYKkL1UcvQ8AAAAAFnMir3SOuI8AAAAAHfvjL3blQQ9AAAAAN7qjL1t1dw8AAAAAJzLjr3ochE9AAAAAIlPjr3I+QA9AAAAAP/+kb2vp908AAAAACm4kL1sEw89AAAAAJuGkb3o9B49AAAAAAOTj73ulR09AAAAAL0wkb3ochE9AAAAAIlPjr2nPBE9AAAAAM7fjL0qoxo9AAAAAGUBjr0AgSE9AAAAABbmjb3qth49AAAAAHw+jb3WnSY9AAAAAPIIj70o3yo9AAAAAKF1jr3hois9AAAAAB/Gjb3qth49AAAAAHw+jb0o3yo9AAAAAKF1jr0JNQ49AAAAAPHci73w4h09AAAAAHCFjL327jE9AAAAAEraj73o9B49AAAAAAOTj70i/DQ9AAAAALwMj71uYDc9AAAAAF+Fjb25DCw9AAAAABoVjb0KWDY9AAAAANFEjr0i/DQ9AAAAALwMj72B46E9AAAAALxljr0azaA9AAAAACg2j71xi6U9AAAAAG0Nj73wYag9AAAAAIF2jr1EgaE9AAAAAK7kj72/qac9AAAAANRyj70azaA9AAAAACg2j7025a09AAAAAAXLjr3wYag9AAAAAIF2jr3zC509AAAAAGo9jb1L5ps9AAAAACd5jr1hyaQ9AAAAAERfjb0atZs9AAAAAIpkj72GPqw9AAAAAA6Gjb1VeaI9AAAAAIiUkL0yV5w9AAAAACEzkL0atZs9AAAAAIpkj71cgLM9AAAAAJHPjb2S3LA9AAAAAD16j71+oKk9AAAAABUnjL29/K89AAAAAPNcjL1eiLI9AAAAANFhi71TYa89AAAAAG3jir3AtLY9AAAAAFlnjL2Ag7c9AAAAAE/yir2/obU9AAAAABCxib1hyaQ9AAAAAERfjb2696M9AAAAAE/Yi72GPqw9AAAAAA6Gjb0/0Ko9AAAAALtyir36tbw9AAAAAJZejL3lzbw9AAAAAHF8ir2I7LU9AAAAAISZhr3rTbE9AAAAAGHoiL3aSrs9AAAAAJisiL0/0Ko9AAAAALtyir3lzbw9AAAAAHF8ir2gghY9AAAAAOZni7002SE9AAAAAB0FjL2+Lyc9AAAAAKzAi73HdiM9AAAAACpOi71OYC49AAAAAEx9jL2cwjA9AAAAAJX0i7002SE9AAAAAB0FjL0/3jA9AAAAAHlki72cwjA9AAAAAJX0i70JNQ49AAAAAPHci71drxA9AAAAAEWuir3w4h09AAAAAHCFjL3U3yE9AAAAAHm8ir0hRjk9AAAAAEjVjL0bMTs9AAAAAOAtjL2wWD09AAAAAPLkir0iMDE9AAAAAFzRir11PDw9AAAAAJyHi73U3yE9AAAAAHm8ir0bMTs9AAAAAOAtjL1HTZ09AAAAADNcir1lwZ09AAAAAMv5ir2Ih6I9AAAAAMhNir0J6aM9AAAAAL6mib33/Z89AAAAAKhxi70fEqY9AAAAANBKir1R0Ko9AAAAADsSib1oO5c9AAAAALFVir3u1Jc9AAAAADv+ir3YBp09AAAAALe9ib3rmZg9AAAAAACvi70eRqQ9AAAAAPj5iL2696M9AAAAAE/Yi72cPZo9AAAAAKVgjL0/0Ko9AAAAALtyir3rmZg9AAAAAACvi72JRKw9AAAAAFwSiL3rTbE9AAAAAGHoiL1qERc9AAAAAOz1ib38aCU9AAAAAMUxir1sWSo9AAAAANvJib0m2SM9AAAAAFZsib0dijM9AAAAADtEir2ARTU9AAAAABC3ib38aCU9AAAAAMUxir3n2jI9AAAAAOYYib0pGwo9AAAAABFZib25+Bo9AAAAAHm7iL1SXz89AAAAANpHir0iMDE9AAAAAFzRir2K+EA9AAAAADGmib0MGD49AAAAAKnzh72WOSw9AAAAAGRMiL16pUA9AAAAANvviL25+Bo9AAAAAHm7iL2K+EA9AAAAADGmib24ZJo9AAAAAEBRiL0EgJo9AAAAAJ/QiL3raZ89AAAAAMV1iL3BRqE9AAAAAD/+h71zxps9AAAAANI/ib0YMKI9AAAAAFKZiL0EgJo9AAAAAJ/QiL0A8Kc9AAAAAILUh71H7ZM9AAAAAGEaiL2ajZQ9AAAAAHGkiL0xKpo9AAAAAIbRh73GJZU9AAAAACEzib307aE9AAAAALh4h73YBp09AAAAALe9ib1xMZY9AAAAAPe/ib3GJZU9AAAAACEzib16fKo9AAAAAPYZh70w3QU9AAAAAEk6hb1pIQE9AAAAAHOThr0Pkgw9AAAAACHVhr017hM9AAAAAHU5hr1DyAI9AAAAAOwOiL0eXhI9AAAAADa8h71pIQE9AAAAAHOThr1nFCE9AAAAAP9Kh7017hM9AAAAAHU5hr3X3Qk9AAAAAEczgr3VWfI8AAAAAAVhhL17OxA9AAAAAEVYhL0u6+k8AAAAAOhNhr0Bhx49AAAAAJmshb1Hx+k8AAAAAERLiL25+Bo9AAAAAHm7iL0u6+k8AAAAAOhNhr0TJi49AAAAAOrXhr3t2x49AAAAAJ9yhL1ubyk9AAAAADt6hb2AkDE9AAAAAMl/hb1veC49AAAAANX6hL2WWTc9AAAAAIZxhr1cjTw9AAAAANwShr05pT09AAAAAA2fhb1veC49AAAAANX6hL1cjTw9AAAAANwShr2J5xs9AAAAAD+lg70+uC09AAAAAMB8hL25o0Q9AAAAADU2h73ffEg9AAAAAFmuhr0Lv0s9AAAAAKS/hb3EUj49AAAAAG0yhb1MUUo9AAAAAHUwhr0+uC09AAAAAMB8hL3ffEg9AAAAAFmuhr2yUZc9AAAAADmkhr3qbpc9AAAAABAFh732v5w9AAAAAJ7mhr2Zy549AAAAAC2chr2r0Jg9AAAAAK5kh72jwJ89AAAAAOIZh71nEKY9AAAAAMy5hr2Zy549AAAAAC2chr29VpA9AAAAALtNhr2yA5E9AAAAADu4hr0YF5c9AAAAAANEhr3QqJE9AAAAAGsoh72SpJ89AAAAAMw8hr1H7ZM9AAAAAGEaiL1yy5I9AAAAAN6ch7307aE9AAAAALh4h73QqJE9AAAAAGsoh73aU6k9AAAAAK5Bhr3GjyU9AAAAAJebg72TgjI9AAAAAPFJhL1+3Tg9AAAAAAxIhL27nzQ9AAAAAGztg72aPUE9AAAAAIzmhL3DMkQ9AAAAAJCnhL0bckQ9AAAAAFhYhL2J5xs9AAAAAD+lg70LESA9AAAAAOwOg72jJzM9AAAAAHWWg705Lk49AAAAAHJihb1JnVA9AAAAAHIOhb3JaVM9AAAAADhrhL029kQ9AAAAABINhL0P/FE9AAAAAHO5hL2jJzM9AAAAAHWWg73+CpY9AAAAALARhb2wu5Q9AAAAAIGIhb0B05o9AAAAAEeUhb1HcJ49AAAAANpKhb1xvJU9AAAAAGvohb1Anp09AAAAAEXehb3+qaU9AAAAAL20hb1HcJ49AAAAANpKhb2RvY89AAAAACM6hL3uXY49AAAAAJD+hL3fsZk9AAAAABpghL2AOo49AAAAAN9+hb3hW6M9AAAAAAmshL13KY89AAAAAAfphb2SpJ89AAAAAMw8hr1M6aw9AAAAABcshb3aU6k9AAAAAK5Bhr3hW6M9AAAAAAmshL171Z89AAAAAIFig72EE6g9AAAAAPiyg71gLqs9AAAAAC7Mgr3V+aY9AAAAABhGgr1N17A9AAAAAETrg73Ie7E9AAAAANd4gr0GdK49AAAAALg0gb3V+aY9AAAAABhGgr3Ie7E9AAAAANd4gr2Nipg9AAAAALkag70kAqE9AAAAAJzfgb2HpLg9AAAAAPsThL1yNLg9AAAAADUggr2CJqo9AAAAAG2afL1bXqg9AAAAAB18gL2oNbU9AAAAAHpGgL0AAio9AAAAANwDg730Gjg9AAAAADpzg71z8z49AAAAAIRyg73MVjo9AAAAAHw5g70gDUg9AAAAALXZg71PNEs9AAAAAKyxg730Gjg9AAAAADpzg71Tbks9AAAAAJ+Bg73MVjo9AAAAAHw5g71PNEs9AAAAAKyxg70LESA9AAAAAOwOg710iSQ9AAAAAMOlgr0Z7Tg9AAAAABgEg73JaVM9AAAAADhrhL1mAFY9AAAAAFkshL09lVg9AAAAAMH2g72jJzM9AAAAAHWWg70Zf1s9AAAAAJuYg70890s9AAAAABhXg70WA1o9AAAAALvDg70Z7Tg9AAAAABgEg709lVg9AAAAAMH2g72Q5Y89AAAAAEWAgr0ChpA9AAAAAOHCgr3gjJY9AAAAAMMTgr0+Kpg9AAAAAFSjgb1Va5M9AAAAAKLqgr2U/po9AAAAAMjggb14faA9AAAAAMzXgL0+Kpg9AAAAAFSjgb2U/po9AAAAAMjggb1fF4g9AAAAACcMg72244g9AAAAAHU9g70Efo89AAAAAJBJgr3a6ok9AAAAAJ99g736Ypg9AAAAAF9Qgb2Nipg9AAAAALkag73JEow9AAAAAOnEg70kAqE9AAAAAJzfgb3a6ok9AAAAAJ99g72SZ6E9AAAAAN4rgL1bXqg9AAAAAB18gL0kAqE9AAAAAJzfgb32qog9AAAAAJ0Xgr2FMYs9AAAAAN07gr04R5E9AAAAAAGdgb1U4pE9AAAAAII/gb0ruI09AAAAAMQ9gr1yZpU9AAAAANFggb2FMYs9AAAAAN07gr0TBZs9AAAAAHJ9gL2VrXU9AAAAAFjLgr1nWYE9AAAAAFLTgr0mkIM9AAAAAFbmgb08cYQ9AAAAAK7lgr1HOI49AAAAABTpgL1fF4g9AAAAACcMg71Cn4Y9AAAAAN7zgr08cYQ9AAAAAK7lgr0Gp5k9AAAAACaef72SZ6E9AAAAAN4rgL1HOI49AAAAABTpgL17tDE9AAAAAHaLgr0w/D49AAAAAH/ugr0VrEc9AAAAAJTqgr0lvUU9AAAAAByngr1ajk89AAAAAAE9g71MplQ9AAAAAMcfg70TeFk9AAAAADXigr0lvUU9AAAAAByngr1MplQ9AAAAAMcfg72t6zA9AAAAANv0gb0z0Es9AAAAAEIpgr0CdV49AAAAAGx5g70890s9AAAAABhXg7200GI9AAAAAA1Zg71zLGM9AAAAAHNugr0f5Wg9AAAAAN8mg70z0Es9AAAAAEIpgr200GI9AAAAAA1Zg70vw0k9AAAAALcSgb1/Xl49AAAAAHt4gb3pQXI9AAAAAJHagL3z6W49AAAAAL9GgL1GonQ9AAAAAIezgb0lFYQ9AAAAAL3OgL1/Xl49AAAAAHt4gb1BBYs9AAAAABScf73z6W49AAAAAL9GgL0lFYQ9AAAAAL3OgL2+YDc9AAAAANtTgL0z0Es9AAAAAEIpgr26GWY9AAAAAC++fr0mkIM9AAAAAFbmgb1otIs9AAAAAJxLfb1UrDY9AAAAAMNQd72qeSw9AAAAAOaSer3YMEo9AAAAAF2ber0mH109AAAAADvCeL1Tvi09AAAAAMzTfb24XVc9AAAAAJOBfL2qeSw9AAAAAOaSer0o9389AAAAAMLVer28tiA9AAAAAI2Dcb0ePhQ9AAAAAIRYdr2Q5Eo9AAAAAN0ydL0fUg09AAAAAC6Ner14BnY9AAAAAPBOdr3ZXQo9AAAAAHXWfr26GWY9AAAAAC++fr0fUg09AAAAAC6Ner19f5E9AAAAAN6ZeL1otIs9AAAAAJxLfb14BnY9AAAAAPBOdr3D+Gg9AAAAAPSucb08iYY9AAAAAK/Gc72HR449AAAAAGTQcb1vyIU9AAAAAILJb71enJo9AAAAAKhadb2w55w9AAAAAObmcb08iYY9AAAAAK/Gc73DfZg9AAAAAFiBbr1vyIU9AAAAAILJb72w55w9AAAAAObmcb2Q5Eo9AAAAAN0ydL1F6ko9AAAAAL0Eb72xSHQ9AAAAAKAkbb1Mq6w9AAAAAKt3dr25Waw9AAAAAP35cb14BnY9AAAAAPBOdr2iJ6M9AAAAADmyaL1jtI49AAAAANc/a70DTKk9AAAAAJWmbb2xSHQ9AAAAAKAkbb1R0Dk9AAAAAFn7ZL1pFjI9AAAAAB5daL2SHU49AAAAAMZwaL2VOl49AAAAAKV3Zr0AdDg9AAAAAFjBa73Tq109AAAAAC97ar1pFjI9AAAAAB5daL3jAIA9AAAAAAKPaL3Tq109AAAAAC97ar065iQ9AAAAAKnuXr3AHhk9AAAAAG3zY70EtUw9AAAAAH68Yb0mWBQ9AAAAAOJGaL3exXQ9AAAAADTdY71p3xY9AAAAAC2VbL0mWBQ9AAAAAOJGaL3tjI49AAAAAEr4Zb1jtI49AAAAANc/a73exXQ9AAAAADTdY732Omk9AAAAAHIeX72pV4U9AAAAALM+Yb2M3Iw9AAAAADE8X71y/YQ9AAAAAO4kXb3sd5c9AAAAAI+4Yr2Te5o9AAAAAH5KX72pV4U9AAAAALM+Yb0OppY9AAAAAJrNW71y/YQ9AAAAAO4kXb2Te5o9AAAAAH5KX73t5Uw9AAAAAEhWXL2fAHQ9AAAAAEdhWr2f0qc9AAAAAIa4Y70A8Kg9AAAAAEdYX73exXQ9AAAAADTdY72nqaA9AAAAAIu4Vb28aY09AAAAAGBmWL2fgKY9AAAAAF/oWr2fAHQ9AAAAAEdhWr0+Ij09AAAAABTjUb2ltTU9AAAAADdoVb1MHFA9AAAAAPF6Vb2GWV89AAAAANVrU70sjzs9AAAAAGPvWL2ns149AAAAAE6aV72ltTU9AAAAADdoVb3+Gn89AAAAAI+XVb2GWV89AAAAANVrU731vCk9AAAAADabS71ubh49AAAAAPXTUL0d+049AAAAAK1/Tr1hsRk9AAAAAPdSVb0ilXQ9AAAAAICyUL0E1hs9AAAAAK/MWb1hsRk9AAAAAPdSVb3kPY09AAAAAAfhUr0StWk9AAAAABy/S70AjIQ9AAAAABjyTb2DjYs9AAAAAHfUS711JoQ9AAAAAG6nSb3Qj5U9AAAAAKB3T70NTpg9AAAAABTeS73yopQ9AAAAAB84SL11JoQ9AAAAAG6nSb1WNU89AAAAAFTeSL2MuXM9AAAAAI/JRr3n66Q9AAAAAO9+UL3kPY09AAAAAAfhUr1g1qU9AAAAAOXmS70d2Z09AAAAALXUQb029os9AAAAAKmtRL3bbaM9AAAAAIJAR72MuXM9AAAAAI/JRr227UA9AAAAAGAHPr3H3Dk9AAAAAHWxQb0FalI9AAAAAKS7Qb1Gp2A9AAAAAHCSP70EJD89AAAAAFhZRb1d6l89AAAAAHnrQ73nHX49AAAAABPJQb1Gp2A9AAAAAHCSP72JOi89AAAAAPmKN73qeiQ9AAAAACX6PL3KlFE9AAAAAKd6Or3ozh89AAAAAE6lQb1UZXQ9AAAAAFW0PL2giSE9AAAAAARJRr3+xYs9AAAAAAXrPr029os9AAAAAKmtRL1mR2o9AAAAAN6PN73mqYM9AAAAABrMOb36F4o9AAAAAEGPN70OOYM9AAAAAPdQNb3na5M9AAAAAC5TO72c3ZU9AAAAAI6MN73mqYM9AAAAABrMOb0bZJI9AAAAAMi/M70OOYM9AAAAAPdQNb2c3ZU9AAAAAI6MN73KlFE9AAAAAKd6Or1M2FE9AAAAALGeNL1UZXQ9AAAAAFW0PL11c3M9AAAAAENfMr3Bp6E9AAAAALtYPL3+xYs9AAAAAAXrPr2tW6I9AAAAAFCIN706tpo9AAAAAHgILb3qWYo9AAAAAHkXML3I/Z89AAAAANisMr11c3M9AAAAAENfMr2tW6I9AAAAAFCIN71uMkU9AAAAAA1qKb1/iz49AAAAAKk6Lb2PBlU9AAAAAKk0Lb28I2I9AAAAAEPtKr09MkM9AAAAAAQBMb3TT2E9AAAAAHRwL71/iz49AAAAAKk6Lb2PCn09AAAAAFUlLb3TT2E9AAAAAHRwL72SXjU9AAAAAMa/Ir3AQys9AAAAANRnKL3XgVQ9AAAAADuvJb1FsCY9AAAAAK8/Lb12NnQ9AAAAAHjkJ73N+Sc9AAAAAP8LMr1FsCY9AAAAAK8/Lb1UJYo9AAAAAAsYKr3qWYo9AAAAAHkXML12NnQ9AAAAAHjkJ711c3M9AAAAAENfMr3g8Wo9AAAAAH6SIr1qsYI9AAAAAIfOJL0PfIg9AAAAAFZuIr1JNYI9AAAAAEgjIL1XDJE9AAAAAPxMJr1vKpM9AAAAAK5XIr1qsYI9AAAAAIfOJL2v6Y89AAAAAFRmHr2dzlQ9AAAAACaZH71eLnM9AAAAACckHb1mBp49AAAAAKlHJ70igJ49AAAAAEo+Ir0qQZc9AAAAAJdVF73wlIg9AAAAAJSlGr2YMJw9AAAAACEvHb0igJ49AAAAAEo+Ir0d8Ek9AAAAAN4MFL18wUM9AAAAAJ0FGL248Vc9AAAAAMrnF73KzmM9AAAAABN+Fb2PuUc9AAAAAC7oG73y42I9AAAAAAgrGr18wUM9AAAAAJ0FGL0D4Xs9AAAAABiuF73KzmM9AAAAABN+Fb3y42I9AAAAAAgrGr2oKDw9AAAAAGY7Db1+yDI9AAAAAMgeE70Vwlc9AAAAAC4fEL3+VC49AAAAAOsjGL2KCHQ9AAAAALJEEr0YJi89AAAAAGoXHb0AXIg9AAAAANxpFL3wlIg9AAAAAJSlGr2KCHQ9AAAAALJEEr06tWs9AAAAACnKDL3QooE9AAAAAPX7Dr1Mu4Y9AAAAAMd4DL0zHoE9AAAAAAMrCr2ocY49AAAAADVoEL24N5A9AAAAAFZMDL3QooE9AAAAAPX7Dr1ZPY09AAAAACZQCL0zHoE9AAAAAAMrCr0Vwlc9AAAAAC4fEL1ZGVg9AAAAAMXRCb1J9HI9AAAAADUsB73ACJo9AAAAAANQEb0AXIg9AAAAANxpFL2PSZo9AAAAAMQeDL1ArZM9AAAAACh3Ab0NuYY9AAAAANWZBL2yGZg9AAAAAKEOB71J9HI9AAAAADUsB714PE89AAAAAEC6/LwUhUk9AAAAAN81Ar1LO1s9AAAAACT+Ab26zmU9AAAAAO5C/7zVu0w9AAAAAEsXBr1us2Q9AAAAAOU1BL0UhUk9AAAAAN81Ar2Wy3o9AAAAAH60Ab1us2Q9AAAAAOU1BL0xi0M9AAAAAJCj8LybAjs9AAAAABc7+7zXm1s9AAAAAMWS9bzCujY9AAAAAN93Ar2sPnQ9AAAAAAVc+bzWDTc9AAAAAJhxB71YoYY9AAAAAPRd/bwNuYY9AAAAANWZBL2sPnQ9AAAAAAVc+bxtP209AAAAAAAZ8Lws4oA9AAAAAJ3f87zkZIU9AAAAAJfz77x+hoA9AAAAAE407LwcDYw9AAAAAB+W9rzQro09AAAAAI/877ws4oA9AAAAAJ3f87zOI4s9AAAAAEWu6byXJVw9AAAAAC8467yLuHM9AAAAAMFn57zaLJY9AAAAAEl/+LwnepY9AAAAAOQU8LyXyZA9AAAAAN0b37ybdYU9AAAAAI3J47xuopQ9AAAAACQR6LwbH1Q9AAAAAC0s2bzbPU89AAAAAEUm37yqz149AAAAAEUZ37yoA2g9AAAAAH+M27yKKVI9AAAAAK4/5bwqMWc9AAAAAMCq4rxPhXo9AAAAAEAT37yoA2g9AAAAAH+M27wqMWc9AAAAAMCq4rzapkk9AAAAAF3/zrzUT0I9AAAAACSc17xD2F49AAAAAFJ707zwtj49AAAAAM8637wPknQ9AAAAAMPr1rysGz89AAAAAOoa57yLuHM9AAAAAMFn57wGUIU9AAAAAKRp2rwlO249AAAAAGLYzryUKoA9AAAAAFdK0rwZF4Q9AAAAAFjFzrxzjn89AAAAAORPy7yQAoo9AAAAAHSt1LzLYIs9AAAAAEu/zrxvFYk9AAAAAODhyLxzjn89AAAAAORPy7zLYIs9AAAAAEu/zrxD2F49AAAAAFJ707xzLF89AAAAAAFbyrwPknQ9AAAAAMPr1rwx0HM9AAAAAGXUxrxe7JI9AAAAACZN1ry3HJM9AAAAAGG7zrzO9I09AAAAADW+vrxoEIQ9AAAAACBUw7w0aZE9AAAAAEw/x7y3HJM9AAAAAGG7zrwTV1g9AAAAANuNubxY+lM9AAAAADQ3v7wtk2E9AAAAAMYZv7y/qGk9AAAAAG+wu7xlc1Y9AAAAALTgxLyo22g9AAAAAEZrwryWyHk9AAAAAFXuvryo22g9AAAAAEZrwrzYaE89AAAAAK/6r7xq2Eg9AAAAAIsuuLzywGE9AAAAAAEWtLyBjEU9AAAAADBZv7xYo3Q9AAAAAFc2t7y1x0U9AAAAADWSxrwx0HM9AAAAAGXUxrwq7IM9AAAAAP5lurxoEIQ9AAAAACBUw7xYo3Q9AAAAAFc2t7zfHG89AAAAAJOUr7zY1n49AAAAAI+7srzrzII9AAAAAClWr7x9Fn49AAAAAG8crLyT+oc9AAAAANjgtLyxHYk9AAAAAIo4r7zY1n49AAAAAI+7srxjFIc9AAAAAEuvqbyxHYk9AAAAAIo4r7zywGE9AAAAAAEWtLysFWI9AAAAAA9uq7wo6nM9AAAAAE7yp7xBvI89AAAAALVQtrwq7IM9AAAAAP5lurx30Y89AAAAABEcr7xYo3Q9AAAAAFc2t7y/NIs9AAAAAPsGoLzetoI9AAAAALZ+pLzcQ449AAAAAAUHqLwo6nM9AAAAAE7yp7x30Y89AAAAABEcr7wae1w9AAAAAHOkm7yOn1g9AAAAAOz/oLwjTWQ9AAAAACjJoLwXS2s9AAAAAJuDnby+olo9AAAAADpRprxBgmo9AAAAAN3bo7yOn1g9AAAAAOz/oLw2GHk9AAAAACtyoLxHB1U9AAAAAEe9krz7PE89AAAAAKN6mryfnGQ9AAAAAENvlrwFO0w9AAAAADI9obxku3Q9AAAAAKY4mbysFWI9AAAAAA9uq7zIP0w9AAAAAAMLqLz5lII9AAAAAOsSnLzetoI9AAAAALZ+pLxku3Q9AAAAAKY4mbwo6nM9AAAAAE7yp7ylAHA9AAAAANcZkrxYa309AAAAAOfulLwXkYE9AAAAAFKxkbw1tHw9AAAAAMC6jrzaBIY9AAAAALfRlrxw8IY9AAAAANp8kbxYa309AAAAAOfulLwCKYU9AAAAAAFVjLw1tHw9AAAAAMC6jrxw8IY9AAAAANp8kby18GQ9AAAAACxTjry2DXQ9AAAAADzrirwvpow9AAAAAKYOmLz5lII9AAAAAOsSnLwCpIw9AAAAAJdIkbzYk4g9AAAAAD9Ag7yYboE9AAAAAIyNh7wePos9AAAAANeriry2DXQ9AAAAADzrirwCpIw9AAAAAJdIkbxpfGA9AAAAAExff7zWIF09AAAAAAGxhLy99WY9AAAAAHZihLwb5Ww9AAAAALVIgbxMtl49AAAAAKueibxyI2w9AAAAABcwh7zWIF09AAAAAAGxhLyHd3g9AAAAAKjig7wb5Ww9AAAAALVIgbxyI2w9AAAAABcwh7wWbVo9AAAAAFkPb7yyZlU9AAAAAP54fby6YGc9AAAAABmUdbzlsVI9AAAAAPoHhbwV2nQ9AAAAAO9verw+iFI9AAAAAPBbi7y2DXQ9AAAAADzriryaT4E9AAAAACtwf7yYboE9AAAAAIyNh7y2DXQ9AAAAADzrirxj43A9AAAAAJlZbbxRGHw9AAAAAP5Vcrx9aIA9AAAAAL48bLxCbXs9AAAAAN3iZrzwKIQ9AAAAAKKRdbx74YQ9AAAAAM2qa7zYWoM9AAAAAI83YrxCbXs9AAAAAN3iZrx74YQ9AAAAAM2qa7z/smc9AAAAAImaZrwV2nQ9AAAAAO9very3OnQ9AAAAAPQIYLzztYk9AAAAAE2jd7yaoIk9AAAAAKsXa7yDHIY9AAAAACJoUby/PIA9AAAAAJ2QWbzEY4g9AAAAAObwXrypS2Q9AAAAAJriS7wIbWE9AAAAAMgXVbwDg2k9AAAAAHlRVLzlcG49AAAAAHWHTrysnmI9AAAAALEVXrxNuW09AAAAAMhXWbwIbWE9AAAAAMgXVbxe6Xc9AAAAAH4LU7zlcG49AAAAAHWHTrwqhV89AAAAAM40Pby8PVs9AAAAAA9oSrywAmo9AAAAAIfSQrxa2Fg9AAAAAF/yVbxG/3Q9AAAAAC7zRrz/smc9AAAAAImaZrw+iVg9AAAAAM2JYby3OnQ9AAAAAPQIYLw3IYA9AAAAAFI6S7xG/3Q9AAAAAC7zRrwOwnE9AAAAADAkO7x143o9AAAAAOBsP7zrr349AAAAAK/JObxUR3o9AAAAADcONbxjboI9AAAAANQdQrxH+YI9AAAAALkWObx1sYE9AAAAAL2YMLz2UWo9AAAAAIo+NbwJcXQ9AAAAAKgGL7xc94Y9AAAAANLIQ7w3IYA9AAAAAFI6S7yI04Y9AAAAAGxhOLxG/3Q9AAAAAC7zRrws2YM9AAAAAABZIbz8TH49AAAAAFDtKLyfwIU9AAAAABNvLbwJcXQ9AAAAAKgGL7x+2Wc9AAAAAHxWHbz+cmU9AAAAAACkJbz96ms9AAAAABK+JLyG6G89AAAAAE9xH7yLTGY9AAAAADWvLbzvPW89AAAAAI8mKbyKcHc9AAAAANJCI7zvPW89AAAAAI8mKbxyOmQ9AAAAAP9rELw7qmA9AAAAAEVCHLz1d2w9AAAAAKwfFbyflV49AAAAABChJrzbKnU9AAAAAKSFGLz2UWo9AAAAAIo+NbzyKl49AAAAAJYLMbzyHX49AAAAAKATHLyRmXI9AAAAALIcDrxo0nk9AAAAALGvEbzCyHw9AAAAAIqYDLwSSHk9AAAAAMaECLzA3IA9AAAAAITZE7xJQIE9AAAAAMfPC7xiNIA9AAAAABBfBLwSSHk9AAAAAMaECLxJQIE9AAAAAMfPC7z1d2w9AAAAAKwfFbwQw2w9AAAAADMYCbzbKnU9AAAAAKSFGLyVsHQ9AAAAAC5aA7w0doQ9AAAAADojFbwLSYQ9AAAAAEIEC7w+1IE9AAAAAHbO7bv1YXw9AAAAAAqB+7t5YIM9AAAAAJRnAbyVsHQ9AAAAAC5aA7yRFms9AAAAADZ96LuLIWk9AAAAABET97usI249AAAAAKsh9bsZRnE9AAAAANSt67uOsGk9AAAAAJGNArxnq3A9AAAAAOWo/LvZD3c9AAAAAG/u8bvVd2g9AAAAAPlr0rtblGU9AAAAAOgO57v1tW49AAAAAMYC2rvp0GM9AAAAAMo2+bu0XHU9AAAAAM1j37uCVWM9AAAAAA69Bbzp0GM9AAAAAMo2+bsJPHw9AAAAANkW5bu0XHU9AAAAAM1j37viZnM9AAAAAMKYzbvX6ng9AAAAAFlX07szJXs9AAAAAMVwyrspdXg9AAAAAIOnw7so9349AAAAAHes1rvmfX89AAAAAKTQyLvX6ng9AAAAAFlX07tc1n09AAAAABs4vLvmfX89AAAAAKTQyLu6+249AAAAALxaxbs0+XQ9AAAAADgcu7tJPoI9AAAAAMqP2LsJPHw9AAAAANkW5btpDYI9AAAAAOsrx7smGIA9AAAAAOBNpbu6wno9AAAAACwzsbseT4E9AAAAAJTftrs0+XQ9AAAAADgcu7uF8209AAAAAEY9oruOZ2w9AAAAAG2WrrscI3A9AAAAAMKfrLuug3I9AAAAAHiApLtcu2w9AAAAANVourvQ+3E9AAAAANPSsruOZ2w9AAAAAG2WrrsfynY9AAAAADtpqbtAKGw9AAAAAKUnkLtD5Gk9AAAAAM9uobslsnA9AAAAAAX7lbt3cWg9AAAAAIbBsLuylHU9AAAAAB0Fmru6+249AAAAALxaxbsS8Wc9AAAAAAI8wLt3cWg9AAAAAIbBsLsKp3o9AAAAAB1inruylHU9AAAAAB0FmrvyJnQ9AAAAAPp4i7ttMng9AAAAABPcj7v8znk9AAAAAJNwiLtC1Hc9AAAAAMgQg7vYpHw9AAAAAPZKkrt2+3w9AAAAAGHlhrvQuns9AAAAAOqEebt2+3w9AAAAAGHlhrtq8XA9AAAAAMkHhbvNSnU9AAAAACy0eLtoW4A9AAAAAG2Yk7sKp3o9AAAAAB1inrvkLIA9AAAAAKpYhbuYXn09AAAAAP6wVLufeXk9AAAAAGAfaLuzMH89AAAAAF10cLvNSnU9AAAAACy0eLsFYXA9AAAAAP/oUbvbM289AAAAAJOvZbtY33E9AAAAAEwFYrtim3M9AAAAAPLUVLuYXW89AAAAAMKdeLtAKXM9AAAAAKO1a7svonY9AAAAAMIbXLtAKXM9AAAAAKO1a7ubNm89AAAAAFMaNrsdgm09AAAAALdHUbv2YXI9AAAAAJVnPrt/Xmw9AAAAAC/Cabu10nU9AAAAAM4IRLtq8XA9AAAAAMkHhbvT5Ws9AAAAAIBcgbt/Xmw9AAAAAC/CabtEaXk9AAAAAHNPSrus1nQ9AAAAACvZLbvTrnc9AAAAAA8QNLvWz3g9AAAAAEOdKLsKa3c9AAAAAJ6/ILuq0Xo9AAAAABhjN7spCns9AAAAANcEJrs0JXo9AAAAAGEAF7uFmXI9AAAAAHeGJLu10nU9AAAAAM4IRLs4pXU9AAAAAEYGF7u5sn09AAAAAC8WObuGZ309AAAAALh0I7s5SHs9AAAAAEda+LrvkHg9AAAAAIpqCrvzj3w9AAAAAG8TELu0T3I9AAAAAN2o9rpPdXE9AAAAAK+5CbtfTnM9AAAAACCtBrtHh3Q9AAAAAADv+brvh3E9AAAAADapF7vILXQ9AAAAAJ2hDbtPdXE9AAAAAK+5CbvSmnY9AAAAAH3oAbvILXQ9AAAAAJ2hDbvQjXE9AAAAAIJ60LoNVnA9AAAAALG29rrSunM9AAAAABPj2ro7f289AAAAAIUoDbucFnY9AAAAAGrb4briG289AAAAAGK2H7sEjXg9AAAAAG0Z6rqcFnY9AAAAAGrb4boCc3U9AAAAAFUYxLq5ZXc9AAAAAKHWy7p3MXg9AAAAAGCkvLooP3c9AAAAADS8srq8jHk9AAAAABEN0Lrmunk9AAAAANQxubq5ZXc9AAAAAKHWy7qkJHk9AAAAAGZRprooP3c9AAAAADS8srrmunk9AAAAANQxubqG6XM9AAAAABxjuLpbCHY9AAAAAEKyprrkh3s9AAAAAENK0rqMXHs9AAAAAHHytboFAno9AAAAAGPBhrr+Eng9AAAAAGIKl7qX03o9AAAAAMPjnbqMXHs9AAAAAHHytbo6sHM9AAAAABmXhbq9GnM9AAAAACutlro8ZnQ9AAAAAOGekrpyQXU9AAAAAOoQh7oBK3M9AAAAAGIFqLqCA3U9AAAAAM0Sm7q9GnM9AAAAACutlrrdtnY9AAAAALzQjLqCA3U9AAAAAM0Sm7rMGHM9AAAAAGbxYro+SHI9AAAAAHovhrovsnQ9AAAAADetbLrkunE9AAAAACdnm7pKYHY9AAAAADaNc7pue3E9AAAAAMnesrqcHHg9AAAAAIPlfLpKYHY9AAAAADaNc7pbCHY9AAAAAEKyprq0+HU9AAAAAI2tVrqlXHc9AAAAAC7wXbre/Hc9AAAAABiqULq/VHc9AAAAAD03SLrt5Hg9AAAAAG8GY7oDHXk9AAAAAH6tTrqlXHc9AAAAAC7wXbpQw3g9AAAAAAJDP7q/VHc9AAAAAD03SLovsnQ9AAAAADetbLqE1nQ9AAAAAKOCTLqBcXY9AAAAAGtqPrqOTXo9AAAAACurZrqcHHg9AAAAAIPlfLqITno9AAAAAGlLTbqIhnk9AAAAAJ7NKLoBAXg9AAAAAJddM7pUCXo9AAAAANH3ObqBcXY9AAAAAGtqPrqibXQ9AAAAADHxI7pPEXQ9AAAAAH2LMLrbGHU9AAAAAKsKLroeunU9AAAAAArsJbrtNnQ9AAAAAMGLPro3oXU9AAAAAIzoNLo+7nY9AAAAAEkNK7o3oXU9AAAAAIzoNLolxnM9AAAAAM9EFbqCQnM9AAAAABmcI7puK3U9AAAAAP2sGbo0+XI9AAAAABuvM7oilnY9AAAAAGspHbqr7HI9AAAAAHdSR7o0+XI9AAAAABuvM7rzBXg9AAAAAEmnIboBAXg9AAAAAJddM7q9N3Y9AAAAAOMsE7qqZXc9AAAAADONFroP8Xc9AAAAAOzCErrlY3c9AAAAAAabD7rerng9AAAAAO5zGboZ6Hg9AAAAAOIOE7qqZXc9AAAAADONFrolpHg9AAAAAObtDbrlY3c9AAAAAAabD7oZ6Hg9AAAAAOIOE7puK3U9AAAAAP2sGbqrOXU9AAAAAP8TD7p0nnY9AAAAAMzeC7oO2nk9AAAAAO/UG7oJ7nk9AAAAALqiE7ruWXk9AAAAADTkBrof/nc9AAAAAHSPCbp/wnk9AAAAAAg8DboJ7nk9AAAAALqiE7pSsXQ9AAAAAIocAbpybXQ9AAAAAKJEBbobXHU9AAAAAF9xBboQ5nU9AAAAABgnA7oRoHQ9AAAAAOgNCror33U9AAAAAO0vCLpybXQ9AAAAAKJEBbpnBHc9AAAAACH5BboQ5nU9AAAAABgnA7or33U9AAAAAO0vCLpQAnQ9AAAAAFEP9LkonHM9AAAAAMxd/7mrUnU9AAAAAOAI+7nnb3M9AAAAAKQtBbr3pXY9AAAAAKZTALqrOXU9AAAAAP8TD7rdfnM9AAAAAG3DC7rnb3M9AAAAAKQtBbrU+3c9AAAAAMEwA7r3pXY9AAAAAKZTALp0nnY9AAAAAMzeC7pXRHY9AAAAAIKb9bmOX3c9AAAAALMN+7mB3nc9AAAAAKzG9rkXWXc9AAAAABvJ8bmhkng9AAAAAPQw/7nqxHg9AAAAAJF497mOX3c9AAAAALMN+7lag3g9AAAAACGE77mrUnU9AAAAAOAI+7kKVXU9AAAAABjv7rlhn3Y9AAAAACJM67nUp3k9AAAAAOUdAbrU+3c9AAAAAMEwA7pquXk9AAAAALo6+LlTK3k9AAAAAIW/4rkE53c9AAAAABC457kDj3k9AAAAAPw27rlquXk9AAAAALo6+LkU03Q9AAAAAHF62Llvk3Q9AAAAABuu37nHcXU9AAAAAFs14Lmk8nU9AAAAAAUm3LmRw3Q9AAAAAJVD57kl7HU9AAAAAH/w5LmR/XY9AAAAACw44bmk8nU9AAAAAAUm3LnKMXQ9AAAAAC6Oy7kZ0XM9AAAAAF7n1bn1aXU9AAAAAOjW0bl5p3M9AAAAAA4k37m0pXY9AAAAAPjh1rkKVXU9AAAAABjv7rm/t3M9AAAAAJKv6Llhn3Y9AAAAACJM67k+5Hc9AAAAACYJ3LkE53c9AAAAABC457m0pXY9AAAAAPjh1rmHSnY9AAAAAO24zLkDUnc9AAAAAI2g0blfx3c9AAAAAJyfzbn+Snc9AAAAAN0TybnTb3g9AAAAAGlS1blSnXg9AAAAAGQrzrkDUnc9AAAAAI2g0blDX3g9AAAAAJLcxrn+Snc9AAAAAN0Tybn1aXU9AAAAAOjW0bl6bHU9AAAAAGCtxrmBnnY9AAAAAKsuw7nzcXk9AAAAAJkF2Lk+5Hc9AAAAACYJ3LlbgHk9AAAAAE/FzrnJ+Hg9AAAAAH4Mu7mjzXc9AAAAACbAv7kOV3k9AAAAAOqNxbkw93Q9AAAAAGMdsrlKu3Q9AAAAAIK+uLmIiHU9AAAAAE4gubn4/3U9AAAAAJBYtbmQ5nQ9AAAAALGvv7kG+XU9AAAAAD5qvbnn9XY9AAAAACHhubkG+XU9AAAAAD5qvbmsZHQ9AAAAAK9gprnECXQ9AAAAAArhr7nYgnU9AAAAANn4q7l34XM9AAAAAGFcuLk8pXY9AAAAAKxxsLl6bHU9AAAAAGCtxrmY7nM9AAAAAF8ewbmBnnY9AAAAAKsuw7mfync9AAAAANsGtbmjzXc9AAAAACbAv7mBnnY9AAAAAKsuw7kDUXY9AAAAAO0xp7lAQ3c9AAAAAGWPq7ldrnc9AAAAAMPZp7m4O3c9AAAAAH7Bo7krSng9AAAAAJDRrrmgcng9AAAAAJlCqLlnOHg9AAAAAH+eobm4O3c9AAAAAH7Bo7l/hXU9AAAAAErIobk8pXY9AAAAAKxxsLl4nXY9AAAAAO11nrm9N3k9AAAAACMvsbmfync9AAAAANsGtbnhQnk9AAAAAKK3qLk8pXY9AAAAAKxxsLmewng9AAAAANLPlrlasnc9AAAAACM1m7nsGnk9AAAAAMZToLl4nXY9AAAAAO11nrnhQnk9AAAAAKK3qLmRHXU9AAAAANIqj7m/5XQ9AAAAACEzlbm5oHU9AAAAAOtylbkNDnY9AAAAAPL3kbnsC3U9AAAAAH97m7muBnY9AAAAAFZKmbm/5XQ9AAAAACEzlbmR7XY9AAAAANv3lbkNDnY9AAAAAPL3kbmsmnQ9AAAAAEGkhLkVRnQ9AAAAAItCjbk1nXU9AAAAAOiMiblTH3Q9AAAAAEv1lLmPpHY9AAAAAF91jbk7KXQ9AAAAAG3nnLkYr3c9AAAAAFx6kbmPpHY9AAAAAF91jbl4nXY9AAAAAO11nrnIV3Y9AAAAAEIlhbliM3c9AAAAAJj5iLmhk3c9AAAAANCUhblhK3c9AAAAAGbxgbniIXg9AAAAAH3Oi7kORXg9AAAAAGXehbliM3c9AAAAAJj5iLkDD3g9AAAAAPrTf7lhK3c9AAAAAGbxgbkORXg9AAAAAGXehbn7n3U9AAAAAA9egLlFnHY9AAAAAL+BermI+Xg9AAAAABvZjblWAXk9AAAAAHgyhrkYiXg9AAAAAAhUbLlKlXc9AAAAAHttdLnx2ng9AAAAAIhSfblFnHY9AAAAAL+BerkDRnU9AAAAAC+BX7mbEnU9AAAAAGZTark5unU9AAAAANyWarnNHHY9AAAAAG5FZLl0M3U9AAAAALGJdbkOFXY9AAAAAKpecbmd5HY9AAAAAA83a7nNHHY9AAAAAG5FZLkOFXY9AAAAAKpecbmE03Q9AAAAAK3sTLm5hXQ9AAAAADJSXLnnuHU9AAAAAJFiVbm2YHQ9AAAAAPMXarmwo3Y9AAAAABIYXLlXZ3Q9AAAAAPRPeLm2YHQ9AAAAAPMXarnUkXc9AAAAAL4GY7lKlXc9AAAAAHttdLmwo3Y9AAAAABIYXLnMXnY9AAAAAFtjTbl8Inc9AAAAABr9U7lLd3c9AAAAAOjgTbkNGnc9AAAAAO6FR7ku93c9AAAAAITSWLncFHg9AAAAAAQ+Trl8Inc9AAAAABr9U7lS43c9AAAAAEG+Q7kNGnc9AAAAAO6FR7nJu3U9AAAAAL4ZRbntmnY9AAAAAPVcP7mmt3g9AAAAAGpIXLkTvHg9AAAAAC6tTrmNTHg9AAAAACd3Mrmhdnc9AAAAAGXJObl1l3g9AAAAAC5eQbkTvHg9AAAAAC6tTrlWcHU9AAAAAB35J7mdQXU9AAAAAOd/Mbno1HU9AAAAADOQMbkqLHY9AAAAAM/uK7nwXHU9AAAAADlTO7kSJHY9AAAAAIpvN7mdQXU9AAAAAOd/MbkW23Y9AAAAAKbWMbnrDnU9AAAAALzoF7lfyHQ9AAAAAOBjJbnN1XU9AAAAAFsIH7lSpXQ9AAAAACl7MbmhonY9AAAAAEOpJLmdqHQ9AAAAAH/6Pbn4cnc9AAAAAEiDKrkMZnY9AAAAAOLrF7mnEHc9AAAAAFB7HbmFWXc9AAAAAMQYGLnTB3c9AAAAACyrErlLync9AAAAAO2DIblK4nc9AAAAAEVJGLmnEHc9AAAAAFB7HbmGtXc9AAAAAPo7D7lK4nc9AAAAAEVJGLnF2HU9AAAAAOblELmhonY9AAAAAEOpJLlwmXY9AAAAAGy7C7lzcng9AAAAAE1iJLn4cnc9AAAAAEiDKrluc3g9AAAAAISJGLk/DXg9AAAAAABKALmGVnc9AAAAAHq9BrnLUHg9AAAAAOYLDblwmXY9AAAAAGy7C7lVnHU9AAAAAFPy77iVcnU9AAAAADcnALmj8HU9AAAAAFkOALkNPHY9AAAAAEVS9rgyiHU9AAAAAEiPCLmqM3Y9AAAAAGgEBbkJ0XY9AAAAANwMALmdTHU9AAAAAB7v1Li0DXU9AAAAADzp67jE83U9AAAAAD2P4LjN7HQ9AAAAAIxOALlooXY9AAAAAIO46bjF2HU9AAAAAOblELm47HQ9AAAAAPcIC7lwmXY9AAAAAGy7C7mtUnc9AAAAAJpT87iGVnc9AAAAAHq9Brl4bXY9AAAAADFD1Lj5/XY9AAAAADtZ3bhvOnc9AAAAABsh1LjL9HY9AAAAAJwiy7hsm3c9AAAAALzi47iVrXc9AAAAAP091Lj5/XY9AAAAADtZ3bjXhXc9AAAAAJsaxbjE83U9AAAAAD2P4LjT9nU9AAAAAPW5yLjPl3Y9AAAAACu2v7g9Kng9AAAAAIOC6LjFJ3g9AAAAAPx21LiAy3c9AAAAACkbrLgZNXc9AAAAAGASt7hLB3g9AAAAACw6wbjPl3Y9AAAAACu2v7jFJ3g9AAAAAPx21LjOyXU9AAAAABJ6n7hBpXU9AAAAAJAJrbhODXY9AAAAAJ2brLhqTHY9AAAAAABjpLgEtXU9AAAAACnzurjCQ3Y9AAAAAKy0tLiFxnY9AAAAAB8wrLhqTHY9AAAAAABjpLjCQ3Y9AAAAAKy0tLhRjHU9AAAAAA+oibhrVXU9AAAAAMB9nLiqEnY9AAAAAIC5krjYNnU9AAAAAO6YrbgCoHY9AAAAAPvdmbhaM3U9AAAAAKNrv7gaMXc9AAAAAH1zobgZNXc9AAAAAGASt7gCoHY9AAAAAPvdmbgOdXY9AAAAAAWEiLiH6nY9AAAAAJCfj7g0Gnc9AAAAAFEPiLgN4XY9AAAAADrugLjKanc9AAAAAP+1lLj7dnc9AAAAADr/h7iDVHc9AAAAAKnJd7jLFXY9AAAAAJztfrgSlnY9AAAAAILnb7hg33c9AAAAAGJNmLhs2Xc9AAAAAE8JiLibh3c9AAAAAI8LULiHEnc9AAAAAPyvYbhLu3c9AAAAAJ5McbiO+HU9AAAAAL0BPrhv2XU9AAAAAC5QU7jHKnY9AAAAAEUsUrgrXXY9AAAAAPgTRbg143U9AAAAAFQ3abhLVHY9AAAAALa5XriUu3Y9AAAAAHnaULhLVHY9AAAAALa5XrjDzXU9AAAAAAjkHLgzn3U9AAAAAIf0ObheMnY9AAAAAKwQKrgcg3U9AAAAAPC8VLh1nnY9AAAAAJx9NLgyfHU9AAAAACnucLhlDnc9AAAAAFjKP7iHEnc9AAAAAPyvYbh1nnY9AAAAAJx9NLgSlnY9AAAAAILnb7jFfHY9AAAAAIgqGrhp1nY9AAAAAGOOJLj1+HY9AAAAAM31GLipzHY9AAAAAIhtDrigOHc9AAAAAPMDLLi4Pnc9AAAAADSuGLhp1nY9AAAAAGOOJLi5IXc9AAAAANytBripzHY9AAAAAIhtDri4Pnc9AAAAADSuGLiONXY9AAAAAFH2DLg4lHY9AAAAAPJWAbgxknc9AAAAAAxQMbhlDnc9AAAAAFjKP7jBiHc9AAAAACeaGLjbQXc9AAAAAHZX07f37nY9AAAAAOcq7bcfbXc9AAAAAAW+Abg4lHY9AAAAAPJWAbhgKHY9AAAAAKf4u7ffDnY9AAAAAK6D2rfsSHY9AAAAABQV2LdCbnY9AAAAAKkFxbeNEnY9AAAAAAI++rcvZXY9AAAAADvu6bdDsHY9AAAAADM31bdCbnY9AAAAAKkFxbcvZXY9AAAAADvu6bemEHY9AAAAAP8Kj7e56nU9AAAAAMhOt7e8UnY9AAAAAEHSn7dE0XU9AAAAAI2J3be+nHY9AAAAAHdbrbfvxnU9AAAAAFtSA7g4lHY9AAAAAPJWAbi06nY9AAAAAFCevLe+nHY9AAAAAHdbrbeShHY9AAAAAMDHibe2wXY9AAAAAMs2l7fV1nY9AAAAAIeKh7e+t3Y9AAAAAF7Oc7chBXc9AAAAAPMbobcMBXc9AAAAAOsZh7e47XY9AAAAANmJX7e+t3Y9AAAAAF7Oc7f2VXY9AAAAAL7+cbc/knY9AAAAAKDJUrcAQ3c9AAAAAP9UqLe06nY9AAAAAFCevLcVNnc9AAAAAIAVh7eL+nY9AAAAAFhrGLeNynY9AAAAAAJMN7cdHXc9AAAAALM4U7c/knY9AAAAAKDJUrcTWXY9AAAAAOmV/rZdRXY9AAAAAI1XI7ehZ3Y9AAAAAA4QH7eZf3Y9AAAAALMbCLfhQnY9AAAAAMAwSrdhdnY9AAAAAI5XNLegpHY9AAAAAFd0GreZf3Y9AAAAALMbCLe5VHY9AAAAACYAobatN3Y9AAAAAPnv97alc3Y9AAAAADJwv7b+IHY9AAAAANTKKLfomnY9AAAAAIQg2rb2VXY9AAAAAL7+cbc/E3Y9AAAAABK3W7czxnY9AAAAABea+7aJjHY9AAAAADNGkbaSrHY9AAAAAKoDq7ZXtHY9AAAAAH4qjLYSo3Y9AAAAAH/yZbag0HY9AAAAAMpKwLbvynY9AAAAAHuMjLaSrHY9AAAAAKoDq7b1unY9AAAAALRkRLYSo3Y9AAAAAH/yZbbvynY9AAAAAHuMjLYLd3Y9AAAAAFmSZ7ZgkXY9AAAAAAj+LbZT8nY9AAAAAA1q0bYzxnY9AAAAABea+7Yb43Y9AAAAAK+2jrYGvnY9AAAAAK32tLWcqXY9AAAAAGp9ArYe0HY9AAAAACbsM7ZgkXY9AAAAAAj+LbYb43Y9AAAAAK+2jrYwjnY9AAAAAKHaXrXRfXY9AAAAABdV1bXUiHY9AAAAAOqiwbUHlnY9AAAAAP69gbVEdHY9AAAAAGUVJrZUiXY9AAAAAAHO/bXRfXY9AAAAABdV1bW/nXY9AAAAALOgsLUHlnY9AAAAAP69gbVUiXY9AAAAAAHO/bVtn3Y9AAAAANv2KDTihnY9AAAAABjLWrVQn3Y9AAAAACoVlLRAcnY9AAAAAM6Y8LUupXY9AAAAAJqICLULd3Y9AAAAAFmSZ7bfYHY9AAAAANrNSbYXrnY9AAAAAC75WLWcqXY9AAAAAGp9ArYYq3Y9AAAAAE2mnLNAr3Y9AAAAAJX3gLTss3Y9AAAAAFmHF7S1snY9AAAAAFvmY7MVtnY9AAAAAM8i5LSnuHY9AAAAALGNWLRAr3Y9AAAAAJX3gLSBuHY9AAAAAP3kyLOnuHY9AAAAALGNWLRQqnY9AAAAAMiXdjMupXY9AAAAAJqICLXVsXY9AAAAACkrpTEdvnY9AAAAAFHOIrUXrnY9AAAAAC75WLWsvXY9AAAAAEpcl7Tzu3Y9AAAAADtH27Owt3Y9AAAAACfIXrPSvHY9AAAAAB/DHLTVsXY9AAAAACkrpTGsvXY9AAAAAEpcl7RyrXY9AAAAAIkpqTOUsnY9AAAAAPjyvzLss3Y9AAAAAB1LpjLesXY9AAAAAAhcUTN5t3Y9AAAAAKMXDLNNt3Y9AAAAACULkbKUsnY9AAAAAPjyvzJRtnY9AAAAAFpX3zHesXY9AAAAAAhcUTNNt3Y9AAAAACULkbJQqnY9AAAAAMiXdjMlqnY9AAAAAKiZBDROsHY9AAAAAPu/ozNou3Y9AAAAAPbHqLPgunY9AAAAAB8kc7MruXY9AAAAAPLFFLJUtXY9AAAAAL0d/zIHunY9AAAAALeXCrMFrHY9AAAAADu0CDSjsHY9AAAAANASuTPCsXY9AAAAAGArtjPir3Y9AAAAAMPA5TMLtXY9AAAAAGZPQjPUtHY9AAAAAJIWezOjsHY9AAAAANASuTPis3Y9AAAAAGzApTPir3Y9AAAAAMPA5TPsqHY9AAAAAH/xKTROsHY9AAAAAPu/ozNprnY9AAAAAFOrCTQruXY9AAAAAPLFFLKbuHY9AAAAAOUOOzJUtXY9AAAAAL0d/zIOuHY9AAAAAJ/N+TJgtnY9AAAAAMzRkTPtsnY9AAAAABCIzTM5t3Y9AAAAABHCUTMOuHY9AAAAAJ/N+TJ9qnY9AAAAAGIfMTSkrnY9AAAAALN3EzScr3Y9AAAAANIVFDTjrXY9AAAAABdfJTSZsnY9AAAAAJIy6TNZsnY9AAAAACJeADSkrnY9AAAAALN3EzRwsXY9AAAAAKUVEDTsqHY9AAAAAH/xKTSsp3Y9AAAAABt2RzSDrHY9AAAAAFRlNjTOtXY9AAAAAMYCtDM7tXY9AAAAAEqn0zOVs3Y9AAAAAGLMCjSDsHY9AAAAAPWSHzRotHY9AAAAAH9R9TM7tXY9AAAAAEqn0zP3qHY9AAAAACweUTSnrHY9AAAAAEooPzRzrXY9AAAAABswQTTkq3Y9AAAAAEEeTTQpsHY9AAAAAObCKjTcr3Y9AAAAAI1ENDSnrHY9AAAAAEooPzT9rnY9AAAAAAQxQDTcr3Y9AAAAAI1ENDRspnY9AAAAALKAXjSDrHY9AAAAAFRlNjSdqnY9AAAAAM9IWTT+snY9AAAAAA1gGDRpsnY9AAAAAO/ZJDTJsHY9AAAAAEwuPjQbrnY9AAAAAKbgSzSasXY9AAAAAHHVMTSdqnY9AAAAAM9IWTRvp3Y9AAAAAE2uaTSoqnY9AAAAAErmYDRKq3Y9AAAAAOnKYzTjqXY9AAAAAAdpazS0rXY9AAAAAKimVDRhrXY9AAAAAGUVXDSKrHY9AAAAAFPIZDRspnY9AAAAALKAXjQtpXY9AAAAAIDgbzS3qHY9AAAAAJaQczTJsHY9AAAAAEwuPjQtsHY9AAAAAJmfSDSUr3Y9AAAAALQhUjT9rXY9AAAAANHeZDSwq3Y9AAAAAEM9bTTJrnY9AAAAAEHJWzS3qHY9AAAAAJaQczTnpXY9AAAAAHXNezSpqHY9AAAAANr8eTQgqXY9AAAAAIpMfTTlp3Y9AAAAAETFgDRBq3Y9AAAAAJHaczTiqnY9AAAAAB1teTSpqHY9AAAAANr8eTQWqnY9AAAAAI9xfzTlp3Y9AAAAAETFgDQtpXY9AAAAAIDgbzTuo3Y9AAAAAMxkfDTPpnY9AAAAAL07gzRcrXY9AAAAAK+SbDSwq3Y9AAAAAEM9bTS/rHY9AAAAABWAczQwq3Y9AAAAABVXgDRGqXY9AAAAAHqcgjT5q3Y9AAAAANxWejTPpnY9AAAAAL07gzRhpHY9AAAAAKg8hDSppnY9AAAAAIvbhTT4pnY9AAAAAKuNhzTnpXY9AAAAAPJmiDTQqHY9AAAAAE/6hDRnqHY9AAAAABn0hjSppnY9AAAAAIvbhTSlp3Y9AAAAAFvhiDRnqHY9AAAAABn0hjSvonY9AAAAAGpugjTqpHY9AAAAACSciTQwq3Y9AAAAABVXgDSMqnY9AAAAAP0FgzTrqXY9AAAAAB1lhTRkqHY9AAAAAEK2iTTdpnY9AAAAAO6xijQoqXY9AAAAAHaohzTrqXY9AAAAAB1lhTTXonY9AAAAAMpXiDSqpHY9AAAAABOwizTQpHY9AAAAANJOjTTlo3Y9AAAAAB4/jTRepnY9AAAAAGdFjDTrpXY9AAAAAJKRjTQzpXY9AAAAAOaojjTlo3Y9AAAAAB4/jTTrpXY9AAAAAJKRjTSvonY9AAAAAGpugjRsoXY9AAAAAOwLhTTqpHY9AAAAACSciTQFo3Y9AAAAAOyGjTRkqHY9AAAAAEK2iTS8p3Y9AAAAABJvizQWp3Y9AAAAAKHqjDSWpXY9AAAAAAt1jzR0pHY9AAAAABSnjzRYpnY9AAAAAA1FjjRQoXY9AAAAAPO2ijStonY9AAAAAJUhjzSnonY9AAAAAOGckDTpoXY9AAAAAFzzjzTto3Y9AAAAAJKZkDRvo3Y9AAAAADVdkTStonY9AAAAAJUhjzTBonY9AAAAAGTakTTpoXY9AAAAAFzzjzRvo3Y9AAAAADVdkTRsoXY9AAAAAOwLhTQroHY9AAAAAMD1hTQioXY9AAAAAG2ZjzTtpHY9AAAAAPBtkDR0pHY9AAAAABSnjzREpHY9AAAAACg7kTTOonY9AAAAAId7kjQNonY9AAAAAP5DkjSLo3Y9AAAAAIvqkTQioXY9AAAAAG2ZjzS9n3Y9AAAAAGnGiTSyoHY9AAAAAETVkDSKoHY9AAAAAIspkjT2n3Y9AAAAALEskDR9oXY9AAAAAHbBkjT+oHY9AAAAAMMikzSyoHY9AAAAAETVkDRyoHY9AAAAAO0ZkzTrnXY9AAAAAMWNXzQSn3Y9AAAAAEGgiDQgonY9AAAAAIDrkjQNonY9AAAAAP5DkjR+oXY9AAAAAA4+kzRtoHY9AAAAAEyYkzTzn3Y9AAAAAI9HkjTioHY9AAAAALd3kzR+oXY9AAAAAA4+kzTcP509Lh8pPMKfnL3O4pw9lR4pPAmEm72eeZ09bEcvPCaFm71F1J09M0wvPN2enL1kf5w9Th0pPBtsmr0kK509Lz0vPJlsmr3/EZ891IwvPJOJm731Zp89kZovPKGcnL3uAJ89fWwvPNtwmr3qfp09KpwZPOG/nb2qKp09K5wZPOGfnL2clJ09RB8pPES/nb1BzZw9KpwZPN6Dm73eZpw9K5wZPApsmr2r95s9KpwZPIlYmb1REpw9iRwpPFFYmb3TzJw9CjcvPMRWmb3Q3J49G1IvPHBSmb0Y9aM917ksPAhImb0Wm6I9XTotPJ+Nmr07KKI95W8tPD2Zm72DdqI9BIMtPCaZnL2SyJ89iZwvPEKvnb0i66I9vIUtPHeYnb1yLJ494UwvPPS6nb3Zu589pFA2PP+p7L0Mjp09UlE2PBLQ7b3knJw9RSszPKXY7b0hoZ49zyUzPA207L0hUJs9pVA2PIHk7r39YJo9ziUzPD3t7r35EZo9S/ovPNbv7b3inZs9r+cvPFvR7L2W0pc9r+cvPE0D770jDaI9pOY4PMlw67075J89peY4PI+o7L1x36E99E82PGhy672AsJ09peY4PNjO7b1Kcps9peY4PELj7r39KZk9pOY4PHDl772MB5k99E82PLrm7711Fpg9WSAzPLrv773Ea5U9Rc8vPAsJ8L3k044917ksPFdG8L0jzpI9oTctPGMh773QMJU9DVotPHYc7r12wZU9ojctPG8Y7b0BFp09Rc8vPOad670QV5Q91rksPAvs672en6A9WSAzPM59671AqnM9Th0pPPWQg70HKXE9lR4pPCqhg70Otm89a0cvPG2Yg73A1XI9Lz0vPMCDg70ztW49Lh8pPCi7g72X62w9M0wvPMOzg71vnWs91YwvPIiBg730O3A9fGwvPBdhg71LDGg9kZovPM2fg73HNHY9KpwZPKKNg72dyHM9K5wZPNmSg70FM3Y9iRwpPBeLg70FXnE9KpwZPGiig72S9m49K5wZPDa8g73Uk2w9KpwZPCLgg72CT2w9RB8pPAPfg709cWo94UwvPDLXg70VX2U9iZwvPPfBg70Xf1s9vIUtPJuYg70EdV49BIMtPG15g7210GI95W8tPA1Zg70f5Wg9XDotPN8mg73QA3Y9G1IvPPpGg72VrXU91rksPFnLgr2yJnY9CzcvPEh5g73DajM9OB0pPNNqmr3yoTI95h0pPE6Dm71FZDE99kEvPPN+m71cETI9fzwvPPlhmr1+4zE9OB0pPM2fnL1WjDA9fzwvPOqenL0DCy49IX0vPEtzm73tYC49hWovPMdMmr035Cw9hWovPLeZnL18ejQ9KpwZPJZYmb0anDM9K5wZPBdsmr02RTQ9iRwpPMZWmb1TzzI9KpwZPOyDm72EFDI9K5wZPO6fnL0BbDE9KpwZPO6/nb1QNzE9iRwpPCzAnb11xi89CjcvPN3Bnb1Esis9G1IvPKzGnb30niE917ksPNXSnb3YyCU9oTctPHl7nL0Inyc9DVotPGxdm70NJSc9ojctPKM4mr2hsC49G1IvPCwmmb3PgCQ91rksPLvNmL1N0DI9CzcvPBRKmb2JPHQ9pFA2PHUGDLnqVHQ9UlE2PG98ALkHZnQ9RSszPHt3ALkFUHQ9zyUzPA0CDLnrbXQ9pVA2PNnX6riAf3Q9ziUzPKDI6rg2lHQ9S/ovPOJpALkvhXQ9r+cvPFjhC7mUr3Q9r+cvPJjH6rhEIXQ9pOY4PPUJGLnAOXQ9peY4PBgHDLlcJHQ99E82PF8JGLl3UnQ9peY4PCZ9ALloa3Q9peY4PATa6riMhHQ9pOY4PCiv1bgoh3Q99E82PFas1bhkmXQ9WSAzPJqY1bgDzXQ9Rc8vPOti1bieTHU917ksPGDv1Li2DXU9oTctPHvp67jN7HQ9DVotPKxOALm37HQ9ojctPBcJC7lXd3Q9Rc8vPK/6F7nsDnU91rksPNzoF7kFOnQ9WSAzPEQFGLlN7lQ9pFA2PEkSM7yVx1Y9UlE2PPTAJ7z0qFc9RSszPKygJ7wa9FU9zyUzPBnwMrwjm1g9pVA2PHnCHLxhflk9ziUzPOqdHLzkCFo9S/ovPGJJJ7wtvlg9r+cvPHZ+MryA61s9r+cvPAVOHLzA31I9pOY4PJa6PrzoyFQ9peY4PCsXM7zrCVM99E82PGi1Prxip1Y9peY4PJDFJ7ytelg9peY4PLLHHLw8Qlo9pOY4PIAfErx8Y1o99E82PLgZErw6TFs9WSAzPDrxEbwO3109Rc8vPFx/EbxzOmQ917ksPAJsELw7qmA9oTctPEdCHLyelV49DVotPBChJrzxKl49ojctPJULMby1dFc9Rc8vPDcrPrwrhV891rksPNE0PbwVMVQ9WSAzPCmRPrz3/ng9pFA2PDZ3DLk8GHk9UlE2PNTUGLmpBXk9RSszPHTMGLnJ63g9zyUzPP5uDLnNMHk9pVA2PCqwJbnDG3k9ziUzPJOkJbmN03g9S/ovPL21GLlet3g9r+cvPIRuDLlW4ng9r+cvPM5uJblI6Hg9pOY4PPSZALm3AXk9peY4PGN4DLlv5Xg99E82PL+YALniGnk9peY4PAjWGLnPM3k9peY4PNSxJbl4THk9pOY4PL0KM7klSXk99E82PKgIM7nPMXk9WSAzPBX6MrnG73g9Rc8vPPDRMrmOTHg917ksPEh3Mrlzcng9oTctPG1iJLluc3g9DVotPKKJGLnMUHg9ojctPAUMDbn0mHg9Rc8vPId5ALk/DXg91rksPCFKALl40Xg9WSAzPE2QALmZ4ZE9RB8pPPq0wr3gvpI9RB8pPK/3wb2zapM94UwvPMXowb1Zl5I94kwvPKaiwr3Ul5M9RB8pPFIzwb0DR5Q94kwvPMMmwb0UPZU9iZwvPEzAwb2phJQ9h5wvPOFwwr2DIpY9iJwvPK4Ewb3h4pA9KpwZPEluw72ix5E9K5wZPJi3wr04/pA9RB8pPD1rw71VppI9KpwZPND5wb3MfpM9K5wZPB41wb3dUJQ9KpwZPKxpwL1tapQ9RB8pPC5owL1kHZU94UwvPMNdwL0kA5c9iZwvPIBBwL0VtZo9vIUtPHAKwL2CwJk9wIUtPE3CwL1JyZg9vYUtPHxxwb1WRZg9v4UtPPwPwr0vxZM9iZwvPNobw73yuJc9vIUtPN+qwr2jvZE94UwvPNxVw71kTIo9pFA2PFWwK7yhNIs9UlE2PEOVN7wxtoo9RSszPE+sN7xPzIk9zyUzPNPJK7xfH4w9pVA2PP3QQ7wrjYs9ziUzPEDoQ7weYYk9S/ovPHzqN7wjbog9r+cvPKMkLLxv/ok9r+cvPI8SRLyCfIk9pOY4PDsgILyxXoo9peY4PK6sK7y1aYk99E82PDAkILyyRos9peY4PPeRN7xBNIw9peY4PKzNQ7weJ409pOY4PGVdULyjD4099E82PMRgULxMa4w9WSAzPFR4ULwHmoo9Rc8vPMq7ULyEHIY917ksPCNoUbxd94Y9oTctPNLIQ7yI04Y9DVotPG5hOLyewIU9ojctPBNvLbyIcYc9Rc8vPAiPILwt2YM91rksPAJZIbwZ5og9WSAzPN4/ILybcEg9k082PJB68r0Xq0M981A2POyw8b1KQ0U9TigzPDys8b0Y8kk9SB0zPJ548r0/AD89mVA2PAXU8L0t7EA9cCUzPC3N8L0ylEk9wvEvPOye8b2sHE49Qc0vPFxw8r1+KkY9neYvPBC88L2NE009pOY4PGIw872KOUg9peY4PNl68r0GSE09eE42PHUw873EcEM9peY4PJix8b34uT49peY4PP/U8L3jFTo9pOY4PG3l7707Zjo99E82PEnk772fmDw9WSAzPFnc770S0UI9Rc8vPLXF770BMlI917ksPHSM770TYFA9JTYtPICm8L007FE9Lk4tPCaC8b02gFY94w0tPEVL8r3821I9hqUvPGcy873qb149uzosPD81871Zt049ehQzPAEx872JsX09Lh8pPBi5g72sPXs9lR4pPIWfg72NnHw9bEcvPEOLg704Z389M0wvPDujg70NvHg9Th0pPA2Qg73SeXk9Lz0vPHZ8g71mP4A91IwvPNdTg703CII9kZovPNRng71v1Xs9fWwvPNJFg73E1X89KpwZPCXgg70Ec309K5wZPDe8g72UC4A9RB8pPNXcg72MC3s9KpwZPGmig73xoHg9K5wZPNmSg71oWYE9XTotPFLTgr08cYQ95W8tPK7lgr1Bn4Y9BIMtPN/zgr2oXYM9iZwvPLeGg71fF4g9vIUtPCcMg71y8IA94UwvPKXFg72Mgkw9Lh8pPKo1xL2XNU49lR4pPKXKxL1Ftkw9bUcvPK60xL04Eks9M0wvPLEexL02CVA9Th0pPEtkxb3uUE49Lz0vPHVQxb2Sp0g91IwvPIt3xL2sKkc9kZovPCrgw73Emkk9fGwvPOYWxb2qNks9KpwZPNGuw70st0w9K5wZPPE4xL39Aks9RB8pPJmrw71ZbE49KpwZPMnNxL0dSFA9K5wZPCBnxb1cPFI9KpwZPL3+xb3791E9iRwpPIH8xb1UGVA9CjcvPNbsxb01zko9G1IvPG3Axb3euT0917ksPBlSxb0iT0A9XDotPEyPxL21yUA95W8tPMj4w71LkT89BIMtPG9lw71gw0U9iZwvPL9Xw71WSz49vIUtPGrgwr0/mUk94UwvPASVw70dqLk8k082PAUJoL1/Wbo881A2PNcqnr3w0rw8TigzPHYrnr0qXLw8SB0zPD4KoL0nPLs8mVA2PCtHnL0G6L08cCUzPKFJnL2efcM8wvEvPOornr3VxcM8Qc0vPMAIoL1sMcU8neYvPKFSnL0/rbg8pOY4PA7hob1CRbk8peY4PNgIoL39F7k8eE42PH3hob0B/7k8peY4PMIqnr132ro8peY4PNBGnL2h17s8pOY4PApdmr32QLw89E82PMldmr1OIr88WSAzPA5jmr09Ssc8Rc8vPOpxmr2wdNs817ksPEGWmr31WdM8JTYtPJB1nL0IOdA8Lk4tPIwmnr3XONI84w0tPPfhn73+b8Q8hqUvPPnsob3O89s8uzosPHUDor0kA7w8ehQzPHjkob04upY9ulA2PBvW8L2LZJQ9AVI2PFyy8b1fvJM9ujAzPJ638b0J6pU9fiYzPL/d8L0+ApI9m1I2PER78r2faJE9gTUzPCB+8r039pE9/wkwPH/G8b1pspM9pukvPAj08L3zx489uxcwPPCF8r3115Y9peY4PAPV8L2QfJQ9peY4PJux8b0wGJI9peY4PNx68r0wq489pOY4PGUw873PlY89r1I2PH0w870qAI89MDYzPCQx8739aY09sxkwPOgy870CU4o9vIUtPFk28738nYw9BIMtPImV8r14jY495W8tPIDm8b21Y489XDotPP4p8b1z3HM9pFA2PHrfPrna83M9UlE2PPt2MbnXB3Q9RSszPKh3MbkF83M9zyUzPKPhPrn4C3Q9pVA2PJOEJLm4IHQ9ziUzPJ2CJLnPPXQ9S/ovPEV5MbmcMHQ9r+cvPHfPPrlqWXQ9r+cvPP2UJLm3wXM9pOY4PMu8TLk72XM9peY4PCrfPrlIxXM99E82PEa9TLn98HM9peY4POJ2MbkDCXQ9peY4PNyEJLleyHQ9oTctPABkJblRpXQ9DVotPEd7MbmcqHQ9ojctPJ36PbnjJHQ9Rc8vPP/KTLmE03Q91rksPMzsTLk83nM9WSAzPJbATLltjoM9Th0pPKOEhL0vY4I9lR4pPNhChL2lO4M9a0cvPP8thL27gIQ9Lz0vPF9yhL1uOIE9Lh8pPNIKhL3cEoI9M0wvPCT0g72ehIU91YwvPDf0g70NFYc9fGwvPNM9hL1qY4Q9kZovPGq2g721j4Q9KpwZPCnShL3Pa4M9K5wZPD+HhL35tIQ9iRwpPCvQhL1DRII9KpwZPNNFhL06GYE9K5wZPBAOhL2344g9BIMtPHY9g73a6ok95W8tPKB9g73IEow9XDotPOnEg71znIg9G1IvPNeahL2SvY891rksPCM6hL3auYU9CzcvPDnChL3WF009pFA2PFZ4Y7zCF089UlE2PDHrVrxIMVA9RSszPEfPVrwAXE49zyUzPGlbY7xdFVE9pVA2PEqpSrzHM1I9ziUzPACJSrzJKFM9S/ovPNeDVrxd0FE9r+cvPNT1YrydQlU9r+cvPCBHSrzy2ko9pOY4PN9TcLyI6Uw9peY4PHh8Y7zdDks99E82PI5PcLyK7049peY4PCvvVrx07FA9peY4POetSry6PVs9oTctPBBoSrxa2Fg9DVotPF/yVbw/iVg9ojctPM2JYbwPf1A9Rc8vPFncb7wVbVo91rksPFoPb7xBekw9WSAzPFMxcLzVWp49Th0pPIE0ob1NIJ49lR4pPMEJoL1es549a0cvPJn/n71CAZ89Lz0vPN0oob3I3p09Lh8pPKLinr1DcZ49M0wvPAzbnr0gQaA91YwvPNTin712x6A9fGwvPFQGob2u/p89kZovPFHGnr3+cJ49KpwZPHJkor0OQ549K5wZPCs2ob3Dip49iRwpPNJior1KC549KpwZPDILoL3ZyZ09K5wZPLbjnr2vA6M9BIMtPCmdnr1WQKM95W8tPJ6kn71+O6Q9XDotPG2voL26PaE9G1IvPD03or3sKqY91rksPOHnob0gP589CzcvPHBXor1sIo09mlI2PKnR870pp4o9AVI2PHpe9L1/K4o9vDAzPAJc9L3FmYw9gTUzPG3Q873yIog9u1A2PJnW9L03qoc9fiYzPNvT9L3f24g9/gkwPMxU9L3YJos9uxcwPPzM870CX4Y9p+kvPDbL9L3zNY09peY4PNfR873SuIo9peY4PNNe9L0yNIg9peY4PP7W9L1vqIU9pOY4PPY59b0wmIU99E82PJ059b1zJoU9WSAzPDw39b1e5IM9Rc8vPEkw9b3px4A917ksPJwd9b270IM9XTotPHiy9L1KToY95m8tPBpE9L2CVIg9BIMtPPnF872vYXk9pFA2PLDdQLnueXk9UlE2PK4tT7mJZHk9RiszPE8fT7lmS3k9zyUzPHLPQLlhkXk9pVA2PBX3XblSeXk9ziUzPJbkXbnNKnk9SvovPGz4TrmHDnk9r+cvPN7BQLmnN3k9r+cvPKGYXbneZHk9peY4PLrfQLn8fHk9peY4PLwvT7nTlHk9peY4PLj5XbldrHk9pOY4PKc8bbmTqHk99E82PHg5bbkHjnk9WSAzPDAjbbnfQnk9Rc8vPCnlbLkbiXg917ksPClUbLmnt3g9oTctPIxIXLkTvHg9DFotPE2tTrl0l3g9oTctPE5eQbla9mk9RB8pPOYMhL3so2c9RB8pPJZEhL2g92U94UwvPPA7hL2oMGg94kwvPMYEhL3CU2U9RB8pPNOFhL3Tn2M94kwvPOJ7hL0cbWE9iZwvPHgkhL0zYWM9h5wvPLTug72ZAF89iJwvPOZghL0oN2o9K5wZPA8OhL0b4Wc9KpwZPNJFhL0GkmU9K5wZPD+HhL0/SmM9KpwZPCnShL2+CmM9RB8pPI3QhL0xTmE94UwvPErFhL2Ql1w9iZwvPLymhL3JaVM9vIUtPDhrhL1nAFY9wIUtPFkshL09lVg9vYUtPML2g70ZA1o9v4UtPLzDg71xMY49Th0pPEtjxb1xI489lR4pPJzCxL1t5I89a0cvPMusxL3CDY89Lz0vPHpPxb0uE5A9Lh8pPIUaxL3Lz5A9M0wvPA4ExL1c75E91YwvPBBwxL1MaZE9fGwvPPkVxb2mz5I9kZovPObGw72xFo09KpwZPL7+xb34EY49K5wZPCBmxb3iOI09iRwpPIL8xb3fB489KpwZPLnFxL08+I89K5wZPLgdxL3ds5Y9BIMtPNtOw71I5ZU95W8tPBryw70CEJY9XDotPHqOxL3KzZA9G1IvPG/Axb39V5c91rksPBtSxb04KI49CzcvPNjsxb1LCI49pFA2PMpBXbxzBY89UlE2PPxxarzBaY49RiszPLSEarxHaY09zyUzPBhXXbxgA5A9pVA2PE3vd7zLUI89ziUzPIUBeLy2xYw9SvovPC23aryOtos9r+cvPJ+oXbygaY09r+cvPOYbeLwFH449peY4PMA+XbyyG489peY4PFBvarzkHJA9peY4PLDsd7xZIpE9pOY4PD7agrzTBZE99E82PIXbgrwhPpA9WSAzPH/kgrzHCI49Rc8vPDX+grzYk4g917ksPEBAg7z0tYk9oTctPE2jd7yboIk9DFotPKoXa7zFY4g9oTctPObwXryapTA9Th0pPEjknr2WKDA9lR4pPM8LoL3c/S49a0cvPMoPoL3gUS89Lz0vPOrnnr2cuS89Lh8pPHc2ob3eki49M0wvPFg4ob081Ss91YwvPBAcoL0GsSs9fGwvPPX0nr0kcys9kZovPKA9ob0k1jA9K5wZPMPjnr1BUzA9KpwZPD4LoL234y89K5wZPDQ2ob3ahy89KpwZPHlkor2jXC89RB8pPDxkor0nLi494UwvPJ5ior0d+So9iZwvPDVeor1BuiQ9vIUtPJ9Vor0pXyU9BIMtPNVIob2xuSU95W8tPFc7oL1slSQ9XDotPC0kn73Aer89a042PK4lf72iQcA92E82PFi3gb0fUL89bx8zPIfDgb2DPL49EBQzPKVCf72598A9bE42PF3Ug72QF8A9DxQzPPrgg72nzrw9RtgvPAHkgb3A6bo9kbAvPLqbf71zpr09kLAvPMz+g70A5L49pOY4PCzIer03qL89peY4PIshf73lqr49/kw2PHHMer0hZMA9peY4PJm1gb2/F8E9peY4PJDSg70Pw8E9pOY4PKTnhb3NosE9/kw2PKTphb39wMA9rggzPKL3hb2JKL4933ovPEsghr2J7LU9lakrPISZhr2HpLg9SOAsPPsThL1yNLg9tSotPDYggr2pNbU9R+AsPHpGgL3lhLg933ovPEtFe72EJqo9lakrPG6afL0zG709rggzPFfqer0UGc08cE42PPekxL13lsk8/U82PCxKwr0F0Mw8mSAzPO5Xwr3CwNA8NhQzPNqwxL36dcY81042PKvmv71S0sk8ZhczPA/4v70Ef9U8m9svPE59wr1cwdo8/LAvPLDNxL1+I9M8D7svPKwswL1AUtA8pOY4PPT0xr1qk8w8peY4PESjxL0U6NA8/kw2PFz2xr2GIMk8peY4PDVIwr0T+8U8peY4PC/kv72IJMM8pOY4PIh3vb1wpcM8k002PGF6vb3GK8c8Uw0zPEiOvb1XfdE80IsvPIbIvb1w6PA8neUrPP95vr1+2eU8OPEsPJ23wL3vDeY8WS8tPF/Gwr0cu+083OAsPNbnxL0kEOE833ovPAYdx72YsQM9lakrPHl8x73dANU8rggzPB8Ax72YZ8c9k082PFUnnr12oMc981A2PK/Mn73TBMc9TigzPNfUn72ju8Y9SB0zPBAvnr0Czcc9mVA2PPZpob0cJsc9cCUzPIdyob34YcU9wvEvPLfrn72+5cQ9Qc0vPINInr0nXsU9neYvPIyHob1CQcc9pOY4PNl4nL0qgMc9peY4PDkmnr16Jsc9eE42PM15nL2xtsc9peY4PIbLn73Z5Mc9peY4PLxoob2cCsg9pOY4PNj9or328Mc99E82PAb/or1cPcc9WSAzPD4Ho73MQMU9Rc8vPG8eo71cV8A917ksPDJXo73u4sE9JTYtPOieob1YRMI9Lk4tPAMcoL3wXcE94w0tPN6Znr3ATcQ9hqUvPHaTnL0YZ749uzosPOTGnL37asY9ehQzPHGAnL30GFw9mFA2PITX9L28FVc981A2PERf9L2c41c9TigzPFNi9L17vFw9cCUzPC7b9L2+J1I9lE82PCPS872QS1M9SB0zPEfU871xCVo9w/EvPDxr9L3tfF49n+YvPJTk9L39X1Y9Qs0vPAzc870nGWE9pOY4PPU59b2ZAVw9peY4PP3W9L3pLGE99E82PHs69b1S+FY9peY4PNJe9L0P/lE9peY4PNXR870uC1w94w0tPMz5873XCl49Lk4tPGt/9L0E82E9JTYtPG3y9L3cPmM9Rc8vPCdI9b29B2c91rksPH9f9b0zt2E9WSAzPBc+9b1tgHM9pFA2PFsOebm+lnM9UlE2PKjVabl/rXM9RSszPFLdabnymXM9zyUzPIgYebnbrXM9pVA2PKQPW7mkxXM9ziUzPNkUW7nq6nM9S/ovPNHxabmZ33M9r+cvPOYYebmgBnQ9r+cvPCY+W7lcZnM9pOY4PIZbhLnIfHM9peY4POoMeblianM99E82PGZchLl8k3M9peY4PI/Uabl3qnM9peY4POUOW7m5hXQ9oTctPFJSXLm1YHQ9DVotPBIYarlWZ3Q9ojctPBVQeLkJ1nM9Rc8vPFl0hLmumnQ91rksPFGkhLl6hnM9WSAzPIVihLnDl8Q90042PLjmv72WzsM95E82PFhKwr2l+cI9zh8zPNxYwr1SwcM9TBczPBP4v71T68I9KE42PGelxL3H6ME96xEzPPGzxL3dv8A9UtkvPOJ/wr0tb8E9xbovPI8swL0hL789wakvPAzXxL0MbMU9pOY4PJd3vb1ktsQ9peY4PDzkv70iTMU9k002PGh6vb0B7cM9peY4PERIwr1DEMM9peY4PFOjxL2JIMI9pOY4PAX1xr0W8sE9mEw2PEH3xr3vrMA9fwUzPNoGx73t+Lw9H28vPD00x70tsLE9kn0rPMK9x71TRbo9HdUsPCf2xL2zk7w9LCwtPO7Jwr0uxbw91fAsPDi3wL3X38E90YsvPLLHvb3HLro9neUrPIl1vr2wbMQ9Uw0zPCCOvb05oXY97lY2PL8ukzQGonY9KlQ2PMrkkjT3oXY9/UEzPA/okjQyoXY9HlgzPJYvkzTSonY94FI2PMqBkjS+onY9qjczPDOHkjTQoXY9hT0wPF/vkjQdoXY9cIMwPOEwkzSIonY9LB4wPPyTkjRvoHY9pOY4PFBjkzQ7oXY9peY4PNgtkzRuoHY9lVg2POtjkzQHonY9peY4PIrjkjTVonY9peY4PDyAkjSho3Y9pOY4PMP/kTSco3Y9r1I2PJUBkjSHo3Y9MDYzPNcIkjRHo3Y9sxkwPJkakjTLonY9vIUtPOY7kjQgonY9i40tPNyrkjR/oXY9HMQtPFb+kjTioHY9uUouPM03kzRtoHY9A7QwPBRekzRuoHY92vEuPCZYkzRuoHY9ZGUzPLFikzTiuEQ9pFA2PB1AjLwN10Y9UlE2PA1rhbw1LUg9RSszPPNfhbz1P0Y9zyUzPOs0jLxr9kg9pVA2PKxvfbwpVUo9ziUzPDdVfbxYyEs9S/ovPOhBhbwBa0o9r+cvPAIKjLzLE049r+cvPGElfbxmVUI9pOY4PP03k7wFgUQ9peY4PLhBjLy5k0I99E82PFk2k7wspkY9peY4PKNshbxSxEg9peY4PHVzfbyzZlU9oTctPP14fbzlsVI9DVotPPkHhbw9iFI9ojctPPBbi7wkG0k9Rc8vPKoKk7xJB1U91rksPEi9krz+R0Q9WSAzPN8qk7wUEIM9ulA2PJSH9b2pq4A9AVI2PIPC9b0dbYA9ujAzPPTA9b2gtoI9fiYzPL2F9b1jJX09m1I2PPXs9b3Nwnw9gTUzPCbr9b2fiX89/wkwPAK99b1pw4E9pukvPEGB9b2Tt3s9uxcwPEjm9b3bHIM9peY4PNeH9b2YtIA9peY4PL3C9b14M309peY4PDft9b207Hk9pOY4PNYJ9r0C4Hk9r1I2PIUJ9r0hh3k9MDYzPFQH9r3klXg9sxkwPGAB9r0cwHY9vIUtPMr19b0JsXk9BIMtPP/c9b3aCH095W8tPMu29b3F3H89XDotPL589b0BwHk9pFA2PF30fLkf13k9UlE2PAaThrkJv3k9RiszPDOIhrnEpnk9zyUzPKzefLlZ7Xk9pVA2PGXmjrlp0nk9ziUzPAjZjrkFfnk9SvovPO5qhrnNYXk9r+cvPPG/fLnjiHk9r+cvPCumjrmew3k9peY4PHn3fLmQ2nk9peY4PJKUhrky8Xk9peY4PE/ojrmCB3o9pOY4PG52l7lHA3o99E82PDB0l7ms5Xk9WSAzPHpkl7nXkXk9Rc8vPIQ4l7mewng917ksPOLPlrmK+Xg9oTctPCnZjblWAXk9DFotPIoyhrny2ng9oTctPKdSfbmWlnY93U02PNKjcbKknHY9bFI2PGCASzQJnXY9DjQzPMipVzSol3Y9nQ8zPOiMojJdn3Y9t1Y2PHvMjTRvn3Y9YFYzPBWNjjT2nXY9eBUwPNajczRcmnY90qEvPNcq2jOdn3Y9bn4wPI9FkDQ3i3Y9pOY4PBA/4rRwlnY9peY4PK1ZobJzi3Y9t0s2PJiG3rSVnHY9peY4PAnCSTRbn3Y9peY4PDKwjTTwn3Y9w0MuPKkHkjQSn3Y9YowtPJ1giDTqnXY9l8csPA8PXzS6kXY9tVQvPNS4dLRun3Y9HBArPGh5KDQQjXY9df4yPNOAxLRVEJI9pFA2PEXjibxIHpM9UlE2PMsNkbxXY5I9RiszPHIUkbwOUJE9zyUzPCzribw8K5Q9pVA2PANamLxDVpM9ziUzPBhgmLzzapA9SvovPF8mkbx3Qo89r+cvPGANirwvEZE9r+cvPAlkmLzMK5I9peY4PCTiibz8OJM9peY4PNcMkbyoSZQ9peY4PCRZmLyJXZU9pOY4PNjFn7ysO5U99E82PKjGn7yYTpQ9WSAzPE/Mn7xhr5E9Rc8vPJbcn7y/NIs917ksPPsGoLwtpow9oTctPKYOmLwBpIw9DFotPJZIkbwdPos9oTctPNerirzZAIg9Lh8pPBrqhb206YY9lR4pPISDhb21uoc9bEcvPKmBhb2XzIg9M0wvPNDphb380YU9Th0pPFclhb1qwYY9Lz0vPO0dhb398Ik91IwvPCN+hb139Yo9kZovPDrphb0wUYk9fWwvPJoMhb1O94g9KpwZPFBZhr2/44c9K5wZPCXqhb3NFIk9RB8pPCFZhr3Yy4Y9KpwZPMeDhb3Gr4U9K5wZPGUmhb3tXY49XTotPI/+hL1/Oo495W8tPOB+hb13KY89BIMtPAbphb2QE4w9iZwvPGtUhr28VpA9vIUtPLtNhr0844k94UwvPN1Xhr37/VM9Th0pPBqOxr3sD1Y9lR4pPG8Xx71DhVQ9a0cvPKwTx72+QlI9Lz0vPOyExr06JFg9Lh8pPOKXx729llY9M0wvPF2Vx73qWlA91YwvPBkLx70+i009fGwvPAFvxr1uYFI9kZovPL6Ox71OPVQ9K5wZPGmPxr1NSFY9KpwZPPoXx70EXVg9K5wZPD6Yx70Ye1o9KpwZPAoQyL2gP1o9RB8pPIUPyL1Un1g94UwvPNQLyL1hNVQ9iZwvPM0ByL3wnEs9vIUtPEnux72oL0o9BIMtPN+Cx70LV0g95W8tPKwCx71RbUQ9XDotPAhaxr1ppHY9sFI2PApgkTQ4pXY9sFI2PBuZkDQcpXY9MDYzPNKkkDRRpHY9MDYzPCNpkTQDpnY9sVI2PLGojzTnpXY9MDYzPFG4jzTUpHY9sxkwPK3CkDQMpHY9sRkwPOJ/kTSRpXY9shkwPMrgjzRupHY9peY4PPRdkTQ7pXY9peY4PKaWkDQHpnY9peY4PK2ljzTVpnY9pOY4PN6GjjTRpnY9r1I2PHmKjjSupnY9MDYzPD+ejjRQpnY9sxkwPPjRjjSXpXY9vIUtPGk1jzTtpHY9wIUtPE4ukDRFpHY9vYUtPIf7kDSJo3Y9v4UtPOqqkTRQ1p49OB0pPN/9pb3ZxJ495h0pPHrIpL2sX5899kEvPNPBpL1gfp89fzwvPFj4pb3crJ49OB0pPHOUo71sVJ89fzwvPFGLo713AaE9IX0vPP2vpL0uSaE9hWovPMbmpb1CHqE9hWovPAd1o72Ew549KpwZPK40p71Ovp49K5wZPKn+pb1s3Z49iRwpPPszp727rp49KpwZPG3JpL3ulJ49K5wZPMOVo71ynaQ9oTctPKhco72ZIqQ9DVotPEKOpL1ax6Q9ojctPJGypb3Yk6E9G1IvPD0hp71Uh6Y91rksPAH/pr2wkp89CzcvPBYvp73StHc931I2PGwa9r0sK3Y9KlQ2PBIg9r3m5XU9/kEzPNsd9r3QZXc9qjczPB4Y9r1FoXQ971Y2PHQa9r35Y3Q9HlgzPGEY9r1NKXU9hD0wPNIX9r1Lj3Y9LB4wPOIR9r3dvnM9cIMwPNMS9r0cwHc9peY4PL8a9r0RNXY9peY4PGMg9r0GqnQ9peY4PMEa9r1sfXI9pOY4PNYJ9r0Gd3I9lVg2PJ0J9r05SnI9ZGUzPA0I9r2s3XE9A7QwPEIE9r0yXnE92vEuPM//9b2reXI9uUouPPsH9r0tt3M9HcQtPAQM9r0w7XQ9io0tPLoF9r3pzWA9RB8pPLIkhb0smV49RB8pPPSBhb1pC1094UwvPB51hb1fKF894kwvPMcYhb1maFw9RB8pPAfohb2301o94kwvPC/Zhb3E01g9iZwvPElShb0wsFo9h5wvPG/4hL1GiVY9iJwvPOawhb0gCmE9K5wZPGYmhb0A0l49KpwZPMmDhb01olw9K5wZPCbqhb0Ze1o9KpwZPFFZhr0pQFo9RB8pPOtWhr2Yo1g94UwvPBxGhr3EQ1Q9iZwvPHwYhr0Jv0s9vIUtPKS/hb06Lk49wIUtPHNihb1InVA9vYUtPHIOhb0R/FE9v4UtPHO5hL0qFi89Lh8pPA6Vo70/4i49lR4pPFvIpL1huy09bEcvPMXApL1l8S09M0wvPPGPo717vS49Th0pPHz9pb05by09Lz0vPCP1pb2xnSo91IwvPNGqpL0W1yo9kZovPOmBo71q3ik9fWwvPFzbpb38Py89K5wZPMeVo71fDC89KpwZPHLJpL087S49K5wZPKz+pb3N4i49KpwZPK80p70Dry49iRwpPKEzp718RC09CjcvPEMsp70+Qik9G1IvPGoXp71tWx8917ksPODjpr386SI9XTotPOqTpb3QmSQ95m8tPCp5pL31zSQ9BIMtPLdlo73qKHM9pFA2PAgtnbkHPnM9UlE2PLKvlLlqV3M9RSszPKG3lLk6RXM9zyUzPL82nbkLVHM9pVA2PAdqjLm0bnM9ziUzPOZwjLnqm3M9S/ovPPXMlLmIknM9r+cvPPxBnbmWt3M9r+cvPNKSjLmlD3M9pOY4PNTfpbneJHM9peY4PKQrnbkXFHM99E82PHHhpbllOnM9peY4PJCulLk8UHM9peY4PAtpjLkWRnQ9oTctPJpCjblSH3Q9DVotPFv1lLk7KXQ9ojctPH7nnLksi3M9Rc8vPAcNprmsZHQ91rksPL1gprksM3M9WSAzPLDspbmep3Y9sFI2PC86jTRsqHY9sFI2POmzizRGqHY9MDYzPCXQizR7p3Y9MDYzPItRjTQ4qXY9sVI2PLHziTQOqXY9MDYzPI8XijTep3Y9sxkwPNUajDQZp3Y9sRkwPAOPjTSbqHY9shkwPPV2ijSkp3Y9peY4PBA2jTRxqHY9peY4PBevizQ/qXY9peY4PMntiTQLqnY9pOY4PPrthzQGqnY9r1I2PP/0hzTVqXY9MDYzPKAgiDRYqXY9sxkwPBqViDRkqHY9vIUtPKF2iTS8p3Y9wIUtPHMvizQWp3Y9vYUtPACrjDRZpnY9v4UtPG0FjjTe8js9pFA2PETXqLzjJj49UlE2PCSDobwpvT89RSszPE57obxQwD09zyUzPLjPqLy2X0A9pVA2PBhNmrzhAkI9ziUzPFBDmrxfBUQ9S/ovPBxmobyLq0I9r+cvPOWtqLyDfEY9r+cvPME1mrywcDk9pOY4PMJJsLzzsDs9peY4PFbYqLzruTk99E82PLBIsLzY7D09peY4PESEobzVI0A9peY4PH5Omrz7PE89oTctPKN6mrwEO0w9DVotPDM9obzHP0w9ojctPAILqLwEZkE9Rc8vPFcssLzYaE891rksPK/6r7yTujs9WSAzPDlBsLw4NW892FY2PCbt9b2KBms9e1M2POTC9b0ZLms9iDwzPAPE9b1TK289cFczPLvs9b3TPWY96lA2PDiI9b1MnGY9+CczPNuK9b2qnWs90C0wPE7H9b3CIG89eYEwPCjs9b2enGc9Ie4vPD+S9b2iNm89peY4PDbt9b3jAGs9peY4PL3C9b1XMGY9peY4PNiH9b2hh2k9KUItPE2i9b0mjGw9Ra4tPBTP9b0Ma289/kcuPE/u9b19GXo9pFA2PDs8oLlaL3o9UlE2PJI9qbm2FHo9RiszPIguqblx/Xk9zyUzPAItoLk8RHo9pVA2PEJ3srmUJno9ziUzPCxlsrnPzHk9SvovPOUFqbnIsHk9r+cvPEIToLmd1Xk9r+cvPNojsrmAHXo9peY4PGg+oLkoM3o9peY4PLg/qbl5SHo9peY4PNt5srlvXXo9pOY4PEXsu7nMWHo99E82PEjpu7lJOHo9WSAzPGTUu7lC3Hk9Rc8vPLWZu7nK+Hg917ksPIwMu7m9N3k9oTctPDIvsbnhQnk9DFotPLK3qLnqGnk9oTctPNdToLm/Ioo9Lh8pPOOXx73nLIs9lR4pPHEXx70+8os9bEcvPK4Tx71/6Yo9M0wvPF6Vx73gNYw9Th0pPBuOxr2BE409Lz0vPO2Exr1uB4491IwvPBsLx72pBI09kZovPMCOx71Eb489fWwvPARvxr1O94g9KpwZPA0QyL1bBoo9K5wZPD+Yx70MFYk9RB8pPIcPyL23EIs9KpwZPPsXx704Fow9K5wZPGyPxr0//pM9XTotPAxaxr1gCZI95W8tPK8Cx70THZE9BIMtPOOCx70uGow9iZwvPM4ByL1sZpA9vIUtPEzux70y5Yk94UwvPNYLyL3oU5Y9pFA2PGtSp7yHbpc9UlE2PCf8rrzTkpY9RiszPMj/rryVcJU9zyUzPCZXp7xUhpg9pVA2PLrCtryBjZc9ziUzPIHFtrwJQpQ9SvovPIoJr7xAA5M9r+cvPItxp7x85pQ9r+cvPI2/trxidJY9peY4PL5Rp7zojZc9peY4PKT7rrzhqZg9peY4PFTCtrwGyJk9pOY4PJukvryboJk99E82POqkvrysjJg9WSAzPACnvrxvf5U9Rc8vPCmtvrzO9I0917ksPDa+vrxBvI89oTctPLVQtrx20Y89DFotPBEcr7zcQ449oTctPAQHqLzSD8g9mFA2PBGPpL1bJMg981A2PLMqpr1piMc9TigzPBMvpr2oaMc9cCUzPIGVpL0LKcg9lE82PN/lp70ffcc9SB0zPDrpp72N5MU9w/EvPFY6pr1MoMU9n+YvPE2ppL2RpsU9Qs0vPCrvp720J8g9peY4PCWOpL2fOsg9peY4PBUqpr2eQcg9peY4PGTlp73fOsg9pOY4PNfTqb0nIMg9eE42PF7Uqb0XZcc9ehQzPAnYqb0AScU9haUvPMHjqb15ZL89uzosPMsPqr0kGMI94w0tPHLgp70DxMI9Lk4tPDRNpr3OJsI9JDYtPIvgpL0NMYw9RB8pPPnYh70WK4s9RB8pPLxQh72544s94UwvPEFMh73f7Iw94kwvPEzSh71PIoo9RB8pPLjQhr0F5oo94kwvPADOhr3j2I09iZwvPBhAh72s6o49h5wvPCrAh707+Yw9iJwvPJ7Ghr2xFo09KpwZPJlqiL03Fow9K5wZPO7Zh70MMo09RB8pPFlpiL21EIs9KpwZPGBRh71ZBoo9K5wZPBzRhr2yA5E9wIUtPDy4hr3RqJE9vYUtPGsoh71zy5I9v4UtPN6ch704+Y89iZwvPMNIiL1H7ZM9vIUtPGAaiL2E8Y094UwvPJNgiL3iZ1w9RB8pPIJ+yL2umF49RB8pPLLkyL1zB1094UwvPH3eyL2az1o94kwvPJZ5yL1mzWA9RB8pPNdByb1BJF894kwvPP85yb1oxlg9iZwvPKjNyL1oe1Y9h5wvPDZsyL1Tolo9iJwvPK0kyb01olw9K5wZPDd/yL3/0V49KpwZPJTlyL0fCmE9K5wZPPhCyb0+SmM9KpwZPDWXyb01CmM9RB8pPOOVyb3tSWE94UwvPKaMyb0siVw9iZwvPI5zyb2wR1M9vIUtPLRCyb0v21E9wIUtPCz7yL2gfVA9vYUtPN6syL1ZDU49v4UtPCxSyL3SqnY9sFI2PFmzhTSiq3Y9sFI2PCIrgzRxq3Y9MDYzPC5kgzSlqnY9MDYzPL3khTRurHY9sVI2PKlYgDQ5rHY9MDYzPISegDTsqnY9sxkwPA79gzQiqnY9sRkwPNdohjSnq3Y9shkwPDBagTTbqnY9peY4PIGrhTSoq3Y9peY4PDQigzR2rHY9peY4POZNgDRDrXY9pOY4PNpUejQ8rXY9r1I2PARuejQArXY9MDYzPD4TezRkrHY9sxkwPMbPfDQwq3Y9vIUtPHMXgDSMqnY9wIUtPFzGgjTrqXY9vYUtPHwlhTQpqXY9v4UtPNVohzTDJFg9Lh8pPKHOhr2PEFY9lR4pPAJPh71TilQ9bEcvPFY+h739mlY9M0wvPDW9hr3q/lM9Th0pPNnXh70tSlI9Lz0vPCzJh72ra1A91IwvPMAPh724blI9kZovPLyNhr3ho009fWwvPC6eh70EXVg9K5wZPCDRhr1MSFY9KpwZPGRRh71PPVQ9K5wZPPPZh71dPFI9KpwZPKBqiL03+VE9iRwpPBBpiL0lI1A9CjcvPCZeiL1T8Eo9G1IvPFI/iL0MGD4917ksPKrzh725o0Q9XTotPDU2h73dfEg95m8tPFquhr1OUUo9BIMtPHUwhr1Z1nI9pFA2PL9Ewbkn6nI9UlE2PI/tt7kEBnM9RSszPCH6t7lN9XI9zyUzPKpTwbnz/nI9pVA2PFzMrrlZHHM9ziUzPBzYrrk3UXM9S/ovPP0buLnPSXM9r+cvPIprwbm0bHM9r+cvPOcIr7kGvnI9pOY4PMnOyrnu0XI9peY4PJtCwbnewnI99E82PDbRyrks5nI9peY4PMPrt7nA+nI9peY4PK/KrrnFCXQ9oTctPBrhr7l54XM9DVotPHBcuLmY7nM9ojctPG4ewbmvRHM9Rc8vPLESy7nMMXQ91rksPDyOy7m+5HI9WSAzPC7iyrkJrnY9sFI2PMGCczTWrnY9sFI2PDzpazSbrnY9MDYzPIm0bDTOrXY9MDYzPGo4dDSkr3Y9sVI2POaaYzRir3Y9MDYzPGiNZDT7rXY9sxkwPG7YbjQvrXY9sRkwPJIhdjSxrnY9shkwPL0bZzQSrnY9peY4PD1nczTdrnY9peY4PKDKazSur3Y9peY4PLB2YzR7sHY9pOY4PBJjWjRxsHY9r1I2PMeMWjQqsHY9MDYzPMOlWzRtr3Y9sxkwPIecXjT8rXY9vIUtPJBfZDRdrXY9wIUtPG8TbDS/rHY9vYUtPNYAczT5q3Y9v4UtPJvXeTQ35zI9pFA2POFDx7yyKDU9UlE2PCKAv7ydATc9RSszPMZ7v7xz/TQ9zyUzPCVAx7yrcjc9pVA2PK/Wt7xPXTk9ziUzPKjQt7y3/Ts9S/ovPPpvv7x7rzo9r+cvPPQnx7w+mj49r+cvPCbOt7xgTjA9pOY4PIshz7zlmjI9peY4PGlEx7zdojA99E82PBIhz7wi5TQ9peY4PMCAv7ySLDc9peY4PIzXt7xr2Eg9oTctPIsuuLyCjEU9DVotPC5Zv7y2x0U9ojctPDWSxry6fDk9Rc8vPH4Uz7zapkk91rksPFz/zrxH8jI9WSAzPL0dz7zuMbg8h082PCeJp737Rbg8lFA2PB2Upb1hvLo8ViUzPDOZpb1w4ro86RwzPLyOp717mrg8iE82PHW2o72jSrs86BwzPMO6o70aWsE8POkvPESnpb1SPsI8MMwvPGaap729pMI8McwvPAnLo70x6rc8pOY4PGGjqb2Uz7c8peY4PFqIp70UVbg8eE42PD+kqb3u67c8peY4PGSTpb0rOLg8peY4PNi1o71a1tA8ZwwtPHEMpL2z5M08TkItPBPEpb3leNA8aAwtPB6Up72GscM8hqUvPKC8qb1EQ9s8uzosPE34qb1CQbs8ehQzPE2qqb2qbXo9pFA2PJSTxbklgno9UlE2PBN1z7kZZXo9RiszPFRhz7nzTno9zyUzPGp/xbmUlXo9pVA2PLyM2bledXo9ziUzPGZ12bm1Fno9SvovPPcrz7kM+3k9r+cvPLJZxblwHXo9r+cvPD4k2bkNcno9peY4PHeWxblMhno9peY4POZ3z7ktmno9peY4PBGQ2bmtrXo9pOY4PG/e47mlqHo99E82PKHa47lwhXo9WSAzPP+/47m+IXo9Rc8vPA9147lUK3k917ksPJS/4rn2cXk9oTctPKgF2LlbgHk9DFotPF7FzrkOV3k9oTctPPmNxbkkzoU9RB8pPNpByb2C6IY9RB8pPLTkyL0fsYc94UwvPH/eyL23ooY94kwvPAE6yb3pAIg9RB8pPIV+yL0PzYg94kwvPJl5yL2o0Yk9iZwvPKrNyL2x44g9h5wvPK8kyb0q94o9iJwvPDhsyL21j4Q9KpwZPDWXyb3Hr4U9K5wZPPpCyb27r4Q9RB8pPOeVyb3Yy4Y9KpwZPJblyL2/44c9K5wZPDp/yL03Lo89wIUtPC9SyL0R9o09vYUtPOKsyL1IR409v4UtPDD7yL1D8Ic9iZwvPJJzyb0GkYw9vIUtPLhCyb3fj4U94UwvPKaMyb1swpo9pFA2PHuhxryX5Zs9UlE2PDi3zrwe6Jo9RiszPLi3zrzMupk9zyUzPN2ixrwbBJ09pVA2POnk1rx45ps9ziUzPFnk1rwtPJg9SvovPAm5zrxM6pY9r+cvPNi0xrzr2pg9r+cvPIvU1rwW6Jo9peY4PEmhxrzNCZw9peY4PCW3zrzqLJ09peY4PP/k1rwnUZ49pOY4PKEp37wOJJ499E82PGwp37xa6Jw9WSAzPPon37yIapk9Rc8vPA8k37yXyZA917ksPN4b37xf7JI9oTctPCVN1ry4HJM9DFotPGO7zrw0aZE9oTctPEw/x7xdvS49Th0pPPJpqL0L4i49lR4pPEyfqb28uS09a0cvPN2aqb1Rbi09Lz0vPLBkqL3nFS89Lh8pPJ/Sqr1U7y09M0wvPM/Lqr38lyo91YwvPE+Qqb0C2yk9fGwvPExZqL0Z0Co9kZovPIS5qr087S49K5wZPLJqqL1fDC89KpwZPO2fqb39Py89K5wZPJfTqr3bhy89KpwZPOUErL1eXC89RB8pPGADrL31Ky494UwvPLn4q7248So9iZwvPM/bq724qCQ9vIUtPIKjq71JvSQ9BIMtPNSWqr1piyQ95W8tPCyDqb2P3yI9XDotPCZYqL2OH8s80042PBIiiL17bM085E82PIX+hb1XtdA8zh8zPIEHhr1zac48TBczPDcsiL0Q9s88KE42PITVg70j/NM86xEzPP7eg72Lfdk8UtkvPLgfhr2VhNc8xbovPD5DiL221d48wakvPC7+g724e8g8pOY4PFA+ir1Jp8o8peY4PJ8giL27+Mg8k002PPI/ir1b9Mw8peY4PDz9hb3pYs88peY4PCrUg73t8tE8pOY4PGylgb01rdI8mEw2PMCmgb0xxdc8fwUzPAqwgb1NneY8H28vPBzMgb3X3Qk9kn0rPEUzgr3VWfI8HdUsPAVhhL0u6+k8LCwtPOlNhr1Ix+k81fAsPEVLiL3QX9Y80YsvPGdsir1ScvQ8nuUrPFrMir3PY8w8Uw0zPFlLir0+U2U9RB8pPLjgyb1uo2c9RB8pPBEiyr2s82U94UwvPKwXyr23m2M94kwvPOXWyb3V9Wk9RB8pPKRZyr2MLGg94kwvPAJOyr29X2E9iZwvPHn7yb248l49h5wvPDe8yb1SU2M9iJwvPGkuyr0HkmU9K5wZPCDiyb0c4Wc9KpwZPIsjyr0oN2o9K5wZPFBbyr3Tk2w9KpwZPDmJyr36Tmw9RB8pPGyHyr36bGo94UwvPL16yr20UGU9iZwvPFZYyr0AXVs9vIUtPFIVyr014lk9wIUtPOPwyb2TdVg9vYUtPI/Eyb2F31U9v4UtPEWIyb0/sXY9sFI2PEO0UDQOsnY9sFI2PGIMRjTHsXY9MDYzPINXRzT6sHY9MDYzPOniUTTbsnY9sVI2PNGPOjSOsnY9MDYzPDYTPDQHsXY9sxkwPGDWSjQ7sHY9sRkwPHcUVTTAsXY9shkwPNIqQDRJsXY9peY4PHiHUDQXsnY9peY4PIXbRTTmsnY9peY4POhWOjS0s3Y9pOY4PEvxLTSns3Y9r1I2PAUyLjRUs3Y9MDYzPCTsLzR5snY9sxkwPEeYNDTLsHY9vIUtPAmvPTQusHY9wIUtPFkgSDSUr3Y9vYUtPHOiUTTKrnY9v4UtPABKWzQwiXI9pFA2PMmx6LmUm3I9UlE2POOH3rnCuXI9RSszPJGZ3rmZqnI9zyUzPGHG6LkIr3I9pVA2PE2S1LkAz3I9ziUzPHOj1Lk5C3M9S/ovPDTJ3rnTBXM9r+cvPEbs6LleJnM9r+cvPH7k1LnucXI9pOY4POML87lrhHI9peY4PNmu6Lkmd3I99E82PDIP87lCl3I9peY4PFqF3rl3qnI9peY4PNiP1Lka0XM9oTctPG7n1bl6p3M9DVotPB4k37m+t3M9ojctPJ+v6Ln2AnM9Rc8vPHlo87lQAnQ91rksPGAP9Lmjm3I9WSAzPGIm87kgEZA9RB8pPHBJir1WII89RB8pPN6hib2cy4894UwvPI6Vib1jv5A94kwvPCk6ir3nK449RB8pPL4Bib1t4Y494kwvPGH3iL19nJE9iZwvPCl0ib1dmJI9h5wvPLQQir0gzpA9iJwvPD3biL3f4pA9KpwZPAz7ir08+I89K5wZPJ9Lir1C/JA9RB8pPHb4ir3fB489KpwZPJ6jib34EY49K5wZPDgDib2bjZQ9wIUtPHCkiL3HJZU9vYUtPCAzib1xMZY9v4UtPPa/ib05kJM9iZwvPEu1ir1pO5c9vIUtPLJVir3xrZE94UwvPGDmir11tHY9sFI2POzmIDRCtXY9sFI2PGOrEjTxtHY9MDYzPP2jFDQktHY9MDYzPPW7IjQPtnY9sVI2PMt7AzS4tXY9MDYzPHjBBTQVtHY9sxkwPLP5GTRHs3Y9sRkwPCexJzTMtHY9shkwPGXoCzSBtHY9peY4PFqiIDRNtXY9peY4PL5hEjQctnY9peY4PCEnAzTptnY9pOY4PF/U5TPdtnY9r1I2PP2S5jN+tnY9MDYzPF+z6zODtXY9sxkwPLmV+TOWs3Y9vIUtPCJNCjT/snY9wIUtPM3gFzRpsnY9vYUtPK5aJDSdsXY9v4UtPDFWMTQkhik9pFA2POv/57xb7ys9UlE2PKxa37xeDS49RSszPHlW37wq6Ss9zyUzPBP257zhTi49pVA2PLAd17wbgzA9ziUzPAwb17y5wzM9S/ovPNFL37yNbDI9r+cvPOXN57wLiTY9r+cvPJYi17yKmiY9pOY4PGY48bzZLik9peY4PFIB6LwR+yY99E82PDk28bztoSs9peY4PENb37xF/i09peY4PBAe17zUT0I9oTctPCWc17zwtj49DVotPM8637yqGz89ojctPOka57xaFzE9Rc8vPG398Lwyi0M91rksPJGj8Ly8nik9WSAzPPsm8bz5qZ49Lh8pPKLSqr3nw549lR4pPF6fqb0PWJ89bEcvPGibqb1CPZ89M0wvPOHLqr0+1p49Th0pPChqqL3IfZ89Lz0vPFJmqL316KA91IwvPPGRqb3lzKA9kZovPLq5qr1yR6E9fWwvPH1eqL3+cJ49KpwZPOYErL3ulJ49K5wZPJjTqr2+hp49RB8pPGIDrL27rp49KpwZPO6fqb1Ovp49K5wZPLRqqL04xaQ9XTotPPthqL1H76M95W8tPACGqb1W1qM9BIMtPC+Xqr0WvKA9iZwvPNHbq72e4KM9vIUtPIOjq73zHp894UwvPLn4q70OvHo9pFA2PNNe7rkMz3o9UlE2PCMY+bnFr3o9RiszPD3/+Lnfmno9zyUzPDxF7rnm4Ho9pVA2PLMCArpVvno9ziUzPDH0AbpYW3o9SvovPAG8+LkyQHo9r+cvPCQS7rnwX3o9r+cvPB/DAbrJwHo9peY4PH5i7rmE03o9peY4PLIb+bnW5Xo9peY4PMYEArrB93o9pOY4PMGVB7pf8no99E82PGqTB7qozHo9WSAzPACDB7rgYXo9Rc8vPMBUB7rwWXk917ksPD3kBrrVp3k9oTctPOwdAbpsuXk9DFotPMk6+LkCj3k9oTctPAw37rk1CFA9Th0pPHkCib1AJE49lR4pPH2jib3cq0w9a0cvPGWiib3vWE49Lz0vPBH9iL3eREw9Lh8pPJBLir3O1Uo9M0wvPPtKir02sEg91YwvPP+gib3/u0k9fGwvPGDxiL3B8UY9kZovPJVJir3RRVA9K5wZPEADib0EWk49KpwZPKWjib1OeUw9K5wZPKZLir0HpEo9KpwZPBX7ir3Zbko9RB8pPL36ir2c+kg94UwvPFH4ir0+CEU9iZwvPL/xir2uWD09vIUtPPLkir1SXz89BIMtPNtHir2K+EA95W8tPDGmib17pUA9XDotPNvviL3lOYE9RB8pPKdZyr0cY4I9RB8pPBMiyr39OoM94UwvPK0Xyr2NHoI94kwvPAFOyr01i4M9RB8pPLngyb36ZoQ94kwvPOfWyb34hIU9iZwvPHv7yb0ri4Q9h5wvPGsuyr17u4Y9iJwvPDm8yb3H1X89KpwZPDuJyr07GYE9K5wZPFBbyr1RDYA9RB8pPGyHyr1DRII9KpwZPI0jyr3Pa4M9K5wZPCPiyb0aRYs9wIUtPEmIyb0Q+ok9vYUtPJPEyb2/Q4k9v4UtPOfwyb14jIM9iZwvPFdYyr1Yhog9vIUtPFQVyr1S/oA94UwvPL96yr01TJ89pFA2PLKK57wPeqA9UlE2PAMr8LxFWZ89RiszPFkp8LxtH549zyUzPOWI57w1rKE9pVA2PMEz+bxSZqA9ziUzPM0y+bxUTpw9SvovPPYj8Lx06Zo9r+cvPLCS57xf7Zw9r+cvPKQf+bwwd589peY4PPOK57xQo6A9peY4PD4r8LzF2qE9peY4POMz+bzHIqM9pOY4PCRnAb0476I99E82PDpnAb1OhqE9WSAzPNdnAb2oiJ09Rc8vPGNqAb1CrZM917ksPCl3Ab3bLJY9oTctPEp/+LwnepY9DFotPOMU8LxuopQ9oTctPCMR6LxYuS89Lh8pPDkxrb1OKDA9lR4pPAVcrr2i+y49bEcvPDxNrr28kC49M0wvPJUjrb1EpTA9Th0pPKuDr70xTy89Lz0vPBp2r73EzSs91IwvPEcjrr3uays9kZovPFT+rL0AqCs9fWwvPBRNr7244y89K5wZPCwzrb1CUzA9KpwZPCFerr0k1jA9K5wZPJuFr70BbDE9KpwZPG6psL3tNjE9iRwpPP+nsL1lwy89CjcvPPOdsL2hpys9G1IvPHqBsL2VgSE917ksPNg6sL1agCQ9XTotPDbhrr09qCU95m8tPEbIrb0bTiU9BIMtPJ+0rL2pt3Y9sFI2POMMxDN3uHY9sFI2PNZjnzMauHY9MDYzPEsZpTNMt3Y9MDYzPCVtyTNDuXY9sVI2PB8qcTPguHY9MDYzPKgsfjMit3Y9sxkwPEiQtDNUtnY9sRkwPNz81zPWt3Y9shkwPIC2kDO3t3Y9peY4PCdFwzOFuHY9peY4PO6PnjNSuXY9peY4PBVIbzMfunY9pOY4PKPhHDMRunY9r1I2PMH7HjOmuXY9MDYzPMWGLTOLuHY9sxkwPHPwVDNhtnY9vIUtPEjTkDPNtXY9wIUtPEQEszM6tXY9vYUtPMio0jNqtHY9v4UtPP5S9DO4rng9PRwpPHLVyr0gO3s9Nh4pPHPFyr0ZiHw9dEQvPOS6yr0gD3k9pzQvPNvNyr0rtH09Ih8pPGOryr0zfH891EsvPPueyr28KIA9ToQvPHqdyr2wjno9DlIvPBm4yr0ZLYI9gZkvPDV9yr3HNHY9KpwZPL7byr3yoHg9K5wZPIfWyr3PHnY9DRspPOTayr2NC3s9KpwZPPXGyr0Ec309K5wZPCmtyr0D/4Y9iYEtPPw6yr0yfoQ9BmQtPH5gyr0ieYA9nxAtPK2Fyr0HqnM9WygvPLfFyr2UxGw9uzosPOW2yr0AhXU9LCsvPPTUyr0qN3I9pFA2PPAwDbqQT3I9UlE2PMo7BboXcHI9RSszPCk3BbprW3I9zyUzPAMODbpYZHI9pVA2PP7h/bm4hnI9ziUzPO70/bnUx3I9S/ovPAwuBbpUvnI9r+cvPG6rDLqm5HI9r+cvPFA9/rlDEnI9pOY4PJ2lF7r8MXI9peY4POw1Dbr0F3I99E82PJ2cF7rqSnI9peY4PHM8BbpvX3I9peY4PEnf/bkonHM9oTctPNtd/7nob3M9DVotPKwtBbrdfnM9ojctPHXDC7posHI9Rc8vPF2yFrolxnM91rksPNdEFbrEP3I9WSAzPJRdF7rJmZM9Th0pPGIxjb1jvpI9lR4pPKtsjL3KZpM9a0cvPLhYjL21VpQ9Lz0vPIYdjb3e35E9Lh8pPPWui72MiZI9M0wvPHWbi73gLZU91YwvPE4hjL2KWZY9fGwvPGfkjL3XVZQ9kZovPGNmi73aUJQ9KpwZPKb/jb3KfpM9K5wZPDg0jb34bZQ9iRwpPB79jb1TppI9KpwZPIRvjL2ix5E9K5wZPL2xi73u1Jc9BIMtPDz+ir3pmZg95W8tPP+ui72cPZo9XDotPKVgjL2nepc9G1IvPB65jb3yC5091rksPGo9jb3AOZU9CzcvPFzrjb0NtG49Ih8pPGKryr13I3E9Nh4pPHPFyr2YiW89dEQvPOK6yr1r4mw91EsvPPqeyr1Bm3M9PRwpPHLVyr3FXXI9pzQvPNrNyr2wB2s9TYQvPHqdyr1f7Wc9gJkvPDN9yr2nlm49DlIvPBi4yr2R9m49K5wZPCityr0FXnE9KpwZPPbGyr2dyHM9K5wZPIfWyr0dkWQ9nRAtPKyFyr1+b2E9B2QtPHxgyr3wK149iIEtPPw6yr3dunY9sFI2PET0jzKqu3Y9sFI2PJaLnrFEu3Y9MDYzPI/Re7B2unY9MDYzPOEtrjJ3vHY9sVI2PA3C6LIKvHY9MDYzPJjlxLIuunY9sxkwPFp3HDJcuXY9sRkwPFUMADPeunY9shkwPARdR7LtunY9peY4PGKWizK6u3Y9peY4PLXksLGHvHY9peY4PBHu7bJUvXY9pOY4PHrlXLNDvXY9r1I2PJQHWrPPvHY9MDYzPBYiRrOSu3Y9sxkwPI4wELMruXY9vIUtPAa6HLKcuHY9wIUtPNQaMzIOuHY9vYUtPJbT9TI7t3Y9v4UtPAzFTzOCgx49pFA2PCkbCL11XiE9UlE2POK+Ar06xyM9RSszPGO3Ar32OSE9zyUzPOITCL22OiQ9pVA2PA0X+7w3viY9ziUzPNwG+7z9Rio9S/ovPJyiAr1WoSg9r+cvPN31B73lmy09r+cvPKrs+ryvOxs9pOY4PJ+HDb1MIB49peY4PDMcCL1pqRs99E82PKaGDb1YBiE9peY4PPO/Ar3H3iM9peY4PF0Z+7ycAjs9oTctPBY7+7zCujY9DVotPN53Ar3WDTc9ojctPJhxB71wKCc9Rc8vPE9sDb2pKDw91rksPGY7Db2IqR49WSAzPMt/Db1K4p09Th0pPK2Dr73EIJ49lR4pPAdcrr0ct549a0cvPD1Nrr1UjZ49Lz0vPBx2r70/WJ49Lh8pPDoxrb2Q7J49M0wvPJYjrb0QTqA91YwvPEgjrr3xYKA9fGwvPBZNr738fqA9kZovPFb+rL3qfp09KpwZPHCpsL3byZ09K5wZPJyFr711mZ09iRwpPACosL1KC549KpwZPCFerr0QQ549K5wZPCwzrb3sjaM9BIMtPKC0rL3cYKM95W8tPEnIrb3N9KM9XDotPDnhrr0iYaA9G1IvPHyBsL0zdKU91rksPNo6sL07U549CzcvPPadsL2WBHs9pFA2PFlkDbrBGHs9UlE2PCYzFLr39no9RiszPIsmFLoP4Xo9zyUzPPVUDbp2MHs9pVA2PInjHLpiCns9ziUzPOLaHLrym3o9SvovPHYAFLoGgHo9r+cvPII0Dbq0ono9r+cvPIixHLqqCXs9peY4PIxmDbqUHXs9peY4PPM0FLrmNXs9peY4PMTkHLoMVXs9pOY4PNJZKLoDT3s99E82PB1aKLrHJHs9WSAzPCpcKLpErXo9Rc8vPCpqKLqJhnk917ksPKbNKLoO2nk9oTctPPjUG7oJ7nk9DFotPMOiE7qAwnk9oTctPBE8DboLqEg9RB8pPB6xi71y7UY9RB8pPIhujL2in0U94UwvPFlnjL3ERkc94kwvPIKsi72aO0U9RB8pPMcyjb1z50M94kwvPGMojb2OFUI9iZwvPNpTjL3Uh0M9h5wvPPyfi70kTEA9iJwvPDIMjb2G2kg9K5wZPMexi70hHUc9KpwZPI5vjL01bEU9K5wZPEI0jb0WyEM9KpwZPLL/jb13lkM9RB8pPMv9jb0hO0I94UwvPGnwjb1bjD49iZwvPBnMjb1tYDc9vIUtPGCFjb0hRjk9wIUtPErVjL0aMTs9vYUtPOAtjL1zPDw9v4UtPJuHi71FTaQ9pFA2PE+KBr1DuaU9UlE2PMvvC71Tb6Q9RiszPLP0C70R9aI9zyUzPAONBr0tJKc9pVA2PGB8Eb16saU9ziUzPIqCEb0B9aA9SvovPFwCDL19SJ89r+cvPBefBr2FvaE9r+cvPJ2JEb1wfqQ9peY4PO6JBr1k6KU9peY4PBjvC70kWac9peY4PH17Eb0uyag9pOY4POoTF73Cjqg99E82PMsUF73E9aY9WSAzPOoaF726b6I9Rc8vPB4sF70sQZc917ksPJdVF73ACJo9oTctPARQEb2QSZo9DFotPMQeDL2yGZg9oTctPKAOB70QvnY9sFI2PDSKorPevnY9sFI2PJC32rNsvnY9MDYzPG8F0LOevXY9MDYzPBZHmLOov3Y9sVI2PN/ACrQvv3Y9MDYzPCDDBLQ4vXY9sxkwPDIFs7NlvHY9sRkwPF3oeLPpvXY9shkwPAUI6bMhvnY9peY4PKEEpLPtvnY9peY4PNtB3LO5v3Y9peY4PIudC7SGwHY9pOY4PHyAKrR0wHY9r1I2PESNKbTzv3Y9MDYzPKjxIrSYvnY9sxkwPBAGEbTyu3Y9vIUtPL5F3LNpu3Y9wIUtPHvGqbPgunY9vYUtPCQhdbMIunY9v4UtPL2UDLPNK7o84k42PF7osL1pO7k8W1A2PClgrr1OwLs8jCMzPEtprr3987w8xBczPIP1sL0Bprg8gU82PC7vq71EXbs8sBwzPBX2q715hcI8FuQvPH2Brr1mk8Q8HrwvPA4Tsb2Pz8I8jMsvPOAOrL0W/bo8pOY4PDp2s70Pxrk8peY4PH7msL3pbLs8k002PI94s71I37g8peY4PNterr2vQrg8peY4PDLuq727UtE8ggstPCBqrL2FXc88KDstPJWtrr0pOdM8tPIsPIAasb3masc80YsvPIa4s705XeI8nuUrPBtItL2se748Uw0zPOOIs71fScI9d042PM72h71T58I9NlA2PBv8ib1XNcI9YiIzPBgKir2EgME9bRQzPMAEiL0ueMM9fE82PLL5i72Ou8I9iRwzPGkJjL1KV8A9weAvPF8wir0uW789orEvPDowiL3UtMA9IssvPIIwjL0SZsI9peY4PNT0h73BAMM9peY4PBr6ib0fk8M9peY4PHX3i70rHcQ9pOY4PN/sjb12AMQ9eE42PETvjb2EN8M9ehQzPAQAjr1u88A9haUvPDIwjr0hoLo9uzosPM20jr38tbw97gotPJdejL3lzbw9gzYtPHJ8ir3aSrs9wOEsPJmsiL3fC8g9gE82PGwDrL155sc9W1A2PClmrr0+Rcc9jCMzPMVurr0KXsc9sBwzPMkIrL1Yqsc94042PCPpsL1J+MY9xRczPDj2sL3wk8U9GOQvPLaFrr1xgcU9i8svPKsdrL1sEMU9H7wvPJoTsb2yJMg9peY4PKYCrL2B/cc9peY4PO9krr3Hw8c9peY4PEXnsL0Bdsc9pOY4PEJ2s70LWsc9k002PJh4s71YlsY9Uw0zPOuIs72EWsQ90YsvPI+4s73hnb09nOUrPCBItL30ZsE9s/IsPNoasb3kXcI9KDstPECwrr2b4ME9gwstPDNzrL3lc3E9pFA2PK4pT7q5uHE9UlE2PLF8N7oK3XE9RSszPGEMN7q+nXE9zyUzPMtlTrqS7nE9pVA2PPdZJbpCFHI9ziUzPBANJbrUPnI9S/ovPDXgNbq5D3I9r+cvPMk7TLoIe3I9r+cvPJ9UJLr1FHE9pOY4PGi4bbrqbXE9peY4PKpFT7q0G3E99E82PN2RbbqIs3E9peY4PLyMN7ox6XE9peY4PPJkJbqDQnM9oTctPCGcI7o0+XI9DVotPCKvM7qr7HI9ojctPH5SR7pv0HE9Rc8vPNmZabrNGHM91rksPG7xYrrtSnE9WSAzPBOEbLqJwXY9mlI2POMoXrRUxHY9AVI2PNwMx7R+w3Y9vDAzPCcLwrQAwXY9gTUzPGQCV7SIynY9u1A2PNTcTLX5yHY9fiYzPHvKSLVVwXY9/gkwPBwptLSPv3Y9uxcwPI2KQ7TnxHY9p+kvPMpZPbWcwXY9peY4PPIvX7RwxHY9peY4PL7Ex7TCynY9peY4PCFyTbVM1nY9pOY4PA6FybX41XY99E82PC0sybWx03Y9WSAzPGa/xrVQzXY9Rc8vPD9rwLUGvnY917ksPIQGtbUevnY9XTotPBPuIrWtvXY95m8tPOKbl7TSvHY9BIMtPF1CHbSgWRM9pFA2PHaWHb0fAxY9UlE2PJZGGL2FwBg9RSszPKBCGL3uaxY9zyUzPGSTHb2uzRg9pVA2PO/rEr0Fqhs9ziUzPG/mEr13JSA9S/ovPAA4GL1ezh49r+cvPE2BHb3VeyM9r+cvPD/hEr0wRBA9pOY4PO/bIr1M6RI9peY4POeWHb3YvxA99E82PJbbIr3rnhU9peY4PCZHGL0OZRg9peY4PLjsEr1+yDI9oTctPMkeE73+VC49DVotPOwjGL0YJi89ojctPGoXHb1OtB09Rc8vPAXSIr2RXjU91rksPMa/Ir1uIRQ9WSAzPBzZIr3Sd3s9pFA2PDmLN7oKrXs9UlE2PDypS7o4hXs9RiszPBzeS7pdT3s9zyUzPHKjN7oP8Xs9pVA2PE32ZboMwns9ziUzPAVJZroeGns9SvovPG5mTLrm4Ho9r+cvPCMOOLphQns9r+cvPAr2ZrqZfXs9peY4PMWHN7q7sns9peY4PK2hS7rG93s9peY4PHzqZboNUHw9pOY4PIzSg7pXSHw99E82POHag7pdEnw9WSAzPDUVhLq3eXs9Rc8vPBHEhLoGAno917ksPGjBhrqNTXo9oTctPDSrZrqJTno9DFotPHFLTbpVCXo9oTctPNn3OboDKt48e082PJqszb1GU9k8NlA2PGt6y71A2d08YyIzPKZ3y72mWuQ8ixwzPDehzb2Y8NQ8eE42PJ09yb3WA9k8bhQzPGlCyb2c2ek8weAvPGpwy72O3fQ8IcsvPBJ/zb09YeQ8oLEvPLxSyb11J+I8pOY4PNHWz72lR908peY4PDquzb0uQOM8eE42PF7Uz73Yrdg8peY4PNB6y72OW9Q8peY4PO88yb07svs8wuEsPMuJyb0Z0/88gzYtPNVjy70qxwg97AotPLMnzb2wnAA9hqUvPDGQz73XtyA9uzosPNvqzr0z7eo8ehQzPELDz725+qk9pFA2PGyiHL0sXqs9UlE2PNwgIr0P66k9RiszPDMkIr3Tdag9zyUzPDmnHL2msKw9pVA2PD2QJ70CEqs9ziUzPPWSJ72CAaY9SvovPC4tIr33TqQ9r+cvPMq9HL32paY9r+cvPOSQJ71HMqo9peY4PLuhHL0uk6s9peY4PGMgIr3i66w9peY4PNmPJ71fPK49pOY4PBjwLL1O+6099E82PHDwLL3RM6w9WSAzPMzyLL0iKqc9Rc8vPFj5LL06tpo917ksPHkILb1nBp49oTctPKlHJ70igJ49DFotPEo+Ir2XMJw9oTctPCIvHb1i4zE9Th0pPLnIsb26ozI9lR4pPDblsr2FcjE9a0cvPJfjsr1+izA9Lz0vPLPDsb2BcDM9Lh8pPO38s71IPzI9M0wvPID6s70gOS491YwvPCLhsr0D4Sw9fGwvPNy5sb05Ay89kZovPCD0s72FFDI9K5wZPG/Jsb1UzzI9KpwZPHDlsr0anDM9K5wZPEj9s719ejQ9KpwZPMUQtb0rTTQ9RB8pPPkPtb3pDzM94UwvPGMKtb3Isi89iZwvPDf7tL3XJSk9vIUtPKvdtL2XuCg9BIMtPPHos70gASg95W8tPBXmsr1ovyU9XDotPLTBsb3OtZY9Lh8pPFyHkL2B+JU9lR4pPMyoj71unJY9bEcvPMyfj70NVpc9M0wvPNR9kL0cN5U9Th0pPNPPjr118pU9Lz0vPO7Cjr2GWJg91IwvPPiIj73oCJk9kZovPCNkkL1585c9fWwvPMGijr2lVZc9KpwZPG1tkb3pnpY9K5wZPLqIkL3nbJc9RB8pPKlrkb0W4ZU9KpwZPBSqj71YHJU9K5wZPKvRjr1M5ps9XTotPCZ5jr0atZs95W8tPItkj700V5w9BIMtPCAzkL2gyZk9iZwvPK89kb0uJp09vIUtPD/8kL22D5g94UwvPEhfkb2b58A9Ok42PDU/yb3cyb89fFA2PB19y72sC749jyQzPM2My72Hab89gxIzPLFOyb2rl749ilA2PNCwzb1ch7w9+CQzPH/Czb2oO7k9/uYvPAi4y73uGrs9d6svPOp+yb3N37Y9RuUvPAjvzb0wHsE9peY4PAA9yb2aCcA9peY4PN96y70k4749peY4PEyuzb0rq709pOY4PODWz70TWr099E82PJXZz71jIrs9WSAzPITsz7342rQ9Rc8vPAUi0L0yVaU917ksPHyl0L2Jvqs9RjQtPJ0qzr2ycq89Mz8tPHoPzL2fMrE9fdcsPOMHyr2pAUI9Lh8pPIrPjr17eEA9lR4pPNinj71tLj89bEcvPNKXj72CtUA9M0wvPEbAjr0T9z49Th0pPImGkL22hD09Lz0vPN52kL1Usjs91IwvPPZqj71oMD09kZovPK+Wjr0Vkzk9fWwvPAdJkL0dMUI9K5wZPLfRjr2ip0A9KpwZPCGqj739Kz89K5wZPMiIkL2Gvj09KpwZPHxtkb15hT09iRwpPJNrkb0a9js9CjcvPC9ekb2Dizc9G1IvPFY4kb1foiw917ksPDLbkL307jE9XTotPEnaj70h/DQ95m8tPLsMj70KWDY9BIMtPNFEjr3tSXY9glA2PMsAZ7abY3Y9Q1A2PNrFCrZkZXY9zSIzPO2BCLaGTHY9wCQzPK5WZLYKenY9mU02PPTKkLWxe3Y9dg0zPAwNi7URanY98eEvPDOaAraNU3Y9peQvPJqhXLYEgHY9X5svPFHjebUlLnY9pOY4PHvzsLaPSXY9peY4PFdiZ7amLnY99E82PJi4sLZYY3Y9peY4PMsYC7bPeXY9peY4PCOdkbXihnY9FL0sPMPqWrU/cnY9KjgtPK2o8LXdYHY9ZDMtPMrVSbYePHY9Rc8vPCC1qra5VHY91rksPBwEobYpMnY9WSAzPLEcr7aPjW89pFA2PB+Eu7o2J3A9UlE2PN/GoLoSVXA9RSszPDQuoLp9xG89zyUzPES/urp3rHA9pVA2PDvXibpN2nA9ziUzPCxJibpq0HA9S/ovPJ6PnroCWnA9r+cvPD59uLofV3E9r+cvPJ/oh7qf1W49pOY4PMYm2rq4hW89peY4PDygu7q33m499E82PE8F2rqpIHA9peY4PK7coLrrpXA9peY4PIfribo9SHI9oTctPH4vhrrkunE9DVotPCxnm7pue3E9ojctPM3esrpf0m89Rc8vPOmL1rrRjXE91rksPIh60LpbHm89WSAzPAEb2brX53Y9pFA2PHSjM7bi/nY9UlE2PHhekba6+3Y9RiszPJEYkbY35XY9zyUzPIrAMrZAGXc9pVA2PHWb2bbnFHc9ziUzPPZF2bY783Y9SvovPBFVkLYP3nY9r+cvPOAwMbYbCXc9r+cvPE3i17Y36HY9peY4PPvDM7ZU/3Y9peY4PIBokbbgGXc9peY4PLen2bYONnc9pOY4PESpGbdJNXc99E82PB6iGbfeL3c9WSAzPEJwGbeCIHc9Rc8vPGD3GLeN+nY917ksPFRtGLdT8nY9oTctPAdu0bYZ43Y9DFotPKi6jrYe0HY9oTctPBb0M7ZcNAk9pFA2PHZqMr0kmws9UlE2PKJFLb09qA49RSszPOlELb2Hmgw9zyUzPJJqMr3pJA49pVA2PP0VKL0WWhE9ziUzPFMUKL1F5BY9S/ovPARDLb0k4hU9r+cvPIVhMr1jHho9r+cvPEAZKL0aVQY9pOY4PFeEN70OuAg9peY4PHNqMr1n3QY99E82PHGEN72OKws9peY4PL1FLb2brw09peY4PDgWKL3AQys9oTctPNNnKL1EsCY9DVotPLA/Lb3N+Sc9ojctPP4LMr33JBU9Rc8vPAuHN72KOi891rksPPuKN72Alwo9WSAzPCWFN72rfJw9Lh8pPPD8s70P45w9lR4pPDflsr2re509bEcvPJvjsr1JFZ09M0wvPIH6s706Q509Th0pPLnIsb0v7509Lz0vPLTDsb1fGJ891IwvPCPhsr1Us549kZovPCP0s71vxJ89fWwvPN25sb2s95s9KpwZPMgQtb3fZpw9K5wZPEn9s71WDpw9RB8pPPsPtb1AzZw9KpwZPHHlsr2pKp09K5wZPHDJsb1GVaM9XTotPLfBsb1mNKI95W8tPBjmsr2r2KE9BIMtPPTos72NW549iZwvPDn7tL0LoqE9vIUtPK7dtL35rJw94UwvPGUKtb2ptnw9pFA2PG33mLrJOn09UlE2PJ9bsrqJBH09RiszPFfDsrpngXw9zyUzPKtGmbr30n09pVA2POfzz7pekX09ziUzPFB10LqOcnw9SvovPArbs7rk73s9r+cvPOJVmroG33w9r+cvPBKg0bpHvnw9peY4PBrsmLqIQn09peY4PM9MsrpX3H09peY4PGvhz7omi349pOY4PLuW8bpBgH499E82PO+r8br2M349WSAzPFdA8ropXH09Rc8vPJjt87o6SHs917ksPEta+Lrhh3s9oTctPEdK0rqNXHs9DFotPHXytbqX03o9oTctPMjjnboFgfM8mFA2PJkJ1r21wO0881A2PNAD1L39HvU8TigzPH/0071qgvs8cCUzPL/51b1ZZOg8lE82PMHx0b0eEPA8SB0zPKTg0b0fkgQ9w/EvPETL072iswg9n+YvPLnK1b2ptgI9Qs0vPDW10b1bRfg8pOY4PGkF2L1AXPI8peY4PNwL1r0GfPk89E82PAgD2L0+s+w8peY4PAEG1L3RS+c8peY4PDH00b2Yrxg94w0tPEZ80b0AHhg9Lk4tPN18070VJR49JTYtPPdT1b06BA09Rc8vPDrD172Jvyo91rksPLtN171b/QA9WSAzPGry170MR689pFA2PFFBMr1IirA9UlE2POqCN7098a49RiszPIyDN73Ql609zyUzPNtCMr2gu7E9pVA2PEa1PL0i9a89ziUzPGW1PL1Voao9SvovPDqFN71k/ag9r+cvPCZQMr0wHKs9r+cvPJSsPL2ohK89peY4PBpBMr23xLA9peY4PNSCN72N/LE9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ujZTOhQ267sxM4Y91FP6Opct67sDcoU901P6OhTV17s4uIQ901P6Og9LxbsSBoQ91FP6OluUs7vuUIM9ujZTOh++orvRW4M91FP6OsO1oruvBIM901N6Oab4orsgiS490lP6N8T96b31Cyo90lP6N3Cn6L3S8SI90lN6OaXC6L1MKSc91FN6OTEc6r28fyc90lP6N106573MUB891FN6OQpX5703UCA9ujZTOr3M6L3WdiQ9vDZTOmMm6r1RURw9vDZTOn1i573tZTM90VP6NzdH671pLyU90VP6N4O35b04vxs901N6OZLb5b3naRg9ujZTOkHo5b3/7xc91FP6OhHq5b2r4xs901P6OiFk57377x8901P6Oi3O6L0yFCQ91FP6Otgn6r2ZtSg9ujZTOkRv672TTyg91FP6Or9w673Afys901N6Odpk672IY7Q90lP6N/xibb2aQrY90lP6N/b3cb35M7s90lN6Ocbscb3TCbo91FN6OU5dbb2AWLc90lP6N3ibdr2OKbw91FN6Ofp0dr3dAL09ujZTOjXncb0nGrw9vDZTOvxdbb3A2b09vDZTOtlhdr3hrrI90VP6N1q/aL3lhLg90VP6N01Fe702G70901N6OVnqer3nqr49ujZTOnDMer0A5L491FP6OizIer1/F74901P6Oh1fdr20Qr0901P6Omrmcb2jZbw91FP6OhRebb0kL7s9ujZTOujFaL1JgLs91FP6OibGaL0i97g901N6OTzEaL2HYMc80lP6N5iHmL0R4sc80lP6N8iclr0AGcE80lN6Ob2Clr1aCMA81FN6OeJ1mL0cfMo80lP6N6uulL34z8I81FN6OUeKlL06k748ujZTOl15lr2zWL08vDZTOn1umL34/788vDZTOn9+lL08Ssc80VP6N+txmr02Jdk8AAAAAEwUlb0Gjs080VP6N32wkr02pMQ801N6OcyKkr3JjcE8ujZTOrB9kr3eHME81FP6OtJ7kr0cmb8801P6Os98lL33Nr4801P6OgV4lr139rw81FP6Om5tmL31QLw8ujZTOsldmr2g17s81FP6Oghdmr1OIr8801N6OQ5jmr0Q8qI90lP6N3+V571vpKE90lP6N8726L333qQ90lN6OUna6L1XsaY91FN6OQly573vc5890lP6N+dP6r0lx6I91FN6OVw06r0vEaY9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1FN6OUDoQ7yhNIs9ujZTOkGVN7xkTIo9vDZTOlKwK7xeH4w9vDZTOv3QQ7yfwIU9AAAAABNvLbyI04Y9AAAAAGxhOLxc94Y9AAAAANLIQ7wImoo90VP6N8m7ULxLa4w901N6OVZ4ULyjD409ujZTOsNgULweJ4091FP6OmVdULxBNIw901P6OqrNQ7yyRos901P6OveRN7yxXoo91FP6Oq6sK7yqHE490lP6N1pw8r0ylEk90lP6N+2e8b1KQ0U90lN6OTqs8b0Y8kk91FN6OZp48r1/KkY90lP6NxC88L0t7EA91FN6OS3N8L0Vq0M9ujZTOu2w8b2ccEg9vDZTOpF68r0/AD89vDZTOgbU8L00gFY9AAAAAEZL8r3521I90VP6N2gy870z7FE9AAAAACaC8b34uT4901P6Ov7U8L3EcEM901P6Opix8b2KOUg91FP6Otp68r0HSE09ujZTOnYw872NE0091FP6OmIw871Zt04901N6OQAx873UxcM80lP6N8AIoL2cfcM80lP6N+ornr3x0rw80lN6OXYrnr0rXLw81FN6OT4KoL1rMcU80lP6N6BSnL0F6L081FN6OaFJnL2AWbo8ujZTOtgqnr0eqLk8vDZTOgMJoL0oPLs8vDZTOipHnL3ZONI8AAAAAPfhn739b8Q80VP6N/nsob32WdM8AAAAAJB1nL132ro801P6OtBGnL0B/7k801P6OsIqnr1CRbk81FP6OtgIoL38F7k8ujZTOnzhob0/rbg81FP6Og7hob0kA7w801N6OXfkob1pspM90lP6Nwj08L059pE90lP6N3/G8b1evJM90lN6OZ238b0K6pU91FN6Ob7d8L3yx4891FP6N+6F8r2gaJE91FN6OR5+8r2LZJQ9ujZTOlyy8b03upY9vDZTOhrW8L09ApI9vDZTOkR78r13jY49AAAAAIDm8b37nYw9AAAAAIiV8r0BU4o9AAAAAFg28738aY0901P6N+Yy870qAI8901N6OSIx873QlY89ujZTOnww870xq4891FP6OmUw870wGJI901P6Otx68r2QfJQ901P6Opux8b3215Y91FP6OgPV8L2dMHQ90lP6N1fPPrnOPXQ90lP6NyV5MbnYB3Q90lN6OYp3MbkF83M91FN6OYThPrlpWXQ90lP6N9yUJLm5IHQ91FN6OX6CJLna83M9ujZTOt52Mblz3HM9vDZTOlvfPrn5C3Q9vDZTOnWEJLnkJHQ90VP6N+LKTLkDCXQ901P6Or6EJLn98HM901P6Osd2Mbk72XM91FP6Og3fPrlHxXM9ujZTOia9TLm3wXM91FP6OrG8TLk73nM901N6OXfATLld0FE90lP6N9P1YrzJKFM90lP6N9eDVrxKMVA90lN6OUfPVrwCXE491FN6OWlbY7ydQlU90lP6NyBHSrzHM1I91FN6OQCJSrzDF089ujZTOi/rVrzVF009vDZTOlV4Y7xfFVE9vDZTOkipSrw+iVg9AAAAAM2JYbwOf1A90VP6N1jcb7y8PVs9AAAAAA9oSrx07FA901P6OuetSryK704901P6OirvVryI6Uw91FP6Ond8Y7zcDks9ujZTOoxPcLzy2ko91FP6Ot5TcLxAekw901N6OVIxcLzXJos91FP6N/3M873e24g90lP6N8xU9L2BK4o90lN6OQNc9L3FmYw91FN6OWzQ870BX4Y90lP6NzTL9L04qoc91FN6OdzT9L0qp4o9ujZTOnte9L1sIo09vDZTOqnR8730Iog9vDZTOpnW9L2CVIg9AAAAAPjF871e5IM90VP6N0kw9b1zJoU901N6OTg39b0vmIU9ujZTOp459b1vqIU91FP6OvY59b0zNIg901P6Ov7W9L3TuIo901P6OtNe9L3zNY091FP6OtfR872FDnk90lP6N77BQLnNKnk90lP6N0v4TrmIZHk90lN6OS4fT7lpS3k91FN6OVTPQLmnN3k90lP6N4CYXblTeXk91FN6OXfkXbnteXk9ujZTOo4tT7muYXk9vDZTOpHdQLlhkXk9vDZTOvT2Xbl1l3g9AAAAAC5eQbneQnk90VP6NwjlbLkIjnk901N6ORAjbbmTqHk9ujZTOlg5bbldrHk91FP6Ooo8bbnSlHk901P6Opz5Xbn8fHk901P6OqAvT7neZHk91FP6OpzfQLmNtos90lP6N5+oXby2xYw90lP6Ny63arzDaY490lN6ObaEarxIaY091FN6ORlXXbygaY090lP6N+YbeLzLUI891FN6OYUBeLx1BY89ujZTOvxxarxMCI49vDZTOstBXbxgA5A9vDZTOkzvd7zEY4g9AAAAAObwXrzztYk9AAAAAE2jd7zHCI490VP6NzX+grwgPpA901N6OX7kgrzRBZE9ujZTOobbgrxZIpE91FP6Oj3agrzkHJA901P6Oq/sd7yyG48901P6OlBvarwFH4491FP6OsA+XbzC6bo90lP6N7qbf72mzrw90lP6NwHkgb0fUL890lN6OYbDgb2FPL491FN6OadCf71zpr090lP6N8z+g72QF8A91FN6Ofrgg72hQcA9ujZTOle3gb3Aer89vDZTOq0lf72598A9vDZTOlzUg72HpLg9AAAAAPsThL2IKL490VP6N0sghr3+wMA901N6OaH3hb3OosE9ujZTOqTphb0Qw8E91FP6OqTnhb2/F8E901P6OpDSg70hZMA901P6Opm1gb03qL891FP6Ookhf71dwdo80lP6N7LNxL0Df9U80lP6N099wr0F0Mw80lN6Oe1Xwr3CwNA81FN6OdywxL1/I9M80lP6N60swL1U0sk81FN6ORD4v714lsk8ujZTOi1Kwr0WGc08vDZTOvikxL37dcY8vDZTOqvmv70cu+08AAAAANbnxL0kEOE80VP6NwYdx7192eU8AAAAAJ23wL1ZfdE80VP6N4TIvb3IK8c801N6OUmOvb1wpcM8ujZTOmF6vb2IJMM81FP6Ooh3vb0T+8U801P6Oi/kv72GIMk801P6OjZIwr1qk8w81FP6OkSjxL0U6NA8ujZTOlv2xr1AUtA81FP6OvT0xr3eANU801N6OR4Ax72+5cQ90lP6N4NInr34YcU90lP6N7brn73TBMc90lN6OdfUn72ju8Y91FN6OREvnr0mXsU90lP6N4uHob0cJsc91FN6OYdyob13oMc9ujZTOrHMn72ZZ8c9vDZTOlQnnr0Bzcc9vDZTOvZpob1YRMI9AAAAAAMcoL3t4sE9AAAAAOaeob3OQMU90VP6N28eo71cPcc901N6OTwHo7328Mc9ujZTOgj/or2cCsg91FP6Otn9or3Z5Mc901P6Or1oob2xtsc901P6OobLn70qgMc91FP6Ojkmnr3sfF490lP6N5Tk9L1xCVo90lP6Nzxr9L2c41c90lN6OVVi9L17vFw91FN6OS3b9L39X1Y90lP6Nw7c872PS1M91FN6OUXU8726FVc9ujZTOkNf9L32GFw9vDZTOoPX9L2/J1I9vDZTOiPS870E82E9AAAAAGzy9L3cPmM90VP6NyZI9b0tC1w9AAAAAM35870P/lE901P6OtXR871T+FY9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1FP6Ooshz7xH8jI901N6Obsdz7xQPsI80lP6N2aap70aWsE80lP6N0Wnpb1ivLo80lN6OTKZpb1w4ro81FN6ObuOp728pMI80lP6NwnLo72iSrs81FN6OcO6o737Rbg8ujZTOh6Upb3tMbg8vDZTOiWJp716mrg8vDZTOnO2o73leNA8AAAAAB+Up72FscM80VP6N6O8qb1Y1tA8AAAAAHIMpL0rOLg801P6Oti1o73u67c801P6OmSTpb2Uz7c81FP6OlmIp70UVbg8ujZTOj+kqb0x6rc81FP6OmCjqb1CQbs801N6OU2qqb0N+3k90lP6N6FZxbm3Fno90lP6N+grz7kaZXo90lN6OUNhz7n1Tno91FN6OVt/xblwHXo90lP6Ny8k2bledXo91FN6OVh12bklgno9ujZTOgR1z7mpbXo9vDZTOoaTxbmUlXo9vDZTOquM2blbgHk9AAAAAE/Fzrm9IXo90VP6N/9047lvhXo901N6OfC/47mlqHo9ujZTOpHa47mtrXo91FP6OmLe47ktmno901P6OgSQ2blMhno901P6Otl3z7kNcno91FP6OmmWxblN6pY90lP6N9e0xrwtPJg90lP6Nwq5zrwf6Jo90lN6Obi3zrzMupk91FN6Odyixrzs2pg90lP6N4zU1rx55ps91FN6OVvk1ryX5Zs9ujZTOji3zrxtwpo9vDZTOnqhxrwbBJ09vDZTOuvk1ryKapk90VP6Nw8k37xb6Jw901N6Ofkn37wPJJ49ujZTOm0p37woUZ491FP6OqEp37zqLJ0901P6Ov/k1rzNCZw901P6OiW3zrwX6Jo91FP6OkehxryWhNc80lP6Nz5DiL2Mfdk80lP6N7gfhr1XtdA80lN6OYEHhr1zac481FN6OTcsiL251d480lP6Ny/+g70j/NM81FN6Of7eg717bM08ujZTOoP+hb2QH8s8vDZTOhIiiL0P9s88vDZTOoTVg73RX9Y80VP6N2dsir3VWfI8AAAAAAVhhL3pYs8801P6OirUg71b9Mw801P6Ojz9hb1Jp8o81FP6Op8giL27+Mg8ujZTOvE/ir24e8g81FP6OlA+ir3PY8w801N6OVlLir08sHY91FP6N0GVVTQIsXY90lP6NypXSzTGsXY90lN6ORPYRzT4sHY91FN6OXljUjTAsXY91FP6N5urQDSOsnY9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0VP6N131GLfcL3c901N6OT9uGbdJNXc9ujZTOjCgGbcONnc91FP6OoOnGbfgGXc901P6OjKk2bZU/3Y901P6OvxkkbY36HY91FP6Ou+8M7Yk4hU90lP6N4ZhMr1H5BY90lP6NwRDLb0+qA490lN6OepELb2Imgw91FN6OZJqMr1iHho90lP6N0EZKL0XWhE91FN6OVUUKL0lmws9ujZTOqNFLb1dNAk9vDZTOnZqMr3qJA49vDZTOvwVKL3N+Sc9AAAAAP8LMr33JBU90VP6NwuHN73AQys9AAAAANRnKL2brw0901P6OjgWKL2OKws901P6OrxFLb0PuAg91FP6OnNqMr1n3QY9ujZTOnGEN70bVQY91FP6OleEN71/lwo901N6OSWFN73j73s90lP6N99VmrqOcnw90lP6Nwbbs7qKBH090lN6OVLDsrpmgXw91FN6OahGmboG33w90lP6NxCg0bpdkX091FN6OUx10LrLOn09ujZTOptbsrqotnw9vDZTOmj3mLr30n09vDZTOuTzz7qX03o9AAAAAMPjnbopXH090VP6N5Tt87r5M34901N6OVRA8rpAgH49ujZTOumr8bomi3491FP6OraW8bpX3H0901P6Omnhz7qIQn0901P6OspMsrpHvnw91FP6OhbsmLqiswg90lP6N7rK1b0ekgQ90lP6N0TL073+HvU80lN6OX70071qgvs81FN6Ob751b2otgI90lP6NzW10b0fEPA81FN6OaPg0b21wO08ujZTOs8D1L0FgfM8vDZTOpkJ1r1aZOg8vDZTOsPx0b0VJR49AAAAAPZT1b06BA090VP6NzrD172Xrxg9AAAAAEZ80b3RS+c801P6OjH00b0+s+w801P6OgEG1L1AXPI81FP6OtwL1r0HfPk8ujZTOggD2L1bRfg81FP6OmkF2L1b/QA901N6OWny171l/ag90lP6NyZQMr1Voao90lP6NzmFN70+8a490lN6OYyDN73Ql6091FN6OdxCMr0xHKs90lP6N5SsPL0h9a891FN6OWi1PL1HirA9ujZTOuuCN70MR689vDZTOlFBMr2gu7E9vDZTOke1PL3I/Z89AAAAANisMr3Bp6E9AAAAALtYPL36cqs90VP6N3bXQb2Z87A901N6OSPYQb0Y5bI9ujZTOlbYQb0pLLM91FP6OlvYQb2N/LE901P6OkO1PL23xLA901P6OtSCN72ohK891FP6OhpBMr20BM480lP6N9qfkL1C+c480lP6Nz+Sjr3hpsc80lN6OeN0jr3nEMY81FN6OeeCkL32VdI80lP6NzSGjL3l88k81FN6OfZijL3j7MQ8ujZTOhZqjr0QLMM8vDZTOst2kL3z4cY8vDZTOuBXjL2vp908AAAAACm4kL2tccY801P6OkpWjL0sicQ801P6Ooxojr07wsI81FP6Og51kL3cibQ90lP6N5c60r31CLQ90lP6N3BB1L1Z87g90lN6ObgX1L1/Ebo91FN6OfUH0r0JMLI90lP6N85H1r0sbbc91FN6OaIe1r2Xxbo9ujZTOkYI1L3/F7w9vDZTOrn20b3XV7k9vDZTOkMO1r1Vwak9AAAAAJm30r1Vmqo9AAAAAI+R1L0+8Kc9AAAAAKd+1r1RG7A90VP6N09K2L1X1LU901N6OUwZ2L282bc9ujZTOvMH2L2lI7g91FP6OngF2L3unbk901P6Ou4L1r0xCLs901P6OhAG1L0RYrw91FP6OkP00b0v83U90lP6N+qrY7fqCHY90lP6N/F6LLdc/HU90lN6OetbLred4nU91FN6OWtRZrcJInY90lP6N3zw+bYZF3Y91FN6OR9Z/ba493U9ujZTOqkML7eF3HU9vDZTOlEnZ7cdE3Y9vDZTOpzX/rZ03XU90VP6N2YKkrf+IHY9AAAAANTKKLeMEnY901P6OqMO/7YM93U901P6OhomL7eo23U91FP6OhFGZ7duwXU9ujZTOrbak7dhwHU91FP6Onjsk7e9yHU901N6OQtfk7cxfG090lP6N8W4I7tjMW490lP6N/1xD7tXgm090lN6ORmgELuipWw91FN6OZpCJbsXBm890lP6N54u+bpGWW491FN6OYhc+7pUQW09ujZTOp8PEbvbVmw9vDZTOjrGJbvvGW49vDZTOlFA/LrAt2w90VP6N1sHOrvjEG4901P6Ot1g/LoKOG0901P6OowfEbuZS2w91FP6OgjZJbsvWWs9ujZTOs8/PLsbTGs91FP6OiZVPLu6tGs901N6OWyqO7scPHc90lP6N5KNT7eQVnc90lP6N/Agh7d9Z3c90lN6OaYkh7faS3c91FN6OWJcT7dxbHc90lP6N1S2qrfOgXc91FN6OUsAq7fBbXc9ujZTOsAlh7eZUXc9vDZTOox2T7eiiXc9vDZTOu4Eq7cAQ3c9AAAAAP9UqLcvgnc90VP6N1A207c0nHc901N6OX5I07dmpXc9ujZTOm1S07e1pnc91FP6OvBT07fAinc901P6OrEFq7eobnc901P6OgAmh7dsUnc91FP6Onx6T7d93g090lP6NyaQRr1Djg490lP6N0GdQb3njwU90lN6OTeZQb18yAM91FN6OTiTRr1CqRE90lP6N5CgPL01CQg91FN6OZiUPL3JOgI9ujZTOr2XQb3KFgA9vDZTOhKRRr2IgwQ9vDZTOoaTPL2giSE9AAAAAARJRr30eg090VP6N46JS73ozh89AAAAAE6lQb3qeiQ9AAAAACX6PL24AgQ901P6OmCTPL3qwAE901P6OoeXQb1hH/881FP6OsOQRr1yBfw8ujZTOnB/S70f3vo81FP6Og1/S71XDAI901N6ORqCS71bJ3490lP6N6MDDbu4+X490lP6NyPJIbtgzH890lN6Od3pILt293491FN6OeMFDLtIo3890lP6N6GgOLs8UoA91FN6Oa3IN7tIDYA9ujZTOhSXILuVQ389vDZTOuO3C7t7gYA9vDZTOrFqN7vzj3w9AAAAAG8TELu5sn09AAAAAC8WObuPLYA90VP6N/W1Ubt9yIA901N6Oa2OULs9/4A9ujZTOt4nULsPB4E91FP6Oi0ZULs8iIA901P6OkRdN7veEoA901P6OkCLILt2Tn891FP6Or+sC7sozxM90lP6N01q3b3Mug890lP6N8+d271LXwY90lN6OYfC27164Ak91FN6OU+U3b0BNA490lP6N+a62b3OogM91FN6Oe7g2b3C5wI9ujZTOiTQ270iPgY9vDZTOnGi3b0kiP88vDZTOhvw2b2DVhg90VP6N0ku370Tbf4801P6Okby2b33aAI901P6OhXS2705uQU91FP6Onek3b1Rsgk9ujZTOvJm372RJgk91FP6Og5p372QhA0901N6OTFY3718OK090lP6N4HyRr1jzK490lP6N3LsS71DeLM90lN6OUjvS70VO7I91FN6OWrrRr31Hq890lP6N2PXUL1kWbQ91FN6OeXjUL1jM7U9ujZTOlXwS719ELQ9vDZTOgXsRr2OQ7Y9vDZTOj7lUL36Sa890VP6N7bEVb3MNLU901N6OTPJVb3OS7c9ujZTOr/KVb08mLc91FP6OvTKVb2WibY901P6OnDlUL2vcrU901P6OnrwS72LU7Q91FP6Oh3sRr3cfK890lP6N28y2r37tK490lP6N+kH3L0ZIbM90lN6OSHi271egLQ91FN6OU0E2r11t6w90lP6N3ja3b0VZLE91FN6OV613b2NxLQ9ujZTOiPU272KVrY9vDZTOpX02b3OGbM9vDZTOqGm3b1ekaM9AAAAAA8M3r1Fgqo90VP6N9em371Xla8901N6OeV6370hYLE9ujZTOlZr372qobE91FP6Ohtp371YWLM901P6OoWk3b15ALU901P6OiTS2720mbY91FP6OlXy2b3128E90lP6N6QXkL1mpcI90lP6NwDukb1QXcQ90lN6OWXNkb0MzsM91FN6OUfrj7175sI90lP6N8XBk71zwsQ91FN6Oc6ok73nAMU9ujZTOonBkb3GhMQ9vDZTOnTcj71zcMU9vDZTOsuek71kYb89AAAAAI4vkr20P789AAAAALngk71OicU901P6Ol2dk71CGMU901P6Ote/kb3insQ91FP6Olfaj71PlHU90lP6N6zsBbh3qHU90lP6N+uT37cyk3U90lN6Od6e4Lc8enU91FN6OeGsBrhUwnU90lP6N+sCt7fMrXU91FN6Oebot7dSi3U9ujZTOhYB4bercHU9vDZTOgvlBrhKpnU9vDZTOjxYuLfvxnU9AAAAAFtSA7h1gHU90VP6N/1rHrhE0XU9AAAAAI2J3be56nU9AAAAAMhOt7c6pXU901P6Oj5ouLcxinU901P6OjQP4bdOb3U91FP6Oh7tBrgjVnU9ujZTOhRYH7iPVHU91FP6OhphH7guYXU901N6OT8ZH7hsk2k90lP6N5PLg7vmfGo90lP6NwB4bLvlgGk90lN6OezebbsBYWg91FN6OVqwhLu+m2s90lP6N8WXUrtmomo91FN6OSbrU7tiI2k9ujZTOopjbruO8Gc9vDZTOmr7hLsdR2o9vDZTOhJ4VLufnWg90VP6N3RakrsROmo901P6OjaMVLsGFmk901P6Onx2brt94Gc91FP6OiQGhbuJrGY9ujZTOhCXk7v9mWY91FP6Ou+ik7tQLmc901N6OfRDk7uwnnc90lP6N/4rALjGuXc90lP6N82TGLhW03c90lN6OVyPGLj1t3c91FN6OZECALj9zXc90lP6Ny8LM7i97Hc9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AAAAAMuMvb06ipo90VP6NyewvL2kQZg901N6OSDmvL0mc5c9ujZTOiv5vL2mVZc90lP6OuL7vL0Y4ZU90lP6Oj6/vr1uapQ9ujZTOi5owL3cUJQ90lP6OqxpwL1kHZU901N6OcRdwL3qNEU90lP6N5I0wr0JGEU90lP6N0KGwr1Uwkc90lN6Ofqywr37H0c91FN6OTlTwr2TIkU91FP6N1nlwr1Ghkg91FN6OaMcw73lvkg9ujZTOlfDwr0b2Uc9vDZTOlhewr0Zxkk9vDZTOv0ww73W9z89AAAAAJctwr3pij49AAAAAHx5wr1WSz49AAAAAGrgwr1iw0U901P6N75Xw70+mUk901N6OQWVw738Aks9ujZTOpirw72qNks90lP6OtKuw73K80k901P6OuYzw72O80c901P6Ou5fwr30Zp891FP6N6CcnL3/EZ890lP6N5OJm72feZ090lN6OSaFm71F1J091FN6Od2enL3uAJ890lP6N9twmr0jK5091FN6OZpsmr3N4pw9ujZTOgmEm73bP509vDZTOsGfnL1lf5w9vDZTOhtsmr2BdqI9AAAAACOZnL2TyJ8901P6N0Gvnb0Vm6I9AAAAAKCNmr3Q3J490VP6N29Smb3SzJw901N6OcVWmb1REpw9ujZTOlFYmb2pKp0901P6OuGfnL2blJ09ujZTOka/nb3qfp090lP6OuO/nb1xLJ4901N6OfS6nb3yO3A90lP6Nxdhg71unWs90lP6N4iBg70Otm890lN6OW6Yg72/1XI91FN6OcCDg71LDGg91FP6N8ufg72X62w91FN6OcSzg70HKXE9ujZTOimhg71BqnM9vDZTOvWQg70ztW49vDZTOii7g73PA3Y90VP6N/hGg70CdV49AAAAAGx5g70VX2U901P6N/XBg708cWo901N6OTHXg72BT2w9ujZTOgTfg73Uk2w90lP6OiPgg72T9m4901P6Oja8g70HXnE90lP6Ommig72dyHM901P6OtiSg70FM3Y9ujZTOheLg73HNHY90lP6OqGNg72yJnY901N6OUl5g73sYC490lP6N8ZMmr0CCy490lP6N0tzm71CZDE90lN6OfN+m71cETI91FN6Ofphmr045Cw90lP6N7eZnL1VjDA91FN6OeuenL3yoTI9ujZTOk6Dm73DajM9vDZTOtNqmr1+4zE9vDZTOs2fnL2gsC490VP6Nysmmb1Fsis90VP6N6zGnb1zxi8901N6Od3Bnb1PNzE9ujZTOizAnb2EFDI901P6OuyfnL1VzzI90lP6OuyDm70bnDM901P6OhVsmr04RTQ9ujZTOsdWmb1N0DI901N6ORNKmb2qhJQ91FP6N+Rwwr0UPZU90lP6N0zAwb2zapM90lN6OcXowb1Yl5I91FN6OaWiwr2FIpY91FP6N64Ewb0DR5Q91FN6OcMmwb3hvpI9ujZTOq73wb2Z4ZE9vDZTOvy0wr3Ul5M9vDZTOlEzwb1VRZg9AAAAAPsPwr0xxZM901P6N9obw72AwJk9AAAAAE7CwL3MfpM901P6Oh01wb06/pA9ujZTOj1rw72jvZE901N6Od1Vw704CII91FP6N9Rng71mP4A90VP6N9dTg72MnHw90lN6OUOLg704Z3891FN6OTqjg71w1Xs90lP6N9JFg73PeXk91FN6OXd8g72sPXs9ujZTOoSfg72LsX09vDZTOhi5g70NvHg9vDZTOgyQg71fF4g9AAAAACcMg72oXYM901P6N7aGg72NC3s90lP6Ommig70Cc30901P6Oje8g72VC4A9ujZTOtXcg71y8IA901N6OaXFg72sKkc91FP6Nyrgw72Sp0g90lP6N4p3xL1Dtkw90lN6Oa+0xL04Eks91FN6ObEexL3Emkk90lP6N+gWxb3tUE491FN6OXZQxb2XNU49ujZTOqjKxL2Ngkw9vDZTOqo1xL02CVA9vDZTOkpkxb1KkT89AAAAAG5lw70hT0A9AAAAAEyPxL01zko90VP6N2zAxb1TGVA901N6Odbsxb3891E9ujZTOoD8xb1dPFI90lP6Or7+xb0bSFA901P6OiBnxb1bbE490lP6OsjNxL0st0w901P6OvE4xL0PFYc90lP6N9I9hL2ehIU90lP6Nzf0g72lO4M90lN6Of8thL27gIQ91FN6OV9yhL1pY4Q91FP6N2q2g73cEoI91FN6OSP0g70uY4I9ujZTOtlChL1tjoM9vDZTOqOEhL1vOIE9vDZTOtMKhL3JEow9AAAAAOnEg711nIg90VP6N9aahL3a6ok9AAAAAJ99g72244g9AAAAAHU9g706GYE901P6OhAOhL1CRII90lP6OtNFhL35tIQ9ujZTOivQhL2zj4Q90lP6OijShL3buYU901N6OTrChL12x6A90lP6N1QGob0fQaA90lP6N9Pin71es5490lN6OZj/n71AAZ891FN6Od4oob2u/p891FP6N0/Gnr1CcZ491FN6OQzbnr1MIJ49ujZTOsAJoL3VWp49vDZTOoA0ob3H3p09vDZTOqHinr1/O6Q9AAAAAG6voL26PaE90VP6Nz03or0QQ54901P6Ois2ob3Dip49ujZTOtJior0hP58901N6OXBXor0yYWM91FP6N7Tug70abWE90lP6N3kkhL2h92U90lN6OfA7hL2oMGg91FN6OcUEhL2WAF891FP6N+ZghL3Tn2M91FN6OeN7hL3to2c9ujZTOpZEhL1Z9mk9vDZTOuYMhL3AU2U9vDZTOtOFhL0WA1o9AAAAALvDg709lVg9AAAAAMH2g71mAFY9AAAAAFkshL2Nl1w901P6N7ymhL0wTmE901N6OUvFhL29CmM9ujZTOo3QhL1BSmM90lP6OinShL0f4Wc90lP6OtJFhL1LaZE90lP6N/oVxb1d75E90lP6NxFwxL1s5I890lN6OcusxL3CDY891FN6OXxPxb2nz5I91FP6N+fGw73Mz5A91FN6OQ4ExL1yI489ujZTOp3CxL1xMY49vDZTOktjxb0uE5A9vDZTOoQaxL0CEJY9AAAAAHmOxL3KzZA90VP6N2/Axb1H5ZU9AAAAABryw73gB4890lP6OrrFxL34EY4901P6OiBmxb3iOI09ujZTOoH8xb2yFo090lP6Or/+xb03KI4901N6Odfsxb0GsSs90lP6N/X0nr081Ss90lP6NxAcoL3b/S490lN6OcoPoL3eUS891FN6Oevnnr0kcys91FP6N6A9ob3eki491FN6OVk4ob2VKDA9ujZTOs8LoL2apTA9vDZTOkfknr2cuS89vDZTOng2ob2yuSU9AAAAAFc7oL0oXyU9AAAAANRIob1AuiQ9AAAAAKBVor0c+So901P6NzZeor0oLi4901N6OZ5ior2jXC89ujZTOj9kor3ahy890lP6Onhkor244y8901P6OjM2ob1EUzA90lP6OjwLoL0i1jA901P6OsHjnr139Yo91FP6Nzjphb388Ik90VP6NyJ+hb23uoc90lN6OaiBhb2XzIg91FN6OdHphb0wUYk90lP6N5oMhb1rwYY91FN6Oe4dhb2z6YY9ujZTOoSDhb3aAIg9vDZTOhnqhb360YU9vDZTOlclhb29VpA9AAAAALtNhr13KY89AAAAAAfphb2QE4w901P6N2xUhr2AOo49AAAAAN9+hb2+44c901P6OiTqhb3LFIk9ujZTOiBZhr1N94g90lP6Ok9Zhr0744k901N6Od1Xhr0+i0090lP6NwFvxr3qWlA90lP6NxgLx71ChVQ90lN6OawTx72/QlI91FN6OeuExr1tYFI91FP6N72Ox728llY91FN6OV6Vx73tD1Y9ujZTOm8Xx738/VM9vDZTOhqOxr07JFg9vDZTOuGXx73wnEs9AAAAAEjux71fNVQ901P6N84ByL1Un1g901N6OdMLyL2hP1o9ujZTOoQPyL1PSFY90lP6OvkXx70uSaE90lP6N8Xmpb12AaE90VP6N/+vpL2tX5890lN6OdXBpL1hfp891FN6OVf4pb1BHqE90lP6Nwh1o71uVJ891FN6OVKLo73axJ49ujZTOnrIpL1Q1p49vDZTOuD9pb3crJ49vDZTOnOUo71Zx6Q9AAAAAJKypb3Yk6E90VP6Nz0hp72aIqQ9AAAAAEKOpL1xnaQ9AAAAAKdco73ulJ4901P6OsGVo729rp490lP6Om3JpL1Ovp4901P6Oqn+pb1q3Z49ujZTOvozp72wkp8901N6ORcvp70xsFo91FP6N3D4hL3D01g90lP6N0lShb1pC1090lN6OR51hb1eKF891FN6OcgYhb1HiVY91FP6N+Wwhb2101o91FN6OS/Zhb0tmV49ujZTOvWBhb3nzWA9vDZTOrMkhb1maFw9vDZTOgfohb0P/FE9AAAAAHO5hL1JnVA9AAAAAHIOhb3CQ1Q901P6N30Yhr2Wo1g901N6ORxGhr0pQFo9ujZTOutWhr0Ze1o90lP6OlJZhr01olw901P6Oibqhb0X1yo91FP6N+mBo72wnSo90lP6N9OqpL1huy090lN6OcfApL1m8S091FN6OfKPo71p3ik90lP6N1rbpb04by091FN6OSP1pb1A4i49ujZTOlzIpL0rFi89vDZTOg2Vo718vS49vDZTOnz9pb32zSQ9AAAAALdlo73PmSQ9AAAAACt5pL386SI9AAAAAOuTpb0/Qik90VP6N2oXp718RC0901N6OUQsp70Dry49ujZTOqAzp7087S4901P6Oqv+pb1fDC890lP6OnDJpL39Py8901P6OseVo72rBI091FP6N76Ox71uB4490VP6NxwLx70+8os90lN6Oa4Tx72A6Yo91FN6OV+Vx71Eb4890lP6NwRvxr2CE4091FN6Oe+Exr3pLIs9ujZTOnEXx73AIoo9vDZTOuKXx73gNYw9vDZTOhuOxr0vGow901P6N9EByL1iCZI9AAAAAK8Cx71A/pM9AAAAAAtaxr05Fow901P6OmyPxr24EIs90lP6OvoXx71aBoo901P6Oj6Yx70LFYk9ujZTOogPyL1P94g90lP6Og0QyL0y5Yk901N6OdULyL2s6o491FP6NyvAh73i2I090lP6NxlAh72544s90lN6OUFMh73e7Iw91FN6OU3Sh707+Yw91FP6N53Ghr0E5oo91FN6OQDOhr0WK4s9ujZTOr1Qh70NMYw9vDZTOvrYh71QIoo9vDZTOrnQhr04+Y8901P6N8FIiL2yA5E9AAAAADu4hr1aBoo901P6OhzRhr22EIs90lP6Ol9Rh70LMo09ujZTOlhpiL2E8Y0901N6OZNgiL1oe1Y91FP6NzZsyL1nxlg90lP6N6nNyL10B1090lN6OX7eyL2Zz1o91FN6OZV5yL1Tolo91FP6N6wkyb1BJF891FN6Of45yb2tmF49ujZTOrHkyL3iZ1w9vDZTOoJ+yL1lzWA9vDZTOtZByb1YDU49AAAAACtSyL2yR1M9AAAAALRCyb0qiVw901P6N45zyb3sSWE901N6OaOMyb01CmM9ujZTOuKVyb01olw901P6OjZ/yL25blI91FP6N7uNhr2ta1A90lP6N8APh71SilQ90lN6OVU+h737mlY91FN6OTW9hr3ho0090lP6Ny6eh70vSlI91FN6OSvJh72PEFY9ujZTOgNPh73DJFg9vDZTOqHOhr3q/lM9vDZTOtrXh71MUUo9AAAAAHUwhr25o0Q9AAAAADU2h71S8Eo90VP6N1E/iL0jI1A901N6OSZeiL02+VE9ujZTOg9piL1dPFI90lP6OqBqiL1PPVQ901P6OvPZh71OSFY90lP6OmRRh70FXVg901P6OiDRhr2y44g91FP6N64kyb2o0Yk90lP6N6rNyL0fsYc90lN6OYDeyL23ooY91FN6OQE6yb0q94o91FP6NzlsyL0PzYg91FN6OZl5yL2B6IY9ujZTOrTkyL0lzoU9vDZTOthByb3pAIg9vDZTOoV+yL0GkYw9AAAAALdCyb1IR409AAAAAC77yL1D8Ic901P6N5Fzyb0Q9o09AAAAAOKsyL2/44c901P6Ojh/yL3Hr4U901P6OvlCyb26r4Q9ujZTOueVyb3fj4U901N6OaWMyb0C2yk90lP6N0xZqL38lyo90lP6N1CQqb28uS090lN6Od2aqb1Pbi091FN6Oa9kqL0a0Co91FP6N4S5qr1W7y091FN6OdDLqr0L4i49ujZTOkyfqb1fvS49vDZTOvFpqL3nFS89vDZTOp3Sqr2P3yI9AAAAACVYqL1oiyQ9AAAAACyDqb1JvSQ9AAAAANGWqr238So901P6N8/bq732Ky4901N6Obn4q71cXC89ujZTOl8DrL3ahy890lP6OuUErL087S4901P6OrFqqL248l491FP6Nze8yb2/X2E90lP6N3r7yb2r82U90lN6Oa0Xyr22m2M91FN6OebWyb1TU2M91FP6N2ouyr2MLGg91FN6OQJOyr1vo2c9ujZTOhAiyr0+U2U9vDZTOrfgyb3W9Wk9vDZTOqZZyr014lk9AAAAAOLwyb0AXVs9AAAAAFIVyr2zUGU901P6N1ZYyr36bGo901N6Ob16yr35Tmw9ujZTOmyHyr0oN2o901P6Ok5byr0e4Wc90lP6Ooojyr0HkmU901P6Oh7iyb1emJI91FP6N7QQir19nJE90lP6Nyp0ib2cy4890lN6OY+Vib1iv5A91FN6OSo6ir0hzpA91FP6Nz3biL1s4Y491FN6OV/3iL1XII89ujZTOt6hib0fEZA9vDZTOnBJir3mK449vDZTOr4Bib1oO5c9AAAAALFVir1xMZY9AAAAAPe/ib07kJM901P6N0q1ir3GJZU9AAAAACEzib2ajZQ9AAAAAHGkiL33EY4901P6OjgDib05+I8901P6Op1Lir1D/JA9ujZTOnf4ir3g4pA90lP6Ogz7ir3xrZE901N6OWHmir3mzKA91FP6N7m5qr316KA90VP6N/GRqb0PWJ890lN6OWebqb1DPZ891FN6OeLLqr10R6E90lP6N35eqL3HfZ891FN6OVJmqL3ow549ujZTOl6fqb34qZ49vDZTOqDSqr091p49vDZTOiZqqL1W1qM9AAAAAC6Xqr0YvKA901P6N9Hbq704xaQ9AAAAAPphqL1Nvp4901P6OrJqqL29rp490lP6Ou2fqb3tlJ4901P6OpfTqr2+hp49ujZTOmEDrL3+cJ490lP6OucErL3yHp8901N6Obr4q70AvEk90lP6N1/xiL01sEg90lP6N/+gib3cq0w90lN6OWWiib3vWE491FN6ORD9iL3B8UY91FP6N5VJir3Q1Uo91FN6OftKir1AJE49ujZTOn6jib01CFA9vDZTOnkCib3eREw9vDZTOpFLir2K+EA9AAAAADGmib1SXz89AAAAANpHir2wWD09AAAAAPLkir0+CEU901P6N77xir2b+kg901N6OVH4ir3abko9ujZTOr36ir0HWk490lP6Oqajib3RRVA901P6OkADib0si4Q91FP6N2wuyr32hIU90lP6N3z7yb39OoM90lN6Oa4Xyr2MHoI91FN6OQNOyr18u4Y91FP6Nzq8yb34ZoQ91FN6OefWyb0aY4I9ujZTOhIiyr3lOYE9vDZTOqdZyr01i4M9vDZTOrrgyb1Yhog9AAAAAFcVyr2/Q4k9AAAAAObwyb15jIM901P6N1hYyr3Pa4M901P6OiHiyb1ERII90lP6Oowjyr07GYE901P6Ok9byr1RDYA9ujZTOm2Hyr1T/oA901N6Ob56yr3ways91FP6N1T+rL3DzSs90lP6N0gjrr2h+y490lN6OTxNrr27kC491FN6OZUjrb0BqCs90lP6NxNNr70yTy891FN6ORt2r71OKDA9ujZTOgVcrr1YuS89vDZTOjgxrb1EpTA9vDZTOquDr70cTiU9AAAAAJ20rL1bgCQ9AAAAADfhrr2gpys90VP6N3qBsL1jwy8901N6OfSdsL3sNjE9ujZTOv+nsL0i1jA901P6OpuFr71EUzA90lP6OiFerr2wjno90lP6Nxm4yr27KIA90lP6N3ydyr0ZiHw90lN6OeO6yr0fD3k91FN6OdvNyr0aLYI91FP6NzZ9yr00fH891FN6Ofueyr0fO3s9ujZTOnTFyr25rng9vDZTOnPVyr0rtH09vDZTOmKryr0heYA9AAAAAK6Fyr0HqnM90VP6N7fFyr0xfoQ9AAAAAH9gyr0C/4Y9AAAAAPw6yr0Fc30901P6Oiityr2OC3s90lP6OvbGyr3PHnY9ujZTOuXayr3INHY90lP6Orzbyr0AhXU901N6OfTUyr2LWZY90lP6N2XkjL3hLZU90lP6N08hjL3KZpM90lN6ObhYjL22VpQ91FN6OYYdjb3WVZQ91FP6N2Rmi72LiZI91FN6OXWbi71ivpI9ujZTOqxsjL3JmZM9vDZTOmExjb3f35E9vDZTOvWui72cPZo9AAAAAKVgjL2mepc90VP6Nx25jb3u1Jc9AAAAADv+ir2hx5E901P6Oryxi71UppI90lP6OoRvjL3LfpM901P6OjU0jb34bZQ9ujZTOh79jb2/OZU901N6OVnrjb1g7Wc91FP6NzR9yr2vB2s90VP6N3udyr2YiW890lN6OeK6yr1r4mw91FN6Ofqeyr2nlm490lP6Nxm4yr3EXXI91FN6OdrNyr15I3E9ujZTOnPFyr0NtG49vDZTOmGryr1Dm3M9vDZTOnLVyr3vK149AAAAAPo6yr1+b2E9AAAAAHxgyr0HXnE90lP6OvXGyr2T9m4901P6Oietyr3yYKA90lP6NxRNr70QTqA90lP6N0ojrr0dt5490lN6OT5Nrr1UjZ491FN6OR12r736fqA91FP6N1T+rL2Q7J491FN6OZYjrb3FIJ49ujZTOgdcrr1L4p09vDZTOqyDr70/WJ49vDZTOjgxrb0iYaA90VP6N3yBsL3dYKM9AAAAAEnIrb0QQ54901P6Oiwzrb3ayZ0901P6OpyFr711mZ09ujZTOgGosL3rfp090lP6OnCpsL06U54901N6OfWdsL3Vh0M91FP6N/2fi72OFUI90lP6N9pTjL2gn0U90lN6OVpnjL3ERkc91FN6OYKsi70iTEA91FP6NzEMjb1y50M91FN6OWMojb1x7UY9ujZTOolujL0NqEg9vDZTOh6xi72aO0U9vDZTOsYyjb11PDw9AAAAAJyHi70hRjk9AAAAAEjVjL1uYDc9AAAAAF+Fjb1bjD4901P6NxnMjb0gO0I901N6OWnwjb13lkM9ujZTOsv9jb0zbEU901P6OkE0jb0jHUc90lP6Oo9vjL2F2kg901P6Osexi70E4Sw90lP6N9u5sb0gOS490lP6NyLhsr2EcjE90lN6OZfjsr19izA91FN6ObPDsb05Ay891FP6Nx/0s71IPzI91FN6OX76s726ozI9ujZTOjXlsr1j4zE9vDZTOrnIsb2AcDM9vDZTOu38s71ovyU9AAAAALPBsb0gASg9AAAAABPmsr3Isi8901P6Nzb7tL3nDzM901N6OWEKtb0sTTQ9ujZTOvkPtb1VzzI90lP6OnHlsr2EFDI901P6Om/Jsb3oCJk91FP6NyVkkL2HWJg90VP6N/iIj71unJY90lN6Ocyfj70NVpc91FN6OdV9kL1585c90lP6N8Gijr108pU91FN6Oe7Cjr2B+JU9ujZTOsyoj73OtZY9vDZTOl2HkL0cN5U9vDZTOtPPjr0uJp09AAAAAED8kL0yV5w9AAAAACEzkL2fyZk901P6N7A9kb1L5ps9AAAAACd5jr1ZHJU901P6OqrRjr0X4ZU90lP6Ohaqj73qnpY901P6OrqIkL3obJc9ujZTOqprkb2lVZc90lP6Om5tkb22D5g901N6OUhfkb1pMD091FP6N66Wjr1Usjs90lP6N/Zqj71sLj890lN6OdGXj72CtUA91FN6OUfAjr0Wkzk90lP6NwZJkL23hD091FN6Od92kL17eEA9ujZTOtinj72oAUI9vDZTOorPjr0T9z49vDZTOoqGkL0KWDY9AAAAANFEjr0i/DQ9AAAAALwMj7327jE9AAAAAEraj72Fizc90VP6N1Y4kb0b9js901N6OS9ekb14hT09ujZTOpRrkb2Fvj090lP6Onxtkb39Kz8901P6OseIkL0cMUI901P6OrjRjr1Vs5491FP6NyL0s71gGJ890VP6NyThsr2re5090lN6OZnjsr1JFZ091FN6OYH6s71vxJ890lP6N965sb0v75091FN6ObTDsb0P45w9ujZTOjflsr2sfJw9vDZTOu/8s706Q509vDZTOrrIsb2q2KE9AAAAAPTos72NW54901P6Nzn7tL1GVaM9AAAAALfBsb3eZpw901P6Okn9s71WDpw9ujZTOvsPtb2r95s90lP6OsgQtb34rJw901N6OWUKtb2TwjA91FP6Nwb+tb3z4DE90lP6N9P6tr2AEjU90lN6ORAct70YCTQ91FN6OcIVtr3MtTI91FP6N1vvt73QETY91FN6OX4cuL23PzY9ujZTOk4ot70FPjU9vDZTOoAetr2mTjc9vDZTOh8tuL2tYSo9AAAAAM3Ptb3bqCs9AAAAABu6tr1avyw9AAAAAP9zuL2vmzM901P6N6TguL2UITc901N6OW0Yub3dbTg9ujZTOvssub1UnTg90lP6Ouovub2+ajY90lP6Og4qt70t8Zs90lP6N9T6k70mAps90lP6NzUJk72TXpk90lN6Of81k70oFZo91FN6OSgrlL02Xpo91FP6N2Ufkr1Kt5g91FN6OUpHkr1Vw5g9ujZTOglGk72JZpk9vDZTOsw7lL1kG5g9vDZTOu1Vkr3e05w90VP6N5b8lL1CKp49AAAAAIqrkr2vlJ09AAAAAObQkb0eBZg901P6OgVYkr2XTZk901P6Oiw+lL0zAZo9ujZTOjQ3lb3XvZo901N6OeMnlb0J2pw91FP6N13vt712RJ090lP6N9b6tr2rq5s90lN6ORIct70FLJs91FN6OYEcuL2m05091FP6Nwn+tb1gMJw91FN6OcUVtr0PFZs9ujZTOlAot72XjZo9vDZTOiEtuL3olZs9vDZTOoQetr0ZZ5w901P6N6fguL2IYKA9AAAAAB26tr0gBKE9AAAAANDPtb33dpo901P6OoMvuL39/Zk9ujZTOv0sub0hpJo901N6OXAYub1zzzY90lP6N2I4kr1ROjY90lP6N64zk71ioDk90lN6OcRBk70evDo91FN6OcpNkr3PETU91FP6N74klL03Zzg91FN6OZ42lL2f4To9ujZTOo5Hk70lKzw9vDZTOslWkr22oTk9vDZTOkY9lL3xFi89AAAAALgkkr1JpS89AAAAAGogk70TlS49AAAAAPcClL1myjM901P6NwcUlb1rLzc901N6OVsulb2Xbzg9ujZTOhA4lb1TnTg90lP6OnI5lb2UXzw901P6OhNYkr2Q5DQ91FP6N7TTub1PDTY90VP6N0vGur0Kkzk90lN6OZsGu73PWTg91FN6OUoRur1inTY90lP6Nzm3u71irTo91FN6OdH3u73z3zo9ujZTOrAdu70JoDk9vDZTOucnur1NKTw9vDZTOhoOvL3XKS49AAAAALxaub3JOi89AAAAAKpAur34ni49AAAAADgfu72TXzw901P6OkoRvL2BDzs90lP6Ovwgu7095po90lP6Nzu3u71HLps90lP6N03Gur1ma5k90lN6OZ0Gu7053pg91FN6OdP3u72mwps91FP6N7bTub0ECJo91FN6OU8Rur3wxJg9ujZTOrEdu71DIJg9vDZTOh0OvL3kZJk9vDZTOugnur0KIJ89AAAAAL9aub2YTZk901P6OiUrur0qrZg90lP6Ov0gu70fBZg901P6Ok0RvL1jH5490lP6N5w4mL3VaJ090VP6N2gll70yt5s90lN6OYY3l70tRpw91FN6OVJFmL2iHJ090lP6N8UQlr2kPps91FN6Odwslr1/Fps9ujZTOkk+l72hmJs9vDZTOgZJmL3qj5o9vDZTOjE4lr1ztaE9AAAAABYNmL2Tx6A9AAAAACjulb31dpo901P6Os85lr3Xf5s901P6Oo5JmL1B2zI91FP6N0IKlr2ZzzE90VP6N2gIl71hDDU90lN6OXIvl73JHDY91FN6Oc8rlr1cMjA90lP6N1MPmL203zM91FN6OVI5mL30PjY9ujZTOlM9l70GUDc9vDZTOhw4lr3ZODU9vDZTOpFHmL0jhiw9AAAAAA/Ilb0ODyk9AAAAAN+nl70najU901P6OptJmL2/ajY90lP6Ok8/l71FuOA85pduO2DObL2oEOQ85ZduO3ctaL2oEOQ83767O3gtaL1GuOA83767O2DObL1ciuc85pduO2qBY71ciuc83r67O2mBY72nEOQ85BgAPHYtaL1FuOA85RgAPF/ObL1biuc85RgAPGmBY706gd081FP6OiBkcb1GuOA81FP6OmLObL07gd085JduOxxkcb1iJes81FP6Oj/KXr1hJes85JduO0DKXr1jJes83b67O0HKXr1iJes85RgAPEHKXr07gd085RgAPB1kcb07gd083b67Ox5kcb0RBoQ95pduO1uUs7s3uIQ95ZduOxFLxbs3uIQ93767Ow9LxbsQBoQ93767O1yUs7sDcoU95pduOxPV17sDcoU93r67OxLV17s5uIQ95BgAPBJLxbsSBoQ95RgAPFuUs7sEcoU95RgAPBTV17vRW4M95JduO8K1ors4uIQ901P6Og9LxbsDcoU901P6OhTV17sxM4Y91FP6Opct67sxM4Y95JduO5Ut67swM4Y93b67O5Yt67swM4Y95RgAPJUt67vRW4M95RgAPMK1orvSW4M93b67O8O1ors0FCQ95pduO9Yn6r387x895ZduOy7O6L387x893767Oy7O6L0zFCQ93767O9cn6r2r4xs95pduOyJk572s4xs93r67OyFk57387x895BgAPC7O6L0yFCQ95RgAPNcn6r2r4xs95RgAPCJk570yFCQ91FP6Otgn6r2STyg95JduO75w67377x8901P6Oi3O6L0A8Bc95JduOxLq5b3/7xc93b67Ow/q5b0A8Bc95RgAPBDq5b2STyg95RgAPL9w672UTyg93b67O79w672fZbw95pduOxJebb2yQr095ZduO2nmcb20Qr093767O2jmcb2iZbw93767OxNebb1+F7495pduOx5fdr1+F7493r67Ox5fdr2zQr095BgAPGnmcb2iZbw95RgAPBJebb1+F7495RgAPBxfdr1JgLs91FP6OibGaL2jZbw91FP6OhRebb1IgLs95JduOybGaL1/F74901P6Oh1fdr0A5L495JduOyrIer3/47493b67OyrIer0A5L495RgAPCnIer1IgLs95RgAPCXGaL1JgLs93b67OyTGaL149rw85pduO25tmL35Nr485ZduOwV4lr34Nr483767OwV4lr169rw83767O25tmL0emb885pduO9B8lL0bmb883r67O898lL34Nr485BgAPAR4lr159rw85RgAPG9tmL0cmb885RgAPM58lL2g17s81FP6Oghdmr2g17s85JduOwhdmr3eHME81FP6OtJ7kr3fHME85JduO9J7kr3fHME83b67O9J7kr3eHME85RgAPNF7kr2h17s85RgAPAldmr2h17s83b67Owhdmr0WQ6g95pduOyxk573uPKY95ZduOzjO6L3vPKY93767OzfO6L0XQ6g93767Oy1k573SKqQ95pduO+An6r3SKqQ93r67O+An6r3uPKY95BgAPDjO6L0WQ6g95RgAPCtk573TKqQ95RgAPOAn6r0WQ6g91FP6Oixk573sPKo95JduOxzq5b0iDaI95JduO8hw670jDaI93b67O8hw670iDaI95RgAPMdw673sPKo95RgAPBzq5b3uPKo93b67Oxzq5b1YUsY95pduO2xAl71bqsY95ZduO/AFmb1YqsY93767O+8Fmb1ZUsY93767O21Al737+cY95pduO2rDmr38+cY93r67O2rDmr1YqsY95BgAPPAFmb1aUsY95RgAPG1Al737+cY95RgAPGvDmr0B8sU91FP6OuVylb1bUsY91FP6Om5Al70A8sU95JduO+Vylb39+cY901P6OmvDmr1CQcc91FP6Otl4nL1CQcc95JduO9l4nL1BQcc93b67O9l4nL1BQcc95RgAPNh4nL0A8sU95RgAPOVylb0A8sU93b67O+Zylb3nnXQ95pduO0x7wbh0t3Q95ZduO5hArrh2t3Q93767O6RArrjmnXQ93767O1l7wbg00XQ95pduO6QAnLg10XQ93r67O7AAnLh2t3Q95BgAPLBArrjnnXQ95RgAPGV7wbg20XQ95RgAPL0AnLiMhHQ91FP6OvCu1bjonXQ91FP6OkJ7wbiOhHQ95JduO/qu1bgz0XQ901P6OpkAnLgg63Q95JduOzq9irgj63Q93b67O0e9irgh63Q95RgAPFS9iriNhHQ95RgAPBKv1biOhHQ93b67Owev1biQ/Vs95pduO+fOB7wgrF095ZduO66v+7sfrF093767O66v+7uR/Vs93767O+jOB7xkTV895pduO3V46LtkTV893r67O3R46LsgrF095BgAPK2v+7uQ/Vs95RgAPOjOB7xkTV895RgAPHV46Ls8Qlo91FP6OoAfEryQ/Vs91FP6OufOB7w9Qlo95JduO4AfErwfrF0901P6Oq6v+7tkTV8901P6OnN46LvY4GA91FP6Ov771bvY4GA95JduO//71bvX4GA93b67O//71bvY4GA95RgAPP/71bs9Qlo95RgAPIEfErw+Qlo93b67O4AfEryemng95pduO2wIwLi7tHg95ZduO4u91Li7tHg93767O5i91Liemng93767O3gIwLifzng95pduO1h36rigzng93r67O2V36ri7tHg95BgAPKS91Lifmng95RgAPIUIwLigzng95RgAPHF36rhIgHg91FP6OgJarLifmng91FP6OmEIwLhIgHg95JduOw5arLi7tHg901P6OoK91LhI6Hg91FP6OtiZALlI6Hg95JduO9yZALlK6Hg93b67O+OZALlJ6Hg95RgAPOmZALlJgHg95RgAPCdarLhJgHg93b67OxtarLhipNQ85pduOw/ifr1Gd9c85ZduO/5ter1Fd9c83767O/1ter1jpNQ83767OxDifr2Qa9o85pduO6rudb2Qa9o83r67O6rudb1Fd9c85BgAPP5ter1ipNQ85RgAPA/ifr2Oa9o85RgAPKnudb3t8tE81FP6Omylgb1jpNQ81FP6OhHifr3t8tE85JduO22lgb1Fd9c801P6Ov1ter3t8tE85RgAPGylgb3u8tE83b67O2ylgb19+4Y95pduO8hP/7umyoc95ZduO20bCrymyoc93767O28bCrx9+4Y93767O8pP/7tpoIg95pduOwPvFLxqoIg93r67OwLvFLymyoc95BgAPHAbCrx8+4Y95RgAPMdP/7tooIg95RgAPAPvFLylyoc901P6Om4bCryDfIk95JduOzwgILyCfIk93b67OzsgILyDfIk95RgAPDsgILxGhTU95pduOzvj7r3bCDE95ZduO8/O7b3bCDE93767O9DO7b1FhTU93767Ozzj7r1foSw95pduO4io7L1hoSw93r67O4eo7L3bCDE95BgAPNDO7b1GhTU95RgAPD3j7r1goSw95RgAPIio7L3lFTo95JduO2zl771foSw901P6Oomo7L3lFTo95RgAPGrl773lFTo93b67O2vl77095J895pduO5Co7L2AsJ095ZduO9fO7b1/sJ093767O9fO7b095J893767O4+o7L1Mcps95pduO0Lj7r1Kcps93r67O0Pj7r2AsJ095BgAPNjO7b085J895RgAPJCo7L1Kcps95RgAPEPj7r1Kcps901P6OkLj7r38KZk95JduO2/l7739KZk93b67O3Dl7739KZk95RgAPHDl773AOXQ95pduO/8GDLl3UnQ95ZduOw59ALl5UnQ93767OxV9ALnAOXQ93767OwYHDLlna3Q95pduO9bZ6rhna3Q93r67O+PZ6rh1UnQ95BgAPBp9ALnAOXQ95RgAPA0HDLlma3Q95RgAPO/Z6rjAOXQ91FP6OvsGDLlBIXQ95JduO94JGLl3UnQ901P6Ogl9ALloa3Q901P6Os7Z6rhDIXQ95RgAPOsJGLlDIXQ93b67O+UJGLnmyFQ95pduOykXM7xip1Y95ZduO4/FJ7xip1Y93767O5DFJ7zmyFQ93767OyoXM7yqelg95pduO7DHHLytelg93r67O7LHHLxip1Y95BgAPI7FJ7zmyFQ95RgAPCsXM7yqelg95RgAPLHHHLzoyFQ91FP6OioXM7y/31I95JduO5W6Prytelg901P6OrDHHLzB31I95RgAPJe6PrzA31I93b67O5a6Pry0AXk95pduO014DLnhGnk95ZduO+/VGLnjGnk93767O/jVGLm0AXk93767O1J4DLnMM3k95pduO7yxJbnOM3k93r67O8OxJbniGnk95BgAPPzVGLm1AXk95RgAPFl4DLnNM3k95RgAPMmxJbnPM3k901P6OraxJbl4THk91FP6OqEKM7l3THk95JduO6YKM7l5THk93b67O60KM7l2THk95RgAPLMKM7mxXoo95pduO66sK7yyRos95ZduO/aRN7yxRos93767O/aRN7ywXoo93767O66sK7xBNIw95pduO6rNQ7xBNIw93r67O6rNQ7yxRos95BgAPPaRN7yxXoo95RgAPK2sK7xBNIw95RgAPKrNQ7yxXoo91FP6Oq6sK7yyRos901P6OveRN7wdJ4095JduO2ZdULweJ4093b67O2VdULwdJ4095RgAPGZdULyKOUg95pduO9p68r3GcEM95ZduO5qx8b3GcEM93767O5mx8b2KOUg93767O9l68r35uT495pduO/7U8L34uT493r67O//U8L3EcEM95BgAPJmx8b2LOUg95RgAPNl68r35uT495RgAPP7U8L2KOUg91FP6Otp68r2NE0095JduO2Iw873EcEM901P6Opix8b34uT4901P6Ov7U8L2NE0095RgAPGIw872OE0093b67O2Qw871CRbk85pduO9cIoL0C/7k85ZduO78qnr0A/7k83767O8Aqnr1BRbk83767O9cIoL132ro85pduO9FGnL142ro83r67O9BGnL0A/7k85BgAPMAqnr1CRbk85RgAPNgIoL132ro85RgAPM9GnL0/rbg81FP6Og7hob1CRbk81FP6OtgIoL0/rbg85JduOw/hob0B/7k801P6OsIqnr132ro801P6OtBGnL0+rbg85RgAPA7hob1Arbg83b67Ow/hob3115Y95pduOwPV8L2RfJQ95ZduO56x8b2QfJQ93767O5yx8b3z15Y93767OwPV8L0uGJI95pduO9168r0vGJI93r67O9x68r2QfJQ95BgAPJux8b3015Y95RgAPATV8L0vGJI95RgAPNt68r2QfJQ901P6Opux8b0wq4895JduO2Qw870xq4893b67O2Uw870vq4895RgAPGQw87082XM95pduOxPfPrn+8HM95ZduO8x2Mbn/8HM93767O9F2Mbk52XM93767OxrfPrkCCXQ95pduO8OEJLkACXQ93r67O8qEJLn98HM95BgAPNl2Mbk52XM95RgAPCHfPrkDCXQ95RgAPM+EJLm3wXM91FP6OrG8TLk72XM91FP6Og3fPrm4wXM95JduO7a8TLn98HM901P6Osd2MbkDCXQ901P6Or6EJLm4wXM95RgAPMO8TLm2wXM93b67O7u8TLmG6Uw95pduO3d8Y7yK70495ZduOyrvVryJ70493767OyvvVryH6Uw93767O3l8Y7x07FA95pduO+atSrx07FA93r67O+atSryJ70495BgAPCrvVryH6Uw95RgAPHh8Y7x07FA95RgAPOatSrzy2ko91FP6Ot5TcLzw2ko95JduO+BTcLyK704901P6OirvVrzx2ko95RgAPOBTcLzz2ko93b67O+BTcLzyNY095pduO9fR873TuIo95ZduO9Ze9L3SuIo93767O9Ve9L3xNY093767O9fR870yNIg95pduO//W9L0zNIg93r67O/7W9L3SuIo95BgAPNRe9L3yNY095RgAPNfR870zNIg95RgAPP7W9L1vqIU91FP6OvY59b1vqIU95JduO/U59b1vqIU93b67O/Q59b1vqIU95RgAPPU59b3cZHk95pduO6HfQLn8fHk95ZduO6QvT7n8fHk93767O6svT7ncZHk93767O6nfQLnSlHk95pduO6L5XbnRlHk93r67O6f5Xbn7fHk95BgAPLEvT7ncZHk95RgAPK/fQLnRlHk95RgAPKz5XbneZHk91FP6OpzfQLnSlHk901P6Opz5XbldrHk91FP6Ooo8bbldrHk95JduO488bblerHk93b67O5c8bblerHk95RgAPJw8bbkDH4495pduO8A+XbyyG4895ZduO05varyyG4893767O1BvarwFH4493767O78+XbzlHJA95pduO7Hsd7zkHJA93r67O6/sd7yxG4895BgAPE5varwEH4495RgAPL8+XbzkHJA95RgAPLDsd7wFH4491FP6OsA+XbzkHJA901P6Oq/sd7xZIpE95JduOzzagrxYIpE93b67Oz7agrxYIpE95RgAPD7agrw2qL895pduO4ghf70jZMA95ZduO5i1gb0iZMA93767O5i1gb02qL893767O4ghf729F8E95pduO5DSg73AF8E93r67O4/Sg70hZMA95BgAPJm1gb02qL895RgAPIghf73AF8E95RgAPJDSg703qL891FP6Ookhf70hZMA901P6Opm1gb2/F8E901P6OpDSg70Pw8E95JduO6Pnhb0Rw8E93b67O6Tnhb0Qw8E95RgAPKPnhb1pk8w85pduO0SjxL2HIMk85ZduOzZIwr2IIMk83767OzdIwr1ok8w83767O0SjxL0S+8U85pduOy7kv70U+8U83r67Oy3kv72HIMk85BgAPDdIwr1pk8w85RgAPEKjxL0R+8U85RgAPC3kv71AUtA85JduO/b0xr2HJMM85JduO4h3vb2HJMM83b67O4p3vb2HJMM85RgAPIp3vb0/UtA85RgAPPb0xr0/UtA83b67O/b0xr0pgMc95pduOzcmnr2xtsc95ZduO4bLn72xtsc93767O4XLn70qgMc93767Ozgmnr3Y5Mc95pduO7toob3Y5Mc93r67O75oob2wtsc95BgAPIfLn70pgMc95RgAPDgmnr3X5Mc95RgAPLxoob0qgMc91FP6Ojkmnr2cCsg95JduO9n9or2dCsg93b67O9r9or2eCsg95RgAPNr9or2aAVw95pduO/7W9L1T+FY95ZduO9Ve9L1S+FY93767O9Re9L2ZAVw93767O/7W9L0R/lE95pduO9bR870Q/lE93r67O9bR871S+FY95BgAPNRe9L2YAVw95RgAPP3W9L0Q/lE95RgAPNXR870oGWE91FP6OvQ59b2ZAVw91FP6Ov3W9L0mGWE95JduO/U59b0nGWE95RgAPPY59b0nGWE93b67O/U59b3JfHM95pduO9EMebl8k3M95ZduO3vUabl9k3M93767O3/UabnJfHM93767O9gMebl3qnM95pduO80OW7l2qnM93r67O9UOW7l9k3M95BgAPIfUabnJfHM95RgAPN8Mebl4qnM95RgAPNsOW7nIfHM91FP6Os8MeblcZnM95JduO3tbhLl8k3M901P6OnXUabl3qnM901P6OsoOW7lcZnM95RgAPIBbhLlcZnM93b67O39bhLlitsQ95pduOzvkv70B7cM95ZduO0RIwr0A7cM93767O0VIwr1jtsQ93767Ozrkv71DEMM95pduO1KjxL1CEMM93r67O1KjxL0B7cM95BgAPEVIwr1itsQ95RgAPDvkv71DEMM95RgAPFKjxL0LbMU95JduO5Z3vb0B7cM901P6OkRIwr1DEMM901P6OlOjxL2JIMI91FP6OgX1xr2IIMI95JduOwX1xr2JIMI93b67Owb1xr2IIMI95RgAPAX1xr0MbMU95RgAPJZ3vb0MbMU93b67O5V3vb06oXY95pduO8ZbkzQIonY95ZduO3gRkzQIonY93767O+oEkzQ7oXY93767OzlPkzTTonY95pduOymukjTUonY93r67O5uhkjQIonY95BgAPF74kjQ6oXY95RgAPKxCkzTTonY95RgAPA+VkjRvoHY91FP6OqWbkzQ7oXY91FP6OixmkzRvoHY95JduOz6RkzQHonY901P6Ot0bkzTVonY901P6Oo64kjSho3Y91FP6OhU4kjSgo3Y95JduO68tkjSgo3Y93b67OyMhkjSgo3Y95RgAPJUUkjRuoHY95RgAPCR4kzRuoHY93b67O7KEkzQGgUQ95pduO7dBjLwqpkY95ZduO6VshbwrpkY93767O6RshbwFgUQ93767O7hBjLxSxEg95pduO3RzfbxQxEg93r67O3ZzfbwqpkY95BgAPKVshbwGgUQ95RgAPLhBjLxRxEg95RgAPHZzfbxmVUI91FP6Ovw3k7wFgUQ91FP6OrhBjLxmVUI95JduO/w3k7wspkY901P6OqNshbxmVUI95RgAPPw3k7xmVUI93b67O/w3k7zcHIM95pduO9qH9b2YtIA95ZduO7zC9b2ZtIA93767O77C9b3cHIM93767O9mH9b14M3095pduOzbt9b14M3093r67Ozbt9b2YtIA95BgAPL3C9b3bHIM95RgAPNmH9b14M3095RgAPDjt9b3bHIM91FP6OteH9b2ZtIA901P6Or3C9b2z7Hk91FP6OtYJ9r2z7Hk95JduO9UJ9r2z7Hk93b67O9YJ9r2z7Hk95RgAPNYJ9r2dw3k95pduO2P3fLmP2nk95ZduO4eUhrmQ2nk93767O4qUhrmew3k93767O2n3fLky8Xk95pduO0Lojrkx8Xk93r67O0jojrmO2nk95BgAPI2Uhrmdw3k95RgAPG73fLky8Xk95RgAPEnojrmQ2nk901P6OoSUhrmCB3o91FP6OmB2l7mDB3o95JduO2J2l7mCB3o93b67O2V2l7mDB3o95RgAPGl2l7lulnY95pduO856nrKVnHY95ZduO+IdSjSVnHY93767O8sESjRulnY93767O5tDn7JYn3Y95pduOx/ejTRYn3Y93r67O5PRjTSVnHY95BgAPLHrSTRulnY95RgAPF8MoLJYn3Y95RgAPAXFjTQ3i3Y91FP6Or4G4rRwlnY91FP6On7UnbI1i3Y95JduOyMR4rRbn3Y901P6OobojTQ2i3Y95RgAPDsq4rQ2i3Y93b67O68d4rTMK5I95pduOyTiibz9OJM95ZduO9cMkbz+OJM93767O9cMkbzNK5I93767OyTiibyoSZQ95pduOyRZmLyoSZQ93r67OyVZmLz9OJM95BgAPNcMkbzMK5I95RgAPCHiibynSZQ95RgAPCRZmLzMK5I91FP6OiTiibz8OJM901P6OtgMkbyoSZQ901P6OiVZmLyLXZU91FP6OtnFn7yKXZU95JduO9nFn7yKXZU93b67O9jFn7yKXZU95RgAPNnFn7xvpHY95pduO+OLkTQ7pXY95ZduO5XEkDQ6pXY93767Owe4kDRtpHY93767O1Z/kTQHpnY95pduO5rTjzQJpnY93r67Ow/HjzQ8pXY95BgAPHyrkDRupHY95RgAPMdykTQJpnY95RgAPIG6jzRupHY91FP6OkeWkTQHpnY901P6OgHejzTVpnY95JduO8y0jjTWpnY93b67O0CojjTVpnY95RgAPLObjjQcwHc95pduO8Aa9r0SNXY95ZduO2Qg9r0SNXY93767O2Ug9r0cwHc93767O8Aa9r0HqnQ95pduO8Ea9r0IqnQ93r67O8Aa9r0SNXY95BgAPGMg9r0bwHc95RgAPMEa9r0IqnQ95RgAPMAa9r0bwHc91FP6Or8a9r0GqnQ901P6OsEa9r1sfXI91FP6OtYJ9r1rfXI95JduO9cJ9r1rfXI93b67O9YJ9r1rfXI95RgAPNYJ9r3eJHM95pduO5grnblmOnM95ZduO4SulLllOnM93767O4iulLneJHM93767O5srnbk6UHM95pduOwBpjLk7UHM93r67OwNpjLllOnM95BgAPIuulLndJHM95RgAPJ4rnbk6UHM95RgAPAVpjLnfJHM91FP6OpYrnbmmD3M95JduO8jfpblmOnM901P6OoOulLmlD3M95RgAPM/fpbmnD3M93b67O8zfpbmkp3Y95pduO/1jjTRxqHY95ZduOwTdizRxqHY93767O3jQizSip3Y93767O3FXjTQ+qXY95pduO7YbijQ/qXY93r67OysPijRwqHY95BgAPOzDizSjp3Y95RgAPORKjTQ+qXY95RgAPJ0CijSkp3Y91FP6OmVujTRxqHY901P6OmvnizQMqnY95JduO+cbiDQNqnY93b67O1wPiDQKqnY95RgAPM8CiDT0sDs95pduO1fYqLzY7D095ZduO0SEobzX7D093767O0OEobz0sDs93767O1fYqLzWI0A95pduO31OmrzUI0A93r67O39OmrzX7D095BgAPEOEobzzsDs95RgAPFfYqLzUI0A95RgAPH5OmryvcDk91FP6OsJJsLzzsDs91FP6OlbYqLyvcDk95JduO8BJsLyvcDk95RgAPMFJsLyxcDk93b67O8FJsLyiNm895pduOzbt9b3kAGs95ZduO73C9b3hAGs93767O77C9b2kNm893767Ozft9b1XMGY95pduO9mH9b1XMGY93r67O9iH9b3kAGs95BgAPL7C9b2jNm895RgAPDjt9b1XMGY95RgAPNiH9b3jAGs901P6OrzC9b1XMGY901P6OtiH9b1/HXo95pduO1w+oLkoM3o95ZduO60/qbkpM3o93767O7A/qbl+HXo93767O2E+oLl4SHo95pduO855srl6SHo93r67O9J5srkoM3o95BgAPLM/qbl+HXo95RgAPGM+oLl5SHo95RgAPNR5srmAHXo91FP6Olo+oLkoM3o901P6Oqw/qbl5SHo901P6Ost5srlvXXo91FP6Ojfsu7lwXXo95JduOzjsu7lvXXo93b67Oz7su7lvXXo95RgAPEDsu7lgdJY95pduO79Rp7zqjZc95ZduO6P7rrzqjZc93767O6P7rrxhdJY93767O79Rp7zjqZg95pduO1TCtrzjqZg93r67O1TCtrzqjZc95BgAPKT7rrxidJY95RgAPL5Rp7zhqZg95RgAPFTCtrwGyJk91FP6OpukvrwIyJk95JduO5ukvrwHyJk93b67O5ykvrwGyJk95RgAPJykvry0J8g95pduOyWOpL2eOsg95ZduOxQqpr2eOsg93767OxMqpr2zJ8g93767OyWOpL2bQcg95pduO2Tlp72cQcg93r67O2Tlp72fOsg95BgAPBMqpr2yJ8g95RgAPCSOpL2aQcg95RgAPGTlp72fOsg901P6OhQqpr2eQcg901P6OmTlp73gOsg95JduO9nTqb3hOsg93b67O9jTqb3gOsg95RgAPNfTqb3ZqnY95pduO3DZhTSnq3Y95ZduOyFQgzSnq3Y93767O5RDgzTaqnY93767O+PMhTR0rHY95pduO9R7gDR0rHY93r67O0ZvgDSnq3Y95BgAPAg3gzTYqnY95RgAPFbAhTRzrHY95RgAPLpigDTbqnY91FP6OtbjhTSoq3Y901P6OohagzRDrXY91FP6OoDFejRCrXY95JduO7SwejRDrXY93b67O5uXejRBrXY95RgAPIB+ejTs0XI95pduO5JCwbkt5nI95ZduO7frt7ks5nI93767O7rrt7nt0XI93767O5VCwbnA+nI95pduO6PKrrm/+nI93r67O6fKrrks5nI95BgAPL3rt7nt0XI95RgAPJlCwbm/+nI95RgAPKrKrrkFvnI95JduO7/OyrnA+nI901P6OqPKrrkFvnI95RgAPMXOyrkGvnI93b67O8LOyrkQrnY95pduOxjDczTernY95ZduO3wmbDTdrnY93767O2INbDQRrnY93767O/+pczSqr3Y95pduO4nSYzStr3Y93r67O3G5YzTernY95BgAPEj0azQPrnY95RgAPOWQczSrr3Y95RgAPFegYzQSrnY91FP6OuXXczSur3Y901P6OlbnYzR7sHY91FP6OrjTWjR6sHY95JduO+6+WjR6sHY93b67O9alWjR6sHY95RgAPLuMWjTlmjI95pduO2dEx7wi5TQ95ZduO8GAv7wh5TQ93767O8GAv7zlmjI93767O2lEx7ySLDc95pduO4vXt7yTLDc93r67O47Xt7wi5TQ95BgAPMGAv7zmmjI95RgAPGhEx7ySLDc95RgAPIzXt7xgTjA91FP6Ooshz7zlmjI91FP6OmlEx7xhTjA95JduO40hz7wi5TQ901P6OsGAv7ySLDc901P6OozXt7xhTjA95RgAPIwhz7xgTjA93b67O44hz7yRz7c85pduO1qIp73t67c85ZduO2STpb3r67c83767O2STpb2Tz7c83767O1mIp70sOLg85pduO9i1o70rOLg83r67O9e1o73t67c85BgAPGOTpb2Sz7c85RgAPFmIp70rOLg85RgAPNa1o70x6rc81FP6OmCjqb2Uz7c81FP6OlmIp70w6rc85JduO2Gjqb3u67c801P6OmSTpb0rOLg801P6Oti1o70x6rc85RgAPGGjqb0x6rc83b67O2Gjqb0Ncno95pduO2uWxblMhno95ZduO9l3z7lMhno93767O913z7kNcno93767O2+Wxbkrmno95pduOwWQ2bksmno93r67OwmQ2blLhno95BgAPON3z7kNcno95RgAPHGWxbkrmno95RgAPAuQ2bkNcno91FP6OmmWxblMhno901P6Otl3z7mtrXo91FP6OmLe47msrXo95JduO2Pe47msrXo93b67O2fe47mtrXo95RgAPGre47kW6Jo95pduO0ehxrzMCZw95ZduOyS3zrzOCZw93767OyS3zrwW6Jo93767O0ehxrzpLJ095pduO/7k1rzpLJ093r67O/7k1rzMCZw95BgAPCW3zrwW6Jo95RgAPEehxrzqLJ095RgAPP7k1rzNCZw901P6OiW3zrwoUZ495JduO6Ep37wnUZ493b67O6Ep37wnUZ495RgAPKIp37xJp8o85pduO58giL1c9Mw85ZduOzv9hb1c9Mw83767Ozz9hb1Jp8o83767O54giL3oYs885pduOyvUg73oYs883r67OyrUg71b9Mw85BgAPDz9hb1Jp8o85RgAPJ8giL3pYs885RgAPCrUg724e8g81FP6OlA+ir1Jp8o81FP6Op8giL25e8g85JduO08+ir1b9Mw801P6Ojz9hb24e8g85RgAPFA+ir24e8g83b67O1A+ir1JsXY95pduO1HjUDQXsnY95ZduO183RjQXsnY93767O0UeRjRJsXY93767OzfKUDTlsnY95pduO8KyOjTksnY93r67O6qZOjQXsnY95BgAPC0FRjRJsXY95RgAPB2xUDTksnY95RgAPJGAOjRJsXY91FP6Oh74UDQXsnY901P6OixMRjTmsnY901P6Oo7HOjS0s3Y91FP6OvJhLjSys3Y95JduOyZNLjSys3Y93b67Ow00LjSxs3Y95RgAPPUaLjRrhHI95pduO82u6LlDl3I95ZduO1CF3rlDl3I93767O1KF3rlqhHI93767O9Cu6Ll4qnI95pduO9GP1Ll5qnI93r67O9OP1LlDl3I95BgAPFOF3rlqhHI95RgAPNOu6Ll4qnI95RgAPNaP1LnucXI91FP6OtQL87lrhHI91FP6Osyu6LnwcXI95JduO9YL87l3qnI901P6OsyP1LnvcXI95RgAPNwL87nwcXI93b67O9wL87mAtHY95pduOzb+IDROtXY95ZduO5i9EjRNtXY93767O3+kEjSBtHY93767OxrlIDQctnY95pduO/2CAzQdtnY93r67O+NpAzROtXY95BgAPGWLEjR/tHY95RgAPAPMIDQctnY95RgAPMpQAzSAtHY91FP6OgETITRNtXY901P6OmTSEjQbtnY901P6OsiXAzTptnY91FP6Oqy15jPotnY95JduOxSM5jPptnY93b67O+NZ5jPotnY95RgAPK8n5jPYLik95pduO1AB6LztoSs95ZduO0Vb37ztoSs93767O0Vb37zYLik93767O1EB6LxG/i095pduOxEe17xG/i093r67Ow8e17ztoSs95BgAPERb37zYLik95RgAPFEB6LxH/i095RgAPBAe17yKmiY91FP6OmU48byJmiY95JduO2U48bxF/i0901P6OhAe17yKmiY95RgAPGY48byLmiY93b67O2U48bzKwHo95pduO3Fi7rmD03o95ZduO6cb+bmE03o93767O6ob+bnKwHo93767O3Ri7rnW5Xo95pduO8EEArrY5Xo93r67O8EEArqD03o95BgAPK0b+bnJwHo95RgAPHZi7rnW5Xo95RgAPMQEArrJwHo91FP6Om5i7rnW5Xo901P6Or8EArrC93o95JduO7uVB7rB93o93b67O76VB7rB93o95RgAPL+VB7ovd5895pduO/GK57xPo6A95ZduOz4r8LxQo6A93767Oz8r8Lwvd5893767O/GK57zD2qE95pduO+Yz+bzG2qE93r67O+Uz+bxRo6A95BgAPD0r8Lwvd5895RgAPPKK57zE2qE95RgAPOQz+bwwd5891FP6OvOK57zHIqM91FP6OiRnAb3EIqM95JduOyRnAb3HIqM93b67OyVnAb3FIqM95RgAPCRnAb22t3Y95pduO938wzOGuHY95ZduO6NHnzOEuHY93767O3EVnzO3t3Y93767O6rKwzNSuXY95pduO4G3cDNRuXY93r67OxpTcDOGuHY95BgAPD3jnjO4t3Y95RgAPHWYwzNRuXY95RgAPLfubzO3t3Y91FP6OnQmxDOFuHY901P6OjpxnzNRuXY901P6Oq8KcTMfunY95JduOw1RHjMeunY93b67O6nsHTMfunY95RgAPEKIHTP/MXI95pduO+U1DbrrSnI95ZduO248BbrqSnI93767O3A8Bbr9MXI93767O+g1DbpwX3I95pduOz/f/blvX3I93r67O0Df/bnrSnI95BgAPHA8Bbr9MXI95RgAPOk1DbpvX3I95RgAPEPf/blEEnI95JduO5elF7rqSnI901P6Omw8BbpvX3I901P6Ojzf/blDEnI95RgAPJqlF7pDEnI93b67O5ulF7rtunY95pduOzd1jjK5u3Y95ZduO1lppbG7u3Y93767O4KMqLHuunY93767O22sjTKHvHY95pduOzoP67KHvHY93r67OwPY67K5u3Y95BgAPK6vq7HsunY95RgAPKPjjDKKvHY95RgAPMyg7LLsunY91FP6OpgbjzK6u3Y901P6OuDPorFTvXY95JduOw92W7NWvXY93b67O3PaW7NUvXY95RgAPNg+XLNLIB495pduOzMcCL1ZBiE95ZduO/G/Ar1YBiE93767O/O/Ar1MIB493767OzQcCL3G3iM95pduO1sZ+7zF3iM93r67O1sZ+7xYBiE95BgAPPO/Ar1NIB495RgAPDIcCL3G3iM95RgAPFsZ+7ywOxs91FP6Op+HDb2wOxs95JduO6GHDb3H3iM901P6Ol0Z+7yvOxs95RgAPKGHDb2vOxs93b67O6CHDb2qCXs95pduO4dmDbqSHXs95ZduO+00FLqTHXs93767O+80FLqqCXs93767O4hmDbrmNXs95pduO7/kHLrlNXs93r67O8DkHLqTHXs95BgAPPA0FLqqCXs95RgAPIlmDbrkNXs95RgAPMLkHLqqCXs91FP6OoZmDbqUHXs901P6Ous0FLrnNXs901P6Or3kHLoMVXs91FP6OstZKLoMVXs95JduO8tZKLoOVXs93b67O85ZKLoNVXs95RgAPM5ZKLpyfqQ95pduO+6JBr1k6KU95ZduOxnvC71k6KU93767OxvvC71yfqQ93767O+2JBr0jWac95pduO317Eb0kWac93r67O3x7Eb1l6KU95BgAPBrvC71xfqQ95RgAPO2JBr0kWac95RgAPH17Eb1wfqQ91FP6Ou6JBr0uyag95JduO+oTF70vyag93b67O+wTF70vyag95RgAPOoTF70ivnY95pduO+tMo7PuvnY95ZduOyWK27PvvnY93767O1e827MgvnY93767Ox9/o7O6v3Y95pduO65BC7S6v3Y93r67O8daC7TtvnY95BgAPInu27MhvnY95RgAPFGxo7O8v3Y95RgAPOFzC7TtvnY901P6Ooxg27O5v3Y901P6OuMsC7SGwHY91FP6OtYPKrSHwHY95JduO6AkKrSIwHY93b67O7o9KrSFwHY95RgAPNNWKrQRxrk85pduO37msL1J37g85ZduO9xerr1I37g83767O9perr0Pxrk83767O33msL2tQrg85pduOzHuq72uQrg83r67OzLuq71I37g85BgAPNperr0Pxrk85RgAPH3msL2tQrg85RgAPDLuq70Pxrk81FP6On7msL0Y/bo85JduOzx2s71I37g801P6Otterr2vQrg801P6OjLuq70V/bo85RgAPDt2s70X/bo83b67Ozt2s70RZsI95pduO9P0h73DAMM95ZduOxn6ib3BAMM93767Oxn6ib0SZsI93767O9P0h70gk8M95pduO3T3i70gk8M93r67O3T3i73CAMM95BgAPBj6ib0QZsI95RgAPNP0h70fk8M95RgAPHT3i70SZsI91FP6OtT0h73BAMM901P6Ohr6ib0fk8M901P6OnX3i70rHcQ91FP6Ot7sjb0rHcQ95JduO97sjb0qHcQ93b67O9/sjb0rHcQ95RgAPN/sjb2yJMg95pduO6YCrL2C/cc95ZduO+9krr2C/cc93767O+9krr2yJMg93767O6UCrL3Hw8c95pduO0TnsL3Jw8c93r67O0XnsL2B/cc95BgAPO1krr20JMg95RgAPKYCrL3Hw8c95RgAPEPnsL2yJMg91FP6OqYCrL3Hw8c901P6OkbnsL0Bdsc91FP6OkN2s73+dcc95JduO0J2s73/dcc93b67O0J2s73/dcc95RgAPEF2s73sbXE95pduO6RFT7qJs3E95ZduO7eMN7qJs3E93767O7eMN7rsbXE93767O6NFT7ox6XE95pduO+xkJbov6XE93r67O/BkJbqJs3E95BgAPLmMN7rtbXE95RgAPKdFT7ow6XE95RgAPPBkJbrqbXE91FP6OqJFT7r0FHE95JduO2G4bbox6XE901P6OutkJbr1FHE95RgAPGW4bbr2FHE93b67O2O4bbqewXY95pduOxbUXrRxxHY95ZduO8+Wx7RyxHY93767O1yjx7SdwXY93767OzDtXrTCynY95pduOylbTbXBynY93r67O29hTbVyxHY95BgAPOevx7SewXY95RgAPEkGX7TCynY95RgAPLRnTbVwxHY901P6OmqMx7TCynY901P6OvZVTbVM1nY91FP6Ovh2ybVL1nY95JduO5J5ybVN1nY93b67O7V8ybVL1nY95RgAPNh/ybVM6RI95pduO+aWHb3unhU95ZduOyVHGL3tnhU93767OyZHGL1N6RI93767O+SWHb0PZRg95pduO7fsEr0PZRg93r67O7nsEr3tnhU95BgAPCZHGL1M6RI95RgAPOWWHb0OZRg95RgAPLjsEr0wRBA95JduO+3bIr3snhU901P6OiZHGL0vRBA95RgAPO7bIr0wRBA93b67O+7bIr2ZfXs95pduO7+HN7q6sns95ZduO6ihS7q7sns93767O6qhS7qZfXs93767O8CHN7rF93s95pduO3XqZbrF93s93r67O3fqZbq6sns95BgAPKyhS7qafXs95RgAPMKHN7rG93s95RgAPHnqZbq7sns901P6OqehS7oNUHw91FP6OonSg7oNUHw95JduO4rSg7oOUHw93b67O4vSg7oMUHw95RgAPIrSg7qgR9085pduOz2uzb3Wrdg85ZduO9J6y73Xrdg83767O9F6y72jR9083767Ozuuzb2NW9Q85pduO/A8yb2MW9Q83r67O+88yb3Yrdg85BgAPNB6y72iR9085RgAPDuuzb2MW9Q85RgAPPA8yb10J+I81FP6OtHWz72lR9081FP6Ojquzb10J+I85JduO9DWz710J+I85RgAPNDWz710J+I83b67O9DWz71KMqo95pduO7yhHL0vk6s95ZduO2MgIr0vk6s93767O2MgIr1HMqo93767O7yhHL3i66w95pduO9iPJ73h66w93r67O9mPJ70wk6s95BgAPGIgIr1KMqo95RgAPLyhHL3i66w95RgAPNqPJ73i66w901P6OtmPJ71fPK495JduOxjwLL1gPK493b67OxnwLL1ePK495RgAPBjwLL0yHsE95pduO/88yb2ZCcA95ZduO+J6y72aCcA93767O996y70wHsE93767O/48yb0i47495pduO0yuzb0j47493r67O0yuzb2aCcA95BgAPOB6y70xHsE95RgAPP88yb0j47495RgAPE2uzb0wHsE91FP6OgA9yb0k474901P6Okyuzb0pq7095JduO+DWz70qq7093b67O+HWz70qq7095RgAPODWz72OSXY95pduO5pcZ7ZYY3Y95ZduOw8TC7ZZY3Y93767O58UC7aOSXY93767OyteZ7bOeXY95pduO6iRkbXOeXY93r67O8yUkbVYY3Y95BgAPDEWC7aQSXY95RgAPL5fZ7bNeXY95RgAPO6XkbWPSXY91FP6Ok1bZ7YkLnY95JduO53wsLYmLnY95RgAPC/ysLYkLnY93b67O2bxsLa4hW895pduOzqgu7qpIHA95ZduO6vcoLqnIHA93767O63coLq5hW893767Ozmgu7rqpXA95pduO4PribrqpXA93r67O4TribqpIHA95BgAPK7coLq4hW895RgAPDqgu7rqpXA95RgAPIXribq5hW891FP6Ojqgu7qf1W495JduO8Qm2rqpIHA901P6OqvcoLrqpXA901P6OoXribqf1W495RgAPMUm2rqe1W493b67O8Qm2ro36HY95pduOzu+M7ZV/3Y95ZduO6JlkbZU/3Y93767O2tmkbY36HY93767O86/M7bfGXc95pduO9ik2bbfGXc93r67O6Gl2bZW/3Y95BgAPDNnkbY26HY95RgAPF/BM7beGXc95RgAPGqm2bY36HY91FP6Ou+8M7bgGXc901P6OjKk2bYPNnc95JduO9SnGbcQNnc93b67OzqoGbcONnc95RgAPJ2oGbcNuAg95pduO3JqMr2NKws95ZduO7xFLb2OKws93767O71FLb0NuAg93767O3VqMr2brw095pduOzYWKL2brw093r67OzgWKL2OKws95BgAPLxFLb0NuAg95RgAPHVqMr2arw095RgAPDgWKL0bVQY91FP6OleEN70aVQY95JduO1iEN70aVQY95RgAPFiEN70aVQY93b67O1iEN71Dvnw95pduOxrsmLqJQn095ZduO8tMsrqJQn093767O81MsrpFvnw93767OxjsmLpX3H095pduO2jhz7pW3H093r67O2nhz7qJQn095BgAPM1MsrpEvnw95RgAPBnsmLpW3H095RgAPGvhz7pHvnw91FP6OhbsmLqIQn0901P6OspMsromi3491FP6OraW8bomi3495JduO7eW8booi3493b67O7mW8boni3495RgAPLqW8bo+XPI85pduO90L1r09s+w85ZduOwEG1L1As+w83767OwAG1L0+XPI83767O90L1r3RS+c85pduOzH00b3RS+c83r67OzL00b0+s+w85BgAPAAG1L1AXPI85RgAPN8L1r3RS+c85RgAPDL00b1bRfg81FP6OmkF2L1AXPI81FP6OtwL1r1aRfg85JduO2gF2L0+s+w801P6OgEG1L3RS+c801P6OjH00b1aRfg85RgAPGgF2L1aRfg83b67O2oF2L2mhK895pduOxlBMr21xLA95ZduO9SCN723xLA93767O9OCN72mhK893767OxpBMr2N/LE95pduO0G1PL2M/LE93r67O0K1PL22xLA95BgAPNSCN72lhK895RgAPBlBMr2N/LE95RgAPEG1PL23xLA901P6OtSCN70pLLM91FP6OlvYQb0pLLM95JduO1zYQb0rLLM93b67O1zYQb0qLLM95RgAPF3YQb08wsI85pduOw91kL0ticQ85ZduO4tojr0sicQ83767O4tojr06wsI83767Ow51kL2tccY85pduO0tWjL2tccY83r67O0pWjL0sicQ85BgAPIxojr07wsI85RgAPA11kL2tccY85RgAPEpWjL0sicQ801P6Ooxojr0RYrw95pduO0H00b0yCLs95ZduOxEG1L0xCLs93767Ow8G1L0QYrw93767O0P00b3tnbk95pduO+sL1r3vnbk93r67O+0L1r0xCLs95BgAPBEG1L0PYrw95RgAPEL00b3tnbk95RgAPOwL1r0RYrw91FP6OkP00b2lI7g91FP6OngF2L2lI7g95JduO3cF2L2mI7g93b67O3oF2L2lI7g95RgAPHkF2L2m23U95pduO2VGZ7cN93U95ZduO20mL7cM93U93767O9AmL7ep23U93767O8lGZ7eLEnY95pduO0kP/7aKEnY93r67OxMQ/7YN93U95BgAPDcnL7en23U95RgAPC1HZ7eLEnY95RgAPNoQ/7ZfwHU95JduO6Tsk7cM93U901P6OhomL7eMEnY901P6OqMO/7ZhwHU95RgAPAjtk7dhwHU93b67O9Xsk7eaS2w95pduOwbZJbsLOG095ZduO40fEbsIOG093767O44fEbuaS2w93767OwfZJbvhEG495pduO99g/LrkEG493r67O95g/LoKOG095BgAPI0fEbuZS2w95RgAPAjZJbviEG495RgAPN5g/LobTGs91FP6OiZVPLuZS2w91FP6OgjZJbsdTGs95JduOyZVPLsKOG0901P6OowfEbvjEG4901P6Ot1g/LoZTGs95RgAPCdVPLscTGs93b67OyZVPLtrUnc95pduO896T7enbnc95ZduOykmh7eobnc93767O14mh7dtUnc93767OzJ7T7fBinc95pduO9oFq7fAinc93r67OwoGq7enbnc95BgAPI8mh7dtUnc95RgAPJd7T7e/inc95RgAPD4Gq7dsUnc91FP6Onx6T7fAinc901P6OrEFq7e0pnc95JduOxpU07e1pnc93b67O0xU07ezpnc95RgAPH9U07diH/885pduO8GQRr3qwAE95ZduO4eXQb3pwAE93767O4eXQb1jH/883767O8OQRr23AgQ95pduO2GTPL24AgQ93r67O2GTPL3qwAE95BgAPIWXQb1gH/885RgAPMKQRr25AgQ95RgAPGKTPL1hH/881FP6OsOQRr0g3vo85JduOwx/S73qwAE901P6OoeXQb24AgQ901P6OmCTPL0f3vo85RgAPA5/S70g3vo83b67Ow5/S711Tn895pduO7+sC7veEoA95ZduO0GLILvdEoA93767O0GLILt3Tn893767O8CsC7s7iIA95pduO0RdN7s7iIA93r67O0VdN7veEoA95BgAPEGLILt1Tn895RgAPMCsC7s7iIA95RgAPEVdN7t2Tn891FP6Or+sC7veEoA901P6OkCLILs8iIA901P6OkRdN7sPB4E91FP6Oi0ZULsQB4E95JduOy0ZULsPB4E93b67Oy8ZULsPB4E95RgAPC4ZULs5uQU95pduO3ak3b34aAI95ZduOxPS2733aAI93767OxTS2706uQU93767O3Wk3b0Sbf485pduO0Ty2b0Sbf483r67O0Xy2b33aAI95BgAPBXS2705uQU95RgAPHek3b0Tbf485RgAPEby2b2RJgk91FP6Og5p3705uQU91FP6Onek3b2RJgk95JduOw5p3733aAI901P6OhXS270Tbf4801P6Okby2b2RJgk95RgAPA5p372QJgk93b67Ow1p372KU7Q95pduOx3sRr2ucrU95ZduO3nwS72vcrU93767O3rwS72JU7Q93767OxzsRr2UibY95pduO2/lUL2VibY93r67O27lUL2ucrU95BgAPHnwS72JU7Q95RgAPBzsRr2UibY95RgAPG/lUL2LU7Q91FP6Oh3sRr2vcrU901P6OnrwS708mLc95JduO/XKVb08mLc93b67O/XKVb08mLc95RgAPPTKVb21mbY95pduO1Py2b17ALU95ZduOyLS2716ALU93767OyPS2721mbY93767O1Xy2b1WWLM95pduO4Ok3b1YWLM93r67O4Sk3b17ALU95BgAPCLS272ymbY95RgAPFTy2b1YWLM95RgAPISk3b15ALU901P6OiTS271YWLM901P6OoWk3b2qobE91FP6Ohtp372pobE95JduOxxp372robE93b67Oxxp372pobE95RgAPBtp373insQ95pduO1jaj71EGMU95ZduO9a/kb1DGMU93767O9a/kb3jnsQ93767O1faj71OicU95pduO16dk71OicU93r67O1ydk71DGMU95BgAPNa/kb3insQ95RgAPFbaj71OicU95RgAPF2dk73insQ91FP6Olfaj71CGMU901P6Ote/kb1OicU901P6Ol2dk71Nb3U95pduOzPtBrgyinU95ZduO18P4bcyinU93767O5EP4bdOb3U93767O0ztBrg3pXU95pduO2douLc6pXU93r67O5pouLcyinU95BgAPMMP4bdNb3U95RgAPGXtBrg4pXU95RgAPMxouLePVHU91FP6OhphH7hOb3U91FP6Oh7tBriPVHU95JduOy1hH7gxinU901P6OjQP4bc6pXU901P6Oj5ouLeOVHU95RgAPGBhH7iQVHU93b67O0hhH7h84Gc95pduOyMGhbsHFmk95ZduO3x2brsHFmk93767O3x2brt+4Gc93767OyMGhbsSOmo95pduOzWMVLsTOmo93r67OzSMVLsIFmk95BgAPHx2brt94Gc95RgAPCQGhbsSOmo95RgAPDWMVLt94Gc91FP6OiQGhbv+mWY95JduO/Cik7v+mWY95RgAPO+ik7v7mWY93b67O++ik7uBwnc95pduO0kEALgn3nc95ZduO3KNGLgn3nc93767O42NGLiDwnc93767O2IEALih+Xc95pduO15BM7ii+Xc93r67O3dBM7gk3nc95BgAPKWNGLiCwnc95RgAPHsEALii+Xc95RgAPJJBM7go3nc901P6Ol+NGLih+Xc901P6OklBM7jvFHg95JduO90bULjwFHg93b67O/cbULjuFHg95RgAPBAcULiv4e485pduOwEIWr1Cv/I85ZduO7U6Vb1Cv/I83767O7U6Vb2w4e483767OwIIWr0TvvY85pduO2FiUL0UvvY83r67O19iUL1Dv/I85BgAPLM6Vb2w4e485RgAPAAIWr0UvvY85RgAPGFiUL0UvvY801P6OmJiUL0Yj4E95pduO2C1arsSIII95ZduOx6Ug7sRIII93767Ox6Ug7sYj4E93767O2C1aru9uYI95pduOxS0kru7uYI93r67OxK0krsSIII95BgAPB6Ug7sZj4E95RgAPGC1aru8uYI95RgAPBO0krsSIII901P6Oh6Ug7u8uYI901P6OhS0kru2FRQ95pduO1pg5L2OVRA95ZduO17H4r2PVRA93767O1/H4r22FRQ93767O1tg5L1CsAw95pduO3wf4b1CsAw93r67O3of4b2OVRA95BgAPF/H4r22FRQ95RgAPFpg5L1BsAw95RgAPHof4b23FRQ91FP6Oltg5L1CsAw901P6Onof4b2hnrg95pduOwWhWr3InLk95ZduO5ZnX73InLk93767O5VnX72jnrg93767OwKhWr2rkro95pduO6QeZL2qkro93r67O6MeZL3JnLk95BgAPJVnX72inrg95RgAPAShWr2rkro95RgAPKMeZL2inrg91FP6OgWhWr3InLk901P6OpZnX72rkro901P6OqUeZL3Q3K895pduO4gf4b0oCq495ZduO23H4r0oCq493767O2vH4r3Q3K893767O4gf4b0UKqw95pduO2Vg5L0TKqw93r67O2dg5L0oCq495BgAPGzH4r3R3K895RgAPIcf4b0TKqw95RgAPGZg5L3P3K891FP6Oocf4b0oCq4901P6OmvH4r0SKqw901P6Omhg5L1fnsA85pduO6YCu70aar485ZduO+SFuL0Zar483767O+SFuL1gnsA83767O6cCu70sibw85pduO58Btr0tibw83r67O6EBtr0Zar485BgAPOSFuL1gnsA85RgAPKUCu70sibw85RgAPKEBtr0Yar4801P6OuKFuL0tibw801P6OqABtr08BXU95pduO0TwdLiDH3U95ZduO0dmVriEH3U93767O2BmVrg8BXU93767O17wdLj1OXU95pduOxDgObj1OXU93r67OyngObiEH3U95BgAPHlmVrg9BXU95RgAPHbwdLj1OXU95RgAPEHgObg9BXU91FP6Oi/wdLj1OXU901P6OvvfObjzEsc95pduO6cBtr2zmsY95ZduO+2FuL2ymsY93767O+2FuL30Esc93767O6oBtr2cDcY95pduO7ICu72bDcY93r67O7ECu72zmsY95BgAPO2FuL30Esc95RgAPKoBtr2aDcY95RgAPLECu731Esc91FP6OqkBtr2zmsY901P6Ou6FuL2bDcY901P6OrECu730ZWI95pduOyg+xLsy3GM95ZduO81Cs7sy3GM93767O8xCs7v0ZWI93767Oyk+xLsMQ2U95pduO8YNo7sNQ2U93r67O8YNo7sy3GM95BgAPMxCs7v0ZWI95RgAPCg+xLsNQ2U95RgAPMQNo7v1ZWI91FP6Oik+xLsx3GM901P6OsxCs7sQMHg95pduO8QYb7gBS3g95ZduO/IZiLj+Sng93767O/4ZiLgRMHg93767O94Yb7i+ZXg95pduO4e0mbi+ZXg93r67O5O0mbj/Sng95BgAPAwaiLgQMHg95RgAPPYYb7i+ZXg95RgAPKG0mbj/Sng901P6OugZiLgAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAPwAAAIAAAAAAAACAvwAAAIAAAAAAAACAPwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAAAACAvwAAAIAAAAAA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" From 356b28987dfe46da4aa5eedad71bb3637384afa9 Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 3 Nov 2022 12:24:42 +0100 Subject: [PATCH 169/255] using watt gain and watt offset even for target_watt for proform bikes --- src/proformwifibike.cpp | 5 +++-- src/proformwifibike.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/proformwifibike.cpp b/src/proformwifibike.cpp index d2d9cb3de..5d093748f 100644 --- a/src/proformwifibike.cpp +++ b/src/proformwifibike.cpp @@ -17,6 +17,7 @@ proformwifibike::proformwifibike(bool noWriteResistance, bool noHeartService, ui double bikeResistanceGain) { QSettings settings; m_watt.setType(metric::METRIC_WATT); + target_watts.setType(metric::METRIC_WATT); Speed.setType(metric::METRIC_SPEED); refresh = new QTimer(this); this->noWriteResistance = noWriteResistance; @@ -236,9 +237,9 @@ void proformwifibike::innerWriteResistance() { QSettings settings; double erg_filter_upper = settings.value(QZSettings::zwift_erg_filter, QZSettings::default_zwift_erg_filter).toDouble(); - if (fabs(target_watts - requestPower) > erg_filter_upper) { + if (fabs(target_watts.value() - requestPower) > erg_filter_upper) { qDebug() << "change inclination due to request power = " << requestPower; - if (target_watts > requestPower) { + if (target_watts.value() > requestPower) { requestInclination = currentInclination().value() - 1; } else { requestInclination = currentInclination().value() + 1; diff --git a/src/proformwifibike.h b/src/proformwifibike.h index 566bfc4ef..1b2e1567e 100644 --- a/src/proformwifibike.h +++ b/src/proformwifibike.h @@ -83,7 +83,7 @@ class proformwifibike : public bike { QDateTime lastRefreshCharacteristicChanged = QDateTime::currentDateTime(); uint8_t firstStateChanged = 0; uint16_t m_watts = 0; - double target_watts = 0; + metric target_watts; bool initDone = false; bool initRequest = false; From 3b4b401d9ff8d96d2a8ec4c7150b0d73c94faeca Mon Sep 17 00:00:00 2001 From: Roberto Viola Date: Thu, 3 Nov 2022 12:25:52 +0100 Subject: [PATCH 170/255] GPX Issues on Treadmill #973 cesium metrics on the bottom right and with a rounded green box around --- src/inner_templates/googlemaps/maps.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/inner_templates/googlemaps/maps.htm b/src/inner_templates/googlemaps/maps.htm index 99f6db5f5..1682925d4 100644 --- a/src/inner_templates/googlemaps/maps.htm +++ b/src/inner_templates/googlemaps/maps.htm @@ -71,7 +71,7 @@
-

Speed: --
Cadence: --

+

🏃Speed: 0.00
🚴Cadence:0
💓Heart:0
🔥Calories:0.0
📏Odometer:0.00
⚡Watt:0
⏲️Elapsed:0:00:00
📐Inclination:0.0
🧲Resistance:0
✈️Altitude:0.0
⛰️Elevation:0.0