From a2d0afa0c92e2fde91c08c9b5e4f4e84c9f9c166 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sun, 5 Apr 2026 11:16:10 +0200 Subject: [PATCH 01/38] adc read ok, very slow --- RotaxMonitor/platformio.ini | 2 +- RotaxMonitor/src/devices.h | 3 +++ RotaxMonitor/src/main.cpp | 51 ++++++++++++++++++++++--------------- RotaxMonitor/src/pins.h | 10 +++----- RotaxMonitor/src/tasks.cpp | 7 +++-- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 4803271..f1dd197 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -49,7 +49,7 @@ upload_port = /dev/ttyACM2 upload_speed = 921600 ;Monitor configuration -monitor_speed = 115200 +monitor_speed = 921600 monitor_port = /dev/ttyACM2 ; Debug configuration diff --git a/RotaxMonitor/src/devices.h b/RotaxMonitor/src/devices.h index 869729f..e6027e5 100644 --- a/RotaxMonitor/src/devices.h +++ b/RotaxMonitor/src/devices.h @@ -1,5 +1,8 @@ #pragma once +// Library defines +#define ADS1256_SPI_ALREADY_STARTED + // Device Libraries #include #include diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 70977b6..a149e9e 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -19,7 +19,13 @@ // #define CH_B_ENABLE #define TEST -void printTaskStats() { +float freqToRPM(float freq) +{ + return freq * 60.0f; // 1 pulse per revolution +} + +void printTaskStats() +{ char buffer[1024]; vTaskGetRunTimeStats(buffer); Serial.println(buffer); @@ -102,14 +108,15 @@ void loop() bool spiA_ok = true; bool spiB_ok = true; -#ifndef TEST // Init 2 SPI interfaces SPIClass SPI_A(FSPI); spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); + SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 + #ifndef TEST SPIClass SPI_B(HSPI); spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); -#endif - + SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 + #endif if (!spiA_ok || !spiB_ok) { LOG_ERROR("Unable to Initialize SPI Busses"); @@ -119,13 +126,13 @@ void loop() } LOG_INFO("Init SPI OK"); -#ifndef TEST // Init ADC_A - dev.adc_a = new ADS1256(ADC_A_DRDY, ADC_A_RST, ADC_A_SYNC, ADC_A_CS, 2.5, &SPI_A); + dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADC_A_SYNC, ADC_A_CS, 2.5, &SPI_A); dev.adc_a->InitializeADC(); dev.adc_a->setPGA(PGA_1); - dev.adc_a->setDRATE(DRATE_1000SPS); + dev.adc_a->setDRATE(DRATE_30000SPS); +#ifndef TEST // Init ADC_B dev.adc_a = new ADS1256(ADC_B_DRDY, ADC_B_RST, ADC_B_SYNC, ADC_B_CS, 2.5, &SPI_B); dev.adc_a->InitializeADC(); @@ -185,7 +192,7 @@ void loop() if (ignA.coils12.spark_status == sparkStatus::SPARK_NEG_FAIL || ignA.coils12.spark_status == sparkStatus::SPARK_POS_FAIL) missed_firings12++; if (ignA.coils34.spark_status == sparkStatus::SPARK_POS_FAIL || ignA.coils34.spark_status == sparkStatus::SPARK_NEG_FAIL) - missed_firings34++; + missed_firings34++; clearScreen(); setCursor(0, 0); printField("++ Timestamp", (uint32_t)ignA.timestamp, 0, 0); @@ -194,10 +201,10 @@ void loop() printField("Missed Firing", missed_firings12, 0, 2); printField("Spark Dly", (uint32_t)ignA.coils12.spark_delay, 0, 3); printField("Spark Sts", sparkStatusNames.at(ignA.coils12.spark_status), 0, 4); - // printField("Peak P_IN", ignA.coils12.peak_p_in, 0, 5); - // printField("Peak P_OUT", ignA.coils12.peak_p_out, 0, 6); - // printField("Peak N_IN", ignA.coils12.peak_n_in, 0, 7); - // printField("Peak N_OUT", ignA.coils12.peak_n_out, 0, 8); + printField("Peak P_IN", ignA.coils12.peak_p_in, 0, 5); + printField("Peak N_IN", ignA.coils12.peak_n_in, 0, 7); + printField("Peak P_OUT", ignA.coils12.peak_p_out, 0, 6); + printField("Peak N_OUT", ignA.coils12.peak_n_out, 0, 8); printField("Soft Start ", softStartStatusNames.at(ignA.coils12.sstart_status), 0, 9); Serial.println("========== Coils 34 ============="); @@ -205,22 +212,24 @@ void loop() printField("Missed Firing", missed_firings34, 0, 12); printField("Spark Dly", (uint32_t)ignA.coils34.spark_delay, 0, 13); printField("Spark Sts", sparkStatusNames.at(ignA.coils34.spark_status), 0, 14); - // printField("Peak P_IN", ignA.coils34.peak_p_in, 0, 15); - // printField("Peak P_OUT", ignA.coils34.peak_p_out, 0, 16); - // printField("Peak N_IN", ignA.coils34.peak_n_in, 0, 17); - // printField("Peak N_OUT", ignA.coils34.peak_n_out, 0, 18); + printField("Peak P_IN", ignA.coils34.peak_p_in, 0, 15); + printField("Peak N_IN", ignA.coils34.peak_n_in, 0, 17); + printField("Peak P_OUT", ignA.coils34.peak_p_out, 0, 16); + printField("Peak N_OUT", ignA.coils34.peak_n_out, 0, 18); printField("Soft Start ", softStartStatusNames.at(ignA.coils34.sstart_status), 0, 19); Serial.println("========== END ============="); Serial.println(); - auto delta = (esp_timer_get_time() - last) / 1000000.0f; //in seconds - delta = delta > 0 ? 1.0f / delta : 0; // Calculate frequency (Hz) - printField("Frequency (Hz)", delta, 0, 21); + auto freq = (esp_timer_get_time() - last) / 1000000.0f; // in seconds + freq = freq > 0 ? 1.0f / freq : 0; // Calculate frequency (Hz) + printField("Engine RPM", freqToRPM(freq), 0, 21); printField("Queue Errors", (uint32_t)ignA.n_queue_errors, 0, 22); last = esp_timer_get_time(); - } else + } + else { - Serial.println("Waiting for data... ");; + Serial.println("Waiting for data... "); + delay(500); } } diff --git a/RotaxMonitor/src/pins.h b/RotaxMonitor/src/pins.h index a818b89..62a3ded 100644 --- a/RotaxMonitor/src/pins.h +++ b/RotaxMonitor/src/pins.h @@ -48,19 +48,17 @@ // ===================== #define ADC_A_CS 4 #define ADC_A_DRDY 5 -#define ADC_A_RST 6 -#define ADC_A_SYNC 7 +#define ADC_A_SYNC 6 #define ADC_B_CS 14 #define ADC_B_DRDY 15 -#define ADC_B_RST 16 -#define ADC_B_SYNC 17 +#define ADC_B_SYNC 16 // ===================== // DIGITAL POT // ===================== -//#define POT_A_CS 1 -//#define POT_B_CS 2 +#define POT_A_CS 7 +#define POT_B_CS 17 // ===================== // TRIGGER INPUT INTERRUPTS diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 6b5606a..7f3348d 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -162,6 +162,7 @@ void rtIgnitionTask(void *pvParameters) continue; } + // Select coil status reference based on pickup_flag coilsStatus *coils; switch (pickup_flag) { @@ -176,6 +177,7 @@ void rtIgnitionTask(void *pvParameters) break; } + // Select logic based on pickup and spark flags switch (pickup_flag) { case TRIG_FLAG_12P: @@ -249,7 +251,6 @@ void rtIgnitionTask(void *pvParameters) { cycle12 = false; cycle34 = false; - // vTaskDelay(pdMS_TO_TICKS(1)); // delay 1ms to allow peak detectors to charge for negative cycle // read adc channels: pickup12, out12 [ pos + neg ] if (adc) // read only if adc initialized { @@ -283,7 +284,9 @@ void rtIgnitionTask(void *pvParameters) ign_box_sts.timestamp = esp_timer_get_time(); // update data timestamp if (xQueueSendToBack(rt_queue, (void *)&ign_box_sts, 0) != pdPASS) { - ign_box_sts.n_queue_errors++; + static uint32_t n_errors = 0; + n_errors++; + ign_box_sts.n_queue_errors = n_errors; LOG_ERROR("Failed to send to rt_queue"); } } From 5c9ef7e93b852618a173c8b54c1d659dfff608b0 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sun, 5 Apr 2026 17:05:10 +0200 Subject: [PATCH 02/38] Fast ADC readings ok, to verify timing and settling time --- RotaxMonitor/platformio.ini | 4 +-- RotaxMonitor/src/ADS1256.cpp | 10 +++--- RotaxMonitor/src/isr.h | 1 + RotaxMonitor/src/main.cpp | 55 +++++++++++++++-------------- RotaxMonitor/src/tasks.cpp | 2 ++ RotaxMonitor/src/ui.h | 57 +++++++++---------------------- RotaxMonitorTester/platformio.ini | 4 +-- RotaxMonitorTester/src/main.cpp | 15 ++++---- 8 files changed, 66 insertions(+), 82 deletions(-) diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index f1dd197..117d9d2 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -25,8 +25,8 @@ upload_port = /dev/ttyACM2 upload_speed = 921600 ;Monitor configuration -monitor_speed = 115200 monitor_port = /dev/ttyACM2 +monitor_speed = 921600 ; Build configuration build_type = release @@ -49,8 +49,8 @@ upload_port = /dev/ttyACM2 upload_speed = 921600 ;Monitor configuration -monitor_speed = 921600 monitor_port = /dev/ttyACM2 +monitor_speed = 921600 ; Debug configuration debug_tool = esp-builtin diff --git a/RotaxMonitor/src/ADS1256.cpp b/RotaxMonitor/src/ADS1256.cpp index 3372b47..79e2430 100644 --- a/RotaxMonitor/src/ADS1256.cpp +++ b/RotaxMonitor/src/ADS1256.cpp @@ -120,14 +120,14 @@ void ADS1256::setDRATE(uint8_t drate) //Setting DRATE (sampling frequency) { writeRegister(DRATE_REG, drate); _DRATE = drate; - delay(200); + delayMicroseconds(500); } void ADS1256::setMUX(uint8_t mux) //Setting MUX (input channel) { writeRegister(MUX_REG, mux); _MUX = mux; - delay(200); + //delayMicroseconds(500); } void ADS1256::setPGA(uint8_t pga) //Setting PGA (input voltage range) @@ -138,7 +138,7 @@ void ADS1256::setPGA(uint8_t pga) //Setting PGA (input voltage range) _ADCON = (_ADCON & 0b11111000) | (_PGA & 0b00000111); // Clearing and then setting bits 2-0 based on pga writeRegister(ADCON_REG, _ADCON); - delay(200); + delayMicroseconds(1000); //Delay to allow the PGA to settle after changing its value updateConversionParameter(); //Update the multiplier according top the new PGA value } @@ -501,8 +501,6 @@ void ADS1256::writeRegister(uint8_t registerAddress, uint8_t registerValueToWrit CS_HIGH(); _spi->endTransaction(); - delay(100); - } long ADS1256::readRegister(uint8_t registerAddress) //Reading a register @@ -524,7 +522,7 @@ long ADS1256::readRegister(uint8_t registerAddress) //Reading a register CS_HIGH(); _spi->endTransaction(); - delay(100); + return regValue; } diff --git a/RotaxMonitor/src/isr.h b/RotaxMonitor/src/isr.h index 0893b2c..c75e2c0 100644 --- a/RotaxMonitor/src/isr.h +++ b/RotaxMonitor/src/isr.h @@ -99,6 +99,7 @@ struct ignitionBoxStatus // voltage from generator float volts_gen = 0.0; uint32_t n_queue_errors = 0; + uint32_t adc_read_time = 0; }; struct isrParams diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index a149e9e..ef60521 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -130,7 +130,7 @@ void loop() dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADC_A_SYNC, ADC_A_CS, 2.5, &SPI_A); dev.adc_a->InitializeADC(); dev.adc_a->setPGA(PGA_1); - dev.adc_a->setDRATE(DRATE_30000SPS); + dev.adc_a->setDRATE(DRATE_7500SPS); #ifndef TEST // Init ADC_B @@ -189,42 +189,45 @@ void loop() { if (xQueueReceive(rt_taskA_queue, &ignA, pdMS_TO_TICKS(1000)) == pdTRUE) { - if (ignA.coils12.spark_status == sparkStatus::SPARK_NEG_FAIL || ignA.coils12.spark_status == sparkStatus::SPARK_POS_FAIL) + float freq = (esp_timer_get_time() - last) / 1000000.0f; // in seconds + freq = freq > 0 ? 1.0f / freq : 0; // Calculate frequency (Hz) + last = esp_timer_get_time(); + + if (ignA.coils12.spark_status == sparkStatus::SPARK_POS_FAIL || ignA.coils12.spark_status == sparkStatus::SPARK_NEG_FAIL) missed_firings12++; if (ignA.coils34.spark_status == sparkStatus::SPARK_POS_FAIL || ignA.coils34.spark_status == sparkStatus::SPARK_NEG_FAIL) missed_firings34++; + clearScreen(); setCursor(0, 0); - printField("++ Timestamp", (uint32_t)ignA.timestamp, 0, 0); + printField("++ Timestamp", (uint32_t)ignA.timestamp); Serial.println("========== Coils 12 ============="); - printField("Events", (uint32_t)ignA.coils12.n_events, 0, 1); - printField("Missed Firing", missed_firings12, 0, 2); - printField("Spark Dly", (uint32_t)ignA.coils12.spark_delay, 0, 3); - printField("Spark Sts", sparkStatusNames.at(ignA.coils12.spark_status), 0, 4); - printField("Peak P_IN", ignA.coils12.peak_p_in, 0, 5); - printField("Peak N_IN", ignA.coils12.peak_n_in, 0, 7); - printField("Peak P_OUT", ignA.coils12.peak_p_out, 0, 6); - printField("Peak N_OUT", ignA.coils12.peak_n_out, 0, 8); - printField("Soft Start ", softStartStatusNames.at(ignA.coils12.sstart_status), 0, 9); + printField("Events", (uint32_t)ignA.coils12.n_events); + printField("Missed Firing", missed_firings12); + printField("Spark Dly", (uint32_t)ignA.coils12.spark_delay); + printField("Spark Sts", sparkStatusNames.at(ignA.coils12.spark_status)); + printField("Peak P_IN", ignA.coils12.peak_p_in); + printField("Peak N_IN", ignA.coils12.peak_n_in); + printField("Peak P_OUT", ignA.coils12.peak_p_out); + printField("Peak N_OUT", ignA.coils12.peak_n_out); + printField("Soft Start ", softStartStatusNames.at(ignA.coils12.sstart_status)); Serial.println("========== Coils 34 ============="); - printField("Events", (uint32_t)ignA.coils34.n_events, 0, 11); - printField("Missed Firing", missed_firings34, 0, 12); - printField("Spark Dly", (uint32_t)ignA.coils34.spark_delay, 0, 13); - printField("Spark Sts", sparkStatusNames.at(ignA.coils34.spark_status), 0, 14); - printField("Peak P_IN", ignA.coils34.peak_p_in, 0, 15); - printField("Peak N_IN", ignA.coils34.peak_n_in, 0, 17); - printField("Peak P_OUT", ignA.coils34.peak_p_out, 0, 16); - printField("Peak N_OUT", ignA.coils34.peak_n_out, 0, 18); - printField("Soft Start ", softStartStatusNames.at(ignA.coils34.sstart_status), 0, 19); + printField("Events", (uint32_t)ignA.coils34.n_events); + printField("Missed Firing", missed_firings34); + printField("Spark Dly", (uint32_t)ignA.coils34.spark_delay); + printField("Spark Sts", sparkStatusNames.at(ignA.coils34.spark_status)); + printField("Peak P_IN", ignA.coils34.peak_p_in); + printField("Peak N_IN", ignA.coils34.peak_n_in); + printField("Peak P_OUT", ignA.coils34.peak_p_out); + printField("Peak N_OUT", ignA.coils34.peak_n_out); + printField("Soft Start ", softStartStatusNames.at(ignA.coils34.sstart_status)); Serial.println("========== END ============="); Serial.println(); - auto freq = (esp_timer_get_time() - last) / 1000000.0f; // in seconds - freq = freq > 0 ? 1.0f / freq : 0; // Calculate frequency (Hz) - printField("Engine RPM", freqToRPM(freq), 0, 21); - printField("Queue Errors", (uint32_t)ignA.n_queue_errors, 0, 22); - last = esp_timer_get_time(); + printField("Engine RPM", freqToRPM(freq)); + printField("ADC Read Time", (uint32_t)ignA.adc_read_time); + printField("Queue Errors", (uint32_t)ignA.n_queue_errors); } else { diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 7f3348d..8a72bc0 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -254,6 +254,7 @@ void rtIgnitionTask(void *pvParameters) // read adc channels: pickup12, out12 [ pos + neg ] if (adc) // read only if adc initialized { + uint32_t start_adc_read = esp_timer_get_time(); // from peak detector circuits ign_box_sts.coils12.peak_p_in = adcReadChannel(adc, ADC_CH_PEAK_12P_IN); ign_box_sts.coils12.peak_n_in = adcReadChannel(adc, ADC_CH_PEAK_12N_IN); @@ -263,6 +264,7 @@ void rtIgnitionTask(void *pvParameters) ign_box_sts.coils12.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_12N_OUT); ign_box_sts.coils34.peak_p_out = adcReadChannel(adc, ADC_CH_PEAK_34P_OUT); ign_box_sts.coils34.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_34N_OUT); + ign_box_sts.adc_read_time = (uint32_t)(esp_timer_get_time() - start_adc_read); } else // simulate adc read timig vTaskDelay(pdMS_TO_TICKS(1)); diff --git a/RotaxMonitor/src/ui.h b/RotaxMonitor/src/ui.h index a9f8c9f..9c801be 100644 --- a/RotaxMonitor/src/ui.h +++ b/RotaxMonitor/src/ui.h @@ -2,58 +2,35 @@ #include -static bool firstRun = true; - -void clearScreen(){ +void clearScreen() +{ Serial.print("\033[2J"); // clear screen Serial.print("\033[H"); // cursor home Serial.flush(); } -void setCursor(const uint8_t x, const uint8_t y) { - Serial.printf("\033[%d;%d", y, x+1); +void setCursor(const uint8_t x, const uint8_t y) +{ + Serial.printf("\033[%d;%d", y, x + 1); Serial.flush(); } -void printField(const char name[], const uint32_t val, const uint8_t x, const uint8_t y) { - if (firstRun) { - setCursor(x,y); - Serial.printf("%15s: %06d\n", name, val); - return; - } - setCursor(x+16, y); - Serial.print(val); +void printField(const char name[], const uint32_t val) +{ + Serial.printf("%15s: %06d\n", name, val); } -void printField(const char name[], const int64_t val, const uint8_t x, const uint8_t y) { - if (firstRun) { - setCursor(x,y); - Serial.printf("%15s: %06u\n", name, (uint64_t)val); - return; - } - setCursor(x+16, y); - Serial.print((uint64_t)val); - Serial.flush(); +void printField(const char name[], const int64_t val) +{ + Serial.printf("%15s: %06u\n", name, (uint64_t)val); } -void printField(const char name[], const float val, const uint8_t x, const uint8_t y) { - if (firstRun) { - setCursor(x,y); - Serial.printf("%15s: %4.2f\n", name, val); - return; - } - setCursor(x+16, y); - Serial.print(val); - Serial.flush(); +void printField(const char name[], const float val) +{ + Serial.printf("%15s: %4.2f\n", name, val); } -void printField(const char name[], const char *val, const uint8_t x, const uint8_t y) { - if (firstRun) { - setCursor(x,y); - Serial.printf("%15s: %s\n", name, val); - return; - } - setCursor(x+16, y); - Serial.print(val); - Serial.flush(); +void printField(const char name[], const char *val) +{ + Serial.printf("%15s: %s\n", name, val); } \ No newline at end of file diff --git a/RotaxMonitorTester/platformio.ini b/RotaxMonitorTester/platformio.ini index 7e45ba0..2653613 100644 --- a/RotaxMonitorTester/platformio.ini +++ b/RotaxMonitorTester/platformio.ini @@ -16,7 +16,7 @@ lib_deps = hideakitai/DebugLog@^0.8.4 board_build.flash_size = 4MB board_build.partitions = default.csv -monitor_speed = 115200 +monitor_speed = 921600 build_type = release [env:esp32-devtest-debug] @@ -27,7 +27,7 @@ lib_deps = hideakitai/DebugLog@^0.8.4 board_build.flash_size = 4MB board_build.partitions = default.csv -monitor_speed = 115200 +monitor_speed = 921600 build_type = debug build_flags = -O0 diff --git a/RotaxMonitorTester/src/main.cpp b/RotaxMonitorTester/src/main.cpp index a9d6c66..ea657e7 100644 --- a/RotaxMonitorTester/src/main.cpp +++ b/RotaxMonitorTester/src/main.cpp @@ -18,13 +18,16 @@ static uint32_t count = 0; #define PAUSE_LONG_MIN 5000 #define PAUSE_LONG_MAX PAUSE_LONG_MIN*100 +#define RPM_MIN 800 +#define RPM_MAX 5500 + void clearScreen(){ Serial.print("\033[2J"); // clear screen Serial.print("\033[H"); // cursor home Serial.flush(); } -static double filtered = 0; +static double filtered_rpm = 0; static const std::map pin2Name = { {PIN_TRIG_A12P, "HIGH_PIN_TRIG_A12P"}, @@ -54,7 +57,7 @@ static timerStatus stsA = { void setup() { - Serial.begin(115200); + Serial.begin(921600); delay(1000); LOG_ATTACH_SERIAL(Serial); @@ -94,11 +97,11 @@ void loop() stsA.soft_start = false; } - double new_val = (float)(map(analogRead(FREQ_POT), 0, 4096, PAUSE_LONG_MIN, PAUSE_LONG_MAX)); - filtered = filtered + 0.1 * (new_val - filtered); - stsA.pause_long_us = (uint32_t)filtered; + double new_rpm = (double)(map(analogRead(FREQ_POT), 0, 4096, RPM_MIN, RPM_MAX)); + filtered_rpm = filtered_rpm + 0.1 * (new_rpm - filtered_rpm); + stsA.pause_long_us = (uint32_t)(60000000.0f / filtered_rpm / 2.0f); LOG_INFO("Spark Delay uS: ", stsA.spark_delay_us, "\tSoft Start: ", stsA.soft_start ? "TRUE" : "FALSE"); - LOG_INFO("Pause: ", (uint32_t)(stsA.pause_long_us / 1000), "ms"); + LOG_INFO("Engine Rpm: ", (uint32_t)(filtered_rpm)); LOG_INFO("Coil Pulse: ", stsA.coil_pulse_us, "us"); LOG_INFO("Spark Pulse: ", stsA.spark_pulse_us, "us"); From dc44decd6453a0e35f32a65f96c0d41aed59e2c7 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Tue, 7 Apr 2026 10:19:28 +0200 Subject: [PATCH 03/38] Moved files in libraries --- RotaxMonitor/{src => lib/ADS1256}/ADS1256.cpp | 0 RotaxMonitor/{src => lib/ADS1256}/ADS1256.h | 0 RotaxMonitor/{src => lib/ADS5292}/AD5292.cpp | 0 RotaxMonitor/{src => lib/ADS5292}/AD5292.h | 0 RotaxMonitor/src/channels.h | 11 ----------- RotaxMonitor/src/main.cpp | 1 - 6 files changed, 12 deletions(-) rename RotaxMonitor/{src => lib/ADS1256}/ADS1256.cpp (100%) rename RotaxMonitor/{src => lib/ADS1256}/ADS1256.h (100%) rename RotaxMonitor/{src => lib/ADS5292}/AD5292.cpp (100%) rename RotaxMonitor/{src => lib/ADS5292}/AD5292.h (100%) delete mode 100644 RotaxMonitor/src/channels.h diff --git a/RotaxMonitor/src/ADS1256.cpp b/RotaxMonitor/lib/ADS1256/ADS1256.cpp similarity index 100% rename from RotaxMonitor/src/ADS1256.cpp rename to RotaxMonitor/lib/ADS1256/ADS1256.cpp diff --git a/RotaxMonitor/src/ADS1256.h b/RotaxMonitor/lib/ADS1256/ADS1256.h similarity index 100% rename from RotaxMonitor/src/ADS1256.h rename to RotaxMonitor/lib/ADS1256/ADS1256.h diff --git a/RotaxMonitor/src/AD5292.cpp b/RotaxMonitor/lib/ADS5292/AD5292.cpp similarity index 100% rename from RotaxMonitor/src/AD5292.cpp rename to RotaxMonitor/lib/ADS5292/AD5292.cpp diff --git a/RotaxMonitor/src/AD5292.h b/RotaxMonitor/lib/ADS5292/AD5292.h similarity index 100% rename from RotaxMonitor/src/AD5292.h rename to RotaxMonitor/lib/ADS5292/AD5292.h diff --git a/RotaxMonitor/src/channels.h b/RotaxMonitor/src/channels.h deleted file mode 100644 index f305685..0000000 --- a/RotaxMonitor/src/channels.h +++ /dev/null @@ -1,11 +0,0 @@ -// ADC Channels - -#define A1_RAW 0 -#define A2_RAW 1 -#define B1_RAW 2 -#define B2_RAW 3 - -#define A1_COND 4 -#define A2_COND 5 -#define B1_COND 6 -#define B2_COND 7 diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index ef60521..c36dc41 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -8,7 +8,6 @@ // Definitions #include -#include #include #include From f36cb96f21334e031ec72dc6bcb842703fff2200 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Tue, 7 Apr 2026 10:51:53 +0200 Subject: [PATCH 04/38] Improved task code --- RotaxMonitor/src/isr.cpp | 7 +--- RotaxMonitor/src/isr.h | 18 ++++---- RotaxMonitor/src/main.cpp | 19 +++------ RotaxMonitor/src/tasks.cpp | 86 +++++++++++++------------------------- 4 files changed, 46 insertions(+), 84 deletions(-) diff --git a/RotaxMonitor/src/isr.cpp b/RotaxMonitor/src/isr.cpp index a0c84c9..aedd47c 100644 --- a/RotaxMonitor/src/isr.cpp +++ b/RotaxMonitor/src/isr.cpp @@ -36,18 +36,13 @@ void trig_isr(void *arg) xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); break; case SPARK_FLAG_12: - box->coils34.spark_ok = false; - box->coils12.spark_ok = true; + box->coils12.spark_time = time_us; xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - // vTaskNotifyGiveFromISR(task_handle, &xHigherPriorityTaskWoken); break; case SPARK_FLAG_34: - box->coils12.spark_ok = false; - box->coils34.spark_ok = true; box->coils34.spark_time = time_us; xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - // vTaskNotifyGiveFromISR(task_handle, &xHigherPriorityTaskWoken); break; default: break; diff --git a/RotaxMonitor/src/isr.h b/RotaxMonitor/src/isr.h index c75e2c0..c800b91 100644 --- a/RotaxMonitor/src/isr.h +++ b/RotaxMonitor/src/isr.h @@ -26,10 +26,9 @@ static const uint32_t TRIG_FLAG_12N = (1 << 1); static const uint32_t TRIG_FLAG_34P = (1 << 2); static const uint32_t TRIG_FLAG_34N = (1 << 3); -static const uint32_t SPARK_FLAG_NIL = (1 << 8); +static const uint32_t SPARK_FLAG_TIMEOUT = (1 << 8); static const uint32_t SPARK_FLAG_12 = (1 << 9); static const uint32_t SPARK_FLAG_34 = (1 << 10); -static const uint32_t SPARK_FLAG_TIMEOUT = (1 << 11); // Spark Status enum sparkStatus @@ -78,15 +77,15 @@ struct coilsStatus { int64_t trig_time = 0; int64_t spark_time = 0; - int64_t spark_delay = 0; // in microseconds + uint32_t spark_delay = 0; // in microseconds sparkStatus spark_status = sparkStatus::SPARK_POS_OK; softStartStatus sstart_status = softStartStatus::NORMAL; - float peak_p_in = 0.0, peak_n_in = 0.0; - float peak_p_out = 0.0, peak_n_out = 0.0; - float trigger_spark = 0.0; - bool spark_ok = false; + float peak_p_in = 0.0; + float peak_n_in = 0.0; + float peak_p_out = 0.0; + float peak_n_out = 0.0; + float level_spark = 0.0; uint32_t n_events = 0; - }; // Task internal Status @@ -98,6 +97,9 @@ struct ignitionBoxStatus coilsStatus coils34; // voltage from generator float volts_gen = 0.0; + // enine rpm + uint32_t eng_rpm = 0; + // debug values uint32_t n_queue_errors = 0; uint32_t adc_read_time = 0; }; diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index c36dc41..114f533 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -18,11 +18,6 @@ // #define CH_B_ENABLE #define TEST -float freqToRPM(float freq) -{ - return freq * 60.0f; // 1 pulse per revolution -} - void printTaskStats() { char buffer[1024]; @@ -188,10 +183,6 @@ void loop() { if (xQueueReceive(rt_taskA_queue, &ignA, pdMS_TO_TICKS(1000)) == pdTRUE) { - float freq = (esp_timer_get_time() - last) / 1000000.0f; // in seconds - freq = freq > 0 ? 1.0f / freq : 0; // Calculate frequency (Hz) - last = esp_timer_get_time(); - if (ignA.coils12.spark_status == sparkStatus::SPARK_POS_FAIL || ignA.coils12.spark_status == sparkStatus::SPARK_NEG_FAIL) missed_firings12++; if (ignA.coils34.spark_status == sparkStatus::SPARK_POS_FAIL || ignA.coils34.spark_status == sparkStatus::SPARK_NEG_FAIL) @@ -201,7 +192,7 @@ void loop() setCursor(0, 0); printField("++ Timestamp", (uint32_t)ignA.timestamp); Serial.println("========== Coils 12 ============="); - printField("Events", (uint32_t)ignA.coils12.n_events); + printField("Events", ignA.coils12.n_events); printField("Missed Firing", missed_firings12); printField("Spark Dly", (uint32_t)ignA.coils12.spark_delay); printField("Spark Sts", sparkStatusNames.at(ignA.coils12.spark_status)); @@ -212,7 +203,7 @@ void loop() printField("Soft Start ", softStartStatusNames.at(ignA.coils12.sstart_status)); Serial.println("========== Coils 34 ============="); - printField("Events", (uint32_t)ignA.coils34.n_events); + printField("Events", ignA.coils34.n_events); printField("Missed Firing", missed_firings34); printField("Spark Dly", (uint32_t)ignA.coils34.spark_delay); printField("Spark Sts", sparkStatusNames.at(ignA.coils34.spark_status)); @@ -224,9 +215,9 @@ void loop() Serial.println("========== END ============="); Serial.println(); - printField("Engine RPM", freqToRPM(freq)); - printField("ADC Read Time", (uint32_t)ignA.adc_read_time); - printField("Queue Errors", (uint32_t)ignA.n_queue_errors); + printField("Engine RPM", ignA.eng_rpm); + printField("ADC Read Time", ignA.adc_read_time); + printField("Queue Errors", ignA.n_queue_errors); } else { diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 8a72bc0..da3eeda 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -2,7 +2,8 @@ #include // Timeout callback for microsecond precision -void spark_timeout_callback(void* arg) { +void spark_timeout_callback(void *arg) +{ TaskHandle_t handle = (TaskHandle_t)arg; xTaskNotify(handle, SPARK_FLAG_TIMEOUT, eSetValueWithOverwrite); } @@ -55,17 +56,16 @@ void rtIgnitionTask(void *pvParameters) .flag = SPARK_FLAG_34, .ign_stat = &ign_box_sts, .rt_handle_ptr = rt_handle_ptr}; - + LOG_INFO("rtTask ISR Params OK"); // Create esp_timer for microsecond precision timeout esp_timer_handle_t timeout_timer; esp_timer_create_args_t timer_args = { .callback = spark_timeout_callback, - .arg = (void*)rt_handle_ptr, + .arg = (void *)rt_handle_ptr, .dispatch_method = ESP_TIMER_TASK, - .name = "spark_timeout" - }; + .name = "spark_timeout"}; esp_timer_create(&timer_args, &timeout_timer); // Attach Pin Interrupts @@ -89,6 +89,8 @@ void rtIgnitionTask(void *pvParameters) bool first_cycle = true; bool cycle12 = false; bool cycle34 = false; + int64_t last_cycle_time = 0; + uint32_t n_errors = 0; while (params->rt_running) { @@ -101,11 +103,9 @@ void rtIgnitionTask(void *pvParameters) ULONG_MAX, // pulisci i primi 8 bit &pickup_flag, // valore ricevuto portMAX_DELAY); - + if (first_cycle && pickup_flag != TRIG_FLAG_12P) // skip first cycle because of possible initial noise on pickup signals at startu - { continue; - } #ifdef DEBUG Serial.print("\033[2J"); // clear screen @@ -128,35 +128,19 @@ void rtIgnitionTask(void *pvParameters) esp_timer_stop(timeout_timer); // stop timer in case it was running from previous cycle esp_timer_start_once(timeout_timer, spark_timeout_max); - spark_flag = SPARK_FLAG_NIL; // default value in case of timeout, to be set by ISR if spark event occours // WAIT FOR SPARK TO HAPPEN OR TIMEOUT - BaseType_t sp = pdFALSE; - sp = xTaskNotifyWait( - 0x00, // non pulire all'ingresso - ULONG_MAX, // pulisci i primi 8 bit - &spark_flag, // valore ricevuto + xTaskNotifyWait( + 0x00, // non pulire all'ingresso + ULONG_MAX, // pulisci i primi 8 bit + &spark_flag, // valore ricevuto portMAX_DELAY); // wait indefinitely, timeout handled by esp_timer // Handle timeout or spark event - if (spark_flag == SPARK_FLAG_TIMEOUT) { - spark_flag = SPARK_FLAG_NIL; - } else { - // Spark occurred, stop the timer + if (spark_flag != SPARK_FLAG_TIMEOUT) esp_timer_stop(timeout_timer); - } - -#ifdef DEBUG - // LOG_INFO("Spark Flags: ", printBits(spark_flag).c_str()); - LOG_INFO("Spark12:", ign_box_sts.coils12.spark_ok ? "TRUE" : "FALSE"); - LOG_INFO("Spark34:", ign_box_sts.coils34.spark_ok ? "TRUE" : "FALSE"); - if (names.contains(spark_flag)) - LOG_INFO("Spark Trigger:", names.at(spark_flag)); -#endif - xTaskNotifyStateClear(NULL); - ulTaskNotifyValueClear(NULL, 0xFFFFFFFF); // A trigger from pickup 12 is followed by a spark event on 34 or vice versa pickup 34 triggers spark on 12 - if ((pickup_flag == TRIG_FLAG_12P || pickup_flag == TRIG_FLAG_12N) && (spark_flag != SPARK_FLAG_12 && spark_flag != SPARK_FLAG_NIL)) + if ((pickup_flag == TRIG_FLAG_12P || pickup_flag == TRIG_FLAG_12N) && (spark_flag != SPARK_FLAG_12 && spark_flag != SPARK_FLAG_TIMEOUT)) { ign_box_sts.coils12.spark_status = ign_box_sts.coils34.spark_status = sparkStatus::SPARK_SYNC_FAIL; continue; @@ -167,7 +151,14 @@ void rtIgnitionTask(void *pvParameters) switch (pickup_flag) { case TRIG_FLAG_12P: + { first_cycle = false; + // compute engine rpm from cycle time + auto current_time = esp_timer_get_time(); + auto cycle_time = current_time - last_cycle_time; + last_cycle_time = current_time; + ign_box_sts.eng_rpm = (uint32_t)(60.0f / (cycle_time / 1000000.0f)); + } case TRIG_FLAG_12N: coils = &ign_box_sts.coils12; break; @@ -184,18 +175,14 @@ void rtIgnitionTask(void *pvParameters) case TRIG_FLAG_34P: { // Timeout not occourred, expected POSITIVE edge spark OCCOURRED - if (spark_flag != SPARK_FLAG_NIL) + if (spark_flag != SPARK_FLAG_TIMEOUT) { - coils->spark_delay = coils->spark_time - coils->trig_time; + coils->spark_delay = (uint32_t)(coils->spark_time - coils->trig_time); coils->sstart_status = softStartStatus::NORMAL; // because spark on positive edge coils->spark_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge -#ifdef DEBUG - LOG_INFO("Spark on POSITIVE pulse"); - LOG_INFO("Spark Delay Time: ", (int32_t)coils->spark_delay); -#endif } // Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED - else if (spark_flag == SPARK_FLAG_NIL) + else if (spark_flag == SPARK_FLAG_TIMEOUT) { coils->spark_status = sparkStatus::SPARK_NEG_WAIT; coils->sstart_status = softStartStatus::NORMAL; @@ -208,24 +195,20 @@ void rtIgnitionTask(void *pvParameters) { const bool expected_negative = coils->spark_status == sparkStatus::SPARK_NEG_WAIT; // Timeout not occourred, expected NEGATIVE edge spark OCCOURRED - if (spark_flag != SPARK_FLAG_NIL && expected_negative) + if (spark_flag != SPARK_FLAG_TIMEOUT && expected_negative) { - coils->spark_delay = coils->spark_time - coils->trig_time; + coils->spark_delay = (uint32_t)(coils->spark_time - coils->trig_time); coils->sstart_status = softStartStatus::SOFT_START; coils->spark_status = sparkStatus::SPARK_NEG_OK; -#ifdef DEBUG - LOG_INFO("Spark on NEGATIVE pulse"); - LOG_INFO("Spark Delay Time: ", (int32_t)coils->spark_delay); -#endif } // Timeout occourred, expected POSITIVE edge spark NOT OCCOURRED - else if (spark_flag == SPARK_FLAG_NIL && expected_negative) + else if (spark_flag == SPARK_FLAG_TIMEOUT && expected_negative) { coils->sstart_status = softStartStatus::ERROR; coils->spark_status = sparkStatus::SPARK_NEG_FAIL; } // Timeout not occouured, unexpected negative edge spark - else if (spark_flag != SPARK_FLAG_NIL && !expected_negative) + else if (spark_flag != SPARK_FLAG_TIMEOUT && !expected_negative) { coils->sstart_status = softStartStatus::SOFT_START; coils->spark_status = sparkStatus::SPARK_NEG_UNEXPECTED; @@ -239,11 +222,6 @@ void rtIgnitionTask(void *pvParameters) break; } default: -#ifdef DEUG - LOG_ERROR("Invalid Interrupt"); - LOG_ERROR("Pickup Flags: ", printBits(pickup_flag).c_str()); - LOG_ERROR("Spark Flags: ", printBits(spark_flag).c_str()); -#endif break; } @@ -251,6 +229,7 @@ void rtIgnitionTask(void *pvParameters) { cycle12 = false; cycle34 = false; + // read adc channels: pickup12, out12 [ pos + neg ] if (adc) // read only if adc initialized { @@ -285,12 +264,7 @@ void rtIgnitionTask(void *pvParameters) if (rt_queue) ign_box_sts.timestamp = esp_timer_get_time(); // update data timestamp if (xQueueSendToBack(rt_queue, (void *)&ign_box_sts, 0) != pdPASS) - { - static uint32_t n_errors = 0; - n_errors++; - ign_box_sts.n_queue_errors = n_errors; - LOG_ERROR("Failed to send to rt_queue"); - } + ign_box_sts.n_queue_errors = ++n_errors; } } // Delete the timeout timer From 668b590d7cf418363cfcbec8a5382bd4460af78f Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Tue, 7 Apr 2026 13:21:27 +0200 Subject: [PATCH 05/38] CSV file save on SPIFF filesystem, 10MB on internal flash --- RotaxMonitor/data/config.json | 1 + .../partitions/no_ota_10mb_spiffs.csv | 6 + RotaxMonitor/platformio.ini | 10 +- RotaxMonitor/src/datasave.cpp | 60 ++ RotaxMonitor/src/datasave.h | 24 + RotaxMonitor/src/isr.h | 4 +- RotaxMonitor/src/main.cpp | 62 +- RotaxMonitor/src/psvector.h | 30 + RotaxMonitor/src/utils.h | 7 + RotaxMonitor/unpacked_fs/ignA_history.csv | 855 ++++++++++++++++++ .../unpacked_fs/spiffs/ignA_history.bin | Bin 0 -> 116966 bytes 11 files changed, 1032 insertions(+), 27 deletions(-) create mode 100644 RotaxMonitor/data/config.json create mode 100644 RotaxMonitor/partitions/no_ota_10mb_spiffs.csv create mode 100644 RotaxMonitor/src/datasave.cpp create mode 100644 RotaxMonitor/src/datasave.h create mode 100644 RotaxMonitor/src/psvector.h create mode 100644 RotaxMonitor/unpacked_fs/ignA_history.csv create mode 100644 RotaxMonitor/unpacked_fs/spiffs/ignA_history.bin diff --git a/RotaxMonitor/data/config.json b/RotaxMonitor/data/config.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/RotaxMonitor/data/config.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/RotaxMonitor/partitions/no_ota_10mb_spiffs.csv b/RotaxMonitor/partitions/no_ota_10mb_spiffs.csv new file mode 100644 index 0000000..0ee5735 --- /dev/null +++ b/RotaxMonitor/partitions/no_ota_10mb_spiffs.csv @@ -0,0 +1,6 @@ +# ESP32 Partition Table +# Name, Type, SubType, Offset, Size +nvs, data, nvs, 0x9000, 0x4000 +phy_init, data, phy, 0xd000, 0x1000 +factory, app, factory, 0x10000, 0x5F0000 +spiffs, data, spiffs, 0x600000, 0xA00000 \ No newline at end of file diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 117d9d2..808c594 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -10,6 +10,7 @@ [env:esp32-s3-devkitc1-n16r8] board = esp32-s3-devkitc1-n16r8 +board_build.partitions = partitions/no_ota_10mb_spiffs.csv platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip framework = arduino lib_deps = @@ -21,11 +22,11 @@ lib_deps = ;Upload protocol configuration upload_protocol = esptool -upload_port = /dev/ttyACM2 +upload_port = COM8 upload_speed = 921600 ;Monitor configuration -monitor_port = /dev/ttyACM2 +monitor_port = COM4 monitor_speed = 921600 ; Build configuration @@ -39,17 +40,18 @@ build_flags = [env:esp32-s3-devkitc1-n16r8-debug] board = ${env:esp32-s3-devkitc1-n16r8.board} +board_build.partitions = ${env:esp32-s3-devkitc1-n16r8.board_build.partitions} platform = ${env:esp32-s3-devkitc1-n16r8.platform} framework = ${env:esp32-s3-devkitc1-n16r8.framework} lib_deps = ${env:esp32-s3-devkitc1-n16r8.lib_deps} ;Upload protocol configuration upload_protocol = esptool -upload_port = /dev/ttyACM2 +upload_port = COM4 upload_speed = 921600 ;Monitor configuration -monitor_port = /dev/ttyACM2 +monitor_port = COM4 monitor_speed = 921600 ; Debug configuration diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp new file mode 100644 index 0000000..222004b --- /dev/null +++ b/RotaxMonitor/src/datasave.cpp @@ -0,0 +1,60 @@ +#include "datasave.h" + +void save_history(const PSRAMVector &history) +{ + // Initialize SPIFFS + if (!SPIFFS.begin(true)) + { + LOG_ERROR("Failed to mount SPIFFS"); + LOG_ERROR("5 seconds to restart..."); + vTaskDelay(pdMS_TO_TICKS(5000)); + esp_restart(); + } + else + { + LOG_INFO("SPIFFS mounted successfully"); + return; + } + + std::ofstream ofs("/spiffs/ignA_history.csv", std::ios::out | std::ios::trunc); + if (ofs.fail()) + { + LOG_ERROR("Failed to open file for writing"); + return; + } + + //write csv header + ofs << "TS,\ + EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ + EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ + ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS"; + for (auto &entry : history) + { + ofs << std::to_string(entry.timestamp) << "," + << std::to_string(entry.coils12.n_events) << "," + << std::to_string(entry.coils12.spark_delay) << "," + << std::string(sparkStatusNames.at(entry.coils12.spark_status)) << "," + << std::to_string(entry.coils12.peak_p_in) << "," + << std::to_string(entry.coils12.peak_n_in) << "," + << std::to_string(entry.coils12.peak_p_out) << "," + << std::to_string(entry.coils12.peak_n_out) << "," + << std::string(softStartStatusNames.at(entry.coils12.sstart_status)) << "," + << std::to_string(entry.coils34.n_events) << "," + << std::to_string(entry.coils34.spark_delay) << "," + << std::string(sparkStatusNames.at(entry.coils34.spark_status)) << "," + << std::to_string(entry.coils34.peak_p_in) << "," + << std::to_string(entry.coils34.peak_n_in) << "," + << std::to_string(entry.coils34.peak_p_out) << "," + << std::to_string(entry.coils34.peak_n_out) << "," + << std::string(softStartStatusNames.at(entry.coils34.sstart_status)) << "," + << std::to_string(entry.eng_rpm) << "," + << std::to_string(entry.adc_read_time) << "," + << std::to_string(entry.n_queue_errors); + ofs << std::endl; + } + auto written_bytes = ofs.tellp(); + ofs.flush(); + ofs.close(); + LOG_INFO("Ignition A history saved to SPIFFS, bytes written: ", (uint32_t)written_bytes); + SPIFFS.end(); // unmount SPIFFS to ensure data is written and avoid corruption on next mount +} \ No newline at end of file diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h new file mode 100644 index 0000000..e54efb1 --- /dev/null +++ b/RotaxMonitor/src/datasave.h @@ -0,0 +1,24 @@ +#pragma once + +// System Includes +#include +#include +#include +#include +#include + +// Project Includes +#include "isr.h" +#include "psvector.h" + +const bool SAVE_HISTORY_TO_SPIFFS = true; // Set to true to enable saving history to SPIFFS, false to disable + +static void saveHistoryTask(void *pvParameters) +{ + auto *history = static_cast *>(pvParameters); + save_history(*history); + vTaskDelete(NULL); +} + +void save_history(const PSRAMVector &history); + diff --git a/RotaxMonitor/src/isr.h b/RotaxMonitor/src/isr.h index c800b91..c696bfc 100644 --- a/RotaxMonitor/src/isr.h +++ b/RotaxMonitor/src/isr.h @@ -15,8 +15,8 @@ #define CORE_0 0 #define CORE_1 1 -#define TASK_STACK 4096 // in words -#define TASK_PRIORITY (configMAX_PRIORITIES - 4) // highest priority after wifi tasks +#define RT_TASK_STACK 4096 // in words +#define RT_TASK_PRIORITY (configMAX_PRIORITIES - 4) // highest priority after wifi tasks // ===================== // Event Flags (bitmask) diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 114f533..32e7ab0 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -9,6 +9,8 @@ // Definitions #include #include +#include +#include #include // FreeRTOS directives @@ -18,13 +20,6 @@ // #define CH_B_ENABLE #define TEST -void printTaskStats() -{ - char buffer[1024]; - vTaskGetRunTimeStats(buffer); - Serial.println(buffer); -} - void setup() { Serial.begin(921600); @@ -56,14 +51,22 @@ void loop() { // global variables bool running = true; - static Devices dev; + const uint32_t max_history = 1024; + const uint32_t max_queue = 128; + PSRAMVector ignA_history_0(max_history); + PSRAMVector ignA_history_1(max_history); + auto &active_history = ignA_history_0; + auto &writable_history = ignA_history_1; + + // Resources Initialization + static Devices dev; // Task handle static TaskHandle_t trigA_TaskHandle = NULL; static TaskHandle_t trigB_TaskHandle = NULL; - - static QueueHandle_t rt_taskA_queue = xQueueCreate(10, sizeof(ignitionBoxStatus)); - static QueueHandle_t rt_taskB_queue = xQueueCreate(10, sizeof(ignitionBoxStatus)); + // Data Queue for real time task to main loop communication + static QueueHandle_t rt_taskA_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); + static QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); static rtTaskParams taskA_params{ .rt_running = true, .dev = &dev, @@ -82,7 +85,7 @@ void loop() LOG_INFO("Task Variables OK"); #ifdef CH_B_ENABLE - QueueHandle_t rt_taskB_queue = xQueueCreate(10, sizeof(ignitionBoxStatus)); + QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); rtTaskParams taskB_params{ .rt_running = true, .dev = &dev, @@ -99,18 +102,19 @@ void loop() .rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_B12P, .rst_io_12n = RST_EXT_B12N, .rst_io_34p = RST_EXT_B34P, .rst_io_34n = RST_EXT_B34N}}; #endif + + // Spi ok flags bool spiA_ok = true; bool spiB_ok = true; - // Init 2 SPI interfaces SPIClass SPI_A(FSPI); spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 - #ifndef TEST +#ifndef TEST SPIClass SPI_B(HSPI); spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 - #endif +#endif if (!spiA_ok || !spiB_ok) { LOG_ERROR("Unable to Initialize SPI Busses"); @@ -141,9 +145,9 @@ void loop() ignA_task_success = xTaskCreatePinnedToCore( rtIgnitionTask, "rtIgnitionTask_boxA", - TASK_STACK, + RT_TASK_STACK, (void *)&taskA_params, - TASK_PRIORITY, + RT_TASK_PRIORITY, &trigA_TaskHandle, CORE_0); @@ -153,16 +157,16 @@ void loop() ignB_task_success = xTaskCreatePinnedToCore( rtIgnitionTask, "rtIgnitionTask_boxB", - TASK_STACK, + RT_TASK_STACK, (void *)&taskB_params, - TASK_PRIORITY, // priorità leggermente più alta + RT_TASK_PRIORITY, // priorità leggermente più alta &trigB_TaskHandle, CORE_1); #endif if ((ignA_task_success && ignB_task_success) != pdPASS) { - LOG_ERROR("Unble to initialize ISR task"); + LOG_ERROR("Una ble to initialize ISR task"); LOG_ERROR("5 seconds to restart..."); vTaskDelay(pdMS_TO_TICKS(5000)); esp_restart(); @@ -173,14 +177,28 @@ void loop() ////////////////////// MAIN LOOP ////////////////////// clearScreen(); setCursor(0, 0); + uint32_t counter = 0; ignitionBoxStatus ignA; int64_t last = esp_timer_get_time(); uint32_t missed_firings12 = 0; uint32_t missed_firings34 = 0; - uint32_t counter = 0; while (running) { + if (counter == active_history.size()) + { + counter = 0; + std::swap(active_history, writable_history); // switch active and writable buffers + if (SAVE_HISTORY_TO_SPIFFS) + xTaskCreate( + saveHistoryTask, + "saveHistoryTask", + RT_TASK_STACK / 2, + &writable_history, + RT_TASK_PRIORITY + 1, // higher priority to ensure it runs asap after buffer switch + NULL); + } + if (xQueueReceive(rt_taskA_queue, &ignA, pdMS_TO_TICKS(1000)) == pdTRUE) { if (ignA.coils12.spark_status == sparkStatus::SPARK_POS_FAIL || ignA.coils12.spark_status == sparkStatus::SPARK_NEG_FAIL) @@ -218,6 +236,8 @@ void loop() printField("Engine RPM", ignA.eng_rpm); printField("ADC Read Time", ignA.adc_read_time); printField("Queue Errors", ignA.n_queue_errors); + + active_history[counter++ % active_history.size()] = ignA; } else { diff --git a/RotaxMonitor/src/psvector.h b/RotaxMonitor/src/psvector.h new file mode 100644 index 0000000..43d9cf7 --- /dev/null +++ b/RotaxMonitor/src/psvector.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include "esp_heap_caps.h" + +// Allocator custom per PSRAM +template +struct PSRAMAllocator { + using value_type = T; + + PSRAMAllocator() noexcept {} + + template + PSRAMAllocator(const PSRAMAllocator&) noexcept {} + + T* allocate(std::size_t n) { + void* ptr = heap_caps_malloc(n * sizeof(T), MALLOC_CAP_SPIRAM); + if (!ptr) { + throw std::bad_alloc(); + } + return static_cast(ptr); + } + + void deallocate(T* p, std::size_t) noexcept { + heap_caps_free(p); + } +}; + +template +using PSRAMVector = std::vector>; diff --git a/RotaxMonitor/src/utils.h b/RotaxMonitor/src/utils.h index 2a1bf71..7627292 100644 --- a/RotaxMonitor/src/utils.h +++ b/RotaxMonitor/src/utils.h @@ -4,3 +4,10 @@ #include std::string printBits(uint32_t value); + +static void saveHistoryTask(void *pvParameters) +{ + auto *history = static_cast *>(pvParameters); + save_history(*history); + vTaskDelete(NULL); +} \ No newline at end of file diff --git a/RotaxMonitor/unpacked_fs/ignA_history.csv b/RotaxMonitor/unpacked_fs/ignA_history.csv new file mode 100644 index 0000000..1a6c67e --- /dev/null +++ b/RotaxMonitor/unpacked_fs/ignA_history.csv @@ -0,0 +1,855 @@ +TS,EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS +10821894,171,220,SPARK_NEG_OK,0.291874,0.321984,0.352346,0.354453,SOFT_START,171,221,SPARK_NEG_OK,0.356878,0.361823,0.277541,0.004770,SOFT_START,1293,4274,0 +10867894,172,220,SPARK_NEG_OK,0.291641,0.321847,0.352141,0.354271,SOFT_START,172,220,SPARK_NEG_OK,0.356699,0.361621,0.277369,0.004770,SOFT_START,1302,4207,0 +10913894,173,220,SPARK_NEG_OK,0.291452,0.321704,0.351960,0.354081,SOFT_START,173,220,SPARK_NEG_OK,0.356535,0.361444,0.277177,0.004786,SOFT_START,1302,4261,0 +10959894,174,221,SPARK_NEG_OK,0.291214,0.321550,0.351793,0.353897,SOFT_START,174,220,SPARK_NEG_OK,0.356338,0.361255,0.276995,0.004792,SOFT_START,1310,4269,0 +11004895,175,220,SPARK_NEG_OK,0.290992,0.321397,0.351586,0.353711,SOFT_START,175,190,SPARK_NEG_OK,0.356162,0.361081,0.276814,0.004815,SOFT_START,1312,4244,0 +11050894,176,190,SPARK_NEG_OK,0.290810,0.321243,0.351415,0.353529,SOFT_START,176,191,SPARK_NEG_OK,0.355985,0.360872,0.276650,0.004836,SOFT_START,1317,4224,0 +11095894,177,190,SPARK_NEG_OK,0.290591,0.321098,0.351211,0.353335,SOFT_START,177,190,SPARK_NEG_OK,0.355766,0.360683,0.276479,0.004852,SOFT_START,1319,4206,0 +11141894,178,150,SPARK_NEG_OK,0.290401,0.320932,0.351018,0.353144,SOFT_START,178,150,SPARK_NEG_OK,0.355611,0.360506,0.276300,0.004860,SOFT_START,1319,4163,0 +11186894,179,151,SPARK_NEG_OK,0.290195,0.320794,0.350831,0.352983,SOFT_START,179,150,SPARK_NEG_OK,0.355431,0.360326,0.276120,0.004873,SOFT_START,1322,4264,0 +11232894,180,120,SPARK_NEG_OK,0.290006,0.320647,0.350667,0.352789,SOFT_START,180,120,SPARK_NEG_OK,0.355256,0.360150,0.275930,0.004894,SOFT_START,1320,4196,0 +11277894,181,120,SPARK_NEG_OK,0.289753,0.320502,0.350458,0.352589,SOFT_START,181,121,SPARK_NEG_OK,0.355072,0.359924,0.275752,0.004888,SOFT_START,1322,4272,0 +11322894,182,121,SPARK_NEG_OK,0.289555,0.320359,0.350283,0.352405,SOFT_START,182,90,SPARK_NEG_OK,0.354874,0.359756,0.275572,0.004894,SOFT_START,1322,4203,0 +11368894,183,90,SPARK_NEG_OK,0.289374,0.320207,0.350096,0.352215,SOFT_START,183,90,SPARK_NEG_OK,0.354710,0.359569,0.275415,0.004900,SOFT_START,1312,4157,0 +11414894,184,91,SPARK_NEG_OK,0.289163,0.320063,0.349897,0.352047,SOFT_START,184,61,SPARK_NEG_OK,0.354533,0.359383,0.275223,0.004900,SOFT_START,1314,4224,0 +11460894,185,60,SPARK_NEG_OK,0.288991,0.319898,0.349711,0.351868,SOFT_START,185,60,SPARK_NEG_OK,0.354339,0.359212,0.275054,0.004936,SOFT_START,1307,4160,0 +11506894,186,60,SPARK_NEG_OK,0.288769,0.319761,0.349534,0.351666,SOFT_START,186,61,SPARK_NEG_OK,0.354161,0.359017,0.274898,0.004913,SOFT_START,1302,4227,0 +11552894,187,30,SPARK_NEG_OK,0.288572,0.319604,0.349340,0.351484,SOFT_START,187,30,SPARK_NEG_OK,0.353971,0.358836,0.274721,0.004925,SOFT_START,1294,4175,0 +11599894,188,28,SPARK_NEG_OK,0.288355,0.319456,0.349131,0.351307,SOFT_START,188,30,SPARK_NEG_OK,0.353799,0.358637,0.274544,0.004942,SOFT_START,1288,4275,0 +11765894,189,220,SPARK_POS_OK,0.288172,0.319344,0.349020,0.351149,NORMAL,189,220,SPARK_POS_OK,0.353638,0.358481,0.274398,0.004628,NORMAL,1266,4262,0 +11812894,190,221,SPARK_POS_OK,0.287986,0.319201,0.348818,0.350974,NORMAL,190,220,SPARK_POS_OK,0.353460,0.358317,0.274234,0.004650,NORMAL,1259,4216,0 +11861894,191,200,SPARK_POS_OK,0.287738,0.319054,0.348635,0.350789,NORMAL,191,200,SPARK_POS_OK,0.353298,0.358120,0.274066,0.004659,NORMAL,1238,4274,0 +11909894,192,201,SPARK_POS_OK,0.287534,0.318898,0.348458,0.350605,NORMAL,192,200,SPARK_POS_OK,0.353095,0.357934,0.273899,0.004672,NORMAL,1239,4247,0 +11958894,193,170,SPARK_POS_OK,0.287327,0.318753,0.348269,0.350417,NORMAL,193,200,SPARK_POS_OK,0.352935,0.357761,0.273730,0.004690,NORMAL,1227,4264,0 +12007894,194,170,SPARK_POS_OK,0.287136,0.318620,0.348067,0.350251,NORMAL,194,171,SPARK_POS_OK,0.352752,0.357563,0.273559,0.004696,NORMAL,1216,4158,0 +12057894,195,141,SPARK_POS_OK,0.286947,0.318474,0.347898,0.350049,NORMAL,195,170,SPARK_POS_OK,0.352559,0.357398,0.273376,0.004699,NORMAL,1205,4218,0 +12107894,196,140,SPARK_POS_OK,0.286708,0.318314,0.347713,0.349872,NORMAL,196,140,SPARK_POS_OK,0.352387,0.357202,0.273208,0.004697,NORMAL,1195,4280,0 +12158894,197,110,SPARK_POS_OK,0.286518,0.318181,0.347544,0.349692,NORMAL,197,140,SPARK_POS_OK,0.352211,0.357017,0.273015,0.004702,NORMAL,1183,4229,0 +12209894,198,111,SPARK_POS_OK,0.286322,0.318015,0.347342,0.349513,NORMAL,198,110,SPARK_POS_OK,0.352041,0.356835,0.272858,0.004721,NORMAL,1173,4163,0 +12261894,199,90,SPARK_POS_OK,0.286103,0.317878,0.347158,0.349329,NORMAL,199,110,SPARK_POS_OK,0.351862,0.356678,0.272691,0.004691,NORMAL,1161,4237,0 +12313894,200,90,SPARK_POS_OK,0.285903,0.317712,0.346979,0.349131,NORMAL,200,91,SPARK_POS_OK,0.351683,0.356466,0.272512,0.004713,NORMAL,1151,4264,0 +12366894,201,71,SPARK_POS_OK,0.285721,0.317584,0.346802,0.348973,NORMAL,201,92,SPARK_POS_OK,0.351498,0.356287,0.272346,0.004697,NORMAL,1138,4196,0 +12419894,202,71,SPARK_POS_OK,0.285524,0.317419,0.346613,0.348784,NORMAL,202,70,SPARK_POS_OK,0.351300,0.356096,0.272186,0.004708,NORMAL,1126,4156,0 +12473894,203,60,SPARK_POS_OK,0.285331,0.317279,0.346447,0.348594,NORMAL,203,70,SPARK_POS_OK,0.351147,0.355921,0.271999,0.004705,NORMAL,1113,4269,0 +12527894,204,60,SPARK_POS_OK,0.285091,0.317123,0.346253,0.348431,NORMAL,204,61,SPARK_POS_OK,0.350962,0.355725,0.271855,0.004699,NORMAL,1102,4243,0 +12582894,205,60,SPARK_POS_OK,0.284925,0.317021,0.346054,0.348216,NORMAL,205,61,SPARK_POS_OK,0.350796,0.355549,0.271656,0.004687,NORMAL,1091,4195,0 +12638894,206,60,SPARK_POS_OK,0.284721,0.316844,0.345879,0.348051,NORMAL,206,61,SPARK_POS_OK,0.350621,0.355390,0.271497,0.004652,NORMAL,1082,4239,0 +12694894,207,60,SPARK_POS_OK,0.284523,0.316696,0.345726,0.347897,NORMAL,207,61,SPARK_POS_OK,0.350435,0.355192,0.271319,0.004679,NORMAL,1065,4209,0 +12750894,208,60,SPARK_POS_OK,0.284311,0.316560,0.345530,0.347692,NORMAL,208,60,SPARK_POS_OK,0.350261,0.355031,0.271155,0.004650,NORMAL,1066,4228,0 +12807894,209,60,SPARK_POS_OK,0.284136,0.316435,0.345343,0.347521,NORMAL,209,60,SPARK_POS_OK,0.350083,0.354824,0.270969,0.004657,NORMAL,1050,4179,0 +12864894,210,60,SPARK_POS_OK,0.283932,0.316269,0.345162,0.347337,NORMAL,210,60,SPARK_POS_OK,0.349925,0.354653,0.270828,0.004632,NORMAL,1051,4177,0 +12922894,211,70,SPARK_POS_OK,0.283749,0.316133,0.344989,0.347164,NORMAL,211,70,SPARK_POS_OK,0.349733,0.354481,0.270671,0.004617,NORMAL,1034,4180,0 +12981894,212,80,SPARK_POS_OK,0.283555,0.315993,0.344810,0.346988,NORMAL,212,69,SPARK_POS_OK,0.349549,0.354288,0.270514,0.004611,NORMAL,1027,4192,0 +13040894,213,80,SPARK_POS_OK,0.283352,0.315846,0.344626,0.346801,NORMAL,213,81,SPARK_POS_OK,0.349369,0.354108,0.270325,0.004593,NORMAL,1021,4268,0 +13099894,214,90,SPARK_POS_OK,0.283144,0.315697,0.344451,0.346639,NORMAL,214,81,SPARK_POS_OK,0.349219,0.353949,0.270138,0.004584,NORMAL,1015,4275,0 +13158894,215,90,SPARK_POS_OK,0.282967,0.315561,0.344267,0.346466,NORMAL,215,91,SPARK_POS_OK,0.349048,0.353755,0.269985,0.004572,NORMAL,1012,4186,0 +13217894,216,110,SPARK_POS_OK,0.282770,0.315417,0.344096,0.346274,NORMAL,216,110,SPARK_POS_OK,0.348860,0.353565,0.269793,0.004562,NORMAL,1006,4189,0 +13277894,217,111,SPARK_POS_OK,0.282574,0.315275,0.343914,0.346095,NORMAL,217,110,SPARK_POS_OK,0.348682,0.353402,0.269661,0.004547,NORMAL,1007,4241,0 +13337894,218,130,SPARK_POS_OK,0.282375,0.315123,0.343747,0.345913,NORMAL,218,130,SPARK_POS_OK,0.348535,0.353219,0.269510,0.004527,NORMAL,1003,4217,0 +13397894,219,140,SPARK_POS_OK,0.282168,0.314994,0.343540,0.345718,NORMAL,219,130,SPARK_POS_OK,0.348333,0.353041,0.269329,0.004525,NORMAL,1002,4247,0 +13456894,220,140,SPARK_POS_OK,0.281945,0.314833,0.343373,0.345567,NORMAL,220,140,SPARK_POS_OK,0.348171,0.352871,0.269172,0.004499,NORMAL,1002,4246,0 +13516894,221,160,SPARK_POS_OK,0.281780,0.314691,0.343198,0.345380,NORMAL,221,141,SPARK_POS_OK,0.347996,0.352697,0.268990,0.004496,NORMAL,1000,4185,0 +13576894,222,158,SPARK_POS_OK,0.281596,0.314552,0.343024,0.345215,NORMAL,222,161,SPARK_POS_OK,0.347838,0.352506,0.268822,0.004497,NORMAL,1001,4161,0 +13636894,223,181,SPARK_POS_OK,0.281394,0.314416,0.342835,0.345027,NORMAL,223,180,SPARK_POS_OK,0.347647,0.352321,0.268661,0.004486,NORMAL,1004,4179,0 +13696894,224,181,SPARK_POS_OK,0.281194,0.314263,0.342656,0.344863,NORMAL,224,180,SPARK_POS_OK,0.347478,0.352163,0.268500,0.004463,NORMAL,1005,4245,0 +13755894,225,201,SPARK_POS_OK,0.281022,0.314121,0.342464,0.344678,NORMAL,225,200,SPARK_POS_OK,0.347285,0.351969,0.268348,0.004470,NORMAL,1011,4148,0 +13814894,226,220,SPARK_POS_OK,0.280838,0.313963,0.342288,0.344507,NORMAL,226,200,SPARK_POS_OK,0.347126,0.351819,0.268160,0.004444,NORMAL,1015,4167,0 +13873894,227,220,SPARK_POS_OK,0.280629,0.313827,0.342121,0.344330,NORMAL,227,220,SPARK_POS_OK,0.346951,0.351624,0.267985,0.004456,NORMAL,1021,4220,0 +13931894,228,238,SPARK_POS_OK,0.280473,0.313697,0.341949,0.344143,NORMAL,228,221,SPARK_POS_OK,0.346759,0.351441,0.267839,0.004458,NORMAL,1024,4167,0 +13990894,229,240,SPARK_POS_OK,0.280264,0.313526,0.341761,0.343969,NORMAL,229,240,SPARK_POS_OK,0.346602,0.351270,0.267669,0.004433,NORMAL,1029,4269,0 +14047894,230,11,SPARK_NEG_OK,0.280050,0.313401,0.341582,0.343786,SOFT_START,230,12,SPARK_NEG_OK,0.346419,0.351073,0.267512,0.004433,SOFT_START,1032,4255,0 +14105894,231,11,SPARK_NEG_OK,0.279852,0.313249,0.341405,0.343619,SOFT_START,231,12,SPARK_NEG_OK,0.346251,0.350896,0.267332,0.004425,SOFT_START,1038,4181,0 +14162894,232,40,SPARK_NEG_OK,0.279679,0.313119,0.341244,0.343432,SOFT_START,232,41,SPARK_NEG_OK,0.346085,0.350717,0.267166,0.004453,SOFT_START,1049,4176,0 +14219894,233,40,SPARK_NEG_OK,0.279474,0.312965,0.341028,0.343263,SOFT_START,233,41,SPARK_NEG_OK,0.345911,0.350540,0.267016,0.004442,SOFT_START,1050,4248,0 +14275894,234,60,SPARK_NEG_OK,0.279295,0.312825,0.340890,0.343099,SOFT_START,234,61,SPARK_NEG_OK,0.345735,0.350363,0.266851,0.004426,SOFT_START,1065,4198,0 +14331894,235,80,SPARK_NEG_OK,0.279090,0.312679,0.340686,0.342902,SOFT_START,235,61,SPARK_NEG_OK,0.345562,0.350190,0.266668,0.004430,SOFT_START,1074,4207,0 +14387894,236,80,SPARK_NEG_OK,0.278901,0.312548,0.340523,0.342727,SOFT_START,236,81,SPARK_NEG_OK,0.345393,0.350004,0.266502,0.004441,SOFT_START,1084,4221,0 +14441894,237,110,SPARK_NEG_OK,0.278722,0.312400,0.340346,0.342571,SOFT_START,237,80,SPARK_NEG_OK,0.345206,0.349820,0.266361,0.004433,SOFT_START,1092,4190,0 +14496894,238,111,SPARK_NEG_OK,0.278538,0.312257,0.340148,0.342380,SOFT_START,238,110,SPARK_NEG_OK,0.345017,0.349650,0.266191,0.004449,SOFT_START,1102,4163,0 +14550894,239,131,SPARK_NEG_OK,0.278317,0.312113,0.339990,0.342190,SOFT_START,239,110,SPARK_NEG_OK,0.344860,0.349460,0.266011,0.004453,SOFT_START,1110,4260,0 +14603894,240,130,SPARK_NEG_OK,0.278129,0.311985,0.339815,0.342011,SOFT_START,240,130,SPARK_NEG_OK,0.344681,0.349284,0.265859,0.004457,SOFT_START,1121,4219,0 +14656894,241,160,SPARK_NEG_OK,0.277947,0.311831,0.339648,0.341843,SOFT_START,241,130,SPARK_NEG_OK,0.344517,0.349094,0.265678,0.004458,SOFT_START,1131,4210,0 +14709894,242,160,SPARK_NEG_OK,0.277737,0.311708,0.339428,0.341673,SOFT_START,242,160,SPARK_NEG_OK,0.344340,0.348915,0.265509,0.004467,SOFT_START,1143,4259,0 +14761894,243,201,SPARK_NEG_OK,0.277543,0.311542,0.339262,0.341479,SOFT_START,243,160,SPARK_NEG_OK,0.344167,0.348761,0.265323,0.004476,SOFT_START,1154,4244,0 +14812894,244,200,SPARK_NEG_OK,0.277353,0.311390,0.339096,0.341303,SOFT_START,244,200,SPARK_NEG_OK,0.343997,0.348579,0.265188,0.004480,SOFT_START,1168,4206,0 +14863894,245,220,SPARK_NEG_OK,0.277141,0.311238,0.338919,0.341144,SOFT_START,245,201,SPARK_NEG_OK,0.343816,0.348403,0.265033,0.004494,SOFT_START,1179,4250,0 +14914894,246,221,SPARK_NEG_OK,0.276940,0.311101,0.338711,0.340955,SOFT_START,246,220,SPARK_NEG_OK,0.343642,0.348225,0.264858,0.004509,SOFT_START,1193,4254,0 +14963894,247,219,SPARK_NEG_OK,0.276753,0.310962,0.338569,0.340778,SOFT_START,247,220,SPARK_NEG_OK,0.343467,0.348055,0.264688,0.004524,SOFT_START,1204,4171,0 +15013894,248,220,SPARK_NEG_OK,0.276549,0.310797,0.338376,0.340604,SOFT_START,248,221,SPARK_NEG_OK,0.343291,0.347858,0.264544,0.004519,SOFT_START,1217,4238,0 +15062894,249,220,SPARK_NEG_OK,0.276359,0.310670,0.338200,0.340418,SOFT_START,249,220,SPARK_NEG_OK,0.343134,0.347682,0.264333,0.004538,SOFT_START,1227,4279,0 +15110894,250,220,SPARK_NEG_OK,0.276158,0.310534,0.338027,0.340244,SOFT_START,250,221,SPARK_NEG_OK,0.342966,0.347517,0.264202,0.004557,SOFT_START,1239,4249,0 +15158894,251,220,SPARK_NEG_OK,0.275975,0.310376,0.337833,0.340089,SOFT_START,251,221,SPARK_NEG_OK,0.342786,0.347318,0.264034,0.004550,SOFT_START,1239,4172,0 +15206894,252,220,SPARK_NEG_OK,0.275763,0.310252,0.337676,0.339896,SOFT_START,252,220,SPARK_NEG_OK,0.342599,0.347157,0.263843,0.004563,SOFT_START,1258,4282,0 +15254894,253,221,SPARK_NEG_OK,0.275539,0.310127,0.337480,0.339708,SOFT_START,253,222,SPARK_NEG_OK,0.342442,0.346959,0.263690,0.004616,SOFT_START,1259,4254,0 +15301894,254,220,SPARK_NEG_OK,0.275350,0.309954,0.337303,0.339510,SOFT_START,254,220,SPARK_NEG_OK,0.342258,0.346802,0.263526,0.004594,SOFT_START,1278,4273,0 +15347894,255,220,SPARK_NEG_OK,0.275174,0.309796,0.337130,0.339362,SOFT_START,255,220,SPARK_NEG_OK,0.342102,0.346624,0.263355,0.004622,SOFT_START,1280,4205,0 +15394894,256,220,SPARK_NEG_OK,0.274967,0.309659,0.336950,0.339174,SOFT_START,256,221,SPARK_NEG_OK,0.341921,0.346425,0.263182,0.004622,SOFT_START,1297,4237,0 +15440894,257,223,SPARK_NEG_OK,0.274789,0.309511,0.336785,0.338994,SOFT_START,257,220,SPARK_NEG_OK,0.341733,0.346255,0.263042,0.004638,SOFT_START,1299,4182,0 +15486894,258,221,SPARK_NEG_OK,0.274593,0.309373,0.336576,0.338819,SOFT_START,258,221,SPARK_NEG_OK,0.341574,0.346088,0.262862,0.004668,SOFT_START,1305,4208,0 +15531894,259,220,SPARK_NEG_OK,0.274363,0.309222,0.336419,0.338640,SOFT_START,259,220,SPARK_NEG_OK,0.341392,0.345899,0.262686,0.004668,SOFT_START,1313,4277,0 +15577894,260,221,SPARK_NEG_OK,0.274186,0.309085,0.336248,0.338470,SOFT_START,260,220,SPARK_NEG_OK,0.341223,0.345733,0.262538,0.004680,SOFT_START,1318,4237,0 +15622894,261,220,SPARK_NEG_OK,0.273988,0.308942,0.336065,0.338274,SOFT_START,261,221,SPARK_NEG_OK,0.341040,0.345555,0.262377,0.004697,SOFT_START,1326,4191,0 +15667894,262,220,SPARK_NEG_OK,0.273785,0.308786,0.335875,0.338117,SOFT_START,262,220,SPARK_NEG_OK,0.340880,0.345359,0.262205,0.004693,SOFT_START,1326,4279,0 +15712894,263,221,SPARK_NEG_OK,0.273591,0.308653,0.335709,0.337934,SOFT_START,263,221,SPARK_NEG_OK,0.340683,0.345190,0.262039,0.004723,SOFT_START,1337,4203,0 +15757894,264,220,SPARK_NEG_OK,0.273391,0.308498,0.335528,0.337751,SOFT_START,264,220,SPARK_NEG_OK,0.340517,0.345017,0.261879,0.004717,SOFT_START,1338,4179,0 +15802894,265,220,SPARK_NEG_OK,0.273204,0.308351,0.335353,0.337588,SOFT_START,265,220,SPARK_NEG_OK,0.340366,0.344841,0.261700,0.004731,SOFT_START,1341,4241,0 +15846894,266,221,SPARK_NEG_OK,0.273006,0.308197,0.335171,0.337414,SOFT_START,266,221,SPARK_NEG_OK,0.340174,0.344661,0.261554,0.004756,SOFT_START,1347,4230,0 +15891894,267,180,SPARK_NEG_OK,0.272815,0.308082,0.334992,0.337222,SOFT_START,267,220,SPARK_NEG_OK,0.340018,0.344472,0.261397,0.004770,SOFT_START,1347,4268,0 +15935894,268,180,SPARK_NEG_OK,0.272610,0.307922,0.334812,0.337040,SOFT_START,268,180,SPARK_NEG_OK,0.339837,0.344308,0.261219,0.004772,SOFT_START,1350,4241,0 +15980894,269,181,SPARK_NEG_OK,0.272433,0.307770,0.334638,0.336877,SOFT_START,269,181,SPARK_NEG_OK,0.339680,0.344119,0.261047,0.004802,SOFT_START,1350,4210,0 +16024894,270,150,SPARK_NEG_OK,0.272267,0.307639,0.334473,0.336711,SOFT_START,270,148,SPARK_NEG_OK,0.339497,0.343937,0.260897,0.004804,SOFT_START,1347,4244,0 +16069894,271,150,SPARK_NEG_OK,0.272056,0.307497,0.334284,0.336515,SOFT_START,271,150,SPARK_NEG_OK,0.339306,0.343756,0.260709,0.004807,SOFT_START,1348,4158,0 +16113894,272,140,SPARK_NEG_OK,0.271863,0.307337,0.334108,0.336345,SOFT_START,272,151,SPARK_NEG_OK,0.339141,0.343586,0.260540,0.004798,SOFT_START,1345,4239,0 +16158894,273,140,SPARK_NEG_OK,0.271698,0.307201,0.333925,0.336167,SOFT_START,273,140,SPARK_NEG_OK,0.338959,0.343403,0.260389,0.004823,SOFT_START,1345,4167,0 +16203894,274,130,SPARK_NEG_OK,0.271480,0.307058,0.333768,0.335989,SOFT_START,274,140,SPARK_NEG_OK,0.338812,0.343249,0.260221,0.004836,SOFT_START,1342,4271,0 +16247894,275,130,SPARK_NEG_OK,0.271285,0.306922,0.333574,0.335815,SOFT_START,275,131,SPARK_NEG_OK,0.338630,0.343057,0.260075,0.004844,SOFT_START,1342,4232,0 +16292894,276,130,SPARK_NEG_OK,0.271102,0.306773,0.333405,0.335645,SOFT_START,276,130,SPARK_NEG_OK,0.338458,0.342894,0.259930,0.004845,SOFT_START,1342,4194,0 +16337894,277,120,SPARK_NEG_OK,0.270932,0.306615,0.333204,0.335463,SOFT_START,277,120,SPARK_NEG_OK,0.338296,0.342724,0.259750,0.004863,SOFT_START,1337,4147,0 +16382894,278,120,SPARK_NEG_OK,0.270737,0.306486,0.333048,0.335265,SOFT_START,278,121,SPARK_NEG_OK,0.338100,0.342532,0.259584,0.004867,SOFT_START,1339,4276,0 +16426894,279,110,SPARK_NEG_OK,0.270554,0.306343,0.332868,0.335113,SOFT_START,279,120,SPARK_NEG_OK,0.337940,0.342348,0.259439,0.004864,SOFT_START,1335,4170,0 +16471894,280,111,SPARK_NEG_OK,0.270383,0.306209,0.332687,0.334929,SOFT_START,280,110,SPARK_NEG_OK,0.337764,0.342171,0.259267,0.004873,SOFT_START,1335,4177,0 +16517894,281,90,SPARK_NEG_OK,0.270165,0.306048,0.332520,0.334755,SOFT_START,281,110,SPARK_NEG_OK,0.337594,0.341991,0.259075,0.004871,SOFT_START,1329,4272,0 +16562894,282,90,SPARK_NEG_OK,0.269985,0.305896,0.332350,0.334590,SOFT_START,282,91,SPARK_NEG_OK,0.337431,0.341833,0.258943,0.004854,SOFT_START,1326,4247,0 +16607894,283,91,SPARK_NEG_OK,0.269781,0.305758,0.332175,0.334412,SOFT_START,283,91,SPARK_NEG_OK,0.337263,0.341638,0.258790,0.004885,SOFT_START,1326,4220,0 +16653894,284,70,SPARK_NEG_OK,0.269598,0.305635,0.331991,0.334242,SOFT_START,284,72,SPARK_NEG_OK,0.337071,0.341465,0.258601,0.004866,SOFT_START,1312,4258,0 +16698894,285,71,SPARK_NEG_OK,0.269420,0.305482,0.331814,0.334067,SOFT_START,285,70,SPARK_NEG_OK,0.336933,0.341322,0.258471,0.004867,SOFT_START,1313,4192,0 +16744894,286,40,SPARK_NEG_OK,0.269231,0.305305,0.331654,0.333915,SOFT_START,286,41,SPARK_NEG_OK,0.336744,0.341121,0.258281,0.004871,SOFT_START,1299,4180,0 +16791894,287,40,SPARK_NEG_OK,0.269049,0.305214,0.331465,0.333707,SOFT_START,287,40,SPARK_NEG_OK,0.336584,0.340940,0.258129,0.004892,SOFT_START,1300,4187,0 +16837894,288,30,SPARK_NEG_OK,0.268874,0.305048,0.331298,0.333550,SOFT_START,288,41,SPARK_NEG_OK,0.336404,0.340771,0.257971,0.004876,SOFT_START,1293,4201,0 +16884894,289,30,SPARK_NEG_OK,0.268696,0.304921,0.331123,0.333374,SOFT_START,289,30,SPARK_NEG_OK,0.336235,0.340590,0.257808,0.004873,SOFT_START,1288,4174,0 +16930894,290,12,SPARK_NEG_OK,0.268512,0.304756,0.330947,0.333184,SOFT_START,290,30,SPARK_NEG_OK,0.336077,0.340421,0.257648,0.004867,SOFT_START,1280,4275,0 +16977894,291,11,SPARK_NEG_OK,0.268307,0.304621,0.330780,0.333019,SOFT_START,291,11,SPARK_NEG_OK,0.335906,0.340248,0.257477,0.004886,SOFT_START,1275,4182,0 +17024894,292,12,SPARK_NEG_OK,0.268142,0.304487,0.330597,0.332844,SOFT_START,292,11,SPARK_NEG_OK,0.335712,0.340078,0.257326,0.004880,SOFT_START,1275,4223,0 +17073894,293,240,SPARK_POS_OK,0.267931,0.304347,0.330408,0.332662,NORMAL,293,240,SPARK_POS_OK,0.335556,0.339900,0.257170,0.004864,NORMAL,1265,4283,0 +17120894,294,241,SPARK_POS_OK,0.267733,0.304181,0.330238,0.332494,NORMAL,294,240,SPARK_POS_OK,0.335385,0.339734,0.257022,0.004860,NORMAL,1259,4237,0 +17169894,295,210,SPARK_POS_OK,0.267549,0.304050,0.330071,0.332329,NORMAL,295,210,SPARK_POS_OK,0.335230,0.339558,0.256847,0.004850,NORMAL,1240,4221,0 +17217894,296,211,SPARK_POS_OK,0.267379,0.303919,0.329908,0.332153,NORMAL,296,210,SPARK_POS_OK,0.335050,0.339391,0.256687,0.004830,NORMAL,1240,4255,0 +17266894,297,190,SPARK_POS_OK,0.267209,0.303771,0.329717,0.331997,NORMAL,297,190,SPARK_POS_OK,0.334877,0.339213,0.256514,0.004860,NORMAL,1221,4165,0 +17315894,298,190,SPARK_POS_OK,0.266992,0.303644,0.329559,0.331809,NORMAL,298,191,SPARK_POS_OK,0.334710,0.339048,0.256393,0.004833,NORMAL,1221,4259,0 +17365894,299,160,SPARK_POS_OK,0.266833,0.303503,0.329363,0.331661,NORMAL,299,190,SPARK_POS_OK,0.334555,0.338853,0.256221,0.004839,NORMAL,1212,4189,0 +17415894,300,160,SPARK_POS_OK,0.266654,0.303344,0.329211,0.331482,NORMAL,300,161,SPARK_POS_OK,0.334383,0.338693,0.256031,0.004812,NORMAL,1203,4190,0 +17465894,301,141,SPARK_POS_OK,0.266449,0.303210,0.329055,0.331288,NORMAL,301,160,SPARK_POS_OK,0.334225,0.338532,0.255885,0.004814,NORMAL,1193,4273,0 +17516894,302,140,SPARK_POS_OK,0.266245,0.303064,0.328864,0.331123,NORMAL,302,140,SPARK_POS_OK,0.334033,0.338354,0.255737,0.004802,NORMAL,1184,4273,0 +17567894,303,110,SPARK_POS_OK,0.266058,0.302920,0.328710,0.330976,NORMAL,303,141,SPARK_POS_OK,0.333868,0.338184,0.255600,0.004779,NORMAL,1172,4268,0 +17619894,304,110,SPARK_POS_OK,0.265878,0.302792,0.328532,0.330778,NORMAL,304,110,SPARK_POS_OK,0.333710,0.338012,0.255402,0.004783,NORMAL,1161,4227,0 +17671894,305,81,SPARK_POS_OK,0.265690,0.302648,0.328369,0.330619,NORMAL,305,110,SPARK_POS_OK,0.333537,0.337849,0.255261,0.004770,NORMAL,1148,4232,0 +17724894,306,80,SPARK_POS_OK,0.265476,0.302500,0.328174,0.330463,NORMAL,306,80,SPARK_POS_OK,0.333378,0.337679,0.255098,0.004752,NORMAL,1137,4264,0 +17777894,307,60,SPARK_POS_OK,0.265328,0.302365,0.328012,0.330285,NORMAL,307,81,SPARK_POS_OK,0.333213,0.337498,0.254948,0.004761,NORMAL,1123,4191,0 +17831894,308,60,SPARK_POS_OK,0.265142,0.302238,0.327851,0.330095,NORMAL,308,61,SPARK_POS_OK,0.333058,0.337338,0.254792,0.004728,NORMAL,1112,4244,0 +17885894,309,30,SPARK_POS_OK,0.264945,0.302092,0.327675,0.329918,NORMAL,309,60,SPARK_POS_OK,0.332888,0.337162,0.254622,0.004697,NORMAL,1100,4201,0 +17941894,310,31,SPARK_POS_OK,0.264768,0.301954,0.327485,0.329756,NORMAL,310,30,SPARK_POS_OK,0.332726,0.336969,0.254484,0.004701,NORMAL,1088,4164,0 +17997894,311,12,SPARK_POS_OK,0.264581,0.301821,0.327319,0.329586,NORMAL,311,30,SPARK_POS_OK,0.332555,0.336813,0.254331,0.004685,NORMAL,1065,4223,0 +18053894,312,12,SPARK_POS_OK,0.264429,0.301675,0.327158,0.329433,NORMAL,312,11,SPARK_POS_OK,0.332391,0.336652,0.254169,0.004653,NORMAL,1066,4203,0 +18111894,313,12,SPARK_POS_OK,0.264220,0.301539,0.326988,0.329242,NORMAL,313,11,SPARK_POS_OK,0.332209,0.336474,0.254010,0.004625,NORMAL,1066,4239,0 +18168897,314,12,SPARK_POS_OK,0.264052,0.301399,0.326822,0.329088,NORMAL,314,11,SPARK_POS_OK,0.332057,0.336303,0.253870,0.004619,NORMAL,1066,4191,0 +18228894,315,12,SPARK_POS_OK,0.263894,0.301248,0.326648,0.328944,NORMAL,315,11,SPARK_POS_OK,0.331897,0.336123,0.253718,0.004594,NORMAL,1066,4234,0 +18287894,316,12,SPARK_POS_OK,0.263721,0.301127,0.326463,0.328761,NORMAL,316,11,SPARK_POS_OK,0.331728,0.335987,0.253572,0.004570,NORMAL,1066,4157,0 +18348894,317,12,SPARK_POS_OK,0.263575,0.300995,0.326326,0.328572,NORMAL,317,11,SPARK_POS_OK,0.331570,0.335803,0.253413,0.004551,NORMAL,1066,4152,0 +18409894,318,12,SPARK_POS_OK,0.263376,0.300867,0.326142,0.328431,NORMAL,318,11,SPARK_POS_OK,0.331399,0.335646,0.253223,0.004531,NORMAL,1066,4212,0 +18470894,319,12,SPARK_POS_OK,0.263219,0.300716,0.325989,0.328241,NORMAL,319,11,SPARK_POS_OK,0.331234,0.335476,0.253085,0.004523,NORMAL,1066,4170,0 +18533894,320,12,SPARK_POS_OK,0.263063,0.300580,0.325815,0.328078,NORMAL,320,11,SPARK_POS_OK,0.331081,0.335301,0.252938,0.004483,NORMAL,1066,4166,0 +18596894,321,12,SPARK_POS_OK,0.262910,0.300453,0.325649,0.327910,NORMAL,321,11,SPARK_POS_OK,0.330916,0.335144,0.252804,0.004457,NORMAL,1066,4165,0 +18660894,322,12,SPARK_POS_OK,0.262725,0.300310,0.325455,0.327746,NORMAL,322,11,SPARK_POS_OK,0.330752,0.334975,0.252672,0.004439,NORMAL,1066,4218,0 +18724894,323,12,SPARK_POS_OK,0.262533,0.300167,0.325316,0.327597,NORMAL,323,11,SPARK_POS_OK,0.330575,0.334817,0.252523,0.004401,NORMAL,1066,4189,0 +18788894,324,12,SPARK_POS_OK,0.262383,0.300050,0.325135,0.327423,NORMAL,324,11,SPARK_POS_OK,0.330424,0.334643,0.252364,0.004385,NORMAL,1066,4180,0 +18853894,325,31,SPARK_POS_OK,0.262214,0.299909,0.324991,0.327273,NORMAL,325,30,SPARK_POS_OK,0.330254,0.334481,0.252185,0.004376,NORMAL,75,4155,0 +18918894,326,60,SPARK_POS_OK,0.262047,0.299770,0.324814,0.327099,NORMAL,326,30,SPARK_POS_OK,0.330110,0.334322,0.252017,0.004348,NORMAL,922,4204,0 +18983894,327,61,SPARK_POS_OK,0.261842,0.299639,0.324641,0.326945,NORMAL,327,61,SPARK_POS_OK,0.329948,0.334149,0.251907,0.004337,NORMAL,922,4242,0 +19048894,328,70,SPARK_POS_OK,0.261689,0.299488,0.324500,0.326771,NORMAL,328,70,SPARK_POS_OK,0.329792,0.333999,0.251749,0.004326,NORMAL,923,4197,0 +19113894,329,99,SPARK_POS_OK,0.261513,0.299374,0.324318,0.326604,NORMAL,329,71,SPARK_POS_OK,0.329626,0.333806,0.251604,0.004297,NORMAL,923,4211,0 +19178894,330,101,SPARK_POS_OK,0.261340,0.299222,0.324141,0.326428,NORMAL,330,100,SPARK_POS_OK,0.329466,0.333648,0.251442,0.004287,NORMAL,925,4204,0 +19242894,331,140,SPARK_POS_OK,0.261175,0.299098,0.323993,0.326282,NORMAL,331,100,SPARK_POS_OK,0.329297,0.333476,0.251278,0.004270,NORMAL,927,4203,0 +19307894,332,141,SPARK_POS_OK,0.261015,0.298949,0.323822,0.326133,NORMAL,332,140,SPARK_POS_OK,0.329157,0.333326,0.251157,0.004254,NORMAL,931,4168,0 +19370894,333,180,SPARK_POS_OK,0.260856,0.298833,0.323690,0.325951,NORMAL,333,180,SPARK_POS_OK,0.328997,0.333153,0.251002,0.004216,NORMAL,941,4190,0 +19434894,334,220,SPARK_POS_OK,0.260683,0.298681,0.323502,0.325797,NORMAL,334,180,SPARK_POS_OK,0.328824,0.333012,0.250846,0.004238,NORMAL,949,4212,0 +19496894,335,220,SPARK_POS_OK,0.260522,0.298552,0.323358,0.325621,NORMAL,335,220,SPARK_POS_OK,0.328658,0.332820,0.250706,0.004205,NORMAL,958,4157,0 +19558894,336,11,SPARK_NEG_OK,0.260323,0.298428,0.323166,0.325444,SOFT_START,336,12,SPARK_NEG_OK,0.328495,0.332637,0.250533,0.004199,SOFT_START,964,4228,0 +19619894,337,11,SPARK_NEG_OK,0.260170,0.298282,0.323004,0.325284,SOFT_START,337,11,SPARK_NEG_OK,0.328336,0.332501,0.250398,0.004202,SOFT_START,979,4179,0 +19679894,338,40,SPARK_NEG_OK,0.259990,0.298154,0.322841,0.325130,SOFT_START,338,41,SPARK_NEG_OK,0.328166,0.332343,0.250236,0.004218,SOFT_START,999,4268,0 +19738894,339,80,SPARK_NEG_OK,0.259811,0.298021,0.322664,0.324945,SOFT_START,339,41,SPARK_NEG_OK,0.328009,0.332161,0.250092,0.004217,SOFT_START,1010,4162,0 +19797894,340,83,SPARK_NEG_OK,0.259663,0.297867,0.322503,0.324783,SOFT_START,340,80,SPARK_NEG_OK,0.327846,0.332021,0.249950,0.004224,SOFT_START,1021,4232,0 +19855894,341,110,SPARK_NEG_OK,0.259460,0.297735,0.322354,0.324625,SOFT_START,341,80,SPARK_NEG_OK,0.327682,0.331861,0.249802,0.004217,SOFT_START,1033,4260,0 +19912899,342,110,SPARK_NEG_OK,0.259243,0.297609,0.322173,0.324457,SOFT_START,342,110,SPARK_NEG_OK,0.327532,0.331677,0.249640,0.004229,SOFT_START,1046,4266,0 +19969894,343,140,SPARK_NEG_OK,0.259082,0.297482,0.322000,0.324315,SOFT_START,343,110,SPARK_NEG_OK,0.327353,0.331500,0.249475,0.004230,SOFT_START,1059,4277,0 +20025894,344,140,SPARK_NEG_OK,0.258904,0.297315,0.321835,0.324124,SOFT_START,344,140,SPARK_NEG_OK,0.327191,0.331320,0.249317,0.004232,SOFT_START,1074,4183,0 +20079894,345,170,SPARK_NEG_OK,0.258722,0.297176,0.321677,0.323954,SOFT_START,345,170,SPARK_NEG_OK,0.327038,0.331159,0.249147,0.004234,SOFT_START,1104,4216,0 +20134894,346,170,SPARK_NEG_OK,0.258553,0.297052,0.321513,0.323796,SOFT_START,346,171,SPARK_NEG_OK,0.326892,0.331004,0.249031,0.004253,SOFT_START,1105,4196,0 +20186894,347,210,SPARK_NEG_OK,0.258387,0.296900,0.321335,0.323642,SOFT_START,347,210,SPARK_NEG_OK,0.326720,0.330830,0.248892,0.004249,SOFT_START,1133,4172,0 +20239894,348,211,SPARK_NEG_OK,0.258192,0.296764,0.321176,0.323435,SOFT_START,348,209,SPARK_NEG_OK,0.326536,0.330669,0.248723,0.004274,SOFT_START,1135,4239,0 +20291894,349,222,SPARK_NEG_OK,0.258071,0.296631,0.321015,0.323313,SOFT_START,349,220,SPARK_NEG_OK,0.326385,0.330530,0.248555,0.004287,SOFT_START,1161,4170,0 +20343894,350,220,SPARK_NEG_OK,0.257885,0.296487,0.320839,0.323126,SOFT_START,350,221,SPARK_NEG_OK,0.326209,0.330343,0.248409,0.004294,SOFT_START,1162,4166,0 +20393894,351,221,SPARK_NEG_OK,0.257689,0.296348,0.320674,0.322964,SOFT_START,351,220,SPARK_NEG_OK,0.326070,0.330162,0.248275,0.004317,SOFT_START,1189,4243,0 +20444894,352,220,SPARK_NEG_OK,0.257528,0.296219,0.320523,0.322800,SOFT_START,352,220,SPARK_NEG_OK,0.325900,0.329998,0.248111,0.004302,SOFT_START,1190,4243,0 +20493894,353,220,SPARK_NEG_OK,0.257332,0.296090,0.320352,0.322620,SOFT_START,353,221,SPARK_NEG_OK,0.325734,0.329834,0.247976,0.004354,SOFT_START,1216,4255,0 +20542894,354,220,SPARK_NEG_OK,0.257193,0.295956,0.320160,0.322452,SOFT_START,354,220,SPARK_NEG_OK,0.325580,0.329660,0.247832,0.004338,SOFT_START,1217,4187,0 +20591894,355,220,SPARK_NEG_OK,0.257006,0.295811,0.320002,0.322289,SOFT_START,355,222,SPARK_NEG_OK,0.325417,0.329492,0.247651,0.004367,SOFT_START,1229,4172,0 +20639894,356,221,SPARK_NEG_OK,0.256846,0.295683,0.319828,0.322133,SOFT_START,356,220,SPARK_NEG_OK,0.325261,0.329328,0.247501,0.004339,SOFT_START,1243,4173,0 +20687894,357,222,SPARK_NEG_OK,0.256677,0.295523,0.319645,0.321972,SOFT_START,357,218,SPARK_NEG_OK,0.325086,0.329163,0.247350,0.004399,SOFT_START,1252,4254,0 +20735894,358,221,SPARK_NEG_OK,0.256487,0.295391,0.319504,0.321789,SOFT_START,358,220,SPARK_NEG_OK,0.324938,0.329013,0.247198,0.004386,SOFT_START,1264,4257,0 +20782894,359,220,SPARK_NEG_OK,0.256309,0.295264,0.319327,0.321630,SOFT_START,359,220,SPARK_NEG_OK,0.324761,0.328816,0.247033,0.004420,SOFT_START,1271,4271,0 +20829894,360,221,SPARK_NEG_OK,0.256101,0.295115,0.319163,0.321459,SOFT_START,360,220,SPARK_NEG_OK,0.324587,0.328664,0.246886,0.004438,SOFT_START,1281,4264,0 +20875894,361,220,SPARK_NEG_OK,0.255911,0.294976,0.318999,0.321298,SOFT_START,361,220,SPARK_NEG_OK,0.324433,0.328503,0.246757,0.004437,SOFT_START,1281,4259,0 +20922894,362,220,SPARK_NEG_OK,0.255751,0.294830,0.318828,0.321140,SOFT_START,362,220,SPARK_NEG_OK,0.324269,0.328309,0.246596,0.004463,SOFT_START,1296,4230,0 +20968894,363,220,SPARK_NEG_OK,0.255544,0.294704,0.318658,0.320951,SOFT_START,363,221,SPARK_NEG_OK,0.324112,0.328156,0.246429,0.004478,SOFT_START,1297,4251,0 +21013894,364,220,SPARK_NEG_OK,0.255378,0.294563,0.318509,0.320779,SOFT_START,364,220,SPARK_NEG_OK,0.323953,0.327988,0.246264,0.004461,SOFT_START,1313,4155,0 +21059894,365,221,SPARK_NEG_OK,0.255207,0.294417,0.318331,0.320619,SOFT_START,365,220,SPARK_NEG_OK,0.323799,0.327819,0.246127,0.004505,SOFT_START,1314,4242,0 +21105894,366,220,SPARK_NEG_OK,0.255017,0.294299,0.318168,0.320468,SOFT_START,366,220,SPARK_NEG_OK,0.323625,0.327657,0.245991,0.004532,SOFT_START,1320,4253,0 +21150894,367,220,SPARK_NEG_OK,0.254884,0.294146,0.318006,0.320298,SOFT_START,367,220,SPARK_NEG_OK,0.323460,0.327480,0.245815,0.004519,SOFT_START,1328,4154,0 +21195894,368,210,SPARK_NEG_OK,0.254679,0.294014,0.317810,0.320133,SOFT_START,368,221,SPARK_NEG_OK,0.323297,0.327337,0.245692,0.004536,SOFT_START,1330,4259,0 +21240894,369,210,SPARK_NEG_OK,0.254503,0.293881,0.317658,0.319958,SOFT_START,369,210,SPARK_NEG_OK,0.323118,0.327151,0.245520,0.004557,SOFT_START,1335,4247,0 +21285894,370,211,SPARK_NEG_OK,0.254315,0.293742,0.317503,0.319797,SOFT_START,370,208,SPARK_NEG_OK,0.322980,0.326989,0.245395,0.004555,SOFT_START,1335,4234,0 +21330894,371,160,SPARK_NEG_OK,0.254148,0.293601,0.317314,0.319611,SOFT_START,371,161,SPARK_NEG_OK,0.322809,0.326823,0.245209,0.004575,SOFT_START,1333,4216,0 +21375894,372,160,SPARK_NEG_OK,0.253989,0.293456,0.317158,0.319450,SOFT_START,372,160,SPARK_NEG_OK,0.322645,0.326669,0.245063,0.004587,SOFT_START,1335,4210,0 +21420894,373,131,SPARK_NEG_OK,0.253763,0.293311,0.317000,0.319297,SOFT_START,373,161,SPARK_NEG_OK,0.322486,0.326477,0.244898,0.004608,SOFT_START,1331,4250,0 +21465894,374,130,SPARK_NEG_OK,0.253583,0.293167,0.316819,0.319125,SOFT_START,374,130,SPARK_NEG_OK,0.322325,0.326326,0.244773,0.004621,SOFT_START,1331,4251,0 +21510894,375,100,SPARK_NEG_OK,0.253405,0.293046,0.316660,0.318956,SOFT_START,375,130,SPARK_NEG_OK,0.322174,0.326158,0.244617,0.004613,SOFT_START,1326,4256,0 +21555894,376,98,SPARK_NEG_OK,0.253240,0.292909,0.316489,0.318796,SOFT_START,376,101,SPARK_NEG_OK,0.321996,0.325991,0.244480,0.004627,SOFT_START,1324,4171,0 +21601894,377,100,SPARK_NEG_OK,0.253084,0.292753,0.316325,0.318621,SOFT_START,377,100,SPARK_NEG_OK,0.321842,0.325828,0.244313,0.004628,SOFT_START,1325,4224,0 +21646894,378,71,SPARK_NEG_OK,0.252927,0.292641,0.316149,0.318452,SOFT_START,378,70,SPARK_NEG_OK,0.321690,0.325672,0.244193,0.004615,SOFT_START,1314,4211,0 +21692894,379,70,SPARK_NEG_OK,0.252713,0.292499,0.315984,0.318302,SOFT_START,379,71,SPARK_NEG_OK,0.321518,0.325484,0.243992,0.004643,SOFT_START,1316,4226,0 +21738894,380,44,SPARK_NEG_OK,0.252571,0.292348,0.315827,0.318130,SOFT_START,380,40,SPARK_NEG_OK,0.321364,0.325325,0.243841,0.004649,SOFT_START,1302,4176,0 +21784894,381,41,SPARK_NEG_OK,0.252412,0.292211,0.315657,0.317964,SOFT_START,381,41,SPARK_NEG_OK,0.321205,0.325164,0.243707,0.004649,SOFT_START,1303,4154,0 +21830894,382,25,SPARK_NEG_OK,0.252232,0.292082,0.315511,0.317797,SOFT_START,382,40,SPARK_NEG_OK,0.321046,0.325002,0.243568,0.004656,SOFT_START,1294,4204,0 +21877894,383,25,SPARK_NEG_OK,0.252066,0.291921,0.315345,0.317625,SOFT_START,383,25,SPARK_NEG_OK,0.320892,0.324832,0.243430,0.004650,SOFT_START,1287,4265,0 +22066894,384,221,SPARK_POS_OK,0.251943,0.291840,0.315213,0.317532,NORMAL,385,220,SPARK_POS_OK,0.320773,0.324718,0.243290,0.004334,NORMAL,1260,4187,0 +22114894,385,220,SPARK_POS_OK,0.251784,0.291713,0.315040,0.317362,NORMAL,386,220,SPARK_POS_OK,0.320596,0.324549,0.243174,0.004328,NORMAL,1254,4207,0 +22163894,386,201,SPARK_POS_OK,0.251599,0.291560,0.314904,0.317187,NORMAL,387,200,SPARK_POS_OK,0.320437,0.324401,0.243008,0.004365,NORMAL,1237,4244,0 +22211894,387,200,SPARK_POS_OK,0.251435,0.291431,0.314730,0.317033,NORMAL,388,200,SPARK_POS_OK,0.320293,0.324231,0.242876,0.004377,NORMAL,1238,4199,0 +22260894,388,201,SPARK_POS_OK,0.251231,0.291277,0.314555,0.316856,NORMAL,389,200,SPARK_POS_OK,0.320131,0.324057,0.242704,0.004392,NORMAL,1220,4242,0 +22310894,389,200,SPARK_POS_OK,0.251068,0.291168,0.314403,0.316711,NORMAL,390,200,SPARK_POS_OK,0.319960,0.323902,0.242588,0.004395,NORMAL,1221,4206,0 +22359894,390,200,SPARK_POS_OK,0.250910,0.291023,0.314248,0.316540,NORMAL,391,201,SPARK_POS_OK,0.319814,0.323752,0.242434,0.004389,NORMAL,1212,4163,0 +22409894,391,201,SPARK_POS_OK,0.250749,0.290879,0.314057,0.316370,NORMAL,392,200,SPARK_POS_OK,0.319641,0.323569,0.242269,0.004386,NORMAL,1204,4223,0 +22459894,392,200,SPARK_POS_OK,0.250592,0.290762,0.313917,0.316202,NORMAL,393,200,SPARK_POS_OK,0.319495,0.323399,0.242125,0.004408,NORMAL,1195,4181,0 +22510894,393,200,SPARK_POS_OK,0.250397,0.290606,0.313741,0.316054,NORMAL,394,200,SPARK_POS_OK,0.319328,0.323240,0.241963,0.004426,NORMAL,1189,4274,0 +22560894,394,180,SPARK_POS_OK,0.250229,0.290475,0.313578,0.315884,NORMAL,395,200,SPARK_POS_OK,0.319164,0.323087,0.241815,0.004414,NORMAL,1182,4152,0 +22611894,395,180,SPARK_POS_OK,0.250061,0.290341,0.313404,0.315724,NORMAL,396,180,SPARK_POS_OK,0.319005,0.322919,0.241695,0.004420,NORMAL,1176,4214,0 +22663894,396,160,SPARK_POS_OK,0.249893,0.290205,0.313265,0.315571,NORMAL,397,180,SPARK_POS_OK,0.318839,0.322757,0.241555,0.004427,NORMAL,1168,4185,0 +22714894,397,161,SPARK_POS_OK,0.249780,0.290083,0.313102,0.315400,NORMAL,398,160,SPARK_POS_OK,0.318682,0.322593,0.241399,0.004421,NORMAL,1162,4158,0 +22766894,398,130,SPARK_POS_OK,0.249581,0.289944,0.312937,0.315239,NORMAL,399,160,SPARK_POS_OK,0.318528,0.322440,0.241244,0.004424,NORMAL,1153,4225,0 +22819894,399,130,SPARK_POS_OK,0.249429,0.289794,0.312774,0.315065,NORMAL,400,131,SPARK_POS_OK,0.318367,0.322250,0.241141,0.004423,NORMAL,1144,4219,0 +22872894,400,100,SPARK_POS_OK,0.249244,0.289667,0.312595,0.314922,NORMAL,401,130,SPARK_POS_OK,0.318213,0.322106,0.240951,0.004418,NORMAL,1133,4205,0 +22925894,401,101,SPARK_POS_OK,0.249118,0.289536,0.312445,0.314752,NORMAL,402,100,SPARK_POS_OK,0.318076,0.321957,0.240791,0.004417,NORMAL,1123,4152,0 +22979894,402,80,SPARK_POS_OK,0.248949,0.289407,0.312278,0.314587,NORMAL,403,100,SPARK_POS_OK,0.317907,0.321783,0.240674,0.004404,NORMAL,1112,4195,0 +23033894,403,80,SPARK_POS_OK,0.248800,0.289295,0.312135,0.314437,NORMAL,404,80,SPARK_POS_OK,0.317755,0.321617,0.240517,0.004391,NORMAL,1102,4169,0 +23088894,404,60,SPARK_POS_OK,0.248595,0.289129,0.311957,0.314260,NORMAL,405,81,SPARK_POS_OK,0.317606,0.321452,0.240378,0.004416,NORMAL,1092,4277,0 +23144894,405,58,SPARK_POS_OK,0.248428,0.288990,0.311789,0.314125,NORMAL,406,61,SPARK_POS_OK,0.317430,0.321298,0.240227,0.004388,NORMAL,1083,4216,0 +23200894,406,40,SPARK_POS_OK,0.248251,0.288861,0.311638,0.313944,NORMAL,407,41,SPARK_POS_OK,0.317273,0.321144,0.240096,0.004374,NORMAL,1063,4187,0 +23257894,407,40,SPARK_POS_OK,0.248116,0.288737,0.311475,0.313795,NORMAL,408,41,SPARK_POS_OK,0.317137,0.320997,0.239952,0.004364,NORMAL,1064,4201,0 +23314894,408,11,SPARK_POS_OK,0.247964,0.288606,0.311311,0.313634,NORMAL,409,11,SPARK_POS_OK,0.316954,0.320822,0.239804,0.004355,NORMAL,1041,4163,0 +23372894,409,10,SPARK_POS_OK,0.247810,0.288470,0.311150,0.313477,NORMAL,410,11,SPARK_POS_OK,0.316814,0.320682,0.239655,0.004355,NORMAL,1041,4174,0 +23431894,410,10,SPARK_POS_OK,0.247661,0.288334,0.310993,0.313318,NORMAL,411,11,SPARK_POS_OK,0.316665,0.320500,0.239493,0.004331,NORMAL,1041,4184,0 +23491894,411,10,SPARK_POS_OK,0.247477,0.288216,0.310840,0.313165,NORMAL,412,11,SPARK_POS_OK,0.316504,0.320349,0.239373,0.004325,NORMAL,1041,4180,0 +23551894,412,10,SPARK_POS_OK,0.247323,0.288085,0.310678,0.312979,NORMAL,413,11,SPARK_POS_OK,0.316359,0.320181,0.239230,0.004309,NORMAL,1041,4213,0 +23612894,413,10,SPARK_POS_OK,0.247186,0.287938,0.310524,0.312859,NORMAL,414,11,SPARK_POS_OK,0.316190,0.320023,0.239092,0.004290,NORMAL,1041,4169,0 +23673894,414,10,SPARK_POS_OK,0.246977,0.287805,0.310360,0.312675,NORMAL,415,11,SPARK_POS_OK,0.316062,0.319877,0.238933,0.004276,NORMAL,1041,4281,0 +23736894,415,10,SPARK_POS_OK,0.246847,0.287696,0.310220,0.312530,NORMAL,416,11,SPARK_POS_OK,0.315886,0.319724,0.238806,0.004281,NORMAL,1041,4222,0 +23799894,416,10,SPARK_POS_OK,0.246696,0.287563,0.310060,0.312370,NORMAL,417,11,SPARK_POS_OK,0.315736,0.319582,0.238660,0.004261,NORMAL,1041,4168,0 +23862894,417,10,SPARK_POS_OK,0.246543,0.287425,0.309901,0.312217,NORMAL,418,11,SPARK_POS_OK,0.315586,0.319396,0.238518,0.004233,NORMAL,1041,4165,0 +23926894,418,10,SPARK_POS_OK,0.246392,0.287284,0.309759,0.312039,NORMAL,419,11,SPARK_POS_OK,0.315444,0.319242,0.238376,0.004227,NORMAL,1041,4222,0 +23991894,419,10,SPARK_POS_OK,0.246216,0.287178,0.309595,0.311915,NORMAL,420,11,SPARK_POS_OK,0.315268,0.319102,0.238240,0.004210,NORMAL,1041,4167,0 +24056894,420,10,SPARK_POS_OK,0.246093,0.287024,0.309426,0.311732,NORMAL,421,11,SPARK_POS_OK,0.315140,0.318957,0.238119,0.004194,NORMAL,1041,4169,0 +24122894,421,11,SPARK_POS_OK,0.245922,0.286901,0.309296,0.311624,NORMAL,422,11,SPARK_POS_OK,0.314963,0.318786,0.237943,0.004176,NORMAL,79,4187,0 +24188894,422,11,SPARK_POS_OK,0.245771,0.286802,0.309132,0.311439,NORMAL,423,11,SPARK_POS_OK,0.314819,0.318629,0.237815,0.004169,NORMAL,908,4273,0 +24255894,423,31,SPARK_POS_OK,0.245610,0.286642,0.308980,0.311305,NORMAL,424,31,SPARK_POS_OK,0.314688,0.318487,0.237675,0.004144,NORMAL,904,4240,0 +24321894,424,40,SPARK_POS_OK,0.245454,0.286503,0.308827,0.311134,NORMAL,425,30,SPARK_POS_OK,0.314520,0.318360,0.237542,0.004140,NORMAL,903,4243,0 +24388894,425,41,SPARK_POS_OK,0.245271,0.286397,0.308676,0.310984,NORMAL,426,41,SPARK_POS_OK,0.314375,0.318177,0.237422,0.004111,NORMAL,903,4200,0 +24454894,426,70,SPARK_POS_OK,0.245160,0.286249,0.308500,0.310826,NORMAL,427,70,SPARK_POS_OK,0.314231,0.317993,0.237269,0.004092,NORMAL,900,4149,0 +24521894,427,100,SPARK_POS_OK,0.244949,0.286124,0.308365,0.310673,NORMAL,428,71,SPARK_POS_OK,0.314102,0.317850,0.237157,0.004083,NORMAL,902,4243,0 +24587894,428,100,SPARK_POS_OK,0.244780,0.286021,0.308192,0.310531,NORMAL,429,100,SPARK_POS_OK,0.313907,0.317709,0.236992,0.004075,NORMAL,905,4262,0 +24653894,429,140,SPARK_POS_OK,0.244631,0.285877,0.308051,0.310360,NORMAL,430,101,SPARK_POS_OK,0.313776,0.317557,0.236880,0.004052,NORMAL,909,4190,0 +24718894,430,140,SPARK_POS_OK,0.244453,0.285752,0.307893,0.310200,NORMAL,431,140,SPARK_POS_OK,0.313619,0.317401,0.236712,0.004063,NORMAL,915,4259,0 +24783894,431,168,SPARK_POS_OK,0.244334,0.285628,0.307734,0.310048,NORMAL,432,171,SPARK_POS_OK,0.313465,0.317222,0.236582,0.004047,NORMAL,928,4215,0 +24847894,432,191,SPARK_POS_OK,0.244145,0.285511,0.307571,0.309891,NORMAL,433,170,SPARK_POS_OK,0.313329,0.317090,0.236441,0.004058,NORMAL,935,4214,0 +24911894,433,190,SPARK_POS_OK,0.244005,0.285369,0.307417,0.309735,NORMAL,434,190,SPARK_POS_OK,0.313167,0.316929,0.236317,0.004044,NORMAL,942,4167,0 +24973894,434,210,SPARK_POS_OK,0.243829,0.285247,0.307274,0.309579,NORMAL,435,211,SPARK_POS_OK,0.313028,0.316777,0.236164,0.004048,NORMAL,954,4241,0 +25036894,435,211,SPARK_POS_OK,0.243638,0.285100,0.307117,0.309419,NORMAL,436,210,SPARK_POS_OK,0.312868,0.316624,0.236022,0.004035,NORMAL,955,4227,0 +25098894,436,230,SPARK_POS_OK,0.243536,0.284973,0.306952,0.309280,NORMAL,437,230,SPARK_POS_OK,0.312713,0.316477,0.235901,0.004037,NORMAL,968,4181,0 +25279894,437,27,SPARK_NEG_OK,0.243410,0.284898,0.306835,0.309154,SOFT_START,439,30,SPARK_NEG_OK,0.312610,0.316348,0.235793,0.003853,SOFT_START,1006,4170,0 +25339894,438,31,SPARK_NEG_OK,0.243244,0.284758,0.306692,0.308995,SOFT_START,440,30,SPARK_NEG_OK,0.312451,0.316194,0.235665,0.003845,SOFT_START,1007,4223,0 +25397894,439,61,SPARK_NEG_OK,0.243085,0.284633,0.306507,0.308831,SOFT_START,441,60,SPARK_NEG_OK,0.312278,0.316048,0.235487,0.003866,SOFT_START,1026,4248,0 +25455894,440,79,SPARK_NEG_OK,0.242942,0.284491,0.306376,0.308681,SOFT_START,442,60,SPARK_NEG_OK,0.312144,0.315886,0.235361,0.003877,SOFT_START,1035,4168,0 +25513894,441,81,SPARK_NEG_OK,0.242774,0.284367,0.306208,0.308532,SOFT_START,443,80,SPARK_NEG_OK,0.311990,0.315723,0.235237,0.003896,SOFT_START,1046,4174,0 +25569894,442,111,SPARK_NEG_OK,0.242639,0.284225,0.306057,0.308406,SOFT_START,444,82,SPARK_NEG_OK,0.311850,0.315569,0.235069,0.003919,SOFT_START,1056,4167,0 +25626894,443,111,SPARK_NEG_OK,0.242458,0.284095,0.305898,0.308211,SOFT_START,445,110,SPARK_NEG_OK,0.311676,0.315419,0.234944,0.003915,SOFT_START,1069,4174,0 +25681894,444,141,SPARK_NEG_OK,0.242298,0.283964,0.305749,0.308079,SOFT_START,446,111,SPARK_NEG_OK,0.311534,0.315236,0.234827,0.003957,SOFT_START,1081,4246,0 +25736894,445,137,SPARK_NEG_OK,0.242157,0.283839,0.305581,0.307902,SOFT_START,447,140,SPARK_NEG_OK,0.311376,0.315092,0.234657,0.003968,SOFT_START,1095,4145,0 +25790894,446,180,SPARK_NEG_OK,0.241993,0.283709,0.305410,0.307735,SOFT_START,448,140,SPARK_NEG_OK,0.311230,0.314946,0.234522,0.003969,SOFT_START,1108,4256,0 +25843894,447,180,SPARK_NEG_OK,0.241839,0.283583,0.305283,0.307602,SOFT_START,449,181,SPARK_NEG_OK,0.311077,0.314785,0.234398,0.003995,SOFT_START,1124,4222,0 +25896894,448,220,SPARK_NEG_OK,0.241687,0.283446,0.305122,0.307433,SOFT_START,450,179,SPARK_NEG_OK,0.310912,0.314633,0.234263,0.004035,SOFT_START,1137,4226,0 +25948894,449,221,SPARK_NEG_OK,0.241552,0.283313,0.304958,0.307270,SOFT_START,451,220,SPARK_NEG_OK,0.310754,0.314475,0.234109,0.004036,SOFT_START,1152,4179,0 +26000894,450,220,SPARK_NEG_OK,0.241355,0.283175,0.304803,0.307094,SOFT_START,452,268,SPARK_NEG_OK,0.310596,0.314305,0.233963,0.004069,SOFT_START,1165,4161,0 +26051894,451,220,SPARK_NEG_OK,0.241221,0.283045,0.304646,0.306938,SOFT_START,453,221,SPARK_NEG_OK,0.310454,0.314141,0.233824,0.004046,SOFT_START,1180,4267,0 +26101894,452,221,SPARK_NEG_OK,0.241018,0.282900,0.304496,0.306817,SOFT_START,454,220,SPARK_NEG_OK,0.310305,0.314004,0.233665,0.004085,SOFT_START,1192,4206,0 +26151894,453,218,SPARK_NEG_OK,0.240875,0.282788,0.304329,0.306650,SOFT_START,455,220,SPARK_NEG_OK,0.310143,0.313835,0.233539,0.004078,SOFT_START,1206,4214,0 +26200894,454,220,SPARK_NEG_OK,0.240688,0.282648,0.304160,0.306496,SOFT_START,456,220,SPARK_NEG_OK,0.310012,0.313680,0.233393,0.004114,SOFT_START,1218,4281,0 +26249894,455,220,SPARK_NEG_OK,0.240511,0.282523,0.304000,0.306337,SOFT_START,457,220,SPARK_NEG_OK,0.309834,0.313514,0.233258,0.004125,SOFT_START,1231,4242,0 +26297894,456,220,SPARK_NEG_OK,0.240330,0.282385,0.303854,0.306161,SOFT_START,458,221,SPARK_NEG_OK,0.309701,0.313366,0.233099,0.004139,SOFT_START,1242,4212,0 +26345894,457,220,SPARK_NEG_OK,0.240209,0.282228,0.303696,0.306008,SOFT_START,459,220,SPARK_NEG_OK,0.309542,0.313210,0.232970,0.004177,SOFT_START,1255,4159,0 +26392894,458,221,SPARK_NEG_OK,0.240078,0.282117,0.303548,0.305850,SOFT_START,460,221,SPARK_NEG_OK,0.309392,0.313063,0.232840,0.004176,SOFT_START,1264,4158,0 +26439894,459,220,SPARK_NEG_OK,0.239910,0.281997,0.303388,0.305706,SOFT_START,461,218,SPARK_NEG_OK,0.309226,0.312895,0.232692,0.004209,SOFT_START,1275,4181,0 +26486894,460,220,SPARK_NEG_OK,0.239752,0.281850,0.303227,0.305544,SOFT_START,462,221,SPARK_NEG_OK,0.309097,0.312724,0.232567,0.004241,SOFT_START,1275,4201,0 +26533894,461,220,SPARK_NEG_OK,0.239585,0.281708,0.303050,0.305390,SOFT_START,463,220,SPARK_NEG_OK,0.308936,0.312569,0.232423,0.004239,SOFT_START,1290,4239,0 +26579894,462,221,SPARK_NEG_OK,0.239377,0.281572,0.302912,0.305232,SOFT_START,464,220,SPARK_NEG_OK,0.308763,0.312415,0.232302,0.004249,SOFT_START,1291,4194,0 +26625894,463,220,SPARK_NEG_OK,0.239255,0.281433,0.302743,0.305044,SOFT_START,465,220,SPARK_NEG_OK,0.308610,0.312266,0.232133,0.004289,SOFT_START,1305,4218,0 +26671894,464,221,SPARK_NEG_OK,0.239088,0.281312,0.302593,0.304902,SOFT_START,466,220,SPARK_NEG_OK,0.308440,0.312108,0.231982,0.004290,SOFT_START,1306,4158,0 +26717894,465,221,SPARK_NEG_OK,0.238974,0.281166,0.302429,0.304756,SOFT_START,467,218,SPARK_NEG_OK,0.308318,0.311950,0.231846,0.004302,SOFT_START,1312,4175,0 +26762894,466,220,SPARK_NEG_OK,0.238776,0.281056,0.302278,0.304610,SOFT_START,468,220,SPARK_NEG_OK,0.308143,0.311779,0.231701,0.004311,SOFT_START,1321,4237,0 +26808894,467,221,SPARK_NEG_OK,0.238606,0.280928,0.302129,0.304453,SOFT_START,469,221,SPARK_NEG_OK,0.308000,0.311638,0.231573,0.004339,SOFT_START,1320,4256,0 +26853894,468,220,SPARK_NEG_OK,0.238449,0.280794,0.301973,0.304294,SOFT_START,470,220,SPARK_NEG_OK,0.307863,0.311469,0.231434,0.004324,SOFT_START,1334,4230,0 +26897894,469,220,SPARK_NEG_OK,0.238295,0.280654,0.301797,0.304121,SOFT_START,471,220,SPARK_NEG_OK,0.307693,0.311331,0.231290,0.004362,SOFT_START,1334,4192,0 +26942894,470,200,SPARK_NEG_OK,0.238133,0.280511,0.301649,0.303981,SOFT_START,472,201,SPARK_NEG_OK,0.307544,0.311139,0.231137,0.004382,SOFT_START,1337,4157,0 +26987894,471,200,SPARK_NEG_OK,0.237994,0.280377,0.301474,0.303811,SOFT_START,473,200,SPARK_NEG_OK,0.307391,0.311008,0.230992,0.004389,SOFT_START,1339,4152,0 +27032894,472,150,SPARK_NEG_OK,0.237804,0.280250,0.301327,0.303633,SOFT_START,474,200,SPARK_NEG_OK,0.307240,0.310833,0.230826,0.004396,SOFT_START,1336,4249,0 +27077894,473,150,SPARK_NEG_OK,0.237676,0.280110,0.301155,0.303475,SOFT_START,475,151,SPARK_NEG_OK,0.307068,0.310662,0.230710,0.004426,SOFT_START,1337,4184,0 +27122894,474,120,SPARK_NEG_OK,0.237524,0.279993,0.301018,0.303320,SOFT_START,476,150,SPARK_NEG_OK,0.306935,0.310528,0.230572,0.004422,SOFT_START,1333,4275,0 +27167894,475,121,SPARK_NEG_OK,0.237339,0.279855,0.300857,0.303157,SOFT_START,477,120,SPARK_NEG_OK,0.306786,0.310375,0.230430,0.004435,SOFT_START,1332,4162,0 +27212894,476,120,SPARK_NEG_OK,0.237194,0.279739,0.300708,0.303010,SOFT_START,478,121,SPARK_NEG_OK,0.306616,0.310200,0.230295,0.004436,SOFT_START,1332,4183,0 +27257894,477,100,SPARK_NEG_OK,0.237052,0.279588,0.300550,0.302844,SOFT_START,479,100,SPARK_NEG_OK,0.306465,0.310048,0.230173,0.004442,SOFT_START,1323,4202,0 +27302894,478,101,SPARK_NEG_OK,0.236890,0.279444,0.300393,0.302712,SOFT_START,480,101,SPARK_NEG_OK,0.306319,0.309893,0.230032,0.004466,SOFT_START,1325,4249,0 +27348894,479,80,SPARK_NEG_OK,0.236716,0.279326,0.300222,0.302529,SOFT_START,481,100,SPARK_NEG_OK,0.306185,0.309737,0.229876,0.004470,SOFT_START,1319,4260,0 +27393894,480,80,SPARK_NEG_OK,0.236563,0.279172,0.300086,0.302406,SOFT_START,482,80,SPARK_NEG_OK,0.306013,0.309591,0.229754,0.004476,SOFT_START,1316,4160,0 +27439894,481,60,SPARK_NEG_OK,0.236393,0.279056,0.299922,0.302218,SOFT_START,483,81,SPARK_NEG_OK,0.305859,0.309443,0.229610,0.004498,SOFT_START,1309,4241,0 +27485894,482,60,SPARK_NEG_OK,0.236264,0.278920,0.299768,0.302089,SOFT_START,484,60,SPARK_NEG_OK,0.305741,0.309281,0.229437,0.004495,SOFT_START,1305,4163,0 +27531894,483,61,SPARK_NEG_OK,0.236121,0.278792,0.299601,0.301903,SOFT_START,485,61,SPARK_NEG_OK,0.305582,0.309130,0.229292,0.004489,SOFT_START,1305,4216,0 +27578894,484,40,SPARK_NEG_OK,0.235947,0.278673,0.299451,0.301791,SOFT_START,486,40,SPARK_NEG_OK,0.305398,0.308973,0.229186,0.004495,SOFT_START,1289,4254,0 +27624894,485,41,SPARK_NEG_OK,0.235777,0.278535,0.299291,0.301610,SOFT_START,487,40,SPARK_NEG_OK,0.305252,0.308834,0.229037,0.004504,SOFT_START,1291,4188,0 +27671894,486,25,SPARK_NEG_OK,0.235615,0.278394,0.299131,0.301462,SOFT_START,488,25,SPARK_NEG_OK,0.305108,0.308660,0.228924,0.004501,SOFT_START,1274,4194,0 +27718894,487,25,SPARK_NEG_OK,0.235474,0.278265,0.298988,0.301294,SOFT_START,489,25,SPARK_NEG_OK,0.304982,0.308506,0.228761,0.004511,SOFT_START,1275,4235,0 +27766894,488,240,SPARK_POS_OK,0.235290,0.278150,0.298833,0.301164,NORMAL,490,25,SPARK_NEG_OK,0.304818,0.308329,0.228631,0.004478,SOFT_START,1275,4268,0 +27814894,489,241,SPARK_POS_OK,0.235133,0.278005,0.298676,0.300983,NORMAL,491,240,SPARK_POS_OK,0.304641,0.308191,0.228487,0.004510,NORMAL,1262,4191,0 +27861894,490,220,SPARK_POS_OK,0.235007,0.277883,0.298517,0.300829,NORMAL,492,241,SPARK_POS_OK,0.304506,0.308035,0.228362,0.004495,NORMAL,1253,4171,0 +27910894,491,221,SPARK_POS_OK,0.234870,0.277768,0.298377,0.300696,NORMAL,493,220,SPARK_POS_OK,0.304349,0.307886,0.228217,0.004492,NORMAL,1246,4180,0 +27958894,492,192,SPARK_POS_OK,0.234726,0.277621,0.298216,0.300523,NORMAL,494,221,SPARK_POS_OK,0.304200,0.307726,0.228056,0.004503,NORMAL,1237,4184,0 +28007894,493,191,SPARK_POS_OK,0.234546,0.277506,0.298065,0.300381,NORMAL,495,190,SPARK_POS_OK,0.304072,0.307571,0.227940,0.004511,NORMAL,1228,4158,0 +28056894,494,219,SPARK_POS_OK,0.234405,0.277355,0.297914,0.300225,NORMAL,496,190,SPARK_POS_OK,0.303894,0.307428,0.227815,0.004506,NORMAL,1228,4214,0 +28105894,495,170,SPARK_POS_OK,0.234249,0.277219,0.297754,0.300079,NORMAL,497,170,SPARK_POS_OK,0.303753,0.307287,0.227692,0.004506,NORMAL,1208,4149,0 +28155894,496,172,SPARK_POS_OK,0.234093,0.277112,0.297602,0.299907,NORMAL,498,168,SPARK_POS_OK,0.303609,0.307118,0.227537,0.004491,NORMAL,1208,4216,0 +28206894,497,150,SPARK_POS_OK,0.233985,0.276974,0.297437,0.299759,NORMAL,499,151,SPARK_POS_OK,0.303454,0.306962,0.227410,0.004479,NORMAL,1186,4153,0 +28256894,498,151,SPARK_POS_OK,0.233786,0.276864,0.297296,0.299616,NORMAL,500,150,SPARK_POS_OK,0.303313,0.306812,0.227254,0.004480,NORMAL,1187,4269,0 +28308894,499,130,SPARK_POS_OK,0.233641,0.276716,0.297128,0.299439,NORMAL,501,130,SPARK_POS_OK,0.303178,0.306637,0.227132,0.004466,NORMAL,1167,4170,0 +28359894,500,130,SPARK_POS_OK,0.233482,0.276599,0.297002,0.299293,NORMAL,502,131,SPARK_POS_OK,0.303010,0.306511,0.226998,0.004463,NORMAL,1167,4250,0 +28411894,501,110,SPARK_POS_OK,0.233346,0.276440,0.296826,0.299152,NORMAL,503,110,SPARK_POS_OK,0.302870,0.306368,0.226858,0.004464,NORMAL,1147,4220,0 +28464894,502,111,SPARK_POS_OK,0.233172,0.276349,0.296684,0.299016,NORMAL,504,110,SPARK_POS_OK,0.302728,0.306208,0.226721,0.004426,NORMAL,1148,4240,0 +28517894,503,90,SPARK_POS_OK,0.233042,0.276198,0.296519,0.298835,NORMAL,505,91,SPARK_POS_OK,0.302579,0.306072,0.226577,0.004460,NORMAL,1127,4183,0 +28570894,504,90,SPARK_POS_OK,0.232871,0.276086,0.296401,0.298697,NORMAL,506,90,SPARK_POS_OK,0.302422,0.305900,0.226443,0.004445,NORMAL,1127,4177,0 +28624894,505,70,SPARK_POS_OK,0.232748,0.275949,0.296220,0.298554,NORMAL,507,71,SPARK_POS_OK,0.302281,0.305759,0.226333,0.004415,NORMAL,1103,4200,0 +28679894,506,70,SPARK_POS_OK,0.232572,0.275822,0.296072,0.298413,NORMAL,508,70,SPARK_POS_OK,0.302138,0.305597,0.226177,0.004410,NORMAL,1104,4264,0 +28734894,507,50,SPARK_POS_OK,0.232410,0.275686,0.295929,0.298222,NORMAL,509,50,SPARK_POS_OK,0.301995,0.305448,0.226059,0.004398,NORMAL,1081,4220,0 +28790894,508,30,SPARK_POS_OK,0.232251,0.275572,0.295786,0.298082,NORMAL,510,52,SPARK_POS_OK,0.301843,0.305323,0.225919,0.004374,NORMAL,1070,4269,0 +28847894,509,30,SPARK_POS_OK,0.232106,0.275454,0.295643,0.297915,NORMAL,511,30,SPARK_POS_OK,0.301710,0.305157,0.225785,0.004373,NORMAL,1060,4195,0 +28904894,510,30,SPARK_POS_OK,0.231964,0.275316,0.295492,0.297777,NORMAL,512,29,SPARK_POS_OK,0.301558,0.305012,0.225647,0.004357,NORMAL,1060,4169,0 +28962894,511,30,SPARK_POS_OK,0.231856,0.275185,0.295308,0.297637,NORMAL,513,29,SPARK_POS_OK,0.301403,0.304863,0.225520,0.004330,NORMAL,1060,4154,0 +29020894,512,30,SPARK_POS_OK,0.231654,0.275059,0.295185,0.297471,NORMAL,514,29,SPARK_POS_OK,0.301254,0.304716,0.225407,0.004314,NORMAL,1060,4229,0 +29079894,513,30,SPARK_POS_OK,0.231529,0.274943,0.295056,0.297354,NORMAL,515,29,SPARK_POS_OK,0.301126,0.304580,0.225252,0.004290,NORMAL,1060,4229,0 +29140894,514,30,SPARK_POS_OK,0.231363,0.274788,0.294892,0.297194,NORMAL,516,29,SPARK_POS_OK,0.300963,0.304419,0.225143,0.004274,NORMAL,1060,4265,0 +29201894,515,30,SPARK_POS_OK,0.231243,0.274711,0.294742,0.297049,NORMAL,517,29,SPARK_POS_OK,0.300827,0.304254,0.225012,0.004261,NORMAL,1060,4205,0 +29263894,516,30,SPARK_POS_OK,0.231097,0.274554,0.294609,0.296904,NORMAL,518,29,SPARK_POS_OK,0.300693,0.304128,0.224861,0.004250,NORMAL,1060,4222,0 +29325894,517,30,SPARK_POS_OK,0.230927,0.274445,0.294461,0.296749,NORMAL,519,29,SPARK_POS_OK,0.300543,0.303966,0.224741,0.004233,NORMAL,1060,4208,0 +29388894,518,30,SPARK_POS_OK,0.230758,0.274323,0.294295,0.296606,NORMAL,520,29,SPARK_POS_OK,0.300400,0.303816,0.224615,0.004211,NORMAL,1060,4241,0 +29452894,519,30,SPARK_POS_OK,0.230615,0.274199,0.294167,0.296452,NORMAL,521,29,SPARK_POS_OK,0.300251,0.303678,0.224453,0.004197,NORMAL,1060,4258,0 +29516894,520,30,SPARK_POS_OK,0.230507,0.274069,0.293997,0.296320,NORMAL,522,29,SPARK_POS_OK,0.300115,0.303529,0.224360,0.004165,NORMAL,1060,4201,0 +29580894,521,30,SPARK_POS_OK,0.230321,0.273947,0.293862,0.296165,NORMAL,523,29,SPARK_POS_OK,0.299969,0.303385,0.224254,0.004139,NORMAL,1060,4260,0 +29645894,522,30,SPARK_POS_OK,0.230199,0.273811,0.293727,0.296023,NORMAL,524,29,SPARK_POS_OK,0.299823,0.303254,0.224081,0.004141,NORMAL,1060,4149,0 +29711894,523,30,SPARK_POS_OK,0.230053,0.273697,0.293586,0.295871,NORMAL,525,29,SPARK_POS_OK,0.299684,0.303107,0.223966,0.004110,NORMAL,1060,4234,0 +29778894,524,30,SPARK_POS_OK,0.229897,0.273574,0.293452,0.295721,NORMAL,526,29,SPARK_POS_OK,0.299528,0.302956,0.223830,0.004099,NORMAL,1060,4268,0 +29844894,525,18,SPARK_POS_OK,0.229737,0.273463,0.293287,0.295576,NORMAL,527,29,SPARK_POS_OK,0.299393,0.302807,0.223719,0.004088,NORMAL,60,4253,0 +29911894,526,25,SPARK_POS_OK,0.229585,0.273339,0.293126,0.295432,NORMAL,528,25,SPARK_POS_OK,0.299249,0.302660,0.223577,0.004053,NORMAL,898,4248,0 +29978894,527,50,SPARK_POS_OK,0.229421,0.273230,0.292988,0.295304,NORMAL,529,50,SPARK_POS_OK,0.299109,0.302531,0.223458,0.004053,NORMAL,897,4250,0 +30045894,528,71,SPARK_POS_OK,0.229278,0.273093,0.292861,0.295157,NORMAL,530,50,SPARK_POS_OK,0.298978,0.302386,0.223312,0.004017,NORMAL,898,4157,0 +30111894,529,70,SPARK_POS_OK,0.229153,0.272971,0.292700,0.295006,NORMAL,531,70,SPARK_POS_OK,0.298840,0.302225,0.223220,0.004009,NORMAL,900,4156,0 +30178894,530,81,SPARK_POS_OK,0.229019,0.272849,0.292549,0.294856,NORMAL,532,80,SPARK_POS_OK,0.298682,0.302095,0.223073,0.004002,NORMAL,900,4184,0 +30244894,531,100,SPARK_POS_OK,0.228902,0.272712,0.292414,0.294721,NORMAL,533,80,SPARK_POS_OK,0.298550,0.301940,0.222973,0.003992,NORMAL,901,4190,0 +30311894,532,101,SPARK_POS_OK,0.228704,0.272602,0.292251,0.294572,NORMAL,534,100,SPARK_POS_OK,0.298408,0.301793,0.222811,0.003995,NORMAL,904,4221,0 +30377894,533,110,SPARK_POS_OK,0.228599,0.272483,0.292122,0.294414,NORMAL,535,109,SPARK_POS_OK,0.298252,0.301656,0.222685,0.003978,NORMAL,906,4176,0 +30443894,534,111,SPARK_POS_OK,0.228439,0.272374,0.291972,0.294291,NORMAL,536,110,SPARK_POS_OK,0.298129,0.301508,0.222601,0.003955,NORMAL,910,4154,0 +30508894,535,133,SPARK_POS_OK,0.228352,0.272239,0.291821,0.294130,NORMAL,537,130,SPARK_POS_OK,0.298014,0.301350,0.222435,0.003946,NORMAL,918,4209,0 +30573894,536,150,SPARK_POS_OK,0.228187,0.272096,0.291667,0.293991,NORMAL,538,131,SPARK_POS_OK,0.297840,0.301217,0.222303,0.003926,NORMAL,923,4164,0 +30638894,537,150,SPARK_POS_OK,0.228051,0.271986,0.291539,0.293838,NORMAL,539,150,SPARK_POS_OK,0.297694,0.301065,0.222185,0.003922,NORMAL,928,4197,0 +30702894,538,170,SPARK_POS_OK,0.227895,0.271876,0.291392,0.293676,NORMAL,540,170,SPARK_POS_OK,0.297551,0.300927,0.222085,0.003925,NORMAL,935,4219,0 +30766894,539,191,SPARK_POS_OK,0.227766,0.271754,0.291253,0.293556,NORMAL,541,170,SPARK_POS_OK,0.297411,0.300766,0.221926,0.003914,NORMAL,940,4203,0 +30829894,540,190,SPARK_POS_OK,0.227587,0.271612,0.291104,0.293421,NORMAL,542,190,SPARK_POS_OK,0.297287,0.300643,0.221813,0.003932,NORMAL,947,4209,0 +30892894,541,210,SPARK_POS_OK,0.227440,0.271500,0.290959,0.293264,NORMAL,543,191,SPARK_POS_OK,0.297142,0.300490,0.221671,0.003911,NORMAL,953,4255,0 +30954894,542,208,SPARK_POS_OK,0.227338,0.271378,0.290822,0.293120,NORMAL,544,210,SPARK_POS_OK,0.296986,0.300339,0.221546,0.003938,NORMAL,962,4171,0 +31015894,543,231,SPARK_POS_OK,0.227185,0.271240,0.290673,0.292974,NORMAL,545,230,SPARK_POS_OK,0.296851,0.300217,0.221401,0.003914,NORMAL,978,4189,0 +31196894,544,30,SPARK_NEG_OK,0.227097,0.271150,0.290566,0.292864,SOFT_START,546,230,SPARK_NEG_WAIT,0.296770,0.300094,0.221338,0.003732,NORMAL,1001,4171,0 +31255894,545,30,SPARK_NEG_OK,0.226947,0.271028,0.290417,0.292725,SOFT_START,547,30,SPARK_NEG_OK,0.296605,0.299956,0.221204,0.003748,SOFT_START,1010,4251,0 +31314894,546,50,SPARK_NEG_OK,0.226794,0.270930,0.290271,0.292549,SOFT_START,548,52,SPARK_NEG_OK,0.296459,0.299803,0.221077,0.003765,SOFT_START,1026,4172,0 +31372894,547,51,SPARK_NEG_OK,0.226651,0.270789,0.290137,0.292426,SOFT_START,549,50,SPARK_NEG_OK,0.296304,0.299659,0.220951,0.003769,SOFT_START,1027,4165,0 +31430894,548,70,SPARK_NEG_OK,0.226499,0.270665,0.289981,0.292265,SOFT_START,550,71,SPARK_NEG_OK,0.296170,0.299509,0.220838,0.003793,SOFT_START,1046,4275,0 +31487894,549,92,SPARK_NEG_OK,0.226340,0.270549,0.289845,0.292126,SOFT_START,551,70,SPARK_NEG_OK,0.296020,0.299360,0.220708,0.003812,SOFT_START,1047,4250,0 +31543894,550,90,SPARK_NEG_OK,0.226200,0.270408,0.289685,0.291980,SOFT_START,552,90,SPARK_NEG_OK,0.295882,0.299222,0.220565,0.003802,SOFT_START,1068,4164,0 +31599894,551,110,SPARK_NEG_OK,0.226091,0.270299,0.289539,0.291825,SOFT_START,553,90,SPARK_NEG_OK,0.295726,0.299069,0.220453,0.003850,SOFT_START,1079,4168,0 +31654894,552,110,SPARK_NEG_OK,0.225908,0.270163,0.289385,0.291685,SOFT_START,554,110,SPARK_NEG_OK,0.295606,0.298903,0.220297,0.003855,SOFT_START,1091,4267,0 +31708894,553,140,SPARK_NEG_OK,0.225781,0.270032,0.289235,0.291539,SOFT_START,555,111,SPARK_NEG_OK,0.295478,0.298759,0.220181,0.003861,SOFT_START,1101,4150,0 +31762894,554,140,SPARK_NEG_OK,0.225610,0.269906,0.289096,0.291394,SOFT_START,556,141,SPARK_NEG_OK,0.295316,0.298629,0.220047,0.003878,SOFT_START,1113,4243,0 +31815894,555,171,SPARK_NEG_OK,0.225482,0.269780,0.288954,0.291249,SOFT_START,557,140,SPARK_NEG_OK,0.295166,0.298475,0.219911,0.003871,SOFT_START,1123,4150,0 +31868894,556,171,SPARK_NEG_OK,0.225355,0.269666,0.288804,0.291082,SOFT_START,558,170,SPARK_NEG_OK,0.295011,0.298344,0.219790,0.003916,SOFT_START,1136,4163,0 +31921894,557,200,SPARK_NEG_OK,0.225197,0.269532,0.288649,0.290950,SOFT_START,559,170,SPARK_NEG_OK,0.294881,0.298182,0.219643,0.003912,SOFT_START,1147,4258,0 +31972894,558,200,SPARK_NEG_OK,0.225049,0.269413,0.288505,0.290800,SOFT_START,560,201,SPARK_NEG_OK,0.294744,0.298035,0.219514,0.003937,SOFT_START,1161,4190,0 +32023894,559,221,SPARK_NEG_OK,0.224914,0.269298,0.288351,0.290653,SOFT_START,561,200,SPARK_NEG_OK,0.294604,0.297887,0.219409,0.003936,SOFT_START,1173,4233,0 +32074894,560,220,SPARK_NEG_OK,0.224741,0.269151,0.288212,0.290508,SOFT_START,562,220,SPARK_NEG_OK,0.294451,0.297741,0.219271,0.003975,SOFT_START,1188,4261,0 +32124894,561,220,SPARK_NEG_OK,0.224595,0.269035,0.288078,0.290365,SOFT_START,563,221,SPARK_NEG_OK,0.294299,0.297612,0.219138,0.003971,SOFT_START,1198,4214,0 +32173894,562,221,SPARK_NEG_OK,0.224457,0.268905,0.287915,0.290209,SOFT_START,564,220,SPARK_NEG_OK,0.294173,0.297448,0.219002,0.003996,SOFT_START,1212,4194,0 +32222894,563,220,SPARK_NEG_OK,0.224333,0.268773,0.287753,0.290070,SOFT_START,565,220,SPARK_NEG_OK,0.294014,0.297293,0.218863,0.004018,SOFT_START,1222,4165,0 +32271894,564,221,SPARK_NEG_OK,0.224152,0.268652,0.287609,0.289907,SOFT_START,566,220,SPARK_NEG_OK,0.293874,0.297136,0.218728,0.004048,SOFT_START,1234,4226,0 +32320894,565,220,SPARK_NEG_OK,0.223991,0.268545,0.287464,0.289770,SOFT_START,567,220,SPARK_NEG_OK,0.293739,0.297003,0.218605,0.004079,SOFT_START,1234,4235,0 +32368894,566,221,SPARK_NEG_OK,0.223832,0.268385,0.287308,0.289612,SOFT_START,568,220,SPARK_NEG_OK,0.293614,0.296863,0.218485,0.004086,SOFT_START,1253,4277,0 +32415894,567,220,SPARK_NEG_OK,0.223702,0.268284,0.287163,0.289459,SOFT_START,569,220,SPARK_NEG_OK,0.293436,0.296702,0.218351,0.004088,SOFT_START,1254,4185,0 +32463894,568,221,SPARK_NEG_OK,0.223539,0.268133,0.287021,0.289323,SOFT_START,570,221,SPARK_NEG_OK,0.293300,0.296544,0.218212,0.004120,SOFT_START,1272,4253,0 +32510894,569,220,SPARK_NEG_OK,0.223411,0.268019,0.286869,0.289187,SOFT_START,571,220,SPARK_NEG_OK,0.293167,0.296410,0.218098,0.004146,SOFT_START,1274,4229,0 +32556894,570,221,SPARK_NEG_OK,0.223255,0.267893,0.286747,0.289009,SOFT_START,572,220,SPARK_NEG_OK,0.293028,0.296266,0.217940,0.004130,SOFT_START,1291,4153,0 +32602899,571,220,SPARK_NEG_OK,0.223058,0.267776,0.286589,0.288869,SOFT_START,573,220,SPARK_NEG_OK,0.292874,0.296096,0.217817,0.004131,SOFT_START,1292,4261,0 +32649894,572,221,SPARK_NEG_OK,0.222954,0.267630,0.286425,0.288712,SOFT_START,574,220,SPARK_NEG_OK,0.292727,0.295968,0.217693,0.004166,SOFT_START,1298,4178,0 +32695894,573,220,SPARK_NEG_OK,0.222799,0.267516,0.286273,0.288576,SOFT_START,575,221,SPARK_NEG_OK,0.292587,0.295816,0.217561,0.004193,SOFT_START,1307,4272,0 +32740894,574,220,SPARK_NEG_OK,0.222647,0.267380,0.286134,0.288430,SOFT_START,576,220,SPARK_NEG_OK,0.292442,0.295664,0.217426,0.004186,SOFT_START,1311,4260,0 +32786894,575,221,SPARK_NEG_OK,0.222493,0.267292,0.285975,0.288275,SOFT_START,577,221,SPARK_NEG_OK,0.292296,0.295509,0.217326,0.004219,SOFT_START,1319,4241,0 +32831894,576,220,SPARK_NEG_OK,0.222350,0.267133,0.285851,0.288131,SOFT_START,578,220,SPARK_NEG_OK,0.292144,0.295361,0.217180,0.004225,SOFT_START,1319,4222,0 +32876894,577,220,SPARK_NEG_OK,0.222221,0.267005,0.285688,0.287982,SOFT_START,579,220,SPARK_NEG_OK,0.292020,0.295215,0.217054,0.004244,SOFT_START,1329,4152,0 +32922894,578,220,SPARK_NEG_OK,0.222057,0.266885,0.285548,0.287839,SOFT_START,580,221,SPARK_NEG_OK,0.291863,0.295089,0.216917,0.004260,SOFT_START,1330,4271,0 +32966894,579,220,SPARK_NEG_OK,0.221909,0.266747,0.285396,0.287680,SOFT_START,581,222,SPARK_NEG_OK,0.291705,0.294917,0.216799,0.004268,SOFT_START,1340,4178,0 +33011894,580,218,SPARK_NEG_OK,0.221742,0.266636,0.285243,0.287526,SOFT_START,582,220,SPARK_NEG_OK,0.291577,0.294788,0.216637,0.004264,SOFT_START,1341,4272,0 +33056894,581,220,SPARK_NEG_OK,0.221614,0.266501,0.285096,0.287389,SOFT_START,583,221,SPARK_NEG_OK,0.291437,0.294625,0.216532,0.004283,SOFT_START,1345,4191,0 +33100894,582,220,SPARK_NEG_OK,0.221465,0.266403,0.284954,0.287235,SOFT_START,584,220,SPARK_NEG_OK,0.291283,0.294502,0.216410,0.004286,SOFT_START,1350,4165,0 +33144894,583,221,SPARK_NEG_OK,0.221301,0.266253,0.284796,0.287101,SOFT_START,585,220,SPARK_NEG_OK,0.291148,0.294346,0.216251,0.004312,SOFT_START,1350,4272,0 +33189894,584,190,SPARK_NEG_OK,0.221170,0.266118,0.284649,0.286964,SOFT_START,586,191,SPARK_NEG_OK,0.291015,0.294184,0.216144,0.004308,SOFT_START,1350,4268,0 +33233894,585,190,SPARK_NEG_OK,0.221002,0.266004,0.284517,0.286789,SOFT_START,587,190,SPARK_NEG_OK,0.290853,0.294049,0.216001,0.004324,SOFT_START,1351,4149,0 +33278894,586,151,SPARK_NEG_OK,0.220879,0.265905,0.284364,0.286654,SOFT_START,588,148,SPARK_NEG_OK,0.290717,0.293917,0.215877,0.004335,SOFT_START,1348,4235,0 +33322894,587,150,SPARK_NEG_OK,0.220745,0.265746,0.284213,0.286506,SOFT_START,589,151,SPARK_NEG_OK,0.290567,0.293751,0.215759,0.004358,SOFT_START,1348,4150,0 +33367894,588,120,SPARK_NEG_OK,0.220601,0.265614,0.284064,0.286338,SOFT_START,590,150,SPARK_NEG_OK,0.290433,0.293602,0.215640,0.004355,SOFT_START,1344,4195,0 +33411894,589,121,SPARK_NEG_OK,0.220446,0.265481,0.283915,0.286192,SOFT_START,591,120,SPARK_NEG_OK,0.290278,0.293458,0.215487,0.004383,SOFT_START,1342,4162,0 +33456894,590,120,SPARK_NEG_OK,0.220311,0.265375,0.283771,0.286060,SOFT_START,592,120,SPARK_NEG_OK,0.290154,0.293300,0.215356,0.004362,SOFT_START,1342,4256,0 +33501894,591,100,SPARK_NEG_OK,0.220193,0.265262,0.283619,0.285911,SOFT_START,593,100,SPARK_NEG_OK,0.290006,0.293163,0.215232,0.004379,SOFT_START,1332,4174,0 +33546894,592,101,SPARK_NEG_OK,0.220030,0.265129,0.283490,0.285764,SOFT_START,594,100,SPARK_NEG_OK,0.289842,0.293036,0.215108,0.004383,SOFT_START,1333,4256,0 +33591897,593,70,SPARK_NEG_OK,0.219882,0.265003,0.283312,0.285606,SOFT_START,595,71,SPARK_NEG_OK,0.289702,0.292856,0.214979,0.004376,SOFT_START,1321,4203,0 +33637894,594,70,SPARK_NEG_OK,0.219761,0.264870,0.283198,0.285496,SOFT_START,596,70,SPARK_NEG_OK,0.289568,0.292754,0.214847,0.004398,SOFT_START,1322,4170,0 +33683894,595,40,SPARK_NEG_OK,0.219610,0.264744,0.283063,0.285316,SOFT_START,597,71,SPARK_NEG_OK,0.289434,0.292597,0.214727,0.004407,SOFT_START,1313,4248,0 +33728894,596,40,SPARK_NEG_OK,0.219433,0.264626,0.282887,0.285174,SOFT_START,598,40,SPARK_NEG_OK,0.289289,0.292440,0.214608,0.004391,SOFT_START,1307,4209,0 +33774894,597,40,SPARK_NEG_OK,0.219309,0.264485,0.282733,0.285023,SOFT_START,599,40,SPARK_NEG_OK,0.289144,0.292300,0.214483,0.004406,SOFT_START,1307,4169,0 +33821894,598,25,SPARK_NEG_OK,0.219164,0.264351,0.282601,0.284892,SOFT_START,600,25,SPARK_NEG_OK,0.289014,0.292149,0.214335,0.004404,SOFT_START,1288,4275,0 +33867894,599,25,SPARK_NEG_OK,0.219021,0.264238,0.282480,0.284735,SOFT_START,601,25,SPARK_NEG_OK,0.288854,0.292002,0.214229,0.004414,SOFT_START,1289,4150,0 +34010894,600,230,SPARK_POS_OK,0.218923,0.264163,0.282345,0.284633,NORMAL,602,230,SPARK_POS_OK,0.288753,0.291890,0.214139,0.004190,NORMAL,1262,4161,0 +34058894,601,231,SPARK_POS_OK,0.218782,0.264018,0.282212,0.284500,NORMAL,603,230,SPARK_POS_OK,0.288612,0.291755,0.213985,0.004213,NORMAL,1256,4261,0 +34106894,602,210,SPARK_POS_OK,0.218613,0.263910,0.282043,0.284339,NORMAL,604,231,SPARK_POS_OK,0.288465,0.291602,0.213870,0.004219,NORMAL,1246,4249,0 +34154894,603,211,SPARK_POS_OK,0.218469,0.263771,0.281917,0.284205,NORMAL,605,210,SPARK_POS_OK,0.288340,0.291449,0.213743,0.004221,NORMAL,1239,4223,0 +34203894,604,180,SPARK_POS_OK,0.218338,0.263654,0.281764,0.284051,NORMAL,606,210,SPARK_POS_OK,0.288197,0.291333,0.213640,0.004241,NORMAL,1228,4275,0 +34253894,605,181,SPARK_POS_OK,0.218177,0.263538,0.281628,0.283921,NORMAL,607,180,SPARK_POS_OK,0.288049,0.291172,0.213487,0.004234,NORMAL,1218,4257,0 +34302894,606,160,SPARK_POS_OK,0.218021,0.263417,0.281486,0.283763,NORMAL,608,180,SPARK_POS_OK,0.287909,0.291052,0.213367,0.004215,NORMAL,1206,4250,0 +34352894,607,160,SPARK_POS_OK,0.217876,0.263287,0.281342,0.283609,NORMAL,609,161,SPARK_POS_OK,0.287775,0.290890,0.213259,0.004232,NORMAL,1196,4238,0 +34403894,608,139,SPARK_POS_OK,0.217735,0.263172,0.281190,0.283456,NORMAL,610,160,SPARK_POS_OK,0.287634,0.290743,0.213134,0.004218,NORMAL,1185,4248,0 +34454894,609,140,SPARK_POS_OK,0.217576,0.263045,0.281042,0.283325,NORMAL,611,140,SPARK_POS_OK,0.287511,0.290605,0.213003,0.004237,NORMAL,1175,4248,0 +34506894,610,111,SPARK_POS_OK,0.217422,0.262920,0.280915,0.283189,NORMAL,612,141,SPARK_POS_OK,0.287367,0.290461,0.212876,0.004232,NORMAL,1164,4281,0 +34558894,611,111,SPARK_POS_OK,0.217294,0.262783,0.280773,0.283042,NORMAL,613,110,SPARK_POS_OK,0.287238,0.290313,0.212728,0.004213,NORMAL,1154,4182,0 +34610894,612,93,SPARK_POS_OK,0.217142,0.262676,0.280632,0.282895,NORMAL,614,110,SPARK_POS_OK,0.287075,0.290173,0.212619,0.004225,NORMAL,1143,4218,0 +34663894,613,90,SPARK_POS_OK,0.216988,0.262541,0.280485,0.282761,NORMAL,615,90,SPARK_POS_OK,0.286961,0.290027,0.212517,0.004214,NORMAL,1133,4228,0 +34716894,614,70,SPARK_POS_OK,0.216900,0.262419,0.280350,0.282615,NORMAL,616,91,SPARK_POS_OK,0.286793,0.289903,0.212389,0.004218,NORMAL,1121,4155,0 +34771894,615,70,SPARK_POS_OK,0.216745,0.262302,0.280189,0.282466,NORMAL,617,70,SPARK_POS_OK,0.286642,0.289757,0.212252,0.004212,NORMAL,1110,4242,0 +34825894,616,50,SPARK_POS_OK,0.216602,0.262186,0.280063,0.282335,NORMAL,618,70,SPARK_POS_OK,0.286527,0.289600,0.212144,0.004207,NORMAL,1097,4221,0 +34880894,617,51,SPARK_POS_OK,0.216441,0.262075,0.279932,0.282189,NORMAL,619,50,SPARK_POS_OK,0.286393,0.289466,0.212007,0.004208,NORMAL,1086,4194,0 +34936894,618,41,SPARK_POS_OK,0.216339,0.261927,0.279781,0.282065,NORMAL,620,50,SPARK_POS_OK,0.286254,0.289338,0.211874,0.004185,NORMAL,1074,4184,0 +34993894,619,41,SPARK_POS_OK,0.216206,0.261821,0.279639,0.281928,NORMAL,621,40,SPARK_POS_OK,0.286109,0.289190,0.211774,0.004189,NORMAL,1063,4157,0 +35050894,620,25,SPARK_POS_OK,0.216070,0.261710,0.279472,0.281775,NORMAL,622,40,SPARK_POS_OK,0.285965,0.289056,0.211664,0.004166,NORMAL,1051,4166,0 +35107894,621,25,SPARK_POS_OK,0.215958,0.261584,0.279363,0.281629,NORMAL,623,25,SPARK_POS_OK,0.285835,0.288917,0.211526,0.004141,NORMAL,1041,4179,0 +35166894,622,25,SPARK_POS_OK,0.215852,0.261455,0.279204,0.281507,NORMAL,624,25,SPARK_POS_OK,0.285711,0.288778,0.211395,0.004149,NORMAL,1041,4158,0 +35225894,623,25,SPARK_POS_OK,0.215697,0.261327,0.279067,0.281358,NORMAL,625,25,SPARK_POS_OK,0.285565,0.288635,0.211287,0.004148,NORMAL,1041,4195,0 +35285894,624,25,SPARK_POS_OK,0.215550,0.261243,0.278931,0.281226,NORMAL,626,25,SPARK_POS_OK,0.285427,0.288497,0.211173,0.004114,NORMAL,1041,4264,0 +35346894,625,25,SPARK_POS_OK,0.215418,0.261111,0.278800,0.281084,NORMAL,627,25,SPARK_POS_OK,0.285299,0.288371,0.211050,0.004109,NORMAL,1041,4177,0 +35408894,626,25,SPARK_POS_OK,0.215275,0.260987,0.278656,0.280928,NORMAL,628,25,SPARK_POS_OK,0.285162,0.288201,0.210943,0.004089,NORMAL,1041,4248,0 +35470894,627,25,SPARK_POS_OK,0.215132,0.260886,0.278528,0.280776,NORMAL,629,25,SPARK_POS_OK,0.285029,0.288087,0.210811,0.004069,NORMAL,1041,4193,0 +35533894,628,25,SPARK_POS_OK,0.215003,0.260752,0.278396,0.280665,NORMAL,630,25,SPARK_POS_OK,0.284912,0.287941,0.210699,0.004070,NORMAL,1041,4246,0 +35596894,629,25,SPARK_POS_OK,0.214865,0.260631,0.278243,0.280498,NORMAL,631,25,SPARK_POS_OK,0.284758,0.287799,0.210554,0.004044,NORMAL,1041,4180,0 +35661894,630,25,SPARK_POS_OK,0.214735,0.260540,0.278130,0.280364,NORMAL,632,25,SPARK_POS_OK,0.284619,0.287676,0.210446,0.004028,NORMAL,1041,4205,0 +35725894,631,25,SPARK_POS_OK,0.214604,0.260414,0.277976,0.280225,NORMAL,633,25,SPARK_POS_OK,0.284517,0.287534,0.210330,0.004011,NORMAL,1041,4218,0 +35791894,632,25,SPARK_POS_OK,0.214474,0.260302,0.277838,0.280115,NORMAL,634,25,SPARK_POS_OK,0.284371,0.287407,0.210209,0.003995,NORMAL,1041,4234,0 +35857894,633,25,SPARK_POS_OK,0.214345,0.260153,0.277704,0.279993,NORMAL,635,25,SPARK_POS_OK,0.284230,0.287284,0.210090,0.003946,NORMAL,1041,4146,0 +35924894,634,25,SPARK_POS_OK,0.214211,0.260050,0.277567,0.279846,NORMAL,636,25,SPARK_POS_OK,0.284095,0.287125,0.209954,0.003960,NORMAL,1041,4280,0 +35991894,635,25,SPARK_POS_OK,0.214071,0.259948,0.277441,0.279709,NORMAL,637,25,SPARK_POS_OK,0.283967,0.286993,0.209862,0.003954,NORMAL,1041,4228,0 +36058894,636,25,SPARK_POS_OK,0.213940,0.259834,0.277300,0.279558,NORMAL,638,25,SPARK_POS_OK,0.283840,0.286869,0.209744,0.003928,NORMAL,1041,4226,0 +36126894,637,25,SPARK_POS_OK,0.213813,0.259711,0.277163,0.279440,NORMAL,639,25,SPARK_POS_OK,0.283694,0.286736,0.209639,0.003926,NORMAL,58,4181,0 +36194894,638,51,SPARK_POS_OK,0.213678,0.259607,0.277023,0.279305,NORMAL,640,24,SPARK_POS_OK,0.283580,0.286590,0.209524,0.003909,NORMAL,885,4185,0 +36261894,639,50,SPARK_POS_OK,0.213571,0.259478,0.276902,0.279151,NORMAL,641,51,SPARK_POS_OK,0.283444,0.286450,0.209401,0.003888,NORMAL,887,4159,0 +36329894,640,90,SPARK_POS_OK,0.213425,0.259354,0.276760,0.279043,NORMAL,642,87,SPARK_POS_OK,0.283290,0.286326,0.209283,0.003871,NORMAL,888,4260,0 +36396894,641,110,SPARK_POS_OK,0.213286,0.259249,0.276630,0.278909,NORMAL,643,90,SPARK_POS_OK,0.283167,0.286195,0.209165,0.003867,NORMAL,890,4243,0 +36463894,642,110,SPARK_POS_OK,0.213141,0.259161,0.276492,0.278755,NORMAL,644,110,SPARK_POS_OK,0.283051,0.286046,0.209054,0.003871,NORMAL,893,4162,0 +36530894,643,130,SPARK_POS_OK,0.213040,0.259021,0.276358,0.278633,NORMAL,645,131,SPARK_POS_OK,0.282916,0.285913,0.208927,0.003837,NORMAL,899,4263,0 +36596894,644,140,SPARK_POS_OK,0.212910,0.258908,0.276224,0.278480,NORMAL,646,130,SPARK_POS_OK,0.282785,0.285773,0.208818,0.003849,NORMAL,904,4212,0 +36662894,645,140,SPARK_POS_OK,0.212783,0.258812,0.276097,0.278357,NORMAL,647,140,SPARK_POS_OK,0.282663,0.285640,0.208700,0.003834,NORMAL,910,4189,0 +36727894,646,161,SPARK_POS_OK,0.212635,0.258691,0.275950,0.278206,NORMAL,648,160,SPARK_POS_OK,0.282534,0.285493,0.208591,0.003829,NORMAL,921,4158,0 +36792894,647,181,SPARK_POS_OK,0.212511,0.258538,0.275831,0.278075,NORMAL,649,160,SPARK_POS_OK,0.282395,0.285385,0.208468,0.003807,NORMAL,923,4164,0 +36857894,648,180,SPARK_POS_OK,0.212399,0.258464,0.275685,0.277957,NORMAL,650,181,SPARK_POS_OK,0.282272,0.285238,0.208339,0.003818,NORMAL,933,4162,0 +36921894,649,210,SPARK_POS_OK,0.212275,0.258311,0.275542,0.277777,NORMAL,651,180,SPARK_POS_OK,0.282136,0.285095,0.208236,0.003802,NORMAL,938,4234,0 +36984894,650,213,SPARK_POS_OK,0.212106,0.258200,0.275386,0.277677,NORMAL,652,210,SPARK_POS_OK,0.281998,0.284982,0.208116,0.003808,NORMAL,945,4213,0 +37047894,651,230,SPARK_POS_OK,0.212014,0.258107,0.275283,0.277527,NORMAL,653,230,SPARK_POS_OK,0.281868,0.284844,0.207992,0.003803,NORMAL,959,4228,0 +37108894,652,12,SPARK_NEG_OK,0.211840,0.257963,0.275127,0.277390,SOFT_START,654,230,SPARK_POS_OK,0.281720,0.284698,0.207887,0.003822,NORMAL,964,4278,0 +37169894,653,11,SPARK_NEG_OK,0.211723,0.257869,0.275005,0.277253,SOFT_START,655,11,SPARK_NEG_OK,0.281601,0.284568,0.207760,0.003831,SOFT_START,979,4191,0 +37230894,654,30,SPARK_NEG_OK,0.211592,0.257738,0.274858,0.277121,SOFT_START,656,11,SPARK_NEG_OK,0.281478,0.284427,0.207640,0.003812,SOFT_START,988,4244,0 +37290894,655,30,SPARK_NEG_OK,0.211459,0.257616,0.274735,0.276963,SOFT_START,657,31,SPARK_NEG_OK,0.281326,0.284291,0.207534,0.003821,SOFT_START,998,4178,0 +37349894,656,50,SPARK_NEG_OK,0.211344,0.257522,0.274568,0.276856,SOFT_START,658,50,SPARK_NEG_OK,0.281195,0.284154,0.207424,0.003799,SOFT_START,1016,4186,0 +37408894,657,50,SPARK_NEG_OK,0.211175,0.257400,0.274474,0.276735,SOFT_START,659,50,SPARK_NEG_OK,0.281072,0.284021,0.207309,0.003795,SOFT_START,1017,4264,0 +37466894,658,71,SPARK_NEG_OK,0.211040,0.257265,0.274315,0.276607,SOFT_START,660,70,SPARK_NEG_OK,0.280935,0.283883,0.207184,0.003827,SOFT_START,1034,4247,0 +37524894,659,91,SPARK_NEG_OK,0.210924,0.257138,0.274191,0.276452,SOFT_START,661,70,SPARK_NEG_OK,0.280807,0.283751,0.207044,0.003825,SOFT_START,1045,4277,0 +37580894,660,91,SPARK_NEG_OK,0.210773,0.257016,0.274035,0.276287,SOFT_START,662,90,SPARK_NEG_OK,0.280664,0.283605,0.206951,0.003846,SOFT_START,1056,4156,0 +37637894,661,110,SPARK_NEG_OK,0.210651,0.256919,0.273908,0.276170,SOFT_START,663,90,SPARK_NEG_OK,0.280513,0.283462,0.206825,0.003834,SOFT_START,1067,4200,0 +37692894,662,108,SPARK_NEG_OK,0.210524,0.256817,0.273778,0.276014,SOFT_START,664,110,SPARK_NEG_OK,0.280396,0.283341,0.206679,0.003850,SOFT_START,1080,4268,0 +37747894,663,140,SPARK_NEG_OK,0.210339,0.256675,0.273625,0.275890,SOFT_START,665,110,SPARK_NEG_OK,0.280262,0.283211,0.206587,0.003878,SOFT_START,1092,4246,0 +37801894,664,140,SPARK_NEG_OK,0.210227,0.256556,0.273506,0.275755,SOFT_START,666,141,SPARK_NEG_OK,0.280131,0.283070,0.206459,0.003862,SOFT_START,1106,4152,0 +37855894,665,160,SPARK_NEG_OK,0.210127,0.256458,0.273353,0.275602,SOFT_START,667,141,SPARK_NEG_OK,0.280004,0.282941,0.206351,0.003883,SOFT_START,1117,4169,0 +37908894,666,161,SPARK_NEG_OK,0.210000,0.256337,0.273227,0.275472,SOFT_START,668,160,SPARK_NEG_OK,0.279878,0.282794,0.206226,0.003880,SOFT_START,1130,4168,0 +37961894,667,200,SPARK_NEG_OK,0.209829,0.256199,0.273078,0.275325,SOFT_START,669,161,SPARK_NEG_OK,0.279713,0.282645,0.206130,0.003921,SOFT_START,1141,4248,0 +38013894,668,200,SPARK_NEG_OK,0.209727,0.256077,0.272948,0.275184,SOFT_START,670,200,SPARK_NEG_OK,0.279604,0.282503,0.205991,0.003906,SOFT_START,1155,4189,0 +38064894,669,220,SPARK_NEG_OK,0.209596,0.255956,0.272787,0.275062,SOFT_START,671,200,SPARK_NEG_OK,0.279452,0.282353,0.205868,0.003920,SOFT_START,1167,4239,0 +38115894,670,221,SPARK_NEG_OK,0.209432,0.255836,0.272673,0.274916,SOFT_START,672,220,SPARK_NEG_OK,0.279309,0.282218,0.205765,0.003961,SOFT_START,1182,4272,0 +38165894,671,220,SPARK_NEG_OK,0.209312,0.255718,0.272501,0.274780,SOFT_START,673,220,SPARK_NEG_OK,0.279174,0.282106,0.205613,0.003957,SOFT_START,1194,4180,0 +38214894,672,220,SPARK_NEG_OK,0.209182,0.255595,0.272353,0.274642,SOFT_START,674,221,SPARK_NEG_OK,0.279053,0.281949,0.205492,0.003965,SOFT_START,1210,4193,0 +38264894,673,220,SPARK_NEG_OK,0.209062,0.255480,0.272245,0.274504,SOFT_START,675,220,SPARK_NEG_OK,0.278916,0.281812,0.205392,0.003965,SOFT_START,1221,4153,0 +38312894,674,220,SPARK_NEG_OK,0.208949,0.255389,0.272102,0.274378,SOFT_START,676,221,SPARK_NEG_OK,0.278790,0.281681,0.205267,0.003991,SOFT_START,1236,4161,0 +38360894,675,220,SPARK_NEG_OK,0.208792,0.255247,0.271955,0.274234,SOFT_START,677,220,SPARK_NEG_OK,0.278662,0.281528,0.205157,0.003999,SOFT_START,1245,4251,0 +38408894,676,220,SPARK_NEG_OK,0.208645,0.255117,0.271837,0.274081,SOFT_START,678,221,SPARK_NEG_OK,0.278516,0.281422,0.205005,0.004001,SOFT_START,1257,4259,0 +38456894,677,223,SPARK_NEG_OK,0.208504,0.254996,0.271699,0.273960,SOFT_START,679,220,SPARK_NEG_OK,0.278376,0.281266,0.204897,0.004032,SOFT_START,1257,4214,0 +38503894,678,220,SPARK_NEG_OK,0.208384,0.254872,0.271536,0.273805,SOFT_START,680,221,SPARK_NEG_OK,0.278223,0.281140,0.204788,0.004033,SOFT_START,1274,4237,0 +38550894,679,220,SPARK_NEG_OK,0.208232,0.254766,0.271414,0.273679,SOFT_START,681,220,SPARK_NEG_OK,0.278096,0.281001,0.204660,0.004051,SOFT_START,1275,4257,0 +38596894,680,220,SPARK_NEG_OK,0.208101,0.254632,0.271282,0.273514,SOFT_START,682,221,SPARK_NEG_OK,0.277963,0.280815,0.204550,0.004060,SOFT_START,1291,4202,0 +38643894,681,221,SPARK_NEG_OK,0.207956,0.254499,0.271150,0.273395,SOFT_START,683,220,SPARK_NEG_OK,0.277845,0.280711,0.204415,0.004084,SOFT_START,1293,4195,0 +38689894,682,221,SPARK_NEG_OK,0.207830,0.254421,0.270997,0.273231,SOFT_START,684,223,SPARK_NEG_OK,0.277692,0.280572,0.204302,0.004092,SOFT_START,1309,4227,0 +38734894,683,220,SPARK_NEG_OK,0.207710,0.254275,0.270846,0.273100,SOFT_START,685,220,SPARK_NEG_OK,0.277570,0.280423,0.204185,0.004102,SOFT_START,1310,4175,0 +38780894,684,221,SPARK_NEG_OK,0.207548,0.254160,0.270709,0.272974,SOFT_START,686,217,SPARK_NEG_OK,0.277417,0.280293,0.204057,0.004109,SOFT_START,1317,4218,0 +38825894,685,220,SPARK_NEG_OK,0.207415,0.254024,0.270590,0.272829,SOFT_START,687,221,SPARK_NEG_OK,0.277311,0.280139,0.203938,0.004123,SOFT_START,1326,4193,0 +38870894,686,222,SPARK_NEG_OK,0.207291,0.253907,0.270428,0.272685,SOFT_START,688,220,SPARK_NEG_OK,0.277144,0.280020,0.203822,0.004132,SOFT_START,1326,4165,0 +38915894,687,221,SPARK_NEG_OK,0.207150,0.253793,0.270294,0.272558,SOFT_START,689,220,SPARK_NEG_OK,0.277017,0.279866,0.203716,0.004162,SOFT_START,1337,4224,0 +38960894,688,220,SPARK_NEG_OK,0.207025,0.253657,0.270154,0.272431,SOFT_START,690,220,SPARK_NEG_OK,0.276886,0.279739,0.203577,0.004151,SOFT_START,1338,4199,0 +39005894,689,220,SPARK_NEG_OK,0.206887,0.253541,0.270010,0.272270,SOFT_START,691,221,SPARK_NEG_OK,0.276770,0.279604,0.203462,0.004165,SOFT_START,1346,4177,0 +39049894,690,221,SPARK_NEG_OK,0.206779,0.253445,0.269864,0.272130,SOFT_START,692,221,SPARK_NEG_OK,0.276610,0.279459,0.203337,0.004172,SOFT_START,1348,4204,0 +39093894,691,220,SPARK_NEG_OK,0.206625,0.253299,0.269744,0.271980,SOFT_START,693,220,SPARK_NEG_OK,0.276486,0.279325,0.203225,0.004199,SOFT_START,1351,4219,0 +39138894,692,220,SPARK_NEG_OK,0.206511,0.253202,0.269613,0.271854,SOFT_START,694,220,SPARK_NEG_OK,0.276347,0.279167,0.203116,0.004188,SOFT_START,1358,4187,0 +39182894,693,221,SPARK_NEG_OK,0.206396,0.253100,0.269476,0.271717,SOFT_START,695,220,SPARK_NEG_OK,0.276213,0.279039,0.203003,0.004205,SOFT_START,1358,4154,0 +39226894,694,220,SPARK_NEG_OK,0.206258,0.252935,0.269325,0.271574,SOFT_START,696,220,SPARK_NEG_OK,0.276089,0.278912,0.202873,0.004227,SOFT_START,1364,4179,0 +39270894,695,220,SPARK_NEG_OK,0.206105,0.252839,0.269194,0.271446,SOFT_START,697,221,SPARK_NEG_OK,0.275929,0.278774,0.202767,0.004229,SOFT_START,1366,4254,0 +39314894,696,181,SPARK_NEG_OK,0.205987,0.252725,0.269056,0.271299,SOFT_START,698,180,SPARK_NEG_OK,0.275809,0.278629,0.202613,0.004247,SOFT_START,1365,4224,0 +39357894,697,180,SPARK_NEG_OK,0.205838,0.252599,0.268899,0.271145,SOFT_START,699,181,SPARK_NEG_OK,0.275657,0.278487,0.202522,0.004249,SOFT_START,1367,4206,0 +39401894,698,140,SPARK_NEG_OK,0.205708,0.252507,0.268775,0.271013,SOFT_START,700,180,SPARK_NEG_OK,0.275525,0.278352,0.202399,0.004258,SOFT_START,1363,4240,0 +39445894,699,140,SPARK_NEG_OK,0.205578,0.252335,0.268633,0.270877,SOFT_START,701,140,SPARK_NEG_OK,0.275407,0.278224,0.202285,0.004265,SOFT_START,1362,4214,0 +39489894,700,140,SPARK_NEG_OK,0.205450,0.252241,0.268512,0.270755,SOFT_START,702,141,SPARK_NEG_OK,0.275276,0.278093,0.202169,0.004291,SOFT_START,1362,4190,0 +39534894,701,100,SPARK_NEG_OK,0.205328,0.252104,0.268357,0.270594,SOFT_START,703,100,SPARK_NEG_OK,0.275124,0.277960,0.202031,0.004262,SOFT_START,1350,4195,0 +39578894,702,100,SPARK_NEG_OK,0.205196,0.252012,0.268247,0.270457,SOFT_START,704,102,SPARK_NEG_OK,0.275012,0.277813,0.201943,0.004296,SOFT_START,1351,4207,0 +39623894,703,70,SPARK_NEG_OK,0.205076,0.251896,0.268098,0.270344,SOFT_START,705,71,SPARK_NEG_OK,0.274871,0.277678,0.201812,0.004296,SOFT_START,1337,4182,0 +39668894,704,70,SPARK_NEG_OK,0.204934,0.251762,0.267957,0.270193,SOFT_START,706,70,SPARK_NEG_OK,0.274735,0.277537,0.201693,0.004286,SOFT_START,1339,4177,0 +39713894,705,41,SPARK_NEG_OK,0.204822,0.251641,0.267810,0.270061,SOFT_START,707,70,SPARK_NEG_OK,0.274608,0.277390,0.201574,0.004303,SOFT_START,1330,4167,0 +39758894,706,40,SPARK_NEG_OK,0.204682,0.251549,0.267684,0.269920,SOFT_START,708,41,SPARK_NEG_OK,0.274457,0.277274,0.201457,0.004306,SOFT_START,1324,4195,0 +39804894,707,40,SPARK_NEG_OK,0.204546,0.251395,0.267525,0.269762,SOFT_START,709,40,SPARK_NEG_OK,0.274332,0.277125,0.201312,0.004304,SOFT_START,1324,4223,0 +39943894,708,211,SPARK_POS_OK,0.204431,0.251308,0.267450,0.269685,NORMAL,710,210,SPARK_POS_OK,0.274249,0.277008,0.201241,0.004118,NORMAL,1290,4283,0 +39989894,709,210,SPARK_POS_OK,0.204310,0.251195,0.267299,0.269525,NORMAL,711,211,SPARK_POS_OK,0.274115,0.276889,0.201128,0.004120,NORMAL,1283,4204,0 +40037894,710,170,SPARK_POS_OK,0.204191,0.251074,0.267169,0.269407,NORMAL,712,210,SPARK_POS_OK,0.273974,0.276754,0.201014,0.004125,NORMAL,1269,4236,0 +40084894,711,170,SPARK_POS_OK,0.204046,0.250964,0.267050,0.269277,NORMAL,713,171,SPARK_POS_OK,0.273856,0.276611,0.200901,0.004141,NORMAL,1256,4229,0 +40133894,712,131,SPARK_POS_OK,0.203942,0.250819,0.266888,0.269134,NORMAL,714,170,SPARK_POS_OK,0.273709,0.276471,0.200775,0.004130,NORMAL,1242,4169,0 +40182894,713,130,SPARK_POS_OK,0.203801,0.250719,0.266763,0.268992,NORMAL,715,131,SPARK_POS_OK,0.273576,0.276337,0.200660,0.004146,NORMAL,1229,4168,0 +40231894,714,101,SPARK_POS_OK,0.203679,0.250602,0.266610,0.268854,NORMAL,716,130,SPARK_POS_OK,0.273449,0.276200,0.200556,0.004156,NORMAL,1214,4213,0 +40281894,715,100,SPARK_POS_OK,0.203544,0.250499,0.266479,0.268734,NORMAL,717,100,SPARK_POS_OK,0.273300,0.276085,0.200437,0.004150,NORMAL,1201,4153,0 +40332894,716,60,SPARK_POS_OK,0.203425,0.250357,0.266336,0.268586,NORMAL,718,101,SPARK_POS_OK,0.273175,0.275934,0.200318,0.004133,NORMAL,1187,4237,0 +40383894,717,61,SPARK_POS_OK,0.203306,0.250285,0.266254,0.268469,NORMAL,719,60,SPARK_POS_OK,0.273046,0.275812,0.200194,0.004146,NORMAL,1173,4155,0 +40435894,718,42,SPARK_POS_OK,0.203170,0.250174,0.266094,0.268306,NORMAL,720,60,SPARK_POS_OK,0.272930,0.275672,0.200098,0.004148,NORMAL,1156,4268,0 +40487894,719,40,SPARK_POS_OK,0.203015,0.250028,0.265937,0.268164,NORMAL,721,41,SPARK_POS_OK,0.272765,0.275537,0.199981,0.004146,NORMAL,1142,4276,0 +40540894,720,25,SPARK_POS_OK,0.202909,0.249906,0.265791,0.268040,NORMAL,722,40,SPARK_POS_OK,0.272655,0.275398,0.199848,0.004122,NORMAL,1125,4148,0 +40594894,721,25,SPARK_POS_OK,0.202784,0.249798,0.265670,0.267910,NORMAL,723,25,SPARK_POS_OK,0.272522,0.275282,0.199748,0.004113,NORMAL,1110,4255,0 +40649894,722,25,SPARK_POS_OK,0.202652,0.249678,0.265548,0.267772,NORMAL,724,25,SPARK_POS_OK,0.272388,0.275137,0.199640,0.004106,NORMAL,1110,4212,0 +40705894,723,25,SPARK_POS_OK,0.202504,0.249600,0.265426,0.267656,NORMAL,725,25,SPARK_POS_OK,0.272263,0.275016,0.199504,0.004092,NORMAL,1110,4270,0 +40761894,724,25,SPARK_POS_OK,0.202400,0.249467,0.265272,0.267516,NORMAL,726,25,SPARK_POS_OK,0.272152,0.274868,0.199398,0.004108,NORMAL,1110,4240,0 +40818894,725,25,SPARK_POS_OK,0.202259,0.249345,0.265149,0.267385,NORMAL,727,25,SPARK_POS_OK,0.272015,0.274736,0.199280,0.004070,NORMAL,1110,4227,0 +40876894,726,25,SPARK_POS_OK,0.202144,0.249227,0.265021,0.267236,NORMAL,728,25,SPARK_POS_OK,0.271885,0.274595,0.199181,0.004079,NORMAL,1110,4159,0 +40934894,727,25,SPARK_POS_OK,0.202006,0.249094,0.264886,0.267131,NORMAL,729,25,SPARK_POS_OK,0.271756,0.274480,0.199078,0.004046,NORMAL,1110,4272,0 +40994894,728,25,SPARK_POS_OK,0.201861,0.249012,0.264758,0.266984,NORMAL,730,25,SPARK_POS_OK,0.271606,0.274345,0.198958,0.004050,NORMAL,1110,4247,0 +41053894,729,25,SPARK_POS_OK,0.201721,0.248911,0.264663,0.266860,NORMAL,731,25,SPARK_POS_OK,0.271502,0.274233,0.198841,0.004031,NORMAL,1110,4273,0 +41114894,730,25,SPARK_POS_OK,0.201633,0.248787,0.264506,0.266732,NORMAL,732,25,SPARK_POS_OK,0.271386,0.274118,0.198747,0.004001,NORMAL,1110,4169,0 +41176894,731,25,SPARK_POS_OK,0.201508,0.248668,0.264362,0.266598,NORMAL,733,25,SPARK_POS_OK,0.271242,0.273969,0.198644,0.004007,NORMAL,1110,4191,0 +41238894,732,25,SPARK_POS_OK,0.201376,0.248557,0.264245,0.266468,NORMAL,734,25,SPARK_POS_OK,0.271113,0.273847,0.198520,0.003988,NORMAL,1110,4256,0 +41301894,733,30,SPARK_POS_OK,0.201266,0.248428,0.264118,0.266318,NORMAL,735,30,SPARK_POS_OK,0.271019,0.273695,0.198419,0.003971,NORMAL,84,4205,0 +41363894,734,30,SPARK_POS_OK,0.201120,0.248331,0.263957,0.266209,NORMAL,736,30,SPARK_POS_OK,0.270879,0.273562,0.198269,0.003963,NORMAL,957,4204,0 +41426894,735,70,SPARK_POS_OK,0.201012,0.248233,0.263847,0.266065,NORMAL,737,71,SPARK_POS_OK,0.270754,0.273460,0.198188,0.003932,NORMAL,952,4159,0 +41489894,736,121,SPARK_POS_OK,0.200889,0.248101,0.263735,0.265954,NORMAL,738,70,SPARK_POS_OK,0.270635,0.273333,0.198066,0.003924,NORMAL,951,4218,0 +41552894,737,120,SPARK_POS_OK,0.200770,0.248005,0.263599,0.265783,NORMAL,739,120,SPARK_POS_OK,0.270470,0.273159,0.197971,0.003912,NORMAL,952,4164,0 +41615894,738,160,SPARK_POS_OK,0.200683,0.247887,0.263482,0.265682,NORMAL,740,161,SPARK_POS_OK,0.270364,0.273066,0.197852,0.003889,NORMAL,954,4165,0 +41678894,739,161,SPARK_POS_OK,0.200534,0.247756,0.263340,0.265562,NORMAL,741,160,SPARK_POS_OK,0.270231,0.272928,0.197769,0.003905,NORMAL,956,4218,0 +41740894,740,190,SPARK_POS_OK,0.200435,0.247624,0.263224,0.265428,NORMAL,742,190,SPARK_POS_OK,0.270122,0.272796,0.197648,0.003864,NORMAL,964,4154,0 +41802894,741,220,SPARK_POS_OK,0.200307,0.247547,0.263053,0.265304,NORMAL,743,190,SPARK_POS_OK,0.269973,0.272658,0.197528,0.003868,NORMAL,970,4253,0 +41863894,742,220,SPARK_POS_OK,0.200197,0.247444,0.262943,0.265173,NORMAL,744,221,SPARK_POS_OK,0.269864,0.272553,0.197408,0.003874,NORMAL,979,4164,0 +42043894,743,30,SPARK_NEG_OK,0.200107,0.247387,0.262863,0.265078,SOFT_START,745,30,SPARK_NEG_OK,0.269786,0.272447,0.197350,0.003678,SOFT_START,1009,4247,0 +42102894,744,60,SPARK_NEG_OK,0.199975,0.247245,0.262704,0.264937,SOFT_START,746,30,SPARK_NEG_OK,0.269638,0.272316,0.197238,0.003660,SOFT_START,1017,4203,0 +42160894,745,60,SPARK_NEG_OK,0.199851,0.247157,0.262578,0.264801,SOFT_START,747,61,SPARK_NEG_OK,0.269511,0.272185,0.197123,0.003695,SOFT_START,1027,4196,0 +42218894,746,90,SPARK_NEG_OK,0.199724,0.246996,0.262470,0.264683,SOFT_START,748,61,SPARK_NEG_OK,0.269379,0.272081,0.197006,0.003712,SOFT_START,1036,4165,0 +42275894,747,90,SPARK_NEG_OK,0.199598,0.246891,0.262341,0.264522,SOFT_START,749,91,SPARK_NEG_OK,0.269270,0.271949,0.196900,0.003718,SOFT_START,1048,4271,0 +42332894,748,110,SPARK_NEG_OK,0.199476,0.246797,0.262198,0.264432,SOFT_START,750,107,SPARK_NEG_OK,0.269136,0.271783,0.196793,0.003707,SOFT_START,1060,4178,0 +42388894,749,110,SPARK_NEG_OK,0.199374,0.246669,0.262067,0.264315,SOFT_START,751,111,SPARK_NEG_OK,0.269028,0.271673,0.196687,0.003733,SOFT_START,1073,4157,0 +42442894,750,140,SPARK_NEG_OK,0.199243,0.246548,0.261946,0.264188,SOFT_START,752,140,SPARK_NEG_OK,0.268887,0.271544,0.196567,0.003757,SOFT_START,1098,4178,0 +42497894,751,141,SPARK_NEG_OK,0.199089,0.246437,0.261806,0.264030,SOFT_START,753,140,SPARK_NEG_OK,0.268753,0.271395,0.196472,0.003762,SOFT_START,1099,4277,0 +42550894,752,171,SPARK_NEG_OK,0.198994,0.246323,0.261676,0.263922,SOFT_START,754,170,SPARK_NEG_OK,0.268612,0.271274,0.196361,0.003766,SOFT_START,1123,4183,0 +42604894,753,170,SPARK_NEG_OK,0.198861,0.246233,0.261565,0.263759,SOFT_START,755,170,SPARK_NEG_OK,0.268504,0.271167,0.196233,0.003782,SOFT_START,1124,4170,0 +42656894,754,210,SPARK_NEG_OK,0.198743,0.246103,0.261415,0.263638,SOFT_START,756,211,SPARK_NEG_OK,0.268367,0.271031,0.196128,0.003785,SOFT_START,1148,4160,0 +42708894,755,210,SPARK_NEG_OK,0.198614,0.245963,0.261278,0.263526,SOFT_START,757,210,SPARK_NEG_OK,0.268233,0.270876,0.196034,0.003813,SOFT_START,1149,4240,0 +42759894,756,220,SPARK_NEG_OK,0.198482,0.245838,0.261155,0.263387,SOFT_START,758,220,SPARK_NEG_OK,0.268111,0.270748,0.195891,0.003822,SOFT_START,1175,4260,0 +42810894,757,220,SPARK_NEG_OK,0.198360,0.245746,0.261000,0.263236,SOFT_START,759,220,SPARK_NEG_OK,0.267989,0.270618,0.195792,0.003821,SOFT_START,1176,4207,0 +42860894,758,220,SPARK_NEG_OK,0.198218,0.245627,0.260875,0.263098,SOFT_START,760,223,SPARK_NEG_OK,0.267848,0.270478,0.195671,0.003844,SOFT_START,1204,4237,0 +42910894,759,220,SPARK_NEG_OK,0.198099,0.245525,0.260764,0.262961,SOFT_START,761,220,SPARK_NEG_OK,0.267730,0.270354,0.195575,0.003870,SOFT_START,1205,4184,0 +42959894,760,220,SPARK_NEG_OK,0.197989,0.245395,0.260627,0.262851,SOFT_START,762,221,SPARK_NEG_OK,0.267601,0.270222,0.195455,0.003886,SOFT_START,1229,4168,0 +43007894,761,221,SPARK_NEG_OK,0.197859,0.245275,0.260477,0.262731,SOFT_START,763,220,SPARK_NEG_OK,0.267437,0.270085,0.195344,0.003896,SOFT_START,1230,4202,0 +43056894,762,220,SPARK_NEG_OK,0.197738,0.245203,0.260365,0.262597,SOFT_START,764,221,SPARK_NEG_OK,0.267359,0.269965,0.195224,0.003885,SOFT_START,1239,4196,0 +43104894,763,221,SPARK_NEG_OK,0.197602,0.245073,0.260230,0.262448,SOFT_START,765,220,SPARK_NEG_OK,0.267217,0.269827,0.195113,0.003901,SOFT_START,1251,4250,0 +43151894,764,220,SPARK_NEG_OK,0.197474,0.244928,0.260065,0.262322,SOFT_START,766,220,SPARK_NEG_OK,0.267094,0.269674,0.194982,0.003909,SOFT_START,1258,4184,0 +43199894,765,221,SPARK_NEG_OK,0.197357,0.244827,0.259967,0.262184,SOFT_START,767,220,SPARK_NEG_OK,0.266970,0.269556,0.194883,0.003923,SOFT_START,1268,4231,0 +43246894,766,220,SPARK_NEG_OK,0.197248,0.244722,0.259804,0.262077,SOFT_START,768,220,SPARK_NEG_OK,0.266804,0.269414,0.194749,0.003939,SOFT_START,1276,4149,0 +43292894,767,220,SPARK_NEG_OK,0.197117,0.244605,0.259694,0.261919,SOFT_START,769,220,SPARK_NEG_OK,0.266705,0.269303,0.194654,0.003959,SOFT_START,1286,4169,0 +43339894,768,220,SPARK_NEG_OK,0.196993,0.244474,0.259559,0.261797,SOFT_START,770,221,SPARK_NEG_OK,0.266541,0.269161,0.194563,0.003976,SOFT_START,1286,4190,0 +43385894,769,220,SPARK_NEG_OK,0.196869,0.244370,0.259448,0.261645,SOFT_START,771,220,SPARK_NEG_OK,0.266452,0.269037,0.194426,0.003982,SOFT_START,1302,4269,0 +43431894,770,221,SPARK_NEG_OK,0.196736,0.244229,0.259302,0.261519,SOFT_START,772,221,SPARK_NEG_OK,0.266292,0.268895,0.194313,0.003998,SOFT_START,1304,4262,0 +43477894,771,220,SPARK_NEG_OK,0.196609,0.244130,0.259157,0.261397,SOFT_START,773,220,SPARK_NEG_OK,0.266187,0.268759,0.194212,0.003994,SOFT_START,1317,4193,0 +43522894,772,221,SPARK_NEG_OK,0.196499,0.244040,0.259016,0.261270,SOFT_START,774,220,SPARK_NEG_OK,0.266053,0.268638,0.194097,0.004019,SOFT_START,1319,4175,0 +43567894,773,220,SPARK_NEG_OK,0.196381,0.243890,0.258903,0.261110,SOFT_START,775,221,SPARK_NEG_OK,0.265919,0.268518,0.193987,0.004036,SOFT_START,1323,4172,0 +43612894,774,220,SPARK_NEG_OK,0.196264,0.243790,0.258788,0.260985,SOFT_START,776,220,SPARK_NEG_OK,0.265797,0.268373,0.193867,0.004045,SOFT_START,1330,4153,0 +43658894,775,220,SPARK_NEG_OK,0.196141,0.243672,0.258629,0.260858,SOFT_START,777,220,SPARK_NEG_OK,0.265661,0.268230,0.193754,0.004045,SOFT_START,1332,4201,0 +43702894,776,220,SPARK_NEG_OK,0.196037,0.243563,0.258504,0.260714,SOFT_START,778,220,SPARK_NEG_OK,0.265544,0.268102,0.193647,0.004055,SOFT_START,1338,4158,0 +43747894,777,220,SPARK_NEG_OK,0.195891,0.243415,0.258385,0.260592,SOFT_START,779,220,SPARK_NEG_OK,0.265426,0.268000,0.193529,0.004078,SOFT_START,1338,4246,0 +43792894,778,201,SPARK_NEG_OK,0.195798,0.243320,0.258229,0.260479,SOFT_START,780,201,SPARK_NEG_OK,0.265290,0.267842,0.193396,0.004094,SOFT_START,1340,4156,0 +43837894,779,200,SPARK_NEG_OK,0.195658,0.243208,0.258101,0.260347,SOFT_START,781,200,SPARK_NEG_OK,0.265152,0.267714,0.193290,0.004086,SOFT_START,1341,4225,0 +43881894,780,160,SPARK_NEG_OK,0.195522,0.243081,0.257956,0.260199,SOFT_START,782,200,SPARK_NEG_OK,0.265024,0.267597,0.193209,0.004101,SOFT_START,1340,4182,0 +43926894,781,161,SPARK_NEG_OK,0.195416,0.242981,0.257821,0.260077,SOFT_START,783,161,SPARK_NEG_OK,0.264905,0.267470,0.193109,0.004116,SOFT_START,1342,4163,0 +43971894,782,130,SPARK_NEG_OK,0.195294,0.242833,0.257735,0.259920,SOFT_START,784,158,SPARK_NEG_OK,0.264760,0.267307,0.192973,0.004118,SOFT_START,1339,4208,0 +44016894,783,130,SPARK_NEG_OK,0.195179,0.242740,0.257558,0.259807,SOFT_START,785,130,SPARK_NEG_OK,0.264655,0.267206,0.192842,0.004129,SOFT_START,1339,4221,0 +44060894,784,128,SPARK_NEG_OK,0.195053,0.242636,0.257455,0.259690,SOFT_START,786,131,SPARK_NEG_OK,0.264505,0.267072,0.192737,0.004144,SOFT_START,1339,4236,0 +44106894,785,100,SPARK_NEG_OK,0.194902,0.242509,0.257328,0.259535,SOFT_START,787,100,SPARK_NEG_OK,0.264392,0.266936,0.192629,0.004129,SOFT_START,1329,4203,0 +44151894,786,101,SPARK_NEG_OK,0.194796,0.242376,0.257199,0.259408,SOFT_START,788,100,SPARK_NEG_OK,0.264261,0.266806,0.192531,0.004149,SOFT_START,1330,4178,0 +44196894,787,80,SPARK_NEG_OK,0.194678,0.242286,0.257065,0.259286,SOFT_START,789,101,SPARK_NEG_OK,0.264124,0.266667,0.192397,0.004155,SOFT_START,1322,4176,0 +44242894,788,80,SPARK_NEG_OK,0.194545,0.242181,0.256949,0.259129,SOFT_START,790,80,SPARK_NEG_OK,0.264000,0.266525,0.192301,0.004146,SOFT_START,1318,4255,0 +44287894,789,61,SPARK_NEG_OK,0.194429,0.242080,0.256811,0.259014,SOFT_START,791,81,SPARK_NEG_OK,0.263849,0.266387,0.192185,0.004156,SOFT_START,1309,4187,0 +44333894,790,60,SPARK_NEG_OK,0.194306,0.241948,0.256664,0.258874,SOFT_START,792,60,SPARK_NEG_OK,0.263768,0.266272,0.192068,0.004176,SOFT_START,1304,4182,0 +44379894,791,61,SPARK_NEG_OK,0.194189,0.241806,0.256536,0.258739,SOFT_START,793,60,SPARK_NEG_OK,0.263627,0.266151,0.191975,0.004157,SOFT_START,1304,4175,0 +44426894,792,50,SPARK_NEG_OK,0.194061,0.241702,0.256386,0.258610,SOFT_START,794,50,SPARK_NEG_OK,0.263498,0.266024,0.191851,0.004165,SOFT_START,1291,4264,0 +44472894,793,50,SPARK_NEG_OK,0.193927,0.241601,0.256268,0.258484,SOFT_START,795,50,SPARK_NEG_OK,0.263357,0.265887,0.191762,0.004178,SOFT_START,1293,4257,0 +44519894,794,50,SPARK_NEG_OK,0.193799,0.241491,0.256147,0.258339,SOFT_START,796,51,SPARK_NEG_OK,0.263250,0.265761,0.191653,0.004188,SOFT_START,1281,4241,0 +44566894,795,49,SPARK_NEG_OK,0.193665,0.241373,0.256011,0.258195,SOFT_START,797,50,SPARK_NEG_OK,0.263091,0.265631,0.191526,0.004173,SOFT_START,1283,4276,0 +44613894,796,50,SPARK_NEG_OK,0.193540,0.241243,0.255875,0.258098,SOFT_START,798,51,SPARK_NEG_OK,0.263007,0.265497,0.191412,0.004163,SOFT_START,1276,4193,0 +44660894,797,50,SPARK_NEG_OK,0.193436,0.241147,0.255746,0.257978,SOFT_START,799,50,SPARK_NEG_OK,0.262855,0.265361,0.191306,0.004170,SOFT_START,1272,4229,0 +44707894,798,50,SPARK_NEG_OK,0.193288,0.241022,0.255612,0.257819,SOFT_START,800,51,SPARK_NEG_OK,0.262737,0.265232,0.191194,0.004177,SOFT_START,1265,4268,0 +44755894,799,50,SPARK_NEG_OK,0.193172,0.240936,0.255510,0.257689,SOFT_START,801,50,SPARK_NEG_OK,0.262594,0.265086,0.191092,0.004173,SOFT_START,1260,4149,0 +44803894,800,50,SPARK_NEG_OK,0.193061,0.240822,0.255350,0.257562,SOFT_START,802,51,SPARK_NEG_OK,0.262484,0.264987,0.190976,0.004181,SOFT_START,1255,4228,0 +44851894,801,50,SPARK_NEG_OK,0.192931,0.240676,0.255222,0.257454,SOFT_START,803,50,SPARK_NEG_OK,0.262373,0.264848,0.190865,0.004160,SOFT_START,1253,4212,0 +44898894,802,50,SPARK_NEG_OK,0.192834,0.240576,0.255093,0.257311,SOFT_START,804,51,SPARK_NEG_OK,0.262241,0.264716,0.190771,0.004186,SOFT_START,1253,4191,0 +44947894,803,50,SPARK_NEG_OK,0.192724,0.240459,0.254962,0.257189,SOFT_START,805,50,SPARK_NEG_OK,0.262112,0.264597,0.190664,0.004171,SOFT_START,1245,4150,0 +44995894,804,50,SPARK_NEG_OK,0.192583,0.240365,0.254850,0.257064,SOFT_START,806,51,SPARK_NEG_OK,0.261984,0.264466,0.190551,0.004168,SOFT_START,1246,4155,0 +45043894,805,50,SPARK_NEG_OK,0.192483,0.240215,0.254744,0.256926,SOFT_START,807,50,SPARK_NEG_OK,0.261874,0.264334,0.190439,0.004156,SOFT_START,1240,4178,0 +45091894,806,48,SPARK_NEG_OK,0.192343,0.240144,0.254613,0.256810,SOFT_START,808,51,SPARK_NEG_OK,0.261713,0.264204,0.190327,0.004158,SOFT_START,1241,4253,0 +45140894,807,50,SPARK_NEG_OK,0.192224,0.240026,0.254460,0.256689,SOFT_START,809,50,SPARK_NEG_OK,0.261614,0.264077,0.190225,0.004165,SOFT_START,1232,4243,0 +45189894,808,50,SPARK_NEG_OK,0.192109,0.239901,0.254341,0.256534,SOFT_START,810,50,SPARK_NEG_OK,0.261489,0.263938,0.190108,0.004143,SOFT_START,1234,4284,0 +45238894,809,51,SPARK_NEG_OK,0.191958,0.239796,0.254230,0.256408,SOFT_START,811,50,SPARK_NEG_OK,0.261356,0.263807,0.190001,0.004138,SOFT_START,1229,4268,0 +45286894,810,47,SPARK_NEG_OK,0.191852,0.239690,0.254098,0.256292,SOFT_START,812,50,SPARK_NEG_OK,0.261207,0.263699,0.189890,0.004146,SOFT_START,1226,4162,0 +45335894,811,51,SPARK_NEG_OK,0.191737,0.239571,0.253947,0.256172,SOFT_START,813,50,SPARK_NEG_OK,0.261111,0.263574,0.189781,0.004153,SOFT_START,1223,4172,0 +45385894,812,50,SPARK_NEG_OK,0.191611,0.239471,0.253817,0.256026,SOFT_START,814,50,SPARK_NEG_OK,0.260968,0.263440,0.189676,0.004123,SOFT_START,1221,4266,0 +45434894,813,47,SPARK_NEG_OK,0.191482,0.239350,0.253700,0.255923,SOFT_START,815,51,SPARK_NEG_OK,0.260872,0.263320,0.189580,0.004151,SOFT_START,1219,4251,0 +45483894,814,50,SPARK_NEG_OK,0.191370,0.239239,0.253552,0.255758,SOFT_START,816,50,SPARK_NEG_OK,0.260741,0.263183,0.189472,0.004148,SOFT_START,1219,4223,0 +45532894,815,50,SPARK_NEG_OK,0.191237,0.239108,0.253436,0.255647,SOFT_START,817,50,SPARK_NEG_OK,0.260611,0.263052,0.189347,0.004121,SOFT_START,1216,4231,0 +45582894,816,51,SPARK_NEG_OK,0.191110,0.239028,0.253310,0.255525,SOFT_START,818,50,SPARK_NEG_OK,0.260473,0.262930,0.189257,0.004116,SOFT_START,1216,4237,0 +45631894,817,49,SPARK_NEG_OK,0.190997,0.238910,0.253175,0.255381,SOFT_START,819,50,SPARK_NEG_OK,0.260382,0.262802,0.189146,0.004120,SOFT_START,1216,4244,0 +45680894,818,50,SPARK_NEG_OK,0.190886,0.238796,0.253065,0.255262,SOFT_START,820,51,SPARK_NEG_OK,0.260221,0.262699,0.189050,0.004132,SOFT_START,1210,4155,0 +45730894,819,50,SPARK_NEG_OK,0.190738,0.238699,0.252901,0.255105,SOFT_START,821,50,SPARK_NEG_OK,0.260109,0.262575,0.188913,0.004126,SOFT_START,1212,4249,0 +45780894,820,50,SPARK_NEG_OK,0.190637,0.238562,0.252810,0.255017,SOFT_START,822,50,SPARK_NEG_OK,0.259993,0.262415,0.188825,0.004118,SOFT_START,1205,4206,0 +45830894,821,51,SPARK_NEG_OK,0.190503,0.238465,0.252685,0.254884,SOFT_START,823,50,SPARK_NEG_OK,0.259852,0.262313,0.188717,0.004117,SOFT_START,1206,4219,0 +45879894,822,48,SPARK_NEG_OK,0.190406,0.238347,0.252525,0.254745,SOFT_START,824,50,SPARK_NEG_OK,0.259729,0.262196,0.188599,0.004111,SOFT_START,1202,4164,0 +45929894,823,50,SPARK_NEG_OK,0.190293,0.238234,0.252434,0.254620,SOFT_START,825,51,SPARK_NEG_OK,0.259622,0.262054,0.188497,0.004097,SOFT_START,1203,4164,0 +45979894,824,41,SPARK_NEG_OK,0.190171,0.238089,0.252297,0.254486,SOFT_START,826,40,SPARK_NEG_OK,0.259511,0.261909,0.188398,0.004105,SOFT_START,1201,4237,0 +46029894,825,40,SPARK_NEG_OK,0.190046,0.237992,0.252163,0.254358,SOFT_START,827,40,SPARK_NEG_OK,0.259376,0.261799,0.188283,0.004096,SOFT_START,1202,4219,0 +46079894,826,30,SPARK_NEG_OK,0.189935,0.237876,0.252033,0.254241,SOFT_START,828,30,SPARK_NEG_OK,0.259261,0.261660,0.188177,0.004101,SOFT_START,1199,4192,0 +46129894,827,30,SPARK_NEG_OK,0.189816,0.237765,0.251942,0.254119,SOFT_START,829,30,SPARK_NEG_OK,0.259131,0.261537,0.188060,0.004087,SOFT_START,1200,4206,0 +46179894,828,15,SPARK_NEG_OK,0.189692,0.237678,0.251780,0.253997,SOFT_START,830,12,SPARK_NEG_OK,0.259007,0.261403,0.187978,0.004088,SOFT_START,1192,4174,0 +46230894,829,12,SPARK_NEG_OK,0.189592,0.237572,0.251632,0.253850,SOFT_START,831,11,SPARK_NEG_OK,0.258870,0.261305,0.187864,0.004097,SOFT_START,1193,4175,0 +46281894,830,240,SPARK_POS_OK,0.189475,0.237434,0.251530,0.253745,NORMAL,832,11,SPARK_NEG_OK,0.258766,0.261147,0.187738,0.004087,SOFT_START,1194,4225,0 +46331894,831,240,SPARK_POS_OK,0.189345,0.237330,0.251409,0.253618,NORMAL,833,241,SPARK_POS_OK,0.258665,0.261039,0.187638,0.004082,NORMAL,1184,4245,0 +46382894,832,231,SPARK_POS_OK,0.189261,0.237217,0.251272,0.253481,NORMAL,834,240,SPARK_POS_OK,0.258522,0.260929,0.187556,0.004079,NORMAL,1179,4168,0 +46433894,833,230,SPARK_POS_OK,0.189138,0.237136,0.251175,0.253382,NORMAL,835,230,SPARK_POS_OK,0.258383,0.260813,0.187426,0.004068,NORMAL,1176,4228,0 +46484894,834,220,SPARK_POS_OK,0.189012,0.237026,0.251043,0.253245,NORMAL,836,231,SPARK_POS_OK,0.258259,0.260691,0.187322,0.004076,NORMAL,1171,4212,0 +46536894,835,223,SPARK_POS_OK,0.188912,0.236922,0.250911,0.253098,NORMAL,837,220,SPARK_POS_OK,0.258138,0.260543,0.187244,0.004051,NORMAL,1169,4213,0 +46587894,836,200,SPARK_POS_OK,0.188764,0.236806,0.250795,0.253014,NORMAL,838,220,SPARK_POS_OK,0.258026,0.260438,0.187150,0.004058,NORMAL,1164,4272,0 +46639894,837,200,SPARK_POS_OK,0.188665,0.236703,0.250667,0.252843,NORMAL,839,201,SPARK_POS_OK,0.257918,0.260280,0.187024,0.004051,NORMAL,1161,4206,0 +46691894,838,190,SPARK_POS_OK,0.188524,0.236609,0.250556,0.252748,NORMAL,840,200,SPARK_POS_OK,0.257770,0.260161,0.186925,0.004048,NORMAL,1154,4239,0 +46743894,839,191,SPARK_POS_OK,0.188426,0.236479,0.250418,0.252605,NORMAL,841,190,SPARK_POS_OK,0.257676,0.260048,0.186810,0.004051,NORMAL,1150,4206,0 +46796894,840,180,SPARK_POS_OK,0.188310,0.236364,0.250295,0.252498,NORMAL,842,190,SPARK_POS_OK,0.257535,0.259948,0.186688,0.004035,NORMAL,1143,4232,0 +46848894,841,180,SPARK_POS_OK,0.188194,0.236236,0.250141,0.252351,NORMAL,843,181,SPARK_POS_OK,0.257429,0.259789,0.186617,0.004027,NORMAL,1137,4153,0 +46901894,842,170,SPARK_POS_OK,0.188091,0.236159,0.250050,0.252227,NORMAL,844,180,SPARK_POS_OK,0.257328,0.259672,0.186503,0.004034,NORMAL,1131,4183,0 +46955894,843,171,SPARK_POS_OK,0.187982,0.236027,0.249890,0.252114,NORMAL,845,170,SPARK_POS_OK,0.257170,0.259569,0.186400,0.004032,NORMAL,1127,4160,0 +47008894,844,161,SPARK_POS_OK,0.187868,0.235941,0.249802,0.251991,NORMAL,846,170,SPARK_POS_OK,0.257060,0.259432,0.186309,0.004019,NORMAL,1122,4280,0 +47062894,845,160,SPARK_POS_OK,0.187767,0.235842,0.249661,0.251852,NORMAL,847,160,SPARK_POS_OK,0.256953,0.259300,0.186182,0.004006,NORMAL,1118,4252,0 +47116894,846,160,SPARK_POS_OK,0.187617,0.235729,0.249538,0.251734,NORMAL,848,161,SPARK_POS_OK,0.256835,0.259192,0.186073,0.003994,NORMAL,1113,4244,0 +47170894,847,160,SPARK_POS_OK,0.187524,0.235621,0.249420,0.251602,NORMAL,849,161,SPARK_POS_OK,0.256718,0.259048,0.185969,0.003990,NORMAL,1110,4216,0 +47224894,848,150,SPARK_POS_OK,0.187391,0.235505,0.249296,0.251517,NORMAL,850,150,SPARK_POS_OK,0.256594,0.258952,0.185884,0.003981,NORMAL,1098,4245,0 +47279894,849,151,SPARK_POS_OK,0.187286,0.235388,0.249176,0.251381,NORMAL,851,150,SPARK_POS_OK,0.256472,0.258817,0.185773,0.003980,NORMAL,1099,4192,0 +47334894,850,141,SPARK_POS_OK,0.187168,0.235281,0.249062,0.251256,NORMAL,852,140,SPARK_POS_OK,0.256345,0.258703,0.185671,0.003981,NORMAL,1085,4248,0 +47389894,851,141,SPARK_POS_OK,0.187046,0.235177,0.248922,0.251114,NORMAL,853,140,SPARK_POS_OK,0.256229,0.258580,0.185577,0.003989,NORMAL,1086,4221,0 +47445894,852,134,SPARK_POS_OK,0.186926,0.235064,0.248811,0.251015,NORMAL,854,130,SPARK_POS_OK,0.256121,0.258464,0.185478,0.003960,NORMAL,1074,4230,0 +47501894,853,130,SPARK_POS_OK,0.186813,0.234978,0.248675,0.250870,NORMAL,855,130,SPARK_POS_OK,0.256003,0.258320,0.185378,0.003954,NORMAL,1075,4157,0 +47557894,854,121,SPARK_POS_OK,0.186700,0.234830,0.248588,0.250720,NORMAL,856,120,SPARK_POS_OK,0.255868,0.258222,0.185274,0.003951,NORMAL,1066,4280,0 +47614894,855,130,SPARK_POS_OK,0.186595,0.234727,0.248448,0.250642,NORMAL,857,121,SPARK_POS_OK,0.255758,0.258101,0.185173,0.003955,NORMAL,1062,4222,0 +47670894,856,130,SPARK_POS_OK,0.186488,0.234631,0.248330,0.250527,NORMAL,858,131,SPARK_POS_OK,0.255622,0.257991,0.185075,0.003922,NORMAL,1060,4166,0 +47727894,857,140,SPARK_POS_OK,0.186380,0.234529,0.248209,0.250412,NORMAL,859,131,SPARK_POS_OK,0.255518,0.257864,0.184941,0.003935,NORMAL,1056,4162,0 +47784894,858,140,SPARK_POS_OK,0.186290,0.234465,0.248080,0.250263,NORMAL,860,141,SPARK_POS_OK,0.255391,0.257729,0.184861,0.003924,NORMAL,1054,4169,0 +47841894,859,150,SPARK_POS_OK,0.186153,0.234302,0.247976,0.250136,NORMAL,861,141,SPARK_POS_OK,0.255267,0.257604,0.184757,0.003910,NORMAL,1049,4231,0 +47898894,860,149,SPARK_POS_OK,0.186059,0.234220,0.247833,0.250043,NORMAL,862,151,SPARK_POS_OK,0.255178,0.257509,0.184662,0.003907,NORMAL,1048,4183,0 +47956894,861,160,SPARK_POS_OK,0.185944,0.234099,0.247707,0.249916,NORMAL,863,161,SPARK_POS_OK,0.255066,0.257356,0.184550,0.003906,NORMAL,1044,4192,0 +48013894,862,160,SPARK_POS_OK,0.185822,0.234005,0.247573,0.249782,NORMAL,864,161,SPARK_POS_OK,0.254922,0.257250,0.184442,0.003871,NORMAL,1045,4252,0 +48071894,863,170,SPARK_POS_OK,0.185719,0.233893,0.247480,0.249677,NORMAL,865,171,SPARK_POS_OK,0.254796,0.257124,0.184361,0.003891,NORMAL,1043,4242,0 +48128894,864,172,SPARK_POS_OK,0.185601,0.233812,0.247360,0.249524,NORMAL,866,171,SPARK_POS_OK,0.254678,0.256999,0.184269,0.003884,NORMAL,1044,4230,0 +48185894,865,170,SPARK_POS_OK,0.185485,0.233693,0.247217,0.249421,NORMAL,867,170,SPARK_POS_OK,0.254599,0.256876,0.184159,0.003896,NORMAL,1044,4177,0 +48243894,866,170,SPARK_POS_OK,0.185353,0.233577,0.247125,0.249268,NORMAL,868,170,SPARK_POS_OK,0.254457,0.256770,0.184052,0.003859,NORMAL,1043,4280,0 +48301894,867,170,SPARK_POS_OK,0.185239,0.233474,0.246968,0.249196,NORMAL,869,170,SPARK_POS_OK,0.254325,0.256634,0.183977,0.003852,NORMAL,1043,4241,0 +48358894,868,170,SPARK_POS_OK,0.185137,0.233374,0.246859,0.249055,NORMAL,870,170,SPARK_POS_OK,0.254217,0.256510,0.183860,0.003856,NORMAL,1040,4192,0 +48416894,869,170,SPARK_POS_OK,0.185001,0.233275,0.246729,0.248941,NORMAL,871,170,SPARK_POS_OK,0.254110,0.256423,0.183764,0.003861,NORMAL,1040,4238,0 +48474894,870,170,SPARK_POS_OK,0.184931,0.233169,0.246617,0.248785,NORMAL,872,170,SPARK_POS_OK,0.253994,0.256265,0.183647,0.003806,NORMAL,1038,4174,0 +48531894,871,170,SPARK_POS_OK,0.184818,0.233034,0.246516,0.248690,NORMAL,873,170,SPARK_POS_OK,0.253859,0.256159,0.183561,0.003828,NORMAL,1039,4160,0 +48589894,872,171,SPARK_POS_OK,0.184712,0.232958,0.246370,0.248585,NORMAL,874,170,SPARK_POS_OK,0.253778,0.256029,0.183455,0.003825,NORMAL,1039,4176,0 +48647894,873,170,SPARK_POS_OK,0.184594,0.232822,0.246262,0.248438,NORMAL,875,170,SPARK_POS_OK,0.253631,0.255929,0.183359,0.003824,NORMAL,1040,4242,0 +48704894,874,171,SPARK_POS_OK,0.184495,0.232725,0.246117,0.248336,NORMAL,876,170,SPARK_POS_OK,0.253508,0.255806,0.183246,0.003831,NORMAL,1040,4185,0 +48762894,875,182,SPARK_POS_OK,0.184386,0.232642,0.246041,0.248201,NORMAL,877,171,SPARK_POS_OK,0.253385,0.255686,0.183159,0.003816,NORMAL,1040,4241,0 +48820894,876,181,SPARK_POS_OK,0.184273,0.232522,0.245903,0.248105,NORMAL,878,180,SPARK_POS_OK,0.253309,0.255567,0.183053,0.003799,NORMAL,1040,4187,0 +48877894,877,181,SPARK_POS_OK,0.184165,0.232435,0.245768,0.247996,NORMAL,879,180,SPARK_POS_OK,0.253191,0.255446,0.182964,0.003816,NORMAL,1039,4180,0 +48935894,878,181,SPARK_POS_OK,0.184060,0.232328,0.245652,0.247856,NORMAL,880,180,SPARK_POS_OK,0.253038,0.255304,0.182863,0.003805,NORMAL,1039,4166,0 +48993894,879,191,SPARK_POS_OK,0.183955,0.232198,0.245534,0.247723,NORMAL,881,190,SPARK_POS_OK,0.252912,0.255213,0.182759,0.003794,NORMAL,1039,4162,0 +49051894,880,191,SPARK_POS_OK,0.183828,0.232086,0.245433,0.247585,NORMAL,882,190,SPARK_POS_OK,0.252812,0.255078,0.182651,0.003785,NORMAL,1040,4209,0 +49108894,881,201,SPARK_POS_OK,0.183755,0.232013,0.245312,0.247477,NORMAL,883,199,SPARK_POS_OK,0.252693,0.254959,0.182567,0.003808,NORMAL,1043,4178,0 +49166894,882,201,SPARK_POS_OK,0.183622,0.231887,0.245204,0.247368,NORMAL,884,200,SPARK_POS_OK,0.252554,0.254838,0.182472,0.003796,NORMAL,1044,4197,0 +49223894,883,210,SPARK_POS_OK,0.183548,0.231800,0.245070,0.247249,NORMAL,885,211,SPARK_POS_OK,0.252450,0.254720,0.182371,0.003793,NORMAL,1048,4180,0 +49280894,884,210,SPARK_POS_OK,0.183415,0.231697,0.244941,0.247137,NORMAL,886,210,SPARK_POS_OK,0.252352,0.254604,0.182251,0.003785,NORMAL,1049,4233,0 +49337894,885,210,SPARK_POS_OK,0.183302,0.231607,0.244841,0.246993,NORMAL,887,210,SPARK_POS_OK,0.252231,0.254492,0.182170,0.003790,NORMAL,1052,4272,0 +49394894,886,201,SPARK_POS_OK,0.183178,0.231465,0.244700,0.246891,NORMAL,888,210,SPARK_POS_OK,0.252116,0.254380,0.182086,0.003777,NORMAL,1051,4252,0 +49451894,887,201,SPARK_POS_OK,0.183051,0.231370,0.244613,0.246722,NORMAL,889,200,SPARK_POS_OK,0.252008,0.254268,0.181959,0.003791,NORMAL,1051,4271,0 +49508894,888,181,SPARK_POS_OK,0.182953,0.231250,0.244480,0.246650,NORMAL,890,200,SPARK_POS_OK,0.251892,0.254142,0.181869,0.003777,NORMAL,1051,4231,0 +49565894,889,181,SPARK_POS_OK,0.182852,0.231152,0.244332,0.246547,NORMAL,891,180,SPARK_POS_OK,0.251753,0.254017,0.181770,0.003770,NORMAL,1051,4228,0 +49622894,890,171,SPARK_POS_OK,0.182726,0.231064,0.244222,0.246421,NORMAL,892,170,SPARK_POS_OK,0.251654,0.253898,0.181662,0.003781,NORMAL,1050,4160,0 +49680894,891,171,SPARK_POS_OK,0.182616,0.230951,0.244120,0.246286,NORMAL,893,170,SPARK_POS_OK,0.251557,0.253804,0.181562,0.003788,NORMAL,1051,4277,0 +49737894,892,161,SPARK_POS_OK,0.182503,0.230843,0.243998,0.246158,NORMAL,894,160,SPARK_POS_OK,0.251422,0.253675,0.181480,0.003783,NORMAL,1048,4215,0 +49794894,893,150,SPARK_POS_OK,0.182407,0.230728,0.243864,0.246056,NORMAL,895,160,SPARK_POS_OK,0.251293,0.253534,0.181367,0.003766,NORMAL,1045,4161,0 +49851894,894,150,SPARK_POS_OK,0.182299,0.230612,0.243748,0.245910,NORMAL,896,150,SPARK_POS_OK,0.251176,0.253406,0.181258,0.003772,NORMAL,1044,4161,0 +49909894,895,150,SPARK_POS_OK,0.182188,0.230522,0.243649,0.245810,NORMAL,897,150,SPARK_POS_OK,0.251061,0.253302,0.181175,0.003751,NORMAL,1040,4237,0 +49967894,896,150,SPARK_POS_OK,0.182081,0.230432,0.243503,0.245688,NORMAL,898,150,SPARK_POS_OK,0.250947,0.253167,0.181066,0.003761,NORMAL,1039,4223,0 +50025894,897,140,SPARK_POS_OK,0.181990,0.230336,0.243385,0.245574,NORMAL,899,150,SPARK_POS_OK,0.250832,0.253050,0.180967,0.003765,NORMAL,1036,4183,0 +50083894,898,140,SPARK_POS_OK,0.181845,0.230209,0.243291,0.245417,NORMAL,900,140,SPARK_POS_OK,0.250705,0.252939,0.180880,0.003750,NORMAL,1035,4215,0 +50141894,899,140,SPARK_POS_OK,0.181769,0.230139,0.243139,0.245352,NORMAL,901,140,SPARK_POS_OK,0.250615,0.252838,0.180776,0.003752,NORMAL,1032,4231,0 +50199894,900,140,SPARK_POS_OK,0.181661,0.229990,0.243036,0.245205,NORMAL,902,140,SPARK_POS_OK,0.250475,0.252681,0.180660,0.003754,NORMAL,1033,4164,0 +50257894,901,140,SPARK_POS_OK,0.181559,0.229920,0.242902,0.245090,NORMAL,903,138,SPARK_POS_OK,0.250394,0.252586,0.180570,0.003743,NORMAL,1029,4165,0 +50316894,902,139,SPARK_POS_OK,0.181454,0.229805,0.242788,0.244974,NORMAL,904,141,SPARK_POS_OK,0.250267,0.252476,0.180474,0.003749,NORMAL,1027,4176,0 +50374894,903,140,SPARK_POS_OK,0.181333,0.229685,0.242683,0.244868,NORMAL,905,141,SPARK_POS_OK,0.250145,0.252370,0.180380,0.003731,NORMAL,1025,4222,0 +50433894,904,130,SPARK_POS_OK,0.181242,0.229599,0.242561,0.244744,NORMAL,906,141,SPARK_POS_OK,0.250034,0.252240,0.180277,0.003742,NORMAL,1022,4171,0 +50492894,905,130,SPARK_POS_OK,0.181165,0.229467,0.242457,0.244618,NORMAL,907,130,SPARK_POS_OK,0.249910,0.252100,0.180182,0.003732,NORMAL,1019,4256,0 +50551894,906,130,SPARK_POS_OK,0.181014,0.229410,0.242325,0.244519,NORMAL,908,130,SPARK_POS_OK,0.249804,0.252000,0.180102,0.003753,NORMAL,1015,4206,0 +50610894,907,131,SPARK_POS_OK,0.180916,0.229288,0.242222,0.244411,NORMAL,909,130,SPARK_POS_OK,0.249669,0.251884,0.179996,0.003746,NORMAL,1015,4205,0 +50669894,908,133,SPARK_POS_OK,0.180824,0.229185,0.242077,0.244268,NORMAL,910,130,SPARK_POS_OK,0.249584,0.251774,0.179896,0.003724,NORMAL,1013,4208,0 +50728894,909,130,SPARK_POS_OK,0.180694,0.229062,0.241970,0.244145,NORMAL,911,130,SPARK_POS_OK,0.249456,0.251659,0.179799,0.003727,NORMAL,1014,4208,0 +50787894,910,130,SPARK_POS_OK,0.180615,0.228989,0.241830,0.244040,NORMAL,912,130,SPARK_POS_OK,0.249347,0.251544,0.179687,0.003733,NORMAL,1011,4163,0 +50847894,911,140,SPARK_POS_OK,0.180486,0.228877,0.241734,0.243900,NORMAL,913,130,SPARK_POS_OK,0.249223,0.251398,0.179603,0.003727,NORMAL,1010,4232,0 +50906894,912,140,SPARK_POS_OK,0.180374,0.228772,0.241596,0.243781,NORMAL,914,141,SPARK_POS_OK,0.249118,0.251292,0.179501,0.003721,NORMAL,1009,4251,0 +50966894,913,150,SPARK_POS_OK,0.180268,0.228676,0.241511,0.243672,NORMAL,915,143,SPARK_POS_OK,0.249002,0.251150,0.179390,0.003727,NORMAL,1007,4171,0 +51025894,914,150,SPARK_POS_OK,0.180143,0.228543,0.241371,0.243591,NORMAL,916,150,SPARK_POS_OK,0.248873,0.251072,0.179284,0.003721,NORMAL,1007,4223,0 +51085894,915,161,SPARK_POS_OK,0.180058,0.228450,0.241258,0.243443,NORMAL,917,158,SPARK_POS_OK,0.248755,0.250931,0.179205,0.003712,NORMAL,1007,4152,0 +51144894,916,161,SPARK_POS_OK,0.179952,0.228314,0.241187,0.243336,NORMAL,918,160,SPARK_POS_OK,0.248628,0.250839,0.179121,0.003693,NORMAL,1008,4214,0 +51204894,917,161,SPARK_POS_OK,0.179825,0.228233,0.241035,0.243222,NORMAL,919,160,SPARK_POS_OK,0.248558,0.250704,0.179017,0.003716,NORMAL,1010,4240,0 +51263894,918,170,SPARK_POS_OK,0.179723,0.228140,0.240918,0.243119,NORMAL,920,160,SPARK_POS_OK,0.248442,0.250626,0.178941,0.003673,NORMAL,1012,4163,0 +51322894,919,170,SPARK_POS_OK,0.179611,0.228032,0.240797,0.242962,NORMAL,921,170,SPARK_POS_OK,0.248314,0.250484,0.178823,0.003694,NORMAL,1014,4216,0 +51381894,920,180,SPARK_POS_OK,0.179483,0.227915,0.240700,0.242868,NORMAL,922,170,SPARK_POS_OK,0.248206,0.250369,0.178745,0.003690,NORMAL,1014,4278,0 +51440894,921,181,SPARK_POS_OK,0.179390,0.227807,0.240554,0.242754,NORMAL,923,181,SPARK_POS_OK,0.248052,0.250253,0.178649,0.003718,NORMAL,1016,4185,0 +51499894,922,180,SPARK_POS_OK,0.179291,0.227693,0.240412,0.242594,NORMAL,924,181,SPARK_POS_OK,0.247962,0.250142,0.178552,0.003698,NORMAL,1017,4159,0 +51558894,923,180,SPARK_POS_OK,0.179173,0.227607,0.240358,0.242525,NORMAL,925,180,SPARK_POS_OK,0.247841,0.250010,0.178452,0.003690,NORMAL,1018,4185,0 +51617894,924,180,SPARK_POS_OK,0.179079,0.227488,0.240244,0.242394,NORMAL,926,180,SPARK_POS_OK,0.247728,0.249873,0.178347,0.003700,NORMAL,1020,4188,0 +51676894,925,191,SPARK_POS_OK,0.178958,0.227406,0.240106,0.242279,NORMAL,927,180,SPARK_POS_OK,0.247626,0.249738,0.178260,0.003663,NORMAL,1022,4188,0 +51734894,926,191,SPARK_POS_OK,0.178894,0.227287,0.239970,0.242131,NORMAL,928,190,SPARK_POS_OK,0.247489,0.249669,0.178149,0.003687,NORMAL,1025,4233,0 +51793894,927,191,SPARK_POS_OK,0.178756,0.227187,0.239858,0.242033,NORMAL,929,190,SPARK_POS_OK,0.247404,0.249532,0.178056,0.003693,NORMAL,1026,4206,0 +51851894,928,191,SPARK_POS_OK,0.178682,0.227094,0.239761,0.241903,NORMAL,930,190,SPARK_POS_OK,0.247283,0.249423,0.177974,0.003693,NORMAL,1029,4206,0 +51909894,929,190,SPARK_POS_OK,0.178563,0.226976,0.239627,0.241792,NORMAL,931,190,SPARK_POS_OK,0.247145,0.249316,0.177866,0.003682,NORMAL,1031,4181,0 +51967894,930,190,SPARK_POS_OK,0.178457,0.226884,0.239519,0.241674,NORMAL,932,190,SPARK_POS_OK,0.247059,0.249201,0.177770,0.003687,NORMAL,1032,4208,0 +52025894,931,190,SPARK_POS_OK,0.178345,0.226781,0.239405,0.241570,NORMAL,933,190,SPARK_POS_OK,0.246941,0.249071,0.177685,0.003692,NORMAL,1033,4264,0 +52083894,932,200,SPARK_POS_OK,0.178225,0.226653,0.239264,0.241413,NORMAL,934,190,SPARK_POS_OK,0.246826,0.248956,0.177557,0.003710,NORMAL,1034,4256,0 +52141894,933,202,SPARK_POS_OK,0.178135,0.226579,0.239156,0.241321,NORMAL,935,200,SPARK_POS_OK,0.246705,0.248853,0.177467,0.003691,NORMAL,1036,4237,0 +52199894,934,200,SPARK_POS_OK,0.178037,0.226479,0.239038,0.241219,NORMAL,936,200,SPARK_POS_OK,0.246564,0.248730,0.177386,0.003682,NORMAL,1037,4152,0 +52257894,935,200,SPARK_POS_OK,0.177921,0.226363,0.238945,0.241104,NORMAL,937,199,SPARK_POS_OK,0.246492,0.248597,0.177285,0.003694,NORMAL,1040,4244,0 +52314894,936,200,SPARK_POS_OK,0.177812,0.226263,0.238812,0.240967,NORMAL,938,200,SPARK_POS_OK,0.246376,0.248495,0.177191,0.003685,NORMAL,1041,4231,0 +52372894,937,200,SPARK_POS_OK,0.177680,0.226153,0.238713,0.240849,NORMAL,939,200,SPARK_POS_OK,0.246275,0.248348,0.177107,0.003703,NORMAL,1044,4230,0 +52429894,938,200,SPARK_POS_OK,0.177594,0.226080,0.238577,0.240744,NORMAL,940,201,SPARK_POS_OK,0.246134,0.248282,0.177004,0.003694,NORMAL,1043,4221,0 +52487894,939,200,SPARK_POS_OK,0.177475,0.225956,0.238462,0.240625,NORMAL,941,201,SPARK_POS_OK,0.246044,0.248135,0.176916,0.003704,NORMAL,1044,4265,0 +52544894,940,200,SPARK_POS_OK,0.177384,0.225872,0.238366,0.240521,NORMAL,942,201,SPARK_POS_OK,0.245889,0.248041,0.176803,0.003698,NORMAL,1043,4229,0 +52601894,941,200,SPARK_POS_OK,0.177253,0.225781,0.238213,0.240364,NORMAL,943,201,SPARK_POS_OK,0.245787,0.247910,0.176700,0.003678,NORMAL,1044,4237,0 +52659894,942,200,SPARK_POS_OK,0.177161,0.225646,0.238121,0.240245,NORMAL,944,201,SPARK_POS_OK,0.245695,0.247777,0.176609,0.003685,NORMAL,1045,4204,0 +52716894,943,202,SPARK_POS_OK,0.177056,0.225565,0.238028,0.240158,NORMAL,945,201,SPARK_POS_OK,0.245553,0.247676,0.176513,0.003714,NORMAL,1047,4230,0 +52773894,944,200,SPARK_POS_OK,0.176951,0.225442,0.237892,0.240009,NORMAL,946,201,SPARK_POS_OK,0.245476,0.247564,0.176414,0.003684,NORMAL,1050,4151,0 +52830894,945,200,SPARK_POS_OK,0.176859,0.225365,0.237779,0.239926,NORMAL,947,201,SPARK_POS_OK,0.245338,0.247457,0.176337,0.003695,NORMAL,1050,4242,0 +52887894,946,198,SPARK_POS_OK,0.176730,0.225252,0.237657,0.239801,NORMAL,948,201,SPARK_POS_OK,0.245228,0.247353,0.176218,0.003702,NORMAL,1053,4206,0 +52944894,947,210,SPARK_POS_OK,0.176619,0.225137,0.237545,0.239674,NORMAL,949,210,SPARK_POS_OK,0.245138,0.247210,0.176138,0.003691,NORMAL,1054,4226,0 +53001894,948,210,SPARK_POS_OK,0.176516,0.225054,0.237430,0.239578,NORMAL,950,211,SPARK_POS_OK,0.244980,0.247125,0.176038,0.003704,NORMAL,1055,4157,0 +53058894,949,220,SPARK_POS_OK,0.176409,0.224927,0.237287,0.239444,NORMAL,951,221,SPARK_POS_OK,0.244922,0.246981,0.175939,0.003682,NORMAL,1055,4234,0 +53115894,950,220,SPARK_POS_OK,0.176303,0.224836,0.237187,0.239326,NORMAL,952,221,SPARK_POS_OK,0.244802,0.246869,0.175855,0.003700,NORMAL,1056,4227,0 +53171894,951,220,SPARK_POS_OK,0.176209,0.224728,0.237058,0.239228,NORMAL,953,220,SPARK_POS_OK,0.244660,0.246759,0.175741,0.003686,NORMAL,1059,4236,0 +53228894,952,232,SPARK_POS_OK,0.176130,0.224632,0.236957,0.239087,NORMAL,954,220,SPARK_POS_OK,0.244568,0.246645,0.175671,0.003706,NORMAL,1062,4149,0 +53284894,953,230,SPARK_POS_OK,0.176008,0.224525,0.236865,0.239014,NORMAL,955,230,SPARK_POS_OK,0.244426,0.246528,0.175578,0.003695,NORMAL,1066,4149,0 +53340894,954,241,SPARK_POS_OK,0.175912,0.224442,0.236724,0.238883,NORMAL,956,230,SPARK_POS_OK,0.244311,0.246415,0.175474,0.003710,NORMAL,1068,4264,0 +53396894,955,240,SPARK_POS_OK,0.175794,0.224323,0.236610,0.238752,NORMAL,957,240,SPARK_POS_OK,0.244229,0.246270,0.175374,0.003706,NORMAL,1072,4208,0 +53674894,956,11,SPARK_NEG_OK,0.175783,0.224292,0.236570,0.238706,SOFT_START,959,11,SPARK_NEG_OK,0.244206,0.246261,0.175381,0.003434,SOFT_START,1084,4273,0 +53729894,957,11,SPARK_NEG_OK,0.175673,0.224182,0.236448,0.238615,SOFT_START,960,11,SPARK_NEG_OK,0.244086,0.246149,0.175256,0.003447,SOFT_START,1085,4206,0 +53784894,958,11,SPARK_NEG_OK,0.175576,0.224109,0.236334,0.238502,SOFT_START,961,11,SPARK_NEG_OK,0.243948,0.246023,0.175169,0.003446,SOFT_START,1091,4162,0 +53839894,959,11,SPARK_NEG_OK,0.175478,0.224012,0.236243,0.238401,SOFT_START,962,12,SPARK_NEG_OK,0.243824,0.245910,0.175105,0.003470,SOFT_START,1092,4168,0 +54003894,960,241,SPARK_POS_OK,0.175418,0.223927,0.236150,0.238284,NORMAL,963,240,SPARK_POS_OK,0.243795,0.245828,0.175021,0.003356,NORMAL,1102,4204,0 +54058894,961,231,SPARK_POS_OK,0.175305,0.223829,0.236015,0.238169,NORMAL,964,240,SPARK_POS_OK,0.243664,0.245724,0.174927,0.003375,NORMAL,1096,4267,0 +54113894,962,230,SPARK_POS_OK,0.175204,0.223744,0.235916,0.238052,NORMAL,965,230,SPARK_POS_OK,0.243499,0.245609,0.174820,0.003390,NORMAL,1096,4207,0 +54168894,963,220,SPARK_POS_OK,0.175103,0.223635,0.235816,0.237938,NORMAL,966,230,SPARK_POS_OK,0.243422,0.245486,0.174741,0.003411,NORMAL,1095,4230,0 +54222894,964,220,SPARK_POS_OK,0.174997,0.223547,0.235701,0.237829,NORMAL,967,221,SPARK_POS_OK,0.243309,0.245369,0.174666,0.003443,NORMAL,1096,4170,0 +54277894,965,220,SPARK_POS_OK,0.174891,0.223427,0.235560,0.237699,NORMAL,968,221,SPARK_POS_OK,0.243210,0.245252,0.174542,0.003449,NORMAL,1095,4213,0 +54332894,966,220,SPARK_POS_OK,0.174809,0.223322,0.235466,0.237581,NORMAL,969,220,SPARK_POS_OK,0.243076,0.245125,0.174434,0.003467,NORMAL,1097,4193,0 +54387894,967,210,SPARK_POS_OK,0.174709,0.223221,0.235333,0.237470,NORMAL,970,220,SPARK_POS_OK,0.242979,0.245035,0.174358,0.003471,NORMAL,1096,4237,0 +54441894,968,211,SPARK_POS_OK,0.174584,0.223115,0.235217,0.237331,NORMAL,971,210,SPARK_POS_OK,0.242879,0.244905,0.174257,0.003499,NORMAL,1096,4177,0 +54496894,969,201,SPARK_POS_OK,0.174465,0.223033,0.235104,0.237241,NORMAL,972,210,SPARK_POS_OK,0.242747,0.244792,0.174165,0.003507,NORMAL,1094,4252,0 +54551894,970,200,SPARK_POS_OK,0.174382,0.222914,0.234981,0.237129,NORMAL,973,200,SPARK_POS_OK,0.242670,0.244678,0.174090,0.003508,NORMAL,1093,4165,0 +54606894,971,188,SPARK_POS_OK,0.174282,0.222827,0.234905,0.237012,NORMAL,974,189,SPARK_POS_OK,0.242506,0.244573,0.173976,0.003533,NORMAL,1087,4166,0 +54661894,972,190,SPARK_POS_OK,0.174193,0.222720,0.234750,0.236908,NORMAL,975,191,SPARK_POS_OK,0.242398,0.244440,0.173886,0.003530,NORMAL,1088,4221,0 +54717894,973,190,SPARK_POS_OK,0.174090,0.222608,0.234655,0.236794,NORMAL,976,191,SPARK_POS_OK,0.242307,0.244360,0.173807,0.003555,NORMAL,1083,4158,0 +54772894,974,190,SPARK_POS_OK,0.173970,0.222521,0.234529,0.236660,NORMAL,977,191,SPARK_POS_OK,0.242168,0.244220,0.173696,0.003552,NORMAL,1084,4279,0 +54828894,975,180,SPARK_POS_OK,0.173885,0.222414,0.234400,0.236566,NORMAL,978,180,SPARK_POS_OK,0.242065,0.244108,0.173611,0.003575,NORMAL,1081,4247,0 +54883894,976,183,SPARK_POS_OK,0.173747,0.222317,0.234323,0.236436,NORMAL,979,180,SPARK_POS_OK,0.241960,0.244016,0.173525,0.003580,NORMAL,1082,4268,0 +54939894,977,170,SPARK_POS_OK,0.173649,0.222196,0.234209,0.236310,NORMAL,980,170,SPARK_POS_OK,0.241845,0.243925,0.173399,0.003576,NORMAL,1077,4170,0 +54995894,978,160,SPARK_POS_OK,0.173565,0.222088,0.234081,0.236226,NORMAL,981,170,SPARK_POS_OK,0.241759,0.243788,0.173325,0.003588,NORMAL,1074,4158,0 +55051894,979,161,SPARK_POS_OK,0.173455,0.221997,0.233963,0.236095,NORMAL,982,160,SPARK_POS_OK,0.241627,0.243664,0.173233,0.003607,NORMAL,1071,4152,0 +55107894,980,151,SPARK_POS_OK,0.173360,0.221920,0.233859,0.235954,NORMAL,983,160,SPARK_POS_OK,0.241511,0.243541,0.173141,0.003611,NORMAL,1066,4255,0 +55163894,981,151,SPARK_POS_OK,0.173278,0.221807,0.233724,0.235876,NORMAL,984,150,SPARK_POS_OK,0.241415,0.243439,0.173040,0.003599,NORMAL,1062,4168,0 +55220894,982,141,SPARK_POS_OK,0.173152,0.221723,0.233647,0.235753,NORMAL,985,150,SPARK_POS_OK,0.241306,0.243303,0.172946,0.003625,NORMAL,1057,4231,0 +55277894,983,141,SPARK_POS_OK,0.173031,0.221609,0.233508,0.235673,NORMAL,986,140,SPARK_POS_OK,0.241213,0.243213,0.172861,0.003614,NORMAL,1054,4277,0 +55334894,984,131,SPARK_POS_OK,0.172935,0.221484,0.233424,0.235513,NORMAL,987,130,SPARK_POS_OK,0.241047,0.243092,0.172771,0.003617,NORMAL,1048,4254,0 +55391894,985,129,SPARK_POS_OK,0.172841,0.221410,0.233307,0.235420,NORMAL,988,130,SPARK_POS_OK,0.240950,0.242991,0.172690,0.003616,NORMAL,1049,4157,0 +55449894,986,121,SPARK_POS_OK,0.172748,0.221290,0.233184,0.235296,NORMAL,989,120,SPARK_POS_OK,0.240864,0.242877,0.172592,0.003625,NORMAL,1043,4222,0 +55506894,987,119,SPARK_POS_OK,0.172647,0.221215,0.233061,0.235195,NORMAL,990,120,SPARK_POS_OK,0.240753,0.242780,0.172480,0.003640,NORMAL,1043,4198,0 +55564894,988,121,SPARK_POS_OK,0.172533,0.221091,0.232973,0.235078,NORMAL,991,120,SPARK_POS_OK,0.240631,0.242653,0.172416,0.003634,NORMAL,1034,4224,0 +55623894,989,121,SPARK_POS_OK,0.172437,0.221025,0.232813,0.234967,NORMAL,992,120,SPARK_POS_OK,0.240516,0.242522,0.172309,0.003656,NORMAL,1030,4156,0 +55681894,990,121,SPARK_POS_OK,0.172341,0.220917,0.232717,0.234841,NORMAL,993,120,SPARK_POS_OK,0.240397,0.242425,0.172216,0.003625,NORMAL,1027,4163,0 +55740894,991,120,SPARK_POS_OK,0.172234,0.220792,0.232614,0.234712,NORMAL,994,120,SPARK_POS_OK,0.240303,0.242295,0.172144,0.003639,NORMAL,1024,4232,0 +55798894,992,120,SPARK_POS_OK,0.172144,0.220699,0.232477,0.234637,NORMAL,995,120,SPARK_POS_OK,0.240181,0.242188,0.172036,0.003632,NORMAL,1022,4191,0 +55857894,993,130,SPARK_POS_OK,0.172038,0.220593,0.232363,0.234499,NORMAL,996,129,SPARK_POS_OK,0.240095,0.242084,0.171948,0.003615,NORMAL,1018,4247,0 +55916894,994,130,SPARK_POS_OK,0.171934,0.220514,0.232289,0.234380,NORMAL,997,130,SPARK_POS_OK,0.240006,0.241980,0.171863,0.003595,NORMAL,1020,4220,0 +55975894,995,130,SPARK_POS_OK,0.171849,0.220422,0.232148,0.234308,NORMAL,998,131,SPARK_POS_OK,0.239871,0.241846,0.171753,0.003628,NORMAL,1017,4156,0 +56034894,996,140,SPARK_POS_OK,0.171710,0.220300,0.232062,0.234135,NORMAL,999,128,SPARK_POS_OK,0.239764,0.241757,0.171660,0.003622,NORMAL,1014,4247,0 +56093894,997,140,SPARK_POS_OK,0.171584,0.220205,0.231923,0.234075,NORMAL,1000,140,SPARK_POS_OK,0.239659,0.241607,0.171576,0.003605,NORMAL,1014,4276,0 +56152900,998,141,SPARK_POS_OK,0.171525,0.220073,0.231818,0.233932,NORMAL,1001,140,SPARK_POS_OK,0.239537,0.241546,0.171494,0.003622,NORMAL,1011,4153,0 +56212894,999,141,SPARK_POS_OK,0.171409,0.219982,0.231696,0.233833,NORMAL,1002,140,SPARK_POS_OK,0.239413,0.241408,0.171388,0.003623,NORMAL,1010,4233,0 +56271894,1000,151,SPARK_POS_OK,0.171313,0.219899,0.231600,0.233698,NORMAL,1003,151,SPARK_POS_OK,0.239316,0.241311,0.171290,0.003623,NORMAL,1008,4221,0 +56331894,1001,150,SPARK_POS_OK,0.171214,0.219794,0.231485,0.233610,NORMAL,1004,150,SPARK_POS_OK,0.239228,0.241202,0.171193,0.003611,NORMAL,1009,4261,0 +56390894,1002,150,SPARK_POS_OK,0.171118,0.219672,0.231362,0.233514,NORMAL,1005,150,SPARK_POS_OK,0.239084,0.241068,0.171105,0.003620,NORMAL,1010,4217,0 +56450894,1003,150,SPARK_POS_OK,0.170998,0.219589,0.231270,0.233375,NORMAL,1006,150,SPARK_POS_OK,0.238969,0.240975,0.171028,0.003622,NORMAL,1011,4222,0 +56509894,1004,150,SPARK_POS_OK,0.170899,0.219505,0.231161,0.233266,NORMAL,1007,151,SPARK_POS_OK,0.238878,0.240844,0.170931,0.003621,NORMAL,1013,4195,0 +56568894,1005,150,SPARK_POS_OK,0.170801,0.219401,0.231034,0.233170,NORMAL,1008,151,SPARK_POS_OK,0.238786,0.240709,0.170842,0.003604,NORMAL,1011,4221,0 +56627894,1006,150,SPARK_POS_OK,0.170709,0.219285,0.230920,0.233046,NORMAL,1009,150,SPARK_POS_OK,0.238663,0.240649,0.170770,0.003610,NORMAL,1012,4267,0 +56687894,1007,161,SPARK_POS_OK,0.170597,0.219198,0.230805,0.232953,NORMAL,1010,150,SPARK_POS_OK,0.238556,0.240501,0.170655,0.003626,NORMAL,1010,4217,0 +56746894,1008,161,SPARK_POS_OK,0.170508,0.219094,0.230714,0.232818,NORMAL,1011,160,SPARK_POS_OK,0.238431,0.240412,0.170583,0.003611,NORMAL,1010,4189,0 +56806894,1009,160,SPARK_POS_OK,0.170414,0.219002,0.230615,0.232709,NORMAL,1012,159,SPARK_POS_OK,0.238371,0.240313,0.170481,0.003620,NORMAL,1010,4264,0 +56865894,1010,160,SPARK_POS_OK,0.170291,0.218900,0.230491,0.232625,NORMAL,1013,160,SPARK_POS_OK,0.238225,0.240183,0.170389,0.003610,NORMAL,1011,4192,0 +56924894,1011,160,SPARK_POS_OK,0.170199,0.218821,0.230367,0.232511,NORMAL,1014,160,SPARK_POS_OK,0.238116,0.240076,0.170326,0.003639,NORMAL,1012,4206,0 +56983894,1012,160,SPARK_POS_OK,0.170107,0.218716,0.230243,0.232403,NORMAL,1015,161,SPARK_POS_OK,0.238000,0.239963,0.170224,0.003619,NORMAL,1014,4239,0 +57042894,1013,161,SPARK_POS_OK,0.169992,0.218605,0.230156,0.232281,NORMAL,1016,161,SPARK_POS_OK,0.237895,0.239862,0.170106,0.003601,NORMAL,1016,4258,0 +57101894,1014,160,SPARK_POS_OK,0.169904,0.218504,0.230020,0.232170,NORMAL,1017,161,SPARK_POS_OK,0.237796,0.239727,0.170028,0.003614,NORMAL,1015,4216,0 +57160894,1015,160,SPARK_POS_OK,0.169811,0.218436,0.229915,0.232031,NORMAL,1018,160,SPARK_POS_OK,0.237724,0.239649,0.169947,0.003592,NORMAL,1015,4216,0 +57220894,1016,171,SPARK_POS_OK,0.169690,0.218344,0.229853,0.231928,NORMAL,1019,170,SPARK_POS_OK,0.237590,0.239527,0.169848,0.003619,NORMAL,1014,4258,0 +57279894,1017,171,SPARK_POS_OK,0.169574,0.218239,0.229714,0.231815,NORMAL,1020,170,SPARK_POS_OK,0.237497,0.239438,0.169757,0.003595,NORMAL,1015,4218,0 +57338894,1018,171,SPARK_POS_OK,0.169488,0.218148,0.229599,0.231684,NORMAL,1021,170,SPARK_POS_OK,0.237364,0.239320,0.169677,0.003618,NORMAL,1016,4220,0 +57397894,1019,170,SPARK_POS_OK,0.169376,0.218035,0.229491,0.231606,NORMAL,1022,170,SPARK_POS_OK,0.237283,0.239204,0.169593,0.003594,NORMAL,1018,4223,0 +57455894,1020,170,SPARK_POS_OK,0.169286,0.217936,0.229365,0.231490,NORMAL,1023,170,SPARK_POS_OK,0.237159,0.239098,0.169486,0.003607,NORMAL,1021,4256,0 +57514894,1021,170,SPARK_POS_OK,0.169184,0.217842,0.229250,0.231389,NORMAL,1024,170,SPARK_POS_OK,0.237051,0.238982,0.169410,0.003601,NORMAL,1021,4205,0 +57573894,1022,170,SPARK_POS_OK,0.169092,0.217730,0.229179,0.231260,NORMAL,1025,170,SPARK_POS_OK,0.236936,0.238863,0.169286,0.003614,NORMAL,1024,4171,0 +57631894,1023,180,SPARK_POS_OK,0.169008,0.217618,0.229036,0.231152,NORMAL,1026,181,SPARK_POS_OK,0.236813,0.238746,0.169223,0.003630,NORMAL,1024,4163,0 +57690894,1024,180,SPARK_POS_OK,0.168919,0.217549,0.228928,0.231032,NORMAL,1027,181,SPARK_POS_OK,0.236756,0.238685,0.169133,0.003594,NORMAL,1025,4207,0 \ No newline at end of file diff --git a/RotaxMonitor/unpacked_fs/spiffs/ignA_history.bin b/RotaxMonitor/unpacked_fs/spiffs/ignA_history.bin new file mode 100644 index 0000000000000000000000000000000000000000..343936602bb2e06345e2a6a643d4b205bc4c4b8f GIT binary patch literal 116966 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 t{9yu-FU#30>_m`B2=YH${ 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 Date: Tue, 7 Apr 2026 15:53:52 +0200 Subject: [PATCH 06/38] Save files appending on same session and new file on new session --- RotaxMonitor/src/datasave.cpp | 50 +- RotaxMonitor/src/datasave.h | 25 +- RotaxMonitor/src/datastruct.h | 90 + RotaxMonitor/src/isr.h | 87 +- RotaxMonitor/src/main.cpp | 71 +- RotaxMonitor/src/tasks.cpp | 5 + RotaxMonitor/src/ui.cpp | 68 + RotaxMonitor/src/ui.h | 39 +- RotaxMonitor/src/utils.h | 7 - RotaxMonitor/unpacked_fs/ignA_history.csv | 1713 +++++++++-------- .../unpacked_fs/spiffs/ignA_history.bin | Bin 116966 -> 0 bytes 11 files changed, 1112 insertions(+), 1043 deletions(-) create mode 100644 RotaxMonitor/src/datastruct.h create mode 100644 RotaxMonitor/src/ui.cpp delete mode 100644 RotaxMonitor/unpacked_fs/spiffs/ignA_history.bin diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index 222004b..13d2564 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -1,6 +1,8 @@ #include "datasave.h" -void save_history(const PSRAMVector &history) +static constexpr size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB) + +void save_history(const PSRAMVector &history, const std::filesystem::path &file_path) { // Initialize SPIFFS if (!SPIFFS.begin(true)) @@ -10,25 +12,49 @@ void save_history(const PSRAMVector &history) vTaskDelay(pdMS_TO_TICKS(5000)); esp_restart(); } - else + + LOG_INFO("SPIFFS mounted successfully"); + if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free ) // check if at least 1MB is free for saving history { - LOG_INFO("SPIFFS mounted successfully"); + LOG_ERROR("Not enough space in SPIFFS to save history"); return; } - std::ofstream ofs("/spiffs/ignA_history.csv", std::ios::out | std::ios::trunc); + std::filesystem::path to_save = file_path; + if (file_path.root_path() != "/spiffs") + to_save = std::filesystem::path("/spiffs") / file_path; + + auto save_flags = std::ios::out; + static bool first_save = true; + if (first_save || !SPIFFS.exists(to_save.c_str())) + { + save_flags |= std::ios::trunc; // overwrite existing file + first_save = false; + LOG_INFO("Saving history to SPIFFS, new file: ", to_save.c_str()); + } + else + { + save_flags |= std::ios::app; // append to new file + LOG_INFO("Saving history to SPIFFS, appending to existing file: ", to_save.c_str()); + } + + std::ofstream ofs(to_save, save_flags); if (ofs.fail()) { LOG_ERROR("Failed to open file for writing"); return; } - //write csv header - ofs << "TS,\ - EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ - EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ - ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS"; - for (auto &entry : history) + // write csv header + if (first_save) + { + ofs << "TS,\ + EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ + EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ + ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS"; + } + + for (const auto &entry : history) { ofs << std::to_string(entry.timestamp) << "," << std::to_string(entry.coils12.n_events) << "," @@ -52,9 +78,9 @@ void save_history(const PSRAMVector &history) << std::to_string(entry.n_queue_errors); ofs << std::endl; } - auto written_bytes = ofs.tellp(); + ofs.flush(); ofs.close(); - LOG_INFO("Ignition A history saved to SPIFFS, bytes written: ", (uint32_t)written_bytes); + LOG_INFO("Ignition A history saved to SPIFFS, records written: ", history.size()); SPIFFS.end(); // unmount SPIFFS to ensure data is written and avoid corruption on next mount } \ No newline at end of file diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index e54efb1..52cf403 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -6,19 +6,34 @@ #include #include #include +#include // Project Includes #include "isr.h" #include "psvector.h" +const uint32_t max_history = 1024; const bool SAVE_HISTORY_TO_SPIFFS = true; // Set to true to enable saving history to SPIFFS, false to disable +struct dataSaveParams +{ + PSRAMVector *history; + const std::filesystem::path file_path; +}; + +void save_history(const PSRAMVector &history, const std::filesystem::path& file_path); + static void saveHistoryTask(void *pvParameters) { - auto *history = static_cast *>(pvParameters); - save_history(*history); + auto *params = static_cast(pvParameters); + auto &history = *params->history; + auto &file_path = params->file_path; + if (!params) { + LOG_ERROR("Invalid parameters for saveHistoryTask"); + return; + } + + save_history(history, file_path); + history.reserve(max_history); // ensure writable buffer has the correct size vTaskDelete(NULL); } - -void save_history(const PSRAMVector &history); - diff --git a/RotaxMonitor/src/datastruct.h b/RotaxMonitor/src/datastruct.h new file mode 100644 index 0000000..3903976 --- /dev/null +++ b/RotaxMonitor/src/datastruct.h @@ -0,0 +1,90 @@ +#pragma once +#include +#include + +// ===================== +// Event Flags (bitmask) +// ===================== +static const uint32_t TRIG_FLAG_12P = (1 << 0); +static const uint32_t TRIG_FLAG_12N = (1 << 1); +static const uint32_t TRIG_FLAG_34P = (1 << 2); +static const uint32_t TRIG_FLAG_34N = (1 << 3); + +static const uint32_t SPARK_FLAG_TIMEOUT = (1 << 8); +static const uint32_t SPARK_FLAG_12 = (1 << 9); +static const uint32_t SPARK_FLAG_34 = (1 << 10); + +// Spark Status +enum sparkStatus +{ + SPARK_POS_OK, + SPARK_NEG_OK, + SPARK_POS_SKIP, + SPARK_NEG_SKIP, + SPARK_POS_WAIT, + SPARK_NEG_WAIT, + SPARK_POS_FAIL, + SPARK_NEG_FAIL, + SPARK_POS_UNEXPECTED, + SPARK_NEG_UNEXPECTED, + SPARK_SYNC_FAIL, +}; + +static const std::map sparkStatusNames = { + {SPARK_POS_OK, "SPARK_POS_OK"}, + {SPARK_NEG_OK, "SPARK_NEG_OK"}, + {SPARK_POS_SKIP, "SPARK_POS_SKIP"}, + {SPARK_NEG_SKIP, "SPARK_NEG_SKIP"}, + {SPARK_POS_WAIT, "SPARK_POS_WAIT"}, + {SPARK_NEG_WAIT, "SPARK_NEG_WAIT"}, + {SPARK_POS_FAIL, "SPARK_POS_FAIL"}, + {SPARK_NEG_FAIL, "SPARK_NEG_FAIL"}, + {SPARK_POS_UNEXPECTED, "SPARK_POS_UNEXPECTED"}, + {SPARK_NEG_UNEXPECTED, "SPARK_NEG_UNEXPECTED"}, + {SPARK_SYNC_FAIL, "SPARK_SYNC_FAIL"}, +}; + +enum softStartStatus +{ + NORMAL, + SOFT_START, + ERROR, +}; + +const std::map softStartStatusNames = { + {NORMAL, "NORMAL"}, + {SOFT_START, "SOFT_START"}, + {ERROR, "ERROR"}, +}; + +struct coilsStatus +{ + int64_t trig_time = 0; + int64_t spark_time = 0; + uint32_t spark_delay = 0; // in microseconds + sparkStatus spark_status = sparkStatus::SPARK_POS_OK; + softStartStatus sstart_status = softStartStatus::NORMAL; + float peak_p_in = 0.0; + float peak_n_in = 0.0; + float peak_p_out = 0.0; + float peak_n_out = 0.0; + float level_spark = 0.0; + uint32_t n_events = 0; + uint32_t n_missed_firing = 0; +}; + +// Task internal Status +struct ignitionBoxStatus +{ + int64_t timestamp = 0; + // coils pairs for each ignition + coilsStatus coils12; + coilsStatus coils34; + // voltage from generator + float volts_gen = 0.0; + // enine rpm + uint32_t eng_rpm = 0; + // debug values + uint32_t n_queue_errors = 0; + uint32_t adc_read_time = 0; +}; diff --git a/RotaxMonitor/src/isr.h b/RotaxMonitor/src/isr.h index c696bfc..efb118c 100644 --- a/RotaxMonitor/src/isr.h +++ b/RotaxMonitor/src/isr.h @@ -12,98 +12,13 @@ #else #include "pins_test.h" #endif +#include "datastruct.h" #define CORE_0 0 #define CORE_1 1 #define RT_TASK_STACK 4096 // in words #define RT_TASK_PRIORITY (configMAX_PRIORITIES - 4) // highest priority after wifi tasks -// ===================== -// Event Flags (bitmask) -// ===================== -static const uint32_t TRIG_FLAG_12P = (1 << 0); -static const uint32_t TRIG_FLAG_12N = (1 << 1); -static const uint32_t TRIG_FLAG_34P = (1 << 2); -static const uint32_t TRIG_FLAG_34N = (1 << 3); - -static const uint32_t SPARK_FLAG_TIMEOUT = (1 << 8); -static const uint32_t SPARK_FLAG_12 = (1 << 9); -static const uint32_t SPARK_FLAG_34 = (1 << 10); - -// Spark Status -enum sparkStatus -{ - SPARK_POS_OK, - SPARK_NEG_OK, - SPARK_POS_SKIP, - SPARK_NEG_SKIP, - SPARK_POS_WAIT, - SPARK_NEG_WAIT, - SPARK_POS_FAIL, - SPARK_NEG_FAIL, - SPARK_POS_UNEXPECTED, - SPARK_NEG_UNEXPECTED, - SPARK_SYNC_FAIL, -}; - -static const std::map sparkStatusNames = { - {SPARK_POS_OK, "SPARK_POS_OK"}, - {SPARK_NEG_OK, "SPARK_NEG_OK"}, - {SPARK_POS_SKIP, "SPARK_POS_SKIP"}, - {SPARK_NEG_SKIP, "SPARK_NEG_SKIP"}, - {SPARK_POS_WAIT, "SPARK_POS_WAIT"}, - {SPARK_NEG_WAIT, "SPARK_NEG_WAIT"}, - {SPARK_POS_FAIL, "SPARK_POS_FAIL"}, - {SPARK_NEG_FAIL, "SPARK_NEG_FAIL"}, - {SPARK_POS_UNEXPECTED, "SPARK_POS_UNEXPECTED"}, - {SPARK_NEG_UNEXPECTED, "SPARK_NEG_UNEXPECTED"}, - {SPARK_SYNC_FAIL, "SPARK_SYNC_FAIL"}, -}; - -enum softStartStatus -{ - NORMAL, - SOFT_START, - ERROR, -}; - -const std::map softStartStatusNames = { - {NORMAL, "NORMAL"}, - {SOFT_START, "SOFT_START"}, - {ERROR, "ERROR"}, -}; - -struct coilsStatus -{ - int64_t trig_time = 0; - int64_t spark_time = 0; - uint32_t spark_delay = 0; // in microseconds - sparkStatus spark_status = sparkStatus::SPARK_POS_OK; - softStartStatus sstart_status = softStartStatus::NORMAL; - float peak_p_in = 0.0; - float peak_n_in = 0.0; - float peak_p_out = 0.0; - float peak_n_out = 0.0; - float level_spark = 0.0; - uint32_t n_events = 0; -}; - -// Task internal Status -struct ignitionBoxStatus -{ - int64_t timestamp = 0; - // coils pairs for each ignition - coilsStatus coils12; - coilsStatus coils34; - // voltage from generator - float volts_gen = 0.0; - // enine rpm - uint32_t eng_rpm = 0; - // debug values - uint32_t n_queue_errors = 0; - uint32_t adc_read_time = 0; -}; - struct isrParams { const uint32_t flag; diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 32e7ab0..10c7cac 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -9,7 +9,6 @@ // Definitions #include #include -#include #include #include @@ -51,13 +50,12 @@ void loop() { // global variables bool running = true; - const uint32_t max_history = 1024; + const uint32_t max_queue = 128; - PSRAMVector ignA_history_0(max_history); PSRAMVector ignA_history_1(max_history); - auto &active_history = ignA_history_0; - auto &writable_history = ignA_history_1; + auto *active_history = &ignA_history_0; + auto *writable_history = &ignA_history_1; // Resources Initialization static Devices dev; @@ -177,71 +175,50 @@ void loop() ////////////////////// MAIN LOOP ////////////////////// clearScreen(); setCursor(0, 0); + bool partial_save = false; // flag to indicate if a partial save has been done after a timeout uint32_t counter = 0; - ignitionBoxStatus ignA; + ignitionBoxStatus ign_info; int64_t last = esp_timer_get_time(); uint32_t missed_firings12 = 0; uint32_t missed_firings34 = 0; while (running) { - if (counter == active_history.size()) + if (counter >= active_history->size()) { counter = 0; + partial_save = false; // reset partial save flag on new data cycle std::swap(active_history, writable_history); // switch active and writable buffers + dataSaveParams save_params{ + .history = writable_history, + .file_path = "ignition_history.csv" + }; if (SAVE_HISTORY_TO_SPIFFS) xTaskCreate( saveHistoryTask, "saveHistoryTask", RT_TASK_STACK / 2, - &writable_history, - RT_TASK_PRIORITY + 1, // higher priority to ensure it runs asap after buffer switch + &save_params, + RT_TASK_PRIORITY - 10, // higher priority to ensure it runs asap after buffer switch NULL); } - if (xQueueReceive(rt_taskA_queue, &ignA, pdMS_TO_TICKS(1000)) == pdTRUE) + if (xQueueReceive(rt_taskA_queue, &ign_info, pdMS_TO_TICKS(1000)) == pdTRUE) { - if (ignA.coils12.spark_status == sparkStatus::SPARK_POS_FAIL || ignA.coils12.spark_status == sparkStatus::SPARK_NEG_FAIL) - missed_firings12++; - if (ignA.coils34.spark_status == sparkStatus::SPARK_POS_FAIL || ignA.coils34.spark_status == sparkStatus::SPARK_NEG_FAIL) - missed_firings34++; - - clearScreen(); - setCursor(0, 0); - printField("++ Timestamp", (uint32_t)ignA.timestamp); - Serial.println("========== Coils 12 ============="); - printField("Events", ignA.coils12.n_events); - printField("Missed Firing", missed_firings12); - printField("Spark Dly", (uint32_t)ignA.coils12.spark_delay); - printField("Spark Sts", sparkStatusNames.at(ignA.coils12.spark_status)); - printField("Peak P_IN", ignA.coils12.peak_p_in); - printField("Peak N_IN", ignA.coils12.peak_n_in); - printField("Peak P_OUT", ignA.coils12.peak_p_out); - printField("Peak N_OUT", ignA.coils12.peak_n_out); - printField("Soft Start ", softStartStatusNames.at(ignA.coils12.sstart_status)); - - Serial.println("========== Coils 34 ============="); - printField("Events", ignA.coils34.n_events); - printField("Missed Firing", missed_firings34); - printField("Spark Dly", (uint32_t)ignA.coils34.spark_delay); - printField("Spark Sts", sparkStatusNames.at(ignA.coils34.spark_status)); - printField("Peak P_IN", ignA.coils34.peak_p_in); - printField("Peak N_IN", ignA.coils34.peak_n_in); - printField("Peak P_OUT", ignA.coils34.peak_p_out); - printField("Peak N_OUT", ignA.coils34.peak_n_out); - printField("Soft Start ", softStartStatusNames.at(ignA.coils34.sstart_status)); - - Serial.println("========== END ============="); - Serial.println(); - printField("Engine RPM", ignA.eng_rpm); - printField("ADC Read Time", ignA.adc_read_time); - printField("Queue Errors", ignA.n_queue_errors); - - active_history[counter++ % active_history.size()] = ignA; + printInfo(ign_info); + auto &hist = *active_history; + hist[counter++ % active_history->size()] = ign_info; } else { Serial.println("Waiting for data... "); + if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout + { + counter = 0; // reset counter after saving + partial_save = true; + Serial.println("Saving history to SPIFFS..."); + save_history(*active_history, "ignition_history.csv"); + } delay(500); } } diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index da3eeda..afc3b82 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -230,6 +230,11 @@ void rtIgnitionTask(void *pvParameters) cycle12 = false; cycle34 = false; + if (ign_box_sts.coils12.spark_status == sparkStatus::SPARK_POS_FAIL || ign_box_sts.coils12.spark_status == sparkStatus::SPARK_NEG_FAIL) + ign_box_sts.coils12.n_missed_firing++; + if (ign_box_sts.coils34.spark_status == sparkStatus::SPARK_POS_FAIL || ign_box_sts.coils34.spark_status == sparkStatus::SPARK_NEG_FAIL) + ign_box_sts.coils34.n_missed_firing++; + // read adc channels: pickup12, out12 [ pos + neg ] if (adc) // read only if adc initialized { diff --git a/RotaxMonitor/src/ui.cpp b/RotaxMonitor/src/ui.cpp new file mode 100644 index 0000000..331a339 --- /dev/null +++ b/RotaxMonitor/src/ui.cpp @@ -0,0 +1,68 @@ +#include + +void clearScreen() +{ + Serial.print("\033[2J"); // clear screen + Serial.print("\033[H"); // cursor home + Serial.flush(); +} + +void setCursor(const uint8_t x, const uint8_t y) +{ + Serial.printf("\033[%d;%d", y, x + 1); + Serial.flush(); +} + +void printField(const char name[], const uint32_t val) +{ + Serial.printf("%15s: %06d\n", name, val); +} + +void printField(const char name[], const int64_t val) +{ + Serial.printf("%15s: %06u\n", name, (uint64_t)val); +} + +void printField(const char name[], const float val) +{ + Serial.printf("%15s: %4.2f\n", name, val); +} + +void printField(const char name[], const char *val) +{ + Serial.printf("%15s: %s\n", name, val); +} + +void printInfo(const ignitionBoxStatus &info) +{ + clearScreen(); + setCursor(0, 0); + printField("++ Timestamp ++", (uint32_t)info.timestamp); + Serial.println("========== Coils 12 ============="); + printField("Events", info.coils12.n_events); + printField("Events Missed", info.coils12.n_missed_firing); + printField("Spark Dly", (uint32_t)info.coils12.spark_delay); + printField("Spark Sts", sparkStatusNames.at(info.coils12.spark_status)); + printField("Peak P_IN", info.coils12.peak_p_in); + printField("Peak N_IN", info.coils12.peak_n_in); + printField("Peak P_OUT", info.coils12.peak_p_out); + printField("Peak N_OUT", info.coils12.peak_n_out); + printField("Soft Start ", softStartStatusNames.at(info.coils12.sstart_status)); + + Serial.println("========== Coils 34 ============="); + printField("Events", info.coils34.n_events); + printField("Events Missed", info.coils34.n_missed_firing); + printField("Spark Dly", (uint32_t)info.coils34.spark_delay); + printField("Spark Sts", sparkStatusNames.at(info.coils34.spark_status)); + printField("Peak P_IN", info.coils34.peak_p_in); + printField("Peak N_IN", info.coils34.peak_n_in); + printField("Peak P_OUT", info.coils34.peak_p_out); + printField("Peak N_OUT", info.coils34.peak_n_out); + printField("Soft Start ", softStartStatusNames.at(info.coils34.sstart_status)); + + Serial.println("============ END ==============="); + Serial.println(); + printField("Engine RPM", info.eng_rpm); + printField("ADC Read Time", info.adc_read_time); + printField("Queue Errors", info.n_queue_errors); +} diff --git a/RotaxMonitor/src/ui.h b/RotaxMonitor/src/ui.h index 9c801be..a260e19 100644 --- a/RotaxMonitor/src/ui.h +++ b/RotaxMonitor/src/ui.h @@ -1,36 +1,13 @@ #pragma once #include +#include -void clearScreen() -{ - Serial.print("\033[2J"); // clear screen - Serial.print("\033[H"); // cursor home - Serial.flush(); -} +void clearScreen(); +void setCursor(const uint8_t x, const uint8_t y); +void printField(const char name[], const uint32_t val); +void printField(const char name[], const int64_t val); +void printField(const char name[], const float val); +void printField(const char name[], const char *val); -void setCursor(const uint8_t x, const uint8_t y) -{ - Serial.printf("\033[%d;%d", y, x + 1); - Serial.flush(); -} - -void printField(const char name[], const uint32_t val) -{ - Serial.printf("%15s: %06d\n", name, val); -} - -void printField(const char name[], const int64_t val) -{ - Serial.printf("%15s: %06u\n", name, (uint64_t)val); -} - -void printField(const char name[], const float val) -{ - Serial.printf("%15s: %4.2f\n", name, val); -} - -void printField(const char name[], const char *val) -{ - Serial.printf("%15s: %s\n", name, val); -} \ No newline at end of file +void printInfo(const ignitionBoxStatus &info); \ No newline at end of file diff --git a/RotaxMonitor/src/utils.h b/RotaxMonitor/src/utils.h index 7627292..2a1bf71 100644 --- a/RotaxMonitor/src/utils.h +++ b/RotaxMonitor/src/utils.h @@ -4,10 +4,3 @@ #include std::string printBits(uint32_t value); - -static void saveHistoryTask(void *pvParameters) -{ - auto *history = static_cast *>(pvParameters); - save_history(*history); - vTaskDelete(NULL); -} \ No newline at end of file diff --git a/RotaxMonitor/unpacked_fs/ignA_history.csv b/RotaxMonitor/unpacked_fs/ignA_history.csv index 1a6c67e..8566e14 100644 --- a/RotaxMonitor/unpacked_fs/ignA_history.csv +++ b/RotaxMonitor/unpacked_fs/ignA_history.csv @@ -1,855 +1,858 @@ -TS,EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS -10821894,171,220,SPARK_NEG_OK,0.291874,0.321984,0.352346,0.354453,SOFT_START,171,221,SPARK_NEG_OK,0.356878,0.361823,0.277541,0.004770,SOFT_START,1293,4274,0 -10867894,172,220,SPARK_NEG_OK,0.291641,0.321847,0.352141,0.354271,SOFT_START,172,220,SPARK_NEG_OK,0.356699,0.361621,0.277369,0.004770,SOFT_START,1302,4207,0 -10913894,173,220,SPARK_NEG_OK,0.291452,0.321704,0.351960,0.354081,SOFT_START,173,220,SPARK_NEG_OK,0.356535,0.361444,0.277177,0.004786,SOFT_START,1302,4261,0 -10959894,174,221,SPARK_NEG_OK,0.291214,0.321550,0.351793,0.353897,SOFT_START,174,220,SPARK_NEG_OK,0.356338,0.361255,0.276995,0.004792,SOFT_START,1310,4269,0 -11004895,175,220,SPARK_NEG_OK,0.290992,0.321397,0.351586,0.353711,SOFT_START,175,190,SPARK_NEG_OK,0.356162,0.361081,0.276814,0.004815,SOFT_START,1312,4244,0 -11050894,176,190,SPARK_NEG_OK,0.290810,0.321243,0.351415,0.353529,SOFT_START,176,191,SPARK_NEG_OK,0.355985,0.360872,0.276650,0.004836,SOFT_START,1317,4224,0 -11095894,177,190,SPARK_NEG_OK,0.290591,0.321098,0.351211,0.353335,SOFT_START,177,190,SPARK_NEG_OK,0.355766,0.360683,0.276479,0.004852,SOFT_START,1319,4206,0 -11141894,178,150,SPARK_NEG_OK,0.290401,0.320932,0.351018,0.353144,SOFT_START,178,150,SPARK_NEG_OK,0.355611,0.360506,0.276300,0.004860,SOFT_START,1319,4163,0 -11186894,179,151,SPARK_NEG_OK,0.290195,0.320794,0.350831,0.352983,SOFT_START,179,150,SPARK_NEG_OK,0.355431,0.360326,0.276120,0.004873,SOFT_START,1322,4264,0 -11232894,180,120,SPARK_NEG_OK,0.290006,0.320647,0.350667,0.352789,SOFT_START,180,120,SPARK_NEG_OK,0.355256,0.360150,0.275930,0.004894,SOFT_START,1320,4196,0 -11277894,181,120,SPARK_NEG_OK,0.289753,0.320502,0.350458,0.352589,SOFT_START,181,121,SPARK_NEG_OK,0.355072,0.359924,0.275752,0.004888,SOFT_START,1322,4272,0 -11322894,182,121,SPARK_NEG_OK,0.289555,0.320359,0.350283,0.352405,SOFT_START,182,90,SPARK_NEG_OK,0.354874,0.359756,0.275572,0.004894,SOFT_START,1322,4203,0 -11368894,183,90,SPARK_NEG_OK,0.289374,0.320207,0.350096,0.352215,SOFT_START,183,90,SPARK_NEG_OK,0.354710,0.359569,0.275415,0.004900,SOFT_START,1312,4157,0 -11414894,184,91,SPARK_NEG_OK,0.289163,0.320063,0.349897,0.352047,SOFT_START,184,61,SPARK_NEG_OK,0.354533,0.359383,0.275223,0.004900,SOFT_START,1314,4224,0 -11460894,185,60,SPARK_NEG_OK,0.288991,0.319898,0.349711,0.351868,SOFT_START,185,60,SPARK_NEG_OK,0.354339,0.359212,0.275054,0.004936,SOFT_START,1307,4160,0 -11506894,186,60,SPARK_NEG_OK,0.288769,0.319761,0.349534,0.351666,SOFT_START,186,61,SPARK_NEG_OK,0.354161,0.359017,0.274898,0.004913,SOFT_START,1302,4227,0 -11552894,187,30,SPARK_NEG_OK,0.288572,0.319604,0.349340,0.351484,SOFT_START,187,30,SPARK_NEG_OK,0.353971,0.358836,0.274721,0.004925,SOFT_START,1294,4175,0 -11599894,188,28,SPARK_NEG_OK,0.288355,0.319456,0.349131,0.351307,SOFT_START,188,30,SPARK_NEG_OK,0.353799,0.358637,0.274544,0.004942,SOFT_START,1288,4275,0 -11765894,189,220,SPARK_POS_OK,0.288172,0.319344,0.349020,0.351149,NORMAL,189,220,SPARK_POS_OK,0.353638,0.358481,0.274398,0.004628,NORMAL,1266,4262,0 -11812894,190,221,SPARK_POS_OK,0.287986,0.319201,0.348818,0.350974,NORMAL,190,220,SPARK_POS_OK,0.353460,0.358317,0.274234,0.004650,NORMAL,1259,4216,0 -11861894,191,200,SPARK_POS_OK,0.287738,0.319054,0.348635,0.350789,NORMAL,191,200,SPARK_POS_OK,0.353298,0.358120,0.274066,0.004659,NORMAL,1238,4274,0 -11909894,192,201,SPARK_POS_OK,0.287534,0.318898,0.348458,0.350605,NORMAL,192,200,SPARK_POS_OK,0.353095,0.357934,0.273899,0.004672,NORMAL,1239,4247,0 -11958894,193,170,SPARK_POS_OK,0.287327,0.318753,0.348269,0.350417,NORMAL,193,200,SPARK_POS_OK,0.352935,0.357761,0.273730,0.004690,NORMAL,1227,4264,0 -12007894,194,170,SPARK_POS_OK,0.287136,0.318620,0.348067,0.350251,NORMAL,194,171,SPARK_POS_OK,0.352752,0.357563,0.273559,0.004696,NORMAL,1216,4158,0 -12057894,195,141,SPARK_POS_OK,0.286947,0.318474,0.347898,0.350049,NORMAL,195,170,SPARK_POS_OK,0.352559,0.357398,0.273376,0.004699,NORMAL,1205,4218,0 -12107894,196,140,SPARK_POS_OK,0.286708,0.318314,0.347713,0.349872,NORMAL,196,140,SPARK_POS_OK,0.352387,0.357202,0.273208,0.004697,NORMAL,1195,4280,0 -12158894,197,110,SPARK_POS_OK,0.286518,0.318181,0.347544,0.349692,NORMAL,197,140,SPARK_POS_OK,0.352211,0.357017,0.273015,0.004702,NORMAL,1183,4229,0 -12209894,198,111,SPARK_POS_OK,0.286322,0.318015,0.347342,0.349513,NORMAL,198,110,SPARK_POS_OK,0.352041,0.356835,0.272858,0.004721,NORMAL,1173,4163,0 -12261894,199,90,SPARK_POS_OK,0.286103,0.317878,0.347158,0.349329,NORMAL,199,110,SPARK_POS_OK,0.351862,0.356678,0.272691,0.004691,NORMAL,1161,4237,0 -12313894,200,90,SPARK_POS_OK,0.285903,0.317712,0.346979,0.349131,NORMAL,200,91,SPARK_POS_OK,0.351683,0.356466,0.272512,0.004713,NORMAL,1151,4264,0 -12366894,201,71,SPARK_POS_OK,0.285721,0.317584,0.346802,0.348973,NORMAL,201,92,SPARK_POS_OK,0.351498,0.356287,0.272346,0.004697,NORMAL,1138,4196,0 -12419894,202,71,SPARK_POS_OK,0.285524,0.317419,0.346613,0.348784,NORMAL,202,70,SPARK_POS_OK,0.351300,0.356096,0.272186,0.004708,NORMAL,1126,4156,0 -12473894,203,60,SPARK_POS_OK,0.285331,0.317279,0.346447,0.348594,NORMAL,203,70,SPARK_POS_OK,0.351147,0.355921,0.271999,0.004705,NORMAL,1113,4269,0 -12527894,204,60,SPARK_POS_OK,0.285091,0.317123,0.346253,0.348431,NORMAL,204,61,SPARK_POS_OK,0.350962,0.355725,0.271855,0.004699,NORMAL,1102,4243,0 -12582894,205,60,SPARK_POS_OK,0.284925,0.317021,0.346054,0.348216,NORMAL,205,61,SPARK_POS_OK,0.350796,0.355549,0.271656,0.004687,NORMAL,1091,4195,0 -12638894,206,60,SPARK_POS_OK,0.284721,0.316844,0.345879,0.348051,NORMAL,206,61,SPARK_POS_OK,0.350621,0.355390,0.271497,0.004652,NORMAL,1082,4239,0 -12694894,207,60,SPARK_POS_OK,0.284523,0.316696,0.345726,0.347897,NORMAL,207,61,SPARK_POS_OK,0.350435,0.355192,0.271319,0.004679,NORMAL,1065,4209,0 -12750894,208,60,SPARK_POS_OK,0.284311,0.316560,0.345530,0.347692,NORMAL,208,60,SPARK_POS_OK,0.350261,0.355031,0.271155,0.004650,NORMAL,1066,4228,0 -12807894,209,60,SPARK_POS_OK,0.284136,0.316435,0.345343,0.347521,NORMAL,209,60,SPARK_POS_OK,0.350083,0.354824,0.270969,0.004657,NORMAL,1050,4179,0 -12864894,210,60,SPARK_POS_OK,0.283932,0.316269,0.345162,0.347337,NORMAL,210,60,SPARK_POS_OK,0.349925,0.354653,0.270828,0.004632,NORMAL,1051,4177,0 -12922894,211,70,SPARK_POS_OK,0.283749,0.316133,0.344989,0.347164,NORMAL,211,70,SPARK_POS_OK,0.349733,0.354481,0.270671,0.004617,NORMAL,1034,4180,0 -12981894,212,80,SPARK_POS_OK,0.283555,0.315993,0.344810,0.346988,NORMAL,212,69,SPARK_POS_OK,0.349549,0.354288,0.270514,0.004611,NORMAL,1027,4192,0 -13040894,213,80,SPARK_POS_OK,0.283352,0.315846,0.344626,0.346801,NORMAL,213,81,SPARK_POS_OK,0.349369,0.354108,0.270325,0.004593,NORMAL,1021,4268,0 -13099894,214,90,SPARK_POS_OK,0.283144,0.315697,0.344451,0.346639,NORMAL,214,81,SPARK_POS_OK,0.349219,0.353949,0.270138,0.004584,NORMAL,1015,4275,0 -13158894,215,90,SPARK_POS_OK,0.282967,0.315561,0.344267,0.346466,NORMAL,215,91,SPARK_POS_OK,0.349048,0.353755,0.269985,0.004572,NORMAL,1012,4186,0 -13217894,216,110,SPARK_POS_OK,0.282770,0.315417,0.344096,0.346274,NORMAL,216,110,SPARK_POS_OK,0.348860,0.353565,0.269793,0.004562,NORMAL,1006,4189,0 -13277894,217,111,SPARK_POS_OK,0.282574,0.315275,0.343914,0.346095,NORMAL,217,110,SPARK_POS_OK,0.348682,0.353402,0.269661,0.004547,NORMAL,1007,4241,0 -13337894,218,130,SPARK_POS_OK,0.282375,0.315123,0.343747,0.345913,NORMAL,218,130,SPARK_POS_OK,0.348535,0.353219,0.269510,0.004527,NORMAL,1003,4217,0 -13397894,219,140,SPARK_POS_OK,0.282168,0.314994,0.343540,0.345718,NORMAL,219,130,SPARK_POS_OK,0.348333,0.353041,0.269329,0.004525,NORMAL,1002,4247,0 -13456894,220,140,SPARK_POS_OK,0.281945,0.314833,0.343373,0.345567,NORMAL,220,140,SPARK_POS_OK,0.348171,0.352871,0.269172,0.004499,NORMAL,1002,4246,0 -13516894,221,160,SPARK_POS_OK,0.281780,0.314691,0.343198,0.345380,NORMAL,221,141,SPARK_POS_OK,0.347996,0.352697,0.268990,0.004496,NORMAL,1000,4185,0 -13576894,222,158,SPARK_POS_OK,0.281596,0.314552,0.343024,0.345215,NORMAL,222,161,SPARK_POS_OK,0.347838,0.352506,0.268822,0.004497,NORMAL,1001,4161,0 -13636894,223,181,SPARK_POS_OK,0.281394,0.314416,0.342835,0.345027,NORMAL,223,180,SPARK_POS_OK,0.347647,0.352321,0.268661,0.004486,NORMAL,1004,4179,0 -13696894,224,181,SPARK_POS_OK,0.281194,0.314263,0.342656,0.344863,NORMAL,224,180,SPARK_POS_OK,0.347478,0.352163,0.268500,0.004463,NORMAL,1005,4245,0 -13755894,225,201,SPARK_POS_OK,0.281022,0.314121,0.342464,0.344678,NORMAL,225,200,SPARK_POS_OK,0.347285,0.351969,0.268348,0.004470,NORMAL,1011,4148,0 -13814894,226,220,SPARK_POS_OK,0.280838,0.313963,0.342288,0.344507,NORMAL,226,200,SPARK_POS_OK,0.347126,0.351819,0.268160,0.004444,NORMAL,1015,4167,0 -13873894,227,220,SPARK_POS_OK,0.280629,0.313827,0.342121,0.344330,NORMAL,227,220,SPARK_POS_OK,0.346951,0.351624,0.267985,0.004456,NORMAL,1021,4220,0 -13931894,228,238,SPARK_POS_OK,0.280473,0.313697,0.341949,0.344143,NORMAL,228,221,SPARK_POS_OK,0.346759,0.351441,0.267839,0.004458,NORMAL,1024,4167,0 -13990894,229,240,SPARK_POS_OK,0.280264,0.313526,0.341761,0.343969,NORMAL,229,240,SPARK_POS_OK,0.346602,0.351270,0.267669,0.004433,NORMAL,1029,4269,0 -14047894,230,11,SPARK_NEG_OK,0.280050,0.313401,0.341582,0.343786,SOFT_START,230,12,SPARK_NEG_OK,0.346419,0.351073,0.267512,0.004433,SOFT_START,1032,4255,0 -14105894,231,11,SPARK_NEG_OK,0.279852,0.313249,0.341405,0.343619,SOFT_START,231,12,SPARK_NEG_OK,0.346251,0.350896,0.267332,0.004425,SOFT_START,1038,4181,0 -14162894,232,40,SPARK_NEG_OK,0.279679,0.313119,0.341244,0.343432,SOFT_START,232,41,SPARK_NEG_OK,0.346085,0.350717,0.267166,0.004453,SOFT_START,1049,4176,0 -14219894,233,40,SPARK_NEG_OK,0.279474,0.312965,0.341028,0.343263,SOFT_START,233,41,SPARK_NEG_OK,0.345911,0.350540,0.267016,0.004442,SOFT_START,1050,4248,0 -14275894,234,60,SPARK_NEG_OK,0.279295,0.312825,0.340890,0.343099,SOFT_START,234,61,SPARK_NEG_OK,0.345735,0.350363,0.266851,0.004426,SOFT_START,1065,4198,0 -14331894,235,80,SPARK_NEG_OK,0.279090,0.312679,0.340686,0.342902,SOFT_START,235,61,SPARK_NEG_OK,0.345562,0.350190,0.266668,0.004430,SOFT_START,1074,4207,0 -14387894,236,80,SPARK_NEG_OK,0.278901,0.312548,0.340523,0.342727,SOFT_START,236,81,SPARK_NEG_OK,0.345393,0.350004,0.266502,0.004441,SOFT_START,1084,4221,0 -14441894,237,110,SPARK_NEG_OK,0.278722,0.312400,0.340346,0.342571,SOFT_START,237,80,SPARK_NEG_OK,0.345206,0.349820,0.266361,0.004433,SOFT_START,1092,4190,0 -14496894,238,111,SPARK_NEG_OK,0.278538,0.312257,0.340148,0.342380,SOFT_START,238,110,SPARK_NEG_OK,0.345017,0.349650,0.266191,0.004449,SOFT_START,1102,4163,0 -14550894,239,131,SPARK_NEG_OK,0.278317,0.312113,0.339990,0.342190,SOFT_START,239,110,SPARK_NEG_OK,0.344860,0.349460,0.266011,0.004453,SOFT_START,1110,4260,0 -14603894,240,130,SPARK_NEG_OK,0.278129,0.311985,0.339815,0.342011,SOFT_START,240,130,SPARK_NEG_OK,0.344681,0.349284,0.265859,0.004457,SOFT_START,1121,4219,0 -14656894,241,160,SPARK_NEG_OK,0.277947,0.311831,0.339648,0.341843,SOFT_START,241,130,SPARK_NEG_OK,0.344517,0.349094,0.265678,0.004458,SOFT_START,1131,4210,0 -14709894,242,160,SPARK_NEG_OK,0.277737,0.311708,0.339428,0.341673,SOFT_START,242,160,SPARK_NEG_OK,0.344340,0.348915,0.265509,0.004467,SOFT_START,1143,4259,0 -14761894,243,201,SPARK_NEG_OK,0.277543,0.311542,0.339262,0.341479,SOFT_START,243,160,SPARK_NEG_OK,0.344167,0.348761,0.265323,0.004476,SOFT_START,1154,4244,0 -14812894,244,200,SPARK_NEG_OK,0.277353,0.311390,0.339096,0.341303,SOFT_START,244,200,SPARK_NEG_OK,0.343997,0.348579,0.265188,0.004480,SOFT_START,1168,4206,0 -14863894,245,220,SPARK_NEG_OK,0.277141,0.311238,0.338919,0.341144,SOFT_START,245,201,SPARK_NEG_OK,0.343816,0.348403,0.265033,0.004494,SOFT_START,1179,4250,0 -14914894,246,221,SPARK_NEG_OK,0.276940,0.311101,0.338711,0.340955,SOFT_START,246,220,SPARK_NEG_OK,0.343642,0.348225,0.264858,0.004509,SOFT_START,1193,4254,0 -14963894,247,219,SPARK_NEG_OK,0.276753,0.310962,0.338569,0.340778,SOFT_START,247,220,SPARK_NEG_OK,0.343467,0.348055,0.264688,0.004524,SOFT_START,1204,4171,0 -15013894,248,220,SPARK_NEG_OK,0.276549,0.310797,0.338376,0.340604,SOFT_START,248,221,SPARK_NEG_OK,0.343291,0.347858,0.264544,0.004519,SOFT_START,1217,4238,0 -15062894,249,220,SPARK_NEG_OK,0.276359,0.310670,0.338200,0.340418,SOFT_START,249,220,SPARK_NEG_OK,0.343134,0.347682,0.264333,0.004538,SOFT_START,1227,4279,0 -15110894,250,220,SPARK_NEG_OK,0.276158,0.310534,0.338027,0.340244,SOFT_START,250,221,SPARK_NEG_OK,0.342966,0.347517,0.264202,0.004557,SOFT_START,1239,4249,0 -15158894,251,220,SPARK_NEG_OK,0.275975,0.310376,0.337833,0.340089,SOFT_START,251,221,SPARK_NEG_OK,0.342786,0.347318,0.264034,0.004550,SOFT_START,1239,4172,0 -15206894,252,220,SPARK_NEG_OK,0.275763,0.310252,0.337676,0.339896,SOFT_START,252,220,SPARK_NEG_OK,0.342599,0.347157,0.263843,0.004563,SOFT_START,1258,4282,0 -15254894,253,221,SPARK_NEG_OK,0.275539,0.310127,0.337480,0.339708,SOFT_START,253,222,SPARK_NEG_OK,0.342442,0.346959,0.263690,0.004616,SOFT_START,1259,4254,0 -15301894,254,220,SPARK_NEG_OK,0.275350,0.309954,0.337303,0.339510,SOFT_START,254,220,SPARK_NEG_OK,0.342258,0.346802,0.263526,0.004594,SOFT_START,1278,4273,0 -15347894,255,220,SPARK_NEG_OK,0.275174,0.309796,0.337130,0.339362,SOFT_START,255,220,SPARK_NEG_OK,0.342102,0.346624,0.263355,0.004622,SOFT_START,1280,4205,0 -15394894,256,220,SPARK_NEG_OK,0.274967,0.309659,0.336950,0.339174,SOFT_START,256,221,SPARK_NEG_OK,0.341921,0.346425,0.263182,0.004622,SOFT_START,1297,4237,0 -15440894,257,223,SPARK_NEG_OK,0.274789,0.309511,0.336785,0.338994,SOFT_START,257,220,SPARK_NEG_OK,0.341733,0.346255,0.263042,0.004638,SOFT_START,1299,4182,0 -15486894,258,221,SPARK_NEG_OK,0.274593,0.309373,0.336576,0.338819,SOFT_START,258,221,SPARK_NEG_OK,0.341574,0.346088,0.262862,0.004668,SOFT_START,1305,4208,0 -15531894,259,220,SPARK_NEG_OK,0.274363,0.309222,0.336419,0.338640,SOFT_START,259,220,SPARK_NEG_OK,0.341392,0.345899,0.262686,0.004668,SOFT_START,1313,4277,0 -15577894,260,221,SPARK_NEG_OK,0.274186,0.309085,0.336248,0.338470,SOFT_START,260,220,SPARK_NEG_OK,0.341223,0.345733,0.262538,0.004680,SOFT_START,1318,4237,0 -15622894,261,220,SPARK_NEG_OK,0.273988,0.308942,0.336065,0.338274,SOFT_START,261,221,SPARK_NEG_OK,0.341040,0.345555,0.262377,0.004697,SOFT_START,1326,4191,0 -15667894,262,220,SPARK_NEG_OK,0.273785,0.308786,0.335875,0.338117,SOFT_START,262,220,SPARK_NEG_OK,0.340880,0.345359,0.262205,0.004693,SOFT_START,1326,4279,0 -15712894,263,221,SPARK_NEG_OK,0.273591,0.308653,0.335709,0.337934,SOFT_START,263,221,SPARK_NEG_OK,0.340683,0.345190,0.262039,0.004723,SOFT_START,1337,4203,0 -15757894,264,220,SPARK_NEG_OK,0.273391,0.308498,0.335528,0.337751,SOFT_START,264,220,SPARK_NEG_OK,0.340517,0.345017,0.261879,0.004717,SOFT_START,1338,4179,0 -15802894,265,220,SPARK_NEG_OK,0.273204,0.308351,0.335353,0.337588,SOFT_START,265,220,SPARK_NEG_OK,0.340366,0.344841,0.261700,0.004731,SOFT_START,1341,4241,0 -15846894,266,221,SPARK_NEG_OK,0.273006,0.308197,0.335171,0.337414,SOFT_START,266,221,SPARK_NEG_OK,0.340174,0.344661,0.261554,0.004756,SOFT_START,1347,4230,0 -15891894,267,180,SPARK_NEG_OK,0.272815,0.308082,0.334992,0.337222,SOFT_START,267,220,SPARK_NEG_OK,0.340018,0.344472,0.261397,0.004770,SOFT_START,1347,4268,0 -15935894,268,180,SPARK_NEG_OK,0.272610,0.307922,0.334812,0.337040,SOFT_START,268,180,SPARK_NEG_OK,0.339837,0.344308,0.261219,0.004772,SOFT_START,1350,4241,0 -15980894,269,181,SPARK_NEG_OK,0.272433,0.307770,0.334638,0.336877,SOFT_START,269,181,SPARK_NEG_OK,0.339680,0.344119,0.261047,0.004802,SOFT_START,1350,4210,0 -16024894,270,150,SPARK_NEG_OK,0.272267,0.307639,0.334473,0.336711,SOFT_START,270,148,SPARK_NEG_OK,0.339497,0.343937,0.260897,0.004804,SOFT_START,1347,4244,0 -16069894,271,150,SPARK_NEG_OK,0.272056,0.307497,0.334284,0.336515,SOFT_START,271,150,SPARK_NEG_OK,0.339306,0.343756,0.260709,0.004807,SOFT_START,1348,4158,0 -16113894,272,140,SPARK_NEG_OK,0.271863,0.307337,0.334108,0.336345,SOFT_START,272,151,SPARK_NEG_OK,0.339141,0.343586,0.260540,0.004798,SOFT_START,1345,4239,0 -16158894,273,140,SPARK_NEG_OK,0.271698,0.307201,0.333925,0.336167,SOFT_START,273,140,SPARK_NEG_OK,0.338959,0.343403,0.260389,0.004823,SOFT_START,1345,4167,0 -16203894,274,130,SPARK_NEG_OK,0.271480,0.307058,0.333768,0.335989,SOFT_START,274,140,SPARK_NEG_OK,0.338812,0.343249,0.260221,0.004836,SOFT_START,1342,4271,0 -16247894,275,130,SPARK_NEG_OK,0.271285,0.306922,0.333574,0.335815,SOFT_START,275,131,SPARK_NEG_OK,0.338630,0.343057,0.260075,0.004844,SOFT_START,1342,4232,0 -16292894,276,130,SPARK_NEG_OK,0.271102,0.306773,0.333405,0.335645,SOFT_START,276,130,SPARK_NEG_OK,0.338458,0.342894,0.259930,0.004845,SOFT_START,1342,4194,0 -16337894,277,120,SPARK_NEG_OK,0.270932,0.306615,0.333204,0.335463,SOFT_START,277,120,SPARK_NEG_OK,0.338296,0.342724,0.259750,0.004863,SOFT_START,1337,4147,0 -16382894,278,120,SPARK_NEG_OK,0.270737,0.306486,0.333048,0.335265,SOFT_START,278,121,SPARK_NEG_OK,0.338100,0.342532,0.259584,0.004867,SOFT_START,1339,4276,0 -16426894,279,110,SPARK_NEG_OK,0.270554,0.306343,0.332868,0.335113,SOFT_START,279,120,SPARK_NEG_OK,0.337940,0.342348,0.259439,0.004864,SOFT_START,1335,4170,0 -16471894,280,111,SPARK_NEG_OK,0.270383,0.306209,0.332687,0.334929,SOFT_START,280,110,SPARK_NEG_OK,0.337764,0.342171,0.259267,0.004873,SOFT_START,1335,4177,0 -16517894,281,90,SPARK_NEG_OK,0.270165,0.306048,0.332520,0.334755,SOFT_START,281,110,SPARK_NEG_OK,0.337594,0.341991,0.259075,0.004871,SOFT_START,1329,4272,0 -16562894,282,90,SPARK_NEG_OK,0.269985,0.305896,0.332350,0.334590,SOFT_START,282,91,SPARK_NEG_OK,0.337431,0.341833,0.258943,0.004854,SOFT_START,1326,4247,0 -16607894,283,91,SPARK_NEG_OK,0.269781,0.305758,0.332175,0.334412,SOFT_START,283,91,SPARK_NEG_OK,0.337263,0.341638,0.258790,0.004885,SOFT_START,1326,4220,0 -16653894,284,70,SPARK_NEG_OK,0.269598,0.305635,0.331991,0.334242,SOFT_START,284,72,SPARK_NEG_OK,0.337071,0.341465,0.258601,0.004866,SOFT_START,1312,4258,0 -16698894,285,71,SPARK_NEG_OK,0.269420,0.305482,0.331814,0.334067,SOFT_START,285,70,SPARK_NEG_OK,0.336933,0.341322,0.258471,0.004867,SOFT_START,1313,4192,0 -16744894,286,40,SPARK_NEG_OK,0.269231,0.305305,0.331654,0.333915,SOFT_START,286,41,SPARK_NEG_OK,0.336744,0.341121,0.258281,0.004871,SOFT_START,1299,4180,0 -16791894,287,40,SPARK_NEG_OK,0.269049,0.305214,0.331465,0.333707,SOFT_START,287,40,SPARK_NEG_OK,0.336584,0.340940,0.258129,0.004892,SOFT_START,1300,4187,0 -16837894,288,30,SPARK_NEG_OK,0.268874,0.305048,0.331298,0.333550,SOFT_START,288,41,SPARK_NEG_OK,0.336404,0.340771,0.257971,0.004876,SOFT_START,1293,4201,0 -16884894,289,30,SPARK_NEG_OK,0.268696,0.304921,0.331123,0.333374,SOFT_START,289,30,SPARK_NEG_OK,0.336235,0.340590,0.257808,0.004873,SOFT_START,1288,4174,0 -16930894,290,12,SPARK_NEG_OK,0.268512,0.304756,0.330947,0.333184,SOFT_START,290,30,SPARK_NEG_OK,0.336077,0.340421,0.257648,0.004867,SOFT_START,1280,4275,0 -16977894,291,11,SPARK_NEG_OK,0.268307,0.304621,0.330780,0.333019,SOFT_START,291,11,SPARK_NEG_OK,0.335906,0.340248,0.257477,0.004886,SOFT_START,1275,4182,0 -17024894,292,12,SPARK_NEG_OK,0.268142,0.304487,0.330597,0.332844,SOFT_START,292,11,SPARK_NEG_OK,0.335712,0.340078,0.257326,0.004880,SOFT_START,1275,4223,0 -17073894,293,240,SPARK_POS_OK,0.267931,0.304347,0.330408,0.332662,NORMAL,293,240,SPARK_POS_OK,0.335556,0.339900,0.257170,0.004864,NORMAL,1265,4283,0 -17120894,294,241,SPARK_POS_OK,0.267733,0.304181,0.330238,0.332494,NORMAL,294,240,SPARK_POS_OK,0.335385,0.339734,0.257022,0.004860,NORMAL,1259,4237,0 -17169894,295,210,SPARK_POS_OK,0.267549,0.304050,0.330071,0.332329,NORMAL,295,210,SPARK_POS_OK,0.335230,0.339558,0.256847,0.004850,NORMAL,1240,4221,0 -17217894,296,211,SPARK_POS_OK,0.267379,0.303919,0.329908,0.332153,NORMAL,296,210,SPARK_POS_OK,0.335050,0.339391,0.256687,0.004830,NORMAL,1240,4255,0 -17266894,297,190,SPARK_POS_OK,0.267209,0.303771,0.329717,0.331997,NORMAL,297,190,SPARK_POS_OK,0.334877,0.339213,0.256514,0.004860,NORMAL,1221,4165,0 -17315894,298,190,SPARK_POS_OK,0.266992,0.303644,0.329559,0.331809,NORMAL,298,191,SPARK_POS_OK,0.334710,0.339048,0.256393,0.004833,NORMAL,1221,4259,0 -17365894,299,160,SPARK_POS_OK,0.266833,0.303503,0.329363,0.331661,NORMAL,299,190,SPARK_POS_OK,0.334555,0.338853,0.256221,0.004839,NORMAL,1212,4189,0 -17415894,300,160,SPARK_POS_OK,0.266654,0.303344,0.329211,0.331482,NORMAL,300,161,SPARK_POS_OK,0.334383,0.338693,0.256031,0.004812,NORMAL,1203,4190,0 -17465894,301,141,SPARK_POS_OK,0.266449,0.303210,0.329055,0.331288,NORMAL,301,160,SPARK_POS_OK,0.334225,0.338532,0.255885,0.004814,NORMAL,1193,4273,0 -17516894,302,140,SPARK_POS_OK,0.266245,0.303064,0.328864,0.331123,NORMAL,302,140,SPARK_POS_OK,0.334033,0.338354,0.255737,0.004802,NORMAL,1184,4273,0 -17567894,303,110,SPARK_POS_OK,0.266058,0.302920,0.328710,0.330976,NORMAL,303,141,SPARK_POS_OK,0.333868,0.338184,0.255600,0.004779,NORMAL,1172,4268,0 -17619894,304,110,SPARK_POS_OK,0.265878,0.302792,0.328532,0.330778,NORMAL,304,110,SPARK_POS_OK,0.333710,0.338012,0.255402,0.004783,NORMAL,1161,4227,0 -17671894,305,81,SPARK_POS_OK,0.265690,0.302648,0.328369,0.330619,NORMAL,305,110,SPARK_POS_OK,0.333537,0.337849,0.255261,0.004770,NORMAL,1148,4232,0 -17724894,306,80,SPARK_POS_OK,0.265476,0.302500,0.328174,0.330463,NORMAL,306,80,SPARK_POS_OK,0.333378,0.337679,0.255098,0.004752,NORMAL,1137,4264,0 -17777894,307,60,SPARK_POS_OK,0.265328,0.302365,0.328012,0.330285,NORMAL,307,81,SPARK_POS_OK,0.333213,0.337498,0.254948,0.004761,NORMAL,1123,4191,0 -17831894,308,60,SPARK_POS_OK,0.265142,0.302238,0.327851,0.330095,NORMAL,308,61,SPARK_POS_OK,0.333058,0.337338,0.254792,0.004728,NORMAL,1112,4244,0 -17885894,309,30,SPARK_POS_OK,0.264945,0.302092,0.327675,0.329918,NORMAL,309,60,SPARK_POS_OK,0.332888,0.337162,0.254622,0.004697,NORMAL,1100,4201,0 -17941894,310,31,SPARK_POS_OK,0.264768,0.301954,0.327485,0.329756,NORMAL,310,30,SPARK_POS_OK,0.332726,0.336969,0.254484,0.004701,NORMAL,1088,4164,0 -17997894,311,12,SPARK_POS_OK,0.264581,0.301821,0.327319,0.329586,NORMAL,311,30,SPARK_POS_OK,0.332555,0.336813,0.254331,0.004685,NORMAL,1065,4223,0 -18053894,312,12,SPARK_POS_OK,0.264429,0.301675,0.327158,0.329433,NORMAL,312,11,SPARK_POS_OK,0.332391,0.336652,0.254169,0.004653,NORMAL,1066,4203,0 -18111894,313,12,SPARK_POS_OK,0.264220,0.301539,0.326988,0.329242,NORMAL,313,11,SPARK_POS_OK,0.332209,0.336474,0.254010,0.004625,NORMAL,1066,4239,0 -18168897,314,12,SPARK_POS_OK,0.264052,0.301399,0.326822,0.329088,NORMAL,314,11,SPARK_POS_OK,0.332057,0.336303,0.253870,0.004619,NORMAL,1066,4191,0 -18228894,315,12,SPARK_POS_OK,0.263894,0.301248,0.326648,0.328944,NORMAL,315,11,SPARK_POS_OK,0.331897,0.336123,0.253718,0.004594,NORMAL,1066,4234,0 -18287894,316,12,SPARK_POS_OK,0.263721,0.301127,0.326463,0.328761,NORMAL,316,11,SPARK_POS_OK,0.331728,0.335987,0.253572,0.004570,NORMAL,1066,4157,0 -18348894,317,12,SPARK_POS_OK,0.263575,0.300995,0.326326,0.328572,NORMAL,317,11,SPARK_POS_OK,0.331570,0.335803,0.253413,0.004551,NORMAL,1066,4152,0 -18409894,318,12,SPARK_POS_OK,0.263376,0.300867,0.326142,0.328431,NORMAL,318,11,SPARK_POS_OK,0.331399,0.335646,0.253223,0.004531,NORMAL,1066,4212,0 -18470894,319,12,SPARK_POS_OK,0.263219,0.300716,0.325989,0.328241,NORMAL,319,11,SPARK_POS_OK,0.331234,0.335476,0.253085,0.004523,NORMAL,1066,4170,0 -18533894,320,12,SPARK_POS_OK,0.263063,0.300580,0.325815,0.328078,NORMAL,320,11,SPARK_POS_OK,0.331081,0.335301,0.252938,0.004483,NORMAL,1066,4166,0 -18596894,321,12,SPARK_POS_OK,0.262910,0.300453,0.325649,0.327910,NORMAL,321,11,SPARK_POS_OK,0.330916,0.335144,0.252804,0.004457,NORMAL,1066,4165,0 -18660894,322,12,SPARK_POS_OK,0.262725,0.300310,0.325455,0.327746,NORMAL,322,11,SPARK_POS_OK,0.330752,0.334975,0.252672,0.004439,NORMAL,1066,4218,0 -18724894,323,12,SPARK_POS_OK,0.262533,0.300167,0.325316,0.327597,NORMAL,323,11,SPARK_POS_OK,0.330575,0.334817,0.252523,0.004401,NORMAL,1066,4189,0 -18788894,324,12,SPARK_POS_OK,0.262383,0.300050,0.325135,0.327423,NORMAL,324,11,SPARK_POS_OK,0.330424,0.334643,0.252364,0.004385,NORMAL,1066,4180,0 -18853894,325,31,SPARK_POS_OK,0.262214,0.299909,0.324991,0.327273,NORMAL,325,30,SPARK_POS_OK,0.330254,0.334481,0.252185,0.004376,NORMAL,75,4155,0 -18918894,326,60,SPARK_POS_OK,0.262047,0.299770,0.324814,0.327099,NORMAL,326,30,SPARK_POS_OK,0.330110,0.334322,0.252017,0.004348,NORMAL,922,4204,0 -18983894,327,61,SPARK_POS_OK,0.261842,0.299639,0.324641,0.326945,NORMAL,327,61,SPARK_POS_OK,0.329948,0.334149,0.251907,0.004337,NORMAL,922,4242,0 -19048894,328,70,SPARK_POS_OK,0.261689,0.299488,0.324500,0.326771,NORMAL,328,70,SPARK_POS_OK,0.329792,0.333999,0.251749,0.004326,NORMAL,923,4197,0 -19113894,329,99,SPARK_POS_OK,0.261513,0.299374,0.324318,0.326604,NORMAL,329,71,SPARK_POS_OK,0.329626,0.333806,0.251604,0.004297,NORMAL,923,4211,0 -19178894,330,101,SPARK_POS_OK,0.261340,0.299222,0.324141,0.326428,NORMAL,330,100,SPARK_POS_OK,0.329466,0.333648,0.251442,0.004287,NORMAL,925,4204,0 -19242894,331,140,SPARK_POS_OK,0.261175,0.299098,0.323993,0.326282,NORMAL,331,100,SPARK_POS_OK,0.329297,0.333476,0.251278,0.004270,NORMAL,927,4203,0 -19307894,332,141,SPARK_POS_OK,0.261015,0.298949,0.323822,0.326133,NORMAL,332,140,SPARK_POS_OK,0.329157,0.333326,0.251157,0.004254,NORMAL,931,4168,0 -19370894,333,180,SPARK_POS_OK,0.260856,0.298833,0.323690,0.325951,NORMAL,333,180,SPARK_POS_OK,0.328997,0.333153,0.251002,0.004216,NORMAL,941,4190,0 -19434894,334,220,SPARK_POS_OK,0.260683,0.298681,0.323502,0.325797,NORMAL,334,180,SPARK_POS_OK,0.328824,0.333012,0.250846,0.004238,NORMAL,949,4212,0 -19496894,335,220,SPARK_POS_OK,0.260522,0.298552,0.323358,0.325621,NORMAL,335,220,SPARK_POS_OK,0.328658,0.332820,0.250706,0.004205,NORMAL,958,4157,0 -19558894,336,11,SPARK_NEG_OK,0.260323,0.298428,0.323166,0.325444,SOFT_START,336,12,SPARK_NEG_OK,0.328495,0.332637,0.250533,0.004199,SOFT_START,964,4228,0 -19619894,337,11,SPARK_NEG_OK,0.260170,0.298282,0.323004,0.325284,SOFT_START,337,11,SPARK_NEG_OK,0.328336,0.332501,0.250398,0.004202,SOFT_START,979,4179,0 -19679894,338,40,SPARK_NEG_OK,0.259990,0.298154,0.322841,0.325130,SOFT_START,338,41,SPARK_NEG_OK,0.328166,0.332343,0.250236,0.004218,SOFT_START,999,4268,0 -19738894,339,80,SPARK_NEG_OK,0.259811,0.298021,0.322664,0.324945,SOFT_START,339,41,SPARK_NEG_OK,0.328009,0.332161,0.250092,0.004217,SOFT_START,1010,4162,0 -19797894,340,83,SPARK_NEG_OK,0.259663,0.297867,0.322503,0.324783,SOFT_START,340,80,SPARK_NEG_OK,0.327846,0.332021,0.249950,0.004224,SOFT_START,1021,4232,0 -19855894,341,110,SPARK_NEG_OK,0.259460,0.297735,0.322354,0.324625,SOFT_START,341,80,SPARK_NEG_OK,0.327682,0.331861,0.249802,0.004217,SOFT_START,1033,4260,0 -19912899,342,110,SPARK_NEG_OK,0.259243,0.297609,0.322173,0.324457,SOFT_START,342,110,SPARK_NEG_OK,0.327532,0.331677,0.249640,0.004229,SOFT_START,1046,4266,0 -19969894,343,140,SPARK_NEG_OK,0.259082,0.297482,0.322000,0.324315,SOFT_START,343,110,SPARK_NEG_OK,0.327353,0.331500,0.249475,0.004230,SOFT_START,1059,4277,0 -20025894,344,140,SPARK_NEG_OK,0.258904,0.297315,0.321835,0.324124,SOFT_START,344,140,SPARK_NEG_OK,0.327191,0.331320,0.249317,0.004232,SOFT_START,1074,4183,0 -20079894,345,170,SPARK_NEG_OK,0.258722,0.297176,0.321677,0.323954,SOFT_START,345,170,SPARK_NEG_OK,0.327038,0.331159,0.249147,0.004234,SOFT_START,1104,4216,0 -20134894,346,170,SPARK_NEG_OK,0.258553,0.297052,0.321513,0.323796,SOFT_START,346,171,SPARK_NEG_OK,0.326892,0.331004,0.249031,0.004253,SOFT_START,1105,4196,0 -20186894,347,210,SPARK_NEG_OK,0.258387,0.296900,0.321335,0.323642,SOFT_START,347,210,SPARK_NEG_OK,0.326720,0.330830,0.248892,0.004249,SOFT_START,1133,4172,0 -20239894,348,211,SPARK_NEG_OK,0.258192,0.296764,0.321176,0.323435,SOFT_START,348,209,SPARK_NEG_OK,0.326536,0.330669,0.248723,0.004274,SOFT_START,1135,4239,0 -20291894,349,222,SPARK_NEG_OK,0.258071,0.296631,0.321015,0.323313,SOFT_START,349,220,SPARK_NEG_OK,0.326385,0.330530,0.248555,0.004287,SOFT_START,1161,4170,0 -20343894,350,220,SPARK_NEG_OK,0.257885,0.296487,0.320839,0.323126,SOFT_START,350,221,SPARK_NEG_OK,0.326209,0.330343,0.248409,0.004294,SOFT_START,1162,4166,0 -20393894,351,221,SPARK_NEG_OK,0.257689,0.296348,0.320674,0.322964,SOFT_START,351,220,SPARK_NEG_OK,0.326070,0.330162,0.248275,0.004317,SOFT_START,1189,4243,0 -20444894,352,220,SPARK_NEG_OK,0.257528,0.296219,0.320523,0.322800,SOFT_START,352,220,SPARK_NEG_OK,0.325900,0.329998,0.248111,0.004302,SOFT_START,1190,4243,0 -20493894,353,220,SPARK_NEG_OK,0.257332,0.296090,0.320352,0.322620,SOFT_START,353,221,SPARK_NEG_OK,0.325734,0.329834,0.247976,0.004354,SOFT_START,1216,4255,0 -20542894,354,220,SPARK_NEG_OK,0.257193,0.295956,0.320160,0.322452,SOFT_START,354,220,SPARK_NEG_OK,0.325580,0.329660,0.247832,0.004338,SOFT_START,1217,4187,0 -20591894,355,220,SPARK_NEG_OK,0.257006,0.295811,0.320002,0.322289,SOFT_START,355,222,SPARK_NEG_OK,0.325417,0.329492,0.247651,0.004367,SOFT_START,1229,4172,0 -20639894,356,221,SPARK_NEG_OK,0.256846,0.295683,0.319828,0.322133,SOFT_START,356,220,SPARK_NEG_OK,0.325261,0.329328,0.247501,0.004339,SOFT_START,1243,4173,0 -20687894,357,222,SPARK_NEG_OK,0.256677,0.295523,0.319645,0.321972,SOFT_START,357,218,SPARK_NEG_OK,0.325086,0.329163,0.247350,0.004399,SOFT_START,1252,4254,0 -20735894,358,221,SPARK_NEG_OK,0.256487,0.295391,0.319504,0.321789,SOFT_START,358,220,SPARK_NEG_OK,0.324938,0.329013,0.247198,0.004386,SOFT_START,1264,4257,0 -20782894,359,220,SPARK_NEG_OK,0.256309,0.295264,0.319327,0.321630,SOFT_START,359,220,SPARK_NEG_OK,0.324761,0.328816,0.247033,0.004420,SOFT_START,1271,4271,0 -20829894,360,221,SPARK_NEG_OK,0.256101,0.295115,0.319163,0.321459,SOFT_START,360,220,SPARK_NEG_OK,0.324587,0.328664,0.246886,0.004438,SOFT_START,1281,4264,0 -20875894,361,220,SPARK_NEG_OK,0.255911,0.294976,0.318999,0.321298,SOFT_START,361,220,SPARK_NEG_OK,0.324433,0.328503,0.246757,0.004437,SOFT_START,1281,4259,0 -20922894,362,220,SPARK_NEG_OK,0.255751,0.294830,0.318828,0.321140,SOFT_START,362,220,SPARK_NEG_OK,0.324269,0.328309,0.246596,0.004463,SOFT_START,1296,4230,0 -20968894,363,220,SPARK_NEG_OK,0.255544,0.294704,0.318658,0.320951,SOFT_START,363,221,SPARK_NEG_OK,0.324112,0.328156,0.246429,0.004478,SOFT_START,1297,4251,0 -21013894,364,220,SPARK_NEG_OK,0.255378,0.294563,0.318509,0.320779,SOFT_START,364,220,SPARK_NEG_OK,0.323953,0.327988,0.246264,0.004461,SOFT_START,1313,4155,0 -21059894,365,221,SPARK_NEG_OK,0.255207,0.294417,0.318331,0.320619,SOFT_START,365,220,SPARK_NEG_OK,0.323799,0.327819,0.246127,0.004505,SOFT_START,1314,4242,0 -21105894,366,220,SPARK_NEG_OK,0.255017,0.294299,0.318168,0.320468,SOFT_START,366,220,SPARK_NEG_OK,0.323625,0.327657,0.245991,0.004532,SOFT_START,1320,4253,0 -21150894,367,220,SPARK_NEG_OK,0.254884,0.294146,0.318006,0.320298,SOFT_START,367,220,SPARK_NEG_OK,0.323460,0.327480,0.245815,0.004519,SOFT_START,1328,4154,0 -21195894,368,210,SPARK_NEG_OK,0.254679,0.294014,0.317810,0.320133,SOFT_START,368,221,SPARK_NEG_OK,0.323297,0.327337,0.245692,0.004536,SOFT_START,1330,4259,0 -21240894,369,210,SPARK_NEG_OK,0.254503,0.293881,0.317658,0.319958,SOFT_START,369,210,SPARK_NEG_OK,0.323118,0.327151,0.245520,0.004557,SOFT_START,1335,4247,0 -21285894,370,211,SPARK_NEG_OK,0.254315,0.293742,0.317503,0.319797,SOFT_START,370,208,SPARK_NEG_OK,0.322980,0.326989,0.245395,0.004555,SOFT_START,1335,4234,0 -21330894,371,160,SPARK_NEG_OK,0.254148,0.293601,0.317314,0.319611,SOFT_START,371,161,SPARK_NEG_OK,0.322809,0.326823,0.245209,0.004575,SOFT_START,1333,4216,0 -21375894,372,160,SPARK_NEG_OK,0.253989,0.293456,0.317158,0.319450,SOFT_START,372,160,SPARK_NEG_OK,0.322645,0.326669,0.245063,0.004587,SOFT_START,1335,4210,0 -21420894,373,131,SPARK_NEG_OK,0.253763,0.293311,0.317000,0.319297,SOFT_START,373,161,SPARK_NEG_OK,0.322486,0.326477,0.244898,0.004608,SOFT_START,1331,4250,0 -21465894,374,130,SPARK_NEG_OK,0.253583,0.293167,0.316819,0.319125,SOFT_START,374,130,SPARK_NEG_OK,0.322325,0.326326,0.244773,0.004621,SOFT_START,1331,4251,0 -21510894,375,100,SPARK_NEG_OK,0.253405,0.293046,0.316660,0.318956,SOFT_START,375,130,SPARK_NEG_OK,0.322174,0.326158,0.244617,0.004613,SOFT_START,1326,4256,0 -21555894,376,98,SPARK_NEG_OK,0.253240,0.292909,0.316489,0.318796,SOFT_START,376,101,SPARK_NEG_OK,0.321996,0.325991,0.244480,0.004627,SOFT_START,1324,4171,0 -21601894,377,100,SPARK_NEG_OK,0.253084,0.292753,0.316325,0.318621,SOFT_START,377,100,SPARK_NEG_OK,0.321842,0.325828,0.244313,0.004628,SOFT_START,1325,4224,0 -21646894,378,71,SPARK_NEG_OK,0.252927,0.292641,0.316149,0.318452,SOFT_START,378,70,SPARK_NEG_OK,0.321690,0.325672,0.244193,0.004615,SOFT_START,1314,4211,0 -21692894,379,70,SPARK_NEG_OK,0.252713,0.292499,0.315984,0.318302,SOFT_START,379,71,SPARK_NEG_OK,0.321518,0.325484,0.243992,0.004643,SOFT_START,1316,4226,0 -21738894,380,44,SPARK_NEG_OK,0.252571,0.292348,0.315827,0.318130,SOFT_START,380,40,SPARK_NEG_OK,0.321364,0.325325,0.243841,0.004649,SOFT_START,1302,4176,0 -21784894,381,41,SPARK_NEG_OK,0.252412,0.292211,0.315657,0.317964,SOFT_START,381,41,SPARK_NEG_OK,0.321205,0.325164,0.243707,0.004649,SOFT_START,1303,4154,0 -21830894,382,25,SPARK_NEG_OK,0.252232,0.292082,0.315511,0.317797,SOFT_START,382,40,SPARK_NEG_OK,0.321046,0.325002,0.243568,0.004656,SOFT_START,1294,4204,0 -21877894,383,25,SPARK_NEG_OK,0.252066,0.291921,0.315345,0.317625,SOFT_START,383,25,SPARK_NEG_OK,0.320892,0.324832,0.243430,0.004650,SOFT_START,1287,4265,0 -22066894,384,221,SPARK_POS_OK,0.251943,0.291840,0.315213,0.317532,NORMAL,385,220,SPARK_POS_OK,0.320773,0.324718,0.243290,0.004334,NORMAL,1260,4187,0 -22114894,385,220,SPARK_POS_OK,0.251784,0.291713,0.315040,0.317362,NORMAL,386,220,SPARK_POS_OK,0.320596,0.324549,0.243174,0.004328,NORMAL,1254,4207,0 -22163894,386,201,SPARK_POS_OK,0.251599,0.291560,0.314904,0.317187,NORMAL,387,200,SPARK_POS_OK,0.320437,0.324401,0.243008,0.004365,NORMAL,1237,4244,0 -22211894,387,200,SPARK_POS_OK,0.251435,0.291431,0.314730,0.317033,NORMAL,388,200,SPARK_POS_OK,0.320293,0.324231,0.242876,0.004377,NORMAL,1238,4199,0 -22260894,388,201,SPARK_POS_OK,0.251231,0.291277,0.314555,0.316856,NORMAL,389,200,SPARK_POS_OK,0.320131,0.324057,0.242704,0.004392,NORMAL,1220,4242,0 -22310894,389,200,SPARK_POS_OK,0.251068,0.291168,0.314403,0.316711,NORMAL,390,200,SPARK_POS_OK,0.319960,0.323902,0.242588,0.004395,NORMAL,1221,4206,0 -22359894,390,200,SPARK_POS_OK,0.250910,0.291023,0.314248,0.316540,NORMAL,391,201,SPARK_POS_OK,0.319814,0.323752,0.242434,0.004389,NORMAL,1212,4163,0 -22409894,391,201,SPARK_POS_OK,0.250749,0.290879,0.314057,0.316370,NORMAL,392,200,SPARK_POS_OK,0.319641,0.323569,0.242269,0.004386,NORMAL,1204,4223,0 -22459894,392,200,SPARK_POS_OK,0.250592,0.290762,0.313917,0.316202,NORMAL,393,200,SPARK_POS_OK,0.319495,0.323399,0.242125,0.004408,NORMAL,1195,4181,0 -22510894,393,200,SPARK_POS_OK,0.250397,0.290606,0.313741,0.316054,NORMAL,394,200,SPARK_POS_OK,0.319328,0.323240,0.241963,0.004426,NORMAL,1189,4274,0 -22560894,394,180,SPARK_POS_OK,0.250229,0.290475,0.313578,0.315884,NORMAL,395,200,SPARK_POS_OK,0.319164,0.323087,0.241815,0.004414,NORMAL,1182,4152,0 -22611894,395,180,SPARK_POS_OK,0.250061,0.290341,0.313404,0.315724,NORMAL,396,180,SPARK_POS_OK,0.319005,0.322919,0.241695,0.004420,NORMAL,1176,4214,0 -22663894,396,160,SPARK_POS_OK,0.249893,0.290205,0.313265,0.315571,NORMAL,397,180,SPARK_POS_OK,0.318839,0.322757,0.241555,0.004427,NORMAL,1168,4185,0 -22714894,397,161,SPARK_POS_OK,0.249780,0.290083,0.313102,0.315400,NORMAL,398,160,SPARK_POS_OK,0.318682,0.322593,0.241399,0.004421,NORMAL,1162,4158,0 -22766894,398,130,SPARK_POS_OK,0.249581,0.289944,0.312937,0.315239,NORMAL,399,160,SPARK_POS_OK,0.318528,0.322440,0.241244,0.004424,NORMAL,1153,4225,0 -22819894,399,130,SPARK_POS_OK,0.249429,0.289794,0.312774,0.315065,NORMAL,400,131,SPARK_POS_OK,0.318367,0.322250,0.241141,0.004423,NORMAL,1144,4219,0 -22872894,400,100,SPARK_POS_OK,0.249244,0.289667,0.312595,0.314922,NORMAL,401,130,SPARK_POS_OK,0.318213,0.322106,0.240951,0.004418,NORMAL,1133,4205,0 -22925894,401,101,SPARK_POS_OK,0.249118,0.289536,0.312445,0.314752,NORMAL,402,100,SPARK_POS_OK,0.318076,0.321957,0.240791,0.004417,NORMAL,1123,4152,0 -22979894,402,80,SPARK_POS_OK,0.248949,0.289407,0.312278,0.314587,NORMAL,403,100,SPARK_POS_OK,0.317907,0.321783,0.240674,0.004404,NORMAL,1112,4195,0 -23033894,403,80,SPARK_POS_OK,0.248800,0.289295,0.312135,0.314437,NORMAL,404,80,SPARK_POS_OK,0.317755,0.321617,0.240517,0.004391,NORMAL,1102,4169,0 -23088894,404,60,SPARK_POS_OK,0.248595,0.289129,0.311957,0.314260,NORMAL,405,81,SPARK_POS_OK,0.317606,0.321452,0.240378,0.004416,NORMAL,1092,4277,0 -23144894,405,58,SPARK_POS_OK,0.248428,0.288990,0.311789,0.314125,NORMAL,406,61,SPARK_POS_OK,0.317430,0.321298,0.240227,0.004388,NORMAL,1083,4216,0 -23200894,406,40,SPARK_POS_OK,0.248251,0.288861,0.311638,0.313944,NORMAL,407,41,SPARK_POS_OK,0.317273,0.321144,0.240096,0.004374,NORMAL,1063,4187,0 -23257894,407,40,SPARK_POS_OK,0.248116,0.288737,0.311475,0.313795,NORMAL,408,41,SPARK_POS_OK,0.317137,0.320997,0.239952,0.004364,NORMAL,1064,4201,0 -23314894,408,11,SPARK_POS_OK,0.247964,0.288606,0.311311,0.313634,NORMAL,409,11,SPARK_POS_OK,0.316954,0.320822,0.239804,0.004355,NORMAL,1041,4163,0 -23372894,409,10,SPARK_POS_OK,0.247810,0.288470,0.311150,0.313477,NORMAL,410,11,SPARK_POS_OK,0.316814,0.320682,0.239655,0.004355,NORMAL,1041,4174,0 -23431894,410,10,SPARK_POS_OK,0.247661,0.288334,0.310993,0.313318,NORMAL,411,11,SPARK_POS_OK,0.316665,0.320500,0.239493,0.004331,NORMAL,1041,4184,0 -23491894,411,10,SPARK_POS_OK,0.247477,0.288216,0.310840,0.313165,NORMAL,412,11,SPARK_POS_OK,0.316504,0.320349,0.239373,0.004325,NORMAL,1041,4180,0 -23551894,412,10,SPARK_POS_OK,0.247323,0.288085,0.310678,0.312979,NORMAL,413,11,SPARK_POS_OK,0.316359,0.320181,0.239230,0.004309,NORMAL,1041,4213,0 -23612894,413,10,SPARK_POS_OK,0.247186,0.287938,0.310524,0.312859,NORMAL,414,11,SPARK_POS_OK,0.316190,0.320023,0.239092,0.004290,NORMAL,1041,4169,0 -23673894,414,10,SPARK_POS_OK,0.246977,0.287805,0.310360,0.312675,NORMAL,415,11,SPARK_POS_OK,0.316062,0.319877,0.238933,0.004276,NORMAL,1041,4281,0 -23736894,415,10,SPARK_POS_OK,0.246847,0.287696,0.310220,0.312530,NORMAL,416,11,SPARK_POS_OK,0.315886,0.319724,0.238806,0.004281,NORMAL,1041,4222,0 -23799894,416,10,SPARK_POS_OK,0.246696,0.287563,0.310060,0.312370,NORMAL,417,11,SPARK_POS_OK,0.315736,0.319582,0.238660,0.004261,NORMAL,1041,4168,0 -23862894,417,10,SPARK_POS_OK,0.246543,0.287425,0.309901,0.312217,NORMAL,418,11,SPARK_POS_OK,0.315586,0.319396,0.238518,0.004233,NORMAL,1041,4165,0 -23926894,418,10,SPARK_POS_OK,0.246392,0.287284,0.309759,0.312039,NORMAL,419,11,SPARK_POS_OK,0.315444,0.319242,0.238376,0.004227,NORMAL,1041,4222,0 -23991894,419,10,SPARK_POS_OK,0.246216,0.287178,0.309595,0.311915,NORMAL,420,11,SPARK_POS_OK,0.315268,0.319102,0.238240,0.004210,NORMAL,1041,4167,0 -24056894,420,10,SPARK_POS_OK,0.246093,0.287024,0.309426,0.311732,NORMAL,421,11,SPARK_POS_OK,0.315140,0.318957,0.238119,0.004194,NORMAL,1041,4169,0 -24122894,421,11,SPARK_POS_OK,0.245922,0.286901,0.309296,0.311624,NORMAL,422,11,SPARK_POS_OK,0.314963,0.318786,0.237943,0.004176,NORMAL,79,4187,0 -24188894,422,11,SPARK_POS_OK,0.245771,0.286802,0.309132,0.311439,NORMAL,423,11,SPARK_POS_OK,0.314819,0.318629,0.237815,0.004169,NORMAL,908,4273,0 -24255894,423,31,SPARK_POS_OK,0.245610,0.286642,0.308980,0.311305,NORMAL,424,31,SPARK_POS_OK,0.314688,0.318487,0.237675,0.004144,NORMAL,904,4240,0 -24321894,424,40,SPARK_POS_OK,0.245454,0.286503,0.308827,0.311134,NORMAL,425,30,SPARK_POS_OK,0.314520,0.318360,0.237542,0.004140,NORMAL,903,4243,0 -24388894,425,41,SPARK_POS_OK,0.245271,0.286397,0.308676,0.310984,NORMAL,426,41,SPARK_POS_OK,0.314375,0.318177,0.237422,0.004111,NORMAL,903,4200,0 -24454894,426,70,SPARK_POS_OK,0.245160,0.286249,0.308500,0.310826,NORMAL,427,70,SPARK_POS_OK,0.314231,0.317993,0.237269,0.004092,NORMAL,900,4149,0 -24521894,427,100,SPARK_POS_OK,0.244949,0.286124,0.308365,0.310673,NORMAL,428,71,SPARK_POS_OK,0.314102,0.317850,0.237157,0.004083,NORMAL,902,4243,0 -24587894,428,100,SPARK_POS_OK,0.244780,0.286021,0.308192,0.310531,NORMAL,429,100,SPARK_POS_OK,0.313907,0.317709,0.236992,0.004075,NORMAL,905,4262,0 -24653894,429,140,SPARK_POS_OK,0.244631,0.285877,0.308051,0.310360,NORMAL,430,101,SPARK_POS_OK,0.313776,0.317557,0.236880,0.004052,NORMAL,909,4190,0 -24718894,430,140,SPARK_POS_OK,0.244453,0.285752,0.307893,0.310200,NORMAL,431,140,SPARK_POS_OK,0.313619,0.317401,0.236712,0.004063,NORMAL,915,4259,0 -24783894,431,168,SPARK_POS_OK,0.244334,0.285628,0.307734,0.310048,NORMAL,432,171,SPARK_POS_OK,0.313465,0.317222,0.236582,0.004047,NORMAL,928,4215,0 -24847894,432,191,SPARK_POS_OK,0.244145,0.285511,0.307571,0.309891,NORMAL,433,170,SPARK_POS_OK,0.313329,0.317090,0.236441,0.004058,NORMAL,935,4214,0 -24911894,433,190,SPARK_POS_OK,0.244005,0.285369,0.307417,0.309735,NORMAL,434,190,SPARK_POS_OK,0.313167,0.316929,0.236317,0.004044,NORMAL,942,4167,0 -24973894,434,210,SPARK_POS_OK,0.243829,0.285247,0.307274,0.309579,NORMAL,435,211,SPARK_POS_OK,0.313028,0.316777,0.236164,0.004048,NORMAL,954,4241,0 -25036894,435,211,SPARK_POS_OK,0.243638,0.285100,0.307117,0.309419,NORMAL,436,210,SPARK_POS_OK,0.312868,0.316624,0.236022,0.004035,NORMAL,955,4227,0 -25098894,436,230,SPARK_POS_OK,0.243536,0.284973,0.306952,0.309280,NORMAL,437,230,SPARK_POS_OK,0.312713,0.316477,0.235901,0.004037,NORMAL,968,4181,0 -25279894,437,27,SPARK_NEG_OK,0.243410,0.284898,0.306835,0.309154,SOFT_START,439,30,SPARK_NEG_OK,0.312610,0.316348,0.235793,0.003853,SOFT_START,1006,4170,0 -25339894,438,31,SPARK_NEG_OK,0.243244,0.284758,0.306692,0.308995,SOFT_START,440,30,SPARK_NEG_OK,0.312451,0.316194,0.235665,0.003845,SOFT_START,1007,4223,0 -25397894,439,61,SPARK_NEG_OK,0.243085,0.284633,0.306507,0.308831,SOFT_START,441,60,SPARK_NEG_OK,0.312278,0.316048,0.235487,0.003866,SOFT_START,1026,4248,0 -25455894,440,79,SPARK_NEG_OK,0.242942,0.284491,0.306376,0.308681,SOFT_START,442,60,SPARK_NEG_OK,0.312144,0.315886,0.235361,0.003877,SOFT_START,1035,4168,0 -25513894,441,81,SPARK_NEG_OK,0.242774,0.284367,0.306208,0.308532,SOFT_START,443,80,SPARK_NEG_OK,0.311990,0.315723,0.235237,0.003896,SOFT_START,1046,4174,0 -25569894,442,111,SPARK_NEG_OK,0.242639,0.284225,0.306057,0.308406,SOFT_START,444,82,SPARK_NEG_OK,0.311850,0.315569,0.235069,0.003919,SOFT_START,1056,4167,0 -25626894,443,111,SPARK_NEG_OK,0.242458,0.284095,0.305898,0.308211,SOFT_START,445,110,SPARK_NEG_OK,0.311676,0.315419,0.234944,0.003915,SOFT_START,1069,4174,0 -25681894,444,141,SPARK_NEG_OK,0.242298,0.283964,0.305749,0.308079,SOFT_START,446,111,SPARK_NEG_OK,0.311534,0.315236,0.234827,0.003957,SOFT_START,1081,4246,0 -25736894,445,137,SPARK_NEG_OK,0.242157,0.283839,0.305581,0.307902,SOFT_START,447,140,SPARK_NEG_OK,0.311376,0.315092,0.234657,0.003968,SOFT_START,1095,4145,0 -25790894,446,180,SPARK_NEG_OK,0.241993,0.283709,0.305410,0.307735,SOFT_START,448,140,SPARK_NEG_OK,0.311230,0.314946,0.234522,0.003969,SOFT_START,1108,4256,0 -25843894,447,180,SPARK_NEG_OK,0.241839,0.283583,0.305283,0.307602,SOFT_START,449,181,SPARK_NEG_OK,0.311077,0.314785,0.234398,0.003995,SOFT_START,1124,4222,0 -25896894,448,220,SPARK_NEG_OK,0.241687,0.283446,0.305122,0.307433,SOFT_START,450,179,SPARK_NEG_OK,0.310912,0.314633,0.234263,0.004035,SOFT_START,1137,4226,0 -25948894,449,221,SPARK_NEG_OK,0.241552,0.283313,0.304958,0.307270,SOFT_START,451,220,SPARK_NEG_OK,0.310754,0.314475,0.234109,0.004036,SOFT_START,1152,4179,0 -26000894,450,220,SPARK_NEG_OK,0.241355,0.283175,0.304803,0.307094,SOFT_START,452,268,SPARK_NEG_OK,0.310596,0.314305,0.233963,0.004069,SOFT_START,1165,4161,0 -26051894,451,220,SPARK_NEG_OK,0.241221,0.283045,0.304646,0.306938,SOFT_START,453,221,SPARK_NEG_OK,0.310454,0.314141,0.233824,0.004046,SOFT_START,1180,4267,0 -26101894,452,221,SPARK_NEG_OK,0.241018,0.282900,0.304496,0.306817,SOFT_START,454,220,SPARK_NEG_OK,0.310305,0.314004,0.233665,0.004085,SOFT_START,1192,4206,0 -26151894,453,218,SPARK_NEG_OK,0.240875,0.282788,0.304329,0.306650,SOFT_START,455,220,SPARK_NEG_OK,0.310143,0.313835,0.233539,0.004078,SOFT_START,1206,4214,0 -26200894,454,220,SPARK_NEG_OK,0.240688,0.282648,0.304160,0.306496,SOFT_START,456,220,SPARK_NEG_OK,0.310012,0.313680,0.233393,0.004114,SOFT_START,1218,4281,0 -26249894,455,220,SPARK_NEG_OK,0.240511,0.282523,0.304000,0.306337,SOFT_START,457,220,SPARK_NEG_OK,0.309834,0.313514,0.233258,0.004125,SOFT_START,1231,4242,0 -26297894,456,220,SPARK_NEG_OK,0.240330,0.282385,0.303854,0.306161,SOFT_START,458,221,SPARK_NEG_OK,0.309701,0.313366,0.233099,0.004139,SOFT_START,1242,4212,0 -26345894,457,220,SPARK_NEG_OK,0.240209,0.282228,0.303696,0.306008,SOFT_START,459,220,SPARK_NEG_OK,0.309542,0.313210,0.232970,0.004177,SOFT_START,1255,4159,0 -26392894,458,221,SPARK_NEG_OK,0.240078,0.282117,0.303548,0.305850,SOFT_START,460,221,SPARK_NEG_OK,0.309392,0.313063,0.232840,0.004176,SOFT_START,1264,4158,0 -26439894,459,220,SPARK_NEG_OK,0.239910,0.281997,0.303388,0.305706,SOFT_START,461,218,SPARK_NEG_OK,0.309226,0.312895,0.232692,0.004209,SOFT_START,1275,4181,0 -26486894,460,220,SPARK_NEG_OK,0.239752,0.281850,0.303227,0.305544,SOFT_START,462,221,SPARK_NEG_OK,0.309097,0.312724,0.232567,0.004241,SOFT_START,1275,4201,0 -26533894,461,220,SPARK_NEG_OK,0.239585,0.281708,0.303050,0.305390,SOFT_START,463,220,SPARK_NEG_OK,0.308936,0.312569,0.232423,0.004239,SOFT_START,1290,4239,0 -26579894,462,221,SPARK_NEG_OK,0.239377,0.281572,0.302912,0.305232,SOFT_START,464,220,SPARK_NEG_OK,0.308763,0.312415,0.232302,0.004249,SOFT_START,1291,4194,0 -26625894,463,220,SPARK_NEG_OK,0.239255,0.281433,0.302743,0.305044,SOFT_START,465,220,SPARK_NEG_OK,0.308610,0.312266,0.232133,0.004289,SOFT_START,1305,4218,0 -26671894,464,221,SPARK_NEG_OK,0.239088,0.281312,0.302593,0.304902,SOFT_START,466,220,SPARK_NEG_OK,0.308440,0.312108,0.231982,0.004290,SOFT_START,1306,4158,0 -26717894,465,221,SPARK_NEG_OK,0.238974,0.281166,0.302429,0.304756,SOFT_START,467,218,SPARK_NEG_OK,0.308318,0.311950,0.231846,0.004302,SOFT_START,1312,4175,0 -26762894,466,220,SPARK_NEG_OK,0.238776,0.281056,0.302278,0.304610,SOFT_START,468,220,SPARK_NEG_OK,0.308143,0.311779,0.231701,0.004311,SOFT_START,1321,4237,0 -26808894,467,221,SPARK_NEG_OK,0.238606,0.280928,0.302129,0.304453,SOFT_START,469,221,SPARK_NEG_OK,0.308000,0.311638,0.231573,0.004339,SOFT_START,1320,4256,0 -26853894,468,220,SPARK_NEG_OK,0.238449,0.280794,0.301973,0.304294,SOFT_START,470,220,SPARK_NEG_OK,0.307863,0.311469,0.231434,0.004324,SOFT_START,1334,4230,0 -26897894,469,220,SPARK_NEG_OK,0.238295,0.280654,0.301797,0.304121,SOFT_START,471,220,SPARK_NEG_OK,0.307693,0.311331,0.231290,0.004362,SOFT_START,1334,4192,0 -26942894,470,200,SPARK_NEG_OK,0.238133,0.280511,0.301649,0.303981,SOFT_START,472,201,SPARK_NEG_OK,0.307544,0.311139,0.231137,0.004382,SOFT_START,1337,4157,0 -26987894,471,200,SPARK_NEG_OK,0.237994,0.280377,0.301474,0.303811,SOFT_START,473,200,SPARK_NEG_OK,0.307391,0.311008,0.230992,0.004389,SOFT_START,1339,4152,0 -27032894,472,150,SPARK_NEG_OK,0.237804,0.280250,0.301327,0.303633,SOFT_START,474,200,SPARK_NEG_OK,0.307240,0.310833,0.230826,0.004396,SOFT_START,1336,4249,0 -27077894,473,150,SPARK_NEG_OK,0.237676,0.280110,0.301155,0.303475,SOFT_START,475,151,SPARK_NEG_OK,0.307068,0.310662,0.230710,0.004426,SOFT_START,1337,4184,0 -27122894,474,120,SPARK_NEG_OK,0.237524,0.279993,0.301018,0.303320,SOFT_START,476,150,SPARK_NEG_OK,0.306935,0.310528,0.230572,0.004422,SOFT_START,1333,4275,0 -27167894,475,121,SPARK_NEG_OK,0.237339,0.279855,0.300857,0.303157,SOFT_START,477,120,SPARK_NEG_OK,0.306786,0.310375,0.230430,0.004435,SOFT_START,1332,4162,0 -27212894,476,120,SPARK_NEG_OK,0.237194,0.279739,0.300708,0.303010,SOFT_START,478,121,SPARK_NEG_OK,0.306616,0.310200,0.230295,0.004436,SOFT_START,1332,4183,0 -27257894,477,100,SPARK_NEG_OK,0.237052,0.279588,0.300550,0.302844,SOFT_START,479,100,SPARK_NEG_OK,0.306465,0.310048,0.230173,0.004442,SOFT_START,1323,4202,0 -27302894,478,101,SPARK_NEG_OK,0.236890,0.279444,0.300393,0.302712,SOFT_START,480,101,SPARK_NEG_OK,0.306319,0.309893,0.230032,0.004466,SOFT_START,1325,4249,0 -27348894,479,80,SPARK_NEG_OK,0.236716,0.279326,0.300222,0.302529,SOFT_START,481,100,SPARK_NEG_OK,0.306185,0.309737,0.229876,0.004470,SOFT_START,1319,4260,0 -27393894,480,80,SPARK_NEG_OK,0.236563,0.279172,0.300086,0.302406,SOFT_START,482,80,SPARK_NEG_OK,0.306013,0.309591,0.229754,0.004476,SOFT_START,1316,4160,0 -27439894,481,60,SPARK_NEG_OK,0.236393,0.279056,0.299922,0.302218,SOFT_START,483,81,SPARK_NEG_OK,0.305859,0.309443,0.229610,0.004498,SOFT_START,1309,4241,0 -27485894,482,60,SPARK_NEG_OK,0.236264,0.278920,0.299768,0.302089,SOFT_START,484,60,SPARK_NEG_OK,0.305741,0.309281,0.229437,0.004495,SOFT_START,1305,4163,0 -27531894,483,61,SPARK_NEG_OK,0.236121,0.278792,0.299601,0.301903,SOFT_START,485,61,SPARK_NEG_OK,0.305582,0.309130,0.229292,0.004489,SOFT_START,1305,4216,0 -27578894,484,40,SPARK_NEG_OK,0.235947,0.278673,0.299451,0.301791,SOFT_START,486,40,SPARK_NEG_OK,0.305398,0.308973,0.229186,0.004495,SOFT_START,1289,4254,0 -27624894,485,41,SPARK_NEG_OK,0.235777,0.278535,0.299291,0.301610,SOFT_START,487,40,SPARK_NEG_OK,0.305252,0.308834,0.229037,0.004504,SOFT_START,1291,4188,0 -27671894,486,25,SPARK_NEG_OK,0.235615,0.278394,0.299131,0.301462,SOFT_START,488,25,SPARK_NEG_OK,0.305108,0.308660,0.228924,0.004501,SOFT_START,1274,4194,0 -27718894,487,25,SPARK_NEG_OK,0.235474,0.278265,0.298988,0.301294,SOFT_START,489,25,SPARK_NEG_OK,0.304982,0.308506,0.228761,0.004511,SOFT_START,1275,4235,0 -27766894,488,240,SPARK_POS_OK,0.235290,0.278150,0.298833,0.301164,NORMAL,490,25,SPARK_NEG_OK,0.304818,0.308329,0.228631,0.004478,SOFT_START,1275,4268,0 -27814894,489,241,SPARK_POS_OK,0.235133,0.278005,0.298676,0.300983,NORMAL,491,240,SPARK_POS_OK,0.304641,0.308191,0.228487,0.004510,NORMAL,1262,4191,0 -27861894,490,220,SPARK_POS_OK,0.235007,0.277883,0.298517,0.300829,NORMAL,492,241,SPARK_POS_OK,0.304506,0.308035,0.228362,0.004495,NORMAL,1253,4171,0 -27910894,491,221,SPARK_POS_OK,0.234870,0.277768,0.298377,0.300696,NORMAL,493,220,SPARK_POS_OK,0.304349,0.307886,0.228217,0.004492,NORMAL,1246,4180,0 -27958894,492,192,SPARK_POS_OK,0.234726,0.277621,0.298216,0.300523,NORMAL,494,221,SPARK_POS_OK,0.304200,0.307726,0.228056,0.004503,NORMAL,1237,4184,0 -28007894,493,191,SPARK_POS_OK,0.234546,0.277506,0.298065,0.300381,NORMAL,495,190,SPARK_POS_OK,0.304072,0.307571,0.227940,0.004511,NORMAL,1228,4158,0 -28056894,494,219,SPARK_POS_OK,0.234405,0.277355,0.297914,0.300225,NORMAL,496,190,SPARK_POS_OK,0.303894,0.307428,0.227815,0.004506,NORMAL,1228,4214,0 -28105894,495,170,SPARK_POS_OK,0.234249,0.277219,0.297754,0.300079,NORMAL,497,170,SPARK_POS_OK,0.303753,0.307287,0.227692,0.004506,NORMAL,1208,4149,0 -28155894,496,172,SPARK_POS_OK,0.234093,0.277112,0.297602,0.299907,NORMAL,498,168,SPARK_POS_OK,0.303609,0.307118,0.227537,0.004491,NORMAL,1208,4216,0 -28206894,497,150,SPARK_POS_OK,0.233985,0.276974,0.297437,0.299759,NORMAL,499,151,SPARK_POS_OK,0.303454,0.306962,0.227410,0.004479,NORMAL,1186,4153,0 -28256894,498,151,SPARK_POS_OK,0.233786,0.276864,0.297296,0.299616,NORMAL,500,150,SPARK_POS_OK,0.303313,0.306812,0.227254,0.004480,NORMAL,1187,4269,0 -28308894,499,130,SPARK_POS_OK,0.233641,0.276716,0.297128,0.299439,NORMAL,501,130,SPARK_POS_OK,0.303178,0.306637,0.227132,0.004466,NORMAL,1167,4170,0 -28359894,500,130,SPARK_POS_OK,0.233482,0.276599,0.297002,0.299293,NORMAL,502,131,SPARK_POS_OK,0.303010,0.306511,0.226998,0.004463,NORMAL,1167,4250,0 -28411894,501,110,SPARK_POS_OK,0.233346,0.276440,0.296826,0.299152,NORMAL,503,110,SPARK_POS_OK,0.302870,0.306368,0.226858,0.004464,NORMAL,1147,4220,0 -28464894,502,111,SPARK_POS_OK,0.233172,0.276349,0.296684,0.299016,NORMAL,504,110,SPARK_POS_OK,0.302728,0.306208,0.226721,0.004426,NORMAL,1148,4240,0 -28517894,503,90,SPARK_POS_OK,0.233042,0.276198,0.296519,0.298835,NORMAL,505,91,SPARK_POS_OK,0.302579,0.306072,0.226577,0.004460,NORMAL,1127,4183,0 -28570894,504,90,SPARK_POS_OK,0.232871,0.276086,0.296401,0.298697,NORMAL,506,90,SPARK_POS_OK,0.302422,0.305900,0.226443,0.004445,NORMAL,1127,4177,0 -28624894,505,70,SPARK_POS_OK,0.232748,0.275949,0.296220,0.298554,NORMAL,507,71,SPARK_POS_OK,0.302281,0.305759,0.226333,0.004415,NORMAL,1103,4200,0 -28679894,506,70,SPARK_POS_OK,0.232572,0.275822,0.296072,0.298413,NORMAL,508,70,SPARK_POS_OK,0.302138,0.305597,0.226177,0.004410,NORMAL,1104,4264,0 -28734894,507,50,SPARK_POS_OK,0.232410,0.275686,0.295929,0.298222,NORMAL,509,50,SPARK_POS_OK,0.301995,0.305448,0.226059,0.004398,NORMAL,1081,4220,0 -28790894,508,30,SPARK_POS_OK,0.232251,0.275572,0.295786,0.298082,NORMAL,510,52,SPARK_POS_OK,0.301843,0.305323,0.225919,0.004374,NORMAL,1070,4269,0 -28847894,509,30,SPARK_POS_OK,0.232106,0.275454,0.295643,0.297915,NORMAL,511,30,SPARK_POS_OK,0.301710,0.305157,0.225785,0.004373,NORMAL,1060,4195,0 -28904894,510,30,SPARK_POS_OK,0.231964,0.275316,0.295492,0.297777,NORMAL,512,29,SPARK_POS_OK,0.301558,0.305012,0.225647,0.004357,NORMAL,1060,4169,0 -28962894,511,30,SPARK_POS_OK,0.231856,0.275185,0.295308,0.297637,NORMAL,513,29,SPARK_POS_OK,0.301403,0.304863,0.225520,0.004330,NORMAL,1060,4154,0 -29020894,512,30,SPARK_POS_OK,0.231654,0.275059,0.295185,0.297471,NORMAL,514,29,SPARK_POS_OK,0.301254,0.304716,0.225407,0.004314,NORMAL,1060,4229,0 -29079894,513,30,SPARK_POS_OK,0.231529,0.274943,0.295056,0.297354,NORMAL,515,29,SPARK_POS_OK,0.301126,0.304580,0.225252,0.004290,NORMAL,1060,4229,0 -29140894,514,30,SPARK_POS_OK,0.231363,0.274788,0.294892,0.297194,NORMAL,516,29,SPARK_POS_OK,0.300963,0.304419,0.225143,0.004274,NORMAL,1060,4265,0 -29201894,515,30,SPARK_POS_OK,0.231243,0.274711,0.294742,0.297049,NORMAL,517,29,SPARK_POS_OK,0.300827,0.304254,0.225012,0.004261,NORMAL,1060,4205,0 -29263894,516,30,SPARK_POS_OK,0.231097,0.274554,0.294609,0.296904,NORMAL,518,29,SPARK_POS_OK,0.300693,0.304128,0.224861,0.004250,NORMAL,1060,4222,0 -29325894,517,30,SPARK_POS_OK,0.230927,0.274445,0.294461,0.296749,NORMAL,519,29,SPARK_POS_OK,0.300543,0.303966,0.224741,0.004233,NORMAL,1060,4208,0 -29388894,518,30,SPARK_POS_OK,0.230758,0.274323,0.294295,0.296606,NORMAL,520,29,SPARK_POS_OK,0.300400,0.303816,0.224615,0.004211,NORMAL,1060,4241,0 -29452894,519,30,SPARK_POS_OK,0.230615,0.274199,0.294167,0.296452,NORMAL,521,29,SPARK_POS_OK,0.300251,0.303678,0.224453,0.004197,NORMAL,1060,4258,0 -29516894,520,30,SPARK_POS_OK,0.230507,0.274069,0.293997,0.296320,NORMAL,522,29,SPARK_POS_OK,0.300115,0.303529,0.224360,0.004165,NORMAL,1060,4201,0 -29580894,521,30,SPARK_POS_OK,0.230321,0.273947,0.293862,0.296165,NORMAL,523,29,SPARK_POS_OK,0.299969,0.303385,0.224254,0.004139,NORMAL,1060,4260,0 -29645894,522,30,SPARK_POS_OK,0.230199,0.273811,0.293727,0.296023,NORMAL,524,29,SPARK_POS_OK,0.299823,0.303254,0.224081,0.004141,NORMAL,1060,4149,0 -29711894,523,30,SPARK_POS_OK,0.230053,0.273697,0.293586,0.295871,NORMAL,525,29,SPARK_POS_OK,0.299684,0.303107,0.223966,0.004110,NORMAL,1060,4234,0 -29778894,524,30,SPARK_POS_OK,0.229897,0.273574,0.293452,0.295721,NORMAL,526,29,SPARK_POS_OK,0.299528,0.302956,0.223830,0.004099,NORMAL,1060,4268,0 -29844894,525,18,SPARK_POS_OK,0.229737,0.273463,0.293287,0.295576,NORMAL,527,29,SPARK_POS_OK,0.299393,0.302807,0.223719,0.004088,NORMAL,60,4253,0 -29911894,526,25,SPARK_POS_OK,0.229585,0.273339,0.293126,0.295432,NORMAL,528,25,SPARK_POS_OK,0.299249,0.302660,0.223577,0.004053,NORMAL,898,4248,0 -29978894,527,50,SPARK_POS_OK,0.229421,0.273230,0.292988,0.295304,NORMAL,529,50,SPARK_POS_OK,0.299109,0.302531,0.223458,0.004053,NORMAL,897,4250,0 -30045894,528,71,SPARK_POS_OK,0.229278,0.273093,0.292861,0.295157,NORMAL,530,50,SPARK_POS_OK,0.298978,0.302386,0.223312,0.004017,NORMAL,898,4157,0 -30111894,529,70,SPARK_POS_OK,0.229153,0.272971,0.292700,0.295006,NORMAL,531,70,SPARK_POS_OK,0.298840,0.302225,0.223220,0.004009,NORMAL,900,4156,0 -30178894,530,81,SPARK_POS_OK,0.229019,0.272849,0.292549,0.294856,NORMAL,532,80,SPARK_POS_OK,0.298682,0.302095,0.223073,0.004002,NORMAL,900,4184,0 -30244894,531,100,SPARK_POS_OK,0.228902,0.272712,0.292414,0.294721,NORMAL,533,80,SPARK_POS_OK,0.298550,0.301940,0.222973,0.003992,NORMAL,901,4190,0 -30311894,532,101,SPARK_POS_OK,0.228704,0.272602,0.292251,0.294572,NORMAL,534,100,SPARK_POS_OK,0.298408,0.301793,0.222811,0.003995,NORMAL,904,4221,0 -30377894,533,110,SPARK_POS_OK,0.228599,0.272483,0.292122,0.294414,NORMAL,535,109,SPARK_POS_OK,0.298252,0.301656,0.222685,0.003978,NORMAL,906,4176,0 -30443894,534,111,SPARK_POS_OK,0.228439,0.272374,0.291972,0.294291,NORMAL,536,110,SPARK_POS_OK,0.298129,0.301508,0.222601,0.003955,NORMAL,910,4154,0 -30508894,535,133,SPARK_POS_OK,0.228352,0.272239,0.291821,0.294130,NORMAL,537,130,SPARK_POS_OK,0.298014,0.301350,0.222435,0.003946,NORMAL,918,4209,0 -30573894,536,150,SPARK_POS_OK,0.228187,0.272096,0.291667,0.293991,NORMAL,538,131,SPARK_POS_OK,0.297840,0.301217,0.222303,0.003926,NORMAL,923,4164,0 -30638894,537,150,SPARK_POS_OK,0.228051,0.271986,0.291539,0.293838,NORMAL,539,150,SPARK_POS_OK,0.297694,0.301065,0.222185,0.003922,NORMAL,928,4197,0 -30702894,538,170,SPARK_POS_OK,0.227895,0.271876,0.291392,0.293676,NORMAL,540,170,SPARK_POS_OK,0.297551,0.300927,0.222085,0.003925,NORMAL,935,4219,0 -30766894,539,191,SPARK_POS_OK,0.227766,0.271754,0.291253,0.293556,NORMAL,541,170,SPARK_POS_OK,0.297411,0.300766,0.221926,0.003914,NORMAL,940,4203,0 -30829894,540,190,SPARK_POS_OK,0.227587,0.271612,0.291104,0.293421,NORMAL,542,190,SPARK_POS_OK,0.297287,0.300643,0.221813,0.003932,NORMAL,947,4209,0 -30892894,541,210,SPARK_POS_OK,0.227440,0.271500,0.290959,0.293264,NORMAL,543,191,SPARK_POS_OK,0.297142,0.300490,0.221671,0.003911,NORMAL,953,4255,0 -30954894,542,208,SPARK_POS_OK,0.227338,0.271378,0.290822,0.293120,NORMAL,544,210,SPARK_POS_OK,0.296986,0.300339,0.221546,0.003938,NORMAL,962,4171,0 -31015894,543,231,SPARK_POS_OK,0.227185,0.271240,0.290673,0.292974,NORMAL,545,230,SPARK_POS_OK,0.296851,0.300217,0.221401,0.003914,NORMAL,978,4189,0 -31196894,544,30,SPARK_NEG_OK,0.227097,0.271150,0.290566,0.292864,SOFT_START,546,230,SPARK_NEG_WAIT,0.296770,0.300094,0.221338,0.003732,NORMAL,1001,4171,0 -31255894,545,30,SPARK_NEG_OK,0.226947,0.271028,0.290417,0.292725,SOFT_START,547,30,SPARK_NEG_OK,0.296605,0.299956,0.221204,0.003748,SOFT_START,1010,4251,0 -31314894,546,50,SPARK_NEG_OK,0.226794,0.270930,0.290271,0.292549,SOFT_START,548,52,SPARK_NEG_OK,0.296459,0.299803,0.221077,0.003765,SOFT_START,1026,4172,0 -31372894,547,51,SPARK_NEG_OK,0.226651,0.270789,0.290137,0.292426,SOFT_START,549,50,SPARK_NEG_OK,0.296304,0.299659,0.220951,0.003769,SOFT_START,1027,4165,0 -31430894,548,70,SPARK_NEG_OK,0.226499,0.270665,0.289981,0.292265,SOFT_START,550,71,SPARK_NEG_OK,0.296170,0.299509,0.220838,0.003793,SOFT_START,1046,4275,0 -31487894,549,92,SPARK_NEG_OK,0.226340,0.270549,0.289845,0.292126,SOFT_START,551,70,SPARK_NEG_OK,0.296020,0.299360,0.220708,0.003812,SOFT_START,1047,4250,0 -31543894,550,90,SPARK_NEG_OK,0.226200,0.270408,0.289685,0.291980,SOFT_START,552,90,SPARK_NEG_OK,0.295882,0.299222,0.220565,0.003802,SOFT_START,1068,4164,0 -31599894,551,110,SPARK_NEG_OK,0.226091,0.270299,0.289539,0.291825,SOFT_START,553,90,SPARK_NEG_OK,0.295726,0.299069,0.220453,0.003850,SOFT_START,1079,4168,0 -31654894,552,110,SPARK_NEG_OK,0.225908,0.270163,0.289385,0.291685,SOFT_START,554,110,SPARK_NEG_OK,0.295606,0.298903,0.220297,0.003855,SOFT_START,1091,4267,0 -31708894,553,140,SPARK_NEG_OK,0.225781,0.270032,0.289235,0.291539,SOFT_START,555,111,SPARK_NEG_OK,0.295478,0.298759,0.220181,0.003861,SOFT_START,1101,4150,0 -31762894,554,140,SPARK_NEG_OK,0.225610,0.269906,0.289096,0.291394,SOFT_START,556,141,SPARK_NEG_OK,0.295316,0.298629,0.220047,0.003878,SOFT_START,1113,4243,0 -31815894,555,171,SPARK_NEG_OK,0.225482,0.269780,0.288954,0.291249,SOFT_START,557,140,SPARK_NEG_OK,0.295166,0.298475,0.219911,0.003871,SOFT_START,1123,4150,0 -31868894,556,171,SPARK_NEG_OK,0.225355,0.269666,0.288804,0.291082,SOFT_START,558,170,SPARK_NEG_OK,0.295011,0.298344,0.219790,0.003916,SOFT_START,1136,4163,0 -31921894,557,200,SPARK_NEG_OK,0.225197,0.269532,0.288649,0.290950,SOFT_START,559,170,SPARK_NEG_OK,0.294881,0.298182,0.219643,0.003912,SOFT_START,1147,4258,0 -31972894,558,200,SPARK_NEG_OK,0.225049,0.269413,0.288505,0.290800,SOFT_START,560,201,SPARK_NEG_OK,0.294744,0.298035,0.219514,0.003937,SOFT_START,1161,4190,0 -32023894,559,221,SPARK_NEG_OK,0.224914,0.269298,0.288351,0.290653,SOFT_START,561,200,SPARK_NEG_OK,0.294604,0.297887,0.219409,0.003936,SOFT_START,1173,4233,0 -32074894,560,220,SPARK_NEG_OK,0.224741,0.269151,0.288212,0.290508,SOFT_START,562,220,SPARK_NEG_OK,0.294451,0.297741,0.219271,0.003975,SOFT_START,1188,4261,0 -32124894,561,220,SPARK_NEG_OK,0.224595,0.269035,0.288078,0.290365,SOFT_START,563,221,SPARK_NEG_OK,0.294299,0.297612,0.219138,0.003971,SOFT_START,1198,4214,0 -32173894,562,221,SPARK_NEG_OK,0.224457,0.268905,0.287915,0.290209,SOFT_START,564,220,SPARK_NEG_OK,0.294173,0.297448,0.219002,0.003996,SOFT_START,1212,4194,0 -32222894,563,220,SPARK_NEG_OK,0.224333,0.268773,0.287753,0.290070,SOFT_START,565,220,SPARK_NEG_OK,0.294014,0.297293,0.218863,0.004018,SOFT_START,1222,4165,0 -32271894,564,221,SPARK_NEG_OK,0.224152,0.268652,0.287609,0.289907,SOFT_START,566,220,SPARK_NEG_OK,0.293874,0.297136,0.218728,0.004048,SOFT_START,1234,4226,0 -32320894,565,220,SPARK_NEG_OK,0.223991,0.268545,0.287464,0.289770,SOFT_START,567,220,SPARK_NEG_OK,0.293739,0.297003,0.218605,0.004079,SOFT_START,1234,4235,0 -32368894,566,221,SPARK_NEG_OK,0.223832,0.268385,0.287308,0.289612,SOFT_START,568,220,SPARK_NEG_OK,0.293614,0.296863,0.218485,0.004086,SOFT_START,1253,4277,0 -32415894,567,220,SPARK_NEG_OK,0.223702,0.268284,0.287163,0.289459,SOFT_START,569,220,SPARK_NEG_OK,0.293436,0.296702,0.218351,0.004088,SOFT_START,1254,4185,0 -32463894,568,221,SPARK_NEG_OK,0.223539,0.268133,0.287021,0.289323,SOFT_START,570,221,SPARK_NEG_OK,0.293300,0.296544,0.218212,0.004120,SOFT_START,1272,4253,0 -32510894,569,220,SPARK_NEG_OK,0.223411,0.268019,0.286869,0.289187,SOFT_START,571,220,SPARK_NEG_OK,0.293167,0.296410,0.218098,0.004146,SOFT_START,1274,4229,0 -32556894,570,221,SPARK_NEG_OK,0.223255,0.267893,0.286747,0.289009,SOFT_START,572,220,SPARK_NEG_OK,0.293028,0.296266,0.217940,0.004130,SOFT_START,1291,4153,0 -32602899,571,220,SPARK_NEG_OK,0.223058,0.267776,0.286589,0.288869,SOFT_START,573,220,SPARK_NEG_OK,0.292874,0.296096,0.217817,0.004131,SOFT_START,1292,4261,0 -32649894,572,221,SPARK_NEG_OK,0.222954,0.267630,0.286425,0.288712,SOFT_START,574,220,SPARK_NEG_OK,0.292727,0.295968,0.217693,0.004166,SOFT_START,1298,4178,0 -32695894,573,220,SPARK_NEG_OK,0.222799,0.267516,0.286273,0.288576,SOFT_START,575,221,SPARK_NEG_OK,0.292587,0.295816,0.217561,0.004193,SOFT_START,1307,4272,0 -32740894,574,220,SPARK_NEG_OK,0.222647,0.267380,0.286134,0.288430,SOFT_START,576,220,SPARK_NEG_OK,0.292442,0.295664,0.217426,0.004186,SOFT_START,1311,4260,0 -32786894,575,221,SPARK_NEG_OK,0.222493,0.267292,0.285975,0.288275,SOFT_START,577,221,SPARK_NEG_OK,0.292296,0.295509,0.217326,0.004219,SOFT_START,1319,4241,0 -32831894,576,220,SPARK_NEG_OK,0.222350,0.267133,0.285851,0.288131,SOFT_START,578,220,SPARK_NEG_OK,0.292144,0.295361,0.217180,0.004225,SOFT_START,1319,4222,0 -32876894,577,220,SPARK_NEG_OK,0.222221,0.267005,0.285688,0.287982,SOFT_START,579,220,SPARK_NEG_OK,0.292020,0.295215,0.217054,0.004244,SOFT_START,1329,4152,0 -32922894,578,220,SPARK_NEG_OK,0.222057,0.266885,0.285548,0.287839,SOFT_START,580,221,SPARK_NEG_OK,0.291863,0.295089,0.216917,0.004260,SOFT_START,1330,4271,0 -32966894,579,220,SPARK_NEG_OK,0.221909,0.266747,0.285396,0.287680,SOFT_START,581,222,SPARK_NEG_OK,0.291705,0.294917,0.216799,0.004268,SOFT_START,1340,4178,0 -33011894,580,218,SPARK_NEG_OK,0.221742,0.266636,0.285243,0.287526,SOFT_START,582,220,SPARK_NEG_OK,0.291577,0.294788,0.216637,0.004264,SOFT_START,1341,4272,0 -33056894,581,220,SPARK_NEG_OK,0.221614,0.266501,0.285096,0.287389,SOFT_START,583,221,SPARK_NEG_OK,0.291437,0.294625,0.216532,0.004283,SOFT_START,1345,4191,0 -33100894,582,220,SPARK_NEG_OK,0.221465,0.266403,0.284954,0.287235,SOFT_START,584,220,SPARK_NEG_OK,0.291283,0.294502,0.216410,0.004286,SOFT_START,1350,4165,0 -33144894,583,221,SPARK_NEG_OK,0.221301,0.266253,0.284796,0.287101,SOFT_START,585,220,SPARK_NEG_OK,0.291148,0.294346,0.216251,0.004312,SOFT_START,1350,4272,0 -33189894,584,190,SPARK_NEG_OK,0.221170,0.266118,0.284649,0.286964,SOFT_START,586,191,SPARK_NEG_OK,0.291015,0.294184,0.216144,0.004308,SOFT_START,1350,4268,0 -33233894,585,190,SPARK_NEG_OK,0.221002,0.266004,0.284517,0.286789,SOFT_START,587,190,SPARK_NEG_OK,0.290853,0.294049,0.216001,0.004324,SOFT_START,1351,4149,0 -33278894,586,151,SPARK_NEG_OK,0.220879,0.265905,0.284364,0.286654,SOFT_START,588,148,SPARK_NEG_OK,0.290717,0.293917,0.215877,0.004335,SOFT_START,1348,4235,0 -33322894,587,150,SPARK_NEG_OK,0.220745,0.265746,0.284213,0.286506,SOFT_START,589,151,SPARK_NEG_OK,0.290567,0.293751,0.215759,0.004358,SOFT_START,1348,4150,0 -33367894,588,120,SPARK_NEG_OK,0.220601,0.265614,0.284064,0.286338,SOFT_START,590,150,SPARK_NEG_OK,0.290433,0.293602,0.215640,0.004355,SOFT_START,1344,4195,0 -33411894,589,121,SPARK_NEG_OK,0.220446,0.265481,0.283915,0.286192,SOFT_START,591,120,SPARK_NEG_OK,0.290278,0.293458,0.215487,0.004383,SOFT_START,1342,4162,0 -33456894,590,120,SPARK_NEG_OK,0.220311,0.265375,0.283771,0.286060,SOFT_START,592,120,SPARK_NEG_OK,0.290154,0.293300,0.215356,0.004362,SOFT_START,1342,4256,0 -33501894,591,100,SPARK_NEG_OK,0.220193,0.265262,0.283619,0.285911,SOFT_START,593,100,SPARK_NEG_OK,0.290006,0.293163,0.215232,0.004379,SOFT_START,1332,4174,0 -33546894,592,101,SPARK_NEG_OK,0.220030,0.265129,0.283490,0.285764,SOFT_START,594,100,SPARK_NEG_OK,0.289842,0.293036,0.215108,0.004383,SOFT_START,1333,4256,0 -33591897,593,70,SPARK_NEG_OK,0.219882,0.265003,0.283312,0.285606,SOFT_START,595,71,SPARK_NEG_OK,0.289702,0.292856,0.214979,0.004376,SOFT_START,1321,4203,0 -33637894,594,70,SPARK_NEG_OK,0.219761,0.264870,0.283198,0.285496,SOFT_START,596,70,SPARK_NEG_OK,0.289568,0.292754,0.214847,0.004398,SOFT_START,1322,4170,0 -33683894,595,40,SPARK_NEG_OK,0.219610,0.264744,0.283063,0.285316,SOFT_START,597,71,SPARK_NEG_OK,0.289434,0.292597,0.214727,0.004407,SOFT_START,1313,4248,0 -33728894,596,40,SPARK_NEG_OK,0.219433,0.264626,0.282887,0.285174,SOFT_START,598,40,SPARK_NEG_OK,0.289289,0.292440,0.214608,0.004391,SOFT_START,1307,4209,0 -33774894,597,40,SPARK_NEG_OK,0.219309,0.264485,0.282733,0.285023,SOFT_START,599,40,SPARK_NEG_OK,0.289144,0.292300,0.214483,0.004406,SOFT_START,1307,4169,0 -33821894,598,25,SPARK_NEG_OK,0.219164,0.264351,0.282601,0.284892,SOFT_START,600,25,SPARK_NEG_OK,0.289014,0.292149,0.214335,0.004404,SOFT_START,1288,4275,0 -33867894,599,25,SPARK_NEG_OK,0.219021,0.264238,0.282480,0.284735,SOFT_START,601,25,SPARK_NEG_OK,0.288854,0.292002,0.214229,0.004414,SOFT_START,1289,4150,0 -34010894,600,230,SPARK_POS_OK,0.218923,0.264163,0.282345,0.284633,NORMAL,602,230,SPARK_POS_OK,0.288753,0.291890,0.214139,0.004190,NORMAL,1262,4161,0 -34058894,601,231,SPARK_POS_OK,0.218782,0.264018,0.282212,0.284500,NORMAL,603,230,SPARK_POS_OK,0.288612,0.291755,0.213985,0.004213,NORMAL,1256,4261,0 -34106894,602,210,SPARK_POS_OK,0.218613,0.263910,0.282043,0.284339,NORMAL,604,231,SPARK_POS_OK,0.288465,0.291602,0.213870,0.004219,NORMAL,1246,4249,0 -34154894,603,211,SPARK_POS_OK,0.218469,0.263771,0.281917,0.284205,NORMAL,605,210,SPARK_POS_OK,0.288340,0.291449,0.213743,0.004221,NORMAL,1239,4223,0 -34203894,604,180,SPARK_POS_OK,0.218338,0.263654,0.281764,0.284051,NORMAL,606,210,SPARK_POS_OK,0.288197,0.291333,0.213640,0.004241,NORMAL,1228,4275,0 -34253894,605,181,SPARK_POS_OK,0.218177,0.263538,0.281628,0.283921,NORMAL,607,180,SPARK_POS_OK,0.288049,0.291172,0.213487,0.004234,NORMAL,1218,4257,0 -34302894,606,160,SPARK_POS_OK,0.218021,0.263417,0.281486,0.283763,NORMAL,608,180,SPARK_POS_OK,0.287909,0.291052,0.213367,0.004215,NORMAL,1206,4250,0 -34352894,607,160,SPARK_POS_OK,0.217876,0.263287,0.281342,0.283609,NORMAL,609,161,SPARK_POS_OK,0.287775,0.290890,0.213259,0.004232,NORMAL,1196,4238,0 -34403894,608,139,SPARK_POS_OK,0.217735,0.263172,0.281190,0.283456,NORMAL,610,160,SPARK_POS_OK,0.287634,0.290743,0.213134,0.004218,NORMAL,1185,4248,0 -34454894,609,140,SPARK_POS_OK,0.217576,0.263045,0.281042,0.283325,NORMAL,611,140,SPARK_POS_OK,0.287511,0.290605,0.213003,0.004237,NORMAL,1175,4248,0 -34506894,610,111,SPARK_POS_OK,0.217422,0.262920,0.280915,0.283189,NORMAL,612,141,SPARK_POS_OK,0.287367,0.290461,0.212876,0.004232,NORMAL,1164,4281,0 -34558894,611,111,SPARK_POS_OK,0.217294,0.262783,0.280773,0.283042,NORMAL,613,110,SPARK_POS_OK,0.287238,0.290313,0.212728,0.004213,NORMAL,1154,4182,0 -34610894,612,93,SPARK_POS_OK,0.217142,0.262676,0.280632,0.282895,NORMAL,614,110,SPARK_POS_OK,0.287075,0.290173,0.212619,0.004225,NORMAL,1143,4218,0 -34663894,613,90,SPARK_POS_OK,0.216988,0.262541,0.280485,0.282761,NORMAL,615,90,SPARK_POS_OK,0.286961,0.290027,0.212517,0.004214,NORMAL,1133,4228,0 -34716894,614,70,SPARK_POS_OK,0.216900,0.262419,0.280350,0.282615,NORMAL,616,91,SPARK_POS_OK,0.286793,0.289903,0.212389,0.004218,NORMAL,1121,4155,0 -34771894,615,70,SPARK_POS_OK,0.216745,0.262302,0.280189,0.282466,NORMAL,617,70,SPARK_POS_OK,0.286642,0.289757,0.212252,0.004212,NORMAL,1110,4242,0 -34825894,616,50,SPARK_POS_OK,0.216602,0.262186,0.280063,0.282335,NORMAL,618,70,SPARK_POS_OK,0.286527,0.289600,0.212144,0.004207,NORMAL,1097,4221,0 -34880894,617,51,SPARK_POS_OK,0.216441,0.262075,0.279932,0.282189,NORMAL,619,50,SPARK_POS_OK,0.286393,0.289466,0.212007,0.004208,NORMAL,1086,4194,0 -34936894,618,41,SPARK_POS_OK,0.216339,0.261927,0.279781,0.282065,NORMAL,620,50,SPARK_POS_OK,0.286254,0.289338,0.211874,0.004185,NORMAL,1074,4184,0 -34993894,619,41,SPARK_POS_OK,0.216206,0.261821,0.279639,0.281928,NORMAL,621,40,SPARK_POS_OK,0.286109,0.289190,0.211774,0.004189,NORMAL,1063,4157,0 -35050894,620,25,SPARK_POS_OK,0.216070,0.261710,0.279472,0.281775,NORMAL,622,40,SPARK_POS_OK,0.285965,0.289056,0.211664,0.004166,NORMAL,1051,4166,0 -35107894,621,25,SPARK_POS_OK,0.215958,0.261584,0.279363,0.281629,NORMAL,623,25,SPARK_POS_OK,0.285835,0.288917,0.211526,0.004141,NORMAL,1041,4179,0 -35166894,622,25,SPARK_POS_OK,0.215852,0.261455,0.279204,0.281507,NORMAL,624,25,SPARK_POS_OK,0.285711,0.288778,0.211395,0.004149,NORMAL,1041,4158,0 -35225894,623,25,SPARK_POS_OK,0.215697,0.261327,0.279067,0.281358,NORMAL,625,25,SPARK_POS_OK,0.285565,0.288635,0.211287,0.004148,NORMAL,1041,4195,0 -35285894,624,25,SPARK_POS_OK,0.215550,0.261243,0.278931,0.281226,NORMAL,626,25,SPARK_POS_OK,0.285427,0.288497,0.211173,0.004114,NORMAL,1041,4264,0 -35346894,625,25,SPARK_POS_OK,0.215418,0.261111,0.278800,0.281084,NORMAL,627,25,SPARK_POS_OK,0.285299,0.288371,0.211050,0.004109,NORMAL,1041,4177,0 -35408894,626,25,SPARK_POS_OK,0.215275,0.260987,0.278656,0.280928,NORMAL,628,25,SPARK_POS_OK,0.285162,0.288201,0.210943,0.004089,NORMAL,1041,4248,0 -35470894,627,25,SPARK_POS_OK,0.215132,0.260886,0.278528,0.280776,NORMAL,629,25,SPARK_POS_OK,0.285029,0.288087,0.210811,0.004069,NORMAL,1041,4193,0 -35533894,628,25,SPARK_POS_OK,0.215003,0.260752,0.278396,0.280665,NORMAL,630,25,SPARK_POS_OK,0.284912,0.287941,0.210699,0.004070,NORMAL,1041,4246,0 -35596894,629,25,SPARK_POS_OK,0.214865,0.260631,0.278243,0.280498,NORMAL,631,25,SPARK_POS_OK,0.284758,0.287799,0.210554,0.004044,NORMAL,1041,4180,0 -35661894,630,25,SPARK_POS_OK,0.214735,0.260540,0.278130,0.280364,NORMAL,632,25,SPARK_POS_OK,0.284619,0.287676,0.210446,0.004028,NORMAL,1041,4205,0 -35725894,631,25,SPARK_POS_OK,0.214604,0.260414,0.277976,0.280225,NORMAL,633,25,SPARK_POS_OK,0.284517,0.287534,0.210330,0.004011,NORMAL,1041,4218,0 -35791894,632,25,SPARK_POS_OK,0.214474,0.260302,0.277838,0.280115,NORMAL,634,25,SPARK_POS_OK,0.284371,0.287407,0.210209,0.003995,NORMAL,1041,4234,0 -35857894,633,25,SPARK_POS_OK,0.214345,0.260153,0.277704,0.279993,NORMAL,635,25,SPARK_POS_OK,0.284230,0.287284,0.210090,0.003946,NORMAL,1041,4146,0 -35924894,634,25,SPARK_POS_OK,0.214211,0.260050,0.277567,0.279846,NORMAL,636,25,SPARK_POS_OK,0.284095,0.287125,0.209954,0.003960,NORMAL,1041,4280,0 -35991894,635,25,SPARK_POS_OK,0.214071,0.259948,0.277441,0.279709,NORMAL,637,25,SPARK_POS_OK,0.283967,0.286993,0.209862,0.003954,NORMAL,1041,4228,0 -36058894,636,25,SPARK_POS_OK,0.213940,0.259834,0.277300,0.279558,NORMAL,638,25,SPARK_POS_OK,0.283840,0.286869,0.209744,0.003928,NORMAL,1041,4226,0 -36126894,637,25,SPARK_POS_OK,0.213813,0.259711,0.277163,0.279440,NORMAL,639,25,SPARK_POS_OK,0.283694,0.286736,0.209639,0.003926,NORMAL,58,4181,0 -36194894,638,51,SPARK_POS_OK,0.213678,0.259607,0.277023,0.279305,NORMAL,640,24,SPARK_POS_OK,0.283580,0.286590,0.209524,0.003909,NORMAL,885,4185,0 -36261894,639,50,SPARK_POS_OK,0.213571,0.259478,0.276902,0.279151,NORMAL,641,51,SPARK_POS_OK,0.283444,0.286450,0.209401,0.003888,NORMAL,887,4159,0 -36329894,640,90,SPARK_POS_OK,0.213425,0.259354,0.276760,0.279043,NORMAL,642,87,SPARK_POS_OK,0.283290,0.286326,0.209283,0.003871,NORMAL,888,4260,0 -36396894,641,110,SPARK_POS_OK,0.213286,0.259249,0.276630,0.278909,NORMAL,643,90,SPARK_POS_OK,0.283167,0.286195,0.209165,0.003867,NORMAL,890,4243,0 -36463894,642,110,SPARK_POS_OK,0.213141,0.259161,0.276492,0.278755,NORMAL,644,110,SPARK_POS_OK,0.283051,0.286046,0.209054,0.003871,NORMAL,893,4162,0 -36530894,643,130,SPARK_POS_OK,0.213040,0.259021,0.276358,0.278633,NORMAL,645,131,SPARK_POS_OK,0.282916,0.285913,0.208927,0.003837,NORMAL,899,4263,0 -36596894,644,140,SPARK_POS_OK,0.212910,0.258908,0.276224,0.278480,NORMAL,646,130,SPARK_POS_OK,0.282785,0.285773,0.208818,0.003849,NORMAL,904,4212,0 -36662894,645,140,SPARK_POS_OK,0.212783,0.258812,0.276097,0.278357,NORMAL,647,140,SPARK_POS_OK,0.282663,0.285640,0.208700,0.003834,NORMAL,910,4189,0 -36727894,646,161,SPARK_POS_OK,0.212635,0.258691,0.275950,0.278206,NORMAL,648,160,SPARK_POS_OK,0.282534,0.285493,0.208591,0.003829,NORMAL,921,4158,0 -36792894,647,181,SPARK_POS_OK,0.212511,0.258538,0.275831,0.278075,NORMAL,649,160,SPARK_POS_OK,0.282395,0.285385,0.208468,0.003807,NORMAL,923,4164,0 -36857894,648,180,SPARK_POS_OK,0.212399,0.258464,0.275685,0.277957,NORMAL,650,181,SPARK_POS_OK,0.282272,0.285238,0.208339,0.003818,NORMAL,933,4162,0 -36921894,649,210,SPARK_POS_OK,0.212275,0.258311,0.275542,0.277777,NORMAL,651,180,SPARK_POS_OK,0.282136,0.285095,0.208236,0.003802,NORMAL,938,4234,0 -36984894,650,213,SPARK_POS_OK,0.212106,0.258200,0.275386,0.277677,NORMAL,652,210,SPARK_POS_OK,0.281998,0.284982,0.208116,0.003808,NORMAL,945,4213,0 -37047894,651,230,SPARK_POS_OK,0.212014,0.258107,0.275283,0.277527,NORMAL,653,230,SPARK_POS_OK,0.281868,0.284844,0.207992,0.003803,NORMAL,959,4228,0 -37108894,652,12,SPARK_NEG_OK,0.211840,0.257963,0.275127,0.277390,SOFT_START,654,230,SPARK_POS_OK,0.281720,0.284698,0.207887,0.003822,NORMAL,964,4278,0 -37169894,653,11,SPARK_NEG_OK,0.211723,0.257869,0.275005,0.277253,SOFT_START,655,11,SPARK_NEG_OK,0.281601,0.284568,0.207760,0.003831,SOFT_START,979,4191,0 -37230894,654,30,SPARK_NEG_OK,0.211592,0.257738,0.274858,0.277121,SOFT_START,656,11,SPARK_NEG_OK,0.281478,0.284427,0.207640,0.003812,SOFT_START,988,4244,0 -37290894,655,30,SPARK_NEG_OK,0.211459,0.257616,0.274735,0.276963,SOFT_START,657,31,SPARK_NEG_OK,0.281326,0.284291,0.207534,0.003821,SOFT_START,998,4178,0 -37349894,656,50,SPARK_NEG_OK,0.211344,0.257522,0.274568,0.276856,SOFT_START,658,50,SPARK_NEG_OK,0.281195,0.284154,0.207424,0.003799,SOFT_START,1016,4186,0 -37408894,657,50,SPARK_NEG_OK,0.211175,0.257400,0.274474,0.276735,SOFT_START,659,50,SPARK_NEG_OK,0.281072,0.284021,0.207309,0.003795,SOFT_START,1017,4264,0 -37466894,658,71,SPARK_NEG_OK,0.211040,0.257265,0.274315,0.276607,SOFT_START,660,70,SPARK_NEG_OK,0.280935,0.283883,0.207184,0.003827,SOFT_START,1034,4247,0 -37524894,659,91,SPARK_NEG_OK,0.210924,0.257138,0.274191,0.276452,SOFT_START,661,70,SPARK_NEG_OK,0.280807,0.283751,0.207044,0.003825,SOFT_START,1045,4277,0 -37580894,660,91,SPARK_NEG_OK,0.210773,0.257016,0.274035,0.276287,SOFT_START,662,90,SPARK_NEG_OK,0.280664,0.283605,0.206951,0.003846,SOFT_START,1056,4156,0 -37637894,661,110,SPARK_NEG_OK,0.210651,0.256919,0.273908,0.276170,SOFT_START,663,90,SPARK_NEG_OK,0.280513,0.283462,0.206825,0.003834,SOFT_START,1067,4200,0 -37692894,662,108,SPARK_NEG_OK,0.210524,0.256817,0.273778,0.276014,SOFT_START,664,110,SPARK_NEG_OK,0.280396,0.283341,0.206679,0.003850,SOFT_START,1080,4268,0 -37747894,663,140,SPARK_NEG_OK,0.210339,0.256675,0.273625,0.275890,SOFT_START,665,110,SPARK_NEG_OK,0.280262,0.283211,0.206587,0.003878,SOFT_START,1092,4246,0 -37801894,664,140,SPARK_NEG_OK,0.210227,0.256556,0.273506,0.275755,SOFT_START,666,141,SPARK_NEG_OK,0.280131,0.283070,0.206459,0.003862,SOFT_START,1106,4152,0 -37855894,665,160,SPARK_NEG_OK,0.210127,0.256458,0.273353,0.275602,SOFT_START,667,141,SPARK_NEG_OK,0.280004,0.282941,0.206351,0.003883,SOFT_START,1117,4169,0 -37908894,666,161,SPARK_NEG_OK,0.210000,0.256337,0.273227,0.275472,SOFT_START,668,160,SPARK_NEG_OK,0.279878,0.282794,0.206226,0.003880,SOFT_START,1130,4168,0 -37961894,667,200,SPARK_NEG_OK,0.209829,0.256199,0.273078,0.275325,SOFT_START,669,161,SPARK_NEG_OK,0.279713,0.282645,0.206130,0.003921,SOFT_START,1141,4248,0 -38013894,668,200,SPARK_NEG_OK,0.209727,0.256077,0.272948,0.275184,SOFT_START,670,200,SPARK_NEG_OK,0.279604,0.282503,0.205991,0.003906,SOFT_START,1155,4189,0 -38064894,669,220,SPARK_NEG_OK,0.209596,0.255956,0.272787,0.275062,SOFT_START,671,200,SPARK_NEG_OK,0.279452,0.282353,0.205868,0.003920,SOFT_START,1167,4239,0 -38115894,670,221,SPARK_NEG_OK,0.209432,0.255836,0.272673,0.274916,SOFT_START,672,220,SPARK_NEG_OK,0.279309,0.282218,0.205765,0.003961,SOFT_START,1182,4272,0 -38165894,671,220,SPARK_NEG_OK,0.209312,0.255718,0.272501,0.274780,SOFT_START,673,220,SPARK_NEG_OK,0.279174,0.282106,0.205613,0.003957,SOFT_START,1194,4180,0 -38214894,672,220,SPARK_NEG_OK,0.209182,0.255595,0.272353,0.274642,SOFT_START,674,221,SPARK_NEG_OK,0.279053,0.281949,0.205492,0.003965,SOFT_START,1210,4193,0 -38264894,673,220,SPARK_NEG_OK,0.209062,0.255480,0.272245,0.274504,SOFT_START,675,220,SPARK_NEG_OK,0.278916,0.281812,0.205392,0.003965,SOFT_START,1221,4153,0 -38312894,674,220,SPARK_NEG_OK,0.208949,0.255389,0.272102,0.274378,SOFT_START,676,221,SPARK_NEG_OK,0.278790,0.281681,0.205267,0.003991,SOFT_START,1236,4161,0 -38360894,675,220,SPARK_NEG_OK,0.208792,0.255247,0.271955,0.274234,SOFT_START,677,220,SPARK_NEG_OK,0.278662,0.281528,0.205157,0.003999,SOFT_START,1245,4251,0 -38408894,676,220,SPARK_NEG_OK,0.208645,0.255117,0.271837,0.274081,SOFT_START,678,221,SPARK_NEG_OK,0.278516,0.281422,0.205005,0.004001,SOFT_START,1257,4259,0 -38456894,677,223,SPARK_NEG_OK,0.208504,0.254996,0.271699,0.273960,SOFT_START,679,220,SPARK_NEG_OK,0.278376,0.281266,0.204897,0.004032,SOFT_START,1257,4214,0 -38503894,678,220,SPARK_NEG_OK,0.208384,0.254872,0.271536,0.273805,SOFT_START,680,221,SPARK_NEG_OK,0.278223,0.281140,0.204788,0.004033,SOFT_START,1274,4237,0 -38550894,679,220,SPARK_NEG_OK,0.208232,0.254766,0.271414,0.273679,SOFT_START,681,220,SPARK_NEG_OK,0.278096,0.281001,0.204660,0.004051,SOFT_START,1275,4257,0 -38596894,680,220,SPARK_NEG_OK,0.208101,0.254632,0.271282,0.273514,SOFT_START,682,221,SPARK_NEG_OK,0.277963,0.280815,0.204550,0.004060,SOFT_START,1291,4202,0 -38643894,681,221,SPARK_NEG_OK,0.207956,0.254499,0.271150,0.273395,SOFT_START,683,220,SPARK_NEG_OK,0.277845,0.280711,0.204415,0.004084,SOFT_START,1293,4195,0 -38689894,682,221,SPARK_NEG_OK,0.207830,0.254421,0.270997,0.273231,SOFT_START,684,223,SPARK_NEG_OK,0.277692,0.280572,0.204302,0.004092,SOFT_START,1309,4227,0 -38734894,683,220,SPARK_NEG_OK,0.207710,0.254275,0.270846,0.273100,SOFT_START,685,220,SPARK_NEG_OK,0.277570,0.280423,0.204185,0.004102,SOFT_START,1310,4175,0 -38780894,684,221,SPARK_NEG_OK,0.207548,0.254160,0.270709,0.272974,SOFT_START,686,217,SPARK_NEG_OK,0.277417,0.280293,0.204057,0.004109,SOFT_START,1317,4218,0 -38825894,685,220,SPARK_NEG_OK,0.207415,0.254024,0.270590,0.272829,SOFT_START,687,221,SPARK_NEG_OK,0.277311,0.280139,0.203938,0.004123,SOFT_START,1326,4193,0 -38870894,686,222,SPARK_NEG_OK,0.207291,0.253907,0.270428,0.272685,SOFT_START,688,220,SPARK_NEG_OK,0.277144,0.280020,0.203822,0.004132,SOFT_START,1326,4165,0 -38915894,687,221,SPARK_NEG_OK,0.207150,0.253793,0.270294,0.272558,SOFT_START,689,220,SPARK_NEG_OK,0.277017,0.279866,0.203716,0.004162,SOFT_START,1337,4224,0 -38960894,688,220,SPARK_NEG_OK,0.207025,0.253657,0.270154,0.272431,SOFT_START,690,220,SPARK_NEG_OK,0.276886,0.279739,0.203577,0.004151,SOFT_START,1338,4199,0 -39005894,689,220,SPARK_NEG_OK,0.206887,0.253541,0.270010,0.272270,SOFT_START,691,221,SPARK_NEG_OK,0.276770,0.279604,0.203462,0.004165,SOFT_START,1346,4177,0 -39049894,690,221,SPARK_NEG_OK,0.206779,0.253445,0.269864,0.272130,SOFT_START,692,221,SPARK_NEG_OK,0.276610,0.279459,0.203337,0.004172,SOFT_START,1348,4204,0 -39093894,691,220,SPARK_NEG_OK,0.206625,0.253299,0.269744,0.271980,SOFT_START,693,220,SPARK_NEG_OK,0.276486,0.279325,0.203225,0.004199,SOFT_START,1351,4219,0 -39138894,692,220,SPARK_NEG_OK,0.206511,0.253202,0.269613,0.271854,SOFT_START,694,220,SPARK_NEG_OK,0.276347,0.279167,0.203116,0.004188,SOFT_START,1358,4187,0 -39182894,693,221,SPARK_NEG_OK,0.206396,0.253100,0.269476,0.271717,SOFT_START,695,220,SPARK_NEG_OK,0.276213,0.279039,0.203003,0.004205,SOFT_START,1358,4154,0 -39226894,694,220,SPARK_NEG_OK,0.206258,0.252935,0.269325,0.271574,SOFT_START,696,220,SPARK_NEG_OK,0.276089,0.278912,0.202873,0.004227,SOFT_START,1364,4179,0 -39270894,695,220,SPARK_NEG_OK,0.206105,0.252839,0.269194,0.271446,SOFT_START,697,221,SPARK_NEG_OK,0.275929,0.278774,0.202767,0.004229,SOFT_START,1366,4254,0 -39314894,696,181,SPARK_NEG_OK,0.205987,0.252725,0.269056,0.271299,SOFT_START,698,180,SPARK_NEG_OK,0.275809,0.278629,0.202613,0.004247,SOFT_START,1365,4224,0 -39357894,697,180,SPARK_NEG_OK,0.205838,0.252599,0.268899,0.271145,SOFT_START,699,181,SPARK_NEG_OK,0.275657,0.278487,0.202522,0.004249,SOFT_START,1367,4206,0 -39401894,698,140,SPARK_NEG_OK,0.205708,0.252507,0.268775,0.271013,SOFT_START,700,180,SPARK_NEG_OK,0.275525,0.278352,0.202399,0.004258,SOFT_START,1363,4240,0 -39445894,699,140,SPARK_NEG_OK,0.205578,0.252335,0.268633,0.270877,SOFT_START,701,140,SPARK_NEG_OK,0.275407,0.278224,0.202285,0.004265,SOFT_START,1362,4214,0 -39489894,700,140,SPARK_NEG_OK,0.205450,0.252241,0.268512,0.270755,SOFT_START,702,141,SPARK_NEG_OK,0.275276,0.278093,0.202169,0.004291,SOFT_START,1362,4190,0 -39534894,701,100,SPARK_NEG_OK,0.205328,0.252104,0.268357,0.270594,SOFT_START,703,100,SPARK_NEG_OK,0.275124,0.277960,0.202031,0.004262,SOFT_START,1350,4195,0 -39578894,702,100,SPARK_NEG_OK,0.205196,0.252012,0.268247,0.270457,SOFT_START,704,102,SPARK_NEG_OK,0.275012,0.277813,0.201943,0.004296,SOFT_START,1351,4207,0 -39623894,703,70,SPARK_NEG_OK,0.205076,0.251896,0.268098,0.270344,SOFT_START,705,71,SPARK_NEG_OK,0.274871,0.277678,0.201812,0.004296,SOFT_START,1337,4182,0 -39668894,704,70,SPARK_NEG_OK,0.204934,0.251762,0.267957,0.270193,SOFT_START,706,70,SPARK_NEG_OK,0.274735,0.277537,0.201693,0.004286,SOFT_START,1339,4177,0 -39713894,705,41,SPARK_NEG_OK,0.204822,0.251641,0.267810,0.270061,SOFT_START,707,70,SPARK_NEG_OK,0.274608,0.277390,0.201574,0.004303,SOFT_START,1330,4167,0 -39758894,706,40,SPARK_NEG_OK,0.204682,0.251549,0.267684,0.269920,SOFT_START,708,41,SPARK_NEG_OK,0.274457,0.277274,0.201457,0.004306,SOFT_START,1324,4195,0 -39804894,707,40,SPARK_NEG_OK,0.204546,0.251395,0.267525,0.269762,SOFT_START,709,40,SPARK_NEG_OK,0.274332,0.277125,0.201312,0.004304,SOFT_START,1324,4223,0 -39943894,708,211,SPARK_POS_OK,0.204431,0.251308,0.267450,0.269685,NORMAL,710,210,SPARK_POS_OK,0.274249,0.277008,0.201241,0.004118,NORMAL,1290,4283,0 -39989894,709,210,SPARK_POS_OK,0.204310,0.251195,0.267299,0.269525,NORMAL,711,211,SPARK_POS_OK,0.274115,0.276889,0.201128,0.004120,NORMAL,1283,4204,0 -40037894,710,170,SPARK_POS_OK,0.204191,0.251074,0.267169,0.269407,NORMAL,712,210,SPARK_POS_OK,0.273974,0.276754,0.201014,0.004125,NORMAL,1269,4236,0 -40084894,711,170,SPARK_POS_OK,0.204046,0.250964,0.267050,0.269277,NORMAL,713,171,SPARK_POS_OK,0.273856,0.276611,0.200901,0.004141,NORMAL,1256,4229,0 -40133894,712,131,SPARK_POS_OK,0.203942,0.250819,0.266888,0.269134,NORMAL,714,170,SPARK_POS_OK,0.273709,0.276471,0.200775,0.004130,NORMAL,1242,4169,0 -40182894,713,130,SPARK_POS_OK,0.203801,0.250719,0.266763,0.268992,NORMAL,715,131,SPARK_POS_OK,0.273576,0.276337,0.200660,0.004146,NORMAL,1229,4168,0 -40231894,714,101,SPARK_POS_OK,0.203679,0.250602,0.266610,0.268854,NORMAL,716,130,SPARK_POS_OK,0.273449,0.276200,0.200556,0.004156,NORMAL,1214,4213,0 -40281894,715,100,SPARK_POS_OK,0.203544,0.250499,0.266479,0.268734,NORMAL,717,100,SPARK_POS_OK,0.273300,0.276085,0.200437,0.004150,NORMAL,1201,4153,0 -40332894,716,60,SPARK_POS_OK,0.203425,0.250357,0.266336,0.268586,NORMAL,718,101,SPARK_POS_OK,0.273175,0.275934,0.200318,0.004133,NORMAL,1187,4237,0 -40383894,717,61,SPARK_POS_OK,0.203306,0.250285,0.266254,0.268469,NORMAL,719,60,SPARK_POS_OK,0.273046,0.275812,0.200194,0.004146,NORMAL,1173,4155,0 -40435894,718,42,SPARK_POS_OK,0.203170,0.250174,0.266094,0.268306,NORMAL,720,60,SPARK_POS_OK,0.272930,0.275672,0.200098,0.004148,NORMAL,1156,4268,0 -40487894,719,40,SPARK_POS_OK,0.203015,0.250028,0.265937,0.268164,NORMAL,721,41,SPARK_POS_OK,0.272765,0.275537,0.199981,0.004146,NORMAL,1142,4276,0 -40540894,720,25,SPARK_POS_OK,0.202909,0.249906,0.265791,0.268040,NORMAL,722,40,SPARK_POS_OK,0.272655,0.275398,0.199848,0.004122,NORMAL,1125,4148,0 -40594894,721,25,SPARK_POS_OK,0.202784,0.249798,0.265670,0.267910,NORMAL,723,25,SPARK_POS_OK,0.272522,0.275282,0.199748,0.004113,NORMAL,1110,4255,0 -40649894,722,25,SPARK_POS_OK,0.202652,0.249678,0.265548,0.267772,NORMAL,724,25,SPARK_POS_OK,0.272388,0.275137,0.199640,0.004106,NORMAL,1110,4212,0 -40705894,723,25,SPARK_POS_OK,0.202504,0.249600,0.265426,0.267656,NORMAL,725,25,SPARK_POS_OK,0.272263,0.275016,0.199504,0.004092,NORMAL,1110,4270,0 -40761894,724,25,SPARK_POS_OK,0.202400,0.249467,0.265272,0.267516,NORMAL,726,25,SPARK_POS_OK,0.272152,0.274868,0.199398,0.004108,NORMAL,1110,4240,0 -40818894,725,25,SPARK_POS_OK,0.202259,0.249345,0.265149,0.267385,NORMAL,727,25,SPARK_POS_OK,0.272015,0.274736,0.199280,0.004070,NORMAL,1110,4227,0 -40876894,726,25,SPARK_POS_OK,0.202144,0.249227,0.265021,0.267236,NORMAL,728,25,SPARK_POS_OK,0.271885,0.274595,0.199181,0.004079,NORMAL,1110,4159,0 -40934894,727,25,SPARK_POS_OK,0.202006,0.249094,0.264886,0.267131,NORMAL,729,25,SPARK_POS_OK,0.271756,0.274480,0.199078,0.004046,NORMAL,1110,4272,0 -40994894,728,25,SPARK_POS_OK,0.201861,0.249012,0.264758,0.266984,NORMAL,730,25,SPARK_POS_OK,0.271606,0.274345,0.198958,0.004050,NORMAL,1110,4247,0 -41053894,729,25,SPARK_POS_OK,0.201721,0.248911,0.264663,0.266860,NORMAL,731,25,SPARK_POS_OK,0.271502,0.274233,0.198841,0.004031,NORMAL,1110,4273,0 -41114894,730,25,SPARK_POS_OK,0.201633,0.248787,0.264506,0.266732,NORMAL,732,25,SPARK_POS_OK,0.271386,0.274118,0.198747,0.004001,NORMAL,1110,4169,0 -41176894,731,25,SPARK_POS_OK,0.201508,0.248668,0.264362,0.266598,NORMAL,733,25,SPARK_POS_OK,0.271242,0.273969,0.198644,0.004007,NORMAL,1110,4191,0 -41238894,732,25,SPARK_POS_OK,0.201376,0.248557,0.264245,0.266468,NORMAL,734,25,SPARK_POS_OK,0.271113,0.273847,0.198520,0.003988,NORMAL,1110,4256,0 -41301894,733,30,SPARK_POS_OK,0.201266,0.248428,0.264118,0.266318,NORMAL,735,30,SPARK_POS_OK,0.271019,0.273695,0.198419,0.003971,NORMAL,84,4205,0 -41363894,734,30,SPARK_POS_OK,0.201120,0.248331,0.263957,0.266209,NORMAL,736,30,SPARK_POS_OK,0.270879,0.273562,0.198269,0.003963,NORMAL,957,4204,0 -41426894,735,70,SPARK_POS_OK,0.201012,0.248233,0.263847,0.266065,NORMAL,737,71,SPARK_POS_OK,0.270754,0.273460,0.198188,0.003932,NORMAL,952,4159,0 -41489894,736,121,SPARK_POS_OK,0.200889,0.248101,0.263735,0.265954,NORMAL,738,70,SPARK_POS_OK,0.270635,0.273333,0.198066,0.003924,NORMAL,951,4218,0 -41552894,737,120,SPARK_POS_OK,0.200770,0.248005,0.263599,0.265783,NORMAL,739,120,SPARK_POS_OK,0.270470,0.273159,0.197971,0.003912,NORMAL,952,4164,0 -41615894,738,160,SPARK_POS_OK,0.200683,0.247887,0.263482,0.265682,NORMAL,740,161,SPARK_POS_OK,0.270364,0.273066,0.197852,0.003889,NORMAL,954,4165,0 -41678894,739,161,SPARK_POS_OK,0.200534,0.247756,0.263340,0.265562,NORMAL,741,160,SPARK_POS_OK,0.270231,0.272928,0.197769,0.003905,NORMAL,956,4218,0 -41740894,740,190,SPARK_POS_OK,0.200435,0.247624,0.263224,0.265428,NORMAL,742,190,SPARK_POS_OK,0.270122,0.272796,0.197648,0.003864,NORMAL,964,4154,0 -41802894,741,220,SPARK_POS_OK,0.200307,0.247547,0.263053,0.265304,NORMAL,743,190,SPARK_POS_OK,0.269973,0.272658,0.197528,0.003868,NORMAL,970,4253,0 -41863894,742,220,SPARK_POS_OK,0.200197,0.247444,0.262943,0.265173,NORMAL,744,221,SPARK_POS_OK,0.269864,0.272553,0.197408,0.003874,NORMAL,979,4164,0 -42043894,743,30,SPARK_NEG_OK,0.200107,0.247387,0.262863,0.265078,SOFT_START,745,30,SPARK_NEG_OK,0.269786,0.272447,0.197350,0.003678,SOFT_START,1009,4247,0 -42102894,744,60,SPARK_NEG_OK,0.199975,0.247245,0.262704,0.264937,SOFT_START,746,30,SPARK_NEG_OK,0.269638,0.272316,0.197238,0.003660,SOFT_START,1017,4203,0 -42160894,745,60,SPARK_NEG_OK,0.199851,0.247157,0.262578,0.264801,SOFT_START,747,61,SPARK_NEG_OK,0.269511,0.272185,0.197123,0.003695,SOFT_START,1027,4196,0 -42218894,746,90,SPARK_NEG_OK,0.199724,0.246996,0.262470,0.264683,SOFT_START,748,61,SPARK_NEG_OK,0.269379,0.272081,0.197006,0.003712,SOFT_START,1036,4165,0 -42275894,747,90,SPARK_NEG_OK,0.199598,0.246891,0.262341,0.264522,SOFT_START,749,91,SPARK_NEG_OK,0.269270,0.271949,0.196900,0.003718,SOFT_START,1048,4271,0 -42332894,748,110,SPARK_NEG_OK,0.199476,0.246797,0.262198,0.264432,SOFT_START,750,107,SPARK_NEG_OK,0.269136,0.271783,0.196793,0.003707,SOFT_START,1060,4178,0 -42388894,749,110,SPARK_NEG_OK,0.199374,0.246669,0.262067,0.264315,SOFT_START,751,111,SPARK_NEG_OK,0.269028,0.271673,0.196687,0.003733,SOFT_START,1073,4157,0 -42442894,750,140,SPARK_NEG_OK,0.199243,0.246548,0.261946,0.264188,SOFT_START,752,140,SPARK_NEG_OK,0.268887,0.271544,0.196567,0.003757,SOFT_START,1098,4178,0 -42497894,751,141,SPARK_NEG_OK,0.199089,0.246437,0.261806,0.264030,SOFT_START,753,140,SPARK_NEG_OK,0.268753,0.271395,0.196472,0.003762,SOFT_START,1099,4277,0 -42550894,752,171,SPARK_NEG_OK,0.198994,0.246323,0.261676,0.263922,SOFT_START,754,170,SPARK_NEG_OK,0.268612,0.271274,0.196361,0.003766,SOFT_START,1123,4183,0 -42604894,753,170,SPARK_NEG_OK,0.198861,0.246233,0.261565,0.263759,SOFT_START,755,170,SPARK_NEG_OK,0.268504,0.271167,0.196233,0.003782,SOFT_START,1124,4170,0 -42656894,754,210,SPARK_NEG_OK,0.198743,0.246103,0.261415,0.263638,SOFT_START,756,211,SPARK_NEG_OK,0.268367,0.271031,0.196128,0.003785,SOFT_START,1148,4160,0 -42708894,755,210,SPARK_NEG_OK,0.198614,0.245963,0.261278,0.263526,SOFT_START,757,210,SPARK_NEG_OK,0.268233,0.270876,0.196034,0.003813,SOFT_START,1149,4240,0 -42759894,756,220,SPARK_NEG_OK,0.198482,0.245838,0.261155,0.263387,SOFT_START,758,220,SPARK_NEG_OK,0.268111,0.270748,0.195891,0.003822,SOFT_START,1175,4260,0 -42810894,757,220,SPARK_NEG_OK,0.198360,0.245746,0.261000,0.263236,SOFT_START,759,220,SPARK_NEG_OK,0.267989,0.270618,0.195792,0.003821,SOFT_START,1176,4207,0 -42860894,758,220,SPARK_NEG_OK,0.198218,0.245627,0.260875,0.263098,SOFT_START,760,223,SPARK_NEG_OK,0.267848,0.270478,0.195671,0.003844,SOFT_START,1204,4237,0 -42910894,759,220,SPARK_NEG_OK,0.198099,0.245525,0.260764,0.262961,SOFT_START,761,220,SPARK_NEG_OK,0.267730,0.270354,0.195575,0.003870,SOFT_START,1205,4184,0 -42959894,760,220,SPARK_NEG_OK,0.197989,0.245395,0.260627,0.262851,SOFT_START,762,221,SPARK_NEG_OK,0.267601,0.270222,0.195455,0.003886,SOFT_START,1229,4168,0 -43007894,761,221,SPARK_NEG_OK,0.197859,0.245275,0.260477,0.262731,SOFT_START,763,220,SPARK_NEG_OK,0.267437,0.270085,0.195344,0.003896,SOFT_START,1230,4202,0 -43056894,762,220,SPARK_NEG_OK,0.197738,0.245203,0.260365,0.262597,SOFT_START,764,221,SPARK_NEG_OK,0.267359,0.269965,0.195224,0.003885,SOFT_START,1239,4196,0 -43104894,763,221,SPARK_NEG_OK,0.197602,0.245073,0.260230,0.262448,SOFT_START,765,220,SPARK_NEG_OK,0.267217,0.269827,0.195113,0.003901,SOFT_START,1251,4250,0 -43151894,764,220,SPARK_NEG_OK,0.197474,0.244928,0.260065,0.262322,SOFT_START,766,220,SPARK_NEG_OK,0.267094,0.269674,0.194982,0.003909,SOFT_START,1258,4184,0 -43199894,765,221,SPARK_NEG_OK,0.197357,0.244827,0.259967,0.262184,SOFT_START,767,220,SPARK_NEG_OK,0.266970,0.269556,0.194883,0.003923,SOFT_START,1268,4231,0 -43246894,766,220,SPARK_NEG_OK,0.197248,0.244722,0.259804,0.262077,SOFT_START,768,220,SPARK_NEG_OK,0.266804,0.269414,0.194749,0.003939,SOFT_START,1276,4149,0 -43292894,767,220,SPARK_NEG_OK,0.197117,0.244605,0.259694,0.261919,SOFT_START,769,220,SPARK_NEG_OK,0.266705,0.269303,0.194654,0.003959,SOFT_START,1286,4169,0 -43339894,768,220,SPARK_NEG_OK,0.196993,0.244474,0.259559,0.261797,SOFT_START,770,221,SPARK_NEG_OK,0.266541,0.269161,0.194563,0.003976,SOFT_START,1286,4190,0 -43385894,769,220,SPARK_NEG_OK,0.196869,0.244370,0.259448,0.261645,SOFT_START,771,220,SPARK_NEG_OK,0.266452,0.269037,0.194426,0.003982,SOFT_START,1302,4269,0 -43431894,770,221,SPARK_NEG_OK,0.196736,0.244229,0.259302,0.261519,SOFT_START,772,221,SPARK_NEG_OK,0.266292,0.268895,0.194313,0.003998,SOFT_START,1304,4262,0 -43477894,771,220,SPARK_NEG_OK,0.196609,0.244130,0.259157,0.261397,SOFT_START,773,220,SPARK_NEG_OK,0.266187,0.268759,0.194212,0.003994,SOFT_START,1317,4193,0 -43522894,772,221,SPARK_NEG_OK,0.196499,0.244040,0.259016,0.261270,SOFT_START,774,220,SPARK_NEG_OK,0.266053,0.268638,0.194097,0.004019,SOFT_START,1319,4175,0 -43567894,773,220,SPARK_NEG_OK,0.196381,0.243890,0.258903,0.261110,SOFT_START,775,221,SPARK_NEG_OK,0.265919,0.268518,0.193987,0.004036,SOFT_START,1323,4172,0 -43612894,774,220,SPARK_NEG_OK,0.196264,0.243790,0.258788,0.260985,SOFT_START,776,220,SPARK_NEG_OK,0.265797,0.268373,0.193867,0.004045,SOFT_START,1330,4153,0 -43658894,775,220,SPARK_NEG_OK,0.196141,0.243672,0.258629,0.260858,SOFT_START,777,220,SPARK_NEG_OK,0.265661,0.268230,0.193754,0.004045,SOFT_START,1332,4201,0 -43702894,776,220,SPARK_NEG_OK,0.196037,0.243563,0.258504,0.260714,SOFT_START,778,220,SPARK_NEG_OK,0.265544,0.268102,0.193647,0.004055,SOFT_START,1338,4158,0 -43747894,777,220,SPARK_NEG_OK,0.195891,0.243415,0.258385,0.260592,SOFT_START,779,220,SPARK_NEG_OK,0.265426,0.268000,0.193529,0.004078,SOFT_START,1338,4246,0 -43792894,778,201,SPARK_NEG_OK,0.195798,0.243320,0.258229,0.260479,SOFT_START,780,201,SPARK_NEG_OK,0.265290,0.267842,0.193396,0.004094,SOFT_START,1340,4156,0 -43837894,779,200,SPARK_NEG_OK,0.195658,0.243208,0.258101,0.260347,SOFT_START,781,200,SPARK_NEG_OK,0.265152,0.267714,0.193290,0.004086,SOFT_START,1341,4225,0 -43881894,780,160,SPARK_NEG_OK,0.195522,0.243081,0.257956,0.260199,SOFT_START,782,200,SPARK_NEG_OK,0.265024,0.267597,0.193209,0.004101,SOFT_START,1340,4182,0 -43926894,781,161,SPARK_NEG_OK,0.195416,0.242981,0.257821,0.260077,SOFT_START,783,161,SPARK_NEG_OK,0.264905,0.267470,0.193109,0.004116,SOFT_START,1342,4163,0 -43971894,782,130,SPARK_NEG_OK,0.195294,0.242833,0.257735,0.259920,SOFT_START,784,158,SPARK_NEG_OK,0.264760,0.267307,0.192973,0.004118,SOFT_START,1339,4208,0 -44016894,783,130,SPARK_NEG_OK,0.195179,0.242740,0.257558,0.259807,SOFT_START,785,130,SPARK_NEG_OK,0.264655,0.267206,0.192842,0.004129,SOFT_START,1339,4221,0 -44060894,784,128,SPARK_NEG_OK,0.195053,0.242636,0.257455,0.259690,SOFT_START,786,131,SPARK_NEG_OK,0.264505,0.267072,0.192737,0.004144,SOFT_START,1339,4236,0 -44106894,785,100,SPARK_NEG_OK,0.194902,0.242509,0.257328,0.259535,SOFT_START,787,100,SPARK_NEG_OK,0.264392,0.266936,0.192629,0.004129,SOFT_START,1329,4203,0 -44151894,786,101,SPARK_NEG_OK,0.194796,0.242376,0.257199,0.259408,SOFT_START,788,100,SPARK_NEG_OK,0.264261,0.266806,0.192531,0.004149,SOFT_START,1330,4178,0 -44196894,787,80,SPARK_NEG_OK,0.194678,0.242286,0.257065,0.259286,SOFT_START,789,101,SPARK_NEG_OK,0.264124,0.266667,0.192397,0.004155,SOFT_START,1322,4176,0 -44242894,788,80,SPARK_NEG_OK,0.194545,0.242181,0.256949,0.259129,SOFT_START,790,80,SPARK_NEG_OK,0.264000,0.266525,0.192301,0.004146,SOFT_START,1318,4255,0 -44287894,789,61,SPARK_NEG_OK,0.194429,0.242080,0.256811,0.259014,SOFT_START,791,81,SPARK_NEG_OK,0.263849,0.266387,0.192185,0.004156,SOFT_START,1309,4187,0 -44333894,790,60,SPARK_NEG_OK,0.194306,0.241948,0.256664,0.258874,SOFT_START,792,60,SPARK_NEG_OK,0.263768,0.266272,0.192068,0.004176,SOFT_START,1304,4182,0 -44379894,791,61,SPARK_NEG_OK,0.194189,0.241806,0.256536,0.258739,SOFT_START,793,60,SPARK_NEG_OK,0.263627,0.266151,0.191975,0.004157,SOFT_START,1304,4175,0 -44426894,792,50,SPARK_NEG_OK,0.194061,0.241702,0.256386,0.258610,SOFT_START,794,50,SPARK_NEG_OK,0.263498,0.266024,0.191851,0.004165,SOFT_START,1291,4264,0 -44472894,793,50,SPARK_NEG_OK,0.193927,0.241601,0.256268,0.258484,SOFT_START,795,50,SPARK_NEG_OK,0.263357,0.265887,0.191762,0.004178,SOFT_START,1293,4257,0 -44519894,794,50,SPARK_NEG_OK,0.193799,0.241491,0.256147,0.258339,SOFT_START,796,51,SPARK_NEG_OK,0.263250,0.265761,0.191653,0.004188,SOFT_START,1281,4241,0 -44566894,795,49,SPARK_NEG_OK,0.193665,0.241373,0.256011,0.258195,SOFT_START,797,50,SPARK_NEG_OK,0.263091,0.265631,0.191526,0.004173,SOFT_START,1283,4276,0 -44613894,796,50,SPARK_NEG_OK,0.193540,0.241243,0.255875,0.258098,SOFT_START,798,51,SPARK_NEG_OK,0.263007,0.265497,0.191412,0.004163,SOFT_START,1276,4193,0 -44660894,797,50,SPARK_NEG_OK,0.193436,0.241147,0.255746,0.257978,SOFT_START,799,50,SPARK_NEG_OK,0.262855,0.265361,0.191306,0.004170,SOFT_START,1272,4229,0 -44707894,798,50,SPARK_NEG_OK,0.193288,0.241022,0.255612,0.257819,SOFT_START,800,51,SPARK_NEG_OK,0.262737,0.265232,0.191194,0.004177,SOFT_START,1265,4268,0 -44755894,799,50,SPARK_NEG_OK,0.193172,0.240936,0.255510,0.257689,SOFT_START,801,50,SPARK_NEG_OK,0.262594,0.265086,0.191092,0.004173,SOFT_START,1260,4149,0 -44803894,800,50,SPARK_NEG_OK,0.193061,0.240822,0.255350,0.257562,SOFT_START,802,51,SPARK_NEG_OK,0.262484,0.264987,0.190976,0.004181,SOFT_START,1255,4228,0 -44851894,801,50,SPARK_NEG_OK,0.192931,0.240676,0.255222,0.257454,SOFT_START,803,50,SPARK_NEG_OK,0.262373,0.264848,0.190865,0.004160,SOFT_START,1253,4212,0 -44898894,802,50,SPARK_NEG_OK,0.192834,0.240576,0.255093,0.257311,SOFT_START,804,51,SPARK_NEG_OK,0.262241,0.264716,0.190771,0.004186,SOFT_START,1253,4191,0 -44947894,803,50,SPARK_NEG_OK,0.192724,0.240459,0.254962,0.257189,SOFT_START,805,50,SPARK_NEG_OK,0.262112,0.264597,0.190664,0.004171,SOFT_START,1245,4150,0 -44995894,804,50,SPARK_NEG_OK,0.192583,0.240365,0.254850,0.257064,SOFT_START,806,51,SPARK_NEG_OK,0.261984,0.264466,0.190551,0.004168,SOFT_START,1246,4155,0 -45043894,805,50,SPARK_NEG_OK,0.192483,0.240215,0.254744,0.256926,SOFT_START,807,50,SPARK_NEG_OK,0.261874,0.264334,0.190439,0.004156,SOFT_START,1240,4178,0 -45091894,806,48,SPARK_NEG_OK,0.192343,0.240144,0.254613,0.256810,SOFT_START,808,51,SPARK_NEG_OK,0.261713,0.264204,0.190327,0.004158,SOFT_START,1241,4253,0 -45140894,807,50,SPARK_NEG_OK,0.192224,0.240026,0.254460,0.256689,SOFT_START,809,50,SPARK_NEG_OK,0.261614,0.264077,0.190225,0.004165,SOFT_START,1232,4243,0 -45189894,808,50,SPARK_NEG_OK,0.192109,0.239901,0.254341,0.256534,SOFT_START,810,50,SPARK_NEG_OK,0.261489,0.263938,0.190108,0.004143,SOFT_START,1234,4284,0 -45238894,809,51,SPARK_NEG_OK,0.191958,0.239796,0.254230,0.256408,SOFT_START,811,50,SPARK_NEG_OK,0.261356,0.263807,0.190001,0.004138,SOFT_START,1229,4268,0 -45286894,810,47,SPARK_NEG_OK,0.191852,0.239690,0.254098,0.256292,SOFT_START,812,50,SPARK_NEG_OK,0.261207,0.263699,0.189890,0.004146,SOFT_START,1226,4162,0 -45335894,811,51,SPARK_NEG_OK,0.191737,0.239571,0.253947,0.256172,SOFT_START,813,50,SPARK_NEG_OK,0.261111,0.263574,0.189781,0.004153,SOFT_START,1223,4172,0 -45385894,812,50,SPARK_NEG_OK,0.191611,0.239471,0.253817,0.256026,SOFT_START,814,50,SPARK_NEG_OK,0.260968,0.263440,0.189676,0.004123,SOFT_START,1221,4266,0 -45434894,813,47,SPARK_NEG_OK,0.191482,0.239350,0.253700,0.255923,SOFT_START,815,51,SPARK_NEG_OK,0.260872,0.263320,0.189580,0.004151,SOFT_START,1219,4251,0 -45483894,814,50,SPARK_NEG_OK,0.191370,0.239239,0.253552,0.255758,SOFT_START,816,50,SPARK_NEG_OK,0.260741,0.263183,0.189472,0.004148,SOFT_START,1219,4223,0 -45532894,815,50,SPARK_NEG_OK,0.191237,0.239108,0.253436,0.255647,SOFT_START,817,50,SPARK_NEG_OK,0.260611,0.263052,0.189347,0.004121,SOFT_START,1216,4231,0 -45582894,816,51,SPARK_NEG_OK,0.191110,0.239028,0.253310,0.255525,SOFT_START,818,50,SPARK_NEG_OK,0.260473,0.262930,0.189257,0.004116,SOFT_START,1216,4237,0 -45631894,817,49,SPARK_NEG_OK,0.190997,0.238910,0.253175,0.255381,SOFT_START,819,50,SPARK_NEG_OK,0.260382,0.262802,0.189146,0.004120,SOFT_START,1216,4244,0 -45680894,818,50,SPARK_NEG_OK,0.190886,0.238796,0.253065,0.255262,SOFT_START,820,51,SPARK_NEG_OK,0.260221,0.262699,0.189050,0.004132,SOFT_START,1210,4155,0 -45730894,819,50,SPARK_NEG_OK,0.190738,0.238699,0.252901,0.255105,SOFT_START,821,50,SPARK_NEG_OK,0.260109,0.262575,0.188913,0.004126,SOFT_START,1212,4249,0 -45780894,820,50,SPARK_NEG_OK,0.190637,0.238562,0.252810,0.255017,SOFT_START,822,50,SPARK_NEG_OK,0.259993,0.262415,0.188825,0.004118,SOFT_START,1205,4206,0 -45830894,821,51,SPARK_NEG_OK,0.190503,0.238465,0.252685,0.254884,SOFT_START,823,50,SPARK_NEG_OK,0.259852,0.262313,0.188717,0.004117,SOFT_START,1206,4219,0 -45879894,822,48,SPARK_NEG_OK,0.190406,0.238347,0.252525,0.254745,SOFT_START,824,50,SPARK_NEG_OK,0.259729,0.262196,0.188599,0.004111,SOFT_START,1202,4164,0 -45929894,823,50,SPARK_NEG_OK,0.190293,0.238234,0.252434,0.254620,SOFT_START,825,51,SPARK_NEG_OK,0.259622,0.262054,0.188497,0.004097,SOFT_START,1203,4164,0 -45979894,824,41,SPARK_NEG_OK,0.190171,0.238089,0.252297,0.254486,SOFT_START,826,40,SPARK_NEG_OK,0.259511,0.261909,0.188398,0.004105,SOFT_START,1201,4237,0 -46029894,825,40,SPARK_NEG_OK,0.190046,0.237992,0.252163,0.254358,SOFT_START,827,40,SPARK_NEG_OK,0.259376,0.261799,0.188283,0.004096,SOFT_START,1202,4219,0 -46079894,826,30,SPARK_NEG_OK,0.189935,0.237876,0.252033,0.254241,SOFT_START,828,30,SPARK_NEG_OK,0.259261,0.261660,0.188177,0.004101,SOFT_START,1199,4192,0 -46129894,827,30,SPARK_NEG_OK,0.189816,0.237765,0.251942,0.254119,SOFT_START,829,30,SPARK_NEG_OK,0.259131,0.261537,0.188060,0.004087,SOFT_START,1200,4206,0 -46179894,828,15,SPARK_NEG_OK,0.189692,0.237678,0.251780,0.253997,SOFT_START,830,12,SPARK_NEG_OK,0.259007,0.261403,0.187978,0.004088,SOFT_START,1192,4174,0 -46230894,829,12,SPARK_NEG_OK,0.189592,0.237572,0.251632,0.253850,SOFT_START,831,11,SPARK_NEG_OK,0.258870,0.261305,0.187864,0.004097,SOFT_START,1193,4175,0 -46281894,830,240,SPARK_POS_OK,0.189475,0.237434,0.251530,0.253745,NORMAL,832,11,SPARK_NEG_OK,0.258766,0.261147,0.187738,0.004087,SOFT_START,1194,4225,0 -46331894,831,240,SPARK_POS_OK,0.189345,0.237330,0.251409,0.253618,NORMAL,833,241,SPARK_POS_OK,0.258665,0.261039,0.187638,0.004082,NORMAL,1184,4245,0 -46382894,832,231,SPARK_POS_OK,0.189261,0.237217,0.251272,0.253481,NORMAL,834,240,SPARK_POS_OK,0.258522,0.260929,0.187556,0.004079,NORMAL,1179,4168,0 -46433894,833,230,SPARK_POS_OK,0.189138,0.237136,0.251175,0.253382,NORMAL,835,230,SPARK_POS_OK,0.258383,0.260813,0.187426,0.004068,NORMAL,1176,4228,0 -46484894,834,220,SPARK_POS_OK,0.189012,0.237026,0.251043,0.253245,NORMAL,836,231,SPARK_POS_OK,0.258259,0.260691,0.187322,0.004076,NORMAL,1171,4212,0 -46536894,835,223,SPARK_POS_OK,0.188912,0.236922,0.250911,0.253098,NORMAL,837,220,SPARK_POS_OK,0.258138,0.260543,0.187244,0.004051,NORMAL,1169,4213,0 -46587894,836,200,SPARK_POS_OK,0.188764,0.236806,0.250795,0.253014,NORMAL,838,220,SPARK_POS_OK,0.258026,0.260438,0.187150,0.004058,NORMAL,1164,4272,0 -46639894,837,200,SPARK_POS_OK,0.188665,0.236703,0.250667,0.252843,NORMAL,839,201,SPARK_POS_OK,0.257918,0.260280,0.187024,0.004051,NORMAL,1161,4206,0 -46691894,838,190,SPARK_POS_OK,0.188524,0.236609,0.250556,0.252748,NORMAL,840,200,SPARK_POS_OK,0.257770,0.260161,0.186925,0.004048,NORMAL,1154,4239,0 -46743894,839,191,SPARK_POS_OK,0.188426,0.236479,0.250418,0.252605,NORMAL,841,190,SPARK_POS_OK,0.257676,0.260048,0.186810,0.004051,NORMAL,1150,4206,0 -46796894,840,180,SPARK_POS_OK,0.188310,0.236364,0.250295,0.252498,NORMAL,842,190,SPARK_POS_OK,0.257535,0.259948,0.186688,0.004035,NORMAL,1143,4232,0 -46848894,841,180,SPARK_POS_OK,0.188194,0.236236,0.250141,0.252351,NORMAL,843,181,SPARK_POS_OK,0.257429,0.259789,0.186617,0.004027,NORMAL,1137,4153,0 -46901894,842,170,SPARK_POS_OK,0.188091,0.236159,0.250050,0.252227,NORMAL,844,180,SPARK_POS_OK,0.257328,0.259672,0.186503,0.004034,NORMAL,1131,4183,0 -46955894,843,171,SPARK_POS_OK,0.187982,0.236027,0.249890,0.252114,NORMAL,845,170,SPARK_POS_OK,0.257170,0.259569,0.186400,0.004032,NORMAL,1127,4160,0 -47008894,844,161,SPARK_POS_OK,0.187868,0.235941,0.249802,0.251991,NORMAL,846,170,SPARK_POS_OK,0.257060,0.259432,0.186309,0.004019,NORMAL,1122,4280,0 -47062894,845,160,SPARK_POS_OK,0.187767,0.235842,0.249661,0.251852,NORMAL,847,160,SPARK_POS_OK,0.256953,0.259300,0.186182,0.004006,NORMAL,1118,4252,0 -47116894,846,160,SPARK_POS_OK,0.187617,0.235729,0.249538,0.251734,NORMAL,848,161,SPARK_POS_OK,0.256835,0.259192,0.186073,0.003994,NORMAL,1113,4244,0 -47170894,847,160,SPARK_POS_OK,0.187524,0.235621,0.249420,0.251602,NORMAL,849,161,SPARK_POS_OK,0.256718,0.259048,0.185969,0.003990,NORMAL,1110,4216,0 -47224894,848,150,SPARK_POS_OK,0.187391,0.235505,0.249296,0.251517,NORMAL,850,150,SPARK_POS_OK,0.256594,0.258952,0.185884,0.003981,NORMAL,1098,4245,0 -47279894,849,151,SPARK_POS_OK,0.187286,0.235388,0.249176,0.251381,NORMAL,851,150,SPARK_POS_OK,0.256472,0.258817,0.185773,0.003980,NORMAL,1099,4192,0 -47334894,850,141,SPARK_POS_OK,0.187168,0.235281,0.249062,0.251256,NORMAL,852,140,SPARK_POS_OK,0.256345,0.258703,0.185671,0.003981,NORMAL,1085,4248,0 -47389894,851,141,SPARK_POS_OK,0.187046,0.235177,0.248922,0.251114,NORMAL,853,140,SPARK_POS_OK,0.256229,0.258580,0.185577,0.003989,NORMAL,1086,4221,0 -47445894,852,134,SPARK_POS_OK,0.186926,0.235064,0.248811,0.251015,NORMAL,854,130,SPARK_POS_OK,0.256121,0.258464,0.185478,0.003960,NORMAL,1074,4230,0 -47501894,853,130,SPARK_POS_OK,0.186813,0.234978,0.248675,0.250870,NORMAL,855,130,SPARK_POS_OK,0.256003,0.258320,0.185378,0.003954,NORMAL,1075,4157,0 -47557894,854,121,SPARK_POS_OK,0.186700,0.234830,0.248588,0.250720,NORMAL,856,120,SPARK_POS_OK,0.255868,0.258222,0.185274,0.003951,NORMAL,1066,4280,0 -47614894,855,130,SPARK_POS_OK,0.186595,0.234727,0.248448,0.250642,NORMAL,857,121,SPARK_POS_OK,0.255758,0.258101,0.185173,0.003955,NORMAL,1062,4222,0 -47670894,856,130,SPARK_POS_OK,0.186488,0.234631,0.248330,0.250527,NORMAL,858,131,SPARK_POS_OK,0.255622,0.257991,0.185075,0.003922,NORMAL,1060,4166,0 -47727894,857,140,SPARK_POS_OK,0.186380,0.234529,0.248209,0.250412,NORMAL,859,131,SPARK_POS_OK,0.255518,0.257864,0.184941,0.003935,NORMAL,1056,4162,0 -47784894,858,140,SPARK_POS_OK,0.186290,0.234465,0.248080,0.250263,NORMAL,860,141,SPARK_POS_OK,0.255391,0.257729,0.184861,0.003924,NORMAL,1054,4169,0 -47841894,859,150,SPARK_POS_OK,0.186153,0.234302,0.247976,0.250136,NORMAL,861,141,SPARK_POS_OK,0.255267,0.257604,0.184757,0.003910,NORMAL,1049,4231,0 -47898894,860,149,SPARK_POS_OK,0.186059,0.234220,0.247833,0.250043,NORMAL,862,151,SPARK_POS_OK,0.255178,0.257509,0.184662,0.003907,NORMAL,1048,4183,0 -47956894,861,160,SPARK_POS_OK,0.185944,0.234099,0.247707,0.249916,NORMAL,863,161,SPARK_POS_OK,0.255066,0.257356,0.184550,0.003906,NORMAL,1044,4192,0 -48013894,862,160,SPARK_POS_OK,0.185822,0.234005,0.247573,0.249782,NORMAL,864,161,SPARK_POS_OK,0.254922,0.257250,0.184442,0.003871,NORMAL,1045,4252,0 -48071894,863,170,SPARK_POS_OK,0.185719,0.233893,0.247480,0.249677,NORMAL,865,171,SPARK_POS_OK,0.254796,0.257124,0.184361,0.003891,NORMAL,1043,4242,0 -48128894,864,172,SPARK_POS_OK,0.185601,0.233812,0.247360,0.249524,NORMAL,866,171,SPARK_POS_OK,0.254678,0.256999,0.184269,0.003884,NORMAL,1044,4230,0 -48185894,865,170,SPARK_POS_OK,0.185485,0.233693,0.247217,0.249421,NORMAL,867,170,SPARK_POS_OK,0.254599,0.256876,0.184159,0.003896,NORMAL,1044,4177,0 -48243894,866,170,SPARK_POS_OK,0.185353,0.233577,0.247125,0.249268,NORMAL,868,170,SPARK_POS_OK,0.254457,0.256770,0.184052,0.003859,NORMAL,1043,4280,0 -48301894,867,170,SPARK_POS_OK,0.185239,0.233474,0.246968,0.249196,NORMAL,869,170,SPARK_POS_OK,0.254325,0.256634,0.183977,0.003852,NORMAL,1043,4241,0 -48358894,868,170,SPARK_POS_OK,0.185137,0.233374,0.246859,0.249055,NORMAL,870,170,SPARK_POS_OK,0.254217,0.256510,0.183860,0.003856,NORMAL,1040,4192,0 -48416894,869,170,SPARK_POS_OK,0.185001,0.233275,0.246729,0.248941,NORMAL,871,170,SPARK_POS_OK,0.254110,0.256423,0.183764,0.003861,NORMAL,1040,4238,0 -48474894,870,170,SPARK_POS_OK,0.184931,0.233169,0.246617,0.248785,NORMAL,872,170,SPARK_POS_OK,0.253994,0.256265,0.183647,0.003806,NORMAL,1038,4174,0 -48531894,871,170,SPARK_POS_OK,0.184818,0.233034,0.246516,0.248690,NORMAL,873,170,SPARK_POS_OK,0.253859,0.256159,0.183561,0.003828,NORMAL,1039,4160,0 -48589894,872,171,SPARK_POS_OK,0.184712,0.232958,0.246370,0.248585,NORMAL,874,170,SPARK_POS_OK,0.253778,0.256029,0.183455,0.003825,NORMAL,1039,4176,0 -48647894,873,170,SPARK_POS_OK,0.184594,0.232822,0.246262,0.248438,NORMAL,875,170,SPARK_POS_OK,0.253631,0.255929,0.183359,0.003824,NORMAL,1040,4242,0 -48704894,874,171,SPARK_POS_OK,0.184495,0.232725,0.246117,0.248336,NORMAL,876,170,SPARK_POS_OK,0.253508,0.255806,0.183246,0.003831,NORMAL,1040,4185,0 -48762894,875,182,SPARK_POS_OK,0.184386,0.232642,0.246041,0.248201,NORMAL,877,171,SPARK_POS_OK,0.253385,0.255686,0.183159,0.003816,NORMAL,1040,4241,0 -48820894,876,181,SPARK_POS_OK,0.184273,0.232522,0.245903,0.248105,NORMAL,878,180,SPARK_POS_OK,0.253309,0.255567,0.183053,0.003799,NORMAL,1040,4187,0 -48877894,877,181,SPARK_POS_OK,0.184165,0.232435,0.245768,0.247996,NORMAL,879,180,SPARK_POS_OK,0.253191,0.255446,0.182964,0.003816,NORMAL,1039,4180,0 -48935894,878,181,SPARK_POS_OK,0.184060,0.232328,0.245652,0.247856,NORMAL,880,180,SPARK_POS_OK,0.253038,0.255304,0.182863,0.003805,NORMAL,1039,4166,0 -48993894,879,191,SPARK_POS_OK,0.183955,0.232198,0.245534,0.247723,NORMAL,881,190,SPARK_POS_OK,0.252912,0.255213,0.182759,0.003794,NORMAL,1039,4162,0 -49051894,880,191,SPARK_POS_OK,0.183828,0.232086,0.245433,0.247585,NORMAL,882,190,SPARK_POS_OK,0.252812,0.255078,0.182651,0.003785,NORMAL,1040,4209,0 -49108894,881,201,SPARK_POS_OK,0.183755,0.232013,0.245312,0.247477,NORMAL,883,199,SPARK_POS_OK,0.252693,0.254959,0.182567,0.003808,NORMAL,1043,4178,0 -49166894,882,201,SPARK_POS_OK,0.183622,0.231887,0.245204,0.247368,NORMAL,884,200,SPARK_POS_OK,0.252554,0.254838,0.182472,0.003796,NORMAL,1044,4197,0 -49223894,883,210,SPARK_POS_OK,0.183548,0.231800,0.245070,0.247249,NORMAL,885,211,SPARK_POS_OK,0.252450,0.254720,0.182371,0.003793,NORMAL,1048,4180,0 -49280894,884,210,SPARK_POS_OK,0.183415,0.231697,0.244941,0.247137,NORMAL,886,210,SPARK_POS_OK,0.252352,0.254604,0.182251,0.003785,NORMAL,1049,4233,0 -49337894,885,210,SPARK_POS_OK,0.183302,0.231607,0.244841,0.246993,NORMAL,887,210,SPARK_POS_OK,0.252231,0.254492,0.182170,0.003790,NORMAL,1052,4272,0 -49394894,886,201,SPARK_POS_OK,0.183178,0.231465,0.244700,0.246891,NORMAL,888,210,SPARK_POS_OK,0.252116,0.254380,0.182086,0.003777,NORMAL,1051,4252,0 -49451894,887,201,SPARK_POS_OK,0.183051,0.231370,0.244613,0.246722,NORMAL,889,200,SPARK_POS_OK,0.252008,0.254268,0.181959,0.003791,NORMAL,1051,4271,0 -49508894,888,181,SPARK_POS_OK,0.182953,0.231250,0.244480,0.246650,NORMAL,890,200,SPARK_POS_OK,0.251892,0.254142,0.181869,0.003777,NORMAL,1051,4231,0 -49565894,889,181,SPARK_POS_OK,0.182852,0.231152,0.244332,0.246547,NORMAL,891,180,SPARK_POS_OK,0.251753,0.254017,0.181770,0.003770,NORMAL,1051,4228,0 -49622894,890,171,SPARK_POS_OK,0.182726,0.231064,0.244222,0.246421,NORMAL,892,170,SPARK_POS_OK,0.251654,0.253898,0.181662,0.003781,NORMAL,1050,4160,0 -49680894,891,171,SPARK_POS_OK,0.182616,0.230951,0.244120,0.246286,NORMAL,893,170,SPARK_POS_OK,0.251557,0.253804,0.181562,0.003788,NORMAL,1051,4277,0 -49737894,892,161,SPARK_POS_OK,0.182503,0.230843,0.243998,0.246158,NORMAL,894,160,SPARK_POS_OK,0.251422,0.253675,0.181480,0.003783,NORMAL,1048,4215,0 -49794894,893,150,SPARK_POS_OK,0.182407,0.230728,0.243864,0.246056,NORMAL,895,160,SPARK_POS_OK,0.251293,0.253534,0.181367,0.003766,NORMAL,1045,4161,0 -49851894,894,150,SPARK_POS_OK,0.182299,0.230612,0.243748,0.245910,NORMAL,896,150,SPARK_POS_OK,0.251176,0.253406,0.181258,0.003772,NORMAL,1044,4161,0 -49909894,895,150,SPARK_POS_OK,0.182188,0.230522,0.243649,0.245810,NORMAL,897,150,SPARK_POS_OK,0.251061,0.253302,0.181175,0.003751,NORMAL,1040,4237,0 -49967894,896,150,SPARK_POS_OK,0.182081,0.230432,0.243503,0.245688,NORMAL,898,150,SPARK_POS_OK,0.250947,0.253167,0.181066,0.003761,NORMAL,1039,4223,0 -50025894,897,140,SPARK_POS_OK,0.181990,0.230336,0.243385,0.245574,NORMAL,899,150,SPARK_POS_OK,0.250832,0.253050,0.180967,0.003765,NORMAL,1036,4183,0 -50083894,898,140,SPARK_POS_OK,0.181845,0.230209,0.243291,0.245417,NORMAL,900,140,SPARK_POS_OK,0.250705,0.252939,0.180880,0.003750,NORMAL,1035,4215,0 -50141894,899,140,SPARK_POS_OK,0.181769,0.230139,0.243139,0.245352,NORMAL,901,140,SPARK_POS_OK,0.250615,0.252838,0.180776,0.003752,NORMAL,1032,4231,0 -50199894,900,140,SPARK_POS_OK,0.181661,0.229990,0.243036,0.245205,NORMAL,902,140,SPARK_POS_OK,0.250475,0.252681,0.180660,0.003754,NORMAL,1033,4164,0 -50257894,901,140,SPARK_POS_OK,0.181559,0.229920,0.242902,0.245090,NORMAL,903,138,SPARK_POS_OK,0.250394,0.252586,0.180570,0.003743,NORMAL,1029,4165,0 -50316894,902,139,SPARK_POS_OK,0.181454,0.229805,0.242788,0.244974,NORMAL,904,141,SPARK_POS_OK,0.250267,0.252476,0.180474,0.003749,NORMAL,1027,4176,0 -50374894,903,140,SPARK_POS_OK,0.181333,0.229685,0.242683,0.244868,NORMAL,905,141,SPARK_POS_OK,0.250145,0.252370,0.180380,0.003731,NORMAL,1025,4222,0 -50433894,904,130,SPARK_POS_OK,0.181242,0.229599,0.242561,0.244744,NORMAL,906,141,SPARK_POS_OK,0.250034,0.252240,0.180277,0.003742,NORMAL,1022,4171,0 -50492894,905,130,SPARK_POS_OK,0.181165,0.229467,0.242457,0.244618,NORMAL,907,130,SPARK_POS_OK,0.249910,0.252100,0.180182,0.003732,NORMAL,1019,4256,0 -50551894,906,130,SPARK_POS_OK,0.181014,0.229410,0.242325,0.244519,NORMAL,908,130,SPARK_POS_OK,0.249804,0.252000,0.180102,0.003753,NORMAL,1015,4206,0 -50610894,907,131,SPARK_POS_OK,0.180916,0.229288,0.242222,0.244411,NORMAL,909,130,SPARK_POS_OK,0.249669,0.251884,0.179996,0.003746,NORMAL,1015,4205,0 -50669894,908,133,SPARK_POS_OK,0.180824,0.229185,0.242077,0.244268,NORMAL,910,130,SPARK_POS_OK,0.249584,0.251774,0.179896,0.003724,NORMAL,1013,4208,0 -50728894,909,130,SPARK_POS_OK,0.180694,0.229062,0.241970,0.244145,NORMAL,911,130,SPARK_POS_OK,0.249456,0.251659,0.179799,0.003727,NORMAL,1014,4208,0 -50787894,910,130,SPARK_POS_OK,0.180615,0.228989,0.241830,0.244040,NORMAL,912,130,SPARK_POS_OK,0.249347,0.251544,0.179687,0.003733,NORMAL,1011,4163,0 -50847894,911,140,SPARK_POS_OK,0.180486,0.228877,0.241734,0.243900,NORMAL,913,130,SPARK_POS_OK,0.249223,0.251398,0.179603,0.003727,NORMAL,1010,4232,0 -50906894,912,140,SPARK_POS_OK,0.180374,0.228772,0.241596,0.243781,NORMAL,914,141,SPARK_POS_OK,0.249118,0.251292,0.179501,0.003721,NORMAL,1009,4251,0 -50966894,913,150,SPARK_POS_OK,0.180268,0.228676,0.241511,0.243672,NORMAL,915,143,SPARK_POS_OK,0.249002,0.251150,0.179390,0.003727,NORMAL,1007,4171,0 -51025894,914,150,SPARK_POS_OK,0.180143,0.228543,0.241371,0.243591,NORMAL,916,150,SPARK_POS_OK,0.248873,0.251072,0.179284,0.003721,NORMAL,1007,4223,0 -51085894,915,161,SPARK_POS_OK,0.180058,0.228450,0.241258,0.243443,NORMAL,917,158,SPARK_POS_OK,0.248755,0.250931,0.179205,0.003712,NORMAL,1007,4152,0 -51144894,916,161,SPARK_POS_OK,0.179952,0.228314,0.241187,0.243336,NORMAL,918,160,SPARK_POS_OK,0.248628,0.250839,0.179121,0.003693,NORMAL,1008,4214,0 -51204894,917,161,SPARK_POS_OK,0.179825,0.228233,0.241035,0.243222,NORMAL,919,160,SPARK_POS_OK,0.248558,0.250704,0.179017,0.003716,NORMAL,1010,4240,0 -51263894,918,170,SPARK_POS_OK,0.179723,0.228140,0.240918,0.243119,NORMAL,920,160,SPARK_POS_OK,0.248442,0.250626,0.178941,0.003673,NORMAL,1012,4163,0 -51322894,919,170,SPARK_POS_OK,0.179611,0.228032,0.240797,0.242962,NORMAL,921,170,SPARK_POS_OK,0.248314,0.250484,0.178823,0.003694,NORMAL,1014,4216,0 -51381894,920,180,SPARK_POS_OK,0.179483,0.227915,0.240700,0.242868,NORMAL,922,170,SPARK_POS_OK,0.248206,0.250369,0.178745,0.003690,NORMAL,1014,4278,0 -51440894,921,181,SPARK_POS_OK,0.179390,0.227807,0.240554,0.242754,NORMAL,923,181,SPARK_POS_OK,0.248052,0.250253,0.178649,0.003718,NORMAL,1016,4185,0 -51499894,922,180,SPARK_POS_OK,0.179291,0.227693,0.240412,0.242594,NORMAL,924,181,SPARK_POS_OK,0.247962,0.250142,0.178552,0.003698,NORMAL,1017,4159,0 -51558894,923,180,SPARK_POS_OK,0.179173,0.227607,0.240358,0.242525,NORMAL,925,180,SPARK_POS_OK,0.247841,0.250010,0.178452,0.003690,NORMAL,1018,4185,0 -51617894,924,180,SPARK_POS_OK,0.179079,0.227488,0.240244,0.242394,NORMAL,926,180,SPARK_POS_OK,0.247728,0.249873,0.178347,0.003700,NORMAL,1020,4188,0 -51676894,925,191,SPARK_POS_OK,0.178958,0.227406,0.240106,0.242279,NORMAL,927,180,SPARK_POS_OK,0.247626,0.249738,0.178260,0.003663,NORMAL,1022,4188,0 -51734894,926,191,SPARK_POS_OK,0.178894,0.227287,0.239970,0.242131,NORMAL,928,190,SPARK_POS_OK,0.247489,0.249669,0.178149,0.003687,NORMAL,1025,4233,0 -51793894,927,191,SPARK_POS_OK,0.178756,0.227187,0.239858,0.242033,NORMAL,929,190,SPARK_POS_OK,0.247404,0.249532,0.178056,0.003693,NORMAL,1026,4206,0 -51851894,928,191,SPARK_POS_OK,0.178682,0.227094,0.239761,0.241903,NORMAL,930,190,SPARK_POS_OK,0.247283,0.249423,0.177974,0.003693,NORMAL,1029,4206,0 -51909894,929,190,SPARK_POS_OK,0.178563,0.226976,0.239627,0.241792,NORMAL,931,190,SPARK_POS_OK,0.247145,0.249316,0.177866,0.003682,NORMAL,1031,4181,0 -51967894,930,190,SPARK_POS_OK,0.178457,0.226884,0.239519,0.241674,NORMAL,932,190,SPARK_POS_OK,0.247059,0.249201,0.177770,0.003687,NORMAL,1032,4208,0 -52025894,931,190,SPARK_POS_OK,0.178345,0.226781,0.239405,0.241570,NORMAL,933,190,SPARK_POS_OK,0.246941,0.249071,0.177685,0.003692,NORMAL,1033,4264,0 -52083894,932,200,SPARK_POS_OK,0.178225,0.226653,0.239264,0.241413,NORMAL,934,190,SPARK_POS_OK,0.246826,0.248956,0.177557,0.003710,NORMAL,1034,4256,0 -52141894,933,202,SPARK_POS_OK,0.178135,0.226579,0.239156,0.241321,NORMAL,935,200,SPARK_POS_OK,0.246705,0.248853,0.177467,0.003691,NORMAL,1036,4237,0 -52199894,934,200,SPARK_POS_OK,0.178037,0.226479,0.239038,0.241219,NORMAL,936,200,SPARK_POS_OK,0.246564,0.248730,0.177386,0.003682,NORMAL,1037,4152,0 -52257894,935,200,SPARK_POS_OK,0.177921,0.226363,0.238945,0.241104,NORMAL,937,199,SPARK_POS_OK,0.246492,0.248597,0.177285,0.003694,NORMAL,1040,4244,0 -52314894,936,200,SPARK_POS_OK,0.177812,0.226263,0.238812,0.240967,NORMAL,938,200,SPARK_POS_OK,0.246376,0.248495,0.177191,0.003685,NORMAL,1041,4231,0 -52372894,937,200,SPARK_POS_OK,0.177680,0.226153,0.238713,0.240849,NORMAL,939,200,SPARK_POS_OK,0.246275,0.248348,0.177107,0.003703,NORMAL,1044,4230,0 -52429894,938,200,SPARK_POS_OK,0.177594,0.226080,0.238577,0.240744,NORMAL,940,201,SPARK_POS_OK,0.246134,0.248282,0.177004,0.003694,NORMAL,1043,4221,0 -52487894,939,200,SPARK_POS_OK,0.177475,0.225956,0.238462,0.240625,NORMAL,941,201,SPARK_POS_OK,0.246044,0.248135,0.176916,0.003704,NORMAL,1044,4265,0 -52544894,940,200,SPARK_POS_OK,0.177384,0.225872,0.238366,0.240521,NORMAL,942,201,SPARK_POS_OK,0.245889,0.248041,0.176803,0.003698,NORMAL,1043,4229,0 -52601894,941,200,SPARK_POS_OK,0.177253,0.225781,0.238213,0.240364,NORMAL,943,201,SPARK_POS_OK,0.245787,0.247910,0.176700,0.003678,NORMAL,1044,4237,0 -52659894,942,200,SPARK_POS_OK,0.177161,0.225646,0.238121,0.240245,NORMAL,944,201,SPARK_POS_OK,0.245695,0.247777,0.176609,0.003685,NORMAL,1045,4204,0 -52716894,943,202,SPARK_POS_OK,0.177056,0.225565,0.238028,0.240158,NORMAL,945,201,SPARK_POS_OK,0.245553,0.247676,0.176513,0.003714,NORMAL,1047,4230,0 -52773894,944,200,SPARK_POS_OK,0.176951,0.225442,0.237892,0.240009,NORMAL,946,201,SPARK_POS_OK,0.245476,0.247564,0.176414,0.003684,NORMAL,1050,4151,0 -52830894,945,200,SPARK_POS_OK,0.176859,0.225365,0.237779,0.239926,NORMAL,947,201,SPARK_POS_OK,0.245338,0.247457,0.176337,0.003695,NORMAL,1050,4242,0 -52887894,946,198,SPARK_POS_OK,0.176730,0.225252,0.237657,0.239801,NORMAL,948,201,SPARK_POS_OK,0.245228,0.247353,0.176218,0.003702,NORMAL,1053,4206,0 -52944894,947,210,SPARK_POS_OK,0.176619,0.225137,0.237545,0.239674,NORMAL,949,210,SPARK_POS_OK,0.245138,0.247210,0.176138,0.003691,NORMAL,1054,4226,0 -53001894,948,210,SPARK_POS_OK,0.176516,0.225054,0.237430,0.239578,NORMAL,950,211,SPARK_POS_OK,0.244980,0.247125,0.176038,0.003704,NORMAL,1055,4157,0 -53058894,949,220,SPARK_POS_OK,0.176409,0.224927,0.237287,0.239444,NORMAL,951,221,SPARK_POS_OK,0.244922,0.246981,0.175939,0.003682,NORMAL,1055,4234,0 -53115894,950,220,SPARK_POS_OK,0.176303,0.224836,0.237187,0.239326,NORMAL,952,221,SPARK_POS_OK,0.244802,0.246869,0.175855,0.003700,NORMAL,1056,4227,0 -53171894,951,220,SPARK_POS_OK,0.176209,0.224728,0.237058,0.239228,NORMAL,953,220,SPARK_POS_OK,0.244660,0.246759,0.175741,0.003686,NORMAL,1059,4236,0 -53228894,952,232,SPARK_POS_OK,0.176130,0.224632,0.236957,0.239087,NORMAL,954,220,SPARK_POS_OK,0.244568,0.246645,0.175671,0.003706,NORMAL,1062,4149,0 -53284894,953,230,SPARK_POS_OK,0.176008,0.224525,0.236865,0.239014,NORMAL,955,230,SPARK_POS_OK,0.244426,0.246528,0.175578,0.003695,NORMAL,1066,4149,0 -53340894,954,241,SPARK_POS_OK,0.175912,0.224442,0.236724,0.238883,NORMAL,956,230,SPARK_POS_OK,0.244311,0.246415,0.175474,0.003710,NORMAL,1068,4264,0 -53396894,955,240,SPARK_POS_OK,0.175794,0.224323,0.236610,0.238752,NORMAL,957,240,SPARK_POS_OK,0.244229,0.246270,0.175374,0.003706,NORMAL,1072,4208,0 -53674894,956,11,SPARK_NEG_OK,0.175783,0.224292,0.236570,0.238706,SOFT_START,959,11,SPARK_NEG_OK,0.244206,0.246261,0.175381,0.003434,SOFT_START,1084,4273,0 -53729894,957,11,SPARK_NEG_OK,0.175673,0.224182,0.236448,0.238615,SOFT_START,960,11,SPARK_NEG_OK,0.244086,0.246149,0.175256,0.003447,SOFT_START,1085,4206,0 -53784894,958,11,SPARK_NEG_OK,0.175576,0.224109,0.236334,0.238502,SOFT_START,961,11,SPARK_NEG_OK,0.243948,0.246023,0.175169,0.003446,SOFT_START,1091,4162,0 -53839894,959,11,SPARK_NEG_OK,0.175478,0.224012,0.236243,0.238401,SOFT_START,962,12,SPARK_NEG_OK,0.243824,0.245910,0.175105,0.003470,SOFT_START,1092,4168,0 -54003894,960,241,SPARK_POS_OK,0.175418,0.223927,0.236150,0.238284,NORMAL,963,240,SPARK_POS_OK,0.243795,0.245828,0.175021,0.003356,NORMAL,1102,4204,0 -54058894,961,231,SPARK_POS_OK,0.175305,0.223829,0.236015,0.238169,NORMAL,964,240,SPARK_POS_OK,0.243664,0.245724,0.174927,0.003375,NORMAL,1096,4267,0 -54113894,962,230,SPARK_POS_OK,0.175204,0.223744,0.235916,0.238052,NORMAL,965,230,SPARK_POS_OK,0.243499,0.245609,0.174820,0.003390,NORMAL,1096,4207,0 -54168894,963,220,SPARK_POS_OK,0.175103,0.223635,0.235816,0.237938,NORMAL,966,230,SPARK_POS_OK,0.243422,0.245486,0.174741,0.003411,NORMAL,1095,4230,0 -54222894,964,220,SPARK_POS_OK,0.174997,0.223547,0.235701,0.237829,NORMAL,967,221,SPARK_POS_OK,0.243309,0.245369,0.174666,0.003443,NORMAL,1096,4170,0 -54277894,965,220,SPARK_POS_OK,0.174891,0.223427,0.235560,0.237699,NORMAL,968,221,SPARK_POS_OK,0.243210,0.245252,0.174542,0.003449,NORMAL,1095,4213,0 -54332894,966,220,SPARK_POS_OK,0.174809,0.223322,0.235466,0.237581,NORMAL,969,220,SPARK_POS_OK,0.243076,0.245125,0.174434,0.003467,NORMAL,1097,4193,0 -54387894,967,210,SPARK_POS_OK,0.174709,0.223221,0.235333,0.237470,NORMAL,970,220,SPARK_POS_OK,0.242979,0.245035,0.174358,0.003471,NORMAL,1096,4237,0 -54441894,968,211,SPARK_POS_OK,0.174584,0.223115,0.235217,0.237331,NORMAL,971,210,SPARK_POS_OK,0.242879,0.244905,0.174257,0.003499,NORMAL,1096,4177,0 -54496894,969,201,SPARK_POS_OK,0.174465,0.223033,0.235104,0.237241,NORMAL,972,210,SPARK_POS_OK,0.242747,0.244792,0.174165,0.003507,NORMAL,1094,4252,0 -54551894,970,200,SPARK_POS_OK,0.174382,0.222914,0.234981,0.237129,NORMAL,973,200,SPARK_POS_OK,0.242670,0.244678,0.174090,0.003508,NORMAL,1093,4165,0 -54606894,971,188,SPARK_POS_OK,0.174282,0.222827,0.234905,0.237012,NORMAL,974,189,SPARK_POS_OK,0.242506,0.244573,0.173976,0.003533,NORMAL,1087,4166,0 -54661894,972,190,SPARK_POS_OK,0.174193,0.222720,0.234750,0.236908,NORMAL,975,191,SPARK_POS_OK,0.242398,0.244440,0.173886,0.003530,NORMAL,1088,4221,0 -54717894,973,190,SPARK_POS_OK,0.174090,0.222608,0.234655,0.236794,NORMAL,976,191,SPARK_POS_OK,0.242307,0.244360,0.173807,0.003555,NORMAL,1083,4158,0 -54772894,974,190,SPARK_POS_OK,0.173970,0.222521,0.234529,0.236660,NORMAL,977,191,SPARK_POS_OK,0.242168,0.244220,0.173696,0.003552,NORMAL,1084,4279,0 -54828894,975,180,SPARK_POS_OK,0.173885,0.222414,0.234400,0.236566,NORMAL,978,180,SPARK_POS_OK,0.242065,0.244108,0.173611,0.003575,NORMAL,1081,4247,0 -54883894,976,183,SPARK_POS_OK,0.173747,0.222317,0.234323,0.236436,NORMAL,979,180,SPARK_POS_OK,0.241960,0.244016,0.173525,0.003580,NORMAL,1082,4268,0 -54939894,977,170,SPARK_POS_OK,0.173649,0.222196,0.234209,0.236310,NORMAL,980,170,SPARK_POS_OK,0.241845,0.243925,0.173399,0.003576,NORMAL,1077,4170,0 -54995894,978,160,SPARK_POS_OK,0.173565,0.222088,0.234081,0.236226,NORMAL,981,170,SPARK_POS_OK,0.241759,0.243788,0.173325,0.003588,NORMAL,1074,4158,0 -55051894,979,161,SPARK_POS_OK,0.173455,0.221997,0.233963,0.236095,NORMAL,982,160,SPARK_POS_OK,0.241627,0.243664,0.173233,0.003607,NORMAL,1071,4152,0 -55107894,980,151,SPARK_POS_OK,0.173360,0.221920,0.233859,0.235954,NORMAL,983,160,SPARK_POS_OK,0.241511,0.243541,0.173141,0.003611,NORMAL,1066,4255,0 -55163894,981,151,SPARK_POS_OK,0.173278,0.221807,0.233724,0.235876,NORMAL,984,150,SPARK_POS_OK,0.241415,0.243439,0.173040,0.003599,NORMAL,1062,4168,0 -55220894,982,141,SPARK_POS_OK,0.173152,0.221723,0.233647,0.235753,NORMAL,985,150,SPARK_POS_OK,0.241306,0.243303,0.172946,0.003625,NORMAL,1057,4231,0 -55277894,983,141,SPARK_POS_OK,0.173031,0.221609,0.233508,0.235673,NORMAL,986,140,SPARK_POS_OK,0.241213,0.243213,0.172861,0.003614,NORMAL,1054,4277,0 -55334894,984,131,SPARK_POS_OK,0.172935,0.221484,0.233424,0.235513,NORMAL,987,130,SPARK_POS_OK,0.241047,0.243092,0.172771,0.003617,NORMAL,1048,4254,0 -55391894,985,129,SPARK_POS_OK,0.172841,0.221410,0.233307,0.235420,NORMAL,988,130,SPARK_POS_OK,0.240950,0.242991,0.172690,0.003616,NORMAL,1049,4157,0 -55449894,986,121,SPARK_POS_OK,0.172748,0.221290,0.233184,0.235296,NORMAL,989,120,SPARK_POS_OK,0.240864,0.242877,0.172592,0.003625,NORMAL,1043,4222,0 -55506894,987,119,SPARK_POS_OK,0.172647,0.221215,0.233061,0.235195,NORMAL,990,120,SPARK_POS_OK,0.240753,0.242780,0.172480,0.003640,NORMAL,1043,4198,0 -55564894,988,121,SPARK_POS_OK,0.172533,0.221091,0.232973,0.235078,NORMAL,991,120,SPARK_POS_OK,0.240631,0.242653,0.172416,0.003634,NORMAL,1034,4224,0 -55623894,989,121,SPARK_POS_OK,0.172437,0.221025,0.232813,0.234967,NORMAL,992,120,SPARK_POS_OK,0.240516,0.242522,0.172309,0.003656,NORMAL,1030,4156,0 -55681894,990,121,SPARK_POS_OK,0.172341,0.220917,0.232717,0.234841,NORMAL,993,120,SPARK_POS_OK,0.240397,0.242425,0.172216,0.003625,NORMAL,1027,4163,0 -55740894,991,120,SPARK_POS_OK,0.172234,0.220792,0.232614,0.234712,NORMAL,994,120,SPARK_POS_OK,0.240303,0.242295,0.172144,0.003639,NORMAL,1024,4232,0 -55798894,992,120,SPARK_POS_OK,0.172144,0.220699,0.232477,0.234637,NORMAL,995,120,SPARK_POS_OK,0.240181,0.242188,0.172036,0.003632,NORMAL,1022,4191,0 -55857894,993,130,SPARK_POS_OK,0.172038,0.220593,0.232363,0.234499,NORMAL,996,129,SPARK_POS_OK,0.240095,0.242084,0.171948,0.003615,NORMAL,1018,4247,0 -55916894,994,130,SPARK_POS_OK,0.171934,0.220514,0.232289,0.234380,NORMAL,997,130,SPARK_POS_OK,0.240006,0.241980,0.171863,0.003595,NORMAL,1020,4220,0 -55975894,995,130,SPARK_POS_OK,0.171849,0.220422,0.232148,0.234308,NORMAL,998,131,SPARK_POS_OK,0.239871,0.241846,0.171753,0.003628,NORMAL,1017,4156,0 -56034894,996,140,SPARK_POS_OK,0.171710,0.220300,0.232062,0.234135,NORMAL,999,128,SPARK_POS_OK,0.239764,0.241757,0.171660,0.003622,NORMAL,1014,4247,0 -56093894,997,140,SPARK_POS_OK,0.171584,0.220205,0.231923,0.234075,NORMAL,1000,140,SPARK_POS_OK,0.239659,0.241607,0.171576,0.003605,NORMAL,1014,4276,0 -56152900,998,141,SPARK_POS_OK,0.171525,0.220073,0.231818,0.233932,NORMAL,1001,140,SPARK_POS_OK,0.239537,0.241546,0.171494,0.003622,NORMAL,1011,4153,0 -56212894,999,141,SPARK_POS_OK,0.171409,0.219982,0.231696,0.233833,NORMAL,1002,140,SPARK_POS_OK,0.239413,0.241408,0.171388,0.003623,NORMAL,1010,4233,0 -56271894,1000,151,SPARK_POS_OK,0.171313,0.219899,0.231600,0.233698,NORMAL,1003,151,SPARK_POS_OK,0.239316,0.241311,0.171290,0.003623,NORMAL,1008,4221,0 -56331894,1001,150,SPARK_POS_OK,0.171214,0.219794,0.231485,0.233610,NORMAL,1004,150,SPARK_POS_OK,0.239228,0.241202,0.171193,0.003611,NORMAL,1009,4261,0 -56390894,1002,150,SPARK_POS_OK,0.171118,0.219672,0.231362,0.233514,NORMAL,1005,150,SPARK_POS_OK,0.239084,0.241068,0.171105,0.003620,NORMAL,1010,4217,0 -56450894,1003,150,SPARK_POS_OK,0.170998,0.219589,0.231270,0.233375,NORMAL,1006,150,SPARK_POS_OK,0.238969,0.240975,0.171028,0.003622,NORMAL,1011,4222,0 -56509894,1004,150,SPARK_POS_OK,0.170899,0.219505,0.231161,0.233266,NORMAL,1007,151,SPARK_POS_OK,0.238878,0.240844,0.170931,0.003621,NORMAL,1013,4195,0 -56568894,1005,150,SPARK_POS_OK,0.170801,0.219401,0.231034,0.233170,NORMAL,1008,151,SPARK_POS_OK,0.238786,0.240709,0.170842,0.003604,NORMAL,1011,4221,0 -56627894,1006,150,SPARK_POS_OK,0.170709,0.219285,0.230920,0.233046,NORMAL,1009,150,SPARK_POS_OK,0.238663,0.240649,0.170770,0.003610,NORMAL,1012,4267,0 -56687894,1007,161,SPARK_POS_OK,0.170597,0.219198,0.230805,0.232953,NORMAL,1010,150,SPARK_POS_OK,0.238556,0.240501,0.170655,0.003626,NORMAL,1010,4217,0 -56746894,1008,161,SPARK_POS_OK,0.170508,0.219094,0.230714,0.232818,NORMAL,1011,160,SPARK_POS_OK,0.238431,0.240412,0.170583,0.003611,NORMAL,1010,4189,0 -56806894,1009,160,SPARK_POS_OK,0.170414,0.219002,0.230615,0.232709,NORMAL,1012,159,SPARK_POS_OK,0.238371,0.240313,0.170481,0.003620,NORMAL,1010,4264,0 -56865894,1010,160,SPARK_POS_OK,0.170291,0.218900,0.230491,0.232625,NORMAL,1013,160,SPARK_POS_OK,0.238225,0.240183,0.170389,0.003610,NORMAL,1011,4192,0 -56924894,1011,160,SPARK_POS_OK,0.170199,0.218821,0.230367,0.232511,NORMAL,1014,160,SPARK_POS_OK,0.238116,0.240076,0.170326,0.003639,NORMAL,1012,4206,0 -56983894,1012,160,SPARK_POS_OK,0.170107,0.218716,0.230243,0.232403,NORMAL,1015,161,SPARK_POS_OK,0.238000,0.239963,0.170224,0.003619,NORMAL,1014,4239,0 -57042894,1013,161,SPARK_POS_OK,0.169992,0.218605,0.230156,0.232281,NORMAL,1016,161,SPARK_POS_OK,0.237895,0.239862,0.170106,0.003601,NORMAL,1016,4258,0 -57101894,1014,160,SPARK_POS_OK,0.169904,0.218504,0.230020,0.232170,NORMAL,1017,161,SPARK_POS_OK,0.237796,0.239727,0.170028,0.003614,NORMAL,1015,4216,0 -57160894,1015,160,SPARK_POS_OK,0.169811,0.218436,0.229915,0.232031,NORMAL,1018,160,SPARK_POS_OK,0.237724,0.239649,0.169947,0.003592,NORMAL,1015,4216,0 -57220894,1016,171,SPARK_POS_OK,0.169690,0.218344,0.229853,0.231928,NORMAL,1019,170,SPARK_POS_OK,0.237590,0.239527,0.169848,0.003619,NORMAL,1014,4258,0 -57279894,1017,171,SPARK_POS_OK,0.169574,0.218239,0.229714,0.231815,NORMAL,1020,170,SPARK_POS_OK,0.237497,0.239438,0.169757,0.003595,NORMAL,1015,4218,0 -57338894,1018,171,SPARK_POS_OK,0.169488,0.218148,0.229599,0.231684,NORMAL,1021,170,SPARK_POS_OK,0.237364,0.239320,0.169677,0.003618,NORMAL,1016,4220,0 -57397894,1019,170,SPARK_POS_OK,0.169376,0.218035,0.229491,0.231606,NORMAL,1022,170,SPARK_POS_OK,0.237283,0.239204,0.169593,0.003594,NORMAL,1018,4223,0 -57455894,1020,170,SPARK_POS_OK,0.169286,0.217936,0.229365,0.231490,NORMAL,1023,170,SPARK_POS_OK,0.237159,0.239098,0.169486,0.003607,NORMAL,1021,4256,0 -57514894,1021,170,SPARK_POS_OK,0.169184,0.217842,0.229250,0.231389,NORMAL,1024,170,SPARK_POS_OK,0.237051,0.238982,0.169410,0.003601,NORMAL,1021,4205,0 -57573894,1022,170,SPARK_POS_OK,0.169092,0.217730,0.229179,0.231260,NORMAL,1025,170,SPARK_POS_OK,0.236936,0.238863,0.169286,0.003614,NORMAL,1024,4171,0 -57631894,1023,180,SPARK_POS_OK,0.169008,0.217618,0.229036,0.231152,NORMAL,1026,181,SPARK_POS_OK,0.236813,0.238746,0.169223,0.003630,NORMAL,1024,4163,0 -57690894,1024,180,SPARK_POS_OK,0.168919,0.217549,0.228928,0.231032,NORMAL,1027,181,SPARK_POS_OK,0.236756,0.238685,0.169133,0.003594,NORMAL,1025,4207,0 \ No newline at end of file +6,1.158892,1.127349,1.126361,SOFT_START,168,71,SPARK_NEG_OK,1.126999,1.126893,1.127753,1.140731,SOFT_START,1262,2386,0 +184341897,169,69,SPARK_NEG_OK,1.158158,1.158448,1.127634,1.126717,SOFT_START,169,70,SPARK_NEG_OK,1.127301,1.127223,1.128051,1.140767,SOFT_START,1261,2405,0 +184389897,170,70,SPARK_NEG_OK,1.157709,1.157992,1.127911,1.127002,SOFT_START,170,68,SPARK_NEG_OK,1.127591,1.127506,1.128346,1.140777,SOFT_START,1264,2404,0 +184436897,171,70,SPARK_NEG_OK,1.157262,1.157583,1.128229,1.127315,SOFT_START,171,70,SPARK_NEG_OK,1.127875,1.127787,1.128626,1.140696,SOFT_START,1264,2399,0 +184484897,172,70,SPARK_NEG_OK,1.156892,1.157145,1.128529,1.127571,SOFT_START,172,71,SPARK_NEG_OK,1.128153,1.128111,1.128893,1.140749,SOFT_START,1263,2385,0 +184531897,173,70,SPARK_NEG_OK,1.156517,1.156719,1.128732,1.127865,SOFT_START,173,70,SPARK_NEG_OK,1.128455,1.128367,1.129126,1.140565,SOFT_START,1264,2380,0 +184579897,174,70,SPARK_NEG_OK,1.156120,1.156375,1.129014,1.128138,SOFT_START,174,70,SPARK_NEG_OK,1.128681,1.128639,1.129413,1.140733,SOFT_START,1262,2380,0 +184626897,175,71,SPARK_NEG_OK,1.155782,1.155964,1.129223,1.128410,SOFT_START,175,70,SPARK_NEG_OK,1.128941,1.128904,1.129636,1.140796,SOFT_START,1264,2381,0 +184674897,176,70,SPARK_NEG_OK,1.155373,1.155608,1.129481,1.128699,SOFT_START,176,72,SPARK_NEG_OK,1.129176,1.129144,1.129818,1.140771,SOFT_START,1262,2402,0 +184721897,177,71,SPARK_NEG_OK,1.154977,1.155200,1.129765,1.128957,SOFT_START,177,70,SPARK_NEG_OK,1.129455,1.129380,1.130080,1.140834,SOFT_START,1262,2379,0 +184769897,178,70,SPARK_NEG_OK,1.154684,1.154854,1.129964,1.129212,SOFT_START,178,70,SPARK_NEG_OK,1.129641,1.129627,1.130321,1.140804,SOFT_START,1261,2382,0 +184816897,179,71,SPARK_NEG_OK,1.154302,1.154438,1.130198,1.129506,SOFT_START,179,70,SPARK_NEG_OK,1.129878,1.129890,1.130555,1.140743,SOFT_START,1261,2405,0 +184864897,180,70,SPARK_NEG_OK,1.153993,1.154155,1.130427,1.129752,SOFT_START,180,70,SPARK_NEG_OK,1.130168,1.130088,1.130776,1.140695,SOFT_START,1261,2388,0 +184911897,181,71,SPARK_NEG_OK,1.153612,1.153803,1.130581,1.129934,SOFT_START,181,70,SPARK_NEG_OK,1.130362,1.130309,1.131000,1.140781,SOFT_START,1264,2388,0 +184959897,182,70,SPARK_NEG_OK,1.153310,1.153420,1.130870,1.130156,SOFT_START,182,70,SPARK_NEG_OK,1.130589,1.130573,1.131204,1.140671,SOFT_START,1264,2383,0 +185006897,183,70,SPARK_NEG_OK,1.153002,1.153169,1.131068,1.130346,SOFT_START,183,71,SPARK_NEG_OK,1.130778,1.130788,1.131430,1.140798,SOFT_START,1263,2403,0 +185054897,184,71,SPARK_NEG_OK,1.152678,1.152841,1.131254,1.130592,SOFT_START,184,68,SPARK_NEG_OK,1.131003,1.130990,1.131607,1.140681,SOFT_START,1264,2397,0 +185101897,185,70,SPARK_NEG_OK,1.152409,1.152545,1.131476,1.130779,SOFT_START,185,71,SPARK_NEG_OK,1.131200,1.131176,1.131827,1.140775,SOFT_START,1262,2398,0 +185149897,186,70,SPARK_NEG_OK,1.152096,1.152209,1.131658,1.130998,SOFT_START,186,69,SPARK_NEG_OK,1.131361,1.131336,1.132019,1.140593,SOFT_START,1264,2395,0 +185196897,187,70,SPARK_NEG_OK,1.151797,1.151918,1.131840,1.131188,SOFT_START,187,71,SPARK_NEG_OK,1.131609,1.131526,1.132186,1.140742,SOFT_START,1261,2389,0 +185244897,188,70,SPARK_NEG_OK,1.151529,1.151687,1.132007,1.131374,SOFT_START,188,70,SPARK_NEG_OK,1.131717,1.131786,1.132398,1.140748,SOFT_START,1263,2383,0 +185291897,189,70,SPARK_NEG_OK,1.151277,1.151378,1.132189,1.131579,SOFT_START,189,70,SPARK_NEG_OK,1.131982,1.131895,1.132557,1.140770,SOFT_START,1261,2388,0 +185339897,190,71,SPARK_NEG_OK,1.151009,1.151122,1.132369,1.131733,SOFT_START,190,70,SPARK_NEG_OK,1.132153,1.132103,1.132733,1.140745,SOFT_START,1262,2408,0 +185386897,191,70,SPARK_NEG_OK,1.150732,1.150857,1.132556,1.131938,SOFT_START,191,70,SPARK_NEG_OK,1.132309,1.132228,1.132839,1.140754,SOFT_START,1261,2406,0 +185434897,192,71,SPARK_NEG_OK,1.150472,1.150618,1.132696,1.132114,SOFT_START,192,70,SPARK_NEG_OK,1.132509,1.132457,1.133056,1.140756,SOFT_START,1263,2387,0 +185481897,193,70,SPARK_NEG_OK,1.150245,1.150371,1.132858,1.132306,SOFT_START,193,70,SPARK_NEG_OK,1.132713,1.132596,1.133170,1.140887,SOFT_START,1263,2391,0 +185529897,194,70,SPARK_NEG_OK,1.150005,1.150116,1.133036,1.132491,SOFT_START,194,70,SPARK_NEG_OK,1.132876,1.132798,1.133364,1.140847,SOFT_START,1264,2385,0 +185576897,195,70,SPARK_NEG_OK,1.149743,1.149899,1.133211,1.132619,SOFT_START,195,70,SPARK_NEG_OK,1.133001,1.132960,1.133552,1.140627,SOFT_START,1265,2385,0 +185624897,196,72,SPARK_NEG_OK,1.149547,1.149643,1.133342,1.132796,SOFT_START,196,71,SPARK_NEG_OK,1.133152,1.133107,1.133668,1.140708,SOFT_START,1264,2392,0 +185671897,197,70,SPARK_NEG_OK,1.149332,1.149414,1.133471,1.132975,SOFT_START,197,70,SPARK_NEG_OK,1.133358,1.133236,1.133819,1.140464,SOFT_START,1265,2411,0 +185719897,198,70,SPARK_NEG_OK,1.149096,1.149192,1.133621,1.133124,SOFT_START,198,71,SPARK_NEG_OK,1.133456,1.133426,1.134008,1.140715,SOFT_START,1261,2403,0 +185766897,199,70,SPARK_NEG_OK,1.148887,1.149018,1.133759,1.133286,SOFT_START,199,70,SPARK_NEG_OK,1.133550,1.133572,1.134113,1.140726,SOFT_START,1263,2398,0 +185814897,200,70,SPARK_NEG_OK,1.148686,1.148788,1.133918,1.133437,SOFT_START,200,71,SPARK_NEG_OK,1.133758,1.133692,1.134248,1.140733,SOFT_START,1261,2388,0 +185861897,201,70,SPARK_NEG_OK,1.148506,1.148576,1.134027,1.133577,SOFT_START,201,70,SPARK_NEG_OK,1.133902,1.133835,1.134381,1.140782,SOFT_START,1262,2397,0 +185909897,202,70,SPARK_NEG_OK,1.148284,1.148381,1.134209,1.133720,SOFT_START,202,71,SPARK_NEG_OK,1.134034,1.133974,1.134507,1.140788,SOFT_START,1261,2406,0 +185956897,203,71,SPARK_NEG_OK,1.148085,1.148207,1.134299,1.133856,SOFT_START,203,70,SPARK_NEG_OK,1.134121,1.134132,1.134626,1.140798,SOFT_START,1262,2400,0 +186004897,204,70,SPARK_NEG_OK,1.147912,1.148009,1.134418,1.133952,SOFT_START,204,70,SPARK_NEG_OK,1.134306,1.134219,1.134747,1.140752,SOFT_START,1263,2384,0 +186051897,205,71,SPARK_NEG_OK,1.147758,1.147838,1.134569,1.134104,SOFT_START,205,70,SPARK_NEG_OK,1.134400,1.134322,1.134853,1.140792,SOFT_START,1263,2392,0 +186099897,206,70,SPARK_NEG_OK,1.147557,1.147578,1.134689,1.134259,SOFT_START,206,70,SPARK_NEG_OK,1.134546,1.134517,1.134962,1.140752,SOFT_START,1265,2382,0 +186146897,207,71,SPARK_NEG_OK,1.147360,1.147425,1.134798,1.134400,SOFT_START,207,70,SPARK_NEG_OK,1.134619,1.134629,1.135068,1.140788,SOFT_START,1263,2390,0 +186194897,208,70,SPARK_NEG_OK,1.147206,1.147272,1.134887,1.134529,SOFT_START,208,70,SPARK_NEG_OK,1.134769,1.134724,1.135192,1.140577,SOFT_START,1265,2407,0 +186241897,209,71,SPARK_NEG_OK,1.147069,1.147093,1.135019,1.134653,SOFT_START,209,70,SPARK_NEG_OK,1.134878,1.134849,1.135309,1.140776,SOFT_START,1261,2401,0 +186289897,210,70,SPARK_NEG_OK,1.146875,1.146907,1.135117,1.134751,SOFT_START,210,70,SPARK_NEG_OK,1.134980,1.134974,1.135411,1.140729,SOFT_START,1263,2395,0 +186336897,211,70,SPARK_NEG_OK,1.146767,1.146819,1.135241,1.134853,SOFT_START,211,71,SPARK_NEG_OK,1.135086,1.135052,1.135511,1.140984,SOFT_START,1261,2386,0 +186384897,212,70,SPARK_NEG_OK,1.146604,1.146629,1.135346,1.134951,SOFT_START,212,70,SPARK_NEG_OK,1.135221,1.135214,1.135627,1.140739,SOFT_START,1262,2393,0 +186431897,213,70,SPARK_NEG_OK,1.146423,1.146501,1.135468,1.135070,SOFT_START,213,71,SPARK_NEG_OK,1.135320,1.135294,1.135706,1.140595,SOFT_START,1261,2403,0 +186479897,214,70,SPARK_NEG_OK,1.146299,1.146310,1.135559,1.135200,SOFT_START,214,70,SPARK_NEG_OK,1.135406,1.135374,1.135790,1.140648,SOFT_START,1263,2398,0 +186526897,215,69,SPARK_NEG_OK,1.146140,1.146215,1.135640,1.135277,SOFT_START,215,71,SPARK_NEG_OK,1.135512,1.135457,1.135911,1.140693,SOFT_START,1262,2388,0 +186574897,216,70,SPARK_NEG_OK,1.146044,1.146017,1.135722,1.135378,SOFT_START,216,70,SPARK_NEG_OK,1.135628,1.135572,1.135996,1.140716,SOFT_START,1265,2396,0 +186621897,217,70,SPARK_NEG_OK,1.145868,1.145893,1.135834,1.135549,SOFT_START,217,71,SPARK_NEG_OK,1.135663,1.135689,1.136095,1.140702,SOFT_START,1265,2409,0 +186669897,218,71,SPARK_NEG_OK,1.145768,1.145779,1.135929,1.135541,SOFT_START,218,70,SPARK_NEG_OK,1.135783,1.135786,1.136184,1.140776,SOFT_START,1263,2397,0 +186716897,219,70,SPARK_NEG_OK,1.145607,1.145645,1.136020,1.135672,SOFT_START,219,70,SPARK_NEG_OK,1.135885,1.135874,1.136253,1.140493,SOFT_START,1264,2404,0 +186764897,220,71,SPARK_NEG_OK,1.145490,1.145504,1.136116,1.135755,SOFT_START,220,70,SPARK_NEG_OK,1.135993,1.135982,1.136325,1.140779,SOFT_START,1261,2399,0 +186811897,221,70,SPARK_NEG_OK,1.145382,1.145386,1.136182,1.135828,SOFT_START,221,69,SPARK_NEG_OK,1.136033,1.136065,1.136438,1.140781,SOFT_START,1263,2392,0 +186859897,222,71,SPARK_NEG_OK,1.145250,1.145279,1.136251,1.135953,SOFT_START,222,72,SPARK_NEG_OK,1.136116,1.136131,1.136507,1.140998,SOFT_START,1261,2395,0 +186906897,223,70,SPARK_NEG_OK,1.145156,1.145163,1.136373,1.136032,SOFT_START,223,70,SPARK_NEG_OK,1.136228,1.136224,1.136552,1.140813,SOFT_START,1262,2384,0 +186954897,224,71,SPARK_NEG_OK,1.145039,1.145037,1.136417,1.136104,SOFT_START,224,70,SPARK_NEG_OK,1.136295,1.136322,1.136648,1.140755,SOFT_START,1261,2394,0 +187001897,225,70,SPARK_NEG_OK,1.144934,1.144922,1.136483,1.136158,SOFT_START,225,70,SPARK_NEG_OK,1.136373,1.136378,1.136700,1.140758,SOFT_START,1263,2390,0 +187049897,226,70,SPARK_NEG_OK,1.144872,1.144804,1.136569,1.136243,SOFT_START,226,68,SPARK_NEG_OK,1.136437,1.136467,1.136804,1.140947,SOFT_START,1262,2379,0 +187096897,227,70,SPARK_NEG_OK,1.144739,1.144745,1.136674,1.136328,SOFT_START,227,70,SPARK_NEG_OK,1.136522,1.136539,1.136872,1.140844,SOFT_START,1265,2387,0 +187144897,228,70,SPARK_NEG_OK,1.144628,1.144605,1.136727,1.136420,SOFT_START,228,71,SPARK_NEG_OK,1.136560,1.136622,1.136953,1.140733,SOFT_START,1265,2400,0 +187191897,229,70,SPARK_NEG_OK,1.144550,1.144496,1.136795,1.136510,SOFT_START,229,70,SPARK_NEG_OK,1.136668,1.136663,1.137003,1.140752,SOFT_START,1263,2388,0 +187239897,230,70,SPARK_NEG_OK,1.144437,1.144432,1.136830,1.136577,SOFT_START,230,71,SPARK_NEG_OK,1.136729,1.136767,1.137068,1.140632,SOFT_START,1264,2385,0 +187286897,231,70,SPARK_NEG_OK,1.144356,1.144350,1.136940,1.136685,SOFT_START,231,70,SPARK_NEG_OK,1.136803,1.136810,1.137175,1.140776,SOFT_START,1261,2393,0 +187334897,232,70,SPARK_NEG_OK,1.144264,1.144226,1.136986,1.136733,SOFT_START,232,69,SPARK_NEG_OK,1.136854,1.136868,1.137193,1.140608,SOFT_START,1262,2406,0 +187381897,233,71,SPARK_NEG_OK,1.144099,1.144120,1.137043,1.136743,SOFT_START,233,70,SPARK_NEG_OK,1.136906,1.136966,1.137272,1.140772,SOFT_START,1260,2394,0 +187429897,234,70,SPARK_NEG_OK,1.144049,1.143996,1.137094,1.136868,SOFT_START,234,70,SPARK_NEG_OK,1.136965,1.137027,1.137345,1.140746,SOFT_START,1262,2414,0 +187476897,235,71,SPARK_NEG_OK,1.143983,1.143996,1.120251,1.136963,SOFT_START,235,70,SPARK_NEG_OK,1.137028,1.137102,1.137386,1.140764,SOFT_START,1260,2385,0 +187524897,236,70,SPARK_NEG_OK,1.143846,1.143883,1.096806,1.136643,SOFT_START,236,70,SPARK_NEG_OK,1.137081,1.137113,1.137423,1.140757,SOFT_START,1262,2407,0 +187572897,237,71,SPARK_NEG_OK,1.143768,1.143805,1.070337,1.135372,SOFT_START,237,70,SPARK_NEG_OK,1.137131,1.137189,1.137480,1.140747,SOFT_START,1260,2396,0 +187619897,238,70,SPARK_NEG_OK,1.143745,1.143776,1.039791,1.129135,SOFT_START,238,70,SPARK_NEG_OK,1.137272,1.137301,1.137562,1.140734,SOFT_START,1262,2404,0 +187667897,239,70,SPARK_NEG_OK,1.143672,1.143671,1.008092,1.115076,SOFT_START,239,70,SPARK_NEG_OK,1.137304,1.137289,1.137605,1.140685,SOFT_START,1262,2395,0 +187714897,240,70,SPARK_NEG_OK,1.143569,1.143593,0.980268,1.099116,SOFT_START,240,70,SPARK_NEG_OK,1.137341,1.135566,1.137606,1.140727,SOFT_START,1261,2403,0 +187762897,241,70,SPARK_NEG_OK,1.143511,1.143554,0.953581,1.081454,SOFT_START,241,71,SPARK_NEG_OK,1.137413,1.130987,1.137647,1.140644,SOFT_START,1262,2406,0 +187809897,242,70,SPARK_NEG_OK,1.143422,1.143468,0.927338,1.062001,SOFT_START,242,70,SPARK_NEG_OK,1.137457,1.122334,1.137655,1.140615,SOFT_START,1260,2407,0 +187857897,243,70,SPARK_NEG_OK,1.143379,1.143412,0.903567,1.042058,SOFT_START,243,71,SPARK_NEG_OK,1.137521,1.112101,1.137741,1.140404,SOFT_START,1261,2405,0 +187905897,244,72,SPARK_NEG_OK,1.143281,1.143293,0.880494,1.013783,SOFT_START,244,70,SPARK_NEG_OK,1.137545,1.101102,1.137720,1.140631,SOFT_START,1259,2398,0 +187952897,245,70,SPARK_NEG_OK,1.143202,1.143193,0.860400,0.982646,SOFT_START,245,71,SPARK_NEG_OK,1.137577,1.090156,1.137699,1.140628,SOFT_START,1260,2392,0 +188000897,246,70,SPARK_NEG_OK,1.143173,1.143115,0.843756,0.953143,SOFT_START,246,70,SPARK_NEG_OK,1.137629,1.084144,1.137766,1.140650,SOFT_START,1259,2403,0 +188047897,247,70,SPARK_NEG_OK,1.143079,1.143020,0.835966,0.938045,SOFT_START,247,71,SPARK_NEG_OK,1.137651,1.085550,1.137752,1.140644,SOFT_START,1260,2396,0 +188095897,248,70,SPARK_NEG_OK,1.142969,1.142960,0.844243,0.943484,SOFT_START,248,70,SPARK_NEG_OK,1.137699,1.087011,1.137705,1.140645,SOFT_START,1260,2407,0 +188143897,249,70,SPARK_NEG_OK,1.142907,1.142849,0.852197,0.948761,SOFT_START,249,70,SPARK_NEG_OK,1.137729,1.088431,1.137778,1.140617,SOFT_START,1263,2407,0 +188190897,250,73,SPARK_NEG_OK,1.142826,1.142780,0.859877,0.953805,SOFT_START,250,70,SPARK_NEG_OK,1.136677,1.073985,1.137795,1.140592,SOFT_START,1261,2392,0 +188238897,251,70,SPARK_NEG_OK,1.142789,1.142347,0.860271,0.958759,SOFT_START,251,70,SPARK_NEG_OK,1.108766,1.030127,1.137731,1.140604,SOFT_START,1262,2399,0 +188285897,252,71,SPARK_NEG_OK,1.142671,1.134727,0.858706,0.963482,SOFT_START,252,70,SPARK_NEG_OK,1.078349,0.982358,1.137716,1.140530,SOFT_START,1262,2380,0 +188333897,253,70,SPARK_NEG_OK,1.142627,1.108004,0.856692,0.968112,SOFT_START,253,70,SPARK_NEG_OK,1.048051,0.938429,1.137709,1.140584,SOFT_START,1260,2400,0 +188380897,254,71,SPARK_NEG_OK,1.142588,1.053496,0.854957,0.972576,SOFT_START,254,70,SPARK_NEG_OK,1.018492,0.900981,1.137740,1.140455,SOFT_START,1262,2385,0 +188428897,255,71,SPARK_NEG_OK,1.142541,0.994486,0.851908,0.976958,SOFT_START,255,70,SPARK_NEG_OK,0.987433,0.866305,1.137760,1.140595,SOFT_START,1259,2394,0 +188475897,256,71,SPARK_NEG_OK,1.142513,0.967498,0.851087,0.981219,SOFT_START,256,70,SPARK_NEG_OK,0.959564,0.830488,1.137817,1.140580,SOFT_START,1261,2378,0 +188523897,257,70,SPARK_NEG_OK,1.142451,0.970832,0.857853,0.985299,SOFT_START,257,70,SPARK_NEG_OK,0.959603,0.815096,1.137829,1.140557,SOFT_START,1259,2391,0 +188571897,258,70,SPARK_NEG_OK,1.142374,0.975548,0.865321,0.989294,SOFT_START,258,71,SPARK_NEG_OK,0.964402,0.823892,1.137807,1.140571,SOFT_START,1260,2384,0 +188618897,259,70,SPARK_NEG_OK,1.142286,0.980019,0.872535,0.993165,SOFT_START,259,70,SPARK_NEG_OK,0.969036,0.832360,1.137847,1.140644,SOFT_START,1260,2408,0 +188666897,260,70,SPARK_NEG_OK,1.121544,0.917158,0.879552,0.996955,SOFT_START,260,71,SPARK_NEG_OK,0.964869,0.840536,1.137853,1.140586,SOFT_START,1262,2383,0 +188713897,261,70,SPARK_NEG_OK,1.006838,0.871430,0.886389,1.000649,SOFT_START,261,70,SPARK_NEG_OK,0.939159,0.848396,1.137869,1.140559,SOFT_START,1261,2393,0 +188761897,262,70,SPARK_NEG_OK,0.894324,0.794024,0.892994,1.004145,SOFT_START,262,68,SPARK_NEG_OK,0.928019,0.852248,1.137821,1.140596,SOFT_START,1263,2380,0 +188808897,263,70,SPARK_NEG_OK,0.792378,0.713205,0.899369,1.007688,SOFT_START,263,70,SPARK_NEG_OK,0.907278,0.853344,1.137887,1.140532,SOFT_START,1263,2388,0 +188856897,264,70,SPARK_NEG_OK,0.711993,0.641000,0.905662,1.011057,SOFT_START,264,68,SPARK_NEG_OK,0.883424,0.847877,1.137824,1.140597,SOFT_START,1261,2394,0 +188904897,265,70,SPARK_NEG_OK,0.642690,0.579099,0.911708,1.014376,SOFT_START,265,70,SPARK_NEG_OK,0.857443,0.834920,1.137865,1.140476,SOFT_START,1262,2399,0 +188951897,266,70,SPARK_NEG_OK,0.579383,0.525275,0.917584,1.017608,SOFT_START,266,70,SPARK_NEG_OK,0.830497,0.815192,1.137882,1.140587,SOFT_START,1260,2399,0 +188999897,267,72,SPARK_NEG_OK,0.539801,0.480517,0.923313,1.020726,SOFT_START,267,70,SPARK_NEG_OK,0.805323,0.781777,1.137908,1.140289,SOFT_START,1261,2407,0 +189046897,268,70,SPARK_NEG_OK,0.503846,0.442174,0.928857,1.023766,SOFT_START,268,70,SPARK_NEG_OK,0.779868,0.747729,1.137869,1.140617,SOFT_START,1259,2387,0 +189094897,269,71,SPARK_NEG_OK,0.473605,0.411652,0.934254,1.026766,SOFT_START,269,70,SPARK_NEG_OK,0.754997,0.717442,1.137917,1.140615,SOFT_START,1260,2401,0 +189142897,270,70,SPARK_NEG_OK,0.447165,0.388206,0.939519,1.029673,SOFT_START,270,70,SPARK_NEG_OK,0.730941,0.691622,1.137973,1.140569,SOFT_START,1260,2390,0 +189189897,271,71,SPARK_NEG_OK,0.423068,0.368305,0.944640,1.032477,SOFT_START,271,70,SPARK_NEG_OK,0.699619,0.675431,1.137970,1.140774,SOFT_START,1261,2386,0 +189237897,272,70,SPARK_NEG_OK,0.407107,0.355234,0.949636,1.035297,SOFT_START,272,70,SPARK_NEG_OK,0.670904,0.671463,1.138054,1.140611,SOFT_START,1260,2404,0 +189284897,273,71,SPARK_NEG_OK,0.394313,0.343097,0.954507,1.037993,SOFT_START,273,70,SPARK_NEG_OK,0.647012,0.682203,1.138121,1.140590,SOFT_START,1261,2404,0 +189332897,274,70,SPARK_NEG_OK,0.398661,0.337926,0.959170,1.040582,SOFT_START,274,70,SPARK_NEG_OK,0.650623,0.694205,1.138129,1.140496,SOFT_START,1261,2405,0 +189379897,275,70,SPARK_NEG_OK,0.410626,0.346069,0.963689,1.043091,SOFT_START,275,71,SPARK_NEG_OK,0.663587,0.705626,1.138141,1.140475,SOFT_START,1259,2392,0 +189427897,276,70,SPARK_NEG_OK,0.429541,0.367099,0.968152,1.045567,SOFT_START,276,70,SPARK_NEG_OK,0.676201,0.716953,1.138143,1.140402,SOFT_START,1261,2403,0 +189475897,277,70,SPARK_NEG_OK,0.439961,0.354449,0.972412,1.047925,SOFT_START,277,71,SPARK_NEG_OK,0.668110,0.696240,1.138114,1.140418,SOFT_START,1258,2377,0 +189522897,278,70,SPARK_NEG_OK,0.435195,0.341094,0.972803,1.050244,SOFT_START,278,70,SPARK_NEG_OK,0.648581,0.646859,1.138051,1.140268,SOFT_START,1260,2401,0 +189570897,279,70,SPARK_NEG_OK,0.430396,0.323398,0.969666,1.052520,SOFT_START,279,71,SPARK_NEG_OK,0.625216,0.602841,1.138069,1.140502,SOFT_START,1258,2408,0 +189618897,280,72,SPARK_NEG_OK,0.421043,0.310248,0.965737,1.054794,SOFT_START,280,70,SPARK_NEG_OK,0.601267,0.576609,1.138109,1.140491,SOFT_START,1260,2382,0 +189665897,281,70,SPARK_NEG_OK,0.408700,0.294498,0.953568,1.056967,SOFT_START,281,71,SPARK_NEG_OK,0.577353,0.565181,1.138116,1.140410,SOFT_START,1258,2392,0 +189713897,282,70,SPARK_NEG_OK,0.395401,0.283706,0.949467,1.059158,SOFT_START,282,70,SPARK_NEG_OK,0.562693,0.557966,1.138261,1.140411,SOFT_START,1260,2387,0 +189761897,283,70,SPARK_NEG_OK,0.408309,0.289696,0.954339,1.061185,SOFT_START,283,71,SPARK_NEG_OK,0.572813,0.558249,1.138240,1.140365,SOFT_START,1259,2384,0 +189808897,284,70,SPARK_NEG_OK,0.428518,0.312431,0.959098,1.063156,SOFT_START,284,70,SPARK_NEG_OK,0.587675,0.573570,1.138274,1.140383,SOFT_START,1261,2398,0 +189856897,285,70,SPARK_NEG_OK,0.447344,0.334479,0.963700,1.065129,SOFT_START,285,70,SPARK_NEG_OK,0.602085,0.588391,1.138332,1.140342,SOFT_START,1259,2389,0 +189903897,286,71,SPARK_NEG_OK,0.465884,0.355819,0.968169,1.067016,SOFT_START,286,70,SPARK_NEG_OK,0.616104,0.602788,1.138285,1.140370,SOFT_START,1259,2396,0 +189951897,287,70,SPARK_NEG_OK,0.483671,0.376604,0.972544,1.068796,SOFT_START,287,70,SPARK_NEG_OK,0.629680,0.616722,1.138292,1.140230,SOFT_START,1259,2390,0 +189999897,288,71,SPARK_NEG_OK,0.501574,0.396738,0.976741,1.070604,SOFT_START,288,70,SPARK_NEG_OK,0.642881,0.630298,1.128877,1.126575,SOFT_START,1256,2404,0 +190047897,289,70,SPARK_NEG_OK,0.518438,0.415909,0.980912,1.072384,SOFT_START,289,70,SPARK_NEG_OK,0.655706,0.643550,1.075861,1.114373,SOFT_START,1258,2391,0 +190094897,290,71,SPARK_NEG_OK,0.534669,0.434959,0.984921,1.050166,SOFT_START,290,70,SPARK_NEG_OK,0.668052,0.656343,1.037807,1.098530,SOFT_START,1256,2385,0 +190142897,291,70,SPARK_NEG_OK,0.550009,0.453601,0.988777,1.023545,SOFT_START,291,70,SPARK_NEG_OK,0.680209,0.668812,1.001649,1.094294,SOFT_START,1257,2382,0 +190190897,292,71,SPARK_NEG_OK,0.564892,0.471567,0.992526,0.989840,SOFT_START,292,70,SPARK_NEG_OK,0.691987,0.681003,0.971676,1.088048,SOFT_START,1257,2383,0 +190237897,293,70,SPARK_NEG_OK,0.579583,0.488998,0.996294,0.954406,SOFT_START,293,70,SPARK_NEG_OK,0.703526,0.692990,0.944268,1.082551,SOFT_START,1258,2385,0 +190285897,294,71,SPARK_NEG_OK,0.593919,0.505990,0.999874,0.918449,SOFT_START,294,70,SPARK_NEG_OK,0.714712,0.704528,0.913285,1.074791,SOFT_START,1257,2392,0 +190333897,295,70,SPARK_NEG_OK,0.609040,0.522488,1.003314,0.880556,SOFT_START,295,70,SPARK_NEG_OK,0.725584,0.715716,0.882231,1.071677,SOFT_START,1259,2409,0 +190380897,296,70,SPARK_NEG_OK,0.622788,0.538580,1.006724,0.835291,SOFT_START,296,71,SPARK_NEG_OK,0.736191,0.726812,0.850815,1.075814,SOFT_START,1257,2393,0 +190428897,297,70,SPARK_NEG_OK,0.636339,0.554193,1.010138,0.788835,SOFT_START,297,70,SPARK_NEG_OK,0.746495,0.737415,0.818412,1.074355,SOFT_START,1258,2394,0 +190476897,298,70,SPARK_NEG_OK,0.649769,0.569394,1.013394,0.747768,SOFT_START,298,71,SPARK_NEG_OK,0.756562,0.747749,0.789492,1.074809,SOFT_START,1258,2401,0 +190523897,299,70,SPARK_NEG_OK,0.662090,0.584210,1.016519,0.711938,SOFT_START,299,70,SPARK_NEG_OK,0.766363,0.757764,0.762480,1.072893,SOFT_START,1256,2382,0 +190571897,300,70,SPARK_NEG_OK,0.674841,0.598598,1.019611,0.680598,SOFT_START,300,71,SPARK_NEG_OK,0.775893,0.767547,0.732986,1.070690,SOFT_START,1258,2402,0 +190619897,301,70,SPARK_NEG_OK,0.686823,0.612609,1.022608,0.654848,SOFT_START,301,70,SPARK_NEG_OK,0.785160,0.777064,0.707974,1.072136,SOFT_START,1256,2396,0 +190667897,302,70,SPARK_NEG_OK,0.698590,0.626316,1.025476,0.631757,SOFT_START,302,71,SPARK_NEG_OK,0.794262,0.786403,0.686486,1.068516,SOFT_START,1257,2393,0 +190714897,303,70,SPARK_NEG_OK,0.710099,0.639511,1.028345,0.611635,SOFT_START,303,70,SPARK_NEG_OK,0.803024,0.795431,0.670051,1.069409,SOFT_START,1257,2394,0 +190762897,304,70,SPARK_NEG_OK,0.721261,0.652429,1.031089,0.591972,SOFT_START,304,71,SPARK_NEG_OK,0.811570,0.804190,0.656787,1.070213,SOFT_START,1259,2394,0 +190810897,305,70,SPARK_NEG_OK,0.731868,0.665058,1.033797,0.572663,SOFT_START,305,70,SPARK_NEG_OK,0.819991,0.812809,0.644847,1.069613,SOFT_START,1257,2386,0 +190857897,306,70,SPARK_NEG_OK,0.742422,0.677364,1.036482,0.555892,SOFT_START,306,71,SPARK_NEG_OK,0.828177,0.821185,0.635573,1.075899,SOFT_START,1260,2392,0 +190905897,307,71,SPARK_NEG_OK,0.752888,0.689259,1.039063,0.542604,SOFT_START,307,72,SPARK_NEG_OK,0.836152,0.829360,0.633015,1.099085,SOFT_START,1258,2396,0 +190953897,308,70,SPARK_NEG_OK,0.762556,0.700566,1.041470,0.558567,SOFT_START,308,70,SPARK_NEG_OK,0.843797,0.837128,0.641674,1.137978,SOFT_START,1259,2384,0 +191000897,309,81,SPARK_NEG_OK,0.772207,0.711884,1.043870,0.573983,SOFT_START,309,80,SPARK_NEG_OK,0.851268,0.844831,0.655099,1.139367,SOFT_START,1257,2385,0 +191048897,310,80,SPARK_NEG_OK,0.781264,0.722896,1.041488,0.580509,SOFT_START,310,80,SPARK_NEG_OK,0.858574,0.852370,0.647225,1.139547,SOFT_START,1257,2378,0 +191096897,311,81,SPARK_NEG_OK,0.790655,0.733562,0.990750,0.563973,SOFT_START,311,70,SPARK_NEG_OK,0.865586,0.850257,0.620382,1.128847,SOFT_START,1257,2399,0 +191143897,312,70,SPARK_NEG_OK,0.799589,0.743960,0.942124,0.543885,SOFT_START,312,70,SPARK_NEG_OK,0.872611,0.837538,0.585876,1.119562,SOFT_START,1256,2394,0 +191191897,313,70,SPARK_NEG_OK,0.808343,0.754052,0.894533,0.521106,SOFT_START,313,70,SPARK_NEG_OK,0.879362,0.815218,0.568060,1.110529,SOFT_START,1257,2392,0 +191239897,314,70,SPARK_NEG_OK,0.816672,0.763920,0.848632,0.499606,SOFT_START,314,70,SPARK_NEG_OK,0.885992,0.795727,0.562121,1.108317,SOFT_START,1257,2391,0 +191287897,315,71,SPARK_NEG_OK,0.825053,0.773296,0.803438,0.478330,SOFT_START,315,71,SPARK_NEG_OK,0.892382,0.777851,0.544412,1.104877,SOFT_START,1258,2394,0 +191334897,316,70,SPARK_NEG_OK,0.833554,0.782652,0.762842,0.455941,SOFT_START,316,70,SPARK_NEG_OK,0.898632,0.761204,0.542561,1.104763,SOFT_START,1258,2404,0 +191382897,317,71,SPARK_NEG_OK,0.841953,0.791766,0.728159,0.435472,SOFT_START,317,70,SPARK_NEG_OK,0.904728,0.743864,0.542182,1.105455,SOFT_START,1259,2410,0 +191429899,318,70,SPARK_NEG_OK,0.849262,0.800627,0.697125,0.414697,SOFT_START,318,70,SPARK_NEG_OK,0.910636,0.726589,0.536417,1.105343,SOFT_START,1258,2381,0 +191477897,319,70,SPARK_NEG_OK,0.856977,0.809301,0.671430,0.398297,SOFT_START,319,71,SPARK_NEG_OK,0.916439,0.710132,0.536246,1.106201,SOFT_START,1259,2401,0 +191525897,320,68,SPARK_NEG_OK,0.864226,0.817706,0.649173,0.383372,SOFT_START,320,70,SPARK_NEG_OK,0.922053,0.693378,0.535363,1.106548,SOFT_START,1257,2399,0 +191573897,321,70,SPARK_NEG_OK,0.871081,0.825708,0.628685,0.370935,SOFT_START,321,71,SPARK_NEG_OK,0.927595,0.682542,0.534340,1.107010,SOFT_START,1258,2379,0 +191620897,322,70,SPARK_NEG_OK,0.877873,0.833690,0.610544,0.361459,SOFT_START,322,71,SPARK_NEG_OK,0.932933,0.684170,0.533530,1.108972,SOFT_START,1258,2387,0 +191668897,323,70,SPARK_NEG_OK,0.884545,0.841509,0.594100,0.352716,SOFT_START,323,71,SPARK_NEG_OK,0.938066,0.696053,0.529802,1.110553,SOFT_START,1257,2387,0 +191716897,324,70,SPARK_NEG_OK,0.890825,0.849009,0.586866,0.347410,SOFT_START,324,70,SPARK_NEG_OK,0.943151,0.707584,0.525452,1.110213,SOFT_START,1258,2382,0 +191763897,325,70,SPARK_NEG_OK,0.897419,0.856338,0.588261,0.345953,SOFT_START,325,71,SPARK_NEG_OK,0.948024,0.716192,0.524531,1.098732,SOFT_START,1257,2403,0 +191811897,326,70,SPARK_NEG_OK,0.903310,0.863463,0.590606,0.345289,SOFT_START,326,72,SPARK_NEG_OK,0.952848,0.722920,0.528352,1.092634,SOFT_START,1259,2381,0 +191859897,327,70,SPARK_NEG_OK,0.909297,0.870429,0.586400,0.347955,SOFT_START,327,71,SPARK_NEG_OK,0.957583,0.733342,0.533801,1.089435,SOFT_START,1258,2390,0 +191906897,328,70,SPARK_NEG_OK,0.915223,0.877239,0.581699,0.348344,SOFT_START,328,70,SPARK_NEG_OK,0.962174,0.743883,0.536938,1.086290,SOFT_START,1259,2398,0 +191954897,329,70,SPARK_NEG_OK,0.921147,0.883843,0.574491,0.350075,SOFT_START,329,72,SPARK_NEG_OK,0.966603,0.754163,0.540155,1.083750,SOFT_START,1258,2400,0 +192002897,330,71,SPARK_NEG_OK,0.926576,0.890207,0.559911,0.354365,SOFT_START,330,70,SPARK_NEG_OK,0.970954,0.764207,0.544133,1.081342,SOFT_START,1259,2389,0 +192049897,331,70,SPARK_NEG_OK,0.932415,0.896492,0.538313,0.357807,SOFT_START,331,70,SPARK_NEG_OK,0.975103,0.773910,0.547756,1.076151,SOFT_START,1257,2405,0 +192097897,332,71,SPARK_NEG_OK,0.937918,0.902609,0.515330,0.364317,SOFT_START,332,70,SPARK_NEG_OK,0.979365,0.783376,0.554141,1.073771,SOFT_START,1259,2406,0 +192145897,333,70,SPARK_NEG_OK,0.943314,0.908580,0.498574,0.368890,SOFT_START,333,70,SPARK_NEG_OK,0.983343,0.792553,0.559369,1.070050,SOFT_START,1257,2404,0 +192192897,334,71,SPARK_NEG_OK,0.948131,0.914369,0.508566,0.368342,SOFT_START,334,70,SPARK_NEG_OK,0.987229,0.801677,0.562606,1.066432,SOFT_START,1258,2384,0 +192240897,335,70,SPARK_NEG_OK,0.953181,0.920057,0.520288,0.358691,SOFT_START,335,70,SPARK_NEG_OK,0.991074,0.810406,0.566635,1.066079,SOFT_START,1258,2401,0 +192288897,336,71,SPARK_NEG_OK,0.957879,0.925593,0.533798,0.340669,SOFT_START,336,70,SPARK_NEG_OK,0.994776,0.818911,0.570375,1.063755,SOFT_START,1258,2389,0 +192335897,337,70,SPARK_NEG_OK,0.962690,0.930984,0.547384,0.336614,SOFT_START,337,70,SPARK_NEG_OK,0.998428,0.827124,0.575967,1.062478,SOFT_START,1259,2403,0 +192383897,338,71,SPARK_NEG_OK,0.967425,0.936232,0.562908,0.348035,SOFT_START,338,72,SPARK_NEG_OK,1.001999,0.835164,0.580236,1.061581,SOFT_START,1258,2408,0 +192431897,339,70,SPARK_NEG_OK,0.971728,0.941358,0.578160,0.363296,SOFT_START,339,71,SPARK_NEG_OK,1.005390,0.842988,0.583218,1.060054,SOFT_START,1259,2389,0 +192478897,340,70,SPARK_NEG_OK,0.975807,0.946314,0.592960,0.378453,SOFT_START,340,71,SPARK_NEG_OK,1.008667,0.850523,0.589486,1.062918,SOFT_START,1258,2378,0 +192526897,341,70,SPARK_NEG_OK,0.979980,0.951179,0.607321,0.394570,SOFT_START,341,70,SPARK_NEG_OK,1.011981,0.857860,0.593049,1.060285,SOFT_START,1259,2400,0 +192574897,342,70,SPARK_NEG_OK,0.983860,0.955915,0.621075,0.406840,SOFT_START,342,71,SPARK_NEG_OK,1.015145,0.865094,0.596339,1.058868,SOFT_START,1257,2383,0 +192621897,343,70,SPARK_NEG_OK,0.987717,0.960475,0.634681,0.414582,SOFT_START,343,70,SPARK_NEG_OK,1.018227,0.872234,0.598782,1.059689,SOFT_START,1258,2384,0 +192669897,344,70,SPARK_NEG_OK,0.991434,0.964962,0.647946,0.416000,SOFT_START,344,71,SPARK_NEG_OK,1.021250,0.879025,0.596784,1.057622,SOFT_START,1257,2381,0 +192717897,345,70,SPARK_NEG_OK,0.995185,0.969330,0.659711,0.417155,SOFT_START,345,70,SPARK_NEG_OK,1.024167,0.885672,0.595410,1.059654,SOFT_START,1258,2395,0 +192764900,346,69,SPARK_NEG_OK,0.998966,0.973598,0.658923,0.414504,SOFT_START,346,71,SPARK_NEG_OK,1.027060,0.892162,0.595211,1.062050,SOFT_START,1258,2402,0 +192812897,347,70,SPARK_NEG_OK,1.002623,0.977703,0.639119,0.411404,SOFT_START,347,70,SPARK_NEG_OK,1.029796,0.898438,0.595747,1.063986,SOFT_START,1257,2403,0 +192860897,348,70,SPARK_NEG_OK,1.006231,0.981752,0.613019,0.406735,SOFT_START,348,71,SPARK_NEG_OK,1.032530,0.904560,0.597475,1.067961,SOFT_START,1258,2408,0 +192907897,349,70,SPARK_NEG_OK,1.009482,0.985759,0.571611,0.402676,SOFT_START,349,70,SPARK_NEG_OK,1.035263,0.910570,0.599487,1.074504,SOFT_START,1258,2381,0 +192955897,350,70,SPARK_NEG_OK,1.012916,0.989633,0.576071,0.408452,SOFT_START,350,71,SPARK_NEG_OK,1.037896,0.916445,0.598219,1.118112,SOFT_START,1260,2394,0 +193003897,351,70,SPARK_NEG_OK,1.015959,0.993312,0.591127,0.427592,SOFT_START,351,70,SPARK_NEG_OK,1.040300,0.922058,0.612183,1.139008,SOFT_START,1257,2382,0 +193050897,352,70,SPARK_NEG_OK,1.019269,0.997037,0.605723,0.446277,SOFT_START,352,69,SPARK_NEG_OK,1.042816,0.927587,0.626343,1.139585,SOFT_START,1259,2404,0 +193098897,353,71,SPARK_NEG_OK,1.022347,1.000603,0.610359,0.463060,SOFT_START,353,70,SPARK_NEG_OK,1.045161,0.928534,0.639951,1.139781,SOFT_START,1256,2395,0 +193146897,354,70,SPARK_NEG_OK,1.025310,1.003061,0.591187,0.464465,SOFT_START,354,70,SPARK_NEG_OK,0.991983,0.872154,0.653077,1.139730,SOFT_START,1257,2400,0 +193194897,355,71,SPARK_NEG_OK,1.028230,0.943663,0.568030,0.468370,SOFT_START,355,70,SPARK_NEG_OK,0.917254,0.826780,0.665873,1.139807,SOFT_START,1255,2392,0 +193241897,356,70,SPARK_NEG_OK,1.031079,0.888375,0.531271,0.473001,SOFT_START,356,70,SPARK_NEG_OK,0.851082,0.790309,0.678361,1.139907,SOFT_START,1257,2399,0 +193289897,357,71,SPARK_NEG_OK,1.033816,0.842385,0.486686,0.476835,SOFT_START,357,70,SPARK_NEG_OK,0.791644,0.759033,0.690480,1.140005,SOFT_START,1255,2391,0 +193337897,358,72,SPARK_NEG_OK,1.036532,0.806363,0.446562,0.481356,SOFT_START,358,70,SPARK_NEG_OK,0.733872,0.741358,0.702291,1.140096,SOFT_START,1257,2397,0 +193385897,359,71,SPARK_NEG_OK,1.039274,0.815593,0.417851,0.463129,SOFT_START,359,70,SPARK_NEG_OK,0.722080,0.724129,0.713770,1.140032,SOFT_START,1257,2397,0 +193432897,360,70,SPARK_NEG_OK,1.041692,0.803937,0.422419,0.480573,SOFT_START,360,71,SPARK_NEG_OK,0.701705,0.705495,0.724836,1.140009,SOFT_START,1256,2391,0 +193480897,361,71,SPARK_NEG_OK,1.040588,0.764834,0.441830,0.497825,SOFT_START,361,68,SPARK_NEG_OK,0.701593,0.717017,0.735635,1.139827,SOFT_START,1257,2402,0 +193528897,362,69,SPARK_NEG_OK,0.943286,0.737903,0.460395,0.514492,SOFT_START,362,70,SPARK_NEG_OK,0.677440,0.728059,0.746189,1.139968,SOFT_START,1256,2398,0 +193576897,363,71,SPARK_NEG_OK,0.859758,0.610667,0.478484,0.530713,SOFT_START,363,70,SPARK_NEG_OK,0.675141,0.738817,0.756457,1.139762,SOFT_START,1257,2397,0 +193623897,364,70,SPARK_NEG_OK,0.759543,0.509748,0.495975,0.546516,SOFT_START,364,70,SPARK_NEG_OK,0.679256,0.749259,0.766445,1.139993,SOFT_START,1255,2404,0 +193671897,365,71,SPARK_NEG_OK,0.681712,0.430894,0.512948,0.561854,SOFT_START,365,70,SPARK_NEG_OK,0.679159,0.759298,0.776160,1.139968,SOFT_START,1257,2378,0 +193719897,366,70,SPARK_NEG_OK,0.616158,0.390927,0.529459,0.576734,SOFT_START,366,70,SPARK_NEG_OK,0.689732,0.769073,0.785657,1.139937,SOFT_START,1255,2416,0 +193767897,367,70,SPARK_NEG_OK,0.569114,0.396481,0.545491,0.591248,SOFT_START,367,71,SPARK_NEG_OK,0.701455,0.778584,0.794792,1.139957,SOFT_START,1256,2402,0 +193814897,368,70,SPARK_NEG_OK,0.539470,0.416414,0.561114,0.605364,SOFT_START,368,70,SPARK_NEG_OK,0.712866,0.787783,0.803744,1.139974,SOFT_START,1255,2407,0 +193862897,369,70,SPARK_NEG_OK,0.513363,0.435762,0.576231,0.619119,SOFT_START,369,71,SPARK_NEG_OK,0.723912,0.796808,0.812445,1.139996,SOFT_START,1256,2394,0 +193910897,370,70,SPARK_NEG_OK,0.499718,0.454457,0.591065,0.632217,SOFT_START,370,70,SPARK_NEG_OK,0.734664,0.805569,0.820919,1.139912,SOFT_START,1255,2405,0 +193958897,371,70,SPARK_NEG_OK,0.458908,0.472177,0.605624,0.645221,SOFT_START,371,71,SPARK_NEG_OK,0.745131,0.814028,0.829176,1.139857,SOFT_START,1257,2398,0 +194005897,372,70,SPARK_NEG_OK,0.414161,0.489759,0.619569,0.657945,SOFT_START,372,70,SPARK_NEG_OK,0.755258,0.822368,0.837253,1.139791,SOFT_START,1257,2409,0 +194053897,373,67,SPARK_NEG_OK,0.389282,0.506837,0.633170,0.670336,SOFT_START,373,71,SPARK_NEG_OK,0.765198,0.830492,0.845079,1.139596,SOFT_START,1256,2403,0 +194101897,374,70,SPARK_NEG_OK,0.410736,0.523409,0.646330,0.682328,SOFT_START,374,70,SPARK_NEG_OK,0.774783,0.838342,0.852683,1.139454,SOFT_START,1257,2408,0 +194149897,375,70,SPARK_NEG_OK,0.430081,0.539525,0.659195,0.693962,SOFT_START,375,71,SPARK_NEG_OK,0.784162,0.845987,0.860129,1.139765,SOFT_START,1254,2388,0 +194196897,376,70,SPARK_NEG_OK,0.448516,0.555187,0.671666,0.705381,SOFT_START,376,72,SPARK_NEG_OK,0.793269,0.853422,0.867366,1.139636,SOFT_START,1255,2383,0 +194244897,377,70,SPARK_NEG_OK,0.448713,0.526941,0.683811,0.716451,SOFT_START,377,71,SPARK_NEG_OK,0.794423,0.860678,0.874374,1.139442,SOFT_START,1254,2379,0 +194292897,378,70,SPARK_NEG_OK,0.411646,0.484101,0.695498,0.727075,SOFT_START,378,70,SPARK_NEG_OK,0.743201,0.867624,0.881081,1.139567,SOFT_START,1255,2407,0 +194340897,379,70,SPARK_NEG_OK,0.380747,0.444918,0.706997,0.737512,SOFT_START,379,71,SPARK_NEG_OK,0.691245,0.874469,0.887774,1.139737,SOFT_START,1253,2403,0 +194388897,380,71,SPARK_NEG_OK,0.349463,0.379552,0.718315,0.747783,SOFT_START,380,70,SPARK_NEG_OK,0.650082,0.881072,0.894248,1.139803,SOFT_START,1255,2385,0 +194435897,381,70,SPARK_NEG_OK,0.318486,0.317509,0.729185,0.757706,SOFT_START,381,70,SPARK_NEG_OK,0.614719,0.887564,0.900618,1.139713,SOFT_START,1254,2388,0 +194483897,382,71,SPARK_NEG_OK,0.293643,0.275019,0.739657,0.767452,SOFT_START,382,68,SPARK_NEG_OK,0.584599,0.893788,0.906743,1.139688,SOFT_START,1256,2409,0 +194531897,383,70,SPARK_NEG_OK,0.265042,0.240133,0.749997,0.776879,SOFT_START,383,70,SPARK_NEG_OK,0.557883,0.899736,0.912724,1.139598,SOFT_START,1256,2389,0 +194579897,384,71,SPARK_NEG_OK,0.245752,0.215394,0.759985,0.786088,SOFT_START,384,70,SPARK_NEG_OK,0.535682,0.905674,0.918611,1.139730,SOFT_START,1256,2397,0 +194626897,385,70,SPARK_NEG_OK,0.227054,0.195889,0.769749,0.795034,SOFT_START,385,70,SPARK_NEG_OK,0.516067,0.911434,0.924313,1.139698,SOFT_START,1257,2377,0 +194674897,386,71,SPARK_NEG_OK,0.210389,0.180584,0.779215,0.803801,SOFT_START,386,70,SPARK_NEG_OK,0.498500,0.917002,0.929878,1.139756,SOFT_START,1255,2398,0 +194722897,387,70,SPARK_NEG_OK,0.210795,0.171658,0.788510,0.812395,SOFT_START,387,70,SPARK_NEG_OK,0.487638,0.922533,0.935345,1.139140,SOFT_START,1256,2393,0 +194770897,388,71,SPARK_NEG_OK,0.209922,0.181316,0.797400,0.820652,SOFT_START,388,70,SPARK_NEG_OK,0.500386,0.927792,0.940543,1.139169,SOFT_START,1254,2393,0 +194818897,389,70,SPARK_NEG_OK,0.235092,0.207329,0.806135,0.828743,SOFT_START,389,70,SPARK_NEG_OK,0.517223,0.932924,0.945657,1.139223,SOFT_START,1256,2398,0 +194865897,390,71,SPARK_NEG_OK,0.259536,0.232139,0.814663,0.836604,SOFT_START,390,70,SPARK_NEG_OK,0.533477,0.937994,0.950645,1.138840,SOFT_START,1255,2397,0 +194913897,391,68,SPARK_NEG_OK,0.282499,0.256298,0.778925,0.843626,SOFT_START,391,70,SPARK_NEG_OK,0.549246,0.928463,0.955310,1.139047,SOFT_START,1256,2385,0 +194961897,392,71,SPARK_NEG_OK,0.305440,0.279715,0.735527,0.743704,SOFT_START,392,70,SPARK_NEG_OK,0.564599,0.886894,0.926742,1.132833,SOFT_START,1255,2395,0 +195009897,393,70,SPARK_NEG_OK,0.327359,0.302435,0.715210,0.661168,SOFT_START,393,69,SPARK_NEG_OK,0.579449,0.871477,0.831993,1.104728,SOFT_START,1257,2395,0 +195056897,394,70,SPARK_NEG_OK,0.348352,0.324542,0.688795,0.601309,SOFT_START,394,71,SPARK_NEG_OK,0.593755,0.865296,0.751398,1.101071,SOFT_START,1256,2387,0 +195104897,395,70,SPARK_NEG_OK,0.369970,0.346324,0.655285,0.559288,SOFT_START,395,70,SPARK_NEG_OK,0.607886,0.862819,0.691777,1.095065,SOFT_START,1258,2401,0 +195152897,396,70,SPARK_NEG_OK,0.389749,0.367254,0.612344,0.522242,SOFT_START,396,71,SPARK_NEG_OK,0.621668,0.859252,0.651463,1.080623,SOFT_START,1258,2388,0 +195199897,397,70,SPARK_NEG_OK,0.408787,0.387484,0.576465,0.490590,SOFT_START,397,70,SPARK_NEG_OK,0.634968,0.860549,0.620983,1.070460,SOFT_START,1256,2382,0 +195247897,398,70,SPARK_NEG_OK,0.427249,0.407187,0.541549,0.468117,SOFT_START,398,73,SPARK_NEG_OK,0.647950,0.851352,0.595222,1.061361,SOFT_START,1257,2380,0 +195295897,399,70,SPARK_NEG_OK,0.445415,0.426301,0.502493,0.450258,SOFT_START,399,70,SPARK_NEG_OK,0.660548,0.835061,0.575306,1.053540,SOFT_START,1255,2391,0 +195343897,400,70,SPARK_NEG_OK,0.462913,0.444932,0.460909,0.437908,SOFT_START,400,71,SPARK_NEG_OK,0.672863,0.816779,0.561062,1.049340,SOFT_START,1257,2380,0 +195390897,401,70,SPARK_NEG_OK,0.480255,0.463036,0.423845,0.428616,SOFT_START,401,70,SPARK_NEG_OK,0.684830,0.799495,0.549327,1.041117,SOFT_START,1255,2388,0 +195438897,402,68,SPARK_NEG_OK,0.497649,0.480735,0.395966,0.424913,SOFT_START,402,71,SPARK_NEG_OK,0.696477,0.788710,0.541575,1.035540,SOFT_START,1257,2395,0 +195486897,403,71,SPARK_NEG_OK,0.514337,0.497772,0.375275,0.421812,SOFT_START,403,70,SPARK_NEG_OK,0.707844,0.778397,0.536014,1.029574,SOFT_START,1256,2393,0 +195534897,404,70,SPARK_NEG_OK,0.531467,0.514451,0.357180,0.420932,SOFT_START,404,71,SPARK_NEG_OK,0.718875,0.769340,0.531498,1.023295,SOFT_START,1258,2410,0 +195581897,405,70,SPARK_NEG_OK,0.547957,0.530673,0.345371,0.423130,SOFT_START,405,68,SPARK_NEG_OK,0.729517,0.760951,0.529671,1.019849,SOFT_START,1256,2404,0 +195629897,406,70,SPARK_NEG_OK,0.562891,0.546544,0.337175,0.424153,SOFT_START,406,71,SPARK_NEG_OK,0.739949,0.752168,0.527497,1.014099,SOFT_START,1258,2384,0 +195677897,407,70,SPARK_NEG_OK,0.578579,0.561872,0.331700,0.425733,SOFT_START,407,70,SPARK_NEG_OK,0.750111,0.745311,0.526377,1.010666,SOFT_START,1258,2405,0 +195724897,408,70,SPARK_NEG_OK,0.593423,0.576733,0.328864,0.428541,SOFT_START,408,70,SPARK_NEG_OK,0.759987,0.740290,0.526363,1.008461,SOFT_START,1256,2400,0 +195772897,409,71,SPARK_NEG_OK,0.608006,0.591232,0.326842,0.430810,SOFT_START,409,70,SPARK_NEG_OK,0.769629,0.735317,0.525264,1.004090,SOFT_START,1257,2400,0 +195820897,410,70,SPARK_NEG_OK,0.622252,0.605335,0.327471,0.431709,SOFT_START,410,70,SPARK_NEG_OK,0.779007,0.730571,0.526602,1.003827,SOFT_START,1256,2407,0 +195868897,411,71,SPARK_NEG_OK,0.635929,0.618970,0.327794,0.430644,SOFT_START,411,70,SPARK_NEG_OK,0.788230,0.726069,0.526972,1.000861,SOFT_START,1257,2398,0 +195915897,412,70,SPARK_NEG_OK,0.649498,0.632347,0.328463,0.429895,SOFT_START,412,70,SPARK_NEG_OK,0.797049,0.721974,0.527271,0.998697,SOFT_START,1256,2405,0 +195963897,413,71,SPARK_NEG_OK,0.661583,0.645319,0.330486,0.431867,SOFT_START,413,70,SPARK_NEG_OK,0.805707,0.718610,0.528444,0.998928,SOFT_START,1257,2379,0 +196011897,414,70,SPARK_NEG_OK,0.674603,0.657951,0.332386,0.433189,SOFT_START,414,70,SPARK_NEG_OK,0.814090,0.715082,0.528497,0.995190,SOFT_START,1256,2409,0 +196058897,415,71,SPARK_NEG_OK,0.686598,0.670295,0.335856,0.435284,SOFT_START,415,70,SPARK_NEG_OK,0.822357,0.712208,0.529659,0.995315,SOFT_START,1258,2390,0 +196106897,416,70,SPARK_NEG_OK,0.697910,0.682217,0.339230,0.436991,SOFT_START,416,70,SPARK_NEG_OK,0.830402,0.709519,0.530642,0.994439,SOFT_START,1257,2387,0 +196154897,417,71,SPARK_NEG_OK,0.709521,0.693904,0.343508,0.437927,SOFT_START,417,70,SPARK_NEG_OK,0.838199,0.706606,0.531059,0.991716,SOFT_START,1258,2396,0 +196202897,418,70,SPARK_NEG_OK,0.720154,0.705253,0.348450,0.440330,SOFT_START,418,70,SPARK_NEG_OK,0.845796,0.704414,0.532942,0.993031,SOFT_START,1256,2381,0 +196249897,419,71,SPARK_NEG_OK,0.731535,0.716321,0.351739,0.441970,SOFT_START,419,70,SPARK_NEG_OK,0.853224,0.702141,0.534596,0.989261,SOFT_START,1257,2406,0 +196297897,420,72,SPARK_NEG_OK,0.742173,0.727088,0.354928,0.444053,SOFT_START,420,70,SPARK_NEG_OK,0.860410,0.700425,0.536754,0.989192,SOFT_START,1257,2398,0 +196345897,421,71,SPARK_NEG_OK,0.751955,0.737589,0.357251,0.446453,SOFT_START,421,71,SPARK_NEG_OK,0.867425,0.699195,0.538892,0.990196,SOFT_START,1255,2384,0 +196393897,422,70,SPARK_NEG_OK,0.761726,0.747836,0.357944,0.447455,SOFT_START,422,70,SPARK_NEG_OK,0.874292,0.697886,0.539917,0.987804,SOFT_START,1256,2389,0 +196440897,423,71,SPARK_NEG_OK,0.771020,0.757717,0.359999,0.449529,SOFT_START,423,71,SPARK_NEG_OK,0.881009,0.697231,0.542271,0.989618,SOFT_START,1255,2375,0 +196488897,424,70,SPARK_NEG_OK,0.780604,0.767414,0.361903,0.450774,SOFT_START,424,70,SPARK_NEG_OK,0.887476,0.696497,0.543872,0.987710,SOFT_START,1256,2400,0 +196536897,425,70,SPARK_NEG_OK,0.789748,0.776840,0.363056,0.452746,SOFT_START,425,71,SPARK_NEG_OK,0.893809,0.696051,0.545713,0.987282,SOFT_START,1256,2393,0 +196584897,426,70,SPARK_NEG_OK,0.798498,0.785926,0.364348,0.455781,SOFT_START,426,70,SPARK_NEG_OK,0.899980,0.695949,0.548121,0.989075,SOFT_START,1257,2388,0 +196631897,427,70,SPARK_NEG_OK,0.807515,0.794898,0.364979,0.457662,SOFT_START,427,71,SPARK_NEG_OK,0.906025,0.696300,0.549321,0.987119,SOFT_START,1256,2398,0 +196679897,428,70,SPARK_NEG_OK,0.816078,0.803599,0.366492,0.460225,SOFT_START,428,70,SPARK_NEG_OK,0.911877,0.697439,0.551886,0.989428,SOFT_START,1257,2393,0 +196727897,429,70,SPARK_NEG_OK,0.824717,0.812083,0.368203,0.463473,SOFT_START,429,71,SPARK_NEG_OK,0.917574,0.699270,0.555409,0.992225,SOFT_START,1256,2403,0 +196774896,430,70,SPARK_NEG_OK,0.832838,0.820377,0.368649,0.468495,SOFT_START,430,70,SPARK_NEG_OK,0.923170,0.702636,0.559613,0.996209,SOFT_START,1257,2397,0 +196822897,431,68,SPARK_NEG_OK,0.840947,0.828457,0.370733,0.475840,SOFT_START,431,71,SPARK_NEG_OK,0.928569,0.712827,0.566477,1.011644,SOFT_START,1255,2401,0 +196870897,432,70,SPARK_NEG_OK,0.848425,0.836203,0.379615,0.481983,SOFT_START,432,70,SPARK_NEG_OK,0.933813,0.723934,0.575102,1.036452,SOFT_START,1256,2388,0 +196918897,433,70,SPARK_NEG_OK,0.855833,0.843859,0.399843,0.498175,SOFT_START,433,71,SPARK_NEG_OK,0.938929,0.734705,0.586255,1.128287,SOFT_START,1256,2392,0 +196966897,434,70,SPARK_NEG_OK,0.862790,0.851090,0.419458,0.514846,SOFT_START,434,71,SPARK_NEG_OK,0.943903,0.745150,0.600918,1.138106,SOFT_START,1255,2379,0 +197013897,435,70,SPARK_NEG_OK,0.870082,0.858337,0.438476,0.531024,SOFT_START,435,71,SPARK_NEG_OK,0.948843,0.755377,0.615200,1.138211,SOFT_START,1256,2400,0 +197061897,436,71,SPARK_NEG_OK,0.876852,0.865397,0.456955,0.546771,SOFT_START,436,70,SPARK_NEG_OK,0.953586,0.765290,0.629039,1.138381,SOFT_START,1258,2387,0 +197109897,437,70,SPARK_NEG_OK,0.883547,0.872315,0.474864,0.562065,SOFT_START,437,69,SPARK_NEG_OK,0.958107,0.774966,0.642518,1.138355,SOFT_START,1259,2391,0 +197156897,438,71,SPARK_NEG_OK,0.889871,0.878985,0.492376,0.576943,SOFT_START,438,70,SPARK_NEG_OK,0.962681,0.784309,0.655579,1.138502,SOFT_START,1258,2385,0 +197204897,439,70,SPARK_NEG_OK,0.895979,0.885549,0.509285,0.591406,SOFT_START,439,70,SPARK_NEG_OK,0.967083,0.793441,0.668283,1.138515,SOFT_START,1260,2379,0 +197252897,440,71,SPARK_NEG_OK,0.901951,0.891907,0.525828,0.605496,SOFT_START,440,70,SPARK_NEG_OK,0.971358,0.802382,0.680685,1.138523,SOFT_START,1258,2389,0 +197299897,441,70,SPARK_NEG_OK,0.908242,0.898100,0.541903,0.619220,SOFT_START,441,70,SPARK_NEG_OK,0.975564,0.811036,0.692725,1.138558,SOFT_START,1259,2404,0 +197347897,442,71,SPARK_NEG_OK,0.913891,0.904184,0.557505,0.632538,SOFT_START,442,70,SPARK_NEG_OK,0.979622,0.819438,0.704461,1.138542,SOFT_START,1257,2381,0 +197395897,443,70,SPARK_NEG_OK,0.919912,0.910037,0.572453,0.645549,SOFT_START,443,70,SPARK_NEG_OK,0.983565,0.827636,0.715870,1.138603,SOFT_START,1257,2408,0 +197442897,444,71,SPARK_NEG_OK,0.925835,0.915761,0.587258,0.658139,SOFT_START,444,70,SPARK_NEG_OK,0.987424,0.835754,0.726960,1.138510,SOFT_START,1257,2409,0 +197490897,445,70,SPARK_NEG_OK,0.931081,0.921384,0.601662,0.670450,SOFT_START,445,70,SPARK_NEG_OK,0.991197,0.843522,0.737714,1.138547,SOFT_START,1255,2384,0 +197538897,446,68,SPARK_NEG_OK,0.936205,0.926822,0.615648,0.682462,SOFT_START,446,70,SPARK_NEG_OK,0.994881,0.851083,0.748222,1.138457,SOFT_START,1257,2394,0 +197586897,447,70,SPARK_NEG_OK,0.941679,0.932009,0.629239,0.694079,SOFT_START,447,70,SPARK_NEG_OK,0.998521,0.858462,0.758372,1.138576,SOFT_START,1256,2409,0 +197633897,448,71,SPARK_NEG_OK,0.946813,0.937189,0.642501,0.705446,SOFT_START,448,70,SPARK_NEG_OK,1.001968,0.865648,0.768343,1.138353,SOFT_START,1258,2392,0 +197681897,449,70,SPARK_NEG_OK,0.951939,0.942289,0.655406,0.716542,SOFT_START,449,70,SPARK_NEG_OK,1.005418,0.872613,0.777958,1.138580,SOFT_START,1257,2410,0 +197729897,450,70,SPARK_NEG_OK,0.956769,0.947143,0.667902,0.727336,SOFT_START,450,71,SPARK_NEG_OK,1.008716,0.879436,0.787351,1.138567,SOFT_START,1259,2400,0 +197776897,451,70,SPARK_NEG_OK,0.961485,0.951946,0.680074,0.737779,SOFT_START,451,72,SPARK_NEG_OK,1.011902,0.885992,0.796536,1.138632,SOFT_START,1257,2395,0 +197824897,452,70,SPARK_NEG_OK,0.965814,0.956672,0.691974,0.748004,SOFT_START,452,71,SPARK_NEG_OK,1.015096,0.892447,0.805374,1.138683,SOFT_START,1258,2378,0 +197872897,453,70,SPARK_NEG_OK,0.969991,0.961169,0.703571,0.757943,SOFT_START,453,70,SPARK_NEG_OK,1.018174,0.898783,0.814090,1.138651,SOFT_START,1256,2382,0 +197920897,454,70,SPARK_NEG_OK,0.974422,0.965638,0.714827,0.767618,SOFT_START,454,71,SPARK_NEG_OK,1.021154,0.904873,0.822687,1.138588,SOFT_START,1256,2404,0 +197967897,455,70,SPARK_NEG_OK,0.978434,0.969967,0.725800,0.777068,SOFT_START,455,70,SPARK_NEG_OK,1.024073,0.910866,0.830897,1.138610,SOFT_START,1255,2388,0 +198015897,456,71,SPARK_NEG_OK,0.982476,0.974114,0.736486,0.786243,SOFT_START,456,71,SPARK_NEG_OK,1.026915,0.916633,0.838767,1.138631,SOFT_START,1256,2387,0 +198063897,457,70,SPARK_NEG_OK,0.986497,0.978253,0.746858,0.795330,SOFT_START,457,70,SPARK_NEG_OK,1.029671,0.922282,0.846566,1.138586,SOFT_START,1256,2401,0 +198111897,458,70,SPARK_NEG_OK,0.990388,0.982236,0.757039,0.804005,SOFT_START,458,71,SPARK_NEG_OK,1.032391,0.927808,0.854118,1.138704,SOFT_START,1256,2395,0 +198158897,459,70,SPARK_NEG_OK,0.994188,0.986171,0.766867,0.812482,SOFT_START,459,70,SPARK_NEG_OK,1.035048,0.933197,0.861503,1.138524,SOFT_START,1257,2393,0 +198206897,460,70,SPARK_NEG_OK,0.997861,0.989932,0.776478,0.820764,SOFT_START,460,71,SPARK_NEG_OK,1.037596,0.938282,0.868723,1.138554,SOFT_START,1257,2393,0 +198254897,461,70,SPARK_NEG_OK,1.001484,0.993586,0.785827,0.828819,SOFT_START,461,72,SPARK_NEG_OK,1.040122,0.943370,0.875672,1.138457,SOFT_START,1258,2399,0 +198301897,462,70,SPARK_NEG_OK,1.004820,0.997251,0.794877,0.836490,SOFT_START,462,71,SPARK_NEG_OK,1.042532,0.948245,0.882468,1.138612,SOFT_START,1257,2381,0 +198349897,463,71,SPARK_NEG_OK,1.008261,1.000777,0.803945,0.844142,SOFT_START,463,70,SPARK_NEG_OK,1.044953,0.953137,0.889168,1.138601,SOFT_START,1258,2395,0 +198397897,464,70,SPARK_NEG_OK,1.011630,1.004187,0.812561,0.851560,SOFT_START,464,70,SPARK_NEG_OK,1.047267,0.957842,0.895617,1.138586,SOFT_START,1256,2399,0 +198445897,465,70,SPARK_NEG_OK,1.014755,1.007419,0.820917,0.858834,SOFT_START,465,70,SPARK_NEG_OK,1.049514,0.962403,0.901838,1.138570,SOFT_START,1256,2386,0 +198492897,466,70,SPARK_NEG_OK,1.017913,1.010736,0.829131,0.865717,SOFT_START,466,70,SPARK_NEG_OK,1.051728,0.966837,0.907962,1.138636,SOFT_START,1255,2390,0 +198540897,467,71,SPARK_NEG_OK,1.020833,1.013905,0.837208,0.872640,SOFT_START,467,70,SPARK_NEG_OK,1.053870,0.971184,0.913940,1.138763,SOFT_START,1256,2378,0 +198588897,468,68,SPARK_NEG_OK,1.023827,1.016993,0.844943,0.879311,SOFT_START,468,70,SPARK_NEG_OK,1.055968,0.975426,0.919718,1.138736,SOFT_START,1256,2401,0 +198636897,469,71,SPARK_NEG_OK,1.026771,1.019992,0.852468,0.885863,SOFT_START,469,70,SPARK_NEG_OK,1.057974,0.979553,0.925345,1.138719,SOFT_START,1256,2396,0 +198683897,470,70,SPARK_NEG_OK,1.029617,1.022981,0.859785,0.892249,SOFT_START,470,70,SPARK_NEG_OK,1.059937,0.983578,0.930845,1.138595,SOFT_START,1257,2392,0 +198731897,471,71,SPARK_NEG_OK,1.032406,1.025834,0.866962,0.898444,SOFT_START,471,71,SPARK_NEG_OK,1.061925,0.987495,0.936190,1.138741,SOFT_START,1257,2393,0 +198779897,472,70,SPARK_NEG_OK,1.035117,1.028681,0.873880,0.904470,SOFT_START,472,70,SPARK_NEG_OK,1.063795,0.991260,0.941454,1.138520,SOFT_START,1258,2401,0 +198826897,473,71,SPARK_NEG_OK,1.037666,1.031381,0.880714,0.910354,SOFT_START,473,70,SPARK_NEG_OK,1.065649,0.995018,0.946509,1.138749,SOFT_START,1256,2381,0 +198874897,474,70,SPARK_NEG_OK,1.040186,1.034034,0.887304,0.916088,SOFT_START,474,70,SPARK_NEG_OK,1.067454,0.998622,0.951377,1.138802,SOFT_START,1258,2396,0 +198922897,475,71,SPARK_NEG_OK,1.042747,1.036620,0.893693,0.921721,SOFT_START,475,70,SPARK_NEG_OK,1.069213,1.002159,0.956199,1.138736,SOFT_START,1256,2399,0 +198970897,476,70,SPARK_NEG_OK,1.045139,1.039166,0.900021,0.927205,SOFT_START,476,70,SPARK_NEG_OK,1.070951,1.005632,0.960873,1.138778,SOFT_START,1256,2387,0 +199017897,477,71,SPARK_NEG_OK,1.047575,1.041696,0.906057,0.932533,SOFT_START,477,68,SPARK_NEG_OK,1.072591,1.008968,0.965450,1.138802,SOFT_START,1255,2404,0 +199065897,478,70,SPARK_NEG_OK,1.049927,1.044093,0.911966,0.937669,SOFT_START,478,70,SPARK_NEG_OK,1.074216,1.012245,0.969922,1.138794,SOFT_START,1256,2405,0 +199113897,479,70,SPARK_NEG_OK,1.052106,1.046392,0.917790,0.942686,SOFT_START,479,71,SPARK_NEG_OK,1.075827,1.015409,0.974250,1.138965,SOFT_START,1255,2382,0 +199161897,480,70,SPARK_NEG_OK,1.054415,1.048661,0.923340,0.947649,SOFT_START,480,70,SPARK_NEG_OK,1.077308,1.018512,0.978477,1.138893,SOFT_START,1257,2410,0 +199208897,481,70,SPARK_NEG_OK,1.056542,1.050912,0.928867,0.952318,SOFT_START,481,71,SPARK_NEG_OK,1.078835,1.021546,0.982547,1.138763,SOFT_START,1257,2393,0 +199256897,482,70,SPARK_NEG_OK,1.058652,1.053063,0.934328,0.957001,SOFT_START,482,70,SPARK_NEG_OK,1.080312,1.024505,0.986578,1.138800,SOFT_START,1258,2401,0 +199304897,483,70,SPARK_NEG_OK,1.060624,1.055197,0.939485,0.961571,SOFT_START,483,71,SPARK_NEG_OK,1.081753,1.027358,0.990457,1.138735,SOFT_START,1259,2381,0 +199351897,484,70,SPARK_NEG_OK,1.062620,1.057284,0.944619,0.965979,SOFT_START,484,70,SPARK_NEG_OK,1.083105,1.030152,0.994279,1.138887,SOFT_START,1258,2402,0 +199399897,485,70,SPARK_NEG_OK,1.064650,1.059279,0.949562,0.970278,SOFT_START,485,71,SPARK_NEG_OK,1.084507,1.032863,0.997985,1.138619,SOFT_START,1259,2409,0 +199447897,486,70,SPARK_NEG_OK,1.066502,1.061223,0.954372,0.974510,SOFT_START,486,70,SPARK_NEG_OK,1.085833,1.035513,1.001592,1.138877,SOFT_START,1256,2404,0 +199494897,487,70,SPARK_NEG_OK,1.068381,1.063136,0.959049,0.978616,SOFT_START,487,71,SPARK_NEG_OK,1.087151,1.038102,1.005077,1.138884,SOFT_START,1257,2397,0 +199542897,488,70,SPARK_NEG_OK,1.070222,1.064984,0.963625,0.982598,SOFT_START,488,70,SPARK_NEG_OK,1.088380,1.040629,1.008493,1.138843,SOFT_START,1256,2401,0 +199590897,489,70,SPARK_NEG_OK,1.071929,1.066837,0.968059,0.986540,SOFT_START,489,71,SPARK_NEG_OK,1.089634,1.043045,1.011835,1.138870,SOFT_START,1256,2388,0 +199638897,490,70,SPARK_NEG_OK,1.073522,1.068571,0.972405,0.990316,SOFT_START,490,70,SPARK_NEG_OK,1.090859,1.045417,1.015100,1.138884,SOFT_START,1255,2379,0 +199685897,491,70,SPARK_NEG_OK,1.075127,1.070310,0.976613,0.994056,SOFT_START,491,69,SPARK_NEG_OK,1.092004,1.047779,1.018229,1.138948,SOFT_START,1257,2386,0 +199733897,492,70,SPARK_NEG_OK,1.076706,1.071989,0.980760,0.997673,SOFT_START,492,70,SPARK_NEG_OK,1.093139,1.050047,1.021312,1.138892,SOFT_START,1256,2397,0 +199781897,493,70,SPARK_NEG_OK,1.078337,1.073658,0.984789,1.001220,SOFT_START,493,70,SPARK_NEG_OK,1.094322,1.052256,1.024339,1.138899,SOFT_START,1258,2411,0 +199829897,494,71,SPARK_NEG_OK,1.079882,1.075291,0.988694,1.004609,SOFT_START,494,70,SPARK_NEG_OK,1.095378,1.054404,1.027223,1.138871,SOFT_START,1258,2399,0 +199876897,495,70,SPARK_NEG_OK,1.081359,1.076829,0.992493,1.007938,SOFT_START,495,70,SPARK_NEG_OK,1.096408,1.056505,1.030062,1.138875,SOFT_START,1256,2392,0 +199924897,496,71,SPARK_NEG_OK,1.082857,1.078333,0.996218,1.011209,SOFT_START,496,70,SPARK_NEG_OK,1.097444,1.058553,1.032846,1.138789,SOFT_START,1257,2407,0 +199972897,497,70,SPARK_NEG_OK,1.084253,1.079819,0.999807,1.014365,SOFT_START,497,70,SPARK_NEG_OK,1.098434,1.060597,1.035516,1.138882,SOFT_START,1254,2407,0 +200020897,498,71,SPARK_NEG_OK,1.085703,1.081288,1.003265,1.017464,SOFT_START,498,71,SPARK_NEG_OK,1.099413,1.062520,1.038158,1.138892,SOFT_START,1256,2407,0 +200068897,499,70,SPARK_NEG_OK,1.087030,1.082680,1.006688,1.020468,SOFT_START,499,70,SPARK_NEG_OK,1.100335,1.064399,1.040694,1.138884,SOFT_START,1254,2404,0 +200115897,500,71,SPARK_NEG_OK,1.088346,1.084013,1.010080,1.023328,SOFT_START,500,70,SPARK_NEG_OK,1.101301,1.066244,1.043216,1.138926,SOFT_START,1254,2406,0 +200163897,501,70,SPARK_NEG_OK,1.089662,1.085361,1.013315,1.026210,SOFT_START,501,70,SPARK_NEG_OK,1.102178,1.068069,1.045630,1.138916,SOFT_START,1253,2403,0 +200211897,502,71,SPARK_NEG_OK,1.090860,1.086680,1.016490,1.029004,SOFT_START,502,70,SPARK_NEG_OK,1.103074,1.069821,1.047994,1.138919,SOFT_START,1255,2384,0 +200259897,503,70,SPARK_NEG_OK,1.092005,1.087983,1.019544,1.031712,SOFT_START,503,70,SPARK_NEG_OK,1.103947,1.071544,1.050300,1.138840,SOFT_START,1254,2387,0 +200307897,504,71,SPARK_NEG_OK,1.093218,1.089222,1.022528,1.034365,SOFT_START,504,68,SPARK_NEG_OK,1.104780,1.073183,1.052552,1.138921,SOFT_START,1256,2408,0 +200354897,505,70,SPARK_NEG_OK,1.094334,1.090431,1.025525,1.036956,SOFT_START,505,70,SPARK_NEG_OK,1.105585,1.074843,1.054726,1.138817,SOFT_START,1256,2379,0 +200402897,506,71,SPARK_NEG_OK,1.095472,1.091625,1.028365,1.039474,SOFT_START,506,70,SPARK_NEG_OK,1.106395,1.076389,1.056848,1.138862,SOFT_START,1255,2401,0 +200450897,507,70,SPARK_NEG_OK,1.096483,1.092761,1.031119,1.041970,SOFT_START,507,70,SPARK_NEG_OK,1.107152,1.077968,1.058919,1.138759,SOFT_START,1256,2397,0 +200498897,508,70,SPARK_NEG_OK,1.097583,1.093895,1.033847,1.044332,SOFT_START,508,70,SPARK_NEG_OK,1.107902,1.079450,1.060951,1.138824,SOFT_START,1253,2404,0 +200546897,509,70,SPARK_NEG_OK,1.098644,1.094969,1.036481,1.046677,SOFT_START,509,80,SPARK_NEG_OK,1.108671,1.080885,1.062919,1.138581,SOFT_START,1254,2409,0 +200593897,510,80,SPARK_NEG_OK,1.099628,1.096037,1.039064,1.048962,SOFT_START,510,81,SPARK_NEG_OK,1.109383,1.082374,1.064863,1.138833,SOFT_START,1252,2391,0 +200641897,511,80,SPARK_NEG_OK,1.100538,1.097053,1.041567,1.051172,SOFT_START,511,80,SPARK_NEG_OK,1.110090,1.083744,1.066708,1.138848,SOFT_START,1254,2383,0 +200689897,512,70,SPARK_NEG_OK,1.101493,1.098135,1.044021,1.053308,SOFT_START,512,71,SPARK_NEG_OK,1.110775,1.085066,1.068553,1.138845,SOFT_START,1253,2383,0 +200737897,513,70,SPARK_NEG_OK,1.102372,1.099089,1.046416,1.055438,SOFT_START,513,70,SPARK_NEG_OK,1.111474,1.086422,1.070324,1.138824,SOFT_START,1254,2391,0 +200785897,514,80,SPARK_NEG_OK,1.103214,1.100050,1.048707,1.057488,SOFT_START,514,81,SPARK_NEG_OK,1.112085,1.087756,1.072024,1.138831,SOFT_START,1253,2378,0 +200833897,515,80,SPARK_NEG_OK,1.104085,1.100979,1.050979,1.059471,SOFT_START,515,80,SPARK_NEG_OK,1.112735,1.089014,1.073769,1.138822,SOFT_START,1255,2393,0 +200880897,516,70,SPARK_NEG_OK,1.104988,1.101883,1.053209,1.061469,SOFT_START,516,71,SPARK_NEG_OK,1.113369,1.090220,1.075408,1.138798,SOFT_START,1254,2399,0 +200928897,517,70,SPARK_NEG_OK,1.105760,1.102788,1.055311,1.063389,SOFT_START,517,70,SPARK_NEG_OK,1.113955,1.091417,1.077015,1.138873,SOFT_START,1255,2380,0 +200976897,518,70,SPARK_NEG_OK,1.106611,1.103647,1.057402,1.065237,SOFT_START,518,71,SPARK_NEG_OK,1.114541,1.092560,1.078509,1.138787,SOFT_START,1255,2380,0 +201024897,519,70,SPARK_NEG_OK,1.107370,1.104487,1.059424,1.067051,SOFT_START,519,70,SPARK_NEG_OK,1.115107,1.093731,1.080037,1.138859,SOFT_START,1252,2401,0 +201072897,520,70,SPARK_NEG_OK,1.108094,1.105347,1.061434,1.068819,SOFT_START,520,71,SPARK_NEG_OK,1.115653,1.094762,1.081535,1.138700,SOFT_START,1254,2385,0 +201120897,521,70,SPARK_NEG_OK,1.108882,1.106136,1.063333,1.070519,SOFT_START,521,70,SPARK_NEG_OK,1.116232,1.095880,1.082894,1.138834,SOFT_START,1251,2400,0 +201168897,522,70,SPARK_NEG_OK,1.109611,1.106956,1.065228,1.072187,SOFT_START,522,71,SPARK_NEG_OK,1.116765,1.096914,1.084377,1.138551,SOFT_START,1253,2396,0 +201216897,523,68,SPARK_NEG_OK,1.110393,1.107690,1.067030,1.073779,SOFT_START,523,70,SPARK_NEG_OK,1.117291,1.097961,1.085720,1.138756,SOFT_START,1251,2411,0 +201263897,524,70,SPARK_NEG_OK,1.111047,1.108446,1.068894,1.075400,SOFT_START,524,71,SPARK_NEG_OK,1.117790,1.098970,1.087092,1.138818,SOFT_START,1253,2391,0 +201311897,525,70,SPARK_NEG_OK,1.111712,1.109200,1.070623,1.076945,SOFT_START,525,70,SPARK_NEG_OK,1.118264,1.099969,1.088384,1.138778,SOFT_START,1252,2383,0 +201359897,526,70,SPARK_NEG_OK,1.112347,1.109911,1.072314,1.078471,SOFT_START,526,71,SPARK_NEG_OK,1.118742,1.100888,1.089628,1.138970,SOFT_START,1254,2388,0 +201407897,527,80,SPARK_NEG_OK,1.112952,1.110553,1.074007,1.079976,SOFT_START,527,80,SPARK_NEG_OK,1.119235,1.101813,1.090854,1.138966,SOFT_START,1253,2391,0 +201455897,528,80,SPARK_NEG_OK,1.113597,1.111251,1.075578,1.081411,SOFT_START,528,81,SPARK_NEG_OK,1.119695,1.102700,1.092065,1.138864,SOFT_START,1255,2383,0 +201503897,529,81,SPARK_NEG_OK,1.114163,1.111869,1.077154,1.082782,SOFT_START,529,80,SPARK_NEG_OK,1.120153,1.103555,1.093213,1.138805,SOFT_START,1253,2388,0 +201550897,530,80,SPARK_NEG_OK,1.114832,1.112595,1.078709,1.084148,SOFT_START,530,81,SPARK_NEG_OK,1.120566,1.104442,1.094389,1.138831,SOFT_START,1254,2409,0 +201598897,531,80,SPARK_NEG_OK,1.115439,1.113194,1.080167,1.085449,SOFT_START,531,70,SPARK_NEG_OK,1.121023,1.105274,1.095546,1.138757,SOFT_START,1254,2402,0 +201646897,532,70,SPARK_NEG_OK,1.115975,1.113811,1.081679,1.086762,SOFT_START,532,71,SPARK_NEG_OK,1.121441,1.106076,1.096582,1.138828,SOFT_START,1251,2383,0 +201694897,533,70,SPARK_NEG_OK,1.116499,1.114403,1.083114,1.088068,SOFT_START,533,80,SPARK_NEG_OK,1.121813,1.106853,1.097677,1.138723,SOFT_START,1252,2380,0 +201742897,534,80,SPARK_NEG_OK,1.117015,1.114991,1.084445,1.089289,SOFT_START,534,80,SPARK_NEG_OK,1.122192,1.107674,1.098652,1.138834,SOFT_START,1252,2380,0 +201790897,535,81,SPARK_NEG_OK,1.117530,1.115546,1.085800,1.090488,SOFT_START,535,70,SPARK_NEG_OK,1.122588,1.108392,1.099638,1.138642,SOFT_START,1253,2405,0 +201838897,536,71,SPARK_NEG_OK,1.118104,1.116104,1.087092,1.091663,SOFT_START,536,70,SPARK_NEG_OK,1.122990,1.109141,1.100665,1.139036,SOFT_START,1253,2398,0 +201886897,537,71,SPARK_NEG_OK,1.118549,1.116635,1.088361,1.092771,SOFT_START,537,70,SPARK_NEG_OK,1.123285,1.109860,1.101645,1.138850,SOFT_START,1255,2394,0 +201933897,538,70,SPARK_NEG_OK,1.119111,1.117174,1.089655,1.093875,SOFT_START,538,70,SPARK_NEG_OK,1.123696,1.110489,1.102509,1.138873,SOFT_START,1253,2403,0 +201981897,539,71,SPARK_NEG_OK,1.119568,1.117647,1.090816,1.095059,SOFT_START,539,70,SPARK_NEG_OK,1.124062,1.111242,1.103415,1.138797,SOFT_START,1255,2397,0 +202029897,540,80,SPARK_NEG_OK,1.120059,1.118185,1.092016,1.096061,SOFT_START,540,80,SPARK_NEG_OK,1.124328,1.111915,1.104305,1.138807,SOFT_START,1253,2392,0 +202077897,541,79,SPARK_NEG_OK,1.120474,1.118659,1.093126,1.097113,SOFT_START,541,80,SPARK_NEG_OK,1.124708,1.112576,1.105129,1.138814,SOFT_START,1253,2378,0 +202125897,542,81,SPARK_NEG_OK,1.120901,1.119217,1.094308,1.098135,SOFT_START,542,81,SPARK_NEG_OK,1.124997,1.113158,1.105974,1.138845,SOFT_START,1254,2395,0 +202173897,543,81,SPARK_NEG_OK,1.121387,1.119600,1.095368,1.099109,SOFT_START,543,80,SPARK_NEG_OK,1.125306,1.113785,1.106868,1.138796,SOFT_START,1251,2410,0 +202221897,544,80,SPARK_NEG_OK,1.121778,1.120050,1.096434,1.100059,SOFT_START,544,70,SPARK_NEG_OK,1.125649,1.114410,1.107573,1.138732,SOFT_START,1253,2393,0 +202268897,545,71,SPARK_NEG_OK,1.122131,1.120490,1.097474,1.101034,SOFT_START,545,70,SPARK_NEG_OK,1.125904,1.114989,1.108328,1.138809,SOFT_START,1252,2394,0 +202316897,546,70,SPARK_NEG_OK,1.122556,1.120923,1.098465,1.101942,SOFT_START,546,80,SPARK_NEG_OK,1.126221,1.115513,1.109101,1.138626,SOFT_START,1253,2388,0 +202364897,547,81,SPARK_NEG_OK,1.122971,1.121345,1.099439,1.102881,SOFT_START,547,80,SPARK_NEG_OK,1.126502,1.116087,1.109859,1.138797,SOFT_START,1253,2395,0 +202412897,548,80,SPARK_NEG_OK,1.123367,1.121764,1.100420,1.103704,SOFT_START,548,80,SPARK_NEG_OK,1.126735,1.116588,1.110508,1.138771,SOFT_START,1254,2402,0 +202460897,549,81,SPARK_NEG_OK,1.123729,1.122118,1.101326,1.104504,SOFT_START,549,80,SPARK_NEG_OK,1.127037,1.117154,1.111209,1.138871,SOFT_START,1253,2413,0 +202508897,550,80,SPARK_NEG_OK,1.124052,1.122540,1.102247,1.105285,SOFT_START,550,80,SPARK_NEG_OK,1.127303,1.117652,1.111873,1.138899,SOFT_START,1255,2407,0 +202556897,551,71,SPARK_NEG_OK,1.124464,1.122864,1.103110,1.106164,SOFT_START,551,70,SPARK_NEG_OK,1.127528,1.118168,1.112547,1.138874,SOFT_START,1253,2408,0 +202603897,552,70,SPARK_NEG_OK,1.124817,1.123246,1.103999,1.106918,SOFT_START,552,70,SPARK_NEG_OK,1.127766,1.118714,1.113204,1.138896,SOFT_START,1254,2382,0 +202651897,553,71,SPARK_NEG_OK,1.125109,1.123635,1.104894,1.107679,SOFT_START,553,70,SPARK_NEG_OK,1.128072,1.119144,1.113821,1.138880,SOFT_START,1252,2379,0 +202699897,554,70,SPARK_NEG_OK,1.125482,1.123979,1.105682,1.108425,SOFT_START,554,70,SPARK_NEG_OK,1.128288,1.119595,1.114442,1.138847,SOFT_START,1253,2394,0 +202747897,555,71,SPARK_NEG_OK,1.125780,1.124310,1.106517,1.109173,SOFT_START,555,70,SPARK_NEG_OK,1.128522,1.120074,1.115050,1.138802,SOFT_START,1252,2391,0 +202795897,556,70,SPARK_NEG_OK,1.126087,1.124665,1.107286,1.109830,SOFT_START,556,70,SPARK_NEG_OK,1.128744,1.120507,1.115615,1.138902,SOFT_START,1251,2405,0 +202843897,557,71,SPARK_NEG_OK,1.126372,1.124983,1.108062,1.110542,SOFT_START,557,70,SPARK_NEG_OK,1.128954,1.120918,1.116185,1.138737,SOFT_START,1252,2393,0 +202891897,558,70,SPARK_NEG_OK,1.126746,1.125274,1.108785,1.111185,SOFT_START,558,70,SPARK_NEG_OK,1.129195,1.121339,1.116720,1.138896,SOFT_START,1253,2406,0 +202939897,559,71,SPARK_NEG_OK,1.126972,1.125579,1.109431,1.111852,SOFT_START,559,70,SPARK_NEG_OK,1.129389,1.121787,1.117278,1.138616,SOFT_START,1254,2383,0 +202986897,560,70,SPARK_NEG_OK,1.127256,1.125954,1.110200,1.112527,SOFT_START,560,70,SPARK_NEG_OK,1.129605,1.122178,1.117793,1.138837,SOFT_START,1254,2397,0 +203034897,561,70,SPARK_NEG_OK,1.127521,1.126215,1.110948,1.113124,SOFT_START,561,71,SPARK_NEG_OK,1.129785,1.122516,1.118301,1.138837,SOFT_START,1255,2377,0 +203082897,562,80,SPARK_NEG_OK,1.127763,1.126499,1.111594,1.113740,SOFT_START,562,80,SPARK_NEG_OK,1.129978,1.122965,1.118799,1.138864,SOFT_START,1254,2379,0 +203130897,563,82,SPARK_NEG_OK,1.128008,1.126766,1.112216,1.114309,SOFT_START,563,81,SPARK_NEG_OK,1.130173,1.123309,1.119263,1.138856,SOFT_START,1255,2405,0 +203178897,564,80,SPARK_NEG_OK,1.128282,1.127065,1.112880,1.114911,SOFT_START,564,80,SPARK_NEG_OK,1.130401,1.123667,1.119744,1.138949,SOFT_START,1253,2390,0 +203226897,565,77,SPARK_NEG_OK,1.128497,1.127325,1.113498,1.115477,SOFT_START,565,81,SPARK_NEG_OK,1.130569,1.124066,1.120234,1.139036,SOFT_START,1253,2390,0 +203274897,566,82,SPARK_NEG_OK,1.128756,1.127586,1.114134,1.116016,SOFT_START,566,80,SPARK_NEG_OK,1.130741,1.124399,1.120687,1.138871,SOFT_START,1252,2412,0 +203321897,567,80,SPARK_NEG_OK,1.129027,1.127842,1.114693,1.116534,SOFT_START,567,81,SPARK_NEG_OK,1.130925,1.124694,1.121141,1.138884,SOFT_START,1253,2408,0 +203369897,568,80,SPARK_NEG_OK,1.129220,1.128073,1.115343,1.117056,SOFT_START,568,70,SPARK_NEG_OK,1.131092,1.125062,1.121511,1.138843,SOFT_START,1253,2399,0 +203417897,569,70,SPARK_NEG_OK,1.129464,1.128345,1.115847,1.117597,SOFT_START,569,71,SPARK_NEG_OK,1.131223,1.125338,1.121945,1.138898,SOFT_START,1253,2393,0 +203465897,570,70,SPARK_NEG_OK,1.129640,1.128587,1.116409,1.118097,SOFT_START,570,70,SPARK_NEG_OK,1.131420,1.125678,1.122339,1.138816,SOFT_START,1255,2390,0 +203513897,571,70,SPARK_NEG_OK,1.129864,1.128784,1.116922,1.118577,SOFT_START,571,71,SPARK_NEG_OK,1.131573,1.125948,1.122746,1.138926,SOFT_START,1254,2390,0 +203560897,572,70,SPARK_NEG_OK,1.130129,1.129021,1.117457,1.119039,SOFT_START,572,70,SPARK_NEG_OK,1.131730,1.126280,1.123102,1.138676,SOFT_START,1256,2398,0 +203608897,573,70,SPARK_NEG_OK,1.130254,1.129213,1.117969,1.119496,SOFT_START,573,71,SPARK_NEG_OK,1.131891,1.126558,1.123507,1.138920,SOFT_START,1254,2379,0 +203656897,574,70,SPARK_NEG_OK,1.130479,1.129481,1.118445,1.119968,SOFT_START,574,70,SPARK_NEG_OK,1.132035,1.126829,1.123875,1.138936,SOFT_START,1255,2393,0 +203704897,575,80,SPARK_NEG_OK,1.130633,1.129645,1.118931,1.120403,SOFT_START,575,81,SPARK_NEG_OK,1.132177,1.127099,1.124249,1.138933,SOFT_START,1253,2386,0 +203752897,576,80,SPARK_NEG_OK,1.130868,1.129883,1.119400,1.120870,SOFT_START,576,80,SPARK_NEG_OK,1.132313,1.127391,1.124581,1.138894,SOFT_START,1254,2407,0 +203800897,577,70,SPARK_NEG_OK,1.131052,1.130082,1.119840,1.121246,SOFT_START,577,71,SPARK_NEG_OK,1.132451,1.127626,1.124902,1.138918,SOFT_START,1252,2388,0 +203848897,578,70,SPARK_NEG_OK,1.131209,1.130256,1.120329,1.121694,SOFT_START,578,70,SPARK_NEG_OK,1.132597,1.127908,1.125255,1.138948,SOFT_START,1254,2416,0 +203895897,579,80,SPARK_NEG_OK,1.131371,1.130462,1.120753,1.122053,SOFT_START,579,81,SPARK_NEG_OK,1.132736,1.128177,1.125531,1.138886,SOFT_START,1253,2395,0 +203943897,580,80,SPARK_NEG_OK,1.131585,1.130660,1.121199,1.122443,SOFT_START,580,80,SPARK_NEG_OK,1.132843,1.128360,1.125883,1.138901,SOFT_START,1255,2410,0 +203991897,581,79,SPARK_NEG_OK,1.131753,1.130794,1.121595,1.122828,SOFT_START,581,71,SPARK_NEG_OK,1.132978,1.128653,1.126165,1.138776,SOFT_START,1255,2403,0 +204039897,582,70,SPARK_NEG_OK,1.131896,1.131007,1.122040,1.123224,SOFT_START,582,70,SPARK_NEG_OK,1.133085,1.128849,1.126499,1.138889,SOFT_START,1255,2391,0 +204086897,583,70,SPARK_NEG_OK,1.132048,1.131191,1.122390,1.123527,SOFT_START,583,71,SPARK_NEG_OK,1.133176,1.129067,1.126790,1.138747,SOFT_START,1256,2396,0 +204134897,584,71,SPARK_NEG_OK,1.132182,1.131328,1.122783,1.123902,SOFT_START,584,70,SPARK_NEG_OK,1.133327,1.129296,1.127064,1.138871,SOFT_START,1255,2383,0 +204182897,585,70,SPARK_NEG_OK,1.132326,1.131483,1.123149,1.124233,SOFT_START,585,70,SPARK_NEG_OK,1.133432,1.129522,1.127334,1.138717,SOFT_START,1256,2391,0 +204230897,586,71,SPARK_NEG_OK,1.132447,1.131675,1.123508,1.124576,SOFT_START,586,70,SPARK_NEG_OK,1.133550,1.129704,1.127616,1.138788,SOFT_START,1253,2384,0 +204278897,587,70,SPARK_NEG_OK,1.132576,1.131840,1.123859,1.124949,SOFT_START,587,73,SPARK_NEG_OK,1.133661,1.129873,1.127878,1.138865,SOFT_START,1255,2409,0 +204326897,588,71,SPARK_NEG_OK,1.132775,1.132003,1.124236,1.125205,SOFT_START,588,70,SPARK_NEG_OK,1.133687,1.130081,1.128122,1.138859,SOFT_START,1253,2408,0 +204373897,589,70,SPARK_NEG_OK,1.132886,1.132116,1.124533,1.125501,SOFT_START,589,70,SPARK_NEG_OK,1.133823,1.130288,1.128405,1.138873,SOFT_START,1254,2408,0 +204421897,590,81,SPARK_NEG_OK,1.133031,1.132269,1.124906,1.125804,SOFT_START,590,80,SPARK_NEG_OK,1.133918,1.130489,1.128632,1.138848,SOFT_START,1254,2383,0 +204469897,591,80,SPARK_NEG_OK,1.133114,1.132400,1.125188,1.126098,SOFT_START,591,80,SPARK_NEG_OK,1.133995,1.130626,1.128935,1.138927,SOFT_START,1256,2378,0 +204517897,592,69,SPARK_NEG_OK,1.133261,1.132538,1.125499,1.126412,SOFT_START,592,70,SPARK_NEG_OK,1.134138,1.130829,1.129041,1.138785,SOFT_START,1256,2397,0 +204564897,593,70,SPARK_NEG_OK,1.133376,1.132649,1.125786,1.126693,SOFT_START,593,70,SPARK_NEG_OK,1.134183,1.131005,1.129361,1.138824,SOFT_START,1255,2404,0 +204612897,594,71,SPARK_NEG_OK,1.133503,1.132825,1.126093,1.126937,SOFT_START,594,70,SPARK_NEG_OK,1.134316,1.131185,1.129503,1.138696,SOFT_START,1257,2385,0 +204660897,595,70,SPARK_NEG_OK,1.133618,1.132931,1.126370,1.127225,SOFT_START,595,70,SPARK_NEG_OK,1.134375,1.131340,1.129751,1.138813,SOFT_START,1255,2407,0 +204708897,596,71,SPARK_NEG_OK,1.133702,1.133084,1.126682,1.127475,SOFT_START,596,70,SPARK_NEG_OK,1.134505,1.131500,1.129915,1.138619,SOFT_START,1256,2380,0 +204756897,597,72,SPARK_NEG_OK,1.133820,1.133178,1.126940,1.127722,SOFT_START,597,70,SPARK_NEG_OK,1.134550,1.131664,1.130131,1.138905,SOFT_START,1253,2408,0 +204803897,598,71,SPARK_NEG_OK,1.133943,1.133238,1.127186,1.127970,SOFT_START,598,70,SPARK_NEG_OK,1.134608,1.131836,1.130339,1.138842,SOFT_START,1255,2401,0 +204851897,599,70,SPARK_NEG_OK,1.134033,1.133389,1.127473,1.128185,SOFT_START,599,70,SPARK_NEG_OK,1.134678,1.131936,1.130502,1.138830,SOFT_START,1253,2392,0 +204899897,600,71,SPARK_NEG_OK,1.134166,1.133459,1.127691,1.128410,SOFT_START,600,70,SPARK_NEG_OK,1.134800,1.132101,1.130686,1.138820,SOFT_START,1254,2399,0 +204947897,601,70,SPARK_NEG_OK,1.134239,1.133617,1.127937,1.128651,SOFT_START,601,70,SPARK_NEG_OK,1.134834,1.132230,1.130866,1.138802,SOFT_START,1253,2397,0 +204995897,602,71,SPARK_NEG_OK,1.134290,1.133719,1.128195,1.128885,SOFT_START,602,72,SPARK_NEG_OK,1.134951,1.132371,1.131055,1.138833,SOFT_START,1255,2408,0 +205042897,603,70,SPARK_NEG_OK,1.134422,1.133826,1.128433,1.129097,SOFT_START,603,70,SPARK_NEG_OK,1.134976,1.132500,1.131225,1.138776,SOFT_START,1255,2407,0 +205090897,604,70,SPARK_NEG_OK,1.134560,1.133960,1.128629,1.129293,SOFT_START,604,71,SPARK_NEG_OK,1.135051,1.132664,1.131401,1.138805,SOFT_START,1258,2388,0 +205138897,605,70,SPARK_NEG_OK,1.134604,1.134044,1.128886,1.129477,SOFT_START,605,70,SPARK_NEG_OK,1.135131,1.132760,1.131556,1.138778,SOFT_START,1258,2409,0 +205186897,606,72,SPARK_NEG_OK,1.134708,1.134147,1.129117,1.129703,SOFT_START,606,71,SPARK_NEG_OK,1.135171,1.132931,1.131679,1.138850,SOFT_START,1256,2408,0 +205233897,607,70,SPARK_NEG_OK,1.134787,1.134223,1.129311,1.129915,SOFT_START,607,70,SPARK_NEG_OK,1.135274,1.133052,1.131873,1.138710,SOFT_START,1257,2384,0 +205281897,608,70,SPARK_NEG_OK,1.134865,1.134356,1.129528,1.130109,SOFT_START,608,71,SPARK_NEG_OK,1.135339,1.133137,1.132033,1.138831,SOFT_START,1254,2384,0 +205329897,609,70,SPARK_NEG_OK,1.134943,1.134419,1.129721,1.130335,SOFT_START,609,70,SPARK_NEG_OK,1.135429,1.133248,1.132148,1.138665,SOFT_START,1256,2377,0 +205377897,610,70,SPARK_NEG_OK,1.135026,1.134529,1.129931,1.130496,SOFT_START,610,71,SPARK_NEG_OK,1.135463,1.133364,1.132323,1.138867,SOFT_START,1254,2409,0 +205425897,611,70,SPARK_NEG_OK,1.135066,1.134599,1.130127,1.130676,SOFT_START,611,70,SPARK_NEG_OK,1.135522,1.133486,1.132442,1.138880,SOFT_START,1255,2406,0 +205472897,612,70,SPARK_NEG_OK,1.135182,1.134692,1.130301,1.130835,SOFT_START,612,71,SPARK_NEG_OK,1.135612,1.133574,1.132601,1.138867,SOFT_START,1254,2388,0 +205520897,613,70,SPARK_NEG_OK,1.135260,1.134777,1.130508,1.130986,SOFT_START,613,70,SPARK_NEG_OK,1.135617,1.133719,1.132755,1.138851,SOFT_START,1256,2389,0 +205568897,614,70,SPARK_NEG_OK,1.135315,1.134852,1.130677,1.131207,SOFT_START,614,71,SPARK_NEG_OK,1.135724,1.133778,1.132845,1.138829,SOFT_START,1255,2411,0 +205616897,615,70,SPARK_NEG_OK,1.135399,1.134927,1.130881,1.131350,SOFT_START,615,70,SPARK_NEG_OK,1.135759,1.133909,1.133006,1.138879,SOFT_START,1257,2386,0 +205663897,616,79,SPARK_NEG_OK,1.135495,1.134959,1.131017,1.131487,SOFT_START,616,81,SPARK_NEG_OK,1.135787,1.133997,1.133127,1.138874,SOFT_START,1255,2399,0 +205711897,617,80,SPARK_NEG_OK,1.135520,1.135067,1.131204,1.131659,SOFT_START,617,80,SPARK_NEG_OK,1.135874,1.134105,1.133274,1.138873,SOFT_START,1257,2407,0 +205759897,618,80,SPARK_NEG_OK,1.135619,1.135129,1.131348,1.131824,SOFT_START,618,81,SPARK_NEG_OK,1.135916,1.134202,1.133389,1.138812,SOFT_START,1257,2384,0 +205807897,619,80,SPARK_NEG_OK,1.135651,1.135225,1.131532,1.131940,SOFT_START,619,82,SPARK_NEG_OK,1.135957,1.134341,1.133502,1.138892,SOFT_START,1253,2383,0 +205855897,620,80,SPARK_NEG_OK,1.135715,1.135327,1.131660,1.132147,SOFT_START,620,71,SPARK_NEG_OK,1.136003,1.134349,1.133665,1.138714,SOFT_START,1255,2395,0 +205902897,621,70,SPARK_NEG_OK,1.135788,1.135347,1.131834,1.132263,SOFT_START,621,70,SPARK_NEG_OK,1.136041,1.134463,1.133713,1.138917,SOFT_START,1253,2404,0 +205950897,622,70,SPARK_NEG_OK,1.135820,1.135389,1.131979,1.132408,SOFT_START,622,69,SPARK_NEG_OK,1.136087,1.134558,1.133811,1.138713,SOFT_START,1254,2402,0 +205998897,623,71,SPARK_NEG_OK,1.135876,1.135477,1.132106,1.132482,SOFT_START,623,70,SPARK_NEG_OK,1.136100,1.134619,1.133996,1.138872,SOFT_START,1253,2398,0 +206046897,624,70,SPARK_NEG_OK,1.135936,1.135568,1.132252,1.132615,SOFT_START,624,70,SPARK_NEG_OK,1.136187,1.134738,1.134033,1.138862,SOFT_START,1255,2392,0 +206094897,625,71,SPARK_NEG_OK,1.135975,1.135554,1.132411,1.132753,SOFT_START,625,70,SPARK_NEG_OK,1.136206,1.134777,1.134079,1.138827,SOFT_START,1254,2395,0 +206141897,626,70,SPARK_NEG_OK,1.136060,1.135671,1.132526,1.132892,SOFT_START,626,70,SPARK_NEG_OK,1.136236,1.134861,1.134246,1.138902,SOFT_START,1256,2382,0 +206189897,627,71,SPARK_NEG_OK,1.136098,1.135743,1.132665,1.133006,SOFT_START,627,70,SPARK_NEG_OK,1.136296,1.134892,1.134322,1.138861,SOFT_START,1255,2401,0 +206237897,628,70,SPARK_NEG_OK,1.136178,1.135821,1.132780,1.133171,SOFT_START,628,70,SPARK_NEG_OK,1.136329,1.135037,1.134430,1.138902,SOFT_START,1256,2400,0 +206285897,629,69,SPARK_NEG_OK,1.136190,1.135806,1.132932,1.133249,SOFT_START,629,68,SPARK_NEG_OK,1.136373,1.135075,1.134543,1.138810,SOFT_START,1256,2388,0 +206333897,630,70,SPARK_NEG_OK,1.136256,1.135892,1.133022,1.133398,SOFT_START,630,70,SPARK_NEG_OK,1.136389,1.135152,1.134625,1.138916,SOFT_START,1253,2395,0 +206381897,631,71,SPARK_NEG_OK,1.136281,1.135964,1.133145,1.133482,SOFT_START,631,70,SPARK_NEG_OK,1.136442,1.135265,1.134719,1.138995,SOFT_START,1254,2410,0 +206428897,632,70,SPARK_NEG_OK,1.136367,1.135965,1.133221,1.133585,SOFT_START,632,70,SPARK_NEG_OK,1.136491,1.135330,1.134806,1.139027,SOFT_START,1252,2396,0 +206476897,633,71,SPARK_NEG_OK,1.136441,1.136047,1.133353,1.133731,SOFT_START,633,70,SPARK_NEG_OK,1.136546,1.135391,1.134880,1.138713,SOFT_START,1254,2377,0 +206524897,634,70,SPARK_NEG_OK,1.136444,1.136106,1.133487,1.133835,SOFT_START,634,70,SPARK_NEG_OK,1.136540,1.135456,1.134954,1.138911,SOFT_START,1253,2384,0 +206572897,635,71,SPARK_NEG_OK,1.136501,1.136176,1.133603,1.133894,SOFT_START,635,70,SPARK_NEG_OK,1.136585,1.135475,1.135038,1.138917,SOFT_START,1254,2390,0 +206620897,636,68,SPARK_NEG_OK,1.136528,1.136224,1.133661,1.133976,SOFT_START,636,70,SPARK_NEG_OK,1.136616,1.135532,1.135086,1.138950,SOFT_START,1253,2402,0 +206668897,637,71,SPARK_NEG_OK,1.136578,1.136293,1.133782,1.134093,SOFT_START,637,70,SPARK_NEG_OK,1.136661,1.135601,1.135119,1.138937,SOFT_START,1255,2398,0 +206715897,638,70,SPARK_NEG_OK,1.136572,1.136293,1.133899,1.134155,SOFT_START,638,70,SPARK_NEG_OK,1.136705,1.135700,1.135234,1.138884,SOFT_START,1253,2400,0 +206763897,639,71,SPARK_NEG_OK,1.136661,1.136320,1.134009,1.134276,SOFT_START,639,70,SPARK_NEG_OK,1.136727,1.135731,1.135298,1.138865,SOFT_START,1254,2388,0 +206811897,640,70,SPARK_NEG_OK,1.136684,1.136315,1.134021,1.134324,SOFT_START,640,70,SPARK_NEG_OK,1.136751,1.135793,1.135439,1.138874,SOFT_START,1251,2377,0 +206859897,641,71,SPARK_NEG_OK,1.136736,1.136401,1.134177,1.134433,SOFT_START,641,70,SPARK_NEG_OK,1.136810,1.135805,1.135440,1.138849,SOFT_START,1251,2386,0 +206907897,642,70,SPARK_NEG_OK,1.136760,1.136377,1.134238,1.134508,SOFT_START,642,70,SPARK_NEG_OK,1.136824,1.135889,1.135496,1.138819,SOFT_START,1252,2403,0 +206955897,643,71,SPARK_NEG_OK,1.136823,1.136481,1.134346,1.134581,SOFT_START,643,70,SPARK_NEG_OK,1.136829,1.135958,1.135588,1.138839,SOFT_START,1248,2396,0 +207003897,644,70,SPARK_NEG_OK,1.136875,1.136538,1.134424,1.134701,SOFT_START,644,70,SPARK_NEG_OK,1.136903,1.135998,1.135640,1.138859,SOFT_START,1250,2407,0 +207051897,645,71,SPARK_NEG_OK,1.136889,1.136612,1.134498,1.134824,SOFT_START,645,70,SPARK_NEG_OK,1.136884,1.136024,1.135685,1.138971,SOFT_START,1248,2401,0 +207099897,646,70,SPARK_NEG_OK,1.136907,1.136622,1.134619,1.134846,SOFT_START,646,70,SPARK_NEG_OK,1.136922,1.136099,1.135741,1.138781,SOFT_START,1250,2400,0 +207147897,647,71,SPARK_NEG_OK,1.136925,1.136633,1.134694,1.134923,SOFT_START,647,70,SPARK_NEG_OK,1.136970,1.136153,1.135821,1.138911,SOFT_START,1249,2399,0 +207195897,648,70,SPARK_NEG_OK,1.136994,1.136702,1.134779,1.134986,SOFT_START,648,70,SPARK_NEG_OK,1.136993,1.136173,1.135860,1.138910,SOFT_START,1251,2400,0 +207243897,649,71,SPARK_NEG_OK,1.137035,1.136782,1.134806,1.135014,SOFT_START,649,70,SPARK_NEG_OK,1.136991,1.136198,1.135871,1.138946,SOFT_START,1249,2397,0 +207291897,650,70,SPARK_NEG_OK,1.137052,1.136751,1.134884,1.135129,SOFT_START,650,70,SPARK_NEG_OK,1.137061,1.136202,1.135965,1.139167,SOFT_START,1250,2410,0 +207339897,651,71,SPARK_NEG_OK,1.137053,1.136799,1.135005,1.135190,SOFT_START,651,70,SPARK_NEG_OK,1.137055,1.136305,1.136019,1.139131,SOFT_START,1248,2395,0 +207387897,652,70,SPARK_NEG_OK,1.137114,1.136843,1.135079,1.135268,SOFT_START,652,70,SPARK_NEG_OK,1.137056,1.136323,1.136070,1.138959,SOFT_START,1248,2395,0 +207436897,653,71,SPARK_NEG_OK,1.137147,1.136870,1.135135,1.135329,SOFT_START,653,70,SPARK_NEG_OK,1.137103,1.136361,1.136140,1.138963,SOFT_START,1246,2391,0 +207484897,654,70,SPARK_NEG_OK,1.137186,1.136910,1.135207,1.135374,SOFT_START,654,70,SPARK_NEG_OK,1.137115,1.136386,1.136172,1.138939,SOFT_START,1246,2393,0 +207532897,655,71,SPARK_NEG_OK,1.137220,1.136937,1.135207,1.135443,SOFT_START,655,70,SPARK_NEG_OK,1.137133,1.136455,1.136222,1.138845,SOFT_START,1246,2384,0 +207580897,656,70,SPARK_NEG_OK,1.137244,1.136963,1.135340,1.135508,SOFT_START,656,70,SPARK_NEG_OK,1.137129,1.136511,1.136242,1.138897,SOFT_START,1245,2390,0 +207628897,657,71,SPARK_NEG_OK,1.137260,1.137051,1.135381,1.135535,SOFT_START,657,70,SPARK_NEG_OK,1.137165,1.136539,1.136326,1.138820,SOFT_START,1246,2400,0 +207676897,658,70,SPARK_NEG_OK,1.137275,1.137039,1.135451,1.135614,SOFT_START,658,70,SPARK_NEG_OK,1.137177,1.136581,1.136347,1.138896,SOFT_START,1246,2383,0 +207724897,659,71,SPARK_NEG_OK,1.137291,1.137071,1.135532,1.135697,SOFT_START,659,70,SPARK_NEG_OK,1.137220,1.136616,1.136430,1.138723,SOFT_START,1247,2390,0 +207772897,660,70,SPARK_NEG_OK,1.137345,1.137084,1.135578,1.135753,SOFT_START,660,70,SPARK_NEG_OK,1.137217,1.136657,1.136453,1.138899,SOFT_START,1247,2390,0 +207820897,661,71,SPARK_NEG_OK,1.137336,1.137136,1.135653,1.135782,SOFT_START,661,71,SPARK_NEG_OK,1.137232,1.136684,1.136476,1.138793,SOFT_START,1248,2389,0 +207869897,662,70,SPARK_NEG_OK,1.137339,1.137162,1.135653,1.135827,SOFT_START,662,70,SPARK_NEG_OK,1.137230,1.136649,1.136519,1.138955,SOFT_START,1246,2394,0 +207917897,663,71,SPARK_NEG_OK,1.137378,1.137158,1.135715,1.135840,SOFT_START,663,70,SPARK_NEG_OK,1.137323,1.136763,1.136547,1.138941,SOFT_START,1246,2382,0 +207965897,664,70,SPARK_NEG_OK,1.137402,1.137172,1.135809,1.135924,SOFT_START,664,70,SPARK_NEG_OK,1.137288,1.136780,1.136626,1.138881,SOFT_START,1244,2405,0 +208013897,665,71,SPARK_NEG_OK,1.137406,1.137213,1.135818,1.135986,SOFT_START,665,70,SPARK_NEG_OK,1.137280,1.136815,1.136605,1.138930,SOFT_START,1244,2381,0 +208062897,666,70,SPARK_NEG_OK,1.137441,1.137217,1.135890,1.136030,SOFT_START,666,70,SPARK_NEG_OK,1.137332,1.136788,1.136665,1.138889,SOFT_START,1242,2383,0 +208110897,667,71,SPARK_NEG_OK,1.137428,1.137276,1.135906,1.136067,SOFT_START,667,70,SPARK_NEG_OK,1.137349,1.136858,1.136656,1.138921,SOFT_START,1243,2404,0 +208158897,668,71,SPARK_NEG_OK,1.137445,1.137310,1.135996,1.136121,SOFT_START,668,70,SPARK_NEG_OK,1.137372,1.136899,1.136745,1.138875,SOFT_START,1243,2401,0 +208206897,669,71,SPARK_NEG_OK,1.137513,1.137339,1.136035,1.136145,SOFT_START,669,70,SPARK_NEG_OK,1.137406,1.136923,1.136765,1.138910,SOFT_START,1245,2382,0 +208254897,670,70,SPARK_NEG_OK,1.137507,1.137315,1.136053,1.136214,SOFT_START,670,71,SPARK_NEG_OK,1.137404,1.136933,1.136842,1.138818,SOFT_START,1245,2390,0 +208303897,671,71,SPARK_NEG_OK,1.137514,1.137354,1.136136,1.136269,SOFT_START,671,70,SPARK_NEG_OK,1.137457,1.136939,1.136837,1.138895,SOFT_START,1244,2390,0 +208351897,672,70,SPARK_NEG_OK,1.137560,1.137413,1.136165,1.136279,SOFT_START,672,71,SPARK_NEG_OK,1.137465,1.137029,1.136847,1.138875,SOFT_START,1245,2410,0 +208399897,673,70,SPARK_NEG_OK,1.137582,1.137403,1.136202,1.136299,SOFT_START,673,70,SPARK_NEG_OK,1.137475,1.137018,1.136890,1.138923,SOFT_START,1242,2386,0 +208447897,674,70,SPARK_NEG_OK,1.137592,1.137396,1.136280,1.136379,SOFT_START,674,70,SPARK_NEG_OK,1.137473,1.137047,1.136881,1.138676,SOFT_START,1244,2410,0 +208496897,675,70,SPARK_NEG_OK,1.137592,1.137460,1.136273,1.136407,SOFT_START,675,70,SPARK_NEG_OK,1.137475,1.137080,1.136939,1.138871,SOFT_START,1241,2392,0 +208544897,676,70,SPARK_NEG_OK,1.137590,1.137447,1.136316,1.136456,SOFT_START,676,71,SPARK_NEG_OK,1.137534,1.137108,1.136980,1.138809,SOFT_START,1242,2406,0 +208592897,677,70,SPARK_NEG_OK,1.137633,1.137507,1.136345,1.136532,SOFT_START,677,70,SPARK_NEG_OK,1.137542,1.137111,1.137003,1.138898,SOFT_START,1241,2404,0 +208641897,678,70,SPARK_NEG_OK,1.137679,1.137521,1.136377,1.136529,SOFT_START,678,71,SPARK_NEG_OK,1.137469,1.137170,1.137097,1.138923,SOFT_START,1242,2384,0 +208689897,679,70,SPARK_NEG_OK,1.137649,1.137515,1.136469,1.136563,SOFT_START,679,72,SPARK_NEG_OK,1.137542,1.137152,1.137072,1.138843,SOFT_START,1241,2386,0 +208737897,680,70,SPARK_NEG_OK,1.137701,1.137541,1.136492,1.136580,SOFT_START,680,71,SPARK_NEG_OK,1.137546,1.137183,1.137108,1.138945,SOFT_START,1243,2408,0 +208785897,681,70,SPARK_NEG_OK,1.137725,1.137537,1.136547,1.136606,SOFT_START,681,70,SPARK_NEG_OK,1.137558,1.137155,1.137124,1.138886,SOFT_START,1242,2399,0 +208834897,682,70,SPARK_NEG_OK,1.137691,1.137584,1.136563,1.136664,SOFT_START,682,71,SPARK_NEG_OK,1.137617,1.137251,1.137169,1.138918,SOFT_START,1244,2406,0 +208882897,683,70,SPARK_NEG_OK,1.137699,1.137587,1.136602,1.136702,SOFT_START,683,70,SPARK_NEG_OK,1.137563,1.137258,1.137179,1.138815,SOFT_START,1244,2412,0 +208930897,684,70,SPARK_NEG_OK,1.137713,1.137607,1.136653,1.136650,SOFT_START,684,71,SPARK_NEG_OK,1.137600,1.137266,1.137206,1.138885,SOFT_START,1241,2411,0 +208978899,685,70,SPARK_NEG_OK,1.137746,1.137627,1.136679,1.136745,SOFT_START,685,70,SPARK_NEG_OK,1.137625,1.137311,1.137226,1.138851,SOFT_START,1243,2398,0 +209027897,686,70,SPARK_NEG_OK,1.137723,1.137634,1.136693,1.136773,SOFT_START,686,71,SPARK_NEG_OK,1.137648,1.137345,1.137269,1.138915,SOFT_START,1240,2405,0 +209075897,687,70,SPARK_NEG_OK,1.137763,1.137643,1.136718,1.136824,SOFT_START,687,70,SPARK_NEG_OK,1.137634,1.137334,1.137307,1.138732,SOFT_START,1241,2396,0 +209124897,688,70,SPARK_NEG_OK,1.137781,1.137671,1.136783,1.136880,SOFT_START,688,70,SPARK_NEG_OK,1.137646,1.137368,1.137317,1.138941,SOFT_START,1240,2407,0 +209172897,689,70,SPARK_NEG_OK,1.137768,1.137643,1.136767,1.136814,SOFT_START,689,70,SPARK_NEG_OK,1.137663,1.137373,1.137310,1.138902,SOFT_START,1241,2411,0 +209220897,690,71,SPARK_NEG_OK,1.137781,1.137674,1.136758,1.136814,SOFT_START,690,70,SPARK_NEG_OK,1.137654,1.137396,1.137297,1.138838,SOFT_START,1241,2394,0 +209268897,691,70,SPARK_NEG_OK,1.137773,1.137729,1.136826,1.136902,SOFT_START,691,70,SPARK_NEG_OK,1.137680,1.137432,1.137341,1.138957,SOFT_START,1243,2394,0 +209317897,692,71,SPARK_NEG_OK,1.137832,1.137734,1.136842,1.136949,SOFT_START,692,70,SPARK_NEG_OK,1.137698,1.137413,1.137412,1.138883,SOFT_START,1242,2385,0 +209365897,693,70,SPARK_NEG_OK,1.137817,1.137738,1.136888,1.136965,SOFT_START,693,72,SPARK_NEG_OK,1.137694,1.137418,1.137387,1.138899,SOFT_START,1244,2384,0 +209413897,694,71,SPARK_NEG_OK,1.137847,1.137711,1.136894,1.136992,SOFT_START,694,70,SPARK_NEG_OK,1.137710,1.137507,1.137427,1.138846,SOFT_START,1242,2397,0 +209461897,695,70,SPARK_NEG_OK,1.137819,1.137764,1.136895,1.137000,SOFT_START,695,70,SPARK_NEG_OK,1.137711,1.137467,1.137421,1.138884,SOFT_START,1243,2383,0 +209510897,696,72,SPARK_NEG_OK,1.137864,1.137789,1.136960,1.137031,SOFT_START,696,70,SPARK_NEG_OK,1.137716,1.137476,1.137458,1.138875,SOFT_START,1243,2402,0 +209558897,697,70,SPARK_NEG_OK,1.137865,1.137774,1.136977,1.137070,SOFT_START,697,70,SPARK_NEG_OK,1.137719,1.137494,1.137466,1.138852,SOFT_START,1241,2381,0 +209606897,698,71,SPARK_NEG_OK,1.137885,1.137747,1.137041,1.137088,SOFT_START,698,70,SPARK_NEG_OK,1.137729,1.137481,1.137471,1.138851,SOFT_START,1242,2380,0 +209655897,699,70,SPARK_NEG_OK,1.137878,1.137837,1.137046,1.137101,SOFT_START,699,70,SPARK_NEG_OK,1.137738,1.137557,1.137504,1.138878,SOFT_START,1241,2392,0 +209703897,700,71,SPARK_NEG_OK,1.137918,1.137805,1.137046,1.137153,SOFT_START,700,70,SPARK_NEG_OK,1.137747,1.137551,1.137550,1.138800,SOFT_START,1242,2410,0 +209751897,701,70,SPARK_NEG_OK,1.137910,1.137801,1.137085,1.137159,SOFT_START,701,70,SPARK_NEG_OK,1.137764,1.137571,1.137541,1.138932,SOFT_START,1242,2397,0 +209799902,702,71,SPARK_NEG_OK,1.137905,1.137841,1.137140,1.137174,SOFT_START,702,81,SPARK_NEG_OK,1.137774,1.137558,1.137542,1.138691,SOFT_START,1243,2409,0 +209848897,703,80,SPARK_NEG_OK,1.137861,1.137843,1.137123,1.137176,SOFT_START,703,80,SPARK_NEG_OK,1.137791,1.137603,1.137529,1.138969,SOFT_START,1243,2405,0 +209896897,704,81,SPARK_NEG_OK,1.137929,1.137857,1.137139,1.137183,SOFT_START,704,80,SPARK_NEG_OK,1.137794,1.137597,1.137577,1.138943,SOFT_START,1244,2399,0 +209944897,705,70,SPARK_NEG_OK,1.137953,1.137835,1.137151,1.137241,SOFT_START,705,70,SPARK_NEG_OK,1.137789,1.137597,1.137594,1.138930,SOFT_START,1243,2406,0 +209992897,706,71,SPARK_NEG_OK,1.137976,1.137872,1.137211,1.137235,SOFT_START,706,70,SPARK_NEG_OK,1.137817,1.137612,1.137649,1.139014,SOFT_START,1245,2387,0 +210041897,707,70,SPARK_NEG_OK,1.137991,1.137860,1.137187,1.137286,SOFT_START,707,71,SPARK_NEG_OK,1.137801,1.137645,1.137658,1.139110,SOFT_START,1243,2397,0 +210089897,708,70,SPARK_NEG_OK,1.138004,1.137912,1.137238,1.137297,SOFT_START,708,70,SPARK_NEG_OK,1.137846,1.137665,1.137652,1.138920,SOFT_START,1244,2392,0 +210137897,709,70,SPARK_NEG_OK,1.137998,1.137903,1.137260,1.137341,SOFT_START,709,71,SPARK_NEG_OK,1.137859,1.137704,1.137658,1.138911,SOFT_START,1243,2388,0 +210185897,710,70,SPARK_NEG_OK,1.138005,1.137950,1.137276,1.137326,SOFT_START,710,70,SPARK_NEG_OK,1.137846,1.137695,1.137651,1.138958,SOFT_START,1245,2403,0 +210233897,711,71,SPARK_NEG_OK,1.138015,1.137934,1.137314,1.137378,SOFT_START,711,71,SPARK_NEG_OK,1.137862,1.137675,1.137690,1.138846,SOFT_START,1245,2406,0 +210281897,712,70,SPARK_NEG_OK,1.138023,1.137950,1.137308,1.137351,SOFT_START,712,70,SPARK_NEG_OK,1.137897,1.137687,1.137752,1.138893,SOFT_START,1246,2400,0 +210330897,713,70,SPARK_NEG_OK,1.138036,1.137974,1.137332,1.137399,SOFT_START,713,71,SPARK_NEG_OK,1.137875,1.137727,1.137742,1.138827,SOFT_START,1247,2407,0 +210378897,714,70,SPARK_NEG_OK,1.138043,1.137970,1.137351,1.137382,SOFT_START,714,70,SPARK_NEG_OK,1.137884,1.137701,1.137730,1.138895,SOFT_START,1247,2395,0 +210426897,715,70,SPARK_NEG_OK,1.138008,1.137986,1.137360,1.137441,SOFT_START,715,71,SPARK_NEG_OK,1.137902,1.137705,1.137768,1.138687,SOFT_START,1248,2398,0 +210474897,716,70,SPARK_NEG_OK,1.138081,1.138036,1.137435,1.137413,SOFT_START,716,70,SPARK_NEG_OK,1.137910,1.137754,1.137767,1.138964,SOFT_START,1247,2386,0 +210522897,717,70,SPARK_NEG_OK,1.138100,1.138011,1.137373,1.137469,SOFT_START,717,71,SPARK_NEG_OK,1.137930,1.137763,1.137778,1.138929,SOFT_START,1248,2406,0 +210570897,718,70,SPARK_NEG_OK,1.138043,1.137998,1.137429,1.137460,SOFT_START,718,70,SPARK_NEG_OK,1.137934,1.137778,1.137801,1.138956,SOFT_START,1247,2404,0 +210618897,719,70,SPARK_NEG_OK,1.138090,1.138018,1.137393,1.137499,SOFT_START,719,71,SPARK_NEG_OK,1.137956,1.137770,1.137803,1.138976,SOFT_START,1247,2384,0 +210666897,720,70,SPARK_NEG_OK,1.138112,1.137938,1.137431,1.137509,SOFT_START,720,70,SPARK_NEG_OK,1.137940,1.137810,1.137819,1.138958,SOFT_START,1246,2382,0 +210714897,721,70,SPARK_NEG_OK,1.138068,1.138042,1.137441,1.137522,SOFT_START,721,71,SPARK_NEG_OK,1.137947,1.137820,1.137858,1.138958,SOFT_START,1247,2395,0 +210762897,722,70,SPARK_NEG_OK,1.138151,1.138049,1.137485,1.137538,SOFT_START,722,71,SPARK_NEG_OK,1.137938,1.137806,1.137837,1.138951,SOFT_START,1247,2406,0 +210810897,723,71,SPARK_NEG_OK,1.138098,1.138023,1.137503,1.137535,SOFT_START,723,71,SPARK_NEG_OK,1.137950,1.137818,1.137838,1.138974,SOFT_START,1249,2400,0 +210858897,724,70,SPARK_NEG_OK,1.138130,1.138054,1.137501,1.137530,SOFT_START,724,70,SPARK_NEG_OK,1.137995,1.137803,1.137873,1.138867,SOFT_START,1250,2408,0 +210906897,725,70,SPARK_NEG_OK,1.138141,1.138052,1.137540,1.137519,SOFT_START,725,71,SPARK_NEG_OK,1.137975,1.137847,1.137889,1.138939,SOFT_START,1250,2395,0 +210954897,726,70,SPARK_NEG_OK,1.138138,1.138044,1.137550,1.137602,SOFT_START,726,70,SPARK_NEG_OK,1.137962,1.137841,1.137889,1.138863,SOFT_START,1251,2399,0 +211002897,727,70,SPARK_NEG_OK,1.138136,1.138062,1.137559,1.137611,SOFT_START,727,71,SPARK_NEG_OK,1.137992,1.137902,1.137881,1.138971,SOFT_START,1250,2386,0 +211050897,728,70,SPARK_NEG_OK,1.138138,1.138079,1.137583,1.137606,SOFT_START,728,80,SPARK_NEG_OK,1.137988,1.137871,1.137957,1.138744,SOFT_START,1251,2383,0 +211098897,729,80,SPARK_NEG_OK,1.138191,1.138085,1.137638,1.137646,SOFT_START,729,81,SPARK_NEG_OK,1.137975,1.137877,1.137929,1.138996,SOFT_START,1248,2377,0 +211146897,730,80,SPARK_NEG_OK,1.138163,1.138112,1.137584,1.137645,SOFT_START,730,80,SPARK_NEG_OK,1.137998,1.137894,1.137933,1.138982,SOFT_START,1250,2405,0 +211194897,731,70,SPARK_NEG_OK,1.138152,1.138104,1.137643,1.137658,SOFT_START,731,71,SPARK_NEG_OK,1.138001,1.137852,1.137915,1.138994,SOFT_START,1248,2392,0 +211242897,732,70,SPARK_NEG_OK,1.138180,1.138099,1.137653,1.137661,SOFT_START,732,70,SPARK_NEG_OK,1.138040,1.137912,1.137971,1.138949,SOFT_START,1250,2386,0 +211290897,733,70,SPARK_NEG_OK,1.138184,1.138105,1.137664,1.137684,SOFT_START,733,71,SPARK_NEG_OK,1.138033,1.137890,1.137953,1.138962,SOFT_START,1249,2404,0 +211338897,734,70,SPARK_NEG_OK,1.138155,1.138122,1.137687,1.137703,SOFT_START,734,70,SPARK_NEG_OK,1.138028,1.137899,1.137933,1.139022,SOFT_START,1251,2404,0 +211386897,735,70,SPARK_NEG_OK,1.138198,1.138129,1.137674,1.137721,SOFT_START,735,71,SPARK_NEG_OK,1.138017,1.137896,1.137973,1.139181,SOFT_START,1250,2381,0 +211434897,736,70,SPARK_NEG_OK,1.138204,1.138211,1.137695,1.137647,SOFT_START,736,70,SPARK_NEG_OK,1.138058,1.137925,1.137958,1.139197,SOFT_START,1252,2409,0 +211482897,737,70,SPARK_NEG_OK,1.138175,1.138160,1.137719,1.137723,SOFT_START,737,71,SPARK_NEG_OK,1.138090,1.137953,1.137981,1.138944,SOFT_START,1252,2409,0 +211530897,738,70,SPARK_NEG_OK,1.138211,1.138162,1.137719,1.137768,SOFT_START,738,67,SPARK_NEG_OK,1.138083,1.137950,1.137990,1.138940,SOFT_START,1250,2383,0 +211578897,739,70,SPARK_NEG_OK,1.138220,1.138145,1.137765,1.137730,SOFT_START,739,70,SPARK_NEG_OK,1.138057,1.137959,1.138009,1.138917,SOFT_START,1251,2376,0 +211626897,740,70,SPARK_NEG_OK,1.138227,1.138154,1.137730,1.137791,SOFT_START,740,70,SPARK_NEG_OK,1.138057,1.137968,1.137996,1.139023,SOFT_START,1249,2392,0 +211674897,741,70,SPARK_NEG_OK,1.138252,1.138147,1.137752,1.137821,SOFT_START,741,71,SPARK_NEG_OK,1.138051,1.137983,1.138033,1.138769,SOFT_START,1250,2388,0 +211722897,742,69,SPARK_NEG_OK,1.138198,1.138179,1.137787,1.137830,SOFT_START,742,67,SPARK_NEG_OK,1.138079,1.137997,1.138012,1.138998,SOFT_START,1249,2402,0 +211770897,743,70,SPARK_NEG_OK,1.138225,1.138172,1.137791,1.137828,SOFT_START,743,71,SPARK_NEG_OK,1.138089,1.137985,1.138058,1.139023,SOFT_START,1250,2382,0 +211818897,744,71,SPARK_NEG_OK,1.138244,1.138158,1.137771,1.137835,SOFT_START,744,70,SPARK_NEG_OK,1.138102,1.138019,1.138072,1.139014,SOFT_START,1249,2387,0 +211866897,745,70,SPARK_NEG_OK,1.138276,1.138204,1.137782,1.137824,SOFT_START,745,71,SPARK_NEG_OK,1.138067,1.138024,1.138080,1.139066,SOFT_START,1251,2401,0 +211914897,746,70,SPARK_NEG_OK,1.138249,1.138198,1.137795,1.137868,SOFT_START,746,70,SPARK_NEG_OK,1.138113,1.138045,1.138071,1.139055,SOFT_START,1251,2405,0 +211962897,747,70,SPARK_NEG_OK,1.138272,1.138200,1.137807,1.137894,SOFT_START,747,71,SPARK_NEG_OK,1.138088,1.138040,1.138110,1.139042,SOFT_START,1252,2385,0 +212010897,748,70,SPARK_NEG_OK,1.138278,1.138203,1.137821,1.137896,SOFT_START,748,70,SPARK_NEG_OK,1.138071,1.138080,1.138109,1.138993,SOFT_START,1251,2384,0 +212058897,749,70,SPARK_NEG_OK,1.138303,1.138232,1.137800,1.137891,SOFT_START,749,71,SPARK_NEG_OK,1.138113,1.138065,1.138104,1.138943,SOFT_START,1252,2398,0 +212105901,750,70,SPARK_NEG_OK,1.138300,1.138235,1.137834,1.137903,SOFT_START,750,70,SPARK_NEG_OK,1.138152,1.138082,1.138091,1.138951,SOFT_START,1253,2407,0 +212153897,751,70,SPARK_NEG_OK,1.138335,1.138216,1.137862,1.137893,SOFT_START,751,71,SPARK_NEG_OK,1.138098,1.138100,1.138108,1.138986,SOFT_START,1250,2380,0 +212201897,752,70,SPARK_NEG_OK,1.138334,1.138244,1.137835,1.137930,SOFT_START,752,70,SPARK_NEG_OK,1.138149,1.138077,1.138115,1.138865,SOFT_START,1252,2395,0 +212249897,753,71,SPARK_NEG_OK,1.138324,1.138262,1.137785,1.137929,SOFT_START,753,71,SPARK_NEG_OK,1.138080,1.138062,1.138220,1.139033,SOFT_START,1250,2383,0 +212297897,754,70,SPARK_NEG_OK,1.138334,1.138273,1.137887,1.137937,SOFT_START,754,70,SPARK_NEG_OK,1.138138,1.138076,1.138165,1.138825,SOFT_START,1251,2406,0 +212345897,755,70,SPARK_NEG_OK,1.138358,1.138275,1.137871,1.137906,SOFT_START,755,71,SPARK_NEG_OK,1.138119,1.138117,1.138132,1.139039,SOFT_START,1251,2401,0 +212393897,756,70,SPARK_NEG_OK,1.138328,1.138268,1.137897,1.137944,SOFT_START,756,70,SPARK_NEG_OK,1.138145,1.138114,1.138170,1.139033,SOFT_START,1252,2394,0 +212441897,757,70,SPARK_NEG_OK,1.138311,1.138281,1.137884,1.137955,SOFT_START,757,71,SPARK_NEG_OK,1.138170,1.138145,1.138166,1.139054,SOFT_START,1251,2398,0 +212489897,758,71,SPARK_NEG_OK,1.138322,1.138261,1.137891,1.137973,SOFT_START,758,70,SPARK_NEG_OK,1.138126,1.138099,1.138163,1.138975,SOFT_START,1254,2385,0 +212537897,759,70,SPARK_NEG_OK,1.138352,1.138296,1.137900,1.137995,SOFT_START,759,71,SPARK_NEG_OK,1.138163,1.138120,1.138195,1.139035,SOFT_START,1252,2389,0 +212585897,760,70,SPARK_NEG_OK,1.138368,1.138262,1.137908,1.138051,SOFT_START,760,70,SPARK_NEG_OK,1.138172,1.138127,1.138158,1.139053,SOFT_START,1254,2410,0 +212633897,761,70,SPARK_NEG_OK,1.138395,1.138263,1.137933,1.137996,SOFT_START,761,71,SPARK_NEG_OK,1.138169,1.138124,1.138185,1.139020,SOFT_START,1251,2400,0 +212680897,762,70,SPARK_NEG_OK,1.138372,1.138293,1.137924,1.137992,SOFT_START,762,70,SPARK_NEG_OK,1.138122,1.138132,1.138182,1.139024,SOFT_START,1252,2408,0 +212728897,763,70,SPARK_NEG_OK,1.138381,1.138294,1.137922,1.138018,SOFT_START,763,70,SPARK_NEG_OK,1.138168,1.138127,1.138197,1.138944,SOFT_START,1251,2388,0 +212776897,764,70,SPARK_NEG_OK,1.138382,1.138298,1.137940,1.138020,SOFT_START,764,70,SPARK_NEG_OK,1.138219,1.138154,1.138232,1.139016,SOFT_START,1250,2409,0 +212824897,765,70,SPARK_NEG_OK,1.138403,1.138309,1.137928,1.138024,SOFT_START,765,71,SPARK_NEG_OK,1.138146,1.138127,1.138215,1.138958,SOFT_START,1251,2389,0 +212872897,766,70,SPARK_NEG_OK,1.138396,1.138304,1.137938,1.138067,SOFT_START,766,70,SPARK_NEG_OK,1.138192,1.138150,1.138200,1.139035,SOFT_START,1250,2397,0 +212920897,767,70,SPARK_NEG_OK,1.138405,1.138303,1.137975,1.138058,SOFT_START,767,71,SPARK_NEG_OK,1.138178,1.138164,1.138215,1.138743,SOFT_START,1251,2384,0 +212968897,768,70,SPARK_NEG_OK,1.138398,1.138332,1.137937,1.138052,SOFT_START,768,70,SPARK_NEG_OK,1.138191,1.138152,1.138211,1.139006,SOFT_START,1252,2385,0 +213016897,769,70,SPARK_NEG_OK,1.138415,1.138344,1.137995,1.138049,SOFT_START,769,71,SPARK_NEG_OK,1.138185,1.138163,1.138201,1.139008,SOFT_START,1253,2385,0 +213064897,770,70,SPARK_NEG_OK,1.138393,1.138344,1.138009,1.138029,SOFT_START,770,70,SPARK_NEG_OK,1.138173,1.138194,1.138180,1.139050,SOFT_START,1252,2403,0 +213112897,771,70,SPARK_NEG_OK,1.138391,1.138341,1.137991,1.138070,SOFT_START,771,71,SPARK_NEG_OK,1.138182,1.138166,1.138241,1.139045,SOFT_START,1253,2403,0 +213160897,772,70,SPARK_NEG_OK,1.138342,1.138349,1.138004,1.138089,SOFT_START,772,70,SPARK_NEG_OK,1.138202,1.138191,1.138259,1.139045,SOFT_START,1251,2394,0 +213208897,773,70,SPARK_NEG_OK,1.138428,1.138371,1.137958,1.138074,SOFT_START,773,71,SPARK_NEG_OK,1.138228,1.138192,1.138249,1.139044,SOFT_START,1251,2401,0 +213256897,774,71,SPARK_NEG_OK,1.138425,1.138361,1.138018,1.138079,SOFT_START,774,70,SPARK_NEG_OK,1.138206,1.138217,1.138265,1.139022,SOFT_START,1250,2385,0 +213304897,775,70,SPARK_NEG_OK,1.138386,1.138420,1.138002,1.138036,SOFT_START,775,71,SPARK_NEG_OK,1.138225,1.138148,1.138297,1.139051,SOFT_START,1250,2386,0 +213352897,776,70,SPARK_NEG_OK,1.138456,1.138390,1.137986,1.138085,SOFT_START,776,70,SPARK_NEG_OK,1.138209,1.138197,1.138290,1.138976,SOFT_START,1251,2381,0 +213400897,777,70,SPARK_NEG_OK,1.138428,1.138401,1.138026,1.138081,SOFT_START,777,71,SPARK_NEG_OK,1.138187,1.138217,1.138275,1.139073,SOFT_START,1250,2400,0 +213448897,778,70,SPARK_NEG_OK,1.138452,1.138402,1.138032,1.138088,SOFT_START,778,70,SPARK_NEG_OK,1.138163,1.138203,1.138282,1.138884,SOFT_START,1251,2406,0 +213495897,779,70,SPARK_NEG_OK,1.138428,1.138403,1.138020,1.138105,SOFT_START,779,71,SPARK_NEG_OK,1.138228,1.138189,1.138291,1.139023,SOFT_START,1251,2381,0 +213543897,780,70,SPARK_NEG_OK,1.138448,1.138382,1.138065,1.138100,SOFT_START,780,70,SPARK_NEG_OK,1.138238,1.138213,1.138292,1.138755,SOFT_START,1253,2412,0 +213591897,781,70,SPARK_NEG_OK,1.138423,1.138395,1.138057,1.138120,SOFT_START,781,71,SPARK_NEG_OK,1.138223,1.138205,1.138307,1.139048,SOFT_START,1251,2393,0 +213639897,782,71,SPARK_NEG_OK,1.138446,1.138397,1.138073,1.138099,SOFT_START,782,70,SPARK_NEG_OK,1.138188,1.138216,1.138323,1.139057,SOFT_START,1253,2407,0 +213687897,783,72,SPARK_NEG_OK,1.138451,1.138409,1.138069,1.138136,SOFT_START,783,71,SPARK_NEG_OK,1.138234,1.138239,1.138324,1.139079,SOFT_START,1250,2377,0 +213735897,784,71,SPARK_NEG_OK,1.138471,1.138388,1.138074,1.138095,SOFT_START,784,70,SPARK_NEG_OK,1.138217,1.138256,1.138316,1.139051,SOFT_START,1251,2398,0 +213783897,785,70,SPARK_NEG_OK,1.138414,1.138446,1.138042,1.138093,SOFT_START,785,71,SPARK_NEG_OK,1.138267,1.138250,1.138312,1.138973,SOFT_START,1249,2408,0 +213831897,786,71,SPARK_NEG_OK,1.138427,1.138439,1.138047,1.138116,SOFT_START,786,70,SPARK_NEG_OK,1.138250,1.138248,1.138345,1.139036,SOFT_START,1250,2403,0 +213879897,787,70,SPARK_NEG_OK,1.138458,1.138443,1.138033,1.138148,SOFT_START,787,73,SPARK_NEG_OK,1.138244,1.138253,1.138349,1.139001,SOFT_START,1248,2398,0 +213927897,788,71,SPARK_NEG_OK,1.138447,1.138411,1.138048,1.138149,SOFT_START,788,70,SPARK_NEG_OK,1.138240,1.138247,1.138395,1.139035,SOFT_START,1250,2380,0 +213975897,789,70,SPARK_NEG_OK,1.138427,1.138411,1.138066,1.138158,SOFT_START,789,71,SPARK_NEG_OK,1.138246,1.138246,1.138328,1.139023,SOFT_START,1250,2407,0 +214023897,790,70,SPARK_NEG_OK,1.138447,1.138439,1.138089,1.138154,SOFT_START,790,70,SPARK_NEG_OK,1.138283,1.138240,1.138356,1.139094,SOFT_START,1250,2382,0 +214071897,791,70,SPARK_NEG_OK,1.138467,1.138428,1.138092,1.138182,SOFT_START,791,71,SPARK_NEG_OK,1.138228,1.138306,1.138362,1.139122,SOFT_START,1251,2382,0 +214119897,792,71,SPARK_NEG_OK,1.138449,1.138431,1.138101,1.138186,SOFT_START,792,70,SPARK_NEG_OK,1.138307,1.138330,1.138378,1.139101,SOFT_START,1251,2404,0 +214167897,793,70,SPARK_NEG_OK,1.138552,1.138453,1.138151,1.138173,SOFT_START,793,70,SPARK_NEG_OK,1.138274,1.138269,1.138341,1.138859,SOFT_START,1252,2391,0 +214215897,794,71,SPARK_NEG_OK,1.138480,1.138455,1.138086,1.138193,SOFT_START,794,70,SPARK_NEG_OK,1.138254,1.138270,1.138371,1.139011,SOFT_START,1249,2391,0 +214263897,795,70,SPARK_NEG_OK,1.138474,1.138450,1.138149,1.138179,SOFT_START,795,71,SPARK_NEG_OK,1.138239,1.138273,1.138381,1.139054,SOFT_START,1250,2391,0 +214311897,796,71,SPARK_NEG_OK,1.138446,1.138428,1.138096,1.138195,SOFT_START,796,70,SPARK_NEG_OK,1.138242,1.138265,1.138371,1.139048,SOFT_START,1249,2402,0 +214359897,797,70,SPARK_NEG_OK,1.138456,1.138474,1.138082,1.138171,SOFT_START,797,71,SPARK_NEG_OK,1.138275,1.138265,1.138336,1.139057,SOFT_START,1249,2396,0 +214407897,798,71,SPARK_NEG_OK,1.138477,1.138422,1.138150,1.138211,SOFT_START,798,70,SPARK_NEG_OK,1.138242,1.138308,1.138430,1.139064,SOFT_START,1248,2393,0 +214455897,799,70,SPARK_NEG_OK,1.138467,1.138456,1.138117,1.138208,SOFT_START,799,71,SPARK_NEG_OK,1.138306,1.138263,1.138409,1.139035,SOFT_START,1250,2407,0 +214503897,800,71,SPARK_NEG_OK,1.138468,1.138417,1.138114,1.138202,SOFT_START,800,70,SPARK_NEG_OK,1.138266,1.138245,1.138414,1.139016,SOFT_START,1249,2398,0 +214551897,801,70,SPARK_NEG_OK,1.138483,1.138476,1.138146,1.138198,SOFT_START,801,71,SPARK_NEG_OK,1.138288,1.138328,1.138394,1.139047,SOFT_START,1252,2405,0 +214599897,802,71,SPARK_NEG_OK,1.138486,1.138464,1.138102,1.138209,SOFT_START,802,70,SPARK_NEG_OK,1.138279,1.138242,1.138398,1.139002,SOFT_START,1252,2406,0 +214647897,803,70,SPARK_NEG_OK,1.138459,1.138501,1.138144,1.138201,SOFT_START,803,71,SPARK_NEG_OK,1.138278,1.138291,1.138401,1.138992,SOFT_START,1251,2399,0 +214695897,804,71,SPARK_NEG_OK,1.138479,1.138467,1.138116,1.138197,SOFT_START,804,70,SPARK_NEG_OK,1.138301,1.138332,1.138430,1.138932,SOFT_START,1252,2390,0 +214743897,805,70,SPARK_NEG_OK,1.138486,1.138425,1.138162,1.138229,SOFT_START,805,71,SPARK_NEG_OK,1.138298,1.138256,1.138420,1.139050,SOFT_START,1250,2378,0 +214791897,806,71,SPARK_NEG_OK,1.138501,1.138467,1.138133,1.138153,SOFT_START,806,70,SPARK_NEG_OK,1.138309,1.138292,1.138414,1.138875,SOFT_START,1251,2384,0 +214839897,807,70,SPARK_NEG_OK,1.138507,1.138448,1.138161,1.138209,SOFT_START,807,71,SPARK_NEG_OK,1.138198,1.138241,1.138430,1.139084,SOFT_START,1248,2379,0 +214887897,808,70,SPARK_NEG_OK,1.138470,1.138480,1.138146,1.138220,SOFT_START,808,70,SPARK_NEG_OK,1.138322,1.138297,1.138424,1.139072,SOFT_START,1250,2406,0 +214935897,809,70,SPARK_NEG_OK,1.138491,1.138465,1.138143,1.138226,SOFT_START,809,71,SPARK_NEG_OK,1.138254,1.138277,1.138397,1.139054,SOFT_START,1248,2383,0 +214983897,810,71,SPARK_NEG_OK,1.138481,1.138449,1.138163,1.138223,SOFT_START,810,70,SPARK_NEG_OK,1.138306,1.138301,1.138436,1.139079,SOFT_START,1250,2411,0 +215031897,811,70,SPARK_NEG_OK,1.138518,1.138470,1.138156,1.138200,SOFT_START,811,71,SPARK_NEG_OK,1.138248,1.138315,1.138418,1.139088,SOFT_START,1249,2394,0 +215079897,812,70,SPARK_NEG_OK,1.138515,1.138473,1.138163,1.138228,SOFT_START,812,70,SPARK_NEG_OK,1.138258,1.138291,1.138429,1.139048,SOFT_START,1251,2395,0 +215127897,813,69,SPARK_NEG_OK,1.138512,1.138452,1.138198,1.138222,SOFT_START,813,71,SPARK_NEG_OK,1.138250,1.138309,1.138430,1.139001,SOFT_START,1249,2399,0 +215175897,814,70,SPARK_NEG_OK,1.138524,1.138493,1.138192,1.138233,SOFT_START,814,70,SPARK_NEG_OK,1.138266,1.138299,1.138408,1.139073,SOFT_START,1251,2392,0 +215223897,815,71,SPARK_NEG_OK,1.138552,1.138468,1.138200,1.138255,SOFT_START,815,71,SPARK_NEG_OK,1.138245,1.138306,1.138424,1.138976,SOFT_START,1251,2382,0 +215270900,816,71,SPARK_NEG_OK,1.138565,1.138468,1.138196,1.138242,SOFT_START,816,70,SPARK_NEG_OK,1.138309,1.138321,1.138430,1.139065,SOFT_START,1249,2381,0 +215319897,817,70,SPARK_NEG_OK,1.138528,1.138504,1.138189,1.138284,SOFT_START,817,71,SPARK_NEG_OK,1.138285,1.138337,1.138492,1.138961,SOFT_START,1250,2402,0 +215367897,818,70,SPARK_NEG_OK,1.138511,1.138494,1.138194,1.138268,SOFT_START,818,70,SPARK_NEG_OK,1.138259,1.138306,1.138455,1.139041,SOFT_START,1248,2409,0 +215415897,819,70,SPARK_NEG_OK,1.138490,1.138517,1.138215,1.138276,SOFT_START,819,81,SPARK_NEG_OK,1.138259,1.138287,1.138430,1.138900,SOFT_START,1249,2399,0 +215463897,820,80,SPARK_NEG_OK,1.138518,1.138476,1.138185,1.138240,SOFT_START,820,80,SPARK_NEG_OK,1.138217,1.138318,1.138436,1.139259,SOFT_START,1248,2393,0 +215511897,821,80,SPARK_NEG_OK,1.138481,1.138518,1.138205,1.138226,SOFT_START,821,81,SPARK_NEG_OK,1.138195,1.138300,1.138445,1.139256,SOFT_START,1249,2387,0 +215559897,822,70,SPARK_NEG_OK,1.138484,1.138480,1.138192,1.138263,SOFT_START,822,70,SPARK_NEG_OK,1.138259,1.138348,1.138447,1.139029,SOFT_START,1249,2401,0 +215607897,823,69,SPARK_NEG_OK,1.138505,1.138493,1.138193,1.138270,SOFT_START,823,71,SPARK_NEG_OK,1.138267,1.138299,1.138486,1.138973,SOFT_START,1251,2388,0 +215655897,824,70,SPARK_NEG_OK,1.138484,1.138511,1.138229,1.138265,SOFT_START,824,70,SPARK_NEG_OK,1.138248,1.138271,1.138461,1.139051,SOFT_START,1250,2400,0 +215702897,825,70,SPARK_NEG_OK,1.138524,1.138477,1.138238,1.138301,SOFT_START,825,71,SPARK_NEG_OK,1.138252,1.138344,1.138511,1.139089,SOFT_START,1252,2393,0 +215750897,826,71,SPARK_NEG_OK,1.138477,1.138499,1.138226,1.138278,SOFT_START,826,70,SPARK_NEG_OK,1.138259,1.138334,1.138464,1.138977,SOFT_START,1250,2397,0 +215798897,827,70,SPARK_NEG_OK,1.138552,1.138506,1.138250,1.138270,SOFT_START,827,71,SPARK_NEG_OK,1.138319,1.138334,1.138440,1.139089,SOFT_START,1251,2384,0 +215846897,828,70,SPARK_NEG_OK,1.138582,1.138483,1.138216,1.138285,SOFT_START,828,70,SPARK_NEG_OK,1.138330,1.138296,1.138458,1.139041,SOFT_START,1251,2392,0 +215894897,829,70,SPARK_NEG_OK,1.138521,1.138510,1.138206,1.138275,SOFT_START,829,71,SPARK_NEG_OK,1.138287,1.138381,1.138420,1.139037,SOFT_START,1248,2385,0 +215942897,830,70,SPARK_NEG_OK,1.138532,1.138511,1.138244,1.138247,SOFT_START,830,70,SPARK_NEG_OK,1.138295,1.138340,1.138440,1.138875,SOFT_START,1250,2386,0 +215990897,831,70,SPARK_NEG_OK,1.138490,1.138517,1.138223,1.138322,SOFT_START,831,71,SPARK_NEG_OK,1.138285,1.138335,1.138432,1.138997,SOFT_START,1247,2393,0 +216039897,832,70,SPARK_NEG_OK,1.138487,1.138530,1.138200,1.138294,SOFT_START,832,71,SPARK_NEG_OK,1.138273,1.138306,1.138449,1.138920,SOFT_START,1249,2386,0 +216086897,833,70,SPARK_NEG_OK,1.138521,1.138455,1.138199,1.138298,SOFT_START,833,71,SPARK_NEG_OK,1.138241,1.138312,1.138469,1.139084,SOFT_START,1249,2381,0 +216134897,834,70,SPARK_NEG_OK,1.138502,1.138512,1.138235,1.138312,SOFT_START,834,70,SPARK_NEG_OK,1.138263,1.138290,1.138486,1.139112,SOFT_START,1250,2382,0 +216182897,835,80,SPARK_NEG_OK,1.138532,1.138452,1.138203,1.138307,SOFT_START,835,81,SPARK_NEG_OK,1.138279,1.138321,1.138476,1.139079,SOFT_START,1250,2396,0 +216230897,836,80,SPARK_NEG_OK,1.138548,1.138516,1.138220,1.138309,SOFT_START,836,80,SPARK_NEG_OK,1.138315,1.138310,1.138442,1.139051,SOFT_START,1252,2403,0 +216278897,837,70,SPARK_NEG_OK,1.138517,1.138518,1.138211,1.138343,SOFT_START,837,71,SPARK_NEG_OK,1.138269,1.138303,1.138446,1.139132,SOFT_START,1250,2397,0 +216326897,838,68,SPARK_NEG_OK,1.138520,1.138499,1.138174,1.138355,SOFT_START,838,70,SPARK_NEG_OK,1.138278,1.138321,1.138489,1.139149,SOFT_START,1250,2398,0 +216374897,839,70,SPARK_NEG_OK,1.138527,1.138501,1.138227,1.138337,SOFT_START,839,71,SPARK_NEG_OK,1.138293,1.138291,1.138470,1.139072,SOFT_START,1248,2388,0 +216422897,840,70,SPARK_NEG_OK,1.138527,1.138489,1.138206,1.138326,SOFT_START,840,70,SPARK_NEG_OK,1.138273,1.138356,1.138478,1.139288,SOFT_START,1249,2395,0 +216471897,841,70,SPARK_NEG_OK,1.138546,1.138527,1.138250,1.138381,SOFT_START,841,71,SPARK_NEG_OK,1.138332,1.138349,1.138503,1.139151,SOFT_START,1249,2406,0 +216519897,842,70,SPARK_NEG_OK,1.138522,1.138514,1.138229,1.138400,SOFT_START,842,70,SPARK_NEG_OK,1.138301,1.138368,1.138527,1.139107,SOFT_START,1247,2400,0 +216567897,843,70,SPARK_NEG_OK,1.138535,1.138543,1.138236,1.138390,SOFT_START,843,70,SPARK_NEG_OK,1.138307,1.138346,1.138498,1.138964,SOFT_START,1248,2404,0 +216615897,844,70,SPARK_NEG_OK,1.138550,1.138555,1.138241,1.138369,SOFT_START,844,70,SPARK_NEG_OK,1.138328,1.138341,1.138508,1.139114,SOFT_START,1248,2412,0 +216663897,845,70,SPARK_NEG_OK,1.138542,1.138541,1.138265,1.138356,SOFT_START,845,70,SPARK_NEG_OK,1.138309,1.138325,1.138487,1.138971,SOFT_START,1249,2408,0 +216711897,846,70,SPARK_NEG_OK,1.138548,1.138501,1.138245,1.138341,SOFT_START,846,70,SPARK_NEG_OK,1.138300,1.138322,1.138474,1.139084,SOFT_START,1250,2396,0 +216759897,847,70,SPARK_NEG_OK,1.138493,1.138547,1.138240,1.138379,SOFT_START,847,71,SPARK_NEG_OK,1.138277,1.138295,1.138487,1.139060,SOFT_START,1251,2383,0 +216807897,848,70,SPARK_NEG_OK,1.138539,1.138554,1.138327,1.138390,SOFT_START,848,70,SPARK_NEG_OK,1.138270,1.138328,1.138485,1.139219,SOFT_START,1250,2401,0 +216855897,849,70,SPARK_NEG_OK,1.138560,1.138601,1.138268,1.138361,SOFT_START,849,71,SPARK_NEG_OK,1.138322,1.138334,1.138518,1.139304,SOFT_START,1250,2401,0 +216903897,850,70,SPARK_NEG_OK,1.138549,1.138557,1.138250,1.138391,SOFT_START,850,70,SPARK_NEG_OK,1.138330,1.138349,1.138527,1.139089,SOFT_START,1248,2392,0 +216951897,851,70,SPARK_NEG_OK,1.138607,1.138610,1.138299,1.138422,SOFT_START,851,71,SPARK_NEG_OK,1.138344,1.138320,1.138532,1.139114,SOFT_START,1249,2399,0 +216999897,852,68,SPARK_NEG_OK,1.138590,1.138583,1.138316,1.138387,SOFT_START,852,70,SPARK_NEG_OK,1.138328,1.138357,1.138518,1.139020,SOFT_START,1247,2403,0 +217047897,853,70,SPARK_NEG_OK,1.138565,1.138542,1.138294,1.138381,SOFT_START,853,71,SPARK_NEG_OK,1.138319,1.138338,1.138487,1.139031,SOFT_START,1248,2390,0 +217095897,854,70,SPARK_NEG_OK,1.138560,1.138588,1.138318,1.138377,SOFT_START,854,70,SPARK_NEG_OK,1.138297,1.138317,1.138487,1.138980,SOFT_START,1248,2404,0 +217143897,855,70,SPARK_NEG_OK,1.138568,1.138591,1.138288,1.138344,SOFT_START,855,71,SPARK_NEG_OK,1.138279,1.138338,1.138511,1.139027,SOFT_START,1248,2405,0 +217191897,856,69,SPARK_NEG_OK,1.138587,1.138564,1.138309,1.138394,SOFT_START,856,70,SPARK_NEG_OK,1.138339,1.138366,1.138506,1.138941,SOFT_START,1249,2409,0 +217239897,857,70,SPARK_NEG_OK,1.138549,1.138560,1.138278,1.138383,SOFT_START,857,71,SPARK_NEG_OK,1.138310,1.138363,1.138543,1.139092,SOFT_START,1250,2396,0 +217287897,858,70,SPARK_NEG_OK,1.138577,1.138525,1.138279,1.138408,SOFT_START,858,70,SPARK_NEG_OK,1.138337,1.138442,1.138528,1.139015,SOFT_START,1251,2398,0 +217335897,859,70,SPARK_NEG_OK,1.138548,1.138519,1.138304,1.138421,SOFT_START,859,71,SPARK_NEG_OK,1.138304,1.138350,1.138549,1.139295,SOFT_START,1250,2387,0 +217383897,860,70,SPARK_NEG_OK,1.138586,1.138577,1.138266,1.138399,SOFT_START,860,70,SPARK_NEG_OK,1.138324,1.138343,1.138542,1.139333,SOFT_START,1251,2408,0 +217431897,861,70,SPARK_NEG_OK,1.138586,1.138573,1.138324,1.138422,SOFT_START,861,71,SPARK_NEG_OK,1.138351,1.138338,1.138511,1.139140,SOFT_START,1249,2385,0 +217479897,862,70,SPARK_NEG_OK,1.138607,1.138555,1.138257,1.138417,SOFT_START,862,70,SPARK_NEG_OK,1.138318,1.138350,1.138532,1.139102,SOFT_START,1250,2413,0 +217527897,863,70,SPARK_NEG_OK,1.138586,1.138567,1.138321,1.138395,SOFT_START,863,71,SPARK_NEG_OK,1.138316,1.138328,1.138551,1.139092,SOFT_START,1248,2377,0 +217575897,864,70,SPARK_NEG_OK,1.138588,1.138548,1.138326,1.138450,SOFT_START,864,70,SPARK_NEG_OK,1.138288,1.138411,1.138558,1.139145,SOFT_START,1248,2404,0 +217623897,865,70,SPARK_NEG_OK,1.138580,1.138589,1.138295,1.138440,SOFT_START,865,71,SPARK_NEG_OK,1.138348,1.138396,1.138538,1.139111,SOFT_START,1248,2402,0 +217671897,866,70,SPARK_NEG_OK,1.138604,1.138605,1.138306,1.138406,SOFT_START,866,70,SPARK_NEG_OK,1.138321,1.138411,1.138599,1.139143,SOFT_START,1250,2382,0 +217719897,867,70,SPARK_NEG_OK,1.138617,1.138567,1.138355,1.138427,SOFT_START,867,71,SPARK_NEG_OK,1.138306,1.138415,1.138564,1.139084,SOFT_START,1250,2398,0 +217767897,868,70,SPARK_NEG_OK,1.138602,1.138534,1.138331,1.138430,SOFT_START,868,73,SPARK_NEG_OK,1.138302,1.138369,1.138538,1.139151,SOFT_START,1250,2383,0 +217815897,869,70,SPARK_NEG_OK,1.138623,1.138582,1.138336,1.138406,SOFT_START,869,71,SPARK_NEG_OK,1.138301,1.138471,1.138548,1.138996,SOFT_START,1251,2386,0 +217863897,870,70,SPARK_NEG_OK,1.138642,1.138554,1.138318,1.138428,SOFT_START,870,70,SPARK_NEG_OK,1.138318,1.138403,1.138542,1.139169,SOFT_START,1250,2411,0 +217911897,871,70,SPARK_NEG_OK,1.138672,1.138587,1.138328,1.138414,SOFT_START,871,69,SPARK_NEG_OK,1.138327,1.138440,1.138535,1.138997,SOFT_START,1251,2384,0 +217959897,872,70,SPARK_NEG_OK,1.138634,1.138582,1.138342,1.138425,SOFT_START,872,70,SPARK_NEG_OK,1.138257,1.138398,1.138561,1.139163,SOFT_START,1248,2412,0 +218007897,873,70,SPARK_NEG_OK,1.138611,1.138590,1.138345,1.138425,SOFT_START,873,71,SPARK_NEG_OK,1.138305,1.138422,1.138549,1.139166,SOFT_START,1249,2405,0 +218055897,874,70,SPARK_NEG_OK,1.138608,1.138617,1.138309,1.138455,SOFT_START,874,70,SPARK_NEG_OK,1.138326,1.138449,1.138542,1.139153,SOFT_START,1248,2411,0 +218103897,875,70,SPARK_NEG_OK,1.138639,1.138597,1.138353,1.138443,SOFT_START,875,71,SPARK_NEG_OK,1.138312,1.138433,1.138538,1.139192,SOFT_START,1248,2397,0 +218151897,876,70,SPARK_NEG_OK,1.138624,1.138604,1.138347,1.138433,SOFT_START,876,70,SPARK_NEG_OK,1.138306,1.138461,1.138561,1.139135,SOFT_START,1247,2388,0 +218199897,877,70,SPARK_NEG_OK,1.138622,1.138594,1.138381,1.138431,SOFT_START,877,71,SPARK_NEG_OK,1.138392,1.138459,1.138592,1.139425,SOFT_START,1249,2394,0 +218247897,878,70,SPARK_NEG_OK,1.138653,1.138602,1.138384,1.138423,SOFT_START,878,70,SPARK_NEG_OK,1.138366,1.138442,1.138563,1.139250,SOFT_START,1248,2379,0 +218295897,879,70,SPARK_NEG_OK,1.138637,1.138626,1.138394,1.138425,SOFT_START,879,71,SPARK_NEG_OK,1.138351,1.138458,1.138601,1.139175,SOFT_START,1250,2379,0 +218343897,880,70,SPARK_NEG_OK,1.138645,1.138624,1.138379,1.138467,SOFT_START,880,70,SPARK_NEG_OK,1.138366,1.138477,1.138600,1.139104,SOFT_START,1251,2397,0 +218391897,881,70,SPARK_NEG_OK,1.138657,1.138604,1.138365,1.138420,SOFT_START,881,71,SPARK_NEG_OK,1.138360,1.138473,1.138594,1.139125,SOFT_START,1249,2397,0 +218439897,882,70,SPARK_NEG_OK,1.138628,1.138623,1.138384,1.138427,SOFT_START,882,70,SPARK_NEG_OK,1.138400,1.138477,1.138602,1.139050,SOFT_START,1251,2385,0 +218487897,883,70,SPARK_NEG_OK,1.138652,1.138634,1.138394,1.138490,SOFT_START,883,71,SPARK_NEG_OK,1.138355,1.138552,1.138619,1.139155,SOFT_START,1248,2391,0 +218535897,884,70,SPARK_NEG_OK,1.138629,1.138613,1.138399,1.138437,SOFT_START,884,69,SPARK_NEG_OK,1.138358,1.138471,1.138608,1.138936,SOFT_START,1249,2399,0 +218583897,885,70,SPARK_NEG_OK,1.138610,1.138597,1.138387,1.138431,SOFT_START,885,73,SPARK_NEG_OK,1.138369,1.138508,1.138621,1.139168,SOFT_START,1245,2404,0 +218631897,886,70,SPARK_NEG_OK,1.138641,1.138602,1.138392,1.138493,SOFT_START,886,70,SPARK_NEG_OK,1.138371,1.138498,1.138634,1.139189,SOFT_START,1246,2381,0 +218680897,887,70,SPARK_NEG_OK,1.138602,1.138647,1.138378,1.138447,SOFT_START,887,71,SPARK_NEG_OK,1.138380,1.138490,1.138642,1.139162,SOFT_START,1245,2384,0 +218728897,888,70,SPARK_NEG_OK,1.138627,1.138601,1.138406,1.138457,SOFT_START,888,70,SPARK_NEG_OK,1.138391,1.138477,1.138616,1.139142,SOFT_START,1246,2405,0 +218776897,889,70,SPARK_NEG_OK,1.138642,1.138624,1.138432,1.138456,SOFT_START,889,70,SPARK_NEG_OK,1.138390,1.138476,1.138601,1.139123,SOFT_START,1245,2382,0 +218824897,890,70,SPARK_NEG_OK,1.138672,1.138610,1.138408,1.138479,SOFT_START,890,70,SPARK_NEG_OK,1.138347,1.138467,1.138620,1.139167,SOFT_START,1247,2411,0 +218872897,891,71,SPARK_NEG_OK,1.138641,1.138614,1.138403,1.138440,SOFT_START,891,70,SPARK_NEG_OK,1.138426,1.138508,1.138587,1.139138,SOFT_START,1245,2386,0 +218920897,892,70,SPARK_NEG_OK,1.138673,1.138636,1.138422,1.138453,SOFT_START,892,70,SPARK_NEG_OK,1.138434,1.138475,1.138613,1.139152,SOFT_START,1247,2414,0 +218969897,893,73,SPARK_NEG_OK,1.138662,1.138619,1.138402,1.138477,SOFT_START,893,70,SPARK_NEG_OK,1.138417,1.138515,1.138647,1.139086,SOFT_START,1247,2390,0 +219017897,894,70,SPARK_NEG_OK,1.138691,1.138607,1.138390,1.138450,SOFT_START,894,71,SPARK_NEG_OK,1.138358,1.138538,1.138587,1.139165,SOFT_START,1244,2398,0 +219065897,895,71,SPARK_NEG_OK,1.138647,1.138612,1.138396,1.138458,SOFT_START,895,70,SPARK_NEG_OK,1.138403,1.138467,1.138626,1.139022,SOFT_START,1245,2399,0 +219113897,896,70,SPARK_NEG_OK,1.138684,1.138647,1.138412,1.138424,SOFT_START,896,70,SPARK_NEG_OK,1.138400,1.138519,1.138634,1.139187,SOFT_START,1242,2387,0 +219162897,897,71,SPARK_NEG_OK,1.138642,1.138673,1.138410,1.138477,SOFT_START,897,70,SPARK_NEG_OK,1.138387,1.138532,1.138558,1.138885,SOFT_START,1243,2397,0 +219210897,898,70,SPARK_NEG_OK,1.138694,1.138656,1.138395,1.138443,SOFT_START,898,70,SPARK_NEG_OK,1.138403,1.138521,1.138630,1.139143,SOFT_START,1242,2410,0 +219258897,899,71,SPARK_NEG_OK,1.138663,1.138673,1.138411,1.138471,SOFT_START,899,70,SPARK_NEG_OK,1.138383,1.138541,1.138608,1.139140,SOFT_START,1243,2398,0 +219306897,900,70,SPARK_NEG_OK,1.138693,1.138663,1.138418,1.138428,SOFT_START,900,70,SPARK_NEG_OK,1.138430,1.138517,1.138645,1.139151,SOFT_START,1243,2408,0 +219354897,901,71,SPARK_NEG_OK,1.138690,1.138638,1.138396,1.138427,SOFT_START,901,70,SPARK_NEG_OK,1.138417,1.138504,1.138599,1.139144,SOFT_START,1244,2402,0 +219403897,902,80,SPARK_NEG_OK,1.138667,1.138660,1.138384,1.138483,SOFT_START,902,80,SPARK_NEG_OK,1.138473,1.138504,1.138635,1.139138,SOFT_START,1243,2389,0 +219451897,903,81,SPARK_NEG_OK,1.138726,1.138665,1.138471,1.138487,SOFT_START,903,80,SPARK_NEG_OK,1.138452,1.138522,1.138626,1.139170,SOFT_START,1245,2405,0 +219499897,904,70,SPARK_NEG_OK,1.138700,1.138678,1.138409,1.138476,SOFT_START,904,70,SPARK_NEG_OK,1.138496,1.138518,1.138644,1.139162,SOFT_START,1243,2384,0 +219547897,905,71,SPARK_NEG_OK,1.138695,1.138734,1.138450,1.138469,SOFT_START,905,70,SPARK_NEG_OK,1.138472,1.138521,1.138626,1.139174,SOFT_START,1243,2406,0 +219596897,906,70,SPARK_NEG_OK,1.138708,1.138728,1.138401,1.138480,SOFT_START,906,70,SPARK_NEG_OK,1.138439,1.138536,1.138636,1.139138,SOFT_START,1243,2402,0 +219644897,907,71,SPARK_NEG_OK,1.138728,1.138681,1.138412,1.138474,SOFT_START,907,70,SPARK_NEG_OK,1.138455,1.138493,1.138638,1.139159,SOFT_START,1240,2409,0 +219692897,908,70,SPARK_NEG_OK,1.138721,1.138668,1.138405,1.138470,SOFT_START,908,73,SPARK_NEG_OK,1.138459,1.138530,1.138620,1.139131,SOFT_START,1241,2397,0 +219741897,909,70,SPARK_NEG_OK,1.138727,1.138678,1.138438,1.138504,SOFT_START,909,71,SPARK_NEG_OK,1.138441,1.138532,1.138629,1.139200,SOFT_START,1240,2406,0 +219789897,910,70,SPARK_NEG_OK,1.138710,1.138663,1.138406,1.138470,SOFT_START,910,71,SPARK_NEG_OK,1.138486,1.138529,1.138630,1.138990,SOFT_START,1241,2384,0 +219837897,911,70,SPARK_NEG_OK,1.138743,1.138648,1.138436,1.138477,SOFT_START,911,70,SPARK_NEG_OK,1.138466,1.138487,1.138642,1.139210,SOFT_START,1241,2398,0 +219886897,912,70,SPARK_NEG_OK,1.138725,1.138688,1.138431,1.138484,SOFT_START,912,72,SPARK_NEG_OK,1.138453,1.138577,1.138648,1.139072,SOFT_START,1242,2394,0 +219934897,913,70,SPARK_NEG_OK,1.138715,1.138649,1.138395,1.138445,SOFT_START,913,70,SPARK_NEG_OK,1.138434,1.138469,1.138639,1.139132,SOFT_START,1241,2383,0 +219982897,914,70,SPARK_NEG_OK,1.138715,1.138665,1.138388,1.138463,SOFT_START,914,71,SPARK_NEG_OK,1.138423,1.138514,1.138570,1.139191,SOFT_START,1243,2403,0 +220031897,915,70,SPARK_NEG_OK,1.138723,1.138682,1.138421,1.138452,SOFT_START,915,70,SPARK_NEG_OK,1.138442,1.138572,1.138615,1.139210,SOFT_START,1241,2385,0 +220079897,916,70,SPARK_NEG_OK,1.138694,1.138664,1.138434,1.138448,SOFT_START,916,71,SPARK_NEG_OK,1.138440,1.138488,1.138620,1.139233,SOFT_START,1242,2407,0 +220127897,917,70,SPARK_NEG_OK,1.138734,1.138667,1.138445,1.138474,SOFT_START,917,70,SPARK_NEG_OK,1.138465,1.138519,1.138678,1.139187,SOFT_START,1239,2405,0 +220176897,918,70,SPARK_NEG_OK,1.138715,1.138663,1.138380,1.138499,SOFT_START,918,71,SPARK_NEG_OK,1.138488,1.138514,1.138673,1.139215,SOFT_START,1240,2385,0 +220224897,919,76,SPARK_NEG_OK,1.138730,1.138671,1.138433,1.138500,SOFT_START,919,70,SPARK_NEG_OK,1.138501,1.138561,1.138666,1.139113,SOFT_START,1238,2383,0 +220272896,920,70,SPARK_NEG_OK,1.138715,1.138648,1.138427,1.138495,SOFT_START,920,70,SPARK_NEG_OK,1.138480,1.138545,1.138686,1.139234,SOFT_START,1240,2396,0 +220321897,921,70,SPARK_NEG_OK,1.138718,1.138695,1.138424,1.138474,SOFT_START,921,70,SPARK_NEG_OK,1.138481,1.138502,1.138655,1.139151,SOFT_START,1240,2392,0 +220369897,922,71,SPARK_NEG_OK,1.138739,1.138659,1.138448,1.138504,SOFT_START,922,70,SPARK_NEG_OK,1.138498,1.138550,1.138651,1.139207,SOFT_START,1240,2399,0 +220418897,923,70,SPARK_NEG_OK,1.138737,1.138682,1.138443,1.138465,SOFT_START,923,70,SPARK_NEG_OK,1.138454,1.138571,1.138635,1.139098,SOFT_START,1241,2399,0 +220466897,924,71,SPARK_NEG_OK,1.138719,1.138707,1.138497,1.138504,SOFT_START,924,70,SPARK_NEG_OK,1.138495,1.138530,1.138682,1.139373,SOFT_START,1240,2392,0 +220514897,925,70,SPARK_NEG_OK,1.138741,1.138710,1.138463,1.138506,SOFT_START,925,70,SPARK_NEG_OK,1.138505,1.138539,1.138701,1.139042,SOFT_START,1242,2407,0 +220563897,926,71,SPARK_NEG_OK,1.138765,1.138703,1.138470,1.138495,SOFT_START,926,70,SPARK_NEG_OK,1.138495,1.138548,1.138691,1.139212,SOFT_START,1239,2407,0 +220611897,927,70,SPARK_NEG_OK,1.138759,1.138679,1.138473,1.138549,SOFT_START,927,70,SPARK_NEG_OK,1.138501,1.138553,1.138677,1.139235,SOFT_START,1240,2407,0 +220659897,928,71,SPARK_NEG_OK,1.138782,1.138693,1.138459,1.138471,SOFT_START,928,70,SPARK_NEG_OK,1.138487,1.138561,1.138661,1.139202,SOFT_START,1238,2399,0 +220708897,929,70,SPARK_NEG_OK,1.138685,1.138699,1.138495,1.138465,SOFT_START,929,70,SPARK_NEG_OK,1.138538,1.138575,1.138648,1.139215,SOFT_START,1239,2404,0 +220756897,930,71,SPARK_NEG_OK,1.138716,1.138688,1.138489,1.138510,SOFT_START,930,70,SPARK_NEG_OK,1.138470,1.138572,1.138648,1.139168,SOFT_START,1237,2396,0 +220805897,931,67,SPARK_NEG_OK,1.138732,1.138712,1.138481,1.138530,SOFT_START,931,71,SPARK_NEG_OK,1.138526,1.138597,1.138682,1.139260,SOFT_START,1238,2402,0 +220853897,932,70,SPARK_NEG_OK,1.138763,1.138694,1.138465,1.138509,SOFT_START,932,70,SPARK_NEG_OK,1.138540,1.138591,1.138651,1.139228,SOFT_START,1238,2387,0 +220902897,933,70,SPARK_NEG_OK,1.138775,1.138701,1.138453,1.138505,SOFT_START,933,71,SPARK_NEG_OK,1.138542,1.138608,1.138680,1.139384,SOFT_START,1240,2389,0 +220950897,934,69,SPARK_NEG_OK,1.138798,1.138686,1.138499,1.138535,SOFT_START,934,70,SPARK_NEG_OK,1.138515,1.138596,1.138704,1.139450,SOFT_START,1240,2381,0 +220998897,935,70,SPARK_NEG_OK,1.138781,1.138711,1.138491,1.138521,SOFT_START,935,70,SPARK_NEG_OK,1.138535,1.138591,1.138738,1.139210,SOFT_START,1239,2401,0 +221047897,936,70,SPARK_NEG_OK,1.138781,1.138735,1.138506,1.138545,SOFT_START,936,70,SPARK_NEG_OK,1.138547,1.138617,1.138716,1.139153,SOFT_START,1241,2386,0 +221095897,937,70,SPARK_NEG_OK,1.138791,1.138720,1.138507,1.138532,SOFT_START,937,71,SPARK_NEG_OK,1.138547,1.138669,1.138684,1.139240,SOFT_START,1238,2399,0 +221144897,938,70,SPARK_NEG_OK,1.138785,1.138762,1.138490,1.138516,SOFT_START,938,70,SPARK_NEG_OK,1.138545,1.138592,1.138685,1.139056,SOFT_START,1240,2401,0 +221192897,939,70,SPARK_NEG_OK,1.138803,1.138709,1.138518,1.138557,SOFT_START,939,71,SPARK_NEG_OK,1.138565,1.138603,1.138721,1.139246,SOFT_START,1237,2387,0 +221240897,940,70,SPARK_NEG_OK,1.138800,1.138734,1.138511,1.138530,SOFT_START,940,70,SPARK_NEG_OK,1.138546,1.138600,1.138703,1.138926,SOFT_START,1238,2381,0 +221289897,941,70,SPARK_NEG_OK,1.138788,1.138774,1.138521,1.138585,SOFT_START,941,70,SPARK_NEG_OK,1.138563,1.138574,1.138689,1.139204,SOFT_START,1236,2381,0 +221337897,942,70,SPARK_NEG_OK,1.138830,1.138751,1.138535,1.138561,SOFT_START,942,70,SPARK_NEG_OK,1.138546,1.138608,1.138725,1.139248,SOFT_START,1238,2383,0 +221386897,943,71,SPARK_NEG_OK,1.138820,1.138737,1.138547,1.138544,SOFT_START,943,70,SPARK_NEG_OK,1.138559,1.138645,1.138738,1.139249,SOFT_START,1237,2393,0 +221434897,944,70,SPARK_NEG_OK,1.138825,1.138796,1.138527,1.138588,SOFT_START,944,70,SPARK_NEG_OK,1.138582,1.138610,1.138727,1.139465,SOFT_START,1239,2386,0 +221483897,945,71,SPARK_NEG_OK,1.138806,1.138788,1.138517,1.138623,SOFT_START,945,70,SPARK_NEG_OK,1.138571,1.138602,1.138726,1.139297,SOFT_START,1238,2405,0 +221531897,946,70,SPARK_NEG_OK,1.138816,1.138747,1.138539,1.138577,SOFT_START,946,70,SPARK_NEG_OK,1.138563,1.138610,1.138747,1.139203,SOFT_START,1240,2404,0 +221579900,947,71,SPARK_NEG_OK,1.138776,1.138788,1.138563,1.138593,SOFT_START,947,70,SPARK_NEG_OK,1.138578,1.138632,1.138720,1.139211,SOFT_START,1238,2382,0 +221628897,948,70,SPARK_NEG_OK,1.138836,1.138794,1.138538,1.138551,SOFT_START,948,70,SPARK_NEG_OK,1.138592,1.138584,1.138733,1.139262,SOFT_START,1239,2404,0 +221676897,949,71,SPARK_NEG_OK,1.138831,1.138744,1.138527,1.138594,SOFT_START,949,70,SPARK_NEG_OK,1.138592,1.138608,1.138694,1.139244,SOFT_START,1239,2390,0 +221725897,950,70,SPARK_NEG_OK,1.138841,1.138745,1.138577,1.138580,SOFT_START,950,71,SPARK_NEG_OK,1.138584,1.138639,1.138732,1.139308,SOFT_START,1236,2391,0 +221773897,951,70,SPARK_NEG_OK,1.138803,1.138784,1.138544,1.138599,SOFT_START,951,70,SPARK_NEG_OK,1.138560,1.138605,1.138712,1.139237,SOFT_START,1237,2398,0 +221822897,952,67,SPARK_NEG_OK,1.138826,1.138778,1.138582,1.138611,SOFT_START,952,71,SPARK_NEG_OK,1.138581,1.138636,1.138760,1.139311,SOFT_START,1236,2411,0 +221870897,953,70,SPARK_NEG_OK,1.138809,1.138782,1.138555,1.138604,SOFT_START,953,70,SPARK_NEG_OK,1.138584,1.138626,1.138759,1.139137,SOFT_START,1237,2405,0 +221919897,954,70,SPARK_NEG_OK,1.138847,1.138759,1.138517,1.138604,SOFT_START,954,71,SPARK_NEG_OK,1.138621,1.138611,1.138723,1.139257,SOFT_START,1237,2379,0 +221967897,955,70,SPARK_NEG_OK,1.138815,1.138777,1.138562,1.138632,SOFT_START,955,80,SPARK_NEG_OK,1.138623,1.138625,1.138754,1.139073,SOFT_START,1239,2380,0 +222016897,956,80,SPARK_NEG_OK,1.138807,1.138755,1.138570,1.138625,SOFT_START,956,78,SPARK_NEG_OK,1.138563,1.138600,1.138769,1.139265,SOFT_START,1238,2393,0 +222064897,957,80,SPARK_NEG_OK,1.138812,1.138755,1.138597,1.138626,SOFT_START,957,80,SPARK_NEG_OK,1.138592,1.138649,1.138756,1.139272,SOFT_START,1240,2408,0 +222112897,958,70,SPARK_NEG_OK,1.138793,1.138753,1.138610,1.138633,SOFT_START,958,71,SPARK_NEG_OK,1.138590,1.138628,1.138749,1.139288,SOFT_START,1238,2394,0 +222161897,959,70,SPARK_NEG_OK,1.138840,1.138799,1.138552,1.138639,SOFT_START,959,70,SPARK_NEG_OK,1.138585,1.138557,1.138757,1.139279,SOFT_START,1239,2389,0 +222209897,960,70,SPARK_NEG_OK,1.138841,1.138772,1.138570,1.138614,SOFT_START,960,70,SPARK_NEG_OK,1.138585,1.138639,1.138766,1.139285,SOFT_START,1237,2405,0 +222258897,961,70,SPARK_NEG_OK,1.138833,1.138800,1.138585,1.138653,SOFT_START,961,70,SPARK_NEG_OK,1.138595,1.138622,1.138784,1.139384,SOFT_START,1238,2406,0 +222306897,962,71,SPARK_NEG_OK,1.138852,1.138758,1.138602,1.138672,SOFT_START,962,70,SPARK_NEG_OK,1.138633,1.138619,1.138763,1.139520,SOFT_START,1236,2403,0 +222355897,963,70,SPARK_NEG_OK,1.138843,1.138833,1.138565,1.138701,SOFT_START,963,70,SPARK_NEG_OK,1.138626,1.138626,1.138800,1.139292,SOFT_START,1237,2383,0 +222403897,964,71,SPARK_NEG_OK,1.138830,1.138762,1.138578,1.138647,SOFT_START,964,70,SPARK_NEG_OK,1.138619,1.138657,1.138798,1.139174,SOFT_START,1237,2401,0 +222452897,965,72,SPARK_NEG_OK,1.138903,1.138783,1.138594,1.138710,SOFT_START,965,70,SPARK_NEG_OK,1.138614,1.138672,1.138800,1.139312,SOFT_START,1237,2388,0 +222500897,966,71,SPARK_NEG_OK,1.138862,1.138792,1.138600,1.138672,SOFT_START,966,70,SPARK_NEG_OK,1.138620,1.138646,1.138802,1.139234,SOFT_START,1238,2400,0 +222549897,967,70,SPARK_NEG_OK,1.138904,1.138875,1.138622,1.138669,SOFT_START,967,70,SPARK_NEG_OK,1.138627,1.138691,1.138802,1.139306,SOFT_START,1239,2399,0 +222597897,968,71,SPARK_NEG_OK,1.138884,1.138830,1.138582,1.138691,SOFT_START,968,70,SPARK_NEG_OK,1.138622,1.138670,1.138780,1.139097,SOFT_START,1240,2393,0 +222645897,969,70,SPARK_NEG_OK,1.138865,1.138819,1.138597,1.138703,SOFT_START,969,71,SPARK_NEG_OK,1.138647,1.138665,1.138845,1.139318,SOFT_START,1239,2380,0 +222694897,970,70,SPARK_NEG_OK,1.138878,1.138823,1.138593,1.138674,SOFT_START,970,70,SPARK_NEG_OK,1.138612,1.138645,1.138784,1.139202,SOFT_START,1241,2384,0 +222742897,971,70,SPARK_NEG_OK,1.138830,1.138797,1.138572,1.138687,SOFT_START,971,71,SPARK_NEG_OK,1.138602,1.138667,1.138794,1.139299,SOFT_START,1239,2398,0 +222791897,972,70,SPARK_NEG_OK,1.138851,1.138797,1.138566,1.138682,SOFT_START,972,70,SPARK_NEG_OK,1.138632,1.138676,1.138814,1.139310,SOFT_START,1240,2385,0 +222839897,973,70,SPARK_NEG_OK,1.138866,1.138806,1.138585,1.138617,SOFT_START,973,71,SPARK_NEG_OK,1.138625,1.138655,1.138796,1.139300,SOFT_START,1239,2396,0 +222887897,974,70,SPARK_NEG_OK,1.138897,1.138807,1.138552,1.138721,SOFT_START,974,70,SPARK_NEG_OK,1.138619,1.138669,1.138784,1.139385,SOFT_START,1240,2397,0 +222936897,975,70,SPARK_NEG_OK,1.138884,1.138812,1.138592,1.138690,SOFT_START,975,71,SPARK_NEG_OK,1.138631,1.138670,1.138766,1.139302,SOFT_START,1240,2393,0 +222984897,976,70,SPARK_NEG_OK,1.138868,1.138822,1.138634,1.138695,SOFT_START,976,70,SPARK_NEG_OK,1.138658,1.138657,1.138794,1.139517,SOFT_START,1242,2403,0 +223032897,977,71,SPARK_NEG_OK,1.138901,1.138828,1.138607,1.138684,SOFT_START,977,71,SPARK_NEG_OK,1.138665,1.138663,1.138790,1.139341,SOFT_START,1242,2385,0 +223080897,978,70,SPARK_NEG_OK,1.138902,1.138812,1.138616,1.138704,SOFT_START,978,70,SPARK_NEG_OK,1.138665,1.138660,1.138778,1.139281,SOFT_START,1244,2379,0 +223129897,979,70,SPARK_NEG_OK,1.138884,1.138841,1.138542,1.138719,SOFT_START,979,73,SPARK_NEG_OK,1.138638,1.138677,1.138811,1.139278,SOFT_START,1244,2387,0 +223177897,980,70,SPARK_NEG_OK,1.138862,1.138856,1.138607,1.138679,SOFT_START,980,70,SPARK_NEG_OK,1.138656,1.138695,1.138780,1.139324,SOFT_START,1243,2417,0 +223225897,981,70,SPARK_NEG_OK,1.138876,1.138814,1.138586,1.138719,SOFT_START,981,80,SPARK_NEG_OK,1.138645,1.138687,1.138798,1.139123,SOFT_START,1244,2387,0 +223273897,982,80,SPARK_NEG_OK,1.138898,1.138846,1.138635,1.138726,SOFT_START,982,80,SPARK_NEG_OK,1.138624,1.138696,1.138837,1.139340,SOFT_START,1242,2388,0 +223322897,983,81,SPARK_NEG_OK,1.138914,1.138859,1.138597,1.138715,SOFT_START,983,70,SPARK_NEG_OK,1.138714,1.138678,1.138788,1.139118,SOFT_START,1243,2382,0 +223370897,984,70,SPARK_NEG_OK,1.138915,1.138847,1.138616,1.138738,SOFT_START,984,71,SPARK_NEG_OK,1.138674,1.138713,1.138816,1.139309,SOFT_START,1242,2382,0 +223418897,985,71,SPARK_NEG_OK,1.138903,1.138847,1.138608,1.138732,SOFT_START,985,70,SPARK_NEG_OK,1.138670,1.138697,1.138800,1.139299,SOFT_START,1243,2383,0 +223466897,986,70,SPARK_NEG_OK,1.138903,1.138867,1.138614,1.138725,SOFT_START,986,70,SPARK_NEG_OK,1.138655,1.138679,1.138816,1.139315,SOFT_START,1242,2393,0 +223515897,987,71,SPARK_NEG_OK,1.138933,1.138856,1.138626,1.138716,SOFT_START,987,70,SPARK_NEG_OK,1.138663,1.138709,1.138830,1.139382,SOFT_START,1244,2387,0 +223563897,988,70,SPARK_NEG_OK,1.138935,1.138870,1.138586,1.138726,SOFT_START,988,70,SPARK_NEG_OK,1.138689,1.138706,1.138839,1.139328,SOFT_START,1244,2392,0 +223611897,989,71,SPARK_NEG_OK,1.138937,1.138858,1.138626,1.138777,SOFT_START,989,70,SPARK_NEG_OK,1.138700,1.138722,1.138809,1.139390,SOFT_START,1246,2379,0 +223659897,990,70,SPARK_NEG_OK,1.138968,1.138861,1.138628,1.138763,SOFT_START,990,70,SPARK_NEG_OK,1.138660,1.138732,1.138847,1.139570,SOFT_START,1244,2395,0 +223707897,991,71,SPARK_NEG_OK,1.138954,1.138886,1.138666,1.138755,SOFT_START,991,70,SPARK_NEG_OK,1.138688,1.138717,1.138804,1.139407,SOFT_START,1245,2397,0 +223756897,992,70,SPARK_NEG_OK,1.138944,1.138866,1.138636,1.138788,SOFT_START,992,70,SPARK_NEG_OK,1.138676,1.138759,1.138830,1.139321,SOFT_START,1245,2383,0 +223804897,993,68,SPARK_NEG_OK,1.138946,1.138868,1.138659,1.138794,SOFT_START,993,70,SPARK_NEG_OK,1.138674,1.138731,1.138842,1.139379,SOFT_START,1242,2391,0 +223852897,994,70,SPARK_NEG_OK,1.138946,1.138850,1.138634,1.138771,SOFT_START,994,70,SPARK_NEG_OK,1.138694,1.138738,1.138844,1.139194,SOFT_START,1244,2404,0 +223900897,995,71,SPARK_NEG_OK,1.138949,1.138909,1.138604,1.138780,SOFT_START,995,70,SPARK_NEG_OK,1.138718,1.138716,1.138879,1.139388,SOFT_START,1242,2392,0 +223949897,996,70,SPARK_NEG_OK,1.138946,1.138915,1.138656,1.138787,SOFT_START,996,71,SPARK_NEG_OK,1.138709,1.138753,1.138822,1.139180,SOFT_START,1243,2382,0 +223997897,997,68,SPARK_NEG_OK,1.138949,1.138892,1.138663,1.138756,SOFT_START,997,70,SPARK_NEG_OK,1.138691,1.138743,1.138866,1.139335,SOFT_START,1243,2410,0 +224045897,998,70,SPARK_NEG_OK,1.138949,1.138883,1.138634,1.138793,SOFT_START,998,69,SPARK_NEG_OK,1.138707,1.138716,1.138836,1.139343,SOFT_START,1244,2403,0 +224093897,999,80,SPARK_NEG_OK,1.138917,1.138883,1.138647,1.138756,SOFT_START,999,80,SPARK_NEG_OK,1.138684,1.138726,1.138807,1.139317,SOFT_START,1244,2398,0 +224141897,1000,80,SPARK_NEG_OK,1.138939,1.138874,1.138588,1.138735,SOFT_START,1000,81,SPARK_NEG_OK,1.138645,1.138714,1.138837,1.139371,SOFT_START,1246,2385,0 +224190897,1001,70,SPARK_NEG_OK,1.138955,1.138870,1.138671,1.138775,SOFT_START,1001,70,SPARK_NEG_OK,1.138683,1.138736,1.138842,1.139333,SOFT_START,1245,2392,0 +224238897,1002,70,SPARK_NEG_OK,1.138917,1.138862,1.138651,1.138737,SOFT_START,1002,73,SPARK_NEG_OK,1.138679,1.138750,1.138825,1.139338,SOFT_START,1247,2390,0 +224286897,1003,70,SPARK_NEG_OK,1.138952,1.138886,1.138638,1.138759,SOFT_START,1003,70,SPARK_NEG_OK,1.138705,1.138757,1.138890,1.139334,SOFT_START,1244,2383,0 +224334897,1004,69,SPARK_NEG_OK,1.138941,1.138895,1.138652,1.138778,SOFT_START,1004,71,SPARK_NEG_OK,1.138698,1.138734,1.138830,1.139365,SOFT_START,1245,2404,0 +224382897,1005,70,SPARK_NEG_OK,1.138944,1.138875,1.138656,1.138818,SOFT_START,1005,70,SPARK_NEG_OK,1.138688,1.138743,1.138831,1.139299,SOFT_START,1245,2392,0 +224431897,1006,70,SPARK_NEG_OK,1.138985,1.138936,1.138653,1.138768,SOFT_START,1006,71,SPARK_NEG_OK,1.138737,1.138753,1.138809,1.139378,SOFT_START,1243,2389,0 +224479897,1007,70,SPARK_NEG_OK,1.138914,1.138886,1.138652,1.138788,SOFT_START,1007,68,SPARK_NEG_OK,1.138703,1.138780,1.138848,1.139292,SOFT_START,1244,2384,0 +224527897,1008,70,SPARK_NEG_OK,1.138924,1.138872,1.138663,1.138751,SOFT_START,1008,71,SPARK_NEG_OK,1.138696,1.138762,1.138840,1.139331,SOFT_START,1244,2383,0 +224575897,1009,71,SPARK_NEG_OK,1.138951,1.138893,1.138700,1.138775,SOFT_START,1009,70,SPARK_NEG_OK,1.138704,1.138714,1.138847,1.139207,SOFT_START,1245,2407,0 +224623897,1010,70,SPARK_NEG_OK,1.138962,1.138887,1.138644,1.138802,SOFT_START,1010,71,SPARK_NEG_OK,1.138706,1.138759,1.138844,1.139350,SOFT_START,1246,2387,0 +224671897,1011,70,SPARK_NEG_OK,1.138935,1.138905,1.138672,1.138784,SOFT_START,1011,71,SPARK_NEG_OK,1.138719,1.138740,1.138861,1.139166,SOFT_START,1247,2393,0 +224719897,1012,70,SPARK_NEG_OK,1.138909,1.138878,1.138669,1.138743,SOFT_START,1012,71,SPARK_NEG_OK,1.138687,1.138735,1.138897,1.139342,SOFT_START,1247,2395,0 +224767897,1013,70,SPARK_NEG_OK,1.138970,1.138876,1.138679,1.138750,SOFT_START,1013,70,SPARK_NEG_OK,1.138700,1.138729,1.138870,1.139369,SOFT_START,1248,2396,0 +224816897,1014,70,SPARK_NEG_OK,1.138975,1.138873,1.138675,1.138785,SOFT_START,1014,71,SPARK_NEG_OK,1.138699,1.138754,1.138854,1.139352,SOFT_START,1246,2386,0 +224864897,1015,70,SPARK_NEG_OK,1.138952,1.138886,1.138665,1.138803,SOFT_START,1015,70,SPARK_NEG_OK,1.138687,1.138715,1.138868,1.139390,SOFT_START,1246,2394,0 +224912897,1016,70,SPARK_NEG_OK,1.138920,1.138883,1.138670,1.138804,SOFT_START,1016,71,SPARK_NEG_OK,1.138706,1.138721,1.138867,1.139406,SOFT_START,1245,2394,0 +224960897,1017,71,SPARK_NEG_OK,1.138930,1.138887,1.138698,1.138773,SOFT_START,1017,70,SPARK_NEG_OK,1.138694,1.138741,1.138884,1.139380,SOFT_START,1246,2386,0 +225008897,1018,72,SPARK_NEG_OK,1.138961,1.138881,1.138669,1.138738,SOFT_START,1018,70,SPARK_NEG_OK,1.138717,1.138730,1.138901,1.139514,SOFT_START,1245,2409,0 +225056897,1019,70,SPARK_NEG_OK,1.138943,1.138933,1.138666,1.138755,SOFT_START,1019,70,SPARK_NEG_OK,1.138697,1.138756,1.138895,1.139596,SOFT_START,1246,2383,0 +225104897,1020,71,SPARK_NEG_OK,1.138999,1.138936,1.138720,1.138818,SOFT_START,1020,70,SPARK_NEG_OK,1.138699,1.138786,1.138910,1.139345,SOFT_START,1246,2380,0 +225153897,1021,70,SPARK_NEG_OK,1.138970,1.138912,1.138685,1.138822,SOFT_START,1021,70,SPARK_NEG_OK,1.138746,1.138774,1.138903,1.139404,SOFT_START,1247,2406,0 +225201897,1022,71,SPARK_NEG_OK,1.138975,1.138952,1.138692,1.138825,SOFT_START,1022,70,SPARK_NEG_OK,1.138728,1.138761,1.138909,1.139309,SOFT_START,1248,2405,0 +225249897,1023,70,SPARK_NEG_OK,1.138976,1.138929,1.138706,1.138787,SOFT_START,1023,70,SPARK_NEG_OK,1.138740,1.138774,1.138877,1.139427,SOFT_START,1247,2393,0 +225297897,1024,71,SPARK_NEG_OK,1.138995,1.138904,1.138741,1.138799,SOFT_START,1024,70,SPARK_NEG_OK,1.138749,1.138751,1.138943,1.139138,SOFT_START,1248,2399,0 +ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/RotaxMonitor/unpacked_fs/spiffs/ignA_history.bin b/RotaxMonitor/unpacked_fs/spiffs/ignA_history.bin deleted file mode 100644 index 343936602bb2e06345e2a6a643d4b205bc4c4b8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116966 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 t{9yu-FU#30>_m`B2=YH${ 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 Date: Tue, 7 Apr 2026 17:33:08 +0200 Subject: [PATCH 07/38] SPIFFS mount sometimes fail --- RotaxMonitor/.gitignore | 1 + RotaxMonitor/data/config.json | 4 +- RotaxMonitor/src/datasave.cpp | 16 +- RotaxMonitor/src/datasave.h | 15 +- RotaxMonitor/src/main.cpp | 38 +- RotaxMonitor/unpacked_fs/ignA_history.csv | 858 ---------------------- 6 files changed, 42 insertions(+), 890 deletions(-) delete mode 100644 RotaxMonitor/unpacked_fs/ignA_history.csv diff --git a/RotaxMonitor/.gitignore b/RotaxMonitor/.gitignore index 89cc49c..18aafbe 100644 --- a/RotaxMonitor/.gitignore +++ b/RotaxMonitor/.gitignore @@ -3,3 +3,4 @@ .vscode/c_cpp_properties.json .vscode/launch.json .vscode/ipch +unpacked_fs diff --git a/RotaxMonitor/data/config.json b/RotaxMonitor/data/config.json index 9e26dfe..544b7b4 100644 --- a/RotaxMonitor/data/config.json +++ b/RotaxMonitor/data/config.json @@ -1 +1,3 @@ -{} \ No newline at end of file +{ + +} \ No newline at end of file diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index 13d2564..ccf52bf 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -1,6 +1,7 @@ #include "datasave.h" -static constexpr size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB) +static const size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB) +static bool first_save = true; // flag to indicate if this is the first save (to write header) void save_history(const PSRAMVector &history, const std::filesystem::path &file_path) { @@ -25,11 +26,11 @@ void save_history(const PSRAMVector &history, const std::file to_save = std::filesystem::path("/spiffs") / file_path; auto save_flags = std::ios::out; - static bool first_save = true; - if (first_save || !SPIFFS.exists(to_save.c_str())) + if (first_save && SPIFFS.exists(to_save.c_str())) { - save_flags |= std::ios::trunc; // overwrite existing file first_save = false; + save_flags |= std::ios::trunc; // overwrite existing file + SPIFFS.remove(to_save.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS LOG_INFO("Saving history to SPIFFS, new file: ", to_save.c_str()); } else @@ -51,7 +52,8 @@ void save_history(const PSRAMVector &history, const std::file ofs << "TS,\ EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ - ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS"; + ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" << std::endl; + ofs.flush(); } for (const auto &entry : history) @@ -77,10 +79,10 @@ void save_history(const PSRAMVector &history, const std::file << std::to_string(entry.adc_read_time) << "," << std::to_string(entry.n_queue_errors); ofs << std::endl; + ofs.flush(); } - ofs.flush(); ofs.close(); LOG_INFO("Ignition A history saved to SPIFFS, records written: ", history.size()); SPIFFS.end(); // unmount SPIFFS to ensure data is written and avoid corruption on next mount -} \ No newline at end of file +} diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index 52cf403..109e3e0 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -12,12 +12,12 @@ #include "isr.h" #include "psvector.h" -const uint32_t max_history = 1024; +const uint32_t max_history = 256; const bool SAVE_HISTORY_TO_SPIFFS = true; // Set to true to enable saving history to SPIFFS, false to disable struct dataSaveParams { - PSRAMVector *history; + const PSRAMVector *history; const std::filesystem::path file_path; }; @@ -25,15 +25,14 @@ void save_history(const PSRAMVector &history, const std::file static void saveHistoryTask(void *pvParameters) { - auto *params = static_cast(pvParameters); - auto &history = *params->history; - auto &file_path = params->file_path; + const auto *params = static_cast(pvParameters); + const auto &history = *params->history; + const auto &file_path = params->file_path; if (!params) { LOG_ERROR("Invalid parameters for saveHistoryTask"); return; } - + LOG_INFO("Starting saving: ", file_path.c_str()); save_history(history, file_path); - history.reserve(max_history); // ensure writable buffer has the correct size - vTaskDelete(NULL); + //vTaskDelete(NULL); } diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 10c7cac..050146a 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -50,13 +50,12 @@ void loop() { // global variables bool running = true; - const uint32_t max_queue = 128; PSRAMVector ignA_history_0(max_history); PSRAMVector ignA_history_1(max_history); auto *active_history = &ignA_history_0; auto *writable_history = &ignA_history_1; - + // Resources Initialization static Devices dev; // Task handle @@ -100,7 +99,6 @@ void loop() .rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_B12P, .rst_io_12n = RST_EXT_B12N, .rst_io_34p = RST_EXT_B34P, .rst_io_34n = RST_EXT_B34N}}; #endif - // Spi ok flags bool spiA_ok = true; bool spiB_ok = true; @@ -184,30 +182,38 @@ void loop() while (running) { - if (counter >= active_history->size()) + if (counter >= active_history->size()) // not concurrent with write task { counter = 0; partial_save = false; // reset partial save flag on new data cycle - std::swap(active_history, writable_history); // switch active and writable buffers + auto *temp = active_history; + active_history = writable_history; // switch active and writable buffers + writable_history = temp; // ensure writable_history points to the buffer we just filled dataSaveParams save_params{ .history = writable_history, - .file_path = "ignition_history.csv" - }; - if (SAVE_HISTORY_TO_SPIFFS) - xTaskCreate( - saveHistoryTask, - "saveHistoryTask", - RT_TASK_STACK / 2, - &save_params, - RT_TASK_PRIORITY - 10, // higher priority to ensure it runs asap after buffer switch - NULL); + .file_path = "ignition_history.csv"}; + saveHistoryTask(&save_params); // directly call the save task function to save without delay, since we already switched buffers and writable_history is now empty and ready for new data + // if (SAVE_HISTORY_TO_SPIFFS) + // if (pdFAIL == + // xTaskCreatePinnedToCore( + // saveHistoryTask, + // "saveHistoryTask", + // RT_TASK_STACK, + // &save_params, + // RT_TASK_PRIORITY - 1, // higher priority to ensure it runs asap after buffer switch + // NULL, + // CORE_1)) + // { + // LOG_ERROR("Unable to create saveHistoryTask"); + // } } if (xQueueReceive(rt_taskA_queue, &ign_info, pdMS_TO_TICKS(1000)) == pdTRUE) { - printInfo(ign_info); + // printInfo(ign_info); auto &hist = *active_history; hist[counter++ % active_history->size()] = ign_info; + Serial.print("Data Received: " + String(counter) + "/" + String(hist.size()) + '\r'); } else { diff --git a/RotaxMonitor/unpacked_fs/ignA_history.csv b/RotaxMonitor/unpacked_fs/ignA_history.csv deleted file mode 100644 index 8566e14..0000000 --- a/RotaxMonitor/unpacked_fs/ignA_history.csv +++ /dev/null @@ -1,858 +0,0 @@ -6,1.158892,1.127349,1.126361,SOFT_START,168,71,SPARK_NEG_OK,1.126999,1.126893,1.127753,1.140731,SOFT_START,1262,2386,0 -184341897,169,69,SPARK_NEG_OK,1.158158,1.158448,1.127634,1.126717,SOFT_START,169,70,SPARK_NEG_OK,1.127301,1.127223,1.128051,1.140767,SOFT_START,1261,2405,0 -184389897,170,70,SPARK_NEG_OK,1.157709,1.157992,1.127911,1.127002,SOFT_START,170,68,SPARK_NEG_OK,1.127591,1.127506,1.128346,1.140777,SOFT_START,1264,2404,0 -184436897,171,70,SPARK_NEG_OK,1.157262,1.157583,1.128229,1.127315,SOFT_START,171,70,SPARK_NEG_OK,1.127875,1.127787,1.128626,1.140696,SOFT_START,1264,2399,0 -184484897,172,70,SPARK_NEG_OK,1.156892,1.157145,1.128529,1.127571,SOFT_START,172,71,SPARK_NEG_OK,1.128153,1.128111,1.128893,1.140749,SOFT_START,1263,2385,0 -184531897,173,70,SPARK_NEG_OK,1.156517,1.156719,1.128732,1.127865,SOFT_START,173,70,SPARK_NEG_OK,1.128455,1.128367,1.129126,1.140565,SOFT_START,1264,2380,0 -184579897,174,70,SPARK_NEG_OK,1.156120,1.156375,1.129014,1.128138,SOFT_START,174,70,SPARK_NEG_OK,1.128681,1.128639,1.129413,1.140733,SOFT_START,1262,2380,0 -184626897,175,71,SPARK_NEG_OK,1.155782,1.155964,1.129223,1.128410,SOFT_START,175,70,SPARK_NEG_OK,1.128941,1.128904,1.129636,1.140796,SOFT_START,1264,2381,0 -184674897,176,70,SPARK_NEG_OK,1.155373,1.155608,1.129481,1.128699,SOFT_START,176,72,SPARK_NEG_OK,1.129176,1.129144,1.129818,1.140771,SOFT_START,1262,2402,0 -184721897,177,71,SPARK_NEG_OK,1.154977,1.155200,1.129765,1.128957,SOFT_START,177,70,SPARK_NEG_OK,1.129455,1.129380,1.130080,1.140834,SOFT_START,1262,2379,0 -184769897,178,70,SPARK_NEG_OK,1.154684,1.154854,1.129964,1.129212,SOFT_START,178,70,SPARK_NEG_OK,1.129641,1.129627,1.130321,1.140804,SOFT_START,1261,2382,0 -184816897,179,71,SPARK_NEG_OK,1.154302,1.154438,1.130198,1.129506,SOFT_START,179,70,SPARK_NEG_OK,1.129878,1.129890,1.130555,1.140743,SOFT_START,1261,2405,0 -184864897,180,70,SPARK_NEG_OK,1.153993,1.154155,1.130427,1.129752,SOFT_START,180,70,SPARK_NEG_OK,1.130168,1.130088,1.130776,1.140695,SOFT_START,1261,2388,0 -184911897,181,71,SPARK_NEG_OK,1.153612,1.153803,1.130581,1.129934,SOFT_START,181,70,SPARK_NEG_OK,1.130362,1.130309,1.131000,1.140781,SOFT_START,1264,2388,0 -184959897,182,70,SPARK_NEG_OK,1.153310,1.153420,1.130870,1.130156,SOFT_START,182,70,SPARK_NEG_OK,1.130589,1.130573,1.131204,1.140671,SOFT_START,1264,2383,0 -185006897,183,70,SPARK_NEG_OK,1.153002,1.153169,1.131068,1.130346,SOFT_START,183,71,SPARK_NEG_OK,1.130778,1.130788,1.131430,1.140798,SOFT_START,1263,2403,0 -185054897,184,71,SPARK_NEG_OK,1.152678,1.152841,1.131254,1.130592,SOFT_START,184,68,SPARK_NEG_OK,1.131003,1.130990,1.131607,1.140681,SOFT_START,1264,2397,0 -185101897,185,70,SPARK_NEG_OK,1.152409,1.152545,1.131476,1.130779,SOFT_START,185,71,SPARK_NEG_OK,1.131200,1.131176,1.131827,1.140775,SOFT_START,1262,2398,0 -185149897,186,70,SPARK_NEG_OK,1.152096,1.152209,1.131658,1.130998,SOFT_START,186,69,SPARK_NEG_OK,1.131361,1.131336,1.132019,1.140593,SOFT_START,1264,2395,0 -185196897,187,70,SPARK_NEG_OK,1.151797,1.151918,1.131840,1.131188,SOFT_START,187,71,SPARK_NEG_OK,1.131609,1.131526,1.132186,1.140742,SOFT_START,1261,2389,0 -185244897,188,70,SPARK_NEG_OK,1.151529,1.151687,1.132007,1.131374,SOFT_START,188,70,SPARK_NEG_OK,1.131717,1.131786,1.132398,1.140748,SOFT_START,1263,2383,0 -185291897,189,70,SPARK_NEG_OK,1.151277,1.151378,1.132189,1.131579,SOFT_START,189,70,SPARK_NEG_OK,1.131982,1.131895,1.132557,1.140770,SOFT_START,1261,2388,0 -185339897,190,71,SPARK_NEG_OK,1.151009,1.151122,1.132369,1.131733,SOFT_START,190,70,SPARK_NEG_OK,1.132153,1.132103,1.132733,1.140745,SOFT_START,1262,2408,0 -185386897,191,70,SPARK_NEG_OK,1.150732,1.150857,1.132556,1.131938,SOFT_START,191,70,SPARK_NEG_OK,1.132309,1.132228,1.132839,1.140754,SOFT_START,1261,2406,0 -185434897,192,71,SPARK_NEG_OK,1.150472,1.150618,1.132696,1.132114,SOFT_START,192,70,SPARK_NEG_OK,1.132509,1.132457,1.133056,1.140756,SOFT_START,1263,2387,0 -185481897,193,70,SPARK_NEG_OK,1.150245,1.150371,1.132858,1.132306,SOFT_START,193,70,SPARK_NEG_OK,1.132713,1.132596,1.133170,1.140887,SOFT_START,1263,2391,0 -185529897,194,70,SPARK_NEG_OK,1.150005,1.150116,1.133036,1.132491,SOFT_START,194,70,SPARK_NEG_OK,1.132876,1.132798,1.133364,1.140847,SOFT_START,1264,2385,0 -185576897,195,70,SPARK_NEG_OK,1.149743,1.149899,1.133211,1.132619,SOFT_START,195,70,SPARK_NEG_OK,1.133001,1.132960,1.133552,1.140627,SOFT_START,1265,2385,0 -185624897,196,72,SPARK_NEG_OK,1.149547,1.149643,1.133342,1.132796,SOFT_START,196,71,SPARK_NEG_OK,1.133152,1.133107,1.133668,1.140708,SOFT_START,1264,2392,0 -185671897,197,70,SPARK_NEG_OK,1.149332,1.149414,1.133471,1.132975,SOFT_START,197,70,SPARK_NEG_OK,1.133358,1.133236,1.133819,1.140464,SOFT_START,1265,2411,0 -185719897,198,70,SPARK_NEG_OK,1.149096,1.149192,1.133621,1.133124,SOFT_START,198,71,SPARK_NEG_OK,1.133456,1.133426,1.134008,1.140715,SOFT_START,1261,2403,0 -185766897,199,70,SPARK_NEG_OK,1.148887,1.149018,1.133759,1.133286,SOFT_START,199,70,SPARK_NEG_OK,1.133550,1.133572,1.134113,1.140726,SOFT_START,1263,2398,0 -185814897,200,70,SPARK_NEG_OK,1.148686,1.148788,1.133918,1.133437,SOFT_START,200,71,SPARK_NEG_OK,1.133758,1.133692,1.134248,1.140733,SOFT_START,1261,2388,0 -185861897,201,70,SPARK_NEG_OK,1.148506,1.148576,1.134027,1.133577,SOFT_START,201,70,SPARK_NEG_OK,1.133902,1.133835,1.134381,1.140782,SOFT_START,1262,2397,0 -185909897,202,70,SPARK_NEG_OK,1.148284,1.148381,1.134209,1.133720,SOFT_START,202,71,SPARK_NEG_OK,1.134034,1.133974,1.134507,1.140788,SOFT_START,1261,2406,0 -185956897,203,71,SPARK_NEG_OK,1.148085,1.148207,1.134299,1.133856,SOFT_START,203,70,SPARK_NEG_OK,1.134121,1.134132,1.134626,1.140798,SOFT_START,1262,2400,0 -186004897,204,70,SPARK_NEG_OK,1.147912,1.148009,1.134418,1.133952,SOFT_START,204,70,SPARK_NEG_OK,1.134306,1.134219,1.134747,1.140752,SOFT_START,1263,2384,0 -186051897,205,71,SPARK_NEG_OK,1.147758,1.147838,1.134569,1.134104,SOFT_START,205,70,SPARK_NEG_OK,1.134400,1.134322,1.134853,1.140792,SOFT_START,1263,2392,0 -186099897,206,70,SPARK_NEG_OK,1.147557,1.147578,1.134689,1.134259,SOFT_START,206,70,SPARK_NEG_OK,1.134546,1.134517,1.134962,1.140752,SOFT_START,1265,2382,0 -186146897,207,71,SPARK_NEG_OK,1.147360,1.147425,1.134798,1.134400,SOFT_START,207,70,SPARK_NEG_OK,1.134619,1.134629,1.135068,1.140788,SOFT_START,1263,2390,0 -186194897,208,70,SPARK_NEG_OK,1.147206,1.147272,1.134887,1.134529,SOFT_START,208,70,SPARK_NEG_OK,1.134769,1.134724,1.135192,1.140577,SOFT_START,1265,2407,0 -186241897,209,71,SPARK_NEG_OK,1.147069,1.147093,1.135019,1.134653,SOFT_START,209,70,SPARK_NEG_OK,1.134878,1.134849,1.135309,1.140776,SOFT_START,1261,2401,0 -186289897,210,70,SPARK_NEG_OK,1.146875,1.146907,1.135117,1.134751,SOFT_START,210,70,SPARK_NEG_OK,1.134980,1.134974,1.135411,1.140729,SOFT_START,1263,2395,0 -186336897,211,70,SPARK_NEG_OK,1.146767,1.146819,1.135241,1.134853,SOFT_START,211,71,SPARK_NEG_OK,1.135086,1.135052,1.135511,1.140984,SOFT_START,1261,2386,0 -186384897,212,70,SPARK_NEG_OK,1.146604,1.146629,1.135346,1.134951,SOFT_START,212,70,SPARK_NEG_OK,1.135221,1.135214,1.135627,1.140739,SOFT_START,1262,2393,0 -186431897,213,70,SPARK_NEG_OK,1.146423,1.146501,1.135468,1.135070,SOFT_START,213,71,SPARK_NEG_OK,1.135320,1.135294,1.135706,1.140595,SOFT_START,1261,2403,0 -186479897,214,70,SPARK_NEG_OK,1.146299,1.146310,1.135559,1.135200,SOFT_START,214,70,SPARK_NEG_OK,1.135406,1.135374,1.135790,1.140648,SOFT_START,1263,2398,0 -186526897,215,69,SPARK_NEG_OK,1.146140,1.146215,1.135640,1.135277,SOFT_START,215,71,SPARK_NEG_OK,1.135512,1.135457,1.135911,1.140693,SOFT_START,1262,2388,0 -186574897,216,70,SPARK_NEG_OK,1.146044,1.146017,1.135722,1.135378,SOFT_START,216,70,SPARK_NEG_OK,1.135628,1.135572,1.135996,1.140716,SOFT_START,1265,2396,0 -186621897,217,70,SPARK_NEG_OK,1.145868,1.145893,1.135834,1.135549,SOFT_START,217,71,SPARK_NEG_OK,1.135663,1.135689,1.136095,1.140702,SOFT_START,1265,2409,0 -186669897,218,71,SPARK_NEG_OK,1.145768,1.145779,1.135929,1.135541,SOFT_START,218,70,SPARK_NEG_OK,1.135783,1.135786,1.136184,1.140776,SOFT_START,1263,2397,0 -186716897,219,70,SPARK_NEG_OK,1.145607,1.145645,1.136020,1.135672,SOFT_START,219,70,SPARK_NEG_OK,1.135885,1.135874,1.136253,1.140493,SOFT_START,1264,2404,0 -186764897,220,71,SPARK_NEG_OK,1.145490,1.145504,1.136116,1.135755,SOFT_START,220,70,SPARK_NEG_OK,1.135993,1.135982,1.136325,1.140779,SOFT_START,1261,2399,0 -186811897,221,70,SPARK_NEG_OK,1.145382,1.145386,1.136182,1.135828,SOFT_START,221,69,SPARK_NEG_OK,1.136033,1.136065,1.136438,1.140781,SOFT_START,1263,2392,0 -186859897,222,71,SPARK_NEG_OK,1.145250,1.145279,1.136251,1.135953,SOFT_START,222,72,SPARK_NEG_OK,1.136116,1.136131,1.136507,1.140998,SOFT_START,1261,2395,0 -186906897,223,70,SPARK_NEG_OK,1.145156,1.145163,1.136373,1.136032,SOFT_START,223,70,SPARK_NEG_OK,1.136228,1.136224,1.136552,1.140813,SOFT_START,1262,2384,0 -186954897,224,71,SPARK_NEG_OK,1.145039,1.145037,1.136417,1.136104,SOFT_START,224,70,SPARK_NEG_OK,1.136295,1.136322,1.136648,1.140755,SOFT_START,1261,2394,0 -187001897,225,70,SPARK_NEG_OK,1.144934,1.144922,1.136483,1.136158,SOFT_START,225,70,SPARK_NEG_OK,1.136373,1.136378,1.136700,1.140758,SOFT_START,1263,2390,0 -187049897,226,70,SPARK_NEG_OK,1.144872,1.144804,1.136569,1.136243,SOFT_START,226,68,SPARK_NEG_OK,1.136437,1.136467,1.136804,1.140947,SOFT_START,1262,2379,0 -187096897,227,70,SPARK_NEG_OK,1.144739,1.144745,1.136674,1.136328,SOFT_START,227,70,SPARK_NEG_OK,1.136522,1.136539,1.136872,1.140844,SOFT_START,1265,2387,0 -187144897,228,70,SPARK_NEG_OK,1.144628,1.144605,1.136727,1.136420,SOFT_START,228,71,SPARK_NEG_OK,1.136560,1.136622,1.136953,1.140733,SOFT_START,1265,2400,0 -187191897,229,70,SPARK_NEG_OK,1.144550,1.144496,1.136795,1.136510,SOFT_START,229,70,SPARK_NEG_OK,1.136668,1.136663,1.137003,1.140752,SOFT_START,1263,2388,0 -187239897,230,70,SPARK_NEG_OK,1.144437,1.144432,1.136830,1.136577,SOFT_START,230,71,SPARK_NEG_OK,1.136729,1.136767,1.137068,1.140632,SOFT_START,1264,2385,0 -187286897,231,70,SPARK_NEG_OK,1.144356,1.144350,1.136940,1.136685,SOFT_START,231,70,SPARK_NEG_OK,1.136803,1.136810,1.137175,1.140776,SOFT_START,1261,2393,0 -187334897,232,70,SPARK_NEG_OK,1.144264,1.144226,1.136986,1.136733,SOFT_START,232,69,SPARK_NEG_OK,1.136854,1.136868,1.137193,1.140608,SOFT_START,1262,2406,0 -187381897,233,71,SPARK_NEG_OK,1.144099,1.144120,1.137043,1.136743,SOFT_START,233,70,SPARK_NEG_OK,1.136906,1.136966,1.137272,1.140772,SOFT_START,1260,2394,0 -187429897,234,70,SPARK_NEG_OK,1.144049,1.143996,1.137094,1.136868,SOFT_START,234,70,SPARK_NEG_OK,1.136965,1.137027,1.137345,1.140746,SOFT_START,1262,2414,0 -187476897,235,71,SPARK_NEG_OK,1.143983,1.143996,1.120251,1.136963,SOFT_START,235,70,SPARK_NEG_OK,1.137028,1.137102,1.137386,1.140764,SOFT_START,1260,2385,0 -187524897,236,70,SPARK_NEG_OK,1.143846,1.143883,1.096806,1.136643,SOFT_START,236,70,SPARK_NEG_OK,1.137081,1.137113,1.137423,1.140757,SOFT_START,1262,2407,0 -187572897,237,71,SPARK_NEG_OK,1.143768,1.143805,1.070337,1.135372,SOFT_START,237,70,SPARK_NEG_OK,1.137131,1.137189,1.137480,1.140747,SOFT_START,1260,2396,0 -187619897,238,70,SPARK_NEG_OK,1.143745,1.143776,1.039791,1.129135,SOFT_START,238,70,SPARK_NEG_OK,1.137272,1.137301,1.137562,1.140734,SOFT_START,1262,2404,0 -187667897,239,70,SPARK_NEG_OK,1.143672,1.143671,1.008092,1.115076,SOFT_START,239,70,SPARK_NEG_OK,1.137304,1.137289,1.137605,1.140685,SOFT_START,1262,2395,0 -187714897,240,70,SPARK_NEG_OK,1.143569,1.143593,0.980268,1.099116,SOFT_START,240,70,SPARK_NEG_OK,1.137341,1.135566,1.137606,1.140727,SOFT_START,1261,2403,0 -187762897,241,70,SPARK_NEG_OK,1.143511,1.143554,0.953581,1.081454,SOFT_START,241,71,SPARK_NEG_OK,1.137413,1.130987,1.137647,1.140644,SOFT_START,1262,2406,0 -187809897,242,70,SPARK_NEG_OK,1.143422,1.143468,0.927338,1.062001,SOFT_START,242,70,SPARK_NEG_OK,1.137457,1.122334,1.137655,1.140615,SOFT_START,1260,2407,0 -187857897,243,70,SPARK_NEG_OK,1.143379,1.143412,0.903567,1.042058,SOFT_START,243,71,SPARK_NEG_OK,1.137521,1.112101,1.137741,1.140404,SOFT_START,1261,2405,0 -187905897,244,72,SPARK_NEG_OK,1.143281,1.143293,0.880494,1.013783,SOFT_START,244,70,SPARK_NEG_OK,1.137545,1.101102,1.137720,1.140631,SOFT_START,1259,2398,0 -187952897,245,70,SPARK_NEG_OK,1.143202,1.143193,0.860400,0.982646,SOFT_START,245,71,SPARK_NEG_OK,1.137577,1.090156,1.137699,1.140628,SOFT_START,1260,2392,0 -188000897,246,70,SPARK_NEG_OK,1.143173,1.143115,0.843756,0.953143,SOFT_START,246,70,SPARK_NEG_OK,1.137629,1.084144,1.137766,1.140650,SOFT_START,1259,2403,0 -188047897,247,70,SPARK_NEG_OK,1.143079,1.143020,0.835966,0.938045,SOFT_START,247,71,SPARK_NEG_OK,1.137651,1.085550,1.137752,1.140644,SOFT_START,1260,2396,0 -188095897,248,70,SPARK_NEG_OK,1.142969,1.142960,0.844243,0.943484,SOFT_START,248,70,SPARK_NEG_OK,1.137699,1.087011,1.137705,1.140645,SOFT_START,1260,2407,0 -188143897,249,70,SPARK_NEG_OK,1.142907,1.142849,0.852197,0.948761,SOFT_START,249,70,SPARK_NEG_OK,1.137729,1.088431,1.137778,1.140617,SOFT_START,1263,2407,0 -188190897,250,73,SPARK_NEG_OK,1.142826,1.142780,0.859877,0.953805,SOFT_START,250,70,SPARK_NEG_OK,1.136677,1.073985,1.137795,1.140592,SOFT_START,1261,2392,0 -188238897,251,70,SPARK_NEG_OK,1.142789,1.142347,0.860271,0.958759,SOFT_START,251,70,SPARK_NEG_OK,1.108766,1.030127,1.137731,1.140604,SOFT_START,1262,2399,0 -188285897,252,71,SPARK_NEG_OK,1.142671,1.134727,0.858706,0.963482,SOFT_START,252,70,SPARK_NEG_OK,1.078349,0.982358,1.137716,1.140530,SOFT_START,1262,2380,0 -188333897,253,70,SPARK_NEG_OK,1.142627,1.108004,0.856692,0.968112,SOFT_START,253,70,SPARK_NEG_OK,1.048051,0.938429,1.137709,1.140584,SOFT_START,1260,2400,0 -188380897,254,71,SPARK_NEG_OK,1.142588,1.053496,0.854957,0.972576,SOFT_START,254,70,SPARK_NEG_OK,1.018492,0.900981,1.137740,1.140455,SOFT_START,1262,2385,0 -188428897,255,71,SPARK_NEG_OK,1.142541,0.994486,0.851908,0.976958,SOFT_START,255,70,SPARK_NEG_OK,0.987433,0.866305,1.137760,1.140595,SOFT_START,1259,2394,0 -188475897,256,71,SPARK_NEG_OK,1.142513,0.967498,0.851087,0.981219,SOFT_START,256,70,SPARK_NEG_OK,0.959564,0.830488,1.137817,1.140580,SOFT_START,1261,2378,0 -188523897,257,70,SPARK_NEG_OK,1.142451,0.970832,0.857853,0.985299,SOFT_START,257,70,SPARK_NEG_OK,0.959603,0.815096,1.137829,1.140557,SOFT_START,1259,2391,0 -188571897,258,70,SPARK_NEG_OK,1.142374,0.975548,0.865321,0.989294,SOFT_START,258,71,SPARK_NEG_OK,0.964402,0.823892,1.137807,1.140571,SOFT_START,1260,2384,0 -188618897,259,70,SPARK_NEG_OK,1.142286,0.980019,0.872535,0.993165,SOFT_START,259,70,SPARK_NEG_OK,0.969036,0.832360,1.137847,1.140644,SOFT_START,1260,2408,0 -188666897,260,70,SPARK_NEG_OK,1.121544,0.917158,0.879552,0.996955,SOFT_START,260,71,SPARK_NEG_OK,0.964869,0.840536,1.137853,1.140586,SOFT_START,1262,2383,0 -188713897,261,70,SPARK_NEG_OK,1.006838,0.871430,0.886389,1.000649,SOFT_START,261,70,SPARK_NEG_OK,0.939159,0.848396,1.137869,1.140559,SOFT_START,1261,2393,0 -188761897,262,70,SPARK_NEG_OK,0.894324,0.794024,0.892994,1.004145,SOFT_START,262,68,SPARK_NEG_OK,0.928019,0.852248,1.137821,1.140596,SOFT_START,1263,2380,0 -188808897,263,70,SPARK_NEG_OK,0.792378,0.713205,0.899369,1.007688,SOFT_START,263,70,SPARK_NEG_OK,0.907278,0.853344,1.137887,1.140532,SOFT_START,1263,2388,0 -188856897,264,70,SPARK_NEG_OK,0.711993,0.641000,0.905662,1.011057,SOFT_START,264,68,SPARK_NEG_OK,0.883424,0.847877,1.137824,1.140597,SOFT_START,1261,2394,0 -188904897,265,70,SPARK_NEG_OK,0.642690,0.579099,0.911708,1.014376,SOFT_START,265,70,SPARK_NEG_OK,0.857443,0.834920,1.137865,1.140476,SOFT_START,1262,2399,0 -188951897,266,70,SPARK_NEG_OK,0.579383,0.525275,0.917584,1.017608,SOFT_START,266,70,SPARK_NEG_OK,0.830497,0.815192,1.137882,1.140587,SOFT_START,1260,2399,0 -188999897,267,72,SPARK_NEG_OK,0.539801,0.480517,0.923313,1.020726,SOFT_START,267,70,SPARK_NEG_OK,0.805323,0.781777,1.137908,1.140289,SOFT_START,1261,2407,0 -189046897,268,70,SPARK_NEG_OK,0.503846,0.442174,0.928857,1.023766,SOFT_START,268,70,SPARK_NEG_OK,0.779868,0.747729,1.137869,1.140617,SOFT_START,1259,2387,0 -189094897,269,71,SPARK_NEG_OK,0.473605,0.411652,0.934254,1.026766,SOFT_START,269,70,SPARK_NEG_OK,0.754997,0.717442,1.137917,1.140615,SOFT_START,1260,2401,0 -189142897,270,70,SPARK_NEG_OK,0.447165,0.388206,0.939519,1.029673,SOFT_START,270,70,SPARK_NEG_OK,0.730941,0.691622,1.137973,1.140569,SOFT_START,1260,2390,0 -189189897,271,71,SPARK_NEG_OK,0.423068,0.368305,0.944640,1.032477,SOFT_START,271,70,SPARK_NEG_OK,0.699619,0.675431,1.137970,1.140774,SOFT_START,1261,2386,0 -189237897,272,70,SPARK_NEG_OK,0.407107,0.355234,0.949636,1.035297,SOFT_START,272,70,SPARK_NEG_OK,0.670904,0.671463,1.138054,1.140611,SOFT_START,1260,2404,0 -189284897,273,71,SPARK_NEG_OK,0.394313,0.343097,0.954507,1.037993,SOFT_START,273,70,SPARK_NEG_OK,0.647012,0.682203,1.138121,1.140590,SOFT_START,1261,2404,0 -189332897,274,70,SPARK_NEG_OK,0.398661,0.337926,0.959170,1.040582,SOFT_START,274,70,SPARK_NEG_OK,0.650623,0.694205,1.138129,1.140496,SOFT_START,1261,2405,0 -189379897,275,70,SPARK_NEG_OK,0.410626,0.346069,0.963689,1.043091,SOFT_START,275,71,SPARK_NEG_OK,0.663587,0.705626,1.138141,1.140475,SOFT_START,1259,2392,0 -189427897,276,70,SPARK_NEG_OK,0.429541,0.367099,0.968152,1.045567,SOFT_START,276,70,SPARK_NEG_OK,0.676201,0.716953,1.138143,1.140402,SOFT_START,1261,2403,0 -189475897,277,70,SPARK_NEG_OK,0.439961,0.354449,0.972412,1.047925,SOFT_START,277,71,SPARK_NEG_OK,0.668110,0.696240,1.138114,1.140418,SOFT_START,1258,2377,0 -189522897,278,70,SPARK_NEG_OK,0.435195,0.341094,0.972803,1.050244,SOFT_START,278,70,SPARK_NEG_OK,0.648581,0.646859,1.138051,1.140268,SOFT_START,1260,2401,0 -189570897,279,70,SPARK_NEG_OK,0.430396,0.323398,0.969666,1.052520,SOFT_START,279,71,SPARK_NEG_OK,0.625216,0.602841,1.138069,1.140502,SOFT_START,1258,2408,0 -189618897,280,72,SPARK_NEG_OK,0.421043,0.310248,0.965737,1.054794,SOFT_START,280,70,SPARK_NEG_OK,0.601267,0.576609,1.138109,1.140491,SOFT_START,1260,2382,0 -189665897,281,70,SPARK_NEG_OK,0.408700,0.294498,0.953568,1.056967,SOFT_START,281,71,SPARK_NEG_OK,0.577353,0.565181,1.138116,1.140410,SOFT_START,1258,2392,0 -189713897,282,70,SPARK_NEG_OK,0.395401,0.283706,0.949467,1.059158,SOFT_START,282,70,SPARK_NEG_OK,0.562693,0.557966,1.138261,1.140411,SOFT_START,1260,2387,0 -189761897,283,70,SPARK_NEG_OK,0.408309,0.289696,0.954339,1.061185,SOFT_START,283,71,SPARK_NEG_OK,0.572813,0.558249,1.138240,1.140365,SOFT_START,1259,2384,0 -189808897,284,70,SPARK_NEG_OK,0.428518,0.312431,0.959098,1.063156,SOFT_START,284,70,SPARK_NEG_OK,0.587675,0.573570,1.138274,1.140383,SOFT_START,1261,2398,0 -189856897,285,70,SPARK_NEG_OK,0.447344,0.334479,0.963700,1.065129,SOFT_START,285,70,SPARK_NEG_OK,0.602085,0.588391,1.138332,1.140342,SOFT_START,1259,2389,0 -189903897,286,71,SPARK_NEG_OK,0.465884,0.355819,0.968169,1.067016,SOFT_START,286,70,SPARK_NEG_OK,0.616104,0.602788,1.138285,1.140370,SOFT_START,1259,2396,0 -189951897,287,70,SPARK_NEG_OK,0.483671,0.376604,0.972544,1.068796,SOFT_START,287,70,SPARK_NEG_OK,0.629680,0.616722,1.138292,1.140230,SOFT_START,1259,2390,0 -189999897,288,71,SPARK_NEG_OK,0.501574,0.396738,0.976741,1.070604,SOFT_START,288,70,SPARK_NEG_OK,0.642881,0.630298,1.128877,1.126575,SOFT_START,1256,2404,0 -190047897,289,70,SPARK_NEG_OK,0.518438,0.415909,0.980912,1.072384,SOFT_START,289,70,SPARK_NEG_OK,0.655706,0.643550,1.075861,1.114373,SOFT_START,1258,2391,0 -190094897,290,71,SPARK_NEG_OK,0.534669,0.434959,0.984921,1.050166,SOFT_START,290,70,SPARK_NEG_OK,0.668052,0.656343,1.037807,1.098530,SOFT_START,1256,2385,0 -190142897,291,70,SPARK_NEG_OK,0.550009,0.453601,0.988777,1.023545,SOFT_START,291,70,SPARK_NEG_OK,0.680209,0.668812,1.001649,1.094294,SOFT_START,1257,2382,0 -190190897,292,71,SPARK_NEG_OK,0.564892,0.471567,0.992526,0.989840,SOFT_START,292,70,SPARK_NEG_OK,0.691987,0.681003,0.971676,1.088048,SOFT_START,1257,2383,0 -190237897,293,70,SPARK_NEG_OK,0.579583,0.488998,0.996294,0.954406,SOFT_START,293,70,SPARK_NEG_OK,0.703526,0.692990,0.944268,1.082551,SOFT_START,1258,2385,0 -190285897,294,71,SPARK_NEG_OK,0.593919,0.505990,0.999874,0.918449,SOFT_START,294,70,SPARK_NEG_OK,0.714712,0.704528,0.913285,1.074791,SOFT_START,1257,2392,0 -190333897,295,70,SPARK_NEG_OK,0.609040,0.522488,1.003314,0.880556,SOFT_START,295,70,SPARK_NEG_OK,0.725584,0.715716,0.882231,1.071677,SOFT_START,1259,2409,0 -190380897,296,70,SPARK_NEG_OK,0.622788,0.538580,1.006724,0.835291,SOFT_START,296,71,SPARK_NEG_OK,0.736191,0.726812,0.850815,1.075814,SOFT_START,1257,2393,0 -190428897,297,70,SPARK_NEG_OK,0.636339,0.554193,1.010138,0.788835,SOFT_START,297,70,SPARK_NEG_OK,0.746495,0.737415,0.818412,1.074355,SOFT_START,1258,2394,0 -190476897,298,70,SPARK_NEG_OK,0.649769,0.569394,1.013394,0.747768,SOFT_START,298,71,SPARK_NEG_OK,0.756562,0.747749,0.789492,1.074809,SOFT_START,1258,2401,0 -190523897,299,70,SPARK_NEG_OK,0.662090,0.584210,1.016519,0.711938,SOFT_START,299,70,SPARK_NEG_OK,0.766363,0.757764,0.762480,1.072893,SOFT_START,1256,2382,0 -190571897,300,70,SPARK_NEG_OK,0.674841,0.598598,1.019611,0.680598,SOFT_START,300,71,SPARK_NEG_OK,0.775893,0.767547,0.732986,1.070690,SOFT_START,1258,2402,0 -190619897,301,70,SPARK_NEG_OK,0.686823,0.612609,1.022608,0.654848,SOFT_START,301,70,SPARK_NEG_OK,0.785160,0.777064,0.707974,1.072136,SOFT_START,1256,2396,0 -190667897,302,70,SPARK_NEG_OK,0.698590,0.626316,1.025476,0.631757,SOFT_START,302,71,SPARK_NEG_OK,0.794262,0.786403,0.686486,1.068516,SOFT_START,1257,2393,0 -190714897,303,70,SPARK_NEG_OK,0.710099,0.639511,1.028345,0.611635,SOFT_START,303,70,SPARK_NEG_OK,0.803024,0.795431,0.670051,1.069409,SOFT_START,1257,2394,0 -190762897,304,70,SPARK_NEG_OK,0.721261,0.652429,1.031089,0.591972,SOFT_START,304,71,SPARK_NEG_OK,0.811570,0.804190,0.656787,1.070213,SOFT_START,1259,2394,0 -190810897,305,70,SPARK_NEG_OK,0.731868,0.665058,1.033797,0.572663,SOFT_START,305,70,SPARK_NEG_OK,0.819991,0.812809,0.644847,1.069613,SOFT_START,1257,2386,0 -190857897,306,70,SPARK_NEG_OK,0.742422,0.677364,1.036482,0.555892,SOFT_START,306,71,SPARK_NEG_OK,0.828177,0.821185,0.635573,1.075899,SOFT_START,1260,2392,0 -190905897,307,71,SPARK_NEG_OK,0.752888,0.689259,1.039063,0.542604,SOFT_START,307,72,SPARK_NEG_OK,0.836152,0.829360,0.633015,1.099085,SOFT_START,1258,2396,0 -190953897,308,70,SPARK_NEG_OK,0.762556,0.700566,1.041470,0.558567,SOFT_START,308,70,SPARK_NEG_OK,0.843797,0.837128,0.641674,1.137978,SOFT_START,1259,2384,0 -191000897,309,81,SPARK_NEG_OK,0.772207,0.711884,1.043870,0.573983,SOFT_START,309,80,SPARK_NEG_OK,0.851268,0.844831,0.655099,1.139367,SOFT_START,1257,2385,0 -191048897,310,80,SPARK_NEG_OK,0.781264,0.722896,1.041488,0.580509,SOFT_START,310,80,SPARK_NEG_OK,0.858574,0.852370,0.647225,1.139547,SOFT_START,1257,2378,0 -191096897,311,81,SPARK_NEG_OK,0.790655,0.733562,0.990750,0.563973,SOFT_START,311,70,SPARK_NEG_OK,0.865586,0.850257,0.620382,1.128847,SOFT_START,1257,2399,0 -191143897,312,70,SPARK_NEG_OK,0.799589,0.743960,0.942124,0.543885,SOFT_START,312,70,SPARK_NEG_OK,0.872611,0.837538,0.585876,1.119562,SOFT_START,1256,2394,0 -191191897,313,70,SPARK_NEG_OK,0.808343,0.754052,0.894533,0.521106,SOFT_START,313,70,SPARK_NEG_OK,0.879362,0.815218,0.568060,1.110529,SOFT_START,1257,2392,0 -191239897,314,70,SPARK_NEG_OK,0.816672,0.763920,0.848632,0.499606,SOFT_START,314,70,SPARK_NEG_OK,0.885992,0.795727,0.562121,1.108317,SOFT_START,1257,2391,0 -191287897,315,71,SPARK_NEG_OK,0.825053,0.773296,0.803438,0.478330,SOFT_START,315,71,SPARK_NEG_OK,0.892382,0.777851,0.544412,1.104877,SOFT_START,1258,2394,0 -191334897,316,70,SPARK_NEG_OK,0.833554,0.782652,0.762842,0.455941,SOFT_START,316,70,SPARK_NEG_OK,0.898632,0.761204,0.542561,1.104763,SOFT_START,1258,2404,0 -191382897,317,71,SPARK_NEG_OK,0.841953,0.791766,0.728159,0.435472,SOFT_START,317,70,SPARK_NEG_OK,0.904728,0.743864,0.542182,1.105455,SOFT_START,1259,2410,0 -191429899,318,70,SPARK_NEG_OK,0.849262,0.800627,0.697125,0.414697,SOFT_START,318,70,SPARK_NEG_OK,0.910636,0.726589,0.536417,1.105343,SOFT_START,1258,2381,0 -191477897,319,70,SPARK_NEG_OK,0.856977,0.809301,0.671430,0.398297,SOFT_START,319,71,SPARK_NEG_OK,0.916439,0.710132,0.536246,1.106201,SOFT_START,1259,2401,0 -191525897,320,68,SPARK_NEG_OK,0.864226,0.817706,0.649173,0.383372,SOFT_START,320,70,SPARK_NEG_OK,0.922053,0.693378,0.535363,1.106548,SOFT_START,1257,2399,0 -191573897,321,70,SPARK_NEG_OK,0.871081,0.825708,0.628685,0.370935,SOFT_START,321,71,SPARK_NEG_OK,0.927595,0.682542,0.534340,1.107010,SOFT_START,1258,2379,0 -191620897,322,70,SPARK_NEG_OK,0.877873,0.833690,0.610544,0.361459,SOFT_START,322,71,SPARK_NEG_OK,0.932933,0.684170,0.533530,1.108972,SOFT_START,1258,2387,0 -191668897,323,70,SPARK_NEG_OK,0.884545,0.841509,0.594100,0.352716,SOFT_START,323,71,SPARK_NEG_OK,0.938066,0.696053,0.529802,1.110553,SOFT_START,1257,2387,0 -191716897,324,70,SPARK_NEG_OK,0.890825,0.849009,0.586866,0.347410,SOFT_START,324,70,SPARK_NEG_OK,0.943151,0.707584,0.525452,1.110213,SOFT_START,1258,2382,0 -191763897,325,70,SPARK_NEG_OK,0.897419,0.856338,0.588261,0.345953,SOFT_START,325,71,SPARK_NEG_OK,0.948024,0.716192,0.524531,1.098732,SOFT_START,1257,2403,0 -191811897,326,70,SPARK_NEG_OK,0.903310,0.863463,0.590606,0.345289,SOFT_START,326,72,SPARK_NEG_OK,0.952848,0.722920,0.528352,1.092634,SOFT_START,1259,2381,0 -191859897,327,70,SPARK_NEG_OK,0.909297,0.870429,0.586400,0.347955,SOFT_START,327,71,SPARK_NEG_OK,0.957583,0.733342,0.533801,1.089435,SOFT_START,1258,2390,0 -191906897,328,70,SPARK_NEG_OK,0.915223,0.877239,0.581699,0.348344,SOFT_START,328,70,SPARK_NEG_OK,0.962174,0.743883,0.536938,1.086290,SOFT_START,1259,2398,0 -191954897,329,70,SPARK_NEG_OK,0.921147,0.883843,0.574491,0.350075,SOFT_START,329,72,SPARK_NEG_OK,0.966603,0.754163,0.540155,1.083750,SOFT_START,1258,2400,0 -192002897,330,71,SPARK_NEG_OK,0.926576,0.890207,0.559911,0.354365,SOFT_START,330,70,SPARK_NEG_OK,0.970954,0.764207,0.544133,1.081342,SOFT_START,1259,2389,0 -192049897,331,70,SPARK_NEG_OK,0.932415,0.896492,0.538313,0.357807,SOFT_START,331,70,SPARK_NEG_OK,0.975103,0.773910,0.547756,1.076151,SOFT_START,1257,2405,0 -192097897,332,71,SPARK_NEG_OK,0.937918,0.902609,0.515330,0.364317,SOFT_START,332,70,SPARK_NEG_OK,0.979365,0.783376,0.554141,1.073771,SOFT_START,1259,2406,0 -192145897,333,70,SPARK_NEG_OK,0.943314,0.908580,0.498574,0.368890,SOFT_START,333,70,SPARK_NEG_OK,0.983343,0.792553,0.559369,1.070050,SOFT_START,1257,2404,0 -192192897,334,71,SPARK_NEG_OK,0.948131,0.914369,0.508566,0.368342,SOFT_START,334,70,SPARK_NEG_OK,0.987229,0.801677,0.562606,1.066432,SOFT_START,1258,2384,0 -192240897,335,70,SPARK_NEG_OK,0.953181,0.920057,0.520288,0.358691,SOFT_START,335,70,SPARK_NEG_OK,0.991074,0.810406,0.566635,1.066079,SOFT_START,1258,2401,0 -192288897,336,71,SPARK_NEG_OK,0.957879,0.925593,0.533798,0.340669,SOFT_START,336,70,SPARK_NEG_OK,0.994776,0.818911,0.570375,1.063755,SOFT_START,1258,2389,0 -192335897,337,70,SPARK_NEG_OK,0.962690,0.930984,0.547384,0.336614,SOFT_START,337,70,SPARK_NEG_OK,0.998428,0.827124,0.575967,1.062478,SOFT_START,1259,2403,0 -192383897,338,71,SPARK_NEG_OK,0.967425,0.936232,0.562908,0.348035,SOFT_START,338,72,SPARK_NEG_OK,1.001999,0.835164,0.580236,1.061581,SOFT_START,1258,2408,0 -192431897,339,70,SPARK_NEG_OK,0.971728,0.941358,0.578160,0.363296,SOFT_START,339,71,SPARK_NEG_OK,1.005390,0.842988,0.583218,1.060054,SOFT_START,1259,2389,0 -192478897,340,70,SPARK_NEG_OK,0.975807,0.946314,0.592960,0.378453,SOFT_START,340,71,SPARK_NEG_OK,1.008667,0.850523,0.589486,1.062918,SOFT_START,1258,2378,0 -192526897,341,70,SPARK_NEG_OK,0.979980,0.951179,0.607321,0.394570,SOFT_START,341,70,SPARK_NEG_OK,1.011981,0.857860,0.593049,1.060285,SOFT_START,1259,2400,0 -192574897,342,70,SPARK_NEG_OK,0.983860,0.955915,0.621075,0.406840,SOFT_START,342,71,SPARK_NEG_OK,1.015145,0.865094,0.596339,1.058868,SOFT_START,1257,2383,0 -192621897,343,70,SPARK_NEG_OK,0.987717,0.960475,0.634681,0.414582,SOFT_START,343,70,SPARK_NEG_OK,1.018227,0.872234,0.598782,1.059689,SOFT_START,1258,2384,0 -192669897,344,70,SPARK_NEG_OK,0.991434,0.964962,0.647946,0.416000,SOFT_START,344,71,SPARK_NEG_OK,1.021250,0.879025,0.596784,1.057622,SOFT_START,1257,2381,0 -192717897,345,70,SPARK_NEG_OK,0.995185,0.969330,0.659711,0.417155,SOFT_START,345,70,SPARK_NEG_OK,1.024167,0.885672,0.595410,1.059654,SOFT_START,1258,2395,0 -192764900,346,69,SPARK_NEG_OK,0.998966,0.973598,0.658923,0.414504,SOFT_START,346,71,SPARK_NEG_OK,1.027060,0.892162,0.595211,1.062050,SOFT_START,1258,2402,0 -192812897,347,70,SPARK_NEG_OK,1.002623,0.977703,0.639119,0.411404,SOFT_START,347,70,SPARK_NEG_OK,1.029796,0.898438,0.595747,1.063986,SOFT_START,1257,2403,0 -192860897,348,70,SPARK_NEG_OK,1.006231,0.981752,0.613019,0.406735,SOFT_START,348,71,SPARK_NEG_OK,1.032530,0.904560,0.597475,1.067961,SOFT_START,1258,2408,0 -192907897,349,70,SPARK_NEG_OK,1.009482,0.985759,0.571611,0.402676,SOFT_START,349,70,SPARK_NEG_OK,1.035263,0.910570,0.599487,1.074504,SOFT_START,1258,2381,0 -192955897,350,70,SPARK_NEG_OK,1.012916,0.989633,0.576071,0.408452,SOFT_START,350,71,SPARK_NEG_OK,1.037896,0.916445,0.598219,1.118112,SOFT_START,1260,2394,0 -193003897,351,70,SPARK_NEG_OK,1.015959,0.993312,0.591127,0.427592,SOFT_START,351,70,SPARK_NEG_OK,1.040300,0.922058,0.612183,1.139008,SOFT_START,1257,2382,0 -193050897,352,70,SPARK_NEG_OK,1.019269,0.997037,0.605723,0.446277,SOFT_START,352,69,SPARK_NEG_OK,1.042816,0.927587,0.626343,1.139585,SOFT_START,1259,2404,0 -193098897,353,71,SPARK_NEG_OK,1.022347,1.000603,0.610359,0.463060,SOFT_START,353,70,SPARK_NEG_OK,1.045161,0.928534,0.639951,1.139781,SOFT_START,1256,2395,0 -193146897,354,70,SPARK_NEG_OK,1.025310,1.003061,0.591187,0.464465,SOFT_START,354,70,SPARK_NEG_OK,0.991983,0.872154,0.653077,1.139730,SOFT_START,1257,2400,0 -193194897,355,71,SPARK_NEG_OK,1.028230,0.943663,0.568030,0.468370,SOFT_START,355,70,SPARK_NEG_OK,0.917254,0.826780,0.665873,1.139807,SOFT_START,1255,2392,0 -193241897,356,70,SPARK_NEG_OK,1.031079,0.888375,0.531271,0.473001,SOFT_START,356,70,SPARK_NEG_OK,0.851082,0.790309,0.678361,1.139907,SOFT_START,1257,2399,0 -193289897,357,71,SPARK_NEG_OK,1.033816,0.842385,0.486686,0.476835,SOFT_START,357,70,SPARK_NEG_OK,0.791644,0.759033,0.690480,1.140005,SOFT_START,1255,2391,0 -193337897,358,72,SPARK_NEG_OK,1.036532,0.806363,0.446562,0.481356,SOFT_START,358,70,SPARK_NEG_OK,0.733872,0.741358,0.702291,1.140096,SOFT_START,1257,2397,0 -193385897,359,71,SPARK_NEG_OK,1.039274,0.815593,0.417851,0.463129,SOFT_START,359,70,SPARK_NEG_OK,0.722080,0.724129,0.713770,1.140032,SOFT_START,1257,2397,0 -193432897,360,70,SPARK_NEG_OK,1.041692,0.803937,0.422419,0.480573,SOFT_START,360,71,SPARK_NEG_OK,0.701705,0.705495,0.724836,1.140009,SOFT_START,1256,2391,0 -193480897,361,71,SPARK_NEG_OK,1.040588,0.764834,0.441830,0.497825,SOFT_START,361,68,SPARK_NEG_OK,0.701593,0.717017,0.735635,1.139827,SOFT_START,1257,2402,0 -193528897,362,69,SPARK_NEG_OK,0.943286,0.737903,0.460395,0.514492,SOFT_START,362,70,SPARK_NEG_OK,0.677440,0.728059,0.746189,1.139968,SOFT_START,1256,2398,0 -193576897,363,71,SPARK_NEG_OK,0.859758,0.610667,0.478484,0.530713,SOFT_START,363,70,SPARK_NEG_OK,0.675141,0.738817,0.756457,1.139762,SOFT_START,1257,2397,0 -193623897,364,70,SPARK_NEG_OK,0.759543,0.509748,0.495975,0.546516,SOFT_START,364,70,SPARK_NEG_OK,0.679256,0.749259,0.766445,1.139993,SOFT_START,1255,2404,0 -193671897,365,71,SPARK_NEG_OK,0.681712,0.430894,0.512948,0.561854,SOFT_START,365,70,SPARK_NEG_OK,0.679159,0.759298,0.776160,1.139968,SOFT_START,1257,2378,0 -193719897,366,70,SPARK_NEG_OK,0.616158,0.390927,0.529459,0.576734,SOFT_START,366,70,SPARK_NEG_OK,0.689732,0.769073,0.785657,1.139937,SOFT_START,1255,2416,0 -193767897,367,70,SPARK_NEG_OK,0.569114,0.396481,0.545491,0.591248,SOFT_START,367,71,SPARK_NEG_OK,0.701455,0.778584,0.794792,1.139957,SOFT_START,1256,2402,0 -193814897,368,70,SPARK_NEG_OK,0.539470,0.416414,0.561114,0.605364,SOFT_START,368,70,SPARK_NEG_OK,0.712866,0.787783,0.803744,1.139974,SOFT_START,1255,2407,0 -193862897,369,70,SPARK_NEG_OK,0.513363,0.435762,0.576231,0.619119,SOFT_START,369,71,SPARK_NEG_OK,0.723912,0.796808,0.812445,1.139996,SOFT_START,1256,2394,0 -193910897,370,70,SPARK_NEG_OK,0.499718,0.454457,0.591065,0.632217,SOFT_START,370,70,SPARK_NEG_OK,0.734664,0.805569,0.820919,1.139912,SOFT_START,1255,2405,0 -193958897,371,70,SPARK_NEG_OK,0.458908,0.472177,0.605624,0.645221,SOFT_START,371,71,SPARK_NEG_OK,0.745131,0.814028,0.829176,1.139857,SOFT_START,1257,2398,0 -194005897,372,70,SPARK_NEG_OK,0.414161,0.489759,0.619569,0.657945,SOFT_START,372,70,SPARK_NEG_OK,0.755258,0.822368,0.837253,1.139791,SOFT_START,1257,2409,0 -194053897,373,67,SPARK_NEG_OK,0.389282,0.506837,0.633170,0.670336,SOFT_START,373,71,SPARK_NEG_OK,0.765198,0.830492,0.845079,1.139596,SOFT_START,1256,2403,0 -194101897,374,70,SPARK_NEG_OK,0.410736,0.523409,0.646330,0.682328,SOFT_START,374,70,SPARK_NEG_OK,0.774783,0.838342,0.852683,1.139454,SOFT_START,1257,2408,0 -194149897,375,70,SPARK_NEG_OK,0.430081,0.539525,0.659195,0.693962,SOFT_START,375,71,SPARK_NEG_OK,0.784162,0.845987,0.860129,1.139765,SOFT_START,1254,2388,0 -194196897,376,70,SPARK_NEG_OK,0.448516,0.555187,0.671666,0.705381,SOFT_START,376,72,SPARK_NEG_OK,0.793269,0.853422,0.867366,1.139636,SOFT_START,1255,2383,0 -194244897,377,70,SPARK_NEG_OK,0.448713,0.526941,0.683811,0.716451,SOFT_START,377,71,SPARK_NEG_OK,0.794423,0.860678,0.874374,1.139442,SOFT_START,1254,2379,0 -194292897,378,70,SPARK_NEG_OK,0.411646,0.484101,0.695498,0.727075,SOFT_START,378,70,SPARK_NEG_OK,0.743201,0.867624,0.881081,1.139567,SOFT_START,1255,2407,0 -194340897,379,70,SPARK_NEG_OK,0.380747,0.444918,0.706997,0.737512,SOFT_START,379,71,SPARK_NEG_OK,0.691245,0.874469,0.887774,1.139737,SOFT_START,1253,2403,0 -194388897,380,71,SPARK_NEG_OK,0.349463,0.379552,0.718315,0.747783,SOFT_START,380,70,SPARK_NEG_OK,0.650082,0.881072,0.894248,1.139803,SOFT_START,1255,2385,0 -194435897,381,70,SPARK_NEG_OK,0.318486,0.317509,0.729185,0.757706,SOFT_START,381,70,SPARK_NEG_OK,0.614719,0.887564,0.900618,1.139713,SOFT_START,1254,2388,0 -194483897,382,71,SPARK_NEG_OK,0.293643,0.275019,0.739657,0.767452,SOFT_START,382,68,SPARK_NEG_OK,0.584599,0.893788,0.906743,1.139688,SOFT_START,1256,2409,0 -194531897,383,70,SPARK_NEG_OK,0.265042,0.240133,0.749997,0.776879,SOFT_START,383,70,SPARK_NEG_OK,0.557883,0.899736,0.912724,1.139598,SOFT_START,1256,2389,0 -194579897,384,71,SPARK_NEG_OK,0.245752,0.215394,0.759985,0.786088,SOFT_START,384,70,SPARK_NEG_OK,0.535682,0.905674,0.918611,1.139730,SOFT_START,1256,2397,0 -194626897,385,70,SPARK_NEG_OK,0.227054,0.195889,0.769749,0.795034,SOFT_START,385,70,SPARK_NEG_OK,0.516067,0.911434,0.924313,1.139698,SOFT_START,1257,2377,0 -194674897,386,71,SPARK_NEG_OK,0.210389,0.180584,0.779215,0.803801,SOFT_START,386,70,SPARK_NEG_OK,0.498500,0.917002,0.929878,1.139756,SOFT_START,1255,2398,0 -194722897,387,70,SPARK_NEG_OK,0.210795,0.171658,0.788510,0.812395,SOFT_START,387,70,SPARK_NEG_OK,0.487638,0.922533,0.935345,1.139140,SOFT_START,1256,2393,0 -194770897,388,71,SPARK_NEG_OK,0.209922,0.181316,0.797400,0.820652,SOFT_START,388,70,SPARK_NEG_OK,0.500386,0.927792,0.940543,1.139169,SOFT_START,1254,2393,0 -194818897,389,70,SPARK_NEG_OK,0.235092,0.207329,0.806135,0.828743,SOFT_START,389,70,SPARK_NEG_OK,0.517223,0.932924,0.945657,1.139223,SOFT_START,1256,2398,0 -194865897,390,71,SPARK_NEG_OK,0.259536,0.232139,0.814663,0.836604,SOFT_START,390,70,SPARK_NEG_OK,0.533477,0.937994,0.950645,1.138840,SOFT_START,1255,2397,0 -194913897,391,68,SPARK_NEG_OK,0.282499,0.256298,0.778925,0.843626,SOFT_START,391,70,SPARK_NEG_OK,0.549246,0.928463,0.955310,1.139047,SOFT_START,1256,2385,0 -194961897,392,71,SPARK_NEG_OK,0.305440,0.279715,0.735527,0.743704,SOFT_START,392,70,SPARK_NEG_OK,0.564599,0.886894,0.926742,1.132833,SOFT_START,1255,2395,0 -195009897,393,70,SPARK_NEG_OK,0.327359,0.302435,0.715210,0.661168,SOFT_START,393,69,SPARK_NEG_OK,0.579449,0.871477,0.831993,1.104728,SOFT_START,1257,2395,0 -195056897,394,70,SPARK_NEG_OK,0.348352,0.324542,0.688795,0.601309,SOFT_START,394,71,SPARK_NEG_OK,0.593755,0.865296,0.751398,1.101071,SOFT_START,1256,2387,0 -195104897,395,70,SPARK_NEG_OK,0.369970,0.346324,0.655285,0.559288,SOFT_START,395,70,SPARK_NEG_OK,0.607886,0.862819,0.691777,1.095065,SOFT_START,1258,2401,0 -195152897,396,70,SPARK_NEG_OK,0.389749,0.367254,0.612344,0.522242,SOFT_START,396,71,SPARK_NEG_OK,0.621668,0.859252,0.651463,1.080623,SOFT_START,1258,2388,0 -195199897,397,70,SPARK_NEG_OK,0.408787,0.387484,0.576465,0.490590,SOFT_START,397,70,SPARK_NEG_OK,0.634968,0.860549,0.620983,1.070460,SOFT_START,1256,2382,0 -195247897,398,70,SPARK_NEG_OK,0.427249,0.407187,0.541549,0.468117,SOFT_START,398,73,SPARK_NEG_OK,0.647950,0.851352,0.595222,1.061361,SOFT_START,1257,2380,0 -195295897,399,70,SPARK_NEG_OK,0.445415,0.426301,0.502493,0.450258,SOFT_START,399,70,SPARK_NEG_OK,0.660548,0.835061,0.575306,1.053540,SOFT_START,1255,2391,0 -195343897,400,70,SPARK_NEG_OK,0.462913,0.444932,0.460909,0.437908,SOFT_START,400,71,SPARK_NEG_OK,0.672863,0.816779,0.561062,1.049340,SOFT_START,1257,2380,0 -195390897,401,70,SPARK_NEG_OK,0.480255,0.463036,0.423845,0.428616,SOFT_START,401,70,SPARK_NEG_OK,0.684830,0.799495,0.549327,1.041117,SOFT_START,1255,2388,0 -195438897,402,68,SPARK_NEG_OK,0.497649,0.480735,0.395966,0.424913,SOFT_START,402,71,SPARK_NEG_OK,0.696477,0.788710,0.541575,1.035540,SOFT_START,1257,2395,0 -195486897,403,71,SPARK_NEG_OK,0.514337,0.497772,0.375275,0.421812,SOFT_START,403,70,SPARK_NEG_OK,0.707844,0.778397,0.536014,1.029574,SOFT_START,1256,2393,0 -195534897,404,70,SPARK_NEG_OK,0.531467,0.514451,0.357180,0.420932,SOFT_START,404,71,SPARK_NEG_OK,0.718875,0.769340,0.531498,1.023295,SOFT_START,1258,2410,0 -195581897,405,70,SPARK_NEG_OK,0.547957,0.530673,0.345371,0.423130,SOFT_START,405,68,SPARK_NEG_OK,0.729517,0.760951,0.529671,1.019849,SOFT_START,1256,2404,0 -195629897,406,70,SPARK_NEG_OK,0.562891,0.546544,0.337175,0.424153,SOFT_START,406,71,SPARK_NEG_OK,0.739949,0.752168,0.527497,1.014099,SOFT_START,1258,2384,0 -195677897,407,70,SPARK_NEG_OK,0.578579,0.561872,0.331700,0.425733,SOFT_START,407,70,SPARK_NEG_OK,0.750111,0.745311,0.526377,1.010666,SOFT_START,1258,2405,0 -195724897,408,70,SPARK_NEG_OK,0.593423,0.576733,0.328864,0.428541,SOFT_START,408,70,SPARK_NEG_OK,0.759987,0.740290,0.526363,1.008461,SOFT_START,1256,2400,0 -195772897,409,71,SPARK_NEG_OK,0.608006,0.591232,0.326842,0.430810,SOFT_START,409,70,SPARK_NEG_OK,0.769629,0.735317,0.525264,1.004090,SOFT_START,1257,2400,0 -195820897,410,70,SPARK_NEG_OK,0.622252,0.605335,0.327471,0.431709,SOFT_START,410,70,SPARK_NEG_OK,0.779007,0.730571,0.526602,1.003827,SOFT_START,1256,2407,0 -195868897,411,71,SPARK_NEG_OK,0.635929,0.618970,0.327794,0.430644,SOFT_START,411,70,SPARK_NEG_OK,0.788230,0.726069,0.526972,1.000861,SOFT_START,1257,2398,0 -195915897,412,70,SPARK_NEG_OK,0.649498,0.632347,0.328463,0.429895,SOFT_START,412,70,SPARK_NEG_OK,0.797049,0.721974,0.527271,0.998697,SOFT_START,1256,2405,0 -195963897,413,71,SPARK_NEG_OK,0.661583,0.645319,0.330486,0.431867,SOFT_START,413,70,SPARK_NEG_OK,0.805707,0.718610,0.528444,0.998928,SOFT_START,1257,2379,0 -196011897,414,70,SPARK_NEG_OK,0.674603,0.657951,0.332386,0.433189,SOFT_START,414,70,SPARK_NEG_OK,0.814090,0.715082,0.528497,0.995190,SOFT_START,1256,2409,0 -196058897,415,71,SPARK_NEG_OK,0.686598,0.670295,0.335856,0.435284,SOFT_START,415,70,SPARK_NEG_OK,0.822357,0.712208,0.529659,0.995315,SOFT_START,1258,2390,0 -196106897,416,70,SPARK_NEG_OK,0.697910,0.682217,0.339230,0.436991,SOFT_START,416,70,SPARK_NEG_OK,0.830402,0.709519,0.530642,0.994439,SOFT_START,1257,2387,0 -196154897,417,71,SPARK_NEG_OK,0.709521,0.693904,0.343508,0.437927,SOFT_START,417,70,SPARK_NEG_OK,0.838199,0.706606,0.531059,0.991716,SOFT_START,1258,2396,0 -196202897,418,70,SPARK_NEG_OK,0.720154,0.705253,0.348450,0.440330,SOFT_START,418,70,SPARK_NEG_OK,0.845796,0.704414,0.532942,0.993031,SOFT_START,1256,2381,0 -196249897,419,71,SPARK_NEG_OK,0.731535,0.716321,0.351739,0.441970,SOFT_START,419,70,SPARK_NEG_OK,0.853224,0.702141,0.534596,0.989261,SOFT_START,1257,2406,0 -196297897,420,72,SPARK_NEG_OK,0.742173,0.727088,0.354928,0.444053,SOFT_START,420,70,SPARK_NEG_OK,0.860410,0.700425,0.536754,0.989192,SOFT_START,1257,2398,0 -196345897,421,71,SPARK_NEG_OK,0.751955,0.737589,0.357251,0.446453,SOFT_START,421,71,SPARK_NEG_OK,0.867425,0.699195,0.538892,0.990196,SOFT_START,1255,2384,0 -196393897,422,70,SPARK_NEG_OK,0.761726,0.747836,0.357944,0.447455,SOFT_START,422,70,SPARK_NEG_OK,0.874292,0.697886,0.539917,0.987804,SOFT_START,1256,2389,0 -196440897,423,71,SPARK_NEG_OK,0.771020,0.757717,0.359999,0.449529,SOFT_START,423,71,SPARK_NEG_OK,0.881009,0.697231,0.542271,0.989618,SOFT_START,1255,2375,0 -196488897,424,70,SPARK_NEG_OK,0.780604,0.767414,0.361903,0.450774,SOFT_START,424,70,SPARK_NEG_OK,0.887476,0.696497,0.543872,0.987710,SOFT_START,1256,2400,0 -196536897,425,70,SPARK_NEG_OK,0.789748,0.776840,0.363056,0.452746,SOFT_START,425,71,SPARK_NEG_OK,0.893809,0.696051,0.545713,0.987282,SOFT_START,1256,2393,0 -196584897,426,70,SPARK_NEG_OK,0.798498,0.785926,0.364348,0.455781,SOFT_START,426,70,SPARK_NEG_OK,0.899980,0.695949,0.548121,0.989075,SOFT_START,1257,2388,0 -196631897,427,70,SPARK_NEG_OK,0.807515,0.794898,0.364979,0.457662,SOFT_START,427,71,SPARK_NEG_OK,0.906025,0.696300,0.549321,0.987119,SOFT_START,1256,2398,0 -196679897,428,70,SPARK_NEG_OK,0.816078,0.803599,0.366492,0.460225,SOFT_START,428,70,SPARK_NEG_OK,0.911877,0.697439,0.551886,0.989428,SOFT_START,1257,2393,0 -196727897,429,70,SPARK_NEG_OK,0.824717,0.812083,0.368203,0.463473,SOFT_START,429,71,SPARK_NEG_OK,0.917574,0.699270,0.555409,0.992225,SOFT_START,1256,2403,0 -196774896,430,70,SPARK_NEG_OK,0.832838,0.820377,0.368649,0.468495,SOFT_START,430,70,SPARK_NEG_OK,0.923170,0.702636,0.559613,0.996209,SOFT_START,1257,2397,0 -196822897,431,68,SPARK_NEG_OK,0.840947,0.828457,0.370733,0.475840,SOFT_START,431,71,SPARK_NEG_OK,0.928569,0.712827,0.566477,1.011644,SOFT_START,1255,2401,0 -196870897,432,70,SPARK_NEG_OK,0.848425,0.836203,0.379615,0.481983,SOFT_START,432,70,SPARK_NEG_OK,0.933813,0.723934,0.575102,1.036452,SOFT_START,1256,2388,0 -196918897,433,70,SPARK_NEG_OK,0.855833,0.843859,0.399843,0.498175,SOFT_START,433,71,SPARK_NEG_OK,0.938929,0.734705,0.586255,1.128287,SOFT_START,1256,2392,0 -196966897,434,70,SPARK_NEG_OK,0.862790,0.851090,0.419458,0.514846,SOFT_START,434,71,SPARK_NEG_OK,0.943903,0.745150,0.600918,1.138106,SOFT_START,1255,2379,0 -197013897,435,70,SPARK_NEG_OK,0.870082,0.858337,0.438476,0.531024,SOFT_START,435,71,SPARK_NEG_OK,0.948843,0.755377,0.615200,1.138211,SOFT_START,1256,2400,0 -197061897,436,71,SPARK_NEG_OK,0.876852,0.865397,0.456955,0.546771,SOFT_START,436,70,SPARK_NEG_OK,0.953586,0.765290,0.629039,1.138381,SOFT_START,1258,2387,0 -197109897,437,70,SPARK_NEG_OK,0.883547,0.872315,0.474864,0.562065,SOFT_START,437,69,SPARK_NEG_OK,0.958107,0.774966,0.642518,1.138355,SOFT_START,1259,2391,0 -197156897,438,71,SPARK_NEG_OK,0.889871,0.878985,0.492376,0.576943,SOFT_START,438,70,SPARK_NEG_OK,0.962681,0.784309,0.655579,1.138502,SOFT_START,1258,2385,0 -197204897,439,70,SPARK_NEG_OK,0.895979,0.885549,0.509285,0.591406,SOFT_START,439,70,SPARK_NEG_OK,0.967083,0.793441,0.668283,1.138515,SOFT_START,1260,2379,0 -197252897,440,71,SPARK_NEG_OK,0.901951,0.891907,0.525828,0.605496,SOFT_START,440,70,SPARK_NEG_OK,0.971358,0.802382,0.680685,1.138523,SOFT_START,1258,2389,0 -197299897,441,70,SPARK_NEG_OK,0.908242,0.898100,0.541903,0.619220,SOFT_START,441,70,SPARK_NEG_OK,0.975564,0.811036,0.692725,1.138558,SOFT_START,1259,2404,0 -197347897,442,71,SPARK_NEG_OK,0.913891,0.904184,0.557505,0.632538,SOFT_START,442,70,SPARK_NEG_OK,0.979622,0.819438,0.704461,1.138542,SOFT_START,1257,2381,0 -197395897,443,70,SPARK_NEG_OK,0.919912,0.910037,0.572453,0.645549,SOFT_START,443,70,SPARK_NEG_OK,0.983565,0.827636,0.715870,1.138603,SOFT_START,1257,2408,0 -197442897,444,71,SPARK_NEG_OK,0.925835,0.915761,0.587258,0.658139,SOFT_START,444,70,SPARK_NEG_OK,0.987424,0.835754,0.726960,1.138510,SOFT_START,1257,2409,0 -197490897,445,70,SPARK_NEG_OK,0.931081,0.921384,0.601662,0.670450,SOFT_START,445,70,SPARK_NEG_OK,0.991197,0.843522,0.737714,1.138547,SOFT_START,1255,2384,0 -197538897,446,68,SPARK_NEG_OK,0.936205,0.926822,0.615648,0.682462,SOFT_START,446,70,SPARK_NEG_OK,0.994881,0.851083,0.748222,1.138457,SOFT_START,1257,2394,0 -197586897,447,70,SPARK_NEG_OK,0.941679,0.932009,0.629239,0.694079,SOFT_START,447,70,SPARK_NEG_OK,0.998521,0.858462,0.758372,1.138576,SOFT_START,1256,2409,0 -197633897,448,71,SPARK_NEG_OK,0.946813,0.937189,0.642501,0.705446,SOFT_START,448,70,SPARK_NEG_OK,1.001968,0.865648,0.768343,1.138353,SOFT_START,1258,2392,0 -197681897,449,70,SPARK_NEG_OK,0.951939,0.942289,0.655406,0.716542,SOFT_START,449,70,SPARK_NEG_OK,1.005418,0.872613,0.777958,1.138580,SOFT_START,1257,2410,0 -197729897,450,70,SPARK_NEG_OK,0.956769,0.947143,0.667902,0.727336,SOFT_START,450,71,SPARK_NEG_OK,1.008716,0.879436,0.787351,1.138567,SOFT_START,1259,2400,0 -197776897,451,70,SPARK_NEG_OK,0.961485,0.951946,0.680074,0.737779,SOFT_START,451,72,SPARK_NEG_OK,1.011902,0.885992,0.796536,1.138632,SOFT_START,1257,2395,0 -197824897,452,70,SPARK_NEG_OK,0.965814,0.956672,0.691974,0.748004,SOFT_START,452,71,SPARK_NEG_OK,1.015096,0.892447,0.805374,1.138683,SOFT_START,1258,2378,0 -197872897,453,70,SPARK_NEG_OK,0.969991,0.961169,0.703571,0.757943,SOFT_START,453,70,SPARK_NEG_OK,1.018174,0.898783,0.814090,1.138651,SOFT_START,1256,2382,0 -197920897,454,70,SPARK_NEG_OK,0.974422,0.965638,0.714827,0.767618,SOFT_START,454,71,SPARK_NEG_OK,1.021154,0.904873,0.822687,1.138588,SOFT_START,1256,2404,0 -197967897,455,70,SPARK_NEG_OK,0.978434,0.969967,0.725800,0.777068,SOFT_START,455,70,SPARK_NEG_OK,1.024073,0.910866,0.830897,1.138610,SOFT_START,1255,2388,0 -198015897,456,71,SPARK_NEG_OK,0.982476,0.974114,0.736486,0.786243,SOFT_START,456,71,SPARK_NEG_OK,1.026915,0.916633,0.838767,1.138631,SOFT_START,1256,2387,0 -198063897,457,70,SPARK_NEG_OK,0.986497,0.978253,0.746858,0.795330,SOFT_START,457,70,SPARK_NEG_OK,1.029671,0.922282,0.846566,1.138586,SOFT_START,1256,2401,0 -198111897,458,70,SPARK_NEG_OK,0.990388,0.982236,0.757039,0.804005,SOFT_START,458,71,SPARK_NEG_OK,1.032391,0.927808,0.854118,1.138704,SOFT_START,1256,2395,0 -198158897,459,70,SPARK_NEG_OK,0.994188,0.986171,0.766867,0.812482,SOFT_START,459,70,SPARK_NEG_OK,1.035048,0.933197,0.861503,1.138524,SOFT_START,1257,2393,0 -198206897,460,70,SPARK_NEG_OK,0.997861,0.989932,0.776478,0.820764,SOFT_START,460,71,SPARK_NEG_OK,1.037596,0.938282,0.868723,1.138554,SOFT_START,1257,2393,0 -198254897,461,70,SPARK_NEG_OK,1.001484,0.993586,0.785827,0.828819,SOFT_START,461,72,SPARK_NEG_OK,1.040122,0.943370,0.875672,1.138457,SOFT_START,1258,2399,0 -198301897,462,70,SPARK_NEG_OK,1.004820,0.997251,0.794877,0.836490,SOFT_START,462,71,SPARK_NEG_OK,1.042532,0.948245,0.882468,1.138612,SOFT_START,1257,2381,0 -198349897,463,71,SPARK_NEG_OK,1.008261,1.000777,0.803945,0.844142,SOFT_START,463,70,SPARK_NEG_OK,1.044953,0.953137,0.889168,1.138601,SOFT_START,1258,2395,0 -198397897,464,70,SPARK_NEG_OK,1.011630,1.004187,0.812561,0.851560,SOFT_START,464,70,SPARK_NEG_OK,1.047267,0.957842,0.895617,1.138586,SOFT_START,1256,2399,0 -198445897,465,70,SPARK_NEG_OK,1.014755,1.007419,0.820917,0.858834,SOFT_START,465,70,SPARK_NEG_OK,1.049514,0.962403,0.901838,1.138570,SOFT_START,1256,2386,0 -198492897,466,70,SPARK_NEG_OK,1.017913,1.010736,0.829131,0.865717,SOFT_START,466,70,SPARK_NEG_OK,1.051728,0.966837,0.907962,1.138636,SOFT_START,1255,2390,0 -198540897,467,71,SPARK_NEG_OK,1.020833,1.013905,0.837208,0.872640,SOFT_START,467,70,SPARK_NEG_OK,1.053870,0.971184,0.913940,1.138763,SOFT_START,1256,2378,0 -198588897,468,68,SPARK_NEG_OK,1.023827,1.016993,0.844943,0.879311,SOFT_START,468,70,SPARK_NEG_OK,1.055968,0.975426,0.919718,1.138736,SOFT_START,1256,2401,0 -198636897,469,71,SPARK_NEG_OK,1.026771,1.019992,0.852468,0.885863,SOFT_START,469,70,SPARK_NEG_OK,1.057974,0.979553,0.925345,1.138719,SOFT_START,1256,2396,0 -198683897,470,70,SPARK_NEG_OK,1.029617,1.022981,0.859785,0.892249,SOFT_START,470,70,SPARK_NEG_OK,1.059937,0.983578,0.930845,1.138595,SOFT_START,1257,2392,0 -198731897,471,71,SPARK_NEG_OK,1.032406,1.025834,0.866962,0.898444,SOFT_START,471,71,SPARK_NEG_OK,1.061925,0.987495,0.936190,1.138741,SOFT_START,1257,2393,0 -198779897,472,70,SPARK_NEG_OK,1.035117,1.028681,0.873880,0.904470,SOFT_START,472,70,SPARK_NEG_OK,1.063795,0.991260,0.941454,1.138520,SOFT_START,1258,2401,0 -198826897,473,71,SPARK_NEG_OK,1.037666,1.031381,0.880714,0.910354,SOFT_START,473,70,SPARK_NEG_OK,1.065649,0.995018,0.946509,1.138749,SOFT_START,1256,2381,0 -198874897,474,70,SPARK_NEG_OK,1.040186,1.034034,0.887304,0.916088,SOFT_START,474,70,SPARK_NEG_OK,1.067454,0.998622,0.951377,1.138802,SOFT_START,1258,2396,0 -198922897,475,71,SPARK_NEG_OK,1.042747,1.036620,0.893693,0.921721,SOFT_START,475,70,SPARK_NEG_OK,1.069213,1.002159,0.956199,1.138736,SOFT_START,1256,2399,0 -198970897,476,70,SPARK_NEG_OK,1.045139,1.039166,0.900021,0.927205,SOFT_START,476,70,SPARK_NEG_OK,1.070951,1.005632,0.960873,1.138778,SOFT_START,1256,2387,0 -199017897,477,71,SPARK_NEG_OK,1.047575,1.041696,0.906057,0.932533,SOFT_START,477,68,SPARK_NEG_OK,1.072591,1.008968,0.965450,1.138802,SOFT_START,1255,2404,0 -199065897,478,70,SPARK_NEG_OK,1.049927,1.044093,0.911966,0.937669,SOFT_START,478,70,SPARK_NEG_OK,1.074216,1.012245,0.969922,1.138794,SOFT_START,1256,2405,0 -199113897,479,70,SPARK_NEG_OK,1.052106,1.046392,0.917790,0.942686,SOFT_START,479,71,SPARK_NEG_OK,1.075827,1.015409,0.974250,1.138965,SOFT_START,1255,2382,0 -199161897,480,70,SPARK_NEG_OK,1.054415,1.048661,0.923340,0.947649,SOFT_START,480,70,SPARK_NEG_OK,1.077308,1.018512,0.978477,1.138893,SOFT_START,1257,2410,0 -199208897,481,70,SPARK_NEG_OK,1.056542,1.050912,0.928867,0.952318,SOFT_START,481,71,SPARK_NEG_OK,1.078835,1.021546,0.982547,1.138763,SOFT_START,1257,2393,0 -199256897,482,70,SPARK_NEG_OK,1.058652,1.053063,0.934328,0.957001,SOFT_START,482,70,SPARK_NEG_OK,1.080312,1.024505,0.986578,1.138800,SOFT_START,1258,2401,0 -199304897,483,70,SPARK_NEG_OK,1.060624,1.055197,0.939485,0.961571,SOFT_START,483,71,SPARK_NEG_OK,1.081753,1.027358,0.990457,1.138735,SOFT_START,1259,2381,0 -199351897,484,70,SPARK_NEG_OK,1.062620,1.057284,0.944619,0.965979,SOFT_START,484,70,SPARK_NEG_OK,1.083105,1.030152,0.994279,1.138887,SOFT_START,1258,2402,0 -199399897,485,70,SPARK_NEG_OK,1.064650,1.059279,0.949562,0.970278,SOFT_START,485,71,SPARK_NEG_OK,1.084507,1.032863,0.997985,1.138619,SOFT_START,1259,2409,0 -199447897,486,70,SPARK_NEG_OK,1.066502,1.061223,0.954372,0.974510,SOFT_START,486,70,SPARK_NEG_OK,1.085833,1.035513,1.001592,1.138877,SOFT_START,1256,2404,0 -199494897,487,70,SPARK_NEG_OK,1.068381,1.063136,0.959049,0.978616,SOFT_START,487,71,SPARK_NEG_OK,1.087151,1.038102,1.005077,1.138884,SOFT_START,1257,2397,0 -199542897,488,70,SPARK_NEG_OK,1.070222,1.064984,0.963625,0.982598,SOFT_START,488,70,SPARK_NEG_OK,1.088380,1.040629,1.008493,1.138843,SOFT_START,1256,2401,0 -199590897,489,70,SPARK_NEG_OK,1.071929,1.066837,0.968059,0.986540,SOFT_START,489,71,SPARK_NEG_OK,1.089634,1.043045,1.011835,1.138870,SOFT_START,1256,2388,0 -199638897,490,70,SPARK_NEG_OK,1.073522,1.068571,0.972405,0.990316,SOFT_START,490,70,SPARK_NEG_OK,1.090859,1.045417,1.015100,1.138884,SOFT_START,1255,2379,0 -199685897,491,70,SPARK_NEG_OK,1.075127,1.070310,0.976613,0.994056,SOFT_START,491,69,SPARK_NEG_OK,1.092004,1.047779,1.018229,1.138948,SOFT_START,1257,2386,0 -199733897,492,70,SPARK_NEG_OK,1.076706,1.071989,0.980760,0.997673,SOFT_START,492,70,SPARK_NEG_OK,1.093139,1.050047,1.021312,1.138892,SOFT_START,1256,2397,0 -199781897,493,70,SPARK_NEG_OK,1.078337,1.073658,0.984789,1.001220,SOFT_START,493,70,SPARK_NEG_OK,1.094322,1.052256,1.024339,1.138899,SOFT_START,1258,2411,0 -199829897,494,71,SPARK_NEG_OK,1.079882,1.075291,0.988694,1.004609,SOFT_START,494,70,SPARK_NEG_OK,1.095378,1.054404,1.027223,1.138871,SOFT_START,1258,2399,0 -199876897,495,70,SPARK_NEG_OK,1.081359,1.076829,0.992493,1.007938,SOFT_START,495,70,SPARK_NEG_OK,1.096408,1.056505,1.030062,1.138875,SOFT_START,1256,2392,0 -199924897,496,71,SPARK_NEG_OK,1.082857,1.078333,0.996218,1.011209,SOFT_START,496,70,SPARK_NEG_OK,1.097444,1.058553,1.032846,1.138789,SOFT_START,1257,2407,0 -199972897,497,70,SPARK_NEG_OK,1.084253,1.079819,0.999807,1.014365,SOFT_START,497,70,SPARK_NEG_OK,1.098434,1.060597,1.035516,1.138882,SOFT_START,1254,2407,0 -200020897,498,71,SPARK_NEG_OK,1.085703,1.081288,1.003265,1.017464,SOFT_START,498,71,SPARK_NEG_OK,1.099413,1.062520,1.038158,1.138892,SOFT_START,1256,2407,0 -200068897,499,70,SPARK_NEG_OK,1.087030,1.082680,1.006688,1.020468,SOFT_START,499,70,SPARK_NEG_OK,1.100335,1.064399,1.040694,1.138884,SOFT_START,1254,2404,0 -200115897,500,71,SPARK_NEG_OK,1.088346,1.084013,1.010080,1.023328,SOFT_START,500,70,SPARK_NEG_OK,1.101301,1.066244,1.043216,1.138926,SOFT_START,1254,2406,0 -200163897,501,70,SPARK_NEG_OK,1.089662,1.085361,1.013315,1.026210,SOFT_START,501,70,SPARK_NEG_OK,1.102178,1.068069,1.045630,1.138916,SOFT_START,1253,2403,0 -200211897,502,71,SPARK_NEG_OK,1.090860,1.086680,1.016490,1.029004,SOFT_START,502,70,SPARK_NEG_OK,1.103074,1.069821,1.047994,1.138919,SOFT_START,1255,2384,0 -200259897,503,70,SPARK_NEG_OK,1.092005,1.087983,1.019544,1.031712,SOFT_START,503,70,SPARK_NEG_OK,1.103947,1.071544,1.050300,1.138840,SOFT_START,1254,2387,0 -200307897,504,71,SPARK_NEG_OK,1.093218,1.089222,1.022528,1.034365,SOFT_START,504,68,SPARK_NEG_OK,1.104780,1.073183,1.052552,1.138921,SOFT_START,1256,2408,0 -200354897,505,70,SPARK_NEG_OK,1.094334,1.090431,1.025525,1.036956,SOFT_START,505,70,SPARK_NEG_OK,1.105585,1.074843,1.054726,1.138817,SOFT_START,1256,2379,0 -200402897,506,71,SPARK_NEG_OK,1.095472,1.091625,1.028365,1.039474,SOFT_START,506,70,SPARK_NEG_OK,1.106395,1.076389,1.056848,1.138862,SOFT_START,1255,2401,0 -200450897,507,70,SPARK_NEG_OK,1.096483,1.092761,1.031119,1.041970,SOFT_START,507,70,SPARK_NEG_OK,1.107152,1.077968,1.058919,1.138759,SOFT_START,1256,2397,0 -200498897,508,70,SPARK_NEG_OK,1.097583,1.093895,1.033847,1.044332,SOFT_START,508,70,SPARK_NEG_OK,1.107902,1.079450,1.060951,1.138824,SOFT_START,1253,2404,0 -200546897,509,70,SPARK_NEG_OK,1.098644,1.094969,1.036481,1.046677,SOFT_START,509,80,SPARK_NEG_OK,1.108671,1.080885,1.062919,1.138581,SOFT_START,1254,2409,0 -200593897,510,80,SPARK_NEG_OK,1.099628,1.096037,1.039064,1.048962,SOFT_START,510,81,SPARK_NEG_OK,1.109383,1.082374,1.064863,1.138833,SOFT_START,1252,2391,0 -200641897,511,80,SPARK_NEG_OK,1.100538,1.097053,1.041567,1.051172,SOFT_START,511,80,SPARK_NEG_OK,1.110090,1.083744,1.066708,1.138848,SOFT_START,1254,2383,0 -200689897,512,70,SPARK_NEG_OK,1.101493,1.098135,1.044021,1.053308,SOFT_START,512,71,SPARK_NEG_OK,1.110775,1.085066,1.068553,1.138845,SOFT_START,1253,2383,0 -200737897,513,70,SPARK_NEG_OK,1.102372,1.099089,1.046416,1.055438,SOFT_START,513,70,SPARK_NEG_OK,1.111474,1.086422,1.070324,1.138824,SOFT_START,1254,2391,0 -200785897,514,80,SPARK_NEG_OK,1.103214,1.100050,1.048707,1.057488,SOFT_START,514,81,SPARK_NEG_OK,1.112085,1.087756,1.072024,1.138831,SOFT_START,1253,2378,0 -200833897,515,80,SPARK_NEG_OK,1.104085,1.100979,1.050979,1.059471,SOFT_START,515,80,SPARK_NEG_OK,1.112735,1.089014,1.073769,1.138822,SOFT_START,1255,2393,0 -200880897,516,70,SPARK_NEG_OK,1.104988,1.101883,1.053209,1.061469,SOFT_START,516,71,SPARK_NEG_OK,1.113369,1.090220,1.075408,1.138798,SOFT_START,1254,2399,0 -200928897,517,70,SPARK_NEG_OK,1.105760,1.102788,1.055311,1.063389,SOFT_START,517,70,SPARK_NEG_OK,1.113955,1.091417,1.077015,1.138873,SOFT_START,1255,2380,0 -200976897,518,70,SPARK_NEG_OK,1.106611,1.103647,1.057402,1.065237,SOFT_START,518,71,SPARK_NEG_OK,1.114541,1.092560,1.078509,1.138787,SOFT_START,1255,2380,0 -201024897,519,70,SPARK_NEG_OK,1.107370,1.104487,1.059424,1.067051,SOFT_START,519,70,SPARK_NEG_OK,1.115107,1.093731,1.080037,1.138859,SOFT_START,1252,2401,0 -201072897,520,70,SPARK_NEG_OK,1.108094,1.105347,1.061434,1.068819,SOFT_START,520,71,SPARK_NEG_OK,1.115653,1.094762,1.081535,1.138700,SOFT_START,1254,2385,0 -201120897,521,70,SPARK_NEG_OK,1.108882,1.106136,1.063333,1.070519,SOFT_START,521,70,SPARK_NEG_OK,1.116232,1.095880,1.082894,1.138834,SOFT_START,1251,2400,0 -201168897,522,70,SPARK_NEG_OK,1.109611,1.106956,1.065228,1.072187,SOFT_START,522,71,SPARK_NEG_OK,1.116765,1.096914,1.084377,1.138551,SOFT_START,1253,2396,0 -201216897,523,68,SPARK_NEG_OK,1.110393,1.107690,1.067030,1.073779,SOFT_START,523,70,SPARK_NEG_OK,1.117291,1.097961,1.085720,1.138756,SOFT_START,1251,2411,0 -201263897,524,70,SPARK_NEG_OK,1.111047,1.108446,1.068894,1.075400,SOFT_START,524,71,SPARK_NEG_OK,1.117790,1.098970,1.087092,1.138818,SOFT_START,1253,2391,0 -201311897,525,70,SPARK_NEG_OK,1.111712,1.109200,1.070623,1.076945,SOFT_START,525,70,SPARK_NEG_OK,1.118264,1.099969,1.088384,1.138778,SOFT_START,1252,2383,0 -201359897,526,70,SPARK_NEG_OK,1.112347,1.109911,1.072314,1.078471,SOFT_START,526,71,SPARK_NEG_OK,1.118742,1.100888,1.089628,1.138970,SOFT_START,1254,2388,0 -201407897,527,80,SPARK_NEG_OK,1.112952,1.110553,1.074007,1.079976,SOFT_START,527,80,SPARK_NEG_OK,1.119235,1.101813,1.090854,1.138966,SOFT_START,1253,2391,0 -201455897,528,80,SPARK_NEG_OK,1.113597,1.111251,1.075578,1.081411,SOFT_START,528,81,SPARK_NEG_OK,1.119695,1.102700,1.092065,1.138864,SOFT_START,1255,2383,0 -201503897,529,81,SPARK_NEG_OK,1.114163,1.111869,1.077154,1.082782,SOFT_START,529,80,SPARK_NEG_OK,1.120153,1.103555,1.093213,1.138805,SOFT_START,1253,2388,0 -201550897,530,80,SPARK_NEG_OK,1.114832,1.112595,1.078709,1.084148,SOFT_START,530,81,SPARK_NEG_OK,1.120566,1.104442,1.094389,1.138831,SOFT_START,1254,2409,0 -201598897,531,80,SPARK_NEG_OK,1.115439,1.113194,1.080167,1.085449,SOFT_START,531,70,SPARK_NEG_OK,1.121023,1.105274,1.095546,1.138757,SOFT_START,1254,2402,0 -201646897,532,70,SPARK_NEG_OK,1.115975,1.113811,1.081679,1.086762,SOFT_START,532,71,SPARK_NEG_OK,1.121441,1.106076,1.096582,1.138828,SOFT_START,1251,2383,0 -201694897,533,70,SPARK_NEG_OK,1.116499,1.114403,1.083114,1.088068,SOFT_START,533,80,SPARK_NEG_OK,1.121813,1.106853,1.097677,1.138723,SOFT_START,1252,2380,0 -201742897,534,80,SPARK_NEG_OK,1.117015,1.114991,1.084445,1.089289,SOFT_START,534,80,SPARK_NEG_OK,1.122192,1.107674,1.098652,1.138834,SOFT_START,1252,2380,0 -201790897,535,81,SPARK_NEG_OK,1.117530,1.115546,1.085800,1.090488,SOFT_START,535,70,SPARK_NEG_OK,1.122588,1.108392,1.099638,1.138642,SOFT_START,1253,2405,0 -201838897,536,71,SPARK_NEG_OK,1.118104,1.116104,1.087092,1.091663,SOFT_START,536,70,SPARK_NEG_OK,1.122990,1.109141,1.100665,1.139036,SOFT_START,1253,2398,0 -201886897,537,71,SPARK_NEG_OK,1.118549,1.116635,1.088361,1.092771,SOFT_START,537,70,SPARK_NEG_OK,1.123285,1.109860,1.101645,1.138850,SOFT_START,1255,2394,0 -201933897,538,70,SPARK_NEG_OK,1.119111,1.117174,1.089655,1.093875,SOFT_START,538,70,SPARK_NEG_OK,1.123696,1.110489,1.102509,1.138873,SOFT_START,1253,2403,0 -201981897,539,71,SPARK_NEG_OK,1.119568,1.117647,1.090816,1.095059,SOFT_START,539,70,SPARK_NEG_OK,1.124062,1.111242,1.103415,1.138797,SOFT_START,1255,2397,0 -202029897,540,80,SPARK_NEG_OK,1.120059,1.118185,1.092016,1.096061,SOFT_START,540,80,SPARK_NEG_OK,1.124328,1.111915,1.104305,1.138807,SOFT_START,1253,2392,0 -202077897,541,79,SPARK_NEG_OK,1.120474,1.118659,1.093126,1.097113,SOFT_START,541,80,SPARK_NEG_OK,1.124708,1.112576,1.105129,1.138814,SOFT_START,1253,2378,0 -202125897,542,81,SPARK_NEG_OK,1.120901,1.119217,1.094308,1.098135,SOFT_START,542,81,SPARK_NEG_OK,1.124997,1.113158,1.105974,1.138845,SOFT_START,1254,2395,0 -202173897,543,81,SPARK_NEG_OK,1.121387,1.119600,1.095368,1.099109,SOFT_START,543,80,SPARK_NEG_OK,1.125306,1.113785,1.106868,1.138796,SOFT_START,1251,2410,0 -202221897,544,80,SPARK_NEG_OK,1.121778,1.120050,1.096434,1.100059,SOFT_START,544,70,SPARK_NEG_OK,1.125649,1.114410,1.107573,1.138732,SOFT_START,1253,2393,0 -202268897,545,71,SPARK_NEG_OK,1.122131,1.120490,1.097474,1.101034,SOFT_START,545,70,SPARK_NEG_OK,1.125904,1.114989,1.108328,1.138809,SOFT_START,1252,2394,0 -202316897,546,70,SPARK_NEG_OK,1.122556,1.120923,1.098465,1.101942,SOFT_START,546,80,SPARK_NEG_OK,1.126221,1.115513,1.109101,1.138626,SOFT_START,1253,2388,0 -202364897,547,81,SPARK_NEG_OK,1.122971,1.121345,1.099439,1.102881,SOFT_START,547,80,SPARK_NEG_OK,1.126502,1.116087,1.109859,1.138797,SOFT_START,1253,2395,0 -202412897,548,80,SPARK_NEG_OK,1.123367,1.121764,1.100420,1.103704,SOFT_START,548,80,SPARK_NEG_OK,1.126735,1.116588,1.110508,1.138771,SOFT_START,1254,2402,0 -202460897,549,81,SPARK_NEG_OK,1.123729,1.122118,1.101326,1.104504,SOFT_START,549,80,SPARK_NEG_OK,1.127037,1.117154,1.111209,1.138871,SOFT_START,1253,2413,0 -202508897,550,80,SPARK_NEG_OK,1.124052,1.122540,1.102247,1.105285,SOFT_START,550,80,SPARK_NEG_OK,1.127303,1.117652,1.111873,1.138899,SOFT_START,1255,2407,0 -202556897,551,71,SPARK_NEG_OK,1.124464,1.122864,1.103110,1.106164,SOFT_START,551,70,SPARK_NEG_OK,1.127528,1.118168,1.112547,1.138874,SOFT_START,1253,2408,0 -202603897,552,70,SPARK_NEG_OK,1.124817,1.123246,1.103999,1.106918,SOFT_START,552,70,SPARK_NEG_OK,1.127766,1.118714,1.113204,1.138896,SOFT_START,1254,2382,0 -202651897,553,71,SPARK_NEG_OK,1.125109,1.123635,1.104894,1.107679,SOFT_START,553,70,SPARK_NEG_OK,1.128072,1.119144,1.113821,1.138880,SOFT_START,1252,2379,0 -202699897,554,70,SPARK_NEG_OK,1.125482,1.123979,1.105682,1.108425,SOFT_START,554,70,SPARK_NEG_OK,1.128288,1.119595,1.114442,1.138847,SOFT_START,1253,2394,0 -202747897,555,71,SPARK_NEG_OK,1.125780,1.124310,1.106517,1.109173,SOFT_START,555,70,SPARK_NEG_OK,1.128522,1.120074,1.115050,1.138802,SOFT_START,1252,2391,0 -202795897,556,70,SPARK_NEG_OK,1.126087,1.124665,1.107286,1.109830,SOFT_START,556,70,SPARK_NEG_OK,1.128744,1.120507,1.115615,1.138902,SOFT_START,1251,2405,0 -202843897,557,71,SPARK_NEG_OK,1.126372,1.124983,1.108062,1.110542,SOFT_START,557,70,SPARK_NEG_OK,1.128954,1.120918,1.116185,1.138737,SOFT_START,1252,2393,0 -202891897,558,70,SPARK_NEG_OK,1.126746,1.125274,1.108785,1.111185,SOFT_START,558,70,SPARK_NEG_OK,1.129195,1.121339,1.116720,1.138896,SOFT_START,1253,2406,0 -202939897,559,71,SPARK_NEG_OK,1.126972,1.125579,1.109431,1.111852,SOFT_START,559,70,SPARK_NEG_OK,1.129389,1.121787,1.117278,1.138616,SOFT_START,1254,2383,0 -202986897,560,70,SPARK_NEG_OK,1.127256,1.125954,1.110200,1.112527,SOFT_START,560,70,SPARK_NEG_OK,1.129605,1.122178,1.117793,1.138837,SOFT_START,1254,2397,0 -203034897,561,70,SPARK_NEG_OK,1.127521,1.126215,1.110948,1.113124,SOFT_START,561,71,SPARK_NEG_OK,1.129785,1.122516,1.118301,1.138837,SOFT_START,1255,2377,0 -203082897,562,80,SPARK_NEG_OK,1.127763,1.126499,1.111594,1.113740,SOFT_START,562,80,SPARK_NEG_OK,1.129978,1.122965,1.118799,1.138864,SOFT_START,1254,2379,0 -203130897,563,82,SPARK_NEG_OK,1.128008,1.126766,1.112216,1.114309,SOFT_START,563,81,SPARK_NEG_OK,1.130173,1.123309,1.119263,1.138856,SOFT_START,1255,2405,0 -203178897,564,80,SPARK_NEG_OK,1.128282,1.127065,1.112880,1.114911,SOFT_START,564,80,SPARK_NEG_OK,1.130401,1.123667,1.119744,1.138949,SOFT_START,1253,2390,0 -203226897,565,77,SPARK_NEG_OK,1.128497,1.127325,1.113498,1.115477,SOFT_START,565,81,SPARK_NEG_OK,1.130569,1.124066,1.120234,1.139036,SOFT_START,1253,2390,0 -203274897,566,82,SPARK_NEG_OK,1.128756,1.127586,1.114134,1.116016,SOFT_START,566,80,SPARK_NEG_OK,1.130741,1.124399,1.120687,1.138871,SOFT_START,1252,2412,0 -203321897,567,80,SPARK_NEG_OK,1.129027,1.127842,1.114693,1.116534,SOFT_START,567,81,SPARK_NEG_OK,1.130925,1.124694,1.121141,1.138884,SOFT_START,1253,2408,0 -203369897,568,80,SPARK_NEG_OK,1.129220,1.128073,1.115343,1.117056,SOFT_START,568,70,SPARK_NEG_OK,1.131092,1.125062,1.121511,1.138843,SOFT_START,1253,2399,0 -203417897,569,70,SPARK_NEG_OK,1.129464,1.128345,1.115847,1.117597,SOFT_START,569,71,SPARK_NEG_OK,1.131223,1.125338,1.121945,1.138898,SOFT_START,1253,2393,0 -203465897,570,70,SPARK_NEG_OK,1.129640,1.128587,1.116409,1.118097,SOFT_START,570,70,SPARK_NEG_OK,1.131420,1.125678,1.122339,1.138816,SOFT_START,1255,2390,0 -203513897,571,70,SPARK_NEG_OK,1.129864,1.128784,1.116922,1.118577,SOFT_START,571,71,SPARK_NEG_OK,1.131573,1.125948,1.122746,1.138926,SOFT_START,1254,2390,0 -203560897,572,70,SPARK_NEG_OK,1.130129,1.129021,1.117457,1.119039,SOFT_START,572,70,SPARK_NEG_OK,1.131730,1.126280,1.123102,1.138676,SOFT_START,1256,2398,0 -203608897,573,70,SPARK_NEG_OK,1.130254,1.129213,1.117969,1.119496,SOFT_START,573,71,SPARK_NEG_OK,1.131891,1.126558,1.123507,1.138920,SOFT_START,1254,2379,0 -203656897,574,70,SPARK_NEG_OK,1.130479,1.129481,1.118445,1.119968,SOFT_START,574,70,SPARK_NEG_OK,1.132035,1.126829,1.123875,1.138936,SOFT_START,1255,2393,0 -203704897,575,80,SPARK_NEG_OK,1.130633,1.129645,1.118931,1.120403,SOFT_START,575,81,SPARK_NEG_OK,1.132177,1.127099,1.124249,1.138933,SOFT_START,1253,2386,0 -203752897,576,80,SPARK_NEG_OK,1.130868,1.129883,1.119400,1.120870,SOFT_START,576,80,SPARK_NEG_OK,1.132313,1.127391,1.124581,1.138894,SOFT_START,1254,2407,0 -203800897,577,70,SPARK_NEG_OK,1.131052,1.130082,1.119840,1.121246,SOFT_START,577,71,SPARK_NEG_OK,1.132451,1.127626,1.124902,1.138918,SOFT_START,1252,2388,0 -203848897,578,70,SPARK_NEG_OK,1.131209,1.130256,1.120329,1.121694,SOFT_START,578,70,SPARK_NEG_OK,1.132597,1.127908,1.125255,1.138948,SOFT_START,1254,2416,0 -203895897,579,80,SPARK_NEG_OK,1.131371,1.130462,1.120753,1.122053,SOFT_START,579,81,SPARK_NEG_OK,1.132736,1.128177,1.125531,1.138886,SOFT_START,1253,2395,0 -203943897,580,80,SPARK_NEG_OK,1.131585,1.130660,1.121199,1.122443,SOFT_START,580,80,SPARK_NEG_OK,1.132843,1.128360,1.125883,1.138901,SOFT_START,1255,2410,0 -203991897,581,79,SPARK_NEG_OK,1.131753,1.130794,1.121595,1.122828,SOFT_START,581,71,SPARK_NEG_OK,1.132978,1.128653,1.126165,1.138776,SOFT_START,1255,2403,0 -204039897,582,70,SPARK_NEG_OK,1.131896,1.131007,1.122040,1.123224,SOFT_START,582,70,SPARK_NEG_OK,1.133085,1.128849,1.126499,1.138889,SOFT_START,1255,2391,0 -204086897,583,70,SPARK_NEG_OK,1.132048,1.131191,1.122390,1.123527,SOFT_START,583,71,SPARK_NEG_OK,1.133176,1.129067,1.126790,1.138747,SOFT_START,1256,2396,0 -204134897,584,71,SPARK_NEG_OK,1.132182,1.131328,1.122783,1.123902,SOFT_START,584,70,SPARK_NEG_OK,1.133327,1.129296,1.127064,1.138871,SOFT_START,1255,2383,0 -204182897,585,70,SPARK_NEG_OK,1.132326,1.131483,1.123149,1.124233,SOFT_START,585,70,SPARK_NEG_OK,1.133432,1.129522,1.127334,1.138717,SOFT_START,1256,2391,0 -204230897,586,71,SPARK_NEG_OK,1.132447,1.131675,1.123508,1.124576,SOFT_START,586,70,SPARK_NEG_OK,1.133550,1.129704,1.127616,1.138788,SOFT_START,1253,2384,0 -204278897,587,70,SPARK_NEG_OK,1.132576,1.131840,1.123859,1.124949,SOFT_START,587,73,SPARK_NEG_OK,1.133661,1.129873,1.127878,1.138865,SOFT_START,1255,2409,0 -204326897,588,71,SPARK_NEG_OK,1.132775,1.132003,1.124236,1.125205,SOFT_START,588,70,SPARK_NEG_OK,1.133687,1.130081,1.128122,1.138859,SOFT_START,1253,2408,0 -204373897,589,70,SPARK_NEG_OK,1.132886,1.132116,1.124533,1.125501,SOFT_START,589,70,SPARK_NEG_OK,1.133823,1.130288,1.128405,1.138873,SOFT_START,1254,2408,0 -204421897,590,81,SPARK_NEG_OK,1.133031,1.132269,1.124906,1.125804,SOFT_START,590,80,SPARK_NEG_OK,1.133918,1.130489,1.128632,1.138848,SOFT_START,1254,2383,0 -204469897,591,80,SPARK_NEG_OK,1.133114,1.132400,1.125188,1.126098,SOFT_START,591,80,SPARK_NEG_OK,1.133995,1.130626,1.128935,1.138927,SOFT_START,1256,2378,0 -204517897,592,69,SPARK_NEG_OK,1.133261,1.132538,1.125499,1.126412,SOFT_START,592,70,SPARK_NEG_OK,1.134138,1.130829,1.129041,1.138785,SOFT_START,1256,2397,0 -204564897,593,70,SPARK_NEG_OK,1.133376,1.132649,1.125786,1.126693,SOFT_START,593,70,SPARK_NEG_OK,1.134183,1.131005,1.129361,1.138824,SOFT_START,1255,2404,0 -204612897,594,71,SPARK_NEG_OK,1.133503,1.132825,1.126093,1.126937,SOFT_START,594,70,SPARK_NEG_OK,1.134316,1.131185,1.129503,1.138696,SOFT_START,1257,2385,0 -204660897,595,70,SPARK_NEG_OK,1.133618,1.132931,1.126370,1.127225,SOFT_START,595,70,SPARK_NEG_OK,1.134375,1.131340,1.129751,1.138813,SOFT_START,1255,2407,0 -204708897,596,71,SPARK_NEG_OK,1.133702,1.133084,1.126682,1.127475,SOFT_START,596,70,SPARK_NEG_OK,1.134505,1.131500,1.129915,1.138619,SOFT_START,1256,2380,0 -204756897,597,72,SPARK_NEG_OK,1.133820,1.133178,1.126940,1.127722,SOFT_START,597,70,SPARK_NEG_OK,1.134550,1.131664,1.130131,1.138905,SOFT_START,1253,2408,0 -204803897,598,71,SPARK_NEG_OK,1.133943,1.133238,1.127186,1.127970,SOFT_START,598,70,SPARK_NEG_OK,1.134608,1.131836,1.130339,1.138842,SOFT_START,1255,2401,0 -204851897,599,70,SPARK_NEG_OK,1.134033,1.133389,1.127473,1.128185,SOFT_START,599,70,SPARK_NEG_OK,1.134678,1.131936,1.130502,1.138830,SOFT_START,1253,2392,0 -204899897,600,71,SPARK_NEG_OK,1.134166,1.133459,1.127691,1.128410,SOFT_START,600,70,SPARK_NEG_OK,1.134800,1.132101,1.130686,1.138820,SOFT_START,1254,2399,0 -204947897,601,70,SPARK_NEG_OK,1.134239,1.133617,1.127937,1.128651,SOFT_START,601,70,SPARK_NEG_OK,1.134834,1.132230,1.130866,1.138802,SOFT_START,1253,2397,0 -204995897,602,71,SPARK_NEG_OK,1.134290,1.133719,1.128195,1.128885,SOFT_START,602,72,SPARK_NEG_OK,1.134951,1.132371,1.131055,1.138833,SOFT_START,1255,2408,0 -205042897,603,70,SPARK_NEG_OK,1.134422,1.133826,1.128433,1.129097,SOFT_START,603,70,SPARK_NEG_OK,1.134976,1.132500,1.131225,1.138776,SOFT_START,1255,2407,0 -205090897,604,70,SPARK_NEG_OK,1.134560,1.133960,1.128629,1.129293,SOFT_START,604,71,SPARK_NEG_OK,1.135051,1.132664,1.131401,1.138805,SOFT_START,1258,2388,0 -205138897,605,70,SPARK_NEG_OK,1.134604,1.134044,1.128886,1.129477,SOFT_START,605,70,SPARK_NEG_OK,1.135131,1.132760,1.131556,1.138778,SOFT_START,1258,2409,0 -205186897,606,72,SPARK_NEG_OK,1.134708,1.134147,1.129117,1.129703,SOFT_START,606,71,SPARK_NEG_OK,1.135171,1.132931,1.131679,1.138850,SOFT_START,1256,2408,0 -205233897,607,70,SPARK_NEG_OK,1.134787,1.134223,1.129311,1.129915,SOFT_START,607,70,SPARK_NEG_OK,1.135274,1.133052,1.131873,1.138710,SOFT_START,1257,2384,0 -205281897,608,70,SPARK_NEG_OK,1.134865,1.134356,1.129528,1.130109,SOFT_START,608,71,SPARK_NEG_OK,1.135339,1.133137,1.132033,1.138831,SOFT_START,1254,2384,0 -205329897,609,70,SPARK_NEG_OK,1.134943,1.134419,1.129721,1.130335,SOFT_START,609,70,SPARK_NEG_OK,1.135429,1.133248,1.132148,1.138665,SOFT_START,1256,2377,0 -205377897,610,70,SPARK_NEG_OK,1.135026,1.134529,1.129931,1.130496,SOFT_START,610,71,SPARK_NEG_OK,1.135463,1.133364,1.132323,1.138867,SOFT_START,1254,2409,0 -205425897,611,70,SPARK_NEG_OK,1.135066,1.134599,1.130127,1.130676,SOFT_START,611,70,SPARK_NEG_OK,1.135522,1.133486,1.132442,1.138880,SOFT_START,1255,2406,0 -205472897,612,70,SPARK_NEG_OK,1.135182,1.134692,1.130301,1.130835,SOFT_START,612,71,SPARK_NEG_OK,1.135612,1.133574,1.132601,1.138867,SOFT_START,1254,2388,0 -205520897,613,70,SPARK_NEG_OK,1.135260,1.134777,1.130508,1.130986,SOFT_START,613,70,SPARK_NEG_OK,1.135617,1.133719,1.132755,1.138851,SOFT_START,1256,2389,0 -205568897,614,70,SPARK_NEG_OK,1.135315,1.134852,1.130677,1.131207,SOFT_START,614,71,SPARK_NEG_OK,1.135724,1.133778,1.132845,1.138829,SOFT_START,1255,2411,0 -205616897,615,70,SPARK_NEG_OK,1.135399,1.134927,1.130881,1.131350,SOFT_START,615,70,SPARK_NEG_OK,1.135759,1.133909,1.133006,1.138879,SOFT_START,1257,2386,0 -205663897,616,79,SPARK_NEG_OK,1.135495,1.134959,1.131017,1.131487,SOFT_START,616,81,SPARK_NEG_OK,1.135787,1.133997,1.133127,1.138874,SOFT_START,1255,2399,0 -205711897,617,80,SPARK_NEG_OK,1.135520,1.135067,1.131204,1.131659,SOFT_START,617,80,SPARK_NEG_OK,1.135874,1.134105,1.133274,1.138873,SOFT_START,1257,2407,0 -205759897,618,80,SPARK_NEG_OK,1.135619,1.135129,1.131348,1.131824,SOFT_START,618,81,SPARK_NEG_OK,1.135916,1.134202,1.133389,1.138812,SOFT_START,1257,2384,0 -205807897,619,80,SPARK_NEG_OK,1.135651,1.135225,1.131532,1.131940,SOFT_START,619,82,SPARK_NEG_OK,1.135957,1.134341,1.133502,1.138892,SOFT_START,1253,2383,0 -205855897,620,80,SPARK_NEG_OK,1.135715,1.135327,1.131660,1.132147,SOFT_START,620,71,SPARK_NEG_OK,1.136003,1.134349,1.133665,1.138714,SOFT_START,1255,2395,0 -205902897,621,70,SPARK_NEG_OK,1.135788,1.135347,1.131834,1.132263,SOFT_START,621,70,SPARK_NEG_OK,1.136041,1.134463,1.133713,1.138917,SOFT_START,1253,2404,0 -205950897,622,70,SPARK_NEG_OK,1.135820,1.135389,1.131979,1.132408,SOFT_START,622,69,SPARK_NEG_OK,1.136087,1.134558,1.133811,1.138713,SOFT_START,1254,2402,0 -205998897,623,71,SPARK_NEG_OK,1.135876,1.135477,1.132106,1.132482,SOFT_START,623,70,SPARK_NEG_OK,1.136100,1.134619,1.133996,1.138872,SOFT_START,1253,2398,0 -206046897,624,70,SPARK_NEG_OK,1.135936,1.135568,1.132252,1.132615,SOFT_START,624,70,SPARK_NEG_OK,1.136187,1.134738,1.134033,1.138862,SOFT_START,1255,2392,0 -206094897,625,71,SPARK_NEG_OK,1.135975,1.135554,1.132411,1.132753,SOFT_START,625,70,SPARK_NEG_OK,1.136206,1.134777,1.134079,1.138827,SOFT_START,1254,2395,0 -206141897,626,70,SPARK_NEG_OK,1.136060,1.135671,1.132526,1.132892,SOFT_START,626,70,SPARK_NEG_OK,1.136236,1.134861,1.134246,1.138902,SOFT_START,1256,2382,0 -206189897,627,71,SPARK_NEG_OK,1.136098,1.135743,1.132665,1.133006,SOFT_START,627,70,SPARK_NEG_OK,1.136296,1.134892,1.134322,1.138861,SOFT_START,1255,2401,0 -206237897,628,70,SPARK_NEG_OK,1.136178,1.135821,1.132780,1.133171,SOFT_START,628,70,SPARK_NEG_OK,1.136329,1.135037,1.134430,1.138902,SOFT_START,1256,2400,0 -206285897,629,69,SPARK_NEG_OK,1.136190,1.135806,1.132932,1.133249,SOFT_START,629,68,SPARK_NEG_OK,1.136373,1.135075,1.134543,1.138810,SOFT_START,1256,2388,0 -206333897,630,70,SPARK_NEG_OK,1.136256,1.135892,1.133022,1.133398,SOFT_START,630,70,SPARK_NEG_OK,1.136389,1.135152,1.134625,1.138916,SOFT_START,1253,2395,0 -206381897,631,71,SPARK_NEG_OK,1.136281,1.135964,1.133145,1.133482,SOFT_START,631,70,SPARK_NEG_OK,1.136442,1.135265,1.134719,1.138995,SOFT_START,1254,2410,0 -206428897,632,70,SPARK_NEG_OK,1.136367,1.135965,1.133221,1.133585,SOFT_START,632,70,SPARK_NEG_OK,1.136491,1.135330,1.134806,1.139027,SOFT_START,1252,2396,0 -206476897,633,71,SPARK_NEG_OK,1.136441,1.136047,1.133353,1.133731,SOFT_START,633,70,SPARK_NEG_OK,1.136546,1.135391,1.134880,1.138713,SOFT_START,1254,2377,0 -206524897,634,70,SPARK_NEG_OK,1.136444,1.136106,1.133487,1.133835,SOFT_START,634,70,SPARK_NEG_OK,1.136540,1.135456,1.134954,1.138911,SOFT_START,1253,2384,0 -206572897,635,71,SPARK_NEG_OK,1.136501,1.136176,1.133603,1.133894,SOFT_START,635,70,SPARK_NEG_OK,1.136585,1.135475,1.135038,1.138917,SOFT_START,1254,2390,0 -206620897,636,68,SPARK_NEG_OK,1.136528,1.136224,1.133661,1.133976,SOFT_START,636,70,SPARK_NEG_OK,1.136616,1.135532,1.135086,1.138950,SOFT_START,1253,2402,0 -206668897,637,71,SPARK_NEG_OK,1.136578,1.136293,1.133782,1.134093,SOFT_START,637,70,SPARK_NEG_OK,1.136661,1.135601,1.135119,1.138937,SOFT_START,1255,2398,0 -206715897,638,70,SPARK_NEG_OK,1.136572,1.136293,1.133899,1.134155,SOFT_START,638,70,SPARK_NEG_OK,1.136705,1.135700,1.135234,1.138884,SOFT_START,1253,2400,0 -206763897,639,71,SPARK_NEG_OK,1.136661,1.136320,1.134009,1.134276,SOFT_START,639,70,SPARK_NEG_OK,1.136727,1.135731,1.135298,1.138865,SOFT_START,1254,2388,0 -206811897,640,70,SPARK_NEG_OK,1.136684,1.136315,1.134021,1.134324,SOFT_START,640,70,SPARK_NEG_OK,1.136751,1.135793,1.135439,1.138874,SOFT_START,1251,2377,0 -206859897,641,71,SPARK_NEG_OK,1.136736,1.136401,1.134177,1.134433,SOFT_START,641,70,SPARK_NEG_OK,1.136810,1.135805,1.135440,1.138849,SOFT_START,1251,2386,0 -206907897,642,70,SPARK_NEG_OK,1.136760,1.136377,1.134238,1.134508,SOFT_START,642,70,SPARK_NEG_OK,1.136824,1.135889,1.135496,1.138819,SOFT_START,1252,2403,0 -206955897,643,71,SPARK_NEG_OK,1.136823,1.136481,1.134346,1.134581,SOFT_START,643,70,SPARK_NEG_OK,1.136829,1.135958,1.135588,1.138839,SOFT_START,1248,2396,0 -207003897,644,70,SPARK_NEG_OK,1.136875,1.136538,1.134424,1.134701,SOFT_START,644,70,SPARK_NEG_OK,1.136903,1.135998,1.135640,1.138859,SOFT_START,1250,2407,0 -207051897,645,71,SPARK_NEG_OK,1.136889,1.136612,1.134498,1.134824,SOFT_START,645,70,SPARK_NEG_OK,1.136884,1.136024,1.135685,1.138971,SOFT_START,1248,2401,0 -207099897,646,70,SPARK_NEG_OK,1.136907,1.136622,1.134619,1.134846,SOFT_START,646,70,SPARK_NEG_OK,1.136922,1.136099,1.135741,1.138781,SOFT_START,1250,2400,0 -207147897,647,71,SPARK_NEG_OK,1.136925,1.136633,1.134694,1.134923,SOFT_START,647,70,SPARK_NEG_OK,1.136970,1.136153,1.135821,1.138911,SOFT_START,1249,2399,0 -207195897,648,70,SPARK_NEG_OK,1.136994,1.136702,1.134779,1.134986,SOFT_START,648,70,SPARK_NEG_OK,1.136993,1.136173,1.135860,1.138910,SOFT_START,1251,2400,0 -207243897,649,71,SPARK_NEG_OK,1.137035,1.136782,1.134806,1.135014,SOFT_START,649,70,SPARK_NEG_OK,1.136991,1.136198,1.135871,1.138946,SOFT_START,1249,2397,0 -207291897,650,70,SPARK_NEG_OK,1.137052,1.136751,1.134884,1.135129,SOFT_START,650,70,SPARK_NEG_OK,1.137061,1.136202,1.135965,1.139167,SOFT_START,1250,2410,0 -207339897,651,71,SPARK_NEG_OK,1.137053,1.136799,1.135005,1.135190,SOFT_START,651,70,SPARK_NEG_OK,1.137055,1.136305,1.136019,1.139131,SOFT_START,1248,2395,0 -207387897,652,70,SPARK_NEG_OK,1.137114,1.136843,1.135079,1.135268,SOFT_START,652,70,SPARK_NEG_OK,1.137056,1.136323,1.136070,1.138959,SOFT_START,1248,2395,0 -207436897,653,71,SPARK_NEG_OK,1.137147,1.136870,1.135135,1.135329,SOFT_START,653,70,SPARK_NEG_OK,1.137103,1.136361,1.136140,1.138963,SOFT_START,1246,2391,0 -207484897,654,70,SPARK_NEG_OK,1.137186,1.136910,1.135207,1.135374,SOFT_START,654,70,SPARK_NEG_OK,1.137115,1.136386,1.136172,1.138939,SOFT_START,1246,2393,0 -207532897,655,71,SPARK_NEG_OK,1.137220,1.136937,1.135207,1.135443,SOFT_START,655,70,SPARK_NEG_OK,1.137133,1.136455,1.136222,1.138845,SOFT_START,1246,2384,0 -207580897,656,70,SPARK_NEG_OK,1.137244,1.136963,1.135340,1.135508,SOFT_START,656,70,SPARK_NEG_OK,1.137129,1.136511,1.136242,1.138897,SOFT_START,1245,2390,0 -207628897,657,71,SPARK_NEG_OK,1.137260,1.137051,1.135381,1.135535,SOFT_START,657,70,SPARK_NEG_OK,1.137165,1.136539,1.136326,1.138820,SOFT_START,1246,2400,0 -207676897,658,70,SPARK_NEG_OK,1.137275,1.137039,1.135451,1.135614,SOFT_START,658,70,SPARK_NEG_OK,1.137177,1.136581,1.136347,1.138896,SOFT_START,1246,2383,0 -207724897,659,71,SPARK_NEG_OK,1.137291,1.137071,1.135532,1.135697,SOFT_START,659,70,SPARK_NEG_OK,1.137220,1.136616,1.136430,1.138723,SOFT_START,1247,2390,0 -207772897,660,70,SPARK_NEG_OK,1.137345,1.137084,1.135578,1.135753,SOFT_START,660,70,SPARK_NEG_OK,1.137217,1.136657,1.136453,1.138899,SOFT_START,1247,2390,0 -207820897,661,71,SPARK_NEG_OK,1.137336,1.137136,1.135653,1.135782,SOFT_START,661,71,SPARK_NEG_OK,1.137232,1.136684,1.136476,1.138793,SOFT_START,1248,2389,0 -207869897,662,70,SPARK_NEG_OK,1.137339,1.137162,1.135653,1.135827,SOFT_START,662,70,SPARK_NEG_OK,1.137230,1.136649,1.136519,1.138955,SOFT_START,1246,2394,0 -207917897,663,71,SPARK_NEG_OK,1.137378,1.137158,1.135715,1.135840,SOFT_START,663,70,SPARK_NEG_OK,1.137323,1.136763,1.136547,1.138941,SOFT_START,1246,2382,0 -207965897,664,70,SPARK_NEG_OK,1.137402,1.137172,1.135809,1.135924,SOFT_START,664,70,SPARK_NEG_OK,1.137288,1.136780,1.136626,1.138881,SOFT_START,1244,2405,0 -208013897,665,71,SPARK_NEG_OK,1.137406,1.137213,1.135818,1.135986,SOFT_START,665,70,SPARK_NEG_OK,1.137280,1.136815,1.136605,1.138930,SOFT_START,1244,2381,0 -208062897,666,70,SPARK_NEG_OK,1.137441,1.137217,1.135890,1.136030,SOFT_START,666,70,SPARK_NEG_OK,1.137332,1.136788,1.136665,1.138889,SOFT_START,1242,2383,0 -208110897,667,71,SPARK_NEG_OK,1.137428,1.137276,1.135906,1.136067,SOFT_START,667,70,SPARK_NEG_OK,1.137349,1.136858,1.136656,1.138921,SOFT_START,1243,2404,0 -208158897,668,71,SPARK_NEG_OK,1.137445,1.137310,1.135996,1.136121,SOFT_START,668,70,SPARK_NEG_OK,1.137372,1.136899,1.136745,1.138875,SOFT_START,1243,2401,0 -208206897,669,71,SPARK_NEG_OK,1.137513,1.137339,1.136035,1.136145,SOFT_START,669,70,SPARK_NEG_OK,1.137406,1.136923,1.136765,1.138910,SOFT_START,1245,2382,0 -208254897,670,70,SPARK_NEG_OK,1.137507,1.137315,1.136053,1.136214,SOFT_START,670,71,SPARK_NEG_OK,1.137404,1.136933,1.136842,1.138818,SOFT_START,1245,2390,0 -208303897,671,71,SPARK_NEG_OK,1.137514,1.137354,1.136136,1.136269,SOFT_START,671,70,SPARK_NEG_OK,1.137457,1.136939,1.136837,1.138895,SOFT_START,1244,2390,0 -208351897,672,70,SPARK_NEG_OK,1.137560,1.137413,1.136165,1.136279,SOFT_START,672,71,SPARK_NEG_OK,1.137465,1.137029,1.136847,1.138875,SOFT_START,1245,2410,0 -208399897,673,70,SPARK_NEG_OK,1.137582,1.137403,1.136202,1.136299,SOFT_START,673,70,SPARK_NEG_OK,1.137475,1.137018,1.136890,1.138923,SOFT_START,1242,2386,0 -208447897,674,70,SPARK_NEG_OK,1.137592,1.137396,1.136280,1.136379,SOFT_START,674,70,SPARK_NEG_OK,1.137473,1.137047,1.136881,1.138676,SOFT_START,1244,2410,0 -208496897,675,70,SPARK_NEG_OK,1.137592,1.137460,1.136273,1.136407,SOFT_START,675,70,SPARK_NEG_OK,1.137475,1.137080,1.136939,1.138871,SOFT_START,1241,2392,0 -208544897,676,70,SPARK_NEG_OK,1.137590,1.137447,1.136316,1.136456,SOFT_START,676,71,SPARK_NEG_OK,1.137534,1.137108,1.136980,1.138809,SOFT_START,1242,2406,0 -208592897,677,70,SPARK_NEG_OK,1.137633,1.137507,1.136345,1.136532,SOFT_START,677,70,SPARK_NEG_OK,1.137542,1.137111,1.137003,1.138898,SOFT_START,1241,2404,0 -208641897,678,70,SPARK_NEG_OK,1.137679,1.137521,1.136377,1.136529,SOFT_START,678,71,SPARK_NEG_OK,1.137469,1.137170,1.137097,1.138923,SOFT_START,1242,2384,0 -208689897,679,70,SPARK_NEG_OK,1.137649,1.137515,1.136469,1.136563,SOFT_START,679,72,SPARK_NEG_OK,1.137542,1.137152,1.137072,1.138843,SOFT_START,1241,2386,0 -208737897,680,70,SPARK_NEG_OK,1.137701,1.137541,1.136492,1.136580,SOFT_START,680,71,SPARK_NEG_OK,1.137546,1.137183,1.137108,1.138945,SOFT_START,1243,2408,0 -208785897,681,70,SPARK_NEG_OK,1.137725,1.137537,1.136547,1.136606,SOFT_START,681,70,SPARK_NEG_OK,1.137558,1.137155,1.137124,1.138886,SOFT_START,1242,2399,0 -208834897,682,70,SPARK_NEG_OK,1.137691,1.137584,1.136563,1.136664,SOFT_START,682,71,SPARK_NEG_OK,1.137617,1.137251,1.137169,1.138918,SOFT_START,1244,2406,0 -208882897,683,70,SPARK_NEG_OK,1.137699,1.137587,1.136602,1.136702,SOFT_START,683,70,SPARK_NEG_OK,1.137563,1.137258,1.137179,1.138815,SOFT_START,1244,2412,0 -208930897,684,70,SPARK_NEG_OK,1.137713,1.137607,1.136653,1.136650,SOFT_START,684,71,SPARK_NEG_OK,1.137600,1.137266,1.137206,1.138885,SOFT_START,1241,2411,0 -208978899,685,70,SPARK_NEG_OK,1.137746,1.137627,1.136679,1.136745,SOFT_START,685,70,SPARK_NEG_OK,1.137625,1.137311,1.137226,1.138851,SOFT_START,1243,2398,0 -209027897,686,70,SPARK_NEG_OK,1.137723,1.137634,1.136693,1.136773,SOFT_START,686,71,SPARK_NEG_OK,1.137648,1.137345,1.137269,1.138915,SOFT_START,1240,2405,0 -209075897,687,70,SPARK_NEG_OK,1.137763,1.137643,1.136718,1.136824,SOFT_START,687,70,SPARK_NEG_OK,1.137634,1.137334,1.137307,1.138732,SOFT_START,1241,2396,0 -209124897,688,70,SPARK_NEG_OK,1.137781,1.137671,1.136783,1.136880,SOFT_START,688,70,SPARK_NEG_OK,1.137646,1.137368,1.137317,1.138941,SOFT_START,1240,2407,0 -209172897,689,70,SPARK_NEG_OK,1.137768,1.137643,1.136767,1.136814,SOFT_START,689,70,SPARK_NEG_OK,1.137663,1.137373,1.137310,1.138902,SOFT_START,1241,2411,0 -209220897,690,71,SPARK_NEG_OK,1.137781,1.137674,1.136758,1.136814,SOFT_START,690,70,SPARK_NEG_OK,1.137654,1.137396,1.137297,1.138838,SOFT_START,1241,2394,0 -209268897,691,70,SPARK_NEG_OK,1.137773,1.137729,1.136826,1.136902,SOFT_START,691,70,SPARK_NEG_OK,1.137680,1.137432,1.137341,1.138957,SOFT_START,1243,2394,0 -209317897,692,71,SPARK_NEG_OK,1.137832,1.137734,1.136842,1.136949,SOFT_START,692,70,SPARK_NEG_OK,1.137698,1.137413,1.137412,1.138883,SOFT_START,1242,2385,0 -209365897,693,70,SPARK_NEG_OK,1.137817,1.137738,1.136888,1.136965,SOFT_START,693,72,SPARK_NEG_OK,1.137694,1.137418,1.137387,1.138899,SOFT_START,1244,2384,0 -209413897,694,71,SPARK_NEG_OK,1.137847,1.137711,1.136894,1.136992,SOFT_START,694,70,SPARK_NEG_OK,1.137710,1.137507,1.137427,1.138846,SOFT_START,1242,2397,0 -209461897,695,70,SPARK_NEG_OK,1.137819,1.137764,1.136895,1.137000,SOFT_START,695,70,SPARK_NEG_OK,1.137711,1.137467,1.137421,1.138884,SOFT_START,1243,2383,0 -209510897,696,72,SPARK_NEG_OK,1.137864,1.137789,1.136960,1.137031,SOFT_START,696,70,SPARK_NEG_OK,1.137716,1.137476,1.137458,1.138875,SOFT_START,1243,2402,0 -209558897,697,70,SPARK_NEG_OK,1.137865,1.137774,1.136977,1.137070,SOFT_START,697,70,SPARK_NEG_OK,1.137719,1.137494,1.137466,1.138852,SOFT_START,1241,2381,0 -209606897,698,71,SPARK_NEG_OK,1.137885,1.137747,1.137041,1.137088,SOFT_START,698,70,SPARK_NEG_OK,1.137729,1.137481,1.137471,1.138851,SOFT_START,1242,2380,0 -209655897,699,70,SPARK_NEG_OK,1.137878,1.137837,1.137046,1.137101,SOFT_START,699,70,SPARK_NEG_OK,1.137738,1.137557,1.137504,1.138878,SOFT_START,1241,2392,0 -209703897,700,71,SPARK_NEG_OK,1.137918,1.137805,1.137046,1.137153,SOFT_START,700,70,SPARK_NEG_OK,1.137747,1.137551,1.137550,1.138800,SOFT_START,1242,2410,0 -209751897,701,70,SPARK_NEG_OK,1.137910,1.137801,1.137085,1.137159,SOFT_START,701,70,SPARK_NEG_OK,1.137764,1.137571,1.137541,1.138932,SOFT_START,1242,2397,0 -209799902,702,71,SPARK_NEG_OK,1.137905,1.137841,1.137140,1.137174,SOFT_START,702,81,SPARK_NEG_OK,1.137774,1.137558,1.137542,1.138691,SOFT_START,1243,2409,0 -209848897,703,80,SPARK_NEG_OK,1.137861,1.137843,1.137123,1.137176,SOFT_START,703,80,SPARK_NEG_OK,1.137791,1.137603,1.137529,1.138969,SOFT_START,1243,2405,0 -209896897,704,81,SPARK_NEG_OK,1.137929,1.137857,1.137139,1.137183,SOFT_START,704,80,SPARK_NEG_OK,1.137794,1.137597,1.137577,1.138943,SOFT_START,1244,2399,0 -209944897,705,70,SPARK_NEG_OK,1.137953,1.137835,1.137151,1.137241,SOFT_START,705,70,SPARK_NEG_OK,1.137789,1.137597,1.137594,1.138930,SOFT_START,1243,2406,0 -209992897,706,71,SPARK_NEG_OK,1.137976,1.137872,1.137211,1.137235,SOFT_START,706,70,SPARK_NEG_OK,1.137817,1.137612,1.137649,1.139014,SOFT_START,1245,2387,0 -210041897,707,70,SPARK_NEG_OK,1.137991,1.137860,1.137187,1.137286,SOFT_START,707,71,SPARK_NEG_OK,1.137801,1.137645,1.137658,1.139110,SOFT_START,1243,2397,0 -210089897,708,70,SPARK_NEG_OK,1.138004,1.137912,1.137238,1.137297,SOFT_START,708,70,SPARK_NEG_OK,1.137846,1.137665,1.137652,1.138920,SOFT_START,1244,2392,0 -210137897,709,70,SPARK_NEG_OK,1.137998,1.137903,1.137260,1.137341,SOFT_START,709,71,SPARK_NEG_OK,1.137859,1.137704,1.137658,1.138911,SOFT_START,1243,2388,0 -210185897,710,70,SPARK_NEG_OK,1.138005,1.137950,1.137276,1.137326,SOFT_START,710,70,SPARK_NEG_OK,1.137846,1.137695,1.137651,1.138958,SOFT_START,1245,2403,0 -210233897,711,71,SPARK_NEG_OK,1.138015,1.137934,1.137314,1.137378,SOFT_START,711,71,SPARK_NEG_OK,1.137862,1.137675,1.137690,1.138846,SOFT_START,1245,2406,0 -210281897,712,70,SPARK_NEG_OK,1.138023,1.137950,1.137308,1.137351,SOFT_START,712,70,SPARK_NEG_OK,1.137897,1.137687,1.137752,1.138893,SOFT_START,1246,2400,0 -210330897,713,70,SPARK_NEG_OK,1.138036,1.137974,1.137332,1.137399,SOFT_START,713,71,SPARK_NEG_OK,1.137875,1.137727,1.137742,1.138827,SOFT_START,1247,2407,0 -210378897,714,70,SPARK_NEG_OK,1.138043,1.137970,1.137351,1.137382,SOFT_START,714,70,SPARK_NEG_OK,1.137884,1.137701,1.137730,1.138895,SOFT_START,1247,2395,0 -210426897,715,70,SPARK_NEG_OK,1.138008,1.137986,1.137360,1.137441,SOFT_START,715,71,SPARK_NEG_OK,1.137902,1.137705,1.137768,1.138687,SOFT_START,1248,2398,0 -210474897,716,70,SPARK_NEG_OK,1.138081,1.138036,1.137435,1.137413,SOFT_START,716,70,SPARK_NEG_OK,1.137910,1.137754,1.137767,1.138964,SOFT_START,1247,2386,0 -210522897,717,70,SPARK_NEG_OK,1.138100,1.138011,1.137373,1.137469,SOFT_START,717,71,SPARK_NEG_OK,1.137930,1.137763,1.137778,1.138929,SOFT_START,1248,2406,0 -210570897,718,70,SPARK_NEG_OK,1.138043,1.137998,1.137429,1.137460,SOFT_START,718,70,SPARK_NEG_OK,1.137934,1.137778,1.137801,1.138956,SOFT_START,1247,2404,0 -210618897,719,70,SPARK_NEG_OK,1.138090,1.138018,1.137393,1.137499,SOFT_START,719,71,SPARK_NEG_OK,1.137956,1.137770,1.137803,1.138976,SOFT_START,1247,2384,0 -210666897,720,70,SPARK_NEG_OK,1.138112,1.137938,1.137431,1.137509,SOFT_START,720,70,SPARK_NEG_OK,1.137940,1.137810,1.137819,1.138958,SOFT_START,1246,2382,0 -210714897,721,70,SPARK_NEG_OK,1.138068,1.138042,1.137441,1.137522,SOFT_START,721,71,SPARK_NEG_OK,1.137947,1.137820,1.137858,1.138958,SOFT_START,1247,2395,0 -210762897,722,70,SPARK_NEG_OK,1.138151,1.138049,1.137485,1.137538,SOFT_START,722,71,SPARK_NEG_OK,1.137938,1.137806,1.137837,1.138951,SOFT_START,1247,2406,0 -210810897,723,71,SPARK_NEG_OK,1.138098,1.138023,1.137503,1.137535,SOFT_START,723,71,SPARK_NEG_OK,1.137950,1.137818,1.137838,1.138974,SOFT_START,1249,2400,0 -210858897,724,70,SPARK_NEG_OK,1.138130,1.138054,1.137501,1.137530,SOFT_START,724,70,SPARK_NEG_OK,1.137995,1.137803,1.137873,1.138867,SOFT_START,1250,2408,0 -210906897,725,70,SPARK_NEG_OK,1.138141,1.138052,1.137540,1.137519,SOFT_START,725,71,SPARK_NEG_OK,1.137975,1.137847,1.137889,1.138939,SOFT_START,1250,2395,0 -210954897,726,70,SPARK_NEG_OK,1.138138,1.138044,1.137550,1.137602,SOFT_START,726,70,SPARK_NEG_OK,1.137962,1.137841,1.137889,1.138863,SOFT_START,1251,2399,0 -211002897,727,70,SPARK_NEG_OK,1.138136,1.138062,1.137559,1.137611,SOFT_START,727,71,SPARK_NEG_OK,1.137992,1.137902,1.137881,1.138971,SOFT_START,1250,2386,0 -211050897,728,70,SPARK_NEG_OK,1.138138,1.138079,1.137583,1.137606,SOFT_START,728,80,SPARK_NEG_OK,1.137988,1.137871,1.137957,1.138744,SOFT_START,1251,2383,0 -211098897,729,80,SPARK_NEG_OK,1.138191,1.138085,1.137638,1.137646,SOFT_START,729,81,SPARK_NEG_OK,1.137975,1.137877,1.137929,1.138996,SOFT_START,1248,2377,0 -211146897,730,80,SPARK_NEG_OK,1.138163,1.138112,1.137584,1.137645,SOFT_START,730,80,SPARK_NEG_OK,1.137998,1.137894,1.137933,1.138982,SOFT_START,1250,2405,0 -211194897,731,70,SPARK_NEG_OK,1.138152,1.138104,1.137643,1.137658,SOFT_START,731,71,SPARK_NEG_OK,1.138001,1.137852,1.137915,1.138994,SOFT_START,1248,2392,0 -211242897,732,70,SPARK_NEG_OK,1.138180,1.138099,1.137653,1.137661,SOFT_START,732,70,SPARK_NEG_OK,1.138040,1.137912,1.137971,1.138949,SOFT_START,1250,2386,0 -211290897,733,70,SPARK_NEG_OK,1.138184,1.138105,1.137664,1.137684,SOFT_START,733,71,SPARK_NEG_OK,1.138033,1.137890,1.137953,1.138962,SOFT_START,1249,2404,0 -211338897,734,70,SPARK_NEG_OK,1.138155,1.138122,1.137687,1.137703,SOFT_START,734,70,SPARK_NEG_OK,1.138028,1.137899,1.137933,1.139022,SOFT_START,1251,2404,0 -211386897,735,70,SPARK_NEG_OK,1.138198,1.138129,1.137674,1.137721,SOFT_START,735,71,SPARK_NEG_OK,1.138017,1.137896,1.137973,1.139181,SOFT_START,1250,2381,0 -211434897,736,70,SPARK_NEG_OK,1.138204,1.138211,1.137695,1.137647,SOFT_START,736,70,SPARK_NEG_OK,1.138058,1.137925,1.137958,1.139197,SOFT_START,1252,2409,0 -211482897,737,70,SPARK_NEG_OK,1.138175,1.138160,1.137719,1.137723,SOFT_START,737,71,SPARK_NEG_OK,1.138090,1.137953,1.137981,1.138944,SOFT_START,1252,2409,0 -211530897,738,70,SPARK_NEG_OK,1.138211,1.138162,1.137719,1.137768,SOFT_START,738,67,SPARK_NEG_OK,1.138083,1.137950,1.137990,1.138940,SOFT_START,1250,2383,0 -211578897,739,70,SPARK_NEG_OK,1.138220,1.138145,1.137765,1.137730,SOFT_START,739,70,SPARK_NEG_OK,1.138057,1.137959,1.138009,1.138917,SOFT_START,1251,2376,0 -211626897,740,70,SPARK_NEG_OK,1.138227,1.138154,1.137730,1.137791,SOFT_START,740,70,SPARK_NEG_OK,1.138057,1.137968,1.137996,1.139023,SOFT_START,1249,2392,0 -211674897,741,70,SPARK_NEG_OK,1.138252,1.138147,1.137752,1.137821,SOFT_START,741,71,SPARK_NEG_OK,1.138051,1.137983,1.138033,1.138769,SOFT_START,1250,2388,0 -211722897,742,69,SPARK_NEG_OK,1.138198,1.138179,1.137787,1.137830,SOFT_START,742,67,SPARK_NEG_OK,1.138079,1.137997,1.138012,1.138998,SOFT_START,1249,2402,0 -211770897,743,70,SPARK_NEG_OK,1.138225,1.138172,1.137791,1.137828,SOFT_START,743,71,SPARK_NEG_OK,1.138089,1.137985,1.138058,1.139023,SOFT_START,1250,2382,0 -211818897,744,71,SPARK_NEG_OK,1.138244,1.138158,1.137771,1.137835,SOFT_START,744,70,SPARK_NEG_OK,1.138102,1.138019,1.138072,1.139014,SOFT_START,1249,2387,0 -211866897,745,70,SPARK_NEG_OK,1.138276,1.138204,1.137782,1.137824,SOFT_START,745,71,SPARK_NEG_OK,1.138067,1.138024,1.138080,1.139066,SOFT_START,1251,2401,0 -211914897,746,70,SPARK_NEG_OK,1.138249,1.138198,1.137795,1.137868,SOFT_START,746,70,SPARK_NEG_OK,1.138113,1.138045,1.138071,1.139055,SOFT_START,1251,2405,0 -211962897,747,70,SPARK_NEG_OK,1.138272,1.138200,1.137807,1.137894,SOFT_START,747,71,SPARK_NEG_OK,1.138088,1.138040,1.138110,1.139042,SOFT_START,1252,2385,0 -212010897,748,70,SPARK_NEG_OK,1.138278,1.138203,1.137821,1.137896,SOFT_START,748,70,SPARK_NEG_OK,1.138071,1.138080,1.138109,1.138993,SOFT_START,1251,2384,0 -212058897,749,70,SPARK_NEG_OK,1.138303,1.138232,1.137800,1.137891,SOFT_START,749,71,SPARK_NEG_OK,1.138113,1.138065,1.138104,1.138943,SOFT_START,1252,2398,0 -212105901,750,70,SPARK_NEG_OK,1.138300,1.138235,1.137834,1.137903,SOFT_START,750,70,SPARK_NEG_OK,1.138152,1.138082,1.138091,1.138951,SOFT_START,1253,2407,0 -212153897,751,70,SPARK_NEG_OK,1.138335,1.138216,1.137862,1.137893,SOFT_START,751,71,SPARK_NEG_OK,1.138098,1.138100,1.138108,1.138986,SOFT_START,1250,2380,0 -212201897,752,70,SPARK_NEG_OK,1.138334,1.138244,1.137835,1.137930,SOFT_START,752,70,SPARK_NEG_OK,1.138149,1.138077,1.138115,1.138865,SOFT_START,1252,2395,0 -212249897,753,71,SPARK_NEG_OK,1.138324,1.138262,1.137785,1.137929,SOFT_START,753,71,SPARK_NEG_OK,1.138080,1.138062,1.138220,1.139033,SOFT_START,1250,2383,0 -212297897,754,70,SPARK_NEG_OK,1.138334,1.138273,1.137887,1.137937,SOFT_START,754,70,SPARK_NEG_OK,1.138138,1.138076,1.138165,1.138825,SOFT_START,1251,2406,0 -212345897,755,70,SPARK_NEG_OK,1.138358,1.138275,1.137871,1.137906,SOFT_START,755,71,SPARK_NEG_OK,1.138119,1.138117,1.138132,1.139039,SOFT_START,1251,2401,0 -212393897,756,70,SPARK_NEG_OK,1.138328,1.138268,1.137897,1.137944,SOFT_START,756,70,SPARK_NEG_OK,1.138145,1.138114,1.138170,1.139033,SOFT_START,1252,2394,0 -212441897,757,70,SPARK_NEG_OK,1.138311,1.138281,1.137884,1.137955,SOFT_START,757,71,SPARK_NEG_OK,1.138170,1.138145,1.138166,1.139054,SOFT_START,1251,2398,0 -212489897,758,71,SPARK_NEG_OK,1.138322,1.138261,1.137891,1.137973,SOFT_START,758,70,SPARK_NEG_OK,1.138126,1.138099,1.138163,1.138975,SOFT_START,1254,2385,0 -212537897,759,70,SPARK_NEG_OK,1.138352,1.138296,1.137900,1.137995,SOFT_START,759,71,SPARK_NEG_OK,1.138163,1.138120,1.138195,1.139035,SOFT_START,1252,2389,0 -212585897,760,70,SPARK_NEG_OK,1.138368,1.138262,1.137908,1.138051,SOFT_START,760,70,SPARK_NEG_OK,1.138172,1.138127,1.138158,1.139053,SOFT_START,1254,2410,0 -212633897,761,70,SPARK_NEG_OK,1.138395,1.138263,1.137933,1.137996,SOFT_START,761,71,SPARK_NEG_OK,1.138169,1.138124,1.138185,1.139020,SOFT_START,1251,2400,0 -212680897,762,70,SPARK_NEG_OK,1.138372,1.138293,1.137924,1.137992,SOFT_START,762,70,SPARK_NEG_OK,1.138122,1.138132,1.138182,1.139024,SOFT_START,1252,2408,0 -212728897,763,70,SPARK_NEG_OK,1.138381,1.138294,1.137922,1.138018,SOFT_START,763,70,SPARK_NEG_OK,1.138168,1.138127,1.138197,1.138944,SOFT_START,1251,2388,0 -212776897,764,70,SPARK_NEG_OK,1.138382,1.138298,1.137940,1.138020,SOFT_START,764,70,SPARK_NEG_OK,1.138219,1.138154,1.138232,1.139016,SOFT_START,1250,2409,0 -212824897,765,70,SPARK_NEG_OK,1.138403,1.138309,1.137928,1.138024,SOFT_START,765,71,SPARK_NEG_OK,1.138146,1.138127,1.138215,1.138958,SOFT_START,1251,2389,0 -212872897,766,70,SPARK_NEG_OK,1.138396,1.138304,1.137938,1.138067,SOFT_START,766,70,SPARK_NEG_OK,1.138192,1.138150,1.138200,1.139035,SOFT_START,1250,2397,0 -212920897,767,70,SPARK_NEG_OK,1.138405,1.138303,1.137975,1.138058,SOFT_START,767,71,SPARK_NEG_OK,1.138178,1.138164,1.138215,1.138743,SOFT_START,1251,2384,0 -212968897,768,70,SPARK_NEG_OK,1.138398,1.138332,1.137937,1.138052,SOFT_START,768,70,SPARK_NEG_OK,1.138191,1.138152,1.138211,1.139006,SOFT_START,1252,2385,0 -213016897,769,70,SPARK_NEG_OK,1.138415,1.138344,1.137995,1.138049,SOFT_START,769,71,SPARK_NEG_OK,1.138185,1.138163,1.138201,1.139008,SOFT_START,1253,2385,0 -213064897,770,70,SPARK_NEG_OK,1.138393,1.138344,1.138009,1.138029,SOFT_START,770,70,SPARK_NEG_OK,1.138173,1.138194,1.138180,1.139050,SOFT_START,1252,2403,0 -213112897,771,70,SPARK_NEG_OK,1.138391,1.138341,1.137991,1.138070,SOFT_START,771,71,SPARK_NEG_OK,1.138182,1.138166,1.138241,1.139045,SOFT_START,1253,2403,0 -213160897,772,70,SPARK_NEG_OK,1.138342,1.138349,1.138004,1.138089,SOFT_START,772,70,SPARK_NEG_OK,1.138202,1.138191,1.138259,1.139045,SOFT_START,1251,2394,0 -213208897,773,70,SPARK_NEG_OK,1.138428,1.138371,1.137958,1.138074,SOFT_START,773,71,SPARK_NEG_OK,1.138228,1.138192,1.138249,1.139044,SOFT_START,1251,2401,0 -213256897,774,71,SPARK_NEG_OK,1.138425,1.138361,1.138018,1.138079,SOFT_START,774,70,SPARK_NEG_OK,1.138206,1.138217,1.138265,1.139022,SOFT_START,1250,2385,0 -213304897,775,70,SPARK_NEG_OK,1.138386,1.138420,1.138002,1.138036,SOFT_START,775,71,SPARK_NEG_OK,1.138225,1.138148,1.138297,1.139051,SOFT_START,1250,2386,0 -213352897,776,70,SPARK_NEG_OK,1.138456,1.138390,1.137986,1.138085,SOFT_START,776,70,SPARK_NEG_OK,1.138209,1.138197,1.138290,1.138976,SOFT_START,1251,2381,0 -213400897,777,70,SPARK_NEG_OK,1.138428,1.138401,1.138026,1.138081,SOFT_START,777,71,SPARK_NEG_OK,1.138187,1.138217,1.138275,1.139073,SOFT_START,1250,2400,0 -213448897,778,70,SPARK_NEG_OK,1.138452,1.138402,1.138032,1.138088,SOFT_START,778,70,SPARK_NEG_OK,1.138163,1.138203,1.138282,1.138884,SOFT_START,1251,2406,0 -213495897,779,70,SPARK_NEG_OK,1.138428,1.138403,1.138020,1.138105,SOFT_START,779,71,SPARK_NEG_OK,1.138228,1.138189,1.138291,1.139023,SOFT_START,1251,2381,0 -213543897,780,70,SPARK_NEG_OK,1.138448,1.138382,1.138065,1.138100,SOFT_START,780,70,SPARK_NEG_OK,1.138238,1.138213,1.138292,1.138755,SOFT_START,1253,2412,0 -213591897,781,70,SPARK_NEG_OK,1.138423,1.138395,1.138057,1.138120,SOFT_START,781,71,SPARK_NEG_OK,1.138223,1.138205,1.138307,1.139048,SOFT_START,1251,2393,0 -213639897,782,71,SPARK_NEG_OK,1.138446,1.138397,1.138073,1.138099,SOFT_START,782,70,SPARK_NEG_OK,1.138188,1.138216,1.138323,1.139057,SOFT_START,1253,2407,0 -213687897,783,72,SPARK_NEG_OK,1.138451,1.138409,1.138069,1.138136,SOFT_START,783,71,SPARK_NEG_OK,1.138234,1.138239,1.138324,1.139079,SOFT_START,1250,2377,0 -213735897,784,71,SPARK_NEG_OK,1.138471,1.138388,1.138074,1.138095,SOFT_START,784,70,SPARK_NEG_OK,1.138217,1.138256,1.138316,1.139051,SOFT_START,1251,2398,0 -213783897,785,70,SPARK_NEG_OK,1.138414,1.138446,1.138042,1.138093,SOFT_START,785,71,SPARK_NEG_OK,1.138267,1.138250,1.138312,1.138973,SOFT_START,1249,2408,0 -213831897,786,71,SPARK_NEG_OK,1.138427,1.138439,1.138047,1.138116,SOFT_START,786,70,SPARK_NEG_OK,1.138250,1.138248,1.138345,1.139036,SOFT_START,1250,2403,0 -213879897,787,70,SPARK_NEG_OK,1.138458,1.138443,1.138033,1.138148,SOFT_START,787,73,SPARK_NEG_OK,1.138244,1.138253,1.138349,1.139001,SOFT_START,1248,2398,0 -213927897,788,71,SPARK_NEG_OK,1.138447,1.138411,1.138048,1.138149,SOFT_START,788,70,SPARK_NEG_OK,1.138240,1.138247,1.138395,1.139035,SOFT_START,1250,2380,0 -213975897,789,70,SPARK_NEG_OK,1.138427,1.138411,1.138066,1.138158,SOFT_START,789,71,SPARK_NEG_OK,1.138246,1.138246,1.138328,1.139023,SOFT_START,1250,2407,0 -214023897,790,70,SPARK_NEG_OK,1.138447,1.138439,1.138089,1.138154,SOFT_START,790,70,SPARK_NEG_OK,1.138283,1.138240,1.138356,1.139094,SOFT_START,1250,2382,0 -214071897,791,70,SPARK_NEG_OK,1.138467,1.138428,1.138092,1.138182,SOFT_START,791,71,SPARK_NEG_OK,1.138228,1.138306,1.138362,1.139122,SOFT_START,1251,2382,0 -214119897,792,71,SPARK_NEG_OK,1.138449,1.138431,1.138101,1.138186,SOFT_START,792,70,SPARK_NEG_OK,1.138307,1.138330,1.138378,1.139101,SOFT_START,1251,2404,0 -214167897,793,70,SPARK_NEG_OK,1.138552,1.138453,1.138151,1.138173,SOFT_START,793,70,SPARK_NEG_OK,1.138274,1.138269,1.138341,1.138859,SOFT_START,1252,2391,0 -214215897,794,71,SPARK_NEG_OK,1.138480,1.138455,1.138086,1.138193,SOFT_START,794,70,SPARK_NEG_OK,1.138254,1.138270,1.138371,1.139011,SOFT_START,1249,2391,0 -214263897,795,70,SPARK_NEG_OK,1.138474,1.138450,1.138149,1.138179,SOFT_START,795,71,SPARK_NEG_OK,1.138239,1.138273,1.138381,1.139054,SOFT_START,1250,2391,0 -214311897,796,71,SPARK_NEG_OK,1.138446,1.138428,1.138096,1.138195,SOFT_START,796,70,SPARK_NEG_OK,1.138242,1.138265,1.138371,1.139048,SOFT_START,1249,2402,0 -214359897,797,70,SPARK_NEG_OK,1.138456,1.138474,1.138082,1.138171,SOFT_START,797,71,SPARK_NEG_OK,1.138275,1.138265,1.138336,1.139057,SOFT_START,1249,2396,0 -214407897,798,71,SPARK_NEG_OK,1.138477,1.138422,1.138150,1.138211,SOFT_START,798,70,SPARK_NEG_OK,1.138242,1.138308,1.138430,1.139064,SOFT_START,1248,2393,0 -214455897,799,70,SPARK_NEG_OK,1.138467,1.138456,1.138117,1.138208,SOFT_START,799,71,SPARK_NEG_OK,1.138306,1.138263,1.138409,1.139035,SOFT_START,1250,2407,0 -214503897,800,71,SPARK_NEG_OK,1.138468,1.138417,1.138114,1.138202,SOFT_START,800,70,SPARK_NEG_OK,1.138266,1.138245,1.138414,1.139016,SOFT_START,1249,2398,0 -214551897,801,70,SPARK_NEG_OK,1.138483,1.138476,1.138146,1.138198,SOFT_START,801,71,SPARK_NEG_OK,1.138288,1.138328,1.138394,1.139047,SOFT_START,1252,2405,0 -214599897,802,71,SPARK_NEG_OK,1.138486,1.138464,1.138102,1.138209,SOFT_START,802,70,SPARK_NEG_OK,1.138279,1.138242,1.138398,1.139002,SOFT_START,1252,2406,0 -214647897,803,70,SPARK_NEG_OK,1.138459,1.138501,1.138144,1.138201,SOFT_START,803,71,SPARK_NEG_OK,1.138278,1.138291,1.138401,1.138992,SOFT_START,1251,2399,0 -214695897,804,71,SPARK_NEG_OK,1.138479,1.138467,1.138116,1.138197,SOFT_START,804,70,SPARK_NEG_OK,1.138301,1.138332,1.138430,1.138932,SOFT_START,1252,2390,0 -214743897,805,70,SPARK_NEG_OK,1.138486,1.138425,1.138162,1.138229,SOFT_START,805,71,SPARK_NEG_OK,1.138298,1.138256,1.138420,1.139050,SOFT_START,1250,2378,0 -214791897,806,71,SPARK_NEG_OK,1.138501,1.138467,1.138133,1.138153,SOFT_START,806,70,SPARK_NEG_OK,1.138309,1.138292,1.138414,1.138875,SOFT_START,1251,2384,0 -214839897,807,70,SPARK_NEG_OK,1.138507,1.138448,1.138161,1.138209,SOFT_START,807,71,SPARK_NEG_OK,1.138198,1.138241,1.138430,1.139084,SOFT_START,1248,2379,0 -214887897,808,70,SPARK_NEG_OK,1.138470,1.138480,1.138146,1.138220,SOFT_START,808,70,SPARK_NEG_OK,1.138322,1.138297,1.138424,1.139072,SOFT_START,1250,2406,0 -214935897,809,70,SPARK_NEG_OK,1.138491,1.138465,1.138143,1.138226,SOFT_START,809,71,SPARK_NEG_OK,1.138254,1.138277,1.138397,1.139054,SOFT_START,1248,2383,0 -214983897,810,71,SPARK_NEG_OK,1.138481,1.138449,1.138163,1.138223,SOFT_START,810,70,SPARK_NEG_OK,1.138306,1.138301,1.138436,1.139079,SOFT_START,1250,2411,0 -215031897,811,70,SPARK_NEG_OK,1.138518,1.138470,1.138156,1.138200,SOFT_START,811,71,SPARK_NEG_OK,1.138248,1.138315,1.138418,1.139088,SOFT_START,1249,2394,0 -215079897,812,70,SPARK_NEG_OK,1.138515,1.138473,1.138163,1.138228,SOFT_START,812,70,SPARK_NEG_OK,1.138258,1.138291,1.138429,1.139048,SOFT_START,1251,2395,0 -215127897,813,69,SPARK_NEG_OK,1.138512,1.138452,1.138198,1.138222,SOFT_START,813,71,SPARK_NEG_OK,1.138250,1.138309,1.138430,1.139001,SOFT_START,1249,2399,0 -215175897,814,70,SPARK_NEG_OK,1.138524,1.138493,1.138192,1.138233,SOFT_START,814,70,SPARK_NEG_OK,1.138266,1.138299,1.138408,1.139073,SOFT_START,1251,2392,0 -215223897,815,71,SPARK_NEG_OK,1.138552,1.138468,1.138200,1.138255,SOFT_START,815,71,SPARK_NEG_OK,1.138245,1.138306,1.138424,1.138976,SOFT_START,1251,2382,0 -215270900,816,71,SPARK_NEG_OK,1.138565,1.138468,1.138196,1.138242,SOFT_START,816,70,SPARK_NEG_OK,1.138309,1.138321,1.138430,1.139065,SOFT_START,1249,2381,0 -215319897,817,70,SPARK_NEG_OK,1.138528,1.138504,1.138189,1.138284,SOFT_START,817,71,SPARK_NEG_OK,1.138285,1.138337,1.138492,1.138961,SOFT_START,1250,2402,0 -215367897,818,70,SPARK_NEG_OK,1.138511,1.138494,1.138194,1.138268,SOFT_START,818,70,SPARK_NEG_OK,1.138259,1.138306,1.138455,1.139041,SOFT_START,1248,2409,0 -215415897,819,70,SPARK_NEG_OK,1.138490,1.138517,1.138215,1.138276,SOFT_START,819,81,SPARK_NEG_OK,1.138259,1.138287,1.138430,1.138900,SOFT_START,1249,2399,0 -215463897,820,80,SPARK_NEG_OK,1.138518,1.138476,1.138185,1.138240,SOFT_START,820,80,SPARK_NEG_OK,1.138217,1.138318,1.138436,1.139259,SOFT_START,1248,2393,0 -215511897,821,80,SPARK_NEG_OK,1.138481,1.138518,1.138205,1.138226,SOFT_START,821,81,SPARK_NEG_OK,1.138195,1.138300,1.138445,1.139256,SOFT_START,1249,2387,0 -215559897,822,70,SPARK_NEG_OK,1.138484,1.138480,1.138192,1.138263,SOFT_START,822,70,SPARK_NEG_OK,1.138259,1.138348,1.138447,1.139029,SOFT_START,1249,2401,0 -215607897,823,69,SPARK_NEG_OK,1.138505,1.138493,1.138193,1.138270,SOFT_START,823,71,SPARK_NEG_OK,1.138267,1.138299,1.138486,1.138973,SOFT_START,1251,2388,0 -215655897,824,70,SPARK_NEG_OK,1.138484,1.138511,1.138229,1.138265,SOFT_START,824,70,SPARK_NEG_OK,1.138248,1.138271,1.138461,1.139051,SOFT_START,1250,2400,0 -215702897,825,70,SPARK_NEG_OK,1.138524,1.138477,1.138238,1.138301,SOFT_START,825,71,SPARK_NEG_OK,1.138252,1.138344,1.138511,1.139089,SOFT_START,1252,2393,0 -215750897,826,71,SPARK_NEG_OK,1.138477,1.138499,1.138226,1.138278,SOFT_START,826,70,SPARK_NEG_OK,1.138259,1.138334,1.138464,1.138977,SOFT_START,1250,2397,0 -215798897,827,70,SPARK_NEG_OK,1.138552,1.138506,1.138250,1.138270,SOFT_START,827,71,SPARK_NEG_OK,1.138319,1.138334,1.138440,1.139089,SOFT_START,1251,2384,0 -215846897,828,70,SPARK_NEG_OK,1.138582,1.138483,1.138216,1.138285,SOFT_START,828,70,SPARK_NEG_OK,1.138330,1.138296,1.138458,1.139041,SOFT_START,1251,2392,0 -215894897,829,70,SPARK_NEG_OK,1.138521,1.138510,1.138206,1.138275,SOFT_START,829,71,SPARK_NEG_OK,1.138287,1.138381,1.138420,1.139037,SOFT_START,1248,2385,0 -215942897,830,70,SPARK_NEG_OK,1.138532,1.138511,1.138244,1.138247,SOFT_START,830,70,SPARK_NEG_OK,1.138295,1.138340,1.138440,1.138875,SOFT_START,1250,2386,0 -215990897,831,70,SPARK_NEG_OK,1.138490,1.138517,1.138223,1.138322,SOFT_START,831,71,SPARK_NEG_OK,1.138285,1.138335,1.138432,1.138997,SOFT_START,1247,2393,0 -216039897,832,70,SPARK_NEG_OK,1.138487,1.138530,1.138200,1.138294,SOFT_START,832,71,SPARK_NEG_OK,1.138273,1.138306,1.138449,1.138920,SOFT_START,1249,2386,0 -216086897,833,70,SPARK_NEG_OK,1.138521,1.138455,1.138199,1.138298,SOFT_START,833,71,SPARK_NEG_OK,1.138241,1.138312,1.138469,1.139084,SOFT_START,1249,2381,0 -216134897,834,70,SPARK_NEG_OK,1.138502,1.138512,1.138235,1.138312,SOFT_START,834,70,SPARK_NEG_OK,1.138263,1.138290,1.138486,1.139112,SOFT_START,1250,2382,0 -216182897,835,80,SPARK_NEG_OK,1.138532,1.138452,1.138203,1.138307,SOFT_START,835,81,SPARK_NEG_OK,1.138279,1.138321,1.138476,1.139079,SOFT_START,1250,2396,0 -216230897,836,80,SPARK_NEG_OK,1.138548,1.138516,1.138220,1.138309,SOFT_START,836,80,SPARK_NEG_OK,1.138315,1.138310,1.138442,1.139051,SOFT_START,1252,2403,0 -216278897,837,70,SPARK_NEG_OK,1.138517,1.138518,1.138211,1.138343,SOFT_START,837,71,SPARK_NEG_OK,1.138269,1.138303,1.138446,1.139132,SOFT_START,1250,2397,0 -216326897,838,68,SPARK_NEG_OK,1.138520,1.138499,1.138174,1.138355,SOFT_START,838,70,SPARK_NEG_OK,1.138278,1.138321,1.138489,1.139149,SOFT_START,1250,2398,0 -216374897,839,70,SPARK_NEG_OK,1.138527,1.138501,1.138227,1.138337,SOFT_START,839,71,SPARK_NEG_OK,1.138293,1.138291,1.138470,1.139072,SOFT_START,1248,2388,0 -216422897,840,70,SPARK_NEG_OK,1.138527,1.138489,1.138206,1.138326,SOFT_START,840,70,SPARK_NEG_OK,1.138273,1.138356,1.138478,1.139288,SOFT_START,1249,2395,0 -216471897,841,70,SPARK_NEG_OK,1.138546,1.138527,1.138250,1.138381,SOFT_START,841,71,SPARK_NEG_OK,1.138332,1.138349,1.138503,1.139151,SOFT_START,1249,2406,0 -216519897,842,70,SPARK_NEG_OK,1.138522,1.138514,1.138229,1.138400,SOFT_START,842,70,SPARK_NEG_OK,1.138301,1.138368,1.138527,1.139107,SOFT_START,1247,2400,0 -216567897,843,70,SPARK_NEG_OK,1.138535,1.138543,1.138236,1.138390,SOFT_START,843,70,SPARK_NEG_OK,1.138307,1.138346,1.138498,1.138964,SOFT_START,1248,2404,0 -216615897,844,70,SPARK_NEG_OK,1.138550,1.138555,1.138241,1.138369,SOFT_START,844,70,SPARK_NEG_OK,1.138328,1.138341,1.138508,1.139114,SOFT_START,1248,2412,0 -216663897,845,70,SPARK_NEG_OK,1.138542,1.138541,1.138265,1.138356,SOFT_START,845,70,SPARK_NEG_OK,1.138309,1.138325,1.138487,1.138971,SOFT_START,1249,2408,0 -216711897,846,70,SPARK_NEG_OK,1.138548,1.138501,1.138245,1.138341,SOFT_START,846,70,SPARK_NEG_OK,1.138300,1.138322,1.138474,1.139084,SOFT_START,1250,2396,0 -216759897,847,70,SPARK_NEG_OK,1.138493,1.138547,1.138240,1.138379,SOFT_START,847,71,SPARK_NEG_OK,1.138277,1.138295,1.138487,1.139060,SOFT_START,1251,2383,0 -216807897,848,70,SPARK_NEG_OK,1.138539,1.138554,1.138327,1.138390,SOFT_START,848,70,SPARK_NEG_OK,1.138270,1.138328,1.138485,1.139219,SOFT_START,1250,2401,0 -216855897,849,70,SPARK_NEG_OK,1.138560,1.138601,1.138268,1.138361,SOFT_START,849,71,SPARK_NEG_OK,1.138322,1.138334,1.138518,1.139304,SOFT_START,1250,2401,0 -216903897,850,70,SPARK_NEG_OK,1.138549,1.138557,1.138250,1.138391,SOFT_START,850,70,SPARK_NEG_OK,1.138330,1.138349,1.138527,1.139089,SOFT_START,1248,2392,0 -216951897,851,70,SPARK_NEG_OK,1.138607,1.138610,1.138299,1.138422,SOFT_START,851,71,SPARK_NEG_OK,1.138344,1.138320,1.138532,1.139114,SOFT_START,1249,2399,0 -216999897,852,68,SPARK_NEG_OK,1.138590,1.138583,1.138316,1.138387,SOFT_START,852,70,SPARK_NEG_OK,1.138328,1.138357,1.138518,1.139020,SOFT_START,1247,2403,0 -217047897,853,70,SPARK_NEG_OK,1.138565,1.138542,1.138294,1.138381,SOFT_START,853,71,SPARK_NEG_OK,1.138319,1.138338,1.138487,1.139031,SOFT_START,1248,2390,0 -217095897,854,70,SPARK_NEG_OK,1.138560,1.138588,1.138318,1.138377,SOFT_START,854,70,SPARK_NEG_OK,1.138297,1.138317,1.138487,1.138980,SOFT_START,1248,2404,0 -217143897,855,70,SPARK_NEG_OK,1.138568,1.138591,1.138288,1.138344,SOFT_START,855,71,SPARK_NEG_OK,1.138279,1.138338,1.138511,1.139027,SOFT_START,1248,2405,0 -217191897,856,69,SPARK_NEG_OK,1.138587,1.138564,1.138309,1.138394,SOFT_START,856,70,SPARK_NEG_OK,1.138339,1.138366,1.138506,1.138941,SOFT_START,1249,2409,0 -217239897,857,70,SPARK_NEG_OK,1.138549,1.138560,1.138278,1.138383,SOFT_START,857,71,SPARK_NEG_OK,1.138310,1.138363,1.138543,1.139092,SOFT_START,1250,2396,0 -217287897,858,70,SPARK_NEG_OK,1.138577,1.138525,1.138279,1.138408,SOFT_START,858,70,SPARK_NEG_OK,1.138337,1.138442,1.138528,1.139015,SOFT_START,1251,2398,0 -217335897,859,70,SPARK_NEG_OK,1.138548,1.138519,1.138304,1.138421,SOFT_START,859,71,SPARK_NEG_OK,1.138304,1.138350,1.138549,1.139295,SOFT_START,1250,2387,0 -217383897,860,70,SPARK_NEG_OK,1.138586,1.138577,1.138266,1.138399,SOFT_START,860,70,SPARK_NEG_OK,1.138324,1.138343,1.138542,1.139333,SOFT_START,1251,2408,0 -217431897,861,70,SPARK_NEG_OK,1.138586,1.138573,1.138324,1.138422,SOFT_START,861,71,SPARK_NEG_OK,1.138351,1.138338,1.138511,1.139140,SOFT_START,1249,2385,0 -217479897,862,70,SPARK_NEG_OK,1.138607,1.138555,1.138257,1.138417,SOFT_START,862,70,SPARK_NEG_OK,1.138318,1.138350,1.138532,1.139102,SOFT_START,1250,2413,0 -217527897,863,70,SPARK_NEG_OK,1.138586,1.138567,1.138321,1.138395,SOFT_START,863,71,SPARK_NEG_OK,1.138316,1.138328,1.138551,1.139092,SOFT_START,1248,2377,0 -217575897,864,70,SPARK_NEG_OK,1.138588,1.138548,1.138326,1.138450,SOFT_START,864,70,SPARK_NEG_OK,1.138288,1.138411,1.138558,1.139145,SOFT_START,1248,2404,0 -217623897,865,70,SPARK_NEG_OK,1.138580,1.138589,1.138295,1.138440,SOFT_START,865,71,SPARK_NEG_OK,1.138348,1.138396,1.138538,1.139111,SOFT_START,1248,2402,0 -217671897,866,70,SPARK_NEG_OK,1.138604,1.138605,1.138306,1.138406,SOFT_START,866,70,SPARK_NEG_OK,1.138321,1.138411,1.138599,1.139143,SOFT_START,1250,2382,0 -217719897,867,70,SPARK_NEG_OK,1.138617,1.138567,1.138355,1.138427,SOFT_START,867,71,SPARK_NEG_OK,1.138306,1.138415,1.138564,1.139084,SOFT_START,1250,2398,0 -217767897,868,70,SPARK_NEG_OK,1.138602,1.138534,1.138331,1.138430,SOFT_START,868,73,SPARK_NEG_OK,1.138302,1.138369,1.138538,1.139151,SOFT_START,1250,2383,0 -217815897,869,70,SPARK_NEG_OK,1.138623,1.138582,1.138336,1.138406,SOFT_START,869,71,SPARK_NEG_OK,1.138301,1.138471,1.138548,1.138996,SOFT_START,1251,2386,0 -217863897,870,70,SPARK_NEG_OK,1.138642,1.138554,1.138318,1.138428,SOFT_START,870,70,SPARK_NEG_OK,1.138318,1.138403,1.138542,1.139169,SOFT_START,1250,2411,0 -217911897,871,70,SPARK_NEG_OK,1.138672,1.138587,1.138328,1.138414,SOFT_START,871,69,SPARK_NEG_OK,1.138327,1.138440,1.138535,1.138997,SOFT_START,1251,2384,0 -217959897,872,70,SPARK_NEG_OK,1.138634,1.138582,1.138342,1.138425,SOFT_START,872,70,SPARK_NEG_OK,1.138257,1.138398,1.138561,1.139163,SOFT_START,1248,2412,0 -218007897,873,70,SPARK_NEG_OK,1.138611,1.138590,1.138345,1.138425,SOFT_START,873,71,SPARK_NEG_OK,1.138305,1.138422,1.138549,1.139166,SOFT_START,1249,2405,0 -218055897,874,70,SPARK_NEG_OK,1.138608,1.138617,1.138309,1.138455,SOFT_START,874,70,SPARK_NEG_OK,1.138326,1.138449,1.138542,1.139153,SOFT_START,1248,2411,0 -218103897,875,70,SPARK_NEG_OK,1.138639,1.138597,1.138353,1.138443,SOFT_START,875,71,SPARK_NEG_OK,1.138312,1.138433,1.138538,1.139192,SOFT_START,1248,2397,0 -218151897,876,70,SPARK_NEG_OK,1.138624,1.138604,1.138347,1.138433,SOFT_START,876,70,SPARK_NEG_OK,1.138306,1.138461,1.138561,1.139135,SOFT_START,1247,2388,0 -218199897,877,70,SPARK_NEG_OK,1.138622,1.138594,1.138381,1.138431,SOFT_START,877,71,SPARK_NEG_OK,1.138392,1.138459,1.138592,1.139425,SOFT_START,1249,2394,0 -218247897,878,70,SPARK_NEG_OK,1.138653,1.138602,1.138384,1.138423,SOFT_START,878,70,SPARK_NEG_OK,1.138366,1.138442,1.138563,1.139250,SOFT_START,1248,2379,0 -218295897,879,70,SPARK_NEG_OK,1.138637,1.138626,1.138394,1.138425,SOFT_START,879,71,SPARK_NEG_OK,1.138351,1.138458,1.138601,1.139175,SOFT_START,1250,2379,0 -218343897,880,70,SPARK_NEG_OK,1.138645,1.138624,1.138379,1.138467,SOFT_START,880,70,SPARK_NEG_OK,1.138366,1.138477,1.138600,1.139104,SOFT_START,1251,2397,0 -218391897,881,70,SPARK_NEG_OK,1.138657,1.138604,1.138365,1.138420,SOFT_START,881,71,SPARK_NEG_OK,1.138360,1.138473,1.138594,1.139125,SOFT_START,1249,2397,0 -218439897,882,70,SPARK_NEG_OK,1.138628,1.138623,1.138384,1.138427,SOFT_START,882,70,SPARK_NEG_OK,1.138400,1.138477,1.138602,1.139050,SOFT_START,1251,2385,0 -218487897,883,70,SPARK_NEG_OK,1.138652,1.138634,1.138394,1.138490,SOFT_START,883,71,SPARK_NEG_OK,1.138355,1.138552,1.138619,1.139155,SOFT_START,1248,2391,0 -218535897,884,70,SPARK_NEG_OK,1.138629,1.138613,1.138399,1.138437,SOFT_START,884,69,SPARK_NEG_OK,1.138358,1.138471,1.138608,1.138936,SOFT_START,1249,2399,0 -218583897,885,70,SPARK_NEG_OK,1.138610,1.138597,1.138387,1.138431,SOFT_START,885,73,SPARK_NEG_OK,1.138369,1.138508,1.138621,1.139168,SOFT_START,1245,2404,0 -218631897,886,70,SPARK_NEG_OK,1.138641,1.138602,1.138392,1.138493,SOFT_START,886,70,SPARK_NEG_OK,1.138371,1.138498,1.138634,1.139189,SOFT_START,1246,2381,0 -218680897,887,70,SPARK_NEG_OK,1.138602,1.138647,1.138378,1.138447,SOFT_START,887,71,SPARK_NEG_OK,1.138380,1.138490,1.138642,1.139162,SOFT_START,1245,2384,0 -218728897,888,70,SPARK_NEG_OK,1.138627,1.138601,1.138406,1.138457,SOFT_START,888,70,SPARK_NEG_OK,1.138391,1.138477,1.138616,1.139142,SOFT_START,1246,2405,0 -218776897,889,70,SPARK_NEG_OK,1.138642,1.138624,1.138432,1.138456,SOFT_START,889,70,SPARK_NEG_OK,1.138390,1.138476,1.138601,1.139123,SOFT_START,1245,2382,0 -218824897,890,70,SPARK_NEG_OK,1.138672,1.138610,1.138408,1.138479,SOFT_START,890,70,SPARK_NEG_OK,1.138347,1.138467,1.138620,1.139167,SOFT_START,1247,2411,0 -218872897,891,71,SPARK_NEG_OK,1.138641,1.138614,1.138403,1.138440,SOFT_START,891,70,SPARK_NEG_OK,1.138426,1.138508,1.138587,1.139138,SOFT_START,1245,2386,0 -218920897,892,70,SPARK_NEG_OK,1.138673,1.138636,1.138422,1.138453,SOFT_START,892,70,SPARK_NEG_OK,1.138434,1.138475,1.138613,1.139152,SOFT_START,1247,2414,0 -218969897,893,73,SPARK_NEG_OK,1.138662,1.138619,1.138402,1.138477,SOFT_START,893,70,SPARK_NEG_OK,1.138417,1.138515,1.138647,1.139086,SOFT_START,1247,2390,0 -219017897,894,70,SPARK_NEG_OK,1.138691,1.138607,1.138390,1.138450,SOFT_START,894,71,SPARK_NEG_OK,1.138358,1.138538,1.138587,1.139165,SOFT_START,1244,2398,0 -219065897,895,71,SPARK_NEG_OK,1.138647,1.138612,1.138396,1.138458,SOFT_START,895,70,SPARK_NEG_OK,1.138403,1.138467,1.138626,1.139022,SOFT_START,1245,2399,0 -219113897,896,70,SPARK_NEG_OK,1.138684,1.138647,1.138412,1.138424,SOFT_START,896,70,SPARK_NEG_OK,1.138400,1.138519,1.138634,1.139187,SOFT_START,1242,2387,0 -219162897,897,71,SPARK_NEG_OK,1.138642,1.138673,1.138410,1.138477,SOFT_START,897,70,SPARK_NEG_OK,1.138387,1.138532,1.138558,1.138885,SOFT_START,1243,2397,0 -219210897,898,70,SPARK_NEG_OK,1.138694,1.138656,1.138395,1.138443,SOFT_START,898,70,SPARK_NEG_OK,1.138403,1.138521,1.138630,1.139143,SOFT_START,1242,2410,0 -219258897,899,71,SPARK_NEG_OK,1.138663,1.138673,1.138411,1.138471,SOFT_START,899,70,SPARK_NEG_OK,1.138383,1.138541,1.138608,1.139140,SOFT_START,1243,2398,0 -219306897,900,70,SPARK_NEG_OK,1.138693,1.138663,1.138418,1.138428,SOFT_START,900,70,SPARK_NEG_OK,1.138430,1.138517,1.138645,1.139151,SOFT_START,1243,2408,0 -219354897,901,71,SPARK_NEG_OK,1.138690,1.138638,1.138396,1.138427,SOFT_START,901,70,SPARK_NEG_OK,1.138417,1.138504,1.138599,1.139144,SOFT_START,1244,2402,0 -219403897,902,80,SPARK_NEG_OK,1.138667,1.138660,1.138384,1.138483,SOFT_START,902,80,SPARK_NEG_OK,1.138473,1.138504,1.138635,1.139138,SOFT_START,1243,2389,0 -219451897,903,81,SPARK_NEG_OK,1.138726,1.138665,1.138471,1.138487,SOFT_START,903,80,SPARK_NEG_OK,1.138452,1.138522,1.138626,1.139170,SOFT_START,1245,2405,0 -219499897,904,70,SPARK_NEG_OK,1.138700,1.138678,1.138409,1.138476,SOFT_START,904,70,SPARK_NEG_OK,1.138496,1.138518,1.138644,1.139162,SOFT_START,1243,2384,0 -219547897,905,71,SPARK_NEG_OK,1.138695,1.138734,1.138450,1.138469,SOFT_START,905,70,SPARK_NEG_OK,1.138472,1.138521,1.138626,1.139174,SOFT_START,1243,2406,0 -219596897,906,70,SPARK_NEG_OK,1.138708,1.138728,1.138401,1.138480,SOFT_START,906,70,SPARK_NEG_OK,1.138439,1.138536,1.138636,1.139138,SOFT_START,1243,2402,0 -219644897,907,71,SPARK_NEG_OK,1.138728,1.138681,1.138412,1.138474,SOFT_START,907,70,SPARK_NEG_OK,1.138455,1.138493,1.138638,1.139159,SOFT_START,1240,2409,0 -219692897,908,70,SPARK_NEG_OK,1.138721,1.138668,1.138405,1.138470,SOFT_START,908,73,SPARK_NEG_OK,1.138459,1.138530,1.138620,1.139131,SOFT_START,1241,2397,0 -219741897,909,70,SPARK_NEG_OK,1.138727,1.138678,1.138438,1.138504,SOFT_START,909,71,SPARK_NEG_OK,1.138441,1.138532,1.138629,1.139200,SOFT_START,1240,2406,0 -219789897,910,70,SPARK_NEG_OK,1.138710,1.138663,1.138406,1.138470,SOFT_START,910,71,SPARK_NEG_OK,1.138486,1.138529,1.138630,1.138990,SOFT_START,1241,2384,0 -219837897,911,70,SPARK_NEG_OK,1.138743,1.138648,1.138436,1.138477,SOFT_START,911,70,SPARK_NEG_OK,1.138466,1.138487,1.138642,1.139210,SOFT_START,1241,2398,0 -219886897,912,70,SPARK_NEG_OK,1.138725,1.138688,1.138431,1.138484,SOFT_START,912,72,SPARK_NEG_OK,1.138453,1.138577,1.138648,1.139072,SOFT_START,1242,2394,0 -219934897,913,70,SPARK_NEG_OK,1.138715,1.138649,1.138395,1.138445,SOFT_START,913,70,SPARK_NEG_OK,1.138434,1.138469,1.138639,1.139132,SOFT_START,1241,2383,0 -219982897,914,70,SPARK_NEG_OK,1.138715,1.138665,1.138388,1.138463,SOFT_START,914,71,SPARK_NEG_OK,1.138423,1.138514,1.138570,1.139191,SOFT_START,1243,2403,0 -220031897,915,70,SPARK_NEG_OK,1.138723,1.138682,1.138421,1.138452,SOFT_START,915,70,SPARK_NEG_OK,1.138442,1.138572,1.138615,1.139210,SOFT_START,1241,2385,0 -220079897,916,70,SPARK_NEG_OK,1.138694,1.138664,1.138434,1.138448,SOFT_START,916,71,SPARK_NEG_OK,1.138440,1.138488,1.138620,1.139233,SOFT_START,1242,2407,0 -220127897,917,70,SPARK_NEG_OK,1.138734,1.138667,1.138445,1.138474,SOFT_START,917,70,SPARK_NEG_OK,1.138465,1.138519,1.138678,1.139187,SOFT_START,1239,2405,0 -220176897,918,70,SPARK_NEG_OK,1.138715,1.138663,1.138380,1.138499,SOFT_START,918,71,SPARK_NEG_OK,1.138488,1.138514,1.138673,1.139215,SOFT_START,1240,2385,0 -220224897,919,76,SPARK_NEG_OK,1.138730,1.138671,1.138433,1.138500,SOFT_START,919,70,SPARK_NEG_OK,1.138501,1.138561,1.138666,1.139113,SOFT_START,1238,2383,0 -220272896,920,70,SPARK_NEG_OK,1.138715,1.138648,1.138427,1.138495,SOFT_START,920,70,SPARK_NEG_OK,1.138480,1.138545,1.138686,1.139234,SOFT_START,1240,2396,0 -220321897,921,70,SPARK_NEG_OK,1.138718,1.138695,1.138424,1.138474,SOFT_START,921,70,SPARK_NEG_OK,1.138481,1.138502,1.138655,1.139151,SOFT_START,1240,2392,0 -220369897,922,71,SPARK_NEG_OK,1.138739,1.138659,1.138448,1.138504,SOFT_START,922,70,SPARK_NEG_OK,1.138498,1.138550,1.138651,1.139207,SOFT_START,1240,2399,0 -220418897,923,70,SPARK_NEG_OK,1.138737,1.138682,1.138443,1.138465,SOFT_START,923,70,SPARK_NEG_OK,1.138454,1.138571,1.138635,1.139098,SOFT_START,1241,2399,0 -220466897,924,71,SPARK_NEG_OK,1.138719,1.138707,1.138497,1.138504,SOFT_START,924,70,SPARK_NEG_OK,1.138495,1.138530,1.138682,1.139373,SOFT_START,1240,2392,0 -220514897,925,70,SPARK_NEG_OK,1.138741,1.138710,1.138463,1.138506,SOFT_START,925,70,SPARK_NEG_OK,1.138505,1.138539,1.138701,1.139042,SOFT_START,1242,2407,0 -220563897,926,71,SPARK_NEG_OK,1.138765,1.138703,1.138470,1.138495,SOFT_START,926,70,SPARK_NEG_OK,1.138495,1.138548,1.138691,1.139212,SOFT_START,1239,2407,0 -220611897,927,70,SPARK_NEG_OK,1.138759,1.138679,1.138473,1.138549,SOFT_START,927,70,SPARK_NEG_OK,1.138501,1.138553,1.138677,1.139235,SOFT_START,1240,2407,0 -220659897,928,71,SPARK_NEG_OK,1.138782,1.138693,1.138459,1.138471,SOFT_START,928,70,SPARK_NEG_OK,1.138487,1.138561,1.138661,1.139202,SOFT_START,1238,2399,0 -220708897,929,70,SPARK_NEG_OK,1.138685,1.138699,1.138495,1.138465,SOFT_START,929,70,SPARK_NEG_OK,1.138538,1.138575,1.138648,1.139215,SOFT_START,1239,2404,0 -220756897,930,71,SPARK_NEG_OK,1.138716,1.138688,1.138489,1.138510,SOFT_START,930,70,SPARK_NEG_OK,1.138470,1.138572,1.138648,1.139168,SOFT_START,1237,2396,0 -220805897,931,67,SPARK_NEG_OK,1.138732,1.138712,1.138481,1.138530,SOFT_START,931,71,SPARK_NEG_OK,1.138526,1.138597,1.138682,1.139260,SOFT_START,1238,2402,0 -220853897,932,70,SPARK_NEG_OK,1.138763,1.138694,1.138465,1.138509,SOFT_START,932,70,SPARK_NEG_OK,1.138540,1.138591,1.138651,1.139228,SOFT_START,1238,2387,0 -220902897,933,70,SPARK_NEG_OK,1.138775,1.138701,1.138453,1.138505,SOFT_START,933,71,SPARK_NEG_OK,1.138542,1.138608,1.138680,1.139384,SOFT_START,1240,2389,0 -220950897,934,69,SPARK_NEG_OK,1.138798,1.138686,1.138499,1.138535,SOFT_START,934,70,SPARK_NEG_OK,1.138515,1.138596,1.138704,1.139450,SOFT_START,1240,2381,0 -220998897,935,70,SPARK_NEG_OK,1.138781,1.138711,1.138491,1.138521,SOFT_START,935,70,SPARK_NEG_OK,1.138535,1.138591,1.138738,1.139210,SOFT_START,1239,2401,0 -221047897,936,70,SPARK_NEG_OK,1.138781,1.138735,1.138506,1.138545,SOFT_START,936,70,SPARK_NEG_OK,1.138547,1.138617,1.138716,1.139153,SOFT_START,1241,2386,0 -221095897,937,70,SPARK_NEG_OK,1.138791,1.138720,1.138507,1.138532,SOFT_START,937,71,SPARK_NEG_OK,1.138547,1.138669,1.138684,1.139240,SOFT_START,1238,2399,0 -221144897,938,70,SPARK_NEG_OK,1.138785,1.138762,1.138490,1.138516,SOFT_START,938,70,SPARK_NEG_OK,1.138545,1.138592,1.138685,1.139056,SOFT_START,1240,2401,0 -221192897,939,70,SPARK_NEG_OK,1.138803,1.138709,1.138518,1.138557,SOFT_START,939,71,SPARK_NEG_OK,1.138565,1.138603,1.138721,1.139246,SOFT_START,1237,2387,0 -221240897,940,70,SPARK_NEG_OK,1.138800,1.138734,1.138511,1.138530,SOFT_START,940,70,SPARK_NEG_OK,1.138546,1.138600,1.138703,1.138926,SOFT_START,1238,2381,0 -221289897,941,70,SPARK_NEG_OK,1.138788,1.138774,1.138521,1.138585,SOFT_START,941,70,SPARK_NEG_OK,1.138563,1.138574,1.138689,1.139204,SOFT_START,1236,2381,0 -221337897,942,70,SPARK_NEG_OK,1.138830,1.138751,1.138535,1.138561,SOFT_START,942,70,SPARK_NEG_OK,1.138546,1.138608,1.138725,1.139248,SOFT_START,1238,2383,0 -221386897,943,71,SPARK_NEG_OK,1.138820,1.138737,1.138547,1.138544,SOFT_START,943,70,SPARK_NEG_OK,1.138559,1.138645,1.138738,1.139249,SOFT_START,1237,2393,0 -221434897,944,70,SPARK_NEG_OK,1.138825,1.138796,1.138527,1.138588,SOFT_START,944,70,SPARK_NEG_OK,1.138582,1.138610,1.138727,1.139465,SOFT_START,1239,2386,0 -221483897,945,71,SPARK_NEG_OK,1.138806,1.138788,1.138517,1.138623,SOFT_START,945,70,SPARK_NEG_OK,1.138571,1.138602,1.138726,1.139297,SOFT_START,1238,2405,0 -221531897,946,70,SPARK_NEG_OK,1.138816,1.138747,1.138539,1.138577,SOFT_START,946,70,SPARK_NEG_OK,1.138563,1.138610,1.138747,1.139203,SOFT_START,1240,2404,0 -221579900,947,71,SPARK_NEG_OK,1.138776,1.138788,1.138563,1.138593,SOFT_START,947,70,SPARK_NEG_OK,1.138578,1.138632,1.138720,1.139211,SOFT_START,1238,2382,0 -221628897,948,70,SPARK_NEG_OK,1.138836,1.138794,1.138538,1.138551,SOFT_START,948,70,SPARK_NEG_OK,1.138592,1.138584,1.138733,1.139262,SOFT_START,1239,2404,0 -221676897,949,71,SPARK_NEG_OK,1.138831,1.138744,1.138527,1.138594,SOFT_START,949,70,SPARK_NEG_OK,1.138592,1.138608,1.138694,1.139244,SOFT_START,1239,2390,0 -221725897,950,70,SPARK_NEG_OK,1.138841,1.138745,1.138577,1.138580,SOFT_START,950,71,SPARK_NEG_OK,1.138584,1.138639,1.138732,1.139308,SOFT_START,1236,2391,0 -221773897,951,70,SPARK_NEG_OK,1.138803,1.138784,1.138544,1.138599,SOFT_START,951,70,SPARK_NEG_OK,1.138560,1.138605,1.138712,1.139237,SOFT_START,1237,2398,0 -221822897,952,67,SPARK_NEG_OK,1.138826,1.138778,1.138582,1.138611,SOFT_START,952,71,SPARK_NEG_OK,1.138581,1.138636,1.138760,1.139311,SOFT_START,1236,2411,0 -221870897,953,70,SPARK_NEG_OK,1.138809,1.138782,1.138555,1.138604,SOFT_START,953,70,SPARK_NEG_OK,1.138584,1.138626,1.138759,1.139137,SOFT_START,1237,2405,0 -221919897,954,70,SPARK_NEG_OK,1.138847,1.138759,1.138517,1.138604,SOFT_START,954,71,SPARK_NEG_OK,1.138621,1.138611,1.138723,1.139257,SOFT_START,1237,2379,0 -221967897,955,70,SPARK_NEG_OK,1.138815,1.138777,1.138562,1.138632,SOFT_START,955,80,SPARK_NEG_OK,1.138623,1.138625,1.138754,1.139073,SOFT_START,1239,2380,0 -222016897,956,80,SPARK_NEG_OK,1.138807,1.138755,1.138570,1.138625,SOFT_START,956,78,SPARK_NEG_OK,1.138563,1.138600,1.138769,1.139265,SOFT_START,1238,2393,0 -222064897,957,80,SPARK_NEG_OK,1.138812,1.138755,1.138597,1.138626,SOFT_START,957,80,SPARK_NEG_OK,1.138592,1.138649,1.138756,1.139272,SOFT_START,1240,2408,0 -222112897,958,70,SPARK_NEG_OK,1.138793,1.138753,1.138610,1.138633,SOFT_START,958,71,SPARK_NEG_OK,1.138590,1.138628,1.138749,1.139288,SOFT_START,1238,2394,0 -222161897,959,70,SPARK_NEG_OK,1.138840,1.138799,1.138552,1.138639,SOFT_START,959,70,SPARK_NEG_OK,1.138585,1.138557,1.138757,1.139279,SOFT_START,1239,2389,0 -222209897,960,70,SPARK_NEG_OK,1.138841,1.138772,1.138570,1.138614,SOFT_START,960,70,SPARK_NEG_OK,1.138585,1.138639,1.138766,1.139285,SOFT_START,1237,2405,0 -222258897,961,70,SPARK_NEG_OK,1.138833,1.138800,1.138585,1.138653,SOFT_START,961,70,SPARK_NEG_OK,1.138595,1.138622,1.138784,1.139384,SOFT_START,1238,2406,0 -222306897,962,71,SPARK_NEG_OK,1.138852,1.138758,1.138602,1.138672,SOFT_START,962,70,SPARK_NEG_OK,1.138633,1.138619,1.138763,1.139520,SOFT_START,1236,2403,0 -222355897,963,70,SPARK_NEG_OK,1.138843,1.138833,1.138565,1.138701,SOFT_START,963,70,SPARK_NEG_OK,1.138626,1.138626,1.138800,1.139292,SOFT_START,1237,2383,0 -222403897,964,71,SPARK_NEG_OK,1.138830,1.138762,1.138578,1.138647,SOFT_START,964,70,SPARK_NEG_OK,1.138619,1.138657,1.138798,1.139174,SOFT_START,1237,2401,0 -222452897,965,72,SPARK_NEG_OK,1.138903,1.138783,1.138594,1.138710,SOFT_START,965,70,SPARK_NEG_OK,1.138614,1.138672,1.138800,1.139312,SOFT_START,1237,2388,0 -222500897,966,71,SPARK_NEG_OK,1.138862,1.138792,1.138600,1.138672,SOFT_START,966,70,SPARK_NEG_OK,1.138620,1.138646,1.138802,1.139234,SOFT_START,1238,2400,0 -222549897,967,70,SPARK_NEG_OK,1.138904,1.138875,1.138622,1.138669,SOFT_START,967,70,SPARK_NEG_OK,1.138627,1.138691,1.138802,1.139306,SOFT_START,1239,2399,0 -222597897,968,71,SPARK_NEG_OK,1.138884,1.138830,1.138582,1.138691,SOFT_START,968,70,SPARK_NEG_OK,1.138622,1.138670,1.138780,1.139097,SOFT_START,1240,2393,0 -222645897,969,70,SPARK_NEG_OK,1.138865,1.138819,1.138597,1.138703,SOFT_START,969,71,SPARK_NEG_OK,1.138647,1.138665,1.138845,1.139318,SOFT_START,1239,2380,0 -222694897,970,70,SPARK_NEG_OK,1.138878,1.138823,1.138593,1.138674,SOFT_START,970,70,SPARK_NEG_OK,1.138612,1.138645,1.138784,1.139202,SOFT_START,1241,2384,0 -222742897,971,70,SPARK_NEG_OK,1.138830,1.138797,1.138572,1.138687,SOFT_START,971,71,SPARK_NEG_OK,1.138602,1.138667,1.138794,1.139299,SOFT_START,1239,2398,0 -222791897,972,70,SPARK_NEG_OK,1.138851,1.138797,1.138566,1.138682,SOFT_START,972,70,SPARK_NEG_OK,1.138632,1.138676,1.138814,1.139310,SOFT_START,1240,2385,0 -222839897,973,70,SPARK_NEG_OK,1.138866,1.138806,1.138585,1.138617,SOFT_START,973,71,SPARK_NEG_OK,1.138625,1.138655,1.138796,1.139300,SOFT_START,1239,2396,0 -222887897,974,70,SPARK_NEG_OK,1.138897,1.138807,1.138552,1.138721,SOFT_START,974,70,SPARK_NEG_OK,1.138619,1.138669,1.138784,1.139385,SOFT_START,1240,2397,0 -222936897,975,70,SPARK_NEG_OK,1.138884,1.138812,1.138592,1.138690,SOFT_START,975,71,SPARK_NEG_OK,1.138631,1.138670,1.138766,1.139302,SOFT_START,1240,2393,0 -222984897,976,70,SPARK_NEG_OK,1.138868,1.138822,1.138634,1.138695,SOFT_START,976,70,SPARK_NEG_OK,1.138658,1.138657,1.138794,1.139517,SOFT_START,1242,2403,0 -223032897,977,71,SPARK_NEG_OK,1.138901,1.138828,1.138607,1.138684,SOFT_START,977,71,SPARK_NEG_OK,1.138665,1.138663,1.138790,1.139341,SOFT_START,1242,2385,0 -223080897,978,70,SPARK_NEG_OK,1.138902,1.138812,1.138616,1.138704,SOFT_START,978,70,SPARK_NEG_OK,1.138665,1.138660,1.138778,1.139281,SOFT_START,1244,2379,0 -223129897,979,70,SPARK_NEG_OK,1.138884,1.138841,1.138542,1.138719,SOFT_START,979,73,SPARK_NEG_OK,1.138638,1.138677,1.138811,1.139278,SOFT_START,1244,2387,0 -223177897,980,70,SPARK_NEG_OK,1.138862,1.138856,1.138607,1.138679,SOFT_START,980,70,SPARK_NEG_OK,1.138656,1.138695,1.138780,1.139324,SOFT_START,1243,2417,0 -223225897,981,70,SPARK_NEG_OK,1.138876,1.138814,1.138586,1.138719,SOFT_START,981,80,SPARK_NEG_OK,1.138645,1.138687,1.138798,1.139123,SOFT_START,1244,2387,0 -223273897,982,80,SPARK_NEG_OK,1.138898,1.138846,1.138635,1.138726,SOFT_START,982,80,SPARK_NEG_OK,1.138624,1.138696,1.138837,1.139340,SOFT_START,1242,2388,0 -223322897,983,81,SPARK_NEG_OK,1.138914,1.138859,1.138597,1.138715,SOFT_START,983,70,SPARK_NEG_OK,1.138714,1.138678,1.138788,1.139118,SOFT_START,1243,2382,0 -223370897,984,70,SPARK_NEG_OK,1.138915,1.138847,1.138616,1.138738,SOFT_START,984,71,SPARK_NEG_OK,1.138674,1.138713,1.138816,1.139309,SOFT_START,1242,2382,0 -223418897,985,71,SPARK_NEG_OK,1.138903,1.138847,1.138608,1.138732,SOFT_START,985,70,SPARK_NEG_OK,1.138670,1.138697,1.138800,1.139299,SOFT_START,1243,2383,0 -223466897,986,70,SPARK_NEG_OK,1.138903,1.138867,1.138614,1.138725,SOFT_START,986,70,SPARK_NEG_OK,1.138655,1.138679,1.138816,1.139315,SOFT_START,1242,2393,0 -223515897,987,71,SPARK_NEG_OK,1.138933,1.138856,1.138626,1.138716,SOFT_START,987,70,SPARK_NEG_OK,1.138663,1.138709,1.138830,1.139382,SOFT_START,1244,2387,0 -223563897,988,70,SPARK_NEG_OK,1.138935,1.138870,1.138586,1.138726,SOFT_START,988,70,SPARK_NEG_OK,1.138689,1.138706,1.138839,1.139328,SOFT_START,1244,2392,0 -223611897,989,71,SPARK_NEG_OK,1.138937,1.138858,1.138626,1.138777,SOFT_START,989,70,SPARK_NEG_OK,1.138700,1.138722,1.138809,1.139390,SOFT_START,1246,2379,0 -223659897,990,70,SPARK_NEG_OK,1.138968,1.138861,1.138628,1.138763,SOFT_START,990,70,SPARK_NEG_OK,1.138660,1.138732,1.138847,1.139570,SOFT_START,1244,2395,0 -223707897,991,71,SPARK_NEG_OK,1.138954,1.138886,1.138666,1.138755,SOFT_START,991,70,SPARK_NEG_OK,1.138688,1.138717,1.138804,1.139407,SOFT_START,1245,2397,0 -223756897,992,70,SPARK_NEG_OK,1.138944,1.138866,1.138636,1.138788,SOFT_START,992,70,SPARK_NEG_OK,1.138676,1.138759,1.138830,1.139321,SOFT_START,1245,2383,0 -223804897,993,68,SPARK_NEG_OK,1.138946,1.138868,1.138659,1.138794,SOFT_START,993,70,SPARK_NEG_OK,1.138674,1.138731,1.138842,1.139379,SOFT_START,1242,2391,0 -223852897,994,70,SPARK_NEG_OK,1.138946,1.138850,1.138634,1.138771,SOFT_START,994,70,SPARK_NEG_OK,1.138694,1.138738,1.138844,1.139194,SOFT_START,1244,2404,0 -223900897,995,71,SPARK_NEG_OK,1.138949,1.138909,1.138604,1.138780,SOFT_START,995,70,SPARK_NEG_OK,1.138718,1.138716,1.138879,1.139388,SOFT_START,1242,2392,0 -223949897,996,70,SPARK_NEG_OK,1.138946,1.138915,1.138656,1.138787,SOFT_START,996,71,SPARK_NEG_OK,1.138709,1.138753,1.138822,1.139180,SOFT_START,1243,2382,0 -223997897,997,68,SPARK_NEG_OK,1.138949,1.138892,1.138663,1.138756,SOFT_START,997,70,SPARK_NEG_OK,1.138691,1.138743,1.138866,1.139335,SOFT_START,1243,2410,0 -224045897,998,70,SPARK_NEG_OK,1.138949,1.138883,1.138634,1.138793,SOFT_START,998,69,SPARK_NEG_OK,1.138707,1.138716,1.138836,1.139343,SOFT_START,1244,2403,0 -224093897,999,80,SPARK_NEG_OK,1.138917,1.138883,1.138647,1.138756,SOFT_START,999,80,SPARK_NEG_OK,1.138684,1.138726,1.138807,1.139317,SOFT_START,1244,2398,0 -224141897,1000,80,SPARK_NEG_OK,1.138939,1.138874,1.138588,1.138735,SOFT_START,1000,81,SPARK_NEG_OK,1.138645,1.138714,1.138837,1.139371,SOFT_START,1246,2385,0 -224190897,1001,70,SPARK_NEG_OK,1.138955,1.138870,1.138671,1.138775,SOFT_START,1001,70,SPARK_NEG_OK,1.138683,1.138736,1.138842,1.139333,SOFT_START,1245,2392,0 -224238897,1002,70,SPARK_NEG_OK,1.138917,1.138862,1.138651,1.138737,SOFT_START,1002,73,SPARK_NEG_OK,1.138679,1.138750,1.138825,1.139338,SOFT_START,1247,2390,0 -224286897,1003,70,SPARK_NEG_OK,1.138952,1.138886,1.138638,1.138759,SOFT_START,1003,70,SPARK_NEG_OK,1.138705,1.138757,1.138890,1.139334,SOFT_START,1244,2383,0 -224334897,1004,69,SPARK_NEG_OK,1.138941,1.138895,1.138652,1.138778,SOFT_START,1004,71,SPARK_NEG_OK,1.138698,1.138734,1.138830,1.139365,SOFT_START,1245,2404,0 -224382897,1005,70,SPARK_NEG_OK,1.138944,1.138875,1.138656,1.138818,SOFT_START,1005,70,SPARK_NEG_OK,1.138688,1.138743,1.138831,1.139299,SOFT_START,1245,2392,0 -224431897,1006,70,SPARK_NEG_OK,1.138985,1.138936,1.138653,1.138768,SOFT_START,1006,71,SPARK_NEG_OK,1.138737,1.138753,1.138809,1.139378,SOFT_START,1243,2389,0 -224479897,1007,70,SPARK_NEG_OK,1.138914,1.138886,1.138652,1.138788,SOFT_START,1007,68,SPARK_NEG_OK,1.138703,1.138780,1.138848,1.139292,SOFT_START,1244,2384,0 -224527897,1008,70,SPARK_NEG_OK,1.138924,1.138872,1.138663,1.138751,SOFT_START,1008,71,SPARK_NEG_OK,1.138696,1.138762,1.138840,1.139331,SOFT_START,1244,2383,0 -224575897,1009,71,SPARK_NEG_OK,1.138951,1.138893,1.138700,1.138775,SOFT_START,1009,70,SPARK_NEG_OK,1.138704,1.138714,1.138847,1.139207,SOFT_START,1245,2407,0 -224623897,1010,70,SPARK_NEG_OK,1.138962,1.138887,1.138644,1.138802,SOFT_START,1010,71,SPARK_NEG_OK,1.138706,1.138759,1.138844,1.139350,SOFT_START,1246,2387,0 -224671897,1011,70,SPARK_NEG_OK,1.138935,1.138905,1.138672,1.138784,SOFT_START,1011,71,SPARK_NEG_OK,1.138719,1.138740,1.138861,1.139166,SOFT_START,1247,2393,0 -224719897,1012,70,SPARK_NEG_OK,1.138909,1.138878,1.138669,1.138743,SOFT_START,1012,71,SPARK_NEG_OK,1.138687,1.138735,1.138897,1.139342,SOFT_START,1247,2395,0 -224767897,1013,70,SPARK_NEG_OK,1.138970,1.138876,1.138679,1.138750,SOFT_START,1013,70,SPARK_NEG_OK,1.138700,1.138729,1.138870,1.139369,SOFT_START,1248,2396,0 -224816897,1014,70,SPARK_NEG_OK,1.138975,1.138873,1.138675,1.138785,SOFT_START,1014,71,SPARK_NEG_OK,1.138699,1.138754,1.138854,1.139352,SOFT_START,1246,2386,0 -224864897,1015,70,SPARK_NEG_OK,1.138952,1.138886,1.138665,1.138803,SOFT_START,1015,70,SPARK_NEG_OK,1.138687,1.138715,1.138868,1.139390,SOFT_START,1246,2394,0 -224912897,1016,70,SPARK_NEG_OK,1.138920,1.138883,1.138670,1.138804,SOFT_START,1016,71,SPARK_NEG_OK,1.138706,1.138721,1.138867,1.139406,SOFT_START,1245,2394,0 -224960897,1017,71,SPARK_NEG_OK,1.138930,1.138887,1.138698,1.138773,SOFT_START,1017,70,SPARK_NEG_OK,1.138694,1.138741,1.138884,1.139380,SOFT_START,1246,2386,0 -225008897,1018,72,SPARK_NEG_OK,1.138961,1.138881,1.138669,1.138738,SOFT_START,1018,70,SPARK_NEG_OK,1.138717,1.138730,1.138901,1.139514,SOFT_START,1245,2409,0 -225056897,1019,70,SPARK_NEG_OK,1.138943,1.138933,1.138666,1.138755,SOFT_START,1019,70,SPARK_NEG_OK,1.138697,1.138756,1.138895,1.139596,SOFT_START,1246,2383,0 -225104897,1020,71,SPARK_NEG_OK,1.138999,1.138936,1.138720,1.138818,SOFT_START,1020,70,SPARK_NEG_OK,1.138699,1.138786,1.138910,1.139345,SOFT_START,1246,2380,0 -225153897,1021,70,SPARK_NEG_OK,1.138970,1.138912,1.138685,1.138822,SOFT_START,1021,70,SPARK_NEG_OK,1.138746,1.138774,1.138903,1.139404,SOFT_START,1247,2406,0 -225201897,1022,71,SPARK_NEG_OK,1.138975,1.138952,1.138692,1.138825,SOFT_START,1022,70,SPARK_NEG_OK,1.138728,1.138761,1.138909,1.139309,SOFT_START,1248,2405,0 -225249897,1023,70,SPARK_NEG_OK,1.138976,1.138929,1.138706,1.138787,SOFT_START,1023,70,SPARK_NEG_OK,1.138740,1.138774,1.138877,1.139427,SOFT_START,1247,2393,0 -225297897,1024,71,SPARK_NEG_OK,1.138995,1.138904,1.138741,1.138799,SOFT_START,1024,70,SPARK_NEG_OK,1.138749,1.138751,1.138943,1.139138,SOFT_START,1248,2399,0 -ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ \ No newline at end of file From 481f12f526e4f5c0be706bb6855c210732a5e67b Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Wed, 8 Apr 2026 10:26:44 +0200 Subject: [PATCH 08/38] Enable/Disable pickup simulation --- RotaxMonitorTester/src/main.cpp | 23 ++++++++++++++++++++++- RotaxMonitorTester/src/pins.h | 3 +++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/RotaxMonitorTester/src/main.cpp b/RotaxMonitorTester/src/main.cpp index ea657e7..27744ef 100644 --- a/RotaxMonitorTester/src/main.cpp +++ b/RotaxMonitorTester/src/main.cpp @@ -54,6 +54,8 @@ static timerStatus stsA = { .spark_delay_us = 50, .main_task = NULL}; +static bool isEnabled = false; + void setup() { @@ -76,9 +78,14 @@ void setup() pinMode(SPARK_B34, OUTPUT); pinMode(SPARK_DELAY_POT, ANALOG); + pinMode(FREQ_POT, ANALOG); + + pinMode(ENABLE_PIN, INPUT_PULLUP); + stsA.main_task = xTaskGetCurrentTaskHandleForCore(1); timerA = timerBegin(FREQUENCY); + timerStop(timerA); timerAttachInterruptArg(timerA, &onTimer, (void *)&stsA); timerAlarm(timerA, 1, true, 0); @@ -100,11 +107,25 @@ void loop() double new_rpm = (double)(map(analogRead(FREQ_POT), 0, 4096, RPM_MIN, RPM_MAX)); filtered_rpm = filtered_rpm + 0.1 * (new_rpm - filtered_rpm); stsA.pause_long_us = (uint32_t)(60000000.0f / filtered_rpm / 2.0f); + + if (isEnabled) { + LOG_INFO("==== System is ENABLED ===="); + } else { + LOG_INFO("==== System is DISABLED ===="); + } + LOG_INFO("Spark Delay uS: ", stsA.spark_delay_us, "\tSoft Start: ", stsA.soft_start ? "TRUE" : "FALSE"); LOG_INFO("Engine Rpm: ", (uint32_t)(filtered_rpm)); LOG_INFO("Coil Pulse: ", stsA.coil_pulse_us, "us"); LOG_INFO("Spark Pulse: ", stsA.spark_pulse_us, "us"); - + + if (digitalRead(ENABLE_PIN) == LOW && !isEnabled) { + timerStart(timerA); + isEnabled = true; + } else if (digitalRead(ENABLE_PIN) == HIGH && isEnabled) { + timerStop(timerA); + isEnabled = false; + } delay(100); clearScreen(); diff --git a/RotaxMonitorTester/src/pins.h b/RotaxMonitorTester/src/pins.h index cced640..6d2e8da 100644 --- a/RotaxMonitorTester/src/pins.h +++ b/RotaxMonitorTester/src/pins.h @@ -1,5 +1,8 @@ #pragma once +// Enable Pin +#define ENABLE_PIN 16 + ///// Ignition Box A ///// #define PIN_TRIG_A12P 18 #define PIN_TRIG_A12N 19 From 07eb06f67bdd6f2c541bdd68b468bb42958ab766 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Wed, 8 Apr 2026 10:27:18 +0200 Subject: [PATCH 09/38] Save History Sync on flash, still some issues in deleting previous file --- .../partitions/no_ota_10mb_spiffs.csv | 4 +- RotaxMonitor/platformio.ini | 2 +- RotaxMonitor/src/datasave.cpp | 49 ++++++++++--------- RotaxMonitor/src/datasave.h | 36 +++++++++----- RotaxMonitor/src/main.cpp | 10 ++-- 5 files changed, 59 insertions(+), 42 deletions(-) diff --git a/RotaxMonitor/partitions/no_ota_10mb_spiffs.csv b/RotaxMonitor/partitions/no_ota_10mb_spiffs.csv index 0ee5735..c585eb5 100644 --- a/RotaxMonitor/partitions/no_ota_10mb_spiffs.csv +++ b/RotaxMonitor/partitions/no_ota_10mb_spiffs.csv @@ -2,5 +2,5 @@ # Name, Type, SubType, Offset, Size nvs, data, nvs, 0x9000, 0x4000 phy_init, data, phy, 0xd000, 0x1000 -factory, app, factory, 0x10000, 0x5F0000 -spiffs, data, spiffs, 0x600000, 0xA00000 \ No newline at end of file +factory, app, factory, 0x10000, 0x300000 +spiffs, data, spiffs, 0x310000, 0xCF0000 \ No newline at end of file diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 808c594..9001479 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -47,7 +47,7 @@ lib_deps = ${env:esp32-s3-devkitc1-n16r8.lib_deps} ;Upload protocol configuration upload_protocol = esptool -upload_port = COM4 +upload_port = COM8 upload_speed = 921600 ;Monitor configuration diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index ccf52bf..7387dc4 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -1,45 +1,51 @@ #include "datasave.h" static const size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB) -static bool first_save = true; // flag to indicate if this is the first save (to write header) -void save_history(const PSRAMVector &history, const std::filesystem::path &file_path) +void saveHistoryTask(void *pvParameters) +{ + const auto *params = static_cast(pvParameters); + const auto &history = *params->history; + const auto &file_path = params->file_path; + if (!params) { + LOG_ERROR("Invalid parameters for saveHistoryTask"); + return; + } + LOG_DEBUG("Starting saving: ", file_path.c_str()); + save_history(history, file_path); + vTaskDelete(NULL); +} + +void save_history(const PSRAMVector &history, const std::filesystem::path &file_name) { // Initialize SPIFFS - if (!SPIFFS.begin(true)) - { - LOG_ERROR("Failed to mount SPIFFS"); - LOG_ERROR("5 seconds to restart..."); - vTaskDelay(pdMS_TO_TICKS(5000)); - esp_restart(); - } + auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted - LOG_INFO("SPIFFS mounted successfully"); if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free ) // check if at least 1MB is free for saving history { LOG_ERROR("Not enough space in SPIFFS to save history"); return; } - std::filesystem::path to_save = file_path; - if (file_path.root_path() != "/spiffs") - to_save = std::filesystem::path("/spiffs") / file_path; + std::filesystem::path file_path = file_name; + if (file_name.root_path() != "/spiffs") + file_path = std::filesystem::path("/spiffs") / file_name; auto save_flags = std::ios::out; - if (first_save && SPIFFS.exists(to_save.c_str())) + if (first_save && SPIFFS.exists(file_path.c_str())) { first_save = false; save_flags |= std::ios::trunc; // overwrite existing file - SPIFFS.remove(to_save.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS - LOG_INFO("Saving history to SPIFFS, new file: ", to_save.c_str()); + SPIFFS.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS + LOG_INFO("Saving history to SPIFFS, new file:", file_path.c_str()); } else { save_flags |= std::ios::app; // append to new file - LOG_INFO("Saving history to SPIFFS, appending to existing file: ", to_save.c_str()); + LOG_INFO("Saving history to SPIFFS, appending to existing file:", file_path.c_str()); } - std::ofstream ofs(to_save, save_flags); + std::ofstream ofs(file_path, save_flags); if (ofs.fail()) { LOG_ERROR("Failed to open file for writing"); @@ -50,9 +56,9 @@ void save_history(const PSRAMVector &history, const std::file if (first_save) { ofs << "TS,\ - EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ - EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ - ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" << std::endl; + EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ + EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ + ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" << std::endl; ofs.flush(); } @@ -84,5 +90,4 @@ void save_history(const PSRAMVector &history, const std::file ofs.close(); LOG_INFO("Ignition A history saved to SPIFFS, records written: ", history.size()); - SPIFFS.end(); // unmount SPIFFS to ensure data is written and avoid corruption on next mount } diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index 109e3e0..60e7599 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -1,4 +1,5 @@ #pragma once +#define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO // System Includes #include @@ -14,6 +15,7 @@ const uint32_t max_history = 256; const bool SAVE_HISTORY_TO_SPIFFS = true; // Set to true to enable saving history to SPIFFS, false to disable +static bool first_save = true; // flag to indicate if this is the first save (to write header) struct dataSaveParams { @@ -21,18 +23,26 @@ struct dataSaveParams const std::filesystem::path file_path; }; +class SPIFFSGuard +{ +public: + SPIFFSGuard() { + if (!SPIFFS.begin(true)) { + LOG_ERROR("Failed to mount SPIFFS"); + LOG_ERROR("5 seconds to restart..."); + vTaskDelay(pdMS_TO_TICKS(5000)); + esp_restart(); + } + LOG_DEBUG("SPIFFS mounted successfully"); + } + + ~SPIFFSGuard() { + SPIFFS.end(); + LOG_DEBUG("SPIFFS unmounted successfully"); + } +}; + +// Task and function declarations +void saveHistoryTask(void *pvParameters); void save_history(const PSRAMVector &history, const std::filesystem::path& file_path); -static void saveHistoryTask(void *pvParameters) -{ - const auto *params = static_cast(pvParameters); - const auto &history = *params->history; - const auto &file_path = params->file_path; - if (!params) { - LOG_ERROR("Invalid parameters for saveHistoryTask"); - return; - } - LOG_INFO("Starting saving: ", file_path.c_str()); - save_history(history, file_path); - //vTaskDelete(NULL); -} diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 050146a..65a2ec8 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -189,10 +189,10 @@ void loop() auto *temp = active_history; active_history = writable_history; // switch active and writable buffers writable_history = temp; // ensure writable_history points to the buffer we just filled - dataSaveParams save_params{ + dataSaveParams save_params { .history = writable_history, .file_path = "ignition_history.csv"}; - saveHistoryTask(&save_params); // directly call the save task function to save without delay, since we already switched buffers and writable_history is now empty and ready for new data + save_history(*writable_history, "ignition_history.csv"); // directly call the save task function to save without delay, since we already switched buffers and writable_history is now empty and ready for new data // if (SAVE_HISTORY_TO_SPIFFS) // if (pdFAIL == // xTaskCreatePinnedToCore( @@ -220,10 +220,12 @@ void loop() Serial.println("Waiting for data... "); if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout { + active_history->resize(counter); // resize active history to actual number of records received to avoid saving empty records + save_history(*active_history, "ignition_history.csv"); + active_history->resize(max_history); // resize back to max history size for next data cycle counter = 0; // reset counter after saving partial_save = true; - Serial.println("Saving history to SPIFFS..."); - save_history(*active_history, "ignition_history.csv"); + first_save = true; } delay(500); } From 4dc45954e9c0d2adc83f152a0fbea9b7b8dfcc3d Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Wed, 8 Apr 2026 15:23:21 +0200 Subject: [PATCH 10/38] Webpage is OK, html in memory since SPIFFS is to slow. Moving average to be fixed --- RotaxMonitor/data/index.html | 198 ++++++++++++++++++++++++++++++++++ RotaxMonitor/platformio.ini | 60 ++++++----- RotaxMonitor/src/datasave.cpp | 106 +++++++++++++++++- RotaxMonitor/src/datasave.h | 42 +++++--- RotaxMonitor/src/devices.h | 2 - RotaxMonitor/src/main.cpp | 109 ++++++++++++++----- RotaxMonitor/src/ui.h | 190 +++++++++++++++++++++++++++++++- 7 files changed, 629 insertions(+), 78 deletions(-) create mode 100644 RotaxMonitor/data/index.html diff --git a/RotaxMonitor/data/index.html b/RotaxMonitor/data/index.html new file mode 100644 index 0000000..783cd00 --- /dev/null +++ b/RotaxMonitor/data/index.html @@ -0,0 +1,198 @@ + + + + + ESP32 Dashboard + + + + +

RotaxMonitor realtime data

+ + + + +
+

Timestamp: -

+

Generator voltage: -

+

Engine RPM: -

+

ADC read time: -

+

Queue errors: -

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyCoils 12Coils 34
Trigger time--
Spark time--
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Events--
Missed firings--
+
+ + + + + \ No newline at end of file diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 9001479..9e5b1bf 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -11,60 +11,62 @@ [env:esp32-s3-devkitc1-n16r8] board = esp32-s3-devkitc1-n16r8 board_build.partitions = partitions/no_ota_10mb_spiffs.csv +board_build.filesystem = spiffs platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip framework = arduino lib_deps = hideakitai/DebugLog@^0.8.4 bblanchon/ArduinoJson@^7.4.2 hideakitai/PCA95x5@^0.1.3 - adafruit/Adafruit SSD1306@^2.5.16 - garfius/Menu-UI@^1.2.0 - -;Upload protocol configuration + me-no-dev/AsyncTCP@^3.3.2 + me-no-dev/ESPAsyncWebServer@^3.6.0 upload_protocol = esptool upload_port = COM8 upload_speed = 921600 - -;Monitor configuration monitor_port = COM4 monitor_speed = 921600 - -; Build configuration build_type = release build_flags = - -DARDUINO_USB_CDC_ON_BOOT=0 - -DARDUINO_USB_MODE=0 - -fstack-protector-all - -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 - -DCONFIG_FREERTOS_USE_TRACE_FACILITY=1 + -DCORE_DEBUG_LEVEL=5 + -DARDUINO_USB_CDC_ON_BOOT=0 + -DARDUINO_USB_MODE=0 + -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 + -DCONFIG_FREERTOS_USE_TRACE_FACILITY=1 + -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 + -DCONFIG_ASYNC_TCP_PRIORITY=20 + -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 + -DCONFIG_ASYNC_TCP_RUNNING_CORE=1 + -DCONFIG_ASYNC_TCP_STACK_SIZE=8192 + -fstack-protector-all [env:esp32-s3-devkitc1-n16r8-debug] board = ${env:esp32-s3-devkitc1-n16r8.board} board_build.partitions = ${env:esp32-s3-devkitc1-n16r8.board_build.partitions} +board_build.filesystem = ${env:esp32-s3-devkitc1-n16r8.board_build.filesystem} platform = ${env:esp32-s3-devkitc1-n16r8.platform} framework = ${env:esp32-s3-devkitc1-n16r8.framework} -lib_deps = ${env:esp32-s3-devkitc1-n16r8.lib_deps} - -;Upload protocol configuration +lib_deps = + ${env:esp32-s3-devkitc1-n16r8.lib_deps} upload_protocol = esptool upload_port = COM8 upload_speed = 921600 - -;Monitor configuration monitor_port = COM4 monitor_speed = 921600 - -; Debug configuration debug_tool = esp-builtin debug_speed = 15000 - -; Build configuration build_type = debug build_flags = - -O0 - -g3 - -ggdb3 - -DCORE_DEBUG_LEVEL=5 - -DARDUINO_USB_CDC_ON_BOOT=0 - -DARDUINO_USB_MODE=0 - -fstack-protector-all + -O0 + -g3 + -ggdb3 + -DCORE_DEBUG_LEVEL=5 + -DARDUINO_USB_CDC_ON_BOOT=0 + -DARDUINO_USB_MODE=0 + -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 + -DCONFIG_FREERTOS_USE_TRACE_FACILITY=1 + -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 + -DCONFIG_ASYNC_TCP_PRIORITY=20 + -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 + -DCONFIG_ASYNC_TCP_RUNNING_CORE=1 + -DCONFIG_ASYNC_TCP_STACK_SIZE=8192 + -fstack-protector-all diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index 7387dc4..37fc778 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -2,12 +2,106 @@ static const size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB) +void ignitionBoxStatusAverage::reset() +{ + m_last = ignitionBoxStatus(); + m_count = 0; + m_data_valid = false; +} + +void ignitionBoxStatusAverage::update(const ignitionBoxStatus &new_status) +{ + if (m_count == 0) + { + m_last = new_status; + } + else + { + // simple moving average calculation + m_last.timestamp = new_status.timestamp; // keep timestamp of latest status + + m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging + m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging + m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status + m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status + m_last.coils12.spark_delay += (uint32_t)(0.1f * (float)(new_status.coils12.spark_delay - m_last.coils12.spark_delay)); // incremental average calculation + m_last.coils12.peak_p_in += 1.0f / m_max_count * (new_status.coils12.peak_p_in - m_last.coils12.peak_p_in); // incremental average calculation + m_last.coils12.peak_n_in += 1.0f / m_max_count * (new_status.coils12.peak_n_in - m_last.coils12.peak_n_in); // incremental average calculation + m_last.coils12.peak_p_out += 1.0f / m_max_count * (new_status.coils12.peak_p_out - m_last.coils12.peak_p_out); // incremental average calculation + m_last.coils12.peak_n_out += 1.0f / m_max_count * (new_status.coils12.peak_n_out - m_last.coils12.peak_n_out); // incremental average calculation + + m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging + m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging + m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status + m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status + m_last.coils34.spark_delay += (uint32_t)(0.1f * (float)(new_status.coils34.spark_delay - m_last.coils34.spark_delay)); // incremental average calculation + m_last.coils34.peak_p_in += 1.0f / m_max_count * (new_status.coils34.peak_p_in - m_last.coils34.peak_p_in); // incremental average calculation + m_last.coils34.peak_n_in += 1.0f / m_max_count * (new_status.coils34.peak_n_in - m_last.coils34.peak_n_in); // incremental average calculation + m_last.coils34.peak_p_out += 1.0f / m_max_count * (new_status.coils34.peak_p_out - m_last.coils34.peak_p_out); // incremental average calculation + m_last.coils34.peak_n_out += 1.0f / m_max_count * (new_status.coils34.peak_n_out - m_last.coils34.peak_n_out); // incremental average calculation + + m_last.eng_rpm += (uint32_t)(0.1f * (float)(new_status.eng_rpm - m_last.eng_rpm)); // incremental average calculation + m_last.adc_read_time += (uint32_t)(0.1f * (float)(new_status.adc_read_time - m_last.adc_read_time)); // incremental average calculation + m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value + } + m_count++; + if (m_count >= m_max_count) + { + m_count = 0; // reset count after reaching max samples to average + m_data_valid = true; // set data valid flag after first average is calculated + } +} + +const bool ignitionBoxStatusAverage::get(ignitionBoxStatus &status) const +{ + if (m_data_valid) + { + status = m_last; + } + return m_data_valid; +} + +const ArduinoJson::JsonDocument ignitionBoxStatusAverage::toJson() const +{ + ArduinoJson::JsonDocument doc; + if (m_data_valid) + { + doc["timestamp"] = m_last.timestamp; + + doc["coils12"]["n_events"] = m_last.coils12.n_events; + doc["coils12"]["n_missed_firing"] = m_last.coils12.n_missed_firing; + doc["coils12"]["spark_delay"] = m_last.coils12.spark_delay; + doc["coils12"]["spark_status"] = sparkStatusNames.at(m_last.coils12.spark_status); + doc["coils12"]["peak_p_in"] = m_last.coils12.peak_p_in; + doc["coils12"]["peak_n_in"] = m_last.coils12.peak_n_in; + doc["coils12"]["peak_p_out"] = m_last.coils12.peak_p_out; + doc["coils12"]["peak_n_out"] = m_last.coils12.peak_n_out; + doc["coils12"]["sstart_status"] = softStartStatusNames.at(m_last.coils12.sstart_status); + + doc["coils34"]["n_events"] = m_last.coils34.n_events; + doc["coils34"]["n_missed_firing"] = m_last.coils34.n_missed_firing; + doc["coils34"]["spark_delay"] = m_last.coils34.spark_delay; + doc["coils34"]["spark_status"] = sparkStatusNames.at(m_last.coils34.spark_status); + doc["coils34"]["peak_p_in"] = m_last.coils34.peak_p_in; + doc["coils34"]["peak_n_in"] = m_last.coils34.peak_n_in; + doc["coils34"]["peak_p_out"] = m_last.coils34.peak_p_out; + doc["coils34"]["peak_n_out"] = m_last.coils34.peak_n_out; + doc["coils34"]["sstart_status"] = softStartStatusNames.at(m_last.coils34.sstart_status); + + doc["eng_rpm"] = m_last.eng_rpm; + doc["adc_read_time"] = m_last.adc_read_time; + doc["n_queue_errors"] = m_last.n_queue_errors; + } + return doc; +} + void saveHistoryTask(void *pvParameters) { const auto *params = static_cast(pvParameters); const auto &history = *params->history; const auto &file_path = params->file_path; - if (!params) { + if (!params) + { LOG_ERROR("Invalid parameters for saveHistoryTask"); return; } @@ -19,9 +113,10 @@ void saveHistoryTask(void *pvParameters) void save_history(const PSRAMVector &history, const std::filesystem::path &file_name) { // Initialize SPIFFS - auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted + if (!SAVE_HISTORY_TO_SPIFFS) return; + //auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted - if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free ) // check if at least 1MB is free for saving history + if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free) // check if at least 1MB is free for saving history { LOG_ERROR("Not enough space in SPIFFS to save history"); return; @@ -35,7 +130,7 @@ void save_history(const PSRAMVector &history, const std::file if (first_save && SPIFFS.exists(file_path.c_str())) { first_save = false; - save_flags |= std::ios::trunc; // overwrite existing file + save_flags |= std::ios::trunc; // overwrite existing file SPIFFS.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS LOG_INFO("Saving history to SPIFFS, new file:", file_path.c_str()); } @@ -58,7 +153,8 @@ void save_history(const PSRAMVector &history, const std::file ofs << "TS,\ EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ - ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" << std::endl; + ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" + << std::endl; ofs.flush(); } diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index 60e7599..21851b6 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -8,14 +8,15 @@ #include #include #include +#include // Project Includes #include "isr.h" #include "psvector.h" const uint32_t max_history = 256; -const bool SAVE_HISTORY_TO_SPIFFS = true; // Set to true to enable saving history to SPIFFS, false to disable -static bool first_save = true; // flag to indicate if this is the first save (to write header) +const bool SAVE_HISTORY_TO_SPIFFS = false; // Set to true to enable saving history to SPIFFS, false to disable +static bool first_save = true; // flag to indicate if this is the first save (to write header) struct dataSaveParams { @@ -26,23 +27,40 @@ struct dataSaveParams class SPIFFSGuard { public: - SPIFFSGuard() { - if (!SPIFFS.begin(true)) { + SPIFFSGuard() + { + if (!SPIFFS.begin(true)) + { LOG_ERROR("Failed to mount SPIFFS"); - LOG_ERROR("5 seconds to restart..."); - vTaskDelay(pdMS_TO_TICKS(5000)); - esp_restart(); } - LOG_DEBUG("SPIFFS mounted successfully"); + LOG_INFO("SPIFFS mounted successfully"); } - ~SPIFFSGuard() { + ~SPIFFSGuard() + { SPIFFS.end(); - LOG_DEBUG("SPIFFS unmounted successfully"); + LOG_INFO("SPIFFS unmounted successfully"); } }; +class ignitionBoxStatusAverage +{ +private: + ignitionBoxStatus m_last; + uint32_t m_count = 0; + uint32_t m_max_count = 100; // number of samples to average before resetting + bool m_data_valid = false; // flag to indicate if the average data is valid (i.e. at least one sample has been added) + +public: + ignitionBoxStatusAverage() = default; + ignitionBoxStatusAverage(const uint32_t max_count) : m_max_count(max_count) {} + + void reset(); + void update(const ignitionBoxStatus &new_status); + const bool get(ignitionBoxStatus &status) const; + const ArduinoJson::JsonDocument toJson() const; +}; + // Task and function declarations void saveHistoryTask(void *pvParameters); -void save_history(const PSRAMVector &history, const std::filesystem::path& file_path); - +void save_history(const PSRAMVector &history, const std::filesystem::path &file_path); diff --git a/RotaxMonitor/src/devices.h b/RotaxMonitor/src/devices.h index e6027e5..d43d2c1 100644 --- a/RotaxMonitor/src/devices.h +++ b/RotaxMonitor/src/devices.h @@ -6,7 +6,6 @@ // Device Libraries #include #include -#include #include // ADC Channel mapping @@ -23,7 +22,6 @@ struct Devices { AD5292 *pot_a = NULL, *pot_b = NULL; ADS1256 *adc_a = NULL, *adc_b = NULL; - Adafruit_SSD1306* lcd = NULL; PCA9555* io = NULL; }; diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 65a2ec8..c793436 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -5,6 +5,10 @@ #include #include #include +#include +#include +#include +#include // Definitions #include @@ -19,6 +23,23 @@ // #define CH_B_ENABLE #define TEST +#define WIFI_SSID "AstroRotaxMonitor" +#define WIFI_PASSWORD "maledettirotax" + +void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, + AwsEventType type, void *arg, uint8_t *data, size_t len) +{ + switch (type) + { + case WS_EVT_CONNECT: + Serial.printf("WS client IP[%s]-ID[%u] CONNECTED\r\n", client->remoteIP().toString().c_str(), client->id()); + break; + case WS_EVT_DISCONNECT: + Serial.printf("WS client ID[%u] DISCONNECTED\r\n", client->remoteIP().toString().c_str(), client->id()); + break; + } +} + void setup() { Serial.begin(921600); @@ -29,21 +50,43 @@ void setup() LOG_SET_LEVEL(DebugLogLevel::LVL_INFO); // Print Processor Info - LOG_INFO("ESP32 Chip:", ESP.getChipModel()); + LOG_DEBUG("ESP32 Chip:", ESP.getChipModel()); if (psramFound()) { - LOG_INFO("ESP32 PSram Found"); - LOG_INFO("ESP32 PSram:", ESP.getPsramSize()); + LOG_DEBUG("ESP32 PSram Found"); + LOG_DEBUG("ESP32 PSram:", ESP.getPsramSize()); psramInit(); } - LOG_INFO("ESP32 Flash:", ESP.getFlashChipSize()); - LOG_INFO("ESP32 Heap:", ESP.getHeapSize()); - LOG_INFO("ESP32 Sketch:", ESP.getFreeSketchSpace()); + LOG_DEBUG("ESP32 Flash:", ESP.getFlashChipSize()); + LOG_DEBUG("ESP32 Heap:", ESP.getHeapSize()); + LOG_DEBUG("ESP32 Sketch:", ESP.getFreeSketchSpace()); // Initialize Interrupt pins on PICKUP detectors initTriggerPinsInputs(); // Initialize Interrupt pins on SPARK detectors initSparkPinInputs(); + + // Init Wifi station + LOG_INFO("Initializing WiFi..."); + WiFi.mode(WIFI_AP); + IPAddress local_IP(10, 11, 12, 1); + IPAddress gateway(10, 11, 12, 1); + IPAddress subnet(255, 255, 255, 0); + WiFi.softAPConfig(local_IP, gateway, subnet); + if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD)) + { + LOG_INFO("WiFi AP Mode Started"); + LOG_INFO("Wifi SSID:", WIFI_SSID); + LOG_INFO("Wifi Password:", WIFI_PASSWORD); + LOG_INFO("WiFi IP:" + WiFi.softAPIP().toString()); + } + else + { + LOG_ERROR("Failed to start WiFi AP Mode"); + LOG_ERROR("5 seconds to restart..."); + vTaskDelay(pdMS_TO_TICKS(5000)); + esp_restart(); + } } void loop() @@ -79,7 +122,7 @@ void loop() .spark_pin_34 = SPARK_PIN_A34}, .rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_A12P, .rst_io_12n = RST_EXT_A12N, .rst_io_34p = RST_EXT_A34P, .rst_io_34n = RST_EXT_A34N}}; - LOG_INFO("Task Variables OK"); + LOG_DEBUG("Task Variables OK"); #ifdef CH_B_ENABLE QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); @@ -118,7 +161,7 @@ void loop() vTaskDelay(pdMS_TO_TICKS(5000)); esp_restart(); } - LOG_INFO("Init SPI OK"); + LOG_DEBUG("Init SPI OK"); // Init ADC_A dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADC_A_SYNC, ADC_A_CS, 2.5, &SPI_A); @@ -134,7 +177,7 @@ void loop() dev.adc_a->setDRATE(DRATE_1000SPS); #endif - LOG_INFO("Init ADC OK"); + LOG_DEBUG("Init ADC OK"); // Ignition A on Core 0 auto ignA_task_success = pdPASS; @@ -168,17 +211,29 @@ void loop() esp_restart(); } - LOG_INFO("Real Time Tasks A & B initialized"); + LOG_DEBUG("Real Time Tasks A & B initialized"); ////////////////////// MAIN LOOP ////////////////////// - clearScreen(); - setCursor(0, 0); bool partial_save = false; // flag to indicate if a partial save has been done after a timeout uint32_t counter = 0; + uint32_t wait_count = 0; ignitionBoxStatus ign_info; int64_t last = esp_timer_get_time(); uint32_t missed_firings12 = 0; uint32_t missed_firings34 = 0; + ignitionBoxStatusAverage ignA_avg(max_queue); // moving average calculator for ignition box A with a window of 100 samples + + AsyncWebServer server(80); + AsyncWebSocket ws("/ws"); + ws.onEvent(onWsEvent); + server.addHandler(&ws); + + auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html"); + server.begin(); + + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) + { request->send(200, "text/html", htmlTest.c_str()); }); while (running) { @@ -189,23 +244,10 @@ void loop() auto *temp = active_history; active_history = writable_history; // switch active and writable buffers writable_history = temp; // ensure writable_history points to the buffer we just filled - dataSaveParams save_params { + dataSaveParams save_params{ .history = writable_history, .file_path = "ignition_history.csv"}; - save_history(*writable_history, "ignition_history.csv"); // directly call the save task function to save without delay, since we already switched buffers and writable_history is now empty and ready for new data - // if (SAVE_HISTORY_TO_SPIFFS) - // if (pdFAIL == - // xTaskCreatePinnedToCore( - // saveHistoryTask, - // "saveHistoryTask", - // RT_TASK_STACK, - // &save_params, - // RT_TASK_PRIORITY - 1, // higher priority to ensure it runs asap after buffer switch - // NULL, - // CORE_1)) - // { - // LOG_ERROR("Unable to create saveHistoryTask"); - // } + save_history(*writable_history, "ignition_history.csv"); // directly call the save task function to save without delay } if (xQueueReceive(rt_taskA_queue, &ign_info, pdMS_TO_TICKS(1000)) == pdTRUE) @@ -213,17 +255,26 @@ void loop() // printInfo(ign_info); auto &hist = *active_history; hist[counter++ % active_history->size()] = ign_info; + ignA_avg.update(ign_info); // update moving average with latest ignition status Serial.print("Data Received: " + String(counter) + "/" + String(hist.size()) + '\r'); + + if (ws.count() > 0 && counter % max_queue == 0) + { + Serial.println(); + LOG_INFO("Sending average ignition status to websocket clients..."); + auto msg = ignA_avg.toJson().as(); + ws.textAll(msg); + } } else { - Serial.println("Waiting for data... "); + Serial.printf("[%d] Waiting for data...\r", wait_count++); if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout { active_history->resize(counter); // resize active history to actual number of records received to avoid saving empty records save_history(*active_history, "ignition_history.csv"); active_history->resize(max_history); // resize back to max history size for next data cycle - counter = 0; // reset counter after saving + counter = 0; // reset counter after saving partial_save = true; first_save = true; } diff --git a/RotaxMonitor/src/ui.h b/RotaxMonitor/src/ui.h index a260e19..2d439ec 100644 --- a/RotaxMonitor/src/ui.h +++ b/RotaxMonitor/src/ui.h @@ -2,6 +2,7 @@ #include #include +#include void clearScreen(); void setCursor(const uint8_t x, const uint8_t y); @@ -10,4 +11,191 @@ void printField(const char name[], const int64_t val); void printField(const char name[], const float val); void printField(const char name[], const char *val); -void printInfo(const ignitionBoxStatus &info); \ No newline at end of file +void printInfo(const ignitionBoxStatus &info); + +static const std::string htmlTest = R"rawliteral( + + + + + ESP32 Dashboard + + + + +

RotaxMonitor realtime data

+ + + + +
+

Timestamp: -

+

Generator voltage: -

+

Engine RPM: -

+

ADC read time: -

+

Queue errors: -

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyCoils 12Coils 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Events--
Missed firings--
+
+ + + + + +)rawliteral"; \ No newline at end of file From 12e1e8e7a4abc9a74b66e73fef3dc3ccaefe87fb Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Wed, 8 Apr 2026 16:55:03 +0200 Subject: [PATCH 11/38] Fixed Filters, split file in html, script and css --- RotaxMonitor/data/index.html | 116 +--------------------------------- RotaxMonitor/data/script.js | 66 +++++++++++++++++++ RotaxMonitor/data/style.css | 29 +++++++++ RotaxMonitor/src/datasave.cpp | 78 +++++++++++++---------- RotaxMonitor/src/datasave.h | 9 ++- RotaxMonitor/src/datastruct.h | 6 +- RotaxMonitor/src/main.cpp | 2 +- RotaxMonitor/src/tasks.cpp | 8 +-- RotaxMonitor/src/ui.cpp | 5 ++ RotaxMonitor/src/ui.h | 3 + 10 files changed, 167 insertions(+), 155 deletions(-) create mode 100644 RotaxMonitor/data/script.js create mode 100644 RotaxMonitor/data/style.css diff --git a/RotaxMonitor/data/index.html b/RotaxMonitor/data/index.html index 783cd00..656686d 100644 --- a/RotaxMonitor/data/index.html +++ b/RotaxMonitor/data/index.html @@ -3,37 +3,7 @@ ESP32 Dashboard - + @@ -44,6 +14,7 @@

Timestamp: -

+

Data Valid: -

Generator voltage: -

Engine RPM: -

ADC read time: -

@@ -58,16 +29,6 @@ - - Trigger time - - - - - - - Spark time - - - - - Spark delay - @@ -122,77 +83,6 @@
- - + \ No newline at end of file diff --git a/RotaxMonitor/data/script.js b/RotaxMonitor/data/script.js new file mode 100644 index 0000000..db58a84 --- /dev/null +++ b/RotaxMonitor/data/script.js @@ -0,0 +1,66 @@ +let ws; + +function connectWS() { + ws = new WebSocket("ws://" + location.host + "/ws"); + + ws.onopen = () => { + console.log("WebSocket connesso"); + }; + + ws.onclose = () => { + console.log("WebSocket disconnesso, retry..."); + setTimeout(connectWS, 5000); + }; + + ws.onmessage = (event) => { + let data; + + try { + data = JSON.parse(event.data); + } catch (e) { + console.error("Invalid JSON received", e); + return; + } + + document.getElementById("datavalid").textContent = data.datavalid ?? "-"; + document.getElementById("timestamp").textContent = data.timestamp ?? "-"; + document.getElementById("volts_gen").textContent = data.volts_gen ?? "-"; + document.getElementById("eng_rpm").textContent = data.eng_rpm ?? "-"; + document.getElementById("adc_read_time").textContent = data.adc_read_time ?? "-"; + document.getElementById("n_queue_errors").textContent = data.n_queue_errors ?? "-"; + + const coils12 = data.coils12 || {}; + const coils34 = data.coils34 || {}; + + document.getElementById("coils12_spark_delay").textContent = coils12.spark_delay ?? "-"; + document.getElementById("coils34_spark_delay").textContent = coils34.spark_delay ?? "-"; + document.getElementById("coils12_spark_status").textContent = coils12.spark_status ?? "-"; + document.getElementById("coils34_spark_status").textContent = coils34.spark_status ?? "-"; + document.getElementById("coils12_sstart_status").textContent = coils12.sstart_status ?? "-"; + document.getElementById("coils34_sstart_status").textContent = coils34.sstart_status ?? "-"; + document.getElementById("coils12_peak_p_in").textContent = coils12.peak_p_in ?? "-"; + document.getElementById("coils34_peak_p_in").textContent = coils34.peak_p_in ?? "-"; + document.getElementById("coils12_peak_n_in").textContent = coils12.peak_n_in ?? "-"; + document.getElementById("coils34_peak_n_in").textContent = coils34.peak_n_in ?? "-"; + document.getElementById("coils12_peak_p_out").textContent = coils12.peak_p_out ?? "-"; + document.getElementById("coils34_peak_p_out").textContent = coils34.peak_p_out ?? "-"; + document.getElementById("coils12_peak_n_out").textContent = coils12.peak_n_out ?? "-"; + document.getElementById("coils34_peak_n_out").textContent = coils34.peak_n_out ?? "-"; + document.getElementById("coils12_level_spark").textContent = coils12.level_spark ?? "-"; + document.getElementById("coils34_level_spark").textContent = coils34.level_spark ?? "-"; + document.getElementById("coils12_n_events").textContent = coils12.n_events ?? "-"; + document.getElementById("coils34_n_events").textContent = coils34.n_events ?? "-"; + document.getElementById("coils12_n_missed_firing").textContent = coils12.n_missed_firing ?? "-"; + document.getElementById("coils34_n_missed_firing").textContent = coils34.n_missed_firing ?? "-"; + }; +} + +function start() { + fetch("/start"); +} + +function stop() { + fetch("/stop"); +} + +connectWS(); diff --git a/RotaxMonitor/data/style.css b/RotaxMonitor/data/style.css new file mode 100644 index 0000000..ea261fa --- /dev/null +++ b/RotaxMonitor/data/style.css @@ -0,0 +1,29 @@ +body { + font-family: Arial; + text-align: center; + margin-top: 40px; +} + +table { + margin: auto; + border-collapse: collapse; + width: 100%; + max-width: 900px; +} + +th, td { + border: 1px solid #ccc; + padding: 10px; + font-size: 16px; + text-align: left; +} + +th { + background-color: #f4f4f4; +} + +button { + margin: 10px; + padding: 10px 20px; + font-size: 16px; +} diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index 37fc778..148c955 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -1,7 +1,20 @@ #include "datasave.h" +#include static const size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB) +void ignitionBoxStatusAverage::filter(int32_t &old, const int32_t value, const uint32_t k) +{ + float alpha = 1.0f / (float)k; + old = old + (int32_t)(alpha * (float)(value - old)); +} + +void ignitionBoxStatusAverage::filter(float &old, const float value, const uint32_t k) +{ + float alpha = 1.0f / (float)k; + old = old + (float)(alpha * (float)(value - old)); +} + void ignitionBoxStatusAverage::reset() { m_last = ignitionBoxStatus(); @@ -11,40 +24,37 @@ void ignitionBoxStatusAverage::reset() void ignitionBoxStatusAverage::update(const ignitionBoxStatus &new_status) { - if (m_count == 0) + if (m_count == 0 && !m_data_valid) { m_last = new_status; } - else - { - // simple moving average calculation - m_last.timestamp = new_status.timestamp; // keep timestamp of latest status - - m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging - m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging - m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status - m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status - m_last.coils12.spark_delay += (uint32_t)(0.1f * (float)(new_status.coils12.spark_delay - m_last.coils12.spark_delay)); // incremental average calculation - m_last.coils12.peak_p_in += 1.0f / m_max_count * (new_status.coils12.peak_p_in - m_last.coils12.peak_p_in); // incremental average calculation - m_last.coils12.peak_n_in += 1.0f / m_max_count * (new_status.coils12.peak_n_in - m_last.coils12.peak_n_in); // incremental average calculation - m_last.coils12.peak_p_out += 1.0f / m_max_count * (new_status.coils12.peak_p_out - m_last.coils12.peak_p_out); // incremental average calculation - m_last.coils12.peak_n_out += 1.0f / m_max_count * (new_status.coils12.peak_n_out - m_last.coils12.peak_n_out); // incremental average calculation - - m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging - m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging - m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status - m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status - m_last.coils34.spark_delay += (uint32_t)(0.1f * (float)(new_status.coils34.spark_delay - m_last.coils34.spark_delay)); // incremental average calculation - m_last.coils34.peak_p_in += 1.0f / m_max_count * (new_status.coils34.peak_p_in - m_last.coils34.peak_p_in); // incremental average calculation - m_last.coils34.peak_n_in += 1.0f / m_max_count * (new_status.coils34.peak_n_in - m_last.coils34.peak_n_in); // incremental average calculation - m_last.coils34.peak_p_out += 1.0f / m_max_count * (new_status.coils34.peak_p_out - m_last.coils34.peak_p_out); // incremental average calculation - m_last.coils34.peak_n_out += 1.0f / m_max_count * (new_status.coils34.peak_n_out - m_last.coils34.peak_n_out); // incremental average calculation - - m_last.eng_rpm += (uint32_t)(0.1f * (float)(new_status.eng_rpm - m_last.eng_rpm)); // incremental average calculation - m_last.adc_read_time += (uint32_t)(0.1f * (float)(new_status.adc_read_time - m_last.adc_read_time)); // incremental average calculation - m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value - } m_count++; + // simple moving average calculation + m_last.timestamp = new_status.timestamp; // keep timestamp of latest status + + m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging + m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging + m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status + m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status + filter(m_last.coils12.spark_delay, new_status.coils12.spark_delay, m_max_count); // incremental average calculation + filter(m_last.coils12.peak_p_in, new_status.coils12.peak_p_in, m_max_count); // incremental average calculation + filter(m_last.coils12.peak_n_in, new_status.coils12.peak_n_in, m_max_count); // incremental average calculation + filter(m_last.coils12.peak_p_out, new_status.coils12.peak_p_out, m_max_count); // incremental average calculation + filter(m_last.coils12.peak_n_out, new_status.coils12.peak_n_out, m_max_count); // incremental average calculation + + m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging + m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging + m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status + m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status + filter(m_last.coils34.spark_delay, new_status.coils34.spark_delay, m_max_count); // incremental average calculation + filter(m_last.coils34.peak_p_in, new_status.coils34.peak_p_in, m_max_count); // incremental average calculation + filter(m_last.coils34.peak_n_in, new_status.coils34.peak_n_in, m_max_count); // incremental average calculation + filter(m_last.coils34.peak_p_out, new_status.coils34.peak_p_out, m_max_count); // incremental average calculation + filter(m_last.coils34.peak_n_out, new_status.coils34.peak_n_out, m_max_count); // incremental average calculation + filter(m_last.eng_rpm, new_status.eng_rpm, m_max_count); // incremental average calculation // incremental average calculation + filter(m_last.adc_read_time, m_last.adc_read_time, m_max_count); // incremental average calculation + m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value + if (m_count >= m_max_count) { m_count = 0; // reset count after reaching max samples to average @@ -67,6 +77,7 @@ const ArduinoJson::JsonDocument ignitionBoxStatusAverage::toJson() const if (m_data_valid) { doc["timestamp"] = m_last.timestamp; + doc["datavalid"] = m_data_valid ? "TRUE" : "FALSE"; doc["coils12"]["n_events"] = m_last.coils12.n_events; doc["coils12"]["n_missed_firing"] = m_last.coils12.n_missed_firing; @@ -77,7 +88,7 @@ const ArduinoJson::JsonDocument ignitionBoxStatusAverage::toJson() const doc["coils12"]["peak_p_out"] = m_last.coils12.peak_p_out; doc["coils12"]["peak_n_out"] = m_last.coils12.peak_n_out; doc["coils12"]["sstart_status"] = softStartStatusNames.at(m_last.coils12.sstart_status); - + doc["coils34"]["n_events"] = m_last.coils34.n_events; doc["coils34"]["n_missed_firing"] = m_last.coils34.n_missed_firing; doc["coils34"]["spark_delay"] = m_last.coils34.spark_delay; @@ -113,8 +124,9 @@ void saveHistoryTask(void *pvParameters) void save_history(const PSRAMVector &history, const std::filesystem::path &file_name) { // Initialize SPIFFS - if (!SAVE_HISTORY_TO_SPIFFS) return; - //auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted + if (!SAVE_HISTORY_TO_SPIFFS) + return; + // auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free) // check if at least 1MB is free for saving history { diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index 21851b6..9297f4c 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -53,12 +53,19 @@ private: public: ignitionBoxStatusAverage() = default; - ignitionBoxStatusAverage(const uint32_t max_count) : m_max_count(max_count) {} + ignitionBoxStatusAverage(const uint32_t max_count) : m_max_count(max_count) { + m_data_valid = false; + m_count = 0; + } void reset(); void update(const ignitionBoxStatus &new_status); const bool get(ignitionBoxStatus &status) const; const ArduinoJson::JsonDocument toJson() const; + +private: + void filter(int32_t &old, const int32_t value, const uint32_t k); + void filter(float &old, const float value, const uint32_t k); }; // Task and function declarations diff --git a/RotaxMonitor/src/datastruct.h b/RotaxMonitor/src/datastruct.h index 3903976..9936313 100644 --- a/RotaxMonitor/src/datastruct.h +++ b/RotaxMonitor/src/datastruct.h @@ -61,7 +61,7 @@ struct coilsStatus { int64_t trig_time = 0; int64_t spark_time = 0; - uint32_t spark_delay = 0; // in microseconds + int32_t spark_delay = 0; // in microseconds sparkStatus spark_status = sparkStatus::SPARK_POS_OK; softStartStatus sstart_status = softStartStatus::NORMAL; float peak_p_in = 0.0; @@ -83,8 +83,8 @@ struct ignitionBoxStatus // voltage from generator float volts_gen = 0.0; // enine rpm - uint32_t eng_rpm = 0; + int32_t eng_rpm = 0; // debug values uint32_t n_queue_errors = 0; - uint32_t adc_read_time = 0; + int32_t adc_read_time = 0; }; diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index c793436..8185102 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -258,7 +258,7 @@ void loop() ignA_avg.update(ign_info); // update moving average with latest ignition status Serial.print("Data Received: " + String(counter) + "/" + String(hist.size()) + '\r'); - if (ws.count() > 0 && counter % max_queue == 0) + if (ws.count() > 0 && counter % 10 == 0) // send data every 10 samples { Serial.println(); LOG_INFO("Sending average ignition status to websocket clients..."); diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index afc3b82..86b9681 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -157,7 +157,7 @@ void rtIgnitionTask(void *pvParameters) auto current_time = esp_timer_get_time(); auto cycle_time = current_time - last_cycle_time; last_cycle_time = current_time; - ign_box_sts.eng_rpm = (uint32_t)(60.0f / (cycle_time / 1000000.0f)); + ign_box_sts.eng_rpm = (int32_t)(60.0f / (cycle_time / 1000000.0f)); } case TRIG_FLAG_12N: coils = &ign_box_sts.coils12; @@ -177,7 +177,7 @@ void rtIgnitionTask(void *pvParameters) // Timeout not occourred, expected POSITIVE edge spark OCCOURRED if (spark_flag != SPARK_FLAG_TIMEOUT) { - coils->spark_delay = (uint32_t)(coils->spark_time - coils->trig_time); + coils->spark_delay = (int32_t)(coils->spark_time - coils->trig_time); coils->sstart_status = softStartStatus::NORMAL; // because spark on positive edge coils->spark_status = sparkStatus::SPARK_POS_OK; // do not wait for spark on negative edge } @@ -197,7 +197,7 @@ void rtIgnitionTask(void *pvParameters) // Timeout not occourred, expected NEGATIVE edge spark OCCOURRED if (spark_flag != SPARK_FLAG_TIMEOUT && expected_negative) { - coils->spark_delay = (uint32_t)(coils->spark_time - coils->trig_time); + coils->spark_delay = (int32_t)(coils->spark_time - coils->trig_time); coils->sstart_status = softStartStatus::SOFT_START; coils->spark_status = sparkStatus::SPARK_NEG_OK; } @@ -248,7 +248,7 @@ void rtIgnitionTask(void *pvParameters) ign_box_sts.coils12.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_12N_OUT); ign_box_sts.coils34.peak_p_out = adcReadChannel(adc, ADC_CH_PEAK_34P_OUT); ign_box_sts.coils34.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_34N_OUT); - ign_box_sts.adc_read_time = (uint32_t)(esp_timer_get_time() - start_adc_read); + ign_box_sts.adc_read_time = (int32_t)(esp_timer_get_time() - start_adc_read); } else // simulate adc read timig vTaskDelay(pdMS_TO_TICKS(1)); diff --git a/RotaxMonitor/src/ui.cpp b/RotaxMonitor/src/ui.cpp index 331a339..80e31e5 100644 --- a/RotaxMonitor/src/ui.cpp +++ b/RotaxMonitor/src/ui.cpp @@ -14,6 +14,11 @@ void setCursor(const uint8_t x, const uint8_t y) } void printField(const char name[], const uint32_t val) +{ + Serial.printf("%15s: %06u\n", name, val); +} + +void printField(const char name[], const int32_t val) { Serial.printf("%15s: %06d\n", name, val); } diff --git a/RotaxMonitor/src/ui.h b/RotaxMonitor/src/ui.h index 2d439ec..8fdf35b 100644 --- a/RotaxMonitor/src/ui.h +++ b/RotaxMonitor/src/ui.h @@ -7,6 +7,7 @@ void clearScreen(); void setCursor(const uint8_t x, const uint8_t y); void printField(const char name[], const uint32_t val); +void printField(const char name[], const int32_t val); void printField(const char name[], const int64_t val); void printField(const char name[], const float val); void printField(const char name[], const char *val); @@ -60,6 +61,7 @@ static const std::string htmlTest = R"rawliteral(

Timestamp: -

+

Data Valid: -

Generator voltage: -

Engine RPM: -

ADC read time: -

@@ -153,6 +155,7 @@ static const std::string htmlTest = R"rawliteral( return; } + document.getElementById("datavalid").textContent = data.datavalid ?? "-"; document.getElementById("timestamp").textContent = data.timestamp ?? "-"; document.getElementById("volts_gen").textContent = data.volts_gen ?? "-"; document.getElementById("eng_rpm").textContent = data.eng_rpm ?? "-"; From 97bce90ba63a558f892fd63a0941def6f7b459cb Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Wed, 8 Apr 2026 17:10:30 +0200 Subject: [PATCH 12/38] changed partition to littlefs, not working yet --- .../partitions/no_ota_10mb_littlefs.csv | 6 ++++++ RotaxMonitor/platformio.ini | 6 +++--- RotaxMonitor/src/datasave.cpp | 18 +++++++++--------- RotaxMonitor/src/datasave.h | 16 ++++++++-------- RotaxMonitor/src/main.cpp | 7 ++++--- 5 files changed, 30 insertions(+), 23 deletions(-) create mode 100644 RotaxMonitor/partitions/no_ota_10mb_littlefs.csv diff --git a/RotaxMonitor/partitions/no_ota_10mb_littlefs.csv b/RotaxMonitor/partitions/no_ota_10mb_littlefs.csv new file mode 100644 index 0000000..b449d64 --- /dev/null +++ b/RotaxMonitor/partitions/no_ota_10mb_littlefs.csv @@ -0,0 +1,6 @@ +# ESP32 Partition Table +# Name, Type, SubType, Offset, Size +nvs, data, nvs, 0x9000, 0x4000 +phy_init, data, phy, 0xd000, 0x1000 +factory, app, factory, 0x10000, 0x300000 +littlefs, data, littlefs, 0x310000, 0xCF0000 diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 9e5b1bf..e84e71b 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -10,8 +10,8 @@ [env:esp32-s3-devkitc1-n16r8] board = esp32-s3-devkitc1-n16r8 -board_build.partitions = partitions/no_ota_10mb_spiffs.csv -board_build.filesystem = spiffs +board_build.partitions = partitions/no_ota_10mb_littlefs.csv +board_build.filesystem = littlefs platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip framework = arduino lib_deps = @@ -21,7 +21,7 @@ lib_deps = me-no-dev/AsyncTCP@^3.3.2 me-no-dev/ESPAsyncWebServer@^3.6.0 upload_protocol = esptool -upload_port = COM8 +upload_port = COM4 upload_speed = 921600 monitor_port = COM4 monitor_speed = 921600 diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index 148c955..1f5111f 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -126,30 +126,30 @@ void save_history(const PSRAMVector &history, const std::file // Initialize SPIFFS if (!SAVE_HISTORY_TO_SPIFFS) return; - // auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted + // auto spiffs_guard = LITTLEFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted - if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free) // check if at least 1MB is free for saving history + if (LittleFS.totalBytes() - LittleFS.usedBytes() < min_free) // check if at least 1MB is free for saving history { LOG_ERROR("Not enough space in SPIFFS to save history"); return; } std::filesystem::path file_path = file_name; - if (file_name.root_path() != "/spiffs") - file_path = std::filesystem::path("/spiffs") / file_name; + if (file_name.root_path() != "/littlefs") + file_path = std::filesystem::path("/littlefs") / file_name; auto save_flags = std::ios::out; - if (first_save && SPIFFS.exists(file_path.c_str())) + if (first_save && LittleFS.exists(file_path.c_str())) { first_save = false; save_flags |= std::ios::trunc; // overwrite existing file - SPIFFS.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS - LOG_INFO("Saving history to SPIFFS, new file:", file_path.c_str()); + LittleFS.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS + LOG_INFO("Saving history to LittleFS, new file:", file_path.c_str()); } else { save_flags |= std::ios::app; // append to new file - LOG_INFO("Saving history to SPIFFS, appending to existing file:", file_path.c_str()); + LOG_INFO("Saving history to LittleFS, appending to existing file:", file_path.c_str()); } std::ofstream ofs(file_path, save_flags); @@ -197,5 +197,5 @@ void save_history(const PSRAMVector &history, const std::file } ofs.close(); - LOG_INFO("Ignition A history saved to SPIFFS, records written: ", history.size()); + LOG_INFO("Ignition A history saved to LittleFS, records written: ", history.size()); } diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index 9297f4c..6e8373e 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -4,7 +4,7 @@ // System Includes #include #include -#include +#include #include #include #include @@ -24,22 +24,22 @@ struct dataSaveParams const std::filesystem::path file_path; }; -class SPIFFSGuard +class LITTLEFSGuard { public: - SPIFFSGuard() + LITTLEFSGuard() { - if (!SPIFFS.begin(true)) + if (!LittleFS.begin(true)) { - LOG_ERROR("Failed to mount SPIFFS"); + LOG_ERROR("Failed to mount LittleFS"); } LOG_INFO("SPIFFS mounted successfully"); } - ~SPIFFSGuard() + ~LITTLEFSGuard() { - SPIFFS.end(); - LOG_INFO("SPIFFS unmounted successfully"); + LittleFS.end(); + LOG_INFO("LittleFS unmounted successfully"); } }; diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 8185102..c7da43b 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -94,6 +94,7 @@ void loop() // global variables bool running = true; const uint32_t max_queue = 128; + const uint32_t filter_k = 10; PSRAMVector ignA_history_0(max_history); PSRAMVector ignA_history_1(max_history); auto *active_history = &ignA_history_0; @@ -221,15 +222,15 @@ void loop() int64_t last = esp_timer_get_time(); uint32_t missed_firings12 = 0; uint32_t missed_firings34 = 0; - ignitionBoxStatusAverage ignA_avg(max_queue); // moving average calculator for ignition box A with a window of 100 samples + ignitionBoxStatusAverage ignA_avg(filter_k); // moving average calculator for ignition box A with a window of 100 samples AsyncWebServer server(80); AsyncWebSocket ws("/ws"); ws.onEvent(onWsEvent); server.addHandler(&ws); - auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted - server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.html"); + auto spiffs_guard = LITTLEFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted + server.serveStatic("/", LittleFS, "/").setDefaultFile("index.html"); server.begin(); server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) From de9ffe40e5f7e60c1716e1ac42458b1e5b544fdf Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Thu, 9 Apr 2026 10:23:57 +0200 Subject: [PATCH 13/38] refactor variables and LittleFS mount --- ...184d17a9e57c43ec413389783c890f71_optim.pdf | Bin 0 -> 922436 bytes RotaxMonitor/src/datasave.cpp | 2 +- RotaxMonitor/src/datasave.h | 2 +- RotaxMonitor/src/main.cpp | 26 ++++++++---------- 4 files changed, 13 insertions(+), 17 deletions(-) create mode 100644 Datasheet/be729405d0b0e6411fd7e01e69acec34184d17a9e57c43ec413389783c890f71_optim.pdf diff --git a/Datasheet/be729405d0b0e6411fd7e01e69acec34184d17a9e57c43ec413389783c890f71_optim.pdf b/Datasheet/be729405d0b0e6411fd7e01e69acec34184d17a9e57c43ec413389783c890f71_optim.pdf new file mode 100644 index 0000000000000000000000000000000000000000..593de36ef206747b4ce6c9d12e86134e9934a390 GIT binary patch literal 922436 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%0DmDY>V;#cm4lD*MG&2 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%0D3eUa)w%PUk3*_UT+~a?zKfJVe4ImI#YjulM zY?N^l8e@4Sc_pox`P;Mp2W$P$N>>(V-!#^r`Yu_K52vi&z53e(G#aE|Pw|xxH(EDZ z5%~45UmArzT2yZ7&- z70Dw-SqtL>BOzbMN!j0r%ULKWb%n5Y$De+-;iUU+BnX@`eOtw*1Y_Uu+f;Sw8@xaE zf@w~yp?#{Q^HhLVR@4wYDzoAM3}tZuCWfGw!Q-h;BvBU==njHG-2S!d6?%JOp&7I1 zx$YPGZ*xYQ{TIB5K|ln)RasDS@qhe129%9nsyM)fE4Kzg3`NtBI_;iKxx?A3x7xkN zAtfRs2~n3q5om8NfI(RMKb7cjfMNx~ zqh!XOC=-9$MrWE>J}MyhTF_Ry5z0C#lEZk?sS|hpdyJ<4Gm!Z&dV�-bw>Mrxu1? z$-aUC|JWDoe@}P@y6N|F{IMkee8k}--vB-f&3{ezPrbu%2R0{91wG2YHcQ$+^bFN} zc?XRjBn*fq46PKCFYf#J22eSAGzXP|dVUCD{nPbZ{TZkJ6@CREP#6B^sa&=jpl8YE z>olKnX9L8)zWyi^boA4D15{Ml2`%fu>7l5{zmm` zO5hX!?FuVuzq_8R8R)-tsj{H)U*iDC{!5$y{g*zK|FR2)zjg@zEd4Bo<99Hv3^inP zQ_Z*UEZ|f3*Pr)Q>@X9Q;>bAbv`%HuzBIOn=))a&TKK@+N?&S7tN%<7_s=j>{!jS& zx5lB3FlEsLxY>0UaBynzKldOYn_j%K>E-dLw|ojaOagB!4pj#R1`54b*7L6-x~jXy zWDs^c!^hkFQrVEGCD$Hxw?Vzj|o_Iq{c?e@rB=$07SXG9mNzSX}XcMJQ_DBtjLN2H-D9<8}#qlr@g? zVT-E62^7?#gA}TDvsRlnRkqf6rA=Gfd~g6yMwBgo+BL*qG3Wv)>JH=dPxwlcI8rY$ zwTWStr)~fyJ(gVJ>Nb0{>wlhssxdYdCC@t}=gnH5QUBwhNC@~W3J^ZGw8%$zc+glH z>w8BQ&1y%YhM1?5Hm-Qdbf8!mfOAmxh;>u+-z@d0yIqnriny5^RJ1EU+?ndY&v7&^ zb%=II820mgPn@xw$tmZVXRrsx8=#^8fZmMVlmG%JA6A}RnNP-O^Dq$tV9Z7JtVU!T zfQE}!-Q)4urzqB6S);gBny+);)10np58wECLAI=~5`u9>aA3P^E`WgkAwCtYlUmK> zlGrE@Pj^fzZrq4x4-OM!2}O}knwTPs;Mu4obd`j>;4}Ob>mWez&(TVz=4}{^<%t7W z|M#r0qq(gsYNQ8QB2buid{8DlAzw_Xk_W&H!xIUh?a-DFOrQ~!Uo zSIN9wqnQxrWS zrHcCX=OjSGdffMhmb6U-E81zeneUUeT@BaQIY(gbN$Z5}RMJm$Xk8+88xDXF1&biLzS8iHt)KxTLmlmec^bux2J>RPe=BqFO2x4m~b7t#;) zzp*@{;8mo+lHgIuF!)*sO;2{ePYbdBhhzmmO#~E0kwgP#N+6|>VEALHWc%)p%<)J9 zxVIlVPp4G~hv)Mm1H;Hdj@?E*?=Ap^*HMRg8l(Tw4xT_#L=YjhAaji-oUw=bxc`eF zE+8|qs^t*5z0c*&4)69#b?DUymUcXMazP1_ewHl;ccf&wGH9fNj{UrhGf9t(n4#~B z0vz`AQoig5A((9!tvE@;jWN&$pW)MKfU)T3lhuWXLB;r0ESs*_+1L26nOu3P9(qN z&|MM|ksTDFQ7)X{;H|veZxLRvIuh)F@kN23R?Ia4bKyYC1Q+1?A4K+lz1x7rddQjZ z%2}{&E(k}~ZAhI=QdGM;4ZV%g=weCT{IaIs%z8;`fcP z`S*PpgIyYm!qgX`U;y%n)Hsm?omn)*S^zbDH9|3KMosE9d85s_NxRNa? z76Ps`5(brB0P4xHyv3{#hVeXctVtUEL~ug3`_Wtu!xvc=GvlU~7i2x7T4f;&qj{qM zsQ18zFR+erLp7o(p%^h<#Jv@NVWmIt67t*Xzj2EHpnp_Yn2A~c$g41^a1pZt|4Om_ z7XHar{ev`O|D)_bq>&063)^o(>(6%otit+_DnK@3*1yO>mEV*Y>t8gP3KthK%b#!h z-5=X;IUD;Q)a36B3kNaVAI(+%*ZWvl|3QBKhk5!4R^j))KFdHayo<>M>A=LPJ~h_KBR(4rcVsh56Zs6`zH1^2LH#U!c} z3PW8C<$mhV3kxH7L+ZIE>RxkyvwAWBzg_viUfaJq`h(|tUS_+Gnhy2^bZQ<=ALF`= z?{Dv?-|mJv-lqKV)u~HX zf$ZB%_wX{oJ?I>?&K{fT*pX**x!$>X_1XFGv*GrcbsVqT^wD_Fg*E6Uwm>rnbm!Lk z%kCK*>$A08=Poe)bbUF`_RRCz#om#W*YNP`k|E36|EjL}@R4x!<|?V{YQGfL0EE=N zTPx$%ZQ#|$)YiP1b16!yCt4cxm|>l$%rIhPA(8nZB*zVmq1f&~-~@ z6b-6my@H)wZ|7aIKT}}mZFSXMeVW^$$YXhIfA1g>RD8Jkuntn$8PT5ndA`9Z>(5EW zyUlHFd9)b_D&#G;`20x)_j#beeKO;A_f|sO%Y#eTr*PE~`zc}iuHz#`(GUJK-dY+?a z0z>`iX6lIa=Hl)8`C=B69OIAo-U?5bb5bA2VdPb2`y}vu3>0I>K7@HB?!@Ny3xQk> zw%eB0ulC8(&JsV*tsR`c3~XMFU3FL&Ubl&KdUKNyMG7Zgn{zlN=*kOn(|T`xA9!Fj zyZr1e>#B)IYNELGEA;Zk`{}URJ*;aH$)KfM>@<}rGF7!b$5)7VRzD{xt-*2+ZH}T_ zZ|Pf(n0p$S&55hHsX(*5GHc{<=AKbWQ6jQP!2&gCM=Xx3=phR!xe(eS&f%NB0jT?rs&dp;1r0zWen~ zyyTt@eNZc7$`cygQE0994TplC$(RW$$SUYEO+(y$Tu0z>JXaTZ{_1!-F7u%@6XT{0HWSRal zGmc>JhOGbVQScS)e-j3+a1*_>b2{v7zIq!}3)x1_`82q8fwm|4)*Ev~+jOE+PGh9c ze8f|5D1qB!%BOjrZ`ImvAY%eTNlI&(K?{`IEN`T%KDv01Q*zkR$J1VRdDT0*L%u~@?TwQ#tK6*`nL6 z$T6&;W?oM-me;RzZTAcJ3u(~fBXJ!y4-ysjW9D1;3Zvn4j-`h@Nvd@&V~aD0W&%0O zBO^FsGMVeZd;RCywyfhHElE*z`?{x9HL}-U{)JcPO&_b+?{hIT4P=PneV1gNr&|}i zSjuV^JMknGr+awqqd9|$a(_GnBO0r;wRDmBZ`IEZp1!yGdhoFI%r<-1>Pwq)9cS@N zPEBgZb<{?&$Rjj8e>fzgJ8cQ=wsNZ(-T|itYiU~^tecq*&*7N{l$*{m-yz1}R!=c6 zxdNe<92+YcXnL8B7+sv!1V%m5)fkgRjDT5>-gAhFq1rmdNj=(0u7YU-sn}jJ6pVej0&1X@N8#fdKM_g`+25tw9WjVp=)1 zdhzVDg_sA@-s)fujdS}i`Apy9LftrE!YMARx|_@{etp!VN*#gp@X>8H`Kca5Djpu_ zhFnAs-@AjVk@wR`NnS`>=G5qBR@L;qjpa^LHCsRLfwSgUvP<@JdtJ)Og^qy|p6HIK z*3E^Fb@$za^5f1>cCv|%+R`=MytdQL$FdtPmO?;dS8&6;YT<56rkBDpt?Pv^(dY+) zvqE?Bfz#bS#@qXD5*VQ?{f?YVG~bS%wp^bzwo{kqNQF7Fq={qs8+V4S)e^j=OD|b- ztoeIY1N4&O3&)D`sN7+WCBRdIB=Pq1%yUWG(mlh|Qj^!BjH;2&y^FGOd+YbKgZbu# zMp?!ZOui@JMc-E9z^XkjFsrp@7>BehfiR*;?`Mmu!nE6cSYkpy|==VJIEIb zh>k0j_g&D7-B&7UXi@W5)_23hSOLCcN8a6@#`_6@XYr2#7Wo8+Yiavuj(2Z9Ub489 z7lAt+V?5OQ0>`>*;f}nxC{vTI`x}~dI2c4_#vS~U@ES$u;ab(ho-bP~1pBkQRV}RZ zK28pXSC@!u7Gt%G+`x=W!tuj4h6e*@Zl?zOC>G=e=HefIF+8UC=QWEb&RzP`?qXl- zrXH!bxjRyPIYEXqd#k7GQMJ{U#mT_dIvTh9-f$gs_=Ab>?RU@YGR~o;FexP-4W;`$t}DM3(`qMmuekj9G49@ZnqjN7^LO8Cp$@m!z6AL^$uS@3^u)bop!hh zXlqSBhfq6oxv~ppW@L}7&)JoX zDcB=hGZ;x`Ee9lLI4@?bVR@#LOyRKZB>F)4UI?Q@n+QZP8*+Hpt5DyB9smVR=0lhD$mJa&IG(o_gw-(vamY zsl_L)(i+w!_Jw2M&8Xf|-d7eZZ{Jg*I0i-F-vq+8`Y#;f%l+My%v zU&md=6<0{8aU4K72`sVX_7r`UiH+D|D!Lo_^{r-Vd)1jZGo7}W!sd#3M; zNAp`12>dxucrYdVi$Pi3UjlomKVhqlfhK`W+%E(Cv-*JqGb48h9Z{GLMnuU>9Px@}QODhfa|NjtAMh&3Fn^4v}8=gRX)`lgv#mp&cL%C_8{ zFmk)--Y(nZJp9mo_V&`1&O{$(1j)Pud#!m^*%&|Kn)f`}buCg5^NZ{idix$-6*jJR zYp;8He068DxN?w_vPKI&|dDkG6`j9bFCdb0&vXqotc%XuzhZYtH+}c$BW-p>N|9T zIKQpx+Y18a`FDqrc9e8JkIPD44S}7AaDt1@HWSF#M5py1EHondj$rvyru!Z#DXdJJ zth=wfX`7fbHSoqZRvr_2$hO){bxo#&q|%C0S-w%6-5>b7`_>=r+a zhdfxhZmfDDk%v-!ywEIk2MKeu7(5BrFYZ$^>iKs*XeW77qn#u=^RZ?605%Ayk4$^lLG9$H`#sHltFU)9q5(I|=)fHsW3Snx!kk z-F3%Vn+#cyQWD$uRPEOo&b1a{HzGZyyd@zAWLKW~b=H#p#PJGHV~)XQ+^<~`-?C&c zC07!=hg_U1QM7y1mW9-d5(AKn&s1@hd_IHI^USF8Owmvfo92yZlE3tIct47QFnEbmPlIs-~Eu}XXe|i`fUKHQB-)dHy!rd@;qRG1e5K`O8 ze7yQq)9Dzmuk<$wD=D!;2URrzZvy&lx3z83EBN^%)m;+Rp|$g*u0)qC{X?ZZaSN6V zhN215?TYZrb0@~j?y$Y^QzMvvdK>jf8WfT7>VD0 zS~rTKtn#zkGxJA%qB+~|WvL)#GjCJpmu5%oQE~HnmdrR25iNtvsF*^0o}0B34V_ z;A~7`;E^x$=4TyCdRdou8%LyzT)>J_s?^OruvOyG9%Wt zQY)1qmdMUU@P^!%C@>Bfp%_QKJ7r%K>I`--pW!latW7J z3B^4vH7#VL6;f*ry}a;R9e-=Tz~pi!8C#`+*qixR!!?FR?UKW*fI&~4ppCeN|1(Q; zUX913OX1ZMi#v6m__ss>0hw6)7r?OT7V4@h;ZiE@w;F^;6QNFX-NcNfm-W-8;xcdu zOpD6meX8E4!IL^1 zd2j=e17ig5zN@B7;;>Y_-69xsr~bI%14dQZym`yr9E7i z+LkB5Yo1@!ybc5>rti2!PgqNpr&OECXEbLjPNmdjnc1sFgd(0Hn|bG%i5=Do53AlO zH(vZ|tIaR^(Y=|r|6*rtHNR*t#HAvb%Dw+6t;#gY4wk4|GnL(PV~ld8hncn+T<@!P zU%z+rWb(=+gSndOp){V6{b-L`<682XENc2~C#fHJfzc-q+w(BFpKl@l7!dJtpWJUW z6Ct&{kEhLhe8X?8i0qcA=WsUoEliuPgi2e^SzMP=)s|YJx-Gp*&dgoxq9pXUr_6%P zOhYkA$_)CyhW^X3=rK=2IHj_QNnJ zjwq5>JC`Q)vYlZW;+mphP6JbfNM@6h9=FA%H7diV9|$?m95l?mIC9~_1)v|bA=;rX|zP?5wc4s z_g?Ax{(H2&9IRTI;|(SJTi@Vr>U8ZmW@0^m3{lErM1oe6LA*tmdh2RlXNWdI5iRdh z{Z6qxx})kisPIZA;IqckI^J4tuL9)906Bw3ydaum-ZCUehKpozSp)VIX^yruE9ZWR zvEU~B=U4qg8@ml?g5)(dwAXz&j*_XP4(L+%!}<875ZJ@yZNqt4vZeMV1UYRh4$~}Y z1BsTV=?xQ&?MbPISW3rLnzF6Z+N~GT$&^Pfv_c!FBd>1ie8 z{pCY9Kl5oAoOE-zN^rMHRA<-(rw@#rzZ-X3c@rv+RN2Q3mdh%}nClj?Oimm6l@se= zOO4G}1oUDOmtljo7C^}^*muT*cvSP6Eit7@i>D&xx#F8_MG=quP~%kDt4`H#(Rr2p z3kSh{qMYl_R`%-w!8ZI6MauXiFnStfdH~pJCFWDLfz}xLj96iv6_3uJ+(_vyO1Gh$eNa55@i6>l54R-(<4p|b@Yh+%?APqp8CP*if;5XDZ*r@Ag0_S1a9ISmTQ63(@AH-TZ(ad zPqn%y>nR7688D%q0oKtHty6wd&(_1E2)1l>t_`*+x-{Hw+paNj%8icb!k`kb-E+qg$zVOxL-{@zPDGU2<+4BCli@TjL_Mdr8|s~eNvDR&7tWpyu1d!z zuSsQUFs7NMpUG&MttPGDH@`C@-^P`iA3Dcr1t!@h+Je|1C{H2>Be8*Pa&s`8g>YQ* z(5k!c7hn3c5ez2@^i~@wtnxYrSWPA&@>%fi7dZ+k4iDAo$Xq>B9uyoNL7BEXi7{TQ zH!uv-UOZOTCe~z-O*B~>5hb@W>m{b9XX}g?dfWvqnA#q}UtQmf84nQFhDvp7(w%Lw zwF~5QwKxhIJ$2hXfavrxl?6UL+LBRv5wagE`UVuvw1oIb>W8?|q3K+Q5n0&Be*np08OCH?CmAHVYyQcw5L)nylAd)K>ZOxyPq?vpY0 z813v{+x@yfxjDmF5+ucSkEpMBxqDR<;WIX^#K(?j@X*$OTx{j=Lseb$n%T1`o4-biync9X#2jbOIaSM`aZA6-j%&WhAM%Csx?fKzKS{azoEG!kLnhNS~&$v|e8jY0kc%dDT*U2>* zzHI3d7N$$i+1g`kkXWsEnB+~-q8HhW$mCNwWyKtzwXM|7tF~CfpxN>2B6ytZSFLz@ zN7g@V#fGlpJK7X>=nfb~X|3RZBluRUBB+v0rlc>lzxMBHm-wyrE%Lm-rWSS09c1FJ z9-%j|QOT(&&#_mp7Opw3dY|@8;p-}p@0j!rJ{~_qb_nxoy|C=^%S0owi(X~pK>mH! zXn1tJwcW*>!+f@Cg;-TF6O_?zi*sz`8f@!{UztyO0T4bGveo~Uq;Q@4YwDAf<%Y&< zmx)rY>i2W!Cbl;4*3QjKu&*x9ulDgglQZ~A)&h;AsSQ3J&Kn7|pOz*SJf25s_lYH) zjvP&xG}om+Gfd7+)Wp?W3a__J(DkG z*-U^Lu9gZb`nauZ> zjo#hLjRIpDzkKtG)sZgeS4%V%BI-BEV~MlBPuwGQE1IL;j@+_S^0leobYBx!wMFtE zOFl>jMuOzIy)Nu8veX|GJ_U`llR1aJH*!npm2)OZhqv=@8mf;4Sy&)4rI!z4n(s^!eKWs^WVA#!A0+4GaweQmizaZ*Dh*M`~uD zw`e8x#XLGT8}MQ$b~VKf)Ud9*tR8m$C-2l>>MO}N6K_|>N_ZxJgF6q`|8wNIo5-Z89GTFTiqjn09!7pKHrL0C{Us{F9i7UpI&hwh}%k>MAsxlozkoapM5IK-be6_)g+WXe5=>l?cM`Nf1Idt#8f+Idf^whDF9p}Hl4j`)!@L}Nz{l}fwAHAhzGWezm)F>)F6zl~ll zwV!|^;?nmvsMuNcVO<*FRD1hqC{3t*#RXCd7e3JPOS8LJ<c|%OtUG z=FB~VpG*yMP&#wg#|dHPG?SL3pw#CEdD~#i%zC*GP`N2e_P29-P$xb#J1RNykh|9g z%CHj^>j<1pNAEQB&sulE=S#>a_#fr!V8}aj2L~4_D&}y!GCrzu8*tMJ2mmYjw7E>- zo91CDQ?oIf6UT>XN;LHZoRC;4T1l=}i*OxZN4 z7hHIvf01{nAG}@51zUl2G;5rx&+s0u6SK37?#H_iwPWtniLVdUuw z@69pY8m38?jYJFYCXI;NwLB_c9@2w{4QF$!TWl^z4`8kH_(`tteJ7mGP0zy|^4*2&oACz=JC794FdBuK6S(Ko^9dfJd7rwi*Ay;ot5m#<-2=@{XBltRbE+S zh4=Cg&pV#DTgD>R_`FO*zlvIDFDypgJCXc0ytHD5tSxyG;taFaG8%YA`obEP&DS`} zTf~CxxlA@ zYDea5J34RLiCU^Vmx=aebSNcGgpzhAH97sp=MrenUPy?V6tC!RvkK)9)grop3i}Di z;tPEI!gbQc1%_WTrdwPY?hp?d8o*(G#S7XR%67EG?C1fhxzSab?QM;j##tu`+v?sQ z?lDX>MQ~~r)3{>GwxUt=kQM!Mv_syn-SI-xNroPxK7gci{^QVt63BybR=QmGvkDa@% zQ$My4g)u09X+(FbEQaN0f{m0IqbIgkQAkBp?+4G?bllC@^1BND*vsXY93{%mBpKbO zXpIE%mIja&@WSTCF7E1QIQNp>-|YZSK3v~-6ifa>_FQ6#o(V?Ii3sb@7DerKsPLRV z-{Ae(k-4v`h8t_jZMqXeHWS8|`14ETZ9%VIJmnG8l52>C&pSRgpEM2p23LFDJWH4_ zYR2w3t3RR;h26EievHjHEEjkIAomy}umr|x9mS$Vhhj(EgnPMhk_<7E7Ns6*N^=%< zFPZA9yKhlB93AkOk1B^mz61o|mqw-m5BVsN-0*^7WY0$GZj1)X zv_NyQ)e&McHa?~E%2DE4Q`ySVST0XRmp@)%_ibplHi_`B?06zVdUocU_w1B@UUlOx z0(h0$=H3EdTo+x*h^J?PTP}$sxeDd-??kk8uH*fF^~0~ z-qbobUa5pEp&>TQ3a&bf^b~a|#~mx>!xonALszTUItO13!y|MDqjzBQpJ=O$N&i%l zJxjra>4PENAvQYEu9ZZ96C4Z^9kKoaY1%{N$e%FV{)%R=$qw7>-r|3EMkYD0fM^|E z`h--4+Vc9*^(`4QJgy?RmAL3WGA@4BD@CxBtiu#LgVZs-+M4Np+6xqaAVtIu9Q zIR%OcRkopk-z0mUNGuDizqw+Ke7dF(6~+-lQrQoTe0W5p={`zB*X&(%enYqxB-E_& zXBT3goA#Q|~5WiFFFDy&HiQLSFvKsIZy|`Qdj*|GGUoyCM7)i1Q zS!3?3u2|x0QF4_zz@7+2wkmqk{N2?OS$`8D>rVB>KrLS%%NHXhqyaa``j#+@f2N>0 z=;70;sQpotOX_~XifjPPufvP1+!*#?%Cc`7HBa}T(|#4YnNT!Xe>1!oddVg3Q+2wA z5SxlBqNyJnw&NSx9Ut}QVuHpUs>tva?E4Qoy$HiXjT67H66w9D^=z0JvB|=1{xCA? zBEdSh*{Y2>pba@ZZ1S62&z(>ir5#-YRYM0(z#Bj&AlRGI*XbPRvWf=rBt(^L5Ted` z^53Q*e6`N@sg&L7sjK|xg_47Oi4FE#r;#4fYx9pPYiMqys1Ru@?%B@O;$uO%g``!co#=K}ofGK%453f(8=XN0XdBO*`423L6Ls`MHO z*~b7Mnq`uJe#fy=m|nK-7zS=!*s4_p-Rcd}9<9)~Q*`?ycBtlfkV z@o-dMv^r7UP^y-wyMr6598Trxym^mxqZjHplfSoG#gttpAlLc2H?=Y(mBy)QMkpa@0U z^PbD1`A$EKEUusls0ir7-sKh)mvk*W%LWY#`4H&ybuu{0ezDnZlOfO9dunyS&f2KP zMpsz0RFCe(lF2RY+A+@95PfWf!)|3c%?(|98YB*8_xuSlwtUr4I1q*uN;+tq_G`uc zi)^I{K+{QmsLlUu*QdHc1MVKzXw(g#;NUC9EuKEanuj_a?CgyeMxJFkW2Hv4gvSNu z3@*OWV4{1$>H*VtSG#ZJRdRW=UmvjYt3Fg@(qKHv8omr=nqb9IKEJb?LCmLTCxaK9 zoU&32(IdlvZoeJxalNty_Xd=d3F+UTIX+b@b=aOTY4Lq;H= zbsW$|ykU5y4`XH2=aB(+NT5$w%R`zo+r-6m3sZn3z<4pqSHrk^KO zSWL8Cj+a{44zXul3p6;|&wbhv+eJVz8*Zb6A4h_A?6i@G`^N0oG8z2=7Ct}%SuTT(dDP5aS)cI@iC8FemCS@IUsAl$E2ci&t zdeMPcj3#|R5YdJnE@hCww^lZ4cT{JV3J5+~xgV^E&f#KDANslWhxn$ui*gZSmL)7% z17k9gQpl2nGHPDD4|+J+vL!g1ka=veo!H9b6DN}Mvek2+cdq)fiS)~w6D%Ezs%(^P z2<~EHnZ)dhq*RJKAr`J~c!Pj-K|!@Em|YlA7Bn!C3cc*#K3}8y97XU9UN2})P^g#} ze{btKWZuGeQsAk>$tROIv^1kjH-O=XWu{N~+S7mP&hvtwPd6BpPq^S59&CbB+Vr+E zc7Yp;*-Djg{e5sTpM1)}kO;c1phyJ4{qPirIc--h$hxCGS(^)=>a+S}%_EZgY-SL^!0FBL7S@g-4U4EiFo#tJPIs`T&G;R7z;%l%m60rGj}a{BFV66@?b&6N{%^sL{Pm$YPdMEjvmvTmt z?iam?+7iGHfiamqB*r^Fe{C(uXo2PB{~_+3gERTMw$b~JZF^#8V%xTDOl;el*v`bZ zZA@(2&V&=3{NCq#ajKp=b-wSPZ&&y3)tl?u-MeZv_PT6>;I-2XAh|#$Ua|tK;jr)D zvk)`v`aALRkh)&i3MC9#2sWLiFLvI>fSmll&R)xODyBB`dYXQ1=h2&}@>LzyF}5Oq|CeW>xb6^5G62K`;B0-dI+GyL5vqlQz? zy3;{bZ1Wpfk|f6x854;SP?9kUtfp~PpnF#6!$VKPRfhm~PGVjOY&!etiz0A5c_tZa zI?uY6qyAj^-Oo6XYmQ)8?jMnZEB+F`1J+RDPHh9*0v@lB;)U8N0IbgLn zJYQn=LO_zEbh4gca<~v38mo0BFb?+|yyRK3!kN#TVs_dyGXIg{4?M+V z6TDrIDG{yOao35IVYu#~2`e#|(1_^Ta_=g}`xup}v<-1~>h6!?9tF!fDgSG`@9scy zO6MM;&2$#vw}GP>M0Q_Rl~@#Xu*`HH@c@eto$k)&gz?$avPS5#CO{QC=Amj>fv*Y3 zUqBqyBB@SC`;U|`XFo^+RaglBB4()+r%@3fI>enE9lPDqc2ujyKvIDt2+}f?uf>ee za4L^v5XRvBl7~$hO|?V;tRTw_=agEhV@pr8;NaExWrw}aPrM4&QV&-uok&Jl5H`h`<=STUCo@|8}k9zpFZ&KLi@C0!qs?l(q%LHXcEf7q1-`47LQiuMPNyxx}Df z=_+Nn%&squj*7jheZul*>d8#A-L3436o^95>BM!VXij&NV7zXs#mkYL#qjeb9 zssbfMWer~yz+|MXc&vp<^1I{E7tM5m_!c33D}o>Ah+LR@me~)260D+d+)s9u9?+Rh z!EO|Kx`m%i2A;ZT=QWjtwjqksO#nO7IQqB(y7S*si(o=1$qwTiiBzbNw-4Qsuv=Co z&MRa(%IQf4UWZtqlUaJ@W`?imX`di^*SoMLUub%CPd0rP~;A^JIj^`bv>vRX;V_0 z4@L&ZwkcE|0~w_~Fr2Fo?-@QQNe5D^9UKQQ2z))FvT0YYryXSc%du`F@n} z`AQENOG7|ZcWBsQR*r8^t$DHHpC(CkZeu%y;T1S$NR>g}Yv3-SZ74zVBsN&lb+48; z96i4#jDX33TafVH66h6@@?#*crqzk^CKi9jp$zOp;(JafyL2rVb&l(_TPpviSb~n}e zlz4hU73{-i#YHS>A;UQAowEv+z}EmASJaX(%KQG>Ma}``Wfv$e$}D=$s(~?y(m9Jn z#jbYfELE(cv4};Z=1h}%=IohJFPm)FPm?_NgF#ng9<=6HL(_@d>t~>=-m%xjBYmw~ z)709@oHEA)@>&#;ryOlNn2ln9S2Z}^1%Vl zo+g3rO2#4k%xw%OvnZj(q4E#GADAC?0`TakdvxJXMmmsYWe*@VM#Z5PKfrrpFxy~m z>1p%WAjBTR9;7$vnn17+Tr*{-M@+3*Gk619WhXYkZR6JLlHUq5GZ^ z*((CtTpg}Q2Z<5BRsWA)kNK2zNHLxIY_X=rDOsE^7i)nKof*8nDPkJQ`_UW1u9A45 zuI7T3u2+oOOEF2kpkb;*s9w6okD8&&eHJ&+>QZ{?ko3fnTl(LiVSwd6d=Mp_S{ zh29xKjc!)2cnZbdDd7R*=Lj((Qy`r(@Qu@qmtsnk*fVcD-!Q@V zJro+DO_ndJM#bgOjeJ4P?a-#g=8-$#Rm`>h!?_II1ED{9;W=xX`y3$IKS`Y-x}}@X zx(nkIZAlY~A;I->L4rcEG!C{1)xM2@1U}RvgWYh2M=M$wUejT5XFJ8$jnB{R#nv~l ztm9cS1`RXhV_gj&F^JlS=T0-9R@OnG=Hi%kuSV|n{!B{EE|l6YR)@IyMZfqYG+|vz zl&580m3?-;Vr>Tx@q>7XXxo_|Pwae9a3l!)f6D|am%0#4%wvWe6&4^hW?>D|I}0fSQr8dqG*bK3 z$O2<<>hq>OM#D~1_ORh~7RFk^m25R8r1_`B5H!NP;>(K&L^$Rx5+~H(FuayK7|Lytgx`tkH{DQs`8i=de|^Ba^{*2oL$^lf z!g_j%x$qq;>+h@?XunnE_#pE!+1#5mW?n5e0{3@$+%fGKt8nFz?3P0+iAPk&V(x+? zK2$xk5dQeiO>wVnFrS9lF^PVw3ChYY%bISJ5cKd+H4~rQYvONCYDF_ElHdHQoV$~l z^8i1LzQ_}e~Kpu!xgAMP0(Cl4m_YGu(nHV;&I#vK!dOw}v&7!RuoJLsL|8nyh za-mkTbL($+PCFQij+{A{Ywi4~R$OvnVuUhRcIM_^TTOx#d!RE?C3fW8Twl^spV`M{ zV;VLO4))^aGeCJwLU(09@#~rbC(pqO0#2i@K(+PeITM}KeW{$cVkGw^nM5?31HLk= zUM<2CDybQDHI6s%Ykn@N@*dy2VJQCe7EiAtiuJ^YKTqASu%C;0HGfT+@`eim``&}@ zPe1en!96JN?_*$OHIMGTXNyDXX`$Y-@`Pt|t|e2i@LlCWZhf*`rBK=S$ zHhPYu`dzuNrjN%ty(tYDAI$+g+=I^FGSeo6J)KErH}N!YB&)^5>p}8UEtxC3{((?8NQZ zl=`lz`SyOErTnA2K@(|i(}%PcR{BW-H-0&$2B{T%0DpyRbSqIeOuUW{X4PIUyeFr@ zh5@o%pjKg;jN_cxY6;@V59e+$f#HeM`i#7VTco!8%%n#eTr2(xeLCUz<0w8>@EO8F zYY#AiWZV2v>D^U|y245GqE~}fc?MTdMX&AzGR2)-*ib@1KQ$5UT2#9VEh8#17Fw4u zpI98?%sPghd6Sn)S(Ozsv5Ut#lZ%;3Rk%s6<`&DvK7W6Us5;0X(;kR2%^wP8Cel`4 zcR;G;f|&7Z z?54&lZX{|E9%84@BEiC92}20GRP!Ki?!Pa5`-eOLQH<2#9 zdpsq|S7pG2!(Z$wN-W|f#B%10E?X%&RL(@JzUL`aWfPV3^{Qf-232k7OAL+%s?D$t z>8dVu*;M_Y%wC{mq|A`;1i50nQ1-MCWE3oQVp7WcBh}Ge&!0sUrZ@=oeTOm^@Dt3$ zh6>dM#u3yf;LYYxei`ponTHc$jN&j=JVI6o4f*iH{&aFLT?_Iox5(Y^R%p?VSfX9# zHm__@2lTkrK7TR6Kj^n!Q%~D788B;HxTw6*fm02ui*Vy@EDDt6Dr?Uq49;nY(2-Bm zRgjLregqXGGdUp`f>Q?z8r;qHfEPD)Gi1%@`@{Qh)eHy%@*Q@_t2oEAB9`HN)XI#ej(Xi^nQ>V-$(JgzUE%}atrTe^P7&h4g*qCPsv{>zlf(R z5~TeuF#6%wJsu*D;X!tiXqx+0x1~hp>M*bUH6z$eJb>@nG||Og`mIt62rL?tTJUtj z3T{7^=zFqh0#qJ{X@jt$exPIv=9=kSKVTD{dmHxJO{U*A+FUscZ!1kON*F0Z=Mc?b zE8kOd;KMlnAb;h>bBG9z(j0Hp)AgWK6`+E$RXy6KR*0h*Yf$NbKdb7o_wcLqLoZNR zo;XjFqz}fK$IK(Ff&_}`Mm#?9FN6$UqX9;y0zaGXQ1*mBl8U=zp*yOY z{z`1{@S>rHb>m`LU0sFIo)9+a=`j;pr5g|f^(aC;DsGOZ{5=0X_xpz@i?Qm4&2CaK zlN~K(nYwBObxowTRTXviO5Vzl4z1K8GF7-3>=fRBJYBSw@I=2J?<}Sz2Kb1HU_{E0 zAsnU&tRiOwUZ&aa`uD@y$~#z?D36qRHg#Z<@pz@=^g~_zGOZ$WL}yj)$bhH0=GKf? zz~0#Hrox#C1cEBJ+$|t4Yt>Os4LY9rn`@gzMH^X7Cszb2V;3XG#O0QrUO%F3NI;qO zm29YmQ9KQlLTjsnr>PPPnuoMTN6WYpd^{)-(>n?o(D{ z5PUA+7gGRQgM@bW1t%z7hjb0PnE|RSH-zmW!?ka}y^-O0I-;cmJdb^}_mvt0#57Je zTnjp{WG~)M%nFXmf6i}R2CnhhRdXo+2vC>9PHKA2oBXMvnCU|)QwJrG9j(o95oAoL zVGoF`^IbNot3$*%Y)3eH(?XQM@-xp@`H4SFRci3}@_mIX?tAI^bov_Vn^(n*<{>NH z#wIUz1oHuJWYOb!y3=tb%Y6pk2-$L^%Al&Mlg)Wf1zk0?BK}^)wl10b5zV@Pw@$k) zdHcL4ycta*wzKc7zl2sp;X-ggcN*n!M9E~pueVVh&&~9@Lt2X$Ydlo^8VdwZQ%uNDwnA13b$Zh^{0o5r zf;GERUkYL)7tkrMbH1~jXj8Ii;Oh=?T*f0=QHTR@)vF5+a?w2S3tz{R3J&6#||v-ml@e7&u2U&Lyd&G8PscE2l%5NDx4BcPC9>CX>$`Re|Cx)&<$V-4_dD02=G zr+$K$gb{FN(}co^S@rD67RV!Rp1n2tr|VbhWFLww0}6K23L5_nF+I?j`)4Q2zL$l->h~!dl+O_3YWH~?MEgLetQAC`&2{hZq2tGG zm;LO^+r6D2Gn>Pn?~xsdg%|3)LjFN7vdQFnX?L3Dd)jHU3n(}JTm%wb8Dvp=e+{F0 z!1r)6dj8r8v51dbo(yow^2rb+H3OH{n?f_ev3ay<^*H>+nc`gc45Fq7am_ zmY9E1m?Ha0FTTxiX;z*&FX;PbdiHI{Er&F38HM7>+xh*48v$+e1;F?b@|vf&NKXKb z=7U&^)8NxJe`z2ouk}d?9%IhfEzS?o8}3Sa7v>SD^aFIq5u{-wuT|>a{yc9K7M!@w zyNT%zchmpjwA|y2G-X5I_QrjGISqC4puLRzVjjp2wcQxk()X zS8Ov>$64J6!Eae9yMCEEGr=Iyv44;lTA2ziTiwCG=Bz(kWSYXE_+a=31(5InAo?%%w)!E-UF1X`GH&DD`h}6ZQMDua6%N&rWqD z+2AAEPV>D1Le(GzQFy4RC&Av8H>t*G8-4)QfzFX^I&^BJ8ZcgRS|{C>Cj!xHOW&{? z-?Q#fO``L?Vm#4;0CyG~=8FE7V|xp7qe~De$Dr+Aw4wG&w3-d3=Uu?-SW)&Hg|uw| z-F|5Ag`WH55NnMF5Gzx2TjiY@ zX0z7s{zEf1NEhj*qS|8Gmo=&s0*Mj%shE_PkbSJ?CnFr;y+8>b7e`6uZB=9QB5(1-lYqc6r(mQZ-IJ6RC`q3 zd!W-l1R>_CCfp=~SM{alA&d3uv@izg84pRf)NU~hMKE>!X*#gTkZ~ZP()<;J2 zVVp~nuOUd&_3=wfFp-Wq;xv2)7z)=R?GxUC>C1oD49$`>E$`feQLUjY#U7ZZLz>oe zRVy))%VFHb7 zz8nbPdnqq(?o~rDpZ1@{S3U0Kvsl$M2?Ii;IHtn6)Xd@hH6*md!hU|{;Y!M(OgbR8 zqinpH+Xa?zpp!9d1T5FZw{(w(#5(hxscn;e*qrCPG`zqsVZ)okWqtY|Y9~Q5At|(EcN)IYS+eKotK`Q6zgs0T zUV;a_y{3HeCu#d6$p<1T863jHuEZDo-b$s4(jwQb<{^u&zsu>U{XGXMB()@V9eaG@<^URngDm`TN3k-&>t4NQ?{M6Tmijy!cU!me}iF=%k ziVQ|gJtUf4fvpmDyE@15b}S`*?fcJyI1lh5dcWbN5qw4cO1~_~LI}vAgsevCPt_Tt z)JVgPm}2NiJ4zTj)c|0RedDvez271`^s@(bjf^NdTX`Ugsto*z+Ok7)5-6GmE2h+| zaasnFK_hV}PiRXyt&H%i+d}G<=SQ_NOdfx4#WlUVZzKno5w`t!3t?g)-PS~Lx_h!o z8d)#5DF(#Kq^+Xs9Bq@(XfVu@l3E0&&$Fl3%G`LW{SSfGRM+2orVWjEAlDwsN@NgN zb9Xgq4YXV@_8(@NIfk(sTXc*elD9CunZNkH>(x#`h)TEfSQDzkUU=tCO)oPCjR-U- zPdLJ{oulvKs5*lX`bAUUD)rD9J9H{iG-eX(h+D30f4%C=4X*GpeRf~kSq7yv(|`s0%f&zSU`3b}wlI_!8ntIN{9}@-euPHxdwH$I zBMY8bbbADyWliZK$B<3IkYM9Pgu zF}F$gn)?M6k+<*hFLSSgdDSWcpAiw5Hlp)*F7z;%3&b5R9tbdK8+%W>BgWS~QEJ*t zM(Ib%SxADQ2gf&|oayxq_n|-0`mS$zFyw;^sgxJUK~1EMC@V#e)G;ETrO=Rrd?93F zbA#>=UAZfnX+Xe@7nK|1uyc-Td#Ze!rqZ!$5HZ!*bCJ;<--T-1cS`AzNv@LL^<62CSh>9lneeZl1VXQ)$3?%b)BXNQdK=^+NEcJgNQt3f?EYKUR9U2IzCuK7 z)mT|lOU^c1`S=6-rpEyoEyyRhNG;j=5_%ZhsD}rhtlKs0?pl>%7g9_rq;d1stEk0A zmuOz_Q|18gm?^1wXcxix0I02lhoHsv04CeIZ6U9mw6oTv z0dfw?Iz2A|XK&3^P4dj-yh%MbW|!Kzd^Lp7cpQ9L31(pHp?mgtXeS2ZurSLal8SUFMi@f zc*I-*5UkOkQzpF;&hsriMiTR0CyW*$na*k z`D;$15i|#7HB_VNsaoQxUsDOPjaM&|AK{+85wv-UJDsIs4hg#7tc77TV-%x&bhoQx zy>o<@d`-1+1%o&VBa|CjNnwNtF)}aF0reD-Q*}UbY?OH|S_%%Vt1wZo!1hnx2MC$K zhHX5s3-$Em5OY_1L|Bn(Wht`KZM%dvACk8Z{MELcLg5a2!8+_(p)ul9rM6(0w3nHd z#amF%e!hA)R_T-~ndqy&gCAy(K89?xuMyBHX$`2u*~$Mot%XkDfh0A`2x_x_c4-ct zG784M=^hlf(A4^|hwt*btEAQ90)=O?8zk(|py(wE6VYLvMjPeNp<)Rxr|?*q>}Z{I zU&D~Z{SAZHJ*1i7lZIyDvdW0(>7{qkQ8BW7VwTUI=YesyS5*8l)|CzS==FE7FtdFA=M$`Oyt0estbAbI<-K1+}Vv zCT&Rt`5_xJaBl3Evvug3QCoK(WYr!?-?9@MrVsMa#o~I2bgxXn>7d6dItp)%^~k=X z+3YbzZTrL(+)`@LAHkwyUcP+U-;fN8R;)Kl`5D>C+M(4^7H;rky)eq};l$p1>Ccp% z37v&j^rdw2E2|WN>8GyN#8>+RVJdQm^pTIk`agrQEy_R^l-tlx$&W_T4@(|2m6zO| z3aH3(E28UqeF&S#1;^$%3d)(_`Z%5F4|q>6$BBKl4h@qeQ%C)w-Nl`Cm|F3s)d#_l z&#_b>qt@#@5Lx!R#y1G2gj$P_N+R(*$6$r*7!-u+k6>YQx)}2-sD;H{XHe;#568Hu z#1Le{6FbY6er7;hRmg!d3#i8Tlbng)8RBzByPTn6NME)1P%59Gv*D%*l|)HNAU_73 z58-R^A81bAeK}!~k?*%Dp(aH6%g>jWj6d=h$5Z^1m`0i$9% z9RRXr>O?>+mUwgT)m|QnYBt0j!_6^>O7eJuk$g-hz@PMx9m3|sE_EarSq;3pCp&z@ zwZexS(GXQTs)*nKaH>9&Ny|AO=`Mmtz@CjCLeMr9H1~0!1UPN)BBS z)?@h-k{Y~S<#GX(PIaJSflX&5(u#&4GWHx9Q@LPY2Hw14BdBx5dNl}JRLb}QfbM)3 z%vp>C1t}7?v?$Q8k0GKCjjb2JdDftZ*BMr?3Q5#PV6)Vk^=8OY@g@hOm@ZV9e7m^q zt)6X(Hy#tNnV)yJNS%1y{MUGD_U1{^z0jf79$MyohmKH1hWKVL2%TvBfW!*YUbEGg zYt&up=TAE=`G~Xgb6O`K%9M70PmCU(Jz#i$!{&mmFagn?n6TEfZ_~OJopa>(3`g(mzZ)dVxC=%(;bLblvE!Y%bCWoxT~0(X zkv~fQWC3$}7EFB6;|CN)k5x6P+we0#M|~2`l#}UZMbm)?lH=J@V`2sdC=T37TN$X; z{S}!DdOTeRv1tc?rnV($T74aJM6%g=bvd}u6X?V#^tNxmmdL`dZWnnacklY!Lw<`8 ze2{@GaKxJJsoDrM#QW7XArXXfhCYTZCMubnmJim7r%UHTkd!)hkTk=|6jg5mI~5&m3d(#Z2zmaVWfB%QQcleMD%Q0* zPEm92G*F;&XV`?-&%2h$g_a}{?FBTy?U4kd~dt^vi^Sx&=O zcE!MZ^J&*-ZW>}6jrvHl^Yyhfq!jw6WOd}4Lc5O@{Km{Rd4$gIg2y*LV7L}&%`~39)FEG9gnl8I%Dxko%GLT zZC`u@BQk32+$_$;#yn+*fg;2tI4y5B0-J+thHzJor>}r22hu3!3TDe~Z=4YAKT%mP zp^vpIp?CE>qTQ}*W6m@F2qZ5nj+LTrh-&u6GrpS=a{cJk*VpmAOVDP52qFII%o6xM4o0XecEhJN0ZyUsGyvxw9+(J;jtjG0~ZH#YFDu9P)8=>4H|>EJtD@ zCdb5_BB1N5ubkphb=TZyhuv0XwMkeL*;_WXwxd;{Jaf`*VH%FI?7VO~91rAeHi*Hi z+`kxuxWEx-B`0mQ+eRV|E09@hj}zU)ohLc^S^5ce;-)>TEYqqIQ6*fWq^%f@ywa;8 zK9S>r*8T86lG39bBV57Xl%FF4Mn){g13mRT_lUxx)>Abqh>fUe z#3^YyPFb>tUn*SKL*E1H9_E z_8>OJd(HGw>8!@6lZ5){skE8brKUTIa;^C6Te8GLz4hht9J^x6uPGQY45ZFNDIuln zl7g>=Zw@F(I+{O?9NFS{*dUOvpyh3{(!IS@L2ZUgMEbPQ_jRLg5(OY3lxBY3;114< z%^u`kldCM8Y6@1q73VsF%+@6fBrI|=x;?5CDQG%qH=ln$4eDcEp3QBNVhx=&Wsat6 z`rc0L6NFo`zgUPhIC7}*%OX7~QT5|=C9yozrSNhJiUR)Ah=$uF4vUxanfC&lSG&1; z?M00SRN15@`43xVyfROYWTtb|xPlqqGRj2T6+1b-5`=HHWV#6*qz|D)%bm)|*aV(9 zq*ss?<`nOy15}ivAFr2GB9}V&Fr$%6!Ma0M4BbJSL-}4~sXJi#!XW&oaO5GC^E;5# zNwf_j^%s8ahr@RPzuy5m{9vD@sF?JEvASXIg-{mf<6et%1TK4?lr@^iRwV+Bi|UM% zphKhf#MGSBSH9(9SEbBpB<@RfEsEvr+kN=`4N@Cdzf;d*Ln!USU()GDOu{k`gPg)6 zo1%w8{}`c>6-TGmaAG94cibHg<1Azr=tu2?PQFCAq|5U$72G4aN&dQ;w+ro zmG4?ibj%!adp~c@SJ7dgqW7ft!FdK{d!#{v2RJRbOwqploCqq&UWkzm$3LY)4AG+5 z&L>UXVlK$^^P)#9H$I(6c-a$PT>HtK6(ic-PcBJi9&(kbt~t*=A?;KRs&5l@;g5;e1YPFuhyn@EDKYD@FJC)jLyLl|nX6!3ETbsdU>GcJ zm*|+@hknP(u>|c?QD$zz)?{##^zsZe(c3_ZCpr_a18ucc6orW$cR}Q?Rk$cI@!+2M zAFsg;9;-s%uZ;#wLu=M02;n@{|t8(fqzLl^2x_>-tXU=mps2kwZFEa4C0y+FYk^+1uH{ zX5b!1phJ_u>{7uxn#{o8&yt0k?e?us)cD+fGq%(J{KMeaSkuvj9hLp`^Bg1#L;v$l z-tR4p|7!oO=Huy!zvrW&=kO=W?)kah=f}^fd1=mVo0gBFtj_m`7XHs?!q2mMx^~57{q0+#_1cROH9)>%Vf%hr!O@*-oTMwC5zBPMu%nT&u8` z>JuO@{hL;6fGsQOTxH4>6D1r0g*GZQFBpZ_vN@cmYY!?c*3Xf_A-xdw&=FRCPEPJ&>s3uS}4XFVA?8qF1{iwpZxR-i#s^Ke;(A?#VD)Dzhy>G)R&}@qV z{d$=g&5w2R9q-J_0~0Y)=Fj>|GqS3TvnNb}HLXIUb@3VG%%fSY_Ybll)yMlQ8yPgm zR7s4pUt7_&auKj&2@?Z&$i`F=5mJWYv+$qsR(eKU9`XJ6VHQEp zH(oBuC+N7jLnwnO{m2HctUrr43b>HR?<<3g}J)gs1k< zfjM6X4k30!c}~nUq8XrRPG258Q`T%qJbftdyT`&o?*clLi2Pz}Lpnzw-R~R#){Ub4H)P zJujIWFTH)GEVi?K)41xZdTexmL-dj z^@eh@hUaEef3DcW&xZ2Pl^(9IVy1JSZ*yhQ5^hfbI<^2TkQV?z zzY|4=5`g6*>LN&u3m_^Y0ssMJUq#C1-0yVE0EGZ7H_IK%9WnsG?Y|)0#Q`9{stAo@ z-NlU>et{GE%A)@KBvJuU0U-e)A^IAEuM~@~9qSGN5coQ({4e?I@IS&=2O$4C1p@CT zzodVv{Q>}Vblks$Dk|N7rp`Y+Gc0WXgHA@+&f3mV+1}9D^ow`qpNXWzpzLDg>|t-p zAZcT0Zpt8GYH4oaOvLn^jp5%=#i(1FI9m`gF|#uWSvor@m^upE+1T6Jn%X)OaWMQR zj|}twi$>;B*GB%F4UJD%OG?y5`<1*-(rt~8RzU!Kd}2_=fr70&&t@&mGV}5CbL1@n zV+3*uya=3-v1j72xBHWD1#-@h62=S&=L6*6vWy<1ufroDzTLxuyQ0 z65F)Zh-L%#EvzoGI6lWk0K0l+E!5#S&cHI$bUejk?R&F0|3$(!r;Onr=segcdKtM` ziCeVS`(I;~;=YC`@p}ij+$k@2)~O%)3H%LrNt7gWiCm!$Kf8R^ZGu;7B04Fl#3=wi zk3V-U=k_WHWFP?dw+>pBKyP^JRt+q1a}i54MTXe4yW8d=4rJK(1_<{Q|7T{LUV8hn zk=bfdlwlLh*zOQw&;i1&^m0>cOEYVBlwvw(Wl6;GkTw< zHI`wuZ2*Rd-dMBMh-?EX^PL*EbC18t5lOZ@~jzTZw@1kYNwCVjaE#%-1c6 zIwk^rf3f;%4Vf};p!p85`#eKhj&^lq4OUZgpryX`tTul*XIaof;R;5k?#Sk&@$~reP;;6hvP=q zdYZQwBS~;9r7JFPd4^=@u&{Sw;o#IMTUQC@ri}0eGF6l*!;FaA59qOhQMz{FD;*mU zqB$Xj7Bp-HZoX)}Vs=6YQaN2mvG0KEzLqKtSd`2HNwms9_}idn=+ zEryf*B96141qg;QK3E)yECa3?0U4z8A&o0d`OO1e$K@)PuAib&MbPB?$MPu z?RB}|A6ZCtMjFCs9&_{*I$MJe(KmQ&)B(%Ry;D(#w91Qr5%+ua0UrV9=I%Ou`hcgw zVsoYU{>Z~h=+%bFQ1^S7pPwKP41>Si$D)Q)z{xRe_p||?5nk^CX!RY&Y#m0}6DkiM z1FgcOL+Wlct!-UIIX(q0=kTjx9(B>IK(EJu@piqwA<#E*3MMFDQ|^lj_z4iy4nt*v ziD#6REf}}AGs()LCVE5buzK>GCSlE(6(($?DVq|N-fwJXGwWJ-O%K-CjYhv`9*2?Y z%@L(4fotDG<9Ppd!!v^IXzJ_Vw0viyzcq5&k!-7XhToHF(tjz#{hsH>a&fg(+TS4B z5_+PX5^Nm|T6gG-p_DO$m8NVBPvUA&2jq~=s+;W1h_#na3^HK!7f^OzM^6wtx?yMz zFaEU`Ycz&5ph103E!R@hONL=Fm&7q7Nds3@JY@T{%7aFQ@mW$(HY{~fkan4>npI{Q zY|dZ1n0kF~HK^5^6E*x;yhFX59=Nqcz2yro(Z)Q|A`5LSikV!EpiaA%(FK{ikx237 z^qg9jmSon!EmxiD9Nea$e(vpAicHj>np)&B>5wr?KovK$$ zv3{KGYC@MK_4EKYFui9>e2vJYs16x6h=$6~gb|E64;kJf8jA^XlH=uGymUo0`RlNy z7!R+tK1$}8RDD(qX^Y>wNOTl z8}df!8f0Ihr^*ndNw^8}cS4gpL1(+>l zJ?25a1K$|=0^%D6YkQr%O$Rt6U!;@t_ADBeKE{nSkF<#~hDRAs~+jZy4@?Pueb9hua#tS(JAEk)($qz;Zf?HC|Ki-%qu(&X$fV}2Y& zddRS9p4xiYr1T+Wv|6~FzH*&t(rUQ^yN`dT^ufnllAv-@{3aT4IY)sfTtA&-OK42j z-v`wz_^L2eE_0>mu)B(nlZ2%v(n{q=18Yn&eN-d0-tfXAW*-NxuK1W#tS#bV4R2#EcGU_NidnSEq*FQ4b zxlDr%9;YwRn{Qt>19kY_q&P8L*PGbrWgxADm)I+9@|kU<0U4e9yf2N{wu2wbq3+)D zE?C=QPWaNiq?cfE;<)~A&^N^WK5Kw@NvEV!f0~O}phntnpje4>m@etlFBXdE)rO|y zKZuGQd5BTDH|91!U7xnUQjsmBu#ArylULzrHTUhUX?u{^>9b%j2fA!&yYFgn3wb&| zmoRLCJEpmc%Np6~Wl#Nwdy-Swx*}1O?IO1LWpRgXPgpT+23Der;f>k6hi7_>y+a7bC`+1Z%snV7f)mBqMt<@lJGB#b2G)HHPUbU8%L zY)rMRm9=#>|7iq>h=hcJib0KuNv+Av#I55U3JL-S3Jwki_Lb}Nl@9uA!-AY+`C=ZeeNVU~p)7WOQtNZhm2LX?bOJZFg_~;PB}9p!@F0MLKI z`ilQ8F61vo1f8$yMz<~n4E*>Z{fFE$hP|_YLrjc~nYqQH7 zF!QsuqLi5Y0`V5|lIg&Mdcyct#-?MG z;bycV??juHg~ZcDaX-yJ(SYv=)K*MCtr+oY8 z_Rzia%LvOwZ$_k%G+r1qG2^hif%`-8ubVa?Sxm$fz`!X|4MdBYJO@qbH?0)}CoQBF z&$GOw@!yW_o73|@1-;UuV&vh`5lGSI++p%s4leMG^`U>J`HzDH5Xzr^lG-2f9NUA1 zjDaqrbA0nB3PdD|jP>wNd$KX(^#{9u1{IjIS;ac~1SpP&hRm_K;Jy{cwdx!=o%xMc zd5I@TyI6{09XB&E_l;Obt7+*@(x*4qS%auso=))x@io<;1&Y7{u^+(vxTGXARDSKY zzET#X$1QItHY4HUp`L5pZ*2#Aps=g0wsX7{I64JFzcFj8qEG5MBN8~|D#kzmRbc&b zW-jjLI7bQh8+&@nkZ9l5X@2?VZN;Me0=RZQ zxUE&i6qvDzTn)rJ&xXI%Q1~Zf>Jf z8x!uP6>xA|`s%`3B~q~83T{gJB&^Y)_@fPk9M>KD{Db1IN^3gB82;`5Ve6~I+IqHj zQ=p|#3Z;eOQna|c)8fUQ6e;d5MMI%b+@)yH;_d`(arfd-EX6``LP)sj?>pyw=RWuT zF?sgv%$U?zFo|3KvD&1)NdP(}Q=_u8laNll6?S!5;SjNih7GCKP?7@ni|= zEwO!664#FIf1VCz*S-h5lDh{~Gv5PbiRq`q zYVHEo?*TtG?*VxnM&-@jr|16n0AmGIaFhKfo_fxkC6Cyis0q}l1)e6luk*2OxJ&f$ zdXivN`D`h3_78?9wY8~NFTjvqshLbCM|xJEozGVedWIhPeag@@mSA6rPbI@n-hbps zgKN@z#0D`}z|QcBh3-@M-)2be0n$b-MkC%c-|M2BICG!JV^R)x{Q60~O}&}8kWcP4 zL<`q?jt{eZ|02eQtU4shiK-CM4s&sm z_fBLzNC)>QiIN1;XglvD`UnDC-TLi4nok$o*|X+#t@7+wM^H)vZYL~v;YkUx%(a4e zhn<%^RZcau?gJPeZZIvLB+KpU!>RHh&UeROx54e>*hsL=xD|j)j-uB0 z7T0Bk^ZZN9;9S|F;)giwJt?DVpC#NK!bOU#NImnZAtDk?EN=GkL2-|}a@Vx;HSCa0 zvaEcT>?8J~YzrxWnlPovOw?vY5vVQR)rtdo;%3OXcgGX)A&!yZvqm1+KBFl9zd+Li=Ot$KAP*Dd%&q~4vey* zRRO&;MD78HDWLI#d8=gw@AmN@>b&AX%4Vz?FS^DWDrH=Ba0U5+ue z1&<~rgzpwbERZZBG^W7@-|z%qk#x$izGo`IB%|Xz&=6eME<-@-R_?ZPa8l{JMYvvP zRa%h2U;Gqs?F3)WWh^fPPZ>HqI3w9(xF_+qBzRdbwY%4l@q*`RXKHFZ$x&^pcWm>h zaNBU0HlA4Mz!%}s5QTk1`QHM4#jv9d_tMwXJeXLU=;Jlm%nkKupTK%i2WcqXbnj6& z*BiZMS<6PQ6>qme>`b?8i$c?%tG4+}S@PNV#{FW>&?MPz{mMbptg}}f0rQp2)~bX(*~{sagJ!{jES`I&g8h}b*5;pSp@HG zXF^H_smFhjxC%erA&rwFkGj&yE~v?Tps%&A?Up)NOa~-8E>O%aN=Rc}A(I~ZFyJ;T zRSYa6W8;uKIpfqwQfg4A7ap1{=FqCI7d#v1uh~;!vjoco^W5r|nU2P0hsefk>N$S8 z(4{Y>U4EzKWVHsN#P9y4mUhJOx>pT4@Zbms^LEA$pJjLn*D+xTR{t(+V(X>sBfBcI z&y*_Mjx6|awZLOz@!=5)#K;y^UZX9pxtQzueak{@7Y(6 z_+n9tqBz(o<&f)P3_Uju-7W5tvYPl$RO3B>Pg39C0JMk|iArW0fu5NC3JUhqA<@%Z z0ji2~u@03b^decG%3J&T^!%j%lu#gZ_eR`R)Vg%ihe6OiV|;k1*ZOH=NZy0cDd=71 z*TF2Or6Qfx6h|)s%?R>>olgk#GR?;&(fE|Y{lYBf9#97QQ{Eo4Fxv}eT$h%{TB)P8 zv?;x)Tn~vcJ{nbbc%poUV=3?c#3?0M4X}Sf1h$Gt1=*mt{DJyo)ow6i)M@(JBGcTT zk3IXB6&t4^Z()Xht|*)hbUSY%WP{>+HanHw%9RQ)p1imD+H?Nq7MPpZi&OB z65ns{0iwU}0iWQMvm4sV^HhW_I~Ys491z={6FACCf-bfkJFlO^av%hK0Q}!W;QuB( z_-31Rmcub#rO*jI*?#;x9YUOdJ)2hfWtmmRU-DbN)Z4^mOyVuWJ-y?WVa+dZxaj2x zo2hc@pU?!5HxAp@TNnzc#LkGCzeXJ%!{))bBVNQ5J3J&-8)?|ieA!6*qwo!c7Dy63 zXzlSd?Obud<#M3m%8!q;qOh0{3|~Cy;cMa-EkbK>D#E?pnR|fSH>W~+lq3^+_`elq zV#VQ5IWx1DD^j~bFN>IdP_7W%J(BvRu}VSHFuc1Qj8NOS(Ef>n7ooc}4`b{IC-Eh0 zfjB+w9A*`=pai=+==*_uL88$4s%s`EFq!e-(JJPIzh}j-#@U%g8icnCis`dx9e;V# z&%1ynw19ns7O(;a?;MQ_pTs@l`J@Z$-rk!;wbLLUlzrtGPz-mHNf>2i?JL4^bXU3u z;DQ#v++DZ+?P}OPAR!xk*)Mg$R5I*A>8RT=7O%J%KZZ+DXVghZvt)r@G-%0uvS0k4 zrJ^<<_R0Zc*j{`sPw>zq8ud zIt`9jVqjO5mj1+Tv}FOjrSYThlcZ?_rw_yy=D)u^-7?46@qmy@8GT#!&i#a=t6IXk z{sD_x42n!NG?W;p7m+h0`H*TIA!>t7k7X7jOqUHSje$w)k}+HnKM~h+Ew91MBO4Zx z0P!i4s#|}P!%_}qTS=4~-t}%vb-NYKd6!YpMCWn9mJ1upNS3oqVe?opNO*CX<2! zJ~M)po$aVMlK8l&#t5cwO5{UX29{oTwtB<8n39A1w-3aKD>nsy|5lTS5i|o(sn$`i zm476=`&bIOksULIDL$nm#zI6XzTz2o-3eiE{jq|JeNpzie9yZ!Bq3P-F_!<#wAKTi zCixFe!Jo^lMll|(D^wYmiA!!19*@&0d38ypHm7NAj}9`I?oWA59s;}3XOJ;=h361y8sfb!hywgOO}2J? z%zf)A`za)FJDV^Y{9(O}>=kb42$s$66Bf9yc%a(GK;vvGWL zb50zK*dt2#N(`iK@vy|fpnJef<6GVd_zUgUC7k4IO(@%7M5Dk<{Y@)=S(u-p zp;AfSd|PVOO@`%=Mk1jI7QiiuBA@=0^cHMXXFC)9gKlLfmD#>NCa8O7j-BZ#wKE~r z6;@xMz7&_HRLo!gw@MXvh#$tSI(ws{dF&fQ7LZB)Pp3dMCZO8^!a zZ*%Y0oKa;Uz9M&J_1=$&Ku9PVb&3F#GXHmP;p zwN?d)?Og;Fs{w6>Gqqij0{bWFw`?)b1J$ea=3li~WNan&YN>q}SxH7out@O?+>NHY zi{Vrj1h73yIUZ#X;Dlv|QMt1j)on!$J1_PzQd?BR#kaoxVt+Ew1Agu(ztD0<=RL!f=W&g;zwQ6mV6g&ZgTVFAd)_s3@u zo8E{G(}||C$OW=#JE%$e*HMx9i{20H1is28IJ7Su6sbSe#ao=a=~Q1yz*7cRFwwq0zRhqgtT;m=i7jY|~nY985`EPsxB z`FzYx{5{DKVk=rq<8)-eFx)yh_%86=i2tW~u{4z*LN9wA%0fAD%`#asaHO zofG0f^leFTwK804uHGVo%4ZauO50q288P`x^S}Ew#g3 zoc&{UUq|FAStY+OVUtOPgCLz_tT|~Uh*Bpd+-`KkxoKyLQJ5vVD-ln~<} zA7?P@b!i$MV`SLaE8SFOc*g3|4pO~X^p&&4oOe7Y)nQIq3k~a4fnXS(u=B@@e2dqE(m|;%8aVA3{h{G-jF_F%s64sy#^R#Xj47CL;jUOch>n1) zitY`kudJ%tHt#SIJSrH}&M2xKB~A+S2R@(wrQ|a7NHt z(VP~2H0o)Ygl8-Ee0CRIDWzV~l+X7TM^aep_xqyCVU(zGQX%gYu9)W_l% zM&0;fC-vw_Tm@|`OAd9PpQ9x($e!RP4K!H~+T=kaJE<*0v`|Lxxxs^XtP_DssQ;8I zKEloNV5sL@5FeB0mP}>7Q;~u$N&O*3qkBCFg0weeNt80aK6yg;SnG;2GvG(n(WXNv znVn|x-pH8Z5va;GFareLazVfi%~o(o15+Q%atDnBxvERF_8Z>=B0+bE8sv@CFD*L( zE~&9N#mTFff7FS(VR5hDfq`9J^Ngj63pZj(x!zBBpeZJoMg~W*clfohb+LV5@#BN< zEcUg45#yaVUp(F5-8~RR3K9uFy@V#TUOnK`+=7U7PGJh8dxZBA&zXvVIH=4dRg}G0 za{u#oj9U~$2St2v4|qewA-5NRa236sYy3(bl4ohHMMFwDX=DqIhpb2hHSX^z>T}HH zVsFPEs$jxv<#zzaZ!8X8x5AC9nRCu9>?Z79ny;E+#<|YOzpE&+ErDdMyBauzIvLPZOzv8Qm zK32aCOS3w=cK-~*7bOUoJ;L`ypyBkpbU1Fe1E+~vXnoVjb@%UU*ELWjGof#wI&(SV z7C~U23rtrD#d8%eqIG`*c%(!%*`(l}#r5keWdln*cHU-o{F}k;w^%vy#(l{<>BwMF|!Fu2i5)3xWuX6JT!7bi%88!4^QwzLllAN=FL#)@oUUMIWABT~tKkWh?HNtvZGkjcH!cTBKbHfSr$#1vDSnEiHDB zaeW?Aje6635y-=WYPX(c3Lxiv*Nd)QWZ5LwRX&wIR!{DDr{s>aQ-WP14ocP*I}hAQ z>~L}hM^@W_X-@ZFp>^?^n>iBgv4#5Z#zYzIK#^#=8VVKMdjFPVhgF(2SR5?BDm$QdBHM_ z!;@xvNgC{fCulk3i-YsH<1~UtTG~k zvyuIIM!#g3xegLP+YaJdWU02ibcsS(cA zF8PGM&08Yj17=@nv;Rmss}r}W*$>lcYN3{@Ei@o%IB?VaZL;5ffo#IIvz2uaaqaSk zIwigkpp>a5Fh$RT7ut{{y!C3?_>&H_Mi;t&maN{=OgHfe@%FCZ9zfc&y>CSI*M|}C zV1NY(%=A|nDO?+!M!6 zJVgCH*yVZL+@Hj_ZpX~hHVW1<(Cux0rjS{eKvrl2D7Rv8b8VbW!u*wh>G>I)8CTH} zmJX2kHOpWM+W8?4Ju(y3GqF}cy2z%@oqYh_%&fZ;!!2fZrqTuO>w==-f~ePkzp30P z#qkO*iwMPI&FzS4;6LrjFLuhy#uv?;m}72i4ZR_kMjuh094GG=rEZ~YcTU&nJr0$7 zmZbMNIXT7~ZB@>k0W!+rw!8?V0)S9W7Kvs#D0i~yHLO%8*ErJ6mx?U`+ z4W4EK7w4|7^|kZ=f<*ynVqkXc9&o+(#=~B&G0d6Sqw$vtRI2zDYHX0ZKmK<69&4d+gX5~X zBp;Ep+vlSbetsyOeJ*{3JRP;n%h}{RhVucb_h|BbKVi^LY<*S9IoaIg2`w`P$wFg^ z(+XdTWy_l*Ar<~_d&~Suyn?mwEU#&i9`J=6E0ZO(HP33C-MhBzESiNdSb?}q&Ccj| zilEX<22Ln0H=hP0vLnkI643V`<-^Ys=gXIQ3~9iR^j5}wZ5&DXt8Rk}`KqEHw^&cBYC;ct*5aq>|BsvA%>S0 z6=x@2YVyv;JZ-R=wQ~7O$_xS9E4~T81cH_(6+04AWgtmudBJ{ccgF7B%6BJ*IFESs zeXU;Z3|?W{1bL5;*R9#)`j(BFa=fxp;RnAs%y@@zG^DqwCd82TY^t&pgH{ogrNhHC z+c1%RwTYh?YeXqN{j@Kms-1OAo&=UK`Zyn7AX)ogVpKtISJZFO)`R*cg`mB6Kn5)_ zZhYlu+z+UWbkf0xPEv<0sF67uI4&2`P3rbpUMs{fh5AW4v*5%7Y+6UETB)e2AMB@Z z%dSM!#9(NfcZ2Q$3q!)L?yzBM2fQ0PV~W_98Yq3Dqz89?Nv6Xd%hcOISxw-#SP=ar z!~5SSpAK)=>(Awmbh>-St{=X~6-h=EHBdm$}9_94;KNMCSI;!o^i7FsXiB8+KO z_QHw>m;8-@MlH|0ghxsM|0yheLInn^93LXAIJc-FyV(&ubJGkpegA;mLGTtb@X*D5 zTP$3{Lq#VC9eszPfL3lSIhf4jVF^5=ewpFRI9rL9No(2R)^P9AVF1C_(IYAH7LvQq zFwkK(nsr-yVT9aBv{zmsj_q4S>$oE7cQ{f51-VLlVcQ7GLe~KwG;K?)Us^^Z*rGUi z#wqj)!4GDd?p2c(L0y~rbzViHHN+89#Ie*sm8Ps7Wx0s6F5>My;Cz=0c?I59SVmU| zvw;4=pG|UDrb89~RU^I;Z3mRpLcdFPC;|H@43wPdf8F8l3fMT`=R#h9xAp8}GE>}) z8}Z`+uY5KWllY?8*MID(CTo@JMP>@ zc-ta_#D2BVE{AAC`lLN#y@$YOk_t6J9Z{>;w1iXB0+xxdD}?SoJAu}cZ?$2rR-XcT zDrvme7FT&D7xFt&Uv)Mmy=eltW&3PpFz#lJQ-=S3K&`gws$M0jH)99VH+vhQw{W28 z#_n&G@Jn7A9`Af9kkde+7_H8ll$THhkWzMv?QA?%V*5dHk|s-*o+L!xaK)w$zy5-{ zANnQb#O;syj(Z=-H$eyI|^ zO6lYJ#`_>C>nCj>k2-3y0X_K!pp#F!B&zk~m6c8fgGnV1KOXo8VUz)Z8H1_oN5--X zGPVJb=tvqrGfSE+%8NVu+;kUuwQZqiG;HDYl+fJ8i|v(J;;O4BT=2_K)D6+k#@fX< zau_x5Hu1a<6$H~51vdV$bv(9~@$!^hUmX}7n9RFA$!+9+Y@;cG=3s1VM|l5`EE1?& z{QR>uvLu~$LYd)u2N_zj*q>~%e?CCa(D=47E6zw>#QaBBpu#@TUv2|UK5@~D5vAcw zly-Smz8@Sd*u?k4+&|Xu8UjIK|NPdseu4GX)B>sP=?RalC5xv2YouzOk7hG~u0WnW z`4jOON3mdQ(uv0x*JyjdkS6F5{k}|v(JWno&JPKYe^?croHpI3eo#8fce`m6(y)Wz{Sc?E-Y< zmb|i1?DTC(I#!7N>rzwu_H2!^xr!NH=&>b?l=jmZbT;nwd8Oop_Hk_NO7tm2>b>R& z;^Eh%L6X$RxYZbS4B?EvX!2jOi8&o-E=@IYS5ae=T1_lBc9n#RbW`E#$OPoV>RGjWFAA3h{*!b?ZV3kPzdU~$S=Vk+ z%X|penI1Qbe?2@O!j7NSSq|x+DGN2$SCUjNnfjvpnr?s3ddF#z2(YZMd zEF3!*ibskTT4G^WgO}fsAwS()62P3UJcGjbfCqZ7Cs@`#0UDaIBk0NQ0hT(OW@efy z%9}DCFO(x|gNJ^F`%&tBn9hFqV4K!yi2lTadXT2(7f?r+MWB{!W2x_JC@;619J_)P z*M}qjnK$1WnKmrsv6S<2I!=GmykAHq^5Fgp#<4!MDPC5Nj(+_vjG<@N^Q>0NntDF( zjM&j>QtcA#MM0YRHuu*P?g57Vp-Gxp9p9j-ZU2gwVRu;1#n(kqyZ3fRItFFW{|1|5!Lu+$tcU4JD%Wox*SOhpa*(eL zEiX<|HDrd2swXWtjl0jF|9we@N-fasRxgYwcpR*jtF_|1#M`&yJTyF6;|x}gQf1w2 zB{Wftcw-4Omzj_kx!7v@orjk`Q(|e>GE+zxQ|&4;>2afTwLtLjXSOrB8tI36zl6ZR za^(MdH0oLPuhz?Wkp-9PBv^u_eQ(KU%YD566c^7HDOOLnu@hOIDjn%aGUx~;P2%zd ze;d{&W3U0cp*++f9Uoy%J8{qZ6X(h%DQm>7i&`67fVSoa^n@ADh;g}nOH`aNO@S3} z$aG^zLJ9%9cH|sgXOCgKz$=UmI_a>sU3bZ^QaK7#d%rpJ7V+_Z&}N6GiJ!(VRKLMu zLj4+3H1q~|#{^>&zX!fu&{o#Jj`0GyXx@OGYpK}ax%M5jnoqNchzEbqUT|exb>%a&!$@%_z5&|9M_a+d*(QnZbCCn}#@8JS;l0eX zX@QOgV&s+*54L3Sm&-!b<9onn&|3}DClKN913GMSlj3)1=kY?17bB$>w4%ZvAo<5g z`;4Y2HUmq!AEr*lxg*39J5B*gnvm3d3vFoQ)F!xj4m#Dbr#U^m2RPBAH{*qGnVNX-c3#B&XxmpTwyd#u zq8kf^=zn0xqQ(7!J-+jYC*i4yF*$ME+ZU6~noWbF=L87odgU8GMu>xVWa7LJWrBjs zDS8(Ud6YuLvD?4rbvVIej9YY+7vbGGrjqsG;Q^hJ*u&Q&;C^QD&23Clv<{&6tMw~r zGkxS5xQ{m4lnyTkE!J}^uohrc$5a_Q<=_NrgXAfs6l=?qmvdAR%kLh$?T_k?M5?H8 zJV_}mE`+B%-C5XaS{1VZwe9XkNTk-SBHUIE0-J3`Ai?F`x83Y7Y3~7^2*d@d<#)+A zb?Mk}tIE>)%cM2eI7-J4Jww7G^tqxJdqwStw=;cPBeE~VNz`txuc}yC8Q{?|aBq3z zq*Y+uQwJWc^1?keo@}%+r_)|jj-irecz6vh(PUo95otU?Ck$fjQtU%rmmZ*&G$2ha z6q&Dg$a>W)vq8?HJ?|YSbvk1wWTC7iVt-^muM5>qq0UtX{Z`d{QzExZ$eQo5VV~2j zCRMCU?sF?68$p6V=$9Z*kjqLd=i+SaoT4QQ6B?_ID$PVN9HqOeNsY==!?FdzT-7x_BBUin}o=!)Z z-rbiLvIIBC_S=%PQVsA?Me>Od>hnAn7H9EmGPY)JiZS$27o<}0M&YziI~Vlr^s+;6 z;B79B)Lo7JL-zoBS+uk)K+`rq6}vB9sVAVxzkyZItcXyMiJ>gn>|Y8 z^sP=@K4ZPk1hM5W70WYW;a()m`=E(s)9xMHH}?RVYbjXCWof?DDOVeseRn}qtVQlh z$l}(g`7<0l&!so7_cej}=ha_hSol0*EO$<`18rOVg*I;GV+K)-3uwj`{g8YPlS&GW z4NGIB&zn%>Nw&wyK5%Y2NAV2ukVs3Lm+!LlX@7)n>Q-Ob2+dV6s_l+duii#B)<=wm zl=c{U51=al+3ttg{(7oRyn22cooA{tTq?qJ(>*890&K6);)?7b*9YHLmeu(GA$ysb z(ENKZ6-YYtBs)k~?UqTta9hdYyKaXUHrQmt=QOd&n*@7b?+EtHt$S zR+N8CPXB#fnbFv0*}BfCqp^Ga;QU2)4A?oxwjh|kWqLP?NZwY3OAmlLPjFpd^`E7X z%ie@fx13iCMJKbS_`#}RBD#*8-MVwsek!Eg~DO;*e!y}CH z)KvR^mGrRAvnlosiL1pBbDkd7LM)L6i_+-d;bRy|S58w3jZDO-Gn0mYJr4=WxV$S@ z+zS8E>)l%Zp`5PK7W8rD%;`}%N+Sb$4Rg{a%$Iiiy^Mf6Sr>&i{gOxj{g^LrH zsil?Y2RlbDD-TybUM>$;D~tcR^f3M4<>_K->Eh$;=<>mm)79BV%Fa^apJJkai;4bo z>A`|-_}{_U@6eC^SKH3cE}mTSwEx8Vprf|Aw5%*VfxO(joWcUMeB3;o{35jcJlvcj z0<`?Xyqx?(#*&i%4*llg6Zqesr^V09{qLaf|1Ki=2FgoB9B-2x=BNm>Omn8yRTCO^PmzEIuc zcc0R9E&JTt!%dO*Cm__R3(5_IobA4w?t(V%Zc7?fU0YqpcUoMYUryd%3<};)fGAcF z$bB%#QEFokfqFx+aqch)cY=Uoo34JEAXlKr9oF5GDAZuwIhD%&RM+57s!PNXVnrY> z(+vW4gspU}otSy-nSIzebch%8o`jBeA3GrK;_~%#5EtGpH_o@nxPbMI8Xw6?_$h3b z|5g;$DF8_Z*I(VhII{dfCpArb*VIdAC&`^BJKr9eBJjJms+GOFOg+06#5a&T6)>8# zPUtQEQ^7d|itov}U$s101fuJ>a+lK5R@(qQJd3xshxusp_$s%|<+qc46S)&n~uS*ClSv)`2jW#sW9kOi)fPm*`Rl;>N3T zqiTF_qElSYpUg*Q;pZtLH>b**WM|dx>xQ1E(|E>J=Q+K345FOxxsV_95$o)a`d69*7SFIiU3pfxRIw{J|=C(<^GUHc$sdrEv%gE(5D|JnawQk9^Cb< zos677912d`WIOytUeQF!B%Rs_x+elvr9@c$*L(Y}_^e@O{wiMj6m*vA3pe4gJAe3I zlh2pVd3@96uD1tiTv2J-?Ky$cV$;Ss$?5fW+s|hhyWTIf=DhVuNAkN17d7VVm!g%R z>#0jl4R!gbqBRu-D8yG1yqqLPd~E%W)Zqlu(dNqIL8Zm{ol4c*iT)vd%)>hKCB=~T z6;~;CkiVhV8c9_u$R$xTO0eq}zDSqW^MPUC_uns9Iw(@QSB()ZoT>2V*wFB5!!tp( zAj=U;LWF%NEL~5|XVggYdNdcvdxQ#v@@TI=JcFG<{HpUmog8rCY^BbeM)?j`V3Jie z^^rr`c3_Ej%N)b6?o~}|vle%P5Zr}r2x+qo`I))mh4;m5`cYq19z)|{ias+*>Ii2O zUfFwRd*ZBB@A_dzcP}cDA5MCn@o^2t+x9|STy|gYrbcm1?+J`=uBA{&(AgI(wX>Lo z&4WP?o2B#6YK%4pA$b4t@$+qk`<_@RYvaCADT}!=H&ir#PoBKnN?iXa&%UMIRM`^o zEIGY->iMU4Yo!frmC)lSWW{@s@1ji(w#J&XP+s$n)Q$pV)J2YGJz|7r<5i}EMAWcW ze!ZlRdFSvm4L0Y|nZBu!y&{CwizY59Ytw1Po)MWyEIvQf)Yb&F$NsXtH*V=g9mNp0#AoPjqz6Tjk6Z-b>@#>b9)kznYVy zYj%JK6;&#yexQPrqsEsN0++eOnWoCLIDrc)9+NF|emo^r^BolO>XY4KE-^x(g}J|O zc_SMt3=Mz;66d;yyYSwYz>lK*-P29})y7Iz!oRa56eh+E;~~}2JgT^jw@>%z*$$e+ zyX?KI1~-xEpA8J{c2}&e24^U&f=jJtxG(Tx$tx$g7rb~e7u*`kIaqqQpq!rW%aX$% zzv^%%%bN3MUHi}AC50Or6(x5YCVNSxOQw71*E00Zct_g70lQ3zh&w5#8nZR61u;x-QkjBACWc>YQR4C(g zTc4bMQE@M`*y?QGGlav|+U7k`LAqE~YhmPog^+}5GQDqV7gesx59PobMO8K2>30au zR2IMGE!GUL~*Sba1x3+IT;%_hY=dgIR->7B= z78L;Fc@q!F`E)&$OXtWJ_qS57L9>Kx2(;*thwy!R~_}hbXG}nGgPYT z5_6ht`mM6+X(!EV;f1W9)h^g-&h%6J$?A0+NHhGD>af6vq3>YpJLmaj*Q75udHoubm^&S(caRVzB}7A*Py~#Oe_xPJ^sF))VJg!#+%hr zHAqHRl1Lrd`2J6$(!z0>@8HM4CjYXAOLl)Xs1G6#llKL=BDhz|Pase+d0<}uCad?u zUYw-(Z#S{6?uN@T$y>RX!M1r+d&}uNhi(`50e&jvOvj%#AtR!%jU|5rmm}Q7$e&G& zx9qIy*N_p>lvqF{6mawkk0J~z2Yv6>7pZopw=S6rkVAP{~ zZ5&so9wP4bF3~&$bKFJ0f?`FjE|03__dPm|Cw<=5)=XS8Z-_ur1BDPDrnZ+3R-&sb z?TS)(TWVOm^LiqTUf}GG^|oK!3MhMoe|wl({ITB3RoksV2`i@Ymj{Eb|A+jquih+F zyT!Ww{IGhyUT@2x^sZ~X6Y?8ztwy_A>jX!5cbiS%82GxViGSgd^%2gUrHa> z%SttQNMm}WpHC!kJ7!qW?sVo0Io%Axr;T1|0uGtbQxPeyrlhNQKT`NuE{ULu0nB#Z zj9M7j!Y$&o?%Nj+d;KkC){u8O_MvbR+mg_4ifZ41O*YyeE96V$a%zcHZhg=8KNZ`F z_`X3Y$3?Dl6Q&RPHUjUkgO?%!!$&?;`w(o+_`Xj6<&YuA{pVGq>#D6P^bxNq+h>OT9axa>Jo1 z2a+cp_>s8Y#=(+EFBg=7{8M@LiZ~;8;02xx+e2mf?gjy6e$KXKpH;5N*>N#O$Gppz z0-;u~e~)W-<`+kZj$N>r@xX_s#=hfCv>-mL8|~s%(H>2N_+#S=F-~Q>2uRM9V=XGS zXWGeA;?$;wj(ZA84C|%+PFw;#mA5fhGyE{R@@8|SKuDg>rmJA8xhPOCIu>~o5E0?&Us=3M;(-un9i zl`>xpaw3!;BmI_rD;zDZ$!)sf&Ykm&v=Xx01^$81lY)k&F2fbyk1ubHt8(8%R{Sbz z4Ty<8k5XhmJwDmmLgy2lbth>172a7_x3vb%vtjJG3!LOeECzhXd;J3ZZ0}q?(9XuH z={DoFK$HBJo0#)Thet#4ikkjEy<*^BUjs#DR0cFABi&P;b>ObhSX?;HZy4Qc#w74j zxPKay5yvO9CO5@^Mm-)#ne=&x6)09^-uzq*vp-D`Hj*)u1f2OYZ6x>L2fvmt?^~ar zTPNW?A~hxQnpidln-o;Y*vSiPdn*~2+%m6^*8zfeK__XCUr@ydtyi8OQ)$jV-ivZ( zVhgzbso_`usRIvNYTm%?yQ^)@S@BXKV`^#eBBcJe@eRmYWKw5y` zb6a3Pb&kP1KRU*$qCE-@U+R_P%hZfIiOr{m$^NgO?F2>`!&GHGj6 z#r8;xoV-mBw{_QN2N6olRrmuj7@$Pl!sBPzF`Sb8w(>;ibkVV%oN=;2K%<=Te8A5{ zNh#wBuO`KBmIuNRo7=+p#-SM+&8|dj`1S1F+)w4*OumD`uc?oEzaA+%@??#zOM5@u zJGJz-Q~r(hwp%P_nLo4^8o4XX#tlfbgs|7171p2hvQy?P*vLte;}=7>zAyRgJ$mn* z9JP=2Nc-Yl!9n0veP8tF61;9V%Y_TOaAyg)Po6&G^KV;E%R*0HeEHzz?GJpBYA6E} zH&|=*==-ENcfyo5%6=GR?^QhPBiXNP{l?l5MU2;3cxw?D81`LD0a_pUj9Ylpo@(+S zF^vE5FwNX?LO{|K_bpwND!Vwohfv?X$c-rDcjlKaw~{_ZOMj%yN(1&@6QTb=|M<0g z5U@AhXT6|jDYBmYi}|h(*2A6f@bu-ew4J4+s>icl)?PkWiof&CAyV^|HYhwIs=0{^ zi`f(drB1#=I=G7F+7V3{TAu4fgLf0aW!@@&-hVW#<QS_e-81}S6<=tK@3l4q>tC8hao+I6q5pJ z;DOG~2-&Ftbr&8xld2uHAVw$H<}_=;c1m)quVHpfE~GW z!n#HZj?7mle*GHz!_VH`AMnOShy4}w_EJojWshHVY_N9?JT{cD0benXW~vCX-?j!3 z!dVV?x&)xq0qH7y>VdNL>f?b6+KH$+<_J4&EEW?_p!zd5etyUtH0LzWGU?&RPIM6@re#fcPEVtdMD1-g6#YT<<1WBQKUOESO^RvZ zPN}{kyYA}AnUE^}*Vf^$-7(_~Xn&AA^Gf$^|Y>URp#4PSTdc&~U^_*yKqHCAjgW+AH zkV0|4qrOekc@D)-57ceiCvLIEj*uod(qTE9I-ZUQfj(>eZB1TUuivimfxa6OS_r=QfX`SH_U!E+wp)fzDI7T+k-vnt z#KDBycwtG*AJSH4U~9VNxmJYLVWk^WZ&?LH^P|!9+6+JZ6G+w-b8kddXJYjolwoPR$6nN;t!9gMv%XgG16!DTCS_Td zmvWF-PTIqtN?cvrMGYz1jx(zM=G6(%9=ET89A_C@ociv}gdU!y*S$P?MRTN+k+v#w

9p=tz(Q_l>FHz8sFdoqp5;IiJQepY*i!u+pS_Du&ESMt$JF2?wk5kBE9MbSCph_ca4;zoGs{>iFR=_kK-j-L zs>~`B+smsv4!JcMZbzqH>Z>`NfgUFyc$7jljYPJCPE465COnFC%#2Xv)5%*oj6MTG zedZ#Eag$Tnp02fo)TAZ9%{(BEJSv-vn_r`BuFtnA>~m-DuPE51JspX&N!YeGs%DVBHV+h(JmSks?1K_13*0*#mVlGFG;9j;tHtVG6* z!1mL5_tf9@t6v-|CblNlpSVkZ-Zmit^8Ac^mg{kx`?sw3ISrG^nlh|zI|a9;GjJy{ zb&_{mmVcAQpiw+~CYxH5RWYX`9@Zo+Zi^hqJ0ER8W-{heJSZGJYl=J0S;w!Ixt~Tm zXP~3C+cN!nYEfv&Xuj3W^Yu9h79WuW_zDzMCPtR$5ZrCv+ek~ zuArmgzTKDP{BCP%)75W4I8r~BIpp_AQ!mLi{YI2z1$N3lHc1ZAzXDnx?_iZ5tm5qF< z1wn}58&UCG-KM#1a%hjzIPNTsQAKyd`x{j|KZxWX<-g5AUiVQz^|tm?Gup-byc&u9b3mFIO3x{D3}v%o z8y$n$b&vJ;{cEwv9V5q}raMY% z=i4_+D@WPvbpD>|c_0C)I&%!xAtTEi?`{|;(6_Hxe`?GF3oGTxOi2YZgOZFI((SHm zGnRQ7p;oRF@_t**RQIkVt&_n|%QvK7bG?}fIXHrVZ_rueZRMKDTePl7;w9*McZv{+ z*Hkkp2J}>iJeF!#;=I+U3L4C*RERqlt?!K7C-fj8cOQo1$;^r4; zPn`=(oHKL9IVJ3K_jN&H=7B}74xasVJjvVE{7@5jwx#Z*{JJvqq^RhNbvX?oPV^?# zVfMudm}T2Z1SdTnL|%y|NeU*XXuI{=e5Qf9;bDW1ABsC! zo+*~@x-HiM@g?;>@h6wAnjMmUQI0A{r;g8z6Zsv5W0TiDc!F+fdp~jtaHQu9%$@Y~w^-mfVCF zI`donay%YWUuj$Jo@U?o?00U2K^@O$>CooSBn$m`$q>^NZ!2^q(nf7eos8Nb(iV#Q z-IlES*q21m^!Ilq$A?n%=hA_r4W-!Lmdv)HWB%LX=)uyW$aa@1ADD?t*6Hf{W zU7~Dm+yotz+Efz$>qs7&4W(D!R(|<>DxdxA7$nYaE=JUD%G%B8@$Cc{D=aW{K~w_T z>6_nR@%qZzYOH!ZEA2Cn5l^B@Mok?*ru0P$8R}bfR&UQdgq^ZZlt%iKq@)xy&pJt< zGJsN|n$)!@bXh5A{d-xvm43MllfXC6a(rlxSad0GJ#~6^bcT2yAAYWiLYWI)U@m!6 z=7h6}U7K6YfNw$yEo^aDw&q+)QZnacZB;l|-^$0%pl>R5IiV)>Ri2Kg4<%dj9mzp#dsQL&y= z6{Qe$7Gt5ay1A4bXF;~@Qat>6B(js1t^!%;nr%9iZuh$yR=7NXQ^mqKUXYDYdrz3cR>M)6Urq!Yv$ z^6V@W4w|6@NDBh;QMZO~TV??7C*6n>OYMV9hD|@-J`a0@Wvft?=92GQ2u#LK*aWkDjtauP-}mt@=K11dbyhJrBlEMT2*J z+dNq2B_GaszEG~%!57%43@6!vGCERy5oDSKMCSQ;M^JY|0iXP`vf*{kZlI{7A49*1 zkCUrK6fqPOG_sh)A&32fccIu>-e6#0&GQrpGu7238O!!Da#!c85dAezVj~j%GTWe8 zow+|laoKvtpnUCeA0}C-OW_M68MD-j`j)z3T>0N*lWmf1`!oS2>59dQ7&5s`(gio72RKaxQ{s2+g2Gt} zVa**}*|Q~TpS#2}WX%DfF&p*OHliiw=2a^rb$ONcPH^}8nr&K=je6Pg1uf5dI%;cV zYa;@*DVyAhrSnSLrDbL7+b-=~Iia={S$Kr7b^l{7 zX(jzKSEnu=Yh0}<>O%(BUGc_ze(aSZd3T1{*K{Cnb@a~_Z3`uL&5dsqx;1*=!&~q< zH-|BiM@3ubDDOKtz*0{MncZqd%IMG=65HYJ-7>sm!7&*3A@6R9Y1b@q?L{}N$6`Ge zxm^oeb|b!5FXl@St;x37F6PqlgK>j8=>sam#8LLHZT#k?D^bSnckKuCfHK{9%EB_s zb&?mmuq|`_$1@gk6`{$+>D?xB{bTiunWQ|UNqYa8lTvq*sckErW9D6J+lQA{CZe5` zokDE;veU{Qlk7a?Xk1%O{bV^m_BkAtE=6_hkT`Z*>Pav;t-2hO^qr+ZhmkuyAFz%c zw9Ha|lyS|YEK56OY#$Q0EiV#iX;03yp|SJpI8$7+Vo@7A1aJ@ABv&nh-di4`m`BoW zZx~h~YTLVHpUx^1qio1ZpeJ&hjpY)#*sjx4wrd3vZaZ5FcCzNE)N$pv%!{S+`e%Zp+It%eALv^0TFFCBpEMII=ovEmu zZ&j>8t?a7{m-;1rbv~eRleh_x9GOeT74O@kr|yExvmkU_s~pj< zx&7YY^8AE-TRQl<%b#TH392)pR_D&#JUTb>MiTI8WT`rN=a==8rMz)Av=u4wrtq0$ z>||6$Rkot>-eeP8Ntui7P0r%vs*h&MQ{{-*AtsrvWI2wNw-@Q;_YX8=GMRO0PS{-< zw=~O9$gl+$CI_{ULV&u!gN&U2*>LEN)@zEQJ2%2xP& zpQKd|?$g<&S5Aqs-6W16oWacX4!%!k5%b9NH6}c{Rr0>^Agj5GIuA$oM}dm_O*wk) zZ|$2^_D)`d%QYi&h6`eLlnpocEUj{sODH)Wcc+B4Hig!i`^GN^zP@wUKvF*YDv75k zKrQWu73~l=L@M1DJD|Ke=jw>|qv(Mzo2-EnXp^R{Vc{#Vmd*$*4DGCmbNi=<)z9o2;n!IAmS9I;R@HM>)^FnRUr<%`g@pt`h(lfXJ*Qkfz zX*Ij+Nr?v10yVpp&zzPB19YEA*f#a7mh((As;z7+l1?0 zqMYOkeU4WiOXmNvTI9YS9pHH<)%kc)+2WU-p3KMdtH|CsGBUjjH9(@uYX^Rfh!1%b zB6V(i%~Q8PyekoQlKba94pu{s$zf2YzKB=I+0#npR~!_cE}*!{?$)~L{fUp51T zGhGIBvIkSZ!YL+XCw)aem7>%QDm_UxbZVa}iDb)aanotm6^ui4B2Jy8y5>yFk&!W} zFI+e>NnzYR+IAjKEqaRM7)R&E4kDCBWu;1~N@sf~wH;CYsA$(Aj&^4-zr|i(7kf zvcu79y$PU3N=|?0o>~-5b2)^BqEAnqHvTU6Q#oHbD?UClsytaZWeK#?1}2uA6}6Jf z$0?;(Tt0FRGbOhn?`3U9>!W7QMVO--Io@_DqnZyqwf0*%z8dQ3nU0Cp(=Ho5;W4G; zN>U6Hnol1fJ)t?+^6^rea63FIk=JGGF!KNQrUDGG|Y61xn6rv{j+)c@u(7aIwYn z+MfMt{aRP8b0-rWMgQj?(l&u#;OHLta`AMJXbZE@K|q^iIF}TkTS4Q}FY{rSNvFt+ zLE@9hLvFVBQSRm}{l{U^o~*WP?#bl^@v3-XmjvLJz!rM98rpuD|N;3jF#4|@ZXd!*c9K7v2H=W(h<8UoWJi>qEtDq@mPTUoc zG&q7_{(ToPg@Akt5c6_lbnp^rIPZbUFi>9`RbM{3lPn!wiqHFIB;D`uE`vMzcxH*N z$_Kj90c;8|@f;|!=;Ljo?$ZTV0KF^CIl40=`ElAMghNYcsKO5fjB(6iBUMs2LX;dhNMDWeBesm~fj z*Qh$yb#8;){b3E1+V#w5ldz5^gUG#1uvK$)d2$jhPU`(6SN8VATdQoo+y2F#&VgMi zJ>yv6v@&{ZBff;l;bbPu)X15xQl72$pxhQ&I9k_*=QsJP^+TB&r^w(b6~)e@Y$rX7 zUp}!HsKv4Ub0me9-J%5AsJ&esarWVoNi0lrm&n>RTk>MFo$uUbFdo*qJweER)v64r zlqCHlS>Yx(dkXTOzKBWP4|&!xjL?J+or#CToI?@7aH)CE?A$x>yPD)vR2q(D zIc4C5BhZIDlJJ6x^P#|8kS6B?)^&wwd+)XqVe%Wb_s|rzWN{3~u`p1{uQYnY&Qi z8)$IP+%1H5&ULb%T@gT^!jTFxg0nBgcukA@Ovlt=ioe{J;*C}i&px%JYUd1;7#t>Z z*yobkw5QnT%APu@y?+~`zVn8hSs_9AoRA+LEHyCl3pFNwdauiLJ{zi8XL~+^b=7qv zA3B#*U)Hsua3^9}5g@51QGuw^>bjGItQDqH2zOa3VLBXgFv`N}@~(5U?^1=<5)8FV zKiP9azoWfTkLXaK2BN0q1gurAbA<252@1Z16T28a=~+_BN$^rj>y;G+!UZDWAY$oR zu15+7KgEYb$ZO#OWxpSBJ(1D6{t|CjH3qeJwtw{NBS+It3~P+0`3|cQw*D4%|CAMo zkEw*WAfxq)kC4%NhfP1hLoSM1_l1GGG+ywB+>*#!19xyz-kwN^!y*-uxpVXwBrf?< zrH8u}`S*2^!dtnsB#4IT0LNE{+{Mkl1lSQ)dHbGcZ->pdeB*$qB@jXt@(m%6p2w&&dC2(PArMu`&#rP6E zuGpkn+Ovfq2vozOr{zL+Q1_b!iV>-3puZQ~Y04pj{Vz6qSXt8iQ-|9-BSTp|ykdUg|?{=ZkcfQY+Ag5(a-}8;vYS);a1`E3$=bsjDB(;oNP@+*!L8 zUDAz%%W$hB98Pb;<-B?xhlXR4f-@gn{8Yc(WMVW+2i@UfV!a_3>}=kyjpZtZ=H|41 z&D);LQpqaG*88jkfy@bC0+9-DWh}2+=$I=+vn8oQxun0}o>w*o3HyVyju?Ws9!+8(#w>NiaYPJ_ z<3~=k1o!=zeb~x^>+^juSTH)k_YSNW-_UR(KUU9$tQ`4Fl&7HaJ}l6xpg|ski zzLcJJTlM}Tm&|h#VM{86?hQC43G_=yLU`se59Av8jx)X<0gwkLf>^u}b`Y!9D87WU ztM?c2N>}7{ll%@{`HRqrns321Mil&=Z-r(fFo*V_F9F6a1rnLR7W5U{-7UG#I6?_s zk91Z4xvdwr*-E1g(&LzwYj$$`NbfFHF@v>%Gd9*qQr*|h9bpdm-yIsf=jAo09SHV#<_p%;(V;K zRtNPOV##(K9p$hT^BY|O+IUqf2GR0Z6rX9RE~-|HMtJQN&>9?K#gccS+2t?6b#Az* zt4yEKu=W?As|~4|DHQojVf@CLWEYPn`Uq;!44^DEBMCpv&T3SJTq6_&y7SAwb?aea1%m%1v^RRjXHx(H&}bc z8wy@qeGL^NYLVfDdp#=tKHIFhLZ%aF)!sD&p)ht`pGcylAK$1OmZG`=<7=)mU+3hW z`QSw23J_+;xho0F4g_($Y)uDXIud~9DhnyXCH!YUD)JQT1t|`p;?>03VoNgYob;ZE z7XmzpVr=dd3DAu!oP%JF%H;7QyDdVYPCr7#3o6~+x8&cm*Qh$wih_|^Q0r43gmuPBCBobqtSSIi|+XQaWozveLB9CA)NuNj~tM&@Z| zE0|veJq9o=k+8qR>UTQ)9H1-3gP4(`dj%8X&P-fz{bt-^JiLXLYNWenf6t%3iA@Dif@fRLi zC@sYL0nm=iyq!V}cRjy^QK7#({R(%hE<+e)80unxDQGY7#{iiD#8I(<5C;+ra`Q_E zakQ>J*L6DKfhMYetlU1iL}1Ek7xt!}Js3%uv-*-8*FdA7@B*lrmMC39|CqYvZ&Y&7 zQ=unR3lxFMm=vmK2UQ^F;Ds>&8mEj60msyQ3qPU&DYfoI(uHoD?|g`C*xCtCqm}1Q zSyxoE2g$R26k2ygJr!`%m4pd+BlMNn0L?rw;5h7=oJAqTWlJJPm~c6tR^>64t~DCw zn()~Ypr=42g}`m#=&G;o@il>;^(CIQru0X_J0{RiEBGuzRMr4)3NDm2g^hcVpxWAl zV$?DGZG#P4m|zDw0?YZFg02i1^ZlF;ns36q9H0=r`r4yNVKg4ybW7~u{K)}1KcwpV zsa&hh-Jnk1gZc{ArojK_q7I}p;rw= zbz$I&V;Yn)K^|!Z{=Ey1ser+z!midFxX}i5l=3?YTi2QuK5anR4K4_04pbn!u800s zKe?lZXVHWE*sTN4DY0SAz)V&esx{!dDW+}B0jHEsG>VOi7J;Xl$N{b^a!@V!P{AA( zlp9wD1$2}%*n+j{kA4zB=gjI!j%Cv|+MZYVtT2CLf;!S3*C!NjaFJM=CXmT5B9p=VTn=dCo*yu*!DJmc|UegUf10b%u$Iu&R8mG4qX7 z&Y0XsH!8mVroT{Wu}XmNZ!mZPCMa~jAl;cX0U^WY&<{6$HB^og6$G1^eMf<4{#?Gi zwvx)x>8Z2{skH#DHy7nqhoXLD0{Z}vDb*xgySi(Zhjf1j9#snlfTc4^mUGBNeJu~* zo?LI?sJats)q*5I<_09G5-km2?UTK~6K}a=43_JI4ta%BWwS;#kUR|UAGGKaL6zi|7A8v(F&$R$=WsokAqAlyq zO4S5H5|wev+>|fQ+{nxkU~730vI~wtfh39`)=?6D{im2C%i&@kb}y z%dEg{0b3&@>b8U;SlEkOr!eM{|N1Tmjw>D@vE^aAW~v=uqku7JGup zVJVs>z+iYtTVY5e_eR94z4KO}#*EY2Lk<@>8={i^w}O5}mD&b5eB#ya_x^w+H!6^; zkXAs>O7atq<9wKdnc!2zGLYpMEogvBcXGtk|g2n7(&+yOIVw&xRxDaUp3 zOU6C^OxpgOUcJShE|;)mzIbI^|48@w6G6clH5(77wW!8W)f^ zh;r7dn#*Zr7;I#Cr^UQWqQ63@rxfi*5*E-gm96t&)973DJD&N`sk1Be&HeRrrJl0V z6!HY!w0H}_d5D={*HAk$i4^R`+RQ?>R73=TD2g>5H)NzqLTVtTDxKo8K05W{X1A#j5^6YZv~pKn)e?;w^~x zVq6Disr3S{Vy1>@YX!fJ7r6@YE-T}uswHm3Gr1wNJjGu9N@YyO)M2!kA%6$rh|MP) zR)Gr>8(IRUJuhZsuZ)3FKg&pLw}!D{$a^jxn9V}oYT>_pQ-O&0XN_fq2~%V9^{{l_ z6>jBu1H{rg%FG@xIo{yqc;Zqe`VJJ*u^V~2BVrwD!fT}Vp(rg7jl5qrj%B8noH_aI z+JXkWnmxdlMp%{OjNC(ZNgM-qXF;rX?lD`|jg-IxhgHQBdtIjXS%%laXz&SFN?w@< zE+UHFUm*z!0jhmI2B!xi7<<^Ge42x_cWU|^P^NsAh=I!M4vj?40=!I5gPxN*1M2w{ z@8C;UDN|JKMp7sl(EL0h7X{;aP_zkT*X*sxM@|)DegkK36wXG|5xWgkXIp@XI$?N% z3I4zhIj^?CaR)d5ByYX9BDCw#xJ25?#AXXMR16p&ok+)u?Q2N8fCuOis8VI zl$V{OO5>(i2JWOT)%QZnY^WfhT4$}D>g(8SZw&@(BE=xzbUz$M>%>9Fg9Yq3QiWzr zzJ+G1U@77~3fHO=R2wg_s--9;(tC;f_2$qJ_Zv4Th5x3tA;0zN29ysG$PF;lVIHFb zh_DL__!`wHAt;lo*h5mq^+f$(1`N8wL!2^5=3`Aj%?H*ius&R>65FVC9?R1gh32E8 z5VV{a#4dC~Q2>|Q6YRd4P4a8xCK&fSj^5d+0U$ad0Un9 zV_b|ACgZ`KWVY#O7VvUmZuJQ#V#HB$N5Y|E3MCw(C=`Q3(MHrE#77K4b1O>1P|>$i zhN7w!bZ}t3;`E~B0Ge50c7I;o#C;yL3i=&SL_mphpw%LhvhXkZs&QdX-Xn zDtmu(82GXC>+yiGK_wMz6*?IA`Hk#;$*ID;ufw|WRXF}7ePrF@(ql8(reXzvb@t$8 zyUD9|I7z-v5T}t3R~R$B3?k)K>S#m$FgqvnTVT_e54+42@mT{kH%&E}ZIXla^{vp6 zmB3_xXC!JX(L|xP`ct3alb-bqt(0^J^`w8a*`9ZWX*Hkc0se6#l0wjboL5LlXy+xP zWV}l9;lc17||mR(y8iqfUvG3 z5RT+r$E`-@bhfgmx3ZhTI&Ec#(**?icYVVs?;|blaLc6cCmNt}Y6c8gv7%MD@c5e* zBzV@UJ*&r``IRF@oj47woU&GldI*%Z6WNeGf+#Hz)>S>{^LG|ek9n>$0B|aAEM4&q$QGj~Ur zd=P5YlkdbP={f+rtELceA&UC@s!dxW8E8F=XKZ}90LCE9CRAo&<$62tr+pQC@0B!w z`4Yew4*?bnwX8R(piRs1$<9~dWoO^xplMI`cwn_8pSAu=S{Rw=k~9U%j)bS9x^P80R zD;sJ*t6wcck>`s(H3iTgqilHuK$UKx$V=hbC$XcrBE^W* zoghLqcZp$UNHr%e{Hf<*^(Jt-)SB2DQ3R0TFR?6wm2wX=5W$KXRNa6Ilu0X5_UG64 zS3L$2tvIO5CDF~<#FhIl6zol_P`@W&qW;*g1GP91>wY23M6J84upEwuPYeY9&knWT!1jvs{|y;YzF@bfU#4Zd|{1r1E*I6xd6 zwT$z8b__y9DDfA}N3|r>{dxD3Ppz5?hz;!FQApJsl8!l^$k%F7ajejcRsEn)t(_pJ z!N64*WrMBUUr5Brf>zKq#a&g_y=|>)D4o{EJZK`}w7b23t(^h&$F zvOk<4hf%}`FyJVk0FMM@Z7CCV3UUK|f&6XdPuCp!Q#?5i$tUHPM~O{B6cOeAaOuqA znOX1Tm$F0aG}+bfP>9mwZFOeB>|kuL#3*;aXD5Py&v5C z$%_Lt?wsOehYWMYA96lfc0ny3aK{rCo0XD;202_92?cj<?`dP$@bq$1C&l1qQ=7QzkNdG(6t4FcelE4IPe-%3Q%u@~=vS&24ec>(>M zD~zUlU${!t4m4QIS`95jPijQ}Ze~9SU-5Ci*=bafyVBS<19tU3n-~Kq&}rRp#F+P>?6d zvsA+U>aD+Ud4H^b6{1kpIs-p5S&G!mO|(4(wP)Ov5L;}3oWYF7{$EgU)(1;)aD5>s z6ua&PSSaW%z;5k_)a2q2DabBcFCuvax2)_@*~*RJ#pxT7Ng zZou_%Hv=IbRsRBL-#E3*2KD zKQ>*(oy&j_RCr0FcoSA%*p7t8)nQm{wAHDxv8!U@LK!6K=Q0$mcL5d?=80E}kkTuv z>!JOhF#dWpV^!R3;gp0jZ!9ROS5=8BuZnDHtty?^pxDJ+EK1c8DTqc3&K$!}EsR=2 z%feng(HChJ1;=DTiI&A-3>RbzQ8|emn`X_j{pGN%@(T)!d6v^QR{@k`%B)Gx^|6uH zEKxIwysfau!+K{~-q3r2;>q#dQ0im`4plo&@c^Kl*>X-+36V1)cDZP)xh1c>I*Ai8 zy)ih;?cQEq!VhkRfvIfnO@?S0E)4G*J81;4;JOR4(9w?4@ek)XQ5P&9mXlBVEgU;*gB9f zsO!&}+7tYHtI%2HH7(rTJsF8Jz=DEt_e{c z;)&l~C3xm5+kn1Yx^5=A(|QeNE0Y;?e$jwPTC=0ngn_=8DCdc%%z>o*$Xt5enX%<8 zX!&d$6CJN;4p%|#aOq)X8OKT!srm!wnac_8Z`7Ta_!AU=iAJcrRXlg;>Z<{BCc&AX zRs@6<1`4CzFB;e-O$ew1hp%613#+105ER{D_Lo>q{B70v@rN2Mk)QK{X&12YaMJHm zpm5mTR_WF&C})dNzVQM`xYh$n?FWm(0NuO)nA|wb&Ft z@FFe&V>IR32}vK(p!+dZTS2Uug9nVIZ4yvDeK-HS3gdfdK-n5W3G79Z4YpQ zbDY=@ecju9Fow$Kx$VL?*WbXr0?^&Ydi{#K52Nf?Jwkwk`AwB3UYPP(XX0C!(bN*~ z!a5#Ey_zM9;`?EXzXjqNn!o#RLNrIpY3Rc`O+HK>l(qrZ+qH(91sObBETtrA;omip zzU1R!IHL;2pwou0+5gE%orR!!=m9mZk%Dn{FVW07&~|h4 zw(J07_6P4gz@=V56f6EBS~+0LixjUvBVtE7;M zW`n4cx|!Kh&rtRoidF%U zNzYuFZaj$(d){ARz8!k8_Et!|{j188XdWBU1q$vi@i^b!2i(0u5T0PU^F_0;?nSOP z3cvk8d*@M2Aty_2fi2^P!0cXl%*8dYSOFNDS>HnR-FcSp=x8)60DgOD-vuo0yhD?= zR`o3kO{*7A3xl?5Z?wY4F0B0mP03;j5}yWE^h9{)R}EB7rDF>LT02gO1oC4KML58q zklXsfBJN-1I*Z2)8)JZCyuUuKsoVP490!D9=a<3|#?IPr4Tu`>9?!(ldP|PG>z6-p zrprd^e2vt$1SmHL$~w_5*b}eXBb|d`4Ali%G)f0Gkz#X^)Av%C7qKZmj zj9~2>#>aWMi{^6BL0Pt1&BEnoHV1V}wUn|mt_=QCZG?p&uF5H3vjg+h<-9uyPqK(Q z1tj=+(TnaYW(5urV}oLKmBvZ8EY0zEiU~Mv3CH?-PzXXj`%~hZF;)733K)UVI=~#q zE3I>YqK_g@rV;ar+XAhp^uj5ydA_Tmj1DDKbf$LMp-|m=fnh6ivC1uovBuZ$+6{&0 z_8D4ssL)8QgHw$3CPCV{WFyZ1DR8*}?H+~b4sduN2L`yZa%7$R7w*LqX%l4@#r;d7 z)=`VxY4HJGr77YmeBuMoYe5Fmt;=^vgxOz8(+8$rv04_yE-~dK-d6DzVMG^QfGfKg zB@r422$+CTJLw{76$*5xmG1^5nO_~Krxy_CIFMLQKy#!`{)j+w_ zrQpQy%~oMUQ=CL$eC@-5KKZJuw!l^nXU~Aq9aZPRK4{rlWQPF;mU5R2b+6JI`(Yn% z7#aBZJUWz~D3s(PZz#0z(%}K8I29!?+=17!UQmFpTyZz0-N`@^i={#>Gplm13vF43 ztPr>n4fT$VQC?TAh2m`NNRD(q>Q>(+{%z}_b+h>m))@_D44nUfWQefo`3)qpO&EA(Oi&`dKt~@1-vhtq0 zu+7p3LQ3F3AgMhl3Z@{4WJae&-#{4;eY(qz&+;_q>o-;O9Qu>Fsska-2AE`P?>#~o2$tbd#b zqXq}XlAN?l|5eapmx^KBjiw2TZzu{aRe=G&aJ2YvaDUY|3HW&`uS`W1HmZUWRZI=& zR@ZU1lmir4H5W?yW0;x{V6-BJJchTbEKEcCchr~edj76c3ZOs0tM4v&eu_9cVi|DC zw;z*&E#AwfnRu0Cm?gkFWflh5%x+P3(k!(?$b<^kQdWrlNV|RdfO$e~c>eQok!>alBC{w3{MaM`_yM{q=L7gsXjL z_a&MilvN1m9H4iqDcLdReRv1oh|g(Dfa^*9aC3d1&BDnZh!w-hA5kU-Z?PsR&Zgvlt7cb%2-T*h4i7qlO|06TjJr z{>(D6$171Vs<24*G#o~Zx`{1muc*~H#ciU+LA1+>Q2$u{0;;EO$B@Jp%sJf&9);G* zxkW9o_x@EiQtpdF^>?Td5P~DlF|WOZG|82Ofj*roO= zjYR*b2?xYJg(XJP#CY|+pV*t20RZrODR(i(be>hZmruD_Qs-5JA}PuErDF0v>{Yoi zC`-qzK1-GejK<0D(=X}U;YxXqPU5Rfh@699hVP8ZMIqZQ&5tDUgLy$Mjixau7Eoh& z%}r%fM6J`SL`K*Ojl7fzNEsjFr4s_%JTU;CtS~~Rv zO}O7^Pg9iO+O=2$>jO2<(?|?(Y%;DR_%d|eD$>bsm%P{R#SXORgzcqw_1z)dPJ&uF6)QI?sEaZPti-BXCxQ6*u}jh~Q8i|)G)(NW zQ>mY^*2iWI<=X2#u;^lk<@c&3c9A@K-}xkWEG)%ULd>u}t40UA^LCCL9tqJDRLY`p zE{FM|!X0)~_NC&Uu_~)9Fyc6?igvwHy416Gqb}1@%8IDKsi-dcD7<+wrDIyJ%{zr> z>Es1eJs8b^FVjUPUr6ZzuyM_Oyn0=$$?uv7>H!<(YW>^;*lAA+w6rRxvC{~rngJ9c@?BQN2Pl8@OC`}cNBC8u$TwmC zIm_qV2cbvkeIMpCs{lc-U(!<~@J2ldI&hx%36&P2A9jOI&K-=K+tN_GN))}CsjrRh z-cSX1$kdvAFYxyu^Ql^kIz~a9(fQ- z$T0(L+v@FS1(wJJJKcDLkkqxf{^A{V`r%Sqw{-{{WZ{EDakEi-MGA?#Y?v&IfH+iX z1x`@*qm^=Ol=H7Ilsh37J$Qw-9{(#V)a|WeJoov))pAjas>{(na6I)f(ZEGV_KtQo z8|dijDxI3w%09c+&!a$kQbHof8K{yF=j8Xt+k0A2Uxil}^feIoRis2}&eO=;b3YY5 zkY{?r_fS@?!ZKS)P*25eB?UVf`RdyV@W^g>eGyf^Nq(v5Z8H8QhSjFBNSS+^0O`be z*%cB!uWZNTa%R!zC$PH9?hMwKgY-eA=RH25P0a@{)oL~HQlXlim0O0ci)eQZ$-oLz z{fHub;+gm;ypp`5YA&cPPuSTff|==dY$ERC!-rH(%|>fKjc}=^4R@gOi#jXrz#&3`#&#G^~z3Q2~qXOfn}t9Wmua{uxKe1 zDGsGT(c(^VcXxLQP`t&V6iZs5(Be*UcPs7$DPEws7k3XD2+2*q@7#ONeeSux&Y$<$ zWOwJ?*_n5CW_EUGOocIMtYElX@lE)Nh`}ABnx^-z z#jN6*@av})>4Ma%PP*3_92RpG@~ZDX?s(2A(cjQyEeRK5c^oMR@pyR^> zewD~x#m$ty4l0i-^ekhKHj6;7beGUbU~Zt$&*m&5yD7gVFvNAMoX^KJuMXD9cj<^A zSTL3$B%fmBEtly@r<~SlK=rOzu6`;QnKCl-g!5xw&|TQ+)Y}5qC+25V`JS+wZ0u59dURCv81$p z@_z{y-$eQP#euVag5^1NDS-xPGrU~>tcMkPJ&GBd?5~Q4J~1O56jQ%m*>!r+Mn}9WxynSz2G7_6N#gr-6!r{E z*jlMF5JN!;hkD7JlL~1l+bSbjs>6y_Rzx0RNq^Fbt9vUlW-P@!w`0C zIwTn;S5#0*{+@@{LTSP2L!Fd5yq)x0gg3Iz7JDE%55u5~9;})>h`It`t}<>c6!e)b zpCYc-Dq+DKj(QPKZqZE_A*U^k7GIa}iCxR(;O4SaeAwV(fh}uGjg;a#M()`NjBycn z1*T_0ghp&P#^ys`zA{Wa%lIPdhq-np&VmZQ$s(J^G>8Q=cfClpew#oM<;%7H)J`rJ z%ciW;g7y!OC-a9ggz}`CNoXa8J?xr{0Rb)aLp~@*cCHZ4XUpQ5fyHsH#tMKLT|csK z;led>QS7|Myu2c$qD#?DSIWB5=BYM zBF74ho@wQU#!9A@kx-!#b{Ph}Q+Vmq&PH3^mxuB^t;Q&->yTY?dbabk6yEqUd0ZVGIQ6R^3eh7cVm%l7Ale?I&kA(?7KZS+*ol|H@@ zu6@ff`gDX>87kBelC)%?CF4SVDdo?$;TNZ@t=Z+zdvq5?&kRU{XUs^)-3d={E01~z zD;{0HIyKzNexId{`_n`74S;VbyAMQ`M54rxqwDRPml!LPKASKriaxBS#{5mrj+6Ce znuN$AowV?PtolLk1liqG1>|}Vb3xyuM2Gpq=VJ0quYpsyVw6jVi4S*T>~t>1brJSQ z%Ma{d#WVNG1nlb)bjOP-6@Lr_VhO)*k#Vn+!1zR2-YaTFbJ%YDCn$V-M;OT zXR~@~aM7b9Qk=2*1$>ftsN~mwQ#jiJ-T|5(}JQ?U_|#ZCLt6`JVlVK1#om zPM+5pE+t-3FzJrxd9zH}y*O%8ie3NNjX)Yav zF-epwA3*Pe9<7U69nmJRacGUb^Aoh+B90b$x#g>wwr^yXVGrBhcRH{-=R0DqFQsNY z@NZ6A(rxyExRsBM^CmElb|jthGWmOdf$yI9yr^!{q__q!bJz7oxQ&m0WIqewJaMN?L89S@@)zfuxlVrX$&BcKb< zS6^z2Q`n@Krr(V%MPTmxnoa7dx9ESXk}J_Q(}^Nn=+;*n&GviIb$v~r0@jO`tB`8U z%a%uDq*D~f8o&E_w;yi93>TIC?$zq*8*kJKt{Rdd$2YMNQL!6gDcPhdl`H7uYtbAQ#~)59G}%R(niYk-{@P4|^@R!vf)@{^zydLQ9$;kP5a(>P=#(S8fVn@XE(BS?!vsS@;xp&DF$1D1>UAS&>y+E z+h+R!z*h_)qwbd>1Vc}L8W%WoCjOe}`8+4|Y#wL)<+G~2AKNi0flGEbx`#D39rSFw zx1~)IJ~dsDEK9|QualK$>fWEsPYLNX7mhzyd`Zwzpen0-R+5iA_~t=GU~Up?<0%*? zE{INeilya}nHCsefa=m;BHv?5vSkr@o+yohuKPRooZ{!S;^cPj8I%6Zfr(5dtT@N> z>11uPbi%9%kME6sk+zA4S<}&*gODD9`N^C{Re`WcJH9B+#y4$rK_L_+TeAgZKL>Y= z3mwyv5)I%73yI}nJ_RS^n9R5c8+I|u z6g7G_z+>Z+zwD72&AHv`QNGzw`tiy9vDMdDxriNB??)5{FNIe0)IzEsaE~|Aps~;9 zQfP=$Vp1-d7>n?a1(=RUBLTBh)IOX3EHx&3&Lz?fvqn6>Q2U46>DWZrPJ!i$r=@(~ z=|9fZHtUoNt@Tj#)~l|Zj-?*Pd|`3>3Qgl2v<=VL3Gw&hjL?F;7bHPlGT&j)Dfrdua3F!42sX^RHVm?v_7U+jE6xL~9JI z?o~lPUqlC|zKnVgL)>PwSKZWYLNTn7dDNnVQErv_NW9Vnu9v^&R5Nx&%M6yhr)~*0)1f$=gA^}cmGUq55FMvfuEVPIlRWfy z1I6D%Ye(ITJXaQ;l29-e1iZJU@Qa~S6Ibtl#{fw&1%%LZJytK+{P=F#t>JUoVSEuv zGtX96lJCcs!C`I8n2ah@_SmHA^!tGXJhho^xMRi09n05DdL!J%BKiqR6%O#+78&nZ zC7!vm4H)Ij82gs5>_4vfei(Vz&T#*%%wonOS||SyQ5M=ue%})k(!d?io?Z-f+jykC zZ|HkQoL^j8-0V?nD9pEVL+kw(Wsj!L9@8}? z?jP_rtDf63&mNc#I~urb08I*7>UVr+SFQ%Qf_VKclCoA3OFhTyWtJ_l`7&Y>2HB&; zTCv4T2jbYrPVKZ5G{QUI(0B$s*$~$x*wOYW_rP3T=4#$tUnl1l8^Ggyp-kGTPqzCj zooXvn181@eSe)=- z!8@@;8%IZO2zc!Hw3^78OEbJEv*Yo)SqgDSgMh3dnh^(5@KnSs_;CUu3Wu!0PHGU- zYw$>zbxI11+6+89JecLwD+PKy0kuj&!SH+hAcqOiL$egTU91c-gmXU+75V(aClv_n zLLA}U1Sw2ifp&6IotpaZ5bbbK-Vu0H2@%oE6g~XG7&xrdaEs_QvLo8xxdFrQ5s>+d zAlxBAIOGg|2wj0gCT^j#1??G#9WeYz${ctw-;5YVz_JlEpvUl0y!pG8+lh*pYC-`7 z1O&ey)EY!Q);zTD1U25{)T-`M1Nsi$aoR!Db2np*^?YlA^@WA(<#vof$8ci`#6(Phm#r6(nQ^^j zzYto3hK~NOo_d>*iL=Jq2UHG~(i+ZRn8;j*G9X1)rb#)zb9uVRxxlaNFavcUQ?G71 z&0+v=Bs#sIdTE7tPH`*WkG<_7D8lm-G6^d@A&8W}(^i<%)0qu?}p6;F|>1Owd zGi5`gCyK=TeqUzA-*v2c8@o(Hy61qi{z(hi`l?x^`hD8BJ-)=4dOVJH=lwNqh2rT zEG&t~cD^3zDlp4vdu}(aB7b4|`*+>sZsfEgp0Rjig08-%-|ak^<DO+6KOk z!-N{#3)?>4J2 zLy=2)55b=NojAW~8{gIHs z|H{|ps(ZYE&NghiJ&faJNN{2L}Ybl zVv5UkiKtJ)PlDD4SoAUKcV( zKY7UKWx9!>+kvwPy3BqROlNb*vM#zYW4sPn^2_8TDw@7XZF!RE?x_-zEi?@l@SSO# zAJ#6WOpyL6Vk3evbUC-s#Dw<@Kti~(M+Bl z1r8H&kc4V7B#tN6bZcShE>t&^7duLS(R`9Bgd*_-xZQY7CV|83Kp$__+a8-+C&*Z| z5*F%G>PP`(`lLZ8GEd$SJCE9ZC8tOaOhjl6g1_g2z~BdNe4Hxy-n`$A%;YHA_vyOD#Cp#JPh(Koo_#O zTHjQ=%WS=@`1S4r(oR~R?5-8-$dmV`_+{m*a{!u-49>WbyO%C8yzKcnxO#SF(f*r7 z^I5Q&W$5H$QS0llkj|vn6o~L9!Ra|c?75{yLyK1r-i4?r*v%KHxZ*n7ihOUs#ci4A zbG_3b6+dcarRS$!{P}|N%tOBLdl-S-d~(ai?_mnMrHX~>!-&nOVw68$%fFi~rOk7e zO6eBS(XO0L#xogcyyll7EDBys@U;|yR#PQSM&dVRB}(Jm_`Q5V69Fi6`A zUEH^D4A}HPoSviGByKA!9^%!&_@-OWXA94s4yS6OcHxu;qN-E;`}9sc+AeuuspQqbssB{ z6J8S2y5i#b_rlSz%F;LMJ9O-#=*l8Nn926SglC+;WW@Yl&9c#AsRt4~ruaN7ecv}T zk)^*d7+ga#@xdb!Lpo0KGD6Lx3y;K+%^OpFZHn+ERhW*>um;Om{ii4Hc8=G%r?siG z^Vt0g_NR=h0%s1vCMiFwr4P1jlM{FSn9??Q<3J4!-+AAzeEH>Q_;IKKl9u-(h?m50 zvZ`7sUGvLNZSM@aA2zxP1$`nOfCMY%rDyc?ud&|wW`@w0tZi|iXcIE&^t7fDh_(N$ zMYC5`WZ|R@AHk8gS-2))4z8-_)u$1!b>aRvNFi9$n>Y1)ja_jXR~b5@V@u(=vAj`= z;WC$Ja%6Y6_-#`%r*-q^QW&Z(VJvnoOZRACnBn*VBTVe#vHTZVm+>iSPsKWIMyZB~ z_3v7Mn=IbQd6j8m)fKlnFqwEy%GV6|?XeK@bCwFQKewPC%RnNb`}&}H-r2Y%aDj_k z&))gh0yW-IZq4#T+pyjVy~)rQi$9p{E#gw&ZIbc}ja)MpOl&%prcBs@lrIMD-WE@$ zW{z6m)_yI1_=!<0ob58h8v|@b|4JbLXQ8rUGez1IL5>4TI6e4QIc7-yLP3~<{Sfne< zTGtkh#Oo4)9)3FYG;x_HOvK#ggGE>xY~%|-3UvmG%1>{kia zBO?P!_|2;@@$H)0-|iFA4f4d-2YdSu2Kt5M*}g+Wk#2iD;WeKa9z{$Jo zW+L(-mzzHL9HoYHZ3ZWkd*rDG1WJ7j8)ClVpI!az?GeiS$?+z2Arlax0pT|9sAn+~ zOY-h?B#RF0=VSD-w1~>S&7OB&d4_9h`98&5lFVMCI;R9m>BYSK!czyga6NV0Q|GL$ zjBBW{`y3}UL_Jts=UW~*zIe!sU$w2c@}BrNh|->}8)&MgWtwkmVADtO@rk=Y2nWeS zpEUvbTW_UWF1HWMBo48SnD?xQ*j*v$TyiNezld>L1NS?KP%e*1Q$^hrkNNz@47$|3 z@g$iztX~nl-PBxG+T=}RR3{=ht|5ysOo(fF(HUQ^`AyMiV0@Lzjfk>J@ny{jkx&I` z%+554!vWclN!$$=G+lu6P)T?OlznJc{_U zw@2VIf^Y76)9^8yaWeAr%e!aXcX`!-YB=_)z8vfSoAr!e@V}%5lXH9T=Bejy{nn0K z-tL3bTRUAP+5eM-5&!%@dj73z_81$jR2*@t+p5PTpSHcAj!>F79rwcCOyE z!rcFn$4f*=kpI7=@jA)!4SZqur@O@UjIlE=^o1<86~-vmp9)X5VA|}Gy(7P|0_8?p zW9feX@cpu{&x-u+f}f^{En#5=KXb|}if_xvK5?<%3$kbCP?NP`;mtTcdr*=T= zW(>@^&)Dk`iRpXt_hnHd{iASI!C z<}KQ;8r8P1SiqCH(bm=`P5XPS&qp+?$7-JmWr)V$6KvD{55!lx%1~*(sY^3$d{Z9NMi?V%YfgB|AZSilEoA8?HMc%!8*B(#f zb4>DFL0Cfd+f+e&9ISMgG;F6Aq9lkxQ0m5wgO)1^3JeSs?h_CYDE%F;%)sJN2-_ca zZKgnl22jv~g|A*hb;h{GDYwr8{sL#;o_FL&!k~`H{*?Ym3j#ddCJk5PmePI28Zn~~ z1g9RMfu7fo#A*r(3bvVZg;~Fe12?1mgR4-QdKUAJqE0q zr(l)xq)x`%7zV|GeUYvE7*nKHgr%6F25bhpx(V)e0nkZQ9U7T3eMR`x_$QdovmtIg ziBy`|B4s$<@VFeXkl#6H)Rvb4oO?Pk5^Jjn3D0=!E$uPcQL=k}s1b_swC(A?EYxxZ zG2?hy$UlT1iURG=n;)h*75)SZLPs*GKbI6Qjn9MF3XmFtogD&`CPV(ol>$??&(b6X zDw~;6w9RzF_H`Hb?(hA#{fr>=Mc4j8!XC(34lk380~;Yp+Si{zBX-FM*r-{IhV2t+ zOmAEcSzg6eZ%ZBZ$-pI1{~5LvWVY>1JjAz{0y>f2MFAB_?#J15WkvNpTiMYZkb=t$7(Gx6M67>SKE+!7ZF%3?THbXK_pujVRjtpYa$ z?!3x<_gVZ{T!t2H7YyrWe1fEO^|o)TxiWl+k5=j&`!AtH zhG{I-*q1QTLo_rr_S=8+yYRmP2`18l^#2mw2vTrqStA6&QP7DGfLu9C!%LC;g0WCa zOhAQ%E)A6SM&kVhiZY2L2Ff;uJO;8hj^@9q%wvZ-rBh4zHyBosu)lrkX z+s}PH+-P%o7UZO);oFFSX(=_z9a6E;ZV@D>blcqrGh_TplMK4QIa%(5&}#^Dv80X` zsKPJaf;#u(F+7eb@54yucGon6rtItc$&*z)AVX@eqU~=oP24^T8hzya-=L(aiv!<$ z?{Hh|y7yeS=0PnGYuoKoc++j|cp2iR?{o+M)hQW>Jtn7Kh zncYS=-~l#LKW)@*X`s%~4>RT@l6?I41g+iAL^2sZwsT~|iYNr8i#4K|pl+u8odqzN z7+kdU5E+V?QC86yI)->7KWNFAuV_|1)AXYchE8O0zUA&syoV^*gkt?opusp>Fnsxui67K+jS9UmWt&r4 zMT{Z%_f5fc$<8i!W%#prNUF)UCA!wk1Fmye-`6;pC{Nc*cXV1X<~bx40ud5%Ok+?c z&P>`J9H{ClO#&@FT0`T9CHGz`tXB+ecB|ph>EFiN20Q|+T^>)aO3XF)qS}iV@8$Mi zhKE1@A$%XBN*+m6`Ky)C8SaQ=_0Js5@A8YrPd;FLm;UM0(ZK3-4SLFFuO7<{=9XX*P_BLIbE!h&-pUj>#+i0Bn z@bpP4P8pUI`krTN2*<3HopXSW1Y1RXHj32;p4F+!GTuUez^IP=FeLhj%+H9G=PRoc8N=0!L}^Y{ry_q$@7rgMK|IKD67Gwsob zb)N2@cWVBD>Pc-)UqBx*W~n zLA-RB5uD0MNA9o7ddfY#yYIQ!gGHXEuV0UUg;zOBL!>6~?@0C`)6k6|pfUZ`lQMn( zYXKu}BYyq24jj7Azdjw}ev0~LHpF-dUkYZ`XiPuwaQ=378%_)t@!CbQQQ|mfFa9j7 z9^ekq3rfiRtqG(2JCuLe~~}<~g(d@kgv<-TKuyt8T}FCU-m)6z^ICZS#8^=AH{6 zGzhkd|IQ0R%Gwb#S<2ZpcAncLlho)Bm2X(wvte!Ls&0~S!${Ap*=H0KYS%Fy0)apV2I?zkQ7`{l zlb=pXO~h`=55X=?)(9VCO&k3+Hmb9-xIh0}+bIkG{oH(y8&RFLhCE*gQ6fQpy`ej6 zZ9eaiN=LnU-gkk$i_o9)g!QB&Sc=xi&{c{Q0BdTwfdkGlIZl|7Wf0V7dC=~(JThKm zJs8QoR&fj$*0ZJ26hbLU$=Se)*giIn&xii@HmE_6Z)^X>~0S=v5VDuAIp0Zg1m=A7MDo52&U#uM+OSAos_ zl~evG=rtzfjEfCt;*zF9=Z>6ic6+vh3@_ZSBmWuliw^Yz>eo}(=zR=C(|C5N2kqy~ zcgRM_?sFi%iGG<@v+WOPRAoYP4D{Uc>p3wEvPUmOXvwKPd}hd`o~ip<1nTfd!+{>k zQ`y5LGX{(fo@9k)1sd+gd|voh7O5*8g_hf-;JTYX$hW;Iw{#jcg+E&qN`L&){^5_O zOYaX3A;bvy-1W)fsCzxmM@+EB=Fh)EwZMWo2I{NRe+PO8sh*K^i(2?Bq748SeM%jf1U?Yk22}TRzM{;_% zLh9PlwJHNq@OmEv29&y|#6;7^$iQ@|iX0D>3dceZ*%!Y*Vd1&|h8HABqmr;sU|~mw zZqYC6p`=@uw7>YW^Qkp-vXjc_OdvzjvK2x@3-bO8mK9p!y4-Z#yW?Q;;qm_3&(ALe z1HZbunu~*jQpj~B6#(?>Cow84F3zvW5OSlI3>3bn?CRfef4|n%SzAkJl9iQZp{@Pn z?I51_*NCXe0;K}JfZNl@n`JkFSGXF}ZwF%p$i}VR;WMAsgp6<}No{KbMf%QUBI4y8 zSK;h6#?|l3dIBXtwErkI-Lxv30D}TSmnD5u-BgH%!njZJ711-nuoju+;t%+5M* zEw}w#T~EIf(*FrKlPL5sG<=zW*ou|vx>F~N%+c>wWJ6h<^SNQ$QNJdW1s;VlD zlIgr)R1z9|$vax-gqGFQ47VsU>TCOzy7zCVg1T?!^sHtH)3$J)h zNR(d3Y%2+Xz`#ee+4wzcsF|7BTF|Y9ZOgFj;dy3$ettqi!owMurV;zS;PQ8#x7vO3 zMY>rzunpRrL|oph=|ZehYw{XLq^|b)Tvf7)>s~pTj=d)_cTa4AlxSPe+`I$HPTz=` zExpDBl<(|DQ}P5mOsf<@YvtwT52x+;Wv%1ypA@xaY1WJd}{HqKQ&_nbXRHhvosG^vr1J1Ys zQ!v+W^|F=6DAq_;C)myr^>H4wmm=k)@Ug@!QGD?I;}PQOC<^{0Me%b%TR7xg^(@@p zkJG0sG8BarA1O}J)e@=a%-gLW9T)>c*UIWCfm1}KF1Ggr?42+h>O{FnKlgZyq`qaGV-9W*3srNx9{?ZET_j!!dlP>GxR%0BFNHMZhcZy3$9IeGkMRm|aPh$5B0 zQ}{dh(A10a_epg!D;s&}C1N_4;0ewx#$mkvn}Qm0E6l`!8oj!G(8>s9DYW1zazu3W zFjEWtOhK!;yNB;Eg)i-{h-5#j^hiKo1R0|TSs#4x)>s{)F(sS&&fX=h1St+ z@X@S?Uvl593j?Qk_D{w}4yGqWdb!JmC6>7J7>S&=H47CBHcpz?OqT97)36mE`u_@e z6#d>1h>ls)`zmoiUQb+bf~uBAme=WuSLAu5pj9@w87W{t5o`!m>4nk^XkBM%g#wVq z+3m}}GCrO*XFT;^tL!sbJfO#IhBdOo_6?b3&`I+AvSGJk)+BOxPx~4}sK)~D(j2lm z+1Q?sPF$!R`6)-7Qb0&aPTLTMvvEnUV)`MoR?9`@=z5#Y)EkjX+RU-@6v)dEP#Uaj9G%v!({m%2IdkO|{E zEB2Bl1kMTSZ@pCpCTA+p7|Oi=XN7sf4PvF)*uy3OhQ+CwM654A8Uohh!S3_p?-Uuf zixcCIl2nSO*lRkRziis#?h*;aKEX#K{`k0HOJQF-)0!ENx6XLo#vPeiZ$G||3JEX1 z$2|Te07iPO2HB0e{=k^juN6>{_~Oiy{2I%CT-b^|f!RB3>jS#alBaCf$WFrj;QN2c zMV7XA7KrtaH-hjh6;!P9F>)JF|8hI_FF`QfW?FrY$SHjCV}lgoy;*Cv4*QFO;#@@WlFhZ)y9~-^aGcpXOCxQmE zOY^(U?HlKw(B21>~pn=)$Rr{(M(1`qo!D5ITlm z43FPGr3I7Oie@nDQ`@FJ0kgl13BNt6taAWAFg_~h7rq`fH2ro5yzj8?I3A&Y4-Jg zJBJ2{Pi0;Ee@(kloWATAAC5)5%JGl9E@4!kXmkGhB|a};K@Oh$D}V#=V&U6xXhNG8}Ir9#>n-Dk5#reB?bH958+WD1_T z5rE$L%`rfm&a%<=+VwfwKWpDU?zvf9B7;&Qne$D}NZShC{MRfE+Db@80rlprw_ie@^44J`^`L`#}@2e0Tdr_BX%JEJ2lJKR|X5FB!^qq*+6%KD|9F z*C0xQApaIv`YX0NELm`W+Xz=zmjS_&n#!`|c6tA_ghtG`!00k3gwoKQTG(Vu*sG_y z9`#@2B{LEBLIHm9Vev;HeQ)qbOODfIT$SX;s@~}Ry_^9jMFyG|)q?j^miMVk_HIJr zJet@07Guv>g1;oZ6v7GILWpxLTQU!(&BSWG*Cm1(;L(4`;V_0aX4ye)o;}u(c_lkd zk@SE39f|k&-D8;4iII7k-s_j*>{gOJfkA4#=>amN^>*v zN~*8HX#K)|Y>W74`}><4#p9|joBq_29k5-J6YNKj`R{N%lirrAqm_apjoxSvrdi^| zSKG$82;--#AE6Hv%PrIk`2R64;V_Y~K2A+tdIzj;Wg#%VQ{7@#{M?(?L9NZY?bNxf z*N9_}m*D2lOd+N7Ru{O@Nm4zPX+9;hC+~BW@dm%@F8?3_WTqhI-f1BCtfU6-J5Y4X zrn(v#nRVeJTNJA?{?Wlc(EaCw+HqhZq#fVwH=!Bwfzk8f`-!8pXQ)Q$0Xr%{ z7*O_iX1|ep;GsFx=RHhu;9I0KQ`#6_mGx)u42K(GkwE#lF{0>{ImfL>27rrS;y{_p zliu@)+Jv+i=A4fp4knVoT?13)I&XStPg7~3K@LM8hoE=wh*jL#$bCC}?jpF~$3tRA z#NYeYQiczbC!d`N>%p-!TsWgeN&3)+r<#Iqg_>@(;R5gGgJC*(Ccr%p{gC9XefjzDxM530(?d5|W`mp52JKi zT0CFA*K^w}Bf0zDpg~leiG2;#;%z?T)H)g_HL959b5IAEU%vWRrTerE^8fv|>j}lN zjLUGX`Y_0$A^W45FoRuL>(+V+H^5R7uF}cC#;mh&OSurCxbdnq6E56VQGKh~Qq{wY z;;^MfN&gFblgOu7HsfUst!!9;X{=RV*poVd6Sbn+ixSr>F$#S5sQO3Wa=xUctMNP~ z3!Ot2-}>zAVss#nH1Nq+o&Wy>>B;A!Pv#$QBh%78uDqiB!tYXOE!_=hEV(XiCf#YD zK!E_9e?`Fi8ek8%nt;{MO8c@Nr;D9SukbbaxJ(>?xtlq3YHFIkb-&dHlmzuFyl!W?LO{+ zXnsGVMKC@aBmq(1%~bhI_J;R8RhXse`rsMx(E_iC!R2(_@7Z(Q7;Bv6hV7y0wFaO1 z3{J@ferx!rZ_mYBTCZxGkJtjTajOpR=flKpnacE-g;TKg7x4r2+iY^$p{X|@$B`rl zS%}mJ_t!(*bpO2U+AB=lD@!nY%NU3G?#AMBH1oeI z;~YzI%`Q&e6OR)a4sCp_*epPG4Vb9Un}*+C_u!Mccl4O85}l7aS>*p>>A6T4z}2Ec zq)Ob49wG%27V=e$9H7Vv**Fi=srtnbT z!fF-boWSZWPyb+;{|dOy`y%Y#Ghs#|PRgxPu;=v8!%$BVF0hMPc2hS?KQ({fA^!l~ zSEH(V@})Z#KAlIJVZNX;vF<)FkAp&$%WPUuNV;93xn5=6%OHCT>J*UA;wZ%tJ3|As2gM6mB$zA| zB#2mGZlYz*+jP^);1>jbPuZTw!|{Bd(G00iqzPKo@3q<%7`}zGp7;xVtCP>=LM6VU zbX|cPLfibA;)p@Ze2c#A78oPOkM0_xgEQin)0Y|vzof3gpwg+Ru3(|x#+!EGj=C^f z@WNk=ry)W?k7*XX0+)(&MmIA(dl3@Z@du!+44_5*+li_4rNPUAoCL7ld$7|j^Nt@` zNyxQ|vPOr#k_{Z!t|n01_jhIcVbSO5I2aA=YTLhLCuW5iK_*4^E#moCML>qGjjTf0 zJfL;|cm0FK_|W?Xp$DvvKYFv2=Vgq$3}xfHA~!eRK)`oyKi>?yq)pQ(Q_H+nkE|K) zLC58-4@>$OND_(94WHb}PLg=w@=A&H5GDsl&E<1g%j~5SbAzVbImE12@{fmk;X$;; z!^_(a87Y(&0&R$yjB8ezBz8Aq8KJ4Vk_1#}4Dv6|3z4WLKXvYI1!y{S41Veq4=?Ju&Xxqo0Bcd8+^q2sDZi`f z_RE}(zJ;1{pChrxS+7eP?H@jo_)=z!6}WNz zJrtthkPIHaIU&YKnXxv{Ns{28Q~`}ORd5u&1T zXBg)6s<-p7JGfC0NJ5*bnkHo1W59NzHFryz^m26(bSU8w!a6?x()~{47p=hPxAioL zP{(~=hb$O%)s#R8XnD%OI)8t!b=lmeo%57kISs-;MDq^O+^gN9{JL;)6$&vH;9q=F}GT z8>u1aM`hUsRHk0n(KBbK0G#UP>t&n(4}#3Ku*6B7Whr}cP#Sp@(#oM(m;670~Q?{Ou-jH8c2`_J;Q6w-ND zrAJZKA1V5=eTARm<9<9Ae2Y$cHP^2i6@v$fmwG&rWLcJ7N>( zRP<9#&{x`gZv>f6xPpez&{WSnm;|I1s3NzR0G|i2;sD;rPxg5NXm`D&dVU~PAgFPD zUr9LzJ|ISl_r36ED?M%whwz1nvjQ{Oz@r2xAu|<`c2YHF#Qb>5eIVqh@@j9(-J%Kz zHmP1Us`vNkCpATWaL=H(+;_j6S~>TyWZ-_`DbFF?uj<|~AR>=UHRVTY3|7x?^YGI& zId{V^+Ff~E{**`09(6ei?{5i*@ZRE^;9HidB&-*@H!kYks6a86P1!?Q0=*B<5JEnM z>A7#BE^9T#`qB%_C3eobbldsp;WuA`VN&C3R0%YLL*~;9N_D5oNi4E}9{Ahkc*@ls zNVg8=83}0|f=F)rRW+A(8oSFwSG_^roTP%Y(m=Fo?vD_SFG>=EQL%|CEt03IB)c5% z7Yu05iCg$}(gf5~Ir{<`oBHrp_{~#w-aQbmYW^+;^jj44ueMhyG)6I-@C6of6^sQP zgEjhrIEiuTIu}CUF%f^ldQ}nRdOlBD<32Nn#{~(BjtQe?UCVn7Lv~ID8hyi7 zmzqb-V?8(Bc9aEC5e;88yeq{B(;d1|16Tbh_gqNR|Pw-!GJUp~~BL5bJg^{st|M3}^K^`ID{}Kjw+&Nb5+MZB6yJp0bu}8bZA=ZnxtPxk@{az6|QgK(=LHPIx#K0uOva)3xM_aE1aN5oaLyg&W)h^f(QM zO?K@y>}*MzR^8g&#&*8FzPz45Tn!2$#z7Rz503{qp!ZU1yANNy>|32R_w#X z-YEFw-2*Hp&nWBR>O=FL>-}R);GeY`U&#sR#pyKvy(qj>pgl3C?&j{4Ga~?WR@1n9 zOT7p=OYA(`E=C7D;B{?QtA6MLcz4Z-uRU&8oYJIp?%m_z3eG&h`LH)&9|O-4*IaOd zK&zgP^_fGj)|A#}>6zwK$^hm4|2i>TMSAa+~4vUk2_P+v`dB~7*1R}KCM88rz7 z!o>g~fk=F=1C8Yz55IWM+TqodA(hqH%jM(Q3~qI<4eS6-=;@U5%h6{Vx|6+%6oCM( zm=WCYj|uBB*?rOvK7h5>x#hEM`qZNYtEr`(L)g#Nvyrp*clj5svK;{;uW2G=5-uDB zJ>$(Zq(s;P{`CC3;j=%r3Q+SgqM)0w(Ks&0SYkjStYGX2D!!SL2T^VuOc)@Jh5MTFmQ1uA(}zYM6Vmr^>!l30e=Xmb|hES7(xpl@E2pjGjJJB7H7~ z-mx+D7F*6j+}uvzVZTS80}%KYcehgTM-U_&O%oC|w|+S2<*;}eQvI}*K?vHvbV9VH zgy@dmV{14tEoHT_c(W&(x2yOHY$tAXoa@}&22izqAV^GY`c3p%eYLcny>jmao4jbZ zy;rpHouh@$^d7HGM{-C0W5iXKciqDX&D!hqcM=i9x_NbyzBZl11lsJbqffvK^$q(j&&Hl2g(T{SxjH_s{ApxbQ3Onn_s8 z{ucl%K-9l4+chci+s>W3Y@9>iw-1dohGu&C&}s4hE4lU5_0*RH%gB$rt@cK#Z^~!h z^-jr%D{-dgI+IhcbjsDx3}!x^*T~2jL`s_5GWA{huDP4&;kJ{DujE_mtF24%dViwt z?6elEHT9kqnqNvF34PW}bI-TbdNHT1)w~-SJ@ZxT z<@v$4eRw)FztOdOu3brGIOv-_N6yVzkGrmmF-;1z`VHnIE9$m}zG`-@$Kd^!gjiW= z<=bXu$I=^RfT(5CF!T(K8m!JR)^#!i)^W3{Eh)e+=Pq<|+CIs6m{cy4LSizT_j}R| zl7?AYq?5l{lXX9rK9(4IN~u^`&M8E@)X_1c8B#~1#KBdvX?&gNJiV{!pWhA)td2}w z(nse?O3cwN-8C?>7bZ|o({*E;UhZ$F1k{uQ{at|l{g40kii0K5xx__Rq@}?pJKWR6 z5c_N5-QfQeqL(|ZxTA^2V>dlblOuVRz8#)R!%BUxNKH-((M10TpWA5C$l?V$fci!xth+&-J7e=^=xV2w5&A4 zJLPj%up{m@>~C8p&D6WZr87O(Zb#ZAj|18z%_aal>NzB_HtwdhOSbZI~` zV|D$q(^I12wwiiQ*D7`GeILmU9qXcZB*g0C!Y=dmz99ub?_Il{?h<{wzqy`#+BE8P z`if4{Ba_VNP4agw-r1!a*6w;sXBX4;Q(qIMr0sF3sEeM*Hr4?7vPU4_`q28Nxz_b9 z`PQ_0)k;%hTJ>~MW4gD&m*vy7)U!)2r4>B+GVQ|NlEm3>J2IQMt;ZQ6r;#3sv|RAC zN!IPDdB=EtwR@?v^(=c%=Xd*k12PjDNT0z!dNqAWlg8Co_?y9D=8ir*=y5yZzq9qs zKKex#fM}o{=GvF!>v8n|e0ob7ChdXXyUIE!T|Ver+K6#G8W7ISx8&ScuNf2{r(?T4 zM+sJ=?1)&b$9eqT*d652;;XhZ(|mGpVejq?+GxtI)j2Ym?jFnLxh?izb2)OdZ;LSx z)G(ysevLY1_3W+H>2tkZ&v!(yug>=;-#NRLeK-4I(Bs+a+l#KOX{3}gx34L7pumV) z6A9(a!MgPNHA-`arUjLyc(P@1Q*ok61dO!db0lbcVWF5IL)NZwjd9mu-1FYDXe~)h zzRkQLL5D{2Ph95y4aKzndg{A&K3Q1L`h_TPy>&G|nwgx)+tO~OwsdAa(SMtHcI?c2 zTMw<&$R)Zhq{rCx?uMM7tQ6J~PSEf2HTCA*q0L$)1Ej=VShR=!0sZ!noD{VdO<;M- zgGu^XZ)eq#oZPJ}q@=aMm`Mfc?mxdvt;LEXYfLgEE$pN&tugv5N0l~fydMoF3qTaR zSs(i)(TA60M%SjVnC}lX!;pn|T^(8<`aRDKk%rNZK4BwbIeA0=N{)%%FQfFx__(dk z-`R5@hMv=sY%o}*1=;^>$1Ng**5e(+!uwMZtJwCBAms0nSY}u`$VC6uW_87o8O7(UAB#43#`D|A4k=s$;&3YyAcS;UMn!iV>0ceSUID~ zxyDlpEyZQ+>xMz4L@W#uIH4=dqy1(O^O-K9D}80MeXeXEFj_Am9dfran4&qLVihOR z{D^xL4NBWf&Aaw9_lv*#()ujIkP?2`K7sJl9_7wU_$^UIe?}O_!;#*(Eh&*BMShw6 z@T~SB6`7vK6AVEs1xiN0vo%UIF1gxw+%JjK%{wJ*p!F6tgJme_%~QRhrHDGr^eJF5 z`N+`B!VJ#0`(fT%W8R+i|I z*?$d2Y3t)M6%`C zI`qw5o=rMOeV1lyrupU3OSbgsE;)2t^Ve*h_TgLldwN?*niIz^`$`D?dfIubY-9Ht zXTSMwz11ZkJwoH6dwu8cqO;k)S=)Jd7W!SSo?N@zdaJNl6%>Ta8=MX8@8aUydaICb zRn8#AM@(j}xwwASD+1(lHSeB?*nGkaC=;I$=JQ55lfmNxFnnbMM5(udJnMFGP!Qh72&ch}y_t#K*vVpt|2S3$wY|Ibw zAL_9UXjY0m=LS8M&%*a6C2D1~YrgTmDzq<}RvXIP*!PjYBi^}XTV&6JNSC8?Td1y( zmoysw#%e`VZSmW!Rc#wjHE7{u#&|P0@@l_|55|^!dJ z?e&$Ju|41oS(AGx66uq1Mwv%G%m1G6lzg8<3(sg;tt$pn8XCD)3b^HW>nCwVwF`LZZKz0S@@nm*sO6UYczdMZDG=s3`iRCye zFaVZhyDYHsqq6V8EF7KIXGK054yEVf!r6D`23&TNis=LfQ}j%t>V5XI#EXQd48L(? z*7RwHZaw*TpjRalrs55$gYOfEVRd$UTN9O8LGCwao=rO9_b z#Y$#FW?B9f485cJV|{&v!cs@)vV9ORIL~Sw&+3tdGziHb)a{UblF%^vB8p8cJPva= z#OXQsIwis<7H|4Kccj_yKVYbQ<|q`{{b21Va(-LEmv`Qxz}bni8i!)#cLW9GhK85g z%$DTY?5zmXb!K&U_DJZVV!J=ptY`iV6dlyg^kdVMSV_GzqayiBQQhnxg}X#jeUx(6 zjPhyr&Fm3=S<1QIiqe%doaxC10$b0@Do+Kiwm%WA`IRV9tH$IzN6k(wpE1qsxtYyc z@4KA#=IPY?*Lg-q@d1o6y@_{q;B#3c4?iYH7=7wg_{tgaSRTF%EGA899yS8KpJ(x# z)?Li#*fLhqEo{qvx=$QwrQ?;JM;N~(ML3c}zR7JdB6=ni0G=E#sqd8R&>6q_E?W8} zvZ0Qbdkkct*09IqizOlNGptl)yr`$XLe_7LmbQ~*aHfPL!EO$9?-wd2dpJFqhd3LH zJj;IBo4HQ($2pQ@2!Q(zx#`o8RqwRw$~%2YxJGJ7M51t0R6cthEZ=t8-y-h`)8|v- zAydZM?32Bcbemn~P@hF;F_|r+%p%{Zi0Va&f($A@H8yH#e73=R4gIq z`t>_iDdsdy%*VmqpUlXR-}&2OizcgnYU5^q5&0?WD!G z)F+5(Qv@kqbX!jlD>O8_)aRY?pl|JpD8I|yl6Wt{k%GU&-U!zze{lBx6hW7U?QJ56 z7hkEh{A~@2{S>;nuN%dFvdwQ>2E*LWQ(mPY`E8YXIpuOslbXA&G$>|i=Io`xG#1=2T?M%gzpbvwFm#YR zi6!6l4oya~GRa$Bwlu*{4x)N%gmC1k`lB*oQc-j=?mtzzS4o3_4gIquu?{9BSd z&(yUutHhkn*!z+fuHRX34fiOF?yn?lH z7|BIvu`#@eHN<8P<5341wh`|P9lpqfOS(EZuzG((1YoZ$sHn|V{j?rW!^c5%C`8>e zf5KT2V>T0E4kfRJ5Jd1R`XqsrEuFlH;Wy$upAq8>g_0*>mfOy6BKznJ3&LC8gHaD}CEjmr7dp$GClKT58<@<{l5JyXv(lq&je?o8r=E_Y} z&fHArB-!J@YC2=Nui_x!vam>DD}{2J9I3u_N`7^nmIc>IFTUfXvy@Y8(oK6}u8`-z zahNtO@|of;S8^v2b9AW9o{YLB`%T-u@q_ZfcI9lO<$Eu}Q0`h1kqko;an(vj((&l+ z>#!WZl*7|GhL(QG6)+61xt@S?9&lUoz)X%y3bFjV@fP+PKXS<*$Q{f5 zt1mShPrMZ&u_}hJZaF?XUHex;sqBtbhB21cQmm%5YVJux6tf~6#NL+dt8J{Mkt)*D zO_$|EUs>rz32JFqiq;x4P!M;QmY0Rxw*pw&6R4u`RUF>rp=9pRlo(R7AbT+QvhfsF zuGVn=K3~7DKWs&4fBG?upRIV!bfWM1F?T4RMYxhaK1z;n`~b&g-VxbT9@dr`xUCBJ zWI()UTauZR{M+iZq^JFb1-4Sv^_E;-#p$mPIbp1P-wXEb1>tg#w-rCvGTffHl+#{d z^biQh2*6#4W3YLqYu}c$*u6Ze%qkSy%d0yMxiuMXN2gxut2vy39w#7pltML)M7D!Y zOqnJoJc@M8j8Np$$y+&$J_AC1<|2o2lT+B9uC;{Jq$R)2JRpudDw~X(U!!cU&$lV; zb7$|bFJyM4{ZEFzyYgoGAvBSP3CtE(rDuZ9am?H;=R;{&^3-ashUk$4)RkV&IG!!z zmldKrI+L7vypba{1a*^}un&9o5rs=k9|%~iIg(N~7KAG|C3|AyI8l>4sL7}7-_}3g zR=IK#P6jhFY5)A&9eu3SE>M8=K4_S1Ry)Zg{1UmPnYwkFn}xJ!TDHX#A>{EU2->v5d> zx2*R$4U@^5GOTVp1-GR$a3?W!l6PB{f0M%X&iaX9($FG*TpGG@pprf_hGX0X6;B<`4Ye=Y-tY%G_wVF@Pm93j*Z&Znf z4C@bOd!J@R=B`1%qLdYU5z@6Nv_W6(<$ZxO9^rT&ydWw_vz!!qp@!c7Lh z_RZv=XhrvciTw4H!(z~hNY~^WSv%&3W-Su3R{Sxj?9TP9O&C{C=o zn5#@?cSP-_hU~eSn*y4b5M-5{oiy`~CJzc_wiHH6LY;%`pd;g9j#KfRqX75J{LK`{ z`4{4LNbrqkEN7<(b*TB=okO|&iM#~PKaVe34^XU z>FuBD#!y^yK$;m!&na{aWwT-%9fR3*kM;NcYq7{3BgdeoJ4$l4na-c}nIl^gF~j*x zGsSIdTeHQ|4t|$&Sy7{INylvG+c!%qN7?Lj{+{Z2AOWd5a}3rYBg-7`ZWt%fx35@# zYRm%*E9J>dNd+^5l8hSC?XGJxmU$VWR<0BBep}5{_pT(Zlfh5RH>6*4y_pF)ID&w0 z&{^Yc<(kP`w5~|vCFpv0iV%s{R5K|C^i+pDmTFhxyw#`*8qBFwh&vap?~L3h^dKR4 z?Wgu_%D27`r3NGfO^I@ss7RnPQ%HCYuAAkvNy^ zdH?3Ww-sA?ZXF2 z3MQv$yY{(Hu8hJtE0x@Q!c01S){Kl+jyve7eoB70EoN6%i;O9A!e;M6on<~p%{AA@ zYPIt1I)s>c({8a=n{~{$DF}aCL-TCff#|Jv02T=4G@5bVL7df0w)LHLY3^*Nj!-mG zzsxV3Vk~bkfRo^6Y23&Hln8cCL{jVK*P~~xXp6(6A*0`%0BX`!wqVGyi|t2=WaW_C zP})t73bo6wn4J@B<3wGS+=Lf8^IQCKJRVbDX z5YrTID|98&Mr}-;jM^a57K;1bmaO{NmqgI?_je`7hf?(C(t)E5rP$t<%(kIp{@dc{ z!P270c9$w2n2Af)>GgV;U4P>$z&0~jn#;1KJ>Iwn@~>NNHqefF;l?IQ6pH)Vl>0lQ z?p)hcdg}~qgNe2XmVW9Oc)p9THYXdU%n6&ym%IPA^Y4I7$^f0kVmtdO=sTwl0xj*7 zMN3~bl}R?amuhpvM#_Y=9QyuUqHJ#51Ra#xR1*H=2R5b7=eq=^cjnWO)`bS>-C#UcU+KO!bw)Y4My#1^gqXz0>H z6wR`$n&;~KV!6#qmS=J?vD zRc>-VDM2TTc3S~v?K6)NPohdjO&vd`^hF98>RWVH zZ_hl0ow81pM*5Saq!cvII!T~1fKsBG)U_ydSt)4!ds(}cez^>jz&Fowd}xkXbSZB= zb$WJmhIk$yey)l_nG0QDE_qYtgtLiVn_JC*Z$b(!Y;jk%=3GirGUsG%RXA7Qm~T-a z)Lb#&xuRC%hfYJy&8VR#c4*3(nKvwwtP~QSq)Qu@Tjx6dn~3GIw9UiEC}-E|Sauy^ z`Ib2b`4-*FupmCau!fXTv7S>Er4V%%W1+LUxs)7dLALEuJp6hjvXhps0$J#qZYfKP zbg^O=i^Yj2m~1r^u#7%iD65zjqSR}b zLTBG-4Nf@lmU!6T}(v>?{-xnxO+o3j*>{w}x+9W&rOe-G~!Q?So8)O+Vf~ z4|{}Vt5B8ZlJ8sOMp&e~8Q8>ug}ik5XLY2xyuuDacHNrnd>2V~{jS9$aA;JQ!sl8j zT}1R+m@gaFjdBYo+2c!jOfpKuWGK)wuPPtgCSFyXTpJ~XX}5E(glwbkVc)qrD=zyv ztkf&tMQ%yh+W`{7LKq1a9HxZ)UJIC>PtU%HsB9+>A;>tAI^BbP_Ed)7ucr^C)t5AI#PWRWSRs-=J|L> zP4!;{ zhE1Z;>&4kgkd)d;npQ5CW|-?rSZ3Li*c`P8W+dMlNYlpb8MiW%ZIW&KGyx{*ip7c; zGPz9B1vjDxI86jo;&<(W!dVJo%^h6Xvn6VuyTmhO%>ke>8}-#Tq9x|$RVyQPd6o7~ zaQFL~ZCa9zdfD;?Ezf#7YHMU`BLcK3o7{<|^Ge&LWo7HzF6~@7p|%xSc!aQZ|6?xY z3fjh|TdkOLZ5UahOj}qsp|g2gx_B}ZEJ~`Od^%Z2i(H9I7OBF-PU~4fp#&(2rxYX` zEw6kG32Q0eCrYu!IV7@B7<6uFCH*p2r!F09T&*eULk8Ae@y2|9?3E&UcZS*5bRcha z^v@M-3nh2Wjc*jXHG1E}TkttIhcS^yMO)`6?>jlbQcnq)-D*Y3=+GMy+u`lqGQ4BK zF&OtD?{0}{*DP`EMK`R+Vm%hQT?<=wBfeKJ=1UN*$+p-o=F;(laf3SP11iJBQTDEF z{N|-AQO50e?FaOLGTnH}!ZOQsk{7$MEpz?HGZu0cp~=PR-6nGVWA%%fq&%ZZdjFY| zQg@Q6Z7ZE)=3Q&shnH3+qMekTLTvl8)5;!`>^$UXTw6{3WH~?fIUJQPMRn|uICfj= zNiaFBx*U`AouxpBkvlyfu#O$H%u;@oam}MFOFLz39}>4MFA`{JPtLTVvGeOVQ(UuR zQ5!o1a1YxgS1p3xTOOjAN78L?7*-)_+q-0+&MFh5Y{*KWCvuyO|Lwad3%bn_TG+$*&K0fqPttfVvAVV8U2Yo*{g{slw{6H?OCwH;#sAB*}~O2 z3-KsJb)Lm9IjqPmUu;sHsi>WARjfg+?5hix`XzmJKA>@vxCxLPnM=kM@7toM?t;v- zAaq=+v&5kFo5_fbv1@Ma(s0w9Q>jF&q%Q+v;3*ktn4vNWjsmxT{vo2< zIk1-bNNLRf>bF?(M{odg6{Dgg5I{3QFpJeL^sxzTh=g!V*lnRRJS*j*a8G|N%sdv1=0H*))MKE=JRd2Boqmsxz2(_@?X$5CR> zZQW7MbEOVJ+_QVWQL{eER``9Nq*V^?)7hn0PKmMIB#t1Q!OZmzzE5Wn^T_ixCOo-S z^1ksPtGS9g4@dS#fr|T0IeP7H?VDBhPF{n{H6wF|3u1PZ4LA2Jt#Xu0C^;T?r-ZdO zh1Qw-#xDoHzH`?=Qa<}CiKi$)E$xRD?GQIaD%}=4pu9Tg>WKEE=z%Yrtbr0}lNmK% zW`ExC{TaC;8zJw-{yJ{@ZT-bePCENMI@SL3ws(ImZyfJ(0pFXF`D#-Ik&}oNd?A}fOHT=1j|xkuj++TsSgGVcb62b{4B9umDrAnzvXL~2L z9Z~(LXxAZ*c4siZ#a?A!oe;d8+shsW(pQt#NCQ>U#XGqMr)I!8jy{s(4|S1mKpy z7J9cEk;A=Ha+IX5@Q7qbnkmZ8$X3!OQl(5oe?3d4%aZp>GXgrqGe(94NBr<87ku(*;)my(`T*x-%pBbisG2 zZ_^yK@1LiNse9MqdGtDu^Dd(^ke`}ieyOemdKWHR^g^Jy8<(Ulo8CtZ^`$ZYz5#%&sT&bj-Tf69Z5;3Z=SoR7_p7`lSRnzyblSm3oZ6W~oty zQ==<@sc+12r0pCWqT3?X)Ghc*W!^ZMcLDa9Rx-yuPwgtLCb|-moQ%Xs(#hFM-``fy zv(a)!ZLGlIca1M8qX$%}&l*J6s5;hlZiC$YVGWep^~`6Ju#P5!$h}OkRdaQDauO|0 z>ir~F_V&bEt8Bj8{>7fofn6y*<5=OeGJ0$yzJ$o(WG2hh$eFHEo~`zv+!k3lTGxf= zH~FgdLzx<<$lxgz#m=K_Cq0W_KCu_5#j*W!B!!mUq6FHgyf{<;U+hG3i6-6h)Lb#)>9dOLsW6fe=Lb)hZU3k zpta7v%ItRADEGD>hb>WpvlDWvqy{}N28u??EFf=EPL>Q+!~M~0yY$d)J#|0f5bHF3@^xy#L4e|B6q(}G-r+&l2Qn&eYd8jfW-W#EM)(1$#d@Pdl-p}<^_Cg%gzb%khr2s|`=msT9I zb#FVLX$68*V|N+Z;foAGcUgMj%FuAvp?UxU<1UF8KFY3fM2kblj>vXFz&RO{VHK0r zNcXL#oz+|JFR!e=^AR?2a2qh^sz6AX(o38)j_Asw@$p1<35Y?6F0VY?Z5z5r939Jh zY<%XYCZ;kBZu=4j8N%wByHML3XmHQmErfQ?b+Vsb5kQ~9kqR<`voFMWO^f?X$JAkp zzucDMjaCrPKDDH3=M0n>942$v=aSmAr`YGpo;s<$e;cB{^M;&RAwl?@kRKi_H8AoE zH70&~ugi2k8>(4ndp?47)pa8uI+s*m*0rHgg_qrFj&=un^rqNd~otW~aagzv`*3ciFByBIy` zSyIYL@KQ_bl@$fT1tQ=eV(D3~M+yf&#fL-4YvBTAzaMcuk<+rbc$_FbjL z+UANO+5)X-b5&2JeQ2fcn#47d10&f(>9xUiX%Ai93Y+v({9ja{T^D^6m4&hzgKP61 zn?2B>wS)Fv>O*hmi*%Ocq1a1+1^DLeo1Tp|geIrBR;~H<`|86|E6|1#27hK7jVwpj zIqFp_vW0A^s~^tc+-=L;S-Tcp(v5@5aH}I6PH)5Iym}sohGUX~Gap?1RKMJ0Vl+z! z-Qi+ly&)IuY~HSoX_k%n4rtkqU2REU#MVo-;#(I+2T| z+#V6qc|G%&3b1ROe5y;{zpttmdJvrt?il@f+bK!NT)BUXr?R!PC88UVjp=7vULeb ztC+1uOZR|$Dc2!@!*R-{1;8}El%955_5LE4%ySZ9ODcr!4LBtU^h-!Wc;+z=SLAh*{0?3Di_nRhZ^1Q26#SiUg=Ql#hxVW^ z0mdx_5}Cgi^cCCPExFG)LJ3`ubXEVktrxc0N}~rgu zR={g}esN`<`>vI8MnTpNg=zdCrN$_u_vkKj3|%JoqyK#M|Gm>ocqT>d>vgpye)A{f^6TpN+g}*`L}Qw zo7}7z6He7>RgAzFN}i^@;A5HGL-(@>7`HL%o`%}_#UO+=dGGBNPO>^UJ?=?`;5l7PInJZ#!8}x!Z#XU~q$Xbi!kE&`&i}g7m!6bs!tS zfsL+X(wK!wH#$Dt1V0=w=a_(Zc3G7%3x$6G*{r8IuB@9J>Hduw`g#BOCHMztFu{e$ z0R&ob6GD3hJ4xn^I)hC&SbN1A3SL`%4HY74k>P}UJu3b_+pM`lrW0t@-ZcZEFm_#^ zNTQ@4->4gwqPhX&Ypyb1=j5LG;6&mI5N5}@D+$XE1aZ7VglS2xpdY;W)%=O24Ob?wD27*@^t%i| zESRI^M2%N0fP)|0TpA{WKDf6uD0dNaF{uGOOHAQ240DJ?`3=K3?>o?oVrP*A?Xb+sg- zYBAg|(+nhh-I*N)2VBxSqOQsg$3jv8Fo&vv&$~01(0=832fjm4ryZvK0M2=s$T7Acg$9s;u^op(iX#{)p9cG5sExEvc8?P2huJZXWm-v4X5zPXDu76d zuR>8sz(U;=wXC%v@HyS_7am$DEyVf((2mQzok9$EJ->uep}#x*3U{k6Ll|Wk>SBN? zXfN=`0GR>AQL%v#2NDc&^GgSDw5~qabvogJCaQp}+&;NPV9IG1_NJaa7)hD4`jQ;i zK%=1W0;rjmC|yGTn7ZX}RC3T$p(j)e6oJZ^6sl(jRUqf!g)smcr;H5&$JBfaKcWCB zweCdHg>IYge28q=+6hmimFG@bS5&hH$+LYFT6aV}6>!s)gb8>f^p)5E%{(yRIP966 zMIppxOCm;?a5RgAH4lU(S!Tgtpm>~v0=@?Oja7IHQ>7`rftmur<6`K zij9gEfv1|t0j?`@P%ZdS!5kHo8&?Jebd)pLg0%y+Fn?o$ zI?^83C{e^R6R?0PjbyO9PWsh(@<==)ATS_htpgJ`0p#efN*krMjkKmtVNWaI(5bUU z>-M16rH!mRVC#m&1T1g%0-S2qSAwZ_AC4sLZk+ z%*LY?2@JCVr28zn@4(?M{asRyJYU*^*-hz5IhdkHDm95(YaCJMWE|mn&O}x`_RE`oA1e=+CM}cVmT)w=vlFHHPsk8~HwE(R*7v)ulqJCro`v8zB)g)ZIx@(q) zbbkjPRSO1yr87#FbI3$}Ef3(HTyNp1x)W;Ef+RrZ1|+ExFa_d24e-nN#(Vg zwXh(8H3HW!>nK{6$=3HQ1qH4hspY_Q_dQT-O7-qkybxj-NPS?UkpkN*DIRmTQw>>4 zhW9r_-vPL_p$?9~VCNg7zA4)jiGqzS@l|NH zfVx_h``KJMYe2K^fvBliQr|#E-1Y;N)$elDVBSE!?_fU0Iz|clEv!x6X7BA{=B9iq zeTSjYvL$7mcxrE@P#}dBEk|8SE9v2s3VZObN2(BXMjfF@^%_1WZb5 zJZwWFp}vq6)n;7*9cYEY*g^j54>}iKX`S^!NHs+aJNIv_c?p}fgm))iU8DapV0v8? z>#wXIZiP|LwE%BrkS>s-E$hun)dWHkm2t}4lPMDi@%6rn3*Ks{bl4?aQ<;=td*v7d z%$#1TW?}jjnEwJ^stSbkSOs|n{`5jo92DbEX;lEb#z+H*WYJGwKmx=0eHLIcM%#mt zUkjC_l+w-(DC?cRT%PDv2flO6l8R2NC!fW-bWNv1z4cb5TPP}L#EOKDxlpX<0WnK? z7Id!UPY1blD;Y+TV$nKJ?ZIyty<41#A?-*h8QoQgU^f&QW7b_Z)0tLZ1uf?VGRW;z zN$|sZl?2b#!z3r|OW@1)6l8J{xB4j$*q8H8d+6*g#R?_LebjseN&ML_6wnEjNbkx{ z=|{()LO2tc>m%a_7;Al%uu_TbYzvk60H6tiStr5V$jlL7Yk3f|3ywg6EJKfiWR>VH z3xZpQM&ZrQp^TA6)=7kxJyCG2kcFZXf&hk*)OWF%tvs;3P%YG@-3yJ50lh(;Bf~HI zZtwu*>UL`B-LAO?u(j3kMt69~q1XnNS*f8K6}1P;T7lgbQ>+K>>w=EM3{a4$fXjN_DfSQcwHF|ogwY20(v<|= zsk>;L73;g?8#u*#w&E&@sFJ%X@l51M6rlM~n5!R59pY1+qHw=PJwiz|7s^II-1>D? z@gY9o?Sm@{CZ>WvLL)ucqrxhc&y^OgFij1Ek)9xQ86}G98mD=|0iUvKsrq+>#VY|b z(A}K~1rX2N0W)K^=M#x3$93^b#y$Q_+Wwqgy~Um`m#}2Mcx7DwNcZ^@LBSa{8xNs8OveXpR&r zIhacLIls$Ssm!`xm`Uq@3Kdo}#B4uS6kL$v!Y?hZ;BZ+SB>J)1Sz6$m&Sx9}J!qpO z*kGqI72hhuK?iisj$+dq7mzoIa@MMv%V}j8Y-D(+#k@|6zxV57SJ)3t@B{h z=v(wVp83(Kvn%w?{q=LDp0d&u@&w(qcniUKh?!v5P&+b-6zs*?%tE$QLU^#ZSAriN&11;33KxeDuyo!PZsmCc#L_y-%pNc~-r(hU;!-904iwU{8+p4UVjXJ2 zYozv}C@m0;yk9nsWu}&#Ir;3`f(E>rJ;0VmSe4_9+(ULr90PV|L9BM}FiHD!;7eC2Q&jCnQYabF{5&BS1><>8vXkqUy7(1PFk+I6t(&CP?vozZrX)%MwFQFLj#^x_Y zaEPDJGwH0c2os+gWxm;p;lPiSmz|?Zz?xZf&_d?5Ts34$PXRV#;>)32>4F+o> z#US5wKO9Eu#6ib{1?)Idg=S2?g=VW@DdIf}*Qyg#8!xb`r6?uRdx`t?=FkxL8#gG0 z|E9GezxC<{ln)We4KUMT9-{(?unPGB^7KHIvDr)jqHBOslvRk!@BWR zIQ}JlWZmM@V>8*NVg-P8_TXi^$*XoaNxn`Hr;!g=7&E;LBIQ-;XhZ%mJ16s7VAGfn zyUZ2wSpzjUO*NTql7sd2tny~E6%m`# zpKNsYR;H)yWMUH1sp@xtu&yHzj^td&tw!c_wz8+UvYWv=ZDohk1qAtbeZwg4BQ5T5 z%cSoo8lZ7%1`JrSqE)!?_?s0Zc-E>ttH+=Dl_N!+I1Q|vvQ~+D2$Z%H*^oVgC@m1y zRXykPcNS5Pd`FqBAdY$+4eOWVt8mhd`e*u<&U_4o1Teo9fG)*r4tRs0`}Ts0t~_1i zdbe?x>7!oPQ_Fg`pJ_6{L&TKsROhL)HO>=l{!+FO)h@-X85N##SMsWUS$%oyE@dkv zJ}cx64E0?5sb#ee;#|x#cSo3f5Ng$v@5CnQIsm(?rVwx;iu(JiOx-4SG3X++Yz-f?A`POmfmj*{2W3 zYjnN@K*r1IvYMdO@esN5o0Rq|8)`qRUoAtC=Ziiy1<)U(Y814<3GZ;MOOmEGU5VLEA%HbG9?vw-$oN_?HM7U1oO>c7#fa3MAVM^EiD70)H773ospnz!CUCmcn%Ejq1d!n`u`Gg> zat|{Q!HODG-GB;|Nh?wI=hydFJq8l3IH=1d(aqV!mHRFf>`kjszb9a#{@AYrwKx#$ z38qLSiyODM_3*O;lsl_}DVvtP?G+MqIV-Pkx2F;YsL}SEWI=k;m+-~{a?vpcSCt?c z58ko1g`o9nB}@S0#58nWRVZLcZ8z&+*qTt(viUZ@gEJkkZ_df9@JO%@^^VW#iUfy_ zAB7*iRiFm&^Dxv6zI9~<4PZz~3b#=O8HgL=fz?(@dL=2=8!waX&}ZMm1_gB0(a zIm++b5BgpnqXT`fPR?6i^$8r}36ydrx=bNSiqA9-x4iXMnNq*LWSjv8{YLl}Qa%L< zcKPT7(TuM+%e`E$FO_>ZKpY&kjPrbU3_?UG@fXZTwItO2dH0h~t(ppm4ea4jNYxyY zjyayl*J@F5tk8^A{h&~-ogk;dz*QJ!gRR_ONW{p3R?s!YT~*e-ZLMo4ozy5XD4Ixm z0`4~KQ+jAYF+r$vGE$)QO1r+YKb#CEDpS_kT%rFehwLe*~~NV-h%psB=M1LwGKq1BRrgUw#G zzq$A&0i4Q1rK+@XIaV0GAKd)Oivu+7oZ@7M40FXFaz0shK`kC|#}gKtm6C)8Ib0YC z1$S=bJsX$Zh1z{E_5ICNng$*w;5P^EkZ!sNJ{#O@Y=apUhN*W_f`XuZQ1Nf90vF#u zLQUZn!UFJq_DAx;w!lxSXnfaa@VorGU?gRFNu&~_BG0RmOMmPZ!VTMb^@`^W0^pP@ zw!zuoN<`AJ7w>>si8f?;0sWmTjHY{ExJuLxG+4}94J|`ZcWc%zznv?ARQAR!gBXiz z5}iSxW?yXe86WF>VZd+9nenu3?sP-nQp+(&Vo?d6Ak*(t^C~zU3UX^E`aK+RiG+(; z%Cufxc_>vtDF|*==HDt%kSEErRKor0t-o-2f2@BMqEOX313xoaiqy2TO2peIX|lyY2;8DCjM~ZtaKE1fS2Y^efF6n0uJjGKqay%r!1ZxA10f$({{m>=IJL~>LoF0SU|%jGpjjiq3UoYX zd55bb2r}?Tk&62UOdPae7MoB%HeJP?%YYD6cuAvp6INf?j)cb5VOVUm)v2+ut776p z86@fFG8C+L0TvVHiC2q|(krU#q5YpQ{(3ZHRordil!P*GEGVg0Rf#IEifn4FDxKJ% z*u`8dO4Si5h(-&}9K%m7j9Np>!d^Ym7iks+$7Df?mc?NV7i0@jIf)#bX3etw<*=;s z3kr*QmeV#@0hD9PtVz%Hv60s-Q8S6Wt+2<#dS_YQ(0hU6$?@G#>SP8ERXa}c0HB=N za!ytWkuxE7xoE4oC9k|Xi4!rsF*wWZ-d#!hoX<0 zuQ~YHq8F#l{TaYJ~{YRLvZbp`Cs04!jVx;NBw2wicR zSS`@QDV%o>-^F3tASW%mOC`_>kK%I4^>(80m6a0It&{^d*E!^Eb8HqFGJ&L9F>zQ-stTgkQ z9LFWsid4i^Rda3Yo~tdc2~i#5iQio%c;+kHfWBP1ZYH|ZdJSePlNoe=(SS%=v!m36 zfxeh1=ZUAxfu#J%TzcJ^vE?ji`D`2$9j|B(S3&J?>0xCV$4V2a`UB^g%L(pp)SZ|3 z6BKN{WmsHGur`XjyG(G`KmrWz?ykWJE`z%UcMmdX2=49#mjJa|u?K%`Vjho*qX!C^VH3*C>5TrIdS_y{P4YwRQow2DY2u;JB4 zHmKzVs#tid#<%G@iqH0Q_ZQ(Ltckf-LDqyd=T6gSYI#nJ$SUSdV7NX?sWuQM!<=1v z#Puv2fsjNbPRj(q&dDf^&Pv}I zK`J`Rgx>Te(f%?n!aVPwy>*}KdbcX?^G9P<4!yIqo%Lid0xkXMAgo`Wrn~5_vdk#% ztDAdN_G#~AKVInR6D4gdRb`dB>$EBArYF<&=2WM^=wnjxXSUwox%%z>akPKNCX4Bh zfb}?4DgTn&a*Wh8I0-Y53Ms!LuxKz$!6Hl;-!`O7p> z=CirPI4;^-ZVH^U03}%cj-&FB1~6}T53Cbl(x*$`JL^>pkdx#)IPV<%hQW@&1+FlX zLs-d$>QFW~+L%waFP<~@_e9t$6_712B!O}_tc?h9)7=S(SO&;_33{zaf}d;doFu=V zdmEfTTQ_nl;xYjPUyzrsHYG6O6EASJvmLEY>s93doV?*mc@ zf)4E)aX1Jo@4dN$1*9#(Ys1%_-_n2nz)@t!A#Pm26F#S6gEsrPyM!!DK9%>xp{Xxg zkr9FzQ)G{$BIw8S)`7C^VabH*OiDcB`@0n=}F+4p_e=w9ndFVFmX zPY2Ae)j{uo*UR64`2m%5f)`d_DJan5`B$YeS*X`{EEOrpEtw@5O( zpB%+LN{?Fa_wgwTDUhW!LH}NE49kKi7SLxYqOsmw=Su9_*){!#CT+#Y;oNh3{wwa!owicC;~8ikr1ge`<{y-mBrt9di;AV?V&uwLJyNS- z2CmwE7yz#M) zt(Hv3OZjNB6&dLiJjyBC1#o>0aivofE62F?O0vG@RI-X2rTaz1XHQj;l3v~+h;=)x z=h)Em=Kxo=4m44g?z-6Zs#n_CzST!&D1RTTb$FK34)NqBts7Pp#d1Pr)Q~0{$A;b^ zwu%=R#Sv3voLmI0YYERiZFCK#A~RHIJ$|J~xJxrkNnlT2!t&z}s#Bv~zUUz|QnNtQ zj&7l<(&fhm0OA*uz4TtJ!HFeD^azr3vdR7_Z~3_PqjX`X?_*MjzOl1Sa11<%qkL0r z3%J!w)Zh>kv^k8CR8tJC!Qs!2bGV)!J?~mzDft4K3!>zVV~kHo2Zy{`qW?Jm64hpjDeHv$>^~>cI$N~Se?G2dBCeh-Vd8tz z7bNshR@T&`g<&}vIQ33*uSdvgQP(^i8X?U&9nGzJn&ioZ+>wa*{$7ADC5Itphsu$m z;e2`%x)_L0%f1pcUuUQiSY-g>DOw#7!HzBxWBpL>T#ah48&-kUf{lI?7prQhT^YJ% zcPta| zKIr)|ZA2?n-!DZu7*ox77aesWv0!{HoiSRE?o*WjZA{%|PJ7MxG@_W?h6qKeAOp&G ziU@P5V##$8VoblbvAD_0kI(k^9A72n2W-B

TH=8B$mt_}eq`l7G!tDSs;VOi<8J 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≷q(UzPhR_`A5eiWWz#9reJ;cTpP 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 rXJL%4I@CkRpCvJ{MR5%e`#)<+KdNC!`cBZK &history, const std::filesystem::path &file_name) { // Initialize SPIFFS - if (!SAVE_HISTORY_TO_SPIFFS) + if (!SAVE_HISTORY_TO_LITTLEFS) return; // auto spiffs_guard = LITTLEFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index 6e8373e..ca54a0a 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -15,7 +15,7 @@ #include "psvector.h" const uint32_t max_history = 256; -const bool SAVE_HISTORY_TO_SPIFFS = false; // Set to true to enable saving history to SPIFFS, false to disable +const bool SAVE_HISTORY_TO_LITTLEFS = false; // Set to true to enable saving history to SPIFFS, false to disable static bool first_save = true; // flag to indicate if this is the first save (to write header) struct dataSaveParams diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index c7da43b..42c910a 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -101,14 +101,14 @@ void loop() auto *writable_history = &ignA_history_1; // Resources Initialization - static Devices dev; + Devices dev; // Task handle - static TaskHandle_t trigA_TaskHandle = NULL; - static TaskHandle_t trigB_TaskHandle = NULL; + TaskHandle_t trigA_TaskHandle = NULL; + TaskHandle_t trigB_TaskHandle = NULL; // Data Queue for real time task to main loop communication - static QueueHandle_t rt_taskA_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); - static QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); - static rtTaskParams taskA_params{ + QueueHandle_t rt_taskA_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); + QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); + rtTaskParams taskA_params{ .rt_running = true, .dev = &dev, .rt_handle_ptr = &trigA_TaskHandle, @@ -219,22 +219,18 @@ void loop() uint32_t counter = 0; uint32_t wait_count = 0; ignitionBoxStatus ign_info; - int64_t last = esp_timer_get_time(); - uint32_t missed_firings12 = 0; - uint32_t missed_firings34 = 0; - ignitionBoxStatusAverage ignA_avg(filter_k); // moving average calculator for ignition box A with a window of 100 samples + ignitionBoxStatusAverage ign_info_avg(filter_k); + // Initialize Web page AsyncWebServer server(80); AsyncWebSocket ws("/ws"); ws.onEvent(onWsEvent); server.addHandler(&ws); - - auto spiffs_guard = LITTLEFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted server.serveStatic("/", LittleFS, "/").setDefaultFile("index.html"); server.begin(); server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) - { request->send(200, "text/html", htmlTest.c_str()); }); + { request->send(200, "text/plain", "OK"); }); while (running) { @@ -256,14 +252,14 @@ void loop() // printInfo(ign_info); auto &hist = *active_history; hist[counter++ % active_history->size()] = ign_info; - ignA_avg.update(ign_info); // update moving average with latest ignition status + ign_info_avg.update(ign_info); // update moving average with latest ignition status Serial.print("Data Received: " + String(counter) + "/" + String(hist.size()) + '\r'); if (ws.count() > 0 && counter % 10 == 0) // send data every 10 samples { Serial.println(); LOG_INFO("Sending average ignition status to websocket clients..."); - auto msg = ignA_avg.toJson().as(); + auto msg = ign_info_avg.toJson().as(); ws.textAll(msg); } } From 1e068476af0ade15d99007f8b9fe882557ef2731 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Thu, 9 Apr 2026 13:41:50 +0200 Subject: [PATCH 14/38] LittleFS mount OK, updated interface, upload to littlefs from browser --- RotaxMonitor/data/index.html | 34 ++- RotaxMonitor/data/logo_astro_dev.svg | 306 +++++++++++++++++++++++ RotaxMonitor/data/script.js | 59 +++++ RotaxMonitor/data/style.css | 170 ++++++++++++- RotaxMonitor/partitions/default_16MB.csv | 6 - RotaxMonitor/platformio.ini | 6 +- RotaxMonitor/src/datasave.cpp | 42 +++- RotaxMonitor/src/datasave.h | 27 +- RotaxMonitor/src/main.cpp | 101 +++++++- RotaxMonitor/src/tasks.cpp | 7 +- RotaxMonitor/src/webserver.cpp | 0 RotaxMonitor/src/webserver.h | 0 12 files changed, 686 insertions(+), 72 deletions(-) create mode 100644 RotaxMonitor/data/logo_astro_dev.svg delete mode 100644 RotaxMonitor/partitions/default_16MB.csv create mode 100644 RotaxMonitor/src/webserver.cpp create mode 100644 RotaxMonitor/src/webserver.h diff --git a/RotaxMonitor/data/index.html b/RotaxMonitor/data/index.html index 656686d..e1bc07c 100644 --- a/RotaxMonitor/data/index.html +++ b/RotaxMonitor/data/index.html @@ -1,16 +1,23 @@ + - ESP32 Dashboard + Astro Rotax Monitor + +

-

RotaxMonitor realtime data

- - - +
+ Waiting for data... +

Timestamp: -

@@ -24,8 +31,8 @@ Property - Coils 12 - Coils 34 + Pickup 12 + Pickup 34 @@ -70,12 +77,12 @@ - - Events + Spark Events - - - Missed firings + Missed Events - - @@ -83,6 +90,15 @@
+
+

Upload file to Flash

+

Select a file and upload it to Flash.

+ + +
No file uploaded yet.
+
+ + \ No newline at end of file diff --git a/RotaxMonitor/data/logo_astro_dev.svg b/RotaxMonitor/data/logo_astro_dev.svg new file mode 100644 index 0000000..f504444 --- /dev/null +++ b/RotaxMonitor/data/logo_astro_dev.svg @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RotaxMonitor/data/script.js b/RotaxMonitor/data/script.js index db58a84..779c224 100644 --- a/RotaxMonitor/data/script.js +++ b/RotaxMonitor/data/script.js @@ -1,14 +1,35 @@ let ws; +let lastMessageTimestamp = 0; +const IDLE_THRESHOLD_MS = 1000; +const loadingIndicator = document.getElementById("loadingIndicator"); + +function setLoadingIndicator(visible) { + if (!loadingIndicator) { + return; + } + + loadingIndicator.classList.toggle("hidden", !visible); +} + +function updateLoadingState() { + const isConnected = ws && ws.readyState === WebSocket.OPEN; + const idle = Date.now() - lastMessageTimestamp >= IDLE_THRESHOLD_MS; + + setLoadingIndicator(isConnected && idle); +} function connectWS() { ws = new WebSocket("ws://" + location.host + "/ws"); ws.onopen = () => { console.log("WebSocket connesso"); + lastMessageTimestamp = Date.now(); + setLoadingIndicator(false); }; ws.onclose = () => { console.log("WebSocket disconnesso, retry..."); + setLoadingIndicator(false); setTimeout(connectWS, 5000); }; @@ -22,6 +43,9 @@ function connectWS() { return; } + lastMessageTimestamp = Date.now(); + setLoadingIndicator(false); + document.getElementById("datavalid").textContent = data.datavalid ?? "-"; document.getElementById("timestamp").textContent = data.timestamp ?? "-"; document.getElementById("volts_gen").textContent = data.volts_gen ?? "-"; @@ -63,4 +87,39 @@ function stop() { fetch("/stop"); } +function uploadLittleFS() { + const fileInput = document.getElementById("littlefsFile"); + const status = document.getElementById("uploadStatus"); + + if (!fileInput || fileInput.files.length === 0) { + if (status) status.textContent = "Select a file first."; + return; + } + + const file = fileInput.files[0]; + const formData = new FormData(); + formData.append("file", file, file.name); + + if (status) status.textContent = "Uploading..."; + + fetch("/upload", { + method: "POST", + body: formData, + }) + .then((resp) => { + if (!resp.ok) { + throw new Error("Upload failed: " + resp.status + " " + resp.statusText); + } + return resp.text(); + }) + .then(() => { + if (status) status.textContent = "Uploaded: " + file.name; + fileInput.value = ""; + }) + .catch((err) => { + if (status) status.textContent = err.message; + }); +} + +setInterval(updateLoadingState, 200); connectWS(); diff --git a/RotaxMonitor/data/style.css b/RotaxMonitor/data/style.css index ea261fa..cdf3297 100644 --- a/RotaxMonitor/data/style.css +++ b/RotaxMonitor/data/style.css @@ -1,7 +1,46 @@ +:root { + --primary-dark: #0a1929; + --primary-blue: #0144a8; + --accent-blue: #1e88e5; + --light-bg: #f5f7fa; + --border-color: #d0d6dd; + --text-dark: #1a1a1a; + --text-muted: #666666; +} + body { - font-family: Arial; - text-align: center; - margin-top: 40px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; + margin: 0; + padding: 0; + background-color: var(--light-bg); + color: var(--text-dark); +} + +.page-header { + background: linear-gradient(135deg, var(--primary-dark) 0%, #1a3a52 100%); + color: white; + padding: 30px 20px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + margin-bottom: 30px; +} + +.header-content { + max-width: 900px; + margin: 0 auto; + display: flex; + align-items: center; + gap: 20px; +} + +.logo { + height: 50px; + width: auto; +} + +.page-header h1 { + margin: 0; + font-size: 28px; + font-weight: 600; } table { @@ -9,21 +48,136 @@ table { border-collapse: collapse; width: 100%; max-width: 900px; + background: white; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); + border-radius: 6px; + overflow: hidden; } th, td { - border: 1px solid #ccc; - padding: 10px; - font-size: 16px; - text-align: left; + border: 1px solid var(--border-color); + padding: 12px; + font-size: 14px; + text-align: center; } th { - background-color: #f4f4f4; + background-color: var(--primary-blue); + color: white; + font-weight: 600; +} + +tr:hover { + background-color: #f9fbfc; } button { margin: 10px; padding: 10px 20px; font-size: 16px; + background-color: var(--primary-blue); + color: white; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background-color 0.2s; +} + +button:hover { + background-color: var(--accent-blue); +} + +.upload-section { + margin: 30px auto 20px; + max-width: 900px; + text-align: left; + padding: 20px; + border: 1px solid var(--border-color); + border-radius: 6px; + background: white; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); +} + +.upload-section h3 { + margin-top: 0; + margin-bottom: 8px; + color: var(--primary-blue); + font-size: 16px; +} + +.upload-section p { + margin: 8px 0; + color: var(--text-muted); + font-size: 14px; +} + +.upload-section input[type="file"] { + margin-top: 8px; + margin-bottom: 12px; +} + +.upload-status { + margin-top: 10px; + font-size: 14px; + color: var(--text-muted); +} + +.loading-indicator { + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + margin: 0; + padding: 16px 20px; + font-size: 20px; + color: var(--primary-blue); + border-bottom: 1px solid var(--border-color); + background: white; + width: 100%; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); +} + +.loading-indicator.hidden { + display: none; +} + +.spinner { + width: 16px; + height: 16px; + border: 2px solid transparent; + border-top-color: var(--primary-blue); + border-radius: 50%; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +/* Data section */ +div[style*="max-width: 900px"] { + background: white; + padding: 20px; + border-radius: 6px; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); + margin-bottom: 20px; +} + +div[style*="max-width: 900px"] p { + margin: 8px 0; + font-size: 14px; +} + +div[style*="max-width: 900px"] strong { + color: var(--primary-blue); +} + +span { + color: var(--text-dark); +} } diff --git a/RotaxMonitor/partitions/default_16MB.csv b/RotaxMonitor/partitions/default_16MB.csv deleted file mode 100644 index de523c3..0000000 --- a/RotaxMonitor/partitions/default_16MB.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 0x9000, 0x5000, -otadata, data, ota, 0xe000, 0x2000, -app0, app, ota_0, 0x10000, 0x700000, -app1, app, ota_1, 0x710000,0x700000, -spiffs, data, spiffs, 0xE10000,0x1F0000, diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index e84e71b..4a09e62 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -21,13 +21,13 @@ lib_deps = me-no-dev/AsyncTCP@^3.3.2 me-no-dev/ESPAsyncWebServer@^3.6.0 upload_protocol = esptool -upload_port = COM4 +upload_port = COM8 upload_speed = 921600 monitor_port = COM4 monitor_speed = 921600 build_type = release build_flags = - -DCORE_DEBUG_LEVEL=5 + -DCORE_DEBUG_LEVEL=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 @@ -59,7 +59,7 @@ build_flags = -O0 -g3 -ggdb3 - -DCORE_DEBUG_LEVEL=5 + -DCORE_DEBUG_LEVEL=3 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index da3e9f5..49b9c81 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -1,7 +1,26 @@ #include "datasave.h" #include -static const size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB) +static const size_t min_free = 1024 * 1024; // minimum free space in LittleFS to allow saving history (1MB) + +LITTLEFSGuard::LITTLEFSGuard() +{ + if (!LittleFS.begin(true, "/littlefs", 10, "littlefs")) + { + LOG_ERROR("Failed to mount LittleFS"); + } + else + { + LOG_INFO("LittleFS mounted successfully"); + LOG_INFO("LittleFS Free KBytes:", (LittleFS.totalBytes() - LittleFS.usedBytes()) /1024); + } +} + +LITTLEFSGuard::~LITTLEFSGuard() +{ + LittleFS.end(); + LOG_INFO("LittleFS unmounted successfully"); +} void ignitionBoxStatusAverage::filter(int32_t &old, const int32_t value, const uint32_t k) { @@ -42,18 +61,18 @@ void ignitionBoxStatusAverage::update(const ignitionBoxStatus &new_status) filter(m_last.coils12.peak_p_out, new_status.coils12.peak_p_out, m_max_count); // incremental average calculation filter(m_last.coils12.peak_n_out, new_status.coils12.peak_n_out, m_max_count); // incremental average calculation - m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging - m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging - m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status - m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status - filter(m_last.coils34.spark_delay, new_status.coils34.spark_delay, m_max_count); // incremental average calculation + m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging + m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging + m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status + m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status + filter(m_last.coils34.spark_delay, new_status.coils34.spark_delay, m_max_count); // incremental average calculation filter(m_last.coils34.peak_p_in, new_status.coils34.peak_p_in, m_max_count); // incremental average calculation filter(m_last.coils34.peak_n_in, new_status.coils34.peak_n_in, m_max_count); // incremental average calculation filter(m_last.coils34.peak_p_out, new_status.coils34.peak_p_out, m_max_count); // incremental average calculation filter(m_last.coils34.peak_n_out, new_status.coils34.peak_n_out, m_max_count); // incremental average calculation - filter(m_last.eng_rpm, new_status.eng_rpm, m_max_count); // incremental average calculation // incremental average calculation - filter(m_last.adc_read_time, m_last.adc_read_time, m_max_count); // incremental average calculation - m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value + filter(m_last.eng_rpm, new_status.eng_rpm, m_max_count); // incremental average calculation // incremental average calculation + filter(m_last.adc_read_time, m_last.adc_read_time, m_max_count); // incremental average calculation + m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value if (m_count >= m_max_count) { @@ -126,7 +145,8 @@ void save_history(const PSRAMVector &history, const std::file // Initialize SPIFFS if (!SAVE_HISTORY_TO_LITTLEFS) return; - // auto spiffs_guard = LITTLEFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted + + auto littlefs_guard = LITTLEFSGuard(); // use RAII guard to ensure LittleFS is properly mounted and unmounted if (LittleFS.totalBytes() - LittleFS.usedBytes() < min_free) // check if at least 1MB is free for saving history { @@ -142,7 +162,7 @@ void save_history(const PSRAMVector &history, const std::file if (first_save && LittleFS.exists(file_path.c_str())) { first_save = false; - save_flags |= std::ios::trunc; // overwrite existing file + save_flags |= std::ios::trunc; // overwrite existing file LittleFS.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS LOG_INFO("Saving history to LittleFS, new file:", file_path.c_str()); } diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index ca54a0a..d834308 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -4,19 +4,19 @@ // System Includes #include #include -#include #include #include -#include #include +#include +#include // Project Includes #include "isr.h" #include "psvector.h" const uint32_t max_history = 256; -const bool SAVE_HISTORY_TO_LITTLEFS = false; // Set to true to enable saving history to SPIFFS, false to disable -static bool first_save = true; // flag to indicate if this is the first save (to write header) +const bool SAVE_HISTORY_TO_LITTLEFS = false; // Set to true to enable saving history to LittleFS, false to disable +static bool first_save = true; // flag to indicate if this is the first save (to write header) struct dataSaveParams { @@ -27,20 +27,8 @@ struct dataSaveParams class LITTLEFSGuard { public: - LITTLEFSGuard() - { - if (!LittleFS.begin(true)) - { - LOG_ERROR("Failed to mount LittleFS"); - } - LOG_INFO("SPIFFS mounted successfully"); - } - - ~LITTLEFSGuard() - { - LittleFS.end(); - LOG_INFO("LittleFS unmounted successfully"); - } + LITTLEFSGuard(); + ~LITTLEFSGuard(); }; class ignitionBoxStatusAverage @@ -53,7 +41,8 @@ private: public: ignitionBoxStatusAverage() = default; - ignitionBoxStatusAverage(const uint32_t max_count) : m_max_count(max_count) { + ignitionBoxStatusAverage(const uint32_t max_count) : m_max_count(max_count) + { m_data_valid = false; m_count = 0; } diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 42c910a..ed85363 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -1,4 +1,4 @@ -#define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO +#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG // Arduino Libraries #include @@ -16,6 +16,9 @@ #include #include +static File uploadFile; +static bool uploadFailed = false; + // FreeRTOS directives #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -61,11 +64,6 @@ void setup() LOG_DEBUG("ESP32 Heap:", ESP.getHeapSize()); LOG_DEBUG("ESP32 Sketch:", ESP.getFreeSketchSpace()); - // Initialize Interrupt pins on PICKUP detectors - initTriggerPinsInputs(); - // Initialize Interrupt pins on SPARK detectors - initSparkPinInputs(); - // Init Wifi station LOG_INFO("Initializing WiFi..."); WiFi.mode(WIFI_AP); @@ -87,6 +85,11 @@ void setup() vTaskDelay(pdMS_TO_TICKS(5000)); esp_restart(); } + + // Initialize Interrupt pins on PICKUP detectors + initTriggerPinsInputs(); + // Initialize Interrupt pins on SPARK detectors + initSparkPinInputs(); } void loop() @@ -123,7 +126,15 @@ void loop() .spark_pin_34 = SPARK_PIN_A34}, .rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_A12P, .rst_io_12n = RST_EXT_A12N, .rst_io_34p = RST_EXT_A34P, .rst_io_34n = RST_EXT_A34N}}; - LOG_DEBUG("Task Variables OK"); + if (!rt_taskA_queue || !rt_taskB_queue) + { + LOG_ERROR("Unable To Create task queues"); + LOG_ERROR("5 seconds to restart..."); + vTaskDelay(pdMS_TO_TICKS(5000)); + esp_restart(); + } + else + LOG_DEBUG("Task Variables OK"); #ifdef CH_B_ENABLE QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); @@ -190,6 +201,7 @@ void loop() RT_TASK_PRIORITY, &trigA_TaskHandle, CORE_0); + delay(100); // Ignition B on Core 1 auto ignB_task_success = pdPASS; @@ -202,11 +214,12 @@ void loop() RT_TASK_PRIORITY, // priorità leggermente più alta &trigB_TaskHandle, CORE_1); + delay(100); #endif - if ((ignA_task_success && ignB_task_success) != pdPASS) + if (ignA_task_success != pdPASS || ignB_task_success != pdPASS) { - LOG_ERROR("Una ble to initialize ISR task"); + LOG_ERROR("Unable to initialize ISR task"); LOG_ERROR("5 seconds to restart..."); vTaskDelay(pdMS_TO_TICKS(5000)); esp_restart(); @@ -219,7 +232,8 @@ void loop() uint32_t counter = 0; uint32_t wait_count = 0; ignitionBoxStatus ign_info; - ignitionBoxStatusAverage ign_info_avg(filter_k); + ignitionBoxStatusAverage ign_info_avg(filter_k); + LITTLEFSGuard fsGuard; // Initialize Web page AsyncWebServer server(80); @@ -227,6 +241,67 @@ void loop() ws.onEvent(onWsEvent); server.addHandler(&ws); server.serveStatic("/", LittleFS, "/").setDefaultFile("index.html"); + + server.on("/upload", HTTP_POST, + [](AsyncWebServerRequest *request) { + if (uploadFailed) + { + request->send(500, "text/plain", "Upload failed"); + } + else + { + request->send(200, "text/plain", "Upload successful"); + } + }, + [](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) { + if (index == 0) + { + uploadFailed = false; + String safeName = filename; + int slashIndex = safeName.lastIndexOf('/'); + if (slashIndex >= 0) + { + safeName = safeName.substring(slashIndex + 1); + } + if (safeName.length() == 0) + { + uploadFailed = true; + return; + } + + String filePath = "/" + safeName; + if (LittleFS.exists(filePath)) + { + LittleFS.remove(filePath); + } + + uploadFile = LittleFS.open(filePath, FILE_WRITE); + if (!uploadFile) + { + uploadFailed = true; + LOG_ERROR("Failed to open upload file:", filePath); + return; + } + } + + if (!uploadFailed && uploadFile) + { + if (uploadFile.write(data, len) != len) + { + uploadFailed = true; + } + } + + if (final && uploadFile) + { + uploadFile.close(); + if (!uploadFailed) + { + LOG_INFO("Uploaded file to LittleFS:", filename); + } + } + }); + server.begin(); server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) @@ -253,12 +328,12 @@ void loop() auto &hist = *active_history; hist[counter++ % active_history->size()] = ign_info; ign_info_avg.update(ign_info); // update moving average with latest ignition status - Serial.print("Data Received: " + String(counter) + "/" + String(hist.size()) + '\r'); + Serial.print("\033[2K Data Received: " + String(counter) + "/" + String(hist.size()) + '\r'); - if (ws.count() > 0 && counter % 10 == 0) // send data every 10 samples + if (ws.count() > 0 && counter % filter_k == 0) // send data every 10 samples { Serial.println(); - LOG_INFO("Sending average ignition status to websocket clients..."); + LOG_DEBUG("Sending average ignition status to websocket clients..."); auto msg = ign_info_avg.toJson().as(); ws.textAll(msg); } diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 86b9681..45a9aa0 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -110,7 +110,6 @@ void rtIgnitionTask(void *pvParameters) #ifdef DEBUG Serial.print("\033[2J"); // clear screen Serial.print("\033[H"); // cursor home - LOG_INFO("Iteration [", it++, "]"); if (!names.contains(pickup_flag)) { @@ -267,9 +266,11 @@ void rtIgnitionTask(void *pvParameters) // send essage to main loop with ignition info, by copy so local static variable is ok if (rt_queue) + { ign_box_sts.timestamp = esp_timer_get_time(); // update data timestamp - if (xQueueSendToBack(rt_queue, (void *)&ign_box_sts, 0) != pdPASS) - ign_box_sts.n_queue_errors = ++n_errors; + if (xQueueSendToBack(rt_queue, (void *)&ign_box_sts, 0) != pdPASS) + ign_box_sts.n_queue_errors = ++n_errors; + } } } // Delete the timeout timer diff --git a/RotaxMonitor/src/webserver.cpp b/RotaxMonitor/src/webserver.cpp new file mode 100644 index 0000000..e69de29 diff --git a/RotaxMonitor/src/webserver.h b/RotaxMonitor/src/webserver.h new file mode 100644 index 0000000..e69de29 From 155f58a34759f7e8f053710c0a066ced183ec9e1 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Thu, 9 Apr 2026 14:42:13 +0200 Subject: [PATCH 15/38] refactored webserver code --- RotaxMonitor/data/style.css | 1 - RotaxMonitor/src/main.cpp | 105 +++------------------------------ RotaxMonitor/src/webserver.cpp | 98 ++++++++++++++++++++++++++++++ RotaxMonitor/src/webserver.h | 38 ++++++++++++ 4 files changed, 143 insertions(+), 99 deletions(-) diff --git a/RotaxMonitor/data/style.css b/RotaxMonitor/data/style.css index cdf3297..11dd233 100644 --- a/RotaxMonitor/data/style.css +++ b/RotaxMonitor/data/style.css @@ -180,4 +180,3 @@ div[style*="max-width: 900px"] strong { span { color: var(--text-dark); } -} diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index ed85363..48af1a9 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -7,18 +7,14 @@ #include #include #include -#include -#include // Definitions #include #include #include +#include #include -static File uploadFile; -static bool uploadFailed = false; - // FreeRTOS directives #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -29,20 +25,6 @@ static bool uploadFailed = false; #define WIFI_SSID "AstroRotaxMonitor" #define WIFI_PASSWORD "maledettirotax" -void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, - AwsEventType type, void *arg, uint8_t *data, size_t len) -{ - switch (type) - { - case WS_EVT_CONNECT: - Serial.printf("WS client IP[%s]-ID[%u] CONNECTED\r\n", client->remoteIP().toString().c_str(), client->id()); - break; - case WS_EVT_DISCONNECT: - Serial.printf("WS client ID[%u] DISCONNECTED\r\n", client->remoteIP().toString().c_str(), client->id()); - break; - } -} - void setup() { Serial.begin(921600); @@ -201,7 +183,7 @@ void loop() RT_TASK_PRIORITY, &trigA_TaskHandle, CORE_0); - delay(100); + delay(100); // give some time to the thread to start // Ignition B on Core 1 auto ignB_task_success = pdPASS; @@ -214,7 +196,7 @@ void loop() RT_TASK_PRIORITY, // priorità leggermente più alta &trigB_TaskHandle, CORE_1); - delay(100); + delay(100); // give some time to the thread to start #endif if (ignA_task_success != pdPASS || ignB_task_success != pdPASS) @@ -234,78 +216,7 @@ void loop() ignitionBoxStatus ign_info; ignitionBoxStatusAverage ign_info_avg(filter_k); LITTLEFSGuard fsGuard; - - // Initialize Web page - AsyncWebServer server(80); - AsyncWebSocket ws("/ws"); - ws.onEvent(onWsEvent); - server.addHandler(&ws); - server.serveStatic("/", LittleFS, "/").setDefaultFile("index.html"); - - server.on("/upload", HTTP_POST, - [](AsyncWebServerRequest *request) { - if (uploadFailed) - { - request->send(500, "text/plain", "Upload failed"); - } - else - { - request->send(200, "text/plain", "Upload successful"); - } - }, - [](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) { - if (index == 0) - { - uploadFailed = false; - String safeName = filename; - int slashIndex = safeName.lastIndexOf('/'); - if (slashIndex >= 0) - { - safeName = safeName.substring(slashIndex + 1); - } - if (safeName.length() == 0) - { - uploadFailed = true; - return; - } - - String filePath = "/" + safeName; - if (LittleFS.exists(filePath)) - { - LittleFS.remove(filePath); - } - - uploadFile = LittleFS.open(filePath, FILE_WRITE); - if (!uploadFile) - { - uploadFailed = true; - LOG_ERROR("Failed to open upload file:", filePath); - return; - } - } - - if (!uploadFailed && uploadFile) - { - if (uploadFile.write(data, len) != len) - { - uploadFailed = true; - } - } - - if (final && uploadFile) - { - uploadFile.close(); - if (!uploadFailed) - { - LOG_INFO("Uploaded file to LittleFS:", filename); - } - } - }); - - server.begin(); - - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) - { request->send(200, "text/plain", "OK"); }); + WebPage webPage(80, LittleFS); // Initialize webserver and Websocket while (running) { @@ -328,14 +239,12 @@ void loop() auto &hist = *active_history; hist[counter++ % active_history->size()] = ign_info; ign_info_avg.update(ign_info); // update moving average with latest ignition status - Serial.print("\033[2K Data Received: " + String(counter) + "/" + String(hist.size()) + '\r'); - - if (ws.count() > 0 && counter % filter_k == 0) // send data every 10 samples + Serial.printf("\033[2K Data Received: %d/%d\r", counter, hist.size()); + if ( counter % filter_k == 0) // send data every 10 samples { Serial.println(); LOG_DEBUG("Sending average ignition status to websocket clients..."); - auto msg = ign_info_avg.toJson().as(); - ws.textAll(msg); + webPage.sendWsData(ign_info_avg.toJson().as()); } } else diff --git a/RotaxMonitor/src/webserver.cpp b/RotaxMonitor/src/webserver.cpp index e69de29..937be9f 100644 --- a/RotaxMonitor/src/webserver.cpp +++ b/RotaxMonitor/src/webserver.cpp @@ -0,0 +1,98 @@ +#include + +WebPage::WebPage(const uint8_t port, fs::FS &filesystem) : m_port(port), m_webserver(AsyncWebServer(port)), m_websocket(AsyncWebSocket("/ws")), m_filesystem(filesystem) +{ + m_websocket.onEvent([this](AsyncWebSocket *server, AsyncWebSocketClient *client, + AwsEventType type, void *arg, uint8_t *data, size_t len) + { onWsEvent(server, client, type, arg, data, len); }); + + m_webserver.addHandler(&m_websocket); + m_webserver.serveStatic("/", m_filesystem, "/").setDefaultFile("index.html"); + + m_webserver.on("/upload", HTTP_POST, + [this](AsyncWebServerRequest *request) + { onUploadRequest(request); }, + [this](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) + { onUploadHandler(request, filename, index, data, len, final); } + ); + + m_webserver.begin(); +} + +WebPage::~WebPage() +{ + m_webserver.removeHandler(&m_websocket); + m_webserver.end(); +} + +void WebPage::sendWsData(const String &data){ + if (m_websocket.count()){ + m_websocket.textAll(data); + } +} + +void WebPage::onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) +{ + switch (type) + { + case WS_EVT_CONNECT: + Serial.printf("WS client IP[%s]-ID[%u] CONNECTED\r\n", client->remoteIP().toString().c_str(), client->id()); + break; + case WS_EVT_DISCONNECT: + Serial.printf("WS client ID[%u] DISCONNECTED\r\n", client->remoteIP().toString().c_str(), client->id()); + break; + } +} + +void WebPage::onUploadRequest(AsyncWebServerRequest *request) +{ + if (m_upload_failed) + request->send(500, "text/plain", "Upload failed"); + else + request->send(200, "text/plain", "Upload successful"); +} + +void WebPage::onUploadHandler(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) +{ + if (index == 0) // only on first iteration to open file + { + m_upload_failed = false; + String safeName = filename; + int slashIndex = safeName.lastIndexOf('/'); + if (slashIndex >= 0) + safeName = safeName.substring(slashIndex + 1); + if (safeName.length() == 0) + { + m_upload_failed = true; + LOG_ERROR("Invalid file name"); + return; + } + + const std::filesystem::path filePath = std::filesystem::path(m_filesystem.mountpoint()) / safeName.c_str(); + if (m_filesystem.exists(filePath.c_str())) + m_filesystem.remove(filePath.c_str()); + + m_upload_file = m_filesystem.open(filePath.c_str(), FILE_WRITE); + if (!m_upload_file) + { + m_upload_failed = true; + LOG_ERROR("Failed to open upload file:", filePath.c_str()); + return; + } + } + + // Actual write of file data + if (!m_upload_failed && m_upload_file) + { + if (m_upload_file.write(data, len) != len) + m_upload_failed = true; + } + + // close the file and save on final call + if (final && m_upload_file) + { + m_upload_file.close(); + if (!m_upload_failed) + LOG_INFO("Uploaded file to LittleFS:", filename.c_str()); + } +} diff --git a/RotaxMonitor/src/webserver.h b/RotaxMonitor/src/webserver.h index e69de29..5e230f3 100644 --- a/RotaxMonitor/src/webserver.h +++ b/RotaxMonitor/src/webserver.h @@ -0,0 +1,38 @@ +#pragma once +#define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO + +// System includes +#include +#include +#include +#include +#include +#include + +class WebPage +{ + const uint8_t m_port = 80; + fs::FS &m_filesystem; + AsyncWebServer m_webserver; + AsyncWebSocket m_websocket; + bool m_upload_failed = false; + fs::File m_upload_file; + +public: + WebPage(const uint8_t port, fs::FS &filesystem); + ~WebPage(); + + void sendWsData(const String &data); + +private: + void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, + AwsEventType type, void *arg, uint8_t *data, size_t len); + + void onUploadRequest(AsyncWebServerRequest *request); + void onUploadHandler(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final); + + void onStart(AsyncWebServerRequest *request); + void onStop(AsyncWebServerRequest *request); + void onDownload(AsyncWebServerRequest *request); + +}; From 575730a34054c54ec69a8590d9f099462af8f1a6 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Thu, 9 Apr 2026 15:54:59 +0200 Subject: [PATCH 16/38] Finalized PINMAP --- RotaxMonitor/data/index.html | 4 +- RotaxMonitor/data/style.css | 4 +- RotaxMonitor/src/main.cpp | 9 ++-- RotaxMonitor/src/pins.h | 97 ++++++++++++++++++------------------ RotaxMonitor/src/tasks.cpp | 24 +-------- RotaxMonitor/src/tasks.h | 6 +-- 6 files changed, 61 insertions(+), 83 deletions(-) diff --git a/RotaxMonitor/data/index.html b/RotaxMonitor/data/index.html index e1bc07c..31c61bf 100644 --- a/RotaxMonitor/data/index.html +++ b/RotaxMonitor/data/index.html @@ -11,7 +11,9 @@ diff --git a/RotaxMonitor/data/style.css b/RotaxMonitor/data/style.css index 11dd233..47ab887 100644 --- a/RotaxMonitor/data/style.css +++ b/RotaxMonitor/data/style.css @@ -1,6 +1,6 @@ :root { --primary-dark: #0a1929; - --primary-blue: #0144a8; + --primary-blue: #003585; --accent-blue: #1e88e5; --light-bg: #f5f7fa; --border-color: #d0d6dd; @@ -38,7 +38,7 @@ body { } .page-header h1 { - margin: 0; + margin: 5px; font-size: 28px; font-weight: 600; } diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 48af1a9..3157173 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -22,6 +22,7 @@ // #define CH_B_ENABLE #define TEST +// Debug Defines #define WIFI_SSID "AstroRotaxMonitor" #define WIFI_PASSWORD "maledettirotax" @@ -106,7 +107,7 @@ void loop() .trig_pin_34n = TRIG_PIN_A34N, .spark_pin_12 = SPARK_PIN_A12, .spark_pin_34 = SPARK_PIN_A34}, - .rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_A12P, .rst_io_12n = RST_EXT_A12N, .rst_io_34p = RST_EXT_A34P, .rst_io_34n = RST_EXT_A34N}}; + .rt_resets = rtTaskResets{.rst_io_peak= RST_EXT_PEAK_DETECT, .rst_io_sh = RST_EXT_SAMPLE_HOLD}}; if (!rt_taskA_queue || !rt_taskB_queue) { @@ -143,7 +144,7 @@ void loop() SPIClass SPI_A(FSPI); spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 -#ifndef TEST +#ifdef CH_B_ENABLE SPIClass SPI_B(HSPI); spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 @@ -158,12 +159,12 @@ void loop() LOG_DEBUG("Init SPI OK"); // Init ADC_A - dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADC_A_SYNC, ADC_A_CS, 2.5, &SPI_A); + dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); dev.adc_a->InitializeADC(); dev.adc_a->setPGA(PGA_1); dev.adc_a->setDRATE(DRATE_7500SPS); -#ifndef TEST +#ifdef CH_B_ENABLE // Init ADC_B dev.adc_a = new ADS1256(ADC_B_DRDY, ADC_B_RST, ADC_B_SYNC, ADC_B_CS, 2.5, &SPI_B); dev.adc_a->InitializeADC(); diff --git a/RotaxMonitor/src/pins.h b/RotaxMonitor/src/pins.h index 62a3ded..f5477eb 100644 --- a/RotaxMonitor/src/pins.h +++ b/RotaxMonitor/src/pins.h @@ -4,19 +4,19 @@ // ===================== // USB (RISERVATA) // ===================== -#define USB_DM 19 -#define USB_DP 20 +#define USB_DM 19 +#define USB_DP 20 // ===================== // UART DEBUG (RISERVATA) // ===================== -#define UART_TX 43 -#define UART_RX 44 +#define UART_TX 43 +#define UART_RX 44 // ===================== // RGB Led // ===================== -#define LED 48 +#define LED 48 // ===================== // STRAPPING CRITICI (NON USARE) @@ -26,85 +26,84 @@ // ===================== // SPI BUS ADC1 (VSPI) // ===================== -#define SPI_A_MOSI 11 -#define SPI_A_MISO 13 -#define SPI_A_SCK 12 +#define SPI_A_MOSI 10 +#define SPI_A_SCK 11 +#define SPI_A_MISO 12 // ===================== // SPI BUS ADC2 (HSPI) // ===================== -#define SPI_B_MOSI 35 -#define SPI_B_MISO 37 -#define SPI_B_SCK 36 +#define SPI_B_MOSI 36 +#define SPI_B_SCK 37 +#define SPI_B_MISO 38 // ===================== // I2C BUS (PCA9555) // ===================== -#define SDA 8 -#define SCL 9 +#define SDA 8 +#define SCL 9 +#define I2C_INT 17 // ===================== // ADC CONTROL // ===================== -#define ADC_A_CS 4 -#define ADC_A_DRDY 5 -#define ADC_A_SYNC 6 +#define ADC_A_CS 14 +#define ADC_A_DRDY 13 -#define ADC_B_CS 14 -#define ADC_B_DRDY 15 -#define ADC_B_SYNC 16 +#define ADC_B_CS 21 +#define ADC_B_DRDY 47 // ===================== // DIGITAL POT // ===================== -#define POT_A_CS 7 -#define POT_B_CS 17 +#define POT_A_CS 18 +#define POT_B_CS 35 // ===================== // TRIGGER INPUT INTERRUPTS // ===================== -#define TRIG_PIN_A12P 18 -#define TRIG_PIN_A12N 21 -#define TRIG_PIN_A34P 1 -#define TRIG_PIN_A34N 2 -#define TRIG_PIN_B12P 38 -#define TRIG_PIN_B12N 39 -#define TRIG_PIN_B34P 40 -#define TRIG_PIN_B34N 41 +#define TRIG_PIN_A12P 6 +#define TRIG_PIN_A12N 7 +#define TRIG_PIN_A34P 15 +#define TRIG_PIN_A34N 16 +#define TRIG_PIN_B12P 42 +#define TRIG_PIN_B12N 41 +#define TRIG_PIN_B34P 40 +#define TRIG_PIN_B34N 39 // ===================== // SPARK DETECT INPUTS // ===================== -#define SPARK_PIN_A12 42 -#define SPARK_PIN_A34 45 // OK (strapping ma consentito) 45 -#define SPARK_PIN_B12 46 // OK (strapping ma consentito) 46 -#define SPARK_PIN_B34 47 +#define SPARK_PIN_A12 4 +#define SPARK_PIN_A34 5 +#define SPARK_PIN_B12 1 +#define SPARK_PIN_B34 2 // ===================== // PCA9555 (I2C EXPANDER) // ===================== // --- RESET LINES --- -#define RST_EXT_A12P 0 -#define RST_EXT_A12N 1 -#define RST_EXT_A34P 2 -#define RST_EXT_A34N 3 -#define RST_EXT_B12P 4 -#define RST_EXT_B12N 5 -#define RST_EXT_B34P 6 -#define RST_EXT_B34N 7 +#define RST_EXT_PEAK_DETECT 0 +#define RST_EXT_SAMPLE_HOLD 1 +#define BTN_1 2 +#define BTN_2 3 +#define BTN_3 4 +#define BTN_4 5 +#define BTN_5 6 +#define BTN_6 7 // --- RELAY --- -#define A_EXT_RELAY 8 -#define B_EXT_RELAY 9 +#define A_EXT_RELAY 8 +#define B_EXT_RELAY 9 // --- STATUS / BUTTON --- -#define BTN_3 10 -#define BTN_4 11 -#define STA_1 12 -#define STA_2 13 -#define STA_3 14 -#define STA_4 15 +#define BTN_7 10 +#define BTN_8 11 +#define STA_1 12 +#define STA_2 13 +#define STA_3 14 +#define STA_4 15 // Init Pin Functions inline void initTriggerPinsInputs() diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 45a9aa0..8bbc8f2 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -78,13 +78,6 @@ void rtIgnitionTask(void *pvParameters) LOG_INFO("rtTask ISR Attach OK"); - // Compute Reset Pin Bitmask - const uint16_t rst_bitmask = (1 << rt_rst.rst_io_12p) | - (1 << rt_rst.rst_io_12n) | - (1 << rt_rst.rst_io_34p) | - (1 << rt_rst.rst_io_34n); - - LOG_WARN("rtTask Init Correct"); // Global rt_task_ptr variables bool first_cycle = true; bool cycle12 = false; @@ -107,22 +100,6 @@ void rtIgnitionTask(void *pvParameters) if (first_cycle && pickup_flag != TRIG_FLAG_12P) // skip first cycle because of possible initial noise on pickup signals at startu continue; -#ifdef DEBUG - Serial.print("\033[2J"); // clear screen - Serial.print("\033[H"); // cursor home - - if (!names.contains(pickup_flag)) - { - LOG_ERROR("Wrong Pickup Flag"); - LOG_ERROR("Pickup Flags: ", printBits(pickup_flag).c_str()); - continue; - } - else - { - LOG_INFO("Pickup Trigger: ", names.at(pickup_flag)); - } -#endif - // Start microsecond precision timeout timer esp_timer_stop(timeout_timer); // stop timer in case it was running from previous cycle esp_timer_start_once(timeout_timer, spark_timeout_max); @@ -257,6 +234,7 @@ void rtIgnitionTask(void *pvParameters) if (io) { const uint16_t iostat = io->read(); + const uint16_t rst_bitmask = (0x0001 << rt_rst.rst_io_peak); io->write(iostat | rst_bitmask); vTaskDelay(pdMS_TO_TICKS(1)); io->write(iostat & ~rst_bitmask); diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index c1196eb..e5152ec 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -46,10 +46,8 @@ struct rtTaskInterrupts // RT Task Peak Detector Reset pins struct rtTaskResets { - const uint8_t rst_io_12p; - const uint8_t rst_io_12n; - const uint8_t rst_io_34p; - const uint8_t rst_io_34n; + const uint8_t rst_io_peak; + const uint8_t rst_io_sh; }; // RT task parameters From 2083119d79dd85159bf4d914ffe24cb169c0aa70 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 10 Apr 2026 09:27:41 +0200 Subject: [PATCH 17/38] Updated interface to show Box A+B --- RotaxMonitor/data/index.html | 218 ++++++++++++++++++++++++----------- RotaxMonitor/data/script.js | 95 ++++++++++----- RotaxMonitor/data/style.css | 49 +++++++- 3 files changed, 261 insertions(+), 101 deletions(-) diff --git a/RotaxMonitor/data/index.html b/RotaxMonitor/data/index.html index 31c61bf..fea8b87 100644 --- a/RotaxMonitor/data/index.html +++ b/RotaxMonitor/data/index.html @@ -13,6 +13,7 @@
+

Rotax Ignition Box Monitor

@@ -21,75 +22,156 @@ Waiting for data... -
-

Timestamp: -

-

Data Valid: -

-

Generator voltage: -

-

Engine RPM: -

-

ADC read time: -

-

Queue errors: -

+
+
+

Box_A

+
+

Timestamp: -

+

Data Valid: -

+

Generator voltage: -

+

ADC read time: -

+

Queue errors: -

+
+
+ Engine RPM: - +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyPickup 12Pickup 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Spark Events--
Missed Events--
+
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyPickup 12Pickup 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Spark Events--
Missed Events--
+
+

Box_B

+
+

Timestamp: -

+

Data Valid: -

+

Generator voltage: -

+

ADC read time: -

+

Queue errors: -

+
+
+ Engine RPM: - +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyPickup 12Pickup 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Spark Events--
Missed Events--
+
diff --git a/RotaxMonitor/data/script.js b/RotaxMonitor/data/script.js index 779c224..5ea3c66 100644 --- a/RotaxMonitor/data/script.js +++ b/RotaxMonitor/data/script.js @@ -46,36 +46,75 @@ function connectWS() { lastMessageTimestamp = Date.now(); setLoadingIndicator(false); - document.getElementById("datavalid").textContent = data.datavalid ?? "-"; - document.getElementById("timestamp").textContent = data.timestamp ?? "-"; - document.getElementById("volts_gen").textContent = data.volts_gen ?? "-"; - document.getElementById("eng_rpm").textContent = data.eng_rpm ?? "-"; - document.getElementById("adc_read_time").textContent = data.adc_read_time ?? "-"; - document.getElementById("n_queue_errors").textContent = data.n_queue_errors ?? "-"; + // Update Box_A + if (data.box_a) { + const boxA = data.box_a; + document.getElementById("datavalid").textContent = boxA.datavalid ?? "-"; + document.getElementById("timestamp").textContent = boxA.timestamp ?? "-"; + document.getElementById("volts_gen").textContent = boxA.volts_gen ?? "-"; + document.getElementById("eng_rpm").textContent = boxA.eng_rpm ?? "-"; + document.getElementById("adc_read_time").textContent = boxA.adc_read_time ?? "-"; + document.getElementById("n_queue_errors").textContent = boxA.n_queue_errors ?? "-"; - const coils12 = data.coils12 || {}; - const coils34 = data.coils34 || {}; + const coils12A = boxA.coils12 || {}; + const coils34A = boxA.coils34 || {}; - document.getElementById("coils12_spark_delay").textContent = coils12.spark_delay ?? "-"; - document.getElementById("coils34_spark_delay").textContent = coils34.spark_delay ?? "-"; - document.getElementById("coils12_spark_status").textContent = coils12.spark_status ?? "-"; - document.getElementById("coils34_spark_status").textContent = coils34.spark_status ?? "-"; - document.getElementById("coils12_sstart_status").textContent = coils12.sstart_status ?? "-"; - document.getElementById("coils34_sstart_status").textContent = coils34.sstart_status ?? "-"; - document.getElementById("coils12_peak_p_in").textContent = coils12.peak_p_in ?? "-"; - document.getElementById("coils34_peak_p_in").textContent = coils34.peak_p_in ?? "-"; - document.getElementById("coils12_peak_n_in").textContent = coils12.peak_n_in ?? "-"; - document.getElementById("coils34_peak_n_in").textContent = coils34.peak_n_in ?? "-"; - document.getElementById("coils12_peak_p_out").textContent = coils12.peak_p_out ?? "-"; - document.getElementById("coils34_peak_p_out").textContent = coils34.peak_p_out ?? "-"; - document.getElementById("coils12_peak_n_out").textContent = coils12.peak_n_out ?? "-"; - document.getElementById("coils34_peak_n_out").textContent = coils34.peak_n_out ?? "-"; - document.getElementById("coils12_level_spark").textContent = coils12.level_spark ?? "-"; - document.getElementById("coils34_level_spark").textContent = coils34.level_spark ?? "-"; - document.getElementById("coils12_n_events").textContent = coils12.n_events ?? "-"; - document.getElementById("coils34_n_events").textContent = coils34.n_events ?? "-"; - document.getElementById("coils12_n_missed_firing").textContent = coils12.n_missed_firing ?? "-"; - document.getElementById("coils34_n_missed_firing").textContent = coils34.n_missed_firing ?? "-"; + document.getElementById("coils12_spark_delay").textContent = coils12A.spark_delay ?? "-"; + document.getElementById("coils34_spark_delay").textContent = coils34A.spark_delay ?? "-"; + document.getElementById("coils12_spark_status").textContent = coils12A.spark_status ?? "-"; + document.getElementById("coils34_spark_status").textContent = coils34A.spark_status ?? "-"; + document.getElementById("coils12_sstart_status").textContent = coils12A.sstart_status ?? "-"; + document.getElementById("coils34_sstart_status").textContent = coils34A.sstart_status ?? "-"; + document.getElementById("coils12_peak_p_in").textContent = coils12A.peak_p_in ?? "-"; + document.getElementById("coils34_peak_p_in").textContent = coils34A.peak_p_in ?? "-"; + document.getElementById("coils12_peak_n_in").textContent = coils12A.peak_n_in ?? "-"; + document.getElementById("coils34_peak_n_in").textContent = coils34A.peak_n_in ?? "-"; + document.getElementById("coils12_peak_p_out").textContent = coils12A.peak_p_out ?? "-"; + document.getElementById("coils34_peak_p_out").textContent = coils34A.peak_p_out ?? "-"; + document.getElementById("coils12_peak_n_out").textContent = coils12A.peak_n_out ?? "-"; + document.getElementById("coils34_peak_n_out").textContent = coils34A.peak_n_out ?? "-"; + document.getElementById("coils12_level_spark").textContent = coils12A.level_spark ?? "-"; + document.getElementById("coils34_level_spark").textContent = coils34A.level_spark ?? "-"; + document.getElementById("coils12_n_events").textContent = coils12A.n_events ?? "-"; + document.getElementById("coils34_n_events").textContent = coils34A.n_events ?? "-"; + document.getElementById("coils12_n_missed_firing").textContent = coils12A.n_missed_firing ?? "-"; + document.getElementById("coils34_n_missed_firing").textContent = coils34A.n_missed_firing ?? "-"; + } + + // Update Box_B + if (data.box_b) { + const boxB = data.box_b; + document.getElementById("b_datavalid").textContent = boxB.datavalid ?? "-"; + document.getElementById("b_timestamp").textContent = boxB.timestamp ?? "-"; + document.getElementById("b_volts_gen").textContent = boxB.volts_gen ?? "-"; + document.getElementById("b_eng_rpm").textContent = boxB.eng_rpm ?? "-"; + document.getElementById("b_adc_read_time").textContent = boxB.adc_read_time ?? "-"; + document.getElementById("b_n_queue_errors").textContent = boxB.n_queue_errors ?? "-"; + + const coils12B = boxB.coils12 || {}; + const coils34B = boxB.coils34 || {}; + + document.getElementById("b_coils12_spark_delay").textContent = coils12B.spark_delay ?? "-"; + document.getElementById("b_coils34_spark_delay").textContent = coils34B.spark_delay ?? "-"; + document.getElementById("b_coils12_spark_status").textContent = coils12B.spark_status ?? "-"; + document.getElementById("b_coils34_spark_status").textContent = coils34B.spark_status ?? "-"; + document.getElementById("b_coils12_sstart_status").textContent = coils12B.sstart_status ?? "-"; + document.getElementById("b_coils34_sstart_status").textContent = coils34B.sstart_status ?? "-"; + document.getElementById("b_coils12_peak_p_in").textContent = coils12B.peak_p_in ?? "-"; + document.getElementById("b_coils34_peak_p_in").textContent = coils34B.peak_p_in ?? "-"; + document.getElementById("b_coils12_peak_n_in").textContent = coils12B.peak_n_in ?? "-"; + document.getElementById("b_coils34_peak_n_in").textContent = coils34B.peak_n_in ?? "-"; + document.getElementById("b_coils12_peak_p_out").textContent = coils12B.peak_p_out ?? "-"; + document.getElementById("b_coils34_peak_p_out").textContent = coils34B.peak_p_out ?? "-"; + document.getElementById("b_coils12_peak_n_out").textContent = coils12B.peak_n_out ?? "-"; + document.getElementById("b_coils34_peak_n_out").textContent = coils34B.peak_n_out ?? "-"; + document.getElementById("b_coils12_level_spark").textContent = coils12B.level_spark ?? "-"; + document.getElementById("b_coils34_level_spark").textContent = coils34B.level_spark ?? "-"; + document.getElementById("b_coils12_n_events").textContent = coils12B.n_events ?? "-"; + document.getElementById("b_coils34_n_events").textContent = coils34B.n_events ?? "-"; + document.getElementById("b_coils12_n_missed_firing").textContent = coils12B.n_missed_firing ?? "-"; + document.getElementById("b_coils34_n_missed_firing").textContent = coils34B.n_missed_firing ?? "-"; + } }; } diff --git a/RotaxMonitor/data/style.css b/RotaxMonitor/data/style.css index 47ab887..749df1f 100644 --- a/RotaxMonitor/data/style.css +++ b/RotaxMonitor/data/style.css @@ -35,10 +35,13 @@ body { .logo { height: 50px; width: auto; + margin: auto; } .page-header h1 { - margin: 5px; + margin: auto; + margin-top: 20px; + text-align: center; font-size: 28px; font-weight: 600; } @@ -159,21 +162,57 @@ button:hover { } } -/* Data section */ -div[style*="max-width: 900px"] { +.tables-container { + display: flex; + gap: 20px; + max-width: 1800px; + margin: 0 auto; + padding: 0 20px; +} + +.box { + flex: 1; background: white; padding: 20px; border-radius: 6px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); +} + +.box h2 { + margin-top: 0; + margin-bottom: 16px; + color: var(--primary-blue); + font-size: 18px; + font-weight: 700; + text-align: center; +} + +.box-data { margin-bottom: 20px; } -div[style*="max-width: 900px"] p { +.box-data p { margin: 8px 0; font-size: 14px; } -div[style*="max-width: 900px"] strong { +.box-data strong { + color: var(--primary-blue); +} + +.rpm-highlight { + background: #c6e4fa; + border: 3px double var(--primary-blue); + border-radius: 8px; + padding: 12px 16px; + margin-bottom: 20px; + text-align: center; + font-size: 18px; + font-weight: bold; + color: var(--text-dark); +} + +.rpm-highlight strong { color: var(--primary-blue); } From 736a8d8bd5e7594d4aafa09ed7016ef4d766c1f1 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 10 Apr 2026 12:12:28 +0200 Subject: [PATCH 18/38] modified to also read channel B --- RotaxMonitor/platformio.ini | 2 +- RotaxMonitor/src/datastruct.h | 5 ++ RotaxMonitor/src/isr.cpp | 53 +++++++++++- RotaxMonitor/src/isr.h | 3 +- RotaxMonitor/src/main.cpp | 144 ++++++++++++++++++++----------- RotaxMonitor/src/pins.h | 12 +-- RotaxMonitor/src/pins_test.h | 2 +- RotaxMonitor/src/psvector.h | 3 - RotaxMonitor/src/utils.h | 7 ++ RotaxMonitorTester/src/main.cpp | 46 +++++++++- RotaxMonitorTester/src/timer.cpp | 57 ++++-------- RotaxMonitorTester/src/timer.h | 12 +++ 12 files changed, 241 insertions(+), 105 deletions(-) diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 4a09e62..4b5097f 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -27,7 +27,7 @@ monitor_port = COM4 monitor_speed = 921600 build_type = release build_flags = - -DCORE_DEBUG_LEVEL=1 + -DCORE_DEBUG_LEVEL=4 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 diff --git a/RotaxMonitor/src/datastruct.h b/RotaxMonitor/src/datastruct.h index 9936313..5ded4d2 100644 --- a/RotaxMonitor/src/datastruct.h +++ b/RotaxMonitor/src/datastruct.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include // ===================== // Event Flags (bitmask) @@ -88,3 +89,7 @@ struct ignitionBoxStatus uint32_t n_queue_errors = 0; int32_t adc_read_time = 0; }; + + +template +using PSRAMVector = std::vector>; diff --git a/RotaxMonitor/src/isr.cpp b/RotaxMonitor/src/isr.cpp index aedd47c..c87ad0b 100644 --- a/RotaxMonitor/src/isr.cpp +++ b/RotaxMonitor/src/isr.cpp @@ -4,7 +4,7 @@ // ISR (Pass return bitmask to ISR management function) // one function for each wake up pin conncted to a trigger // ===================== -void trig_isr(void *arg) +void trig_isr_A(void *arg) { const int64_t time_us = esp_timer_get_time(); @@ -50,4 +50,53 @@ void trig_isr(void *arg) if (xHigherPriorityTaskWoken) portYIELD_FROM_ISR(); -} \ No newline at end of file +} + + +void trig_isr_B(void *arg) +{ + const int64_t time_us = esp_timer_get_time(); + + // exit if invalid args + if (!arg) + return; + + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + isrParams *params = (isrParams *)arg; + ignitionBoxStatus *box = params->ign_stat; + TaskHandle_t task_handle = params->rt_handle_ptr; + + // exit if task not running + if (!task_handle) + return; + + switch (params->flag) + { + case TRIG_FLAG_12P: + case TRIG_FLAG_12N: + // only on first trigger to avoid multiple firing due to noise, to be fixed with hardware debounce + box->coils12.trig_time = time_us; + xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); + break; + case TRIG_FLAG_34P: + case TRIG_FLAG_34N: + // only on first trigger to avoid multiple firing due to noise, to be fixed with hardware debounce + box->coils34.trig_time = time_us; + xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); + break; + case SPARK_FLAG_12: + + box->coils12.spark_time = time_us; + xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); + break; + case SPARK_FLAG_34: + box->coils34.spark_time = time_us; + xTaskNotifyFromISR(task_handle, params->flag, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); + break; + default: + break; + } + + if (xHigherPriorityTaskWoken) + portYIELD_FROM_ISR(); +} diff --git a/RotaxMonitor/src/isr.h b/RotaxMonitor/src/isr.h index efb118c..ed2e4d1 100644 --- a/RotaxMonitor/src/isr.h +++ b/RotaxMonitor/src/isr.h @@ -26,4 +26,5 @@ struct isrParams TaskHandle_t rt_handle_ptr; }; -void IRAM_ATTR trig_isr(void *arg); +void IRAM_ATTR trig_isr_A(void *arg); +void IRAM_ATTR trig_isr_B(void *arg); diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 3157173..cf1cd4c 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -19,6 +19,7 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +// Defines to enable channel B // #define CH_B_ENABLE #define TEST @@ -81,35 +82,60 @@ void loop() bool running = true; const uint32_t max_queue = 128; const uint32_t filter_k = 10; + PSRAMVector ignA_history_0(max_history); PSRAMVector ignA_history_1(max_history); - auto *active_history = &ignA_history_0; - auto *writable_history = &ignA_history_1; + auto *active_history_A = &ignA_history_0; + auto *writable_history_A = &ignA_history_1; + +#ifdef CH_B_ENABLE + PSRAMVector ignB_history_0(max_history); + PSRAMVector ignB_history_1(max_history); + auto *active_history_B = &ignB_history_0; + auto *writable_history_B = &ignB_history_1; +#endif // Resources Initialization Devices dev; // Task handle TaskHandle_t trigA_TaskHandle = NULL; - TaskHandle_t trigB_TaskHandle = NULL; // Data Queue for real time task to main loop communication QueueHandle_t rt_taskA_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); - QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); rtTaskParams taskA_params{ .rt_running = true, .dev = &dev, .rt_handle_ptr = &trigA_TaskHandle, .rt_queue = rt_taskA_queue, .rt_int = rtTaskInterrupts{ - .isr_ptr = trig_isr, + .isr_ptr = trig_isr_A, .trig_pin_12p = TRIG_PIN_A12P, .trig_pin_12n = TRIG_PIN_A12N, .trig_pin_34p = TRIG_PIN_A34P, .trig_pin_34n = TRIG_PIN_A34N, .spark_pin_12 = SPARK_PIN_A12, .spark_pin_34 = SPARK_PIN_A34}, - .rt_resets = rtTaskResets{.rst_io_peak= RST_EXT_PEAK_DETECT, .rst_io_sh = RST_EXT_SAMPLE_HOLD}}; + .rt_resets = rtTaskResets{.rst_io_peak = RST_EXT_PEAK_DETECT_A, .rst_io_sh = RST_EXT_SAMPLE_HOLD_A}}; - if (!rt_taskA_queue || !rt_taskB_queue) +#ifdef CH_B_ENABLE + TaskHandle_t trigB_TaskHandle = NULL; + QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); + rtTaskParams taskB_params{ + .rt_running = true, + .dev = &dev, + .rt_handle_ptr = &trigB_TaskHandle, + .rt_queue = rt_taskB_queue, + .rt_int = rtTaskInterrupts{ + .isr_ptr = trig_isr_B, + .trig_pin_12p = TRIG_PIN_B12P, + .trig_pin_12n = TRIG_PIN_B12N, + .trig_pin_34p = TRIG_PIN_B34P, + .trig_pin_34n = TRIG_PIN_B34N, + .spark_pin_12 = SPARK_PIN_B12, + .spark_pin_34 = SPARK_PIN_B34}, + .rt_resets = rtTaskResets{.rst_io_peak = RST_EXT_PEAK_DETECT_B, .rst_io_sh = RST_EXT_SAMPLE_HOLD_B}}; +#endif + + if (!rt_taskA_queue /*|| !rt_taskB_queue*/) { LOG_ERROR("Unable To Create task queues"); LOG_ERROR("5 seconds to restart..."); @@ -119,24 +145,6 @@ void loop() else LOG_DEBUG("Task Variables OK"); -#ifdef CH_B_ENABLE - QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); - rtTaskParams taskB_params{ - .rt_running = true, - .dev = &dev, - .rt_handle_ptr = &trigB_TaskHandle, - .rt_queue = rt_taskB_queue, - .rt_int = rtTaskInterrupts{ - .isr_ptr = trig_isr, - .trig_pin_12p = TRIG_PIN_B12P, - .trig_pin_12n = TRIG_PIN_B12N, - .trig_pin_34p = TRIG_PIN_B34P, - .trig_pin_34n = TRIG_PIN_B34N, - .spark_pin_12 = SPARK_PIN_B12, - .spark_pin_34 = SPARK_PIN_B34}, - .rt_resets = rtTaskResets{.rst_io_12p = RST_EXT_B12P, .rst_io_12n = RST_EXT_B12N, .rst_io_34p = RST_EXT_B34P, .rst_io_34n = RST_EXT_B34N}}; -#endif - // Spi ok flags bool spiA_ok = true; bool spiB_ok = true; @@ -145,9 +153,11 @@ void loop() spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 #ifdef CH_B_ENABLE +#ifndef TEST SPIClass SPI_B(HSPI); spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 +#endif #endif if (!spiA_ok || !spiB_ok) { @@ -158,18 +168,21 @@ void loop() } LOG_DEBUG("Init SPI OK"); +#ifndef TEST // Init ADC_A dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); dev.adc_a->InitializeADC(); dev.adc_a->setPGA(PGA_1); dev.adc_a->setDRATE(DRATE_7500SPS); - +#endif #ifdef CH_B_ENABLE +#ifndef TEST // Init ADC_B - dev.adc_a = new ADS1256(ADC_B_DRDY, ADC_B_RST, ADC_B_SYNC, ADC_B_CS, 2.5, &SPI_B); + dev.adc_a = new ADS1256(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); dev.adc_a->InitializeADC(); dev.adc_a->setPGA(PGA_1); dev.adc_a->setDRATE(DRATE_1000SPS); +#endif #endif LOG_DEBUG("Init ADC OK"); @@ -178,7 +191,7 @@ void loop() auto ignA_task_success = pdPASS; ignA_task_success = xTaskCreatePinnedToCore( rtIgnitionTask, - "rtIgnitionTask_boxA", + "rtTask_A", RT_TASK_STACK, (void *)&taskA_params, RT_TASK_PRIORITY, @@ -188,15 +201,16 @@ void loop() // Ignition B on Core 1 auto ignB_task_success = pdPASS; + #ifdef CH_B_ENABLE ignB_task_success = xTaskCreatePinnedToCore( rtIgnitionTask, - "rtIgnitionTask_boxB", + "rtTask_B", RT_TASK_STACK, (void *)&taskB_params, RT_TASK_PRIORITY, // priorità leggermente più alta &trigB_TaskHandle, - CORE_1); + CORE_0); delay(100); // give some time to the thread to start #endif @@ -214,49 +228,75 @@ void loop() bool partial_save = false; // flag to indicate if a partial save has been done after a timeout uint32_t counter = 0; uint32_t wait_count = 0; - ignitionBoxStatus ign_info; - ignitionBoxStatusAverage ign_info_avg(filter_k); + ignitionBoxStatus ign_info_A; + ignitionBoxStatus ign_info_B; + ignitionBoxStatusAverage ign_info_avg_A(filter_k); + ignitionBoxStatusAverage ign_info_avg_B(filter_k); LITTLEFSGuard fsGuard; WebPage webPage(80, LittleFS); // Initialize webserver and Websocket while (running) { - if (counter >= active_history->size()) // not concurrent with write task + auto dataA = pdFALSE; + auto dataB = pdFALSE; + + if (counter >= active_history_A->size()) // not concurrent with write task { counter = 0; partial_save = false; // reset partial save flag on new data cycle - auto *temp = active_history; - active_history = writable_history; // switch active and writable buffers - writable_history = temp; // ensure writable_history points to the buffer we just filled - dataSaveParams save_params{ - .history = writable_history, - .file_path = "ignition_history.csv"}; - save_history(*writable_history, "ignition_history.csv"); // directly call the save task function to save without delay + swapHistory(active_history_A, writable_history_A); + save_history(*writable_history_A, "ignition_historyA.csv"); // directly call the save task function to save without delay } + dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, pdMS_TO_TICKS(100)); +#ifdef CH_B_ENABLE + if (counter >= active_history_B->size()) // not concurrent with write task + { + counter = 0; + partial_save = false; // reset partial save flag on new data cycle + swapHistory(active_history_B, writable_history_B); + save_history(*writable_history_B, "ignition_historyB.csv"); // directly call the save task function to save without delay + } + dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, pdMS_TO_TICKS(100)); +#endif - if (xQueueReceive(rt_taskA_queue, &ign_info, pdMS_TO_TICKS(1000)) == pdTRUE) + if (dataA == pdTRUE || dataB == pdTRUE) { // printInfo(ign_info); - auto &hist = *active_history; - hist[counter++ % active_history->size()] = ign_info; - ign_info_avg.update(ign_info); // update moving average with latest ignition status - Serial.printf("\033[2K Data Received: %d/%d\r", counter, hist.size()); - if ( counter % filter_k == 0) // send data every 10 samples + (*active_history_A)[counter % active_history_A->size()] = ign_info_A; +#ifdef CH_B_ENABLE + (*active_history_B)[counter % active_history_B->size()] = ign_info_B; +#endif + ign_info_avg_A.update(ign_info_A); // update moving average with latest ignition status + ign_info_avg_B.update(ign_info_B); // update moving average with latest ignition status + + Serial.printf("\033[2K Data Received A: %d/%d\r", counter, (*active_history_A).size()); + + if (counter % filter_k == 0) // send data every 10 samples { Serial.println(); LOG_DEBUG("Sending average ignition status to websocket clients..."); - webPage.sendWsData(ign_info_avg.toJson().as()); + ArduinoJson::JsonDocument wsData; + wsData["box_a"] = ign_info_avg_A.toJson(); + wsData["box_b"] = ign_info_avg_B.toJson(); + webPage.sendWsData(wsData.as()); } + + counter++; } else { Serial.printf("[%d] Waiting for data...\r", wait_count++); if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout { - active_history->resize(counter); // resize active history to actual number of records received to avoid saving empty records - save_history(*active_history, "ignition_history.csv"); - active_history->resize(max_history); // resize back to max history size for next data cycle - counter = 0; // reset counter after saving + active_history_A->resize(counter); // resize active history to actual number of records received to avoid saving empty records + save_history(*active_history_A, "ignition_history_A.csv"); + active_history_A->resize(max_history); // resize back to max history size for next data cycle +#ifdef CH_B_ENABLE + active_history_B->resize(counter); // resize active history to actual number of records received to avoid saving empty records + save_history(*active_history_B, "ignition_history_B.csv"); + active_history_B->resize(max_history); // resize back to max history size for next data cycle +#endif + counter = 0; // reset counter after saving partial_save = true; first_save = true; } @@ -266,7 +306,9 @@ void loop() if (trigA_TaskHandle) vTaskDelete(trigA_TaskHandle); +#ifdef CH_B_ENABLE if (trigB_TaskHandle) vTaskDelete(trigB_TaskHandle); +#endif ////////////////////// MAIN LOOP ////////////////////// } diff --git a/RotaxMonitor/src/pins.h b/RotaxMonitor/src/pins.h index f5477eb..4d93ef3 100644 --- a/RotaxMonitor/src/pins.h +++ b/RotaxMonitor/src/pins.h @@ -84,18 +84,18 @@ // ===================== // --- RESET LINES --- -#define RST_EXT_PEAK_DETECT 0 -#define RST_EXT_SAMPLE_HOLD 1 -#define BTN_1 2 -#define BTN_2 3 +#define RST_EXT_PEAK_DETECT_A 0 +#define RST_EXT_SAMPLE_HOLD_A 1 +#define RST_EXT_PEAK_DETECT_B 2 +#define RST_EXT_SAMPLE_HOLD_B 3 #define BTN_3 4 #define BTN_4 5 #define BTN_5 6 #define BTN_6 7 // --- RELAY --- -#define A_EXT_RELAY 8 -#define B_EXT_RELAY 9 +#define EXT_RELAY_A 8 +#define EXT_RELAY_B 9 // --- STATUS / BUTTON --- #define BTN_7 10 diff --git a/RotaxMonitor/src/pins_test.h b/RotaxMonitor/src/pins_test.h index 4db981f..16f196e 100644 --- a/RotaxMonitor/src/pins_test.h +++ b/RotaxMonitor/src/pins_test.h @@ -65,7 +65,7 @@ #define RST_EXT_A34N 3 // --- RELAY --- -#define A_EXT_RELAY 8 +#define EXT_RELAY_A 8 // Init Pin Functions diff --git a/RotaxMonitor/src/psvector.h b/RotaxMonitor/src/psvector.h index 43d9cf7..2bf2013 100644 --- a/RotaxMonitor/src/psvector.h +++ b/RotaxMonitor/src/psvector.h @@ -25,6 +25,3 @@ struct PSRAMAllocator { heap_caps_free(p); } }; - -template -using PSRAMVector = std::vector>; diff --git a/RotaxMonitor/src/utils.h b/RotaxMonitor/src/utils.h index 2a1bf71..40a745e 100644 --- a/RotaxMonitor/src/utils.h +++ b/RotaxMonitor/src/utils.h @@ -2,5 +2,12 @@ #include #include +#include std::string printBits(uint32_t value); + +inline void swapHistory(PSRAMVector* active, PSRAMVector* writable) { + auto *temp = active; + active = writable; // switch active and writable buffers + writable = temp; // ensure writable_history points to the buffer we just filled +} diff --git a/RotaxMonitorTester/src/main.cpp b/RotaxMonitorTester/src/main.cpp index 27744ef..eadb954 100644 --- a/RotaxMonitorTester/src/main.cpp +++ b/RotaxMonitorTester/src/main.cpp @@ -1,3 +1,5 @@ +#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG + #include #include @@ -52,6 +54,31 @@ static timerStatus stsA = { .coil_pulse_us = 1000, .spark_pulse_us = 100, .spark_delay_us = 50, + .pins = { + .pin_trig_12p = PIN_TRIG_A12P, + .pin_trig_12n = PIN_TRIG_A12N, + .pin_trig_34p = PIN_TRIG_A34P, + .pin_trig_34n = PIN_TRIG_A34N, + .pin_spark_12 = SPARK_A12, + .pin_spark_34 = SPARK_A34 + }, + .main_task = NULL}; + +static timerStatus stsB = { + .clock_period_us = (uint32_t)PERIOD_US, + .pause_long_us = 10000, + .pause_short_us = 1000, + .coil_pulse_us = 1000, + .spark_pulse_us = 100, + .spark_delay_us = 50, + .pins = { + .pin_trig_12p = PIN_TRIG_B12P, + .pin_trig_12n = PIN_TRIG_B12N, + .pin_trig_34p = PIN_TRIG_B34P, + .pin_trig_34n = PIN_TRIG_B34N, + .pin_spark_12 = SPARK_B12, + .pin_spark_34 = SPARK_B34 + }, .main_task = NULL}; static bool isEnabled = false; @@ -82,12 +109,23 @@ void setup() pinMode(ENABLE_PIN, INPUT_PULLUP); + // get the task handle for the main loop stsA.main_task = xTaskGetCurrentTaskHandleForCore(1); + stsB.main_task = xTaskGetCurrentTaskHandleForCore(1); + // Begin timer with preset fixed frequency timerA = timerBegin(FREQUENCY); + timerB = timerBegin(FREQUENCY); + + // Stop timers because of autostart timerStop(timerA); + timerStop(timerB); + + // Attach interrupts and call callback every timer expiry timerAttachInterruptArg(timerA, &onTimer, (void *)&stsA); - timerAlarm(timerA, 1, true, 0); + timerAttachInterruptArg(timerB, &onTimer, (void *)&stsB); + timerAlarm(timerA, 1, true, 0); // infinite number of reloads + timerAlarm(timerB, 1, true, 0); LOG_INFO("Setup Complete"); } @@ -103,10 +141,13 @@ void loop() } else { stsA.soft_start = false; } + stsB.soft_start = stsA.soft_start; + stsB.spark_delay_us = stsA.spark_delay_us; double new_rpm = (double)(map(analogRead(FREQ_POT), 0, 4096, RPM_MIN, RPM_MAX)); filtered_rpm = filtered_rpm + 0.1 * (new_rpm - filtered_rpm); stsA.pause_long_us = (uint32_t)(60000000.0f / filtered_rpm / 2.0f); + stsB.pause_long_us = stsA.pause_long_us; if (isEnabled) { LOG_INFO("==== System is ENABLED ===="); @@ -121,8 +162,11 @@ void loop() if (digitalRead(ENABLE_PIN) == LOW && !isEnabled) { timerStart(timerA); + delayMicroseconds(50); + timerStart(timerB); isEnabled = true; } else if (digitalRead(ENABLE_PIN) == HIGH && isEnabled) { + timerStop(timerA); timerStop(timerA); isEnabled = false; } diff --git a/RotaxMonitorTester/src/timer.cpp b/RotaxMonitorTester/src/timer.cpp index 6504230..90c1ba3 100644 --- a/RotaxMonitorTester/src/timer.cpp +++ b/RotaxMonitorTester/src/timer.cpp @@ -7,20 +7,18 @@ void onTimer(void *arg) BaseType_t xHigherPriorityTaskWoken = pdFALSE; timerStatus *params = (timerStatus *)(arg); TaskHandle_t task = params->main_task; + const timerPins pins = params->pins; // increment state time params->state_time += params->clock_period_us; - digitalWrite(PIN_TRIG_B12P, HIGH); - switch (params->state) { case S_12P: if (params->state_time == params->clock_period_us && !params->coil12p_high) { - // xTaskNotifyFromISR(task, PIN_TRIG_A12P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(PIN_TRIG_A12P, HIGH); + digitalWrite(pins.pin_trig_12p, HIGH); params->coil12p_high = true; wait_sent = false; } @@ -29,21 +27,18 @@ void onTimer(void *arg) { if (params->state_time == params->spark_delay_us) { - // xTaskNotifyFromISR(task, SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(SPARK_A12, HIGH); + digitalWrite(pins.pin_spark_12, HIGH); } if (params->state_time == (params->spark_delay_us + params->spark_pulse_us)) { - // xTaskNotifyFromISR(task, ~SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(SPARK_A12, LOW); + digitalWrite(pins.pin_spark_12, LOW); } } if (params->state_time >= params->coil_pulse_us && params->coil12p_high) { - // xTaskNotifyFromISR(task, ~PIN_TRIG_A12P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(PIN_TRIG_A12P, LOW); + digitalWrite(pins.pin_trig_12p, LOW); params->coil12p_high = false; } @@ -57,8 +52,7 @@ void onTimer(void *arg) case S_12N: if (params->state_time == params->clock_period_us && !params->coil12n_high) { - // xTaskNotifyFromISR(task, PIN_TRIG_A12N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(PIN_TRIG_A12N, HIGH); + digitalWrite(pins.pin_trig_12n, HIGH); params->coil12n_high = true; } @@ -66,21 +60,18 @@ void onTimer(void *arg) { if (params->state_time == params->spark_delay_us) { - // xTaskNotifyFromISR(task, SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(SPARK_A12, HIGH); + digitalWrite(pins.pin_spark_12, HIGH); } if (params->state_time == (params->spark_delay_us + params->spark_pulse_us)) { - // xTaskNotifyFromISR(task, ~SPARK_A12, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(SPARK_A12, LOW); + digitalWrite(pins.pin_spark_12, LOW); } } if (params->state_time >= params->coil_pulse_us && params->coil12n_high) { - // xTaskNotifyFromISR(task, ~PIN_TRIG_A12N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(PIN_TRIG_A12N, LOW); + digitalWrite(pins.pin_trig_12n, LOW); params->coil12n_high = false; params->state = S_WAIT_10MS; params->state_time = 0; @@ -90,7 +81,6 @@ void onTimer(void *arg) case S_WAIT_10MS: if (!wait_sent) { - // xTaskNotifyFromISR(task, S_WAIT_10MS, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); wait_sent = true; } if (params->state_time >= params->pause_long_us) @@ -103,8 +93,7 @@ void onTimer(void *arg) case S_34P: if (params->state_time == params->clock_period_us && !params->coil34p_high) { - // xTaskNotifyFromISR(task, PIN_TRIG_A34P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(PIN_TRIG_A34P, HIGH); + digitalWrite(pins.pin_trig_34p, HIGH); params->coil34p_high = true;; wait_sent = false; } @@ -113,21 +102,18 @@ void onTimer(void *arg) { if (params->state_time == params->spark_delay_us) { - // xTaskNotifyFromISR(task, SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(SPARK_A34, HIGH); + digitalWrite(pins.pin_spark_34, HIGH); } if (params->state_time == params->spark_delay_us + params->spark_pulse_us) { - // xTaskNotifyFromISR(task, ~SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(SPARK_A34, LOW); + digitalWrite(pins.pin_spark_34, LOW); } } if (params->state_time >= params->coil_pulse_us && params->coil34p_high) { - // xTaskNotifyFromISR(task, ~PIN_TRIG_A34P, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(PIN_TRIG_A34P, LOW); + digitalWrite(pins.pin_trig_34p, LOW); params->coil34p_high = false; } @@ -141,8 +127,7 @@ void onTimer(void *arg) case S_34N: if (params->state_time == params->clock_period_us && !params->coil34n_high) { - // xTaskNotifyFromISR(task, PIN_TRIG_A34N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(PIN_TRIG_A34N, HIGH); + digitalWrite(pins.pin_trig_34n, HIGH); params->coil34n_high = true; } @@ -150,21 +135,18 @@ void onTimer(void *arg) { if (params->state_time == params->spark_delay_us) { - // xTaskNotifyFromISR(task, SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(SPARK_A34, HIGH); + digitalWrite(pins.pin_spark_34, HIGH); } if (params->state_time == params->spark_delay_us + params->spark_pulse_us) { - // xTaskNotifyFromISR(task, ~SPARK_A34, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(SPARK_A34, LOW); + digitalWrite(pins.pin_spark_34, LOW); } } if (params->state_time >= params->coil_pulse_us && params->coil34n_high) { - // xTaskNotifyFromISR(task, ~PIN_TRIG_A34N, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); - digitalWrite(PIN_TRIG_A34N, LOW); + digitalWrite(pins.pin_trig_34n, LOW); params->coil34n_high = false; params->state = S_WAIT_10MS_END; params->state_time = 0; @@ -174,7 +156,6 @@ void onTimer(void *arg) case S_WAIT_10MS_END: if (!wait_sent) { - // xTaskNotifyFromISR(task, S_WAIT_10MS_END, eSetValueWithOverwrite, &xHigherPriorityTaskWoken); wait_sent = true; } if (params->state_time >= params->pause_long_us) @@ -184,9 +165,7 @@ void onTimer(void *arg) } break; } - - digitalWrite(PIN_TRIG_B12P, LOW); - + if (xHigherPriorityTaskWoken) portYIELD_FROM_ISR(); } diff --git a/RotaxMonitorTester/src/timer.h b/RotaxMonitorTester/src/timer.h index baf976b..711e33f 100644 --- a/RotaxMonitorTester/src/timer.h +++ b/RotaxMonitorTester/src/timer.h @@ -1,5 +1,7 @@ #pragma once +#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG + #include #include #include "pins.h" @@ -19,6 +21,15 @@ enum State S_WAIT_10MS_END }; +struct timerPins { + const uint8_t pin_trig_12p; + const uint8_t pin_trig_12n; + const uint8_t pin_trig_34p; + const uint8_t pin_trig_34n; + const uint8_t pin_spark_12; + const uint8_t pin_spark_34; +}; + struct timerStatus { State state = State::S_12P; @@ -34,6 +45,7 @@ struct timerStatus bool coil34p_high = false; bool coil12n_high = false; bool coil34n_high = false; + timerPins pins; TaskHandle_t main_task; }; From 246ba7eeb275db47ccc45ba9cbc3abc48941ca6e Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 10 Apr 2026 22:03:09 +0200 Subject: [PATCH 19/38] Task A+B concurrency

Box_A

-

Timestamp: -

-

Data Valid: -

-

Generator voltage: -

-

ADC read time: -

-

Queue errors: -

+

Timestamp: -

+

Data Valid: -

+

Generator voltage: -

+

ADC read time: -

+

Queue errors: -

- Engine RPM: - + Engine RPM: -
@@ -46,53 +46,53 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +
Spark delay----
Spark status----
Soft start status----
Peak P in----
Peak N in----
Peak P out----
Peak N out----
Level spark----
Spark Events----
Missed Events----
diff --git a/RotaxMonitor/data/script.js b/RotaxMonitor/data/script.js index 5ea3c66..7ab466c 100644 --- a/RotaxMonitor/data/script.js +++ b/RotaxMonitor/data/script.js @@ -49,36 +49,36 @@ function connectWS() { // Update Box_A if (data.box_a) { const boxA = data.box_a; - document.getElementById("datavalid").textContent = boxA.datavalid ?? "-"; - document.getElementById("timestamp").textContent = boxA.timestamp ?? "-"; - document.getElementById("volts_gen").textContent = boxA.volts_gen ?? "-"; - document.getElementById("eng_rpm").textContent = boxA.eng_rpm ?? "-"; - document.getElementById("adc_read_time").textContent = boxA.adc_read_time ?? "-"; - document.getElementById("n_queue_errors").textContent = boxA.n_queue_errors ?? "-"; + document.getElementById("a_datavalid").textContent = boxA.datavalid ?? "-"; + document.getElementById("a_timestamp").textContent = boxA.timestamp ?? "-"; + document.getElementById("a_volts_gen").textContent = boxA.volts_gen ?? "-"; + document.getElementById("a_eng_rpm").textContent = boxA.eng_rpm ?? "-"; + document.getElementById("a_adc_read_time").textContent = boxA.adc_read_time ?? "-"; + document.getElementById("a_n_queue_errors").textContent = boxA.n_queue_errors ?? "-"; const coils12A = boxA.coils12 || {}; const coils34A = boxA.coils34 || {}; - document.getElementById("coils12_spark_delay").textContent = coils12A.spark_delay ?? "-"; - document.getElementById("coils34_spark_delay").textContent = coils34A.spark_delay ?? "-"; - document.getElementById("coils12_spark_status").textContent = coils12A.spark_status ?? "-"; - document.getElementById("coils34_spark_status").textContent = coils34A.spark_status ?? "-"; - document.getElementById("coils12_sstart_status").textContent = coils12A.sstart_status ?? "-"; - document.getElementById("coils34_sstart_status").textContent = coils34A.sstart_status ?? "-"; - document.getElementById("coils12_peak_p_in").textContent = coils12A.peak_p_in ?? "-"; - document.getElementById("coils34_peak_p_in").textContent = coils34A.peak_p_in ?? "-"; - document.getElementById("coils12_peak_n_in").textContent = coils12A.peak_n_in ?? "-"; - document.getElementById("coils34_peak_n_in").textContent = coils34A.peak_n_in ?? "-"; - document.getElementById("coils12_peak_p_out").textContent = coils12A.peak_p_out ?? "-"; - document.getElementById("coils34_peak_p_out").textContent = coils34A.peak_p_out ?? "-"; - document.getElementById("coils12_peak_n_out").textContent = coils12A.peak_n_out ?? "-"; - document.getElementById("coils34_peak_n_out").textContent = coils34A.peak_n_out ?? "-"; - document.getElementById("coils12_level_spark").textContent = coils12A.level_spark ?? "-"; - document.getElementById("coils34_level_spark").textContent = coils34A.level_spark ?? "-"; - document.getElementById("coils12_n_events").textContent = coils12A.n_events ?? "-"; - document.getElementById("coils34_n_events").textContent = coils34A.n_events ?? "-"; - document.getElementById("coils12_n_missed_firing").textContent = coils12A.n_missed_firing ?? "-"; - document.getElementById("coils34_n_missed_firing").textContent = coils34A.n_missed_firing ?? "-"; + document.getElementById("a_coils12_spark_delay").textContent = coils12A.spark_delay ?? "-"; + document.getElementById("a_coils34_spark_delay").textContent = coils34A.spark_delay ?? "-"; + document.getElementById("a_coils12_spark_status").textContent = coils12A.spark_status ?? "-"; + document.getElementById("a_coils34_spark_status").textContent = coils34A.spark_status ?? "-"; + document.getElementById("a_coils12_sstart_status").textContent = coils12A.sstart_status ?? "-"; + document.getElementById("a_coils34_sstart_status").textContent = coils34A.sstart_status ?? "-"; + document.getElementById("a_coils12_peak_p_in").textContent = coils12A.peak_p_in ?? "-"; + document.getElementById("a_coils34_peak_p_in").textContent = coils34A.peak_p_in ?? "-"; + document.getElementById("a_coils12_peak_n_in").textContent = coils12A.peak_n_in ?? "-"; + document.getElementById("a_coils34_peak_n_in").textContent = coils34A.peak_n_in ?? "-"; + document.getElementById("a_coils12_peak_p_out").textContent = coils12A.peak_p_out ?? "-"; + document.getElementById("a_coils34_peak_p_out").textContent = coils34A.peak_p_out ?? "-"; + document.getElementById("a_coils12_peak_n_out").textContent = coils12A.peak_n_out ?? "-"; + document.getElementById("a_coils34_peak_n_out").textContent = coils34A.peak_n_out ?? "-"; + document.getElementById("a_coils12_level_spark").textContent = coils12A.level_spark ?? "-"; + document.getElementById("a_coils34_level_spark").textContent = coils34A.level_spark ?? "-"; + document.getElementById("a_coils12_n_events").textContent = coils12A.n_events ?? "-"; + document.getElementById("a_coils34_n_events").textContent = coils34A.n_events ?? "-"; + document.getElementById("a_coils12_n_missed_firing").textContent = coils12A.n_missed_firing ?? "-"; + document.getElementById("a_coils34_n_missed_firing").textContent = coils34A.n_missed_firing ?? "-"; } // Update Box_B diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 4b5097f..41ef22d 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -21,17 +21,15 @@ lib_deps = me-no-dev/AsyncTCP@^3.3.2 me-no-dev/ESPAsyncWebServer@^3.6.0 upload_protocol = esptool -upload_port = COM8 +upload_port = /dev/ttyACM1 upload_speed = 921600 -monitor_port = COM4 +monitor_port = /dev/ttyACM0 monitor_speed = 921600 build_type = release build_flags = -DCORE_DEBUG_LEVEL=4 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 - -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 - -DCONFIG_FREERTOS_USE_TRACE_FACILITY=1 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 -DCONFIG_ASYNC_TCP_PRIORITY=20 -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 @@ -48,9 +46,9 @@ framework = ${env:esp32-s3-devkitc1-n16r8.framework} lib_deps = ${env:esp32-s3-devkitc1-n16r8.lib_deps} upload_protocol = esptool -upload_port = COM8 +upload_port = /dev/ttyACM1 upload_speed = 921600 -monitor_port = COM4 +monitor_port = /dev/ttyACM0 monitor_speed = 921600 debug_tool = esp-builtin debug_speed = 15000 @@ -62,8 +60,6 @@ build_flags = -DCORE_DEBUG_LEVEL=3 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 - -DCONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=1 - -DCONFIG_FREERTOS_USE_TRACE_FACILITY=1 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 -DCONFIG_ASYNC_TCP_PRIORITY=20 -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index cf1cd4c..4ac0bd7 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -20,7 +20,7 @@ #include "freertos/task.h" // Defines to enable channel B -// #define CH_B_ENABLE +#define CH_B_ENABLE #define TEST // Debug Defines @@ -99,15 +99,17 @@ void loop() Devices dev; // Task handle TaskHandle_t trigA_TaskHandle = NULL; + TaskHandle_t trigB_TaskHandle = NULL; // Data Queue for real time task to main loop communication QueueHandle_t rt_taskA_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); + QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); + rtTaskParams taskA_params{ .rt_running = true, .dev = &dev, - .rt_handle_ptr = &trigA_TaskHandle, .rt_queue = rt_taskA_queue, .rt_int = rtTaskInterrupts{ - .isr_ptr = trig_isr_A, + .isr_ptr = &trig_isr_A, .trig_pin_12p = TRIG_PIN_A12P, .trig_pin_12n = TRIG_PIN_A12N, .trig_pin_34p = TRIG_PIN_A34P, @@ -117,15 +119,12 @@ void loop() .rt_resets = rtTaskResets{.rst_io_peak = RST_EXT_PEAK_DETECT_A, .rst_io_sh = RST_EXT_SAMPLE_HOLD_A}}; #ifdef CH_B_ENABLE - TaskHandle_t trigB_TaskHandle = NULL; - QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); rtTaskParams taskB_params{ .rt_running = true, .dev = &dev, - .rt_handle_ptr = &trigB_TaskHandle, .rt_queue = rt_taskB_queue, .rt_int = rtTaskInterrupts{ - .isr_ptr = trig_isr_B, + .isr_ptr = &trig_isr_B, .trig_pin_12p = TRIG_PIN_B12P, .trig_pin_12n = TRIG_PIN_B12N, .trig_pin_34p = TRIG_PIN_B34P, @@ -135,7 +134,7 @@ void loop() .rt_resets = rtTaskResets{.rst_io_peak = RST_EXT_PEAK_DETECT_B, .rst_io_sh = RST_EXT_SAMPLE_HOLD_B}}; #endif - if (!rt_taskA_queue /*|| !rt_taskB_queue*/) + if (!rt_taskA_queue || !rt_taskB_queue) { LOG_ERROR("Unable To Create task queues"); LOG_ERROR("5 seconds to restart..."); @@ -210,7 +209,7 @@ void loop() (void *)&taskB_params, RT_TASK_PRIORITY, // priorità leggermente più alta &trigB_TaskHandle, - CORE_0); + CORE_1); delay(100); // give some time to the thread to start #endif @@ -226,12 +225,18 @@ void loop() ////////////////////// MAIN LOOP ////////////////////// bool partial_save = false; // flag to indicate if a partial save has been done after a timeout - uint32_t counter = 0; + auto last_data = millis(); + uint32_t counter_a = 0; + uint32_t counter_b = 0; + uint32_t wait_count = 0; + ignitionBoxStatus ign_info_A; ignitionBoxStatus ign_info_B; + ignitionBoxStatusAverage ign_info_avg_A(filter_k); ignitionBoxStatusAverage ign_info_avg_B(filter_k); + LITTLEFSGuard fsGuard; WebPage webPage(80, LittleFS); // Initialize webserver and Websocket @@ -240,66 +245,78 @@ void loop() auto dataA = pdFALSE; auto dataB = pdFALSE; - if (counter >= active_history_A->size()) // not concurrent with write task + dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, pdMS_TO_TICKS(10)); + if (counter_a >= active_history_A->size()) // not concurrent with write task { - counter = 0; + counter_a = 0; partial_save = false; // reset partial save flag on new data cycle swapHistory(active_history_A, writable_history_A); save_history(*writable_history_A, "ignition_historyA.csv"); // directly call the save task function to save without delay } - dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, pdMS_TO_TICKS(100)); + #ifdef CH_B_ENABLE - if (counter >= active_history_B->size()) // not concurrent with write task + dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, pdMS_TO_TICKS(10)); + if (counter_b >= active_history_B->size()) // not concurrent with write task { - counter = 0; + counter_b = 0; partial_save = false; // reset partial save flag on new data cycle swapHistory(active_history_B, writable_history_B); save_history(*writable_history_B, "ignition_historyB.csv"); // directly call the save task function to save without delay } - dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, pdMS_TO_TICKS(100)); #endif - + // Update last data if (dataA == pdTRUE || dataB == pdTRUE) { - // printInfo(ign_info); - (*active_history_A)[counter % active_history_A->size()] = ign_info_A; -#ifdef CH_B_ENABLE - (*active_history_B)[counter % active_history_B->size()] = ign_info_B; -#endif + last_data = millis(); + } + + if (dataA == pdTRUE) + { + (*active_history_A)[counter_a++ % active_history_A->size()] = ign_info_A; ign_info_avg_A.update(ign_info_A); // update moving average with latest ignition status - ign_info_avg_B.update(ign_info_B); // update moving average with latest ignition status - - Serial.printf("\033[2K Data Received A: %d/%d\r", counter, (*active_history_A).size()); - - if (counter % filter_k == 0) // send data every 10 samples + Serial.printf("Data Received A: %d/%d\n\r", counter_a, (*active_history_A).size()); + if (counter_a % filter_k == 0) // send data every 10 samples { - Serial.println(); - LOG_DEBUG("Sending average ignition status to websocket clients..."); ArduinoJson::JsonDocument wsData; wsData["box_a"] = ign_info_avg_A.toJson(); + wsData["box_b"] = JsonObject(); + webPage.sendWsData(wsData.as()); + } + } +#ifdef CH_B_ENABLE + if (dataB == pdTRUE) + { + (*active_history_B)[counter_b++ % active_history_B->size()] = ign_info_B; + ign_info_avg_B.update(ign_info_B); // update moving average with latest ignition status + Serial.printf("Data Received B: %d/%d\n\r", counter_b, (*active_history_B).size()); + if (counter_b % filter_k == 0) // send data every 10 samples + { + ArduinoJson::JsonDocument wsData; + wsData["box_a"] = JsonObject(); wsData["box_b"] = ign_info_avg_B.toJson(); webPage.sendWsData(wsData.as()); } - - counter++; } - else +#endif + if (dataA == pdFALSE && dataB == pdFALSE && millis() - last_data > 2000) { - Serial.printf("[%d] Waiting for data...\r", wait_count++); - if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout + if (!partial_save && counter_a > 0) // if timeout occurs but we have unsaved data, save it before next timeout { - active_history_A->resize(counter); // resize active history to actual number of records received to avoid saving empty records + active_history_A->resize(counter_a); // resize active history to actual number of records received to avoid saving empty records save_history(*active_history_A, "ignition_history_A.csv"); active_history_A->resize(max_history); // resize back to max history size for next data cycle #ifdef CH_B_ENABLE - active_history_B->resize(counter); // resize active history to actual number of records received to avoid saving empty records + active_history_B->resize(counter_a); // resize active history to actual number of records received to avoid saving empty records save_history(*active_history_B, "ignition_history_B.csv"); active_history_B->resize(max_history); // resize back to max history size for next data cycle #endif - counter = 0; // reset counter after saving + counter_a = 0; // reset counter after saving + counter_b = 0; // reset counter after saving + partial_save = true; first_save = true; } + Serial.printf("[%d] Waiting for data...\r", wait_count++); delay(500); } } diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 8bbc8f2..948a29f 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -17,57 +17,65 @@ void rtIgnitionTask(void *pvParameters) LOG_ERROR("Null rt_task_ptr parameters"); vTaskDelete(NULL); } - LOG_INFO("rtTask Params OK"); + // Task Parameters and Devices rtTaskParams *params = (rtTaskParams *)pvParameters; const rtTaskInterrupts rt_int = params->rt_int; // copy to avoid external override const rtTaskResets rt_rst = params->rt_resets; // copy to avoid external override QueueHandle_t rt_queue = params->rt_queue; - TaskHandle_t rt_handle_ptr = *params->rt_handle_ptr; Devices *dev = params->dev; ADS1256 *adc = dev->adc_a; PCA9555 *io = dev->io; + TaskStatus_t rt_task_info; + vTaskGetInfo(NULL, &rt_task_info, pdFALSE, eInvalid); + + const auto rt_task_name = pcTaskGetName(rt_task_info.xHandle); + LOG_INFO("rtTask Params OK [", rt_task_name, "]"); + ignitionBoxStatus ign_box_sts; // Variables for ISR, static to be fixed in memory locations - static isrParams isr_params_t12p{ + isrParams isr_params_t12p{ .flag = TRIG_FLAG_12P, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_t12n{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_t12n{ .flag = TRIG_FLAG_12N, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_t34p{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_t34p{ .flag = TRIG_FLAG_34P, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_t34n{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_t34n{ .flag = TRIG_FLAG_34N, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_sp12{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_sp12{ .flag = SPARK_FLAG_12, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; - static isrParams isr_params_sp34{ + .rt_handle_ptr = rt_task_info.xHandle}; + isrParams isr_params_sp34{ .flag = SPARK_FLAG_34, .ign_stat = &ign_box_sts, - .rt_handle_ptr = rt_handle_ptr}; + .rt_handle_ptr = rt_task_info.xHandle}; - LOG_INFO("rtTask ISR Params OK"); + LOG_DEBUG("rtTask HDL Params OK, HDL* [", (uint32_t)rt_task_info.xHandle, "]"); + LOG_DEBUG("rtTask ISR Params OK, ISR* [", (uint32_t)rt_int.isr_ptr, "]"); + LOG_DEBUG("rtTask QUE Params OK, QUE* [", (uint32_t)rt_queue, "]"); // Create esp_timer for microsecond precision timeout esp_timer_handle_t timeout_timer; esp_timer_create_args_t timer_args = { .callback = spark_timeout_callback, - .arg = (void *)rt_handle_ptr, + .arg = (void *)rt_task_info.xHandle, .dispatch_method = ESP_TIMER_TASK, .name = "spark_timeout"}; esp_timer_create(&timer_args, &timeout_timer); + // Attach Pin Interrupts attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_12p), rt_int.isr_ptr, (void *)&isr_params_t12p, RISING); attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_12n), rt_int.isr_ptr, (void *)&isr_params_t12n, RISING); @@ -76,7 +84,7 @@ void rtIgnitionTask(void *pvParameters) attachInterruptArg(digitalPinToInterrupt(rt_int.spark_pin_12), rt_int.isr_ptr, (void *)&isr_params_sp12, RISING); attachInterruptArg(digitalPinToInterrupt(rt_int.spark_pin_34), rt_int.isr_ptr, (void *)&isr_params_sp34, RISING); - LOG_INFO("rtTask ISR Attach OK"); + LOG_INFO("rtTask ISR Attach OK [", rt_task_name, "]"); // Global rt_task_ptr variables bool first_cycle = true; diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index e5152ec..542f96d 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -55,7 +55,6 @@ struct rtTaskParams { bool rt_running; // run flag, false to terminate Devices *dev; - TaskHandle_t* rt_handle_ptr; const QueueHandle_t rt_queue; const rtTaskInterrupts rt_int; // interrupt pins to attach const rtTaskResets rt_resets; // reset ping for peak detectors diff --git a/RotaxMonitor/src/ui.h b/RotaxMonitor/src/ui.h index 8fdf35b..36b2a11 100644 --- a/RotaxMonitor/src/ui.h +++ b/RotaxMonitor/src/ui.h @@ -14,191 +14,3 @@ void printField(const char name[], const char *val); void printInfo(const ignitionBoxStatus &info); -static const std::string htmlTest = R"rawliteral( - - - - - ESP32 Dashboard - - - - -

RotaxMonitor realtime data

- - - - -
-

Timestamp: -

-

Data Valid: -

-

Generator voltage: -

-

Engine RPM: -

-

ADC read time: -

-

Queue errors: -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyCoils 12Coils 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Events--
Missed firings--
-
- - - - - -)rawliteral"; \ No newline at end of file diff --git a/RotaxMonitorTester/.vscode/extensions.json b/RotaxMonitorTester/.vscode/extensions.json index 411655e..b397401 100644 --- a/RotaxMonitorTester/.vscode/extensions.json +++ b/RotaxMonitorTester/.vscode/extensions.json @@ -1,8 +1,7 @@ { "recommendations": [ "Jason2866.esp-decoder", - "pioarduino.pioarduino-ide", - "platformio.platformio-ide" + "pioarduino.pioarduino-ide" ], "unwantedRecommendations": [ "ms-vscode.cpptools-extension-pack" diff --git a/RotaxMonitorTester/src/main.cpp b/RotaxMonitorTester/src/main.cpp index eadb954..e2fafd5 100644 --- a/RotaxMonitorTester/src/main.cpp +++ b/RotaxMonitorTester/src/main.cpp @@ -18,15 +18,16 @@ static uint32_t count = 0; #define SPARK_DLY_MAX 490 #define PAUSE_LONG_MIN 5000 -#define PAUSE_LONG_MAX PAUSE_LONG_MIN*100 +#define PAUSE_LONG_MAX PAUSE_LONG_MIN * 100 -#define RPM_MIN 800 +#define RPM_MIN 250 #define RPM_MAX 5500 -void clearScreen(){ - Serial.print("\033[2J"); // clear screen - Serial.print("\033[H"); // cursor home - Serial.flush(); +void clearScreen() +{ + Serial.print("\033[2J"); // clear screen + Serial.print("\033[H"); // cursor home + Serial.flush(); } static double filtered_rpm = 0; @@ -48,45 +49,44 @@ static const std::map pin2Name = { {State::S_WAIT_10MS, "S_WAIT_10MS"}}; static timerStatus stsA = { - .clock_period_us = (uint32_t)PERIOD_US, - .pause_long_us = 10000, - .pause_short_us = 1000, - .coil_pulse_us = 1000, - .spark_pulse_us = 100, - .spark_delay_us = 50, - .pins = { + .clock_period_us = (uint32_t)PERIOD_US, + .pause_long_us = 10000, + .pause_short_us = 1000, + .coil_pulse_us = 1000, + .spark_pulse_us = 100, + .spark_delay_us = 50, + .pins = { .pin_trig_12p = PIN_TRIG_A12P, .pin_trig_12n = PIN_TRIG_A12N, .pin_trig_34p = PIN_TRIG_A34P, .pin_trig_34n = PIN_TRIG_A34N, .pin_spark_12 = SPARK_A12, - .pin_spark_34 = SPARK_A34 - }, - .main_task = NULL}; + .pin_spark_34 = SPARK_A34}, + .main_task = NULL}; static timerStatus stsB = { - .clock_period_us = (uint32_t)PERIOD_US, - .pause_long_us = 10000, - .pause_short_us = 1000, - .coil_pulse_us = 1000, - .spark_pulse_us = 100, - .spark_delay_us = 50, - .pins = { + .clock_period_us = (uint32_t)PERIOD_US, + .pause_long_us = 10000, + .pause_short_us = 1000, + .coil_pulse_us = 1000, + .spark_pulse_us = 100, + .spark_delay_us = 50, + .pins = { .pin_trig_12p = PIN_TRIG_B12P, .pin_trig_12n = PIN_TRIG_B12N, .pin_trig_34p = PIN_TRIG_B34P, .pin_trig_34n = PIN_TRIG_B34N, .pin_spark_12 = SPARK_B12, - .pin_spark_34 = SPARK_B34 - }, - .main_task = NULL}; + .pin_spark_34 = SPARK_B34}, + .main_task = NULL}; -static bool isEnabled = false; +static bool isEnabled_A = false; +static bool isEnabled_B = false; void setup() { - Serial.begin(921600); + Serial.begin(115200); delay(1000); LOG_ATTACH_SERIAL(Serial); @@ -107,7 +107,8 @@ void setup() pinMode(SPARK_DELAY_POT, ANALOG); pinMode(FREQ_POT, ANALOG); - pinMode(ENABLE_PIN, INPUT_PULLUP); + pinMode(ENABLE_PIN_A, INPUT_PULLUP); + pinMode(ENABLE_PIN_B, INPUT_PULLUP); // get the task handle for the main loop stsA.main_task = xTaskGetCurrentTaskHandleForCore(1); @@ -135,40 +136,58 @@ void loop() LOG_INFO("Loop: ", count++); uint32_t spark_delay = (uint32_t)(map(analogRead(SPARK_DELAY_POT), 0, 4096, SPARK_DLY_MIN, SPARK_DLY_MAX) / PERIOD_US); stsA.spark_delay_us = spark_delay * PERIOD_US; - if (stsA.spark_delay_us > (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2) { + if (stsA.spark_delay_us > (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2) + { stsA.soft_start = true; stsA.spark_delay_us -= (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2; - } else { + } + else + { stsA.soft_start = false; } - stsB.soft_start = stsA.soft_start; - stsB.spark_delay_us = stsA.spark_delay_us; + stsB.soft_start = stsA.soft_start; + stsB.spark_delay_us = stsA.spark_delay_us; double new_rpm = (double)(map(analogRead(FREQ_POT), 0, 4096, RPM_MIN, RPM_MAX)); filtered_rpm = filtered_rpm + 0.1 * (new_rpm - filtered_rpm); stsA.pause_long_us = (uint32_t)(60000000.0f / filtered_rpm / 2.0f); stsB.pause_long_us = stsA.pause_long_us; - if (isEnabled) { - LOG_INFO("==== System is ENABLED ===="); - } else { - LOG_INFO("==== System is DISABLED ===="); - } + if (isEnabled_A) + LOG_INFO("==== System A is ENABLED ===="); + else + LOG_INFO("==== System A is DISABLED ===="); + + if (isEnabled_B) + LOG_INFO("==== System B is ENABLED ===="); + else + LOG_INFO("==== System B is DISABLED ===="); LOG_INFO("Spark Delay uS: ", stsA.spark_delay_us, "\tSoft Start: ", stsA.soft_start ? "TRUE" : "FALSE"); LOG_INFO("Engine Rpm: ", (uint32_t)(filtered_rpm)); LOG_INFO("Coil Pulse: ", stsA.coil_pulse_us, "us"); LOG_INFO("Spark Pulse: ", stsA.spark_pulse_us, "us"); - - if (digitalRead(ENABLE_PIN) == LOW && !isEnabled) { + + if (digitalRead(ENABLE_PIN_A) == LOW && !isEnabled_A) + { timerStart(timerA); - delayMicroseconds(50); + isEnabled_A = true; + } + else if (digitalRead(ENABLE_PIN_A) == HIGH && isEnabled_A) + { + timerStop(timerA); + isEnabled_A = false; + } + + if (digitalRead(ENABLE_PIN_B) == LOW && !isEnabled_B) + { timerStart(timerB); - isEnabled = true; - } else if (digitalRead(ENABLE_PIN) == HIGH && isEnabled) { - timerStop(timerA); - timerStop(timerA); - isEnabled = false; + isEnabled_B = true; + } + else if (digitalRead(ENABLE_PIN_B) == HIGH && isEnabled_B) + { + timerStop(timerB); + isEnabled_B = false; } delay(100); diff --git a/RotaxMonitorTester/src/pins.h b/RotaxMonitorTester/src/pins.h index 6d2e8da..04427a1 100644 --- a/RotaxMonitorTester/src/pins.h +++ b/RotaxMonitorTester/src/pins.h @@ -1,7 +1,8 @@ #pragma once // Enable Pin -#define ENABLE_PIN 16 +#define ENABLE_PIN_A 16 +#define ENABLE_PIN_B 15 ///// Ignition Box A ///// #define PIN_TRIG_A12P 18 From eaeb515074557a2cc882a814ff5db16b4677f94b Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 10 Apr 2026 23:33:22 +0200 Subject: [PATCH 20/38] Modified Task display to order based on task number or arbitraruy function --- RotaxMonitor/platformio.ini | 14 ++++---- RotaxMonitor/src/isr.h | 4 +-- RotaxMonitor/src/main.cpp | 43 ++++++++++++----------- RotaxMonitor/src/utils.cpp | 68 +++++++++++++++++++++++++++++++++++++ RotaxMonitor/src/utils.h | 2 ++ 5 files changed, 103 insertions(+), 28 deletions(-) diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 41ef22d..c5d3aa7 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -27,14 +27,14 @@ monitor_port = /dev/ttyACM0 monitor_speed = 921600 build_type = release build_flags = - -DCORE_DEBUG_LEVEL=4 + -DCORE_DEBUG_LEVEL=1 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 - -DCONFIG_ASYNC_TCP_PRIORITY=20 - -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 + -DCONFIG_ASYNC_TCP_PRIORITY=21 + -DCONFIG_ASYNC_TCP_QUEUE_SIZE=64 -DCONFIG_ASYNC_TCP_RUNNING_CORE=1 - -DCONFIG_ASYNC_TCP_STACK_SIZE=8192 + -DCONFIG_ASYNC_TCP_STACK_SIZE=4096 -fstack-protector-all [env:esp32-s3-devkitc1-n16r8-debug] @@ -61,8 +61,8 @@ build_flags = -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 - -DCONFIG_ASYNC_TCP_PRIORITY=20 - -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 + -DCONFIG_ASYNC_TCP_PRIORITY=21 + -DCONFIG_ASYNC_TCP_QUEUE_SIZE=64 -DCONFIG_ASYNC_TCP_RUNNING_CORE=1 - -DCONFIG_ASYNC_TCP_STACK_SIZE=8192 + -DCONFIG_ASYNC_TCP_STACK_SIZE=4096 -fstack-protector-all diff --git a/RotaxMonitor/src/isr.h b/RotaxMonitor/src/isr.h index ed2e4d1..bd1bea5 100644 --- a/RotaxMonitor/src/isr.h +++ b/RotaxMonitor/src/isr.h @@ -16,8 +16,8 @@ #define CORE_0 0 #define CORE_1 1 -#define RT_TASK_STACK 4096 // in words -#define RT_TASK_PRIORITY (configMAX_PRIORITIES - 4) // highest priority after wifi tasks +#define RT_TASK_STACK 2048 // in words +#define RT_TASK_PRIORITY (configMAX_PRIORITIES - 6) // highest priority after wifi tasks struct isrParams { diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 4ac0bd7..a39faa4 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -15,10 +15,6 @@ #include #include -// FreeRTOS directives -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" - // Defines to enable channel B #define CH_B_ENABLE #define TEST @@ -76,6 +72,7 @@ void setup() initSparkPinInputs(); } +////////////////////// MAIN LOOP ////////////////////// void loop() { // global variables @@ -223,12 +220,12 @@ void loop() LOG_DEBUG("Real Time Tasks A & B initialized"); - ////////////////////// MAIN LOOP ////////////////////// bool partial_save = false; // flag to indicate if a partial save has been done after a timeout auto last_data = millis(); + auto last_info = millis(); + uint32_t counter_a = 0; uint32_t counter_b = 0; - uint32_t wait_count = 0; ignitionBoxStatus ign_info_A; @@ -240,12 +237,13 @@ void loop() LITTLEFSGuard fsGuard; WebPage webPage(80, LittleFS); // Initialize webserver and Websocket - while (running) + //////////////// INNER LOOP ///////////////////// + while (running) { auto dataA = pdFALSE; auto dataB = pdFALSE; - dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, pdMS_TO_TICKS(10)); + dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, 0); if (counter_a >= active_history_A->size()) // not concurrent with write task { counter_a = 0; @@ -255,7 +253,7 @@ void loop() } #ifdef CH_B_ENABLE - dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, pdMS_TO_TICKS(10)); + dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, 0); if (counter_b >= active_history_B->size()) // not concurrent with write task { counter_b = 0; @@ -274,7 +272,7 @@ void loop() { (*active_history_A)[counter_a++ % active_history_A->size()] = ign_info_A; ign_info_avg_A.update(ign_info_A); // update moving average with latest ignition status - Serial.printf("Data Received A: %d/%d\n\r", counter_a, (*active_history_A).size()); + // Serial.printf("Data Received A: %d/%d\n\r", counter_a, (*active_history_A).size()); if (counter_a % filter_k == 0) // send data every 10 samples { ArduinoJson::JsonDocument wsData; @@ -288,7 +286,7 @@ void loop() { (*active_history_B)[counter_b++ % active_history_B->size()] = ign_info_B; ign_info_avg_B.update(ign_info_B); // update moving average with latest ignition status - Serial.printf("Data Received B: %d/%d\n\r", counter_b, (*active_history_B).size()); + // Serial.printf("Data Received B: %d/%d\n\r", counter_b, (*active_history_B).size()); if (counter_b % filter_k == 0) // send data every 10 samples { ArduinoJson::JsonDocument wsData; @@ -298,7 +296,7 @@ void loop() } } #endif - if (dataA == pdFALSE && dataB == pdFALSE && millis() - last_data > 2000) + if (dataA == pdFALSE && dataB == pdFALSE && (millis() - last_data) > 2000) { if (!partial_save && counter_a > 0) // if timeout occurs but we have unsaved data, save it before next timeout { @@ -316,16 +314,23 @@ void loop() partial_save = true; first_save = true; } - Serial.printf("[%d] Waiting for data...\r", wait_count++); - delay(500); + //Serial.printf("[%d] Waiting for data...\r", wait_count++); + delay(100); } - } + + if ((millis() - last_info) > 1000) + { + clearScreen(); + Serial.println(); + printRunningTasksMod(Serial); + last_info = millis(); + + } + } //////////////// INNER LOOP ///////////////////// if (trigA_TaskHandle) vTaskDelete(trigA_TaskHandle); -#ifdef CH_B_ENABLE if (trigB_TaskHandle) vTaskDelete(trigB_TaskHandle); -#endif - ////////////////////// MAIN LOOP ////////////////////// -} + +} ////////////////////// MAIN LOOP ////////////////////// diff --git a/RotaxMonitor/src/utils.cpp b/RotaxMonitor/src/utils.cpp index 222f913..a1fad94 100644 --- a/RotaxMonitor/src/utils.cpp +++ b/RotaxMonitor/src/utils.cpp @@ -1,4 +1,15 @@ #include "utils.h" +#include "freertos_stats.h" +#include "sdkconfig.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/portable.h" + +#include +#include +#include + +#define FREERTOS_TASK_NUMBER_MAX_NUM 256 // RunTime stats for how many Tasks to be stored std::string printBits(uint32_t value) { std::string result; @@ -12,3 +23,60 @@ std::string printBits(uint32_t value) { } return result; } + +void printRunningTasksMod(Print &printer, std::function orderBy) +{ + static const char *taskStates[] = {"Running", "Ready", "Blocked", "Suspended", "Deleted", "Invalid"}; + + static uint32_t ulRunTimeCounters[FREERTOS_TASK_NUMBER_MAX_NUM]; + static uint32_t ulLastRunTime = 0; + uint32_t ulCurrentRunTime = 0, ulTaskRunTime = 0; + uint32_t ulTotalRunTime = 0; + + std::vector pxTaskStatusArray; + UBaseType_t uxArraySize = 0; + + // Take a snapshot of the number of tasks in case it changes while this function is executing. + uxArraySize = uxTaskGetNumberOfTasks(); + pxTaskStatusArray.resize(uxArraySize); + + // Generate raw status information about each task. + uxArraySize = uxTaskGetSystemState(pxTaskStatusArray.data(), uxArraySize, &ulTotalRunTime); + + if (orderBy == nullptr) + std::sort(pxTaskStatusArray.begin(), pxTaskStatusArray.end(), [](const TaskStatus_t &a, const TaskStatus_t &b) + { return a.xTaskNumber < b.xTaskNumber; }); + else + std::sort(pxTaskStatusArray.begin(), pxTaskStatusArray.end(), orderBy); + + // Compute system total runtime + ulCurrentRunTime = ulTotalRunTime - ulLastRunTime; + ulLastRunTime = ulTotalRunTime; + + // Print Runtime Information + printer.printf("Tasks: %u, Runtime: %lus, Period: %luus\r\n", uxArraySize, ulTotalRunTime / 1000000, ulCurrentRunTime); + + // Print Task Headers + printer.printf("Num\t Name\tLoad\tPrio\t Free\tCore\tState\r\n"); + for (const auto &task : pxTaskStatusArray) + { + + ulTaskRunTime = (task.ulRunTimeCounter - ulRunTimeCounters[task.xTaskNumber]); + ulRunTimeCounters[task.xTaskNumber] = task.ulRunTimeCounter; + ulTaskRunTime = (ulTaskRunTime * 100) / ulCurrentRunTime; // in percentage + + printer.printf( + "%3u\t%16s" + "\t%3lu%%" + "\t%4u\t%5lu" + "\t%4c" + "\t%s\r\n", + task.xTaskNumber, task.pcTaskName, + ulTaskRunTime, + task.uxCurrentPriority, task.usStackHighWaterMark, + (task.xCoreID == tskNO_AFFINITY) ? '*' : ('0' + task.xCoreID), + taskStates[task.eCurrentState]); + } + printer.println(); +} + diff --git a/RotaxMonitor/src/utils.h b/RotaxMonitor/src/utils.h index 40a745e..f74653e 100644 --- a/RotaxMonitor/src/utils.h +++ b/RotaxMonitor/src/utils.h @@ -6,6 +6,8 @@ std::string printBits(uint32_t value); +void printRunningTasksMod(Print &printer, std::function orderBy = nullptr); + inline void swapHistory(PSRAMVector* active, PSRAMVector* writable) { auto *temp = active; active = writable; // switch active and writable buffers From d41a99ee887cb974622e1ee2271fdb71bf2cf8c7 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sat, 11 Apr 2026 00:40:33 +0200 Subject: [PATCH 21/38] rgb led --- RotaxMonitor/lib/led/led.cpp | 29 ++++++++++++++++++++++ RotaxMonitor/lib/led/led.h | 48 ++++++++++++++++++++++++++++++++++++ RotaxMonitor/platformio.ini | 2 ++ RotaxMonitor/src/main.cpp | 22 ++++++++++++----- 4 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 RotaxMonitor/lib/led/led.cpp create mode 100644 RotaxMonitor/lib/led/led.h diff --git a/RotaxMonitor/lib/led/led.cpp b/RotaxMonitor/lib/led/led.cpp new file mode 100644 index 0000000..c75f987 --- /dev/null +++ b/RotaxMonitor/lib/led/led.cpp @@ -0,0 +1,29 @@ +#include + +RGBled::RGBled(const uint8_t pin, const uint8_t num) +{ + m_led = Adafruit_NeoPixel(num, pin, NEO_GRB + NEO_KHZ800); + m_led.begin(); + m_led.setPixelColor(0, RED); + m_led.show(); +} + +RGBled::~RGBled() +{ + m_led.clear(); +} + +void RGBled::setStatus(const LedStatus s) +{ + if (m_status == s) return; + m_status = s; + RGB_BUILTIN_LED_COLOR_ORDER + m_led.setPixelColor(0, s); + m_led.setBrightness(16); + m_led.show(); +} + +const RGBled::LedStatus RGBled::getSatus(void) +{ + return m_status; +} \ No newline at end of file diff --git a/RotaxMonitor/lib/led/led.h b/RotaxMonitor/lib/led/led.h new file mode 100644 index 0000000..8d026be --- /dev/null +++ b/RotaxMonitor/lib/led/led.h @@ -0,0 +1,48 @@ +#pragma once + +// System Inlcudes +#include +#include + +#define RED 0x00FF00 +#define GREEN 0xFF0000 +#define BLUE 0x0000FF +#define WHITE 0xFFFFFF +#define YELLOW 0xFFFF00 +#define CYAN 0xFF00FF +#define MAGENTA 0x00FFFF +#define ORANGE 0xA5FF00 +#define PURPLE 0x008080 +#define PINK 0x69FFB4 +#define LIME 0xCD3232 +#define SKY_BLUE 0xCE87EB +#define GOLD 0xD7FF00 +#define TURQUOISE 0xE040D0 +#define INDIGO 0x004B82 +#define GRAY 0x808080 + +class RGBled +{ +public: + enum LedStatus + { + OK = GREEN, + ERROR = RED, + INIT = YELLOW, + DATA_A = CYAN, + DATA_B = MAGENTA, + DATA_ALL = ORANGE, + IDLE = GRAY + }; + +public: + RGBled(const uint8_t pin = 48, const uint8_t num = 1); + ~RGBled(); + + void setStatus(const LedStatus s); + const LedStatus getSatus(void); + +private: + Adafruit_NeoPixel m_led; + LedStatus m_status = LedStatus::IDLE; +}; \ No newline at end of file diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index c5d3aa7..e7fb4f6 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -20,6 +20,7 @@ lib_deps = hideakitai/PCA95x5@^0.1.3 me-no-dev/AsyncTCP@^3.3.2 me-no-dev/ESPAsyncWebServer@^3.6.0 + adafruit/Adafruit NeoPixel@^1.15.4 upload_protocol = esptool upload_port = /dev/ttyACM1 upload_speed = 921600 @@ -45,6 +46,7 @@ platform = ${env:esp32-s3-devkitc1-n16r8.platform} framework = ${env:esp32-s3-devkitc1-n16r8.framework} lib_deps = ${env:esp32-s3-devkitc1-n16r8.lib_deps} + adafruit/Adafruit NeoPixel@^1.15.4 upload_protocol = esptool upload_port = /dev/ttyACM1 upload_speed = 921600 diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index a39faa4..c45e175 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -14,6 +14,7 @@ #include #include #include +#include // Defines to enable channel B #define CH_B_ENABLE @@ -76,6 +77,8 @@ void setup() void loop() { // global variables + RGBled led; + led.setStatus(RGBled::LedStatus::INIT); bool running = true; const uint32_t max_queue = 128; const uint32_t filter_k = 10; @@ -219,6 +222,7 @@ void loop() } LOG_DEBUG("Real Time Tasks A & B initialized"); + led.setStatus(RGBled::LedStatus::OK); bool partial_save = false; // flag to indicate if a partial save has been done after a timeout auto last_data = millis(); @@ -238,7 +242,7 @@ void loop() WebPage webPage(80, LittleFS); // Initialize webserver and Websocket //////////////// INNER LOOP ///////////////////// - while (running) + while (running) { auto dataA = pdFALSE; auto dataB = pdFALSE; @@ -264,9 +268,15 @@ void loop() #endif // Update last data if (dataA == pdTRUE || dataB == pdTRUE) - { last_data = millis(); - } + + // Update Led color + if (dataA == pdTRUE && dataB == pdFALSE) + led.setStatus(RGBled::DATA_A); + else if (dataB == pdTRUE && dataA == pdFALSE) + led.setStatus(RGBled::DATA_B); + else + led.setStatus(RGBled::DATA_ALL); if (dataA == pdTRUE) { @@ -314,17 +324,17 @@ void loop() partial_save = true; first_save = true; } - //Serial.printf("[%d] Waiting for data...\r", wait_count++); + // Serial.printf("[%d] Waiting for data...\r", wait_count++); + led.setStatus(RGBled::LedStatus::IDLE); delay(100); } - + if ((millis() - last_info) > 1000) { clearScreen(); Serial.println(); printRunningTasksMod(Serial); last_info = millis(); - } } //////////////// INNER LOOP ///////////////////// From 9c012efef1a8ef0974eb2bc803ca4813e5835033 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sat, 11 Apr 2026 11:37:40 +0200 Subject: [PATCH 22/38] refactor led class --- RotaxMonitor/lib/led/led.cpp | 27 +++++++++++++++------------ RotaxMonitor/lib/led/led.h | 21 ++++++++++++++++++--- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/RotaxMonitor/lib/led/led.cpp b/RotaxMonitor/lib/led/led.cpp index c75f987..9a93a85 100644 --- a/RotaxMonitor/lib/led/led.cpp +++ b/RotaxMonitor/lib/led/led.cpp @@ -1,29 +1,32 @@ #include -RGBled::RGBled(const uint8_t pin, const uint8_t num) +RGBled::RGBled(const uint8_t pin) : m_led(pin) { - m_led = Adafruit_NeoPixel(num, pin, NEO_GRB + NEO_KHZ800); - m_led.begin(); - m_led.setPixelColor(0, RED); - m_led.show(); + pinMode(m_led, OUTPUT); + writeStatus(RGBled::ERROR); } RGBled::~RGBled() { - m_led.clear(); + pinMode(m_led, INPUT); } void RGBled::setStatus(const LedStatus s) { - if (m_status == s) return; + if (m_status == s) + return; + std::lock_guard lock(m_mutex); m_status = s; - RGB_BUILTIN_LED_COLOR_ORDER - m_led.setPixelColor(0, s); - m_led.setBrightness(16); - m_led.show(); + writeStatus(m_status); } const RGBled::LedStatus RGBled::getSatus(void) { return m_status; -} \ No newline at end of file +} + +void RGBled::writeStatus(const RGBled::LedStatus s) +{ + RGBled::color_u u{.status = s}; + rgbLedWrite(m_led, u.color.r, u.color.g, u.color.b); +} diff --git a/RotaxMonitor/lib/led/led.h b/RotaxMonitor/lib/led/led.h index 8d026be..a6da94e 100644 --- a/RotaxMonitor/lib/led/led.h +++ b/RotaxMonitor/lib/led/led.h @@ -2,7 +2,7 @@ // System Inlcudes #include -#include +#include #define RED 0x00FF00 #define GREEN 0xFF0000 @@ -35,14 +35,29 @@ public: IDLE = GRAY }; + struct color_t + { + uint8_t a, g, r, b; + }; + + union color_u + { + uint32_t status; + color_t color; + }; + public: - RGBled(const uint8_t pin = 48, const uint8_t num = 1); + RGBled(const uint8_t pin = 48); ~RGBled(); void setStatus(const LedStatus s); const LedStatus getSatus(void); private: - Adafruit_NeoPixel m_led; + void writeStatus(const LedStatus s); + +private: LedStatus m_status = LedStatus::IDLE; + std::mutex m_mutex; + const uint8_t m_led; }; \ No newline at end of file From 684c34e2093b9316eef19f15c5bf621f5987f595 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sat, 11 Apr 2026 12:27:19 +0200 Subject: [PATCH 23/38] adding pins and task class --- RotaxMonitor/lib/led/led.h | 2 +- RotaxMonitor/src/main.cpp | 11 ++--- RotaxMonitor/src/pins.h | 85 +++++++++++++++++++++++++++++------- RotaxMonitor/src/pins_test.h | 2 +- RotaxMonitor/src/tasks.cpp | 2 +- RotaxMonitor/src/tasks.h | 41 ++++++++++++++++- 6 files changed, 118 insertions(+), 25 deletions(-) diff --git a/RotaxMonitor/lib/led/led.h b/RotaxMonitor/lib/led/led.h index a6da94e..5972709 100644 --- a/RotaxMonitor/lib/led/led.h +++ b/RotaxMonitor/lib/led/led.h @@ -47,7 +47,7 @@ public: }; public: - RGBled(const uint8_t pin = 48); + RGBled(const uint8_t pin = LED); ~RGBled(); void setStatus(const LedStatus s); diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index c45e175..eaca716 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -18,7 +18,7 @@ // Defines to enable channel B #define CH_B_ENABLE -#define TEST +//#define TEST // Debug Defines #define WIFI_SSID "AstroRotaxMonitor" @@ -52,6 +52,7 @@ void setup() IPAddress gateway(10, 11, 12, 1); IPAddress subnet(255, 255, 255, 0); WiFi.softAPConfig(local_IP, gateway, subnet); + WiFi.setTxPower(WIFI_POWER_5dBm); // reduce wifi power if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD)) { LOG_INFO("WiFi AP Mode Started"); @@ -116,7 +117,7 @@ void loop() .trig_pin_34n = TRIG_PIN_A34N, .spark_pin_12 = SPARK_PIN_A12, .spark_pin_34 = SPARK_PIN_A34}, - .rt_resets = rtTaskResets{.rst_io_peak = RST_EXT_PEAK_DETECT_A, .rst_io_sh = RST_EXT_SAMPLE_HOLD_A}}; + .rt_resets = rtTaskResets{.rst_io_peak = POT_CS_12A, .rst_io_sh = POT_CS_34A}}; #ifdef CH_B_ENABLE rtTaskParams taskB_params{ @@ -131,7 +132,7 @@ void loop() .trig_pin_34n = TRIG_PIN_B34N, .spark_pin_12 = SPARK_PIN_B12, .spark_pin_34 = SPARK_PIN_B34}, - .rt_resets = rtTaskResets{.rst_io_peak = RST_EXT_PEAK_DETECT_B, .rst_io_sh = RST_EXT_SAMPLE_HOLD_B}}; + .rt_resets = rtTaskResets{.rst_io_peak = SS_FORCE_A, .rst_io_sh = SS_INIBHIT_A12}}; #endif if (!rt_taskA_queue || !rt_taskB_queue) @@ -189,7 +190,7 @@ void loop() // Ignition A on Core 0 auto ignA_task_success = pdPASS; ignA_task_success = xTaskCreatePinnedToCore( - rtIgnitionTask, + rtIgnitionTask_run, "rtTask_A", RT_TASK_STACK, (void *)&taskA_params, @@ -203,7 +204,7 @@ void loop() #ifdef CH_B_ENABLE ignB_task_success = xTaskCreatePinnedToCore( - rtIgnitionTask, + rtIgnitionTask_run, "rtTask_B", RT_TASK_STACK, (void *)&taskB_params, diff --git a/RotaxMonitor/src/pins.h b/RotaxMonitor/src/pins.h index 4d93ef3..f690ccf 100644 --- a/RotaxMonitor/src/pins.h +++ b/RotaxMonitor/src/pins.h @@ -80,31 +80,86 @@ #define SPARK_PIN_B34 2 // ===================== -// PCA9555 (I2C EXPANDER) +// PCA9555 I/O EXPANDER BOX_A // ===================== -// --- RESET LINES --- -#define RST_EXT_PEAK_DETECT_A 0 -#define RST_EXT_SAMPLE_HOLD_A 1 -#define RST_EXT_PEAK_DETECT_B 2 -#define RST_EXT_SAMPLE_HOLD_B 3 -#define BTN_3 4 -#define BTN_4 5 -#define BTN_5 6 -#define BTN_6 7 +#define EXPANDER_A_ADDR 0x010101 + +// --- DIGITAL POT CHIP SELECT LINES --- +#define POT_CS_A12 0 +#define POT_CS_A34 1 + +// --- SOFT START FORCE LINES --- +#define SS_FORCE_A 2 +#define SS_INIBHIT_A12 3 +#define SS_INHIBIT_A34 4 + +// --- SAMPLE AND HOLD ARM AND DISCHARGE --- +#define SH_DISCH_A12 5 +#define SH_DISCH_A34 6 +#define SH_ARM_A12 7 +#define SH_ARM_A34 8 // --- RELAY --- -#define EXT_RELAY_A 8 -#define EXT_RELAY_B 9 +#define RELAY_IN_A12 9 +#define RELAY_OUT_A12 10 +#define RELAY_IN_A34 11 +#define RELAY_OUT_A34 12 // --- STATUS / BUTTON --- -#define BTN_7 10 -#define BTN_8 11 -#define STA_1 12 #define STA_2 13 #define STA_3 14 #define STA_4 15 +// ===================== +// PCA9555 I/O EXPANDER BOX_B +// ===================== + +#define EXPANDER_B_ADDR 0x101010 + +// --- DIGITAL POT CHIP SELECT LINES --- +#define POT_CS_B12 0 +#define POT_CS_B34 1 + +// --- SOFT START FORCE LINES --- +#define SS_FORCE_A 2 +#define SS_INIBHIT_B12 3 +#define SS_INHIBIT_B34 4 + +// --- SAMPLE AND HOLD ARM AND DISCHARGE --- +#define SH_DISCH_B12 5 +#define SH_DISCH_B34 6 +#define SH_ARM_B12 7 +#define SH_ARM_B34 8 + +// --- RELAY --- +#define RELAY_IN_B12 9 +#define RELAY_OUT_B12 10 +#define RELAY_IN_B34 11 +#define RELAY_OUT_B34 12 + +// --- STATUS / BUTTON --- +#define STA_2 13 +#define STA_3 14 +#define STA_4 15 + +// ===================== +// PCA9555 I/O EXPANDER INPUTS A+B +// ===================== + +#define EXPANDER_IN_ADDR 0x0a0a0a + +#define SS_A12_ON +#define SS_A12_OFF +#define SS_A34_ON +#define SS_A34_OFF + +#define SS_B12_ON +#define SS_B12_OFF +#define SS_B34_ON +#define SS_B34_OFF + + // Init Pin Functions inline void initTriggerPinsInputs() { diff --git a/RotaxMonitor/src/pins_test.h b/RotaxMonitor/src/pins_test.h index 16f196e..fda0ee5 100644 --- a/RotaxMonitor/src/pins_test.h +++ b/RotaxMonitor/src/pins_test.h @@ -65,7 +65,7 @@ #define RST_EXT_A34N 3 // --- RELAY --- -#define EXT_RELAY_A 8 +#define SH_ARM_A34 8 // Init Pin Functions diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 948a29f..5734341 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -8,7 +8,7 @@ void spark_timeout_callback(void *arg) xTaskNotify(handle, SPARK_FLAG_TIMEOUT, eSetValueWithOverwrite); } -void rtIgnitionTask(void *pvParameters) +void rtIgnitionTask::rtIgnitionTask_run(void *pvParameters) { // Invalid real time rt_task_ptr parameters, exit immediate diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index 542f96d..fd5d97f 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -2,12 +2,14 @@ #define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG // Serial debug flag -//#define DEBUG +// #define DEBUG // Arduino Libraries #include #include #include "utils.h" +#include +#include // ISR #include "isr.h" @@ -60,4 +62,39 @@ struct rtTaskParams const rtTaskResets rt_resets; // reset ping for peak detectors }; -void rtIgnitionTask(void *pvParameters); + +class rtIgnitionTask +{ + + using PShistory = PSRAMVector; + + public: + rtIgnitionTask(); + ~rtIgnitionTask(); + + static void rtIgnitionTask_run(void *pvParameters); + + void run(); + void start(); + void stop(); + +private: + bool m_running = true; + + std::shared_ptr m_devices; + std::string m_name; + TaskHandle_t m_handle; + QueueHandle_t m_queue; + rtTaskParams m_params; + + PShistory m_history_0; + PShistory m_history_1; + + std::unique_ptr m_active_history; + std::unique_ptr m_save_history; + + + fs::FS m_filesystem; + + +}; From d1b96e932c130828365d4050a4ba19cfa4100659 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sat, 11 Apr 2026 15:49:40 +0200 Subject: [PATCH 24/38] task refactoring work in progress --- RotaxMonitor/src/datasave.cpp | 108 +------------- RotaxMonitor/src/datasave.h | 14 +- RotaxMonitor/src/main.cpp | 18 +-- RotaxMonitor/src/tasks.cpp | 262 ++++++++++++++++++++++++++++++++-- RotaxMonitor/src/tasks.h | 150 ++++++++++++------- 5 files changed, 367 insertions(+), 185 deletions(-) diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index 49b9c81..6c573af 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -1,7 +1,7 @@ #include "datasave.h" #include -static const size_t min_free = 1024 * 1024; // minimum free space in LittleFS to allow saving history (1MB) + LITTLEFSGuard::LITTLEFSGuard() { @@ -22,26 +22,26 @@ LITTLEFSGuard::~LITTLEFSGuard() LOG_INFO("LittleFS unmounted successfully"); } -void ignitionBoxStatusAverage::filter(int32_t &old, const int32_t value, const uint32_t k) +void ignitionBoxStatusFiltered::filter(int32_t &old, const int32_t value, const uint32_t k) { float alpha = 1.0f / (float)k; old = old + (int32_t)(alpha * (float)(value - old)); } -void ignitionBoxStatusAverage::filter(float &old, const float value, const uint32_t k) +void ignitionBoxStatusFiltered::filter(float &old, const float value, const uint32_t k) { float alpha = 1.0f / (float)k; old = old + (float)(alpha * (float)(value - old)); } -void ignitionBoxStatusAverage::reset() +void ignitionBoxStatusFiltered::reset() { m_last = ignitionBoxStatus(); m_count = 0; m_data_valid = false; } -void ignitionBoxStatusAverage::update(const ignitionBoxStatus &new_status) +void ignitionBoxStatusFiltered::update(const ignitionBoxStatus &new_status) { if (m_count == 0 && !m_data_valid) { @@ -81,7 +81,7 @@ void ignitionBoxStatusAverage::update(const ignitionBoxStatus &new_status) } } -const bool ignitionBoxStatusAverage::get(ignitionBoxStatus &status) const +const bool ignitionBoxStatusFiltered::get(ignitionBoxStatus &status) const { if (m_data_valid) { @@ -90,7 +90,7 @@ const bool ignitionBoxStatusAverage::get(ignitionBoxStatus &status) const return m_data_valid; } -const ArduinoJson::JsonDocument ignitionBoxStatusAverage::toJson() const +const ArduinoJson::JsonDocument ignitionBoxStatusFiltered::toJson() const { ArduinoJson::JsonDocument doc; if (m_data_valid) @@ -125,97 +125,3 @@ const ArduinoJson::JsonDocument ignitionBoxStatusAverage::toJson() const return doc; } -void saveHistoryTask(void *pvParameters) -{ - const auto *params = static_cast(pvParameters); - const auto &history = *params->history; - const auto &file_path = params->file_path; - if (!params) - { - LOG_ERROR("Invalid parameters for saveHistoryTask"); - return; - } - LOG_DEBUG("Starting saving: ", file_path.c_str()); - save_history(history, file_path); - vTaskDelete(NULL); -} - -void save_history(const PSRAMVector &history, const std::filesystem::path &file_name) -{ - // Initialize SPIFFS - if (!SAVE_HISTORY_TO_LITTLEFS) - return; - - auto littlefs_guard = LITTLEFSGuard(); // use RAII guard to ensure LittleFS is properly mounted and unmounted - - if (LittleFS.totalBytes() - LittleFS.usedBytes() < min_free) // check if at least 1MB is free for saving history - { - LOG_ERROR("Not enough space in SPIFFS to save history"); - return; - } - - std::filesystem::path file_path = file_name; - if (file_name.root_path() != "/littlefs") - file_path = std::filesystem::path("/littlefs") / file_name; - - auto save_flags = std::ios::out; - if (first_save && LittleFS.exists(file_path.c_str())) - { - first_save = false; - save_flags |= std::ios::trunc; // overwrite existing file - LittleFS.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS - LOG_INFO("Saving history to LittleFS, new file:", file_path.c_str()); - } - else - { - save_flags |= std::ios::app; // append to new file - LOG_INFO("Saving history to LittleFS, appending to existing file:", file_path.c_str()); - } - - std::ofstream ofs(file_path, save_flags); - if (ofs.fail()) - { - LOG_ERROR("Failed to open file for writing"); - return; - } - - // write csv header - if (first_save) - { - ofs << "TS,\ - EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ - EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ - ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" - << std::endl; - ofs.flush(); - } - - for (const auto &entry : history) - { - ofs << std::to_string(entry.timestamp) << "," - << std::to_string(entry.coils12.n_events) << "," - << std::to_string(entry.coils12.spark_delay) << "," - << std::string(sparkStatusNames.at(entry.coils12.spark_status)) << "," - << std::to_string(entry.coils12.peak_p_in) << "," - << std::to_string(entry.coils12.peak_n_in) << "," - << std::to_string(entry.coils12.peak_p_out) << "," - << std::to_string(entry.coils12.peak_n_out) << "," - << std::string(softStartStatusNames.at(entry.coils12.sstart_status)) << "," - << std::to_string(entry.coils34.n_events) << "," - << std::to_string(entry.coils34.spark_delay) << "," - << std::string(sparkStatusNames.at(entry.coils34.spark_status)) << "," - << std::to_string(entry.coils34.peak_p_in) << "," - << std::to_string(entry.coils34.peak_n_in) << "," - << std::to_string(entry.coils34.peak_p_out) << "," - << std::to_string(entry.coils34.peak_n_out) << "," - << std::string(softStartStatusNames.at(entry.coils34.sstart_status)) << "," - << std::to_string(entry.eng_rpm) << "," - << std::to_string(entry.adc_read_time) << "," - << std::to_string(entry.n_queue_errors); - ofs << std::endl; - ofs.flush(); - } - - ofs.close(); - LOG_INFO("Ignition A history saved to LittleFS, records written: ", history.size()); -} diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index d834308..c39d21b 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -15,14 +15,6 @@ #include "psvector.h" const uint32_t max_history = 256; -const bool SAVE_HISTORY_TO_LITTLEFS = false; // Set to true to enable saving history to LittleFS, false to disable -static bool first_save = true; // flag to indicate if this is the first save (to write header) - -struct dataSaveParams -{ - const PSRAMVector *history; - const std::filesystem::path file_path; -}; class LITTLEFSGuard { @@ -31,7 +23,7 @@ public: ~LITTLEFSGuard(); }; -class ignitionBoxStatusAverage +class ignitionBoxStatusFiltered { private: ignitionBoxStatus m_last; @@ -40,8 +32,8 @@ private: bool m_data_valid = false; // flag to indicate if the average data is valid (i.e. at least one sample has been added) public: - ignitionBoxStatusAverage() = default; - ignitionBoxStatusAverage(const uint32_t max_count) : m_max_count(max_count) + ignitionBoxStatusFiltered() = default; + ignitionBoxStatusFiltered(const uint32_t max_count) : m_max_count(max_count) { m_data_valid = false; m_count = 0; diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index eaca716..81fd5eb 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -107,9 +107,9 @@ void loop() rtTaskParams taskA_params{ .rt_running = true, - .dev = &dev, + .dev = std::make_shared(dev), .rt_queue = rt_taskA_queue, - .rt_int = rtTaskInterrupts{ + .rt_int = rtTaskInterruptParams{ .isr_ptr = &trig_isr_A, .trig_pin_12p = TRIG_PIN_A12P, .trig_pin_12n = TRIG_PIN_A12N, @@ -117,14 +117,14 @@ void loop() .trig_pin_34n = TRIG_PIN_A34N, .spark_pin_12 = SPARK_PIN_A12, .spark_pin_34 = SPARK_PIN_A34}, - .rt_resets = rtTaskResets{.rst_io_peak = POT_CS_12A, .rst_io_sh = POT_CS_34A}}; + .rt_io = rtTaskIOParams{.rst_io_peak = 0, .rst_io_sh = 0}}; #ifdef CH_B_ENABLE rtTaskParams taskB_params{ .rt_running = true, .dev = &dev, .rt_queue = rt_taskB_queue, - .rt_int = rtTaskInterrupts{ + .rt_int = rtTaskInterruptParams{ .isr_ptr = &trig_isr_B, .trig_pin_12p = TRIG_PIN_B12P, .trig_pin_12n = TRIG_PIN_B12N, @@ -132,7 +132,7 @@ void loop() .trig_pin_34n = TRIG_PIN_B34N, .spark_pin_12 = SPARK_PIN_B12, .spark_pin_34 = SPARK_PIN_B34}, - .rt_resets = rtTaskResets{.rst_io_peak = SS_FORCE_A, .rst_io_sh = SS_INIBHIT_A12}}; + .rt_io = rtTaskIOParams{.rst_io_peak = SS_FORCE_A, .rst_io_sh = SS_INIBHIT_A12}}; #endif if (!rt_taskA_queue || !rt_taskB_queue) @@ -190,7 +190,7 @@ void loop() // Ignition A on Core 0 auto ignA_task_success = pdPASS; ignA_task_success = xTaskCreatePinnedToCore( - rtIgnitionTask_run, + rtIgnitionTask_realtime, "rtTask_A", RT_TASK_STACK, (void *)&taskA_params, @@ -204,7 +204,7 @@ void loop() #ifdef CH_B_ENABLE ignB_task_success = xTaskCreatePinnedToCore( - rtIgnitionTask_run, + rtIgnitionTask_realtime, "rtTask_B", RT_TASK_STACK, (void *)&taskB_params, @@ -236,8 +236,8 @@ void loop() ignitionBoxStatus ign_info_A; ignitionBoxStatus ign_info_B; - ignitionBoxStatusAverage ign_info_avg_A(filter_k); - ignitionBoxStatusAverage ign_info_avg_B(filter_k); + ignitionBoxStatusFiltered ign_info_avg_A(filter_k); + ignitionBoxStatusFiltered ign_info_avg_B(filter_k); LITTLEFSGuard fsGuard; WebPage webPage(80, LittleFS); // Initialize webserver and Websocket diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 5734341..bdb1469 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -1,5 +1,8 @@ #include "tasks.h" #include +#include + +//// GLOBAL STATIC FUNCTIONS // Timeout callback for microsecond precision void spark_timeout_callback(void *arg) @@ -8,7 +11,18 @@ void spark_timeout_callback(void *arg) xTaskNotify(handle, SPARK_FLAG_TIMEOUT, eSetValueWithOverwrite); } -void rtIgnitionTask::rtIgnitionTask_run(void *pvParameters) +// Manages queue receive, save data and callback to external tasks for communication +void rtIgnitionTask::rtIgnitionTask_manager(void *pvParameters) +{ + rtIgnitionTask *cls = (rtIgnitionTask *)pvParameters; + while (cls->m_running) + { + cls->run(); + } +} + +// Static task function +void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) { // Invalid real time rt_task_ptr parameters, exit immediate @@ -18,19 +32,18 @@ void rtIgnitionTask::rtIgnitionTask_run(void *pvParameters) vTaskDelete(NULL); } - // Task Parameters and Devices rtTaskParams *params = (rtTaskParams *)pvParameters; - const rtTaskInterrupts rt_int = params->rt_int; // copy to avoid external override - const rtTaskResets rt_rst = params->rt_resets; // copy to avoid external override + const rtTaskInterruptParams rt_int = params->rt_int; // copy to avoid external override + const rtTaskIOParams rt_rst = params->rt_io; // copy to avoid external override QueueHandle_t rt_queue = params->rt_queue; - Devices *dev = params->dev; + Devices *dev = params->dev.get(); ADS1256 *adc = dev->adc_a; PCA9555 *io = dev->io; TaskStatus_t rt_task_info; vTaskGetInfo(NULL, &rt_task_info, pdFALSE, eInvalid); - + const auto rt_task_name = pcTaskGetName(rt_task_info.xHandle); LOG_INFO("rtTask Params OK [", rt_task_name, "]"); @@ -75,7 +88,6 @@ void rtIgnitionTask::rtIgnitionTask_run(void *pvParameters) .name = "spark_timeout"}; esp_timer_create(&timer_args, &timeout_timer); - // Attach Pin Interrupts attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_12p), rt_int.isr_ptr, (void *)&isr_params_t12p, RISING); attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_12n), rt_int.isr_ptr, (void *)&isr_params_t12n, RISING); @@ -235,17 +247,13 @@ void rtIgnitionTask::rtIgnitionTask_run(void *pvParameters) ign_box_sts.adc_read_time = (int32_t)(esp_timer_get_time() - start_adc_read); } else // simulate adc read timig - vTaskDelay(pdMS_TO_TICKS(1)); + vTaskDelay(pdMS_TO_TICKS(c_adc_time)); // reset peak detectors + sample and hold // outputs on io expander if (io) { - const uint16_t iostat = io->read(); - const uint16_t rst_bitmask = (0x0001 << rt_rst.rst_io_peak); - io->write(iostat | rst_bitmask); - vTaskDelay(pdMS_TO_TICKS(1)); - io->write(iostat & ~rst_bitmask); + // [TODO] code to reset sample and hold and arm trigger level detectors } else vTaskDelay(pdMS_TO_TICKS(1)); @@ -261,7 +269,7 @@ void rtIgnitionTask::rtIgnitionTask_run(void *pvParameters) } // Delete the timeout timer esp_timer_delete(timeout_timer); - LOG_WARN("Ending realTime Task"); + LOG_WARN("rtTask Ending [", rt_task_name, "]"); // Ignition A Interrupts DETACH detachInterrupt(rt_int.trig_pin_12p); detachInterrupt(rt_int.trig_pin_12n); @@ -272,3 +280,229 @@ void rtIgnitionTask::rtIgnitionTask_run(void *pvParameters) // delete present task vTaskDelete(NULL); } + +///////////// CLASS MEMBER DEFINITIONS ///////////// +rtIgnitionTask::rtIgnitionTask(const rtTaskParams params, const uint32_t history_size, const uint32_t queue_size, const uint8_t core, std::mutex &fs_mutex, fs::FS &filesystem = LittleFS) : m_params(params), m_filesystem(filesystem), m_fs_mutex(fs_mutex), m_core(core) +{ + // create queue buffers + m_queue = xQueueCreate(queue_size, sizeof(ignitionBoxStatus)); + if (!m_queue) + { + LOG_ERROR("Unable To Create Task [", params.name.c_str(), "] queues"); + m_manager_status = rtTaskStatus::ERROR; + return; + } + else + m_params.rt_queue = m_queue; + + // create PSram history vectors + m_history_0.resize(history_size); + m_history_1.resize(history_size); + // assing active and writable history + m_active_history = std::make_unique(m_history_0.data()); + m_save_history = std::make_unique(m_history_1.data()); + + LOG_WARN("Starting Manager for [", m_params.name.c_str(), "]"); + auto task_success = xTaskCreate( + rtIgnitionTask_manager, + (std::string("man_") + m_params.name).c_str(), + m_params.rt_stack_size, + (void *)this, + 1, + &m_manager_handle); + + if (task_success != pdPASS) + { + LOG_ERROR("Unable To Create Manager for [", params.name.c_str(), "]"); + m_manager_status = rtTaskStatus::ERROR; + return; + } + + // average every 10 samples + m_info_filtered = ignitionBoxStatusFiltered(10); + m_last_data = millis(); + m_manager_status = rtTaskStatus::OK; +} + +rtIgnitionTask::~rtIgnitionTask() +{ + if (m_rt_handle) + vTaskDelete(m_rt_handle); + if (m_manager_handle) + vTaskDelete(m_manager_handle); + if (m_queue) + vQueueDelete(m_queue); +} + +void rtIgnitionTask::run() +{ + // receive new data from the queue + auto new_data = xQueueReceive(m_queue, &m_last_status, 0); // non blocking receive + + if (new_data == pdPASS) + { + m_manager_status = rtTaskStatus::RUNNING; + // if history buffer is full swap buffers and if enabled save history buffer + if (m_counter_status >= m_active_history->size()) + { + m_counter_status = 0; + m_partial_save = false; // reset partial save flag on new data cycle + std::swap(m_active_history, m_save_history); + if (m_enable_save) + save_history(*m_save_history, m_history_path); // directly call the save task function to save without delay + } + + // update filtered data + m_info_filtered.update(m_last_status); + (*m_active_history)[m_counter_status] = m_last_status; + + // update data counter + m_counter_status++; + } + else + { + if (millis() - m_last_data > c_idle_time) + m_manager_status = rtTaskStatus::IDLE; + delay(5); // yeld to another task + } +} + +const bool rtIgnitionTask::start() +{ + LOG_WARN("Starting rtTask [", m_params.name.c_str(), "]"); + auto task_success = xTaskCreatePinnedToCore( + rtIgnitionTask_realtime, + m_params.name.c_str(), + m_params.rt_stack_size, + (void *)&m_params, + m_params.rt_priority, + &m_rt_handle, + m_core); + const bool success = task_success == pdPASS && m_rt_handle != nullptr; + if (success) + m_manager_status = rtTaskStatus::IDLE; + return success; +} + +const bool rtIgnitionTask::stop() +{ + LOG_WARN("Ending Task [", m_params.name.c_str(), "]"); + if (m_rt_handle) + { + m_params.rt_running = false; + m_rt_handle = nullptr; + m_manager_status = rtTaskStatus::STOPPED; + return true; + } + return false; +} + +const ignitionBoxStatus rtIgnitionTask::getLast() const +{ + return m_last_status; +} + +const ignitionBoxStatusFiltered rtIgnitionTask::getFiltered() const +{ + return m_info_filtered; +} + +const rtIgnitionTask::rtTaskStatus rtIgnitionTask::getStatus() const +{ + return m_manager_status; +} + +void rtIgnitionTask::enableSave(const bool enable, const std::filesystem::path filename) +{ + m_enable_save = enable; + if (enable && !filename.empty()) + { + LOG_WARN("Save History Enabled Task [", m_params.name.c_str(), "]"); + m_history_path = m_filesystem.mountpoint() / filename; + } + else + { + LOG_WARN("Save History Disabled Task [", m_params.name.c_str(), "]"); + } +} + +void rtIgnitionTask::saveHistory(const rtIgnitionTask::PSHistory &history, const std::filesystem::path &file_name) +{ + // Lock filesystem mutex to avoid concurrent access + std::lock_guard fs_lock(m_fs_mutex); + + // Check for free space + if (LittleFS.totalBytes() - LittleFS.usedBytes() < history.size() * sizeof(ignitionBoxStatus) * 200) // check if at least 1MB is free for saving history + { + LOG_ERROR("Not enough space in SPIFFS to save history"); + return; + } + + // create complete file path + const std::filesystem::path mount_point = std::filesystem::path(m_filesystem.mountpoint()); + std::filesystem::path file_path = file_name; + if (file_name.root_path() != mount_point) + file_path = mount_point / file_name; + + // if firt save remove old file and create new + auto save_flags = std::ios::out; + if (m_first_save && m_filesystem.exists(file_path.c_str())) + { + m_first_save = false; + save_flags |= std::ios::trunc; // overwrite existing file + m_filesystem.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS + LOG_INFO("Saving history to Flash, new file:", file_path.c_str()); + } + else // else append to existing file + { + save_flags |= std::ios::app; // append to new file + LOG_INFO("Saving history to Flash, appending to existing file:", file_path.c_str()); + } + + std::ofstream ofs(file_path, save_flags); + if (ofs.fail()) + { + LOG_ERROR("Failed to open file for writing"); + return; + } + + // write csv header + if (m_first_save) + { + ofs << "TS,\ + EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ + EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ + ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" + << std::endl; + ofs.flush(); + } + + for (const auto &entry : history) + { + ofs << std::to_string(entry.timestamp) << "," + << std::to_string(entry.coils12.n_events) << "," + << std::to_string(entry.coils12.spark_delay) << "," + << std::string(sparkStatusNames.at(entry.coils12.spark_status)) << "," + << std::to_string(entry.coils12.peak_p_in) << "," + << std::to_string(entry.coils12.peak_n_in) << "," + << std::to_string(entry.coils12.peak_p_out) << "," + << std::to_string(entry.coils12.peak_n_out) << "," + << std::string(softStartStatusNames.at(entry.coils12.sstart_status)) << "," + << std::to_string(entry.coils34.n_events) << "," + << std::to_string(entry.coils34.spark_delay) << "," + << std::string(sparkStatusNames.at(entry.coils34.spark_status)) << "," + << std::to_string(entry.coils34.peak_p_in) << "," + << std::to_string(entry.coils34.peak_n_in) << "," + << std::to_string(entry.coils34.peak_p_out) << "," + << std::to_string(entry.coils34.peak_n_out) << "," + << std::string(softStartStatusNames.at(entry.coils34.sstart_status)) << "," + << std::to_string(entry.eng_rpm) << "," + << std::to_string(entry.adc_read_time) << "," + << std::to_string(entry.n_queue_errors); + ofs << std::endl; + ofs.flush(); + } + + ofs.close(); + LOG_INFO("Ignition Box history saved to Flash, records written: ", history.size()); +} diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index fd5d97f..3686925 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -10,6 +10,9 @@ #include "utils.h" #include #include +#include +#include +#include // ISR #include "isr.h" @@ -33,68 +36,115 @@ static const std::map names = { }; #endif -// RT task Interrupt parameters -struct rtTaskInterrupts -{ - void (*isr_ptr)(void *); - const uint8_t trig_pin_12p; - const uint8_t trig_pin_12n; - const uint8_t trig_pin_34p; - const uint8_t trig_pin_34n; - const uint8_t spark_pin_12; - const uint8_t spark_pin_34; -}; - -// RT Task Peak Detector Reset pins -struct rtTaskResets -{ - const uint8_t rst_io_peak; - const uint8_t rst_io_sh; -}; - -// RT task parameters -struct rtTaskParams -{ - bool rt_running; // run flag, false to terminate - Devices *dev; - const QueueHandle_t rt_queue; - const rtTaskInterrupts rt_int; // interrupt pins to attach - const rtTaskResets rt_resets; // reset ping for peak detectors -}; - - class rtIgnitionTask { - - using PShistory = PSRAMVector; - - public: - rtIgnitionTask(); + using PSHistory = PSRAMVector; + // RT task Interrupt parameters + struct rtTaskInterruptParams + { + void (*isr_ptr)(void *); + const uint8_t trig_pin_12p; + const uint8_t trig_pin_12n; + const uint8_t trig_pin_34p; + const uint8_t trig_pin_34n; + const uint8_t spark_pin_12; + const uint8_t spark_pin_34; + }; + + // RT Task Peak Detector Reset pins + struct rtTaskIOParams + { + const uint32_t expander_addr; + const uint8_t pot_cs_a12; + const uint8_t pot_cs_a34; + const uint8_t ss_force_a; + const uint8_t ss_inhibit_a12; + const uint8_t ss_inhibit_a34; + const uint8_t sh_disch_a12; + const uint8_t sh_disch_a34; + const uint8_t sh_arm_a12; + const uint8_t sh_arm_a34; + const uint8_t relay_in_a12; + const uint8_t relay_in_a34; + const uint8_t relay_out_a12; + const uint8_t relay_out_a34; + }; + + // RT task parameters + struct rtTaskParams + { + bool rt_running; // run flag, false to terminate + const std::string name; + const std::shared_ptr dev; + const uint32_t rt_stack_size; + const uint32_t rt_priority; + const rtTaskInterruptParams rt_int; // interrupt pins to attach + const rtTaskIOParams rt_io; // reset ping for peak detectors + QueueHandle_t rt_queue; // queue for task io + }; + + enum rtTaskStatus + { + INIT, + OK, + ERROR, + RUNNING, + IDLE, + STOPPED + }; + +public: + rtIgnitionTask(const rtTaskParams params, const uint32_t history_size, const uint32_t queue_size, const uint8_t core, std::mutex &fs_mutex, fs::FS &filesystem = LittleFS); ~rtIgnitionTask(); - - static void rtIgnitionTask_run(void *pvParameters); - + void run(); - void start(); - void stop(); + const bool start(); + const bool stop(); + + const ignitionBoxStatus getLast() const; + const ignitionBoxStatusFiltered getFiltered() const; + + const rtTaskStatus getStatus() const; + + void enableSave(const bool enable, const std::filesystem::path filename); + +private: + void rtIgnitionTask::saveHistory(const rtIgnitionTask::PSHistory &history, const std::filesystem::path &file_name); + +private: // static functions for FreeRTOS + static void rtIgnitionTask_manager(void *pvParameters); + static void rtIgnitionTask_realtime(void *pvParameters); private: bool m_running = true; + rtTaskStatus m_manager_status = INIT; - std::shared_ptr m_devices; - std::string m_name; - TaskHandle_t m_handle; - QueueHandle_t m_queue; rtTaskParams m_params; + const uint8_t m_core; - PShistory m_history_0; - PShistory m_history_1; + TaskHandle_t m_rt_handle = nullptr; + TaskHandle_t m_manager_handle = nullptr; + QueueHandle_t m_queue = nullptr; - std::unique_ptr m_active_history; - std::unique_ptr m_save_history; + bool m_enable_save = false; + std::filesystem::path m_history_path; + PSHistory m_history_0; + PSHistory m_history_1; + std::unique_ptr m_active_history; + std::unique_ptr m_save_history; + fs::FS &m_filesystem; + std::mutex &m_fs_mutex; + bool m_partial_save = false; + bool m_first_save = true; - fs::FS m_filesystem; - + uint32_t m_counter_status = 0; + uint32_t m_last_data = 0; + ignitionBoxStatus m_last_status; + ignitionBoxStatusFiltered m_info_filtered; + static const uint32_t c_idle_time = 2000; // in mS + static const uint8_t c_spark_timeout_max = 500; // uS + static const uint8_t c_adc_time = 4; // in mS + static const uint8_t c_io_time = 2; // in mS }; From fdba6d5ad58c4736c72e5c3524a333c148949bd7 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sat, 11 Apr 2026 16:39:59 +0200 Subject: [PATCH 25/38] refactor continued, at least it compiles --- RotaxMonitor/lib/led/led.h | 2 +- RotaxMonitor/src/datasave.h | 4 - RotaxMonitor/src/devices.h | 48 ++++-- RotaxMonitor/src/main.cpp | 307 +++++++++++------------------------- RotaxMonitor/src/pins.h | 2 +- RotaxMonitor/src/tasks.cpp | 22 ++- RotaxMonitor/src/tasks.h | 36 +++-- 7 files changed, 162 insertions(+), 259 deletions(-) diff --git a/RotaxMonitor/lib/led/led.h b/RotaxMonitor/lib/led/led.h index 5972709..a6da94e 100644 --- a/RotaxMonitor/lib/led/led.h +++ b/RotaxMonitor/lib/led/led.h @@ -47,7 +47,7 @@ public: }; public: - RGBled(const uint8_t pin = LED); + RGBled(const uint8_t pin = 48); ~RGBled(); void setStatus(const LedStatus s); diff --git a/RotaxMonitor/src/datasave.h b/RotaxMonitor/src/datasave.h index c39d21b..b27308a 100644 --- a/RotaxMonitor/src/datasave.h +++ b/RotaxMonitor/src/datasave.h @@ -48,7 +48,3 @@ private: void filter(int32_t &old, const int32_t value, const uint32_t k); void filter(float &old, const float value, const uint32_t k); }; - -// Task and function declarations -void saveHistoryTask(void *pvParameters); -void save_history(const PSRAMVector &history, const std::filesystem::path &file_path); diff --git a/RotaxMonitor/src/devices.h b/RotaxMonitor/src/devices.h index d43d2c1..740ff0e 100644 --- a/RotaxMonitor/src/devices.h +++ b/RotaxMonitor/src/devices.h @@ -3,33 +3,53 @@ // Library defines #define ADS1256_SPI_ALREADY_STARTED +// System Includes +#include + // Device Libraries #include #include #include // ADC Channel mapping -#define ADC_CH_PEAK_12P_IN SING_0 -#define ADC_CH_PEAK_12N_IN SING_1 -#define ADC_CH_PEAK_34P_IN SING_2 -#define ADC_CH_PEAK_34N_IN SING_3 -#define ADC_CH_PEAK_12P_OUT SING_4 -#define ADC_CH_PEAK_12N_OUT SING_5 -#define ADC_CH_PEAK_34P_OUT SING_6 -#define ADC_CH_PEAK_34N_OUT SING_7 +#define ADC_CH_PEAK_12P_IN SING_0 +#define ADC_CH_PEAK_12N_IN SING_1 +#define ADC_CH_PEAK_34P_IN SING_2 +#define ADC_CH_PEAK_34N_IN SING_3 +#define ADC_CH_PEAK_12P_OUT SING_4 +#define ADC_CH_PEAK_12N_OUT SING_5 +#define ADC_CH_PEAK_34P_OUT SING_6 +#define ADC_CH_PEAK_34N_OUT SING_7 // Device Pointer structs for tasks -struct Devices { - AD5292 *pot_a = NULL, *pot_b = NULL; - ADS1256 *adc_a = NULL, *adc_b = NULL; - PCA9555* io = NULL; +struct Devices +{ + std::unique_ptr m_spi_a = nullptr; + std::unique_ptr m_spi_b = nullptr; + + std::unique_ptr m_pot_a = nullptr; + std::unique_ptr m_pot_b = nullptr; + + std::unique_ptr m_adc_a = nullptr; + std::unique_ptr m_adc_b = nullptr; + + std::unique_ptr m_expander_a = nullptr; + std::unique_ptr m_expander_b = nullptr; + std::unique_ptr m_expander_inputs_ab = nullptr; + + std::mutex m_spi_a_mutex; + std::mutex m_spi_b_mutex; + + std::mutex m_i2c_mutex; }; // Adc read channel wrapper to selet mux before reading -inline float adcReadChannel(ADS1256* adc, const uint8_t ch){ +inline float adcReadChannel(ADS1256 *adc, const uint8_t ch) +{ adc->setMUX(ch); // scarta 3 conversioni - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) + { adc->readSingle(); } // ora lettura valida a 30kSPS → ~100 µs di settling diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 81fd5eb..cd5f6e0 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -18,7 +18,7 @@ // Defines to enable channel B #define CH_B_ENABLE -//#define TEST +// #define TEST // Debug Defines #define WIFI_SSID "AstroRotaxMonitor" @@ -52,7 +52,7 @@ void setup() IPAddress gateway(10, 11, 12, 1); IPAddress subnet(255, 255, 255, 0); WiFi.softAPConfig(local_IP, gateway, subnet); - WiFi.setTxPower(WIFI_POWER_5dBm); // reduce wifi power + WiFi.setTxPower(WIFI_POWER_5dBm); // reduce wifi power if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD)) { LOG_INFO("WiFi AP Mode Started"); @@ -81,71 +81,9 @@ void loop() RGBled led; led.setStatus(RGBled::LedStatus::INIT); bool running = true; - const uint32_t max_queue = 128; - const uint32_t filter_k = 10; + std::mutex fs_mutex; - PSRAMVector ignA_history_0(max_history); - PSRAMVector ignA_history_1(max_history); - auto *active_history_A = &ignA_history_0; - auto *writable_history_A = &ignA_history_1; - -#ifdef CH_B_ENABLE - PSRAMVector ignB_history_0(max_history); - PSRAMVector ignB_history_1(max_history); - auto *active_history_B = &ignB_history_0; - auto *writable_history_B = &ignB_history_1; -#endif - - // Resources Initialization - Devices dev; - // Task handle - TaskHandle_t trigA_TaskHandle = NULL; - TaskHandle_t trigB_TaskHandle = NULL; - // Data Queue for real time task to main loop communication - QueueHandle_t rt_taskA_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); - QueueHandle_t rt_taskB_queue = xQueueCreate(max_queue, sizeof(ignitionBoxStatus)); - - rtTaskParams taskA_params{ - .rt_running = true, - .dev = std::make_shared(dev), - .rt_queue = rt_taskA_queue, - .rt_int = rtTaskInterruptParams{ - .isr_ptr = &trig_isr_A, - .trig_pin_12p = TRIG_PIN_A12P, - .trig_pin_12n = TRIG_PIN_A12N, - .trig_pin_34p = TRIG_PIN_A34P, - .trig_pin_34n = TRIG_PIN_A34N, - .spark_pin_12 = SPARK_PIN_A12, - .spark_pin_34 = SPARK_PIN_A34}, - .rt_io = rtTaskIOParams{.rst_io_peak = 0, .rst_io_sh = 0}}; - -#ifdef CH_B_ENABLE - rtTaskParams taskB_params{ - .rt_running = true, - .dev = &dev, - .rt_queue = rt_taskB_queue, - .rt_int = rtTaskInterruptParams{ - .isr_ptr = &trig_isr_B, - .trig_pin_12p = TRIG_PIN_B12P, - .trig_pin_12n = TRIG_PIN_B12N, - .trig_pin_34p = TRIG_PIN_B34P, - .trig_pin_34n = TRIG_PIN_B34N, - .spark_pin_12 = SPARK_PIN_B12, - .spark_pin_34 = SPARK_PIN_B34}, - .rt_io = rtTaskIOParams{.rst_io_peak = SS_FORCE_A, .rst_io_sh = SS_INIBHIT_A12}}; -#endif - - if (!rt_taskA_queue || !rt_taskB_queue) - { - LOG_ERROR("Unable To Create task queues"); - LOG_ERROR("5 seconds to restart..."); - vTaskDelay(pdMS_TO_TICKS(5000)); - esp_restart(); - } - else - LOG_DEBUG("Task Variables OK"); - - // Spi ok flags + //////// INIT SPI PORTS //////// bool spiA_ok = true; bool spiB_ok = true; // Init 2 SPI interfaces @@ -153,11 +91,9 @@ void loop() spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 #ifdef CH_B_ENABLE -#ifndef TEST SPIClass SPI_B(HSPI); spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 -#endif #endif if (!spiA_ok || !spiB_ok) { @@ -168,52 +104,91 @@ void loop() } LOG_DEBUG("Init SPI OK"); -#ifndef TEST - // Init ADC_A - dev.adc_a = new ADS1256(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); - dev.adc_a->InitializeADC(); - dev.adc_a->setPGA(PGA_1); - dev.adc_a->setDRATE(DRATE_7500SPS); -#endif -#ifdef CH_B_ENABLE -#ifndef TEST - // Init ADC_B - dev.adc_a = new ADS1256(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); - dev.adc_a->InitializeADC(); - dev.adc_a->setPGA(PGA_1); - dev.adc_a->setDRATE(DRATE_1000SPS); -#endif -#endif + // Resources Initialization + std::shared_ptr dev = std::make_shared(); + dev->m_spi_a = std::make_unique(SPI_A); + dev->m_spi_b = std::make_unique(SPI_B); - LOG_DEBUG("Init ADC OK"); + // Init ADC_A + dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); + dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); + + dev->m_adc_a->InitializeADC(); + dev->m_adc_a->setPGA(PGA_1); + dev->m_adc_a->setDRATE(DRATE_7500SPS); + + dev->m_adc_b->InitializeADC(); + dev->m_adc_b->setPGA(PGA_1); + dev->m_adc_b->setDRATE(DRATE_7500SPS); + + const rtIgnitionTask::rtTaskParams taskA_params{ + .rt_running = true, + .name = "rtIgnTask_A", + .rt_stack_size = RT_TASK_STACK, + .rt_priority = RT_TASK_PRIORITY, + .rt_int = rtIgnitionTask::rtTaskInterruptParams{ + .isr_ptr = &trig_isr_A, + .trig_pin_12p = TRIG_PIN_A12P, + .trig_pin_12n = TRIG_PIN_A12N, + .trig_pin_34p = TRIG_PIN_A34P, + .trig_pin_34n = TRIG_PIN_A34N, + .spark_pin_12 = SPARK_PIN_A12, + .spark_pin_34 = SPARK_PIN_A34}, + .rt_io = rtIgnitionTask::rtTaskIOParams{ + .pot_cs_12 = POT_CS_A12, + .pot_cs_34 = POT_CS_A34, + .ss_force = SS_FORCE_A, + .ss_inhibit_12 = SS_INIBHIT_A12, + .ss_inhibit_34 = SS_INHIBIT_A34, + .sh_disch_12 = SH_DISCH_A12, + .sh_disch_34 = SH_DISCH_A34, + .sh_arm_12 = SH_ARM_A12, + .sh_arm_34 = SH_ARM_A34, + .relay_in_12 = RELAY_IN_A12, + .relay_in_34 = RELAY_OUT_A12, + .relay_out_12 = RELAY_IN_A34, + .relay_out_34 = RELAY_OUT_A34, + }, + .rt_queue = nullptr, + .dev = dev}; + + const rtIgnitionTask::rtTaskParams taskB_params{ + .rt_running = true, + .name = "rtIgnTask_B", + .rt_stack_size = RT_TASK_STACK, + .rt_priority = RT_TASK_PRIORITY, + .rt_int = rtIgnitionTask::rtTaskInterruptParams{ + .isr_ptr = &trig_isr_B, + .trig_pin_12p = TRIG_PIN_B12P, + .trig_pin_12n = TRIG_PIN_B12N, + .trig_pin_34p = TRIG_PIN_B34P, + .trig_pin_34n = TRIG_PIN_B34N, + .spark_pin_12 = SPARK_PIN_B12, + .spark_pin_34 = SPARK_PIN_B34}, + .rt_io = rtIgnitionTask::rtTaskIOParams{ + .pot_cs_12 = POT_CS_B12, + .pot_cs_34 = POT_CS_B34, + .ss_force = SS_FORCE_B, + .ss_inhibit_12 = SS_INIBHIT_B12, + .ss_inhibit_34 = SS_INHIBIT_B34, + .sh_disch_12 = SH_DISCH_B12, + .sh_disch_34 = SH_DISCH_B34, + .sh_arm_12 = SH_ARM_B12, + .sh_arm_34 = SH_ARM_B34, + .relay_in_12 = RELAY_IN_B12, + .relay_in_34 = RELAY_OUT_B12, + .relay_out_12 = RELAY_IN_B34, + .relay_out_34 = RELAY_OUT_B34, + }, + .rt_queue = nullptr, + .dev = dev}; + + auto task_A = rtIgnitionTask(taskA_params, 1024, 128, CORE_0, fs_mutex); + auto task_B = rtIgnitionTask(taskA_params, 1024, 128, CORE_1, fs_mutex); // Ignition A on Core 0 - auto ignA_task_success = pdPASS; - ignA_task_success = xTaskCreatePinnedToCore( - rtIgnitionTask_realtime, - "rtTask_A", - RT_TASK_STACK, - (void *)&taskA_params, - RT_TASK_PRIORITY, - &trigA_TaskHandle, - CORE_0); - delay(100); // give some time to the thread to start - - // Ignition B on Core 1 - auto ignB_task_success = pdPASS; - -#ifdef CH_B_ENABLE - ignB_task_success = xTaskCreatePinnedToCore( - rtIgnitionTask_realtime, - "rtTask_B", - RT_TASK_STACK, - (void *)&taskB_params, - RT_TASK_PRIORITY, // priorità leggermente più alta - &trigB_TaskHandle, - CORE_1); - delay(100); // give some time to the thread to start -#endif - + auto ignA_task_success = task_A.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL; + auto ignB_task_success = task_B.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL; if (ignA_task_success != pdPASS || ignB_task_success != pdPASS) { LOG_ERROR("Unable to initialize ISR task"); @@ -225,123 +200,23 @@ void loop() LOG_DEBUG("Real Time Tasks A & B initialized"); led.setStatus(RGBled::LedStatus::OK); - bool partial_save = false; // flag to indicate if a partial save has been done after a timeout - auto last_data = millis(); - auto last_info = millis(); - - uint32_t counter_a = 0; - uint32_t counter_b = 0; - uint32_t wait_count = 0; - - ignitionBoxStatus ign_info_A; - ignitionBoxStatus ign_info_B; - - ignitionBoxStatusFiltered ign_info_avg_A(filter_k); - ignitionBoxStatusFiltered ign_info_avg_B(filter_k); - LITTLEFSGuard fsGuard; WebPage webPage(80, LittleFS); // Initialize webserver and Websocket + uint32_t last_loop = millis(); //////////////// INNER LOOP ///////////////////// while (running) { - auto dataA = pdFALSE; - auto dataB = pdFALSE; + led.setStatus(RGBled::LedStatus::IDLE); + delay(100); - dataA = xQueueReceive(rt_taskA_queue, &ign_info_A, 0); - if (counter_a >= active_history_A->size()) // not concurrent with write task - { - counter_a = 0; - partial_save = false; // reset partial save flag on new data cycle - swapHistory(active_history_A, writable_history_A); - save_history(*writable_history_A, "ignition_historyA.csv"); // directly call the save task function to save without delay - } - -#ifdef CH_B_ENABLE - dataB = xQueueReceive(rt_taskB_queue, &ign_info_B, 0); - if (counter_b >= active_history_B->size()) // not concurrent with write task - { - counter_b = 0; - partial_save = false; // reset partial save flag on new data cycle - swapHistory(active_history_B, writable_history_B); - save_history(*writable_history_B, "ignition_historyB.csv"); // directly call the save task function to save without delay - } -#endif - // Update last data - if (dataA == pdTRUE || dataB == pdTRUE) - last_data = millis(); - - // Update Led color - if (dataA == pdTRUE && dataB == pdFALSE) - led.setStatus(RGBled::DATA_A); - else if (dataB == pdTRUE && dataA == pdFALSE) - led.setStatus(RGBled::DATA_B); - else - led.setStatus(RGBled::DATA_ALL); - - if (dataA == pdTRUE) - { - (*active_history_A)[counter_a++ % active_history_A->size()] = ign_info_A; - ign_info_avg_A.update(ign_info_A); // update moving average with latest ignition status - // Serial.printf("Data Received A: %d/%d\n\r", counter_a, (*active_history_A).size()); - if (counter_a % filter_k == 0) // send data every 10 samples - { - ArduinoJson::JsonDocument wsData; - wsData["box_a"] = ign_info_avg_A.toJson(); - wsData["box_b"] = JsonObject(); - webPage.sendWsData(wsData.as()); - } - } -#ifdef CH_B_ENABLE - if (dataB == pdTRUE) - { - (*active_history_B)[counter_b++ % active_history_B->size()] = ign_info_B; - ign_info_avg_B.update(ign_info_B); // update moving average with latest ignition status - // Serial.printf("Data Received B: %d/%d\n\r", counter_b, (*active_history_B).size()); - if (counter_b % filter_k == 0) // send data every 10 samples - { - ArduinoJson::JsonDocument wsData; - wsData["box_a"] = JsonObject(); - wsData["box_b"] = ign_info_avg_B.toJson(); - webPage.sendWsData(wsData.as()); - } - } -#endif - if (dataA == pdFALSE && dataB == pdFALSE && (millis() - last_data) > 2000) - { - if (!partial_save && counter_a > 0) // if timeout occurs but we have unsaved data, save it before next timeout - { - active_history_A->resize(counter_a); // resize active history to actual number of records received to avoid saving empty records - save_history(*active_history_A, "ignition_history_A.csv"); - active_history_A->resize(max_history); // resize back to max history size for next data cycle -#ifdef CH_B_ENABLE - active_history_B->resize(counter_a); // resize active history to actual number of records received to avoid saving empty records - save_history(*active_history_B, "ignition_history_B.csv"); - active_history_B->resize(max_history); // resize back to max history size for next data cycle -#endif - counter_a = 0; // reset counter after saving - counter_b = 0; // reset counter after saving - - partial_save = true; - first_save = true; - } - // Serial.printf("[%d] Waiting for data...\r", wait_count++); - led.setStatus(RGBled::LedStatus::IDLE); - delay(100); - } - - if ((millis() - last_info) > 1000) + if ((millis() - last_loop) > 1000) { clearScreen(); Serial.println(); printRunningTasksMod(Serial); - last_info = millis(); + last_loop = millis(); } } //////////////// INNER LOOP ///////////////////// - if (trigA_TaskHandle) - vTaskDelete(trigA_TaskHandle); - if (trigB_TaskHandle) - vTaskDelete(trigB_TaskHandle); - } ////////////////////// MAIN LOOP ////////////////////// diff --git a/RotaxMonitor/src/pins.h b/RotaxMonitor/src/pins.h index f690ccf..1104ac2 100644 --- a/RotaxMonitor/src/pins.h +++ b/RotaxMonitor/src/pins.h @@ -122,7 +122,7 @@ #define POT_CS_B34 1 // --- SOFT START FORCE LINES --- -#define SS_FORCE_A 2 +#define SS_FORCE_B 2 #define SS_INIBHIT_B12 3 #define SS_INHIBIT_B34 4 diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index bdb1469..647b66b 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -38,8 +38,8 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) const rtTaskIOParams rt_rst = params->rt_io; // copy to avoid external override QueueHandle_t rt_queue = params->rt_queue; Devices *dev = params->dev.get(); - ADS1256 *adc = dev->adc_a; - PCA9555 *io = dev->io; + ADS1256 *adc = dev->m_adc_a.get(); + PCA9555 *io = dev->m_expander_a.get(); TaskStatus_t rt_task_info; vTaskGetInfo(NULL, &rt_task_info, pdFALSE, eInvalid); @@ -282,7 +282,7 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) } ///////////// CLASS MEMBER DEFINITIONS ///////////// -rtIgnitionTask::rtIgnitionTask(const rtTaskParams params, const uint32_t history_size, const uint32_t queue_size, const uint8_t core, std::mutex &fs_mutex, fs::FS &filesystem = LittleFS) : m_params(params), m_filesystem(filesystem), m_fs_mutex(fs_mutex), m_core(core) +rtIgnitionTask::rtIgnitionTask(const rtTaskParams params, const uint32_t history_size, const uint32_t queue_size, const uint8_t core, std::mutex &fs_mutex, fs::FS &filesystem) : m_params(params), m_filesystem(filesystem), m_fs_mutex(fs_mutex), m_core(core), m_max_history(history_size) { // create queue buffers m_queue = xQueueCreate(queue_size, sizeof(ignitionBoxStatus)); @@ -299,8 +299,8 @@ rtIgnitionTask::rtIgnitionTask(const rtTaskParams params, const uint32_t history m_history_0.resize(history_size); m_history_1.resize(history_size); // assing active and writable history - m_active_history = std::make_unique(m_history_0.data()); - m_save_history = std::make_unique(m_history_1.data()); + m_active_history = std::unique_ptr(&m_history_0); + m_save_history = std::unique_ptr(&m_history_1); LOG_WARN("Starting Manager for [", m_params.name.c_str(), "]"); auto task_success = xTaskCreate( @@ -349,7 +349,7 @@ void rtIgnitionTask::run() m_partial_save = false; // reset partial save flag on new data cycle std::swap(m_active_history, m_save_history); if (m_enable_save) - save_history(*m_save_history, m_history_path); // directly call the save task function to save without delay + saveHistory(*m_save_history, m_history_path); // directly call the save task function to save without delay } // update filtered data @@ -361,8 +361,16 @@ void rtIgnitionTask::run() } else { - if (millis() - m_last_data > c_idle_time) + if (millis() - m_last_data > c_idle_time){ + if (m_counter_status > 0 && !m_partial_save){ + m_active_history->resize(m_counter_status); + saveHistory(*m_active_history, m_history_path); + m_active_history->resize(m_max_history); + m_counter_status = 0; + m_partial_save = true; + } m_manager_status = rtTaskStatus::IDLE; + } delay(5); // yeld to another task } } diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index 3686925..a37cd9d 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -13,6 +13,7 @@ #include #include #include +#include // ISR #include "isr.h" @@ -39,6 +40,8 @@ static const std::map names = { class rtIgnitionTask { using PSHistory = PSRAMVector; + +public: // RT task Interrupt parameters struct rtTaskInterruptParams { @@ -55,19 +58,19 @@ class rtIgnitionTask struct rtTaskIOParams { const uint32_t expander_addr; - const uint8_t pot_cs_a12; - const uint8_t pot_cs_a34; - const uint8_t ss_force_a; - const uint8_t ss_inhibit_a12; - const uint8_t ss_inhibit_a34; - const uint8_t sh_disch_a12; - const uint8_t sh_disch_a34; - const uint8_t sh_arm_a12; - const uint8_t sh_arm_a34; - const uint8_t relay_in_a12; - const uint8_t relay_in_a34; - const uint8_t relay_out_a12; - const uint8_t relay_out_a34; + const uint8_t pot_cs_12; + const uint8_t pot_cs_34; + const uint8_t ss_force; + const uint8_t ss_inhibit_12; + const uint8_t ss_inhibit_34; + const uint8_t sh_disch_12; + const uint8_t sh_disch_34; + const uint8_t sh_arm_12; + const uint8_t sh_arm_34; + const uint8_t relay_in_12; + const uint8_t relay_in_34; + const uint8_t relay_out_12; + const uint8_t relay_out_34; }; // RT task parameters @@ -75,12 +78,12 @@ class rtIgnitionTask { bool rt_running; // run flag, false to terminate const std::string name; - const std::shared_ptr dev; const uint32_t rt_stack_size; const uint32_t rt_priority; const rtTaskInterruptParams rt_int; // interrupt pins to attach const rtTaskIOParams rt_io; // reset ping for peak detectors QueueHandle_t rt_queue; // queue for task io + const std::shared_ptr dev; }; enum rtTaskStatus @@ -109,7 +112,7 @@ public: void enableSave(const bool enable, const std::filesystem::path filename); private: - void rtIgnitionTask::saveHistory(const rtIgnitionTask::PSHistory &history, const std::filesystem::path &file_name); + void saveHistory(const rtIgnitionTask::PSHistory &history, const std::filesystem::path &file_name); private: // static functions for FreeRTOS static void rtIgnitionTask_manager(void *pvParameters); @@ -128,6 +131,7 @@ private: bool m_enable_save = false; std::filesystem::path m_history_path; + const uint32_t m_max_history; PSHistory m_history_0; PSHistory m_history_1; std::unique_ptr m_active_history; @@ -144,7 +148,7 @@ private: ignitionBoxStatusFiltered m_info_filtered; static const uint32_t c_idle_time = 2000; // in mS - static const uint8_t c_spark_timeout_max = 500; // uS + static const uint32_t c_spark_timeout_max = 500; // uS static const uint8_t c_adc_time = 4; // in mS static const uint8_t c_io_time = 2; // in mS }; From 095aa59f3642c38dccafa3c7fbee23c04e23ec6d Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sun, 12 Apr 2026 01:45:32 +0200 Subject: [PATCH 26/38] task refactoring working, sometimes misses events, check priorities --- RotaxMonitor/lib/led/led.h | 2 +- RotaxMonitor/platformio.ini | 4 +- RotaxMonitor/src/isr.h | 2 +- RotaxMonitor/src/main.cpp | 78 +++++++++++++++-------- RotaxMonitor/src/tasks.cpp | 46 +++++++++----- RotaxMonitor/src/tasks.h | 7 +- RotaxMonitor/src/utils.cpp | 113 +++++++++++++++++++++++++++++++-- RotaxMonitor/src/webserver.cpp | 2 + 8 files changed, 202 insertions(+), 52 deletions(-) diff --git a/RotaxMonitor/lib/led/led.h b/RotaxMonitor/lib/led/led.h index a6da94e..0770314 100644 --- a/RotaxMonitor/lib/led/led.h +++ b/RotaxMonitor/lib/led/led.h @@ -37,7 +37,7 @@ public: struct color_t { - uint8_t a, g, r, b; + uint8_t a, r, g, b; }; union color_u diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index e7fb4f6..5ba4f2c 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -64,7 +64,7 @@ build_flags = -DARDUINO_USB_MODE=0 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 -DCONFIG_ASYNC_TCP_PRIORITY=21 - -DCONFIG_ASYNC_TCP_QUEUE_SIZE=64 + -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 -DCONFIG_ASYNC_TCP_RUNNING_CORE=1 - -DCONFIG_ASYNC_TCP_STACK_SIZE=4096 + -DCONFIG_ASYNC_TCP_STACK_SIZE=8192 -fstack-protector-all diff --git a/RotaxMonitor/src/isr.h b/RotaxMonitor/src/isr.h index bd1bea5..1f1d2e7 100644 --- a/RotaxMonitor/src/isr.h +++ b/RotaxMonitor/src/isr.h @@ -17,7 +17,7 @@ #define CORE_0 0 #define CORE_1 1 #define RT_TASK_STACK 2048 // in words -#define RT_TASK_PRIORITY (configMAX_PRIORITIES - 6) // highest priority after wifi tasks +#define RT_TASK_PRIORITY (configMAX_PRIORITIES - 5) // highest priority after wifi tasks struct isrParams { diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index cd5f6e0..daa940e 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -31,7 +31,7 @@ void setup() // Setup Logger LOG_ATTACH_SERIAL(Serial); - LOG_SET_LEVEL(DebugLogLevel::LVL_INFO); + LOG_SET_LEVEL(DebugLogLevel::LVL_DEBUG); // Print Processor Info LOG_DEBUG("ESP32 Chip:", ESP.getChipModel()); @@ -82,19 +82,20 @@ void loop() led.setStatus(RGBled::LedStatus::INIT); bool running = true; std::mutex fs_mutex; + LITTLEFSGuard fsGuard; //////// INIT SPI PORTS //////// bool spiA_ok = true; bool spiB_ok = true; // Init 2 SPI interfaces - SPIClass SPI_A(FSPI); - spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); - SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 -#ifdef CH_B_ENABLE - SPIClass SPI_B(HSPI); - spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); - SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 -#endif +// SPIClass SPI_A(FSPI); +// spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); +// SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 +// #ifdef CH_B_ENABLE +// SPIClass SPI_B(HSPI); +// spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); +// SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 +// #endif if (!spiA_ok || !spiB_ok) { LOG_ERROR("Unable to Initialize SPI Busses"); @@ -106,20 +107,20 @@ void loop() // Resources Initialization std::shared_ptr dev = std::make_shared(); - dev->m_spi_a = std::make_unique(SPI_A); - dev->m_spi_b = std::make_unique(SPI_B); + // dev->m_spi_a = std::make_unique(SPI_A); + // dev->m_spi_b = std::make_unique(SPI_B); - // Init ADC_A - dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); - dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); + // // Init ADC_A + // dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); + // dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); - dev->m_adc_a->InitializeADC(); - dev->m_adc_a->setPGA(PGA_1); - dev->m_adc_a->setDRATE(DRATE_7500SPS); + // dev->m_adc_a->InitializeADC(); + // dev->m_adc_a->setPGA(PGA_1); + // dev->m_adc_a->setDRATE(DRATE_7500SPS); - dev->m_adc_b->InitializeADC(); - dev->m_adc_b->setPGA(PGA_1); - dev->m_adc_b->setDRATE(DRATE_7500SPS); + // dev->m_adc_b->InitializeADC(); + // dev->m_adc_b->setPGA(PGA_1); + // dev->m_adc_b->setDRATE(DRATE_7500SPS); const rtIgnitionTask::rtTaskParams taskA_params{ .rt_running = true, @@ -183,8 +184,9 @@ void loop() .rt_queue = nullptr, .dev = dev}; - auto task_A = rtIgnitionTask(taskA_params, 1024, 128, CORE_0, fs_mutex); - auto task_B = rtIgnitionTask(taskA_params, 1024, 128, CORE_1, fs_mutex); + auto task_A = rtIgnitionTask(taskA_params, 4096, 256, CORE_1, fs_mutex); + delay(50); + auto task_B = rtIgnitionTask(taskB_params, 4096, 256, CORE_1, fs_mutex); // Ignition A on Core 0 auto ignA_task_success = task_A.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL; @@ -197,23 +199,43 @@ void loop() esp_restart(); } + const bool tasK_A_rt = task_A.start(); + delay(50); + const bool task_B_rt = task_B.start(); + if (tasK_A_rt != true || task_B_rt != true) + { + led.setStatus(RGBled::LedStatus::ERROR); + LOG_ERROR("Unable to start realtime tasks"); + } else LOG_DEBUG("Real Time Tasks A & B initialized"); led.setStatus(RGBled::LedStatus::OK); - LITTLEFSGuard fsGuard; WebPage webPage(80, LittleFS); // Initialize webserver and Websocket + task_A.onMessage([&webPage](ignitionBoxStatusFiltered sts){ + ArduinoJson::JsonDocument doc; + doc["box_a"] = sts.toJson(); + doc["box_b"] = ArduinoJson::JsonDocument(); + webPage.sendWsData(doc.as()); + }); + + task_B.onMessage([&webPage](ignitionBoxStatusFiltered sts){ + ArduinoJson::JsonDocument doc; + doc["box_a"] = ArduinoJson::JsonDocument(); + doc["box_b"] = sts.toJson(); + webPage.sendWsData(doc.as()); + }); + + task_A.enableSave(true, "ignitionA_test.csv"); + task_B.enableSave(true, "ignitionB_test.csv"); + uint32_t last_loop = millis(); //////////////// INNER LOOP ///////////////////// while (running) { - led.setStatus(RGBled::LedStatus::IDLE); - delay(100); - - if ((millis() - last_loop) > 1000) + if ((millis() - last_loop) > 2000) { clearScreen(); - Serial.println(); printRunningTasksMod(Serial); last_loop = millis(); } diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 647b66b..bcc7859 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -296,20 +296,22 @@ rtIgnitionTask::rtIgnitionTask(const rtTaskParams params, const uint32_t history m_params.rt_queue = m_queue; // create PSram history vectors - m_history_0.resize(history_size); - m_history_1.resize(history_size); + m_history_0 = PSHistory(history_size); + m_history_1 = PSHistory(history_size); // assing active and writable history m_active_history = std::unique_ptr(&m_history_0); m_save_history = std::unique_ptr(&m_history_1); LOG_WARN("Starting Manager for [", m_params.name.c_str(), "]"); - auto task_success = xTaskCreate( + // auto task_success = pdPASS; + auto task_success = xTaskCreatePinnedToCore( rtIgnitionTask_manager, (std::string("man_") + m_params.name).c_str(), - m_params.rt_stack_size, + 8192, (void *)this, - 1, - &m_manager_handle); + m_params.rt_priority >> 2, + &m_manager_handle, + m_core); if (task_success != pdPASS) { @@ -341,10 +343,12 @@ void rtIgnitionTask::run() if (new_data == pdPASS) { + m_last_data = millis(); m_manager_status = rtTaskStatus::RUNNING; // if history buffer is full swap buffers and if enabled save history buffer if (m_counter_status >= m_active_history->size()) { + LOG_DEBUG("Save for Buffer Full: ", m_counter_status); m_counter_status = 0; m_partial_save = false; // reset partial save flag on new data cycle std::swap(m_active_history, m_save_history); @@ -356,13 +360,21 @@ void rtIgnitionTask::run() m_info_filtered.update(m_last_status); (*m_active_history)[m_counter_status] = m_last_status; + if (m_on_message_cb && m_counter_status % 10) + { + m_on_message_cb(m_info_filtered); + } + // update data counter m_counter_status++; } else { - if (millis() - m_last_data > c_idle_time){ - if (m_counter_status > 0 && !m_partial_save){ + if (millis() - m_last_data > c_idle_time) + { + if (m_counter_status > 0 && !m_partial_save) + { + LOG_DEBUG("Save Partial: ", m_counter_status); m_active_history->resize(m_counter_status); saveHistory(*m_active_history, m_history_path); m_active_history->resize(m_max_history); @@ -434,13 +446,18 @@ void rtIgnitionTask::enableSave(const bool enable, const std::filesystem::path f } } +void rtIgnitionTask::onMessage(std::function callaback) +{ + m_on_message_cb = callaback; +} + void rtIgnitionTask::saveHistory(const rtIgnitionTask::PSHistory &history, const std::filesystem::path &file_name) { // Lock filesystem mutex to avoid concurrent access std::lock_guard fs_lock(m_fs_mutex); // Check for free space - if (LittleFS.totalBytes() - LittleFS.usedBytes() < history.size() * sizeof(ignitionBoxStatus) * 200) // check if at least 1MB is free for saving history + if (LittleFS.totalBytes() - LittleFS.usedBytes() < history.size() * sizeof(ignitionBoxStatus)) // check if at least 1MB is free for saving history { LOG_ERROR("Not enough space in SPIFFS to save history"); return; @@ -454,9 +471,8 @@ void rtIgnitionTask::saveHistory(const rtIgnitionTask::PSHistory &history, const // if firt save remove old file and create new auto save_flags = std::ios::out; - if (m_first_save && m_filesystem.exists(file_path.c_str())) + if (m_first_save) { - m_first_save = false; save_flags |= std::ios::trunc; // overwrite existing file m_filesystem.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS LOG_INFO("Saving history to Flash, new file:", file_path.c_str()); @@ -477,12 +493,12 @@ void rtIgnitionTask::saveHistory(const rtIgnitionTask::PSHistory &history, const // write csv header if (m_first_save) { - ofs << "TS,\ - EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ - EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ - ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" + ofs << "TS,EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12," + << "EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34," + << "ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" << std::endl; ofs.flush(); + m_first_save = false; } for (const auto &entry : history) diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index a37cd9d..bfe9958 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -14,6 +14,7 @@ #include #include #include +#include // ISR #include "isr.h" @@ -111,6 +112,8 @@ public: void enableSave(const bool enable, const std::filesystem::path filename); + void onMessage(std::function callaback); + private: void saveHistory(const rtIgnitionTask::PSHistory &history, const std::filesystem::path &file_name); @@ -147,7 +150,9 @@ private: ignitionBoxStatus m_last_status; ignitionBoxStatusFiltered m_info_filtered; - static const uint32_t c_idle_time = 2000; // in mS + std::function m_on_message_cb = nullptr; + + static const uint32_t c_idle_time = 10000; // in mS static const uint32_t c_spark_timeout_max = 500; // uS static const uint8_t c_adc_time = 4; // in mS static const uint8_t c_io_time = 2; // in mS diff --git a/RotaxMonitor/src/utils.cpp b/RotaxMonitor/src/utils.cpp index a1fad94..1e59492 100644 --- a/RotaxMonitor/src/utils.cpp +++ b/RotaxMonitor/src/utils.cpp @@ -5,25 +5,69 @@ #include "freertos/FreeRTOS.h" #include "freertos/portable.h" +#include "esp_heap_caps.h" +#include "esp_system.h" +#include "esp_spi_flash.h" +#include "esp_partition.h" +#include "LittleFS.h" + #include #include #include #define FREERTOS_TASK_NUMBER_MAX_NUM 256 // RunTime stats for how many Tasks to be stored -std::string printBits(uint32_t value) { +std::string printBits(uint32_t value) +{ std::string result; - for (int i = 31; i >= 0; i--) { + for (int i = 31; i >= 0; i--) + { // ottieni il singolo bit result += ((value >> i) & 1) ? '1' : '0'; // aggiungi uno spazio ogni 8 bit, tranne dopo l'ultimo - if (i % 8 == 0 && i != 0) { + if (i % 8 == 0 && i != 0) + { result += ' '; } } return result; } +// ANSI colors +#define BAR_WIDTH 30 +#define COLOR_RESET "\033[0m" +#define COLOR_RED "\033[31m" +#define COLOR_GREEN "\033[32m" +#define COLOR_BLUE "\033[34m" +#define COLOR_MAGENTA "\033[35m" +#define COLOR_CYAN "\033[36m" +#define COLOR_YELLOW "\033[33m" +#define COLOR_WHITE "\033[37m" +#define COLOR_LBLUE "\033[94m" + +void printBar(Print &printer, const char *label, size_t used, size_t total, const char *color) +{ + float perc = total > 0 ? ((float)used / total) : 0; + int filled = perc * BAR_WIDTH; + + printer.printf("%s%-12s [" COLOR_RESET, color, label); + + for (int i = 0; i < BAR_WIDTH; i++) + { + if (i < filled) + printer.printf("%s#%s", color, COLOR_RESET); + else + printer.printf("-"); + } + + printer.printf("] %s%6.2f%%%s (%5.3f/%5.3f)MB\n", + color, + perc * 100.0, + COLOR_RESET, + (used / 1024.0f / 1024.0f), + (total / 1024.0f / 1024.0f)); +} + void printRunningTasksMod(Print &printer, std::function orderBy) { static const char *taskStates[] = {"Running", "Ready", "Blocked", "Suspended", "Deleted", "Invalid"}; @@ -53,6 +97,68 @@ void printRunningTasksMod(Print &printer, std::function 0) + { + size_t freePsram = heap_caps_get_free_size(MALLOC_CAP_SPIRAM); + printBar(printer, "PSRAM", totalPsram - freePsram, totalPsram, COLOR_MAGENTA); + } + + printer.printf("\n"); + + // ===== FLASH APP (approssimato) ===== + const esp_partition_t *app_partition = + esp_partition_find_first(ESP_PARTITION_TYPE_APP, + ESP_PARTITION_SUBTYPE_APP_FACTORY, + NULL); + + if (app_partition) + { + size_t totalAPP = app_partition->size; // dimensione reale partizione + size_t sketchSize = ESP.getSketchSize(); + printBar(printer, "FLASH APP", sketchSize, totalAPP, COLOR_CYAN); + } + else + { + printer.printf(COLOR_YELLOW "%-12s [NOT FOUND]\n" COLOR_RESET, "FLASH APP"); + } + + // ===== LITTLEFS (corretto con partition table) ===== + const esp_partition_t *fs_partition = + esp_partition_find_first(ESP_PARTITION_TYPE_DATA, + ESP_PARTITION_SUBTYPE_DATA_LITTLEFS, + "littlefs"); + + if (fs_partition) + { + size_t totalFS = fs_partition->size; // dimensione reale partizione + size_t usedFS = LittleFS.usedBytes(); // spazio usato reale + printBar(printer, "LITTLEFS", usedFS, totalFS, COLOR_YELLOW); + } + else + { + printer.printf(COLOR_YELLOW "%-12s [NOT FOUND]\n" COLOR_RESET, "LITTLEFS"); + } + + // ===== MIN HEAP ===== + size_t minHeap = esp_get_minimum_free_heap_size(); + printer.printf("%s\nMin Heap Ever:%s %u KB\n\n", COLOR_RED, COLOR_RESET, minHeap / 1024); + // Print Runtime Information printer.printf("Tasks: %u, Runtime: %lus, Period: %luus\r\n", uxArraySize, ulTotalRunTime / 1000000, ulCurrentRunTime); @@ -79,4 +185,3 @@ void printRunningTasksMod(Print &printer, std::function Date: Sun, 12 Apr 2026 02:38:27 +0200 Subject: [PATCH 27/38] webpage chats --- RotaxMonitor/data/chart.js | 16 ++ RotaxMonitor/data/index.html | 330 ++++++++++++++++++----------------- RotaxMonitor/data/script.js | 86 +++++++++ RotaxMonitor/data/style.css | 29 +++ 4 files changed, 305 insertions(+), 156 deletions(-) create mode 100644 RotaxMonitor/data/chart.js diff --git a/RotaxMonitor/data/chart.js b/RotaxMonitor/data/chart.js new file mode 100644 index 0000000..0384d3a --- /dev/null +++ b/RotaxMonitor/data/chart.js @@ -0,0 +1,16 @@ +/*! + * Chart.js v4.5.1 + * https://www.chartjs.org + * (c) 2025 Chart.js Contributors + * Released under the MIT License + */ +!function (t, e) { "object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).Chart = e() }(this, (function () { + "use strict"; var t = Object.freeze({ __proto__: null, get Colors() { return Jo }, get Decimation() { return ta }, get Filler() { return ba }, get Legend() { return Ma }, get SubTitle() { return Pa }, get Title() { return ka }, get Tooltip() { return Na } }); function e() { } const i = (() => { let t = 0; return () => t++ })(); function s(t) { return null == t } function n(t) { if (Array.isArray && Array.isArray(t)) return !0; const e = Object.prototype.toString.call(t); return "[object" === e.slice(0, 7) && "Array]" === e.slice(-6) } function o(t) { return null !== t && "[object Object]" === Object.prototype.toString.call(t) } function a(t) { return ("number" == typeof t || t instanceof Number) && isFinite(+t) } function r(t, e) { return a(t) ? t : e } function l(t, e) { return void 0 === t ? e : t } const h = (t, e) => "string" == typeof t && t.endsWith("%") ? parseFloat(t) / 100 : +t / e, c = (t, e) => "string" == typeof t && t.endsWith("%") ? parseFloat(t) / 100 * e : +t; function d(t, e, i) { if (t && "function" == typeof t.call) return t.apply(i, e) } function u(t, e, i, s) { let a, r, l; if (n(t)) if (r = t.length, s) for (a = r - 1; a >= 0; a--)e.call(i, t[a], a); else for (a = 0; a < r; a++)e.call(i, t[a], a); else if (o(t)) for (l = Object.keys(t), r = l.length, a = 0; a < r; a++)e.call(i, t[l[a]], l[a]) } function f(t, e) { let i, s, n, o; if (!t || !e || t.length !== e.length) return !1; for (i = 0, s = t.length; i < s; ++i)if (n = t[i], o = e[i], n.datasetIndex !== o.datasetIndex || n.index !== o.index) return !1; return !0 } function g(t) { if (n(t)) return t.map(g); if (o(t)) { const e = Object.create(null), i = Object.keys(t), s = i.length; let n = 0; for (; n < s; ++n)e[i[n]] = g(t[i[n]]); return e } return t } function p(t) { return -1 === ["__proto__", "prototype", "constructor"].indexOf(t) } function m(t, e, i, s) { if (!p(t)) return; const n = e[t], a = i[t]; o(n) && o(a) ? x(n, a, s) : e[t] = g(a) } function x(t, e, i) { const s = n(e) ? e : [e], a = s.length; if (!o(t)) return t; const r = (i = i || {}).merger || m; let l; for (let e = 0; e < a; ++e) { if (l = s[e], !o(l)) continue; const n = Object.keys(l); for (let e = 0, s = n.length; e < s; ++e)r(n[e], t, l, i) } return t } function b(t, e) { return x(t, e, { merger: _ }) } function _(t, e, i) { if (!p(t)) return; const s = e[t], n = i[t]; o(s) && o(n) ? b(s, n) : Object.prototype.hasOwnProperty.call(e, t) || (e[t] = g(n)) } const y = { "": t => t, x: t => t.x, y: t => t.y }; function v(t) { const e = t.split("."), i = []; let s = ""; for (const t of e) s += t, s.endsWith("\\") ? s = s.slice(0, -1) + "." : (i.push(s), s = ""); return i } function M(t, e) { const i = y[e] || (y[e] = function (t) { const e = v(t); return t => { for (const i of e) { if ("" === i) break; t = t && t[i] } return t } }(e)); return i(t) } function w(t) { return t.charAt(0).toUpperCase() + t.slice(1) } const k = t => void 0 !== t, S = t => "function" == typeof t, P = (t, e) => { if (t.size !== e.size) return !1; for (const i of t) if (!e.has(i)) return !1; return !0 }; function D(t) { return "mouseup" === t.type || "click" === t.type || "contextmenu" === t.type } const C = Math.PI, O = 2 * C, A = O + C, T = Number.POSITIVE_INFINITY, L = C / 180, E = C / 2, R = C / 4, I = 2 * C / 3, z = Math.log10, F = Math.sign; function V(t, e, i) { return Math.abs(t - e) < i } function B(t) { const e = Math.round(t); t = V(t, e, t / 1e3) ? e : t; const i = Math.pow(10, Math.floor(z(t))), s = t / i; return (s <= 1 ? 1 : s <= 2 ? 2 : s <= 5 ? 5 : 10) * i } function W(t) { const e = [], i = Math.sqrt(t); let s; for (s = 1; s < i; s++)t % s == 0 && (e.push(s), e.push(t / s)); return i === (0 | i) && e.push(i), e.sort(((t, e) => t - e)).pop(), e } function N(t) { return !function (t) { return "symbol" == typeof t || "object" == typeof t && null !== t && !(Symbol.toPrimitive in t || "toString" in t || "valueOf" in t) }(t) && !isNaN(parseFloat(t)) && isFinite(t) } function H(t, e) { const i = Math.round(t); return i - e <= t && i + e >= t } function j(t, e, i) { let s, n, o; for (s = 0, n = t.length; s < n; s++)o = t[s][i], isNaN(o) || (e.min = Math.min(e.min, o), e.max = Math.max(e.max, o)) } function $(t) { return t * (C / 180) } function Y(t) { return t * (180 / C) } function U(t) { if (!a(t)) return; let e = 1, i = 0; for (; Math.round(t * e) / e !== t;)e *= 10, i++; return i } function X(t, e) { const i = e.x - t.x, s = e.y - t.y, n = Math.sqrt(i * i + s * s); let o = Math.atan2(s, i); return o < -.5 * C && (o += O), { angle: o, distance: n } } function q(t, e) { return Math.sqrt(Math.pow(e.x - t.x, 2) + Math.pow(e.y - t.y, 2)) } function K(t, e) { return (t - e + A) % O - C } function G(t) { return (t % O + O) % O } function J(t, e, i, s) { const n = G(t), o = G(e), a = G(i), r = G(o - n), l = G(a - n), h = G(n - o), c = G(n - a); return n === o || n === a || s && o === a || r > l && h < c } function Z(t, e, i) { return Math.max(e, Math.min(i, t)) } function Q(t) { return Z(t, -32768, 32767) } function tt(t, e, i, s = 1e-6) { return t >= Math.min(e, i) - s && t <= Math.max(e, i) + s } function et(t, e, i) { i = i || (i => t[i] < e); let s, n = t.length - 1, o = 0; for (; n - o > 1;)s = o + n >> 1, i(s) ? o = s : n = s; return { lo: o, hi: n } } const it = (t, e, i, s) => et(t, i, s ? s => { const n = t[s][e]; return n < i || n === i && t[s + 1][e] === i } : s => t[s][e] < i), st = (t, e, i) => et(t, i, (s => t[s][e] >= i)); function nt(t, e, i) { let s = 0, n = t.length; for (; s < n && t[s] < e;)s++; for (; n > s && t[n - 1] > i;)n--; return s > 0 || n < t.length ? t.slice(s, n) : t } const ot = ["push", "pop", "shift", "splice", "unshift"]; function at(t, e) { t._chartjs ? t._chartjs.listeners.push(e) : (Object.defineProperty(t, "_chartjs", { configurable: !0, enumerable: !1, value: { listeners: [e] } }), ot.forEach((e => { const i = "_onData" + w(e), s = t[e]; Object.defineProperty(t, e, { configurable: !0, enumerable: !1, value(...e) { const n = s.apply(this, e); return t._chartjs.listeners.forEach((t => { "function" == typeof t[i] && t[i](...e) })), n } }) }))) } function rt(t, e) { const i = t._chartjs; if (!i) return; const s = i.listeners, n = s.indexOf(e); -1 !== n && s.splice(n, 1), s.length > 0 || (ot.forEach((e => { delete t[e] })), delete t._chartjs) } function lt(t) { const e = new Set(t); return e.size === t.length ? t : Array.from(e) } const ht = "undefined" == typeof window ? function (t) { return t() } : window.requestAnimationFrame; function ct(t, e) { let i = [], s = !1; return function (...n) { i = n, s || (s = !0, ht.call(window, (() => { s = !1, t.apply(e, i) }))) } } function dt(t, e) { let i; return function (...s) { return e ? (clearTimeout(i), i = setTimeout(t, e, s)) : t.apply(this, s), e } } const ut = t => "start" === t ? "left" : "end" === t ? "right" : "center", ft = (t, e, i) => "start" === t ? e : "end" === t ? i : (e + i) / 2, gt = (t, e, i, s) => t === (s ? "left" : "right") ? i : "center" === t ? (e + i) / 2 : e; function pt(t, e, i) { const n = e.length; let o = 0, a = n; if (t._sorted) { const { iScale: r, vScale: l, _parsed: h } = t, c = t.dataset && t.dataset.options ? t.dataset.options.spanGaps : null, d = r.axis, { min: u, max: f, minDefined: g, maxDefined: p } = r.getUserBounds(); if (g) { if (o = Math.min(it(h, d, u).lo, i ? n : it(e, d, r.getPixelForValue(u)).lo), c) { const t = h.slice(0, o + 1).reverse().findIndex((t => !s(t[l.axis]))); o -= Math.max(0, t) } o = Z(o, 0, n - 1) } if (p) { let t = Math.max(it(h, r.axis, f, !0).hi + 1, i ? 0 : it(e, d, r.getPixelForValue(f), !0).hi + 1); if (c) { const e = h.slice(t - 1).findIndex((t => !s(t[l.axis]))); t += Math.max(0, e) } a = Z(t, o, n) - o } else a = n - o } return { start: o, count: a } } function mt(t) { const { xScale: e, yScale: i, _scaleRanges: s } = t, n = { xmin: e.min, xmax: e.max, ymin: i.min, ymax: i.max }; if (!s) return t._scaleRanges = n, !0; const o = s.xmin !== e.min || s.xmax !== e.max || s.ymin !== i.min || s.ymax !== i.max; return Object.assign(s, n), o } class xt { constructor() { this._request = null, this._charts = new Map, this._running = !1, this._lastDate = void 0 } _notify(t, e, i, s) { const n = e.listeners[s], o = e.duration; n.forEach((s => s({ chart: t, initial: e.initial, numSteps: o, currentStep: Math.min(i - e.start, o) }))) } _refresh() { this._request || (this._running = !0, this._request = ht.call(window, (() => { this._update(), this._request = null, this._running && this._refresh() }))) } _update(t = Date.now()) { let e = 0; this._charts.forEach(((i, s) => { if (!i.running || !i.items.length) return; const n = i.items; let o, a = n.length - 1, r = !1; for (; a >= 0; --a)o = n[a], o._active ? (o._total > i.duration && (i.duration = o._total), o.tick(t), r = !0) : (n[a] = n[n.length - 1], n.pop()); r && (s.draw(), this._notify(s, i, t, "progress")), n.length || (i.running = !1, this._notify(s, i, t, "complete"), i.initial = !1), e += n.length })), this._lastDate = t, 0 === e && (this._running = !1) } _getAnims(t) { const e = this._charts; let i = e.get(t); return i || (i = { running: !1, initial: !0, items: [], listeners: { complete: [], progress: [] } }, e.set(t, i)), i } listen(t, e, i) { this._getAnims(t).listeners[e].push(i) } add(t, e) { e && e.length && this._getAnims(t).items.push(...e) } has(t) { return this._getAnims(t).items.length > 0 } start(t) { const e = this._charts.get(t); e && (e.running = !0, e.start = Date.now(), e.duration = e.items.reduce(((t, e) => Math.max(t, e._duration)), 0), this._refresh()) } running(t) { if (!this._running) return !1; const e = this._charts.get(t); return !!(e && e.running && e.items.length) } stop(t) { const e = this._charts.get(t); if (!e || !e.items.length) return; const i = e.items; let s = i.length - 1; for (; s >= 0; --s)i[s].cancel(); e.items = [], this._notify(t, e, Date.now(), "complete") } remove(t) { return this._charts.delete(t) } } var bt = new xt; +/*! + * @kurkle/color v0.3.2 + * https://github.com/kurkle/color#readme + * (c) 2023 Jukka Kurkela + * Released under the MIT License + */function _t(t) { return t + .5 | 0 } const yt = (t, e, i) => Math.max(Math.min(t, i), e); function vt(t) { return yt(_t(2.55 * t), 0, 255) } function Mt(t) { return yt(_t(255 * t), 0, 255) } function wt(t) { return yt(_t(t / 2.55) / 100, 0, 1) } function kt(t) { return yt(_t(100 * t), 0, 100) } const St = { 0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, A: 10, B: 11, C: 12, D: 13, E: 14, F: 15, a: 10, b: 11, c: 12, d: 13, e: 14, f: 15 }, Pt = [..."0123456789ABCDEF"], Dt = t => Pt[15 & t], Ct = t => Pt[(240 & t) >> 4] + Pt[15 & t], Ot = t => (240 & t) >> 4 == (15 & t); function At(t) { var e = (t => Ot(t.r) && Ot(t.g) && Ot(t.b) && Ot(t.a))(t) ? Dt : Ct; return t ? "#" + e(t.r) + e(t.g) + e(t.b) + ((t, e) => t < 255 ? e(t) : "")(t.a, e) : void 0 } const Tt = /^(hsla?|hwb|hsv)\(\s*([-+.e\d]+)(?:deg)?[\s,]+([-+.e\d]+)%[\s,]+([-+.e\d]+)%(?:[\s,]+([-+.e\d]+)(%)?)?\s*\)$/; function Lt(t, e, i) { const s = e * Math.min(i, 1 - i), n = (e, n = (e + t / 30) % 12) => i - s * Math.max(Math.min(n - 3, 9 - n, 1), -1); return [n(0), n(8), n(4)] } function Et(t, e, i) { const s = (s, n = (s + t / 60) % 6) => i - i * e * Math.max(Math.min(n, 4 - n, 1), 0); return [s(5), s(3), s(1)] } function Rt(t, e, i) { const s = Lt(t, 1, .5); let n; for (e + i > 1 && (n = 1 / (e + i), e *= n, i *= n), n = 0; n < 3; n++)s[n] *= 1 - e - i, s[n] += e; return s } function It(t) { const e = t.r / 255, i = t.g / 255, s = t.b / 255, n = Math.max(e, i, s), o = Math.min(e, i, s), a = (n + o) / 2; let r, l, h; return n !== o && (h = n - o, l = a > .5 ? h / (2 - n - o) : h / (n + o), r = function (t, e, i, s, n) { return t === n ? (e - i) / s + (e < i ? 6 : 0) : e === n ? (i - t) / s + 2 : (t - e) / s + 4 }(e, i, s, h, n), r = 60 * r + .5), [0 | r, l || 0, a] } function zt(t, e, i, s) { return (Array.isArray(e) ? t(e[0], e[1], e[2]) : t(e, i, s)).map(Mt) } function Ft(t, e, i) { return zt(Lt, t, e, i) } function Vt(t) { return (t % 360 + 360) % 360 } function Bt(t) { const e = Tt.exec(t); let i, s = 255; if (!e) return; e[5] !== i && (s = e[6] ? vt(+e[5]) : Mt(+e[5])); const n = Vt(+e[2]), o = +e[3] / 100, a = +e[4] / 100; return i = "hwb" === e[1] ? function (t, e, i) { return zt(Rt, t, e, i) }(n, o, a) : "hsv" === e[1] ? function (t, e, i) { return zt(Et, t, e, i) }(n, o, a) : Ft(n, o, a), { r: i[0], g: i[1], b: i[2], a: s } } const Wt = { x: "dark", Z: "light", Y: "re", X: "blu", W: "gr", V: "medium", U: "slate", A: "ee", T: "ol", S: "or", B: "ra", C: "lateg", D: "ights", R: "in", Q: "turquois", E: "hi", P: "ro", O: "al", N: "le", M: "de", L: "yello", F: "en", K: "ch", G: "arks", H: "ea", I: "ightg", J: "wh" }, Nt = { OiceXe: "f0f8ff", antiquewEte: "faebd7", aqua: "ffff", aquamarRe: "7fffd4", azuY: "f0ffff", beige: "f5f5dc", bisque: "ffe4c4", black: "0", blanKedOmond: "ffebcd", Xe: "ff", XeviTet: "8a2be2", bPwn: "a52a2a", burlywood: "deb887", caMtXe: "5f9ea0", KartYuse: "7fff00", KocTate: "d2691e", cSO: "ff7f50", cSnflowerXe: "6495ed", cSnsilk: "fff8dc", crimson: "dc143c", cyan: "ffff", xXe: "8b", xcyan: "8b8b", xgTMnPd: "b8860b", xWay: "a9a9a9", xgYF: "6400", xgYy: "a9a9a9", xkhaki: "bdb76b", xmagFta: "8b008b", xTivegYF: "556b2f", xSange: "ff8c00", xScEd: "9932cc", xYd: "8b0000", xsOmon: "e9967a", xsHgYF: "8fbc8f", xUXe: "483d8b", xUWay: "2f4f4f", xUgYy: "2f4f4f", xQe: "ced1", xviTet: "9400d3", dAppRk: "ff1493", dApskyXe: "bfff", dimWay: "696969", dimgYy: "696969", dodgerXe: "1e90ff", fiYbrick: "b22222", flSOwEte: "fffaf0", foYstWAn: "228b22", fuKsia: "ff00ff", gaRsbSo: "dcdcdc", ghostwEte: "f8f8ff", gTd: "ffd700", gTMnPd: "daa520", Way: "808080", gYF: "8000", gYFLw: "adff2f", gYy: "808080", honeyMw: "f0fff0", hotpRk: "ff69b4", RdianYd: "cd5c5c", Rdigo: "4b0082", ivSy: "fffff0", khaki: "f0e68c", lavFMr: "e6e6fa", lavFMrXsh: "fff0f5", lawngYF: "7cfc00", NmoncEffon: "fffacd", ZXe: "add8e6", ZcSO: "f08080", Zcyan: "e0ffff", ZgTMnPdLw: "fafad2", ZWay: "d3d3d3", ZgYF: "90ee90", ZgYy: "d3d3d3", ZpRk: "ffb6c1", ZsOmon: "ffa07a", ZsHgYF: "20b2aa", ZskyXe: "87cefa", ZUWay: "778899", ZUgYy: "778899", ZstAlXe: "b0c4de", ZLw: "ffffe0", lime: "ff00", limegYF: "32cd32", lRF: "faf0e6", magFta: "ff00ff", maPon: "800000", VaquamarRe: "66cdaa", VXe: "cd", VScEd: "ba55d3", VpurpN: "9370db", VsHgYF: "3cb371", VUXe: "7b68ee", VsprRggYF: "fa9a", VQe: "48d1cc", VviTetYd: "c71585", midnightXe: "191970", mRtcYam: "f5fffa", mistyPse: "ffe4e1", moccasR: "ffe4b5", navajowEte: "ffdead", navy: "80", Tdlace: "fdf5e6", Tive: "808000", TivedBb: "6b8e23", Sange: "ffa500", SangeYd: "ff4500", ScEd: "da70d6", pOegTMnPd: "eee8aa", pOegYF: "98fb98", pOeQe: "afeeee", pOeviTetYd: "db7093", papayawEp: "ffefd5", pHKpuff: "ffdab9", peru: "cd853f", pRk: "ffc0cb", plum: "dda0dd", powMrXe: "b0e0e6", purpN: "800080", YbeccapurpN: "663399", Yd: "ff0000", Psybrown: "bc8f8f", PyOXe: "4169e1", saddNbPwn: "8b4513", sOmon: "fa8072", sandybPwn: "f4a460", sHgYF: "2e8b57", sHshell: "fff5ee", siFna: "a0522d", silver: "c0c0c0", skyXe: "87ceeb", UXe: "6a5acd", UWay: "708090", UgYy: "708090", snow: "fffafa", sprRggYF: "ff7f", stAlXe: "4682b4", tan: "d2b48c", teO: "8080", tEstN: "d8bfd8", tomato: "ff6347", Qe: "40e0d0", viTet: "ee82ee", JHt: "f5deb3", wEte: "ffffff", wEtesmoke: "f5f5f5", Lw: "ffff00", LwgYF: "9acd32" }; let Ht; function jt(t) { Ht || (Ht = function () { const t = {}, e = Object.keys(Nt), i = Object.keys(Wt); let s, n, o, a, r; for (s = 0; s < e.length; s++) { for (a = r = e[s], n = 0; n < i.length; n++)o = i[n], r = r.replace(o, Wt[o]); o = parseInt(Nt[a], 16), t[r] = [o >> 16 & 255, o >> 8 & 255, 255 & o] } return t }(), Ht.transparent = [0, 0, 0, 0]); const e = Ht[t.toLowerCase()]; return e && { r: e[0], g: e[1], b: e[2], a: 4 === e.length ? e[3] : 255 } } const $t = /^rgba?\(\s*([-+.\d]+)(%)?[\s,]+([-+.e\d]+)(%)?[\s,]+([-+.e\d]+)(%)?(?:[\s,/]+([-+.e\d]+)(%)?)?\s*\)$/; const Yt = t => t <= .0031308 ? 12.92 * t : 1.055 * Math.pow(t, 1 / 2.4) - .055, Ut = t => t <= .04045 ? t / 12.92 : Math.pow((t + .055) / 1.055, 2.4); function Xt(t, e, i) { if (t) { let s = It(t); s[e] = Math.max(0, Math.min(s[e] + s[e] * i, 0 === e ? 360 : 1)), s = Ft(s), t.r = s[0], t.g = s[1], t.b = s[2] } } function qt(t, e) { return t ? Object.assign(e || {}, t) : t } function Kt(t) { var e = { r: 0, g: 0, b: 0, a: 255 }; return Array.isArray(t) ? t.length >= 3 && (e = { r: t[0], g: t[1], b: t[2], a: 255 }, t.length > 3 && (e.a = Mt(t[3]))) : (e = qt(t, { r: 0, g: 0, b: 0, a: 1 })).a = Mt(e.a), e } function Gt(t) { return "r" === t.charAt(0) ? function (t) { const e = $t.exec(t); let i, s, n, o = 255; if (e) { if (e[7] !== i) { const t = +e[7]; o = e[8] ? vt(t) : yt(255 * t, 0, 255) } return i = +e[1], s = +e[3], n = +e[5], i = 255 & (e[2] ? vt(i) : yt(i, 0, 255)), s = 255 & (e[4] ? vt(s) : yt(s, 0, 255)), n = 255 & (e[6] ? vt(n) : yt(n, 0, 255)), { r: i, g: s, b: n, a: o } } }(t) : Bt(t) } class Jt { constructor(t) { if (t instanceof Jt) return t; const e = typeof t; let i; var s, n, o; "object" === e ? i = Kt(t) : "string" === e && (o = (s = t).length, "#" === s[0] && (4 === o || 5 === o ? n = { r: 255 & 17 * St[s[1]], g: 255 & 17 * St[s[2]], b: 255 & 17 * St[s[3]], a: 5 === o ? 17 * St[s[4]] : 255 } : 7 !== o && 9 !== o || (n = { r: St[s[1]] << 4 | St[s[2]], g: St[s[3]] << 4 | St[s[4]], b: St[s[5]] << 4 | St[s[6]], a: 9 === o ? St[s[7]] << 4 | St[s[8]] : 255 })), i = n || jt(t) || Gt(t)), this._rgb = i, this._valid = !!i } get valid() { return this._valid } get rgb() { var t = qt(this._rgb); return t && (t.a = wt(t.a)), t } set rgb(t) { this._rgb = Kt(t) } rgbString() { return this._valid ? (t = this._rgb) && (t.a < 255 ? `rgba(${t.r}, ${t.g}, ${t.b}, ${wt(t.a)})` : `rgb(${t.r}, ${t.g}, ${t.b})`) : void 0; var t } hexString() { return this._valid ? At(this._rgb) : void 0 } hslString() { return this._valid ? function (t) { if (!t) return; const e = It(t), i = e[0], s = kt(e[1]), n = kt(e[2]); return t.a < 255 ? `hsla(${i}, ${s}%, ${n}%, ${wt(t.a)})` : `hsl(${i}, ${s}%, ${n}%)` }(this._rgb) : void 0 } mix(t, e) { if (t) { const i = this.rgb, s = t.rgb; let n; const o = e === n ? .5 : e, a = 2 * o - 1, r = i.a - s.a, l = ((a * r == -1 ? a : (a + r) / (1 + a * r)) + 1) / 2; n = 1 - l, i.r = 255 & l * i.r + n * s.r + .5, i.g = 255 & l * i.g + n * s.g + .5, i.b = 255 & l * i.b + n * s.b + .5, i.a = o * i.a + (1 - o) * s.a, this.rgb = i } return this } interpolate(t, e) { return t && (this._rgb = function (t, e, i) { const s = Ut(wt(t.r)), n = Ut(wt(t.g)), o = Ut(wt(t.b)); return { r: Mt(Yt(s + i * (Ut(wt(e.r)) - s))), g: Mt(Yt(n + i * (Ut(wt(e.g)) - n))), b: Mt(Yt(o + i * (Ut(wt(e.b)) - o))), a: t.a + i * (e.a - t.a) } }(this._rgb, t._rgb, e)), this } clone() { return new Jt(this.rgb) } alpha(t) { return this._rgb.a = Mt(t), this } clearer(t) { return this._rgb.a *= 1 - t, this } greyscale() { const t = this._rgb, e = _t(.3 * t.r + .59 * t.g + .11 * t.b); return t.r = t.g = t.b = e, this } opaquer(t) { return this._rgb.a *= 1 + t, this } negate() { const t = this._rgb; return t.r = 255 - t.r, t.g = 255 - t.g, t.b = 255 - t.b, this } lighten(t) { return Xt(this._rgb, 2, t), this } darken(t) { return Xt(this._rgb, 2, -t), this } saturate(t) { return Xt(this._rgb, 1, t), this } desaturate(t) { return Xt(this._rgb, 1, -t), this } rotate(t) { return function (t, e) { var i = It(t); i[0] = Vt(i[0] + e), i = Ft(i), t.r = i[0], t.g = i[1], t.b = i[2] }(this._rgb, t), this } } function Zt(t) { if (t && "object" == typeof t) { const e = t.toString(); return "[object CanvasPattern]" === e || "[object CanvasGradient]" === e } return !1 } function Qt(t) { return Zt(t) ? t : new Jt(t) } function te(t) { return Zt(t) ? t : new Jt(t).saturate(.5).darken(.1).hexString() } const ee = ["x", "y", "borderWidth", "radius", "tension"], ie = ["color", "borderColor", "backgroundColor"]; const se = new Map; function ne(t, e, i) { return function (t, e) { e = e || {}; const i = t + JSON.stringify(e); let s = se.get(i); return s || (s = new Intl.NumberFormat(t, e), se.set(i, s)), s }(e, i).format(t) } const oe = { values: t => n(t) ? t : "" + t, numeric(t, e, i) { if (0 === t) return "0"; const s = this.chart.options.locale; let n, o = t; if (i.length > 1) { const e = Math.max(Math.abs(i[0].value), Math.abs(i[i.length - 1].value)); (e < 1e-4 || e > 1e15) && (n = "scientific"), o = function (t, e) { let i = e.length > 3 ? e[2].value - e[1].value : e[1].value - e[0].value; Math.abs(i) >= 1 && t !== Math.floor(t) && (i = t - Math.floor(t)); return i }(t, i) } const a = z(Math.abs(o)), r = isNaN(a) ? 1 : Math.max(Math.min(-1 * Math.floor(a), 20), 0), l = { notation: n, minimumFractionDigits: r, maximumFractionDigits: r }; return Object.assign(l, this.options.ticks.format), ne(t, s, l) }, logarithmic(t, e, i) { if (0 === t) return "0"; const s = i[e].significand || t / Math.pow(10, Math.floor(z(t))); return [1, 2, 3, 5, 10, 15].includes(s) || e > .8 * i.length ? oe.numeric.call(this, t, e, i) : "" } }; var ae = { formatters: oe }; const re = Object.create(null), le = Object.create(null); function he(t, e) { if (!e) return t; const i = e.split("."); for (let e = 0, s = i.length; e < s; ++e) { const s = i[e]; t = t[s] || (t[s] = Object.create(null)) } return t } function ce(t, e, i) { return "string" == typeof e ? x(he(t, e), i) : x(he(t, ""), e) } class de { constructor(t, e) { this.animation = void 0, this.backgroundColor = "rgba(0,0,0,0.1)", this.borderColor = "rgba(0,0,0,0.1)", this.color = "#666", this.datasets = {}, this.devicePixelRatio = t => t.chart.platform.getDevicePixelRatio(), this.elements = {}, this.events = ["mousemove", "mouseout", "click", "touchstart", "touchmove"], this.font = { family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", size: 12, style: "normal", lineHeight: 1.2, weight: null }, this.hover = {}, this.hoverBackgroundColor = (t, e) => te(e.backgroundColor), this.hoverBorderColor = (t, e) => te(e.borderColor), this.hoverColor = (t, e) => te(e.color), this.indexAxis = "x", this.interaction = { mode: "nearest", intersect: !0, includeInvisible: !1 }, this.maintainAspectRatio = !0, this.onHover = null, this.onClick = null, this.parsing = !0, this.plugins = {}, this.responsive = !0, this.scale = void 0, this.scales = {}, this.showLine = !0, this.drawActiveElementsOnTop = !0, this.describe(t), this.apply(e) } set(t, e) { return ce(this, t, e) } get(t) { return he(this, t) } describe(t, e) { return ce(le, t, e) } override(t, e) { return ce(re, t, e) } route(t, e, i, s) { const n = he(this, t), a = he(this, i), r = "_" + e; Object.defineProperties(n, { [r]: { value: n[e], writable: !0 }, [e]: { enumerable: !0, get() { const t = this[r], e = a[s]; return o(t) ? Object.assign({}, e, t) : l(t, e) }, set(t) { this[r] = t } } }) } apply(t) { t.forEach((t => t(this))) } } var ue = new de({ _scriptable: t => !t.startsWith("on"), _indexable: t => "events" !== t, hover: { _fallback: "interaction" }, interaction: { _scriptable: !1, _indexable: !1 } }, [function (t) { t.set("animation", { delay: void 0, duration: 1e3, easing: "easeOutQuart", fn: void 0, from: void 0, loop: void 0, to: void 0, type: void 0 }), t.describe("animation", { _fallback: !1, _indexable: !1, _scriptable: t => "onProgress" !== t && "onComplete" !== t && "fn" !== t }), t.set("animations", { colors: { type: "color", properties: ie }, numbers: { type: "number", properties: ee } }), t.describe("animations", { _fallback: "animation" }), t.set("transitions", { active: { animation: { duration: 400 } }, resize: { animation: { duration: 0 } }, show: { animations: { colors: { from: "transparent" }, visible: { type: "boolean", duration: 0 } } }, hide: { animations: { colors: { to: "transparent" }, visible: { type: "boolean", easing: "linear", fn: t => 0 | t } } } }) }, function (t) { t.set("layout", { autoPadding: !0, padding: { top: 0, right: 0, bottom: 0, left: 0 } }) }, function (t) { t.set("scale", { display: !0, offset: !1, reverse: !1, beginAtZero: !1, bounds: "ticks", clip: !0, grace: 0, grid: { display: !0, lineWidth: 1, drawOnChartArea: !0, drawTicks: !0, tickLength: 8, tickWidth: (t, e) => e.lineWidth, tickColor: (t, e) => e.color, offset: !1 }, border: { display: !0, dash: [], dashOffset: 0, width: 1 }, title: { display: !1, text: "", padding: { top: 4, bottom: 4 } }, ticks: { minRotation: 0, maxRotation: 50, mirror: !1, textStrokeWidth: 0, textStrokeColor: "", padding: 3, display: !0, autoSkip: !0, autoSkipPadding: 3, labelOffset: 0, callback: ae.formatters.values, minor: {}, major: {}, align: "center", crossAlign: "near", showLabelBackdrop: !1, backdropColor: "rgba(255, 255, 255, 0.75)", backdropPadding: 2 } }), t.route("scale.ticks", "color", "", "color"), t.route("scale.grid", "color", "", "borderColor"), t.route("scale.border", "color", "", "borderColor"), t.route("scale.title", "color", "", "color"), t.describe("scale", { _fallback: !1, _scriptable: t => !t.startsWith("before") && !t.startsWith("after") && "callback" !== t && "parser" !== t, _indexable: t => "borderDash" !== t && "tickBorderDash" !== t && "dash" !== t }), t.describe("scales", { _fallback: "scale" }), t.describe("scale.ticks", { _scriptable: t => "backdropPadding" !== t && "callback" !== t, _indexable: t => "backdropPadding" !== t }) }]); function fe() { return "undefined" != typeof window && "undefined" != typeof document } function ge(t) { let e = t.parentNode; return e && "[object ShadowRoot]" === e.toString() && (e = e.host), e } function pe(t, e, i) { let s; return "string" == typeof t ? (s = parseInt(t, 10), -1 !== t.indexOf("%") && (s = s / 100 * e.parentNode[i])) : s = t, s } const me = t => t.ownerDocument.defaultView.getComputedStyle(t, null); function xe(t, e) { return me(t).getPropertyValue(e) } const be = ["top", "right", "bottom", "left"]; function _e(t, e, i) { const s = {}; i = i ? "-" + i : ""; for (let n = 0; n < 4; n++) { const o = be[n]; s[o] = parseFloat(t[e + "-" + o + i]) || 0 } return s.width = s.left + s.right, s.height = s.top + s.bottom, s } const ye = (t, e, i) => (t > 0 || e > 0) && (!i || !i.shadowRoot); function ve(t, e) { if ("native" in t) return t; const { canvas: i, currentDevicePixelRatio: s } = e, n = me(i), o = "border-box" === n.boxSizing, a = _e(n, "padding"), r = _e(n, "border", "width"), { x: l, y: h, box: c } = function (t, e) { const i = t.touches, s = i && i.length ? i[0] : t, { offsetX: n, offsetY: o } = s; let a, r, l = !1; if (ye(n, o, t.target)) a = n, r = o; else { const t = e.getBoundingClientRect(); a = s.clientX - t.left, r = s.clientY - t.top, l = !0 } return { x: a, y: r, box: l } }(t, i), d = a.left + (c && r.left), u = a.top + (c && r.top); let { width: f, height: g } = e; return o && (f -= a.width + r.width, g -= a.height + r.height), { x: Math.round((l - d) / f * i.width / s), y: Math.round((h - u) / g * i.height / s) } } const Me = t => Math.round(10 * t) / 10; function we(t, e, i, s) { const n = me(t), o = _e(n, "margin"), a = pe(n.maxWidth, t, "clientWidth") || T, r = pe(n.maxHeight, t, "clientHeight") || T, l = function (t, e, i) { let s, n; if (void 0 === e || void 0 === i) { const o = t && ge(t); if (o) { const t = o.getBoundingClientRect(), a = me(o), r = _e(a, "border", "width"), l = _e(a, "padding"); e = t.width - l.width - r.width, i = t.height - l.height - r.height, s = pe(a.maxWidth, o, "clientWidth"), n = pe(a.maxHeight, o, "clientHeight") } else e = t.clientWidth, i = t.clientHeight } return { width: e, height: i, maxWidth: s || T, maxHeight: n || T } }(t, e, i); let { width: h, height: c } = l; if ("content-box" === n.boxSizing) { const t = _e(n, "border", "width"), e = _e(n, "padding"); h -= e.width + t.width, c -= e.height + t.height } h = Math.max(0, h - o.width), c = Math.max(0, s ? h / s : c - o.height), h = Me(Math.min(h, a, l.maxWidth)), c = Me(Math.min(c, r, l.maxHeight)), h && !c && (c = Me(h / 2)); return (void 0 !== e || void 0 !== i) && s && l.height && c > l.height && (c = l.height, h = Me(Math.floor(c * s))), { width: h, height: c } } function ke(t, e, i) { const s = e || 1, n = Me(t.height * s), o = Me(t.width * s); t.height = Me(t.height), t.width = Me(t.width); const a = t.canvas; return a.style && (i || !a.style.height && !a.style.width) && (a.style.height = `${t.height}px`, a.style.width = `${t.width}px`), (t.currentDevicePixelRatio !== s || a.height !== n || a.width !== o) && (t.currentDevicePixelRatio = s, a.height = n, a.width = o, t.ctx.setTransform(s, 0, 0, s, 0, 0), !0) } const Se = function () { let t = !1; try { const e = { get passive() { return t = !0, !1 } }; fe() && (window.addEventListener("test", null, e), window.removeEventListener("test", null, e)) } catch (t) { } return t }(); function Pe(t, e) { const i = xe(t, e), s = i && i.match(/^(\d+)(\.\d+)?px$/); return s ? +s[1] : void 0 } function De(t) { return !t || s(t.size) || s(t.family) ? null : (t.style ? t.style + " " : "") + (t.weight ? t.weight + " " : "") + t.size + "px " + t.family } function Ce(t, e, i, s, n) { let o = e[n]; return o || (o = e[n] = t.measureText(n).width, i.push(n)), o > s && (s = o), s } function Oe(t, e, i, s) { let o = (s = s || {}).data = s.data || {}, a = s.garbageCollect = s.garbageCollect || []; s.font !== e && (o = s.data = {}, a = s.garbageCollect = [], s.font = e), t.save(), t.font = e; let r = 0; const l = i.length; let h, c, d, u, f; for (h = 0; h < l; h++)if (u = i[h], null == u || n(u)) { if (n(u)) for (c = 0, d = u.length; c < d; c++)f = u[c], null == f || n(f) || (r = Ce(t, o, a, r, f)) } else r = Ce(t, o, a, r, u); t.restore(); const g = a.length / 2; if (g > i.length) { for (h = 0; h < g; h++)delete o[a[h]]; a.splice(0, g) } return r } function Ae(t, e, i) { const s = t.currentDevicePixelRatio, n = 0 !== i ? Math.max(i / 2, .5) : 0; return Math.round((e - n) * s) / s + n } function Te(t, e) { (e || t) && ((e = e || t.getContext("2d")).save(), e.resetTransform(), e.clearRect(0, 0, t.width, t.height), e.restore()) } function Le(t, e, i, s) { Ee(t, e, i, s, null) } function Ee(t, e, i, s, n) { let o, a, r, l, h, c, d, u; const f = e.pointStyle, g = e.rotation, p = e.radius; let m = (g || 0) * L; if (f && "object" == typeof f && (o = f.toString(), "[object HTMLImageElement]" === o || "[object HTMLCanvasElement]" === o)) return t.save(), t.translate(i, s), t.rotate(m), t.drawImage(f, -f.width / 2, -f.height / 2, f.width, f.height), void t.restore(); if (!(isNaN(p) || p <= 0)) { switch (t.beginPath(), f) { default: n ? t.ellipse(i, s, n / 2, p, 0, 0, O) : t.arc(i, s, p, 0, O), t.closePath(); break; case "triangle": c = n ? n / 2 : p, t.moveTo(i + Math.sin(m) * c, s - Math.cos(m) * p), m += I, t.lineTo(i + Math.sin(m) * c, s - Math.cos(m) * p), m += I, t.lineTo(i + Math.sin(m) * c, s - Math.cos(m) * p), t.closePath(); break; case "rectRounded": h = .516 * p, l = p - h, a = Math.cos(m + R) * l, d = Math.cos(m + R) * (n ? n / 2 - h : l), r = Math.sin(m + R) * l, u = Math.sin(m + R) * (n ? n / 2 - h : l), t.arc(i - d, s - r, h, m - C, m - E), t.arc(i + u, s - a, h, m - E, m), t.arc(i + d, s + r, h, m, m + E), t.arc(i - u, s + a, h, m + E, m + C), t.closePath(); break; case "rect": if (!g) { l = Math.SQRT1_2 * p, c = n ? n / 2 : l, t.rect(i - c, s - l, 2 * c, 2 * l); break } m += R; case "rectRot": d = Math.cos(m) * (n ? n / 2 : p), a = Math.cos(m) * p, r = Math.sin(m) * p, u = Math.sin(m) * (n ? n / 2 : p), t.moveTo(i - d, s - r), t.lineTo(i + u, s - a), t.lineTo(i + d, s + r), t.lineTo(i - u, s + a), t.closePath(); break; case "crossRot": m += R; case "cross": d = Math.cos(m) * (n ? n / 2 : p), a = Math.cos(m) * p, r = Math.sin(m) * p, u = Math.sin(m) * (n ? n / 2 : p), t.moveTo(i - d, s - r), t.lineTo(i + d, s + r), t.moveTo(i + u, s - a), t.lineTo(i - u, s + a); break; case "star": d = Math.cos(m) * (n ? n / 2 : p), a = Math.cos(m) * p, r = Math.sin(m) * p, u = Math.sin(m) * (n ? n / 2 : p), t.moveTo(i - d, s - r), t.lineTo(i + d, s + r), t.moveTo(i + u, s - a), t.lineTo(i - u, s + a), m += R, d = Math.cos(m) * (n ? n / 2 : p), a = Math.cos(m) * p, r = Math.sin(m) * p, u = Math.sin(m) * (n ? n / 2 : p), t.moveTo(i - d, s - r), t.lineTo(i + d, s + r), t.moveTo(i + u, s - a), t.lineTo(i - u, s + a); break; case "line": a = n ? n / 2 : Math.cos(m) * p, r = Math.sin(m) * p, t.moveTo(i - a, s - r), t.lineTo(i + a, s + r); break; case "dash": t.moveTo(i, s), t.lineTo(i + Math.cos(m) * (n ? n / 2 : p), s + Math.sin(m) * p); break; case !1: t.closePath() }t.fill(), e.borderWidth > 0 && t.stroke() } } function Re(t, e, i) { return i = i || .5, !e || t && t.x > e.left - i && t.x < e.right + i && t.y > e.top - i && t.y < e.bottom + i } function Ie(t, e) { t.save(), t.beginPath(), t.rect(e.left, e.top, e.right - e.left, e.bottom - e.top), t.clip() } function ze(t) { t.restore() } function Fe(t, e, i, s, n) { if (!e) return t.lineTo(i.x, i.y); if ("middle" === n) { const s = (e.x + i.x) / 2; t.lineTo(s, e.y), t.lineTo(s, i.y) } else "after" === n != !!s ? t.lineTo(e.x, i.y) : t.lineTo(i.x, e.y); t.lineTo(i.x, i.y) } function Ve(t, e, i, s) { if (!e) return t.lineTo(i.x, i.y); t.bezierCurveTo(s ? e.cp1x : e.cp2x, s ? e.cp1y : e.cp2y, s ? i.cp2x : i.cp1x, s ? i.cp2y : i.cp1y, i.x, i.y) } function Be(t, e, i, s, n) { if (n.strikethrough || n.underline) { const o = t.measureText(s), a = e - o.actualBoundingBoxLeft, r = e + o.actualBoundingBoxRight, l = i - o.actualBoundingBoxAscent, h = i + o.actualBoundingBoxDescent, c = n.strikethrough ? (l + h) / 2 : h; t.strokeStyle = t.fillStyle, t.beginPath(), t.lineWidth = n.decorationWidth || 2, t.moveTo(a, c), t.lineTo(r, c), t.stroke() } } function We(t, e) { const i = t.fillStyle; t.fillStyle = e.color, t.fillRect(e.left, e.top, e.width, e.height), t.fillStyle = i } function Ne(t, e, i, o, a, r = {}) { const l = n(e) ? e : [e], h = r.strokeWidth > 0 && "" !== r.strokeColor; let c, d; for (t.save(), t.font = a.string, function (t, e) { e.translation && t.translate(e.translation[0], e.translation[1]), s(e.rotation) || t.rotate(e.rotation), e.color && (t.fillStyle = e.color), e.textAlign && (t.textAlign = e.textAlign), e.textBaseline && (t.textBaseline = e.textBaseline) }(t, r), c = 0; c < l.length; ++c)d = l[c], r.backdrop && We(t, r.backdrop), h && (r.strokeColor && (t.strokeStyle = r.strokeColor), s(r.strokeWidth) || (t.lineWidth = r.strokeWidth), t.strokeText(d, i, o, r.maxWidth)), t.fillText(d, i, o, r.maxWidth), Be(t, i, o, d, r), o += Number(a.lineHeight); t.restore() } function He(t, e) { const { x: i, y: s, w: n, h: o, radius: a } = e; t.arc(i + a.topLeft, s + a.topLeft, a.topLeft, 1.5 * C, C, !0), t.lineTo(i, s + o - a.bottomLeft), t.arc(i + a.bottomLeft, s + o - a.bottomLeft, a.bottomLeft, C, E, !0), t.lineTo(i + n - a.bottomRight, s + o), t.arc(i + n - a.bottomRight, s + o - a.bottomRight, a.bottomRight, E, 0, !0), t.lineTo(i + n, s + a.topRight), t.arc(i + n - a.topRight, s + a.topRight, a.topRight, 0, -E, !0), t.lineTo(i + a.topLeft, s) } function je(t, e = [""], i, s, n = (() => t[0])) { const o = i || t; void 0 === s && (s = ti("_fallback", t)); const a = { [Symbol.toStringTag]: "Object", _cacheable: !0, _scopes: t, _rootScopes: o, _fallback: s, _getTarget: n, override: i => je([i, ...t], e, o, s) }; return new Proxy(a, { deleteProperty: (e, i) => (delete e[i], delete e._keys, delete t[0][i], !0), get: (i, s) => qe(i, s, (() => function (t, e, i, s) { let n; for (const o of e) if (n = ti(Ue(o, t), i), void 0 !== n) return Xe(t, n) ? Ze(i, s, t, n) : n }(s, e, t, i))), getOwnPropertyDescriptor: (t, e) => Reflect.getOwnPropertyDescriptor(t._scopes[0], e), getPrototypeOf: () => Reflect.getPrototypeOf(t[0]), has: (t, e) => ei(t).includes(e), ownKeys: t => ei(t), set(t, e, i) { const s = t._storage || (t._storage = n()); return t[e] = s[e] = i, delete t._keys, !0 } }) } function $e(t, e, i, s) { const a = { _cacheable: !1, _proxy: t, _context: e, _subProxy: i, _stack: new Set, _descriptors: Ye(t, s), setContext: e => $e(t, e, i, s), override: n => $e(t.override(n), e, i, s) }; return new Proxy(a, { deleteProperty: (e, i) => (delete e[i], delete t[i], !0), get: (t, e, i) => qe(t, e, (() => function (t, e, i) { const { _proxy: s, _context: a, _subProxy: r, _descriptors: l } = t; let h = s[e]; S(h) && l.isScriptable(e) && (h = function (t, e, i, s) { const { _proxy: n, _context: o, _subProxy: a, _stack: r } = i; if (r.has(t)) throw new Error("Recursion detected: " + Array.from(r).join("->") + "->" + t); r.add(t); let l = e(o, a || s); r.delete(t), Xe(t, l) && (l = Ze(n._scopes, n, t, l)); return l }(e, h, t, i)); n(h) && h.length && (h = function (t, e, i, s) { const { _proxy: n, _context: a, _subProxy: r, _descriptors: l } = i; if (void 0 !== a.index && s(t)) return e[a.index % e.length]; if (o(e[0])) { const i = e, s = n._scopes.filter((t => t !== i)); e = []; for (const o of i) { const i = Ze(s, n, t, o); e.push($e(i, a, r && r[t], l)) } } return e }(e, h, t, l.isIndexable)); Xe(e, h) && (h = $e(h, a, r && r[e], l)); return h }(t, e, i))), getOwnPropertyDescriptor: (e, i) => e._descriptors.allKeys ? Reflect.has(t, i) ? { enumerable: !0, configurable: !0 } : void 0 : Reflect.getOwnPropertyDescriptor(t, i), getPrototypeOf: () => Reflect.getPrototypeOf(t), has: (e, i) => Reflect.has(t, i), ownKeys: () => Reflect.ownKeys(t), set: (e, i, s) => (t[i] = s, delete e[i], !0) }) } function Ye(t, e = { scriptable: !0, indexable: !0 }) { const { _scriptable: i = e.scriptable, _indexable: s = e.indexable, _allKeys: n = e.allKeys } = t; return { allKeys: n, scriptable: i, indexable: s, isScriptable: S(i) ? i : () => i, isIndexable: S(s) ? s : () => s } } const Ue = (t, e) => t ? t + w(e) : e, Xe = (t, e) => o(e) && "adapters" !== t && (null === Object.getPrototypeOf(e) || e.constructor === Object); function qe(t, e, i) { if (Object.prototype.hasOwnProperty.call(t, e) || "constructor" === e) return t[e]; const s = i(); return t[e] = s, s } function Ke(t, e, i) { return S(t) ? t(e, i) : t } const Ge = (t, e) => !0 === t ? e : "string" == typeof t ? M(e, t) : void 0; function Je(t, e, i, s, n) { for (const o of e) { const e = Ge(i, o); if (e) { t.add(e); const o = Ke(e._fallback, i, n); if (void 0 !== o && o !== i && o !== s) return o } else if (!1 === e && void 0 !== s && i !== s) return null } return !1 } function Ze(t, e, i, s) { const a = e._rootScopes, r = Ke(e._fallback, i, s), l = [...t, ...a], h = new Set; h.add(s); let c = Qe(h, l, i, r || i, s); return null !== c && ((void 0 === r || r === i || (c = Qe(h, l, r, c, s), null !== c)) && je(Array.from(h), [""], a, r, (() => function (t, e, i) { const s = t._getTarget(); e in s || (s[e] = {}); const a = s[e]; if (n(a) && o(i)) return i; return a || {} }(e, i, s)))) } function Qe(t, e, i, s, n) { for (; i;)i = Je(t, e, i, s, n); return i } function ti(t, e) { for (const i of e) { if (!i) continue; const e = i[t]; if (void 0 !== e) return e } } function ei(t) { let e = t._keys; return e || (e = t._keys = function (t) { const e = new Set; for (const i of t) for (const t of Object.keys(i).filter((t => !t.startsWith("_")))) e.add(t); return Array.from(e) }(t._scopes)), e } function ii(t, e, i, s) { const { iScale: n } = t, { key: o = "r" } = this._parsing, a = new Array(s); let r, l, h, c; for (r = 0, l = s; r < l; ++r)h = r + i, c = e[h], a[r] = { r: n.parse(M(c, o), h) }; return a } const si = Number.EPSILON || 1e-14, ni = (t, e) => e < t.length && !t[e].skip && t[e], oi = t => "x" === t ? "y" : "x"; function ai(t, e, i, s) { const n = t.skip ? e : t, o = e, a = i.skip ? e : i, r = q(o, n), l = q(a, o); let h = r / (r + l), c = l / (r + l); h = isNaN(h) ? 0 : h, c = isNaN(c) ? 0 : c; const d = s * h, u = s * c; return { previous: { x: o.x - d * (a.x - n.x), y: o.y - d * (a.y - n.y) }, next: { x: o.x + u * (a.x - n.x), y: o.y + u * (a.y - n.y) } } } function ri(t, e = "x") { const i = oi(e), s = t.length, n = Array(s).fill(0), o = Array(s); let a, r, l, h = ni(t, 0); for (a = 0; a < s; ++a)if (r = l, l = h, h = ni(t, a + 1), l) { if (h) { const t = h[e] - l[e]; n[a] = 0 !== t ? (h[i] - l[i]) / t : 0 } o[a] = r ? h ? F(n[a - 1]) !== F(n[a]) ? 0 : (n[a - 1] + n[a]) / 2 : n[a - 1] : n[a] } !function (t, e, i) { const s = t.length; let n, o, a, r, l, h = ni(t, 0); for (let c = 0; c < s - 1; ++c)l = h, h = ni(t, c + 1), l && h && (V(e[c], 0, si) ? i[c] = i[c + 1] = 0 : (n = i[c] / e[c], o = i[c + 1] / e[c], r = Math.pow(n, 2) + Math.pow(o, 2), r <= 9 || (a = 3 / Math.sqrt(r), i[c] = n * a * e[c], i[c + 1] = o * a * e[c]))) }(t, n, o), function (t, e, i = "x") { const s = oi(i), n = t.length; let o, a, r, l = ni(t, 0); for (let h = 0; h < n; ++h) { if (a = r, r = l, l = ni(t, h + 1), !r) continue; const n = r[i], c = r[s]; a && (o = (n - a[i]) / 3, r[`cp1${i}`] = n - o, r[`cp1${s}`] = c - o * e[h]), l && (o = (l[i] - n) / 3, r[`cp2${i}`] = n + o, r[`cp2${s}`] = c + o * e[h]) } }(t, o, e) } function li(t, e, i) { return Math.max(Math.min(t, i), e) } function hi(t, e, i, s, n) { let o, a, r, l; if (e.spanGaps && (t = t.filter((t => !t.skip))), "monotone" === e.cubicInterpolationMode) ri(t, n); else { let i = s ? t[t.length - 1] : t[0]; for (o = 0, a = t.length; o < a; ++o)r = t[o], l = ai(i, r, t[Math.min(o + 1, a - (s ? 0 : 1)) % a], e.tension), r.cp1x = l.previous.x, r.cp1y = l.previous.y, r.cp2x = l.next.x, r.cp2y = l.next.y, i = r } e.capBezierPoints && function (t, e) { let i, s, n, o, a, r = Re(t[0], e); for (i = 0, s = t.length; i < s; ++i)a = o, o = r, r = i < s - 1 && Re(t[i + 1], e), o && (n = t[i], a && (n.cp1x = li(n.cp1x, e.left, e.right), n.cp1y = li(n.cp1y, e.top, e.bottom)), r && (n.cp2x = li(n.cp2x, e.left, e.right), n.cp2y = li(n.cp2y, e.top, e.bottom))) }(t, i) } const ci = t => 0 === t || 1 === t, di = (t, e, i) => -Math.pow(2, 10 * (t -= 1)) * Math.sin((t - e) * O / i), ui = (t, e, i) => Math.pow(2, -10 * t) * Math.sin((t - e) * O / i) + 1, fi = { linear: t => t, easeInQuad: t => t * t, easeOutQuad: t => -t * (t - 2), easeInOutQuad: t => (t /= .5) < 1 ? .5 * t * t : -.5 * (--t * (t - 2) - 1), easeInCubic: t => t * t * t, easeOutCubic: t => (t -= 1) * t * t + 1, easeInOutCubic: t => (t /= .5) < 1 ? .5 * t * t * t : .5 * ((t -= 2) * t * t + 2), easeInQuart: t => t * t * t * t, easeOutQuart: t => -((t -= 1) * t * t * t - 1), easeInOutQuart: t => (t /= .5) < 1 ? .5 * t * t * t * t : -.5 * ((t -= 2) * t * t * t - 2), easeInQuint: t => t * t * t * t * t, easeOutQuint: t => (t -= 1) * t * t * t * t + 1, easeInOutQuint: t => (t /= .5) < 1 ? .5 * t * t * t * t * t : .5 * ((t -= 2) * t * t * t * t + 2), easeInSine: t => 1 - Math.cos(t * E), easeOutSine: t => Math.sin(t * E), easeInOutSine: t => -.5 * (Math.cos(C * t) - 1), easeInExpo: t => 0 === t ? 0 : Math.pow(2, 10 * (t - 1)), easeOutExpo: t => 1 === t ? 1 : 1 - Math.pow(2, -10 * t), easeInOutExpo: t => ci(t) ? t : t < .5 ? .5 * Math.pow(2, 10 * (2 * t - 1)) : .5 * (2 - Math.pow(2, -10 * (2 * t - 1))), easeInCirc: t => t >= 1 ? t : -(Math.sqrt(1 - t * t) - 1), easeOutCirc: t => Math.sqrt(1 - (t -= 1) * t), easeInOutCirc: t => (t /= .5) < 1 ? -.5 * (Math.sqrt(1 - t * t) - 1) : .5 * (Math.sqrt(1 - (t -= 2) * t) + 1), easeInElastic: t => ci(t) ? t : di(t, .075, .3), easeOutElastic: t => ci(t) ? t : ui(t, .075, .3), easeInOutElastic(t) { const e = .1125; return ci(t) ? t : t < .5 ? .5 * di(2 * t, e, .45) : .5 + .5 * ui(2 * t - 1, e, .45) }, easeInBack(t) { const e = 1.70158; return t * t * ((e + 1) * t - e) }, easeOutBack(t) { const e = 1.70158; return (t -= 1) * t * ((e + 1) * t + e) + 1 }, easeInOutBack(t) { let e = 1.70158; return (t /= .5) < 1 ? t * t * ((1 + (e *= 1.525)) * t - e) * .5 : .5 * ((t -= 2) * t * ((1 + (e *= 1.525)) * t + e) + 2) }, easeInBounce: t => 1 - fi.easeOutBounce(1 - t), easeOutBounce(t) { const e = 7.5625, i = 2.75; return t < 1 / i ? e * t * t : t < 2 / i ? e * (t -= 1.5 / i) * t + .75 : t < 2.5 / i ? e * (t -= 2.25 / i) * t + .9375 : e * (t -= 2.625 / i) * t + .984375 }, easeInOutBounce: t => t < .5 ? .5 * fi.easeInBounce(2 * t) : .5 * fi.easeOutBounce(2 * t - 1) + .5 }; function gi(t, e, i, s) { return { x: t.x + i * (e.x - t.x), y: t.y + i * (e.y - t.y) } } function pi(t, e, i, s) { return { x: t.x + i * (e.x - t.x), y: "middle" === s ? i < .5 ? t.y : e.y : "after" === s ? i < 1 ? t.y : e.y : i > 0 ? e.y : t.y } } function mi(t, e, i, s) { const n = { x: t.cp2x, y: t.cp2y }, o = { x: e.cp1x, y: e.cp1y }, a = gi(t, n, i), r = gi(n, o, i), l = gi(o, e, i), h = gi(a, r, i), c = gi(r, l, i); return gi(h, c, i) } const xi = /^(normal|(\d+(?:\.\d+)?)(px|em|%)?)$/, bi = /^(normal|italic|initial|inherit|unset|(oblique( -?[0-9]?[0-9]deg)?))$/; function _i(t, e) { const i = ("" + t).match(xi); if (!i || "normal" === i[1]) return 1.2 * e; switch (t = +i[2], i[3]) { case "px": return t; case "%": t /= 100 }return e * t } const yi = t => +t || 0; function vi(t, e) { const i = {}, s = o(e), n = s ? Object.keys(e) : e, a = o(t) ? s ? i => l(t[i], t[e[i]]) : e => t[e] : () => t; for (const t of n) i[t] = yi(a(t)); return i } function Mi(t) { return vi(t, { top: "y", right: "x", bottom: "y", left: "x" }) } function wi(t) { return vi(t, ["topLeft", "topRight", "bottomLeft", "bottomRight"]) } function ki(t) { const e = Mi(t); return e.width = e.left + e.right, e.height = e.top + e.bottom, e } function Si(t, e) { t = t || {}, e = e || ue.font; let i = l(t.size, e.size); "string" == typeof i && (i = parseInt(i, 10)); let s = l(t.style, e.style); s && !("" + s).match(bi) && (console.warn('Invalid font style specified: "' + s + '"'), s = void 0); const n = { family: l(t.family, e.family), lineHeight: _i(l(t.lineHeight, e.lineHeight), i), size: i, style: s, weight: l(t.weight, e.weight), string: "" }; return n.string = De(n), n } function Pi(t, e, i, s) { let o, a, r, l = !0; for (o = 0, a = t.length; o < a; ++o)if (r = t[o], void 0 !== r && (void 0 !== e && "function" == typeof r && (r = r(e), l = !1), void 0 !== i && n(r) && (r = r[i % r.length], l = !1), void 0 !== r)) return s && !l && (s.cacheable = !1), r } function Di(t, e, i) { const { min: s, max: n } = t, o = c(e, (n - s) / 2), a = (t, e) => i && 0 === t ? 0 : t + e; return { min: a(s, -Math.abs(o)), max: a(n, o) } } function Ci(t, e) { return Object.assign(Object.create(t), e) } function Oi(t, e, i) { return t ? function (t, e) { return { x: i => t + t + e - i, setWidth(t) { e = t }, textAlign: t => "center" === t ? t : "right" === t ? "left" : "right", xPlus: (t, e) => t - e, leftForLtr: (t, e) => t - e } }(e, i) : { x: t => t, setWidth(t) { }, textAlign: t => t, xPlus: (t, e) => t + e, leftForLtr: (t, e) => t } } function Ai(t, e) { let i, s; "ltr" !== e && "rtl" !== e || (i = t.canvas.style, s = [i.getPropertyValue("direction"), i.getPropertyPriority("direction")], i.setProperty("direction", e, "important"), t.prevTextDirection = s) } function Ti(t, e) { void 0 !== e && (delete t.prevTextDirection, t.canvas.style.setProperty("direction", e[0], e[1])) } function Li(t) { return "angle" === t ? { between: J, compare: K, normalize: G } : { between: tt, compare: (t, e) => t - e, normalize: t => t } } function Ei({ start: t, end: e, count: i, loop: s, style: n }) { return { start: t % i, end: e % i, loop: s && (e - t + 1) % i == 0, style: n } } function Ri(t, e, i) { if (!i) return [t]; const { property: s, start: n, end: o } = i, a = e.length, { compare: r, between: l, normalize: h } = Li(s), { start: c, end: d, loop: u, style: f } = function (t, e, i) { const { property: s, start: n, end: o } = i, { between: a, normalize: r } = Li(s), l = e.length; let h, c, { start: d, end: u, loop: f } = t; if (f) { for (d += l, u += l, h = 0, c = l; h < c && a(r(e[d % l][s]), n, o); ++h)d--, u--; d %= l, u %= l } return u < d && (u += l), { start: d, end: u, loop: f, style: t.style } }(t, e, i), g = []; let p, m, x, b = !1, _ = null; const y = () => b || l(n, x, p) && 0 !== r(n, x), v = () => !b || 0 === r(o, p) || l(o, x, p); for (let t = c, i = c; t <= d; ++t)m = e[t % a], m.skip || (p = h(m[s]), p !== x && (b = l(p, n, o), null === _ && y() && (_ = 0 === r(p, n) ? t : i), null !== _ && v() && (g.push(Ei({ start: _, end: t, loop: u, count: a, style: f })), _ = null), i = t, x = p)); return null !== _ && g.push(Ei({ start: _, end: d, loop: u, count: a, style: f })), g } function Ii(t, e) { const i = [], s = t.segments; for (let n = 0; n < s.length; n++) { const o = Ri(s[n], t.points, e); o.length && i.push(...o) } return i } function zi(t, e) { const i = t.points, s = t.options.spanGaps, n = i.length; if (!n) return []; const o = !!t._loop, { start: a, end: r } = function (t, e, i, s) { let n = 0, o = e - 1; if (i && !s) for (; n < e && !t[n].skip;)n++; for (; n < e && t[n].skip;)n++; for (n %= e, i && (o += n); o > n && t[o % e].skip;)o--; return o %= e, { start: n, end: o } }(i, n, o, s); if (!0 === s) return Fi(t, [{ start: a, end: r, loop: o }], i, e); return Fi(t, function (t, e, i, s) { const n = t.length, o = []; let a, r = e, l = t[e]; for (a = e + 1; a <= i; ++a) { const i = t[a % n]; i.skip || i.stop ? l.skip || (s = !1, o.push({ start: e % n, end: (a - 1) % n, loop: s }), e = r = i.stop ? a : null) : (r = a, l.skip && (e = a)), l = i } return null !== r && o.push({ start: e % n, end: r % n, loop: s }), o }(i, a, r < a ? r + n : r, !!t._fullLoop && 0 === a && r === n - 1), i, e) } function Fi(t, e, i, s) { return s && s.setContext && i ? function (t, e, i, s) { const n = t._chart.getContext(), o = Vi(t.options), { _datasetIndex: a, options: { spanGaps: r } } = t, l = i.length, h = []; let c = o, d = e[0].start, u = d; function f(t, e, s, n) { const o = r ? -1 : 1; if (t !== e) { for (t += l; i[t % l].skip;)t -= o; for (; i[e % l].skip;)e += o; t % l != e % l && (h.push({ start: t % l, end: e % l, loop: s, style: n }), c = n, d = e % l) } } for (const t of e) { d = r ? d : t.start; let e, o = i[d % l]; for (u = d + 1; u <= t.end; u++) { const r = i[u % l]; e = Vi(s.setContext(Ci(n, { type: "segment", p0: o, p1: r, p0DataIndex: (u - 1) % l, p1DataIndex: u % l, datasetIndex: a }))), Bi(e, c) && f(d, u - 1, t.loop, c), o = r, c = e } d < u - 1 && f(d, u - 1, t.loop, c) } return h }(t, e, i, s) : e } function Vi(t) { return { backgroundColor: t.backgroundColor, borderCapStyle: t.borderCapStyle, borderDash: t.borderDash, borderDashOffset: t.borderDashOffset, borderJoinStyle: t.borderJoinStyle, borderWidth: t.borderWidth, borderColor: t.borderColor } } function Bi(t, e) { if (!e) return !1; const i = [], s = function (t, e) { return Zt(e) ? (i.includes(e) || i.push(e), i.indexOf(e)) : e }; return JSON.stringify(t, s) !== JSON.stringify(e, s) } function Wi(t, e, i) { return t.options.clip ? t[i] : e[i] } function Ni(t, e) { const i = e._clip; if (i.disabled) return !1; const s = function (t, e) { const { xScale: i, yScale: s } = t; return i && s ? { left: Wi(i, e, "left"), right: Wi(i, e, "right"), top: Wi(s, e, "top"), bottom: Wi(s, e, "bottom") } : e }(e, t.chartArea); return { left: !1 === i.left ? 0 : s.left - (!0 === i.left ? 0 : i.left), right: !1 === i.right ? t.width : s.right + (!0 === i.right ? 0 : i.right), top: !1 === i.top ? 0 : s.top - (!0 === i.top ? 0 : i.top), bottom: !1 === i.bottom ? t.height : s.bottom + (!0 === i.bottom ? 0 : i.bottom) } } var Hi = Object.freeze({ __proto__: null, HALF_PI: E, INFINITY: T, PI: C, PITAU: A, QUARTER_PI: R, RAD_PER_DEG: L, TAU: O, TWO_THIRDS_PI: I, _addGrace: Di, _alignPixel: Ae, _alignStartEnd: ft, _angleBetween: J, _angleDiff: K, _arrayUnique: lt, _attachContext: $e, _bezierCurveTo: Ve, _bezierInterpolation: mi, _boundSegment: Ri, _boundSegments: Ii, _capitalize: w, _computeSegments: zi, _createResolver: je, _decimalPlaces: U, _deprecated: function (t, e, i, s) { void 0 !== e && console.warn(t + ': "' + i + '" is deprecated. Please use "' + s + '" instead') }, _descriptors: Ye, _elementsEqual: f, _factorize: W, _filterBetween: nt, _getParentNode: ge, _getStartAndCountOfVisiblePoints: pt, _int16Range: Q, _isBetween: tt, _isClickEvent: D, _isDomSupported: fe, _isPointInArea: Re, _limitValue: Z, _longestText: Oe, _lookup: et, _lookupByKey: it, _measureText: Ce, _merger: m, _mergerIf: _, _normalizeAngle: G, _parseObjectDataRadialScale: ii, _pointInLine: gi, _readValueToProps: vi, _rlookupByKey: st, _scaleRangesChanged: mt, _setMinAndMaxByKey: j, _splitKey: v, _steppedInterpolation: pi, _steppedLineTo: Fe, _textX: gt, _toLeftRightCenter: ut, _updateBezierControlPoints: hi, addRoundedRectPath: He, almostEquals: V, almostWhole: H, callback: d, clearCanvas: Te, clipArea: Ie, clone: g, color: Qt, createContext: Ci, debounce: dt, defined: k, distanceBetweenPoints: q, drawPoint: Le, drawPointLegend: Ee, each: u, easingEffects: fi, finiteOrDefault: r, fontString: function (t, e, i) { return e + " " + t + "px " + i }, formatNumber: ne, getAngleFromPoint: X, getDatasetClipArea: Ni, getHoverColor: te, getMaximumSize: we, getRelativePosition: ve, getRtlAdapter: Oi, getStyle: xe, isArray: n, isFinite: a, isFunction: S, isNullOrUndef: s, isNumber: N, isObject: o, isPatternOrGradient: Zt, listenArrayEvents: at, log10: z, merge: x, mergeIf: b, niceNum: B, noop: e, overrideTextDirection: Ai, readUsedSize: Pe, renderText: Ne, requestAnimFrame: ht, resolve: Pi, resolveObjectKey: M, restoreTextDirection: Ti, retinaScale: ke, setsEqual: P, sign: F, splineCurve: ai, splineCurveMonotone: ri, supportsEventListenerOptions: Se, throttled: ct, toDegrees: Y, toDimension: c, toFont: Si, toFontString: De, toLineHeight: _i, toPadding: ki, toPercentage: h, toRadians: $, toTRBL: Mi, toTRBLCorners: wi, uid: i, unclipArea: ze, unlistenArrayEvents: rt, valueOrDefault: l }); function ji(t, e, i, n) { const { controller: o, data: a, _sorted: r } = t, l = o._cachedMeta.iScale, h = t.dataset && t.dataset.options ? t.dataset.options.spanGaps : null; if (l && e === l.axis && "r" !== e && r && a.length) { const r = l._reversePixels ? st : it; if (!n) { const n = r(a, e, i); if (h) { const { vScale: e } = o._cachedMeta, { _parsed: i } = t, a = i.slice(0, n.lo + 1).reverse().findIndex((t => !s(t[e.axis]))); n.lo -= Math.max(0, a); const r = i.slice(n.hi).findIndex((t => !s(t[e.axis]))); n.hi += Math.max(0, r) } return n } if (o._sharedOptions) { const t = a[0], s = "function" == typeof t.getRange && t.getRange(e); if (s) { const t = r(a, e, i - s), n = r(a, e, i + s); return { lo: t.lo, hi: n.hi } } } } return { lo: 0, hi: a.length - 1 } } function $i(t, e, i, s, n) { const o = t.getSortedVisibleDatasetMetas(), a = i[e]; for (let t = 0, i = o.length; t < i; ++t) { const { index: i, data: r } = o[t], { lo: l, hi: h } = ji(o[t], e, a, n); for (let t = l; t <= h; ++t) { const e = r[t]; e.skip || s(e, i, t) } } } function Yi(t, e, i, s, n) { const o = []; if (!n && !t.isPointInArea(e)) return o; return $i(t, i, e, (function (i, a, r) { (n || Re(i, t.chartArea, 0)) && i.inRange(e.x, e.y, s) && o.push({ element: i, datasetIndex: a, index: r }) }), !0), o } function Ui(t, e, i, s, n, o) { let a = []; const r = function (t) { const e = -1 !== t.indexOf("x"), i = -1 !== t.indexOf("y"); return function (t, s) { const n = e ? Math.abs(t.x - s.x) : 0, o = i ? Math.abs(t.y - s.y) : 0; return Math.sqrt(Math.pow(n, 2) + Math.pow(o, 2)) } }(i); let l = Number.POSITIVE_INFINITY; return $i(t, i, e, (function (i, h, c) { const d = i.inRange(e.x, e.y, n); if (s && !d) return; const u = i.getCenterPoint(n); if (!(!!o || t.isPointInArea(u)) && !d) return; const f = r(e, u); f < l ? (a = [{ element: i, datasetIndex: h, index: c }], l = f) : f === l && a.push({ element: i, datasetIndex: h, index: c }) })), a } function Xi(t, e, i, s, n, o) { return o || t.isPointInArea(e) ? "r" !== i || s ? Ui(t, e, i, s, n, o) : function (t, e, i, s) { let n = []; return $i(t, i, e, (function (t, i, o) { const { startAngle: a, endAngle: r } = t.getProps(["startAngle", "endAngle"], s), { angle: l } = X(t, { x: e.x, y: e.y }); J(l, a, r) && n.push({ element: t, datasetIndex: i, index: o }) })), n }(t, e, i, n) : [] } function qi(t, e, i, s, n) { const o = [], a = "x" === i ? "inXRange" : "inYRange"; let r = !1; return $i(t, i, e, ((t, s, l) => { t[a] && t[a](e[i], n) && (o.push({ element: t, datasetIndex: s, index: l }), r = r || t.inRange(e.x, e.y, n)) })), s && !r ? [] : o } var Ki = { evaluateInteractionItems: $i, modes: { index(t, e, i, s) { const n = ve(e, t), o = i.axis || "x", a = i.includeInvisible || !1, r = i.intersect ? Yi(t, n, o, s, a) : Xi(t, n, o, !1, s, a), l = []; return r.length ? (t.getSortedVisibleDatasetMetas().forEach((t => { const e = r[0].index, i = t.data[e]; i && !i.skip && l.push({ element: i, datasetIndex: t.index, index: e }) })), l) : [] }, dataset(t, e, i, s) { const n = ve(e, t), o = i.axis || "xy", a = i.includeInvisible || !1; let r = i.intersect ? Yi(t, n, o, s, a) : Xi(t, n, o, !1, s, a); if (r.length > 0) { const e = r[0].datasetIndex, i = t.getDatasetMeta(e).data; r = []; for (let t = 0; t < i.length; ++t)r.push({ element: i[t], datasetIndex: e, index: t }) } return r }, point: (t, e, i, s) => Yi(t, ve(e, t), i.axis || "xy", s, i.includeInvisible || !1), nearest(t, e, i, s) { const n = ve(e, t), o = i.axis || "xy", a = i.includeInvisible || !1; return Xi(t, n, o, i.intersect, s, a) }, x: (t, e, i, s) => qi(t, ve(e, t), "x", i.intersect, s), y: (t, e, i, s) => qi(t, ve(e, t), "y", i.intersect, s) } }; const Gi = ["left", "top", "right", "bottom"]; function Ji(t, e) { return t.filter((t => t.pos === e)) } function Zi(t, e) { return t.filter((t => -1 === Gi.indexOf(t.pos) && t.box.axis === e)) } function Qi(t, e) { return t.sort(((t, i) => { const s = e ? i : t, n = e ? t : i; return s.weight === n.weight ? s.index - n.index : s.weight - n.weight })) } function ts(t, e) { const i = function (t) { const e = {}; for (const i of t) { const { stack: t, pos: s, stackWeight: n } = i; if (!t || !Gi.includes(s)) continue; const o = e[t] || (e[t] = { count: 0, placed: 0, weight: 0, size: 0 }); o.count++, o.weight += n } return e }(t), { vBoxMaxWidth: s, hBoxMaxHeight: n } = e; let o, a, r; for (o = 0, a = t.length; o < a; ++o) { r = t[o]; const { fullSize: a } = r.box, l = i[r.stack], h = l && r.stackWeight / l.weight; r.horizontal ? (r.width = h ? h * s : a && e.availableWidth, r.height = n) : (r.width = s, r.height = h ? h * n : a && e.availableHeight) } return i } function es(t, e, i, s) { return Math.max(t[i], e[i]) + Math.max(t[s], e[s]) } function is(t, e) { t.top = Math.max(t.top, e.top), t.left = Math.max(t.left, e.left), t.bottom = Math.max(t.bottom, e.bottom), t.right = Math.max(t.right, e.right) } function ss(t, e, i, s) { const { pos: n, box: a } = i, r = t.maxPadding; if (!o(n)) { i.size && (t[n] -= i.size); const e = s[i.stack] || { size: 0, count: 1 }; e.size = Math.max(e.size, i.horizontal ? a.height : a.width), i.size = e.size / e.count, t[n] += i.size } a.getPadding && is(r, a.getPadding()); const l = Math.max(0, e.outerWidth - es(r, t, "left", "right")), h = Math.max(0, e.outerHeight - es(r, t, "top", "bottom")), c = l !== t.w, d = h !== t.h; return t.w = l, t.h = h, i.horizontal ? { same: c, other: d } : { same: d, other: c } } function ns(t, e) { const i = e.maxPadding; function s(t) { const s = { left: 0, top: 0, right: 0, bottom: 0 }; return t.forEach((t => { s[t] = Math.max(e[t], i[t]) })), s } return s(t ? ["left", "right"] : ["top", "bottom"]) } function os(t, e, i, s) { const n = []; let o, a, r, l, h, c; for (o = 0, a = t.length, h = 0; o < a; ++o) { r = t[o], l = r.box, l.update(r.width || e.w, r.height || e.h, ns(r.horizontal, e)); const { same: a, other: d } = ss(e, i, r, s); h |= a && n.length, c = c || d, l.fullSize || n.push(r) } return h && os(n, e, i, s) || c } function as(t, e, i, s, n) { t.top = i, t.left = e, t.right = e + s, t.bottom = i + n, t.width = s, t.height = n } function rs(t, e, i, s) { const n = i.padding; let { x: o, y: a } = e; for (const r of t) { const t = r.box, l = s[r.stack] || { count: 1, placed: 0, weight: 1 }, h = r.stackWeight / l.weight || 1; if (r.horizontal) { const s = e.w * h, o = l.size || t.height; k(l.start) && (a = l.start), t.fullSize ? as(t, n.left, a, i.outerWidth - n.right - n.left, o) : as(t, e.left + l.placed, a, s, o), l.start = a, l.placed += s, a = t.bottom } else { const s = e.h * h, a = l.size || t.width; k(l.start) && (o = l.start), t.fullSize ? as(t, o, n.top, a, i.outerHeight - n.bottom - n.top) : as(t, o, e.top + l.placed, a, s), l.start = o, l.placed += s, o = t.right } } e.x = o, e.y = a } var ls = { addBox(t, e) { t.boxes || (t.boxes = []), e.fullSize = e.fullSize || !1, e.position = e.position || "top", e.weight = e.weight || 0, e._layers = e._layers || function () { return [{ z: 0, draw(t) { e.draw(t) } }] }, t.boxes.push(e) }, removeBox(t, e) { const i = t.boxes ? t.boxes.indexOf(e) : -1; -1 !== i && t.boxes.splice(i, 1) }, configure(t, e, i) { e.fullSize = i.fullSize, e.position = i.position, e.weight = i.weight }, update(t, e, i, s) { if (!t) return; const n = ki(t.options.layout.padding), o = Math.max(e - n.width, 0), a = Math.max(i - n.height, 0), r = function (t) { const e = function (t) { const e = []; let i, s, n, o, a, r; for (i = 0, s = (t || []).length; i < s; ++i)n = t[i], ({ position: o, options: { stack: a, stackWeight: r = 1 } } = n), e.push({ index: i, box: n, pos: o, horizontal: n.isHorizontal(), weight: n.weight, stack: a && o + a, stackWeight: r }); return e }(t), i = Qi(e.filter((t => t.box.fullSize)), !0), s = Qi(Ji(e, "left"), !0), n = Qi(Ji(e, "right")), o = Qi(Ji(e, "top"), !0), a = Qi(Ji(e, "bottom")), r = Zi(e, "x"), l = Zi(e, "y"); return { fullSize: i, leftAndTop: s.concat(o), rightAndBottom: n.concat(l).concat(a).concat(r), chartArea: Ji(e, "chartArea"), vertical: s.concat(n).concat(l), horizontal: o.concat(a).concat(r) } }(t.boxes), l = r.vertical, h = r.horizontal; u(t.boxes, (t => { "function" == typeof t.beforeLayout && t.beforeLayout() })); const c = l.reduce(((t, e) => e.box.options && !1 === e.box.options.display ? t : t + 1), 0) || 1, d = Object.freeze({ outerWidth: e, outerHeight: i, padding: n, availableWidth: o, availableHeight: a, vBoxMaxWidth: o / 2 / c, hBoxMaxHeight: a / 2 }), f = Object.assign({}, n); is(f, ki(s)); const g = Object.assign({ maxPadding: f, w: o, h: a, x: n.left, y: n.top }, n), p = ts(l.concat(h), d); os(r.fullSize, g, d, p), os(l, g, d, p), os(h, g, d, p) && os(l, g, d, p), function (t) { const e = t.maxPadding; function i(i) { const s = Math.max(e[i] - t[i], 0); return t[i] += s, s } t.y += i("top"), t.x += i("left"), i("right"), i("bottom") }(g), rs(r.leftAndTop, g, d, p), g.x += g.w, g.y += g.h, rs(r.rightAndBottom, g, d, p), t.chartArea = { left: g.left, top: g.top, right: g.left + g.w, bottom: g.top + g.h, height: g.h, width: g.w }, u(r.chartArea, (e => { const i = e.box; Object.assign(i, t.chartArea), i.update(g.w, g.h, { left: 0, top: 0, right: 0, bottom: 0 }) })) } }; class hs { acquireContext(t, e) { } releaseContext(t) { return !1 } addEventListener(t, e, i) { } removeEventListener(t, e, i) { } getDevicePixelRatio() { return 1 } getMaximumSize(t, e, i, s) { return e = Math.max(0, e || t.width), i = i || t.height, { width: e, height: Math.max(0, s ? Math.floor(e / s) : i) } } isAttached(t) { return !0 } updateConfig(t) { } } class cs extends hs { acquireContext(t) { return t && t.getContext && t.getContext("2d") || null } updateConfig(t) { t.options.animation = !1 } } const ds = "$chartjs", us = { touchstart: "mousedown", touchmove: "mousemove", touchend: "mouseup", pointerenter: "mouseenter", pointerdown: "mousedown", pointermove: "mousemove", pointerup: "mouseup", pointerleave: "mouseout", pointerout: "mouseout" }, fs = t => null === t || "" === t; const gs = !!Se && { passive: !0 }; function ps(t, e, i) { t && t.canvas && t.canvas.removeEventListener(e, i, gs) } function ms(t, e) { for (const i of t) if (i === e || i.contains(e)) return !0 } function xs(t, e, i) { const s = t.canvas, n = new MutationObserver((t => { let e = !1; for (const i of t) e = e || ms(i.addedNodes, s), e = e && !ms(i.removedNodes, s); e && i() })); return n.observe(document, { childList: !0, subtree: !0 }), n } function bs(t, e, i) { const s = t.canvas, n = new MutationObserver((t => { let e = !1; for (const i of t) e = e || ms(i.removedNodes, s), e = e && !ms(i.addedNodes, s); e && i() })); return n.observe(document, { childList: !0, subtree: !0 }), n } const _s = new Map; let ys = 0; function vs() { const t = window.devicePixelRatio; t !== ys && (ys = t, _s.forEach(((e, i) => { i.currentDevicePixelRatio !== t && e() }))) } function Ms(t, e, i) { const s = t.canvas, n = s && ge(s); if (!n) return; const o = ct(((t, e) => { const s = n.clientWidth; i(t, e), s < n.clientWidth && i() }), window), a = new ResizeObserver((t => { const e = t[0], i = e.contentRect.width, s = e.contentRect.height; 0 === i && 0 === s || o(i, s) })); return a.observe(n), function (t, e) { _s.size || window.addEventListener("resize", vs), _s.set(t, e) }(t, o), a } function ws(t, e, i) { i && i.disconnect(), "resize" === e && function (t) { _s.delete(t), _s.size || window.removeEventListener("resize", vs) }(t) } function ks(t, e, i) { const s = t.canvas, n = ct((e => { null !== t.ctx && i(function (t, e) { const i = us[t.type] || t.type, { x: s, y: n } = ve(t, e); return { type: i, chart: e, native: t, x: void 0 !== s ? s : null, y: void 0 !== n ? n : null } }(e, t)) }), t); return function (t, e, i) { t && t.addEventListener(e, i, gs) }(s, e, n), n } class Ss extends hs { acquireContext(t, e) { const i = t && t.getContext && t.getContext("2d"); return i && i.canvas === t ? (function (t, e) { const i = t.style, s = t.getAttribute("height"), n = t.getAttribute("width"); if (t[ds] = { initial: { height: s, width: n, style: { display: i.display, height: i.height, width: i.width } } }, i.display = i.display || "block", i.boxSizing = i.boxSizing || "border-box", fs(n)) { const e = Pe(t, "width"); void 0 !== e && (t.width = e) } if (fs(s)) if ("" === t.style.height) t.height = t.width / (e || 2); else { const e = Pe(t, "height"); void 0 !== e && (t.height = e) } }(t, e), i) : null } releaseContext(t) { const e = t.canvas; if (!e[ds]) return !1; const i = e[ds].initial;["height", "width"].forEach((t => { const n = i[t]; s(n) ? e.removeAttribute(t) : e.setAttribute(t, n) })); const n = i.style || {}; return Object.keys(n).forEach((t => { e.style[t] = n[t] })), e.width = e.width, delete e[ds], !0 } addEventListener(t, e, i) { this.removeEventListener(t, e); const s = t.$proxies || (t.$proxies = {}), n = { attach: xs, detach: bs, resize: Ms }[e] || ks; s[e] = n(t, e, i) } removeEventListener(t, e) { const i = t.$proxies || (t.$proxies = {}), s = i[e]; if (!s) return; ({ attach: ws, detach: ws, resize: ws }[e] || ps)(t, e, s), i[e] = void 0 } getDevicePixelRatio() { return window.devicePixelRatio } getMaximumSize(t, e, i, s) { return we(t, e, i, s) } isAttached(t) { const e = t && ge(t); return !(!e || !e.isConnected) } } function Ps(t) { return !fe() || "undefined" != typeof OffscreenCanvas && t instanceof OffscreenCanvas ? cs : Ss } var Ds = Object.freeze({ __proto__: null, BasePlatform: hs, BasicPlatform: cs, DomPlatform: Ss, _detectPlatform: Ps }); const Cs = "transparent", Os = { boolean: (t, e, i) => i > .5 ? e : t, color(t, e, i) { const s = Qt(t || Cs), n = s.valid && Qt(e || Cs); return n && n.valid ? n.mix(s, i).hexString() : e }, number: (t, e, i) => t + (e - t) * i }; class As { constructor(t, e, i, s) { const n = e[i]; s = Pi([t.to, s, n, t.from]); const o = Pi([t.from, n, s]); this._active = !0, this._fn = t.fn || Os[t.type || typeof o], this._easing = fi[t.easing] || fi.linear, this._start = Math.floor(Date.now() + (t.delay || 0)), this._duration = this._total = Math.floor(t.duration), this._loop = !!t.loop, this._target = e, this._prop = i, this._from = o, this._to = s, this._promises = void 0 } active() { return this._active } update(t, e, i) { if (this._active) { this._notify(!1); const s = this._target[this._prop], n = i - this._start, o = this._duration - n; this._start = i, this._duration = Math.floor(Math.max(o, t.duration)), this._total += n, this._loop = !!t.loop, this._to = Pi([t.to, e, s, t.from]), this._from = Pi([t.from, s, e]) } } cancel() { this._active && (this.tick(Date.now()), this._active = !1, this._notify(!1)) } tick(t) { const e = t - this._start, i = this._duration, s = this._prop, n = this._from, o = this._loop, a = this._to; let r; if (this._active = n !== a && (o || e < i), !this._active) return this._target[s] = a, void this._notify(!0); e < 0 ? this._target[s] = n : (r = e / i % 2, r = o && r > 1 ? 2 - r : r, r = this._easing(Math.min(1, Math.max(0, r))), this._target[s] = this._fn(n, a, r)) } wait() { const t = this._promises || (this._promises = []); return new Promise(((e, i) => { t.push({ res: e, rej: i }) })) } _notify(t) { const e = t ? "res" : "rej", i = this._promises || []; for (let t = 0; t < i.length; t++)i[t][e]() } } class Ts { constructor(t, e) { this._chart = t, this._properties = new Map, this.configure(e) } configure(t) { if (!o(t)) return; const e = Object.keys(ue.animation), i = this._properties; Object.getOwnPropertyNames(t).forEach((s => { const a = t[s]; if (!o(a)) return; const r = {}; for (const t of e) r[t] = a[t]; (n(a.properties) && a.properties || [s]).forEach((t => { t !== s && i.has(t) || i.set(t, r) })) })) } _animateOptions(t, e) { const i = e.options, s = function (t, e) { if (!e) return; let i = t.options; if (!i) return void (t.options = e); i.$shared && (t.options = i = Object.assign({}, i, { $shared: !1, $animations: {} })); return i }(t, i); if (!s) return []; const n = this._createAnimations(s, i); return i.$shared && function (t, e) { const i = [], s = Object.keys(e); for (let e = 0; e < s.length; e++) { const n = t[s[e]]; n && n.active() && i.push(n.wait()) } return Promise.all(i) }(t.options.$animations, i).then((() => { t.options = i }), (() => { })), n } _createAnimations(t, e) { const i = this._properties, s = [], n = t.$animations || (t.$animations = {}), o = Object.keys(e), a = Date.now(); let r; for (r = o.length - 1; r >= 0; --r) { const l = o[r]; if ("$" === l.charAt(0)) continue; if ("options" === l) { s.push(...this._animateOptions(t, e)); continue } const h = e[l]; let c = n[l]; const d = i.get(l); if (c) { if (d && c.active()) { c.update(d, h, a); continue } c.cancel() } d && d.duration ? (n[l] = c = new As(d, t, l, h), s.push(c)) : t[l] = h } return s } update(t, e) { if (0 === this._properties.size) return void Object.assign(t, e); const i = this._createAnimations(t, e); return i.length ? (bt.add(this._chart, i), !0) : void 0 } } function Ls(t, e) { const i = t && t.options || {}, s = i.reverse, n = void 0 === i.min ? e : 0, o = void 0 === i.max ? e : 0; return { start: s ? o : n, end: s ? n : o } } function Es(t, e) { const i = [], s = t._getSortedDatasetMetas(e); let n, o; for (n = 0, o = s.length; n < o; ++n)i.push(s[n].index); return i } function Rs(t, e, i, s = {}) { const n = t.keys, o = "single" === s.mode; let r, l, h, c; if (null === e) return; let d = !1; for (r = 0, l = n.length; r < l; ++r) { if (h = +n[r], h === i) { if (d = !0, s.all) continue; break } c = t.values[h], a(c) && (o || 0 === e || F(e) === F(c)) && (e += c) } return d || s.all ? e : 0 } function Is(t, e) { const i = t && t.options.stacked; return i || void 0 === i && void 0 !== e.stack } function zs(t, e, i) { const s = t[e] || (t[e] = {}); return s[i] || (s[i] = {}) } function Fs(t, e, i, s) { for (const n of e.getMatchingVisibleMetas(s).reverse()) { const e = t[n.index]; if (i && e > 0 || !i && e < 0) return n.index } return null } function Vs(t, e) { const { chart: i, _cachedMeta: s } = t, n = i._stacks || (i._stacks = {}), { iScale: o, vScale: a, index: r } = s, l = o.axis, h = a.axis, c = function (t, e, i) { return `${t.id}.${e.id}.${i.stack || i.type}` }(o, a, s), d = e.length; let u; for (let t = 0; t < d; ++t) { const i = e[t], { [l]: o, [h]: d } = i; u = (i._stacks || (i._stacks = {}))[h] = zs(n, c, o), u[r] = d, u._top = Fs(u, a, !0, s.type), u._bottom = Fs(u, a, !1, s.type); (u._visualValues || (u._visualValues = {}))[r] = d } } function Bs(t, e) { const i = t.scales; return Object.keys(i).filter((t => i[t].axis === e)).shift() } function Ws(t, e) { const i = t.controller.index, s = t.vScale && t.vScale.axis; if (s) { e = e || t._parsed; for (const t of e) { const e = t._stacks; if (!e || void 0 === e[s] || void 0 === e[s][i]) return; delete e[s][i], void 0 !== e[s]._visualValues && void 0 !== e[s]._visualValues[i] && delete e[s]._visualValues[i] } } } const Ns = t => "reset" === t || "none" === t, Hs = (t, e) => e ? t : Object.assign({}, t); class js { static defaults = {}; static datasetElementType = null; static dataElementType = null; constructor(t, e) { this.chart = t, this._ctx = t.ctx, this.index = e, this._cachedDataOpts = {}, this._cachedMeta = this.getMeta(), this._type = this._cachedMeta.type, this.options = void 0, this._parsing = !1, this._data = void 0, this._objectData = void 0, this._sharedOptions = void 0, this._drawStart = void 0, this._drawCount = void 0, this.enableOptionSharing = !1, this.supportsDecimation = !1, this.$context = void 0, this._syncList = [], this.datasetElementType = new.target.datasetElementType, this.dataElementType = new.target.dataElementType, this.initialize() } initialize() { const t = this._cachedMeta; this.configure(), this.linkScales(), t._stacked = Is(t.vScale, t), this.addElements(), this.options.fill && !this.chart.isPluginEnabled("filler") && console.warn("Tried to use the 'fill' option without the 'Filler' plugin enabled. Please import and register the 'Filler' plugin and make sure it is not disabled in the options") } updateIndex(t) { this.index !== t && Ws(this._cachedMeta), this.index = t } linkScales() { const t = this.chart, e = this._cachedMeta, i = this.getDataset(), s = (t, e, i, s) => "x" === t ? e : "r" === t ? s : i, n = e.xAxisID = l(i.xAxisID, Bs(t, "x")), o = e.yAxisID = l(i.yAxisID, Bs(t, "y")), a = e.rAxisID = l(i.rAxisID, Bs(t, "r")), r = e.indexAxis, h = e.iAxisID = s(r, n, o, a), c = e.vAxisID = s(r, o, n, a); e.xScale = this.getScaleForId(n), e.yScale = this.getScaleForId(o), e.rScale = this.getScaleForId(a), e.iScale = this.getScaleForId(h), e.vScale = this.getScaleForId(c) } getDataset() { return this.chart.data.datasets[this.index] } getMeta() { return this.chart.getDatasetMeta(this.index) } getScaleForId(t) { return this.chart.scales[t] } _getOtherScale(t) { const e = this._cachedMeta; return t === e.iScale ? e.vScale : e.iScale } reset() { this._update("reset") } _destroy() { const t = this._cachedMeta; this._data && rt(this._data, this), t._stacked && Ws(t) } _dataCheck() { const t = this.getDataset(), e = t.data || (t.data = []), i = this._data; if (o(e)) { const t = this._cachedMeta; this._data = function (t, e) { const { iScale: i, vScale: s } = e, n = "x" === i.axis ? "x" : "y", o = "x" === s.axis ? "x" : "y", a = Object.keys(t), r = new Array(a.length); let l, h, c; for (l = 0, h = a.length; l < h; ++l)c = a[l], r[l] = { [n]: c, [o]: t[c] }; return r }(e, t) } else if (i !== e) { if (i) { rt(i, this); const t = this._cachedMeta; Ws(t), t._parsed = [] } e && Object.isExtensible(e) && at(e, this), this._syncList = [], this._data = e } } addElements() { const t = this._cachedMeta; this._dataCheck(), this.datasetElementType && (t.dataset = new this.datasetElementType) } buildOrUpdateElements(t) { const e = this._cachedMeta, i = this.getDataset(); let s = !1; this._dataCheck(); const n = e._stacked; e._stacked = Is(e.vScale, e), e.stack !== i.stack && (s = !0, Ws(e), e.stack = i.stack), this._resyncElements(t), (s || n !== e._stacked) && (Vs(this, e._parsed), e._stacked = Is(e.vScale, e)) } configure() { const t = this.chart.config, e = t.datasetScopeKeys(this._type), i = t.getOptionScopes(this.getDataset(), e, !0); this.options = t.createResolver(i, this.getContext()), this._parsing = this.options.parsing, this._cachedDataOpts = {} } parse(t, e) { const { _cachedMeta: i, _data: s } = this, { iScale: a, _stacked: r } = i, l = a.axis; let h, c, d, u = 0 === t && e === s.length || i._sorted, f = t > 0 && i._parsed[t - 1]; if (!1 === this._parsing) i._parsed = s, i._sorted = !0, d = s; else { d = n(s[t]) ? this.parseArrayData(i, s, t, e) : o(s[t]) ? this.parseObjectData(i, s, t, e) : this.parsePrimitiveData(i, s, t, e); const a = () => null === c[l] || f && c[l] < f[l]; for (h = 0; h < e; ++h)i._parsed[h + t] = c = d[h], u && (a() && (u = !1), f = c); i._sorted = u } r && Vs(this, d) } parsePrimitiveData(t, e, i, s) { const { iScale: n, vScale: o } = t, a = n.axis, r = o.axis, l = n.getLabels(), h = n === o, c = new Array(s); let d, u, f; for (d = 0, u = s; d < u; ++d)f = d + i, c[d] = { [a]: h || n.parse(l[f], f), [r]: o.parse(e[f], f) }; return c } parseArrayData(t, e, i, s) { const { xScale: n, yScale: o } = t, a = new Array(s); let r, l, h, c; for (r = 0, l = s; r < l; ++r)h = r + i, c = e[h], a[r] = { x: n.parse(c[0], h), y: o.parse(c[1], h) }; return a } parseObjectData(t, e, i, s) { const { xScale: n, yScale: o } = t, { xAxisKey: a = "x", yAxisKey: r = "y" } = this._parsing, l = new Array(s); let h, c, d, u; for (h = 0, c = s; h < c; ++h)d = h + i, u = e[d], l[h] = { x: n.parse(M(u, a), d), y: o.parse(M(u, r), d) }; return l } getParsed(t) { return this._cachedMeta._parsed[t] } getDataElement(t) { return this._cachedMeta.data[t] } applyStack(t, e, i) { const s = this.chart, n = this._cachedMeta, o = e[t.axis]; return Rs({ keys: Es(s, !0), values: e._stacks[t.axis]._visualValues }, o, n.index, { mode: i }) } updateRangeFromParsed(t, e, i, s) { const n = i[e.axis]; let o = null === n ? NaN : n; const a = s && i._stacks[e.axis]; s && a && (s.values = a, o = Rs(s, n, this._cachedMeta.index)), t.min = Math.min(t.min, o), t.max = Math.max(t.max, o) } getMinMax(t, e) { const i = this._cachedMeta, s = i._parsed, n = i._sorted && t === i.iScale, o = s.length, r = this._getOtherScale(t), l = ((t, e, i) => t && !e.hidden && e._stacked && { keys: Es(i, !0), values: null })(e, i, this.chart), h = { min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY }, { min: c, max: d } = function (t) { const { min: e, max: i, minDefined: s, maxDefined: n } = t.getUserBounds(); return { min: s ? e : Number.NEGATIVE_INFINITY, max: n ? i : Number.POSITIVE_INFINITY } }(r); let u, f; function g() { f = s[u]; const e = f[r.axis]; return !a(f[t.axis]) || c > e || d < e } for (u = 0; u < o && (g() || (this.updateRangeFromParsed(h, t, f, l), !n)); ++u); if (n) for (u = o - 1; u >= 0; --u)if (!g()) { this.updateRangeFromParsed(h, t, f, l); break } return h } getAllParsedValues(t) { const e = this._cachedMeta._parsed, i = []; let s, n, o; for (s = 0, n = e.length; s < n; ++s)o = e[s][t.axis], a(o) && i.push(o); return i } getMaxOverflow() { return !1 } getLabelAndValue(t) { const e = this._cachedMeta, i = e.iScale, s = e.vScale, n = this.getParsed(t); return { label: i ? "" + i.getLabelForValue(n[i.axis]) : "", value: s ? "" + s.getLabelForValue(n[s.axis]) : "" } } _update(t) { const e = this._cachedMeta; this.update(t || "default"), e._clip = function (t) { let e, i, s, n; return o(t) ? (e = t.top, i = t.right, s = t.bottom, n = t.left) : e = i = s = n = t, { top: e, right: i, bottom: s, left: n, disabled: !1 === t } }(l(this.options.clip, function (t, e, i) { if (!1 === i) return !1; const s = Ls(t, i), n = Ls(e, i); return { top: n.end, right: s.end, bottom: n.start, left: s.start } }(e.xScale, e.yScale, this.getMaxOverflow()))) } update(t) { } draw() { const t = this._ctx, e = this.chart, i = this._cachedMeta, s = i.data || [], n = e.chartArea, o = [], a = this._drawStart || 0, r = this._drawCount || s.length - a, l = this.options.drawActiveElementsOnTop; let h; for (i.dataset && i.dataset.draw(t, n, a, r), h = a; h < a + r; ++h) { const e = s[h]; e.hidden || (e.active && l ? o.push(e) : e.draw(t, n)) } for (h = 0; h < o.length; ++h)o[h].draw(t, n) } getStyle(t, e) { const i = e ? "active" : "default"; return void 0 === t && this._cachedMeta.dataset ? this.resolveDatasetElementOptions(i) : this.resolveDataElementOptions(t || 0, i) } getContext(t, e, i) { const s = this.getDataset(); let n; if (t >= 0 && t < this._cachedMeta.data.length) { const e = this._cachedMeta.data[t]; n = e.$context || (e.$context = function (t, e, i) { return Ci(t, { active: !1, dataIndex: e, parsed: void 0, raw: void 0, element: i, index: e, mode: "default", type: "data" }) }(this.getContext(), t, e)), n.parsed = this.getParsed(t), n.raw = s.data[t], n.index = n.dataIndex = t } else n = this.$context || (this.$context = function (t, e) { return Ci(t, { active: !1, dataset: void 0, datasetIndex: e, index: e, mode: "default", type: "dataset" }) }(this.chart.getContext(), this.index)), n.dataset = s, n.index = n.datasetIndex = this.index; return n.active = !!e, n.mode = i, n } resolveDatasetElementOptions(t) { return this._resolveElementOptions(this.datasetElementType.id, t) } resolveDataElementOptions(t, e) { return this._resolveElementOptions(this.dataElementType.id, e, t) } _resolveElementOptions(t, e = "default", i) { const s = "active" === e, n = this._cachedDataOpts, o = t + "-" + e, a = n[o], r = this.enableOptionSharing && k(i); if (a) return Hs(a, r); const l = this.chart.config, h = l.datasetElementScopeKeys(this._type, t), c = s ? [`${t}Hover`, "hover", t, ""] : [t, ""], d = l.getOptionScopes(this.getDataset(), h), u = Object.keys(ue.elements[t]), f = l.resolveNamedOptions(d, u, (() => this.getContext(i, s, e)), c); return f.$shared && (f.$shared = r, n[o] = Object.freeze(Hs(f, r))), f } _resolveAnimations(t, e, i) { const s = this.chart, n = this._cachedDataOpts, o = `animation-${e}`, a = n[o]; if (a) return a; let r; if (!1 !== s.options.animation) { const s = this.chart.config, n = s.datasetAnimationScopeKeys(this._type, e), o = s.getOptionScopes(this.getDataset(), n); r = s.createResolver(o, this.getContext(t, i, e)) } const l = new Ts(s, r && r.animations); return r && r._cacheable && (n[o] = Object.freeze(l)), l } getSharedOptions(t) { if (t.$shared) return this._sharedOptions || (this._sharedOptions = Object.assign({}, t)) } includeOptions(t, e) { return !e || Ns(t) || this.chart._animationsDisabled } _getSharedOptions(t, e) { const i = this.resolveDataElementOptions(t, e), s = this._sharedOptions, n = this.getSharedOptions(i), o = this.includeOptions(e, n) || n !== s; return this.updateSharedOptions(n, e, i), { sharedOptions: n, includeOptions: o } } updateElement(t, e, i, s) { Ns(s) ? Object.assign(t, i) : this._resolveAnimations(e, s).update(t, i) } updateSharedOptions(t, e, i) { t && !Ns(e) && this._resolveAnimations(void 0, e).update(t, i) } _setStyle(t, e, i, s) { t.active = s; const n = this.getStyle(e, s); this._resolveAnimations(e, i, s).update(t, { options: !s && this.getSharedOptions(n) || n }) } removeHoverStyle(t, e, i) { this._setStyle(t, i, "active", !1) } setHoverStyle(t, e, i) { this._setStyle(t, i, "active", !0) } _removeDatasetHoverStyle() { const t = this._cachedMeta.dataset; t && this._setStyle(t, void 0, "active", !1) } _setDatasetHoverStyle() { const t = this._cachedMeta.dataset; t && this._setStyle(t, void 0, "active", !0) } _resyncElements(t) { const e = this._data, i = this._cachedMeta.data; for (const [t, e, i] of this._syncList) this[t](e, i); this._syncList = []; const s = i.length, n = e.length, o = Math.min(n, s); o && this.parse(0, o), n > s ? this._insertElements(s, n - s, t) : n < s && this._removeElements(n, s - n) } _insertElements(t, e, i = !0) { const s = this._cachedMeta, n = s.data, o = t + e; let a; const r = t => { for (t.length += e, a = t.length - 1; a >= o; a--)t[a] = t[a - e] }; for (r(n), a = t; a < o; ++a)n[a] = new this.dataElementType; this._parsing && r(s._parsed), this.parse(t, e), i && this.updateElements(n, t, e, "reset") } updateElements(t, e, i, s) { } _removeElements(t, e) { const i = this._cachedMeta; if (this._parsing) { const s = i._parsed.splice(t, e); i._stacked && Ws(i, s) } i.data.splice(t, e) } _sync(t) { if (this._parsing) this._syncList.push(t); else { const [e, i, s] = t; this[e](i, s) } this.chart._dataChanges.push([this.index, ...t]) } _onDataPush() { const t = arguments.length; this._sync(["_insertElements", this.getDataset().data.length - t, t]) } _onDataPop() { this._sync(["_removeElements", this._cachedMeta.data.length - 1, 1]) } _onDataShift() { this._sync(["_removeElements", 0, 1]) } _onDataSplice(t, e) { e && this._sync(["_removeElements", t, e]); const i = arguments.length - 2; i && this._sync(["_insertElements", t, i]) } _onDataUnshift() { this._sync(["_insertElements", 0, arguments.length]) } } class $s { static defaults = {}; static defaultRoutes = void 0; x; y; active = !1; options; $animations; tooltipPosition(t) { const { x: e, y: i } = this.getProps(["x", "y"], t); return { x: e, y: i } } hasValue() { return N(this.x) && N(this.y) } getProps(t, e) { const i = this.$animations; if (!e || !i) return this; const s = {}; return t.forEach((t => { s[t] = i[t] && i[t].active() ? i[t]._to : this[t] })), s } } function Ys(t, e) { const i = t.options.ticks, n = function (t) { const e = t.options.offset, i = t._tickSize(), s = t._length / i + (e ? 0 : 1), n = t._maxLength / i; return Math.floor(Math.min(s, n)) }(t), o = Math.min(i.maxTicksLimit || n, n), a = i.major.enabled ? function (t) { const e = []; let i, s; for (i = 0, s = t.length; i < s; i++)t[i].major && e.push(i); return e }(e) : [], r = a.length, l = a[0], h = a[r - 1], c = []; if (r > o) return function (t, e, i, s) { let n, o = 0, a = i[0]; for (s = Math.ceil(s), n = 0; n < t.length; n++)n === a && (e.push(t[n]), o++, a = i[o * s]) }(e, c, a, r / o), c; const d = function (t, e, i) { const s = function (t) { const e = t.length; let i, s; if (e < 2) return !1; for (s = t[0], i = 1; i < e; ++i)if (t[i] - t[i - 1] !== s) return !1; return s }(t), n = e.length / i; if (!s) return Math.max(n, 1); const o = W(s); for (let t = 0, e = o.length - 1; t < e; t++) { const e = o[t]; if (e > n) return e } return Math.max(n, 1) }(a, e, o); if (r > 0) { let t, i; const n = r > 1 ? Math.round((h - l) / (r - 1)) : null; for (Us(e, c, d, s(n) ? 0 : l - n, l), t = 0, i = r - 1; t < i; t++)Us(e, c, d, a[t], a[t + 1]); return Us(e, c, d, h, s(n) ? e.length : h + n), c } return Us(e, c, d), c } function Us(t, e, i, s, n) { const o = l(s, 0), a = Math.min(l(n, t.length), t.length); let r, h, c, d = 0; for (i = Math.ceil(i), n && (r = n - s, i = r / Math.floor(r / i)), c = o; c < 0;)d++, c = Math.round(o + d * i); for (h = Math.max(o, 0); h < a; h++)h === c && (e.push(t[h]), d++, c = Math.round(o + d * i)) } const Xs = (t, e, i) => "top" === e || "left" === e ? t[e] + i : t[e] - i, qs = (t, e) => Math.min(e || t, t); function Ks(t, e) { const i = [], s = t.length / e, n = t.length; let o = 0; for (; o < n; o += s)i.push(t[Math.floor(o)]); return i } function Gs(t, e, i) { const s = t.ticks.length, n = Math.min(e, s - 1), o = t._startPixel, a = t._endPixel, r = 1e-6; let l, h = t.getPixelForTick(n); if (!(i && (l = 1 === s ? Math.max(h - o, a - h) : 0 === e ? (t.getPixelForTick(1) - h) / 2 : (h - t.getPixelForTick(n - 1)) / 2, h += n < e ? l : -l, h < o - r || h > a + r))) return h } function Js(t) { return t.drawTicks ? t.tickLength : 0 } function Zs(t, e) { if (!t.display) return 0; const i = Si(t.font, e), s = ki(t.padding); return (n(t.text) ? t.text.length : 1) * i.lineHeight + s.height } function Qs(t, e, i) { let s = ut(t); return (i && "right" !== e || !i && "right" === e) && (s = (t => "left" === t ? "right" : "right" === t ? "left" : t)(s)), s } class tn extends $s { constructor(t) { super(), this.id = t.id, this.type = t.type, this.options = void 0, this.ctx = t.ctx, this.chart = t.chart, this.top = void 0, this.bottom = void 0, this.left = void 0, this.right = void 0, this.width = void 0, this.height = void 0, this._margins = { left: 0, right: 0, top: 0, bottom: 0 }, this.maxWidth = void 0, this.maxHeight = void 0, this.paddingTop = void 0, this.paddingBottom = void 0, this.paddingLeft = void 0, this.paddingRight = void 0, this.axis = void 0, this.labelRotation = void 0, this.min = void 0, this.max = void 0, this._range = void 0, this.ticks = [], this._gridLineItems = null, this._labelItems = null, this._labelSizes = null, this._length = 0, this._maxLength = 0, this._longestTextCache = {}, this._startPixel = void 0, this._endPixel = void 0, this._reversePixels = !1, this._userMax = void 0, this._userMin = void 0, this._suggestedMax = void 0, this._suggestedMin = void 0, this._ticksLength = 0, this._borderValue = 0, this._cache = {}, this._dataLimitsCached = !1, this.$context = void 0 } init(t) { this.options = t.setContext(this.getContext()), this.axis = t.axis, this._userMin = this.parse(t.min), this._userMax = this.parse(t.max), this._suggestedMin = this.parse(t.suggestedMin), this._suggestedMax = this.parse(t.suggestedMax) } parse(t, e) { return t } getUserBounds() { let { _userMin: t, _userMax: e, _suggestedMin: i, _suggestedMax: s } = this; return t = r(t, Number.POSITIVE_INFINITY), e = r(e, Number.NEGATIVE_INFINITY), i = r(i, Number.POSITIVE_INFINITY), s = r(s, Number.NEGATIVE_INFINITY), { min: r(t, i), max: r(e, s), minDefined: a(t), maxDefined: a(e) } } getMinMax(t) { let e, { min: i, max: s, minDefined: n, maxDefined: o } = this.getUserBounds(); if (n && o) return { min: i, max: s }; const a = this.getMatchingVisibleMetas(); for (let r = 0, l = a.length; r < l; ++r)e = a[r].controller.getMinMax(this, t), n || (i = Math.min(i, e.min)), o || (s = Math.max(s, e.max)); return i = o && i > s ? s : i, s = n && i > s ? i : s, { min: r(i, r(s, i)), max: r(s, r(i, s)) } } getPadding() { return { left: this.paddingLeft || 0, top: this.paddingTop || 0, right: this.paddingRight || 0, bottom: this.paddingBottom || 0 } } getTicks() { return this.ticks } getLabels() { const t = this.chart.data; return this.options.labels || (this.isHorizontal() ? t.xLabels : t.yLabels) || t.labels || [] } getLabelItems(t = this.chart.chartArea) { return this._labelItems || (this._labelItems = this._computeLabelItems(t)) } beforeLayout() { this._cache = {}, this._dataLimitsCached = !1 } beforeUpdate() { d(this.options.beforeUpdate, [this]) } update(t, e, i) { const { beginAtZero: s, grace: n, ticks: o } = this.options, a = o.sampleSize; this.beforeUpdate(), this.maxWidth = t, this.maxHeight = e, this._margins = i = Object.assign({ left: 0, right: 0, top: 0, bottom: 0 }, i), this.ticks = null, this._labelSizes = null, this._gridLineItems = null, this._labelItems = null, this.beforeSetDimensions(), this.setDimensions(), this.afterSetDimensions(), this._maxLength = this.isHorizontal() ? this.width + i.left + i.right : this.height + i.top + i.bottom, this._dataLimitsCached || (this.beforeDataLimits(), this.determineDataLimits(), this.afterDataLimits(), this._range = Di(this, n, s), this._dataLimitsCached = !0), this.beforeBuildTicks(), this.ticks = this.buildTicks() || [], this.afterBuildTicks(); const r = a < this.ticks.length; this._convertTicksToLabels(r ? Ks(this.ticks, a) : this.ticks), this.configure(), this.beforeCalculateLabelRotation(), this.calculateLabelRotation(), this.afterCalculateLabelRotation(), o.display && (o.autoSkip || "auto" === o.source) && (this.ticks = Ys(this, this.ticks), this._labelSizes = null, this.afterAutoSkip()), r && this._convertTicksToLabels(this.ticks), this.beforeFit(), this.fit(), this.afterFit(), this.afterUpdate() } configure() { let t, e, i = this.options.reverse; this.isHorizontal() ? (t = this.left, e = this.right) : (t = this.top, e = this.bottom, i = !i), this._startPixel = t, this._endPixel = e, this._reversePixels = i, this._length = e - t, this._alignToPixels = this.options.alignToPixels } afterUpdate() { d(this.options.afterUpdate, [this]) } beforeSetDimensions() { d(this.options.beforeSetDimensions, [this]) } setDimensions() { this.isHorizontal() ? (this.width = this.maxWidth, this.left = 0, this.right = this.width) : (this.height = this.maxHeight, this.top = 0, this.bottom = this.height), this.paddingLeft = 0, this.paddingTop = 0, this.paddingRight = 0, this.paddingBottom = 0 } afterSetDimensions() { d(this.options.afterSetDimensions, [this]) } _callHooks(t) { this.chart.notifyPlugins(t, this.getContext()), d(this.options[t], [this]) } beforeDataLimits() { this._callHooks("beforeDataLimits") } determineDataLimits() { } afterDataLimits() { this._callHooks("afterDataLimits") } beforeBuildTicks() { this._callHooks("beforeBuildTicks") } buildTicks() { return [] } afterBuildTicks() { this._callHooks("afterBuildTicks") } beforeTickToLabelConversion() { d(this.options.beforeTickToLabelConversion, [this]) } generateTickLabels(t) { const e = this.options.ticks; let i, s, n; for (i = 0, s = t.length; i < s; i++)n = t[i], n.label = d(e.callback, [n.value, i, t], this) } afterTickToLabelConversion() { d(this.options.afterTickToLabelConversion, [this]) } beforeCalculateLabelRotation() { d(this.options.beforeCalculateLabelRotation, [this]) } calculateLabelRotation() { const t = this.options, e = t.ticks, i = qs(this.ticks.length, t.ticks.maxTicksLimit), s = e.minRotation || 0, n = e.maxRotation; let o, a, r, l = s; if (!this._isVisible() || !e.display || s >= n || i <= 1 || !this.isHorizontal()) return void (this.labelRotation = s); const h = this._getLabelSizes(), c = h.widest.width, d = h.highest.height, u = Z(this.chart.width - c, 0, this.maxWidth); o = t.offset ? this.maxWidth / i : u / (i - 1), c + 6 > o && (o = u / (i - (t.offset ? .5 : 1)), a = this.maxHeight - Js(t.grid) - e.padding - Zs(t.title, this.chart.options.font), r = Math.sqrt(c * c + d * d), l = Y(Math.min(Math.asin(Z((h.highest.height + 6) / o, -1, 1)), Math.asin(Z(a / r, -1, 1)) - Math.asin(Z(d / r, -1, 1)))), l = Math.max(s, Math.min(n, l))), this.labelRotation = l } afterCalculateLabelRotation() { d(this.options.afterCalculateLabelRotation, [this]) } afterAutoSkip() { } beforeFit() { d(this.options.beforeFit, [this]) } fit() { const t = { width: 0, height: 0 }, { chart: e, options: { ticks: i, title: s, grid: n } } = this, o = this._isVisible(), a = this.isHorizontal(); if (o) { const o = Zs(s, e.options.font); if (a ? (t.width = this.maxWidth, t.height = Js(n) + o) : (t.height = this.maxHeight, t.width = Js(n) + o), i.display && this.ticks.length) { const { first: e, last: s, widest: n, highest: o } = this._getLabelSizes(), r = 2 * i.padding, l = $(this.labelRotation), h = Math.cos(l), c = Math.sin(l); if (a) { const e = i.mirror ? 0 : c * n.width + h * o.height; t.height = Math.min(this.maxHeight, t.height + e + r) } else { const e = i.mirror ? 0 : h * n.width + c * o.height; t.width = Math.min(this.maxWidth, t.width + e + r) } this._calculatePadding(e, s, c, h) } } this._handleMargins(), a ? (this.width = this._length = e.width - this._margins.left - this._margins.right, this.height = t.height) : (this.width = t.width, this.height = this._length = e.height - this._margins.top - this._margins.bottom) } _calculatePadding(t, e, i, s) { const { ticks: { align: n, padding: o }, position: a } = this.options, r = 0 !== this.labelRotation, l = "top" !== a && "x" === this.axis; if (this.isHorizontal()) { const a = this.getPixelForTick(0) - this.left, h = this.right - this.getPixelForTick(this.ticks.length - 1); let c = 0, d = 0; r ? l ? (c = s * t.width, d = i * e.height) : (c = i * t.height, d = s * e.width) : "start" === n ? d = e.width : "end" === n ? c = t.width : "inner" !== n && (c = t.width / 2, d = e.width / 2), this.paddingLeft = Math.max((c - a + o) * this.width / (this.width - a), 0), this.paddingRight = Math.max((d - h + o) * this.width / (this.width - h), 0) } else { let i = e.height / 2, s = t.height / 2; "start" === n ? (i = 0, s = t.height) : "end" === n && (i = e.height, s = 0), this.paddingTop = i + o, this.paddingBottom = s + o } } _handleMargins() { this._margins && (this._margins.left = Math.max(this.paddingLeft, this._margins.left), this._margins.top = Math.max(this.paddingTop, this._margins.top), this._margins.right = Math.max(this.paddingRight, this._margins.right), this._margins.bottom = Math.max(this.paddingBottom, this._margins.bottom)) } afterFit() { d(this.options.afterFit, [this]) } isHorizontal() { const { axis: t, position: e } = this.options; return "top" === e || "bottom" === e || "x" === t } isFullSize() { return this.options.fullSize } _convertTicksToLabels(t) { let e, i; for (this.beforeTickToLabelConversion(), this.generateTickLabels(t), e = 0, i = t.length; e < i; e++)s(t[e].label) && (t.splice(e, 1), i--, e--); this.afterTickToLabelConversion() } _getLabelSizes() { let t = this._labelSizes; if (!t) { const e = this.options.ticks.sampleSize; let i = this.ticks; e < i.length && (i = Ks(i, e)), this._labelSizes = t = this._computeLabelSizes(i, i.length, this.options.ticks.maxTicksLimit) } return t } _computeLabelSizes(t, e, i) { const { ctx: o, _longestTextCache: a } = this, r = [], l = [], h = Math.floor(e / qs(e, i)); let c, d, f, g, p, m, x, b, _, y, v, M = 0, w = 0; for (c = 0; c < e; c += h) { if (g = t[c].label, p = this._resolveTickFontOptions(c), o.font = m = p.string, x = a[m] = a[m] || { data: {}, gc: [] }, b = p.lineHeight, _ = y = 0, s(g) || n(g)) { if (n(g)) for (d = 0, f = g.length; d < f; ++d)v = g[d], s(v) || n(v) || (_ = Ce(o, x.data, x.gc, _, v), y += b) } else _ = Ce(o, x.data, x.gc, _, g), y = b; r.push(_), l.push(y), M = Math.max(_, M), w = Math.max(y, w) } !function (t, e) { u(t, (t => { const i = t.gc, s = i.length / 2; let n; if (s > e) { for (n = 0; n < s; ++n)delete t.data[i[n]]; i.splice(0, s) } })) }(a, e); const k = r.indexOf(M), S = l.indexOf(w), P = t => ({ width: r[t] || 0, height: l[t] || 0 }); return { first: P(0), last: P(e - 1), widest: P(k), highest: P(S), widths: r, heights: l } } getLabelForValue(t) { return t } getPixelForValue(t, e) { return NaN } getValueForPixel(t) { } getPixelForTick(t) { const e = this.ticks; return t < 0 || t > e.length - 1 ? null : this.getPixelForValue(e[t].value) } getPixelForDecimal(t) { this._reversePixels && (t = 1 - t); const e = this._startPixel + t * this._length; return Q(this._alignToPixels ? Ae(this.chart, e, 0) : e) } getDecimalForPixel(t) { const e = (t - this._startPixel) / this._length; return this._reversePixels ? 1 - e : e } getBasePixel() { return this.getPixelForValue(this.getBaseValue()) } getBaseValue() { const { min: t, max: e } = this; return t < 0 && e < 0 ? e : t > 0 && e > 0 ? t : 0 } getContext(t) { const e = this.ticks || []; if (t >= 0 && t < e.length) { const i = e[t]; return i.$context || (i.$context = function (t, e, i) { return Ci(t, { tick: i, index: e, type: "tick" }) }(this.getContext(), t, i)) } return this.$context || (this.$context = Ci(this.chart.getContext(), { scale: this, type: "scale" })) } _tickSize() { const t = this.options.ticks, e = $(this.labelRotation), i = Math.abs(Math.cos(e)), s = Math.abs(Math.sin(e)), n = this._getLabelSizes(), o = t.autoSkipPadding || 0, a = n ? n.widest.width + o : 0, r = n ? n.highest.height + o : 0; return this.isHorizontal() ? r * i > a * s ? a / i : r / s : r * s < a * i ? r / i : a / s } _isVisible() { const t = this.options.display; return "auto" !== t ? !!t : this.getMatchingVisibleMetas().length > 0 } _computeGridLineItems(t) { const e = this.axis, i = this.chart, s = this.options, { grid: n, position: a, border: r } = s, h = n.offset, c = this.isHorizontal(), d = this.ticks.length + (h ? 1 : 0), u = Js(n), f = [], g = r.setContext(this.getContext()), p = g.display ? g.width : 0, m = p / 2, x = function (t) { return Ae(i, t, p) }; let b, _, y, v, M, w, k, S, P, D, C, O; if ("top" === a) b = x(this.bottom), w = this.bottom - u, S = b - m, D = x(t.top) + m, O = t.bottom; else if ("bottom" === a) b = x(this.top), D = t.top, O = x(t.bottom) - m, w = b + m, S = this.top + u; else if ("left" === a) b = x(this.right), M = this.right - u, k = b - m, P = x(t.left) + m, C = t.right; else if ("right" === a) b = x(this.left), P = t.left, C = x(t.right) - m, M = b + m, k = this.left + u; else if ("x" === e) { if ("center" === a) b = x((t.top + t.bottom) / 2 + .5); else if (o(a)) { const t = Object.keys(a)[0], e = a[t]; b = x(this.chart.scales[t].getPixelForValue(e)) } D = t.top, O = t.bottom, w = b + m, S = w + u } else if ("y" === e) { if ("center" === a) b = x((t.left + t.right) / 2); else if (o(a)) { const t = Object.keys(a)[0], e = a[t]; b = x(this.chart.scales[t].getPixelForValue(e)) } M = b - m, k = M - u, P = t.left, C = t.right } const A = l(s.ticks.maxTicksLimit, d), T = Math.max(1, Math.ceil(d / A)); for (_ = 0; _ < d; _ += T) { const t = this.getContext(_), e = n.setContext(t), s = r.setContext(t), o = e.lineWidth, a = e.color, l = s.dash || [], d = s.dashOffset, u = e.tickWidth, g = e.tickColor, p = e.tickBorderDash || [], m = e.tickBorderDashOffset; y = Gs(this, _, h), void 0 !== y && (v = Ae(i, y, o), c ? M = k = P = C = v : w = S = D = O = v, f.push({ tx1: M, ty1: w, tx2: k, ty2: S, x1: P, y1: D, x2: C, y2: O, width: o, color: a, borderDash: l, borderDashOffset: d, tickWidth: u, tickColor: g, tickBorderDash: p, tickBorderDashOffset: m })) } return this._ticksLength = d, this._borderValue = b, f } _computeLabelItems(t) { const e = this.axis, i = this.options, { position: s, ticks: a } = i, r = this.isHorizontal(), l = this.ticks, { align: h, crossAlign: c, padding: d, mirror: u } = a, f = Js(i.grid), g = f + d, p = u ? -d : g, m = -$(this.labelRotation), x = []; let b, _, y, v, M, w, k, S, P, D, C, O, A = "middle"; if ("top" === s) w = this.bottom - p, k = this._getXAxisLabelAlignment(); else if ("bottom" === s) w = this.top + p, k = this._getXAxisLabelAlignment(); else if ("left" === s) { const t = this._getYAxisLabelAlignment(f); k = t.textAlign, M = t.x } else if ("right" === s) { const t = this._getYAxisLabelAlignment(f); k = t.textAlign, M = t.x } else if ("x" === e) { if ("center" === s) w = (t.top + t.bottom) / 2 + g; else if (o(s)) { const t = Object.keys(s)[0], e = s[t]; w = this.chart.scales[t].getPixelForValue(e) + g } k = this._getXAxisLabelAlignment() } else if ("y" === e) { if ("center" === s) M = (t.left + t.right) / 2 - g; else if (o(s)) { const t = Object.keys(s)[0], e = s[t]; M = this.chart.scales[t].getPixelForValue(e) } k = this._getYAxisLabelAlignment(f).textAlign } "y" === e && ("start" === h ? A = "top" : "end" === h && (A = "bottom")); const T = this._getLabelSizes(); for (b = 0, _ = l.length; b < _; ++b) { y = l[b], v = y.label; const t = a.setContext(this.getContext(b)); S = this.getPixelForTick(b) + a.labelOffset, P = this._resolveTickFontOptions(b), D = P.lineHeight, C = n(v) ? v.length : 1; const e = C / 2, i = t.color, o = t.textStrokeColor, h = t.textStrokeWidth; let d, f = k; if (r ? (M = S, "inner" === k && (f = b === _ - 1 ? this.options.reverse ? "left" : "right" : 0 === b ? this.options.reverse ? "right" : "left" : "center"), O = "top" === s ? "near" === c || 0 !== m ? -C * D + D / 2 : "center" === c ? -T.highest.height / 2 - e * D + D : -T.highest.height + D / 2 : "near" === c || 0 !== m ? D / 2 : "center" === c ? T.highest.height / 2 - e * D : T.highest.height - C * D, u && (O *= -1), 0 === m || t.showLabelBackdrop || (M += D / 2 * Math.sin(m))) : (w = S, O = (1 - C) * D / 2), t.showLabelBackdrop) { const e = ki(t.backdropPadding), i = T.heights[b], s = T.widths[b]; let n = O - e.top, o = 0 - e.left; switch (A) { case "middle": n -= i / 2; break; case "bottom": n -= i }switch (k) { case "center": o -= s / 2; break; case "right": o -= s; break; case "inner": b === _ - 1 ? o -= s : b > 0 && (o -= s / 2) }d = { left: o, top: n, width: s + e.width, height: i + e.height, color: t.backdropColor } } x.push({ label: v, font: P, textOffset: O, options: { rotation: m, color: i, strokeColor: o, strokeWidth: h, textAlign: f, textBaseline: A, translation: [M, w], backdrop: d } }) } return x } _getXAxisLabelAlignment() { const { position: t, ticks: e } = this.options; if (-$(this.labelRotation)) return "top" === t ? "left" : "right"; let i = "center"; return "start" === e.align ? i = "left" : "end" === e.align ? i = "right" : "inner" === e.align && (i = "inner"), i } _getYAxisLabelAlignment(t) { const { position: e, ticks: { crossAlign: i, mirror: s, padding: n } } = this.options, o = t + n, a = this._getLabelSizes().widest.width; let r, l; return "left" === e ? s ? (l = this.right + n, "near" === i ? r = "left" : "center" === i ? (r = "center", l += a / 2) : (r = "right", l += a)) : (l = this.right - o, "near" === i ? r = "right" : "center" === i ? (r = "center", l -= a / 2) : (r = "left", l = this.left)) : "right" === e ? s ? (l = this.left + n, "near" === i ? r = "right" : "center" === i ? (r = "center", l -= a / 2) : (r = "left", l -= a)) : (l = this.left + o, "near" === i ? r = "left" : "center" === i ? (r = "center", l += a / 2) : (r = "right", l = this.right)) : r = "right", { textAlign: r, x: l } } _computeLabelArea() { if (this.options.ticks.mirror) return; const t = this.chart, e = this.options.position; return "left" === e || "right" === e ? { top: 0, left: this.left, bottom: t.height, right: this.right } : "top" === e || "bottom" === e ? { top: this.top, left: 0, bottom: this.bottom, right: t.width } : void 0 } drawBackground() { const { ctx: t, options: { backgroundColor: e }, left: i, top: s, width: n, height: o } = this; e && (t.save(), t.fillStyle = e, t.fillRect(i, s, n, o), t.restore()) } getLineWidthForValue(t) { const e = this.options.grid; if (!this._isVisible() || !e.display) return 0; const i = this.ticks.findIndex((e => e.value === t)); if (i >= 0) { return e.setContext(this.getContext(i)).lineWidth } return 0 } drawGrid(t) { const e = this.options.grid, i = this.ctx, s = this._gridLineItems || (this._gridLineItems = this._computeGridLineItems(t)); let n, o; const a = (t, e, s) => { s.width && s.color && (i.save(), i.lineWidth = s.width, i.strokeStyle = s.color, i.setLineDash(s.borderDash || []), i.lineDashOffset = s.borderDashOffset, i.beginPath(), i.moveTo(t.x, t.y), i.lineTo(e.x, e.y), i.stroke(), i.restore()) }; if (e.display) for (n = 0, o = s.length; n < o; ++n) { const t = s[n]; e.drawOnChartArea && a({ x: t.x1, y: t.y1 }, { x: t.x2, y: t.y2 }, t), e.drawTicks && a({ x: t.tx1, y: t.ty1 }, { x: t.tx2, y: t.ty2 }, { color: t.tickColor, width: t.tickWidth, borderDash: t.tickBorderDash, borderDashOffset: t.tickBorderDashOffset }) } } drawBorder() { const { chart: t, ctx: e, options: { border: i, grid: s } } = this, n = i.setContext(this.getContext()), o = i.display ? n.width : 0; if (!o) return; const a = s.setContext(this.getContext(0)).lineWidth, r = this._borderValue; let l, h, c, d; this.isHorizontal() ? (l = Ae(t, this.left, o) - o / 2, h = Ae(t, this.right, a) + a / 2, c = d = r) : (c = Ae(t, this.top, o) - o / 2, d = Ae(t, this.bottom, a) + a / 2, l = h = r), e.save(), e.lineWidth = n.width, e.strokeStyle = n.color, e.beginPath(), e.moveTo(l, c), e.lineTo(h, d), e.stroke(), e.restore() } drawLabels(t) { if (!this.options.ticks.display) return; const e = this.ctx, i = this._computeLabelArea(); i && Ie(e, i); const s = this.getLabelItems(t); for (const t of s) { const i = t.options, s = t.font; Ne(e, t.label, 0, t.textOffset, s, i) } i && ze(e) } drawTitle() { const { ctx: t, options: { position: e, title: i, reverse: s } } = this; if (!i.display) return; const a = Si(i.font), r = ki(i.padding), l = i.align; let h = a.lineHeight / 2; "bottom" === e || "center" === e || o(e) ? (h += r.bottom, n(i.text) && (h += a.lineHeight * (i.text.length - 1))) : h += r.top; const { titleX: c, titleY: d, maxWidth: u, rotation: f } = function (t, e, i, s) { const { top: n, left: a, bottom: r, right: l, chart: h } = t, { chartArea: c, scales: d } = h; let u, f, g, p = 0; const m = r - n, x = l - a; if (t.isHorizontal()) { if (f = ft(s, a, l), o(i)) { const t = Object.keys(i)[0], s = i[t]; g = d[t].getPixelForValue(s) + m - e } else g = "center" === i ? (c.bottom + c.top) / 2 + m - e : Xs(t, i, e); u = l - a } else { if (o(i)) { const t = Object.keys(i)[0], s = i[t]; f = d[t].getPixelForValue(s) - x + e } else f = "center" === i ? (c.left + c.right) / 2 - x + e : Xs(t, i, e); g = ft(s, r, n), p = "left" === i ? -E : E } return { titleX: f, titleY: g, maxWidth: u, rotation: p } }(this, h, e, l); Ne(t, i.text, 0, 0, a, { color: i.color, maxWidth: u, rotation: f, textAlign: Qs(l, e, s), textBaseline: "middle", translation: [c, d] }) } draw(t) { this._isVisible() && (this.drawBackground(), this.drawGrid(t), this.drawBorder(), this.drawTitle(), this.drawLabels(t)) } _layers() { const t = this.options, e = t.ticks && t.ticks.z || 0, i = l(t.grid && t.grid.z, -1), s = l(t.border && t.border.z, 0); return this._isVisible() && this.draw === tn.prototype.draw ? [{ z: i, draw: t => { this.drawBackground(), this.drawGrid(t), this.drawTitle() } }, { z: s, draw: () => { this.drawBorder() } }, { z: e, draw: t => { this.drawLabels(t) } }] : [{ z: e, draw: t => { this.draw(t) } }] } getMatchingVisibleMetas(t) { const e = this.chart.getSortedVisibleDatasetMetas(), i = this.axis + "AxisID", s = []; let n, o; for (n = 0, o = e.length; n < o; ++n) { const o = e[n]; o[i] !== this.id || t && o.type !== t || s.push(o) } return s } _resolveTickFontOptions(t) { return Si(this.options.ticks.setContext(this.getContext(t)).font) } _maxDigits() { const t = this._resolveTickFontOptions(0).lineHeight; return (this.isHorizontal() ? this.width : this.height) / t } } class en { constructor(t, e, i) { this.type = t, this.scope = e, this.override = i, this.items = Object.create(null) } isForType(t) { return Object.prototype.isPrototypeOf.call(this.type.prototype, t.prototype) } register(t) { const e = Object.getPrototypeOf(t); let i; (function (t) { return "id" in t && "defaults" in t })(e) && (i = this.register(e)); const s = this.items, n = t.id, o = this.scope + "." + n; if (!n) throw new Error("class does not have id: " + t); return n in s || (s[n] = t, function (t, e, i) { const s = x(Object.create(null), [i ? ue.get(i) : {}, ue.get(e), t.defaults]); ue.set(e, s), t.defaultRoutes && function (t, e) { Object.keys(e).forEach((i => { const s = i.split("."), n = s.pop(), o = [t].concat(s).join("."), a = e[i].split("."), r = a.pop(), l = a.join("."); ue.route(o, n, l, r) })) }(e, t.defaultRoutes); t.descriptors && ue.describe(e, t.descriptors) }(t, o, i), this.override && ue.override(t.id, t.overrides)), o } get(t) { return this.items[t] } unregister(t) { const e = this.items, i = t.id, s = this.scope; i in e && delete e[i], s && i in ue[s] && (delete ue[s][i], this.override && delete re[i]) } } class sn { constructor() { this.controllers = new en(js, "datasets", !0), this.elements = new en($s, "elements"), this.plugins = new en(Object, "plugins"), this.scales = new en(tn, "scales"), this._typedRegistries = [this.controllers, this.scales, this.elements] } add(...t) { this._each("register", t) } remove(...t) { this._each("unregister", t) } addControllers(...t) { this._each("register", t, this.controllers) } addElements(...t) { this._each("register", t, this.elements) } addPlugins(...t) { this._each("register", t, this.plugins) } addScales(...t) { this._each("register", t, this.scales) } getController(t) { return this._get(t, this.controllers, "controller") } getElement(t) { return this._get(t, this.elements, "element") } getPlugin(t) { return this._get(t, this.plugins, "plugin") } getScale(t) { return this._get(t, this.scales, "scale") } removeControllers(...t) { this._each("unregister", t, this.controllers) } removeElements(...t) { this._each("unregister", t, this.elements) } removePlugins(...t) { this._each("unregister", t, this.plugins) } removeScales(...t) { this._each("unregister", t, this.scales) } _each(t, e, i) { [...e].forEach((e => { const s = i || this._getRegistryForType(e); i || s.isForType(e) || s === this.plugins && e.id ? this._exec(t, s, e) : u(e, (e => { const s = i || this._getRegistryForType(e); this._exec(t, s, e) })) })) } _exec(t, e, i) { const s = w(t); d(i["before" + s], [], i), e[t](i), d(i["after" + s], [], i) } _getRegistryForType(t) { for (let e = 0; e < this._typedRegistries.length; e++) { const i = this._typedRegistries[e]; if (i.isForType(t)) return i } return this.plugins } _get(t, e, i) { const s = e.get(t); if (void 0 === s) throw new Error('"' + t + '" is not a registered ' + i + "."); return s } } var nn = new sn; class on { constructor() { this._init = void 0 } notify(t, e, i, s) { if ("beforeInit" === e && (this._init = this._createDescriptors(t, !0), this._notify(this._init, t, "install")), void 0 === this._init) return; const n = s ? this._descriptors(t).filter(s) : this._descriptors(t), o = this._notify(n, t, e, i); return "afterDestroy" === e && (this._notify(n, t, "stop"), this._notify(this._init, t, "uninstall"), this._init = void 0), o } _notify(t, e, i, s) { s = s || {}; for (const n of t) { const t = n.plugin; if (!1 === d(t[i], [e, s, n.options], t) && s.cancelable) return !1 } return !0 } invalidate() { s(this._cache) || (this._oldCache = this._cache, this._cache = void 0) } _descriptors(t) { if (this._cache) return this._cache; const e = this._cache = this._createDescriptors(t); return this._notifyStateChanges(t), e } _createDescriptors(t, e) { const i = t && t.config, s = l(i.options && i.options.plugins, {}), n = function (t) { const e = {}, i = [], s = Object.keys(nn.plugins.items); for (let t = 0; t < s.length; t++)i.push(nn.getPlugin(s[t])); const n = t.plugins || []; for (let t = 0; t < n.length; t++) { const s = n[t]; -1 === i.indexOf(s) && (i.push(s), e[s.id] = !0) } return { plugins: i, localIds: e } }(i); return !1 !== s || e ? function (t, { plugins: e, localIds: i }, s, n) { const o = [], a = t.getContext(); for (const r of e) { const e = r.id, l = an(s[e], n); null !== l && o.push({ plugin: r, options: rn(t.config, { plugin: r, local: i[e] }, l, a) }) } return o }(t, n, s, e) : [] } _notifyStateChanges(t) { const e = this._oldCache || [], i = this._cache, s = (t, e) => t.filter((t => !e.some((e => t.plugin.id === e.plugin.id)))); this._notify(s(e, i), t, "stop"), this._notify(s(i, e), t, "start") } } function an(t, e) { return e || !1 !== t ? !0 === t ? {} : t : null } function rn(t, { plugin: e, local: i }, s, n) { const o = t.pluginScopeKeys(e), a = t.getOptionScopes(s, o); return i && e.defaults && a.push(e.defaults), t.createResolver(a, n, [""], { scriptable: !1, indexable: !1, allKeys: !0 }) } function ln(t, e) { const i = ue.datasets[t] || {}; return ((e.datasets || {})[t] || {}).indexAxis || e.indexAxis || i.indexAxis || "x" } function hn(t) { if ("x" === t || "y" === t || "r" === t) return t } function cn(t, ...e) { if (hn(t)) return t; for (const s of e) { const e = s.axis || ("top" === (i = s.position) || "bottom" === i ? "x" : "left" === i || "right" === i ? "y" : void 0) || t.length > 1 && hn(t[0].toLowerCase()); if (e) return e } var i; throw new Error(`Cannot determine type of '${t}' axis. Please provide 'axis' or 'position' option.`) } function dn(t, e, i) { if (i[e + "AxisID"] === t) return { axis: e } } function un(t, e) { const i = re[t.type] || { scales: {} }, s = e.scales || {}, n = ln(t.type, e), a = Object.create(null); return Object.keys(s).forEach((e => { const r = s[e]; if (!o(r)) return console.error(`Invalid scale configuration for scale: ${e}`); if (r._proxy) return console.warn(`Ignoring resolver passed as options for scale: ${e}`); const l = cn(e, r, function (t, e) { if (e.data && e.data.datasets) { const i = e.data.datasets.filter((e => e.xAxisID === t || e.yAxisID === t)); if (i.length) return dn(t, "x", i[0]) || dn(t, "y", i[0]) } return {} }(e, t), ue.scales[r.type]), h = function (t, e) { return t === e ? "_index_" : "_value_" }(l, n), c = i.scales || {}; a[e] = b(Object.create(null), [{ axis: l }, r, c[l], c[h]]) })), t.data.datasets.forEach((i => { const n = i.type || t.type, o = i.indexAxis || ln(n, e), r = (re[n] || {}).scales || {}; Object.keys(r).forEach((t => { const e = function (t, e) { let i = t; return "_index_" === t ? i = e : "_value_" === t && (i = "x" === e ? "y" : "x"), i }(t, o), n = i[e + "AxisID"] || e; a[n] = a[n] || Object.create(null), b(a[n], [{ axis: e }, s[n], r[t]]) })) })), Object.keys(a).forEach((t => { const e = a[t]; b(e, [ue.scales[e.type], ue.scale]) })), a } function fn(t) { const e = t.options || (t.options = {}); e.plugins = l(e.plugins, {}), e.scales = un(t, e) } function gn(t) { return (t = t || {}).datasets = t.datasets || [], t.labels = t.labels || [], t } const pn = new Map, mn = new Set; function xn(t, e) { let i = pn.get(t); return i || (i = e(), pn.set(t, i), mn.add(i)), i } const bn = (t, e, i) => { const s = M(e, i); void 0 !== s && t.add(s) }; class _n { constructor(t) { this._config = function (t) { return (t = t || {}).data = gn(t.data), fn(t), t }(t), this._scopeCache = new Map, this._resolverCache = new Map } get platform() { return this._config.platform } get type() { return this._config.type } set type(t) { this._config.type = t } get data() { return this._config.data } set data(t) { this._config.data = gn(t) } get options() { return this._config.options } set options(t) { this._config.options = t } get plugins() { return this._config.plugins } update() { const t = this._config; this.clearCache(), fn(t) } clearCache() { this._scopeCache.clear(), this._resolverCache.clear() } datasetScopeKeys(t) { return xn(t, (() => [[`datasets.${t}`, ""]])) } datasetAnimationScopeKeys(t, e) { return xn(`${t}.transition.${e}`, (() => [[`datasets.${t}.transitions.${e}`, `transitions.${e}`], [`datasets.${t}`, ""]])) } datasetElementScopeKeys(t, e) { return xn(`${t}-${e}`, (() => [[`datasets.${t}.elements.${e}`, `datasets.${t}`, `elements.${e}`, ""]])) } pluginScopeKeys(t) { const e = t.id; return xn(`${this.type}-plugin-${e}`, (() => [[`plugins.${e}`, ...t.additionalOptionScopes || []]])) } _cachedScopes(t, e) { const i = this._scopeCache; let s = i.get(t); return s && !e || (s = new Map, i.set(t, s)), s } getOptionScopes(t, e, i) { const { options: s, type: n } = this, o = this._cachedScopes(t, i), a = o.get(e); if (a) return a; const r = new Set; e.forEach((e => { t && (r.add(t), e.forEach((e => bn(r, t, e)))), e.forEach((t => bn(r, s, t))), e.forEach((t => bn(r, re[n] || {}, t))), e.forEach((t => bn(r, ue, t))), e.forEach((t => bn(r, le, t))) })); const l = Array.from(r); return 0 === l.length && l.push(Object.create(null)), mn.has(e) && o.set(e, l), l } chartOptionScopes() { const { options: t, type: e } = this; return [t, re[e] || {}, ue.datasets[e] || {}, { type: e }, ue, le] } resolveNamedOptions(t, e, i, s = [""]) { const o = { $shared: !0 }, { resolver: a, subPrefixes: r } = yn(this._resolverCache, t, s); let l = a; if (function (t, e) { const { isScriptable: i, isIndexable: s } = Ye(t); for (const o of e) { const e = i(o), a = s(o), r = (a || e) && t[o]; if (e && (S(r) || vn(r)) || a && n(r)) return !0 } return !1 }(a, e)) { o.$shared = !1; l = $e(a, i = S(i) ? i() : i, this.createResolver(t, i, r)) } for (const t of e) o[t] = l[t]; return o } createResolver(t, e, i = [""], s) { const { resolver: n } = yn(this._resolverCache, t, i); return o(e) ? $e(n, e, void 0, s) : n } } function yn(t, e, i) { let s = t.get(e); s || (s = new Map, t.set(e, s)); const n = i.join(); let o = s.get(n); if (!o) { o = { resolver: je(e, i), subPrefixes: i.filter((t => !t.toLowerCase().includes("hover"))) }, s.set(n, o) } return o } const vn = t => o(t) && Object.getOwnPropertyNames(t).some((e => S(t[e]))); const Mn = ["top", "bottom", "left", "right", "chartArea"]; function wn(t, e) { return "top" === t || "bottom" === t || -1 === Mn.indexOf(t) && "x" === e } function kn(t, e) { return function (i, s) { return i[t] === s[t] ? i[e] - s[e] : i[t] - s[t] } } function Sn(t) { const e = t.chart, i = e.options.animation; e.notifyPlugins("afterRender"), d(i && i.onComplete, [t], e) } function Pn(t) { const e = t.chart, i = e.options.animation; d(i && i.onProgress, [t], e) } function Dn(t) { return fe() && "string" == typeof t ? t = document.getElementById(t) : t && t.length && (t = t[0]), t && t.canvas && (t = t.canvas), t } const Cn = {}, On = t => { const e = Dn(t); return Object.values(Cn).filter((t => t.canvas === e)).pop() }; function An(t, e, i) { const s = Object.keys(t); for (const n of s) { const s = +n; if (s >= e) { const o = t[n]; delete t[n], (i > 0 || s > e) && (t[s + i] = o) } } } class Tn { static defaults = ue; static instances = Cn; static overrides = re; static registry = nn; static version = "4.5.1"; static getChart = On; static register(...t) { nn.add(...t), Ln() } static unregister(...t) { nn.remove(...t), Ln() } constructor(t, e) { const s = this.config = new _n(e), n = Dn(t), o = On(n); if (o) throw new Error("Canvas is already in use. Chart with ID '" + o.id + "' must be destroyed before the canvas with ID '" + o.canvas.id + "' can be reused."); const a = s.createResolver(s.chartOptionScopes(), this.getContext()); this.platform = new (s.platform || Ps(n)), this.platform.updateConfig(s); const r = this.platform.acquireContext(n, a.aspectRatio), l = r && r.canvas, h = l && l.height, c = l && l.width; this.id = i(), this.ctx = r, this.canvas = l, this.width = c, this.height = h, this._options = a, this._aspectRatio = this.aspectRatio, this._layers = [], this._metasets = [], this._stacks = void 0, this.boxes = [], this.currentDevicePixelRatio = void 0, this.chartArea = void 0, this._active = [], this._lastEvent = void 0, this._listeners = {}, this._responsiveListeners = void 0, this._sortedMetasets = [], this.scales = {}, this._plugins = new on, this.$proxies = {}, this._hiddenIndices = {}, this.attached = !1, this._animationsDisabled = void 0, this.$context = void 0, this._doResize = dt((t => this.update(t)), a.resizeDelay || 0), this._dataChanges = [], Cn[this.id] = this, r && l ? (bt.listen(this, "complete", Sn), bt.listen(this, "progress", Pn), this._initialize(), this.attached && this.update()) : console.error("Failed to create chart: can't acquire context from the given item") } get aspectRatio() { const { options: { aspectRatio: t, maintainAspectRatio: e }, width: i, height: n, _aspectRatio: o } = this; return s(t) ? e && o ? o : n ? i / n : null : t } get data() { return this.config.data } set data(t) { this.config.data = t } get options() { return this._options } set options(t) { this.config.options = t } get registry() { return nn } _initialize() { return this.notifyPlugins("beforeInit"), this.options.responsive ? this.resize() : ke(this, this.options.devicePixelRatio), this.bindEvents(), this.notifyPlugins("afterInit"), this } clear() { return Te(this.canvas, this.ctx), this } stop() { return bt.stop(this), this } resize(t, e) { bt.running(this) ? this._resizeBeforeDraw = { width: t, height: e } : this._resize(t, e) } _resize(t, e) { const i = this.options, s = this.canvas, n = i.maintainAspectRatio && this.aspectRatio, o = this.platform.getMaximumSize(s, t, e, n), a = i.devicePixelRatio || this.platform.getDevicePixelRatio(), r = this.width ? "resize" : "attach"; this.width = o.width, this.height = o.height, this._aspectRatio = this.aspectRatio, ke(this, a, !0) && (this.notifyPlugins("resize", { size: o }), d(i.onResize, [this, o], this), this.attached && this._doResize(r) && this.render()) } ensureScalesHaveIDs() { u(this.options.scales || {}, ((t, e) => { t.id = e })) } buildOrUpdateScales() { const t = this.options, e = t.scales, i = this.scales, s = Object.keys(i).reduce(((t, e) => (t[e] = !1, t)), {}); let n = []; e && (n = n.concat(Object.keys(e).map((t => { const i = e[t], s = cn(t, i), n = "r" === s, o = "x" === s; return { options: i, dposition: n ? "chartArea" : o ? "bottom" : "left", dtype: n ? "radialLinear" : o ? "category" : "linear" } })))), u(n, (e => { const n = e.options, o = n.id, a = cn(o, n), r = l(n.type, e.dtype); void 0 !== n.position && wn(n.position, a) === wn(e.dposition) || (n.position = e.dposition), s[o] = !0; let h = null; if (o in i && i[o].type === r) h = i[o]; else { h = new (nn.getScale(r))({ id: o, type: r, ctx: this.ctx, chart: this }), i[h.id] = h } h.init(n, t) })), u(s, ((t, e) => { t || delete i[e] })), u(i, (t => { ls.configure(this, t, t.options), ls.addBox(this, t) })) } _updateMetasets() { const t = this._metasets, e = this.data.datasets.length, i = t.length; if (t.sort(((t, e) => t.index - e.index)), i > e) { for (let t = e; t < i; ++t)this._destroyDatasetMeta(t); t.splice(e, i - e) } this._sortedMetasets = t.slice(0).sort(kn("order", "index")) } _removeUnreferencedMetasets() { const { _metasets: t, data: { datasets: e } } = this; t.length > e.length && delete this._stacks, t.forEach(((t, i) => { 0 === e.filter((e => e === t._dataset)).length && this._destroyDatasetMeta(i) })) } buildOrUpdateControllers() { const t = [], e = this.data.datasets; let i, s; for (this._removeUnreferencedMetasets(), i = 0, s = e.length; i < s; i++) { const s = e[i]; let n = this.getDatasetMeta(i); const o = s.type || this.config.type; if (n.type && n.type !== o && (this._destroyDatasetMeta(i), n = this.getDatasetMeta(i)), n.type = o, n.indexAxis = s.indexAxis || ln(o, this.options), n.order = s.order || 0, n.index = i, n.label = "" + s.label, n.visible = this.isDatasetVisible(i), n.controller) n.controller.updateIndex(i), n.controller.linkScales(); else { const e = nn.getController(o), { datasetElementType: s, dataElementType: a } = ue.datasets[o]; Object.assign(e, { dataElementType: nn.getElement(a), datasetElementType: s && nn.getElement(s) }), n.controller = new e(this, i), t.push(n.controller) } } return this._updateMetasets(), t } _resetElements() { u(this.data.datasets, ((t, e) => { this.getDatasetMeta(e).controller.reset() }), this) } reset() { this._resetElements(), this.notifyPlugins("reset") } update(t) { const e = this.config; e.update(); const i = this._options = e.createResolver(e.chartOptionScopes(), this.getContext()), s = this._animationsDisabled = !i.animation; if (this._updateScales(), this._checkEventBindings(), this._updateHiddenIndices(), this._plugins.invalidate(), !1 === this.notifyPlugins("beforeUpdate", { mode: t, cancelable: !0 })) return; const n = this.buildOrUpdateControllers(); this.notifyPlugins("beforeElementsUpdate"); let o = 0; for (let t = 0, e = this.data.datasets.length; t < e; t++) { const { controller: e } = this.getDatasetMeta(t), i = !s && -1 === n.indexOf(e); e.buildOrUpdateElements(i), o = Math.max(+e.getMaxOverflow(), o) } o = this._minPadding = i.layout.autoPadding ? o : 0, this._updateLayout(o), s || u(n, (t => { t.reset() })), this._updateDatasets(t), this.notifyPlugins("afterUpdate", { mode: t }), this._layers.sort(kn("z", "_idx")); const { _active: a, _lastEvent: r } = this; r ? this._eventHandler(r, !0) : a.length && this._updateHoverStyles(a, a, !0), this.render() } _updateScales() { u(this.scales, (t => { ls.removeBox(this, t) })), this.ensureScalesHaveIDs(), this.buildOrUpdateScales() } _checkEventBindings() { const t = this.options, e = new Set(Object.keys(this._listeners)), i = new Set(t.events); P(e, i) && !!this._responsiveListeners === t.responsive || (this.unbindEvents(), this.bindEvents()) } _updateHiddenIndices() { const { _hiddenIndices: t } = this, e = this._getUniformDataChanges() || []; for (const { method: i, start: s, count: n } of e) { An(t, s, "_removeElements" === i ? -n : n) } } _getUniformDataChanges() { const t = this._dataChanges; if (!t || !t.length) return; this._dataChanges = []; const e = this.data.datasets.length, i = e => new Set(t.filter((t => t[0] === e)).map(((t, e) => e + "," + t.splice(1).join(",")))), s = i(0); for (let t = 1; t < e; t++)if (!P(s, i(t))) return; return Array.from(s).map((t => t.split(","))).map((t => ({ method: t[1], start: +t[2], count: +t[3] }))) } _updateLayout(t) { if (!1 === this.notifyPlugins("beforeLayout", { cancelable: !0 })) return; ls.update(this, this.width, this.height, t); const e = this.chartArea, i = e.width <= 0 || e.height <= 0; this._layers = [], u(this.boxes, (t => { i && "chartArea" === t.position || (t.configure && t.configure(), this._layers.push(...t._layers())) }), this), this._layers.forEach(((t, e) => { t._idx = e })), this.notifyPlugins("afterLayout") } _updateDatasets(t) { if (!1 !== this.notifyPlugins("beforeDatasetsUpdate", { mode: t, cancelable: !0 })) { for (let t = 0, e = this.data.datasets.length; t < e; ++t)this.getDatasetMeta(t).controller.configure(); for (let e = 0, i = this.data.datasets.length; e < i; ++e)this._updateDataset(e, S(t) ? t({ datasetIndex: e }) : t); this.notifyPlugins("afterDatasetsUpdate", { mode: t }) } } _updateDataset(t, e) { const i = this.getDatasetMeta(t), s = { meta: i, index: t, mode: e, cancelable: !0 }; !1 !== this.notifyPlugins("beforeDatasetUpdate", s) && (i.controller._update(e), s.cancelable = !1, this.notifyPlugins("afterDatasetUpdate", s)) } render() { !1 !== this.notifyPlugins("beforeRender", { cancelable: !0 }) && (bt.has(this) ? this.attached && !bt.running(this) && bt.start(this) : (this.draw(), Sn({ chart: this }))) } draw() { let t; if (this._resizeBeforeDraw) { const { width: t, height: e } = this._resizeBeforeDraw; this._resizeBeforeDraw = null, this._resize(t, e) } if (this.clear(), this.width <= 0 || this.height <= 0) return; if (!1 === this.notifyPlugins("beforeDraw", { cancelable: !0 })) return; const e = this._layers; for (t = 0; t < e.length && e[t].z <= 0; ++t)e[t].draw(this.chartArea); for (this._drawDatasets(); t < e.length; ++t)e[t].draw(this.chartArea); this.notifyPlugins("afterDraw") } _getSortedDatasetMetas(t) { const e = this._sortedMetasets, i = []; let s, n; for (s = 0, n = e.length; s < n; ++s) { const n = e[s]; t && !n.visible || i.push(n) } return i } getSortedVisibleDatasetMetas() { return this._getSortedDatasetMetas(!0) } _drawDatasets() { if (!1 === this.notifyPlugins("beforeDatasetsDraw", { cancelable: !0 })) return; const t = this.getSortedVisibleDatasetMetas(); for (let e = t.length - 1; e >= 0; --e)this._drawDataset(t[e]); this.notifyPlugins("afterDatasetsDraw") } _drawDataset(t) { const e = this.ctx, i = { meta: t, index: t.index, cancelable: !0 }, s = Ni(this, t); !1 !== this.notifyPlugins("beforeDatasetDraw", i) && (s && Ie(e, s), t.controller.draw(), s && ze(e), i.cancelable = !1, this.notifyPlugins("afterDatasetDraw", i)) } isPointInArea(t) { return Re(t, this.chartArea, this._minPadding) } getElementsAtEventForMode(t, e, i, s) { const n = Ki.modes[e]; return "function" == typeof n ? n(this, t, i, s) : [] } getDatasetMeta(t) { const e = this.data.datasets[t], i = this._metasets; let s = i.filter((t => t && t._dataset === e)).pop(); return s || (s = { type: null, data: [], dataset: null, controller: null, hidden: null, xAxisID: null, yAxisID: null, order: e && e.order || 0, index: t, _dataset: e, _parsed: [], _sorted: !1 }, i.push(s)), s } getContext() { return this.$context || (this.$context = Ci(null, { chart: this, type: "chart" })) } getVisibleDatasetCount() { return this.getSortedVisibleDatasetMetas().length } isDatasetVisible(t) { const e = this.data.datasets[t]; if (!e) return !1; const i = this.getDatasetMeta(t); return "boolean" == typeof i.hidden ? !i.hidden : !e.hidden } setDatasetVisibility(t, e) { this.getDatasetMeta(t).hidden = !e } toggleDataVisibility(t) { this._hiddenIndices[t] = !this._hiddenIndices[t] } getDataVisibility(t) { return !this._hiddenIndices[t] } _updateVisibility(t, e, i) { const s = i ? "show" : "hide", n = this.getDatasetMeta(t), o = n.controller._resolveAnimations(void 0, s); k(e) ? (n.data[e].hidden = !i, this.update()) : (this.setDatasetVisibility(t, i), o.update(n, { visible: i }), this.update((e => e.datasetIndex === t ? s : void 0))) } hide(t, e) { this._updateVisibility(t, e, !1) } show(t, e) { this._updateVisibility(t, e, !0) } _destroyDatasetMeta(t) { const e = this._metasets[t]; e && e.controller && e.controller._destroy(), delete this._metasets[t] } _stop() { let t, e; for (this.stop(), bt.remove(this), t = 0, e = this.data.datasets.length; t < e; ++t)this._destroyDatasetMeta(t) } destroy() { this.notifyPlugins("beforeDestroy"); const { canvas: t, ctx: e } = this; this._stop(), this.config.clearCache(), t && (this.unbindEvents(), Te(t, e), this.platform.releaseContext(e), this.canvas = null, this.ctx = null), delete Cn[this.id], this.notifyPlugins("afterDestroy") } toBase64Image(...t) { return this.canvas.toDataURL(...t) } bindEvents() { this.bindUserEvents(), this.options.responsive ? this.bindResponsiveEvents() : this.attached = !0 } bindUserEvents() { const t = this._listeners, e = this.platform, i = (i, s) => { e.addEventListener(this, i, s), t[i] = s }, s = (t, e, i) => { t.offsetX = e, t.offsetY = i, this._eventHandler(t) }; u(this.options.events, (t => i(t, s))) } bindResponsiveEvents() { this._responsiveListeners || (this._responsiveListeners = {}); const t = this._responsiveListeners, e = this.platform, i = (i, s) => { e.addEventListener(this, i, s), t[i] = s }, s = (i, s) => { t[i] && (e.removeEventListener(this, i, s), delete t[i]) }, n = (t, e) => { this.canvas && this.resize(t, e) }; let o; const a = () => { s("attach", a), this.attached = !0, this.resize(), i("resize", n), i("detach", o) }; o = () => { this.attached = !1, s("resize", n), this._stop(), this._resize(0, 0), i("attach", a) }, e.isAttached(this.canvas) ? a() : o() } unbindEvents() { u(this._listeners, ((t, e) => { this.platform.removeEventListener(this, e, t) })), this._listeners = {}, u(this._responsiveListeners, ((t, e) => { this.platform.removeEventListener(this, e, t) })), this._responsiveListeners = void 0 } updateHoverStyle(t, e, i) { const s = i ? "set" : "remove"; let n, o, a, r; for ("dataset" === e && (n = this.getDatasetMeta(t[0].datasetIndex), n.controller["_" + s + "DatasetHoverStyle"]()), a = 0, r = t.length; a < r; ++a) { o = t[a]; const e = o && this.getDatasetMeta(o.datasetIndex).controller; e && e[s + "HoverStyle"](o.element, o.datasetIndex, o.index) } } getActiveElements() { return this._active || [] } setActiveElements(t) { const e = this._active || [], i = t.map((({ datasetIndex: t, index: e }) => { const i = this.getDatasetMeta(t); if (!i) throw new Error("No dataset found at index " + t); return { datasetIndex: t, element: i.data[e], index: e } })); !f(i, e) && (this._active = i, this._lastEvent = null, this._updateHoverStyles(i, e)) } notifyPlugins(t, e, i) { return this._plugins.notify(this, t, e, i) } isPluginEnabled(t) { return 1 === this._plugins._cache.filter((e => e.plugin.id === t)).length } _updateHoverStyles(t, e, i) { const s = this.options.hover, n = (t, e) => t.filter((t => !e.some((e => t.datasetIndex === e.datasetIndex && t.index === e.index)))), o = n(e, t), a = i ? t : n(t, e); o.length && this.updateHoverStyle(o, s.mode, !1), a.length && s.mode && this.updateHoverStyle(a, s.mode, !0) } _eventHandler(t, e) { const i = { event: t, replay: e, cancelable: !0, inChartArea: this.isPointInArea(t) }, s = e => (e.options.events || this.options.events).includes(t.native.type); if (!1 === this.notifyPlugins("beforeEvent", i, s)) return; const n = this._handleEvent(t, e, i.inChartArea); return i.cancelable = !1, this.notifyPlugins("afterEvent", i, s), (n || i.changed) && this.render(), this } _handleEvent(t, e, i) { const { _active: s = [], options: n } = this, o = e, a = this._getActiveElements(t, s, i, o), r = D(t), l = function (t, e, i, s) { return i && "mouseout" !== t.type ? s ? e : t : null }(t, this._lastEvent, i, r); i && (this._lastEvent = null, d(n.onHover, [t, a, this], this), r && d(n.onClick, [t, a, this], this)); const h = !f(a, s); return (h || e) && (this._active = a, this._updateHoverStyles(a, s, e)), this._lastEvent = l, h } _getActiveElements(t, e, i, s) { if ("mouseout" === t.type) return []; if (!i) return e; const n = this.options.hover; return this.getElementsAtEventForMode(t, n.mode, n, s) } } function Ln() { return u(Tn.instances, (t => t._plugins.invalidate())) } function En() { throw new Error("This method is not implemented: Check that a complete date adapter is provided.") } class Rn { static override(t) { Object.assign(Rn.prototype, t) } options; constructor(t) { this.options = t || {} } init() { } formats() { return En() } parse() { return En() } format() { return En() } add() { return En() } diff() { return En() } startOf() { return En() } endOf() { return En() } } var In = { _date: Rn }; function zn(t) { const e = t.iScale, i = function (t, e) { if (!t._cache.$bar) { const i = t.getMatchingVisibleMetas(e); let s = []; for (let e = 0, n = i.length; e < n; e++)s = s.concat(i[e].controller.getAllParsedValues(t)); t._cache.$bar = lt(s.sort(((t, e) => t - e))) } return t._cache.$bar }(e, t.type); let s, n, o, a, r = e._length; const l = () => { 32767 !== o && -32768 !== o && (k(a) && (r = Math.min(r, Math.abs(o - a) || r)), a = o) }; for (s = 0, n = i.length; s < n; ++s)o = e.getPixelForValue(i[s]), l(); for (a = void 0, s = 0, n = e.ticks.length; s < n; ++s)o = e.getPixelForTick(s), l(); return r } function Fn(t, e, i, s) { return n(t) ? function (t, e, i, s) { const n = i.parse(t[0], s), o = i.parse(t[1], s), a = Math.min(n, o), r = Math.max(n, o); let l = a, h = r; Math.abs(a) > Math.abs(r) && (l = r, h = a), e[i.axis] = h, e._custom = { barStart: l, barEnd: h, start: n, end: o, min: a, max: r } }(t, e, i, s) : e[i.axis] = i.parse(t, s), e } function Vn(t, e, i, s) { const n = t.iScale, o = t.vScale, a = n.getLabels(), r = n === o, l = []; let h, c, d, u; for (h = i, c = i + s; h < c; ++h)u = e[h], d = {}, d[n.axis] = r || n.parse(a[h], h), l.push(Fn(u, d, o, h)); return l } function Bn(t) { return t && void 0 !== t.barStart && void 0 !== t.barEnd } function Wn(t, e, i, s) { let n = e.borderSkipped; const o = {}; if (!n) return void (t.borderSkipped = o); if (!0 === n) return void (t.borderSkipped = { top: !0, right: !0, bottom: !0, left: !0 }); const { start: a, end: r, reverse: l, top: h, bottom: c } = function (t) { let e, i, s, n, o; return t.horizontal ? (e = t.base > t.x, i = "left", s = "right") : (e = t.base < t.y, i = "bottom", s = "top"), e ? (n = "end", o = "start") : (n = "start", o = "end"), { start: i, end: s, reverse: e, top: n, bottom: o } }(t); "middle" === n && i && (t.enableBorderRadius = !0, (i._top || 0) === s ? n = h : (i._bottom || 0) === s ? n = c : (o[Nn(c, a, r, l)] = !0, n = h)), o[Nn(n, a, r, l)] = !0, t.borderSkipped = o } function Nn(t, e, i, s) { var n, o, a; return s ? (a = i, t = Hn(t = (n = t) === (o = e) ? a : n === a ? o : n, i, e)) : t = Hn(t, e, i), t } function Hn(t, e, i) { return "start" === t ? e : "end" === t ? i : t } function jn(t, { inflateAmount: e }, i) { t.inflateAmount = "auto" === e ? 1 === i ? .33 : 0 : e } class $n extends js { static id = "doughnut"; static defaults = { datasetElementType: !1, dataElementType: "arc", animation: { animateRotate: !0, animateScale: !1 }, animations: { numbers: { type: "number", properties: ["circumference", "endAngle", "innerRadius", "outerRadius", "startAngle", "x", "y", "offset", "borderWidth", "spacing"] } }, cutout: "50%", rotation: 0, circumference: 360, radius: "100%", spacing: 0, indexAxis: "r" }; static descriptors = { _scriptable: t => "spacing" !== t, _indexable: t => "spacing" !== t && !t.startsWith("borderDash") && !t.startsWith("hoverBorderDash") }; static overrides = { aspectRatio: 1, plugins: { legend: { labels: { generateLabels(t) { const e = t.data, { labels: { pointStyle: i, textAlign: s, color: n, useBorderRadius: o, borderRadius: a } } = t.legend.options; return e.labels.length && e.datasets.length ? e.labels.map(((e, r) => { const l = t.getDatasetMeta(0).controller.getStyle(r); return { text: e, fillStyle: l.backgroundColor, fontColor: n, hidden: !t.getDataVisibility(r), lineDash: l.borderDash, lineDashOffset: l.borderDashOffset, lineJoin: l.borderJoinStyle, lineWidth: l.borderWidth, strokeStyle: l.borderColor, textAlign: s, pointStyle: i, borderRadius: o && (a || l.borderRadius), index: r } })) : [] } }, onClick(t, e, i) { i.chart.toggleDataVisibility(e.index), i.chart.update() } } } }; constructor(t, e) { super(t, e), this.enableOptionSharing = !0, this.innerRadius = void 0, this.outerRadius = void 0, this.offsetX = void 0, this.offsetY = void 0 } linkScales() { } parse(t, e) { const i = this.getDataset().data, s = this._cachedMeta; if (!1 === this._parsing) s._parsed = i; else { let n, a, r = t => +i[t]; if (o(i[t])) { const { key: t = "value" } = this._parsing; r = e => +M(i[e], t) } for (n = t, a = t + e; n < a; ++n)s._parsed[n] = r(n) } } _getRotation() { return $(this.options.rotation - 90) } _getCircumference() { return $(this.options.circumference) } _getRotationExtents() { let t = O, e = -O; for (let i = 0; i < this.chart.data.datasets.length; ++i)if (this.chart.isDatasetVisible(i) && this.chart.getDatasetMeta(i).type === this._type) { const s = this.chart.getDatasetMeta(i).controller, n = s._getRotation(), o = s._getCircumference(); t = Math.min(t, n), e = Math.max(e, n + o) } return { rotation: t, circumference: e - t } } update(t) { const e = this.chart, { chartArea: i } = e, s = this._cachedMeta, n = s.data, o = this.getMaxBorderWidth() + this.getMaxOffset(n) + this.options.spacing, a = Math.max((Math.min(i.width, i.height) - o) / 2, 0), r = Math.min(h(this.options.cutout, a), 1), l = this._getRingWeight(this.index), { circumference: d, rotation: u } = this._getRotationExtents(), { ratioX: f, ratioY: g, offsetX: p, offsetY: m } = function (t, e, i) { let s = 1, n = 1, o = 0, a = 0; if (e < O) { const r = t, l = r + e, h = Math.cos(r), c = Math.sin(r), d = Math.cos(l), u = Math.sin(l), f = (t, e, s) => J(t, r, l, !0) ? 1 : Math.max(e, e * i, s, s * i), g = (t, e, s) => J(t, r, l, !0) ? -1 : Math.min(e, e * i, s, s * i), p = f(0, h, d), m = f(E, c, u), x = g(C, h, d), b = g(C + E, c, u); s = (p - x) / 2, n = (m - b) / 2, o = -(p + x) / 2, a = -(m + b) / 2 } return { ratioX: s, ratioY: n, offsetX: o, offsetY: a } }(u, d, r), x = (i.width - o) / f, b = (i.height - o) / g, _ = Math.max(Math.min(x, b) / 2, 0), y = c(this.options.radius, _), v = (y - Math.max(y * r, 0)) / this._getVisibleDatasetWeightTotal(); this.offsetX = p * y, this.offsetY = m * y, s.total = this.calculateTotal(), this.outerRadius = y - v * this._getRingWeightOffset(this.index), this.innerRadius = Math.max(this.outerRadius - v * l, 0), this.updateElements(n, 0, n.length, t) } _circumference(t, e) { const i = this.options, s = this._cachedMeta, n = this._getCircumference(); return e && i.animation.animateRotate || !this.chart.getDataVisibility(t) || null === s._parsed[t] || s.data[t].hidden ? 0 : this.calculateCircumference(s._parsed[t] * n / O) } updateElements(t, e, i, s) { const n = "reset" === s, o = this.chart, a = o.chartArea, r = o.options.animation, l = (a.left + a.right) / 2, h = (a.top + a.bottom) / 2, c = n && r.animateScale, d = c ? 0 : this.innerRadius, u = c ? 0 : this.outerRadius, { sharedOptions: f, includeOptions: g } = this._getSharedOptions(e, s); let p, m = this._getRotation(); for (p = 0; p < e; ++p)m += this._circumference(p, n); for (p = e; p < e + i; ++p) { const e = this._circumference(p, n), i = t[p], o = { x: l + this.offsetX, y: h + this.offsetY, startAngle: m, endAngle: m + e, circumference: e, outerRadius: u, innerRadius: d }; g && (o.options = f || this.resolveDataElementOptions(p, i.active ? "active" : s)), m += e, this.updateElement(i, p, o, s) } } calculateTotal() { const t = this._cachedMeta, e = t.data; let i, s = 0; for (i = 0; i < e.length; i++) { const n = t._parsed[i]; null === n || isNaN(n) || !this.chart.getDataVisibility(i) || e[i].hidden || (s += Math.abs(n)) } return s } calculateCircumference(t) { const e = this._cachedMeta.total; return e > 0 && !isNaN(t) ? O * (Math.abs(t) / e) : 0 } getLabelAndValue(t) { const e = this._cachedMeta, i = this.chart, s = i.data.labels || [], n = ne(e._parsed[t], i.options.locale); return { label: s[t] || "", value: n } } getMaxBorderWidth(t) { let e = 0; const i = this.chart; let s, n, o, a, r; if (!t) for (s = 0, n = i.data.datasets.length; s < n; ++s)if (i.isDatasetVisible(s)) { o = i.getDatasetMeta(s), t = o.data, a = o.controller; break } if (!t) return 0; for (s = 0, n = t.length; s < n; ++s)r = a.resolveDataElementOptions(s), "inner" !== r.borderAlign && (e = Math.max(e, r.borderWidth || 0, r.hoverBorderWidth || 0)); return e } getMaxOffset(t) { let e = 0; for (let i = 0, s = t.length; i < s; ++i) { const t = this.resolveDataElementOptions(i); e = Math.max(e, t.offset || 0, t.hoverOffset || 0) } return e } _getRingWeightOffset(t) { let e = 0; for (let i = 0; i < t; ++i)this.chart.isDatasetVisible(i) && (e += this._getRingWeight(i)); return e } _getRingWeight(t) { return Math.max(l(this.chart.data.datasets[t].weight, 1), 0) } _getVisibleDatasetWeightTotal() { return this._getRingWeightOffset(this.chart.data.datasets.length) || 1 } } class Yn extends js { static id = "polarArea"; static defaults = { dataElementType: "arc", animation: { animateRotate: !0, animateScale: !0 }, animations: { numbers: { type: "number", properties: ["x", "y", "startAngle", "endAngle", "innerRadius", "outerRadius"] } }, indexAxis: "r", startAngle: 0 }; static overrides = { aspectRatio: 1, plugins: { legend: { labels: { generateLabels(t) { const e = t.data; if (e.labels.length && e.datasets.length) { const { labels: { pointStyle: i, color: s } } = t.legend.options; return e.labels.map(((e, n) => { const o = t.getDatasetMeta(0).controller.getStyle(n); return { text: e, fillStyle: o.backgroundColor, strokeStyle: o.borderColor, fontColor: s, lineWidth: o.borderWidth, pointStyle: i, hidden: !t.getDataVisibility(n), index: n } })) } return [] } }, onClick(t, e, i) { i.chart.toggleDataVisibility(e.index), i.chart.update() } } }, scales: { r: { type: "radialLinear", angleLines: { display: !1 }, beginAtZero: !0, grid: { circular: !0 }, pointLabels: { display: !1 }, startAngle: 0 } } }; constructor(t, e) { super(t, e), this.innerRadius = void 0, this.outerRadius = void 0 } getLabelAndValue(t) { const e = this._cachedMeta, i = this.chart, s = i.data.labels || [], n = ne(e._parsed[t].r, i.options.locale); return { label: s[t] || "", value: n } } parseObjectData(t, e, i, s) { return ii.bind(this)(t, e, i, s) } update(t) { const e = this._cachedMeta.data; this._updateRadius(), this.updateElements(e, 0, e.length, t) } getMinMax() { const t = this._cachedMeta, e = { min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY }; return t.data.forEach(((t, i) => { const s = this.getParsed(i).r; !isNaN(s) && this.chart.getDataVisibility(i) && (s < e.min && (e.min = s), s > e.max && (e.max = s)) })), e } _updateRadius() { const t = this.chart, e = t.chartArea, i = t.options, s = Math.min(e.right - e.left, e.bottom - e.top), n = Math.max(s / 2, 0), o = (n - Math.max(i.cutoutPercentage ? n / 100 * i.cutoutPercentage : 1, 0)) / t.getVisibleDatasetCount(); this.outerRadius = n - o * this.index, this.innerRadius = this.outerRadius - o } updateElements(t, e, i, s) { const n = "reset" === s, o = this.chart, a = o.options.animation, r = this._cachedMeta.rScale, l = r.xCenter, h = r.yCenter, c = r.getIndexAngle(0) - .5 * C; let d, u = c; const f = 360 / this.countVisibleElements(); for (d = 0; d < e; ++d)u += this._computeAngle(d, s, f); for (d = e; d < e + i; d++) { const e = t[d]; let i = u, g = u + this._computeAngle(d, s, f), p = o.getDataVisibility(d) ? r.getDistanceFromCenterForValue(this.getParsed(d).r) : 0; u = g, n && (a.animateScale && (p = 0), a.animateRotate && (i = g = c)); const m = { x: l, y: h, innerRadius: 0, outerRadius: p, startAngle: i, endAngle: g, options: this.resolveDataElementOptions(d, e.active ? "active" : s) }; this.updateElement(e, d, m, s) } } countVisibleElements() { const t = this._cachedMeta; let e = 0; return t.data.forEach(((t, i) => { !isNaN(this.getParsed(i).r) && this.chart.getDataVisibility(i) && e++ })), e } _computeAngle(t, e, i) { return this.chart.getDataVisibility(t) ? $(this.resolveDataElementOptions(t, e).angle || i) : 0 } } var Un = Object.freeze({ __proto__: null, BarController: class extends js { static id = "bar"; static defaults = { datasetElementType: !1, dataElementType: "bar", categoryPercentage: .8, barPercentage: .9, grouped: !0, animations: { numbers: { type: "number", properties: ["x", "y", "base", "width", "height"] } } }; static overrides = { scales: { _index_: { type: "category", offset: !0, grid: { offset: !0 } }, _value_: { type: "linear", beginAtZero: !0 } } }; parsePrimitiveData(t, e, i, s) { return Vn(t, e, i, s) } parseArrayData(t, e, i, s) { return Vn(t, e, i, s) } parseObjectData(t, e, i, s) { const { iScale: n, vScale: o } = t, { xAxisKey: a = "x", yAxisKey: r = "y" } = this._parsing, l = "x" === n.axis ? a : r, h = "x" === o.axis ? a : r, c = []; let d, u, f, g; for (d = i, u = i + s; d < u; ++d)g = e[d], f = {}, f[n.axis] = n.parse(M(g, l), d), c.push(Fn(M(g, h), f, o, d)); return c } updateRangeFromParsed(t, e, i, s) { super.updateRangeFromParsed(t, e, i, s); const n = i._custom; n && e === this._cachedMeta.vScale && (t.min = Math.min(t.min, n.min), t.max = Math.max(t.max, n.max)) } getMaxOverflow() { return 0 } getLabelAndValue(t) { const e = this._cachedMeta, { iScale: i, vScale: s } = e, n = this.getParsed(t), o = n._custom, a = Bn(o) ? "[" + o.start + ", " + o.end + "]" : "" + s.getLabelForValue(n[s.axis]); return { label: "" + i.getLabelForValue(n[i.axis]), value: a } } initialize() { this.enableOptionSharing = !0, super.initialize(); this._cachedMeta.stack = this.getDataset().stack } update(t) { const e = this._cachedMeta; this.updateElements(e.data, 0, e.data.length, t) } updateElements(t, e, i, n) { const o = "reset" === n, { index: a, _cachedMeta: { vScale: r } } = this, l = r.getBasePixel(), h = r.isHorizontal(), c = this._getRuler(), { sharedOptions: d, includeOptions: u } = this._getSharedOptions(e, n); for (let f = e; f < e + i; f++) { const e = this.getParsed(f), i = o || s(e[r.axis]) ? { base: l, head: l } : this._calculateBarValuePixels(f), g = this._calculateBarIndexPixels(f, c), p = (e._stacks || {})[r.axis], m = { horizontal: h, base: i.base, enableBorderRadius: !p || Bn(e._custom) || a === p._top || a === p._bottom, x: h ? i.head : g.center, y: h ? g.center : i.head, height: h ? g.size : Math.abs(i.size), width: h ? Math.abs(i.size) : g.size }; u && (m.options = d || this.resolveDataElementOptions(f, t[f].active ? "active" : n)); const x = m.options || t[f].options; Wn(m, x, p, a), jn(m, x, c.ratio), this.updateElement(t[f], f, m, n) } } _getStacks(t, e) { const { iScale: i } = this._cachedMeta, n = i.getMatchingVisibleMetas(this._type).filter((t => t.controller.options.grouped)), o = i.options.stacked, a = [], r = this._cachedMeta.controller.getParsed(e), l = r && r[i.axis], h = t => { const e = t._parsed.find((t => t[i.axis] === l)), n = e && e[t.vScale.axis]; if (s(n) || isNaN(n)) return !0 }; for (const i of n) if ((void 0 === e || !h(i)) && ((!1 === o || -1 === a.indexOf(i.stack) || void 0 === o && void 0 === i.stack) && a.push(i.stack), i.index === t)) break; return a.length || a.push(void 0), a } _getStackCount(t) { return this._getStacks(void 0, t).length } _getAxisCount() { return this._getAxis().length } getFirstScaleIdForIndexAxis() { const t = this.chart.scales, e = this.chart.options.indexAxis; return Object.keys(t).filter((i => t[i].axis === e)).shift() } _getAxis() { const t = {}, e = this.getFirstScaleIdForIndexAxis(); for (const i of this.chart.data.datasets) t[l("x" === this.chart.options.indexAxis ? i.xAxisID : i.yAxisID, e)] = !0; return Object.keys(t) } _getStackIndex(t, e, i) { const s = this._getStacks(t, i), n = void 0 !== e ? s.indexOf(e) : -1; return -1 === n ? s.length - 1 : n } _getRuler() { const t = this.options, e = this._cachedMeta, i = e.iScale, s = []; let n, o; for (n = 0, o = e.data.length; n < o; ++n)s.push(i.getPixelForValue(this.getParsed(n)[i.axis], n)); const a = t.barThickness; return { min: a || zn(e), pixels: s, start: i._startPixel, end: i._endPixel, stackCount: this._getStackCount(), scale: i, grouped: t.grouped, ratio: a ? 1 : t.categoryPercentage * t.barPercentage } } _calculateBarValuePixels(t) { const { _cachedMeta: { vScale: e, _stacked: i, index: n }, options: { base: o, minBarLength: a } } = this, r = o || 0, l = this.getParsed(t), h = l._custom, c = Bn(h); let d, u, f = l[e.axis], g = 0, p = i ? this.applyStack(e, l, i) : f; p !== f && (g = p - f, p = f), c && (f = h.barStart, p = h.barEnd - h.barStart, 0 !== f && F(f) !== F(h.barEnd) && (g = 0), g += f); const m = s(o) || c ? g : o; let x = e.getPixelForValue(m); if (d = this.chart.getDataVisibility(t) ? e.getPixelForValue(g + p) : x, u = d - x, Math.abs(u) < a) { u = function (t, e, i) { return 0 !== t ? F(t) : (e.isHorizontal() ? 1 : -1) * (e.min >= i ? 1 : -1) }(u, e, r) * a, f === r && (x -= u / 2); const t = e.getPixelForDecimal(0), s = e.getPixelForDecimal(1), o = Math.min(t, s), h = Math.max(t, s); x = Math.max(Math.min(x, h), o), d = x + u, i && !c && (l._stacks[e.axis]._visualValues[n] = e.getValueForPixel(d) - e.getValueForPixel(x)) } if (x === e.getPixelForValue(r)) { const t = F(u) * e.getLineWidthForValue(r) / 2; x += t, u -= t } return { size: u, base: x, head: d, center: d + u / 2 } } _calculateBarIndexPixels(t, e) { const i = e.scale, n = this.options, o = n.skipNull, a = l(n.maxBarThickness, 1 / 0); let r, h; const c = this._getAxisCount(); if (e.grouped) { const i = o ? this._getStackCount(t) : e.stackCount, d = "flex" === n.barThickness ? function (t, e, i, s) { const n = e.pixels, o = n[t]; let a = t > 0 ? n[t - 1] : null, r = t < n.length - 1 ? n[t + 1] : null; const l = i.categoryPercentage; null === a && (a = o - (null === r ? e.end - e.start : r - o)), null === r && (r = o + o - a); const h = o - (o - Math.min(a, r)) / 2 * l; return { chunk: Math.abs(r - a) / 2 * l / s, ratio: i.barPercentage, start: h } }(t, e, n, i * c) : function (t, e, i, n) { const o = i.barThickness; let a, r; return s(o) ? (a = e.min * i.categoryPercentage, r = i.barPercentage) : (a = o * n, r = 1), { chunk: a / n, ratio: r, start: e.pixels[t] - a / 2 } }(t, e, n, i * c), u = "x" === this.chart.options.indexAxis ? this.getDataset().xAxisID : this.getDataset().yAxisID, f = this._getAxis().indexOf(l(u, this.getFirstScaleIdForIndexAxis())), g = this._getStackIndex(this.index, this._cachedMeta.stack, o ? t : void 0) + f; r = d.start + d.chunk * g + d.chunk / 2, h = Math.min(a, d.chunk * d.ratio) } else r = i.getPixelForValue(this.getParsed(t)[i.axis], t), h = Math.min(a, e.min * e.ratio); return { base: r - h / 2, head: r + h / 2, center: r, size: h } } draw() { const t = this._cachedMeta, e = t.vScale, i = t.data, s = i.length; let n = 0; for (; n < s; ++n)null === this.getParsed(n)[e.axis] || i[n].hidden || i[n].draw(this._ctx) } }, BubbleController: class extends js { static id = "bubble"; static defaults = { datasetElementType: !1, dataElementType: "point", animations: { numbers: { type: "number", properties: ["x", "y", "borderWidth", "radius"] } } }; static overrides = { scales: { x: { type: "linear" }, y: { type: "linear" } } }; initialize() { this.enableOptionSharing = !0, super.initialize() } parsePrimitiveData(t, e, i, s) { const n = super.parsePrimitiveData(t, e, i, s); for (let t = 0; t < n.length; t++)n[t]._custom = this.resolveDataElementOptions(t + i).radius; return n } parseArrayData(t, e, i, s) { const n = super.parseArrayData(t, e, i, s); for (let t = 0; t < n.length; t++) { const s = e[i + t]; n[t]._custom = l(s[2], this.resolveDataElementOptions(t + i).radius) } return n } parseObjectData(t, e, i, s) { const n = super.parseObjectData(t, e, i, s); for (let t = 0; t < n.length; t++) { const s = e[i + t]; n[t]._custom = l(s && s.r && +s.r, this.resolveDataElementOptions(t + i).radius) } return n } getMaxOverflow() { const t = this._cachedMeta.data; let e = 0; for (let i = t.length - 1; i >= 0; --i)e = Math.max(e, t[i].size(this.resolveDataElementOptions(i)) / 2); return e > 0 && e } getLabelAndValue(t) { const e = this._cachedMeta, i = this.chart.data.labels || [], { xScale: s, yScale: n } = e, o = this.getParsed(t), a = s.getLabelForValue(o.x), r = n.getLabelForValue(o.y), l = o._custom; return { label: i[t] || "", value: "(" + a + ", " + r + (l ? ", " + l : "") + ")" } } update(t) { const e = this._cachedMeta.data; this.updateElements(e, 0, e.length, t) } updateElements(t, e, i, s) { const n = "reset" === s, { iScale: o, vScale: a } = this._cachedMeta, { sharedOptions: r, includeOptions: l } = this._getSharedOptions(e, s), h = o.axis, c = a.axis; for (let d = e; d < e + i; d++) { const e = t[d], i = !n && this.getParsed(d), u = {}, f = u[h] = n ? o.getPixelForDecimal(.5) : o.getPixelForValue(i[h]), g = u[c] = n ? a.getBasePixel() : a.getPixelForValue(i[c]); u.skip = isNaN(f) || isNaN(g), l && (u.options = r || this.resolveDataElementOptions(d, e.active ? "active" : s), n && (u.options.radius = 0)), this.updateElement(e, d, u, s) } } resolveDataElementOptions(t, e) { const i = this.getParsed(t); let s = super.resolveDataElementOptions(t, e); s.$shared && (s = Object.assign({}, s, { $shared: !1 })); const n = s.radius; return "active" !== e && (s.radius = 0), s.radius += l(i && i._custom, n), s } }, DoughnutController: $n, LineController: class extends js { static id = "line"; static defaults = { datasetElementType: "line", dataElementType: "point", showLine: !0, spanGaps: !1 }; static overrides = { scales: { _index_: { type: "category" }, _value_: { type: "linear" } } }; initialize() { this.enableOptionSharing = !0, this.supportsDecimation = !0, super.initialize() } update(t) { const e = this._cachedMeta, { dataset: i, data: s = [], _dataset: n } = e, o = this.chart._animationsDisabled; let { start: a, count: r } = pt(e, s, o); this._drawStart = a, this._drawCount = r, mt(e) && (a = 0, r = s.length), i._chart = this.chart, i._datasetIndex = this.index, i._decimated = !!n._decimated, i.points = s; const l = this.resolveDatasetElementOptions(t); this.options.showLine || (l.borderWidth = 0), l.segment = this.options.segment, this.updateElement(i, void 0, { animated: !o, options: l }, t), this.updateElements(s, a, r, t) } updateElements(t, e, i, n) { const o = "reset" === n, { iScale: a, vScale: r, _stacked: l, _dataset: h } = this._cachedMeta, { sharedOptions: c, includeOptions: d } = this._getSharedOptions(e, n), u = a.axis, f = r.axis, { spanGaps: g, segment: p } = this.options, m = N(g) ? g : Number.POSITIVE_INFINITY, x = this.chart._animationsDisabled || o || "none" === n, b = e + i, _ = t.length; let y = e > 0 && this.getParsed(e - 1); for (let i = 0; i < _; ++i) { const g = t[i], _ = x ? g : {}; if (i < e || i >= b) { _.skip = !0; continue } const v = this.getParsed(i), M = s(v[f]), w = _[u] = a.getPixelForValue(v[u], i), k = _[f] = o || M ? r.getBasePixel() : r.getPixelForValue(l ? this.applyStack(r, v, l) : v[f], i); _.skip = isNaN(w) || isNaN(k) || M, _.stop = i > 0 && Math.abs(v[u] - y[u]) > m, p && (_.parsed = v, _.raw = h.data[i]), d && (_.options = c || this.resolveDataElementOptions(i, g.active ? "active" : n)), x || this.updateElement(g, i, _, n), y = v } } getMaxOverflow() { const t = this._cachedMeta, e = t.dataset, i = e.options && e.options.borderWidth || 0, s = t.data || []; if (!s.length) return i; const n = s[0].size(this.resolveDataElementOptions(0)), o = s[s.length - 1].size(this.resolveDataElementOptions(s.length - 1)); return Math.max(i, n, o) / 2 } draw() { const t = this._cachedMeta; t.dataset.updateControlPoints(this.chart.chartArea, t.iScale.axis), super.draw() } }, PieController: class extends $n { static id = "pie"; static defaults = { cutout: 0, rotation: 0, circumference: 360, radius: "100%" } }, PolarAreaController: Yn, RadarController: class extends js { static id = "radar"; static defaults = { datasetElementType: "line", dataElementType: "point", indexAxis: "r", showLine: !0, elements: { line: { fill: "start" } } }; static overrides = { aspectRatio: 1, scales: { r: { type: "radialLinear" } } }; getLabelAndValue(t) { const e = this._cachedMeta.vScale, i = this.getParsed(t); return { label: e.getLabels()[t], value: "" + e.getLabelForValue(i[e.axis]) } } parseObjectData(t, e, i, s) { return ii.bind(this)(t, e, i, s) } update(t) { const e = this._cachedMeta, i = e.dataset, s = e.data || [], n = e.iScale.getLabels(); if (i.points = s, "resize" !== t) { const e = this.resolveDatasetElementOptions(t); this.options.showLine || (e.borderWidth = 0); const o = { _loop: !0, _fullLoop: n.length === s.length, options: e }; this.updateElement(i, void 0, o, t) } this.updateElements(s, 0, s.length, t) } updateElements(t, e, i, s) { const n = this._cachedMeta.rScale, o = "reset" === s; for (let a = e; a < e + i; a++) { const e = t[a], i = this.resolveDataElementOptions(a, e.active ? "active" : s), r = n.getPointPositionForValue(a, this.getParsed(a).r), l = o ? n.xCenter : r.x, h = o ? n.yCenter : r.y, c = { x: l, y: h, angle: r.angle, skip: isNaN(l) || isNaN(h), options: i }; this.updateElement(e, a, c, s) } } }, ScatterController: class extends js { static id = "scatter"; static defaults = { datasetElementType: !1, dataElementType: "point", showLine: !1, fill: !1 }; static overrides = { interaction: { mode: "point" }, scales: { x: { type: "linear" }, y: { type: "linear" } } }; getLabelAndValue(t) { const e = this._cachedMeta, i = this.chart.data.labels || [], { xScale: s, yScale: n } = e, o = this.getParsed(t), a = s.getLabelForValue(o.x), r = n.getLabelForValue(o.y); return { label: i[t] || "", value: "(" + a + ", " + r + ")" } } update(t) { const e = this._cachedMeta, { data: i = [] } = e, s = this.chart._animationsDisabled; let { start: n, count: o } = pt(e, i, s); if (this._drawStart = n, this._drawCount = o, mt(e) && (n = 0, o = i.length), this.options.showLine) { this.datasetElementType || this.addElements(); const { dataset: n, _dataset: o } = e; n._chart = this.chart, n._datasetIndex = this.index, n._decimated = !!o._decimated, n.points = i; const a = this.resolveDatasetElementOptions(t); a.segment = this.options.segment, this.updateElement(n, void 0, { animated: !s, options: a }, t) } else this.datasetElementType && (delete e.dataset, this.datasetElementType = !1); this.updateElements(i, n, o, t) } addElements() { const { showLine: t } = this.options; !this.datasetElementType && t && (this.datasetElementType = this.chart.registry.getElement("line")), super.addElements() } updateElements(t, e, i, n) { const o = "reset" === n, { iScale: a, vScale: r, _stacked: l, _dataset: h } = this._cachedMeta, c = this.resolveDataElementOptions(e, n), d = this.getSharedOptions(c), u = this.includeOptions(n, d), f = a.axis, g = r.axis, { spanGaps: p, segment: m } = this.options, x = N(p) ? p : Number.POSITIVE_INFINITY, b = this.chart._animationsDisabled || o || "none" === n; let _ = e > 0 && this.getParsed(e - 1); for (let c = e; c < e + i; ++c) { const e = t[c], i = this.getParsed(c), p = b ? e : {}, y = s(i[g]), v = p[f] = a.getPixelForValue(i[f], c), M = p[g] = o || y ? r.getBasePixel() : r.getPixelForValue(l ? this.applyStack(r, i, l) : i[g], c); p.skip = isNaN(v) || isNaN(M) || y, p.stop = c > 0 && Math.abs(i[f] - _[f]) > x, m && (p.parsed = i, p.raw = h.data[c]), u && (p.options = d || this.resolveDataElementOptions(c, e.active ? "active" : n)), b || this.updateElement(e, c, p, n), _ = i } this.updateSharedOptions(d, n, c) } getMaxOverflow() { const t = this._cachedMeta, e = t.data || []; if (!this.options.showLine) { let t = 0; for (let i = e.length - 1; i >= 0; --i)t = Math.max(t, e[i].size(this.resolveDataElementOptions(i)) / 2); return t > 0 && t } const i = t.dataset, s = i.options && i.options.borderWidth || 0; if (!e.length) return s; const n = e[0].size(this.resolveDataElementOptions(0)), o = e[e.length - 1].size(this.resolveDataElementOptions(e.length - 1)); return Math.max(s, n, o) / 2 } } }); function Xn(t, e, i, s) { const n = vi(t.options.borderRadius, ["outerStart", "outerEnd", "innerStart", "innerEnd"]); const o = (i - e) / 2, a = Math.min(o, s * e / 2), r = t => { const e = (i - Math.min(o, t)) * s / 2; return Z(t, 0, Math.min(o, e)) }; return { outerStart: r(n.outerStart), outerEnd: r(n.outerEnd), innerStart: Z(n.innerStart, 0, a), innerEnd: Z(n.innerEnd, 0, a) } } function qn(t, e, i, s) { return { x: i + t * Math.cos(e), y: s + t * Math.sin(e) } } function Kn(t, e, i, s, n, o) { const { x: a, y: r, startAngle: l, pixelMargin: h, innerRadius: c } = e, d = Math.max(e.outerRadius + s + i - h, 0), u = c > 0 ? c + s + i + h : 0; let f = 0; const g = n - l; if (s) { const t = ((c > 0 ? c - s : 0) + (d > 0 ? d - s : 0)) / 2; f = (g - (0 !== t ? g * t / (t + s) : g)) / 2 } const p = (g - Math.max(.001, g * d - i / C) / d) / 2, m = l + p + f, x = n - p - f, { outerStart: b, outerEnd: _, innerStart: y, innerEnd: v } = Xn(e, u, d, x - m), M = d - b, w = d - _, k = m + b / M, S = x - _ / w, P = u + y, D = u + v, O = m + y / P, A = x - v / D; if (t.beginPath(), o) { const e = (k + S) / 2; if (t.arc(a, r, d, k, e), t.arc(a, r, d, e, S), _ > 0) { const e = qn(w, S, a, r); t.arc(e.x, e.y, _, S, x + E) } const i = qn(D, x, a, r); if (t.lineTo(i.x, i.y), v > 0) { const e = qn(D, A, a, r); t.arc(e.x, e.y, v, x + E, A + Math.PI) } const s = (x - v / u + (m + y / u)) / 2; if (t.arc(a, r, u, x - v / u, s, !0), t.arc(a, r, u, s, m + y / u, !0), y > 0) { const e = qn(P, O, a, r); t.arc(e.x, e.y, y, O + Math.PI, m - E) } const n = qn(M, m, a, r); if (t.lineTo(n.x, n.y), b > 0) { const e = qn(M, k, a, r); t.arc(e.x, e.y, b, m - E, k) } } else { t.moveTo(a, r); const e = Math.cos(k) * d + a, i = Math.sin(k) * d + r; t.lineTo(e, i); const s = Math.cos(S) * d + a, n = Math.sin(S) * d + r; t.lineTo(s, n) } t.closePath() } function Gn(t, e, i, s, n) { const { fullCircles: o, startAngle: a, circumference: r, options: l } = e, { borderWidth: h, borderJoinStyle: c, borderDash: d, borderDashOffset: u, borderRadius: f } = l, g = "inner" === l.borderAlign; if (!h) return; t.setLineDash(d || []), t.lineDashOffset = u, g ? (t.lineWidth = 2 * h, t.lineJoin = c || "round") : (t.lineWidth = h, t.lineJoin = c || "bevel"); let p = e.endAngle; if (o) { Kn(t, e, i, s, p, n); for (let e = 0; e < o; ++e)t.stroke(); isNaN(r) || (p = a + (r % O || O)) } g && function (t, e, i) { const { startAngle: s, pixelMargin: n, x: o, y: a, outerRadius: r, innerRadius: l } = e; let h = n / r; t.beginPath(), t.arc(o, a, r, s - h, i + h), l > n ? (h = n / l, t.arc(o, a, l, i + h, s - h, !0)) : t.arc(o, a, n, i + E, s - E), t.closePath(), t.clip() }(t, e, p), l.selfJoin && p - a >= C && 0 === f && "miter" !== c && function (t, e, i) { const { startAngle: s, x: n, y: o, outerRadius: a, innerRadius: r, options: l } = e, { borderWidth: h, borderJoinStyle: c } = l, d = Math.min(h / a, G(s - i)); if (t.beginPath(), t.arc(n, o, a - h / 2, s + d / 2, i - d / 2), r > 0) { const e = Math.min(h / r, G(s - i)); t.arc(n, o, r + h / 2, i - e / 2, s + e / 2, !0) } else { const e = Math.min(h / 2, a * G(s - i)); if ("round" === c) t.arc(n, o, e, i - C / 2, s + C / 2, !0); else if ("bevel" === c) { const a = 2 * e * e, r = -a * Math.cos(i + C / 2) + n, l = -a * Math.sin(i + C / 2) + o, h = a * Math.cos(s + C / 2) + n, c = a * Math.sin(s + C / 2) + o; t.lineTo(r, l), t.lineTo(h, c) } } t.closePath(), t.moveTo(0, 0), t.rect(0, 0, t.canvas.width, t.canvas.height), t.clip("evenodd") }(t, e, p), o || (Kn(t, e, i, s, p, n), t.stroke()) } function Jn(t, e, i = e) { t.lineCap = l(i.borderCapStyle, e.borderCapStyle), t.setLineDash(l(i.borderDash, e.borderDash)), t.lineDashOffset = l(i.borderDashOffset, e.borderDashOffset), t.lineJoin = l(i.borderJoinStyle, e.borderJoinStyle), t.lineWidth = l(i.borderWidth, e.borderWidth), t.strokeStyle = l(i.borderColor, e.borderColor) } function Zn(t, e, i) { t.lineTo(i.x, i.y) } function Qn(t, e, i = {}) { const s = t.length, { start: n = 0, end: o = s - 1 } = i, { start: a, end: r } = e, l = Math.max(n, a), h = Math.min(o, r), c = n < a && o < a || n > r && o > r; return { count: s, start: l, loop: e.loop, ilen: h < l && !c ? s + h - l : h - l } } function to(t, e, i, s) { const { points: n, options: o } = e, { count: a, start: r, loop: l, ilen: h } = Qn(n, i, s), c = function (t) { return t.stepped ? Fe : t.tension || "monotone" === t.cubicInterpolationMode ? Ve : Zn }(o); let d, u, f, { move: g = !0, reverse: p } = s || {}; for (d = 0; d <= h; ++d)u = n[(r + (p ? h - d : d)) % a], u.skip || (g ? (t.moveTo(u.x, u.y), g = !1) : c(t, f, u, p, o.stepped), f = u); return l && (u = n[(r + (p ? h : 0)) % a], c(t, f, u, p, o.stepped)), !!l } function eo(t, e, i, s) { const n = e.points, { count: o, start: a, ilen: r } = Qn(n, i, s), { move: l = !0, reverse: h } = s || {}; let c, d, u, f, g, p, m = 0, x = 0; const b = t => (a + (h ? r - t : t)) % o, _ = () => { f !== g && (t.lineTo(m, g), t.lineTo(m, f), t.lineTo(m, p)) }; for (l && (d = n[b(0)], t.moveTo(d.x, d.y)), c = 0; c <= r; ++c) { if (d = n[b(c)], d.skip) continue; const e = d.x, i = d.y, s = 0 | e; s === u ? (i < f ? f = i : i > g && (g = i), m = (x * m + e) / ++x) : (_(), t.lineTo(e, i), u = s, x = 0, f = g = i), p = i } _() } function io(t) { const e = t.options, i = e.borderDash && e.borderDash.length; return !(t._decimated || t._loop || e.tension || "monotone" === e.cubicInterpolationMode || e.stepped || i) ? eo : to } const so = "function" == typeof Path2D; function no(t, e, i, s) { so && !e.options.segment ? function (t, e, i, s) { let n = e._path; n || (n = e._path = new Path2D, e.path(n, i, s) && n.closePath()), Jn(t, e.options), t.stroke(n) }(t, e, i, s) : function (t, e, i, s) { const { segments: n, options: o } = e, a = io(e); for (const r of n) Jn(t, o, r.style), t.beginPath(), a(t, e, r, { start: i, end: i + s - 1 }) && t.closePath(), t.stroke() }(t, e, i, s) } class oo extends $s { static id = "line"; static defaults = { borderCapStyle: "butt", borderDash: [], borderDashOffset: 0, borderJoinStyle: "miter", borderWidth: 3, capBezierPoints: !0, cubicInterpolationMode: "default", fill: !1, spanGaps: !1, stepped: !1, tension: 0 }; static defaultRoutes = { backgroundColor: "backgroundColor", borderColor: "borderColor" }; static descriptors = { _scriptable: !0, _indexable: t => "borderDash" !== t && "fill" !== t }; constructor(t) { super(), this.animated = !0, this.options = void 0, this._chart = void 0, this._loop = void 0, this._fullLoop = void 0, this._path = void 0, this._points = void 0, this._segments = void 0, this._decimated = !1, this._pointsUpdated = !1, this._datasetIndex = void 0, t && Object.assign(this, t) } updateControlPoints(t, e) { const i = this.options; if ((i.tension || "monotone" === i.cubicInterpolationMode) && !i.stepped && !this._pointsUpdated) { const s = i.spanGaps ? this._loop : this._fullLoop; hi(this._points, i, t, s, e), this._pointsUpdated = !0 } } set points(t) { this._points = t, delete this._segments, delete this._path, this._pointsUpdated = !1 } get points() { return this._points } get segments() { return this._segments || (this._segments = zi(this, this.options.segment)) } first() { const t = this.segments, e = this.points; return t.length && e[t[0].start] } last() { const t = this.segments, e = this.points, i = t.length; return i && e[t[i - 1].end] } interpolate(t, e) { const i = this.options, s = t[e], n = this.points, o = Ii(this, { property: e, start: s, end: s }); if (!o.length) return; const a = [], r = function (t) { return t.stepped ? pi : t.tension || "monotone" === t.cubicInterpolationMode ? mi : gi }(i); let l, h; for (l = 0, h = o.length; l < h; ++l) { const { start: h, end: c } = o[l], d = n[h], u = n[c]; if (d === u) { a.push(d); continue } const f = r(d, u, Math.abs((s - d[e]) / (u[e] - d[e])), i.stepped); f[e] = t[e], a.push(f) } return 1 === a.length ? a[0] : a } pathSegment(t, e, i) { return io(this)(t, this, e, i) } path(t, e, i) { const s = this.segments, n = io(this); let o = this._loop; e = e || 0, i = i || this.points.length - e; for (const a of s) o &= n(t, this, a, { start: e, end: e + i - 1 }); return !!o } draw(t, e, i, s) { const n = this.options || {}; (this.points || []).length && n.borderWidth && (t.save(), no(t, this, i, s), t.restore()), this.animated && (this._pointsUpdated = !1, this._path = void 0) } } function ao(t, e, i, s) { const n = t.options, { [i]: o } = t.getProps([i], s); return Math.abs(e - o) < n.radius + n.hitRadius } function ro(t, e) { const { x: i, y: s, base: n, width: o, height: a } = t.getProps(["x", "y", "base", "width", "height"], e); let r, l, h, c, d; return t.horizontal ? (d = a / 2, r = Math.min(i, n), l = Math.max(i, n), h = s - d, c = s + d) : (d = o / 2, r = i - d, l = i + d, h = Math.min(s, n), c = Math.max(s, n)), { left: r, top: h, right: l, bottom: c } } function lo(t, e, i, s) { return t ? 0 : Z(e, i, s) } function ho(t) { const e = ro(t), i = e.right - e.left, s = e.bottom - e.top, n = function (t, e, i) { const s = t.options.borderWidth, n = t.borderSkipped, o = Mi(s); return { t: lo(n.top, o.top, 0, i), r: lo(n.right, o.right, 0, e), b: lo(n.bottom, o.bottom, 0, i), l: lo(n.left, o.left, 0, e) } }(t, i / 2, s / 2), a = function (t, e, i) { const { enableBorderRadius: s } = t.getProps(["enableBorderRadius"]), n = t.options.borderRadius, a = wi(n), r = Math.min(e, i), l = t.borderSkipped, h = s || o(n); return { topLeft: lo(!h || l.top || l.left, a.topLeft, 0, r), topRight: lo(!h || l.top || l.right, a.topRight, 0, r), bottomLeft: lo(!h || l.bottom || l.left, a.bottomLeft, 0, r), bottomRight: lo(!h || l.bottom || l.right, a.bottomRight, 0, r) } }(t, i / 2, s / 2); return { outer: { x: e.left, y: e.top, w: i, h: s, radius: a }, inner: { x: e.left + n.l, y: e.top + n.t, w: i - n.l - n.r, h: s - n.t - n.b, radius: { topLeft: Math.max(0, a.topLeft - Math.max(n.t, n.l)), topRight: Math.max(0, a.topRight - Math.max(n.t, n.r)), bottomLeft: Math.max(0, a.bottomLeft - Math.max(n.b, n.l)), bottomRight: Math.max(0, a.bottomRight - Math.max(n.b, n.r)) } } } } function co(t, e, i, s) { const n = null === e, o = null === i, a = t && !(n && o) && ro(t, s); return a && (n || tt(e, a.left, a.right)) && (o || tt(i, a.top, a.bottom)) } function uo(t, e) { t.rect(e.x, e.y, e.w, e.h) } function fo(t, e, i = {}) { const s = t.x !== i.x ? -e : 0, n = t.y !== i.y ? -e : 0, o = (t.x + t.w !== i.x + i.w ? e : 0) - s, a = (t.y + t.h !== i.y + i.h ? e : 0) - n; return { x: t.x + s, y: t.y + n, w: t.w + o, h: t.h + a, radius: t.radius } } var go = Object.freeze({ __proto__: null, ArcElement: class extends $s { static id = "arc"; static defaults = { borderAlign: "center", borderColor: "#fff", borderDash: [], borderDashOffset: 0, borderJoinStyle: void 0, borderRadius: 0, borderWidth: 2, offset: 0, spacing: 0, angle: void 0, circular: !0, selfJoin: !1 }; static defaultRoutes = { backgroundColor: "backgroundColor" }; static descriptors = { _scriptable: !0, _indexable: t => "borderDash" !== t }; circumference; endAngle; fullCircles; innerRadius; outerRadius; pixelMargin; startAngle; constructor(t) { super(), this.options = void 0, this.circumference = void 0, this.startAngle = void 0, this.endAngle = void 0, this.innerRadius = void 0, this.outerRadius = void 0, this.pixelMargin = 0, this.fullCircles = 0, t && Object.assign(this, t) } inRange(t, e, i) { const s = this.getProps(["x", "y"], i), { angle: n, distance: o } = X(s, { x: t, y: e }), { startAngle: a, endAngle: r, innerRadius: h, outerRadius: c, circumference: d } = this.getProps(["startAngle", "endAngle", "innerRadius", "outerRadius", "circumference"], i), u = (this.options.spacing + this.options.borderWidth) / 2, f = l(d, r - a), g = J(n, a, r) && a !== r, p = f >= O || g, m = tt(o, h + u, c + u); return p && m } getCenterPoint(t) { const { x: e, y: i, startAngle: s, endAngle: n, innerRadius: o, outerRadius: a } = this.getProps(["x", "y", "startAngle", "endAngle", "innerRadius", "outerRadius"], t), { offset: r, spacing: l } = this.options, h = (s + n) / 2, c = (o + a + l + r) / 2; return { x: e + Math.cos(h) * c, y: i + Math.sin(h) * c } } tooltipPosition(t) { return this.getCenterPoint(t) } draw(t) { const { options: e, circumference: i } = this, s = (e.offset || 0) / 4, n = (e.spacing || 0) / 2, o = e.circular; if (this.pixelMargin = "inner" === e.borderAlign ? .33 : 0, this.fullCircles = i > O ? Math.floor(i / O) : 0, 0 === i || this.innerRadius < 0 || this.outerRadius < 0) return; t.save(); const a = (this.startAngle + this.endAngle) / 2; t.translate(Math.cos(a) * s, Math.sin(a) * s); const r = s * (1 - Math.sin(Math.min(C, i || 0))); t.fillStyle = e.backgroundColor, t.strokeStyle = e.borderColor, function (t, e, i, s, n) { const { fullCircles: o, startAngle: a, circumference: r } = e; let l = e.endAngle; if (o) { Kn(t, e, i, s, l, n); for (let e = 0; e < o; ++e)t.fill(); isNaN(r) || (l = a + (r % O || O)) } Kn(t, e, i, s, l, n), t.fill() }(t, this, r, n, o), Gn(t, this, r, n, o), t.restore() } }, BarElement: class extends $s { static id = "bar"; static defaults = { borderSkipped: "start", borderWidth: 0, borderRadius: 0, inflateAmount: "auto", pointStyle: void 0 }; static defaultRoutes = { backgroundColor: "backgroundColor", borderColor: "borderColor" }; constructor(t) { super(), this.options = void 0, this.horizontal = void 0, this.base = void 0, this.width = void 0, this.height = void 0, this.inflateAmount = void 0, t && Object.assign(this, t) } draw(t) { const { inflateAmount: e, options: { borderColor: i, backgroundColor: s } } = this, { inner: n, outer: o } = ho(this), a = (r = o.radius).topLeft || r.topRight || r.bottomLeft || r.bottomRight ? He : uo; var r; t.save(), o.w === n.w && o.h === n.h || (t.beginPath(), a(t, fo(o, e, n)), t.clip(), a(t, fo(n, -e, o)), t.fillStyle = i, t.fill("evenodd")), t.beginPath(), a(t, fo(n, e)), t.fillStyle = s, t.fill(), t.restore() } inRange(t, e, i) { return co(this, t, e, i) } inXRange(t, e) { return co(this, t, null, e) } inYRange(t, e) { return co(this, null, t, e) } getCenterPoint(t) { const { x: e, y: i, base: s, horizontal: n } = this.getProps(["x", "y", "base", "horizontal"], t); return { x: n ? (e + s) / 2 : e, y: n ? i : (i + s) / 2 } } getRange(t) { return "x" === t ? this.width / 2 : this.height / 2 } }, LineElement: oo, PointElement: class extends $s { static id = "point"; parsed; skip; stop; static defaults = { borderWidth: 1, hitRadius: 1, hoverBorderWidth: 1, hoverRadius: 4, pointStyle: "circle", radius: 3, rotation: 0 }; static defaultRoutes = { backgroundColor: "backgroundColor", borderColor: "borderColor" }; constructor(t) { super(), this.options = void 0, this.parsed = void 0, this.skip = void 0, this.stop = void 0, t && Object.assign(this, t) } inRange(t, e, i) { const s = this.options, { x: n, y: o } = this.getProps(["x", "y"], i); return Math.pow(t - n, 2) + Math.pow(e - o, 2) < Math.pow(s.hitRadius + s.radius, 2) } inXRange(t, e) { return ao(this, t, "x", e) } inYRange(t, e) { return ao(this, t, "y", e) } getCenterPoint(t) { const { x: e, y: i } = this.getProps(["x", "y"], t); return { x: e, y: i } } size(t) { let e = (t = t || this.options || {}).radius || 0; e = Math.max(e, e && t.hoverRadius || 0); return 2 * (e + (e && t.borderWidth || 0)) } draw(t, e) { const i = this.options; this.skip || i.radius < .1 || !Re(this, e, this.size(i) / 2) || (t.strokeStyle = i.borderColor, t.lineWidth = i.borderWidth, t.fillStyle = i.backgroundColor, Le(t, i, this.x, this.y)) } getRange() { const t = this.options || {}; return t.radius + t.hitRadius } } }); function po(t, e, i, s) { const n = t.indexOf(e); if (-1 === n) return ((t, e, i, s) => ("string" == typeof e ? (i = t.push(e) - 1, s.unshift({ index: i, label: e })) : isNaN(e) && (i = null), i))(t, e, i, s); return n !== t.lastIndexOf(e) ? i : n } function mo(t) { const e = this.getLabels(); return t >= 0 && t < e.length ? e[t] : t } function xo(t, e, { horizontal: i, minRotation: s }) { const n = $(s), o = (i ? Math.sin(n) : Math.cos(n)) || .001, a = .75 * e * ("" + t).length; return Math.min(e / o, a) } class bo extends tn { constructor(t) { super(t), this.start = void 0, this.end = void 0, this._startValue = void 0, this._endValue = void 0, this._valueRange = 0 } parse(t, e) { return s(t) || ("number" == typeof t || t instanceof Number) && !isFinite(+t) ? null : +t } handleTickRangeOptions() { const { beginAtZero: t } = this.options, { minDefined: e, maxDefined: i } = this.getUserBounds(); let { min: s, max: n } = this; const o = t => s = e ? s : t, a = t => n = i ? n : t; if (t) { const t = F(s), e = F(n); t < 0 && e < 0 ? a(0) : t > 0 && e > 0 && o(0) } if (s === n) { let e = 0 === n ? 1 : Math.abs(.05 * n); a(n + e), t || o(s - e) } this.min = s, this.max = n } getTickLimit() { const t = this.options.ticks; let e, { maxTicksLimit: i, stepSize: s } = t; return s ? (e = Math.ceil(this.max / s) - Math.floor(this.min / s) + 1, e > 1e3 && (console.warn(`scales.${this.id}.ticks.stepSize: ${s} would result generating up to ${e} ticks. Limiting to 1000.`), e = 1e3)) : (e = this.computeTickLimit(), i = i || 11), i && (e = Math.min(i, e)), e } computeTickLimit() { return Number.POSITIVE_INFINITY } buildTicks() { const t = this.options, e = t.ticks; let i = this.getTickLimit(); i = Math.max(2, i); const n = function (t, e) { const i = [], { bounds: n, step: o, min: a, max: r, precision: l, count: h, maxTicks: c, maxDigits: d, includeBounds: u } = t, f = o || 1, g = c - 1, { min: p, max: m } = e, x = !s(a), b = !s(r), _ = !s(h), y = (m - p) / (d + 1); let v, M, w, k, S = B((m - p) / g / f) * f; if (S < 1e-14 && !x && !b) return [{ value: p }, { value: m }]; k = Math.ceil(m / S) - Math.floor(p / S), k > g && (S = B(k * S / g / f) * f), s(l) || (v = Math.pow(10, l), S = Math.ceil(S * v) / v), "ticks" === n ? (M = Math.floor(p / S) * S, w = Math.ceil(m / S) * S) : (M = p, w = m), x && b && o && H((r - a) / o, S / 1e3) ? (k = Math.round(Math.min((r - a) / S, c)), S = (r - a) / k, M = a, w = r) : _ ? (M = x ? a : M, w = b ? r : w, k = h - 1, S = (w - M) / k) : (k = (w - M) / S, k = V(k, Math.round(k), S / 1e3) ? Math.round(k) : Math.ceil(k)); const P = Math.max(U(S), U(M)); v = Math.pow(10, s(l) ? P : l), M = Math.round(M * v) / v, w = Math.round(w * v) / v; let D = 0; for (x && (u && M !== a ? (i.push({ value: a }), M < a && D++, V(Math.round((M + D * S) * v) / v, a, xo(a, y, t)) && D++) : M < a && D++); D < k; ++D) { const t = Math.round((M + D * S) * v) / v; if (b && t > r) break; i.push({ value: t }) } return b && u && w !== r ? i.length && V(i[i.length - 1].value, r, xo(r, y, t)) ? i[i.length - 1].value = r : i.push({ value: r }) : b && w !== r || i.push({ value: w }), i }({ maxTicks: i, bounds: t.bounds, min: t.min, max: t.max, precision: e.precision, step: e.stepSize, count: e.count, maxDigits: this._maxDigits(), horizontal: this.isHorizontal(), minRotation: e.minRotation || 0, includeBounds: !1 !== e.includeBounds }, this._range || this); return "ticks" === t.bounds && j(n, this, "value"), t.reverse ? (n.reverse(), this.start = this.max, this.end = this.min) : (this.start = this.min, this.end = this.max), n } configure() { const t = this.ticks; let e = this.min, i = this.max; if (super.configure(), this.options.offset && t.length) { const s = (i - e) / Math.max(t.length - 1, 1) / 2; e -= s, i += s } this._startValue = e, this._endValue = i, this._valueRange = i - e } getLabelForValue(t) { return ne(t, this.chart.options.locale, this.options.ticks.format) } } class _o extends bo { static id = "linear"; static defaults = { ticks: { callback: ae.formatters.numeric } }; determineDataLimits() { const { min: t, max: e } = this.getMinMax(!0); this.min = a(t) ? t : 0, this.max = a(e) ? e : 1, this.handleTickRangeOptions() } computeTickLimit() { const t = this.isHorizontal(), e = t ? this.width : this.height, i = $(this.options.ticks.minRotation), s = (t ? Math.sin(i) : Math.cos(i)) || .001, n = this._resolveTickFontOptions(0); return Math.ceil(e / Math.min(40, n.lineHeight / s)) } getPixelForValue(t) { return null === t ? NaN : this.getPixelForDecimal((t - this._startValue) / this._valueRange) } getValueForPixel(t) { return this._startValue + this.getDecimalForPixel(t) * this._valueRange } } const yo = t => Math.floor(z(t)), vo = (t, e) => Math.pow(10, yo(t) + e); function Mo(t) { return 1 === t / Math.pow(10, yo(t)) } function wo(t, e, i) { const s = Math.pow(10, i), n = Math.floor(t / s); return Math.ceil(e / s) - n } function ko(t, { min: e, max: i }) { e = r(t.min, e); const s = [], n = yo(e); let o = function (t, e) { let i = yo(e - t); for (; wo(t, e, i) > 10;)i++; for (; wo(t, e, i) < 10;)i--; return Math.min(i, yo(t)) }(e, i), a = o < 0 ? Math.pow(10, Math.abs(o)) : 1; const l = Math.pow(10, o), h = n > o ? Math.pow(10, n) : 0, c = Math.round((e - h) * a) / a, d = Math.floor((e - h) / l / 10) * l * 10; let u = Math.floor((c - d) / Math.pow(10, o)), f = r(t.min, Math.round((h + d + u * Math.pow(10, o)) * a) / a); for (; f < i;)s.push({ value: f, major: Mo(f), significand: u }), u >= 10 ? u = u < 15 ? 15 : 20 : u++, u >= 20 && (o++, u = 2, a = o >= 0 ? 1 : a), f = Math.round((h + d + u * Math.pow(10, o)) * a) / a; const g = r(t.max, f); return s.push({ value: g, major: Mo(g), significand: u }), s } class So extends tn { static id = "logarithmic"; static defaults = { ticks: { callback: ae.formatters.logarithmic, major: { enabled: !0 } } }; constructor(t) { super(t), this.start = void 0, this.end = void 0, this._startValue = void 0, this._valueRange = 0 } parse(t, e) { const i = bo.prototype.parse.apply(this, [t, e]); if (0 !== i) return a(i) && i > 0 ? i : null; this._zero = !0 } determineDataLimits() { const { min: t, max: e } = this.getMinMax(!0); this.min = a(t) ? Math.max(0, t) : null, this.max = a(e) ? Math.max(0, e) : null, this.options.beginAtZero && (this._zero = !0), this._zero && this.min !== this._suggestedMin && !a(this._userMin) && (this.min = t === vo(this.min, 0) ? vo(this.min, -1) : vo(this.min, 0)), this.handleTickRangeOptions() } handleTickRangeOptions() { const { minDefined: t, maxDefined: e } = this.getUserBounds(); let i = this.min, s = this.max; const n = e => i = t ? i : e, o = t => s = e ? s : t; i === s && (i <= 0 ? (n(1), o(10)) : (n(vo(i, -1)), o(vo(s, 1)))), i <= 0 && n(vo(s, -1)), s <= 0 && o(vo(i, 1)), this.min = i, this.max = s } buildTicks() { const t = this.options, e = ko({ min: this._userMin, max: this._userMax }, this); return "ticks" === t.bounds && j(e, this, "value"), t.reverse ? (e.reverse(), this.start = this.max, this.end = this.min) : (this.start = this.min, this.end = this.max), e } getLabelForValue(t) { return void 0 === t ? "0" : ne(t, this.chart.options.locale, this.options.ticks.format) } configure() { const t = this.min; super.configure(), this._startValue = z(t), this._valueRange = z(this.max) - z(t) } getPixelForValue(t) { return void 0 !== t && 0 !== t || (t = this.min), null === t || isNaN(t) ? NaN : this.getPixelForDecimal(t === this.min ? 0 : (z(t) - this._startValue) / this._valueRange) } getValueForPixel(t) { const e = this.getDecimalForPixel(t); return Math.pow(10, this._startValue + e * this._valueRange) } } function Po(t) { const e = t.ticks; if (e.display && t.display) { const t = ki(e.backdropPadding); return l(e.font && e.font.size, ue.font.size) + t.height } return 0 } function Do(t, e, i, s, n) { return t === s || t === n ? { start: e - i / 2, end: e + i / 2 } : t < s || t > n ? { start: e - i, end: e } : { start: e, end: e + i } } function Co(t) { const e = { l: t.left + t._padding.left, r: t.right - t._padding.right, t: t.top + t._padding.top, b: t.bottom - t._padding.bottom }, i = Object.assign({}, e), s = [], o = [], a = t._pointLabels.length, r = t.options.pointLabels, l = r.centerPointLabels ? C / a : 0; for (let u = 0; u < a; u++) { const a = r.setContext(t.getPointLabelContext(u)); o[u] = a.padding; const f = t.getPointPosition(u, t.drawingArea + o[u], l), g = Si(a.font), p = (h = t.ctx, c = g, d = n(d = t._pointLabels[u]) ? d : [d], { w: Oe(h, c.string, d), h: d.length * c.lineHeight }); s[u] = p; const m = G(t.getIndexAngle(u) + l), x = Math.round(Y(m)); Oo(i, e, m, Do(x, f.x, p.w, 0, 180), Do(x, f.y, p.h, 90, 270)) } var h, c, d; t.setCenterPoint(e.l - i.l, i.r - e.r, e.t - i.t, i.b - e.b), t._pointLabelItems = function (t, e, i) { const s = [], n = t._pointLabels.length, o = t.options, { centerPointLabels: a, display: r } = o.pointLabels, l = { extra: Po(o) / 2, additionalAngle: a ? C / n : 0 }; let h; for (let o = 0; o < n; o++) { l.padding = i[o], l.size = e[o]; const n = Ao(t, o, l); s.push(n), "auto" === r && (n.visible = To(n, h), n.visible && (h = n)) } return s }(t, s, o) } function Oo(t, e, i, s, n) { const o = Math.abs(Math.sin(i)), a = Math.abs(Math.cos(i)); let r = 0, l = 0; s.start < e.l ? (r = (e.l - s.start) / o, t.l = Math.min(t.l, e.l - r)) : s.end > e.r && (r = (s.end - e.r) / o, t.r = Math.max(t.r, e.r + r)), n.start < e.t ? (l = (e.t - n.start) / a, t.t = Math.min(t.t, e.t - l)) : n.end > e.b && (l = (n.end - e.b) / a, t.b = Math.max(t.b, e.b + l)) } function Ao(t, e, i) { const s = t.drawingArea, { extra: n, additionalAngle: o, padding: a, size: r } = i, l = t.getPointPosition(e, s + n + a, o), h = Math.round(Y(G(l.angle + E))), c = function (t, e, i) { 90 === i || 270 === i ? t -= e / 2 : (i > 270 || i < 90) && (t -= e); return t }(l.y, r.h, h), d = function (t) { if (0 === t || 180 === t) return "center"; if (t < 180) return "left"; return "right" }(h), u = function (t, e, i) { "right" === i ? t -= e : "center" === i && (t -= e / 2); return t }(l.x, r.w, d); return { visible: !0, x: l.x, y: c, textAlign: d, left: u, top: c, right: u + r.w, bottom: c + r.h } } function To(t, e) { if (!e) return !0; const { left: i, top: s, right: n, bottom: o } = t; return !(Re({ x: i, y: s }, e) || Re({ x: i, y: o }, e) || Re({ x: n, y: s }, e) || Re({ x: n, y: o }, e)) } function Lo(t, e, i) { const { left: n, top: o, right: a, bottom: r } = i, { backdropColor: l } = e; if (!s(l)) { const i = wi(e.borderRadius), s = ki(e.backdropPadding); t.fillStyle = l; const h = n - s.left, c = o - s.top, d = a - n + s.width, u = r - o + s.height; Object.values(i).some((t => 0 !== t)) ? (t.beginPath(), He(t, { x: h, y: c, w: d, h: u, radius: i }), t.fill()) : t.fillRect(h, c, d, u) } } function Eo(t, e, i, s) { const { ctx: n } = t; if (i) n.arc(t.xCenter, t.yCenter, e, 0, O); else { let i = t.getPointPosition(0, e); n.moveTo(i.x, i.y); for (let o = 1; o < s; o++)i = t.getPointPosition(o, e), n.lineTo(i.x, i.y) } } class Ro extends bo { static id = "radialLinear"; static defaults = { display: !0, animate: !0, position: "chartArea", angleLines: { display: !0, lineWidth: 1, borderDash: [], borderDashOffset: 0 }, grid: { circular: !1 }, startAngle: 0, ticks: { showLabelBackdrop: !0, callback: ae.formatters.numeric }, pointLabels: { backdropColor: void 0, backdropPadding: 2, display: !0, font: { size: 10 }, callback: t => t, padding: 5, centerPointLabels: !1 } }; static defaultRoutes = { "angleLines.color": "borderColor", "pointLabels.color": "color", "ticks.color": "color" }; static descriptors = { angleLines: { _fallback: "grid" } }; constructor(t) { super(t), this.xCenter = void 0, this.yCenter = void 0, this.drawingArea = void 0, this._pointLabels = [], this._pointLabelItems = [] } setDimensions() { const t = this._padding = ki(Po(this.options) / 2), e = this.width = this.maxWidth - t.width, i = this.height = this.maxHeight - t.height; this.xCenter = Math.floor(this.left + e / 2 + t.left), this.yCenter = Math.floor(this.top + i / 2 + t.top), this.drawingArea = Math.floor(Math.min(e, i) / 2) } determineDataLimits() { const { min: t, max: e } = this.getMinMax(!1); this.min = a(t) && !isNaN(t) ? t : 0, this.max = a(e) && !isNaN(e) ? e : 0, this.handleTickRangeOptions() } computeTickLimit() { return Math.ceil(this.drawingArea / Po(this.options)) } generateTickLabels(t) { bo.prototype.generateTickLabels.call(this, t), this._pointLabels = this.getLabels().map(((t, e) => { const i = d(this.options.pointLabels.callback, [t, e], this); return i || 0 === i ? i : "" })).filter(((t, e) => this.chart.getDataVisibility(e))) } fit() { const t = this.options; t.display && t.pointLabels.display ? Co(this) : this.setCenterPoint(0, 0, 0, 0) } setCenterPoint(t, e, i, s) { this.xCenter += Math.floor((t - e) / 2), this.yCenter += Math.floor((i - s) / 2), this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(t, e, i, s)) } getIndexAngle(t) { return G(t * (O / (this._pointLabels.length || 1)) + $(this.options.startAngle || 0)) } getDistanceFromCenterForValue(t) { if (s(t)) return NaN; const e = this.drawingArea / (this.max - this.min); return this.options.reverse ? (this.max - t) * e : (t - this.min) * e } getValueForDistanceFromCenter(t) { if (s(t)) return NaN; const e = t / (this.drawingArea / (this.max - this.min)); return this.options.reverse ? this.max - e : this.min + e } getPointLabelContext(t) { const e = this._pointLabels || []; if (t >= 0 && t < e.length) { const i = e[t]; return function (t, e, i) { return Ci(t, { label: i, index: e, type: "pointLabel" }) }(this.getContext(), t, i) } } getPointPosition(t, e, i = 0) { const s = this.getIndexAngle(t) - E + i; return { x: Math.cos(s) * e + this.xCenter, y: Math.sin(s) * e + this.yCenter, angle: s } } getPointPositionForValue(t, e) { return this.getPointPosition(t, this.getDistanceFromCenterForValue(e)) } getBasePosition(t) { return this.getPointPositionForValue(t || 0, this.getBaseValue()) } getPointLabelPosition(t) { const { left: e, top: i, right: s, bottom: n } = this._pointLabelItems[t]; return { left: e, top: i, right: s, bottom: n } } drawBackground() { const { backgroundColor: t, grid: { circular: e } } = this.options; if (t) { const i = this.ctx; i.save(), i.beginPath(), Eo(this, this.getDistanceFromCenterForValue(this._endValue), e, this._pointLabels.length), i.closePath(), i.fillStyle = t, i.fill(), i.restore() } } drawGrid() { const t = this.ctx, e = this.options, { angleLines: i, grid: s, border: n } = e, o = this._pointLabels.length; let a, r, l; if (e.pointLabels.display && function (t, e) { const { ctx: i, options: { pointLabels: s } } = t; for (let n = e - 1; n >= 0; n--) { const e = t._pointLabelItems[n]; if (!e.visible) continue; const o = s.setContext(t.getPointLabelContext(n)); Lo(i, o, e); const a = Si(o.font), { x: r, y: l, textAlign: h } = e; Ne(i, t._pointLabels[n], r, l + a.lineHeight / 2, a, { color: o.color, textAlign: h, textBaseline: "middle" }) } }(this, o), s.display && this.ticks.forEach(((t, e) => { if (0 !== e || 0 === e && this.min < 0) { r = this.getDistanceFromCenterForValue(t.value); const i = this.getContext(e), a = s.setContext(i), l = n.setContext(i); !function (t, e, i, s, n) { const o = t.ctx, a = e.circular, { color: r, lineWidth: l } = e; !a && !s || !r || !l || i < 0 || (o.save(), o.strokeStyle = r, o.lineWidth = l, o.setLineDash(n.dash || []), o.lineDashOffset = n.dashOffset, o.beginPath(), Eo(t, i, a, s), o.closePath(), o.stroke(), o.restore()) }(this, a, r, o, l) } })), i.display) { for (t.save(), a = o - 1; a >= 0; a--) { const s = i.setContext(this.getPointLabelContext(a)), { color: n, lineWidth: o } = s; o && n && (t.lineWidth = o, t.strokeStyle = n, t.setLineDash(s.borderDash), t.lineDashOffset = s.borderDashOffset, r = this.getDistanceFromCenterForValue(e.reverse ? this.min : this.max), l = this.getPointPosition(a, r), t.beginPath(), t.moveTo(this.xCenter, this.yCenter), t.lineTo(l.x, l.y), t.stroke()) } t.restore() } } drawBorder() { } drawLabels() { const t = this.ctx, e = this.options, i = e.ticks; if (!i.display) return; const s = this.getIndexAngle(0); let n, o; t.save(), t.translate(this.xCenter, this.yCenter), t.rotate(s), t.textAlign = "center", t.textBaseline = "middle", this.ticks.forEach(((s, a) => { if (0 === a && this.min >= 0 && !e.reverse) return; const r = i.setContext(this.getContext(a)), l = Si(r.font); if (n = this.getDistanceFromCenterForValue(this.ticks[a].value), r.showLabelBackdrop) { t.font = l.string, o = t.measureText(s.label).width, t.fillStyle = r.backdropColor; const e = ki(r.backdropPadding); t.fillRect(-o / 2 - e.left, -n - l.size / 2 - e.top, o + e.width, l.size + e.height) } Ne(t, s.label, 0, -n, l, { color: r.color, strokeColor: r.textStrokeColor, strokeWidth: r.textStrokeWidth }) })), t.restore() } drawTitle() { } } const Io = { millisecond: { common: !0, size: 1, steps: 1e3 }, second: { common: !0, size: 1e3, steps: 60 }, minute: { common: !0, size: 6e4, steps: 60 }, hour: { common: !0, size: 36e5, steps: 24 }, day: { common: !0, size: 864e5, steps: 30 }, week: { common: !1, size: 6048e5, steps: 4 }, month: { common: !0, size: 2628e6, steps: 12 }, quarter: { common: !1, size: 7884e6, steps: 4 }, year: { common: !0, size: 3154e7 } }, zo = Object.keys(Io); function Fo(t, e) { return t - e } function Vo(t, e) { if (s(e)) return null; const i = t._adapter, { parser: n, round: o, isoWeekday: r } = t._parseOpts; let l = e; return "function" == typeof n && (l = n(l)), a(l) || (l = "string" == typeof n ? i.parse(l, n) : i.parse(l)), null === l ? null : (o && (l = "week" !== o || !N(r) && !0 !== r ? i.startOf(l, o) : i.startOf(l, "isoWeek", r)), +l) } function Bo(t, e, i, s) { const n = zo.length; for (let o = zo.indexOf(t); o < n - 1; ++o) { const t = Io[zo[o]], n = t.steps ? t.steps : Number.MAX_SAFE_INTEGER; if (t.common && Math.ceil((i - e) / (n * t.size)) <= s) return zo[o] } return zo[n - 1] } function Wo(t, e, i) { if (i) { if (i.length) { const { lo: s, hi: n } = et(i, e); t[i[s] >= e ? i[s] : i[n]] = !0 } } else t[e] = !0 } function No(t, e, i) { const s = [], n = {}, o = e.length; let a, r; for (a = 0; a < o; ++a)r = e[a], n[r] = a, s.push({ value: r, major: !1 }); return 0 !== o && i ? function (t, e, i, s) { const n = t._adapter, o = +n.startOf(e[0].value, s), a = e[e.length - 1].value; let r, l; for (r = o; r <= a; r = +n.add(r, 1, s))l = i[r], l >= 0 && (e[l].major = !0); return e }(t, s, n, i) : s } class Ho extends tn { static id = "time"; static defaults = { bounds: "data", adapters: {}, time: { parser: !1, unit: !1, round: !1, isoWeekday: !1, minUnit: "millisecond", displayFormats: {} }, ticks: { source: "auto", callback: !1, major: { enabled: !1 } } }; constructor(t) { super(t), this._cache = { data: [], labels: [], all: [] }, this._unit = "day", this._majorUnit = void 0, this._offsets = {}, this._normalized = !1, this._parseOpts = void 0 } init(t, e = {}) { const i = t.time || (t.time = {}), s = this._adapter = new In._date(t.adapters.date); s.init(e), b(i.displayFormats, s.formats()), this._parseOpts = { parser: i.parser, round: i.round, isoWeekday: i.isoWeekday }, super.init(t), this._normalized = e.normalized } parse(t, e) { return void 0 === t ? null : Vo(this, t) } beforeLayout() { super.beforeLayout(), this._cache = { data: [], labels: [], all: [] } } determineDataLimits() { const t = this.options, e = this._adapter, i = t.time.unit || "day"; let { min: s, max: n, minDefined: o, maxDefined: r } = this.getUserBounds(); function l(t) { o || isNaN(t.min) || (s = Math.min(s, t.min)), r || isNaN(t.max) || (n = Math.max(n, t.max)) } o && r || (l(this._getLabelBounds()), "ticks" === t.bounds && "labels" === t.ticks.source || l(this.getMinMax(!1))), s = a(s) && !isNaN(s) ? s : +e.startOf(Date.now(), i), n = a(n) && !isNaN(n) ? n : +e.endOf(Date.now(), i) + 1, this.min = Math.min(s, n - 1), this.max = Math.max(s + 1, n) } _getLabelBounds() { const t = this.getLabelTimestamps(); let e = Number.POSITIVE_INFINITY, i = Number.NEGATIVE_INFINITY; return t.length && (e = t[0], i = t[t.length - 1]), { min: e, max: i } } buildTicks() { const t = this.options, e = t.time, i = t.ticks, s = "labels" === i.source ? this.getLabelTimestamps() : this._generate(); "ticks" === t.bounds && s.length && (this.min = this._userMin || s[0], this.max = this._userMax || s[s.length - 1]); const n = this.min, o = nt(s, n, this.max); return this._unit = e.unit || (i.autoSkip ? Bo(e.minUnit, this.min, this.max, this._getLabelCapacity(n)) : function (t, e, i, s, n) { for (let o = zo.length - 1; o >= zo.indexOf(i); o--) { const i = zo[o]; if (Io[i].common && t._adapter.diff(n, s, i) >= e - 1) return i } return zo[i ? zo.indexOf(i) : 0] }(this, o.length, e.minUnit, this.min, this.max)), this._majorUnit = i.major.enabled && "year" !== this._unit ? function (t) { for (let e = zo.indexOf(t) + 1, i = zo.length; e < i; ++e)if (Io[zo[e]].common) return zo[e] }(this._unit) : void 0, this.initOffsets(s), t.reverse && o.reverse(), No(this, o, this._majorUnit) } afterAutoSkip() { this.options.offsetAfterAutoskip && this.initOffsets(this.ticks.map((t => +t.value))) } initOffsets(t = []) { let e, i, s = 0, n = 0; this.options.offset && t.length && (e = this.getDecimalForValue(t[0]), s = 1 === t.length ? 1 - e : (this.getDecimalForValue(t[1]) - e) / 2, i = this.getDecimalForValue(t[t.length - 1]), n = 1 === t.length ? i : (i - this.getDecimalForValue(t[t.length - 2])) / 2); const o = t.length < 3 ? .5 : .25; s = Z(s, 0, o), n = Z(n, 0, o), this._offsets = { start: s, end: n, factor: 1 / (s + 1 + n) } } _generate() { const t = this._adapter, e = this.min, i = this.max, s = this.options, n = s.time, o = n.unit || Bo(n.minUnit, e, i, this._getLabelCapacity(e)), a = l(s.ticks.stepSize, 1), r = "week" === o && n.isoWeekday, h = N(r) || !0 === r, c = {}; let d, u, f = e; if (h && (f = +t.startOf(f, "isoWeek", r)), f = +t.startOf(f, h ? "day" : o), t.diff(i, e, o) > 1e5 * a) throw new Error(e + " and " + i + " are too far apart with stepSize of " + a + " " + o); const g = "data" === s.ticks.source && this.getDataTimestamps(); for (d = f, u = 0; d < i; d = +t.add(d, a, o), u++)Wo(c, d, g); return d !== i && "ticks" !== s.bounds && 1 !== u || Wo(c, d, g), Object.keys(c).sort(Fo).map((t => +t)) } getLabelForValue(t) { const e = this._adapter, i = this.options.time; return i.tooltipFormat ? e.format(t, i.tooltipFormat) : e.format(t, i.displayFormats.datetime) } format(t, e) { const i = this.options.time.displayFormats, s = this._unit, n = e || i[s]; return this._adapter.format(t, n) } _tickFormatFunction(t, e, i, s) { const n = this.options, o = n.ticks.callback; if (o) return d(o, [t, e, i], this); const a = n.time.displayFormats, r = this._unit, l = this._majorUnit, h = r && a[r], c = l && a[l], u = i[e], f = l && c && u && u.major; return this._adapter.format(t, s || (f ? c : h)) } generateTickLabels(t) { let e, i, s; for (e = 0, i = t.length; e < i; ++e)s = t[e], s.label = this._tickFormatFunction(s.value, e, t) } getDecimalForValue(t) { return null === t ? NaN : (t - this.min) / (this.max - this.min) } getPixelForValue(t) { const e = this._offsets, i = this.getDecimalForValue(t); return this.getPixelForDecimal((e.start + i) * e.factor) } getValueForPixel(t) { const e = this._offsets, i = this.getDecimalForPixel(t) / e.factor - e.end; return this.min + i * (this.max - this.min) } _getLabelSize(t) { const e = this.options.ticks, i = this.ctx.measureText(t).width, s = $(this.isHorizontal() ? e.maxRotation : e.minRotation), n = Math.cos(s), o = Math.sin(s), a = this._resolveTickFontOptions(0).size; return { w: i * n + a * o, h: i * o + a * n } } _getLabelCapacity(t) { const e = this.options.time, i = e.displayFormats, s = i[e.unit] || i.millisecond, n = this._tickFormatFunction(t, 0, No(this, [t], this._majorUnit), s), o = this._getLabelSize(n), a = Math.floor(this.isHorizontal() ? this.width / o.w : this.height / o.h) - 1; return a > 0 ? a : 1 } getDataTimestamps() { let t, e, i = this._cache.data || []; if (i.length) return i; const s = this.getMatchingVisibleMetas(); if (this._normalized && s.length) return this._cache.data = s[0].controller.getAllParsedValues(this); for (t = 0, e = s.length; t < e; ++t)i = i.concat(s[t].controller.getAllParsedValues(this)); return this._cache.data = this.normalize(i) } getLabelTimestamps() { const t = this._cache.labels || []; let e, i; if (t.length) return t; const s = this.getLabels(); for (e = 0, i = s.length; e < i; ++e)t.push(Vo(this, s[e])); return this._cache.labels = this._normalized ? t : this.normalize(t) } normalize(t) { return lt(t.sort(Fo)) } } function jo(t, e, i) { let s, n, o, a, r = 0, l = t.length - 1; i ? (e >= t[r].pos && e <= t[l].pos && ({ lo: r, hi: l } = it(t, "pos", e)), ({ pos: s, time: o } = t[r]), ({ pos: n, time: a } = t[l])) : (e >= t[r].time && e <= t[l].time && ({ lo: r, hi: l } = it(t, "time", e)), ({ time: s, pos: o } = t[r]), ({ time: n, pos: a } = t[l])); const h = n - s; return h ? o + (a - o) * (e - s) / h : o } var $o = Object.freeze({ __proto__: null, CategoryScale: class extends tn { static id = "category"; static defaults = { ticks: { callback: mo } }; constructor(t) { super(t), this._startValue = void 0, this._valueRange = 0, this._addedLabels = [] } init(t) { const e = this._addedLabels; if (e.length) { const t = this.getLabels(); for (const { index: i, label: s } of e) t[i] === s && t.splice(i, 1); this._addedLabels = [] } super.init(t) } parse(t, e) { if (s(t)) return null; const i = this.getLabels(); return ((t, e) => null === t ? null : Z(Math.round(t), 0, e))(e = isFinite(e) && i[e] === t ? e : po(i, t, l(e, t), this._addedLabels), i.length - 1) } determineDataLimits() { const { minDefined: t, maxDefined: e } = this.getUserBounds(); let { min: i, max: s } = this.getMinMax(!0); "ticks" === this.options.bounds && (t || (i = 0), e || (s = this.getLabels().length - 1)), this.min = i, this.max = s } buildTicks() { const t = this.min, e = this.max, i = this.options.offset, s = []; let n = this.getLabels(); n = 0 === t && e === n.length - 1 ? n : n.slice(t, e + 1), this._valueRange = Math.max(n.length - (i ? 0 : 1), 1), this._startValue = this.min - (i ? .5 : 0); for (let i = t; i <= e; i++)s.push({ value: i }); return s } getLabelForValue(t) { return mo.call(this, t) } configure() { super.configure(), this.isHorizontal() || (this._reversePixels = !this._reversePixels) } getPixelForValue(t) { return "number" != typeof t && (t = this.parse(t)), null === t ? NaN : this.getPixelForDecimal((t - this._startValue) / this._valueRange) } getPixelForTick(t) { const e = this.ticks; return t < 0 || t > e.length - 1 ? null : this.getPixelForValue(e[t].value) } getValueForPixel(t) { return Math.round(this._startValue + this.getDecimalForPixel(t) * this._valueRange) } getBasePixel() { return this.bottom } }, LinearScale: _o, LogarithmicScale: So, RadialLinearScale: Ro, TimeScale: Ho, TimeSeriesScale: class extends Ho { static id = "timeseries"; static defaults = Ho.defaults; constructor(t) { super(t), this._table = [], this._minPos = void 0, this._tableRange = void 0 } initOffsets() { const t = this._getTimestampsForTable(), e = this._table = this.buildLookupTable(t); this._minPos = jo(e, this.min), this._tableRange = jo(e, this.max) - this._minPos, super.initOffsets(t) } buildLookupTable(t) { const { min: e, max: i } = this, s = [], n = []; let o, a, r, l, h; for (o = 0, a = t.length; o < a; ++o)l = t[o], l >= e && l <= i && s.push(l); if (s.length < 2) return [{ time: e, pos: 0 }, { time: i, pos: 1 }]; for (o = 0, a = s.length; o < a; ++o)h = s[o + 1], r = s[o - 1], l = s[o], Math.round((h + r) / 2) !== l && n.push({ time: l, pos: o / (a - 1) }); return n } _generate() { const t = this.min, e = this.max; let i = super.getDataTimestamps(); return i.includes(t) && i.length || i.splice(0, 0, t), i.includes(e) && 1 !== i.length || i.push(e), i.sort(((t, e) => t - e)) } _getTimestampsForTable() { let t = this._cache.all || []; if (t.length) return t; const e = this.getDataTimestamps(), i = this.getLabelTimestamps(); return t = e.length && i.length ? this.normalize(e.concat(i)) : e.length ? e : i, t = this._cache.all = t, t } getDecimalForValue(t) { return (jo(this._table, t) - this._minPos) / this._tableRange } getValueForPixel(t) { const e = this._offsets, i = this.getDecimalForPixel(t) / e.factor - e.end; return jo(this._table, i * this._tableRange + this._minPos, !0) } } }); const Yo = ["rgb(54, 162, 235)", "rgb(255, 99, 132)", "rgb(255, 159, 64)", "rgb(255, 205, 86)", "rgb(75, 192, 192)", "rgb(153, 102, 255)", "rgb(201, 203, 207)"], Uo = Yo.map((t => t.replace("rgb(", "rgba(").replace(")", ", 0.5)"))); function Xo(t) { return Yo[t % Yo.length] } function qo(t) { return Uo[t % Uo.length] } function Ko(t) { let e = 0; return (i, s) => { const n = t.getDatasetMeta(s).controller; n instanceof $n ? e = function (t, e) { return t.backgroundColor = t.data.map((() => Xo(e++))), e }(i, e) : n instanceof Yn ? e = function (t, e) { return t.backgroundColor = t.data.map((() => qo(e++))), e }(i, e) : n && (e = function (t, e) { return t.borderColor = Xo(e), t.backgroundColor = qo(e), ++e }(i, e)) } } function Go(t) { let e; for (e in t) if (t[e].borderColor || t[e].backgroundColor) return !0; return !1 } var Jo = { id: "colors", defaults: { enabled: !0, forceOverride: !1 }, beforeLayout(t, e, i) { if (!i.enabled) return; const { data: { datasets: s }, options: n } = t.config, { elements: o } = n, a = Go(s) || (r = n) && (r.borderColor || r.backgroundColor) || o && Go(o) || "rgba(0,0,0,0.1)" !== ue.borderColor || "rgba(0,0,0,0.1)" !== ue.backgroundColor; var r; if (!i.forceOverride && a) return; const l = Ko(t); s.forEach(l) } }; function Zo(t) { if (t._decimated) { const e = t._data; delete t._decimated, delete t._data, Object.defineProperty(t, "data", { configurable: !0, enumerable: !0, writable: !0, value: e }) } } function Qo(t) { t.data.datasets.forEach((t => { Zo(t) })) } var ta = { id: "decimation", defaults: { algorithm: "min-max", enabled: !1 }, beforeElementsUpdate: (t, e, i) => { if (!i.enabled) return void Qo(t); const n = t.width; t.data.datasets.forEach(((e, o) => { const { _data: a, indexAxis: r } = e, l = t.getDatasetMeta(o), h = a || e.data; if ("y" === Pi([r, t.options.indexAxis])) return; if (!l.controller.supportsDecimation) return; const c = t.scales[l.xAxisID]; if ("linear" !== c.type && "time" !== c.type) return; if (t.options.parsing) return; let { start: d, count: u } = function (t, e) { const i = e.length; let s, n = 0; const { iScale: o } = t, { min: a, max: r, minDefined: l, maxDefined: h } = o.getUserBounds(); return l && (n = Z(it(e, o.axis, a).lo, 0, i - 1)), s = h ? Z(it(e, o.axis, r).hi + 1, n, i) - n : i - n, { start: n, count: s } }(l, h); if (u <= (i.threshold || 4 * n)) return void Zo(e); let f; switch (s(a) && (e._data = h, delete e.data, Object.defineProperty(e, "data", { configurable: !0, enumerable: !0, get: function () { return this._decimated }, set: function (t) { this._data = t } })), i.algorithm) { case "lttb": f = function (t, e, i, s, n) { const o = n.samples || s; if (o >= i) return t.slice(e, e + i); const a = [], r = (i - 2) / (o - 2); let l = 0; const h = e + i - 1; let c, d, u, f, g, p = e; for (a[l++] = t[p], c = 0; c < o - 2; c++) { let s, n = 0, o = 0; const h = Math.floor((c + 1) * r) + 1 + e, m = Math.min(Math.floor((c + 2) * r) + 1, i) + e, x = m - h; for (s = h; s < m; s++)n += t[s].x, o += t[s].y; n /= x, o /= x; const b = Math.floor(c * r) + 1 + e, _ = Math.min(Math.floor((c + 1) * r) + 1, i) + e, { x: y, y: v } = t[p]; for (u = f = -1, s = b; s < _; s++)f = .5 * Math.abs((y - n) * (t[s].y - v) - (y - t[s].x) * (o - v)), f > u && (u = f, d = t[s], g = s); a[l++] = d, p = g } return a[l++] = t[h], a }(h, d, u, n, i); break; case "min-max": f = function (t, e, i, n) { let o, a, r, l, h, c, d, u, f, g, p = 0, m = 0; const x = [], b = e + i - 1, _ = t[e].x, y = t[b].x - _; for (o = e; o < e + i; ++o) { a = t[o], r = (a.x - _) / y * n, l = a.y; const e = 0 | r; if (e === h) l < f ? (f = l, c = o) : l > g && (g = l, d = o), p = (m * p + a.x) / ++m; else { const i = o - 1; if (!s(c) && !s(d)) { const e = Math.min(c, d), s = Math.max(c, d); e !== u && e !== i && x.push({ ...t[e], x: p }), s !== u && s !== i && x.push({ ...t[s], x: p }) } o > 0 && i !== u && x.push(t[i]), x.push(a), h = e, m = 0, f = g = l, c = d = u = o } } return x }(h, d, u, n); break; default: throw new Error(`Unsupported decimation algorithm '${i.algorithm}'`) }e._decimated = f })) }, destroy(t) { Qo(t) } }; function ea(t, e, i, s) { if (s) return; let n = e[t], o = i[t]; return "angle" === t && (n = G(n), o = G(o)), { property: t, start: n, end: o } } function ia(t, e, i) { for (; e > t; e--) { const t = i[e]; if (!isNaN(t.x) && !isNaN(t.y)) break } return e } function sa(t, e, i, s) { return t && e ? s(t[i], e[i]) : t ? t[i] : e ? e[i] : 0 } function na(t, e) { let i = [], s = !1; return n(t) ? (s = !0, i = t) : i = function (t, e) { const { x: i = null, y: s = null } = t || {}, n = e.points, o = []; return e.segments.forEach((({ start: t, end: e }) => { e = ia(t, e, n); const a = n[t], r = n[e]; null !== s ? (o.push({ x: a.x, y: s }), o.push({ x: r.x, y: s })) : null !== i && (o.push({ x: i, y: a.y }), o.push({ x: i, y: r.y })) })), o }(t, e), i.length ? new oo({ points: i, options: { tension: 0 }, _loop: s, _fullLoop: s }) : null } function oa(t) { return t && !1 !== t.fill } function aa(t, e, i) { let s = t[e].fill; const n = [e]; let o; if (!i) return s; for (; !1 !== s && -1 === n.indexOf(s);) { if (!a(s)) return s; if (o = t[s], !o) return !1; if (o.visible) return s; n.push(s), s = o.fill } return !1 } function ra(t, e, i) { const s = function (t) { const e = t.options, i = e.fill; let s = l(i && i.target, i); void 0 === s && (s = !!e.backgroundColor); if (!1 === s || null === s) return !1; if (!0 === s) return "origin"; return s }(t); if (o(s)) return !isNaN(s.value) && s; let n = parseFloat(s); return a(n) && Math.floor(n) === n ? function (t, e, i, s) { "-" !== t && "+" !== t || (i = e + i); if (i === e || i < 0 || i >= s) return !1; return i }(s[0], e, n, i) : ["origin", "start", "end", "stack", "shape"].indexOf(s) >= 0 && s } function la(t, e, i) { const s = []; for (let n = 0; n < i.length; n++) { const o = i[n], { first: a, last: r, point: l } = ha(o, e, "x"); if (!(!l || a && r)) if (a) s.unshift(l); else if (t.push(l), !r) break } t.push(...s) } function ha(t, e, i) { const s = t.interpolate(e, i); if (!s) return {}; const n = s[i], o = t.segments, a = t.points; let r = !1, l = !1; for (let t = 0; t < o.length; t++) { const e = o[t], s = a[e.start][i], h = a[e.end][i]; if (tt(n, s, h)) { r = n === s, l = n === h; break } } return { first: r, last: l, point: s } } class ca { constructor(t) { this.x = t.x, this.y = t.y, this.radius = t.radius } pathSegment(t, e, i) { const { x: s, y: n, radius: o } = this; return e = e || { start: 0, end: O }, t.arc(s, n, o, e.end, e.start, !0), !i.bounds } interpolate(t) { const { x: e, y: i, radius: s } = this, n = t.angle; return { x: e + Math.cos(n) * s, y: i + Math.sin(n) * s, angle: n } } } function da(t) { const { chart: e, fill: i, line: s } = t; if (a(i)) return function (t, e) { const i = t.getDatasetMeta(e), s = i && t.isDatasetVisible(e); return s ? i.dataset : null }(e, i); if ("stack" === i) return function (t) { const { scale: e, index: i, line: s } = t, n = [], o = s.segments, a = s.points, r = function (t, e) { const i = [], s = t.getMatchingVisibleMetas("line"); for (let t = 0; t < s.length; t++) { const n = s[t]; if (n.index === e) break; n.hidden || i.unshift(n.dataset) } return i }(e, i); r.push(na({ x: null, y: e.bottom }, s)); for (let t = 0; t < o.length; t++) { const e = o[t]; for (let t = e.start; t <= e.end; t++)la(n, a[t], r) } return new oo({ points: n, options: {} }) }(t); if ("shape" === i) return !0; const n = function (t) { const e = t.scale || {}; if (e.getPointPositionForValue) return function (t) { const { scale: e, fill: i } = t, s = e.options, n = e.getLabels().length, a = s.reverse ? e.max : e.min, r = function (t, e, i) { let s; return s = "start" === t ? i : "end" === t ? e.options.reverse ? e.min : e.max : o(t) ? t.value : e.getBaseValue(), s }(i, e, a), l = []; if (s.grid.circular) { const t = e.getPointPositionForValue(0, a); return new ca({ x: t.x, y: t.y, radius: e.getDistanceFromCenterForValue(r) }) } for (let t = 0; t < n; ++t)l.push(e.getPointPositionForValue(t, r)); return l }(t); return function (t) { const { scale: e = {}, fill: i } = t, s = function (t, e) { let i = null; return "start" === t ? i = e.bottom : "end" === t ? i = e.top : o(t) ? i = e.getPixelForValue(t.value) : e.getBasePixel && (i = e.getBasePixel()), i }(i, e); if (a(s)) { const t = e.isHorizontal(); return { x: t ? s : null, y: t ? null : s } } return null }(t) }(t); return n instanceof ca ? n : na(n, s) } function ua(t, e, i) { const s = da(e), { chart: n, index: o, line: a, scale: r, axis: l } = e, h = a.options, c = h.fill, d = h.backgroundColor, { above: u = d, below: f = d } = c || {}, g = n.getDatasetMeta(o), p = Ni(n, g); s && a.points.length && (Ie(t, i), function (t, e) { const { line: i, target: s, above: n, below: o, area: a, scale: r, clip: l } = e, h = i._loop ? "angle" : e.axis; t.save(); let c = o; o !== n && ("x" === h ? (fa(t, s, a.top), pa(t, { line: i, target: s, color: n, scale: r, property: h, clip: l }), t.restore(), t.save(), fa(t, s, a.bottom)) : "y" === h && (ga(t, s, a.left), pa(t, { line: i, target: s, color: o, scale: r, property: h, clip: l }), t.restore(), t.save(), ga(t, s, a.right), c = n)); pa(t, { line: i, target: s, color: c, scale: r, property: h, clip: l }), t.restore() }(t, { line: a, target: s, above: u, below: f, area: i, scale: r, axis: l, clip: p }), ze(t)) } function fa(t, e, i) { const { segments: s, points: n } = e; let o = !0, a = !1; t.beginPath(); for (const r of s) { const { start: s, end: l } = r, h = n[s], c = n[ia(s, l, n)]; o ? (t.moveTo(h.x, h.y), o = !1) : (t.lineTo(h.x, i), t.lineTo(h.x, h.y)), a = !!e.pathSegment(t, r, { move: a }), a ? t.closePath() : t.lineTo(c.x, i) } t.lineTo(e.first().x, i), t.closePath(), t.clip() } function ga(t, e, i) { const { segments: s, points: n } = e; let o = !0, a = !1; t.beginPath(); for (const r of s) { const { start: s, end: l } = r, h = n[s], c = n[ia(s, l, n)]; o ? (t.moveTo(h.x, h.y), o = !1) : (t.lineTo(i, h.y), t.lineTo(h.x, h.y)), a = !!e.pathSegment(t, r, { move: a }), a ? t.closePath() : t.lineTo(i, c.y) } t.lineTo(i, e.first().y), t.closePath(), t.clip() } function pa(t, e) { const { line: i, target: s, property: n, color: o, scale: a, clip: r } = e, l = function (t, e, i) { const s = t.segments, n = t.points, o = e.points, a = []; for (const t of s) { let { start: s, end: r } = t; r = ia(s, r, n); const l = ea(i, n[s], n[r], t.loop); if (!e.segments) { a.push({ source: t, target: l, start: n[s], end: n[r] }); continue } const h = Ii(e, l); for (const e of h) { const s = ea(i, o[e.start], o[e.end], e.loop), r = Ri(t, n, s); for (const t of r) a.push({ source: t, target: e, start: { [i]: sa(l, s, "start", Math.max) }, end: { [i]: sa(l, s, "end", Math.min) } }) } } return a }(i, s, n); for (const { source: e, target: h, start: c, end: d } of l) { const { style: { backgroundColor: l = o } = {} } = e, u = !0 !== s; t.save(), t.fillStyle = l, ma(t, a, r, u && ea(n, c, d)), t.beginPath(); const f = !!i.pathSegment(t, e); let g; if (u) { f ? t.closePath() : xa(t, s, d, n); const e = !!s.pathSegment(t, h, { move: f, reverse: !0 }); g = f && e, g || xa(t, s, c, n) } t.closePath(), t.fill(g ? "evenodd" : "nonzero"), t.restore() } } function ma(t, e, i, s) { const n = e.chart.chartArea, { property: o, start: a, end: r } = s || {}; if ("x" === o || "y" === o) { let e, s, l, h; "x" === o ? (e = a, s = n.top, l = r, h = n.bottom) : (e = n.left, s = a, l = n.right, h = r), t.beginPath(), i && (e = Math.max(e, i.left), l = Math.min(l, i.right), s = Math.max(s, i.top), h = Math.min(h, i.bottom)), t.rect(e, s, l - e, h - s), t.clip() } } function xa(t, e, i, s) { const n = e.interpolate(i, s); n && t.lineTo(n.x, n.y) } var ba = { id: "filler", afterDatasetsUpdate(t, e, i) { const s = (t.data.datasets || []).length, n = []; let o, a, r, l; for (a = 0; a < s; ++a)o = t.getDatasetMeta(a), r = o.dataset, l = null, r && r.options && r instanceof oo && (l = { visible: t.isDatasetVisible(a), index: a, fill: ra(r, a, s), chart: t, axis: o.controller.options.indexAxis, scale: o.vScale, line: r }), o.$filler = l, n.push(l); for (a = 0; a < s; ++a)l = n[a], l && !1 !== l.fill && (l.fill = aa(n, a, i.propagate)) }, beforeDraw(t, e, i) { const s = "beforeDraw" === i.drawTime, n = t.getSortedVisibleDatasetMetas(), o = t.chartArea; for (let e = n.length - 1; e >= 0; --e) { const i = n[e].$filler; i && (i.line.updateControlPoints(o, i.axis), s && i.fill && ua(t.ctx, i, o)) } }, beforeDatasetsDraw(t, e, i) { if ("beforeDatasetsDraw" !== i.drawTime) return; const s = t.getSortedVisibleDatasetMetas(); for (let e = s.length - 1; e >= 0; --e) { const i = s[e].$filler; oa(i) && ua(t.ctx, i, t.chartArea) } }, beforeDatasetDraw(t, e, i) { const s = e.meta.$filler; oa(s) && "beforeDatasetDraw" === i.drawTime && ua(t.ctx, s, t.chartArea) }, defaults: { propagate: !0, drawTime: "beforeDatasetDraw" } }; const _a = (t, e) => { let { boxHeight: i = e, boxWidth: s = e } = t; return t.usePointStyle && (i = Math.min(i, e), s = t.pointStyleWidth || Math.min(s, e)), { boxWidth: s, boxHeight: i, itemHeight: Math.max(e, i) } }; class ya extends $s { constructor(t) { super(), this._added = !1, this.legendHitBoxes = [], this._hoveredItem = null, this.doughnutMode = !1, this.chart = t.chart, this.options = t.options, this.ctx = t.ctx, this.legendItems = void 0, this.columnSizes = void 0, this.lineWidths = void 0, this.maxHeight = void 0, this.maxWidth = void 0, this.top = void 0, this.bottom = void 0, this.left = void 0, this.right = void 0, this.height = void 0, this.width = void 0, this._margins = void 0, this.position = void 0, this.weight = void 0, this.fullSize = void 0 } update(t, e, i) { this.maxWidth = t, this.maxHeight = e, this._margins = i, this.setDimensions(), this.buildLabels(), this.fit() } setDimensions() { this.isHorizontal() ? (this.width = this.maxWidth, this.left = this._margins.left, this.right = this.width) : (this.height = this.maxHeight, this.top = this._margins.top, this.bottom = this.height) } buildLabels() { const t = this.options.labels || {}; let e = d(t.generateLabels, [this.chart], this) || []; t.filter && (e = e.filter((e => t.filter(e, this.chart.data)))), t.sort && (e = e.sort(((e, i) => t.sort(e, i, this.chart.data)))), this.options.reverse && e.reverse(), this.legendItems = e } fit() { const { options: t, ctx: e } = this; if (!t.display) return void (this.width = this.height = 0); const i = t.labels, s = Si(i.font), n = s.size, o = this._computeTitleHeight(), { boxWidth: a, itemHeight: r } = _a(i, n); let l, h; e.font = s.string, this.isHorizontal() ? (l = this.maxWidth, h = this._fitRows(o, n, a, r) + 10) : (h = this.maxHeight, l = this._fitCols(o, s, a, r) + 10), this.width = Math.min(l, t.maxWidth || this.maxWidth), this.height = Math.min(h, t.maxHeight || this.maxHeight) } _fitRows(t, e, i, s) { const { ctx: n, maxWidth: o, options: { labels: { padding: a } } } = this, r = this.legendHitBoxes = [], l = this.lineWidths = [0], h = s + a; let c = t; n.textAlign = "left", n.textBaseline = "middle"; let d = -1, u = -h; return this.legendItems.forEach(((t, f) => { const g = i + e / 2 + n.measureText(t.text).width; (0 === f || l[l.length - 1] + g + 2 * a > o) && (c += h, l[l.length - (f > 0 ? 0 : 1)] = 0, u += h, d++), r[f] = { left: 0, top: u, row: d, width: g, height: s }, l[l.length - 1] += g + a })), c } _fitCols(t, e, i, s) { const { ctx: n, maxHeight: o, options: { labels: { padding: a } } } = this, r = this.legendHitBoxes = [], l = this.columnSizes = [], h = o - t; let c = a, d = 0, u = 0, f = 0, g = 0; return this.legendItems.forEach(((t, o) => { const { itemWidth: p, itemHeight: m } = function (t, e, i, s, n) { const o = function (t, e, i, s) { let n = t.text; n && "string" != typeof n && (n = n.reduce(((t, e) => t.length > e.length ? t : e))); return e + i.size / 2 + s.measureText(n).width }(s, t, e, i), a = function (t, e, i) { let s = t; "string" != typeof e.text && (s = va(e, i)); return s }(n, s, e.lineHeight); return { itemWidth: o, itemHeight: a } }(i, e, n, t, s); o > 0 && u + m + 2 * a > h && (c += d + a, l.push({ width: d, height: u }), f += d + a, g++, d = u = 0), r[o] = { left: f, top: u, col: g, width: p, height: m }, d = Math.max(d, p), u += m + a })), c += d, l.push({ width: d, height: u }), c } adjustHitBoxes() { if (!this.options.display) return; const t = this._computeTitleHeight(), { legendHitBoxes: e, options: { align: i, labels: { padding: s }, rtl: n } } = this, o = Oi(n, this.left, this.width); if (this.isHorizontal()) { let n = 0, a = ft(i, this.left + s, this.right - this.lineWidths[n]); for (const r of e) n !== r.row && (n = r.row, a = ft(i, this.left + s, this.right - this.lineWidths[n])), r.top += this.top + t + s, r.left = o.leftForLtr(o.x(a), r.width), a += r.width + s } else { let n = 0, a = ft(i, this.top + t + s, this.bottom - this.columnSizes[n].height); for (const r of e) r.col !== n && (n = r.col, a = ft(i, this.top + t + s, this.bottom - this.columnSizes[n].height)), r.top = a, r.left += this.left + s, r.left = o.leftForLtr(o.x(r.left), r.width), a += r.height + s } } isHorizontal() { return "top" === this.options.position || "bottom" === this.options.position } draw() { if (this.options.display) { const t = this.ctx; Ie(t, this), this._draw(), ze(t) } } _draw() { const { options: t, columnSizes: e, lineWidths: i, ctx: s } = this, { align: n, labels: o } = t, a = ue.color, r = Oi(t.rtl, this.left, this.width), h = Si(o.font), { padding: c } = o, d = h.size, u = d / 2; let f; this.drawTitle(), s.textAlign = r.textAlign("left"), s.textBaseline = "middle", s.lineWidth = .5, s.font = h.string; const { boxWidth: g, boxHeight: p, itemHeight: m } = _a(o, d), x = this.isHorizontal(), b = this._computeTitleHeight(); f = x ? { x: ft(n, this.left + c, this.right - i[0]), y: this.top + c + b, line: 0 } : { x: this.left + c, y: ft(n, this.top + b + c, this.bottom - e[0].height), line: 0 }, Ai(this.ctx, t.textDirection); const _ = m + c; this.legendItems.forEach(((y, v) => { s.strokeStyle = y.fontColor, s.fillStyle = y.fontColor; const M = s.measureText(y.text).width, w = r.textAlign(y.textAlign || (y.textAlign = o.textAlign)), k = g + u + M; let S = f.x, P = f.y; r.setWidth(this.width), x ? v > 0 && S + k + c > this.right && (P = f.y += _, f.line++, S = f.x = ft(n, this.left + c, this.right - i[f.line])) : v > 0 && P + _ > this.bottom && (S = f.x = S + e[f.line].width + c, f.line++, P = f.y = ft(n, this.top + b + c, this.bottom - e[f.line].height)); if (function (t, e, i) { if (isNaN(g) || g <= 0 || isNaN(p) || p < 0) return; s.save(); const n = l(i.lineWidth, 1); if (s.fillStyle = l(i.fillStyle, a), s.lineCap = l(i.lineCap, "butt"), s.lineDashOffset = l(i.lineDashOffset, 0), s.lineJoin = l(i.lineJoin, "miter"), s.lineWidth = n, s.strokeStyle = l(i.strokeStyle, a), s.setLineDash(l(i.lineDash, [])), o.usePointStyle) { const a = { radius: p * Math.SQRT2 / 2, pointStyle: i.pointStyle, rotation: i.rotation, borderWidth: n }, l = r.xPlus(t, g / 2); Ee(s, a, l, e + u, o.pointStyleWidth && g) } else { const o = e + Math.max((d - p) / 2, 0), a = r.leftForLtr(t, g), l = wi(i.borderRadius); s.beginPath(), Object.values(l).some((t => 0 !== t)) ? He(s, { x: a, y: o, w: g, h: p, radius: l }) : s.rect(a, o, g, p), s.fill(), 0 !== n && s.stroke() } s.restore() }(r.x(S), P, y), S = gt(w, S + g + u, x ? S + k : this.right, t.rtl), function (t, e, i) { Ne(s, i.text, t, e + m / 2, h, { strikethrough: i.hidden, textAlign: r.textAlign(i.textAlign) }) }(r.x(S), P, y), x) f.x += k + c; else if ("string" != typeof y.text) { const t = h.lineHeight; f.y += va(y, t) + c } else f.y += _ })), Ti(this.ctx, t.textDirection) } drawTitle() { const t = this.options, e = t.title, i = Si(e.font), s = ki(e.padding); if (!e.display) return; const n = Oi(t.rtl, this.left, this.width), o = this.ctx, a = e.position, r = i.size / 2, l = s.top + r; let h, c = this.left, d = this.width; if (this.isHorizontal()) d = Math.max(...this.lineWidths), h = this.top + l, c = ft(t.align, c, this.right - d); else { const e = this.columnSizes.reduce(((t, e) => Math.max(t, e.height)), 0); h = l + ft(t.align, this.top, this.bottom - e - t.labels.padding - this._computeTitleHeight()) } const u = ft(a, c, c + d); o.textAlign = n.textAlign(ut(a)), o.textBaseline = "middle", o.strokeStyle = e.color, o.fillStyle = e.color, o.font = i.string, Ne(o, e.text, u, h, i) } _computeTitleHeight() { const t = this.options.title, e = Si(t.font), i = ki(t.padding); return t.display ? e.lineHeight + i.height : 0 } _getLegendItemAt(t, e) { let i, s, n; if (tt(t, this.left, this.right) && tt(e, this.top, this.bottom)) for (n = this.legendHitBoxes, i = 0; i < n.length; ++i)if (s = n[i], tt(t, s.left, s.left + s.width) && tt(e, s.top, s.top + s.height)) return this.legendItems[i]; return null } handleEvent(t) { const e = this.options; if (!function (t, e) { if (("mousemove" === t || "mouseout" === t) && (e.onHover || e.onLeave)) return !0; if (e.onClick && ("click" === t || "mouseup" === t)) return !0; return !1 }(t.type, e)) return; const i = this._getLegendItemAt(t.x, t.y); if ("mousemove" === t.type || "mouseout" === t.type) { const o = this._hoveredItem, a = (n = i, null !== (s = o) && null !== n && s.datasetIndex === n.datasetIndex && s.index === n.index); o && !a && d(e.onLeave, [t, o, this], this), this._hoveredItem = i, i && !a && d(e.onHover, [t, i, this], this) } else i && d(e.onClick, [t, i, this], this); var s, n } } function va(t, e) { return e * (t.text ? t.text.length : 0) } var Ma = { id: "legend", _element: ya, start(t, e, i) { const s = t.legend = new ya({ ctx: t.ctx, options: i, chart: t }); ls.configure(t, s, i), ls.addBox(t, s) }, stop(t) { ls.removeBox(t, t.legend), delete t.legend }, beforeUpdate(t, e, i) { const s = t.legend; ls.configure(t, s, i), s.options = i }, afterUpdate(t) { const e = t.legend; e.buildLabels(), e.adjustHitBoxes() }, afterEvent(t, e) { e.replay || t.legend.handleEvent(e.event) }, defaults: { display: !0, position: "top", align: "center", fullSize: !0, reverse: !1, weight: 1e3, onClick(t, e, i) { const s = e.datasetIndex, n = i.chart; n.isDatasetVisible(s) ? (n.hide(s), e.hidden = !0) : (n.show(s), e.hidden = !1) }, onHover: null, onLeave: null, labels: { color: t => t.chart.options.color, boxWidth: 40, padding: 10, generateLabels(t) { const e = t.data.datasets, { labels: { usePointStyle: i, pointStyle: s, textAlign: n, color: o, useBorderRadius: a, borderRadius: r } } = t.legend.options; return t._getSortedDatasetMetas().map((t => { const l = t.controller.getStyle(i ? 0 : void 0), h = ki(l.borderWidth); return { text: e[t.index].label, fillStyle: l.backgroundColor, fontColor: o, hidden: !t.visible, lineCap: l.borderCapStyle, lineDash: l.borderDash, lineDashOffset: l.borderDashOffset, lineJoin: l.borderJoinStyle, lineWidth: (h.width + h.height) / 4, strokeStyle: l.borderColor, pointStyle: s || l.pointStyle, rotation: l.rotation, textAlign: n || l.textAlign, borderRadius: a && (r || l.borderRadius), datasetIndex: t.index } }), this) } }, title: { color: t => t.chart.options.color, display: !1, position: "center", text: "" } }, descriptors: { _scriptable: t => !t.startsWith("on"), labels: { _scriptable: t => !["generateLabels", "filter", "sort"].includes(t) } } }; class wa extends $s { constructor(t) { super(), this.chart = t.chart, this.options = t.options, this.ctx = t.ctx, this._padding = void 0, this.top = void 0, this.bottom = void 0, this.left = void 0, this.right = void 0, this.width = void 0, this.height = void 0, this.position = void 0, this.weight = void 0, this.fullSize = void 0 } update(t, e) { const i = this.options; if (this.left = 0, this.top = 0, !i.display) return void (this.width = this.height = this.right = this.bottom = 0); this.width = this.right = t, this.height = this.bottom = e; const s = n(i.text) ? i.text.length : 1; this._padding = ki(i.padding); const o = s * Si(i.font).lineHeight + this._padding.height; this.isHorizontal() ? this.height = o : this.width = o } isHorizontal() { const t = this.options.position; return "top" === t || "bottom" === t } _drawArgs(t) { const { top: e, left: i, bottom: s, right: n, options: o } = this, a = o.align; let r, l, h, c = 0; return this.isHorizontal() ? (l = ft(a, i, n), h = e + t, r = n - i) : ("left" === o.position ? (l = i + t, h = ft(a, s, e), c = -.5 * C) : (l = n - t, h = ft(a, e, s), c = .5 * C), r = s - e), { titleX: l, titleY: h, maxWidth: r, rotation: c } } draw() { const t = this.ctx, e = this.options; if (!e.display) return; const i = Si(e.font), s = i.lineHeight / 2 + this._padding.top, { titleX: n, titleY: o, maxWidth: a, rotation: r } = this._drawArgs(s); Ne(t, e.text, 0, 0, i, { color: e.color, maxWidth: a, rotation: r, textAlign: ut(e.align), textBaseline: "middle", translation: [n, o] }) } } var ka = { id: "title", _element: wa, start(t, e, i) { !function (t, e) { const i = new wa({ ctx: t.ctx, options: e, chart: t }); ls.configure(t, i, e), ls.addBox(t, i), t.titleBlock = i }(t, i) }, stop(t) { const e = t.titleBlock; ls.removeBox(t, e), delete t.titleBlock }, beforeUpdate(t, e, i) { const s = t.titleBlock; ls.configure(t, s, i), s.options = i }, defaults: { align: "center", display: !1, font: { weight: "bold" }, fullSize: !0, padding: 10, position: "top", text: "", weight: 2e3 }, defaultRoutes: { color: "color" }, descriptors: { _scriptable: !0, _indexable: !1 } }; const Sa = new WeakMap; var Pa = { id: "subtitle", start(t, e, i) { const s = new wa({ ctx: t.ctx, options: i, chart: t }); ls.configure(t, s, i), ls.addBox(t, s), Sa.set(t, s) }, stop(t) { ls.removeBox(t, Sa.get(t)), Sa.delete(t) }, beforeUpdate(t, e, i) { const s = Sa.get(t); ls.configure(t, s, i), s.options = i }, defaults: { align: "center", display: !1, font: { weight: "normal" }, fullSize: !0, padding: 0, position: "top", text: "", weight: 1500 }, defaultRoutes: { color: "color" }, descriptors: { _scriptable: !0, _indexable: !1 } }; const Da = { average(t) { if (!t.length) return !1; let e, i, s = new Set, n = 0, o = 0; for (e = 0, i = t.length; e < i; ++e) { const i = t[e].element; if (i && i.hasValue()) { const t = i.tooltipPosition(); s.add(t.x), n += t.y, ++o } } if (0 === o || 0 === s.size) return !1; return { x: [...s].reduce(((t, e) => t + e)) / s.size, y: n / o } }, nearest(t, e) { if (!t.length) return !1; let i, s, n, o = e.x, a = e.y, r = Number.POSITIVE_INFINITY; for (i = 0, s = t.length; i < s; ++i) { const s = t[i].element; if (s && s.hasValue()) { const t = q(e, s.getCenterPoint()); t < r && (r = t, n = s) } } if (n) { const t = n.tooltipPosition(); o = t.x, a = t.y } return { x: o, y: a } } }; function Ca(t, e) { return e && (n(e) ? Array.prototype.push.apply(t, e) : t.push(e)), t } function Oa(t) { return ("string" == typeof t || t instanceof String) && t.indexOf("\n") > -1 ? t.split("\n") : t } function Aa(t, e) { const { element: i, datasetIndex: s, index: n } = e, o = t.getDatasetMeta(s).controller, { label: a, value: r } = o.getLabelAndValue(n); return { chart: t, label: a, parsed: o.getParsed(n), raw: t.data.datasets[s].data[n], formattedValue: r, dataset: o.getDataset(), dataIndex: n, datasetIndex: s, element: i } } function Ta(t, e) { const i = t.chart.ctx, { body: s, footer: n, title: o } = t, { boxWidth: a, boxHeight: r } = e, l = Si(e.bodyFont), h = Si(e.titleFont), c = Si(e.footerFont), d = o.length, f = n.length, g = s.length, p = ki(e.padding); let m = p.height, x = 0, b = s.reduce(((t, e) => t + e.before.length + e.lines.length + e.after.length), 0); if (b += t.beforeBody.length + t.afterBody.length, d && (m += d * h.lineHeight + (d - 1) * e.titleSpacing + e.titleMarginBottom), b) { m += g * (e.displayColors ? Math.max(r, l.lineHeight) : l.lineHeight) + (b - g) * l.lineHeight + (b - 1) * e.bodySpacing } f && (m += e.footerMarginTop + f * c.lineHeight + (f - 1) * e.footerSpacing); let _ = 0; const y = function (t) { x = Math.max(x, i.measureText(t).width + _) }; return i.save(), i.font = h.string, u(t.title, y), i.font = l.string, u(t.beforeBody.concat(t.afterBody), y), _ = e.displayColors ? a + 2 + e.boxPadding : 0, u(s, (t => { u(t.before, y), u(t.lines, y), u(t.after, y) })), _ = 0, i.font = c.string, u(t.footer, y), i.restore(), x += p.width, { width: x, height: m } } function La(t, e, i, s) { const { x: n, width: o } = i, { width: a, chartArea: { left: r, right: l } } = t; let h = "center"; return "center" === s ? h = n <= (r + l) / 2 ? "left" : "right" : n <= o / 2 ? h = "left" : n >= a - o / 2 && (h = "right"), function (t, e, i, s) { const { x: n, width: o } = s, a = i.caretSize + i.caretPadding; return "left" === t && n + o + a > e.width || "right" === t && n - o - a < 0 || void 0 }(h, t, e, i) && (h = "center"), h } function Ea(t, e, i) { const s = i.yAlign || e.yAlign || function (t, e) { const { y: i, height: s } = e; return i < s / 2 ? "top" : i > t.height - s / 2 ? "bottom" : "center" }(t, i); return { xAlign: i.xAlign || e.xAlign || La(t, e, i, s), yAlign: s } } function Ra(t, e, i, s) { const { caretSize: n, caretPadding: o, cornerRadius: a } = t, { xAlign: r, yAlign: l } = i, h = n + o, { topLeft: c, topRight: d, bottomLeft: u, bottomRight: f } = wi(a); let g = function (t, e) { let { x: i, width: s } = t; return "right" === e ? i -= s : "center" === e && (i -= s / 2), i }(e, r); const p = function (t, e, i) { let { y: s, height: n } = t; return "top" === e ? s += i : s -= "bottom" === e ? n + i : n / 2, s }(e, l, h); return "center" === l ? "left" === r ? g += h : "right" === r && (g -= h) : "left" === r ? g -= Math.max(c, u) + n : "right" === r && (g += Math.max(d, f) + n), { x: Z(g, 0, s.width - e.width), y: Z(p, 0, s.height - e.height) } } function Ia(t, e, i) { const s = ki(i.padding); return "center" === e ? t.x + t.width / 2 : "right" === e ? t.x + t.width - s.right : t.x + s.left } function za(t) { return Ca([], Oa(t)) } function Fa(t, e) { const i = e && e.dataset && e.dataset.tooltip && e.dataset.tooltip.callbacks; return i ? t.override(i) : t } const Va = { beforeTitle: e, title(t) { if (t.length > 0) { const e = t[0], i = e.chart.data.labels, s = i ? i.length : 0; if (this && this.options && "dataset" === this.options.mode) return e.dataset.label || ""; if (e.label) return e.label; if (s > 0 && e.dataIndex < s) return i[e.dataIndex] } return "" }, afterTitle: e, beforeBody: e, beforeLabel: e, label(t) { if (this && this.options && "dataset" === this.options.mode) return t.label + ": " + t.formattedValue || t.formattedValue; let e = t.dataset.label || ""; e && (e += ": "); const i = t.formattedValue; return s(i) || (e += i), e }, labelColor(t) { const e = t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex); return { borderColor: e.borderColor, backgroundColor: e.backgroundColor, borderWidth: e.borderWidth, borderDash: e.borderDash, borderDashOffset: e.borderDashOffset, borderRadius: 0 } }, labelTextColor() { return this.options.bodyColor }, labelPointStyle(t) { const e = t.chart.getDatasetMeta(t.datasetIndex).controller.getStyle(t.dataIndex); return { pointStyle: e.pointStyle, rotation: e.rotation } }, afterLabel: e, afterBody: e, beforeFooter: e, footer: e, afterFooter: e }; function Ba(t, e, i, s) { const n = t[e].call(i, s); return void 0 === n ? Va[e].call(i, s) : n } class Wa extends $s { static positioners = Da; constructor(t) { super(), this.opacity = 0, this._active = [], this._eventPosition = void 0, this._size = void 0, this._cachedAnimations = void 0, this._tooltipItems = [], this.$animations = void 0, this.$context = void 0, this.chart = t.chart, this.options = t.options, this.dataPoints = void 0, this.title = void 0, this.beforeBody = void 0, this.body = void 0, this.afterBody = void 0, this.footer = void 0, this.xAlign = void 0, this.yAlign = void 0, this.x = void 0, this.y = void 0, this.height = void 0, this.width = void 0, this.caretX = void 0, this.caretY = void 0, this.labelColors = void 0, this.labelPointStyles = void 0, this.labelTextColors = void 0 } initialize(t) { this.options = t, this._cachedAnimations = void 0, this.$context = void 0 } _resolveAnimations() { const t = this._cachedAnimations; if (t) return t; const e = this.chart, i = this.options.setContext(this.getContext()), s = i.enabled && e.options.animation && i.animations, n = new Ts(this.chart, s); return s._cacheable && (this._cachedAnimations = Object.freeze(n)), n } getContext() { return this.$context || (this.$context = (t = this.chart.getContext(), e = this, i = this._tooltipItems, Ci(t, { tooltip: e, tooltipItems: i, type: "tooltip" }))); var t, e, i } getTitle(t, e) { const { callbacks: i } = e, s = Ba(i, "beforeTitle", this, t), n = Ba(i, "title", this, t), o = Ba(i, "afterTitle", this, t); let a = []; return a = Ca(a, Oa(s)), a = Ca(a, Oa(n)), a = Ca(a, Oa(o)), a } getBeforeBody(t, e) { return za(Ba(e.callbacks, "beforeBody", this, t)) } getBody(t, e) { const { callbacks: i } = e, s = []; return u(t, (t => { const e = { before: [], lines: [], after: [] }, n = Fa(i, t); Ca(e.before, Oa(Ba(n, "beforeLabel", this, t))), Ca(e.lines, Ba(n, "label", this, t)), Ca(e.after, Oa(Ba(n, "afterLabel", this, t))), s.push(e) })), s } getAfterBody(t, e) { return za(Ba(e.callbacks, "afterBody", this, t)) } getFooter(t, e) { const { callbacks: i } = e, s = Ba(i, "beforeFooter", this, t), n = Ba(i, "footer", this, t), o = Ba(i, "afterFooter", this, t); let a = []; return a = Ca(a, Oa(s)), a = Ca(a, Oa(n)), a = Ca(a, Oa(o)), a } _createItems(t) { const e = this._active, i = this.chart.data, s = [], n = [], o = []; let a, r, l = []; for (a = 0, r = e.length; a < r; ++a)l.push(Aa(this.chart, e[a])); return t.filter && (l = l.filter(((e, s, n) => t.filter(e, s, n, i)))), t.itemSort && (l = l.sort(((e, s) => t.itemSort(e, s, i)))), u(l, (e => { const i = Fa(t.callbacks, e); s.push(Ba(i, "labelColor", this, e)), n.push(Ba(i, "labelPointStyle", this, e)), o.push(Ba(i, "labelTextColor", this, e)) })), this.labelColors = s, this.labelPointStyles = n, this.labelTextColors = o, this.dataPoints = l, l } update(t, e) { const i = this.options.setContext(this.getContext()), s = this._active; let n, o = []; if (s.length) { const t = Da[i.position].call(this, s, this._eventPosition); o = this._createItems(i), this.title = this.getTitle(o, i), this.beforeBody = this.getBeforeBody(o, i), this.body = this.getBody(o, i), this.afterBody = this.getAfterBody(o, i), this.footer = this.getFooter(o, i); const e = this._size = Ta(this, i), a = Object.assign({}, t, e), r = Ea(this.chart, i, a), l = Ra(i, a, r, this.chart); this.xAlign = r.xAlign, this.yAlign = r.yAlign, n = { opacity: 1, x: l.x, y: l.y, width: e.width, height: e.height, caretX: t.x, caretY: t.y } } else 0 !== this.opacity && (n = { opacity: 0 }); this._tooltipItems = o, this.$context = void 0, n && this._resolveAnimations().update(this, n), t && i.external && i.external.call(this, { chart: this.chart, tooltip: this, replay: e }) } drawCaret(t, e, i, s) { const n = this.getCaretPosition(t, i, s); e.lineTo(n.x1, n.y1), e.lineTo(n.x2, n.y2), e.lineTo(n.x3, n.y3) } getCaretPosition(t, e, i) { const { xAlign: s, yAlign: n } = this, { caretSize: o, cornerRadius: a } = i, { topLeft: r, topRight: l, bottomLeft: h, bottomRight: c } = wi(a), { x: d, y: u } = t, { width: f, height: g } = e; let p, m, x, b, _, y; return "center" === n ? (_ = u + g / 2, "left" === s ? (p = d, m = p - o, b = _ + o, y = _ - o) : (p = d + f, m = p + o, b = _ - o, y = _ + o), x = p) : (m = "left" === s ? d + Math.max(r, h) + o : "right" === s ? d + f - Math.max(l, c) - o : this.caretX, "top" === n ? (b = u, _ = b - o, p = m - o, x = m + o) : (b = u + g, _ = b + o, p = m + o, x = m - o), y = b), { x1: p, x2: m, x3: x, y1: b, y2: _, y3: y } } drawTitle(t, e, i) { const s = this.title, n = s.length; let o, a, r; if (n) { const l = Oi(i.rtl, this.x, this.width); for (t.x = Ia(this, i.titleAlign, i), e.textAlign = l.textAlign(i.titleAlign), e.textBaseline = "middle", o = Si(i.titleFont), a = i.titleSpacing, e.fillStyle = i.titleColor, e.font = o.string, r = 0; r < n; ++r)e.fillText(s[r], l.x(t.x), t.y + o.lineHeight / 2), t.y += o.lineHeight + a, r + 1 === n && (t.y += i.titleMarginBottom - a) } } _drawColorBox(t, e, i, s, n) { const a = this.labelColors[i], r = this.labelPointStyles[i], { boxHeight: l, boxWidth: h } = n, c = Si(n.bodyFont), d = Ia(this, "left", n), u = s.x(d), f = l < c.lineHeight ? (c.lineHeight - l) / 2 : 0, g = e.y + f; if (n.usePointStyle) { const e = { radius: Math.min(h, l) / 2, pointStyle: r.pointStyle, rotation: r.rotation, borderWidth: 1 }, i = s.leftForLtr(u, h) + h / 2, o = g + l / 2; t.strokeStyle = n.multiKeyBackground, t.fillStyle = n.multiKeyBackground, Le(t, e, i, o), t.strokeStyle = a.borderColor, t.fillStyle = a.backgroundColor, Le(t, e, i, o) } else { t.lineWidth = o(a.borderWidth) ? Math.max(...Object.values(a.borderWidth)) : a.borderWidth || 1, t.strokeStyle = a.borderColor, t.setLineDash(a.borderDash || []), t.lineDashOffset = a.borderDashOffset || 0; const e = s.leftForLtr(u, h), i = s.leftForLtr(s.xPlus(u, 1), h - 2), r = wi(a.borderRadius); Object.values(r).some((t => 0 !== t)) ? (t.beginPath(), t.fillStyle = n.multiKeyBackground, He(t, { x: e, y: g, w: h, h: l, radius: r }), t.fill(), t.stroke(), t.fillStyle = a.backgroundColor, t.beginPath(), He(t, { x: i, y: g + 1, w: h - 2, h: l - 2, radius: r }), t.fill()) : (t.fillStyle = n.multiKeyBackground, t.fillRect(e, g, h, l), t.strokeRect(e, g, h, l), t.fillStyle = a.backgroundColor, t.fillRect(i, g + 1, h - 2, l - 2)) } t.fillStyle = this.labelTextColors[i] } drawBody(t, e, i) { const { body: s } = this, { bodySpacing: n, bodyAlign: o, displayColors: a, boxHeight: r, boxWidth: l, boxPadding: h } = i, c = Si(i.bodyFont); let d = c.lineHeight, f = 0; const g = Oi(i.rtl, this.x, this.width), p = function (i) { e.fillText(i, g.x(t.x + f), t.y + d / 2), t.y += d + n }, m = g.textAlign(o); let x, b, _, y, v, M, w; for (e.textAlign = o, e.textBaseline = "middle", e.font = c.string, t.x = Ia(this, m, i), e.fillStyle = i.bodyColor, u(this.beforeBody, p), f = a && "right" !== m ? "center" === o ? l / 2 + h : l + 2 + h : 0, y = 0, M = s.length; y < M; ++y) { for (x = s[y], b = this.labelTextColors[y], e.fillStyle = b, u(x.before, p), _ = x.lines, a && _.length && (this._drawColorBox(e, t, y, g, i), d = Math.max(c.lineHeight, r)), v = 0, w = _.length; v < w; ++v)p(_[v]), d = c.lineHeight; u(x.after, p) } f = 0, d = c.lineHeight, u(this.afterBody, p), t.y -= n } drawFooter(t, e, i) { const s = this.footer, n = s.length; let o, a; if (n) { const r = Oi(i.rtl, this.x, this.width); for (t.x = Ia(this, i.footerAlign, i), t.y += i.footerMarginTop, e.textAlign = r.textAlign(i.footerAlign), e.textBaseline = "middle", o = Si(i.footerFont), e.fillStyle = i.footerColor, e.font = o.string, a = 0; a < n; ++a)e.fillText(s[a], r.x(t.x), t.y + o.lineHeight / 2), t.y += o.lineHeight + i.footerSpacing } } drawBackground(t, e, i, s) { const { xAlign: n, yAlign: o } = this, { x: a, y: r } = t, { width: l, height: h } = i, { topLeft: c, topRight: d, bottomLeft: u, bottomRight: f } = wi(s.cornerRadius); e.fillStyle = s.backgroundColor, e.strokeStyle = s.borderColor, e.lineWidth = s.borderWidth, e.beginPath(), e.moveTo(a + c, r), "top" === o && this.drawCaret(t, e, i, s), e.lineTo(a + l - d, r), e.quadraticCurveTo(a + l, r, a + l, r + d), "center" === o && "right" === n && this.drawCaret(t, e, i, s), e.lineTo(a + l, r + h - f), e.quadraticCurveTo(a + l, r + h, a + l - f, r + h), "bottom" === o && this.drawCaret(t, e, i, s), e.lineTo(a + u, r + h), e.quadraticCurveTo(a, r + h, a, r + h - u), "center" === o && "left" === n && this.drawCaret(t, e, i, s), e.lineTo(a, r + c), e.quadraticCurveTo(a, r, a + c, r), e.closePath(), e.fill(), s.borderWidth > 0 && e.stroke() } _updateAnimationTarget(t) { const e = this.chart, i = this.$animations, s = i && i.x, n = i && i.y; if (s || n) { const i = Da[t.position].call(this, this._active, this._eventPosition); if (!i) return; const o = this._size = Ta(this, t), a = Object.assign({}, i, this._size), r = Ea(e, t, a), l = Ra(t, a, r, e); s._to === l.x && n._to === l.y || (this.xAlign = r.xAlign, this.yAlign = r.yAlign, this.width = o.width, this.height = o.height, this.caretX = i.x, this.caretY = i.y, this._resolveAnimations().update(this, l)) } } _willRender() { return !!this.opacity } draw(t) { const e = this.options.setContext(this.getContext()); let i = this.opacity; if (!i) return; this._updateAnimationTarget(e); const s = { width: this.width, height: this.height }, n = { x: this.x, y: this.y }; i = Math.abs(i) < .001 ? 0 : i; const o = ki(e.padding), a = this.title.length || this.beforeBody.length || this.body.length || this.afterBody.length || this.footer.length; e.enabled && a && (t.save(), t.globalAlpha = i, this.drawBackground(n, t, s, e), Ai(t, e.textDirection), n.y += o.top, this.drawTitle(n, t, e), this.drawBody(n, t, e), this.drawFooter(n, t, e), Ti(t, e.textDirection), t.restore()) } getActiveElements() { return this._active || [] } setActiveElements(t, e) { const i = this._active, s = t.map((({ datasetIndex: t, index: e }) => { const i = this.chart.getDatasetMeta(t); if (!i) throw new Error("Cannot find a dataset at index " + t); return { datasetIndex: t, element: i.data[e], index: e } })), n = !f(i, s), o = this._positionChanged(s, e); (n || o) && (this._active = s, this._eventPosition = e, this._ignoreReplayEvents = !0, this.update(!0)) } handleEvent(t, e, i = !0) { if (e && this._ignoreReplayEvents) return !1; this._ignoreReplayEvents = !1; const s = this.options, n = this._active || [], o = this._getActiveElements(t, n, e, i), a = this._positionChanged(o, t), r = e || !f(o, n) || a; return r && (this._active = o, (s.enabled || s.external) && (this._eventPosition = { x: t.x, y: t.y }, this.update(!0, e))), r } _getActiveElements(t, e, i, s) { const n = this.options; if ("mouseout" === t.type) return []; if (!s) return e.filter((t => this.chart.data.datasets[t.datasetIndex] && void 0 !== this.chart.getDatasetMeta(t.datasetIndex).controller.getParsed(t.index))); const o = this.chart.getElementsAtEventForMode(t, n.mode, n, i); return n.reverse && o.reverse(), o } _positionChanged(t, e) { const { caretX: i, caretY: s, options: n } = this, o = Da[n.position].call(this, t, e); return !1 !== o && (i !== o.x || s !== o.y) } } var Na = { id: "tooltip", _element: Wa, positioners: Da, afterInit(t, e, i) { i && (t.tooltip = new Wa({ chart: t, options: i })) }, beforeUpdate(t, e, i) { t.tooltip && t.tooltip.initialize(i) }, reset(t, e, i) { t.tooltip && t.tooltip.initialize(i) }, afterDraw(t) { const e = t.tooltip; if (e && e._willRender()) { const i = { tooltip: e }; if (!1 === t.notifyPlugins("beforeTooltipDraw", { ...i, cancelable: !0 })) return; e.draw(t.ctx), t.notifyPlugins("afterTooltipDraw", i) } }, afterEvent(t, e) { if (t.tooltip) { const i = e.replay; t.tooltip.handleEvent(e.event, i, e.inChartArea) && (e.changed = !0) } }, defaults: { enabled: !0, external: null, position: "average", backgroundColor: "rgba(0,0,0,0.8)", titleColor: "#fff", titleFont: { weight: "bold" }, titleSpacing: 2, titleMarginBottom: 6, titleAlign: "left", bodyColor: "#fff", bodySpacing: 2, bodyFont: {}, bodyAlign: "left", footerColor: "#fff", footerSpacing: 2, footerMarginTop: 6, footerFont: { weight: "bold" }, footerAlign: "left", padding: 6, caretPadding: 2, caretSize: 5, cornerRadius: 6, boxHeight: (t, e) => e.bodyFont.size, boxWidth: (t, e) => e.bodyFont.size, multiKeyBackground: "#fff", displayColors: !0, boxPadding: 0, borderColor: "rgba(0,0,0,0)", borderWidth: 0, animation: { duration: 400, easing: "easeOutQuart" }, animations: { numbers: { type: "number", properties: ["x", "y", "width", "height", "caretX", "caretY"] }, opacity: { easing: "linear", duration: 200 } }, callbacks: Va }, defaultRoutes: { bodyFont: "font", footerFont: "font", titleFont: "font" }, descriptors: { _scriptable: t => "filter" !== t && "itemSort" !== t && "external" !== t, _indexable: !1, callbacks: { _scriptable: !1, _indexable: !1 }, animation: { _fallback: !1 }, animations: { _fallback: "animation" } }, additionalOptionScopes: ["interaction"] }; return Tn.register(Un, $o, go, t), Tn.helpers = { ...Hi }, Tn._adapters = In, Tn.Animation = As, Tn.Animations = Ts, Tn.animator = bt, Tn.controllers = nn.controllers.items, Tn.DatasetController = js, Tn.Element = $s, Tn.elements = go, Tn.Interaction = Ki, Tn.layouts = ls, Tn.platforms = Ds, Tn.Scale = tn, Tn.Ticks = ae, Object.assign(Tn, Un, $o, go, t, Ds), Tn.Chart = Tn, "undefined" != typeof window && (window.Chart = Tn), Tn +})); +//# sourceMappingURL=chart.umd.min.js.map diff --git a/RotaxMonitor/data/index.html b/RotaxMonitor/data/index.html index 71aa277..1ced547 100644 --- a/RotaxMonitor/data/index.html +++ b/RotaxMonitor/data/index.html @@ -13,176 +13,194 @@
-

Rotax Ignition Box Monitor

-
- Waiting for data... + +
+ +
-
-
-

Box_A

-
-

Timestamp: -

-

Data Valid: -

-

Generator voltage: -

-

ADC read time: -

-

Queue errors: -

-
-
- Engine RPM: - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyPickup 12Pickup 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Spark Events--
Missed Events--
+ +
+ +
+ Waiting for data...
-
-

Box_B

-
-

Timestamp: -

-

Data Valid: -

-

Generator voltage: -

-

ADC read time: -

-

Queue errors: -

+
+
+

Box_A

+
+

Timestamp: -

+

Data Valid: -

+

Generator voltage: -

+

ADC read time: -

+

Queue errors: -

+
+
+ Engine RPM: - +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyPickup 12Pickup 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Spark Events--
Missed Events--
-
- Engine RPM: - + +
+

Box_B

+
+

Timestamp: -

+

Data Valid: -

+

Generator voltage: -

+

ADC read time: -

+

Queue errors: -

+
+
+ Engine RPM: - +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyPickup 12Pickup 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Spark Events--
Missed Events--
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyPickup 12Pickup 34
Spark delay--
Spark status--
Soft start status--
Peak P in--
Peak N in--
Peak P out--
Peak N out--
Level spark--
Spark Events--
Missed Events--
+
+ + +
+
-
-

Upload file to Flash

-

Select a file and upload it to Flash.

- - -
No file uploaded yet.
-
- + +
+

Upload file to Flash

+

Select a file and upload it to Flash.

+ + +
No file uploaded yet.
+
+ + + + \ No newline at end of file diff --git a/RotaxMonitor/data/script.js b/RotaxMonitor/data/script.js index 7ab466c..13913ab 100644 --- a/RotaxMonitor/data/script.js +++ b/RotaxMonitor/data/script.js @@ -3,6 +3,19 @@ let lastMessageTimestamp = 0; const IDLE_THRESHOLD_MS = 1000; const loadingIndicator = document.getElementById("loadingIndicator"); +let chart; +let chartData = { + labels: [], + datasets: [ + { label: "BoxA RPM", data: [] }, + { label: "BoxB RPM", data: [] }, + { label: "Coils12A Delay", data: [] }, + { label: "Coils34A Delay", data: [] }, + { label: "Coils12B Delay", data: [] }, + { label: "Coils34B Delay", data: [] } + ] +}; + function setLoadingIndicator(visible) { if (!loadingIndicator) { return; @@ -46,6 +59,8 @@ function connectWS() { lastMessageTimestamp = Date.now(); setLoadingIndicator(false); + updateChart(data) + // Update Box_A if (data.box_a) { const boxA = data.box_a; @@ -118,6 +133,38 @@ function connectWS() { }; } +function updateChart(data) { + const time = new Date().toLocaleTimeString(); + + chartData.labels.push(time); + + if (data.box_a) { + const boxA = data.box_a; + const coils12A = boxA.coils12 || {}; + const coils34A = boxA.coils34 || {}; + chartData.datasets[0].data.push(boxA.eng_rpm/10); + chartData.datasets[2].data.push(coils12A.spark_delay); + chartData.datasets[3].data.push(coils34A.spark_delay); + } + + if (data.box_b) { + const boxB = data.box_b; + const coils12B = boxB.coils12 || {}; + const coils34B = boxB.coils34 || {}; + chartData.datasets[1].data.push(boxB.eng_rpm/10); + chartData.datasets[4].data.push(coils12B.spark_delay); + chartData.datasets[5].data.push(coils34B.spark_delay); + } + + // limite punti (tipo buffer) + if (chartData.labels.length > 50) { + chartData.labels.shift(); + chartData.datasets.forEach(d => d.data.shift()); + } + + chart.update(); +} + function start() { fetch("/start"); } @@ -160,5 +207,44 @@ function uploadLittleFS() { }); } +function openTab(tabId) { + document.querySelectorAll('.tab-content').forEach(tab => { + tab.classList.remove('active'); + }); + + document.querySelectorAll('.tab-button').forEach(btn => { + btn.classList.remove('active'); + }); + + document.getElementById(tabId).classList.add('active'); + + event.target.classList.add('active'); +} + +function initChart() { + const ctx = document.getElementById('chart').getContext('2d'); + + chart = new Chart(ctx, { + type: 'line', + data: chartData, + options: { + animation: false, + responsive: true, + scales: { + x: { + display: true + }, + y: { + beginAtZero: true + } + } + } + }); +} + +window.onload = () => { + initChart(); +}; + setInterval(updateLoadingState, 200); connectWS(); diff --git a/RotaxMonitor/data/style.css b/RotaxMonitor/data/style.css index 749df1f..08930a0 100644 --- a/RotaxMonitor/data/style.css +++ b/RotaxMonitor/data/style.css @@ -219,3 +219,32 @@ button:hover { span { color: var(--text-dark); } + +/* TABS */ +.tabs { + display: flex; + justify-content: center; + margin: 20px; +} + +.tab-button { + padding: 10px 20px; + margin: 0 5px; + border: none; + cursor: pointer; + background: var(--border-color); + border-radius: 4px; +} + +.tab-button.active { + background: var(--primary-blue); + color: white; +} + +.tab-content { + display: none; +} + +.tab-content.active { + display: block; +} From 7da58c8a4946c487284db685b5914cce466a8e25 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sun, 12 Apr 2026 14:40:58 +0200 Subject: [PATCH 28/38] Set time from browser --- RotaxMonitor/data/script.js | 9 ++- RotaxMonitor/src/main.cpp | 3 +- RotaxMonitor/src/utils.cpp | 9 ++- RotaxMonitor/src/webserver.cpp | 104 ++++++++++++++++++++++++--------- RotaxMonitor/src/webserver.h | 31 ++++++---- 5 files changed, 114 insertions(+), 42 deletions(-) diff --git a/RotaxMonitor/data/script.js b/RotaxMonitor/data/script.js index 13913ab..573dcdf 100644 --- a/RotaxMonitor/data/script.js +++ b/RotaxMonitor/data/script.js @@ -38,6 +38,11 @@ function connectWS() { console.log("WebSocket connesso"); lastMessageTimestamp = Date.now(); setLoadingIndicator(false); + + ws.send(JSON.stringify({ + cmd: "setTime", + time: Math.floor(Date.now() / 1000) + })); }; ws.onclose = () => { @@ -142,7 +147,7 @@ function updateChart(data) { const boxA = data.box_a; const coils12A = boxA.coils12 || {}; const coils34A = boxA.coils34 || {}; - chartData.datasets[0].data.push(boxA.eng_rpm/10); + chartData.datasets[0].data.push(boxA.eng_rpm / 10); chartData.datasets[2].data.push(coils12A.spark_delay); chartData.datasets[3].data.push(coils34A.spark_delay); } @@ -151,7 +156,7 @@ function updateChart(data) { const boxB = data.box_b; const coils12B = boxB.coils12 || {}; const coils34B = boxB.coils34 || {}; - chartData.datasets[1].data.push(boxB.eng_rpm/10); + chartData.datasets[1].data.push(boxB.eng_rpm / 10); chartData.datasets[4].data.push(coils12B.spark_delay); chartData.datasets[5].data.push(coils34B.spark_delay); } diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index daa940e..b8b6f5a 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -210,7 +210,7 @@ void loop() LOG_DEBUG("Real Time Tasks A & B initialized"); led.setStatus(RGBled::LedStatus::OK); - WebPage webPage(80, LittleFS); // Initialize webserver and Websocket + AstroWebServer webPage(80, LittleFS); // Initialize webserver and Websocket task_A.onMessage([&webPage](ignitionBoxStatusFiltered sts){ ArduinoJson::JsonDocument doc; @@ -237,6 +237,7 @@ void loop() { clearScreen(); printRunningTasksMod(Serial); + delay(100); last_loop = millis(); } } //////////////// INNER LOOP ///////////////////// diff --git a/RotaxMonitor/src/utils.cpp b/RotaxMonitor/src/utils.cpp index 1e59492..46951fd 100644 --- a/RotaxMonitor/src/utils.cpp +++ b/RotaxMonitor/src/utils.cpp @@ -99,7 +99,14 @@ void printRunningTasksMod(Print &printer, std::function +#include -WebPage::WebPage(const uint8_t port, fs::FS &filesystem) : m_port(port), m_webserver(AsyncWebServer(port)), m_websocket(AsyncWebSocket("/ws")), m_filesystem(filesystem) +static const std::map s_webserverCommands = { + {"setTime", AstroWebServer::SET_TIME}, +}; + +AstroWebServer::AstroWebServer(const uint8_t port, fs::FS &filesystem) : m_port(port), m_webserver(AsyncWebServer(port)), m_websocket(AsyncWebSocket("/ws")), m_filesystem(filesystem) { LOG_DEBUG("Initializing Web Server"); m_websocket.onEvent([this](AsyncWebSocket *server, AsyncWebSocketClient *client, @@ -10,62 +15,107 @@ WebPage::WebPage(const uint8_t port, fs::FS &filesystem) : m_port(port), m_webse m_webserver.addHandler(&m_websocket); m_webserver.serveStatic("/", m_filesystem, "/").setDefaultFile("index.html"); - m_webserver.on("/upload", HTTP_POST, - [this](AsyncWebServerRequest *request) - { onUploadRequest(request); }, - [this](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) - { onUploadHandler(request, filename, index, data, len, final); } - ); + m_webserver.on("/upload", HTTP_POST, [this](AsyncWebServerRequest *request) + { onUploadRequest(request); }, [this](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) + { onUploadHandler(request, filename, index, data, len, final); }); m_webserver.begin(); LOG_DEBUG("Webserver Init OK"); } -WebPage::~WebPage() +AstroWebServer::~AstroWebServer() { m_webserver.removeHandler(&m_websocket); m_webserver.end(); } -void WebPage::sendWsData(const String &data){ - if (m_websocket.count()){ +void AstroWebServer::sendWsData(const String &data) +{ + if (m_websocket.count()) + { m_websocket.textAll(data); } } -void WebPage::onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) +void AstroWebServer::onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { switch (type) { case WS_EVT_CONNECT: - Serial.printf("WS client IP[%s]-ID[%u] CONNECTED\r\n", client->remoteIP().toString().c_str(), client->id()); + LOG_DEBUG("WS client IP[", client->remoteIP().toString().c_str(), "]-ID[", client->id(), "] CONNECTED"); break; case WS_EVT_DISCONNECT: - Serial.printf("WS client ID[%u] DISCONNECTED\r\n", client->remoteIP().toString().c_str(), client->id()); + LOG_DEBUG("WS client IP[", client->remoteIP().toString().c_str(), "]-ID[", client->id(), "] DISCONNECTED"); break; + case WS_EVT_DATA: + { + AwsFrameInfo *info = (AwsFrameInfo *)arg; + if (info->final && info->index == 0 && info->len == len) + { + std::string data_str((char *)data, len); + ArduinoJson::JsonDocument doc; + if (auto rv = ArduinoJson::deserializeJson(doc, data_str) != ArduinoJson::DeserializationError::Ok) + { + LOG_ERROR("WS Client unable to deserialize Json"); + return; + } + if (!doc["cmd"].is() || !s_webserverCommands.contains(doc["cmd"])) + { + LOG_WARN("WS Client Invalid Json command [", doc["cmd"].as().c_str(), "]"); + return; + } + std::string buffer; + switch (s_webserverCommands.at(doc["cmd"])) + { + case SET_TIME: + { + auto epoch = doc["time"].as(); + timeval te{ + .tv_sec = epoch, + .tv_usec = 0, + }; + timezone tz{ + .tz_minuteswest = 0, + .tz_dsttime = DST_MET, + }; + settimeofday(&te, &tz); + time_t now = time(nullptr); + struct tm *t = localtime(&now); + buffer.resize(64); + strftime(buffer.data(), sizeof(buffer), "%Y-%m-%d %H:%M:%S", t); + LOG_DEBUG("WS Client set Datetime to: ", buffer.c_str()); + break; + } + + default: + // call external command callback + break; + } + } + } } } -void WebPage::onUploadRequest(AsyncWebServerRequest *request) +void AstroWebServer::onUploadRequest(AsyncWebServerRequest *request) { - if (m_upload_failed) + if (m_uploadFailed) request->send(500, "text/plain", "Upload failed"); else request->send(200, "text/plain", "Upload successful"); } -void WebPage::onUploadHandler(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) +void AstroWebServer::onUploadHandler(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) { if (index == 0) // only on first iteration to open file { - m_upload_failed = false; + m_uploadFailed = false; String safeName = filename; int slashIndex = safeName.lastIndexOf('/'); if (slashIndex >= 0) safeName = safeName.substring(slashIndex + 1); if (safeName.length() == 0) { - m_upload_failed = true; + m_uploadFailed = true; LOG_ERROR("Invalid file name"); return; } @@ -74,27 +124,27 @@ void WebPage::onUploadHandler(AsyncWebServerRequest *request, const String &file if (m_filesystem.exists(filePath.c_str())) m_filesystem.remove(filePath.c_str()); - m_upload_file = m_filesystem.open(filePath.c_str(), FILE_WRITE); - if (!m_upload_file) + m_uploadFile = m_filesystem.open(filePath.c_str(), FILE_WRITE); + if (!m_uploadFile) { - m_upload_failed = true; + m_uploadFailed = true; LOG_ERROR("Failed to open upload file:", filePath.c_str()); return; } } // Actual write of file data - if (!m_upload_failed && m_upload_file) + if (!m_uploadFailed && m_uploadFile) { - if (m_upload_file.write(data, len) != len) - m_upload_failed = true; + if (m_uploadFile.write(data, len) != len) + m_uploadFailed = true; } // close the file and save on final call - if (final && m_upload_file) + if (final && m_uploadFile) { - m_upload_file.close(); - if (!m_upload_failed) + m_uploadFile.close(); + if (!m_uploadFailed) LOG_INFO("Uploaded file to LittleFS:", filename.c_str()); } } diff --git a/RotaxMonitor/src/webserver.h b/RotaxMonitor/src/webserver.h index 5e230f3..3eb8aac 100644 --- a/RotaxMonitor/src/webserver.h +++ b/RotaxMonitor/src/webserver.h @@ -1,5 +1,5 @@ #pragma once -#define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO +#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG // System includes #include @@ -7,26 +7,22 @@ #include #include #include +#include + #include -class WebPage +class AstroWebServer { - const uint8_t m_port = 80; - fs::FS &m_filesystem; - AsyncWebServer m_webserver; - AsyncWebSocket m_websocket; - bool m_upload_failed = false; - fs::File m_upload_file; public: - WebPage(const uint8_t port, fs::FS &filesystem); - ~WebPage(); + AstroWebServer(const uint8_t port, fs::FS &filesystem); + ~AstroWebServer(); void sendWsData(const String &data); private: void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, - AwsEventType type, void *arg, uint8_t *data, size_t len); + AwsEventType type, void *arg, uint8_t *data, size_t len); void onUploadRequest(AsyncWebServerRequest *request); void onUploadHandler(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final); @@ -35,4 +31,17 @@ private: void onStop(AsyncWebServerRequest *request); void onDownload(AsyncWebServerRequest *request); +private: + const uint8_t m_port = 80; + fs::FS &m_filesystem; + AsyncWebServer m_webserver; + AsyncWebSocket m_websocket; + bool m_uploadFailed = false; + fs::File m_uploadFile; + +public: + enum c_commandEnum + { + SET_TIME + }; }; From f8c3c69e806fce05ee3f0c84534bb1a230c04dc1 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sun, 12 Apr 2026 14:42:40 +0200 Subject: [PATCH 29/38] fix graph --- RotaxMonitor/data/script.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/RotaxMonitor/data/script.js b/RotaxMonitor/data/script.js index 573dcdf..a115e8e 100644 --- a/RotaxMonitor/data/script.js +++ b/RotaxMonitor/data/script.js @@ -150,6 +150,9 @@ function updateChart(data) { chartData.datasets[0].data.push(boxA.eng_rpm / 10); chartData.datasets[2].data.push(coils12A.spark_delay); chartData.datasets[3].data.push(coils34A.spark_delay); + chartData.datasets[1].data.push(0); + chartData.datasets[4].data.push(0); + chartData.datasets[5].data.push(0); } if (data.box_b) { @@ -159,10 +162,13 @@ function updateChart(data) { chartData.datasets[1].data.push(boxB.eng_rpm / 10); chartData.datasets[4].data.push(coils12B.spark_delay); chartData.datasets[5].data.push(coils34B.spark_delay); + chartData.datasets[0].data.push(0); + chartData.datasets[2].data.push(0); + chartData.datasets[3].data.push(0); } // limite punti (tipo buffer) - if (chartData.labels.length > 50) { + if (chartData.labels.length > 100) { chartData.labels.shift(); chartData.datasets.forEach(d => d.data.shift()); } From 212b37c95f31ee8f4558f6780f57a451dc6abd91 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Mon, 13 Apr 2026 10:26:55 +0200 Subject: [PATCH 30/38] updated and fixed charts --- RotaxMonitor/data/index.html | 14 +++-- RotaxMonitor/data/script.js | 111 +++++++++++++++++++++------------ RotaxMonitor/data/style.css | 9 +++ RotaxMonitor/src/main.cpp | 42 +++++++------ RotaxMonitor/src/tasks.cpp | 2 +- RotaxMonitor/src/webserver.cpp | 18 +++++- RotaxMonitor/src/webserver.h | 1 + 7 files changed, 132 insertions(+), 65 deletions(-) diff --git a/RotaxMonitor/data/index.html b/RotaxMonitor/data/index.html index 1ced547..1f56e79 100644 --- a/RotaxMonitor/data/index.html +++ b/RotaxMonitor/data/index.html @@ -185,11 +185,17 @@
- +
+

Box A

+ +
+ +
+

Box B

+ +
- -
@@ -200,7 +206,7 @@
No file uploaded yet.
+ - \ No newline at end of file diff --git a/RotaxMonitor/data/script.js b/RotaxMonitor/data/script.js index a115e8e..ffb4a5f 100644 --- a/RotaxMonitor/data/script.js +++ b/RotaxMonitor/data/script.js @@ -3,16 +3,23 @@ let lastMessageTimestamp = 0; const IDLE_THRESHOLD_MS = 1000; const loadingIndicator = document.getElementById("loadingIndicator"); -let chart; -let chartData = { +let chartA, chartB; + +let dataA = { labels: [], datasets: [ - { label: "BoxA RPM", data: [] }, - { label: "BoxB RPM", data: [] }, - { label: "Coils12A Delay", data: [] }, - { label: "Coils34A Delay", data: [] }, - { label: "Coils12B Delay", data: [] }, - { label: "Coils34B Delay", data: [] } + { label: "RPM", data: [] }, + { label: "Coils12 Delay", data: [] }, + { label: "Coils34 Delay", data: [] } + ] +}; + +let dataB = { + labels: [], + datasets: [ + { label: "RPM", data: [] }, + { label: "Coils12 Delay", data: [] }, + { label: "Coils34 Delay", data: [] } ] }; @@ -64,7 +71,7 @@ function connectWS() { lastMessageTimestamp = Date.now(); setLoadingIndicator(false); - updateChart(data) + updateCharts(data) // Update Box_A if (data.box_a) { @@ -138,42 +145,49 @@ function connectWS() { }; } -function updateChart(data) { - const time = new Date().toLocaleTimeString(); +function updateCharts(data) { - chartData.labels.push(time); + const t = new Date().toLocaleTimeString(); + // ===== BOX A ===== + dataA.labels.push(t); if (data.box_a) { - const boxA = data.box_a; - const coils12A = boxA.coils12 || {}; - const coils34A = boxA.coils34 || {}; - chartData.datasets[0].data.push(boxA.eng_rpm / 10); - chartData.datasets[2].data.push(coils12A.spark_delay); - chartData.datasets[3].data.push(coils34A.spark_delay); - chartData.datasets[1].data.push(0); - chartData.datasets[4].data.push(0); - chartData.datasets[5].data.push(0); + dataA.datasets[0].data.push(data.box_a.eng_rpm / 10); + dataA.datasets[1].data.push(data.box_a.coils12.spark_delay); + dataA.datasets[2].data.push(data.box_a.coils34.spark_delay); + } else { + dataA.datasets[0].data.push(undefined); + dataA.datasets[1].data.push(undefined); + dataA.datasets[2].data.push(undefined); } + // ===== BOX B ===== + dataB.labels.push(t); if (data.box_b) { - const boxB = data.box_b; - const coils12B = boxB.coils12 || {}; - const coils34B = boxB.coils34 || {}; - chartData.datasets[1].data.push(boxB.eng_rpm / 10); - chartData.datasets[4].data.push(coils12B.spark_delay); - chartData.datasets[5].data.push(coils34B.spark_delay); - chartData.datasets[0].data.push(0); - chartData.datasets[2].data.push(0); - chartData.datasets[3].data.push(0); + dataB.datasets[0].data.push(data.box_b.eng_rpm / 10); + dataB.datasets[1].data.push(data.box_b.coils12.spark_delay); + dataB.datasets[2].data.push(data.box_b.coils34.spark_delay); + } else { + dataB.datasets[0].data.push(undefined); + dataB.datasets[1].data.push(undefined); + dataB.datasets[2].data.push(undefined); } - // limite punti (tipo buffer) - if (chartData.labels.length > 100) { - chartData.labels.shift(); - chartData.datasets.forEach(d => d.data.shift()); + // limite buffer + const maxPoints = 100; + + if (dataA.labels.length > maxPoints) { + dataA.labels.shift(); + dataA.datasets.forEach(d => d.data.shift()); } - chart.update(); + if (dataB.labels.length > maxPoints) { + dataB.labels.shift(); + dataB.datasets.forEach(d => d.data.shift()); + } + + chartA.update(); + chartB.update(); } function start() { @@ -232,12 +246,29 @@ function openTab(tabId) { event.target.classList.add('active'); } -function initChart() { - const ctx = document.getElementById('chart').getContext('2d'); +function initCharts() { + const ctxA = document.getElementById('chartA').getContext('2d'); + const ctxB = document.getElementById('chartB').getContext('2d'); - chart = new Chart(ctx, { + chartA = new Chart(ctxA, { type: 'line', - data: chartData, + data: dataA, + options: { + animation: false, + responsive: true, + scales: { + x: { + display: true + }, + y: { + beginAtZero: true + } + } + } + }); + chartB = new Chart(ctxB, { + type: 'line', + data: dataB, options: { animation: false, responsive: true, @@ -254,7 +285,7 @@ function initChart() { } window.onload = () => { - initChart(); + initCharts(); }; setInterval(updateLoadingState, 200); diff --git a/RotaxMonitor/data/style.css b/RotaxMonitor/data/style.css index 08930a0..f64ff04 100644 --- a/RotaxMonitor/data/style.css +++ b/RotaxMonitor/data/style.css @@ -248,3 +248,12 @@ span { .tab-content.active { display: block; } + +.chart-container { + max-width: 1000px; + margin: 20px auto; + background: white; + padding: 20px; + border-radius: 6px; + box-shadow: 0 1px 3px rgba(0,0,0,0.08); +} \ No newline at end of file diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index b8b6f5a..0451ba0 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -52,7 +52,7 @@ void setup() IPAddress gateway(10, 11, 12, 1); IPAddress subnet(255, 255, 255, 0); WiFi.softAPConfig(local_IP, gateway, subnet); - WiFi.setTxPower(WIFI_POWER_5dBm); // reduce wifi power + WiFi.setTxPower(WIFI_POWER_13dBm); // reduce wifi power if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD)) { LOG_INFO("WiFi AP Mode Started"); @@ -184,7 +184,7 @@ void loop() .rt_queue = nullptr, .dev = dev}; - auto task_A = rtIgnitionTask(taskA_params, 4096, 256, CORE_1, fs_mutex); + auto task_A = rtIgnitionTask(taskA_params, 4096, 256, CORE_0, fs_mutex); delay(50); auto task_B = rtIgnitionTask(taskB_params, 4096, 256, CORE_1, fs_mutex); @@ -211,34 +211,38 @@ void loop() led.setStatus(RGBled::LedStatus::OK); AstroWebServer webPage(80, LittleFS); // Initialize webserver and Websocket - - task_A.onMessage([&webPage](ignitionBoxStatusFiltered sts){ - ArduinoJson::JsonDocument doc; - doc["box_a"] = sts.toJson(); - doc["box_b"] = ArduinoJson::JsonDocument(); - webPage.sendWsData(doc.as()); + ArduinoJson::JsonDocument json_data; + bool data_a, data_b; + task_A.onMessage([&webPage, &json_data, &data_a](ignitionBoxStatusFiltered sts){ + json_data["box_a"] = sts.toJson(); + data_a = true; }); - task_B.onMessage([&webPage](ignitionBoxStatusFiltered sts){ - ArduinoJson::JsonDocument doc; - doc["box_a"] = ArduinoJson::JsonDocument(); - doc["box_b"] = sts.toJson(); - webPage.sendWsData(doc.as()); + task_B.onMessage([&webPage, &json_data, &data_b](ignitionBoxStatusFiltered sts){ + json_data["box_b"] = sts.toJson(); + data_b = true; }); - task_A.enableSave(true, "ignitionA_test.csv"); - task_B.enableSave(true, "ignitionB_test.csv"); + // task_A.enableSave(true, "ignitionA_test.csv"); + // task_B.enableSave(true, "ignitionB_test.csv"); - uint32_t last_loop = millis(); + uint32_t monitor_loop = millis(); + uint32_t data_loop = monitor_loop; //////////////// INNER LOOP ///////////////////// while (running) { - if ((millis() - last_loop) > 2000) + uint32_t this_loop = millis(); + if (this_loop - monitor_loop > 2000) { clearScreen(); printRunningTasksMod(Serial); - delay(100); - last_loop = millis(); + monitor_loop = millis(); + } + if ((data_a && data_b) || (this_loop - data_loop > 500)) { + webPage.sendWsData(json_data.as()); + json_data.clear(); + data_a = data_b = false; + data_loop = millis(); } } //////////////// INNER LOOP ///////////////////// diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index bcc7859..f691590 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -360,7 +360,7 @@ void rtIgnitionTask::run() m_info_filtered.update(m_last_status); (*m_active_history)[m_counter_status] = m_last_status; - if (m_on_message_cb && m_counter_status % 10) + if (m_on_message_cb && m_counter_status % 10 == 0) { m_on_message_cb(m_info_filtered); } diff --git a/RotaxMonitor/src/webserver.cpp b/RotaxMonitor/src/webserver.cpp index 82ab122..086f485 100644 --- a/RotaxMonitor/src/webserver.cpp +++ b/RotaxMonitor/src/webserver.cpp @@ -1,10 +1,19 @@ #include #include -static const std::map s_webserverCommands = { +static std::map s_webserverCommands = { {"setTime", AstroWebServer::SET_TIME}, }; +void on_ping(TimerHandle_t xTimer) +{ + if (!xTimer) + return; + auto ws = (AsyncWebSocket *)pvTimerGetTimerID(xTimer); + ws->pingAll(); + ws->cleanupClients(); +} + AstroWebServer::AstroWebServer(const uint8_t port, fs::FS &filesystem) : m_port(port), m_webserver(AsyncWebServer(port)), m_websocket(AsyncWebSocket("/ws")), m_filesystem(filesystem) { LOG_DEBUG("Initializing Web Server"); @@ -20,11 +29,15 @@ AstroWebServer::AstroWebServer(const uint8_t port, fs::FS &filesystem) : m_port( { onUploadHandler(request, filename, index, data, len, final); }); m_webserver.begin(); + m_websocket.enable(true); + + m_pingTimer = xTimerCreate("wsPingTimer", pdMS_TO_TICKS(2000), pdTRUE, (void *)&m_websocket, on_ping); LOG_DEBUG("Webserver Init OK"); } AstroWebServer::~AstroWebServer() { + xTimerDelete(m_pingTimer, pdMS_TO_TICKS(10)); m_webserver.removeHandler(&m_websocket); m_webserver.end(); } @@ -47,6 +60,9 @@ void AstroWebServer::onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *cli case WS_EVT_DISCONNECT: LOG_DEBUG("WS client IP[", client->remoteIP().toString().c_str(), "]-ID[", client->id(), "] DISCONNECTED"); break; + case WS_EVT_PONG: + LOG_DEBUG("WS client IP[", client->remoteIP().toString().c_str(), "]-ID[", client->id(), "] PONG"); + break; case WS_EVT_DATA: { AwsFrameInfo *info = (AwsFrameInfo *)arg; diff --git a/RotaxMonitor/src/webserver.h b/RotaxMonitor/src/webserver.h index 3eb8aac..c461787 100644 --- a/RotaxMonitor/src/webserver.h +++ b/RotaxMonitor/src/webserver.h @@ -38,6 +38,7 @@ private: AsyncWebSocket m_websocket; bool m_uploadFailed = false; fs::File m_uploadFile; + TimerHandle_t m_pingTimer = NULL; public: enum c_commandEnum From 899c8cffbc86f74b324bd52e1eac997b479c650a Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Tue, 14 Apr 2026 11:02:33 +0200 Subject: [PATCH 31/38] io expander class ok , adc not working --- RotaxMonitor/lib/ADS1256/ADS1256.cpp | 943 ++++++++++++++------------- RotaxMonitor/lib/led/led.cpp | 10 +- RotaxMonitor/lib/led/led.h | 2 + RotaxMonitor/platformio.ini | 4 +- RotaxMonitor/src/devices.h | 19 +- RotaxMonitor/src/extio.cpp | 129 ++++ RotaxMonitor/src/extio.h | 49 ++ RotaxMonitor/src/main.cpp | 117 ++-- RotaxMonitor/src/pins.h | 111 ++-- RotaxMonitor/src/tasks.cpp | 2 +- RotaxMonitor/src/tasks.h | 26 +- 11 files changed, 838 insertions(+), 574 deletions(-) create mode 100644 RotaxMonitor/src/extio.cpp create mode 100644 RotaxMonitor/src/extio.h diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.cpp b/RotaxMonitor/lib/ADS1256/ADS1256.cpp index 79e2430..7a8f51f 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.cpp +++ b/RotaxMonitor/lib/ADS1256/ADS1256.cpp @@ -1,4 +1,4 @@ -//ADS1256 cpp file +// ADS1256 cpp file /* Name: ADS1256.cpp Created: 2022/07/14 @@ -15,391 +15,417 @@ #include "ADS1256.h" #include "SPI.h" +#include "DebugLog.h" + #define convertSigned24BitToLong(value) ((value) & (1l << 23) ? (value) - 0x1000000 : value) -//Constructor -ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYNC_pin, const int8_t CS_pin,float VREF, SPIClass* spi): _spi(spi), - _DRDY_pin(DRDY_pin), _RESET_pin(RESET_pin), _SYNC_pin(SYNC_pin), _CS_pin(CS_pin), _VREF(VREF), _PGA(0) -{ - pinMode(_DRDY_pin, INPUT); - - if(RESET_pin != PIN_UNUSED) +// Constructor +ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYNC_pin, const int8_t CS_pin, float VREF, SPIClass *spi) : _spi(spi), + _DRDY_pin(DRDY_pin), _RESET_pin(RESET_pin), _SYNC_pin(SYNC_pin), _CS_pin(CS_pin), _VREF(VREF), _PGA(0) +{ + pinMode(_DRDY_pin, INPUT); + + if (RESET_pin != PIN_UNUSED) { - pinMode(_RESET_pin, OUTPUT); + pinMode(_RESET_pin, OUTPUT); } - - if(SYNC_pin != PIN_UNUSED) + + if (SYNC_pin != PIN_UNUSED) { - pinMode(_SYNC_pin, OUTPUT); + pinMode(_SYNC_pin, OUTPUT); } - - if(CS_pin != PIN_UNUSED) + + if (CS_pin != PIN_UNUSED) { - pinMode(_CS_pin, OUTPUT); - } - + pinMode(_CS_pin, OUTPUT); + } + + LOG_DEBUG("ADC Class Init OK"); updateConversionParameter(); -} +} -//Initialization +// Initialization void ADS1256::InitializeADC() -{ - //Chip select LOW - CS_LOW(); - - //We do a manual chip reset on the ADS1256 - Datasheet Page 27/ RESET - if(_RESET_pin != PIN_UNUSED) - { - digitalWrite(_RESET_pin, LOW); - delay(200); - digitalWrite(_RESET_pin, HIGH); //RESET is set to high - delay(1000); - } - - //Sync pin is also treated if it is defined - if(_SYNC_pin != PIN_UNUSED) - { - digitalWrite(_SYNC_pin, HIGH); //RESET is set to high - } - -#ifndef ADS1256_SPI_ALREADY_STARTED //Guard macro to allow external initialization of the SPI - _spi->begin(); +{ + LOG_DEBUG("Initialize ADC"); + // Chip select LOW + CS_LOW(); + + // We do a manual chip reset on the ADS1256 - Datasheet Page 27/ RESET + if (_RESET_pin != PIN_UNUSED) + { + digitalWrite(_RESET_pin, LOW); + delay(200); + digitalWrite(_RESET_pin, HIGH); // RESET is set to high + delay(1000); + } + + // Sync pin is also treated if it is defined + if (_SYNC_pin != PIN_UNUSED) + { + digitalWrite(_SYNC_pin, HIGH); // RESET is set to high + } + +#ifndef ADS1256_SPI_ALREADY_STARTED // Guard macro to allow external initialization of the SPI + //_spi->begin(); #endif + + // Applying arbitrary default values to speed up the starting procedure if the user just want to get quick readouts + // We both pass values to the variables and then send those values to the corresponding registers + delay(200); + + _STATUS = 0b00110110; // BUFEN and ACAL enabled, Order is MSB, rest is read only + writeRegister(STATUS_REG, _STATUS); + delay(200); + LOG_DEBUG("Status REG OK"); + + _MUX = 0b00000001; // MUX AIN0+AIN1 + writeRegister(MUX_REG, _MUX); + delay(200); + LOG_DEBUG("Mux REG OK"); + + _ADCON = 0b00000000; // ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) + writeRegister(ADCON_REG, _ADCON); + delay(200); + LOG_DEBUG("Adcon REG OK"); + + updateConversionParameter(); + + _DRATE = 0b10000010; // 100SPS + writeRegister(DRATE_REG, _DRATE); + delay(200); + LOG_DEBUG("Drate REG OK"); - //Applying arbitrary default values to speed up the starting procedure if the user just want to get quick readouts - //We both pass values to the variables and then send those values to the corresponding registers - delay(200); + sendDirectCommand(0b11110000); // Offset and self-gain calibration + LOG_DEBUG("Direct Command OK"); + delay(200); - _STATUS = 0b00110110; //BUFEN and ACAL enabled, Order is MSB, rest is read only - writeRegister(STATUS_REG, _STATUS); - delay(200); - - _MUX = 0b00000001; //MUX AIN0+AIN1 - writeRegister(MUX_REG, _MUX); - delay(200); - - _ADCON = 0b00000000; //ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) - writeRegister(ADCON_REG, _ADCON); - delay(200); - - updateConversionParameter(); - - _DRATE = 0b10000010; //100SPS - writeRegister(DRATE_REG, _DRATE); - delay(200); - - sendDirectCommand(0b11110000); //Offset and self-gain calibration - delay(200); - - _isAcquisitionRunning = false; //MCU will be waiting to start a continuous acquisition + _isAcquisitionRunning = false; // MCU will be waiting to start a continuous acquisition } void ADS1256::waitForLowDRDY() -{ - while (digitalRead(_DRDY_pin) == HIGH) {} +{ + while (digitalRead(_DRDY_pin) == HIGH) + { + } } void ADS1256::waitForHighDRDY() -{ -#if F_CPU >= 48000000 //Fast MCUs need this protection to wait until DRDY goes high after a conversion - while (digitalRead(_DRDY_pin) == LOW) {} +{ +#if F_CPU >= 48000000 // Fast MCUs need this protection to wait until DRDY goes high after a conversion + while (digitalRead(_DRDY_pin) == LOW) + { + } #endif } -void ADS1256::stopConversion() //Sending SDATAC to stop the continuous conversion -{ - waitForLowDRDY(); //SDATAC should be called after DRDY goes LOW (p35. Figure 33) - _spi->transfer(0b00001111); //Send SDATAC to the ADC - CS_HIGH(); //We finished the command sequence, so we switch it back to HIGH +void ADS1256::stopConversion() // Sending SDATAC to stop the continuous conversion +{ + waitForLowDRDY(); // SDATAC should be called after DRDY goes LOW (p35. Figure 33) + _spi->transfer(0b00001111); // Send SDATAC to the ADC + CS_HIGH(); // We finished the command sequence, so we switch it back to HIGH _spi->endTransaction(); - - _isAcquisitionRunning = false; //Reset to false, so the MCU will be able to start a new conversion + + _isAcquisitionRunning = false; // Reset to false, so the MCU will be able to start a new conversion } -void ADS1256::setDRATE(uint8_t drate) //Setting DRATE (sampling frequency) -{ +void ADS1256::setDRATE(uint8_t drate) // Setting DRATE (sampling frequency) +{ + LOG_DEBUG("SetDrate ADC"); writeRegister(DRATE_REG, drate); _DRATE = drate; delayMicroseconds(500); } -void ADS1256::setMUX(uint8_t mux) //Setting MUX (input channel) -{ +void ADS1256::setMUX(uint8_t mux) // Setting MUX (input channel) +{ + LOG_DEBUG("SetMux ADC"); writeRegister(MUX_REG, mux); _MUX = mux; - //delayMicroseconds(500); + // delayMicroseconds(500); } -void ADS1256::setPGA(uint8_t pga) //Setting PGA (input voltage range) -{ +void ADS1256::setPGA(uint8_t pga) // Setting PGA (input voltage range) +{ + LOG_DEBUG("SetPga ADC"); _PGA = pga; - _ADCON = readRegister(ADCON_REG); //Read the most recent value of the register - + _ADCON = readRegister(ADCON_REG); // Read the most recent value of the register + _ADCON = (_ADCON & 0b11111000) | (_PGA & 0b00000111); // Clearing and then setting bits 2-0 based on pga - - writeRegister(ADCON_REG, _ADCON); - delayMicroseconds(1000); //Delay to allow the PGA to settle after changing its value - - updateConversionParameter(); //Update the multiplier according top the new PGA value + + writeRegister(ADCON_REG, _ADCON); + delayMicroseconds(1000); // Delay to allow the PGA to settle after changing its value + + updateConversionParameter(); // Update the multiplier according top the new PGA value } -uint8_t ADS1256::getPGA() //Reading PGA from the ADCON register +uint8_t ADS1256::getPGA() // Reading PGA from the ADCON register { - uint8_t pgaValue = readRegister(ADCON_REG) & 0b00000111; - //Reading the ADCON_REG and keeping the first three bits. - - return(pgaValue); + uint8_t pgaValue = readRegister(ADCON_REG) & 0b00000111; + // Reading the ADCON_REG and keeping the first three bits. + + return (pgaValue); } -void ADS1256::setCLKOUT(uint8_t clkout) //Setting CLKOUT +void ADS1256::setCLKOUT(uint8_t clkout) // Setting CLKOUT { - _ADCON = readRegister(ADCON_REG); //Read the most recent value of the register - - //Values: 0, 1, 2, 3 - - if(clkout == 0) + _ADCON = readRegister(ADCON_REG); // Read the most recent value of the register + + // Values: 0, 1, 2, 3 + + if (clkout == 0) { - //00 + // 00 bitWrite(_ADCON, 6, 0); - bitWrite(_ADCON, 5, 0); + bitWrite(_ADCON, 5, 0); } - else if(clkout == 1) + else if (clkout == 1) { - //01 (default) + // 01 (default) bitWrite(_ADCON, 6, 0); - bitWrite(_ADCON, 5, 1); + bitWrite(_ADCON, 5, 1); } - else if(clkout == 2) + else if (clkout == 2) { - //10 + // 10 bitWrite(_ADCON, 6, 1); - bitWrite(_ADCON, 5, 0); + bitWrite(_ADCON, 5, 0); } - else if(clkout == 3) + else if (clkout == 3) { - //11 + // 11 bitWrite(_ADCON, 6, 1); - bitWrite(_ADCON, 5, 1); + bitWrite(_ADCON, 5, 1); } - else{} - + else + { + } + writeRegister(ADCON_REG, _ADCON); delay(100); } -void ADS1256::setSDCS(uint8_t sdcs) //Setting SDCS +void ADS1256::setSDCS(uint8_t sdcs) // Setting SDCS { - _ADCON = readRegister(ADCON_REG); //Read the most recent value of the register - - //Values: 0, 1, 2, 3 - - if(sdcs == 0) + _ADCON = readRegister(ADCON_REG); // Read the most recent value of the register + + // Values: 0, 1, 2, 3 + + if (sdcs == 0) { - //00 (default) + // 00 (default) bitWrite(_ADCON, 4, 0); - bitWrite(_ADCON, 3, 0); + bitWrite(_ADCON, 3, 0); } - else if(sdcs == 1) + else if (sdcs == 1) { - //01 + // 01 bitWrite(_ADCON, 4, 0); - bitWrite(_ADCON, 3, 1); + bitWrite(_ADCON, 3, 1); } - else if(sdcs == 2) + else if (sdcs == 2) { - //10 + // 10 bitWrite(_ADCON, 4, 1); - bitWrite(_ADCON, 3, 0); + bitWrite(_ADCON, 3, 0); } - else if(sdcs == 3) + else if (sdcs == 3) { - //11 + // 11 bitWrite(_ADCON, 4, 1); - bitWrite(_ADCON, 3, 1); + bitWrite(_ADCON, 3, 1); } - else{} - + else + { + } + writeRegister(ADCON_REG, _ADCON); delay(100); } -void ADS1256::setByteOrder(uint8_t byteOrder) //Setting byte order (MSB/LSB) +void ADS1256::setByteOrder(uint8_t byteOrder) // Setting byte order (MSB/LSB) { - _STATUS = readRegister(STATUS_REG); //Read the most recent value of the register - - if(byteOrder == 0) + _STATUS = readRegister(STATUS_REG); // Read the most recent value of the register + + if (byteOrder == 0) { - //Byte order is MSB (default) + // Byte order is MSB (default) bitWrite(_STATUS, 3, 0); - //Set value of _STATUS at the third bit to 0 + // Set value of _STATUS at the third bit to 0 } - else if(byteOrder == 1) + else if (byteOrder == 1) { - //Byte order is LSB + // Byte order is LSB bitWrite(_STATUS, 3, 1); - //Set value of _STATUS at the third bit to 1 + // Set value of _STATUS at the third bit to 1 } - else{} - + else + { + } + writeRegister(STATUS_REG, _STATUS); delay(100); } -uint8_t ADS1256::getByteOrder() //Getting byte order (MSB/LSB) -{ - uint8_t statusValue = readRegister(STATUS_REG); //Read the whole STATUS register - +uint8_t ADS1256::getByteOrder() // Getting byte order (MSB/LSB) +{ + uint8_t statusValue = readRegister(STATUS_REG); // Read the whole STATUS register + return bitRead(statusValue, 3); } -void ADS1256::setAutoCal(uint8_t acal) //Setting ACAL (Automatic SYSCAL) -{ - _STATUS = readRegister(STATUS_REG); //Read the most recent value of the register - - if(acal == 0) +void ADS1256::setAutoCal(uint8_t acal) // Setting ACAL (Automatic SYSCAL) +{ + _STATUS = readRegister(STATUS_REG); // Read the most recent value of the register + + if (acal == 0) { - //Auto-calibration is disabled (default) + // Auto-calibration is disabled (default) bitWrite(_STATUS, 2, 0); //_STATUS |= B00000000; } - else if(acal == 1) + else if (acal == 1) { - //Auto-calibration is enabled + // Auto-calibration is enabled bitWrite(_STATUS, 2, 1); //_STATUS |= B00000100; } - else{} - + else + { + } + writeRegister(STATUS_REG, _STATUS); delay(100); } -uint8_t ADS1256::getAutoCal() //Getting ACAL (Automatic SYSCAL) -{ - uint8_t statusValue = readRegister(STATUS_REG); //Read the whole STATUS register - +uint8_t ADS1256::getAutoCal() // Getting ACAL (Automatic SYSCAL) +{ + uint8_t statusValue = readRegister(STATUS_REG); // Read the whole STATUS register + return bitRead(statusValue, 2); } -void ADS1256::setBuffer(uint8_t bufen) //Setting input buffer (Input impedance) -{ - _STATUS = readRegister(STATUS_REG); //Read the most recent value of the register - - if(bufen == 0) +void ADS1256::setBuffer(uint8_t bufen) // Setting input buffer (Input impedance) +{ + _STATUS = readRegister(STATUS_REG); // Read the most recent value of the register + + if (bufen == 0) { - //Analog input buffer is disabled (default) + // Analog input buffer is disabled (default) //_STATUS |= B00000000; bitWrite(_STATUS, 1, 0); } - else if(bufen == 1) + else if (bufen == 1) { - //Analog input buffer is enabled (recommended) + // Analog input buffer is enabled (recommended) //_STATUS |= B00000010; bitWrite(_STATUS, 1, 1); } - else{} - + else + { + } + writeRegister(STATUS_REG, _STATUS); delay(100); } -uint8_t ADS1256::getBuffer() //Getting input buffer (Input impedance) -{ - uint8_t statusValue = readRegister(STATUS_REG); //Read the whole STATUS register - +uint8_t ADS1256::getBuffer() // Getting input buffer (Input impedance) +{ + uint8_t statusValue = readRegister(STATUS_REG); // Read the whole STATUS register + return bitRead(statusValue, 1); } -void ADS1256::setGPIO(uint8_t dir0, uint8_t dir1, uint8_t dir2, uint8_t dir3) //Setting GPIO -{ - _GPIO = readRegister(IO_REG); //Read the most recent value of the register - - //Default: 11100000 - DEC: 224 - Ref: p32 I/O section - //Sets D3-D0 as input or output +void ADS1256::setGPIO(uint8_t dir0, uint8_t dir1, uint8_t dir2, uint8_t dir3) // Setting GPIO +{ + _GPIO = readRegister(IO_REG); // Read the most recent value of the register + + // Default: 11100000 - DEC: 224 - Ref: p32 I/O section + // Sets D3-D0 as input or output uint8_t GPIO_bit7, GPIO_bit6, GPIO_bit5, GPIO_bit4; - - //Bit7: DIR3 - if(dir3 == 1) + + // Bit7: DIR3 + if (dir3 == 1) { - GPIO_bit7 = 1; //D3 is input (default) + GPIO_bit7 = 1; // D3 is input (default) } else { - GPIO_bit7 = 0; //D3 is output - } + GPIO_bit7 = 0; // D3 is output + } bitWrite(_GPIO, 7, GPIO_bit7); //----------------------------------------------------- - //Bit6: DIR2 - if(dir2 == 1) + // Bit6: DIR2 + if (dir2 == 1) { - GPIO_bit6 = 1; //D2 is input (default) + GPIO_bit6 = 1; // D2 is input (default) } else { - GPIO_bit6 = 0; //D2 is output + GPIO_bit6 = 0; // D2 is output } bitWrite(_GPIO, 6, GPIO_bit6); //----------------------------------------------------- - //Bit5: DIR1 - if(dir1 == 1) + // Bit5: DIR1 + if (dir1 == 1) { - GPIO_bit5 = 1; //D1 is input (default) + GPIO_bit5 = 1; // D1 is input (default) } else { - GPIO_bit5 = 0; //D1 is output + GPIO_bit5 = 0; // D1 is output } bitWrite(_GPIO, 5, GPIO_bit5); //----------------------------------------------------- - //Bit4: DIR0 - if(dir0 == 1) + // Bit4: DIR0 + if (dir0 == 1) { - GPIO_bit4 = 1; //D0 is input + GPIO_bit4 = 1; // D0 is input } else { - GPIO_bit4 = 0; //D0 is output (default) + GPIO_bit4 = 0; // D0 is output (default) } bitWrite(_GPIO, 4, GPIO_bit4); //----------------------------------------------------- - + writeRegister(IO_REG, _GPIO); delay(100); } -void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, uint8_t dir3value) //Writing GPIO +void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, uint8_t dir3value) // Writing GPIO { _GPIO = readRegister(IO_REG); - - //Sets D3-D0 output values - //It is important that first one must use setGPIO, then writeGPIO - + + // Sets D3-D0 output values + // It is important that first one must use setGPIO, then writeGPIO + uint8_t GPIO_bit3, GPIO_bit2, GPIO_bit1, GPIO_bit0; - - //Bit3: DIR3 - if(dir3value == 1) + + // Bit3: DIR3 + if (dir3value == 1) { GPIO_bit3 = 1; } else { GPIO_bit3 = 0; - } + } bitWrite(_GPIO, 3, GPIO_bit3); //----------------------------------------------------- - //Bit2: DIR2 - if(dir2value == 1) + // Bit2: DIR2 + if (dir2value == 1) { GPIO_bit2 = 1; } else { GPIO_bit2 = 0; - } + } bitWrite(_GPIO, 2, GPIO_bit2); //----------------------------------------------------- - //Bit1: DIR1 - if(dir1value == 1) + // Bit1: DIR1 + if (dir1value == 1) { GPIO_bit1 = 1; } @@ -407,358 +433,371 @@ void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, { GPIO_bit1 = 0; } - bitWrite(_GPIO, 1, GPIO_bit1); + bitWrite(_GPIO, 1, GPIO_bit1); //----------------------------------------------------- - //Bit0: DIR0 - if(dir0value == 1) + // Bit0: DIR0 + if (dir0value == 1) { GPIO_bit0 = 1; } else { GPIO_bit0 = 0; - } + } bitWrite(_GPIO, 0, GPIO_bit0); - //----------------------------------------------------- - + //----------------------------------------------------- + writeRegister(IO_REG, _GPIO); delay(100); } -uint8_t ADS1256::readGPIO(uint8_t gpioPin) //Reading GPIO -{ +uint8_t ADS1256::readGPIO(uint8_t gpioPin) // Reading GPIO +{ uint8_t GPIO_bit3, GPIO_bit2, GPIO_bit1, GPIO_bit0, GPIO_return; - - _GPIO = readRegister(IO_REG); //Read the GPIO register - - //Save each bit values in a variable + + _GPIO = readRegister(IO_REG); // Read the GPIO register + + // Save each bit values in a variable GPIO_bit3 = bitRead(_GPIO, 3); GPIO_bit2 = bitRead(_GPIO, 2); GPIO_bit1 = bitRead(_GPIO, 1); - GPIO_bit0 = bitRead(_GPIO, 0); - - delay(100); - - switch(gpioPin) //Selecting which value should be returned + GPIO_bit0 = bitRead(_GPIO, 0); + + delay(100); + + switch (gpioPin) // Selecting which value should be returned { - case 0: + case 0: GPIO_return = GPIO_bit0; break; - - case 1: + + case 1: GPIO_return = GPIO_bit1; break; - - case 2: + + case 2: GPIO_return = GPIO_bit2; break; - - case 3: + + case 3: GPIO_return = GPIO_bit3; break; } return GPIO_return; - } void ADS1256::sendDirectCommand(uint8_t directCommand) { - //Direct commands can be found in the datasheet Page 34, Table 24. - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - - CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" - delayMicroseconds(5); - _spi->transfer(directCommand); //Send Command - delayMicroseconds(5); - CS_HIGH(); //REF: P34: "CS must stay low during the entire command sequence" - - _spi->endTransaction(); + LOG_DEBUG("Direct Command"); + // Direct commands can be found in the datasheet Page 34, Table 24. + LOG_DEBUG("Direct Command Begin"); + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + + CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" + LOG_DEBUG("Direct Command CS LOW"); + delayMicroseconds(5); + _spi->transfer(directCommand); // Send Command + LOG_DEBUG("Transfer OK"); + delayMicroseconds(5); + CS_HIGH(); // REF: P34: "CS must stay low during the entire command sequence" + LOG_DEBUG("Direct Command CS HIGH"); + + _spi->endTransaction(); + LOG_DEBUG("Direct Command End"); } - -float ADS1256::convertToVoltage(int32_t rawData) //Converting the 24-bit data into a voltage value -{ - return(conversionParameter * rawData); +float ADS1256::convertToVoltage(int32_t rawData) // Converting the 24-bit data into a voltage value +{ + return (conversionParameter * rawData); } void ADS1256::writeRegister(uint8_t registerAddress, uint8_t registerValueToWrite) -{ - waitForLowDRDY(); - - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - //SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. - - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - - delayMicroseconds(5); //see t6 in the datasheet - - _spi->transfer(0x50 | registerAddress); // 0x50 = 01010000 = WREG - - _spi->transfer(0x00); //2nd (empty) command byte - - _spi->transfer(registerValueToWrite); //pass the value to the register - - CS_HIGH(); - _spi->endTransaction(); -} - -long ADS1256::readRegister(uint8_t registerAddress) //Reading a register { - waitForLowDRDY(); - - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - //SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. + waitForLowDRDY(); + LOG_DEBUG("DRDY Low"); - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + // SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. + LOG_DEBUG("SPI Begin"); - _spi->transfer(0x10 | registerAddress); //0x10 = 0001000 = RREG - OR together the two numbers (command + address) + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + LOG_DEBUG("CS Low"); - _spi->transfer(0x00); //2nd (empty) command byte + delayMicroseconds(5); // see t6 in the datasheet - delayMicroseconds(5); //see t6 in the datasheet + _spi->transfer(0x50 | registerAddress); // 0x50 = 01010000 = WREG + LOG_DEBUG("Transfer 1"); - uint8_t regValue = _spi->transfer(0xFF); //read out the register value + _spi->transfer(0x00); // 2nd (empty) command byte + LOG_DEBUG("Transfer 2"); - CS_HIGH(); - _spi->endTransaction(); + _spi->transfer(registerValueToWrite); // pass the value to the register + LOG_DEBUG("Transfer 3"); - return regValue; + CS_HIGH(); + LOG_DEBUG("CS High"); + _spi->endTransaction(); + LOG_DEBUG("SPI End"); } +long ADS1256::readRegister(uint8_t registerAddress) // Reading a register +{ + waitForLowDRDY(); -long ADS1256::readSingle() //Reading a single value ONCE using the RDATA command + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + // SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. + + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + + _spi->transfer(0x10 | registerAddress); // 0x10 = 0001000 = RREG - OR together the two numbers (command + address) + + _spi->transfer(0x00); // 2nd (empty) command byte + + delayMicroseconds(5); // see t6 in the datasheet + + uint8_t regValue = _spi->transfer(0xFF); // read out the register value + + CS_HIGH(); + _spi->endTransaction(); + + return regValue; +} + +long ADS1256::readSingle() // Reading a single value ONCE using the RDATA command { _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" + CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" waitForLowDRDY(); - _spi->transfer(0b00000001); //Issue RDATA (0000 0001) command - delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + _spi->transfer(0b00000001); // Issue RDATA (0000 0001) command + delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. _outputBuffer[0] = _spi->transfer(0); // MSB _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB + _outputBuffer[2] = _spi->transfer(0); // LSB - //Shifting and combining the above three items into a single, 24-bit number - _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); + // Shifting and combining the above three items into a single, 24-bit number + _outputValue = ((long)_outputBuffer[0] << 16) | ((long)_outputBuffer[1] << 8) | (_outputBuffer[2]); _outputValue = convertSigned24BitToLong(_outputValue); - - CS_HIGH(); //We finished the command sequence, so we set CS to HIGH + + CS_HIGH(); // We finished the command sequence, so we set CS to HIGH _spi->endTransaction(); - - return(_outputValue); + + return (_outputValue); } -long ADS1256::readSingleContinuous() //Reads the recently selected input channel using RDATAC -{ - if(_isAcquisitionRunning == false) +long ADS1256::readSingleContinuous() // Reads the recently selected input channel using RDATAC +{ + if (_isAcquisitionRunning == false) { - _isAcquisitionRunning = true; - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" - waitForLowDRDY(); - _spi->transfer(0b00000011); //Issue RDATAC (0000 0011) - delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + _isAcquisitionRunning = true; + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" + waitForLowDRDY(); + _spi->transfer(0b00000011); // Issue RDATAC (0000 0011) + delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. } else { waitForLowDRDY(); - } - - _outputBuffer[0] = _spi->transfer(0); // MSB + } + + _outputBuffer[0] = _spi->transfer(0); // MSB _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB - - _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - + _outputBuffer[2] = _spi->transfer(0); // LSB + + _outputValue = ((long)_outputBuffer[0] << 16) | ((long)_outputBuffer[1] << 8) | (_outputBuffer[2]); + _outputValue = convertSigned24BitToLong(_outputValue); + waitForHighDRDY(); - + return _outputValue; } long ADS1256::cycleSingle() { - if(_isAcquisitionRunning == false) + if (_isAcquisitionRunning == false) { - _isAcquisitionRunning = true; - _cycle = 0; - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX - _spi->transfer(0x00); - _spi->transfer(SING_0); //AIN0+AINCOM - CS_HIGH(); - delay(50); - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] + _isAcquisitionRunning = true; + _cycle = 0; + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX + _spi->transfer(0x00); + _spi->transfer(SING_0); // AIN0+AINCOM + CS_HIGH(); + delay(50); + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] } else - {} - - if(_cycle < 8) - { - _outputValue = 0; - waitForLowDRDY(); - //Step 1. - Updating MUX - switch (_cycle) - { - //Channels are written manually - case 0: //Channel 2 - updateMUX(SING_1); //AIN1+AINCOM - break; + { + } - case 1: //Channel 3 - updateMUX(SING_2); //AIN2+AINCOM - break; + if (_cycle < 8) + { + _outputValue = 0; + waitForLowDRDY(); + // Step 1. - Updating MUX + switch (_cycle) + { + // Channels are written manually + case 0: // Channel 2 + updateMUX(SING_1); // AIN1+AINCOM + break; - case 2: //Channel 4 - updateMUX(SING_3); //AIN3+AINCOM - break; + case 1: // Channel 3 + updateMUX(SING_2); // AIN2+AINCOM + break; - case 3: //Channel 5 - updateMUX(SING_4); //AIN4+AINCOM - break; + case 2: // Channel 4 + updateMUX(SING_3); // AIN3+AINCOM + break; - case 4: //Channel 6 - updateMUX(SING_5); //AIN5+AINCOM - break; + case 3: // Channel 5 + updateMUX(SING_4); // AIN4+AINCOM + break; - case 5: //Channel 7 - updateMUX(SING_6); //AIN6+AINCOM - break; + case 4: // Channel 6 + updateMUX(SING_5); // AIN5+AINCOM + break; - case 6: //Channel 8 - updateMUX(SING_7); //AIN7+AINCOM - break; + case 5: // Channel 7 + updateMUX(SING_6); // AIN6+AINCOM + break; - case 7: //Channel 1 - updateMUX(SING_0); //AIN0+AINCOM - break; - } - //Step 2. - _spi->transfer(0b11111100); //SYNC - delayMicroseconds(4); //t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us - _spi->transfer(0b11111111); //WAKEUP + case 6: // Channel 8 + updateMUX(SING_7); // AIN7+AINCOM + break; - //Step 3. - //Issue RDATA (0000 0001) command - _spi->transfer(0b00000001); - delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + case 7: // Channel 1 + updateMUX(SING_0); // AIN0+AINCOM + break; + } + // Step 2. + _spi->transfer(0b11111100); // SYNC + delayMicroseconds(4); // t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us + _spi->transfer(0b11111111); // WAKEUP + + // Step 3. + // Issue RDATA (0000 0001) command + _spi->transfer(0b00000001); + delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. + + _outputBuffer[0] = _spi->transfer(0x0F); // MSB + _outputBuffer[1] = _spi->transfer(0x0F); // Mid-byte + _outputBuffer[2] = _spi->transfer(0x0F); // LSB + + _outputValue = ((long)_outputBuffer[0] << 16) | ((long)_outputBuffer[1] << 8) | (_outputBuffer[2]); + _outputValue = convertSigned24BitToLong(_outputValue); + + _cycle++; // Increase cycle - This will move to the next MUX input channel + if (_cycle == 8) + { + _cycle = 0; // Reset to 0 - Restart conversion from the 1st input channel + } + } - _outputBuffer[0] = _spi->transfer(0x0F); // MSB - _outputBuffer[1] = _spi->transfer(0x0F); // Mid-byte - _outputBuffer[2] = _spi->transfer(0x0F); // LSB - - _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - - _cycle++; //Increase cycle - This will move to the next MUX input channel - if(_cycle == 8) - { - _cycle = 0; //Reset to 0 - Restart conversion from the 1st input channel - } - } - return _outputValue; } -long ADS1256::cycleDifferential() +long ADS1256::cycleDifferential() { - if(_isAcquisitionRunning == false) + if (_isAcquisitionRunning == false) { - _cycle = 0; - _isAcquisitionRunning = true; - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - - //Set the AIN0+AIN1 as inputs manually - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX - _spi->transfer(0x00); - _spi->transfer(DIFF_0_1); //AIN0+AIN1 - CS_HIGH(); - delay(50); - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] + _cycle = 0; + _isAcquisitionRunning = true; + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + + // Set the AIN0+AIN1 as inputs manually + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX + _spi->transfer(0x00); + _spi->transfer(DIFF_0_1); // AIN0+AIN1 + CS_HIGH(); + delay(50); + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] } else - {} - - if(_cycle < 4) - { - _outputValue = 0; - //DRDY has to go low - waitForLowDRDY(); + { + } - //Step 1. - Updating MUX - switch (_cycle) - { - case 0: //Channel 2 - updateMUX(DIFF_2_3); //AIN2+AIN3 - break; + if (_cycle < 4) + { + _outputValue = 0; + // DRDY has to go low + waitForLowDRDY(); - case 1: //Channel 3 - updateMUX(DIFF_4_5); //AIN4+AIN5 - break; + // Step 1. - Updating MUX + switch (_cycle) + { + case 0: // Channel 2 + updateMUX(DIFF_2_3); // AIN2+AIN3 + break; - case 2: //Channel 4 - updateMUX(DIFF_6_7); //AIN6+AIN7 - break; + case 1: // Channel 3 + updateMUX(DIFF_4_5); // AIN4+AIN5 + break; - case 3: //Channel 1 - updateMUX(DIFF_0_1); //AIN0+AIN1 - break; - } + case 2: // Channel 4 + updateMUX(DIFF_6_7); // AIN6+AIN7 + break; - _spi->transfer(0b11111100); //SYNC - delayMicroseconds(4); //t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us - _spi->transfer(0b11111111); //WAKEUP + case 3: // Channel 1 + updateMUX(DIFF_0_1); // AIN0+AIN1 + break; + } - //Step 3. - _spi->transfer(0b00000001); //Issue RDATA (0000 0001) command - delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + _spi->transfer(0b11111100); // SYNC + delayMicroseconds(4); // t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us + _spi->transfer(0b11111111); // WAKEUP + + // Step 3. + _spi->transfer(0b00000001); // Issue RDATA (0000 0001) command + delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. + + _outputBuffer[0] = _spi->transfer(0); // MSB + _outputBuffer[1] = _spi->transfer(0); // Mid-byte + _outputBuffer[2] = _spi->transfer(0); // LSB + + _outputValue = ((long)_outputBuffer[0] << 16) | ((long)_outputBuffer[1] << 8) | (_outputBuffer[2]); + _outputValue = convertSigned24BitToLong(_outputValue); + + _cycle++; + if (_cycle == 4) + { + _cycle = 0; + // After the 4th cycle, we reset to zero so the next iteration reads the 1st MUX again + } + } - _outputBuffer[0] = _spi->transfer(0); // MSB - _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB - - _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - - _cycle++; - if(_cycle == 4) - { - _cycle = 0; - //After the 4th cycle, we reset to zero so the next iteration reads the 1st MUX again - } - } - return _outputValue; } void ADS1256::updateConversionParameter() { - conversionParameter = ((2.0 * _VREF) / 8388608.0) / (pow(2, _PGA)); //Calculate the "bit to Volts" multiplier - //8388608 = 2^{23} - 1, REF: p23, Table 16. + conversionParameter = ((2.0 * _VREF) / 8388608.0) / (pow(2, _PGA)); // Calculate the "bit to Volts" multiplier + // 8388608 = 2^{23} - 1, REF: p23, Table 16. } void ADS1256::updateMUX(uint8_t muxValue) { - _spi->transfer(0x50 | MUX_REG); //Write to the MUX register (0x50 is the WREG command) - _spi->transfer(0x00); - _spi->transfer(muxValue); //Write the new MUX value + _spi->transfer(0x50 | MUX_REG); // Write to the MUX register (0x50 is the WREG command) + _spi->transfer(0x00); + _spi->transfer(muxValue); // Write the new MUX value } inline void ADS1256::CS_LOW() { - if (_CS_pin != PIN_UNUSED) //Sets CS LOW if it is not an unused pin + if (_CS_pin != PIN_UNUSED) // Sets CS LOW if it is not an unused pin { - digitalWrite(_CS_pin, LOW); + digitalWrite(_CS_pin, LOW); } } inline void ADS1256::CS_HIGH() { - if (_CS_pin != PIN_UNUSED) //Sets CS HIGH if it is not an unused pin + if (_CS_pin != PIN_UNUSED) // Sets CS HIGH if it is not an unused pin { - digitalWrite(_CS_pin, HIGH); + digitalWrite(_CS_pin, HIGH); } } \ No newline at end of file diff --git a/RotaxMonitor/lib/led/led.cpp b/RotaxMonitor/lib/led/led.cpp index 9a93a85..bb48172 100644 --- a/RotaxMonitor/lib/led/led.cpp +++ b/RotaxMonitor/lib/led/led.cpp @@ -4,6 +4,7 @@ RGBled::RGBled(const uint8_t pin) : m_led(pin) { pinMode(m_led, OUTPUT); writeStatus(RGBled::ERROR); + m_brightness = 1.0f; } RGBled::~RGBled() @@ -11,6 +12,11 @@ RGBled::~RGBled() pinMode(m_led, INPUT); } +void RGBled::setBrightness(const float b) +{ + m_brightness = b; +} + void RGBled::setStatus(const LedStatus s) { if (m_status == s) @@ -27,6 +33,6 @@ const RGBled::LedStatus RGBled::getSatus(void) void RGBled::writeStatus(const RGBled::LedStatus s) { - RGBled::color_u u{.status = s}; - rgbLedWrite(m_led, u.color.r, u.color.g, u.color.b); + const RGBled::color_u u{.status = s}; + rgbLedWrite(m_led, (uint8_t)(m_brightness*u.color.r), (uint8_t)(m_brightness*u.color.g), (uint8_t)(m_brightness*u.color.b)); } diff --git a/RotaxMonitor/lib/led/led.h b/RotaxMonitor/lib/led/led.h index 0770314..7b7cf3a 100644 --- a/RotaxMonitor/lib/led/led.h +++ b/RotaxMonitor/lib/led/led.h @@ -50,6 +50,7 @@ public: RGBled(const uint8_t pin = 48); ~RGBled(); + void setBrightness(const float b); void setStatus(const LedStatus s); const LedStatus getSatus(void); @@ -59,5 +60,6 @@ private: private: LedStatus m_status = LedStatus::IDLE; std::mutex m_mutex; + float m_brightness; const uint8_t m_led; }; \ No newline at end of file diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index 5ba4f2c..b43c9e2 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -28,7 +28,7 @@ monitor_port = /dev/ttyACM0 monitor_speed = 921600 build_type = release build_flags = - -DCORE_DEBUG_LEVEL=1 + -DCORE_DEBUG_LEVEL=5 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 @@ -59,7 +59,7 @@ build_flags = -O0 -g3 -ggdb3 - -DCORE_DEBUG_LEVEL=3 + -DCORE_DEBUG_LEVEL=5 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 diff --git a/RotaxMonitor/src/devices.h b/RotaxMonitor/src/devices.h index 740ff0e..70a8b7d 100644 --- a/RotaxMonitor/src/devices.h +++ b/RotaxMonitor/src/devices.h @@ -9,7 +9,8 @@ // Device Libraries #include #include -#include +#include +#include // ADC Channel mapping #define ADC_CH_PEAK_12P_IN SING_0 @@ -24,23 +25,25 @@ // Device Pointer structs for tasks struct Devices { + // Busses + std::unique_ptr m_i2c = nullptr; std::unique_ptr m_spi_a = nullptr; std::unique_ptr m_spi_b = nullptr; + // Bus Mutextes + std::mutex m_spi_a_mutex; + std::mutex m_spi_b_mutex; + std::mutex m_i2c_mutex; + + // Device Pointers std::unique_ptr m_pot_a = nullptr; std::unique_ptr m_pot_b = nullptr; std::unique_ptr m_adc_a = nullptr; std::unique_ptr m_adc_b = nullptr; - std::unique_ptr m_expander_a = nullptr; - std::unique_ptr m_expander_b = nullptr; - std::unique_ptr m_expander_inputs_ab = nullptr; + std::unique_ptr m_ext_io = nullptr; - std::mutex m_spi_a_mutex; - std::mutex m_spi_b_mutex; - - std::mutex m_i2c_mutex; }; // Adc read channel wrapper to selet mux before reading diff --git a/RotaxMonitor/src/extio.cpp b/RotaxMonitor/src/extio.cpp new file mode 100644 index 0000000..3503381 --- /dev/null +++ b/RotaxMonitor/src/extio.cpp @@ -0,0 +1,129 @@ +#include + +// Static interrupt callback +static void onExpanderInterrupt(void *arg) +{ + auto cls = (ExternalIO *)(arg); + if (!cls) // invalid args + return; + cls->extReadInterrupt(); +} + +ExternalIO::ExternalIO(TwoWire &i2c, std::mutex &i2c_mutex, const uint8_t int_pin) : m_i2cMutex(i2c_mutex), m_i2c(i2c), m_intPin(int_pin) +{ + std::lock_guard lock(m_i2cMutex); + // Attach OUT expanders on BUS + m_outMap[EXPANDER_A_OUT_ADDR] = std::make_unique(); + m_outMap[EXPANDER_A_OUT_ADDR]->attach(m_i2c, EXPANDER_A_OUT_ADDR); + m_outMap[EXPANDER_B_OUT_ADDR] = std::make_unique(); + m_outMap[EXPANDER_B_OUT_ADDR]->attach(m_i2c, EXPANDER_B_OUT_ADDR); + + for (auto &[a, e] : m_outMap) + { + e->direction(PCA95x5::Direction::OUT_ALL); + e->polarity(PCA95x5::Polarity::ORIGINAL_ALL); + }; + + // Attach IN Expanders on Bus + m_inMap[EXPANDER_A_IN_ADDR] = std::make_unique(); + m_inMap[EXPANDER_A_IN_ADDR]->attach(m_i2c, EXPANDER_A_IN_ADDR); + m_inMap[EXPANDER_B_IN_ADDR] = std::make_unique(); + m_inMap[EXPANDER_B_IN_ADDR]->attach(m_i2c, EXPANDER_B_IN_ADDR); + + for (auto &[a, e] : m_inMap) + { + e->direction(PCA95x5::Direction::IN_ALL); + e->polarity(PCA95x5::Polarity::ORIGINAL_ALL); + m_lastInputState[a] = e->read(); /// initialize input state to collect interrupts + }; +} +ExternalIO::~ExternalIO() { + +} + +void ExternalIO::extDigitalWrite(const uint32_t mappedPin, const bool val) +{ + std::lock_guard lock(m_i2cMutex); + const io_t pa = map2pin(mappedPin); + if (!m_outMap.contains(pa.addr)) + { + LOG_ERROR("Undefined IO Expander addr: [", pa.addr, "]"); + return; + } + auto &io = m_outMap.at(pa.addr); + if (!io->write(static_cast(pa.pin), val ? PCA95x5::Level::H : PCA95x5::Level::L)) + { + LOG_ERROR("IO Expander [", pa.addr, "] Unable to WRITE Port [", pa.pin, "] to [", val ? "HIGH" : "LOW"); + LOG_ERROR("IO Expander Error [", io->i2c_error(), "]"); + } +} + +const bool ExternalIO::extDigitalRead(const uint32_t mappedPin) +{ + std::lock_guard lock(m_i2cMutex); + const io_t pa = map2pin(mappedPin); + if (!m_inMap.contains(pa.addr)) + { + LOG_ERROR("Undefined IO Expander addr: [", pa.addr, "]"); + return false; + } + auto &io = m_inMap.at(pa.addr); + const bool rv = io->read(static_cast(pa.pin)) == PCA95x5::Level::H ? true : false; // read value + const uint8_t err = io->i2c_error(); + if (err) + { + LOG_ERROR("IO Expander [", pa.addr, "] Unable to READ Port [", pa.pin, "]"); + LOG_ERROR("IO Expander Error [", err, "]"); + } + return rv; +} + +void ExternalIO::extAttachInterrupt(ExtInterruptCb cb) +{ + attachInterruptArg(EXPANDER_ALL_INTERRUPT, onExpanderInterrupt, (void *)(this), FALLING); + m_extInterruptCb = cb; +} + +void ExternalIO::extDetachInterrupt() +{ + detachInterrupt(EXPANDER_ALL_INTERRUPT); +} + +void ExternalIO::extReadInterrupt() +{ + std::lock_guard lock(m_i2cMutex); + disableInterrupt(EXPANDER_ALL_INTERRUPT); + // read all registers and collect + IOstate interruptState; + for (auto &[a, e] : m_inMap) + { + interruptState[a] = e->read(); + } + m_lastInputState = interruptState; // restore to current values + // compare to last state to see the difference + if (m_extInterruptCb) + { + for (auto &[a, v] : interruptState) + { + if (v) + m_extInterruptCb(stat2map(a, v)); + } + } + + enableInterrupt(EXPANDER_ALL_INTERRUPT); +} + +const ExternalIO::io_t ExternalIO::map2pin(const uint32_t mappedIO) +{ + return io_t{ + .addr = (uint8_t)((mappedIO >> 16) & (uint8_t)0xFF), + .pin = (uint8_t)(mappedIO && (uint32_t)0xFF), + }; +} + +const uint32_t ExternalIO::stat2map(const uint8_t addr, const uint16_t stat) +{ + if (!stat) + return 0; + return (uint32_t)(addr << 16) | (1UL << __builtin_ctz(stat)); +} diff --git a/RotaxMonitor/src/extio.h b/RotaxMonitor/src/extio.h new file mode 100644 index 0000000..ddaeb20 --- /dev/null +++ b/RotaxMonitor/src/extio.h @@ -0,0 +1,49 @@ +#pragma once +#define DEBUGLOG_DEFAULT_LOG_LEVEL_DEBUG + +#include +#include +#include + +#include + +#include +#include + +class ExternalIO +{ + using IOptr = std::unique_ptr; + using IOmap = std::map; + using IOstate = std::map; + using ExtInterruptCb = std::function; + + struct io_t + { + uint8_t addr; + uint8_t pin; + }; + +public: + ExternalIO(TwoWire &i2c, std::mutex &i2c_mutex, const uint8_t int_pin); + ~ExternalIO(); + + void extDigitalWrite(const uint32_t mappedPin, const bool val); + const bool extDigitalRead(const uint32_t mappedPin); + void extAttachInterrupt(ExtInterruptCb cb = nullptr); + void extDetachInterrupt(); + void extReadInterrupt(); + +private: + const io_t map2pin(const uint32_t mappedIO); + const uint32_t stat2map(const uint8_t addr, const uint16_t stat); + +private: + const uint8_t m_intPin; + IOmap m_inMap; + IOmap m_outMap; + uint8_t m_intPinChanged; + IOstate m_lastInputState; + ExtInterruptCb m_extInterruptCb = nullptr; + std::mutex &m_i2cMutex; + TwoWire &m_i2c; +}; diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 0451ba0..68afb1f 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -18,11 +18,12 @@ // Defines to enable channel B #define CH_B_ENABLE -// #define TEST // Debug Defines #define WIFI_SSID "AstroRotaxMonitor" #define WIFI_PASSWORD "maledettirotax" +#define PSRAM_MAX 4096 +#define QUEUE_MAX 256 void setup() { @@ -79,49 +80,77 @@ void loop() { // global variables RGBled led; + led.setBrightness(0.025f); led.setStatus(RGBled::LedStatus::INIT); + + std::shared_ptr dev = std::make_shared(); bool running = true; std::mutex fs_mutex; LITTLEFSGuard fsGuard; - //////// INIT SPI PORTS //////// + //////// INIT SPI INTERFACES //////// bool spiA_ok = true; bool spiB_ok = true; - // Init 2 SPI interfaces -// SPIClass SPI_A(FSPI); -// spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); -// SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 -// #ifdef CH_B_ENABLE -// SPIClass SPI_B(HSPI); -// spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); -// SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 -// #endif + LOG_DEBUG("Init SPI Interfaces"); + SPIClass SPI_A(FSPI); + spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); + SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 + LOG_DEBUG("Init SPI A ok"); +#ifdef CH_B_ENABLE + delay(50); + SPIClass SPI_B(HSPI); + spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); + SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 + LOG_DEBUG("Init SPI B ok"); +#endif + if (!spiA_ok || !spiB_ok) { LOG_ERROR("Unable to Initialize SPI Busses"); LOG_ERROR("5 seconds to restart..."); + //vTaskDelay(pdMS_TO_TICKS(5000)); + //esp_restart(); + } + //dev->m_spi_a = std::make_unique(&SPI_A); +#ifdef CH_B_ENABLE + //dev->m_spi_b = std::make_unique(&SPI_B); +#endif + // Init ADCs + dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); + LOG_DEBUG("Init ADC A pointer ok"); + #ifdef CH_B_ENABLE + dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); + LOG_DEBUG("Init ADC B pointer ok"); + #endif + // Configure ADCs + dev->m_adc_a->InitializeADC(); + dev->m_adc_a->setPGA(PGA_1); + dev->m_adc_a->setDRATE(DRATE_7500SPS); + LOG_DEBUG("Init ADC A params ok"); + #ifdef CH_B_ENABLE + dev->m_adc_b->InitializeADC(); + dev->m_adc_b->setPGA(PGA_1); + dev->m_adc_b->setDRATE(DRATE_7500SPS); + LOG_DEBUG("Init ADC B params ok"); +#endif + LOG_DEBUG("Init SPI OK"); + + //////// INIT I2C INTERFACES //////// + LOG_DEBUG("Init I2C Interfaces"); + bool i2c_ok = true; + i2c_ok = Wire.begin(); + if (!i2c_ok) + { + LOG_ERROR("Unable to Initialize I2C Bus"); + LOG_ERROR("5 seconds to restart..."); vTaskDelay(pdMS_TO_TICKS(5000)); esp_restart(); } - LOG_DEBUG("Init SPI OK"); - // Resources Initialization - std::shared_ptr dev = std::make_shared(); - // dev->m_spi_a = std::make_unique(SPI_A); - // dev->m_spi_b = std::make_unique(SPI_B); - - // // Init ADC_A - // dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); - // dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); - - // dev->m_adc_a->InitializeADC(); - // dev->m_adc_a->setPGA(PGA_1); - // dev->m_adc_a->setDRATE(DRATE_7500SPS); - - // dev->m_adc_b->InitializeADC(); - // dev->m_adc_b->setPGA(PGA_1); - // dev->m_adc_b->setDRATE(DRATE_7500SPS); + // Init IO Expanders + dev->m_ext_io = std::make_unique(Wire, dev->m_i2c_mutex, EXPANDER_ALL_INTERRUPT); + //////// INIT REALTIME TASKS PARAMETERS //////// const rtIgnitionTask::rtTaskParams taskA_params{ .rt_running = true, .name = "rtIgnTask_A", @@ -184,9 +213,10 @@ void loop() .rt_queue = nullptr, .dev = dev}; - auto task_A = rtIgnitionTask(taskA_params, 4096, 256, CORE_0, fs_mutex); + //////// SPAWN REALTIME TASKS //////// + auto task_A = rtIgnitionTask(taskA_params, PSRAM_MAX, QUEUE_MAX, CORE_0, fs_mutex); delay(50); - auto task_B = rtIgnitionTask(taskB_params, 4096, 256, CORE_1, fs_mutex); + auto task_B = rtIgnitionTask(taskB_params, PSRAM_MAX, QUEUE_MAX, CORE_1, fs_mutex); // Ignition A on Core 0 auto ignA_task_success = task_A.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL; @@ -206,22 +236,26 @@ void loop() { led.setStatus(RGBled::LedStatus::ERROR); LOG_ERROR("Unable to start realtime tasks"); - } else - LOG_DEBUG("Real Time Tasks A & B initialized"); - led.setStatus(RGBled::LedStatus::OK); + } + else + { + LOG_DEBUG("Real Time Tasks A & B initialized"); + led.setStatus(RGBled::LedStatus::OK); + } - AstroWebServer webPage(80, LittleFS); // Initialize webserver and Websocket + //////// SPAWN WEBSERVER and WEBSOCKET //////// + AstroWebServer webPage(80, LittleFS); ArduinoJson::JsonDocument json_data; bool data_a, data_b; - task_A.onMessage([&webPage, &json_data, &data_a](ignitionBoxStatusFiltered sts){ + task_A.onMessage([&webPage, &json_data, &data_a](ignitionBoxStatusFiltered sts) + { json_data["box_a"] = sts.toJson(); - data_a = true; - }); + data_a = true; }); - task_B.onMessage([&webPage, &json_data, &data_b](ignitionBoxStatusFiltered sts){ + task_B.onMessage([&webPage, &json_data, &data_b](ignitionBoxStatusFiltered sts) + { json_data["box_b"] = sts.toJson(); - data_b = true; - }); + data_b = true; }); // task_A.enableSave(true, "ignitionA_test.csv"); // task_B.enableSave(true, "ignitionB_test.csv"); @@ -238,7 +272,8 @@ void loop() printRunningTasksMod(Serial); monitor_loop = millis(); } - if ((data_a && data_b) || (this_loop - data_loop > 500)) { + if ((data_a && data_b) || (this_loop - data_loop > 500)) + { webPage.sendWsData(json_data.as()); json_data.clear(); data_a = data_b = false; diff --git a/RotaxMonitor/src/pins.h b/RotaxMonitor/src/pins.h index 1104ac2..562c76f 100644 --- a/RotaxMonitor/src/pins.h +++ b/RotaxMonitor/src/pins.h @@ -79,86 +79,87 @@ #define SPARK_PIN_B12 1 #define SPARK_PIN_B34 2 -// ===================== -// PCA9555 I/O EXPANDER BOX_A -// ===================== +// +++++++++++++++++++++ +// MACRO TO COMBINE PIN NUMBER AND ADDRESS +#define PIN2ADDR(p, a) ((1UL << p) | ((uint32_t)(a) << 16)) +// +++++++++++++++++++++ -#define EXPANDER_A_ADDR 0x010101 +// ===================== +// PCA9555 I/O EXPANDER INTERRUPT (Common) +// ===================== +#define EXPANDER_ALL_INTERRUPT 17 + +// ===================== +// PCA9555 I/O EXPANDER BOX_A (OUT) +// ===================== +#define EXPANDER_A_OUT_ADDR 0xFF // --- DIGITAL POT CHIP SELECT LINES --- -#define POT_CS_A12 0 -#define POT_CS_A34 1 +#define POT_CS_A12 PIN2ADDR(0, EXPANDER_A_OUT_ADDR) +#define POT_CS_A34 PIN2ADDR(1, EXPANDER_A_OUT_ADDR) // --- SOFT START FORCE LINES --- -#define SS_FORCE_A 2 -#define SS_INIBHIT_A12 3 -#define SS_INHIBIT_A34 4 +#define SS_FORCE_A PIN2ADDR(2, EXPANDER_A_OUT_ADDR) +#define SS_INIBHIT_A12 PIN2ADDR(3, EXPANDER_A_OUT_ADDR) +#define SS_INHIBIT_A34 PIN2ADDR(4, EXPANDER_A_OUT_ADDR) // --- SAMPLE AND HOLD ARM AND DISCHARGE --- -#define SH_DISCH_A12 5 -#define SH_DISCH_A34 6 -#define SH_ARM_A12 7 -#define SH_ARM_A34 8 +#define SH_DISCH_A12 PIN2ADDR(5, EXPANDER_A_OUT_ADDR) +#define SH_DISCH_A34 PIN2ADDR(6, EXPANDER_A_OUT_ADDR) +#define SH_ARM_A12 PIN2ADDR(7, EXPANDER_A_OUT_ADDR) +#define SH_ARM_A34 PIN2ADDR(8, EXPANDER_A_OUT_ADDR) // --- RELAY --- -#define RELAY_IN_A12 9 -#define RELAY_OUT_A12 10 -#define RELAY_IN_A34 11 -#define RELAY_OUT_A34 12 - -// --- STATUS / BUTTON --- -#define STA_2 13 -#define STA_3 14 -#define STA_4 15 +#define RELAY_IN_A12 PIN2ADDR(9, EXPANDER_A_OUT_ADDR) +#define RELAY_OUT_A12 PIN2ADDR(10, EXPANDER_A_OUT_ADDR) +#define RELAY_IN_A34 PIN2ADDR(11, EXPANDER_A_OUT_ADDR) +#define RELAY_OUT_A34 PIN2ADDR(12, EXPANDER_A_OUT_ADDR) // ===================== -// PCA9555 I/O EXPANDER BOX_B +// PCA9555 I/O EXPANDER BOX_A (IN) // ===================== +#define EXPANDER_A_IN_ADDR 0xFF -#define EXPANDER_B_ADDR 0x101010 +#define SS_A12_ON PIN2ADDR(0, EXPANDER_A_IN_ADDR) +#define SS_A12_OFF PIN2ADDR(1, EXPANDER_A_IN_ADDR) +#define SS_A34_ON PIN2ADDR(2, EXPANDER_A_IN_ADDR) +#define SS_A34_OFF PIN2ADDR(3, EXPANDER_A_IN_ADDR) + +// ===================== +// PCA9555 I/O EXPANDER BOX_B (OUT) +// ===================== +#define EXPANDER_B_OUT_ADDR 0xFF // --- DIGITAL POT CHIP SELECT LINES --- -#define POT_CS_B12 0 -#define POT_CS_B34 1 +#define POT_CS_B12 PIN2ADDR(0, EXPANDER_B_OUT_ADDR) +#define POT_CS_B34 PIN2ADDR(1, EXPANDER_B_OUT_ADDR) // --- SOFT START FORCE LINES --- -#define SS_FORCE_B 2 -#define SS_INIBHIT_B12 3 -#define SS_INHIBIT_B34 4 +#define SS_FORCE_B PIN2ADDR(2, EXPANDER_B_OUT_ADDR) +#define SS_INIBHIT_B12 PIN2ADDR(3, EXPANDER_B_OUT_ADDR) +#define SS_INHIBIT_B34 PIN2ADDR(4, EXPANDER_B_OUT_ADDR) // --- SAMPLE AND HOLD ARM AND DISCHARGE --- -#define SH_DISCH_B12 5 -#define SH_DISCH_B34 6 -#define SH_ARM_B12 7 -#define SH_ARM_B34 8 +#define SH_DISCH_B12 PIN2ADDR(5, EXPANDER_B_OUT_ADDR) +#define SH_DISCH_B34 PIN2ADDR(6, EXPANDER_B_OUT_ADDR) +#define SH_ARM_B12 PIN2ADDR(7, EXPANDER_B_OUT_ADDR) +#define SH_ARM_B34 PIN2ADDR(8, EXPANDER_B_OUT_ADDR) // --- RELAY --- -#define RELAY_IN_B12 9 -#define RELAY_OUT_B12 10 -#define RELAY_IN_B34 11 -#define RELAY_OUT_B34 12 - -// --- STATUS / BUTTON --- -#define STA_2 13 -#define STA_3 14 -#define STA_4 15 +#define RELAY_IN_B12 PIN2ADDR(9, EXPANDER_B_OUT_ADDR) +#define RELAY_OUT_B12 PIN2ADDR(10, EXPANDER_B_OUT_ADDR) +#define RELAY_IN_B34 PIN2ADDR(11, EXPANDER_B_OUT_ADDR) +#define RELAY_OUT_B34 PIN2ADDR(12, EXPANDER_B_OUT_ADDR) // ===================== -// PCA9555 I/O EXPANDER INPUTS A+B +// PCA9555 I/O EXPANDER BOX_B (IN) // ===================== +#define EXPANDER_B_IN_ADDR 0xFF -#define EXPANDER_IN_ADDR 0x0a0a0a - -#define SS_A12_ON -#define SS_A12_OFF -#define SS_A34_ON -#define SS_A34_OFF - -#define SS_B12_ON -#define SS_B12_OFF -#define SS_B34_ON -#define SS_B34_OFF - +#define SS_B12_ON PIN2ADDR(0, EXPANDER_B_IN_ADDR) +#define SS_B12_OFF PIN2ADDR(1, EXPANDER_B_IN_ADDR) +#define SS_B34_ON PIN2ADDR(2, EXPANDER_B_IN_ADDR) +#define SS_B34_OFF PIN2ADDR(3, EXPANDER_B_IN_ADDR) // Init Pin Functions inline void initTriggerPinsInputs() diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index f691590..9c8416b 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -39,7 +39,7 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) QueueHandle_t rt_queue = params->rt_queue; Devices *dev = params->dev.get(); ADS1256 *adc = dev->m_adc_a.get(); - PCA9555 *io = dev->m_expander_a.get(); + ExternalIO* io = dev->m_ext_io.get(); TaskStatus_t rt_task_info; vTaskGetInfo(NULL, &rt_task_info, pdFALSE, eInvalid); diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index bfe9958..e5feb9e 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -59,19 +59,19 @@ public: struct rtTaskIOParams { const uint32_t expander_addr; - const uint8_t pot_cs_12; - const uint8_t pot_cs_34; - const uint8_t ss_force; - const uint8_t ss_inhibit_12; - const uint8_t ss_inhibit_34; - const uint8_t sh_disch_12; - const uint8_t sh_disch_34; - const uint8_t sh_arm_12; - const uint8_t sh_arm_34; - const uint8_t relay_in_12; - const uint8_t relay_in_34; - const uint8_t relay_out_12; - const uint8_t relay_out_34; + const uint32_t pot_cs_12; + const uint32_t pot_cs_34; + const uint32_t ss_force; + const uint32_t ss_inhibit_12; + const uint32_t ss_inhibit_34; + const uint32_t sh_disch_12; + const uint32_t sh_disch_34; + const uint32_t sh_arm_12; + const uint32_t sh_arm_34; + const uint32_t relay_in_12; + const uint32_t relay_in_34; + const uint32_t relay_out_12; + const uint32_t relay_out_34; }; // RT task parameters From 8171cab9cbaa8ede7dc8562eefec278a187c44bd Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Tue, 14 Apr 2026 14:16:11 +0200 Subject: [PATCH 32/38] adc ok --- RotaxMonitor/lib/ADS1256/ADS1256.cpp | 9 --------- RotaxMonitor/src/devices.h | 2 +- RotaxMonitor/src/main.cpp | 20 ++++++++------------ RotaxMonitor/src/pins.h | 6 ------ RotaxMonitor/src/tasks.cpp | 7 +++++-- 5 files changed, 14 insertions(+), 30 deletions(-) diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.cpp b/RotaxMonitor/lib/ADS1256/ADS1256.cpp index 7a8f51f..2841ae5 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.cpp +++ b/RotaxMonitor/lib/ADS1256/ADS1256.cpp @@ -47,7 +47,6 @@ ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYN // Initialization void ADS1256::InitializeADC() { - LOG_DEBUG("Initialize ADC"); // Chip select LOW CS_LOW(); @@ -77,27 +76,22 @@ void ADS1256::InitializeADC() _STATUS = 0b00110110; // BUFEN and ACAL enabled, Order is MSB, rest is read only writeRegister(STATUS_REG, _STATUS); delay(200); - LOG_DEBUG("Status REG OK"); _MUX = 0b00000001; // MUX AIN0+AIN1 writeRegister(MUX_REG, _MUX); delay(200); - LOG_DEBUG("Mux REG OK"); _ADCON = 0b00000000; // ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) writeRegister(ADCON_REG, _ADCON); delay(200); - LOG_DEBUG("Adcon REG OK"); updateConversionParameter(); _DRATE = 0b10000010; // 100SPS writeRegister(DRATE_REG, _DRATE); delay(200); - LOG_DEBUG("Drate REG OK"); sendDirectCommand(0b11110000); // Offset and self-gain calibration - LOG_DEBUG("Direct Command OK"); delay(200); _isAcquisitionRunning = false; // MCU will be waiting to start a continuous acquisition @@ -131,7 +125,6 @@ void ADS1256::stopConversion() // Sending SDATAC to stop the continuous conversi void ADS1256::setDRATE(uint8_t drate) // Setting DRATE (sampling frequency) { - LOG_DEBUG("SetDrate ADC"); writeRegister(DRATE_REG, drate); _DRATE = drate; delayMicroseconds(500); @@ -139,7 +132,6 @@ void ADS1256::setDRATE(uint8_t drate) // Setting DRATE (sampling frequency) void ADS1256::setMUX(uint8_t mux) // Setting MUX (input channel) { - LOG_DEBUG("SetMux ADC"); writeRegister(MUX_REG, mux); _MUX = mux; // delayMicroseconds(500); @@ -147,7 +139,6 @@ void ADS1256::setMUX(uint8_t mux) // Setting MUX (input channel) void ADS1256::setPGA(uint8_t pga) // Setting PGA (input voltage range) { - LOG_DEBUG("SetPga ADC"); _PGA = pga; _ADCON = readRegister(ADCON_REG); // Read the most recent value of the register diff --git a/RotaxMonitor/src/devices.h b/RotaxMonitor/src/devices.h index 70a8b7d..a9d6f25 100644 --- a/RotaxMonitor/src/devices.h +++ b/RotaxMonitor/src/devices.h @@ -51,7 +51,7 @@ inline float adcReadChannel(ADS1256 *adc, const uint8_t ch) { adc->setMUX(ch); // scarta 3 conversioni - for (int i = 0; i < 3; i++) + for (int i = 0; i < 5; i++) { adc->readSingle(); } diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 68afb1f..386a564 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -17,7 +17,7 @@ #include // Defines to enable channel B -#define CH_B_ENABLE +// #define CH_B_ENABLE // Debug Defines #define WIFI_SSID "AstroRotaxMonitor" @@ -32,7 +32,7 @@ void setup() // Setup Logger LOG_ATTACH_SERIAL(Serial); - LOG_SET_LEVEL(DebugLogLevel::LVL_DEBUG); + LOG_SET_LEVEL(DebugLogLevel::LVL_INFO); // Print Processor Info LOG_DEBUG("ESP32 Chip:", ESP.getChipModel()); @@ -108,37 +108,33 @@ void loop() { LOG_ERROR("Unable to Initialize SPI Busses"); LOG_ERROR("5 seconds to restart..."); - //vTaskDelay(pdMS_TO_TICKS(5000)); - //esp_restart(); + vTaskDelay(pdMS_TO_TICKS(5000)); + esp_restart(); } - //dev->m_spi_a = std::make_unique(&SPI_A); + dev->m_spi_a.reset(&SPI_A); #ifdef CH_B_ENABLE - //dev->m_spi_b = std::make_unique(&SPI_B); + dev->m_spi_b.reset(&SPI_B); #endif // Init ADCs dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); - LOG_DEBUG("Init ADC A pointer ok"); #ifdef CH_B_ENABLE dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); - LOG_DEBUG("Init ADC B pointer ok"); #endif // Configure ADCs dev->m_adc_a->InitializeADC(); dev->m_adc_a->setPGA(PGA_1); dev->m_adc_a->setDRATE(DRATE_7500SPS); - LOG_DEBUG("Init ADC A params ok"); #ifdef CH_B_ENABLE dev->m_adc_b->InitializeADC(); dev->m_adc_b->setPGA(PGA_1); dev->m_adc_b->setDRATE(DRATE_7500SPS); - LOG_DEBUG("Init ADC B params ok"); #endif LOG_DEBUG("Init SPI OK"); //////// INIT I2C INTERFACES //////// LOG_DEBUG("Init I2C Interfaces"); bool i2c_ok = true; - i2c_ok = Wire.begin(); + i2c_ok = Wire.begin(SDA, SCL, 100000); if (!i2c_ok) { LOG_ERROR("Unable to Initialize I2C Bus"); @@ -148,7 +144,7 @@ void loop() } // Init IO Expanders - dev->m_ext_io = std::make_unique(Wire, dev->m_i2c_mutex, EXPANDER_ALL_INTERRUPT); + // dev->m_ext_io = std::make_unique(Wire, dev->m_i2c_mutex, EXPANDER_ALL_INTERRUPT); //////// INIT REALTIME TASKS PARAMETERS //////// const rtIgnitionTask::rtTaskParams taskA_params{ diff --git a/RotaxMonitor/src/pins.h b/RotaxMonitor/src/pins.h index 562c76f..8ed24f7 100644 --- a/RotaxMonitor/src/pins.h +++ b/RotaxMonitor/src/pins.h @@ -53,12 +53,6 @@ #define ADC_B_CS 21 #define ADC_B_DRDY 47 -// ===================== -// DIGITAL POT -// ===================== -#define POT_A_CS 18 -#define POT_B_CS 35 - // ===================== // TRIGGER INPUT INTERRUPTS // ===================== diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 9c8416b..dcf3587 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -1,6 +1,7 @@ #include "tasks.h" #include #include +#include //// GLOBAL STATIC FUNCTIONS @@ -38,7 +39,8 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) const rtTaskIOParams rt_rst = params->rt_io; // copy to avoid external override QueueHandle_t rt_queue = params->rt_queue; Devices *dev = params->dev.get(); - ADS1256 *adc = dev->m_adc_a.get(); + ADS1256 *adc = params->name == "rtIgnTask_A" ? dev->m_adc_a.get() : dev->m_adc_b.get(); + std::mutex& spi_mutex = params->name == "rtIgnTask_A" ? dev->m_spi_a_mutex : dev->m_spi_b_mutex; ExternalIO* io = dev->m_ext_io.get(); TaskStatus_t rt_task_info; @@ -234,6 +236,7 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) // read adc channels: pickup12, out12 [ pos + neg ] if (adc) // read only if adc initialized { + std::lock_guard lock (spi_mutex); uint32_t start_adc_read = esp_timer_get_time(); // from peak detector circuits ign_box_sts.coils12.peak_p_in = adcReadChannel(adc, ADC_CH_PEAK_12P_IN); @@ -256,7 +259,7 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) // [TODO] code to reset sample and hold and arm trigger level detectors } else - vTaskDelay(pdMS_TO_TICKS(1)); + vTaskDelay(pdMS_TO_TICKS(2)); // send essage to main loop with ignition info, by copy so local static variable is ok if (rt_queue) From 1b7a531d540296a7b51216a48e0e60001fe741fa Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 17 Apr 2026 09:11:41 +0200 Subject: [PATCH 33/38] Updated test instrument with cli commands --- RotaxMonitorTester/platformio.ini | 2 +- RotaxMonitorTester/src/colors.h | 12 +++ RotaxMonitorTester/src/main.cpp | 171 +++++++++++++++++++++--------- 3 files changed, 135 insertions(+), 50 deletions(-) create mode 100644 RotaxMonitorTester/src/colors.h diff --git a/RotaxMonitorTester/platformio.ini b/RotaxMonitorTester/platformio.ini index 2653613..51de170 100644 --- a/RotaxMonitorTester/platformio.ini +++ b/RotaxMonitorTester/platformio.ini @@ -22,7 +22,7 @@ build_type = release [env:esp32-devtest-debug] board = esp32dev platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip - +framework = arduino lib_deps = hideakitai/DebugLog@^0.8.4 board_build.flash_size = 4MB diff --git a/RotaxMonitorTester/src/colors.h b/RotaxMonitorTester/src/colors.h new file mode 100644 index 0000000..2e313ca --- /dev/null +++ b/RotaxMonitorTester/src/colors.h @@ -0,0 +1,12 @@ +#pragma once + +// ANSI colors +#define COLOR_RESET "\033[0m" +#define COLOR_RED "\033[31m" +#define COLOR_GREEN "\033[32m" +#define COLOR_BLUE "\033[34m" +#define COLOR_MAGENTA "\033[35m" +#define COLOR_CYAN "\033[36m" +#define COLOR_YELLOW "\033[33m" +#define COLOR_WHITE "\033[37m" +#define COLOR_LBLUE "\033[94m" diff --git a/RotaxMonitorTester/src/main.cpp b/RotaxMonitorTester/src/main.cpp index e2fafd5..defe9a1 100644 --- a/RotaxMonitorTester/src/main.cpp +++ b/RotaxMonitorTester/src/main.cpp @@ -4,6 +4,8 @@ #include #include "timer.h" +#include "colors.h" + #include static hw_timer_t *timerA = NULL; @@ -17,6 +19,12 @@ static uint32_t count = 0; #define SPARK_DLY_MIN 10 #define SPARK_DLY_MAX 490 +#define COIL_PULSE_MIN 100 +#define COIL_PULSE_MAX 1000 + +#define SPARK_PULSE_MIN 10 +#define SPARK_PULSE_MAX 500 + #define PAUSE_LONG_MIN 5000 #define PAUSE_LONG_MAX PAUSE_LONG_MIN * 100 @@ -30,7 +38,8 @@ void clearScreen() Serial.flush(); } -static double filtered_rpm = 0; +static uint32_t set_rpm = 500; +static uint32_t set_delay = 100; static const std::map pin2Name = { {PIN_TRIG_A12P, "HIGH_PIN_TRIG_A12P"}, @@ -68,7 +77,7 @@ static timerStatus stsB = { .clock_period_us = (uint32_t)PERIOD_US, .pause_long_us = 10000, .pause_short_us = 1000, - .coil_pulse_us = 1000, + .coil_pulse_us = 500, .spark_pulse_us = 100, .spark_delay_us = 50, .pins = { @@ -83,11 +92,14 @@ static timerStatus stsB = { static bool isEnabled_A = false; static bool isEnabled_B = false; +static String last_command; + void setup() { Serial.begin(115200); delay(1000); + Serial.setTimeout(100); LOG_ATTACH_SERIAL(Serial); pinMode(PIN_TRIG_A12P, OUTPUT); @@ -133,63 +145,124 @@ void setup() void loop() { - LOG_INFO("Loop: ", count++); - uint32_t spark_delay = (uint32_t)(map(analogRead(SPARK_DELAY_POT), 0, 4096, SPARK_DLY_MIN, SPARK_DLY_MAX) / PERIOD_US); - stsA.spark_delay_us = spark_delay * PERIOD_US; - if (stsA.spark_delay_us > (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2) - { - stsA.soft_start = true; - stsA.spark_delay_us -= (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2; - } - else - { - stsA.soft_start = false; - } - stsB.soft_start = stsA.soft_start; - stsB.spark_delay_us = stsA.spark_delay_us; + clearScreen(); - double new_rpm = (double)(map(analogRead(FREQ_POT), 0, 4096, RPM_MIN, RPM_MAX)); - filtered_rpm = filtered_rpm + 0.1 * (new_rpm - filtered_rpm); - stsA.pause_long_us = (uint32_t)(60000000.0f / filtered_rpm / 2.0f); - stsB.pause_long_us = stsA.pause_long_us; + Serial.printf("\t++++ Loop: %u ++++\n", count++); if (isEnabled_A) - LOG_INFO("==== System A is ENABLED ===="); + Serial.println("==== System A is" COLOR_GREEN " ENABLED" COLOR_RESET " ===="); else - LOG_INFO("==== System A is DISABLED ===="); + Serial.println("==== System A is" COLOR_RED " DISABLED" COLOR_RESET " ===="); if (isEnabled_B) - LOG_INFO("==== System B is ENABLED ===="); + Serial.println("==== System B is" COLOR_GREEN " ENABLED" COLOR_RESET " ===="); else - LOG_INFO("==== System B is DISABLED ===="); + Serial.println("==== System B is" COLOR_RED " DISABLED" COLOR_RESET " ===="); - LOG_INFO("Spark Delay uS: ", stsA.spark_delay_us, "\tSoft Start: ", stsA.soft_start ? "TRUE" : "FALSE"); - LOG_INFO("Engine Rpm: ", (uint32_t)(filtered_rpm)); - LOG_INFO("Coil Pulse: ", stsA.coil_pulse_us, "us"); - LOG_INFO("Spark Pulse: ", stsA.spark_pulse_us, "us"); + Serial.printf("Spark Delay uS: %u\n", stsA.spark_delay_us); + Serial.printf("Soft Start: %s\n", stsA.soft_start ? "ENABLED" : "DISABLED"); + Serial.printf("Engine Rpm: %u\n", (uint32_t)(set_rpm)); + Serial.printf("Coil Pulse: %u uS\n", stsA.coil_pulse_us); + Serial.printf("Spark Pulse: %u uS\n", stsA.spark_pulse_us); + Serial.println(COLOR_CYAN "-------------------------------------"); + Serial.println("E[a/b] > Enable Box a/b | D[a/b] > Disable a/b"); + Serial.println("S[ddd] > Spark Delay | R[dddd] > Engine RPM"); + Serial.println("C[ddd] > Spark Pulse | P[ddd] > Coil Pulse"); + Serial.println("-------------------------------------" COLOR_RESET); + Serial.printf("Last Command: %s\n", last_command.c_str()); - if (digitalRead(ENABLE_PIN_A) == LOW && !isEnabled_A) + auto str = Serial.readStringUntil('\n'); + if (!str.isEmpty()) { - timerStart(timerA); - isEnabled_A = true; - } - else if (digitalRead(ENABLE_PIN_A) == HIGH && isEnabled_A) - { - timerStop(timerA); - isEnabled_A = false; + last_command = str; + const auto cmd = str.charAt(0); + char c; + switch (cmd) + { + case 'E': + { + char box; + sscanf(str.c_str(), "%c%c\n", &c, &box); + if (box == 'a' && !isEnabled_A) + { + timerStart(timerA); + isEnabled_A = true; + } + else if (box == 'b' && !isEnabled_B) + { + timerStart(timerB); + isEnabled_B = true; + } + break; + } + case 'D': + { + char c; + char box; + sscanf(str.c_str(), "%c%c\n", &c, &box); + if (box == 'a' && isEnabled_A) + { + timerStop(timerA); + isEnabled_A = false; + } + else if (box == 'b' && isEnabled_B) + { + timerStop(timerB); + isEnabled_B = false; + } + break; + } + case 'R': + { + int new_rpm; + sscanf(str.c_str(), "%c%d\n", &c, &new_rpm); + new_rpm = min(RPM_MAX, max(RPM_MIN, new_rpm)); + stsA.pause_long_us = (uint32_t)(60000000.0f / (float)new_rpm / 2.0f); + stsB.pause_long_us = stsA.pause_long_us; + set_rpm = (uint32_t)new_rpm; + break; + } + case 'S': + { + int new_delay; + sscanf(str.c_str(), "%c%d\n", &c, &new_delay); + new_delay = min(SPARK_DLY_MAX, max(SPARK_DLY_MIN, new_delay)); + stsA.spark_delay_us = (uint32_t)(new_delay); + if (stsA.spark_delay_us > (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2) + { + stsA.soft_start = true; + stsA.spark_delay_us -= (SPARK_DLY_MIN + SPARK_DLY_MAX) / 2; + } + else + { + stsA.soft_start = false; + } + stsB.soft_start = stsA.soft_start; + stsB.spark_delay_us = stsA.spark_delay_us; + break; + } + case 'P': + { + int new_pulse; + sscanf(str.c_str(), "%c%d\n", &c, &new_pulse); + new_pulse = min(COIL_PULSE_MAX, max(COIL_PULSE_MIN, new_pulse)); + stsA.coil_pulse_us = stsB.coil_pulse_us = (uint32_t)new_pulse; + break; + } + case 'C': + { + int new_pulse; + sscanf(str.c_str(), "%c%d\n", &c, &new_pulse); + new_pulse = min(SPARK_PULSE_MAX, max(SPARK_PULSE_MIN, new_pulse)); + stsA.spark_pulse_us = stsB.spark_pulse_us = (uint32_t)new_pulse; + break; + } + default: + break; + } + Serial.read(); } - if (digitalRead(ENABLE_PIN_B) == LOW && !isEnabled_B) - { - timerStart(timerB); - isEnabled_B = true; - } - else if (digitalRead(ENABLE_PIN_B) == HIGH && isEnabled_B) - { - timerStop(timerB); - isEnabled_B = false; - } - - delay(100); - clearScreen(); + str.clear(); + delay(1000); } From 5aa5aaa07a376f484bf54d95fcae91569a6b478f Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 17 Apr 2026 09:13:05 +0200 Subject: [PATCH 34/38] ADC Testing --- RotaxMonitor/lib/ADS1256/ADS1256.cpp | 940 +++++++++++++-------------- RotaxMonitor/src/datasave.cpp | 48 +- RotaxMonitor/src/devices.h | 7 +- RotaxMonitor/src/main.cpp | 35 +- RotaxMonitor/src/tasks.cpp | 30 +- 5 files changed, 530 insertions(+), 530 deletions(-) diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.cpp b/RotaxMonitor/lib/ADS1256/ADS1256.cpp index 2841ae5..3372b47 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.cpp +++ b/RotaxMonitor/lib/ADS1256/ADS1256.cpp @@ -1,4 +1,4 @@ -// ADS1256 cpp file +//ADS1256 cpp file /* Name: ADS1256.cpp Created: 2022/07/14 @@ -15,408 +15,391 @@ #include "ADS1256.h" #include "SPI.h" -#include "DebugLog.h" - #define convertSigned24BitToLong(value) ((value) & (1l << 23) ? (value) - 0x1000000 : value) -// Constructor -ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYNC_pin, const int8_t CS_pin, float VREF, SPIClass *spi) : _spi(spi), - _DRDY_pin(DRDY_pin), _RESET_pin(RESET_pin), _SYNC_pin(SYNC_pin), _CS_pin(CS_pin), _VREF(VREF), _PGA(0) -{ - pinMode(_DRDY_pin, INPUT); - - if (RESET_pin != PIN_UNUSED) +//Constructor +ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYNC_pin, const int8_t CS_pin,float VREF, SPIClass* spi): _spi(spi), + _DRDY_pin(DRDY_pin), _RESET_pin(RESET_pin), _SYNC_pin(SYNC_pin), _CS_pin(CS_pin), _VREF(VREF), _PGA(0) +{ + pinMode(_DRDY_pin, INPUT); + + if(RESET_pin != PIN_UNUSED) { - pinMode(_RESET_pin, OUTPUT); + pinMode(_RESET_pin, OUTPUT); } - - if (SYNC_pin != PIN_UNUSED) - { - pinMode(_SYNC_pin, OUTPUT); - } - - if (CS_pin != PIN_UNUSED) - { - pinMode(_CS_pin, OUTPUT); - } - - LOG_DEBUG("ADC Class Init OK"); - updateConversionParameter(); -} - -// Initialization -void ADS1256::InitializeADC() -{ - // Chip select LOW - CS_LOW(); - - // We do a manual chip reset on the ADS1256 - Datasheet Page 27/ RESET - if (_RESET_pin != PIN_UNUSED) - { - digitalWrite(_RESET_pin, LOW); - delay(200); - digitalWrite(_RESET_pin, HIGH); // RESET is set to high - delay(1000); - } - - // Sync pin is also treated if it is defined - if (_SYNC_pin != PIN_UNUSED) - { - digitalWrite(_SYNC_pin, HIGH); // RESET is set to high - } - -#ifndef ADS1256_SPI_ALREADY_STARTED // Guard macro to allow external initialization of the SPI - //_spi->begin(); -#endif - - // Applying arbitrary default values to speed up the starting procedure if the user just want to get quick readouts - // We both pass values to the variables and then send those values to the corresponding registers - delay(200); - - _STATUS = 0b00110110; // BUFEN and ACAL enabled, Order is MSB, rest is read only - writeRegister(STATUS_REG, _STATUS); - delay(200); - - _MUX = 0b00000001; // MUX AIN0+AIN1 - writeRegister(MUX_REG, _MUX); - delay(200); - - _ADCON = 0b00000000; // ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) - writeRegister(ADCON_REG, _ADCON); - delay(200); - - updateConversionParameter(); - - _DRATE = 0b10000010; // 100SPS - writeRegister(DRATE_REG, _DRATE); - delay(200); - sendDirectCommand(0b11110000); // Offset and self-gain calibration - delay(200); + if(SYNC_pin != PIN_UNUSED) + { + pinMode(_SYNC_pin, OUTPUT); + } + + if(CS_pin != PIN_UNUSED) + { + pinMode(_CS_pin, OUTPUT); + } + + updateConversionParameter(); +} - _isAcquisitionRunning = false; // MCU will be waiting to start a continuous acquisition +//Initialization +void ADS1256::InitializeADC() +{ + //Chip select LOW + CS_LOW(); + + //We do a manual chip reset on the ADS1256 - Datasheet Page 27/ RESET + if(_RESET_pin != PIN_UNUSED) + { + digitalWrite(_RESET_pin, LOW); + delay(200); + digitalWrite(_RESET_pin, HIGH); //RESET is set to high + delay(1000); + } + + //Sync pin is also treated if it is defined + if(_SYNC_pin != PIN_UNUSED) + { + digitalWrite(_SYNC_pin, HIGH); //RESET is set to high + } + +#ifndef ADS1256_SPI_ALREADY_STARTED //Guard macro to allow external initialization of the SPI + _spi->begin(); +#endif + + //Applying arbitrary default values to speed up the starting procedure if the user just want to get quick readouts + //We both pass values to the variables and then send those values to the corresponding registers + delay(200); + + _STATUS = 0b00110110; //BUFEN and ACAL enabled, Order is MSB, rest is read only + writeRegister(STATUS_REG, _STATUS); + delay(200); + + _MUX = 0b00000001; //MUX AIN0+AIN1 + writeRegister(MUX_REG, _MUX); + delay(200); + + _ADCON = 0b00000000; //ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) + writeRegister(ADCON_REG, _ADCON); + delay(200); + + updateConversionParameter(); + + _DRATE = 0b10000010; //100SPS + writeRegister(DRATE_REG, _DRATE); + delay(200); + + sendDirectCommand(0b11110000); //Offset and self-gain calibration + delay(200); + + _isAcquisitionRunning = false; //MCU will be waiting to start a continuous acquisition } void ADS1256::waitForLowDRDY() -{ - while (digitalRead(_DRDY_pin) == HIGH) - { - } +{ + while (digitalRead(_DRDY_pin) == HIGH) {} } void ADS1256::waitForHighDRDY() -{ -#if F_CPU >= 48000000 // Fast MCUs need this protection to wait until DRDY goes high after a conversion - while (digitalRead(_DRDY_pin) == LOW) - { - } +{ +#if F_CPU >= 48000000 //Fast MCUs need this protection to wait until DRDY goes high after a conversion + while (digitalRead(_DRDY_pin) == LOW) {} #endif } -void ADS1256::stopConversion() // Sending SDATAC to stop the continuous conversion -{ - waitForLowDRDY(); // SDATAC should be called after DRDY goes LOW (p35. Figure 33) - _spi->transfer(0b00001111); // Send SDATAC to the ADC - CS_HIGH(); // We finished the command sequence, so we switch it back to HIGH +void ADS1256::stopConversion() //Sending SDATAC to stop the continuous conversion +{ + waitForLowDRDY(); //SDATAC should be called after DRDY goes LOW (p35. Figure 33) + _spi->transfer(0b00001111); //Send SDATAC to the ADC + CS_HIGH(); //We finished the command sequence, so we switch it back to HIGH _spi->endTransaction(); - - _isAcquisitionRunning = false; // Reset to false, so the MCU will be able to start a new conversion + + _isAcquisitionRunning = false; //Reset to false, so the MCU will be able to start a new conversion } -void ADS1256::setDRATE(uint8_t drate) // Setting DRATE (sampling frequency) -{ +void ADS1256::setDRATE(uint8_t drate) //Setting DRATE (sampling frequency) +{ writeRegister(DRATE_REG, drate); _DRATE = drate; - delayMicroseconds(500); + delay(200); } -void ADS1256::setMUX(uint8_t mux) // Setting MUX (input channel) -{ +void ADS1256::setMUX(uint8_t mux) //Setting MUX (input channel) +{ writeRegister(MUX_REG, mux); _MUX = mux; - // delayMicroseconds(500); + delay(200); } -void ADS1256::setPGA(uint8_t pga) // Setting PGA (input voltage range) -{ +void ADS1256::setPGA(uint8_t pga) //Setting PGA (input voltage range) +{ _PGA = pga; - _ADCON = readRegister(ADCON_REG); // Read the most recent value of the register - + _ADCON = readRegister(ADCON_REG); //Read the most recent value of the register + _ADCON = (_ADCON & 0b11111000) | (_PGA & 0b00000111); // Clearing and then setting bits 2-0 based on pga - - writeRegister(ADCON_REG, _ADCON); - delayMicroseconds(1000); // Delay to allow the PGA to settle after changing its value - - updateConversionParameter(); // Update the multiplier according top the new PGA value + + writeRegister(ADCON_REG, _ADCON); + delay(200); + + updateConversionParameter(); //Update the multiplier according top the new PGA value } -uint8_t ADS1256::getPGA() // Reading PGA from the ADCON register +uint8_t ADS1256::getPGA() //Reading PGA from the ADCON register { - uint8_t pgaValue = readRegister(ADCON_REG) & 0b00000111; - // Reading the ADCON_REG and keeping the first three bits. - - return (pgaValue); + uint8_t pgaValue = readRegister(ADCON_REG) & 0b00000111; + //Reading the ADCON_REG and keeping the first three bits. + + return(pgaValue); } -void ADS1256::setCLKOUT(uint8_t clkout) // Setting CLKOUT +void ADS1256::setCLKOUT(uint8_t clkout) //Setting CLKOUT { - _ADCON = readRegister(ADCON_REG); // Read the most recent value of the register - - // Values: 0, 1, 2, 3 - - if (clkout == 0) + _ADCON = readRegister(ADCON_REG); //Read the most recent value of the register + + //Values: 0, 1, 2, 3 + + if(clkout == 0) { - // 00 + //00 bitWrite(_ADCON, 6, 0); - bitWrite(_ADCON, 5, 0); + bitWrite(_ADCON, 5, 0); } - else if (clkout == 1) + else if(clkout == 1) { - // 01 (default) + //01 (default) bitWrite(_ADCON, 6, 0); - bitWrite(_ADCON, 5, 1); + bitWrite(_ADCON, 5, 1); } - else if (clkout == 2) + else if(clkout == 2) { - // 10 + //10 bitWrite(_ADCON, 6, 1); - bitWrite(_ADCON, 5, 0); + bitWrite(_ADCON, 5, 0); } - else if (clkout == 3) + else if(clkout == 3) { - // 11 + //11 bitWrite(_ADCON, 6, 1); - bitWrite(_ADCON, 5, 1); + bitWrite(_ADCON, 5, 1); } - else - { - } - + else{} + writeRegister(ADCON_REG, _ADCON); delay(100); } -void ADS1256::setSDCS(uint8_t sdcs) // Setting SDCS +void ADS1256::setSDCS(uint8_t sdcs) //Setting SDCS { - _ADCON = readRegister(ADCON_REG); // Read the most recent value of the register - - // Values: 0, 1, 2, 3 - - if (sdcs == 0) + _ADCON = readRegister(ADCON_REG); //Read the most recent value of the register + + //Values: 0, 1, 2, 3 + + if(sdcs == 0) { - // 00 (default) + //00 (default) bitWrite(_ADCON, 4, 0); - bitWrite(_ADCON, 3, 0); + bitWrite(_ADCON, 3, 0); } - else if (sdcs == 1) + else if(sdcs == 1) { - // 01 + //01 bitWrite(_ADCON, 4, 0); - bitWrite(_ADCON, 3, 1); + bitWrite(_ADCON, 3, 1); } - else if (sdcs == 2) + else if(sdcs == 2) { - // 10 + //10 bitWrite(_ADCON, 4, 1); - bitWrite(_ADCON, 3, 0); + bitWrite(_ADCON, 3, 0); } - else if (sdcs == 3) + else if(sdcs == 3) { - // 11 + //11 bitWrite(_ADCON, 4, 1); - bitWrite(_ADCON, 3, 1); + bitWrite(_ADCON, 3, 1); } - else - { - } - + else{} + writeRegister(ADCON_REG, _ADCON); delay(100); } -void ADS1256::setByteOrder(uint8_t byteOrder) // Setting byte order (MSB/LSB) +void ADS1256::setByteOrder(uint8_t byteOrder) //Setting byte order (MSB/LSB) { - _STATUS = readRegister(STATUS_REG); // Read the most recent value of the register - - if (byteOrder == 0) + _STATUS = readRegister(STATUS_REG); //Read the most recent value of the register + + if(byteOrder == 0) { - // Byte order is MSB (default) + //Byte order is MSB (default) bitWrite(_STATUS, 3, 0); - // Set value of _STATUS at the third bit to 0 + //Set value of _STATUS at the third bit to 0 } - else if (byteOrder == 1) + else if(byteOrder == 1) { - // Byte order is LSB + //Byte order is LSB bitWrite(_STATUS, 3, 1); - // Set value of _STATUS at the third bit to 1 + //Set value of _STATUS at the third bit to 1 } - else - { - } - + else{} + writeRegister(STATUS_REG, _STATUS); delay(100); } -uint8_t ADS1256::getByteOrder() // Getting byte order (MSB/LSB) -{ - uint8_t statusValue = readRegister(STATUS_REG); // Read the whole STATUS register - +uint8_t ADS1256::getByteOrder() //Getting byte order (MSB/LSB) +{ + uint8_t statusValue = readRegister(STATUS_REG); //Read the whole STATUS register + return bitRead(statusValue, 3); } -void ADS1256::setAutoCal(uint8_t acal) // Setting ACAL (Automatic SYSCAL) -{ - _STATUS = readRegister(STATUS_REG); // Read the most recent value of the register - - if (acal == 0) +void ADS1256::setAutoCal(uint8_t acal) //Setting ACAL (Automatic SYSCAL) +{ + _STATUS = readRegister(STATUS_REG); //Read the most recent value of the register + + if(acal == 0) { - // Auto-calibration is disabled (default) + //Auto-calibration is disabled (default) bitWrite(_STATUS, 2, 0); //_STATUS |= B00000000; } - else if (acal == 1) + else if(acal == 1) { - // Auto-calibration is enabled + //Auto-calibration is enabled bitWrite(_STATUS, 2, 1); //_STATUS |= B00000100; } - else - { - } - + else{} + writeRegister(STATUS_REG, _STATUS); delay(100); } -uint8_t ADS1256::getAutoCal() // Getting ACAL (Automatic SYSCAL) -{ - uint8_t statusValue = readRegister(STATUS_REG); // Read the whole STATUS register - +uint8_t ADS1256::getAutoCal() //Getting ACAL (Automatic SYSCAL) +{ + uint8_t statusValue = readRegister(STATUS_REG); //Read the whole STATUS register + return bitRead(statusValue, 2); } -void ADS1256::setBuffer(uint8_t bufen) // Setting input buffer (Input impedance) -{ - _STATUS = readRegister(STATUS_REG); // Read the most recent value of the register - - if (bufen == 0) +void ADS1256::setBuffer(uint8_t bufen) //Setting input buffer (Input impedance) +{ + _STATUS = readRegister(STATUS_REG); //Read the most recent value of the register + + if(bufen == 0) { - // Analog input buffer is disabled (default) + //Analog input buffer is disabled (default) //_STATUS |= B00000000; bitWrite(_STATUS, 1, 0); } - else if (bufen == 1) + else if(bufen == 1) { - // Analog input buffer is enabled (recommended) + //Analog input buffer is enabled (recommended) //_STATUS |= B00000010; bitWrite(_STATUS, 1, 1); } - else - { - } - + else{} + writeRegister(STATUS_REG, _STATUS); delay(100); } -uint8_t ADS1256::getBuffer() // Getting input buffer (Input impedance) -{ - uint8_t statusValue = readRegister(STATUS_REG); // Read the whole STATUS register - +uint8_t ADS1256::getBuffer() //Getting input buffer (Input impedance) +{ + uint8_t statusValue = readRegister(STATUS_REG); //Read the whole STATUS register + return bitRead(statusValue, 1); } -void ADS1256::setGPIO(uint8_t dir0, uint8_t dir1, uint8_t dir2, uint8_t dir3) // Setting GPIO -{ - _GPIO = readRegister(IO_REG); // Read the most recent value of the register - - // Default: 11100000 - DEC: 224 - Ref: p32 I/O section - // Sets D3-D0 as input or output +void ADS1256::setGPIO(uint8_t dir0, uint8_t dir1, uint8_t dir2, uint8_t dir3) //Setting GPIO +{ + _GPIO = readRegister(IO_REG); //Read the most recent value of the register + + //Default: 11100000 - DEC: 224 - Ref: p32 I/O section + //Sets D3-D0 as input or output uint8_t GPIO_bit7, GPIO_bit6, GPIO_bit5, GPIO_bit4; - - // Bit7: DIR3 - if (dir3 == 1) + + //Bit7: DIR3 + if(dir3 == 1) { - GPIO_bit7 = 1; // D3 is input (default) + GPIO_bit7 = 1; //D3 is input (default) } else { - GPIO_bit7 = 0; // D3 is output - } + GPIO_bit7 = 0; //D3 is output + } bitWrite(_GPIO, 7, GPIO_bit7); //----------------------------------------------------- - // Bit6: DIR2 - if (dir2 == 1) + //Bit6: DIR2 + if(dir2 == 1) { - GPIO_bit6 = 1; // D2 is input (default) + GPIO_bit6 = 1; //D2 is input (default) } else { - GPIO_bit6 = 0; // D2 is output + GPIO_bit6 = 0; //D2 is output } bitWrite(_GPIO, 6, GPIO_bit6); //----------------------------------------------------- - // Bit5: DIR1 - if (dir1 == 1) + //Bit5: DIR1 + if(dir1 == 1) { - GPIO_bit5 = 1; // D1 is input (default) + GPIO_bit5 = 1; //D1 is input (default) } else { - GPIO_bit5 = 0; // D1 is output + GPIO_bit5 = 0; //D1 is output } bitWrite(_GPIO, 5, GPIO_bit5); //----------------------------------------------------- - // Bit4: DIR0 - if (dir0 == 1) + //Bit4: DIR0 + if(dir0 == 1) { - GPIO_bit4 = 1; // D0 is input + GPIO_bit4 = 1; //D0 is input } else { - GPIO_bit4 = 0; // D0 is output (default) + GPIO_bit4 = 0; //D0 is output (default) } bitWrite(_GPIO, 4, GPIO_bit4); //----------------------------------------------------- - + writeRegister(IO_REG, _GPIO); delay(100); } -void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, uint8_t dir3value) // Writing GPIO +void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, uint8_t dir3value) //Writing GPIO { _GPIO = readRegister(IO_REG); - - // Sets D3-D0 output values - // It is important that first one must use setGPIO, then writeGPIO - + + //Sets D3-D0 output values + //It is important that first one must use setGPIO, then writeGPIO + uint8_t GPIO_bit3, GPIO_bit2, GPIO_bit1, GPIO_bit0; - - // Bit3: DIR3 - if (dir3value == 1) + + //Bit3: DIR3 + if(dir3value == 1) { GPIO_bit3 = 1; } else { GPIO_bit3 = 0; - } + } bitWrite(_GPIO, 3, GPIO_bit3); //----------------------------------------------------- - // Bit2: DIR2 - if (dir2value == 1) + //Bit2: DIR2 + if(dir2value == 1) { GPIO_bit2 = 1; } else { GPIO_bit2 = 0; - } + } bitWrite(_GPIO, 2, GPIO_bit2); //----------------------------------------------------- - // Bit1: DIR1 - if (dir1value == 1) + //Bit1: DIR1 + if(dir1value == 1) { GPIO_bit1 = 1; } @@ -424,371 +407,360 @@ void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, { GPIO_bit1 = 0; } - bitWrite(_GPIO, 1, GPIO_bit1); + bitWrite(_GPIO, 1, GPIO_bit1); //----------------------------------------------------- - // Bit0: DIR0 - if (dir0value == 1) + //Bit0: DIR0 + if(dir0value == 1) { GPIO_bit0 = 1; } else { GPIO_bit0 = 0; - } + } bitWrite(_GPIO, 0, GPIO_bit0); - //----------------------------------------------------- - + //----------------------------------------------------- + writeRegister(IO_REG, _GPIO); delay(100); } -uint8_t ADS1256::readGPIO(uint8_t gpioPin) // Reading GPIO -{ +uint8_t ADS1256::readGPIO(uint8_t gpioPin) //Reading GPIO +{ uint8_t GPIO_bit3, GPIO_bit2, GPIO_bit1, GPIO_bit0, GPIO_return; - - _GPIO = readRegister(IO_REG); // Read the GPIO register - - // Save each bit values in a variable + + _GPIO = readRegister(IO_REG); //Read the GPIO register + + //Save each bit values in a variable GPIO_bit3 = bitRead(_GPIO, 3); GPIO_bit2 = bitRead(_GPIO, 2); GPIO_bit1 = bitRead(_GPIO, 1); - GPIO_bit0 = bitRead(_GPIO, 0); - - delay(100); - - switch (gpioPin) // Selecting which value should be returned + GPIO_bit0 = bitRead(_GPIO, 0); + + delay(100); + + switch(gpioPin) //Selecting which value should be returned { - case 0: + case 0: GPIO_return = GPIO_bit0; break; - - case 1: + + case 1: GPIO_return = GPIO_bit1; break; - - case 2: + + case 2: GPIO_return = GPIO_bit2; break; - - case 3: + + case 3: GPIO_return = GPIO_bit3; break; } return GPIO_return; + } void ADS1256::sendDirectCommand(uint8_t directCommand) { - LOG_DEBUG("Direct Command"); - // Direct commands can be found in the datasheet Page 34, Table 24. - LOG_DEBUG("Direct Command Begin"); - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - - CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" - LOG_DEBUG("Direct Command CS LOW"); - delayMicroseconds(5); - _spi->transfer(directCommand); // Send Command - LOG_DEBUG("Transfer OK"); - delayMicroseconds(5); - CS_HIGH(); // REF: P34: "CS must stay low during the entire command sequence" - LOG_DEBUG("Direct Command CS HIGH"); - - _spi->endTransaction(); - LOG_DEBUG("Direct Command End"); + //Direct commands can be found in the datasheet Page 34, Table 24. + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + + CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" + delayMicroseconds(5); + _spi->transfer(directCommand); //Send Command + delayMicroseconds(5); + CS_HIGH(); //REF: P34: "CS must stay low during the entire command sequence" + + _spi->endTransaction(); } -float ADS1256::convertToVoltage(int32_t rawData) // Converting the 24-bit data into a voltage value -{ - return (conversionParameter * rawData); + +float ADS1256::convertToVoltage(int32_t rawData) //Converting the 24-bit data into a voltage value +{ + return(conversionParameter * rawData); } void ADS1256::writeRegister(uint8_t registerAddress, uint8_t registerValueToWrite) -{ - waitForLowDRDY(); - LOG_DEBUG("DRDY Low"); +{ + waitForLowDRDY(); - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - // SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. - LOG_DEBUG("SPI Begin"); + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + //SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. - CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] - LOG_DEBUG("CS Low"); + CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - delayMicroseconds(5); // see t6 in the datasheet + delayMicroseconds(5); //see t6 in the datasheet - _spi->transfer(0x50 | registerAddress); // 0x50 = 01010000 = WREG - LOG_DEBUG("Transfer 1"); + _spi->transfer(0x50 | registerAddress); // 0x50 = 01010000 = WREG - _spi->transfer(0x00); // 2nd (empty) command byte - LOG_DEBUG("Transfer 2"); + _spi->transfer(0x00); //2nd (empty) command byte - _spi->transfer(registerValueToWrite); // pass the value to the register - LOG_DEBUG("Transfer 3"); - - CS_HIGH(); - LOG_DEBUG("CS High"); - _spi->endTransaction(); - LOG_DEBUG("SPI End"); + _spi->transfer(registerValueToWrite); //pass the value to the register + + CS_HIGH(); + _spi->endTransaction(); + delay(100); + } -long ADS1256::readRegister(uint8_t registerAddress) // Reading a register +long ADS1256::readRegister(uint8_t registerAddress) //Reading a register { - waitForLowDRDY(); + waitForLowDRDY(); + + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + //SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - // SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. + CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + _spi->transfer(0x10 | registerAddress); //0x10 = 0001000 = RREG - OR together the two numbers (command + address) - _spi->transfer(0x10 | registerAddress); // 0x10 = 0001000 = RREG - OR together the two numbers (command + address) + _spi->transfer(0x00); //2nd (empty) command byte - _spi->transfer(0x00); // 2nd (empty) command byte + delayMicroseconds(5); //see t6 in the datasheet - delayMicroseconds(5); // see t6 in the datasheet + uint8_t regValue = _spi->transfer(0xFF); //read out the register value - uint8_t regValue = _spi->transfer(0xFF); // read out the register value - - CS_HIGH(); - _spi->endTransaction(); - - return regValue; + CS_HIGH(); + _spi->endTransaction(); + delay(100); + return regValue; } -long ADS1256::readSingle() // Reading a single value ONCE using the RDATA command + +long ADS1256::readSingle() //Reading a single value ONCE using the RDATA command { _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" + CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" waitForLowDRDY(); - _spi->transfer(0b00000001); // Issue RDATA (0000 0001) command - delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. + _spi->transfer(0b00000001); //Issue RDATA (0000 0001) command + delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. _outputBuffer[0] = _spi->transfer(0); // MSB _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB + _outputBuffer[2] = _spi->transfer(0); // LSB - // Shifting and combining the above three items into a single, 24-bit number - _outputValue = ((long)_outputBuffer[0] << 16) | ((long)_outputBuffer[1] << 8) | (_outputBuffer[2]); + //Shifting and combining the above three items into a single, 24-bit number + _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); _outputValue = convertSigned24BitToLong(_outputValue); - - CS_HIGH(); // We finished the command sequence, so we set CS to HIGH + + CS_HIGH(); //We finished the command sequence, so we set CS to HIGH _spi->endTransaction(); - - return (_outputValue); + + return(_outputValue); } -long ADS1256::readSingleContinuous() // Reads the recently selected input channel using RDATAC -{ - if (_isAcquisitionRunning == false) +long ADS1256::readSingleContinuous() //Reads the recently selected input channel using RDATAC +{ + if(_isAcquisitionRunning == false) { - _isAcquisitionRunning = true; - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" - waitForLowDRDY(); - _spi->transfer(0b00000011); // Issue RDATAC (0000 0011) - delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. + _isAcquisitionRunning = true; + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" + waitForLowDRDY(); + _spi->transfer(0b00000011); //Issue RDATAC (0000 0011) + delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. } else { waitForLowDRDY(); - } - - _outputBuffer[0] = _spi->transfer(0); // MSB + } + + _outputBuffer[0] = _spi->transfer(0); // MSB _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB - - _outputValue = ((long)_outputBuffer[0] << 16) | ((long)_outputBuffer[1] << 8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - + _outputBuffer[2] = _spi->transfer(0); // LSB + + _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); + _outputValue = convertSigned24BitToLong(_outputValue); + waitForHighDRDY(); - + return _outputValue; } long ADS1256::cycleSingle() { - if (_isAcquisitionRunning == false) + if(_isAcquisitionRunning == false) { - _isAcquisitionRunning = true; - _cycle = 0; - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX - _spi->transfer(0x00); - _spi->transfer(SING_0); // AIN0+AINCOM - CS_HIGH(); - delay(50); - CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + _isAcquisitionRunning = true; + _cycle = 0; + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] + _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX + _spi->transfer(0x00); + _spi->transfer(SING_0); //AIN0+AINCOM + CS_HIGH(); + delay(50); + CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] } else - { - } + {} + + if(_cycle < 8) + { + _outputValue = 0; + waitForLowDRDY(); + //Step 1. - Updating MUX + switch (_cycle) + { + //Channels are written manually + case 0: //Channel 2 + updateMUX(SING_1); //AIN1+AINCOM + break; - if (_cycle < 8) - { - _outputValue = 0; - waitForLowDRDY(); - // Step 1. - Updating MUX - switch (_cycle) - { - // Channels are written manually - case 0: // Channel 2 - updateMUX(SING_1); // AIN1+AINCOM - break; + case 1: //Channel 3 + updateMUX(SING_2); //AIN2+AINCOM + break; - case 1: // Channel 3 - updateMUX(SING_2); // AIN2+AINCOM - break; + case 2: //Channel 4 + updateMUX(SING_3); //AIN3+AINCOM + break; - case 2: // Channel 4 - updateMUX(SING_3); // AIN3+AINCOM - break; + case 3: //Channel 5 + updateMUX(SING_4); //AIN4+AINCOM + break; - case 3: // Channel 5 - updateMUX(SING_4); // AIN4+AINCOM - break; + case 4: //Channel 6 + updateMUX(SING_5); //AIN5+AINCOM + break; - case 4: // Channel 6 - updateMUX(SING_5); // AIN5+AINCOM - break; + case 5: //Channel 7 + updateMUX(SING_6); //AIN6+AINCOM + break; - case 5: // Channel 7 - updateMUX(SING_6); // AIN6+AINCOM - break; + case 6: //Channel 8 + updateMUX(SING_7); //AIN7+AINCOM + break; - case 6: // Channel 8 - updateMUX(SING_7); // AIN7+AINCOM - break; + case 7: //Channel 1 + updateMUX(SING_0); //AIN0+AINCOM + break; + } + //Step 2. + _spi->transfer(0b11111100); //SYNC + delayMicroseconds(4); //t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us + _spi->transfer(0b11111111); //WAKEUP - case 7: // Channel 1 - updateMUX(SING_0); // AIN0+AINCOM - break; - } - // Step 2. - _spi->transfer(0b11111100); // SYNC - delayMicroseconds(4); // t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us - _spi->transfer(0b11111111); // WAKEUP - - // Step 3. - // Issue RDATA (0000 0001) command - _spi->transfer(0b00000001); - delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. - - _outputBuffer[0] = _spi->transfer(0x0F); // MSB - _outputBuffer[1] = _spi->transfer(0x0F); // Mid-byte - _outputBuffer[2] = _spi->transfer(0x0F); // LSB - - _outputValue = ((long)_outputBuffer[0] << 16) | ((long)_outputBuffer[1] << 8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - - _cycle++; // Increase cycle - This will move to the next MUX input channel - if (_cycle == 8) - { - _cycle = 0; // Reset to 0 - Restart conversion from the 1st input channel - } - } + //Step 3. + //Issue RDATA (0000 0001) command + _spi->transfer(0b00000001); + delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + _outputBuffer[0] = _spi->transfer(0x0F); // MSB + _outputBuffer[1] = _spi->transfer(0x0F); // Mid-byte + _outputBuffer[2] = _spi->transfer(0x0F); // LSB + + _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); + _outputValue = convertSigned24BitToLong(_outputValue); + + _cycle++; //Increase cycle - This will move to the next MUX input channel + if(_cycle == 8) + { + _cycle = 0; //Reset to 0 - Restart conversion from the 1st input channel + } + } + return _outputValue; } -long ADS1256::cycleDifferential() +long ADS1256::cycleDifferential() { - if (_isAcquisitionRunning == false) + if(_isAcquisitionRunning == false) { - _cycle = 0; - _isAcquisitionRunning = true; - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); - - // Set the AIN0+AIN1 as inputs manually - CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX - _spi->transfer(0x00); - _spi->transfer(DIFF_0_1); // AIN0+AIN1 - CS_HIGH(); - delay(50); - CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + _cycle = 0; + _isAcquisitionRunning = true; + _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + + //Set the AIN0+AIN1 as inputs manually + CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] + _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX + _spi->transfer(0x00); + _spi->transfer(DIFF_0_1); //AIN0+AIN1 + CS_HIGH(); + delay(50); + CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] } else - { - } + {} + + if(_cycle < 4) + { + _outputValue = 0; + //DRDY has to go low + waitForLowDRDY(); - if (_cycle < 4) - { - _outputValue = 0; - // DRDY has to go low - waitForLowDRDY(); + //Step 1. - Updating MUX + switch (_cycle) + { + case 0: //Channel 2 + updateMUX(DIFF_2_3); //AIN2+AIN3 + break; - // Step 1. - Updating MUX - switch (_cycle) - { - case 0: // Channel 2 - updateMUX(DIFF_2_3); // AIN2+AIN3 - break; + case 1: //Channel 3 + updateMUX(DIFF_4_5); //AIN4+AIN5 + break; - case 1: // Channel 3 - updateMUX(DIFF_4_5); // AIN4+AIN5 - break; + case 2: //Channel 4 + updateMUX(DIFF_6_7); //AIN6+AIN7 + break; - case 2: // Channel 4 - updateMUX(DIFF_6_7); // AIN6+AIN7 - break; + case 3: //Channel 1 + updateMUX(DIFF_0_1); //AIN0+AIN1 + break; + } - case 3: // Channel 1 - updateMUX(DIFF_0_1); // AIN0+AIN1 - break; - } + _spi->transfer(0b11111100); //SYNC + delayMicroseconds(4); //t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us + _spi->transfer(0b11111111); //WAKEUP - _spi->transfer(0b11111100); // SYNC - delayMicroseconds(4); // t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us - _spi->transfer(0b11111111); // WAKEUP - - // Step 3. - _spi->transfer(0b00000001); // Issue RDATA (0000 0001) command - delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. - - _outputBuffer[0] = _spi->transfer(0); // MSB - _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB - - _outputValue = ((long)_outputBuffer[0] << 16) | ((long)_outputBuffer[1] << 8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - - _cycle++; - if (_cycle == 4) - { - _cycle = 0; - // After the 4th cycle, we reset to zero so the next iteration reads the 1st MUX again - } - } + //Step 3. + _spi->transfer(0b00000001); //Issue RDATA (0000 0001) command + delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + _outputBuffer[0] = _spi->transfer(0); // MSB + _outputBuffer[1] = _spi->transfer(0); // Mid-byte + _outputBuffer[2] = _spi->transfer(0); // LSB + + _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); + _outputValue = convertSigned24BitToLong(_outputValue); + + _cycle++; + if(_cycle == 4) + { + _cycle = 0; + //After the 4th cycle, we reset to zero so the next iteration reads the 1st MUX again + } + } + return _outputValue; } void ADS1256::updateConversionParameter() { - conversionParameter = ((2.0 * _VREF) / 8388608.0) / (pow(2, _PGA)); // Calculate the "bit to Volts" multiplier - // 8388608 = 2^{23} - 1, REF: p23, Table 16. + conversionParameter = ((2.0 * _VREF) / 8388608.0) / (pow(2, _PGA)); //Calculate the "bit to Volts" multiplier + //8388608 = 2^{23} - 1, REF: p23, Table 16. } void ADS1256::updateMUX(uint8_t muxValue) { - _spi->transfer(0x50 | MUX_REG); // Write to the MUX register (0x50 is the WREG command) - _spi->transfer(0x00); - _spi->transfer(muxValue); // Write the new MUX value + _spi->transfer(0x50 | MUX_REG); //Write to the MUX register (0x50 is the WREG command) + _spi->transfer(0x00); + _spi->transfer(muxValue); //Write the new MUX value } inline void ADS1256::CS_LOW() { - if (_CS_pin != PIN_UNUSED) // Sets CS LOW if it is not an unused pin + if (_CS_pin != PIN_UNUSED) //Sets CS LOW if it is not an unused pin { - digitalWrite(_CS_pin, LOW); + digitalWrite(_CS_pin, LOW); } } inline void ADS1256::CS_HIGH() { - if (_CS_pin != PIN_UNUSED) // Sets CS HIGH if it is not an unused pin + if (_CS_pin != PIN_UNUSED) //Sets CS HIGH if it is not an unused pin { - digitalWrite(_CS_pin, HIGH); + digitalWrite(_CS_pin, HIGH); } } \ No newline at end of file diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index 6c573af..c1ae86c 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -1,8 +1,6 @@ #include "datasave.h" #include - - LITTLEFSGuard::LITTLEFSGuard() { if (!LittleFS.begin(true, "/littlefs", 10, "littlefs")) @@ -12,7 +10,7 @@ LITTLEFSGuard::LITTLEFSGuard() else { LOG_INFO("LittleFS mounted successfully"); - LOG_INFO("LittleFS Free KBytes:", (LittleFS.totalBytes() - LittleFS.usedBytes()) /1024); + LOG_INFO("LittleFS Free KBytes:", (LittleFS.totalBytes() - LittleFS.usedBytes()) / 1024); } } @@ -51,28 +49,29 @@ void ignitionBoxStatusFiltered::update(const ignitionBoxStatus &new_status) // simple moving average calculation m_last.timestamp = new_status.timestamp; // keep timestamp of latest status - m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging - m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging - m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status - m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status - filter(m_last.coils12.spark_delay, new_status.coils12.spark_delay, m_max_count); // incremental average calculation - filter(m_last.coils12.peak_p_in, new_status.coils12.peak_p_in, m_max_count); // incremental average calculation - filter(m_last.coils12.peak_n_in, new_status.coils12.peak_n_in, m_max_count); // incremental average calculation - filter(m_last.coils12.peak_p_out, new_status.coils12.peak_p_out, m_max_count); // incremental average calculation - filter(m_last.coils12.peak_n_out, new_status.coils12.peak_n_out, m_max_count); // incremental average calculation + m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging + m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging + m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status + m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status + m_last.coils12.spark_delay = new_status.coils12.spark_delay; // incremental average calculation + m_last.coils12.peak_p_in = new_status.coils12.peak_p_in; // incremental average calculation + m_last.coils12.peak_n_in = new_status.coils12.peak_n_in; // incremental average calculation + m_last.coils12.peak_p_out = new_status.coils12.peak_p_out; // incremental average calculation + m_last.coils12.peak_n_out = new_status.coils12.peak_n_out; // incremental average calculation - m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging - m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging - m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status - m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status - filter(m_last.coils34.spark_delay, new_status.coils34.spark_delay, m_max_count); // incremental average calculation - filter(m_last.coils34.peak_p_in, new_status.coils34.peak_p_in, m_max_count); // incremental average calculation - filter(m_last.coils34.peak_n_in, new_status.coils34.peak_n_in, m_max_count); // incremental average calculation - filter(m_last.coils34.peak_p_out, new_status.coils34.peak_p_out, m_max_count); // incremental average calculation - filter(m_last.coils34.peak_n_out, new_status.coils34.peak_n_out, m_max_count); // incremental average calculation - filter(m_last.eng_rpm, new_status.eng_rpm, m_max_count); // incremental average calculation // incremental average calculation - filter(m_last.adc_read_time, m_last.adc_read_time, m_max_count); // incremental average calculation - m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value + m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging + m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging + m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status + m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status + m_last.coils34.spark_delay = new_status.coils34.spark_delay; // incremental average calculation + m_last.coils34.peak_p_in = new_status.coils34.peak_p_in; // incremental average calculation + m_last.coils34.peak_n_in = new_status.coils34.peak_n_in; // incremental average calculation + m_last.coils34.peak_p_out = new_status.coils34.peak_p_out; // incremental average calculation + m_last.coils34.peak_n_out = new_status.coils34.peak_n_out; // incremental average calculation + + m_last.eng_rpm = new_status.eng_rpm; // incremental average calculation + m_last.adc_read_time = m_last.adc_read_time; // incremental average calculation + m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value if (m_count >= m_max_count) { @@ -124,4 +123,3 @@ const ArduinoJson::JsonDocument ignitionBoxStatusFiltered::toJson() const } return doc; } - diff --git a/RotaxMonitor/src/devices.h b/RotaxMonitor/src/devices.h index a9d6f25..5ee2125 100644 --- a/RotaxMonitor/src/devices.h +++ b/RotaxMonitor/src/devices.h @@ -43,18 +43,13 @@ struct Devices std::unique_ptr m_adc_b = nullptr; std::unique_ptr m_ext_io = nullptr; - }; // Adc read channel wrapper to selet mux before reading inline float adcReadChannel(ADS1256 *adc, const uint8_t ch) { adc->setMUX(ch); - // scarta 3 conversioni - for (int i = 0; i < 5; i++) - { - adc->readSingle(); - } + adc->readSingle(); // ora lettura valida a 30kSPS → ~100 µs di settling return adc->convertToVoltage(adc->readSingle()); } diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 386a564..858a01d 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -53,7 +53,7 @@ void setup() IPAddress gateway(10, 11, 12, 1); IPAddress subnet(255, 255, 255, 0); WiFi.softAPConfig(local_IP, gateway, subnet); - WiFi.setTxPower(WIFI_POWER_13dBm); // reduce wifi power + WiFi.setTxPower(WIFI_POWER_5dBm); // reduce wifi power if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD)) { LOG_INFO("WiFi AP Mode Started"); @@ -117,19 +117,42 @@ void loop() #endif // Init ADCs dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); - #ifdef CH_B_ENABLE +#ifdef CH_B_ENABLE dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); - #endif +#endif // Configure ADCs dev->m_adc_a->InitializeADC(); dev->m_adc_a->setPGA(PGA_1); - dev->m_adc_a->setDRATE(DRATE_7500SPS); - #ifdef CH_B_ENABLE + // dev->m_adc_a->setDRATE(DRATE_15000SPS); +#ifdef CH_B_ENABLE dev->m_adc_b->InitializeADC(); dev->m_adc_b->setPGA(PGA_1); - dev->m_adc_b->setDRATE(DRATE_7500SPS); + dev->m_adc_b->setDRATE(DRATE_30000SPS); #endif LOG_DEBUG("Init SPI OK"); + + uint8_t chs[8] = { + SING_0, SING_1, SING_2, SING_3, SING_4, SING_5, SING_6, SING_7 + }; + float res[8]; + + while (Serial.read() != 's') // The conversion is stopped by a character received from the serial port + { + clearScreen(); + auto start = esp_timer_get_time(); + for (int i = 0; i < 8; i++){ + // dev->m_adc_a->setMUX(chs[i]); + res[i] = dev->m_adc_a->convertToVoltage(dev->m_adc_a->cycleSingle()); + } + auto stop = esp_timer_get_time(); + for (int j = 0; j < 8; j++){ + Serial.printf("ADC_A SING_%d: %5.4f\n",j, res[j]); + } + Serial.printf("ADC Time: %u us\n", stop-start); + delay(100); + + } + dev->m_adc_a->stopConversion(); //////// INIT I2C INTERFACES //////// LOG_DEBUG("Init I2C Interfaces"); diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index dcf3587..40a789e 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -40,14 +40,13 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) QueueHandle_t rt_queue = params->rt_queue; Devices *dev = params->dev.get(); ADS1256 *adc = params->name == "rtIgnTask_A" ? dev->m_adc_a.get() : dev->m_adc_b.get(); - std::mutex& spi_mutex = params->name == "rtIgnTask_A" ? dev->m_spi_a_mutex : dev->m_spi_b_mutex; - ExternalIO* io = dev->m_ext_io.get(); + std::mutex &spi_mutex = params->name == "rtIgnTask_A" ? dev->m_spi_a_mutex : dev->m_spi_b_mutex; + ExternalIO *io = dev->m_ext_io.get(); TaskStatus_t rt_task_info; vTaskGetInfo(NULL, &rt_task_info, pdFALSE, eInvalid); - const auto rt_task_name = pcTaskGetName(rt_task_info.xHandle); - LOG_INFO("rtTask Params OK [", rt_task_name, "]"); + LOG_INFO("rtTask Params OK [", params->name.c_str(), "]"); ignitionBoxStatus ign_box_sts; @@ -98,7 +97,7 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) attachInterruptArg(digitalPinToInterrupt(rt_int.spark_pin_12), rt_int.isr_ptr, (void *)&isr_params_sp12, RISING); attachInterruptArg(digitalPinToInterrupt(rt_int.spark_pin_34), rt_int.isr_ptr, (void *)&isr_params_sp34, RISING); - LOG_INFO("rtTask ISR Attach OK [", rt_task_name, "]"); + LOG_INFO("rtTask ISR Attach OK [", params->name.c_str(), "]"); // Global rt_task_ptr variables bool first_cycle = true; @@ -236,7 +235,7 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) // read adc channels: pickup12, out12 [ pos + neg ] if (adc) // read only if adc initialized { - std::lock_guard lock (spi_mutex); + std::lock_guard lock(spi_mutex); uint32_t start_adc_read = esp_timer_get_time(); // from peak detector circuits ign_box_sts.coils12.peak_p_in = adcReadChannel(adc, ADC_CH_PEAK_12P_IN); @@ -256,10 +255,23 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) // outputs on io expander if (io) { - // [TODO] code to reset sample and hold and arm trigger level detectors + // Discharge Pulse + io->extDigitalWrite(rt_rst.sh_disch_12, true); + io->extDigitalWrite(rt_rst.sh_disch_34, true); + delayMicroseconds(250); + io->extDigitalWrite(rt_rst.sh_disch_12, false); + io->extDigitalWrite(rt_rst.sh_disch_34, false); + // Safety delay + delayMicroseconds(500); + // Re-Arm Pulse + io->extDigitalWrite(rt_rst.sh_arm_12, true); + io->extDigitalWrite(rt_rst.sh_arm_34, true); + delayMicroseconds(250); + io->extDigitalWrite(rt_rst.sh_arm_12, false); + io->extDigitalWrite(rt_rst.sh_arm_34, false); } else - vTaskDelay(pdMS_TO_TICKS(2)); + vTaskDelay(pdMS_TO_TICKS(c_io_time)); // send essage to main loop with ignition info, by copy so local static variable is ok if (rt_queue) @@ -272,7 +284,7 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) } // Delete the timeout timer esp_timer_delete(timeout_timer); - LOG_WARN("rtTask Ending [", rt_task_name, "]"); + LOG_WARN("rtTask Ending [", params->name.c_str(), "]"); // Ignition A Interrupts DETACH detachInterrupt(rt_int.trig_pin_12p); detachInterrupt(rt_int.trig_pin_12n); From 1b8ba88b0594809e1e0c2df975c86e9e7a86d265 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 17 Apr 2026 11:01:41 +0200 Subject: [PATCH 35/38] ADC working ok in sync with system --- RotaxMonitor/lib/ADS1256/ADS1256.cpp | 66 +++++++++++++--------------- RotaxMonitor/lib/ADS1256/ADS1256.h | 3 ++ RotaxMonitor/src/datasave.cpp | 46 ++++++++++--------- RotaxMonitor/src/main.cpp | 32 ++++++++------ RotaxMonitor/src/tasks.cpp | 17 +++---- 5 files changed, 84 insertions(+), 80 deletions(-) diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.cpp b/RotaxMonitor/lib/ADS1256/ADS1256.cpp index 3372b47..eef8eac 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.cpp +++ b/RotaxMonitor/lib/ADS1256/ADS1256.cpp @@ -74,21 +74,21 @@ void ADS1256::InitializeADC() writeRegister(STATUS_REG, _STATUS); delay(200); - _MUX = 0b00000001; //MUX AIN0+AIN1 + _MUX = DIFF_0_1; //MUX AIN0+AIN1 writeRegister(MUX_REG, _MUX); delay(200); - _ADCON = 0b00000000; //ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) + _ADCON = WAKEUP; //ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) writeRegister(ADCON_REG, _ADCON); delay(200); updateConversionParameter(); - _DRATE = 0b10000010; //100SPS + _DRATE = DRATE_100SPS; //100SPS writeRegister(DRATE_REG, _DRATE); delay(200); - sendDirectCommand(0b11110000); //Offset and self-gain calibration + sendDirectCommand(SELFCAL); //Offset and self-gain calibration delay(200); _isAcquisitionRunning = false; //MCU will be waiting to start a continuous acquisition @@ -109,7 +109,7 @@ void ADS1256::waitForHighDRDY() void ADS1256::stopConversion() //Sending SDATAC to stop the continuous conversion { waitForLowDRDY(); //SDATAC should be called after DRDY goes LOW (p35. Figure 33) - _spi->transfer(0b00001111); //Send SDATAC to the ADC + _spi->transfer(SDATAC); //Send SDATAC to the ADC CS_HIGH(); //We finished the command sequence, so we switch it back to HIGH _spi->endTransaction(); @@ -465,7 +465,7 @@ uint8_t ADS1256::readGPIO(uint8_t gpioPin) //Reading GPIO void ADS1256::sendDirectCommand(uint8_t directCommand) { //Direct commands can be found in the datasheet Page 34, Table 24. - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" delayMicroseconds(5); @@ -486,14 +486,14 @@ void ADS1256::writeRegister(uint8_t registerAddress, uint8_t registerValueToWrit { waitForLowDRDY(); - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); //SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] delayMicroseconds(5); //see t6 in the datasheet - _spi->transfer(0x50 | registerAddress); // 0x50 = 01010000 = WREG + _spi->transfer(WREG | registerAddress); // 0x50 = 01010000 = WREG _spi->transfer(0x00); //2nd (empty) command byte @@ -509,18 +509,18 @@ long ADS1256::readRegister(uint8_t registerAddress) //Reading a register { waitForLowDRDY(); - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); //SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(0x10 | registerAddress); //0x10 = 0001000 = RREG - OR together the two numbers (command + address) + _spi->transfer(RREG | registerAddress); //0x10 = 0001000 = RREG - OR together the two numbers (command + address) _spi->transfer(0x00); //2nd (empty) command byte delayMicroseconds(5); //see t6 in the datasheet - uint8_t regValue = _spi->transfer(0xFF); //read out the register value + uint8_t regValue = _spi->transfer(0x00); //read out the register value CS_HIGH(); _spi->endTransaction(); @@ -531,10 +531,10 @@ long ADS1256::readRegister(uint8_t registerAddress) //Reading a register long ADS1256::readSingle() //Reading a single value ONCE using the RDATA command { - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" waitForLowDRDY(); - _spi->transfer(0b00000001); //Issue RDATA (0000 0001) command + _spi->transfer(RDATA); //Issue RDATA (0000 0001) command delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. _outputBuffer[0] = _spi->transfer(0); // MSB @@ -556,10 +556,10 @@ long ADS1256::readSingleContinuous() //Reads the recently selected input channel if(_isAcquisitionRunning == false) { _isAcquisitionRunning = true; - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" waitForLowDRDY(); - _spi->transfer(0b00000011); //Issue RDATAC (0000 0011) + _spi->transfer(RDATAC); //Issue RDATAC (0000 0011) delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. } else @@ -585,14 +585,12 @@ long ADS1256::cycleSingle() { _isAcquisitionRunning = true; _cycle = 0; - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX + _spi->transfer(WREG | MUX_REG); // 0x50 = WREG //1 = MUX _spi->transfer(0x00); _spi->transfer(SING_0); //AIN0+AINCOM - CS_HIGH(); - delay(50); - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] + delayMicroseconds(250); } else {} @@ -638,18 +636,18 @@ long ADS1256::cycleSingle() break; } //Step 2. - _spi->transfer(0b11111100); //SYNC + _spi->transfer(SYNC); //SYNC delayMicroseconds(4); //t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us - _spi->transfer(0b11111111); //WAKEUP + _spi->transfer(WAKEUP); //WAKEUP //Step 3. //Issue RDATA (0000 0001) command - _spi->transfer(0b00000001); + _spi->transfer(RDATA); delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. - _outputBuffer[0] = _spi->transfer(0x0F); // MSB - _outputBuffer[1] = _spi->transfer(0x0F); // Mid-byte - _outputBuffer[2] = _spi->transfer(0x0F); // LSB + _outputBuffer[0] = _spi->transfer(0); // MSB + _outputBuffer[1] = _spi->transfer(0); // Mid-byte + _outputBuffer[2] = _spi->transfer(0); // LSB _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); _outputValue = convertSigned24BitToLong(_outputValue); @@ -670,16 +668,14 @@ long ADS1256::cycleDifferential() { _cycle = 0; _isAcquisitionRunning = true; - _spi->beginTransaction(SPISettings(1920000, MSBFIRST, SPI_MODE1)); + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); //Set the AIN0+AIN1 as inputs manually CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(0x50 | 1); // 0x50 = WREG //1 = MUX + _spi->transfer(WREG | MUX_REG); // 0x50 = WREG //1 = MUX _spi->transfer(0x00); _spi->transfer(DIFF_0_1); //AIN0+AIN1 - CS_HIGH(); - delay(50); - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] + delayMicroseconds(250); } else {} @@ -710,12 +706,12 @@ long ADS1256::cycleDifferential() break; } - _spi->transfer(0b11111100); //SYNC + _spi->transfer(SYNC); //SYNC delayMicroseconds(4); //t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us - _spi->transfer(0b11111111); //WAKEUP + _spi->transfer(WAKEUP); //WAKEUP //Step 3. - _spi->transfer(0b00000001); //Issue RDATA (0000 0001) command + _spi->transfer(RDATA); //Issue RDATA (0000 0001) command delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. _outputBuffer[0] = _spi->transfer(0); // MSB @@ -744,7 +740,7 @@ void ADS1256::updateConversionParameter() void ADS1256::updateMUX(uint8_t muxValue) { - _spi->transfer(0x50 | MUX_REG); //Write to the MUX register (0x50 is the WREG command) + _spi->transfer(WREG | MUX_REG); //Write to the MUX register (0x50 is the WREG command) _spi->transfer(0x00); _spi->transfer(muxValue); //Write the new MUX value } diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.h b/RotaxMonitor/lib/ADS1256/ADS1256.h index 1ded2e2..35ade99 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.h +++ b/RotaxMonitor/lib/ADS1256/ADS1256.h @@ -15,6 +15,9 @@ #include +// SPI Frequency +#define SPI_FREQ 1920000 + //Differential inputs #define DIFF_0_1 0b00000001 //A0 + A1 as differential input #define DIFF_2_3 0b00100011 //A2 + A3 as differential input diff --git a/RotaxMonitor/src/datasave.cpp b/RotaxMonitor/src/datasave.cpp index c1ae86c..5fb8305 100644 --- a/RotaxMonitor/src/datasave.cpp +++ b/RotaxMonitor/src/datasave.cpp @@ -47,31 +47,29 @@ void ignitionBoxStatusFiltered::update(const ignitionBoxStatus &new_status) } m_count++; // simple moving average calculation - m_last.timestamp = new_status.timestamp; // keep timestamp of latest status + m_last.timestamp = new_status.timestamp; // keep timestamp of latest status + m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging + m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging + m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status + m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status + filter(m_last.coils12.spark_delay, new_status.coils12.spark_delay, m_max_count); // incremental average calculation + filter(m_last.coils12.peak_p_in, new_status.coils12.peak_p_in, m_max_count); // incremental average calculation + filter(m_last.coils12.peak_n_in, new_status.coils12.peak_n_in, m_max_count); // incremental average calculation + filter(m_last.coils12.peak_p_out, new_status.coils12.peak_p_out, m_max_count); // incremental average calculation + filter(m_last.coils12.peak_n_out, new_status.coils12.peak_n_out, m_max_count); // incremental average calculation - m_last.coils12.n_events = new_status.coils12.n_events; // sum events instead of averaging - m_last.coils12.n_missed_firing = new_status.coils12.n_missed_firing; // sum missed firings instead of averaging - m_last.coils12.spark_status = new_status.coils12.spark_status; // take latest spark status - m_last.coils12.sstart_status = new_status.coils12.sstart_status; // take latest soft start status - m_last.coils12.spark_delay = new_status.coils12.spark_delay; // incremental average calculation - m_last.coils12.peak_p_in = new_status.coils12.peak_p_in; // incremental average calculation - m_last.coils12.peak_n_in = new_status.coils12.peak_n_in; // incremental average calculation - m_last.coils12.peak_p_out = new_status.coils12.peak_p_out; // incremental average calculation - m_last.coils12.peak_n_out = new_status.coils12.peak_n_out; // incremental average calculation - - m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging - m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging - m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status - m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status - m_last.coils34.spark_delay = new_status.coils34.spark_delay; // incremental average calculation - m_last.coils34.peak_p_in = new_status.coils34.peak_p_in; // incremental average calculation - m_last.coils34.peak_n_in = new_status.coils34.peak_n_in; // incremental average calculation - m_last.coils34.peak_p_out = new_status.coils34.peak_p_out; // incremental average calculation - m_last.coils34.peak_n_out = new_status.coils34.peak_n_out; // incremental average calculation - - m_last.eng_rpm = new_status.eng_rpm; // incremental average calculation - m_last.adc_read_time = m_last.adc_read_time; // incremental average calculation - m_last.n_queue_errors = new_status.n_queue_errors; // take last of queue errors since it's a cumulative count of errors in the queue, not an average value + m_last.coils34.n_events = new_status.coils34.n_events; // sum events instead of averaging + m_last.coils34.n_missed_firing = new_status.coils34.n_missed_firing; // sum missed firings instead of averaging + m_last.coils34.spark_status = new_status.coils34.spark_status; // take latest spark status + m_last.coils34.sstart_status = new_status.coils34.sstart_status; // take latest soft start status + filter(m_last.coils34.spark_delay, new_status.coils34.spark_delay, m_max_count); // incremental average calculation + filter(m_last.coils34.peak_p_in, new_status.coils34.peak_p_in, m_max_count); // incremental average calculation + filter(m_last.coils34.peak_n_in, new_status.coils34.peak_n_in, m_max_count); // incremental average calculation + filter(m_last.coils34.peak_p_out, new_status.coils34.peak_p_out, m_max_count); // incremental average calculation + filter(m_last.coils34.peak_n_out, new_status.coils34.peak_n_out, m_max_count); // incremental average calculation + filter(m_last.eng_rpm, new_status.eng_rpm, m_max_count); // incremental average calculation // incremental average calculation + filter(m_last.adc_read_time, m_last.adc_read_time, m_max_count); // incremental average calculation + m_last.n_queue_errors = new_status.n_queue_errors; if (m_count >= m_max_count) { diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 858a01d..7ae1830 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -123,35 +123,41 @@ void loop() // Configure ADCs dev->m_adc_a->InitializeADC(); dev->m_adc_a->setPGA(PGA_1); - // dev->m_adc_a->setDRATE(DRATE_15000SPS); + dev->m_adc_a->setDRATE(DRATE_7500SPS); #ifdef CH_B_ENABLE dev->m_adc_b->InitializeADC(); dev->m_adc_b->setPGA(PGA_1); dev->m_adc_b->setDRATE(DRATE_30000SPS); #endif LOG_DEBUG("Init SPI OK"); - + uint8_t chs[8] = { - SING_0, SING_1, SING_2, SING_3, SING_4, SING_5, SING_6, SING_7 - }; + SING_0, SING_1, SING_2, SING_3, SING_4, SING_5, SING_6, SING_7}; float res[8]; + auto timeout = Serial.getTimeout(); + Serial.setTimeout(0); + uint64_t count = 0; while (Serial.read() != 's') // The conversion is stopped by a character received from the serial port { - clearScreen(); auto start = esp_timer_get_time(); - for (int i = 0; i < 8; i++){ - // dev->m_adc_a->setMUX(chs[i]); - res[i] = dev->m_adc_a->convertToVoltage(dev->m_adc_a->cycleSingle()); + for (int i = 0; i < 8; i++) + { + // dev->m_adc_a->setMUX(chs[i]); + res[i] += 0.1f * (dev->m_adc_a->convertToVoltage(dev->m_adc_a->cycleSingle()) - res[i]); } auto stop = esp_timer_get_time(); - for (int j = 0; j < 8; j++){ - Serial.printf("ADC_A SING_%d: %5.4f\n",j, res[j]); + if (count++ % 25 == 0) + { + clearScreen(); + for (int j = 0; j < 8; j++) + { + Serial.printf("ADC_A SING_%d: %5.4f\n", j, res[j]); + } + Serial.printf("ADC Time: %5.3f ms\n", (float)((stop - start) / 1000.0f)); } - Serial.printf("ADC Time: %u us\n", stop-start); - delay(100); - } + Serial.setTimeout(timeout); dev->m_adc_a->stopConversion(); //////// INIT I2C INTERFACES //////// diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index 40a789e..e23df0c 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -238,15 +238,16 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) std::lock_guard lock(spi_mutex); uint32_t start_adc_read = esp_timer_get_time(); // from peak detector circuits - ign_box_sts.coils12.peak_p_in = adcReadChannel(adc, ADC_CH_PEAK_12P_IN); - ign_box_sts.coils12.peak_n_in = adcReadChannel(adc, ADC_CH_PEAK_12N_IN); - ign_box_sts.coils34.peak_p_in = adcReadChannel(adc, ADC_CH_PEAK_34P_IN); - ign_box_sts.coils34.peak_n_in = adcReadChannel(adc, ADC_CH_PEAK_34N_IN); - ign_box_sts.coils12.peak_p_out = adcReadChannel(adc, ADC_CH_PEAK_12P_OUT); - ign_box_sts.coils12.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_12N_OUT); - ign_box_sts.coils34.peak_p_out = adcReadChannel(adc, ADC_CH_PEAK_34P_OUT); - ign_box_sts.coils34.peak_n_out = adcReadChannel(adc, ADC_CH_PEAK_34N_OUT); + ign_box_sts.coils12.peak_p_in = adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils12.peak_n_in = adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils34.peak_p_in = adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils34.peak_n_in = adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils12.peak_p_out =adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils12.peak_n_out =adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils34.peak_p_out =adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils34.peak_n_out =adc->convertToVoltage(adc->cycleSingle()); ign_box_sts.adc_read_time = (int32_t)(esp_timer_get_time() - start_adc_read); + adc->stopConversion(); } else // simulate adc read timig vTaskDelay(pdMS_TO_TICKS(c_adc_time)); From bea29dc8f5a866521cd5ddca277724d800649331 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 17 Apr 2026 12:21:35 +0200 Subject: [PATCH 36/38] ADC ok with interrupt or drdy --- RotaxMonitor/lib/ADS1256/ADS1256.cpp | 1017 +++++++++++++------------- RotaxMonitor/lib/ADS1256/ADS1256.h | 229 +++--- RotaxMonitor/src/main.cpp | 29 - 3 files changed, 652 insertions(+), 623 deletions(-) diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.cpp b/RotaxMonitor/lib/ADS1256/ADS1256.cpp index eef8eac..9467dd7 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.cpp +++ b/RotaxMonitor/lib/ADS1256/ADS1256.cpp @@ -1,4 +1,4 @@ -//ADS1256 cpp file +// ADS1256 cpp file /* Name: ADS1256.cpp Created: 2022/07/14 @@ -17,389 +17,426 @@ #define convertSigned24BitToLong(value) ((value) & (1l << 23) ? (value) - 0x1000000 : value) -//Constructor -ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYNC_pin, const int8_t CS_pin,float VREF, SPIClass* spi): _spi(spi), - _DRDY_pin(DRDY_pin), _RESET_pin(RESET_pin), _SYNC_pin(SYNC_pin), _CS_pin(CS_pin), _VREF(VREF), _PGA(0) -{ - pinMode(_DRDY_pin, INPUT); - - if(RESET_pin != PIN_UNUSED) +void drdyCallback(void *arg) +{ + auto cls = (ADS1256 *)arg; + if (!arg) + return; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + if (digitalRead(cls->getDRDYpin())) // impose wait on low { - pinMode(_RESET_pin, OUTPUT); + xSemaphoreTakeFromISR(cls->getDRDYsemaphoreLow(), &xHigherPriorityTaskWoken); + xSemaphoreGiveFromISR(cls->getDRDYsemaphoreHigh(), &xHigherPriorityTaskWoken); } - - if(SYNC_pin != PIN_UNUSED) + else // impose wait on high { - pinMode(_SYNC_pin, OUTPUT); + xSemaphoreTakeFromISR(cls->getDRDYsemaphoreHigh(), &xHigherPriorityTaskWoken); + xSemaphoreGiveFromISR(cls->getDRDYsemaphoreLow(), &xHigherPriorityTaskWoken); } - - if(CS_pin != PIN_UNUSED) + if (xHigherPriorityTaskWoken) + portYIELD_FROM_ISR(); +} + +// Constructor +ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYNC_pin, const int8_t CS_pin, float VREF, SPIClass *spi) : _spi(spi), + m_DRDY_pin(DRDY_pin), m_RESET_pin(RESET_pin), m_SYNC_pin(SYNC_pin), m_CS_pin(CS_pin), m_VREF(VREF), m_PGA(0) +{ + pinMode(m_DRDY_pin, INPUT); + + if (RESET_pin != PIN_UNUSED) { - pinMode(_CS_pin, OUTPUT); - } - + pinMode(m_RESET_pin, OUTPUT); + } + + if (SYNC_pin != PIN_UNUSED) + { + pinMode(m_SYNC_pin, OUTPUT); + } + + if (CS_pin != PIN_UNUSED) + { + pinMode(m_CS_pin, OUTPUT); + } + updateConversionParameter(); -} -//Initialization + m_drdyHigh = xSemaphoreCreateBinary(); + m_drdyLow = xSemaphoreCreateBinary(); + xSemaphoreGive(m_drdyHigh); + xSemaphoreGive(m_drdyLow); + attachInterruptArg(DRDY_pin, drdyCallback, (void *)this, CHANGE); +} + +// Initialization void ADS1256::InitializeADC() -{ - //Chip select LOW - CS_LOW(); - - //We do a manual chip reset on the ADS1256 - Datasheet Page 27/ RESET - if(_RESET_pin != PIN_UNUSED) - { - digitalWrite(_RESET_pin, LOW); - delay(200); - digitalWrite(_RESET_pin, HIGH); //RESET is set to high - delay(1000); - } - - //Sync pin is also treated if it is defined - if(_SYNC_pin != PIN_UNUSED) - { - digitalWrite(_SYNC_pin, HIGH); //RESET is set to high - } - -#ifndef ADS1256_SPI_ALREADY_STARTED //Guard macro to allow external initialization of the SPI - _spi->begin(); +{ + // Chip select LOW + CS_LOW(); + + // We do a manual chip reset on the ADS1256 - Datasheet Page 27/ RESET + if (m_RESET_pin != PIN_UNUSED) + { + digitalWrite(m_RESET_pin, LOW); + delay(200); + digitalWrite(m_RESET_pin, HIGH); // RESET is set to high + delay(1000); + } + + // Sync pin is also treated if it is defined + if (m_SYNC_pin != PIN_UNUSED) + { + digitalWrite(m_SYNC_pin, HIGH); // RESET is set to high + } + +#ifndef ADS1256_SPI_ALREADY_STARTED // Guard macro to allow external initialization of the SPI + _spi->begin(); #endif - - //Applying arbitrary default values to speed up the starting procedure if the user just want to get quick readouts - //We both pass values to the variables and then send those values to the corresponding registers - delay(200); - _STATUS = 0b00110110; //BUFEN and ACAL enabled, Order is MSB, rest is read only - writeRegister(STATUS_REG, _STATUS); - delay(200); - - _MUX = DIFF_0_1; //MUX AIN0+AIN1 - writeRegister(MUX_REG, _MUX); - delay(200); - - _ADCON = WAKEUP; //ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) - writeRegister(ADCON_REG, _ADCON); - delay(200); - - updateConversionParameter(); - - _DRATE = DRATE_100SPS; //100SPS - writeRegister(DRATE_REG, _DRATE); - delay(200); - - sendDirectCommand(SELFCAL); //Offset and self-gain calibration - delay(200); + // Applying arbitrary default values to speed up the starting procedure if the user just want to get quick readouts + // We both pass values to the variables and then send those values to the corresponding registers + delay(200); - _isAcquisitionRunning = false; //MCU will be waiting to start a continuous acquisition + m_STATUS = 0b00110110; // BUFEN and ACAL enabled, Order is MSB, rest is read only + writeRegister(STATUS_REG, m_STATUS); + delay(200); + + m_MUX = DIFF_0_1; // MUX AIN0+AIN1 + writeRegister(MUX_REG, m_MUX); + delay(200); + + m_ADCON = WAKEUP; // ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) + writeRegister(ADCON_REG, m_ADCON); + delay(200); + + updateConversionParameter(); + + m_DRATE = DRATE_100SPS; // 100SPS + writeRegister(DRATE_REG, m_DRATE); + delay(200); + + sendDirectCommand(SELFCAL); // Offset and self-gain calibration + delay(200); + + m_isAcquisitionRunning = false; // MCU will be waiting to start a continuous acquisition } void ADS1256::waitForLowDRDY() -{ - while (digitalRead(_DRDY_pin) == HIGH) {} +{ + xSemaphoreTake(m_drdyLow, pdMS_TO_TICKS(10)); + xSemaphoreGive(m_drdyLow); } void ADS1256::waitForHighDRDY() -{ -#if F_CPU >= 48000000 //Fast MCUs need this protection to wait until DRDY goes high after a conversion - while (digitalRead(_DRDY_pin) == LOW) {} -#endif +{ + xSemaphoreTake(m_drdyHigh, pdMS_TO_TICKS(10)); + xSemaphoreGive(m_drdyHigh); } -void ADS1256::stopConversion() //Sending SDATAC to stop the continuous conversion -{ - waitForLowDRDY(); //SDATAC should be called after DRDY goes LOW (p35. Figure 33) - _spi->transfer(SDATAC); //Send SDATAC to the ADC - CS_HIGH(); //We finished the command sequence, so we switch it back to HIGH +void ADS1256::stopConversion() // Sending SDATAC to stop the continuous conversion +{ + waitForLowDRDY(); // SDATAC should be called after DRDY goes LOW (p35. Figure 33) + _spi->transfer(SDATAC); // Send SDATAC to the ADC + CS_HIGH(); // We finished the command sequence, so we switch it back to HIGH _spi->endTransaction(); - - _isAcquisitionRunning = false; //Reset to false, so the MCU will be able to start a new conversion + + m_isAcquisitionRunning = false; // Reset to false, so the MCU will be able to start a new conversion } -void ADS1256::setDRATE(uint8_t drate) //Setting DRATE (sampling frequency) -{ +void ADS1256::setDRATE(uint8_t drate) // Setting DRATE (sampling frequency) +{ writeRegister(DRATE_REG, drate); - _DRATE = drate; + m_DRATE = drate; delay(200); } -void ADS1256::setMUX(uint8_t mux) //Setting MUX (input channel) -{ +void ADS1256::setMUX(uint8_t mux) // Setting MUX (input channel) +{ writeRegister(MUX_REG, mux); - _MUX = mux; + m_MUX = mux; delay(200); } -void ADS1256::setPGA(uint8_t pga) //Setting PGA (input voltage range) -{ - _PGA = pga; - _ADCON = readRegister(ADCON_REG); //Read the most recent value of the register - - _ADCON = (_ADCON & 0b11111000) | (_PGA & 0b00000111); // Clearing and then setting bits 2-0 based on pga - - writeRegister(ADCON_REG, _ADCON); +void ADS1256::setPGA(uint8_t pga) // Setting PGA (input voltage range) +{ + m_PGA = pga; + m_ADCON = readRegister(ADCON_REG); // Read the most recent value of the register + + m_ADCON = (m_ADCON & 0b11111000) | (m_PGA & 0b00000111); // Clearing and then setting bits 2-0 based on pga + + writeRegister(ADCON_REG, m_ADCON); delay(200); - - updateConversionParameter(); //Update the multiplier according top the new PGA value + + updateConversionParameter(); // Update the multiplier according top the new PGA value } -uint8_t ADS1256::getPGA() //Reading PGA from the ADCON register +uint8_t ADS1256::getPGA() // Reading PGA from the ADCON register { - uint8_t pgaValue = readRegister(ADCON_REG) & 0b00000111; - //Reading the ADCON_REG and keeping the first three bits. - - return(pgaValue); + uint8_t pgaValue = readRegister(ADCON_REG) & 0b00000111; + // Reading the ADCON_REG and keeping the first three bits. + + return (pgaValue); } -void ADS1256::setCLKOUT(uint8_t clkout) //Setting CLKOUT +void ADS1256::setCLKOUT(uint8_t clkout) // Setting CLKOUT { - _ADCON = readRegister(ADCON_REG); //Read the most recent value of the register - - //Values: 0, 1, 2, 3 - - if(clkout == 0) + m_ADCON = readRegister(ADCON_REG); // Read the most recent value of the register + + // Values: 0, 1, 2, 3 + + if (clkout == 0) { - //00 - bitWrite(_ADCON, 6, 0); - bitWrite(_ADCON, 5, 0); + // 00 + bitWrite(m_ADCON, 6, 0); + bitWrite(m_ADCON, 5, 0); } - else if(clkout == 1) + else if (clkout == 1) { - //01 (default) - bitWrite(_ADCON, 6, 0); - bitWrite(_ADCON, 5, 1); + // 01 (default) + bitWrite(m_ADCON, 6, 0); + bitWrite(m_ADCON, 5, 1); } - else if(clkout == 2) + else if (clkout == 2) { - //10 - bitWrite(_ADCON, 6, 1); - bitWrite(_ADCON, 5, 0); + // 10 + bitWrite(m_ADCON, 6, 1); + bitWrite(m_ADCON, 5, 0); } - else if(clkout == 3) + else if (clkout == 3) { - //11 - bitWrite(_ADCON, 6, 1); - bitWrite(_ADCON, 5, 1); + // 11 + bitWrite(m_ADCON, 6, 1); + bitWrite(m_ADCON, 5, 1); } - else{} - - writeRegister(ADCON_REG, _ADCON); + else + { + } + + writeRegister(ADCON_REG, m_ADCON); delay(100); } -void ADS1256::setSDCS(uint8_t sdcs) //Setting SDCS +void ADS1256::setSDCS(uint8_t sdcs) // Setting SDCS { - _ADCON = readRegister(ADCON_REG); //Read the most recent value of the register - - //Values: 0, 1, 2, 3 - - if(sdcs == 0) + m_ADCON = readRegister(ADCON_REG); // Read the most recent value of the register + + // Values: 0, 1, 2, 3 + + if (sdcs == 0) { - //00 (default) - bitWrite(_ADCON, 4, 0); - bitWrite(_ADCON, 3, 0); + // 00 (default) + bitWrite(m_ADCON, 4, 0); + bitWrite(m_ADCON, 3, 0); } - else if(sdcs == 1) + else if (sdcs == 1) { - //01 - bitWrite(_ADCON, 4, 0); - bitWrite(_ADCON, 3, 1); + // 01 + bitWrite(m_ADCON, 4, 0); + bitWrite(m_ADCON, 3, 1); } - else if(sdcs == 2) + else if (sdcs == 2) { - //10 - bitWrite(_ADCON, 4, 1); - bitWrite(_ADCON, 3, 0); + // 10 + bitWrite(m_ADCON, 4, 1); + bitWrite(m_ADCON, 3, 0); } - else if(sdcs == 3) + else if (sdcs == 3) { - //11 - bitWrite(_ADCON, 4, 1); - bitWrite(_ADCON, 3, 1); + // 11 + bitWrite(m_ADCON, 4, 1); + bitWrite(m_ADCON, 3, 1); } - else{} - - writeRegister(ADCON_REG, _ADCON); + else + { + } + + writeRegister(ADCON_REG, m_ADCON); delay(100); } -void ADS1256::setByteOrder(uint8_t byteOrder) //Setting byte order (MSB/LSB) +void ADS1256::setByteOrder(uint8_t byteOrder) // Setting byte order (MSB/LSB) { - _STATUS = readRegister(STATUS_REG); //Read the most recent value of the register - - if(byteOrder == 0) + m_STATUS = readRegister(STATUS_REG); // Read the most recent value of the register + + if (byteOrder == 0) { - //Byte order is MSB (default) - bitWrite(_STATUS, 3, 0); - //Set value of _STATUS at the third bit to 0 + // Byte order is MSB (default) + bitWrite(m_STATUS, 3, 0); + // Set value of _STATUS at the third bit to 0 } - else if(byteOrder == 1) + else if (byteOrder == 1) { - //Byte order is LSB - bitWrite(_STATUS, 3, 1); - //Set value of _STATUS at the third bit to 1 + // Byte order is LSB + bitWrite(m_STATUS, 3, 1); + // Set value of _STATUS at the third bit to 1 } - else{} - - writeRegister(STATUS_REG, _STATUS); + else + { + } + + writeRegister(STATUS_REG, m_STATUS); delay(100); } -uint8_t ADS1256::getByteOrder() //Getting byte order (MSB/LSB) -{ - uint8_t statusValue = readRegister(STATUS_REG); //Read the whole STATUS register - +uint8_t ADS1256::getByteOrder() // Getting byte order (MSB/LSB) +{ + uint8_t statusValue = readRegister(STATUS_REG); // Read the whole STATUS register + return bitRead(statusValue, 3); } -void ADS1256::setAutoCal(uint8_t acal) //Setting ACAL (Automatic SYSCAL) -{ - _STATUS = readRegister(STATUS_REG); //Read the most recent value of the register - - if(acal == 0) +void ADS1256::setAutoCal(uint8_t acal) // Setting ACAL (Automatic SYSCAL) +{ + m_STATUS = readRegister(STATUS_REG); // Read the most recent value of the register + + if (acal == 0) { - //Auto-calibration is disabled (default) - bitWrite(_STATUS, 2, 0); + // Auto-calibration is disabled (default) + bitWrite(m_STATUS, 2, 0); //_STATUS |= B00000000; } - else if(acal == 1) + else if (acal == 1) { - //Auto-calibration is enabled - bitWrite(_STATUS, 2, 1); + // Auto-calibration is enabled + bitWrite(m_STATUS, 2, 1); //_STATUS |= B00000100; } - else{} - - writeRegister(STATUS_REG, _STATUS); + else + { + } + + writeRegister(STATUS_REG, m_STATUS); delay(100); } -uint8_t ADS1256::getAutoCal() //Getting ACAL (Automatic SYSCAL) -{ - uint8_t statusValue = readRegister(STATUS_REG); //Read the whole STATUS register - +uint8_t ADS1256::getAutoCal() // Getting ACAL (Automatic SYSCAL) +{ + uint8_t statusValue = readRegister(STATUS_REG); // Read the whole STATUS register + return bitRead(statusValue, 2); } -void ADS1256::setBuffer(uint8_t bufen) //Setting input buffer (Input impedance) -{ - _STATUS = readRegister(STATUS_REG); //Read the most recent value of the register - - if(bufen == 0) +void ADS1256::setBuffer(uint8_t bufen) // Setting input buffer (Input impedance) +{ + m_STATUS = readRegister(STATUS_REG); // Read the most recent value of the register + + if (bufen == 0) { - //Analog input buffer is disabled (default) + // Analog input buffer is disabled (default) //_STATUS |= B00000000; - bitWrite(_STATUS, 1, 0); + bitWrite(m_STATUS, 1, 0); } - else if(bufen == 1) + else if (bufen == 1) { - //Analog input buffer is enabled (recommended) + // Analog input buffer is enabled (recommended) //_STATUS |= B00000010; - bitWrite(_STATUS, 1, 1); + bitWrite(m_STATUS, 1, 1); } - else{} - - writeRegister(STATUS_REG, _STATUS); + else + { + } + + writeRegister(STATUS_REG, m_STATUS); delay(100); } -uint8_t ADS1256::getBuffer() //Getting input buffer (Input impedance) -{ - uint8_t statusValue = readRegister(STATUS_REG); //Read the whole STATUS register - +uint8_t ADS1256::getBuffer() // Getting input buffer (Input impedance) +{ + uint8_t statusValue = readRegister(STATUS_REG); // Read the whole STATUS register + return bitRead(statusValue, 1); } -void ADS1256::setGPIO(uint8_t dir0, uint8_t dir1, uint8_t dir2, uint8_t dir3) //Setting GPIO -{ - _GPIO = readRegister(IO_REG); //Read the most recent value of the register - - //Default: 11100000 - DEC: 224 - Ref: p32 I/O section - //Sets D3-D0 as input or output +void ADS1256::setGPIO(uint8_t dir0, uint8_t dir1, uint8_t dir2, uint8_t dir3) // Setting GPIO +{ + m_GPIO = readRegister(IO_REG); // Read the most recent value of the register + + // Default: 11100000 - DEC: 224 - Ref: p32 I/O section + // Sets D3-D0 as input or output uint8_t GPIO_bit7, GPIO_bit6, GPIO_bit5, GPIO_bit4; - - //Bit7: DIR3 - if(dir3 == 1) + + // Bit7: DIR3 + if (dir3 == 1) { - GPIO_bit7 = 1; //D3 is input (default) + GPIO_bit7 = 1; // D3 is input (default) } else { - GPIO_bit7 = 0; //D3 is output - } - bitWrite(_GPIO, 7, GPIO_bit7); + GPIO_bit7 = 0; // D3 is output + } + bitWrite(m_GPIO, 7, GPIO_bit7); //----------------------------------------------------- - //Bit6: DIR2 - if(dir2 == 1) + // Bit6: DIR2 + if (dir2 == 1) { - GPIO_bit6 = 1; //D2 is input (default) + GPIO_bit6 = 1; // D2 is input (default) } else { - GPIO_bit6 = 0; //D2 is output + GPIO_bit6 = 0; // D2 is output } - bitWrite(_GPIO, 6, GPIO_bit6); + bitWrite(m_GPIO, 6, GPIO_bit6); //----------------------------------------------------- - //Bit5: DIR1 - if(dir1 == 1) + // Bit5: DIR1 + if (dir1 == 1) { - GPIO_bit5 = 1; //D1 is input (default) + GPIO_bit5 = 1; // D1 is input (default) } else { - GPIO_bit5 = 0; //D1 is output + GPIO_bit5 = 0; // D1 is output } - bitWrite(_GPIO, 5, GPIO_bit5); + bitWrite(m_GPIO, 5, GPIO_bit5); //----------------------------------------------------- - //Bit4: DIR0 - if(dir0 == 1) + // Bit4: DIR0 + if (dir0 == 1) { - GPIO_bit4 = 1; //D0 is input + GPIO_bit4 = 1; // D0 is input } else { - GPIO_bit4 = 0; //D0 is output (default) + GPIO_bit4 = 0; // D0 is output (default) } - bitWrite(_GPIO, 4, GPIO_bit4); + bitWrite(m_GPIO, 4, GPIO_bit4); //----------------------------------------------------- - - writeRegister(IO_REG, _GPIO); + + writeRegister(IO_REG, m_GPIO); delay(100); } -void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, uint8_t dir3value) //Writing GPIO +void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, uint8_t dir3value) // Writing GPIO { - _GPIO = readRegister(IO_REG); - - //Sets D3-D0 output values - //It is important that first one must use setGPIO, then writeGPIO - + m_GPIO = readRegister(IO_REG); + + // Sets D3-D0 output values + // It is important that first one must use setGPIO, then writeGPIO + uint8_t GPIO_bit3, GPIO_bit2, GPIO_bit1, GPIO_bit0; - - //Bit3: DIR3 - if(dir3value == 1) + + // Bit3: DIR3 + if (dir3value == 1) { GPIO_bit3 = 1; } else { GPIO_bit3 = 0; - } - bitWrite(_GPIO, 3, GPIO_bit3); + } + bitWrite(m_GPIO, 3, GPIO_bit3); //----------------------------------------------------- - //Bit2: DIR2 - if(dir2value == 1) + // Bit2: DIR2 + if (dir2value == 1) { GPIO_bit2 = 1; } else { GPIO_bit2 = 0; - } - bitWrite(_GPIO, 2, GPIO_bit2); + } + bitWrite(m_GPIO, 2, GPIO_bit2); //----------------------------------------------------- - //Bit1: DIR1 - if(dir1value == 1) + // Bit1: DIR1 + if (dir1value == 1) { GPIO_bit1 = 1; } @@ -407,356 +444,354 @@ void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, { GPIO_bit1 = 0; } - bitWrite(_GPIO, 1, GPIO_bit1); + bitWrite(m_GPIO, 1, GPIO_bit1); //----------------------------------------------------- - //Bit0: DIR0 - if(dir0value == 1) + // Bit0: DIR0 + if (dir0value == 1) { GPIO_bit0 = 1; } else { GPIO_bit0 = 0; - } - bitWrite(_GPIO, 0, GPIO_bit0); - //----------------------------------------------------- - - writeRegister(IO_REG, _GPIO); + } + bitWrite(m_GPIO, 0, GPIO_bit0); + //----------------------------------------------------- + + writeRegister(IO_REG, m_GPIO); delay(100); } -uint8_t ADS1256::readGPIO(uint8_t gpioPin) //Reading GPIO -{ +uint8_t ADS1256::readGPIO(uint8_t gpioPin) // Reading GPIO +{ uint8_t GPIO_bit3, GPIO_bit2, GPIO_bit1, GPIO_bit0, GPIO_return; - - _GPIO = readRegister(IO_REG); //Read the GPIO register - - //Save each bit values in a variable - GPIO_bit3 = bitRead(_GPIO, 3); - GPIO_bit2 = bitRead(_GPIO, 2); - GPIO_bit1 = bitRead(_GPIO, 1); - GPIO_bit0 = bitRead(_GPIO, 0); - - delay(100); - - switch(gpioPin) //Selecting which value should be returned + + m_GPIO = readRegister(IO_REG); // Read the GPIO register + + // Save each bit values in a variable + GPIO_bit3 = bitRead(m_GPIO, 3); + GPIO_bit2 = bitRead(m_GPIO, 2); + GPIO_bit1 = bitRead(m_GPIO, 1); + GPIO_bit0 = bitRead(m_GPIO, 0); + + delay(100); + + switch (gpioPin) // Selecting which value should be returned { - case 0: + case 0: GPIO_return = GPIO_bit0; break; - - case 1: + + case 1: GPIO_return = GPIO_bit1; break; - - case 2: + + case 2: GPIO_return = GPIO_bit2; break; - - case 3: + + case 3: GPIO_return = GPIO_bit3; break; } return GPIO_return; - } void ADS1256::sendDirectCommand(uint8_t directCommand) { - //Direct commands can be found in the datasheet Page 34, Table 24. - _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); + // Direct commands can be found in the datasheet Page 34, Table 24. + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); - CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" - delayMicroseconds(5); - _spi->transfer(directCommand); //Send Command - delayMicroseconds(5); - CS_HIGH(); //REF: P34: "CS must stay low during the entire command sequence" + CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" + delayMicroseconds(5); + _spi->transfer(directCommand); // Send Command + delayMicroseconds(5); + CS_HIGH(); // REF: P34: "CS must stay low during the entire command sequence" - _spi->endTransaction(); + _spi->endTransaction(); } - -float ADS1256::convertToVoltage(int32_t rawData) //Converting the 24-bit data into a voltage value -{ - return(conversionParameter * rawData); +float ADS1256::convertToVoltage(int32_t rawData) // Converting the 24-bit data into a voltage value +{ + return (m_conversionParameter * rawData); } void ADS1256::writeRegister(uint8_t registerAddress, uint8_t registerValueToWrite) -{ - waitForLowDRDY(); - - _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); - //SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. - - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - - delayMicroseconds(5); //see t6 in the datasheet - - _spi->transfer(WREG | registerAddress); // 0x50 = 01010000 = WREG - - _spi->transfer(0x00); //2nd (empty) command byte - - _spi->transfer(registerValueToWrite); //pass the value to the register - - CS_HIGH(); - _spi->endTransaction(); - delay(100); - -} - -long ADS1256::readRegister(uint8_t registerAddress) //Reading a register { - waitForLowDRDY(); - - _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); - //SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. + waitForLowDRDY(); - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); + // SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. - _spi->transfer(RREG | registerAddress); //0x10 = 0001000 = RREG - OR together the two numbers (command + address) + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(0x00); //2nd (empty) command byte + delayMicroseconds(5); // see t6 in the datasheet - delayMicroseconds(5); //see t6 in the datasheet + _spi->transfer(WREG | registerAddress); // 0x50 = 01010000 = WREG - uint8_t regValue = _spi->transfer(0x00); //read out the register value + _spi->transfer(0x00); // 2nd (empty) command byte - CS_HIGH(); - _spi->endTransaction(); - delay(100); - return regValue; + _spi->transfer(registerValueToWrite); // pass the value to the register + + CS_HIGH(); + _spi->endTransaction(); + delay(100); } +long ADS1256::readRegister(uint8_t registerAddress) // Reading a register +{ + waitForLowDRDY(); -long ADS1256::readSingle() //Reading a single value ONCE using the RDATA command + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); + // SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. + + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + + _spi->transfer(RREG | registerAddress); // 0x10 = 0001000 = RREG - OR together the two numbers (command + address) + + _spi->transfer(0x00); // 2nd (empty) command byte + + delayMicroseconds(5); // see t6 in the datasheet + + uint8_t regValue = _spi->transfer(0x00); // read out the register value + + CS_HIGH(); + _spi->endTransaction(); + delay(100); + return regValue; +} + +long ADS1256::readSingle() // Reading a single value ONCE using the RDATA command { _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); - CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" + CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" waitForLowDRDY(); - _spi->transfer(RDATA); //Issue RDATA (0000 0001) command - delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + _spi->transfer(RDATA); // Issue RDATA (0000 0001) command + delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. - _outputBuffer[0] = _spi->transfer(0); // MSB - _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB + m_outputBuffer[0] = _spi->transfer(0); // MSB + m_outputBuffer[1] = _spi->transfer(0); // Mid-byte + m_outputBuffer[2] = _spi->transfer(0); // LSB - //Shifting and combining the above three items into a single, 24-bit number - _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - - CS_HIGH(); //We finished the command sequence, so we set CS to HIGH + // Shifting and combining the above three items into a single, 24-bit number + m_outputValue = ((long)m_outputBuffer[0] << 16) | ((long)m_outputBuffer[1] << 8) | (m_outputBuffer[2]); + m_outputValue = convertSigned24BitToLong(m_outputValue); + + CS_HIGH(); // We finished the command sequence, so we set CS to HIGH _spi->endTransaction(); - - return(_outputValue); + + return (m_outputValue); } -long ADS1256::readSingleContinuous() //Reads the recently selected input channel using RDATAC -{ - if(_isAcquisitionRunning == false) +long ADS1256::readSingleContinuous() // Reads the recently selected input channel using RDATAC +{ + if (m_isAcquisitionRunning == false) { - _isAcquisitionRunning = true; - _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); - CS_LOW(); //REF: P34: "CS must stay low during the entire command sequence" - waitForLowDRDY(); - _spi->transfer(RDATAC); //Issue RDATAC (0000 0011) - delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + m_isAcquisitionRunning = true; + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); + CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" + waitForLowDRDY(); + _spi->transfer(RDATAC); // Issue RDATAC (0000 0011) + delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. } else { waitForLowDRDY(); - } - - _outputBuffer[0] = _spi->transfer(0); // MSB - _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB - - _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - + } + + m_outputBuffer[0] = _spi->transfer(0); // MSB + m_outputBuffer[1] = _spi->transfer(0); // Mid-byte + m_outputBuffer[2] = _spi->transfer(0); // LSB + + m_outputValue = ((long)m_outputBuffer[0] << 16) | ((long)m_outputBuffer[1] << 8) | (m_outputBuffer[2]); + m_outputValue = convertSigned24BitToLong(m_outputValue); + waitForHighDRDY(); - - return _outputValue; + + return m_outputValue; } long ADS1256::cycleSingle() { - if(_isAcquisitionRunning == false) + if (m_isAcquisitionRunning == false) { - _isAcquisitionRunning = true; - _cycle = 0; - _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(WREG | MUX_REG); // 0x50 = WREG //1 = MUX - _spi->transfer(0x00); - _spi->transfer(SING_0); //AIN0+AINCOM - delayMicroseconds(250); + m_isAcquisitionRunning = true; + m_cycle = 0; + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + _spi->transfer(WREG | MUX_REG); // 0x50 = WREG //1 = MUX + _spi->transfer(0x00); + _spi->transfer(SING_0); // AIN0+AINCOM + delayMicroseconds(250); } else - {} - - if(_cycle < 8) - { - _outputValue = 0; - waitForLowDRDY(); - //Step 1. - Updating MUX - switch (_cycle) - { - //Channels are written manually - case 0: //Channel 2 - updateMUX(SING_1); //AIN1+AINCOM - break; + { + } - case 1: //Channel 3 - updateMUX(SING_2); //AIN2+AINCOM - break; + if (m_cycle < 8) + { + m_outputValue = 0; + waitForLowDRDY(); + // Step 1. - Updating MUX + switch (m_cycle) + { + // Channels are written manually + case 0: // Channel 2 + updateMUX(SING_1); // AIN1+AINCOM + break; - case 2: //Channel 4 - updateMUX(SING_3); //AIN3+AINCOM - break; + case 1: // Channel 3 + updateMUX(SING_2); // AIN2+AINCOM + break; - case 3: //Channel 5 - updateMUX(SING_4); //AIN4+AINCOM - break; + case 2: // Channel 4 + updateMUX(SING_3); // AIN3+AINCOM + break; - case 4: //Channel 6 - updateMUX(SING_5); //AIN5+AINCOM - break; + case 3: // Channel 5 + updateMUX(SING_4); // AIN4+AINCOM + break; - case 5: //Channel 7 - updateMUX(SING_6); //AIN6+AINCOM - break; + case 4: // Channel 6 + updateMUX(SING_5); // AIN5+AINCOM + break; - case 6: //Channel 8 - updateMUX(SING_7); //AIN7+AINCOM - break; + case 5: // Channel 7 + updateMUX(SING_6); // AIN6+AINCOM + break; - case 7: //Channel 1 - updateMUX(SING_0); //AIN0+AINCOM - break; - } - //Step 2. - _spi->transfer(SYNC); //SYNC - delayMicroseconds(4); //t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us - _spi->transfer(WAKEUP); //WAKEUP + case 6: // Channel 8 + updateMUX(SING_7); // AIN7+AINCOM + break; - //Step 3. - //Issue RDATA (0000 0001) command - _spi->transfer(RDATA); - delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + case 7: // Channel 1 + updateMUX(SING_0); // AIN0+AINCOM + break; + } + // Step 2. + _spi->transfer(SYNC); // SYNC + delayMicroseconds(4); // t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us + _spi->transfer(WAKEUP); // WAKEUP - _outputBuffer[0] = _spi->transfer(0); // MSB - _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB - - _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - - _cycle++; //Increase cycle - This will move to the next MUX input channel - if(_cycle == 8) - { - _cycle = 0; //Reset to 0 - Restart conversion from the 1st input channel - } - } - - return _outputValue; + // Step 3. + // Issue RDATA (0000 0001) command + _spi->transfer(RDATA); + delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. + + m_outputBuffer[0] = _spi->transfer(0); // MSB + m_outputBuffer[1] = _spi->transfer(0); // Mid-byte + m_outputBuffer[2] = _spi->transfer(0); // LSB + + m_outputValue = ((long)m_outputBuffer[0] << 16) | ((long)m_outputBuffer[1] << 8) | (m_outputBuffer[2]); + m_outputValue = convertSigned24BitToLong(m_outputValue); + + m_cycle++; // Increase cycle - This will move to the next MUX input channel + if (m_cycle == 8) + { + m_cycle = 0; // Reset to 0 - Restart conversion from the 1st input channel + } + } + + return m_outputValue; } -long ADS1256::cycleDifferential() +long ADS1256::cycleDifferential() { - if(_isAcquisitionRunning == false) + if (m_isAcquisitionRunning == false) { - _cycle = 0; - _isAcquisitionRunning = true; - _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); - - //Set the AIN0+AIN1 as inputs manually - CS_LOW(); //CS must stay LOW during the entire sequence [Ref: P34, T24] - _spi->transfer(WREG | MUX_REG); // 0x50 = WREG //1 = MUX - _spi->transfer(0x00); - _spi->transfer(DIFF_0_1); //AIN0+AIN1 - delayMicroseconds(250); + m_cycle = 0; + m_isAcquisitionRunning = true; + _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); + + // Set the AIN0+AIN1 as inputs manually + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] + _spi->transfer(WREG | MUX_REG); // 0x50 = WREG //1 = MUX + _spi->transfer(0x00); + _spi->transfer(DIFF_0_1); // AIN0+AIN1 + delayMicroseconds(250); } else - {} - - if(_cycle < 4) - { - _outputValue = 0; - //DRDY has to go low - waitForLowDRDY(); + { + } - //Step 1. - Updating MUX - switch (_cycle) - { - case 0: //Channel 2 - updateMUX(DIFF_2_3); //AIN2+AIN3 - break; + if (m_cycle < 4) + { + m_outputValue = 0; + // DRDY has to go low + waitForLowDRDY(); - case 1: //Channel 3 - updateMUX(DIFF_4_5); //AIN4+AIN5 - break; + // Step 1. - Updating MUX + switch (m_cycle) + { + case 0: // Channel 2 + updateMUX(DIFF_2_3); // AIN2+AIN3 + break; - case 2: //Channel 4 - updateMUX(DIFF_6_7); //AIN6+AIN7 - break; + case 1: // Channel 3 + updateMUX(DIFF_4_5); // AIN4+AIN5 + break; - case 3: //Channel 1 - updateMUX(DIFF_0_1); //AIN0+AIN1 - break; - } + case 2: // Channel 4 + updateMUX(DIFF_6_7); // AIN6+AIN7 + break; - _spi->transfer(SYNC); //SYNC - delayMicroseconds(4); //t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us - _spi->transfer(WAKEUP); //WAKEUP + case 3: // Channel 1 + updateMUX(DIFF_0_1); // AIN0+AIN1 + break; + } - //Step 3. - _spi->transfer(RDATA); //Issue RDATA (0000 0001) command - delayMicroseconds(7); //Wait t6 time (~6.51 us) REF: P34, FIG:30. + _spi->transfer(SYNC); // SYNC + delayMicroseconds(4); // t11 delay 24*tau = 3.125 us //delay should be larger, so we delay by 4 us + _spi->transfer(WAKEUP); // WAKEUP - _outputBuffer[0] = _spi->transfer(0); // MSB - _outputBuffer[1] = _spi->transfer(0); // Mid-byte - _outputBuffer[2] = _spi->transfer(0); // LSB - - _outputValue = ((long)_outputBuffer[0]<<16) | ((long)_outputBuffer[1]<<8) | (_outputBuffer[2]); - _outputValue = convertSigned24BitToLong(_outputValue); - - _cycle++; - if(_cycle == 4) - { - _cycle = 0; - //After the 4th cycle, we reset to zero so the next iteration reads the 1st MUX again - } - } - - return _outputValue; + // Step 3. + _spi->transfer(RDATA); // Issue RDATA (0000 0001) command + delayMicroseconds(7); // Wait t6 time (~6.51 us) REF: P34, FIG:30. + + m_outputBuffer[0] = _spi->transfer(0); // MSB + m_outputBuffer[1] = _spi->transfer(0); // Mid-byte + m_outputBuffer[2] = _spi->transfer(0); // LSB + + m_outputValue = ((long)m_outputBuffer[0] << 16) | ((long)m_outputBuffer[1] << 8) | (m_outputBuffer[2]); + m_outputValue = convertSigned24BitToLong(m_outputValue); + + m_cycle++; + if (m_cycle == 4) + { + m_cycle = 0; + // After the 4th cycle, we reset to zero so the next iteration reads the 1st MUX again + } + } + + return m_outputValue; } void ADS1256::updateConversionParameter() { - conversionParameter = ((2.0 * _VREF) / 8388608.0) / (pow(2, _PGA)); //Calculate the "bit to Volts" multiplier - //8388608 = 2^{23} - 1, REF: p23, Table 16. + m_conversionParameter = ((2.0 * m_VREF) / 8388608.0) / (pow(2, m_PGA)); // Calculate the "bit to Volts" multiplier + // 8388608 = 2^{23} - 1, REF: p23, Table 16. } void ADS1256::updateMUX(uint8_t muxValue) { - _spi->transfer(WREG | MUX_REG); //Write to the MUX register (0x50 is the WREG command) - _spi->transfer(0x00); - _spi->transfer(muxValue); //Write the new MUX value + _spi->transfer(WREG | MUX_REG); // Write to the MUX register (0x50 is the WREG command) + _spi->transfer(0x00); + _spi->transfer(muxValue); // Write the new MUX value } inline void ADS1256::CS_LOW() { - if (_CS_pin != PIN_UNUSED) //Sets CS LOW if it is not an unused pin + if (m_CS_pin != PIN_UNUSED) // Sets CS LOW if it is not an unused pin { - digitalWrite(_CS_pin, LOW); + digitalWrite(m_CS_pin, LOW); } } inline void ADS1256::CS_HIGH() { - if (_CS_pin != PIN_UNUSED) //Sets CS HIGH if it is not an unused pin + if (m_CS_pin != PIN_UNUSED) // Sets CS HIGH if it is not an unused pin { - digitalWrite(_CS_pin, HIGH); + digitalWrite(m_CS_pin, HIGH); } } \ No newline at end of file diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.h b/RotaxMonitor/lib/ADS1256/ADS1256.h index 35ade99..5670d5a 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.h +++ b/RotaxMonitor/lib/ADS1256/ADS1256.h @@ -1,11 +1,11 @@ -//ADS1256 header file +// ADS1256 header file /* Name: ADS1256.h Created: 2022/07/14 Author: Curious Scientist Editor: Notepad++ Comment: Visit https://curiousscientist.tech/blog/ADS1256-custom-library - Special thanks to + Special thanks to Abraão Queiroz for spending time on the code and suggesting corrections for ESP32 microcontrollers Benjamin Pelletier for pointing out and fixing an issue around the handling of the DRDY signal */ @@ -14,54 +14,55 @@ #define _ADS1256_h #include +#include // SPI Frequency #define SPI_FREQ 1920000 -//Differential inputs -#define DIFF_0_1 0b00000001 //A0 + A1 as differential input -#define DIFF_2_3 0b00100011 //A2 + A3 as differential input -#define DIFF_4_5 0b01000101 //A4 + A5 as differential input -#define DIFF_6_7 0b01100111 //A6 + A7 as differential input +// Differential inputs +#define DIFF_0_1 0b00000001 // A0 + A1 as differential input +#define DIFF_2_3 0b00100011 // A2 + A3 as differential input +#define DIFF_4_5 0b01000101 // A4 + A5 as differential input +#define DIFF_6_7 0b01100111 // A6 + A7 as differential input -//Single-ended inputs -#define SING_0 0b00001111 //A0 + GND (common) as single-ended input -#define SING_1 0b00011111 //A1 + GND (common) as single-ended input -#define SING_2 0b00101111 //A2 + GND (common) as single-ended input -#define SING_3 0b00111111 //A3 + GND (common) as single-ended input -#define SING_4 0b01001111 //A4 + GND (common) as single-ended input -#define SING_5 0b01011111 //A5 + GND (common) as single-ended input -#define SING_6 0b01101111 //A6 + GND (common) as single-ended input -#define SING_7 0b01111111 //A7 + GND (common) as single-ended input +// Single-ended inputs +#define SING_0 0b00001111 // A0 + GND (common) as single-ended input +#define SING_1 0b00011111 // A1 + GND (common) as single-ended input +#define SING_2 0b00101111 // A2 + GND (common) as single-ended input +#define SING_3 0b00111111 // A3 + GND (common) as single-ended input +#define SING_4 0b01001111 // A4 + GND (common) as single-ended input +#define SING_5 0b01011111 // A5 + GND (common) as single-ended input +#define SING_6 0b01101111 // A6 + GND (common) as single-ended input +#define SING_7 0b01111111 // A7 + GND (common) as single-ended input -//PGA settings //Input voltage range -#define PGA_1 0b00000000 //± 5 V -#define PGA_2 0b00000001 //± 2.5 V -#define PGA_4 0b00000010 //± 1.25 V -#define PGA_8 0b00000011 //± 625 mV -#define PGA_16 0b00000100 //± 312.5 mV +// PGA settings //Input voltage range +#define PGA_1 0b00000000 // ± 5 V +#define PGA_2 0b00000001 // ± 2.5 V +#define PGA_4 0b00000010 // ± 1.25 V +#define PGA_8 0b00000011 // ± 625 mV +#define PGA_16 0b00000100 // ± 312.5 mV #define PGA_32 0b00000101 //+ 156.25 mV -#define PGA_64 0b00000110 //± 78.125 mV +#define PGA_64 0b00000110 // ± 78.125 mV -//Datarate //DEC -#define DRATE_30000SPS 0b11110000 //240 -#define DRATE_15000SPS 0b11100000 //224 -#define DRATE_7500SPS 0b11010000 //208 -#define DRATE_3750SPS 0b11000000 //192 -#define DRATE_2000SPS 0b10110000 //176 -#define DRATE_1000SPS 0b10100001 //161 -#define DRATE_500SPS 0b10010010 //146 -#define DRATE_100SPS 0b10000010 //130 -#define DRATE_60SPS 0b01110010 //114 -#define DRATE_50SPS 0b01100011 //99 -#define DRATE_30SPS 0b01010011 //83 -#define DRATE_25SPS 0b01000011 //67 -#define DRATE_15SPS 0b00110011 //51 -#define DRATE_10SPS 0b00100011 //35 -#define DRATE_5SPS 0b00010011 //19 -#define DRATE_2SPS 0b00000011 //3 +// Datarate //DEC +#define DRATE_30000SPS 0b11110000 // 240 +#define DRATE_15000SPS 0b11100000 // 224 +#define DRATE_7500SPS 0b11010000 // 208 +#define DRATE_3750SPS 0b11000000 // 192 +#define DRATE_2000SPS 0b10110000 // 176 +#define DRATE_1000SPS 0b10100001 // 161 +#define DRATE_500SPS 0b10010010 // 146 +#define DRATE_100SPS 0b10000010 // 130 +#define DRATE_60SPS 0b01110010 // 114 +#define DRATE_50SPS 0b01100011 // 99 +#define DRATE_30SPS 0b01010011 // 83 +#define DRATE_25SPS 0b01000011 // 67 +#define DRATE_15SPS 0b00110011 // 51 +#define DRATE_10SPS 0b00100011 // 35 +#define DRATE_5SPS 0b00010011 // 19 +#define DRATE_2SPS 0b00000011 // 3 -//Status register +// Status register #define BITORDER_MSB 0 #define BITORDER_LSB 1 #define ACAL_DISABLED 0 @@ -69,7 +70,7 @@ #define BUFFER_DISABLED 0 #define BUFFER_ENABLED 1 -//Register addresses +// Register addresses #define STATUS_REG 0x00 #define MUX_REG 0x01 #define ADCON_REG 0x02 @@ -82,7 +83,7 @@ #define FSC1_REG 0x09 #define FSC2_REG 0x0A -//Command definitions +// Command definitions #define WAKEUP 0b00000000 #define RDATA 0b00000001 #define RDATAC 0b00000011 @@ -99,26 +100,30 @@ #define RESET 0b11111110 //---------------------------------------------------------------- - class ADS1256 -{ +{ public: -static constexpr int8_t PIN_UNUSED = -1; + static constexpr int8_t PIN_UNUSED = -1; - //Constructor - ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYNC_pin, const int8_t CS_pin, float VREF, SPIClass* spi = &SPI); - - //Initializing function - void InitializeADC(); - //ADS1256(int drate, int pga, int byteOrder, bool bufen); - - //Read a register + // Constructor + ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYNC_pin, const int8_t CS_pin, float VREF, SPIClass *spi = &SPI); + ~ADS1256() + { + vSemaphoreDelete(m_drdyHigh); + vSemaphoreDelete(m_drdyLow); + } + + // Initializing function + void InitializeADC(); + // ADS1256(int drate, int pga, int byteOrder, bool bufen); + + // Read a register long readRegister(uint8_t registerAddress); - - //Write a register - void writeRegister(uint8_t registerAddress, uint8_t registerValueToWrite); - //Individual methods + // Write a register + void writeRegister(uint8_t registerAddress, uint8_t registerValueToWrite); + + // Individual methods void setDRATE(uint8_t drate); void setPGA(uint8_t pga); uint8_t getPGA(); @@ -131,62 +136,80 @@ static constexpr int8_t PIN_UNUSED = -1; uint8_t getAutoCal(); void setGPIO(uint8_t dir0, uint8_t dir1, uint8_t dir2, uint8_t dir3); void writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, uint8_t dir3value); - uint8_t readGPIO(uint8_t gpioPin); + uint8_t readGPIO(uint8_t gpioPin); void setCLKOUT(uint8_t clkout); - void setSDCS(uint8_t sdcs); - void sendDirectCommand(uint8_t directCommand); + void setSDCS(uint8_t sdcs); + void sendDirectCommand(uint8_t directCommand); - //Get a single conversion + // Get a single conversion long readSingle(); - - //Single input continuous reading + + // Single input continuous reading long readSingleContinuous(); - - //Cycling through the single-ended inputs - long cycleSingle(); //Ax + COM - - //Cycling through the differential inputs - long cycleDifferential(); //Ax + Ay - - //Converts the reading into a voltage value + + // Cycling through the single-ended inputs + long cycleSingle(); // Ax + COM + + // Cycling through the differential inputs + long cycleDifferential(); // Ax + Ay + + // Converts the reading into a voltage value float convertToVoltage(int32_t rawData); - - //Stop AD + + // Stop AD void stopConversion(); - + + // functions for callback + inline uint8_t getDRDYpin() + { + return m_DRDY_pin; + } + + SemaphoreHandle_t getDRDYsemaphoreHigh() + { + return m_drdyHigh; + } + + SemaphoreHandle_t getDRDYsemaphoreLow() + { + return m_drdyLow; + } + private: - -SPIClass* _spi; //Pointer to an SPIClass object + SPIClass *_spi; // Pointer to an SPIClass object -void waitForLowDRDY(); // Block until DRDY is low -void waitForHighDRDY(); // Block until DRDY is high -void updateMUX(uint8_t muxValue); -inline void CS_LOW(); -inline void CS_HIGH(); + void waitForLowDRDY(); // Block until DRDY is low + void waitForHighDRDY(); // Block until DRDY is high + void updateMUX(uint8_t muxValue); + inline void CS_LOW(); + inline void CS_HIGH(); -void updateConversionParameter(); //Refresh the conversion parameter based on the PGA + void updateConversionParameter(); // Refresh the conversion parameter based on the PGA -float _VREF = 0; //Value of the reference voltage -float conversionParameter = 0; //PGA-dependent multiplier -//Pins -int8_t _DRDY_pin; //Pin assigned for DRDY -int8_t _RESET_pin; //Pin assigned for RESET -int8_t _SYNC_pin; //Pin assigned for SYNC -int8_t _CS_pin; //Pin assigned for CS + float m_VREF = 0; // Value of the reference voltage + float m_conversionParameter = 0; // PGA-dependent multiplier + // Pins + int8_t m_DRDY_pin; // Pin assigned for DRDY + int8_t m_RESET_pin; // Pin assigned for RESET + int8_t m_SYNC_pin; // Pin assigned for SYNC + int8_t m_CS_pin; // Pin assigned for CS -//Register values -byte _DRATE; //Value of the DRATE register -byte _ADCON; //Value of the ADCON register -byte _MUX; //Value of the MUX register -byte _PGA; //Value of the PGA (within ADCON) -byte _GPIO; //Value of the GPIO register -byte _STATUS; //Value of the status register -byte _GPIOvalue; //GPIO value -byte _ByteOrder; //Byte order + // Register values + uint8_t m_DRATE; // Value of the DRATE register + uint8_t m_ADCON; // Value of the ADCON register + uint8_t m_MUX; // Value of the MUX register + uint8_t m_PGA; // Value of the PGA (within ADCON) + uint8_t m_GPIO; // Value of the GPIO register + uint8_t m_STATUS; // Value of the status register + uint8_t m_GPIOvalue; // GPIO value + uint8_t m_ByteOrder; // Byte order -byte _outputBuffer[3]; //3-byte (24-bit) buffer for the fast acquisition - Single-channel, continuous -long _outputValue; //Combined value of the _outputBuffer[3] -bool _isAcquisitionRunning; //bool that keeps track of the acquisition (running or not) -uint8_t _cycle; //Tracks the cycles as the MUX is cycling through the input channels + uint8_t m_outputBuffer[3]; // 3-byte (24-bit) buffer for the fast acquisition - Single-channel, continuous + int32_t m_outputValue; // Combined value of the m_outputBuffer[3] + bool m_isAcquisitionRunning; // bool that keeps track of the acquisition (running or not) + uint8_t m_cycle; // Tracks the cycles as the MUX is cycling through the input channels + + SemaphoreHandle_t m_drdyHigh; + SemaphoreHandle_t m_drdyLow; }; #endif \ No newline at end of file diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 7ae1830..cd46365 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -131,35 +131,6 @@ void loop() #endif LOG_DEBUG("Init SPI OK"); - uint8_t chs[8] = { - SING_0, SING_1, SING_2, SING_3, SING_4, SING_5, SING_6, SING_7}; - float res[8]; - auto timeout = Serial.getTimeout(); - Serial.setTimeout(0); - uint64_t count = 0; - - while (Serial.read() != 's') // The conversion is stopped by a character received from the serial port - { - auto start = esp_timer_get_time(); - for (int i = 0; i < 8; i++) - { - // dev->m_adc_a->setMUX(chs[i]); - res[i] += 0.1f * (dev->m_adc_a->convertToVoltage(dev->m_adc_a->cycleSingle()) - res[i]); - } - auto stop = esp_timer_get_time(); - if (count++ % 25 == 0) - { - clearScreen(); - for (int j = 0; j < 8; j++) - { - Serial.printf("ADC_A SING_%d: %5.4f\n", j, res[j]); - } - Serial.printf("ADC Time: %5.3f ms\n", (float)((stop - start) / 1000.0f)); - } - } - Serial.setTimeout(timeout); - dev->m_adc_a->stopConversion(); - //////// INIT I2C INTERFACES //////// LOG_DEBUG("Init I2C Interfaces"); bool i2c_ok = true; From dce6b0fd4fd16d68dc81a11933be8c7c65fed2f9 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Fri, 17 Apr 2026 13:24:43 +0200 Subject: [PATCH 37/38] working on second adc --- RotaxMonitor/lib/ADS1256/ADS1256.cpp | 4 - RotaxMonitor/src/isr.h | 2 +- RotaxMonitor/src/main.cpp | 116 ++++++++++++++------------- 3 files changed, 63 insertions(+), 59 deletions(-) diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.cpp b/RotaxMonitor/lib/ADS1256/ADS1256.cpp index 9467dd7..13ab8e1 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.cpp +++ b/RotaxMonitor/lib/ADS1256/ADS1256.cpp @@ -89,10 +89,6 @@ void ADS1256::InitializeADC() digitalWrite(m_SYNC_pin, HIGH); // RESET is set to high } -#ifndef ADS1256_SPI_ALREADY_STARTED // Guard macro to allow external initialization of the SPI - _spi->begin(); -#endif - // Applying arbitrary default values to speed up the starting procedure if the user just want to get quick readouts // We both pass values to the variables and then send those values to the corresponding registers delay(200); diff --git a/RotaxMonitor/src/isr.h b/RotaxMonitor/src/isr.h index 1f1d2e7..737d1a3 100644 --- a/RotaxMonitor/src/isr.h +++ b/RotaxMonitor/src/isr.h @@ -16,7 +16,7 @@ #define CORE_0 0 #define CORE_1 1 -#define RT_TASK_STACK 2048 // in words +#define RT_TASK_STACK 4096 // in words #define RT_TASK_PRIORITY (configMAX_PRIORITIES - 5) // highest priority after wifi tasks struct isrParams diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index cd46365..0b04eeb 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -17,7 +17,7 @@ #include // Defines to enable channel B -// #define CH_B_ENABLE +#define CH_B_ENABLE // Debug Defines #define WIFI_SSID "AstroRotaxMonitor" @@ -27,12 +27,13 @@ void setup() { - Serial.begin(921600); + Serial.begin(115200); delay(250); + Serial.setTimeout(30000); // Setup Logger LOG_ATTACH_SERIAL(Serial); - LOG_SET_LEVEL(DebugLogLevel::LVL_INFO); + LOG_SET_LEVEL(DebugLogLevel::LVL_DEBUG); // Print Processor Info LOG_DEBUG("ESP32 Chip:", ESP.getChipModel()); @@ -47,27 +48,27 @@ void setup() LOG_DEBUG("ESP32 Sketch:", ESP.getFreeSketchSpace()); // Init Wifi station - LOG_INFO("Initializing WiFi..."); - WiFi.mode(WIFI_AP); - IPAddress local_IP(10, 11, 12, 1); - IPAddress gateway(10, 11, 12, 1); - IPAddress subnet(255, 255, 255, 0); - WiFi.softAPConfig(local_IP, gateway, subnet); - WiFi.setTxPower(WIFI_POWER_5dBm); // reduce wifi power - if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD)) - { - LOG_INFO("WiFi AP Mode Started"); - LOG_INFO("Wifi SSID:", WIFI_SSID); - LOG_INFO("Wifi Password:", WIFI_PASSWORD); - LOG_INFO("WiFi IP:" + WiFi.softAPIP().toString()); - } - else - { - LOG_ERROR("Failed to start WiFi AP Mode"); - LOG_ERROR("5 seconds to restart..."); - vTaskDelay(pdMS_TO_TICKS(5000)); - esp_restart(); - } + // LOG_INFO("Initializing WiFi..."); + // WiFi.mode(WIFI_AP); + // IPAddress local_IP(10, 11, 12, 1); + // IPAddress gateway(10, 11, 12, 1); + // IPAddress subnet(255, 255, 255, 0); + // WiFi.softAPConfig(local_IP, gateway, subnet); + // WiFi.setTxPower(WIFI_POWER_5dBm); // reduce wifi power + // if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD)) + // { + // LOG_INFO("WiFi AP Mode Started"); + // LOG_INFO("Wifi SSID:", WIFI_SSID); + // LOG_INFO("Wifi Password:", WIFI_PASSWORD); + // LOG_INFO("WiFi IP:" + WiFi.softAPIP().toString()); + // } + // else + // { + // LOG_ERROR("Failed to start WiFi AP Mode"); + // LOG_ERROR("5 seconds to restart..."); + // vTaskDelay(pdMS_TO_TICKS(5000)); + // esp_restart(); + // } // Initialize Interrupt pins on PICKUP detectors initTriggerPinsInputs(); @@ -91,17 +92,36 @@ void loop() //////// INIT SPI INTERFACES //////// bool spiA_ok = true; bool spiB_ok = true; + //////// INIT SPI INTERFACES //////// LOG_DEBUG("Init SPI Interfaces"); SPIClass SPI_A(FSPI); spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 LOG_DEBUG("Init SPI A ok"); -#ifdef CH_B_ENABLE - delay(50); + Serial.readStringUntil('\n'); + dev->m_spi_a.reset(&SPI_A); + dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); + dev->m_adc_a->InitializeADC(); + dev->m_adc_a->setPGA(PGA_1); + dev->m_adc_a->setDRATE(DRATE_7500SPS); + LOG_DEBUG("Init ADC A ok"); + Serial.readStringUntil('\n'); + + delay(250); + + #ifdef CH_B_ENABLE SPIClass SPI_B(HSPI); spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 LOG_DEBUG("Init SPI B ok"); + Serial.readStringUntil('\n'); + dev->m_spi_b.reset(&SPI_B); + dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); + dev->m_adc_b->InitializeADC(); + dev->m_adc_b->setPGA(PGA_1); + dev->m_adc_b->setDRATE(DRATE_7500SPS); + LOG_DEBUG("Init ADC B ok"); + Serial.readStringUntil('\n'); #endif if (!spiA_ok || !spiB_ok) @@ -111,37 +131,23 @@ void loop() vTaskDelay(pdMS_TO_TICKS(5000)); esp_restart(); } - dev->m_spi_a.reset(&SPI_A); -#ifdef CH_B_ENABLE - dev->m_spi_b.reset(&SPI_B); -#endif - // Init ADCs - dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); -#ifdef CH_B_ENABLE - dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); -#endif - // Configure ADCs - dev->m_adc_a->InitializeADC(); - dev->m_adc_a->setPGA(PGA_1); - dev->m_adc_a->setDRATE(DRATE_7500SPS); -#ifdef CH_B_ENABLE - dev->m_adc_b->InitializeADC(); - dev->m_adc_b->setPGA(PGA_1); - dev->m_adc_b->setDRATE(DRATE_30000SPS); -#endif + LOG_DEBUG("Init SPI OK"); + Serial.readStringUntil('\n'); //////// INIT I2C INTERFACES //////// - LOG_DEBUG("Init I2C Interfaces"); - bool i2c_ok = true; - i2c_ok = Wire.begin(SDA, SCL, 100000); - if (!i2c_ok) - { - LOG_ERROR("Unable to Initialize I2C Bus"); - LOG_ERROR("5 seconds to restart..."); - vTaskDelay(pdMS_TO_TICKS(5000)); - esp_restart(); - } + // LOG_DEBUG("Init I2C Interfaces"); + // bool i2c_ok = true; + // i2c_ok = Wire.begin(SDA, SCL, 100000); + // if (!i2c_ok) + // { + // LOG_ERROR("Unable to Initialize I2C Bus"); + // LOG_ERROR("5 seconds to restart..."); + // vTaskDelay(pdMS_TO_TICKS(5000)); + // esp_restart(); + // } + // LOG_DEBUG("Init I2c ok"); + // Serial.readStringUntil('\n'); // Init IO Expanders // dev->m_ext_io = std::make_unique(Wire, dev->m_i2c_mutex, EXPANDER_ALL_INTERRUPT); @@ -212,7 +218,9 @@ void loop() //////// SPAWN REALTIME TASKS //////// auto task_A = rtIgnitionTask(taskA_params, PSRAM_MAX, QUEUE_MAX, CORE_0, fs_mutex); delay(50); + Serial.readStringUntil('\n'); auto task_B = rtIgnitionTask(taskB_params, PSRAM_MAX, QUEUE_MAX, CORE_1, fs_mutex); + Serial.readStringUntil('\n'); // Ignition A on Core 0 auto ignA_task_success = task_A.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL; From 7e7d0a1c59e2024cc0aa89240915181aab7756dc Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Tue, 21 Apr 2026 16:11:07 +0200 Subject: [PATCH 38/38] Second ADC debugging in process --- RotaxMonitor/lib/ADS1256/ADS1256.cpp | 28 ++-- RotaxMonitor/platformio.ini | 12 +- RotaxMonitor/src/devices.h | 16 +-- RotaxMonitor/src/main.cpp | 207 +++++++++++++++------------ RotaxMonitor/src/tasks.cpp | 54 ++++--- RotaxMonitor/src/tasks.h | 8 +- RotaxMonitor/src/utils.cpp | 30 ++-- 7 files changed, 199 insertions(+), 156 deletions(-) diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.cpp b/RotaxMonitor/lib/ADS1256/ADS1256.cpp index 13ab8e1..8580685 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.cpp +++ b/RotaxMonitor/lib/ADS1256/ADS1256.cpp @@ -14,10 +14,11 @@ #include "Arduino.h" #include "ADS1256.h" #include "SPI.h" +#include #define convertSigned24BitToLong(value) ((value) & (1l << 23) ? (value) - 0x1000000 : value) -void drdyCallback(void *arg) +void IRAM_ATTR drdyCallback(void *arg) { auto cls = (ADS1256 *)arg; if (!arg) @@ -61,11 +62,16 @@ ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYN updateConversionParameter(); - m_drdyHigh = xSemaphoreCreateBinary(); - m_drdyLow = xSemaphoreCreateBinary(); - xSemaphoreGive(m_drdyHigh); - xSemaphoreGive(m_drdyLow); - attachInterruptArg(DRDY_pin, drdyCallback, (void *)this, CHANGE); + // m_drdyHigh = xSemaphoreCreateBinary(); + // m_drdyLow = xSemaphoreCreateBinary(); + // if (!m_drdyHigh || !m_drdyLow) { + // LOG_ERROR("ADC Unable to create interrupt semaphores"); + // return; + // } + + // xSemaphoreGive(m_drdyHigh); + // xSemaphoreGive(m_drdyLow); + //attachInterruptArg(DRDY_pin, drdyCallback, (void *)this, CHANGE); } // Initialization @@ -119,14 +125,16 @@ void ADS1256::InitializeADC() void ADS1256::waitForLowDRDY() { - xSemaphoreTake(m_drdyLow, pdMS_TO_TICKS(10)); - xSemaphoreGive(m_drdyLow); + while(digitalRead(m_DRDY_pin) == HIGH) {vTaskDelay(1);}; + // xSemaphoreTake(m_drdyLow, pdMS_TO_TICKS(10)); + // xSemaphoreGive(m_drdyLow); } void ADS1256::waitForHighDRDY() { - xSemaphoreTake(m_drdyHigh, pdMS_TO_TICKS(10)); - xSemaphoreGive(m_drdyHigh); + while(digitalRead(m_DRDY_pin) == LOW) {vTaskDelay(1);}; + // xSemaphoreTake(m_drdyHigh, pdMS_TO_TICKS(10)); + // xSemaphoreGive(m_drdyHigh); } void ADS1256::stopConversion() // Sending SDATAC to stop the continuous conversion diff --git a/RotaxMonitor/platformio.ini b/RotaxMonitor/platformio.ini index b43c9e2..c07cdb2 100644 --- a/RotaxMonitor/platformio.ini +++ b/RotaxMonitor/platformio.ini @@ -20,7 +20,6 @@ lib_deps = hideakitai/PCA95x5@^0.1.3 me-no-dev/AsyncTCP@^3.3.2 me-no-dev/ESPAsyncWebServer@^3.6.0 - adafruit/Adafruit NeoPixel@^1.15.4 upload_protocol = esptool upload_port = /dev/ttyACM1 upload_speed = 921600 @@ -28,15 +27,14 @@ monitor_port = /dev/ttyACM0 monitor_speed = 921600 build_type = release build_flags = - -DCORE_DEBUG_LEVEL=5 + -DCORE_DEBUG_LEVEL=3 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 -DCONFIG_ASYNC_TCP_PRIORITY=21 - -DCONFIG_ASYNC_TCP_QUEUE_SIZE=64 + -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 -DCONFIG_ASYNC_TCP_RUNNING_CORE=1 - -DCONFIG_ASYNC_TCP_STACK_SIZE=4096 - -fstack-protector-all + -DCONFIG_ASYNC_TCP_STACK_SIZE=8192 [env:esp32-s3-devkitc1-n16r8-debug] board = ${env:esp32-s3-devkitc1-n16r8.board} @@ -46,7 +44,6 @@ platform = ${env:esp32-s3-devkitc1-n16r8.platform} framework = ${env:esp32-s3-devkitc1-n16r8.framework} lib_deps = ${env:esp32-s3-devkitc1-n16r8.lib_deps} - adafruit/Adafruit NeoPixel@^1.15.4 upload_protocol = esptool upload_port = /dev/ttyACM1 upload_speed = 921600 @@ -59,7 +56,7 @@ build_flags = -O0 -g3 -ggdb3 - -DCORE_DEBUG_LEVEL=5 + -DCORE_DEBUG_LEVEL=3 -DARDUINO_USB_CDC_ON_BOOT=0 -DARDUINO_USB_MODE=0 -DCONFIG_ASYNC_TCP_MAX_ACK_TIME=5000 @@ -67,4 +64,3 @@ build_flags = -DCONFIG_ASYNC_TCP_QUEUE_SIZE=128 -DCONFIG_ASYNC_TCP_RUNNING_CORE=1 -DCONFIG_ASYNC_TCP_STACK_SIZE=8192 - -fstack-protector-all diff --git a/RotaxMonitor/src/devices.h b/RotaxMonitor/src/devices.h index 5ee2125..4a2c52a 100644 --- a/RotaxMonitor/src/devices.h +++ b/RotaxMonitor/src/devices.h @@ -26,9 +26,9 @@ struct Devices { // Busses - std::unique_ptr m_i2c = nullptr; - std::unique_ptr m_spi_a = nullptr; - std::unique_ptr m_spi_b = nullptr; + TwoWire *m_i2c = NULL; + SPIClass *m_spi_a = NULL; + SPIClass *m_spi_b = NULL; // Bus Mutextes std::mutex m_spi_a_mutex; @@ -36,13 +36,13 @@ struct Devices std::mutex m_i2c_mutex; // Device Pointers - std::unique_ptr m_pot_a = nullptr; - std::unique_ptr m_pot_b = nullptr; + AD5292 *m_pot_a = NULL; + AD5292 *m_pot_b = NULL; - std::unique_ptr m_adc_a = nullptr; - std::unique_ptr m_adc_b = nullptr; + ADS1256 *m_adc_a = NULL; + ADS1256 *m_adc_b = NULL; - std::unique_ptr m_ext_io = nullptr; + ExternalIO *m_ext_io = NULL; }; // Adc read channel wrapper to selet mux before reading diff --git a/RotaxMonitor/src/main.cpp b/RotaxMonitor/src/main.cpp index 0b04eeb..565bec9 100644 --- a/RotaxMonitor/src/main.cpp +++ b/RotaxMonitor/src/main.cpp @@ -16,20 +16,24 @@ #include #include -// Defines to enable channel B +#define CH_A_ENABLE #define CH_B_ENABLE +#define CH_A_RT_ENABLE +#define CH_B_RT_ENABLE +// #define I2C_ENABLE +// #define WEB_ENABLE // Debug Defines #define WIFI_SSID "AstroRotaxMonitor" #define WIFI_PASSWORD "maledettirotax" -#define PSRAM_MAX 4096 -#define QUEUE_MAX 256 +#define PSRAM_MAX 1024 +#define QUEUE_MAX 32 void setup() { Serial.begin(115200); delay(250); - Serial.setTimeout(30000); + Serial.setTimeout(5000); // Setup Logger LOG_ATTACH_SERIAL(Serial); @@ -47,28 +51,30 @@ void setup() LOG_DEBUG("ESP32 Heap:", ESP.getHeapSize()); LOG_DEBUG("ESP32 Sketch:", ESP.getFreeSketchSpace()); - // Init Wifi station - // LOG_INFO("Initializing WiFi..."); - // WiFi.mode(WIFI_AP); - // IPAddress local_IP(10, 11, 12, 1); - // IPAddress gateway(10, 11, 12, 1); - // IPAddress subnet(255, 255, 255, 0); - // WiFi.softAPConfig(local_IP, gateway, subnet); - // WiFi.setTxPower(WIFI_POWER_5dBm); // reduce wifi power - // if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD)) - // { - // LOG_INFO("WiFi AP Mode Started"); - // LOG_INFO("Wifi SSID:", WIFI_SSID); - // LOG_INFO("Wifi Password:", WIFI_PASSWORD); - // LOG_INFO("WiFi IP:" + WiFi.softAPIP().toString()); - // } - // else - // { - // LOG_ERROR("Failed to start WiFi AP Mode"); - // LOG_ERROR("5 seconds to restart..."); - // vTaskDelay(pdMS_TO_TICKS(5000)); - // esp_restart(); - // } +// Init Wifi station +#ifdef WEB_ENABLE + LOG_INFO("Initializing WiFi..."); + WiFi.mode(WIFI_AP); + IPAddress local_IP(10, 11, 12, 1); + IPAddress gateway(10, 11, 12, 1); + IPAddress subnet(255, 255, 255, 0); + WiFi.softAPConfig(local_IP, gateway, subnet); + WiFi.setTxPower(WIFI_POWER_5dBm); // reduce wifi power + if (WiFi.softAP(WIFI_SSID, WIFI_PASSWORD)) + { + LOG_INFO("WiFi AP Mode Started"); + LOG_INFO("Wifi SSID:", WIFI_SSID); + LOG_INFO("Wifi Password:", WIFI_PASSWORD); + LOG_INFO("WiFi IP:" + WiFi.softAPIP().toString()); + } + else + { + LOG_ERROR("Failed to start WiFi AP Mode"); + LOG_ERROR("5 seconds to restart..."); + vTaskDelay(pdMS_TO_TICKS(5000)); + esp_restart(); + } +#endif // Initialize Interrupt pins on PICKUP detectors initTriggerPinsInputs(); @@ -84,7 +90,7 @@ void loop() led.setBrightness(0.025f); led.setStatus(RGBled::LedStatus::INIT); - std::shared_ptr dev = std::make_shared(); + Devices dev; bool running = true; std::mutex fs_mutex; LITTLEFSGuard fsGuard; @@ -94,34 +100,40 @@ void loop() bool spiB_ok = true; //////// INIT SPI INTERFACES //////// LOG_DEBUG("Init SPI Interfaces"); - SPIClass SPI_A(FSPI); +#ifdef CH_A_ENABLE + LOG_DEBUG("Begin Init SPI_A"); + SPIClass SPI_A(HSPI); spiA_ok = SPI_A.begin(SPI_A_SCK, SPI_A_MISO, SPI_A_MOSI); SPI_A.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 - LOG_DEBUG("Init SPI A ok"); - Serial.readStringUntil('\n'); - dev->m_spi_a.reset(&SPI_A); - dev->m_adc_a = std::make_unique(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); - dev->m_adc_a->InitializeADC(); - dev->m_adc_a->setPGA(PGA_1); - dev->m_adc_a->setDRATE(DRATE_7500SPS); - LOG_DEBUG("Init ADC A ok"); - Serial.readStringUntil('\n'); - - delay(250); - - #ifdef CH_B_ENABLE - SPIClass SPI_B(HSPI); + LOG_DEBUG("Init SPI_A -> OK"); + delay(500); + LOG_DEBUG("Begin Init ADC_A"); + ADS1256 ADC_A(ADC_A_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_A_CS, 2.5, &SPI_A); + ADC_A.InitializeADC(); + ADC_A.setPGA(PGA_1); + ADC_A.setDRATE(DRATE_7500SPS); + dev.m_adc_a = &ADC_A; + dev.m_spi_a = &SPI_A; + LOG_DEBUG("Init ADC_A -> OK"); + delay(1000); +#endif + +#ifdef CH_B_ENABLE + LOG_DEBUG("Begin Init SPI_B"); + SPIClass SPI_B(FSPI); spiB_ok = SPI_B.begin(SPI_B_SCK, SPI_B_MISO, SPI_B_MOSI); SPI_B.setDataMode(SPI_MODE1); // ADS1256 requires SPI mode 1 - LOG_DEBUG("Init SPI B ok"); - Serial.readStringUntil('\n'); - dev->m_spi_b.reset(&SPI_B); - dev->m_adc_b = std::make_unique(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); - dev->m_adc_b->InitializeADC(); - dev->m_adc_b->setPGA(PGA_1); - dev->m_adc_b->setDRATE(DRATE_7500SPS); - LOG_DEBUG("Init ADC B ok"); - Serial.readStringUntil('\n'); + LOG_DEBUG("Init SPI_B -> OK"); + delay(500); + LOG_DEBUG("Begin Init ADC_B"); + ADS1256 ADC_B(ADC_B_DRDY, ADS1256::PIN_UNUSED, ADS1256::PIN_UNUSED, ADC_B_CS, 2.5, &SPI_B); + ADC_B.InitializeADC(); + ADC_B.setPGA(PGA_1); + ADC_B.setDRATE(DRATE_7500SPS); + dev.m_adc_b = &ADC_B; + dev.m_spi_b = &SPI_B; + LOG_DEBUG("Init ADC_B -> OK"); + delay(1000); #endif if (!spiA_ok || !spiB_ok) @@ -132,27 +144,29 @@ void loop() esp_restart(); } - LOG_DEBUG("Init SPI OK"); + LOG_DEBUG("Init SPI -> OK"); + +//////// INIT I2C INTERFACES //////// +#ifdef I2C_ENABLE + LOG_DEBUG("Init I2C Interfaces"); + bool i2c_ok = true; + i2c_ok = Wire.begin(SDA, SCL, 100000); + if (!i2c_ok) + { + LOG_ERROR("Unable to Initialize I2C Bus"); + LOG_ERROR("5 seconds to restart..."); + vTaskDelay(pdMS_TO_TICKS(5000)); + esp_restart(); + } + LOG_DEBUG("Init I2c ok"); Serial.readStringUntil('\n'); - //////// INIT I2C INTERFACES //////// - // LOG_DEBUG("Init I2C Interfaces"); - // bool i2c_ok = true; - // i2c_ok = Wire.begin(SDA, SCL, 100000); - // if (!i2c_ok) - // { - // LOG_ERROR("Unable to Initialize I2C Bus"); - // LOG_ERROR("5 seconds to restart..."); - // vTaskDelay(pdMS_TO_TICKS(5000)); - // esp_restart(); - // } - // LOG_DEBUG("Init I2c ok"); - // Serial.readStringUntil('\n'); - // Init IO Expanders - // dev->m_ext_io = std::make_unique(Wire, dev->m_i2c_mutex, EXPANDER_ALL_INTERRUPT); + dev->m_ext_io = std::make_unique(Wire, dev->m_i2c_mutex, EXPANDER_ALL_INTERRUPT); +#endif - //////// INIT REALTIME TASKS PARAMETERS //////// +//////// INIT REALTIME TASKS PARAMETERS //////// +#ifdef CH_A_RT_ENABLE const rtIgnitionTask::rtTaskParams taskA_params{ .rt_running = true, .name = "rtIgnTask_A", @@ -182,8 +196,9 @@ void loop() .relay_out_34 = RELAY_OUT_A34, }, .rt_queue = nullptr, - .dev = dev}; - + .dev = &dev}; +#endif +#ifdef CH_B_RT_ENABLE const rtIgnitionTask::rtTaskParams taskB_params{ .rt_running = true, .name = "rtIgnTask_B", @@ -213,18 +228,30 @@ void loop() .relay_out_34 = RELAY_OUT_B34, }, .rt_queue = nullptr, - .dev = dev}; + .dev = &dev}; +#endif //////// SPAWN REALTIME TASKS //////// - auto task_A = rtIgnitionTask(taskA_params, PSRAM_MAX, QUEUE_MAX, CORE_0, fs_mutex); - delay(50); - Serial.readStringUntil('\n'); + bool tasK_A_rt = true; + bool task_B_rt = true; + BaseType_t ignA_task_success = pdPASS; + BaseType_t ignB_task_success = pdPASS; + +#ifdef CH_A_RT_ENABLE + auto task_A = rtIgnitionTask(taskA_params, PSRAM_MAX, QUEUE_MAX, CORE_1, fs_mutex); + ignA_task_success = task_A.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL; + //tasK_A_rt = task_A.start(); + delay(1000); +#endif + +#ifdef CH_B_RT_ENABLE auto task_B = rtIgnitionTask(taskB_params, PSRAM_MAX, QUEUE_MAX, CORE_1, fs_mutex); - Serial.readStringUntil('\n'); + ignB_task_success = task_B.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL; + //task_B_rt = task_B.start(); + delay(1000); +#endif // Ignition A on Core 0 - auto ignA_task_success = task_A.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL; - auto ignB_task_success = task_B.getStatus() == rtIgnitionTask::OK ? pdPASS : pdFAIL; if (ignA_task_success != pdPASS || ignB_task_success != pdPASS) { LOG_ERROR("Unable to initialize ISR task"); @@ -232,10 +259,6 @@ void loop() vTaskDelay(pdMS_TO_TICKS(5000)); esp_restart(); } - - const bool tasK_A_rt = task_A.start(); - delay(50); - const bool task_B_rt = task_B.start(); if (tasK_A_rt != true || task_B_rt != true) { led.setStatus(RGBled::LedStatus::ERROR); @@ -248,18 +271,23 @@ void loop() } //////// SPAWN WEBSERVER and WEBSOCKET //////// - AstroWebServer webPage(80, LittleFS); ArduinoJson::JsonDocument json_data; - bool data_a, data_b; + bool data_a = false, data_b = false; +#ifdef WEB_ENABLE + AstroWebServer webPage(80, LittleFS); + delay(1000); task_A.onMessage([&webPage, &json_data, &data_a](ignitionBoxStatusFiltered sts) { - json_data["box_a"] = sts.toJson(); - data_a = true; }); + json_data["box_a"] = sts.toJson(); + data_a = true; }); + #ifdef CH_B_RT_ENABLE task_B.onMessage([&webPage, &json_data, &data_b](ignitionBoxStatusFiltered sts) { - json_data["box_b"] = sts.toJson(); - data_b = true; }); + json_data["box_b"] = sts.toJson(); + data_b = true; }); + #endif +#endif // task_A.enableSave(true, "ignitionA_test.csv"); // task_B.enableSave(true, "ignitionB_test.csv"); @@ -270,12 +298,14 @@ void loop() while (running) { uint32_t this_loop = millis(); - if (this_loop - monitor_loop > 2000) + if (this_loop - monitor_loop > 5000) { clearScreen(); printRunningTasksMod(Serial); monitor_loop = millis(); } + vTaskDelay(pdMS_TO_TICKS(10)); +#ifdef WEB_ENABLE if ((data_a && data_b) || (this_loop - data_loop > 500)) { webPage.sendWsData(json_data.as()); @@ -283,6 +313,7 @@ void loop() data_a = data_b = false; data_loop = millis(); } +#endif } //////////////// INNER LOOP ///////////////////// } ////////////////////// MAIN LOOP ////////////////////// diff --git a/RotaxMonitor/src/tasks.cpp b/RotaxMonitor/src/tasks.cpp index e23df0c..a5b6b92 100644 --- a/RotaxMonitor/src/tasks.cpp +++ b/RotaxMonitor/src/tasks.cpp @@ -16,9 +16,16 @@ void spark_timeout_callback(void *arg) void rtIgnitionTask::rtIgnitionTask_manager(void *pvParameters) { rtIgnitionTask *cls = (rtIgnitionTask *)pvParameters; + auto last_loop = millis(); + uint32_t count(0); while (cls->m_running) { cls->run(); + // if (millis() - last_loop > 2000) { + // LOG_DEBUG("TASK [", cls->m_name.c_str(), "] Alive -", count++); + // last_loop = millis(); + // } + vTaskDelay(pdMS_TO_TICKS(1)); } } @@ -38,10 +45,12 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) const rtTaskInterruptParams rt_int = params->rt_int; // copy to avoid external override const rtTaskIOParams rt_rst = params->rt_io; // copy to avoid external override QueueHandle_t rt_queue = params->rt_queue; - Devices *dev = params->dev.get(); - ADS1256 *adc = params->name == "rtIgnTask_A" ? dev->m_adc_a.get() : dev->m_adc_b.get(); - std::mutex &spi_mutex = params->name == "rtIgnTask_A" ? dev->m_spi_a_mutex : dev->m_spi_b_mutex; - ExternalIO *io = dev->m_ext_io.get(); + Devices *dev = params->dev; + ExternalIO *io = dev->m_ext_io; + // ADS1256 *adc = params->name == "rtIgnTask_A" ? dev->m_adc_a : dev->m_adc_b; + ADS1256 *adc = NULL; + // std::mutex &spi_mutex = params->name == "rtIgnTask_A" ? dev->m_spi_a_mutex : dev->m_spi_b_mutex; + std::mutex spi_mutex; TaskStatus_t rt_task_info; vTaskGetInfo(NULL, &rt_task_info, pdFALSE, eInvalid); @@ -76,10 +85,6 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) .ign_stat = &ign_box_sts, .rt_handle_ptr = rt_task_info.xHandle}; - LOG_DEBUG("rtTask HDL Params OK, HDL* [", (uint32_t)rt_task_info.xHandle, "]"); - LOG_DEBUG("rtTask ISR Params OK, ISR* [", (uint32_t)rt_int.isr_ptr, "]"); - LOG_DEBUG("rtTask QUE Params OK, QUE* [", (uint32_t)rt_queue, "]"); - // Create esp_timer for microsecond precision timeout esp_timer_handle_t timeout_timer; esp_timer_create_args_t timer_args = { @@ -87,7 +92,11 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) .arg = (void *)rt_task_info.xHandle, .dispatch_method = ESP_TIMER_TASK, .name = "spark_timeout"}; - esp_timer_create(&timer_args, &timeout_timer); + if (esp_timer_create(&timer_args, &timeout_timer) != ESP_OK) + { + LOG_INFO("rtTask [", params->name.c_str(), "] Fail to allocate timeoutTimer"); + vTaskDelete(NULL); + } // Attach Pin Interrupts attachInterruptArg(digitalPinToInterrupt(rt_int.trig_pin_12p), rt_int.isr_ptr, (void *)&isr_params_t12p, RISING); @@ -242,10 +251,10 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) ign_box_sts.coils12.peak_n_in = adc->convertToVoltage(adc->cycleSingle()); ign_box_sts.coils34.peak_p_in = adc->convertToVoltage(adc->cycleSingle()); ign_box_sts.coils34.peak_n_in = adc->convertToVoltage(adc->cycleSingle()); - ign_box_sts.coils12.peak_p_out =adc->convertToVoltage(adc->cycleSingle()); - ign_box_sts.coils12.peak_n_out =adc->convertToVoltage(adc->cycleSingle()); - ign_box_sts.coils34.peak_p_out =adc->convertToVoltage(adc->cycleSingle()); - ign_box_sts.coils34.peak_n_out =adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils12.peak_p_out = adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils12.peak_n_out = adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils34.peak_p_out = adc->convertToVoltage(adc->cycleSingle()); + ign_box_sts.coils34.peak_n_out = adc->convertToVoltage(adc->cycleSingle()); ign_box_sts.adc_read_time = (int32_t)(esp_timer_get_time() - start_adc_read); adc->stopConversion(); } @@ -300,6 +309,7 @@ void rtIgnitionTask::rtIgnitionTask_realtime(void *pvParameters) ///////////// CLASS MEMBER DEFINITIONS ///////////// rtIgnitionTask::rtIgnitionTask(const rtTaskParams params, const uint32_t history_size, const uint32_t queue_size, const uint8_t core, std::mutex &fs_mutex, fs::FS &filesystem) : m_params(params), m_filesystem(filesystem), m_fs_mutex(fs_mutex), m_core(core), m_max_history(history_size) { + LOG_WARN("Starting Manager for [", m_params.name.c_str(), "]"); // create queue buffers m_queue = xQueueCreate(queue_size, sizeof(ignitionBoxStatus)); if (!m_queue) @@ -318,12 +328,12 @@ rtIgnitionTask::rtIgnitionTask(const rtTaskParams params, const uint32_t history m_active_history = std::unique_ptr(&m_history_0); m_save_history = std::unique_ptr(&m_history_1); - LOG_WARN("Starting Manager for [", m_params.name.c_str(), "]"); + m_name = (std::string("man_") + m_params.name).c_str(); // auto task_success = pdPASS; auto task_success = xTaskCreatePinnedToCore( rtIgnitionTask_manager, - (std::string("man_") + m_params.name).c_str(), - 8192, + m_name.c_str(), + RT_TASK_STACK, (void *)this, m_params.rt_priority >> 2, &m_manager_handle, @@ -362,14 +372,15 @@ void rtIgnitionTask::run() m_last_data = millis(); m_manager_status = rtTaskStatus::RUNNING; // if history buffer is full swap buffers and if enabled save history buffer - if (m_counter_status >= m_active_history->size()) + if (m_counter_status >= m_max_history) { LOG_DEBUG("Save for Buffer Full: ", m_counter_status); m_counter_status = 0; m_partial_save = false; // reset partial save flag on new data cycle std::swap(m_active_history, m_save_history); if (m_enable_save) - saveHistory(*m_save_history, m_history_path); // directly call the save task function to save without delay + // saveHistory(m_save_history, m_history_path); // directly call the save task function to save without delay + LOG_INFO("Save History"); } // update filtered data @@ -391,15 +402,14 @@ void rtIgnitionTask::run() if (m_counter_status > 0 && !m_partial_save) { LOG_DEBUG("Save Partial: ", m_counter_status); - m_active_history->resize(m_counter_status); - saveHistory(*m_active_history, m_history_path); - m_active_history->resize(m_max_history); + // m_active_history->resize(m_counter_status); + // saveHistory(m_active_history, m_history_path); + // m_active_history->resize(m_max_history); m_counter_status = 0; m_partial_save = true; } m_manager_status = rtTaskStatus::IDLE; } - delay(5); // yeld to another task } } diff --git a/RotaxMonitor/src/tasks.h b/RotaxMonitor/src/tasks.h index e5feb9e..04f0af8 100644 --- a/RotaxMonitor/src/tasks.h +++ b/RotaxMonitor/src/tasks.h @@ -41,6 +41,7 @@ static const std::map names = { class rtIgnitionTask { using PSHistory = PSRAMVector; + // using PSHistory = std::vector; public: // RT task Interrupt parameters @@ -84,7 +85,7 @@ public: const rtTaskInterruptParams rt_int; // interrupt pins to attach const rtTaskIOParams rt_io; // reset ping for peak detectors QueueHandle_t rt_queue; // queue for task io - const std::shared_ptr dev; + Devices *dev; }; enum rtTaskStatus @@ -124,6 +125,7 @@ private: // static functions for FreeRTOS private: bool m_running = true; rtTaskStatus m_manager_status = INIT; + std::string m_name; rtTaskParams m_params; const uint8_t m_core; @@ -154,6 +156,6 @@ private: static const uint32_t c_idle_time = 10000; // in mS static const uint32_t c_spark_timeout_max = 500; // uS - static const uint8_t c_adc_time = 4; // in mS - static const uint8_t c_io_time = 2; // in mS + static const uint8_t c_adc_time = 4; // in mS + static const uint8_t c_io_time = 2; // in mS }; diff --git a/RotaxMonitor/src/utils.cpp b/RotaxMonitor/src/utils.cpp index 46951fd..0474abc 100644 --- a/RotaxMonitor/src/utils.cpp +++ b/RotaxMonitor/src/utils.cpp @@ -7,7 +7,7 @@ #include "esp_heap_caps.h" #include "esp_system.h" -#include "esp_spi_flash.h" +#include "spi_flash_mmap.h" #include "esp_partition.h" #include "LittleFS.h" @@ -49,23 +49,27 @@ void printBar(Print &printer, const char *label, size_t used, size_t total, cons { float perc = total > 0 ? ((float)used / total) : 0; int filled = perc * BAR_WIDTH; + char str[256] = {0}; + uint16_t k(0); - printer.printf("%s%-12s [" COLOR_RESET, color, label); + k += sprintf(str, "%s%-12s [" COLOR_RESET, color, label); for (int i = 0; i < BAR_WIDTH; i++) { if (i < filled) - printer.printf("%s#%s", color, COLOR_RESET); + k += sprintf(&str[k], "%s#%s", color, COLOR_RESET); else - printer.printf("-"); + k += sprintf(&str[k], "-"); } - printer.printf("] %s%6.2f%%%s (%5.3f/%5.3f)MB\n", + sprintf(&str[k], "] %s%6.2f%%%s (%5.3f/%5.3f)MB\n", color, perc * 100.0, COLOR_RESET, (used / 1024.0f / 1024.0f), (total / 1024.0f / 1024.0f)); + + printer.println(str); } void printRunningTasksMod(Print &printer, std::function orderBy) @@ -95,6 +99,7 @@ void printRunningTasksMod(Print &printer, std::function 0 ? ulCurrentRunTime : 1; ulLastRunTime = ulTotalRunTime; // PRINT MEMORY INFO @@ -134,17 +139,6 @@ void printRunningTasksMod(Print &printer, std::functionsize; // dimensione reale partizione - size_t sketchSize = ESP.getSketchSize(); - printBar(printer, "FLASH APP", sketchSize, totalAPP, COLOR_CYAN); - } - else - { - printer.printf(COLOR_YELLOW "%-12s [NOT FOUND]\n" COLOR_RESET, "FLASH APP"); - } - // ===== LITTLEFS (corretto con partition table) ===== const esp_partition_t *fs_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, @@ -164,7 +158,9 @@ void printRunningTasksMod(Print &printer, std::function