commit d938069aa6bdbbc14ce64d250afe32f928638ffe Author: eulaly Date: Mon Apr 20 13:09:27 2026 -0400 initial commit diff --git a/aitrip-inmp441-amazon.jpg b/aitrip-inmp441-amazon.jpg new file mode 100644 index 0000000..14ae4eb Binary files /dev/null and b/aitrip-inmp441-amazon.jpg differ diff --git a/esp32 pinout.png b/esp32 pinout.png new file mode 100644 index 0000000..e467edb Binary files /dev/null and b/esp32 pinout.png differ diff --git a/esp32-pinout-devkitv1.png b/esp32-pinout-devkitv1.png new file mode 100644 index 0000000..de4227a Binary files /dev/null and b/esp32-pinout-devkitv1.png differ diff --git a/esp32-wroom-32e_esp32-wroom-32ue_datasheet_en.pdf b/esp32-wroom-32e_esp32-wroom-32ue_datasheet_en.pdf new file mode 100644 index 0000000..c97108c Binary files /dev/null and b/esp32-wroom-32e_esp32-wroom-32ue_datasheet_en.pdf differ diff --git a/inmp441-datasheet.pdf b/inmp441-datasheet.pdf new file mode 100644 index 0000000..914fdbf Binary files /dev/null and b/inmp441-datasheet.pdf differ diff --git a/mic/mic.ino b/mic/mic.ino new file mode 100644 index 0000000..f54b3cf --- /dev/null +++ b/mic/mic.ino @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 8000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; +const float MIC_GAIN = 4.0f; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 500; + +const int I2S_WS = 25; +const int I2S_SCK = 22; +const int I2S_SD = 21; + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; // timer + static unsigned long last_touch_check = 0; // timer + static bool last_touch_state = false; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // frame buffer + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + int32_t mic_buf[FRAME_SIZE]; + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + + if (bytes_read != sizeof(mic_buf)) { + memset(samples, 0, sizeof(samples)); + } else { + for (int i = 0; i < FRAME_SIZE; i++) { + float y = (mic_buf[i] >> 16) * MIC_GAIN; //gain + if (y > 32767.0f) y = 32767.0f; + if (y < -32768.0f) y = -32768.0f; + samples[i] = (int16_t)y; + } + } + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} diff --git a/mic/mic.ino~ b/mic/mic.ino~ new file mode 100644 index 0000000..8ee7b2c --- /dev/null +++ b/mic/mic.ino~ @@ -0,0 +1,183 @@ +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 22; // lrcl / ws +const int I2S_SCK = 26; // bclk +const int I2S_SD = 21; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup() { + Serial.begin(115200); + + // init touch + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + // init i2s for adc sampling + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN), + .sample_rate = OUTPUT_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_MSB, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 128, + .use_apll = false + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_0); // gpio36 + i2s_adc_enable(I2S_NUM_0); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; + static unsigned long last_touch_check = 0; + static bool last_touch_state = false; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("switched to %s mode\n", tone_mode ? "tone" : "mic"); + delay(200); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + // read from i2s adc buffer - need multiple reads to fill frame + static float dc_filter = 2048.0; // dc offset removal filter + int samples_filled = 0; + + while (samples_filled < FRAME_SIZE) { + size_t bytes_read; + uint16_t i2s_buffer[64]; // bigger buffer + i2s_read(I2S_NUM_0, i2s_buffer, 128, &bytes_read, 10); + + int samples_read = bytes_read / 2; // 2 bytes per sample + for (int i = 0; i < samples_read && samples_filled < FRAME_SIZE; i++) { + // i2s adc gives 12-bit data in upper bits of 16-bit word + int adc_val = (i2s_buffer[i] >> 4) & 0x0FFF; + + // dc offset removal with simple iir filter + dc_filter = dc_filter * 0.999 + adc_val * 0.001; + + // scale and store + samples[samples_filled] = (int16_t)((adc_val - dc_filter) * 16); + samples_filled++; + } + } + } + + // ΅-law encode + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + // build rtp header + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + // send packet + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} diff --git a/plink.log b/plink.log new file mode 100644 index 0000000..d14e689 Binary files /dev/null and b/plink.log differ diff --git a/vtech.lnk b/vtech.lnk new file mode 100644 index 0000000..4b080a7 Binary files /dev/null and b/vtech.lnk differ diff --git a/vtech.org b/vtech.org new file mode 100644 index 0000000..0d079bf --- /dev/null +++ b/vtech.org @@ -0,0 +1,18626 @@ +C:\Users\moses\Documents\Arduino\ +migrated from notes.org [2026-04-19 Sun] +* ESP32-DEVKIT-V1 +** diagram + ----------------- + EN | |_|Μ… |_|Μ… |_|Μ… |_| | D23 + VP | | D22 GPIO22 I2C_SCL + VN | β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” | TX0 UART + D34 | β”‚ β”‚ | RXO UART + D35 | β”‚ β”‚ | D21 GPIO21 I2C_SDA + D32 | β”‚ β”‚ | D19 +GPIO33 D33 | β”‚ β”‚ | D18 +GPIO25 D25 | β”‚ β”‚ | D5 +GPIO26 D26 | β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ | TX2 + D27 | | RX2 + D14 | | D4 + D12 | | D2 + D13 | | D15 + GND | | GND + VN | | 3V3 + | | + ----------------- + en usb boot + +** pinlist +EN,VP,VN,D34,D35,D32,D33,D25,D26,D27,D14,D12,D13,GND,VN,3V3,GND,D15,D2,D4,RX2,TX2,D5,D18,D19,D21,RX0,TX0,D22,D23 +** vertical pins +EN +VP +VN +D34 +D35 +D32 +D33 +D25 +D26 +D27 +D14 +D12 +D13 +GND +VN + +3V3 +GND +D15 +D2 +D4 +RX2 +TX2 +D5 +D18 +D19 +D21 +RX0 +TX0 +D22 +D23 + + + +* Instructions +Plug-in ESP32 to PC +Launch arduino IDE - load "ESP32 Dev Module" +Upload sketch, will parse/compile/upload +paladin defaults to COM3 (recall this workin in emacs but i forget) +~plink -serial COM3 -sercfg 115200 | tee-object -FilePath "plink.log"~ +~plink -serial COM3 -sercfg 115200 | tee-object -FilePath "plink.log"~ + +* Project Expl +#+DATE: [2026-04-20 Mon] +intake raw sample words +clock in, chop into frames +convert sample rate/format +wrap in rtp/udp +send on schedule + + + +* === Running notes === +* esp32 + vtech baby monitor [2025-07-27 Sun] +tap speaker to gpio36 +need to power (vtech is 6V) +esp32wroom vreg is 11 17c / 33 d323; it shoudl be able to take 6v ok +consider adding a button to turn on/off the esp32 +then add voltage divider bt +* baby monitor [2025-09-03 Wed] +this baby monitor (vtech dm221-2) runs at 6V DC, i want to tap a 3V or 5V pin to run an esp32 so i can tap the speaker on an ADC and broadcast it over wifi. here's a pic of the board - i tested some pads and components: + +SOT23-3 package: (1pin on top, two on bottom), commong for transistors, diodes, vreg + +Q1 lone pin is 3.7V +Q6 bottom pins are 3.17V (L) and 3.6V (R) +TP20: 3.17V +TP12: 3.17V +TP21: 3.77V + +i might be able to tap an LED? but those are more likely to be current limited right + +- look for 3-pin regulators (SOT23) - middle pin is usually output +- check caps near the main processor - usually fed by the clean 3.3V rail +- that U401 chip in the upper section might be a regulator too + + + also maybe add a small decoupling cap (10uF) close to your tap point bc esp32s are kinda noisy when they boot + + +https://randomnerdtutorials.com/esp32-pinout-reference-gpios/ + + +https://discord.com/api/webhooks/1411806429576429799/zRFcDio3B_BSxFQ8Rus2gMrJhkpC6olXCGgdZ71L3_7zAxsm2Cy86VBynUxcPNfwq4Xg + +** wireshark packets +https://support.adder.com/tiki/tiki-index.php?page=Network%3A+Using+Wireshark+to+check+if+IGMP+is+configured + +- start collection on Ethernet3 +- _Do NOT leave this running!!_ Collect and STOP to analyze +- DisplayFilter is not CaptureFilter; default is collect all and display some! + CaptureFilter syntax: https://wiki.wireshark.org/CaptureFilters#capture-filter-is-not-a-display-filter +- Create a CaptureFilter eg "src 192.168.1.145 and port 5004" +- DisplayFilter syntax eg "udp.port==5004 && ip.src==192.268.1.145" + +add filter: ip.dst==224.0.0.0/4 +IGMP should ounly show traffic to dest 239.255.x.x if someone's listening (me). + +- first few bytes are packet headers! src/dest. bottom left pane, see "Data (172 bytes)" and click, it will highlight the bytes on the right pane. THIS is where your datagram headers are. + +RTP headers: +byte 0: 0x80 (v=2, p=0, x=0, cc=0) +byte 1: 0x00 (m=0, pt=0 β†’ pcmu) +byte 2-3: sequence number (big endian) +byte 4-7: timestamp (big endian) +byte 8-11: ssrc (big endian, arbitrary) + +first packet might look like (seq=1,ts=0,ssrc=0x12345678): +80 00 00 01 00 00 00 00 12 34 56 78 + +** my first headers look like _WRONG! this was 0000, 0010, not 0000 0001_ +d8 43 ae 28 55 33 6c c8 00 c8 d3 df +after manual construction of headers: +d8 43 ae 28 55 33 6c c8 00 c8 b4 b4 + +should be +0x80 0x00 00 01 00 00 00 01 12 34 56 78 + +d8 43 ae 28 55 33 6c c8 40 8a bd 80 08 00 45 00 + +** sample - data begins on byte 6! +0000 d8 43 ae 28 55 33 6c c8 40 8a bd 80 08 00 45 00 +0010 00 c8 94 45 00 00 40 11 61 9a c0 a8 01 91 c0 a8 +0020 01 64 13 8c 13 8c 00 b4 2b 5b 80 00 94 43 00 fc +0030 a9 e0 12 34 56 78 ff ff ff ff ff ff ff ff ff ff +0040 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0050 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0060 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0070 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0080 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0090 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +00a0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +00b0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +00c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +00d0 ff ff ff ff ff ff ...... + +DOIT ESP32 DEVKIT V1 +Serial: baud 115200 + +htons() "host-to-network short" converts a short integer from host byte order to network byte order, swapping bytes if needed, for 16-bit values. + +htonl() "host-to-network long" converts u_long from host to TCP/IP network order (big-endian) + + +https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32/api-reference/peripherals/adc.html + +For ADC1, configure desired precision and attenuation by calling functions adc1_config_width() and adc1_config_channel_atten(). + + +PCM5102 I2S DAC board? + +8000d10f0122a96012345678a198929091969eb33f2319131011161e2fc7a599939091959dad4f261a131011151c2bdda89b949091949baaf92a1b141110141b285aac9c959190939aa6cd2e1d15111013192445b09e9691909398a2be341f1712101218213bb79f97929092979fb73b211 + +8000d1100122aa00123456781a264dae9d9591909399a4c5301e1611101318223eb49f9792909298a1bb371f17121012171f37bba198929091969eb33f2319131011161e2fc7a599939091959dad4f261a131011151c2bdda89b949091949baaf92a1b141110141b285aac9c959190939aa + +8000d1110122aaa012345678131011151d2dcfa69a939091959cab5d281b141011141b2a79aa9b949190949ba8da2c1c151110131a264dae9d9591909399a4c5301e1611101318223eb49f9792909298a1bb371f17121012171f37bba198929091969eb33f2319131011161e2fc7a599939 + +*** packet analysis +you lost me. I'm seeing these two bits increment per-packet in byte 6 (first two bits belong to UDP header/checksum): +[] [] 80 00 55 fe 00 35 +[] [] 80 00 55 ff 00 35 +[] [] 80 00 56 00 00 35 +[] [] 80 00 56 00 01 35 +this looks like bits 2-3 are simply incrementing per packet, which is exactly what our code says ("hdr->seq = htons(seq++)"), only q is whether that's correct? + +here's what i'm seeing in the serial out: +80 00 00 00 00 00 00 00 12 34 56 78 +80 00 00 01 00 00 00 a0 12 34 56 78 +80 00 00 02 00 00 01 40 12 34 56 78 +80 00 00 03 00 00 01 e0 12 34 56 78 +80 00 00 04 00 00 02 80 12 34 56 78 +80 00 00 05 00 00 03 20 12 34 56 78 +80 00 00 06 00 00 03 c0 12 34 56 78 +80 00 00 07 00 00 04 60 12 34 56 78 +80 00 00 08 00 00 05 00 12 34 56 78 + +another few lines from WS (obv not the same packets): +80 00 08 61 00 05 3c a0 12 34 56 78 +80 00 08 62 00 05 3d 40 12 34 56 78 +80 00 08 63 00 05 3d e0 12 34 56 78 + +** vlc sdp file - this never worked! +use rtp://192.168.1.100:5004 +** file +v=0 +o=- 0 0 IN IP4 192.168.1.100 +s=ESP32 Tone +c=IN IP4 192.168.1.100 +t=0 0 +m=audio 5004 RTP/AVP 0 +a=rtpmap:0 PCMU/8000 +a=sendonly + +* new notes vtech [2025-09-04 Thu] +tone2 - claude claude tone works! +check the ulaw function deeply, and packet vs payload formation - i dont see memcpy in the functioning tonegen code, just a raw feeding of the packet into the ulaw function, appending header, and firing it off? + +Checklist: +- first 12 bytes: 80 00 SS SS TT TT TT TT XX XX XX XX +- packet length: 12 + 160 = 172 bytes +- inter-packet gap: ~20 ms +- seq monotonic +1; ts monotonic +160; stable ssrc +- vlc opens via rtp://@:5004 or sdp with a=rtpmap:0 PCMU/8000 + +** working udp-tone2 claude +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.100"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz +const int FRAME_SIZE = 160; // 20ms frames +const float TONE_HZ = 440.0; + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup() { + Serial.begin(115200); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); +} + +float phase = 0; +const float phase_inc = 2.0 * M_PI * TONE_HZ / OUTPUT_RATE; + +void loop() { + static unsigned long last_send = 0; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + + // only send if it's time + unsigned long now = millis(); + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + // generate 20ms tone + for (int i=0; i 2*M_PI) phase -= 2*M_PI; + } + + // Β΅-law encode + for (int i=0; ivpxcc = 0x80; // v=2, p=0, x=0, cc=0 + hdr->mpt = 0x00; // m=0, pt=0 (PCMU) + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + // send packet + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} +** orig file to integrate +#include +// #include +#include +// #include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* MULTICAST_IP = "239.255.0.1"; +const char* DEST_IP = "192.168.1.100"; +const int UDP_PORT = 5004; +const int SAMPLE_RATE = 32000; +const int OUTPUT_RATE = 8000; +const int FRAME_SIZE = 160; +static bool blink = false; + +const i2s_port_t I2S_PORT = I2S_NUM_0; +const adc1_channel_t ADC_CHANNEL = ADC1_CHANNEL_0; //gpio36 + +char id_str[17]; +char status_id[32]; + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; + +// rtp header struct (minimal) +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +// Β΅-law encode +uint8_t linear2ulaw(int16_t pcm_val) { + const int BIAS = 0x84; + const int CLIP = 32635; + int mask, seg, uval; + pcm_val = pcm_val >> 2; // bitshift right 2^arg (2), unsure if this works? if pcm value is encoded + if (pcm_val < 0) { + pcm_val = -pcm_val; + mask = 0x7F; + } else mask = 0xFF; + if (pcm_val > CLIP) pcm_val = CLIP; + pcm_val += BIAS; + seg = 7; + for (int v = pcm_val; v > 0x3F; v >>= 1) seg--; + uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF); + return (uval ^ mask); +} + +void setup_i2s() { + i2s_config_t cfg = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN), + .sample_rate = SAMPLE_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_I2S_MSB, + .intr_alloc_flags = 0, + .dma_buf_count = 4, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = true + }; + i2s_driver_install(I2S_PORT, &cfg, 0, NULL); + i2s_set_adc_mode(ADC_UNIT_1, ADC_CHANNEL); + i2s_adc_enable(I2S_PORT); +} + +void setup() { + uint64_t chipid = ESP.getEfuseMac(); + snprintf(id_str, sizeof(id_str), "%04X", (uint16_t)(chipid >>32)); + + Serial.begin(115200); //begin serial connection for debugging + // delay(200); // pause for usb host + WiFi.begin(ssid, password); + Serial.printf("[wifi] "); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf(" connected %s with ip %s\n", id_str, WiFi.localIP().toString().c_str()); + + setup_i2s(); + Serial.printf("[udp] "); + if (udp.begin(UDP_PORT)) { + Serial.printf("listening on port %d\n", UDP_PORT); + } else { + Serial.println(" failed to bind\n"); + } +} + +void loop() { + int16_t samples[FRAME_SIZE*2]; // 320 samples @ 16kHz = 20ms; adc is tied to clock speed + size_t bytes_read; + i2s_read(I2S_PORT, (char*)samples, sizeof(samples), &bytes_read, portMAX_DELAY); + + if (bytes_read == 0) { Serial.println("[i2s] no samples read\n"); return; } + + uint8_t payload[FRAME_SIZE]; + for (int i=0;ivpxcc = 0x80; // v=2 + hdr->mpt = 0x00; // payload type 0 = PCMU + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + memcpy(packet+12, payload, FRAME_SIZE); + + if (udp.beginPacket(DEST_IP, UDP_PORT)) { + udp.write(packet, sizeof(packet)); + udp.endPacket(); + Serial.print("\r"); + Serial.print(blink ? '.' : ' '); + Serial.flush(); + blink = !blink; + }; + + ts += FRAME_SIZE; // 20ms worth of samples +} + +** compairson bt tonegen and original: +loop() ++ last_send, frame interval + +samples[ framesize] + +** TODO variant tonegen with multicast + +* circuit descr +the adc (GPIO36) is connected to a vtech pm221 speaker through an RC circuit w/ voltage divider: +SP+ to C1 to node A to R1 to node B to Rf to GPIO36; +Node B to R2 to node c to SP-; +Cf connects node c and node a. +GPIO36 is biased with two 1M resistors connected to 3V3 and GND pins. +C1 = 1 uF, Cf = 4.7nF, R1 = 22k, R2 = 10k, Rf = 1k +SP+ --- C1 --- a --- R1 --- b --- Rf --- GPIO --- d --- 1M --- GND + | | | +SP- --------- C2 --------- R2 1M --- 3V3 + +* prompt +gravity check this: +esp32 script streams udp data (rtp) +mode 1: send 440hz default on launch (works) +mode 2: (toggle mode on tapping pin) stream from ADC pin + +the adc (GPIO36) is connected to a vtech pm221 speaker through an RC circuit w/ voltage divider: +SP+ to C1 to node A to R1 to node B to Rf to GPIO36; +Node B to R2 to node c to SP-; +Cf connects node c and node a. +GPIO36 is biased with two 1M resistors connected to 3V3 and GND pins. +C1 = 1 uF, Cf = 4.7nF, R1 = 22k, R2 = 10k, Rf = 1k +``` +SP+ --- C1 --- a --- R1 --- b --- Rf --- GPIO --- d --- 1M --- GND + | | | +SP- --------- Cf --------- R2 1M --- 3V3 +``` + +need to troubleshoot this, either the circuit is wrong, or the ADC implementation. +before i redesign the circuit again, i'd like to know how i can test the ADC to be sure it's working; how would i create a 440Hz tone i can feed to the ADC that would be interpreted by our algorithm? +the program is right, because I can send the 440hz sine wave through it and it works! +so it's almost certainly an issue with the cercuit. + +* voltage/adc test 1 [2025-09-02 Tue] +- GND and 43V3 show 4095 range is good! and we're sitting at the midpoint +- voltage is confirmed (3.3v at 3V3 and 0V at GND) +- SP+ and SP- sit at 1.6V; ADC sits at 1.6V when idle +** data +switched to mic mode +4039-4095 +3997-4095 +3951-4095 +4023-4095 +4095-4095 +0-1994 +0-366 +0-366 +0-0 +0-0 +0-0 +0-0 +0-0 +0-0 +0-1087 +1489-2135 +1456-2150 +1493-2257 +1465-2636 +1299-2598 +1463-2177 +1522-2191 +1535-2261 + +** test2 +... + connected, ip=192.168.1.145 + tap pin 4 to switch modes +switched to mic mode +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:2698-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-1690(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-512(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:375-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-3909(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:3101-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryfcircuitworks) +adcrange:0-3101(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:509-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) + +** after 1M bias both directions +948-2559 +1376-2645 +1776-2866 +1535-2976 +1411-2640 +895-2093 +921-2638 +1119-2496 +1719-2878 +1422-3535 +1383-2812 +1041-2290 +991-2496 +956-2641 +1503-2837 +1731-2797 +1307-2951 +1055-2778 +976-2686 +983-2559 +1535-2870 +1475-2987 +1452-2896 +812-2272 +1019-2096 +852-2596 +1616-2867 +1739-2805 +1417-2734 +951-2380 +911-2245 +855-2549 +1611-2992 +1733-3344 +1236-2799 +976-2190 +1011-2503 +959-2526 +1702-2976 +1489-2839 +1215-3424 +959-2206 +956-2691 +1214-2480 +1645-2801 +1437-2989 +847-2551 +1126-2176 +849-2590 +1486-2879 +1655-2837 +1424-2881 +763-2232 +976-2128 +975-2734 +1555-2876 +1711-3258 +1232-3037 +1104-2457 +808-2144 +799-2854 +1535-3453 +1653-3236 +1313-2811 +934-2172 +1006-2784 +969-2588 +1525-3474 +1573-2872 +1329-3504 +829-2864 +921-2156 +1040-2542 +1136-2985 +1682-2921 +1495-2895 +1033-2694(shouldvar +yifcircuitworks) +912-2123 +998-2606 +1294-2541 +1617-3219 +1390-3737 +1383-2992 +1023-2309 +948-2391 +1043-2490 +1731-2804 +1567-2835 +1391-2976 +917-2224 +884-2262 +1111-2534 +1725-2976 +1500-2797 +1406-2653 +787-2205 +1023-2486 +1189-2517 +1580-2915 +1509-2954 + +** after circuit swap (this is way worse) +adc range: 0-602 (should vary if circuit works) +adc range: 0-487 (should vary if circuit works) +adc range: 0-400 (should vary if circuit works) +adc range: 0-112 (should vary if circuit works) +adc range: 0-621 (should vary if circuit works) +adc range: 0-570 (should vary if circuit works) +adc range: 0-659 (should vary if circuit works) +adc range: 0-325 (should vary if circuit works) +adc range: 0-63 (should vary if circuit works) +adc range: 0-418 (should vary if circuit works) + + + +* [2025-09-03 Wed] +1687/1746 to 2041 + +... +connected, ip=192.168.1.145 +tap pin 4 to switch modes +switched to mic mode +adc range: 1746-1971 (should vary if circuit works) +adc range: 1733-1966 (should vary if circuit works) +adc range: 1754-1965 (should vary if circuit works) +adc range: 1755-1965 (should vary if circuit works) +adc range: 1702-2009 (should vary if circuit works) +adc range: 1675-1957 (should vary if circuit works) +adc range: 1696-2041 (should vary if circuit works) +adc range: 1686-1962 (should vary if circuit works) +adc range: 1741-2004 (should vary if circuit works) +adc range: 1687-1965 (should vary if circuit works) +adc range: 1735-1957 (should vary if circuit works) +adc range: 1718-2031 (should vary if circuit works) +adc range: 1714-2000 (should vary if circuit works) + + +** funcgen +FG- to ESP32 ground +FG+ to GPIO36, then to SP+ +recognizable tone once DC offset turned on (~halfway bt 0/+) + (anything above this resets ESP32) +amplitude knob made little/no difference + (too high resets the ESP32) + +tone very choppy and _not_ 440Hz +no tone difference bt GPIO and SP+; + either wired wrong (possible) or + circuit is functioning (not impacting input) + +i'm thinking, we shouldnt expect adc serialout to be useful, unless i send a value ~1Hz +so let's generate that first: add a function to generate a 0.5 or .25Hz wave, + so that we can see the ADC values change in the serial out; + we should see values fluctuate between 0 and 4096, + and if we sync the timing right, should get a proper sense of the range right? + +** ok ran some basic tests +- ADC confirmed w dmm: 3.3v when ADC-3V3 and 0V when ADC-GND +- SP+ and SP- sit at 1.6V; ADC sits at 1.6V when idle +- ADC shows 0 at GND and 4095 at 3V3; midpoint ~2k when idle, with some noise +- FG- to ESP32 ground; FG+ to GPIO36, then to SP+. + recognizable tone once DC offset turned on (~halfway bt "0"/"+") + +tone very choppy and _not_ 440Hz, still comes in pulses where the audio cuts ~twice/sec. no tone difference bt connecting FG+ to GPIO vs SP+, indicating the code has more impact than the circuit. Upping to 540 and 640 Hz, I _can_ hear streaming tone go up - good sign! However the ESP-generated 440Hz tone in tone_mode also walks around a bit - this could be another (separate) problem in the ulaw/packetization logic. + +i removed the sampling limiter and moved the print to output adv_val directly after: samples[i] = int16_t)((adv_val-2048)*16); +So this is actually _upstream_ of packetization... but it's still crazy noisy, here's some data: +- 0.1Hz wave ranges from ~2100-2650, with noise usually +/-80, but spikes as big as 150 in both directions +- 1Hz wave ranges from ~2075-2650, with noise usually +/-80 +- 440Hz wave is essentially unrecognizable, though sample rate is def playing a role; range is the same (2075-2750). + +So we're currently using 25% of available bandwidth; need to scale ADC better. First, we need to look closely at the ADC reader/scale at lines 115-125: is this doing what we want? +#+begin_src c++ + static int debug_counter = 0; + int min_val = 4095, max_val = 0; + for (int i = 0; i < FRAME_SIZE; i++) { + int adc_val = adc1_get_raw(ADC1_CHANNEL_0); + if (adc_val < min_val) min_val = adc_val; + if (adc_val > max_val) max_val = adc_val; + // convert 12-bit adc (0-4095) to signed 16-bit (-32768 to 32767) + samples[i] = (int16_t)((adc_val - 2048) * 16); // center around 0, scale up + Serial.printf("%d\n", adc_val); //remove + } +#+end_src +Then, at the ulaw encoder: +#+begin_src c++ +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} +#+end_src + +claude_v3_functionaladc - decent 440hz tone, still walks a little; music playing through monitor is audible but chops every ~1s, and a high-pitched whiny tone is on top + +** python plot simple - see final version ~/Documents/Arduino/udp-tone-ai/plots +#+begin_src python +s = +title = "" +import plotly.graph_objects as go +import pandas as pd + +data = [(int(x.split(',')[0]), int(x.split(',')[1])) for x in s.split('\n')] +lows, highs = zip(*data) +x = list(range(len(data))) +go.Figure([go.Scatter(x=x, y=lows, name='low'),go.Scatter(x=x, y=highs, name='high')],title=title).show() + +#+end_src +** putty output +# use Tee-Object to output to console AND a file +$ plink -serial COM3 -sercfg 115200 | tee-object -FilePath "plink.log" +this is the winner! + +*** _other variants_ untested + +putty -serial COM3 -sercfg 115200,8,n,1,N | -sessionlog C:\users\moses\putty.log -logoverwrite +plink -serial COM3 -sercfg 115200 > plink.log + + +#+begin_src powershell +$port = new-Object System.IO.Ports.SerialPort COM3,115200,None,8,one +$port.Open() +while($true) { + if($port.BytesToRead -gt 0) { + $data = $port.ReadLine() + "$data" | Tee-Object -Append -FilePath serial.log + } +} +#+end_src + +** data +2096 +2073 +2095 +2081 +2095 +2096 +2095 +2086 +2096 +2096 +2083 +2093 +2083 +2080 +2073 +2078 +2098 +2077 +2096 +2093 +2096 +2101 +2006 +2096 +2160 +2096 +2079 +2090 +2093 +2077 +2097 +2064 +2096 +2092 +2076 +2085 +2087 +2096 +2090 +2086 +2096 +2082 +2135 +2183 +2087 +2090 +2087 +2058 +2091 +2091 +2082 +2151 +2088 +2083 +2105 +2082 +2094 +2077 +2095 +2091 +2085 +2066 +2086 +2096 +2139 +2078 +2096 +2096 +2097 +2098 +2093 +2109 +2096 +2098 +2096 +2085 +2096 +2075 +2076 +2096 +2094 +2095 +2095 +2067 +2097 +2083 +2089 +2107 +2134 +2107 +2080 +2096 +2094 +2197 +2043 +2176 +2133 +2007 +2032 +2045 +2114 +2075 +2117 +2087 +2145 +2104 +2106 +2096 +2086 +2065 +2096 +2117 +2094 +2108 +2109 +2105 +2097 +2097 +2096 +2087 +2079 +2096 +2007 +2101 +2111 +2096 +2089 +1990 +2087 +2081 +2082 +2100 +2101 +2089 +2097 +2097 +2092 +2105 +2091 +2071 +2096 +2057 +2096 +2098 +2095 +2096 +2096 +2085 +2093 +2123 +2080 +2090 +2096 +2089 +2089 +2119 +2087 +2083 +2071 +2087 +2010 +2046 +2084 +2074 +2083 +2085 +2096 +2079 +2064 +2080 +2095 +2094 +2139 +2090 +2085 +2081 +2089 +2075 +2095 +2090 +2032 +2090 +2096 +2090 +2082 +2085 +2097 +2096 +2074 +2083 +2075 +2115 +2079 +2125 +2096 +2082 +2192 +2091 +2103 +2080 +2174 +2083 +2093 +2096 +2097 +2096 +2086 +2100 +2061 +2092 +2091 +2094 +2096 +2091 +2085 +2092 +2085 +1977 +2092 +2102 +2091 +2079 +2096 +2002 +2096 +2103 +2065 +2083 +2096 +2094 +2171 +2088 +2098 +2112 +2096 +2095 +2090 +2105 +2054 +2096 +1972 +2119 +2096 +2083 +2103 +2078 +2036 +2097 +2083 +2090 +2066 +2091 +2099 +2080 +2112 +2082 +2104 +2099 +2160 +2097 +2109 +2093 +2093 +2096 +2087 +2117 +1984 +2096 +2063 +2061 +2096 +2112 +2078 +2102 +2099 +2081 +2099 +2103 +2066 +2098 +2103 +2187 +2102 +2095 +2097 +2093 +2086 +2126 +2063 +2088 +2096 +2043 +2106 +2073 +2105 +2114 +2099 +2099 +2107 +2096 +2086 +2100 +2103 +2215 +2101 +2119 +2102 +2055 +2096 +2101 +2086 +2101 +2128 +2061 +2099 +2109 +2109 +2100 +2097 +2115 +2046 +2055 +2093 +2083 +2135 +2081 +1997 +2073 +2096 +2103 +2098 +2081 +2085 +2096 +2099 +2103 +2081 +2096 +2096 +2100 +2074 +2100 +2105 +2096 +2073 +2069 +2097 +2097 +2068 +2085 +2096 +2096 +2091 +2095 +2137 +2095 +2096 +2096 +2096 +2096 +2097 +2089 +2116 +2106 +2111 +2096 +2111 +2044 +2112 +2080 +2075 +2097 +2106 +2064 +2105 +2093 +2032 +2114 +2076 +2083 +2095 +2103 +2160 +2112 +2098 +2098 +2098 +2102 +2091 +2089 +2096 +2096 +2115 +2091 +2094 +2074 +2112 +2090 +2096 +2096 +2116 +2083 +2094 +2096 +2091 +2094 +2129 +2089 +2105 +2116 +2096 +2098 +2085 +2096 +2087 +2135 +2085 +2096 +2101 +2093 +2115 +2101 +2101 +2103 +2107 +2106 +2080 +1989 +2070 +2097 +2144 +2099 +2117 +2064 +2096 +2038 +2106 +2096 +2120 +2097 +2096 +2205 +2113 +2099 +2103 +2096 +2098 +2108 +2087 +2108 +2097 +2106 +2109 +2110 +2097 +2107 +2111 +2188 +2130 +2105 +2206 +2112 +2101 +2112 +2089 +2095 +2112 +2098 +2103 +2121 +2072 +2119 +2114 +2100 +2106 +2113 +2112 +2119 +2103 +2098 +2104 +2119 +2103 +2041 +2143 +2096 +2112 +2105 +2106 +2109 +2097 +2091 +2055 +2128 +2109 +2101 +2097 +2135 +2064 +2057 +2094 +2106 +2096 +2092 +2090 +2143 +2090 +2097 +2094 +2092 +2074 +2118 +2113 +2119 +2112 +2107 +2128 +2095 +2096 +2158 +2094 +2106 +2112 +2092 +2073 +2085 +2041 +2098 +2095 +2096 +2202 +2074 +2110 +2103 +2105 +2126 +2096 +2122 +2163 +2071 +2109 +2115 +2109 +2068 +2096 +2037 +2105 +2108 +2133 +2128 +2085 +2107 +2105 +2194 +2065 +2103 +2112 +2093 +2079 +2118 +2103 +2103 +2107 +2070 +2113 +2091 +2105 +2085 +2090 +2111 +2112 +2192 +2110 +2097 +2098 +2107 +2087 +2121 +2091 +2114 +2108 +2094 +2096 +2128 +2110 +2117 +2109 +1971 +2145 +2092 +2098 +2078 +2086 +2093 +2079 +2107 +2096 +2161 +2111 +2096 +2102 +2097 +2102 +2096 +2015 +2107 +2094 +2034 +2101 +2032 +2141 +2097 +2090 +2085 +2000 +2107 +2175 +2005 +2105 +2220 +2096 +2123 +2117 +2112 +2122 +2103 +2089 +2113 +2124 +2025 +2147 +2117 +2111 +2058 +2102 +2102 +2096 +2106 +2109 +2111 +2111 +2112 +2094 +2112 +2109 +2095 +2118 +2106 +2091 +2098 +2111 +2033 +2105 +2106 +2109 +2093 +2114 +2096 +2100 +2112 +2109 +2106 +2109 +2117 +2066 +2070 +2065 +2110 +2080 +2129 +2093 +2100 +2106 +2111 +2115 +2142 +2124 +2101 +2045 +2125 +2212 +2139 +2105 +2128 +2103 +2121 +2104 +2107 +2102 +2117 +2107 +2096 +2094 +2106 +2105 +2110 +2128 +2103 +2084 +2099 +2096 +2250 +2119 +2099 +2107 +2109 +2096 +2121 +2108 +2091 +2097 +2122 +2043 +2095 +2102 +2119 +2112 +2097 +2108 +2103 +2105 +2105 +2192 +2084 +2116 +2098 +2110 +2081 +2096 +2125 +2146 +2227 +2099 +2114 +2112 +2131 +2087 +2112 +2207 +2112 +2096 +2084 +2096 +2112 +2108 +2097 +2137 +2113 +2145 +2123 +2112 +2133 +2097 +2102 +2231 +2098 +2098 +2118 +2119 +2106 +2111 +2103 +2097 +2128 +2155 +2112 +2140 +2109 +2111 +2099 +2116 +2096 +2103 +2113 +2107 +2111 +2110 +2002 +2105 +2115 +2159 +2109 +2102 +2112 +2110 +2125 +2131 +2117 +2116 +2110 +2110 +2131 +2021 +2112 +2122 +2097 +2130 +2116 +2112 +2109 +2043 +2113 +2113 +2128 +2096 +2119 +2114 +2093 +2109 +2122 +2096 +2099 +2118 +2115 +2112 +2112 +2071 +2127 +2139 +2128 +2137 +2094 +2108 +2117 +2115 +2096 +2116 +2094 +2127 +2113 +2231 +2111 +2112 +2105 +2087 +2112 +2128 +2045 +2110 +2095 +2114 +2115 +2127 +2150 +2111 +2099 +2119 +2119 +2112 +2124 +2244 +2119 +2127 +2067 +2112 +2007 +2107 +2046 +2024 +2125 +2064 +2114 +2109 +2114 +2118 +2117 +2112 +2210 +2251 +2125 +2125 +2115 +2123 +2031 +2110 +2111 +2114 +2117 +2103 +2112 +2112 +2121 +2098 +2112 +2108 +2112 +2096 +2121 +2103 +2112 +2111 +2064 +2113 +2107 +2096 +2106 +2237 +2110 +2101 +2091 +2104 +2115 +2117 +2128 +2114 +2121 +2114 +2102 +2064 +2068 +2131 +2096 +2144 +2091 +2118 +2167 +2095 +2123 +2093 +2119 +2115 +2146 +2112 +2115 +2139 +2102 +2126 +2093 +2130 +2016 +2103 +2015 +2119 +2125 +2119 +2112 +2117 +2118 +2124 +2044 +2117 +2111 +2119 +2113 +2126 +2113 +2115 +2110 +2103 +2118 +2114 +2106 +2121 +2102 +2092 +2116 +2176 +2216 +2127 +2112 +2146 +2128 +2094 +2115 +2112 +2126 +2128 +2110 +2111 +2143 +2130 +2125 +2117 +2127 +2124 +2128 +2117 +2064 +2109 +2107 +2148 +2117 +1929 +2096 +2133 +2121 +2112 +2128 +2114 +2128 +2129 +2116 +2112 +2126 +2114 +2130 +2111 +2042 +2122 +2119 +2127 +2123 +2166 +2198 +2118 +2130 +2105 +2174 +2062 +2125 +2155 +2116 +2137 +2119 +2104 +2125 +2119 +2127 +2113 +2119 +2102 +2131 +2119 +2113 +2127 +2112 +2111 +2117 +2128 +2126 +2114 +2125 +2129 +2122 +2255 +2114 +2139 +2119 +2126 +2126 +2123 +2091 +1969 +2115 +2111 +2118 +2109 +2089 +2144 +2148 +2127 +2069 +2116 +2118 +2084 +2091 +2123 +2112 +2114 +2126 +2117 +2128 +2130 +2087 +2111 +2125 +2163 +2126 +2127 +2128 +2125 +2122 +2128 +2221 +2096 +2118 +2119 +2107 +2128 +2125 +2123 +2131 +2122 +2128 +2122 +2175 +2128 +2162 +2142 +2102 +2121 +2127 +2113 +2123 +2118 +2128 +2116 +2128 +2119 +2126 +2138 +2129 +2128 +2158 +2153 +2141 +2121 +2120 +2125 +2114 +2092 +2128 +2151 +2128 +2128 +2128 +2121 +2122 +2137 +2118 +2098 +2127 +2125 +2129 +2123 +2124 +2095 +2119 +2107 +2107 +2126 +2129 +2125 +2084 +2103 +2124 +2118 +2169 +2112 +2128 +2118 +2123 +2125 +2128 +2119 +2138 +2144 +2067 +2127 +2107 +2115 +2113 +2139 +2139 +2126 +2129 +2101 +2081 +2128 +2147 +2128 +2141 +2129 +2128 +2112 +2158 +2131 +2123 +2102 +2176 +2130 +2121 +2101 +2131 +2133 +2122 +2095 +2114 +2202 +2128 +2125 +2101 +2128 +2096 +2131 +2128 +2128 +2137 +2131 +2121 +2128 +2137 +2102 +2115 +2129 +2127 +2131 +2153 +2127 +2128 +2133 +2109 +2129 +2127 +2013 +2137 +2109 +2134 +2148 +2105 +2125 +2151 +2128 +2117 +2124 +2113 +2101 +2128 +2131 +2144 +2126 +2025 +2125 +2119 +2130 +2130 +2138 +2125 +2126 +2118 +2131 +2124 +2117 +2136 +2125 +2097 +2126 +2133 +2111 +2121 +2118 +2126 +2131 +2131 +2144 +2131 +2129 +2132 +2128 +2155 +2127 +2145 +2171 +2128 +2135 +2145 +2151 +2149 +2140 +2138 +2167 +2128 +2137 +2105 +2150 +2127 +2134 +2137 +2128 +2133 +2073 +2154 +2114 +2136 +2142 +2135 +2146 +2150 +2182 +2122 +2118 +2147 +2128 +2107 +2125 +2129 +2119 +2123 +2118 +2128 +2138 +2134 +2125 +2149 +2135 +2129 +2138 +2111 +2138 +2134 +2142 +2146 +2094 +2069 +2141 +2128 +2174 +2128 +2127 +2128 +2136 +2075 +2115 +2135 +2148 +2143 +2064 +2128 +2133 +2134 +2129 +2140 +2133 +2100 +2030 +2150 +2043 +2129 +2135 +2146 +2142 +2116 +2132 +2146 +2138 +2138 +2177 +2089 +2145 +2146 +2138 +2256 +2157 +2131 +2189 +2134 +2151 +2144 +2141 +2139 +2148 +2148 +2145 +2134 +2033 +2157 +2145 +2064 +2132 +2132 +2181 +2137 +2144 +2135 +2125 +2141 +2118 +2165 +2143 +2157 +2150 +2133 +2131 +2150 +2138 +2146 +2129 +2240 +2145 +2133 +2129 +2099 +2115 +2160 +2143 +2160 +2128 +2160 +2069 +2142 +2133 +2149 +2134 +2125 +2147 +2142 +2139 +2151 +2066 +2135 +2143 +2133 +2128 +2128 +2140 +2140 +2147 +2122 +2149 +2147 +2156 +2144 +2150 +2071 +2141 +2063 +2144 +2141 +2141 +2151 +2145 +2141 +2143 +2151 +2142 +2147 +2147 +2139 +2081 +2155 +2147 +2091 +2154 +2147 +2149 +2142 +2128 +2130 +2159 +2154 +2149 +2146 +2120 +2111 +2134 +2133 +2144 +2133 +2147 +2156 +2162 +2145 +2139 +2149 +2133 +2141 +2150 +2107 +2166 +2142 +2174 +2148 +2155 +2129 +2128 +2151 +2136 +2149 +2153 +2054 +2129 +2149 +2174 +2191 +2155 +2146 +2167 +2158 +2036 +2142 +2130 +2149 +2141 +2130 +2145 +2139 +2138 +2151 +2142 +2150 +2145 +2161 +2145 +2145 +2145 +2145 +2180 +2127 +2143 +2143 +2155 +2107 +2145 +2148 +2143 +2143 +2149 +2131 +2147 +2128 +2226 +2145 +2146 +2193 +2071 +2158 +2155 +2142 +2160 +2290 +2137 +2146 +2141 +2143 +2144 +2081 +2160 +2145 +2150 +2137 +2143 +2128 +2160 +2135 +2160 +2150 +2127 +2174 +2161 +2131 +2140 +2166 +2157 +2128 +2141 +2145 +2194 +2128 +2160 +2160 +2141 +2221 +2150 +2157 +2148 +2148 +2128 +2136 +2148 +2182 +2146 +2153 +2155 +2094 +2208 +2143 +2158 +2158 +2137 +2172 +2155 +2265 +2139 +2154 +2151 +2149 +2139 +2136 +2148 +2146 +2137 +2167 +2155 +2143 +2160 +2159 +2174 +2157 +2154 +2151 +2162 +2032 +2159 +2202 +2128 +2148 +2176 +2160 +2153 +2196 +2143 +2157 +2158 +2142 +2149 +2155 +2128 +2164 +2156 +2157 +2162 +2144 +2158 +2160 +2156 +2191 +2144 +2151 +2133 +2243 +2173 +2143 +2146 +2183 +2154 +2151 +2167 +2158 +2088 +2150 +2129 +2175 +2227 +2147 +2155 +2151 +2155 +2149 +2192 +2159 +2152 +2156 +2150 +2160 +2111 +2160 +2160 +2156 +2140 +2158 +2162 +2148 +2159 +2118 +2139 +2117 +2128 +2163 +2148 +2156 +2171 +2147 +2138 +2160 +2149 +2251 +2151 +2147 +2155 +2153 +2159 +2155 +2160 +2149 +2155 +2114 +2154 +2085 +2212 +2160 +2160 +2137 +2165 +2155 +2160 +2179 +2027 +2143 +2167 +2156 +2164 +2072 +2158 +2160 +2167 +2165 +2161 +2159 +2157 +2161 +2173 +2178 +2158 +2179 +2141 +2165 +2171 +2169 +2133 +2161 +2160 +2160 +2198 +2160 +2154 +2160 +2171 +2160 +2160 +2160 +2170 +2159 +2135 +2157 +2104 +2147 +2111 +2141 +2256 +2147 +2147 +2169 +2148 +2157 +2170 +2174 +2160 +2149 +2135 +2159 +2143 +2162 +2214 +2189 +2160 +2160 +2165 +2130 +2169 +2154 +2186 +2158 +2186 +2160 +2144 +2160 +2170 +2169 +2171 +2161 +2143 +2157 +2160 +2160 +2176 +2173 +2155 +2178 +2160 +2158 +2143 +2154 +2143 +2129 +2160 +2157 +2163 +2195 +2161 +2167 +2155 +2170 +2173 +2171 +2160 +2039 +2089 +2161 +2201 +2175 +2163 +2285 +2173 +2155 +2158 +2157 +2102 +2169 +2122 +2160 +2160 +2174 +2167 +2163 +2170 +2176 +2133 +2160 +2166 +2117 +2164 +2163 +2161 +2151 +2172 +2139 +2165 +2185 +2173 +2120 +2177 +2164 +2156 +2176 +2163 +2160 +2160 +2161 +2164 +2177 +2160 +2185 +2160 +2168 +2143 +2173 +2157 +2195 +2161 +2163 +2163 +2162 +2142 +2131 +2175 +2174 +2166 +2160 +2154 +2147 +2171 +2164 +1974 +2160 +2039 +2160 +2160 +2176 +2175 +2163 +2157 +2157 +2187 +2182 +2161 +2171 +2166 +2152 +2165 +2164 +2179 +2162 +2138 +2171 +2176 +2162 +2170 +2160 +2162 +2162 +2180 +2160 +2155 +2166 +2165 +2174 +2173 +2160 +2153 +2138 +2165 +2185 +2167 +2153 +2174 +2175 +2131 +2165 +2174 +2167 +2289 +2180 +2170 +2171 +2301 +2187 +2176 +2123 +2170 +2175 +2175 +2154 +2178 +2158 +2174 +2107 +2185 +2112 +2127 +2159 +2171 +2170 +2171 +2268 +2176 +2190 +2169 +2189 +2161 +2161 +2168 +2170 +2170 +2176 +2170 +2179 +2167 +2158 +2160 +2154 +2098 +2160 +2167 +2077 +2192 +2160 +2176 +2160 +2150 +2135 +2157 +2158 +2166 +2148 +2169 +2167 +2187 +2198 +2176 +2173 +2170 +2160 +2206 +2160 +2175 +2160 +2177 +2187 +2174 +2175 +2164 +2185 +2161 +2175 +2173 +2171 +2182 +2177 +2175 +2165 +2178 +2176 +2175 +2178 +2165 +2170 +2178 +2173 +2155 +2161 +2171 +2189 +2175 +2173 +2162 +2191 +2169 +2162 +2186 +2137 +2162 +2180 +2175 +2209 +2173 +2176 +2165 +2171 +2037 +2178 +2175 +2166 +2174 +2167 +2174 +2171 +2187 +2085 +2186 +2165 +2163 +2175 +2182 +2171 +2148 +2160 +2167 +2181 +2214 +2160 +2176 +2179 +2160 +2179 +2166 +2168 +2178 +2187 +2176 +2118 +2171 +2162 +2161 +2183 +2191 +2187 +2160 +2170 +2181 +2098 +2191 +2176 +2144 +2160 +2178 +2190 +2182 +2170 +2179 +2181 +2177 +2190 +2176 +2224 +2192 +2169 +2192 +2190 +2126 +2193 +2164 +2170 +2177 +2139 +2181 +2176 +2182 +2183 +2180 +2185 +2201 +2195 +2161 +2191 +2181 +2176 +2173 +2170 +2186 +2256 +2178 +2275 +2174 +2177 +2182 +2166 +2172 +2173 +2131 +2166 +2183 +2169 +2183 +2160 +2179 +2179 +2171 +2187 +2189 +2183 +2174 +2121 +2166 +2173 +2096 +2160 +2176 +2163 +2117 +2160 +2178 +2179 +2189 +2190 +2178 +2171 +2221 +2174 +2179 +2176 +2170 +2192 +2188 +2261 +2196 +2175 +2190 +2201 +2194 +2185 +2186 +2127 +2171 +2288 +2188 +2192 +2192 +2174 +2102 +2149 +2186 +2187 +2187 +2192 +2173 +2177 +2231 +2169 +2183 +2178 +2011 +2189 +2225 +2182 +2147 +2137 +2221 +2103 +2182 +2083 +2183 +2196 +2190 +2192 +2187 +2186 +2199 +2181 +2187 +2185 +2180 +2193 +2192 +2192 +2179 +2192 +2199 +2176 +2202 +2188 +2186 +2195 +2190 +2176 +2163 +2183 +2176 +2192 +2195 +2190 +2174 +2192 +2185 +2311 +2218 +2169 +2194 +2186 +2197 +2155 +2259 +2192 +2190 +2209 +2191 +2177 +2196 +2181 +2200 +2196 +2181 +2240 +2192 +2282 +2259 +2189 +2195 +2204 +2200 +2176 +2161 +2191 +2237 +2186 +2182 +2076 +2197 +2198 +2187 +2207 +2190 +2213 +2177 +2178 +2173 +2142 +2192 +2185 +2186 +2187 +2192 +2174 +2182 +2194 +2215 +2170 +2191 +2194 +2192 +2176 +2188 +2210 +2173 +2192 +2164 +2145 +2191 +2182 +2182 +2194 +2227 +2082 +2206 +2191 +2173 +2174 +2206 +2192 +2183 +2187 +2192 +2160 +2239 +2208 +2194 +2151 +2192 +2196 +2190 +2187 +2185 +2192 +2190 +2201 +2187 +2223 +2193 +2191 +2182 +2185 +2195 +2192 +2135 +2160 +2286 +2176 +2192 +2191 +2192 +2234 +2195 +2226 +2223 +2020 +2198 +2203 +2199 +2202 +2182 +2199 +2185 +2193 +2237 +2197 +2192 +2192 +2188 +2192 +2176 +2197 +2203 +2156 +2204 +2174 +2192 +2197 +2194 +2181 +2192 +2180 +2192 +2245 +2196 +2188 +2195 +2198 +2242 +2166 +2192 +2099 +2192 +2196 +2191 +2203 +2176 +2196 +2180 +2194 +2205 +2192 +2192 +2192 +2197 +2192 +2219 +2192 +2166 +2215 +2194 +2203 +2214 +2200 +2196 +2241 +2197 +2240 +2223 +2205 +2139 +2187 +2192 +2171 +2201 +2185 +2198 +2187 +2213 +2192 +2194 +2193 +2208 +2202 +2131 +2203 +2197 +2194 +2180 +2198 +2194 +2182 +2204 +2172 +2158 +2192 +2203 +2197 +2198 +2204 +2181 +2240 +2265 +2208 +2202 +2214 +2187 +2176 +2241 +2099 +2163 +2209 +2196 +2205 +2190 +2238 +2215 +2205 +2205 +2197 +2199 +2218 +2224 +2212 +2197 +2207 +2294 +2199 +2288 +2309 +2192 +2209 +2135 +2203 +2192 +2203 +2198 +2147 +2170 +2203 +2206 +2197 +2162 +2193 +2205 +2199 +2206 +2332 +2199 +2207 +2194 +2191 +2151 +2288 +2206 +2206 +2192 +2219 +2198 +2187 +2224 +2201 +2211 +2210 +2195 +2192 +2201 +2202 +2211 +2199 +2201 +2174 +2198 +2206 +2176 +2222 +2205 +2209 +2192 +2205 +2192 +2205 +2192 +2188 +2209 +2213 +2210 +2192 +2206 +2212 +2205 +2203 +2208 +2228 +2208 +2224 +2209 +2204 +2212 +2205 +2278 +2210 +2202 +2200 +2193 +2203 +2224 +2254 +2197 +2212 +2210 +2222 +2224 +2207 +2227 +2204 +2203 +2213 +2204 +2192 +2208 +2176 +2192 +2199 +2203 +2219 +2203 +2192 +2195 +2206 +2207 +2215 +2224 +2224 +2197 +2203 +2200 +2181 +2194 +2188 +2204 +2207 +2131 +2192 +2206 +2198 +2203 +2204 +2221 +2213 +2224 +2207 +2203 +2182 +2199 +2166 +2191 +2195 +2215 +2203 +2208 +2252 +2186 +2207 +2224 +2195 +2224 +2247 +2315 +2181 +2369 +2192 +2203 +2117 +2206 +2226 +2229 +2214 +2218 +2224 +2199 +2214 +2193 +2209 +2206 +2208 +2217 +2240 +2211 +2202 +2208 +2211 +2217 +2208 +2229 +2240 +2215 +2222 +2192 +2213 +2199 +2198 +2192 +2207 +2206 +2215 +2224 +2267 +2208 +2340 +2213 +2218 +2211 +2173 +2214 +2241 +2220 +2224 +2208 +2213 +2198 +2209 +2224 +2213 +2223 +2240 +2213 +2219 +2215 +2219 +2201 +2213 +2202 +2215 +2208 +2208 +2213 +2163 +2185 +2230 +2217 +2215 +2224 +2181 +2224 +2225 +2205 +2236 +2253 +2225 +2215 +2192 +2225 +2209 +2203 +2207 +2210 +2222 +2207 +2222 +2222 +2199 +2237 +2223 +2224 +2224 +2204 +2209 +2224 +2231 +2231 +2210 +2224 +2217 +2219 +2219 +2224 +2256 +2218 +2215 +2209 +2198 +2224 +2231 +2222 +2221 +2236 +2274 +2187 +2149 +2254 +2223 +2210 +2240 +2187 +2201 +2220 +2207 +2224 +2213 +2150 +2199 +2192 +2224 +2235 +2213 +2215 +2222 +2224 +2237 +2224 +2240 +2316 +2223 +2303 +2241 +2171 +2191 +2221 +2211 +2190 +2192 +2187 +2217 +2220 +2221 +2225 +2215 +2215 +2222 +2219 +2224 +2255 +2223 +2209 +2205 +2218 +2285 +2219 +2195 +2198 +2145 +2211 +2224 +2224 +2223 +2215 +2202 +2224 +2224 +2240 +2223 +2206 +2219 +2224 +2202 +2192 +2256 +2223 +2222 +2227 +2224 +2142 +2218 +2320 +2209 +2215 +2162 +2223 +2227 +2214 +2226 +2221 +2159 +2255 +2224 +2227 +2224 +2218 +2226 +2240 +2228 +2229 +2230 +2277 +2206 +2255 +2231 +2254 +2212 +2223 +2275 +2237 +2224 +2207 +2203 +2225 +2225 +2222 +2257 +2230 +2154 +2229 +2222 +2220 +2218 +2227 +2227 +2224 +2209 +2209 +2192 +2219 +2239 +2255 +2206 +2218 +2224 +2213 +2192 +2230 +2219 +2229 +2246 +2223 +2224 +2239 +2141 +2232 +2226 +2207 +2223 +2202 +2336 +2224 +2146 +2223 +2216 +2217 +2235 +2222 +2272 +2242 +2228 +2227 +2240 +2229 +2256 +2223 +2225 +2161 +2245 +2251 +2198 +2234 +2160 +2224 +2226 +2240 +2229 +2215 +2243 +2243 +2138 +2224 +2226 +2229 +2228 +2217 +2234 +2222 +2233 +2229 +2224 +2240 +2194 +2223 +2231 +2230 +2167 +2236 +2226 +2231 +2225 +2235 +2307 +2240 +2235 +2234 +2256 +2234 +2217 +2227 +2224 +2239 +2230 +2254 +2228 +2254 +2231 +2224 +2192 +2224 +2229 +2226 +2303 +2229 +2224 +2259 +2227 +2225 +2240 +2321 +2224 +2225 +2223 +2231 +2224 +2230 +2231 +2227 +2235 +2251 +2224 +2224 +2223 +2269 +2232 +2229 +2231 +2199 +2235 +2240 +2193 +2206 +2274 +2244 +2282 +2236 +2241 +2256 +2240 +2240 +2235 +2234 +2234 +2219 +2253 +2227 +2238 +2256 +2182 +2229 +2184 +2244 +2207 +2241 +2246 +2238 +2274 +2233 +2224 +2230 +2240 +2256 +2235 +2354 +2240 +2235 +2239 +2254 +2256 +2240 +2288 +2238 +2237 +2238 +2241 +2240 +2238 +2246 +2240 +2242 +2250 +2243 +2230 +2253 +2224 +2277 +2238 +2234 +2228 +2241 +2256 +2256 +2230 +2223 +2233 +2239 +2207 +2240 +2233 +2162 +2097 +2240 +2237 +2190 +2185 +2231 +2230 +2359 +2241 +2215 +2241 +2224 +2226 +2235 +2239 +2245 +2240 +2246 +2256 +2266 +2244 +2271 +2275 +2252 +2240 +2242 +2245 +2236 +2264 +2253 +2245 +2380 +2193 +2246 +2261 +2237 +2253 +2221 +2251 +2243 +2246 +2246 +2249 +2249 +2254 +2246 +2256 +2254 +2246 +2240 +2253 +2244 +2238 +2162 +2135 +2256 +2308 +2256 +2247 +2240 +2220 +2241 +2250 +2246 +2225 +2243 +2242 +2224 +2255 +2262 +2267 +2239 +2239 +2229 +2240 +2318 +2240 +2245 +2203 +2237 +2205 +2190 +2239 +2266 +2293 +2349 +2247 +2195 +2253 +2222 +2244 +2250 +2256 +2222 +2245 +2231 +2243 +2227 +2256 +2290 +2222 +2227 +2247 +2245 +2347 +2241 +2249 +2224 +2250 +2245 +2245 +2271 +2239 +2256 +2238 +2255 +2268 +2255 +2235 +2247 +2250 +2245 +2236 +2240 +2253 +2255 +2259 +2245 +2259 +2265 +2253 +2251 +2257 +2241 +2256 +2256 +2253 +2246 +2261 +2239 +2275 +2241 +2256 +2243 +2216 +2222 +2246 +2253 +2246 +2246 +2275 +2269 +2250 +2286 +2240 +2253 +2265 +2254 +2261 +2256 +2285 +2249 +2250 +2256 +2238 +2253 +2253 +2256 +2256 +2272 +2259 +2254 +2367 +2262 +2246 +2263 +2358 +2306 +2267 +2263 +2202 +2257 +2256 +2256 +2212 +2262 +2271 +2257 +2259 +2261 +2257 +2240 +2251 +2236 +2152 +2258 +2259 +2240 +2229 +2257 +2257 +2259 +2254 +2345 +2240 +2256 +2256 +2255 +2256 +2254 +2252 +2242 +2256 +2246 +2217 +2256 +2256 +2235 +2267 +2271 +2254 +2245 +2249 +2247 +2254 +2257 +2271 +2220 +2256 +2255 +2247 +2250 +2262 +2257 +2219 +2259 +2257 +2258 +2288 +2256 +2253 +2256 +2262 +2247 +2272 +2262 +2269 +2259 +2166 +2263 +2287 +2247 +2256 +2255 +2259 +2229 +2247 +2244 +2263 +2233 +2272 +2236 +2256 +2256 +2256 +2261 +2240 +2253 +2250 +2234 +2251 +2255 +2263 +2258 +2294 +2256 +2256 +2256 +2165 +2243 +2264 +2256 +2261 +2257 +2228 +2253 +2250 +2283 +2242 +2259 +2268 +2273 +2353 +2163 +2258 +2250 +2271 +2267 +2270 +2385 +2243 +2261 +2263 +2273 +2305 +2273 +2247 +2315 +2256 +2231 +2301 +2262 +2256 +2256 +2295 +2293 +2316 +2256 +2241 +2265 +2257 +2262 +2257 +2247 +2251 +2256 +2271 +2274 +2260 +2394 +2209 +2260 +2269 +2261 +2247 +2260 +2257 +2263 +2260 +2273 +2253 +2256 +2253 +2272 +2235 +2265 +2263 +2309 +2269 +2262 +2277 +2279 +2267 +2254 +2310 +2279 +2218 +2263 +2307 +2260 +2276 +2267 +2267 +2286 +2273 +2270 +2243 +2380 +2274 +2271 +2267 +2261 +2194 +2283 +2291 +2273 +2270 +2268 +2285 +2289 +2261 +2231 +2271 +2270 +2279 +2273 +2243 +2260 +2267 +2320 +2278 +2263 +2253 +2265 +2336 +2281 +2253 +2271 +2267 +2273 +2256 +2256 +2265 +2261 +2195 +2259 +2271 +2311 +2263 +2160 +2347 +2278 +2185 +2302 +2259 +2265 +2273 +2208 +2302 +2259 +2256 +2267 +2269 +2246 +2254 +2267 +2271 +2193 +2265 +2272 +2236 +2266 +2260 +2265 +2339 +2263 +2346 +2261 +2273 +2278 +2256 +2281 +2272 +2305 +2257 +2274 +2279 +2278 +2258 +2242 +2270 +2256 +2271 +2256 +2274 +2273 +2272 +2255 +2283 +2275 +2256 +2281 +2303 +2213 +2283 +2261 +2268 +2267 +2279 +2244 +2267 +2265 +2279 +2389 +2340 +2281 +2276 +2275 +2256 +2290 +2278 +2268 +2278 +2305 +2320 +2271 +2348 +2298 +2295 +2283 +2282 +2256 +2290 +2277 +2263 +2251 +2277 +2279 +2225 +2288 +2282 +2289 +2227 +2282 +2224 +2286 +2291 +2288 +2276 +2284 +2254 +2271 +2267 +2270 +2286 +2276 +2277 +2287 +2254 +2285 +2277 +2271 +2265 +2269 +2288 +2355 +2267 +2285 +2307 +2365 +2286 +2277 +2311 +2269 +2283 +2273 +2289 +2285 +2287 +2275 +2286 +2288 +2272 +2278 +2239 +2293 +2283 +2286 +2288 +2272 +2227 +2271 +2295 +2289 +2285 +2287 +2253 +2292 +2282 +2285 +2284 +2281 +2288 +2285 +2277 +2267 +2405 +2327 +2267 +2305 +2320 +2361 +2275 +2288 +2281 +2288 +2289 +2275 +2283 +2267 +2312 +2288 +2292 +2283 +2274 +2285 +2277 +2295 +2279 +2321 +2282 +2283 +2274 +2291 +2274 +2287 +2277 +2289 +2268 +2288 +2277 +2282 +2284 +2283 +2420 +2257 +2283 +2282 +2278 +2352 +2272 +2288 +2294 +2285 +2269 +2290 +2290 +2306 +2293 +2241 +2284 +2267 +2298 +2266 +2272 +2261 +2287 +2303 +2284 +2314 +2273 +2283 +2287 +2311 +2278 +2284 +2284 +2280 +2259 +2285 +2297 +2151 +2246 +2285 +2288 +2279 +2294 +2288 +2286 +2341 +2299 +2297 +2294 +2399 +2287 +2289 +2285 +2335 +2274 +2291 +2337 +2288 +2285 +2295 +2334 +2302 +2277 +2290 +2275 +2288 +2288 +2289 +2283 +2217 +2275 +2290 +2306 +2300 +2348 +2288 +2293 +2288 +2298 +2295 +2303 +2297 +2289 +2299 +2292 +2286 +2280 +2295 +2288 +2288 +2303 +2288 +2281 +2290 +2291 +2295 +2285 +2281 +2233 +2282 +2301 +2268 +2338 +2289 +2290 +2281 +2284 +2291 +2291 +2286 +2280 +2296 +2301 +2310 +2305 +2330 +2292 +2271 +2398 +2299 +2195 +2187 +2349 +2304 +2287 +2273 +2291 +2289 +2296 +2289 +2305 +2299 +2290 +2304 +2250 +2272 +2311 +2311 +2295 +2295 +2240 +2299 +2299 +2293 +2301 +2369 +2298 +2300 +2406 +2295 +2245 +2337 +2301 +2383 +2302 +2307 +2311 +2299 +2331 +2306 +2290 +2287 +2303 +2297 +2295 +2283 +2294 +2302 +2292 +2330 +2288 +2315 +2298 +2339 +2317 +2289 +2314 +2293 +2289 +2301 +2303 +2290 +2299 +2292 +2292 +2317 +2290 +2316 +2320 +2298 +2256 +2289 +2321 +2323 +2320 +2309 +2311 +2298 +2304 +2427 +2314 +2305 +2415 +2319 +2305 +2331 +2295 +2303 +2304 +2303 +2290 +2314 +2293 +2318 +2286 +2320 +2304 +2288 +2313 +2304 +2307 +2321 +2341 +2300 +2310 +2357 +2299 +2420 +2309 +2320 +2256 +2299 +2349 +2307 +2304 +2244 +2293 +2304 +2299 +2227 +2291 +2307 +2311 +2293 +2304 +2303 +2306 +2306 +2319 +2335 +2305 +2307 +2309 +2306 +2301 +2311 +2412 +2311 +2295 +2256 +2306 +2323 +2310 +2320 +2301 +2301 +2285 +2313 +2293 +2306 +2304 +2304 +2320 +2304 +2306 +2283 +2331 +2327 +2321 +2298 +2313 +2316 +2322 +2297 +2465 +2338 +2306 +2305 +2331 +2346 +2303 +2311 +2316 +2317 +2317 +2305 +2304 +2313 +2311 +2346 +2295 +2311 +2319 +2320 +2270 +2310 +2308 +2245 +2322 +2284 +2299 +2307 +2290 +2302 +2327 +2298 +2306 +2318 +2287 +2320 +2313 +2309 +2310 +2283 +2303 +2317 +2304 +2215 +2307 +2327 +2315 +2341 +2308 +2319 +2304 +2309 +2334 +2320 +2309 +2319 +2310 +2426 +2304 +2295 +2316 +2298 +2287 +2318 +2314 +2311 +2322 +2307 +2274 +2319 +2295 +2311 +2330 +2318 +2320 +2311 +2319 +2320 +2319 +2311 +2306 +2320 +2314 +2398 +2308 +2315 +2323 +2301 +2320 +2309 +2428 +2320 +2320 +2315 +2366 +2321 +2334 +2317 +2321 +2309 +2317 +2304 +2320 +2245 +2319 +2320 +2318 +2321 +2321 +2329 +2351 +2319 +2315 +2320 +2325 +2331 +2320 +2312 +2352 +2306 +2307 +2315 +2320 +2288 +2320 +2286 +2320 +2327 +2325 +2313 +2314 +2320 +2289 +2354 +2320 +2317 +2323 +2417 +2325 +2298 +2331 +2317 +2323 +2330 +2331 +2317 +2327 +2319 +2301 +2317 +2320 +2291 +2323 +2317 +2325 +2311 +2316 +2309 +2325 +2336 +2315 +2305 +2321 +2311 +2320 +2290 +2331 +2335 +2205 +2346 +2319 +2320 +2314 +2236 +2320 +2323 +2311 +2334 +2320 +2350 +2326 +2322 +2321 +2317 +2363 +2323 +2314 +2318 +2335 +2316 +2325 +2343 +2336 +2328 +2327 +2333 +2335 +2330 +2287 +2323 +2325 +2325 +2333 +2330 +2333 +2323 +2325 +2297 +2325 +2325 +2238 +2289 +2335 +2318 +2326 +2305 +2310 +2455 +2317 +2337 +2329 +2320 +2322 +2275 +2335 +2333 +2322 +2334 +2358 +2335 +2400 +2320 +2322 +2225 +2326 +2325 +2321 +2347 +2323 +2323 +2339 +2350 +2327 +2336 +2352 +2323 +2331 +2350 +2335 +2337 +2333 +2322 +2461 +2303 +2343 +2329 +2347 +2233 +2341 +2241 +2351 +2334 +2333 +2329 +2342 +2326 +2319 +2330 +2350 +2322 +2337 +2331 +2325 +2333 +2320 +2321 +2325 +2325 +2326 +2336 +2333 +2419 +2349 +2446 +2302 +2331 +2335 +2339 +2328 +2335 +2321 +2288 +2333 +2320 +2373 +2334 +2329 +2325 +2353 +2330 +2367 +2270 +2329 +2331 +2329 +2329 +2347 +2327 +2334 +2331 +2281 +2322 +2337 +2335 +2331 +2341 +2334 +2343 +2333 +2341 +2330 +2338 +2339 +2330 +2346 +2331 +2337 +2329 +2323 +2356 +2315 +2329 +2310 +2333 +2336 +2352 +2350 +2327 +2320 +2338 +2428 +2332 +2325 +2335 +2332 +2331 +2325 +2327 +2323 +2351 +2320 +2333 +2345 +2332 +2263 +2341 +2331 +2323 +2334 +2316 +2309 +2337 +2363 +2366 +2285 +2346 +2311 +2339 +2323 +2225 +2335 +2330 +2346 +2337 +2357 +2352 +2343 +2334 +2332 +2331 +2350 +2349 +2320 +2340 +2321 +2321 +2305 +2339 +2343 +2353 +2279 +2331 +2345 +2352 +2341 +2336 +2339 +2352 +2361 +2338 +2346 +2361 +2355 +2389 +2334 +2342 +2333 +2342 +2341 +2352 +2333 +2357 +2355 +2300 +2343 +2338 +2337 +2341 +2331 +2352 +2322 +2477 +2346 +2339 +2329 +2311 +2347 +2345 +2345 +2287 +2338 +2352 +2354 +2342 +2346 +2346 +2407 +2339 +2343 +2342 +2352 +2307 +2342 +2347 +2333 +2485 +2350 +2352 +2336 +2334 +2336 +2477 +2255 +2333 +2347 +2338 +2336 +2338 +2337 +2363 +2346 +2354 +2362 +2286 +2330 +2340 +2345 +2331 +2343 +2406 +2345 +2363 +2446 +2346 +2342 +2337 +2296 +2320 +2347 +2363 +2349 +2356 +2349 +2352 +2343 +2342 +2433 +2352 +2348 +2343 +2350 +2343 +2302 +2352 +2382 +2352 +2334 +2383 +2349 +2362 +2366 +2347 +2351 +2352 +2359 +2337 +2342 +2352 +2352 +2341 +2357 +2347 +2355 +2347 +2315 +2348 +2353 +2379 +2257 +2366 +2338 +2291 +2478 +2293 +2371 +2353 +2353 +2374 +2352 +2340 +2295 +2347 +2417 +2336 +2365 +2339 +2356 +2363 +2352 +2364 +2349 +2356 +2519 +2333 +2355 +2357 +2359 +2305 +2351 +2359 +2353 +2368 +2353 +2371 +2354 +2341 +2352 +2352 +2356 +2351 +2363 +2359 +2358 +2299 +2378 +2326 +2377 +2351 +2357 +2365 +2390 +2352 +2382 +2351 +2331 +2301 +2339 +2353 +2350 +2357 +2353 +2352 +2332 +2357 +2338 +2352 +2334 +2350 +2354 +2352 +2299 +2314 +2347 +2342 +2371 +2333 +2352 +2350 +2379 +2359 +2390 +2352 +2299 +2353 +2343 +2353 +2358 +2363 +2352 +2363 +2353 +2331 +2373 +2357 +2343 +2353 +2367 +2363 +2368 +2352 +2341 +2411 +2353 +2361 +2364 +2354 +2514 +2353 +2352 +2353 +2355 +2350 +2356 +2351 +2355 +2356 +2358 +2350 +2288 +2355 +2358 +2349 +2364 +2370 +2366 +2346 +2353 +2374 +2435 +2410 +2351 +2357 +2361 +2354 +2371 +2369 +2361 +2367 +2358 +2364 +2341 +2367 +2352 +2326 +2378 +2370 +2346 +2352 +2353 +2352 +2361 +2350 +2394 +2368 +2354 +2369 +2357 +2286 +2359 +2361 +2380 +2363 +2368 +2352 +2349 +2368 +2367 +2377 +2358 +2311 +2341 +2362 +2365 +2361 +2367 +2355 +2352 +2372 +2589 +2368 +2352 +2350 +2352 +2359 +2383 +2370 +2363 +2384 +2363 +2364 +2345 +2368 +2372 +2353 +2358 +2341 +2277 +2379 +2373 +2368 +2377 +2378 +2371 +2384 +2368 +2367 +2375 +2369 +2335 +2389 +2375 +2371 +2377 +2417 +2378 +2370 +2384 +2332 +2195 +2388 +2369 +2409 +2377 +2355 +2289 +2365 +2369 +2372 +2397 +2503 +2366 +2339 +2365 +2366 +2368 +2384 +2366 +2369 +2450 +2367 +2367 +2371 +2342 +2366 +2377 +2368 +2354 +2367 +2371 +2366 +2219 +2381 +2352 +2368 +2352 +2379 +2368 +2271 +2487 +2369 +2295 +2356 +2349 +2342 +2384 +2369 +2368 +2415 +2320 +2362 +2287 +2451 +2368 +2368 +2365 +2320 +2384 +2356 +2357 +2365 +2376 +2345 +2346 +2351 +2369 +2352 +2365 +2352 +2365 +2364 +2353 +2368 +2366 +2371 +2378 +2374 +2377 +2372 +2320 +2370 +2368 +2400 +2364 +2369 +2543 +2358 +2304 +2368 +2395 +2321 +2368 +2383 +2372 +2371 +2375 +2321 +2382 +2386 +2382 +2307 +2366 +2379 +2372 +2368 +2382 +2365 +2374 +2374 +2379 +2321 +2294 +2371 +2372 +2365 +2304 +2371 +2386 +2369 +2367 +2375 +2386 +2374 +2372 +2375 +2386 +2361 +2378 +2368 +2375 +2378 +2363 +2381 +2384 +2385 +2383 +2390 +2384 +2387 +2386 +2348 +2375 +2422 +2373 +2386 +2358 +2327 +2362 +2384 +2384 +2402 +2389 +2378 +2370 +2379 +2368 +2386 +2382 +2393 +2423 +2381 +2401 +2378 +2359 +2359 +2379 +2395 +2359 +2382 +2384 +2365 +2363 +2384 +2395 +2381 +2371 +2480 +2420 +2379 +2342 +2383 +2357 +2379 +2382 +2340 +2372 +2391 +2351 +2386 +2430 +2354 +2375 +2383 +2368 +2389 +2361 +2380 +2374 +2398 +2373 +2386 +2375 +2363 +2395 +2385 +2459 +2373 +2384 +2377 +2384 +2373 +2379 +2372 +2381 +2389 +2378 +2380 +2384 +2387 +2376 +2403 +2379 +2371 +2395 +2378 +2384 +2381 +2378 +2291 +2387 +2378 +2359 +2386 +2398 +2379 +2372 +2290 +2382 +2389 +2391 +2385 +2368 +2381 +2373 +2404 +2385 +2382 +2386 +2375 +2493 +2336 +2397 +2387 +2428 +2391 +2413 +2403 +2391 +2430 +2401 +2398 +2384 +2384 +2367 +2389 +2416 +2377 +2387 +2377 +2385 +2363 +2386 +2391 +2385 +2391 +2396 +2398 +2391 +2386 +2378 +2384 +2384 +2382 +2386 +2387 +2383 +2382 +2373 +2411 +2420 +2385 +2383 +2384 +2384 +2389 +2366 +2384 +2386 +2401 +2350 +2386 +2397 +2400 +2384 +2391 +2389 +2382 +2386 +2377 +2383 +2414 +2390 +2366 +2390 +2391 +2383 +2389 +2402 +2388 +2395 +2401 +2326 +2394 +2390 +2387 +2415 +2382 +2384 +2384 +2382 +2375 +2386 +2387 +2368 +2384 +2368 +2386 +2383 +2452 +2379 +2416 +2379 +2384 +2385 +2384 +2478 +2408 +2390 +2402 +2388 +2398 +2444 +2365 +2384 +2387 +2369 +2399 +2393 +2419 +2393 +2385 +2378 +2374 +2398 +2399 +2389 +2398 +2374 +2389 +2394 +2526 +2391 +2391 +2407 +2401 +2388 +2397 +2387 +2394 +2393 +2386 +2394 +2339 +2398 +2384 +2397 +2400 +2387 +2384 +2399 +2394 +2394 +2385 +2394 +2425 +2421 +2405 +2402 +2397 +2395 +2379 +2397 +2419 +2409 +2387 +2405 +2384 +2390 +2384 +2372 +2395 +2348 +2385 +2415 +2403 +2401 +2385 +2395 +2399 +2384 +2400 +2396 +2405 +2384 +2386 +2355 +2384 +2421 +2395 +2401 +2397 +2398 +2416 +2313 +2448 +2413 +2413 +2403 +2416 +2320 +2406 +2385 +2417 +2433 +2403 +2405 +2406 +2399 +2419 +2402 +2389 +2222 +2403 +2405 +2403 +2398 +2400 +2416 +2416 +2384 +2398 +2415 +2389 +2438 +2411 +2411 +2409 +2372 +2415 +2373 +2421 +2387 +2401 +2395 +2395 +2418 +2410 +2416 +2352 +2409 +2432 +2397 +2413 +2404 +2395 +2393 +2355 +2400 +2403 +2393 +2402 +2542 +2416 +2402 +2398 +2433 +2326 +2395 +2416 +2391 +2375 +2454 +2410 +2384 +2415 +2395 +2397 +2395 +2412 +2378 +2403 +2397 +2389 +2416 +2393 +2352 +2378 +2394 +2399 +2395 +2374 +2418 +2382 +2406 +2395 +2401 +2416 +2407 +2434 +2352 +2419 +2397 +2403 +2449 +2404 +2352 +2409 +2411 +2403 +2382 +2311 +2314 +2365 +2400 +2404 +2417 +2422 +2416 +2405 +2416 +2411 +2402 +2429 +2406 +2416 +2416 +2490 +2462 +2416 +2405 +2416 +2355 +2450 +2420 +2414 +2342 +2402 +2337 +2538 +2386 +2519 +2416 +2419 +2417 +2416 +2416 +2395 +2329 +2411 +2416 +2390 +2399 +2427 +2418 +2406 +2421 +2417 +2407 +2396 +2417 +2401 +2411 +2406 +2354 +2397 +2412 +2415 +2419 +2416 +2350 +2409 +2417 +2400 +2405 +2402 +2410 +2389 +2415 +2406 +2416 +2388 +2406 +2419 +2450 +2432 +2416 +2427 +2413 +2418 +2413 +2324 +2341 +2390 +2494 +2427 +2420 +2414 +2422 +2417 +2421 +2397 +2399 +2427 +2373 +2416 +2419 +2422 +2419 +2416 +2415 +2428 +2420 +2434 +2368 +2447 +2430 +2388 +2403 +2413 +2433 +2423 +2416 +2422 +2416 +2415 +2431 +2434 +2415 +2402 +2421 +2431 +2409 +2420 +2416 +2423 +2435 +2418 +2412 +2419 +2412 +2395 +2411 +2437 +2410 +2415 +2432 +2417 +2399 +2417 +2416 +2420 +2427 +2489 +2416 +2482 +2422 +2414 +2415 +2416 +2432 +2514 +2411 +2380 +2418 +2399 +2411 +2423 +2415 +2414 +2411 +2421 +2439 +2432 +2465 +2430 +2483 +2416 +2410 +2416 +2416 +2437 +2415 +2416 +2449 +2417 +2425 +2417 +2458 +2351 +2422 +2431 +2400 +2419 +2426 +2423 +2421 +2431 +2416 +2442 +2425 +2403 +2421 +2419 +2462 +2430 +2423 +2416 +2431 +2441 +2439 +2432 +2437 +2421 +2510 +2426 +2421 +2432 +2406 +2427 +2414 +2396 +2480 +2461 +2427 +2352 +2418 +2421 +2445 +2423 +2441 +2437 +2416 +2419 +2425 +2427 +2433 +2425 +2435 +2431 +2414 +2424 +2432 +2433 +2421 +2425 +2430 +2425 +2374 +2385 +2434 +2418 +2401 +2423 +2416 +2607 +2439 +2427 +2479 +2416 +2448 +2359 +2429 +2405 +2429 +2430 +2435 +2460 +2460 +2430 +2423 +2433 +2416 +2416 +2421 +2448 +2429 +2448 +2512 +2431 +2420 +2402 +2429 +2455 +2423 +2423 +2434 +2421 +2432 +2415 +2443 +2426 +2435 +2371 +2417 +2421 +2430 +2439 +2434 +2434 +2431 +2423 +2422 +2408 +2432 +2433 +2428 +2435 +2475 +2427 +2426 +2469 +2413 +2440 +2457 +2420 +2438 +2439 +2441 +2443 +2429 +2416 +2444 +2480 +2427 +2429 +2433 +2450 +2427 +2416 +2433 +2424 +2447 +2432 +2422 +2403 +2423 +2433 +2414 +2516 +2414 +2435 +2431 +2393 +2433 +2428 +2441 +2434 +2362 +2429 +2434 +2445 +2434 +2432 +2400 +2431 +2442 +2426 +2435 +2429 +2433 +2420 +2435 +2416 +2416 +2441 +2494 +2363 +2443 +2399 +2434 +2439 +2533 +2423 +2438 +2433 +2453 +2426 +2466 +2448 +2430 +2435 +2534 +2436 +2439 +2445 +2443 +2438 +2442 +2435 +2539 +2434 +2431 +2427 +2422 +2430 +2441 +2438 +2420 +2443 +2436 +2429 +2436 +2435 +2443 +2444 +2447 +2438 +2433 +2459 +2440 +2446 +2437 +2418 +2445 +2486 +2444 +2432 +2459 +2447 +2449 +2449 +2439 +2470 +2439 +2438 +2419 +2436 +2439 +2438 +2448 +2450 +2448 +2439 +2436 +2453 +2419 +2416 +2447 +2447 +2447 +2418 +2476 +2447 +2442 +2447 +2433 +2439 +2426 +2439 +2432 +2433 +2369 +2442 +2445 +2459 +2478 +2407 +2447 +2384 +2477 +2443 +2446 +2437 +2459 +2441 +2442 +2448 +2483 +2439 +2387 +2442 +2403 +2454 +2433 +2437 +2421 +2438 +2439 +2442 +2430 +2585 +2440 +2450 +2441 +2413 +2450 +2427 +2444 +2450 +2459 +2445 +2469 +2423 +2429 +2446 +2441 +2477 +2448 +2445 +2448 +2434 +2460 +2448 +2431 +2431 +2395 +2431 +2444 +2416 +2442 +2439 +2445 +2448 +2438 +2448 +2443 +2480 +2432 +2439 +2448 +2384 +2344 +2438 +2404 +2446 +2448 +2602 +2445 +2446 +2443 +2440 +2461 +2448 +2448 +2447 +2448 +2461 +2438 +2461 +2448 +2516 +2441 +2464 +2347 +2448 +2473 +2446 +2460 +2462 +2455 +2459 +2448 +2435 +2437 +2448 +2432 +2434 +2453 +2425 +2443 +2432 +2439 +2412 +2454 +2465 +2504 +2455 +2446 +2351 +2447 +2448 +2469 +2448 +2486 +2473 +2466 +2465 +2448 +2445 +2455 +2434 +2449 +2448 +2385 +2460 +2446 +2466 +2454 +2405 +2449 +2448 +2378 +2449 +2435 +2453 +2442 +2450 +2450 +2451 +2469 +2448 +2458 +2465 +2462 +2461 +2552 +2351 +2496 +2448 +2411 +2453 +2469 +2453 +2557 +2471 +2470 +2389 +2489 +2448 +2449 +2448 +2451 +2454 +2448 +2452 +2455 +2461 +2451 +2459 +2438 +2448 +2356 +2443 +2466 +2491 +2406 +2448 +2465 +2459 +2462 +2505 +2454 +2442 +2443 +2474 +2457 +2451 +2471 +2471 +2459 +2529 +2453 +2384 +2453 +2442 +2451 +2435 +2457 +2437 +2454 +2413 +2450 +2448 +2450 +2446 +2448 +2469 +2480 +2369 +2457 +2458 +2468 +2448 +2438 +2452 +2445 +2442 +2453 +2513 +2454 +2463 +2457 +2448 +2373 +2458 +2496 +2458 +2453 +2428 +2462 +2459 +2451 +2450 +2461 +2448 +2463 +2448 +2459 +2464 +2442 +2448 +2453 +2448 +2455 +2496 +2463 +2457 +2459 +2453 +2496 +2459 +2450 +2465 +2463 +2473 +2473 +2472 +2391 +2469 +2444 +2455 +2400 +2490 +2496 +2458 +2459 +2452 +2443 +2421 +2387 +2463 +2390 +2426 +2489 +2451 +2455 +2480 +2470 +2466 +2476 +2469 +2458 +2497 +2448 +2385 +2454 +2462 +2464 +2453 +2455 +2458 +2461 +2471 +2464 +2454 +2454 +2481 +2527 +2544 +2449 +2468 +2480 +2423 +2459 +2476 +2521 +2491 +2479 +2451 +2435 +2461 +2460 +2458 +2434 +2447 +2465 +2559 +2451 +2451 +2461 +2436 +2448 +2475 +2465 +2477 +2473 +2448 +2470 +2470 +2458 +2467 +2452 +2463 +2403 +2459 +2475 +2475 +2374 +2466 +2489 +2493 +2463 +2454 +2397 +2464 +2461 +2467 +2462 +2455 +2447 +2543 +2467 +2481 +2483 +2481 +2383 +2469 +2479 +2474 +2469 +2462 +2380 +2458 +2595 +2416 +2458 +2463 +2480 +2466 +2551 +2479 +2466 +2445 +2487 +2598 +2478 +2478 +2480 +2467 +2473 +2475 +2449 +2468 +2479 +2462 +2462 +2473 +2463 +2468 +2508 +2467 +2497 +2470 +2471 +2469 +2423 +2448 +2489 +2461 +2463 +2555 +2465 +2480 +2480 +2453 +2471 +2465 +2476 +2480 +2458 +2476 +2464 +2479 +2480 +2423 +2453 +2384 +2477 +2475 +2450 +2487 +2473 +2473 +2398 +2466 +2474 +2413 +2492 +2498 +2501 +2477 +2496 +2494 +2463 +2473 +2448 +2480 +2481 +2502 +2478 +2479 +2480 +2485 +2467 +2533 +2478 +2477 +2479 +2434 +2487 +2489 +2493 +2467 +2483 +2480 +2442 +2478 +2467 +2479 +2467 +2469 +2482 +2467 +2480 +2466 +2482 +2448 +2462 +2475 +2480 +2480 +2480 +2417 +2462 +2455 +2474 +2479 +2465 +2500 +2477 +2478 +2597 +2465 +2477 +2463 +2470 +2495 +2475 +2458 +2471 +2483 +2474 +2433 +2470 +2471 +2471 +2475 +2467 +2469 +2486 +2471 +2477 +2481 +2485 +2419 +2481 +2460 +2471 +2479 +2499 +2490 +2463 +2480 +2494 +2489 +2469 +2485 +2480 +2479 +2416 +2489 +2482 +2451 +2484 +2497 +2512 +2485 +2487 +2420 +2484 +2497 +2483 +2483 +2579 +2473 +2554 +2466 +2506 +2482 +2474 +2502 +2481 +2453 +2478 +2374 +2448 +2490 +2495 +2500 +2503 +2528 +2474 +2502 +2480 +2473 +2480 +2487 +2480 +2483 +2493 +2480 +2467 +2407 +2485 +2503 +2480 +2484 +2489 +2480 +2479 +2482 +2502 +2506 +2480 +2487 +2463 +2486 +2471 +2493 +2490 +2544 +2486 +2478 +2479 +2480 +2496 +2483 +2485 +2481 +2483 +2491 +2474 +2480 +2486 +2481 +2475 +2487 +2502 +2484 +2492 +2510 +2495 +2464 +2493 +2498 +2482 +2474 +2496 +2495 +2526 +2498 +2496 +2485 +2500 +2467 +2461 +2466 +2503 +2494 +2517 +2427 +2510 +2483 +2487 +2480 +2455 +2505 +2626 +2483 +2485 +2495 +2493 +2487 +2544 +2478 +2498 +2487 +2479 +2496 +2480 +2550 +2471 +2501 +2480 +2506 +2481 +2496 +2504 +2482 +2491 +2495 +2418 +2494 +2491 +2493 +2493 +2496 +2526 +2492 +2490 +2486 +2486 +2470 +2418 +2496 +2490 +2510 +2490 +2472 +2503 +2480 +2482 +2330 +2530 +2495 +2486 +2603 +2478 +2485 +2490 +2519 +2501 +2489 +2502 +2497 +2419 +2486 +2482 +2500 +2503 +2493 +2537 +2497 +2516 +2496 +2496 +2495 +2508 +2443 +2490 +2502 +2559 +2496 +2487 +2499 +2516 +2491 +2497 +2494 +2497 +2483 +2497 +2497 +2532 +2515 +2512 +2500 +2501 +2491 +2499 +2493 +2501 +2509 +2505 +2501 +2503 +2503 +2522 +2512 +2635 +2493 +2506 +2508 +2487 +2496 +2465 +2512 +2496 +2425 +2499 +2479 +2503 +2503 +2498 +2494 +2505 +2512 +2652 +2480 +2528 +2493 +2503 +2581 +2501 +2489 +2509 +2384 +2515 +2503 +2509 +2506 +2512 +2515 +2516 +2502 +2559 +2514 +2506 +2517 +2511 +2610 +2515 +2498 +2499 +2458 +2511 +2521 +2513 +2496 +2507 +2544 +2507 +2528 +2501 +2559 +2491 +2515 +2489 +2496 +2517 +2509 +2485 +2512 +2461 +2503 +2502 +2457 +2513 +2531 +2499 +2495 +2502 +2499 +2506 +2511 +2416 +2510 +2529 +2506 +2503 +2494 +2499 +2512 +2497 +2506 +2498 +2512 +2499 +2507 +2496 +2507 +2512 +2518 +2521 +2506 +2475 +2509 +2513 +2605 +2505 +2495 +2509 +2501 +2503 +2481 +2511 +2511 +2503 +2499 +2506 +2375 +2505 +2505 +2506 +2543 +2533 +2501 +2593 +2499 +2608 +2512 +2510 +2516 +2510 +2501 +2505 +2512 +2512 +2512 +2506 +2507 +2500 +2416 +2512 +2509 +2512 +2451 +2523 +2502 +2500 +2457 +2515 +2496 +2513 +2506 +2534 +2585 +2599 +2512 +2498 +2506 +2523 +2505 +2503 +2509 +2535 +2513 +2517 +2471 +2537 +2502 +2512 +2503 +2379 +2494 +2502 +2514 +2512 +2518 +2512 +2507 +2511 +2501 +2448 +2587 +2507 +2512 +2405 +2506 +2493 +2507 +2496 +2507 +2512 +2505 +2510 +2525 +2506 +2531 +2506 +2498 +2501 +2517 +2493 +2514 +2511 +2515 +2516 +2512 +2497 +2512 +2641 +2529 +2503 +2518 +2492 +2513 +2512 +2450 +2515 +2489 +2507 +2496 +2508 +2512 +2499 +2504 +2404 +2523 +2593 +2515 +2513 +2516 +2511 +2509 +2511 +2496 +2512 +2529 +2529 +2512 +2518 +2524 +2505 +2464 +2512 +2507 +2513 +2559 +2511 +2491 +2514 +2516 +2523 +2448 +2519 +2517 +2502 +2512 +2513 +2589 +2539 +2503 +2517 +2533 +2510 +2559 +2527 +2512 +2506 +2653 +2505 +2515 +2511 +2512 +2517 +2528 +2509 +2518 +2501 +2512 +2508 +2482 +2525 +2435 +2531 +2512 +2495 +2463 +2513 +2516 +2448 +2542 +2529 +2507 +2507 +2512 +2527 +2507 +2516 +2512 +2530 +2497 +2512 +2509 +2513 +2519 +2473 +2512 +2529 +2521 +2513 +2517 +2517 +2517 +2662 +2523 +2522 +2530 +2513 +2516 +2514 +2540 +2526 +2517 +2515 +2524 +2512 +2512 +2512 +2534 +2527 +2514 +2531 +2528 +2518 +2519 +2537 +2477 +2508 +2542 +2535 +2610 +2522 +2528 +2507 +2593 +2532 +2522 +2521 +2510 +2526 +2529 +2559 +2545 +2513 +2508 +2522 +2559 +2532 +2608 +2518 +2523 +2512 +2502 +2439 +2502 +2535 +2511 +2538 +2526 +2526 +2513 +2588 +2541 +2496 +2511 +2527 +2515 +2551 +2544 +2515 +2591 +2486 +2511 +2546 +2548 +2497 +2519 +2448 +2517 +2516 +2559 +2524 +2507 +2509 +2528 +2512 +2521 +2529 +2519 +2498 +2496 +2518 +2701 +2546 +2525 +2528 +2512 +2531 +2518 +2511 +2487 +2532 +2481 +2525 +2527 +2501 +2514 +2559 +2526 +2529 +2502 +2539 +2515 +2514 +2515 +2542 +2519 +2522 +2543 +2531 +2538 +2540 +2512 +2533 +2532 +2519 +2522 +2515 +2523 +2518 +2530 +2535 +2517 +2534 +2525 +2537 +2538 +2531 +2462 +2537 +2492 +2433 +2528 +2512 +2523 +2512 +2519 +2555 +2508 +2543 +2527 +2583 +2527 +2526 +2533 +2502 +2553 +2542 +2551 +2577 +2522 +2559 +2544 +2454 +2480 +2530 +2529 +2512 +2519 +2524 +2530 +2511 +2533 +2469 +2513 +2509 +2512 +2531 +2538 +2523 +2531 +2499 +2512 +2523 +2513 +2524 +2524 +2535 +2541 +2537 +2542 +2514 +2544 +2555 +2531 +2506 +2529 +2515 +2523 +2544 +2463 +2528 +2590 +2535 +2559 +2538 +2535 +2545 +2531 +2529 +2535 +2609 +2543 +2555 +2555 +2531 +2553 +2544 +2528 +2535 +2529 +2530 +2526 +2544 +2514 +2528 +2515 +2535 +2553 +2542 +2529 +2531 +2498 +2541 +2466 +2529 +2495 +2541 +2586 +2543 +2526 +2482 +2531 +2537 +2544 +2521 +2525 +2540 +2527 +2536 +2540 +2518 +2530 +2526 +2544 +2517 +2526 +2539 +2531 +2529 +2535 +2528 +2538 +2543 +2531 +2545 +2533 +2529 +2529 +2533 +2533 +2537 +2542 +2543 +2541 +2544 +2537 +2489 +2595 +2542 +2521 +2518 +2613 +2554 +2544 +2529 +2544 +2559 +2535 +2540 +2538 +2544 +2534 +2548 +2535 +2537 +2593 +2525 +2559 +2530 +2541 +2640 +2535 +2532 +2549 +2531 +2535 +2544 +2529 +2555 +2513 +2559 +2544 +2543 +2559 +2555 +2526 +2559 +2537 +2545 +2544 +2544 +2544 +2480 +2547 +2517 +2537 +2559 +2531 +2559 +2541 +2462 +2586 +2538 +2534 +2545 +2457 +2539 +2543 +2544 +2544 +2533 +2559 +2542 +2687 +2533 +2512 +2555 +2549 +2645 +2535 +2544 +2545 +2535 +2549 +2541 +2448 +2585 +2543 +2544 +2554 +2545 +2557 +2581 +2555 +2556 +2554 +2557 +2544 +2551 +2539 +2607 +2555 +2551 +2610 +2544 +2546 +2605 +2531 +2550 +2552 +2494 +2557 +2541 +2523 +2528 +2547 +2548 +2544 +2505 +2550 +2539 +2539 +2540 +2521 +2547 +2541 +2544 +2543 +2535 +2546 +2537 +2467 +2539 +2544 +2516 +2544 +2559 +2533 +2547 +2538 +2559 +2545 +2542 +2538 +2559 +2528 +2545 +2549 +2551 +2559 +2534 +2486 +2559 +2559 +2551 +2544 +2457 +2542 +2519 +2538 +2543 +2548 +2530 +2544 +2532 +2545 +2544 +2557 +2526 +2550 +2554 +2678 +2559 +2544 +2528 +2539 +2535 +2538 +2539 +2555 +2506 +2531 +2549 +2555 +2559 +2559 +2554 +2557 +2543 +2549 +2555 +2559 +2510 +2549 +2543 +2544 +2538 +2554 +2549 +2541 +2559 +2539 +2460 +2544 +2547 +2553 +2559 +2555 +2550 +2550 +2479 +2496 +2528 +2543 +2527 +2537 +2554 +2557 +2556 +2542 +2518 +2543 +2599 +2544 +2545 +2551 +2547 +2559 +2553 +2549 +2519 +2544 +2466 +2557 +2544 +2686 +2559 +2559 +2554 +2557 +2555 +2556 +2559 +2449 +2592 +2559 +2541 +2544 +2519 +2550 +2640 +2525 +2559 +2559 +2559 +2559 +2559 +2550 +2559 +2582 +2559 +2559 +2544 +2550 +2544 +2545 +2555 +2559 +2559 +2544 +2559 +2614 +2547 +2608 +2553 +2534 +2559 +2555 +2559 +2522 +2547 +2559 +2559 +2555 +2586 +2557 +2559 +2559 +2537 +2519 +2558 +2554 +2546 +2544 +2558 +2528 +2550 +2496 +2534 +2467 +2550 +2558 +2544 +2558 +2559 +2546 +2557 +2545 +2490 +2546 +2545 +2549 +2559 +2552 +2559 +2547 +2547 +2559 +2557 +2546 +2544 +2550 +2474 +2544 +2549 +2587 +2544 +2551 +2597 +2559 +2512 +2555 +2559 +2556 +2545 +2559 +2558 +2559 +2547 +2626 +2469 +2559 +2431 +2559 +2558 +2546 +2543 +2448 +2548 +2601 +2550 +2545 +2549 +2543 +2559 +2501 +2559 +2559 +2554 +2559 +2613 +2559 +2559 +2559 +2559 +2543 +2559 +2549 +2559 +2559 +2559 +2554 +2559 +2546 +2559 +2559 +2581 +2611 +2544 +2557 +2579 +2559 +2559 +2555 +2559 +2540 +2555 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2614 +2511 +2624 +2559 +2544 +2559 +2559 +2591 +2580 +2555 +2544 +2544 +2599 +2559 +2507 +2543 +2545 +2559 +2559 +2559 +2580 +2559 +2559 +2559 +2581 +2559 +2559 +2559 +2548 +2559 +2559 +2559 +2559 +2559 +2608 +2606 +2559 +2554 +2559 +2559 +2555 +2549 +2551 +2529 +2547 +2455 +2558 +2523 +2602 +2549 +2558 +2550 +2558 +2559 +2559 +2556 +2559 +2559 +2559 +2557 +2559 +2559 +2559 +2491 +2559 +2559 +2559 +2559 +2589 +2512 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2554 +2524 +2559 +2555 +2502 +2545 +2547 +2559 +2581 +2558 +2559 +2581 +2555 +2673 +2540 +2559 +2558 +2559 +2596 +2587 +2553 +2559 +2556 +2603 +2519 +2552 +2559 +2559 +2559 +2559 +2590 +2554 +2557 +2559 +2559 +2547 +2559 +2586 +2554 +2482 +2559 +2559 +2611 +2583 +2559 +2587 +2559 +2559 +2559 +2541 +2559 +2583 +2558 +2559 +2559 +2559 +2559 +2559 +2494 +2559 +2559 +2551 +2512 +2559 +2559 +2594 +2559 +2587 +2503 +2581 +2559 +2559 +2559 +2559 +2559 +2559 +2548 +2545 +2559 +2602 +2559 +2559 +2559 +2591 +2559 +2487 +2559 +2559 +2539 +2559 +2559 +2559 +2589 +2604 +2559 +2583 +2587 +2583 +2556 +2736 +2586 +2591 +2587 +2539 +2585 +2559 +2559 +2559 +2604 +2513 +2559 +2583 +2559 +2583 +2558 +2599 +2582 +2559 +2555 +2605 +2559 +2590 +2527 +2559 +2499 +2559 +2559 +2559 +2559 +2613 +2559 +2559 +2591 +2559 +2590 +2559 +2559 +2590 +2581 +2558 +2579 +2724 +2593 +2583 +2622 +2559 +2559 +2582 +2559 +2583 +2559 +2559 +2608 +2609 +2559 +2557 +2608 +2582 +2593 +2581 +2589 +2704 +2591 +2559 +2559 +2533 +2587 +2593 +2559 +2503 +2618 +2593 +2592 +2559 +2556 +2559 +2585 +2559 +2589 +2549 +2582 +2614 +2622 +2559 +2559 +2551 +2559 +2559 +2693 +2607 +2581 +2583 +2617 +2559 +2559 +2559 +2559 +2598 +2559 +2587 +2583 +2559 +2704 +2581 +2585 +2591 +2581 +2592 +2559 +2589 +2588 +2582 +2512 +2622 +2524 +2559 +2586 +2559 +2555 +2592 +2554 +2583 +2559 +2605 +2559 +2559 +2610 +2583 +2579 +2559 +2592 +2559 +2597 +2559 +2559 +2559 +2603 +2586 +2559 +2590 +2589 +2591 +2559 +2534 +2585 +2581 +2606 +2559 +2535 +2602 +2582 +2628 +2587 +2587 +2597 +2559 +2559 +2587 +2591 +2608 +2583 +2592 +2588 +2590 +2602 +2625 +2597 +2559 +2587 +2559 +2619 +2614 +2604 +2630 +2598 +2594 +2590 +2553 +2595 +2603 +2583 +2546 +2608 +2590 +2559 +2559 +2624 +2581 +2581 +2559 +2559 +2608 +2587 +2592 +2585 +2582 +2593 +2590 +2559 +2588 +2619 +2583 +2593 +2544 +2559 +2604 +2595 +2557 +2647 +2559 +2582 +2589 +2583 +2588 +2579 +2593 +2590 +2588 +2582 +2582 +2559 +2586 +2590 +2595 +2592 +2501 +2559 +2619 +2591 +2585 +2583 +2559 +2559 +2608 +2559 +2559 +2598 +2539 +2601 +2559 +2621 +2559 +2559 +2689 +2585 +2559 +2609 +2605 +2553 +2589 +2608 +2559 +2581 +2593 +2581 +2642 +2594 +2589 +2597 +2592 +2623 +2608 +2592 +2622 +2599 +2599 +2601 +2585 +2559 +2587 +2524 +2585 +2582 +2559 +2582 +2559 +2585 +2594 +2624 +2609 +2587 +2589 +2559 +2582 +2608 +2599 +2608 +2585 +2584 +2590 +2598 +2503 +2648 +2559 +2610 +2597 +2602 +2559 +2592 +2505 +2597 +2559 +2599 +2591 +2559 +2588 +2559 +2593 +2601 +2598 +2591 +2559 +2608 +2559 +2535 +2595 +2611 +2589 +2591 +2592 +2594 +2755 +2602 +2591 +2601 +2604 +2608 +2559 +2599 +2590 +2624 +2598 +2608 +2615 +2607 +2599 +2612 +2599 +2600 +2599 +2587 +2492 +2602 +2607 +2602 +2592 +2608 +2608 +2594 +2592 +2559 +2602 +2589 +2521 +2594 +2624 +2521 +2624 +2687 +2595 +2592 +2590 +2588 +2507 +2608 +2527 +2603 +2601 +2496 +2602 +2624 +2559 +2599 +2598 +2587 +2587 +2595 +2598 +2586 +2611 +2595 +2595 +2599 +2606 +2589 +2745 +2615 +2587 +2599 +2715 +2603 +2710 +2599 +2559 +2653 +2594 +2595 +2545 +2653 +2607 +2599 +2597 +2583 +2590 +2599 +2595 +2619 +2554 +2587 +2559 +2513 +2589 +2590 +2559 +2607 +2607 +2598 +2606 +2559 +2587 +2559 +2624 +2608 +2602 +2595 +2691 +2592 +2613 +2598 +2609 +2608 +2595 +2559 +2512 +2605 +2603 +2590 +2591 +2597 +2602 +2601 +2519 +2586 +2593 +2587 +2588 +2586 +2603 +2595 +2602 +2559 +2609 +2603 +2559 +2596 +2599 +2594 +2602 +2704 +2624 +2591 +2617 +2600 +2477 +2598 +2622 +2600 +2604 +2559 +2602 +2596 +2586 +2583 +2593 +2590 +2608 +2608 +2608 +2593 +2582 +2608 +2596 +2593 +2609 +2597 +2587 +2599 +2559 +2613 +2580 +2604 +2596 +2589 +2531 +2608 +2595 +2607 +2603 +2597 +2606 +2602 +2610 +2541 +2614 +2552 +2672 +2603 +2674 +2598 +2599 +2599 +2559 +2608 +2608 +2607 +2608 +2607 +2624 +2610 +2608 +2597 +2603 +2606 +2596 +2606 +2615 +2604 +2589 +2606 +2609 +2605 +2607 +2608 +2609 +2607 +2583 +2550 +2607 +2603 +2716 +2608 +2559 +2595 +2600 +2624 +2607 +2595 +2609 +2608 +2599 +2619 +2695 +2559 +2603 +2622 +2595 +2589 +2603 +2606 +2742 +2608 +2606 +2620 +2603 +2608 +2618 +2601 +2608 +2610 +2601 +2606 +2604 +2601 +2601 +2613 +2602 +2619 +2609 +2609 +2448 +2607 +2608 +2597 +2607 +2601 +2606 +2611 +2595 +2606 +2624 +2624 +2611 +2607 +2597 +2592 +2595 +2591 +2612 +2621 +2621 +2619 +2607 +2595 +2539 +2614 +2609 +2626 +2589 +2611 +2615 +2603 +2559 +2615 +2622 +2615 +2599 +2611 +2547 +2615 +2587 +2613 +2608 +2619 +2621 +2554 +2611 +2599 +2623 +2599 +2616 +2614 +2607 +2613 +2617 +2559 +2626 +2597 +2608 +2608 +2625 +2597 +2613 +2608 +2617 +2613 +2595 +2608 +2608 +2624 +2640 +2619 +2524 +2537 +2619 +2619 +2615 +2608 +2614 +2609 +2610 +2603 +2610 +2512 +2609 +2598 +2626 +2559 +2613 +2609 +2701 +2605 +2615 +2608 +2619 +2637 +2598 +2583 +2625 +2603 +2590 +2608 +2587 +2605 +2612 +2622 +2643 +2612 +2610 +2609 +2619 +2611 +2599 +2619 +2621 +2594 +2614 +2639 +2615 +2608 +2603 +2630 +2615 +2632 +2585 +2630 +2619 +2615 +2608 +2598 +2608 +2601 +2615 +2625 +2615 +2625 +2612 +2736 +2644 +2586 +2619 +2510 +2595 +2617 +2614 +2611 +2614 +2619 +2608 +2697 +2609 +2627 +2637 +2606 +2608 +2605 +2612 +2610 +2599 +2627 +2605 +2619 +2594 +2609 +2621 +2622 +2657 +2627 +2614 +2627 +2623 +2608 +2606 +2594 +2559 +2624 +2607 +2667 +2724 +2608 +2615 +2613 +2537 +2605 +2611 +2627 +2669 +2605 +2609 +2585 +2606 +2604 +2625 +2613 +2607 +2619 +2624 +2598 +2631 +2610 +2665 +2618 +2608 +2637 +2613 +2609 +2630 +2704 +2642 +2606 +2611 +2620 +2734 +2590 +2624 +2603 +2611 +2618 +2611 +2607 +2620 +2615 +2617 +2549 +2614 +2595 +2591 +2736 +2634 +2627 +2608 +2608 +2612 +2686 +2607 +2610 +2606 +2624 +2585 +2647 +2612 +2608 +2610 +2640 +2594 +2607 +2559 +2611 +2621 +2623 +2596 +2627 +2613 +2613 +2607 +2611 +2559 +2538 +2665 +2608 +2614 +2618 +2624 +2608 +2586 +2624 +2614 +2608 +2615 +2612 +2624 +2625 +2610 +2611 +2608 +2619 +2734 +2611 +2644 +2608 +2630 +2640 +2608 +2625 +2611 +2589 +2615 +2602 +2624 +2618 +2615 +2559 +2619 +2623 +2621 +2614 +2615 +2618 +2635 +2624 +2625 +2642 +2622 +2635 +2557 +2630 +2599 +2624 +2595 +2615 +2608 +2624 +2619 +2608 +2614 +2623 +2642 +2608 +2617 +2618 +2618 +2635 +2615 +2627 +2615 +2625 +2607 +2624 +2555 +2624 +2608 +2613 +2622 +2640 +2627 +2615 +2626 +2623 +2634 +2623 +2623 +2549 +2611 +2617 +2640 +2605 +2621 +2622 +2613 +2629 +2645 +2620 +2621 +2624 +2623 +2710 +2591 +2621 +2612 +2641 +2631 +2625 +2619 +2626 +2620 +2619 +2783 +2640 +2582 +2592 +2559 +2625 +2614 +2637 +2608 +2624 +2608 +2640 +2559 +2622 +2622 +2625 +2631 +2631 +2631 +2640 +2636 +2637 +2558 +2639 +2617 +2743 +2631 +2647 +2616 +2645 +2625 +2633 +2647 +2605 +2552 +2609 +2624 +2613 +2559 +2640 +2623 +2624 +2612 +2619 +2545 +2610 +2625 +2627 +2628 +2644 +2619 +2626 +2624 +2624 +2607 +2626 +2614 +2690 +2631 +2630 +2624 +2623 +2634 +2635 +2622 +2615 +2625 +2623 +2607 +2607 +2610 +2630 +2635 +2559 +2817 +2639 +2705 +2758 +2619 +2603 +2607 +2609 +2625 +2608 +2641 +2641 +2624 +2581 +2615 +2593 +2630 +2629 +2614 +2615 +2608 +2628 +2618 +2721 +2619 +2608 +2614 +2657 +2544 +2609 +2641 +2637 +2633 +2582 +2305 +2654 +2617 +2608 +2524 +2624 +2622 +2640 +2631 +2624 +2635 +2651 +2608 +2639 +2608 +2628 +2624 +2629 +2629 +2624 +2632 +2639 +2641 +2613 +2608 +2631 +2643 +2624 +2630 +2638 +2622 +2626 +2628 +2612 +2608 +2624 +2726 +2624 +2617 +2641 +2629 +2557 +2626 +2636 +2651 +2559 +2626 +2601 +2629 +2614 +2599 +2631 +2643 +2601 +2635 +2633 +2630 +2628 +2706 +2629 +2634 +2764 +2631 +2627 +2617 +2639 +2637 +2593 +2638 +2630 +2631 +2634 +2609 +2634 +2649 +2608 +2635 +2625 +2627 +2559 +2638 +2637 +2677 +2631 +2559 +2627 +2636 +2546 +2624 +2603 +2628 +2607 +2681 +2559 +2640 +2619 +2629 +2633 +2531 +2646 +2623 +2631 +2640 +2634 +2626 +2637 +2671 +2620 +2679 +2617 +2639 +2559 +2624 +2623 +2637 +2624 +2651 +2613 +2633 +2639 +2589 +2663 +2619 +2615 +2500 +2631 +2414 +2608 +2609 +2615 +2624 +2624 +2641 +2622 +2591 +2635 +2647 +2625 +2623 +2627 +2663 +2614 +2655 +2603 +2593 +2635 +2633 +2648 +2639 +2624 +2800 +2636 +2637 +2749 +2621 +2636 +2770 +2625 +2622 +2633 +2671 +2640 +2636 +2631 +2618 +2615 +2635 +2631 +2663 +2630 +2587 +2630 +2638 +2641 +2640 +2630 +2506 +2633 +2559 +2628 +2647 +2639 +2597 +2608 +2630 +2598 +2638 +2609 +2633 +2542 +2631 +2637 +2636 +2647 +2640 +2624 +2670 +2627 +2633 +2874 +2629 +2642 +2638 +2637 +2645 +2639 +2647 +2625 +2637 +2639 +2652 +2640 +2640 +2558 +2672 +2641 +2583 +2635 +2636 +2635 +2612 +2634 +2639 +2613 +2631 +2617 +2639 +2624 +2644 +2639 +2763 +2634 +2662 +2559 +2624 +2507 +2645 +2647 +2638 +2588 +2630 +2629 +2645 +2593 +2615 +2634 +2633 +2628 +2545 +2627 +2663 +2634 +2627 +2641 +2621 +2642 +2628 +2635 +2640 +2627 +2640 +2626 +2614 +2608 +2640 +2646 +2623 +2635 +2640 +2621 +2623 +2615 +2642 +2645 +2643 +2665 +2642 +2634 +2640 +2641 +2640 +2640 +2634 +2635 +2640 +2632 +2618 +2559 +2633 +2631 +2627 +2638 +2639 +2642 +2667 +2551 +2687 +2629 +2613 +2640 +2655 +2626 +2632 +2640 +2554 +2625 +2512 +2640 +2634 +2632 +2630 +2636 +2663 +2623 +2633 +2644 +2559 +2625 +2630 +2651 +2641 +2642 +2639 +2640 +2631 +2633 +2634 +2636 +2624 +2639 +2622 +2641 +2640 +2643 +2634 +2643 +2628 +2613 +2636 +2644 +2544 +2647 +2640 +2642 +2653 +2541 +2631 +2652 +2641 +2633 +2630 +2559 +2646 +2663 +2641 +2756 +2608 +2640 +2642 +2638 +2639 +2630 +2637 +2638 +2655 +2655 +2644 +2623 +2635 +2656 +2623 +2655 +2651 +2647 +2627 +2630 +2640 +2638 +2642 +2627 +2653 +2636 +2641 +2641 +2626 +2626 +2717 +2544 +2641 +2642 +2639 +2754 +2649 +2656 +2639 +2621 +2640 +2605 +2559 +2633 +2636 +2644 +2640 +2624 +2645 +2635 +2624 +2647 +2640 +2631 +2634 +2550 +2625 +2701 +2625 +2639 +2644 +2667 +2667 +2632 +2628 +2624 +2639 +2618 +2634 +2646 +2647 +2633 +2640 +2635 +2642 +2657 +2633 +2590 +2643 +2626 +2641 +2638 +2654 +2643 +2640 +2646 +2611 +2629 +2642 +2634 +2559 +2694 +2639 +2650 +2640 +2620 +2637 +2646 +2645 +2641 +2641 +2642 +2644 +2639 +2669 +2620 +2636 +2660 +2663 +2755 +2592 +2640 +2640 +2635 +2624 +2637 +2640 +2640 +2633 +2619 +2647 +2643 +2627 +2618 +2629 +2642 +2636 +2636 +2641 +2643 +2640 +2657 +2611 +2626 +2641 +2624 +2643 +2654 +2639 +2640 +2656 +2635 +2640 +2637 +2647 +2645 +2671 +2644 +2637 +2622 +2638 +2639 +2641 +2641 +2716 +2631 +2639 +2649 +2637 +2640 +2626 +2651 +2668 +2646 +2646 +2645 +2640 +2653 +2640 +2640 +2634 +2646 +2641 +2646 +2640 +2649 +2653 +2663 +2645 +2653 +2631 +2646 +2656 +2661 +2753 +2701 +2655 +2645 +2647 +2672 +2655 +2656 +2693 +2655 +2659 +2649 +2646 +2653 +2640 +2652 +2653 +2640 +2640 +2659 +2670 +2647 +2650 +2654 +2621 +2639 +2646 +2630 +2657 +2638 +2642 +2647 +2672 +2665 +2684 +2640 +2661 +2647 +2643 +2667 +2656 +2650 +2798 +2641 +2667 +2656 +2639 +2637 +2651 +2644 +2642 +2626 +2637 +2646 +2652 +2627 +2651 +2637 +2642 +2642 +2661 +2641 +2657 +2640 +2591 +2634 +2640 +2651 +2713 +2800 +2640 +2645 +2646 +2645 +2559 +2644 +2646 +2653 +2645 +2640 +2652 +2554 +2654 +2647 +2640 +2640 +2643 +2657 +2659 +2657 +2643 +2653 +2663 +2629 +2602 +2602 +2661 +2683 +2661 +2640 +2651 +2654 +2537 +2647 +2641 +2669 +2642 +2755 +2668 +2651 +2637 +2628 +2624 +2640 +2646 +2652 +2647 +2681 +2636 +2645 +2627 +2648 +2636 +2628 +2650 +2645 +2648 +2640 +2651 +2654 +2645 +2654 +2653 +2656 +2653 +2559 +2646 +2634 +2642 +2651 +2611 +2663 +2657 +2639 +2640 +2659 +2665 +2640 +2640 +2645 +2559 +2627 +2695 +2640 +2645 +2658 +2640 +2649 +2655 +2653 +2646 +2662 +2647 +2640 +2647 +2641 +2644 +2672 +2659 +2669 +2659 +2647 +2710 +2637 +2656 +2667 +2662 +2652 +2672 +2653 +2635 +2651 +2702 +2663 +2642 +2647 +2678 +2665 +2663 +2645 +2643 +2640 +2649 +2655 +2656 +2653 +2658 +2682 +2662 +2627 +2653 +2643 +2636 +2731 +2640 +2662 +2674 +2635 +2662 +2641 +2626 +2640 +2655 +2622 +2647 +2645 +2640 +2672 +2655 +2586 +2649 +2655 +2626 +2657 +2645 +2674 +2671 +2647 +2657 +2667 +2629 +2640 +2647 +2651 +2743 +2677 +2640 +2657 +2650 +2661 +2666 +2650 +2656 +2550 +2643 +2663 +2643 +2644 +2641 +2688 +2592 +2646 +2559 +2635 +2659 +2651 +2649 +2659 +2661 +2643 +2647 +2647 +2647 +2651 +2655 +2631 +2661 +2658 +2640 +2642 +2585 +2669 +2650 +2647 +2650 +2640 +2599 +2652 +2663 +2655 +2649 +2611 +2666 +2662 +2671 +2668 +2649 +2656 +2646 +2632 +2657 +2661 +2672 +2634 +2629 +2653 +2639 +2644 +2723 +2659 +2671 +2694 +2653 +2653 +2651 +2653 +2647 +2658 +2648 +2643 +2667 +2650 +2657 +2634 +2743 +2655 +2663 +2641 +2666 +2652 +2559 +2637 +2688 +2643 +2643 +2646 +2657 +2651 +2636 +2640 +2664 +2640 +2669 +2646 +2657 +2677 +2667 +2668 +2642 +2655 +2646 +2673 +2683 +2656 +2670 +2652 +2660 +2669 +2654 +2656 +2653 +2659 +2672 +2649 +2653 +2646 +2650 +2653 +2672 +2653 +2658 +2591 +2624 +2663 +2654 +2661 +2648 +2651 +2672 +2667 +2652 +2657 +2655 +2662 +2666 +2606 +2686 +2615 +2642 +2656 +2655 +2647 +2627 +2658 +2643 +2671 +2694 +2639 +2655 +2645 +2642 +2635 +2636 +2555 +2656 +2645 +2651 +2659 +2598 +2556 +2606 +2635 +2634 +2674 +2642 +2655 +2649 +2643 +2649 +2645 +2659 +2647 +2669 +2559 +2635 +2660 +2658 +2673 +2674 +2655 +2653 +2653 +2658 +2665 +2639 +2642 +2621 +2657 +2643 +2637 +2670 +2786 +2653 +2645 +2655 +2665 +2654 +2607 +2637 +2666 +2608 +2656 +2636 +2667 +2652 +2657 +2669 +2683 +2637 +2621 +2652 +2674 +2675 +2649 +2645 +2657 +2638 +2582 +2652 +2632 +2679 +2672 +2641 +2651 +2682 +2672 +2666 +2629 +2654 +2657 +2677 +2672 +2672 +2750 +2654 +2663 +2738 +2640 +2480 +2768 +2641 +2707 +2665 +2676 +2682 +2672 +2649 +2659 +2663 +2653 +2670 +2628 +2667 +2659 +2654 +2665 +2658 +2659 +2660 +2634 +2654 +2661 +2623 +2661 +2653 +2656 +2674 +2653 +2633 +2655 +2657 +2559 +2655 +2646 +2639 +2663 +2663 +2672 +2677 +2653 +2654 +2689 +2672 +2643 +2665 +2654 +2668 +2671 +2656 +2646 +2656 +2651 +2559 +2672 +2657 +2656 +2662 +2635 +2667 +2650 +2651 +2636 +2687 +2655 +2647 +2605 +2704 +2654 +2649 +2681 +2663 +2786 +2659 +2656 +2657 +2626 +2656 +2656 +2634 +2663 +2730 +2682 +2647 +2646 +2635 +2656 +2644 +2666 +2652 +2644 +2653 +2651 +2643 +2640 +2643 +2650 +2665 +2609 +2653 +2655 +2662 +2665 +2679 +2655 +2656 +2655 +2661 +2695 +2668 +2658 +2678 +2656 +2622 +2649 +2646 +2662 +2655 +2653 +2641 +2644 +2663 +2667 +2664 +2642 +2646 +2619 +2658 +2672 +2661 +2656 +2658 +2653 +2743 +2672 +2649 +2666 +2676 +2645 +2642 +2671 +2672 +2658 +2648 +2587 +2663 +2646 +2647 +2652 +2655 +2642 +2672 +2654 +2653 +2684 +2608 +2663 +2661 +2672 +2626 +2781 +2659 +2658 +2663 +2606 +2646 +2650 +2658 +2642 +2665 +2661 +2662 +2663 +2675 +2663 +2663 +2663 +2716 +2625 +2639 +2643 +2663 +2635 +2637 +2663 +2657 +2688 +2663 +2693 +2702 +2640 +2662 +2655 +2635 +2719 +2658 +2653 +2658 +2559 +2671 +2640 +2663 +2666 +2646 +2640 +2674 +2663 +2651 +2621 +2691 +2661 +2673 +2651 +2659 +2640 +2666 +2662 +2658 +2640 +2647 +2620 +2662 +2650 +2608 +2675 +2690 +2672 +2650 +2634 +2656 +2659 +2615 +2635 +2653 +2661 +2622 +2662 +2674 +2669 +2656 +2650 +2667 +2676 +2671 +2654 +2654 +2657 +2661 +2696 +2667 +2673 +2654 +2635 +2672 +2654 +2662 +2652 +2653 +2636 +2672 +2759 +2623 +2649 +2667 +2630 +2693 +2701 +2672 +2655 +2651 +2641 +2611 +2661 +2640 +2639 +2653 +2667 +2631 +2646 +2663 +2643 +2667 +2655 +2720 +2717 +2671 +2653 +2658 +2622 +2559 +2657 +2704 +2651 +2663 +2649 +2666 +2693 +2645 +2658 +2634 +2657 +2665 +2625 +2658 +2642 +2657 +2654 +2657 +2659 +2734 +2602 +2647 +2659 +2641 +2615 +2655 +2671 +2663 +2651 +2650 +2599 +2654 +2667 +2695 +2663 +2708 +2640 +2688 +2667 +2672 +2671 +2669 +2682 +2659 +2630 +2665 +2701 +2660 +2681 +2673 +2657 +2666 +2671 +2558 +2658 +2660 +2646 +2658 +2641 +2611 +2757 +2629 +2651 +2655 +2610 +2661 +2653 +2674 +2656 +2621 +2677 +2667 +2608 +2663 +2666 +2639 +2655 +2662 +2790 +2658 +2658 +2640 +2677 +2654 +2700 +2669 +2647 +2640 +2655 +2685 +2631 +2595 +2659 +2656 +2663 +2671 +2655 +2633 +2670 +2594 +2615 +2662 +2676 +2655 +2669 +2656 +2658 +2653 +2665 +2659 +2671 +2658 +2653 +2667 +2653 +2669 +2657 +2661 +2647 +2656 +2629 +2650 +2765 +2659 +2769 +2653 +2640 +2645 +2671 +2645 +2699 +2656 +2646 +2662 +2658 +2659 +2657 +2652 +2646 +2658 +2650 +2661 +2707 +2559 +2665 +2788 +2666 +2590 +2653 +2668 +2640 +2605 +2661 +2640 +2669 +2648 +2624 +2635 +2646 +2661 +2658 +2683 +2661 +2647 +2663 +2662 +2631 +2672 +2661 +2660 +2670 +2651 +2670 +2653 +2658 +2665 +2654 +2671 +2672 +2688 +2655 +2637 +2647 +2661 +2661 +2659 +2659 +2679 +2688 +2686 +2659 +2666 +2655 +2623 +2681 +2672 +2663 +2659 +2659 +2665 +2675 +2637 +2665 +2688 +2652 +2704 +2626 +2607 +2656 +2667 +2671 +2665 +2647 +2650 +2670 +2644 +2671 +2629 +2651 +2640 +2639 +2649 +2661 +2656 +2640 +2580 +2663 +2671 +2688 +2655 +2650 +2647 +2653 +2662 +2662 +2716 +2659 +2611 +2669 +2652 +2657 +2660 +2672 +2667 +2639 +2645 +2640 +2676 +2654 +2643 +2662 +2684 +2672 +2669 +2666 +2714 +2659 +2654 +2659 +2666 +2663 +2672 +2658 +2641 +2661 +2740 +2659 +2658 +2673 +2655 +2659 +2667 +2656 +2737 +2655 +2665 +2660 +2655 +2620 +2657 +2667 +2655 +2662 +2586 +2654 +2662 +2670 +2665 +2661 +2663 +2656 +2655 +2663 +2668 +2651 +2677 +2660 +2654 +2638 +2661 +2674 +2643 +2642 +2654 +2667 +2652 +2679 +2674 +2649 +2647 +2662 +2683 +2643 +2734 +2673 +2651 +2559 +2666 +2662 +2654 +2650 +2661 +2653 +2657 +2649 +2662 +2656 +2659 +2669 +2658 +2703 +2662 +2735 +2675 +2640 +2678 +2666 +2655 +2655 +2671 +2780 +2665 +2661 +2657 +2654 +2623 +2602 +2652 +2672 +2662 +2648 +2722 +2663 +2655 +2644 +2666 +2607 +2624 +2667 +2655 +2678 +2448 +2659 +2670 +2559 +2655 +2635 +2668 +2668 +2672 +2685 +2589 +2661 +2663 +2666 +2678 +2677 +2646 +2649 +2657 +2651 +2647 +2663 +2645 +2646 +2653 +2662 +2579 +2670 +2653 +2645 +2646 +2650 +2649 +2544 +2647 +2690 +2655 +2654 +2590 +2591 +2657 +2667 +2661 +2639 +2679 +2659 +2646 +2418 +2671 +2640 +2669 +2651 +2663 +2629 +2654 +2665 +2640 +2675 +2661 +2669 +2666 +2659 +2673 +2657 +2659 +2671 +2658 +2666 +2671 +2653 +2658 +2654 +2693 +2655 +2655 +2722 +2656 +2667 +2659 +2672 +2661 +2667 +2655 +2663 +2819 +2655 +2669 +2655 +2658 +2663 +2643 +2675 +2661 +2653 +2661 +2702 +2657 +2658 +2634 +2640 +2727 +2661 +2663 +2666 +2667 +2663 +2663 +2657 +2676 +2658 +2625 +2657 +2644 +2635 +2659 +2646 +2669 +2669 +2706 +2647 +2659 +2653 +2688 +2651 +2659 +2658 +2642 +2663 +2658 +2658 +2668 +2666 +2669 +2653 +2666 +2652 +2672 +2662 +2670 +2640 +2651 +2673 +2657 +2657 +2589 +2658 +2655 +2661 +2663 +2654 +2656 +2659 +2643 +2641 +2667 +2654 +2649 +2651 +2669 +2640 +2640 +2559 +2670 +2667 +2666 +2861 +2691 +2672 +2669 +2666 +2652 +2654 +2640 +2669 +2640 +2671 +2682 +2661 +2588 +2690 +2643 +2662 +2667 +2602 +2660 +2642 +2666 +2663 +2657 +2629 +2663 +2748 +2658 +2640 +2669 +2647 +2655 +2646 +2649 +2672 +2672 +2670 +2690 +2659 +2647 +2663 +2652 +2657 +2741 +2642 +2655 +2663 +2662 +2642 +2663 +2656 +2658 +2662 +2645 +2647 +2661 +2656 +2646 +2665 +2608 +2624 +2775 +2659 +2669 +2670 +2655 +2654 +2656 +2640 +2653 +2674 +2660 +2656 +2660 +2675 +2672 +2593 +2658 +2678 +2662 +2666 +2652 +2663 +2668 +2644 +2646 +2651 +2657 +2655 +2679 +2663 +2665 +2657 +2671 +2676 +2651 +2654 +2657 +2655 +2559 +2650 +2647 +2544 +2651 +2687 +2637 +2658 +2523 +2678 +2671 +2666 +2659 +2656 +2652 +2667 +2649 +2658 +2657 +2649 +2652 +2661 +2674 +2663 +2658 +2733 +2673 +2683 +2699 +2647 +2692 +2659 +2667 +2612 +2655 +2666 +2657 +2666 +2670 +2655 +2669 +2672 +2669 +2675 +2664 +2687 +2657 +2695 +2704 +2693 +2662 +2639 +2657 +2627 +2672 +2666 +2672 +2663 +2681 +2649 +2672 +2681 +2663 +2643 +2671 +2670 +2597 +2659 +2667 +2649 +2659 +2681 +2637 +2667 +2672 +2662 +2654 +2764 +2638 +2649 +2661 +2650 +2649 +2675 +2661 +2679 +2656 +2677 +2663 +2596 +2647 +2659 +2623 +2663 +2687 +2667 +2665 +2662 +2640 +2639 +2662 +2646 +2655 +2639 +2669 +2661 +2670 +2655 +2672 +2659 +2675 +2639 +2665 +2659 +2661 +2605 +2590 +2624 +2662 +2663 +2614 +2657 +2678 +2662 +2670 +2654 +2656 +2672 +2672 +2663 +2667 +2651 +2662 +2676 +2649 +2678 +2649 +2670 +2672 +2662 +2640 +2659 +2656 +2665 +2656 +2734 +2672 +2670 +2703 +2660 +2559 +2657 +2658 +2647 +2662 +2657 +2669 +2618 +2651 +2655 +2661 +2657 +2670 +2672 +2665 +2662 +2641 +2593 +2674 +2658 +2667 +2672 +2663 +2666 +2620 +2662 +2669 +2659 +2657 +2695 +2655 +2591 +2641 +2658 +2661 +2640 +2670 +2790 +2657 +2655 +2768 +2653 +2667 +2671 +2662 +2640 +2654 +2743 +2658 +2659 +2657 +2779 +2651 +2650 +2670 +2647 +2660 +2663 +2675 +2690 +2654 +2652 +2655 +2646 +2647 +2665 +2525 +2669 +2650 +2654 +2659 +2666 +2650 +2672 +2602 +2666 +2659 +2659 +2674 +2658 +2666 +2679 +2667 +2665 +2624 +2658 +2688 +2661 +2656 +2674 +2651 +2704 +2658 +2666 +2646 +2661 +2652 +2653 +2662 +2655 +2643 +2677 +2646 +2611 +2704 +2663 +2653 +2665 +2647 +2658 +2641 +2671 +2659 +2637 +2653 +2624 +2641 +2666 +2666 +2678 +2653 +2661 +2657 +2644 +2661 +2662 +2662 +2656 +2657 +2653 +2593 +2644 +2651 +2654 +2659 +2665 +2640 +2656 +2672 +2657 +2601 +2653 +2640 +2661 +2659 +2629 +2642 +2671 +2662 +2591 +2663 +2641 +2677 +2687 +2639 +2648 +2704 +2559 +2671 +2559 +2647 +2623 +2649 +2657 +2640 +2667 +2663 +2657 +2649 +2585 +2559 +2659 +2666 +2627 +2674 +2658 +2647 +2667 +2650 +2661 +2918 +2672 +2661 +2599 +2663 +2657 +2657 +2646 +2660 +2665 +2644 +2657 +2661 +2653 +2645 +2658 +2601 +2641 +2666 +2659 +2653 +2670 +2661 +2671 +2647 +2661 +2559 +2647 +2701 +2669 +2647 +2663 +2645 +2655 +2662 +2670 +2674 +2674 +2669 +2667 +2620 +2693 +2751 +2662 +2660 +2656 +2659 +2559 +2662 +2668 +2654 +2678 +2661 +2656 +2629 +2662 +2683 +2666 +2661 +2669 +2631 +2642 +2645 +2667 +2702 +2656 +2631 +2647 +2673 +2647 +2667 +2608 +2663 +2653 +2658 +2635 +2645 +2640 +2661 +2658 +2644 +2665 +2647 +2666 +2672 +2639 +2655 +2658 +2670 +2669 +2531 +2655 +2667 +2651 +2559 +2650 +2646 +2646 +2651 +2718 +2669 +2639 +2664 +2664 +2655 +2784 +2655 +2681 +2672 +2658 +2662 +2635 +2643 +2669 +2662 +2656 +2651 +2646 +2640 +2660 +2657 +2659 +2662 +2659 +2640 +2663 +2662 +2656 +2559 +2622 +2638 +2642 +2652 +2614 +2661 +2666 +2657 +2656 +2704 +2662 +2653 +2640 +2645 +2635 +2655 +2608 +2657 +2666 +2634 +2659 +2661 +2655 +2638 +2653 +2653 +2646 +2673 +2658 +2656 +2677 +2624 +2671 +2653 +2653 +2593 +2667 +2703 +2653 +2768 +2640 +2641 +2631 +2659 +2651 +2640 +2658 +2659 +2659 +2654 +2703 +2559 +2672 +2672 +2647 +2637 +2646 +2653 +2635 +2640 +2663 +2662 +2642 +2646 +2659 +2647 +2638 +2653 +2635 +2625 +2637 +2645 +2652 +2675 +2656 +2656 +2627 +2699 +2651 +2666 +2651 +2656 +2649 +2640 +2626 +2635 +2636 +2678 +2651 +2663 +2655 +2674 +2643 +2679 +2620 +2614 +2526 +2650 +2611 +2649 +2641 +2643 +2651 +2636 +2632 +2653 +2642 +2665 +2665 +2642 +2671 +2665 +2654 +2651 +2671 +2645 +2672 +2656 +2643 +2656 +2645 +2651 +2663 +2650 +2652 +2662 +2651 +2640 +2651 +2678 +2652 +2637 +2589 +2640 +2640 +2647 +2657 +2599 +2652 +2656 +2647 +2645 +2662 +2643 +2650 +2626 +2640 +2656 +2608 +2661 +2658 +2707 +2606 +2646 +2589 +2640 +2603 +2655 +2646 +2662 +2636 +2645 +2640 +2651 +2659 +2637 +2658 +2645 +2658 +2665 +2667 +2736 +2670 +2638 +2559 +2595 +2666 +2671 +2654 +2654 +2689 +2646 +2650 +2672 +2654 +2687 +2645 +2656 +2667 +2650 +2691 +2659 +2590 +2646 +2609 +2587 +2640 +2658 +2659 +2642 +2656 +2647 +2657 +2654 +2651 +2647 +2637 +2626 +2675 +2649 +2647 +2640 +2667 +2659 +2650 +2653 +2667 +2654 +2636 +2640 +2639 +2624 +2646 +2647 +2649 +2640 +2596 +2644 +2650 +2645 +2663 +2641 +2642 +2658 +2661 +2547 +2657 +2640 +2650 +2625 +2651 +2663 +2660 +2656 +2652 +2645 +2639 +2667 +2652 +2655 +2650 +2674 +2646 +2658 +2656 +2646 +2651 +2766 +2661 +2650 +2638 +2650 +2645 +2658 +2615 +2547 +2643 +2643 +2658 +2640 +2672 +2640 +2643 +2648 +2655 +2663 +2663 +2666 +2631 +2655 +2642 +2656 +2645 +2646 +2656 +2788 +2644 +2640 +2650 +2642 +2690 +2657 +2641 +2641 +2640 +2646 +2631 +2641 +2640 +2640 +2650 +2657 +2633 +2614 +2602 +2643 +2645 +2651 +2637 +2601 +2643 +2658 +2635 +2657 +2646 +2660 +2593 +2645 +2645 +2649 +2647 +2657 +2653 +2776 +2652 +2649 +2640 +2654 +2640 +2646 +2672 +2640 +2651 +2643 +2647 +2639 +2618 +2645 +2640 +2641 +2702 +2653 +2646 +2647 +2647 +2643 +2653 +2640 +2649 +2644 +2627 +2608 +2630 +2646 +2602 +2653 +2654 +2542 +2640 +2663 +2660 +2642 +2624 +2640 +2646 +2646 +2665 +2641 +2624 +2640 +2637 +2644 +2641 +2638 +2647 +2643 +2632 +2647 +2641 +2651 +2624 +2651 +2660 +2646 +2671 +2644 +2667 +2651 +2647 +2650 +2652 +2601 +2633 +2656 +2658 +2637 +2637 +2627 +2735 +2653 +2595 +2656 +2647 +2629 +2640 +2672 +2655 +2582 +2640 +2646 +2645 +2559 +2643 +2659 +2653 +2646 +2743 +2636 +2654 +2655 +2654 +2658 +2645 +2650 +2655 +2652 +2636 +2657 +2639 +2647 +2613 +2559 +2665 +2651 +2652 +2653 +2642 +2662 +2647 +2743 +2662 +2649 +2654 +2644 +2674 +2649 +2646 +2649 +2714 +2666 +2643 +2645 +2647 +2654 +2640 +2633 +2639 +2640 +2590 +2559 +2645 +2688 +2635 +2677 +2638 +2655 +2637 +2640 +2608 +2649 +2655 +2641 +2641 +2640 +2642 +2640 +2640 +2662 +2559 +2654 +2655 +2646 +2638 +2648 +2611 +2646 +2669 +2640 +2649 +2638 +2634 +2637 +2668 +2715 +2651 +2640 +2659 +2634 +2627 +2651 +2630 +2625 +2651 +2663 +2640 +2642 +2643 +2643 +2637 +2639 +2605 +2606 +2653 +2643 +2645 +2629 +2647 +2672 +2647 +2640 +2638 +2559 +2641 +2666 +2670 +2640 +2644 +2639 +2643 +2639 +2624 +2648 +2651 +2635 +2559 +2637 +2614 +2651 +2624 +2713 +2607 +2668 +2655 +2611 +2644 +2631 +2634 +2697 +2640 +2640 +2641 +2651 +2658 +2718 +2663 +2652 +2640 +2641 +2651 +2649 +2644 +2643 +2658 +2637 +2699 +2644 +2645 +2645 +2643 +2654 +2653 +2544 +2645 +2665 +2634 +2640 +2640 +2640 +2631 +2605 +2623 +2650 +2638 +2631 +2749 +2618 +2637 +2642 +2654 +2559 +2647 +2619 +2559 +2633 +2631 +2634 +2644 +2645 +2641 +2640 +2628 +2663 +2640 +2661 +2639 +2645 +2593 +2641 +2640 +2642 +2606 +2640 +2640 +2644 +2644 +2645 +2594 +2660 +2647 +2669 +2639 +2640 +2640 +2644 +2649 +2640 +2634 +2639 +2639 +2641 +2647 +2640 +2642 +2653 +2656 +2631 +2641 +2649 +2639 +2672 +2637 +2640 +2639 +2649 +2645 +2629 +2629 +2661 +2656 +2639 +2634 +2649 +2640 +2635 +2594 +2651 +2633 +2631 +2626 +2640 +2644 +2640 +2639 +2631 +2634 +2631 +2640 +2618 +2642 +2640 +2662 +2640 +2646 +2642 +2636 +2608 +2637 +2629 +2637 +2640 +2646 +2643 +2639 +2624 +2603 +2643 +2641 +2645 +2643 +2633 +2655 +2635 +2613 +2533 +2627 +2643 +2559 +2736 +2642 +2647 +2606 +2640 +2623 +2637 +2671 +2626 +2642 +2647 +2639 +2629 +2640 +2657 +2640 +2649 +2659 +2635 +2641 +2619 +2647 +2641 +2651 +2651 +2655 +2640 +2640 +2645 +2640 +2672 +2635 +2641 +2639 +2641 +2640 +2634 +2677 +2643 +2590 +2645 +2624 +2640 +2640 +2612 +2668 +2652 +2663 +2626 +2609 +2639 +2634 +2638 +2635 +2651 +2636 +2634 +2638 +2650 +2634 +2643 +2640 +2638 +2635 +2585 +2624 +2635 +2652 +2485 +2635 +2768 +2631 +2603 +2639 +2640 +2638 +2641 +2630 +2640 +2654 +2582 +2625 +2638 +2625 +2651 +2732 +2635 +2634 +2644 +2635 +2647 +2639 +2640 +2631 +2643 +2678 +2636 +2662 +2631 +2629 +2641 +2604 +2643 +2640 +2631 +2638 +2614 +2635 +2640 +2845 +2670 +2638 +2646 +2635 +2640 +2596 +2640 +2624 +2638 +2628 +2662 +2640 +2623 +2623 +2634 +2640 +2624 +2640 +2650 +2636 +2539 +2633 +2629 +2726 +2640 +2659 +2626 +2645 +2682 +2599 +2628 +2636 +2626 +2640 +2635 +2650 +2634 +2625 +2621 +2640 +2637 +2640 +2638 +2637 +2631 +2617 +2590 +2641 +2665 +2634 +2627 +2634 +2637 +2640 +2624 +2629 +2643 +2630 +2626 +2656 +2554 +2615 +2641 +2639 +2606 +2657 +2617 +2637 +2626 +2647 +2649 +2624 +2626 +2634 +2624 +2644 +2627 +2640 +2640 +2721 +2617 +2639 +2590 +2658 +2628 +2628 +2644 +2608 +2625 +2670 +2638 +2623 +2634 +2694 +2629 +2623 +2640 +2608 +2641 +2651 +2637 +2633 +2681 +2640 +2624 +2608 +2631 +2635 +2637 +2608 +2624 +2614 +2626 +2630 +2628 +2654 +2637 +2637 +2630 +2646 +2631 +2639 +2618 +2629 +2613 +2610 +2640 +2619 +2624 +2623 +2622 +2662 +2626 +2634 +2636 +2663 +2640 +2614 +2623 +2627 +2634 +2637 +2637 +2639 +2623 +2559 +2644 +2639 +2640 +2646 +2627 +2641 +2622 +2675 +2631 +2631 +2640 +2581 +2634 +2627 +2629 +2608 +2704 +2643 +2672 +2624 +2627 +2608 +2559 +2613 +2631 +2586 +2639 +2634 +2624 +2627 +2640 +2630 +2639 +2640 +2624 +2640 +2623 +2633 +2607 +2739 +2639 +2627 +2621 +2756 +2636 +2559 +2633 +2607 +2627 +2555 +2628 +2639 +2643 +2626 +2633 +2637 +2640 +2627 +2609 +2626 +2617 +2634 +2608 +2637 +2638 +2643 +2629 +2634 +2625 +2639 +2615 +2643 +2631 +2627 +2788 +2643 +2628 +2641 +2631 +2647 +2599 +2634 +2635 +2624 +2627 +2537 +2640 +2627 +2592 +2625 +2551 +2633 +2640 +2640 +2620 +2627 +2689 +2636 +2639 +2559 +2634 +2617 +2621 +2640 +2633 +2614 +2639 +2630 +2480 +2591 +2619 +2628 +2544 +2637 +2619 +2636 +2608 +2612 +2559 +2586 +2620 +2667 +2625 +2627 +2615 +2624 +2640 +2639 +2559 +2621 +2641 +2620 +2611 +2592 +2620 +2603 +2624 +2614 +2637 +2631 +2624 +2617 +2625 +2614 +2559 +2618 +2609 +2615 +2615 +2619 +2622 +2618 +2638 +2639 +2612 +2581 +2637 +2633 +2621 +2624 +2640 +2622 +2635 +2730 +2629 +2621 +2626 +2591 +2619 +2610 +2621 +2618 +2607 +2643 +2624 +2621 +2628 +2643 +2623 +2630 +2624 +2672 +2559 +2608 +2625 +2639 +2622 +2608 +2624 +2627 +2609 +2762 +2624 +2625 +2608 +2559 +2630 +2619 +2631 +2625 +2631 +2615 +2624 +2625 +2736 +2624 +2609 +2611 +2618 +2594 +2623 +2615 +2612 +2645 +2603 +2619 +2624 +2617 +2619 +2619 +2625 +2624 +2608 +2579 +2631 +2644 +2628 +2631 +2621 +2719 +2620 +2618 +2617 +2608 +2652 +2544 +2615 +2634 +2630 +2622 +2635 +2637 +2630 +2631 +2622 +2623 +2643 +2636 +2621 +2640 +2631 +2640 +2607 +2625 +2638 +2671 +2622 +2615 +2605 +2608 +2435 +2615 +2510 +2624 +2625 +2629 +2727 +2615 +2625 +2619 +2629 +2614 +2604 +2623 +2613 +2747 +2630 +2613 +2623 +2418 +2618 +2620 +2612 +2608 +2585 +2618 +2611 +2608 +2631 +2640 +2619 +2590 +2613 +2630 +2608 +2622 +2602 +2559 +2559 +2640 +2608 +2559 +2642 +2620 +2613 +2619 +2615 +2606 +2623 +2617 +2671 +2593 +2631 +2639 +2640 +2582 +2617 +2620 +2599 +2637 +2633 +2621 +2619 +2626 +2625 +2647 +2608 +2618 +2618 +2579 +2623 +2606 +2618 +2629 +2623 +2617 +2609 +2631 +2632 +2639 +2624 +2619 +2623 +2607 +2645 +2627 +2603 +2613 +2643 +2607 +2610 +2619 +2624 +2769 +2613 +2559 +2613 +2609 +2634 +2618 +2617 +2559 +2603 +2611 +2624 +2608 +2630 +2548 +2615 +2608 +2603 +2605 +2608 +2597 +2608 +2608 +2610 +2615 +2620 +2617 +2619 +2614 +2618 +2538 +2732 +2608 +2619 +2601 +2547 +2603 +2619 +2602 +2623 +2619 +2624 +2628 +2613 +2620 +2673 +2617 +2645 +2625 +2625 +2624 +2623 +2623 +2614 +2608 +2625 +2610 +2625 +2589 +2628 +2624 +2694 +2624 +2611 +2619 +2602 +2611 +2606 +2609 +2617 +2624 +2607 +2608 +2603 +2527 +2613 +2436 +2656 +2593 +2595 +2607 +2602 +2607 +2617 +2616 +2608 +2559 +2622 +2608 +2611 +2619 +2665 +2608 +2597 +2659 +2682 +2617 +2609 +2583 +2622 +2607 +2437 +2621 +2612 +2767 +2612 +2608 +2617 +2602 +2606 +2612 +2613 +2608 +2650 +2610 +2610 +2608 +2602 +2612 +2616 +2645 +2596 +2608 +2621 +2621 +2608 +2603 +2603 +2609 +2599 +2598 +2591 +2609 +2608 +2594 +2615 +2559 +2646 +2596 +2606 +2607 +2505 +2617 +2607 +2596 +2610 +2601 +2705 +2613 +2646 +2605 +2585 +2607 +2603 +2559 +2618 +2608 +2608 +2534 +2614 +2613 +2614 +2626 +2594 +2638 +2609 +2612 +2617 +2603 +2598 +2606 +2604 +2608 +2591 +2607 +2607 +2626 +2608 +2603 +2608 +2607 +2608 +2596 +2615 +2611 +2559 +2637 +2613 +2619 +2611 +2606 +2646 +2601 +2601 +2527 +2613 +2614 +2622 +2617 +2624 +2619 +2608 +2614 +2782 +2607 +2622 +2624 +2619 +2616 +2606 +2620 +2614 +2637 +2624 +2601 +2583 +2625 +2631 +2630 +2640 +2608 +2622 +2603 +2610 +2597 +2606 +2588 +2608 +2608 +2611 +2614 +2604 +2597 +2608 +2613 +2603 +2585 +2602 +2583 +2592 +2608 +2605 +2603 +2614 +2590 +2626 +2606 +2602 +2716 +2585 +2587 +2588 +2624 +2624 +2608 +2606 +2595 +2587 +2611 +2595 +2559 +2615 +2606 +2603 +2608 +2599 +2542 +2598 +2592 +2599 +2608 +2581 +2604 +2621 +2602 +2609 +2605 +2613 +2609 +2597 +2559 +2592 +2616 +2661 +2559 +2559 +2613 +2608 +2516 +2608 +2559 +2587 +2605 +2624 +2599 +2608 +2583 +2592 +2585 +2603 +2605 +2585 +2608 +2605 +2608 +2711 +2609 +2598 +2559 +2559 +2603 +2622 +2603 +2589 +2594 +2606 +2591 +2597 +2515 +2601 +2603 +2605 +2496 +2594 +2508 +2597 +2559 +2609 +2615 +2604 +2592 +2559 +2640 +2593 +2599 +2591 +2543 +2603 +2630 +2605 +2598 +2583 +2623 +2599 +2591 +2582 +2608 +2551 +2595 +2559 +2658 +2582 +2581 +2544 +2664 +2587 +2595 +2592 +2627 +2594 +2605 +2606 +2596 +2595 +2588 +2593 +2559 +2597 +2609 +2606 +2590 +2598 +2593 +2639 +2615 +2559 +2608 +2596 +2593 +2590 +2611 +2590 +2595 +2602 +2591 +2592 +2559 +2606 +2607 +2548 +2559 +2598 +2605 +2591 +2591 +2597 +2596 +2590 +2608 +2589 +2586 +2594 +2595 +2587 +2582 +2615 +2603 +2594 +2597 +2598 +2597 +2529 +2593 +2604 +2757 +2595 +2589 +2591 +2554 +2608 +2594 +2599 +2593 +2609 +2587 +2593 +2608 +2605 +2602 +2603 +2592 +2603 +2602 +2607 +2598 +2595 +2619 +2516 +2592 +2608 +2598 +2614 +2559 +2559 +2606 +2583 +2594 +2591 +2618 +2589 +2522 +2603 +2597 +2606 +2613 +2599 +2559 +2626 +2605 +2590 +2587 +2589 +2600 +2594 +2559 +2586 +2641 +2595 +2586 +2597 +2599 +2594 +2559 +2590 +2587 +2583 +2593 +2501 +2590 +2589 +2559 +2559 +2585 +2591 +2597 +2593 +2613 +2592 +2559 +2559 +2585 +2580 +2559 +2592 +2641 +2592 +2615 +2608 +2618 +2509 +2597 +2582 +2593 +2527 +2559 +2593 +2596 +2524 +2599 +2603 +2585 +2605 +2583 +2599 +2682 +2587 +2591 +2559 +2539 +2595 +2624 +2601 +2624 +2559 +2591 +2587 +2559 +2559 +2597 +2603 +2594 +2594 +2601 +2512 +2591 +2604 +2585 +2593 +2559 +2598 +2559 +2604 +2601 +2603 +2608 +2586 +2594 +2595 +2579 +2545 +2591 +2583 +2558 +2579 +2585 +2594 +2559 +2593 +2559 +2583 +2583 +2559 +2660 +2588 +2595 +2559 +2585 +2583 +2591 +2598 +2705 +2545 +2587 +2556 +2583 +2559 +2605 +2603 +2559 +2588 +2586 +2589 +2559 +2586 +2590 +2603 +2606 +2603 +2617 +2595 +2619 +2590 +2559 +2640 +2587 +2559 +2736 +2557 +2555 +2559 +2586 +2592 +2602 +2586 +2593 +2555 +2598 +2554 +2586 +2595 +2592 +2590 +2602 +2603 +2605 +2592 +2587 +2480 +2596 +2592 +2532 +2589 +2602 +2608 +2590 +2559 +2589 +2594 +2589 +2599 +2626 +2599 +2559 +2512 +2594 +2592 +2596 +2603 +2655 +2559 +2527 +2589 +2594 +2588 +2559 +2501 +2559 +2559 +2414 +2586 +2590 +2663 +2559 +2559 +2559 +2582 +2583 +2559 +2554 +2678 +2589 +2559 +2474 +2586 +2598 +2559 +2594 +2582 +2559 +2559 +2590 +2481 +2599 +2587 +2692 +2595 +2559 +2587 +2586 +2600 +2592 +2496 +2579 +2559 +2623 +2624 +2559 +2583 +2559 +2559 +2485 +2581 +2597 +2581 +2559 +2591 +2596 +2588 +2582 +2559 +2591 +2678 +2583 +2588 +2559 +2494 +2608 +2583 +2583 +2653 +2586 +2583 +2582 +2586 +2524 +2582 +2593 +2606 +2559 +2619 +2586 +2586 +2585 +2559 +2591 +2559 +2559 +2594 +2712 +2581 +2533 +2635 +2559 +2559 +2589 +2581 +2559 +2559 +2559 +2559 +2559 +2614 +2581 +2653 +2559 +2584 +2583 +2559 +2608 +2559 +2559 +2590 +2559 +2559 +2580 +2678 +2559 +2559 +2544 +2581 +2616 +2559 +2534 +2617 +2559 +2559 +2557 +2559 +2559 +2559 +2683 +2553 +2559 +2626 +2559 +2607 +2559 +2559 +2679 +2582 +2588 +2559 +2581 +2559 +2583 +2588 +2581 +2559 +2583 +2559 +2589 +2559 +2629 +2559 +2559 +2579 +2559 +2554 +2558 +2559 +2559 +2559 +2590 +2558 +2581 +2559 +2559 +2582 +2559 +2559 +2583 +2499 +2547 +2534 +2491 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2549 +2557 +2608 +2559 +2591 +2559 +2559 +2602 +2559 +2583 +2586 +2586 +2587 +2531 +2559 +2581 +2559 +2610 +2614 +2508 +2559 +2557 +2559 +2590 +2558 +2559 +2594 +2559 +2541 +2558 +2559 +2559 +2551 +2592 +2582 +2559 +2608 +2586 +2538 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2549 +2559 +2589 +2559 +2549 +2559 +2559 +2559 +2555 +2555 +2559 +2557 +2628 +2559 +2559 +2559 +2554 +2473 +2559 +2559 +2559 +2556 +2559 +2559 +2559 +2582 +2550 +2559 +2559 +2586 +2559 +2559 +2559 +2475 +2592 +2559 +2559 +2557 +2559 +2559 +2531 +2559 +2559 +2559 +2559 +2559 +2600 +2559 +2550 +2551 +2547 +2559 +2553 +2589 +2559 +2559 +2559 +2559 +2592 +2559 +2690 +2468 +2512 +2534 +2597 +2558 +2533 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2551 +2551 +2559 +2547 +2549 +2556 +2581 +2559 +2559 +2559 +2584 +2559 +2559 +2593 +2555 +2545 +2559 +2543 +2557 +2559 +2608 +2559 +2550 +2559 +2548 +2559 +2554 +2559 +2549 +2559 +2559 +2559 +2559 +2586 +2558 +2559 +2559 +2559 +2700 +2559 +2559 +2521 +2559 +2550 +2553 +2544 +2713 +2559 +2554 +2559 +2559 +2533 +2559 +2541 +2541 +2559 +2537 +2557 +2555 +2451 +2559 +2559 +2530 +2559 +2545 +2559 +2559 +2543 +2559 +2585 +2453 +2557 +2559 +2557 +2551 +2594 +2546 +2559 +2455 +2480 +2557 +2551 +2548 +2523 +2545 +2557 +2586 +2511 +2559 +2514 +2544 +2559 +2559 +2544 +2543 +2555 +2554 +2559 +2551 +2559 +2558 +2558 +2469 +2559 +2556 +2555 +2544 +2515 +2559 +2550 +2554 +2553 +2493 +2557 +2505 +2558 +2512 +2547 +2549 +2546 +2549 +2443 +2543 +2550 +2543 +2621 +2559 +2559 +2554 +2587 +2555 +2554 +2500 +2552 +2556 +2559 +2549 +2559 +2555 +2538 +2559 +2559 +2559 +2559 +2559 +2558 +2490 +2556 +2559 +2545 +2559 +2559 +2559 +2539 +2608 +2545 +2546 +2549 +2550 +2549 +2605 +2555 +2554 +2544 +2559 +2552 +2547 +2557 +2591 +2557 +2544 +2548 +2551 +2521 +2545 +2448 +2547 +2475 +2544 +2559 +2559 +2544 +2559 +2559 +2549 +2552 +2549 +2546 +2586 +2553 +2439 +2551 +2548 +2608 +2544 +2480 +2546 +2559 +2525 +2555 +2556 +2547 +2549 +2546 +2544 +2559 +2541 +2544 +2557 +2553 +2522 +2544 +2541 +2541 +2540 +2531 +2483 +2545 +2548 +2559 +2545 +2544 +2559 +2559 +2554 +2544 +2528 +2549 +2553 +2503 +2581 +2542 +2616 +2484 +2559 +2544 +2557 +2527 +2559 +2523 +2555 +2546 +2527 +2590 +2532 +2487 +2556 +2530 +2547 +2542 +2557 +2480 +2542 +2546 +2545 +2583 +2544 +2526 +2544 +2559 +2559 +2544 +2546 +2544 +2550 +2509 +2553 +2539 +2549 +2545 +2654 +2542 +2534 +2542 +2708 +2551 +2544 +2548 +2544 +2546 +2542 +2539 +2559 +2559 +2551 +2582 +2544 +2543 +2559 +2558 +2527 +2544 +2529 +2544 +2656 +2539 +2544 +2545 +2550 +2491 +2541 +2549 +2534 +2554 +2543 +2544 +2496 +2551 +2532 +2580 +2545 +2544 +2544 +2550 +2534 +2559 +2559 +2550 +2539 +2546 +2545 +2541 +2551 +2656 +2553 +2538 +2549 +2528 +2544 +2542 +2455 +2540 +2538 +2480 +2544 +2518 +2507 +2538 +2544 +2544 +2480 +2559 +2534 +2525 +2543 +2559 +2535 +2531 +2672 +2547 +2550 +2533 +2542 +2481 +2539 +2530 +2526 +2557 +2550 +2535 +2559 +2529 +2500 +2591 +2547 +2545 +2535 +2597 +2546 +2545 +2539 +2473 +2535 +2544 +2549 +2548 +2481 +2535 +2530 +2544 +2545 +2559 +2481 +2463 +2557 +2541 +2551 +2531 +2548 +2547 +2547 +2558 +2543 +2559 +2537 +2537 +2506 +2544 +2527 +2550 +2547 +2541 +2530 +2477 +2535 +2547 +2534 +2527 +2539 +2531 +2544 +2534 +2528 +2533 +2530 +2527 +2534 +2551 +2547 +2548 +2544 +2544 +2542 +2493 +2535 +2518 +2512 +2527 +2593 +2544 +2528 +2535 +2557 +2519 +2540 +2541 +2559 +2541 +2531 +2534 +2669 +2546 +2549 +2539 +2503 +2534 +2518 +2538 +2530 +2542 +2534 +2512 +2530 +2611 +2543 +2528 +2518 +2532 +2534 +2402 +2545 +2512 +2559 +2544 +2528 +2515 +2545 +2525 +2521 +2534 +2543 +2525 +2534 +2541 +2547 +2535 +2535 +2541 +2530 +2534 +2525 +2538 +2559 +2523 +2530 +2518 +2555 +2543 +2529 +2534 +2473 +2495 +2500 +2542 +2522 +2495 +2439 +2534 +2537 +2527 +2531 +2480 +2545 +2539 +2544 +2559 +2526 +2512 +2528 +2515 +2527 +2527 +2504 +2459 +2530 +2517 +2512 +2521 +2559 +2526 +2517 +2526 +2511 +2538 +2527 +2515 +2672 +2523 +2678 +2535 +2457 +2509 +2522 +2507 +2515 +2416 +2528 +2514 +2526 +2608 +2510 +2529 +2515 +2507 +2529 +2522 +2527 +2533 +2527 +2513 +2530 +2525 +2491 +2532 +2499 +2524 +2517 +2478 +2524 +2474 +2512 +2530 +2500 +2531 +2657 +2530 +2514 +2539 +2533 +2533 +2529 +2554 +2527 +2513 +2594 +2531 +2522 +2415 +2544 +2529 +2513 +2515 +2547 +2530 +2515 +2526 +2517 +2530 +2389 +2522 +2529 +2559 +2531 +2532 +2518 +2526 +2559 +2514 +2525 +2499 +2524 +2527 +2528 +2512 +2506 +2542 +2509 +2533 +2512 +2512 +2518 +2497 +2519 +2513 +2481 +2522 +2512 +2545 +2521 +2545 +2534 +2512 +2512 +2518 +2509 +2524 +2516 +2541 +2523 +2551 +2512 +2477 +2523 +2529 +2526 +2493 +2521 +2515 +2521 +2545 +2535 +2541 +2525 +2519 +2518 +2403 +2512 +2514 +2438 +2512 +2511 +2528 +2521 +2525 +2559 +2507 +2538 +2559 +2535 +2523 +2522 +2462 +2543 +2524 +2512 +2507 +2493 +2516 +2508 +2512 +2549 +2538 +2453 +2523 +2535 +2522 +2542 +2546 +2512 +2515 +2557 +2536 +2522 +2531 +2507 +2509 +2544 +2502 +2523 +2522 +2549 +2522 +2512 +2522 +2525 +2521 +2529 +2526 +2517 +2526 +2512 +2522 +2509 +2512 +2509 +2521 +2513 +2512 +2523 +2510 +2418 +2497 +2512 +2520 +2512 +2516 +2529 +2529 +2522 +2519 +2679 +2529 +2519 +2527 +2531 +2491 +2448 +2501 +2512 +2543 +2506 +2529 +2494 +2506 +2542 +2509 +2522 +2501 +2494 +2491 +2650 +2518 +2513 +2512 +2527 +2515 +2523 +2538 +2511 +2480 +2510 +2517 +2512 +2511 +2510 +2505 +2513 +2526 +2522 +2504 +2513 +2522 +2594 +2539 +2519 +2509 +2512 +2544 +2527 +2508 +2442 +2513 +2538 +2518 +2516 +2511 +2521 +2550 +2523 +2513 +2529 +2557 +2522 +2505 +2507 +2507 +2509 +2507 +2542 +2505 +2512 +2509 +2483 +2514 +2506 +2516 +2521 +2515 +2513 +2505 +2510 +2509 +2477 +2512 +2501 +2512 +2522 +2511 +2510 +2499 +2506 +2498 +2499 +2512 +2479 +2489 +2506 +2510 +2514 +2557 +2451 +2495 +2512 +2502 +2491 +2525 +2465 +2512 +2506 +2519 +2494 +2502 +2503 +2496 +2465 +2512 +2559 +2523 +2497 +2495 +2512 +2497 +2494 +2486 +2517 +2514 +2509 +2519 +2512 +2514 +2522 +2508 +2445 +2510 +2525 +2503 +2509 +2519 +2509 +2496 +2495 +2506 +2458 +2510 +2496 +2530 +2509 +2506 +2512 +2505 +2407 +2506 +2505 +2501 +2518 +2494 +2523 +2510 +2510 +2501 +2510 +2559 +2506 +2512 +2512 +2457 +2509 +2512 +2493 +2503 +2505 +2494 +2503 +2501 +2459 +2491 +2506 +2513 +2482 +2426 +2496 +2505 +2512 +2495 +2503 +2494 +2492 +2499 +2505 +2512 +2503 +2498 +2505 +2409 +2489 +2516 +2512 +2559 +2504 +2487 +2544 +2504 +2512 +2499 +2559 +2510 +2485 +2531 +2653 +2535 +2491 +2502 +2510 +2509 +2501 +2481 +2509 +2501 +2512 +2512 +2491 +2501 +2492 +2511 +2496 +2502 +2498 +2559 +2527 +2548 +2531 +2512 +2500 +2434 +2529 +2498 +2502 +2509 +2550 +2491 +2513 +2540 +2527 +2544 +2506 +2475 +2559 +2502 +2494 +2549 +2423 +2502 +2511 +2540 +2509 +2495 +2494 +2496 +2498 +2583 +2518 +2507 +2497 +2501 +2485 +2507 +2496 +2496 +2500 +2557 +2502 +2497 +2497 +2495 +2494 +2486 +2497 +2507 +2495 +2498 +2421 +2474 +2499 +2496 +2508 +2498 +2481 +2493 +2499 +2470 +2512 +2491 +2479 +2502 +2498 +2497 +2496 +2492 +2527 +2455 +2510 +2502 +2509 +2531 +2502 +2496 +2499 +2500 +2444 +2503 +2512 +2512 +2409 +2512 +2498 +2499 +2501 +2506 +2509 +2526 +2510 +2506 +2478 +2463 +2621 +2494 +2495 +2491 +2496 +2482 +2486 +2508 +2498 +2517 +2501 +2496 +2530 +2480 +2496 +2508 +2487 +2474 +2480 +2485 +2423 +2486 +2489 +2624 +2498 +2496 +2500 +2490 +2499 +2503 +2482 +2490 +2477 +2500 +2487 +2493 +2491 +2497 +2625 +2467 +2485 +2491 +2488 +2497 +2497 +2486 +2491 +2486 +2491 +2497 +2497 +2512 +2469 +2496 +2493 +2513 +2495 +2497 +2491 +2506 +2489 +2496 +2487 +2490 +2489 +2496 +2416 +2525 +2480 +2489 +2491 +2487 +2480 +2496 +2513 +2497 +2491 +2490 +2395 +2491 +2482 +2483 +2498 +2471 +2489 +2493 +2485 +2490 +2496 +2497 +2388 +2483 +2496 +2448 +2506 +2473 +2485 +2479 +2480 +2480 +2477 +2475 +2482 +2522 +2511 +2495 +2448 +2489 +2406 +2507 +2547 +2486 +2447 +2489 +2487 +2476 +2495 +2480 +2480 +2427 +2530 +2491 +2479 +2481 +2483 +2321 +2477 +2480 +2479 +2461 +2489 +2478 +2494 +2480 +2486 +2489 +2461 +2427 +2482 +2508 +2484 +2527 +2484 +2482 +2485 +2414 +2487 +2487 +2487 +2385 +2482 +2482 +2479 +2480 +2505 +2497 +2507 +2484 +2477 +2507 +2386 +2480 +2483 +2481 +2485 +2470 +2470 +2486 +2467 +2480 +2485 +2493 +2416 +2461 +2477 +2482 +2491 +2462 +2468 +2487 +2481 +2507 +2480 +2480 +2457 +2478 +2608 +2459 +2503 +2480 +2487 +2517 +2471 +2479 +2483 +2471 +2376 +2476 +2448 +2484 +2354 +2459 +2541 +2448 +2480 +2479 +2477 +2477 +2474 +2478 +2475 +2480 +2479 +2460 +2430 +2495 +2493 +2459 +2462 +2475 +2477 +2477 +2478 +2485 +2480 +2480 +2455 +2416 +2481 +2439 +2476 +2467 +2485 +2478 +2475 +2474 +2486 +2470 +2485 +2461 +2480 +2511 +2483 +2482 +2481 +2480 +2461 +2465 +2479 +2475 +2472 +2487 +2475 +2487 +2393 +2481 +2417 +2482 +2474 +2419 +2486 +2512 +2448 +2471 +2480 +2386 +2478 +2642 +2485 +2480 +2462 +2492 +2451 +2513 +2480 +2469 +2471 +2473 +2417 +2477 +2479 +2475 +2481 +2503 +2527 +2470 +2471 +2473 +2470 +2469 +2465 +2480 +2475 +2469 +2465 +2480 +2467 +2475 +2475 +2468 +2455 +2465 +2464 +2480 +2473 +2451 +2480 +2479 +2484 +2459 +2430 +2480 +2448 +2484 +2470 +2435 +2476 +2496 +2475 +2480 +2462 +2477 +2460 +2467 +2480 +2475 +2468 +2495 +2464 +2473 +2471 +2466 +2512 +2461 +2510 +2466 +2473 +2485 +2496 +2471 +2467 +2489 +2471 +2454 +2491 +2423 +2493 +2461 +2469 +2519 +2477 +2469 +2481 +2427 +2475 +2471 +2472 +2479 +2455 +2471 +2479 +2466 +2464 +2475 +2429 +2477 +2453 +2384 +2467 +2473 +2511 +2415 +2469 +2463 +2453 +2463 +2464 +2475 +2459 +2380 +2476 +2448 +2453 +2465 +2457 +2449 +2478 +2467 +2411 +2453 +2466 +2469 +2451 +2451 +2474 +2465 +2505 +2437 +2478 +2433 +2463 +2466 +2463 +2486 +2478 +2463 +2467 +2470 +2462 +2471 +2471 +2483 +2455 +2474 +2475 +2461 +2468 +2438 +2456 +2389 +2464 +2470 +2463 +2451 +2453 +2485 +2455 +2448 +2433 +2463 +2467 +2468 +2448 +2469 +2459 +2463 +2471 +2463 +2384 +2468 +2471 +2463 +2466 +2475 +2465 +2483 +2463 +2469 +2468 +2457 +2464 +2414 +2480 +2462 +2468 +2458 +2473 +2473 +2449 +2469 +2464 +2467 +2405 +2443 +2489 +2518 +2367 +2464 +2467 +2494 +2467 +2403 +2480 +2467 +2460 +2374 +2448 +2471 +2450 +2448 +2442 +2448 +2445 +2539 +2448 +2448 +2453 +2448 +2464 +2455 +2485 +2448 +2480 +2468 +2449 +2466 +2454 +2463 +2459 +2455 +2457 +2452 +2466 +2481 +2466 +2448 +2459 +2481 +2551 +2464 +2466 +2458 +2495 +2466 +2450 +2455 +2435 +2447 +2435 +2434 +2455 +2464 +2601 +2469 +2451 +2463 +2459 +2447 +2462 +2457 +2459 +2332 +2459 +2459 +2455 +2434 +2453 +2442 +2472 +2463 +2462 +2448 +2451 +2461 +2464 +2449 +2455 +2461 +2467 +2438 +2454 +2454 +2452 +2448 +2457 +2474 +2441 +2458 +2495 +2458 +2464 +2434 +2433 +2418 +2559 +2442 +2448 +2449 +2464 +2448 +2453 +2450 +2448 +2451 +2449 +2416 +2451 +2463 +2440 +2559 +2449 +2528 +2608 +2452 +2448 +2448 +2465 +2384 +2432 +2439 +2442 +2419 +2447 +2464 +2433 +2451 +2436 +2463 +2438 +2444 +2460 +2451 +2494 +2450 +2459 +2448 +2448 +2461 +2457 +2410 +2448 +2399 +2447 +2434 +2447 +2454 +2448 +2470 +2448 +2445 +2439 +2448 +2448 +2402 +2459 +2432 +2451 +2463 +2462 +2467 +2448 +2450 +2453 +2485 +2422 +2535 +2431 +2445 +2442 +2449 +2541 +2442 +2447 +2441 +2430 +2445 +2457 +2447 +2371 +2451 +2448 +2430 +2426 +2678 +2435 +2367 +2445 +2446 +2448 +2434 +2368 +2450 +2428 +2442 +2464 +2432 +2461 +2546 +2384 +2427 +2447 +2476 +2441 +2451 +2439 +2416 +2434 +2453 +2455 +2534 +2438 +2447 +2453 +2439 +2474 +2455 +2438 +2441 +2550 +2443 +2437 +2437 +2437 +2432 +2447 +2431 +2445 +2512 +2512 +2448 +2447 +2448 +2435 +2482 +2429 +2453 +2416 +2448 +2485 +2436 +2445 +2423 +2447 +2443 +2454 +2448 +2448 +2448 +2448 +2545 +2445 +2443 +2453 +2429 +2453 +2453 +2417 +2432 +2433 +2437 +2432 +2442 +2446 +2449 +2387 +2427 +2439 +2448 +2442 +2433 +2438 +2403 +2438 +2451 +2417 +2409 +2441 +2443 +2471 +2475 +2425 +2439 +2428 +2418 +2398 +2437 +2439 +2431 +2439 +2395 +2454 +2439 +2431 +2422 +2432 +2458 +2436 +2422 +2435 +2446 +2437 +2428 +2436 +2435 +2447 +2437 +2435 +2448 +2425 +2442 +2445 +2386 +2441 +2441 +2445 +2447 +2439 +2449 +2440 +2435 +2432 +2437 +2405 +2448 +2521 +2494 +2446 +2465 +2433 +2470 +2404 +2431 +2256 +2431 +2353 +2430 +2433 +2432 +2499 +2422 +2432 +2414 +2430 +2361 +2441 +2430 +2442 +2445 +2431 +2432 +2411 +2384 +2438 +2396 +2529 +2428 +2369 +2416 +2423 +2433 +2427 +2408 +2493 +2407 +2425 +2436 +2374 +2425 +2411 +2395 +2430 +2431 +2434 +2446 +2431 +2425 +2369 +2423 +2435 +2457 +2399 +2431 +2418 +2434 +2407 +2418 +2418 +2434 +2419 +2417 +2427 +2429 +2441 +2467 +2425 +2416 +2427 +2441 +2447 +2426 +2432 +2428 +2429 +2438 +2417 +2426 +2333 +2435 +2407 +2422 +2439 +2430 +2400 +2438 +2411 +2428 +2440 +2451 +2458 +2427 +2427 +2426 +2435 +2439 +2430 +2371 +2454 +2431 +2429 +2470 +2418 +2354 +2435 +2439 +2432 +2427 +2421 +2416 +2431 +2419 +2558 +2416 +2438 +2404 +2425 +2441 +2351 +2375 +2419 +2427 +2352 +2421 +2418 +2423 +2443 +2421 +2442 +2420 +2424 +2432 +2422 +2432 +2411 +2433 +2443 +2439 +2387 +2434 +2407 +2441 +2436 +2438 +2427 +2399 +2434 +2421 +2419 +2432 +2432 +2416 +2434 +2421 +2432 +2443 +2400 +2414 +2432 +2435 +2429 +2423 +2427 +2419 +2411 +2427 +2426 +2513 +2420 +2391 +2455 +2416 +2432 +2432 +2426 +2427 +2430 +2415 +2425 +2429 +2416 +2414 +2417 +2418 +2397 +2412 +2419 +2406 +2410 +2414 +2381 +2425 +2450 +2407 +2416 +2401 +2420 +2416 +2411 +2419 +2379 +2416 +2391 +2434 +2407 +2397 +2416 +2351 +2405 +2426 +2415 +2402 +2419 +2415 +2413 +2433 +2416 +2427 +2412 +2559 +2386 +2416 +2365 +2443 +2291 +2397 +2419 +2432 +2409 +2415 +2432 +2415 +2426 +2377 +2410 +2417 +2418 +2452 +2460 +2416 +2529 +2404 +2386 +2416 +2422 +2423 +2416 +2416 +2417 +2416 +2416 +2410 +2377 +2401 +2416 +2352 +2402 +2414 +2530 +2405 +2407 +2403 +2418 +2395 +2411 +2311 +2407 +2406 +2446 +2411 +2416 +2332 +2415 +2413 +2399 +2423 +2416 +2417 +2415 +2417 +2423 +2421 +2432 +2307 +2425 +2415 +2413 +2397 +2384 +2410 +2406 +2431 +2421 +2416 +2410 +2410 +2401 +2394 +2436 +2416 +2399 +2400 +2353 +2405 +2407 +2398 +2401 +2400 +2401 +2413 +2411 +2404 +2408 +2411 +2413 +2411 +2406 +2422 +2416 +2410 +2390 +2416 +2512 +2409 +2411 +2326 +2415 +2395 +2349 +2423 +2395 +2394 +2404 +2397 +2375 +2369 +2419 +2414 +2358 +2390 +2400 +2406 +2384 +2398 +2397 +2395 +2410 +2403 +2466 +2430 +2386 +2421 +2411 +2397 +2413 +2410 +2415 +2380 +2403 +2390 +2405 +2391 +2297 +2423 +2394 +2470 +2384 +2346 +2398 +2405 +2405 +2397 +2391 +2399 +2397 +2398 +2402 +2389 +2395 +2421 +2367 +2375 +2396 +2401 +2416 +2404 +2414 +2403 +2391 +2302 +2463 +2421 +2387 +2425 +2405 +2410 +2426 +2401 +2404 +2425 +2406 +2395 +2409 +2395 +2432 +2407 +2402 +2543 +2400 +2417 +2416 +2403 +2416 +2351 +2403 +2403 +2379 +2379 +2409 +2409 +2409 +2425 +2394 +2397 +2399 +2503 +2333 +2411 +2439 +2401 +2390 +2401 +2395 +2517 +2418 +2387 +2498 +2402 +2406 +2395 +2408 +2362 +2394 +2391 +2404 +2403 +2416 +2399 +2387 +2405 +2421 +2400 +2398 +2284 +2397 +2405 +2402 +2398 +2395 +2449 +2401 +2410 +2401 +2409 +2407 +2378 +2412 +2411 +2394 +2402 +2423 +2387 +2393 +2382 +2413 +2401 +2409 +2388 +2403 +2397 +2400 +2395 +2395 +2393 +2406 +2326 +2393 +2385 +2428 +2389 +2395 +2398 +2386 +2387 +2310 +2352 +2394 +2393 +2369 +2383 +2381 +2403 +2381 +2407 +2401 +2393 +2400 +2398 +2395 +2370 +2395 +2390 +2383 +2429 +2375 +2429 +2387 +2385 +2493 +2399 +2384 +2385 +2397 +2391 +2351 +2416 +2397 +2409 +2381 +2393 +2382 +2391 +2320 +2384 +2384 +2390 +2380 +2380 +2384 +2393 +2387 +2384 +2383 +2381 +2383 +2507 +2387 +2393 +2369 +2392 +2370 +2375 +2384 +2384 +2387 +2346 +2404 +2384 +2385 +2366 +2393 +2395 +2390 +2387 +2400 +2394 +2383 +2385 +2311 +2382 +2373 +2397 +2384 +2386 +2394 +2384 +2370 +2389 +2378 +2391 +2320 +2384 +2388 +2517 +2394 +2389 +2389 +2438 +2385 +2421 +2384 +2423 +2390 +2390 +2383 +2394 +2492 +2384 +2391 +2381 +2384 +2418 +2385 +2411 +2395 +2389 +2305 +2394 +2390 +2389 +2384 +2384 +2384 +2397 +2394 +2384 +2320 +2526 +2396 +2384 +2381 +2524 +2341 +2393 +2388 +2403 +2339 +2413 +2371 +2400 +2365 +2401 +2343 +2405 +2384 +2291 +2319 +2397 +2397 +2389 +2384 +2364 +2373 +2373 +2397 +2339 +2383 +2389 +2379 +2375 +2390 +2362 +2314 +2398 +2464 +2535 +2393 +2402 +2384 +2381 +2382 +2381 +2343 +2375 +2335 +2394 +2368 +2375 +2385 +2359 +2368 +2395 +2384 +2383 +2352 +2380 +2384 +2391 +2381 +2339 +2404 +2386 +2450 +2384 +2369 +2484 +2395 +2448 +2382 +2377 +2384 +2379 +2385 +2370 +2384 +2422 +2375 +2455 +2385 +2363 +2384 +2385 +2375 +2389 +2382 +2374 +2383 +2309 +2378 +2374 +2385 +2426 +2330 +2379 +2362 +2373 +2370 +2377 +2343 +2379 +2373 +2372 +2371 +2378 +2384 +2281 +2368 +2369 +2369 +2374 +2389 +2342 +2435 +2368 +2363 +2375 +2387 +2373 +2384 +2364 +2382 +2373 +2375 +2366 +2369 +2375 +2373 +2364 +2358 +2342 +2384 +2321 +2337 +2383 +2358 +2371 +2384 +2307 +2320 +2358 +2371 +2379 +2378 +2366 +2387 +2368 +2374 +2382 +2374 +2367 +2384 +2381 +2383 +2352 +2311 +2389 +2382 +2397 +2366 +2397 +2375 +2384 +2382 +2387 +2362 +2377 +2378 +2368 +2398 +2258 +2380 +2356 +2384 +2408 +2400 +2381 +2375 +2384 +2359 +2381 +2370 +2349 +2369 +2315 +2322 +2371 +2363 +2342 +2383 +2361 +2384 +2364 +2386 +2365 +2315 +2304 +2367 +2354 +2384 +2352 +2335 +2370 +2366 +2294 +2259 +2367 +2371 +2372 +2372 +2355 +2368 +2365 +2365 +2382 +2368 +2384 +2367 +2373 +2353 +2368 +2368 +2384 +2371 +2383 +2368 +2359 +2382 +2352 +2369 +2363 +2355 +2370 +2348 +2366 +2418 +2367 +2352 +2434 +2365 +2321 +2367 +2347 +2364 +2351 +2383 +2384 +2352 +2374 +2167 +2371 +2372 +2385 +2367 +2385 +2385 +2350 +2359 +2379 +2362 +2375 +2366 +2305 +2367 +2366 +2471 +2361 +2365 +2363 +2381 +2357 +2356 +2384 +2378 +2390 +2362 +2364 +2363 +2352 +2365 +2364 +2361 +2353 +2358 +2354 +2352 +2358 +2349 +2367 +2352 +2358 +2368 +2298 +2352 +2368 +2365 +2369 +2352 +2384 +2333 +2377 +2363 +2311 +2349 +2377 +2360 +2352 +2369 +2353 +2395 +2357 +2357 +2355 +2350 +2366 +2359 +2357 +2362 +2367 +2359 +2365 +2350 +2361 +2354 +2360 +2353 +2285 +2352 +2363 +2349 +2355 +2399 +2355 +2361 +2352 +2393 +2362 +2357 +2351 +2368 +2315 +2357 +2360 +2367 +2365 +2279 +2357 +2368 +2363 +2359 +2361 +2368 +2363 +2358 +2480 +2367 +2279 +2341 +2366 +2403 +2353 +2366 +2309 +2323 +2352 +2367 +2336 +2408 +2357 +2347 +2358 +2351 +2420 +2357 +2369 +2335 +2375 +2354 +2373 +2367 +2352 +2348 +2355 +2355 +2368 +2352 +2377 +2331 +2460 +2364 +2336 +2351 +2345 +2350 +2301 +2375 +2355 +2351 +2323 +2352 +2353 +2494 +2354 +2362 +2367 +2353 +2482 +2384 +2355 +2363 +2352 +2337 +2275 +2462 +2354 +2355 +2391 +2350 +2352 +2355 +2328 +2347 +2278 +2358 +2359 +2275 +2365 +2352 +2368 +2359 +2353 +2350 +2354 +2351 +2359 +2352 +2365 +2368 +2333 +2279 +2350 +2362 +2353 +2353 +2358 +2354 +2375 +2350 +2347 +2343 +2353 +2365 +2343 +2354 +2363 +2357 +2343 +2340 +2345 +2354 +2346 +2353 +2355 +2354 + +* Mic branch [2026-04-19 Sun] +INMP441 +heres my overall (very messy) notes. + +i need a stepwise checklist of work to do, picking up this project after 6mo. + +i think broadest steps are: +1. remind myself of circuit state, how to hookup and test +2. implement inmp441 - may need to retool the circuit? + 1. will this functino on the existing power (big goal) + 2. remove/modify any inline circuitry to make this work? +3. ??? test? + +_Goal_: replace noisy speaker-tap adc path with an inmp441 mic path + - reuse existing esp32 + wifi + rtp stack + - reuse existing 3.17v power tap +** checklist +*** Bench Check +- the exact esp32 board +- the vtech dm221-2 / pm221 +- known-good firmware that can stream the 440hz tone over rtp to vlc +- the current ip/ssid/port expectations +- success = you can flash, boot, and hear tone mode again in vlc. this revalidates the network/rtp side before you perturb the input path + +*** Confirm live circuit: +- take clear photos of pcb top/bottom +- mark current power tap location +- mark current speaker/adc wiring +- note whether gpio36 speaker-tap circuit is still installed +- note whether touch pin mode switching is still wired +- your notes show enough circuit churn that future-you will otherwise get gaslit by Past You. + +*** Verify power in isolation: +- measure the 3.17v rail again at tp20/tp12/q6 +- confirm esp32 still boots stably from that rail +- add/confirm local decoupling near esp32 power if needed +- success = stable boot, wifi connect, no brownout/reboot weirdness. you already concluded the 3.17v tap was viable and a major goal is to keep it. + +*** Verify s/w baseline +keep hardware input out of it for a minute: + +- flash the known-good tone generator +- confirm seq/ts behavior and vlc playback +- optionally disable wifi power save while testing +- success = tone stream sounds clean enough that any later ugliness is input-side, not transport-side. + +*** hardware cutover +assume the old speaker-to-gpio36 analog front end gets bypassed or removed: +- gpio36 adc path is no longer the primary input +- the RC/divider/bias network for speaker tap is not needed for the mic path +- keep it only if you explicitly want fallback mode later +- this is the big topology change. don’t half-migrate and leave yourself ambiguous failure modes. your notes already point to the speaker tap being the pain source. + +*** bench-test the inmp441 off the existing esp32 power +- power inmp441 from the same esp32 3.xv rail +- wire only power + ground + i2s lines +- capture raw samples / stream audio with the mic sitting on the bench +- success = it powers and produces stable audio without resets/noise disasters. + +** inmp441 table +| PIN | NAME | FUNCTION | +|-----+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1 | SCK | Serial-Data Clock for IΒ²S Interface | +| 2 | SD | Serial-Data Output for IΒ²S Interface. This pin tri-states when not actively driving the appropriate output channel. The SD trace should have a 100 kΞ© pulldown resistor to discharge the line during the time that all microphones on the bus have tri-stated their outputs. | +| 3 | WS | Serial Data-Word Select for IΒ²S Interface | +| 4 | L/R | Left/Right Channel Select. When set low, the microphone outputs its signal in the left channel of the IΒ²S frame. When set high, the microphone outputs its signal in the right channel. | +| 5 | GND | Ground. Connect to ground on the PCB. | +| 6 | GND | Ground. Connect to ground on the PCB. | +| 7 | VDD | Power, 1.8 V to 3.3 V. This pin should be decoupled to Pin 6 with a 0.1 ΞΌF capacitor. | +| 8 | CHIPEN | Microphone Enable. When set low (ground), the microphone is disabled and put in power-down mode. When set high (VDD), the microphone is enabled. | +| 9 | GND | Ground. Connect to ground on the PCB | + +- added sketch to /proj/vtech/mic + +couple caveats, bc esp32 audio loves being a goblin: +the >> 11 unpack line is the bit most likely to need fiddling on your exact board/core, and I2S_COMM_FORMAT_STAND_I2S vs one of the older enum names can vary by installed core. + +*** script +#+begin_src c +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 25; // +const int I2S_SCK = 26; // +const int I2S_SD = 33; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + // init touch + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; + static unsigned long last_touch_check = 0; + static bool last_touch_state = false; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("switched to %s mode\n", tone_mode ? "tone" : "mic"); + delay(200); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + + // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz + int32_t mic_buf[FRAME_SIZE * 2]; + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + + int frames_read = bytes_read / sizeof(int32_t); + if (frames_read < FRAME_SIZE * 2) { + for (int i = 0; i < FRAME_SIZE; i++) samples[i] = 0; + } else { + static float dc = 0.0f; + static float lpf = 0.0f; + + for (int i = 0; i < FRAME_SIZE; i++) { + // inmp441 data is typically left-justified in 32-bit words; shift may need + // minor tweaking on your exact board/core + int32_t raw = mic_buf[i * 2] >> 14; // collapse toward 16-bit-ish range + float x = (float)raw; + + dc = dc * 0.999f + x * 0.001f; + x -= dc; + + lpf = lpf * 0.7f + x * 0.3f; + float y = lpf * 1.0f; // gain trim try 8.0f? + + if (y > 32767.0f) y = 32767.0f; + if (y < -32768.0f) y = -32768.0f; + samples[i] = (int16_t)y; + } + //DEBUG + static unsigned long last_dbg = 0; + int16_t minv = 32767; + int16_t maxv = -32768; + + for (int j = 0; j < FRAME_SIZE; j++) { + if (samples[j] < minv) minv = samples[j]; + if (samples[j] > maxv) maxv = samples[j]; + } + + if (millis() - last_dbg > 250) { + Serial.printf("mic range: %d .. %d\n", minv, maxv); + last_dbg = millis(); + } + // END DEBUG + } + } + + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} +#+end_src +*** script2 - simple mic processing (ln160 ff) +#+begin_src c +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 25; // +const int I2S_SCK = 26; // +const int I2S_SD = 33; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + // init touch + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; + static unsigned long last_touch_check = 0; + static bool last_touch_state = false; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + + // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz + int32_t mic_buf[FRAME_SIZE * 2]; + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + + int frames_read = bytes_read / sizeof(int32_t); + if (frames_read < FRAME_SIZE * 2) { + for (int i = 0; i < FRAME_SIZE; i++) samples[i] = 0; + } else { + static float dc = 0.0f; + static float lpf = 0.0f; + // + int16_t minv = 32767; + int16_t maxv = -32768; + static unsigned long last_dbg = 0; + + for (int i = 0; i < FRAME_SIZE; i++) { + int32_t raw = mic_buf[i * 2] >> 8; // try 8 first, not 14 + if (raw > 32767) raw = 32767; + if (raw < -32768) raw = -32768; + samples[i] = (int16_t)raw; + + if (samples[i] < minv) minv = samples[i]; + if (samples[i] > maxv) maxv = samples[i]; + } + + if (millis() - last_dbg > 250) { + Serial.printf("raw range: %d .. %d\n", minv, maxv); + last_dbg = millis(); + } + } + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} +#+end_src +*** script3 - hex dump version: +#+begin_src c++ +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 25; // +const int I2S_SCK = 26; // +const int I2S_SD = 33; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + // init touch + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; + static unsigned long last_touch_check = 0; + static bool last_touch_state = false; + static unsigned long last_dbg = 0; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + + // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz + int32_t mic_buf[FRAME_SIZE * 2]; + + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + for (int i = 0; i < FRAME_SIZE; i++) { + samples[i] = 0; + } + + if (bytes_read >= 16 * sizeof(int32_t) && millis() - last_dbg > 500) { + Serial.println("first 16 raw words:"); + for (int i = 0; i < 16; i++) { + Serial.printf("%2d: 0x%08lx\n", i, (uint32_t)mic_buf[i]); + } + last_dbg = millis(); + } + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} +#+end_src + +** issue +https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/ +- dump is overwhelmingly 0x00000000, 0x00000001, or 0xffffffff, with only very occasional nontrivial words like 0xffbffb41. that means the esp32 is clocking something, but it is mostly seeing a line that is effectively stuck low/high or only barely transitioning, not normal audio sample words. +- in esp32 standard i2s mode, the bus is just bclk, ws, and data, and standard mode always has left/right slots. in master mode, the esp32 generates sck and ws; the mic only drives the data line. +- standard-mode format differences on esp32 are basically philips vs msb, where philips has a one-bit shift relative to ws and msb does not. so β€œwrong format” can cause junk, but a stream dominated by exact 0/1/-1 patterns is more consistent with bad data capture than mere gain. +* [2026-04-20 Mon] +very useful expl thanks, you're refreshign my memory on the rtp header work i did a few months ago. good insight on 440hz wandering - i didnt account for network instability inherent in the chipset, of course that makes sense. + +heres the mic datasheet. + +(WHT) LR GND (BLK) +(YEL) WS VDD (RED) +(WHT) SCK SD (BLUE) + + +gnd (WHT) LR GND (BLK) +g25 (YEL) WS VDD (RED) +g22 (WHT) SCK SD (BLUE) g21 + +mic outputs 24-bit signed sample, left-justified in 32-bit word +[31........8][7.....0] + sample pad + +** successful hex word test of inmf441 +#+begin_src c++ +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 25; // +const int I2S_SCK = 22; // +const int I2S_SD = 21; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + // .communication_format = I2S_COMM_FORMAT_I2S_MSB, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; // timer + static unsigned long last_touch_check = 0; // timer + static bool last_touch_state = false; + static unsigned long last_dbg = 0; // timer + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + + // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz + int32_t mic_buf[FRAME_SIZE * 2]; + + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + for (int i = 0; i < FRAME_SIZE; i++) { + samples[i] = 0; + } + + if (bytes_read >= 16 * sizeof(int32_t) && millis() - last_dbg > 500) { + Serial.println("first 16 raw words:"); + for (int i = 0; i < 16; i++) { + Serial.printf("%2d: 0x%08lx\n", i, (uint32_t)mic_buf[i]); + } + last_dbg = millis(); + } + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} +#+end_src +** to add +dc gain +dc = dc * 0.999f + x * 0.001f; +x -= dc; + +low pass filter +lpf = lpf * 0.7f + x * 0.3f; + +gain +float y = x * 2.0f; +before adding gains: +#+begin_src C++ + #include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 25; // +const int I2S_SCK = 22; // +const int I2S_SD = 21; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + // .communication_format = I2S_COMM_FORMAT_I2S_MSB, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; // timer + static unsigned long last_touch_check = 0; // timer + static bool last_touch_state = false; + static unsigned long last_dbg = 0; // timer + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + + // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz + int32_t mic_buf[FRAME_SIZE * 2]; + size_t bytes_read = 0; + + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + + for (int i = 0; i < FRAME_SIZE; i++) { + // decimate 16k β†’ 8k + int32_t raw = mic_buf[i * 2] >> 16; // decimate 16k -> 8k by keeping every other sample + if (raw > 32767) raw = 32767; + if (raw < -32768) raw = -32768; + samples[i] = (int16_t)raw; + } + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} + +#+end_src + +after gains SUCCESS IWTH SOUND! +#+begin_src c++ + #include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 25; // +const int I2S_SCK = 22; // +const int I2S_SD = 21; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + // .communication_format = I2S_COMM_FORMAT_I2S_MSB, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; // timer + static unsigned long last_touch_check = 0; // timer + static bool last_touch_state = false; + static unsigned long last_dbg = 0; // timer + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + + // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz + int32_t mic_buf[FRAME_SIZE * 2]; + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + + //debug + if (millis() - last_dbg > 500) { + for (int i = 0; i < 8; i++) { + Serial.printf("%d: 0x%08lx\n", i, (uint32_t)mic_buf[i]); + } + last_dbg = millis(); + } + //end debug + + for (int i = 0; i < FRAME_SIZE; i++) { + // decimate 16k β†’ 8k + int32_t raw = mic_buf[i] >> 16; // full send + // int32_t raw = mic_buf[i*2] >> 16; // drop every other frame to get to 8k + samples[i] = (int16_t)raw; + } + + int16_t minv = 32767; + int16_t maxv = -32768; + + for (int j = 0; j < FRAME_SIZE; j++) { + if (samples[j] < minv) minv = samples[j]; + if (samples[j] > maxv) maxv = samples[j]; + } + //debug2 + if (millis() - last_dbg > 500) { + Serial.printf("mic range: %d .. %d\n", minv, maxv); + } + //end debug2 + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} + +#+end_src + +likely slow bc of full send line: +: int32_t raw = mic_buf[i] >> 16; // full send + +** done +#+begin_src c++ + #include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 8000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 500; + +const int I2S_WS = 25; +const int I2S_SCK = 22; +const int I2S_SD = 21; + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; // timer + static unsigned long last_touch_check = 0; // timer + static bool last_touch_state = false; + static unsigned long last_dbg = 0; // timer + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // frame buffer + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + int32_t mic_buf[FRAME_SIZE]; + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + + for (int i = 0; i < FRAME_SIZE; i++) { + float y = (mic_buf[i] >> 16) * 4.0f; //gain + if (y > 32767.0f) y = 32767.0f; + if (y < -32768.0f) y = -32768.0f; + samples[i] = (int16_t)y; + } + + int16_t minv = 32767; + int16_t maxv = -32768; + + for (int j = 0; j < FRAME_SIZE; j++) { + if (samples[j] < minv) minv = samples[j]; + if (samples[j] > maxv) maxv = samples[j]; + } + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} + +#+end_src +* Final Veersion mic.cpp +#+begin_src c++ +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 8000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; +const float MIC_GAIN = 4.0f; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 500; + +const int I2S_WS = 25; +const int I2S_SCK = 22; +const int I2S_SD = 21; + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; // timer + static unsigned long last_touch_check = 0; // timer + static bool last_touch_state = false; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // frame buffer + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + int32_t mic_buf[FRAME_SIZE]; + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + + if (bytes_read != sizeof(mic_buf)) { + memset(samples, 0, sizeof(samples)); + } else { + for (int i = 0; i < FRAME_SIZE; i++) { + float y = (mic_buf[i] >> 16) * MIC_GAIN; //gain + if (y > 32767.0f) y = 32767.0f; + if (y < -32768.0f) y = -32768.0f; + samples[i] = (int16_t)y; + } + } + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} + +#+end_src +** optimize: +* TODOs +- add pot knob gain, middle at 4.0f +- web server interface/config - need to load wifi creds etc + +try hardcoded station connect +if fail, start softap + web portal +from portal, optionally save new ssid/pwd and switch to station mode diff --git a/vtech.org~ b/vtech.org~ new file mode 100644 index 0000000..7d66a8e --- /dev/null +++ b/vtech.org~ @@ -0,0 +1,17597 @@ +C:\Users\moses\Documents\Arduino\ +migrated from notes.org [2026-04-19 Sun] +* ESP32-DEVKIT-V1 +** diagram + ----------------- + EN | |_|Μ… |_|Μ… |_|Μ… |_| | D23 + VP | | D22 GPIO22 I2C_SCL + VN | β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” | TX0 UART + D34 | β”‚ β”‚ | RXO UART + D35 | β”‚ β”‚ | D21 GPIO21 I2C_SDA + D32 | β”‚ β”‚ | D19 +GPIO33 D33 | β”‚ β”‚ | D18 +GPIO25 D25 | β”‚ β”‚ | D5 +GPIO26 D26 | β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ | TX2 + D27 | | RX2 + D14 | | D4 + D12 | | D2 + D13 | | D15 + GND | | GND + VN | | 3V3 + | | + ----------------- + en usb boot + +** pinlist +EN,VP,VN,D34,D35,D32,D33,D25,D26,D27,D14,D12,D13,GND,VN,3V3,GND,D15,D2,D4,RX2,TX2,D5,D18,D19,D21,RX0,TX0,D22,D23 +** vertical pins +EN +VP +VN +D34 +D35 +D32 +D33 +D25 +D26 +D27 +D14 +D12 +D13 +GND +VN + +3V3 +GND +D15 +D2 +D4 +RX2 +TX2 +D5 +D18 +D19 +D21 +RX0 +TX0 +D22 +D23 + + + +* esp32 + vtech baby monitor [2025-07-27 Sun] +tap speaker to gpio36 +need to power (vtech is 6V) +esp32wroom vreg is 11 17c / 33 d323; it shoudl be able to take 6v ok +consider adding a button to turn on/off the esp32 +then add voltage divider bt +* baby monitor [2025-09-03 Wed] +this baby monitor (vtech dm221-2) runs at 6V DC, i want to tap a 3V or 5V pin to run an esp32 so i can tap the speaker on an ADC and broadcast it over wifi. here's a pic of the board - i tested some pads and components: + +SOT23-3 package: (1pin on top, two on bottom), commong for transistors, diodes, vreg + +Q1 lone pin is 3.7V +Q6 bottom pins are 3.17V (L) and 3.6V (R) +TP20: 3.17V +TP12: 3.17V +TP21: 3.77V + +i might be able to tap an LED? but those are more likely to be current limited right + +- look for 3-pin regulators (SOT23) - middle pin is usually output +- check caps near the main processor - usually fed by the clean 3.3V rail +- that U401 chip in the upper section might be a regulator too + + + also maybe add a small decoupling cap (10uF) close to your tap point bc esp32s are kinda noisy when they boot + + +https://randomnerdtutorials.com/esp32-pinout-reference-gpios/ + + +https://discord.com/api/webhooks/1411806429576429799/zRFcDio3B_BSxFQ8Rus2gMrJhkpC6olXCGgdZ71L3_7zAxsm2Cy86VBynUxcPNfwq4Xg + +** wireshark packets +https://support.adder.com/tiki/tiki-index.php?page=Network%3A+Using+Wireshark+to+check+if+IGMP+is+configured + +- start collection on Ethernet3 +- _Do NOT leave this running!!_ Collect and STOP to analyze +- DisplayFilter is not CaptureFilter; default is collect all and display some! + CaptureFilter syntax: https://wiki.wireshark.org/CaptureFilters#capture-filter-is-not-a-display-filter +- Create a CaptureFilter eg "src 192.168.1.145 and port 5004" +- DisplayFilter syntax eg "udp.port==5004 && ip.src==192.268.1.145" + +add filter: ip.dst==224.0.0.0/4 +IGMP should ounly show traffic to dest 239.255.x.x if someone's listening (me). + +- first few bytes are packet headers! src/dest. bottom left pane, see "Data (172 bytes)" and click, it will highlight the bytes on the right pane. THIS is where your datagram headers are. + +RTP headers: +byte 0: 0x80 (v=2, p=0, x=0, cc=0) +byte 1: 0x00 (m=0, pt=0 β†’ pcmu) +byte 2-3: sequence number (big endian) +byte 4-7: timestamp (big endian) +byte 8-11: ssrc (big endian, arbitrary) + +first packet might look like (seq=1,ts=0,ssrc=0x12345678): +80 00 00 01 00 00 00 00 12 34 56 78 + +** my first headers look like _WRONG! this was 0000, 0010, not 0000 0001_ +d8 43 ae 28 55 33 6c c8 00 c8 d3 df +after manual construction of headers: +d8 43 ae 28 55 33 6c c8 00 c8 b4 b4 + +should be +0x80 0x00 00 01 00 00 00 01 12 34 56 78 + +d8 43 ae 28 55 33 6c c8 40 8a bd 80 08 00 45 00 + +** sample - data begins on byte 6! +0000 d8 43 ae 28 55 33 6c c8 40 8a bd 80 08 00 45 00 +0010 00 c8 94 45 00 00 40 11 61 9a c0 a8 01 91 c0 a8 +0020 01 64 13 8c 13 8c 00 b4 2b 5b 80 00 94 43 00 fc +0030 a9 e0 12 34 56 78 ff ff ff ff ff ff ff ff ff ff +0040 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0050 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0060 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0070 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0080 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +0090 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +00a0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +00b0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +00c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +00d0 ff ff ff ff ff ff ...... + +DOIT ESP32 DEVKIT V1 +Serial: baud 115200 + +htons() "host-to-network short" converts a short integer from host byte order to network byte order, swapping bytes if needed, for 16-bit values. + +htonl() "host-to-network long" converts u_long from host to TCP/IP network order (big-endian) + + +https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32/api-reference/peripherals/adc.html + +For ADC1, configure desired precision and attenuation by calling functions adc1_config_width() and adc1_config_channel_atten(). + + +PCM5102 I2S DAC board? + +8000d10f0122a96012345678a198929091969eb33f2319131011161e2fc7a599939091959dad4f261a131011151c2bdda89b949091949baaf92a1b141110141b285aac9c959190939aa6cd2e1d15111013192445b09e9691909398a2be341f1712101218213bb79f97929092979fb73b211 + +8000d1100122aa00123456781a264dae9d9591909399a4c5301e1611101318223eb49f9792909298a1bb371f17121012171f37bba198929091969eb33f2319131011161e2fc7a599939091959dad4f261a131011151c2bdda89b949091949baaf92a1b141110141b285aac9c959190939aa + +8000d1110122aaa012345678131011151d2dcfa69a939091959cab5d281b141011141b2a79aa9b949190949ba8da2c1c151110131a264dae9d9591909399a4c5301e1611101318223eb49f9792909298a1bb371f17121012171f37bba198929091969eb33f2319131011161e2fc7a599939 + +*** packet analysis +you lost me. I'm seeing these two bits increment per-packet in byte 6 (first two bits belong to UDP header/checksum): +[] [] 80 00 55 fe 00 35 +[] [] 80 00 55 ff 00 35 +[] [] 80 00 56 00 00 35 +[] [] 80 00 56 00 01 35 +this looks like bits 2-3 are simply incrementing per packet, which is exactly what our code says ("hdr->seq = htons(seq++)"), only q is whether that's correct? + +here's what i'm seeing in the serial out: +80 00 00 00 00 00 00 00 12 34 56 78 +80 00 00 01 00 00 00 a0 12 34 56 78 +80 00 00 02 00 00 01 40 12 34 56 78 +80 00 00 03 00 00 01 e0 12 34 56 78 +80 00 00 04 00 00 02 80 12 34 56 78 +80 00 00 05 00 00 03 20 12 34 56 78 +80 00 00 06 00 00 03 c0 12 34 56 78 +80 00 00 07 00 00 04 60 12 34 56 78 +80 00 00 08 00 00 05 00 12 34 56 78 + +another few lines from WS (obv not the same packets): +80 00 08 61 00 05 3c a0 12 34 56 78 +80 00 08 62 00 05 3d 40 12 34 56 78 +80 00 08 63 00 05 3d e0 12 34 56 78 + +** vlc sdp file - this never worked! +use rtp://192.168.1.100:5004 +** file +v=0 +o=- 0 0 IN IP4 192.168.1.100 +s=ESP32 Tone +c=IN IP4 192.168.1.100 +t=0 0 +m=audio 5004 RTP/AVP 0 +a=rtpmap:0 PCMU/8000 +a=sendonly + +* new notes vtech [2025-09-04 Thu] +tone2 - claude claude tone works! +check the ulaw function deeply, and packet vs payload formation - i dont see memcpy in the functioning tonegen code, just a raw feeding of the packet into the ulaw function, appending header, and firing it off? + +Checklist: +- first 12 bytes: 80 00 SS SS TT TT TT TT XX XX XX XX +- packet length: 12 + 160 = 172 bytes +- inter-packet gap: ~20 ms +- seq monotonic +1; ts monotonic +160; stable ssrc +- vlc opens via rtp://@:5004 or sdp with a=rtpmap:0 PCMU/8000 + +** working udp-tone2 claude +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.100"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz +const int FRAME_SIZE = 160; // 20ms frames +const float TONE_HZ = 440.0; + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup() { + Serial.begin(115200); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); +} + +float phase = 0; +const float phase_inc = 2.0 * M_PI * TONE_HZ / OUTPUT_RATE; + +void loop() { + static unsigned long last_send = 0; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + + // only send if it's time + unsigned long now = millis(); + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + // generate 20ms tone + for (int i=0; i 2*M_PI) phase -= 2*M_PI; + } + + // Β΅-law encode + for (int i=0; ivpxcc = 0x80; // v=2, p=0, x=0, cc=0 + hdr->mpt = 0x00; // m=0, pt=0 (PCMU) + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + // send packet + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} +** orig file to integrate +#include +// #include +#include +// #include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* MULTICAST_IP = "239.255.0.1"; +const char* DEST_IP = "192.168.1.100"; +const int UDP_PORT = 5004; +const int SAMPLE_RATE = 32000; +const int OUTPUT_RATE = 8000; +const int FRAME_SIZE = 160; +static bool blink = false; + +const i2s_port_t I2S_PORT = I2S_NUM_0; +const adc1_channel_t ADC_CHANNEL = ADC1_CHANNEL_0; //gpio36 + +char id_str[17]; +char status_id[32]; + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; + +// rtp header struct (minimal) +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +// Β΅-law encode +uint8_t linear2ulaw(int16_t pcm_val) { + const int BIAS = 0x84; + const int CLIP = 32635; + int mask, seg, uval; + pcm_val = pcm_val >> 2; // bitshift right 2^arg (2), unsure if this works? if pcm value is encoded + if (pcm_val < 0) { + pcm_val = -pcm_val; + mask = 0x7F; + } else mask = 0xFF; + if (pcm_val > CLIP) pcm_val = CLIP; + pcm_val += BIAS; + seg = 7; + for (int v = pcm_val; v > 0x3F; v >>= 1) seg--; + uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF); + return (uval ^ mask); +} + +void setup_i2s() { + i2s_config_t cfg = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_ADC_BUILT_IN), + .sample_rate = SAMPLE_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_I2S_MSB, + .intr_alloc_flags = 0, + .dma_buf_count = 4, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = true + }; + i2s_driver_install(I2S_PORT, &cfg, 0, NULL); + i2s_set_adc_mode(ADC_UNIT_1, ADC_CHANNEL); + i2s_adc_enable(I2S_PORT); +} + +void setup() { + uint64_t chipid = ESP.getEfuseMac(); + snprintf(id_str, sizeof(id_str), "%04X", (uint16_t)(chipid >>32)); + + Serial.begin(115200); //begin serial connection for debugging + // delay(200); // pause for usb host + WiFi.begin(ssid, password); + Serial.printf("[wifi] "); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf(" connected %s with ip %s\n", id_str, WiFi.localIP().toString().c_str()); + + setup_i2s(); + Serial.printf("[udp] "); + if (udp.begin(UDP_PORT)) { + Serial.printf("listening on port %d\n", UDP_PORT); + } else { + Serial.println(" failed to bind\n"); + } +} + +void loop() { + int16_t samples[FRAME_SIZE*2]; // 320 samples @ 16kHz = 20ms; adc is tied to clock speed + size_t bytes_read; + i2s_read(I2S_PORT, (char*)samples, sizeof(samples), &bytes_read, portMAX_DELAY); + + if (bytes_read == 0) { Serial.println("[i2s] no samples read\n"); return; } + + uint8_t payload[FRAME_SIZE]; + for (int i=0;ivpxcc = 0x80; // v=2 + hdr->mpt = 0x00; // payload type 0 = PCMU + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + memcpy(packet+12, payload, FRAME_SIZE); + + if (udp.beginPacket(DEST_IP, UDP_PORT)) { + udp.write(packet, sizeof(packet)); + udp.endPacket(); + Serial.print("\r"); + Serial.print(blink ? '.' : ' '); + Serial.flush(); + blink = !blink; + }; + + ts += FRAME_SIZE; // 20ms worth of samples +} + +** compairson bt tonegen and original: +loop() ++ last_send, frame interval + +samples[ framesize] + +** TODO variant tonegen with multicast + +* circuit descr +the adc (GPIO36) is connected to a vtech pm221 speaker through an RC circuit w/ voltage divider: +SP+ to C1 to node A to R1 to node B to Rf to GPIO36; +Node B to R2 to node c to SP-; +Cf connects node c and node a. +GPIO36 is biased with two 1M resistors connected to 3V3 and GND pins. +C1 = 1 uF, Cf = 4.7nF, R1 = 22k, R2 = 10k, Rf = 1k +SP+ --- C1 --- a --- R1 --- b --- Rf --- GPIO --- d --- 1M --- GND + | | | +SP- --------- C2 --------- R2 1M --- 3V3 + +* prompt +gravity check this: +esp32 script streams udp data (rtp) +mode 1: send 440hz default on launch (works) +mode 2: (toggle mode on tapping pin) stream from ADC pin + +the adc (GPIO36) is connected to a vtech pm221 speaker through an RC circuit w/ voltage divider: +SP+ to C1 to node A to R1 to node B to Rf to GPIO36; +Node B to R2 to node c to SP-; +Cf connects node c and node a. +GPIO36 is biased with two 1M resistors connected to 3V3 and GND pins. +C1 = 1 uF, Cf = 4.7nF, R1 = 22k, R2 = 10k, Rf = 1k +``` +SP+ --- C1 --- a --- R1 --- b --- Rf --- GPIO --- d --- 1M --- GND + | | | +SP- --------- Cf --------- R2 1M --- 3V3 +``` + +need to troubleshoot this, either the circuit is wrong, or the ADC implementation. +before i redesign the circuit again, i'd like to know how i can test the ADC to be sure it's working; how would i create a 440Hz tone i can feed to the ADC that would be interpreted by our algorithm? +the program is right, because I can send the 440hz sine wave through it and it works! +so it's almost certainly an issue with the cercuit. + +* voltage/adc test 1 [2025-09-02 Tue] +- GND and 43V3 show 4095 range is good! and we're sitting at the midpoint +- voltage is confirmed (3.3v at 3V3 and 0V at GND) +- SP+ and SP- sit at 1.6V; ADC sits at 1.6V when idle +** data +switched to mic mode +4039-4095 +3997-4095 +3951-4095 +4023-4095 +4095-4095 +0-1994 +0-366 +0-366 +0-0 +0-0 +0-0 +0-0 +0-0 +0-0 +0-1087 +1489-2135 +1456-2150 +1493-2257 +1465-2636 +1299-2598 +1463-2177 +1522-2191 +1535-2261 + +** test2 +... + connected, ip=192.168.1.145 + tap pin 4 to switch modes +switched to mic mode +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:2698-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-1690(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-512(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:375-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-3909(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:3101-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryfcircuitworks) +adcrange:0-3101(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) +adcrange:509-4095(shouldvaryifcircuitworks) +adcrange:0-4095(shouldvaryifcircuitworks) + +** after 1M bias both directions +948-2559 +1376-2645 +1776-2866 +1535-2976 +1411-2640 +895-2093 +921-2638 +1119-2496 +1719-2878 +1422-3535 +1383-2812 +1041-2290 +991-2496 +956-2641 +1503-2837 +1731-2797 +1307-2951 +1055-2778 +976-2686 +983-2559 +1535-2870 +1475-2987 +1452-2896 +812-2272 +1019-2096 +852-2596 +1616-2867 +1739-2805 +1417-2734 +951-2380 +911-2245 +855-2549 +1611-2992 +1733-3344 +1236-2799 +976-2190 +1011-2503 +959-2526 +1702-2976 +1489-2839 +1215-3424 +959-2206 +956-2691 +1214-2480 +1645-2801 +1437-2989 +847-2551 +1126-2176 +849-2590 +1486-2879 +1655-2837 +1424-2881 +763-2232 +976-2128 +975-2734 +1555-2876 +1711-3258 +1232-3037 +1104-2457 +808-2144 +799-2854 +1535-3453 +1653-3236 +1313-2811 +934-2172 +1006-2784 +969-2588 +1525-3474 +1573-2872 +1329-3504 +829-2864 +921-2156 +1040-2542 +1136-2985 +1682-2921 +1495-2895 +1033-2694(shouldvar +yifcircuitworks) +912-2123 +998-2606 +1294-2541 +1617-3219 +1390-3737 +1383-2992 +1023-2309 +948-2391 +1043-2490 +1731-2804 +1567-2835 +1391-2976 +917-2224 +884-2262 +1111-2534 +1725-2976 +1500-2797 +1406-2653 +787-2205 +1023-2486 +1189-2517 +1580-2915 +1509-2954 + +** after circuit swap (this is way worse) +adc range: 0-602 (should vary if circuit works) +adc range: 0-487 (should vary if circuit works) +adc range: 0-400 (should vary if circuit works) +adc range: 0-112 (should vary if circuit works) +adc range: 0-621 (should vary if circuit works) +adc range: 0-570 (should vary if circuit works) +adc range: 0-659 (should vary if circuit works) +adc range: 0-325 (should vary if circuit works) +adc range: 0-63 (should vary if circuit works) +adc range: 0-418 (should vary if circuit works) + +* [2025-09-03 Wed] +1687/1746 to 2041 + +... +connected, ip=192.168.1.145 +tap pin 4 to switch modes +switched to mic mode +adc range: 1746-1971 (should vary if circuit works) +adc range: 1733-1966 (should vary if circuit works) +adc range: 1754-1965 (should vary if circuit works) +adc range: 1755-1965 (should vary if circuit works) +adc range: 1702-2009 (should vary if circuit works) +adc range: 1675-1957 (should vary if circuit works) +adc range: 1696-2041 (should vary if circuit works) +adc range: 1686-1962 (should vary if circuit works) +adc range: 1741-2004 (should vary if circuit works) +adc range: 1687-1965 (should vary if circuit works) +adc range: 1735-1957 (should vary if circuit works) +adc range: 1718-2031 (should vary if circuit works) +adc range: 1714-2000 (should vary if circuit works) + + +** funcgen +FG- to ESP32 ground +FG+ to GPIO36, then to SP+ +recognizable tone once DC offset turned on (~halfway bt 0/+) + (anything above this resets ESP32) +amplitude knob made little/no difference + (too high resets the ESP32) + +tone very choppy and _not_ 440Hz +no tone difference bt GPIO and SP+; + either wired wrong (possible) or + circuit is functioning (not impacting input) + +i'm thinking, we shouldnt expect adc serialout to be useful, unless i send a value ~1Hz +so let's generate that first: add a function to generate a 0.5 or .25Hz wave, + so that we can see the ADC values change in the serial out; + we should see values fluctuate between 0 and 4096, + and if we sync the timing right, should get a proper sense of the range right? + +** ok ran some basic tests +- ADC confirmed w dmm: 3.3v when ADC-3V3 and 0V when ADC-GND +- SP+ and SP- sit at 1.6V; ADC sits at 1.6V when idle +- ADC shows 0 at GND and 4095 at 3V3; midpoint ~2k when idle, with some noise +- FG- to ESP32 ground; FG+ to GPIO36, then to SP+. + recognizable tone once DC offset turned on (~halfway bt "0"/"+") + +tone very choppy and _not_ 440Hz, still comes in pulses where the audio cuts ~twice/sec. no tone difference bt connecting FG+ to GPIO vs SP+, indicating the code has more impact than the circuit. Upping to 540 and 640 Hz, I _can_ hear streaming tone go up - good sign! However the ESP-generated 440Hz tone in tone_mode also walks around a bit - this could be another (separate) problem in the ulaw/packetization logic. + +i removed the sampling limiter and moved the print to output adv_val directly after: samples[i] = int16_t)((adv_val-2048)*16); +So this is actually _upstream_ of packetization... but it's still crazy noisy, here's some data: +- 0.1Hz wave ranges from ~2100-2650, with noise usually +/-80, but spikes as big as 150 in both directions +- 1Hz wave ranges from ~2075-2650, with noise usually +/-80 +- 440Hz wave is essentially unrecognizable, though sample rate is def playing a role; range is the same (2075-2750). + +So we're currently using 25% of available bandwidth; need to scale ADC better. First, we need to look closely at the ADC reader/scale at lines 115-125: is this doing what we want? +#+begin_src c++ + static int debug_counter = 0; + int min_val = 4095, max_val = 0; + for (int i = 0; i < FRAME_SIZE; i++) { + int adc_val = adc1_get_raw(ADC1_CHANNEL_0); + if (adc_val < min_val) min_val = adc_val; + if (adc_val > max_val) max_val = adc_val; + // convert 12-bit adc (0-4095) to signed 16-bit (-32768 to 32767) + samples[i] = (int16_t)((adc_val - 2048) * 16); // center around 0, scale up + Serial.printf("%d\n", adc_val); //remove + } +#+end_src +Then, at the ulaw encoder: +#+begin_src c++ +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} +#+end_src + +claude_v3_functionaladc - decent 440hz tone, still walks a little; music playing through monitor is audible but chops every ~1s, and a high-pitched whiny tone is on top + +** python plot simple - see final version ~/Documents/Arduino/udp-tone-ai/plots +#+begin_src python +s = +title = "" +import plotly.graph_objects as go +import pandas as pd + +data = [(int(x.split(',')[0]), int(x.split(',')[1])) for x in s.split('\n')] +lows, highs = zip(*data) +x = list(range(len(data))) +go.Figure([go.Scatter(x=x, y=lows, name='low'),go.Scatter(x=x, y=highs, name='high')],title=title).show() + +#+end_src +** putty output +# use Tee-Object to output to console AND a file +$ plink -serial COM3 -sercfg 115200 | tee-object -FilePath "plink.log" +this is the winner! + +*** _other variants_ untested + +putty -serial COM3 -sercfg 115200,8,n,1,N | -sessionlog C:\users\moses\putty.log -logoverwrite +plink -serial COM3 -sercfg 115200 > plink.log + + +#+begin_src powershell +$port = new-Object System.IO.Ports.SerialPort COM3,115200,None,8,one +$port.Open() +while($true) { + if($port.BytesToRead -gt 0) { + $data = $port.ReadLine() + "$data" | Tee-Object -Append -FilePath serial.log + } +} +#+end_src + +** data +2096 +2073 +2095 +2081 +2095 +2096 +2095 +2086 +2096 +2096 +2083 +2093 +2083 +2080 +2073 +2078 +2098 +2077 +2096 +2093 +2096 +2101 +2006 +2096 +2160 +2096 +2079 +2090 +2093 +2077 +2097 +2064 +2096 +2092 +2076 +2085 +2087 +2096 +2090 +2086 +2096 +2082 +2135 +2183 +2087 +2090 +2087 +2058 +2091 +2091 +2082 +2151 +2088 +2083 +2105 +2082 +2094 +2077 +2095 +2091 +2085 +2066 +2086 +2096 +2139 +2078 +2096 +2096 +2097 +2098 +2093 +2109 +2096 +2098 +2096 +2085 +2096 +2075 +2076 +2096 +2094 +2095 +2095 +2067 +2097 +2083 +2089 +2107 +2134 +2107 +2080 +2096 +2094 +2197 +2043 +2176 +2133 +2007 +2032 +2045 +2114 +2075 +2117 +2087 +2145 +2104 +2106 +2096 +2086 +2065 +2096 +2117 +2094 +2108 +2109 +2105 +2097 +2097 +2096 +2087 +2079 +2096 +2007 +2101 +2111 +2096 +2089 +1990 +2087 +2081 +2082 +2100 +2101 +2089 +2097 +2097 +2092 +2105 +2091 +2071 +2096 +2057 +2096 +2098 +2095 +2096 +2096 +2085 +2093 +2123 +2080 +2090 +2096 +2089 +2089 +2119 +2087 +2083 +2071 +2087 +2010 +2046 +2084 +2074 +2083 +2085 +2096 +2079 +2064 +2080 +2095 +2094 +2139 +2090 +2085 +2081 +2089 +2075 +2095 +2090 +2032 +2090 +2096 +2090 +2082 +2085 +2097 +2096 +2074 +2083 +2075 +2115 +2079 +2125 +2096 +2082 +2192 +2091 +2103 +2080 +2174 +2083 +2093 +2096 +2097 +2096 +2086 +2100 +2061 +2092 +2091 +2094 +2096 +2091 +2085 +2092 +2085 +1977 +2092 +2102 +2091 +2079 +2096 +2002 +2096 +2103 +2065 +2083 +2096 +2094 +2171 +2088 +2098 +2112 +2096 +2095 +2090 +2105 +2054 +2096 +1972 +2119 +2096 +2083 +2103 +2078 +2036 +2097 +2083 +2090 +2066 +2091 +2099 +2080 +2112 +2082 +2104 +2099 +2160 +2097 +2109 +2093 +2093 +2096 +2087 +2117 +1984 +2096 +2063 +2061 +2096 +2112 +2078 +2102 +2099 +2081 +2099 +2103 +2066 +2098 +2103 +2187 +2102 +2095 +2097 +2093 +2086 +2126 +2063 +2088 +2096 +2043 +2106 +2073 +2105 +2114 +2099 +2099 +2107 +2096 +2086 +2100 +2103 +2215 +2101 +2119 +2102 +2055 +2096 +2101 +2086 +2101 +2128 +2061 +2099 +2109 +2109 +2100 +2097 +2115 +2046 +2055 +2093 +2083 +2135 +2081 +1997 +2073 +2096 +2103 +2098 +2081 +2085 +2096 +2099 +2103 +2081 +2096 +2096 +2100 +2074 +2100 +2105 +2096 +2073 +2069 +2097 +2097 +2068 +2085 +2096 +2096 +2091 +2095 +2137 +2095 +2096 +2096 +2096 +2096 +2097 +2089 +2116 +2106 +2111 +2096 +2111 +2044 +2112 +2080 +2075 +2097 +2106 +2064 +2105 +2093 +2032 +2114 +2076 +2083 +2095 +2103 +2160 +2112 +2098 +2098 +2098 +2102 +2091 +2089 +2096 +2096 +2115 +2091 +2094 +2074 +2112 +2090 +2096 +2096 +2116 +2083 +2094 +2096 +2091 +2094 +2129 +2089 +2105 +2116 +2096 +2098 +2085 +2096 +2087 +2135 +2085 +2096 +2101 +2093 +2115 +2101 +2101 +2103 +2107 +2106 +2080 +1989 +2070 +2097 +2144 +2099 +2117 +2064 +2096 +2038 +2106 +2096 +2120 +2097 +2096 +2205 +2113 +2099 +2103 +2096 +2098 +2108 +2087 +2108 +2097 +2106 +2109 +2110 +2097 +2107 +2111 +2188 +2130 +2105 +2206 +2112 +2101 +2112 +2089 +2095 +2112 +2098 +2103 +2121 +2072 +2119 +2114 +2100 +2106 +2113 +2112 +2119 +2103 +2098 +2104 +2119 +2103 +2041 +2143 +2096 +2112 +2105 +2106 +2109 +2097 +2091 +2055 +2128 +2109 +2101 +2097 +2135 +2064 +2057 +2094 +2106 +2096 +2092 +2090 +2143 +2090 +2097 +2094 +2092 +2074 +2118 +2113 +2119 +2112 +2107 +2128 +2095 +2096 +2158 +2094 +2106 +2112 +2092 +2073 +2085 +2041 +2098 +2095 +2096 +2202 +2074 +2110 +2103 +2105 +2126 +2096 +2122 +2163 +2071 +2109 +2115 +2109 +2068 +2096 +2037 +2105 +2108 +2133 +2128 +2085 +2107 +2105 +2194 +2065 +2103 +2112 +2093 +2079 +2118 +2103 +2103 +2107 +2070 +2113 +2091 +2105 +2085 +2090 +2111 +2112 +2192 +2110 +2097 +2098 +2107 +2087 +2121 +2091 +2114 +2108 +2094 +2096 +2128 +2110 +2117 +2109 +1971 +2145 +2092 +2098 +2078 +2086 +2093 +2079 +2107 +2096 +2161 +2111 +2096 +2102 +2097 +2102 +2096 +2015 +2107 +2094 +2034 +2101 +2032 +2141 +2097 +2090 +2085 +2000 +2107 +2175 +2005 +2105 +2220 +2096 +2123 +2117 +2112 +2122 +2103 +2089 +2113 +2124 +2025 +2147 +2117 +2111 +2058 +2102 +2102 +2096 +2106 +2109 +2111 +2111 +2112 +2094 +2112 +2109 +2095 +2118 +2106 +2091 +2098 +2111 +2033 +2105 +2106 +2109 +2093 +2114 +2096 +2100 +2112 +2109 +2106 +2109 +2117 +2066 +2070 +2065 +2110 +2080 +2129 +2093 +2100 +2106 +2111 +2115 +2142 +2124 +2101 +2045 +2125 +2212 +2139 +2105 +2128 +2103 +2121 +2104 +2107 +2102 +2117 +2107 +2096 +2094 +2106 +2105 +2110 +2128 +2103 +2084 +2099 +2096 +2250 +2119 +2099 +2107 +2109 +2096 +2121 +2108 +2091 +2097 +2122 +2043 +2095 +2102 +2119 +2112 +2097 +2108 +2103 +2105 +2105 +2192 +2084 +2116 +2098 +2110 +2081 +2096 +2125 +2146 +2227 +2099 +2114 +2112 +2131 +2087 +2112 +2207 +2112 +2096 +2084 +2096 +2112 +2108 +2097 +2137 +2113 +2145 +2123 +2112 +2133 +2097 +2102 +2231 +2098 +2098 +2118 +2119 +2106 +2111 +2103 +2097 +2128 +2155 +2112 +2140 +2109 +2111 +2099 +2116 +2096 +2103 +2113 +2107 +2111 +2110 +2002 +2105 +2115 +2159 +2109 +2102 +2112 +2110 +2125 +2131 +2117 +2116 +2110 +2110 +2131 +2021 +2112 +2122 +2097 +2130 +2116 +2112 +2109 +2043 +2113 +2113 +2128 +2096 +2119 +2114 +2093 +2109 +2122 +2096 +2099 +2118 +2115 +2112 +2112 +2071 +2127 +2139 +2128 +2137 +2094 +2108 +2117 +2115 +2096 +2116 +2094 +2127 +2113 +2231 +2111 +2112 +2105 +2087 +2112 +2128 +2045 +2110 +2095 +2114 +2115 +2127 +2150 +2111 +2099 +2119 +2119 +2112 +2124 +2244 +2119 +2127 +2067 +2112 +2007 +2107 +2046 +2024 +2125 +2064 +2114 +2109 +2114 +2118 +2117 +2112 +2210 +2251 +2125 +2125 +2115 +2123 +2031 +2110 +2111 +2114 +2117 +2103 +2112 +2112 +2121 +2098 +2112 +2108 +2112 +2096 +2121 +2103 +2112 +2111 +2064 +2113 +2107 +2096 +2106 +2237 +2110 +2101 +2091 +2104 +2115 +2117 +2128 +2114 +2121 +2114 +2102 +2064 +2068 +2131 +2096 +2144 +2091 +2118 +2167 +2095 +2123 +2093 +2119 +2115 +2146 +2112 +2115 +2139 +2102 +2126 +2093 +2130 +2016 +2103 +2015 +2119 +2125 +2119 +2112 +2117 +2118 +2124 +2044 +2117 +2111 +2119 +2113 +2126 +2113 +2115 +2110 +2103 +2118 +2114 +2106 +2121 +2102 +2092 +2116 +2176 +2216 +2127 +2112 +2146 +2128 +2094 +2115 +2112 +2126 +2128 +2110 +2111 +2143 +2130 +2125 +2117 +2127 +2124 +2128 +2117 +2064 +2109 +2107 +2148 +2117 +1929 +2096 +2133 +2121 +2112 +2128 +2114 +2128 +2129 +2116 +2112 +2126 +2114 +2130 +2111 +2042 +2122 +2119 +2127 +2123 +2166 +2198 +2118 +2130 +2105 +2174 +2062 +2125 +2155 +2116 +2137 +2119 +2104 +2125 +2119 +2127 +2113 +2119 +2102 +2131 +2119 +2113 +2127 +2112 +2111 +2117 +2128 +2126 +2114 +2125 +2129 +2122 +2255 +2114 +2139 +2119 +2126 +2126 +2123 +2091 +1969 +2115 +2111 +2118 +2109 +2089 +2144 +2148 +2127 +2069 +2116 +2118 +2084 +2091 +2123 +2112 +2114 +2126 +2117 +2128 +2130 +2087 +2111 +2125 +2163 +2126 +2127 +2128 +2125 +2122 +2128 +2221 +2096 +2118 +2119 +2107 +2128 +2125 +2123 +2131 +2122 +2128 +2122 +2175 +2128 +2162 +2142 +2102 +2121 +2127 +2113 +2123 +2118 +2128 +2116 +2128 +2119 +2126 +2138 +2129 +2128 +2158 +2153 +2141 +2121 +2120 +2125 +2114 +2092 +2128 +2151 +2128 +2128 +2128 +2121 +2122 +2137 +2118 +2098 +2127 +2125 +2129 +2123 +2124 +2095 +2119 +2107 +2107 +2126 +2129 +2125 +2084 +2103 +2124 +2118 +2169 +2112 +2128 +2118 +2123 +2125 +2128 +2119 +2138 +2144 +2067 +2127 +2107 +2115 +2113 +2139 +2139 +2126 +2129 +2101 +2081 +2128 +2147 +2128 +2141 +2129 +2128 +2112 +2158 +2131 +2123 +2102 +2176 +2130 +2121 +2101 +2131 +2133 +2122 +2095 +2114 +2202 +2128 +2125 +2101 +2128 +2096 +2131 +2128 +2128 +2137 +2131 +2121 +2128 +2137 +2102 +2115 +2129 +2127 +2131 +2153 +2127 +2128 +2133 +2109 +2129 +2127 +2013 +2137 +2109 +2134 +2148 +2105 +2125 +2151 +2128 +2117 +2124 +2113 +2101 +2128 +2131 +2144 +2126 +2025 +2125 +2119 +2130 +2130 +2138 +2125 +2126 +2118 +2131 +2124 +2117 +2136 +2125 +2097 +2126 +2133 +2111 +2121 +2118 +2126 +2131 +2131 +2144 +2131 +2129 +2132 +2128 +2155 +2127 +2145 +2171 +2128 +2135 +2145 +2151 +2149 +2140 +2138 +2167 +2128 +2137 +2105 +2150 +2127 +2134 +2137 +2128 +2133 +2073 +2154 +2114 +2136 +2142 +2135 +2146 +2150 +2182 +2122 +2118 +2147 +2128 +2107 +2125 +2129 +2119 +2123 +2118 +2128 +2138 +2134 +2125 +2149 +2135 +2129 +2138 +2111 +2138 +2134 +2142 +2146 +2094 +2069 +2141 +2128 +2174 +2128 +2127 +2128 +2136 +2075 +2115 +2135 +2148 +2143 +2064 +2128 +2133 +2134 +2129 +2140 +2133 +2100 +2030 +2150 +2043 +2129 +2135 +2146 +2142 +2116 +2132 +2146 +2138 +2138 +2177 +2089 +2145 +2146 +2138 +2256 +2157 +2131 +2189 +2134 +2151 +2144 +2141 +2139 +2148 +2148 +2145 +2134 +2033 +2157 +2145 +2064 +2132 +2132 +2181 +2137 +2144 +2135 +2125 +2141 +2118 +2165 +2143 +2157 +2150 +2133 +2131 +2150 +2138 +2146 +2129 +2240 +2145 +2133 +2129 +2099 +2115 +2160 +2143 +2160 +2128 +2160 +2069 +2142 +2133 +2149 +2134 +2125 +2147 +2142 +2139 +2151 +2066 +2135 +2143 +2133 +2128 +2128 +2140 +2140 +2147 +2122 +2149 +2147 +2156 +2144 +2150 +2071 +2141 +2063 +2144 +2141 +2141 +2151 +2145 +2141 +2143 +2151 +2142 +2147 +2147 +2139 +2081 +2155 +2147 +2091 +2154 +2147 +2149 +2142 +2128 +2130 +2159 +2154 +2149 +2146 +2120 +2111 +2134 +2133 +2144 +2133 +2147 +2156 +2162 +2145 +2139 +2149 +2133 +2141 +2150 +2107 +2166 +2142 +2174 +2148 +2155 +2129 +2128 +2151 +2136 +2149 +2153 +2054 +2129 +2149 +2174 +2191 +2155 +2146 +2167 +2158 +2036 +2142 +2130 +2149 +2141 +2130 +2145 +2139 +2138 +2151 +2142 +2150 +2145 +2161 +2145 +2145 +2145 +2145 +2180 +2127 +2143 +2143 +2155 +2107 +2145 +2148 +2143 +2143 +2149 +2131 +2147 +2128 +2226 +2145 +2146 +2193 +2071 +2158 +2155 +2142 +2160 +2290 +2137 +2146 +2141 +2143 +2144 +2081 +2160 +2145 +2150 +2137 +2143 +2128 +2160 +2135 +2160 +2150 +2127 +2174 +2161 +2131 +2140 +2166 +2157 +2128 +2141 +2145 +2194 +2128 +2160 +2160 +2141 +2221 +2150 +2157 +2148 +2148 +2128 +2136 +2148 +2182 +2146 +2153 +2155 +2094 +2208 +2143 +2158 +2158 +2137 +2172 +2155 +2265 +2139 +2154 +2151 +2149 +2139 +2136 +2148 +2146 +2137 +2167 +2155 +2143 +2160 +2159 +2174 +2157 +2154 +2151 +2162 +2032 +2159 +2202 +2128 +2148 +2176 +2160 +2153 +2196 +2143 +2157 +2158 +2142 +2149 +2155 +2128 +2164 +2156 +2157 +2162 +2144 +2158 +2160 +2156 +2191 +2144 +2151 +2133 +2243 +2173 +2143 +2146 +2183 +2154 +2151 +2167 +2158 +2088 +2150 +2129 +2175 +2227 +2147 +2155 +2151 +2155 +2149 +2192 +2159 +2152 +2156 +2150 +2160 +2111 +2160 +2160 +2156 +2140 +2158 +2162 +2148 +2159 +2118 +2139 +2117 +2128 +2163 +2148 +2156 +2171 +2147 +2138 +2160 +2149 +2251 +2151 +2147 +2155 +2153 +2159 +2155 +2160 +2149 +2155 +2114 +2154 +2085 +2212 +2160 +2160 +2137 +2165 +2155 +2160 +2179 +2027 +2143 +2167 +2156 +2164 +2072 +2158 +2160 +2167 +2165 +2161 +2159 +2157 +2161 +2173 +2178 +2158 +2179 +2141 +2165 +2171 +2169 +2133 +2161 +2160 +2160 +2198 +2160 +2154 +2160 +2171 +2160 +2160 +2160 +2170 +2159 +2135 +2157 +2104 +2147 +2111 +2141 +2256 +2147 +2147 +2169 +2148 +2157 +2170 +2174 +2160 +2149 +2135 +2159 +2143 +2162 +2214 +2189 +2160 +2160 +2165 +2130 +2169 +2154 +2186 +2158 +2186 +2160 +2144 +2160 +2170 +2169 +2171 +2161 +2143 +2157 +2160 +2160 +2176 +2173 +2155 +2178 +2160 +2158 +2143 +2154 +2143 +2129 +2160 +2157 +2163 +2195 +2161 +2167 +2155 +2170 +2173 +2171 +2160 +2039 +2089 +2161 +2201 +2175 +2163 +2285 +2173 +2155 +2158 +2157 +2102 +2169 +2122 +2160 +2160 +2174 +2167 +2163 +2170 +2176 +2133 +2160 +2166 +2117 +2164 +2163 +2161 +2151 +2172 +2139 +2165 +2185 +2173 +2120 +2177 +2164 +2156 +2176 +2163 +2160 +2160 +2161 +2164 +2177 +2160 +2185 +2160 +2168 +2143 +2173 +2157 +2195 +2161 +2163 +2163 +2162 +2142 +2131 +2175 +2174 +2166 +2160 +2154 +2147 +2171 +2164 +1974 +2160 +2039 +2160 +2160 +2176 +2175 +2163 +2157 +2157 +2187 +2182 +2161 +2171 +2166 +2152 +2165 +2164 +2179 +2162 +2138 +2171 +2176 +2162 +2170 +2160 +2162 +2162 +2180 +2160 +2155 +2166 +2165 +2174 +2173 +2160 +2153 +2138 +2165 +2185 +2167 +2153 +2174 +2175 +2131 +2165 +2174 +2167 +2289 +2180 +2170 +2171 +2301 +2187 +2176 +2123 +2170 +2175 +2175 +2154 +2178 +2158 +2174 +2107 +2185 +2112 +2127 +2159 +2171 +2170 +2171 +2268 +2176 +2190 +2169 +2189 +2161 +2161 +2168 +2170 +2170 +2176 +2170 +2179 +2167 +2158 +2160 +2154 +2098 +2160 +2167 +2077 +2192 +2160 +2176 +2160 +2150 +2135 +2157 +2158 +2166 +2148 +2169 +2167 +2187 +2198 +2176 +2173 +2170 +2160 +2206 +2160 +2175 +2160 +2177 +2187 +2174 +2175 +2164 +2185 +2161 +2175 +2173 +2171 +2182 +2177 +2175 +2165 +2178 +2176 +2175 +2178 +2165 +2170 +2178 +2173 +2155 +2161 +2171 +2189 +2175 +2173 +2162 +2191 +2169 +2162 +2186 +2137 +2162 +2180 +2175 +2209 +2173 +2176 +2165 +2171 +2037 +2178 +2175 +2166 +2174 +2167 +2174 +2171 +2187 +2085 +2186 +2165 +2163 +2175 +2182 +2171 +2148 +2160 +2167 +2181 +2214 +2160 +2176 +2179 +2160 +2179 +2166 +2168 +2178 +2187 +2176 +2118 +2171 +2162 +2161 +2183 +2191 +2187 +2160 +2170 +2181 +2098 +2191 +2176 +2144 +2160 +2178 +2190 +2182 +2170 +2179 +2181 +2177 +2190 +2176 +2224 +2192 +2169 +2192 +2190 +2126 +2193 +2164 +2170 +2177 +2139 +2181 +2176 +2182 +2183 +2180 +2185 +2201 +2195 +2161 +2191 +2181 +2176 +2173 +2170 +2186 +2256 +2178 +2275 +2174 +2177 +2182 +2166 +2172 +2173 +2131 +2166 +2183 +2169 +2183 +2160 +2179 +2179 +2171 +2187 +2189 +2183 +2174 +2121 +2166 +2173 +2096 +2160 +2176 +2163 +2117 +2160 +2178 +2179 +2189 +2190 +2178 +2171 +2221 +2174 +2179 +2176 +2170 +2192 +2188 +2261 +2196 +2175 +2190 +2201 +2194 +2185 +2186 +2127 +2171 +2288 +2188 +2192 +2192 +2174 +2102 +2149 +2186 +2187 +2187 +2192 +2173 +2177 +2231 +2169 +2183 +2178 +2011 +2189 +2225 +2182 +2147 +2137 +2221 +2103 +2182 +2083 +2183 +2196 +2190 +2192 +2187 +2186 +2199 +2181 +2187 +2185 +2180 +2193 +2192 +2192 +2179 +2192 +2199 +2176 +2202 +2188 +2186 +2195 +2190 +2176 +2163 +2183 +2176 +2192 +2195 +2190 +2174 +2192 +2185 +2311 +2218 +2169 +2194 +2186 +2197 +2155 +2259 +2192 +2190 +2209 +2191 +2177 +2196 +2181 +2200 +2196 +2181 +2240 +2192 +2282 +2259 +2189 +2195 +2204 +2200 +2176 +2161 +2191 +2237 +2186 +2182 +2076 +2197 +2198 +2187 +2207 +2190 +2213 +2177 +2178 +2173 +2142 +2192 +2185 +2186 +2187 +2192 +2174 +2182 +2194 +2215 +2170 +2191 +2194 +2192 +2176 +2188 +2210 +2173 +2192 +2164 +2145 +2191 +2182 +2182 +2194 +2227 +2082 +2206 +2191 +2173 +2174 +2206 +2192 +2183 +2187 +2192 +2160 +2239 +2208 +2194 +2151 +2192 +2196 +2190 +2187 +2185 +2192 +2190 +2201 +2187 +2223 +2193 +2191 +2182 +2185 +2195 +2192 +2135 +2160 +2286 +2176 +2192 +2191 +2192 +2234 +2195 +2226 +2223 +2020 +2198 +2203 +2199 +2202 +2182 +2199 +2185 +2193 +2237 +2197 +2192 +2192 +2188 +2192 +2176 +2197 +2203 +2156 +2204 +2174 +2192 +2197 +2194 +2181 +2192 +2180 +2192 +2245 +2196 +2188 +2195 +2198 +2242 +2166 +2192 +2099 +2192 +2196 +2191 +2203 +2176 +2196 +2180 +2194 +2205 +2192 +2192 +2192 +2197 +2192 +2219 +2192 +2166 +2215 +2194 +2203 +2214 +2200 +2196 +2241 +2197 +2240 +2223 +2205 +2139 +2187 +2192 +2171 +2201 +2185 +2198 +2187 +2213 +2192 +2194 +2193 +2208 +2202 +2131 +2203 +2197 +2194 +2180 +2198 +2194 +2182 +2204 +2172 +2158 +2192 +2203 +2197 +2198 +2204 +2181 +2240 +2265 +2208 +2202 +2214 +2187 +2176 +2241 +2099 +2163 +2209 +2196 +2205 +2190 +2238 +2215 +2205 +2205 +2197 +2199 +2218 +2224 +2212 +2197 +2207 +2294 +2199 +2288 +2309 +2192 +2209 +2135 +2203 +2192 +2203 +2198 +2147 +2170 +2203 +2206 +2197 +2162 +2193 +2205 +2199 +2206 +2332 +2199 +2207 +2194 +2191 +2151 +2288 +2206 +2206 +2192 +2219 +2198 +2187 +2224 +2201 +2211 +2210 +2195 +2192 +2201 +2202 +2211 +2199 +2201 +2174 +2198 +2206 +2176 +2222 +2205 +2209 +2192 +2205 +2192 +2205 +2192 +2188 +2209 +2213 +2210 +2192 +2206 +2212 +2205 +2203 +2208 +2228 +2208 +2224 +2209 +2204 +2212 +2205 +2278 +2210 +2202 +2200 +2193 +2203 +2224 +2254 +2197 +2212 +2210 +2222 +2224 +2207 +2227 +2204 +2203 +2213 +2204 +2192 +2208 +2176 +2192 +2199 +2203 +2219 +2203 +2192 +2195 +2206 +2207 +2215 +2224 +2224 +2197 +2203 +2200 +2181 +2194 +2188 +2204 +2207 +2131 +2192 +2206 +2198 +2203 +2204 +2221 +2213 +2224 +2207 +2203 +2182 +2199 +2166 +2191 +2195 +2215 +2203 +2208 +2252 +2186 +2207 +2224 +2195 +2224 +2247 +2315 +2181 +2369 +2192 +2203 +2117 +2206 +2226 +2229 +2214 +2218 +2224 +2199 +2214 +2193 +2209 +2206 +2208 +2217 +2240 +2211 +2202 +2208 +2211 +2217 +2208 +2229 +2240 +2215 +2222 +2192 +2213 +2199 +2198 +2192 +2207 +2206 +2215 +2224 +2267 +2208 +2340 +2213 +2218 +2211 +2173 +2214 +2241 +2220 +2224 +2208 +2213 +2198 +2209 +2224 +2213 +2223 +2240 +2213 +2219 +2215 +2219 +2201 +2213 +2202 +2215 +2208 +2208 +2213 +2163 +2185 +2230 +2217 +2215 +2224 +2181 +2224 +2225 +2205 +2236 +2253 +2225 +2215 +2192 +2225 +2209 +2203 +2207 +2210 +2222 +2207 +2222 +2222 +2199 +2237 +2223 +2224 +2224 +2204 +2209 +2224 +2231 +2231 +2210 +2224 +2217 +2219 +2219 +2224 +2256 +2218 +2215 +2209 +2198 +2224 +2231 +2222 +2221 +2236 +2274 +2187 +2149 +2254 +2223 +2210 +2240 +2187 +2201 +2220 +2207 +2224 +2213 +2150 +2199 +2192 +2224 +2235 +2213 +2215 +2222 +2224 +2237 +2224 +2240 +2316 +2223 +2303 +2241 +2171 +2191 +2221 +2211 +2190 +2192 +2187 +2217 +2220 +2221 +2225 +2215 +2215 +2222 +2219 +2224 +2255 +2223 +2209 +2205 +2218 +2285 +2219 +2195 +2198 +2145 +2211 +2224 +2224 +2223 +2215 +2202 +2224 +2224 +2240 +2223 +2206 +2219 +2224 +2202 +2192 +2256 +2223 +2222 +2227 +2224 +2142 +2218 +2320 +2209 +2215 +2162 +2223 +2227 +2214 +2226 +2221 +2159 +2255 +2224 +2227 +2224 +2218 +2226 +2240 +2228 +2229 +2230 +2277 +2206 +2255 +2231 +2254 +2212 +2223 +2275 +2237 +2224 +2207 +2203 +2225 +2225 +2222 +2257 +2230 +2154 +2229 +2222 +2220 +2218 +2227 +2227 +2224 +2209 +2209 +2192 +2219 +2239 +2255 +2206 +2218 +2224 +2213 +2192 +2230 +2219 +2229 +2246 +2223 +2224 +2239 +2141 +2232 +2226 +2207 +2223 +2202 +2336 +2224 +2146 +2223 +2216 +2217 +2235 +2222 +2272 +2242 +2228 +2227 +2240 +2229 +2256 +2223 +2225 +2161 +2245 +2251 +2198 +2234 +2160 +2224 +2226 +2240 +2229 +2215 +2243 +2243 +2138 +2224 +2226 +2229 +2228 +2217 +2234 +2222 +2233 +2229 +2224 +2240 +2194 +2223 +2231 +2230 +2167 +2236 +2226 +2231 +2225 +2235 +2307 +2240 +2235 +2234 +2256 +2234 +2217 +2227 +2224 +2239 +2230 +2254 +2228 +2254 +2231 +2224 +2192 +2224 +2229 +2226 +2303 +2229 +2224 +2259 +2227 +2225 +2240 +2321 +2224 +2225 +2223 +2231 +2224 +2230 +2231 +2227 +2235 +2251 +2224 +2224 +2223 +2269 +2232 +2229 +2231 +2199 +2235 +2240 +2193 +2206 +2274 +2244 +2282 +2236 +2241 +2256 +2240 +2240 +2235 +2234 +2234 +2219 +2253 +2227 +2238 +2256 +2182 +2229 +2184 +2244 +2207 +2241 +2246 +2238 +2274 +2233 +2224 +2230 +2240 +2256 +2235 +2354 +2240 +2235 +2239 +2254 +2256 +2240 +2288 +2238 +2237 +2238 +2241 +2240 +2238 +2246 +2240 +2242 +2250 +2243 +2230 +2253 +2224 +2277 +2238 +2234 +2228 +2241 +2256 +2256 +2230 +2223 +2233 +2239 +2207 +2240 +2233 +2162 +2097 +2240 +2237 +2190 +2185 +2231 +2230 +2359 +2241 +2215 +2241 +2224 +2226 +2235 +2239 +2245 +2240 +2246 +2256 +2266 +2244 +2271 +2275 +2252 +2240 +2242 +2245 +2236 +2264 +2253 +2245 +2380 +2193 +2246 +2261 +2237 +2253 +2221 +2251 +2243 +2246 +2246 +2249 +2249 +2254 +2246 +2256 +2254 +2246 +2240 +2253 +2244 +2238 +2162 +2135 +2256 +2308 +2256 +2247 +2240 +2220 +2241 +2250 +2246 +2225 +2243 +2242 +2224 +2255 +2262 +2267 +2239 +2239 +2229 +2240 +2318 +2240 +2245 +2203 +2237 +2205 +2190 +2239 +2266 +2293 +2349 +2247 +2195 +2253 +2222 +2244 +2250 +2256 +2222 +2245 +2231 +2243 +2227 +2256 +2290 +2222 +2227 +2247 +2245 +2347 +2241 +2249 +2224 +2250 +2245 +2245 +2271 +2239 +2256 +2238 +2255 +2268 +2255 +2235 +2247 +2250 +2245 +2236 +2240 +2253 +2255 +2259 +2245 +2259 +2265 +2253 +2251 +2257 +2241 +2256 +2256 +2253 +2246 +2261 +2239 +2275 +2241 +2256 +2243 +2216 +2222 +2246 +2253 +2246 +2246 +2275 +2269 +2250 +2286 +2240 +2253 +2265 +2254 +2261 +2256 +2285 +2249 +2250 +2256 +2238 +2253 +2253 +2256 +2256 +2272 +2259 +2254 +2367 +2262 +2246 +2263 +2358 +2306 +2267 +2263 +2202 +2257 +2256 +2256 +2212 +2262 +2271 +2257 +2259 +2261 +2257 +2240 +2251 +2236 +2152 +2258 +2259 +2240 +2229 +2257 +2257 +2259 +2254 +2345 +2240 +2256 +2256 +2255 +2256 +2254 +2252 +2242 +2256 +2246 +2217 +2256 +2256 +2235 +2267 +2271 +2254 +2245 +2249 +2247 +2254 +2257 +2271 +2220 +2256 +2255 +2247 +2250 +2262 +2257 +2219 +2259 +2257 +2258 +2288 +2256 +2253 +2256 +2262 +2247 +2272 +2262 +2269 +2259 +2166 +2263 +2287 +2247 +2256 +2255 +2259 +2229 +2247 +2244 +2263 +2233 +2272 +2236 +2256 +2256 +2256 +2261 +2240 +2253 +2250 +2234 +2251 +2255 +2263 +2258 +2294 +2256 +2256 +2256 +2165 +2243 +2264 +2256 +2261 +2257 +2228 +2253 +2250 +2283 +2242 +2259 +2268 +2273 +2353 +2163 +2258 +2250 +2271 +2267 +2270 +2385 +2243 +2261 +2263 +2273 +2305 +2273 +2247 +2315 +2256 +2231 +2301 +2262 +2256 +2256 +2295 +2293 +2316 +2256 +2241 +2265 +2257 +2262 +2257 +2247 +2251 +2256 +2271 +2274 +2260 +2394 +2209 +2260 +2269 +2261 +2247 +2260 +2257 +2263 +2260 +2273 +2253 +2256 +2253 +2272 +2235 +2265 +2263 +2309 +2269 +2262 +2277 +2279 +2267 +2254 +2310 +2279 +2218 +2263 +2307 +2260 +2276 +2267 +2267 +2286 +2273 +2270 +2243 +2380 +2274 +2271 +2267 +2261 +2194 +2283 +2291 +2273 +2270 +2268 +2285 +2289 +2261 +2231 +2271 +2270 +2279 +2273 +2243 +2260 +2267 +2320 +2278 +2263 +2253 +2265 +2336 +2281 +2253 +2271 +2267 +2273 +2256 +2256 +2265 +2261 +2195 +2259 +2271 +2311 +2263 +2160 +2347 +2278 +2185 +2302 +2259 +2265 +2273 +2208 +2302 +2259 +2256 +2267 +2269 +2246 +2254 +2267 +2271 +2193 +2265 +2272 +2236 +2266 +2260 +2265 +2339 +2263 +2346 +2261 +2273 +2278 +2256 +2281 +2272 +2305 +2257 +2274 +2279 +2278 +2258 +2242 +2270 +2256 +2271 +2256 +2274 +2273 +2272 +2255 +2283 +2275 +2256 +2281 +2303 +2213 +2283 +2261 +2268 +2267 +2279 +2244 +2267 +2265 +2279 +2389 +2340 +2281 +2276 +2275 +2256 +2290 +2278 +2268 +2278 +2305 +2320 +2271 +2348 +2298 +2295 +2283 +2282 +2256 +2290 +2277 +2263 +2251 +2277 +2279 +2225 +2288 +2282 +2289 +2227 +2282 +2224 +2286 +2291 +2288 +2276 +2284 +2254 +2271 +2267 +2270 +2286 +2276 +2277 +2287 +2254 +2285 +2277 +2271 +2265 +2269 +2288 +2355 +2267 +2285 +2307 +2365 +2286 +2277 +2311 +2269 +2283 +2273 +2289 +2285 +2287 +2275 +2286 +2288 +2272 +2278 +2239 +2293 +2283 +2286 +2288 +2272 +2227 +2271 +2295 +2289 +2285 +2287 +2253 +2292 +2282 +2285 +2284 +2281 +2288 +2285 +2277 +2267 +2405 +2327 +2267 +2305 +2320 +2361 +2275 +2288 +2281 +2288 +2289 +2275 +2283 +2267 +2312 +2288 +2292 +2283 +2274 +2285 +2277 +2295 +2279 +2321 +2282 +2283 +2274 +2291 +2274 +2287 +2277 +2289 +2268 +2288 +2277 +2282 +2284 +2283 +2420 +2257 +2283 +2282 +2278 +2352 +2272 +2288 +2294 +2285 +2269 +2290 +2290 +2306 +2293 +2241 +2284 +2267 +2298 +2266 +2272 +2261 +2287 +2303 +2284 +2314 +2273 +2283 +2287 +2311 +2278 +2284 +2284 +2280 +2259 +2285 +2297 +2151 +2246 +2285 +2288 +2279 +2294 +2288 +2286 +2341 +2299 +2297 +2294 +2399 +2287 +2289 +2285 +2335 +2274 +2291 +2337 +2288 +2285 +2295 +2334 +2302 +2277 +2290 +2275 +2288 +2288 +2289 +2283 +2217 +2275 +2290 +2306 +2300 +2348 +2288 +2293 +2288 +2298 +2295 +2303 +2297 +2289 +2299 +2292 +2286 +2280 +2295 +2288 +2288 +2303 +2288 +2281 +2290 +2291 +2295 +2285 +2281 +2233 +2282 +2301 +2268 +2338 +2289 +2290 +2281 +2284 +2291 +2291 +2286 +2280 +2296 +2301 +2310 +2305 +2330 +2292 +2271 +2398 +2299 +2195 +2187 +2349 +2304 +2287 +2273 +2291 +2289 +2296 +2289 +2305 +2299 +2290 +2304 +2250 +2272 +2311 +2311 +2295 +2295 +2240 +2299 +2299 +2293 +2301 +2369 +2298 +2300 +2406 +2295 +2245 +2337 +2301 +2383 +2302 +2307 +2311 +2299 +2331 +2306 +2290 +2287 +2303 +2297 +2295 +2283 +2294 +2302 +2292 +2330 +2288 +2315 +2298 +2339 +2317 +2289 +2314 +2293 +2289 +2301 +2303 +2290 +2299 +2292 +2292 +2317 +2290 +2316 +2320 +2298 +2256 +2289 +2321 +2323 +2320 +2309 +2311 +2298 +2304 +2427 +2314 +2305 +2415 +2319 +2305 +2331 +2295 +2303 +2304 +2303 +2290 +2314 +2293 +2318 +2286 +2320 +2304 +2288 +2313 +2304 +2307 +2321 +2341 +2300 +2310 +2357 +2299 +2420 +2309 +2320 +2256 +2299 +2349 +2307 +2304 +2244 +2293 +2304 +2299 +2227 +2291 +2307 +2311 +2293 +2304 +2303 +2306 +2306 +2319 +2335 +2305 +2307 +2309 +2306 +2301 +2311 +2412 +2311 +2295 +2256 +2306 +2323 +2310 +2320 +2301 +2301 +2285 +2313 +2293 +2306 +2304 +2304 +2320 +2304 +2306 +2283 +2331 +2327 +2321 +2298 +2313 +2316 +2322 +2297 +2465 +2338 +2306 +2305 +2331 +2346 +2303 +2311 +2316 +2317 +2317 +2305 +2304 +2313 +2311 +2346 +2295 +2311 +2319 +2320 +2270 +2310 +2308 +2245 +2322 +2284 +2299 +2307 +2290 +2302 +2327 +2298 +2306 +2318 +2287 +2320 +2313 +2309 +2310 +2283 +2303 +2317 +2304 +2215 +2307 +2327 +2315 +2341 +2308 +2319 +2304 +2309 +2334 +2320 +2309 +2319 +2310 +2426 +2304 +2295 +2316 +2298 +2287 +2318 +2314 +2311 +2322 +2307 +2274 +2319 +2295 +2311 +2330 +2318 +2320 +2311 +2319 +2320 +2319 +2311 +2306 +2320 +2314 +2398 +2308 +2315 +2323 +2301 +2320 +2309 +2428 +2320 +2320 +2315 +2366 +2321 +2334 +2317 +2321 +2309 +2317 +2304 +2320 +2245 +2319 +2320 +2318 +2321 +2321 +2329 +2351 +2319 +2315 +2320 +2325 +2331 +2320 +2312 +2352 +2306 +2307 +2315 +2320 +2288 +2320 +2286 +2320 +2327 +2325 +2313 +2314 +2320 +2289 +2354 +2320 +2317 +2323 +2417 +2325 +2298 +2331 +2317 +2323 +2330 +2331 +2317 +2327 +2319 +2301 +2317 +2320 +2291 +2323 +2317 +2325 +2311 +2316 +2309 +2325 +2336 +2315 +2305 +2321 +2311 +2320 +2290 +2331 +2335 +2205 +2346 +2319 +2320 +2314 +2236 +2320 +2323 +2311 +2334 +2320 +2350 +2326 +2322 +2321 +2317 +2363 +2323 +2314 +2318 +2335 +2316 +2325 +2343 +2336 +2328 +2327 +2333 +2335 +2330 +2287 +2323 +2325 +2325 +2333 +2330 +2333 +2323 +2325 +2297 +2325 +2325 +2238 +2289 +2335 +2318 +2326 +2305 +2310 +2455 +2317 +2337 +2329 +2320 +2322 +2275 +2335 +2333 +2322 +2334 +2358 +2335 +2400 +2320 +2322 +2225 +2326 +2325 +2321 +2347 +2323 +2323 +2339 +2350 +2327 +2336 +2352 +2323 +2331 +2350 +2335 +2337 +2333 +2322 +2461 +2303 +2343 +2329 +2347 +2233 +2341 +2241 +2351 +2334 +2333 +2329 +2342 +2326 +2319 +2330 +2350 +2322 +2337 +2331 +2325 +2333 +2320 +2321 +2325 +2325 +2326 +2336 +2333 +2419 +2349 +2446 +2302 +2331 +2335 +2339 +2328 +2335 +2321 +2288 +2333 +2320 +2373 +2334 +2329 +2325 +2353 +2330 +2367 +2270 +2329 +2331 +2329 +2329 +2347 +2327 +2334 +2331 +2281 +2322 +2337 +2335 +2331 +2341 +2334 +2343 +2333 +2341 +2330 +2338 +2339 +2330 +2346 +2331 +2337 +2329 +2323 +2356 +2315 +2329 +2310 +2333 +2336 +2352 +2350 +2327 +2320 +2338 +2428 +2332 +2325 +2335 +2332 +2331 +2325 +2327 +2323 +2351 +2320 +2333 +2345 +2332 +2263 +2341 +2331 +2323 +2334 +2316 +2309 +2337 +2363 +2366 +2285 +2346 +2311 +2339 +2323 +2225 +2335 +2330 +2346 +2337 +2357 +2352 +2343 +2334 +2332 +2331 +2350 +2349 +2320 +2340 +2321 +2321 +2305 +2339 +2343 +2353 +2279 +2331 +2345 +2352 +2341 +2336 +2339 +2352 +2361 +2338 +2346 +2361 +2355 +2389 +2334 +2342 +2333 +2342 +2341 +2352 +2333 +2357 +2355 +2300 +2343 +2338 +2337 +2341 +2331 +2352 +2322 +2477 +2346 +2339 +2329 +2311 +2347 +2345 +2345 +2287 +2338 +2352 +2354 +2342 +2346 +2346 +2407 +2339 +2343 +2342 +2352 +2307 +2342 +2347 +2333 +2485 +2350 +2352 +2336 +2334 +2336 +2477 +2255 +2333 +2347 +2338 +2336 +2338 +2337 +2363 +2346 +2354 +2362 +2286 +2330 +2340 +2345 +2331 +2343 +2406 +2345 +2363 +2446 +2346 +2342 +2337 +2296 +2320 +2347 +2363 +2349 +2356 +2349 +2352 +2343 +2342 +2433 +2352 +2348 +2343 +2350 +2343 +2302 +2352 +2382 +2352 +2334 +2383 +2349 +2362 +2366 +2347 +2351 +2352 +2359 +2337 +2342 +2352 +2352 +2341 +2357 +2347 +2355 +2347 +2315 +2348 +2353 +2379 +2257 +2366 +2338 +2291 +2478 +2293 +2371 +2353 +2353 +2374 +2352 +2340 +2295 +2347 +2417 +2336 +2365 +2339 +2356 +2363 +2352 +2364 +2349 +2356 +2519 +2333 +2355 +2357 +2359 +2305 +2351 +2359 +2353 +2368 +2353 +2371 +2354 +2341 +2352 +2352 +2356 +2351 +2363 +2359 +2358 +2299 +2378 +2326 +2377 +2351 +2357 +2365 +2390 +2352 +2382 +2351 +2331 +2301 +2339 +2353 +2350 +2357 +2353 +2352 +2332 +2357 +2338 +2352 +2334 +2350 +2354 +2352 +2299 +2314 +2347 +2342 +2371 +2333 +2352 +2350 +2379 +2359 +2390 +2352 +2299 +2353 +2343 +2353 +2358 +2363 +2352 +2363 +2353 +2331 +2373 +2357 +2343 +2353 +2367 +2363 +2368 +2352 +2341 +2411 +2353 +2361 +2364 +2354 +2514 +2353 +2352 +2353 +2355 +2350 +2356 +2351 +2355 +2356 +2358 +2350 +2288 +2355 +2358 +2349 +2364 +2370 +2366 +2346 +2353 +2374 +2435 +2410 +2351 +2357 +2361 +2354 +2371 +2369 +2361 +2367 +2358 +2364 +2341 +2367 +2352 +2326 +2378 +2370 +2346 +2352 +2353 +2352 +2361 +2350 +2394 +2368 +2354 +2369 +2357 +2286 +2359 +2361 +2380 +2363 +2368 +2352 +2349 +2368 +2367 +2377 +2358 +2311 +2341 +2362 +2365 +2361 +2367 +2355 +2352 +2372 +2589 +2368 +2352 +2350 +2352 +2359 +2383 +2370 +2363 +2384 +2363 +2364 +2345 +2368 +2372 +2353 +2358 +2341 +2277 +2379 +2373 +2368 +2377 +2378 +2371 +2384 +2368 +2367 +2375 +2369 +2335 +2389 +2375 +2371 +2377 +2417 +2378 +2370 +2384 +2332 +2195 +2388 +2369 +2409 +2377 +2355 +2289 +2365 +2369 +2372 +2397 +2503 +2366 +2339 +2365 +2366 +2368 +2384 +2366 +2369 +2450 +2367 +2367 +2371 +2342 +2366 +2377 +2368 +2354 +2367 +2371 +2366 +2219 +2381 +2352 +2368 +2352 +2379 +2368 +2271 +2487 +2369 +2295 +2356 +2349 +2342 +2384 +2369 +2368 +2415 +2320 +2362 +2287 +2451 +2368 +2368 +2365 +2320 +2384 +2356 +2357 +2365 +2376 +2345 +2346 +2351 +2369 +2352 +2365 +2352 +2365 +2364 +2353 +2368 +2366 +2371 +2378 +2374 +2377 +2372 +2320 +2370 +2368 +2400 +2364 +2369 +2543 +2358 +2304 +2368 +2395 +2321 +2368 +2383 +2372 +2371 +2375 +2321 +2382 +2386 +2382 +2307 +2366 +2379 +2372 +2368 +2382 +2365 +2374 +2374 +2379 +2321 +2294 +2371 +2372 +2365 +2304 +2371 +2386 +2369 +2367 +2375 +2386 +2374 +2372 +2375 +2386 +2361 +2378 +2368 +2375 +2378 +2363 +2381 +2384 +2385 +2383 +2390 +2384 +2387 +2386 +2348 +2375 +2422 +2373 +2386 +2358 +2327 +2362 +2384 +2384 +2402 +2389 +2378 +2370 +2379 +2368 +2386 +2382 +2393 +2423 +2381 +2401 +2378 +2359 +2359 +2379 +2395 +2359 +2382 +2384 +2365 +2363 +2384 +2395 +2381 +2371 +2480 +2420 +2379 +2342 +2383 +2357 +2379 +2382 +2340 +2372 +2391 +2351 +2386 +2430 +2354 +2375 +2383 +2368 +2389 +2361 +2380 +2374 +2398 +2373 +2386 +2375 +2363 +2395 +2385 +2459 +2373 +2384 +2377 +2384 +2373 +2379 +2372 +2381 +2389 +2378 +2380 +2384 +2387 +2376 +2403 +2379 +2371 +2395 +2378 +2384 +2381 +2378 +2291 +2387 +2378 +2359 +2386 +2398 +2379 +2372 +2290 +2382 +2389 +2391 +2385 +2368 +2381 +2373 +2404 +2385 +2382 +2386 +2375 +2493 +2336 +2397 +2387 +2428 +2391 +2413 +2403 +2391 +2430 +2401 +2398 +2384 +2384 +2367 +2389 +2416 +2377 +2387 +2377 +2385 +2363 +2386 +2391 +2385 +2391 +2396 +2398 +2391 +2386 +2378 +2384 +2384 +2382 +2386 +2387 +2383 +2382 +2373 +2411 +2420 +2385 +2383 +2384 +2384 +2389 +2366 +2384 +2386 +2401 +2350 +2386 +2397 +2400 +2384 +2391 +2389 +2382 +2386 +2377 +2383 +2414 +2390 +2366 +2390 +2391 +2383 +2389 +2402 +2388 +2395 +2401 +2326 +2394 +2390 +2387 +2415 +2382 +2384 +2384 +2382 +2375 +2386 +2387 +2368 +2384 +2368 +2386 +2383 +2452 +2379 +2416 +2379 +2384 +2385 +2384 +2478 +2408 +2390 +2402 +2388 +2398 +2444 +2365 +2384 +2387 +2369 +2399 +2393 +2419 +2393 +2385 +2378 +2374 +2398 +2399 +2389 +2398 +2374 +2389 +2394 +2526 +2391 +2391 +2407 +2401 +2388 +2397 +2387 +2394 +2393 +2386 +2394 +2339 +2398 +2384 +2397 +2400 +2387 +2384 +2399 +2394 +2394 +2385 +2394 +2425 +2421 +2405 +2402 +2397 +2395 +2379 +2397 +2419 +2409 +2387 +2405 +2384 +2390 +2384 +2372 +2395 +2348 +2385 +2415 +2403 +2401 +2385 +2395 +2399 +2384 +2400 +2396 +2405 +2384 +2386 +2355 +2384 +2421 +2395 +2401 +2397 +2398 +2416 +2313 +2448 +2413 +2413 +2403 +2416 +2320 +2406 +2385 +2417 +2433 +2403 +2405 +2406 +2399 +2419 +2402 +2389 +2222 +2403 +2405 +2403 +2398 +2400 +2416 +2416 +2384 +2398 +2415 +2389 +2438 +2411 +2411 +2409 +2372 +2415 +2373 +2421 +2387 +2401 +2395 +2395 +2418 +2410 +2416 +2352 +2409 +2432 +2397 +2413 +2404 +2395 +2393 +2355 +2400 +2403 +2393 +2402 +2542 +2416 +2402 +2398 +2433 +2326 +2395 +2416 +2391 +2375 +2454 +2410 +2384 +2415 +2395 +2397 +2395 +2412 +2378 +2403 +2397 +2389 +2416 +2393 +2352 +2378 +2394 +2399 +2395 +2374 +2418 +2382 +2406 +2395 +2401 +2416 +2407 +2434 +2352 +2419 +2397 +2403 +2449 +2404 +2352 +2409 +2411 +2403 +2382 +2311 +2314 +2365 +2400 +2404 +2417 +2422 +2416 +2405 +2416 +2411 +2402 +2429 +2406 +2416 +2416 +2490 +2462 +2416 +2405 +2416 +2355 +2450 +2420 +2414 +2342 +2402 +2337 +2538 +2386 +2519 +2416 +2419 +2417 +2416 +2416 +2395 +2329 +2411 +2416 +2390 +2399 +2427 +2418 +2406 +2421 +2417 +2407 +2396 +2417 +2401 +2411 +2406 +2354 +2397 +2412 +2415 +2419 +2416 +2350 +2409 +2417 +2400 +2405 +2402 +2410 +2389 +2415 +2406 +2416 +2388 +2406 +2419 +2450 +2432 +2416 +2427 +2413 +2418 +2413 +2324 +2341 +2390 +2494 +2427 +2420 +2414 +2422 +2417 +2421 +2397 +2399 +2427 +2373 +2416 +2419 +2422 +2419 +2416 +2415 +2428 +2420 +2434 +2368 +2447 +2430 +2388 +2403 +2413 +2433 +2423 +2416 +2422 +2416 +2415 +2431 +2434 +2415 +2402 +2421 +2431 +2409 +2420 +2416 +2423 +2435 +2418 +2412 +2419 +2412 +2395 +2411 +2437 +2410 +2415 +2432 +2417 +2399 +2417 +2416 +2420 +2427 +2489 +2416 +2482 +2422 +2414 +2415 +2416 +2432 +2514 +2411 +2380 +2418 +2399 +2411 +2423 +2415 +2414 +2411 +2421 +2439 +2432 +2465 +2430 +2483 +2416 +2410 +2416 +2416 +2437 +2415 +2416 +2449 +2417 +2425 +2417 +2458 +2351 +2422 +2431 +2400 +2419 +2426 +2423 +2421 +2431 +2416 +2442 +2425 +2403 +2421 +2419 +2462 +2430 +2423 +2416 +2431 +2441 +2439 +2432 +2437 +2421 +2510 +2426 +2421 +2432 +2406 +2427 +2414 +2396 +2480 +2461 +2427 +2352 +2418 +2421 +2445 +2423 +2441 +2437 +2416 +2419 +2425 +2427 +2433 +2425 +2435 +2431 +2414 +2424 +2432 +2433 +2421 +2425 +2430 +2425 +2374 +2385 +2434 +2418 +2401 +2423 +2416 +2607 +2439 +2427 +2479 +2416 +2448 +2359 +2429 +2405 +2429 +2430 +2435 +2460 +2460 +2430 +2423 +2433 +2416 +2416 +2421 +2448 +2429 +2448 +2512 +2431 +2420 +2402 +2429 +2455 +2423 +2423 +2434 +2421 +2432 +2415 +2443 +2426 +2435 +2371 +2417 +2421 +2430 +2439 +2434 +2434 +2431 +2423 +2422 +2408 +2432 +2433 +2428 +2435 +2475 +2427 +2426 +2469 +2413 +2440 +2457 +2420 +2438 +2439 +2441 +2443 +2429 +2416 +2444 +2480 +2427 +2429 +2433 +2450 +2427 +2416 +2433 +2424 +2447 +2432 +2422 +2403 +2423 +2433 +2414 +2516 +2414 +2435 +2431 +2393 +2433 +2428 +2441 +2434 +2362 +2429 +2434 +2445 +2434 +2432 +2400 +2431 +2442 +2426 +2435 +2429 +2433 +2420 +2435 +2416 +2416 +2441 +2494 +2363 +2443 +2399 +2434 +2439 +2533 +2423 +2438 +2433 +2453 +2426 +2466 +2448 +2430 +2435 +2534 +2436 +2439 +2445 +2443 +2438 +2442 +2435 +2539 +2434 +2431 +2427 +2422 +2430 +2441 +2438 +2420 +2443 +2436 +2429 +2436 +2435 +2443 +2444 +2447 +2438 +2433 +2459 +2440 +2446 +2437 +2418 +2445 +2486 +2444 +2432 +2459 +2447 +2449 +2449 +2439 +2470 +2439 +2438 +2419 +2436 +2439 +2438 +2448 +2450 +2448 +2439 +2436 +2453 +2419 +2416 +2447 +2447 +2447 +2418 +2476 +2447 +2442 +2447 +2433 +2439 +2426 +2439 +2432 +2433 +2369 +2442 +2445 +2459 +2478 +2407 +2447 +2384 +2477 +2443 +2446 +2437 +2459 +2441 +2442 +2448 +2483 +2439 +2387 +2442 +2403 +2454 +2433 +2437 +2421 +2438 +2439 +2442 +2430 +2585 +2440 +2450 +2441 +2413 +2450 +2427 +2444 +2450 +2459 +2445 +2469 +2423 +2429 +2446 +2441 +2477 +2448 +2445 +2448 +2434 +2460 +2448 +2431 +2431 +2395 +2431 +2444 +2416 +2442 +2439 +2445 +2448 +2438 +2448 +2443 +2480 +2432 +2439 +2448 +2384 +2344 +2438 +2404 +2446 +2448 +2602 +2445 +2446 +2443 +2440 +2461 +2448 +2448 +2447 +2448 +2461 +2438 +2461 +2448 +2516 +2441 +2464 +2347 +2448 +2473 +2446 +2460 +2462 +2455 +2459 +2448 +2435 +2437 +2448 +2432 +2434 +2453 +2425 +2443 +2432 +2439 +2412 +2454 +2465 +2504 +2455 +2446 +2351 +2447 +2448 +2469 +2448 +2486 +2473 +2466 +2465 +2448 +2445 +2455 +2434 +2449 +2448 +2385 +2460 +2446 +2466 +2454 +2405 +2449 +2448 +2378 +2449 +2435 +2453 +2442 +2450 +2450 +2451 +2469 +2448 +2458 +2465 +2462 +2461 +2552 +2351 +2496 +2448 +2411 +2453 +2469 +2453 +2557 +2471 +2470 +2389 +2489 +2448 +2449 +2448 +2451 +2454 +2448 +2452 +2455 +2461 +2451 +2459 +2438 +2448 +2356 +2443 +2466 +2491 +2406 +2448 +2465 +2459 +2462 +2505 +2454 +2442 +2443 +2474 +2457 +2451 +2471 +2471 +2459 +2529 +2453 +2384 +2453 +2442 +2451 +2435 +2457 +2437 +2454 +2413 +2450 +2448 +2450 +2446 +2448 +2469 +2480 +2369 +2457 +2458 +2468 +2448 +2438 +2452 +2445 +2442 +2453 +2513 +2454 +2463 +2457 +2448 +2373 +2458 +2496 +2458 +2453 +2428 +2462 +2459 +2451 +2450 +2461 +2448 +2463 +2448 +2459 +2464 +2442 +2448 +2453 +2448 +2455 +2496 +2463 +2457 +2459 +2453 +2496 +2459 +2450 +2465 +2463 +2473 +2473 +2472 +2391 +2469 +2444 +2455 +2400 +2490 +2496 +2458 +2459 +2452 +2443 +2421 +2387 +2463 +2390 +2426 +2489 +2451 +2455 +2480 +2470 +2466 +2476 +2469 +2458 +2497 +2448 +2385 +2454 +2462 +2464 +2453 +2455 +2458 +2461 +2471 +2464 +2454 +2454 +2481 +2527 +2544 +2449 +2468 +2480 +2423 +2459 +2476 +2521 +2491 +2479 +2451 +2435 +2461 +2460 +2458 +2434 +2447 +2465 +2559 +2451 +2451 +2461 +2436 +2448 +2475 +2465 +2477 +2473 +2448 +2470 +2470 +2458 +2467 +2452 +2463 +2403 +2459 +2475 +2475 +2374 +2466 +2489 +2493 +2463 +2454 +2397 +2464 +2461 +2467 +2462 +2455 +2447 +2543 +2467 +2481 +2483 +2481 +2383 +2469 +2479 +2474 +2469 +2462 +2380 +2458 +2595 +2416 +2458 +2463 +2480 +2466 +2551 +2479 +2466 +2445 +2487 +2598 +2478 +2478 +2480 +2467 +2473 +2475 +2449 +2468 +2479 +2462 +2462 +2473 +2463 +2468 +2508 +2467 +2497 +2470 +2471 +2469 +2423 +2448 +2489 +2461 +2463 +2555 +2465 +2480 +2480 +2453 +2471 +2465 +2476 +2480 +2458 +2476 +2464 +2479 +2480 +2423 +2453 +2384 +2477 +2475 +2450 +2487 +2473 +2473 +2398 +2466 +2474 +2413 +2492 +2498 +2501 +2477 +2496 +2494 +2463 +2473 +2448 +2480 +2481 +2502 +2478 +2479 +2480 +2485 +2467 +2533 +2478 +2477 +2479 +2434 +2487 +2489 +2493 +2467 +2483 +2480 +2442 +2478 +2467 +2479 +2467 +2469 +2482 +2467 +2480 +2466 +2482 +2448 +2462 +2475 +2480 +2480 +2480 +2417 +2462 +2455 +2474 +2479 +2465 +2500 +2477 +2478 +2597 +2465 +2477 +2463 +2470 +2495 +2475 +2458 +2471 +2483 +2474 +2433 +2470 +2471 +2471 +2475 +2467 +2469 +2486 +2471 +2477 +2481 +2485 +2419 +2481 +2460 +2471 +2479 +2499 +2490 +2463 +2480 +2494 +2489 +2469 +2485 +2480 +2479 +2416 +2489 +2482 +2451 +2484 +2497 +2512 +2485 +2487 +2420 +2484 +2497 +2483 +2483 +2579 +2473 +2554 +2466 +2506 +2482 +2474 +2502 +2481 +2453 +2478 +2374 +2448 +2490 +2495 +2500 +2503 +2528 +2474 +2502 +2480 +2473 +2480 +2487 +2480 +2483 +2493 +2480 +2467 +2407 +2485 +2503 +2480 +2484 +2489 +2480 +2479 +2482 +2502 +2506 +2480 +2487 +2463 +2486 +2471 +2493 +2490 +2544 +2486 +2478 +2479 +2480 +2496 +2483 +2485 +2481 +2483 +2491 +2474 +2480 +2486 +2481 +2475 +2487 +2502 +2484 +2492 +2510 +2495 +2464 +2493 +2498 +2482 +2474 +2496 +2495 +2526 +2498 +2496 +2485 +2500 +2467 +2461 +2466 +2503 +2494 +2517 +2427 +2510 +2483 +2487 +2480 +2455 +2505 +2626 +2483 +2485 +2495 +2493 +2487 +2544 +2478 +2498 +2487 +2479 +2496 +2480 +2550 +2471 +2501 +2480 +2506 +2481 +2496 +2504 +2482 +2491 +2495 +2418 +2494 +2491 +2493 +2493 +2496 +2526 +2492 +2490 +2486 +2486 +2470 +2418 +2496 +2490 +2510 +2490 +2472 +2503 +2480 +2482 +2330 +2530 +2495 +2486 +2603 +2478 +2485 +2490 +2519 +2501 +2489 +2502 +2497 +2419 +2486 +2482 +2500 +2503 +2493 +2537 +2497 +2516 +2496 +2496 +2495 +2508 +2443 +2490 +2502 +2559 +2496 +2487 +2499 +2516 +2491 +2497 +2494 +2497 +2483 +2497 +2497 +2532 +2515 +2512 +2500 +2501 +2491 +2499 +2493 +2501 +2509 +2505 +2501 +2503 +2503 +2522 +2512 +2635 +2493 +2506 +2508 +2487 +2496 +2465 +2512 +2496 +2425 +2499 +2479 +2503 +2503 +2498 +2494 +2505 +2512 +2652 +2480 +2528 +2493 +2503 +2581 +2501 +2489 +2509 +2384 +2515 +2503 +2509 +2506 +2512 +2515 +2516 +2502 +2559 +2514 +2506 +2517 +2511 +2610 +2515 +2498 +2499 +2458 +2511 +2521 +2513 +2496 +2507 +2544 +2507 +2528 +2501 +2559 +2491 +2515 +2489 +2496 +2517 +2509 +2485 +2512 +2461 +2503 +2502 +2457 +2513 +2531 +2499 +2495 +2502 +2499 +2506 +2511 +2416 +2510 +2529 +2506 +2503 +2494 +2499 +2512 +2497 +2506 +2498 +2512 +2499 +2507 +2496 +2507 +2512 +2518 +2521 +2506 +2475 +2509 +2513 +2605 +2505 +2495 +2509 +2501 +2503 +2481 +2511 +2511 +2503 +2499 +2506 +2375 +2505 +2505 +2506 +2543 +2533 +2501 +2593 +2499 +2608 +2512 +2510 +2516 +2510 +2501 +2505 +2512 +2512 +2512 +2506 +2507 +2500 +2416 +2512 +2509 +2512 +2451 +2523 +2502 +2500 +2457 +2515 +2496 +2513 +2506 +2534 +2585 +2599 +2512 +2498 +2506 +2523 +2505 +2503 +2509 +2535 +2513 +2517 +2471 +2537 +2502 +2512 +2503 +2379 +2494 +2502 +2514 +2512 +2518 +2512 +2507 +2511 +2501 +2448 +2587 +2507 +2512 +2405 +2506 +2493 +2507 +2496 +2507 +2512 +2505 +2510 +2525 +2506 +2531 +2506 +2498 +2501 +2517 +2493 +2514 +2511 +2515 +2516 +2512 +2497 +2512 +2641 +2529 +2503 +2518 +2492 +2513 +2512 +2450 +2515 +2489 +2507 +2496 +2508 +2512 +2499 +2504 +2404 +2523 +2593 +2515 +2513 +2516 +2511 +2509 +2511 +2496 +2512 +2529 +2529 +2512 +2518 +2524 +2505 +2464 +2512 +2507 +2513 +2559 +2511 +2491 +2514 +2516 +2523 +2448 +2519 +2517 +2502 +2512 +2513 +2589 +2539 +2503 +2517 +2533 +2510 +2559 +2527 +2512 +2506 +2653 +2505 +2515 +2511 +2512 +2517 +2528 +2509 +2518 +2501 +2512 +2508 +2482 +2525 +2435 +2531 +2512 +2495 +2463 +2513 +2516 +2448 +2542 +2529 +2507 +2507 +2512 +2527 +2507 +2516 +2512 +2530 +2497 +2512 +2509 +2513 +2519 +2473 +2512 +2529 +2521 +2513 +2517 +2517 +2517 +2662 +2523 +2522 +2530 +2513 +2516 +2514 +2540 +2526 +2517 +2515 +2524 +2512 +2512 +2512 +2534 +2527 +2514 +2531 +2528 +2518 +2519 +2537 +2477 +2508 +2542 +2535 +2610 +2522 +2528 +2507 +2593 +2532 +2522 +2521 +2510 +2526 +2529 +2559 +2545 +2513 +2508 +2522 +2559 +2532 +2608 +2518 +2523 +2512 +2502 +2439 +2502 +2535 +2511 +2538 +2526 +2526 +2513 +2588 +2541 +2496 +2511 +2527 +2515 +2551 +2544 +2515 +2591 +2486 +2511 +2546 +2548 +2497 +2519 +2448 +2517 +2516 +2559 +2524 +2507 +2509 +2528 +2512 +2521 +2529 +2519 +2498 +2496 +2518 +2701 +2546 +2525 +2528 +2512 +2531 +2518 +2511 +2487 +2532 +2481 +2525 +2527 +2501 +2514 +2559 +2526 +2529 +2502 +2539 +2515 +2514 +2515 +2542 +2519 +2522 +2543 +2531 +2538 +2540 +2512 +2533 +2532 +2519 +2522 +2515 +2523 +2518 +2530 +2535 +2517 +2534 +2525 +2537 +2538 +2531 +2462 +2537 +2492 +2433 +2528 +2512 +2523 +2512 +2519 +2555 +2508 +2543 +2527 +2583 +2527 +2526 +2533 +2502 +2553 +2542 +2551 +2577 +2522 +2559 +2544 +2454 +2480 +2530 +2529 +2512 +2519 +2524 +2530 +2511 +2533 +2469 +2513 +2509 +2512 +2531 +2538 +2523 +2531 +2499 +2512 +2523 +2513 +2524 +2524 +2535 +2541 +2537 +2542 +2514 +2544 +2555 +2531 +2506 +2529 +2515 +2523 +2544 +2463 +2528 +2590 +2535 +2559 +2538 +2535 +2545 +2531 +2529 +2535 +2609 +2543 +2555 +2555 +2531 +2553 +2544 +2528 +2535 +2529 +2530 +2526 +2544 +2514 +2528 +2515 +2535 +2553 +2542 +2529 +2531 +2498 +2541 +2466 +2529 +2495 +2541 +2586 +2543 +2526 +2482 +2531 +2537 +2544 +2521 +2525 +2540 +2527 +2536 +2540 +2518 +2530 +2526 +2544 +2517 +2526 +2539 +2531 +2529 +2535 +2528 +2538 +2543 +2531 +2545 +2533 +2529 +2529 +2533 +2533 +2537 +2542 +2543 +2541 +2544 +2537 +2489 +2595 +2542 +2521 +2518 +2613 +2554 +2544 +2529 +2544 +2559 +2535 +2540 +2538 +2544 +2534 +2548 +2535 +2537 +2593 +2525 +2559 +2530 +2541 +2640 +2535 +2532 +2549 +2531 +2535 +2544 +2529 +2555 +2513 +2559 +2544 +2543 +2559 +2555 +2526 +2559 +2537 +2545 +2544 +2544 +2544 +2480 +2547 +2517 +2537 +2559 +2531 +2559 +2541 +2462 +2586 +2538 +2534 +2545 +2457 +2539 +2543 +2544 +2544 +2533 +2559 +2542 +2687 +2533 +2512 +2555 +2549 +2645 +2535 +2544 +2545 +2535 +2549 +2541 +2448 +2585 +2543 +2544 +2554 +2545 +2557 +2581 +2555 +2556 +2554 +2557 +2544 +2551 +2539 +2607 +2555 +2551 +2610 +2544 +2546 +2605 +2531 +2550 +2552 +2494 +2557 +2541 +2523 +2528 +2547 +2548 +2544 +2505 +2550 +2539 +2539 +2540 +2521 +2547 +2541 +2544 +2543 +2535 +2546 +2537 +2467 +2539 +2544 +2516 +2544 +2559 +2533 +2547 +2538 +2559 +2545 +2542 +2538 +2559 +2528 +2545 +2549 +2551 +2559 +2534 +2486 +2559 +2559 +2551 +2544 +2457 +2542 +2519 +2538 +2543 +2548 +2530 +2544 +2532 +2545 +2544 +2557 +2526 +2550 +2554 +2678 +2559 +2544 +2528 +2539 +2535 +2538 +2539 +2555 +2506 +2531 +2549 +2555 +2559 +2559 +2554 +2557 +2543 +2549 +2555 +2559 +2510 +2549 +2543 +2544 +2538 +2554 +2549 +2541 +2559 +2539 +2460 +2544 +2547 +2553 +2559 +2555 +2550 +2550 +2479 +2496 +2528 +2543 +2527 +2537 +2554 +2557 +2556 +2542 +2518 +2543 +2599 +2544 +2545 +2551 +2547 +2559 +2553 +2549 +2519 +2544 +2466 +2557 +2544 +2686 +2559 +2559 +2554 +2557 +2555 +2556 +2559 +2449 +2592 +2559 +2541 +2544 +2519 +2550 +2640 +2525 +2559 +2559 +2559 +2559 +2559 +2550 +2559 +2582 +2559 +2559 +2544 +2550 +2544 +2545 +2555 +2559 +2559 +2544 +2559 +2614 +2547 +2608 +2553 +2534 +2559 +2555 +2559 +2522 +2547 +2559 +2559 +2555 +2586 +2557 +2559 +2559 +2537 +2519 +2558 +2554 +2546 +2544 +2558 +2528 +2550 +2496 +2534 +2467 +2550 +2558 +2544 +2558 +2559 +2546 +2557 +2545 +2490 +2546 +2545 +2549 +2559 +2552 +2559 +2547 +2547 +2559 +2557 +2546 +2544 +2550 +2474 +2544 +2549 +2587 +2544 +2551 +2597 +2559 +2512 +2555 +2559 +2556 +2545 +2559 +2558 +2559 +2547 +2626 +2469 +2559 +2431 +2559 +2558 +2546 +2543 +2448 +2548 +2601 +2550 +2545 +2549 +2543 +2559 +2501 +2559 +2559 +2554 +2559 +2613 +2559 +2559 +2559 +2559 +2543 +2559 +2549 +2559 +2559 +2559 +2554 +2559 +2546 +2559 +2559 +2581 +2611 +2544 +2557 +2579 +2559 +2559 +2555 +2559 +2540 +2555 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2614 +2511 +2624 +2559 +2544 +2559 +2559 +2591 +2580 +2555 +2544 +2544 +2599 +2559 +2507 +2543 +2545 +2559 +2559 +2559 +2580 +2559 +2559 +2559 +2581 +2559 +2559 +2559 +2548 +2559 +2559 +2559 +2559 +2559 +2608 +2606 +2559 +2554 +2559 +2559 +2555 +2549 +2551 +2529 +2547 +2455 +2558 +2523 +2602 +2549 +2558 +2550 +2558 +2559 +2559 +2556 +2559 +2559 +2559 +2557 +2559 +2559 +2559 +2491 +2559 +2559 +2559 +2559 +2589 +2512 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2554 +2524 +2559 +2555 +2502 +2545 +2547 +2559 +2581 +2558 +2559 +2581 +2555 +2673 +2540 +2559 +2558 +2559 +2596 +2587 +2553 +2559 +2556 +2603 +2519 +2552 +2559 +2559 +2559 +2559 +2590 +2554 +2557 +2559 +2559 +2547 +2559 +2586 +2554 +2482 +2559 +2559 +2611 +2583 +2559 +2587 +2559 +2559 +2559 +2541 +2559 +2583 +2558 +2559 +2559 +2559 +2559 +2559 +2494 +2559 +2559 +2551 +2512 +2559 +2559 +2594 +2559 +2587 +2503 +2581 +2559 +2559 +2559 +2559 +2559 +2559 +2548 +2545 +2559 +2602 +2559 +2559 +2559 +2591 +2559 +2487 +2559 +2559 +2539 +2559 +2559 +2559 +2589 +2604 +2559 +2583 +2587 +2583 +2556 +2736 +2586 +2591 +2587 +2539 +2585 +2559 +2559 +2559 +2604 +2513 +2559 +2583 +2559 +2583 +2558 +2599 +2582 +2559 +2555 +2605 +2559 +2590 +2527 +2559 +2499 +2559 +2559 +2559 +2559 +2613 +2559 +2559 +2591 +2559 +2590 +2559 +2559 +2590 +2581 +2558 +2579 +2724 +2593 +2583 +2622 +2559 +2559 +2582 +2559 +2583 +2559 +2559 +2608 +2609 +2559 +2557 +2608 +2582 +2593 +2581 +2589 +2704 +2591 +2559 +2559 +2533 +2587 +2593 +2559 +2503 +2618 +2593 +2592 +2559 +2556 +2559 +2585 +2559 +2589 +2549 +2582 +2614 +2622 +2559 +2559 +2551 +2559 +2559 +2693 +2607 +2581 +2583 +2617 +2559 +2559 +2559 +2559 +2598 +2559 +2587 +2583 +2559 +2704 +2581 +2585 +2591 +2581 +2592 +2559 +2589 +2588 +2582 +2512 +2622 +2524 +2559 +2586 +2559 +2555 +2592 +2554 +2583 +2559 +2605 +2559 +2559 +2610 +2583 +2579 +2559 +2592 +2559 +2597 +2559 +2559 +2559 +2603 +2586 +2559 +2590 +2589 +2591 +2559 +2534 +2585 +2581 +2606 +2559 +2535 +2602 +2582 +2628 +2587 +2587 +2597 +2559 +2559 +2587 +2591 +2608 +2583 +2592 +2588 +2590 +2602 +2625 +2597 +2559 +2587 +2559 +2619 +2614 +2604 +2630 +2598 +2594 +2590 +2553 +2595 +2603 +2583 +2546 +2608 +2590 +2559 +2559 +2624 +2581 +2581 +2559 +2559 +2608 +2587 +2592 +2585 +2582 +2593 +2590 +2559 +2588 +2619 +2583 +2593 +2544 +2559 +2604 +2595 +2557 +2647 +2559 +2582 +2589 +2583 +2588 +2579 +2593 +2590 +2588 +2582 +2582 +2559 +2586 +2590 +2595 +2592 +2501 +2559 +2619 +2591 +2585 +2583 +2559 +2559 +2608 +2559 +2559 +2598 +2539 +2601 +2559 +2621 +2559 +2559 +2689 +2585 +2559 +2609 +2605 +2553 +2589 +2608 +2559 +2581 +2593 +2581 +2642 +2594 +2589 +2597 +2592 +2623 +2608 +2592 +2622 +2599 +2599 +2601 +2585 +2559 +2587 +2524 +2585 +2582 +2559 +2582 +2559 +2585 +2594 +2624 +2609 +2587 +2589 +2559 +2582 +2608 +2599 +2608 +2585 +2584 +2590 +2598 +2503 +2648 +2559 +2610 +2597 +2602 +2559 +2592 +2505 +2597 +2559 +2599 +2591 +2559 +2588 +2559 +2593 +2601 +2598 +2591 +2559 +2608 +2559 +2535 +2595 +2611 +2589 +2591 +2592 +2594 +2755 +2602 +2591 +2601 +2604 +2608 +2559 +2599 +2590 +2624 +2598 +2608 +2615 +2607 +2599 +2612 +2599 +2600 +2599 +2587 +2492 +2602 +2607 +2602 +2592 +2608 +2608 +2594 +2592 +2559 +2602 +2589 +2521 +2594 +2624 +2521 +2624 +2687 +2595 +2592 +2590 +2588 +2507 +2608 +2527 +2603 +2601 +2496 +2602 +2624 +2559 +2599 +2598 +2587 +2587 +2595 +2598 +2586 +2611 +2595 +2595 +2599 +2606 +2589 +2745 +2615 +2587 +2599 +2715 +2603 +2710 +2599 +2559 +2653 +2594 +2595 +2545 +2653 +2607 +2599 +2597 +2583 +2590 +2599 +2595 +2619 +2554 +2587 +2559 +2513 +2589 +2590 +2559 +2607 +2607 +2598 +2606 +2559 +2587 +2559 +2624 +2608 +2602 +2595 +2691 +2592 +2613 +2598 +2609 +2608 +2595 +2559 +2512 +2605 +2603 +2590 +2591 +2597 +2602 +2601 +2519 +2586 +2593 +2587 +2588 +2586 +2603 +2595 +2602 +2559 +2609 +2603 +2559 +2596 +2599 +2594 +2602 +2704 +2624 +2591 +2617 +2600 +2477 +2598 +2622 +2600 +2604 +2559 +2602 +2596 +2586 +2583 +2593 +2590 +2608 +2608 +2608 +2593 +2582 +2608 +2596 +2593 +2609 +2597 +2587 +2599 +2559 +2613 +2580 +2604 +2596 +2589 +2531 +2608 +2595 +2607 +2603 +2597 +2606 +2602 +2610 +2541 +2614 +2552 +2672 +2603 +2674 +2598 +2599 +2599 +2559 +2608 +2608 +2607 +2608 +2607 +2624 +2610 +2608 +2597 +2603 +2606 +2596 +2606 +2615 +2604 +2589 +2606 +2609 +2605 +2607 +2608 +2609 +2607 +2583 +2550 +2607 +2603 +2716 +2608 +2559 +2595 +2600 +2624 +2607 +2595 +2609 +2608 +2599 +2619 +2695 +2559 +2603 +2622 +2595 +2589 +2603 +2606 +2742 +2608 +2606 +2620 +2603 +2608 +2618 +2601 +2608 +2610 +2601 +2606 +2604 +2601 +2601 +2613 +2602 +2619 +2609 +2609 +2448 +2607 +2608 +2597 +2607 +2601 +2606 +2611 +2595 +2606 +2624 +2624 +2611 +2607 +2597 +2592 +2595 +2591 +2612 +2621 +2621 +2619 +2607 +2595 +2539 +2614 +2609 +2626 +2589 +2611 +2615 +2603 +2559 +2615 +2622 +2615 +2599 +2611 +2547 +2615 +2587 +2613 +2608 +2619 +2621 +2554 +2611 +2599 +2623 +2599 +2616 +2614 +2607 +2613 +2617 +2559 +2626 +2597 +2608 +2608 +2625 +2597 +2613 +2608 +2617 +2613 +2595 +2608 +2608 +2624 +2640 +2619 +2524 +2537 +2619 +2619 +2615 +2608 +2614 +2609 +2610 +2603 +2610 +2512 +2609 +2598 +2626 +2559 +2613 +2609 +2701 +2605 +2615 +2608 +2619 +2637 +2598 +2583 +2625 +2603 +2590 +2608 +2587 +2605 +2612 +2622 +2643 +2612 +2610 +2609 +2619 +2611 +2599 +2619 +2621 +2594 +2614 +2639 +2615 +2608 +2603 +2630 +2615 +2632 +2585 +2630 +2619 +2615 +2608 +2598 +2608 +2601 +2615 +2625 +2615 +2625 +2612 +2736 +2644 +2586 +2619 +2510 +2595 +2617 +2614 +2611 +2614 +2619 +2608 +2697 +2609 +2627 +2637 +2606 +2608 +2605 +2612 +2610 +2599 +2627 +2605 +2619 +2594 +2609 +2621 +2622 +2657 +2627 +2614 +2627 +2623 +2608 +2606 +2594 +2559 +2624 +2607 +2667 +2724 +2608 +2615 +2613 +2537 +2605 +2611 +2627 +2669 +2605 +2609 +2585 +2606 +2604 +2625 +2613 +2607 +2619 +2624 +2598 +2631 +2610 +2665 +2618 +2608 +2637 +2613 +2609 +2630 +2704 +2642 +2606 +2611 +2620 +2734 +2590 +2624 +2603 +2611 +2618 +2611 +2607 +2620 +2615 +2617 +2549 +2614 +2595 +2591 +2736 +2634 +2627 +2608 +2608 +2612 +2686 +2607 +2610 +2606 +2624 +2585 +2647 +2612 +2608 +2610 +2640 +2594 +2607 +2559 +2611 +2621 +2623 +2596 +2627 +2613 +2613 +2607 +2611 +2559 +2538 +2665 +2608 +2614 +2618 +2624 +2608 +2586 +2624 +2614 +2608 +2615 +2612 +2624 +2625 +2610 +2611 +2608 +2619 +2734 +2611 +2644 +2608 +2630 +2640 +2608 +2625 +2611 +2589 +2615 +2602 +2624 +2618 +2615 +2559 +2619 +2623 +2621 +2614 +2615 +2618 +2635 +2624 +2625 +2642 +2622 +2635 +2557 +2630 +2599 +2624 +2595 +2615 +2608 +2624 +2619 +2608 +2614 +2623 +2642 +2608 +2617 +2618 +2618 +2635 +2615 +2627 +2615 +2625 +2607 +2624 +2555 +2624 +2608 +2613 +2622 +2640 +2627 +2615 +2626 +2623 +2634 +2623 +2623 +2549 +2611 +2617 +2640 +2605 +2621 +2622 +2613 +2629 +2645 +2620 +2621 +2624 +2623 +2710 +2591 +2621 +2612 +2641 +2631 +2625 +2619 +2626 +2620 +2619 +2783 +2640 +2582 +2592 +2559 +2625 +2614 +2637 +2608 +2624 +2608 +2640 +2559 +2622 +2622 +2625 +2631 +2631 +2631 +2640 +2636 +2637 +2558 +2639 +2617 +2743 +2631 +2647 +2616 +2645 +2625 +2633 +2647 +2605 +2552 +2609 +2624 +2613 +2559 +2640 +2623 +2624 +2612 +2619 +2545 +2610 +2625 +2627 +2628 +2644 +2619 +2626 +2624 +2624 +2607 +2626 +2614 +2690 +2631 +2630 +2624 +2623 +2634 +2635 +2622 +2615 +2625 +2623 +2607 +2607 +2610 +2630 +2635 +2559 +2817 +2639 +2705 +2758 +2619 +2603 +2607 +2609 +2625 +2608 +2641 +2641 +2624 +2581 +2615 +2593 +2630 +2629 +2614 +2615 +2608 +2628 +2618 +2721 +2619 +2608 +2614 +2657 +2544 +2609 +2641 +2637 +2633 +2582 +2305 +2654 +2617 +2608 +2524 +2624 +2622 +2640 +2631 +2624 +2635 +2651 +2608 +2639 +2608 +2628 +2624 +2629 +2629 +2624 +2632 +2639 +2641 +2613 +2608 +2631 +2643 +2624 +2630 +2638 +2622 +2626 +2628 +2612 +2608 +2624 +2726 +2624 +2617 +2641 +2629 +2557 +2626 +2636 +2651 +2559 +2626 +2601 +2629 +2614 +2599 +2631 +2643 +2601 +2635 +2633 +2630 +2628 +2706 +2629 +2634 +2764 +2631 +2627 +2617 +2639 +2637 +2593 +2638 +2630 +2631 +2634 +2609 +2634 +2649 +2608 +2635 +2625 +2627 +2559 +2638 +2637 +2677 +2631 +2559 +2627 +2636 +2546 +2624 +2603 +2628 +2607 +2681 +2559 +2640 +2619 +2629 +2633 +2531 +2646 +2623 +2631 +2640 +2634 +2626 +2637 +2671 +2620 +2679 +2617 +2639 +2559 +2624 +2623 +2637 +2624 +2651 +2613 +2633 +2639 +2589 +2663 +2619 +2615 +2500 +2631 +2414 +2608 +2609 +2615 +2624 +2624 +2641 +2622 +2591 +2635 +2647 +2625 +2623 +2627 +2663 +2614 +2655 +2603 +2593 +2635 +2633 +2648 +2639 +2624 +2800 +2636 +2637 +2749 +2621 +2636 +2770 +2625 +2622 +2633 +2671 +2640 +2636 +2631 +2618 +2615 +2635 +2631 +2663 +2630 +2587 +2630 +2638 +2641 +2640 +2630 +2506 +2633 +2559 +2628 +2647 +2639 +2597 +2608 +2630 +2598 +2638 +2609 +2633 +2542 +2631 +2637 +2636 +2647 +2640 +2624 +2670 +2627 +2633 +2874 +2629 +2642 +2638 +2637 +2645 +2639 +2647 +2625 +2637 +2639 +2652 +2640 +2640 +2558 +2672 +2641 +2583 +2635 +2636 +2635 +2612 +2634 +2639 +2613 +2631 +2617 +2639 +2624 +2644 +2639 +2763 +2634 +2662 +2559 +2624 +2507 +2645 +2647 +2638 +2588 +2630 +2629 +2645 +2593 +2615 +2634 +2633 +2628 +2545 +2627 +2663 +2634 +2627 +2641 +2621 +2642 +2628 +2635 +2640 +2627 +2640 +2626 +2614 +2608 +2640 +2646 +2623 +2635 +2640 +2621 +2623 +2615 +2642 +2645 +2643 +2665 +2642 +2634 +2640 +2641 +2640 +2640 +2634 +2635 +2640 +2632 +2618 +2559 +2633 +2631 +2627 +2638 +2639 +2642 +2667 +2551 +2687 +2629 +2613 +2640 +2655 +2626 +2632 +2640 +2554 +2625 +2512 +2640 +2634 +2632 +2630 +2636 +2663 +2623 +2633 +2644 +2559 +2625 +2630 +2651 +2641 +2642 +2639 +2640 +2631 +2633 +2634 +2636 +2624 +2639 +2622 +2641 +2640 +2643 +2634 +2643 +2628 +2613 +2636 +2644 +2544 +2647 +2640 +2642 +2653 +2541 +2631 +2652 +2641 +2633 +2630 +2559 +2646 +2663 +2641 +2756 +2608 +2640 +2642 +2638 +2639 +2630 +2637 +2638 +2655 +2655 +2644 +2623 +2635 +2656 +2623 +2655 +2651 +2647 +2627 +2630 +2640 +2638 +2642 +2627 +2653 +2636 +2641 +2641 +2626 +2626 +2717 +2544 +2641 +2642 +2639 +2754 +2649 +2656 +2639 +2621 +2640 +2605 +2559 +2633 +2636 +2644 +2640 +2624 +2645 +2635 +2624 +2647 +2640 +2631 +2634 +2550 +2625 +2701 +2625 +2639 +2644 +2667 +2667 +2632 +2628 +2624 +2639 +2618 +2634 +2646 +2647 +2633 +2640 +2635 +2642 +2657 +2633 +2590 +2643 +2626 +2641 +2638 +2654 +2643 +2640 +2646 +2611 +2629 +2642 +2634 +2559 +2694 +2639 +2650 +2640 +2620 +2637 +2646 +2645 +2641 +2641 +2642 +2644 +2639 +2669 +2620 +2636 +2660 +2663 +2755 +2592 +2640 +2640 +2635 +2624 +2637 +2640 +2640 +2633 +2619 +2647 +2643 +2627 +2618 +2629 +2642 +2636 +2636 +2641 +2643 +2640 +2657 +2611 +2626 +2641 +2624 +2643 +2654 +2639 +2640 +2656 +2635 +2640 +2637 +2647 +2645 +2671 +2644 +2637 +2622 +2638 +2639 +2641 +2641 +2716 +2631 +2639 +2649 +2637 +2640 +2626 +2651 +2668 +2646 +2646 +2645 +2640 +2653 +2640 +2640 +2634 +2646 +2641 +2646 +2640 +2649 +2653 +2663 +2645 +2653 +2631 +2646 +2656 +2661 +2753 +2701 +2655 +2645 +2647 +2672 +2655 +2656 +2693 +2655 +2659 +2649 +2646 +2653 +2640 +2652 +2653 +2640 +2640 +2659 +2670 +2647 +2650 +2654 +2621 +2639 +2646 +2630 +2657 +2638 +2642 +2647 +2672 +2665 +2684 +2640 +2661 +2647 +2643 +2667 +2656 +2650 +2798 +2641 +2667 +2656 +2639 +2637 +2651 +2644 +2642 +2626 +2637 +2646 +2652 +2627 +2651 +2637 +2642 +2642 +2661 +2641 +2657 +2640 +2591 +2634 +2640 +2651 +2713 +2800 +2640 +2645 +2646 +2645 +2559 +2644 +2646 +2653 +2645 +2640 +2652 +2554 +2654 +2647 +2640 +2640 +2643 +2657 +2659 +2657 +2643 +2653 +2663 +2629 +2602 +2602 +2661 +2683 +2661 +2640 +2651 +2654 +2537 +2647 +2641 +2669 +2642 +2755 +2668 +2651 +2637 +2628 +2624 +2640 +2646 +2652 +2647 +2681 +2636 +2645 +2627 +2648 +2636 +2628 +2650 +2645 +2648 +2640 +2651 +2654 +2645 +2654 +2653 +2656 +2653 +2559 +2646 +2634 +2642 +2651 +2611 +2663 +2657 +2639 +2640 +2659 +2665 +2640 +2640 +2645 +2559 +2627 +2695 +2640 +2645 +2658 +2640 +2649 +2655 +2653 +2646 +2662 +2647 +2640 +2647 +2641 +2644 +2672 +2659 +2669 +2659 +2647 +2710 +2637 +2656 +2667 +2662 +2652 +2672 +2653 +2635 +2651 +2702 +2663 +2642 +2647 +2678 +2665 +2663 +2645 +2643 +2640 +2649 +2655 +2656 +2653 +2658 +2682 +2662 +2627 +2653 +2643 +2636 +2731 +2640 +2662 +2674 +2635 +2662 +2641 +2626 +2640 +2655 +2622 +2647 +2645 +2640 +2672 +2655 +2586 +2649 +2655 +2626 +2657 +2645 +2674 +2671 +2647 +2657 +2667 +2629 +2640 +2647 +2651 +2743 +2677 +2640 +2657 +2650 +2661 +2666 +2650 +2656 +2550 +2643 +2663 +2643 +2644 +2641 +2688 +2592 +2646 +2559 +2635 +2659 +2651 +2649 +2659 +2661 +2643 +2647 +2647 +2647 +2651 +2655 +2631 +2661 +2658 +2640 +2642 +2585 +2669 +2650 +2647 +2650 +2640 +2599 +2652 +2663 +2655 +2649 +2611 +2666 +2662 +2671 +2668 +2649 +2656 +2646 +2632 +2657 +2661 +2672 +2634 +2629 +2653 +2639 +2644 +2723 +2659 +2671 +2694 +2653 +2653 +2651 +2653 +2647 +2658 +2648 +2643 +2667 +2650 +2657 +2634 +2743 +2655 +2663 +2641 +2666 +2652 +2559 +2637 +2688 +2643 +2643 +2646 +2657 +2651 +2636 +2640 +2664 +2640 +2669 +2646 +2657 +2677 +2667 +2668 +2642 +2655 +2646 +2673 +2683 +2656 +2670 +2652 +2660 +2669 +2654 +2656 +2653 +2659 +2672 +2649 +2653 +2646 +2650 +2653 +2672 +2653 +2658 +2591 +2624 +2663 +2654 +2661 +2648 +2651 +2672 +2667 +2652 +2657 +2655 +2662 +2666 +2606 +2686 +2615 +2642 +2656 +2655 +2647 +2627 +2658 +2643 +2671 +2694 +2639 +2655 +2645 +2642 +2635 +2636 +2555 +2656 +2645 +2651 +2659 +2598 +2556 +2606 +2635 +2634 +2674 +2642 +2655 +2649 +2643 +2649 +2645 +2659 +2647 +2669 +2559 +2635 +2660 +2658 +2673 +2674 +2655 +2653 +2653 +2658 +2665 +2639 +2642 +2621 +2657 +2643 +2637 +2670 +2786 +2653 +2645 +2655 +2665 +2654 +2607 +2637 +2666 +2608 +2656 +2636 +2667 +2652 +2657 +2669 +2683 +2637 +2621 +2652 +2674 +2675 +2649 +2645 +2657 +2638 +2582 +2652 +2632 +2679 +2672 +2641 +2651 +2682 +2672 +2666 +2629 +2654 +2657 +2677 +2672 +2672 +2750 +2654 +2663 +2738 +2640 +2480 +2768 +2641 +2707 +2665 +2676 +2682 +2672 +2649 +2659 +2663 +2653 +2670 +2628 +2667 +2659 +2654 +2665 +2658 +2659 +2660 +2634 +2654 +2661 +2623 +2661 +2653 +2656 +2674 +2653 +2633 +2655 +2657 +2559 +2655 +2646 +2639 +2663 +2663 +2672 +2677 +2653 +2654 +2689 +2672 +2643 +2665 +2654 +2668 +2671 +2656 +2646 +2656 +2651 +2559 +2672 +2657 +2656 +2662 +2635 +2667 +2650 +2651 +2636 +2687 +2655 +2647 +2605 +2704 +2654 +2649 +2681 +2663 +2786 +2659 +2656 +2657 +2626 +2656 +2656 +2634 +2663 +2730 +2682 +2647 +2646 +2635 +2656 +2644 +2666 +2652 +2644 +2653 +2651 +2643 +2640 +2643 +2650 +2665 +2609 +2653 +2655 +2662 +2665 +2679 +2655 +2656 +2655 +2661 +2695 +2668 +2658 +2678 +2656 +2622 +2649 +2646 +2662 +2655 +2653 +2641 +2644 +2663 +2667 +2664 +2642 +2646 +2619 +2658 +2672 +2661 +2656 +2658 +2653 +2743 +2672 +2649 +2666 +2676 +2645 +2642 +2671 +2672 +2658 +2648 +2587 +2663 +2646 +2647 +2652 +2655 +2642 +2672 +2654 +2653 +2684 +2608 +2663 +2661 +2672 +2626 +2781 +2659 +2658 +2663 +2606 +2646 +2650 +2658 +2642 +2665 +2661 +2662 +2663 +2675 +2663 +2663 +2663 +2716 +2625 +2639 +2643 +2663 +2635 +2637 +2663 +2657 +2688 +2663 +2693 +2702 +2640 +2662 +2655 +2635 +2719 +2658 +2653 +2658 +2559 +2671 +2640 +2663 +2666 +2646 +2640 +2674 +2663 +2651 +2621 +2691 +2661 +2673 +2651 +2659 +2640 +2666 +2662 +2658 +2640 +2647 +2620 +2662 +2650 +2608 +2675 +2690 +2672 +2650 +2634 +2656 +2659 +2615 +2635 +2653 +2661 +2622 +2662 +2674 +2669 +2656 +2650 +2667 +2676 +2671 +2654 +2654 +2657 +2661 +2696 +2667 +2673 +2654 +2635 +2672 +2654 +2662 +2652 +2653 +2636 +2672 +2759 +2623 +2649 +2667 +2630 +2693 +2701 +2672 +2655 +2651 +2641 +2611 +2661 +2640 +2639 +2653 +2667 +2631 +2646 +2663 +2643 +2667 +2655 +2720 +2717 +2671 +2653 +2658 +2622 +2559 +2657 +2704 +2651 +2663 +2649 +2666 +2693 +2645 +2658 +2634 +2657 +2665 +2625 +2658 +2642 +2657 +2654 +2657 +2659 +2734 +2602 +2647 +2659 +2641 +2615 +2655 +2671 +2663 +2651 +2650 +2599 +2654 +2667 +2695 +2663 +2708 +2640 +2688 +2667 +2672 +2671 +2669 +2682 +2659 +2630 +2665 +2701 +2660 +2681 +2673 +2657 +2666 +2671 +2558 +2658 +2660 +2646 +2658 +2641 +2611 +2757 +2629 +2651 +2655 +2610 +2661 +2653 +2674 +2656 +2621 +2677 +2667 +2608 +2663 +2666 +2639 +2655 +2662 +2790 +2658 +2658 +2640 +2677 +2654 +2700 +2669 +2647 +2640 +2655 +2685 +2631 +2595 +2659 +2656 +2663 +2671 +2655 +2633 +2670 +2594 +2615 +2662 +2676 +2655 +2669 +2656 +2658 +2653 +2665 +2659 +2671 +2658 +2653 +2667 +2653 +2669 +2657 +2661 +2647 +2656 +2629 +2650 +2765 +2659 +2769 +2653 +2640 +2645 +2671 +2645 +2699 +2656 +2646 +2662 +2658 +2659 +2657 +2652 +2646 +2658 +2650 +2661 +2707 +2559 +2665 +2788 +2666 +2590 +2653 +2668 +2640 +2605 +2661 +2640 +2669 +2648 +2624 +2635 +2646 +2661 +2658 +2683 +2661 +2647 +2663 +2662 +2631 +2672 +2661 +2660 +2670 +2651 +2670 +2653 +2658 +2665 +2654 +2671 +2672 +2688 +2655 +2637 +2647 +2661 +2661 +2659 +2659 +2679 +2688 +2686 +2659 +2666 +2655 +2623 +2681 +2672 +2663 +2659 +2659 +2665 +2675 +2637 +2665 +2688 +2652 +2704 +2626 +2607 +2656 +2667 +2671 +2665 +2647 +2650 +2670 +2644 +2671 +2629 +2651 +2640 +2639 +2649 +2661 +2656 +2640 +2580 +2663 +2671 +2688 +2655 +2650 +2647 +2653 +2662 +2662 +2716 +2659 +2611 +2669 +2652 +2657 +2660 +2672 +2667 +2639 +2645 +2640 +2676 +2654 +2643 +2662 +2684 +2672 +2669 +2666 +2714 +2659 +2654 +2659 +2666 +2663 +2672 +2658 +2641 +2661 +2740 +2659 +2658 +2673 +2655 +2659 +2667 +2656 +2737 +2655 +2665 +2660 +2655 +2620 +2657 +2667 +2655 +2662 +2586 +2654 +2662 +2670 +2665 +2661 +2663 +2656 +2655 +2663 +2668 +2651 +2677 +2660 +2654 +2638 +2661 +2674 +2643 +2642 +2654 +2667 +2652 +2679 +2674 +2649 +2647 +2662 +2683 +2643 +2734 +2673 +2651 +2559 +2666 +2662 +2654 +2650 +2661 +2653 +2657 +2649 +2662 +2656 +2659 +2669 +2658 +2703 +2662 +2735 +2675 +2640 +2678 +2666 +2655 +2655 +2671 +2780 +2665 +2661 +2657 +2654 +2623 +2602 +2652 +2672 +2662 +2648 +2722 +2663 +2655 +2644 +2666 +2607 +2624 +2667 +2655 +2678 +2448 +2659 +2670 +2559 +2655 +2635 +2668 +2668 +2672 +2685 +2589 +2661 +2663 +2666 +2678 +2677 +2646 +2649 +2657 +2651 +2647 +2663 +2645 +2646 +2653 +2662 +2579 +2670 +2653 +2645 +2646 +2650 +2649 +2544 +2647 +2690 +2655 +2654 +2590 +2591 +2657 +2667 +2661 +2639 +2679 +2659 +2646 +2418 +2671 +2640 +2669 +2651 +2663 +2629 +2654 +2665 +2640 +2675 +2661 +2669 +2666 +2659 +2673 +2657 +2659 +2671 +2658 +2666 +2671 +2653 +2658 +2654 +2693 +2655 +2655 +2722 +2656 +2667 +2659 +2672 +2661 +2667 +2655 +2663 +2819 +2655 +2669 +2655 +2658 +2663 +2643 +2675 +2661 +2653 +2661 +2702 +2657 +2658 +2634 +2640 +2727 +2661 +2663 +2666 +2667 +2663 +2663 +2657 +2676 +2658 +2625 +2657 +2644 +2635 +2659 +2646 +2669 +2669 +2706 +2647 +2659 +2653 +2688 +2651 +2659 +2658 +2642 +2663 +2658 +2658 +2668 +2666 +2669 +2653 +2666 +2652 +2672 +2662 +2670 +2640 +2651 +2673 +2657 +2657 +2589 +2658 +2655 +2661 +2663 +2654 +2656 +2659 +2643 +2641 +2667 +2654 +2649 +2651 +2669 +2640 +2640 +2559 +2670 +2667 +2666 +2861 +2691 +2672 +2669 +2666 +2652 +2654 +2640 +2669 +2640 +2671 +2682 +2661 +2588 +2690 +2643 +2662 +2667 +2602 +2660 +2642 +2666 +2663 +2657 +2629 +2663 +2748 +2658 +2640 +2669 +2647 +2655 +2646 +2649 +2672 +2672 +2670 +2690 +2659 +2647 +2663 +2652 +2657 +2741 +2642 +2655 +2663 +2662 +2642 +2663 +2656 +2658 +2662 +2645 +2647 +2661 +2656 +2646 +2665 +2608 +2624 +2775 +2659 +2669 +2670 +2655 +2654 +2656 +2640 +2653 +2674 +2660 +2656 +2660 +2675 +2672 +2593 +2658 +2678 +2662 +2666 +2652 +2663 +2668 +2644 +2646 +2651 +2657 +2655 +2679 +2663 +2665 +2657 +2671 +2676 +2651 +2654 +2657 +2655 +2559 +2650 +2647 +2544 +2651 +2687 +2637 +2658 +2523 +2678 +2671 +2666 +2659 +2656 +2652 +2667 +2649 +2658 +2657 +2649 +2652 +2661 +2674 +2663 +2658 +2733 +2673 +2683 +2699 +2647 +2692 +2659 +2667 +2612 +2655 +2666 +2657 +2666 +2670 +2655 +2669 +2672 +2669 +2675 +2664 +2687 +2657 +2695 +2704 +2693 +2662 +2639 +2657 +2627 +2672 +2666 +2672 +2663 +2681 +2649 +2672 +2681 +2663 +2643 +2671 +2670 +2597 +2659 +2667 +2649 +2659 +2681 +2637 +2667 +2672 +2662 +2654 +2764 +2638 +2649 +2661 +2650 +2649 +2675 +2661 +2679 +2656 +2677 +2663 +2596 +2647 +2659 +2623 +2663 +2687 +2667 +2665 +2662 +2640 +2639 +2662 +2646 +2655 +2639 +2669 +2661 +2670 +2655 +2672 +2659 +2675 +2639 +2665 +2659 +2661 +2605 +2590 +2624 +2662 +2663 +2614 +2657 +2678 +2662 +2670 +2654 +2656 +2672 +2672 +2663 +2667 +2651 +2662 +2676 +2649 +2678 +2649 +2670 +2672 +2662 +2640 +2659 +2656 +2665 +2656 +2734 +2672 +2670 +2703 +2660 +2559 +2657 +2658 +2647 +2662 +2657 +2669 +2618 +2651 +2655 +2661 +2657 +2670 +2672 +2665 +2662 +2641 +2593 +2674 +2658 +2667 +2672 +2663 +2666 +2620 +2662 +2669 +2659 +2657 +2695 +2655 +2591 +2641 +2658 +2661 +2640 +2670 +2790 +2657 +2655 +2768 +2653 +2667 +2671 +2662 +2640 +2654 +2743 +2658 +2659 +2657 +2779 +2651 +2650 +2670 +2647 +2660 +2663 +2675 +2690 +2654 +2652 +2655 +2646 +2647 +2665 +2525 +2669 +2650 +2654 +2659 +2666 +2650 +2672 +2602 +2666 +2659 +2659 +2674 +2658 +2666 +2679 +2667 +2665 +2624 +2658 +2688 +2661 +2656 +2674 +2651 +2704 +2658 +2666 +2646 +2661 +2652 +2653 +2662 +2655 +2643 +2677 +2646 +2611 +2704 +2663 +2653 +2665 +2647 +2658 +2641 +2671 +2659 +2637 +2653 +2624 +2641 +2666 +2666 +2678 +2653 +2661 +2657 +2644 +2661 +2662 +2662 +2656 +2657 +2653 +2593 +2644 +2651 +2654 +2659 +2665 +2640 +2656 +2672 +2657 +2601 +2653 +2640 +2661 +2659 +2629 +2642 +2671 +2662 +2591 +2663 +2641 +2677 +2687 +2639 +2648 +2704 +2559 +2671 +2559 +2647 +2623 +2649 +2657 +2640 +2667 +2663 +2657 +2649 +2585 +2559 +2659 +2666 +2627 +2674 +2658 +2647 +2667 +2650 +2661 +2918 +2672 +2661 +2599 +2663 +2657 +2657 +2646 +2660 +2665 +2644 +2657 +2661 +2653 +2645 +2658 +2601 +2641 +2666 +2659 +2653 +2670 +2661 +2671 +2647 +2661 +2559 +2647 +2701 +2669 +2647 +2663 +2645 +2655 +2662 +2670 +2674 +2674 +2669 +2667 +2620 +2693 +2751 +2662 +2660 +2656 +2659 +2559 +2662 +2668 +2654 +2678 +2661 +2656 +2629 +2662 +2683 +2666 +2661 +2669 +2631 +2642 +2645 +2667 +2702 +2656 +2631 +2647 +2673 +2647 +2667 +2608 +2663 +2653 +2658 +2635 +2645 +2640 +2661 +2658 +2644 +2665 +2647 +2666 +2672 +2639 +2655 +2658 +2670 +2669 +2531 +2655 +2667 +2651 +2559 +2650 +2646 +2646 +2651 +2718 +2669 +2639 +2664 +2664 +2655 +2784 +2655 +2681 +2672 +2658 +2662 +2635 +2643 +2669 +2662 +2656 +2651 +2646 +2640 +2660 +2657 +2659 +2662 +2659 +2640 +2663 +2662 +2656 +2559 +2622 +2638 +2642 +2652 +2614 +2661 +2666 +2657 +2656 +2704 +2662 +2653 +2640 +2645 +2635 +2655 +2608 +2657 +2666 +2634 +2659 +2661 +2655 +2638 +2653 +2653 +2646 +2673 +2658 +2656 +2677 +2624 +2671 +2653 +2653 +2593 +2667 +2703 +2653 +2768 +2640 +2641 +2631 +2659 +2651 +2640 +2658 +2659 +2659 +2654 +2703 +2559 +2672 +2672 +2647 +2637 +2646 +2653 +2635 +2640 +2663 +2662 +2642 +2646 +2659 +2647 +2638 +2653 +2635 +2625 +2637 +2645 +2652 +2675 +2656 +2656 +2627 +2699 +2651 +2666 +2651 +2656 +2649 +2640 +2626 +2635 +2636 +2678 +2651 +2663 +2655 +2674 +2643 +2679 +2620 +2614 +2526 +2650 +2611 +2649 +2641 +2643 +2651 +2636 +2632 +2653 +2642 +2665 +2665 +2642 +2671 +2665 +2654 +2651 +2671 +2645 +2672 +2656 +2643 +2656 +2645 +2651 +2663 +2650 +2652 +2662 +2651 +2640 +2651 +2678 +2652 +2637 +2589 +2640 +2640 +2647 +2657 +2599 +2652 +2656 +2647 +2645 +2662 +2643 +2650 +2626 +2640 +2656 +2608 +2661 +2658 +2707 +2606 +2646 +2589 +2640 +2603 +2655 +2646 +2662 +2636 +2645 +2640 +2651 +2659 +2637 +2658 +2645 +2658 +2665 +2667 +2736 +2670 +2638 +2559 +2595 +2666 +2671 +2654 +2654 +2689 +2646 +2650 +2672 +2654 +2687 +2645 +2656 +2667 +2650 +2691 +2659 +2590 +2646 +2609 +2587 +2640 +2658 +2659 +2642 +2656 +2647 +2657 +2654 +2651 +2647 +2637 +2626 +2675 +2649 +2647 +2640 +2667 +2659 +2650 +2653 +2667 +2654 +2636 +2640 +2639 +2624 +2646 +2647 +2649 +2640 +2596 +2644 +2650 +2645 +2663 +2641 +2642 +2658 +2661 +2547 +2657 +2640 +2650 +2625 +2651 +2663 +2660 +2656 +2652 +2645 +2639 +2667 +2652 +2655 +2650 +2674 +2646 +2658 +2656 +2646 +2651 +2766 +2661 +2650 +2638 +2650 +2645 +2658 +2615 +2547 +2643 +2643 +2658 +2640 +2672 +2640 +2643 +2648 +2655 +2663 +2663 +2666 +2631 +2655 +2642 +2656 +2645 +2646 +2656 +2788 +2644 +2640 +2650 +2642 +2690 +2657 +2641 +2641 +2640 +2646 +2631 +2641 +2640 +2640 +2650 +2657 +2633 +2614 +2602 +2643 +2645 +2651 +2637 +2601 +2643 +2658 +2635 +2657 +2646 +2660 +2593 +2645 +2645 +2649 +2647 +2657 +2653 +2776 +2652 +2649 +2640 +2654 +2640 +2646 +2672 +2640 +2651 +2643 +2647 +2639 +2618 +2645 +2640 +2641 +2702 +2653 +2646 +2647 +2647 +2643 +2653 +2640 +2649 +2644 +2627 +2608 +2630 +2646 +2602 +2653 +2654 +2542 +2640 +2663 +2660 +2642 +2624 +2640 +2646 +2646 +2665 +2641 +2624 +2640 +2637 +2644 +2641 +2638 +2647 +2643 +2632 +2647 +2641 +2651 +2624 +2651 +2660 +2646 +2671 +2644 +2667 +2651 +2647 +2650 +2652 +2601 +2633 +2656 +2658 +2637 +2637 +2627 +2735 +2653 +2595 +2656 +2647 +2629 +2640 +2672 +2655 +2582 +2640 +2646 +2645 +2559 +2643 +2659 +2653 +2646 +2743 +2636 +2654 +2655 +2654 +2658 +2645 +2650 +2655 +2652 +2636 +2657 +2639 +2647 +2613 +2559 +2665 +2651 +2652 +2653 +2642 +2662 +2647 +2743 +2662 +2649 +2654 +2644 +2674 +2649 +2646 +2649 +2714 +2666 +2643 +2645 +2647 +2654 +2640 +2633 +2639 +2640 +2590 +2559 +2645 +2688 +2635 +2677 +2638 +2655 +2637 +2640 +2608 +2649 +2655 +2641 +2641 +2640 +2642 +2640 +2640 +2662 +2559 +2654 +2655 +2646 +2638 +2648 +2611 +2646 +2669 +2640 +2649 +2638 +2634 +2637 +2668 +2715 +2651 +2640 +2659 +2634 +2627 +2651 +2630 +2625 +2651 +2663 +2640 +2642 +2643 +2643 +2637 +2639 +2605 +2606 +2653 +2643 +2645 +2629 +2647 +2672 +2647 +2640 +2638 +2559 +2641 +2666 +2670 +2640 +2644 +2639 +2643 +2639 +2624 +2648 +2651 +2635 +2559 +2637 +2614 +2651 +2624 +2713 +2607 +2668 +2655 +2611 +2644 +2631 +2634 +2697 +2640 +2640 +2641 +2651 +2658 +2718 +2663 +2652 +2640 +2641 +2651 +2649 +2644 +2643 +2658 +2637 +2699 +2644 +2645 +2645 +2643 +2654 +2653 +2544 +2645 +2665 +2634 +2640 +2640 +2640 +2631 +2605 +2623 +2650 +2638 +2631 +2749 +2618 +2637 +2642 +2654 +2559 +2647 +2619 +2559 +2633 +2631 +2634 +2644 +2645 +2641 +2640 +2628 +2663 +2640 +2661 +2639 +2645 +2593 +2641 +2640 +2642 +2606 +2640 +2640 +2644 +2644 +2645 +2594 +2660 +2647 +2669 +2639 +2640 +2640 +2644 +2649 +2640 +2634 +2639 +2639 +2641 +2647 +2640 +2642 +2653 +2656 +2631 +2641 +2649 +2639 +2672 +2637 +2640 +2639 +2649 +2645 +2629 +2629 +2661 +2656 +2639 +2634 +2649 +2640 +2635 +2594 +2651 +2633 +2631 +2626 +2640 +2644 +2640 +2639 +2631 +2634 +2631 +2640 +2618 +2642 +2640 +2662 +2640 +2646 +2642 +2636 +2608 +2637 +2629 +2637 +2640 +2646 +2643 +2639 +2624 +2603 +2643 +2641 +2645 +2643 +2633 +2655 +2635 +2613 +2533 +2627 +2643 +2559 +2736 +2642 +2647 +2606 +2640 +2623 +2637 +2671 +2626 +2642 +2647 +2639 +2629 +2640 +2657 +2640 +2649 +2659 +2635 +2641 +2619 +2647 +2641 +2651 +2651 +2655 +2640 +2640 +2645 +2640 +2672 +2635 +2641 +2639 +2641 +2640 +2634 +2677 +2643 +2590 +2645 +2624 +2640 +2640 +2612 +2668 +2652 +2663 +2626 +2609 +2639 +2634 +2638 +2635 +2651 +2636 +2634 +2638 +2650 +2634 +2643 +2640 +2638 +2635 +2585 +2624 +2635 +2652 +2485 +2635 +2768 +2631 +2603 +2639 +2640 +2638 +2641 +2630 +2640 +2654 +2582 +2625 +2638 +2625 +2651 +2732 +2635 +2634 +2644 +2635 +2647 +2639 +2640 +2631 +2643 +2678 +2636 +2662 +2631 +2629 +2641 +2604 +2643 +2640 +2631 +2638 +2614 +2635 +2640 +2845 +2670 +2638 +2646 +2635 +2640 +2596 +2640 +2624 +2638 +2628 +2662 +2640 +2623 +2623 +2634 +2640 +2624 +2640 +2650 +2636 +2539 +2633 +2629 +2726 +2640 +2659 +2626 +2645 +2682 +2599 +2628 +2636 +2626 +2640 +2635 +2650 +2634 +2625 +2621 +2640 +2637 +2640 +2638 +2637 +2631 +2617 +2590 +2641 +2665 +2634 +2627 +2634 +2637 +2640 +2624 +2629 +2643 +2630 +2626 +2656 +2554 +2615 +2641 +2639 +2606 +2657 +2617 +2637 +2626 +2647 +2649 +2624 +2626 +2634 +2624 +2644 +2627 +2640 +2640 +2721 +2617 +2639 +2590 +2658 +2628 +2628 +2644 +2608 +2625 +2670 +2638 +2623 +2634 +2694 +2629 +2623 +2640 +2608 +2641 +2651 +2637 +2633 +2681 +2640 +2624 +2608 +2631 +2635 +2637 +2608 +2624 +2614 +2626 +2630 +2628 +2654 +2637 +2637 +2630 +2646 +2631 +2639 +2618 +2629 +2613 +2610 +2640 +2619 +2624 +2623 +2622 +2662 +2626 +2634 +2636 +2663 +2640 +2614 +2623 +2627 +2634 +2637 +2637 +2639 +2623 +2559 +2644 +2639 +2640 +2646 +2627 +2641 +2622 +2675 +2631 +2631 +2640 +2581 +2634 +2627 +2629 +2608 +2704 +2643 +2672 +2624 +2627 +2608 +2559 +2613 +2631 +2586 +2639 +2634 +2624 +2627 +2640 +2630 +2639 +2640 +2624 +2640 +2623 +2633 +2607 +2739 +2639 +2627 +2621 +2756 +2636 +2559 +2633 +2607 +2627 +2555 +2628 +2639 +2643 +2626 +2633 +2637 +2640 +2627 +2609 +2626 +2617 +2634 +2608 +2637 +2638 +2643 +2629 +2634 +2625 +2639 +2615 +2643 +2631 +2627 +2788 +2643 +2628 +2641 +2631 +2647 +2599 +2634 +2635 +2624 +2627 +2537 +2640 +2627 +2592 +2625 +2551 +2633 +2640 +2640 +2620 +2627 +2689 +2636 +2639 +2559 +2634 +2617 +2621 +2640 +2633 +2614 +2639 +2630 +2480 +2591 +2619 +2628 +2544 +2637 +2619 +2636 +2608 +2612 +2559 +2586 +2620 +2667 +2625 +2627 +2615 +2624 +2640 +2639 +2559 +2621 +2641 +2620 +2611 +2592 +2620 +2603 +2624 +2614 +2637 +2631 +2624 +2617 +2625 +2614 +2559 +2618 +2609 +2615 +2615 +2619 +2622 +2618 +2638 +2639 +2612 +2581 +2637 +2633 +2621 +2624 +2640 +2622 +2635 +2730 +2629 +2621 +2626 +2591 +2619 +2610 +2621 +2618 +2607 +2643 +2624 +2621 +2628 +2643 +2623 +2630 +2624 +2672 +2559 +2608 +2625 +2639 +2622 +2608 +2624 +2627 +2609 +2762 +2624 +2625 +2608 +2559 +2630 +2619 +2631 +2625 +2631 +2615 +2624 +2625 +2736 +2624 +2609 +2611 +2618 +2594 +2623 +2615 +2612 +2645 +2603 +2619 +2624 +2617 +2619 +2619 +2625 +2624 +2608 +2579 +2631 +2644 +2628 +2631 +2621 +2719 +2620 +2618 +2617 +2608 +2652 +2544 +2615 +2634 +2630 +2622 +2635 +2637 +2630 +2631 +2622 +2623 +2643 +2636 +2621 +2640 +2631 +2640 +2607 +2625 +2638 +2671 +2622 +2615 +2605 +2608 +2435 +2615 +2510 +2624 +2625 +2629 +2727 +2615 +2625 +2619 +2629 +2614 +2604 +2623 +2613 +2747 +2630 +2613 +2623 +2418 +2618 +2620 +2612 +2608 +2585 +2618 +2611 +2608 +2631 +2640 +2619 +2590 +2613 +2630 +2608 +2622 +2602 +2559 +2559 +2640 +2608 +2559 +2642 +2620 +2613 +2619 +2615 +2606 +2623 +2617 +2671 +2593 +2631 +2639 +2640 +2582 +2617 +2620 +2599 +2637 +2633 +2621 +2619 +2626 +2625 +2647 +2608 +2618 +2618 +2579 +2623 +2606 +2618 +2629 +2623 +2617 +2609 +2631 +2632 +2639 +2624 +2619 +2623 +2607 +2645 +2627 +2603 +2613 +2643 +2607 +2610 +2619 +2624 +2769 +2613 +2559 +2613 +2609 +2634 +2618 +2617 +2559 +2603 +2611 +2624 +2608 +2630 +2548 +2615 +2608 +2603 +2605 +2608 +2597 +2608 +2608 +2610 +2615 +2620 +2617 +2619 +2614 +2618 +2538 +2732 +2608 +2619 +2601 +2547 +2603 +2619 +2602 +2623 +2619 +2624 +2628 +2613 +2620 +2673 +2617 +2645 +2625 +2625 +2624 +2623 +2623 +2614 +2608 +2625 +2610 +2625 +2589 +2628 +2624 +2694 +2624 +2611 +2619 +2602 +2611 +2606 +2609 +2617 +2624 +2607 +2608 +2603 +2527 +2613 +2436 +2656 +2593 +2595 +2607 +2602 +2607 +2617 +2616 +2608 +2559 +2622 +2608 +2611 +2619 +2665 +2608 +2597 +2659 +2682 +2617 +2609 +2583 +2622 +2607 +2437 +2621 +2612 +2767 +2612 +2608 +2617 +2602 +2606 +2612 +2613 +2608 +2650 +2610 +2610 +2608 +2602 +2612 +2616 +2645 +2596 +2608 +2621 +2621 +2608 +2603 +2603 +2609 +2599 +2598 +2591 +2609 +2608 +2594 +2615 +2559 +2646 +2596 +2606 +2607 +2505 +2617 +2607 +2596 +2610 +2601 +2705 +2613 +2646 +2605 +2585 +2607 +2603 +2559 +2618 +2608 +2608 +2534 +2614 +2613 +2614 +2626 +2594 +2638 +2609 +2612 +2617 +2603 +2598 +2606 +2604 +2608 +2591 +2607 +2607 +2626 +2608 +2603 +2608 +2607 +2608 +2596 +2615 +2611 +2559 +2637 +2613 +2619 +2611 +2606 +2646 +2601 +2601 +2527 +2613 +2614 +2622 +2617 +2624 +2619 +2608 +2614 +2782 +2607 +2622 +2624 +2619 +2616 +2606 +2620 +2614 +2637 +2624 +2601 +2583 +2625 +2631 +2630 +2640 +2608 +2622 +2603 +2610 +2597 +2606 +2588 +2608 +2608 +2611 +2614 +2604 +2597 +2608 +2613 +2603 +2585 +2602 +2583 +2592 +2608 +2605 +2603 +2614 +2590 +2626 +2606 +2602 +2716 +2585 +2587 +2588 +2624 +2624 +2608 +2606 +2595 +2587 +2611 +2595 +2559 +2615 +2606 +2603 +2608 +2599 +2542 +2598 +2592 +2599 +2608 +2581 +2604 +2621 +2602 +2609 +2605 +2613 +2609 +2597 +2559 +2592 +2616 +2661 +2559 +2559 +2613 +2608 +2516 +2608 +2559 +2587 +2605 +2624 +2599 +2608 +2583 +2592 +2585 +2603 +2605 +2585 +2608 +2605 +2608 +2711 +2609 +2598 +2559 +2559 +2603 +2622 +2603 +2589 +2594 +2606 +2591 +2597 +2515 +2601 +2603 +2605 +2496 +2594 +2508 +2597 +2559 +2609 +2615 +2604 +2592 +2559 +2640 +2593 +2599 +2591 +2543 +2603 +2630 +2605 +2598 +2583 +2623 +2599 +2591 +2582 +2608 +2551 +2595 +2559 +2658 +2582 +2581 +2544 +2664 +2587 +2595 +2592 +2627 +2594 +2605 +2606 +2596 +2595 +2588 +2593 +2559 +2597 +2609 +2606 +2590 +2598 +2593 +2639 +2615 +2559 +2608 +2596 +2593 +2590 +2611 +2590 +2595 +2602 +2591 +2592 +2559 +2606 +2607 +2548 +2559 +2598 +2605 +2591 +2591 +2597 +2596 +2590 +2608 +2589 +2586 +2594 +2595 +2587 +2582 +2615 +2603 +2594 +2597 +2598 +2597 +2529 +2593 +2604 +2757 +2595 +2589 +2591 +2554 +2608 +2594 +2599 +2593 +2609 +2587 +2593 +2608 +2605 +2602 +2603 +2592 +2603 +2602 +2607 +2598 +2595 +2619 +2516 +2592 +2608 +2598 +2614 +2559 +2559 +2606 +2583 +2594 +2591 +2618 +2589 +2522 +2603 +2597 +2606 +2613 +2599 +2559 +2626 +2605 +2590 +2587 +2589 +2600 +2594 +2559 +2586 +2641 +2595 +2586 +2597 +2599 +2594 +2559 +2590 +2587 +2583 +2593 +2501 +2590 +2589 +2559 +2559 +2585 +2591 +2597 +2593 +2613 +2592 +2559 +2559 +2585 +2580 +2559 +2592 +2641 +2592 +2615 +2608 +2618 +2509 +2597 +2582 +2593 +2527 +2559 +2593 +2596 +2524 +2599 +2603 +2585 +2605 +2583 +2599 +2682 +2587 +2591 +2559 +2539 +2595 +2624 +2601 +2624 +2559 +2591 +2587 +2559 +2559 +2597 +2603 +2594 +2594 +2601 +2512 +2591 +2604 +2585 +2593 +2559 +2598 +2559 +2604 +2601 +2603 +2608 +2586 +2594 +2595 +2579 +2545 +2591 +2583 +2558 +2579 +2585 +2594 +2559 +2593 +2559 +2583 +2583 +2559 +2660 +2588 +2595 +2559 +2585 +2583 +2591 +2598 +2705 +2545 +2587 +2556 +2583 +2559 +2605 +2603 +2559 +2588 +2586 +2589 +2559 +2586 +2590 +2603 +2606 +2603 +2617 +2595 +2619 +2590 +2559 +2640 +2587 +2559 +2736 +2557 +2555 +2559 +2586 +2592 +2602 +2586 +2593 +2555 +2598 +2554 +2586 +2595 +2592 +2590 +2602 +2603 +2605 +2592 +2587 +2480 +2596 +2592 +2532 +2589 +2602 +2608 +2590 +2559 +2589 +2594 +2589 +2599 +2626 +2599 +2559 +2512 +2594 +2592 +2596 +2603 +2655 +2559 +2527 +2589 +2594 +2588 +2559 +2501 +2559 +2559 +2414 +2586 +2590 +2663 +2559 +2559 +2559 +2582 +2583 +2559 +2554 +2678 +2589 +2559 +2474 +2586 +2598 +2559 +2594 +2582 +2559 +2559 +2590 +2481 +2599 +2587 +2692 +2595 +2559 +2587 +2586 +2600 +2592 +2496 +2579 +2559 +2623 +2624 +2559 +2583 +2559 +2559 +2485 +2581 +2597 +2581 +2559 +2591 +2596 +2588 +2582 +2559 +2591 +2678 +2583 +2588 +2559 +2494 +2608 +2583 +2583 +2653 +2586 +2583 +2582 +2586 +2524 +2582 +2593 +2606 +2559 +2619 +2586 +2586 +2585 +2559 +2591 +2559 +2559 +2594 +2712 +2581 +2533 +2635 +2559 +2559 +2589 +2581 +2559 +2559 +2559 +2559 +2559 +2614 +2581 +2653 +2559 +2584 +2583 +2559 +2608 +2559 +2559 +2590 +2559 +2559 +2580 +2678 +2559 +2559 +2544 +2581 +2616 +2559 +2534 +2617 +2559 +2559 +2557 +2559 +2559 +2559 +2683 +2553 +2559 +2626 +2559 +2607 +2559 +2559 +2679 +2582 +2588 +2559 +2581 +2559 +2583 +2588 +2581 +2559 +2583 +2559 +2589 +2559 +2629 +2559 +2559 +2579 +2559 +2554 +2558 +2559 +2559 +2559 +2590 +2558 +2581 +2559 +2559 +2582 +2559 +2559 +2583 +2499 +2547 +2534 +2491 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2549 +2557 +2608 +2559 +2591 +2559 +2559 +2602 +2559 +2583 +2586 +2586 +2587 +2531 +2559 +2581 +2559 +2610 +2614 +2508 +2559 +2557 +2559 +2590 +2558 +2559 +2594 +2559 +2541 +2558 +2559 +2559 +2551 +2592 +2582 +2559 +2608 +2586 +2538 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2549 +2559 +2589 +2559 +2549 +2559 +2559 +2559 +2555 +2555 +2559 +2557 +2628 +2559 +2559 +2559 +2554 +2473 +2559 +2559 +2559 +2556 +2559 +2559 +2559 +2582 +2550 +2559 +2559 +2586 +2559 +2559 +2559 +2475 +2592 +2559 +2559 +2557 +2559 +2559 +2531 +2559 +2559 +2559 +2559 +2559 +2600 +2559 +2550 +2551 +2547 +2559 +2553 +2589 +2559 +2559 +2559 +2559 +2592 +2559 +2690 +2468 +2512 +2534 +2597 +2558 +2533 +2559 +2559 +2559 +2559 +2559 +2559 +2559 +2551 +2551 +2559 +2547 +2549 +2556 +2581 +2559 +2559 +2559 +2584 +2559 +2559 +2593 +2555 +2545 +2559 +2543 +2557 +2559 +2608 +2559 +2550 +2559 +2548 +2559 +2554 +2559 +2549 +2559 +2559 +2559 +2559 +2586 +2558 +2559 +2559 +2559 +2700 +2559 +2559 +2521 +2559 +2550 +2553 +2544 +2713 +2559 +2554 +2559 +2559 +2533 +2559 +2541 +2541 +2559 +2537 +2557 +2555 +2451 +2559 +2559 +2530 +2559 +2545 +2559 +2559 +2543 +2559 +2585 +2453 +2557 +2559 +2557 +2551 +2594 +2546 +2559 +2455 +2480 +2557 +2551 +2548 +2523 +2545 +2557 +2586 +2511 +2559 +2514 +2544 +2559 +2559 +2544 +2543 +2555 +2554 +2559 +2551 +2559 +2558 +2558 +2469 +2559 +2556 +2555 +2544 +2515 +2559 +2550 +2554 +2553 +2493 +2557 +2505 +2558 +2512 +2547 +2549 +2546 +2549 +2443 +2543 +2550 +2543 +2621 +2559 +2559 +2554 +2587 +2555 +2554 +2500 +2552 +2556 +2559 +2549 +2559 +2555 +2538 +2559 +2559 +2559 +2559 +2559 +2558 +2490 +2556 +2559 +2545 +2559 +2559 +2559 +2539 +2608 +2545 +2546 +2549 +2550 +2549 +2605 +2555 +2554 +2544 +2559 +2552 +2547 +2557 +2591 +2557 +2544 +2548 +2551 +2521 +2545 +2448 +2547 +2475 +2544 +2559 +2559 +2544 +2559 +2559 +2549 +2552 +2549 +2546 +2586 +2553 +2439 +2551 +2548 +2608 +2544 +2480 +2546 +2559 +2525 +2555 +2556 +2547 +2549 +2546 +2544 +2559 +2541 +2544 +2557 +2553 +2522 +2544 +2541 +2541 +2540 +2531 +2483 +2545 +2548 +2559 +2545 +2544 +2559 +2559 +2554 +2544 +2528 +2549 +2553 +2503 +2581 +2542 +2616 +2484 +2559 +2544 +2557 +2527 +2559 +2523 +2555 +2546 +2527 +2590 +2532 +2487 +2556 +2530 +2547 +2542 +2557 +2480 +2542 +2546 +2545 +2583 +2544 +2526 +2544 +2559 +2559 +2544 +2546 +2544 +2550 +2509 +2553 +2539 +2549 +2545 +2654 +2542 +2534 +2542 +2708 +2551 +2544 +2548 +2544 +2546 +2542 +2539 +2559 +2559 +2551 +2582 +2544 +2543 +2559 +2558 +2527 +2544 +2529 +2544 +2656 +2539 +2544 +2545 +2550 +2491 +2541 +2549 +2534 +2554 +2543 +2544 +2496 +2551 +2532 +2580 +2545 +2544 +2544 +2550 +2534 +2559 +2559 +2550 +2539 +2546 +2545 +2541 +2551 +2656 +2553 +2538 +2549 +2528 +2544 +2542 +2455 +2540 +2538 +2480 +2544 +2518 +2507 +2538 +2544 +2544 +2480 +2559 +2534 +2525 +2543 +2559 +2535 +2531 +2672 +2547 +2550 +2533 +2542 +2481 +2539 +2530 +2526 +2557 +2550 +2535 +2559 +2529 +2500 +2591 +2547 +2545 +2535 +2597 +2546 +2545 +2539 +2473 +2535 +2544 +2549 +2548 +2481 +2535 +2530 +2544 +2545 +2559 +2481 +2463 +2557 +2541 +2551 +2531 +2548 +2547 +2547 +2558 +2543 +2559 +2537 +2537 +2506 +2544 +2527 +2550 +2547 +2541 +2530 +2477 +2535 +2547 +2534 +2527 +2539 +2531 +2544 +2534 +2528 +2533 +2530 +2527 +2534 +2551 +2547 +2548 +2544 +2544 +2542 +2493 +2535 +2518 +2512 +2527 +2593 +2544 +2528 +2535 +2557 +2519 +2540 +2541 +2559 +2541 +2531 +2534 +2669 +2546 +2549 +2539 +2503 +2534 +2518 +2538 +2530 +2542 +2534 +2512 +2530 +2611 +2543 +2528 +2518 +2532 +2534 +2402 +2545 +2512 +2559 +2544 +2528 +2515 +2545 +2525 +2521 +2534 +2543 +2525 +2534 +2541 +2547 +2535 +2535 +2541 +2530 +2534 +2525 +2538 +2559 +2523 +2530 +2518 +2555 +2543 +2529 +2534 +2473 +2495 +2500 +2542 +2522 +2495 +2439 +2534 +2537 +2527 +2531 +2480 +2545 +2539 +2544 +2559 +2526 +2512 +2528 +2515 +2527 +2527 +2504 +2459 +2530 +2517 +2512 +2521 +2559 +2526 +2517 +2526 +2511 +2538 +2527 +2515 +2672 +2523 +2678 +2535 +2457 +2509 +2522 +2507 +2515 +2416 +2528 +2514 +2526 +2608 +2510 +2529 +2515 +2507 +2529 +2522 +2527 +2533 +2527 +2513 +2530 +2525 +2491 +2532 +2499 +2524 +2517 +2478 +2524 +2474 +2512 +2530 +2500 +2531 +2657 +2530 +2514 +2539 +2533 +2533 +2529 +2554 +2527 +2513 +2594 +2531 +2522 +2415 +2544 +2529 +2513 +2515 +2547 +2530 +2515 +2526 +2517 +2530 +2389 +2522 +2529 +2559 +2531 +2532 +2518 +2526 +2559 +2514 +2525 +2499 +2524 +2527 +2528 +2512 +2506 +2542 +2509 +2533 +2512 +2512 +2518 +2497 +2519 +2513 +2481 +2522 +2512 +2545 +2521 +2545 +2534 +2512 +2512 +2518 +2509 +2524 +2516 +2541 +2523 +2551 +2512 +2477 +2523 +2529 +2526 +2493 +2521 +2515 +2521 +2545 +2535 +2541 +2525 +2519 +2518 +2403 +2512 +2514 +2438 +2512 +2511 +2528 +2521 +2525 +2559 +2507 +2538 +2559 +2535 +2523 +2522 +2462 +2543 +2524 +2512 +2507 +2493 +2516 +2508 +2512 +2549 +2538 +2453 +2523 +2535 +2522 +2542 +2546 +2512 +2515 +2557 +2536 +2522 +2531 +2507 +2509 +2544 +2502 +2523 +2522 +2549 +2522 +2512 +2522 +2525 +2521 +2529 +2526 +2517 +2526 +2512 +2522 +2509 +2512 +2509 +2521 +2513 +2512 +2523 +2510 +2418 +2497 +2512 +2520 +2512 +2516 +2529 +2529 +2522 +2519 +2679 +2529 +2519 +2527 +2531 +2491 +2448 +2501 +2512 +2543 +2506 +2529 +2494 +2506 +2542 +2509 +2522 +2501 +2494 +2491 +2650 +2518 +2513 +2512 +2527 +2515 +2523 +2538 +2511 +2480 +2510 +2517 +2512 +2511 +2510 +2505 +2513 +2526 +2522 +2504 +2513 +2522 +2594 +2539 +2519 +2509 +2512 +2544 +2527 +2508 +2442 +2513 +2538 +2518 +2516 +2511 +2521 +2550 +2523 +2513 +2529 +2557 +2522 +2505 +2507 +2507 +2509 +2507 +2542 +2505 +2512 +2509 +2483 +2514 +2506 +2516 +2521 +2515 +2513 +2505 +2510 +2509 +2477 +2512 +2501 +2512 +2522 +2511 +2510 +2499 +2506 +2498 +2499 +2512 +2479 +2489 +2506 +2510 +2514 +2557 +2451 +2495 +2512 +2502 +2491 +2525 +2465 +2512 +2506 +2519 +2494 +2502 +2503 +2496 +2465 +2512 +2559 +2523 +2497 +2495 +2512 +2497 +2494 +2486 +2517 +2514 +2509 +2519 +2512 +2514 +2522 +2508 +2445 +2510 +2525 +2503 +2509 +2519 +2509 +2496 +2495 +2506 +2458 +2510 +2496 +2530 +2509 +2506 +2512 +2505 +2407 +2506 +2505 +2501 +2518 +2494 +2523 +2510 +2510 +2501 +2510 +2559 +2506 +2512 +2512 +2457 +2509 +2512 +2493 +2503 +2505 +2494 +2503 +2501 +2459 +2491 +2506 +2513 +2482 +2426 +2496 +2505 +2512 +2495 +2503 +2494 +2492 +2499 +2505 +2512 +2503 +2498 +2505 +2409 +2489 +2516 +2512 +2559 +2504 +2487 +2544 +2504 +2512 +2499 +2559 +2510 +2485 +2531 +2653 +2535 +2491 +2502 +2510 +2509 +2501 +2481 +2509 +2501 +2512 +2512 +2491 +2501 +2492 +2511 +2496 +2502 +2498 +2559 +2527 +2548 +2531 +2512 +2500 +2434 +2529 +2498 +2502 +2509 +2550 +2491 +2513 +2540 +2527 +2544 +2506 +2475 +2559 +2502 +2494 +2549 +2423 +2502 +2511 +2540 +2509 +2495 +2494 +2496 +2498 +2583 +2518 +2507 +2497 +2501 +2485 +2507 +2496 +2496 +2500 +2557 +2502 +2497 +2497 +2495 +2494 +2486 +2497 +2507 +2495 +2498 +2421 +2474 +2499 +2496 +2508 +2498 +2481 +2493 +2499 +2470 +2512 +2491 +2479 +2502 +2498 +2497 +2496 +2492 +2527 +2455 +2510 +2502 +2509 +2531 +2502 +2496 +2499 +2500 +2444 +2503 +2512 +2512 +2409 +2512 +2498 +2499 +2501 +2506 +2509 +2526 +2510 +2506 +2478 +2463 +2621 +2494 +2495 +2491 +2496 +2482 +2486 +2508 +2498 +2517 +2501 +2496 +2530 +2480 +2496 +2508 +2487 +2474 +2480 +2485 +2423 +2486 +2489 +2624 +2498 +2496 +2500 +2490 +2499 +2503 +2482 +2490 +2477 +2500 +2487 +2493 +2491 +2497 +2625 +2467 +2485 +2491 +2488 +2497 +2497 +2486 +2491 +2486 +2491 +2497 +2497 +2512 +2469 +2496 +2493 +2513 +2495 +2497 +2491 +2506 +2489 +2496 +2487 +2490 +2489 +2496 +2416 +2525 +2480 +2489 +2491 +2487 +2480 +2496 +2513 +2497 +2491 +2490 +2395 +2491 +2482 +2483 +2498 +2471 +2489 +2493 +2485 +2490 +2496 +2497 +2388 +2483 +2496 +2448 +2506 +2473 +2485 +2479 +2480 +2480 +2477 +2475 +2482 +2522 +2511 +2495 +2448 +2489 +2406 +2507 +2547 +2486 +2447 +2489 +2487 +2476 +2495 +2480 +2480 +2427 +2530 +2491 +2479 +2481 +2483 +2321 +2477 +2480 +2479 +2461 +2489 +2478 +2494 +2480 +2486 +2489 +2461 +2427 +2482 +2508 +2484 +2527 +2484 +2482 +2485 +2414 +2487 +2487 +2487 +2385 +2482 +2482 +2479 +2480 +2505 +2497 +2507 +2484 +2477 +2507 +2386 +2480 +2483 +2481 +2485 +2470 +2470 +2486 +2467 +2480 +2485 +2493 +2416 +2461 +2477 +2482 +2491 +2462 +2468 +2487 +2481 +2507 +2480 +2480 +2457 +2478 +2608 +2459 +2503 +2480 +2487 +2517 +2471 +2479 +2483 +2471 +2376 +2476 +2448 +2484 +2354 +2459 +2541 +2448 +2480 +2479 +2477 +2477 +2474 +2478 +2475 +2480 +2479 +2460 +2430 +2495 +2493 +2459 +2462 +2475 +2477 +2477 +2478 +2485 +2480 +2480 +2455 +2416 +2481 +2439 +2476 +2467 +2485 +2478 +2475 +2474 +2486 +2470 +2485 +2461 +2480 +2511 +2483 +2482 +2481 +2480 +2461 +2465 +2479 +2475 +2472 +2487 +2475 +2487 +2393 +2481 +2417 +2482 +2474 +2419 +2486 +2512 +2448 +2471 +2480 +2386 +2478 +2642 +2485 +2480 +2462 +2492 +2451 +2513 +2480 +2469 +2471 +2473 +2417 +2477 +2479 +2475 +2481 +2503 +2527 +2470 +2471 +2473 +2470 +2469 +2465 +2480 +2475 +2469 +2465 +2480 +2467 +2475 +2475 +2468 +2455 +2465 +2464 +2480 +2473 +2451 +2480 +2479 +2484 +2459 +2430 +2480 +2448 +2484 +2470 +2435 +2476 +2496 +2475 +2480 +2462 +2477 +2460 +2467 +2480 +2475 +2468 +2495 +2464 +2473 +2471 +2466 +2512 +2461 +2510 +2466 +2473 +2485 +2496 +2471 +2467 +2489 +2471 +2454 +2491 +2423 +2493 +2461 +2469 +2519 +2477 +2469 +2481 +2427 +2475 +2471 +2472 +2479 +2455 +2471 +2479 +2466 +2464 +2475 +2429 +2477 +2453 +2384 +2467 +2473 +2511 +2415 +2469 +2463 +2453 +2463 +2464 +2475 +2459 +2380 +2476 +2448 +2453 +2465 +2457 +2449 +2478 +2467 +2411 +2453 +2466 +2469 +2451 +2451 +2474 +2465 +2505 +2437 +2478 +2433 +2463 +2466 +2463 +2486 +2478 +2463 +2467 +2470 +2462 +2471 +2471 +2483 +2455 +2474 +2475 +2461 +2468 +2438 +2456 +2389 +2464 +2470 +2463 +2451 +2453 +2485 +2455 +2448 +2433 +2463 +2467 +2468 +2448 +2469 +2459 +2463 +2471 +2463 +2384 +2468 +2471 +2463 +2466 +2475 +2465 +2483 +2463 +2469 +2468 +2457 +2464 +2414 +2480 +2462 +2468 +2458 +2473 +2473 +2449 +2469 +2464 +2467 +2405 +2443 +2489 +2518 +2367 +2464 +2467 +2494 +2467 +2403 +2480 +2467 +2460 +2374 +2448 +2471 +2450 +2448 +2442 +2448 +2445 +2539 +2448 +2448 +2453 +2448 +2464 +2455 +2485 +2448 +2480 +2468 +2449 +2466 +2454 +2463 +2459 +2455 +2457 +2452 +2466 +2481 +2466 +2448 +2459 +2481 +2551 +2464 +2466 +2458 +2495 +2466 +2450 +2455 +2435 +2447 +2435 +2434 +2455 +2464 +2601 +2469 +2451 +2463 +2459 +2447 +2462 +2457 +2459 +2332 +2459 +2459 +2455 +2434 +2453 +2442 +2472 +2463 +2462 +2448 +2451 +2461 +2464 +2449 +2455 +2461 +2467 +2438 +2454 +2454 +2452 +2448 +2457 +2474 +2441 +2458 +2495 +2458 +2464 +2434 +2433 +2418 +2559 +2442 +2448 +2449 +2464 +2448 +2453 +2450 +2448 +2451 +2449 +2416 +2451 +2463 +2440 +2559 +2449 +2528 +2608 +2452 +2448 +2448 +2465 +2384 +2432 +2439 +2442 +2419 +2447 +2464 +2433 +2451 +2436 +2463 +2438 +2444 +2460 +2451 +2494 +2450 +2459 +2448 +2448 +2461 +2457 +2410 +2448 +2399 +2447 +2434 +2447 +2454 +2448 +2470 +2448 +2445 +2439 +2448 +2448 +2402 +2459 +2432 +2451 +2463 +2462 +2467 +2448 +2450 +2453 +2485 +2422 +2535 +2431 +2445 +2442 +2449 +2541 +2442 +2447 +2441 +2430 +2445 +2457 +2447 +2371 +2451 +2448 +2430 +2426 +2678 +2435 +2367 +2445 +2446 +2448 +2434 +2368 +2450 +2428 +2442 +2464 +2432 +2461 +2546 +2384 +2427 +2447 +2476 +2441 +2451 +2439 +2416 +2434 +2453 +2455 +2534 +2438 +2447 +2453 +2439 +2474 +2455 +2438 +2441 +2550 +2443 +2437 +2437 +2437 +2432 +2447 +2431 +2445 +2512 +2512 +2448 +2447 +2448 +2435 +2482 +2429 +2453 +2416 +2448 +2485 +2436 +2445 +2423 +2447 +2443 +2454 +2448 +2448 +2448 +2448 +2545 +2445 +2443 +2453 +2429 +2453 +2453 +2417 +2432 +2433 +2437 +2432 +2442 +2446 +2449 +2387 +2427 +2439 +2448 +2442 +2433 +2438 +2403 +2438 +2451 +2417 +2409 +2441 +2443 +2471 +2475 +2425 +2439 +2428 +2418 +2398 +2437 +2439 +2431 +2439 +2395 +2454 +2439 +2431 +2422 +2432 +2458 +2436 +2422 +2435 +2446 +2437 +2428 +2436 +2435 +2447 +2437 +2435 +2448 +2425 +2442 +2445 +2386 +2441 +2441 +2445 +2447 +2439 +2449 +2440 +2435 +2432 +2437 +2405 +2448 +2521 +2494 +2446 +2465 +2433 +2470 +2404 +2431 +2256 +2431 +2353 +2430 +2433 +2432 +2499 +2422 +2432 +2414 +2430 +2361 +2441 +2430 +2442 +2445 +2431 +2432 +2411 +2384 +2438 +2396 +2529 +2428 +2369 +2416 +2423 +2433 +2427 +2408 +2493 +2407 +2425 +2436 +2374 +2425 +2411 +2395 +2430 +2431 +2434 +2446 +2431 +2425 +2369 +2423 +2435 +2457 +2399 +2431 +2418 +2434 +2407 +2418 +2418 +2434 +2419 +2417 +2427 +2429 +2441 +2467 +2425 +2416 +2427 +2441 +2447 +2426 +2432 +2428 +2429 +2438 +2417 +2426 +2333 +2435 +2407 +2422 +2439 +2430 +2400 +2438 +2411 +2428 +2440 +2451 +2458 +2427 +2427 +2426 +2435 +2439 +2430 +2371 +2454 +2431 +2429 +2470 +2418 +2354 +2435 +2439 +2432 +2427 +2421 +2416 +2431 +2419 +2558 +2416 +2438 +2404 +2425 +2441 +2351 +2375 +2419 +2427 +2352 +2421 +2418 +2423 +2443 +2421 +2442 +2420 +2424 +2432 +2422 +2432 +2411 +2433 +2443 +2439 +2387 +2434 +2407 +2441 +2436 +2438 +2427 +2399 +2434 +2421 +2419 +2432 +2432 +2416 +2434 +2421 +2432 +2443 +2400 +2414 +2432 +2435 +2429 +2423 +2427 +2419 +2411 +2427 +2426 +2513 +2420 +2391 +2455 +2416 +2432 +2432 +2426 +2427 +2430 +2415 +2425 +2429 +2416 +2414 +2417 +2418 +2397 +2412 +2419 +2406 +2410 +2414 +2381 +2425 +2450 +2407 +2416 +2401 +2420 +2416 +2411 +2419 +2379 +2416 +2391 +2434 +2407 +2397 +2416 +2351 +2405 +2426 +2415 +2402 +2419 +2415 +2413 +2433 +2416 +2427 +2412 +2559 +2386 +2416 +2365 +2443 +2291 +2397 +2419 +2432 +2409 +2415 +2432 +2415 +2426 +2377 +2410 +2417 +2418 +2452 +2460 +2416 +2529 +2404 +2386 +2416 +2422 +2423 +2416 +2416 +2417 +2416 +2416 +2410 +2377 +2401 +2416 +2352 +2402 +2414 +2530 +2405 +2407 +2403 +2418 +2395 +2411 +2311 +2407 +2406 +2446 +2411 +2416 +2332 +2415 +2413 +2399 +2423 +2416 +2417 +2415 +2417 +2423 +2421 +2432 +2307 +2425 +2415 +2413 +2397 +2384 +2410 +2406 +2431 +2421 +2416 +2410 +2410 +2401 +2394 +2436 +2416 +2399 +2400 +2353 +2405 +2407 +2398 +2401 +2400 +2401 +2413 +2411 +2404 +2408 +2411 +2413 +2411 +2406 +2422 +2416 +2410 +2390 +2416 +2512 +2409 +2411 +2326 +2415 +2395 +2349 +2423 +2395 +2394 +2404 +2397 +2375 +2369 +2419 +2414 +2358 +2390 +2400 +2406 +2384 +2398 +2397 +2395 +2410 +2403 +2466 +2430 +2386 +2421 +2411 +2397 +2413 +2410 +2415 +2380 +2403 +2390 +2405 +2391 +2297 +2423 +2394 +2470 +2384 +2346 +2398 +2405 +2405 +2397 +2391 +2399 +2397 +2398 +2402 +2389 +2395 +2421 +2367 +2375 +2396 +2401 +2416 +2404 +2414 +2403 +2391 +2302 +2463 +2421 +2387 +2425 +2405 +2410 +2426 +2401 +2404 +2425 +2406 +2395 +2409 +2395 +2432 +2407 +2402 +2543 +2400 +2417 +2416 +2403 +2416 +2351 +2403 +2403 +2379 +2379 +2409 +2409 +2409 +2425 +2394 +2397 +2399 +2503 +2333 +2411 +2439 +2401 +2390 +2401 +2395 +2517 +2418 +2387 +2498 +2402 +2406 +2395 +2408 +2362 +2394 +2391 +2404 +2403 +2416 +2399 +2387 +2405 +2421 +2400 +2398 +2284 +2397 +2405 +2402 +2398 +2395 +2449 +2401 +2410 +2401 +2409 +2407 +2378 +2412 +2411 +2394 +2402 +2423 +2387 +2393 +2382 +2413 +2401 +2409 +2388 +2403 +2397 +2400 +2395 +2395 +2393 +2406 +2326 +2393 +2385 +2428 +2389 +2395 +2398 +2386 +2387 +2310 +2352 +2394 +2393 +2369 +2383 +2381 +2403 +2381 +2407 +2401 +2393 +2400 +2398 +2395 +2370 +2395 +2390 +2383 +2429 +2375 +2429 +2387 +2385 +2493 +2399 +2384 +2385 +2397 +2391 +2351 +2416 +2397 +2409 +2381 +2393 +2382 +2391 +2320 +2384 +2384 +2390 +2380 +2380 +2384 +2393 +2387 +2384 +2383 +2381 +2383 +2507 +2387 +2393 +2369 +2392 +2370 +2375 +2384 +2384 +2387 +2346 +2404 +2384 +2385 +2366 +2393 +2395 +2390 +2387 +2400 +2394 +2383 +2385 +2311 +2382 +2373 +2397 +2384 +2386 +2394 +2384 +2370 +2389 +2378 +2391 +2320 +2384 +2388 +2517 +2394 +2389 +2389 +2438 +2385 +2421 +2384 +2423 +2390 +2390 +2383 +2394 +2492 +2384 +2391 +2381 +2384 +2418 +2385 +2411 +2395 +2389 +2305 +2394 +2390 +2389 +2384 +2384 +2384 +2397 +2394 +2384 +2320 +2526 +2396 +2384 +2381 +2524 +2341 +2393 +2388 +2403 +2339 +2413 +2371 +2400 +2365 +2401 +2343 +2405 +2384 +2291 +2319 +2397 +2397 +2389 +2384 +2364 +2373 +2373 +2397 +2339 +2383 +2389 +2379 +2375 +2390 +2362 +2314 +2398 +2464 +2535 +2393 +2402 +2384 +2381 +2382 +2381 +2343 +2375 +2335 +2394 +2368 +2375 +2385 +2359 +2368 +2395 +2384 +2383 +2352 +2380 +2384 +2391 +2381 +2339 +2404 +2386 +2450 +2384 +2369 +2484 +2395 +2448 +2382 +2377 +2384 +2379 +2385 +2370 +2384 +2422 +2375 +2455 +2385 +2363 +2384 +2385 +2375 +2389 +2382 +2374 +2383 +2309 +2378 +2374 +2385 +2426 +2330 +2379 +2362 +2373 +2370 +2377 +2343 +2379 +2373 +2372 +2371 +2378 +2384 +2281 +2368 +2369 +2369 +2374 +2389 +2342 +2435 +2368 +2363 +2375 +2387 +2373 +2384 +2364 +2382 +2373 +2375 +2366 +2369 +2375 +2373 +2364 +2358 +2342 +2384 +2321 +2337 +2383 +2358 +2371 +2384 +2307 +2320 +2358 +2371 +2379 +2378 +2366 +2387 +2368 +2374 +2382 +2374 +2367 +2384 +2381 +2383 +2352 +2311 +2389 +2382 +2397 +2366 +2397 +2375 +2384 +2382 +2387 +2362 +2377 +2378 +2368 +2398 +2258 +2380 +2356 +2384 +2408 +2400 +2381 +2375 +2384 +2359 +2381 +2370 +2349 +2369 +2315 +2322 +2371 +2363 +2342 +2383 +2361 +2384 +2364 +2386 +2365 +2315 +2304 +2367 +2354 +2384 +2352 +2335 +2370 +2366 +2294 +2259 +2367 +2371 +2372 +2372 +2355 +2368 +2365 +2365 +2382 +2368 +2384 +2367 +2373 +2353 +2368 +2368 +2384 +2371 +2383 +2368 +2359 +2382 +2352 +2369 +2363 +2355 +2370 +2348 +2366 +2418 +2367 +2352 +2434 +2365 +2321 +2367 +2347 +2364 +2351 +2383 +2384 +2352 +2374 +2167 +2371 +2372 +2385 +2367 +2385 +2385 +2350 +2359 +2379 +2362 +2375 +2366 +2305 +2367 +2366 +2471 +2361 +2365 +2363 +2381 +2357 +2356 +2384 +2378 +2390 +2362 +2364 +2363 +2352 +2365 +2364 +2361 +2353 +2358 +2354 +2352 +2358 +2349 +2367 +2352 +2358 +2368 +2298 +2352 +2368 +2365 +2369 +2352 +2384 +2333 +2377 +2363 +2311 +2349 +2377 +2360 +2352 +2369 +2353 +2395 +2357 +2357 +2355 +2350 +2366 +2359 +2357 +2362 +2367 +2359 +2365 +2350 +2361 +2354 +2360 +2353 +2285 +2352 +2363 +2349 +2355 +2399 +2355 +2361 +2352 +2393 +2362 +2357 +2351 +2368 +2315 +2357 +2360 +2367 +2365 +2279 +2357 +2368 +2363 +2359 +2361 +2368 +2363 +2358 +2480 +2367 +2279 +2341 +2366 +2403 +2353 +2366 +2309 +2323 +2352 +2367 +2336 +2408 +2357 +2347 +2358 +2351 +2420 +2357 +2369 +2335 +2375 +2354 +2373 +2367 +2352 +2348 +2355 +2355 +2368 +2352 +2377 +2331 +2460 +2364 +2336 +2351 +2345 +2350 +2301 +2375 +2355 +2351 +2323 +2352 +2353 +2494 +2354 +2362 +2367 +2353 +2482 +2384 +2355 +2363 +2352 +2337 +2275 +2462 +2354 +2355 +2391 +2350 +2352 +2355 +2328 +2347 +2278 +2358 +2359 +2275 +2365 +2352 +2368 +2359 +2353 +2350 +2354 +2351 +2359 +2352 +2365 +2368 +2333 +2279 +2350 +2362 +2353 +2353 +2358 +2354 +2375 +2350 +2347 +2343 +2353 +2365 +2343 +2354 +2363 +2357 +2343 +2340 +2345 +2354 +2346 +2353 +2355 +2354 + +* Mic branch [2026-04-19 Sun] +INMP441 +heres my overall (very messy) notes. + +i need a stepwise checklist of work to do, picking up this project after 6mo. + +i think broadest steps are: +1. remind myself of circuit state, how to hookup and test +2. implement inmp441 - may need to retool the circuit? + 1. will this functino on the existing power (big goal) + 2. remove/modify any inline circuitry to make this work? +3. ??? test? + +_Goal_: replace noisy speaker-tap adc path with an inmp441 mic path + - reuse existing esp32 + wifi + rtp stack + - reuse existing 3.17v power tap +** checklist +*** Bench Check +- the exact esp32 board +- the vtech dm221-2 / pm221 +- known-good firmware that can stream the 440hz tone over rtp to vlc +- the current ip/ssid/port expectations +- success = you can flash, boot, and hear tone mode again in vlc. this revalidates the network/rtp side before you perturb the input path + +*** Confirm live circuit: +- take clear photos of pcb top/bottom +- mark current power tap location +- mark current speaker/adc wiring +- note whether gpio36 speaker-tap circuit is still installed +- note whether touch pin mode switching is still wired +- your notes show enough circuit churn that future-you will otherwise get gaslit by Past You. + +*** Verify power in isolation: +- measure the 3.17v rail again at tp20/tp12/q6 +- confirm esp32 still boots stably from that rail +- add/confirm local decoupling near esp32 power if needed +- success = stable boot, wifi connect, no brownout/reboot weirdness. you already concluded the 3.17v tap was viable and a major goal is to keep it. + +*** Verify s/w baseline +keep hardware input out of it for a minute: + +- flash the known-good tone generator +- confirm seq/ts behavior and vlc playback +- optionally disable wifi power save while testing +- success = tone stream sounds clean enough that any later ugliness is input-side, not transport-side. + +*** hardware cutover +assume the old speaker-to-gpio36 analog front end gets bypassed or removed: +- gpio36 adc path is no longer the primary input +- the RC/divider/bias network for speaker tap is not needed for the mic path +- keep it only if you explicitly want fallback mode later +- this is the big topology change. don’t half-migrate and leave yourself ambiguous failure modes. your notes already point to the speaker tap being the pain source. + +*** bench-test the inmp441 off the existing esp32 power +- power inmp441 from the same esp32 3.xv rail +- wire only power + ground + i2s lines +- capture raw samples / stream audio with the mic sitting on the bench +- success = it powers and produces stable audio without resets/noise disasters. + +** inmp441 table +| PIN | NAME | FUNCTION | +|-----+--------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1 | SCK | Serial-Data Clock for IΒ²S Interface | +| 2 | SD | Serial-Data Output for IΒ²S Interface. This pin tri-states when not actively driving the appropriate output channel. The SD trace should have a 100 kΞ© pulldown resistor to discharge the line during the time that all microphones on the bus have tri-stated their outputs. | +| 3 | WS | Serial Data-Word Select for IΒ²S Interface | +| 4 | L/R | Left/Right Channel Select. When set low, the microphone outputs its signal in the left channel of the IΒ²S frame. When set high, the microphone outputs its signal in the right channel. | +| 5 | GND | Ground. Connect to ground on the PCB. | +| 6 | GND | Ground. Connect to ground on the PCB. | +| 7 | VDD | Power, 1.8 V to 3.3 V. This pin should be decoupled to Pin 6 with a 0.1 ΞΌF capacitor. | +| 8 | CHIPEN | Microphone Enable. When set low (ground), the microphone is disabled and put in power-down mode. When set high (VDD), the microphone is enabled. | +| 9 | GND | Ground. Connect to ground on the PCB | + +- added sketch to /proj/vtech/mic + +couple caveats, bc esp32 audio loves being a goblin: +the >> 11 unpack line is the bit most likely to need fiddling on your exact board/core, and I2S_COMM_FORMAT_STAND_I2S vs one of the older enum names can vary by installed core. + +*** script +#+begin_src c +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 25; // +const int I2S_SCK = 26; // +const int I2S_SD = 33; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + // init touch + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; + static unsigned long last_touch_check = 0; + static bool last_touch_state = false; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("switched to %s mode\n", tone_mode ? "tone" : "mic"); + delay(200); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + + // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz + int32_t mic_buf[FRAME_SIZE * 2]; + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + + int frames_read = bytes_read / sizeof(int32_t); + if (frames_read < FRAME_SIZE * 2) { + for (int i = 0; i < FRAME_SIZE; i++) samples[i] = 0; + } else { + static float dc = 0.0f; + static float lpf = 0.0f; + + for (int i = 0; i < FRAME_SIZE; i++) { + // inmp441 data is typically left-justified in 32-bit words; shift may need + // minor tweaking on your exact board/core + int32_t raw = mic_buf[i * 2] >> 14; // collapse toward 16-bit-ish range + float x = (float)raw; + + dc = dc * 0.999f + x * 0.001f; + x -= dc; + + lpf = lpf * 0.7f + x * 0.3f; + float y = lpf * 1.0f; // gain trim try 8.0f? + + if (y > 32767.0f) y = 32767.0f; + if (y < -32768.0f) y = -32768.0f; + samples[i] = (int16_t)y; + } + //DEBUG + static unsigned long last_dbg = 0; + int16_t minv = 32767; + int16_t maxv = -32768; + + for (int j = 0; j < FRAME_SIZE; j++) { + if (samples[j] < minv) minv = samples[j]; + if (samples[j] > maxv) maxv = samples[j]; + } + + if (millis() - last_dbg > 250) { + Serial.printf("mic range: %d .. %d\n", minv, maxv); + last_dbg = millis(); + } + // END DEBUG + } + } + + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} +#+end_src +*** script2 - simple mic processing (ln160 ff) +#+begin_src c +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 25; // +const int I2S_SCK = 26; // +const int I2S_SD = 33; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + // init touch + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; + static unsigned long last_touch_check = 0; + static bool last_touch_state = false; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + + // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz + int32_t mic_buf[FRAME_SIZE * 2]; + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + + int frames_read = bytes_read / sizeof(int32_t); + if (frames_read < FRAME_SIZE * 2) { + for (int i = 0; i < FRAME_SIZE; i++) samples[i] = 0; + } else { + static float dc = 0.0f; + static float lpf = 0.0f; + // + int16_t minv = 32767; + int16_t maxv = -32768; + static unsigned long last_dbg = 0; + + for (int i = 0; i < FRAME_SIZE; i++) { + int32_t raw = mic_buf[i * 2] >> 8; // try 8 first, not 14 + if (raw > 32767) raw = 32767; + if (raw < -32768) raw = -32768; + samples[i] = (int16_t)raw; + + if (samples[i] < minv) minv = samples[i]; + if (samples[i] > maxv) maxv = samples[i]; + } + + if (millis() - last_dbg > 250) { + Serial.printf("raw range: %d .. %d\n", minv, maxv); + last_dbg = millis(); + } + } + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} +#+end_src +*** script3 - hex dump version: +#+begin_src c++ +#include +#include +#include +#include +#include + +const char* ssid = "Fios-8EKF5"; +const char* password = "hero816cars7050jon"; +const char* DEST_IP = "192.168.1.190"; +const int UDP_PORT = 5004; + +const int OUTPUT_RATE = 8000; // 8kHz rtp payload rate +const int MIC_RATE = 16000; // capture rate inmp441 +const int FRAME_SIZE = 160; // 20ms frames @ 8kHz +const float TONE_HZ = 440.0; + +const touch_pad_t TOUCH_PIN = TOUCH_PAD_NUM4; // gpio13 +const int TOUCH_THRESHOLD = 800; // adjust as needed + +// inmp441 pins - change as needed +const int I2S_WS = 25; // +const int I2S_SCK = 26; // +const int I2S_SD = 33; // data from mic to esp32 + +WiFiUDP udp; +uint16_t seq = 0; +uint32_t ts = 0; +bool tone_mode = true; // start with tone + +struct rtp_hdr { + uint8_t vpxcc; + uint8_t mpt; + uint16_t seq; + uint32_t ts; + uint32_t ssrc; +}; + +static const int16_t exp_lut[256] = { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +uint8_t linear2ulaw(int16_t pcm_val) { + int sign = (pcm_val >> 8) & 0x80; + if (sign) pcm_val = (short)-pcm_val; + if (pcm_val > 32635) pcm_val = 32635; + pcm_val = pcm_val + 0x84; + int exponent = exp_lut[(pcm_val >> 7) & 0xFF]; + int mantissa = (pcm_val >> (exponent + 3)) & 0x0F; + return ~(sign | (exponent << 4) | mantissa); +} + +void setup_i2s_mic() { + i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = MIC_RATE, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, + .communication_format = I2S_COMM_FORMAT_STAND_I2S, + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, + .dma_buf_len = 256, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0 + }; + + i2s_pin_config_t pin_config = { + .bck_io_num = I2S_SCK, + .ws_io_num = I2S_WS, + .data_out_num = I2S_PIN_NO_CHANGE, + .data_in_num = I2S_SD + }; + + i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); + i2s_set_pin(I2S_NUM_0, &pin_config); + i2s_zero_dma_buffer(I2S_NUM_0); +} + +void setup() { + Serial.begin(115200); + + // init touch + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(TOUCH_PIN, 0); + + setup_i2s_mic(); + + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } + Serial.printf("\nconnected, ip=%s\n", WiFi.localIP().toString().c_str()); + udp.begin(UDP_PORT); + + Serial.println("tap pin 13 to switch modes"); +} + +void loop() { + static unsigned long last_send = 0; + static unsigned long last_touch_check = 0; + static bool last_touch_state = false; + static unsigned long last_dbg = 0; + static const unsigned long FRAME_INTERVAL = 20; // 20ms + static const unsigned long TOUCH_CHECK_INTERVAL = 50; // check every 50ms + + // check touch state periodically + unsigned long now = millis(); + if (now - last_touch_check > TOUCH_CHECK_INTERVAL) { + uint16_t touch_val; + touch_pad_read(TOUCH_PIN, &touch_val); + bool touched = touch_val < TOUCH_THRESHOLD; + + // detect touch press (not hold) + if (touched && !last_touch_state) { + tone_mode = !tone_mode; + Serial.printf("%s mode active\n", tone_mode ? "tone" : "mic"); + delay(300); // debounce + } + + last_touch_state = touched; + last_touch_check = now; + } + + // only send if it's time + if (now - last_send < FRAME_INTERVAL) { + yield(); + return; + } + + uint8_t packet[12 + FRAME_SIZE]; + int16_t samples[FRAME_SIZE]; + + if (tone_mode) { + // fixed tone generation with integer phase accumulator + static uint32_t phase_acc = 0; + const uint32_t phase_inc_int = (uint32_t)(TONE_HZ * (1ULL << 32) / OUTPUT_RATE); + + for (int i = 0; i < FRAME_SIZE; i++) { + float phase = (phase_acc >> 16) * (2.0 * M_PI / 65536.0); + samples[i] = (int16_t)(16000.0 * sinf(phase)); + phase_acc += phase_inc_int; + } + + } else { + + // read 320 mic samples @16khz, decimate by 2 -> 160 samples @8khz + int32_t mic_buf[FRAME_SIZE * 2]; + + size_t bytes_read = 0; + i2s_read(I2S_NUM_0, mic_buf, sizeof(mic_buf), &bytes_read, portMAX_DELAY); + for (int i = 0; i < FRAME_SIZE; i++) { + samples[i] = 0; + } + + if (bytes_read >= 16 * sizeof(int32_t) && millis() - last_dbg > 500) { + Serial.println("first 16 raw words:"); + for (int i = 0; i < 16; i++) { + Serial.printf("%2d: 0x%08lx\n", i, (uint32_t)mic_buf[i]); + } + last_dbg = millis(); + } + } + for (int i = 0; i < FRAME_SIZE; i++) { + packet[12 + i] = linear2ulaw(samples[i]); + } + + rtp_hdr* hdr = (rtp_hdr*)packet; + hdr->vpxcc = 0x80; + hdr->mpt = 0x00; + hdr->seq = htons(seq++); + hdr->ts = htonl(ts); + hdr->ssrc = htonl(0x12345678); + + udp.beginPacket(DEST_IP, UDP_PORT); + udp.write(packet, sizeof(packet)); + udp.endPacket(); + + ts += FRAME_SIZE; + last_send = now; + + yield(); +} +#+end_src + +** issue +https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/ +- dump is overwhelmingly 0x00000000, 0x00000001, or 0xffffffff, with only very occasional nontrivial words like 0xffbffb41. that means the esp32 is clocking something, but it is mostly seeing a line that is effectively stuck low/high or only barely transitioning, not normal audio sample words. +- in esp32 standard i2s mode, the bus is just bclk, ws, and data, and standard mode always has left/right slots. in master mode, the esp32 generates sck and ws; the mic only drives the data line. +- standard-mode format differences on esp32 are basically philips vs msb, where philips has a one-bit shift relative to ws and msb does not. so β€œwrong format” can cause junk, but a stream dominated by exact 0/1/-1 patterns is more consistent with bad data capture than mere gain. diff --git a/web/web.ino b/web/web.ino new file mode 100644 index 0000000..a4a88b3 --- /dev/null +++ b/web/web.ino @@ -0,0 +1,255 @@ +#include +#include +#include +#include + +preferences prefs; +webserver server(80); + +// touch pad used as boot override / setup trigger +const touch_pad_t touch_pin = TOUCH_PAD_NUM4; // gpio13 +const int touch_threshold = 500; + +// softap fallback +const char* ap_ssid = "baby-monitor-setup"; +const char* ap_password = "setup1234"; + +// saved / editable config +String wifi_ssid = ""; +String wifi_password = ""; +String dest_ip_str = "192.168.1.190"; +uint16_t udp_port = 5004; + +bool config_mode = false; +const unsigned long wifi_connect_timeout_ms = 15000; + +String html_escape(const String& s) { + String out = s; + out.replace("&", "&"); + out.replace("<", "<"); + out.replace(">", ">"); + out.replace("\"", """); + return out; +} + +void load_config() { + prefs.begin("bmcfg", true); + wifi_ssid = prefs.getString("ssid", ""); + wifi_password = prefs.getString("pwd", ""); + dest_ip_str = prefs.getString("destip", "192.168.1.190"); + udp_port = prefs.getUShort("port", 5004); + prefs.end(); +} + +void save_config(const String& ssid, const String& pwd, const String& dest_ip, uint16_t port) { + prefs.begin("bmcfg", false); + prefs.putString("ssid", ssid); + prefs.putString("pwd", pwd); + prefs.putString("destip", dest_ip); + prefs.putUShort("port", port); + prefs.end(); +} + +void clear_config() { + prefs.begin("bmcfg", false); + prefs.clear(); + prefs.end(); +} + +bool force_setup_requested() { + // give touch pad a moment to settle + delay(100); + + uint16_t touch_val = 0; + touch_pad_read(touch_pin, &touch_val); + + Serial.printf("touch boot check: %u\n", touch_val); + return touch_val < touch_threshold; +} + +void handle_root() { + String page = + "" + "" + "" + "baby monitor setup" + "" + "" + "

baby monitor setup

" + "

connect to ap " + String(ap_ssid) + " then browse to 192.168.4.1.

" + "
" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
" + "
" + "" + "
" + "

status json

" + ""; + + server.send(200, "text/html", page); +} + +void handle_status() { + String json = "{"; + json += "\"config_mode\":" + String(config_mode ? "true" : "false") + ","; + json += "\"ap_ssid\":\"" + String(ap_ssid) + "\","; + json += "\"saved_ssid\":\"" + html_escape(wifi_ssid) + "\","; + json += "\"dest_ip\":\"" + html_escape(dest_ip_str) + "\","; + json += "\"udp_port\":" + String(udp_port); + json += "}"; + + server.send(200, "application/json", json); +} + +bool valid_ipv4(const String& s) { + ipaddress ip; + return ip.fromString(s); +} + +void handle_save() { + String new_ssid = server.arg("ssid"); + String new_pwd = server.arg("pwd"); + String new_dest = server.arg("destip"); + uint16_t new_port = (uint16_t)server.arg("port").toInt(); + + if (new_ssid.length() == 0) { + server.send(400, "text/plain", "ssid required"); + return; + } + + if (!valid_ipv4(new_dest)) { + server.send(400, "text/plain", "invalid destination ip"); + return; + } + + if (new_port == 0) { + server.send(400, "text/plain", "invalid udp port"); + return; + } + + save_config(new_ssid, new_pwd, new_dest, new_port); + + server.send(200, "text/html", + "

saved. rebooting...

"); + delay(1000); + esp_restart(); +} + +void handle_clear() { + clear_config(); + server.send(200, "text/html", + "

config cleared. rebooting...

"); + delay(1000); + esp_restart(); +} + +void start_config_ap() { + config_mode = true; + + WiFi.disconnect(true, true); + delay(250); + + WiFi.mode(WIFI_AP); + WiFi.softAP(ap_ssid, ap_password); + + IPAddress ip = WiFi.softAPIP(); + Serial.printf("config ap active\n"); + Serial.printf(" ssid: %s\n", ap_ssid); + Serial.printf(" pass: %s\n", ap_password); + Serial.printf(" ip: %s\n", ip.toString().c_str()); + + server.on("/", HTTP_GET, handle_root); + server.on("/save", HTTP_POST, handle_save); + server.on("/clear", HTTP_POST, handle_clear); + server.on("/status", HTTP_GET, handle_status); + server.begin(); +} + +bool try_connect_wifi() { + if (wifi_ssid.length() == 0) { + Serial.println("no saved wifi ssid"); + return false; + } + + WiFi.disconnect(true, true); + delay(250); + + WiFi.mode(WIFI_STA); + WiFi.begin(wifi_ssid.c_str(), wifi_password.c_str()); + + Serial.printf("connecting to wifi: %s\n", wifi_ssid.c_str()); + + unsigned long start = millis(); + while (WiFi.status() != WL_CONNECTED && + millis() - start < wifi_connect_timeout_ms) { + delay(500); + Serial.print("."); + } + Serial.println(); + + if (WiFi.status() == WL_CONNECTED) { + Serial.printf("connected\n"); + Serial.printf(" ip: %s\n", WiFi.localIP().toString().c_str()); + Serial.printf(" dest ip: %s\n", dest_ip_str.c_str()); + Serial.printf(" udp port: %u\n", udp_port); + return true; + } + + Serial.println("wifi connect failed"); + return false; +} + +void setup() { + Serial.begin(115200); + delay(200); + + touch_pad_init(); + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + touch_pad_config(touch_pin, 0); + + load_config(); + + if (force_setup_requested()) { + Serial.println("force setup mode requested"); + start_config_ap(); + return; + } + + if (!try_connect_wifi()) { + start_config_ap(); + } +} + +void loop() { + if (config_mode) { + server.handleClient(); + delay(2); + return; + } + + // placeholder for later normal-mode behavior + static unsigned long last_print = 0; + if (millis() - last_print > 5000) { + Serial.printf("normal mode alive. wifi=%s ip=%s dest=%s:%u\n", + wifi_ssid.c_str(), + WiFi.localIP().toString().c_str(), + dest_ip_str.c_str(), + udp_port); + last_print = millis(); + } + + delay(10); +} \ No newline at end of file